Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jbarnes/pci
authorLinus Torvalds <torvalds@linux-foundation.org>
Sat, 18 Feb 2012 23:26:11 +0000 (15:26 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sat, 18 Feb 2012 23:26:11 +0000 (15:26 -0800)
One regression fix for SR-IOV on PPC and a couple of misc fixes from
Yinghai.

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jbarnes/pci:
  PCI: Fix pci cardbus removal
  PCI: set pci sriov page size before reading SRIOV BAR
  PCI: workaround hard-wired bus number V2

879 files changed:
Documentation/DocBook/device-drivers.tmpl
Documentation/driver-model/devres.txt
Documentation/feature-removal-schedule.txt
Documentation/input/event-codes.txt
Documentation/pinctrl.txt
Documentation/stable_kernel_rules.txt
Documentation/sysctl/kernel.txt
Documentation/virtual/00-INDEX
MAINTAINERS
Makefile
arch/arm/Kconfig
arch/arm/common/gic.c
arch/arm/include/asm/assembler.h
arch/arm/include/asm/domain.h
arch/arm/include/asm/futex.h
arch/arm/include/asm/smp.h
arch/arm/include/asm/smp_plat.h
arch/arm/include/asm/tlb.h
arch/arm/include/asm/uaccess.h
arch/arm/kernel/entry-armv.S
arch/arm/kernel/entry-common.S
arch/arm/kernel/perf_event_v7.c
arch/arm/kernel/ptrace.c
arch/arm/kernel/setup.c
arch/arm/kernel/signal.c
arch/arm/kernel/smp.c
arch/arm/kernel/smp_twd.c
arch/arm/kernel/traps.c
arch/arm/kernel/vmlinux.lds.S
arch/arm/lib/getuser.S
arch/arm/lib/putuser.S
arch/arm/lib/uaccess.S
arch/arm/mach-at91/Kconfig
arch/arm/mach-at91/Makefile
arch/arm/mach-at91/at91cap9.c
arch/arm/mach-at91/at91sam9260.c
arch/arm/mach-at91/at91sam9261.c
arch/arm/mach-at91/at91sam9263.c
arch/arm/mach-at91/at91sam9_alt_reset.S
arch/arm/mach-at91/at91sam9g45.c
arch/arm/mach-at91/at91sam9g45_reset.S [new file with mode: 0644]
arch/arm/mach-at91/at91sam9rl.c
arch/arm/mach-at91/generic.h
arch/arm/mach-at91/include/mach/at91_rstc.h
arch/arm/mach-at91/include/mach/at91cap9.h
arch/arm/mach-at91/include/mach/at91cap9_ddrsdr.h [deleted file]
arch/arm/mach-at91/include/mach/at91sam9260.h
arch/arm/mach-at91/include/mach/at91sam9261.h
arch/arm/mach-at91/include/mach/at91sam9263.h
arch/arm/mach-at91/include/mach/at91sam9_ddrsdr.h
arch/arm/mach-at91/include/mach/at91sam9g45.h
arch/arm/mach-at91/include/mach/at91sam9rl.h
arch/arm/mach-at91/include/mach/board.h
arch/arm/mach-at91/pm.c
arch/arm/mach-at91/pm.h
arch/arm/mach-at91/pm_slowclock.S
arch/arm/mach-at91/setup.c
arch/arm/mach-bcmring/arch.c
arch/arm/mach-bcmring/dma.c
arch/arm/mach-bcmring/include/mach/dma.h
arch/arm/mach-davinci/board-da850-evm.c
arch/arm/mach-davinci/board-dm365-evm.c
arch/arm/mach-davinci/board-dm644x-evm.c
arch/arm/mach-davinci/board-dm646x-evm.c
arch/arm/mach-davinci/board-neuros-osd2.c
arch/arm/mach-davinci/board-omapl138-hawk.c
arch/arm/mach-davinci/board-sffsdr.c
arch/arm/mach-davinci/da850.c
arch/arm/mach-exynos/hotplug.c
arch/arm/mach-exynos/platsmp.c
arch/arm/mach-highbank/highbank.c
arch/arm/mach-imx/Kconfig
arch/arm/mach-imx/clock-imx6q.c
arch/arm/mach-imx/mach-mx53_ard.c
arch/arm/mach-imx/src.c
arch/arm/mach-msm/hotplug.c
arch/arm/mach-msm/platsmp.c
arch/arm/mach-omap2/Kconfig
arch/arm/mach-omap2/board-4430sdp.c
arch/arm/mach-omap2/board-omap3evm.c
arch/arm/mach-omap2/board-omap4panda.c
arch/arm/mach-omap2/board-zoom-peripherals.c
arch/arm/mach-omap2/devices.c
arch/arm/mach-omap2/display.c
arch/arm/mach-omap2/gpmc.c
arch/arm/mach-omap2/hsmmc.c
arch/arm/mach-omap2/io.c
arch/arm/mach-omap2/mux.c
arch/arm/mach-omap2/omap-headsmp.S
arch/arm/mach-omap2/omap_hwmod.c
arch/arm/mach-omap2/omap_hwmod_2xxx_3xxx_ipblock_data.c
arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c
arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
arch/arm/mach-omap2/omap_hwmod_44xx_data.c
arch/arm/mach-omap2/prm2xxx_3xxx.c
arch/arm/mach-omap2/prm44xx.c
arch/arm/mach-omap2/serial.c
arch/arm/mach-omap2/smartreflex.c
arch/arm/mach-omap2/timer.c
arch/arm/mach-omap2/vc.c
arch/arm/mach-omap2/vp.c
arch/arm/mach-pxa/devices.c
arch/arm/mach-pxa/pxa25x.c
arch/arm/mach-pxa/pxa27x.c
arch/arm/mach-pxa/pxa300.c
arch/arm/mach-pxa/pxa320.c
arch/arm/mach-pxa/pxa3xx.c
arch/arm/mach-pxa/pxa95x.c
arch/arm/mach-realview/hotplug.c
arch/arm/mach-realview/include/mach/board-eb.h
arch/arm/mach-realview/include/mach/board-pb11mp.h
arch/arm/mach-realview/realview_eb.c
arch/arm/mach-realview/realview_pb11mp.c
arch/arm/mach-sa1100/assabet.c
arch/arm/mach-sa1100/cerf.c
arch/arm/mach-sa1100/clock.c
arch/arm/mach-sa1100/collie.c
arch/arm/mach-sa1100/cpu-sa1100.c
arch/arm/mach-sa1100/generic.c
arch/arm/mach-sa1100/include/mach/mcp.h
arch/arm/mach-sa1100/jornada720_ssp.c
arch/arm/mach-sa1100/lart.c
arch/arm/mach-sa1100/shannon.c
arch/arm/mach-sa1100/simpad.c
arch/arm/mach-shmobile/setup-sh7372.c
arch/arm/mach-shmobile/smp-r8a7779.c
arch/arm/mach-shmobile/smp-sh73a0.c
arch/arm/mach-ux500/Kconfig
arch/arm/mach-ux500/board-mop500-sdi.c
arch/arm/mach-ux500/cache-l2x0.c
arch/arm/mach-ux500/hotplug.c
arch/arm/mach-ux500/platsmp.c
arch/arm/mach-ux500/usb.c
arch/arm/mach-vexpress/ct-ca9x4.c
arch/arm/mach-vexpress/hotplug.c
arch/arm/mm/Kconfig
arch/arm/mm/cache-v7.S
arch/arm/mm/init.c
arch/arm/mm/proc-v7.S
arch/arm/plat-mxc/include/mach/iomux-v1.h
arch/arm/plat-versatile/platsmp.c
arch/avr32/Kconfig
arch/microblaze/Kconfig
arch/microblaze/include/asm/atomic.h
arch/microblaze/kernel/setup.c
arch/mips/Kconfig
arch/mips/lib/iomap-pci.c
arch/powerpc/include/asm/ppc-pci.h
arch/powerpc/include/asm/ptrace.h
arch/powerpc/kernel/irq.c
arch/powerpc/kernel/rtas.c
arch/powerpc/platforms/powernv/pci.c
arch/powerpc/platforms/pseries/eeh.c
arch/powerpc/platforms/pseries/suspend.c
arch/powerpc/platforms/wsp/ics.c
arch/powerpc/platforms/wsp/wsp_pci.c
arch/s390/Makefile
arch/s390/kernel/vmlinux.lds.S
arch/sh/Kconfig
arch/sh/drivers/pci/pci.c
arch/sparc/Kconfig
arch/sparc/lib/divdi3.S
arch/x86/include/asm/cmpxchg.h
arch/x86/include/asm/i387.h
arch/x86/include/asm/kvm_emulate.h
arch/x86/include/asm/processor.h
arch/x86/include/asm/thread_info.h
arch/x86/kernel/cpu/perf_event_intel_ds.c
arch/x86/kernel/cpu/perf_event_intel_lbr.c
arch/x86/kernel/dumpstack.c
arch/x86/kernel/dumpstack_64.c
arch/x86/kernel/process_32.c
arch/x86/kernel/process_64.c
arch/x86/kernel/reboot.c
arch/x86/kernel/traps.c
arch/x86/kernel/xsave.c
arch/x86/kvm/emulate.c
arch/x86/kvm/vmx.c
arch/x86/kvm/x86.c
arch/x86/mm/fault.c
arch/x86/pci/xen.c
arch/x86/xen/smp.c
arch/x86/xen/spinlock.c
arch/xtensa/include/asm/string.h
block/blk-cgroup.c
block/blk-core.c
block/blk-ioc.c
block/blk-merge.c
block/blk.h
block/bsg.c
block/cfq-iosched.c
block/elevator.c
crypto/sha512_generic.c
drivers/acpi/processor_driver.c
drivers/base/Makefile
drivers/base/core.c
drivers/base/cpu.c
drivers/base/memory.c
drivers/base/node.c
drivers/base/sys.c [deleted file]
drivers/bcma/main.c
drivers/bcma/scan.c
drivers/block/floppy.c
drivers/block/loop.c
drivers/block/mtip32xx/mtip32xx.c
drivers/block/mtip32xx/mtip32xx.h
drivers/block/rbd.c
drivers/cdrom/cdrom.c
drivers/dma/at_hdmac.c
drivers/dma/at_hdmac_regs.h
drivers/dma/dmatest.c
drivers/dma/imx-sdma.c
drivers/dma/shdma.c
drivers/firewire/ohci.c
drivers/gpio/gpio-lpc32xx.c
drivers/gpio/gpio-ml-ioh.c
drivers/gpio/gpio-pch.c
drivers/gpio/gpio-samsung.c
drivers/gpu/drm/drm_gem.c
drivers/gpu/drm/drm_ioc32.c
drivers/gpu/drm/i810/i810_dma.c
drivers/gpu/drm/i810/i810_drv.c
drivers/gpu/drm/i810/i810_drv.h
drivers/gpu/drm/i915/intel_display.c
drivers/gpu/drm/i915/intel_dp.c
drivers/gpu/drm/i915/intel_lvds.c
drivers/gpu/drm/nouveau/nouveau_bios.h
drivers/gpu/drm/nouveau/nouveau_display.c
drivers/gpu/drm/nouveau/nouveau_drv.c
drivers/gpu/drm/nouveau/nouveau_gem.c
drivers/gpu/drm/nouveau/nouveau_mxm.c
drivers/gpu/drm/nouveau/nv50_pm.c
drivers/gpu/drm/radeon/atombios_crtc.c
drivers/gpu/drm/radeon/atombios_dp.c
drivers/gpu/drm/radeon/evergreen.c
drivers/gpu/drm/radeon/r100.c
drivers/gpu/drm/radeon/r600_blit_kms.c
drivers/gpu/drm/radeon/radeon_atombios.c
drivers/gpu/drm/radeon/radeon_atpx_handler.c
drivers/gpu/drm/radeon/radeon_device.c
drivers/gpu/drm/radeon/radeon_fence.c
drivers/gpu/drm/radeon/radeon_i2c.c
drivers/gpu/drm/radeon/rs600.c
drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
drivers/hid/hid-hyperv.c
drivers/hid/hid-wacom.c
drivers/hid/hid-wiimote-core.c
drivers/hid/usbhid/hiddev.c
drivers/hwmon/f71805f.c
drivers/hwmon/f75375s.c
drivers/hwmon/sht15.c
drivers/hwmon/w83627ehf.c
drivers/i2c/busses/i2c-omap.c
drivers/infiniband/core/ucma.c
drivers/infiniband/core/uverbs_cmd.c
drivers/infiniband/core/verbs.c
drivers/infiniband/hw/ipath/ipath_fs.c
drivers/infiniband/hw/mlx4/mad.c
drivers/infiniband/hw/nes/nes.c
drivers/infiniband/hw/nes/nes.h
drivers/infiniband/hw/nes/nes_cm.c
drivers/infiniband/hw/nes/nes_cm.h
drivers/infiniband/hw/nes/nes_context.h
drivers/infiniband/hw/nes/nes_hw.c
drivers/infiniband/hw/nes/nes_hw.h
drivers/infiniband/hw/nes/nes_mgt.c
drivers/infiniband/hw/nes/nes_mgt.h
drivers/infiniband/hw/nes/nes_nic.c
drivers/infiniband/hw/nes/nes_user.h
drivers/infiniband/hw/nes/nes_utils.c
drivers/infiniband/hw/nes/nes_verbs.c
drivers/infiniband/hw/nes/nes_verbs.h
drivers/infiniband/hw/qib/qib_iba6120.c
drivers/infiniband/hw/qib/qib_pcie.c
drivers/infiniband/ulp/ipoib/ipoib.h
drivers/infiniband/ulp/ipoib/ipoib_main.c
drivers/infiniband/ulp/ipoib/ipoib_multicast.c
drivers/infiniband/ulp/srpt/ib_srpt.c
drivers/infiniband/ulp/srpt/ib_srpt.h
drivers/input/evdev.c
drivers/input/keyboard/twl4030_keypad.c
drivers/input/serio/i8042-x86ia64io.h
drivers/input/serio/serio_raw.c
drivers/iommu/amd_iommu.c
drivers/iommu/msm_iommu.c
drivers/isdn/i4l/isdn_net.c
drivers/leds/leds-lm3530.c
drivers/md/dm-raid.c
drivers/md/md.c
drivers/mfd/Kconfig
drivers/mfd/mcp-core.c
drivers/mfd/mcp-sa11x0.c
drivers/mfd/twl-core.c
drivers/mfd/twl4030-power.c
drivers/mfd/twl6040-core.c
drivers/mfd/ucb1x00-core.c
drivers/mfd/ucb1x00-ts.c
drivers/misc/Kconfig
drivers/misc/c2port/c2port-duramar2150.c
drivers/misc/cb710/core.c
drivers/misc/cs5535-mfgpt.c
drivers/misc/lkdtm.c
drivers/misc/vmw_balloon.c
drivers/mmc/card/block.c
drivers/mmc/core/core.c
drivers/mmc/core/host.h
drivers/mmc/core/mmc.c
drivers/mmc/core/sd.c
drivers/mmc/core/sdio.c
drivers/mmc/core/sdio_irq.c
drivers/mmc/host/Kconfig
drivers/mmc/host/atmel-mci.c
drivers/mmc/host/dw_mmc.c
drivers/mmc/host/of_mmc_spi.c
drivers/mmc/host/sdhci-of-esdhc.c
drivers/mmc/host/sdhci-pci.c
drivers/mmc/host/sdhci-pltfm.c
drivers/mmc/host/sh_mmcif.c
drivers/mmc/host/tmio_mmc.h
drivers/mmc/host/tmio_mmc_dma.c
drivers/mmc/host/tmio_mmc_pio.c
drivers/mtd/mtdcore.c
drivers/mtd/nand/atmel_nand.c
drivers/mtd/nand/gpmi-nand/gpmi-lib.c
drivers/mtd/nand/nand_base.c
drivers/net/can/cc770/cc770.c
drivers/net/can/cc770/cc770_isa.c
drivers/net/can/flexcan.c
drivers/net/can/pch_can.c
drivers/net/can/sja1000/peak_pci.c
drivers/net/can/ti_hecc.c
drivers/net/can/usb/ems_usb.c
drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
drivers/net/ethernet/brocade/bna/bnad_ethtool.c
drivers/net/ethernet/emulex/benet/be_ethtool.c
drivers/net/ethernet/freescale/fec.c
drivers/net/ethernet/intel/e1000/e1000_main.c
drivers/net/ethernet/intel/igb/igb_main.c
drivers/net/ethernet/intel/igbvf/Makefile
drivers/net/ethernet/intel/igbvf/defines.h
drivers/net/ethernet/intel/igbvf/ethtool.c
drivers/net/ethernet/intel/igbvf/igbvf.h
drivers/net/ethernet/intel/igbvf/mbx.c
drivers/net/ethernet/intel/igbvf/mbx.h
drivers/net/ethernet/intel/igbvf/netdev.c
drivers/net/ethernet/intel/igbvf/regs.h
drivers/net/ethernet/intel/igbvf/vf.c
drivers/net/ethernet/intel/igbvf/vf.h
drivers/net/ethernet/intel/ixgbe/Makefile
drivers/net/ethernet/intel/ixgbe/ixgbe.h
drivers/net/ethernet/intel/ixgbe/ixgbe_82598.c
drivers/net/ethernet/intel/ixgbe/ixgbe_82599.c
drivers/net/ethernet/intel/ixgbe/ixgbe_common.c
drivers/net/ethernet/intel/ixgbe/ixgbe_common.h
drivers/net/ethernet/intel/ixgbe/ixgbe_dcb.c
drivers/net/ethernet/intel/ixgbe/ixgbe_dcb.h
drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_82598.c
drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_82598.h
drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_82599.c
drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_82599.h
drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_nl.c
drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c
drivers/net/ethernet/intel/ixgbe/ixgbe_fcoe.c
drivers/net/ethernet/intel/ixgbe/ixgbe_fcoe.h
drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
drivers/net/ethernet/intel/ixgbe/ixgbe_mbx.c
drivers/net/ethernet/intel/ixgbe/ixgbe_mbx.h
drivers/net/ethernet/intel/ixgbe/ixgbe_phy.c
drivers/net/ethernet/intel/ixgbe/ixgbe_phy.h
drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c
drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.h
drivers/net/ethernet/intel/ixgbe/ixgbe_type.h
drivers/net/ethernet/intel/ixgbe/ixgbe_x540.c
drivers/net/ethernet/intel/ixgbevf/Makefile
drivers/net/ethernet/intel/ixgbevf/defines.h
drivers/net/ethernet/intel/ixgbevf/ethtool.c
drivers/net/ethernet/intel/ixgbevf/ixgbevf.h
drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
drivers/net/ethernet/intel/ixgbevf/mbx.c
drivers/net/ethernet/intel/ixgbevf/mbx.h
drivers/net/ethernet/intel/ixgbevf/regs.h
drivers/net/ethernet/intel/ixgbevf/vf.c
drivers/net/ethernet/intel/ixgbevf/vf.h
drivers/net/ethernet/marvell/skge.c
drivers/net/ethernet/mellanox/mlx4/cmd.c
drivers/net/ethernet/mellanox/mlx4/en_netdev.c
drivers/net/ethernet/mellanox/mlx4/en_rx.c
drivers/net/ethernet/mellanox/mlx4/mcg.c
drivers/net/ethernet/mellanox/mlx4/mlx4_en.h
drivers/net/ethernet/micrel/Kconfig
drivers/net/ethernet/renesas/sh_eth.c
drivers/net/ethernet/renesas/sh_eth.h
drivers/net/ethernet/ti/davinci_emac.c
drivers/net/ethernet/ti/davinci_mdio.c
drivers/net/ethernet/toshiba/Kconfig
drivers/net/ethernet/via/via-velocity.c
drivers/net/hyperv/netvsc_drv.c
drivers/net/hyperv/rndis_filter.c
drivers/net/tokenring/Kconfig
drivers/net/wireless/ath/ath9k/hw.c
drivers/net/wireless/ath/ath9k/init.c
drivers/net/wireless/ath/ath9k/rc.c
drivers/net/wireless/ath/ath9k/recv.c
drivers/net/wireless/iwlwifi/iwl-agn-tx.c
drivers/net/wireless/iwlwifi/iwl-commands.h
drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c
drivers/net/wireless/iwlwifi/iwl-trans-pcie.c
drivers/net/wireless/mwifiex/init.c
drivers/net/wireless/mwifiex/main.c
drivers/net/wireless/mwifiex/sta_ioctl.c
drivers/net/wireless/rt2x00/rt2800lib.c
drivers/net/wireless/zd1211rw/zd_mac.c
drivers/net/xen-netfront.c
drivers/pci/xen-pcifront.c
drivers/pcmcia/ds.c
drivers/pcmcia/sa1111_generic.c
drivers/pinctrl/core.c
drivers/pinctrl/core.h
drivers/pinctrl/pinconf.c
drivers/pinctrl/pinconf.h
drivers/pinctrl/pinmux.c
drivers/pinctrl/pinmux.h
drivers/power/bq27x00_battery.c
drivers/power/charger-manager.c
drivers/power/lp8727_charger.c
drivers/regulator/max8649.c
drivers/regulator/mc13xxx-regulator-core.c
drivers/regulator/of_regulator.c
drivers/rtc/Kconfig
drivers/rtc/rtc-sa1100.c
drivers/s390/block/dasd.c
drivers/s390/block/dasd_alias.c
drivers/s390/block/dasd_eckd.c
drivers/s390/block/dasd_int.h
drivers/spi/Kconfig
drivers/spi/spi-topcliff-pch.c
drivers/ssb/driver_pcicore.c
drivers/staging/Kconfig
drivers/staging/Makefile
drivers/staging/android/Kconfig
drivers/staging/android/Makefile
drivers/staging/android/android_pmem.h [deleted file]
drivers/staging/android/binder.c
drivers/staging/android/lowmemorykiller.c
drivers/staging/android/pmem.c [deleted file]
drivers/staging/asus_oled/asus_oled.c
drivers/staging/gma500/Kconfig [deleted file]
drivers/staging/gma500/Makefile [deleted file]
drivers/staging/gma500/TODO [deleted file]
drivers/staging/gma500/accel_2d.c [deleted file]
drivers/staging/gma500/backlight.c [deleted file]
drivers/staging/gma500/cdv_device.c [deleted file]
drivers/staging/gma500/cdv_device.h [deleted file]
drivers/staging/gma500/cdv_intel_crt.c [deleted file]
drivers/staging/gma500/cdv_intel_display.c [deleted file]
drivers/staging/gma500/cdv_intel_hdmi.c [deleted file]
drivers/staging/gma500/cdv_intel_lvds.c [deleted file]
drivers/staging/gma500/displays/hdmi.h [deleted file]
drivers/staging/gma500/displays/pyr_cmd.h [deleted file]
drivers/staging/gma500/displays/pyr_vid.h [deleted file]
drivers/staging/gma500/displays/tmd_cmd.h [deleted file]
drivers/staging/gma500/displays/tmd_vid.h [deleted file]
drivers/staging/gma500/displays/tpo_cmd.h [deleted file]
drivers/staging/gma500/displays/tpo_vid.h [deleted file]
drivers/staging/gma500/framebuffer.c [deleted file]
drivers/staging/gma500/framebuffer.h [deleted file]
drivers/staging/gma500/gem.c [deleted file]
drivers/staging/gma500/gem_glue.c [deleted file]
drivers/staging/gma500/gem_glue.h [deleted file]
drivers/staging/gma500/gtt.c [deleted file]
drivers/staging/gma500/gtt.h [deleted file]
drivers/staging/gma500/intel_bios.c [deleted file]
drivers/staging/gma500/intel_bios.h [deleted file]
drivers/staging/gma500/intel_i2c.c [deleted file]
drivers/staging/gma500/intel_opregion.c [deleted file]
drivers/staging/gma500/mdfld_device.c [deleted file]
drivers/staging/gma500/mdfld_dsi_dbi.c [deleted file]
drivers/staging/gma500/mdfld_dsi_dbi.h [deleted file]
drivers/staging/gma500/mdfld_dsi_dbi_dpu.c [deleted file]
drivers/staging/gma500/mdfld_dsi_dbi_dpu.h [deleted file]
drivers/staging/gma500/mdfld_dsi_dpi.c [deleted file]
drivers/staging/gma500/mdfld_dsi_dpi.h [deleted file]
drivers/staging/gma500/mdfld_dsi_output.c [deleted file]
drivers/staging/gma500/mdfld_dsi_output.h [deleted file]
drivers/staging/gma500/mdfld_dsi_pkg_sender.c [deleted file]
drivers/staging/gma500/mdfld_dsi_pkg_sender.h [deleted file]
drivers/staging/gma500/mdfld_intel_display.c [deleted file]
drivers/staging/gma500/mdfld_msic.h [deleted file]
drivers/staging/gma500/mdfld_output.c [deleted file]
drivers/staging/gma500/mdfld_output.h [deleted file]
drivers/staging/gma500/mdfld_pyr_cmd.c [deleted file]
drivers/staging/gma500/mdfld_tmd_vid.c [deleted file]
drivers/staging/gma500/mdfld_tpo_cmd.c [deleted file]
drivers/staging/gma500/mdfld_tpo_vid.c [deleted file]
drivers/staging/gma500/medfield.h [deleted file]
drivers/staging/gma500/mid_bios.c [deleted file]
drivers/staging/gma500/mid_bios.h [deleted file]
drivers/staging/gma500/mmu.c [deleted file]
drivers/staging/gma500/mrst.h [deleted file]
drivers/staging/gma500/mrst_crtc.c [deleted file]
drivers/staging/gma500/mrst_device.c [deleted file]
drivers/staging/gma500/mrst_hdmi.c [deleted file]
drivers/staging/gma500/mrst_hdmi_i2c.c [deleted file]
drivers/staging/gma500/mrst_lvds.c [deleted file]
drivers/staging/gma500/power.c [deleted file]
drivers/staging/gma500/power.h [deleted file]
drivers/staging/gma500/psb_device.c [deleted file]
drivers/staging/gma500/psb_drm.h [deleted file]
drivers/staging/gma500/psb_drv.c [deleted file]
drivers/staging/gma500/psb_drv.h [deleted file]
drivers/staging/gma500/psb_intel_display.c [deleted file]
drivers/staging/gma500/psb_intel_display.h [deleted file]
drivers/staging/gma500/psb_intel_drv.h [deleted file]
drivers/staging/gma500/psb_intel_lvds.c [deleted file]
drivers/staging/gma500/psb_intel_modes.c [deleted file]
drivers/staging/gma500/psb_intel_reg.h [deleted file]
drivers/staging/gma500/psb_intel_sdvo.c [deleted file]
drivers/staging/gma500/psb_intel_sdvo_regs.h [deleted file]
drivers/staging/gma500/psb_irq.c [deleted file]
drivers/staging/gma500/psb_irq.h [deleted file]
drivers/staging/gma500/psb_lid.c [deleted file]
drivers/staging/gma500/psb_reg.h [deleted file]
drivers/staging/media/go7007/go7007-usb.c
drivers/staging/omapdrm/Makefile
drivers/staging/omapdrm/omap_crtc.c
drivers/staging/omapdrm/omap_drv.c
drivers/staging/omapdrm/omap_drv.h
drivers/staging/omapdrm/omap_fb.c
drivers/staging/omapdrm/omap_fbdev.c
drivers/staging/omapdrm/omap_gem.c
drivers/staging/omapdrm/omap_plane.c [new file with mode: 0644]
drivers/staging/omapdrm/omap_priv.h
drivers/staging/pohmelfs/Kconfig [deleted file]
drivers/staging/pohmelfs/Makefile [deleted file]
drivers/staging/pohmelfs/config.c [deleted file]
drivers/staging/pohmelfs/crypto.c [deleted file]
drivers/staging/pohmelfs/dir.c [deleted file]
drivers/staging/pohmelfs/inode.c [deleted file]
drivers/staging/pohmelfs/lock.c [deleted file]
drivers/staging/pohmelfs/mcache.c [deleted file]
drivers/staging/pohmelfs/net.c [deleted file]
drivers/staging/pohmelfs/netfs.h [deleted file]
drivers/staging/pohmelfs/path_entry.c [deleted file]
drivers/staging/pohmelfs/trans.c [deleted file]
drivers/staging/rtl8712/drv_types.h
drivers/staging/rtl8712/hal_init.c
drivers/staging/rtl8712/os_intfs.c
drivers/staging/rtl8712/rtl8712_hal.h
drivers/staging/rtl8712/rtl871x_sta_mgt.c
drivers/staging/rtl8712/usb_intf.c
drivers/staging/tidspbridge/core/tiomap3430.c
drivers/staging/tidspbridge/rmgr/drv_interface.c
drivers/staging/usbip/stub_main.c
drivers/staging/zcache/zcache-main.c
drivers/target/iscsi/iscsi_target.c
drivers/target/iscsi/iscsi_target_configfs.c
drivers/target/iscsi/iscsi_target_core.h
drivers/target/iscsi/iscsi_target_erl1.c
drivers/target/iscsi/iscsi_target_login.c
drivers/target/iscsi/iscsi_target_util.c
drivers/target/target_core_alua.c
drivers/target/target_core_cdb.c
drivers/target/target_core_configfs.c
drivers/target/target_core_device.c
drivers/target/target_core_fabric_configfs.c
drivers/target/target_core_iblock.c
drivers/target/target_core_internal.h
drivers/target/target_core_pr.c
drivers/target/target_core_pscsi.c
drivers/target/target_core_tpg.c
drivers/target/target_core_transport.c
drivers/target/tcm_fc/tfc_cmd.c
drivers/tty/serial/8250.c [deleted file]
drivers/tty/serial/8250.h [deleted file]
drivers/tty/serial/8250/8250.c [new file with mode: 0644]
drivers/tty/serial/8250/8250.h [new file with mode: 0644]
drivers/tty/serial/8250/8250_accent.c [new file with mode: 0644]
drivers/tty/serial/8250/8250_acorn.c [new file with mode: 0644]
drivers/tty/serial/8250/8250_boca.c [new file with mode: 0644]
drivers/tty/serial/8250/8250_dw.c [new file with mode: 0644]
drivers/tty/serial/8250/8250_early.c [new file with mode: 0644]
drivers/tty/serial/8250/8250_exar_st16c554.c [new file with mode: 0644]
drivers/tty/serial/8250/8250_fourport.c [new file with mode: 0644]
drivers/tty/serial/8250/8250_fsl.c [new file with mode: 0644]
drivers/tty/serial/8250/8250_gsc.c [new file with mode: 0644]
drivers/tty/serial/8250/8250_hp300.c [new file with mode: 0644]
drivers/tty/serial/8250/8250_hub6.c [new file with mode: 0644]
drivers/tty/serial/8250/8250_mca.c [new file with mode: 0644]
drivers/tty/serial/8250/8250_pci.c [new file with mode: 0644]
drivers/tty/serial/8250/8250_pnp.c [new file with mode: 0644]
drivers/tty/serial/8250/Kconfig [new file with mode: 0644]
drivers/tty/serial/8250/Makefile [new file with mode: 0644]
drivers/tty/serial/8250/serial_cs.c [new file with mode: 0644]
drivers/tty/serial/8250_accent.c [deleted file]
drivers/tty/serial/8250_acorn.c [deleted file]
drivers/tty/serial/8250_boca.c [deleted file]
drivers/tty/serial/8250_dw.c [deleted file]
drivers/tty/serial/8250_early.c [deleted file]
drivers/tty/serial/8250_exar_st16c554.c [deleted file]
drivers/tty/serial/8250_fourport.c [deleted file]
drivers/tty/serial/8250_fsl.c [deleted file]
drivers/tty/serial/8250_gsc.c [deleted file]
drivers/tty/serial/8250_hp300.c [deleted file]
drivers/tty/serial/8250_hub6.c [deleted file]
drivers/tty/serial/8250_mca.c [deleted file]
drivers/tty/serial/8250_pci.c [deleted file]
drivers/tty/serial/8250_pnp.c [deleted file]
drivers/tty/serial/Kconfig
drivers/tty/serial/Makefile
drivers/tty/serial/amba-pl011.c
drivers/tty/serial/jsm/jsm_driver.c
drivers/tty/serial/max3107-aava.c [deleted file]
drivers/tty/serial/omap-serial.c
drivers/tty/serial/samsung.c
drivers/tty/serial/serial_core.c
drivers/tty/serial/serial_cs.c [deleted file]
drivers/tty/tty_port.c
drivers/tty/vt/vt_ioctl.c
drivers/usb/class/cdc-wdm.c
drivers/usb/dwc3/ep0.c
drivers/usb/dwc3/gadget.c
drivers/usb/gadget/composite.c
drivers/usb/gadget/epautoconf.c
drivers/usb/gadget/f_loopback.c
drivers/usb/gadget/f_mass_storage.c
drivers/usb/gadget/fsl_udc_core.c
drivers/usb/gadget/langwell_udc.c
drivers/usb/gadget/langwell_udc.h
drivers/usb/gadget/storage_common.c
drivers/usb/host/Kconfig
drivers/usb/host/ehci-fsl.c
drivers/usb/host/ehci-fsl.h
drivers/usb/host/ehci-pci.c
drivers/usb/host/ohci-at91.c
drivers/usb/host/ohci-dbg.c
drivers/usb/host/ohci-pci.c
drivers/usb/host/pci-quirks.c
drivers/usb/host/xhci-ring.c
drivers/usb/misc/emi26.c
drivers/usb/misc/emi62.c
drivers/usb/misc/usbsevseg.c
drivers/usb/musb/davinci.c
drivers/usb/musb/musb_core.c
drivers/usb/musb/musb_io.h
drivers/usb/musb/omap2430.c
drivers/usb/otg/Kconfig
drivers/usb/otg/Makefile
drivers/usb/otg/langwell_otg.c [deleted file]
drivers/usb/otg/mv_otg.c
drivers/usb/renesas_usbhs/mod_gadget.c
drivers/usb/serial/cp210x.c
drivers/usb/serial/ftdi_sio.c
drivers/usb/serial/ftdi_sio_ids.h
drivers/usb/serial/io_ti.c
drivers/usb/serial/kobil_sct.c
drivers/usb/serial/option.c
drivers/usb/serial/qcaux.c
drivers/usb/serial/qcserial.c
drivers/usb/storage/realtek_cr.c
drivers/usb/usb-skeleton.c
drivers/usb/wusbcore/Kconfig
drivers/video/atmel_lcdfb.c
drivers/video/fsl-diu-fb.c
drivers/video/intelfb/intelfbdrv.c
drivers/video/omap2/dss/dispc.c
drivers/video/omap2/dss/dpi.c
drivers/video/omap2/dss/dsi.c
drivers/video/omap2/dss/dss.c
drivers/video/omap2/dss/hdmi.c
drivers/video/omap2/dss/rfbi.c
drivers/video/omap2/dss/ti_hdmi.h
drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c
drivers/video/omap2/dss/venc.c
drivers/virtio/virtio_ring.c
drivers/watchdog/dw_wdt.c
drivers/watchdog/iTCO_wdt.c
drivers/watchdog/imx2_wdt.c
drivers/watchdog/nuc900_wdt.c
drivers/watchdog/omap_wdt.c
drivers/watchdog/pnx4008_wdt.c
drivers/watchdog/stmp3xxx_wdt.c
drivers/watchdog/via_wdt.c
drivers/watchdog/wafer5823wdt.c
drivers/watchdog/wm8350_wdt.c
drivers/xen/cpu_hotplug.c
drivers/xen/grant-table.c
drivers/xen/xen-pciback/pci_stub.c
drivers/xen/xen-pciback/xenbus.c
drivers/xen/xenbus/xenbus_dev_frontend.c
fs/bio.c
fs/btrfs/backref.c
fs/btrfs/check-integrity.c
fs/btrfs/disk-io.c
fs/btrfs/extent-tree.c
fs/btrfs/extent_io.c
fs/btrfs/free-space-cache.c
fs/btrfs/inode.c
fs/btrfs/ioctl.c
fs/btrfs/tree-log.c
fs/ceph/caps.c
fs/ceph/dir.c
fs/ceph/mds_client.c
fs/ceph/mds_client.h
fs/ceph/xattr.c
fs/cifs/Kconfig
fs/cifs/connect.c
fs/cifs/dir.c
fs/cifs/sess.c
fs/exec.c
fs/fs-writeback.c
fs/ioprio.c
fs/jffs2/erase.c
fs/logfs/dev_mtd.c
fs/logfs/dir.c
fs/logfs/file.c
fs/logfs/gc.c
fs/logfs/inode.c
fs/logfs/journal.c
fs/logfs/logfs.h
fs/logfs/readwrite.c
fs/logfs/segment.c
fs/logfs/super.c
fs/nilfs2/ioctl.c
fs/proc/base.c
fs/sysfs/file.c
fs/sysfs/inode.c
fs/xfs/kmem.h
fs/xfs/xfs_dquot.c
fs/xfs/xfs_log_recover.c
fs/xfs/xfs_qm.c
fs/xfs/xfs_qm.h
fs/xfs/xfs_qm_stats.c
fs/xfs/xfs_trace.h
include/asm-generic/pci_iomap.h
include/linux/binfmts.h
include/linux/bitops.h
include/linux/blkdev.h
include/linux/cdrom.h
include/linux/elevator.h
include/linux/freezer.h
include/linux/gpio_keys.h
include/linux/hyperv.h
include/linux/iocontext.h
include/linux/lp8727.h [changed mode: 0755->0644]
include/linux/mfd/mcp.h
include/linux/mfd/twl6040.h
include/linux/mfd/ucb1x00.h
include/linux/mmc/card.h
include/linux/mmc/dw_mmc.h
include/linux/mmc/host.h
include/linux/mod_devicetable.h
include/linux/mpi.h
include/linux/mtd/mtd.h
include/linux/perf_event.h
include/linux/pm_qos.h
include/linux/proportions.h
include/linux/sched.h
include/linux/sh_dma.h
include/linux/sysdev.h [deleted file]
include/linux/usb/ch9.h
include/linux/usb/langwell_otg.h [deleted file]
include/net/flow.h
include/net/netns/generic.h
include/net/netprio_cgroup.h
include/net/route.h
include/net/sch_generic.h
include/net/sock.h
include/net/tcp.h
include/sound/core.h
include/target/target_core_backend.h
include/target/target_core_base.h
include/target/target_core_fabric.h
include/trace/events/writeback.h
include/video/omapdss.h
kernel/events/core.c
kernel/exit.c
kernel/fork.c
kernel/kprobes.c
kernel/params.c
kernel/power/power.h
kernel/power/process.c
kernel/power/user.c
kernel/relay.c
kernel/sched/core.c
kernel/sched/fair.c
kernel/sched/rt.c
kernel/watchdog.c
lib/Kconfig
lib/Makefile
lib/bug.c
lib/clz_tab.c [new file with mode: 0644]
lib/digsig.c
lib/kstrtox.c
lib/mpi/longlong.h
lib/mpi/mpi-bit.c
lib/mpi/mpi-div.c
lib/mpi/mpi-pow.c
lib/mpi/mpicoder.c
lib/mpi/mpih-div.c
lib/mpi/mpiutil.c
lib/pci_iomap.c
mm/backing-dev.c
mm/compaction.c
mm/filemap.c
mm/filemap_xip.c
mm/huge_memory.c
mm/kmemleak.c
mm/memcontrol.c
mm/migrate.c
mm/process_vm_access.c
mm/swap.c
net/caif/caif_dev.c
net/caif/caif_socket.c
net/caif/cfcnfg.c
net/caif/cfmuxl.c
net/ceph/ceph_common.c
net/ceph/mon_client.c
net/core/dev.c
net/core/ethtool.c
net/core/net_namespace.c
net/core/netprio_cgroup.c
net/core/rtnetlink.c
net/core/sock.c
net/ipv4/Kconfig
net/ipv4/arp.c
net/ipv4/inet_connection_sock.c
net/ipv4/ip_gre.c
net/ipv4/ip_options.c
net/ipv4/sysctl_net_ipv4.c
net/ipv4/tcp.c
net/ipv4/tcp_ipv4.c
net/ipv4/tcp_output.c
net/ipv4/tcp_timer.c
net/l2tp/l2tp_ip.c
net/mac80211/ibss.c
net/mac80211/iface.c
net/mac80211/rx.c
net/sched/sch_choke.c
net/sched/sch_netem.c
net/sched/sch_sfb.c
net/sched/sch_sfq.c
net/sunrpc/auth_generic.c
net/unix/af_unix.c
scripts/checkpatch.pl
scripts/mod/file2alias.c
sound/isa/sb/emu8000_patch.c
sound/pci/hda/hda_codec.c
sound/pci/hda/hda_jack.c
sound/pci/hda/patch_ca0132.c
sound/pci/hda/patch_cirrus.c
sound/pci/hda/patch_realtek.c
sound/pci/hda/patch_sigmatel.c
sound/pci/hda/patch_via.c
sound/pci/intel8x0.c
sound/pci/oxygen/oxygen_mixer.c
sound/soc/codecs/cs42l73.c
sound/soc/codecs/wm5100.c
sound/soc/codecs/wm8962.c
sound/soc/codecs/wm8994.c
sound/soc/codecs/wm8996.c
sound/soc/codecs/wm_hubs.c
sound/soc/samsung/neo1973_wm8753.c
sound/soc/sh/fsi.c
sound/soc/soc-core.c
sound/usb/quirks-table.h
tools/perf/Makefile
tools/perf/bench/mem-memcpy-x86-64-asm.S
tools/perf/builtin-probe.c
tools/perf/builtin-top.c
tools/perf/util/event.c
tools/perf/util/evsel.c
tools/perf/util/header.c
tools/perf/util/probe-event.c
tools/perf/util/symbol.c
tools/perf/util/trace-event-parse.c
tools/perf/util/ui/browsers/hists.c
tools/perf/util/ui/helpline.c
tools/perf/util/util.h
virt/kvm/kvm_main.c

index 2f7fd43..9c27e51 100644 (file)
@@ -102,9 +102,12 @@ X!Iinclude/linux/kobject.h
 !Iinclude/linux/device.h
      </sect1>
      <sect1><title>Device Drivers Base</title>
+!Idrivers/base/init.c
 !Edrivers/base/driver.c
 !Edrivers/base/core.c
+!Edrivers/base/syscore.c
 !Edrivers/base/class.c
+!Idrivers/base/node.c
 !Edrivers/base/firmware_class.c
 !Edrivers/base/transport_class.c
 <!-- Cannot be included, because
@@ -113,13 +116,18 @@ X!Iinclude/linux/kobject.h
      exceed allowed 44 characters maximum
 X!Edrivers/base/attribute_container.c
 -->
-!Edrivers/base/sys.c
+!Edrivers/base/dd.c
 <!--
 X!Edrivers/base/interface.c
 -->
 !Iinclude/linux/platform_device.h
 !Edrivers/base/platform.c
 !Edrivers/base/bus.c
+     </sect1>
+     <sect1><title>Device Drivers DMA Management</title>
+!Edrivers/base/dma-buf.c
+!Edrivers/base/dma-coherent.c
+!Edrivers/base/dma-mapping.c
      </sect1>
      <sect1><title>Device Drivers Power Management</title>
 !Edrivers/base/power/main.c
@@ -219,7 +227,7 @@ X!Isound/sound_firmware.c
   <chapter id="uart16x50">
      <title>16x50 UART Driver</title>
 !Edrivers/tty/serial/serial_core.c
-!Edrivers/tty/serial/8250.c
+!Edrivers/tty/serial/8250/8250.c
   </chapter>
 
   <chapter id="fbdev">
index 10c64c8..41c0c5d 100644 (file)
@@ -233,6 +233,10 @@ certainly invest a bit more effort into libata core layer).
   6. List of managed interfaces
   -----------------------------
 
+MEM
+  devm_kzalloc()
+  devm_kfree()
+
 IO region
   devm_request_region()
   devm_request_mem_region()
index 1bea46a..a0ffac0 100644 (file)
@@ -510,3 +510,17 @@ Why:       The pci_scan_bus_parented() interface creates a new root bus.  The
        convert to using pci_scan_root_bus() so they can supply a list of
        bus resources when the bus is created.
 Who:   Bjorn Helgaas <bhelgaas@google.com>
+
+----------------------------
+
+What:  The CAP9 SoC family will be removed
+When:  3.4
+Files: arch/arm/mach-at91/at91cap9.c
+       arch/arm/mach-at91/at91cap9_devices.c
+       arch/arm/mach-at91/include/mach/at91cap9.h
+       arch/arm/mach-at91/include/mach/at91cap9_matrix.h
+       arch/arm/mach-at91/include/mach/at91cap9_ddrsdr.h
+       arch/arm/mach-at91/board-cap9adk.c
+Why:   The code is not actively maintained and platforms are now hard to find.
+Who:   Nicolas Ferre <nicolas.ferre@atmel.com>
+       Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
index 23fcb05..53305bd 100644 (file)
@@ -17,11 +17,11 @@ reports supported by a device are also provided by sysfs in
 class/input/event*/device/capabilities/, and the properties of a device are
 provided in class/input/event*/device/properties.
 
-Types:
-==========
-Types are groupings of codes under a logical input construct. Each type has a
-set of applicable codes to be used in generating events. See the Codes section
-for details on valid codes for each type.
+Event types:
+===========
+Event types are groupings of codes under a logical input construct. Each
+type has a set of applicable codes to be used in generating events. See the
+Codes section for details on valid codes for each type.
 
 * EV_SYN:
   - Used as markers to separate events. Events may be separated in time or in
@@ -63,9 +63,9 @@ for details on valid codes for each type.
 * EV_FF_STATUS:
   - Used to receive force feedback device status.
 
-Codes:
-==========
-Codes define the precise type of event.
+Event codes:
+===========
+Event codes define the precise type of event.
 
 EV_SYN:
 ----------
@@ -220,6 +220,56 @@ EV_PWR:
 EV_PWR events are a special type of event used specifically for power
 mangement. Its usage is not well defined. To be addressed later.
 
+Device properties:
+=================
+Normally, userspace sets up an input device based on the data it emits,
+i.e., the event types. In the case of two devices emitting the same event
+types, additional information can be provided in the form of device
+properties.
+
+INPUT_PROP_DIRECT + INPUT_PROP_POINTER:
+--------------------------------------
+The INPUT_PROP_DIRECT property indicates that device coordinates should be
+directly mapped to screen coordinates (not taking into account trivial
+transformations, such as scaling, flipping and rotating). Non-direct input
+devices require non-trivial transformation, such as absolute to relative
+transformation for touchpads. Typical direct input devices: touchscreens,
+drawing tablets; non-direct devices: touchpads, mice.
+
+The INPUT_PROP_POINTER property indicates that the device is not transposed
+on the screen and thus requires use of an on-screen pointer to trace user's
+movements.  Typical pointer devices: touchpads, tablets, mice; non-pointer
+device: touchscreen.
+
+If neither INPUT_PROP_DIRECT or INPUT_PROP_POINTER are set, the property is
+considered undefined and the device type should be deduced in the
+traditional way, using emitted event types.
+
+INPUT_PROP_BUTTONPAD:
+--------------------
+For touchpads where the button is placed beneath the surface, such that
+pressing down on the pad causes a button click, this property should be
+set. Common in clickpad notebooks and macbooks from 2009 and onwards.
+
+Originally, the buttonpad property was coded into the bcm5974 driver
+version field under the name integrated button. For backwards
+compatibility, both methods need to be checked in userspace.
+
+INPUT_PROP_SEMI_MT:
+------------------
+Some touchpads, most common between 2008 and 2011, can detect the presence
+of multiple contacts without resolving the individual positions; only the
+number of contacts and a rectangular shape is known. For such
+touchpads, the semi-mt property should be set.
+
+Depending on the device, the rectangle may enclose all touches, like a
+bounding box, or just some of them, for instance the two most recent
+touches. The diversity makes the rectangle of limited use, but some
+gestures can normally be extracted from it.
+
+If INPUT_PROP_SEMI_MT is not set, the device is assumed to be a true MT
+device.
+
 Guidelines:
 ==========
 The guidelines below ensure proper single-touch and multi-finger functionality.
@@ -240,6 +290,8 @@ used to report when a touch is active on the screen.
 BTN_{MOUSE,LEFT,MIDDLE,RIGHT} must not be reported as the result of touch
 contact. BTN_TOOL_<name> events should be reported where possible.
 
+For new hardware, INPUT_PROP_DIRECT should be set.
+
 Trackpads:
 ----------
 Legacy trackpads that only provide relative position information must report
@@ -250,6 +302,8 @@ location of the touch. BTN_TOUCH should be used to report when a touch is active
 on the trackpad. Where multi-finger support is available, BTN_TOOL_<name> should
 be used to report the number of touches active on the trackpad.
 
+For new hardware, INPUT_PROP_POINTER should be set.
+
 Tablets:
 ----------
 BTN_TOOL_<name> events must be reported when a stylus or other tool is active on
@@ -260,3 +314,5 @@ button may be used for buttons on the tablet except BTN_{MOUSE,LEFT}.
 BTN_{0,1,2,etc} are good generic codes for unlabeled buttons. Do not use
 meaningful buttons, like BTN_FORWARD, unless the button is labeled for that
 purpose on the device.
+
+For new hardware, both INPUT_PROP_DIRECT and INPUT_PROP_POINTER should be set.
index 6727b92..150fd38 100644 (file)
@@ -857,42 +857,41 @@ case), we define a mapping like this:
 
 ...
 {
-       .name "2bit"
+       .name "2bit"
        .ctrl_dev_name = "pinctrl-foo",
        .function = "mmc0",
        .group = "mmc0_1_grp",
        .dev_name = "foo-mmc.0",
 },
 {
-       .name "4bit"
+       .name "4bit"
        .ctrl_dev_name = "pinctrl-foo",
        .function = "mmc0",
        .group = "mmc0_1_grp",
        .dev_name = "foo-mmc.0",
 },
 {
-       .name "4bit"
+       .name "4bit"
        .ctrl_dev_name = "pinctrl-foo",
        .function = "mmc0",
        .group = "mmc0_2_grp",
        .dev_name = "foo-mmc.0",
 },
 {
-       .name "8bit"
+       .name "8bit"
        .ctrl_dev_name = "pinctrl-foo",
-       .function = "mmc0",
        .group = "mmc0_1_grp",
        .dev_name = "foo-mmc.0",
 },
 {
-       .name "8bit"
+       .name "8bit"
        .ctrl_dev_name = "pinctrl-foo",
        .function = "mmc0",
        .group = "mmc0_2_grp",
        .dev_name = "foo-mmc.0",
 },
 {
-       .name "8bit"
+       .name "8bit"
        .ctrl_dev_name = "pinctrl-foo",
        .function = "mmc0",
        .group = "mmc0_3_grp",
@@ -995,7 +994,7 @@ This is enabled by simply setting the .hog_on_boot field in the map to true,
 like this:
 
 {
-       .name "POWERMAP"
+       .name "POWERMAP"
        .ctrl_dev_name = "pinctrl-foo",
        .function = "power_func",
        .hog_on_boot = true,
@@ -1025,7 +1024,7 @@ it, disables and releases it, and muxes it in on the pins defined by group B:
 
 foo_switch()
 {
-       struct pinmux pmx;
+       struct pinmux *pmx;
 
        /* Enable on position A */
        pmx = pinmux_get(&device, "spi0-pos-A");
index 21fd05c..f0ab5cf 100644 (file)
@@ -25,7 +25,8 @@ Procedure for submitting patches to the -stable tree:
 
  - Send the patch, after verifying that it follows the above rules, to
    stable@vger.kernel.org.  You must note the upstream commit ID in the
-   changelog of your submission.
+   changelog of your submission, as well as the kernel version you wish
+   it to be applied to.
  - To have the patch automatically included in the stable tree, add the tag
      Cc: stable@vger.kernel.org
    in the sign-off area. Once the patch is merged it will be applied to
index 8c20fbd..6d78841 100644 (file)
@@ -601,6 +601,8 @@ can be ORed together:
         instead of using the one provided by the hardware.
  512 - A kernel warning has occurred.
 1024 - A module from drivers/staging was loaded.
+2048 - The system is working around a severe firmware bug.
+4096 - An out-of-tree module has been loaded.
 
 ==============================================================
 
index 8e60199..924bd46 100644 (file)
@@ -4,8 +4,6 @@ Virtualization support in the Linux kernel.
        - this file.
 kvm/
        - Kernel Virtual Machine.  See also http://linux-kvm.org
-lguest/
-       - Extremely simple hypervisor for experimental/educational use.
 uml/
        - User Mode Linux, builds/runs Linux kernel as a userspace program.
 virtio.txt
index 1b6e835..9a648eb 100644 (file)
@@ -159,7 +159,7 @@ S:  Maintained
 F:     drivers/net/ethernet/realtek/r8169.c
 
 8250/16?50 (AND CLONE UARTS) SERIAL DRIVER
-M:     Greg Kroah-Hartman <gregkh@suse.de>
+M:     Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 L:     linux-serial@vger.kernel.org
 W:     http://serial.sourceforge.net
 S:     Maintained
@@ -789,12 +789,6 @@ F: arch/arm/mach-mx*/
 F:     arch/arm/mach-imx/
 F:     arch/arm/plat-mxc/
 
-ARM/FREESCALE IMX51
-M:     Amit Kucheria <amit.kucheria@canonical.com>
-L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
-S:     Maintained
-F:     arch/arm/mach-mx5/
-
 ARM/FREESCALE IMX6
 M:     Shawn Guo <shawn.guo@linaro.org>
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
@@ -1783,9 +1777,9 @@ X:        net/wireless/wext*
 
 CHAR and MISC DRIVERS
 M:     Arnd Bergmann <arnd@arndb.de>
-M:     Greg Kroah-Hartman <greg@kroah.com>
+M:     Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc.git
-S:     Maintained
+S:     Supported
 F:     drivers/char/*
 F:     drivers/misc/*
 
@@ -2287,7 +2281,7 @@ F:        drivers/acpi/dock.c
 DOCUMENTATION
 M:     Randy Dunlap <rdunlap@xenotime.net>
 L:     linux-doc@vger.kernel.org
-T:     quilt http://userweb.kernel.org/~rdunlap/kernel-doc-patches/current/
+T:     quilt http://xenotime.net/kernel-doc-patches/current/
 S:     Maintained
 F:     Documentation/
 
@@ -2320,7 +2314,7 @@ F:        lib/lru_cache.c
 F:     Documentation/blockdev/drbd/
 
 DRIVER CORE, KOBJECTS, DEBUGFS AND SYSFS
-M:     Greg Kroah-Hartman <gregkh@suse.de>
+M:     Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core-2.6.git
 S:     Supported
 F:     Documentation/kobject.txt
@@ -3324,6 +3318,12 @@ S:       Maintained
 F:     net/ieee802154/
 F:     drivers/ieee802154/
 
+IIO SUBSYSTEM AND DRIVERS
+M:     Jonathan Cameron <jic23@cam.ac.uk>
+L:     linux-iio@vger.kernel.org
+S:     Maintained
+F:     drivers/staging/iio/
+
 IKANOS/ADI EAGLE ADSL USB DRIVER
 M:     Matthieu Castet <castet.matthieu@free.fr>
 M:     Stanislaw Gruszka <stf_xl@wp.pl>
@@ -3992,11 +3992,11 @@ M:      Rusty Russell <rusty@rustcorp.com.au>
 L:     lguest@lists.ozlabs.org
 W:     http://lguest.ozlabs.org/
 S:     Odd Fixes
-F:     Documentation/virtual/lguest/
+F:     arch/x86/include/asm/lguest*.h
 F:     arch/x86/lguest/
 F:     drivers/lguest/
 F:     include/linux/lguest*.h
-F:     arch/x86/include/asm/lguest*.h
+F:     tools/lguest/
 
 LINUX FOR IBM pSERIES (RS/6000)
 M:     Paul Mackerras <paulus@au.ibm.com>
@@ -4136,10 +4136,11 @@ L:      linux-ntfs-dev@lists.sourceforge.net
 W:     http://www.linux-ntfs.org/content/view/19/37/
 S:     Maintained
 F:     Documentation/ldm.txt
-F:     fs/partitions/ldm.*
+F:     block/partitions/ldm.*
 
 LogFS
 M:     Joern Engel <joern@logfs.org>
+M:     Prasad Joshi <prasadjoshi.linux@gmail.com>
 L:     logfs@logfs.org
 W:     logfs.org
 S:     Maintained
@@ -4281,13 +4282,6 @@ S:       Orphan
 F:     drivers/video/matrox/matroxfb_*
 F:     include/linux/matroxfb.h
 
-MAX1668 TEMPERATURE SENSOR DRIVER
-M:     "David George" <david.george@ska.ac.za>
-L:     lm-sensors@lm-sensors.org
-S:     Maintained
-F:     Documentation/hwmon/max1668
-F:     drivers/hwmon/max1668.c
-
 MAX6650 HARDWARE MONITOR AND FAN CONTROLLER DRIVER
 M:     "Hans J. Koch" <hjk@hansjkoch.de>
 L:     lm-sensors@lm-sensors.org
@@ -5639,7 +5633,7 @@ W:        http://www.ibm.com/developerworks/linux/linux390/
 S:     Supported
 F:     arch/s390/
 F:     drivers/s390/
-F:     fs/partitions/ibm.c
+F:     block/partitions/ibm.c
 F:     Documentation/s390/
 F:     Documentation/DocBook/s390*
 
@@ -6282,15 +6276,15 @@ S:      Maintained
 F:     arch/alpha/kernel/srm_env.c
 
 STABLE BRANCH
-M:     Greg Kroah-Hartman <greg@kroah.com>
+M:     Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 L:     stable@vger.kernel.org
-S:     Maintained
+S:     Supported
 
 STAGING SUBSYSTEM
-M:     Greg Kroah-Hartman <gregkh@suse.de>
+M:     Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging.git
 L:     devel@driverdev.osuosl.org
-S:     Maintained
+S:     Supported
 F:     drivers/staging/
 
 STAGING - AGERE HERMES II and II.5 WIRELESS DRIVERS
@@ -6402,11 +6396,6 @@ M:       Omar Ramirez Luna <omar.ramirez@ti.com>
 S:     Odd Fixes
 F:     drivers/staging/tidspbridge/
 
-STAGING - TRIDENT TVMASTER TMxxxx USB VIDEO CAPTURE DRIVERS
-L:     linux-media@vger.kernel.org
-S:     Odd Fixes
-F:     drivers/staging/tm6000/
-
 STAGING - USB ENE SM/MS CARD READER DRIVER
 M:     Al Cho <acho@novell.com>
 S:     Odd Fixes
@@ -6675,10 +6664,10 @@ S:      Maintained
 K:     ^Subject:.*(?i)trivial
 
 TTY LAYER
-M:     Greg Kroah-Hartman <gregkh@suse.de>
-S:     Maintained
+M:     Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+S:     Supported
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty-2.6.git
-F:     drivers/tty/*
+F:     drivers/tty/
 F:     drivers/tty/serial/serial_core.c
 F:     include/linux/serial_core.h
 F:     include/linux/serial.h
@@ -6964,7 +6953,7 @@ S:        Maintained
 F:     drivers/usb/serial/digi_acceleport.c
 
 USB SERIAL DRIVER
-M:     Greg Kroah-Hartman <gregkh@suse.de>
+M:     Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 L:     linux-usb@vger.kernel.org
 S:     Supported
 F:     Documentation/usb/usb-serial.txt
@@ -6979,9 +6968,8 @@ S:        Maintained
 F:     drivers/usb/serial/empeg.c
 
 USB SERIAL KEYSPAN DRIVER
-M:     Greg Kroah-Hartman <greg@kroah.com>
+M:     Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 L:     linux-usb@vger.kernel.org
-W:     http://www.kroah.com/linux/
 S:     Maintained
 F:     drivers/usb/serial/*keyspan*
 
@@ -7009,7 +6997,7 @@ F:        Documentation/video4linux/sn9c102.txt
 F:     drivers/media/video/sn9c102/
 
 USB SUBSYSTEM
-M:     Greg Kroah-Hartman <gregkh@suse.de>
+M:     Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 L:     linux-usb@vger.kernel.org
 W:     http://www.linux-usb.org
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb-2.6.git
@@ -7096,7 +7084,7 @@ F:        fs/hppfs/
 
 USERSPACE I/O (UIO)
 M:     "Hans J. Koch" <hjk@hansjkoch.de>
-M:     Greg Kroah-Hartman <gregkh@suse.de>
+M:     Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 S:     Maintained
 F:     Documentation/DocBook/uio-howto.tmpl
 F:     drivers/uio/
@@ -7371,6 +7359,7 @@ S:        Supported
 F:     Documentation/hwmon/wm83??
 F:     arch/arm/mach-s3c64xx/mach-crag6410*
 F:     drivers/leds/leds-wm83*.c
+F:     drivers/hwmon/wm83??-hwmon.c
 F:     drivers/input/misc/wm831x-on.c
 F:     drivers/input/touchscreen/wm831x-ts.c
 F:     drivers/input/touchscreen/wm97*.c
index 71e6ed2..7c44b67 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 VERSION = 3
 PATCHLEVEL = 3
 SUBLEVEL = 0
-EXTRAVERSION = -rc1
+EXTRAVERSION = -rc3
 NAME = Saber-toothed Squirrel
 
 # *DOCUMENTATION*
index 24626b0..a48aecc 100644 (file)
@@ -754,7 +754,7 @@ config ARCH_SA1100
        select ARCH_HAS_CPUFREQ
        select CPU_FREQ
        select GENERIC_CLOCKEVENTS
-       select CLKDEV_LOOKUP
+       select HAVE_CLK
        select HAVE_SCHED_CLOCK
        select TICK_ONESHOT
        select ARCH_REQUIRE_GPIOLIB
@@ -825,7 +825,6 @@ config ARCH_S5PC100
        select HAVE_CLK
        select CLKDEV_LOOKUP
        select CPU_V7
-       select ARM_L1_CACHE_SHIFT_6
        select ARCH_USES_GETTIMEOFFSET
        select HAVE_S3C2410_I2C if I2C
        select HAVE_S3C_RTC if RTC_CLASS
@@ -842,7 +841,6 @@ config ARCH_S5PV210
        select HAVE_CLK
        select CLKDEV_LOOKUP
        select CLKSRC_MMIO
-       select ARM_L1_CACHE_SHIFT_6
        select ARCH_HAS_CPUFREQ
        select GENERIC_CLOCKEVENTS
        select HAVE_SCHED_CLOCK
index b2dc2dd..c47d619 100644 (file)
@@ -41,6 +41,7 @@
 
 #include <asm/irq.h>
 #include <asm/exception.h>
+#include <asm/smp_plat.h>
 #include <asm/mach/irq.h>
 #include <asm/hardware/gic.h>
 
@@ -352,11 +353,7 @@ static void __init gic_dist_init(struct gic_chip_data *gic)
        unsigned int gic_irqs = gic->gic_irqs;
        struct irq_domain *domain = &gic->domain;
        void __iomem *base = gic_data_dist_base(gic);
-       u32 cpu = 0;
-
-#ifdef CONFIG_SMP
-       cpu = cpu_logical_map(smp_processor_id());
-#endif
+       u32 cpu = cpu_logical_map(smp_processor_id());
 
        cpumask = 1 << cpu;
        cpumask |= cpumask << 8;
index b6e65de..62f8095 100644 (file)
  */
 #ifdef CONFIG_THUMB2_KERNEL
 
-       .macro  usraccoff, instr, reg, ptr, inc, off, cond, abort, t=T()
+       .macro  usraccoff, instr, reg, ptr, inc, off, cond, abort, t=TUSER()
 9999:
        .if     \inc == 1
        \instr\cond\()b\()\t\().w \reg, [\ptr, #\off]
 
 #else  /* !CONFIG_THUMB2_KERNEL */
 
-       .macro  usracc, instr, reg, ptr, inc, cond, rept, abort, t=T()
+       .macro  usracc, instr, reg, ptr, inc, cond, rept, abort, t=TUSER()
        .rept   \rept
 9999:
        .if     \inc == 1
index af18cea..b5dc173 100644 (file)
@@ -83,9 +83,9 @@
  * instructions (inline assembly)
  */
 #ifdef CONFIG_CPU_USE_DOMAINS
-#define T(instr)       #instr "t"
+#define TUSER(instr)   #instr "t"
 #else
-#define T(instr)       #instr
+#define TUSER(instr)   #instr
 #endif
 
 #else /* __ASSEMBLY__ */
@@ -95,9 +95,9 @@
  * instructions
  */
 #ifdef CONFIG_CPU_USE_DOMAINS
-#define T(instr)       instr ## t
+#define TUSER(instr)   instr ## t
 #else
-#define T(instr)       instr
+#define TUSER(instr)   instr
 #endif
 
 #endif /* __ASSEMBLY__ */
index 253cc86..7be5469 100644 (file)
@@ -75,9 +75,9 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
 
 #define __futex_atomic_op(insn, ret, oldval, tmp, uaddr, oparg)        \
        __asm__ __volatile__(                                   \
-       "1:     " T(ldr) "      %1, [%3]\n"                     \
+       "1:     " TUSER(ldr) "  %1, [%3]\n"                     \
        "       " insn "\n"                                     \
-       "2:     " T(str) "      %0, [%3]\n"                     \
+       "2:     " TUSER(str) "  %0, [%3]\n"                     \
        "       mov     %0, #0\n"                               \
        __futex_atomic_ex_table("%5")                           \
        : "=&r" (ret), "=&r" (oldval), "=&r" (tmp)              \
@@ -95,10 +95,10 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
                return -EFAULT;
 
        __asm__ __volatile__("@futex_atomic_cmpxchg_inatomic\n"
-       "1:     " T(ldr) "      %1, [%4]\n"
+       "1:     " TUSER(ldr) "  %1, [%4]\n"
        "       teq     %1, %2\n"
        "       it      eq      @ explicit IT needed for the 2b label\n"
-       "2:     " T(streq) "    %3, [%4]\n"
+       "2:     " TUSER(streq) "        %3, [%4]\n"
        __futex_atomic_ex_table("%5")
        : "+r" (ret), "=&r" (val)
        : "r" (oldval), "r" (newval), "r" (uaddr), "Ir" (-EFAULT)
index 1e5717a..ae29293 100644 (file)
@@ -70,12 +70,6 @@ extern void platform_secondary_init(unsigned int cpu);
  */
 extern void platform_smp_prepare_cpus(unsigned int);
 
-/*
- * Logical CPU mapping.
- */
-extern int __cpu_logical_map[NR_CPUS];
-#define cpu_logical_map(cpu)   __cpu_logical_map[cpu]
-
 /*
  * Initial data for bringing up a secondary CPU.
  */
index f24c1b9..558d6c8 100644 (file)
@@ -43,4 +43,10 @@ static inline int cache_ops_need_broadcast(void)
 }
 #endif
 
+/*
+ * Logical CPU mapping.
+ */
+extern int __cpu_logical_map[];
+#define cpu_logical_map(cpu)   __cpu_logical_map[cpu]
+
 #endif
index 5d3ed7e..314d466 100644 (file)
@@ -198,7 +198,15 @@ static inline void __pte_free_tlb(struct mmu_gather *tlb, pgtable_t pte,
        unsigned long addr)
 {
        pgtable_page_dtor(pte);
-       tlb_add_flush(tlb, addr);
+
+       /*
+        * With the classic ARM MMU, a pte page has two corresponding pmd
+        * entries, each covering 1MB.
+        */
+       addr &= PMD_MASK;
+       tlb_add_flush(tlb, addr + SZ_1M - PAGE_SIZE);
+       tlb_add_flush(tlb, addr + SZ_1M);
+
        tlb_remove_page(tlb, pte);
 }
 
index b293616..2958976 100644 (file)
@@ -227,7 +227,7 @@ do {                                                                        \
 
 #define __get_user_asm_byte(x,addr,err)                                \
        __asm__ __volatile__(                                   \
-       "1:     " T(ldrb) "     %1,[%2],#0\n"                   \
+       "1:     " TUSER(ldrb) " %1,[%2],#0\n"                   \
        "2:\n"                                                  \
        "       .pushsection .fixup,\"ax\"\n"                   \
        "       .align  2\n"                                    \
@@ -263,7 +263,7 @@ do {                                                                        \
 
 #define __get_user_asm_word(x,addr,err)                                \
        __asm__ __volatile__(                                   \
-       "1:     " T(ldr) "      %1,[%2],#0\n"                   \
+       "1:     " TUSER(ldr) "  %1,[%2],#0\n"                   \
        "2:\n"                                                  \
        "       .pushsection .fixup,\"ax\"\n"                   \
        "       .align  2\n"                                    \
@@ -308,7 +308,7 @@ do {                                                                        \
 
 #define __put_user_asm_byte(x,__pu_addr,err)                   \
        __asm__ __volatile__(                                   \
-       "1:     " T(strb) "     %1,[%2],#0\n"                   \
+       "1:     " TUSER(strb) " %1,[%2],#0\n"                   \
        "2:\n"                                                  \
        "       .pushsection .fixup,\"ax\"\n"                   \
        "       .align  2\n"                                    \
@@ -341,7 +341,7 @@ do {                                                                        \
 
 #define __put_user_asm_word(x,__pu_addr,err)                   \
        __asm__ __volatile__(                                   \
-       "1:     " T(str) "      %1,[%2],#0\n"                   \
+       "1:     " TUSER(str) "  %1,[%2],#0\n"                   \
        "2:\n"                                                  \
        "       .pushsection .fixup,\"ax\"\n"                   \
        "       .align  2\n"                                    \
@@ -366,10 +366,10 @@ do {                                                                      \
 
 #define __put_user_asm_dword(x,__pu_addr,err)                  \
        __asm__ __volatile__(                                   \
- ARM(  "1:     " T(str) "      " __reg_oper1 ", [%1], #4\n"    )       \
- ARM(  "2:     " T(str) "      " __reg_oper0 ", [%1]\n"        )       \
- THUMB(        "1:     " T(str) "      " __reg_oper1 ", [%1]\n"        )       \
- THUMB(        "2:     " T(str) "      " __reg_oper0 ", [%1, #4]\n"    )       \
+ ARM(  "1:     " TUSER(str) "  " __reg_oper1 ", [%1], #4\n"    ) \
+ ARM(  "2:     " TUSER(str) "  " __reg_oper0 ", [%1]\n"        ) \
+ THUMB(        "1:     " TUSER(str) "  " __reg_oper1 ", [%1]\n"        ) \
+ THUMB(        "2:     " TUSER(str) "  " __reg_oper0 ", [%1, #4]\n"    ) \
        "3:\n"                                                  \
        "       .pushsection .fixup,\"ax\"\n"                   \
        "       .align  2\n"                                    \
index 3a456c6..be16a48 100644 (file)
@@ -790,7 +790,7 @@ __kuser_cmpxchg64:                          @ 0xffff0f60
        smp_dmb arm
        rsbs    r0, r3, #0                      @ set returned val and C flag
        ldmfd   sp!, {r4, r5, r6, r7}
-       bx      lr
+       usr_ret lr
 
 #elif !defined(CONFIG_SMP)
 
index 520889c..9fd0ba9 100644 (file)
@@ -149,6 +149,11 @@ ENDPROC(ret_from_fork)
 #endif
 #endif
 
+.macro mcount_adjust_addr rd, rn
+       bic     \rd, \rn, #1            @ clear the Thumb bit if present
+       sub     \rd, \rd, #MCOUNT_INSN_SIZE
+.endm
+
 .macro __mcount suffix
        mcount_enter
        ldr     r0, =ftrace_trace_function
@@ -173,8 +178,7 @@ ENDPROC(ret_from_fork)
        mcount_exit
 
 1:     mcount_get_lr   r1                      @ lr of instrumented func
-       mov     r0, lr                          @ instrumented function
-       sub     r0, r0, #MCOUNT_INSN_SIZE
+       mcount_adjust_addr      r0, lr          @ instrumented function
        adr     lr, BSYM(2f)
        mov     pc, r2
 2:     mcount_exit
@@ -184,8 +188,7 @@ ENDPROC(ret_from_fork)
        mcount_enter
 
        mcount_get_lr   r1                      @ lr of instrumented func
-       mov     r0, lr                          @ instrumented function
-       sub     r0, r0, #MCOUNT_INSN_SIZE
+       mcount_adjust_addr      r0, lr          @ instrumented function
 
        .globl ftrace_call\suffix
 ftrace_call\suffix:
@@ -205,11 +208,11 @@ ftrace_graph_call\suffix:
 #ifdef CONFIG_DYNAMIC_FTRACE
        @ called from __ftrace_caller, saved in mcount_enter
        ldr     r1, [sp, #16]           @ instrumented routine (func)
+       mcount_adjust_addr      r1, r1
 #else
        @ called from __mcount, untouched in lr
-       mov     r1, lr                  @ instrumented routine (func)
+       mcount_adjust_addr      r1, lr  @ instrumented routine (func)
 #endif
-       sub     r1, r1, #MCOUNT_INSN_SIZE
        mov     r2, fp                  @ frame pointer
        bl      prepare_ftrace_return
        mcount_exit
index 460bbbb..6933244 100644 (file)
@@ -469,6 +469,20 @@ static const unsigned armv7_a5_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
                        [C(RESULT_MISS)]        = CACHE_OP_UNSUPPORTED,
                },
        },
+       [C(NODE)] = {
+               [C(OP_READ)] = {
+                       [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
+                       [C(RESULT_MISS)]        = CACHE_OP_UNSUPPORTED,
+               },
+               [C(OP_WRITE)] = {
+                       [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
+                       [C(RESULT_MISS)]        = CACHE_OP_UNSUPPORTED,
+               },
+               [C(OP_PREFETCH)] = {
+                       [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
+                       [C(RESULT_MISS)]        = CACHE_OP_UNSUPPORTED,
+               },
+       },
 };
 
 /*
@@ -579,6 +593,20 @@ static const unsigned armv7_a15_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
                        [C(RESULT_MISS)]        = CACHE_OP_UNSUPPORTED,
                },
        },
+       [C(NODE)] = {
+               [C(OP_READ)] = {
+                       [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
+                       [C(RESULT_MISS)]        = CACHE_OP_UNSUPPORTED,
+               },
+               [C(OP_WRITE)] = {
+                       [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
+                       [C(RESULT_MISS)]        = CACHE_OP_UNSUPPORTED,
+               },
+               [C(OP_PREFETCH)] = {
+                       [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
+                       [C(RESULT_MISS)]        = CACHE_OP_UNSUPPORTED,
+               },
+       },
 };
 
 /*
index e1d5e19..e33870f 100644 (file)
@@ -699,10 +699,13 @@ static int vfp_set(struct task_struct *target,
 {
        int ret;
        struct thread_info *thread = task_thread_info(target);
-       struct vfp_hard_struct new_vfp = thread->vfpstate.hard;
+       struct vfp_hard_struct new_vfp;
        const size_t user_fpregs_offset = offsetof(struct user_vfp, fpregs);
        const size_t user_fpscr_offset = offsetof(struct user_vfp, fpscr);
 
+       vfp_sync_hwstate(thread);
+       new_vfp = thread->vfpstate.hard;
+
        ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
                                  &new_vfp.fpregs,
                                  user_fpregs_offset,
@@ -723,9 +726,8 @@ static int vfp_set(struct task_struct *target,
        if (ret)
                return ret;
 
-       vfp_sync_hwstate(thread);
-       thread->vfpstate.hard = new_vfp;
        vfp_flush_hwstate(thread);
+       thread->vfpstate.hard = new_vfp;
 
        return 0;
 }
index 129fbd5..a255c39 100644 (file)
@@ -21,7 +21,6 @@
 #include <linux/init.h>
 #include <linux/kexec.h>
 #include <linux/of_fdt.h>
-#include <linux/crash_dump.h>
 #include <linux/root_dev.h>
 #include <linux/cpu.h>
 #include <linux/interrupt.h>
@@ -160,7 +159,7 @@ static struct resource mem_res[] = {
                .flags = IORESOURCE_MEM
        },
        {
-               .name = "Kernel text",
+               .name = "Kernel code",
                .start = 0,
                .end = 0,
                .flags = IORESOURCE_MEM
@@ -427,6 +426,20 @@ void cpu_init(void)
            : "r14");
 }
 
+int __cpu_logical_map[NR_CPUS];
+
+void __init smp_setup_processor_id(void)
+{
+       int i;
+       u32 cpu = is_smp() ? read_cpuid_mpidr() & 0xff : 0;
+
+       cpu_logical_map(0) = cpu;
+       for (i = 1; i < NR_CPUS; ++i)
+               cpu_logical_map(i) = i == cpu ? 0 : i;
+
+       printk(KERN_INFO "Booting Linux on physical CPU %d\n", cpu);
+}
+
 static void __init setup_processor(void)
 {
        struct proc_info_list *list;
index 0340224..9e617bd 100644 (file)
@@ -227,6 +227,8 @@ static int restore_vfp_context(struct vfp_sigframe __user *frame)
        if (magic != VFP_MAGIC || size != VFP_STORAGE_SIZE)
                return -EINVAL;
 
+       vfp_flush_hwstate(thread);
+
        /*
         * Copy the floating point registers. There can be unused
         * registers see asm/hwcap.h for details.
@@ -251,9 +253,6 @@ static int restore_vfp_context(struct vfp_sigframe __user *frame)
        __get_user_error(h->fpinst, &frame->ufp_exc.fpinst, err);
        __get_user_error(h->fpinst2, &frame->ufp_exc.fpinst2, err);
 
-       if (!err)
-               vfp_flush_hwstate(thread);
-
        return err ? -EFAULT : 0;
 }
 
index 57db122..cdeb727 100644 (file)
@@ -233,20 +233,6 @@ void __ref cpu_die(void)
 }
 #endif /* CONFIG_HOTPLUG_CPU */
 
-int __cpu_logical_map[NR_CPUS];
-
-void __init smp_setup_processor_id(void)
-{
-       int i;
-       u32 cpu = is_smp() ? read_cpuid_mpidr() & 0xff : 0;
-
-       cpu_logical_map(0) = cpu;
-       for (i = 1; i < NR_CPUS; ++i)
-               cpu_logical_map(i) = i == cpu ? 0 : i;
-
-       printk(KERN_INFO "Booting Linux on physical CPU %d\n", cpu);
-}
-
 /*
  * Called by both boot and secondaries to move global data into
  * per-processor storage.
@@ -443,9 +429,7 @@ static DEFINE_PER_CPU(struct clock_event_device, percpu_clockevent);
 static void ipi_timer(void)
 {
        struct clock_event_device *evt = &__get_cpu_var(percpu_clockevent);
-       irq_enter();
        evt->event_handler(evt);
-       irq_exit();
 }
 
 #ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST
@@ -548,7 +532,9 @@ void handle_IPI(int ipinr, struct pt_regs *regs)
 
        switch (ipinr) {
        case IPI_TIMER:
+               irq_enter();
                ipi_timer();
+               irq_exit();
                break;
 
        case IPI_RESCHEDULE:
@@ -556,15 +542,21 @@ void handle_IPI(int ipinr, struct pt_regs *regs)
                break;
 
        case IPI_CALL_FUNC:
+               irq_enter();
                generic_smp_call_function_interrupt();
+               irq_exit();
                break;
 
        case IPI_CALL_FUNC_SINGLE:
+               irq_enter();
                generic_smp_call_function_single_interrupt();
+               irq_exit();
                break;
 
        case IPI_CPU_STOP:
+               irq_enter();
                ipi_cpu_stop(cpu);
+               irq_exit();
                break;
 
        default:
index c8e9385..4285daa 100644 (file)
@@ -252,6 +252,8 @@ void __cpuinit twd_timer_setup(struct clock_event_device *clk)
        else
                twd_calibrate_rate();
 
+       __raw_writel(0, twd_base + TWD_TIMER_CONTROL);
+
        clk->name = "local_timer";
        clk->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT |
                        CLOCK_EVT_FEAT_C3STOP;
index 99a5727..f84dfe6 100644 (file)
@@ -266,6 +266,7 @@ void die(const char *str, struct pt_regs *regs, int err)
 {
        struct thread_info *thread = current_thread_info();
        int ret;
+       enum bug_trap_type bug_type = BUG_TRAP_TYPE_NONE;
 
        oops_enter();
 
@@ -273,7 +274,9 @@ void die(const char *str, struct pt_regs *regs, int err)
        console_verbose();
        bust_spinlocks(1);
        if (!user_mode(regs))
-               report_bug(regs->ARM_pc, regs);
+               bug_type = report_bug(regs->ARM_pc, regs);
+       if (bug_type != BUG_TRAP_TYPE_NONE)
+               str = "Oops - BUG";
        ret = __die(str, err, thread, regs);
 
        if (regs && kexec_should_crash(thread->task))
index f76e755..43a31fb 100644 (file)
@@ -4,11 +4,13 @@
  */
 
 #include <asm-generic/vmlinux.lds.h>
+#include <asm/cache.h>
 #include <asm/thread_info.h>
 #include <asm/memory.h>
 #include <asm/page.h>
        
 #define PROC_INFO                                                      \
+       . = ALIGN(4);                                                   \
        VMLINUX_SYMBOL(__proc_info_begin) = .;                          \
        *(.proc.info.init)                                              \
        VMLINUX_SYMBOL(__proc_info_end) = .;
@@ -181,7 +183,7 @@ SECTIONS
        }
 #endif
 
-       PERCPU_SECTION(32)
+       PERCPU_SECTION(L1_CACHE_BYTES)
 
 #ifdef CONFIG_XIP_KERNEL
        __data_loc = ALIGN(4);          /* location in binary */
@@ -212,13 +214,13 @@ SECTIONS
 #endif
 
                NOSAVE_DATA
-               CACHELINE_ALIGNED_DATA(32)
-               READ_MOSTLY_DATA(32)
+               CACHELINE_ALIGNED_DATA(L1_CACHE_BYTES)
+               READ_MOSTLY_DATA(L1_CACHE_BYTES)
 
                /*
                 * The exception fixup table (might need resorting at runtime)
                 */
-               . = ALIGN(32);
+               . = ALIGN(4);
                __start___ex_table = .;
 #ifdef CONFIG_MMU
                *(__ex_table)
index 1b049cd..11093a7 100644 (file)
 #include <asm/domain.h>
 
 ENTRY(__get_user_1)
-1:     T(ldrb) r2, [r0]
+1: TUSER(ldrb) r2, [r0]
        mov     r0, #0
        mov     pc, lr
 ENDPROC(__get_user_1)
 
 ENTRY(__get_user_2)
 #ifdef CONFIG_THUMB2_KERNEL
-2:     T(ldrb) r2, [r0]
-3:     T(ldrb) r3, [r0, #1]
+2: TUSER(ldrb) r2, [r0]
+3: TUSER(ldrb) r3, [r0, #1]
 #else
-2:     T(ldrb) r2, [r0], #1
-3:     T(ldrb) r3, [r0]
+2: TUSER(ldrb) r2, [r0], #1
+3: TUSER(ldrb) r3, [r0]
 #endif
 #ifndef __ARMEB__
        orr     r2, r2, r3, lsl #8
@@ -54,7 +54,7 @@ ENTRY(__get_user_2)
 ENDPROC(__get_user_2)
 
 ENTRY(__get_user_4)
-4:     T(ldr)  r2, [r0]
+4: TUSER(ldr)  r2, [r0]
        mov     r0, #0
        mov     pc, lr
 ENDPROC(__get_user_4)
index c023fc1..7db2599 100644 (file)
@@ -31,7 +31,7 @@
 #include <asm/domain.h>
 
 ENTRY(__put_user_1)
-1:     T(strb) r2, [r0]
+1: TUSER(strb) r2, [r0]
        mov     r0, #0
        mov     pc, lr
 ENDPROC(__put_user_1)
@@ -40,19 +40,19 @@ ENTRY(__put_user_2)
        mov     ip, r2, lsr #8
 #ifdef CONFIG_THUMB2_KERNEL
 #ifndef __ARMEB__
-2:     T(strb) r2, [r0]
-3:     T(strb) ip, [r0, #1]
+2: TUSER(strb) r2, [r0]
+3: TUSER(strb) ip, [r0, #1]
 #else
-2:     T(strb) ip, [r0]
-3:     T(strb) r2, [r0, #1]
+2: TUSER(strb) ip, [r0]
+3: TUSER(strb) r2, [r0, #1]
 #endif
 #else  /* !CONFIG_THUMB2_KERNEL */
 #ifndef __ARMEB__
-2:     T(strb) r2, [r0], #1
-3:     T(strb) ip, [r0]
+2: TUSER(strb) r2, [r0], #1
+3: TUSER(strb) ip, [r0]
 #else
-2:     T(strb) ip, [r0], #1
-3:     T(strb) r2, [r0]
+2: TUSER(strb) ip, [r0], #1
+3: TUSER(strb) r2, [r0]
 #endif
 #endif /* CONFIG_THUMB2_KERNEL */
        mov     r0, #0
@@ -60,18 +60,18 @@ ENTRY(__put_user_2)
 ENDPROC(__put_user_2)
 
 ENTRY(__put_user_4)
-4:     T(str)  r2, [r0]
+4: TUSER(str)  r2, [r0]
        mov     r0, #0
        mov     pc, lr
 ENDPROC(__put_user_4)
 
 ENTRY(__put_user_8)
 #ifdef CONFIG_THUMB2_KERNEL
-5:     T(str)  r2, [r0]
-6:     T(str)  r3, [r0, #4]
+5: TUSER(str)  r2, [r0]
+6: TUSER(str)  r3, [r0, #4]
 #else
-5:     T(str)  r2, [r0], #4
-6:     T(str)  r3, [r0]
+5: TUSER(str)  r2, [r0], #4
+6: TUSER(str)  r3, [r0]
 #endif
        mov     r0, #0
        mov     pc, lr
index d0ece2a..5c908b1 100644 (file)
                rsb     ip, ip, #4
                cmp     ip, #2
                ldrb    r3, [r1], #1
-USER(          T(strb) r3, [r0], #1)                   @ May fault
+USER(  TUSER(  strb)   r3, [r0], #1)                   @ May fault
                ldrgeb  r3, [r1], #1
-USER(          T(strgeb) r3, [r0], #1)                 @ May fault
+USER(  TUSER(  strgeb) r3, [r0], #1)                   @ May fault
                ldrgtb  r3, [r1], #1
-USER(          T(strgtb) r3, [r0], #1)                 @ May fault
+USER(  TUSER(  strgtb) r3, [r0], #1)                   @ May fault
                sub     r2, r2, ip
                b       .Lc2u_dest_aligned
 
@@ -59,7 +59,7 @@ ENTRY(__copy_to_user)
                addmi   ip, r2, #4
                bmi     .Lc2u_0nowords
                ldr     r3, [r1], #4
-USER(          T(str)  r3, [r0], #4)                   @ May fault
+USER(  TUSER(  str)    r3, [r0], #4)                   @ May fault
                mov     ip, r0, lsl #32 - PAGE_SHIFT    @ On each page, use a ld/st??t instruction
                rsb     ip, ip, #0
                movs    ip, ip, lsr #32 - PAGE_SHIFT
@@ -88,18 +88,18 @@ USER(               T(str)  r3, [r0], #4)                   @ May fault
                stmneia r0!, {r3 - r4}                  @ Shouldnt fault
                tst     ip, #4
                ldrne   r3, [r1], #4
-               T(strne) r3, [r0], #4                   @ Shouldnt fault
+       TUSER(  strne) r3, [r0], #4                     @ Shouldnt fault
                ands    ip, ip, #3
                beq     .Lc2u_0fupi
 .Lc2u_0nowords:        teq     ip, #0
                beq     .Lc2u_finished
 .Lc2u_nowords: cmp     ip, #2
                ldrb    r3, [r1], #1
-USER(          T(strb) r3, [r0], #1)                   @ May fault
+USER(  TUSER(  strb)   r3, [r0], #1)                   @ May fault
                ldrgeb  r3, [r1], #1
-USER(          T(strgeb) r3, [r0], #1)                 @ May fault
+USER(  TUSER(  strgeb) r3, [r0], #1)                   @ May fault
                ldrgtb  r3, [r1], #1
-USER(          T(strgtb) r3, [r0], #1)                 @ May fault
+USER(  TUSER(  strgtb) r3, [r0], #1)                   @ May fault
                b       .Lc2u_finished
 
 .Lc2u_not_enough:
@@ -120,7 +120,7 @@ USER(               T(strgtb) r3, [r0], #1)                 @ May fault
                mov     r3, r7, pull #8
                ldr     r7, [r1], #4
                orr     r3, r3, r7, push #24
-USER(          T(str)  r3, [r0], #4)                   @ May fault
+USER(  TUSER(  str)    r3, [r0], #4)                   @ May fault
                mov     ip, r0, lsl #32 - PAGE_SHIFT
                rsb     ip, ip, #0
                movs    ip, ip, lsr #32 - PAGE_SHIFT
@@ -155,18 +155,18 @@ USER(             T(str)  r3, [r0], #4)                   @ May fault
                movne   r3, r7, pull #8
                ldrne   r7, [r1], #4
                orrne   r3, r3, r7, push #24
-               T(strne) r3, [r0], #4                   @ Shouldnt fault
+       TUSER(  strne) r3, [r0], #4                     @ Shouldnt fault
                ands    ip, ip, #3
                beq     .Lc2u_1fupi
 .Lc2u_1nowords:        mov     r3, r7, get_byte_1
                teq     ip, #0
                beq     .Lc2u_finished
                cmp     ip, #2
-USER(          T(strb) r3, [r0], #1)                   @ May fault
+USER(  TUSER(  strb)   r3, [r0], #1)                   @ May fault
                movge   r3, r7, get_byte_2
-USER(          T(strgeb) r3, [r0], #1)                 @ May fault
+USER(  TUSER(  strgeb) r3, [r0], #1)                   @ May fault
                movgt   r3, r7, get_byte_3
-USER(          T(strgtb) r3, [r0], #1)                 @ May fault
+USER(  TUSER(  strgtb) r3, [r0], #1)                   @ May fault
                b       .Lc2u_finished
 
 .Lc2u_2fupi:   subs    r2, r2, #4
@@ -175,7 +175,7 @@ USER(               T(strgtb) r3, [r0], #1)                 @ May fault
                mov     r3, r7, pull #16
                ldr     r7, [r1], #4
                orr     r3, r3, r7, push #16
-USER(          T(str)  r3, [r0], #4)                   @ May fault
+USER(  TUSER(  str)    r3, [r0], #4)                   @ May fault
                mov     ip, r0, lsl #32 - PAGE_SHIFT
                rsb     ip, ip, #0
                movs    ip, ip, lsr #32 - PAGE_SHIFT
@@ -210,18 +210,18 @@ USER(             T(str)  r3, [r0], #4)                   @ May fault
                movne   r3, r7, pull #16
                ldrne   r7, [r1], #4
                orrne   r3, r3, r7, push #16
-               T(strne) r3, [r0], #4                   @ Shouldnt fault
+       TUSER(  strne) r3, [r0], #4                     @ Shouldnt fault
                ands    ip, ip, #3
                beq     .Lc2u_2fupi
 .Lc2u_2nowords:        mov     r3, r7, get_byte_2
                teq     ip, #0
                beq     .Lc2u_finished
                cmp     ip, #2
-USER(          T(strb) r3, [r0], #1)                   @ May fault
+USER(  TUSER(  strb)   r3, [r0], #1)                   @ May fault
                movge   r3, r7, get_byte_3
-USER(          T(strgeb) r3, [r0], #1)                 @ May fault
+USER(  TUSER(  strgeb) r3, [r0], #1)                   @ May fault
                ldrgtb  r3, [r1], #0
-USER(          T(strgtb) r3, [r0], #1)                 @ May fault
+USER(  TUSER(  strgtb) r3, [r0], #1)                   @ May fault
                b       .Lc2u_finished
 
 .Lc2u_3fupi:   subs    r2, r2, #4
@@ -230,7 +230,7 @@ USER(               T(strgtb) r3, [r0], #1)                 @ May fault
                mov     r3, r7, pull #24
                ldr     r7, [r1], #4
                orr     r3, r3, r7, push #8
-USER(          T(str)  r3, [r0], #4)                   @ May fault
+USER(  TUSER(  str)    r3, [r0], #4)                   @ May fault
                mov     ip, r0, lsl #32 - PAGE_SHIFT
                rsb     ip, ip, #0
                movs    ip, ip, lsr #32 - PAGE_SHIFT
@@ -265,18 +265,18 @@ USER(             T(str)  r3, [r0], #4)                   @ May fault
                movne   r3, r7, pull #24
                ldrne   r7, [r1], #4
                orrne   r3, r3, r7, push #8
-               T(strne) r3, [r0], #4                   @ Shouldnt fault
+       TUSER(  strne) r3, [r0], #4                     @ Shouldnt fault
                ands    ip, ip, #3
                beq     .Lc2u_3fupi
 .Lc2u_3nowords:        mov     r3, r7, get_byte_3
                teq     ip, #0
                beq     .Lc2u_finished
                cmp     ip, #2
-USER(          T(strb) r3, [r0], #1)                   @ May fault
+USER(  TUSER(  strb)   r3, [r0], #1)                   @ May fault
                ldrgeb  r3, [r1], #1
-USER(          T(strgeb) r3, [r0], #1)                 @ May fault
+USER(  TUSER(  strgeb) r3, [r0], #1)                   @ May fault
                ldrgtb  r3, [r1], #0
-USER(          T(strgtb) r3, [r0], #1)                 @ May fault
+USER(  TUSER(  strgtb) r3, [r0], #1)                   @ May fault
                b       .Lc2u_finished
 ENDPROC(__copy_to_user)
 
@@ -295,11 +295,11 @@ ENDPROC(__copy_to_user)
 .Lcfu_dest_not_aligned:
                rsb     ip, ip, #4
                cmp     ip, #2
-USER(          T(ldrb) r3, [r1], #1)                   @ May fault
+USER(  TUSER(  ldrb)   r3, [r1], #1)                   @ May fault
                strb    r3, [r0], #1
-USER(          T(ldrgeb) r3, [r1], #1)                 @ May fault
+USER(  TUSER(  ldrgeb) r3, [r1], #1)                   @ May fault
                strgeb  r3, [r0], #1
-USER(          T(ldrgtb) r3, [r1], #1)                 @ May fault
+USER(  TUSER(  ldrgtb) r3, [r1], #1)                   @ May fault
                strgtb  r3, [r0], #1
                sub     r2, r2, ip
                b       .Lcfu_dest_aligned
@@ -322,7 +322,7 @@ ENTRY(__copy_from_user)
 .Lcfu_0fupi:   subs    r2, r2, #4
                addmi   ip, r2, #4
                bmi     .Lcfu_0nowords
-USER(          T(ldr)  r3, [r1], #4)
+USER(  TUSER(  ldr)    r3, [r1], #4)
                str     r3, [r0], #4
                mov     ip, r1, lsl #32 - PAGE_SHIFT    @ On each page, use a ld/st??t instruction
                rsb     ip, ip, #0
@@ -351,18 +351,18 @@ USER(             T(ldr)  r3, [r1], #4)
                ldmneia r1!, {r3 - r4}                  @ Shouldnt fault
                stmneia r0!, {r3 - r4}
                tst     ip, #4
-               T(ldrne) r3, [r1], #4                   @ Shouldnt fault
+       TUSER(  ldrne) r3, [r1], #4                     @ Shouldnt fault
                strne   r3, [r0], #4
                ands    ip, ip, #3
                beq     .Lcfu_0fupi
 .Lcfu_0nowords:        teq     ip, #0
                beq     .Lcfu_finished
 .Lcfu_nowords: cmp     ip, #2
-USER(          T(ldrb) r3, [r1], #1)                   @ May fault
+USER(  TUSER(  ldrb)   r3, [r1], #1)                   @ May fault
                strb    r3, [r0], #1
-USER(          T(ldrgeb) r3, [r1], #1)                 @ May fault
+USER(  TUSER(  ldrgeb) r3, [r1], #1)                   @ May fault
                strgeb  r3, [r0], #1
-USER(          T(ldrgtb) r3, [r1], #1)                 @ May fault
+USER(  TUSER(  ldrgtb) r3, [r1], #1)                   @ May fault
                strgtb  r3, [r0], #1
                b       .Lcfu_finished
 
@@ -375,7 +375,7 @@ USER(               T(ldrgtb) r3, [r1], #1)                 @ May fault
 
 .Lcfu_src_not_aligned:
                bic     r1, r1, #3
-USER(          T(ldr)  r7, [r1], #4)                   @ May fault
+USER(  TUSER(  ldr)    r7, [r1], #4)                   @ May fault
                cmp     ip, #2
                bgt     .Lcfu_3fupi
                beq     .Lcfu_2fupi
@@ -383,7 +383,7 @@ USER(               T(ldr)  r7, [r1], #4)                   @ May fault
                addmi   ip, r2, #4
                bmi     .Lcfu_1nowords
                mov     r3, r7, pull #8
-USER(          T(ldr)  r7, [r1], #4)                   @ May fault
+USER(  TUSER(  ldr)    r7, [r1], #4)                   @ May fault
                orr     r3, r3, r7, push #24
                str     r3, [r0], #4
                mov     ip, r1, lsl #32 - PAGE_SHIFT
@@ -418,7 +418,7 @@ USER(               T(ldr)  r7, [r1], #4)                   @ May fault
                stmneia r0!, {r3 - r4}
                tst     ip, #4
                movne   r3, r7, pull #8
-USER(          T(ldrne) r7, [r1], #4)                  @ May fault
+USER(  TUSER(  ldrne) r7, [r1], #4)                    @ May fault
                orrne   r3, r3, r7, push #24
                strne   r3, [r0], #4
                ands    ip, ip, #3
@@ -438,7 +438,7 @@ USER(               T(ldrne) r7, [r1], #4)                  @ May fault
                addmi   ip, r2, #4
                bmi     .Lcfu_2nowords
                mov     r3, r7, pull #16
-USER(          T(ldr)  r7, [r1], #4)                   @ May fault
+USER(  TUSER(  ldr)    r7, [r1], #4)                   @ May fault
                orr     r3, r3, r7, push #16
                str     r3, [r0], #4
                mov     ip, r1, lsl #32 - PAGE_SHIFT
@@ -474,7 +474,7 @@ USER(               T(ldr)  r7, [r1], #4)                   @ May fault
                stmneia r0!, {r3 - r4}
                tst     ip, #4
                movne   r3, r7, pull #16
-USER(          T(ldrne) r7, [r1], #4)                  @ May fault
+USER(  TUSER(  ldrne) r7, [r1], #4)                    @ May fault
                orrne   r3, r3, r7, push #16
                strne   r3, [r0], #4
                ands    ip, ip, #3
@@ -486,7 +486,7 @@ USER(               T(ldrne) r7, [r1], #4)                  @ May fault
                strb    r3, [r0], #1
                movge   r3, r7, get_byte_3
                strgeb  r3, [r0], #1
-USER(          T(ldrgtb) r3, [r1], #0)                 @ May fault
+USER(  TUSER(  ldrgtb) r3, [r1], #0)                   @ May fault
                strgtb  r3, [r0], #1
                b       .Lcfu_finished
 
@@ -494,7 +494,7 @@ USER(               T(ldrgtb) r3, [r1], #0)                 @ May fault
                addmi   ip, r2, #4
                bmi     .Lcfu_3nowords
                mov     r3, r7, pull #24
-USER(          T(ldr)  r7, [r1], #4)                   @ May fault
+USER(  TUSER(  ldr)    r7, [r1], #4)                   @ May fault
                orr     r3, r3, r7, push #8
                str     r3, [r0], #4
                mov     ip, r1, lsl #32 - PAGE_SHIFT
@@ -529,7 +529,7 @@ USER(               T(ldr)  r7, [r1], #4)                   @ May fault
                stmneia r0!, {r3 - r4}
                tst     ip, #4
                movne   r3, r7, pull #24
-USER(          T(ldrne) r7, [r1], #4)                  @ May fault
+USER(  TUSER(  ldrne) r7, [r1], #4)                    @ May fault
                orrne   r3, r3, r7, push #8
                strne   r3, [r0], #4
                ands    ip, ip, #3
@@ -539,9 +539,9 @@ USER(               T(ldrne) r7, [r1], #4)                  @ May fault
                beq     .Lcfu_finished
                cmp     ip, #2
                strb    r3, [r0], #1
-USER(          T(ldrgeb) r3, [r1], #1)                 @ May fault
+USER(  TUSER(  ldrgeb) r3, [r1], #1)                   @ May fault
                strgeb  r3, [r0], #1
-USER(          T(ldrgtb) r3, [r1], #1)                 @ May fault
+USER(  TUSER(  ldrgtb) r3, [r1], #1)                   @ May fault
                strgtb  r3, [r0], #1
                b       .Lcfu_finished
 ENDPROC(__copy_from_user)
index 4f991f2..71feb00 100644 (file)
@@ -18,6 +18,12 @@ config HAVE_AT91_USART4
 config HAVE_AT91_USART5
        bool
 
+config AT91_SAM9_ALT_RESET
+       bool
+
+config AT91_SAM9G45_RESET
+       bool
+
 menu "Atmel AT91 System-on-Chip"
 
 choice
@@ -39,6 +45,7 @@ config ARCH_AT91SAM9260
        select HAVE_AT91_USART4
        select HAVE_AT91_USART5
        select HAVE_NET_MACB
+       select AT91_SAM9_ALT_RESET
 
 config ARCH_AT91SAM9261
        bool "AT91SAM9261"
@@ -46,6 +53,7 @@ config ARCH_AT91SAM9261
        select GENERIC_CLOCKEVENTS
        select HAVE_FB_ATMEL
        select HAVE_AT91_DBGU0
+       select AT91_SAM9_ALT_RESET
 
 config ARCH_AT91SAM9G10
        bool "AT91SAM9G10"
@@ -53,6 +61,7 @@ config ARCH_AT91SAM9G10
        select GENERIC_CLOCKEVENTS
        select HAVE_AT91_DBGU0
        select HAVE_FB_ATMEL
+       select AT91_SAM9_ALT_RESET
 
 config ARCH_AT91SAM9263
        bool "AT91SAM9263"
@@ -61,6 +70,7 @@ config ARCH_AT91SAM9263
        select HAVE_FB_ATMEL
        select HAVE_NET_MACB
        select HAVE_AT91_DBGU1
+       select AT91_SAM9_ALT_RESET
 
 config ARCH_AT91SAM9RL
        bool "AT91SAM9RL"
@@ -69,6 +79,7 @@ config ARCH_AT91SAM9RL
        select HAVE_AT91_USART3
        select HAVE_FB_ATMEL
        select HAVE_AT91_DBGU0
+       select AT91_SAM9_ALT_RESET
 
 config ARCH_AT91SAM9G20
        bool "AT91SAM9G20"
@@ -79,6 +90,7 @@ config ARCH_AT91SAM9G20
        select HAVE_AT91_USART4
        select HAVE_AT91_USART5
        select HAVE_NET_MACB
+       select AT91_SAM9_ALT_RESET
 
 config ARCH_AT91SAM9G45
        bool "AT91SAM9G45"
@@ -88,6 +100,7 @@ config ARCH_AT91SAM9G45
        select HAVE_FB_ATMEL
        select HAVE_NET_MACB
        select HAVE_AT91_DBGU1
+       select AT91_SAM9G45_RESET
 
 config ARCH_AT91CAP9
        bool "AT91CAP9"
@@ -96,6 +109,7 @@ config ARCH_AT91CAP9
        select HAVE_FB_ATMEL
        select HAVE_NET_MACB
        select HAVE_AT91_DBGU1
+       select AT91_SAM9G45_RESET
 
 config ARCH_AT91X40
        bool "AT91x40"
index 242174f..705e1fb 100644 (file)
@@ -8,15 +8,17 @@ obj-n         :=
 obj-           :=
 
 obj-$(CONFIG_AT91_PMC_UNIT)    += clock.o
+obj-$(CONFIG_AT91_SAM9_ALT_RESET) += at91sam9_alt_reset.o
+obj-$(CONFIG_AT91_SAM9G45_RESET) += at91sam9g45_reset.o
 
 # CPU-specific support
 obj-$(CONFIG_ARCH_AT91RM9200)  += at91rm9200.o at91rm9200_time.o at91rm9200_devices.o
-obj-$(CONFIG_ARCH_AT91SAM9260) += at91sam9260.o at91sam926x_time.o at91sam9260_devices.o sam9_smc.o at91sam9_alt_reset.o
-obj-$(CONFIG_ARCH_AT91SAM9261) += at91sam9261.o at91sam926x_time.o at91sam9261_devices.o sam9_smc.o at91sam9_alt_reset.o
-obj-$(CONFIG_ARCH_AT91SAM9G10) += at91sam9261.o at91sam926x_time.o at91sam9261_devices.o sam9_smc.o at91sam9_alt_reset.o
-obj-$(CONFIG_ARCH_AT91SAM9263) += at91sam9263.o at91sam926x_time.o at91sam9263_devices.o sam9_smc.o at91sam9_alt_reset.o
-obj-$(CONFIG_ARCH_AT91SAM9RL)  += at91sam9rl.o at91sam926x_time.o at91sam9rl_devices.o sam9_smc.o at91sam9_alt_reset.o
-obj-$(CONFIG_ARCH_AT91SAM9G20) += at91sam9260.o at91sam926x_time.o at91sam9260_devices.o sam9_smc.o at91sam9_alt_reset.o
+obj-$(CONFIG_ARCH_AT91SAM9260) += at91sam9260.o at91sam926x_time.o at91sam9260_devices.o sam9_smc.o
+obj-$(CONFIG_ARCH_AT91SAM9261) += at91sam9261.o at91sam926x_time.o at91sam9261_devices.o sam9_smc.o
+obj-$(CONFIG_ARCH_AT91SAM9G10) += at91sam9261.o at91sam926x_time.o at91sam9261_devices.o sam9_smc.o
+obj-$(CONFIG_ARCH_AT91SAM9263) += at91sam9263.o at91sam926x_time.o at91sam9263_devices.o sam9_smc.o
+obj-$(CONFIG_ARCH_AT91SAM9RL)  += at91sam9rl.o at91sam926x_time.o at91sam9rl_devices.o sam9_smc.o
+obj-$(CONFIG_ARCH_AT91SAM9G20) += at91sam9260.o at91sam926x_time.o at91sam9260_devices.o sam9_smc.o
 obj-$(CONFIG_ARCH_AT91SAM9G45) += at91sam9g45.o at91sam926x_time.o at91sam9g45_devices.o sam9_smc.o
 obj-$(CONFIG_ARCH_AT91CAP9)    += at91cap9.o at91sam926x_time.o at91cap9_devices.o sam9_smc.o
 obj-$(CONFIG_ARCH_AT91X40)     += at91x40.o at91x40_time.o
index edb879a..a42edc2 100644 (file)
@@ -21,7 +21,6 @@
 #include <mach/cpu.h>
 #include <mach/at91cap9.h>
 #include <mach/at91_pmc.h>
-#include <mach/at91_rstc.h>
 
 #include "soc.h"
 #include "generic.h"
@@ -314,11 +313,6 @@ static struct at91_gpio_bank at91cap9_gpio[] __initdata = {
        }
 };
 
-static void at91cap9_restart(char mode, const char *cmd)
-{
-       at91_sys_write(AT91_RSTC_CR, AT91_RSTC_KEY | AT91_RSTC_PROCRST | AT91_RSTC_PERRST);
-}
-
 /* --------------------------------------------------------------------
  *  AT91CAP9 processor initialization
  * -------------------------------------------------------------------- */
@@ -331,13 +325,14 @@ static void __init at91cap9_map_io(void)
 static void __init at91cap9_ioremap_registers(void)
 {
        at91_ioremap_shdwc(AT91CAP9_BASE_SHDWC);
+       at91_ioremap_rstc(AT91CAP9_BASE_RSTC);
        at91sam926x_ioremap_pit(AT91CAP9_BASE_PIT);
        at91sam9_ioremap_smc(0, AT91CAP9_BASE_SMC);
 }
 
 static void __init at91cap9_initialize(void)
 {
-       arm_pm_restart = at91cap9_restart;
+       arm_pm_restart = at91sam9g45_restart;
        at91_extern_irq = (1 << AT91CAP9_ID_IRQ0) | (1 << AT91CAP9_ID_IRQ1);
 
        /* Register GPIO subsystem */
index 5e46e4a..d4036ba 100644 (file)
@@ -323,6 +323,7 @@ static void __init at91sam9260_map_io(void)
 static void __init at91sam9260_ioremap_registers(void)
 {
        at91_ioremap_shdwc(AT91SAM9260_BASE_SHDWC);
+       at91_ioremap_rstc(AT91SAM9260_BASE_RSTC);
        at91sam926x_ioremap_pit(AT91SAM9260_BASE_PIT);
        at91sam9_ioremap_smc(0, AT91SAM9260_BASE_SMC);
 }
index b85b9ea..023c2ff 100644 (file)
@@ -281,6 +281,7 @@ static void __init at91sam9261_map_io(void)
 static void __init at91sam9261_ioremap_registers(void)
 {
        at91_ioremap_shdwc(AT91SAM9261_BASE_SHDWC);
+       at91_ioremap_rstc(AT91SAM9261_BASE_RSTC);
        at91sam926x_ioremap_pit(AT91SAM9261_BASE_PIT);
        at91sam9_ioremap_smc(0, AT91SAM9261_BASE_SMC);
 }
index 79e3669..75e876c 100644 (file)
@@ -301,6 +301,7 @@ static void __init at91sam9263_map_io(void)
 static void __init at91sam9263_ioremap_registers(void)
 {
        at91_ioremap_shdwc(AT91SAM9263_BASE_SHDWC);
+       at91_ioremap_rstc(AT91SAM9263_BASE_RSTC);
        at91sam926x_ioremap_pit(AT91SAM9263_BASE_PIT);
        at91sam9_ioremap_smc(0, AT91SAM9263_BASE_SMC0);
        at91sam9_ioremap_smc(1, AT91SAM9263_BASE_SMC1);
index d3f931c..518e423 100644 (file)
@@ -23,7 +23,8 @@
                        .globl  at91sam9_alt_restart
 
 at91sam9_alt_restart:  ldr     r0, .at91_va_base_sdramc        @ preload constants
-                       ldr     r1, .at91_va_base_rstc_cr
+                       ldr     r1, =at91_rstc_base
+                       ldr     r1, [r1]
 
                        mov     r2, #1
                        mov     r3, #AT91_SDRAMC_LPCB_POWER_DOWN
@@ -33,11 +34,9 @@ at91sam9_alt_restart:        ldr     r0, .at91_va_base_sdramc        @ preload constants
 
                        str     r2, [r0, #AT91_SDRAMC_TR]       @ disable SDRAM access
                        str     r3, [r0, #AT91_SDRAMC_LPR]      @ power down SDRAM
-                       str     r4, [r1]                        @ reset processor
+                       str     r4, [r1, #AT91_RSTC_CR]         @ reset processor
 
                        b       .
 
 .at91_va_base_sdramc:
        .word AT91_VA_BASE_SYS + AT91_SDRAMC0
-.at91_va_base_rstc_cr:
-       .word AT91_VA_BASE_SYS + AT91_RSTC_CR
index 7032dd3..1cb6a96 100644 (file)
@@ -18,7 +18,6 @@
 #include <asm/mach/map.h>
 #include <mach/at91sam9g45.h>
 #include <mach/at91_pmc.h>
-#include <mach/at91_rstc.h>
 #include <mach/cpu.h>
 
 #include "soc.h"
@@ -318,11 +317,6 @@ static struct at91_gpio_bank at91sam9g45_gpio[] __initdata = {
        }
 };
 
-static void at91sam9g45_restart(char mode, const char *cmd)
-{
-       at91_sys_write(AT91_RSTC_CR, AT91_RSTC_KEY | AT91_RSTC_PROCRST | AT91_RSTC_PERRST);
-}
-
 /* --------------------------------------------------------------------
  *  AT91SAM9G45 processor initialization
  * -------------------------------------------------------------------- */
@@ -336,6 +330,7 @@ static void __init at91sam9g45_map_io(void)
 static void __init at91sam9g45_ioremap_registers(void)
 {
        at91_ioremap_shdwc(AT91SAM9G45_BASE_SHDWC);
+       at91_ioremap_rstc(AT91SAM9G45_BASE_RSTC);
        at91sam926x_ioremap_pit(AT91SAM9G45_BASE_PIT);
        at91sam9_ioremap_smc(0, AT91SAM9G45_BASE_SMC);
 }
diff --git a/arch/arm/mach-at91/at91sam9g45_reset.S b/arch/arm/mach-at91/at91sam9g45_reset.S
new file mode 100644 (file)
index 0000000..0468be1
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * reset AT91SAM9G45 as per errata
+ *
+ * Copyright (C) 2011 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcosoft.com>
+ *
+ * unless the SDRAM is cleanly shutdown before we hit the
+ * reset register it can be left driving the data bus and
+ * killing the chance of a subsequent boot from NAND
+ *
+ * GPLv2 Only
+ */
+
+#include <linux/linkage.h>
+#include <mach/hardware.h>
+#include <mach/at91sam9_ddrsdr.h>
+#include <mach/at91_rstc.h>
+
+                       .arm
+
+                       .globl  at91sam9g45_restart
+
+at91sam9g45_restart:
+                       ldr     r0, .at91_va_base_sdramc0       @ preload constants
+                       ldr     r1, =at91_rstc_base
+                       ldr     r1, [r1]
+
+                       mov     r2, #1
+                       mov     r3, #AT91_DDRSDRC_LPCB_POWER_DOWN
+                       ldr     r4, =AT91_RSTC_KEY | AT91_RSTC_PERRST | AT91_RSTC_PROCRST
+
+                       .balign 32                              @ align to cache line
+
+                       str     r2, [r0, #AT91_DDRSDRC_RTR]     @ disable DDR0 access
+                       str     r3, [r0, #AT91_DDRSDRC_LPR]     @ power down DDR0
+                       str     r4, [r1, #AT91_RSTC_CR]         @ reset processor
+
+                       b       .
+
+.at91_va_base_sdramc0:
+       .word AT91_VA_BASE_SYS + AT91_DDRSDRC0
index d6bcb1d..d2c91a8 100644 (file)
@@ -286,6 +286,7 @@ static void __init at91sam9rl_map_io(void)
 static void __init at91sam9rl_ioremap_registers(void)
 {
        at91_ioremap_shdwc(AT91SAM9RL_BASE_SHDWC);
+       at91_ioremap_rstc(AT91SAM9RL_BASE_RSTC);
        at91sam926x_ioremap_pit(AT91SAM9RL_BASE_PIT);
        at91sam9_ioremap_smc(0, AT91SAM9RL_BASE_SMC);
 }
index 4866b81..5941334 100644 (file)
@@ -58,7 +58,9 @@ extern void at91_irq_suspend(void);
 extern void at91_irq_resume(void);
 
 /* reset */
+extern void at91_ioremap_rstc(u32 base_addr);
 extern void at91sam9_alt_restart(char, const char *);
+extern void at91sam9g45_restart(char, const char *);
 
 /* shutdown */
 extern void at91_ioremap_shdwc(u32 base_addr);
index cbd2bf0..875fa33 100644 (file)
 #ifndef AT91_RSTC_H
 #define AT91_RSTC_H
 
-#define AT91_RSTC_CR           (AT91_RSTC + 0x00)      /* Reset Controller Control Register */
+#ifndef __ASSEMBLY__
+extern void __iomem *at91_rstc_base;
+
+#define at91_rstc_read(field) \
+       __raw_readl(at91_rstc_base + field)
+
+#define at91_rstc_write(field, value) \
+       __raw_writel(value, at91_rstc_base + field);
+#else
+.extern at91_rstc_base
+#endif
+
+#define AT91_RSTC_CR           0x00                    /* Reset Controller Control Register */
 #define                AT91_RSTC_PROCRST       (1 << 0)                /* Processor Reset */
 #define                AT91_RSTC_PERRST        (1 << 2)                /* Peripheral Reset */
 #define                AT91_RSTC_EXTRST        (1 << 3)                /* External Reset */
 #define                AT91_RSTC_KEY           (0xa5 << 24)            /* KEY Password */
 
-#define AT91_RSTC_SR           (AT91_RSTC + 0x04)      /* Reset Controller Status Register */
+#define AT91_RSTC_SR           0x04                    /* Reset Controller Status Register */
 #define                AT91_RSTC_URSTS         (1 << 0)                /* User Reset Status */
 #define                AT91_RSTC_RSTTYP        (7 << 8)                /* Reset Type */
 #define                        AT91_RSTC_RSTTYP_GENERAL        (0 << 8)
@@ -33,7 +45,7 @@
 #define                AT91_RSTC_NRSTL         (1 << 16)               /* NRST Pin Level */
 #define                AT91_RSTC_SRCMP         (1 << 17)               /* Software Reset Command in Progress */
 
-#define AT91_RSTC_MR           (AT91_RSTC + 0x08)      /* Reset Controller Mode Register */
+#define AT91_RSTC_MR           0x08                    /* Reset Controller Mode Register */
 #define                AT91_RSTC_URSTEN        (1 << 0)                /* User Reset Enable */
 #define                AT91_RSTC_URSTIEN       (1 << 4)                /* User Reset Interrupt Enable */
 #define                AT91_RSTC_ERSTL         (0xf << 8)              /* External Reset Length */
index 4c0e2f6..61d9529 100644 (file)
@@ -83,7 +83,6 @@
 #define AT91_DDRSDRC0  (0xffffe600 - AT91_BASE_SYS)
 #define AT91_MATRIX    (0xffffea00 - AT91_BASE_SYS)
 #define AT91_PMC       (0xfffffc00 - AT91_BASE_SYS)
-#define AT91_RSTC      (0xfffffd00 - AT91_BASE_SYS)
 #define AT91_GPBR      (cpu_is_at91cap9_revB() ?       \
                        (0xfffffd50 - AT91_BASE_SYS) :  \
                        (0xfffffd60 - AT91_BASE_SYS))
@@ -96,6 +95,7 @@
 #define AT91CAP9_BASE_PIOB     0xfffff400
 #define AT91CAP9_BASE_PIOC     0xfffff600
 #define AT91CAP9_BASE_PIOD     0xfffff800
+#define AT91CAP9_BASE_RSTC     0xfffffd00
 #define AT91CAP9_BASE_SHDWC    0xfffffd10
 #define AT91CAP9_BASE_RTT      0xfffffd20
 #define AT91CAP9_BASE_PIT      0xfffffd30
diff --git a/arch/arm/mach-at91/include/mach/at91cap9_ddrsdr.h b/arch/arm/mach-at91/include/mach/at91cap9_ddrsdr.h
deleted file mode 100644 (file)
index 976f4a6..0000000
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * arch/arm/mach-at91/include/mach/at91cap9_ddrsdr.h
- *
- *  (C) 2008 Andrew Victor
- *
- * DDR/SDR Controller (DDRSDRC) - System peripherals registers.
- * Based on AT91CAP9 datasheet revision B.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-#ifndef AT91CAP9_DDRSDR_H
-#define AT91CAP9_DDRSDR_H
-
-#define AT91_DDRSDRC_MR                0x00    /* Mode Register */
-#define                AT91_DDRSDRC_MODE       (0xf << 0)              /* Command Mode */
-#define                        AT91_DDRSDRC_MODE_NORMAL                0
-#define                        AT91_DDRSDRC_MODE_NOP           1
-#define                        AT91_DDRSDRC_MODE_PRECHARGE     2
-#define                        AT91_DDRSDRC_MODE_LMR           3
-#define                        AT91_DDRSDRC_MODE_REFRESH       4
-#define                        AT91_DDRSDRC_MODE_EXT_LMR       5
-#define                        AT91_DDRSDRC_MODE_DEEP          6
-
-#define AT91_DDRSDRC_RTR       0x04    /* Refresh Timer Register */
-#define                AT91_DDRSDRC_COUNT      (0xfff << 0)            /* Refresh Timer Counter */
-
-#define AT91_DDRSDRC_CR                0x08    /* Configuration Register */
-#define                AT91_DDRSDRC_NC         (3 << 0)                /* Number of Column Bits */
-#define                        AT91_DDRSDRC_NC_SDR8    (0 << 0)
-#define                        AT91_DDRSDRC_NC_SDR9    (1 << 0)
-#define                        AT91_DDRSDRC_NC_SDR10   (2 << 0)
-#define                        AT91_DDRSDRC_NC_SDR11   (3 << 0)
-#define                        AT91_DDRSDRC_NC_DDR9    (0 << 0)
-#define                        AT91_DDRSDRC_NC_DDR10   (1 << 0)
-#define                        AT91_DDRSDRC_NC_DDR11   (2 << 0)
-#define                        AT91_DDRSDRC_NC_DDR12   (3 << 0)
-#define                AT91_DDRSDRC_NR         (3 << 2)                /* Number of Row Bits */
-#define                        AT91_DDRSDRC_NR_11      (0 << 2)
-#define                        AT91_DDRSDRC_NR_12      (1 << 2)
-#define                        AT91_DDRSDRC_NR_13      (2 << 2)
-#define                AT91_DDRSDRC_CAS        (7 << 4)                /* CAS Latency */
-#define                        AT91_DDRSDRC_CAS_2      (2 << 4)
-#define                        AT91_DDRSDRC_CAS_3      (3 << 4)
-#define                        AT91_DDRSDRC_CAS_25     (6 << 4)
-#define                AT91_DDRSDRC_DLL        (1 << 7)                /* Reset DLL */
-#define                AT91_DDRSDRC_DICDS      (1 << 8)                /* Output impedance control */
-
-#define AT91_DDRSDRC_T0PR      0x0C    /* Timing 0 Register */
-#define                AT91_DDRSDRC_TRAS       (0xf <<  0)             /* Active to Precharge delay */
-#define                AT91_DDRSDRC_TRCD       (0xf <<  4)             /* Row to Column delay */
-#define                AT91_DDRSDRC_TWR        (0xf <<  8)             /* Write recovery delay */
-#define                AT91_DDRSDRC_TRC        (0xf << 12)             /* Row cycle delay */
-#define                AT91_DDRSDRC_TRP        (0xf << 16)             /* Row precharge delay */
-#define                AT91_DDRSDRC_TRRD       (0xf << 20)             /* Active BankA to BankB */
-#define                AT91_DDRSDRC_TWTR       (1   << 24)             /* Internal Write to Read delay */
-#define                AT91_DDRSDRC_TMRD       (0xf << 28)             /* Load mode to active/refresh delay */
-
-#define AT91_DDRSDRC_T1PR      0x10    /* Timing 1 Register */
-#define                AT91_DDRSDRC_TRFC       (0x1f << 0)             /* Row Cycle Delay */
-#define                AT91_DDRSDRC_TXSNR      (0xff << 8)             /* Exit self-refresh to non-read */
-#define                AT91_DDRSDRC_TXSRD      (0xff << 16)            /* Exit self-refresh to read */
-#define                AT91_DDRSDRC_TXP        (0xf  << 24)            /* Exit power-down delay */
-
-#define AT91_DDRSDRC_LPR       0x18    /* Low Power Register */
-#define                AT91_DDRSDRC_LPCB               (3 << 0)        /* Low-power Configurations */
-#define                        AT91_DDRSDRC_LPCB_DISABLE               0
-#define                        AT91_DDRSDRC_LPCB_SELF_REFRESH          1
-#define                        AT91_DDRSDRC_LPCB_POWER_DOWN            2
-#define                        AT91_DDRSDRC_LPCB_DEEP_POWER_DOWN       3
-#define                AT91_DDRSDRC_CLKFR              (1 << 2)        /* Clock Frozen */
-#define                AT91_DDRSDRC_PASR               (7 << 4)        /* Partial Array Self Refresh */
-#define                AT91_DDRSDRC_TCSR               (3 << 8)        /* Temperature Compensated Self Refresh */
-#define                AT91_DDRSDRC_DS                 (3 << 10)       /* Drive Strength */
-#define                AT91_DDRSDRC_TIMEOUT            (3 << 12)       /* Time to define when Low Power Mode is enabled */
-#define                        AT91_DDRSDRC_TIMEOUT_0_CLK_CYCLES       (0 << 12)
-#define                        AT91_DDRSDRC_TIMEOUT_64_CLK_CYCLES      (1 << 12)
-#define                        AT91_DDRSDRC_TIMEOUT_128_CLK_CYCLES     (2 << 12)
-
-#define AT91_DDRSDRC_MDR       0x1C    /* Memory Device Register */
-#define                AT91_DDRSDRC_MD         (3 << 0)                /* Memory Device Type */
-#define                        AT91_DDRSDRC_MD_SDR             0
-#define                        AT91_DDRSDRC_MD_LOW_POWER_SDR   1
-#define                        AT91_DDRSDRC_MD_DDR             2
-#define                        AT91_DDRSDRC_MD_LOW_POWER_DDR   3
-
-#define AT91_DDRSDRC_DLLR      0x20    /* DLL Information Register */
-#define                AT91_DDRSDRC_MDINC      (1 << 0)                /* Master Delay increment */
-#define                AT91_DDRSDRC_MDDEC      (1 << 1)                /* Master Delay decrement */
-#define                AT91_DDRSDRC_MDOVF      (1 << 2)                /* Master Delay Overflow */
-#define                AT91_DDRSDRC_SDCOVF     (1 << 3)                /* Slave Delay Correction Overflow */
-#define                AT91_DDRSDRC_SDCUDF     (1 << 4)                /* Slave Delay Correction Underflow */
-#define                AT91_DDRSDRC_SDERF      (1 << 5)                /* Slave Delay Correction error */
-#define                AT91_DDRSDRC_MDVAL      (0xff <<  8)            /* Master Delay value */
-#define                AT91_DDRSDRC_SDVAL      (0xff << 16)            /* Slave Delay value */
-#define                AT91_DDRSDRC_SDCVAL     (0xff << 24)            /* Slave Delay Correction value */
-
-/* Register access macros */
-#define at91_ramc_read(num, reg) \
-       at91_sys_read(AT91_DDRSDRC##num + reg)
-#define at91_ramc_write(num, reg, value) \
-       at91_sys_write(AT91_DDRSDRC##num + reg, value)
-
-
-#endif
index f937c47..fa5ca27 100644 (file)
@@ -83,7 +83,6 @@
 #define AT91_SDRAMC0   (0xffffea00 - AT91_BASE_SYS)
 #define AT91_MATRIX    (0xffffee00 - AT91_BASE_SYS)
 #define AT91_PMC       (0xfffffc00 - AT91_BASE_SYS)
-#define AT91_RSTC      (0xfffffd00 - AT91_BASE_SYS)
 #define AT91_GPBR      (0xfffffd50 - AT91_BASE_SYS)
 
 #define AT91SAM9260_BASE_ECC   0xffffe800
@@ -92,6 +91,7 @@
 #define AT91SAM9260_BASE_PIOA  0xfffff400
 #define AT91SAM9260_BASE_PIOB  0xfffff600
 #define AT91SAM9260_BASE_PIOC  0xfffff800
+#define AT91SAM9260_BASE_RSTC  0xfffffd00
 #define AT91SAM9260_BASE_SHDWC 0xfffffd10
 #define AT91SAM9260_BASE_RTT   0xfffffd20
 #define AT91SAM9260_BASE_PIT   0xfffffd30
index 175604e..7cde2d3 100644 (file)
@@ -68,7 +68,6 @@
 #define AT91_SDRAMC0   (0xffffea00 - AT91_BASE_SYS)
 #define AT91_MATRIX    (0xffffee00 - AT91_BASE_SYS)
 #define AT91_PMC       (0xfffffc00 - AT91_BASE_SYS)
-#define AT91_RSTC      (0xfffffd00 - AT91_BASE_SYS)
 #define AT91_GPBR      (0xfffffd50 - AT91_BASE_SYS)
 
 #define AT91SAM9261_BASE_SMC   0xffffec00
@@ -76,6 +75,7 @@
 #define AT91SAM9261_BASE_PIOA  0xfffff400
 #define AT91SAM9261_BASE_PIOB  0xfffff600
 #define AT91SAM9261_BASE_PIOC  0xfffff800
+#define AT91SAM9261_BASE_RSTC  0xfffffd00
 #define AT91SAM9261_BASE_SHDWC 0xfffffd10
 #define AT91SAM9261_BASE_RTT   0xfffffd20
 #define AT91SAM9261_BASE_PIT   0xfffffd30
index 80c9150..5949abd 100644 (file)
@@ -78,7 +78,6 @@
 #define AT91_SDRAMC1   (0xffffe800 - AT91_BASE_SYS)
 #define AT91_MATRIX    (0xffffec00 - AT91_BASE_SYS)
 #define AT91_PMC       (0xfffffc00 - AT91_BASE_SYS)
-#define AT91_RSTC      (0xfffffd00 - AT91_BASE_SYS)
 #define AT91_GPBR      (0xfffffd60 - AT91_BASE_SYS)
 
 #define AT91SAM9263_BASE_ECC0  0xffffe000
@@ -91,6 +90,7 @@
 #define AT91SAM9263_BASE_PIOC  0xfffff600
 #define AT91SAM9263_BASE_PIOD  0xfffff800
 #define AT91SAM9263_BASE_PIOE  0xfffffa00
+#define AT91SAM9263_BASE_RSTC  0xfffffd00
 #define AT91SAM9263_BASE_SHDWC 0xfffffd10
 #define AT91SAM9263_BASE_RTT0  0xfffffd20
 #define AT91SAM9263_BASE_PIT   0xfffffd30
index d27b15b..e2f8da8 100644 (file)
 #define                        AT91_DDRSDRC_CAS_25     (6 << 4)
 #define                AT91_DDRSDRC_RST_DLL    (1 << 7)                /* Reset DLL */
 #define                AT91_DDRSDRC_DICDS      (1 << 8)                /* Output impedance control */
-#define                AT91_DDRSDRC_DIS_DLL    (1 << 9)                /* Disable DLL */
-#define                AT91_DDRSDRC_OCD        (1 << 12)               /* Off-Chip Driver */
-#define                AT91_DDRSDRC_DQMS       (1 << 16)               /* Mask Data is Shared */
-#define                AT91_DDRSDRC_ACTBST     (1 << 18)               /* Active Bank X to Burst Stop Read Access Bank Y */
+#define                AT91_DDRSDRC_DIS_DLL    (1 << 9)                /* Disable DLL [SAM9 Only] */
+#define                AT91_DDRSDRC_OCD        (1 << 12)               /* Off-Chip Driver [SAM9 Only] */
+#define                AT91_DDRSDRC_DQMS       (1 << 16)               /* Mask Data is Shared [SAM9 Only] */
+#define                AT91_DDRSDRC_ACTBST     (1 << 18)               /* Active Bank X to Burst Stop Read Access Bank Y [SAM9 Only] */
 
 #define AT91_DDRSDRC_T0PR      0x0C    /* Timing 0 Register */
 #define                AT91_DDRSDRC_TRAS       (0xf <<  0)             /* Active to Precharge delay */
@@ -59,7 +59,8 @@
 #define                AT91_DDRSDRC_TRP        (0xf << 16)             /* Row precharge delay */
 #define                AT91_DDRSDRC_TRRD       (0xf << 20)             /* Active BankA to BankB */
 #define                AT91_DDRSDRC_TWTR       (0x7 << 24)             /* Internal Write to Read delay */
-#define                AT91_DDRSDRC_RED_WRRD   (0x1 << 27)             /* Reduce Write to Read Delay */
+#define                AT91CAP9_DDRSDRC_TWTR   (1   << 24)             /* Internal Write to Read delay */
+#define                AT91_DDRSDRC_RED_WRRD   (0x1 << 27)             /* Reduce Write to Read Delay [SAM9 Only] */
 #define                AT91_DDRSDRC_TMRD       (0xf << 28)             /* Load mode to active/refresh delay */
 
 #define AT91_DDRSDRC_T1PR      0x10    /* Timing 1 Register */
 #define                AT91_DDRSDRC_TXSRD      (0xff << 16)            /* Exit self-refresh to read */
 #define                AT91_DDRSDRC_TXP        (0xf  << 24)            /* Exit power-down delay */
 
-#define AT91_DDRSDRC_T2PR      0x14    /* Timing 2 Register */
+#define AT91_DDRSDRC_T2PR      0x14    /* Timing 2 Register [SAM9 Only] */
 #define                AT91_DDRSDRC_TXARD      (0xf  << 0)             /* Exit active power down delay to read command in mode "Fast Exit" */
 #define                AT91_DDRSDRC_TXARDS     (0xf  << 4)             /* Exit active power down delay to read command in mode "Slow Exit" */
 #define                AT91_DDRSDRC_TRPA       (0xf  << 8)             /* Row Precharge All delay */
 #define                AT91_DDRSDRC_TRTP       (0x7  << 12)            /* Read to Precharge delay */
 
 #define AT91_DDRSDRC_LPR       0x1C    /* Low Power Register */
+#define AT91CAP9_DDRSDRC_LPR   0x18    /* Low Power Register */
 #define                AT91_DDRSDRC_LPCB       (3 << 0)                /* Low-power Configurations */
 #define                        AT91_DDRSDRC_LPCB_DISABLE               0
 #define                        AT91_DDRSDRC_LPCB_SELF_REFRESH          1
 #define                AT91_DDRSDRC_UPD_MR     (3 << 20)        /* Update load mode register and extended mode register */
 
 #define AT91_DDRSDRC_MDR       0x20    /* Memory Device Register */
+#define AT91CAP9_DDRSDRC_MDR   0x1C    /* Memory Device Register */
 #define                AT91_DDRSDRC_MD         (3 << 0)                /* Memory Device Type */
 #define                        AT91_DDRSDRC_MD_SDR             0
 #define                        AT91_DDRSDRC_MD_LOW_POWER_SDR   1
+#define                        AT91CAP9_DDRSDRC_MD_DDR         2
 #define                        AT91_DDRSDRC_MD_LOW_POWER_DDR   3
-#define                        AT91_DDRSDRC_MD_DDR2            6
+#define                        AT91_DDRSDRC_MD_DDR2            6       /* [SAM9 Only] */
 #define                AT91_DDRSDRC_DBW        (1 << 4)                /* Data Bus Width */
 #define                        AT91_DDRSDRC_DBW_32BITS         (0 <<  4)
 #define                        AT91_DDRSDRC_DBW_16BITS         (1 <<  4)
 
 #define AT91_DDRSDRC_DLL       0x24    /* DLL Information Register */
+#define AT91CAP9_DDRSDRC_DLL   0x20    /* DLL Information Register */
 #define                AT91_DDRSDRC_MDINC      (1 << 0)                /* Master Delay increment */
 #define                AT91_DDRSDRC_MDDEC      (1 << 1)                /* Master Delay decrement */
 #define                AT91_DDRSDRC_MDOVF      (1 << 2)                /* Master Delay Overflow */
+#define                AT91CAP9_DDRSDRC_SDCOVF (1 << 3)                /* Slave Delay Correction Overflow */
+#define                AT91CAP9_DDRSDRC_SDCUDF (1 << 4)                /* Slave Delay Correction Underflow */
+#define                AT91CAP9_DDRSDRC_SDERF  (1 << 5)                /* Slave Delay Correction error */
 #define                AT91_DDRSDRC_MDVAL      (0xff <<  8)            /* Master Delay value */
+#define                AT91CAP9_DDRSDRC_SDVAL  (0xff << 16)            /* Slave Delay value */
+#define                AT91CAP9_DDRSDRC_SDCVAL (0xff << 24)            /* Slave Delay Correction value */
 
-#define AT91_DDRSDRC_HS                0x2C    /* High Speed Register */
+#define AT91_DDRSDRC_HS                0x2C    /* High Speed Register [SAM9 Only] */
 #define                AT91_DDRSDRC_DIS_ATCP_RD        (1 << 2)        /* Anticip read access is disabled */
 
 #define AT91_DDRSDRC_DELAY(n)  (0x30 + (0x4 * (n)))    /* Delay I/O Register n */
 
-#define AT91_DDRSDRC_WPMR      0xE4    /* Write Protect Mode Register */
+#define AT91_DDRSDRC_WPMR      0xE4    /* Write Protect Mode Register [SAM9 Only] */
 #define                AT91_DDRSDRC_WP         (1 << 0)                /* Write protect enable */
 #define                AT91_DDRSDRC_WPKEY      (0xffffff << 8)         /* Write protect key */
 #define                AT91_DDRSDRC_KEY        (0x444452 << 8)         /* Write protect key = "DDR" */
 
-#define AT91_DDRSDRC_WPSR      0xE8    /* Write Protect Status Register */
+#define AT91_DDRSDRC_WPSR      0xE8    /* Write Protect Status Register [SAM9 Only] */
 #define                AT91_DDRSDRC_WPVS       (1 << 0)                /* Write protect violation status */
 #define                AT91_DDRSDRC_WPVSRC     (0xffff << 8)           /* Write protect violation source */
 
index f0c23c9..dd9c95e 100644 (file)
@@ -90,7 +90,6 @@
 #define AT91_DDRSDRC0  (0xffffe600 - AT91_BASE_SYS)
 #define AT91_MATRIX    (0xffffea00 - AT91_BASE_SYS)
 #define AT91_PMC       (0xfffffc00 - AT91_BASE_SYS)
-#define AT91_RSTC      (0xfffffd00 - AT91_BASE_SYS)
 #define AT91_GPBR      (0xfffffd60 - AT91_BASE_SYS)
 
 #define AT91SAM9G45_BASE_ECC   0xffffe200
 #define AT91SAM9G45_BASE_PIOC  0xfffff600
 #define AT91SAM9G45_BASE_PIOD  0xfffff800
 #define AT91SAM9G45_BASE_PIOE  0xfffffa00
+#define AT91SAM9G45_BASE_RSTC  0xfffffd00
 #define AT91SAM9G45_BASE_SHDWC 0xfffffd10
 #define AT91SAM9G45_BASE_RTT   0xfffffd20
 #define AT91SAM9G45_BASE_PIT   0xfffffd30
index 2bb359e..d7bead7 100644 (file)
@@ -72,7 +72,6 @@
 #define AT91_SDRAMC0   (0xffffea00 - AT91_BASE_SYS)
 #define AT91_MATRIX    (0xffffee00 - AT91_BASE_SYS)
 #define AT91_PMC       (0xfffffc00 - AT91_BASE_SYS)
-#define AT91_RSTC      (0xfffffd00 - AT91_BASE_SYS)
 #define AT91_SCKCR     (0xfffffd50 - AT91_BASE_SYS)
 #define AT91_GPBR      (0xfffffd60 - AT91_BASE_SYS)
 
@@ -84,6 +83,7 @@
 #define AT91SAM9RL_BASE_PIOB   0xfffff600
 #define AT91SAM9RL_BASE_PIOC   0xfffff800
 #define AT91SAM9RL_BASE_PIOD   0xfffffa00
+#define AT91SAM9RL_BASE_RSTC   0xfffffd00
 #define AT91SAM9RL_BASE_SHDWC  0xfffffd10
 #define AT91SAM9RL_BASE_RTT    0xfffffd20
 #define AT91SAM9RL_BASE_PIT    0xfffffd30
index d0b377b..3b33f07 100644 (file)
@@ -88,7 +88,7 @@ extern void __init at91_add_device_eth(struct macb_platform_data *data);
 struct at91_usbh_data {
        u8              ports;          /* number of ports on root hub */
        int             vbus_pin[2];    /* port power-control pin */
-       u8              vbus_pin_inverted;
+       u8              vbus_pin_active_low[2];
        u8              overcurrent_supported;
        int             overcurrent_pin[2];
        u8              overcurrent_status[2];
index 62ad955..1606379 100644 (file)
@@ -34,7 +34,6 @@
 /*
  * Show the reason for the previous system reset.
  */
-#if defined(AT91_RSTC)
 
 #include <mach/at91_rstc.h>
 #include <mach/at91_shdwc.h>
@@ -58,10 +57,10 @@ static void __init show_reset_status(void)
        char *reason, *r2 = reset;
        u32 reset_type, wake_type;
 
-       if (!at91_shdwc_base)
+       if (!at91_shdwc_base || !at91_rstc_base)
                return;
 
-       reset_type = at91_sys_read(AT91_RSTC_SR) & AT91_RSTC_RSTTYP;
+       reset_type = at91_rstc_read(AT91_RSTC_SR) & AT91_RSTC_RSTTYP;
        wake_type = at91_shdwc_read(AT91_SHDW_SR);
 
        switch (reset_type) {
@@ -102,10 +101,6 @@ static void __init show_reset_status(void)
        }
        pr_info("AT91: Starting after %s %s\n", reason, r2);
 }
-#else
-static void __init show_reset_status(void) {}
-#endif
-
 
 static int at91_pm_valid_state(suspend_state_t state)
 {
index ce9a206..7eb40d2 100644 (file)
@@ -25,21 +25,21 @@ static inline u32 sdram_selfrefresh_enable(void)
                                                                : : "r" (0))
 
 #elif defined(CONFIG_ARCH_AT91CAP9)
-#include <mach/at91cap9_ddrsdr.h>
+#include <mach/at91sam9_ddrsdr.h>
 
 
 static inline u32 sdram_selfrefresh_enable(void)
 {
        u32 saved_lpr, lpr;
 
-       saved_lpr = at91_ramc_read(0, AT91_DDRSDRC_LPR);
+       saved_lpr = at91_ramc_read(0, AT91CAP9_DDRSDRC_LPR);
 
        lpr = saved_lpr & ~AT91_DDRSDRC_LPCB;
-       at91_ramc_write(0, AT91_DDRSDRC_LPR, lpr | AT91_DDRSDRC_LPCB_SELF_REFRESH);
+       at91_ramc_write(0, AT91CAP9_DDRSDRC_LPR, lpr | AT91_DDRSDRC_LPCB_SELF_REFRESH);
        return saved_lpr;
 }
 
-#define sdram_selfrefresh_disable(saved_lpr)   at91_ramc_write(0, AT91_DDRSDRC_LPR, saved_lpr)
+#define sdram_selfrefresh_disable(saved_lpr)   at91_ramc_write(0, AT91CAP9_DDRSDRC_LPR, saved_lpr)
 #define wait_for_interrupt_enable()            cpu_do_idle()
 
 #elif defined(CONFIG_ARCH_AT91SAM9G45)
index f7922a4..92dfb84 100644 (file)
@@ -18,9 +18,8 @@
 
 #if defined(CONFIG_ARCH_AT91RM9200)
 #include <mach/at91rm9200_mc.h>
-#elif defined(CONFIG_ARCH_AT91CAP9)
-#include <mach/at91cap9_ddrsdr.h>
-#elif defined(CONFIG_ARCH_AT91SAM9G45)
+#elif defined(CONFIG_ARCH_AT91CAP9) \
+       || defined(CONFIG_ARCH_AT91SAM9G45)
 #include <mach/at91sam9_ddrsdr.h>
 #else
 #include <mach/at91sam9_sdramc.h>
index 8bdcc3c..69d3fc4 100644 (file)
@@ -29,9 +29,12 @@ EXPORT_SYMBOL(at91_soc_initdata);
 void __init at91rm9200_set_type(int type)
 {
        if (type == ARCH_REVISON_9200_PQFP)
-               at91_soc_initdata.subtype = AT91_SOC_RM9200_BGA;
-       else
                at91_soc_initdata.subtype = AT91_SOC_RM9200_PQFP;
+       else
+               at91_soc_initdata.subtype = AT91_SOC_RM9200_BGA;
+
+       pr_info("AT91: filled in soc subtype: %s\n",
+               at91_get_soc_subtype(&at91_soc_initdata));
 }
 
 void __init at91_init_irq_default(void)
@@ -281,6 +284,15 @@ void __init at91_ioremap_shdwc(u32 base_addr)
        pm_power_off = at91sam9_poweroff;
 }
 
+void __iomem *at91_rstc_base;
+
+void __init at91_ioremap_rstc(u32 base_addr)
+{
+       at91_rstc_base = ioremap(base_addr, 16);
+       if (!at91_rstc_base)
+               panic("Impossible to ioremap at91_rstc_base\n");
+}
+
 void __init at91_initialize(unsigned long main_clock)
 {
        at91_boot_soc.ioremap_registers();
index 9e5e755..45c97b1 100644 (file)
@@ -194,6 +194,6 @@ MACHINE_START(BCMRING, "BCMRING")
        .init_early = bcmring_init_early,
        .init_irq = bcmring_init_irq,
        .timer = &bcmring_timer,
-       .init_machine = bcmring_init_machine
+       .init_machine = bcmring_init_machine,
        .restart = bcmring_restart,
 MACHINE_END
index 1a1a27d..1024396 100644 (file)
 
 #include <mach/timer.h>
 
-#include <linux/mm.h>
 #include <linux/pfn.h>
 #include <linux/atomic.h>
 #include <linux/sched.h>
 #include <mach/dma.h>
 
-/* I don't quite understand why dc4 fails when this is set to 1 and DMA is enabled */
-/* especially since dc4 doesn't use kmalloc'd memory. */
-
-#define ALLOW_MAP_OF_KMALLOC_MEMORY 0
-
 /* ---- Public Variables ------------------------------------------------- */
 
 /* ---- Private Constants and Types -------------------------------------- */
 #define CONTROLLER_FROM_HANDLE(handle)    (((handle) >> 4) & 0x0f)
 #define CHANNEL_FROM_HANDLE(handle)       ((handle) & 0x0f)
 
-#define DMA_MAP_DEBUG   0
-
-#if DMA_MAP_DEBUG
-#   define  DMA_MAP_PRINT(fmt, args...)   printk("%s: " fmt, __func__,  ## args)
-#else
-#   define  DMA_MAP_PRINT(fmt, args...)
-#endif
 
 /* ---- Private Variables ------------------------------------------------ */
 
 static DMA_Global_t gDMA;
 static struct proc_dir_entry *gDmaDir;
 
-static atomic_t gDmaStatMemTypeKmalloc = ATOMIC_INIT(0);
-static atomic_t gDmaStatMemTypeVmalloc = ATOMIC_INIT(0);
-static atomic_t gDmaStatMemTypeUser = ATOMIC_INIT(0);
-static atomic_t gDmaStatMemTypeCoherent = ATOMIC_INIT(0);
-
 #include "dma_device.c"
 
 /* ---- Private Function Prototypes -------------------------------------- */
 
 /* ---- Functions  ------------------------------------------------------- */
 
-/****************************************************************************/
-/**
-*   Displays information for /proc/dma/mem-type
-*/
-/****************************************************************************/
-
-static int dma_proc_read_mem_type(char *buf, char **start, off_t offset,
-                                 int count, int *eof, void *data)
-{
-       int len = 0;
-
-       len += sprintf(buf + len, "dma_map_mem statistics\n");
-       len +=
-           sprintf(buf + len, "coherent: %d\n",
-                   atomic_read(&gDmaStatMemTypeCoherent));
-       len +=
-           sprintf(buf + len, "kmalloc:  %d\n",
-                   atomic_read(&gDmaStatMemTypeKmalloc));
-       len +=
-           sprintf(buf + len, "vmalloc:  %d\n",
-                   atomic_read(&gDmaStatMemTypeVmalloc));
-       len +=
-           sprintf(buf + len, "user:     %d\n",
-                   atomic_read(&gDmaStatMemTypeUser));
-
-       return len;
-}
-
 /****************************************************************************/
 /**
 *   Displays information for /proc/dma/channels
@@ -846,8 +800,6 @@ int dma_init(void)
                                       dma_proc_read_channels, NULL);
                create_proc_read_entry("devices", 0, gDmaDir,
                                       dma_proc_read_devices, NULL);
-               create_proc_read_entry("mem-type", 0, gDmaDir,
-                                      dma_proc_read_mem_type, NULL);
        }
 
 out:
@@ -1565,767 +1517,3 @@ int dma_set_device_handler(DMA_Device_t dev,    /* Device to set the callback for.
 }
 
 EXPORT_SYMBOL(dma_set_device_handler);
-
-/****************************************************************************/
-/**
-*   Initializes a memory mapping structure
-*/
-/****************************************************************************/
-
-int dma_init_mem_map(DMA_MemMap_t *memMap)
-{
-       memset(memMap, 0, sizeof(*memMap));
-
-       sema_init(&memMap->lock, 1);
-
-       return 0;
-}
-
-EXPORT_SYMBOL(dma_init_mem_map);
-
-/****************************************************************************/
-/**
-*   Releases any memory currently being held by a memory mapping structure.
-*/
-/****************************************************************************/
-
-int dma_term_mem_map(DMA_MemMap_t *memMap)
-{
-       down(&memMap->lock);    /* Just being paranoid */
-
-       /* Free up any allocated memory */
-
-       up(&memMap->lock);
-       memset(memMap, 0, sizeof(*memMap));
-
-       return 0;
-}
-
-EXPORT_SYMBOL(dma_term_mem_map);
-
-/****************************************************************************/
-/**
-*   Looks at a memory address and categorizes it.
-*
-*   @return One of the values from the DMA_MemType_t enumeration.
-*/
-/****************************************************************************/
-
-DMA_MemType_t dma_mem_type(void *addr)
-{
-       unsigned long addrVal = (unsigned long)addr;
-
-       if (addrVal >= CONSISTENT_BASE) {
-               /* NOTE: DMA virtual memory space starts at 0xFFxxxxxx */
-
-               /* dma_alloc_xxx pages are physically and virtually contiguous */
-
-               return DMA_MEM_TYPE_DMA;
-       }
-
-       /* Technically, we could add one more classification. Addresses between VMALLOC_END */
-       /* and the beginning of the DMA virtual address could be considered to be I/O space. */
-       /* Right now, nobody cares about this particular classification, so we ignore it. */
-
-       if (is_vmalloc_addr(addr)) {
-               /* Address comes from the vmalloc'd region. Pages are virtually */
-               /* contiguous but NOT physically contiguous */
-
-               return DMA_MEM_TYPE_VMALLOC;
-       }
-
-       if (addrVal >= PAGE_OFFSET) {
-               /* PAGE_OFFSET is typically 0xC0000000 */
-
-               /* kmalloc'd pages are physically contiguous */
-
-               return DMA_MEM_TYPE_KMALLOC;
-       }
-
-       return DMA_MEM_TYPE_USER;
-}
-
-EXPORT_SYMBOL(dma_mem_type);
-
-/****************************************************************************/
-/**
-*   Looks at a memory address and determines if we support DMA'ing to/from
-*   that type of memory.
-*
-*   @return boolean -
-*               return value != 0 means dma supported
-*               return value == 0 means dma not supported
-*/
-/****************************************************************************/
-
-int dma_mem_supports_dma(void *addr)
-{
-       DMA_MemType_t memType = dma_mem_type(addr);
-
-       return (memType == DMA_MEM_TYPE_DMA)
-#if ALLOW_MAP_OF_KMALLOC_MEMORY
-           || (memType == DMA_MEM_TYPE_KMALLOC)
-#endif
-           || (memType == DMA_MEM_TYPE_USER);
-}
-
-EXPORT_SYMBOL(dma_mem_supports_dma);
-
-/****************************************************************************/
-/**
-*   Maps in a memory region such that it can be used for performing a DMA.
-*
-*   @return
-*/
-/****************************************************************************/
-
-int dma_map_start(DMA_MemMap_t *memMap,        /* Stores state information about the map */
-                 enum dma_data_direction dir   /* Direction that the mapping will be going */
-    ) {
-       int rc;
-
-       down(&memMap->lock);
-
-       DMA_MAP_PRINT("memMap: %p\n", memMap);
-
-       if (memMap->inUse) {
-               printk(KERN_ERR "%s: memory map %p is already being used\n",
-                      __func__, memMap);
-               rc = -EBUSY;
-               goto out;
-       }
-
-       memMap->inUse = 1;
-       memMap->dir = dir;
-       memMap->numRegionsUsed = 0;
-
-       rc = 0;
-
-out:
-
-       DMA_MAP_PRINT("returning %d", rc);
-
-       up(&memMap->lock);
-
-       return rc;
-}
-
-EXPORT_SYMBOL(dma_map_start);
-
-/****************************************************************************/
-/**
-*   Adds a segment of memory to a memory map. Each segment is both
-*   physically and virtually contiguous.
-*
-*   @return     0 on success, error code otherwise.
-*/
-/****************************************************************************/
-
-static int dma_map_add_segment(DMA_MemMap_t *memMap,   /* Stores state information about the map */
-                              DMA_Region_t *region,    /* Region that the segment belongs to */
-                              void *virtAddr,  /* Virtual address of the segment being added */
-                              dma_addr_t physAddr,     /* Physical address of the segment being added */
-                              size_t numBytes  /* Number of bytes of the segment being added */
-    ) {
-       DMA_Segment_t *segment;
-
-       DMA_MAP_PRINT("memMap:%p va:%p pa:0x%x #:%d\n", memMap, virtAddr,
-                     physAddr, numBytes);
-
-       /* Sanity check */
-
-       if (((unsigned long)virtAddr < (unsigned long)region->virtAddr)
-           || (((unsigned long)virtAddr + numBytes)) >
-           ((unsigned long)region->virtAddr + region->numBytes)) {
-               printk(KERN_ERR
-                      "%s: virtAddr %p is outside region @ %p len: %d\n",
-                      __func__, virtAddr, region->virtAddr, region->numBytes);
-               return -EINVAL;
-       }
-
-       if (region->numSegmentsUsed > 0) {
-               /* Check to see if this segment is physically contiguous with the previous one */
-
-               segment = &region->segment[region->numSegmentsUsed - 1];
-
-               if ((segment->physAddr + segment->numBytes) == physAddr) {
-                       /* It is - just add on to the end */
-
-                       DMA_MAP_PRINT("appending %d bytes to last segment\n",
-                                     numBytes);
-
-                       segment->numBytes += numBytes;
-
-                       return 0;
-               }
-       }
-
-       /* Reallocate to hold more segments, if required. */
-
-       if (region->numSegmentsUsed >= region->numSegmentsAllocated) {
-               DMA_Segment_t *newSegment;
-               size_t oldSize =
-                   region->numSegmentsAllocated * sizeof(*newSegment);
-               int newAlloc = region->numSegmentsAllocated + 4;
-               size_t newSize = newAlloc * sizeof(*newSegment);
-
-               newSegment = kmalloc(newSize, GFP_KERNEL);
-               if (newSegment == NULL) {
-                       return -ENOMEM;
-               }
-               memcpy(newSegment, region->segment, oldSize);
-               memset(&((uint8_t *) newSegment)[oldSize], 0,
-                      newSize - oldSize);
-               kfree(region->segment);
-
-               region->numSegmentsAllocated = newAlloc;
-               region->segment = newSegment;
-       }
-
-       segment = &region->segment[region->numSegmentsUsed];
-       region->numSegmentsUsed++;
-
-       segment->virtAddr = virtAddr;
-       segment->physAddr = physAddr;
-       segment->numBytes = numBytes;
-
-       DMA_MAP_PRINT("returning success\n");
-
-       return 0;
-}
-
-/****************************************************************************/
-/**
-*   Adds a region of memory to a memory map. Each region is virtually
-*   contiguous, but not necessarily physically contiguous.
-*
-*   @return     0 on success, error code otherwise.
-*/
-/****************************************************************************/
-
-int dma_map_add_region(DMA_MemMap_t *memMap,   /* Stores state information about the map */
-                      void *mem,       /* Virtual address that we want to get a map of */
-                      size_t numBytes  /* Number of bytes being mapped */
-    ) {
-       unsigned long addr = (unsigned long)mem;
-       unsigned int offset;
-       int rc = 0;
-       DMA_Region_t *region;
-       dma_addr_t physAddr;
-
-       down(&memMap->lock);
-
-       DMA_MAP_PRINT("memMap:%p va:%p #:%d\n", memMap, mem, numBytes);
-
-       if (!memMap->inUse) {
-               printk(KERN_ERR "%s: Make sure you call dma_map_start first\n",
-                      __func__);
-               rc = -EINVAL;
-               goto out;
-       }
-
-       /* Reallocate to hold more regions. */
-
-       if (memMap->numRegionsUsed >= memMap->numRegionsAllocated) {
-               DMA_Region_t *newRegion;
-               size_t oldSize =
-                   memMap->numRegionsAllocated * sizeof(*newRegion);
-               int newAlloc = memMap->numRegionsAllocated + 4;
-               size_t newSize = newAlloc * sizeof(*newRegion);
-
-               newRegion = kmalloc(newSize, GFP_KERNEL);
-               if (newRegion == NULL) {
-                       rc = -ENOMEM;
-                       goto out;
-               }
-               memcpy(newRegion, memMap->region, oldSize);
-               memset(&((uint8_t *) newRegion)[oldSize], 0, newSize - oldSize);
-
-               kfree(memMap->region);
-
-               memMap->numRegionsAllocated = newAlloc;
-               memMap->region = newRegion;
-       }
-
-       region = &memMap->region[memMap->numRegionsUsed];
-       memMap->numRegionsUsed++;
-
-       offset = addr & ~PAGE_MASK;
-
-       region->memType = dma_mem_type(mem);
-       region->virtAddr = mem;
-       region->numBytes = numBytes;
-       region->numSegmentsUsed = 0;
-       region->numLockedPages = 0;
-       region->lockedPages = NULL;
-
-       switch (region->memType) {
-       case DMA_MEM_TYPE_VMALLOC:
-               {
-                       atomic_inc(&gDmaStatMemTypeVmalloc);
-
-                       /* printk(KERN_ERR "%s: vmalloc'd pages are not supported\n", __func__); */
-
-                       /* vmalloc'd pages are not physically contiguous */
-
-                       rc = -EINVAL;
-                       break;
-               }
-
-       case DMA_MEM_TYPE_KMALLOC:
-               {
-                       atomic_inc(&gDmaStatMemTypeKmalloc);
-
-                       /* kmalloc'd pages are physically contiguous, so they'll have exactly */
-                       /* one segment */
-
-#if ALLOW_MAP_OF_KMALLOC_MEMORY
-                       physAddr =
-                           dma_map_single(NULL, mem, numBytes, memMap->dir);
-                       rc = dma_map_add_segment(memMap, region, mem, physAddr,
-                                                numBytes);
-#else
-                       rc = -EINVAL;
-#endif
-                       break;
-               }
-
-       case DMA_MEM_TYPE_DMA:
-               {
-                       /* dma_alloc_xxx pages are physically contiguous */
-
-                       atomic_inc(&gDmaStatMemTypeCoherent);
-
-                       physAddr = (vmalloc_to_pfn(mem) << PAGE_SHIFT) + offset;
-
-                       dma_sync_single_for_cpu(NULL, physAddr, numBytes,
-                                               memMap->dir);
-                       rc = dma_map_add_segment(memMap, region, mem, physAddr,
-                                                numBytes);
-                       break;
-               }
-
-       case DMA_MEM_TYPE_USER:
-               {
-                       size_t firstPageOffset;
-                       size_t firstPageSize;
-                       struct page **pages;
-                       struct task_struct *userTask;
-
-                       atomic_inc(&gDmaStatMemTypeUser);
-
-#if 1
-                       /* If the pages are user pages, then the dma_mem_map_set_user_task function */
-                       /* must have been previously called. */
-
-                       if (memMap->userTask == NULL) {
-                               printk(KERN_ERR
-                                      "%s: must call dma_mem_map_set_user_task when using user-mode memory\n",
-                                      __func__);
-                               return -EINVAL;
-                       }
-
-                       /* User pages need to be locked. */
-
-                       firstPageOffset =
-                           (unsigned long)region->virtAddr & (PAGE_SIZE - 1);
-                       firstPageSize = PAGE_SIZE - firstPageOffset;
-
-                       region->numLockedPages = (firstPageOffset
-                                                 + region->numBytes +
-                                                 PAGE_SIZE - 1) / PAGE_SIZE;
-                       pages =
-                           kmalloc(region->numLockedPages *
-                                   sizeof(struct page *), GFP_KERNEL);
-
-                       if (pages == NULL) {
-                               region->numLockedPages = 0;
-                               return -ENOMEM;
-                       }
-
-                       userTask = memMap->userTask;
-
-                       down_read(&userTask->mm->mmap_sem);
-                       rc = get_user_pages(userTask,   /* task */
-                                           userTask->mm,       /* mm */
-                                           (unsigned long)region->virtAddr,    /* start */
-                                           region->numLockedPages,     /* len */
-                                           memMap->dir == DMA_FROM_DEVICE,     /* write */
-                                           0,  /* force */
-                                           pages,      /* pages (array of pointers to page) */
-                                           NULL);      /* vmas */
-                       up_read(&userTask->mm->mmap_sem);
-
-                       if (rc != region->numLockedPages) {
-                               kfree(pages);
-                               region->numLockedPages = 0;
-
-                               if (rc >= 0) {
-                                       rc = -EINVAL;
-                               }
-                       } else {
-                               uint8_t *virtAddr = region->virtAddr;
-                               size_t bytesRemaining;
-                               int pageIdx;
-
-                               rc = 0; /* Since get_user_pages returns +ve number */
-
-                               region->lockedPages = pages;
-
-                               /* We've locked the user pages. Now we need to walk them and figure */
-                               /* out the physical addresses. */
-
-                               /* The first page may be partial */
-
-                               dma_map_add_segment(memMap,
-                                                   region,
-                                                   virtAddr,
-                                                   PFN_PHYS(page_to_pfn
-                                                            (pages[0])) +
-                                                   firstPageOffset,
-                                                   firstPageSize);
-
-                               virtAddr += firstPageSize;
-                               bytesRemaining =
-                                   region->numBytes - firstPageSize;
-
-                               for (pageIdx = 1;
-                                    pageIdx < region->numLockedPages;
-                                    pageIdx++) {
-                                       size_t bytesThisPage =
-                                           (bytesRemaining >
-                                            PAGE_SIZE ? PAGE_SIZE :
-                                            bytesRemaining);
-
-                                       DMA_MAP_PRINT
-                                           ("pageIdx:%d pages[pageIdx]=%p pfn=%u phys=%u\n",
-                                            pageIdx, pages[pageIdx],
-                                            page_to_pfn(pages[pageIdx]),
-                                            PFN_PHYS(page_to_pfn
-                                                     (pages[pageIdx])));
-
-                                       dma_map_add_segment(memMap,
-                                                           region,
-                                                           virtAddr,
-                                                           PFN_PHYS(page_to_pfn
-                                                                    (pages
-                                                                     [pageIdx])),
-                                                           bytesThisPage);
-
-                                       virtAddr += bytesThisPage;
-                                       bytesRemaining -= bytesThisPage;
-                               }
-                       }
-#else
-                       printk(KERN_ERR
-                              "%s: User mode pages are not yet supported\n",
-                              __func__);
-
-                       /* user pages are not physically contiguous */
-
-                       rc = -EINVAL;
-#endif
-                       break;
-               }
-
-       default:
-               {
-                       printk(KERN_ERR "%s: Unsupported memory type: %d\n",
-                              __func__, region->memType);
-
-                       rc = -EINVAL;
-                       break;
-               }
-       }
-
-       if (rc != 0) {
-               memMap->numRegionsUsed--;
-       }
-
-out:
-
-       DMA_MAP_PRINT("returning %d\n", rc);
-
-       up(&memMap->lock);
-
-       return rc;
-}
-
-EXPORT_SYMBOL(dma_map_add_segment);
-
-/****************************************************************************/
-/**
-*   Maps in a memory region such that it can be used for performing a DMA.
-*
-*   @return     0 on success, error code otherwise.
-*/
-/****************************************************************************/
-
-int dma_map_mem(DMA_MemMap_t *memMap,  /* Stores state information about the map */
-               void *mem,      /* Virtual address that we want to get a map of */
-               size_t numBytes,        /* Number of bytes being mapped */
-               enum dma_data_direction dir     /* Direction that the mapping will be going */
-    ) {
-       int rc;
-
-       rc = dma_map_start(memMap, dir);
-       if (rc == 0) {
-               rc = dma_map_add_region(memMap, mem, numBytes);
-               if (rc < 0) {
-                       /* Since the add fails, this function will fail, and the caller won't */
-                       /* call unmap, so we need to do it here. */
-
-                       dma_unmap(memMap, 0);
-               }
-       }
-
-       return rc;
-}
-
-EXPORT_SYMBOL(dma_map_mem);
-
-/****************************************************************************/
-/**
-*   Setup a descriptor ring for a given memory map.
-*
-*   It is assumed that the descriptor ring has already been initialized, and
-*   this routine will only reallocate a new descriptor ring if the existing
-*   one is too small.
-*
-*   @return     0 on success, error code otherwise.
-*/
-/****************************************************************************/
-
-int dma_map_create_descriptor_ring(DMA_Device_t dev,   /* DMA device (where the ring is stored) */
-                                  DMA_MemMap_t *memMap,        /* Memory map that will be used */
-                                  dma_addr_t devPhysAddr       /* Physical address of device */
-    ) {
-       int rc;
-       int numDescriptors;
-       DMA_DeviceAttribute_t *devAttr;
-       DMA_Region_t *region;
-       DMA_Segment_t *segment;
-       dma_addr_t srcPhysAddr;
-       dma_addr_t dstPhysAddr;
-       int regionIdx;
-       int segmentIdx;
-
-       devAttr = &DMA_gDeviceAttribute[dev];
-
-       down(&memMap->lock);
-
-       /* Figure out how many descriptors we need */
-
-       numDescriptors = 0;
-       for (regionIdx = 0; regionIdx < memMap->numRegionsUsed; regionIdx++) {
-               region = &memMap->region[regionIdx];
-
-               for (segmentIdx = 0; segmentIdx < region->numSegmentsUsed;
-                    segmentIdx++) {
-                       segment = &region->segment[segmentIdx];
-
-                       if (memMap->dir == DMA_TO_DEVICE) {
-                               srcPhysAddr = segment->physAddr;
-                               dstPhysAddr = devPhysAddr;
-                       } else {
-                               srcPhysAddr = devPhysAddr;
-                               dstPhysAddr = segment->physAddr;
-                       }
-
-                       rc =
-                            dma_calculate_descriptor_count(dev, srcPhysAddr,
-                                                           dstPhysAddr,
-                                                           segment->
-                                                           numBytes);
-                       if (rc < 0) {
-                               printk(KERN_ERR
-                                      "%s: dma_calculate_descriptor_count failed: %d\n",
-                                      __func__, rc);
-                               goto out;
-                       }
-                       numDescriptors += rc;
-               }
-       }
-
-       /* Adjust the size of the ring, if it isn't big enough */
-
-       if (numDescriptors > devAttr->ring.descriptorsAllocated) {
-               dma_free_descriptor_ring(&devAttr->ring);
-               rc =
-                    dma_alloc_descriptor_ring(&devAttr->ring,
-                                              numDescriptors);
-               if (rc < 0) {
-                       printk(KERN_ERR
-                              "%s: dma_alloc_descriptor_ring failed: %d\n",
-                              __func__, rc);
-                       goto out;
-               }
-       } else {
-               rc =
-                    dma_init_descriptor_ring(&devAttr->ring,
-                                             numDescriptors);
-               if (rc < 0) {
-                       printk(KERN_ERR
-                              "%s: dma_init_descriptor_ring failed: %d\n",
-                              __func__, rc);
-                       goto out;
-               }
-       }
-
-       /* Populate the descriptors */
-
-       for (regionIdx = 0; regionIdx < memMap->numRegionsUsed; regionIdx++) {
-               region = &memMap->region[regionIdx];
-
-               for (segmentIdx = 0; segmentIdx < region->numSegmentsUsed;
-                    segmentIdx++) {
-                       segment = &region->segment[segmentIdx];
-
-                       if (memMap->dir == DMA_TO_DEVICE) {
-                               srcPhysAddr = segment->physAddr;
-                               dstPhysAddr = devPhysAddr;
-                       } else {
-                               srcPhysAddr = devPhysAddr;
-                               dstPhysAddr = segment->physAddr;
-                       }
-
-                       rc =
-                            dma_add_descriptors(&devAttr->ring, dev,
-                                                srcPhysAddr, dstPhysAddr,
-                                                segment->numBytes);
-                       if (rc < 0) {
-                               printk(KERN_ERR
-                                      "%s: dma_add_descriptors failed: %d\n",
-                                      __func__, rc);
-                               goto out;
-                       }
-               }
-       }
-
-       rc = 0;
-
-out:
-
-       up(&memMap->lock);
-       return rc;
-}
-
-EXPORT_SYMBOL(dma_map_create_descriptor_ring);
-
-/****************************************************************************/
-/**
-*   Maps in a memory region such that it can be used for performing a DMA.
-*
-*   @return
-*/
-/****************************************************************************/
-
-int dma_unmap(DMA_MemMap_t *memMap,    /* Stores state information about the map */
-             int dirtied       /* non-zero if any of the pages were modified */
-    ) {
-
-       int rc = 0;
-       int regionIdx;
-       int segmentIdx;
-       DMA_Region_t *region;
-       DMA_Segment_t *segment;
-
-       down(&memMap->lock);
-
-       for (regionIdx = 0; regionIdx < memMap->numRegionsUsed; regionIdx++) {
-               region = &memMap->region[regionIdx];
-
-               for (segmentIdx = 0; segmentIdx < region->numSegmentsUsed;
-                    segmentIdx++) {
-                       segment = &region->segment[segmentIdx];
-
-                       switch (region->memType) {
-                       case DMA_MEM_TYPE_VMALLOC:
-                               {
-                                       printk(KERN_ERR
-                                              "%s: vmalloc'd pages are not yet supported\n",
-                                              __func__);
-                                       rc = -EINVAL;
-                                       goto out;
-                               }
-
-                       case DMA_MEM_TYPE_KMALLOC:
-                               {
-#if ALLOW_MAP_OF_KMALLOC_MEMORY
-                                       dma_unmap_single(NULL,
-                                                        segment->physAddr,
-                                                        segment->numBytes,
-                                                        memMap->dir);
-#endif
-                                       break;
-                               }
-
-                       case DMA_MEM_TYPE_DMA:
-                               {
-                                       dma_sync_single_for_cpu(NULL,
-                                                               segment->
-                                                               physAddr,
-                                                               segment->
-                                                               numBytes,
-                                                               memMap->dir);
-                                       break;
-                               }
-
-                       case DMA_MEM_TYPE_USER:
-                               {
-                                       /* Nothing to do here. */
-
-                                       break;
-                               }
-
-                       default:
-                               {
-                                       printk(KERN_ERR
-                                              "%s: Unsupported memory type: %d\n",
-                                              __func__, region->memType);
-                                       rc = -EINVAL;
-                                       goto out;
-                               }
-                       }
-
-                       segment->virtAddr = NULL;
-                       segment->physAddr = 0;
-                       segment->numBytes = 0;
-               }
-
-               if (region->numLockedPages > 0) {
-                       int pageIdx;
-
-                       /* Some user pages were locked. We need to go and unlock them now. */
-
-                       for (pageIdx = 0; pageIdx < region->numLockedPages;
-                            pageIdx++) {
-                               struct page *page =
-                                   region->lockedPages[pageIdx];
-
-                               if (memMap->dir == DMA_FROM_DEVICE) {
-                                       SetPageDirty(page);
-                               }
-                               page_cache_release(page);
-                       }
-                       kfree(region->lockedPages);
-                       region->numLockedPages = 0;
-                       region->lockedPages = NULL;
-               }
-
-               region->memType = DMA_MEM_TYPE_NONE;
-               region->virtAddr = NULL;
-               region->numBytes = 0;
-               region->numSegmentsUsed = 0;
-       }
-       memMap->userTask = NULL;
-       memMap->numRegionsUsed = 0;
-       memMap->inUse = 0;
-
-out:
-       up(&memMap->lock);
-
-       return rc;
-}
-
-EXPORT_SYMBOL(dma_unmap);
index 1f2c531..7254378 100644 (file)
 /* ---- Include Files ---------------------------------------------------- */
 
 #include <linux/kernel.h>
-#include <linux/wait.h>
 #include <linux/semaphore.h>
 #include <csp/dmacHw.h>
 #include <mach/timer.h>
-#include <linux/scatterlist.h>
-#include <linux/dma-mapping.h>
-#include <linux/mm.h>
-#include <linux/vmalloc.h>
-#include <linux/pagemap.h>
 
 /* ---- Constants and Types ---------------------------------------------- */
 
@@ -111,78 +105,6 @@ typedef struct {
 
 } DMA_DescriptorRing_t;
 
-/****************************************************************************
-*
-*   The DMA_MemType_t and DMA_MemMap_t are helper structures used to setup
-*   DMA chains from a variety of memory sources.
-*
-*****************************************************************************/
-
-#define DMA_MEM_MAP_MIN_SIZE    4096   /* Pages less than this size are better */
-                                       /* off not being DMA'd. */
-
-typedef enum {
-       DMA_MEM_TYPE_NONE,      /* Not a valid setting */
-       DMA_MEM_TYPE_VMALLOC,   /* Memory came from vmalloc call */
-       DMA_MEM_TYPE_KMALLOC,   /* Memory came from kmalloc call */
-       DMA_MEM_TYPE_DMA,       /* Memory came from dma_alloc_xxx call */
-       DMA_MEM_TYPE_USER,      /* Memory came from user space. */
-
-} DMA_MemType_t;
-
-/* A segment represents a physically and virtually contiguous chunk of memory. */
-/* i.e. each segment can be DMA'd */
-/* A user of the DMA code will add memory regions. Each region may need to be */
-/* represented by one or more segments. */
-
-typedef struct {
-       void *virtAddr;         /* Virtual address used for this segment */
-       dma_addr_t physAddr;    /* Physical address this segment maps to */
-       size_t numBytes;        /* Size of the segment, in bytes */
-
-} DMA_Segment_t;
-
-/* A region represents a virtually contiguous chunk of memory, which may be */
-/* made up of multiple segments. */
-
-typedef struct {
-       DMA_MemType_t memType;
-       void *virtAddr;
-       size_t numBytes;
-
-       /* Each region (virtually contiguous) consists of one or more segments. Each */
-       /* segment is virtually and physically contiguous. */
-
-       int numSegmentsUsed;
-       int numSegmentsAllocated;
-       DMA_Segment_t *segment;
-
-       /* When a region corresponds to user memory, we need to lock all of the pages */
-       /* down before we can figure out the physical addresses. The lockedPage array contains */
-       /* the pages that were locked, and which subsequently need to be unlocked once the */
-       /* memory is unmapped. */
-
-       unsigned numLockedPages;
-       struct page **lockedPages;
-
-} DMA_Region_t;
-
-typedef struct {
-       int inUse;              /* Is this mapping currently being used? */
-       struct semaphore lock;  /* Acquired when using this structure */
-       enum dma_data_direction dir;    /* Direction this transfer is intended for */
-
-       /* In the event that we're mapping user memory, we need to know which task */
-       /* the memory is for, so that we can obtain the correct mm locks. */
-
-       struct task_struct *userTask;
-
-       int numRegionsUsed;
-       int numRegionsAllocated;
-       DMA_Region_t *region;
-
-} DMA_MemMap_t;
-
 /****************************************************************************
 *
 *   The DMA_DeviceAttribute_t contains information which describes a
@@ -568,124 +490,6 @@ int dma_alloc_double_dst_descriptors(DMA_Handle_t handle, /* DMA Handle */
                                     size_t numBytes    /* Number of bytes in each destination buffer */
     );
 
-/****************************************************************************/
-/**
-*   Initializes a DMA_MemMap_t data structure
-*/
-/****************************************************************************/
-
-int dma_init_mem_map(DMA_MemMap_t *memMap      /* Stores state information about the map */
-    );
-
-/****************************************************************************/
-/**
-*   Releases any memory currently being held by a memory mapping structure.
-*/
-/****************************************************************************/
-
-int dma_term_mem_map(DMA_MemMap_t *memMap      /* Stores state information about the map */
-    );
-
-/****************************************************************************/
-/**
-*   Looks at a memory address and categorizes it.
-*
-*   @return One of the values from the DMA_MemType_t enumeration.
-*/
-/****************************************************************************/
-
-DMA_MemType_t dma_mem_type(void *addr);
-
-/****************************************************************************/
-/**
-*   Sets the process (aka userTask) associated with a mem map. This is
-*   required if user-mode segments will be added to the mapping.
-*/
-/****************************************************************************/
-
-static inline void dma_mem_map_set_user_task(DMA_MemMap_t *memMap,
-                                            struct task_struct *task)
-{
-       memMap->userTask = task;
-}
-
-/****************************************************************************/
-/**
-*   Looks at a memory address and determines if we support DMA'ing to/from
-*   that type of memory.
-*
-*   @return boolean -
-*               return value != 0 means dma supported
-*               return value == 0 means dma not supported
-*/
-/****************************************************************************/
-
-int dma_mem_supports_dma(void *addr);
-
-/****************************************************************************/
-/**
-*   Initializes a memory map for use. Since this function acquires a
-*   sempaphore within the memory map, it is VERY important that dma_unmap
-*   be called when you're finished using the map.
-*/
-/****************************************************************************/
-
-int dma_map_start(DMA_MemMap_t *memMap,        /* Stores state information about the map */
-                 enum dma_data_direction dir   /* Direction that the mapping will be going */
-    );
-
-/****************************************************************************/
-/**
-*   Adds a segment of memory to a memory map.
-*
-*   @return     0 on success, error code otherwise.
-*/
-/****************************************************************************/
-
-int dma_map_add_region(DMA_MemMap_t *memMap,   /* Stores state information about the map */
-                      void *mem,       /* Virtual address that we want to get a map of */
-                      size_t numBytes  /* Number of bytes being mapped */
-    );
-
-/****************************************************************************/
-/**
-*   Creates a descriptor ring from a memory mapping.
-*
-*   @return 0 on success, error code otherwise.
-*/
-/****************************************************************************/
-
-int dma_map_create_descriptor_ring(DMA_Device_t dev,   /* DMA device (where the ring is stored) */
-                                  DMA_MemMap_t *memMap,        /* Memory map that will be used */
-                                  dma_addr_t devPhysAddr       /* Physical address of device */
-    );
-
-/****************************************************************************/
-/**
-*   Maps in a memory region such that it can be used for performing a DMA.
-*
-*   @return
-*/
-/****************************************************************************/
-
-int dma_map_mem(DMA_MemMap_t *memMap,  /* Stores state information about the map */
-               void *addr,     /* Virtual address that we want to get a map of */
-               size_t count,   /* Number of bytes being mapped */
-               enum dma_data_direction dir     /* Direction that the mapping will be going */
-    );
-
-/****************************************************************************/
-/**
-*   Maps in a memory region such that it can be used for performing a DMA.
-*
-*   @return
-*/
-/****************************************************************************/
-
-int dma_unmap(DMA_MemMap_t *memMap,    /* Stores state information about the map */
-             int dirtied       /* non-zero if any of the pages were modified */
-    );
-
 /****************************************************************************/
 /**
 *   Initiates a transfer when the descriptors have already been setup.
index 6b22b54..d508890 100644 (file)
@@ -44,7 +44,7 @@
 #include <mach/aemif.h>
 #include <mach/spi.h>
 
-#define DA850_EVM_PHY_ID               "0:00"
+#define DA850_EVM_PHY_ID               "davinci_mdio-0:00"
 #define DA850_LCD_PWR_PIN              GPIO_TO_PIN(2, 8)
 #define DA850_LCD_BL_PIN               GPIO_TO_PIN(2, 15)
 
index 346e1de..849311d 100644 (file)
@@ -54,7 +54,7 @@ static inline int have_tvp7002(void)
        return 0;
 }
 
-#define DM365_EVM_PHY_ID               "0:01"
+#define DM365_EVM_PHY_ID               "davinci_mdio-0:01"
 /*
  * A MAX-II CPLD is used for various board control functions.
  */
index a64b49c..1247ecd 100644 (file)
@@ -40,7 +40,7 @@
 #include <mach/usb.h>
 #include <mach/aemif.h>
 
-#define DM644X_EVM_PHY_ID              "0:01"
+#define DM644X_EVM_PHY_ID              "davinci_mdio-0:01"
 #define LXT971_PHY_ID  (0x001378e2)
 #define LXT971_PHY_MASK        (0xfffffff0)
 
index 6401755..872ac69 100644 (file)
@@ -736,7 +736,7 @@ static struct davinci_uart_config uart_config __initdata = {
        .enabled_uarts = (1 << 0),
 };
 
-#define DM646X_EVM_PHY_ID              "0:01"
+#define DM646X_EVM_PHY_ID              "davinci_mdio-0:01"
 /*
  * The following EDMA channels/slots are not being used by drivers (for
  * example: Timer, GPIO, UART events etc) on dm646x, hence they are being
index 6c4a164..8d34f51 100644 (file)
@@ -39,7 +39,7 @@
 #include <mach/mmc.h>
 #include <mach/usb.h>
 
-#define NEUROS_OSD2_PHY_ID             "0:01"
+#define NEUROS_OSD2_PHY_ID             "davinci_mdio-0:01"
 #define LXT971_PHY_ID                  0x001378e2
 #define LXT971_PHY_MASK                        0xfffffff0
 
index e7c0c7c..45e8157 100644 (file)
@@ -21,7 +21,7 @@
 #include <mach/da8xx.h>
 #include <mach/mux.h>
 
-#define HAWKBOARD_PHY_ID               "0:07"
+#define HAWKBOARD_PHY_ID               "davinci_mdio-0:07"
 #define DA850_HAWK_MMCSD_CD_PIN                GPIO_TO_PIN(3, 12)
 #define DA850_HAWK_MMCSD_WP_PIN                GPIO_TO_PIN(3, 13)
 
index 0b136a8..31da3c5 100644 (file)
@@ -42,7 +42,7 @@
 #include <mach/mux.h>
 #include <mach/usb.h>
 
-#define SFFSDR_PHY_ID          "0:01"
+#define SFFSDR_PHY_ID          "davinci_mdio-0:01"
 static struct mtd_partition davinci_sffsdr_nandflash_partition[] = {
        /* U-Boot Environment: Block 0
         * UBL:                Block 1
index 0ed7fdb..992c4c4 100644 (file)
@@ -153,34 +153,6 @@ static struct clk pll1_sysclk3 = {
        .div_reg        = PLLDIV3,
 };
 
-static struct clk pll1_sysclk4 = {
-       .name           = "pll1_sysclk4",
-       .parent         = &pll1_clk,
-       .flags          = CLK_PLL,
-       .div_reg        = PLLDIV4,
-};
-
-static struct clk pll1_sysclk5 = {
-       .name           = "pll1_sysclk5",
-       .parent         = &pll1_clk,
-       .flags          = CLK_PLL,
-       .div_reg        = PLLDIV5,
-};
-
-static struct clk pll1_sysclk6 = {
-       .name           = "pll0_sysclk6",
-       .parent         = &pll0_clk,
-       .flags          = CLK_PLL,
-       .div_reg        = PLLDIV6,
-};
-
-static struct clk pll1_sysclk7 = {
-       .name           = "pll1_sysclk7",
-       .parent         = &pll1_clk,
-       .flags          = CLK_PLL,
-       .div_reg        = PLLDIV7,
-};
-
 static struct clk i2c0_clk = {
        .name           = "i2c0",
        .parent         = &pll0_aux_clk,
@@ -397,10 +369,6 @@ static struct clk_lookup da850_clks[] = {
        CLK(NULL,               "pll1_aux",     &pll1_aux_clk),
        CLK(NULL,               "pll1_sysclk2", &pll1_sysclk2),
        CLK(NULL,               "pll1_sysclk3", &pll1_sysclk3),
-       CLK(NULL,               "pll1_sysclk4", &pll1_sysclk4),
-       CLK(NULL,               "pll1_sysclk5", &pll1_sysclk5),
-       CLK(NULL,               "pll1_sysclk6", &pll1_sysclk6),
-       CLK(NULL,               "pll1_sysclk7", &pll1_sysclk7),
        CLK("i2c_davinci.1",    NULL,           &i2c0_clk),
        CLK(NULL,               "timer0",       &timerp64_0_clk),
        CLK("watchdog",         NULL,           &timerp64_1_clk),
index da70e7e..dd1ad55 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/io.h>
 
 #include <asm/cacheflush.h>
+#include <asm/smp_plat.h>
 
 #include <mach/regs-pmu.h>
 
index 683aec7..0f2035a 100644 (file)
@@ -23,6 +23,7 @@
 
 #include <asm/cacheflush.h>
 #include <asm/hardware/gic.h>
+#include <asm/smp_plat.h>
 #include <asm/smp_scu.h>
 
 #include <mach/hardware.h>
index 7afbe1e..8394d51 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/smp.h>
 
 #include <asm/cacheflush.h>
+#include <asm/smp_plat.h>
 #include <asm/smp_scu.h>
 #include <asm/hardware/arm_timer.h>
 #include <asm/hardware/timer-sp.h>
@@ -72,9 +73,7 @@ static void __init highbank_map_io(void)
 
 void highbank_set_cpu_jump(int cpu, void *jump_addr)
 {
-#ifdef CONFIG_SMP
        cpu = cpu_logical_map(cpu);
-#endif
        writel(virt_to_phys(jump_addr), HB_JUMP_TABLE_VIRT(cpu));
        __cpuc_flush_dcache_area(HB_JUMP_TABLE_VIRT(cpu), 16);
        outer_clean_range(HB_JUMP_TABLE_PHYS(cpu),
index 09f357b..4defb97 100644 (file)
@@ -87,7 +87,6 @@ config SOC_IMX35
 
 config SOC_IMX5
        select CPU_V7
-       select ARM_L1_CACHE_SHIFT_6
        select MXC_TZIC
        select ARCH_MXC_IOMUX_V3
        select ARCH_MXC_AUDMUX_V2
index 9273c2a..2d88f8b 100644 (file)
@@ -814,6 +814,16 @@ DEF_PFD(pll3_pfd_540m, PFD_480, PFD1, &pll3_usb_otg);
 DEF_PFD(pll3_pfd_508m, PFD_480, PFD2, &pll3_usb_otg);
 DEF_PFD(pll3_pfd_454m, PFD_480, PFD3, &pll3_usb_otg);
 
+static unsigned long twd_clk_get_rate(struct clk *clk)
+{
+       return clk_get_rate(clk->parent) / 2;
+}
+
+static struct clk twd_clk = {
+       .parent = &arm_clk,
+       .get_rate = twd_clk_get_rate,
+};
+
 static unsigned long pll2_200m_get_rate(struct clk *clk)
 {
        return clk_get_rate(clk->parent) / 2;
@@ -1894,6 +1904,7 @@ static struct clk_lookup lookups[] = {
        _REGISTER_CLOCK("20ec000.sdma", NULL, sdma_clk),
        _REGISTER_CLOCK("20bc000.wdog", NULL, dummy_clk),
        _REGISTER_CLOCK("20c0000.wdog", NULL, dummy_clk),
+       _REGISTER_CLOCK("smp_twd", NULL, twd_clk),
        _REGISTER_CLOCK(NULL, "ckih", ckih_clk),
        _REGISTER_CLOCK(NULL, "ckil_clk", ckil_clk),
        _REGISTER_CLOCK(NULL, "aips_tz1_clk", aips_tz1_clk),
index 08dfb76..753f4fc 100644 (file)
@@ -188,8 +188,10 @@ static int weim_cs_config(void)
                return -ENOMEM;
 
        iomuxc_base = ioremap(MX53_IOMUXC_BASE_ADDR, SZ_4K);
-       if (!iomuxc_base)
+       if (!iomuxc_base) {
+               iounmap(weim_base);
                return -ENOMEM;
+       }
 
        /* CS1 timings for LAN9220 */
        writel(0x20001, (weim_base + 0x18));
index 29bd124..e15f155 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/of.h>
 #include <linux/of_address.h>
 #include <linux/smp.h>
+#include <asm/smp_plat.h>
 
 #define SRC_SCR                                0x000
 #define SRC_GPR1                       0x020
 
 static void __iomem *src_base;
 
-#ifndef CONFIG_SMP
-#define cpu_logical_map(cpu)           0
-#endif
-
 void imx_enable_cpu(int cpu, bool enable)
 {
        u32 mask, val;
index 41c252d..a446fc1 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/smp.h>
 
 #include <asm/cacheflush.h>
+#include <asm/smp_plat.h>
 
 extern volatile int pen_release;
 
index 0b3e357..db0117e 100644 (file)
@@ -20,6 +20,7 @@
 #include <asm/cacheflush.h>
 #include <asm/cputype.h>
 #include <asm/mach-types.h>
+#include <asm/smp_plat.h>
 
 #include <mach/msm_iomap.h>
 
index a8ba7b9..d965da4 100644 (file)
@@ -33,7 +33,6 @@ config ARCH_OMAP3
        default y
        select CPU_V7
        select USB_ARCH_HAS_EHCI
-       select ARM_L1_CACHE_SHIFT_6 if !ARCH_OMAP4
        select ARCH_HAS_OPP
        select PM_OPP if PM
        select ARM_CPU_SUSPEND if PM
@@ -214,13 +213,12 @@ config MACH_OMAP3_PANDORA
        depends on ARCH_OMAP3
        default y
        select OMAP_PACKAGE_CBB
-       select REGULATOR_FIXED_VOLTAGE
+       select REGULATOR_FIXED_VOLTAGE if REGULATOR
 
 config MACH_OMAP3_TOUCHBOOK
        bool "OMAP3 Touch Book"
        depends on ARCH_OMAP3
        default y
-       select BACKLIGHT_CLASS_DEVICE
 
 config MACH_OMAP_3430SDP
        bool "OMAP 3430 SDP board"
@@ -266,7 +264,7 @@ config MACH_OMAP_ZOOM2
        select SERIAL_8250
        select SERIAL_CORE_CONSOLE
        select SERIAL_8250_CONSOLE
-       select REGULATOR_FIXED_VOLTAGE
+       select REGULATOR_FIXED_VOLTAGE if REGULATOR
 
 config MACH_OMAP_ZOOM3
        bool "OMAP3630 Zoom3 board"
@@ -276,7 +274,7 @@ config MACH_OMAP_ZOOM3
        select SERIAL_8250
        select SERIAL_CORE_CONSOLE
        select SERIAL_8250_CONSOLE
-       select REGULATOR_FIXED_VOLTAGE
+       select REGULATOR_FIXED_VOLTAGE if REGULATOR
 
 config MACH_CM_T35
        bool "CompuLab CM-T35/CM-T3730 modules"
@@ -335,7 +333,7 @@ config MACH_OMAP_4430SDP
        depends on ARCH_OMAP4
        select OMAP_PACKAGE_CBL
        select OMAP_PACKAGE_CBS
-       select REGULATOR_FIXED_VOLTAGE
+       select REGULATOR_FIXED_VOLTAGE if REGULATOR
 
 config MACH_OMAP4_PANDA
        bool "OMAP4 Panda Board"
@@ -343,7 +341,7 @@ config MACH_OMAP4_PANDA
        depends on ARCH_OMAP4
        select OMAP_PACKAGE_CBL
        select OMAP_PACKAGE_CBS
-       select REGULATOR_FIXED_VOLTAGE
+       select REGULATOR_FIXED_VOLTAGE if REGULATOR
 
 config OMAP3_EMU
        bool "OMAP3 debugging peripherals"
index 39fba9d..4e90715 100644 (file)
@@ -52,8 +52,9 @@
 #define ETH_KS8851_QUART               138
 #define OMAP4_SFH7741_SENSOR_OUTPUT_GPIO       184
 #define OMAP4_SFH7741_ENABLE_GPIO              188
-#define HDMI_GPIO_HPD 60 /* Hot plug pin for HDMI */
+#define HDMI_GPIO_CT_CP_HPD 60 /* HPD mode enable/disable */
 #define HDMI_GPIO_LS_OE 41 /* Level shifter for HDMI */
+#define HDMI_GPIO_HPD  63 /* Hotplug detect */
 #define DISPLAY_SEL_GPIO       59      /* LCD2/PicoDLP switch */
 #define DLP_POWER_ON_GPIO      40
 
@@ -603,8 +604,9 @@ static void __init omap_sfh7741prox_init(void)
 }
 
 static struct gpio sdp4430_hdmi_gpios[] = {
-       { HDMI_GPIO_HPD,        GPIOF_OUT_INIT_HIGH,    "hdmi_gpio_hpd"   },
+       { HDMI_GPIO_CT_CP_HPD, GPIOF_OUT_INIT_HIGH, "hdmi_gpio_ct_cp_hpd" },
        { HDMI_GPIO_LS_OE,      GPIOF_OUT_INIT_HIGH,    "hdmi_gpio_ls_oe" },
+       { HDMI_GPIO_HPD, GPIOF_DIR_IN, "hdmi_gpio_hpd" },
 };
 
 static int sdp4430_panel_enable_hdmi(struct omap_dss_device *dssdev)
@@ -621,8 +623,7 @@ static int sdp4430_panel_enable_hdmi(struct omap_dss_device *dssdev)
 
 static void sdp4430_panel_disable_hdmi(struct omap_dss_device *dssdev)
 {
-       gpio_free(HDMI_GPIO_LS_OE);
-       gpio_free(HDMI_GPIO_HPD);
+       gpio_free_array(sdp4430_hdmi_gpios, ARRAY_SIZE(sdp4430_hdmi_gpios));
 }
 
 static struct nokia_dsi_panel_data dsi1_panel = {
@@ -738,6 +739,10 @@ static void sdp4430_lcd_init(void)
                pr_err("%s: Could not get lcd2_reset_gpio\n", __func__);
 }
 
+static struct omap_dss_hdmi_data sdp4430_hdmi_data = {
+       .hpd_gpio = HDMI_GPIO_HPD,
+};
+
 static struct omap_dss_device sdp4430_hdmi_device = {
        .name = "hdmi",
        .driver_name = "hdmi_panel",
@@ -745,6 +750,7 @@ static struct omap_dss_device sdp4430_hdmi_device = {
        .platform_enable = sdp4430_panel_enable_hdmi,
        .platform_disable = sdp4430_panel_disable_hdmi,
        .channel = OMAP_DSS_CHANNEL_DIGIT,
+       .data = &sdp4430_hdmi_data,
 };
 
 static struct picodlp_panel_data sdp4430_picodlp_pdata = {
@@ -808,7 +814,7 @@ static struct omap_dss_board_info sdp4430_dss_data = {
        .default_device = &sdp4430_lcd_device,
 };
 
-static void omap_4430sdp_display_init(void)
+static void __init omap_4430sdp_display_init(void)
 {
        int r;
 
@@ -829,6 +835,10 @@ static void omap_4430sdp_display_init(void)
                omap_hdmi_init(OMAP_HDMI_SDA_SCL_EXTERNAL_PULLUP);
        else
                omap_hdmi_init(0);
+
+       omap_mux_init_gpio(HDMI_GPIO_LS_OE, OMAP_PIN_OUTPUT);
+       omap_mux_init_gpio(HDMI_GPIO_CT_CP_HPD, OMAP_PIN_OUTPUT);
+       omap_mux_init_gpio(HDMI_GPIO_HPD, OMAP_PIN_INPUT_PULLDOWN);
 }
 
 #ifdef CONFIG_OMAP_MUX
@@ -841,7 +851,7 @@ static struct omap_board_mux board_mux[] __initdata = {
 #define board_mux      NULL
  #endif
 
-static void omap4_sdp4430_wifi_mux_init(void)
+static void __init omap4_sdp4430_wifi_mux_init(void)
 {
        omap_mux_init_gpio(GPIO_WIFI_IRQ, OMAP_PIN_INPUT |
                                OMAP_PIN_OFF_WAKEUPENABLE);
@@ -868,12 +878,17 @@ static struct wl12xx_platform_data omap4_sdp4430_wlan_data __initdata = {
        .board_tcxo_clock = WL12XX_TCXOCLOCK_26,
 };
 
-static void omap4_sdp4430_wifi_init(void)
+static void __init omap4_sdp4430_wifi_init(void)
 {
+       int ret;
+
        omap4_sdp4430_wifi_mux_init();
-       if (wl12xx_set_platform_data(&omap4_sdp4430_wlan_data))
-               pr_err("Error setting wl12xx data\n");
-       platform_device_register(&omap_vwlan_device);
+       ret = wl12xx_set_platform_data(&omap4_sdp4430_wlan_data);
+       if (ret)
+               pr_err("Error setting wl12xx data: %d\n", ret);
+       ret = platform_device_register(&omap_vwlan_device);
+       if (ret)
+               pr_err("Error registering wl12xx device: %d\n", ret);
 }
 
 static void __init omap_4430sdp_init(void)
index 003fe34..c775bea 100644 (file)
@@ -617,6 +617,21 @@ static struct gpio omap3_evm_ehci_gpios[] __initdata = {
        { OMAP3_EVM_EHCI_SELECT, GPIOF_OUT_INIT_LOW,   "select EHCI port" },
 };
 
+static void __init omap3_evm_wl12xx_init(void)
+{
+#ifdef CONFIG_WL12XX_PLATFORM_DATA
+       int ret;
+
+       /* WL12xx WLAN Init */
+       ret = wl12xx_set_platform_data(&omap3evm_wlan_data);
+       if (ret)
+               pr_err("error setting wl12xx data: %d\n", ret);
+       ret = platform_device_register(&omap3evm_wlan_regulator);
+       if (ret)
+               pr_err("error registering wl12xx device: %d\n", ret);
+#endif
+}
+
 static void __init omap3_evm_init(void)
 {
        omap3_evm_get_revision();
@@ -665,13 +680,7 @@ static void __init omap3_evm_init(void)
        omap_ads7846_init(1, OMAP3_EVM_TS_GPIO, 310, NULL);
        omap3evm_init_smsc911x();
        omap3_evm_display_init();
-
-#ifdef CONFIG_WL12XX_PLATFORM_DATA
-       /* WL12xx WLAN Init */
-       if (wl12xx_set_platform_data(&omap3evm_wlan_data))
-               pr_err("error setting wl12xx data\n");
-       platform_device_register(&omap3evm_wlan_regulator);
-#endif
+       omap3_evm_wl12xx_init();
 }
 
 MACHINE_START(OMAP3EVM, "OMAP3 EVM")
index 30ad40d..28fc271 100644 (file)
@@ -51,8 +51,9 @@
 #define GPIO_HUB_NRESET                62
 #define GPIO_WIFI_PMENA                43
 #define GPIO_WIFI_IRQ          53
-#define HDMI_GPIO_HPD 60 /* Hot plug pin for HDMI */
+#define HDMI_GPIO_CT_CP_HPD 60 /* HPD mode enable/disable */
 #define HDMI_GPIO_LS_OE 41 /* Level shifter for HDMI */
+#define HDMI_GPIO_HPD  63 /* Hotplug detect */
 
 /* wl127x BT, FM, GPS connectivity chip */
 static int wl1271_gpios[] = {46, -1, -1};
@@ -413,8 +414,9 @@ int __init omap4_panda_dvi_init(void)
 }
 
 static struct gpio panda_hdmi_gpios[] = {
-       { HDMI_GPIO_HPD,        GPIOF_OUT_INIT_HIGH, "hdmi_gpio_hpd"   },
+       { HDMI_GPIO_CT_CP_HPD, GPIOF_OUT_INIT_HIGH, "hdmi_gpio_ct_cp_hpd" },
        { HDMI_GPIO_LS_OE,      GPIOF_OUT_INIT_HIGH, "hdmi_gpio_ls_oe" },
+       { HDMI_GPIO_HPD, GPIOF_DIR_IN, "hdmi_gpio_hpd" },
 };
 
 static int omap4_panda_panel_enable_hdmi(struct omap_dss_device *dssdev)
@@ -431,10 +433,13 @@ static int omap4_panda_panel_enable_hdmi(struct omap_dss_device *dssdev)
 
 static void omap4_panda_panel_disable_hdmi(struct omap_dss_device *dssdev)
 {
-       gpio_free(HDMI_GPIO_LS_OE);
-       gpio_free(HDMI_GPIO_HPD);
+       gpio_free_array(panda_hdmi_gpios, ARRAY_SIZE(panda_hdmi_gpios));
 }
 
+static struct omap_dss_hdmi_data omap4_panda_hdmi_data = {
+       .hpd_gpio = HDMI_GPIO_HPD,
+};
+
 static struct omap_dss_device  omap4_panda_hdmi_device = {
        .name = "hdmi",
        .driver_name = "hdmi_panel",
@@ -442,6 +447,7 @@ static struct omap_dss_device  omap4_panda_hdmi_device = {
        .platform_enable = omap4_panda_panel_enable_hdmi,
        .platform_disable = omap4_panda_panel_disable_hdmi,
        .channel = OMAP_DSS_CHANNEL_DIGIT,
+       .data = &omap4_panda_hdmi_data,
 };
 
 static struct omap_dss_device *omap4_panda_dss_devices[] = {
@@ -473,18 +479,24 @@ void omap4_panda_display_init(void)
                omap_hdmi_init(OMAP_HDMI_SDA_SCL_EXTERNAL_PULLUP);
        else
                omap_hdmi_init(0);
+
+       omap_mux_init_gpio(HDMI_GPIO_LS_OE, OMAP_PIN_OUTPUT);
+       omap_mux_init_gpio(HDMI_GPIO_CT_CP_HPD, OMAP_PIN_OUTPUT);
+       omap_mux_init_gpio(HDMI_GPIO_HPD, OMAP_PIN_INPUT_PULLDOWN);
 }
 
 static void __init omap4_panda_init(void)
 {
        int package = OMAP_PACKAGE_CBS;
+       int ret;
 
        if (omap_rev() == OMAP4430_REV_ES1_0)
                package = OMAP_PACKAGE_CBL;
        omap4_mux_init(board_mux, NULL, package);
 
-       if (wl12xx_set_platform_data(&omap_panda_wlan_data))
-               pr_err("error setting wl12xx data\n");
+       ret = wl12xx_set_platform_data(&omap_panda_wlan_data);
+       if (ret)
+               pr_err("error setting wl12xx data: %d\n", ret);
 
        omap4_panda_i2c_init();
        platform_add_devices(panda_devices, ARRAY_SIZE(panda_devices));
index 8d7ce11..c126461 100644 (file)
@@ -296,8 +296,10 @@ static void enable_board_wakeup_source(void)
 
 void __init zoom_peripherals_init(void)
 {
-       if (wl12xx_set_platform_data(&omap_zoom_wlan_data))
-               pr_err("error setting wl12xx data\n");
+       int ret = wl12xx_set_platform_data(&omap_zoom_wlan_data);
+
+       if (ret)
+               pr_err("error setting wl12xx data: %d\n", ret);
 
        omap_i2c_init();
        platform_device_register(&omap_vwlan_device);
index 0b510ad..283d11e 100644 (file)
@@ -405,6 +405,7 @@ static int omap_mcspi_init(struct omap_hwmod *oh, void *unused)
                        break;
        default:
                        pr_err("Invalid McSPI Revision value\n");
+                       kfree(pdata);
                        return -EINVAL;
        }
 
index 3c446d1..3677b1f 100644 (file)
@@ -103,12 +103,8 @@ static void omap4_hdmi_mux_pads(enum omap_hdmi_flags flags)
        u32 reg;
        u16 control_i2c_1;
 
-       /* PAD0_HDMI_HPD_PAD1_HDMI_CEC */
-       omap_mux_init_signal("hdmi_hpd",
-                       OMAP_PIN_INPUT_PULLUP);
        omap_mux_init_signal("hdmi_cec",
                        OMAP_PIN_INPUT_PULLUP);
-       /* PAD0_HDMI_DDC_SCL_PAD1_HDMI_DDC_SDA */
        omap_mux_init_signal("hdmi_ddc_scl",
                        OMAP_PIN_INPUT_PULLUP);
        omap_mux_init_signal("hdmi_ddc_sda",
index 130034b..dfffbbf 100644 (file)
@@ -528,7 +528,13 @@ int gpmc_cs_configure(int cs, int cmd, int wval)
 
        case GPMC_CONFIG_DEV_SIZE:
                regval  = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG1);
+
+               /* clear 2 target bits */
+               regval &= ~GPMC_CONFIG1_DEVICESIZE(3);
+
+               /* set the proper value */
                regval |= GPMC_CONFIG1_DEVICESIZE(wval);
+
                gpmc_cs_write_reg(cs, GPMC_CS_CONFIG1, regval);
                break;
 
index bd844af..b40c288 100644 (file)
@@ -175,14 +175,15 @@ static void hsmmc2_select_input_clk_src(struct omap_mmc_platform_data *mmc)
 {
        u32 reg;
 
-       if (mmc->slots[0].internal_clock) {
-               reg = omap_ctrl_readl(control_devconf1_offset);
+       reg = omap_ctrl_readl(control_devconf1_offset);
+       if (mmc->slots[0].internal_clock)
                reg |= OMAP2_MMCSDIO2ADPCLKISEL;
-               omap_ctrl_writel(reg, control_devconf1_offset);
-       }
+       else
+               reg &= ~OMAP2_MMCSDIO2ADPCLKISEL;
+       omap_ctrl_writel(reg, control_devconf1_offset);
 }
 
-static void hsmmc23_before_set_reg(struct device *dev, int slot,
+static void hsmmc2_before_set_reg(struct device *dev, int slot,
                                   int power_on, int vdd)
 {
        struct omap_mmc_platform_data *mmc = dev->platform_data;
@@ -292,8 +293,8 @@ static inline void omap_hsmmc_mux(struct omap_mmc_platform_data *mmc_controller,
        }
 }
 
-static int __init omap_hsmmc_pdata_init(struct omap2_hsmmc_info *c,
-                                       struct omap_mmc_platform_data *mmc)
+static int omap_hsmmc_pdata_init(struct omap2_hsmmc_info *c,
+                                struct omap_mmc_platform_data *mmc)
 {
        char *hc_name;
 
@@ -407,14 +408,13 @@ static int __init omap_hsmmc_pdata_init(struct omap2_hsmmc_info *c,
                        c->caps &= ~MMC_CAP_8_BIT_DATA;
                        c->caps |= MMC_CAP_4_BIT_DATA;
                }
-               /* FALLTHROUGH */
-       case 3:
                if (mmc->slots[0].features & HSMMC_HAS_PBIAS) {
                        /* off-chip level shifting, or none */
-                       mmc->slots[0].before_set_reg = hsmmc23_before_set_reg;
+                       mmc->slots[0].before_set_reg = hsmmc2_before_set_reg;
                        mmc->slots[0].after_set_reg = NULL;
                }
                break;
+       case 3:
        case 4:
        case 5:
                mmc->slots[0].before_set_reg = NULL;
@@ -430,7 +430,7 @@ static int __init omap_hsmmc_pdata_init(struct omap2_hsmmc_info *c,
 
 #define MAX_OMAP_MMC_HWMOD_NAME_LEN            16
 
-void __init omap_init_hsmmc(struct omap2_hsmmc_info *hsmmcinfo, int ctrl_nr)
+void omap_init_hsmmc(struct omap2_hsmmc_info *hsmmcinfo, int ctrl_nr)
 {
        struct omap_hwmod *oh;
        struct platform_device *pdev;
@@ -487,7 +487,7 @@ done:
        kfree(mmc_data);
 }
 
-void __init omap2_hsmmc_init(struct omap2_hsmmc_info *controllers)
+void omap2_hsmmc_init(struct omap2_hsmmc_info *controllers)
 {
        u32 reg;
 
index 3f174d5..eb50c29 100644 (file)
@@ -388,7 +388,7 @@ static void __init omap_hwmod_init_postsetup(void)
        omap_pm_if_early_init();
 }
 
-#ifdef CONFIG_ARCH_OMAP2
+#ifdef CONFIG_SOC_OMAP2420
 void __init omap2420_init_early(void)
 {
        omap2_set_globals_242x();
@@ -400,7 +400,9 @@ void __init omap2420_init_early(void)
        omap_hwmod_init_postsetup();
        omap2420_clk_init();
 }
+#endif
 
+#ifdef CONFIG_SOC_OMAP2430
 void __init omap2430_init_early(void)
 {
        omap2_set_globals_243x();
index e1cc75d..fb8bc9f 100644 (file)
@@ -100,8 +100,8 @@ void omap_mux_write_array(struct omap_mux_partition *partition,
 
 static char *omap_mux_options;
 
-static int __init _omap_mux_init_gpio(struct omap_mux_partition *partition,
-                                     int gpio, int val)
+static int _omap_mux_init_gpio(struct omap_mux_partition *partition,
+                              int gpio, int val)
 {
        struct omap_mux_entry *e;
        struct omap_mux *gpio_mux = NULL;
@@ -145,7 +145,7 @@ static int __init _omap_mux_init_gpio(struct omap_mux_partition *partition,
        return 0;
 }
 
-int __init omap_mux_init_gpio(int gpio, int val)
+int omap_mux_init_gpio(int gpio, int val)
 {
        struct omap_mux_partition *partition;
        int ret;
@@ -159,9 +159,9 @@ int __init omap_mux_init_gpio(int gpio, int val)
        return -ENODEV;
 }
 
-static int __init _omap_mux_get_by_name(struct omap_mux_partition *partition,
-                                       const char *muxname,
-                                       struct omap_mux **found_mux)
+static int _omap_mux_get_by_name(struct omap_mux_partition *partition,
+                                const char *muxname,
+                                struct omap_mux **found_mux)
 {
        struct omap_mux *mux = NULL;
        struct omap_mux_entry *e;
@@ -240,7 +240,7 @@ omap_mux_get_by_name(const char *muxname,
        return -ENODEV;
 }
 
-int __init omap_mux_init_signal(const char *muxname, int val)
+int omap_mux_init_signal(const char *muxname, int val)
 {
        struct omap_mux_partition *partition = NULL;
        struct omap_mux *mux = NULL;
@@ -1094,8 +1094,8 @@ static void omap_mux_init_package(struct omap_mux *superset,
                omap_mux_package_init_balls(package_balls, superset);
 }
 
-static void omap_mux_init_signals(struct omap_mux_partition *partition,
-                                 struct omap_board_mux *board_mux)
+static void __init omap_mux_init_signals(struct omap_mux_partition *partition,
+                                        struct omap_board_mux *board_mux)
 {
        omap_mux_set_cmdline_signals();
        omap_mux_write_array(partition, board_mux);
@@ -1109,8 +1109,8 @@ static void omap_mux_init_package(struct omap_mux *superset,
 {
 }
 
-static void omap_mux_init_signals(struct omap_mux_partition *partition,
-                                 struct omap_board_mux *board_mux)
+static void __init omap_mux_init_signals(struct omap_mux_partition *partition,
+                                        struct omap_board_mux *board_mux)
 {
 }
 
index b13ef7e..503ac77 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/linkage.h>
 #include <linux/init.h>
 
+       __CPUINIT
 /*
  * OMAP4 specific entry point for secondary CPU to jump from ROM
  * code.  This routine also provides a holding flag into which
index 5192cab..eba6cd3 100644 (file)
@@ -1517,8 +1517,8 @@ static int _enable(struct omap_hwmod *oh)
        if (oh->_state != _HWMOD_STATE_INITIALIZED &&
            oh->_state != _HWMOD_STATE_IDLE &&
            oh->_state != _HWMOD_STATE_DISABLED) {
-               WARN(1, "omap_hwmod: %s: enabled state can only be entered "
-                    "from initialized, idle, or disabled state\n", oh->name);
+               WARN(1, "omap_hwmod: %s: enabled state can only be entered from initialized, idle, or disabled state\n",
+                       oh->name);
                return -EINVAL;
        }
 
@@ -1600,8 +1600,8 @@ static int _idle(struct omap_hwmod *oh)
        pr_debug("omap_hwmod: %s: idling\n", oh->name);
 
        if (oh->_state != _HWMOD_STATE_ENABLED) {
-               WARN(1, "omap_hwmod: %s: idle state can only be entered from "
-                    "enabled state\n", oh->name);
+               WARN(1, "omap_hwmod: %s: idle state can only be entered from enabled state\n",
+                       oh->name);
                return -EINVAL;
        }
 
@@ -1682,8 +1682,8 @@ static int _shutdown(struct omap_hwmod *oh)
 
        if (oh->_state != _HWMOD_STATE_IDLE &&
            oh->_state != _HWMOD_STATE_ENABLED) {
-               WARN(1, "omap_hwmod: %s: disabled state can only be entered "
-                    "from idle, or enabled state\n", oh->name);
+               WARN(1, "omap_hwmod: %s: disabled state can only be entered from idle, or enabled state\n",
+                       oh->name);
                return -EINVAL;
        }
 
@@ -2240,8 +2240,8 @@ void omap_hwmod_ocp_barrier(struct omap_hwmod *oh)
        BUG_ON(!oh);
 
        if (!oh->class->sysc || !oh->class->sysc->sysc_flags) {
-               WARN(1, "omap_device: %s: OCP barrier impossible due to "
-                     "device configuration\n", oh->name);
+               WARN(1, "omap_device: %s: OCP barrier impossible due to device configuration\n",
+                       oh->name);
                return;
        }
 
index c11273d..f08e442 100644 (file)
@@ -55,27 +55,6 @@ struct omap_hwmod_class omap2_dss_hwmod_class = {
        .reset  = omap_dss_reset,
 };
 
-/*
- * 'dispc' class
- * display controller
- */
-
-static struct omap_hwmod_class_sysconfig omap2_dispc_sysc = {
-       .rev_offs       = 0x0000,
-       .sysc_offs      = 0x0010,
-       .syss_offs      = 0x0014,
-       .sysc_flags     = (SYSC_HAS_SIDLEMODE | SYSC_HAS_MIDLEMODE |
-                          SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE),
-       .idlemodes      = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
-                          MSTANDBY_FORCE | MSTANDBY_NO | MSTANDBY_SMART),
-       .sysc_fields    = &omap_hwmod_sysc_type1,
-};
-
-struct omap_hwmod_class omap2_dispc_hwmod_class = {
-       .name   = "dispc",
-       .sysc   = &omap2_dispc_sysc,
-};
-
 /*
  * 'rfbi' class
  * remote frame buffer interface
index 177dee2..2a67297 100644 (file)
@@ -28,6 +28,28 @@ struct omap_hwmod_dma_info omap2xxx_dss_sdma_chs[] = {
        { .name = "dispc", .dma_req = 5 },
        { .dma_req = -1 }
 };
+
+/*
+ * 'dispc' class
+ * display controller
+ */
+
+static struct omap_hwmod_class_sysconfig omap2_dispc_sysc = {
+       .rev_offs       = 0x0000,
+       .sysc_offs      = 0x0010,
+       .syss_offs      = 0x0014,
+       .sysc_flags     = (SYSC_HAS_SIDLEMODE | SYSC_HAS_MIDLEMODE |
+                          SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE),
+       .idlemodes      = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
+                          MSTANDBY_FORCE | MSTANDBY_NO | MSTANDBY_SMART),
+       .sysc_fields    = &omap_hwmod_sysc_type1,
+};
+
+struct omap_hwmod_class omap2_dispc_hwmod_class = {
+       .name   = "dispc",
+       .sysc   = &omap2_dispc_sysc,
+};
+
 /* OMAP2xxx Timer Common */
 static struct omap_hwmod_class_sysconfig omap2xxx_timer_sysc = {
        .rev_offs       = 0x0000,
index 5324e8d..3c8dd92 100644 (file)
@@ -1480,6 +1480,28 @@ static struct omap_hwmod omap3xxx_dss_core_hwmod = {
        .masters_cnt    = ARRAY_SIZE(omap3xxx_dss_masters),
 };
 
+/*
+ * 'dispc' class
+ * display controller
+ */
+
+static struct omap_hwmod_class_sysconfig omap3_dispc_sysc = {
+       .rev_offs       = 0x0000,
+       .sysc_offs      = 0x0010,
+       .syss_offs      = 0x0014,
+       .sysc_flags     = (SYSC_HAS_SIDLEMODE | SYSC_HAS_MIDLEMODE |
+                          SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE |
+                          SYSC_HAS_ENAWAKEUP),
+       .idlemodes      = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
+                          MSTANDBY_FORCE | MSTANDBY_NO | MSTANDBY_SMART),
+       .sysc_fields    = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class omap3_dispc_hwmod_class = {
+       .name   = "dispc",
+       .sysc   = &omap3_dispc_sysc,
+};
+
 /* l4_core -> dss_dispc */
 static struct omap_hwmod_ocp_if omap3xxx_l4_core__dss_dispc = {
        .master         = &omap3xxx_l4_core_hwmod,
@@ -1503,7 +1525,7 @@ static struct omap_hwmod_ocp_if *omap3xxx_dss_dispc_slaves[] = {
 
 static struct omap_hwmod omap3xxx_dss_dispc_hwmod = {
        .name           = "dss_dispc",
-       .class          = &omap2_dispc_hwmod_class,
+       .class          = &omap3_dispc_hwmod_class,
        .mpu_irqs       = omap2_dispc_irqs,
        .main_clk       = "dss1_alwon_fck",
        .prcm           = {
@@ -3523,12 +3545,6 @@ static __initdata struct omap_hwmod *omap3xxx_hwmods[] = {
        &omap3xxx_uart2_hwmod,
        &omap3xxx_uart3_hwmod,
 
-       /* dss class */
-       &omap3xxx_dss_dispc_hwmod,
-       &omap3xxx_dss_dsi1_hwmod,
-       &omap3xxx_dss_rfbi_hwmod,
-       &omap3xxx_dss_venc_hwmod,
-
        /* i2c class */
        &omap3xxx_i2c1_hwmod,
        &omap3xxx_i2c2_hwmod,
@@ -3635,6 +3651,15 @@ static __initdata struct omap_hwmod *am35xx_hwmods[] = {
        NULL
 };
 
+static __initdata struct omap_hwmod *omap3xxx_dss_hwmods[] = {
+       /* dss class */
+       &omap3xxx_dss_dispc_hwmod,
+       &omap3xxx_dss_dsi1_hwmod,
+       &omap3xxx_dss_rfbi_hwmod,
+       &omap3xxx_dss_venc_hwmod,
+       NULL
+};
+
 int __init omap3xxx_hwmod_init(void)
 {
        int r;
@@ -3708,6 +3733,21 @@ int __init omap3xxx_hwmod_init(void)
 
        if (h)
                r = omap_hwmod_register(h);
+       if (r < 0)
+               return r;
+
+       /*
+        * DSS code presumes that dss_core hwmod is handled first,
+        * _before_ any other DSS related hwmods so register common
+        * DSS hwmods last to ensure that dss_core is already registered.
+        * Otherwise some change things may happen, for ex. if dispc
+        * is handled before dss_core and DSS is enabled in bootloader
+        * DIPSC will be reset with outputs enabled which sometimes leads
+        * to unrecoverable L3 error.
+        * XXX The long-term fix to this is to ensure modules are set up
+        * in dependency order in the hwmod core code.
+        */
+       r = omap_hwmod_register(omap3xxx_dss_hwmods);
 
        return r;
 }
index f9f1510..ef0524c 100644 (file)
@@ -1031,6 +1031,7 @@ static struct omap_hwmod_dma_info omap44xx_dmic_sdma_reqs[] = {
 
 static struct omap_hwmod_addr_space omap44xx_dmic_addrs[] = {
        {
+               .name           = "mpu",
                .pa_start       = 0x4012e000,
                .pa_end         = 0x4012e07f,
                .flags          = ADDR_TYPE_RT
@@ -1049,6 +1050,7 @@ static struct omap_hwmod_ocp_if omap44xx_l4_abe__dmic = {
 
 static struct omap_hwmod_addr_space omap44xx_dmic_dma_addrs[] = {
        {
+               .name           = "dma",
                .pa_start       = 0x4902e000,
                .pa_end         = 0x4902e07f,
                .flags          = ADDR_TYPE_RT
index c1c4d86..9ce7654 100644 (file)
@@ -19,6 +19,7 @@
 #include "common.h"
 #include <plat/cpu.h>
 #include <plat/prcm.h>
+#include <plat/irqs.h>
 
 #include "vp.h"
 
index 33dd655..a1d6154 100644 (file)
@@ -19,6 +19,7 @@
 
 #include "common.h"
 #include <plat/cpu.h>
+#include <plat/irqs.h>
 #include <plat/prcm.h>
 
 #include "vp.h"
index 247d894..f590afc 100644 (file)
@@ -107,18 +107,18 @@ static void omap_uart_set_noidle(struct platform_device *pdev)
        omap_hwmod_set_slave_idlemode(od->hwmods[0], HWMOD_IDLEMODE_NO);
 }
 
-static void omap_uart_set_forceidle(struct platform_device *pdev)
+static void omap_uart_set_smartidle(struct platform_device *pdev)
 {
        struct omap_device *od = to_omap_device(pdev);
 
-       omap_hwmod_set_slave_idlemode(od->hwmods[0], HWMOD_IDLEMODE_FORCE);
+       omap_hwmod_set_slave_idlemode(od->hwmods[0], HWMOD_IDLEMODE_SMART);
 }
 
 #else
 static void omap_uart_enable_wakeup(struct platform_device *pdev, bool enable)
 {}
 static void omap_uart_set_noidle(struct platform_device *pdev) {}
-static void omap_uart_set_forceidle(struct platform_device *pdev) {}
+static void omap_uart_set_smartidle(struct platform_device *pdev) {}
 #endif /* CONFIG_PM */
 
 #ifdef CONFIG_OMAP_MUX
@@ -349,7 +349,7 @@ void __init omap_serial_init_port(struct omap_board_data *bdata,
        omap_up.uartclk = OMAP24XX_BASE_BAUD * 16;
        omap_up.flags = UPF_BOOT_AUTOCONF;
        omap_up.get_context_loss_count = omap_pm_get_dev_context_loss_count;
-       omap_up.set_forceidle = omap_uart_set_forceidle;
+       omap_up.set_forceidle = omap_uart_set_smartidle;
        omap_up.set_noidle = omap_uart_set_noidle;
        omap_up.enable_wakeup = omap_uart_enable_wakeup;
        omap_up.dma_rx_buf_size = info->dma_rx_buf_size;
index 9dd9345..7e755bb 100644 (file)
@@ -897,7 +897,7 @@ static int __init omap_sr_probe(struct platform_device *pdev)
                ret = sr_late_init(sr_info);
                if (ret) {
                        pr_warning("%s: Error in SR late init\n", __func__);
-                       return ret;
+                       goto err_iounmap;
                }
        }
 
index 6eeff0e..5c9acea 100644 (file)
@@ -270,7 +270,7 @@ static struct clocksource clocksource_gpt = {
 static u32 notrace dmtimer_read_sched_clock(void)
 {
        if (clksrc.reserved)
-               return __omap_dm_timer_read_counter(clksrc.io_base, 1);
+               return __omap_dm_timer_read_counter(&clksrc, 1);
 
        return 0;
 }
index 031d116..175b7d8 100644 (file)
@@ -247,7 +247,7 @@ static void __init omap4_vc_init_channel(struct voltagedomain *voltdm)
  * omap_vc_i2c_init - initialize I2C interface to PMIC
  * @voltdm: voltage domain containing VC data
  *
- * Use PMIC supplied seetings for I2C high-speed mode and
+ * Use PMIC supplied settings for I2C high-speed mode and
  * master code (if set) and program the VC I2C configuration
  * register.
  *
@@ -265,8 +265,8 @@ static void __init omap_vc_i2c_init(struct voltagedomain *voltdm)
 
        if (initialized) {
                if (voltdm->pmic->i2c_high_speed != i2c_high_speed)
-                       pr_warn("%s: I2C config for all channels must match.",
-                               __func__);
+                       pr_warn("%s: I2C config for vdd_%s does not match other channels (%u).",
+                               __func__, voltdm->name, i2c_high_speed);
                return;
        }
 
@@ -292,9 +292,7 @@ void __init omap_vc_init_channel(struct voltagedomain *voltdm)
        u32 val;
 
        if (!voltdm->pmic || !voltdm->pmic->uv_to_vsel) {
-               pr_err("%s: PMIC info requried to configure vc for"
-                       "vdd_%s not populated.Hence cannot initialize vc\n",
-                       __func__, voltdm->name);
+               pr_err("%s: No PMIC info for vdd_%s\n", __func__, voltdm->name);
                return;
        }
 
index 807391d..0df8882 100644 (file)
@@ -41,6 +41,11 @@ void __init omap_vp_init(struct voltagedomain *voltdm)
        u32 val, sys_clk_rate, timeout, waittime;
        u32 vddmin, vddmax, vstepmin, vstepmax;
 
+       if (!voltdm->pmic || !voltdm->pmic->uv_to_vsel) {
+               pr_err("%s: No PMIC info for vdd_%s\n", __func__, voltdm->name);
+               return;
+       }
+
        if (!voltdm->read || !voltdm->write) {
                pr_err("%s: No read/write API for accessing vdd_%s regs\n",
                        __func__, voltdm->name);
index 18fd177..5bc1312 100644 (file)
@@ -415,29 +415,9 @@ static struct resource pxa_rtc_resources[] = {
        },
 };
 
-static struct resource sa1100_rtc_resources[] = {
-       [0] = {
-               .start  = 0x40900000,
-               .end    = 0x409000ff,
-               .flags  = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start  = IRQ_RTC1Hz,
-               .end    = IRQ_RTC1Hz,
-               .flags  = IORESOURCE_IRQ,
-       },
-       [2] = {
-               .start  = IRQ_RTCAlrm,
-               .end    = IRQ_RTCAlrm,
-               .flags  = IORESOURCE_IRQ,
-       },
-};
-
 struct platform_device sa1100_device_rtc = {
        .name           = "sa1100-rtc",
        .id             = -1,
-       .num_resources  = ARRAY_SIZE(sa1100_rtc_resources),
-       .resource       = sa1100_rtc_resources,
 };
 
 struct platform_device pxa_device_rtc = {
index adf058f..91e4f6c 100644 (file)
@@ -209,8 +209,6 @@ static struct clk_lookup pxa25x_clkregs[] = {
        INIT_CLKREG(&clk_pxa25x_gpio11, NULL, "GPIO11_CLK"),
        INIT_CLKREG(&clk_pxa25x_gpio12, NULL, "GPIO12_CLK"),
        INIT_CLKREG(&clk_pxa25x_mem, "pxa2xx-pcmcia", NULL),
-       INIT_CLKREG(&clk_dummy, "pxa-gpio", NULL),
-       INIT_CLKREG(&clk_dummy, "sa1100-rtc", NULL),
 };
 
 static struct clk_lookup pxa25x_hwuart_clkreg =
index 180bd86..aed6cbc 100644 (file)
@@ -230,8 +230,6 @@ static struct clk_lookup pxa27x_clkregs[] = {
        INIT_CLKREG(&clk_pxa27x_im, NULL, "IMCLK"),
        INIT_CLKREG(&clk_pxa27x_memc, NULL, "MEMCLK"),
        INIT_CLKREG(&clk_pxa27x_mem, "pxa2xx-pcmcia", NULL),
-       INIT_CLKREG(&clk_dummy, "pxa-gpio", NULL),
-       INIT_CLKREG(&clk_dummy, "sa1100-rtc", NULL),
 };
 
 #ifdef CONFIG_PM
index 0388eda..40bb165 100644 (file)
@@ -89,7 +89,6 @@ static DEFINE_PXA3_CKEN(gcu, PXA300_GCU, 0, 0);
 static struct clk_lookup common_clkregs[] = {
        INIT_CLKREG(&clk_common_nand, "pxa3xx-nand", NULL),
        INIT_CLKREG(&clk_gcu, "pxa3xx-gcu", NULL),
-       INIT_CLKREG(&clk_dummy, "sa1100-rtc", NULL),
 };
 
 static DEFINE_PXA3_CKEN(pxa310_mmc3, MMC3, 19500000, 0);
index d487e1f..8d614ec 100644 (file)
@@ -83,7 +83,6 @@ static DEFINE_PXA3_CKEN(gcu, PXA320_GCU, 0, 0);
 static struct clk_lookup pxa320_clkregs[] = {
        INIT_CLKREG(&clk_pxa320_nand, "pxa3xx-nand", NULL),
        INIT_CLKREG(&clk_gcu, "pxa3xx-gcu", NULL),
-       INIT_CLKREG(&clk_dummy, "sa1100-rtc", NULL),
 };
 
 static int __init pxa320_init(void)
index f107c71..4f402af 100644 (file)
@@ -67,7 +67,6 @@ static struct clk_lookup pxa3xx_clkregs[] = {
        INIT_CLKREG(&clk_pxa3xx_pout, NULL, "CLK_POUT"),
        /* Power I2C clock is always on */
        INIT_CLKREG(&clk_dummy, "pxa3xx-pwri2c.1", NULL),
-       INIT_CLKREG(&clk_dummy, "sa1100-rtc", NULL),
        INIT_CLKREG(&clk_pxa3xx_lcd, "pxa2xx-fb", NULL),
        INIT_CLKREG(&clk_pxa3xx_camera, NULL, "CAMCLK"),
        INIT_CLKREG(&clk_pxa3xx_ac97, NULL, "AC97CLK"),
index fccc644..d082a58 100644 (file)
@@ -217,7 +217,6 @@ static struct clk_lookup pxa95x_clkregs[] = {
        INIT_CLKREG(&clk_pxa95x_pout, NULL, "CLK_POUT"),
        /* Power I2C clock is always on */
        INIT_CLKREG(&clk_dummy, "pxa3xx-pwri2c.1", NULL),
-       INIT_CLKREG(&clk_dummy, "sa1100-rtc", NULL),
        INIT_CLKREG(&clk_pxa95x_lcd, "pxa2xx-fb", NULL),
        INIT_CLKREG(&clk_pxa95x_ffuart, "pxa2xx-uart.0", NULL),
        INIT_CLKREG(&clk_pxa95x_btuart, "pxa2xx-uart.1", NULL),
index ac1aed2..eb55f05 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/smp.h>
 
 #include <asm/cacheflush.h>
+#include <asm/smp_plat.h>
 
 extern volatile int pen_release;
 
index 794a8d9..124bce6 100644 (file)
 #define REALVIEW_EB_USB_BASE           0x4F000000      /* USB */
 
 #ifdef CONFIG_REALVIEW_EB_ARM11MP_REVB
-#define REALVIEW_EB11MP_SCU_BASE       0x10100000      /* SCU registers */
-#define REALVIEW_EB11MP_GIC_CPU_BASE   0x10100100      /* Generic interrupt controller CPU interface */
-#define REALVIEW_EB11MP_TWD_BASE       0x10100600
-#define REALVIEW_EB11MP_GIC_DIST_BASE  0x10101000      /* Generic interrupt controller distributor */
+#define REALVIEW_EB11MP_PRIV_MEM_BASE  0x1F000000
 #define REALVIEW_EB11MP_L220_BASE      0x10102000      /* L220 registers */
 #define REALVIEW_EB11MP_SYS_PLD_CTRL1  0xD8            /* Register offset for MPCore sysctl */
 #else
-#define REALVIEW_EB11MP_SCU_BASE       0x1F000000      /* SCU registers */
-#define REALVIEW_EB11MP_GIC_CPU_BASE   0x1F000100      /* Generic interrupt controller CPU interface */
-#define REALVIEW_EB11MP_TWD_BASE       0x1F000600
-#define REALVIEW_EB11MP_GIC_DIST_BASE  0x1F001000      /* Generic interrupt controller distributor */
+#define REALVIEW_EB11MP_PRIV_MEM_BASE  0x1F000000
 #define REALVIEW_EB11MP_L220_BASE      0x1F002000      /* L220 registers */
 #define REALVIEW_EB11MP_SYS_PLD_CTRL1  0x74            /* Register offset for MPCore sysctl */
 #endif
 
+#define REALVIEW_EB11MP_PRIV_MEM_SIZE  SZ_8K
+#define REALVIEW_EB11MP_PRIV_MEM_OFF(x)        (REALVIEW_EB11MP_PRIV_MEM_BASE + (x))
+
+#define REALVIEW_EB11MP_SCU_BASE       REALVIEW_EB11MP_PRIV_MEM_OFF(0)         /* SCU registers */
+#define REALVIEW_EB11MP_GIC_CPU_BASE   REALVIEW_EB11MP_PRIV_MEM_OFF(0x0100)    /* Generic interrupt controller CPU interface */
+#define REALVIEW_EB11MP_TWD_BASE       REALVIEW_EB11MP_PRIV_MEM_OFF(0x0600)
+#define REALVIEW_EB11MP_GIC_DIST_BASE  REALVIEW_EB11MP_PRIV_MEM_OFF(0x1000)    /* Generic interrupt controller distributor */
+
 /*
  * Core tile identification (REALVIEW_SYS_PROCID)
  */
index 7abf918..aa2d4e0 100644 (file)
@@ -75,6 +75,8 @@
 /*
  * Testchip peripheral and fpga gic regions
  */
+#define REALVIEW_TC11MP_PRIV_MEM_BASE          0x1F000000
+#define REALVIEW_TC11MP_PRIV_MEM_SIZE          SZ_8K
 #define REALVIEW_TC11MP_SCU_BASE               0x1F000000      /* IRQ, Test chip */
 #define REALVIEW_TC11MP_GIC_CPU_BASE           0x1F000100      /* Test chip interrupt controller CPU interface */
 #define REALVIEW_TC11MP_TWD_BASE               0x1F000600
index e629621..9578145 100644 (file)
@@ -91,14 +91,9 @@ static struct map_desc realview_eb_io_desc[] __initdata = {
 
 static struct map_desc realview_eb11mp_io_desc[] __initdata = {
        {
-               .virtual        = IO_ADDRESS(REALVIEW_EB11MP_SCU_BASE),
-               .pfn            = __phys_to_pfn(REALVIEW_EB11MP_SCU_BASE),
-               .length         = SZ_4K,
-               .type           = MT_DEVICE,
-       }, {
-               .virtual        = IO_ADDRESS(REALVIEW_EB11MP_GIC_DIST_BASE),
-               .pfn            = __phys_to_pfn(REALVIEW_EB11MP_GIC_DIST_BASE),
-               .length         = SZ_4K,
+               .virtual        = IO_ADDRESS(REALVIEW_EB11MP_PRIV_MEM_BASE),
+               .pfn            = __phys_to_pfn(REALVIEW_EB11MP_PRIV_MEM_BASE),
+               .length         = REALVIEW_EB11MP_PRIV_MEM_SIZE,
                .type           = MT_DEVICE,
        }, {
                .virtual        = IO_ADDRESS(REALVIEW_EB11MP_L220_BASE),
index 127a3fd..2147335 100644 (file)
@@ -64,15 +64,10 @@ static struct map_desc realview_pb11mp_io_desc[] __initdata = {
                .pfn            = __phys_to_pfn(REALVIEW_PB11MP_GIC_DIST_BASE),
                .length         = SZ_4K,
                .type           = MT_DEVICE,
-       }, {
-               .virtual        = IO_ADDRESS(REALVIEW_TC11MP_GIC_CPU_BASE),
-               .pfn            = __phys_to_pfn(REALVIEW_TC11MP_GIC_CPU_BASE),
-               .length         = SZ_4K,
-               .type           = MT_DEVICE,
-       }, {
-               .virtual        = IO_ADDRESS(REALVIEW_TC11MP_GIC_DIST_BASE),
-               .pfn            = __phys_to_pfn(REALVIEW_TC11MP_GIC_DIST_BASE),
-               .length         = SZ_4K,
+       }, {    /* Maps the SCU, GIC CPU interface, TWD, GIC DIST */
+               .virtual        = IO_ADDRESS(REALVIEW_TC11MP_PRIV_MEM_BASE),
+               .pfn            = __phys_to_pfn(REALVIEW_TC11MP_PRIV_MEM_BASE),
+               .length         = REALVIEW_TC11MP_PRIV_MEM_SIZE,
                .type           = MT_DEVICE,
        }, {
                .virtual        = IO_ADDRESS(REALVIEW_SCTL_BASE),
index ebafe8a..0c4b76a 100644 (file)
@@ -202,7 +202,6 @@ static struct irda_platform_data assabet_irda_data = {
 static struct mcp_plat_data assabet_mcp_data = {
        .mccr0          = MCCR0_ADM,
        .sclk_rate      = 11981000,
-       .codec          = "ucb1x00",
 };
 
 static void __init assabet_init(void)
@@ -253,17 +252,6 @@ static void __init assabet_init(void)
        sa11x0_register_mtd(&assabet_flash_data, assabet_flash_resources,
                            ARRAY_SIZE(assabet_flash_resources));
        sa11x0_register_irda(&assabet_irda_data);
-
-       /*
-        * Setup the PPC unit correctly.
-        */
-       PPDR &= ~PPC_RXD4;
-       PPDR |= PPC_TXD4 | PPC_SCLK | PPC_SFRM;
-       PSDR |= PPC_RXD4;
-       PSDR &= ~(PPC_TXD4 | PPC_SCLK | PPC_SFRM);
-       PPSR &= ~(PPC_TXD4 | PPC_SCLK | PPC_SFRM);
-
-       ASSABET_BCR_set(ASSABET_BCR_CODEC_RST);
        sa11x0_register_mcp(&assabet_mcp_data);
 }
 
index d12d0f4..11bb6d0 100644 (file)
@@ -124,23 +124,12 @@ static void __init cerf_map_io(void)
 static struct mcp_plat_data cerf_mcp_data = {
        .mccr0          = MCCR0_ADM,
        .sclk_rate      = 11981000,
-       .codec          = "ucb1x00",
 };
 
 static void __init cerf_init(void)
 {
        platform_add_devices(cerf_devices, ARRAY_SIZE(cerf_devices));
        sa11x0_register_mtd(&cerf_flash_data, &cerf_flash_resource, 1);
-
-       /*
-        * Setup the PPC unit correctly.
-        */
-       PPDR &= ~PPC_RXD4;
-       PPDR |= PPC_TXD4 | PPC_SCLK | PPC_SFRM;
-       PSDR |= PPC_RXD4;
-       PSDR &= ~(PPC_TXD4 | PPC_SCLK | PPC_SFRM);
-       PPSR &= ~(PPC_TXD4 | PPC_SCLK | PPC_SFRM);
-
        sa11x0_register_mcp(&cerf_mcp_data);
 }
 
index d6df9f6..dab3c63 100644 (file)
 #include <linux/clk.h>
 #include <linux/spinlock.h>
 #include <linux/mutex.h>
-#include <linux/io.h>
-#include <linux/clkdev.h>
 
 #include <mach/hardware.h>
 
-struct clkops {
-       void                    (*enable)(struct clk *);
-       void                    (*disable)(struct clk *);
-       unsigned long           (*getrate)(struct clk *);
-};
-
+/*
+ * Very simple clock implementation - we only have one clock to deal with.
+ */
 struct clk {
-       const struct clkops     *ops;
-       unsigned long           rate;
        unsigned int            enabled;
 };
 
-#define INIT_CLKREG(_clk, _devname, _conname)          \
-       {                                               \
-               .clk            = _clk,                 \
-               .dev_id         = _devname,             \
-               .con_id         = _conname,             \
-       }
-
-#define DEFINE_CLK(_name, _ops, _rate)                 \
-struct clk clk_##_name = {                             \
-               .ops    = _ops,                         \
-               .rate   = _rate,                        \
-       }
-
-static DEFINE_SPINLOCK(clocks_lock);
-
-static void clk_gpio27_enable(struct clk *clk)
+static void clk_gpio27_enable(void)
 {
        /*
         * First, set up the 3.6864MHz clock on GPIO 27 for the SA-1111:
@@ -54,22 +32,38 @@ static void clk_gpio27_enable(struct clk *clk)
        TUCR = TUCR_3_6864MHz;
 }
 
-static void clk_gpio27_disable(struct clk *clk)
+static void clk_gpio27_disable(void)
 {
        TUCR = 0;
        GPDR &= ~GPIO_32_768kHz;
        GAFR &= ~GPIO_32_768kHz;
 }
 
+static struct clk clk_gpio27;
+
+static DEFINE_SPINLOCK(clocks_lock);
+
+struct clk *clk_get(struct device *dev, const char *id)
+{
+       const char *devname = dev_name(dev);
+
+       return strcmp(devname, "sa1111.0") ? ERR_PTR(-ENOENT) : &clk_gpio27;
+}
+EXPORT_SYMBOL(clk_get);
+
+void clk_put(struct clk *clk)
+{
+}
+EXPORT_SYMBOL(clk_put);
+
 int clk_enable(struct clk *clk)
 {
        unsigned long flags;
 
        spin_lock_irqsave(&clocks_lock, flags);
        if (clk->enabled++ == 0)
-               clk->ops->enable(clk);
+               clk_gpio27_enable();
        spin_unlock_irqrestore(&clocks_lock, flags);
-
        return 0;
 }
 EXPORT_SYMBOL(clk_enable);
@@ -82,48 +76,13 @@ void clk_disable(struct clk *clk)
 
        spin_lock_irqsave(&clocks_lock, flags);
        if (--clk->enabled == 0)
-               clk->ops->disable(clk);
+               clk_gpio27_disable();
        spin_unlock_irqrestore(&clocks_lock, flags);
 }
 EXPORT_SYMBOL(clk_disable);
 
 unsigned long clk_get_rate(struct clk *clk)
 {
-       unsigned long rate;
-
-       rate = clk->rate;
-       if (clk->ops->getrate)
-               rate = clk->ops->getrate(clk);
-
-       return rate;
+       return 3686400;
 }
 EXPORT_SYMBOL(clk_get_rate);
-
-const struct clkops clk_gpio27_ops = {
-       .enable         = clk_gpio27_enable,
-       .disable        = clk_gpio27_disable,
-};
-
-static void clk_dummy_enable(struct clk *clk) { }
-static void clk_dummy_disable(struct clk *clk) { }
-
-const struct clkops clk_dummy_ops = {
-       .enable         = clk_dummy_enable,
-       .disable        = clk_dummy_disable,
-};
-
-static DEFINE_CLK(gpio27, &clk_gpio27_ops, 3686400);
-static DEFINE_CLK(dummy, &clk_dummy_ops, 0);
-
-static struct clk_lookup sa11xx_clkregs[] = {
-       INIT_CLKREG(&clk_gpio27, "sa1111.0", NULL),
-       INIT_CLKREG(&clk_dummy, "sa1100-rtc", NULL),
-};
-
-static int __init sa11xx_clk_init(void)
-{
-       clkdev_add_table(sa11xx_clkregs, ARRAY_SIZE(sa11xx_clkregs));
-       return 0;
-}
-
-postcore_initcall(sa11xx_clk_init);
index c483912..fd56521 100644 (file)
@@ -27,7 +27,6 @@
 #include <linux/timer.h>
 #include <linux/gpio.h>
 #include <linux/pda_power.h>
-#include <linux/mfd/ucb1x00.h>
 
 #include <mach/hardware.h>
 #include <asm/mach-types.h>
@@ -86,15 +85,10 @@ static struct scoop_pcmcia_config collie_pcmcia_config = {
        .num_devs       = 1,
 };
 
-static struct ucb1x00_plat_data collie_ucb1x00_data = {
-       .gpio_base      = COLLIE_TC35143_GPIO_BASE,
-};
-
 static struct mcp_plat_data collie_mcp_data = {
        .mccr0          = MCCR0_ADM | MCCR0_ExtClk,
        .sclk_rate      = 9216000,
-       .codec          = "ucb1x00",
-       .codec_pdata    = &collie_ucb1x00_data,
+       .gpio_base      = COLLIE_TC35143_GPIO_BASE,
 };
 
 /*
@@ -144,8 +138,6 @@ static struct pda_power_pdata collie_power_data = {
 static struct resource collie_power_resource[] = {
        {
                .name           = "ac",
-               .start          = gpio_to_irq(COLLIE_GPIO_AC_IN),
-               .end            = gpio_to_irq(COLLIE_GPIO_AC_IN),
                .flags          = IORESOURCE_IRQ |
                                  IORESOURCE_IRQ_HIGHEDGE |
                                  IORESOURCE_IRQ_LOWEDGE,
@@ -347,7 +339,8 @@ static void __init collie_init(void)
 
        GPSR |= _COLLIE_GPIO_UCB1x00_RESET;
 
-
+       collie_power_resource[0].start = gpio_to_irq(COLLIE_GPIO_AC_IN);
+       collie_power_resource[0].end = gpio_to_irq(COLLIE_GPIO_AC_IN);
        platform_scoop_config = &collie_pcmcia_config;
 
        ret = platform_add_devices(devices, ARRAY_SIZE(devices));
@@ -357,16 +350,6 @@ static void __init collie_init(void)
 
        sa11x0_register_mtd(&collie_flash_data, collie_flash_resources,
                            ARRAY_SIZE(collie_flash_resources));
-
-       /*
-        * Setup the PPC unit correctly.
-        */
-       PPDR &= ~PPC_RXD4;
-       PPDR |= PPC_TXD4 | PPC_SCLK | PPC_SFRM;
-       PSDR |= PPC_RXD4;
-       PSDR &= ~(PPC_TXD4 | PPC_SCLK | PPC_SFRM);
-       PPSR &= ~(PPC_TXD4 | PPC_SCLK | PPC_SFRM);
-
        sa11x0_register_mcp(&collie_mcp_data);
 
        sharpsl_save_param();
index aaa8acf..19b2053 100644 (file)
@@ -228,7 +228,7 @@ static int __init sa1100_cpu_init(struct cpufreq_policy *policy)
        return 0;
 }
 
-static struct cpufreq_driver sa1100_driver = {
+static struct cpufreq_driver sa1100_driver __refdata = {
        .flags          = CPUFREQ_STICKY,
        .verify         = sa11x0_verify_speed,
        .target         = sa1100_target,
index e3a28ca..bb10ee2 100644 (file)
@@ -217,15 +217,10 @@ static struct platform_device sa11x0uart3_device = {
 static struct resource sa11x0mcp_resources[] = {
        [0] = {
                .start  = __PREG(Ser4MCCR0),
-               .end    = __PREG(Ser4MCCR0) + 0x1C - 1,
+               .end    = __PREG(Ser4MCCR0) + 0xffff,
                .flags  = IORESOURCE_MEM,
        },
        [1] = {
-               .start  = __PREG(Ser4MCCR1),
-               .end    = __PREG(Ser4MCCR1) + 0x4 - 1,
-               .flags  = IORESOURCE_MEM,
-       },
-       [2] = {
                .start  = IRQ_Ser4MCP,
                .end    = IRQ_Ser4MCP,
                .flags  = IORESOURCE_IRQ,
@@ -350,29 +345,9 @@ void sa11x0_register_irda(struct irda_platform_data *irda)
        sa11x0_register_device(&sa11x0ir_device, irda);
 }
 
-static struct resource sa11x0rtc_resources[] = {
-       [0] = {
-               .start  = 0x90010000,
-               .end    = 0x900100ff,
-               .flags  = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start  = IRQ_RTC1Hz,
-               .end    = IRQ_RTC1Hz,
-               .flags  = IORESOURCE_IRQ,
-       },
-       [2] = {
-               .start  = IRQ_RTCAlrm,
-               .end    = IRQ_RTCAlrm,
-               .flags  = IORESOURCE_IRQ,
-       },
-};
-
 static struct platform_device sa11x0rtc_device = {
        .name           = "sa1100-rtc",
        .id             = -1,
-       .resource       = sa11x0rtc_resources,
-       .num_resources  = ARRAY_SIZE(sa11x0rtc_resources),
 };
 
 static struct platform_device *sa11x0_devices[] __initdata = {
index 586cec8..ed1a331 100644 (file)
@@ -17,8 +17,6 @@ struct mcp_plat_data {
        u32 mccr1;
        unsigned int sclk_rate;
        int gpio_base;
-       const char *codec;
-       void *codec_pdata;
 };
 
 #endif
index f50b00b..b412fc0 100644 (file)
@@ -198,3 +198,5 @@ static int __init jornada_ssp_init(void)
 {
        return platform_driver_register(&jornadassp_driver);
 }
+
+module_init(jornada_ssp_init);
index d117cea..af4e276 100644 (file)
 static struct mcp_plat_data lart_mcp_data = {
        .mccr0          = MCCR0_ADM,
        .sclk_rate      = 11981000,
-       .codec          = "ucb1x00",
 };
 
 static void __init lart_init(void)
 {
-       /*
-        * Setup the PPC unit correctly.
-        */
-       PPDR &= ~PPC_RXD4;
-       PPDR |= PPC_TXD4 | PPC_SCLK | PPC_SFRM;
-       PSDR |= PPC_RXD4;
-       PSDR &= ~(PPC_TXD4 | PPC_SCLK | PPC_SFRM);
-       PPSR &= ~(PPC_TXD4 | PPC_SCLK | PPC_SFRM);
-
        sa11x0_register_mcp(&lart_mcp_data);
 }
 
index 748d344..318b2b7 100644 (file)
@@ -55,22 +55,11 @@ static struct resource shannon_flash_resource = {
 static struct mcp_plat_data shannon_mcp_data = {
        .mccr0          = MCCR0_ADM,
        .sclk_rate      = 11981000,
-       .codec          = "ucb1x00",
 };
 
 static void __init shannon_init(void)
 {
        sa11x0_register_mtd(&shannon_flash_data, &shannon_flash_resource, 1);
-
-       /*
-        * Setup the PPC unit correctly.
-        */
-       PPDR &= ~PPC_RXD4;
-       PPDR |= PPC_TXD4 | PPC_SCLK | PPC_SFRM;
-       PSDR |= PPC_RXD4;
-       PSDR &= ~(PPC_TXD4 | PPC_SCLK | PPC_SFRM);
-       PPSR &= ~(PPC_TXD4 | PPC_SCLK | PPC_SFRM);
-
        sa11x0_register_mcp(&shannon_mcp_data);
 }
 
index 458ecec..e17c04d 100644 (file)
@@ -14,7 +14,6 @@
 #include <linux/mtd/partitions.h>
 #include <linux/io.h>
 #include <linux/gpio.h>
-#include <linux/mfd/ucb1x00.h>
 
 #include <asm/irq.h>
 #include <mach/hardware.h>
@@ -188,15 +187,10 @@ static struct resource simpad_flash_resources [] = {
        }
 };
 
-static struct ucb1x00_plat_data simpad_ucb1x00_data = {
-       .gpio_base      = SIMPAD_UCB1X00_GPIO_BASE,
-};
-
 static struct mcp_plat_data simpad_mcp_data = {
        .mccr0          = MCCR0_ADM,
        .sclk_rate      = 11981000,
-       .codec          = "ucb1300",
-       .codec_pdata    = &simpad_ucb1x00_data,
+       .gpio_base      = SIMPAD_UCB1X00_GPIO_BASE,
 };
 
 
@@ -384,16 +378,6 @@ static int __init simpad_init(void)
 
        sa11x0_register_mtd(&simpad_flash_data, simpad_flash_resources,
                              ARRAY_SIZE(simpad_flash_resources));
-
-       /*
-        * Setup the PPC unit correctly.
-        */
-       PPDR &= ~PPC_RXD4;
-       PPDR |= PPC_TXD4 | PPC_SCLK | PPC_SFRM;
-       PSDR |= PPC_RXD4;
-       PSDR &= ~(PPC_TXD4 | PPC_SCLK | PPC_SFRM);
-       PPSR &= ~(PPC_TXD4 | PPC_SCLK | PPC_SFRM);
-
        sa11x0_register_mcp(&simpad_mcp_data);
 
        ret = platform_add_devices(devices, ARRAY_SIZE(devices));
index 6fcf304..a83cf51 100644 (file)
@@ -662,6 +662,7 @@ static struct sh_dmae_pdata usb_dma0_platform_data = {
        .dmaor_is_32bit = 1,
        .needs_tend_set = 1,
        .no_dmars       = 1,
+       .slave_only     = 1,
 };
 
 static struct resource sh7372_usb_dmae0_resources[] = {
@@ -723,6 +724,7 @@ static struct sh_dmae_pdata usb_dma1_platform_data = {
        .dmaor_is_32bit = 1,
        .needs_tend_set = 1,
        .no_dmars       = 1,
+       .slave_only     = 1,
 };
 
 static struct resource sh7372_usb_dmae1_resources[] = {
index cc97ef8..4fe2e9e 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/delay.h>
 #include <mach/common.h>
 #include <mach/r8a7779.h>
+#include <asm/smp_plat.h>
 #include <asm/smp_scu.h>
 #include <asm/smp_twd.h>
 #include <asm/hardware/gic.h>
index be1ade7..0d159d6 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/spinlock.h>
 #include <linux/io.h>
 #include <mach/common.h>
+#include <asm/smp_plat.h>
 #include <asm/smp_scu.h>
 #include <asm/smp_twd.h>
 #include <asm/hardware/gic.h>
index a3e0c86..52af004 100644 (file)
@@ -7,6 +7,7 @@ config UX500_SOC_COMMON
        select HAS_MTU
        select ARM_ERRATA_753970
        select ARM_ERRATA_754322
+       select ARM_ERRATA_764369
 
 menu "Ux500 SoC"
 
index 23be34b..5dde4d4 100644 (file)
@@ -261,6 +261,8 @@ void __init mop500_sdi_init(void)
 
 void __init snowball_sdi_init(void)
 {
+       /* On Snowball MMC_CAP_SD_HIGHSPEED isn't supported (Hardware issue?) */
+       mop500_sdi0_data.capabilities &= ~MMC_CAP_SD_HIGHSPEED;
        /* On-board eMMC */
        db8500_add_sdi4(&mop500_sdi4_data, U8500_SDI_V2_PERIPHID);
        /* External Micro SD slot */
index 122ddde..da5569d 100644 (file)
 
 static void __iomem *l2x0_base;
 
-static inline void ux500_cache_wait(void __iomem *reg, unsigned long mask)
-{
-       /* wait for the operation to complete */
-       while (readl_relaxed(reg) & mask)
-               cpu_relax();
-}
-
-static inline void ux500_cache_sync(void)
-{
-       writel_relaxed(0, l2x0_base + L2X0_CACHE_SYNC);
-       ux500_cache_wait(l2x0_base + L2X0_CACHE_SYNC, 1);
-}
-
-/*
- * The L2 cache cannot be turned off in the non-secure world.
- * Dummy until a secure service is in place.
- */
-static void ux500_l2x0_disable(void)
-{
-}
-
-/*
- * This is only called when doing a kexec, just after turning off the L2
- * and L1 cache, and it is surrounded by a spinlock in the generic version.
- * However, we're not really turning off the L2 cache right now and the
- * PL310 does not support exclusive accesses (used to implement the spinlock).
- * So, the invalidation needs to be done without the spinlock.
- */
-static void ux500_l2x0_inv_all(void)
-{
-       uint32_t l2x0_way_mask = (1<<16) - 1;   /* Bitmask of active ways */
-
-       /* invalidate all ways */
-       writel_relaxed(l2x0_way_mask, l2x0_base + L2X0_INV_WAY);
-       ux500_cache_wait(l2x0_base + L2X0_INV_WAY, l2x0_way_mask);
-       ux500_cache_sync();
-}
-
 static int __init ux500_l2x0_unlock(void)
 {
        int i;
@@ -85,9 +47,13 @@ static int __init ux500_l2x0_init(void)
        /* 64KB way size, 8 way associativity, force WA */
        l2x0_init(l2x0_base, 0x3e060000, 0xc0000fff);
 
-       /* Override invalidate function */
-       outer_cache.disable = ux500_l2x0_disable;
-       outer_cache.inv_all = ux500_l2x0_inv_all;
+       /*
+        * We can't disable l2 as we are in non secure mode, currently
+        * this seems be called only during kexec path. So let's
+        * override outer.disable with nasty assignment until we have
+        * some SMI service available.
+        */
+       outer_cache.disable = NULL;
 
        return 0;
 }
index 572015e..c76f0f4 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/smp.h>
 
 #include <asm/cacheflush.h>
+#include <asm/smp_plat.h>
 
 extern volatile int pen_release;
 
index a19e398..d2058ef 100644 (file)
@@ -19,6 +19,7 @@
 
 #include <asm/cacheflush.h>
 #include <asm/hardware/gic.h>
+#include <asm/smp_plat.h>
 #include <asm/smp_scu.h>
 #include <mach/hardware.h>
 #include <mach/setup.h>
index 0a01cbd..9f9e1c2 100644 (file)
@@ -95,13 +95,7 @@ static struct musb_hdrc_config musb_hdrc_config = {
 };
 
 static struct musb_hdrc_platform_data musb_platform_data = {
-#if defined(CONFIG_USB_MUSB_OTG)
        .mode = MUSB_OTG,
-#elif defined(CONFIG_USB_MUSB_PERIPHERAL)
-       .mode = MUSB_PERIPHERAL,
-#else /* defined(CONFIG_USB_MUSB_HOST) */
-       .mode = MUSB_HOST,
-#endif
        .config = &musb_hdrc_config,
        .board_data = &musb_board_data,
 };
index 2b1e836..b1e87c1 100644 (file)
@@ -217,7 +217,7 @@ static void __init ct_ca9x4_init(void)
 }
 
 #ifdef CONFIG_SMP
-static void ct_ca9x4_init_cpu_map(void)
+static void __init ct_ca9x4_init_cpu_map(void)
 {
        int i, ncores = scu_get_core_count(MMIO_P2V(A9_MPCORE_SCU));
 
@@ -233,7 +233,7 @@ static void ct_ca9x4_init_cpu_map(void)
        set_smp_cross_call(gic_raise_softirq);
 }
 
-static void ct_ca9x4_smp_enable(unsigned int max_cpus)
+static void __init ct_ca9x4_smp_enable(unsigned int max_cpus)
 {
        scu_enable(MMIO_P2V(A9_MPCORE_SCU));
 }
index 813ee08..3034a4d 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/smp.h>
 
 #include <asm/cacheflush.h>
+#include <asm/smp_plat.h>
 #include <asm/system.h>
 
 extern volatile int pen_release;
index 4cefb57..1a3ca24 100644 (file)
@@ -882,6 +882,7 @@ config CACHE_XSC3L2
 
 config ARM_L1_CACHE_SHIFT_6
        bool
+       default y if CPU_V7
        help
          Setting ARM L1 cache line size to 64 Bytes.
 
index 07c4bc8..7a24d39 100644 (file)
@@ -54,9 +54,15 @@ loop1:
        and     r1, r1, #7                      @ mask of the bits for current cache only
        cmp     r1, #2                          @ see what cache we have at this level
        blt     skip                            @ skip if no cache, or just i-cache
+#ifdef CONFIG_PREEMPT
+       save_and_disable_irqs r9                @ make cssr&csidr read atomic
+#endif
        mcr     p15, 2, r10, c0, c0, 0          @ select current cache level in cssr
        isb                                     @ isb to sych the new cssr&csidr
        mrc     p15, 1, r1, c0, c0, 0           @ read the new csidr
+#ifdef CONFIG_PREEMPT
+       restore_irqs_notrace r9
+#endif
        and     r2, r1, #7                      @ extract the length of the cache lines
        add     r2, r2, #4                      @ add 4 (line length offset)
        ldr     r4, =0x3ff
index 6ec1226..5dc7d12 100644 (file)
@@ -310,7 +310,7 @@ static void arm_memory_present(void)
 
 static bool arm_memblock_steal_permitted = true;
 
-phys_addr_t arm_memblock_steal(phys_addr_t size, phys_addr_t align)
+phys_addr_t __init arm_memblock_steal(phys_addr_t size, phys_addr_t align)
 {
        phys_addr_t phys;
 
index 7e9b5bf..0404ccb 100644 (file)
@@ -148,10 +148,6 @@ ENDPROC(cpu_v7_do_resume)
  *     Initialise TLB, Caches, and MMU state ready to switch the MMU
  *     on.  Return in r0 the new CP15 C1 control register setting.
  *
- *     We automatically detect if we have a Harvard cache, and use the
- *     Harvard cache control instructions insead of the unified cache
- *     control instructions.
- *
  *     This should be able to cover all ARMv7 cores.
  *
  *     It is assumed that:
@@ -251,9 +247,7 @@ __v7_setup:
 #endif
 
 3:     mov     r10, #0
-#ifdef HARVARD_CACHE
        mcr     p15, 0, r10, c7, c5, 0          @ I+BTB cache invalidate
-#endif
        dsb
 #ifdef CONFIG_MMU
        mcr     p15, 0, r10, c8, c7, 0          @ invalidate I + D TLBs
@@ -329,16 +323,6 @@ __v7_ca5mp_proc_info:
        __v7_proc __v7_ca5mp_setup
        .size   __v7_ca5mp_proc_info, . - __v7_ca5mp_proc_info
 
-       /*
-        * ARM Ltd. Cortex A7 processor.
-        */
-       .type   __v7_ca7mp_proc_info, #object
-__v7_ca7mp_proc_info:
-       .long   0x410fc070
-       .long   0xff0ffff0
-       __v7_proc __v7_ca7mp_setup, hwcaps = HWCAP_IDIV
-       .size   __v7_ca7mp_proc_info, . - __v7_ca7mp_proc_info
-
        /*
         * ARM Ltd. Cortex A9 processor.
         */
@@ -350,6 +334,16 @@ __v7_ca9mp_proc_info:
        .size   __v7_ca9mp_proc_info, . - __v7_ca9mp_proc_info
 #endif /* CONFIG_ARM_LPAE */
 
+       /*
+        * ARM Ltd. Cortex A7 processor.
+        */
+       .type   __v7_ca7mp_proc_info, #object
+__v7_ca7mp_proc_info:
+       .long   0x410fc070
+       .long   0xff0ffff0
+       __v7_proc __v7_ca7mp_setup, hwcaps = HWCAP_IDIV
+       .size   __v7_ca7mp_proc_info, . - __v7_ca7mp_proc_info
+
        /*
         * ARM Ltd. Cortex A15 processor.
         */
index 6fa8a70..f7d1804 100644 (file)
@@ -96,6 +96,6 @@ extern int mxc_gpio_mode(int gpio_mode);
 extern int mxc_gpio_setup_multiple_pins(const int *pin_list, unsigned count,
                const char *label);
 
-extern int __init imx_iomuxv1_init(void __iomem *base, int numports);
+extern int imx_iomuxv1_init(void __iomem *base, int numports);
 
 #endif /* __MACH_IOMUX_V1_H__ */
index 92f18d3..49c7db4 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/smp.h>
 
 #include <asm/cacheflush.h>
+#include <asm/smp_plat.h>
 #include <asm/hardware/gic.h>
 
 /*
index 197e96f..3dea723 100644 (file)
@@ -8,6 +8,7 @@ config AVR32
        select HAVE_KPROBES
        select HAVE_GENERIC_HARDIRQS
        select GENERIC_IRQ_PROBE
+       select GENERIC_ATOMIC64
        select HARDIRQS_SW_RESEND
        select GENERIC_IRQ_SHOW
        select ARCH_HAVE_NMI_SAFE_CMPXCHG
index 74f23a4..c8d6efb 100644 (file)
@@ -19,6 +19,7 @@ config MICROBLAZE
        select GENERIC_IRQ_SHOW
        select GENERIC_PCI_IOMAP
        select GENERIC_CPU_DEVICES
+       select GENERIC_ATOMIC64
 
 config SWAP
        def_bool n
index 6d2e1d4..615f539 100644 (file)
@@ -2,6 +2,7 @@
 #define _ASM_MICROBLAZE_ATOMIC_H
 
 #include <asm-generic/atomic.h>
+#include <asm-generic/atomic64.h>
 
 /*
  * Atomically test *v and decrement if it is greater than 0.
index d4fc1a9..604cd9d 100644 (file)
@@ -26,7 +26,6 @@
 #include <linux/cache.h>
 #include <linux/of_platform.h>
 #include <linux/dma-mapping.h>
-#include <linux/cpu.h>
 #include <asm/cacheflush.h>
 #include <asm/entry.h>
 #include <asm/cpuinfo.h>
@@ -227,23 +226,5 @@ static int __init setup_bus_notifier(void)
 
        return 0;
 }
-arch_initcall(setup_bus_notifier);
-
-static DEFINE_PER_CPU(struct cpu, cpu_devices);
-
-static int __init topology_init(void)
-{
-       int i, ret;
-
-       for_each_present_cpu(i) {
-               struct cpu *c = &per_cpu(cpu_devices, i);
 
-               ret = register_cpu(c, i);
-               if (ret)
-                       printk(KERN_WARNING "topology_init: register_cpu %d "
-                                               "failed (%d)\n", i, ret);
-       }
-
-       return 0;
-}
-subsys_initcall(topology_init);
+arch_initcall(setup_bus_notifier);
index c4c1312..5ab6e89 100644 (file)
@@ -2356,6 +2356,7 @@ config PCI
        depends on HW_HAS_PCI
        select PCI_DOMAINS
        select GENERIC_PCI_IOMAP
+       select NO_GENERIC_PCI_IOPORT_MAP
        help
          Find out whether you have a PCI motherboard. PCI is the name of a
          bus system, i.e. the way the CPU talks to the other stuff inside
index 2635b1a..fd35daa 100644 (file)
@@ -10,8 +10,8 @@
 #include <linux/module.h>
 #include <asm/io.h>
 
-static void __iomem *ioport_map_pci(struct pci_dev *dev,
-                                     unsigned long port, unsigned int nr)
+void __iomem *__pci_ioport_map(struct pci_dev *dev,
+                              unsigned long port, unsigned int nr)
 {
        struct pci_controller *ctrl = dev->bus->sysdata;
        unsigned long base = ctrl->io_map_base;
index 43268f1..6d42297 100644 (file)
@@ -142,6 +142,11 @@ static inline const char *eeh_pci_name(struct pci_dev *pdev)
        return pdev ? pci_name(pdev) : "<null>";
 } 
 
+static inline const char *eeh_driver_name(struct pci_dev *pdev)
+{
+       return (pdev && pdev->driver) ? pdev->driver->name : "<null>";
+}
+
 #endif /* CONFIG_EEH */
 
 #else /* CONFIG_PCI */
index 78a2051..84cc784 100644 (file)
@@ -83,8 +83,18 @@ struct pt_regs {
 
 #ifndef __ASSEMBLY__
 
-#define instruction_pointer(regs) ((regs)->nip)
-#define user_stack_pointer(regs) ((regs)->gpr[1])
+#define GET_IP(regs)           ((regs)->nip)
+#define GET_USP(regs)          ((regs)->gpr[1])
+#define GET_FP(regs)           (0)
+#define SET_FP(regs, val)
+
+#ifdef CONFIG_SMP
+extern unsigned long profile_pc(struct pt_regs *regs);
+#define profile_pc profile_pc
+#endif
+
+#include <asm-generic/ptrace.h>
+
 #define kernel_stack_pointer(regs) ((regs)->gpr[1])
 static inline int is_syscall_success(struct pt_regs *regs)
 {
@@ -99,12 +109,6 @@ static inline long regs_return_value(struct pt_regs *regs)
                return -regs->gpr[3];
 }
 
-#ifdef CONFIG_SMP
-extern unsigned long profile_pc(struct pt_regs *regs);
-#else
-#define profile_pc(regs) instruction_pointer(regs)
-#endif
-
 #ifdef __powerpc64__
 #define user_mode(regs) ((((regs)->msr) >> MSR_PR_LG) & 0x1)
 #else
index 701d4ac..01e2877 100644 (file)
@@ -118,10 +118,14 @@ static inline notrace void set_soft_enabled(unsigned long enable)
 static inline notrace void decrementer_check_overflow(void)
 {
        u64 now = get_tb_or_rtc();
-       u64 *next_tb = &__get_cpu_var(decrementers_next_tb);
+       u64 *next_tb;
+
+       preempt_disable();
+       next_tb = &__get_cpu_var(decrementers_next_tb);
 
        if (now >= *next_tb)
                set_dec(1);
+       preempt_enable();
 }
 
 notrace void arch_local_irq_restore(unsigned long en)
index 517b1d8..9f843cd 100644 (file)
@@ -716,7 +716,6 @@ static int __rtas_suspend_last_cpu(struct rtas_suspend_me_data *data, int wake_w
        int cpu;
 
        slb_set_size(SLB_MIN_SIZE);
-       stop_topology_update();
        printk(KERN_DEBUG "calling ibm,suspend-me on cpu %i\n", smp_processor_id());
 
        while (rc == H_MULTI_THREADS_ACTIVE && !atomic_read(&data->done) &&
@@ -732,7 +731,6 @@ static int __rtas_suspend_last_cpu(struct rtas_suspend_me_data *data, int wake_w
                rc = atomic_read(&data->error);
 
        atomic_set(&data->error, rc);
-       start_topology_update();
        pSeries_coalesce_init();
 
        if (wake_when_done) {
@@ -846,6 +844,7 @@ int rtas_ibm_suspend_me(struct rtas_args *args)
        atomic_set(&data.error, 0);
        data.token = rtas_token("ibm,suspend-me");
        data.complete = &done;
+       stop_topology_update();
 
        /* Call function on all CPUs.  One of us will make the
         * rtas call
@@ -858,6 +857,8 @@ int rtas_ibm_suspend_me(struct rtas_args *args)
        if (atomic_read(&data.error) != 0)
                printk(KERN_ERR "Error doing global join\n");
 
+       start_topology_update();
+
        return atomic_read(&data.error);
 }
 #else /* CONFIG_PPC_PSERIES */
index a70bc1e..f92b9ef 100644 (file)
@@ -52,32 +52,38 @@ static int pnv_msi_check_device(struct pci_dev* pdev, int nvec, int type)
 
 static unsigned int pnv_get_one_msi(struct pnv_phb *phb)
 {
-       unsigned int id;
+       unsigned long flags;
+       unsigned int id, rc;
+
+       spin_lock_irqsave(&phb->lock, flags);
 
-       spin_lock(&phb->lock);
        id = find_next_zero_bit(phb->msi_map, phb->msi_count, phb->msi_next);
        if (id >= phb->msi_count && phb->msi_next)
                id = find_next_zero_bit(phb->msi_map, phb->msi_count, 0);
        if (id >= phb->msi_count) {
-               spin_unlock(&phb->lock);
-               return 0;
+               rc = 0;
+               goto out;
        }
        __set_bit(id, phb->msi_map);
-       spin_unlock(&phb->lock);
-       return id + phb->msi_base;
+       rc = id + phb->msi_base;
+out:
+       spin_unlock_irqrestore(&phb->lock, flags);
+       return rc;
 }
 
 static void pnv_put_msi(struct pnv_phb *phb, unsigned int hwirq)
 {
+       unsigned long flags;
        unsigned int id;
 
        if (WARN_ON(hwirq < phb->msi_base ||
                    hwirq >= (phb->msi_base + phb->msi_count)))
                return;
        id = hwirq - phb->msi_base;
-       spin_lock(&phb->lock);
+
+       spin_lock_irqsave(&phb->lock, flags);
        __clear_bit(id, phb->msi_map);
-       spin_unlock(&phb->lock);
+       spin_unlock_irqrestore(&phb->lock, flags);
 }
 
 static int pnv_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)
index 5658690..c0b40af 100644 (file)
@@ -551,9 +551,9 @@ int eeh_dn_check_failure(struct device_node *dn, struct pci_dev *dev)
                        printk (KERN_ERR "EEH: %d reads ignored for recovering device at "
                                "location=%s driver=%s pci addr=%s\n",
                                pdn->eeh_check_count, location,
-                               dev->driver->name, eeh_pci_name(dev));
+                               eeh_driver_name(dev), eeh_pci_name(dev));
                        printk (KERN_ERR "EEH: Might be infinite loop in %s driver\n",
-                               dev->driver->name);
+                               eeh_driver_name(dev));
                        dump_stack();
                }
                goto dn_unlock;
index b84a8b2..47226e0 100644 (file)
@@ -24,6 +24,7 @@
 #include <asm/machdep.h>
 #include <asm/mmu.h>
 #include <asm/rtas.h>
+#include <asm/topology.h>
 
 static u64 stream_id;
 static struct device suspend_dev;
@@ -138,8 +139,11 @@ static ssize_t store_hibernate(struct device *dev,
                        ssleep(1);
        } while (rc == -EAGAIN);
 
-       if (!rc)
+       if (!rc) {
+               stop_topology_update();
                rc = pm_suspend(PM_SUSPEND_MEM);
+               start_topology_update();
+       }
 
        stream_id = 0;
 
index 5768743..97fe82e 100644 (file)
@@ -346,7 +346,7 @@ static int wsp_chip_set_affinity(struct irq_data *d,
         * For the moment only implement delivery to all cpus or one cpu.
         * Get current irq_server for the given irq
         */
-       ret = cache_hwirq_map(ics, d->irq, cpumask);
+       ret = cache_hwirq_map(ics, hw_irq, cpumask);
        if (ret == -1) {
                char cpulist[128];
                cpumask_scnprintf(cpulist, sizeof(cpulist), cpumask);
index e0262cd..d24b3ac 100644 (file)
@@ -468,15 +468,15 @@ static void __init wsp_pcie_configure_hw(struct pci_controller *hose)
 #define DUMP_REG(x) \
        pr_debug("%-30s : 0x%016llx\n", #x, in_be64(hose->cfg_data + x))
 
-#ifdef CONFIG_WSP_DD1_WORKAROUND_BAD_PCIE_CLASS
-       /* WSP DD1 has a bogus class code by default in the PCI-E
-        * root complex's built-in P2P bridge */
+       /*
+        * Some WSP variants  has a bogus class code by default in the PCI-E
+        * root complex's built-in P2P bridge
+        */
        val = in_be64(hose->cfg_data + PCIE_REG_SYS_CFG1);
        pr_debug("PCI-E SYS_CFG1 : 0x%llx\n", val);
        out_be64(hose->cfg_data + PCIE_REG_SYS_CFG1,
                 (val & ~PCIE_REG_SYS_CFG1_CLASS_CODE) | (PCI_CLASS_BRIDGE_PCI << 8));
        pr_debug("PCI-E SYS_CFG1 : 0x%llx\n", in_be64(hose->cfg_data + PCIE_REG_SYS_CFG1));
-#endif /* CONFIG_WSP_DD1_WORKAROUND_BAD_PCIE_CLASS */
 
 #ifdef CONFIG_WSP_DD1_WORKAROUND_DD1_TCE_BUGS
        /* XXX Disable TCE caching, it doesn't work on DD1 */
index e9f3533..0ad2f1e 100644 (file)
@@ -88,7 +88,6 @@ KBUILD_CFLAGS += -pipe -fno-strength-reduce -Wno-sign-compare
 KBUILD_AFLAGS  += $(aflags-y)
 
 OBJCOPYFLAGS   := -O binary
-LDFLAGS_vmlinux := -e start
 
 head-y         := arch/s390/kernel/head.o
 head-y         += arch/s390/kernel/$(if $(CONFIG_64BIT),head64.o,head31.o)
index e4c79eb..21109c6 100644 (file)
@@ -9,12 +9,12 @@
 #ifndef CONFIG_64BIT
 OUTPUT_FORMAT("elf32-s390", "elf32-s390", "elf32-s390")
 OUTPUT_ARCH(s390)
-ENTRY(_start)
+ENTRY(startup)
 jiffies = jiffies_64 + 4;
 #else
 OUTPUT_FORMAT("elf64-s390", "elf64-s390", "elf64-s390")
 OUTPUT_ARCH(s390:64-bit)
-ENTRY(_start)
+ENTRY(startup)
 jiffies = jiffies_64;
 #endif
 
index 3c8db65..713fb58 100644 (file)
@@ -859,6 +859,7 @@ config PCI
        depends on SYS_SUPPORTS_PCI
        select PCI_DOMAINS
        select GENERIC_PCI_IOMAP
+       select NO_GENERIC_PCI_IOPORT_MAP
        help
          Find out whether you have a PCI motherboard. PCI is the name of a
          bus system, i.e. the way the CPU talks to the other stuff inside
index 8f18dd0..1e7b0e2 100644 (file)
@@ -356,8 +356,8 @@ int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
 
 #ifndef CONFIG_GENERIC_IOMAP
 
-static void __iomem *ioport_map_pci(struct pci_dev *dev,
-                                   unsigned long port, unsigned int nr)
+void __iomem *__pci_ioport_map(struct pci_dev *dev,
+                              unsigned long port, unsigned int nr)
 {
        struct pci_channel *chan = dev->sysdata;
 
index 9665799..ca5580e 100644 (file)
@@ -33,6 +33,7 @@ config SPARC
 config SPARC32
        def_bool !64BIT
        select GENERIC_ATOMIC64
+       select CLZ_TAB
 
 config SPARC64
        def_bool 64BIT
index 681b368..d74bc09 100644 (file)
@@ -17,23 +17,9 @@ along with GNU CC; see the file COPYING.  If not, write to
 the Free Software Foundation, 59 Temple Place - Suite 330,
 Boston, MA 02111-1307, USA.  */
 
-       .data
-       .align 8
-       .globl  __clz_tab
-__clz_tab:
-       .byte   0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5
-       .byte   6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6
-       .byte   7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7
-       .byte   7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7
-       .byte   8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8
-       .byte   8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8
-       .byte   8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8
-       .byte   8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8
-       .size    __clz_tab,256
-       .global .udiv
-
        .text
        .align 4
+       .global .udiv
        .globl __divdi3
 __divdi3:
        save %sp,-104,%sp
index 0c9fa27..b3b7332 100644 (file)
@@ -145,13 +145,13 @@ extern void __add_wrong_size(void)
 
 #ifdef __HAVE_ARCH_CMPXCHG
 #define cmpxchg(ptr, old, new)                                         \
-       __cmpxchg((ptr), (old), (new), sizeof(*ptr))
+       __cmpxchg(ptr, old, new, sizeof(*(ptr)))
 
 #define sync_cmpxchg(ptr, old, new)                                    \
-       __sync_cmpxchg((ptr), (old), (new), sizeof(*ptr))
+       __sync_cmpxchg(ptr, old, new, sizeof(*(ptr)))
 
 #define cmpxchg_local(ptr, old, new)                                   \
-       __cmpxchg_local((ptr), (old), (new), sizeof(*ptr))
+       __cmpxchg_local(ptr, old, new, sizeof(*(ptr)))
 #endif
 
 /*
index 6919e93..a850b4d 100644 (file)
@@ -29,8 +29,8 @@ extern unsigned int sig_xstate_size;
 extern void fpu_init(void);
 extern void mxcsr_feature_mask_init(void);
 extern int init_fpu(struct task_struct *child);
-extern asmlinkage void math_state_restore(void);
-extern void __math_state_restore(void);
+extern void __math_state_restore(struct task_struct *);
+extern void math_state_restore(void);
 extern int dump_fpu(struct pt_regs *, struct user_i387_struct *);
 
 extern user_regset_active_fn fpregs_active, xfpregs_active;
@@ -212,19 +212,11 @@ static inline void fpu_fxsave(struct fpu *fpu)
 
 #endif /* CONFIG_X86_64 */
 
-/* We need a safe address that is cheap to find and that is already
-   in L1 during context switch. The best choices are unfortunately
-   different for UP and SMP */
-#ifdef CONFIG_SMP
-#define safe_address (__per_cpu_offset[0])
-#else
-#define safe_address (__get_cpu_var(kernel_cpustat).cpustat[CPUTIME_USER])
-#endif
-
 /*
- * These must be called with preempt disabled
+ * These must be called with preempt disabled. Returns
+ * 'true' if the FPU state is still intact.
  */
-static inline void fpu_save_init(struct fpu *fpu)
+static inline int fpu_save_init(struct fpu *fpu)
 {
        if (use_xsave()) {
                fpu_xsave(fpu);
@@ -233,33 +225,33 @@ static inline void fpu_save_init(struct fpu *fpu)
                 * xsave header may indicate the init state of the FP.
                 */
                if (!(fpu->state->xsave.xsave_hdr.xstate_bv & XSTATE_FP))
-                       return;
+                       return 1;
        } else if (use_fxsr()) {
                fpu_fxsave(fpu);
        } else {
                asm volatile("fnsave %[fx]; fwait"
                             : [fx] "=m" (fpu->state->fsave));
-               return;
+               return 0;
        }
 
-       if (unlikely(fpu->state->fxsave.swd & X87_FSW_ES))
+       /*
+        * If exceptions are pending, we need to clear them so
+        * that we don't randomly get exceptions later.
+        *
+        * FIXME! Is this perhaps only true for the old-style
+        * irq13 case? Maybe we could leave the x87 state
+        * intact otherwise?
+        */
+       if (unlikely(fpu->state->fxsave.swd & X87_FSW_ES)) {
                asm volatile("fnclex");
-
-       /* AMD K7/K8 CPUs don't save/restore FDP/FIP/FOP unless an exception
-          is pending.  Clear the x87 state here by setting it to fixed
-          values. safe_address is a random variable that should be in L1 */
-       alternative_input(
-               ASM_NOP8 ASM_NOP2,
-               "emms\n\t"              /* clear stack tags */
-               "fildl %P[addr]",       /* set F?P to defined value */
-               X86_FEATURE_FXSAVE_LEAK,
-               [addr] "m" (safe_address));
+               return 0;
+       }
+       return 1;
 }
 
-static inline void __save_init_fpu(struct task_struct *tsk)
+static inline int __save_init_fpu(struct task_struct *tsk)
 {
-       fpu_save_init(&tsk->thread.fpu);
-       task_thread_info(tsk)->status &= ~TS_USEDFPU;
+       return fpu_save_init(&tsk->thread.fpu);
 }
 
 static inline int fpu_fxrstor_checking(struct fpu *fpu)
@@ -281,39 +273,185 @@ static inline int restore_fpu_checking(struct task_struct *tsk)
 }
 
 /*
- * Signal frame handlers...
+ * Software FPU state helpers. Careful: these need to
+ * be preemption protection *and* they need to be
+ * properly paired with the CR0.TS changes!
  */
-extern int save_i387_xstate(void __user *buf);
-extern int restore_i387_xstate(void __user *buf);
+static inline int __thread_has_fpu(struct task_struct *tsk)
+{
+       return tsk->thread.has_fpu;
+}
 
-static inline void __unlazy_fpu(struct task_struct *tsk)
+/* Must be paired with an 'stts' after! */
+static inline void __thread_clear_has_fpu(struct task_struct *tsk)
 {
-       if (task_thread_info(tsk)->status & TS_USEDFPU) {
-               __save_init_fpu(tsk);
-               stts();
-       } else
-               tsk->fpu_counter = 0;
+       tsk->thread.has_fpu = 0;
+}
+
+/* Must be paired with a 'clts' before! */
+static inline void __thread_set_has_fpu(struct task_struct *tsk)
+{
+       tsk->thread.has_fpu = 1;
 }
 
+/*
+ * Encapsulate the CR0.TS handling together with the
+ * software flag.
+ *
+ * These generally need preemption protection to work,
+ * do try to avoid using these on their own.
+ */
+static inline void __thread_fpu_end(struct task_struct *tsk)
+{
+       __thread_clear_has_fpu(tsk);
+       stts();
+}
+
+static inline void __thread_fpu_begin(struct task_struct *tsk)
+{
+       clts();
+       __thread_set_has_fpu(tsk);
+}
+
+/*
+ * FPU state switching for scheduling.
+ *
+ * This is a two-stage process:
+ *
+ *  - switch_fpu_prepare() saves the old state and
+ *    sets the new state of the CR0.TS bit. This is
+ *    done within the context of the old process.
+ *
+ *  - switch_fpu_finish() restores the new state as
+ *    necessary.
+ */
+typedef struct { int preload; } fpu_switch_t;
+
+/*
+ * FIXME! We could do a totally lazy restore, but we need to
+ * add a per-cpu "this was the task that last touched the FPU
+ * on this CPU" variable, and the task needs to have a "I last
+ * touched the FPU on this CPU" and check them.
+ *
+ * We don't do that yet, so "fpu_lazy_restore()" always returns
+ * false, but some day..
+ */
+#define fpu_lazy_restore(tsk) (0)
+#define fpu_lazy_state_intact(tsk) do { } while (0)
+
+static inline fpu_switch_t switch_fpu_prepare(struct task_struct *old, struct task_struct *new)
+{
+       fpu_switch_t fpu;
+
+       fpu.preload = tsk_used_math(new) && new->fpu_counter > 5;
+       if (__thread_has_fpu(old)) {
+               if (__save_init_fpu(old))
+                       fpu_lazy_state_intact(old);
+               __thread_clear_has_fpu(old);
+               old->fpu_counter++;
+
+               /* Don't change CR0.TS if we just switch! */
+               if (fpu.preload) {
+                       __thread_set_has_fpu(new);
+                       prefetch(new->thread.fpu.state);
+               } else
+                       stts();
+       } else {
+               old->fpu_counter = 0;
+               if (fpu.preload) {
+                       if (fpu_lazy_restore(new))
+                               fpu.preload = 0;
+                       else
+                               prefetch(new->thread.fpu.state);
+                       __thread_fpu_begin(new);
+               }
+       }
+       return fpu;
+}
+
+/*
+ * By the time this gets called, we've already cleared CR0.TS and
+ * given the process the FPU if we are going to preload the FPU
+ * state - all we need to do is to conditionally restore the register
+ * state itself.
+ */
+static inline void switch_fpu_finish(struct task_struct *new, fpu_switch_t fpu)
+{
+       if (fpu.preload)
+               __math_state_restore(new);
+}
+
+/*
+ * Signal frame handlers...
+ */
+extern int save_i387_xstate(void __user *buf);
+extern int restore_i387_xstate(void __user *buf);
+
 static inline void __clear_fpu(struct task_struct *tsk)
 {
-       if (task_thread_info(tsk)->status & TS_USEDFPU) {
+       if (__thread_has_fpu(tsk)) {
                /* Ignore delayed exceptions from user space */
                asm volatile("1: fwait\n"
                             "2:\n"
                             _ASM_EXTABLE(1b, 2b));
-               task_thread_info(tsk)->status &= ~TS_USEDFPU;
-               stts();
+               __thread_fpu_end(tsk);
        }
 }
 
+/*
+ * Were we in an interrupt that interrupted kernel mode?
+ *
+ * We can do a kernel_fpu_begin/end() pair *ONLY* if that
+ * pair does nothing at all: the thread must not have fpu (so
+ * that we don't try to save the FPU state), and TS must
+ * be set (so that the clts/stts pair does nothing that is
+ * visible in the interrupted kernel thread).
+ */
+static inline bool interrupted_kernel_fpu_idle(void)
+{
+       return !__thread_has_fpu(current) &&
+               (read_cr0() & X86_CR0_TS);
+}
+
+/*
+ * Were we in user mode (or vm86 mode) when we were
+ * interrupted?
+ *
+ * Doing kernel_fpu_begin/end() is ok if we are running
+ * in an interrupt context from user mode - we'll just
+ * save the FPU state as required.
+ */
+static inline bool interrupted_user_mode(void)
+{
+       struct pt_regs *regs = get_irq_regs();
+       return regs && user_mode_vm(regs);
+}
+
+/*
+ * Can we use the FPU in kernel mode with the
+ * whole "kernel_fpu_begin/end()" sequence?
+ *
+ * It's always ok in process context (ie "not interrupt")
+ * but it is sometimes ok even from an irq.
+ */
+static inline bool irq_fpu_usable(void)
+{
+       return !in_interrupt() ||
+               interrupted_user_mode() ||
+               interrupted_kernel_fpu_idle();
+}
+
 static inline void kernel_fpu_begin(void)
 {
-       struct thread_info *me = current_thread_info();
+       struct task_struct *me = current;
+
+       WARN_ON_ONCE(!irq_fpu_usable());
        preempt_disable();
-       if (me->status & TS_USEDFPU)
-               __save_init_fpu(me->task);
-       else
+       if (__thread_has_fpu(me)) {
+               __save_init_fpu(me);
+               __thread_clear_has_fpu(me);
+               /* We do 'stts()' in kernel_fpu_end() */
+       } else
                clts();
 }
 
@@ -323,14 +461,6 @@ static inline void kernel_fpu_end(void)
        preempt_enable();
 }
 
-static inline bool irq_fpu_usable(void)
-{
-       struct pt_regs *regs;
-
-       return !in_interrupt() || !(regs = get_irq_regs()) || \
-               user_mode(regs) || (read_cr0() & X86_CR0_TS);
-}
-
 /*
  * Some instructions like VIA's padlock instructions generate a spurious
  * DNA fault but don't modify SSE registers. And these instructions
@@ -362,21 +492,65 @@ static inline void irq_ts_restore(int TS_state)
                stts();
 }
 
+/*
+ * The question "does this thread have fpu access?"
+ * is slightly racy, since preemption could come in
+ * and revoke it immediately after the test.
+ *
+ * However, even in that very unlikely scenario,
+ * we can just assume we have FPU access - typically
+ * to save the FP state - we'll just take a #NM
+ * fault and get the FPU access back.
+ *
+ * The actual user_fpu_begin/end() functions
+ * need to be preemption-safe, though.
+ *
+ * NOTE! user_fpu_end() must be used only after you
+ * have saved the FP state, and user_fpu_begin() must
+ * be used only immediately before restoring it.
+ * These functions do not do any save/restore on
+ * their own.
+ */
+static inline int user_has_fpu(void)
+{
+       return __thread_has_fpu(current);
+}
+
+static inline void user_fpu_end(void)
+{
+       preempt_disable();
+       __thread_fpu_end(current);
+       preempt_enable();
+}
+
+static inline void user_fpu_begin(void)
+{
+       preempt_disable();
+       if (!user_has_fpu())
+               __thread_fpu_begin(current);
+       preempt_enable();
+}
+
 /*
  * These disable preemption on their own and are safe
  */
 static inline void save_init_fpu(struct task_struct *tsk)
 {
+       WARN_ON_ONCE(!__thread_has_fpu(tsk));
        preempt_disable();
        __save_init_fpu(tsk);
-       stts();
+       __thread_fpu_end(tsk);
        preempt_enable();
 }
 
 static inline void unlazy_fpu(struct task_struct *tsk)
 {
        preempt_disable();
-       __unlazy_fpu(tsk);
+       if (__thread_has_fpu(tsk)) {
+               __save_init_fpu(tsk);
+               __thread_fpu_end(tsk);
+       } else
+               tsk->fpu_counter = 0;
        preempt_enable();
 }
 
index ab4092e..7b9cfc4 100644 (file)
@@ -190,6 +190,9 @@ struct x86_emulate_ops {
        int (*intercept)(struct x86_emulate_ctxt *ctxt,
                         struct x86_instruction_info *info,
                         enum x86_intercept_stage stage);
+
+       bool (*get_cpuid)(struct x86_emulate_ctxt *ctxt,
+                        u32 *eax, u32 *ebx, u32 *ecx, u32 *edx);
 };
 
 typedef u32 __attribute__((vector_size(16))) sse128_t;
@@ -298,6 +301,19 @@ struct x86_emulate_ctxt {
 #define X86EMUL_MODE_PROT     (X86EMUL_MODE_PROT16|X86EMUL_MODE_PROT32| \
                               X86EMUL_MODE_PROT64)
 
+/* CPUID vendors */
+#define X86EMUL_CPUID_VENDOR_AuthenticAMD_ebx 0x68747541
+#define X86EMUL_CPUID_VENDOR_AuthenticAMD_ecx 0x444d4163
+#define X86EMUL_CPUID_VENDOR_AuthenticAMD_edx 0x69746e65
+
+#define X86EMUL_CPUID_VENDOR_AMDisbetterI_ebx 0x69444d41
+#define X86EMUL_CPUID_VENDOR_AMDisbetterI_ecx 0x21726574
+#define X86EMUL_CPUID_VENDOR_AMDisbetterI_edx 0x74656273
+
+#define X86EMUL_CPUID_VENDOR_GenuineIntel_ebx 0x756e6547
+#define X86EMUL_CPUID_VENDOR_GenuineIntel_ecx 0x6c65746e
+#define X86EMUL_CPUID_VENDOR_GenuineIntel_edx 0x49656e69
+
 enum x86_intercept_stage {
        X86_ICTP_NONE = 0,   /* Allow zero-init to not match anything */
        X86_ICPT_PRE_EXCEPT,
index aa9088c..f7c89e2 100644 (file)
@@ -454,6 +454,7 @@ struct thread_struct {
        unsigned long           trap_no;
        unsigned long           error_code;
        /* floating point and extended processor state */
+       unsigned long           has_fpu;
        struct fpu              fpu;
 #ifdef CONFIG_X86_32
        /* Virtual 86 mode info */
index bc817cd..cfd8144 100644 (file)
@@ -247,8 +247,6 @@ static inline struct thread_info *current_thread_info(void)
  * ever touches our thread-synchronous status, so we don't
  * have to worry about atomic accesses.
  */
-#define TS_USEDFPU             0x0001  /* FPU was used by this task
-                                          this quantum (SMP) */
 #define TS_COMPAT              0x0002  /* 32bit syscall active (64BIT)*/
 #define TS_POLLING             0x0004  /* idle task polling need_resched,
                                           skip sending interrupt */
index 73da6b6..d6bd49f 100644 (file)
@@ -439,7 +439,6 @@ void intel_pmu_pebs_enable(struct perf_event *event)
        hwc->config &= ~ARCH_PERFMON_EVENTSEL_INT;
 
        cpuc->pebs_enabled |= 1ULL << hwc->idx;
-       WARN_ON_ONCE(cpuc->enabled);
 
        if (x86_pmu.intel_cap.pebs_trap && event->attr.precise_ip > 1)
                intel_pmu_lbr_enable(event);
index 3fab3de..47a7e63 100644 (file)
@@ -72,8 +72,6 @@ void intel_pmu_lbr_enable(struct perf_event *event)
        if (!x86_pmu.lbr_nr)
                return;
 
-       WARN_ON_ONCE(cpuc->enabled);
-
        /*
         * Reset the LBR stack if we changed task context to
         * avoid data leaks.
index 1aae78f..4025fe4 100644 (file)
@@ -252,7 +252,8 @@ int __kprobes __die(const char *str, struct pt_regs *regs, long err)
        unsigned short ss;
        unsigned long sp;
 #endif
-       printk(KERN_EMERG "%s: %04lx [#%d] ", str, err & 0xffff, ++die_counter);
+       printk(KERN_DEFAULT
+              "%s: %04lx [#%d] ", str, err & 0xffff, ++die_counter);
 #ifdef CONFIG_PREEMPT
        printk("PREEMPT ");
 #endif
index 6d728d9..17107bd 100644 (file)
@@ -129,7 +129,7 @@ void dump_trace(struct task_struct *task, struct pt_regs *regs,
        if (!stack) {
                if (regs)
                        stack = (unsigned long *)regs->sp;
-               else if (task && task != current)
+               else if (task != current)
                        stack = (unsigned long *)task->thread.sp;
                else
                        stack = &dummy;
@@ -269,11 +269,11 @@ void show_registers(struct pt_regs *regs)
                unsigned char c;
                u8 *ip;
 
-               printk(KERN_EMERG "Stack:\n");
+               printk(KERN_DEFAULT "Stack:\n");
                show_stack_log_lvl(NULL, regs, (unsigned long *)sp,
-                                  0, KERN_EMERG);
+                                  0, KERN_DEFAULT);
 
-               printk(KERN_EMERG "Code: ");
+               printk(KERN_DEFAULT "Code: ");
 
                ip = (u8 *)regs->ip - code_prologue;
                if (ip < (u8 *)PAGE_OFFSET || probe_kernel_address(ip, c)) {
index 485204f..80bfe1a 100644 (file)
@@ -299,22 +299,11 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
                                 *next = &next_p->thread;
        int cpu = smp_processor_id();
        struct tss_struct *tss = &per_cpu(init_tss, cpu);
-       bool preload_fpu;
+       fpu_switch_t fpu;
 
        /* never put a printk in __switch_to... printk() calls wake_up*() indirectly */
 
-       /*
-        * If the task has used fpu the last 5 timeslices, just do a full
-        * restore of the math state immediately to avoid the trap; the
-        * chances of needing FPU soon are obviously high now
-        */
-       preload_fpu = tsk_used_math(next_p) && next_p->fpu_counter > 5;
-
-       __unlazy_fpu(prev_p);
-
-       /* we're going to use this soon, after a few expensive things */
-       if (preload_fpu)
-               prefetch(next->fpu.state);
+       fpu = switch_fpu_prepare(prev_p, next_p);
 
        /*
         * Reload esp0.
@@ -354,11 +343,6 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
                     task_thread_info(next_p)->flags & _TIF_WORK_CTXSW_NEXT))
                __switch_to_xtra(prev_p, next_p, tss);
 
-       /* If we're going to preload the fpu context, make sure clts
-          is run while we're batching the cpu state updates. */
-       if (preload_fpu)
-               clts();
-
        /*
         * Leave lazy mode, flushing any hypercalls made here.
         * This must be done before restoring TLS segments so
@@ -368,15 +352,14 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
         */
        arch_end_context_switch(next_p);
 
-       if (preload_fpu)
-               __math_state_restore();
-
        /*
         * Restore %gs if needed (which is common)
         */
        if (prev->gs | next->gs)
                lazy_load_gs(next->gs);
 
+       switch_fpu_finish(next_p, fpu);
+
        percpu_write(current_task, next_p);
 
        return prev_p;
index 9b9fe4a..1fd94bc 100644 (file)
@@ -386,18 +386,9 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
        int cpu = smp_processor_id();
        struct tss_struct *tss = &per_cpu(init_tss, cpu);
        unsigned fsindex, gsindex;
-       bool preload_fpu;
+       fpu_switch_t fpu;
 
-       /*
-        * If the task has used fpu the last 5 timeslices, just do a full
-        * restore of the math state immediately to avoid the trap; the
-        * chances of needing FPU soon are obviously high now
-        */
-       preload_fpu = tsk_used_math(next_p) && next_p->fpu_counter > 5;
-
-       /* we're going to use this soon, after a few expensive things */
-       if (preload_fpu)
-               prefetch(next->fpu.state);
+       fpu = switch_fpu_prepare(prev_p, next_p);
 
        /*
         * Reload esp0, LDT and the page table pointer:
@@ -427,13 +418,6 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
 
        load_TLS(next, cpu);
 
-       /* Must be after DS reload */
-       __unlazy_fpu(prev_p);
-
-       /* Make sure cpu is ready for new context */
-       if (preload_fpu)
-               clts();
-
        /*
         * Leave lazy mode, flushing any hypercalls made here.
         * This must be done before restoring TLS segments so
@@ -474,6 +458,8 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
                wrmsrl(MSR_KERNEL_GS_BASE, next->gs);
        prev->gsindex = gsindex;
 
+       switch_fpu_finish(next_p, fpu);
+
        /*
         * Switch the PDA and FPU contexts.
         */
@@ -492,13 +478,6 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
                     task_thread_info(prev_p)->flags & _TIF_WORK_CTXSW_PREV))
                __switch_to_xtra(prev_p, next_p, tss);
 
-       /*
-        * Preload the FPU context, now that we've determined that the
-        * task is likely to be using it. 
-        */
-       if (preload_fpu)
-               __math_state_restore();
-
        return prev_p;
 }
 
index 37a458b..d840e69 100644 (file)
@@ -39,6 +39,14 @@ static int reboot_mode;
 enum reboot_type reboot_type = BOOT_ACPI;
 int reboot_force;
 
+/* This variable is used privately to keep track of whether or not
+ * reboot_type is still set to its default value (i.e., reboot= hasn't
+ * been set on the command line).  This is needed so that we can
+ * suppress DMI scanning for reboot quirks.  Without it, it's
+ * impossible to override a faulty reboot quirk without recompiling.
+ */
+static int reboot_default = 1;
+
 #if defined(CONFIG_X86_32) && defined(CONFIG_SMP)
 static int reboot_cpu = -1;
 #endif
@@ -67,6 +75,12 @@ bool port_cf9_safe = false;
 static int __init reboot_setup(char *str)
 {
        for (;;) {
+               /* Having anything passed on the command line via
+                * reboot= will cause us to disable DMI checking
+                * below.
+                */
+               reboot_default = 0;
+
                switch (*str) {
                case 'w':
                        reboot_mode = 0x1234;
@@ -295,14 +309,6 @@ static struct dmi_system_id __initdata reboot_dmi_table[] = {
                        DMI_MATCH(DMI_BOARD_NAME, "P4S800"),
                },
        },
-       {       /* Handle problems with rebooting on VersaLogic Menlow boards */
-               .callback = set_bios_reboot,
-               .ident = "VersaLogic Menlow based board",
-               .matches = {
-                       DMI_MATCH(DMI_BOARD_VENDOR, "VersaLogic Corporation"),
-                       DMI_MATCH(DMI_BOARD_NAME, "VersaLogic Menlow board"),
-               },
-       },
        { /* Handle reboot issue on Acer Aspire one */
                .callback = set_kbd_reboot,
                .ident = "Acer Aspire One A110",
@@ -316,7 +322,12 @@ static struct dmi_system_id __initdata reboot_dmi_table[] = {
 
 static int __init reboot_init(void)
 {
-       dmi_check_system(reboot_dmi_table);
+       /* Only do the DMI check if reboot_type hasn't been overridden
+        * on the command line
+        */
+       if (reboot_default) {
+               dmi_check_system(reboot_dmi_table);
+       }
        return 0;
 }
 core_initcall(reboot_init);
@@ -465,7 +476,12 @@ static struct dmi_system_id __initdata pci_reboot_dmi_table[] = {
 
 static int __init pci_reboot_init(void)
 {
-       dmi_check_system(pci_reboot_dmi_table);
+       /* Only do the DMI check if reboot_type hasn't been overridden
+        * on the command line
+        */
+       if (reboot_default) {
+               dmi_check_system(pci_reboot_dmi_table);
+       }
        return 0;
 }
 core_initcall(pci_reboot_init);
index 482ec3a..77da5b4 100644 (file)
@@ -571,25 +571,34 @@ asmlinkage void __attribute__((weak)) smp_threshold_interrupt(void)
 }
 
 /*
- * __math_state_restore assumes that cr0.TS is already clear and the
- * fpu state is all ready for use.  Used during context switch.
+ * This gets called with the process already owning the
+ * FPU state, and with CR0.TS cleared. It just needs to
+ * restore the FPU register state.
  */
-void __math_state_restore(void)
+void __math_state_restore(struct task_struct *tsk)
 {
-       struct thread_info *thread = current_thread_info();
-       struct task_struct *tsk = thread->task;
+       /* We need a safe address that is cheap to find and that is already
+          in L1. We've just brought in "tsk->thread.has_fpu", so use that */
+#define safe_address (tsk->thread.has_fpu)
+
+       /* AMD K7/K8 CPUs don't save/restore FDP/FIP/FOP unless an exception
+          is pending.  Clear the x87 state here by setting it to fixed
+          values. safe_address is a random variable that should be in L1 */
+       alternative_input(
+               ASM_NOP8 ASM_NOP2,
+               "emms\n\t"              /* clear stack tags */
+               "fildl %P[addr]",       /* set F?P to defined value */
+               X86_FEATURE_FXSAVE_LEAK,
+               [addr] "m" (safe_address));
 
        /*
         * Paranoid restore. send a SIGSEGV if we fail to restore the state.
         */
        if (unlikely(restore_fpu_checking(tsk))) {
-               stts();
+               __thread_fpu_end(tsk);
                force_sig(SIGSEGV, tsk);
                return;
        }
-
-       thread->status |= TS_USEDFPU;   /* So we fnsave on switch_to() */
-       tsk->fpu_counter++;
 }
 
 /*
@@ -599,13 +608,12 @@ void __math_state_restore(void)
  * Careful.. There are problems with IBM-designed IRQ13 behaviour.
  * Don't touch unless you *really* know how it works.
  *
- * Must be called with kernel preemption disabled (in this case,
- * local interrupts are disabled at the call-site in entry.S).
+ * Must be called with kernel preemption disabled (eg with local
+ * local interrupts as in the case of do_device_not_available).
  */
-asmlinkage void math_state_restore(void)
+void math_state_restore(void)
 {
-       struct thread_info *thread = current_thread_info();
-       struct task_struct *tsk = thread->task;
+       struct task_struct *tsk = current;
 
        if (!tsk_used_math(tsk)) {
                local_irq_enable();
@@ -622,9 +630,10 @@ asmlinkage void math_state_restore(void)
                local_irq_disable();
        }
 
-       clts();                         /* Allow maths ops (or we recurse) */
+       __thread_fpu_begin(tsk);
+       __math_state_restore(tsk);
 
-       __math_state_restore();
+       tsk->fpu_counter++;
 }
 EXPORT_SYMBOL_GPL(math_state_restore);
 
index a391134..7110911 100644 (file)
@@ -47,7 +47,7 @@ void __sanitize_i387_state(struct task_struct *tsk)
        if (!fx)
                return;
 
-       BUG_ON(task_thread_info(tsk)->status & TS_USEDFPU);
+       BUG_ON(__thread_has_fpu(tsk));
 
        xstate_bv = tsk->thread.fpu.state->xsave.xsave_hdr.xstate_bv;
 
@@ -168,7 +168,7 @@ int save_i387_xstate(void __user *buf)
        if (!used_math())
                return 0;
 
-       if (task_thread_info(tsk)->status & TS_USEDFPU) {
+       if (user_has_fpu()) {
                if (use_xsave())
                        err = xsave_user(buf);
                else
@@ -176,8 +176,7 @@ int save_i387_xstate(void __user *buf)
 
                if (err)
                        return err;
-               task_thread_info(tsk)->status &= ~TS_USEDFPU;
-               stts();
+               user_fpu_end();
        } else {
                sanitize_i387_state(tsk);
                if (__copy_to_user(buf, &tsk->thread.fpu.state->fxsave,
@@ -292,10 +291,7 @@ int restore_i387_xstate(void __user *buf)
                        return err;
        }
 
-       if (!(task_thread_info(current)->status & TS_USEDFPU)) {
-               clts();
-               task_thread_info(current)->status |= TS_USEDFPU;
-       }
+       user_fpu_begin();
        if (use_xsave())
                err = restore_user_xstate(buf);
        else
index 05a562b..0982507 100644 (file)
@@ -1891,6 +1891,51 @@ setup_syscalls_segments(struct x86_emulate_ctxt *ctxt,
        ss->p = 1;
 }
 
+static bool em_syscall_is_enabled(struct x86_emulate_ctxt *ctxt)
+{
+       struct x86_emulate_ops *ops = ctxt->ops;
+       u32 eax, ebx, ecx, edx;
+
+       /*
+        * syscall should always be enabled in longmode - so only become
+        * vendor specific (cpuid) if other modes are active...
+        */
+       if (ctxt->mode == X86EMUL_MODE_PROT64)
+               return true;
+
+       eax = 0x00000000;
+       ecx = 0x00000000;
+       if (ops->get_cpuid(ctxt, &eax, &ebx, &ecx, &edx)) {
+               /*
+                * Intel ("GenuineIntel")
+                * remark: Intel CPUs only support "syscall" in 64bit
+                * longmode. Also an 64bit guest with a
+                * 32bit compat-app running will #UD !! While this
+                * behaviour can be fixed (by emulating) into AMD
+                * response - CPUs of AMD can't behave like Intel.
+                */
+               if (ebx == X86EMUL_CPUID_VENDOR_GenuineIntel_ebx &&
+                   ecx == X86EMUL_CPUID_VENDOR_GenuineIntel_ecx &&
+                   edx == X86EMUL_CPUID_VENDOR_GenuineIntel_edx)
+                       return false;
+
+               /* AMD ("AuthenticAMD") */
+               if (ebx == X86EMUL_CPUID_VENDOR_AuthenticAMD_ebx &&
+                   ecx == X86EMUL_CPUID_VENDOR_AuthenticAMD_ecx &&
+                   edx == X86EMUL_CPUID_VENDOR_AuthenticAMD_edx)
+                       return true;
+
+               /* AMD ("AMDisbetter!") */
+               if (ebx == X86EMUL_CPUID_VENDOR_AMDisbetterI_ebx &&
+                   ecx == X86EMUL_CPUID_VENDOR_AMDisbetterI_ecx &&
+                   edx == X86EMUL_CPUID_VENDOR_AMDisbetterI_edx)
+                       return true;
+       }
+
+       /* default: (not Intel, not AMD), apply Intel's stricter rules... */
+       return false;
+}
+
 static int em_syscall(struct x86_emulate_ctxt *ctxt)
 {
        struct x86_emulate_ops *ops = ctxt->ops;
@@ -1904,9 +1949,15 @@ static int em_syscall(struct x86_emulate_ctxt *ctxt)
            ctxt->mode == X86EMUL_MODE_VM86)
                return emulate_ud(ctxt);
 
+       if (!(em_syscall_is_enabled(ctxt)))
+               return emulate_ud(ctxt);
+
        ops->get_msr(ctxt, MSR_EFER, &efer);
        setup_syscalls_segments(ctxt, &cs, &ss);
 
+       if (!(efer & EFER_SCE))
+               return emulate_ud(ctxt);
+
        ops->get_msr(ctxt, MSR_STAR, &msr_data);
        msr_data >>= 32;
        cs_sel = (u16)(msr_data & 0xfffc);
index d29216c..3b4c8d8 100644 (file)
@@ -1457,7 +1457,7 @@ static void __vmx_load_host_state(struct vcpu_vmx *vmx)
 #ifdef CONFIG_X86_64
        wrmsrl(MSR_KERNEL_GS_BASE, vmx->msr_host_kernel_gs_base);
 #endif
-       if (current_thread_info()->status & TS_USEDFPU)
+       if (__thread_has_fpu(current))
                clts();
        load_gdt(&__get_cpu_var(host_gdt));
 }
index 14d6cad..9cbfc06 100644 (file)
@@ -1495,6 +1495,8 @@ static void record_steal_time(struct kvm_vcpu *vcpu)
 
 int kvm_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data)
 {
+       bool pr = false;
+
        switch (msr) {
        case MSR_EFER:
                return set_efer(vcpu, data);
@@ -1635,6 +1637,18 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data)
                pr_unimpl(vcpu, "unimplemented perfctr wrmsr: "
                        "0x%x data 0x%llx\n", msr, data);
                break;
+       case MSR_P6_PERFCTR0:
+       case MSR_P6_PERFCTR1:
+               pr = true;
+       case MSR_P6_EVNTSEL0:
+       case MSR_P6_EVNTSEL1:
+               if (kvm_pmu_msr(vcpu, msr))
+                       return kvm_pmu_set_msr(vcpu, msr, data);
+
+               if (pr || data != 0)
+                       pr_unimpl(vcpu, "disabled perfctr wrmsr: "
+                               "0x%x data 0x%llx\n", msr, data);
+               break;
        case MSR_K7_CLK_CTL:
                /*
                 * Ignore all writes to this no longer documented MSR.
@@ -1835,6 +1849,14 @@ int kvm_get_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata)
        case MSR_FAM10H_MMIO_CONF_BASE:
                data = 0;
                break;
+       case MSR_P6_PERFCTR0:
+       case MSR_P6_PERFCTR1:
+       case MSR_P6_EVNTSEL0:
+       case MSR_P6_EVNTSEL1:
+               if (kvm_pmu_msr(vcpu, msr))
+                       return kvm_pmu_get_msr(vcpu, msr, pdata);
+               data = 0;
+               break;
        case MSR_IA32_UCODE_REV:
                data = 0x100000000ULL;
                break;
@@ -4180,6 +4202,28 @@ static int emulator_intercept(struct x86_emulate_ctxt *ctxt,
        return kvm_x86_ops->check_intercept(emul_to_vcpu(ctxt), info, stage);
 }
 
+static bool emulator_get_cpuid(struct x86_emulate_ctxt *ctxt,
+                              u32 *eax, u32 *ebx, u32 *ecx, u32 *edx)
+{
+       struct kvm_cpuid_entry2 *cpuid = NULL;
+
+       if (eax && ecx)
+               cpuid = kvm_find_cpuid_entry(emul_to_vcpu(ctxt),
+                                           *eax, *ecx);
+
+       if (cpuid) {
+               *eax = cpuid->eax;
+               *ecx = cpuid->ecx;
+               if (ebx)
+                       *ebx = cpuid->ebx;
+               if (edx)
+                       *edx = cpuid->edx;
+               return true;
+       }
+
+       return false;
+}
+
 static struct x86_emulate_ops emulate_ops = {
        .read_std            = kvm_read_guest_virt_system,
        .write_std           = kvm_write_guest_virt_system,
@@ -4211,6 +4255,7 @@ static struct x86_emulate_ops emulate_ops = {
        .get_fpu             = emulator_get_fpu,
        .put_fpu             = emulator_put_fpu,
        .intercept           = emulator_intercept,
+       .get_cpuid           = emulator_get_cpuid,
 };
 
 static void cache_all_regs(struct kvm_vcpu *vcpu)
index 9d74824..f0b4caf 100644 (file)
@@ -673,7 +673,7 @@ no_context(struct pt_regs *regs, unsigned long error_code,
 
        stackend = end_of_stack(tsk);
        if (tsk != &init_task && *stackend != STACK_END_MAGIC)
-               printk(KERN_ALERT "Thread overran stack, or stack corrupted\n");
+               printk(KERN_EMERG "Thread overran stack, or stack corrupted\n");
 
        tsk->thread.cr2         = address;
        tsk->thread.trap_no     = 14;
@@ -684,7 +684,7 @@ no_context(struct pt_regs *regs, unsigned long error_code,
                sig = 0;
 
        /* Executive summary in case the body of the oops scrolled away */
-       printk(KERN_EMERG "CR2: %016lx\n", address);
+       printk(KERN_DEFAULT "CR2: %016lx\n", address);
 
        oops_end(flags, regs, sig);
 }
index 492ade8..d99346e 100644 (file)
@@ -374,7 +374,7 @@ int __init pci_xen_init(void)
 
 int __init pci_xen_hvm_init(void)
 {
-       if (!xen_feature(XENFEAT_hvm_pirqs))
+       if (!xen_have_vector_callback || !xen_feature(XENFEAT_hvm_pirqs))
                return 0;
 
 #ifdef CONFIG_ACPI
index 041d4fe..501d4e0 100644 (file)
@@ -409,6 +409,13 @@ static void __cpuinit xen_play_dead(void) /* used only with HOTPLUG_CPU */
        play_dead_common();
        HYPERVISOR_vcpu_op(VCPUOP_down, smp_processor_id(), NULL);
        cpu_bringup();
+       /*
+        * Balance out the preempt calls - as we are running in cpu_idle
+        * loop which has been called at bootup from cpu_bringup_and_idle.
+        * The cpucpu_bringup_and_idle called cpu_bringup which made a
+        * preempt_disable() So this preempt_enable will balance it out.
+        */
+       preempt_enable();
 }
 
 #else /* !CONFIG_HOTPLUG_CPU */
index cc9b1e1..d69cc6c 100644 (file)
@@ -116,9 +116,26 @@ static inline void spin_time_accum_blocked(u64 start)
 }
 #endif  /* CONFIG_XEN_DEBUG_FS */
 
+/*
+ * Size struct xen_spinlock so it's the same as arch_spinlock_t.
+ */
+#if NR_CPUS < 256
+typedef u8 xen_spinners_t;
+# define inc_spinners(xl) \
+       asm(LOCK_PREFIX " incb %0" : "+m" ((xl)->spinners) : : "memory");
+# define dec_spinners(xl) \
+       asm(LOCK_PREFIX " decb %0" : "+m" ((xl)->spinners) : : "memory");
+#else
+typedef u16 xen_spinners_t;
+# define inc_spinners(xl) \
+       asm(LOCK_PREFIX " incw %0" : "+m" ((xl)->spinners) : : "memory");
+# define dec_spinners(xl) \
+       asm(LOCK_PREFIX " decw %0" : "+m" ((xl)->spinners) : : "memory");
+#endif
+
 struct xen_spinlock {
        unsigned char lock;             /* 0 -> free; 1 -> locked */
-       unsigned short spinners;        /* count of waiting cpus */
+       xen_spinners_t spinners;        /* count of waiting cpus */
 };
 
 static int xen_spin_is_locked(struct arch_spinlock *lock)
@@ -164,8 +181,7 @@ static inline struct xen_spinlock *spinning_lock(struct xen_spinlock *xl)
 
        wmb();                  /* set lock of interest before count */
 
-       asm(LOCK_PREFIX " incw %0"
-           : "+m" (xl->spinners) : : "memory");
+       inc_spinners(xl);
 
        return prev;
 }
@@ -176,8 +192,7 @@ static inline struct xen_spinlock *spinning_lock(struct xen_spinlock *xl)
  */
 static inline void unspinning_lock(struct xen_spinlock *xl, struct xen_spinlock *prev)
 {
-       asm(LOCK_PREFIX " decw %0"
-           : "+m" (xl->spinners) : : "memory");
+       dec_spinners(xl);
        wmb();                  /* decrement count before restoring lock */
        __this_cpu_write(lock_spinners, prev);
 }
@@ -373,6 +388,8 @@ void xen_uninit_lock_cpu(int cpu)
 
 void __init xen_init_spinlocks(void)
 {
+       BUILD_BUG_ON(sizeof(struct xen_spinlock) > sizeof(arch_spinlock_t));
+
        pv_lock_ops.spin_is_locked = xen_spin_is_locked;
        pv_lock_ops.spin_is_contended = xen_spin_is_contended;
        pv_lock_ops.spin_lock = xen_spin_lock;
index 5fb8c27..405a8c4 100644 (file)
@@ -118,7 +118,4 @@ extern void *memmove(void *__dest, __const__ void *__src, size_t __n);
 /* Don't build bcopy at all ...  */
 #define __HAVE_ARCH_BCOPY
 
-#define __HAVE_ARCH_MEMSCAN
-#define memscan memchr
-
 #endif /* _XTENSA_STRING_H */
index fa8f263..75642a3 100644 (file)
@@ -1659,7 +1659,7 @@ static void blkiocg_attach(struct cgroup_subsys *ss, struct cgroup *cgrp,
                ioc = get_task_io_context(task, GFP_ATOMIC, NUMA_NO_NODE);
                if (ioc) {
                        ioc_cgroup_changed(ioc);
-                       put_io_context(ioc, NULL);
+                       put_io_context(ioc);
                }
        }
 }
index e6c05a9..3a78b00 100644 (file)
@@ -642,7 +642,7 @@ static inline void blk_free_request(struct request_queue *q, struct request *rq)
        if (rq->cmd_flags & REQ_ELVPRIV) {
                elv_put_request(q, rq);
                if (rq->elv.icq)
-                       put_io_context(rq->elv.icq->ioc, q);
+                       put_io_context(rq->elv.icq->ioc);
        }
 
        mempool_free(rq, q->rq.rq_pool);
@@ -872,13 +872,15 @@ retry:
        spin_unlock_irq(q->queue_lock);
 
        /* create icq if missing */
-       if (unlikely(et->icq_cache && !icq))
+       if ((rw_flags & REQ_ELVPRIV) && unlikely(et->icq_cache && !icq)) {
                icq = ioc_create_icq(q, gfp_mask);
+               if (!icq)
+                       goto fail_icq;
+       }
 
-       /* rqs are guaranteed to have icq on elv_set_request() if requested */
-       if (likely(!et->icq_cache || icq))
-               rq = blk_alloc_request(q, icq, rw_flags, gfp_mask);
+       rq = blk_alloc_request(q, icq, rw_flags, gfp_mask);
 
+fail_icq:
        if (unlikely(!rq)) {
                /*
                 * Allocation failed presumably due to memory. Undo anything
@@ -1210,7 +1212,6 @@ static bool bio_attempt_back_merge(struct request_queue *q, struct request *req,
        req->ioprio = ioprio_best(req->ioprio, bio_prio(bio));
 
        drive_stat_acct(req, 0);
-       elv_bio_merged(q, req, bio);
        return true;
 }
 
@@ -1241,7 +1242,6 @@ static bool bio_attempt_front_merge(struct request_queue *q,
        req->ioprio = ioprio_best(req->ioprio, bio_prio(bio));
 
        drive_stat_acct(req, 0);
-       elv_bio_merged(q, req, bio);
        return true;
 }
 
@@ -1255,13 +1255,12 @@ static bool bio_attempt_front_merge(struct request_queue *q,
  * on %current's plugged list.  Returns %true if merge was successful,
  * otherwise %false.
  *
- * This function is called without @q->queue_lock; however, elevator is
- * accessed iff there already are requests on the plugged list which in
- * turn guarantees validity of the elevator.
- *
- * Note that, on successful merge, elevator operation
- * elevator_bio_merged_fn() will be called without queue lock.  Elevator
- * must be ready for this.
+ * Plugging coalesces IOs from the same issuer for the same purpose without
+ * going through @q->queue_lock.  As such it's more of an issuing mechanism
+ * than scheduling, and the request, while may have elvpriv data, is not
+ * added on the elevator at this point.  In addition, we don't have
+ * reliable access to the elevator outside queue lock.  Only check basic
+ * merging parameters without querying the elevator.
  */
 static bool attempt_plug_merge(struct request_queue *q, struct bio *bio,
                               unsigned int *request_count)
@@ -1280,10 +1279,10 @@ static bool attempt_plug_merge(struct request_queue *q, struct bio *bio,
 
                (*request_count)++;
 
-               if (rq->q != q)
+               if (rq->q != q || !blk_rq_merge_ok(rq, bio))
                        continue;
 
-               el_ret = elv_try_merge(rq, bio);
+               el_ret = blk_try_merge(rq, bio);
                if (el_ret == ELEVATOR_BACK_MERGE) {
                        ret = bio_attempt_back_merge(q, rq, bio);
                        if (ret)
@@ -1345,12 +1344,14 @@ void blk_queue_bio(struct request_queue *q, struct bio *bio)
        el_ret = elv_merge(q, &req, bio);
        if (el_ret == ELEVATOR_BACK_MERGE) {
                if (bio_attempt_back_merge(q, req, bio)) {
+                       elv_bio_merged(q, req, bio);
                        if (!attempt_back_merge(q, req))
                                elv_merged_request(q, req, el_ret);
                        goto out_unlock;
                }
        } else if (el_ret == ELEVATOR_FRONT_MERGE) {
                if (bio_attempt_front_merge(q, req, bio)) {
+                       elv_bio_merged(q, req, bio);
                        if (!attempt_front_merge(q, req))
                                elv_merged_request(q, req, el_ret);
                        goto out_unlock;
index 27a06e0..8b782a6 100644 (file)
@@ -29,21 +29,6 @@ void get_io_context(struct io_context *ioc)
 }
 EXPORT_SYMBOL(get_io_context);
 
-/*
- * Releasing ioc may nest into another put_io_context() leading to nested
- * fast path release.  As the ioc's can't be the same, this is okay but
- * makes lockdep whine.  Keep track of nesting and use it as subclass.
- */
-#ifdef CONFIG_LOCKDEP
-#define ioc_release_depth(q)           ((q) ? (q)->ioc_release_depth : 0)
-#define ioc_release_depth_inc(q)       (q)->ioc_release_depth++
-#define ioc_release_depth_dec(q)       (q)->ioc_release_depth--
-#else
-#define ioc_release_depth(q)           0
-#define ioc_release_depth_inc(q)       do { } while (0)
-#define ioc_release_depth_dec(q)       do { } while (0)
-#endif
-
 static void icq_free_icq_rcu(struct rcu_head *head)
 {
        struct io_cq *icq = container_of(head, struct io_cq, __rcu_head);
@@ -75,11 +60,8 @@ static void ioc_exit_icq(struct io_cq *icq)
        if (rcu_dereference_raw(ioc->icq_hint) == icq)
                rcu_assign_pointer(ioc->icq_hint, NULL);
 
-       if (et->ops.elevator_exit_icq_fn) {
-               ioc_release_depth_inc(q);
+       if (et->ops.elevator_exit_icq_fn)
                et->ops.elevator_exit_icq_fn(icq);
-               ioc_release_depth_dec(q);
-       }
 
        /*
         * @icq->q might have gone away by the time RCU callback runs
@@ -98,8 +80,15 @@ static void ioc_release_fn(struct work_struct *work)
        struct io_context *ioc = container_of(work, struct io_context,
                                              release_work);
        struct request_queue *last_q = NULL;
+       unsigned long flags;
 
-       spin_lock_irq(&ioc->lock);
+       /*
+        * Exiting icq may call into put_io_context() through elevator
+        * which will trigger lockdep warning.  The ioc's are guaranteed to
+        * be different, use a different locking subclass here.  Use
+        * irqsave variant as there's no spin_lock_irq_nested().
+        */
+       spin_lock_irqsave_nested(&ioc->lock, flags, 1);
 
        while (!hlist_empty(&ioc->icq_list)) {
                struct io_cq *icq = hlist_entry(ioc->icq_list.first,
@@ -121,15 +110,15 @@ static void ioc_release_fn(struct work_struct *work)
                         */
                        if (last_q) {
                                spin_unlock(last_q->queue_lock);
-                               spin_unlock_irq(&ioc->lock);
+                               spin_unlock_irqrestore(&ioc->lock, flags);
                                blk_put_queue(last_q);
                        } else {
-                               spin_unlock_irq(&ioc->lock);
+                               spin_unlock_irqrestore(&ioc->lock, flags);
                        }
 
                        last_q = this_q;
-                       spin_lock_irq(this_q->queue_lock);
-                       spin_lock(&ioc->lock);
+                       spin_lock_irqsave(this_q->queue_lock, flags);
+                       spin_lock_nested(&ioc->lock, 1);
                        continue;
                }
                ioc_exit_icq(icq);
@@ -137,10 +126,10 @@ static void ioc_release_fn(struct work_struct *work)
 
        if (last_q) {
                spin_unlock(last_q->queue_lock);
-               spin_unlock_irq(&ioc->lock);
+               spin_unlock_irqrestore(&ioc->lock, flags);
                blk_put_queue(last_q);
        } else {
-               spin_unlock_irq(&ioc->lock);
+               spin_unlock_irqrestore(&ioc->lock, flags);
        }
 
        kmem_cache_free(iocontext_cachep, ioc);
@@ -149,79 +138,29 @@ static void ioc_release_fn(struct work_struct *work)
 /**
  * put_io_context - put a reference of io_context
  * @ioc: io_context to put
- * @locked_q: request_queue the caller is holding queue_lock of (hint)
  *
  * Decrement reference count of @ioc and release it if the count reaches
- * zero.  If the caller is holding queue_lock of a queue, it can indicate
- * that with @locked_q.  This is an optimization hint and the caller is
- * allowed to pass in %NULL even when it's holding a queue_lock.
+ * zero.
  */
-void put_io_context(struct io_context *ioc, struct request_queue *locked_q)
+void put_io_context(struct io_context *ioc)
 {
-       struct request_queue *last_q = locked_q;
        unsigned long flags;
 
        if (ioc == NULL)
                return;
 
        BUG_ON(atomic_long_read(&ioc->refcount) <= 0);
-       if (locked_q)
-               lockdep_assert_held(locked_q->queue_lock);
-
-       if (!atomic_long_dec_and_test(&ioc->refcount))
-               return;
 
        /*
-        * Destroy @ioc.  This is a bit messy because icq's are chained
-        * from both ioc and queue, and ioc->lock nests inside queue_lock.
-        * The inner ioc->lock should be held to walk our icq_list and then
-        * for each icq the outer matching queue_lock should be grabbed.
-        * ie. We need to do reverse-order double lock dancing.
-        *
-        * Another twist is that we are often called with one of the
-        * matching queue_locks held as indicated by @locked_q, which
-        * prevents performing double-lock dance for other queues.
-        *
-        * So, we do it in two stages.  The fast path uses the queue_lock
-        * the caller is holding and, if other queues need to be accessed,
-        * uses trylock to avoid introducing locking dependency.  This can
-        * handle most cases, especially if @ioc was performing IO on only
-        * single device.
-        *
-        * If trylock doesn't cut it, we defer to @ioc->release_work which
-        * can do all the double-locking dancing.
+        * Releasing ioc requires reverse order double locking and we may
+        * already be holding a queue_lock.  Do it asynchronously from wq.
         */
-       spin_lock_irqsave_nested(&ioc->lock, flags,
-                                ioc_release_depth(locked_q));
-
-       while (!hlist_empty(&ioc->icq_list)) {
-               struct io_cq *icq = hlist_entry(ioc->icq_list.first,
-                                               struct io_cq, ioc_node);
-               struct request_queue *this_q = icq->q;
-
-               if (this_q != last_q) {
-                       if (last_q && last_q != locked_q)
-                               spin_unlock(last_q->queue_lock);
-                       last_q = NULL;
-
-                       if (!spin_trylock(this_q->queue_lock))
-                               break;
-                       last_q = this_q;
-                       continue;
-               }
-               ioc_exit_icq(icq);
+       if (atomic_long_dec_and_test(&ioc->refcount)) {
+               spin_lock_irqsave(&ioc->lock, flags);
+               if (!hlist_empty(&ioc->icq_list))
+                       schedule_work(&ioc->release_work);
+               spin_unlock_irqrestore(&ioc->lock, flags);
        }
-
-       if (last_q && last_q != locked_q)
-               spin_unlock(last_q->queue_lock);
-
-       spin_unlock_irqrestore(&ioc->lock, flags);
-
-       /* if no icq is left, we're done; otherwise, kick release_work */
-       if (hlist_empty(&ioc->icq_list))
-               kmem_cache_free(iocontext_cachep, ioc);
-       else
-               schedule_work(&ioc->release_work);
 }
 EXPORT_SYMBOL(put_io_context);
 
@@ -236,7 +175,7 @@ void exit_io_context(struct task_struct *task)
        task_unlock(task);
 
        atomic_dec(&ioc->nr_tasks);
-       put_io_context(ioc, NULL);
+       put_io_context(ioc);
 }
 
 /**
index cfcc37c..160035f 100644 (file)
@@ -471,3 +471,40 @@ int blk_attempt_req_merge(struct request_queue *q, struct request *rq,
 {
        return attempt_merge(q, rq, next);
 }
+
+bool blk_rq_merge_ok(struct request *rq, struct bio *bio)
+{
+       if (!rq_mergeable(rq))
+               return false;
+
+       /* don't merge file system requests and discard requests */
+       if ((bio->bi_rw & REQ_DISCARD) != (rq->bio->bi_rw & REQ_DISCARD))
+               return false;
+
+       /* don't merge discard requests and secure discard requests */
+       if ((bio->bi_rw & REQ_SECURE) != (rq->bio->bi_rw & REQ_SECURE))
+               return false;
+
+       /* different data direction or already started, don't merge */
+       if (bio_data_dir(bio) != rq_data_dir(rq))
+               return false;
+
+       /* must be same device and not a special request */
+       if (rq->rq_disk != bio->bi_bdev->bd_disk || rq->special)
+               return false;
+
+       /* only merge integrity protected bio into ditto rq */
+       if (bio_integrity(bio) != blk_integrity_rq(rq))
+               return false;
+
+       return true;
+}
+
+int blk_try_merge(struct request *rq, struct bio *bio)
+{
+       if (blk_rq_pos(rq) + blk_rq_sectors(rq) == bio->bi_sector)
+               return ELEVATOR_BACK_MERGE;
+       else if (blk_rq_pos(rq) - bio_sectors(bio) == bio->bi_sector)
+               return ELEVATOR_FRONT_MERGE;
+       return ELEVATOR_NO_MERGE;
+}
index 7efd772..9c12f80 100644 (file)
@@ -137,6 +137,8 @@ int blk_attempt_req_merge(struct request_queue *q, struct request *rq,
                                struct request *next);
 void blk_recalc_rq_segments(struct request *rq);
 void blk_rq_set_mixed_merge(struct request *rq);
+bool blk_rq_merge_ok(struct request *rq, struct bio *bio);
+int blk_try_merge(struct request *rq, struct bio *bio);
 
 void blk_queue_congestion_threshold(struct request_queue *q);
 
index 4cf703f..ff64ae3 100644 (file)
@@ -983,7 +983,8 @@ void bsg_unregister_queue(struct request_queue *q)
 
        mutex_lock(&bsg_mutex);
        idr_remove(&bsg_minor_idr, bcd->minor);
-       sysfs_remove_link(&q->kobj, "bsg");
+       if (q->kobj.sd)
+               sysfs_remove_link(&q->kobj, "bsg");
        device_unregister(bcd->class_dev);
        bcd->class_dev = NULL;
        kref_put(&bcd->ref, bsg_kref_release_function);
index ee55019..d0ba505 100644 (file)
@@ -1699,18 +1699,11 @@ static int cfq_allow_merge(struct request_queue *q, struct request *rq,
 
        /*
         * Lookup the cfqq that this bio will be queued with and allow
-        * merge only if rq is queued there.  This function can be called
-        * from plug merge without queue_lock.  In such cases, ioc of @rq
-        * and %current are guaranteed to be equal.  Avoid lookup which
-        * requires queue_lock by using @rq's cic.
+        * merge only if rq is queued there.
         */
-       if (current->io_context == RQ_CIC(rq)->icq.ioc) {
-               cic = RQ_CIC(rq);
-       } else {
-               cic = cfq_cic_lookup(cfqd, current->io_context);
-               if (!cic)
-                       return false;
-       }
+       cic = cfq_cic_lookup(cfqd, current->io_context);
+       if (!cic)
+               return false;
 
        cfqq = cic_to_cfqq(cic, cfq_bio_sync(bio));
        return cfqq == RQ_CFQQ(rq);
@@ -1794,7 +1787,7 @@ __cfq_slice_expired(struct cfq_data *cfqd, struct cfq_queue *cfqq,
                cfqd->active_queue = NULL;
 
        if (cfqd->active_cic) {
-               put_io_context(cfqd->active_cic->icq.ioc, cfqd->queue);
+               put_io_context(cfqd->active_cic->icq.ioc);
                cfqd->active_cic = NULL;
        }
 }
@@ -3117,17 +3110,18 @@ cfq_should_preempt(struct cfq_data *cfqd, struct cfq_queue *new_cfqq,
  */
 static void cfq_preempt_queue(struct cfq_data *cfqd, struct cfq_queue *cfqq)
 {
+       enum wl_type_t old_type = cfqq_type(cfqd->active_queue);
+
        cfq_log_cfqq(cfqd, cfqq, "preempt");
+       cfq_slice_expired(cfqd, 1);
 
        /*
         * workload type is changed, don't save slice, otherwise preempt
         * doesn't happen
         */
-       if (cfqq_type(cfqd->active_queue) != cfqq_type(cfqq))
+       if (old_type != cfqq_type(cfqq))
                cfqq->cfqg->saved_workload_slice = 0;
 
-       cfq_slice_expired(cfqd, 1);
-
        /*
         * Put the new queue at the front of the of the current list,
         * so we know that it will be selected next.
index 91e18f8..f016855 100644 (file)
@@ -70,39 +70,9 @@ static int elv_iosched_allow_merge(struct request *rq, struct bio *bio)
 /*
  * can we safely merge with this request?
  */
-int elv_rq_merge_ok(struct request *rq, struct bio *bio)
+bool elv_rq_merge_ok(struct request *rq, struct bio *bio)
 {
-       if (!rq_mergeable(rq))
-               return 0;
-
-       /*
-        * Don't merge file system requests and discard requests
-        */
-       if ((bio->bi_rw & REQ_DISCARD) != (rq->bio->bi_rw & REQ_DISCARD))
-               return 0;
-
-       /*
-        * Don't merge discard requests and secure discard requests
-        */
-       if ((bio->bi_rw & REQ_SECURE) != (rq->bio->bi_rw & REQ_SECURE))
-               return 0;
-
-       /*
-        * different data direction or already started, don't merge
-        */
-       if (bio_data_dir(bio) != rq_data_dir(rq))
-               return 0;
-
-       /*
-        * must be same device and not a special request
-        */
-       if (rq->rq_disk != bio->bi_bdev->bd_disk || rq->special)
-               return 0;
-
-       /*
-        * only merge integrity protected bio into ditto rq
-        */
-       if (bio_integrity(bio) != blk_integrity_rq(rq))
+       if (!blk_rq_merge_ok(rq, bio))
                return 0;
 
        if (!elv_iosched_allow_merge(rq, bio))
@@ -112,23 +82,6 @@ int elv_rq_merge_ok(struct request *rq, struct bio *bio)
 }
 EXPORT_SYMBOL(elv_rq_merge_ok);
 
-int elv_try_merge(struct request *__rq, struct bio *bio)
-{
-       int ret = ELEVATOR_NO_MERGE;
-
-       /*
-        * we can merge and sequence is ok, check if it's possible
-        */
-       if (elv_rq_merge_ok(__rq, bio)) {
-               if (blk_rq_pos(__rq) + blk_rq_sectors(__rq) == bio->bi_sector)
-                       ret = ELEVATOR_BACK_MERGE;
-               else if (blk_rq_pos(__rq) - bio_sectors(bio) == bio->bi_sector)
-                       ret = ELEVATOR_FRONT_MERGE;
-       }
-
-       return ret;
-}
-
 static struct elevator_type *elevator_find(const char *name)
 {
        struct elevator_type *e;
@@ -478,8 +431,8 @@ int elv_merge(struct request_queue *q, struct request **req, struct bio *bio)
        /*
         * First try one-hit cache.
         */
-       if (q->last_merge) {
-               ret = elv_try_merge(q->last_merge, bio);
+       if (q->last_merge && elv_rq_merge_ok(q->last_merge, bio)) {
+               ret = blk_try_merge(q->last_merge, bio);
                if (ret != ELEVATOR_NO_MERGE) {
                        *req = q->last_merge;
                        return ret;
index 88f160b..107f6f7 100644 (file)
@@ -31,11 +31,6 @@ static inline u64 Maj(u64 x, u64 y, u64 z)
         return (x & y) | (z & (x | y));
 }
 
-static inline u64 RORu64(u64 x, u64 y)
-{
-        return (x >> y) | (x << (64 - y));
-}
-
 static const u64 sha512_K[80] = {
         0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL, 0xb5c0fbcfec4d3b2fULL,
         0xe9b5dba58189dbbcULL, 0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL,
@@ -66,10 +61,10 @@ static const u64 sha512_K[80] = {
         0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL,
 };
 
-#define e0(x)       (RORu64(x,28) ^ RORu64(x,34) ^ RORu64(x,39))
-#define e1(x)       (RORu64(x,14) ^ RORu64(x,18) ^ RORu64(x,41))
-#define s0(x)       (RORu64(x, 1) ^ RORu64(x, 8) ^ (x >> 7))
-#define s1(x)       (RORu64(x,19) ^ RORu64(x,61) ^ (x >> 6))
+#define e0(x)       (ror64(x,28) ^ ror64(x,34) ^ ror64(x,39))
+#define e1(x)       (ror64(x,14) ^ ror64(x,18) ^ ror64(x,41))
+#define s0(x)       (ror64(x, 1) ^ ror64(x, 8) ^ (x >> 7))
+#define s1(x)       (ror64(x,19) ^ ror64(x,61) ^ (x >> 6))
 
 static inline void LOAD_OP(int I, u64 *W, const u8 *input)
 {
@@ -78,7 +73,7 @@ static inline void LOAD_OP(int I, u64 *W, const u8 *input)
 
 static inline void BLEND_OP(int I, u64 *W)
 {
-       W[I % 16] += s1(W[(I-2) % 16]) + W[(I-7) % 16] + s0(W[(I-15) % 16]);
+       W[I & 15] += s1(W[(I-2) & 15]) + W[(I-7) & 15] + s0(W[(I-15) & 15]);
 }
 
 static void
@@ -89,46 +84,42 @@ sha512_transform(u64 *state, const u8 *input)
        int i;
        u64 W[16];
 
-       /* load the input */
-        for (i = 0; i < 16; i++)
-                LOAD_OP(i, W, input);
-
        /* load the state into our registers */
        a=state[0];   b=state[1];   c=state[2];   d=state[3];
        e=state[4];   f=state[5];   g=state[6];   h=state[7];
 
-#define SHA512_0_15(i, a, b, c, d, e, f, g, h)                 \
-       t1 = h + e1(e) + Ch(e, f, g) + sha512_K[i] + W[i];      \
-       t2 = e0(a) + Maj(a, b, c);                              \
-       d += t1;                                                \
-       h = t1 + t2
-
-#define SHA512_16_79(i, a, b, c, d, e, f, g, h)                        \
-       BLEND_OP(i, W);                                         \
-       t1 = h + e1(e) + Ch(e, f, g) + sha512_K[i] + W[(i)%16]; \
-       t2 = e0(a) + Maj(a, b, c);                              \
-       d += t1;                                                \
-       h = t1 + t2
-
-       for (i = 0; i < 16; i += 8) {
-               SHA512_0_15(i, a, b, c, d, e, f, g, h);
-               SHA512_0_15(i + 1, h, a, b, c, d, e, f, g);
-               SHA512_0_15(i + 2, g, h, a, b, c, d, e, f);
-               SHA512_0_15(i + 3, f, g, h, a, b, c, d, e);
-               SHA512_0_15(i + 4, e, f, g, h, a, b, c, d);
-               SHA512_0_15(i + 5, d, e, f, g, h, a, b, c);
-               SHA512_0_15(i + 6, c, d, e, f, g, h, a, b);
-               SHA512_0_15(i + 7, b, c, d, e, f, g, h, a);
-       }
-       for (i = 16; i < 80; i += 8) {
-               SHA512_16_79(i, a, b, c, d, e, f, g, h);
-               SHA512_16_79(i + 1, h, a, b, c, d, e, f, g);
-               SHA512_16_79(i + 2, g, h, a, b, c, d, e, f);
-               SHA512_16_79(i + 3, f, g, h, a, b, c, d, e);
-               SHA512_16_79(i + 4, e, f, g, h, a, b, c, d);
-               SHA512_16_79(i + 5, d, e, f, g, h, a, b, c);
-               SHA512_16_79(i + 6, c, d, e, f, g, h, a, b);
-               SHA512_16_79(i + 7, b, c, d, e, f, g, h, a);
+       /* now iterate */
+       for (i=0; i<80; i+=8) {
+               if (!(i & 8)) {
+                       int j;
+
+                       if (i < 16) {
+                               /* load the input */
+                               for (j = 0; j < 16; j++)
+                                       LOAD_OP(i + j, W, input);
+                       } else {
+                               for (j = 0; j < 16; j++) {
+                                       BLEND_OP(i + j, W);
+                               }
+                       }
+               }
+
+               t1 = h + e1(e) + Ch(e,f,g) + sha512_K[i  ] + W[(i & 15)];
+               t2 = e0(a) + Maj(a,b,c);    d+=t1;    h=t1+t2;
+               t1 = g + e1(d) + Ch(d,e,f) + sha512_K[i+1] + W[(i & 15) + 1];
+               t2 = e0(h) + Maj(h,a,b);    c+=t1;    g=t1+t2;
+               t1 = f + e1(c) + Ch(c,d,e) + sha512_K[i+2] + W[(i & 15) + 2];
+               t2 = e0(g) + Maj(g,h,a);    b+=t1;    f=t1+t2;
+               t1 = e + e1(b) + Ch(b,c,d) + sha512_K[i+3] + W[(i & 15) + 3];
+               t2 = e0(f) + Maj(f,g,h);    a+=t1;    e=t1+t2;
+               t1 = d + e1(a) + Ch(a,b,c) + sha512_K[i+4] + W[(i & 15) + 4];
+               t2 = e0(e) + Maj(e,f,g);    h+=t1;    d=t1+t2;
+               t1 = c + e1(h) + Ch(h,a,b) + sha512_K[i+5] + W[(i & 15) + 5];
+               t2 = e0(d) + Maj(d,e,f);    g+=t1;    c=t1+t2;
+               t1 = b + e1(g) + Ch(g,h,a) + sha512_K[i+6] + W[(i & 15) + 6];
+               t2 = e0(c) + Maj(c,d,e);    f+=t1;    b=t1+t2;
+               t1 = a + e1(f) + Ch(f,g,h) + sha512_K[i+7] + W[(i & 15) + 7];
+               t2 = e0(b) + Maj(b,c,d);    e+=t1;    a=t1+t2;
        }
 
        state[0] += a; state[1] += b; state[2] += c; state[3] += d;
index 2b805d7..8ae05ce 100644 (file)
@@ -579,13 +579,6 @@ static int __cpuinit acpi_processor_add(struct acpi_device *device)
                goto err_free_cpumask;
        }
 
-       /*
-        * Do not start hotplugged CPUs now, but when they
-        * are onlined the first time
-        */
-       if (pr->flags.need_hotplug_init)
-               return 0;
-
        /*
         * Do not start hotplugged CPUs now, but when they
         * are onlined the first time
index 2c8272d..610f999 100644 (file)
@@ -1,6 +1,6 @@
 # Makefile for the Linux device tree
 
-obj-y                  := core.o sys.o bus.o dd.o syscore.o \
+obj-y                  := core.o bus.o dd.o syscore.o \
                           driver.o class.o platform.o \
                           cpu.o firmware.o init.o map.o devres.o \
                           attribute_container.o transport_class.o \
index 4a67cc0..74dda4f 100644 (file)
@@ -632,6 +632,11 @@ static void klist_children_put(struct klist_node *n)
  * may be used for reference counting of @dev after calling this
  * function.
  *
+ * All fields in @dev must be initialized by the caller to 0, except
+ * for those explicitly set to some other value.  The simplest
+ * approach is to use kzalloc() to allocate the structure containing
+ * @dev.
+ *
  * NOTE: Use put_device() to give up your reference instead of freeing
  * @dev directly once you have called this function.
  */
@@ -930,6 +935,13 @@ int device_private_init(struct device *dev)
  * to the global and sibling lists for the device, then
  * adds it to the other relevant subsystems of the driver model.
  *
+ * Do not call this routine or device_register() more than once for
+ * any device structure.  The driver model core is not designed to work
+ * with devices that get unregistered and then spring back to life.
+ * (Among other things, it's very hard to guarantee that all references
+ * to the previous incarnation of @dev have been dropped.)  Allocate
+ * and register a fresh new struct device instead.
+ *
  * NOTE: _Never_ directly free @dev after calling this function, even
  * if it returned an error! Always use put_device() to give up your
  * reference instead.
@@ -1022,7 +1034,7 @@ int device_add(struct device *dev)
        device_pm_add(dev);
 
        /* Notify clients of device addition.  This call must come
-        * after dpm_sysf_add() and before kobject_uevent().
+        * after dpm_sysfs_add() and before kobject_uevent().
         */
        if (dev->bus)
                blocking_notifier_call_chain(&dev->bus->p->bus_notifier,
@@ -1090,6 +1102,9 @@ name_error:
  * have a clearly defined need to use and refcount the device
  * before it is added to the hierarchy.
  *
+ * For more information, see the kerneldoc for device_initialize()
+ * and device_add().
+ *
  * NOTE: _Never_ directly free @dev after calling this function, even
  * if it returned an error! Always use put_device() to give up the
  * reference initialized in this function instead.
index db87e78..4dabf50 100644 (file)
@@ -208,6 +208,25 @@ static ssize_t print_cpus_offline(struct device *dev,
 }
 static DEVICE_ATTR(offline, 0444, print_cpus_offline, NULL);
 
+static void cpu_device_release(struct device *dev)
+{
+       /*
+        * This is an empty function to prevent the driver core from spitting a
+        * warning at us.  Yes, I know this is directly opposite of what the
+        * documentation for the driver core and kobjects say, and the author
+        * of this code has already been publically ridiculed for doing
+        * something as foolish as this.  However, at this point in time, it is
+        * the only way to handle the issue of statically allocated cpu
+        * devices.  The different architectures will have their cpu device
+        * code reworked to properly handle this in the near future, so this
+        * function will then be changed to correctly free up the memory held
+        * by the cpu device.
+        *
+        * Never copy this way of doing things, or you too will be made fun of
+        * on the linux-kerenl list, you have been warned.
+        */
+}
+
 /*
  * register_cpu - Setup a sysfs device for a CPU.
  * @cpu - cpu->hotpluggable field set to 1 will generate a control file in
@@ -221,8 +240,10 @@ int __cpuinit register_cpu(struct cpu *cpu, int num)
        int error;
 
        cpu->node_id = cpu_to_node(num);
+       memset(&cpu->dev, 0x00, sizeof(struct device));
        cpu->dev.id = num;
        cpu->dev.bus = &cpu_subsys;
+       cpu->dev.release = cpu_device_release;
        error = device_register(&cpu->dev);
        if (!error && cpu->hotpluggable)
                register_cpu_control(cpu);
index ed5de58..9e60dbe 100644 (file)
@@ -572,19 +572,36 @@ static int init_memory_block(struct memory_block **memory,
 }
 
 static int add_memory_section(int nid, struct mem_section *section,
+                       struct memory_block **mem_p,
                        unsigned long state, enum mem_add_context context)
 {
-       struct memory_block *mem;
+       struct memory_block *mem = NULL;
+       int scn_nr = __section_nr(section);
        int ret = 0;
 
        mutex_lock(&mem_sysfs_mutex);
 
-       mem = find_memory_block(section);
+       if (context == BOOT) {
+               /* same memory block ? */
+               if (mem_p && *mem_p)
+                       if (scn_nr >= (*mem_p)->start_section_nr &&
+                           scn_nr <= (*mem_p)->end_section_nr) {
+                               mem = *mem_p;
+                               kobject_get(&mem->dev.kobj);
+                       }
+       } else
+               mem = find_memory_block(section);
+
        if (mem) {
                mem->section_count++;
                kobject_put(&mem->dev.kobj);
-       } else
+       } else {
                ret = init_memory_block(&mem, section, state);
+               /* store memory_block pointer for next loop */
+               if (!ret && context == BOOT)
+                       if (mem_p)
+                               *mem_p = mem;
+       }
 
        if (!ret) {
                if (context == HOTPLUG &&
@@ -627,7 +644,7 @@ int remove_memory_block(unsigned long node_id, struct mem_section *section,
  */
 int register_new_memory(int nid, struct mem_section *section)
 {
-       return add_memory_section(nid, section, MEM_OFFLINE, HOTPLUG);
+       return add_memory_section(nid, section, NULL, MEM_OFFLINE, HOTPLUG);
 }
 
 int unregister_memory_section(struct mem_section *section)
@@ -647,6 +664,7 @@ int __init memory_dev_init(void)
        int ret;
        int err;
        unsigned long block_sz;
+       struct memory_block *mem = NULL;
 
        ret = subsys_system_register(&memory_subsys, NULL);
        if (ret)
@@ -662,7 +680,10 @@ int __init memory_dev_init(void)
        for (i = 0; i < NR_MEM_SECTIONS; i++) {
                if (!present_section_nr(i))
                        continue;
-               err = add_memory_section(0, __nr_to_section(i), MEM_ONLINE,
+               /* don't need to reuse memory_block if only one per block */
+               err = add_memory_section(0, __nr_to_section(i),
+                                (sections_per_block == 1) ? NULL : &mem,
+                                        MEM_ONLINE,
                                         BOOT);
                if (!ret)
                        ret = err;
index 44f427a..90aa2a1 100644 (file)
@@ -456,7 +456,15 @@ static int link_mem_sections(int nid)
                if (!present_section_nr(section_nr))
                        continue;
                mem_sect = __nr_to_section(section_nr);
+
+               /* same memblock ? */
+               if (mem_blk)
+                       if ((section_nr >= mem_blk->start_section_nr) &&
+                           (section_nr <= mem_blk->end_section_nr))
+                               continue;
+
                mem_blk = find_memory_block_hinted(mem_sect, mem_blk);
+
                ret = register_mem_sect_under_node(mem_blk, nid);
                if (!err)
                        err = ret;
diff --git a/drivers/base/sys.c b/drivers/base/sys.c
deleted file mode 100644 (file)
index 409f5ce..0000000
+++ /dev/null
@@ -1,383 +0,0 @@
-/*
- * sys.c - pseudo-bus for system 'devices' (cpus, PICs, timers, etc)
- *
- * Copyright (c) 2002-3 Patrick Mochel
- *               2002-3 Open Source Development Lab
- *
- * This file is released under the GPLv2
- *
- * This exports a 'system' bus type.
- * By default, a 'sys' bus gets added to the root of the system. There will
- * always be core system devices. Devices can use sysdev_register() to
- * add themselves as children of the system bus.
- */
-
-#include <linux/sysdev.h>
-#include <linux/err.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/string.h>
-#include <linux/pm.h>
-#include <linux/device.h>
-#include <linux/mutex.h>
-#include <linux/interrupt.h>
-
-#include "base.h"
-
-#define to_sysdev(k) container_of(k, struct sys_device, kobj)
-#define to_sysdev_attr(a) container_of(a, struct sysdev_attribute, attr)
-
-
-static ssize_t
-sysdev_show(struct kobject *kobj, struct attribute *attr, char *buffer)
-{
-       struct sys_device *sysdev = to_sysdev(kobj);
-       struct sysdev_attribute *sysdev_attr = to_sysdev_attr(attr);
-
-       if (sysdev_attr->show)
-               return sysdev_attr->show(sysdev, sysdev_attr, buffer);
-       return -EIO;
-}
-
-
-static ssize_t
-sysdev_store(struct kobject *kobj, struct attribute *attr,
-            const char *buffer, size_t count)
-{
-       struct sys_device *sysdev = to_sysdev(kobj);
-       struct sysdev_attribute *sysdev_attr = to_sysdev_attr(attr);
-
-       if (sysdev_attr->store)
-               return sysdev_attr->store(sysdev, sysdev_attr, buffer, count);
-       return -EIO;
-}
-
-static const struct sysfs_ops sysfs_ops = {
-       .show   = sysdev_show,
-       .store  = sysdev_store,
-};
-
-static struct kobj_type ktype_sysdev = {
-       .sysfs_ops      = &sysfs_ops,
-};
-
-
-int sysdev_create_file(struct sys_device *s, struct sysdev_attribute *a)
-{
-       return sysfs_create_file(&s->kobj, &a->attr);
-}
-
-
-void sysdev_remove_file(struct sys_device *s, struct sysdev_attribute *a)
-{
-       sysfs_remove_file(&s->kobj, &a->attr);
-}
-
-EXPORT_SYMBOL_GPL(sysdev_create_file);
-EXPORT_SYMBOL_GPL(sysdev_remove_file);
-
-#define to_sysdev_class(k) container_of(k, struct sysdev_class, kset.kobj)
-#define to_sysdev_class_attr(a) container_of(a, \
-       struct sysdev_class_attribute, attr)
-
-static ssize_t sysdev_class_show(struct kobject *kobj, struct attribute *attr,
-                                char *buffer)
-{
-       struct sysdev_class *class = to_sysdev_class(kobj);
-       struct sysdev_class_attribute *class_attr = to_sysdev_class_attr(attr);
-
-       if (class_attr->show)
-               return class_attr->show(class, class_attr, buffer);
-       return -EIO;
-}
-
-static ssize_t sysdev_class_store(struct kobject *kobj, struct attribute *attr,
-                                 const char *buffer, size_t count)
-{
-       struct sysdev_class *class = to_sysdev_class(kobj);
-       struct sysdev_class_attribute *class_attr = to_sysdev_class_attr(attr);
-
-       if (class_attr->store)
-               return class_attr->store(class, class_attr, buffer, count);
-       return -EIO;
-}
-
-static const struct sysfs_ops sysfs_class_ops = {
-       .show   = sysdev_class_show,
-       .store  = sysdev_class_store,
-};
-
-static struct kobj_type ktype_sysdev_class = {
-       .sysfs_ops      = &sysfs_class_ops,
-};
-
-int sysdev_class_create_file(struct sysdev_class *c,
-                            struct sysdev_class_attribute *a)
-{
-       return sysfs_create_file(&c->kset.kobj, &a->attr);
-}
-EXPORT_SYMBOL_GPL(sysdev_class_create_file);
-
-void sysdev_class_remove_file(struct sysdev_class *c,
-                             struct sysdev_class_attribute *a)
-{
-       sysfs_remove_file(&c->kset.kobj, &a->attr);
-}
-EXPORT_SYMBOL_GPL(sysdev_class_remove_file);
-
-extern struct kset *system_kset;
-
-int sysdev_class_register(struct sysdev_class *cls)
-{
-       int retval;
-
-       pr_debug("Registering sysdev class '%s'\n", cls->name);
-
-       INIT_LIST_HEAD(&cls->drivers);
-       memset(&cls->kset.kobj, 0x00, sizeof(struct kobject));
-       cls->kset.kobj.parent = &system_kset->kobj;
-       cls->kset.kobj.ktype = &ktype_sysdev_class;
-       cls->kset.kobj.kset = system_kset;
-
-       retval = kobject_set_name(&cls->kset.kobj, "%s", cls->name);
-       if (retval)
-               return retval;
-
-       retval = kset_register(&cls->kset);
-       if (!retval && cls->attrs)
-               retval = sysfs_create_files(&cls->kset.kobj,
-                                           (const struct attribute **)cls->attrs);
-       return retval;
-}
-
-void sysdev_class_unregister(struct sysdev_class *cls)
-{
-       pr_debug("Unregistering sysdev class '%s'\n",
-                kobject_name(&cls->kset.kobj));
-       if (cls->attrs)
-               sysfs_remove_files(&cls->kset.kobj,
-                                  (const struct attribute **)cls->attrs);
-       kset_unregister(&cls->kset);
-}
-
-EXPORT_SYMBOL_GPL(sysdev_class_register);
-EXPORT_SYMBOL_GPL(sysdev_class_unregister);
-
-static DEFINE_MUTEX(sysdev_drivers_lock);
-
-/*
- * @dev != NULL means that we're unwinding because some drv->add()
- * failed for some reason. You need to grab sysdev_drivers_lock before
- * calling this.
- */
-static void __sysdev_driver_remove(struct sysdev_class *cls,
-                                  struct sysdev_driver *drv,
-                                  struct sys_device *from_dev)
-{
-       struct sys_device *dev = from_dev;
-
-       list_del_init(&drv->entry);
-       if (!cls)
-               return;
-
-       if (!drv->remove)
-               goto kset_put;
-
-       if (dev)
-               list_for_each_entry_continue_reverse(dev, &cls->kset.list,
-                                                    kobj.entry)
-                       drv->remove(dev);
-       else
-               list_for_each_entry(dev, &cls->kset.list, kobj.entry)
-                       drv->remove(dev);
-
-kset_put:
-       kset_put(&cls->kset);
-}
-
-/**
- *     sysdev_driver_register - Register auxiliary driver
- *     @cls:   Device class driver belongs to.
- *     @drv:   Driver.
- *
- *     @drv is inserted into @cls->drivers to be
- *     called on each operation on devices of that class. The refcount
- *     of @cls is incremented.
- */
-int sysdev_driver_register(struct sysdev_class *cls, struct sysdev_driver *drv)
-{
-       struct sys_device *dev = NULL;
-       int err = 0;
-
-       if (!cls) {
-               WARN(1, KERN_WARNING "sysdev: invalid class passed to %s!\n",
-                       __func__);
-               return -EINVAL;
-       }
-
-       /* Check whether this driver has already been added to a class. */
-       if (drv->entry.next && !list_empty(&drv->entry))
-               WARN(1, KERN_WARNING "sysdev: class %s: driver (%p) has already"
-                       " been registered to a class, something is wrong, but "
-                       "will forge on!\n", cls->name, drv);
-
-       mutex_lock(&sysdev_drivers_lock);
-       if (cls && kset_get(&cls->kset)) {
-               list_add_tail(&drv->entry, &cls->drivers);
-
-               /* If devices of this class already exist, tell the driver */
-               if (drv->add) {
-                       list_for_each_entry(dev, &cls->kset.list, kobj.entry) {
-                               err = drv->add(dev);
-                               if (err)
-                                       goto unwind;
-                       }
-               }
-       } else {
-               err = -EINVAL;
-               WARN(1, KERN_ERR "%s: invalid device class\n", __func__);
-       }
-
-       goto unlock;
-
-unwind:
-       __sysdev_driver_remove(cls, drv, dev);
-
-unlock:
-       mutex_unlock(&sysdev_drivers_lock);
-       return err;
-}
-
-/**
- *     sysdev_driver_unregister - Remove an auxiliary driver.
- *     @cls:   Class driver belongs to.
- *     @drv:   Driver.
- */
-void sysdev_driver_unregister(struct sysdev_class *cls,
-                             struct sysdev_driver *drv)
-{
-       mutex_lock(&sysdev_drivers_lock);
-       __sysdev_driver_remove(cls, drv, NULL);
-       mutex_unlock(&sysdev_drivers_lock);
-}
-EXPORT_SYMBOL_GPL(sysdev_driver_register);
-EXPORT_SYMBOL_GPL(sysdev_driver_unregister);
-
-/**
- *     sysdev_register - add a system device to the tree
- *     @sysdev:        device in question
- *
- */
-int sysdev_register(struct sys_device *sysdev)
-{
-       int error;
-       struct sysdev_class *cls = sysdev->cls;
-
-       if (!cls)
-               return -EINVAL;
-
-       pr_debug("Registering sys device of class '%s'\n",
-                kobject_name(&cls->kset.kobj));
-
-       /* initialize the kobject to 0, in case it had previously been used */
-       memset(&sysdev->kobj, 0x00, sizeof(struct kobject));
-
-       /* Make sure the kset is set */
-       sysdev->kobj.kset = &cls->kset;
-
-       /* Register the object */
-       error = kobject_init_and_add(&sysdev->kobj, &ktype_sysdev, NULL,
-                                    "%s%d", kobject_name(&cls->kset.kobj),
-                                    sysdev->id);
-
-       if (!error) {
-               struct sysdev_driver *drv;
-
-               pr_debug("Registering sys device '%s'\n",
-                        kobject_name(&sysdev->kobj));
-
-               mutex_lock(&sysdev_drivers_lock);
-               /* Generic notification is implicit, because it's that
-                * code that should have called us.
-                */
-
-               /* Notify class auxiliary drivers */
-               list_for_each_entry(drv, &cls->drivers, entry) {
-                       if (drv->add)
-                               drv->add(sysdev);
-               }
-               mutex_unlock(&sysdev_drivers_lock);
-               kobject_uevent(&sysdev->kobj, KOBJ_ADD);
-       }
-
-       return error;
-}
-
-void sysdev_unregister(struct sys_device *sysdev)
-{
-       struct sysdev_driver *drv;
-
-       mutex_lock(&sysdev_drivers_lock);
-       list_for_each_entry(drv, &sysdev->cls->drivers, entry) {
-               if (drv->remove)
-                       drv->remove(sysdev);
-       }
-       mutex_unlock(&sysdev_drivers_lock);
-
-       kobject_put(&sysdev->kobj);
-}
-
-EXPORT_SYMBOL_GPL(sysdev_register);
-EXPORT_SYMBOL_GPL(sysdev_unregister);
-
-#define to_ext_attr(x) container_of(x, struct sysdev_ext_attribute, attr)
-
-ssize_t sysdev_store_ulong(struct sys_device *sysdev,
-                          struct sysdev_attribute *attr,
-                          const char *buf, size_t size)
-{
-       struct sysdev_ext_attribute *ea = to_ext_attr(attr);
-       char *end;
-       unsigned long new = simple_strtoul(buf, &end, 0);
-       if (end == buf)
-               return -EINVAL;
-       *(unsigned long *)(ea->var) = new;
-       /* Always return full write size even if we didn't consume all */
-       return size;
-}
-EXPORT_SYMBOL_GPL(sysdev_store_ulong);
-
-ssize_t sysdev_show_ulong(struct sys_device *sysdev,
-                         struct sysdev_attribute *attr,
-                         char *buf)
-{
-       struct sysdev_ext_attribute *ea = to_ext_attr(attr);
-       return snprintf(buf, PAGE_SIZE, "%lx\n", *(unsigned long *)(ea->var));
-}
-EXPORT_SYMBOL_GPL(sysdev_show_ulong);
-
-ssize_t sysdev_store_int(struct sys_device *sysdev,
-                          struct sysdev_attribute *attr,
-                          const char *buf, size_t size)
-{
-       struct sysdev_ext_attribute *ea = to_ext_attr(attr);
-       char *end;
-       long new = simple_strtol(buf, &end, 0);
-       if (end == buf || new > INT_MAX || new < INT_MIN)
-               return -EINVAL;
-       *(int *)(ea->var) = new;
-       /* Always return full write size even if we didn't consume all */
-       return size;
-}
-EXPORT_SYMBOL_GPL(sysdev_store_int);
-
-ssize_t sysdev_show_int(struct sys_device *sysdev,
-                         struct sysdev_attribute *attr,
-                         char *buf)
-{
-       struct sysdev_ext_attribute *ea = to_ext_attr(attr);
-       return snprintf(buf, PAGE_SIZE, "%d\n", *(int *)(ea->var));
-}
-EXPORT_SYMBOL_GPL(sysdev_show_int);
-
index febbc0a..ec31f7d 100644 (file)
@@ -169,10 +169,8 @@ int bcma_bus_register(struct bcma_bus *bus)
        err = bcma_sprom_get(bus);
        if (err == -ENOENT) {
                pr_err("No SPROM available\n");
-       } else if (err) {
+       } else if (err)
                pr_err("Failed to get SPROM: %d\n", err);
-               return -ENOENT;
-       }
 
        /* Register found cores */
        bcma_register_cores(bus);
index cad9948..3a2f672 100644 (file)
@@ -399,15 +399,18 @@ int bcma_bus_scan(struct bcma_bus *bus)
                core->bus = bus;
 
                err = bcma_get_next_core(bus, &eromptr, NULL, core_num, core);
-               if (err == -ENODEV) {
-                       core_num++;
-                       continue;
-               } else if (err == -ENXIO)
-                       continue;
-               else if (err == -ESPIPE)
-                       break;
-               else if (err < 0)
+               if (err < 0) {
+                       kfree(core);
+                       if (err == -ENODEV) {
+                               core_num++;
+                               continue;
+                       } else if (err == -ENXIO) {
+                               continue;
+                       } else if (err == -ESPIPE) {
+                               break;
+                       }
                        return err;
+               }
 
                core->core_index = core_num++;
                bus->nr_cores++;
index 510fb10..9baf11e 100644 (file)
@@ -4368,8 +4368,14 @@ out_unreg_blkdev:
 out_put_disk:
        while (dr--) {
                del_timer_sync(&motor_off_timer[dr]);
-               if (disks[dr]->queue)
+               if (disks[dr]->queue) {
                        blk_cleanup_queue(disks[dr]->queue);
+                       /*
+                        * put_disk() is not paired with add_disk() and
+                        * will put queue reference one extra time. fix it.
+                        */
+                       disks[dr]->queue = NULL;
+               }
                put_disk(disks[dr]);
        }
        return err;
@@ -4579,6 +4585,15 @@ static void __exit floppy_module_exit(void)
                        platform_device_unregister(&floppy_device[drive]);
                }
                blk_cleanup_queue(disks[drive]->queue);
+
+               /*
+                * These disks have not called add_disk().  Don't put down
+                * queue reference in put_disk().
+                */
+               if (!(allowed_drive_mask & (1 << drive)) ||
+                   fdc_state[FDC(drive)].version == FDC_NONE)
+                       disks[drive]->queue = NULL;
+
                put_disk(disks[drive]);
        }
 
index f002577..cd50435 100644 (file)
@@ -356,14 +356,14 @@ lo_direct_splice_actor(struct pipe_inode_info *pipe, struct splice_desc *sd)
        return __splice_from_pipe(pipe, sd, lo_splice_actor);
 }
 
-static int
+static ssize_t
 do_lo_receive(struct loop_device *lo,
              struct bio_vec *bvec, int bsize, loff_t pos)
 {
        struct lo_read_data cookie;
        struct splice_desc sd;
        struct file *file;
-       long retval;
+       ssize_t retval;
 
        cookie.lo = lo;
        cookie.page = bvec->bv_page;
@@ -379,26 +379,28 @@ do_lo_receive(struct loop_device *lo,
        file = lo->lo_backing_file;
        retval = splice_direct_to_actor(file, &sd, lo_direct_splice_actor);
 
-       if (retval < 0)
-               return retval;
-       if (retval != bvec->bv_len)
-               return -EIO;
-       return 0;
+       return retval;
 }
 
 static int
 lo_receive(struct loop_device *lo, struct bio *bio, int bsize, loff_t pos)
 {
        struct bio_vec *bvec;
-       int i, ret = 0;
+       ssize_t s;
+       int i;
 
        bio_for_each_segment(bvec, bio, i) {
-               ret = do_lo_receive(lo, bvec, bsize, pos);
-               if (ret < 0)
+               s = do_lo_receive(lo, bvec, bsize, pos);
+               if (s < 0)
+                       return s;
+
+               if (s != bvec->bv_len) {
+                       zero_fill_bio(bio);
                        break;
+               }
                pos += bvec->bv_len;
        }
-       return ret;
+       return 0;
 }
 
 static int do_bio_filebacked(struct loop_device *lo, struct bio *bio)
index b74eab7..8eb81c9 100644 (file)
@@ -2068,8 +2068,6 @@ static int mtip_hw_ioctl(struct driver_data *dd, unsigned int cmd,
  *          when the read completes.
  * @data     Callback data passed to the callback function
  *          when the read completes.
- * @barrier  If non-zero, this command must be completed before
- *          issuing any other commands.
  * @dir      Direction (read or write)
  *
  * return value
@@ -2077,7 +2075,7 @@ static int mtip_hw_ioctl(struct driver_data *dd, unsigned int cmd,
  */
 static void mtip_hw_submit_io(struct driver_data *dd, sector_t start,
                              int nsect, int nents, int tag, void *callback,
-                             void *data, int barrier, int dir)
+                             void *data, int dir)
 {
        struct host_to_dev_fis  *fis;
        struct mtip_port *port = dd->port;
@@ -2108,8 +2106,6 @@ static void mtip_hw_submit_io(struct driver_data *dd, sector_t start,
        *((unsigned int *) &fis->lba_low) = (start & 0xFFFFFF);
        *((unsigned int *) &fis->lba_low_ex) = ((start >> 24) & 0xFFFFFF);
        fis->device      = 1 << 6;
-       if (barrier)
-               fis->device |= FUA_BIT;
        fis->features    = nsect & 0xFF;
        fis->features_ex = (nsect >> 8) & 0xFF;
        fis->sect_count  = ((tag << 3) | (tag >> 5));
@@ -3087,7 +3083,6 @@ static void mtip_make_request(struct request_queue *queue, struct bio *bio)
                                tag,
                                bio_endio,
                                bio,
-                               bio->bi_rw & REQ_FUA,
                                bio_data_dir(bio));
        } else
                bio_io_error(bio);
@@ -3187,6 +3182,10 @@ skip_create_disk:
        blk_queue_max_segments(dd->queue, MTIP_MAX_SG);
        blk_queue_physical_block_size(dd->queue, 4096);
        blk_queue_io_min(dd->queue, 4096);
+       /*
+        * write back cache is not supported in the device. FUA depends on
+        * write back cache support, hence setting flush support to zero.
+        */
        blk_queue_flush(dd->queue, 0);
 
        /* Set the capacity of the device in 512 byte sectors. */
index 723d7c4..e0554a8 100644 (file)
 /* BAR number used to access the HBA registers. */
 #define MTIP_ABAR              5
 
-/* Forced Unit Access Bit */
-#define FUA_BIT                        0x80
-
 #ifdef DEBUG
  #define dbg_printk(format, arg...)    \
        printk(pr_fmt(format), ##arg);
@@ -415,8 +412,6 @@ struct driver_data {
 
        atomic_t resumeflag; /* Atomic variable to track suspend/resume */
 
-       atomic_t eh_active; /* Flag for error handling tracking */
-
        struct task_struct *mtip_svc_handler; /* task_struct of svc thd */
 };
 
index 3fd31de..a6278e7 100644 (file)
@@ -380,6 +380,7 @@ static int rbd_get_client(struct rbd_device *rbd_dev, const char *mon_addr,
        rbdc = __rbd_client_find(opt);
        if (rbdc) {
                ceph_destroy_options(opt);
+               kfree(rbd_opts);
 
                /* using an existing client */
                kref_get(&rbdc->kref);
@@ -406,15 +407,15 @@ done_err:
 
 /*
  * Destroy ceph client
+ *
+ * Caller must hold node_lock.
  */
 static void rbd_client_release(struct kref *kref)
 {
        struct rbd_client *rbdc = container_of(kref, struct rbd_client, kref);
 
        dout("rbd_release_client %p\n", rbdc);
-       spin_lock(&node_lock);
        list_del(&rbdc->node);
-       spin_unlock(&node_lock);
 
        ceph_destroy_client(rbdc->client);
        kfree(rbdc->rbd_opts);
@@ -427,7 +428,9 @@ static void rbd_client_release(struct kref *kref)
  */
 static void rbd_put_client(struct rbd_device *rbd_dev)
 {
+       spin_lock(&node_lock);
        kref_put(&rbd_dev->rbd_client->kref, rbd_client_release);
+       spin_unlock(&node_lock);
        rbd_dev->rbd_client = NULL;
        rbd_dev->client = NULL;
 }
index 55eaf47..d620b44 100644 (file)
 
 /* used to tell the module to turn on full debugging messages */
 static bool debug;
-/* used to keep tray locked at all times */
-static int keeplocked;
 /* default compatibility mode */
 static bool autoclose=1;
 static bool autoeject;
@@ -1204,7 +1202,7 @@ void cdrom_release(struct cdrom_device_info *cdi, fmode_t mode)
                cdinfo(CD_CLOSE, "Use count for \"/dev/%s\" now zero\n", cdi->name);
                cdrom_dvd_rw_close_write(cdi);
 
-               if ((cdo->capability & CDC_LOCK) && !keeplocked) {
+               if ((cdo->capability & CDC_LOCK) && !cdi->keeplocked) {
                        cdinfo(CD_CLOSE, "Unlocking door!\n");
                        cdo->lock_door(cdi, 0);
                }
@@ -1371,7 +1369,7 @@ static int cdrom_select_disc(struct cdrom_device_info *cdi, int slot)
        curslot = info->hdr.curslot;
        kfree(info);
 
-       if (cdi->use_count > 1 || keeplocked) {
+       if (cdi->use_count > 1 || cdi->keeplocked) {
                if (slot == CDSL_CURRENT) {
                        return curslot;
                } else {
@@ -2119,11 +2117,6 @@ static int cdrom_read_cdda_old(struct cdrom_device_info *cdi, __u8 __user *ubuf,
        if (!nr)
                return -ENOMEM;
 
-       if (!access_ok(VERIFY_WRITE, ubuf, nframes * CD_FRAMESIZE_RAW)) {
-               ret = -EFAULT;
-               goto out;
-       }
-
        cgc.data_direction = CGC_DATA_READ;
        while (nframes > 0) {
                if (nr > nframes)
@@ -2132,7 +2125,7 @@ static int cdrom_read_cdda_old(struct cdrom_device_info *cdi, __u8 __user *ubuf,
                ret = cdrom_read_block(cdi, &cgc, lba, nr, 1, CD_FRAMESIZE_RAW);
                if (ret)
                        break;
-               if (__copy_to_user(ubuf, cgc.buffer, CD_FRAMESIZE_RAW * nr)) {
+               if (copy_to_user(ubuf, cgc.buffer, CD_FRAMESIZE_RAW * nr)) {
                        ret = -EFAULT;
                        break;
                }
@@ -2140,7 +2133,6 @@ static int cdrom_read_cdda_old(struct cdrom_device_info *cdi, __u8 __user *ubuf,
                nframes -= nr;
                lba += nr;
        }
-out:
        kfree(cgc.buffer);
        return ret;
 }
@@ -2295,7 +2287,7 @@ static int cdrom_ioctl_eject(struct cdrom_device_info *cdi)
 
        if (!CDROM_CAN(CDC_OPEN_TRAY))
                return -ENOSYS;
-       if (cdi->use_count != 1 || keeplocked)
+       if (cdi->use_count != 1 || cdi->keeplocked)
                return -EBUSY;
        if (CDROM_CAN(CDC_LOCK)) {
                int ret = cdi->ops->lock_door(cdi, 0);
@@ -2322,7 +2314,7 @@ static int cdrom_ioctl_eject_sw(struct cdrom_device_info *cdi,
 
        if (!CDROM_CAN(CDC_OPEN_TRAY))
                return -ENOSYS;
-       if (keeplocked)
+       if (cdi->keeplocked)
                return -EBUSY;
 
        cdi->options &= ~(CDO_AUTO_CLOSE | CDO_AUTO_EJECT);
@@ -2453,7 +2445,7 @@ static int cdrom_ioctl_lock_door(struct cdrom_device_info *cdi,
        if (!CDROM_CAN(CDC_LOCK))
                return -EDRIVE_CANT_DO_THIS;
 
-       keeplocked = arg ? 1 : 0;
+       cdi->keeplocked = arg ? 1 : 0;
 
        /*
         * Don't unlock the door on multiple opens by default, but allow
index 97f87b2..f4aed5f 100644 (file)
@@ -1343,7 +1343,7 @@ static int __init at_dma_probe(struct platform_device *pdev)
 
                tasklet_init(&atchan->tasklet, atc_tasklet,
                                (unsigned long)atchan);
-               atc_enable_irq(atchan);
+               atc_enable_chan_irq(atdma, i);
        }
 
        /* set base routines */
@@ -1410,7 +1410,7 @@ static int __exit at_dma_remove(struct platform_device *pdev)
                struct at_dma_chan      *atchan = to_at_dma_chan(chan);
 
                /* Disable interrupts */
-               atc_disable_irq(atchan);
+               atc_disable_chan_irq(atdma, chan->chan_id);
                tasklet_disable(&atchan->tasklet);
 
                tasklet_kill(&atchan->tasklet);
index dcaedfc..a8d3277 100644 (file)
@@ -327,28 +327,27 @@ static void atc_dump_lli(struct at_dma_chan *atchan, struct at_lli *lli)
 }
 
 
-static void atc_setup_irq(struct at_dma_chan *atchan, int on)
+static void atc_setup_irq(struct at_dma *atdma, int chan_id, int on)
 {
-       struct at_dma   *atdma = to_at_dma(atchan->chan_common.device);
-       u32             ebci;
+       u32 ebci;
 
        /* enable interrupts on buffer transfer completion & error */
-       ebci =    AT_DMA_BTC(atchan->chan_common.chan_id)
-               | AT_DMA_ERR(atchan->chan_common.chan_id);
+       ebci =    AT_DMA_BTC(chan_id)
+               | AT_DMA_ERR(chan_id);
        if (on)
                dma_writel(atdma, EBCIER, ebci);
        else
                dma_writel(atdma, EBCIDR, ebci);
 }
 
-static inline void atc_enable_irq(struct at_dma_chan *atchan)
+static void atc_enable_chan_irq(struct at_dma *atdma, int chan_id)
 {
-       atc_setup_irq(atchan, 1);
+       atc_setup_irq(atdma, chan_id, 1);
 }
 
-static inline void atc_disable_irq(struct at_dma_chan *atchan)
+static void atc_disable_chan_irq(struct at_dma *atdma, int chan_id)
 {
-       atc_setup_irq(atchan, 0);
+       atc_setup_irq(atdma, chan_id, 0);
 }
 
 
index 2b8661b..24225f0 100644 (file)
@@ -599,7 +599,7 @@ static int dmatest_add_channel(struct dma_chan *chan)
        }
        if (dma_has_cap(DMA_PQ, dma_dev->cap_mask)) {
                cnt = dmatest_add_threads(dtc, DMA_PQ);
-               thread_count += cnt > 0 ?: 0;
+               thread_count += cnt > 0 ? cnt : 0;
        }
 
        pr_info("dmatest: Started %u threads using %s\n",
index a8af379..8bc5acf 100644 (file)
@@ -1102,11 +1102,13 @@ static int sdma_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
        case DMA_SLAVE_CONFIG:
                if (dmaengine_cfg->direction == DMA_DEV_TO_MEM) {
                        sdmac->per_address = dmaengine_cfg->src_addr;
-                       sdmac->watermark_level = dmaengine_cfg->src_maxburst;
+                       sdmac->watermark_level = dmaengine_cfg->src_maxburst *
+                                               dmaengine_cfg->src_addr_width;
                        sdmac->word_size = dmaengine_cfg->src_addr_width;
                } else {
                        sdmac->per_address = dmaengine_cfg->dst_addr;
-                       sdmac->watermark_level = dmaengine_cfg->dst_maxburst;
+                       sdmac->watermark_level = dmaengine_cfg->dst_maxburst *
+                                               dmaengine_cfg->dst_addr_width;
                        sdmac->word_size = dmaengine_cfg->dst_addr_width;
                }
                sdmac->direction = dmaengine_cfg->direction;
index 54043cd..812fd76 100644 (file)
@@ -1262,7 +1262,8 @@ static int __init sh_dmae_probe(struct platform_device *pdev)
 
        INIT_LIST_HEAD(&shdev->common.channels);
 
-       dma_cap_set(DMA_MEMCPY, shdev->common.cap_mask);
+       if (!pdata->slave_only)
+               dma_cap_set(DMA_MEMCPY, shdev->common.cap_mask);
        if (pdata->slave && pdata->slave_num)
                dma_cap_set(DMA_SLAVE, shdev->common.cap_mask);
 
index 6628fea..7f5f0da 100644 (file)
@@ -263,6 +263,7 @@ static inline struct fw_ohci *fw_ohci(struct fw_card *card)
 static char ohci_driver_name[] = KBUILD_MODNAME;
 
 #define PCI_DEVICE_ID_AGERE_FW643      0x5901
+#define PCI_DEVICE_ID_CREATIVE_SB1394  0x4001
 #define PCI_DEVICE_ID_JMICRON_JMB38X_FW        0x2380
 #define PCI_DEVICE_ID_TI_TSB12LV22     0x8009
 #define PCI_DEVICE_ID_TI_TSB12LV26     0x8020
@@ -289,6 +290,9 @@ static const struct {
        {PCI_VENDOR_ID_ATT, PCI_DEVICE_ID_AGERE_FW643, 6,
                QUIRK_NO_MSI},
 
+       {PCI_VENDOR_ID_CREATIVE, PCI_DEVICE_ID_CREATIVE_SB1394, PCI_ANY_ID,
+               QUIRK_RESET_PACKET},
+
        {PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB38X_FW, PCI_ANY_ID,
                QUIRK_NO_MSI},
 
@@ -299,7 +303,7 @@ static const struct {
                QUIRK_NO_MSI},
 
        {PCI_VENDOR_ID_RICOH, PCI_ANY_ID, PCI_ANY_ID,
-               QUIRK_CYCLE_TIMER},
+               QUIRK_CYCLE_TIMER | QUIRK_NO_MSI},
 
        {PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_TSB12LV22, PCI_ANY_ID,
                QUIRK_CYCLE_TIMER | QUIRK_RESET_PACKET | QUIRK_NO_1394A},
index 5b69480..ddfacc5 100644 (file)
@@ -96,7 +96,7 @@ static const char *gpio_p2_names[LPC32XX_GPIO_P2_MAX] = {
 };
 
 static const char *gpio_p3_names[LPC32XX_GPIO_P3_MAX] = {
-       "gpi000", "gpio01", "gpio02", "gpio03",
+       "gpio00", "gpio01", "gpio02", "gpio03",
        "gpio04", "gpio05"
 };
 
index 03d6dd5..f0febe5 100644 (file)
@@ -448,6 +448,7 @@ static int __devinit ioh_gpio_probe(struct pci_dev *pdev,
                chip->reg = chip->base;
                chip->ch = i;
                mutex_init(&chip->lock);
+               spin_lock_init(&chip->spinlock);
                ioh_gpio_setup(chip, num_ports[i]);
                ret = gpiochip_add(&chip->gpio);
                if (ret) {
index 68fa55e..e8729cc 100644 (file)
@@ -392,6 +392,7 @@ static int __devinit pch_gpio_probe(struct pci_dev *pdev,
        chip->reg = chip->base;
        pci_set_drvdata(pdev, chip);
        mutex_init(&chip->lock);
+       spin_lock_init(&chip->spinlock);
        pch_gpio_setup(chip);
        ret = gpiochip_add(&chip->gpio);
        if (ret) {
index a766177..0a79a11 100644 (file)
@@ -2387,27 +2387,30 @@ static struct samsung_gpio_chip exynos4_gpios_3[] = {
 };
 
 #if defined(CONFIG_ARCH_EXYNOS4) && defined(CONFIG_OF)
-static int exynos4_gpio_xlate(struct gpio_chip *gc, struct device_node *np,
-                             const void *gpio_spec, u32 *flags)
+static int exynos4_gpio_xlate(struct gpio_chip *gc,
+                       const struct of_phandle_args *gpiospec, u32 *flags)
 {
-       const __be32 *gpio = gpio_spec;
-       const u32 n = be32_to_cpup(gpio);
-       unsigned int pin = gc->base + be32_to_cpu(gpio[0]);
+       unsigned int pin;
 
        if (WARN_ON(gc->of_gpio_n_cells < 4))
                return -EINVAL;
 
-       if (n > gc->ngpio)
+       if (WARN_ON(gpiospec->args_count < gc->of_gpio_n_cells))
                return -EINVAL;
 
-       if (s3c_gpio_cfgpin(pin, S3C_GPIO_SFN(be32_to_cpu(gpio[1]))))
+       if (gpiospec->args[0] > gc->ngpio)
+               return -EINVAL;
+
+       pin = gc->base + gpiospec->args[0];
+
+       if (s3c_gpio_cfgpin(pin, S3C_GPIO_SFN(gpiospec->args[1])))
                pr_warn("gpio_xlate: failed to set pin function\n");
-       if (s3c_gpio_setpull(pin, be32_to_cpu(gpio[2])))
+       if (s3c_gpio_setpull(pin, gpiospec->args[2]))
                pr_warn("gpio_xlate: failed to set pin pull up/down\n");
-       if (s5p_gpio_set_drvstr(pin, be32_to_cpu(gpio[3])))
+       if (s5p_gpio_set_drvstr(pin, gpiospec->args[3]))
                pr_warn("gpio_xlate: failed to set pin drive strength\n");
 
-       return n;
+       return gpiospec->args[0];
 }
 
 static const struct of_device_id exynos4_gpio_dt_match[] __initdata = {
index 396e60c..f8625e2 100644 (file)
@@ -140,7 +140,7 @@ int drm_gem_object_init(struct drm_device *dev,
        obj->dev = dev;
        obj->filp = shmem_file_setup("drm mm object", size, VM_NORESERVE);
        if (IS_ERR(obj->filp))
-               return -ENOMEM;
+               return PTR_ERR(obj->filp);
 
        kref_init(&obj->refcount);
        atomic_set(&obj->handle_count, 0);
index ddd70db..637fcc3 100644 (file)
@@ -315,7 +315,8 @@ static int compat_drm_getclient(struct file *file, unsigned int cmd,
        if (err)
                return err;
 
-       if (__get_user(c32.auth, &client->auth)
+       if (__get_user(c32.idx, &client->idx)
+           || __get_user(c32.auth, &client->auth)
            || __get_user(c32.pid, &client->pid)
            || __get_user(c32.uid, &client->uid)
            || __get_user(c32.magic, &client->magic)
index f7c17b2..7f4b4e1 100644 (file)
@@ -886,7 +886,7 @@ static int i810_flush_queue(struct drm_device *dev)
 }
 
 /* Must be called with the lock held */
-void i810_driver_reclaim_buffers(struct drm_device *dev,
+static void i810_reclaim_buffers(struct drm_device *dev,
                                 struct drm_file *file_priv)
 {
        struct drm_device_dma *dma = dev->dma;
@@ -1223,17 +1223,12 @@ void i810_driver_preclose(struct drm_device *dev, struct drm_file *file_priv)
                if (dev_priv->page_flipping)
                        i810_do_cleanup_pageflip(dev);
        }
+}
 
-       if (file_priv->master && file_priv->master->lock.hw_lock) {
-               drm_idlelock_take(&file_priv->master->lock);
-               i810_driver_reclaim_buffers(dev, file_priv);
-               drm_idlelock_release(&file_priv->master->lock);
-       } else {
-               /* master disappeared, clean up stuff anyway and hope nothing
-                * goes wrong */
-               i810_driver_reclaim_buffers(dev, file_priv);
-       }
-
+void i810_driver_reclaim_buffers_locked(struct drm_device *dev,
+                                       struct drm_file *file_priv)
+{
+       i810_reclaim_buffers(dev, file_priv);
 }
 
 int i810_driver_dma_quiescent(struct drm_device *dev)
index 053f1ee..ec12f7d 100644 (file)
@@ -63,6 +63,7 @@ static struct drm_driver driver = {
        .lastclose = i810_driver_lastclose,
        .preclose = i810_driver_preclose,
        .device_is_agp = i810_driver_device_is_agp,
+       .reclaim_buffers_locked = i810_driver_reclaim_buffers_locked,
        .dma_quiescent = i810_driver_dma_quiescent,
        .ioctls = i810_ioctls,
        .fops = &i810_driver_fops,
index 6e0acad..c9339f4 100644 (file)
@@ -116,12 +116,14 @@ typedef struct drm_i810_private {
 
                                /* i810_dma.c */
 extern int i810_driver_dma_quiescent(struct drm_device *dev);
-void i810_driver_reclaim_buffers(struct drm_device *dev,
-                                struct drm_file *file_priv);
+extern void i810_driver_reclaim_buffers_locked(struct drm_device *dev,
+                                              struct drm_file *file_priv);
 extern int i810_driver_load(struct drm_device *, unsigned long flags);
 extern void i810_driver_lastclose(struct drm_device *dev);
 extern void i810_driver_preclose(struct drm_device *dev,
                                 struct drm_file *file_priv);
+extern void i810_driver_reclaim_buffers_locked(struct drm_device *dev,
+                                              struct drm_file *file_priv);
 extern int i810_driver_device_is_agp(struct drm_device *dev);
 
 extern long i810_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
index b3b51c4..00fbff5 100644 (file)
@@ -1872,7 +1872,7 @@ static void intel_update_fbc(struct drm_device *dev)
        if (enable_fbc < 0) {
                DRM_DEBUG_KMS("fbc set to per-chip default\n");
                enable_fbc = 1;
-               if (INTEL_INFO(dev)->gen <= 5)
+               if (INTEL_INFO(dev)->gen <= 6)
                        enable_fbc = 0;
        }
        if (!enable_fbc) {
@@ -5307,6 +5307,7 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc,
                }
        }
 
+       pipeconf &= ~PIPECONF_INTERLACE_MASK;
        if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) {
                pipeconf |= PIPECONF_INTERLACE_W_FIELD_INDICATION;
                /* the chip adds 2 halflines automatically */
@@ -5317,7 +5318,7 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc,
                adjusted_mode->crtc_vsync_end -= 1;
                adjusted_mode->crtc_vsync_start -= 1;
        } else
-               pipeconf &= ~PIPECONF_INTERLACE_MASK; /* progressive */
+               pipeconf |= PIPECONF_PROGRESSIVE;
 
        I915_WRITE(HTOTAL(pipe),
                   (adjusted_mode->crtc_hdisplay - 1) |
@@ -5902,6 +5903,7 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
                }
        }
 
+       pipeconf &= ~PIPECONF_INTERLACE_MASK;
        if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) {
                pipeconf |= PIPECONF_INTERLACE_W_FIELD_INDICATION;
                /* the chip adds 2 halflines automatically */
@@ -5912,7 +5914,7 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
                adjusted_mode->crtc_vsync_end -= 1;
                adjusted_mode->crtc_vsync_start -= 1;
        } else
-               pipeconf &= ~PIPECONF_INTERLACE_W_FIELD_INDICATION; /* progressive */
+               pipeconf |= PIPECONF_PROGRESSIVE;
 
        I915_WRITE(HTOTAL(pipe),
                   (adjusted_mode->crtc_hdisplay - 1) |
index db3b461..94f860c 100644 (file)
@@ -208,17 +208,8 @@ intel_dp_link_clock(uint8_t link_bw)
  */
 
 static int
-intel_dp_link_required(struct intel_dp *intel_dp, int pixel_clock, int check_bpp)
+intel_dp_link_required(int pixel_clock, int bpp)
 {
-       struct drm_crtc *crtc = intel_dp->base.base.crtc;
-       struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
-       int bpp = 24;
-
-       if (check_bpp)
-               bpp = check_bpp;
-       else if (intel_crtc)
-               bpp = intel_crtc->bpp;
-
        return (pixel_clock * bpp + 9) / 10;
 }
 
@@ -245,12 +236,11 @@ intel_dp_mode_valid(struct drm_connector *connector,
                        return MODE_PANEL;
        }
 
-       mode_rate = intel_dp_link_required(intel_dp, mode->clock, 0);
+       mode_rate = intel_dp_link_required(mode->clock, 24);
        max_rate = intel_dp_max_data_rate(max_link_clock, max_lanes);
 
        if (mode_rate > max_rate) {
-                       mode_rate = intel_dp_link_required(intel_dp,
-                                                          mode->clock, 18);
+                       mode_rate = intel_dp_link_required(mode->clock, 18);
                        if (mode_rate > max_rate)
                                return MODE_CLOCK_HIGH;
                        else
@@ -683,7 +673,7 @@ intel_dp_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode,
        int lane_count, clock;
        int max_lane_count = intel_dp_max_lane_count(intel_dp);
        int max_clock = intel_dp_max_link_bw(intel_dp) == DP_LINK_BW_2_7 ? 1 : 0;
-       int bpp = mode->private_flags & INTEL_MODE_DP_FORCE_6BPC ? 18 : 0;
+       int bpp = mode->private_flags & INTEL_MODE_DP_FORCE_6BPC ? 18 : 24;
        static int bws[2] = { DP_LINK_BW_1_62, DP_LINK_BW_2_7 };
 
        if (is_edp(intel_dp) && intel_dp->panel_fixed_mode) {
@@ -701,7 +691,7 @@ intel_dp_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode,
                for (clock = 0; clock <= max_clock; clock++) {
                        int link_avail = intel_dp_max_data_rate(intel_dp_link_clock(bws[clock]), lane_count);
 
-                       if (intel_dp_link_required(intel_dp, mode->clock, bpp)
+                       if (intel_dp_link_required(mode->clock, bpp)
                                        <= link_avail) {
                                intel_dp->link_bw = bws[clock];
                                intel_dp->lane_count = lane_count;
index 798f6e1..aa84832 100644 (file)
@@ -692,6 +692,14 @@ static const struct dmi_system_id intel_no_lvds[] = {
                        DMI_MATCH(DMI_BOARD_NAME, "i915GMm-HFS"),
                },
        },
+       {
+               .callback = intel_no_lvds_dmi_callback,
+                .ident = "AOpen i45GMx-I",
+                .matches = {
+                        DMI_MATCH(DMI_BOARD_VENDOR, "AOpen"),
+                        DMI_MATCH(DMI_BOARD_NAME, "i45GMx-I"),
+                },
+        },
        {
                .callback = intel_no_lvds_dmi_callback,
                .ident = "Aopen i945GTt-VFA",
index 1e382ad..a37c31e 100644 (file)
@@ -54,9 +54,10 @@ struct bit_entry {
 int bit_table(struct drm_device *, u8 id, struct bit_entry *);
 
 enum dcb_gpio_tag {
-       DCB_GPIO_TVDAC0 = 0xc,
+       DCB_GPIO_PANEL_POWER = 0x01,
+       DCB_GPIO_TVDAC0 = 0x0c,
        DCB_GPIO_TVDAC1 = 0x2d,
-       DCB_GPIO_PWM_FAN = 0x9,
+       DCB_GPIO_PWM_FAN = 0x09,
        DCB_GPIO_FAN_SENSE = 0x3d,
        DCB_GPIO_UNUSED = 0xff
 };
index 3cb52bc..795a9e3 100644 (file)
@@ -219,6 +219,16 @@ nouveau_display_init(struct drm_device *dev)
        if (ret)
                return ret;
 
+       /* power on internal panel if it's not already.  the init tables of
+        * some vbios default this to off for some reason, causing the
+        * panel to not work after resume
+        */
+       if (nouveau_gpio_func_get(dev, DCB_GPIO_PANEL_POWER) == 0) {
+               nouveau_gpio_func_set(dev, DCB_GPIO_PANEL_POWER, true);
+               msleep(300);
+       }
+
+       /* enable polling for external displays */
        drm_kms_helper_poll_enable(dev);
 
        /* enable hotplug interrupts */
index e4a7cfe..81d7962 100644 (file)
@@ -124,7 +124,7 @@ MODULE_PARM_DESC(ctxfw, "Use external HUB/GPC ucode (fermi)\n");
 int nouveau_ctxfw;
 module_param_named(ctxfw, nouveau_ctxfw, int, 0400);
 
-MODULE_PARM_DESC(ctxfw, "Santise DCB table according to MXM-SIS\n");
+MODULE_PARM_DESC(mxmdcb, "Santise DCB table according to MXM-SIS\n");
 int nouveau_mxmdcb = 1;
 module_param_named(mxmdcb, nouveau_mxmdcb, int, 0400);
 
index 5f0bc57..7ce3fde 100644 (file)
@@ -379,6 +379,25 @@ retry:
        return 0;
 }
 
+static int
+validate_sync(struct nouveau_channel *chan, struct nouveau_bo *nvbo)
+{
+       struct nouveau_fence *fence = NULL;
+       int ret = 0;
+
+       spin_lock(&nvbo->bo.bdev->fence_lock);
+       if (nvbo->bo.sync_obj)
+               fence = nouveau_fence_ref(nvbo->bo.sync_obj);
+       spin_unlock(&nvbo->bo.bdev->fence_lock);
+
+       if (fence) {
+               ret = nouveau_fence_sync(fence, chan);
+               nouveau_fence_unref(&fence);
+       }
+
+       return ret;
+}
+
 static int
 validate_list(struct nouveau_channel *chan, struct list_head *list,
              struct drm_nouveau_gem_pushbuf_bo *pbbo, uint64_t user_pbbo_ptr)
@@ -393,7 +412,7 @@ validate_list(struct nouveau_channel *chan, struct list_head *list,
        list_for_each_entry(nvbo, list, entry) {
                struct drm_nouveau_gem_pushbuf_bo *b = &pbbo[nvbo->pbbo_index];
 
-               ret = nouveau_fence_sync(nvbo->bo.sync_obj, chan);
+               ret = validate_sync(chan, nvbo);
                if (unlikely(ret)) {
                        NV_ERROR(dev, "fail pre-validate sync\n");
                        return ret;
@@ -416,7 +435,7 @@ validate_list(struct nouveau_channel *chan, struct list_head *list,
                        return ret;
                }
 
-               ret = nouveau_fence_sync(nvbo->bo.sync_obj, chan);
+               ret = validate_sync(chan, nvbo);
                if (unlikely(ret)) {
                        NV_ERROR(dev, "fail post-validate sync\n");
                        return ret;
index 8bccddf..e5a64f0 100644 (file)
@@ -656,7 +656,16 @@ nouveau_mxm_init(struct drm_device *dev)
 
        if (mxm_shadow(dev, mxm[0])) {
                MXM_MSG(dev, "failed to locate valid SIS\n");
+#if 0
+               /* we should, perhaps, fall back to some kind of limited
+                * mode here if the x86 vbios hasn't already done the
+                * work for us (so we prevent loading with completely
+                * whacked vbios tables).
+                */
                return -EINVAL;
+#else
+               return 0;
+#endif
        }
 
        MXM_MSG(dev, "MXMS Version %d.%d\n",
index 0393721..ec5481d 100644 (file)
@@ -495,9 +495,9 @@ nv50_pm_clocks_pre(struct drm_device *dev, struct nouveau_pm_level *perflvl)
        struct drm_nouveau_private *dev_priv = dev->dev_private;
        struct nv50_pm_state *info;
        struct pll_lims pll;
-       int ret = -EINVAL;
+       int clk, ret = -EINVAL;
        int N, M, P1, P2;
-       u32 clk, out;
+       u32 out;
 
        if (dev_priv->chipset == 0xaa ||
            dev_priv->chipset == 0xac)
index 8919352..742f17f 100644 (file)
@@ -1184,7 +1184,7 @@ static int dce4_crtc_do_set_base(struct drm_crtc *crtc,
        WREG32(EVERGREEN_GRPH_ENABLE + radeon_crtc->crtc_offset, 1);
 
        WREG32(EVERGREEN_DESKTOP_HEIGHT + radeon_crtc->crtc_offset,
-              crtc->mode.vdisplay);
+              target_fb->height);
        x &= ~3;
        y &= ~1;
        WREG32(EVERGREEN_VIEWPORT_START + radeon_crtc->crtc_offset,
@@ -1353,7 +1353,7 @@ static int avivo_crtc_do_set_base(struct drm_crtc *crtc,
        WREG32(AVIVO_D1GRPH_ENABLE + radeon_crtc->crtc_offset, 1);
 
        WREG32(AVIVO_D1MODE_DESKTOP_HEIGHT + radeon_crtc->crtc_offset,
-              crtc->mode.vdisplay);
+              target_fb->height);
        x &= ~3;
        y &= ~1;
        WREG32(AVIVO_D1MODE_VIEWPORT_START + radeon_crtc->crtc_offset,
index a71557c..552b436 100644 (file)
@@ -564,9 +564,21 @@ int radeon_dp_get_panel_mode(struct drm_encoder *encoder,
            ENCODER_OBJECT_ID_NUTMEG)
                panel_mode = DP_PANEL_MODE_INTERNAL_DP1_MODE;
        else if (radeon_connector_encoder_get_dp_bridge_encoder_id(connector) ==
-                ENCODER_OBJECT_ID_TRAVIS)
-               panel_mode = DP_PANEL_MODE_INTERNAL_DP2_MODE;
-       else if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) {
+                ENCODER_OBJECT_ID_TRAVIS) {
+               u8 id[6];
+               int i;
+               for (i = 0; i < 6; i++)
+                       id[i] = radeon_read_dpcd_reg(radeon_connector, 0x503 + i);
+               if (id[0] == 0x73 &&
+                   id[1] == 0x69 &&
+                   id[2] == 0x76 &&
+                   id[3] == 0x61 &&
+                   id[4] == 0x72 &&
+                   id[5] == 0x54)
+                       panel_mode = DP_PANEL_MODE_INTERNAL_DP1_MODE;
+               else
+                       panel_mode = DP_PANEL_MODE_INTERNAL_DP2_MODE;
+       } else if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) {
                u8 tmp = radeon_read_dpcd_reg(radeon_connector, DP_EDP_CONFIGURATION_CAP);
                if (tmp & 1)
                        panel_mode = DP_PANEL_MODE_INTERNAL_DP2_MODE;
index ae09fe8..9be353b 100644 (file)
@@ -3191,6 +3191,7 @@ static int evergreen_startup(struct radeon_device *rdev)
        if (r) {
                DRM_ERROR("radeon: failed testing IB (%d).\n", r);
                rdev->accel_working = false;
+               return r;
        }
 
        r = r600_audio_init(rdev);
index bfd36ab..18cd84f 100644 (file)
@@ -789,9 +789,7 @@ int r100_irq_process(struct radeon_device *rdev)
                        WREG32(RADEON_AIC_CNTL, msi_rearm | RS400_MSI_REARM);
                        break;
                default:
-                       msi_rearm = RREG32(RADEON_MSI_REARM_EN) & ~RV370_MSI_REARM_EN;
-                       WREG32(RADEON_MSI_REARM_EN, msi_rearm);
-                       WREG32(RADEON_MSI_REARM_EN, msi_rearm | RV370_MSI_REARM_EN);
+                       WREG32(RADEON_MSI_REARM_EN, RV370_MSI_REARM_EN);
                        break;
                }
        }
index d996f43..accc032 100644 (file)
@@ -468,27 +468,42 @@ set_default_state(struct radeon_device *rdev)
        radeon_ring_write(ring, sq_stack_resource_mgmt_2);
 }
 
+#define I2F_MAX_BITS 15
+#define I2F_MAX_INPUT  ((1 << I2F_MAX_BITS) - 1)
+#define I2F_SHIFT (24 - I2F_MAX_BITS)
+
+/*
+ * Converts unsigned integer into 32-bit IEEE floating point representation.
+ * Conversion is not universal and only works for the range from 0
+ * to 2^I2F_MAX_BITS-1. Currently we only use it with inputs between
+ * 0 and 16384 (inclusive), so I2F_MAX_BITS=15 is enough. If necessary,
+ * I2F_MAX_BITS can be increased, but that will add to the loop iterations
+ * and slow us down. Conversion is done by shifting the input and counting
+ * down until the first 1 reaches bit position 23. The resulting counter
+ * and the shifted input are, respectively, the exponent and the fraction.
+ * The sign is always zero.
+ */
 static uint32_t i2f(uint32_t input)
 {
        u32 result, i, exponent, fraction;
 
-       if ((input & 0x3fff) == 0)
-               result = 0; /* 0 is a special case */
+       WARN_ON_ONCE(input > I2F_MAX_INPUT);
+
+       if ((input & I2F_MAX_INPUT) == 0)
+               result = 0;
        else {
-               exponent = 140; /* exponent biased by 127; */
-               fraction = (input & 0x3fff) << 10; /* cheat and only
-                                                     handle numbers below 2^^15 */
-               for (i = 0; i < 14; i++) {
+               exponent = 126 + I2F_MAX_BITS;
+               fraction = (input & I2F_MAX_INPUT) << I2F_SHIFT;
+
+               for (i = 0; i < I2F_MAX_BITS; i++) {
                        if (fraction & 0x800000)
                                break;
                        else {
-                               fraction = fraction << 1; /* keep
-                                                            shifting left until top bit = 1 */
+                               fraction = fraction << 1;
                                exponent = exponent - 1;
                        }
                }
-               result = exponent << 23 | (fraction & 0x7fffff); /* mask
-                                                                   off top bit; assumed 1 */
+               result = exponent << 23 | (fraction & 0x7fffff);
        }
        return result;
 }
index 5082d17..9e72dae 100644 (file)
@@ -2931,6 +2931,20 @@ radeon_atombios_connected_scratch_regs(struct drm_connector *connector,
                        bios_6_scratch &= ~ATOM_S6_ACC_REQ_DFP5;
                }
        }
+       if ((radeon_encoder->devices & ATOM_DEVICE_DFP6_SUPPORT) &&
+           (radeon_connector->devices & ATOM_DEVICE_DFP6_SUPPORT)) {
+               if (connected) {
+                       DRM_DEBUG_KMS("DFP6 connected\n");
+                       bios_0_scratch |= ATOM_S0_DFP6;
+                       bios_3_scratch |= ATOM_S3_DFP6_ACTIVE;
+                       bios_6_scratch |= ATOM_S6_ACC_REQ_DFP6;
+               } else {
+                       DRM_DEBUG_KMS("DFP6 disconnected\n");
+                       bios_0_scratch &= ~ATOM_S0_DFP6;
+                       bios_3_scratch &= ~ATOM_S3_DFP6_ACTIVE;
+                       bios_6_scratch &= ~ATOM_S6_ACC_REQ_DFP6;
+               }
+       }
 
        if (rdev->family >= CHIP_R600) {
                WREG32(R600_BIOS_0_SCRATCH, bios_0_scratch);
@@ -2951,6 +2965,9 @@ radeon_atombios_encoder_crtc_scratch_regs(struct drm_encoder *encoder, int crtc)
        struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
        uint32_t bios_3_scratch;
 
+       if (ASIC_IS_DCE4(rdev))
+               return;
+
        if (rdev->family >= CHIP_R600)
                bios_3_scratch = RREG32(R600_BIOS_3_SCRATCH);
        else
index 13ac63b..98724fc 100644 (file)
@@ -59,8 +59,9 @@ static int radeon_atrm_call(acpi_handle atrm_handle, uint8_t *bios,
 
        obj = (union acpi_object *)buffer.pointer;
        memcpy(bios+offset, obj->buffer.pointer, obj->buffer.length);
+       len = obj->buffer.length;
        kfree(buffer.pointer);
-       return obj->buffer.length;
+       return len;
 }
 
 bool radeon_atrm_supported(struct pci_dev *pdev)
index cec51a5..49f7cb7 100644 (file)
@@ -883,6 +883,8 @@ int radeon_suspend_kms(struct drm_device *dev, pm_message_t state)
        if (dev->switch_power_state == DRM_SWITCH_POWER_OFF)
                return 0;
 
+       drm_kms_helper_poll_disable(dev);
+
        /* turn off display hw */
        list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
                drm_helper_connector_dpms(connector, DRM_MODE_DPMS_OFF);
@@ -972,6 +974,8 @@ int radeon_resume_kms(struct drm_device *dev)
        list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
                drm_helper_connector_dpms(connector, DRM_MODE_DPMS_ON);
        }
+
+       drm_kms_helper_poll_enable(dev);
        return 0;
 }
 
index 64ea3dd..4bd36a3 100644 (file)
@@ -364,8 +364,10 @@ int radeon_fence_count_emitted(struct radeon_device *rdev, int ring)
        int not_processed = 0;
 
        read_lock_irqsave(&rdev->fence_lock, irq_flags);
-       if (!rdev->fence_drv[ring].initialized)
+       if (!rdev->fence_drv[ring].initialized) {
+               read_unlock_irqrestore(&rdev->fence_lock, irq_flags);
                return 0;
+       }
 
        if (!list_empty(&rdev->fence_drv[ring].emitted)) {
                struct list_head *ptr;
index 7bb1b07..98a8ad6 100644 (file)
@@ -897,6 +897,7 @@ struct radeon_i2c_chan *radeon_i2c_create(struct drm_device *dev,
        i2c->rec = *rec;
        i2c->adapter.owner = THIS_MODULE;
        i2c->adapter.class = I2C_CLASS_DDC;
+       i2c->adapter.dev.parent = &dev->pdev->dev;
        i2c->dev = dev;
        i2c_set_adapdata(&i2c->adapter, i2c);
        if (rec->mm_i2c ||
@@ -957,6 +958,7 @@ struct radeon_i2c_chan *radeon_i2c_create_dp(struct drm_device *dev,
        i2c->rec = *rec;
        i2c->adapter.owner = THIS_MODULE;
        i2c->adapter.class = I2C_CLASS_DDC;
+       i2c->adapter.dev.parent = &dev->pdev->dev;
        i2c->dev = dev;
        snprintf(i2c->adapter.name, sizeof(i2c->adapter.name),
                 "Radeon aux bus %s", name);
index ec46eb4..c05865e 100644 (file)
@@ -684,9 +684,7 @@ int rs600_irq_process(struct radeon_device *rdev)
                        WREG32(RADEON_BUS_CNTL, msi_rearm | RS600_MSI_REARM);
                        break;
                default:
-                       msi_rearm = RREG32(RADEON_MSI_REARM_EN) & ~RV370_MSI_REARM_EN;
-                       WREG32(RADEON_MSI_REARM_EN, msi_rearm);
-                       WREG32(RADEON_MSI_REARM_EN, msi_rearm | RV370_MSI_REARM_EN);
+                       WREG32(RADEON_MSI_REARM_EN, RV370_MSI_REARM_EN);
                        break;
                }
        }
index 0af6ebd..b66ef0e 100644 (file)
@@ -378,7 +378,7 @@ int vmw_framebuffer_create_handle(struct drm_framebuffer *fb,
                                  unsigned int *handle)
 {
        if (handle)
-               handle = 0;
+               *handle = 0;
 
        return 0;
 }
index 0c33ae9..4066324 100644 (file)
@@ -548,6 +548,7 @@ static int mousevsc_remove(struct hv_device *dev)
        struct mousevsc_dev *input_dev = hv_get_drvdata(dev);
 
        vmbus_close(dev->channel);
+       hid_hw_stop(input_dev->hid_device);
        hid_destroy_device(input_dev->hid_device);
        mousevsc_free_device(input_dev);
 
index b47e58b..acab74c 100644 (file)
@@ -531,7 +531,6 @@ static int wacom_probe(struct hid_device *hdev,
        wdata->battery.type = POWER_SUPPLY_TYPE_BATTERY;
        wdata->battery.use_for_apm = 0;
 
-       power_supply_powers(&wdata->battery, &hdev->dev);
 
        ret = power_supply_register(&hdev->dev, &wdata->battery);
        if (ret) {
@@ -540,6 +539,8 @@ static int wacom_probe(struct hid_device *hdev,
                goto err_battery;
        }
 
+       power_supply_powers(&wdata->battery, &hdev->dev);
+
        wdata->ac.properties = wacom_ac_props;
        wdata->ac.num_properties = ARRAY_SIZE(wacom_ac_props);
        wdata->ac.get_property = wacom_ac_get_property;
@@ -547,14 +548,14 @@ static int wacom_probe(struct hid_device *hdev,
        wdata->ac.type = POWER_SUPPLY_TYPE_MAINS;
        wdata->ac.use_for_apm = 0;
 
-       power_supply_powers(&wdata->battery, &hdev->dev);
-
        ret = power_supply_register(&hdev->dev, &wdata->ac);
        if (ret) {
                hid_warn(hdev,
                         "can't create ac battery attribute, err: %d\n", ret);
                goto err_ac;
        }
+
+       power_supply_powers(&wdata->ac, &hdev->dev);
 #endif
        return 0;
 
index fc253b4..cac3589 100644 (file)
@@ -1226,14 +1226,14 @@ static int wiimote_hid_probe(struct hid_device *hdev,
        wdata->battery.type = POWER_SUPPLY_TYPE_BATTERY;
        wdata->battery.use_for_apm = 0;
 
-       power_supply_powers(&wdata->battery, &hdev->dev);
-
        ret = power_supply_register(&wdata->hdev->dev, &wdata->battery);
        if (ret) {
                hid_err(hdev, "Cannot register battery device\n");
                goto err_battery;
        }
 
+       power_supply_powers(&wdata->battery, &hdev->dev);
+
        ret = wiimote_leds_create(wdata);
        if (ret)
                goto err_free;
index 7c297d3..b1ec0e2 100644 (file)
@@ -922,11 +922,11 @@ void hiddev_disconnect(struct hid_device *hid)
        struct hiddev *hiddev = hid->hiddev;
        struct usbhid_device *usbhid = hid->driver_data;
 
+       usb_deregister_dev(usbhid->intf, &hiddev_class);
+
        mutex_lock(&hiddev->existancelock);
        hiddev->exist = 0;
 
-       usb_deregister_dev(usbhid->intf, &hiddev_class);
-
        if (hiddev->open) {
                mutex_unlock(&hiddev->existancelock);
                usbhid_close(hiddev->hid);
index 92f9497..6dbfd3e 100644 (file)
@@ -283,11 +283,11 @@ static inline long temp_from_reg(u8 reg)
 
 static inline u8 temp_to_reg(long val)
 {
-       if (val < 0)
-               val = 0;
-       else if (val > 1000 * 0xff)
-               val = 0xff;
-       return ((val + 500) / 1000);
+       if (val <= 0)
+               return 0;
+       if (val >= 1000 * 0xff)
+               return 0xff;
+       return (val + 500) / 1000;
 }
 
 /*
index eedf574..f609b57 100644 (file)
@@ -172,7 +172,7 @@ static inline void f75375_write8(struct i2c_client *client, u8 reg,
 static inline void f75375_write16(struct i2c_client *client, u8 reg,
                u16 value)
 {
-       int err = i2c_smbus_write_byte_data(client, reg, (value << 8));
+       int err = i2c_smbus_write_byte_data(client, reg, (value >> 8));
        if (err)
                return;
        i2c_smbus_write_byte_data(client, reg + 1, (value & 0xFF));
@@ -200,9 +200,6 @@ static struct f75375_data *f75375_update_device(struct device *dev)
                                f75375_read16(client, F75375_REG_FAN_MIN(nr));
                        data->fan_target[nr] =
                                f75375_read16(client, F75375_REG_FAN_EXP(nr));
-                       data->pwm[nr] = f75375_read8(client,
-                               F75375_REG_FAN_PWM_DUTY(nr));
-
                }
                for (nr = 0; nr < 4; nr++) {
                        data->in_max[nr] =
@@ -218,6 +215,8 @@ static struct f75375_data *f75375_update_device(struct device *dev)
        if (time_after(jiffies, data->last_updated + 2 * HZ)
                || !data->valid) {
                for (nr = 0; nr < 2; nr++) {
+                       data->pwm[nr] = f75375_read8(client,
+                               F75375_REG_FAN_PWM_DUTY(nr));
                        /* assign MSB, therefore shift it by 8 bits */
                        data->temp11[nr] =
                                f75375_read8(client, F75375_REG_TEMP(nr)) << 8;
@@ -369,7 +368,7 @@ static int set_pwm_enable_direct(struct i2c_client *client, int nr, int val)
                        fanmode  |= (3 << FAN_CTRL_MODE(nr));
                        break;
                case 2: /* AUTOMATIC*/
-                       fanmode  |= (2 << FAN_CTRL_MODE(nr));
+                       fanmode  |= (1 << FAN_CTRL_MODE(nr));
                        break;
                case 3: /* fan speed */
                        break;
@@ -723,7 +722,7 @@ static void f75375_init(struct i2c_client *client, struct f75375_data *data,
                        if (data->kind == f75387) {
                                bool manu, duty;
 
-                               if (!(conf & (1 << F75387_FAN_CTRL_LINEAR(nr))))
+                               if (!(mode & (1 << F75387_FAN_CTRL_LINEAR(nr))))
                                        data->pwm_mode[nr] = 1;
 
                                manu = ((mode >> F75387_FAN_MANU_MODE(nr)) & 1);
index 6ddeae0..91fdd1f 100644 (file)
@@ -883,7 +883,7 @@ static int sht15_invalidate_voltage(struct notifier_block *nb,
 
 static int __devinit sht15_probe(struct platform_device *pdev)
 {
-       int ret = 0;
+       int ret;
        struct sht15_data *data = kzalloc(sizeof(*data), GFP_KERNEL);
        u8 status = 0;
 
@@ -901,6 +901,7 @@ static int __devinit sht15_probe(struct platform_device *pdev)
        init_waitqueue_head(&data->wait_queue);
 
        if (pdev->dev.platform_data == NULL) {
+               ret = -EINVAL;
                dev_err(&pdev->dev, "no platform data supplied\n");
                goto err_free_data;
        }
index 0e0af04..5276d19 100644 (file)
@@ -1319,6 +1319,7 @@ store_pwm_mode(struct device *dev, struct device_attribute *attr,
 {
        struct w83627ehf_data *data = dev_get_drvdata(dev);
        struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+       struct w83627ehf_sio_data *sio_data = dev->platform_data;
        int nr = sensor_attr->index;
        unsigned long val;
        int err;
@@ -1330,6 +1331,11 @@ store_pwm_mode(struct device *dev, struct device_attribute *attr,
 
        if (val > 1)
                return -EINVAL;
+
+       /* On NCT67766F, DC mode is only supported for pwm1 */
+       if (sio_data->kind == nct6776 && nr && val != 1)
+               return -EINVAL;
+
        mutex_lock(&data->update_lock);
        reg = w83627ehf_read_value(data, W83627EHF_REG_PWM_ENABLE[nr]);
        data->pwm_mode[nr] = val;
@@ -1914,9 +1920,26 @@ w83627ehf_check_fan_inputs(const struct w83627ehf_sio_data *sio_data,
                fan4min = 0;
                fan5pin = 0;
        } else if (sio_data->kind == nct6776) {
-               fan3pin = !(superio_inb(sio_data->sioreg, 0x24) & 0x40);
-               fan4pin = !!(superio_inb(sio_data->sioreg, 0x1C) & 0x01);
-               fan5pin = !!(superio_inb(sio_data->sioreg, 0x1C) & 0x02);
+               bool gpok = superio_inb(sio_data->sioreg, 0x27) & 0x80;
+
+               superio_select(sio_data->sioreg, W83627EHF_LD_HWM);
+               regval = superio_inb(sio_data->sioreg, SIO_REG_ENABLE);
+
+               if (regval & 0x80)
+                       fan3pin = gpok;
+               else
+                       fan3pin = !(superio_inb(sio_data->sioreg, 0x24) & 0x40);
+
+               if (regval & 0x40)
+                       fan4pin = gpok;
+               else
+                       fan4pin = !!(superio_inb(sio_data->sioreg, 0x1C) & 0x01);
+
+               if (regval & 0x20)
+                       fan5pin = gpok;
+               else
+                       fan5pin = !!(superio_inb(sio_data->sioreg, 0x1C) & 0x02);
+
                fan4min = fan4pin;
        } else if (sio_data->kind == w83667hg || sio_data->kind == w83667hg_b) {
                fan3pin = 1;
@@ -2326,11 +2349,6 @@ static int __devinit w83627ehf_probe(struct platform_device *pdev)
        /* Read fan clock dividers immediately */
        w83627ehf_update_fan_div_common(dev, data);
 
-       /* Read pwm data to save original values */
-       w83627ehf_update_pwm_common(dev, data);
-       for (i = 0; i < data->pwm_num; i++)
-               data->pwm_enable_orig[i] = data->pwm_enable[i];
-
        /* Read pwm data to save original values */
        w83627ehf_update_pwm_common(dev, data);
        for (i = 0; i < data->pwm_num; i++)
index f713eac..801df60 100644 (file)
@@ -1018,7 +1018,7 @@ omap_i2c_probe(struct platform_device *pdev)
                goto err_release_region;
        }
 
-       match = of_match_device(omap_i2c_of_match, &pdev->dev);
+       match = of_match_device(of_match_ptr(omap_i2c_of_match), &pdev->dev);
        if (match) {
                u32 freq = 100000; /* default to 100000 Hz */
 
index b37b0c0..5034a87 100644 (file)
@@ -808,9 +808,12 @@ static ssize_t ucma_accept(struct ucma_file *file, const char __user *inbuf,
                return PTR_ERR(ctx);
 
        if (cmd.conn_param.valid) {
-               ctx->uid = cmd.uid;
                ucma_copy_conn_param(&conn_param, &cmd.conn_param);
+               mutex_lock(&file->mut);
                ret = rdma_accept(ctx->cm_id, &conn_param);
+               if (!ret)
+                       ctx->uid = cmd.uid;
+               mutex_unlock(&file->mut);
        } else
                ret = rdma_accept(ctx->cm_id, NULL);
 
index b930da4..4d27e4c 100644 (file)
@@ -1485,6 +1485,7 @@ ssize_t ib_uverbs_create_qp(struct ib_uverbs_file *file,
                qp->event_handler = attr.event_handler;
                qp->qp_context    = attr.qp_context;
                qp->qp_type       = attr.qp_type;
+               atomic_set(&qp->usecnt, 0);
                atomic_inc(&pd->usecnt);
                atomic_inc(&attr.send_cq->usecnt);
                if (attr.recv_cq)
index 602b1bd..575b780 100644 (file)
@@ -421,6 +421,7 @@ struct ib_qp *ib_create_qp(struct ib_pd *pd,
                qp->uobject    = NULL;
                qp->qp_type    = qp_init_attr->qp_type;
 
+               atomic_set(&qp->usecnt, 0);
                if (qp_init_attr->qp_type == IB_QPT_XRC_TGT) {
                        qp->event_handler = __ib_shared_qp_event_handler;
                        qp->qp_context = qp;
@@ -430,7 +431,6 @@ struct ib_qp *ib_create_qp(struct ib_pd *pd,
                        qp->xrcd = qp_init_attr->xrcd;
                        atomic_inc(&qp_init_attr->xrcd->usecnt);
                        INIT_LIST_HEAD(&qp->open_list);
-                       atomic_set(&qp->usecnt, 0);
 
                        real_qp = qp;
                        qp = __ib_open_qp(real_qp, qp_init_attr->event_handler,
index b7d4216..a4de9d5 100644 (file)
@@ -89,7 +89,7 @@ static int create_file(const char *name, umode_t mode,
                error = ipathfs_mknod(parent->d_inode, *dentry,
                                      mode, fops, data);
        else
-               error = PTR_ERR(dentry);
+               error = PTR_ERR(*dentry);
        mutex_unlock(&parent->d_inode->i_mutex);
 
        return error;
index 95c94d8..259b067 100644 (file)
@@ -257,12 +257,9 @@ static int ib_process_mad(struct ib_device *ibdev, int mad_flags, u8 port_num,
                        return IB_MAD_RESULT_SUCCESS;
 
                /*
-                * Don't process SMInfo queries or vendor-specific
-                * MADs -- the SMA can't handle them.
+                * Don't process SMInfo queries -- the SMA can't handle them.
                 */
-               if (in_mad->mad_hdr.attr_id == IB_SMP_ATTR_SM_INFO ||
-                   ((in_mad->mad_hdr.attr_id & IB_SMP_ATTR_VENDOR_MASK) ==
-                    IB_SMP_ATTR_VENDOR_MASK))
+               if (in_mad->mad_hdr.attr_id == IB_SMP_ATTR_SM_INFO)
                        return IB_MAD_RESULT_SUCCESS;
        } else if (in_mad->mad_hdr.mgmt_class == IB_MGMT_CLASS_PERF_MGMT ||
                   in_mad->mad_hdr.mgmt_class == MLX4_IB_VENDOR_CLASS1   ||
index 7013da5..7140199 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006 - 2009 Intel Corporation.  All rights reserved.
+ * Copyright (c) 2006 - 2011 Intel Corporation.  All rights reserved.
  * Copyright (c) 2005 Open Grid Computing, Inc. All rights reserved.
  *
  * This software is available to you under a choice of one of two
index 568b4f1..c438e46 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006 - 2009 Intel Corporation.  All rights reserved.
+ * Copyright (c) 2006 - 2011 Intel Corporation.  All rights reserved.
  * Copyright (c) 2005 Open Grid Computing, Inc. All rights reserved.
  *
  * This software is available to you under a choice of one of two
index 425065b..a4972ab 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006 - 2009 Intel Corporation.  All rights reserved.
+ * Copyright (c) 2006 - 2011 Intel Corporation.  All rights reserved.
  *
  * This software is available to you under a choice of one of two
  * licenses.  You may choose to be licensed under the terms of the GNU
@@ -233,6 +233,7 @@ static int send_mpa_reject(struct nes_cm_node *cm_node)
        u8 *start_ptr = &start_addr;
        u8 **start_buff = &start_ptr;
        u16 buff_len = 0;
+       struct ietf_mpa_v1 *mpa_frame;
 
        skb = dev_alloc_skb(MAX_CM_BUFFER);
        if (!skb) {
@@ -242,6 +243,8 @@ static int send_mpa_reject(struct nes_cm_node *cm_node)
 
        /* send an MPA reject frame */
        cm_build_mpa_frame(cm_node, start_buff, &buff_len, NULL, MPA_KEY_REPLY);
+       mpa_frame = (struct ietf_mpa_v1 *)*start_buff;
+       mpa_frame->flags |= IETF_MPA_FLAGS_REJECT;
        form_cm_frame(skb, cm_node, NULL, 0, *start_buff, buff_len, SET_ACK | SET_FIN);
 
        cm_node->state = NES_CM_STATE_FIN_WAIT1;
@@ -1360,8 +1363,7 @@ static int nes_addr_resolve_neigh(struct nes_vnic *nesvnic, u32 dst_ip, int arpi
                                if (!memcmp(nesadapter->arp_table[arpindex].mac_addr,
                                            neigh->ha, ETH_ALEN)) {
                                        /* Mac address same as in nes_arp_table */
-                                       ip_rt_put(rt);
-                                       return rc;
+                                       goto out;
                                }
 
                                nes_manage_arp_cache(nesvnic->netdev,
@@ -1377,6 +1379,8 @@ static int nes_addr_resolve_neigh(struct nes_vnic *nesvnic, u32 dst_ip, int arpi
                        neigh_event_send(neigh, NULL);
                }
        }
+
+out:
        rcu_read_unlock();
        ip_rt_put(rt);
        return rc;
index bdfa1fb..4646e66 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006 - 2009 Intel Corporation.  All rights reserved.
+ * Copyright (c) 2006 - 2011 Intel Corporation.  All rights reserved.
  *
  * This software is available to you under a choice of one of two
  * licenses.  You may choose to be licensed under the terms of the GNU
index b4393a1..a69eef1 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006 - 2009 Intel Corporation.  All rights reserved.
+ * Copyright (c) 2006 - 2011 Intel Corporation.  All rights reserved.
  *
  * This software is available to you under a choice of one of two
  * licenses.  You may choose to be licensed under the terms of the GNU
index 055f4b5..d42c9f4 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006 - 2009 Intel Corporation.  All rights reserved.
+ * Copyright (c) 2006 - 2011 Intel Corporation.  All rights reserved.
  *
  * This software is available to you under a choice of one of two
  * licenses.  You may choose to be licensed under the terms of the GNU
index 0b590e1..d748e4b 100644 (file)
@@ -1,5 +1,5 @@
 /*
-* Copyright (c) 2006 - 2009 Intel Corporation.  All rights reserved.
+* Copyright (c) 2006 - 2011 Intel Corporation.  All rights reserved.
 *
 * This software is available to you under a choice of one of two
 * licenses.  You may choose to be licensed under the terms of the GNU
index b3b2a24..3ba7be3 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006 - 2009 Intel-NE, Inc.  All rights reserved.
+ * Copyright (c) 2006 - 2011 Intel-NE, Inc.  All rights reserved.
  *
  * This software is available to you under a choice of one of two
  * licenses.  You may choose to be licensed under the terms of the GNU
index 8c8af25..4f7f701 100644 (file)
@@ -1,5 +1,5 @@
 /*
-* Copyright (c) 2010 Intel-NE, Inc.  All rights reserved.
+* Copyright (c) 2006 - 2011 Intel-NE, Inc.  All rights reserved.
 *
 * This software is available to you under a choice of one of two
 * licenses.  You may choose to be licensed under the terms of the GNU
index 4b3fa71..f3a3ecf 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006 - 2009 Intel Corporation.  All rights reserved.
+ * Copyright (c) 2006 - 2011 Intel Corporation.  All rights reserved.
  *
  * This software is available to you under a choice of one of two
  * licenses.  You may choose to be licensed under the terms of the GNU
index 71e133a..4926de7 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006 - 2009 Intel Corporation.  All rights reserved.
+ * Copyright (c) 2006 - 2011 Intel Corporation.  All rights reserved.
  * Copyright (c) 2005 Topspin Communications.  All rights reserved.
  * Copyright (c) 2005 Cisco Systems.  All rights reserved.
  * Copyright (c) 2005 Open Grid Computing, Inc. All rights reserved.
index 8b4c2ff..e98f4fc 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006 - 2009 Intel Corporation.  All rights reserved.
+ * Copyright (c) 2006 - 2011 Intel Corporation.  All rights reserved.
  *
  * This software is available to you under a choice of one of two
  * licenses.  You may choose to be licensed under the terms of the GNU
index 5095bc4..0927b5c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006 - 2009 Intel Corporation.  All rights reserved.
+ * Copyright (c) 2006 - 2011 Intel Corporation.  All rights reserved.
  *
  * This software is available to you under a choice of one of two
  * licenses.  You may choose to be licensed under the terms of the GNU
@@ -3427,6 +3427,8 @@ static int nes_post_send(struct ib_qp *ibqp, struct ib_send_wr *ib_wr,
                        set_wqe_32bit_value(wqe->wqe_words,
                                            NES_IWARP_SQ_FMR_WQE_LENGTH_LOW_IDX,
                                            ib_wr->wr.fast_reg.length);
+                       set_wqe_32bit_value(wqe->wqe_words,
+                                           NES_IWARP_SQ_FMR_WQE_LENGTH_HIGH_IDX, 0);
                        set_wqe_32bit_value(wqe->wqe_words,
                                            NES_IWARP_SQ_FMR_WQE_MR_STAG_IDX,
                                            ib_wr->wr.fast_reg.rkey);
@@ -3724,7 +3726,7 @@ static int nes_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *entry)
                                                entry->opcode = IB_WC_SEND;
                                                break;
                                        case NES_IWARP_SQ_OP_LOCINV:
-                                               entry->opcode = IB_WR_LOCAL_INV;
+                                               entry->opcode = IB_WC_LOCAL_INV;
                                                break;
                                        case NES_IWARP_SQ_OP_FAST_REG:
                                                entry->opcode = IB_WC_FAST_REG_MR;
index fe6b6e9..0eff7c4 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006 - 2009 Intel Corporation.  All rights reserved.
+ * Copyright (c) 2006 - 2011 Intel Corporation.  All rights reserved.
  * Copyright (c) 2005 Open Grid Computing, Inc. All rights reserved.
  *
  * This software is available to you under a choice of one of two
index 4f18e2d..d0c64d5 100644 (file)
@@ -2105,7 +2105,7 @@ static void alloc_dummy_hdrq(struct qib_devdata *dd)
        dd->cspec->dummy_hdrq = dma_alloc_coherent(&dd->pcidev->dev,
                                        dd->rcd[0]->rcvhdrq_size,
                                        &dd->cspec->dummy_hdrq_phys,
-                                       GFP_KERNEL | __GFP_COMP);
+                                       GFP_ATOMIC | __GFP_COMP);
        if (!dd->cspec->dummy_hdrq) {
                qib_devinfo(dd->pcidev, "Couldn't allocate dummy hdrq\n");
                /* fallback to just 0'ing */
index f695061..0fde788 100644 (file)
@@ -560,7 +560,7 @@ static int qib_tune_pcie_coalesce(struct qib_devdata *dd)
  * BIOS may not set PCIe bus-utilization parameters for best performance.
  * Check and optionally adjust them to maximize our throughput.
  */
-static int qib_pcie_caps = 0x51;
+static int qib_pcie_caps;
 module_param_named(pcie_caps, qib_pcie_caps, int, S_IRUGO);
 MODULE_PARM_DESC(pcie_caps, "Max PCIe tuning: Payload (0..3), ReadReq (4..7)");
 
index b3cc1e0..86df632 100644 (file)
@@ -44,6 +44,7 @@
 #include <linux/mutex.h>
 
 #include <net/neighbour.h>
+#include <net/sch_generic.h>
 
 #include <linux/atomic.h>
 
@@ -117,8 +118,9 @@ struct ipoib_header {
        u16     reserved;
 };
 
-struct ipoib_pseudoheader {
-       u8  hwaddr[INFINIBAND_ALEN];
+struct ipoib_cb {
+       struct qdisc_skb_cb     qdisc_cb;
+       u8                      hwaddr[INFINIBAND_ALEN];
 };
 
 /* Used for all multicast joins (broadcast, IPv4 mcast and IPv6 mcast) */
index 3514ca0..3974c29 100644 (file)
@@ -653,7 +653,7 @@ static void ipoib_path_lookup(struct sk_buff *skb, struct neighbour *n, struct n
 }
 
 static void unicast_arp_send(struct sk_buff *skb, struct net_device *dev,
-                            struct ipoib_pseudoheader *phdr)
+                            struct ipoib_cb *cb)
 {
        struct ipoib_dev_priv *priv = netdev_priv(dev);
        struct ipoib_path *path;
@@ -661,17 +661,15 @@ static void unicast_arp_send(struct sk_buff *skb, struct net_device *dev,
 
        spin_lock_irqsave(&priv->lock, flags);
 
-       path = __path_find(dev, phdr->hwaddr + 4);
+       path = __path_find(dev, cb->hwaddr + 4);
        if (!path || !path->valid) {
                int new_path = 0;
 
                if (!path) {
-                       path = path_rec_create(dev, phdr->hwaddr + 4);
+                       path = path_rec_create(dev, cb->hwaddr + 4);
                        new_path = 1;
                }
                if (path) {
-                       /* put pseudoheader back on for next time */
-                       skb_push(skb, sizeof *phdr);
                        __skb_queue_tail(&path->queue, skb);
 
                        if (!path->query && path_rec_start(dev, path)) {
@@ -695,12 +693,10 @@ static void unicast_arp_send(struct sk_buff *skb, struct net_device *dev,
                          be16_to_cpu(path->pathrec.dlid));
 
                spin_unlock_irqrestore(&priv->lock, flags);
-               ipoib_send(dev, skb, path->ah, IPOIB_QPN(phdr->hwaddr));
+               ipoib_send(dev, skb, path->ah, IPOIB_QPN(cb->hwaddr));
                return;
        } else if ((path->query || !path_rec_start(dev, path)) &&
                   skb_queue_len(&path->queue) < IPOIB_MAX_PATH_REC_QUEUE) {
-               /* put pseudoheader back on for next time */
-               skb_push(skb, sizeof *phdr);
                __skb_queue_tail(&path->queue, skb);
        } else {
                ++dev->stats.tx_dropped;
@@ -774,16 +770,14 @@ static int ipoib_start_xmit(struct sk_buff *skb, struct net_device *dev)
                        dev_kfree_skb_any(skb);
                }
        } else {
-               struct ipoib_pseudoheader *phdr =
-                       (struct ipoib_pseudoheader *) skb->data;
-               skb_pull(skb, sizeof *phdr);
+               struct ipoib_cb *cb = (struct ipoib_cb *) skb->cb;
 
-               if (phdr->hwaddr[4] == 0xff) {
+               if (cb->hwaddr[4] == 0xff) {
                        /* Add in the P_Key for multicast*/
-                       phdr->hwaddr[8] = (priv->pkey >> 8) & 0xff;
-                       phdr->hwaddr[9] = priv->pkey & 0xff;
+                       cb->hwaddr[8] = (priv->pkey >> 8) & 0xff;
+                       cb->hwaddr[9] = priv->pkey & 0xff;
 
-                       ipoib_mcast_send(dev, phdr->hwaddr + 4, skb);
+                       ipoib_mcast_send(dev, cb->hwaddr + 4, skb);
                } else {
                        /* unicast GID -- should be ARP or RARP reply */
 
@@ -792,14 +786,14 @@ static int ipoib_start_xmit(struct sk_buff *skb, struct net_device *dev)
                                ipoib_warn(priv, "Unicast, no %s: type %04x, QPN %06x %pI6\n",
                                           skb_dst(skb) ? "neigh" : "dst",
                                           be16_to_cpup((__be16 *) skb->data),
-                                          IPOIB_QPN(phdr->hwaddr),
-                                          phdr->hwaddr + 4);
+                                          IPOIB_QPN(cb->hwaddr),
+                                          cb->hwaddr + 4);
                                dev_kfree_skb_any(skb);
                                ++dev->stats.tx_dropped;
                                goto unlock;
                        }
 
-                       unicast_arp_send(skb, dev, phdr);
+                       unicast_arp_send(skb, dev, cb);
                }
        }
 unlock:
@@ -825,8 +819,6 @@ static int ipoib_hard_header(struct sk_buff *skb,
                             const void *daddr, const void *saddr, unsigned len)
 {
        struct ipoib_header *header;
-       struct dst_entry *dst;
-       struct neighbour *n;
 
        header = (struct ipoib_header *) skb_push(skb, sizeof *header);
 
@@ -834,18 +826,13 @@ static int ipoib_hard_header(struct sk_buff *skb,
        header->reserved = 0;
 
        /*
-        * If we don't have a neighbour structure, stuff the
-        * destination address onto the front of the skb so we can
-        * figure out where to send the packet later.
+        * If we don't have a dst_entry structure, stuff the
+        * destination address into skb->cb so we can figure out where
+        * to send the packet later.
         */
-       dst = skb_dst(skb);
-       n = NULL;
-       if (dst)
-               n = dst_get_neighbour_noref_raw(dst);
-       if ((!dst || !n) && daddr) {
-               struct ipoib_pseudoheader *phdr =
-                       (struct ipoib_pseudoheader *) skb_push(skb, sizeof *phdr);
-               memcpy(phdr->hwaddr, daddr, INFINIBAND_ALEN);
+       if (!skb_dst(skb)) {
+               struct ipoib_cb *cb = (struct ipoib_cb *) skb->cb;
+               memcpy(cb->hwaddr, daddr, INFINIBAND_ALEN);
        }
 
        return 0;
@@ -1021,11 +1008,7 @@ static void ipoib_setup(struct net_device *dev)
 
        dev->flags              |= IFF_BROADCAST | IFF_MULTICAST;
 
-       /*
-        * We add in INFINIBAND_ALEN to allow for the destination
-        * address "pseudoheader" for skbs without neighbour struct.
-        */
-       dev->hard_header_len     = IPOIB_ENCAP_LEN + INFINIBAND_ALEN;
+       dev->hard_header_len     = IPOIB_ENCAP_LEN;
        dev->addr_len            = INFINIBAND_ALEN;
        dev->type                = ARPHRD_INFINIBAND;
        dev->tx_queue_len        = ipoib_sendq_size * 2;
index f7ff9dd..20ebc6f 100644 (file)
@@ -262,21 +262,13 @@ static int ipoib_mcast_join_finish(struct ipoib_mcast *mcast,
        netif_tx_lock_bh(dev);
        while (!skb_queue_empty(&mcast->pkt_queue)) {
                struct sk_buff *skb = skb_dequeue(&mcast->pkt_queue);
-               struct dst_entry *dst = skb_dst(skb);
-               struct neighbour *n = NULL;
 
                netif_tx_unlock_bh(dev);
 
                skb->dev = dev;
-               if (dst)
-                       n = dst_get_neighbour_noref_raw(dst);
-               if (!dst || !n) {
-                       /* put pseudoheader back on for next time */
-                       skb_push(skb, sizeof (struct ipoib_pseudoheader));
-               }
-
                if (dev_queue_xmit(skb))
                        ipoib_warn(priv, "dev_queue_xmit failed to requeue packet\n");
+
                netif_tx_lock_bh(dev);
        }
        netif_tx_unlock_bh(dev);
index cd5d05e..2b73d43 100644 (file)
@@ -69,8 +69,8 @@ MODULE_LICENSE("Dual BSD/GPL");
  */
 
 static u64 srpt_service_guid;
-static spinlock_t srpt_dev_lock;       /* Protects srpt_dev_list. */
-static struct list_head srpt_dev_list; /* List of srpt_device structures. */
+static DEFINE_SPINLOCK(srpt_dev_lock); /* Protects srpt_dev_list. */
+static LIST_HEAD(srpt_dev_list);       /* List of srpt_device structures. */
 
 static unsigned srp_max_req_size = DEFAULT_MAX_REQ_SIZE;
 module_param(srp_max_req_size, int, 0444);
@@ -687,6 +687,7 @@ err:
        while (--i >= 0)
                srpt_free_ioctx(sdev, ring[i], dma_size, dir);
        kfree(ring);
+       ring = NULL;
 out:
        return ring;
 }
@@ -2595,7 +2596,7 @@ static int srpt_cm_req_recv(struct ib_cm_id *cm_id,
        }
 
        ch->sess = transport_init_session();
-       if (!ch->sess) {
+       if (IS_ERR(ch->sess)) {
                rej->reason = __constant_cpu_to_be32(
                                SRP_LOGIN_REJ_INSUFFICIENT_RESOURCES);
                pr_debug("Failed to create session\n");
@@ -3264,8 +3265,7 @@ static void srpt_add_one(struct ib_device *device)
        for (i = 0; i < sdev->srq_size; ++i)
                srpt_post_recv(sdev, sdev->ioctx_ring[i]);
 
-       WARN_ON(sdev->device->phys_port_cnt
-               > sizeof(sdev->port)/sizeof(sdev->port[0]));
+       WARN_ON(sdev->device->phys_port_cnt > ARRAY_SIZE(sdev->port));
 
        for (i = 1; i <= sdev->device->phys_port_cnt; i++) {
                sport = &sdev->port[i - 1];
@@ -4010,13 +4010,10 @@ static int __init srpt_init_module(void)
                goto out;
        }
 
-       spin_lock_init(&srpt_dev_lock);
-       INIT_LIST_HEAD(&srpt_dev_list);
-
-       ret = -ENODEV;
        srpt_target = target_fabric_configfs_init(THIS_MODULE, "srpt");
-       if (!srpt_target) {
+       if (IS_ERR(srpt_target)) {
                printk(KERN_ERR "couldn't register\n");
+               ret = PTR_ERR(srpt_target);
                goto out;
        }
 
index b4b4bbc..61e52b8 100644 (file)
@@ -35,7 +35,6 @@
 #ifndef IB_SRPT_H
 #define IB_SRPT_H
 
-#include <linux/version.h>
 #include <linux/types.h>
 #include <linux/list.h>
 #include <linux/wait.h>
index 76457d5..afc166f 100644 (file)
@@ -386,7 +386,7 @@ static ssize_t evdev_read(struct file *file, char __user *buffer,
        struct evdev_client *client = file->private_data;
        struct evdev *evdev = client->evdev;
        struct input_event event;
-       int retval;
+       int retval = 0;
 
        if (count < input_event_size())
                return -EINVAL;
index a588578..67bec14 100644 (file)
@@ -34,7 +34,6 @@
 #include <linux/i2c/twl.h>
 #include <linux/slab.h>
 
-
 /*
  * The TWL4030 family chips include a keypad controller that supports
  * up to an 8x8 switch matrix.  The controller can issue system wakeup
@@ -302,7 +301,7 @@ static int __devinit twl4030_kp_program(struct twl4030_keypad *kp)
        if (twl4030_kpwrite_u8(kp, i, KEYP_DEB) < 0)
                return -EIO;
 
-       /* Set timeout period to 100 ms */
+       /* Set timeout period to 200 ms */
        i = KEYP_PERIOD_US(200000, PTV_PRESCALER);
        if (twl4030_kpwrite_u8(kp, (i & 0xFF), KEYP_TIMEOUT_L) < 0)
                return -EIO;
@@ -466,4 +465,3 @@ MODULE_AUTHOR("Texas Instruments");
 MODULE_DESCRIPTION("TWL4030 Keypad Driver");
 MODULE_LICENSE("GPL");
 MODULE_ALIAS("platform:twl4030_keypad");
-
index b4cfc6c..5ec774d 100644 (file)
@@ -512,6 +512,13 @@ static const struct dmi_system_id __initconst i8042_dmi_reset_table[] = {
                        DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 1720"),
                },
        },
+       {
+               /* Lenovo Ideapad U455 */
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "20046"),
+               },
+       },
        { }
 };
 
index 8250299..4494233 100644 (file)
@@ -164,7 +164,8 @@ static ssize_t serio_raw_read(struct file *file, char __user *buffer,
        struct serio_raw_client *client = file->private_data;
        struct serio_raw *serio_raw = client->serio_raw;
        char uninitialized_var(c);
-       ssize_t retval = 0;
+       ssize_t read = 0;
+       int retval;
 
        if (serio_raw->dead)
                return -ENODEV;
@@ -180,13 +181,15 @@ static ssize_t serio_raw_read(struct file *file, char __user *buffer,
        if (serio_raw->dead)
                return -ENODEV;
 
-       while (retval < count && serio_raw_fetch_byte(serio_raw, &c)) {
-               if (put_user(c, buffer++))
-                       return -EFAULT;
-               retval++;
+       while (read < count && serio_raw_fetch_byte(serio_raw, &c)) {
+               if (put_user(c, buffer++)) {
+                       retval = -EFAULT;
+                       break;
+               }
+               read++;
        }
 
-       return retval;
+       return read ?: retval;
 }
 
 static ssize_t serio_raw_write(struct file *file, const char __user *buffer,
index cce1f03..f75e060 100644 (file)
@@ -2863,6 +2863,9 @@ static unsigned device_dma_ops_init(void)
 
        for_each_pci_dev(pdev) {
                if (!check_device(&pdev->dev)) {
+
+                       iommu_ignore_device(&pdev->dev);
+
                        unhandled += 1;
                        continue;
                }
index 08a90b8..cee307e 100644 (file)
@@ -482,23 +482,19 @@ static size_t msm_iommu_unmap(struct iommu_domain *domain, unsigned long va,
 
        priv = domain->priv;
 
-       if (!priv) {
-               ret = -ENODEV;
+       if (!priv)
                goto fail;
-       }
 
        fl_table = priv->pgtable;
 
        if (len != SZ_16M && len != SZ_1M &&
            len != SZ_64K && len != SZ_4K) {
                pr_debug("Bad length: %d\n", len);
-               ret = -EINVAL;
                goto fail;
        }
 
        if (!fl_table) {
                pr_debug("Null page table\n");
-               ret = -EINVAL;
                goto fail;
        }
 
@@ -507,7 +503,6 @@ static size_t msm_iommu_unmap(struct iommu_domain *domain, unsigned long va,
 
        if (*fl_pte == 0) {
                pr_debug("First level PTE is 0\n");
-               ret = -ENODEV;
                goto fail;
        }
 
index 2339d73..802ab87 100644 (file)
@@ -1901,7 +1901,7 @@ static int isdn_net_header(struct sk_buff *skb, struct net_device *dev,
 {
        isdn_net_local *lp = netdev_priv(dev);
        unsigned char *p;
-       ushort len = 0;
+       int len = 0;
 
        switch (lp->p_encap) {
                case ISDN_NET_ENCAP_ETHER:
index 45e6878..e59c166 100644 (file)
@@ -164,8 +164,8 @@ static int lm3530_init_registers(struct lm3530_data *drvdata)
 
        if (drvdata->mode == LM3530_BL_MODE_ALS) {
                if (pltfm->als_vmax == 0) {
-                       pltfm->als_vmin = als_vmin = 0;
-                       pltfm->als_vmin = als_vmax = LM3530_ALS_WINDOW_mV;
+                       pltfm->als_vmin = 0;
+                       pltfm->als_vmax = LM3530_ALS_WINDOW_mV;
                }
 
                als_vmin = pltfm->als_vmin;
index c2907d8..86cb7e5 100644 (file)
@@ -56,7 +56,8 @@ struct raid_dev {
 struct raid_set {
        struct dm_target *ti;
 
-       uint64_t print_flags;
+       uint32_t bitmap_loaded;
+       uint32_t print_flags;
 
        struct mddev md;
        struct raid_type *raid_type;
@@ -1085,7 +1086,7 @@ static int raid_status(struct dm_target *ti, status_type_t type,
                                raid_param_cnt += 2;
                }
 
-               raid_param_cnt += (hweight64(rs->print_flags & ~DMPF_REBUILD) * 2);
+               raid_param_cnt += (hweight32(rs->print_flags & ~DMPF_REBUILD) * 2);
                if (rs->print_flags & (DMPF_SYNC | DMPF_NOSYNC))
                        raid_param_cnt--;
 
@@ -1197,7 +1198,12 @@ static void raid_resume(struct dm_target *ti)
 {
        struct raid_set *rs = ti->private;
 
-       bitmap_load(&rs->md);
+       if (!rs->bitmap_loaded) {
+               bitmap_load(&rs->md);
+               rs->bitmap_loaded = 1;
+       } else
+               md_wakeup_thread(rs->md.thread);
+
        mddev_resume(&rs->md);
 }
 
index 9417ae2..ce88755 100644 (file)
@@ -7333,7 +7333,8 @@ void md_do_sync(struct mddev *mddev)
                                        printk(KERN_INFO
                                               "md: checkpointing %s of %s.\n",
                                               desc, mdname(mddev));
-                                       mddev->recovery_cp = mddev->curr_resync;
+                                       mddev->recovery_cp =
+                                               mddev->curr_resync_completed;
                                }
                        } else
                                mddev->recovery_cp = MaxSector;
@@ -7351,9 +7352,9 @@ void md_do_sync(struct mddev *mddev)
                        rcu_read_unlock();
                }
        }
+ skip:
        set_bit(MD_CHANGE_DEVS, &mddev->flags);
 
- skip:
        if (!test_bit(MD_RECOVERY_INTR, &mddev->recovery)) {
                /* We completed so min/max setting can be forgotten if used. */
                if (test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery))
index cd13e9f..f147395 100644 (file)
@@ -200,7 +200,7 @@ config MENELAUS
 
 config TWL4030_CORE
        bool "Texas Instruments TWL4030/TWL5030/TWL6030/TPS659x0 Support"
-       depends on I2C=y && GENERIC_HARDIRQS && IRQ_DOMAIN
+       depends on I2C=y && GENERIC_HARDIRQS
        help
          Say yes here if you have TWL4030 / TWL6030 family chip on your board.
          This core driver provides register access and IRQ handling
index 63be60b..86cc3f7 100644 (file)
 #define to_mcp(d)              container_of(d, struct mcp, attached_device)
 #define to_mcp_driver(d)       container_of(d, struct mcp_driver, drv)
 
-static const struct mcp_device_id *mcp_match_id(const struct mcp_device_id *id,
-                                               const char *codec)
-{
-       while (id->name[0]) {
-               if (strcmp(codec, id->name) == 0)
-                       return id;
-               id++;
-       }
-       return NULL;
-}
-
-const struct mcp_device_id *mcp_get_device_id(const struct mcp *mcp)
-{
-       const struct mcp_driver *driver =
-               to_mcp_driver(mcp->attached_device.driver);
-
-       return mcp_match_id(driver->id_table, mcp->codec);
-}
-EXPORT_SYMBOL(mcp_get_device_id);
-
 static int mcp_bus_match(struct device *dev, struct device_driver *drv)
 {
-       const struct mcp *mcp = to_mcp(dev);
-       const struct mcp_driver *driver = to_mcp_driver(drv);
-
-       if (driver->id_table)
-               return !!mcp_match_id(driver->id_table, mcp->codec);
-
-       return 0;
+       return 1;
 }
 
 static int mcp_bus_probe(struct device *dev)
@@ -100,18 +74,9 @@ static int mcp_bus_resume(struct device *dev)
        return ret;
 }
 
-static int mcp_bus_uevent(struct device *dev, struct kobj_uevent_env *env)
-{
-       struct mcp *mcp = to_mcp(dev);
-
-       add_uevent_var(env, "MODALIAS=%s%s", MCP_MODULE_PREFIX, mcp->codec);
-       return 0;
-}
-
 static struct bus_type mcp_bus_type = {
        .name           = "mcp",
        .match          = mcp_bus_match,
-       .uevent         = mcp_bus_uevent,
        .probe          = mcp_bus_probe,
        .remove         = mcp_bus_remove,
        .suspend        = mcp_bus_suspend,
@@ -128,9 +93,11 @@ static struct bus_type mcp_bus_type = {
  */
 void mcp_set_telecom_divisor(struct mcp *mcp, unsigned int div)
 {
-       spin_lock_irq(&mcp->lock);
+       unsigned long flags;
+
+       spin_lock_irqsave(&mcp->lock, flags);
        mcp->ops->set_telecom_divisor(mcp, div);
-       spin_unlock_irq(&mcp->lock);
+       spin_unlock_irqrestore(&mcp->lock, flags);
 }
 EXPORT_SYMBOL(mcp_set_telecom_divisor);
 
@@ -143,9 +110,11 @@ EXPORT_SYMBOL(mcp_set_telecom_divisor);
  */
 void mcp_set_audio_divisor(struct mcp *mcp, unsigned int div)
 {
-       spin_lock_irq(&mcp->lock);
+       unsigned long flags;
+
+       spin_lock_irqsave(&mcp->lock, flags);
        mcp->ops->set_audio_divisor(mcp, div);
-       spin_unlock_irq(&mcp->lock);
+       spin_unlock_irqrestore(&mcp->lock, flags);
 }
 EXPORT_SYMBOL(mcp_set_audio_divisor);
 
@@ -198,10 +167,11 @@ EXPORT_SYMBOL(mcp_reg_read);
  */
 void mcp_enable(struct mcp *mcp)
 {
-       spin_lock_irq(&mcp->lock);
+       unsigned long flags;
+       spin_lock_irqsave(&mcp->lock, flags);
        if (mcp->use_count++ == 0)
                mcp->ops->enable(mcp);
-       spin_unlock_irq(&mcp->lock);
+       spin_unlock_irqrestore(&mcp->lock, flags);
 }
 EXPORT_SYMBOL(mcp_enable);
 
@@ -247,14 +217,9 @@ struct mcp *mcp_host_alloc(struct device *parent, size_t size)
 }
 EXPORT_SYMBOL(mcp_host_alloc);
 
-int mcp_host_register(struct mcp *mcp, void *pdata)
+int mcp_host_register(struct mcp *mcp)
 {
-       if (!mcp->codec)
-               return -EINVAL;
-
-       mcp->attached_device.platform_data = pdata;
        dev_set_name(&mcp->attached_device, "mcp0");
-       request_module("%s%s", MCP_MODULE_PREFIX, mcp->codec);
        return device_register(&mcp->attached_device);
 }
 EXPORT_SYMBOL(mcp_host_register);
index 9adc2eb..02c53a0 100644 (file)
@@ -19,7 +19,6 @@
 #include <linux/spinlock.h>
 #include <linux/platform_device.h>
 #include <linux/mfd/mcp.h>
-#include <linux/io.h>
 
 #include <mach/dma.h>
 #include <mach/hardware.h>
 #include <asm/system.h>
 #include <mach/mcp.h>
 
-/* Register offsets */
-#define MCCR0  0x00
-#define MCDR0  0x08
-#define MCDR1  0x0C
-#define MCDR2  0x10
-#define MCSR   0x18
-#define MCCR1  0x00
+#include <mach/assabet.h>
+
 
 struct mcp_sa11x0 {
-       u32             mccr0;
-       u32             mccr1;
-       unsigned char   *mccr0_base;
-       unsigned char   *mccr1_base;
+       u32     mccr0;
+       u32     mccr1;
 };
 
 #define priv(mcp)      ((struct mcp_sa11x0 *)mcp_priv(mcp))
@@ -47,25 +39,25 @@ struct mcp_sa11x0 {
 static void
 mcp_sa11x0_set_telecom_divisor(struct mcp *mcp, unsigned int divisor)
 {
-       struct mcp_sa11x0 *priv = priv(mcp);
+       unsigned int mccr0;
 
        divisor /= 32;
 
-       priv->mccr0 &= ~0x00007f00;
-       priv->mccr0 |= divisor << 8;
-       __raw_writel(priv->mccr0, priv->mccr0_base + MCCR0);
+       mccr0 = Ser4MCCR0 & ~0x00007f00;
+       mccr0 |= divisor << 8;
+       Ser4MCCR0 = mccr0;
 }
 
 static void
 mcp_sa11x0_set_audio_divisor(struct mcp *mcp, unsigned int divisor)
 {
-       struct mcp_sa11x0 *priv = priv(mcp);
+       unsigned int mccr0;
 
        divisor /= 32;
 
-       priv->mccr0 &= ~0x0000007f;
-       priv->mccr0 |= divisor;
-       __raw_writel(priv->mccr0, priv->mccr0_base + MCCR0);
+       mccr0 = Ser4MCCR0 & ~0x0000007f;
+       mccr0 |= divisor;
+       Ser4MCCR0 = mccr0;
 }
 
 /*
@@ -79,16 +71,12 @@ mcp_sa11x0_write(struct mcp *mcp, unsigned int reg, unsigned int val)
 {
        int ret = -ETIME;
        int i;
-       u32 mcpreg;
-       struct mcp_sa11x0 *priv = priv(mcp);
 
-       mcpreg = reg << 17 | MCDR2_Wr | (val & 0xffff);
-       __raw_writel(mcpreg, priv->mccr0_base + MCDR2);
+       Ser4MCDR2 = reg << 17 | MCDR2_Wr | (val & 0xffff);
 
        for (i = 0; i < 2; i++) {
                udelay(mcp->rw_timeout);
-               mcpreg = __raw_readl(priv->mccr0_base + MCSR);
-               if (mcpreg & MCSR_CWC) {
+               if (Ser4MCSR & MCSR_CWC) {
                        ret = 0;
                        break;
                }
@@ -109,18 +97,13 @@ mcp_sa11x0_read(struct mcp *mcp, unsigned int reg)
 {
        int ret = -ETIME;
        int i;
-       u32 mcpreg;
-       struct mcp_sa11x0 *priv = priv(mcp);
 
-       mcpreg = reg << 17 | MCDR2_Rd;
-       __raw_writel(mcpreg, priv->mccr0_base + MCDR2);
+       Ser4MCDR2 = reg << 17 | MCDR2_Rd;
 
        for (i = 0; i < 2; i++) {
                udelay(mcp->rw_timeout);
-               mcpreg = __raw_readl(priv->mccr0_base + MCSR);
-               if (mcpreg & MCSR_CRC) {
-                       ret = __raw_readl(priv->mccr0_base + MCDR2)
-                               & 0xffff;
+               if (Ser4MCSR & MCSR_CRC) {
+                       ret = Ser4MCDR2 & 0xffff;
                        break;
                }
        }
@@ -133,19 +116,13 @@ mcp_sa11x0_read(struct mcp *mcp, unsigned int reg)
 
 static void mcp_sa11x0_enable(struct mcp *mcp)
 {
-       struct mcp_sa11x0 *priv = priv(mcp);
-
-       __raw_writel(-1, priv->mccr0_base + MCSR);
-       priv->mccr0 |= MCCR0_MCE;
-       __raw_writel(priv->mccr0, priv->mccr0_base + MCCR0);
+       Ser4MCSR = -1;
+       Ser4MCCR0 |= MCCR0_MCE;
 }
 
 static void mcp_sa11x0_disable(struct mcp *mcp)
 {
-       struct mcp_sa11x0 *priv = priv(mcp);
-
-       priv->mccr0 &= ~MCCR0_MCE;
-       __raw_writel(priv->mccr0, priv->mccr0_base + MCCR0);
+       Ser4MCCR0 &= ~MCCR0_MCE;
 }
 
 /*
@@ -165,69 +142,50 @@ static int mcp_sa11x0_probe(struct platform_device *pdev)
        struct mcp_plat_data *data = pdev->dev.platform_data;
        struct mcp *mcp;
        int ret;
-       struct mcp_sa11x0 *priv;
-       struct resource *res_mem0, *res_mem1;
-       u32 size0, size1;
 
        if (!data)
                return -ENODEV;
 
-       if (!data->codec)
-               return -ENODEV;
-
-       res_mem0 = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       if (!res_mem0)
-               return -ENODEV;
-       size0 = res_mem0->end - res_mem0->start + 1;
-
-       res_mem1 = platform_get_resource(pdev, IORESOURCE_MEM, 1);
-       if (!res_mem1)
-               return -ENODEV;
-       size1 = res_mem1->end - res_mem1->start + 1;
-
-       if (!request_mem_region(res_mem0->start, size0, "sa11x0-mcp"))
+       if (!request_mem_region(0x80060000, 0x60, "sa11x0-mcp"))
                return -EBUSY;
 
-       if (!request_mem_region(res_mem1->start, size1, "sa11x0-mcp")) {
-               ret = -EBUSY;
-               goto release;
-       }
-
        mcp = mcp_host_alloc(&pdev->dev, sizeof(struct mcp_sa11x0));
        if (!mcp) {
                ret = -ENOMEM;
-               goto release2;
+               goto release;
        }
 
-       priv = priv(mcp);
-
        mcp->owner              = THIS_MODULE;
        mcp->ops                = &mcp_sa11x0;
        mcp->sclk_rate          = data->sclk_rate;
-       mcp->dma_audio_rd       = DDAR_DevAdd(res_mem0->start + MCDR0)
-                               + DDAR_DevRd + DDAR_Brst4 + DDAR_8BitDev;
-       mcp->dma_audio_wr       = DDAR_DevAdd(res_mem0->start + MCDR0)
-                               + DDAR_DevWr + DDAR_Brst4 + DDAR_8BitDev;
-       mcp->dma_telco_rd       = DDAR_DevAdd(res_mem0->start + MCDR1)
-                               + DDAR_DevRd + DDAR_Brst4 + DDAR_8BitDev;
-       mcp->dma_telco_wr       = DDAR_DevAdd(res_mem0->start + MCDR1)
-                               + DDAR_DevWr + DDAR_Brst4 + DDAR_8BitDev;
-       mcp->codec              = data->codec;
+       mcp->dma_audio_rd       = DMA_Ser4MCP0Rd;
+       mcp->dma_audio_wr       = DMA_Ser4MCP0Wr;
+       mcp->dma_telco_rd       = DMA_Ser4MCP1Rd;
+       mcp->dma_telco_wr       = DMA_Ser4MCP1Wr;
+       mcp->gpio_base          = data->gpio_base;
 
        platform_set_drvdata(pdev, mcp);
 
+       if (machine_is_assabet()) {
+               ASSABET_BCR_set(ASSABET_BCR_CODEC_RST);
+       }
+
+       /*
+        * Setup the PPC unit correctly.
+        */
+       PPDR &= ~PPC_RXD4;
+       PPDR |= PPC_TXD4 | PPC_SCLK | PPC_SFRM;
+       PSDR |= PPC_RXD4;
+       PSDR &= ~(PPC_TXD4 | PPC_SCLK | PPC_SFRM);
+       PPSR &= ~(PPC_TXD4 | PPC_SCLK | PPC_SFRM);
+
        /*
         * Initialise device.  Note that we initially
         * set the sampling rate to minimum.
         */
-       priv->mccr0_base = ioremap(res_mem0->start, size0);
-       priv->mccr1_base = ioremap(res_mem1->start, size1);
-
-       __raw_writel(-1, priv->mccr0_base + MCSR);
-       priv->mccr1 = data->mccr1;
-       priv->mccr0 = data->mccr0 | 0x7f7f;
-       __raw_writel(priv->mccr0, priv->mccr0_base + MCCR0);
-       __raw_writel(priv->mccr1, priv->mccr1_base + MCCR1);
+       Ser4MCSR = -1;
+       Ser4MCCR1 = data->mccr1;
+       Ser4MCCR0 = data->mccr0 | 0x7f7f;
 
        /*
         * Calculate the read/write timeout (us) from the bit clock
@@ -237,53 +195,36 @@ static int mcp_sa11x0_probe(struct platform_device *pdev)
        mcp->rw_timeout = (64 * 3 * 1000000 + mcp->sclk_rate - 1) /
                          mcp->sclk_rate;
 
-       ret = mcp_host_register(mcp, data->codec_pdata);
+       ret = mcp_host_register(mcp);
        if (ret == 0)
                goto out;
 
- release2:
-       release_mem_region(res_mem1->start, size1);
  release:
-       release_mem_region(res_mem0->start, size0);
+       release_mem_region(0x80060000, 0x60);
        platform_set_drvdata(pdev, NULL);
 
  out:
        return ret;
 }
 
-static int mcp_sa11x0_remove(struct platform_device *pdev)
+static int mcp_sa11x0_remove(struct platform_device *dev)
 {
-       struct mcp *mcp = platform_get_drvdata(pdev);
-       struct mcp_sa11x0 *priv = priv(mcp);
-       struct resource *res_mem;
-       u32 size;
+       struct mcp *mcp = platform_get_drvdata(dev);
 
-       platform_set_drvdata(pdev, NULL);
+       platform_set_drvdata(dev, NULL);
        mcp_host_unregister(mcp);
+       release_mem_region(0x80060000, 0x60);
 
-       res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       if (res_mem) {
-               size = res_mem->end - res_mem->start + 1;
-               release_mem_region(res_mem->start, size);
-       }
-       res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 1);
-       if (res_mem) {
-               size = res_mem->end - res_mem->start + 1;
-               release_mem_region(res_mem->start, size);
-       }
-       iounmap(priv->mccr0_base);
-       iounmap(priv->mccr1_base);
        return 0;
 }
 
 static int mcp_sa11x0_suspend(struct platform_device *dev, pm_message_t state)
 {
        struct mcp *mcp = platform_get_drvdata(dev);
-       struct mcp_sa11x0 *priv = priv(mcp);
-       u32 mccr0;
 
-       mccr0 = priv->mccr0 & ~MCCR0_MCE;
-       __raw_writel(mccr0, priv->mccr0_base + MCCR0);
+       priv(mcp)->mccr0 = Ser4MCCR0;
+       priv(mcp)->mccr1 = Ser4MCCR1;
+       Ser4MCCR0 &= ~MCCR0_MCE;
 
        return 0;
 }
@@ -291,10 +232,9 @@ static int mcp_sa11x0_suspend(struct platform_device *dev, pm_message_t state)
 static int mcp_sa11x0_resume(struct platform_device *dev)
 {
        struct mcp *mcp = platform_get_drvdata(dev);
-       struct mcp_sa11x0 *priv = priv(mcp);
 
-       __raw_writel(priv->mccr0, priv->mccr0_base + MCCR0);
-       __raw_writel(priv->mccr1, priv->mccr1_base + MCCR1);
+       Ser4MCCR1 = priv(mcp)->mccr1;
+       Ser4MCCR0 = priv(mcp)->mccr0;
 
        return 0;
 }
@@ -311,7 +251,6 @@ static struct platform_driver mcp_sa11x0_driver = {
        .resume         = mcp_sa11x0_resume,
        .driver         = {
                .name   = "sa11x0-mcp",
-               .owner  = THIS_MODULE,
        },
 };
 
index e04e04d..8ce3959 100644 (file)
@@ -263,7 +263,9 @@ struct twl_client {
 
 static struct twl_client twl_modules[TWL_NUM_SLAVES];
 
+#ifdef CONFIG_IRQ_DOMAIN
 static struct irq_domain domain;
+#endif
 
 /* mapping the module id to slave id and base address */
 struct twl_mapping {
@@ -1226,13 +1228,13 @@ twl_probe(struct i2c_client *client, const struct i2c_device_id *id)
        pdata->irq_base = status;
        pdata->irq_end = pdata->irq_base + nr_irqs;
 
+#ifdef CONFIG_IRQ_DOMAIN
        domain.irq_base = pdata->irq_base;
        domain.nr_irq = nr_irqs;
-#ifdef CONFIG_OF_IRQ
        domain.of_node = of_node_get(node);
        domain.ops = &irq_domain_simple_ops;
-#endif
        irq_domain_add(&domain);
+#endif
 
        if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C) == 0) {
                dev_dbg(&client->dev, "can't talk I2C?\n");
index d905f51..79ca33d 100644 (file)
@@ -124,7 +124,7 @@ static u8 res_config_addrs[] = {
        [RES_MAIN_REF]  = 0x94,
 };
 
-static int __init twl4030_write_script_byte(u8 address, u8 byte)
+static int __devinit twl4030_write_script_byte(u8 address, u8 byte)
 {
        int err;
 
@@ -138,7 +138,7 @@ out:
        return err;
 }
 
-static int __init twl4030_write_script_ins(u8 address, u16 pmb_message,
+static int __devinit twl4030_write_script_ins(u8 address, u16 pmb_message,
                                           u8 delay, u8 next)
 {
        int err;
@@ -158,7 +158,7 @@ out:
        return err;
 }
 
-static int __init twl4030_write_script(u8 address, struct twl4030_ins *script,
+static int __devinit twl4030_write_script(u8 address, struct twl4030_ins *script,
                                       int len)
 {
        int err;
@@ -183,7 +183,7 @@ static int __init twl4030_write_script(u8 address, struct twl4030_ins *script,
        return err;
 }
 
-static int __init twl4030_config_wakeup3_sequence(u8 address)
+static int __devinit twl4030_config_wakeup3_sequence(u8 address)
 {
        int err;
        u8 data;
@@ -208,7 +208,7 @@ out:
        return err;
 }
 
-static int __init twl4030_config_wakeup12_sequence(u8 address)
+static int __devinit twl4030_config_wakeup12_sequence(u8 address)
 {
        int err = 0;
        u8 data;
@@ -262,7 +262,7 @@ out:
        return err;
 }
 
-static int __init twl4030_config_sleep_sequence(u8 address)
+static int __devinit twl4030_config_sleep_sequence(u8 address)
 {
        int err;
 
@@ -276,7 +276,7 @@ static int __init twl4030_config_sleep_sequence(u8 address)
        return err;
 }
 
-static int __init twl4030_config_warmreset_sequence(u8 address)
+static int __devinit twl4030_config_warmreset_sequence(u8 address)
 {
        int err;
        u8 rd_data;
@@ -324,7 +324,7 @@ out:
        return err;
 }
 
-static int __init twl4030_configure_resource(struct twl4030_resconfig *rconfig)
+static int __devinit twl4030_configure_resource(struct twl4030_resconfig *rconfig)
 {
        int rconfig_addr;
        int err;
@@ -416,7 +416,7 @@ static int __init twl4030_configure_resource(struct twl4030_resconfig *rconfig)
        return 0;
 }
 
-static int __init load_twl4030_script(struct twl4030_script *tscript,
+static int __devinit load_twl4030_script(struct twl4030_script *tscript,
               u8 address)
 {
        int err;
@@ -527,7 +527,7 @@ void twl4030_power_off(void)
                pr_err("TWL4030 Unable to power off\n");
 }
 
-void __init twl4030_power_init(struct twl4030_power_data *twl4030_scripts)
+void __devinit twl4030_power_init(struct twl4030_power_data *twl4030_scripts)
 {
        int err = 0;
        int i;
index dda8629..b2d8e51 100644 (file)
@@ -282,6 +282,7 @@ int twl6040_power(struct twl6040 *twl6040, int on)
                /* Default PLL configuration after power up */
                twl6040->pll = TWL6040_SYSCLK_SEL_LPPLL;
                twl6040->sysclk = 19200000;
+               twl6040->mclk = 32768;
        } else {
                /* already powered-down */
                if (!twl6040->power_count) {
@@ -305,6 +306,7 @@ int twl6040_power(struct twl6040 *twl6040, int on)
                        twl6040_power_down(twl6040);
                }
                twl6040->sysclk = 0;
+               twl6040->mclk = 0;
        }
 
 out:
@@ -324,23 +326,38 @@ int twl6040_set_pll(struct twl6040 *twl6040, int pll_id,
        hppllctl = twl6040_reg_read(twl6040, TWL6040_REG_HPPLLCTL);
        lppllctl = twl6040_reg_read(twl6040, TWL6040_REG_LPPLLCTL);
 
+       /* Force full reconfiguration when switching between PLL */
+       if (pll_id != twl6040->pll) {
+               twl6040->sysclk = 0;
+               twl6040->mclk = 0;
+       }
+
        switch (pll_id) {
        case TWL6040_SYSCLK_SEL_LPPLL:
                /* low-power PLL divider */
-               switch (freq_out) {
-               case 17640000:
-                       lppllctl |= TWL6040_LPLLFIN;
-                       break;
-               case 19200000:
-                       lppllctl &= ~TWL6040_LPLLFIN;
-                       break;
-               default:
-                       dev_err(twl6040->dev,
-                               "freq_out %d not supported\n", freq_out);
-                       ret = -EINVAL;
-                       goto pll_out;
+               /* Change the sysclk configuration only if it has been canged */
+               if (twl6040->sysclk != freq_out) {
+                       switch (freq_out) {
+                       case 17640000:
+                               lppllctl |= TWL6040_LPLLFIN;
+                               break;
+                       case 19200000:
+                               lppllctl &= ~TWL6040_LPLLFIN;
+                               break;
+                       default:
+                               dev_err(twl6040->dev,
+                                       "freq_out %d not supported\n",
+                                       freq_out);
+                               ret = -EINVAL;
+                               goto pll_out;
+                       }
+                       twl6040_reg_write(twl6040, TWL6040_REG_LPPLLCTL,
+                                         lppllctl);
                }
-               twl6040_reg_write(twl6040, TWL6040_REG_LPPLLCTL, lppllctl);
+
+               /* The PLL in use has not been change, we can exit */
+               if (twl6040->pll == pll_id)
+                       break;
 
                switch (freq_in) {
                case 32768:
@@ -371,48 +388,56 @@ int twl6040_set_pll(struct twl6040 *twl6040, int pll_id,
                        goto pll_out;
                }
 
-               hppllctl &= ~TWL6040_MCLK_MSK;
+               if (twl6040->mclk != freq_in) {
+                       hppllctl &= ~TWL6040_MCLK_MSK;
+
+                       switch (freq_in) {
+                       case 12000000:
+                               /* PLL enabled, active mode */
+                               hppllctl |= TWL6040_MCLK_12000KHZ |
+                                           TWL6040_HPLLENA;
+                               break;
+                       case 19200000:
+                               /*
+                               * PLL disabled
+                               * (enable PLL if MCLK jitter quality
+                               *  doesn't meet specification)
+                               */
+                               hppllctl |= TWL6040_MCLK_19200KHZ;
+                               break;
+                       case 26000000:
+                               /* PLL enabled, active mode */
+                               hppllctl |= TWL6040_MCLK_26000KHZ |
+                                           TWL6040_HPLLENA;
+                               break;
+                       case 38400000:
+                               /* PLL enabled, active mode */
+                               hppllctl |= TWL6040_MCLK_38400KHZ |
+                                           TWL6040_HPLLENA;
+                               break;
+                       default:
+                               dev_err(twl6040->dev,
+                                       "freq_in %d not supported\n", freq_in);
+                               ret = -EINVAL;
+                               goto pll_out;
+                       }
 
-               switch (freq_in) {
-               case 12000000:
-                       /* PLL enabled, active mode */
-                       hppllctl |= TWL6040_MCLK_12000KHZ |
-                                   TWL6040_HPLLENA;
-                       break;
-               case 19200000:
                        /*
-                        * PLL disabled
-                        * (enable PLL if MCLK jitter quality
-                        *  doesn't meet specification)
+                        * enable clock slicer to ensure input waveform is
+                        * square
                         */
-                       hppllctl |= TWL6040_MCLK_19200KHZ;
-                       break;
-               case 26000000:
-                       /* PLL enabled, active mode */
-                       hppllctl |= TWL6040_MCLK_26000KHZ |
-                                   TWL6040_HPLLENA;
-                       break;
-               case 38400000:
-                       /* PLL enabled, active mode */
-                       hppllctl |= TWL6040_MCLK_38400KHZ |
-                                   TWL6040_HPLLENA;
-                       break;
-               default:
-                       dev_err(twl6040->dev,
-                               "freq_in %d not supported\n", freq_in);
-                       ret = -EINVAL;
-                       goto pll_out;
-               }
+                       hppllctl |= TWL6040_HPLLSQRENA;
 
-               /* enable clock slicer to ensure input waveform is square */
-               hppllctl |= TWL6040_HPLLSQRENA;
-
-               twl6040_reg_write(twl6040, TWL6040_REG_HPPLLCTL, hppllctl);
-               usleep_range(500, 700);
-               lppllctl |= TWL6040_HPLLSEL;
-               twl6040_reg_write(twl6040, TWL6040_REG_LPPLLCTL, lppllctl);
-               lppllctl &= ~TWL6040_LPLLENA;
-               twl6040_reg_write(twl6040, TWL6040_REG_LPPLLCTL, lppllctl);
+                       twl6040_reg_write(twl6040, TWL6040_REG_HPPLLCTL,
+                                         hppllctl);
+                       usleep_range(500, 700);
+                       lppllctl |= TWL6040_HPLLSEL;
+                       twl6040_reg_write(twl6040, TWL6040_REG_LPPLLCTL,
+                                         lppllctl);
+                       lppllctl &= ~TWL6040_LPLLENA;
+                       twl6040_reg_write(twl6040, TWL6040_REG_LPPLLCTL,
+                                         lppllctl);
+               }
                break;
        default:
                dev_err(twl6040->dev, "unknown pll id %d\n", pll_id);
@@ -421,6 +446,7 @@ int twl6040_set_pll(struct twl6040 *twl6040, int pll_id,
        }
 
        twl6040->sysclk = freq_out;
+       twl6040->mclk = freq_in;
        twl6040->pll = pll_id;
 
 pll_out:
index 91c4f25..febc90c 100644 (file)
@@ -36,15 +36,6 @@ static DEFINE_MUTEX(ucb1x00_mutex);
 static LIST_HEAD(ucb1x00_drivers);
 static LIST_HEAD(ucb1x00_devices);
 
-static struct mcp_device_id ucb1x00_id[] = {
-       { "ucb1x00", 0 },  /* auto-detection */
-       { "ucb1200", UCB_ID_1200 },
-       { "ucb1300", UCB_ID_1300 },
-       { "tc35143", UCB_ID_TC35143 },
-       { }
-};
-MODULE_DEVICE_TABLE(mcp, ucb1x00_id);
-
 /**
  *     ucb1x00_io_set_dir - set IO direction
  *     @ucb: UCB1x00 structure describing chip
@@ -157,16 +148,22 @@ static int ucb1x00_gpio_direction_output(struct gpio_chip *chip, unsigned offset
 {
        struct ucb1x00 *ucb = container_of(chip, struct ucb1x00, gpio);
        unsigned long flags;
+       unsigned old, mask = 1 << offset;
 
        spin_lock_irqsave(&ucb->io_lock, flags);
-       ucb->io_dir |= (1 << offset);
-       ucb1x00_reg_write(ucb, UCB_IO_DIR, ucb->io_dir);
-
+       old = ucb->io_out;
        if (value)
-               ucb->io_out |= 1 << offset;
+               ucb->io_out |= mask;
        else
-               ucb->io_out &= ~(1 << offset);
-       ucb1x00_reg_write(ucb, UCB_IO_DATA, ucb->io_out);
+               ucb->io_out &= ~mask;
+
+       if (old != ucb->io_out)
+               ucb1x00_reg_write(ucb, UCB_IO_DATA, ucb->io_out);
+
+       if (!(ucb->io_dir & mask)) {
+               ucb->io_dir |= mask;
+               ucb1x00_reg_write(ucb, UCB_IO_DIR, ucb->io_dir);
+       }
        spin_unlock_irqrestore(&ucb->io_lock, flags);
 
        return 0;
@@ -536,33 +533,17 @@ static struct class ucb1x00_class = {
 
 static int ucb1x00_probe(struct mcp *mcp)
 {
-       const struct mcp_device_id *mid;
        struct ucb1x00 *ucb;
        struct ucb1x00_driver *drv;
-       struct ucb1x00_plat_data *pdata;
        unsigned int id;
        int ret = -ENODEV;
        int temp;
 
        mcp_enable(mcp);
        id = mcp_reg_read(mcp, UCB_ID);
-       mid = mcp_get_device_id(mcp);
 
-       if (mid && mid->driver_data) {
-               if (id != mid->driver_data) {
-                       printk(KERN_WARNING "%s wrong ID %04x found: %04x\n",
-                               mid->name, (unsigned int) mid->driver_data, id);
-                       goto err_disable;
-               }
-       } else {
-               mid = &ucb1x00_id[1];
-               while (mid->driver_data) {
-                       if (id == mid->driver_data)
-                               break;
-                       mid++;
-               }
-               printk(KERN_WARNING "%s ID not found: %04x\n",
-                       ucb1x00_id[0].name, id);
+       if (id != UCB_ID_1200 && id != UCB_ID_1300 && id != UCB_ID_TC35143) {
+               printk(KERN_WARNING "UCB1x00 ID not found: %04x\n", id);
                goto err_disable;
        }
 
@@ -571,28 +552,28 @@ static int ucb1x00_probe(struct mcp *mcp)
        if (!ucb)
                goto err_disable;
 
-       pdata = mcp->attached_device.platform_data;
+
        ucb->dev.class = &ucb1x00_class;
        ucb->dev.parent = &mcp->attached_device;
-       dev_set_name(&ucb->dev, mid->name);
+       dev_set_name(&ucb->dev, "ucb1x00");
 
        spin_lock_init(&ucb->lock);
        spin_lock_init(&ucb->io_lock);
        sema_init(&ucb->adc_sem, 1);
 
-       ucb->id  = mid;
+       ucb->id  = id;
        ucb->mcp = mcp;
        ucb->irq = ucb1x00_detect_irq(ucb);
        if (ucb->irq == NO_IRQ) {
-               printk(KERN_ERR "%s: IRQ probe failed\n", mid->name);
+               printk(KERN_ERR "UCB1x00: IRQ probe failed\n");
                ret = -ENODEV;
                goto err_free;
        }
 
        ucb->gpio.base = -1;
-       if (pdata && (pdata->gpio_base >= 0)) {
+       if (mcp->gpio_base != 0) {
                ucb->gpio.label = dev_name(&ucb->dev);
-               ucb->gpio.base = pdata->gpio_base;
+               ucb->gpio.base = mcp->gpio_base;
                ucb->gpio.ngpio = 10;
                ucb->gpio.set = ucb1x00_gpio_set;
                ucb->gpio.get = ucb1x00_gpio_get;
@@ -605,10 +586,10 @@ static int ucb1x00_probe(struct mcp *mcp)
                dev_info(&ucb->dev, "gpio_base not set so no gpiolib support");
 
        ret = request_irq(ucb->irq, ucb1x00_irq, IRQF_TRIGGER_RISING,
-                         mid->name, ucb);
+                         "UCB1x00", ucb);
        if (ret) {
-               printk(KERN_ERR "%s: unable to grab irq%d: %d\n",
-                       mid->name, ucb->irq, ret);
+               printk(KERN_ERR "ucb1x00: unable to grab irq%d: %d\n",
+                       ucb->irq, ret);
                goto err_gpio;
        }
 
@@ -712,6 +693,7 @@ static int ucb1x00_resume(struct mcp *mcp)
        struct ucb1x00 *ucb = mcp_get_drvdata(mcp);
        struct ucb1x00_dev *dev;
 
+       ucb1x00_reg_write(ucb, UCB_IO_DATA, ucb->io_out);
        ucb1x00_reg_write(ucb, UCB_IO_DIR, ucb->io_dir);
        mutex_lock(&ucb1x00_mutex);
        list_for_each_entry(dev, &ucb->devs, dev_node) {
@@ -730,7 +712,6 @@ static struct mcp_driver ucb1x00_driver = {
        .remove         = ucb1x00_remove,
        .suspend        = ucb1x00_suspend,
        .resume         = ucb1x00_resume,
-       .id_table       = ucb1x00_id,
 };
 
 static int __init ucb1x00_init(void)
index 40ec3c1..63a3cbd 100644 (file)
@@ -47,7 +47,6 @@ struct ucb1x00_ts {
        u16                     x_res;
        u16                     y_res;
 
-       unsigned int            restart:1;
        unsigned int            adcsync:1;
 };
 
@@ -207,15 +206,17 @@ static int ucb1x00_thread(void *_ts)
 {
        struct ucb1x00_ts *ts = _ts;
        DECLARE_WAITQUEUE(wait, current);
+       bool frozen, ignore = false;
        int valid = 0;
 
        set_freezable();
        add_wait_queue(&ts->irq_wait, &wait);
-       while (!kthread_should_stop()) {
+       while (!kthread_freezable_should_stop(&frozen)) {
                unsigned int x, y, p;
                signed long timeout;
 
-               ts->restart = 0;
+               if (frozen)
+                       ignore = true;
 
                ucb1x00_adc_enable(ts->ucb);
 
@@ -258,7 +259,7 @@ static int ucb1x00_thread(void *_ts)
                         * space.  We therefore leave it to user space
                         * to do any filtering they please.
                         */
-                       if (!ts->restart) {
+                       if (!ignore) {
                                ucb1x00_ts_evt_add(ts, p, x, y);
                                valid = 1;
                        }
@@ -267,8 +268,6 @@ static int ucb1x00_thread(void *_ts)
                        timeout = HZ / 100;
                }
 
-               try_to_freeze();
-
                schedule_timeout(timeout);
        }
 
@@ -340,26 +339,6 @@ static void ucb1x00_ts_close(struct input_dev *idev)
        ucb1x00_disable(ts->ucb);
 }
 
-#ifdef CONFIG_PM
-static int ucb1x00_ts_resume(struct ucb1x00_dev *dev)
-{
-       struct ucb1x00_ts *ts = dev->priv;
-
-       if (ts->rtask != NULL) {
-               /*
-                * Restart the TS thread to ensure the
-                * TS interrupt mode is set up again
-                * after sleep.
-                */
-               ts->restart = 1;
-               wake_up(&ts->irq_wait);
-       }
-       return 0;
-}
-#else
-#define ucb1x00_ts_resume NULL
-#endif
-
 
 /*
  * Initialisation.
@@ -382,7 +361,7 @@ static int ucb1x00_ts_add(struct ucb1x00_dev *dev)
        ts->adcsync = adcsync ? UCB_SYNC : UCB_NOSYNC;
 
        idev->name       = "Touchscreen panel";
-       idev->id.product = ts->ucb->id->driver_data;
+       idev->id.product = ts->ucb->id;
        idev->open       = ucb1x00_ts_open;
        idev->close      = ucb1x00_ts_close;
 
@@ -425,7 +404,6 @@ static void ucb1x00_ts_remove(struct ucb1x00_dev *dev)
 static struct ucb1x00_driver ucb1x00_ts_driver = {
        .add            = ucb1x00_ts_add,
        .remove         = ucb1x00_ts_remove,
-       .resume         = ucb1x00_ts_resume,
 };
 
 static int __init ucb1x00_ts_init(void)
index 6a1a092..c779509 100644 (file)
@@ -2,24 +2,14 @@
 # Misc strange devices
 #
 
-# This one has to live outside of the MISC_DEVICES conditional,
-# because it may be selected by drivers/platform/x86/hp_accel.
+menu "Misc devices"
+
 config SENSORS_LIS3LV02D
        tristate
        depends on INPUT
        select INPUT_POLLDEV
        default n
 
-menuconfig MISC_DEVICES
-       bool "Misc devices"
-       ---help---
-         Say Y here to get to see options for device drivers from various
-         different categories. This option alone does not add any kernel code.
-
-         If you say N, all options in this submenu will be skipped and disabled.
-
-if MISC_DEVICES
-
 config AD525X_DPOT
        tristate "Analog Devices Digital Potentiometers"
        depends on (I2C || SPI) && SYSFS
@@ -516,5 +506,4 @@ source "drivers/misc/ti-st/Kconfig"
 source "drivers/misc/lis3lv02d/Kconfig"
 source "drivers/misc/carma/Kconfig"
 source "drivers/misc/altera-stapl/Kconfig"
-
-endif # MISC_DEVICES
+endmenu
index 778fc3f..5484301 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/module.h>
 #include <linux/delay.h>
 #include <linux/io.h>
+#include <linux/ioport.h>
 #include <linux/c2port.h>
 
 #define DATA_PORT      0x325
index 68cd05b..85cc771 100644 (file)
@@ -245,6 +245,7 @@ static int __devinit cb710_probe(struct pci_dev *pdev,
        if (err)
                return err;
 
+       spin_lock_init(&chip->irq_lock);
        chip->pdev = pdev;
        chip->iobase = pcim_iomap_table(pdev)[0];
 
index bc685bf..87a390d 100644 (file)
@@ -262,7 +262,7 @@ static void __init reset_all_timers(void)
  * In other cases (such as with VSAless OpenFirmware), the system firmware
  * leaves timers available for us to use.
  */
-static int __init scan_timers(struct cs5535_mfgpt_chip *mfgpt)
+static int __devinit scan_timers(struct cs5535_mfgpt_chip *mfgpt)
 {
        struct cs5535_mfgpt_timer timer = { .chip = mfgpt };
        unsigned long flags;
index 150cd70..28adefe 100644 (file)
@@ -354,6 +354,7 @@ static void lkdtm_do_action(enum ctype which)
 static void lkdtm_handler(void)
 {
        unsigned long flags;
+       bool do_it = false;
 
        spin_lock_irqsave(&count_lock, flags);
        count--;
@@ -361,10 +362,13 @@ static void lkdtm_handler(void)
                        cp_name_to_str(cpoint), cp_type_to_str(cptype), count);
 
        if (count == 0) {
-               lkdtm_do_action(cptype);
+               do_it = true;
                count = cpoint_count;
        }
        spin_unlock_irqrestore(&count_lock, flags);
+
+       if (do_it)
+               lkdtm_do_action(cptype);
 }
 
 static int lkdtm_register_cpoint(enum cname which)
index cd41d40..cb56e27 100644 (file)
@@ -314,7 +314,7 @@ static bool vmballoon_send_get_target(struct vmballoon *b, u32 *new_target)
  * fear that guest will need it. Host may reject some pages, we need to
  * check the return value and maybe submit a different page.
  */
-static bool vmballoon_send_lock_page(struct vmballoon *b, unsigned long pfn,
+static int vmballoon_send_lock_page(struct vmballoon *b, unsigned long pfn,
                                     unsigned int *hv_status)
 {
        unsigned long status, dummy;
@@ -322,17 +322,17 @@ static bool vmballoon_send_lock_page(struct vmballoon *b, unsigned long pfn,
 
        pfn32 = (u32)pfn;
        if (pfn32 != pfn)
-               return false;
+               return -1;
 
        STATS_INC(b->stats.lock);
 
        *hv_status = status = VMWARE_BALLOON_CMD(LOCK, pfn, dummy);
        if (vmballoon_check_status(b, status))
-               return true;
+               return 0;
 
        pr_debug("%s - ppn %lx, hv returns %ld\n", __func__, pfn, status);
        STATS_INC(b->stats.lock_fail);
-       return false;
+       return 1;
 }
 
 /*
@@ -411,7 +411,7 @@ static int vmballoon_reserve_page(struct vmballoon *b, bool can_sleep)
        struct page *page;
        gfp_t flags;
        unsigned int hv_status;
-       bool locked = false;
+       int locked;
        flags = can_sleep ? VMW_PAGE_ALLOC_CANSLEEP : VMW_PAGE_ALLOC_NOSLEEP;
 
        do {
@@ -431,7 +431,7 @@ static int vmballoon_reserve_page(struct vmballoon *b, bool can_sleep)
 
                /* inform monitor */
                locked = vmballoon_send_lock_page(b, page_to_pfn(page), &hv_status);
-               if (!locked) {
+               if (locked > 0) {
                        STATS_INC(b->stats.refused_alloc);
 
                        if (hv_status == VMW_BALLOON_ERROR_RESET ||
@@ -449,7 +449,7 @@ static int vmballoon_reserve_page(struct vmballoon *b, bool can_sleep)
                        if (++b->n_refused_pages >= VMW_BALLOON_MAX_REFUSED)
                                return -EIO;
                }
-       } while (!locked);
+       } while (locked != 0);
 
        /* track allocated page */
        list_add(&page->lru, &b->pages);
index 0cad48a..c6a383d 100644 (file)
@@ -1694,6 +1694,7 @@ static int mmc_add_disk(struct mmc_blk_data *md)
 
                md->power_ro_lock.show = power_ro_lock_show;
                md->power_ro_lock.store = power_ro_lock_store;
+               sysfs_attr_init(&md->power_ro_lock.attr);
                md->power_ro_lock.attr.mode = mode;
                md->power_ro_lock.attr.name =
                                        "ro_lock_until_next_power_on";
index f545a3e..690255c 100644 (file)
@@ -290,8 +290,11 @@ static void mmc_wait_for_req_done(struct mmc_host *host,
 static void mmc_pre_req(struct mmc_host *host, struct mmc_request *mrq,
                 bool is_first_req)
 {
-       if (host->ops->pre_req)
+       if (host->ops->pre_req) {
+               mmc_host_clk_hold(host);
                host->ops->pre_req(host, mrq, is_first_req);
+               mmc_host_clk_release(host);
+       }
 }
 
 /**
@@ -306,8 +309,11 @@ static void mmc_pre_req(struct mmc_host *host, struct mmc_request *mrq,
 static void mmc_post_req(struct mmc_host *host, struct mmc_request *mrq,
                         int err)
 {
-       if (host->ops->post_req)
+       if (host->ops->post_req) {
+               mmc_host_clk_hold(host);
                host->ops->post_req(host, mrq, err);
+               mmc_host_clk_release(host);
+       }
 }
 
 /**
@@ -620,7 +626,9 @@ int mmc_host_enable(struct mmc_host *host)
                int err;
 
                host->en_dis_recurs = 1;
+               mmc_host_clk_hold(host);
                err = host->ops->enable(host);
+               mmc_host_clk_release(host);
                host->en_dis_recurs = 0;
 
                if (err) {
@@ -640,7 +648,9 @@ static int mmc_host_do_disable(struct mmc_host *host, int lazy)
                int err;
 
                host->en_dis_recurs = 1;
+               mmc_host_clk_hold(host);
                err = host->ops->disable(host, lazy);
+               mmc_host_clk_release(host);
                host->en_dis_recurs = 0;
 
                if (err < 0) {
@@ -1121,6 +1131,10 @@ int mmc_regulator_set_ocr(struct mmc_host *mmc,
                 * might not allow this operation
                 */
                voltage = regulator_get_voltage(supply);
+
+               if (mmc->caps2 & MMC_CAP2_BROKEN_VOLTAGE)
+                       min_uV = max_uV = voltage;
+
                if (voltage < 0)
                        result = voltage;
                else if (voltage < min_uV || voltage > max_uV)
@@ -1203,8 +1217,11 @@ int mmc_set_signal_voltage(struct mmc_host *host, int signal_voltage, bool cmd11
 
        host->ios.signal_voltage = signal_voltage;
 
-       if (host->ops->start_signal_voltage_switch)
+       if (host->ops->start_signal_voltage_switch) {
+               mmc_host_clk_hold(host);
                err = host->ops->start_signal_voltage_switch(host, &host->ios);
+               mmc_host_clk_release(host);
+       }
 
        return err;
 }
@@ -1239,6 +1256,7 @@ static void mmc_poweroff_notify(struct mmc_host *host)
        int err = 0;
 
        card = host->card;
+       mmc_claim_host(host);
 
        /*
         * Send power notify command only if card
@@ -1269,6 +1287,7 @@ static void mmc_poweroff_notify(struct mmc_host *host)
                /* Set the card state to no notification after the poweroff */
                card->poweroff_notify_state = MMC_NO_POWER_NOTIFICATION;
        }
+       mmc_release_host(host);
 }
 
 /*
@@ -1327,12 +1346,28 @@ static void mmc_power_up(struct mmc_host *host)
 
 void mmc_power_off(struct mmc_host *host)
 {
+       int err = 0;
        mmc_host_clk_hold(host);
 
        host->ios.clock = 0;
        host->ios.vdd = 0;
 
-       mmc_poweroff_notify(host);
+       /*
+        * For eMMC 4.5 device send AWAKE command before
+        * POWER_OFF_NOTIFY command, because in sleep state
+        * eMMC 4.5 devices respond to only RESET and AWAKE cmd
+        */
+       if (host->card && mmc_card_is_sleep(host->card) &&
+           host->bus_ops->resume) {
+               err = host->bus_ops->resume(host);
+
+               if (!err)
+                       mmc_poweroff_notify(host);
+               else
+                       pr_warning("%s: error %d during resume "
+                                  "(continue with poweroff sequence)\n",
+                                  mmc_hostname(host), err);
+       }
 
        /*
         * Reset ocr mask to be the highest possible voltage supported for
@@ -2386,12 +2421,6 @@ int mmc_suspend_host(struct mmc_host *host)
                 */
                if (mmc_try_claim_host(host)) {
                        if (host->bus_ops->suspend) {
-                               /*
-                                * For eMMC 4.5 device send notify command
-                                * before sleep, because in sleep state eMMC 4.5
-                                * devices respond to only RESET and AWAKE cmd
-                                */
-                               mmc_poweroff_notify(host);
                                err = host->bus_ops->suspend(host);
                        }
                        mmc_do_release_host(host);
index fb8a5cd..08a7852 100644 (file)
 
 int mmc_register_host_class(void);
 void mmc_unregister_host_class(void);
-
-#ifdef CONFIG_MMC_CLKGATE
-void mmc_host_clk_hold(struct mmc_host *host);
-void mmc_host_clk_release(struct mmc_host *host);
-unsigned int mmc_host_clk_rate(struct mmc_host *host);
-
-#else
-static inline void mmc_host_clk_hold(struct mmc_host *host)
-{
-}
-
-static inline void mmc_host_clk_release(struct mmc_host *host)
-{
-}
-
-static inline unsigned int mmc_host_clk_rate(struct mmc_host *host)
-{
-       return host->ios.clock;
-}
-#endif
-
 void mmc_host_deeper_disable(struct work_struct *work);
 
 #endif
index 59b9ba5..a480663 100644 (file)
@@ -376,7 +376,7 @@ static int mmc_read_ext_csd(struct mmc_card *card, u8 *ext_csd)
        }
 
        card->ext_csd.raw_hc_erase_gap_size =
-               ext_csd[EXT_CSD_PARTITION_ATTRIBUTE];
+               ext_csd[EXT_CSD_HC_WP_GRP_SIZE];
        card->ext_csd.raw_sec_trim_mult =
                ext_csd[EXT_CSD_SEC_TRIM_MULT];
        card->ext_csd.raw_sec_erase_mult =
@@ -551,7 +551,7 @@ static int mmc_compare_ext_csds(struct mmc_card *card, unsigned bus_width)
                goto out;
 
        /* only compare read only fields */
-       err = (!(card->ext_csd.raw_partition_support ==
+       err = !((card->ext_csd.raw_partition_support ==
                        bw_ext_csd[EXT_CSD_PARTITION_SUPPORT]) &&
                (card->ext_csd.raw_erased_mem_count ==
                        bw_ext_csd[EXT_CSD_ERASED_MEM_CONT]) &&
@@ -1006,7 +1006,8 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
                        err = mmc_select_hs200(card);
                else if (host->caps & MMC_CAP_MMC_HIGHSPEED)
                        err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
-                                        EXT_CSD_HS_TIMING, 1, 0);
+                                        EXT_CSD_HS_TIMING, 1,
+                                        card->ext_csd.generic_cmd6_time);
 
                if (err && err != -EBADMSG)
                        goto free_card;
@@ -1116,7 +1117,7 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
         * Activate wide bus and DDR (if supported).
         */
        if (!mmc_card_hs200(card) &&
-           (card->csd.mmca_vsn >= CSD_SPEC_VER_3) &&
+           (card->csd.mmca_vsn >= CSD_SPEC_VER_4) &&
            (host->caps & (MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA))) {
                static unsigned ext_csd_bits[][2] = {
                        { EXT_CSD_BUS_WIDTH_8, EXT_CSD_DDR_BUS_WIDTH_8 },
@@ -1315,11 +1316,13 @@ static int mmc_suspend(struct mmc_host *host)
        BUG_ON(!host->card);
 
        mmc_claim_host(host);
-       if (mmc_card_can_sleep(host))
+       if (mmc_card_can_sleep(host)) {
                err = mmc_card_sleep(host);
-       else if (!mmc_host_is_spi(host))
+               if (!err)
+                       mmc_card_set_sleep(host->card);
+       } else if (!mmc_host_is_spi(host))
                mmc_deselect_cards(host);
-       host->card->state &= ~MMC_STATE_HIGHSPEED;
+       host->card->state &= ~(MMC_STATE_HIGHSPEED | MMC_STATE_HIGHSPEED_200);
        mmc_release_host(host);
 
        return err;
@@ -1339,7 +1342,11 @@ static int mmc_resume(struct mmc_host *host)
        BUG_ON(!host->card);
 
        mmc_claim_host(host);
-       err = mmc_init_card(host, host->ocr, host->card);
+       if (mmc_card_is_sleep(host->card)) {
+               err = mmc_card_awake(host);
+               mmc_card_clr_sleep(host->card);
+       } else
+               err = mmc_init_card(host, host->ocr, host->card);
        mmc_release_host(host);
 
        return err;
@@ -1349,7 +1356,8 @@ static int mmc_power_restore(struct mmc_host *host)
 {
        int ret;
 
-       host->card->state &= ~MMC_STATE_HIGHSPEED;
+       host->card->state &= ~(MMC_STATE_HIGHSPEED | MMC_STATE_HIGHSPEED_200);
+       mmc_card_clr_sleep(host->card);
        mmc_claim_host(host);
        ret = mmc_init_card(host, host->ocr, host->card);
        mmc_release_host(host);
index c63ad03..5017f93 100644 (file)
@@ -451,9 +451,11 @@ static int sd_select_driver_type(struct mmc_card *card, u8 *status)
         * information and let the hardware specific code
         * return what is possible given the options
         */
+       mmc_host_clk_hold(card->host);
        drive_strength = card->host->ops->select_drive_strength(
                card->sw_caps.uhs_max_dtr,
                host_drv_type, card_drv_type);
+       mmc_host_clk_release(card->host);
 
        err = mmc_sd_switch(card, 1, 2, drive_strength, status);
        if (err)
@@ -660,9 +662,12 @@ static int mmc_sd_init_uhs_card(struct mmc_card *card)
                goto out;
 
        /* SPI mode doesn't define CMD19 */
-       if (!mmc_host_is_spi(card->host) && card->host->ops->execute_tuning)
+       if (!mmc_host_is_spi(card->host) && card->host->ops->execute_tuning) {
+               mmc_host_clk_hold(card->host);
                err = card->host->ops->execute_tuning(card->host,
                                                      MMC_SEND_TUNING_BLOCK);
+               mmc_host_clk_release(card->host);
+       }
 
 out:
        kfree(status);
@@ -850,8 +855,11 @@ int mmc_sd_setup_card(struct mmc_host *host, struct mmc_card *card,
        if (!reinit) {
                int ro = -1;
 
-               if (host->ops->get_ro)
+               if (host->ops->get_ro) {
+                       mmc_host_clk_hold(card->host);
                        ro = host->ops->get_ro(host);
+                       mmc_host_clk_release(card->host);
+               }
 
                if (ro < 0) {
                        pr_warning("%s: host does not "
@@ -967,8 +975,11 @@ static int mmc_sd_init_card(struct mmc_host *host, u32 ocr,
                 * Since initialization is now complete, enable preset
                 * value registers for UHS-I cards.
                 */
-               if (host->ops->enable_preset_value)
+               if (host->ops->enable_preset_value) {
+                       mmc_host_clk_hold(card->host);
                        host->ops->enable_preset_value(host, true);
+                       mmc_host_clk_release(card->host);
+               }
        } else {
                /*
                 * Attempt to change to high-speed (if supported)
@@ -1151,8 +1162,11 @@ int mmc_attach_sd(struct mmc_host *host)
                return err;
 
        /* Disable preset value enable if already set since last time */
-       if (host->ops->enable_preset_value)
+       if (host->ops->enable_preset_value) {
+               mmc_host_clk_hold(host);
                host->ops->enable_preset_value(host, false);
+               mmc_host_clk_release(host);
+       }
 
        err = mmc_send_app_op_cond(host, 0, &ocr);
        if (err)
index bd7bacc..12cde6e 100644 (file)
@@ -98,10 +98,11 @@ fail:
        return ret;
 }
 
-static int sdio_read_cccr(struct mmc_card *card)
+static int sdio_read_cccr(struct mmc_card *card, u32 ocr)
 {
        int ret;
        int cccr_vsn;
+       int uhs = ocr & R4_18V_PRESENT;
        unsigned char data;
        unsigned char speed;
 
@@ -149,7 +150,7 @@ static int sdio_read_cccr(struct mmc_card *card)
                card->scr.sda_spec3 = 0;
                card->sw_caps.sd3_bus_mode = 0;
                card->sw_caps.sd3_drv_type = 0;
-               if (cccr_vsn >= SDIO_CCCR_REV_3_00) {
+               if (cccr_vsn >= SDIO_CCCR_REV_3_00 && uhs) {
                        card->scr.sda_spec3 = 1;
                        ret = mmc_io_rw_direct(card, 0, 0,
                                SDIO_CCCR_UHS, 0, &data);
@@ -712,7 +713,7 @@ static int mmc_sdio_init_card(struct mmc_host *host, u32 ocr,
        /*
         * Read the common registers.
         */
-       err = sdio_read_cccr(card);
+       err = sdio_read_cccr(card, ocr);
        if (err)
                goto remove;
 
index 68f81b9..f573e7f 100644 (file)
@@ -146,15 +146,21 @@ static int sdio_irq_thread(void *_host)
                }
 
                set_current_state(TASK_INTERRUPTIBLE);
-               if (host->caps & MMC_CAP_SDIO_IRQ)
+               if (host->caps & MMC_CAP_SDIO_IRQ) {
+                       mmc_host_clk_hold(host);
                        host->ops->enable_sdio_irq(host, 1);
+                       mmc_host_clk_release(host);
+               }
                if (!kthread_should_stop())
                        schedule_timeout(period);
                set_current_state(TASK_RUNNING);
        } while (!kthread_should_stop());
 
-       if (host->caps & MMC_CAP_SDIO_IRQ)
+       if (host->caps & MMC_CAP_SDIO_IRQ) {
+               mmc_host_clk_hold(host);
                host->ops->enable_sdio_irq(host, 0);
+               mmc_host_clk_release(host);
+       }
 
        pr_debug("%s: IRQ thread exiting with code %d\n",
                 mmc_hostname(host), ret);
index cf444b0..00fcbed 100644 (file)
@@ -477,7 +477,6 @@ config MMC_SDHI
 config MMC_CB710
        tristate "ENE CB710 MMC/SD Interface support"
        depends on PCI
-       select MISC_DEVICES
        select CB710_CORE
        help
          This option enables support for MMC/SD part of ENE CB710/720 Flash
index fcfe1eb..6985cdb 100644 (file)
@@ -969,11 +969,14 @@ static void atmci_start_request(struct atmel_mci *host,
        host->data_status = 0;
 
        if (host->need_reset) {
+               iflags = atmci_readl(host, ATMCI_IMR);
+               iflags &= (ATMCI_SDIOIRQA | ATMCI_SDIOIRQB);
                atmci_writel(host, ATMCI_CR, ATMCI_CR_SWRST);
                atmci_writel(host, ATMCI_CR, ATMCI_CR_MCIEN);
                atmci_writel(host, ATMCI_MR, host->mode_reg);
                if (host->caps.has_cfg_reg)
                        atmci_writel(host, ATMCI_CFG, host->cfg_reg);
+               atmci_writel(host, ATMCI_IER, iflags);
                host->need_reset = false;
        }
        atmci_writel(host, ATMCI_SDCR, slot->sdc_reg);
index 0e34279..8bec1c3 100644 (file)
@@ -22,7 +22,6 @@
 #include <linux/ioport.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
-#include <linux/scatterlist.h>
 #include <linux/seq_file.h>
 #include <linux/slab.h>
 #include <linux/stat.h>
@@ -502,8 +501,14 @@ static void dw_mci_submit_data(struct dw_mci *host, struct mmc_data *data)
                host->dir_status = DW_MCI_SEND_STATUS;
 
        if (dw_mci_submit_data_dma(host, data)) {
+               int flags = SG_MITER_ATOMIC;
+               if (host->data->flags & MMC_DATA_READ)
+                       flags |= SG_MITER_TO_SG;
+               else
+                       flags |= SG_MITER_FROM_SG;
+
+               sg_miter_start(&host->sg_miter, data->sg, data->sg_len, flags);
                host->sg = data->sg;
-               host->pio_offset = 0;
                host->part_buf_start = 0;
                host->part_buf_count = 0;
 
@@ -972,6 +977,7 @@ static void dw_mci_tasklet_func(unsigned long priv)
                                 * generates a block interrupt, hence setting
                                 * the scatter-gather pointer to NULL.
                                 */
+                               sg_miter_stop(&host->sg_miter);
                                host->sg = NULL;
                                ctrl = mci_readl(host, CTRL);
                                ctrl |= SDMMC_CTRL_FIFO_RESET;
@@ -1311,54 +1317,44 @@ static void dw_mci_pull_data(struct dw_mci *host, void *buf, int cnt)
 
 static void dw_mci_read_data_pio(struct dw_mci *host)
 {
-       struct scatterlist *sg = host->sg;
-       void *buf = sg_virt(sg);
-       unsigned int offset = host->pio_offset;
+       struct sg_mapping_iter *sg_miter = &host->sg_miter;
+       void *buf;
+       unsigned int offset;
        struct mmc_data *data = host->data;
        int shift = host->data_shift;
        u32 status;
        unsigned int nbytes = 0, len;
+       unsigned int remain, fcnt;
 
        do {
-               len = host->part_buf_count +
-                       (SDMMC_GET_FCNT(mci_readl(host, STATUS)) << shift);
-               if (offset + len <= sg->length) {
+               if (!sg_miter_next(sg_miter))
+                       goto done;
+
+               host->sg = sg_miter->__sg;
+               buf = sg_miter->addr;
+               remain = sg_miter->length;
+               offset = 0;
+
+               do {
+                       fcnt = (SDMMC_GET_FCNT(mci_readl(host, STATUS))
+                                       << shift) + host->part_buf_count;
+                       len = min(remain, fcnt);
+                       if (!len)
+                               break;
                        dw_mci_pull_data(host, (void *)(buf + offset), len);
-
                        offset += len;
                        nbytes += len;
-
-                       if (offset == sg->length) {
-                               flush_dcache_page(sg_page(sg));
-                               host->sg = sg = sg_next(sg);
-                               if (!sg)
-                                       goto done;
-
-                               offset = 0;
-                               buf = sg_virt(sg);
-                       }
-               } else {
-                       unsigned int remaining = sg->length - offset;
-                       dw_mci_pull_data(host, (void *)(buf + offset),
-                                        remaining);
-                       nbytes += remaining;
-
-                       flush_dcache_page(sg_page(sg));
-                       host->sg = sg = sg_next(sg);
-                       if (!sg)
-                               goto done;
-
-                       offset = len - remaining;
-                       buf = sg_virt(sg);
-                       dw_mci_pull_data(host, buf, offset);
-                       nbytes += offset;
-               }
+                       remain -= len;
+               } while (remain);
+               sg_miter->consumed = offset;
 
                status = mci_readl(host, MINTSTS);
                mci_writel(host, RINTSTS, SDMMC_INT_RXDR);
                if (status & DW_MCI_DATA_ERROR_FLAGS) {
                        host->data_status = status;
                        data->bytes_xfered += nbytes;
+                       sg_miter_stop(sg_miter);
+                       host->sg = NULL;
                        smp_wmb();
 
                        set_bit(EVENT_DATA_ERROR, &host->pending_events);
@@ -1367,65 +1363,66 @@ static void dw_mci_read_data_pio(struct dw_mci *host)
                        return;
                }
        } while (status & SDMMC_INT_RXDR); /*if the RXDR is ready read again*/
-       host->pio_offset = offset;
        data->bytes_xfered += nbytes;
+
+       if (!remain) {
+               if (!sg_miter_next(sg_miter))
+                       goto done;
+               sg_miter->consumed = 0;
+       }
+       sg_miter_stop(sg_miter);
        return;
 
 done:
        data->bytes_xfered += nbytes;
+       sg_miter_stop(sg_miter);
+       host->sg = NULL;
        smp_wmb();
        set_bit(EVENT_XFER_COMPLETE, &host->pending_events);
 }
 
 static void dw_mci_write_data_pio(struct dw_mci *host)
 {
-       struct scatterlist *sg = host->sg;
-       void *buf = sg_virt(sg);
-       unsigned int offset = host->pio_offset;
+       struct sg_mapping_iter *sg_miter = &host->sg_miter;
+       void *buf;
+       unsigned int offset;
        struct mmc_data *data = host->data;
        int shift = host->data_shift;
        u32 status;
        unsigned int nbytes = 0, len;
+       unsigned int fifo_depth = host->fifo_depth;
+       unsigned int remain, fcnt;
 
        do {
-               len = ((host->fifo_depth -
-                       SDMMC_GET_FCNT(mci_readl(host, STATUS))) << shift)
-                       - host->part_buf_count;
-               if (offset + len <= sg->length) {
+               if (!sg_miter_next(sg_miter))
+                       goto done;
+
+               host->sg = sg_miter->__sg;
+               buf = sg_miter->addr;
+               remain = sg_miter->length;
+               offset = 0;
+
+               do {
+                       fcnt = ((fifo_depth -
+                                SDMMC_GET_FCNT(mci_readl(host, STATUS)))
+                                       << shift) - host->part_buf_count;
+                       len = min(remain, fcnt);
+                       if (!len)
+                               break;
                        host->push_data(host, (void *)(buf + offset), len);
-
                        offset += len;
                        nbytes += len;
-                       if (offset == sg->length) {
-                               host->sg = sg = sg_next(sg);
-                               if (!sg)
-                                       goto done;
-
-                               offset = 0;
-                               buf = sg_virt(sg);
-                       }
-               } else {
-                       unsigned int remaining = sg->length - offset;
-
-                       host->push_data(host, (void *)(buf + offset),
-                                       remaining);
-                       nbytes += remaining;
-
-                       host->sg = sg = sg_next(sg);
-                       if (!sg)
-                               goto done;
-
-                       offset = len - remaining;
-                       buf = sg_virt(sg);
-                       host->push_data(host, (void *)buf, offset);
-                       nbytes += offset;
-               }
+                       remain -= len;
+               } while (remain);
+               sg_miter->consumed = offset;
 
                status = mci_readl(host, MINTSTS);
                mci_writel(host, RINTSTS, SDMMC_INT_TXDR);
                if (status & DW_MCI_DATA_ERROR_FLAGS) {
                        host->data_status = status;
                        data->bytes_xfered += nbytes;
+                       sg_miter_stop(sg_miter);
+                       host->sg = NULL;
 
                        smp_wmb();
 
@@ -1435,12 +1432,20 @@ static void dw_mci_write_data_pio(struct dw_mci *host)
                        return;
                }
        } while (status & SDMMC_INT_TXDR); /* if TXDR write again */
-       host->pio_offset = offset;
        data->bytes_xfered += nbytes;
+
+       if (!remain) {
+               if (!sg_miter_next(sg_miter))
+                       goto done;
+               sg_miter->consumed = 0;
+       }
+       sg_miter_stop(sg_miter);
        return;
 
 done:
        data->bytes_xfered += nbytes;
+       sg_miter_stop(sg_miter);
+       host->sg = NULL;
        smp_wmb();
        set_bit(EVENT_XFER_COMPLETE, &host->pending_events);
 }
@@ -1643,6 +1648,7 @@ static void dw_mci_work_routine_card(struct work_struct *work)
                                 * block interrupt, hence setting the
                                 * scatter-gather pointer to NULL.
                                 */
+                               sg_miter_stop(&host->sg_miter);
                                host->sg = NULL;
 
                                ctrl = mci_readl(host, CTRL);
index ab66f24..1534b58 100644 (file)
@@ -113,8 +113,8 @@ struct mmc_spi_platform_data *mmc_spi_get_pdata(struct spi_device *spi)
                const int j = i * 2;
                u32 mask;
 
-               mask = mmc_vddrange_to_ocrmask(voltage_ranges[j],
-                                              voltage_ranges[j + 1]);
+               mask = mmc_vddrange_to_ocrmask(be32_to_cpu(voltage_ranges[j]),
+                                              be32_to_cpu(voltage_ranges[j + 1]));
                if (!mask) {
                        ret = -EINVAL;
                        dev_err(dev, "OF: voltage-range #%d is invalid\n", i);
index ff4adc0..5d876ff 100644 (file)
@@ -38,6 +38,23 @@ static u8 esdhc_readb(struct sdhci_host *host, int reg)
        int base = reg & ~0x3;
        int shift = (reg & 0x3) * 8;
        u8 ret = (in_be32(host->ioaddr + base) >> shift) & 0xff;
+
+       /*
+        * "DMA select" locates at offset 0x28 in SD specification, but on
+        * P5020 or P3041, it locates at 0x29.
+        */
+       if (reg == SDHCI_HOST_CONTROL) {
+               u32 dma_bits;
+
+               dma_bits = in_be32(host->ioaddr + reg);
+               /* DMA select is 22,23 bits in Protocol Control Register */
+               dma_bits = (dma_bits >> 5) & SDHCI_CTRL_DMA_MASK;
+
+               /* fixup the result */
+               ret &= ~SDHCI_CTRL_DMA_MASK;
+               ret |= dma_bits;
+       }
+
        return ret;
 }
 
@@ -56,6 +73,21 @@ static void esdhc_writew(struct sdhci_host *host, u16 val, int reg)
 
 static void esdhc_writeb(struct sdhci_host *host, u8 val, int reg)
 {
+       /*
+        * "DMA select" location is offset 0x28 in SD specification, but on
+        * P5020 or P3041, it's located at 0x29.
+        */
+       if (reg == SDHCI_HOST_CONTROL) {
+               u32 dma_bits;
+
+               /* DMA select is 22,23 bits in Protocol Control Register */
+               dma_bits = (val & SDHCI_CTRL_DMA_MASK) << 5;
+               clrsetbits_be32(host->ioaddr + reg , SDHCI_CTRL_DMA_MASK << 5,
+                       dma_bits);
+               val &= ~SDHCI_CTRL_DMA_MASK;
+               val |= in_be32(host->ioaddr + reg) & SDHCI_CTRL_DMA_MASK;
+       }
+
        /* Prevent SDHCI core from writing reserved bits (e.g. HISPD). */
        if (reg == SDHCI_HOST_CONTROL)
                val &= ~ESDHC_HOST_CONTROL_RES;
index 7165e6a..6ebdc40 100644 (file)
@@ -250,7 +250,7 @@ static int mfd_emmc_probe_slot(struct sdhci_pci_slot *slot)
 
 static int mfd_sdio_probe_slot(struct sdhci_pci_slot *slot)
 {
-       slot->host->mmc->caps |= MMC_CAP_POWER_OFF_CARD;
+       slot->host->mmc->caps |= MMC_CAP_POWER_OFF_CARD | MMC_CAP_NONREMOVABLE;
        return 0;
 }
 
index 03970bc..c5c2a48 100644 (file)
@@ -2,7 +2,7 @@
  * sdhci-pltfm.c Support for SDHCI platform devices
  * Copyright (c) 2009 Intel Corporation
  *
- * Copyright (c) 2007 Freescale Semiconductor, Inc.
+ * Copyright (c) 2007, 2011 Freescale Semiconductor, Inc.
  * Copyright (c) 2009 MontaVista Software, Inc.
  *
  * Authors: Xiaobo Xie <X.Xie@freescale.com>
@@ -71,6 +71,14 @@ void sdhci_get_of_property(struct platform_device *pdev)
                if (sdhci_of_wp_inverted(np))
                        host->quirks |= SDHCI_QUIRK_INVERTED_WRITE_PROTECT;
 
+               if (of_device_is_compatible(np, "fsl,p2020-rev1-esdhc"))
+                       host->quirks |= SDHCI_QUIRK_BROKEN_DMA;
+
+               if (of_device_is_compatible(np, "fsl,p2020-esdhc") ||
+                   of_device_is_compatible(np, "fsl,p1010-esdhc") ||
+                   of_device_is_compatible(np, "fsl,mpc8536-esdhc"))
+                       host->quirks |= SDHCI_QUIRK_BROKEN_TIMEOUT_VAL;
+
                clk = of_get_property(np, "clock-frequency", &size);
                if (clk && size == sizeof(*clk) && *clk)
                        pltfm_host->clock = be32_to_cpup(clk);
index f5d8b53..352d479 100644 (file)
@@ -1327,7 +1327,7 @@ static int __devinit sh_mmcif_probe(struct platform_device *pdev)
        if (ret < 0)
                goto clean_up2;
 
-       mmc_add_host(mmc);
+       INIT_DELAYED_WORK(&host->timeout_work, mmcif_timeout_work);
 
        sh_mmcif_writel(host->addr, MMCIF_CE_INT_MASK, MASK_ALL);
 
@@ -1338,22 +1338,24 @@ static int __devinit sh_mmcif_probe(struct platform_device *pdev)
        }
        ret = request_threaded_irq(irq[1], sh_mmcif_intr, sh_mmcif_irqt, 0, "sh_mmc:int", host);
        if (ret) {
-               free_irq(irq[0], host);
                dev_err(&pdev->dev, "request_irq error (sh_mmc:int)\n");
-               goto clean_up3;
+               goto clean_up4;
        }
 
-       INIT_DELAYED_WORK(&host->timeout_work, mmcif_timeout_work);
-
-       mmc_detect_change(host->mmc, 0);
+       ret = mmc_add_host(mmc);
+       if (ret < 0)
+               goto clean_up5;
 
        dev_info(&pdev->dev, "driver version %s\n", DRIVER_VERSION);
        dev_dbg(&pdev->dev, "chip ver H'%04x\n",
                sh_mmcif_readl(host->addr, MMCIF_CE_VERSION) & 0x0000ffff);
        return ret;
 
+clean_up5:
+       free_irq(irq[1], host);
+clean_up4:
+       free_irq(irq[0], host);
 clean_up3:
-       mmc_remove_host(mmc);
        pm_runtime_suspend(&pdev->dev);
 clean_up2:
        pm_runtime_disable(&pdev->dev);
index a95e6d9..f96c536 100644 (file)
@@ -20,8 +20,8 @@
 #include <linux/mmc/tmio.h>
 #include <linux/mutex.h>
 #include <linux/pagemap.h>
-#include <linux/spinlock.h>
 #include <linux/scatterlist.h>
+#include <linux/spinlock.h>
 
 /* Definitions for values the CTRL_SDIO_STATUS register can take. */
 #define TMIO_SDIO_STAT_IOIRQ   0x0001
@@ -120,6 +120,7 @@ void tmio_mmc_start_dma(struct tmio_mmc_host *host, struct mmc_data *data);
 void tmio_mmc_enable_dma(struct tmio_mmc_host *host, bool enable);
 void tmio_mmc_request_dma(struct tmio_mmc_host *host, struct tmio_mmc_data *pdata);
 void tmio_mmc_release_dma(struct tmio_mmc_host *host);
+void tmio_mmc_abort_dma(struct tmio_mmc_host *host);
 #else
 static inline void tmio_mmc_start_dma(struct tmio_mmc_host *host,
                               struct mmc_data *data)
@@ -140,6 +141,10 @@ static inline void tmio_mmc_request_dma(struct tmio_mmc_host *host,
 static inline void tmio_mmc_release_dma(struct tmio_mmc_host *host)
 {
 }
+
+static inline void tmio_mmc_abort_dma(struct tmio_mmc_host *host)
+{
+}
 #endif
 
 #ifdef CONFIG_PM
index 7a6e6cc..8253ec1 100644 (file)
@@ -34,6 +34,18 @@ void tmio_mmc_enable_dma(struct tmio_mmc_host *host, bool enable)
 #endif
 }
 
+void tmio_mmc_abort_dma(struct tmio_mmc_host *host)
+{
+       tmio_mmc_enable_dma(host, false);
+
+       if (host->chan_rx)
+               dmaengine_terminate_all(host->chan_rx);
+       if (host->chan_tx)
+               dmaengine_terminate_all(host->chan_tx);
+
+       tmio_mmc_enable_dma(host, true);
+}
+
 static void tmio_mmc_start_dma_rx(struct tmio_mmc_host *host)
 {
        struct scatterlist *sg = host->sg_ptr, *sg_tmp;
index abad01b..5f9ad74 100644 (file)
@@ -41,8 +41,8 @@
 #include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
 #include <linux/scatterlist.h>
-#include <linux/workqueue.h>
 #include <linux/spinlock.h>
+#include <linux/workqueue.h>
 
 #include "tmio_mmc.h"
 
@@ -246,6 +246,7 @@ static void tmio_mmc_reset_work(struct work_struct *work)
        /* Ready for new calls */
        host->mrq = NULL;
 
+       tmio_mmc_abort_dma(host);
        mmc_request_done(host->mmc, mrq);
 }
 
@@ -272,6 +273,9 @@ static void tmio_mmc_finish_request(struct tmio_mmc_host *host)
        host->mrq = NULL;
        spin_unlock_irqrestore(&host->lock, flags);
 
+       if (mrq->cmd->error || (mrq->data && mrq->data->error))
+               tmio_mmc_abort_dma(host);
+
        mmc_request_done(host->mmc, mrq);
 }
 
index 6ae9ca0..9a9ce71 100644 (file)
@@ -119,7 +119,7 @@ static int mtd_cls_suspend(struct device *dev, pm_message_t state)
 {
        struct mtd_info *mtd = dev_get_drvdata(dev);
 
-       return mtd_suspend(mtd);
+       return mtd ? mtd_suspend(mtd) : 0;
 }
 
 static int mtd_cls_resume(struct device *dev)
index 4dd056e..35b4fb5 100644 (file)
@@ -161,6 +161,37 @@ static int atmel_nand_device_ready(struct mtd_info *mtd)
                 !!host->board->rdy_pin_active_low;
 }
 
+/*
+ * Minimal-overhead PIO for data access.
+ */
+static void atmel_read_buf8(struct mtd_info *mtd, u8 *buf, int len)
+{
+       struct nand_chip        *nand_chip = mtd->priv;
+
+       __raw_readsb(nand_chip->IO_ADDR_R, buf, len);
+}
+
+static void atmel_read_buf16(struct mtd_info *mtd, u8 *buf, int len)
+{
+       struct nand_chip        *nand_chip = mtd->priv;
+
+       __raw_readsw(nand_chip->IO_ADDR_R, buf, len / 2);
+}
+
+static void atmel_write_buf8(struct mtd_info *mtd, const u8 *buf, int len)
+{
+       struct nand_chip        *nand_chip = mtd->priv;
+
+       __raw_writesb(nand_chip->IO_ADDR_W, buf, len);
+}
+
+static void atmel_write_buf16(struct mtd_info *mtd, const u8 *buf, int len)
+{
+       struct nand_chip        *nand_chip = mtd->priv;
+
+       __raw_writesw(nand_chip->IO_ADDR_W, buf, len / 2);
+}
+
 static void dma_complete_func(void *completion)
 {
        complete(completion);
@@ -235,27 +266,33 @@ err_buf:
 static void atmel_read_buf(struct mtd_info *mtd, u8 *buf, int len)
 {
        struct nand_chip *chip = mtd->priv;
+       struct atmel_nand_host *host = chip->priv;
 
        if (use_dma && len > mtd->oobsize)
                /* only use DMA for bigger than oob size: better performances */
                if (atmel_nand_dma_op(mtd, buf, len, 1) == 0)
                        return;
 
-       /* if no DMA operation possible, use PIO */
-       memcpy_fromio(buf, chip->IO_ADDR_R, len);
+       if (host->board->bus_width_16)
+               atmel_read_buf16(mtd, buf, len);
+       else
+               atmel_read_buf8(mtd, buf, len);
 }
 
 static void atmel_write_buf(struct mtd_info *mtd, const u8 *buf, int len)
 {
        struct nand_chip *chip = mtd->priv;
+       struct atmel_nand_host *host = chip->priv;
 
        if (use_dma && len > mtd->oobsize)
                /* only use DMA for bigger than oob size: better performances */
                if (atmel_nand_dma_op(mtd, (void *)buf, len, 0) == 0)
                        return;
 
-       /* if no DMA operation possible, use PIO */
-       memcpy_toio(chip->IO_ADDR_W, buf, len);
+       if (host->board->bus_width_16)
+               atmel_write_buf16(mtd, buf, len);
+       else
+               atmel_write_buf8(mtd, buf, len);
 }
 
 /*
index 7f68042..7db6555 100644 (file)
@@ -69,17 +69,19 @@ static int clear_poll_bit(void __iomem *addr, u32 mask)
  *  [1] enable the module.
  *  [2] reset the module.
  *
- * In most of the cases, it's ok. But there is a hardware bug in the BCH block.
+ * In most of the cases, it's ok.
+ * But in MX23, there is a hardware bug in the BCH block (see erratum #2847).
  * If you try to soft reset the BCH block, it becomes unusable until
  * the next hard reset. This case occurs in the NAND boot mode. When the board
  * boots by NAND, the ROM of the chip will initialize the BCH blocks itself.
  * So If the driver tries to reset the BCH again, the BCH will not work anymore.
- * You will see a DMA timeout in this case.
+ * You will see a DMA timeout in this case. The bug has been fixed
+ * in the following chips, such as MX28.
  *
  * To avoid this bug, just add a new parameter `just_enable` for
  * the mxs_reset_block(), and rewrite it here.
  */
-int gpmi_reset_block(void __iomem *reset_addr, bool just_enable)
+static int gpmi_reset_block(void __iomem *reset_addr, bool just_enable)
 {
        int ret;
        int timeout = 0x400;
@@ -206,7 +208,15 @@ int bch_set_geometry(struct gpmi_nand_data *this)
        if (ret)
                goto err_out;
 
-       ret = gpmi_reset_block(r->bch_regs, true);
+       /*
+       * Due to erratum #2847 of the MX23, the BCH cannot be soft reset on this
+       * chip, otherwise it will lock up. So we skip resetting BCH on the MX23.
+       * On the other hand, the MX28 needs the reset, because one case has been
+       * seen where the BCH produced ECC errors constantly after 10000
+       * consecutive reboots. The latter case has not been seen on the MX23 yet,
+       * still we don't know if it could happen there as well.
+       */
+       ret = gpmi_reset_block(r->bch_regs, GPMI_IS_MX23(this));
        if (ret)
                goto err_out;
 
index 35b4565..8a393f9 100644 (file)
@@ -2588,7 +2588,7 @@ int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr,
        instr->state = MTD_ERASING;
 
        while (len) {
-               /* Heck if we have a bad block, we do not erase bad blocks! */
+               /* Check if we have a bad block, we do not erase bad blocks! */
                if (nand_block_checkbad(mtd, ((loff_t) page) <<
                                        chip->page_shift, 0, allowbbt)) {
                        pr_warn("%s: attempt to erase a bad block at page 0x%08x\n",
index 7668967..c30f0e6 100644 (file)
@@ -440,12 +440,14 @@ static netdev_tx_t cc770_start_xmit(struct sk_buff *skb, struct net_device *dev)
        for (i = 0; i < dlc; i++)
                cc770_write_reg(priv, msgobj[mo].data[i], cf->data[i]);
 
+       /* Store echo skb before starting the transfer */
+       can_put_echo_skb(skb, dev, 0);
+
        cc770_write_reg(priv, msgobj[mo].ctrl1,
                        RMTPND_RES | TXRQST_SET | CPUUPD_RES | NEWDAT_UNC);
 
        stats->tx_bytes += dlc;
 
-       can_put_echo_skb(skb, dev, 0);
 
        /*
         * HM: We had some cases of repeated IRQs so make sure the
index 4be5fe2..9f3a25c 100644 (file)
@@ -110,6 +110,11 @@ MODULE_PARM_DESC(bcr, "Bus configuration register (default=0x40 [CBY])");
 #define CC770_IOSIZE          0x20
 #define CC770_IOSIZE_INDIRECT 0x02
 
+/* Spinlock for cc770_isa_port_write_reg_indirect
+ * and cc770_isa_port_read_reg_indirect
+ */
+static DEFINE_SPINLOCK(cc770_isa_port_lock);
+
 static struct platform_device *cc770_isa_devs[MAXDEV];
 
 static u8 cc770_isa_mem_read_reg(const struct cc770_priv *priv, int reg)
@@ -138,18 +143,27 @@ static u8 cc770_isa_port_read_reg_indirect(const struct cc770_priv *priv,
                                             int reg)
 {
        unsigned long base = (unsigned long)priv->reg_base;
+       unsigned long flags;
+       u8 val;
 
+       spin_lock_irqsave(&cc770_isa_port_lock, flags);
        outb(reg, base);
-       return inb(base + 1);
+       val = inb(base + 1);
+       spin_unlock_irqrestore(&cc770_isa_port_lock, flags);
+
+       return val;
 }
 
 static void cc770_isa_port_write_reg_indirect(const struct cc770_priv *priv,
                                                int reg, u8 val)
 {
        unsigned long base = (unsigned long)priv->reg_base;
+       unsigned long flags;
 
+       spin_lock_irqsave(&cc770_isa_port_lock, flags);
        outb(reg, base);
        outb(val, base + 1);
+       spin_unlock_irqrestore(&cc770_isa_port_lock, flags);
 }
 
 static int __devinit cc770_isa_probe(struct platform_device *pdev)
index 7fd8089..96d2357 100644 (file)
        (FLEXCAN_ESR_TWRN_INT | FLEXCAN_ESR_RWRN_INT | FLEXCAN_ESR_BOFF_INT)
 #define FLEXCAN_ESR_ERR_ALL \
        (FLEXCAN_ESR_ERR_BUS | FLEXCAN_ESR_ERR_STATE)
+#define FLEXCAN_ESR_ALL_INT \
+       (FLEXCAN_ESR_TWRN_INT | FLEXCAN_ESR_RWRN_INT | \
+        FLEXCAN_ESR_BOFF_INT | FLEXCAN_ESR_ERR_INT)
 
 /* FLEXCAN interrupt flag register (IFLAG) bits */
 #define FLEXCAN_TX_BUF_ID              8
@@ -577,7 +580,9 @@ static irqreturn_t flexcan_irq(int irq, void *dev_id)
 
        reg_iflag1 = flexcan_read(&regs->iflag1);
        reg_esr = flexcan_read(&regs->esr);
-       flexcan_write(FLEXCAN_ESR_ERR_INT, &regs->esr); /* ACK err IRQ */
+       /* ACK all bus error and state change IRQ sources */
+       if (reg_esr & FLEXCAN_ESR_ALL_INT)
+               flexcan_write(reg_esr & FLEXCAN_ESR_ALL_INT, &regs->esr);
 
        /*
         * schedule NAPI in case of:
index d11fbb2..6edc25e 100644 (file)
@@ -66,6 +66,7 @@
 #define PCH_IF_CREQ_BUSY       BIT(15)
 
 #define PCH_STATUS_INT         0x8000
+#define PCH_RP                 0x00008000
 #define PCH_REC                        0x00007f00
 #define PCH_TEC                        0x000000ff
 
@@ -527,7 +528,7 @@ static void pch_can_error(struct net_device *ndev, u32 status)
                priv->can.can_stats.error_passive++;
                state = CAN_STATE_ERROR_PASSIVE;
                cf->can_id |= CAN_ERR_CRTL;
-               if (((errc & PCH_REC) >> 8) > 127)
+               if (errc & PCH_RP)
                        cf->data[1] |= CAN_ERR_CRTL_RX_PASSIVE;
                if ((errc & PCH_TEC) > 127)
                        cf->data[1] |= CAN_ERR_CRTL_TX_PASSIVE;
index 2c7f503..2147959 100644 (file)
@@ -39,9 +39,9 @@ MODULE_LICENSE("GPL v2");
 #define DRV_NAME  "peak_pci"
 
 struct peak_pci_chan {
-       void __iomem *cfg_base;      /* Common for all channels */
-       struct net_device *next_dev; /* Chain of network devices */
-       u16 icr_mask;                /* Interrupt mask for fast ack */
+       void __iomem *cfg_base;         /* Common for all channels */
+       struct net_device *prev_dev;    /* Chain of network devices */
+       u16 icr_mask;                   /* Interrupt mask for fast ack */
 };
 
 #define PEAK_PCI_CAN_CLOCK     (16000000 / 2)
@@ -98,7 +98,7 @@ static int __devinit peak_pci_probe(struct pci_dev *pdev,
 {
        struct sja1000_priv *priv;
        struct peak_pci_chan *chan;
-       struct net_device *dev, *dev0 = NULL;
+       struct net_device *dev;
        void __iomem *cfg_base, *reg_base;
        u16 sub_sys_id, icr;
        int i, err, channels;
@@ -196,18 +196,14 @@ static int __devinit peak_pci_probe(struct pci_dev *pdev,
                }
 
                /* Create chain of SJA1000 devices */
-               if (i == 0)
-                       dev0 = dev;
-               else
-                       chan->next_dev = dev;
+               chan->prev_dev = pci_get_drvdata(pdev);
+               pci_set_drvdata(pdev, dev);
 
                dev_info(&pdev->dev,
                         "%s at reg_base=0x%p cfg_base=0x%p irq=%d\n",
                         dev->name, priv->reg_base, chan->cfg_base, dev->irq);
        }
 
-       pci_set_drvdata(pdev, dev0);
-
        /* Enable interrupts */
        writew(icr, cfg_base + PITA_ICR + 2);
 
@@ -217,12 +213,11 @@ failure_remove_channels:
        /* Disable interrupts */
        writew(0x0, cfg_base + PITA_ICR + 2);
 
-       for (dev = dev0; dev; dev = chan->next_dev) {
+       for (dev = pci_get_drvdata(pdev); dev; dev = chan->prev_dev) {
                unregister_sja1000dev(dev);
                free_sja1000dev(dev);
                priv = netdev_priv(dev);
                chan = priv->priv;
-               dev = chan->next_dev;
        }
 
        pci_iounmap(pdev, reg_base);
@@ -241,7 +236,7 @@ failure_disable_pci:
 
 static void __devexit peak_pci_remove(struct pci_dev *pdev)
 {
-       struct net_device *dev = pci_get_drvdata(pdev); /* First device */
+       struct net_device *dev = pci_get_drvdata(pdev); /* Last device */
        struct sja1000_priv *priv = netdev_priv(dev);
        struct peak_pci_chan *chan = priv->priv;
        void __iomem *cfg_base = chan->cfg_base;
@@ -255,7 +250,7 @@ static void __devexit peak_pci_remove(struct pci_dev *pdev)
                dev_info(&pdev->dev, "removing device %s\n", dev->name);
                unregister_sja1000dev(dev);
                free_sja1000dev(dev);
-               dev = chan->next_dev;
+               dev = chan->prev_dev;
                if (!dev)
                        break;
                priv = netdev_priv(dev);
index df809e3..5a2e1e3 100644 (file)
@@ -745,9 +745,10 @@ static int ti_hecc_error(struct net_device *ndev, int int_status,
                }
        }
 
-       netif_receive_skb(skb);
+       netif_rx(skb);
        stats->rx_packets++;
        stats->rx_bytes += cf->can_dlc;
+
        return 0;
 }
 
index 9697c14..7dae64d 100644 (file)
@@ -627,9 +627,6 @@ static int ems_usb_start(struct ems_usb *dev)
 
                err = usb_submit_urb(urb, GFP_KERNEL);
                if (err) {
-                       if (err == -ENODEV)
-                               netif_device_detach(dev->netdev);
-
                        usb_unanchor_urb(urb);
                        usb_free_coherent(dev->udev, RX_BUFFER_SIZE, buf,
                                          urb->transfer_dma);
@@ -659,9 +656,6 @@ static int ems_usb_start(struct ems_usb *dev)
 
        err = usb_submit_urb(dev->intr_urb, GFP_KERNEL);
        if (err) {
-               if (err == -ENODEV)
-                       netif_device_detach(dev->netdev);
-
                dev_warn(netdev->dev.parent, "intr URB submit failed: %d\n",
                         err);
 
@@ -692,9 +686,6 @@ static int ems_usb_start(struct ems_usb *dev)
        return 0;
 
 failed:
-       if (err == -ENODEV)
-               netif_device_detach(dev->netdev);
-
        dev_warn(netdev->dev.parent, "couldn't submit control: %d\n", err);
 
        return err;
index 03f3935..7aee469 100644 (file)
@@ -523,7 +523,6 @@ static void bnx2x_tpa_stop(struct bnx2x *bp, struct bnx2x_fastpath *fp,
                skb = build_skb(data);
 
        if (likely(skb)) {
-
 #ifdef BNX2X_STOP_ON_ERROR
                if (pad + len > fp->rx_buf_size) {
                        BNX2X_ERR("skb_put is about to fail...  "
@@ -557,7 +556,7 @@ static void bnx2x_tpa_stop(struct bnx2x *bp, struct bnx2x_fastpath *fp,
 
                return;
        }
-
+       kfree(new_data);
 drop:
        /* drop the packet and keep the buffer in the bin */
        DP(NETIF_MSG_RX_STATUS,
index 9b44ec8..803ea32 100644 (file)
@@ -946,7 +946,7 @@ bnad_get_flash_partition_by_offset(struct bnad *bnad, u32 offset,
 
        flash_attr = kzalloc(sizeof(struct bfa_flash_attr), GFP_KERNEL);
        if (!flash_attr)
-               return -ENOMEM;
+               return 0;
 
        fcomp.bnad = bnad;
        fcomp.comp_status = 0;
@@ -958,7 +958,7 @@ bnad_get_flash_partition_by_offset(struct bnad *bnad, u32 offset,
        if (ret != BFA_STATUS_OK) {
                spin_unlock_irqrestore(&bnad->bna_lock, flags);
                kfree(flash_attr);
-               goto out_err;
+               return 0;
        }
        spin_unlock_irqrestore(&bnad->bna_lock, flags);
        wait_for_completion(&fcomp.comp);
@@ -978,8 +978,6 @@ bnad_get_flash_partition_by_offset(struct bnad *bnad, u32 offset,
        }
        kfree(flash_attr);
        return flash_part;
-out_err:
-       return -EINVAL;
 }
 
 static int
@@ -1006,7 +1004,7 @@ bnad_get_eeprom(struct net_device *netdev, struct ethtool_eeprom *eeprom,
        /* Query the flash partition based on the offset */
        flash_part = bnad_get_flash_partition_by_offset(bnad,
                                eeprom->offset, &base_offset);
-       if (flash_part <= 0)
+       if (flash_part == 0)
                return -EFAULT;
 
        fcomp.bnad = bnad;
@@ -1048,7 +1046,7 @@ bnad_set_eeprom(struct net_device *netdev, struct ethtool_eeprom *eeprom,
        /* Query the flash partition based on the offset */
        flash_part = bnad_get_flash_partition_by_offset(bnad,
                                eeprom->offset, &base_offset);
-       if (flash_part <= 0)
+       if (flash_part == 0)
                return -EFAULT;
 
        fcomp.bnad = bnad;
index 6db6b6a..802e5dd 100644 (file)
@@ -716,12 +716,8 @@ static int
 be_do_flash(struct net_device *netdev, struct ethtool_flash *efl)
 {
        struct be_adapter *adapter = netdev_priv(netdev);
-       char file_name[ETHTOOL_FLASH_MAX_FILENAME];
 
-       file_name[ETHTOOL_FLASH_MAX_FILENAME - 1] = 0;
-       strcpy(file_name, efl->data);
-
-       return be_load_fw(adapter, file_name);
+       return be_load_fw(adapter, efl->data);
 }
 
 static int
index 7b25e9c..1c7aad8 100644 (file)
@@ -990,7 +990,7 @@ static int fec_enet_mii_probe(struct net_device *ndev)
                phy_id = 0;
        }
 
-       snprintf(phy_name, MII_BUS_ID_SIZE, PHY_ID_FMT, mdio_bus_id, phy_id);
+       snprintf(phy_name, sizeof(phy_name), PHY_ID_FMT, mdio_bus_id, phy_id);
        phy_dev = phy_connect(ndev, phy_name, &fec_enet_adjust_link, 0,
                              fep->phy_interface);
        if (IS_ERR(phy_dev)) {
index 669ca38..d94d64b 100644 (file)
@@ -4740,12 +4740,14 @@ static int __e1000_shutdown(struct pci_dev *pdev, bool *enable_wake)
                e1000_setup_rctl(adapter);
                e1000_set_rx_mode(netdev);
 
+               rctl = er32(RCTL);
+
                /* turn on all-multi mode if wake on multicast is enabled */
-               if (wufc & E1000_WUFC_MC) {
-                       rctl = er32(RCTL);
+               if (wufc & E1000_WUFC_MC)
                        rctl |= E1000_RCTL_MPE;
-                       ew32(RCTL, rctl);
-               }
+
+               /* enable receives in the hardware */
+               ew32(RCTL, rctl | E1000_RCTL_EN);
 
                if (hw->mac_type >= e1000_82540) {
                        ctrl = er32(CTRL);
index e91d73c..94be6c3 100644 (file)
@@ -5012,7 +5012,8 @@ static int igb_find_enabled_vfs(struct igb_adapter *adapter)
        vf_devfn = pdev->devfn + 0x80;
        pvfdev = pci_get_device(hw->vendor_id, device_id, NULL);
        while (pvfdev) {
-               if (pvfdev->devfn == vf_devfn)
+               if (pvfdev->devfn == vf_devfn &&
+                   (pvfdev->bus->number >= pdev->bus->number))
                        vfs_found++;
                vf_devfn += vf_stride;
                pvfdev = pci_get_device(hw->vendor_id,
index 0fa3db3..044b0ad 100644 (file)
@@ -1,7 +1,7 @@
 ################################################################################
 #
 # Intel(R) 82576 Virtual Function Linux driver
-# Copyright(c) 2009 - 2010 Intel Corporation.
+# Copyright(c) 2009 - 2012 Intel Corporation.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms and conditions of the GNU General Public License,
index 79f2604..33f40d3 100644 (file)
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel(R) 82576 Virtual Function Linux driver
-  Copyright(c) 1999 - 2010 Intel Corporation.
+  Copyright(c) 1999 - 2012 Intel Corporation.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms and conditions of the GNU General Public License,
index 2dba534..db7dce2 100644 (file)
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel(R) 82576 Virtual Function Linux driver
-  Copyright(c) 2009 - 2010 Intel Corporation.
+  Copyright(c) 2009 - 2012 Intel Corporation.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms and conditions of the GNU General Public License,
index fd4a7b7..2c6d87e 100644 (file)
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel(R) 82576 Virtual Function Linux driver
-  Copyright(c) 2009 - 2010 Intel Corporation.
+  Copyright(c) 2009 - 2012 Intel Corporation.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms and conditions of the GNU General Public License,
index 048aae2..b4b65bc 100644 (file)
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel(R) 82576 Virtual Function Linux driver
-  Copyright(c) 2009 - 2010 Intel Corporation.
+  Copyright(c) 2009 - 2012 Intel Corporation.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms and conditions of the GNU General Public License,
index c2883c4..24370bc 100644 (file)
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel(R) 82576 Virtual Function Linux driver
-  Copyright(c) 1999 - 2010 Intel Corporation.
+  Copyright(c) 1999 - 2012 Intel Corporation.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms and conditions of the GNU General Public License,
index a4b20c8..4e9141c 100644 (file)
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel(R) 82576 Virtual Function Linux driver
-  Copyright(c) 2009 - 2010 Intel Corporation.
+  Copyright(c) 2009 - 2012 Intel Corporation.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms and conditions of the GNU General Public License,
@@ -53,7 +53,7 @@ const char igbvf_driver_version[] = DRV_VERSION;
 static const char igbvf_driver_string[] =
                  "Intel(R) Gigabit Virtual Function Network Driver";
 static const char igbvf_copyright[] =
-                 "Copyright (c) 2009 - 2011 Intel Corporation.";
+                 "Copyright (c) 2009 - 2012 Intel Corporation.";
 
 static int igbvf_poll(struct napi_struct *napi, int budget);
 static void igbvf_reset(struct igbvf_adapter *);
index 77e18d3..7dc6341 100644 (file)
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel(R) 82576 Virtual Function Linux driver
-  Copyright(c) 2009 - 2010 Intel Corporation.
+  Copyright(c) 2009 - 2012 Intel Corporation.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms and conditions of the GNU General Public License,
index af3822f..1955197 100644 (file)
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel(R) 82576 Virtual Function Linux driver
-  Copyright(c) 2009 - 2010 Intel Corporation.
+  Copyright(c) 2009 - 2012 Intel Corporation.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms and conditions of the GNU General Public License,
index d7ed58f..57db3c6 100644 (file)
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel(R) 82576 Virtual Function Linux driver
-  Copyright(c) 2009 - 2010 Intel Corporation.
+  Copyright(c) 2009 - 2012 Intel Corporation.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms and conditions of the GNU General Public License,
index 7d7387f..7a16177 100644 (file)
@@ -1,7 +1,7 @@
 ################################################################################
 #
 # Intel 10 Gigabit PCI Express Linux driver
-# Copyright(c) 1999 - 2010 Intel Corporation.
+# Copyright(c) 1999 - 2012 Intel Corporation.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms and conditions of the GNU General Public License,
index 258164d..e6aeb64 100644 (file)
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel 10 Gigabit PCI Express Linux driver
-  Copyright(c) 1999 - 2011 Intel Corporation.
+  Copyright(c) 1999 - 2012 Intel Corporation.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms and conditions of the GNU General Public License,
index ef2afef..b406c36 100644 (file)
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel 10 Gigabit PCI Express Linux driver
-  Copyright(c) 1999 - 2011 Intel Corporation.
+  Copyright(c) 1999 - 2012 Intel Corporation.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms and conditions of the GNU General Public License,
index 7720721..4e59083 100644 (file)
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel 10 Gigabit PCI Express Linux driver
-  Copyright(c) 1999 - 2011 Intel Corporation.
+  Copyright(c) 1999 - 2012 Intel Corporation.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms and conditions of the GNU General Public License,
index a3aa633..383b941 100644 (file)
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel 10 Gigabit PCI Express Linux driver
-  Copyright(c) 1999 - 2011 Intel Corporation.
+  Copyright(c) 1999 - 2012 Intel Corporation.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms and conditions of the GNU General Public License,
index 863f9c1..2c834c4 100644 (file)
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel 10 Gigabit PCI Express Linux driver
-  Copyright(c) 1999 - 2011 Intel Corporation.
+  Copyright(c) 1999 - 2012 Intel Corporation.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms and conditions of the GNU General Public License,
@@ -75,7 +75,7 @@ s32 ixgbe_update_mc_addr_list_generic(struct ixgbe_hw *hw,
 s32 ixgbe_enable_mc_generic(struct ixgbe_hw *hw);
 s32 ixgbe_disable_mc_generic(struct ixgbe_hw *hw);
 s32 ixgbe_enable_rx_dma_generic(struct ixgbe_hw *hw, u32 regval);
-s32 ixgbe_fc_enable_generic(struct ixgbe_hw *hw, s32 packtetbuf_num);
+s32 ixgbe_fc_enable_generic(struct ixgbe_hw *hw, s32 packetbuf_num);
 s32 ixgbe_fc_autoneg(struct ixgbe_hw *hw);
 
 s32 ixgbe_validate_mac_addr(u8 *mac_addr);
index 318caf4..8bfaaee 100644 (file)
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel 10 Gigabit PCI Express Linux driver
-  Copyright(c) 1999 - 2011 Intel Corporation.
+  Copyright(c) 1999 - 2012 Intel Corporation.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms and conditions of the GNU General Public License,
index e162775..24333b7 100644 (file)
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel 10 Gigabit PCI Express Linux driver
-  Copyright(c) 1999 - 2011 Intel Corporation.
+  Copyright(c) 1999 - 2012 Intel Corporation.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms and conditions of the GNU General Public License,
index fcd0e47..d3695ed 100644 (file)
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel 10 Gigabit PCI Express Linux driver
-  Copyright(c) 1999 - 2011 Intel Corporation.
+  Copyright(c) 1999 - 2012 Intel Corporation.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms and conditions of the GNU General Public License,
index 2f31893..ba83570 100644 (file)
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel 10 Gigabit PCI Express Linux driver
-  Copyright(c) 1999 - 2011 Intel Corporation.
+  Copyright(c) 1999 - 2012 Intel Corporation.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms and conditions of the GNU General Public License,
index 32cd97b..888a419 100644 (file)
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel 10 Gigabit PCI Express Linux driver
-  Copyright(c) 1999 - 2011 Intel Corporation.
+  Copyright(c) 1999 - 2012 Intel Corporation.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms and conditions of the GNU General Public License,
index a59d5dc..4dec47f 100644 (file)
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel 10 Gigabit PCI Express Linux driver
-  Copyright(c) 1999 - 2011 Intel Corporation.
+  Copyright(c) 1999 - 2012 Intel Corporation.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms and conditions of the GNU General Public License,
index da31735..79a92fe 100644 (file)
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel 10 Gigabit PCI Express Linux driver
-  Copyright(c) 1999 - 2011 Intel Corporation.
+  Copyright(c) 1999 - 2012 Intel Corporation.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms and conditions of the GNU General Public License,
@@ -112,6 +112,8 @@ static u8 ixgbe_dcbnl_get_state(struct net_device *netdev)
 static u8 ixgbe_dcbnl_set_state(struct net_device *netdev, u8 state)
 {
        u8 err = 0;
+       u8 prio_tc[MAX_USER_PRIORITY] = {0};
+       int i;
        struct ixgbe_adapter *adapter = netdev_priv(netdev);
 
        /* Fail command if not in CEE mode */
@@ -122,10 +124,15 @@ static u8 ixgbe_dcbnl_set_state(struct net_device *netdev, u8 state)
        if (!!state != !(adapter->flags & IXGBE_FLAG_DCB_ENABLED))
                return err;
 
-       if (state > 0)
+       if (state > 0) {
                err = ixgbe_setup_tc(netdev, adapter->dcb_cfg.num_tcs.pg_tcs);
-       else
+               ixgbe_dcb_unpack_map(&adapter->dcb_cfg, DCB_TX_CONFIG, prio_tc);
+       } else {
                err = ixgbe_setup_tc(netdev, 0);
+       }
+
+       for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++)
+               netdev_set_prio_tc_map(netdev, i, prio_tc[i]);
 
        return err;
 }
index da7e580..a629754 100644 (file)
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel 10 Gigabit PCI Express Linux driver
-  Copyright(c) 1999 - 2011 Intel Corporation.
+  Copyright(c) 1999 - 2012 Intel Corporation.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms and conditions of the GNU General Public License,
@@ -58,7 +58,7 @@ struct ixgbe_stats {
                                sizeof(((struct rtnl_link_stats64 *)0)->m), \
                                offsetof(struct rtnl_link_stats64, m)
 
-static struct ixgbe_stats ixgbe_gstrings_stats[] = {
+static const struct ixgbe_stats ixgbe_gstrings_stats[] = {
        {"rx_packets", IXGBE_NETDEV_STAT(rx_packets)},
        {"tx_packets", IXGBE_NETDEV_STAT(tx_packets)},
        {"rx_bytes", IXGBE_NETDEV_STAT(rx_bytes)},
@@ -120,19 +120,23 @@ static struct ixgbe_stats ixgbe_gstrings_stats[] = {
 #endif /* IXGBE_FCOE */
 };
 
-#define IXGBE_QUEUE_STATS_LEN \
-       ((((struct ixgbe_adapter *)netdev_priv(netdev))->num_tx_queues + \
-       ((struct ixgbe_adapter *)netdev_priv(netdev))->num_rx_queues) * \
+/* ixgbe allocates num_tx_queues and num_rx_queues symmetrically so
+ * we set the num_rx_queues to evaluate to num_tx_queues. This is
+ * used because we do not have a good way to get the max number of
+ * rx queues with CONFIG_RPS disabled.
+ */
+#define IXGBE_NUM_RX_QUEUES netdev->num_tx_queues
+
+#define IXGBE_QUEUE_STATS_LEN ( \
+       (netdev->num_tx_queues + IXGBE_NUM_RX_QUEUES) * \
        (sizeof(struct ixgbe_queue_stats) / sizeof(u64)))
 #define IXGBE_GLOBAL_STATS_LEN ARRAY_SIZE(ixgbe_gstrings_stats)
 #define IXGBE_PB_STATS_LEN ( \
-                 (((struct ixgbe_adapter *)netdev_priv(netdev))->flags & \
-                 IXGBE_FLAG_DCB_ENABLED) ? \
-                 (sizeof(((struct ixgbe_adapter *)0)->stats.pxonrxc) + \
-                  sizeof(((struct ixgbe_adapter *)0)->stats.pxontxc) + \
-                  sizeof(((struct ixgbe_adapter *)0)->stats.pxoffrxc) + \
-                  sizeof(((struct ixgbe_adapter *)0)->stats.pxofftxc)) \
-                  / sizeof(u64) : 0)
+                       (sizeof(((struct ixgbe_adapter *)0)->stats.pxonrxc) + \
+                        sizeof(((struct ixgbe_adapter *)0)->stats.pxontxc) + \
+                        sizeof(((struct ixgbe_adapter *)0)->stats.pxoffrxc) + \
+                        sizeof(((struct ixgbe_adapter *)0)->stats.pxofftxc)) \
+                       / sizeof(u64))
 #define IXGBE_STATS_LEN (IXGBE_GLOBAL_STATS_LEN + \
                          IXGBE_PB_STATS_LEN + \
                          IXGBE_QUEUE_STATS_LEN)
@@ -1078,8 +1082,15 @@ static void ixgbe_get_ethtool_stats(struct net_device *netdev,
                data[i] = (ixgbe_gstrings_stats[i].sizeof_stat ==
                           sizeof(u64)) ? *(u64 *)p : *(u32 *)p;
        }
-       for (j = 0; j < adapter->num_tx_queues; j++) {
+       for (j = 0; j < IXGBE_NUM_RX_QUEUES; j++) {
                ring = adapter->tx_ring[j];
+               if (!ring) {
+                       data[i] = 0;
+                       data[i+1] = 0;
+                       i += 2;
+                       continue;
+               }
+
                do {
                        start = u64_stats_fetch_begin_bh(&ring->syncp);
                        data[i]   = ring->stats.packets;
@@ -1087,8 +1098,15 @@ static void ixgbe_get_ethtool_stats(struct net_device *netdev,
                } while (u64_stats_fetch_retry_bh(&ring->syncp, start));
                i += 2;
        }
-       for (j = 0; j < adapter->num_rx_queues; j++) {
+       for (j = 0; j < IXGBE_NUM_RX_QUEUES; j++) {
                ring = adapter->rx_ring[j];
+               if (!ring) {
+                       data[i] = 0;
+                       data[i+1] = 0;
+                       i += 2;
+                       continue;
+               }
+
                do {
                        start = u64_stats_fetch_begin_bh(&ring->syncp);
                        data[i]   = ring->stats.packets;
@@ -1096,22 +1114,20 @@ static void ixgbe_get_ethtool_stats(struct net_device *netdev,
                } while (u64_stats_fetch_retry_bh(&ring->syncp, start));
                i += 2;
        }
-       if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) {
-               for (j = 0; j < MAX_TX_PACKET_BUFFERS; j++) {
-                       data[i++] = adapter->stats.pxontxc[j];
-                       data[i++] = adapter->stats.pxofftxc[j];
-               }
-               for (j = 0; j < MAX_RX_PACKET_BUFFERS; j++) {
-                       data[i++] = adapter->stats.pxonrxc[j];
-                       data[i++] = adapter->stats.pxoffrxc[j];
-               }
+
+       for (j = 0; j < IXGBE_MAX_PACKET_BUFFERS; j++) {
+               data[i++] = adapter->stats.pxontxc[j];
+               data[i++] = adapter->stats.pxofftxc[j];
+       }
+       for (j = 0; j < IXGBE_MAX_PACKET_BUFFERS; j++) {
+               data[i++] = adapter->stats.pxonrxc[j];
+               data[i++] = adapter->stats.pxoffrxc[j];
        }
 }
 
 static void ixgbe_get_strings(struct net_device *netdev, u32 stringset,
                               u8 *data)
 {
-       struct ixgbe_adapter *adapter = netdev_priv(netdev);
        char *p = (char *)data;
        int i;
 
@@ -1126,31 +1142,29 @@ static void ixgbe_get_strings(struct net_device *netdev, u32 stringset,
                               ETH_GSTRING_LEN);
                        p += ETH_GSTRING_LEN;
                }
-               for (i = 0; i < adapter->num_tx_queues; i++) {
+               for (i = 0; i < netdev->num_tx_queues; i++) {
                        sprintf(p, "tx_queue_%u_packets", i);
                        p += ETH_GSTRING_LEN;
                        sprintf(p, "tx_queue_%u_bytes", i);
                        p += ETH_GSTRING_LEN;
                }
-               for (i = 0; i < adapter->num_rx_queues; i++) {
+               for (i = 0; i < IXGBE_NUM_RX_QUEUES; i++) {
                        sprintf(p, "rx_queue_%u_packets", i);
                        p += ETH_GSTRING_LEN;
                        sprintf(p, "rx_queue_%u_bytes", i);
                        p += ETH_GSTRING_LEN;
                }
-               if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) {
-                       for (i = 0; i < MAX_TX_PACKET_BUFFERS; i++) {
-                               sprintf(p, "tx_pb_%u_pxon", i);
-                               p += ETH_GSTRING_LEN;
-                               sprintf(p, "tx_pb_%u_pxoff", i);
-                               p += ETH_GSTRING_LEN;
-                       }
-                       for (i = 0; i < MAX_RX_PACKET_BUFFERS; i++) {
-                               sprintf(p, "rx_pb_%u_pxon", i);
-                               p += ETH_GSTRING_LEN;
-                               sprintf(p, "rx_pb_%u_pxoff", i);
-                               p += ETH_GSTRING_LEN;
-                       }
+               for (i = 0; i < IXGBE_MAX_PACKET_BUFFERS; i++) {
+                       sprintf(p, "tx_pb_%u_pxon", i);
+                       p += ETH_GSTRING_LEN;
+                       sprintf(p, "tx_pb_%u_pxoff", i);
+                       p += ETH_GSTRING_LEN;
+               }
+               for (i = 0; i < IXGBE_MAX_PACKET_BUFFERS; i++) {
+                       sprintf(p, "rx_pb_%u_pxon", i);
+                       p += ETH_GSTRING_LEN;
+                       sprintf(p, "rx_pb_%u_pxoff", i);
+                       p += ETH_GSTRING_LEN;
                }
                /* BUG_ON(p - data != IXGBE_STATS_LEN * ETH_GSTRING_LEN); */
                break;
index d18d615..4bc7942 100644 (file)
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel 10 Gigabit PCI Express Linux driver
-  Copyright(c) 1999 - 2011 Intel Corporation.
+  Copyright(c) 1999 - 2012 Intel Corporation.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms and conditions of the GNU General Public License,
index 261fd62..1dbed17 100644 (file)
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel 10 Gigabit PCI Express Linux driver
-  Copyright(c) 1999 - 2011 Intel Corporation.
+  Copyright(c) 1999 - 2012 Intel Corporation.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms and conditions of the GNU General Public License,
index 1ee5d0f..3dc6cef 100644 (file)
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel 10 Gigabit PCI Express Linux driver
-  Copyright(c) 1999 - 2011 Intel Corporation.
+  Copyright(c) 1999 - 2012 Intel Corporation.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms and conditions of the GNU General Public License,
@@ -64,7 +64,7 @@ char ixgbe_default_device_descr[] =
        __stringify(BUILD) "-k"
 const char ixgbe_driver_version[] = DRV_VERSION;
 static const char ixgbe_copyright[] =
-                               "Copyright (c) 1999-2011 Intel Corporation.";
+                               "Copyright (c) 1999-2012 Intel Corporation.";
 
 static const struct ixgbe_info *ixgbe_info_tbl[] = {
        [board_82598] = &ixgbe_82598_info,
@@ -2633,22 +2633,22 @@ static void ixgbe_configure_rscctl(struct ixgbe_adapter *adapter,
        /*
         * we must limit the number of descriptors so that the
         * total size of max desc * buf_len is not greater
-        * than 65535
+        * than 65536
         */
        if (ring_is_ps_enabled(ring)) {
-#if (MAX_SKB_FRAGS > 16)
+#if (PAGE_SIZE < 8192)
                rscctrl |= IXGBE_RSCCTL_MAXDESC_16;
-#elif (MAX_SKB_FRAGS > 8)
+#elif (PAGE_SIZE < 16384)
                rscctrl |= IXGBE_RSCCTL_MAXDESC_8;
-#elif (MAX_SKB_FRAGS > 4)
+#elif (PAGE_SIZE < 32768)
                rscctrl |= IXGBE_RSCCTL_MAXDESC_4;
 #else
                rscctrl |= IXGBE_RSCCTL_MAXDESC_1;
 #endif
        } else {
-               if (rx_buf_len < IXGBE_RXBUFFER_4K)
+               if (rx_buf_len <= IXGBE_RXBUFFER_4K)
                        rscctrl |= IXGBE_RSCCTL_MAXDESC_16;
-               else if (rx_buf_len < IXGBE_RXBUFFER_8K)
+               else if (rx_buf_len <= IXGBE_RXBUFFER_8K)
                        rscctrl |= IXGBE_RSCCTL_MAXDESC_8;
                else
                        rscctrl |= IXGBE_RSCCTL_MAXDESC_4;
@@ -2830,7 +2830,7 @@ static void ixgbe_configure_virtualization(struct ixgbe_adapter *adapter)
        IXGBE_WRITE_REG(hw, IXGBE_VT_CTL, vmdctl | vt_reg_bits);
 
        vf_shift = adapter->num_vfs % 32;
-       reg_offset = (adapter->num_vfs > 32) ? 1 : 0;
+       reg_offset = (adapter->num_vfs >= 32) ? 1 : 0;
 
        /* Enable only the PF's pool for Tx/Rx */
        IXGBE_WRITE_REG(hw, IXGBE_VFRE(reg_offset), (1 << vf_shift));
@@ -4330,6 +4330,10 @@ static int ixgbe_set_num_queues(struct ixgbe_adapter *adapter)
        adapter->num_tx_queues = 1;
 
 done:
+       if ((adapter->netdev->reg_state == NETREG_UNREGISTERED) ||
+           (adapter->netdev->reg_state == NETREG_UNREGISTERING))
+               return 0;
+
        /* Notify the stack of the (possibly) reduced queue counts. */
        netif_set_real_num_tx_queues(adapter->netdev, adapter->num_tx_queues);
        return netif_set_real_num_rx_queues(adapter->netdev,
index 3f725d4..1f3e32b 100644 (file)
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel 10 Gigabit PCI Express Linux driver
-  Copyright(c) 1999 - 2011 Intel Corporation.
+  Copyright(c) 1999 - 2012 Intel Corporation.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms and conditions of the GNU General Public License,
index b239bda..310bdd9 100644 (file)
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel 10 Gigabit PCI Express Linux driver
-  Copyright(c) 1999 - 2011 Intel Corporation.
+  Copyright(c) 1999 - 2012 Intel Corporation.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms and conditions of the GNU General Public License,
index 7cf1e1f..b917735 100644 (file)
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel 10 Gigabit PCI Express Linux driver
-  Copyright(c) 1999 - 2011 Intel Corporation.
+  Copyright(c) 1999 - 2012 Intel Corporation.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms and conditions of the GNU General Public License,
index 197bdd1..cc18165 100644 (file)
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel 10 Gigabit PCI Express Linux driver
-  Copyright(c) 1999 - 2011 Intel Corporation.
+  Copyright(c) 1999 - 2012 Intel Corporation.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms and conditions of the GNU General Public License,
index cf6812d..b01ecb4 100644 (file)
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel 10 Gigabit PCI Express Linux driver
-  Copyright(c) 1999 - 2011 Intel Corporation.
+  Copyright(c) 1999 - 2012 Intel Corporation.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms and conditions of the GNU General Public License,
@@ -67,7 +67,8 @@ static int ixgbe_find_enabled_vfs(struct ixgbe_adapter *adapter)
        vf_devfn = pdev->devfn + 0x80;
        pvfdev = pci_get_device(IXGBE_INTEL_VENDOR_ID, device_id, NULL);
        while (pvfdev) {
-               if (pvfdev->devfn == vf_devfn)
+               if (pvfdev->devfn == vf_devfn &&
+                   (pvfdev->bus->number >= pdev->bus->number))
                        vfs_found++;
                vf_devfn += 2;
                pvfdev = pci_get_device(IXGBE_INTEL_VENDOR_ID,
@@ -646,6 +647,9 @@ static int ixgbe_rcv_msg_from_vf(struct ixgbe_adapter *adapter, u32 vf)
                        ixgbe_ndo_set_vf_spoofchk(adapter->netdev, vf, false);
                retval = ixgbe_set_vf_macvlan(adapter, vf, index,
                                              (unsigned char *)(&msgbuf[1]));
+               if (retval == -ENOSPC)
+                       e_warn(drv, "VF %d has requested a MACVLAN filter "
+                                   "but there is no space for it\n", vf);
                break;
        default:
                e_err(drv, "Unhandled Msg %8.8x\n", msgbuf[0]);
index e8badab..2ab38d5 100644 (file)
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel 10 Gigabit PCI Express Linux driver
-  Copyright(c) 1999 - 2011 Intel Corporation.
+  Copyright(c) 1999 - 2012 Intel Corporation.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms and conditions of the GNU General Public License,
index 775602e..9b95bef 100644 (file)
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel 10 Gigabit PCI Express Linux driver
-  Copyright(c) 1999 - 2011 Intel Corporation.
+  Copyright(c) 1999 - 2012 Intel Corporation.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms and conditions of the GNU General Public License,
index 8cc5ecc..f838a2b 100644 (file)
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel 10 Gigabit PCI Express Linux driver
-  Copyright(c) 1999 - 2011 Intel Corporation.
+  Copyright(c) 1999 - 2012 Intel Corporation.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms and conditions of the GNU General Public License,
index 1f35d22..4ce4c97 100644 (file)
@@ -1,7 +1,7 @@
 ################################################################################
 #
 # Intel 82599 Virtual Function driver
-# Copyright(c) 1999 - 2010 Intel Corporation.
+# Copyright(c) 1999 - 2012 Intel Corporation.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms and conditions of the GNU General Public License,
index 2eb89cb..947b5c8 100644 (file)
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel 82599 Virtual Function driver
-  Copyright(c) 1999 - 2010 Intel Corporation.
+  Copyright(c) 1999 - 2012 Intel Corporation.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms and conditions of the GNU General Public License,
index c857003..2bfe0d1 100644 (file)
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel 82599 Virtual Function driver
-  Copyright(c) 1999 - 2009 Intel Corporation.
+  Copyright(c) 1999 - 2012 Intel Corporation.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms and conditions of the GNU General Public License,
index 9075c1d..dfed420 100644 (file)
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel 82599 Virtual Function driver
-  Copyright(c) 1999 - 2010 Intel Corporation.
+  Copyright(c) 1999 - 2012 Intel Corporation.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms and conditions of the GNU General Public License,
index bed411b..e51d552 100644 (file)
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel 82599 Virtual Function driver
-  Copyright(c) 1999 - 2010 Intel Corporation.
+  Copyright(c) 1999 - 2012 Intel Corporation.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms and conditions of the GNU General Public License,
@@ -60,7 +60,7 @@ static const char ixgbevf_driver_string[] =
 #define DRV_VERSION "2.2.0-k"
 const char ixgbevf_driver_version[] = DRV_VERSION;
 static char ixgbevf_copyright[] =
-       "Copyright (c) 2009 - 2010 Intel Corporation.";
+       "Copyright (c) 2009 - 2012 Intel Corporation.";
 
 static const struct ixgbevf_info *ixgbevf_info_tbl[] = {
        [board_82599_vf] = &ixgbevf_82599_vf_info,
@@ -935,7 +935,11 @@ static irqreturn_t ixgbevf_msix_mbx(int irq, void *data)
                if (msg & IXGBE_VT_MSGTYPE_NACK)
                        pr_warn("Last Request of type %2.2x to PF Nacked\n",
                                msg & 0xFF);
-               goto out;
+               /*
+                * Restore the PFSTS bit in case someone is polling for a
+                * return message from the PF
+                */
+               hw->mbx.v2p_mailbox |= IXGBE_VFMAILBOX_PFSTS;
        }
 
        /*
@@ -945,7 +949,7 @@ static irqreturn_t ixgbevf_msix_mbx(int irq, void *data)
         */
        if (got_ack)
                hw->mbx.v2p_mailbox |= IXGBE_VFMAILBOX_PFACK;
-out:
+
        return IRQ_HANDLED;
 }
 
index 13532d9..9c95590 100644 (file)
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel 82599 Virtual Function driver
-  Copyright(c) 1999 - 2010 Intel Corporation.
+  Copyright(c) 1999 - 2012 Intel Corporation.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms and conditions of the GNU General Public License,
index 9d38a94..cf9131c 100644 (file)
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel 82599 Virtual Function driver
-  Copyright(c) 1999 - 2010 Intel Corporation.
+  Copyright(c) 1999 - 2012 Intel Corporation.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms and conditions of the GNU General Public License,
index 5e4d5e5..debd8c0 100644 (file)
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel 82599 Virtual Function driver
-  Copyright(c) 1999 - 2010 Intel Corporation.
+  Copyright(c) 1999 - 2012 Intel Corporation.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms and conditions of the GNU General Public License,
index d0138d7..74be741 100644 (file)
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel 82599 Virtual Function driver
-  Copyright(c) 1999 - 2010 Intel Corporation.
+  Copyright(c) 1999 - 2012 Intel Corporation.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms and conditions of the GNU General Public License,
@@ -283,6 +283,17 @@ static s32 ixgbevf_set_rar_vf(struct ixgbe_hw *hw, u32 index, u8 *addr,
        return ret_val;
 }
 
+static void ixgbevf_write_msg_read_ack(struct ixgbe_hw *hw,
+                                       u32 *msg, u16 size)
+{
+       struct ixgbe_mbx_info *mbx = &hw->mbx;
+       u32 retmsg[IXGBE_VFMAILBOX_SIZE];
+       s32 retval = mbx->ops.write_posted(hw, msg, size);
+
+       if (!retval)
+               mbx->ops.read_posted(hw, retmsg, size);
+}
+
 /**
  *  ixgbevf_update_mc_addr_list_vf - Update Multicast addresses
  *  @hw: pointer to the HW structure
@@ -294,7 +305,6 @@ static s32 ixgbevf_update_mc_addr_list_vf(struct ixgbe_hw *hw,
                                          struct net_device *netdev)
 {
        struct netdev_hw_addr *ha;
-       struct ixgbe_mbx_info *mbx = &hw->mbx;
        u32 msgbuf[IXGBE_VFMAILBOX_SIZE];
        u16 *vector_list = (u16 *)&msgbuf[1];
        u32 cnt, i;
@@ -321,7 +331,7 @@ static s32 ixgbevf_update_mc_addr_list_vf(struct ixgbe_hw *hw,
                vector_list[i++] = ixgbevf_mta_vector(hw, ha->addr);
        }
 
-       mbx->ops.write_posted(hw, msgbuf, IXGBE_VFMAILBOX_SIZE);
+       ixgbevf_write_msg_read_ack(hw, msgbuf, IXGBE_VFMAILBOX_SIZE);
 
        return 0;
 }
@@ -336,7 +346,6 @@ static s32 ixgbevf_update_mc_addr_list_vf(struct ixgbe_hw *hw,
 static s32 ixgbevf_set_vfta_vf(struct ixgbe_hw *hw, u32 vlan, u32 vind,
                               bool vlan_on)
 {
-       struct ixgbe_mbx_info *mbx = &hw->mbx;
        u32 msgbuf[2];
 
        msgbuf[0] = IXGBE_VF_SET_VLAN;
@@ -344,7 +353,9 @@ static s32 ixgbevf_set_vfta_vf(struct ixgbe_hw *hw, u32 vlan, u32 vind,
        /* Setting the 8 bit field MSG INFO to TRUE indicates "add" */
        msgbuf[0] |= vlan_on << IXGBE_VT_MSGINFO_SHIFT;
 
-       return mbx->ops.write_posted(hw, msgbuf, 2);
+       ixgbevf_write_msg_read_ack(hw, msgbuf, 2);
+
+       return 0;
 }
 
 /**
index d556619..25c951d 100644 (file)
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel 82599 Virtual Function driver
-  Copyright(c) 1999 - 2010 Intel Corporation.
+  Copyright(c) 1999 - 2012 Intel Corporation.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms and conditions of the GNU General Public License,
index edb9bda..33947ac 100644 (file)
@@ -931,20 +931,17 @@ static int skge_ring_alloc(struct skge_ring *ring, void *vaddr, u32 base)
 }
 
 /* Allocate and setup a new buffer for receiving */
-static int skge_rx_setup(struct pci_dev *pdev,
-                        struct skge_element *e,
-                        struct sk_buff *skb, unsigned int bufsize)
+static void skge_rx_setup(struct skge_port *skge, struct skge_element *e,
+                         struct sk_buff *skb, unsigned int bufsize)
 {
        struct skge_rx_desc *rd = e->desc;
-       dma_addr_t map;
+       u64 map;
 
-       map = pci_map_single(pdev, skb->data, bufsize,
+       map = pci_map_single(skge->hw->pdev, skb->data, bufsize,
                             PCI_DMA_FROMDEVICE);
-       if (pci_dma_mapping_error(pdev, map))
-               goto mapping_error;
 
-       rd->dma_lo = lower_32_bits(map);
-       rd->dma_hi = upper_32_bits(map);
+       rd->dma_lo = map;
+       rd->dma_hi = map >> 32;
        e->skb = skb;
        rd->csum1_start = ETH_HLEN;
        rd->csum2_start = ETH_HLEN;
@@ -956,13 +953,6 @@ static int skge_rx_setup(struct pci_dev *pdev,
        rd->control = BMU_OWN | BMU_STF | BMU_IRQ_EOF | BMU_TCP_CHECK | bufsize;
        dma_unmap_addr_set(e, mapaddr, map);
        dma_unmap_len_set(e, maplen, bufsize);
-       return 0;
-
-mapping_error:
-       if (net_ratelimit())
-               dev_warn(&pdev->dev, "%s: rx mapping error\n",
-                        skb->dev->name);
-       return -EIO;
 }
 
 /* Resume receiving using existing skb,
@@ -1024,11 +1014,7 @@ static int skge_rx_fill(struct net_device *dev)
                        return -ENOMEM;
 
                skb_reserve(skb, NET_IP_ALIGN);
-               if (skge_rx_setup(skge->hw->pdev, e, skb, skge->rx_buf_size)) {
-                       kfree_skb(skb);
-                       return -ENOMEM;
-               }
-
+               skge_rx_setup(skge, e, skb, skge->rx_buf_size);
        } while ((e = e->next) != ring->start);
 
        ring->to_clean = ring->start;
@@ -2743,7 +2729,7 @@ static netdev_tx_t skge_xmit_frame(struct sk_buff *skb,
        struct skge_tx_desc *td;
        int i;
        u32 control, len;
-       dma_addr_t map;
+       u64 map;
 
        if (skb_padto(skb, ETH_ZLEN))
                return NETDEV_TX_OK;
@@ -2757,14 +2743,11 @@ static netdev_tx_t skge_xmit_frame(struct sk_buff *skb,
        e->skb = skb;
        len = skb_headlen(skb);
        map = pci_map_single(hw->pdev, skb->data, len, PCI_DMA_TODEVICE);
-       if (pci_dma_mapping_error(hw->pdev, map))
-               goto mapping_error;
-
        dma_unmap_addr_set(e, mapaddr, map);
        dma_unmap_len_set(e, maplen, len);
 
-       td->dma_lo = lower_32_bits(map);
-       td->dma_hi = upper_32_bits(map);
+       td->dma_lo = map;
+       td->dma_hi = map >> 32;
 
        if (skb->ip_summed == CHECKSUM_PARTIAL) {
                const int offset = skb_checksum_start_offset(skb);
@@ -2795,16 +2778,14 @@ static netdev_tx_t skge_xmit_frame(struct sk_buff *skb,
 
                        map = skb_frag_dma_map(&hw->pdev->dev, frag, 0,
                                               skb_frag_size(frag), DMA_TO_DEVICE);
-                       if (dma_mapping_error(&hw->pdev->dev, map))
-                               goto mapping_unwind;
 
                        e = e->next;
                        e->skb = skb;
                        tf = e->desc;
                        BUG_ON(tf->control & BMU_OWN);
 
-                       tf->dma_lo = lower_32_bits(map);
-                       tf->dma_hi = upper_32_bits(map);
+                       tf->dma_lo = map;
+                       tf->dma_hi = (u64) map >> 32;
                        dma_unmap_addr_set(e, mapaddr, map);
                        dma_unmap_len_set(e, maplen, skb_frag_size(frag));
 
@@ -2834,28 +2815,6 @@ static netdev_tx_t skge_xmit_frame(struct sk_buff *skb,
        }
 
        return NETDEV_TX_OK;
-
-mapping_unwind:
-       /* unroll any pages that were already mapped.  */
-       if (e != skge->tx_ring.to_use) {
-               struct skge_element *u;
-
-               for (u = skge->tx_ring.to_use->next; u != e; u = u->next)
-                       pci_unmap_page(hw->pdev, dma_unmap_addr(u, mapaddr),
-                                      dma_unmap_len(u, maplen),
-                                      PCI_DMA_TODEVICE);
-               e = skge->tx_ring.to_use;
-       }
-       /* undo the mapping for the skb header */
-       pci_unmap_single(hw->pdev, dma_unmap_addr(e, mapaddr),
-                        dma_unmap_len(e, maplen),
-                        PCI_DMA_TODEVICE);
-mapping_error:
-       /* mapping error causes error message and packet to be discarded. */
-       if (net_ratelimit())
-               dev_warn(&hw->pdev->dev, "%s: tx mapping error\n", dev->name);
-       dev_kfree_skb(skb);
-       return NETDEV_TX_OK;
 }
 
 
@@ -3099,17 +3058,13 @@ static struct sk_buff *skge_rx_get(struct net_device *dev,
                if (!nskb)
                        goto resubmit;
 
-               if (unlikely(skge_rx_setup(skge->hw->pdev, e, nskb, skge->rx_buf_size))) {
-                       dev_kfree_skb(nskb);
-                       goto resubmit;
-               }
-
                pci_unmap_single(skge->hw->pdev,
                                 dma_unmap_addr(e, mapaddr),
                                 dma_unmap_len(e, maplen),
                                 PCI_DMA_FROMDEVICE);
                skb = e->skb;
                prefetch(skb->data);
+               skge_rx_setup(skge, e, nskb, skge->rx_buf_size);
        }
 
        skb_put(skb, len);
index 405e6ac..eaf09d4 100644 (file)
@@ -1616,12 +1616,12 @@ void mlx4_multi_func_cleanup(struct mlx4_dev *dev)
                                kfree(priv->mfunc.master.slave_state[i].vlan_filter[port]);
                }
                kfree(priv->mfunc.master.slave_state);
-               iounmap(priv->mfunc.comm);
-               dma_free_coherent(&(dev->pdev->dev), PAGE_SIZE,
-                                                    priv->mfunc.vhcr,
-                                                    priv->mfunc.vhcr_dma);
-               priv->mfunc.vhcr = NULL;
        }
+
+       iounmap(priv->mfunc.comm);
+       dma_free_coherent(&(dev->pdev->dev), PAGE_SIZE,
+                    priv->mfunc.vhcr, priv->mfunc.vhcr_dma);
+       priv->mfunc.vhcr = NULL;
 }
 
 void mlx4_cmd_cleanup(struct mlx4_dev *dev)
index 467ae58..149e60d 100644 (file)
@@ -892,7 +892,8 @@ void mlx4_en_free_resources(struct mlx4_en_priv *priv)
 
        for (i = 0; i < priv->rx_ring_num; i++) {
                if (priv->rx_ring[i].rx_info)
-                       mlx4_en_destroy_rx_ring(priv, &priv->rx_ring[i]);
+                       mlx4_en_destroy_rx_ring(priv, &priv->rx_ring[i],
+                               priv->prof->rx_ring_size, priv->stride);
                if (priv->rx_cq[i].buf)
                        mlx4_en_destroy_cq(priv, &priv->rx_cq[i]);
        }
index 971d4b6..d4ad8c2 100644 (file)
@@ -168,8 +168,12 @@ static int mlx4_en_prepare_rx_desc(struct mlx4_en_priv *priv,
        return 0;
 
 err:
-       while (i--)
+       while (i--) {
+               dma_addr_t dma = be64_to_cpu(rx_desc->data[i].addr);
+               pci_unmap_single(priv->mdev->pdev, dma, skb_frags[i].size,
+                                PCI_DMA_FROMDEVICE);
                put_page(skb_frags[i].page);
+       }
        return -ENOMEM;
 }
 
@@ -380,12 +384,12 @@ err_allocator:
 }
 
 void mlx4_en_destroy_rx_ring(struct mlx4_en_priv *priv,
-                            struct mlx4_en_rx_ring *ring)
+                            struct mlx4_en_rx_ring *ring, u32 size, u16 stride)
 {
        struct mlx4_en_dev *mdev = priv->mdev;
 
        mlx4_en_unmap_buffer(&ring->wqres.buf);
-       mlx4_free_hwq_res(mdev->dev, &ring->wqres, ring->buf_size + TXBB_SIZE);
+       mlx4_free_hwq_res(mdev->dev, &ring->wqres, size * stride + TXBB_SIZE);
        vfree(ring->rx_info);
        ring->rx_info = NULL;
 }
index 0785d9b..ca574d8 100644 (file)
@@ -136,7 +136,7 @@ static int new_steering_entry(struct mlx4_dev *dev, u8 port,
        u32 prot;
        int err;
 
-       s_steer = &mlx4_priv(dev)->steer[0];
+       s_steer = &mlx4_priv(dev)->steer[port - 1];
        new_entry = kzalloc(sizeof *new_entry, GFP_KERNEL);
        if (!new_entry)
                return -ENOMEM;
@@ -220,7 +220,7 @@ static int existing_steering_entry(struct mlx4_dev *dev, u8 port,
        struct mlx4_promisc_qp *pqp;
        struct mlx4_promisc_qp *dqp;
 
-       s_steer = &mlx4_priv(dev)->steer[0];
+       s_steer = &mlx4_priv(dev)->steer[port - 1];
 
        pqp = get_promisc_qp(dev, 0, steer, qpn);
        if (!pqp)
@@ -265,7 +265,7 @@ static bool check_duplicate_entry(struct mlx4_dev *dev, u8 port,
        struct mlx4_steer_index *tmp_entry, *entry = NULL;
        struct mlx4_promisc_qp *dqp, *tmp_dqp;
 
-       s_steer = &mlx4_priv(dev)->steer[0];
+       s_steer = &mlx4_priv(dev)->steer[port - 1];
 
        /* if qp is not promisc, it cannot be duplicated */
        if (!get_promisc_qp(dev, 0, steer, qpn))
@@ -306,7 +306,7 @@ static bool can_remove_steering_entry(struct mlx4_dev *dev, u8 port,
        bool ret = false;
        int i;
 
-       s_steer = &mlx4_priv(dev)->steer[0];
+       s_steer = &mlx4_priv(dev)->steer[port - 1];
 
        mailbox = mlx4_alloc_cmd_mailbox(dev);
        if (IS_ERR(mailbox))
@@ -361,7 +361,7 @@ static int add_promisc_qp(struct mlx4_dev *dev, u8 port,
        int err;
        struct mlx4_priv *priv = mlx4_priv(dev);
 
-       s_steer = &mlx4_priv(dev)->steer[0];
+       s_steer = &mlx4_priv(dev)->steer[port - 1];
 
        mutex_lock(&priv->mcg_table.mutex);
 
@@ -466,7 +466,7 @@ static int remove_promisc_qp(struct mlx4_dev *dev, u8 port,
        int loc, i;
        int err;
 
-       s_steer = &mlx4_priv(dev)->steer[0];
+       s_steer = &mlx4_priv(dev)->steer[port - 1];
        mutex_lock(&priv->mcg_table.mutex);
 
        pqp = get_promisc_qp(dev, 0, steer, qpn);
@@ -1004,7 +1004,7 @@ EXPORT_SYMBOL_GPL(mlx4_multicast_promisc_remove);
 
 int mlx4_unicast_promisc_add(struct mlx4_dev *dev, u32 qpn, u8 port)
 {
-       if (!(dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_MC_STEER))
+       if (!(dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_UC_STEER))
                return 0;
 
        if (mlx4_is_mfunc(dev))
@@ -1016,7 +1016,7 @@ EXPORT_SYMBOL_GPL(mlx4_unicast_promisc_add);
 
 int mlx4_unicast_promisc_remove(struct mlx4_dev *dev, u32 qpn, u8 port)
 {
-       if (!(dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_MC_STEER))
+       if (!(dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_UC_STEER))
                return 0;
 
        if (mlx4_is_mfunc(dev))
index 35f0884..d60335f 100644 (file)
@@ -528,7 +528,8 @@ int mlx4_en_create_rx_ring(struct mlx4_en_priv *priv,
                           struct mlx4_en_rx_ring *ring,
                           u32 size, u16 stride);
 void mlx4_en_destroy_rx_ring(struct mlx4_en_priv *priv,
-                            struct mlx4_en_rx_ring *ring);
+                            struct mlx4_en_rx_ring *ring,
+                            u32 size, u16 stride);
 int mlx4_en_activate_rx_rings(struct mlx4_en_priv *priv);
 void mlx4_en_deactivate_rx_ring(struct mlx4_en_priv *priv,
                                struct mlx4_en_rx_ring *ring);
index 1ea811c..fe42fc0 100644 (file)
@@ -42,7 +42,6 @@ config KS8851
        select NET_CORE
        select MII
        select CRC32
-       select MISC_DEVICES
        select EEPROM_93CX6
        ---help---
          SPI driver for Micrel KS8851 SPI attached network chip.
index 813d41c..87b6501 100644 (file)
@@ -38,6 +38,7 @@
 #include <linux/pm_runtime.h>
 #include <linux/slab.h>
 #include <linux/ethtool.h>
+#include <linux/if_vlan.h>
 #include <linux/sh_eth.h>
 
 #include "sh_eth.h"
@@ -817,7 +818,8 @@ static int sh_eth_dev_init(struct net_device *ndev)
                sh_eth_write(ndev, 0, TRIMD);
 
        /* Recv frame limit set register */
-       sh_eth_write(ndev, RFLR_VALUE, RFLR);
+       sh_eth_write(ndev, ndev->mtu + ETH_HLEN + VLAN_HLEN + ETH_FCS_LEN,
+                    RFLR);
 
        sh_eth_write(ndev, sh_eth_read(ndev, EESR), EESR);
        sh_eth_write(ndev, mdp->cd->eesipr_value, EESIPR);
index 47877b1..cdbd844 100644 (file)
@@ -575,9 +575,6 @@ enum RPADIR_BIT {
        RPADIR_PADR = 0x0003f,
 };
 
-/* RFLR */
-#define RFLR_VALUE 0x1000
-
 /* FDR */
 #define DEFAULT_FDR_INIT       0x00000707
 
index 794ac30..4fa0bcb 100644 (file)
@@ -1600,8 +1600,9 @@ static int emac_dev_open(struct net_device *ndev)
                if (IS_ERR(priv->phydev)) {
                        dev_err(emac_dev, "could not connect to phy %s\n",
                                priv->phy_id);
+                       ret = PTR_ERR(priv->phydev);
                        priv->phydev = NULL;
-                       return PTR_ERR(priv->phydev);
+                       return ret;
                }
 
                priv->link = 0;
index ef7c9c1..af8b8fc 100644 (file)
@@ -318,9 +318,9 @@ static int __devinit davinci_mdio_probe(struct platform_device *pdev)
 
        data->clk = clk_get(dev, NULL);
        if (IS_ERR(data->clk)) {
-               data->clk = NULL;
                dev_err(dev, "failed to get device clock\n");
                ret = PTR_ERR(data->clk);
+               data->clk = NULL;
                goto bail_out;
        }
 
index 0517647..74acb5c 100644 (file)
@@ -5,7 +5,7 @@
 config NET_VENDOR_TOSHIBA
        bool "Toshiba devices"
        default y
-       depends on PCI && (PPC_IBM_CELL_BLADE || PPC_CELLEB) || PPC_PS3
+       depends on PCI && (PPC_IBM_CELL_BLADE || PPC_CELLEB || MIPS) || PPC_PS3
        ---help---
          If you have a network (Ethernet) card belonging to this class, say Y
          and read the Ethernet-HOWTO, available from
index 4128d6b..cb35b14 100644 (file)
@@ -2491,9 +2491,6 @@ static int velocity_close(struct net_device *dev)
        if (dev->irq != 0)
                free_irq(dev->irq, dev);
 
-       /* Power down the chip */
-       pci_set_power_state(vptr->pdev, PCI_D3hot);
-
        velocity_free_rings(vptr);
 
        vptr->flags &= (~VELOCITY_FLAGS_OPENED);
index 1a1ca6c..466c58a 100644 (file)
@@ -123,7 +123,7 @@ static int netvsc_close(struct net_device *net)
        struct hv_device *device_obj = net_device_ctx->device_ctx;
        int ret;
 
-       netif_stop_queue(net);
+       netif_tx_disable(net);
 
        ret = rndis_filter_close(device_obj);
        if (ret != 0)
@@ -151,10 +151,10 @@ static int netvsc_start_xmit(struct sk_buff *skb, struct net_device *net)
        int ret;
        unsigned int i, num_pages, npg_data;
 
-       /* Add multipage for skb->data and additional one for RNDIS */
+       /* Add multipages for skb->data and additional 2 for RNDIS */
        npg_data = (((unsigned long)skb->data + skb_headlen(skb) - 1)
                >> PAGE_SHIFT) - ((unsigned long)skb->data >> PAGE_SHIFT) + 1;
-       num_pages = skb_shinfo(skb)->nr_frags + npg_data + 1;
+       num_pages = skb_shinfo(skb)->nr_frags + npg_data + 2;
 
        /* Allocate a netvsc packet based on # of frags. */
        packet = kzalloc(sizeof(struct hv_netvsc_packet) +
@@ -173,8 +173,8 @@ static int netvsc_start_xmit(struct sk_buff *skb, struct net_device *net)
                                sizeof(struct hv_netvsc_packet) +
                                    (num_pages * sizeof(struct hv_page_buffer));
 
-       /* Setup the rndis header */
-       packet->page_buf_cnt = num_pages;
+       /* If the rndis msg goes beyond 1 page, we will add 1 later */
+       packet->page_buf_cnt = num_pages - 1;
 
        /* Initialize it from the skb */
        packet->total_data_buflen = skb->len;
@@ -256,7 +256,7 @@ void netvsc_linkstatus_callback(struct hv_device *device_obj,
                schedule_delayed_work(&ndev_ctx->dwork, msecs_to_jiffies(20));
        } else {
                netif_carrier_off(net);
-               netif_stop_queue(net);
+               netif_tx_disable(net);
        }
 }
 
@@ -298,7 +298,7 @@ int netvsc_recv_callback(struct hv_device *device_obj,
        skb->ip_summed = CHECKSUM_NONE;
 
        net->stats.rx_packets++;
-       net->stats.rx_bytes += skb->len;
+       net->stats.rx_bytes += packet->total_data_buflen;
 
        /*
         * Pass the skb back up. Network stack will deallocate the skb when it
@@ -337,7 +337,7 @@ static int netvsc_change_mtu(struct net_device *ndev, int mtu)
 
        nvdev->start_remove = true;
        cancel_delayed_work_sync(&ndevctx->dwork);
-       netif_stop_queue(ndev);
+       netif_tx_disable(ndev);
        rndis_filter_device_remove(hdev);
 
        ndev->mtu = mtu;
@@ -460,7 +460,7 @@ static int netvsc_remove(struct hv_device *dev)
        cancel_delayed_work_sync(&ndev_ctx->dwork);
 
        /* Stop outbound asap */
-       netif_stop_queue(net);
+       netif_tx_disable(net);
 
        unregister_netdev(net);
 
index da181f9..133b7fb 100644 (file)
@@ -321,6 +321,25 @@ static void rndis_filter_receive_data(struct rndis_device *dev,
        data_offset = RNDIS_HEADER_SIZE + rndis_pkt->data_offset;
 
        pkt->total_data_buflen -= data_offset;
+
+       /*
+        * Make sure we got a valid RNDIS message, now total_data_buflen
+        * should be the data packet size plus the trailer padding size
+        */
+       if (pkt->total_data_buflen < rndis_pkt->data_len) {
+               netdev_err(dev->net_dev->ndev, "rndis message buffer "
+                          "overflow detected (got %u, min %u)"
+                          "...dropping this message!\n",
+                          pkt->total_data_buflen, rndis_pkt->data_len);
+               return;
+       }
+
+       /*
+        * Remove the rndis trailer padding from rndis packet message
+        * rndis_pkt->data_len tell us the real data length, we only copy
+        * the data packet to the stack, without the rndis trailer padding
+        */
+       pkt->total_data_buflen = rndis_pkt->data_len;
        pkt->data = (void *)((unsigned long)pkt->data + data_offset);
 
        pkt->is_data_pkt = true;
@@ -778,6 +797,19 @@ int rndis_filter_send(struct hv_device *dev,
                        (unsigned long)rndisMessage & (PAGE_SIZE-1);
        pkt->page_buf[0].len = rndisMessageSize;
 
+       /* Add one page_buf if the rndis msg goes beyond page boundary */
+       if (pkt->page_buf[0].offset + rndisMessageSize > PAGE_SIZE) {
+               int i;
+               for (i = pkt->page_buf_cnt; i > 1; i--)
+                       pkt->page_buf[i] = pkt->page_buf[i-1];
+               pkt->page_buf_cnt++;
+               pkt->page_buf[0].len = PAGE_SIZE - pkt->page_buf[0].offset;
+               pkt->page_buf[1].pfn = virt_to_phys((void *)((ulong)
+                       rndisMessage + pkt->page_buf[0].len)) >> PAGE_SHIFT;
+               pkt->page_buf[1].offset = 0;
+               pkt->page_buf[1].len = rndisMessageSize - pkt->page_buf[0].len;
+       }
+
        /* Save the packet send completion and context */
        filterPacket->completion = pkt->completion.send.send_completion;
        filterPacket->completion_ctx =
index c7e0149..45550d4 100644 (file)
@@ -7,7 +7,6 @@ menuconfig TR
        bool "Token Ring driver support"
        depends on NETDEVICES && !UML
        depends on (PCI || ISA || MCA || CCW || PCMCIA)
-       select LLC
        help
          Token Ring is IBM's way of communication on a local network; the
          rest of the world uses Ethernet. To participate on a Token Ring
@@ -20,6 +19,10 @@ menuconfig TR
 
 if TR
 
+config WANT_LLC
+       def_bool y
+       select LLC
+
 config PCMCIA_IBMTR
        tristate "IBM PCMCIA tokenring adapter support"
        depends on IBMTR!=y && PCMCIA
index ee77595..87db1ee 100644 (file)
@@ -1037,13 +1037,16 @@ void ath9k_hw_init_global_settings(struct ath_hw *ah)
 
        /*
         * Workaround for early ACK timeouts, add an offset to match the
-        * initval's 64us ack timeout value.
+        * initval's 64us ack timeout value. Use 48us for the CTS timeout.
         * This was initially only meant to work around an issue with delayed
         * BA frames in some implementations, but it has been found to fix ACK
         * timeout issues in other cases as well.
         */
-       if (conf->channel && conf->channel->band == IEEE80211_BAND_2GHZ)
+       if (conf->channel && conf->channel->band == IEEE80211_BAND_2GHZ) {
                acktimeout += 64 - sifstime - ah->slottime;
+               ctstimeout += 48 - sifstime - ah->slottime;
+       }
+
 
        ath9k_hw_set_sifs_time(ah, sifstime);
        ath9k_hw_setslottime(ah, slottime);
index abf9435..53a005d 100644 (file)
@@ -822,6 +822,11 @@ int ath9k_init_device(u16 devid, struct ath_softc *sc,
                ARRAY_SIZE(ath9k_tpt_blink));
 #endif
 
+       INIT_WORK(&sc->hw_reset_work, ath_reset_work);
+       INIT_WORK(&sc->hw_check_work, ath_hw_check);
+       INIT_WORK(&sc->paprd_work, ath_paprd_calibrate);
+       INIT_DELAYED_WORK(&sc->hw_pll_work, ath_hw_pll_work);
+
        /* Register with mac80211 */
        error = ieee80211_register_hw(hw);
        if (error)
@@ -840,10 +845,6 @@ int ath9k_init_device(u16 devid, struct ath_softc *sc,
                        goto error_world;
        }
 
-       INIT_WORK(&sc->hw_reset_work, ath_reset_work);
-       INIT_WORK(&sc->hw_check_work, ath_hw_check);
-       INIT_WORK(&sc->paprd_work, ath_paprd_calibrate);
-       INIT_DELAYED_WORK(&sc->hw_pll_work, ath_hw_pll_work);
        sc->last_rssi = ATH_RSSI_DUMMY_MARKER;
 
        ath_init_leds(sc);
index b3c3798..635b592 100644 (file)
@@ -694,7 +694,7 @@ static u8 ath_rc_get_highest_rix(struct ath_softc *sc,
                return rate;
 
        /* This should not happen */
-       WARN_ON(1);
+       WARN_ON_ONCE(1);
 
        rate = ath_rc_priv->valid_rate_index[0];
 
index 0e666fb..7e1a91a 100644 (file)
@@ -822,6 +822,14 @@ static bool ath9k_rx_accept(struct ath_common *common,
                (ATH9K_RXERR_DECRYPT | ATH9K_RXERR_CRC | ATH9K_RXERR_MIC |
                 ATH9K_RXERR_KEYMISS));
 
+       /*
+        * Key miss events are only relevant for pairwise keys where the
+        * descriptor does contain a valid key index. This has been observed
+        * mostly with CCMP encryption.
+        */
+       if (rx_stats->rs_keyix == ATH9K_RXKEYIX_INVALID)
+               rx_stats->rs_status &= ~ATH9K_RXERR_KEYMISS;
+
        if (!rx_stats->rs_datalen)
                return false;
         /*
index c664c27..63bbc60 100644 (file)
@@ -91,6 +91,7 @@ static void iwlagn_tx_cmd_build_basic(struct iwl_priv *priv,
                tx_cmd->tid_tspec = qc[0] & 0xf;
                tx_flags &= ~TX_CMD_FLG_SEQ_CTL_MSK;
        } else {
+               tx_cmd->tid_tspec = IWL_TID_NON_QOS;
                if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ)
                        tx_flags |= TX_CMD_FLG_SEQ_CTL_MSK;
                else
@@ -620,7 +621,7 @@ int iwlagn_tx_agg_oper(struct iwl_priv *priv, struct ieee80211_vif *vif,
        sta_priv->lq_sta.lq.agg_params.agg_frame_cnt_limit =
                sta_priv->max_agg_bufsize;
 
-       IWL_INFO(priv, "Tx aggregation enabled on ra = %pM tid = %d\n",
+       IWL_DEBUG_HT(priv, "Tx aggregation enabled on ra = %pM tid = %d\n",
                 sta->addr, tid);
 
        return iwl_send_lq_cmd(priv, ctx,
@@ -808,6 +809,8 @@ static void iwl_rx_reply_tx_agg(struct iwl_priv *priv,
        u32 status = le16_to_cpu(tx_resp->status.status);
        int i;
 
+       WARN_ON(tid == IWL_TID_NON_QOS);
+
        if (agg->wait_for_ba)
                IWL_DEBUG_TX_REPLY(priv,
                        "got tx response w/o block-ack\n");
@@ -1035,10 +1038,13 @@ int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb,
                }
 
                __skb_queue_head_init(&skbs);
-               priv->tid_data[sta_id][tid].next_reclaimed = next_reclaimed;
 
-               IWL_DEBUG_TX_REPLY(priv, "Next reclaimed packet:%d",
-                                         next_reclaimed);
+               if (tid != IWL_TID_NON_QOS) {
+                       priv->tid_data[sta_id][tid].next_reclaimed =
+                               next_reclaimed;
+                       IWL_DEBUG_TX_REPLY(priv, "Next reclaimed packet:%d",
+                                                 next_reclaimed);
+               }
 
                /*we can free until ssn % q.n_bd not inclusive */
                WARN_ON(iwl_trans_reclaim(trans(priv), sta_id, tid, txq_id,
index 265de39..f822ac4 100644 (file)
@@ -815,6 +815,7 @@ struct iwl_qosparam_cmd {
 
 #define        IWL_INVALID_STATION     255
 #define IWL_MAX_TID_COUNT      8
+#define IWL_TID_NON_QOS IWL_MAX_TID_COUNT
 
 #define STA_FLG_TX_RATE_MSK            cpu_to_le32(1 << 2)
 #define STA_FLG_PWR_SAVE_MSK           cpu_to_le32(1 << 8)
index 752493f..65d1f05 100644 (file)
@@ -972,11 +972,11 @@ void iwl_irq_tasklet(struct iwl_trans *trans)
        }
 #endif
 
-       spin_unlock_irqrestore(&trans->shrd->lock, flags);
-
        /* saved interrupt in inta variable now we can reset trans_pcie->inta */
        trans_pcie->inta = 0;
 
+       spin_unlock_irqrestore(&trans->shrd->lock, flags);
+
        /* Now service all interrupt bits discovered above. */
        if (inta & CSR_INT_BIT_HW_ERR) {
                IWL_ERR(trans, "Hardware error detected.  Restarting.\n");
index 67d6e32..324d06d 100644 (file)
@@ -1262,6 +1262,7 @@ static int iwl_trans_pcie_reclaim(struct iwl_trans *trans, int sta_id, int tid,
        txq->time_stamp = jiffies;
 
        if (unlikely(txq_id >= IWLAGN_FIRST_AMPDU_QUEUE &&
+                    tid != IWL_TID_NON_QOS &&
                     txq_id != trans_pcie->agg_txq[sta_id][tid])) {
                /*
                 * FIXME: this is a uCode bug which need to be addressed,
index e05b417..1d0ec57 100644 (file)
@@ -382,7 +382,8 @@ mwifiex_free_adapter(struct mwifiex_adapter *adapter)
 
        adapter->if_ops.cleanup_if(adapter);
 
-       dev_kfree_skb_any(adapter->sleep_cfm);
+       if (adapter->sleep_cfm)
+               dev_kfree_skb_any(adapter->sleep_cfm);
 }
 
 /*
index 84be196..b728f54 100644 (file)
@@ -822,7 +822,9 @@ int mwifiex_remove_card(struct mwifiex_adapter *adapter, struct semaphore *sem)
                        continue;
 
                rtnl_lock();
-               mwifiex_del_virtual_intf(priv->wdev->wiphy, priv->netdev);
+               if (priv->wdev && priv->netdev)
+                       mwifiex_del_virtual_intf(priv->wdev->wiphy,
+                                                priv->netdev);
                rtnl_unlock();
        }
 
@@ -830,9 +832,11 @@ int mwifiex_remove_card(struct mwifiex_adapter *adapter, struct semaphore *sem)
        if (!priv)
                goto exit_remove;
 
-       wiphy_unregister(priv->wdev->wiphy);
-       wiphy_free(priv->wdev->wiphy);
-       kfree(priv->wdev);
+       if (priv->wdev) {
+               wiphy_unregister(priv->wdev->wiphy);
+               wiphy_free(priv->wdev->wiphy);
+               kfree(priv->wdev);
+       }
 
        mwifiex_terminate_workqueue(adapter);
 
index 470ca75..b0fbf5d 100644 (file)
@@ -54,7 +54,7 @@ int mwifiex_copy_mcast_addr(struct mwifiex_multicast_list *mlist,
 int mwifiex_wait_queue_complete(struct mwifiex_adapter *adapter)
 {
        bool cancel_flag = false;
-       int status = adapter->cmd_wait_q.status;
+       int status;
        struct cmd_ctrl_node *cmd_queued;
 
        if (!adapter->cmd_queued)
@@ -79,6 +79,8 @@ int mwifiex_wait_queue_complete(struct mwifiex_adapter *adapter)
                mwifiex_cancel_pending_ioctl(adapter);
                dev_dbg(adapter->dev, "cmd cancel\n");
        }
+
+       status = adapter->cmd_wait_q.status;
        adapter->cmd_wait_q.status = 0;
 
        return status;
@@ -240,6 +242,8 @@ int mwifiex_bss_start(struct mwifiex_private *priv, struct cfg80211_bss *bss,
 
                if (!netif_queue_stopped(priv->netdev))
                        mwifiex_stop_net_dev_queue(priv->netdev, adapter);
+               if (netif_carrier_ok(priv->netdev))
+                       netif_carrier_off(priv->netdev);
 
                /* Clear any past association response stored for
                 * application retrieval */
@@ -271,6 +275,8 @@ int mwifiex_bss_start(struct mwifiex_private *priv, struct cfg80211_bss *bss,
 
                if (!netif_queue_stopped(priv->netdev))
                        mwifiex_stop_net_dev_queue(priv->netdev, adapter);
+               if (netif_carrier_ok(priv->netdev))
+                       netif_carrier_off(priv->netdev);
 
                if (!ret) {
                        dev_dbg(adapter->dev, "info: network found in scan"
index 22a1a8f..7bef66d 100644 (file)
@@ -514,9 +514,9 @@ EXPORT_SYMBOL_GPL(rt2800_write_tx_data);
 
 static int rt2800_agc_to_rssi(struct rt2x00_dev *rt2x00dev, u32 rxwi_w2)
 {
-       int rssi0 = rt2x00_get_field32(rxwi_w2, RXWI_W2_RSSI0);
-       int rssi1 = rt2x00_get_field32(rxwi_w2, RXWI_W2_RSSI1);
-       int rssi2 = rt2x00_get_field32(rxwi_w2, RXWI_W2_RSSI2);
+       s8 rssi0 = rt2x00_get_field32(rxwi_w2, RXWI_W2_RSSI0);
+       s8 rssi1 = rt2x00_get_field32(rxwi_w2, RXWI_W2_RSSI1);
+       s8 rssi2 = rt2x00_get_field32(rxwi_w2, RXWI_W2_RSSI2);
        u16 eeprom;
        u8 offset0;
        u8 offset1;
@@ -552,7 +552,7 @@ static int rt2800_agc_to_rssi(struct rt2x00_dev *rt2x00dev, u32 rxwi_w2)
         * which gives less energy...
         */
        rssi0 = max(rssi0, rssi1);
-       return max(rssi0, rssi2);
+       return (int)max(rssi0, rssi2);
 }
 
 void rt2800_process_rxwi(struct queue_entry *entry,
index 0a70149..98a574a 100644 (file)
@@ -866,6 +866,14 @@ static int fill_ctrlset(struct zd_mac *mac,
 
        ZD_ASSERT(frag_len <= 0xffff);
 
+       /*
+        * Firmware computes the duration itself (for all frames except PSPoll)
+        * and needs the field set to 0 at input, otherwise firmware messes up
+        * duration_id and sets bits 14 and 15 on.
+        */
+       if (!ieee80211_is_pspoll(hdr->frame_control))
+               hdr->duration_id = 0;
+
        txrate = ieee80211_get_tx_rate(mac->hw, info);
 
        cs->modulation = txrate->hw_value;
index fa67905..698b905 100644 (file)
@@ -68,7 +68,7 @@ struct netfront_cb {
 
 #define NET_TX_RING_SIZE __CONST_RING_SIZE(xen_netif_tx, PAGE_SIZE)
 #define NET_RX_RING_SIZE __CONST_RING_SIZE(xen_netif_rx, PAGE_SIZE)
-#define TX_MAX_TARGET min_t(int, NET_RX_RING_SIZE, 256)
+#define TX_MAX_TARGET min_t(int, NET_TX_RING_SIZE, 256)
 
 struct netfront_stats {
        u64                     rx_packets;
index 7cf3d2f..1620088 100644 (file)
@@ -189,7 +189,7 @@ static int pcifront_bus_read(struct pci_bus *bus, unsigned int devfn,
 
        if (verbose_request)
                dev_info(&pdev->xdev->dev,
-                        "read dev=%04x:%02x:%02x.%01x - offset %x size %d\n",
+                        "read dev=%04x:%02x:%02x.%d - offset %x size %d\n",
                         pci_domain_nr(bus), bus->number, PCI_SLOT(devfn),
                         PCI_FUNC(devfn), where, size);
 
@@ -228,7 +228,7 @@ static int pcifront_bus_write(struct pci_bus *bus, unsigned int devfn,
 
        if (verbose_request)
                dev_info(&pdev->xdev->dev,
-                        "write dev=%04x:%02x:%02x.%01x - "
+                        "write dev=%04x:%02x:%02x.%d - "
                         "offset %x size %d val %x\n",
                         pci_domain_nr(bus), bus->number,
                         PCI_SLOT(devfn), PCI_FUNC(devfn), where, size, val);
@@ -432,7 +432,7 @@ static int __devinit pcifront_scan_bus(struct pcifront_device *pdev,
                d = pci_scan_single_device(b, devfn);
                if (d)
                        dev_info(&pdev->xdev->dev, "New device on "
-                                "%04x:%02x:%02x.%02x found.\n", domain, bus,
+                                "%04x:%02x:%02x.%d found.\n", domain, bus,
                                 PCI_SLOT(devfn), PCI_FUNC(devfn));
        }
 
@@ -1041,7 +1041,7 @@ static int pcifront_detach_devices(struct pcifront_device *pdev)
                pci_dev = pci_get_slot(pci_bus, PCI_DEVFN(slot, func));
                if (!pci_dev) {
                        dev_dbg(&pdev->xdev->dev,
-                               "Cannot get PCI device %04x:%02x:%02x.%02x\n",
+                               "Cannot get PCI device %04x:%02x:%02x.%d\n",
                                domain, bus, slot, func);
                        continue;
                }
@@ -1049,7 +1049,7 @@ static int pcifront_detach_devices(struct pcifront_device *pdev)
                pci_dev_put(pci_dev);
 
                dev_dbg(&pdev->xdev->dev,
-                       "PCI device %04x:%02x:%02x.%02x removed.\n",
+                       "PCI device %04x:%02x:%02x.%d removed.\n",
                        domain, bus, slot, func);
        }
 
index 749c2a1..1932029 100644 (file)
@@ -1269,10 +1269,8 @@ static int pcmcia_bus_add(struct pcmcia_socket *skt)
 
 static int pcmcia_bus_early_resume(struct pcmcia_socket *skt)
 {
-       if (!verify_cis_cache(skt)) {
-               pcmcia_put_socket(skt);
+       if (!verify_cis_cache(skt))
                return 0;
-       }
 
        dev_dbg(&skt->dev, "cis mismatch - different card\n");
 
index 5986690..27f2fe3 100644 (file)
@@ -205,7 +205,8 @@ static int __devexit pcmcia_remove(struct sa1111_dev *dev)
 
        dev_set_drvdata(&dev->dev, NULL);
 
-       for (; next = s->next, s; s = next) {
+       for (; s; s = next) {
+               next = s->next;
                soc_pcmcia_remove_one(&s->soc);
                kfree(s);
        }
index 569bdb3..8fe15cf 100644 (file)
@@ -510,10 +510,12 @@ static struct dentry *debugfs_root;
 
 static void pinctrl_init_device_debugfs(struct pinctrl_dev *pctldev)
 {
-       static struct dentry *device_root;
+       struct dentry *device_root;
 
        device_root = debugfs_create_dir(dev_name(pctldev->dev),
                                         debugfs_root);
+       pctldev->device_root = device_root;
+
        if (IS_ERR(device_root) || !device_root) {
                pr_warn("failed to create debugfs directory for %s\n",
                        dev_name(pctldev->dev));
@@ -529,6 +531,11 @@ static void pinctrl_init_device_debugfs(struct pinctrl_dev *pctldev)
        pinconf_init_device_debugfs(device_root, pctldev);
 }
 
+static void pinctrl_remove_device_debugfs(struct pinctrl_dev *pctldev)
+{
+       debugfs_remove_recursive(pctldev->device_root);
+}
+
 static void pinctrl_init_debugfs(void)
 {
        debugfs_root = debugfs_create_dir("pinctrl", NULL);
@@ -553,6 +560,10 @@ static void pinctrl_init_debugfs(void)
 {
 }
 
+static void pinctrl_remove_device_debugfs(struct pinctrl_dev *pctldev)
+{
+}
+
 #endif
 
 /**
@@ -572,40 +583,40 @@ struct pinctrl_dev *pinctrl_register(struct pinctrl_desc *pctldesc,
        if (pctldesc->name == NULL)
                return NULL;
 
+       pctldev = kzalloc(sizeof(struct pinctrl_dev), GFP_KERNEL);
+       if (pctldev == NULL)
+               return NULL;
+
+       /* Initialize pin control device struct */
+       pctldev->owner = pctldesc->owner;
+       pctldev->desc = pctldesc;
+       pctldev->driver_data = driver_data;
+       INIT_RADIX_TREE(&pctldev->pin_desc_tree, GFP_KERNEL);
+       spin_lock_init(&pctldev->pin_desc_tree_lock);
+       INIT_LIST_HEAD(&pctldev->gpio_ranges);
+       mutex_init(&pctldev->gpio_ranges_lock);
+       pctldev->dev = dev;
+
        /* If we're implementing pinmuxing, check the ops for sanity */
        if (pctldesc->pmxops) {
-               ret = pinmux_check_ops(pctldesc->pmxops);
+               ret = pinmux_check_ops(pctldev);
                if (ret) {
                        pr_err("%s pinmux ops lacks necessary functions\n",
                               pctldesc->name);
-                       return NULL;
+                       goto out_err;
                }
        }
 
        /* If we're implementing pinconfig, check the ops for sanity */
        if (pctldesc->confops) {
-               ret = pinconf_check_ops(pctldesc->confops);
+               ret = pinconf_check_ops(pctldev);
                if (ret) {
                        pr_err("%s pin config ops lacks necessary functions\n",
                               pctldesc->name);
-                       return NULL;
+                       goto out_err;
                }
        }
 
-       pctldev = kzalloc(sizeof(struct pinctrl_dev), GFP_KERNEL);
-       if (pctldev == NULL)
-               return NULL;
-
-       /* Initialize pin control device struct */
-       pctldev->owner = pctldesc->owner;
-       pctldev->desc = pctldesc;
-       pctldev->driver_data = driver_data;
-       INIT_RADIX_TREE(&pctldev->pin_desc_tree, GFP_KERNEL);
-       spin_lock_init(&pctldev->pin_desc_tree_lock);
-       INIT_LIST_HEAD(&pctldev->gpio_ranges);
-       mutex_init(&pctldev->gpio_ranges_lock);
-       pctldev->dev = dev;
-
        /* Register all the pins */
        pr_debug("try to register %d pins on %s...\n",
                 pctldesc->npins, pctldesc->name);
@@ -641,6 +652,7 @@ void pinctrl_unregister(struct pinctrl_dev *pctldev)
        if (pctldev == NULL)
                return;
 
+       pinctrl_remove_device_debugfs(pctldev);
        pinmux_unhog_maps(pctldev);
        /* TODO: check that no pinmuxes are still active? */
        mutex_lock(&pinctrldev_list_mutex);
index 177a331..cfa86da 100644 (file)
@@ -41,6 +41,9 @@ struct pinctrl_dev {
        struct device *dev;
        struct module *owner;
        void *driver_data;
+#ifdef CONFIG_DEBUG_FS
+       struct dentry *device_root;
+#endif
 #ifdef CONFIG_PINMUX
        struct mutex pinmux_hogs_lock;
        struct list_head pinmux_hogs;
index 1259872..9fb7545 100644 (file)
@@ -205,8 +205,10 @@ int pin_config_group_set(const char *dev_name, const char *pin_group,
 }
 EXPORT_SYMBOL(pin_config_group_set);
 
-int pinconf_check_ops(const struct pinconf_ops *ops)
+int pinconf_check_ops(struct pinctrl_dev *pctldev)
 {
+       const struct pinconf_ops *ops = pctldev->desc->confops;
+
        /* We must be able to read out pin status */
        if (!ops->pin_config_get && !ops->pin_config_group_get)
                return -EINVAL;
@@ -236,7 +238,7 @@ static int pinconf_pins_show(struct seq_file *s, void *what)
        seq_puts(s, "Format: pin (name): pinmux setting array\n");
 
        /* The pin number can be retrived from the pin controller descriptor */
-       for (i = 0; pin < pctldev->desc->npins; i++) {
+       for (i = 0; i < pctldev->desc->npins; i++) {
                struct pin_desc *desc;
 
                pin = pctldev->desc->pins[i].number;
index e7dc616..006b77f 100644 (file)
@@ -13,7 +13,7 @@
 
 #ifdef CONFIG_PINCONF
 
-int pinconf_check_ops(const struct pinconf_ops *ops);
+int pinconf_check_ops(struct pinctrl_dev *pctldev);
 void pinconf_init_device_debugfs(struct dentry *devroot,
                                 struct pinctrl_dev *pctldev);
 int pin_config_get_for_pin(struct pinctrl_dev *pctldev, unsigned pin,
@@ -23,7 +23,7 @@ int pin_config_set_for_pin(struct pinctrl_dev *pctldev, unsigned pin,
 
 #else
 
-static inline int pinconf_check_ops(const struct pinconf_ops *ops)
+static inline int pinconf_check_ops(struct pinctrl_dev *pctldev)
 {
        return 0;
 }
index a76a348..7c3193f 100644 (file)
@@ -53,11 +53,6 @@ struct pinmux_group {
  * @dev: the device using this pinmux
  * @usecount: the number of active users of this mux setting, used to keep
  *     track of nested use cases
- * @pins: an array of discrete physical pins used in this mapping, taken
- *     from the global pin enumeration space (copied from pinmux map)
- * @num_pins: the number of pins in this mapping array, i.e. the number of
- *     elements in .pins so we can iterate over that array (copied from
- *     pinmux map)
  * @pctldev: pin control device handling this pinmux
  * @func_selector: the function selector for the pinmux device handling
  *     this pinmux
@@ -152,8 +147,7 @@ static int pin_request(struct pinctrl_dev *pctldev,
                status = 0;
 
        if (status)
-               dev_err(pctldev->dev, "->request on device %s failed "
-                      "for pin %d\n",
+               dev_err(pctldev->dev, "->request on device %s failed for pin %d\n",
                       pctldev->desc->name, pin);
 out_free_pin:
        if (status) {
@@ -355,21 +349,20 @@ int __init pinmux_register_mappings(struct pinmux_map const *maps,
        /* First sanity check the new mapping */
        for (i = 0; i < num_maps; i++) {
                if (!maps[i].name) {
-                       pr_err("failed to register map %d: "
-                              "no map name given\n", i);
+                       pr_err("failed to register map %d: no map name given\n",
+                                       i);
                        return -EINVAL;
                }
 
                if (!maps[i].ctrl_dev && !maps[i].ctrl_dev_name) {
-                       pr_err("failed to register map %s (%d): "
-                              "no pin control device given\n",
+                       pr_err("failed to register map %s (%d): no pin control device given\n",
                               maps[i].name, i);
                        return -EINVAL;
                }
 
                if (!maps[i].function) {
-                       pr_err("failed to register map %s (%d): "
-                              "no function ID given\n", maps[i].name, i);
+                       pr_err("failed to register map %s (%d): no function ID given\n",
+                                       maps[i].name, i);
                        return -EINVAL;
                }
 
@@ -411,7 +404,7 @@ int __init pinmux_register_mappings(struct pinmux_map const *maps,
 }
 
 /**
- * acquire_pins() - acquire all the pins for a certain funcion on a pinmux
+ * acquire_pins() - acquire all the pins for a certain function on a pinmux
  * @pctldev: the device to take the pins on
  * @func_selector: the function selector to acquire the pins for
  * @group_selector: the group selector containing the pins to acquire
@@ -442,8 +435,7 @@ static int acquire_pins(struct pinctrl_dev *pctldev,
                ret = pin_request(pctldev, pins[i], func, NULL);
                if (ret) {
                        dev_err(pctldev->dev,
-                               "could not get pin %d for function %s "
-                               "on device %s - conflicting mux mappings?\n",
+                               "could not get pin %d for function %s on device %s - conflicting mux mappings?\n",
                                pins[i], func ? : "(undefined)",
                                pinctrl_dev_get_name(pctldev));
                        /* On error release all taken pins */
@@ -458,7 +450,7 @@ static int acquire_pins(struct pinctrl_dev *pctldev,
 
 /**
  * release_pins() - release pins taken by earlier acquirement
- * @pctldev: the device to free the pinx on
+ * @pctldev: the device to free the pins on
  * @group_selector: the group selector containing the pins to free
  */
 static void release_pins(struct pinctrl_dev *pctldev,
@@ -473,8 +465,7 @@ static void release_pins(struct pinctrl_dev *pctldev,
        ret = pctlops->get_group_pins(pctldev, group_selector,
                                      &pins, &num_pins);
        if (ret) {
-               dev_err(pctldev->dev, "could not get pins to release for "
-                       "group selector %d\n",
+               dev_err(pctldev->dev, "could not get pins to release for group selector %d\n",
                        group_selector);
                return;
        }
@@ -526,8 +517,7 @@ static int pinmux_check_pin_group(struct pinctrl_dev *pctldev,
                ret = pinctrl_get_group_selector(pctldev, groups[0]);
                if (ret < 0) {
                        dev_err(pctldev->dev,
-                               "function %s wants group %s but the pin "
-                               "controller does not seem to have that group\n",
+                               "function %s wants group %s but the pin controller does not seem to have that group\n",
                                pmxops->get_function_name(pctldev, func_selector),
                                groups[0]);
                        return ret;
@@ -535,8 +525,7 @@ static int pinmux_check_pin_group(struct pinctrl_dev *pctldev,
 
                if (num_groups > 1)
                        dev_dbg(pctldev->dev,
-                               "function %s support more than one group, "
-                               "default-selecting first group %s (%d)\n",
+                               "function %s support more than one group, default-selecting first group %s (%d)\n",
                                pmxops->get_function_name(pctldev, func_selector),
                                groups[0],
                                ret);
@@ -628,10 +617,8 @@ static int pinmux_enable_muxmap(struct pinctrl_dev *pctldev,
 
        if (pmx->pctldev && pmx->pctldev != pctldev) {
                dev_err(pctldev->dev,
-                       "different pin control devices given for device %s, "
-                       "function %s\n",
-                       devname,
-                       map->function);
+                       "different pin control devices given for device %s, function %s\n",
+                       devname, map->function);
                return -EINVAL;
        }
        pmx->dev = dev;
@@ -695,7 +682,6 @@ static void pinmux_free_groups(struct pinmux *pmx)
  */
 struct pinmux *pinmux_get(struct device *dev, const char *name)
 {
-
        struct pinmux_map const *map = NULL;
        struct pinctrl_dev *pctldev = NULL;
        const char *devname = NULL;
@@ -745,8 +731,7 @@ struct pinmux *pinmux_get(struct device *dev, const char *name)
                        else if (map->ctrl_dev_name)
                                devname = map->ctrl_dev_name;
 
-                       pr_warning("could not find a pinctrl device for pinmux "
-                                  "function %s, fishy, they shall all have one\n",
+                       pr_warning("could not find a pinctrl device for pinmux function %s, fishy, they shall all have one\n",
                                   map->function);
                        pr_warning("given pinctrl device name: %s",
                                   devname ? devname : "UNDEFINED");
@@ -904,8 +889,11 @@ void pinmux_disable(struct pinmux *pmx)
 }
 EXPORT_SYMBOL_GPL(pinmux_disable);
 
-int pinmux_check_ops(const struct pinmux_ops *ops)
+int pinmux_check_ops(struct pinctrl_dev *pctldev)
 {
+       const struct pinmux_ops *ops = pctldev->desc->pmxops;
+       unsigned selector = 0;
+
        /* Check that we implement required operations */
        if (!ops->list_functions ||
            !ops->get_function_name ||
@@ -914,6 +902,18 @@ int pinmux_check_ops(const struct pinmux_ops *ops)
            !ops->disable)
                return -EINVAL;
 
+       /* Check that all functions registered have names */
+       while (ops->list_functions(pctldev, selector) >= 0) {
+               const char *fname = ops->get_function_name(pctldev,
+                                                          selector);
+               if (!fname) {
+                       pr_err("pinmux ops has no name for function%u\n",
+                               selector);
+                       return -EINVAL;
+               }
+               selector++;
+       }
+
        return 0;
 }
 
@@ -932,8 +932,8 @@ static int pinmux_hog_map(struct pinctrl_dev *pctldev,
                 * without any problems, so then we can hog pinmuxes for
                 * all devices that just want a static pin mux at this point.
                 */
-               dev_err(pctldev->dev, "map %s wants to hog a non-system "
-                       "pinmux, this is not going to work\n", map->name);
+               dev_err(pctldev->dev, "map %s wants to hog a non-system pinmux, this is not going to work\n",
+                               map->name);
                return -EINVAL;
        }
 
@@ -993,9 +993,12 @@ int pinmux_hog_maps(struct pinctrl_dev *pctldev)
        for (i = 0; i < pinmux_maps_num; i++) {
                struct pinmux_map const *map = &pinmux_maps[i];
 
-               if (((map->ctrl_dev == dev) ||
-                    !strcmp(map->ctrl_dev_name, devname)) &&
-                   map->hog_on_boot) {
+               if (!map->hog_on_boot)
+                       continue;
+
+               if ((map->ctrl_dev == dev) ||
+                       (map->ctrl_dev_name &&
+                               !strcmp(map->ctrl_dev_name, devname))) {
                        /* OK time to hog! */
                        ret = pinmux_hog_map(pctldev, map);
                        if (ret)
@@ -1122,13 +1125,15 @@ static int pinmux_show(struct seq_file *s, void *what)
 
                seq_printf(s, "device: %s function: %s (%u),",
                           pinctrl_dev_get_name(pmx->pctldev),
-                          pmxops->get_function_name(pctldev, pmx->func_selector),
+                          pmxops->get_function_name(pctldev,
+                                  pmx->func_selector),
                           pmx->func_selector);
 
                seq_printf(s, " groups: [");
                list_for_each_entry(grp, &pmx->groups, node) {
                        seq_printf(s, " %s (%u)",
-                                  pctlops->get_group_name(pctldev, grp->group_selector),
+                                  pctlops->get_group_name(pctldev,
+                                          grp->group_selector),
                                   grp->group_selector);
                }
                seq_printf(s, " ]");
index 844500b..97f5222 100644 (file)
@@ -12,7 +12,7 @@
  */
 #ifdef CONFIG_PINMUX
 
-int pinmux_check_ops(const struct pinmux_ops *ops);
+int pinmux_check_ops(struct pinctrl_dev *pctldev);
 void pinmux_init_device_debugfs(struct dentry *devroot,
                                struct pinctrl_dev *pctldev);
 void pinmux_init_debugfs(struct dentry *subsys_root);
@@ -21,7 +21,7 @@ void pinmux_unhog_maps(struct pinctrl_dev *pctldev);
 
 #else
 
-static inline int pinmux_check_ops(const struct pinmux_ops *ops)
+static inline int pinmux_check_ops(struct pinctrl_dev *pctldev)
 {
        return 0;
 }
index 98bf567..1ed6ea0 100644 (file)
 
 #define BQ27500_REG_SOC                        0x2C
 #define BQ27500_REG_DCAP               0x3C /* Design capacity */
-#define BQ27500_FLAG_DSG               BIT(0) /* Discharging */
+#define BQ27500_FLAG_DSC               BIT(0)
 #define BQ27500_FLAG_SOCF              BIT(1) /* State-of-Charge threshold final */
 #define BQ27500_FLAG_SOC1              BIT(2) /* State-of-Charge threshold 1 */
-#define BQ27500_FLAG_CHG               BIT(8) /* Charging */
-#define BQ27500_FLAG_FC                        BIT(9) /* Fully charged */
+#define BQ27500_FLAG_FC                        BIT(9)
 
 #define BQ27000_RS                     20 /* Resistor sense */
 
@@ -312,7 +311,7 @@ static void bq27x00_update(struct bq27x00_device_info *di)
        struct bq27x00_reg_cache cache = {0, };
        bool is_bq27500 = di->chip == BQ27500;
 
-       cache.flags = bq27x00_read(di, BQ27x00_REG_FLAGS, is_bq27500);
+       cache.flags = bq27x00_read(di, BQ27x00_REG_FLAGS, !is_bq27500);
        if (cache.flags >= 0) {
                if (!is_bq27500 && (cache.flags & BQ27000_FLAG_CI)) {
                        dev_info(di->dev, "battery is not calibrated! ignoring capacity values\n");
@@ -401,14 +400,10 @@ static int bq27x00_battery_status(struct bq27x00_device_info *di,
        if (di->chip == BQ27500) {
                if (di->cache.flags & BQ27500_FLAG_FC)
                        status = POWER_SUPPLY_STATUS_FULL;
-               else if (di->cache.flags & BQ27500_FLAG_DSG)
+               else if (di->cache.flags & BQ27500_FLAG_DSC)
                        status = POWER_SUPPLY_STATUS_DISCHARGING;
-               else if (di->cache.flags & BQ27500_FLAG_CHG)
-                       status = POWER_SUPPLY_STATUS_CHARGING;
-               else if (power_supply_am_i_supplied(&di->bat))
-                       status = POWER_SUPPLY_STATUS_NOT_CHARGING;
                else
-                       status = POWER_SUPPLY_STATUS_UNKNOWN;
+                       status = POWER_SUPPLY_STATUS_CHARGING;
        } else {
                if (di->cache.flags & BQ27000_FLAG_FC)
                        status = POWER_SUPPLY_STATUS_FULL;
index 0378d01..88fd971 100644 (file)
@@ -974,10 +974,11 @@ static int __devexit charger_manager_remove(struct platform_device *pdev)
        return 0;
 }
 
-const struct platform_device_id charger_manager_id[] = {
+static const struct platform_device_id charger_manager_id[] = {
        { "charger-manager", 0 },
        { },
 };
+MODULE_DEVICE_TABLE(platform, charger_manager_id);
 
 static int cm_suspend_prepare(struct device *dev)
 {
@@ -1069,4 +1070,3 @@ module_exit(charger_manager_cleanup);
 MODULE_AUTHOR("MyungJoo Ham <myungjoo.ham@samsung.com>");
 MODULE_DESCRIPTION("Charger Manager");
 MODULE_LICENSE("GPL");
-MODULE_ALIAS("charger-manager");
index b15b575..c53dd12 100644 (file)
@@ -464,6 +464,7 @@ static int __devexit lp8727_remove(struct i2c_client *cl)
 
 static const struct i2c_device_id lp8727_ids[] = {
        {"lp8727", 0},
+       { }
 };
 
 static struct i2c_driver lp8727_driver = {
index b06a239..d0e1180 100644 (file)
@@ -150,7 +150,7 @@ static int max8649_enable_time(struct regulator_dev *rdev)
        if (ret != 0)
                return ret;
        val &= MAX8649_VOL_MASK;
-       voltage = max8649_list_voltage(rdev, (unsigned char)ret); /* uV */
+       voltage = max8649_list_voltage(rdev, (unsigned char)val); /* uV */
 
        /* get rate */
        ret = regmap_read(info->regmap, MAX8649_RAMP, &val);
index 80ecafe..62dcd0a 100644 (file)
@@ -254,6 +254,7 @@ int __devinit mc13xxx_get_num_regulators_dt(struct platform_device *pdev)
 
        return num;
 }
+EXPORT_SYMBOL_GPL(mc13xxx_get_num_regulators_dt);
 
 struct mc13xxx_regulator_init_data * __devinit mc13xxx_parse_regulators_dt(
        struct platform_device *pdev, struct mc13xxx_regulator *regulators,
@@ -291,6 +292,7 @@ struct mc13xxx_regulator_init_data * __devinit mc13xxx_parse_regulators_dt(
 
        return data;
 }
+EXPORT_SYMBOL_GPL(mc13xxx_parse_regulators_dt);
 #endif
 
 MODULE_LICENSE("GPL v2");
index f1651eb..679734d 100644 (file)
@@ -35,7 +35,7 @@ static void of_get_regulation_constraints(struct device_node *np,
        if (constraints->min_uV != constraints->max_uV)
                constraints->valid_ops_mask |= REGULATOR_CHANGE_VOLTAGE;
        /* Only one voltage?  Then make sure it's set. */
-       if (constraints->min_uV == constraints->max_uV)
+       if (min_uV && max_uV && constraints->min_uV == constraints->max_uV)
                constraints->apply_uV = true;
 
        uV_offset = of_get_property(np, "regulator-microvolt-offset", NULL);
index e19a403..3a125b8 100644 (file)
@@ -774,7 +774,7 @@ config RTC_DRV_EP93XX
 
 config RTC_DRV_SA1100
        tristate "SA11x0/PXA2xx"
-       depends on ARCH_SA1100 || ARCH_PXA || ARCH_MMP
+       depends on ARCH_SA1100 || ARCH_PXA
        help
          If you say Y here you will get access to the real time clock
          built into your SA11x0 or PXA2xx CPU.
index 4595d3e..cb9a585 100644 (file)
 #include <linux/init.h>
 #include <linux/fs.h>
 #include <linux/interrupt.h>
+#include <linux/string.h>
 #include <linux/pm.h>
-#include <linux/slab.h>
-#include <linux/clk.h>
-#include <linux/io.h>
+#include <linux/bitops.h>
 
 #include <mach/hardware.h>
 #include <asm/irq.h>
 
+#ifdef CONFIG_ARCH_PXA
+#include <mach/regs-rtc.h>
+#endif
+
 #define RTC_DEF_DIVIDER                (32768 - 1)
 #define RTC_DEF_TRIM           0
-#define RTC_FREQ               1024
-
-#define RCNR           0x00    /* RTC Count Register */
-#define RTAR           0x04    /* RTC Alarm Register */
-#define RTSR           0x08    /* RTC Status Register */
-#define RTTR           0x0c    /* RTC Timer Trim Register */
-
-#define RTSR_HZE       (1 << 3)        /* HZ interrupt enable */
-#define RTSR_ALE       (1 << 2)        /* RTC alarm interrupt enable */
-#define RTSR_HZ                (1 << 1)        /* HZ rising-edge detected */
-#define RTSR_AL                (1 << 0)        /* RTC alarm detected */
-
-#define rtc_readl(sa1100_rtc, reg)     \
-       readl_relaxed((sa1100_rtc)->base + (reg))
-#define rtc_writel(sa1100_rtc, reg, value)     \
-       writel_relaxed((value), (sa1100_rtc)->base + (reg))
-
-struct sa1100_rtc {
-       struct resource         *ress;
-       void __iomem            *base;
-       struct clk              *clk;
-       int                     irq_1Hz;
-       int                     irq_Alrm;
-       struct rtc_device       *rtc;
-       spinlock_t              lock;           /* Protects this structure */
-};
+
+static const unsigned long RTC_FREQ = 1024;
+static struct rtc_time rtc_alarm;
+static DEFINE_SPINLOCK(sa1100_rtc_lock);
+
+static inline int rtc_periodic_alarm(struct rtc_time *tm)
+{
+       return  (tm->tm_year == -1) ||
+               ((unsigned)tm->tm_mon >= 12) ||
+               ((unsigned)(tm->tm_mday - 1) >= 31) ||
+               ((unsigned)tm->tm_hour > 23) ||
+               ((unsigned)tm->tm_min > 59) ||
+               ((unsigned)tm->tm_sec > 59);
+}
+
 /*
  * Calculate the next alarm time given the requested alarm time mask
  * and the current time.
@@ -90,26 +82,46 @@ static void rtc_next_alarm_time(struct rtc_time *next, struct rtc_time *now,
        }
 }
 
+static int rtc_update_alarm(struct rtc_time *alrm)
+{
+       struct rtc_time alarm_tm, now_tm;
+       unsigned long now, time;
+       int ret;
+
+       do {
+               now = RCNR;
+               rtc_time_to_tm(now, &now_tm);
+               rtc_next_alarm_time(&alarm_tm, &now_tm, alrm);
+               ret = rtc_tm_to_time(&alarm_tm, &time);
+               if (ret != 0)
+                       break;
+
+               RTSR = RTSR & (RTSR_HZE|RTSR_ALE|RTSR_AL);
+               RTAR = time;
+       } while (now != RCNR);
+
+       return ret;
+}
+
 static irqreturn_t sa1100_rtc_interrupt(int irq, void *dev_id)
 {
        struct platform_device *pdev = to_platform_device(dev_id);
-       struct sa1100_rtc *sa1100_rtc = platform_get_drvdata(pdev);
+       struct rtc_device *rtc = platform_get_drvdata(pdev);
        unsigned int rtsr;
        unsigned long events = 0;
 
-       spin_lock(&sa1100_rtc->lock);
+       spin_lock(&sa1100_rtc_lock);
 
+       rtsr = RTSR;
        /* clear interrupt sources */
-       rtsr = rtc_readl(sa1100_rtc, RTSR);
-       rtc_writel(sa1100_rtc, RTSR, 0);
-
+       RTSR = 0;
        /* Fix for a nasty initialization problem the in SA11xx RTSR register.
         * See also the comments in sa1100_rtc_probe(). */
        if (rtsr & (RTSR_ALE | RTSR_HZE)) {
                /* This is the original code, before there was the if test
                 * above. This code does not clear interrupts that were not
                 * enabled. */
-               rtc_writel(sa1100_rtc, RTSR, (RTSR_AL | RTSR_HZ) & (rtsr >> 2));
+               RTSR = (RTSR_AL | RTSR_HZ) & (rtsr >> 2);
        } else {
                /* For some reason, it is possible to enter this routine
                 * without interruptions enabled, it has been tested with
@@ -118,13 +130,13 @@ static irqreturn_t sa1100_rtc_interrupt(int irq, void *dev_id)
                 * This situation leads to an infinite "loop" of interrupt
                 * routine calling and as a result the processor seems to
                 * lock on its first call to open(). */
-               rtc_writel(sa1100_rtc, RTSR, (RTSR_AL | RTSR_HZ));
+               RTSR = RTSR_AL | RTSR_HZ;
        }
 
        /* clear alarm interrupt if it has occurred */
        if (rtsr & RTSR_AL)
                rtsr &= ~RTSR_ALE;
-       rtc_writel(sa1100_rtc, RTSR, rtsr & (RTSR_ALE | RTSR_HZE));
+       RTSR = rtsr & (RTSR_ALE | RTSR_HZE);
 
        /* update irq data & counter */
        if (rtsr & RTSR_AL)
@@ -132,100 +144,89 @@ static irqreturn_t sa1100_rtc_interrupt(int irq, void *dev_id)
        if (rtsr & RTSR_HZ)
                events |= RTC_UF | RTC_IRQF;
 
-       rtc_update_irq(sa1100_rtc->rtc, 1, events);
+       rtc_update_irq(rtc, 1, events);
 
-       spin_unlock(&sa1100_rtc->lock);
+       if (rtsr & RTSR_AL && rtc_periodic_alarm(&rtc_alarm))
+               rtc_update_alarm(&rtc_alarm);
+
+       spin_unlock(&sa1100_rtc_lock);
 
        return IRQ_HANDLED;
 }
 
 static int sa1100_rtc_open(struct device *dev)
 {
-       struct sa1100_rtc *sa1100_rtc = dev_get_drvdata(dev);
        int ret;
+       struct platform_device *plat_dev = to_platform_device(dev);
+       struct rtc_device *rtc = platform_get_drvdata(plat_dev);
 
-       ret = request_irq(sa1100_rtc->irq_1Hz, sa1100_rtc_interrupt,
-                               IRQF_DISABLED, "rtc 1Hz", dev);
+       ret = request_irq(IRQ_RTC1Hz, sa1100_rtc_interrupt, IRQF_DISABLED,
+               "rtc 1Hz", dev);
        if (ret) {
-               dev_err(dev, "IRQ %d already in use.\n", sa1100_rtc->irq_1Hz);
+               dev_err(dev, "IRQ %d already in use.\n", IRQ_RTC1Hz);
                goto fail_ui;
        }
-       ret = request_irq(sa1100_rtc->irq_Alrm, sa1100_rtc_interrupt,
-                               IRQF_DISABLED, "rtc Alrm", dev);
+       ret = request_irq(IRQ_RTCAlrm, sa1100_rtc_interrupt, IRQF_DISABLED,
+               "rtc Alrm", dev);
        if (ret) {
-               dev_err(dev, "IRQ %d already in use.\n", sa1100_rtc->irq_Alrm);
+               dev_err(dev, "IRQ %d already in use.\n", IRQ_RTCAlrm);
                goto fail_ai;
        }
-       sa1100_rtc->rtc->max_user_freq = RTC_FREQ;
-       rtc_irq_set_freq(sa1100_rtc->rtc, NULL, RTC_FREQ);
+       rtc->max_user_freq = RTC_FREQ;
+       rtc_irq_set_freq(rtc, NULL, RTC_FREQ);
 
        return 0;
 
  fail_ai:
-       free_irq(sa1100_rtc->irq_1Hz, dev);
+       free_irq(IRQ_RTC1Hz, dev);
  fail_ui:
        return ret;
 }
 
 static void sa1100_rtc_release(struct device *dev)
 {
-       struct sa1100_rtc *sa1100_rtc = dev_get_drvdata(dev);
-
-       spin_lock_irq(&sa1100_rtc->lock);
-       rtc_writel(sa1100_rtc, RTSR, 0);
-       spin_unlock_irq(&sa1100_rtc->lock);
+       spin_lock_irq(&sa1100_rtc_lock);
+       RTSR = 0;
+       spin_unlock_irq(&sa1100_rtc_lock);
 
-       free_irq(sa1100_rtc->irq_Alrm, dev);
-       free_irq(sa1100_rtc->irq_1Hz, dev);
+       free_irq(IRQ_RTCAlrm, dev);
+       free_irq(IRQ_RTC1Hz, dev);
 }
 
 static int sa1100_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
 {
-       struct sa1100_rtc *sa1100_rtc = dev_get_drvdata(dev);
-       unsigned int rtsr;
-
-       spin_lock_irq(&sa1100_rtc->lock);
-
-       rtsr = rtc_readl(sa1100_rtc, RTSR);
+       spin_lock_irq(&sa1100_rtc_lock);
        if (enabled)
-               rtsr |= RTSR_ALE;
+               RTSR |= RTSR_ALE;
        else
-               rtsr &= ~RTSR_ALE;
-       rtc_writel(sa1100_rtc, RTSR, rtsr);
-
-       spin_unlock_irq(&sa1100_rtc->lock);
+               RTSR &= ~RTSR_ALE;
+       spin_unlock_irq(&sa1100_rtc_lock);
        return 0;
 }
 
 static int sa1100_rtc_read_time(struct device *dev, struct rtc_time *tm)
 {
-       struct sa1100_rtc *sa1100_rtc = dev_get_drvdata(dev);
-
-       rtc_time_to_tm(rtc_readl(sa1100_rtc, RCNR), tm);
+       rtc_time_to_tm(RCNR, tm);
        return 0;
 }
 
 static int sa1100_rtc_set_time(struct device *dev, struct rtc_time *tm)
 {
-       struct sa1100_rtc *sa1100_rtc = dev_get_drvdata(dev);
        unsigned long time;
        int ret;
 
        ret = rtc_tm_to_time(tm, &time);
        if (ret == 0)
-               rtc_writel(sa1100_rtc, RCNR, time);
+               RCNR = time;
        return ret;
 }
 
 static int sa1100_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
 {
-       struct sa1100_rtc *sa1100_rtc = dev_get_drvdata(dev);
-       unsigned long time;
-       unsigned int rtsr;
+       u32     rtsr;
 
-       time = rtc_readl(sa1100_rtc, RCNR);
-       rtc_time_to_tm(time, &alrm->time);
-       rtsr = rtc_readl(sa1100_rtc, RTSR);
+       memcpy(&alrm->time, &rtc_alarm, sizeof(struct rtc_time));
+       rtsr = RTSR;
        alrm->enabled = (rtsr & RTSR_ALE) ? 1 : 0;
        alrm->pending = (rtsr & RTSR_AL) ? 1 : 0;
        return 0;
@@ -233,39 +234,26 @@ static int sa1100_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
 
 static int sa1100_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
 {
-       struct sa1100_rtc *sa1100_rtc = dev_get_drvdata(dev);
-       struct rtc_time now_tm, alarm_tm;
-       unsigned long time, alarm;
-       unsigned int rtsr;
-
-       spin_lock_irq(&sa1100_rtc->lock);
-
-       time = rtc_readl(sa1100_rtc, RCNR);
-       rtc_time_to_tm(time, &now_tm);
-       rtc_next_alarm_time(&alarm_tm, &now_tm, &alrm->time);
-       rtc_tm_to_time(&alarm_tm, &alarm);
-       rtc_writel(sa1100_rtc, RTAR, alarm);
-
-       rtsr = rtc_readl(sa1100_rtc, RTSR);
-       if (alrm->enabled)
-               rtsr |= RTSR_ALE;
-       else
-               rtsr &= ~RTSR_ALE;
-       rtc_writel(sa1100_rtc, RTSR, rtsr);
+       int ret;
 
-       spin_unlock_irq(&sa1100_rtc->lock);
+       spin_lock_irq(&sa1100_rtc_lock);
+       ret = rtc_update_alarm(&alrm->time);
+       if (ret == 0) {
+               if (alrm->enabled)
+                       RTSR |= RTSR_ALE;
+               else
+                       RTSR &= ~RTSR_ALE;
+       }
+       spin_unlock_irq(&sa1100_rtc_lock);
 
-       return 0;
+       return ret;
 }
 
 static int sa1100_rtc_proc(struct device *dev, struct seq_file *seq)
 {
-       struct sa1100_rtc *sa1100_rtc = dev_get_drvdata(dev);
+       seq_printf(seq, "trim/divider\t\t: 0x%08x\n", (u32) RTTR);
+       seq_printf(seq, "RTSR\t\t\t: 0x%08x\n", (u32)RTSR);
 
-       seq_printf(seq, "trim/divider\t\t: 0x%08x\n",
-                       rtc_readl(sa1100_rtc, RTTR));
-       seq_printf(seq, "RTSR\t\t\t: 0x%08x\n",
-                       rtc_readl(sa1100_rtc, RTSR));
        return 0;
 }
 
@@ -282,51 +270,7 @@ static const struct rtc_class_ops sa1100_rtc_ops = {
 
 static int sa1100_rtc_probe(struct platform_device *pdev)
 {
-       struct sa1100_rtc *sa1100_rtc;
-       unsigned int rttr;
-       int ret;
-
-       sa1100_rtc = kzalloc(sizeof(struct sa1100_rtc), GFP_KERNEL);
-       if (!sa1100_rtc)
-               return -ENOMEM;
-
-       spin_lock_init(&sa1100_rtc->lock);
-       platform_set_drvdata(pdev, sa1100_rtc);
-
-       ret = -ENXIO;
-       sa1100_rtc->ress = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       if (!sa1100_rtc->ress) {
-               dev_err(&pdev->dev, "No I/O memory resource defined\n");
-               goto err_ress;
-       }
-
-       sa1100_rtc->irq_1Hz = platform_get_irq(pdev, 0);
-       if (sa1100_rtc->irq_1Hz < 0) {
-               dev_err(&pdev->dev, "No 1Hz IRQ resource defined\n");
-               goto err_ress;
-       }
-       sa1100_rtc->irq_Alrm = platform_get_irq(pdev, 1);
-       if (sa1100_rtc->irq_Alrm < 0) {
-               dev_err(&pdev->dev, "No alarm IRQ resource defined\n");
-               goto err_ress;
-       }
-
-       ret = -ENOMEM;
-       sa1100_rtc->base = ioremap(sa1100_rtc->ress->start,
-                               resource_size(sa1100_rtc->ress));
-       if (!sa1100_rtc->base) {
-               dev_err(&pdev->dev, "Unable to map pxa RTC I/O memory\n");
-               goto err_map;
-       }
-
-       sa1100_rtc->clk = clk_get(&pdev->dev, NULL);
-       if (IS_ERR(sa1100_rtc->clk)) {
-               dev_err(&pdev->dev, "failed to find rtc clock source\n");
-               ret = PTR_ERR(sa1100_rtc->clk);
-               goto err_clk;
-       }
-       clk_prepare(sa1100_rtc->clk);
-       clk_enable(sa1100_rtc->clk);
+       struct rtc_device *rtc;
 
        /*
         * According to the manual we should be able to let RTTR be zero
@@ -335,24 +279,24 @@ static int sa1100_rtc_probe(struct platform_device *pdev)
         * If the clock divider is uninitialized then reset it to the
         * default value to get the 1Hz clock.
         */
-       if (rtc_readl(sa1100_rtc, RTTR) == 0) {
-               rttr = RTC_DEF_DIVIDER + (RTC_DEF_TRIM << 16);
-               rtc_writel(sa1100_rtc, RTTR, rttr);
-               dev_warn(&pdev->dev, "warning: initializing default clock"
-                        " divider/trim value\n");
+       if (RTTR == 0) {
+               RTTR = RTC_DEF_DIVIDER + (RTC_DEF_TRIM << 16);
+               dev_warn(&pdev->dev, "warning: "
+                       "initializing default clock divider/trim value\n");
                /* The current RTC value probably doesn't make sense either */
-               rtc_writel(sa1100_rtc, RCNR, 0);
+               RCNR = 0;
        }
 
        device_init_wakeup(&pdev->dev, 1);
 
-       sa1100_rtc->rtc = rtc_device_register(pdev->name, &pdev->dev,
-                                               &sa1100_rtc_ops, THIS_MODULE);
-       if (IS_ERR(sa1100_rtc->rtc)) {
-               dev_err(&pdev->dev, "Failed to register RTC device -> %d\n",
-                       ret);
-               goto err_rtc_reg;
-       }
+       rtc = rtc_device_register(pdev->name, &pdev->dev, &sa1100_rtc_ops,
+               THIS_MODULE);
+
+       if (IS_ERR(rtc))
+               return PTR_ERR(rtc);
+
+       platform_set_drvdata(pdev, rtc);
+
        /* Fix for a nasty initialization problem the in SA11xx RTSR register.
         * See also the comments in sa1100_rtc_interrupt().
         *
@@ -375,46 +319,33 @@ static int sa1100_rtc_probe(struct platform_device *pdev)
         *
         * Notice that clearing bit 1 and 0 is accomplished by writting ONES to
         * the corresponding bits in RTSR. */
-       rtc_writel(sa1100_rtc, RTSR, (RTSR_AL | RTSR_HZ));
+       RTSR = RTSR_AL | RTSR_HZ;
 
        return 0;
-
-err_rtc_reg:
-err_clk:
-       iounmap(sa1100_rtc->base);
-err_ress:
-err_map:
-       kfree(sa1100_rtc);
-       return ret;
 }
 
 static int sa1100_rtc_remove(struct platform_device *pdev)
 {
-       struct sa1100_rtc *sa1100_rtc = platform_get_drvdata(pdev);
+       struct rtc_device *rtc = platform_get_drvdata(pdev);
+
+       if (rtc)
+               rtc_device_unregister(rtc);
 
-       rtc_device_unregister(sa1100_rtc->rtc);
-       clk_disable(sa1100_rtc->clk);
-       clk_unprepare(sa1100_rtc->clk);
-       iounmap(sa1100_rtc->base);
        return 0;
 }
 
 #ifdef CONFIG_PM
 static int sa1100_rtc_suspend(struct device *dev)
 {
-       struct sa1100_rtc *sa1100_rtc = dev_get_drvdata(dev);
-
        if (device_may_wakeup(dev))
-               enable_irq_wake(sa1100_rtc->irq_Alrm);
+               enable_irq_wake(IRQ_RTCAlrm);
        return 0;
 }
 
 static int sa1100_rtc_resume(struct device *dev)
 {
-       struct sa1100_rtc *sa1100_rtc = dev_get_drvdata(dev);
-
        if (device_may_wakeup(dev))
-               disable_irq_wake(sa1100_rtc->irq_Alrm);
+               disable_irq_wake(IRQ_RTCAlrm);
        return 0;
 }
 
index eef27a1..110137e 100644 (file)
@@ -3261,6 +3261,12 @@ void dasd_generic_path_event(struct ccw_device *cdev, int *path_event)
                        device->path_data.tbvpm |= eventlpm;
                        dasd_schedule_device_bh(device);
                }
+               if (path_event[chp] & PE_PATHGROUP_ESTABLISHED) {
+                       DBF_DEV_EVENT(DBF_WARNING, device, "%s",
+                                     "Pathgroup re-established\n");
+                       if (device->discipline->kick_validate)
+                               device->discipline->kick_validate(device);
+               }
        }
        dasd_put_device(device);
 }
index 553b3c5..b3beed5 100644 (file)
@@ -189,14 +189,12 @@ int dasd_alias_make_device_known_to_lcu(struct dasd_device *device)
        unsigned long flags;
        struct alias_server *server, *newserver;
        struct alias_lcu *lcu, *newlcu;
-       int is_lcu_known;
        struct dasd_uid uid;
 
        private = (struct dasd_eckd_private *) device->private;
 
        device->discipline->get_uid(device, &uid);
        spin_lock_irqsave(&aliastree.lock, flags);
-       is_lcu_known = 1;
        server = _find_server(&uid);
        if (!server) {
                spin_unlock_irqrestore(&aliastree.lock, flags);
@@ -208,7 +206,6 @@ int dasd_alias_make_device_known_to_lcu(struct dasd_device *device)
                if (!server) {
                        list_add(&newserver->server, &aliastree.serverlist);
                        server = newserver;
-                       is_lcu_known = 0;
                } else {
                        /* someone was faster */
                        _free_server(newserver);
@@ -226,12 +223,10 @@ int dasd_alias_make_device_known_to_lcu(struct dasd_device *device)
                if (!lcu) {
                        list_add(&newlcu->lcu, &server->lculist);
                        lcu = newlcu;
-                       is_lcu_known = 0;
                } else {
                        /* someone was faster */
                        _free_lcu(newlcu);
                }
-               is_lcu_known = 0;
        }
        spin_lock(&lcu->lock);
        list_add(&device->alias_list, &lcu->inactive_devices);
@@ -239,64 +234,7 @@ int dasd_alias_make_device_known_to_lcu(struct dasd_device *device)
        spin_unlock(&lcu->lock);
        spin_unlock_irqrestore(&aliastree.lock, flags);
 
-       return is_lcu_known;
-}
-
-/*
- * The first device to be registered on an LCU will have to do
- * some additional setup steps to configure that LCU on the
- * storage server. All further devices should wait with their
- * initialization until the first device is done.
- * To synchronize this work, the first device will call
- * dasd_alias_lcu_setup_complete when it is done, and all
- * other devices will wait for it with dasd_alias_wait_for_lcu_setup.
- */
-void dasd_alias_lcu_setup_complete(struct dasd_device *device)
-{
-       unsigned long flags;
-       struct alias_server *server;
-       struct alias_lcu *lcu;
-       struct dasd_uid uid;
-
-       device->discipline->get_uid(device, &uid);
-       lcu = NULL;
-       spin_lock_irqsave(&aliastree.lock, flags);
-       server = _find_server(&uid);
-       if (server)
-               lcu = _find_lcu(server, &uid);
-       spin_unlock_irqrestore(&aliastree.lock, flags);
-       if (!lcu) {
-               DBF_EVENT_DEVID(DBF_ERR, device->cdev,
-                               "could not find lcu for %04x %02x",
-                               uid.ssid, uid.real_unit_addr);
-               WARN_ON(1);
-               return;
-       }
-       complete_all(&lcu->lcu_setup);
-}
-
-void dasd_alias_wait_for_lcu_setup(struct dasd_device *device)
-{
-       unsigned long flags;
-       struct alias_server *server;
-       struct alias_lcu *lcu;
-       struct dasd_uid uid;
-
-       device->discipline->get_uid(device, &uid);
-       lcu = NULL;
-       spin_lock_irqsave(&aliastree.lock, flags);
-       server = _find_server(&uid);
-       if (server)
-               lcu = _find_lcu(server, &uid);
-       spin_unlock_irqrestore(&aliastree.lock, flags);
-       if (!lcu) {
-               DBF_EVENT_DEVID(DBF_ERR, device->cdev,
-                               "could not find lcu for %04x %02x",
-                               uid.ssid, uid.real_unit_addr);
-               WARN_ON(1);
-               return;
-       }
-       wait_for_completion(&lcu->lcu_setup);
+       return 0;
 }
 
 /*
index bbcd5e9..70880be 100644 (file)
@@ -1534,6 +1534,10 @@ static void dasd_eckd_validate_server(struct dasd_device *device)
        struct dasd_eckd_private *private;
        int enable_pav;
 
+       private = (struct dasd_eckd_private *) device->private;
+       if (private->uid.type == UA_BASE_PAV_ALIAS ||
+           private->uid.type == UA_HYPER_PAV_ALIAS)
+               return;
        if (dasd_nopav || MACHINE_IS_VM)
                enable_pav = 0;
        else
@@ -1542,11 +1546,28 @@ static void dasd_eckd_validate_server(struct dasd_device *device)
 
        /* may be requested feature is not available on server,
         * therefore just report error and go ahead */
-       private = (struct dasd_eckd_private *) device->private;
        DBF_EVENT_DEVID(DBF_WARNING, device->cdev, "PSF-SSC for SSID %04x "
                        "returned rc=%d", private->uid.ssid, rc);
 }
 
+/*
+ * worker to do a validate server in case of a lost pathgroup
+ */
+static void dasd_eckd_do_validate_server(struct work_struct *work)
+{
+       struct dasd_device *device = container_of(work, struct dasd_device,
+                                                 kick_validate);
+       dasd_eckd_validate_server(device);
+       dasd_put_device(device);
+}
+
+static void dasd_eckd_kick_validate_server(struct dasd_device *device)
+{
+       dasd_get_device(device);
+       /* queue call to do_validate_server to the kernel event daemon. */
+       schedule_work(&device->kick_validate);
+}
+
 static u32 get_fcx_max_data(struct dasd_device *device)
 {
 #if defined(CONFIG_64BIT)
@@ -1588,10 +1609,13 @@ dasd_eckd_check_characteristics(struct dasd_device *device)
        struct dasd_eckd_private *private;
        struct dasd_block *block;
        struct dasd_uid temp_uid;
-       int is_known, rc, i;
+       int rc, i;
        int readonly;
        unsigned long value;
 
+       /* setup work queue for validate server*/
+       INIT_WORK(&device->kick_validate, dasd_eckd_do_validate_server);
+
        if (!ccw_device_is_pathgroup(device->cdev)) {
                dev_warn(&device->cdev->dev,
                         "A channel path group could not be established\n");
@@ -1651,22 +1675,12 @@ dasd_eckd_check_characteristics(struct dasd_device *device)
                block->base = device;
        }
 
-       /* register lcu with alias handling, enable PAV if this is a new lcu */
-       is_known = dasd_alias_make_device_known_to_lcu(device);
-       if (is_known < 0) {
-               rc = is_known;
+       /* register lcu with alias handling, enable PAV */
+       rc = dasd_alias_make_device_known_to_lcu(device);
+       if (rc)
                goto out_err2;
-       }
-       /*
-        * dasd_eckd_validate_server is done on the first device that
-        * is found for an LCU. All later other devices have to wait
-        * for it, so they will read the correct feature codes.
-        */
-       if (!is_known) {
-               dasd_eckd_validate_server(device);
-               dasd_alias_lcu_setup_complete(device);
-       } else
-               dasd_alias_wait_for_lcu_setup(device);
+
+       dasd_eckd_validate_server(device);
 
        /* device may report different configuration data after LCU setup */
        rc = dasd_eckd_read_conf(device);
@@ -4098,7 +4112,7 @@ static int dasd_eckd_restore_device(struct dasd_device *device)
 {
        struct dasd_eckd_private *private;
        struct dasd_eckd_characteristics temp_rdc_data;
-       int is_known, rc;
+       int rc;
        struct dasd_uid temp_uid;
        unsigned long flags;
 
@@ -4121,14 +4135,10 @@ static int dasd_eckd_restore_device(struct dasd_device *device)
                goto out_err;
 
        /* register lcu with alias handling, enable PAV if this is a new lcu */
-       is_known = dasd_alias_make_device_known_to_lcu(device);
-       if (is_known < 0)
-               return is_known;
-       if (!is_known) {
-               dasd_eckd_validate_server(device);
-               dasd_alias_lcu_setup_complete(device);
-       } else
-               dasd_alias_wait_for_lcu_setup(device);
+       rc = dasd_alias_make_device_known_to_lcu(device);
+       if (rc)
+               return rc;
+       dasd_eckd_validate_server(device);
 
        /* RE-Read Configuration Data */
        rc = dasd_eckd_read_conf(device);
@@ -4270,6 +4280,7 @@ static struct dasd_discipline dasd_eckd_discipline = {
        .restore = dasd_eckd_restore_device,
        .reload = dasd_eckd_reload_device,
        .get_uid = dasd_eckd_get_uid,
+       .kick_validate = dasd_eckd_kick_validate_server,
 };
 
 static int __init
index afe8c33..33a6743 100644 (file)
@@ -355,6 +355,7 @@ struct dasd_discipline {
        int (*reload) (struct dasd_device *);
 
        int (*get_uid) (struct dasd_device *, struct dasd_uid *);
+       void (*kick_validate) (struct dasd_device *);
 };
 
 extern struct dasd_discipline *dasd_diag_discipline_pointer;
@@ -455,6 +456,7 @@ struct dasd_device {
        struct work_struct kick_work;
        struct work_struct restore_device;
        struct work_struct reload_device;
+       struct work_struct kick_validate;
        struct timer_list timer;
 
        debug_info_t *debug_area;
index 3f9a47e..8293658 100644 (file)
@@ -299,7 +299,7 @@ config SPI_S3C24XX_FIQ
 
 config SPI_S3C64XX
        tristate "Samsung S3C64XX series type SPI"
-       depends on (ARCH_S3C64XX || ARCH_S5P64X0)
+       depends on (ARCH_S3C64XX || ARCH_S5P64X0 || ARCH_EXYNOS)
        select S3C64XX_DMA if ARCH_S3C64XX
        help
          SPI driver for Samsung S3C64XX and newer SoCs.
index 2a6429d..10182eb 100644 (file)
@@ -1720,7 +1720,7 @@ static int pch_spi_resume(struct pci_dev *pdev)
 
 #endif
 
-static struct pci_driver pch_spi_pcidev = {
+static struct pci_driver pch_spi_pcidev_driver = {
        .name = "pch_spi",
        .id_table = pch_spi_pcidev_id,
        .probe = pch_spi_probe,
@@ -1736,7 +1736,7 @@ static int __init pch_spi_init(void)
        if (ret)
                return ret;
 
-       ret = pci_register_driver(&pch_spi_pcidev);
+       ret = pci_register_driver(&pch_spi_pcidev_driver);
        if (ret)
                return ret;
 
@@ -1746,7 +1746,7 @@ module_init(pch_spi_init);
 
 static void __exit pch_spi_exit(void)
 {
-       pci_unregister_driver(&pch_spi_pcidev);
+       pci_unregister_driver(&pch_spi_pcidev_driver);
        platform_driver_unregister(&pch_spi_pd_driver);
 }
 module_exit(pch_spi_exit);
index 520e828..49d2091 100644 (file)
@@ -75,7 +75,7 @@ static u32 get_cfgspace_addr(struct ssb_pcicore *pc,
        u32 tmp;
 
        /* We do only have one cardbus device behind the bridge. */
-       if (pc->cardbusmode && (dev >= 1))
+       if (pc->cardbusmode && (dev > 1))
                goto out;
 
        if (bus == 0) {
index 21e2f4b..9e63472 100644 (file)
@@ -60,8 +60,6 @@ source "drivers/staging/rts5139/Kconfig"
 
 source "drivers/staging/frontier/Kconfig"
 
-source "drivers/staging/pohmelfs/Kconfig"
-
 source "drivers/staging/phison/Kconfig"
 
 source "drivers/staging/line6/Kconfig"
@@ -120,8 +118,6 @@ source "drivers/staging/cptm1217/Kconfig"
 
 source "drivers/staging/ste_rmi4/Kconfig"
 
-source "drivers/staging/gma500/Kconfig"
-
 source "drivers/staging/mei/Kconfig"
 
 source "drivers/staging/nvec/Kconfig"
index 7c5808d..943e148 100644 (file)
@@ -22,7 +22,6 @@ obj-$(CONFIG_R8712U)          += rtl8712/
 obj-$(CONFIG_RTS_PSTOR)                += rts_pstor/
 obj-$(CONFIG_RTS5139)          += rts5139/
 obj-$(CONFIG_TRANZPORT)                += frontier/
-obj-$(CONFIG_POHMELFS)         += pohmelfs/
 obj-$(CONFIG_IDE_PHISON)       += phison/
 obj-$(CONFIG_LINE6_USB)                += line6/
 obj-$(CONFIG_USB_SERIAL_QUATECH2)      += serqt_usb2/
@@ -52,7 +51,6 @@ obj-$(CONFIG_FT1000)          += ft1000/
 obj-$(CONFIG_SPEAKUP)          += speakup/
 obj-$(CONFIG_TOUCHSCREEN_CLEARPAD_TM1217)      += cptm1217/
 obj-$(CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI4)   += ste_rmi4/
-obj-$(CONFIG_DRM_PSB)          += gma500/
 obj-$(CONFIG_INTEL_MEI)                += mei/
 obj-$(CONFIG_MFD_NVEC)         += nvec/
 obj-$(CONFIG_DRM_OMAP)         += omapdrm/
index becf711..fef3580 100644 (file)
@@ -27,6 +27,7 @@ config ANDROID_LOGGER
 
 config ANDROID_RAM_CONSOLE
        bool "Android RAM buffer console"
+       depends on !S390 && !UML
        default n
 
 config ANDROID_RAM_CONSOLE_ENABLE_VERBOSE
@@ -99,10 +100,6 @@ config ANDROID_LOW_MEMORY_KILLER
        ---help---
          Register processes to be killed when memory is low
 
-config ANDROID_PMEM
-       bool "Android pmem allocator"
-       depends on ARM
-
 source "drivers/staging/android/switch/Kconfig"
 
 endif # if ANDROID
index eaed1ff..5fcc24f 100644 (file)
@@ -5,5 +5,4 @@ obj-$(CONFIG_ANDROID_RAM_CONSOLE)       += ram_console.o
 obj-$(CONFIG_ANDROID_TIMED_OUTPUT)     += timed_output.o
 obj-$(CONFIG_ANDROID_TIMED_GPIO)       += timed_gpio.o
 obj-$(CONFIG_ANDROID_LOW_MEMORY_KILLER)        += lowmemorykiller.o
-obj-$(CONFIG_ANDROID_PMEM)             += pmem.o
 obj-$(CONFIG_ANDROID_SWITCH)           += switch/
diff --git a/drivers/staging/android/android_pmem.h b/drivers/staging/android/android_pmem.h
deleted file mode 100644 (file)
index f633621..0000000
+++ /dev/null
@@ -1,93 +0,0 @@
-/* include/linux/android_pmem.h
- *
- * Copyright (C) 2007 Google, Inc.
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of 
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- */
-
-#ifndef _ANDROID_PMEM_H_
-#define _ANDROID_PMEM_H_
-
-#define PMEM_IOCTL_MAGIC 'p'
-#define PMEM_GET_PHYS          _IOW(PMEM_IOCTL_MAGIC, 1, unsigned int)
-#define PMEM_MAP               _IOW(PMEM_IOCTL_MAGIC, 2, unsigned int)
-#define PMEM_GET_SIZE          _IOW(PMEM_IOCTL_MAGIC, 3, unsigned int)
-#define PMEM_UNMAP             _IOW(PMEM_IOCTL_MAGIC, 4, unsigned int)
-/* This ioctl will allocate pmem space, backing the file, it will fail
- * if the file already has an allocation, pass it the len as the argument
- * to the ioctl */
-#define PMEM_ALLOCATE          _IOW(PMEM_IOCTL_MAGIC, 5, unsigned int)
-/* This will connect a one pmem file to another, pass the file that is already
- * backed in memory as the argument to the ioctl
- */
-#define PMEM_CONNECT           _IOW(PMEM_IOCTL_MAGIC, 6, unsigned int)
-/* Returns the total size of the pmem region it is sent to as a pmem_region
- * struct (with offset set to 0). 
- */
-#define PMEM_GET_TOTAL_SIZE    _IOW(PMEM_IOCTL_MAGIC, 7, unsigned int)
-#define PMEM_CACHE_FLUSH       _IOW(PMEM_IOCTL_MAGIC, 8, unsigned int)
-
-struct android_pmem_platform_data
-{
-       const char* name;
-       /* starting physical address of memory region */
-       unsigned long start;
-       /* size of memory region */
-       unsigned long size;
-       /* set to indicate the region should not be managed with an allocator */
-       unsigned no_allocator;
-       /* set to indicate maps of this region should be cached, if a mix of
-        * cached and uncached is desired, set this and open the device with
-        * O_SYNC to get an uncached region */
-       unsigned cached;
-       /* The MSM7k has bits to enable a write buffer in the bus controller*/
-       unsigned buffered;
-};
-
-struct pmem_region {
-       unsigned long offset;
-       unsigned long len;
-};
-
-#ifdef CONFIG_ANDROID_PMEM
-int is_pmem_file(struct file *file);
-int get_pmem_file(int fd, unsigned long *start, unsigned long *vstart,
-                 unsigned long *end, struct file **filp);
-int get_pmem_user_addr(struct file *file, unsigned long *start,
-                      unsigned long *end);
-void put_pmem_file(struct file* file);
-void flush_pmem_file(struct file *file, unsigned long start, unsigned long len);
-int pmem_setup(struct android_pmem_platform_data *pdata,
-              long (*ioctl)(struct file *, unsigned int, unsigned long),
-              int (*release)(struct inode *, struct file *));
-int pmem_remap(struct pmem_region *region, struct file *file,
-              unsigned operation);
-
-#else
-static inline int is_pmem_file(struct file *file) { return 0; }
-static inline int get_pmem_file(int fd, unsigned long *start,
-                               unsigned long *vstart, unsigned long *end,
-                               struct file **filp) { return -ENOSYS; }
-static inline int get_pmem_user_addr(struct file *file, unsigned long *start,
-                                    unsigned long *end) { return -ENOSYS; }
-static inline void put_pmem_file(struct file* file) { return; }
-static inline void flush_pmem_file(struct file *file, unsigned long start,
-                                  unsigned long len) { return; }
-static inline int pmem_setup(struct android_pmem_platform_data *pdata,
-             long (*ioctl)(struct file *, unsigned int, unsigned long),
-             int (*release)(struct inode *, struct file *)) { return -ENOSYS; }
-
-static inline int pmem_remap(struct pmem_region *region, struct file *file,
-                            unsigned operation) { return -ENOSYS; }
-#endif
-
-#endif //_ANDROID_PPP_H_
-
index 7491801..f0b7e66 100644 (file)
@@ -38,6 +38,7 @@
 
 static DEFINE_MUTEX(binder_lock);
 static DEFINE_MUTEX(binder_deferred_lock);
+static DEFINE_MUTEX(binder_mmap_lock);
 
 static HLIST_HEAD(binder_procs);
 static HLIST_HEAD(binder_deferred_list);
@@ -632,6 +633,11 @@ static int binder_update_page_range(struct binder_proc *proc, int allocate,
        if (mm) {
                down_write(&mm->mmap_sem);
                vma = proc->vma;
+               if (vma && mm != vma->vm_mm) {
+                       pr_err("binder: %d: vma mm and task mm mismatch\n",
+                               proc->pid);
+                       vma = NULL;
+               }
        }
 
        if (allocate == 0)
@@ -2759,7 +2765,6 @@ static void binder_vma_open(struct vm_area_struct *vma)
                     proc->pid, vma->vm_start, vma->vm_end,
                     (vma->vm_end - vma->vm_start) / SZ_1K, vma->vm_flags,
                     (unsigned long)pgprot_val(vma->vm_page_prot));
-       dump_stack();
 }
 
 static void binder_vma_close(struct vm_area_struct *vma)
@@ -2803,6 +2808,7 @@ static int binder_mmap(struct file *filp, struct vm_area_struct *vma)
        }
        vma->vm_flags = (vma->vm_flags | VM_DONTCOPY) & ~VM_MAYWRITE;
 
+       mutex_lock(&binder_mmap_lock);
        if (proc->buffer) {
                ret = -EBUSY;
                failure_string = "already mapped";
@@ -2817,6 +2823,7 @@ static int binder_mmap(struct file *filp, struct vm_area_struct *vma)
        }
        proc->buffer = area->addr;
        proc->user_buffer_offset = vma->vm_start - (uintptr_t)proc->buffer;
+       mutex_unlock(&binder_mmap_lock);
 
 #ifdef CONFIG_CPU_CACHE_VIPT
        if (cache_is_vipt_aliasing()) {
@@ -2849,7 +2856,7 @@ static int binder_mmap(struct file *filp, struct vm_area_struct *vma)
        binder_insert_free_buffer(proc, buffer);
        proc->free_async_space = proc->buffer_size / 2;
        barrier();
-       proc->files = get_files_struct(current);
+       proc->files = get_files_struct(proc->tsk);
        proc->vma = vma;
 
        /*printk(KERN_INFO "binder_mmap: %d %lx-%lx maps %p\n",
@@ -2860,10 +2867,12 @@ err_alloc_small_buf_failed:
        kfree(proc->pages);
        proc->pages = NULL;
 err_alloc_pages_failed:
+       mutex_lock(&binder_mmap_lock);
        vfree(proc->buffer);
        proc->buffer = NULL;
 err_get_vm_area_failed:
 err_already_mapped:
+       mutex_unlock(&binder_mmap_lock);
 err_bad_arg:
        printk(KERN_ERR "binder_mmap: %d %lx-%lx %s failed %d\n",
               proc->pid, vma->vm_start, vma->vm_end, failure_string, ret);
index 2d8d2b7..efc7dc1 100644 (file)
@@ -54,6 +54,7 @@ static size_t lowmem_minfree[6] = {
 static int lowmem_minfree_size = 4;
 
 static struct task_struct *lowmem_deathpending;
+static unsigned long lowmem_deathpending_timeout;
 
 #define lowmem_print(level, x...)                      \
        do {                                            \
@@ -103,7 +104,8 @@ static int lowmem_shrink(struct shrinker *s, struct shrink_control *sc)
         * Note: Currently you need CONFIG_PROFILING
         * for this to work correctly.
         */
-       if (lowmem_deathpending)
+       if (lowmem_deathpending &&
+           time_before_eq(jiffies, lowmem_deathpending_timeout))
                return 0;
 
        if (lowmem_adj_size < array_size)
@@ -178,6 +180,7 @@ static int lowmem_shrink(struct shrinker *s, struct shrink_control *sc)
                 */
 #ifdef CONFIG_PROFILING
                lowmem_deathpending = selected;
+               lowmem_deathpending_timeout = jiffies + HZ;
                task_handoff_register(&task_nb);
 #endif
                force_sig(SIGKILL, selected);
diff --git a/drivers/staging/android/pmem.c b/drivers/staging/android/pmem.c
deleted file mode 100644 (file)
index 7d97032..0000000
+++ /dev/null
@@ -1,1345 +0,0 @@
-/* pmem.c
- *
- * Copyright (C) 2007 Google, Inc.
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- */
-
-#include <linux/miscdevice.h>
-#include <linux/platform_device.h>
-#include <linux/fs.h>
-#include <linux/file.h>
-#include <linux/mm.h>
-#include <linux/list.h>
-#include <linux/mutex.h>
-#include <linux/debugfs.h>
-#include <linux/mempolicy.h>
-#include <linux/sched.h>
-#include <asm/io.h>
-#include <asm/uaccess.h>
-#include <asm/cacheflush.h>
-#include "android_pmem.h"
-
-#define PMEM_MAX_DEVICES 10
-#define PMEM_MAX_ORDER 128
-#define PMEM_MIN_ALLOC PAGE_SIZE
-
-#define PMEM_DEBUG 1
-
-/* indicates that a refernce to this file has been taken via get_pmem_file,
- * the file should not be released until put_pmem_file is called */
-#define PMEM_FLAGS_BUSY 0x1
-/* indicates that this is a suballocation of a larger master range */
-#define PMEM_FLAGS_CONNECTED 0x1 << 1
-/* indicates this is a master and not a sub allocation and that it is mmaped */
-#define PMEM_FLAGS_MASTERMAP 0x1 << 2
-/* submap and unsubmap flags indicate:
- * 00: subregion has never been mmaped
- * 10: subregion has been mmaped, reference to the mm was taken
- * 11: subretion has ben released, refernece to the mm still held
- * 01: subretion has been released, reference to the mm has been released
- */
-#define PMEM_FLAGS_SUBMAP 0x1 << 3
-#define PMEM_FLAGS_UNSUBMAP 0x1 << 4
-
-
-struct pmem_data {
-       /* in alloc mode: an index into the bitmap
-        * in no_alloc mode: the size of the allocation */
-       int index;
-       /* see flags above for descriptions */
-       unsigned int flags;
-       /* protects this data field, if the mm_mmap sem will be held at the
-        * same time as this sem, the mm sem must be taken first (as this is
-        * the order for vma_open and vma_close ops */
-       struct rw_semaphore sem;
-       /* info about the mmaping process */
-       struct vm_area_struct *vma;
-       /* task struct of the mapping process */
-       struct task_struct *task;
-       /* process id of teh mapping process */
-       pid_t pid;
-       /* file descriptor of the master */
-       int master_fd;
-       /* file struct of the master */
-       struct file *master_file;
-       /* a list of currently available regions if this is a suballocation */
-       struct list_head region_list;
-       /* a linked list of data so we can access them for debugging */
-       struct list_head list;
-#if PMEM_DEBUG
-       int ref;
-#endif
-};
-
-struct pmem_bits {
-       unsigned allocated:1;           /* 1 if allocated, 0 if free */
-       unsigned order:7;               /* size of the region in pmem space */
-};
-
-struct pmem_region_node {
-       struct pmem_region region;
-       struct list_head list;
-};
-
-#define PMEM_DEBUG_MSGS 0
-#if PMEM_DEBUG_MSGS
-#define DLOG(fmt,args...) \
-       do { printk(KERN_INFO "[%s:%s:%d] "fmt, __FILE__, __func__, __LINE__, \
-                   ##args); } \
-       while (0)
-#else
-#define DLOG(x...) do {} while (0)
-#endif
-
-struct pmem_info {
-       struct miscdevice dev;
-       /* physical start address of the remaped pmem space */
-       unsigned long base;
-       /* vitual start address of the remaped pmem space */
-       unsigned char __iomem *vbase;
-       /* total size of the pmem space */
-       unsigned long size;
-       /* number of entries in the pmem space */
-       unsigned long num_entries;
-       /* pfn of the garbage page in memory */
-       unsigned long garbage_pfn;
-       /* index of the garbage page in the pmem space */
-       int garbage_index;
-       /* the bitmap for the region indicating which entries are allocated
-        * and which are free */
-       struct pmem_bits *bitmap;
-       /* indicates the region should not be managed with an allocator */
-       unsigned no_allocator;
-       /* indicates maps of this region should be cached, if a mix of
-        * cached and uncached is desired, set this and open the device with
-        * O_SYNC to get an uncached region */
-       unsigned cached;
-       unsigned buffered;
-       /* in no_allocator mode the first mapper gets the whole space and sets
-        * this flag */
-       unsigned allocated;
-       /* for debugging, creates a list of pmem file structs, the
-        * data_list_lock should be taken before pmem_data->sem if both are
-        * needed */
-       struct mutex data_list_lock;
-       struct list_head data_list;
-       /* pmem_sem protects the bitmap array
-        * a write lock should be held when modifying entries in bitmap
-        * a read lock should be held when reading data from bits or
-        * dereferencing a pointer into bitmap
-        *
-        * pmem_data->sem protects the pmem data of a particular file
-        * Many of the function that require the pmem_data->sem have a non-
-        * locking version for when the caller is already holding that sem.
-        *
-        * IF YOU TAKE BOTH LOCKS TAKE THEM IN THIS ORDER:
-        * down(pmem_data->sem) => down(bitmap_sem)
-        */
-       struct rw_semaphore bitmap_sem;
-
-       long (*ioctl)(struct file *, unsigned int, unsigned long);
-       int (*release)(struct inode *, struct file *);
-};
-
-static struct pmem_info pmem[PMEM_MAX_DEVICES];
-static int id_count;
-
-#define PMEM_IS_FREE(id, index) !(pmem[id].bitmap[index].allocated)
-#define PMEM_ORDER(id, index) pmem[id].bitmap[index].order
-#define PMEM_BUDDY_INDEX(id, index) (index ^ (1 << PMEM_ORDER(id, index)))
-#define PMEM_NEXT_INDEX(id, index) (index + (1 << PMEM_ORDER(id, index)))
-#define PMEM_OFFSET(index) (index * PMEM_MIN_ALLOC)
-#define PMEM_START_ADDR(id, index) (PMEM_OFFSET(index) + pmem[id].base)
-#define PMEM_LEN(id, index) ((1 << PMEM_ORDER(id, index)) * PMEM_MIN_ALLOC)
-#define PMEM_END_ADDR(id, index) (PMEM_START_ADDR(id, index) + \
-       PMEM_LEN(id, index))
-#define PMEM_START_VADDR(id, index) (PMEM_OFFSET(id, index) + pmem[id].vbase)
-#define PMEM_END_VADDR(id, index) (PMEM_START_VADDR(id, index) + \
-       PMEM_LEN(id, index))
-#define PMEM_REVOKED(data) (data->flags & PMEM_FLAGS_REVOKED)
-#define PMEM_IS_PAGE_ALIGNED(addr) (!((addr) & (~PAGE_MASK)))
-#define PMEM_IS_SUBMAP(data) ((data->flags & PMEM_FLAGS_SUBMAP) && \
-       (!(data->flags & PMEM_FLAGS_UNSUBMAP)))
-
-static int pmem_release(struct inode *, struct file *);
-static int pmem_mmap(struct file *, struct vm_area_struct *);
-static int pmem_open(struct inode *, struct file *);
-static long pmem_ioctl(struct file *, unsigned int, unsigned long);
-
-struct file_operations pmem_fops = {
-       .release = pmem_release,
-       .mmap = pmem_mmap,
-       .open = pmem_open,
-       .unlocked_ioctl = pmem_ioctl,
-};
-
-static int get_id(struct file *file)
-{
-       return MINOR(file->f_dentry->d_inode->i_rdev);
-}
-
-int is_pmem_file(struct file *file)
-{
-       int id;
-
-       if (unlikely(!file || !file->f_dentry || !file->f_dentry->d_inode))
-               return 0;
-       id = get_id(file);
-       if (unlikely(id >= PMEM_MAX_DEVICES))
-               return 0;
-       if (unlikely(file->f_dentry->d_inode->i_rdev !=
-            MKDEV(MISC_MAJOR, pmem[id].dev.minor)))
-               return 0;
-       return 1;
-}
-
-static int has_allocation(struct file *file)
-{
-       struct pmem_data *data;
-       /* check is_pmem_file first if not accessed via pmem_file_ops */
-
-       if (unlikely(!file->private_data))
-               return 0;
-       data = (struct pmem_data *)file->private_data;
-       if (unlikely(data->index < 0))
-               return 0;
-       return 1;
-}
-
-static int is_master_owner(struct file *file)
-{
-       struct file *master_file;
-       struct pmem_data *data;
-       int put_needed, ret = 0;
-
-       if (!is_pmem_file(file) || !has_allocation(file))
-               return 0;
-       data = (struct pmem_data *)file->private_data;
-       if (PMEM_FLAGS_MASTERMAP & data->flags)
-               return 1;
-       master_file = fget_light(data->master_fd, &put_needed);
-       if (master_file && data->master_file == master_file)
-               ret = 1;
-       fput_light(master_file, put_needed);
-       return ret;
-}
-
-static int pmem_free(int id, int index)
-{
-       /* caller should hold the write lock on pmem_sem! */
-       int buddy, curr = index;
-       DLOG("index %d\n", index);
-
-       if (pmem[id].no_allocator) {
-               pmem[id].allocated = 0;
-               return 0;
-       }
-       /* clean up the bitmap, merging any buddies */
-       pmem[id].bitmap[curr].allocated = 0;
-       /* find a slots buddy Buddy# = Slot# ^ (1 << order)
-        * if the buddy is also free merge them
-        * repeat until the buddy is not free or end of the bitmap is reached
-        */
-       do {
-               buddy = PMEM_BUDDY_INDEX(id, curr);
-               if (PMEM_IS_FREE(id, buddy) &&
-                               PMEM_ORDER(id, buddy) == PMEM_ORDER(id, curr)) {
-                       PMEM_ORDER(id, buddy)++;
-                       PMEM_ORDER(id, curr)++;
-                       curr = min(buddy, curr);
-               } else {
-                       break;
-               }
-       } while (curr < pmem[id].num_entries);
-
-       return 0;
-}
-
-static void pmem_revoke(struct file *file, struct pmem_data *data);
-
-static int pmem_release(struct inode *inode, struct file *file)
-{
-       struct pmem_data *data = (struct pmem_data *)file->private_data;
-       struct pmem_region_node *region_node;
-       struct list_head *elt, *elt2;
-       int id = get_id(file), ret = 0;
-
-
-       mutex_lock(&pmem[id].data_list_lock);
-       /* if this file is a master, revoke all the memory in the connected
-        *  files */
-       if (PMEM_FLAGS_MASTERMAP & data->flags) {
-               struct pmem_data *sub_data;
-               list_for_each(elt, &pmem[id].data_list) {
-                       sub_data = list_entry(elt, struct pmem_data, list);
-                       down_read(&sub_data->sem);
-                       if (PMEM_IS_SUBMAP(sub_data) &&
-                           file == sub_data->master_file) {
-                               up_read(&sub_data->sem);
-                               pmem_revoke(file, sub_data);
-                       }  else
-                               up_read(&sub_data->sem);
-               }
-       }
-       list_del(&data->list);
-       mutex_unlock(&pmem[id].data_list_lock);
-
-
-       down_write(&data->sem);
-
-       /* if its not a conencted file and it has an allocation, free it */
-       if (!(PMEM_FLAGS_CONNECTED & data->flags) && has_allocation(file)) {
-               down_write(&pmem[id].bitmap_sem);
-               ret = pmem_free(id, data->index);
-               up_write(&pmem[id].bitmap_sem);
-       }
-
-       /* if this file is a submap (mapped, connected file), downref the
-        * task struct */
-       if (PMEM_FLAGS_SUBMAP & data->flags)
-               if (data->task) {
-                       put_task_struct(data->task);
-                       data->task = NULL;
-               }
-
-       file->private_data = NULL;
-
-       list_for_each_safe(elt, elt2, &data->region_list) {
-               region_node = list_entry(elt, struct pmem_region_node, list);
-               list_del(elt);
-               kfree(region_node);
-       }
-       BUG_ON(!list_empty(&data->region_list));
-
-       up_write(&data->sem);
-       kfree(data);
-       if (pmem[id].release)
-               ret = pmem[id].release(inode, file);
-
-       return ret;
-}
-
-static int pmem_open(struct inode *inode, struct file *file)
-{
-       struct pmem_data *data;
-       int id = get_id(file);
-       int ret = 0;
-
-       DLOG("current %u file %p(%d)\n", current->pid, file, file_count(file));
-       /* setup file->private_data to indicate its unmapped */
-       /*  you can only open a pmem device one time */
-       if (file->private_data != NULL)
-               return -1;
-       data = kmalloc(sizeof(struct pmem_data), GFP_KERNEL);
-       if (!data) {
-               printk("pmem: unable to allocate memory for pmem metadata.");
-               return -1;
-       }
-       data->flags = 0;
-       data->index = -1;
-       data->task = NULL;
-       data->vma = NULL;
-       data->pid = 0;
-       data->master_file = NULL;
-#if PMEM_DEBUG
-       data->ref = 0;
-#endif
-       INIT_LIST_HEAD(&data->region_list);
-       init_rwsem(&data->sem);
-
-       file->private_data = data;
-       INIT_LIST_HEAD(&data->list);
-
-       mutex_lock(&pmem[id].data_list_lock);
-       list_add(&data->list, &pmem[id].data_list);
-       mutex_unlock(&pmem[id].data_list_lock);
-       return ret;
-}
-
-static unsigned long pmem_order(unsigned long len)
-{
-       int i;
-
-       len = (len + PMEM_MIN_ALLOC - 1)/PMEM_MIN_ALLOC;
-       len--;
-       for (i = 0; i < sizeof(len)*8; i++)
-               if (len >> i == 0)
-                       break;
-       return i;
-}
-
-static int pmem_allocate(int id, unsigned long len)
-{
-       /* caller should hold the write lock on pmem_sem! */
-       /* return the corresponding pdata[] entry */
-       int curr = 0;
-       int end = pmem[id].num_entries;
-       int best_fit = -1;
-       unsigned long order = pmem_order(len);
-
-       if (pmem[id].no_allocator) {
-               DLOG("no allocator");
-               if ((len > pmem[id].size) || pmem[id].allocated)
-                       return -1;
-               pmem[id].allocated = 1;
-               return len;
-       }
-
-       if (order > PMEM_MAX_ORDER)
-               return -1;
-       DLOG("order %lx\n", order);
-
-       /* look through the bitmap:
-        *      if you find a free slot of the correct order use it
-        *      otherwise, use the best fit (smallest with size > order) slot
-        */
-       while (curr < end) {
-               if (PMEM_IS_FREE(id, curr)) {
-                       if (PMEM_ORDER(id, curr) == (unsigned char)order) {
-                               /* set the not free bit and clear others */
-                               best_fit = curr;
-                               break;
-                       }
-                       if (PMEM_ORDER(id, curr) > (unsigned char)order &&
-                           (best_fit < 0 ||
-                            PMEM_ORDER(id, curr) < PMEM_ORDER(id, best_fit)))
-                               best_fit = curr;
-               }
-               curr = PMEM_NEXT_INDEX(id, curr);
-       }
-
-       /* if best_fit < 0, there are no suitable slots,
-        * return an error
-        */
-       if (best_fit < 0) {
-               printk("pmem: no space left to allocate!\n");
-               return -1;
-       }
-
-       /* now partition the best fit:
-        *      split the slot into 2 buddies of order - 1
-        *      repeat until the slot is of the correct order
-        */
-       while (PMEM_ORDER(id, best_fit) > (unsigned char)order) {
-               int buddy;
-               PMEM_ORDER(id, best_fit) -= 1;
-               buddy = PMEM_BUDDY_INDEX(id, best_fit);
-               PMEM_ORDER(id, buddy) = PMEM_ORDER(id, best_fit);
-       }
-       pmem[id].bitmap[best_fit].allocated = 1;
-       return best_fit;
-}
-
-static pgprot_t pmem_access_prot(struct file *file, pgprot_t vma_prot)
-{
-       int id = get_id(file);
-#ifdef pgprot_noncached
-       if (pmem[id].cached == 0 || file->f_flags & O_SYNC)
-               return pgprot_noncached(vma_prot);
-#endif
-#ifdef pgprot_ext_buffered
-       else if (pmem[id].buffered)
-               return pgprot_ext_buffered(vma_prot);
-#endif
-       return vma_prot;
-}
-
-static unsigned long pmem_start_addr(int id, struct pmem_data *data)
-{
-       if (pmem[id].no_allocator)
-               return PMEM_START_ADDR(id, 0);
-       else
-               return PMEM_START_ADDR(id, data->index);
-
-}
-
-static void *pmem_start_vaddr(int id, struct pmem_data *data)
-{
-       return pmem_start_addr(id, data) - pmem[id].base + pmem[id].vbase;
-}
-
-static unsigned long pmem_len(int id, struct pmem_data *data)
-{
-       if (pmem[id].no_allocator)
-               return data->index;
-       else
-               return PMEM_LEN(id, data->index);
-}
-
-static int pmem_map_garbage(int id, struct vm_area_struct *vma,
-                           struct pmem_data *data, unsigned long offset,
-                           unsigned long len)
-{
-       int i, garbage_pages = len >> PAGE_SHIFT;
-
-       vma->vm_flags |= VM_IO | VM_RESERVED | VM_PFNMAP | VM_SHARED | VM_WRITE;
-       for (i = 0; i < garbage_pages; i++) {
-               if (vm_insert_pfn(vma, vma->vm_start + offset + (i * PAGE_SIZE),
-                   pmem[id].garbage_pfn))
-                       return -EAGAIN;
-       }
-       return 0;
-}
-
-static int pmem_unmap_pfn_range(int id, struct vm_area_struct *vma,
-                               struct pmem_data *data, unsigned long offset,
-                               unsigned long len)
-{
-       int garbage_pages;
-       DLOG("unmap offset %lx len %lx\n", offset, len);
-
-       BUG_ON(!PMEM_IS_PAGE_ALIGNED(len));
-
-       garbage_pages = len >> PAGE_SHIFT;
-       zap_page_range(vma, vma->vm_start + offset, len, NULL);
-       pmem_map_garbage(id, vma, data, offset, len);
-       return 0;
-}
-
-static int pmem_map_pfn_range(int id, struct vm_area_struct *vma,
-                             struct pmem_data *data, unsigned long offset,
-                             unsigned long len)
-{
-       DLOG("map offset %lx len %lx\n", offset, len);
-       BUG_ON(!PMEM_IS_PAGE_ALIGNED(vma->vm_start));
-       BUG_ON(!PMEM_IS_PAGE_ALIGNED(vma->vm_end));
-       BUG_ON(!PMEM_IS_PAGE_ALIGNED(len));
-       BUG_ON(!PMEM_IS_PAGE_ALIGNED(offset));
-
-       if (io_remap_pfn_range(vma, vma->vm_start + offset,
-               (pmem_start_addr(id, data) + offset) >> PAGE_SHIFT,
-               len, vma->vm_page_prot)) {
-               return -EAGAIN;
-       }
-       return 0;
-}
-
-static int pmem_remap_pfn_range(int id, struct vm_area_struct *vma,
-                             struct pmem_data *data, unsigned long offset,
-                             unsigned long len)
-{
-       /* hold the mm semp for the vma you are modifying when you call this */
-       BUG_ON(!vma);
-       zap_page_range(vma, vma->vm_start + offset, len, NULL);
-       return pmem_map_pfn_range(id, vma, data, offset, len);
-}
-
-static void pmem_vma_open(struct vm_area_struct *vma)
-{
-       struct file *file = vma->vm_file;
-       struct pmem_data *data = file->private_data;
-       int id = get_id(file);
-       /* this should never be called as we don't support copying pmem
-        * ranges via fork */
-       BUG_ON(!has_allocation(file));
-       down_write(&data->sem);
-       /* remap the garbage pages, forkers don't get access to the data */
-       pmem_unmap_pfn_range(id, vma, data, 0, vma->vm_start - vma->vm_end);
-       up_write(&data->sem);
-}
-
-static void pmem_vma_close(struct vm_area_struct *vma)
-{
-       struct file *file = vma->vm_file;
-       struct pmem_data *data = file->private_data;
-
-       DLOG("current %u ppid %u file %p count %d\n", current->pid,
-            current->parent->pid, file, file_count(file));
-       if (unlikely(!is_pmem_file(file) || !has_allocation(file))) {
-               printk(KERN_WARNING "pmem: something is very wrong, you are "
-                      "closing a vm backing an allocation that doesn't "
-                      "exist!\n");
-               return;
-       }
-       down_write(&data->sem);
-       if (data->vma == vma) {
-               data->vma = NULL;
-               if ((data->flags & PMEM_FLAGS_CONNECTED) &&
-                   (data->flags & PMEM_FLAGS_SUBMAP))
-                       data->flags |= PMEM_FLAGS_UNSUBMAP;
-       }
-       /* the kernel is going to free this vma now anyway */
-       up_write(&data->sem);
-}
-
-static struct vm_operations_struct vm_ops = {
-       .open = pmem_vma_open,
-       .close = pmem_vma_close,
-};
-
-static int pmem_mmap(struct file *file, struct vm_area_struct *vma)
-{
-       struct pmem_data *data;
-       int index;
-       unsigned long vma_size =  vma->vm_end - vma->vm_start;
-       int ret = 0, id = get_id(file);
-
-       if (vma->vm_pgoff || !PMEM_IS_PAGE_ALIGNED(vma_size)) {
-#if PMEM_DEBUG
-               printk(KERN_ERR "pmem: mmaps must be at offset zero, aligned"
-                               " and a multiple of pages_size.\n");
-#endif
-               return -EINVAL;
-       }
-
-       data = (struct pmem_data *)file->private_data;
-       down_write(&data->sem);
-       /* check this file isn't already mmaped, for submaps check this file
-        * has never been mmaped */
-       if ((data->flags & PMEM_FLAGS_SUBMAP) ||
-           (data->flags & PMEM_FLAGS_UNSUBMAP)) {
-#if PMEM_DEBUG
-               printk(KERN_ERR "pmem: you can only mmap a pmem file once, "
-                      "this file is already mmaped. %x\n", data->flags);
-#endif
-               ret = -EINVAL;
-               goto error;
-       }
-       /* if file->private_data == unalloced, alloc*/
-       if (data && data->index == -1) {
-               down_write(&pmem[id].bitmap_sem);
-               index = pmem_allocate(id, vma->vm_end - vma->vm_start);
-               up_write(&pmem[id].bitmap_sem);
-               data->index = index;
-       }
-       /* either no space was available or an error occured */
-       if (!has_allocation(file)) {
-               ret = -EINVAL;
-               printk("pmem: could not find allocation for map.\n");
-               goto error;
-       }
-
-       if (pmem_len(id, data) < vma_size) {
-#if PMEM_DEBUG
-               printk(KERN_WARNING "pmem: mmap size [%lu] does not match"
-                      "size of backing region [%lu].\n", vma_size,
-                      pmem_len(id, data));
-#endif
-               ret = -EINVAL;
-               goto error;
-       }
-
-       vma->vm_pgoff = pmem_start_addr(id, data) >> PAGE_SHIFT;
-       vma->vm_page_prot = pmem_access_prot(file, vma->vm_page_prot);
-
-       if (data->flags & PMEM_FLAGS_CONNECTED) {
-               struct pmem_region_node *region_node;
-               struct list_head *elt;
-               if (pmem_map_garbage(id, vma, data, 0, vma_size)) {
-                       printk("pmem: mmap failed in kernel!\n");
-                       ret = -EAGAIN;
-                       goto error;
-               }
-               list_for_each(elt, &data->region_list) {
-                       region_node = list_entry(elt, struct pmem_region_node,
-                                                list);
-                       DLOG("remapping file: %p %lx %lx\n", file,
-                               region_node->region.offset,
-                               region_node->region.len);
-                       if (pmem_remap_pfn_range(id, vma, data,
-                                                region_node->region.offset,
-                                                region_node->region.len)) {
-                               ret = -EAGAIN;
-                               goto error;
-                       }
-               }
-               data->flags |= PMEM_FLAGS_SUBMAP;
-               get_task_struct(current->group_leader);
-               data->task = current->group_leader;
-               data->vma = vma;
-#if PMEM_DEBUG
-               data->pid = current->pid;
-#endif
-               DLOG("submmapped file %p vma %p pid %u\n", file, vma,
-                    current->pid);
-       } else {
-               if (pmem_map_pfn_range(id, vma, data, 0, vma_size)) {
-                       printk(KERN_INFO "pmem: mmap failed in kernel!\n");
-                       ret = -EAGAIN;
-                       goto error;
-               }
-               data->flags |= PMEM_FLAGS_MASTERMAP;
-               data->pid = current->pid;
-       }
-       vma->vm_ops = &vm_ops;
-error:
-       up_write(&data->sem);
-       return ret;
-}
-
-/* the following are the api for accessing pmem regions by other drivers
- * from inside the kernel */
-int get_pmem_user_addr(struct file *file, unsigned long *start,
-                  unsigned long *len)
-{
-       struct pmem_data *data;
-       if (!is_pmem_file(file) || !has_allocation(file)) {
-#if PMEM_DEBUG
-               printk(KERN_INFO "pmem: requested pmem data from invalid"
-                                 "file.\n");
-#endif
-               return -1;
-       }
-       data = (struct pmem_data *)file->private_data;
-       down_read(&data->sem);
-       if (data->vma) {
-               *start = data->vma->vm_start;
-               *len = data->vma->vm_end - data->vma->vm_start;
-       } else {
-               *start = 0;
-               *len = 0;
-       }
-       up_read(&data->sem);
-       return 0;
-}
-
-int get_pmem_addr(struct file *file, unsigned long *start,
-                 unsigned long *vstart, unsigned long *len)
-{
-       struct pmem_data *data;
-       int id;
-
-       if (!is_pmem_file(file) || !has_allocation(file)) {
-               return -1;
-       }
-
-       data = (struct pmem_data *)file->private_data;
-       if (data->index == -1) {
-#if PMEM_DEBUG
-               printk(KERN_INFO "pmem: requested pmem data from file with no "
-                      "allocation.\n");
-               return -1;
-#endif
-       }
-       id = get_id(file);
-
-       down_read(&data->sem);
-       *start = pmem_start_addr(id, data);
-       *len = pmem_len(id, data);
-       *vstart = (unsigned long)pmem_start_vaddr(id, data);
-       up_read(&data->sem);
-#if PMEM_DEBUG
-       down_write(&data->sem);
-       data->ref++;
-       up_write(&data->sem);
-#endif
-       return 0;
-}
-
-int get_pmem_file(int fd, unsigned long *start, unsigned long *vstart,
-                 unsigned long *len, struct file **filp)
-{
-       struct file *file;
-
-       file = fget(fd);
-       if (unlikely(file == NULL)) {
-               printk(KERN_INFO "pmem: requested data from file descriptor "
-                      "that doesn't exist.");
-               return -1;
-       }
-
-       if (get_pmem_addr(file, start, vstart, len))
-               goto end;
-
-       if (filp)
-               *filp = file;
-       return 0;
-end:
-       fput(file);
-       return -1;
-}
-
-void put_pmem_file(struct file *file)
-{
-       struct pmem_data *data;
-       int id;
-
-       if (!is_pmem_file(file))
-               return;
-       id = get_id(file);
-       data = (struct pmem_data *)file->private_data;
-#if PMEM_DEBUG
-       down_write(&data->sem);
-       if (data->ref == 0) {
-               printk("pmem: pmem_put > pmem_get %s (pid %d)\n",
-                      pmem[id].dev.name, data->pid);
-               BUG();
-       }
-       data->ref--;
-       up_write(&data->sem);
-#endif
-       fput(file);
-}
-
-void flush_pmem_file(struct file *file, unsigned long offset, unsigned long len)
-{
-       struct pmem_data *data;
-       int id;
-       void *vaddr;
-       struct pmem_region_node *region_node;
-       struct list_head *elt;
-       void *flush_start, *flush_end;
-
-       if (!is_pmem_file(file) || !has_allocation(file)) {
-               return;
-       }
-
-       id = get_id(file);
-       data = (struct pmem_data *)file->private_data;
-       if (!pmem[id].cached || file->f_flags & O_SYNC)
-               return;
-
-       down_read(&data->sem);
-       vaddr = pmem_start_vaddr(id, data);
-       /* if this isn't a submmapped file, flush the whole thing */
-       if (unlikely(!(data->flags & PMEM_FLAGS_CONNECTED))) {
-               dmac_flush_range(vaddr, vaddr + pmem_len(id, data));
-               goto end;
-       }
-       /* otherwise, flush the region of the file we are drawing */
-       list_for_each(elt, &data->region_list) {
-               region_node = list_entry(elt, struct pmem_region_node, list);
-               if ((offset >= region_node->region.offset) &&
-                   ((offset + len) <= (region_node->region.offset +
-                       region_node->region.len))) {
-                       flush_start = vaddr + region_node->region.offset;
-                       flush_end = flush_start + region_node->region.len;
-                       dmac_flush_range(flush_start, flush_end);
-                       break;
-               }
-       }
-end:
-       up_read(&data->sem);
-}
-
-static int pmem_connect(unsigned long connect, struct file *file)
-{
-       struct pmem_data *data = (struct pmem_data *)file->private_data;
-       struct pmem_data *src_data;
-       struct file *src_file;
-       int ret = 0, put_needed;
-
-       down_write(&data->sem);
-       /* retrieve the src file and check it is a pmem file with an alloc */
-       src_file = fget_light(connect, &put_needed);
-       DLOG("connect %p to %p\n", file, src_file);
-       if (!src_file) {
-               printk("pmem: src file not found!\n");
-               ret = -EINVAL;
-               goto err_no_file;
-       }
-       if (unlikely(!is_pmem_file(src_file) || !has_allocation(src_file))) {
-               printk(KERN_INFO "pmem: src file is not a pmem file or has no "
-                      "alloc!\n");
-               ret = -EINVAL;
-               goto err_bad_file;
-       }
-       src_data = (struct pmem_data *)src_file->private_data;
-
-       if (has_allocation(file) && (data->index != src_data->index)) {
-               printk("pmem: file is already mapped but doesn't match this"
-                      " src_file!\n");
-               ret = -EINVAL;
-               goto err_bad_file;
-       }
-       data->index = src_data->index;
-       data->flags |= PMEM_FLAGS_CONNECTED;
-       data->master_fd = connect;
-       data->master_file = src_file;
-
-err_bad_file:
-       fput_light(src_file, put_needed);
-err_no_file:
-       up_write(&data->sem);
-       return ret;
-}
-
-static void pmem_unlock_data_and_mm(struct pmem_data *data,
-                                   struct mm_struct *mm)
-{
-       up_write(&data->sem);
-       if (mm != NULL) {
-               up_write(&mm->mmap_sem);
-               mmput(mm);
-       }
-}
-
-static int pmem_lock_data_and_mm(struct file *file, struct pmem_data *data,
-                                struct mm_struct **locked_mm)
-{
-       int ret = 0;
-       struct mm_struct *mm = NULL;
-       *locked_mm = NULL;
-lock_mm:
-       down_read(&data->sem);
-       if (PMEM_IS_SUBMAP(data)) {
-               mm = get_task_mm(data->task);
-               if (!mm) {
-#if PMEM_DEBUG
-                       printk("pmem: can't remap task is gone!\n");
-#endif
-                       up_read(&data->sem);
-                       return -1;
-               }
-       }
-       up_read(&data->sem);
-
-       if (mm)
-               down_write(&mm->mmap_sem);
-
-       down_write(&data->sem);
-       /* check that the file didn't get mmaped before we could take the
-        * data sem, this should be safe b/c you can only submap each file
-        * once */
-       if (PMEM_IS_SUBMAP(data) && !mm) {
-               pmem_unlock_data_and_mm(data, mm);
-               up_write(&data->sem);
-               goto lock_mm;
-       }
-       /* now check that vma.mm is still there, it could have been
-        * deleted by vma_close before we could get the data->sem */
-       if ((data->flags & PMEM_FLAGS_UNSUBMAP) && (mm != NULL)) {
-               /* might as well release this */
-               if (data->flags & PMEM_FLAGS_SUBMAP) {
-                       put_task_struct(data->task);
-                       data->task = NULL;
-                       /* lower the submap flag to show the mm is gone */
-                       data->flags &= ~(PMEM_FLAGS_SUBMAP);
-               }
-               pmem_unlock_data_and_mm(data, mm);
-               return -1;
-       }
-       *locked_mm = mm;
-       return ret;
-}
-
-int pmem_remap(struct pmem_region *region, struct file *file,
-                     unsigned operation)
-{
-       int ret;
-       struct pmem_region_node *region_node;
-       struct mm_struct *mm = NULL;
-       struct list_head *elt, *elt2;
-       int id = get_id(file);
-       struct pmem_data *data = (struct pmem_data *)file->private_data;
-
-       /* pmem region must be aligned on a page boundry */
-       if (unlikely(!PMEM_IS_PAGE_ALIGNED(region->offset) ||
-                !PMEM_IS_PAGE_ALIGNED(region->len))) {
-#if PMEM_DEBUG
-               printk("pmem: request for unaligned pmem suballocation "
-                      "%lx %lx\n", region->offset, region->len);
-#endif
-               return -EINVAL;
-       }
-
-       /* if userspace requests a region of len 0, there's nothing to do */
-       if (region->len == 0)
-               return 0;
-
-       /* lock the mm and data */
-       ret = pmem_lock_data_and_mm(file, data, &mm);
-       if (ret)
-               return 0;
-
-       /* only the owner of the master file can remap the client fds
-        * that back in it */
-       if (!is_master_owner(file)) {
-#if PMEM_DEBUG
-               printk("pmem: remap requested from non-master process\n");
-#endif
-               ret = -EINVAL;
-               goto err;
-       }
-
-       /* check that the requested range is within the src allocation */
-       if (unlikely((region->offset > pmem_len(id, data)) ||
-                    (region->len > pmem_len(id, data)) ||
-                    (region->offset + region->len > pmem_len(id, data)))) {
-#if PMEM_DEBUG
-               printk(KERN_INFO "pmem: suballoc doesn't fit in src_file!\n");
-#endif
-               ret = -EINVAL;
-               goto err;
-       }
-
-       if (operation == PMEM_MAP) {
-               region_node = kmalloc(sizeof(struct pmem_region_node),
-                             GFP_KERNEL);
-               if (!region_node) {
-                       ret = -ENOMEM;
-#if PMEM_DEBUG
-                       printk(KERN_INFO "No space to allocate metadata!");
-#endif
-                       goto err;
-               }
-               region_node->region = *region;
-               list_add(&region_node->list, &data->region_list);
-       } else if (operation == PMEM_UNMAP) {
-               int found = 0;
-               list_for_each_safe(elt, elt2, &data->region_list) {
-                       region_node = list_entry(elt, struct pmem_region_node,
-                                     list);
-                       if (region->len == 0 ||
-                           (region_node->region.offset == region->offset &&
-                           region_node->region.len == region->len)) {
-                               list_del(elt);
-                               kfree(region_node);
-                               found = 1;
-                       }
-               }
-               if (!found) {
-#if PMEM_DEBUG
-                       printk("pmem: Unmap region does not map any mapped "
-                               "region!");
-#endif
-                       ret = -EINVAL;
-                       goto err;
-               }
-       }
-
-       if (data->vma && PMEM_IS_SUBMAP(data)) {
-               if (operation == PMEM_MAP)
-                       ret = pmem_remap_pfn_range(id, data->vma, data,
-                                                  region->offset, region->len);
-               else if (operation == PMEM_UNMAP)
-                       ret = pmem_unmap_pfn_range(id, data->vma, data,
-                                                  region->offset, region->len);
-       }
-
-err:
-       pmem_unlock_data_and_mm(data, mm);
-       return ret;
-}
-
-static void pmem_revoke(struct file *file, struct pmem_data *data)
-{
-       struct pmem_region_node *region_node;
-       struct list_head *elt, *elt2;
-       struct mm_struct *mm = NULL;
-       int id = get_id(file);
-       int ret = 0;
-
-       data->master_file = NULL;
-       ret = pmem_lock_data_and_mm(file, data, &mm);
-       /* if lock_data_and_mm fails either the task that mapped the fd, or
-        * the vma that mapped it have already gone away, nothing more
-        * needs to be done */
-       if (ret)
-               return;
-       /* unmap everything */
-       /* delete the regions and region list nothing is mapped any more */
-       if (data->vma)
-               list_for_each_safe(elt, elt2, &data->region_list) {
-                       region_node = list_entry(elt, struct pmem_region_node,
-                                                list);
-                       pmem_unmap_pfn_range(id, data->vma, data,
-                                            region_node->region.offset,
-                                            region_node->region.len);
-                       list_del(elt);
-                       kfree(region_node);
-       }
-       /* delete the master file */
-       pmem_unlock_data_and_mm(data, mm);
-}
-
-static void pmem_get_size(struct pmem_region *region, struct file *file)
-{
-       struct pmem_data *data = (struct pmem_data *)file->private_data;
-       int id = get_id(file);
-
-       if (!has_allocation(file)) {
-               region->offset = 0;
-               region->len = 0;
-               return;
-       } else {
-               region->offset = pmem_start_addr(id, data);
-               region->len = pmem_len(id, data);
-       }
-       DLOG("offset %lx len %lx\n", region->offset, region->len);
-}
-
-
-static long pmem_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
-{
-       struct pmem_data *data;
-       int id = get_id(file);
-
-       switch (cmd) {
-       case PMEM_GET_PHYS:
-               {
-                       struct pmem_region region;
-                       DLOG("get_phys\n");
-                       if (!has_allocation(file)) {
-                               region.offset = 0;
-                               region.len = 0;
-                       } else {
-                               data = (struct pmem_data *)file->private_data;
-                               region.offset = pmem_start_addr(id, data);
-                               region.len = pmem_len(id, data);
-                       }
-                       printk(KERN_INFO "pmem: request for physical address of pmem region "
-                                       "from process %d.\n", current->pid);
-                       if (copy_to_user((void __user *)arg, &region,
-                                               sizeof(struct pmem_region)))
-                               return -EFAULT;
-                       break;
-               }
-       case PMEM_MAP:
-               {
-                       struct pmem_region region;
-                       if (copy_from_user(&region, (void __user *)arg,
-                                               sizeof(struct pmem_region)))
-                               return -EFAULT;
-                       data = (struct pmem_data *)file->private_data;
-                       return pmem_remap(&region, file, PMEM_MAP);
-               }
-               break;
-       case PMEM_UNMAP:
-               {
-                       struct pmem_region region;
-                       if (copy_from_user(&region, (void __user *)arg,
-                                               sizeof(struct pmem_region)))
-                               return -EFAULT;
-                       data = (struct pmem_data *)file->private_data;
-                       return pmem_remap(&region, file, PMEM_UNMAP);
-                       break;
-               }
-       case PMEM_GET_SIZE:
-               {
-                       struct pmem_region region;
-                       DLOG("get_size\n");
-                       pmem_get_size(&region, file);
-                       if (copy_to_user((void __user *)arg, &region,
-                                               sizeof(struct pmem_region)))
-                               return -EFAULT;
-                       break;
-               }
-       case PMEM_GET_TOTAL_SIZE:
-               {
-                       struct pmem_region region;
-                       DLOG("get total size\n");
-                       region.offset = 0;
-                       get_id(file);
-                       region.len = pmem[id].size;
-                       if (copy_to_user((void __user *)arg, &region,
-                                               sizeof(struct pmem_region)))
-                               return -EFAULT;
-                       break;
-               }
-       case PMEM_ALLOCATE:
-               {
-                       if (has_allocation(file))
-                               return -EINVAL;
-                       data = (struct pmem_data *)file->private_data;
-                       data->index = pmem_allocate(id, arg);
-                       break;
-               }
-       case PMEM_CONNECT:
-               DLOG("connect\n");
-               return pmem_connect(arg, file);
-               break;
-       case PMEM_CACHE_FLUSH:
-               {
-                       struct pmem_region region;
-                       DLOG("flush\n");
-                       if (copy_from_user(&region, (void __user *)arg,
-                                          sizeof(struct pmem_region)))
-                               return -EFAULT;
-                       flush_pmem_file(file, region.offset, region.len);
-                       break;
-               }
-       default:
-               if (pmem[id].ioctl)
-                       return pmem[id].ioctl(file, cmd, arg);
-               return -EINVAL;
-       }
-       return 0;
-}
-
-#if PMEM_DEBUG
-static ssize_t debug_open(struct inode *inode, struct file *file)
-{
-       file->private_data = inode->i_private;
-       return 0;
-}
-
-static ssize_t debug_read(struct file *file, char __user *buf, size_t count,
-                         loff_t *ppos)
-{
-       struct list_head *elt, *elt2;
-       struct pmem_data *data;
-       struct pmem_region_node *region_node;
-       int id = (int)file->private_data;
-       const int debug_bufmax = 4096;
-       static char buffer[4096];
-       int n = 0;
-
-       DLOG("debug open\n");
-       n = scnprintf(buffer, debug_bufmax,
-                     "pid #: mapped regions (offset, len) (offset,len)...\n");
-
-       mutex_lock(&pmem[id].data_list_lock);
-       list_for_each(elt, &pmem[id].data_list) {
-               data = list_entry(elt, struct pmem_data, list);
-               down_read(&data->sem);
-               n += scnprintf(buffer + n, debug_bufmax - n, "pid %u:",
-                               data->pid);
-               list_for_each(elt2, &data->region_list) {
-                       region_node = list_entry(elt2, struct pmem_region_node,
-                                     list);
-                       n += scnprintf(buffer + n, debug_bufmax - n,
-                                       "(%lx,%lx) ",
-                                       region_node->region.offset,
-                                       region_node->region.len);
-               }
-               n += scnprintf(buffer + n, debug_bufmax - n, "\n");
-               up_read(&data->sem);
-       }
-       mutex_unlock(&pmem[id].data_list_lock);
-
-       n++;
-       buffer[n] = 0;
-       return simple_read_from_buffer(buf, count, ppos, buffer, n);
-}
-
-static struct file_operations debug_fops = {
-       .read = debug_read,
-       .open = debug_open,
-};
-#endif
-
-#if 0
-static struct miscdevice pmem_dev = {
-       .name = "pmem",
-       .fops = &pmem_fops,
-};
-#endif
-
-int pmem_setup(struct android_pmem_platform_data *pdata,
-              long (*ioctl)(struct file *, unsigned int, unsigned long),
-              int (*release)(struct inode *, struct file *))
-{
-       int err = 0;
-       int i, index = 0;
-       int id = id_count;
-       id_count++;
-
-       pmem[id].no_allocator = pdata->no_allocator;
-       pmem[id].cached = pdata->cached;
-       pmem[id].buffered = pdata->buffered;
-       pmem[id].base = pdata->start;
-       pmem[id].size = pdata->size;
-       pmem[id].ioctl = ioctl;
-       pmem[id].release = release;
-       init_rwsem(&pmem[id].bitmap_sem);
-       mutex_init(&pmem[id].data_list_lock);
-       INIT_LIST_HEAD(&pmem[id].data_list);
-       pmem[id].dev.name = pdata->name;
-       pmem[id].dev.minor = id;
-       pmem[id].dev.fops = &pmem_fops;
-       printk(KERN_INFO "%s: %d init\n", pdata->name, pdata->cached);
-
-       err = misc_register(&pmem[id].dev);
-       if (err) {
-               printk(KERN_ALERT "Unable to register pmem driver!\n");
-               goto err_cant_register_device;
-       }
-       pmem[id].num_entries = pmem[id].size / PMEM_MIN_ALLOC;
-
-       pmem[id].bitmap = kmalloc(pmem[id].num_entries *
-                                 sizeof(struct pmem_bits), GFP_KERNEL);
-       if (!pmem[id].bitmap)
-               goto err_no_mem_for_metadata;
-
-       memset(pmem[id].bitmap, 0, sizeof(struct pmem_bits) *
-                                         pmem[id].num_entries);
-
-       for (i = sizeof(pmem[id].num_entries) * 8 - 1; i >= 0; i--) {
-               if ((pmem[id].num_entries) &  1<<i) {
-                       PMEM_ORDER(id, index) = i;
-                       index = PMEM_NEXT_INDEX(id, index);
-               }
-       }
-
-       if (pmem[id].cached)
-               pmem[id].vbase = ioremap_cached(pmem[id].base,
-                                               pmem[id].size);
-#ifdef ioremap_ext_buffered
-       else if (pmem[id].buffered)
-               pmem[id].vbase = ioremap_ext_buffered(pmem[id].base,
-                                                     pmem[id].size);
-#endif
-       else
-               pmem[id].vbase = ioremap(pmem[id].base, pmem[id].size);
-
-       if (pmem[id].vbase == 0)
-               goto error_cant_remap;
-
-       pmem[id].garbage_pfn = page_to_pfn(alloc_page(GFP_KERNEL));
-       if (pmem[id].no_allocator)
-               pmem[id].allocated = 0;
-
-#if PMEM_DEBUG
-       debugfs_create_file(pdata->name, S_IFREG | S_IRUGO, NULL, (void *)id,
-                           &debug_fops);
-#endif
-       return 0;
-error_cant_remap:
-       kfree(pmem[id].bitmap);
-err_no_mem_for_metadata:
-       misc_deregister(&pmem[id].dev);
-err_cant_register_device:
-       return -1;
-}
-
-static int pmem_probe(struct platform_device *pdev)
-{
-       struct android_pmem_platform_data *pdata;
-
-       if (!pdev || !pdev->dev.platform_data) {
-               printk(KERN_ALERT "Unable to probe pmem!\n");
-               return -1;
-       }
-       pdata = pdev->dev.platform_data;
-       return pmem_setup(pdata, NULL, NULL);
-}
-
-
-static int pmem_remove(struct platform_device *pdev)
-{
-       int id = pdev->id;
-       __free_page(pfn_to_page(pmem[id].garbage_pfn));
-       misc_deregister(&pmem[id].dev);
-       return 0;
-}
-
-static struct platform_driver pmem_driver = {
-       .probe = pmem_probe,
-       .remove = pmem_remove,
-       .driver = { .name = "android_pmem" }
-};
-
-
-static int __init pmem_init(void)
-{
-       return platform_driver_register(&pmem_driver);
-}
-
-static void __exit pmem_exit(void)
-{
-       platform_driver_unregister(&pmem_driver);
-}
-
-module_init(pmem_init);
-module_exit(pmem_exit);
-
index e77e4e0..1df9586 100644 (file)
@@ -355,7 +355,14 @@ static void send_data(struct asus_oled_dev *odev)
 
 static int append_values(struct asus_oled_dev *odev, uint8_t val, size_t count)
 {
-       while (count-- > 0 && val) {
+       odev->last_val = val;
+
+       if (val == 0) {
+               odev->buf_offs += count;
+               return 0;
+       }
+
+       while (count-- > 0) {
                size_t x = odev->buf_offs % odev->width;
                size_t y = odev->buf_offs / odev->width;
                size_t i;
@@ -406,7 +413,6 @@ static int append_values(struct asus_oled_dev *odev, uint8_t val, size_t count)
                        ;
                }
 
-               odev->last_val = val;
                odev->buf_offs++;
        }
 
@@ -805,10 +811,9 @@ error:
 
 static void __exit asus_oled_exit(void)
 {
+       usb_deregister(&oled_driver);
        class_remove_file(oled_class, &class_attr_version.attr);
        class_destroy(oled_class);
-
-       usb_deregister(&oled_driver);
 }
 
 module_init(asus_oled_init);
diff --git a/drivers/staging/gma500/Kconfig b/drivers/staging/gma500/Kconfig
deleted file mode 100644 (file)
index c7a2b3b..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-config DRM_PSB
-       tristate "Intel GMA5/600 KMS Framebuffer"
-       depends on DRM && PCI && X86 && BROKEN
-       select FB_CFB_COPYAREA
-        select FB_CFB_FILLRECT
-        select FB_CFB_IMAGEBLIT
-        select DRM_KMS_HELPER
-        select DRM_TTM
-       help
-         Say yes for an experimental 2D KMS framebuffer driver for the
-         Intel GMA500 ('Poulsbo') and other Intel IMG based graphics
-         devices.
-
-config DRM_PSB_MRST
-       bool "Intel GMA600 support (Experimental)"
-       depends on DRM_PSB
-       help
-         Say yes to include support for GMA600 (Intel Moorestown/Oaktrail)
-         platforms with LVDS ports. HDMI and MIPI are not currently
-         supported.
-
-config DRM_PSB_MFLD
-       bool "Intel Medfield support (Experimental)"
-       depends on DRM_PSB
-       help
-         Say yes to include support for Intel Medfield platforms with MIPI
-         interfaces.
-       
-config DRM_PSB_CDV
-       bool "Intel Cedarview support (Experimental)"
-       depends on DRM_PSB
-       help
-         Say yes to include support for Intel Cedarview platforms
diff --git a/drivers/staging/gma500/Makefile b/drivers/staging/gma500/Makefile
deleted file mode 100644 (file)
index c729868..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-#
-#      KMS driver for the GMA500
-#
-ccflags-y += -Iinclude/drm
-
-psb_gfx-y += gem_glue.o \
-         accel_2d.o \
-         backlight.o \
-         framebuffer.o \
-         gem.o \
-         gtt.o \
-         intel_bios.o \
-         intel_i2c.o \
-         intel_opregion.o \
-         mmu.o \
-         power.o \
-         psb_drv.o \
-         psb_intel_display.o \
-         psb_intel_lvds.o \
-         psb_intel_modes.o \
-         psb_intel_sdvo.o \
-         psb_lid.o \
-         psb_irq.o \
-         psb_device.o \
-         mid_bios.o
-
-psb_gfx-$(CONFIG_DRM_PSB_CDV) +=  cdv_device.o \
-         cdv_intel_crt.o \
-         cdv_intel_display.o \
-         cdv_intel_hdmi.o \
-         cdv_intel_lvds.o
-
-psb_gfx-$(CONFIG_DRM_PSB_MRST) += mrst_device.o \
-         mrst_crtc.o \
-         mrst_lvds.o \
-         mrst_hdmi.o \
-         mrst_hdmi_i2c.o
-
-psb_gfx-$(CONFIG_DRM_PSB_MFLD) += mdfld_device.o \
-         mdfld_output.o \
-         mdfld_pyr_cmd.o \
-         mdfld_tmd_vid.o \
-         mdfld_tpo_cmd.o \
-         mdfld_tpo_vid.o \
-         mdfld_dsi_pkg_sender.o \
-         mdfld_dsi_dpi.o \
-         mdfld_dsi_output.o \
-         mdfld_dsi_dbi.o \
-         mdfld_dsi_dbi_dpu.o \
-         mdfld_intel_display.o
-
-obj-$(CONFIG_DRM_PSB) += psb_gfx.o
diff --git a/drivers/staging/gma500/TODO b/drivers/staging/gma500/TODO
deleted file mode 100644 (file)
index fc83615..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
--      Sort out the power management side. Not important for Poulsbo but
-       matters for Moorestown/Medfield
--      Debug Oaktrail/Moorestown support (single pipe, no BIOS on mrst,
-                                       some other differences)
--      Add 2D acceleration via console and DRM
--      Add scrolling acceleration using the GTT to do remapping on the main
-       framebuffer.
--      HDMI testing
--      Oaktrail HDMI and other features
--      Oaktrail MIPI
--      Medfield needs a lot of further love
-
-As per kernel policy and the in the interest of the safety of various
-kittens there is no support or plans to add hooks for the closed user space
-stuff.
diff --git a/drivers/staging/gma500/accel_2d.c b/drivers/staging/gma500/accel_2d.c
deleted file mode 100644 (file)
index b8f78eb..0000000
+++ /dev/null
@@ -1,414 +0,0 @@
-/**************************************************************************
- * Copyright (c) 2007-2011, Intel Corporation.
- * All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
- * develop this driver.
- *
- **************************************************************************/
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/string.h>
-#include <linux/mm.h>
-#include <linux/tty.h>
-#include <linux/slab.h>
-#include <linux/delay.h>
-#include <linux/fb.h>
-#include <linux/init.h>
-#include <linux/console.h>
-
-#include <drm/drmP.h>
-#include <drm/drm.h>
-#include <drm/drm_crtc.h>
-
-#include "psb_drv.h"
-#include "psb_reg.h"
-#include "framebuffer.h"
-
-/**
- *     psb_spank               -       reset the 2D engine
- *     @dev_priv: our PSB DRM device
- *
- *     Soft reset the graphics engine and then reload the necessary registers.
- *     We use this at initialisation time but it will become relevant for
- *     accelerated X later
- */
-void psb_spank(struct drm_psb_private *dev_priv)
-{
-       PSB_WSGX32(_PSB_CS_RESET_BIF_RESET | _PSB_CS_RESET_DPM_RESET |
-               _PSB_CS_RESET_TA_RESET | _PSB_CS_RESET_USE_RESET |
-               _PSB_CS_RESET_ISP_RESET | _PSB_CS_RESET_TSP_RESET |
-               _PSB_CS_RESET_TWOD_RESET, PSB_CR_SOFT_RESET);
-       PSB_RSGX32(PSB_CR_SOFT_RESET);
-
-       msleep(1);
-
-       PSB_WSGX32(0, PSB_CR_SOFT_RESET);
-       wmb();
-       PSB_WSGX32(PSB_RSGX32(PSB_CR_BIF_CTRL) | _PSB_CB_CTRL_CLEAR_FAULT,
-                  PSB_CR_BIF_CTRL);
-       wmb();
-       (void) PSB_RSGX32(PSB_CR_BIF_CTRL);
-
-       msleep(1);
-       PSB_WSGX32(PSB_RSGX32(PSB_CR_BIF_CTRL) & ~_PSB_CB_CTRL_CLEAR_FAULT,
-                  PSB_CR_BIF_CTRL);
-       (void) PSB_RSGX32(PSB_CR_BIF_CTRL);
-       PSB_WSGX32(dev_priv->gtt.gatt_start, PSB_CR_BIF_TWOD_REQ_BASE);
-}
-
-/**
- *     psb2_2d_wait_available  -       wait for FIFO room
- *     @dev_priv: our DRM device
- *     @size: size (in dwords) of the command we want to issue
- *
- *     Wait until there is room to load the FIFO with our data. If the
- *     device is not responding then reset it
- */
-static int psb_2d_wait_available(struct drm_psb_private *dev_priv,
-                         unsigned size)
-{
-       uint32_t avail = PSB_RSGX32(PSB_CR_2D_SOCIF);
-       unsigned long t = jiffies + HZ;
-
-       while (avail < size) {
-               avail = PSB_RSGX32(PSB_CR_2D_SOCIF);
-               if (time_after(jiffies, t)) {
-                       psb_spank(dev_priv);
-                       return -EIO;
-               }
-       }
-       return 0;
-}
-
-/**
- *     psb_2d_submit           -       submit a 2D command
- *     @dev_priv: our DRM device
- *     @cmdbuf: command to issue
- *     @size: length (in dwords)
- *
- *     Issue one or more 2D commands to the accelerator. This needs to be
- *     serialized later when we add the GEM interfaces for acceleration
- */
-static int psbfb_2d_submit(struct drm_psb_private *dev_priv, uint32_t *cmdbuf,
-                                                               unsigned size)
-{
-       int ret = 0;
-       int i;
-       unsigned submit_size;
-       unsigned long flags;
-
-       spin_lock_irqsave(&dev_priv->lock_2d, flags);
-       while (size > 0) {
-               submit_size = (size < 0x60) ? size : 0x60;
-               size -= submit_size;
-               ret = psb_2d_wait_available(dev_priv, submit_size);
-               if (ret)
-                       break;
-
-               submit_size <<= 2;
-
-               for (i = 0; i < submit_size; i += 4)
-                       PSB_WSGX32(*cmdbuf++, PSB_SGX_2D_SLAVE_PORT + i);
-
-               (void)PSB_RSGX32(PSB_SGX_2D_SLAVE_PORT + i - 4);
-       }
-       spin_unlock_irqrestore(&dev_priv->lock_2d, flags);
-       return ret;
-}
-
-
-/**
- *     psb_accel_2d_copy_direction     -       compute blit order
- *     @xdir: X direction of move
- *     @ydir: Y direction of move
- *
- *     Compute the correct order setings to ensure that an overlapping blit
- *     correctly copies all the pixels.
- */
-static u32 psb_accel_2d_copy_direction(int xdir, int ydir)
-{
-       if (xdir < 0)
-               return (ydir < 0) ? PSB_2D_COPYORDER_BR2TL :
-                                               PSB_2D_COPYORDER_TR2BL;
-       else
-               return (ydir < 0) ? PSB_2D_COPYORDER_BL2TR :
-                                               PSB_2D_COPYORDER_TL2BR;
-}
-
-/**
- *     psb_accel_2d_copy               -       accelerated 2D copy
- *     @dev_priv: our DRM device
- *     @src_offset in bytes
- *     @src_stride in bytes
- *     @src_format psb 2D format defines
- *     @dst_offset in bytes
- *     @dst_stride in bytes
- *     @dst_format psb 2D format defines
- *     @src_x offset in pixels
- *     @src_y offset in pixels
- *     @dst_x offset in pixels
- *     @dst_y offset in pixels
- *     @size_x of the copied area
- *     @size_y of the copied area
- *
- *     Format and issue a 2D accelerated copy command.
- */
-static int psb_accel_2d_copy(struct drm_psb_private *dev_priv,
-                            uint32_t src_offset, uint32_t src_stride,
-                            uint32_t src_format, uint32_t dst_offset,
-                            uint32_t dst_stride, uint32_t dst_format,
-                            uint16_t src_x, uint16_t src_y,
-                            uint16_t dst_x, uint16_t dst_y,
-                            uint16_t size_x, uint16_t size_y)
-{
-       uint32_t blit_cmd;
-       uint32_t buffer[10];
-       uint32_t *buf;
-       uint32_t direction;
-
-       buf = buffer;
-
-       direction =
-           psb_accel_2d_copy_direction(src_x - dst_x, src_y - dst_y);
-
-       if (direction == PSB_2D_COPYORDER_BR2TL ||
-           direction == PSB_2D_COPYORDER_TR2BL) {
-               src_x += size_x - 1;
-               dst_x += size_x - 1;
-       }
-       if (direction == PSB_2D_COPYORDER_BR2TL ||
-           direction == PSB_2D_COPYORDER_BL2TR) {
-               src_y += size_y - 1;
-               dst_y += size_y - 1;
-       }
-
-       blit_cmd =
-           PSB_2D_BLIT_BH |
-           PSB_2D_ROT_NONE |
-           PSB_2D_DSTCK_DISABLE |
-           PSB_2D_SRCCK_DISABLE |
-           PSB_2D_USE_PAT | PSB_2D_ROP3_SRCCOPY | direction;
-
-       *buf++ = PSB_2D_FENCE_BH;
-       *buf++ =
-           PSB_2D_DST_SURF_BH | dst_format | (dst_stride <<
-                                              PSB_2D_DST_STRIDE_SHIFT);
-       *buf++ = dst_offset;
-       *buf++ =
-           PSB_2D_SRC_SURF_BH | src_format | (src_stride <<
-                                              PSB_2D_SRC_STRIDE_SHIFT);
-       *buf++ = src_offset;
-       *buf++ =
-           PSB_2D_SRC_OFF_BH | (src_x << PSB_2D_SRCOFF_XSTART_SHIFT) |
-           (src_y << PSB_2D_SRCOFF_YSTART_SHIFT);
-       *buf++ = blit_cmd;
-       *buf++ =
-           (dst_x << PSB_2D_DST_XSTART_SHIFT) | (dst_y <<
-                                                 PSB_2D_DST_YSTART_SHIFT);
-       *buf++ =
-           (size_x << PSB_2D_DST_XSIZE_SHIFT) | (size_y <<
-                                                 PSB_2D_DST_YSIZE_SHIFT);
-       *buf++ = PSB_2D_FLUSH_BH;
-
-       return psbfb_2d_submit(dev_priv, buffer, buf - buffer);
-}
-
-/**
- *     psbfb_copyarea_accel    -       copyarea acceleration for /dev/fb
- *     @info: our framebuffer
- *     @a: copyarea parameters from the framebuffer core
- *
- *     Perform a 2D copy via the accelerator
- */
-static void psbfb_copyarea_accel(struct fb_info *info,
-                                const struct fb_copyarea *a)
-{
-       struct psb_fbdev *fbdev = info->par;
-       struct psb_framebuffer *psbfb = &fbdev->pfb;
-       struct drm_device *dev = psbfb->base.dev;
-       struct drm_framebuffer *fb = fbdev->psb_fb_helper.fb;
-       struct drm_psb_private *dev_priv = dev->dev_private;
-       uint32_t offset;
-       uint32_t stride;
-       uint32_t src_format;
-       uint32_t dst_format;
-
-       if (!fb)
-               return;
-
-       offset = psbfb->gtt->offset;
-       stride = fb->pitches[0];
-
-       switch (fb->depth) {
-       case 8:
-               src_format = PSB_2D_SRC_332RGB;
-               dst_format = PSB_2D_DST_332RGB;
-               break;
-       case 15:
-               src_format = PSB_2D_SRC_555RGB;
-               dst_format = PSB_2D_DST_555RGB;
-               break;
-       case 16:
-               src_format = PSB_2D_SRC_565RGB;
-               dst_format = PSB_2D_DST_565RGB;
-               break;
-       case 24:
-       case 32:
-               /* this is wrong but since we don't do blending its okay */
-               src_format = PSB_2D_SRC_8888ARGB;
-               dst_format = PSB_2D_DST_8888ARGB;
-               break;
-       default:
-               /* software fallback */
-               cfb_copyarea(info, a);
-               return;
-       }
-
-       if (!gma_power_begin(dev, false)) {
-               cfb_copyarea(info, a);
-               return;
-       }
-       psb_accel_2d_copy(dev_priv,
-                         offset, stride, src_format,
-                         offset, stride, dst_format,
-                         a->sx, a->sy, a->dx, a->dy, a->width, a->height);
-       gma_power_end(dev);
-}
-
-/**
- *     psbfb_copyarea  -       2D copy interface
- *     @info: our framebuffer
- *     @region: region to copy
- *
- *     Copy an area of the framebuffer console either by the accelerator
- *     or directly using the cfb helpers according to the request
- */
-void psbfb_copyarea(struct fb_info *info,
-                          const struct fb_copyarea *region)
-{
-       if (unlikely(info->state != FBINFO_STATE_RUNNING))
-               return;
-
-       /* Avoid the 8 pixel erratum */
-       if (region->width == 8 || region->height == 8 ||
-               (info->flags & FBINFO_HWACCEL_DISABLED))
-               return cfb_copyarea(info, region);
-
-       psbfb_copyarea_accel(info, region);
-}
-
-/**
- *     psbfb_sync      -       synchronize 2D
- *     @info: our framebuffer
- *
- *     Wait for the 2D engine to quiesce so that we can do CPU
- *     access to the framebuffer again
- */
-int psbfb_sync(struct fb_info *info)
-{
-       struct psb_fbdev *fbdev = info->par;
-       struct psb_framebuffer *psbfb = &fbdev->pfb;
-       struct drm_device *dev = psbfb->base.dev;
-       struct drm_psb_private *dev_priv = dev->dev_private;
-       unsigned long _end = jiffies + DRM_HZ;
-       int busy = 0;
-       unsigned long flags;
-
-       spin_lock_irqsave(&dev_priv->lock_2d, flags);
-       /*
-        * First idle the 2D engine.
-        */
-
-       if ((PSB_RSGX32(PSB_CR_2D_SOCIF) == _PSB_C2_SOCIF_EMPTY) &&
-           ((PSB_RSGX32(PSB_CR_2D_BLIT_STATUS) & _PSB_C2B_STATUS_BUSY) == 0))
-               goto out;
-
-       do {
-               busy = (PSB_RSGX32(PSB_CR_2D_SOCIF) != _PSB_C2_SOCIF_EMPTY);
-               cpu_relax();
-       } while (busy && !time_after_eq(jiffies, _end));
-
-       if (busy)
-               busy = (PSB_RSGX32(PSB_CR_2D_SOCIF) != _PSB_C2_SOCIF_EMPTY);
-       if (busy)
-               goto out;
-
-       do {
-               busy = ((PSB_RSGX32(PSB_CR_2D_BLIT_STATUS) &
-                                               _PSB_C2B_STATUS_BUSY) != 0);
-               cpu_relax();
-       } while (busy && !time_after_eq(jiffies, _end));
-       if (busy)
-               busy = ((PSB_RSGX32(PSB_CR_2D_BLIT_STATUS) &
-                                       _PSB_C2B_STATUS_BUSY) != 0);
-
-out:
-       spin_unlock_irqrestore(&dev_priv->lock_2d, flags);
-       return (busy) ? -EBUSY : 0;
-}
-
-int psb_accel_ioctl(struct drm_device *dev, void *data, struct drm_file *file)
-{
-       struct drm_psb_private *dev_priv = dev->dev_private;
-       struct drm_psb_2d_op *op = data;
-       u32 *op_ptr = &op->cmd[0];
-       int i;
-       struct drm_gem_object *obj;
-       struct gtt_range *gtt;
-       int err = -EINVAL;
-
-       if (!dev_priv->ops->accel_2d)
-               return -EOPNOTSUPP;
-       if (op->size > PSB_2D_OP_BUFLEN)
-               return -EINVAL;
-
-       /* The GEM object being used. We need to support separate src/dst/etc
-          in the end but for now keep them all the same */
-       obj = drm_gem_object_lookup(dev, file, op->src);
-       if (obj == NULL)
-               return -ENOENT;
-       gtt = container_of(obj, struct gtt_range, gem);
-
-       if (psb_gtt_pin(gtt) < 0)
-               goto bad_2;
-       for (i = 0; i < op->size; i++, op_ptr++) {
-               u32 r = *op_ptr & 0xF0000000;
-               /* Fill in the GTT offsets for the command buffer */
-               if (r == PSB_2D_SRC_SURF_BH ||
-                       r == PSB_2D_DST_SURF_BH ||
-                       r == PSB_2D_MASK_SURF_BH ||
-                       r == PSB_2D_PAT_SURF_BH) {
-                       i++;
-                       op_ptr++;
-                       if (i == op->size)
-                               goto bad;
-                       if (*op_ptr)
-                               goto bad;
-                       *op_ptr = gtt->offset;
-                       continue;
-               }
-       }
-       psbfb_2d_submit(dev_priv, op->cmd, op->size);
-       err = 0;
-bad:
-       psb_gtt_unpin(gtt);
-bad_2:
-       drm_gem_object_unreference(obj);
-       return err;
-}
diff --git a/drivers/staging/gma500/backlight.c b/drivers/staging/gma500/backlight.c
deleted file mode 100644 (file)
index 2079395..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * GMA500 Backlight Interface
- *
- * Copyright (c) 2009-2011, Intel Corporation.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Authors: Eric Knopp
- *
- */
-
-#include "psb_drv.h"
-#include "psb_intel_reg.h"
-#include "psb_intel_drv.h"
-#include "intel_bios.h"
-#include "power.h"
-
-int gma_backlight_init(struct drm_device *dev)
-{
-#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
-       struct drm_psb_private *dev_priv = dev->dev_private;
-       return dev_priv->ops->backlight_init(dev);
-#else
-       return 0;
-#endif
-}
-
-void gma_backlight_exit(struct drm_device *dev)
-{
-#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
-       struct drm_psb_private *dev_priv = dev->dev_private;
-       if (dev_priv->backlight_device) {
-               dev_priv->backlight_device->props.brightness = 0;
-               backlight_update_status(dev_priv->backlight_device);
-               backlight_device_unregister(dev_priv->backlight_device);
-       }
-#endif
-}
diff --git a/drivers/staging/gma500/cdv_device.c b/drivers/staging/gma500/cdv_device.c
deleted file mode 100644 (file)
index 8ec10ca..0000000
+++ /dev/null
@@ -1,350 +0,0 @@
-/**************************************************************************
- * Copyright (c) 2011, Intel Corporation.
- * All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- **************************************************************************/
-
-#include <linux/backlight.h>
-#include <drm/drmP.h>
-#include <drm/drm.h>
-#include "psb_drm.h"
-#include "psb_drv.h"
-#include "psb_reg.h"
-#include "psb_intel_reg.h"
-#include "intel_bios.h"
-#include "cdv_device.h"
-
-#define VGA_SR_INDEX           0x3c4
-#define VGA_SR_DATA            0x3c5
-
-static void cdv_disable_vga(struct drm_device *dev)
-{
-       u8 sr1;
-       u32 vga_reg;
-
-       vga_reg = VGACNTRL;
-
-       outb(1, VGA_SR_INDEX);
-       sr1 = inb(VGA_SR_DATA);
-       outb(sr1 | 1<<5, VGA_SR_DATA);
-       udelay(300);
-
-       REG_WRITE(vga_reg, VGA_DISP_DISABLE);
-       REG_READ(vga_reg);
-}
-
-static int cdv_output_init(struct drm_device *dev)
-{
-       struct drm_psb_private *dev_priv = dev->dev_private;
-       cdv_disable_vga(dev);
-
-       cdv_intel_crt_init(dev, &dev_priv->mode_dev);
-       cdv_intel_lvds_init(dev, &dev_priv->mode_dev);
-
-       /* These bits indicate HDMI not SDVO on CDV, but we don't yet support
-          the HDMI interface */
-       if (REG_READ(SDVOB) & SDVO_DETECTED)
-               cdv_hdmi_init(dev, &dev_priv->mode_dev, SDVOB);
-       if (REG_READ(SDVOC) & SDVO_DETECTED)
-               cdv_hdmi_init(dev, &dev_priv->mode_dev, SDVOC);
-       return 0;
-}
-
-#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
-
-/*
- *     Poulsbo Backlight Interfaces
- */
-
-#define BLC_PWM_PRECISION_FACTOR 100   /* 10000000 */
-#define BLC_PWM_FREQ_CALC_CONSTANT 32
-#define MHz 1000000
-
-#define PSB_BLC_PWM_PRECISION_FACTOR    10
-#define PSB_BLC_MAX_PWM_REG_FREQ        0xFFFE
-#define PSB_BLC_MIN_PWM_REG_FREQ        0x2
-
-#define PSB_BACKLIGHT_PWM_POLARITY_BIT_CLEAR (0xFFFE)
-#define PSB_BACKLIGHT_PWM_CTL_SHIFT    (16)
-
-static int cdv_brightness;
-static struct backlight_device *cdv_backlight_device;
-
-static int cdv_get_brightness(struct backlight_device *bd)
-{
-       /* return locally cached var instead of HW read (due to DPST etc.) */
-       /* FIXME: ideally return actual value in case firmware fiddled with
-          it */
-       return cdv_brightness;
-}
-
-
-static int cdv_backlight_setup(struct drm_device *dev)
-{
-       struct drm_psb_private *dev_priv = dev->dev_private;
-       unsigned long core_clock;
-       /* u32 bl_max_freq; */
-       /* unsigned long value; */
-       u16 bl_max_freq;
-       uint32_t value;
-       uint32_t blc_pwm_precision_factor;
-
-       /* get bl_max_freq and pol from dev_priv*/
-       if (!dev_priv->lvds_bl) {
-               dev_err(dev->dev, "Has no valid LVDS backlight info\n");
-               return -ENOENT;
-       }
-       bl_max_freq = dev_priv->lvds_bl->freq;
-       blc_pwm_precision_factor = PSB_BLC_PWM_PRECISION_FACTOR;
-
-       core_clock = dev_priv->core_freq;
-
-       value = (core_clock * MHz) / BLC_PWM_FREQ_CALC_CONSTANT;
-       value *= blc_pwm_precision_factor;
-       value /= bl_max_freq;
-       value /= blc_pwm_precision_factor;
-
-       if (value > (unsigned long long)PSB_BLC_MAX_PWM_REG_FREQ ||
-                value < (unsigned long long)PSB_BLC_MIN_PWM_REG_FREQ)
-                               return -ERANGE;
-       else {
-               /* FIXME */
-       }
-       return 0;
-}
-
-static int cdv_set_brightness(struct backlight_device *bd)
-{
-       int level = bd->props.brightness;
-
-       /* Percentage 1-100% being valid */
-       if (level < 1)
-               level = 1;
-
-       /*cdv_intel_lvds_set_brightness(dev, level); FIXME */
-       cdv_brightness = level;
-       return 0;
-}
-
-static const struct backlight_ops cdv_ops = {
-       .get_brightness = cdv_get_brightness,
-       .update_status  = cdv_set_brightness,
-};
-
-static int cdv_backlight_init(struct drm_device *dev)
-{
-       struct drm_psb_private *dev_priv = dev->dev_private;
-       int ret;
-       struct backlight_properties props;
-
-       memset(&props, 0, sizeof(struct backlight_properties));
-       props.max_brightness = 100;
-       props.type = BACKLIGHT_PLATFORM;
-
-       cdv_backlight_device = backlight_device_register("psb-bl",
-                                       NULL, (void *)dev, &cdv_ops, &props);
-       if (IS_ERR(cdv_backlight_device))
-               return PTR_ERR(cdv_backlight_device);
-
-       ret = cdv_backlight_setup(dev);
-       if (ret < 0) {
-               backlight_device_unregister(cdv_backlight_device);
-               cdv_backlight_device = NULL;
-               return ret;
-       }
-       cdv_backlight_device->props.brightness = 100;
-       cdv_backlight_device->props.max_brightness = 100;
-       backlight_update_status(cdv_backlight_device);
-       dev_priv->backlight_device = cdv_backlight_device;
-       return 0;
-}
-
-#endif
-
-/*
- *     Provide the Cedarview specific chip logic and low level methods
- *     for power management
- *
- *     FIXME: we need to implement the apm/ospm base management bits
- *     for this and the MID devices.
- */
-
-static inline u32 CDV_MSG_READ32(uint port, uint offset)
-{
-       int mcr = (0x10<<24) | (port << 16) | (offset << 8);
-       uint32_t ret_val = 0;
-       struct pci_dev *pci_root = pci_get_bus_and_slot(0, 0);
-       pci_write_config_dword(pci_root, 0xD0, mcr);
-       pci_read_config_dword(pci_root, 0xD4, &ret_val);
-       pci_dev_put(pci_root);
-       return ret_val;
-}
-
-static inline void CDV_MSG_WRITE32(uint port, uint offset, u32 value)
-{
-       int mcr = (0x11<<24) | (port << 16) | (offset << 8) | 0xF0;
-       struct pci_dev *pci_root = pci_get_bus_and_slot(0, 0);
-       pci_write_config_dword(pci_root, 0xD4, value);
-       pci_write_config_dword(pci_root, 0xD0, mcr);
-       pci_dev_put(pci_root);
-}
-
-#define PSB_APM_CMD                    0x0
-#define PSB_APM_STS                    0x04
-#define PSB_PM_SSC                     0x20
-#define PSB_PM_SSS                     0x30
-#define PSB_PWRGT_GFX_MASK             0x3
-#define CDV_PWRGT_DISPLAY_CNTR         0x000fc00c
-#define CDV_PWRGT_DISPLAY_STS          0x000fc00c
-
-static void cdv_init_pm(struct drm_device *dev)
-{
-       struct drm_psb_private *dev_priv = dev->dev_private;
-       u32 pwr_cnt;
-       int i;
-
-       dev_priv->apm_base = CDV_MSG_READ32(PSB_PUNIT_PORT,
-                                                       PSB_APMBA) & 0xFFFF;
-       dev_priv->ospm_base = CDV_MSG_READ32(PSB_PUNIT_PORT,
-                                                       PSB_OSPMBA) & 0xFFFF;
-
-       /* Force power on for now */
-       pwr_cnt = inl(dev_priv->apm_base + PSB_APM_CMD);
-       pwr_cnt &= ~PSB_PWRGT_GFX_MASK;
-
-       outl(pwr_cnt, dev_priv->apm_base + PSB_APM_CMD);
-       for (i = 0; i < 5; i++) {
-               u32 pwr_sts = inl(dev_priv->apm_base + PSB_APM_STS);
-               if ((pwr_sts & PSB_PWRGT_GFX_MASK) == 0)
-                       break;
-               udelay(10);
-       }
-       pwr_cnt = inl(dev_priv->ospm_base + PSB_PM_SSC);
-       pwr_cnt &= ~CDV_PWRGT_DISPLAY_CNTR;
-       outl(pwr_cnt, dev_priv->ospm_base + PSB_PM_SSC);
-       for (i = 0; i < 5; i++) {
-               u32 pwr_sts = inl(dev_priv->ospm_base + PSB_PM_SSS);
-               if ((pwr_sts & CDV_PWRGT_DISPLAY_STS) == 0)
-                       break;
-               udelay(10);
-       }
-}
-
-/**
- *     cdv_save_display_registers      -       save registers lost on suspend
- *     @dev: our DRM device
- *
- *     Save the state we need in order to be able to restore the interface
- *     upon resume from suspend
- *
- *     FIXME: review
- */
-static int cdv_save_display_registers(struct drm_device *dev)
-{
-       return 0;
-}
-
-/**
- *     cdv_restore_display_registers   -       restore lost register state
- *     @dev: our DRM device
- *
- *     Restore register state that was lost during suspend and resume.
- *
- *     FIXME: review
- */
-static int cdv_restore_display_registers(struct drm_device *dev)
-{
-       return 0;
-}
-
-static int cdv_power_down(struct drm_device *dev)
-{
-       return 0;
-}
-
-static int cdv_power_up(struct drm_device *dev)
-{
-       return 0;
-}
-
-/* FIXME ? - shared with Poulsbo */
-static void cdv_get_core_freq(struct drm_device *dev)
-{
-       uint32_t clock;
-       struct pci_dev *pci_root = pci_get_bus_and_slot(0, 0);
-       struct drm_psb_private *dev_priv = dev->dev_private;
-
-       pci_write_config_dword(pci_root, 0xD0, 0xD0050300);
-       pci_read_config_dword(pci_root, 0xD4, &clock);
-       pci_dev_put(pci_root);
-
-       switch (clock & 0x07) {
-       case 0:
-               dev_priv->core_freq = 100;
-               break;
-       case 1:
-               dev_priv->core_freq = 133;
-               break;
-       case 2:
-               dev_priv->core_freq = 150;
-               break;
-       case 3:
-               dev_priv->core_freq = 178;
-               break;
-       case 4:
-               dev_priv->core_freq = 200;
-               break;
-       case 5:
-       case 6:
-       case 7:
-               dev_priv->core_freq = 266;
-       default:
-               dev_priv->core_freq = 0;
-       }
-}
-
-static int cdv_chip_setup(struct drm_device *dev)
-{
-       cdv_get_core_freq(dev);
-       gma_intel_opregion_init(dev);
-       psb_intel_init_bios(dev);
-       return 0;
-}
-
-/* CDV is much like Poulsbo but has MID like SGX offsets and PM */
-
-const struct psb_ops cdv_chip_ops = {
-       .name = "Cedartrail",
-       .accel_2d = 0,
-       .pipes = 2,
-       .sgx_offset = MRST_SGX_OFFSET,
-       .chip_setup = cdv_chip_setup,
-
-       .crtc_helper = &cdv_intel_helper_funcs,
-       .crtc_funcs = &cdv_intel_crtc_funcs,
-
-       .output_init = cdv_output_init,
-
-#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
-       .backlight_init = cdv_backlight_init,
-#endif
-
-       .init_pm = cdv_init_pm,
-       .save_regs = cdv_save_display_registers,
-       .restore_regs = cdv_restore_display_registers,
-       .power_down = cdv_power_down,
-       .power_up = cdv_power_up,
-};
diff --git a/drivers/staging/gma500/cdv_device.h b/drivers/staging/gma500/cdv_device.h
deleted file mode 100644 (file)
index 2a88b7b..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright Â© 2011 Intel Corporation
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc., 
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-extern const struct drm_crtc_helper_funcs cdv_intel_helper_funcs;
-extern const struct drm_crtc_funcs cdv_intel_crtc_funcs;
-extern void cdv_intel_crt_init(struct drm_device *dev,
-                       struct psb_intel_mode_device *mode_dev);
-extern void cdv_intel_lvds_init(struct drm_device *dev,
-                       struct psb_intel_mode_device *mode_dev);
-extern void cdv_hdmi_init(struct drm_device *dev, struct psb_intel_mode_device *mode_dev,
-                       int reg);
-extern struct drm_display_mode *cdv_intel_crtc_mode_get(struct drm_device *dev,
-                                            struct drm_crtc *crtc);
-
-extern inline void cdv_intel_wait_for_vblank(struct drm_device *dev)
-{
-       /* Wait for 20ms, i.e. one cycle at 50hz. */
-        /* FIXME: msleep ?? */
-       mdelay(20);
-}
-
-
diff --git a/drivers/staging/gma500/cdv_intel_crt.c b/drivers/staging/gma500/cdv_intel_crt.c
deleted file mode 100644 (file)
index efda63b..0000000
+++ /dev/null
@@ -1,326 +0,0 @@
-/*
- * Copyright Â© 2006-2007 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Authors:
- *     Eric Anholt <eric@anholt.net>
- */
-
-#include <linux/i2c.h>
-#include <drm/drmP.h>
-
-#include "intel_bios.h"
-#include "psb_drv.h"
-#include "psb_intel_drv.h"
-#include "psb_intel_reg.h"
-#include "power.h"
-#include <linux/pm_runtime.h>
-
-
-static void cdv_intel_crt_dpms(struct drm_encoder *encoder, int mode)
-{
-       struct drm_device *dev = encoder->dev;
-       u32 temp, reg;
-       reg = ADPA;
-
-       temp = REG_READ(reg);
-       temp &= ~(ADPA_HSYNC_CNTL_DISABLE | ADPA_VSYNC_CNTL_DISABLE);
-       temp &= ~ADPA_DAC_ENABLE;
-
-       switch (mode) {
-       case DRM_MODE_DPMS_ON:
-               temp |= ADPA_DAC_ENABLE;
-               break;
-       case DRM_MODE_DPMS_STANDBY:
-               temp |= ADPA_DAC_ENABLE | ADPA_HSYNC_CNTL_DISABLE;
-               break;
-       case DRM_MODE_DPMS_SUSPEND:
-               temp |= ADPA_DAC_ENABLE | ADPA_VSYNC_CNTL_DISABLE;
-               break;
-       case DRM_MODE_DPMS_OFF:
-               temp |= ADPA_HSYNC_CNTL_DISABLE | ADPA_VSYNC_CNTL_DISABLE;
-               break;
-       }
-
-       REG_WRITE(reg, temp);
-}
-
-static int cdv_intel_crt_mode_valid(struct drm_connector *connector,
-                               struct drm_display_mode *mode)
-{
-       int max_clock = 0;
-       if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
-               return MODE_NO_DBLESCAN;
-
-       /* The lowest clock for CDV is 20000KHz */
-       if (mode->clock < 20000)
-               return MODE_CLOCK_LOW;
-
-       /* The max clock for CDV is 355 instead of 400 */
-       max_clock = 355000;
-       if (mode->clock > max_clock)
-               return MODE_CLOCK_HIGH;
-
-       if (mode->hdisplay > 1680 || mode->vdisplay > 1050)
-               return MODE_PANEL;
-
-       return MODE_OK;
-}
-
-static bool cdv_intel_crt_mode_fixup(struct drm_encoder *encoder,
-                                struct drm_display_mode *mode,
-                                struct drm_display_mode *adjusted_mode)
-{
-       return true;
-}
-
-static void cdv_intel_crt_mode_set(struct drm_encoder *encoder,
-                              struct drm_display_mode *mode,
-                              struct drm_display_mode *adjusted_mode)
-{
-
-       struct drm_device *dev = encoder->dev;
-       struct drm_crtc *crtc = encoder->crtc;
-       struct psb_intel_crtc *psb_intel_crtc =
-                                       to_psb_intel_crtc(crtc);
-       int dpll_md_reg;
-       u32 adpa, dpll_md;
-       u32 adpa_reg;
-
-       if (psb_intel_crtc->pipe == 0)
-               dpll_md_reg = DPLL_A_MD;
-       else
-               dpll_md_reg = DPLL_B_MD;
-
-       adpa_reg = ADPA;
-
-       /*
-        * Disable separate mode multiplier used when cloning SDVO to CRT
-        * XXX this needs to be adjusted when we really are cloning
-        */
-       {
-               dpll_md = REG_READ(dpll_md_reg);
-               REG_WRITE(dpll_md_reg,
-                          dpll_md & ~DPLL_MD_UDI_MULTIPLIER_MASK);
-       }
-
-       adpa = 0;
-       if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC)
-               adpa |= ADPA_HSYNC_ACTIVE_HIGH;
-       if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC)
-               adpa |= ADPA_VSYNC_ACTIVE_HIGH;
-
-       if (psb_intel_crtc->pipe == 0)
-               adpa |= ADPA_PIPE_A_SELECT;
-       else
-               adpa |= ADPA_PIPE_B_SELECT;
-
-       REG_WRITE(adpa_reg, adpa);
-}
-
-
-/**
- * Uses CRT_HOTPLUG_EN and CRT_HOTPLUG_STAT to detect CRT presence.
- *
- * \return true if CRT is connected.
- * \return false if CRT is disconnected.
- */
-static bool cdv_intel_crt_detect_hotplug(struct drm_connector *connector,
-                                                               bool force)
-{
-       struct drm_device *dev = connector->dev;
-       u32 hotplug_en;
-       int i, tries = 0, ret = false;
-       u32 adpa_orig;
-
-       /* disable the DAC when doing the hotplug detection */
-
-       adpa_orig = REG_READ(ADPA);
-
-       REG_WRITE(ADPA, adpa_orig & ~(ADPA_DAC_ENABLE));
-
-       /*
-        * On a CDV thep, CRT detect sequence need to be done twice
-        * to get a reliable result.
-        */
-       tries = 2;
-
-       hotplug_en = REG_READ(PORT_HOTPLUG_EN);
-       hotplug_en &= ~(CRT_HOTPLUG_DETECT_MASK);
-       hotplug_en |= CRT_HOTPLUG_FORCE_DETECT;
-
-       hotplug_en |= CRT_HOTPLUG_ACTIVATION_PERIOD_64;
-       hotplug_en |= CRT_HOTPLUG_VOLTAGE_COMPARE_50;
-
-       for (i = 0; i < tries ; i++) {
-               unsigned long timeout;
-               /* turn on the FORCE_DETECT */
-               REG_WRITE(PORT_HOTPLUG_EN, hotplug_en);
-               timeout = jiffies + msecs_to_jiffies(1000);
-               /* wait for FORCE_DETECT to go off */
-               do {
-                       if (!(REG_READ(PORT_HOTPLUG_EN) &
-                                       CRT_HOTPLUG_FORCE_DETECT))
-                               break;
-                       msleep(1);
-               } while (time_after(timeout, jiffies));
-       }
-
-       if ((REG_READ(PORT_HOTPLUG_STAT) & CRT_HOTPLUG_MONITOR_MASK) !=
-           CRT_HOTPLUG_MONITOR_NONE)
-               ret = true;
-
-       /* Restore the saved ADPA */
-       REG_WRITE(ADPA, adpa_orig);
-       return ret;
-}
-
-static enum drm_connector_status cdv_intel_crt_detect(
-                               struct drm_connector *connector, bool force)
-{
-       if (cdv_intel_crt_detect_hotplug(connector, force))
-               return connector_status_connected;
-       else
-               return connector_status_disconnected;
-}
-
-static void cdv_intel_crt_destroy(struct drm_connector *connector)
-{
-       struct psb_intel_output *intel_output = to_psb_intel_output(connector);
-
-       psb_intel_i2c_destroy(intel_output->ddc_bus);
-       drm_sysfs_connector_remove(connector);
-       drm_connector_cleanup(connector);
-       kfree(connector);
-}
-
-static int cdv_intel_crt_get_modes(struct drm_connector *connector)
-{
-       struct psb_intel_output *intel_output =
-                               to_psb_intel_output(connector);
-       return psb_intel_ddc_get_modes(intel_output);
-}
-
-static int cdv_intel_crt_set_property(struct drm_connector *connector,
-                                 struct drm_property *property,
-                                 uint64_t value)
-{
-       return 0;
-}
-
-/*
- * Routines for controlling stuff on the analog port
- */
-
-static const struct drm_encoder_helper_funcs cdv_intel_crt_helper_funcs = {
-       .dpms = cdv_intel_crt_dpms,
-       .mode_fixup = cdv_intel_crt_mode_fixup,
-       .prepare = psb_intel_encoder_prepare,
-       .commit = psb_intel_encoder_commit,
-       .mode_set = cdv_intel_crt_mode_set,
-};
-
-static const struct drm_connector_funcs cdv_intel_crt_connector_funcs = {
-       .dpms = drm_helper_connector_dpms,
-       .detect = cdv_intel_crt_detect,
-       .fill_modes = drm_helper_probe_single_connector_modes,
-       .destroy = cdv_intel_crt_destroy,
-       .set_property = cdv_intel_crt_set_property,
-};
-
-static const struct drm_connector_helper_funcs
-                               cdv_intel_crt_connector_helper_funcs = {
-       .mode_valid = cdv_intel_crt_mode_valid,
-       .get_modes = cdv_intel_crt_get_modes,
-       .best_encoder = psb_intel_best_encoder,
-};
-
-static void cdv_intel_crt_enc_destroy(struct drm_encoder *encoder)
-{
-       drm_encoder_cleanup(encoder);
-}
-
-static const struct drm_encoder_funcs cdv_intel_crt_enc_funcs = {
-       .destroy = cdv_intel_crt_enc_destroy,
-};
-
-void cdv_intel_crt_init(struct drm_device *dev,
-                       struct psb_intel_mode_device *mode_dev)
-{
-
-       struct psb_intel_output *psb_intel_output;
-       struct drm_connector *connector;
-       struct drm_encoder *encoder;
-
-       u32 i2c_reg;
-
-       psb_intel_output = kzalloc(sizeof(struct psb_intel_output), GFP_KERNEL);
-       if (!psb_intel_output)
-               return;
-
-       psb_intel_output->mode_dev = mode_dev;
-       connector = &psb_intel_output->base;
-       drm_connector_init(dev, connector,
-               &cdv_intel_crt_connector_funcs, DRM_MODE_CONNECTOR_VGA);
-
-       encoder = &psb_intel_output->enc;
-       drm_encoder_init(dev, encoder,
-               &cdv_intel_crt_enc_funcs, DRM_MODE_ENCODER_DAC);
-
-       drm_mode_connector_attach_encoder(&psb_intel_output->base,
-                                         &psb_intel_output->enc);
-
-       /* Set up the DDC bus. */
-       i2c_reg = GPIOA;
-       /* Remove the following code for CDV */
-       /*
-       if (dev_priv->crt_ddc_bus != 0)
-               i2c_reg = dev_priv->crt_ddc_bus;
-       }*/
-       psb_intel_output->ddc_bus = psb_intel_i2c_create(dev,
-                                               i2c_reg, "CRTDDC_A");
-       if (!psb_intel_output->ddc_bus) {
-               dev_printk(KERN_ERR, &dev->pdev->dev, "DDC bus registration "
-                          "failed.\n");
-               goto failed_ddc;
-       }
-
-       psb_intel_output->type = INTEL_OUTPUT_ANALOG;
-       /*
-       psb_intel_output->clone_mask = (1 << INTEL_ANALOG_CLONE_BIT);
-       psb_intel_output->crtc_mask = (1 << 0) | (1 << 1);
-       */
-       connector->interlace_allowed = 0;
-       connector->doublescan_allowed = 0;
-
-       drm_encoder_helper_add(encoder, &cdv_intel_crt_helper_funcs);
-       drm_connector_helper_add(connector,
-                                       &cdv_intel_crt_connector_helper_funcs);
-
-       drm_sysfs_connector_add(connector);
-
-       return;
-failed_ddc:
-       drm_encoder_cleanup(&psb_intel_output->enc);
-       drm_connector_cleanup(&psb_intel_output->base);
-       kfree(psb_intel_output);
-       return;
-}
diff --git a/drivers/staging/gma500/cdv_intel_display.c b/drivers/staging/gma500/cdv_intel_display.c
deleted file mode 100644 (file)
index c63a327..0000000
+++ /dev/null
@@ -1,1508 +0,0 @@
-/*
- * Copyright Â© 2006-2011 Intel Corporation
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Authors:
- *     Eric Anholt <eric@anholt.net>
- */
-
-#include <linux/i2c.h>
-#include <linux/pm_runtime.h>
-
-#include <drm/drmP.h>
-#include "framebuffer.h"
-#include "psb_drv.h"
-#include "psb_intel_drv.h"
-#include "psb_intel_reg.h"
-#include "psb_intel_display.h"
-#include "power.h"
-#include "cdv_device.h"
-
-
-struct cdv_intel_range_t {
-       int min, max;
-};
-
-struct cdv_intel_p2_t {
-       int dot_limit;
-       int p2_slow, p2_fast;
-};
-
-struct cdv_intel_clock_t {
-       /* given values */
-       int n;
-       int m1, m2;
-       int p1, p2;
-       /* derived values */
-       int dot;
-       int vco;
-       int m;
-       int p;
-};
-
-#define INTEL_P2_NUM                 2
-
-struct cdv_intel_limit_t {
-       struct cdv_intel_range_t dot, vco, n, m, m1, m2, p, p1;
-       struct cdv_intel_p2_t p2;
-};
-
-#define CDV_LIMIT_SINGLE_LVDS_96       0
-#define CDV_LIMIT_SINGLE_LVDS_100      1
-#define CDV_LIMIT_DAC_HDMI_27          2
-#define CDV_LIMIT_DAC_HDMI_96          3
-
-static const struct cdv_intel_limit_t cdv_intel_limits[] = {
-       {                       /* CDV_SIGNLE_LVDS_96MHz */
-        .dot = {.min = 20000, .max = 115500},
-        .vco = {.min = 1800000, .max = 3600000},
-        .n = {.min = 2, .max = 6},
-        .m = {.min = 60, .max = 160},
-        .m1 = {.min = 0, .max = 0},
-        .m2 = {.min = 58, .max = 158},
-        .p = {.min = 28, .max = 140},
-        .p1 = {.min = 2, .max = 10},
-        .p2 = {.dot_limit = 200000,
-               .p2_slow = 14, .p2_fast = 14},
-        },
-       {                       /* CDV_SINGLE_LVDS_100MHz */
-        .dot = {.min = 20000, .max = 115500},
-        .vco = {.min = 1800000, .max = 3600000},
-        .n = {.min = 2, .max = 6},
-        .m = {.min = 60, .max = 160},
-        .m1 = {.min = 0, .max = 0},
-        .m2 = {.min = 58, .max = 158},
-        .p = {.min = 28, .max = 140},
-        .p1 = {.min = 2, .max = 10},
-        /* The single-channel range is 25-112Mhz, and dual-channel
-         * is 80-224Mhz.  Prefer single channel as much as possible.
-         */
-        .p2 = {.dot_limit = 200000, .p2_slow = 14, .p2_fast = 14},
-        },
-       {                       /* CDV_DAC_HDMI_27MHz */
-        .dot = {.min = 20000, .max = 400000},
-        .vco = {.min = 1809000, .max = 3564000},
-        .n = {.min = 1, .max = 1},
-        .m = {.min = 67, .max = 132},
-        .m1 = {.min = 0, .max = 0},
-        .m2 = {.min = 65, .max = 130},
-        .p = {.min = 5, .max = 90},
-        .p1 = {.min = 1, .max = 9},
-        .p2 = {.dot_limit = 225000, .p2_slow = 10, .p2_fast = 5},
-        },
-       {                       /* CDV_DAC_HDMI_96MHz */
-        .dot = {.min = 20000, .max = 400000},
-        .vco = {.min = 1800000, .max = 3600000},
-        .n = {.min = 2, .max = 6},
-        .m = {.min = 60, .max = 160},
-        .m1 = {.min = 0, .max = 0},
-        .m2 = {.min = 58, .max = 158},
-        .p = {.min = 5, .max = 100},
-        .p1 = {.min = 1, .max = 10},
-        .p2 = {.dot_limit = 225000, .p2_slow = 10, .p2_fast = 5},
-        },
-};
-
-#define _wait_for(COND, MS, W) ({ \
-       unsigned long timeout__ = jiffies + msecs_to_jiffies(MS);       \
-       int ret__ = 0;                                                  \
-       while (!(COND)) {                                               \
-               if (time_after(jiffies, timeout__)) {                   \
-                       ret__ = -ETIMEDOUT;                             \
-                       break;                                          \
-               }                                                       \
-               if (W && !in_dbg_master())                              \
-                       msleep(W);                                      \
-       }                                                               \
-       ret__;                                                          \
-})
-
-#define wait_for(COND, MS) _wait_for(COND, MS, 1)
-
-
-static int cdv_sb_read(struct drm_device *dev, u32 reg, u32 *val)
-{
-       int ret;
-
-       ret = wait_for((REG_READ(SB_PCKT) & SB_BUSY) == 0, 1000);
-       if (ret) {
-               DRM_ERROR("timeout waiting for SB to idle before read\n");
-               return ret;
-       }
-
-       REG_WRITE(SB_ADDR, reg);
-       REG_WRITE(SB_PCKT,
-                  SET_FIELD(SB_OPCODE_READ, SB_OPCODE) |
-                  SET_FIELD(SB_DEST_DPLL, SB_DEST) |
-                  SET_FIELD(0xf, SB_BYTE_ENABLE));
-
-       ret = wait_for((REG_READ(SB_PCKT) & SB_BUSY) == 0, 1000);
-       if (ret) {
-               DRM_ERROR("timeout waiting for SB to idle after read\n");
-               return ret;
-       }
-
-       *val = REG_READ(SB_DATA);
-
-       return 0;
-}
-
-static int cdv_sb_write(struct drm_device *dev, u32 reg, u32 val)
-{
-       int ret;
-       static bool dpio_debug = true;
-       u32 temp;
-
-       if (dpio_debug) {
-               if (cdv_sb_read(dev, reg, &temp) == 0)
-                       DRM_DEBUG_KMS("0x%08x: 0x%08x (before)\n", reg, temp);
-               DRM_DEBUG_KMS("0x%08x: 0x%08x\n", reg, val);
-       }
-
-       ret = wait_for((REG_READ(SB_PCKT) & SB_BUSY) == 0, 1000);
-       if (ret) {
-               DRM_ERROR("timeout waiting for SB to idle before write\n");
-               return ret;
-       }
-
-       REG_WRITE(SB_ADDR, reg);
-       REG_WRITE(SB_DATA, val);
-       REG_WRITE(SB_PCKT,
-                  SET_FIELD(SB_OPCODE_WRITE, SB_OPCODE) |
-                  SET_FIELD(SB_DEST_DPLL, SB_DEST) |
-                  SET_FIELD(0xf, SB_BYTE_ENABLE));
-
-       ret = wait_for((REG_READ(SB_PCKT) & SB_BUSY) == 0, 1000);
-       if (ret) {
-               DRM_ERROR("timeout waiting for SB to idle after write\n");
-               return ret;
-       }
-
-       if (dpio_debug) {
-               if (cdv_sb_read(dev, reg, &temp) == 0)
-                       DRM_DEBUG_KMS("0x%08x: 0x%08x (after)\n", reg, temp);
-       }
-
-       return 0;
-}
-
-/* Reset the DPIO configuration register.  The BIOS does this at every
- * mode set.
- */
-static void cdv_sb_reset(struct drm_device *dev)
-{
-
-       REG_WRITE(DPIO_CFG, 0);
-       REG_READ(DPIO_CFG);
-       REG_WRITE(DPIO_CFG, DPIO_MODE_SELECT_0 | DPIO_CMN_RESET_N);
-}
-
-/* Unlike most Intel display engines, on Cedarview the DPLL registers
- * are behind this sideband bus.  They must be programmed while the
- * DPLL reference clock is on in the DPLL control register, but before
- * the DPLL is enabled in the DPLL control register.
- */
-static int
-cdv_dpll_set_clock_cdv(struct drm_device *dev, struct drm_crtc *crtc,
-                              struct cdv_intel_clock_t *clock)
-{
-       struct psb_intel_crtc *psb_crtc =
-                               to_psb_intel_crtc(crtc);
-       int pipe = psb_crtc->pipe;
-       u32 m, n_vco, p;
-       int ret = 0;
-       int dpll_reg = (pipe == 0) ? DPLL_A : DPLL_B;
-       u32 ref_value;
-
-       cdv_sb_reset(dev);
-
-       if ((REG_READ(dpll_reg) & DPLL_SYNCLOCK_ENABLE) == 0) {
-               DRM_ERROR("Attempting to set DPLL with refclk disabled\n");
-               return -EBUSY;
-       }
-
-       /* Follow the BIOS and write the REF/SFR Register. Hardcoded value */
-       ref_value = 0x68A701;
-
-       cdv_sb_write(dev, SB_REF_SFR(pipe), ref_value);
-
-       /* We don't know what the other fields of these regs are, so
-        * leave them in place.
-        */
-       ret = cdv_sb_read(dev, SB_M(pipe), &m);
-       if (ret)
-               return ret;
-       m &= ~SB_M_DIVIDER_MASK;
-       m |= ((clock->m2) << SB_M_DIVIDER_SHIFT);
-       ret = cdv_sb_write(dev, SB_M(pipe), m);
-       if (ret)
-               return ret;
-
-       ret = cdv_sb_read(dev, SB_N_VCO(pipe), &n_vco);
-       if (ret)
-               return ret;
-
-       /* Follow the BIOS to program the N_DIVIDER REG */
-       n_vco &= 0xFFFF;
-       n_vco |= 0x107;
-       n_vco &= ~(SB_N_VCO_SEL_MASK |
-                  SB_N_DIVIDER_MASK |
-                  SB_N_CB_TUNE_MASK);
-
-       n_vco |= ((clock->n) << SB_N_DIVIDER_SHIFT);
-
-       if (clock->vco < 2250000) {
-               n_vco |= (2 << SB_N_CB_TUNE_SHIFT);
-               n_vco |= (0 << SB_N_VCO_SEL_SHIFT);
-       } else if (clock->vco < 2750000) {
-               n_vco |= (1 << SB_N_CB_TUNE_SHIFT);
-               n_vco |= (1 << SB_N_VCO_SEL_SHIFT);
-       } else if (clock->vco < 3300000) {
-               n_vco |= (0 << SB_N_CB_TUNE_SHIFT);
-               n_vco |= (2 << SB_N_VCO_SEL_SHIFT);
-       } else {
-               n_vco |= (0 << SB_N_CB_TUNE_SHIFT);
-               n_vco |= (3 << SB_N_VCO_SEL_SHIFT);
-       }
-
-       ret = cdv_sb_write(dev, SB_N_VCO(pipe), n_vco);
-       if (ret)
-               return ret;
-
-       ret = cdv_sb_read(dev, SB_P(pipe), &p);
-       if (ret)
-               return ret;
-       p &= ~(SB_P2_DIVIDER_MASK | SB_P1_DIVIDER_MASK);
-       p |= SET_FIELD(clock->p1, SB_P1_DIVIDER);
-       switch (clock->p2) {
-       case 5:
-               p |= SET_FIELD(SB_P2_5, SB_P2_DIVIDER);
-               break;
-       case 10:
-               p |= SET_FIELD(SB_P2_10, SB_P2_DIVIDER);
-               break;
-       case 14:
-               p |= SET_FIELD(SB_P2_14, SB_P2_DIVIDER);
-               break;
-       case 7:
-               p |= SET_FIELD(SB_P2_7, SB_P2_DIVIDER);
-               break;
-       default:
-               DRM_ERROR("Bad P2 clock: %d\n", clock->p2);
-               return -EINVAL;
-       }
-       ret = cdv_sb_write(dev, SB_P(pipe), p);
-       if (ret)
-               return ret;
-
-       /* always Program the Lane Register for the Pipe A*/
-       if (pipe == 0) {
-               /* Program the Lane0/1 for HDMI B */
-               u32 lane_reg, lane_value;
-
-               lane_reg = PSB_LANE0;
-               cdv_sb_read(dev, lane_reg, &lane_value);
-               lane_value &= ~(LANE_PLL_MASK);
-               lane_value |= LANE_PLL_ENABLE;
-               cdv_sb_write(dev, lane_reg, lane_value);
-
-               lane_reg = PSB_LANE1;
-               cdv_sb_read(dev, lane_reg, &lane_value);
-               lane_value &= ~(LANE_PLL_MASK);
-               lane_value |= LANE_PLL_ENABLE;
-               cdv_sb_write(dev, lane_reg, lane_value);
-
-               /* Program the Lane2/3 for HDMI C */
-               lane_reg = PSB_LANE2;
-               cdv_sb_read(dev, lane_reg, &lane_value);
-               lane_value &= ~(LANE_PLL_MASK);
-               lane_value |= LANE_PLL_ENABLE;
-               cdv_sb_write(dev, lane_reg, lane_value);
-
-               lane_reg = PSB_LANE3;
-               cdv_sb_read(dev, lane_reg, &lane_value);
-               lane_value &= ~(LANE_PLL_MASK);
-               lane_value |= LANE_PLL_ENABLE;
-               cdv_sb_write(dev, lane_reg, lane_value);
-       }
-
-       return 0;
-}
-
-/*
- * Returns whether any output on the specified pipe is of the specified type
- */
-bool cdv_intel_pipe_has_type(struct drm_crtc *crtc, int type)
-{
-       struct drm_device *dev = crtc->dev;
-       struct drm_mode_config *mode_config = &dev->mode_config;
-       struct drm_connector *l_entry;
-
-       list_for_each_entry(l_entry, &mode_config->connector_list, head) {
-               if (l_entry->encoder && l_entry->encoder->crtc == crtc) {
-                       struct psb_intel_output *psb_intel_output =
-                           to_psb_intel_output(l_entry);
-                       if (psb_intel_output->type == type)
-                               return true;
-               }
-       }
-       return false;
-}
-
-static const struct cdv_intel_limit_t *cdv_intel_limit(struct drm_crtc *crtc,
-                                                       int refclk)
-{
-       const struct cdv_intel_limit_t *limit;
-       if (cdv_intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) {
-               /*
-                * Now only single-channel LVDS is supported on CDV. If it is
-                * incorrect, please add the dual-channel LVDS.
-                */
-               if (refclk == 96000)
-                       limit = &cdv_intel_limits[CDV_LIMIT_SINGLE_LVDS_96];
-               else
-                       limit = &cdv_intel_limits[CDV_LIMIT_SINGLE_LVDS_100];
-       } else {
-               if (refclk == 27000)
-                       limit = &cdv_intel_limits[CDV_LIMIT_DAC_HDMI_27];
-               else
-                       limit = &cdv_intel_limits[CDV_LIMIT_DAC_HDMI_96];
-       }
-       return limit;
-}
-
-/* m1 is reserved as 0 in CDV, n is a ring counter */
-static void cdv_intel_clock(struct drm_device *dev,
-                       int refclk, struct cdv_intel_clock_t *clock)
-{
-       clock->m = clock->m2 + 2;
-       clock->p = clock->p1 * clock->p2;
-       clock->vco = (refclk * clock->m) / clock->n;
-       clock->dot = clock->vco / clock->p;
-}
-
-
-#define INTELPllInvalid(s)   { /* ErrorF (s) */; return false; }
-static bool cdv_intel_PLL_is_valid(struct drm_crtc *crtc,
-                               const struct cdv_intel_limit_t *limit,
-                              struct cdv_intel_clock_t *clock)
-{
-       if (clock->p1 < limit->p1.min || limit->p1.max < clock->p1)
-               INTELPllInvalid("p1 out of range\n");
-       if (clock->p < limit->p.min || limit->p.max < clock->p)
-               INTELPllInvalid("p out of range\n");
-       /* unnecessary to check the range of m(m1/M2)/n again */
-       if (clock->vco < limit->vco.min || limit->vco.max < clock->vco)
-               INTELPllInvalid("vco out of range\n");
-       /* XXX: We may need to be checking "Dot clock"
-        * depending on the multiplier, connector, etc.,
-        * rather than just a single range.
-        */
-       if (clock->dot < limit->dot.min || limit->dot.max < clock->dot)
-               INTELPllInvalid("dot out of range\n");
-
-       return true;
-}
-
-static bool cdv_intel_find_best_PLL(struct drm_crtc *crtc, int target,
-                               int refclk,
-                               struct cdv_intel_clock_t *best_clock)
-{
-       struct drm_device *dev = crtc->dev;
-       struct cdv_intel_clock_t clock;
-       const struct cdv_intel_limit_t *limit = cdv_intel_limit(crtc, refclk);
-       int err = target;
-
-
-       if (cdv_intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) &&
-           (REG_READ(LVDS) & LVDS_PORT_EN) != 0) {
-               /*
-                * For LVDS, if the panel is on, just rely on its current
-                * settings for dual-channel.  We haven't figured out how to
-                * reliably set up different single/dual channel state, if we
-                * even can.
-                */
-               if ((REG_READ(LVDS) & LVDS_CLKB_POWER_MASK) ==
-                   LVDS_CLKB_POWER_UP)
-                       clock.p2 = limit->p2.p2_fast;
-               else
-                       clock.p2 = limit->p2.p2_slow;
-       } else {
-               if (target < limit->p2.dot_limit)
-                       clock.p2 = limit->p2.p2_slow;
-               else
-                       clock.p2 = limit->p2.p2_fast;
-       }
-
-       memset(best_clock, 0, sizeof(*best_clock));
-       clock.m1 = 0;
-       /* m1 is reserved as 0 in CDV, n is a ring counter.
-          So skip the m1 loop */
-       for (clock.n = limit->n.min; clock.n <= limit->n.max; clock.n++) {
-               for (clock.m2 = limit->m2.min; clock.m2 <= limit->m2.max;
-                                            clock.m2++) {
-                       for (clock.p1 = limit->p1.min;
-                                       clock.p1 <= limit->p1.max;
-                                       clock.p1++) {
-                               int this_err;
-
-                               cdv_intel_clock(dev, refclk, &clock);
-
-                               if (!cdv_intel_PLL_is_valid(crtc,
-                                                               limit, &clock))
-                                               continue;
-
-                               this_err = abs(clock.dot - target);
-                               if (this_err < err) {
-                                       *best_clock = clock;
-                                       err = this_err;
-                               }
-                       }
-               }
-       }
-
-       return err != target;
-}
-
-int cdv_intel_pipe_set_base(struct drm_crtc *crtc,
-                           int x, int y, struct drm_framebuffer *old_fb)
-{
-       struct drm_device *dev = crtc->dev;
-       struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
-       struct psb_framebuffer *psbfb = to_psb_fb(crtc->fb);
-       int pipe = psb_intel_crtc->pipe;
-       unsigned long start, offset;
-       int dspbase = (pipe == 0 ? DSPABASE : DSPBBASE);
-       int dspsurf = (pipe == 0 ? DSPASURF : DSPBSURF);
-       int dspstride = (pipe == 0) ? DSPASTRIDE : DSPBSTRIDE;
-       int dspcntr_reg = (pipe == 0) ? DSPACNTR : DSPBCNTR;
-       u32 dspcntr;
-       int ret = 0;
-
-       if (!gma_power_begin(dev, true))
-               return 0;
-
-       /* no fb bound */
-       if (!crtc->fb) {
-               dev_err(dev->dev, "No FB bound\n");
-               goto psb_intel_pipe_cleaner;
-       }
-
-
-       /* We are displaying this buffer, make sure it is actually loaded
-          into the GTT */
-       ret = psb_gtt_pin(psbfb->gtt);
-       if (ret < 0)
-               goto psb_intel_pipe_set_base_exit;
-       start = psbfb->gtt->offset;
-       offset = y * crtc->fb->pitches[0] + x * (crtc->fb->bits_per_pixel / 8);
-
-       REG_WRITE(dspstride, crtc->fb->pitches[0]);
-
-       dspcntr = REG_READ(dspcntr_reg);
-       dspcntr &= ~DISPPLANE_PIXFORMAT_MASK;
-
-       switch (crtc->fb->bits_per_pixel) {
-       case 8:
-               dspcntr |= DISPPLANE_8BPP;
-               break;
-       case 16:
-               if (crtc->fb->depth == 15)
-                       dspcntr |= DISPPLANE_15_16BPP;
-               else
-                       dspcntr |= DISPPLANE_16BPP;
-               break;
-       case 24:
-       case 32:
-               dspcntr |= DISPPLANE_32BPP_NO_ALPHA;
-               break;
-       default:
-               dev_err(dev->dev, "Unknown color depth\n");
-               ret = -EINVAL;
-               goto psb_intel_pipe_set_base_exit;
-       }
-       REG_WRITE(dspcntr_reg, dspcntr);
-
-       dev_dbg(dev->dev,
-               "Writing base %08lX %08lX %d %d\n", start, offset, x, y);
-
-       REG_WRITE(dspbase, offset);
-       REG_READ(dspbase);
-       REG_WRITE(dspsurf, start);
-       REG_READ(dspsurf);
-
-psb_intel_pipe_cleaner:
-       /* If there was a previous display we can now unpin it */
-       if (old_fb)
-               psb_gtt_unpin(to_psb_fb(old_fb)->gtt);
-
-psb_intel_pipe_set_base_exit:
-       gma_power_end(dev);
-       return ret;
-}
-
-/**
- * Sets the power management mode of the pipe and plane.
- *
- * This code should probably grow support for turning the cursor off and back
- * on appropriately at the same time as we're turning the pipe off/on.
- */
-static void cdv_intel_crtc_dpms(struct drm_crtc *crtc, int mode)
-{
-       struct drm_device *dev = crtc->dev;
-       struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
-       int pipe = psb_intel_crtc->pipe;
-       int dpll_reg = (pipe == 0) ? DPLL_A : DPLL_B;
-       int dspcntr_reg = (pipe == 0) ? DSPACNTR : DSPBCNTR;
-       int dspbase_reg = (pipe == 0) ? DSPABASE : DSPBBASE;
-       int pipeconf_reg = (pipe == 0) ? PIPEACONF : PIPEBCONF;
-       u32 temp;
-       bool enabled;
-
-       /* XXX: When our outputs are all unaware of DPMS modes other than off
-        * and on, we should map those modes to DRM_MODE_DPMS_OFF in the CRTC.
-        */
-       switch (mode) {
-       case DRM_MODE_DPMS_ON:
-       case DRM_MODE_DPMS_STANDBY:
-       case DRM_MODE_DPMS_SUSPEND:
-               /* Enable the DPLL */
-               temp = REG_READ(dpll_reg);
-               if ((temp & DPLL_VCO_ENABLE) == 0) {
-                       REG_WRITE(dpll_reg, temp);
-                       REG_READ(dpll_reg);
-                       /* Wait for the clocks to stabilize. */
-                       udelay(150);
-                       REG_WRITE(dpll_reg, temp | DPLL_VCO_ENABLE);
-                       REG_READ(dpll_reg);
-                       /* Wait for the clocks to stabilize. */
-                       udelay(150);
-                       REG_WRITE(dpll_reg, temp | DPLL_VCO_ENABLE);
-                       REG_READ(dpll_reg);
-                       /* Wait for the clocks to stabilize. */
-                       udelay(150);
-               }
-
-               /* Jim Bish - switch plan and pipe per scott */
-               /* Enable the plane */
-               temp = REG_READ(dspcntr_reg);
-               if ((temp & DISPLAY_PLANE_ENABLE) == 0) {
-                       REG_WRITE(dspcntr_reg,
-                                 temp | DISPLAY_PLANE_ENABLE);
-                       /* Flush the plane changes */
-                       REG_WRITE(dspbase_reg, REG_READ(dspbase_reg));
-               }
-
-               udelay(150);
-
-               /* Enable the pipe */
-               temp = REG_READ(pipeconf_reg);
-               if ((temp & PIPEACONF_ENABLE) == 0)
-                       REG_WRITE(pipeconf_reg, temp | PIPEACONF_ENABLE);
-
-               psb_intel_crtc_load_lut(crtc);
-
-               /* Give the overlay scaler a chance to enable
-                * if it's on this pipe */
-               /* psb_intel_crtc_dpms_video(crtc, true); TODO */
-               break;
-       case DRM_MODE_DPMS_OFF:
-               /* Give the overlay scaler a chance to disable
-                * if it's on this pipe */
-               /* psb_intel_crtc_dpms_video(crtc, FALSE); TODO */
-
-               /* Disable the VGA plane that we never use */
-               REG_WRITE(VGACNTRL, VGA_DISP_DISABLE);
-
-               /* Jim Bish - changed pipe/plane here as well. */
-
-               /* Wait for vblank for the disable to take effect */
-               cdv_intel_wait_for_vblank(dev);
-
-               /* Next, disable display pipes */
-               temp = REG_READ(pipeconf_reg);
-               if ((temp & PIPEACONF_ENABLE) != 0) {
-                       REG_WRITE(pipeconf_reg, temp & ~PIPEACONF_ENABLE);
-                       REG_READ(pipeconf_reg);
-               }
-
-               /* Wait for vblank for the disable to take effect. */
-               cdv_intel_wait_for_vblank(dev);
-
-               udelay(150);
-
-               /* Disable display plane */
-               temp = REG_READ(dspcntr_reg);
-               if ((temp & DISPLAY_PLANE_ENABLE) != 0) {
-                       REG_WRITE(dspcntr_reg,
-                                 temp & ~DISPLAY_PLANE_ENABLE);
-                       /* Flush the plane changes */
-                       REG_WRITE(dspbase_reg, REG_READ(dspbase_reg));
-                       REG_READ(dspbase_reg);
-               }
-
-               temp = REG_READ(dpll_reg);
-               if ((temp & DPLL_VCO_ENABLE) != 0) {
-                       REG_WRITE(dpll_reg, temp & ~DPLL_VCO_ENABLE);
-                       REG_READ(dpll_reg);
-               }
-
-               /* Wait for the clocks to turn off. */
-               udelay(150);
-               break;
-       }
-       enabled = crtc->enabled && mode != DRM_MODE_DPMS_OFF;
-       /*Set FIFO Watermarks*/
-       REG_WRITE(DSPARB, 0x3F3E);
-}
-
-static void cdv_intel_crtc_prepare(struct drm_crtc *crtc)
-{
-       struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
-       crtc_funcs->dpms(crtc, DRM_MODE_DPMS_OFF);
-}
-
-static void cdv_intel_crtc_commit(struct drm_crtc *crtc)
-{
-       struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
-       crtc_funcs->dpms(crtc, DRM_MODE_DPMS_ON);
-}
-
-void cdv_intel_encoder_prepare(struct drm_encoder *encoder)
-{
-       struct drm_encoder_helper_funcs *encoder_funcs =
-           encoder->helper_private;
-       /* lvds has its own version of prepare see cdv_intel_lvds_prepare */
-       encoder_funcs->dpms(encoder, DRM_MODE_DPMS_OFF);
-}
-
-void cdv_intel_encoder_commit(struct drm_encoder *encoder)
-{
-       struct drm_encoder_helper_funcs *encoder_funcs =
-           encoder->helper_private;
-       /* lvds has its own version of commit see cdv_intel_lvds_commit */
-       encoder_funcs->dpms(encoder, DRM_MODE_DPMS_ON);
-}
-
-static bool cdv_intel_crtc_mode_fixup(struct drm_crtc *crtc,
-                                 struct drm_display_mode *mode,
-                                 struct drm_display_mode *adjusted_mode)
-{
-       return true;
-}
-
-
-/**
- * Return the pipe currently connected to the panel fitter,
- * or -1 if the panel fitter is not present or not in use
- */
-static int cdv_intel_panel_fitter_pipe(struct drm_device *dev)
-{
-       u32 pfit_control;
-
-       pfit_control = REG_READ(PFIT_CONTROL);
-
-       /* See if the panel fitter is in use */
-       if ((pfit_control & PFIT_ENABLE) == 0)
-               return -1;
-       return (pfit_control >> 29) & 0x3;
-}
-
-static int cdv_intel_crtc_mode_set(struct drm_crtc *crtc,
-                              struct drm_display_mode *mode,
-                              struct drm_display_mode *adjusted_mode,
-                              int x, int y,
-                              struct drm_framebuffer *old_fb)
-{
-       struct drm_device *dev = crtc->dev;
-       struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
-       int pipe = psb_intel_crtc->pipe;
-       int dpll_reg = (pipe == 0) ? DPLL_A : DPLL_B;
-       int dpll_md_reg = (psb_intel_crtc->pipe == 0) ? DPLL_A_MD : DPLL_B_MD;
-       int dspcntr_reg = (pipe == 0) ? DSPACNTR : DSPBCNTR;
-       int pipeconf_reg = (pipe == 0) ? PIPEACONF : PIPEBCONF;
-       int htot_reg = (pipe == 0) ? HTOTAL_A : HTOTAL_B;
-       int hblank_reg = (pipe == 0) ? HBLANK_A : HBLANK_B;
-       int hsync_reg = (pipe == 0) ? HSYNC_A : HSYNC_B;
-       int vtot_reg = (pipe == 0) ? VTOTAL_A : VTOTAL_B;
-       int vblank_reg = (pipe == 0) ? VBLANK_A : VBLANK_B;
-       int vsync_reg = (pipe == 0) ? VSYNC_A : VSYNC_B;
-       int dspsize_reg = (pipe == 0) ? DSPASIZE : DSPBSIZE;
-       int dsppos_reg = (pipe == 0) ? DSPAPOS : DSPBPOS;
-       int pipesrc_reg = (pipe == 0) ? PIPEASRC : PIPEBSRC;
-       int refclk;
-       struct cdv_intel_clock_t clock;
-       u32 dpll = 0, dspcntr, pipeconf;
-       bool ok, is_sdvo = false, is_dvo = false;
-       bool is_crt = false, is_lvds = false, is_tv = false;
-       bool is_hdmi = false;
-       struct drm_mode_config *mode_config = &dev->mode_config;
-       struct drm_connector *connector;
-
-       list_for_each_entry(connector, &mode_config->connector_list, head) {
-               struct psb_intel_output *psb_intel_output =
-                   to_psb_intel_output(connector);
-
-               if (!connector->encoder
-                   || connector->encoder->crtc != crtc)
-                       continue;
-
-               switch (psb_intel_output->type) {
-               case INTEL_OUTPUT_LVDS:
-                       is_lvds = true;
-                       break;
-               case INTEL_OUTPUT_SDVO:
-                       is_sdvo = true;
-                       break;
-               case INTEL_OUTPUT_DVO:
-                       is_dvo = true;
-                       break;
-               case INTEL_OUTPUT_TVOUT:
-                       is_tv = true;
-                       break;
-               case INTEL_OUTPUT_ANALOG:
-                       is_crt = true;
-                       break;
-               case INTEL_OUTPUT_HDMI:
-                       is_hdmi = true;
-                       break;
-               }
-       }
-
-       refclk = 96000;
-
-       /* Hack selection about ref clk for CRT */
-       /* Select 27MHz as the reference clk for HDMI */
-       if (is_crt || is_hdmi)
-               refclk = 27000;
-
-       drm_mode_debug_printmodeline(adjusted_mode);
-
-       ok = cdv_intel_find_best_PLL(crtc, adjusted_mode->clock, refclk,
-                                &clock);
-       if (!ok) {
-               dev_err(dev->dev, "Couldn't find PLL settings for mode!\n");
-               return 0;
-       }
-
-       dpll = DPLL_VGA_MODE_DIS;
-       if (is_tv) {
-               /* XXX: just matching BIOS for now */
-/*     dpll |= PLL_REF_INPUT_TVCLKINBC; */
-               dpll |= 3;
-       }
-               dpll |= PLL_REF_INPUT_DREFCLK;
-
-       dpll |= DPLL_SYNCLOCK_ENABLE;
-       dpll |= DPLL_VGA_MODE_DIS;
-       if (is_lvds)
-               dpll |= DPLLB_MODE_LVDS;
-       else
-               dpll |= DPLLB_MODE_DAC_SERIAL;
-       /* dpll |= (2 << 11); */
-
-       /* setup pipeconf */
-       pipeconf = REG_READ(pipeconf_reg);
-
-       /* Set up the display plane register */
-       dspcntr = DISPPLANE_GAMMA_ENABLE;
-
-       if (pipe == 0)
-               dspcntr |= DISPPLANE_SEL_PIPE_A;
-       else
-               dspcntr |= DISPPLANE_SEL_PIPE_B;
-
-       dspcntr |= DISPLAY_PLANE_ENABLE;
-       pipeconf |= PIPEACONF_ENABLE;
-
-       REG_WRITE(dpll_reg, dpll | DPLL_VGA_MODE_DIS | DPLL_SYNCLOCK_ENABLE);
-       REG_READ(dpll_reg);
-
-       cdv_dpll_set_clock_cdv(dev, crtc, &clock);
-
-       udelay(150);
-
-
-       /* The LVDS pin pair needs to be on before the DPLLs are enabled.
-        * This is an exception to the general rule that mode_set doesn't turn
-        * things on.
-        */
-       if (is_lvds) {
-               u32 lvds = REG_READ(LVDS);
-
-               lvds |=
-                   LVDS_PORT_EN | LVDS_A0A2_CLKA_POWER_UP |
-                   LVDS_PIPEB_SELECT;
-               /* Set the B0-B3 data pairs corresponding to
-                * whether we're going to
-                * set the DPLLs for dual-channel mode or not.
-                */
-               if (clock.p2 == 7)
-                       lvds |= LVDS_B0B3_POWER_UP | LVDS_CLKB_POWER_UP;
-               else
-                       lvds &= ~(LVDS_B0B3_POWER_UP | LVDS_CLKB_POWER_UP);
-
-               /* It would be nice to set 24 vs 18-bit mode (LVDS_A3_POWER_UP)
-                * appropriately here, but we need to look more
-                * thoroughly into how panels behave in the two modes.
-                */
-
-               REG_WRITE(LVDS, lvds);
-               REG_READ(LVDS);
-       }
-
-       dpll |= DPLL_VCO_ENABLE;
-
-       /* Disable the panel fitter if it was on our pipe */
-       if (cdv_intel_panel_fitter_pipe(dev) == pipe)
-               REG_WRITE(PFIT_CONTROL, 0);
-
-       DRM_DEBUG_KMS("Mode for pipe %c:\n", pipe == 0 ? 'A' : 'B');
-       drm_mode_debug_printmodeline(mode);
-
-       REG_WRITE(dpll_reg,
-               (REG_READ(dpll_reg) & ~DPLL_LOCK) | DPLL_VCO_ENABLE);
-       REG_READ(dpll_reg);
-       /* Wait for the clocks to stabilize. */
-       udelay(150); /* 42 usec w/o calibration, 110 with.  rounded up. */
-
-       if (!(REG_READ(dpll_reg) & DPLL_LOCK)) {
-               dev_err(dev->dev, "Failed to get DPLL lock\n");
-               return -EBUSY;
-       }
-
-       {
-               int sdvo_pixel_multiply = adjusted_mode->clock / mode->clock;
-               REG_WRITE(dpll_md_reg, (0 << DPLL_MD_UDI_DIVIDER_SHIFT) | ((sdvo_pixel_multiply - 1) << DPLL_MD_UDI_MULTIPLIER_SHIFT));
-       }
-
-       REG_WRITE(htot_reg, (adjusted_mode->crtc_hdisplay - 1) |
-                 ((adjusted_mode->crtc_htotal - 1) << 16));
-       REG_WRITE(hblank_reg, (adjusted_mode->crtc_hblank_start - 1) |
-                 ((adjusted_mode->crtc_hblank_end - 1) << 16));
-       REG_WRITE(hsync_reg, (adjusted_mode->crtc_hsync_start - 1) |
-                 ((adjusted_mode->crtc_hsync_end - 1) << 16));
-       REG_WRITE(vtot_reg, (adjusted_mode->crtc_vdisplay - 1) |
-                 ((adjusted_mode->crtc_vtotal - 1) << 16));
-       REG_WRITE(vblank_reg, (adjusted_mode->crtc_vblank_start - 1) |
-                 ((adjusted_mode->crtc_vblank_end - 1) << 16));
-       REG_WRITE(vsync_reg, (adjusted_mode->crtc_vsync_start - 1) |
-                 ((adjusted_mode->crtc_vsync_end - 1) << 16));
-       /* pipesrc and dspsize control the size that is scaled from,
-        * which should always be the user's requested size.
-        */
-       REG_WRITE(dspsize_reg,
-                 ((mode->vdisplay - 1) << 16) | (mode->hdisplay - 1));
-       REG_WRITE(dsppos_reg, 0);
-       REG_WRITE(pipesrc_reg,
-                 ((mode->hdisplay - 1) << 16) | (mode->vdisplay - 1));
-       REG_WRITE(pipeconf_reg, pipeconf);
-       REG_READ(pipeconf_reg);
-
-       cdv_intel_wait_for_vblank(dev);
-
-       REG_WRITE(dspcntr_reg, dspcntr);
-
-       /* Flush the plane changes */
-       {
-               struct drm_crtc_helper_funcs *crtc_funcs =
-                   crtc->helper_private;
-               crtc_funcs->mode_set_base(crtc, x, y, old_fb);
-       }
-
-       cdv_intel_wait_for_vblank(dev);
-
-       return 0;
-}
-
-/** Loads the palette/gamma unit for the CRTC with the prepared values */
-void cdv_intel_crtc_load_lut(struct drm_crtc *crtc)
-{
-       struct drm_device *dev = crtc->dev;
-       struct drm_psb_private *dev_priv =
-                               (struct drm_psb_private *)dev->dev_private;
-       struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
-       int palreg = PALETTE_A;
-       int i;
-
-       /* The clocks have to be on to load the palette. */
-       if (!crtc->enabled)
-               return;
-
-       switch (psb_intel_crtc->pipe) {
-       case 0:
-               break;
-       case 1:
-               palreg = PALETTE_B;
-               break;
-       case 2:
-               palreg = PALETTE_C;
-               break;
-       default:
-               dev_err(dev->dev, "Illegal Pipe Number.\n");
-               return;
-       }
-
-       if (gma_power_begin(dev, false)) {
-               for (i = 0; i < 256; i++) {
-                       REG_WRITE(palreg + 4 * i,
-                                 ((psb_intel_crtc->lut_r[i] +
-                                 psb_intel_crtc->lut_adj[i]) << 16) |
-                                 ((psb_intel_crtc->lut_g[i] +
-                                 psb_intel_crtc->lut_adj[i]) << 8) |
-                                 (psb_intel_crtc->lut_b[i] +
-                                 psb_intel_crtc->lut_adj[i]));
-               }
-               gma_power_end(dev);
-       } else {
-               for (i = 0; i < 256; i++) {
-                       dev_priv->save_palette_a[i] =
-                                 ((psb_intel_crtc->lut_r[i] +
-                                 psb_intel_crtc->lut_adj[i]) << 16) |
-                                 ((psb_intel_crtc->lut_g[i] +
-                                 psb_intel_crtc->lut_adj[i]) << 8) |
-                                 (psb_intel_crtc->lut_b[i] +
-                                 psb_intel_crtc->lut_adj[i]);
-               }
-
-       }
-}
-
-/**
- * Save HW states of giving crtc
- */
-static void cdv_intel_crtc_save(struct drm_crtc *crtc)
-{
-       struct drm_device *dev = crtc->dev;
-       /* struct drm_psb_private *dev_priv =
-                       (struct drm_psb_private *)dev->dev_private; */
-       struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
-       struct psb_intel_crtc_state *crtc_state = psb_intel_crtc->crtc_state;
-       int pipeA = (psb_intel_crtc->pipe == 0);
-       uint32_t paletteReg;
-       int i;
-
-       if (!crtc_state) {
-               dev_dbg(dev->dev, "No CRTC state found\n");
-               return;
-       }
-
-       crtc_state->saveDSPCNTR = REG_READ(pipeA ? DSPACNTR : DSPBCNTR);
-       crtc_state->savePIPECONF = REG_READ(pipeA ? PIPEACONF : PIPEBCONF);
-       crtc_state->savePIPESRC = REG_READ(pipeA ? PIPEASRC : PIPEBSRC);
-       crtc_state->saveFP0 = REG_READ(pipeA ? FPA0 : FPB0);
-       crtc_state->saveFP1 = REG_READ(pipeA ? FPA1 : FPB1);
-       crtc_state->saveDPLL = REG_READ(pipeA ? DPLL_A : DPLL_B);
-       crtc_state->saveHTOTAL = REG_READ(pipeA ? HTOTAL_A : HTOTAL_B);
-       crtc_state->saveHBLANK = REG_READ(pipeA ? HBLANK_A : HBLANK_B);
-       crtc_state->saveHSYNC = REG_READ(pipeA ? HSYNC_A : HSYNC_B);
-       crtc_state->saveVTOTAL = REG_READ(pipeA ? VTOTAL_A : VTOTAL_B);
-       crtc_state->saveVBLANK = REG_READ(pipeA ? VBLANK_A : VBLANK_B);
-       crtc_state->saveVSYNC = REG_READ(pipeA ? VSYNC_A : VSYNC_B);
-       crtc_state->saveDSPSTRIDE = REG_READ(pipeA ? DSPASTRIDE : DSPBSTRIDE);
-
-       /*NOTE: DSPSIZE DSPPOS only for psb*/
-       crtc_state->saveDSPSIZE = REG_READ(pipeA ? DSPASIZE : DSPBSIZE);
-       crtc_state->saveDSPPOS = REG_READ(pipeA ? DSPAPOS : DSPBPOS);
-
-       crtc_state->saveDSPBASE = REG_READ(pipeA ? DSPABASE : DSPBBASE);
-
-       DRM_DEBUG("(%x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x)\n",
-                       crtc_state->saveDSPCNTR,
-                       crtc_state->savePIPECONF,
-                       crtc_state->savePIPESRC,
-                       crtc_state->saveFP0,
-                       crtc_state->saveFP1,
-                       crtc_state->saveDPLL,
-                       crtc_state->saveHTOTAL,
-                       crtc_state->saveHBLANK,
-                       crtc_state->saveHSYNC,
-                       crtc_state->saveVTOTAL,
-                       crtc_state->saveVBLANK,
-                       crtc_state->saveVSYNC,
-                       crtc_state->saveDSPSTRIDE,
-                       crtc_state->saveDSPSIZE,
-                       crtc_state->saveDSPPOS,
-                       crtc_state->saveDSPBASE
-               );
-
-       paletteReg = pipeA ? PALETTE_A : PALETTE_B;
-       for (i = 0; i < 256; ++i)
-               crtc_state->savePalette[i] = REG_READ(paletteReg + (i << 2));
-}
-
-/**
- * Restore HW states of giving crtc
- */
-static void cdv_intel_crtc_restore(struct drm_crtc *crtc)
-{
-       struct drm_device *dev = crtc->dev;
-       /* struct drm_psb_private * dev_priv =
-                               (struct drm_psb_private *)dev->dev_private; */
-       struct psb_intel_crtc *psb_intel_crtc =  to_psb_intel_crtc(crtc);
-       struct psb_intel_crtc_state *crtc_state = psb_intel_crtc->crtc_state;
-       /* struct drm_crtc_helper_funcs * crtc_funcs = crtc->helper_private; */
-       int pipeA = (psb_intel_crtc->pipe == 0);
-       uint32_t paletteReg;
-       int i;
-
-       if (!crtc_state) {
-               dev_dbg(dev->dev, "No crtc state\n");
-               return;
-       }
-
-       DRM_DEBUG(
-               "current:(%x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x)\n",
-               REG_READ(pipeA ? DSPACNTR : DSPBCNTR),
-               REG_READ(pipeA ? PIPEACONF : PIPEBCONF),
-               REG_READ(pipeA ? PIPEASRC : PIPEBSRC),
-               REG_READ(pipeA ? FPA0 : FPB0),
-               REG_READ(pipeA ? FPA1 : FPB1),
-               REG_READ(pipeA ? DPLL_A : DPLL_B),
-               REG_READ(pipeA ? HTOTAL_A : HTOTAL_B),
-               REG_READ(pipeA ? HBLANK_A : HBLANK_B),
-               REG_READ(pipeA ? HSYNC_A : HSYNC_B),
-               REG_READ(pipeA ? VTOTAL_A : VTOTAL_B),
-               REG_READ(pipeA ? VBLANK_A : VBLANK_B),
-               REG_READ(pipeA ? VSYNC_A : VSYNC_B),
-               REG_READ(pipeA ? DSPASTRIDE : DSPBSTRIDE),
-               REG_READ(pipeA ? DSPASIZE : DSPBSIZE),
-               REG_READ(pipeA ? DSPAPOS : DSPBPOS),
-               REG_READ(pipeA ? DSPABASE : DSPBBASE)
-               );
-
-       DRM_DEBUG(
-               "saved: (%x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x)\n",
-               crtc_state->saveDSPCNTR,
-               crtc_state->savePIPECONF,
-               crtc_state->savePIPESRC,
-               crtc_state->saveFP0,
-               crtc_state->saveFP1,
-               crtc_state->saveDPLL,
-               crtc_state->saveHTOTAL,
-               crtc_state->saveHBLANK,
-               crtc_state->saveHSYNC,
-               crtc_state->saveVTOTAL,
-               crtc_state->saveVBLANK,
-               crtc_state->saveVSYNC,
-               crtc_state->saveDSPSTRIDE,
-               crtc_state->saveDSPSIZE,
-               crtc_state->saveDSPPOS,
-               crtc_state->saveDSPBASE
-               );
-
-
-       if (crtc_state->saveDPLL & DPLL_VCO_ENABLE) {
-               REG_WRITE(pipeA ? DPLL_A : DPLL_B,
-                       crtc_state->saveDPLL & ~DPLL_VCO_ENABLE);
-               REG_READ(pipeA ? DPLL_A : DPLL_B);
-               DRM_DEBUG("write dpll: %x\n",
-                               REG_READ(pipeA ? DPLL_A : DPLL_B));
-               udelay(150);
-       }
-
-       REG_WRITE(pipeA ? FPA0 : FPB0, crtc_state->saveFP0);
-       REG_READ(pipeA ? FPA0 : FPB0);
-
-       REG_WRITE(pipeA ? FPA1 : FPB1, crtc_state->saveFP1);
-       REG_READ(pipeA ? FPA1 : FPB1);
-
-       REG_WRITE(pipeA ? DPLL_A : DPLL_B, crtc_state->saveDPLL);
-       REG_READ(pipeA ? DPLL_A : DPLL_B);
-       udelay(150);
-
-       REG_WRITE(pipeA ? HTOTAL_A : HTOTAL_B, crtc_state->saveHTOTAL);
-       REG_WRITE(pipeA ? HBLANK_A : HBLANK_B, crtc_state->saveHBLANK);
-       REG_WRITE(pipeA ? HSYNC_A : HSYNC_B, crtc_state->saveHSYNC);
-       REG_WRITE(pipeA ? VTOTAL_A : VTOTAL_B, crtc_state->saveVTOTAL);
-       REG_WRITE(pipeA ? VBLANK_A : VBLANK_B, crtc_state->saveVBLANK);
-       REG_WRITE(pipeA ? VSYNC_A : VSYNC_B, crtc_state->saveVSYNC);
-       REG_WRITE(pipeA ? DSPASTRIDE : DSPBSTRIDE, crtc_state->saveDSPSTRIDE);
-
-       REG_WRITE(pipeA ? DSPASIZE : DSPBSIZE, crtc_state->saveDSPSIZE);
-       REG_WRITE(pipeA ? DSPAPOS : DSPBPOS, crtc_state->saveDSPPOS);
-
-       REG_WRITE(pipeA ? PIPEASRC : PIPEBSRC, crtc_state->savePIPESRC);
-       REG_WRITE(pipeA ? DSPABASE : DSPBBASE, crtc_state->saveDSPBASE);
-       REG_WRITE(pipeA ? PIPEACONF : PIPEBCONF, crtc_state->savePIPECONF);
-
-       cdv_intel_wait_for_vblank(dev);
-
-       REG_WRITE(pipeA ? DSPACNTR : DSPBCNTR, crtc_state->saveDSPCNTR);
-       REG_WRITE(pipeA ? DSPABASE : DSPBBASE, crtc_state->saveDSPBASE);
-
-       cdv_intel_wait_for_vblank(dev);
-
-       paletteReg = pipeA ? PALETTE_A : PALETTE_B;
-       for (i = 0; i < 256; ++i)
-               REG_WRITE(paletteReg + (i << 2), crtc_state->savePalette[i]);
-}
-
-static int cdv_intel_crtc_cursor_set(struct drm_crtc *crtc,
-                                struct drm_file *file_priv,
-                                uint32_t handle,
-                                uint32_t width, uint32_t height)
-{
-       struct drm_device *dev = crtc->dev;
-       struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
-       int pipe = psb_intel_crtc->pipe;
-       uint32_t control = (pipe == 0) ? CURACNTR : CURBCNTR;
-       uint32_t base = (pipe == 0) ? CURABASE : CURBBASE;
-       uint32_t temp;
-       size_t addr = 0;
-       struct gtt_range *gt;
-       struct drm_gem_object *obj;
-       int ret;
-
-       /* if we want to turn of the cursor ignore width and height */
-       if (!handle) {
-               /* turn off the cursor */
-               temp = CURSOR_MODE_DISABLE;
-
-               if (gma_power_begin(dev, false)) {
-                       REG_WRITE(control, temp);
-                       REG_WRITE(base, 0);
-                       gma_power_end(dev);
-               }
-
-               /* unpin the old GEM object */
-               if (psb_intel_crtc->cursor_obj) {
-                       gt = container_of(psb_intel_crtc->cursor_obj,
-                                                       struct gtt_range, gem);
-                       psb_gtt_unpin(gt);
-                       drm_gem_object_unreference(psb_intel_crtc->cursor_obj);
-                       psb_intel_crtc->cursor_obj = NULL;
-               }
-
-               return 0;
-       }
-
-       /* Currently we only support 64x64 cursors */
-       if (width != 64 || height != 64) {
-               dev_dbg(dev->dev, "we currently only support 64x64 cursors\n");
-               return -EINVAL;
-       }
-
-       obj = drm_gem_object_lookup(dev, file_priv, handle);
-       if (!obj)
-               return -ENOENT;
-
-       if (obj->size < width * height * 4) {
-               dev_dbg(dev->dev, "buffer is to small\n");
-               return -ENOMEM;
-       }
-
-       gt = container_of(obj, struct gtt_range, gem);
-
-       /* Pin the memory into the GTT */
-       ret = psb_gtt_pin(gt);
-       if (ret) {
-               dev_err(dev->dev, "Can not pin down handle 0x%x\n", handle);
-               return ret;
-       }
-
-       addr = gt->offset;      /* Or resource.start ??? */
-
-       psb_intel_crtc->cursor_addr = addr;
-
-       temp = 0;
-       /* set the pipe for the cursor */
-       temp |= (pipe << 28);
-       temp |= CURSOR_MODE_64_ARGB_AX | MCURSOR_GAMMA_ENABLE;
-
-       if (gma_power_begin(dev, false)) {
-               REG_WRITE(control, temp);
-               REG_WRITE(base, addr);
-               gma_power_end(dev);
-       }
-
-       /* unpin the old GEM object */
-       if (psb_intel_crtc->cursor_obj) {
-               gt = container_of(psb_intel_crtc->cursor_obj,
-                                                       struct gtt_range, gem);
-               psb_gtt_unpin(gt);
-               drm_gem_object_unreference(psb_intel_crtc->cursor_obj);
-               psb_intel_crtc->cursor_obj = obj;
-       }
-       return 0;
-}
-
-static int cdv_intel_crtc_cursor_move(struct drm_crtc *crtc, int x, int y)
-{
-       struct drm_device *dev = crtc->dev;
-       struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
-       int pipe = psb_intel_crtc->pipe;
-       uint32_t temp = 0;
-       uint32_t adder;
-
-
-       if (x < 0) {
-               temp |= (CURSOR_POS_SIGN << CURSOR_X_SHIFT);
-               x = -x;
-       }
-       if (y < 0) {
-               temp |= (CURSOR_POS_SIGN << CURSOR_Y_SHIFT);
-               y = -y;
-       }
-
-       temp |= ((x & CURSOR_POS_MASK) << CURSOR_X_SHIFT);
-       temp |= ((y & CURSOR_POS_MASK) << CURSOR_Y_SHIFT);
-
-       adder = psb_intel_crtc->cursor_addr;
-
-       if (gma_power_begin(dev, false)) {
-               REG_WRITE((pipe == 0) ? CURAPOS : CURBPOS, temp);
-               REG_WRITE((pipe == 0) ? CURABASE : CURBBASE, adder);
-               gma_power_end(dev);
-       }
-       return 0;
-}
-
-static void cdv_intel_crtc_gamma_set(struct drm_crtc *crtc, u16 *red,
-                        u16 *green, u16 *blue, uint32_t start, uint32_t size)
-{
-       struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
-       int i;
-       int end = (start + size > 256) ? 256 : start + size;
-
-       for (i = start; i < end; i++) {
-               psb_intel_crtc->lut_r[i] = red[i] >> 8;
-               psb_intel_crtc->lut_g[i] = green[i] >> 8;
-               psb_intel_crtc->lut_b[i] = blue[i] >> 8;
-       }
-
-       cdv_intel_crtc_load_lut(crtc);
-}
-
-static int cdv_crtc_set_config(struct drm_mode_set *set)
-{
-       int ret = 0;
-       struct drm_device *dev = set->crtc->dev;
-       struct drm_psb_private *dev_priv = dev->dev_private;
-
-       if (!dev_priv->rpm_enabled)
-               return drm_crtc_helper_set_config(set);
-
-       pm_runtime_forbid(&dev->pdev->dev);
-
-       ret = drm_crtc_helper_set_config(set);
-
-       pm_runtime_allow(&dev->pdev->dev);
-
-       return ret;
-}
-
-/** Derive the pixel clock for the given refclk and divisors for 8xx chips. */
-
-/* FIXME: why are we using this, should it be cdv_ in this tree ? */
-
-static void i8xx_clock(int refclk, struct cdv_intel_clock_t *clock)
-{
-       clock->m = 5 * (clock->m1 + 2) + (clock->m2 + 2);
-       clock->p = clock->p1 * clock->p2;
-       clock->vco = refclk * clock->m / (clock->n + 2);
-       clock->dot = clock->vco / clock->p;
-}
-
-/* Returns the clock of the currently programmed mode of the given pipe. */
-static int cdv_intel_crtc_clock_get(struct drm_device *dev,
-                               struct drm_crtc *crtc)
-{
-       struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
-       int pipe = psb_intel_crtc->pipe;
-       u32 dpll;
-       u32 fp;
-       struct cdv_intel_clock_t clock;
-       bool is_lvds;
-       struct drm_psb_private *dev_priv = dev->dev_private;
-
-       if (gma_power_begin(dev, false)) {
-               dpll = REG_READ((pipe == 0) ? DPLL_A : DPLL_B);
-               if ((dpll & DISPLAY_RATE_SELECT_FPA1) == 0)
-                       fp = REG_READ((pipe == 0) ? FPA0 : FPB0);
-               else
-                       fp = REG_READ((pipe == 0) ? FPA1 : FPB1);
-               is_lvds = (pipe == 1) && (REG_READ(LVDS) & LVDS_PORT_EN);
-               gma_power_end(dev);
-       } else {
-               dpll = (pipe == 0) ?
-                       dev_priv->saveDPLL_A : dev_priv->saveDPLL_B;
-
-               if ((dpll & DISPLAY_RATE_SELECT_FPA1) == 0)
-                       fp = (pipe == 0) ?
-                               dev_priv->saveFPA0 :
-                               dev_priv->saveFPB0;
-               else
-                       fp = (pipe == 0) ?
-                               dev_priv->saveFPA1 :
-                               dev_priv->saveFPB1;
-
-               is_lvds = (pipe == 1) && (dev_priv->saveLVDS & LVDS_PORT_EN);
-       }
-
-       clock.m1 = (fp & FP_M1_DIV_MASK) >> FP_M1_DIV_SHIFT;
-       clock.m2 = (fp & FP_M2_DIV_MASK) >> FP_M2_DIV_SHIFT;
-       clock.n = (fp & FP_N_DIV_MASK) >> FP_N_DIV_SHIFT;
-
-       if (is_lvds) {
-               clock.p1 =
-                   ffs((dpll &
-                        DPLL_FPA01_P1_POST_DIV_MASK_I830_LVDS) >>
-                       DPLL_FPA01_P1_POST_DIV_SHIFT);
-               if (clock.p1 == 0) {
-                       clock.p1 = 4;
-                       dev_err(dev->dev, "PLL %d\n", dpll);
-               }
-               clock.p2 = 14;
-
-               if ((dpll & PLL_REF_INPUT_MASK) ==
-                   PLLB_REF_INPUT_SPREADSPECTRUMIN) {
-                       /* XXX: might not be 66MHz */
-                       i8xx_clock(66000, &clock);
-               } else
-                       i8xx_clock(48000, &clock);
-       } else {
-               if (dpll & PLL_P1_DIVIDE_BY_TWO)
-                       clock.p1 = 2;
-               else {
-                       clock.p1 =
-                           ((dpll &
-                             DPLL_FPA01_P1_POST_DIV_MASK_I830) >>
-                            DPLL_FPA01_P1_POST_DIV_SHIFT) + 2;
-               }
-               if (dpll & PLL_P2_DIVIDE_BY_4)
-                       clock.p2 = 4;
-               else
-                       clock.p2 = 2;
-
-               i8xx_clock(48000, &clock);
-       }
-
-       /* XXX: It would be nice to validate the clocks, but we can't reuse
-        * i830PllIsValid() because it relies on the xf86_config connector
-        * configuration being accurate, which it isn't necessarily.
-        */
-
-       return clock.dot;
-}
-
-/** Returns the currently programmed mode of the given pipe. */
-struct drm_display_mode *cdv_intel_crtc_mode_get(struct drm_device *dev,
-                                            struct drm_crtc *crtc)
-{
-       struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
-       int pipe = psb_intel_crtc->pipe;
-       struct drm_display_mode *mode;
-       int htot;
-       int hsync;
-       int vtot;
-       int vsync;
-       struct drm_psb_private *dev_priv = dev->dev_private;
-
-       if (gma_power_begin(dev, false)) {
-               htot = REG_READ((pipe == 0) ? HTOTAL_A : HTOTAL_B);
-               hsync = REG_READ((pipe == 0) ? HSYNC_A : HSYNC_B);
-               vtot = REG_READ((pipe == 0) ? VTOTAL_A : VTOTAL_B);
-               vsync = REG_READ((pipe == 0) ? VSYNC_A : VSYNC_B);
-               gma_power_end(dev);
-       } else {
-               htot = (pipe == 0) ?
-                       dev_priv->saveHTOTAL_A : dev_priv->saveHTOTAL_B;
-               hsync = (pipe == 0) ?
-                       dev_priv->saveHSYNC_A : dev_priv->saveHSYNC_B;
-               vtot = (pipe == 0) ?
-                       dev_priv->saveVTOTAL_A : dev_priv->saveVTOTAL_B;
-               vsync = (pipe == 0) ?
-                       dev_priv->saveVSYNC_A : dev_priv->saveVSYNC_B;
-       }
-
-       mode = kzalloc(sizeof(*mode), GFP_KERNEL);
-       if (!mode)
-               return NULL;
-
-       mode->clock = cdv_intel_crtc_clock_get(dev, crtc);
-       mode->hdisplay = (htot & 0xffff) + 1;
-       mode->htotal = ((htot & 0xffff0000) >> 16) + 1;
-       mode->hsync_start = (hsync & 0xffff) + 1;
-       mode->hsync_end = ((hsync & 0xffff0000) >> 16) + 1;
-       mode->vdisplay = (vtot & 0xffff) + 1;
-       mode->vtotal = ((vtot & 0xffff0000) >> 16) + 1;
-       mode->vsync_start = (vsync & 0xffff) + 1;
-       mode->vsync_end = ((vsync & 0xffff0000) >> 16) + 1;
-
-       drm_mode_set_name(mode);
-       drm_mode_set_crtcinfo(mode, 0);
-
-       return mode;
-}
-
-static void cdv_intel_crtc_destroy(struct drm_crtc *crtc)
-{
-       struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
-
-       kfree(psb_intel_crtc->crtc_state);
-       drm_crtc_cleanup(crtc);
-       kfree(psb_intel_crtc);
-}
-
-const struct drm_crtc_helper_funcs cdv_intel_helper_funcs = {
-       .dpms = cdv_intel_crtc_dpms,
-       .mode_fixup = cdv_intel_crtc_mode_fixup,
-       .mode_set = cdv_intel_crtc_mode_set,
-       .mode_set_base = cdv_intel_pipe_set_base,
-       .prepare = cdv_intel_crtc_prepare,
-       .commit = cdv_intel_crtc_commit,
-};
-
-const struct drm_crtc_funcs cdv_intel_crtc_funcs = {
-       .save = cdv_intel_crtc_save,
-       .restore = cdv_intel_crtc_restore,
-       .cursor_set = cdv_intel_crtc_cursor_set,
-       .cursor_move = cdv_intel_crtc_cursor_move,
-       .gamma_set = cdv_intel_crtc_gamma_set,
-       .set_config = cdv_crtc_set_config,
-       .destroy = cdv_intel_crtc_destroy,
-};
-
-/*
- * Set the default value of cursor control and base register
- * to zero. This is a workaround for h/w defect on oaktrail
- */
-void cdv_intel_cursor_init(struct drm_device *dev, int pipe)
-{
-       uint32_t control;
-       uint32_t base;
-
-       switch (pipe) {
-       case 0:
-               control = CURACNTR;
-               base = CURABASE;
-               break;
-       case 1:
-               control = CURBCNTR;
-               base = CURBBASE;
-               break;
-       case 2:
-               control = CURCCNTR;
-               base = CURCBASE;
-               break;
-       default:
-               return;
-       }
-
-       REG_WRITE(control, 0);
-       REG_WRITE(base, 0);
-}
-
diff --git a/drivers/staging/gma500/cdv_intel_hdmi.c b/drivers/staging/gma500/cdv_intel_hdmi.c
deleted file mode 100644 (file)
index cbca2b0..0000000
+++ /dev/null
@@ -1,376 +0,0 @@
-/*
- * Copyright Â© 2006-2011 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Authors:
- *     jim liu <jim.liu@intel.com>
- *
- * FIXME:
- *     We should probably make this generic and share it with Medfield
- */
-
-#include <drm/drmP.h>
-#include <drm/drm.h>
-#include <drm/drm_crtc.h>
-#include <drm/drm_edid.h>
-#include "psb_intel_drv.h"
-#include "psb_drv.h"
-#include "psb_intel_reg.h"
-#include <linux/pm_runtime.h>
-
-/* hdmi control bits */
-#define HDMI_NULL_PACKETS_DURING_VSYNC (1 << 9)
-#define HDMI_BORDER_ENABLE             (1 << 7)
-#define HDMI_AUDIO_ENABLE              (1 << 6)
-#define HDMI_VSYNC_ACTIVE_HIGH         (1 << 4)
-#define HDMI_HSYNC_ACTIVE_HIGH         (1 << 3)
-/* hdmi-b control bits */
-#define        HDMIB_PIPE_B_SELECT             (1 << 30)
-
-
-struct mid_intel_hdmi_priv {
-       u32 hdmi_reg;
-       u32 save_HDMIB;
-       bool has_hdmi_sink;
-       bool has_hdmi_audio;
-       /* Should set this when detect hotplug */
-       bool hdmi_device_connected;
-       struct mdfld_hdmi_i2c *i2c_bus;
-       struct i2c_adapter *hdmi_i2c_adapter;   /* for control functions */
-       struct drm_device *dev;
-};
-
-static void cdv_hdmi_mode_set(struct drm_encoder *encoder,
-                       struct drm_display_mode *mode,
-                       struct drm_display_mode *adjusted_mode)
-{
-       struct drm_device *dev = encoder->dev;
-       struct psb_intel_output *output = enc_to_psb_intel_output(encoder);
-       struct mid_intel_hdmi_priv *hdmi_priv = output->dev_priv;
-       u32 hdmib;
-       struct drm_crtc *crtc = encoder->crtc;
-       struct psb_intel_crtc *intel_crtc = to_psb_intel_crtc(crtc);
-
-       hdmib = (2 << 10);
-
-       if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC)
-               hdmib |= HDMI_VSYNC_ACTIVE_HIGH;
-       if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC)
-               hdmib |= HDMI_HSYNC_ACTIVE_HIGH;
-
-       if (intel_crtc->pipe == 1)
-               hdmib |= HDMIB_PIPE_B_SELECT;
-
-       if (hdmi_priv->has_hdmi_audio) {
-               hdmib |= HDMI_AUDIO_ENABLE;
-               hdmib |= HDMI_NULL_PACKETS_DURING_VSYNC;
-       }
-
-       REG_WRITE(hdmi_priv->hdmi_reg, hdmib);
-       REG_READ(hdmi_priv->hdmi_reg);
-}
-
-static bool cdv_hdmi_mode_fixup(struct drm_encoder *encoder,
-                                 struct drm_display_mode *mode,
-                                 struct drm_display_mode *adjusted_mode)
-{
-       return true;
-}
-
-static void cdv_hdmi_dpms(struct drm_encoder *encoder, int mode)
-{
-       struct drm_device *dev = encoder->dev;
-       struct psb_intel_output *output = enc_to_psb_intel_output(encoder);
-       struct mid_intel_hdmi_priv *hdmi_priv = output->dev_priv;
-       u32 hdmib;
-
-       hdmib = REG_READ(hdmi_priv->hdmi_reg);
-
-       if (mode != DRM_MODE_DPMS_ON)
-               REG_WRITE(hdmi_priv->hdmi_reg, hdmib & ~HDMIB_PORT_EN);
-       else
-               REG_WRITE(hdmi_priv->hdmi_reg, hdmib | HDMIB_PORT_EN);
-       REG_READ(hdmi_priv->hdmi_reg);
-}
-
-static void cdv_hdmi_save(struct drm_connector *connector)
-{
-       struct drm_device *dev = connector->dev;
-       struct psb_intel_output *output = to_psb_intel_output(connector);
-       struct mid_intel_hdmi_priv *hdmi_priv = output->dev_priv;
-
-       hdmi_priv->save_HDMIB = REG_READ(hdmi_priv->hdmi_reg);
-}
-
-static void cdv_hdmi_restore(struct drm_connector *connector)
-{
-       struct drm_device *dev = connector->dev;
-       struct psb_intel_output *output = to_psb_intel_output(connector);
-       struct mid_intel_hdmi_priv *hdmi_priv = output->dev_priv;
-
-       REG_WRITE(hdmi_priv->hdmi_reg, hdmi_priv->save_HDMIB);
-       REG_READ(hdmi_priv->hdmi_reg);
-}
-
-static enum drm_connector_status cdv_hdmi_detect(
-                               struct drm_connector *connector, bool force)
-{
-       struct psb_intel_output *psb_intel_output =
-                                               to_psb_intel_output(connector);
-       struct mid_intel_hdmi_priv *hdmi_priv = psb_intel_output->dev_priv;
-       struct edid *edid = NULL;
-       enum drm_connector_status status = connector_status_disconnected;
-
-       edid = drm_get_edid(&psb_intel_output->base,
-                        psb_intel_output->hdmi_i2c_adapter);
-
-       hdmi_priv->has_hdmi_sink = false;
-       hdmi_priv->has_hdmi_audio = false;
-       if (edid) {
-               if (edid->input & DRM_EDID_INPUT_DIGITAL) {
-                       status = connector_status_connected;
-                       hdmi_priv->has_hdmi_sink =
-                                               drm_detect_hdmi_monitor(edid);
-                       hdmi_priv->has_hdmi_audio =
-                                               drm_detect_monitor_audio(edid);
-               }
-
-               psb_intel_output->base.display_info.raw_edid = NULL;
-               kfree(edid);
-       }
-       return status;
-}
-
-static int cdv_hdmi_set_property(struct drm_connector *connector,
-                                      struct drm_property *property,
-                                      uint64_t value)
-{
-       struct drm_encoder *encoder = connector->encoder;
-
-       if (!strcmp(property->name, "scaling mode") && encoder) {
-               struct psb_intel_crtc *crtc = to_psb_intel_crtc(encoder->crtc);
-               bool centre;
-               uint64_t curValue;
-
-               if (!crtc)
-                       return -1;
-
-               switch (value) {
-               case DRM_MODE_SCALE_FULLSCREEN:
-                       break;
-               case DRM_MODE_SCALE_NO_SCALE:
-                       break;
-               case DRM_MODE_SCALE_ASPECT:
-                       break;
-               default:
-                       return -1;
-               }
-
-               if (drm_connector_property_get_value(connector,
-                                                       property, &curValue))
-                       return -1;
-
-               if (curValue == value)
-                       return 0;
-
-               if (drm_connector_property_set_value(connector,
-                                                       property, value))
-                       return -1;
-
-               centre = (curValue == DRM_MODE_SCALE_NO_SCALE) ||
-                       (value == DRM_MODE_SCALE_NO_SCALE);
-
-               if (crtc->saved_mode.hdisplay != 0 &&
-                   crtc->saved_mode.vdisplay != 0) {
-                       if (centre) {
-                               if (!drm_crtc_helper_set_mode(encoder->crtc, &crtc->saved_mode,
-                                           encoder->crtc->x, encoder->crtc->y, encoder->crtc->fb))
-                                       return -1;
-                       } else {
-                               struct drm_encoder_helper_funcs *helpers
-                                                   = encoder->helper_private;
-                               helpers->mode_set(encoder, &crtc->saved_mode,
-                                            &crtc->saved_adjusted_mode);
-                       }
-               }
-       }
-       return 0;
-}
-
-/*
- * Return the list of HDMI DDC modes if available.
- */
-static int cdv_hdmi_get_modes(struct drm_connector *connector)
-{
-       struct psb_intel_output *psb_intel_output =
-                                       to_psb_intel_output(connector);
-       struct edid *edid = NULL;
-       int ret = 0;
-
-       edid = drm_get_edid(&psb_intel_output->base,
-                        psb_intel_output->hdmi_i2c_adapter);
-       if (edid) {
-               drm_mode_connector_update_edid_property(&psb_intel_output->
-                                                       base, edid);
-               ret = drm_add_edid_modes(&psb_intel_output->base, edid);
-               kfree(edid);
-       }
-       return ret;
-}
-
-static int cdv_hdmi_mode_valid(struct drm_connector *connector,
-                                struct drm_display_mode *mode)
-{
-
-       if (mode->clock > 165000)
-               return MODE_CLOCK_HIGH;
-       if (mode->clock < 20000)
-               return MODE_CLOCK_HIGH;
-
-       /* just in case */
-       if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
-               return MODE_NO_DBLESCAN;
-
-       /* just in case */
-       if (mode->flags & DRM_MODE_FLAG_INTERLACE)
-               return MODE_NO_INTERLACE;
-
-       /*
-        * FIXME: for now we limit the size to 1680x1050 on CDV, otherwise it
-        * will go beyond the stolen memory size allocated to the framebuffer
-        */
-       if (mode->hdisplay > 1680)
-               return MODE_PANEL;
-       if (mode->vdisplay > 1050)
-               return MODE_PANEL;
-       return MODE_OK;
-}
-
-static void cdv_hdmi_destroy(struct drm_connector *connector)
-{
-       struct psb_intel_output *psb_intel_output =
-                                       to_psb_intel_output(connector);
-
-       if (psb_intel_output->ddc_bus)
-               psb_intel_i2c_destroy(psb_intel_output->ddc_bus);
-       drm_sysfs_connector_remove(connector);
-       drm_connector_cleanup(connector);
-       kfree(connector);
-}
-
-static const struct drm_encoder_helper_funcs cdv_hdmi_helper_funcs = {
-       .dpms = cdv_hdmi_dpms,
-       .mode_fixup = cdv_hdmi_mode_fixup,
-       .prepare = psb_intel_encoder_prepare,
-       .mode_set = cdv_hdmi_mode_set,
-       .commit = psb_intel_encoder_commit,
-};
-
-static const struct drm_connector_helper_funcs
-                                       cdv_hdmi_connector_helper_funcs = {
-       .get_modes = cdv_hdmi_get_modes,
-       .mode_valid = cdv_hdmi_mode_valid,
-       .best_encoder = psb_intel_best_encoder,
-};
-
-static const struct drm_connector_funcs cdv_hdmi_connector_funcs = {
-       .dpms = drm_helper_connector_dpms,
-       .save = cdv_hdmi_save,
-       .restore = cdv_hdmi_restore,
-       .detect = cdv_hdmi_detect,
-       .fill_modes = drm_helper_probe_single_connector_modes,
-       .set_property = cdv_hdmi_set_property,
-       .destroy = cdv_hdmi_destroy,
-};
-
-void cdv_hdmi_init(struct drm_device *dev,
-                       struct psb_intel_mode_device *mode_dev, int reg)
-{
-       struct psb_intel_output *psb_intel_output;
-       struct drm_connector *connector;
-       struct drm_encoder *encoder;
-       struct mid_intel_hdmi_priv *hdmi_priv;
-       int ddc_bus;
-
-       psb_intel_output = kzalloc(sizeof(struct psb_intel_output) +
-                              sizeof(struct mid_intel_hdmi_priv), GFP_KERNEL);
-       if (!psb_intel_output)
-               return;
-
-       hdmi_priv = (struct mid_intel_hdmi_priv *)(psb_intel_output + 1);
-       psb_intel_output->mode_dev = mode_dev;
-       connector = &psb_intel_output->base;
-       encoder = &psb_intel_output->enc;
-       drm_connector_init(dev, &psb_intel_output->base,
-                          &cdv_hdmi_connector_funcs,
-                          DRM_MODE_CONNECTOR_DVID);
-
-       drm_encoder_init(dev, &psb_intel_output->enc, &psb_intel_lvds_enc_funcs,
-                        DRM_MODE_ENCODER_TMDS);
-
-       drm_mode_connector_attach_encoder(&psb_intel_output->base,
-                                         &psb_intel_output->enc);
-       psb_intel_output->type = INTEL_OUTPUT_HDMI;
-       hdmi_priv->hdmi_reg = reg;
-       hdmi_priv->has_hdmi_sink = false;
-       psb_intel_output->dev_priv = hdmi_priv;
-
-       drm_encoder_helper_add(encoder, &cdv_hdmi_helper_funcs);
-       drm_connector_helper_add(connector,
-                                &cdv_hdmi_connector_helper_funcs);
-       connector->display_info.subpixel_order = SubPixelHorizontalRGB;
-       connector->interlace_allowed = false;
-       connector->doublescan_allowed = false;
-
-       drm_connector_attach_property(connector,
-           dev->mode_config.scaling_mode_property, DRM_MODE_SCALE_FULLSCREEN);
-
-       switch (reg) {
-       case SDVOB:
-               ddc_bus = GPIOE;
-               break;
-       case SDVOC:
-               ddc_bus = GPIOD;
-               break;
-       default:
-               DRM_ERROR("unknown reg 0x%x for HDMI\n", reg);
-               goto failed_ddc;
-               break;
-       }
-
-       psb_intel_output->ddc_bus = psb_intel_i2c_create(dev,
-                               ddc_bus, (reg == SDVOB) ? "HDMIB" : "HDMIC");
-
-       if (!psb_intel_output->ddc_bus) {
-               dev_err(dev->dev, "No ddc adapter available!\n");
-               goto failed_ddc;
-       }
-       psb_intel_output->hdmi_i2c_adapter =
-                               &(psb_intel_output->ddc_bus->adapter);
-       hdmi_priv->dev = dev;
-       drm_sysfs_connector_add(connector);
-       return;
-
-failed_ddc:
-       drm_encoder_cleanup(&psb_intel_output->enc);
-       drm_connector_cleanup(&psb_intel_output->base);
-       kfree(psb_intel_output);
-}
diff --git a/drivers/staging/gma500/cdv_intel_lvds.c b/drivers/staging/gma500/cdv_intel_lvds.c
deleted file mode 100644 (file)
index 988b2d0..0000000
+++ /dev/null
@@ -1,721 +0,0 @@
-/*
- * Copyright Â© 2006-2011 Intel Corporation
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Authors:
- *     Eric Anholt <eric@anholt.net>
- *     Dave Airlie <airlied@linux.ie>
- *     Jesse Barnes <jesse.barnes@intel.com>
- */
-
-#include <linux/i2c.h>
-#include <linux/dmi.h>
-#include <drm/drmP.h>
-
-#include "intel_bios.h"
-#include "psb_drv.h"
-#include "psb_intel_drv.h"
-#include "psb_intel_reg.h"
-#include "power.h"
-#include <linux/pm_runtime.h>
-#include "cdv_device.h"
-
-/**
- * LVDS I2C backlight control macros
- */
-#define BRIGHTNESS_MAX_LEVEL 100
-#define BRIGHTNESS_MASK 0xFF
-#define BLC_I2C_TYPE   0x01
-#define BLC_PWM_TYPT   0x02
-
-#define BLC_POLARITY_NORMAL 0
-#define BLC_POLARITY_INVERSE 1
-
-#define PSB_BLC_MAX_PWM_REG_FREQ       (0xFFFE)
-#define PSB_BLC_MIN_PWM_REG_FREQ       (0x2)
-#define PSB_BLC_PWM_PRECISION_FACTOR   (10)
-#define PSB_BACKLIGHT_PWM_CTL_SHIFT    (16)
-#define PSB_BACKLIGHT_PWM_POLARITY_BIT_CLEAR (0xFFFE)
-
-struct cdv_intel_lvds_priv {
-       /**
-        * Saved LVDO output states
-        */
-       uint32_t savePP_ON;
-       uint32_t savePP_OFF;
-       uint32_t saveLVDS;
-       uint32_t savePP_CONTROL;
-       uint32_t savePP_CYCLE;
-       uint32_t savePFIT_CONTROL;
-       uint32_t savePFIT_PGM_RATIOS;
-       uint32_t saveBLC_PWM_CTL;
-};
-
-/*
- * Returns the maximum level of the backlight duty cycle field.
- */
-static u32 cdv_intel_lvds_get_max_backlight(struct drm_device *dev)
-{
-       struct drm_psb_private *dev_priv = dev->dev_private;
-       u32 retval;
-
-       if (gma_power_begin(dev, false)) {
-               retval = ((REG_READ(BLC_PWM_CTL) &
-                         BACKLIGHT_MODULATION_FREQ_MASK) >>
-                         BACKLIGHT_MODULATION_FREQ_SHIFT) * 2;
-
-               gma_power_end(dev);
-       } else
-               retval = ((dev_priv->saveBLC_PWM_CTL &
-                         BACKLIGHT_MODULATION_FREQ_MASK) >>
-                         BACKLIGHT_MODULATION_FREQ_SHIFT) * 2;
-
-       return retval;
-}
-
-/*
- * Set LVDS backlight level by I2C command
- */
-static int cdv_lvds_i2c_set_brightness(struct drm_device *dev,
-                                       unsigned int level)
-{
-       struct drm_psb_private *dev_priv = dev->dev_private;
-       struct psb_intel_i2c_chan *lvds_i2c_bus = dev_priv->lvds_i2c_bus;
-       u8 out_buf[2];
-       unsigned int blc_i2c_brightness;
-
-       struct i2c_msg msgs[] = {
-               {
-                       .addr = lvds_i2c_bus->slave_addr,
-                       .flags = 0,
-                       .len = 2,
-                       .buf = out_buf,
-               }
-       };
-
-       blc_i2c_brightness = BRIGHTNESS_MASK & ((unsigned int)level *
-                            BRIGHTNESS_MASK /
-                            BRIGHTNESS_MAX_LEVEL);
-
-       if (dev_priv->lvds_bl->pol == BLC_POLARITY_INVERSE)
-               blc_i2c_brightness = BRIGHTNESS_MASK - blc_i2c_brightness;
-
-       out_buf[0] = dev_priv->lvds_bl->brightnesscmd;
-       out_buf[1] = (u8)blc_i2c_brightness;
-
-       if (i2c_transfer(&lvds_i2c_bus->adapter, msgs, 1) == 1)
-               return 0;
-
-       DRM_ERROR("I2C transfer error\n");
-       return -1;
-}
-
-
-static int cdv_lvds_pwm_set_brightness(struct drm_device *dev, int level)
-{
-       struct drm_psb_private *dev_priv = dev->dev_private;
-
-       u32 max_pwm_blc;
-       u32 blc_pwm_duty_cycle;
-
-       max_pwm_blc = cdv_intel_lvds_get_max_backlight(dev);
-
-       /*BLC_PWM_CTL Should be initiated while backlight device init*/
-       BUG_ON((max_pwm_blc & PSB_BLC_MAX_PWM_REG_FREQ) == 0);
-
-       blc_pwm_duty_cycle = level * max_pwm_blc / BRIGHTNESS_MAX_LEVEL;
-
-       if (dev_priv->lvds_bl->pol == BLC_POLARITY_INVERSE)
-               blc_pwm_duty_cycle = max_pwm_blc - blc_pwm_duty_cycle;
-
-       blc_pwm_duty_cycle &= PSB_BACKLIGHT_PWM_POLARITY_BIT_CLEAR;
-       REG_WRITE(BLC_PWM_CTL,
-                 (max_pwm_blc << PSB_BACKLIGHT_PWM_CTL_SHIFT) |
-                 (blc_pwm_duty_cycle));
-
-       return 0;
-}
-
-/*
- * Set LVDS backlight level either by I2C or PWM
- */
-void cdv_intel_lvds_set_brightness(struct drm_device *dev, int level)
-{
-       struct drm_psb_private *dev_priv = dev->dev_private;
-
-       if (!dev_priv->lvds_bl) {
-               DRM_ERROR("NO LVDS Backlight Info\n");
-               return;
-       }
-
-       if (dev_priv->lvds_bl->type == BLC_I2C_TYPE)
-               cdv_lvds_i2c_set_brightness(dev, level);
-       else
-               cdv_lvds_pwm_set_brightness(dev, level);
-}
-
-/**
- * Sets the backlight level.
- *
- * level backlight level, from 0 to cdv_intel_lvds_get_max_backlight().
- */
-static void cdv_intel_lvds_set_backlight(struct drm_device *dev, int level)
-{
-       struct drm_psb_private *dev_priv = dev->dev_private;
-       u32 blc_pwm_ctl;
-
-       if (gma_power_begin(dev, false)) {
-               blc_pwm_ctl =
-                       REG_READ(BLC_PWM_CTL) & ~BACKLIGHT_DUTY_CYCLE_MASK;
-               REG_WRITE(BLC_PWM_CTL,
-                               (blc_pwm_ctl |
-                               (level << BACKLIGHT_DUTY_CYCLE_SHIFT)));
-               gma_power_end(dev);
-       } else {
-               blc_pwm_ctl = dev_priv->saveBLC_PWM_CTL &
-                               ~BACKLIGHT_DUTY_CYCLE_MASK;
-               dev_priv->saveBLC_PWM_CTL = (blc_pwm_ctl |
-                                       (level << BACKLIGHT_DUTY_CYCLE_SHIFT));
-       }
-}
-
-/**
- * Sets the power state for the panel.
- */
-static void cdv_intel_lvds_set_power(struct drm_device *dev,
-                                struct psb_intel_output *output, bool on)
-{
-       u32 pp_status;
-
-       if (!gma_power_begin(dev, true))
-               return;
-
-       if (on) {
-               REG_WRITE(PP_CONTROL, REG_READ(PP_CONTROL) |
-                         POWER_TARGET_ON);
-               do {
-                       pp_status = REG_READ(PP_STATUS);
-               } while ((pp_status & PP_ON) == 0);
-
-               cdv_intel_lvds_set_backlight(dev,
-                                        output->
-                                        mode_dev->backlight_duty_cycle);
-       } else {
-               cdv_intel_lvds_set_backlight(dev, 0);
-
-               REG_WRITE(PP_CONTROL, REG_READ(PP_CONTROL) &
-                         ~POWER_TARGET_ON);
-               do {
-                       pp_status = REG_READ(PP_STATUS);
-               } while (pp_status & PP_ON);
-       }
-       gma_power_end(dev);
-}
-
-static void cdv_intel_lvds_encoder_dpms(struct drm_encoder *encoder, int mode)
-{
-       struct drm_device *dev = encoder->dev;
-       struct psb_intel_output *output = enc_to_psb_intel_output(encoder);
-       if (mode == DRM_MODE_DPMS_ON)
-               cdv_intel_lvds_set_power(dev, output, true);
-       else
-               cdv_intel_lvds_set_power(dev, output, false);
-       /* XXX: We never power down the LVDS pairs. */
-}
-
-static void cdv_intel_lvds_save(struct drm_connector *connector)
-{
-}
-
-static void cdv_intel_lvds_restore(struct drm_connector *connector)
-{
-}
-
-int cdv_intel_lvds_mode_valid(struct drm_connector *connector,
-                                struct drm_display_mode *mode)
-{
-       struct psb_intel_output *psb_intel_output =
-                               to_psb_intel_output(connector);
-       struct drm_display_mode *fixed_mode =
-           psb_intel_output->mode_dev->panel_fixed_mode;
-
-       /* just in case */
-       if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
-               return MODE_NO_DBLESCAN;
-
-       /* just in case */
-       if (mode->flags & DRM_MODE_FLAG_INTERLACE)
-               return MODE_NO_INTERLACE;
-
-       if (fixed_mode) {
-               if (mode->hdisplay > fixed_mode->hdisplay)
-                       return MODE_PANEL;
-               if (mode->vdisplay > fixed_mode->vdisplay)
-                       return MODE_PANEL;
-       }
-       return MODE_OK;
-}
-
-bool cdv_intel_lvds_mode_fixup(struct drm_encoder *encoder,
-                                 struct drm_display_mode *mode,
-                                 struct drm_display_mode *adjusted_mode)
-{
-       struct psb_intel_mode_device *mode_dev =
-           enc_to_psb_intel_output(encoder)->mode_dev;
-       struct drm_device *dev = encoder->dev;
-       struct drm_encoder *tmp_encoder;
-       struct drm_display_mode *panel_fixed_mode = mode_dev->panel_fixed_mode;
-
-       /* Should never happen!! */
-       list_for_each_entry(tmp_encoder, &dev->mode_config.encoder_list,
-                           head) {
-               if (tmp_encoder != encoder
-                   && tmp_encoder->crtc == encoder->crtc) {
-                       printk(KERN_ERR "Can't enable LVDS and another "
-                              "encoder on the same pipe\n");
-                       return false;
-               }
-       }
-
-       /*
-        * If we have timings from the BIOS for the panel, put them in
-        * to the adjusted mode.  The CRTC will be set up for this mode,
-        * with the panel scaling set up to source from the H/VDisplay
-        * of the original mode.
-        */
-       if (panel_fixed_mode != NULL) {
-               adjusted_mode->hdisplay = panel_fixed_mode->hdisplay;
-               adjusted_mode->hsync_start = panel_fixed_mode->hsync_start;
-               adjusted_mode->hsync_end = panel_fixed_mode->hsync_end;
-               adjusted_mode->htotal = panel_fixed_mode->htotal;
-               adjusted_mode->vdisplay = panel_fixed_mode->vdisplay;
-               adjusted_mode->vsync_start = panel_fixed_mode->vsync_start;
-               adjusted_mode->vsync_end = panel_fixed_mode->vsync_end;
-               adjusted_mode->vtotal = panel_fixed_mode->vtotal;
-               adjusted_mode->clock = panel_fixed_mode->clock;
-               drm_mode_set_crtcinfo(adjusted_mode,
-                                     CRTC_INTERLACE_HALVE_V);
-       }
-
-       /*
-        * XXX: It would be nice to support lower refresh rates on the
-        * panels to reduce power consumption, and perhaps match the
-        * user's requested refresh rate.
-        */
-
-       return true;
-}
-
-static void cdv_intel_lvds_prepare(struct drm_encoder *encoder)
-{
-       struct drm_device *dev = encoder->dev;
-       struct psb_intel_output *output = enc_to_psb_intel_output(encoder);
-       struct psb_intel_mode_device *mode_dev = output->mode_dev;
-
-       if (!gma_power_begin(dev, true))
-               return;
-
-       mode_dev->saveBLC_PWM_CTL = REG_READ(BLC_PWM_CTL);
-       mode_dev->backlight_duty_cycle = (mode_dev->saveBLC_PWM_CTL &
-                                         BACKLIGHT_DUTY_CYCLE_MASK);
-
-       cdv_intel_lvds_set_power(dev, output, false);
-
-       gma_power_end(dev);
-}
-
-static void cdv_intel_lvds_commit(struct drm_encoder *encoder)
-{
-       struct drm_device *dev = encoder->dev;
-       struct psb_intel_output *output = enc_to_psb_intel_output(encoder);
-       struct psb_intel_mode_device *mode_dev = output->mode_dev;
-
-       if (mode_dev->backlight_duty_cycle == 0)
-               mode_dev->backlight_duty_cycle =
-                   cdv_intel_lvds_get_max_backlight(dev);
-
-       cdv_intel_lvds_set_power(dev, output, true);
-}
-
-static void cdv_intel_lvds_mode_set(struct drm_encoder *encoder,
-                               struct drm_display_mode *mode,
-                               struct drm_display_mode *adjusted_mode)
-{
-       struct drm_device *dev = encoder->dev;
-       struct drm_psb_private *dev_priv = dev->dev_private;
-       u32 pfit_control;
-
-       /*
-        * The LVDS pin pair will already have been turned on in the
-        * cdv_intel_crtc_mode_set since it has a large impact on the DPLL
-        * settings.
-        */
-
-       /*
-        * Enable automatic panel scaling so that non-native modes fill the
-        * screen.  Should be enabled before the pipe is enabled, according to
-        * register description and PRM.
-        */
-       if (mode->hdisplay != adjusted_mode->hdisplay ||
-           mode->vdisplay != adjusted_mode->vdisplay)
-               pfit_control = (PFIT_ENABLE | VERT_AUTO_SCALE |
-                               HORIZ_AUTO_SCALE | VERT_INTERP_BILINEAR |
-                               HORIZ_INTERP_BILINEAR);
-       else
-               pfit_control = 0;
-
-       if (dev_priv->lvds_dither)
-               pfit_control |= PANEL_8TO6_DITHER_ENABLE;
-
-       REG_WRITE(PFIT_CONTROL, pfit_control);
-}
-
-/**
- * Detect the LVDS connection.
- *
- * This always returns CONNECTOR_STATUS_CONNECTED.
- * This connector should only have
- * been set up if the LVDS was actually connected anyway.
- */
-static enum drm_connector_status cdv_intel_lvds_detect(
-                               struct drm_connector *connector, bool force)
-{
-       return connector_status_connected;
-}
-
-/**
- * Return the list of DDC modes if available, or the BIOS fixed mode otherwise.
- */
-static int cdv_intel_lvds_get_modes(struct drm_connector *connector)
-{
-       struct drm_device *dev = connector->dev;
-       struct psb_intel_output *psb_intel_output =
-                                       to_psb_intel_output(connector);
-       struct psb_intel_mode_device *mode_dev =
-                                       psb_intel_output->mode_dev;
-       int ret;
-
-       ret = psb_intel_ddc_get_modes(psb_intel_output);
-
-       if (ret)
-               return ret;
-
-       /* Didn't get an EDID, so
-        * Set wide sync ranges so we get all modes
-        * handed to valid_mode for checking
-        */
-       connector->display_info.min_vfreq = 0;
-       connector->display_info.max_vfreq = 200;
-       connector->display_info.min_hfreq = 0;
-       connector->display_info.max_hfreq = 200;
-       if (mode_dev->panel_fixed_mode != NULL) {
-               struct drm_display_mode *mode =
-                   drm_mode_duplicate(dev, mode_dev->panel_fixed_mode);
-               drm_mode_probed_add(connector, mode);
-               return 1;
-       }
-
-       return 0;
-}
-
-/**
- * cdv_intel_lvds_destroy - unregister and free LVDS structures
- * @connector: connector to free
- *
- * Unregister the DDC bus for this connector then free the driver private
- * structure.
- */
-void cdv_intel_lvds_destroy(struct drm_connector *connector)
-{
-       struct psb_intel_output *psb_intel_output =
-                                       to_psb_intel_output(connector);
-
-       if (psb_intel_output->ddc_bus)
-               psb_intel_i2c_destroy(psb_intel_output->ddc_bus);
-       drm_sysfs_connector_remove(connector);
-       drm_connector_cleanup(connector);
-       kfree(connector);
-}
-
-int cdv_intel_lvds_set_property(struct drm_connector *connector,
-                                      struct drm_property *property,
-                                      uint64_t value)
-{
-       struct drm_encoder *encoder = connector->encoder;
-
-       if (!strcmp(property->name, "scaling mode") && encoder) {
-               struct psb_intel_crtc *crtc =
-                                       to_psb_intel_crtc(encoder->crtc);
-               uint64_t curValue;
-
-               if (!crtc)
-                       return -1;
-
-               switch (value) {
-               case DRM_MODE_SCALE_FULLSCREEN:
-                       break;
-               case DRM_MODE_SCALE_NO_SCALE:
-                       break;
-               case DRM_MODE_SCALE_ASPECT:
-                       break;
-               default:
-                       return -1;
-               }
-
-               if (drm_connector_property_get_value(connector,
-                                                    property,
-                                                    &curValue))
-                       return -1;
-
-               if (curValue == value)
-                       return 0;
-
-               if (drm_connector_property_set_value(connector,
-                                                       property,
-                                                       value))
-                       return -1;
-
-               if (crtc->saved_mode.hdisplay != 0 &&
-                   crtc->saved_mode.vdisplay != 0) {
-                       if (!drm_crtc_helper_set_mode(encoder->crtc,
-                                                     &crtc->saved_mode,
-                                                     encoder->crtc->x,
-                                                     encoder->crtc->y,
-                                                     encoder->crtc->fb))
-                               return -1;
-               }
-       } else if (!strcmp(property->name, "backlight") && encoder) {
-               if (drm_connector_property_set_value(connector,
-                                                       property,
-                                                       value))
-                       return -1;
-               else {
-#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
-                       struct drm_psb_private *dev_priv =
-                                               encoder->dev->dev_private;
-                       struct backlight_device *bd =
-                                               dev_priv->backlight_device;
-                       bd->props.brightness = value;
-                       backlight_update_status(bd);
-#endif
-               }
-       } else if (!strcmp(property->name, "DPMS") && encoder) {
-               struct drm_encoder_helper_funcs *helpers =
-                                       encoder->helper_private;
-               helpers->dpms(encoder, value);
-       }
-       return 0;
-}
-
-static const struct drm_encoder_helper_funcs
-                                       cdv_intel_lvds_helper_funcs = {
-       .dpms = cdv_intel_lvds_encoder_dpms,
-       .mode_fixup = cdv_intel_lvds_mode_fixup,
-       .prepare = cdv_intel_lvds_prepare,
-       .mode_set = cdv_intel_lvds_mode_set,
-       .commit = cdv_intel_lvds_commit,
-};
-
-static const struct drm_connector_helper_funcs
-                               cdv_intel_lvds_connector_helper_funcs = {
-       .get_modes = cdv_intel_lvds_get_modes,
-       .mode_valid = cdv_intel_lvds_mode_valid,
-       .best_encoder = psb_intel_best_encoder,
-};
-
-static const struct drm_connector_funcs cdv_intel_lvds_connector_funcs = {
-       .dpms = drm_helper_connector_dpms,
-       .save = cdv_intel_lvds_save,
-       .restore = cdv_intel_lvds_restore,
-       .detect = cdv_intel_lvds_detect,
-       .fill_modes = drm_helper_probe_single_connector_modes,
-       .set_property = cdv_intel_lvds_set_property,
-       .destroy = cdv_intel_lvds_destroy,
-};
-
-
-static void cdv_intel_lvds_enc_destroy(struct drm_encoder *encoder)
-{
-       drm_encoder_cleanup(encoder);
-}
-
-const struct drm_encoder_funcs cdv_intel_lvds_enc_funcs = {
-       .destroy = cdv_intel_lvds_enc_destroy,
-};
-
-/**
- * cdv_intel_lvds_init - setup LVDS connectors on this device
- * @dev: drm device
- *
- * Create the connector, register the LVDS DDC bus, and try to figure out what
- * modes we can display on the LVDS panel (if present).
- */
-void cdv_intel_lvds_init(struct drm_device *dev,
-                    struct psb_intel_mode_device *mode_dev)
-{
-       struct psb_intel_output *psb_intel_output;
-       struct cdv_intel_lvds_priv *lvds_priv;
-       struct drm_connector *connector;
-       struct drm_encoder *encoder;
-       struct drm_display_mode *scan;
-       struct drm_crtc *crtc;
-       struct drm_psb_private *dev_priv = dev->dev_private;
-       u32 lvds;
-       int pipe;
-
-       psb_intel_output = kzalloc(sizeof(struct psb_intel_output) +
-                       sizeof(struct cdv_intel_lvds_priv), GFP_KERNEL);
-       if (!psb_intel_output)
-               return;
-
-       lvds_priv = (struct cdv_intel_lvds_priv *)(psb_intel_output + 1);
-
-       psb_intel_output->dev_priv = lvds_priv;
-
-       psb_intel_output->mode_dev = mode_dev;
-       connector = &psb_intel_output->base;
-       encoder = &psb_intel_output->enc;
-
-
-       drm_connector_init(dev, &psb_intel_output->base,
-                          &cdv_intel_lvds_connector_funcs,
-                          DRM_MODE_CONNECTOR_LVDS);
-
-       drm_encoder_init(dev, &psb_intel_output->enc,
-                        &cdv_intel_lvds_enc_funcs,
-                        DRM_MODE_ENCODER_LVDS);
-
-
-       drm_mode_connector_attach_encoder(&psb_intel_output->base,
-                                         &psb_intel_output->enc);
-       psb_intel_output->type = INTEL_OUTPUT_LVDS;
-
-       drm_encoder_helper_add(encoder, &cdv_intel_lvds_helper_funcs);
-       drm_connector_helper_add(connector,
-                                &cdv_intel_lvds_connector_helper_funcs);
-       connector->display_info.subpixel_order = SubPixelHorizontalRGB;
-       connector->interlace_allowed = false;
-       connector->doublescan_allowed = false;
-
-       /*Attach connector properties*/
-       drm_connector_attach_property(connector,
-                                     dev->mode_config.scaling_mode_property,
-                                     DRM_MODE_SCALE_FULLSCREEN);
-       drm_connector_attach_property(connector,
-                                     dev_priv->backlight_property,
-                                     BRIGHTNESS_MAX_LEVEL);
-
-       /**
-        * Set up I2C bus
-        * FIXME: distroy i2c_bus when exit
-        */
-       psb_intel_output->i2c_bus = psb_intel_i2c_create(dev,
-                                                        GPIOB,
-                                                        "LVDSBLC_B");
-       if (!psb_intel_output->i2c_bus) {
-               dev_printk(KERN_ERR,
-                       &dev->pdev->dev, "I2C bus registration failed.\n");
-               goto failed_blc_i2c;
-       }
-       psb_intel_output->i2c_bus->slave_addr = 0x2C;
-       dev_priv->lvds_i2c_bus =  psb_intel_output->i2c_bus;
-
-       /*
-        * LVDS discovery:
-        * 1) check for EDID on DDC
-        * 2) check for VBT data
-        * 3) check to see if LVDS is already on
-        *    if none of the above, no panel
-        * 4) make sure lid is open
-        *    if closed, act like it's not there for now
-        */
-
-       /* Set up the DDC bus. */
-       psb_intel_output->ddc_bus = psb_intel_i2c_create(dev,
-                                                        GPIOC,
-                                                        "LVDSDDC_C");
-       if (!psb_intel_output->ddc_bus) {
-               dev_printk(KERN_ERR, &dev->pdev->dev,
-                          "DDC bus registration " "failed.\n");
-               goto failed_ddc;
-       }
-
-       /*
-        * Attempt to get the fixed panel mode from DDC.  Assume that the
-        * preferred mode is the right one.
-        */
-       psb_intel_ddc_get_modes(psb_intel_output);
-       list_for_each_entry(scan, &connector->probed_modes, head) {
-               if (scan->type & DRM_MODE_TYPE_PREFERRED) {
-                       mode_dev->panel_fixed_mode =
-                           drm_mode_duplicate(dev, scan);
-                       goto out;       /* FIXME: check for quirks */
-               }
-       }
-
-       /* Failed to get EDID, what about VBT? do we need this?*/
-       if (dev_priv->lfp_lvds_vbt_mode) {
-               mode_dev->panel_fixed_mode =
-                       drm_mode_duplicate(dev, dev_priv->lfp_lvds_vbt_mode);
-               if (mode_dev->panel_fixed_mode) {
-                       mode_dev->panel_fixed_mode->type |=
-                               DRM_MODE_TYPE_PREFERRED;
-                       goto out;       /* FIXME: check for quirks */
-               }
-       }
-       /*
-        * If we didn't get EDID, try checking if the panel is already turned
-        * on.  If so, assume that whatever is currently programmed is the
-        * correct mode.
-        */
-       lvds = REG_READ(LVDS);
-       pipe = (lvds & LVDS_PIPEB_SELECT) ? 1 : 0;
-       crtc = psb_intel_get_crtc_from_pipe(dev, pipe);
-
-       if (crtc && (lvds & LVDS_PORT_EN)) {
-               mode_dev->panel_fixed_mode =
-                   cdv_intel_crtc_mode_get(dev, crtc);
-               if (mode_dev->panel_fixed_mode) {
-                       mode_dev->panel_fixed_mode->type |=
-                           DRM_MODE_TYPE_PREFERRED;
-                       goto out;       /* FIXME: check for quirks */
-               }
-       }
-
-       /* If we still don't have a mode after all that, give up. */
-       if (!mode_dev->panel_fixed_mode) {
-               DRM_DEBUG
-                       ("Found no modes on the lvds, ignoring the LVDS\n");
-               goto failed_find;
-       }
-
-out:
-       drm_sysfs_connector_add(connector);
-       return;
-
-failed_find:
-       printk(KERN_ERR "Failed find\n");
-       if (psb_intel_output->ddc_bus)
-               psb_intel_i2c_destroy(psb_intel_output->ddc_bus);
-failed_ddc:
-       printk(KERN_ERR "Failed DDC\n");
-       if (psb_intel_output->i2c_bus)
-               psb_intel_i2c_destroy(psb_intel_output->i2c_bus);
-failed_blc_i2c:
-       printk(KERN_ERR "Failed BLC\n");
-       drm_encoder_cleanup(encoder);
-       drm_connector_cleanup(connector);
-       kfree(connector);
-}
diff --git a/drivers/staging/gma500/displays/hdmi.h b/drivers/staging/gma500/displays/hdmi.h
deleted file mode 100644 (file)
index d58ba9b..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (c)  2010 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Authors:
- * Thomas Eaton <thomas.g.eaton@intel.com>
- * Scott Rowe <scott.m.rowe@intel.com>
- */
-
-#ifndef HDMI_H
-#define HDMI_H
-
-extern void hdmi_init(struct drm_device *dev);
-
-#endif
diff --git a/drivers/staging/gma500/displays/pyr_cmd.h b/drivers/staging/gma500/displays/pyr_cmd.h
deleted file mode 100644 (file)
index 84bae5c..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (c)  2010 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicensen
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Authors:
- * Thomas Eaton <thomas.g.eaton@intel.com>
- * Scott Rowe <scott.m.rowe@intel.com>
- */
-
-#ifndef PYR_CMD_H
-#define PYR_CMD_H
-
-extern void pyr_cmd_init(struct drm_device *dev, struct panel_funcs *p_funcs);
-
-#endif
-
diff --git a/drivers/staging/gma500/displays/pyr_vid.h b/drivers/staging/gma500/displays/pyr_vid.h
deleted file mode 100644 (file)
index ce98860..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (c)  2010 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicensen
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Authors:
- * Thomas Eaton <thomas.g.eaton@intel.com>
- * Scott Rowe <scott.m.rowe@intel.com>
-*/
-
-#ifndef PYR_VID_H
-#define PYR_VID_H
-
-extern void pyr_vid_init(struct drm_device *dev, struct panel_funcs *p_funcs);
-extern struct drm_display_mode *pyr_vid_get_config_mode(struct drm_device* dev);
-
-#endif
diff --git a/drivers/staging/gma500/displays/tmd_cmd.h b/drivers/staging/gma500/displays/tmd_cmd.h
deleted file mode 100644 (file)
index 641e85e..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (c)  2010 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicensen
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Authors:
- * Thomas Eaton <thomas.g.eaton@intel.com>
- * Scott Rowe <scott.m.rowe@intel.com>
- */
-
-#ifndef TMD_CMD_H
-#define TMD_CMD_H
-
-extern void tmd_cmd_init(struct drm_device *dev, struct panel_funcs *p_funcs);
-extern struct drm_display_mode *tmd_cmd_get_config_mode(struct drm_device *dev);
-
-#endif
diff --git a/drivers/staging/gma500/displays/tmd_vid.h b/drivers/staging/gma500/displays/tmd_vid.h
deleted file mode 100644 (file)
index 7a5fa3b..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (c)  2010 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicensen
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Authors:
- * Thomas Eaton <thomas.g.eaton@intel.com>
- * Scott Rowe <scott.m.rowe@intel.com>
-*/
-
-#ifndef TMD_VID_H
-#define TMD_VID_H
-
-extern void tmd_vid_init(struct drm_device *dev, struct panel_funcs *p_funcs);
-extern struct drm_display_mode *tmd_vid_get_config_mode(struct drm_device *dev);
-
-#endif
diff --git a/drivers/staging/gma500/displays/tpo_cmd.h b/drivers/staging/gma500/displays/tpo_cmd.h
deleted file mode 100644 (file)
index 6105527..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (c)  2010 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicensen
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Authors:
- * Thomas Eaton <thomas.g.eaton@intel.com>
- * Scott Rowe <scott.m.rowe@intel.com>
-*/
-
-#ifndef TPO_CMD_H
-#define TPO_CMD_H
-
-extern void tpo_cmd_init(struct drm_device *dev, struct panel_funcs *p_funcs);
-/* extern struct drm_display_mode * */
-/* tpo_cmd_get_config_mode(struct drm_device *dev); */
-
-#endif
diff --git a/drivers/staging/gma500/displays/tpo_vid.h b/drivers/staging/gma500/displays/tpo_vid.h
deleted file mode 100644 (file)
index c24f057..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (c)  2010 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicensen
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Authors:
- * Thomas Eaton <thomas.g.eaton@intel.com>
- * Scott Rowe <scott.m.rowe@intel.com>
- */
-
-#ifndef TPO_VID_H
-#define TPO_VID_H
-
-extern void tpo_vid_init(struct drm_device *dev, struct panel_funcs *p_funcs);
-
-#endif
diff --git a/drivers/staging/gma500/framebuffer.c b/drivers/staging/gma500/framebuffer.c
deleted file mode 100644 (file)
index b00761c..0000000
+++ /dev/null
@@ -1,856 +0,0 @@
-/**************************************************************************
- * Copyright (c) 2007-2011, Intel Corporation.
- * All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- **************************************************************************/
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/string.h>
-#include <linux/mm.h>
-#include <linux/tty.h>
-#include <linux/slab.h>
-#include <linux/delay.h>
-#include <linux/fb.h>
-#include <linux/init.h>
-#include <linux/console.h>
-
-#include <drm/drmP.h>
-#include <drm/drm.h>
-#include <drm/drm_crtc.h>
-#include <drm/drm_fb_helper.h>
-
-#include "psb_drv.h"
-#include "psb_intel_reg.h"
-#include "psb_intel_drv.h"
-#include "framebuffer.h"
-#include "gtt.h"
-
-#include "mdfld_output.h"
-
-static void psb_user_framebuffer_destroy(struct drm_framebuffer *fb);
-static int psb_user_framebuffer_create_handle(struct drm_framebuffer *fb,
-                                             struct drm_file *file_priv,
-                                             unsigned int *handle);
-
-static const struct drm_framebuffer_funcs psb_fb_funcs = {
-       .destroy = psb_user_framebuffer_destroy,
-       .create_handle = psb_user_framebuffer_create_handle,
-};
-
-#define CMAP_TOHW(_val, _width) ((((_val) << (_width)) + 0x7FFF - (_val)) >> 16)
-
-static int psbfb_setcolreg(unsigned regno, unsigned red, unsigned green,
-                          unsigned blue, unsigned transp,
-                          struct fb_info *info)
-{
-       struct psb_fbdev *fbdev = info->par;
-       struct drm_framebuffer *fb = fbdev->psb_fb_helper.fb;
-       uint32_t v;
-
-       if (!fb)
-               return -ENOMEM;
-
-       if (regno > 255)
-               return 1;
-
-       red = CMAP_TOHW(red, info->var.red.length);
-       blue = CMAP_TOHW(blue, info->var.blue.length);
-       green = CMAP_TOHW(green, info->var.green.length);
-       transp = CMAP_TOHW(transp, info->var.transp.length);
-
-       v = (red << info->var.red.offset) |
-           (green << info->var.green.offset) |
-           (blue << info->var.blue.offset) |
-           (transp << info->var.transp.offset);
-
-       if (regno < 16) {
-               switch (fb->bits_per_pixel) {
-               case 16:
-                       ((uint32_t *) info->pseudo_palette)[regno] = v;
-                       break;
-               case 24:
-               case 32:
-                       ((uint32_t *) info->pseudo_palette)[regno] = v;
-                       break;
-               }
-       }
-
-       return 0;
-}
-
-static int psbfb_pan(struct fb_var_screeninfo *var, struct fb_info *info)
-{
-       struct psb_fbdev *fbdev = info->par;
-       struct psb_framebuffer *psbfb = &fbdev->pfb;
-       struct drm_device *dev = psbfb->base.dev;
-
-       /*
-        *      We have to poke our nose in here. The core fb code assumes
-        *      panning is part of the hardware that can be invoked before
-        *      the actual fb is mapped. In our case that isn't quite true.
-        */
-       if (psbfb->gtt->npage)
-               psb_gtt_roll(dev, psbfb->gtt, var->yoffset);
-       return 0;
-}
-
-void psbfb_suspend(struct drm_device *dev)
-{
-       struct drm_framebuffer *fb = 0;
-       struct psb_framebuffer *psbfb = to_psb_fb(fb);
-
-       console_lock();
-       mutex_lock(&dev->mode_config.mutex);
-       list_for_each_entry(fb, &dev->mode_config.fb_list, head) {
-               struct fb_info *info = psbfb->fbdev;
-               fb_set_suspend(info, 1);
-               drm_fb_helper_blank(FB_BLANK_POWERDOWN, info);
-       }
-       mutex_unlock(&dev->mode_config.mutex);
-       console_unlock();
-}
-
-void psbfb_resume(struct drm_device *dev)
-{
-       struct drm_framebuffer *fb = 0;
-       struct psb_framebuffer *psbfb = to_psb_fb(fb);
-
-       console_lock();
-       mutex_lock(&dev->mode_config.mutex);
-       list_for_each_entry(fb, &dev->mode_config.fb_list, head) {
-               struct fb_info *info = psbfb->fbdev;
-               fb_set_suspend(info, 0);
-               drm_fb_helper_blank(FB_BLANK_UNBLANK, info);
-       }
-       mutex_unlock(&dev->mode_config.mutex);
-       console_unlock();
-       drm_helper_disable_unused_functions(dev);
-}
-
-static int psbfb_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
-{
-       struct psb_framebuffer *psbfb = vma->vm_private_data;
-       struct drm_device *dev = psbfb->base.dev;
-       struct drm_psb_private *dev_priv = dev->dev_private;
-       int page_num;
-       int i;
-       unsigned long address;
-       int ret;
-       unsigned long pfn;
-       /* FIXME: assumes fb at stolen base which may not be true */
-       unsigned long phys_addr = (unsigned long)dev_priv->stolen_base;
-
-       page_num = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT;
-       address = (unsigned long)vmf->virtual_address;
-
-       vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
-
-       for (i = 0; i < page_num; i++) {
-               pfn = (phys_addr >> PAGE_SHIFT);
-
-               ret = vm_insert_mixed(vma, address, pfn);
-               if (unlikely((ret == -EBUSY) || (ret != 0 && i > 0)))
-                       break;
-               else if (unlikely(ret != 0)) {
-                       ret = (ret == -ENOMEM) ? VM_FAULT_OOM : VM_FAULT_SIGBUS;
-                       return ret;
-               }
-               address += PAGE_SIZE;
-               phys_addr += PAGE_SIZE;
-       }
-       return VM_FAULT_NOPAGE;
-}
-
-static void psbfb_vm_open(struct vm_area_struct *vma)
-{
-}
-
-static void psbfb_vm_close(struct vm_area_struct *vma)
-{
-}
-
-static struct vm_operations_struct psbfb_vm_ops = {
-       .fault  = psbfb_vm_fault,
-       .open   = psbfb_vm_open,
-       .close  = psbfb_vm_close
-};
-
-static int psbfb_mmap(struct fb_info *info, struct vm_area_struct *vma)
-{
-       struct psb_fbdev *fbdev = info->par;
-       struct psb_framebuffer *psbfb = &fbdev->pfb;
-
-       if (vma->vm_pgoff != 0)
-               return -EINVAL;
-       if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT))
-               return -EINVAL;
-
-       if (!psbfb->addr_space)
-               psbfb->addr_space = vma->vm_file->f_mapping;
-       /*
-        * If this is a GEM object then info->screen_base is the virtual
-        * kernel remapping of the object. FIXME: Review if this is
-        * suitable for our mmap work
-        */
-       vma->vm_ops = &psbfb_vm_ops;
-       vma->vm_private_data = (void *)psbfb;
-       vma->vm_flags |= VM_RESERVED | VM_IO |
-                                       VM_MIXEDMAP | VM_DONTEXPAND;
-       return 0;
-}
-
-static int psbfb_ioctl(struct fb_info *info, unsigned int cmd,
-                                               unsigned long arg)
-{
-       return -ENOTTY;
-}
-
-static struct fb_ops psbfb_ops = {
-       .owner = THIS_MODULE,
-       .fb_check_var = drm_fb_helper_check_var,
-       .fb_set_par = drm_fb_helper_set_par,
-       .fb_blank = drm_fb_helper_blank,
-       .fb_setcolreg = psbfb_setcolreg,
-       .fb_fillrect = cfb_fillrect,
-       .fb_copyarea = psbfb_copyarea,
-       .fb_imageblit = cfb_imageblit,
-       .fb_mmap = psbfb_mmap,
-       .fb_sync = psbfb_sync,
-       .fb_ioctl = psbfb_ioctl,
-};
-
-static struct fb_ops psbfb_roll_ops = {
-       .owner = THIS_MODULE,
-       .fb_check_var = drm_fb_helper_check_var,
-       .fb_set_par = drm_fb_helper_set_par,
-       .fb_blank = drm_fb_helper_blank,
-       .fb_setcolreg = psbfb_setcolreg,
-       .fb_fillrect = cfb_fillrect,
-       .fb_copyarea = cfb_copyarea,
-       .fb_imageblit = cfb_imageblit,
-       .fb_pan_display = psbfb_pan,
-       .fb_mmap = psbfb_mmap,
-       .fb_sync = psbfb_sync,
-       .fb_ioctl = psbfb_ioctl,
-};
-
-static struct fb_ops psbfb_unaccel_ops = {
-       .owner = THIS_MODULE,
-       .fb_check_var = drm_fb_helper_check_var,
-       .fb_set_par = drm_fb_helper_set_par,
-       .fb_blank = drm_fb_helper_blank,
-       .fb_setcolreg = psbfb_setcolreg,
-       .fb_fillrect = cfb_fillrect,
-       .fb_copyarea = cfb_copyarea,
-       .fb_imageblit = cfb_imageblit,
-       .fb_mmap = psbfb_mmap,
-       .fb_ioctl = psbfb_ioctl,
-};
-
-/**
- *     psb_framebuffer_init    -       initialize a framebuffer
- *     @dev: our DRM device
- *     @fb: framebuffer to set up
- *     @mode_cmd: mode description
- *     @gt: backing object
- *
- *     Configure and fill in the boilerplate for our frame buffer. Return
- *     0 on success or an error code if we fail.
- */
-static int psb_framebuffer_init(struct drm_device *dev,
-                                       struct psb_framebuffer *fb,
-                                       struct drm_mode_fb_cmd2 *mode_cmd,
-                                       struct gtt_range *gt)
-{
-       u32 bpp, depth;
-       int ret;
-
-       drm_fb_get_bpp_depth(mode_cmd->pixel_format, &depth, &bpp);
-
-       if (mode_cmd->pitches[0] & 63)
-               return -EINVAL;
-       switch (bpp) {
-       case 8:
-       case 16:
-       case 24:
-       case 32:
-               break;
-       default:
-               return -EINVAL;
-       }
-       ret = drm_framebuffer_init(dev, &fb->base, &psb_fb_funcs);
-       if (ret) {
-               dev_err(dev->dev, "framebuffer init failed: %d\n", ret);
-               return ret;
-       }
-       drm_helper_mode_fill_fb_struct(&fb->base, mode_cmd);
-       fb->gtt = gt;
-       return 0;
-}
-
-/**
- *     psb_framebuffer_create  -       create a framebuffer backed by gt
- *     @dev: our DRM device
- *     @mode_cmd: the description of the requested mode
- *     @gt: the backing object
- *
- *     Create a framebuffer object backed by the gt, and fill in the
- *     boilerplate required
- *
- *     TODO: review object references
- */
-
-static struct drm_framebuffer *psb_framebuffer_create
-                       (struct drm_device *dev,
-                        struct drm_mode_fb_cmd2 *mode_cmd,
-                        struct gtt_range *gt)
-{
-       struct psb_framebuffer *fb;
-       int ret;
-
-       fb = kzalloc(sizeof(*fb), GFP_KERNEL);
-       if (!fb)
-               return ERR_PTR(-ENOMEM);
-
-       ret = psb_framebuffer_init(dev, fb, mode_cmd, gt);
-       if (ret) {
-               kfree(fb);
-               return ERR_PTR(ret);
-       }
-       return &fb->base;
-}
-
-/**
- *     psbfb_alloc             -       allocate frame buffer memory
- *     @dev: the DRM device
- *     @aligned_size: space needed
- *     @force: fall back to GEM buffers if need be
- *
- *     Allocate the frame buffer. In the usual case we get a GTT range that
- *     is stolen memory backed and life is simple. If there isn't sufficient
- *     stolen memory or the system has no stolen memory we allocate a range
- *     and back it with a GEM object.
- *
- *     In this case the GEM object has no handle.
- */
-static struct gtt_range *psbfb_alloc(struct drm_device *dev,
-                                               int aligned_size, int force)
-{
-       struct gtt_range *backing;
-       /* Begin by trying to use stolen memory backing */
-       backing = psb_gtt_alloc_range(dev, aligned_size, "fb", 1);
-       if (backing) {
-               if (drm_gem_private_object_init(dev,
-                                       &backing->gem, aligned_size) == 0)
-                       return backing;
-               psb_gtt_free_range(dev, backing);
-       }
-       if (!force)
-               return NULL;
-
-       /* Next try using GEM host memory */
-       backing = psb_gtt_alloc_range(dev, aligned_size, "fb(gem)", 0);
-       if (backing == NULL)
-               return NULL;
-
-       /* Now back it with an object */
-       if (drm_gem_object_init(dev, &backing->gem, aligned_size) != 0) {
-               psb_gtt_free_range(dev, backing);
-               return NULL;
-       }
-       return backing;
-}
-
-/**
- *     psbfb_create            -       create a framebuffer
- *     @fbdev: the framebuffer device
- *     @sizes: specification of the layout
- *
- *     Create a framebuffer to the specifications provided
- */
-static int psbfb_create(struct psb_fbdev *fbdev,
-                               struct drm_fb_helper_surface_size *sizes)
-{
-       struct drm_device *dev = fbdev->psb_fb_helper.dev;
-       struct drm_psb_private *dev_priv = dev->dev_private;
-       struct fb_info *info;
-       struct drm_framebuffer *fb;
-       struct psb_framebuffer *psbfb = &fbdev->pfb;
-       struct drm_mode_fb_cmd2 mode_cmd;
-       struct device *device = &dev->pdev->dev;
-       int size;
-       int ret;
-       struct gtt_range *backing;
-       int gtt_roll = 1;
-       u32 bpp, depth;
-
-       mode_cmd.width = sizes->surface_width;
-       mode_cmd.height = sizes->surface_height;
-       bpp = sizes->surface_bpp;
-
-       /* No 24bit packed */
-       if (bpp == 24)
-               bpp = 32;
-
-       /* Acceleration via the GTT requires pitch to be 4096 byte aligned 
-          (ie 1024 or 2048 pixels in normal use) */
-       mode_cmd.pitches[0] =  ALIGN(mode_cmd.width * ((bpp + 7) / 8), 4096);
-       depth = sizes->surface_depth;
-
-       size = mode_cmd.pitches[0] * mode_cmd.height;
-       size = ALIGN(size, PAGE_SIZE);
-
-       /* Allocate the framebuffer in the GTT with stolen page backing */
-       backing = psbfb_alloc(dev, size, 0);
-       if (backing == NULL) {
-               /*
-                *      We couldn't get the space we wanted, fall back to the
-                *      display engine requirement instead.  The HW requires
-                *      the pitch to be 64 byte aligned
-                */
-
-               gtt_roll = 0;   /* Don't use GTT accelerated scrolling */
-
-               mode_cmd.pitches[0] =  ALIGN(mode_cmd.width * ((bpp + 7) / 8), 64);
-               depth = sizes->surface_depth;
-
-               size = mode_cmd.pitches[0] * mode_cmd.height;
-               size = ALIGN(size, PAGE_SIZE);
-
-               /* Allocate the framebuffer in the GTT with stolen page
-                  backing when there is room */
-               backing = psbfb_alloc(dev, size, 1);
-               if (backing == NULL)
-                       return -ENOMEM;
-       }
-
-       mutex_lock(&dev->struct_mutex);
-
-       info = framebuffer_alloc(0, device);
-       if (!info) {
-               ret = -ENOMEM;
-               goto out_err1;
-       }
-       info->par = fbdev;
-
-       mode_cmd.pixel_format = drm_mode_legacy_fb_format(bpp, depth);
-
-       ret = psb_framebuffer_init(dev, psbfb, &mode_cmd, backing);
-       if (ret)
-               goto out_unref;
-
-       fb = &psbfb->base;
-       psbfb->fbdev = info;
-
-       fbdev->psb_fb_helper.fb = fb;
-       fbdev->psb_fb_helper.fbdev = info;
-
-       strcpy(info->fix.id, "psbfb");
-
-       info->flags = FBINFO_DEFAULT;
-       if (gtt_roll) { /* GTT rolling seems best */
-               info->fbops = &psbfb_roll_ops;
-               info->flags |= FBINFO_HWACCEL_YPAN;
-        }
-       else if (dev_priv->ops->accel_2d)       /* 2D engine */
-               info->fbops = &psbfb_ops;
-       else    /* Software */
-               info->fbops = &psbfb_unaccel_ops;
-
-       ret = fb_alloc_cmap(&info->cmap, 256, 0);
-       if (ret) {
-               ret = -ENOMEM;
-               goto out_unref;
-       }
-
-       info->fix.smem_start = dev->mode_config.fb_base;
-       info->fix.smem_len = size;
-       info->fix.ywrapstep = gtt_roll;
-       info->fix.ypanstep = gtt_roll;
-
-       if (backing->stolen) {
-               /* Accessed stolen memory directly */
-               info->screen_base = (char *)dev_priv->vram_addr +
-                                                       backing->offset;
-       } else {
-               /* Pin the pages into the GTT and create a mapping to them */
-               psb_gtt_pin(backing);
-               info->screen_base = vm_map_ram(backing->pages, backing->npage,
-                               -1, PAGE_KERNEL);
-               if (info->screen_base == NULL) {
-                       psb_gtt_unpin(backing);
-                       ret = -ENOMEM;
-                       goto out_unref;
-               }
-               psbfb->vm_map = 1;
-       }
-       info->screen_size = size;
-
-       if (dev_priv->gtt.stolen_size) {
-               info->apertures = alloc_apertures(1);
-               if (!info->apertures) {
-                       ret = -ENOMEM;
-                       goto out_unref;
-               }
-               info->apertures->ranges[0].base = dev->mode_config.fb_base;
-               info->apertures->ranges[0].size = dev_priv->gtt.stolen_size;
-       }
-
-       drm_fb_helper_fill_fix(info, fb->pitches[0], fb->depth);
-       drm_fb_helper_fill_var(info, &fbdev->psb_fb_helper,
-                               sizes->fb_width, sizes->fb_height);
-
-       info->fix.mmio_start = pci_resource_start(dev->pdev, 0);
-       info->fix.mmio_len = pci_resource_len(dev->pdev, 0);
-
-       info->pixmap.size = 64 * 1024;
-       info->pixmap.buf_align = 8;
-       info->pixmap.access_align = 32;
-       info->pixmap.flags = FB_PIXMAP_SYSTEM;
-       info->pixmap.scan_align = 1;
-
-       dev_info(dev->dev, "allocated %dx%d fb\n",
-                                       psbfb->base.width, psbfb->base.height);
-
-       mutex_unlock(&dev->struct_mutex);
-       return 0;
-out_unref:
-       if (backing->stolen)
-               psb_gtt_free_range(dev, backing);
-       else {
-               if (psbfb->vm_map)
-                       vm_unmap_ram(info->screen_base, backing->npage);
-               drm_gem_object_unreference(&backing->gem);
-       }
-out_err1:
-       mutex_unlock(&dev->struct_mutex);
-       psb_gtt_free_range(dev, backing);
-       return ret;
-}
-
-/**
- *     psb_user_framebuffer_create     -       create framebuffer
- *     @dev: our DRM device
- *     @filp: client file
- *     @cmd: mode request
- *
- *     Create a new framebuffer backed by a userspace GEM object
- */
-static struct drm_framebuffer *psb_user_framebuffer_create
-                       (struct drm_device *dev, struct drm_file *filp,
-                        struct drm_mode_fb_cmd2 *cmd)
-{
-       struct gtt_range *r;
-       struct drm_gem_object *obj;
-
-       /*
-        *      Find the GEM object and thus the gtt range object that is
-        *      to back this space
-        */
-       obj = drm_gem_object_lookup(dev, filp, cmd->handles[0]);
-       if (obj == NULL)
-               return ERR_PTR(-ENOENT);
-
-       /* Let the core code do all the work */
-       r = container_of(obj, struct gtt_range, gem);
-       return psb_framebuffer_create(dev, cmd, r);
-}
-
-static void psbfb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green,
-                                                       u16 blue, int regno)
-{
-}
-
-static void psbfb_gamma_get(struct drm_crtc *crtc, u16 *red,
-                                       u16 *green, u16 *blue, int regno)
-{
-}
-
-static int psbfb_probe(struct drm_fb_helper *helper,
-                               struct drm_fb_helper_surface_size *sizes)
-{
-       struct psb_fbdev *psb_fbdev = (struct psb_fbdev *)helper;
-       int new_fb = 0;
-       int ret;
-
-       if (!helper->fb) {
-               ret = psbfb_create(psb_fbdev, sizes);
-               if (ret)
-                       return ret;
-               new_fb = 1;
-       }
-       return new_fb;
-}
-
-struct drm_fb_helper_funcs psb_fb_helper_funcs = {
-       .gamma_set = psbfb_gamma_set,
-       .gamma_get = psbfb_gamma_get,
-       .fb_probe = psbfb_probe,
-};
-
-int psb_fbdev_destroy(struct drm_device *dev, struct psb_fbdev *fbdev)
-{
-       struct fb_info *info;
-       struct psb_framebuffer *psbfb = &fbdev->pfb;
-
-       if (fbdev->psb_fb_helper.fbdev) {
-               info = fbdev->psb_fb_helper.fbdev;
-
-               /* If this is our base framebuffer then kill any virtual map
-                  for the framebuffer layer and unpin it */
-               if (psbfb->vm_map) {
-                       vm_unmap_ram(info->screen_base, psbfb->gtt->npage);
-                       psb_gtt_unpin(psbfb->gtt);
-               }
-               unregister_framebuffer(info);
-               if (info->cmap.len)
-                       fb_dealloc_cmap(&info->cmap);
-               framebuffer_release(info);
-       }
-       drm_fb_helper_fini(&fbdev->psb_fb_helper);
-       drm_framebuffer_cleanup(&psbfb->base);
-
-       if (psbfb->gtt)
-               drm_gem_object_unreference(&psbfb->gtt->gem);
-       return 0;
-}
-
-int psb_fbdev_init(struct drm_device *dev)
-{
-       struct psb_fbdev *fbdev;
-       struct drm_psb_private *dev_priv = dev->dev_private;
-
-       fbdev = kzalloc(sizeof(struct psb_fbdev), GFP_KERNEL);
-       if (!fbdev) {
-               dev_err(dev->dev, "no memory\n");
-               return -ENOMEM;
-       }
-
-       dev_priv->fbdev = fbdev;
-       fbdev->psb_fb_helper.funcs = &psb_fb_helper_funcs;
-
-       drm_fb_helper_init(dev, &fbdev->psb_fb_helper, dev_priv->ops->crtcs,
-                                                       INTELFB_CONN_LIMIT);
-
-       drm_fb_helper_single_add_all_connectors(&fbdev->psb_fb_helper);
-       drm_fb_helper_initial_config(&fbdev->psb_fb_helper, 32);
-       return 0;
-}
-
-void psb_fbdev_fini(struct drm_device *dev)
-{
-       struct drm_psb_private *dev_priv = dev->dev_private;
-
-       if (!dev_priv->fbdev)
-               return;
-
-       psb_fbdev_destroy(dev, dev_priv->fbdev);
-       kfree(dev_priv->fbdev);
-       dev_priv->fbdev = NULL;
-}
-
-static void psbfb_output_poll_changed(struct drm_device *dev)
-{
-       struct drm_psb_private *dev_priv = dev->dev_private;
-       struct psb_fbdev *fbdev = (struct psb_fbdev *)dev_priv->fbdev;
-       drm_fb_helper_hotplug_event(&fbdev->psb_fb_helper);
-}
-
-/**
- *     psb_user_framebuffer_create_handle - add hamdle to a framebuffer
- *     @fb: framebuffer
- *     @file_priv: our DRM file
- *     @handle: returned handle
- *
- *     Our framebuffer object is a GTT range which also contains a GEM
- *     object. We need to turn it into a handle for userspace. GEM will do
- *     the work for us
- */
-static int psb_user_framebuffer_create_handle(struct drm_framebuffer *fb,
-                                             struct drm_file *file_priv,
-                                             unsigned int *handle)
-{
-       struct psb_framebuffer *psbfb = to_psb_fb(fb);
-       struct gtt_range *r = psbfb->gtt;
-       return drm_gem_handle_create(file_priv, &r->gem, handle);
-}
-
-/**
- *     psb_user_framebuffer_destroy    -       destruct user created fb
- *     @fb: framebuffer
- *
- *     User framebuffers are backed by GEM objects so all we have to do is
- *     clean up a bit and drop the reference, GEM will handle the fallout
- */
-static void psb_user_framebuffer_destroy(struct drm_framebuffer *fb)
-{
-       struct psb_framebuffer *psbfb = to_psb_fb(fb);
-       struct gtt_range *r = psbfb->gtt;
-       struct drm_device *dev = fb->dev;
-       struct drm_psb_private *dev_priv = dev->dev_private;
-       struct psb_fbdev *fbdev = dev_priv->fbdev;
-       struct drm_crtc *crtc;
-       int reset = 0;
-
-       /* Should never get stolen memory for a user fb */
-       WARN_ON(r->stolen);
-
-       /* Check if we are erroneously live */
-       list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
-               if (crtc->fb == fb)
-                       reset = 1;
-
-       if (reset)
-               /*
-                * Now force a sane response before we permit the DRM CRTC
-                * layer to do stupid things like blank the display. Instead
-                * we reset this framebuffer as if the user had forced a reset.
-                * We must do this before the cleanup so that the DRM layer
-                * doesn't get a chance to stick its oar in where it isn't
-                * wanted.
-                */
-               drm_fb_helper_restore_fbdev_mode(&fbdev->psb_fb_helper);
-
-       /* Let DRM do its clean up */
-       drm_framebuffer_cleanup(fb);
-       /*  We are no longer using the resource in GEM */
-       drm_gem_object_unreference_unlocked(&r->gem);
-       kfree(fb);
-}
-
-static const struct drm_mode_config_funcs psb_mode_funcs = {
-       .fb_create = psb_user_framebuffer_create,
-       .output_poll_changed = psbfb_output_poll_changed,
-};
-
-static int psb_create_backlight_property(struct drm_device *dev)
-{
-       struct drm_psb_private *dev_priv = dev->dev_private;
-       struct drm_property *backlight;
-
-       if (dev_priv->backlight_property)
-               return 0;
-
-       backlight = drm_property_create(dev, DRM_MODE_PROP_RANGE,
-                                                       "backlight", 2);
-       backlight->values[0] = 0;
-       backlight->values[1] = 100;
-
-       dev_priv->backlight_property = backlight;
-
-       return 0;
-}
-
-static void psb_setup_outputs(struct drm_device *dev)
-{
-       struct drm_psb_private *dev_priv = dev->dev_private;
-       struct drm_connector *connector;
-
-       drm_mode_create_scaling_mode_property(dev);
-       psb_create_backlight_property(dev);
-
-       dev_priv->ops->output_init(dev);
-
-       list_for_each_entry(connector, &dev->mode_config.connector_list,
-                           head) {
-               struct psb_intel_output *psb_intel_output =
-                   to_psb_intel_output(connector);
-               struct drm_encoder *encoder = &psb_intel_output->enc;
-               int crtc_mask = 0, clone_mask = 0;
-
-               /* valid crtcs */
-               switch (psb_intel_output->type) {
-               case INTEL_OUTPUT_ANALOG:
-                       crtc_mask = (1 << 0);
-                       clone_mask = (1 << INTEL_OUTPUT_ANALOG);
-                       break;
-               case INTEL_OUTPUT_SDVO:
-                       crtc_mask = ((1 << 0) | (1 << 1));
-                       clone_mask = (1 << INTEL_OUTPUT_SDVO);
-                       break;
-               case INTEL_OUTPUT_LVDS:
-                       if (IS_MRST(dev))
-                               crtc_mask = (1 << 0);
-                       else
-                               crtc_mask = (1 << 1);
-                       clone_mask = (1 << INTEL_OUTPUT_LVDS);
-                       break;
-               case INTEL_OUTPUT_MIPI:
-                       crtc_mask = (1 << 0);
-                       clone_mask = (1 << INTEL_OUTPUT_MIPI);
-                       break;
-               case INTEL_OUTPUT_MIPI2:
-                       crtc_mask = (1 << 2);
-                       clone_mask = (1 << INTEL_OUTPUT_MIPI2);
-                       break;
-               case INTEL_OUTPUT_HDMI:
-                       /* HDMI on crtc 1 for SoC devices and crtc 0 for
-                           Cedarview. HDMI on Poulsbo is only via external
-                          logic */
-                       if (IS_MFLD(dev) || IS_MRST(dev))
-                               crtc_mask = (1 << 1);
-                       else
-                               crtc_mask = (1 << 0);   /* Cedarview */
-                       clone_mask = (1 << INTEL_OUTPUT_HDMI);
-                       break;
-               }
-               encoder->possible_crtcs = crtc_mask;
-               encoder->possible_clones =
-                   psb_intel_connector_clones(dev, clone_mask);
-       }
-}
-
-void psb_modeset_init(struct drm_device *dev)
-{
-       struct drm_psb_private *dev_priv =
-           (struct drm_psb_private *) dev->dev_private;
-       struct psb_intel_mode_device *mode_dev = &dev_priv->mode_dev;
-       int i;
-
-       drm_mode_config_init(dev);
-
-       dev->mode_config.min_width = 0;
-       dev->mode_config.min_height = 0;
-
-       dev->mode_config.funcs = (void *) &psb_mode_funcs;
-
-       /* set memory base */
-       /* MRST and PSB should use BAR 2*/
-       pci_read_config_dword(dev->pdev, PSB_BSM, (u32 *)
-                                       &(dev->mode_config.fb_base));
-
-       /* num pipes is 2 for PSB but 1 for Mrst */
-       for (i = 0; i < dev_priv->num_pipe; i++)
-               psb_intel_crtc_init(dev, i, mode_dev);
-
-       dev->mode_config.max_width = 2048;
-       dev->mode_config.max_height = 2048;
-
-       psb_setup_outputs(dev);
-}
-
-void psb_modeset_cleanup(struct drm_device *dev)
-{
-       mutex_lock(&dev->struct_mutex);
-
-       drm_kms_helper_poll_fini(dev);
-       psb_fbdev_fini(dev);
-       drm_mode_config_cleanup(dev);
-
-       mutex_unlock(&dev->struct_mutex);
-}
diff --git a/drivers/staging/gma500/framebuffer.h b/drivers/staging/gma500/framebuffer.h
deleted file mode 100644 (file)
index d1b2289..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (c) 2008-2011, Intel Corporation
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Authors:
- *      Eric Anholt <eric@anholt.net>
- *
- */
-
-#ifndef _FRAMEBUFFER_H_
-#define _FRAMEBUFFER_H_
-
-#include <drm/drmP.h>
-#include <drm/drm_fb_helper.h>
-
-#include "psb_drv.h"
-
-struct psb_framebuffer {
-       struct drm_framebuffer base;
-       struct address_space *addr_space;
-       struct fb_info *fbdev;
-       struct gtt_range *gtt;
-       bool vm_map;            /* True if we must undo a vm_map_ram */
-};
-
-struct psb_fbdev {
-       struct drm_fb_helper psb_fb_helper;
-       struct psb_framebuffer pfb;
-};
-
-#define to_psb_fb(x) container_of(x, struct psb_framebuffer, base)
-
-extern int psb_intel_connector_clones(struct drm_device *dev, int type_mask);
-
-#endif
-
diff --git a/drivers/staging/gma500/gem.c b/drivers/staging/gma500/gem.c
deleted file mode 100644 (file)
index f6433c0..0000000
+++ /dev/null
@@ -1,292 +0,0 @@
-/*
- *  psb GEM interface
- *
- * Copyright (c) 2011, Intel Corporation.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Authors: Alan Cox
- *
- * TODO:
- *     -       we need to work out if the MMU is relevant (eg for
- *             accelerated operations on a GEM object)
- */
-
-#include <drm/drmP.h>
-#include <drm/drm.h>
-#include "psb_drm.h"
-#include "psb_drv.h"
-
-int psb_gem_init_object(struct drm_gem_object *obj)
-{
-       return -EINVAL;
-}
-
-void psb_gem_free_object(struct drm_gem_object *obj)
-{
-       struct gtt_range *gtt = container_of(obj, struct gtt_range, gem);
-       drm_gem_object_release_wrap(obj);
-       /* This must occur last as it frees up the memory of the GEM object */
-       psb_gtt_free_range(obj->dev, gtt);
-}
-
-int psb_gem_get_aperture(struct drm_device *dev, void *data,
-                               struct drm_file *file)
-{
-       return -EINVAL;
-}
-
-/**
- *     psb_gem_dumb_map_gtt    -       buffer mapping for dumb interface
- *     @file: our drm client file
- *     @dev: drm device
- *     @handle: GEM handle to the object (from dumb_create)
- *
- *     Do the necessary setup to allow the mapping of the frame buffer
- *     into user memory. We don't have to do much here at the moment.
- */
-int psb_gem_dumb_map_gtt(struct drm_file *file, struct drm_device *dev,
-                        uint32_t handle, uint64_t *offset)
-{
-       int ret = 0;
-       struct drm_gem_object *obj;
-
-       if (!(dev->driver->driver_features & DRIVER_GEM))
-               return -ENODEV;
-
-       mutex_lock(&dev->struct_mutex);
-
-       /* GEM does all our handle to object mapping */
-       obj = drm_gem_object_lookup(dev, file, handle);
-       if (obj == NULL) {
-               ret = -ENOENT;
-               goto unlock;
-       }
-       /* What validation is needed here ? */
-
-       /* Make it mmapable */
-       if (!obj->map_list.map) {
-               ret = gem_create_mmap_offset(obj);
-               if (ret)
-                       goto out;
-       }
-       /* GEM should really work out the hash offsets for us */
-       *offset = (u64)obj->map_list.hash.key << PAGE_SHIFT;
-out:
-       drm_gem_object_unreference(obj);
-unlock:
-       mutex_unlock(&dev->struct_mutex);
-       return ret;
-}
-
-/**
- *     psb_gem_create          -       create a mappable object
- *     @file: the DRM file of the client
- *     @dev: our device
- *     @size: the size requested
- *     @handlep: returned handle (opaque number)
- *
- *     Create a GEM object, fill in the boilerplate and attach a handle to
- *     it so that userspace can speak about it. This does the core work
- *     for the various methods that do/will create GEM objects for things
- */
-static int psb_gem_create(struct drm_file *file,
-       struct drm_device *dev, uint64_t size, uint32_t *handlep)
-{
-       struct gtt_range *r;
-       int ret;
-       u32 handle;
-
-       size = roundup(size, PAGE_SIZE);
-
-       /* Allocate our object - for now a direct gtt range which is not
-          stolen memory backed */
-       r = psb_gtt_alloc_range(dev, size, "gem", 0);
-       if (r == NULL) {
-               dev_err(dev->dev, "no memory for %lld byte GEM object\n", size);
-               return -ENOSPC;
-       }
-       /* Initialize the extra goodies GEM needs to do all the hard work */
-       if (drm_gem_object_init(dev, &r->gem, size) != 0) {
-               psb_gtt_free_range(dev, r);
-               /* GEM doesn't give an error code so use -ENOMEM */
-               dev_err(dev->dev, "GEM init failed for %lld\n", size);
-               return -ENOMEM;
-       }
-       /* Give the object a handle so we can carry it more easily */
-       ret = drm_gem_handle_create(file, &r->gem, &handle);
-       if (ret) {
-               dev_err(dev->dev, "GEM handle failed for %p, %lld\n",
-                                                       &r->gem, size);
-               drm_gem_object_release(&r->gem);
-               psb_gtt_free_range(dev, r);
-               return ret;
-       }
-       /* We have the initial and handle reference but need only one now */
-       drm_gem_object_unreference(&r->gem);
-       *handlep = handle;
-       return 0;
-}
-
-/**
- *     psb_gem_dumb_create     -       create a dumb buffer
- *     @drm_file: our client file
- *     @dev: our device
- *     @args: the requested arguments copied from userspace
- *
- *     Allocate a buffer suitable for use for a frame buffer of the
- *     form described by user space. Give userspace a handle by which
- *     to reference it.
- */
-int psb_gem_dumb_create(struct drm_file *file, struct drm_device *dev,
-                       struct drm_mode_create_dumb *args)
-{
-       args->pitch = ALIGN(args->width * ((args->bpp + 7) / 8), 64);
-       args->size = args->pitch * args->height;
-       return psb_gem_create(file, dev, args->size, &args->handle);
-}
-
-/**
- *     psb_gem_dumb_destroy    -       destroy a dumb buffer
- *     @file: client file
- *     @dev: our DRM device
- *     @handle: the object handle
- *
- *     Destroy a handle that was created via psb_gem_dumb_create, at least
- *     we hope it was created that way. i915 seems to assume the caller
- *     does the checking but that might be worth review ! FIXME
- */
-int psb_gem_dumb_destroy(struct drm_file *file, struct drm_device *dev,
-                       uint32_t handle)
-{
-       /* No special work needed, drop the reference and see what falls out */
-       return drm_gem_handle_delete(file, handle);
-}
-
-/**
- *     psb_gem_fault           -       pagefault handler for GEM objects
- *     @vma: the VMA of the GEM object
- *     @vmf: fault detail
- *
- *     Invoked when a fault occurs on an mmap of a GEM managed area. GEM
- *     does most of the work for us including the actual map/unmap calls
- *     but we need to do the actual page work.
- *
- *     This code eventually needs to handle faulting objects in and out
- *     of the GTT and repacking it when we run out of space. We can put
- *     that off for now and for our simple uses
- *
- *     The VMA was set up by GEM. In doing so it also ensured that the
- *     vma->vm_private_data points to the GEM object that is backing this
- *     mapping.
- */
-int psb_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
-{
-       struct drm_gem_object *obj;
-       struct gtt_range *r;
-       int ret;
-       unsigned long pfn;
-       pgoff_t page_offset;
-       struct drm_device *dev;
-       struct drm_psb_private *dev_priv;
-
-       obj = vma->vm_private_data;     /* GEM object */
-       dev = obj->dev;
-       dev_priv = dev->dev_private;
-
-       r = container_of(obj, struct gtt_range, gem);   /* Get the gtt range */
-
-       /* Make sure we don't parallel update on a fault, nor move or remove
-          something from beneath our feet */
-       mutex_lock(&dev->struct_mutex);
-
-       /* For now the mmap pins the object and it stays pinned. As things
-          stand that will do us no harm */
-       if (r->mmapping == 0) {
-               ret = psb_gtt_pin(r);
-               if (ret < 0) {
-                       dev_err(dev->dev, "gma500: pin failed: %d\n", ret);
-                       goto fail;
-               }
-               r->mmapping = 1;
-       }
-
-       /* Page relative to the VMA start - we must calculate this ourselves
-          because vmf->pgoff is the fake GEM offset */
-       page_offset = ((unsigned long) vmf->virtual_address - vma->vm_start)
-                               >> PAGE_SHIFT;
-
-       /* CPU view of the page, don't go via the GART for CPU writes */
-       if (r->stolen)
-               pfn = (dev_priv->stolen_base + r->offset) >> PAGE_SHIFT;
-       else
-               pfn = page_to_pfn(r->pages[page_offset]);
-       ret = vm_insert_pfn(vma, (unsigned long)vmf->virtual_address, pfn);
-
-fail:
-       mutex_unlock(&dev->struct_mutex);
-       switch (ret) {
-       case 0:
-       case -ERESTARTSYS:
-       case -EINTR:
-               return VM_FAULT_NOPAGE;
-       case -ENOMEM:
-               return VM_FAULT_OOM;
-       default:
-               return VM_FAULT_SIGBUS;
-       }
-}
-
-static int psb_gem_create_stolen(struct drm_file *file, struct drm_device *dev,
-                                               int size, u32 *handle)
-{
-       struct gtt_range *gtt = psb_gtt_alloc_range(dev, size, "gem", 1);
-       if (gtt == NULL)
-               return -ENOMEM;
-       if (drm_gem_private_object_init(dev, &gtt->gem, size) != 0)
-               goto free_gtt;
-       if (drm_gem_handle_create(file, &gtt->gem, handle) == 0)
-               return 0;
-free_gtt:
-       psb_gtt_free_range(dev, gtt);
-       return -ENOMEM;
-}
-
-/*
- *     GEM interfaces for our specific client
- */
-int psb_gem_create_ioctl(struct drm_device *dev, void *data,
-                                       struct drm_file *file)
-{
-       struct drm_psb_gem_create *args = data;
-       int ret;
-       if (args->flags & PSB_GEM_CREATE_STOLEN) {
-               ret = psb_gem_create_stolen(file, dev, args->size,
-                                                       &args->handle);
-               if (ret == 0)
-                       return 0;
-               /* Fall throguh */
-               args->flags &= ~PSB_GEM_CREATE_STOLEN;
-       }
-       return psb_gem_create(file, dev, args->size, &args->handle);
-}
-
-int psb_gem_mmap_ioctl(struct drm_device *dev, void *data,
-                                       struct drm_file *file)
-{
-       struct drm_psb_gem_mmap *args = data;
-       return dev->driver->dumb_map_offset(file, dev,
-                                               args->handle, &args->offset);
-}
-
diff --git a/drivers/staging/gma500/gem_glue.c b/drivers/staging/gma500/gem_glue.c
deleted file mode 100644 (file)
index daac121..0000000
+++ /dev/null
@@ -1,89 +0,0 @@
-/**************************************************************************
- * Copyright (c) 2011, Intel Corporation.
- * All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- **************************************************************************/
-
-#include <drm/drmP.h>
-#include <drm/drm.h>
-
-void drm_gem_object_release_wrap(struct drm_gem_object *obj)
-{
-       /* Remove the list map if one is present */
-       if (obj->map_list.map) {
-               struct drm_gem_mm *mm = obj->dev->mm_private;
-               struct drm_map_list *list = &obj->map_list;
-               drm_ht_remove_item(&mm->offset_hash, &list->hash);
-               drm_mm_put_block(list->file_offset_node);
-               kfree(list->map);
-               list->map = NULL;
-       }
-       drm_gem_object_release(obj);
-}
-
-/**
- *     gem_create_mmap_offset          -       invent an mmap offset
- *     @obj: our object
- *
- *     Standard implementation of offset generation for mmap as is
- *     duplicated in several drivers. This belongs in GEM.
- */
-int gem_create_mmap_offset(struct drm_gem_object *obj)
-{
-       struct drm_device *dev = obj->dev;
-       struct drm_gem_mm *mm = dev->mm_private;
-       struct drm_map_list *list;
-       struct drm_local_map *map;
-       int ret;
-
-       list = &obj->map_list;
-       list->map = kzalloc(sizeof(struct drm_map_list), GFP_KERNEL);
-       if (list->map == NULL)
-               return -ENOMEM;
-       map = list->map;
-       map->type = _DRM_GEM;
-       map->size = obj->size;
-       map->handle = obj;
-
-       list->file_offset_node = drm_mm_search_free(&mm->offset_manager,
-                                       obj->size / PAGE_SIZE, 0, 0);
-       if (!list->file_offset_node) {
-               dev_err(dev->dev, "failed to allocate offset for bo %d\n",
-                                                               obj->name);
-               ret = -ENOSPC;
-               goto free_it;
-       }
-       list->file_offset_node = drm_mm_get_block(list->file_offset_node,
-                                       obj->size / PAGE_SIZE, 0);
-       if (!list->file_offset_node) {
-               ret = -ENOMEM;
-               goto free_it;
-       }
-       list->hash.key = list->file_offset_node->start;
-       ret = drm_ht_insert_item(&mm->offset_hash, &list->hash);
-       if (ret) {
-               dev_err(dev->dev, "failed to add to map hash\n");
-               goto free_mm;
-       }
-       return 0;
-
-free_mm:
-       drm_mm_put_block(list->file_offset_node);
-free_it:
-       kfree(list->map);
-       list->map = NULL;
-       return ret;
-}
diff --git a/drivers/staging/gma500/gem_glue.h b/drivers/staging/gma500/gem_glue.h
deleted file mode 100644 (file)
index ce5ce30..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-extern void drm_gem_object_release_wrap(struct drm_gem_object *obj);
-extern int gem_create_mmap_offset(struct drm_gem_object *obj);
diff --git a/drivers/staging/gma500/gtt.c b/drivers/staging/gma500/gtt.c
deleted file mode 100644 (file)
index e770bd1..0000000
+++ /dev/null
@@ -1,553 +0,0 @@
-/*
- * Copyright (c) 2007, Intel Corporation.
- * All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Authors: Thomas Hellstrom <thomas-at-tungstengraphics.com>
- *         Alan Cox <alan@linux.intel.com>
- */
-
-#include <drm/drmP.h>
-#include "psb_drv.h"
-
-
-/*
- *     GTT resource allocator - manage page mappings in GTT space
- */
-
-/**
- *     psb_gtt_mask_pte        -       generate GTT pte entry
- *     @pfn: page number to encode
- *     @type: type of memory in the GTT
- *
- *     Set the GTT entry for the appropriate memory type.
- */
-static inline uint32_t psb_gtt_mask_pte(uint32_t pfn, int type)
-{
-       uint32_t mask = PSB_PTE_VALID;
-
-       if (type & PSB_MMU_CACHED_MEMORY)
-               mask |= PSB_PTE_CACHED;
-       if (type & PSB_MMU_RO_MEMORY)
-               mask |= PSB_PTE_RO;
-       if (type & PSB_MMU_WO_MEMORY)
-               mask |= PSB_PTE_WO;
-
-       return (pfn << PAGE_SHIFT) | mask;
-}
-
-/**
- *     psb_gtt_entry           -       find the GTT entries for a gtt_range
- *     @dev: our DRM device
- *     @r: our GTT range
- *
- *     Given a gtt_range object return the GTT offset of the page table
- *     entries for this gtt_range
- */
-u32 *psb_gtt_entry(struct drm_device *dev, struct gtt_range *r)
-{
-       struct drm_psb_private *dev_priv = dev->dev_private;
-       unsigned long offset;
-
-       offset = r->resource.start - dev_priv->gtt_mem->start;
-
-       return dev_priv->gtt_map + (offset >> PAGE_SHIFT);
-}
-
-/**
- *     psb_gtt_insert  -       put an object into the GTT
- *     @dev: our DRM device
- *     @r: our GTT range
- *
- *     Take our preallocated GTT range and insert the GEM object into
- *     the GTT. This is protected via the gtt mutex which the caller
- *     must hold.
- */
-static int psb_gtt_insert(struct drm_device *dev, struct gtt_range *r)
-{
-       u32 *gtt_slot, pte;
-       struct page **pages;
-       int i;
-
-       if (r->pages == NULL) {
-               WARN_ON(1);
-               return -EINVAL;
-       }
-
-       WARN_ON(r->stolen);     /* refcount these maybe ? */
-
-       gtt_slot = psb_gtt_entry(dev, r);
-       pages = r->pages;
-
-       /* Make sure changes are visible to the GPU */
-       set_pages_array_uc(pages, r->npage);
-
-       /* Write our page entries into the GTT itself */
-       for (i = r->roll; i < r->npage; i++) {
-               pte = psb_gtt_mask_pte(page_to_pfn(r->pages[i]), 0);
-               iowrite32(pte, gtt_slot++);
-       }
-       for (i = 0; i < r->roll; i++) {
-               pte = psb_gtt_mask_pte(page_to_pfn(r->pages[i]), 0);
-               iowrite32(pte, gtt_slot++);
-       }
-       /* Make sure all the entries are set before we return */
-       ioread32(gtt_slot - 1);
-
-       return 0;
-}
-
-/**
- *     psb_gtt_remove  -       remove an object from the GTT
- *     @dev: our DRM device
- *     @r: our GTT range
- *
- *     Remove a preallocated GTT range from the GTT. Overwrite all the
- *     page table entries with the dummy page. This is protected via the gtt
- *     mutex which the caller must hold.
- */
-static void psb_gtt_remove(struct drm_device *dev, struct gtt_range *r)
-{
-       struct drm_psb_private *dev_priv = dev->dev_private;
-       u32 *gtt_slot, pte;
-       int i;
-
-       WARN_ON(r->stolen);
-
-       gtt_slot = psb_gtt_entry(dev, r);
-       pte = psb_gtt_mask_pte(page_to_pfn(dev_priv->scratch_page), 0);
-
-       for (i = 0; i < r->npage; i++)
-               iowrite32(pte, gtt_slot++);
-       ioread32(gtt_slot - 1);
-       set_pages_array_wb(r->pages, r->npage);
-}
-
-/**
- *     psb_gtt_roll    -       set scrolling position
- *     @dev: our DRM device
- *     @r: the gtt mapping we are using
- *     @roll: roll offset
- *
- *     Roll an existing pinned mapping by moving the pages through the GTT.
- *     This allows us to implement hardware scrolling on the consoles without
- *     a 2D engine
- */
-void psb_gtt_roll(struct drm_device *dev, struct gtt_range *r, int roll)
-{
-       u32 *gtt_slot, pte;
-       int i;
-
-       if (roll >= r->npage) {
-               WARN_ON(1);
-               return;
-       }
-
-       r->roll = roll;
-
-       /* Not currently in the GTT - no worry we will write the mapping at
-          the right position when it gets pinned */
-       if (!r->stolen && !r->in_gart)
-               return;
-
-       gtt_slot = psb_gtt_entry(dev, r);
-
-       for (i = r->roll; i < r->npage; i++) {
-               pte = psb_gtt_mask_pte(page_to_pfn(r->pages[i]), 0);
-               iowrite32(pte, gtt_slot++);
-       }
-       for (i = 0; i < r->roll; i++) {
-               pte = psb_gtt_mask_pte(page_to_pfn(r->pages[i]), 0);
-               iowrite32(pte, gtt_slot++);
-       }
-       ioread32(gtt_slot - 1);
-}
-
-/**
- *     psb_gtt_attach_pages    -       attach and pin GEM pages
- *     @gt: the gtt range
- *
- *     Pin and build an in kernel list of the pages that back our GEM object.
- *     While we hold this the pages cannot be swapped out. This is protected
- *     via the gtt mutex which the caller must hold.
- */
-static int psb_gtt_attach_pages(struct gtt_range *gt)
-{
-       struct inode *inode;
-       struct address_space *mapping;
-       int i;
-       struct page *p;
-       int pages = gt->gem.size / PAGE_SIZE;
-
-       WARN_ON(gt->pages);
-
-       /* This is the shared memory object that backs the GEM resource */
-       inode = gt->gem.filp->f_path.dentry->d_inode;
-       mapping = inode->i_mapping;
-
-       gt->pages = kmalloc(pages * sizeof(struct page *), GFP_KERNEL);
-       if (gt->pages == NULL)
-               return -ENOMEM;
-       gt->npage = pages;
-
-       for (i = 0; i < pages; i++) {
-               /* FIXME: needs updating as per mail from Hugh Dickins */
-               p = read_cache_page_gfp(mapping, i,
-                                       __GFP_COLD | GFP_KERNEL);
-               if (IS_ERR(p))
-                       goto err;
-               gt->pages[i] = p;
-       }
-       return 0;
-
-err:
-       while (i--)
-               page_cache_release(gt->pages[i]);
-       kfree(gt->pages);
-       gt->pages = NULL;
-       return PTR_ERR(p);
-}
-
-/**
- *     psb_gtt_detach_pages    -       attach and pin GEM pages
- *     @gt: the gtt range
- *
- *     Undo the effect of psb_gtt_attach_pages. At this point the pages
- *     must have been removed from the GTT as they could now be paged out
- *     and move bus address. This is protected via the gtt mutex which the
- *     caller must hold.
- */
-static void psb_gtt_detach_pages(struct gtt_range *gt)
-{
-       int i;
-       for (i = 0; i < gt->npage; i++) {
-               /* FIXME: do we need to force dirty */
-               set_page_dirty(gt->pages[i]);
-               page_cache_release(gt->pages[i]);
-       }
-       kfree(gt->pages);
-       gt->pages = NULL;
-}
-
-/**
- *     psb_gtt_pin             -       pin pages into the GTT
- *     @gt: range to pin
- *
- *     Pin a set of pages into the GTT. The pins are refcounted so that
- *     multiple pins need multiple unpins to undo.
- *
- *     Non GEM backed objects treat this as a no-op as they are always GTT
- *     backed objects.
- */
-int psb_gtt_pin(struct gtt_range *gt)
-{
-       int ret = 0;
-       struct drm_device *dev = gt->gem.dev;
-       struct drm_psb_private *dev_priv = dev->dev_private;
-
-       mutex_lock(&dev_priv->gtt_mutex);
-
-       if (gt->in_gart == 0 && gt->stolen == 0) {
-               ret = psb_gtt_attach_pages(gt);
-               if (ret < 0)
-                       goto out;
-               ret = psb_gtt_insert(dev, gt);
-               if (ret < 0) {
-                       psb_gtt_detach_pages(gt);
-                       goto out;
-               }
-       }
-       gt->in_gart++;
-out:
-       mutex_unlock(&dev_priv->gtt_mutex);
-       return ret;
-}
-
-/**
- *     psb_gtt_unpin           -       Drop a GTT pin requirement
- *     @gt: range to pin
- *
- *     Undoes the effect of psb_gtt_pin. On the last drop the GEM object
- *     will be removed from the GTT which will also drop the page references
- *     and allow the VM to clean up or page stuff.
- *
- *     Non GEM backed objects treat this as a no-op as they are always GTT
- *     backed objects.
- */
-void psb_gtt_unpin(struct gtt_range *gt)
-{
-       struct drm_device *dev = gt->gem.dev;
-       struct drm_psb_private *dev_priv = dev->dev_private;
-
-       mutex_lock(&dev_priv->gtt_mutex);
-
-       WARN_ON(!gt->in_gart);
-
-       gt->in_gart--;
-       if (gt->in_gart == 0 && gt->stolen == 0) {
-               psb_gtt_remove(dev, gt);
-               psb_gtt_detach_pages(gt);
-       }
-       mutex_unlock(&dev_priv->gtt_mutex);
-}
-
-/*
- *     GTT resource allocator - allocate and manage GTT address space
- */
-
-/**
- *     psb_gtt_alloc_range     -       allocate GTT address space
- *     @dev: Our DRM device
- *     @len: length (bytes) of address space required
- *     @name: resource name
- *     @backed: resource should be backed by stolen pages
- *
- *     Ask the kernel core to find us a suitable range of addresses
- *     to use for a GTT mapping.
- *
- *     Returns a gtt_range structure describing the object, or NULL on
- *     error. On successful return the resource is both allocated and marked
- *     as in use.
- */
-struct gtt_range *psb_gtt_alloc_range(struct drm_device *dev, int len,
-                                               const char *name, int backed)
-{
-       struct drm_psb_private *dev_priv = dev->dev_private;
-       struct gtt_range *gt;
-       struct resource *r = dev_priv->gtt_mem;
-       int ret;
-       unsigned long start, end;
-
-       if (backed) {
-               /* The start of the GTT is the stolen pages */
-               start = r->start;
-               end = r->start + dev_priv->gtt.stolen_size - 1;
-       } else {
-               /* The rest we will use for GEM backed objects */
-               start = r->start + dev_priv->gtt.stolen_size;
-               end = r->end;
-       }
-
-       gt = kzalloc(sizeof(struct gtt_range), GFP_KERNEL);
-       if (gt == NULL)
-               return NULL;
-       gt->resource.name = name;
-       gt->stolen = backed;
-       gt->in_gart = backed;
-       gt->roll = 0;
-       /* Ensure this is set for non GEM objects */
-       gt->gem.dev = dev;
-       ret = allocate_resource(dev_priv->gtt_mem, &gt->resource,
-                               len, start, end, PAGE_SIZE, NULL, NULL);
-       if (ret == 0) {
-               gt->offset = gt->resource.start - r->start;
-               return gt;
-       }
-       kfree(gt);
-       return NULL;
-}
-
-/**
- *     psb_gtt_free_range      -       release GTT address space
- *     @dev: our DRM device
- *     @gt: a mapping created with psb_gtt_alloc_range
- *
- *     Release a resource that was allocated with psb_gtt_alloc_range. If the
- *     object has been pinned by mmap users we clean this up here currently.
- */
-void psb_gtt_free_range(struct drm_device *dev, struct gtt_range *gt)
-{
-       /* Undo the mmap pin if we are destroying the object */
-       if (gt->mmapping) {
-               psb_gtt_unpin(gt);
-               gt->mmapping = 0;
-       }
-       WARN_ON(gt->in_gart && !gt->stolen);
-       release_resource(&gt->resource);
-       kfree(gt);
-}
-
-void psb_gtt_alloc(struct drm_device *dev)
-{
-       struct drm_psb_private *dev_priv = dev->dev_private;
-       init_rwsem(&dev_priv->gtt.sem);
-}
-
-void psb_gtt_takedown(struct drm_device *dev)
-{
-       struct drm_psb_private *dev_priv = dev->dev_private;
-
-       if (dev_priv->gtt_map) {
-               iounmap(dev_priv->gtt_map);
-               dev_priv->gtt_map = NULL;
-       }
-       if (dev_priv->gtt_initialized) {
-               pci_write_config_word(dev->pdev, PSB_GMCH_CTRL,
-                                     dev_priv->gmch_ctrl);
-               PSB_WVDC32(dev_priv->pge_ctl, PSB_PGETBL_CTL);
-               (void) PSB_RVDC32(PSB_PGETBL_CTL);
-       }
-       if (dev_priv->vram_addr)
-               iounmap(dev_priv->gtt_map);
-}
-
-int psb_gtt_init(struct drm_device *dev, int resume)
-{
-       struct drm_psb_private *dev_priv = dev->dev_private;
-       unsigned gtt_pages;
-       unsigned long stolen_size, vram_stolen_size;
-       unsigned i, num_pages;
-       unsigned pfn_base;
-       uint32_t vram_pages;
-       uint32_t dvmt_mode = 0;
-       struct psb_gtt *pg;
-
-       int ret = 0;
-       uint32_t pte;
-
-       mutex_init(&dev_priv->gtt_mutex);
-
-       psb_gtt_alloc(dev);
-       pg = &dev_priv->gtt;
-
-       /* Enable the GTT */
-       pci_read_config_word(dev->pdev, PSB_GMCH_CTRL, &dev_priv->gmch_ctrl);
-       pci_write_config_word(dev->pdev, PSB_GMCH_CTRL,
-                             dev_priv->gmch_ctrl | _PSB_GMCH_ENABLED);
-
-       dev_priv->pge_ctl = PSB_RVDC32(PSB_PGETBL_CTL);
-       PSB_WVDC32(dev_priv->pge_ctl | _PSB_PGETBL_ENABLED, PSB_PGETBL_CTL);
-       (void) PSB_RVDC32(PSB_PGETBL_CTL);
-
-       /* The root resource we allocate address space from */
-       dev_priv->gtt_initialized = 1;
-
-       pg->gtt_phys_start = dev_priv->pge_ctl & PAGE_MASK;
-
-       /*
-        *      The video mmu has a hw bug when accessing 0x0D0000000.
-        *      Make gatt start at 0x0e000,0000. This doesn't actually
-        *      matter for us but may do if the video acceleration ever
-        *      gets opened up.
-        */
-       pg->mmu_gatt_start = 0xE0000000;
-
-       pg->gtt_start = pci_resource_start(dev->pdev, PSB_GTT_RESOURCE);
-       gtt_pages = pci_resource_len(dev->pdev, PSB_GTT_RESOURCE)
-                                                               >> PAGE_SHIFT;
-       /* Some CDV firmware doesn't report this currently. In which case the
-          system has 64 gtt pages */
-       if (pg->gtt_start == 0 || gtt_pages == 0) {
-               dev_err(dev->dev, "GTT PCI BAR not initialized.\n");
-               gtt_pages = 64;
-               pg->gtt_start = dev_priv->pge_ctl;
-       }
-
-       pg->gatt_start = pci_resource_start(dev->pdev, PSB_GATT_RESOURCE);
-       pg->gatt_pages = pci_resource_len(dev->pdev, PSB_GATT_RESOURCE)
-                                                               >> PAGE_SHIFT;
-       dev_priv->gtt_mem = &dev->pdev->resource[PSB_GATT_RESOURCE];
-
-       if (pg->gatt_pages == 0 || pg->gatt_start == 0) {
-               static struct resource fudge;   /* Preferably peppermint */
-               /* This can occur on CDV SDV systems. Fudge it in this case.
-                  We really don't care what imaginary space is being allocated
-                  at this point */
-               dev_err(dev->dev, "GATT PCI BAR not initialized.\n");
-               pg->gatt_start = 0x40000000;
-               pg->gatt_pages = (128 * 1024 * 1024) >> PAGE_SHIFT;
-               /* This is a little confusing but in fact the GTT is providing
-                  a view from the GPU into memory and not vice versa. As such
-                  this is really allocating space that is not the same as the
-                  CPU address space on CDV */
-               fudge.start = 0x40000000;
-               fudge.end = 0x40000000 + 128 * 1024 * 1024 - 1;
-               fudge.name = "fudge";
-               fudge.flags = IORESOURCE_MEM;
-               dev_priv->gtt_mem = &fudge;
-       }
-
-       pci_read_config_dword(dev->pdev, PSB_BSM, &dev_priv->stolen_base);
-       vram_stolen_size = pg->gtt_phys_start - dev_priv->stolen_base
-                                                               - PAGE_SIZE;
-
-       stolen_size = vram_stolen_size;
-
-       printk(KERN_INFO "Stolen memory information\n");
-       printk(KERN_INFO "       base in RAM: 0x%x\n", dev_priv->stolen_base);
-       printk(KERN_INFO "       size: %luK, calculated by (GTT RAM base) - (Stolen base), seems wrong\n",
-               vram_stolen_size/1024);
-       dvmt_mode = (dev_priv->gmch_ctrl >> 4) & 0x7;
-       printk(KERN_INFO "      the correct size should be: %dM(dvmt mode=%d)\n",
-               (dvmt_mode == 1) ? 1 : (2 << (dvmt_mode - 1)), dvmt_mode);
-
-       if (resume && (gtt_pages != pg->gtt_pages) &&
-           (stolen_size != pg->stolen_size)) {
-               dev_err(dev->dev, "GTT resume error.\n");
-               ret = -EINVAL;
-               goto out_err;
-       }
-
-       pg->gtt_pages = gtt_pages;
-       pg->stolen_size = stolen_size;
-       dev_priv->vram_stolen_size = vram_stolen_size;
-
-       /*
-        *      Map the GTT and the stolen memory area
-        */
-       dev_priv->gtt_map = ioremap_nocache(pg->gtt_phys_start,
-                                               gtt_pages << PAGE_SHIFT);
-       if (!dev_priv->gtt_map) {
-               dev_err(dev->dev, "Failure to map gtt.\n");
-               ret = -ENOMEM;
-               goto out_err;
-       }
-
-       dev_priv->vram_addr = ioremap_wc(dev_priv->stolen_base, stolen_size);
-       if (!dev_priv->vram_addr) {
-               dev_err(dev->dev, "Failure to map stolen base.\n");
-               ret = -ENOMEM;
-               goto out_err;
-       }
-
-       /*
-        * Insert vram stolen pages into the GTT
-        */
-
-       pfn_base = dev_priv->stolen_base >> PAGE_SHIFT;
-       vram_pages = num_pages = vram_stolen_size >> PAGE_SHIFT;
-       printk(KERN_INFO"Set up %d stolen pages starting at 0x%08x, GTT offset %dK\n",
-               num_pages, pfn_base << PAGE_SHIFT, 0);
-       for (i = 0; i < num_pages; ++i) {
-               pte = psb_gtt_mask_pte(pfn_base + i, 0);
-               iowrite32(pte, dev_priv->gtt_map + i);
-       }
-
-       /*
-        * Init rest of GTT to the scratch page to avoid accidents or scribbles
-        */
-
-       pfn_base = page_to_pfn(dev_priv->scratch_page);
-       pte = psb_gtt_mask_pte(pfn_base, 0);
-       for (; i < gtt_pages; ++i)
-               iowrite32(pte, dev_priv->gtt_map + i);
-
-       (void) ioread32(dev_priv->gtt_map + i - 1);
-       return 0;
-
-out_err:
-       psb_gtt_takedown(dev);
-       return ret;
-}
diff --git a/drivers/staging/gma500/gtt.h b/drivers/staging/gma500/gtt.h
deleted file mode 100644 (file)
index aa17423..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-/**************************************************************************
- * Copyright (c) 2007-2008, Intel Corporation.
- * All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- **************************************************************************/
-
-#ifndef _PSB_GTT_H_
-#define _PSB_GTT_H_
-
-#include <drm/drmP.h>
-
-/* This wants cleaning up with respect to the psb_dev and un-needed stuff */
-struct psb_gtt {
-       uint32_t gatt_start;
-       uint32_t mmu_gatt_start;
-       uint32_t gtt_start;
-       uint32_t gtt_phys_start;
-       unsigned gtt_pages;
-       unsigned gatt_pages;
-       unsigned long stolen_size;
-       unsigned long vram_stolen_size;
-       struct rw_semaphore sem;
-};
-
-/* Exported functions */
-extern int psb_gtt_init(struct drm_device *dev, int resume);
-extern void psb_gtt_takedown(struct drm_device *dev);
-
-/* Each gtt_range describes an allocation in the GTT area */
-struct gtt_range {
-       struct resource resource;       /* Resource for our allocation */
-       u32 offset;                     /* GTT offset of our object */
-       struct drm_gem_object gem;      /* GEM high level stuff */
-       int in_gart;                    /* Currently in the GART (ref ct) */
-       bool stolen;                    /* Backed from stolen RAM */
-       bool mmapping;                  /* Is mmappable */
-       struct page **pages;            /* Backing pages if present */
-       int npage;                      /* Number of backing pages */
-       int roll;                       /* Roll applied to the GTT entries */
-};
-
-extern struct gtt_range *psb_gtt_alloc_range(struct drm_device *dev, int len,
-                                               const char *name, int backed);
-extern void psb_gtt_kref_put(struct gtt_range *gt);
-extern void psb_gtt_free_range(struct drm_device *dev, struct gtt_range *gt);
-extern int psb_gtt_pin(struct gtt_range *gt);
-extern void psb_gtt_unpin(struct gtt_range *gt);
-extern void psb_gtt_roll(struct drm_device *dev,
-                                       struct gtt_range *gt, int roll);
-
-#endif
diff --git a/drivers/staging/gma500/intel_bios.c b/drivers/staging/gma500/intel_bios.c
deleted file mode 100644 (file)
index 096757f..0000000
+++ /dev/null
@@ -1,303 +0,0 @@
-/*
- * Copyright (c) 2006 Intel Corporation
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Authors:
- *    Eric Anholt <eric@anholt.net>
- *
- */
-#include <drm/drmP.h>
-#include <drm/drm.h>
-#include "psb_drm.h"
-#include "psb_drv.h"
-#include "psb_intel_drv.h"
-#include "psb_intel_reg.h"
-#include "intel_bios.h"
-
-
-static void *find_section(struct bdb_header *bdb, int section_id)
-{
-       u8 *base = (u8 *)bdb;
-       int index = 0;
-       u16 total, current_size;
-       u8 current_id;
-
-       /* skip to first section */
-       index += bdb->header_size;
-       total = bdb->bdb_size;
-
-       /* walk the sections looking for section_id */
-       while (index < total) {
-               current_id = *(base + index);
-               index++;
-               current_size = *((u16 *)(base + index));
-               index += 2;
-               if (current_id == section_id)
-                       return base + index;
-               index += current_size;
-       }
-
-       return NULL;
-}
-
-static void fill_detail_timing_data(struct drm_display_mode *panel_fixed_mode,
-                       struct lvds_dvo_timing *dvo_timing)
-{
-       panel_fixed_mode->hdisplay = (dvo_timing->hactive_hi << 8) |
-               dvo_timing->hactive_lo;
-       panel_fixed_mode->hsync_start = panel_fixed_mode->hdisplay +
-               ((dvo_timing->hsync_off_hi << 8) | dvo_timing->hsync_off_lo);
-       panel_fixed_mode->hsync_end = panel_fixed_mode->hsync_start +
-               dvo_timing->hsync_pulse_width;
-       panel_fixed_mode->htotal = panel_fixed_mode->hdisplay +
-               ((dvo_timing->hblank_hi << 8) | dvo_timing->hblank_lo);
-
-       panel_fixed_mode->vdisplay = (dvo_timing->vactive_hi << 8) |
-               dvo_timing->vactive_lo;
-       panel_fixed_mode->vsync_start = panel_fixed_mode->vdisplay +
-               dvo_timing->vsync_off;
-       panel_fixed_mode->vsync_end = panel_fixed_mode->vsync_start +
-               dvo_timing->vsync_pulse_width;
-       panel_fixed_mode->vtotal = panel_fixed_mode->vdisplay +
-               ((dvo_timing->vblank_hi << 8) | dvo_timing->vblank_lo);
-       panel_fixed_mode->clock = dvo_timing->clock * 10;
-       panel_fixed_mode->type = DRM_MODE_TYPE_PREFERRED;
-
-       /* Some VBTs have bogus h/vtotal values */
-       if (panel_fixed_mode->hsync_end > panel_fixed_mode->htotal)
-               panel_fixed_mode->htotal = panel_fixed_mode->hsync_end + 1;
-       if (panel_fixed_mode->vsync_end > panel_fixed_mode->vtotal)
-               panel_fixed_mode->vtotal = panel_fixed_mode->vsync_end + 1;
-
-       drm_mode_set_name(panel_fixed_mode);
-}
-
-static void parse_backlight_data(struct drm_psb_private *dev_priv,
-                               struct bdb_header *bdb)
-{
-       struct bdb_lvds_backlight *vbt_lvds_bl = NULL;
-       struct bdb_lvds_backlight *lvds_bl;
-       u8 p_type = 0;
-       void *bl_start = NULL;
-       struct bdb_lvds_options *lvds_opts
-                               = find_section(bdb, BDB_LVDS_OPTIONS);
-
-       dev_priv->lvds_bl = NULL;
-
-       if (lvds_opts)
-               p_type = lvds_opts->panel_type;
-       else
-               return;
-
-       bl_start = find_section(bdb, BDB_LVDS_BACKLIGHT);
-       vbt_lvds_bl = (struct bdb_lvds_backlight *)(bl_start + 1) + p_type;
-
-       lvds_bl = kzalloc(sizeof(*vbt_lvds_bl), GFP_KERNEL);
-       if (!lvds_bl) {
-               dev_err(dev_priv->dev->dev, "out of memory for backlight data\n");
-               return;
-       }
-       memcpy(lvds_bl, vbt_lvds_bl, sizeof(*vbt_lvds_bl));
-       dev_priv->lvds_bl = lvds_bl;
-}
-
-/* Try to find integrated panel data */
-static void parse_lfp_panel_data(struct drm_psb_private *dev_priv,
-                           struct bdb_header *bdb)
-{
-       struct bdb_lvds_options *lvds_options;
-       struct bdb_lvds_lfp_data *lvds_lfp_data;
-       struct bdb_lvds_lfp_data_entry *entry;
-       struct lvds_dvo_timing *dvo_timing;
-       struct drm_display_mode *panel_fixed_mode;
-
-       /* Defaults if we can't find VBT info */
-       dev_priv->lvds_dither = 0;
-       dev_priv->lvds_vbt = 0;
-
-       lvds_options = find_section(bdb, BDB_LVDS_OPTIONS);
-       if (!lvds_options)
-               return;
-
-       dev_priv->lvds_dither = lvds_options->pixel_dither;
-       if (lvds_options->panel_type == 0xff)
-               return;
-
-       lvds_lfp_data = find_section(bdb, BDB_LVDS_LFP_DATA);
-       if (!lvds_lfp_data)
-               return;
-
-
-       entry = &lvds_lfp_data->data[lvds_options->panel_type];
-       dvo_timing = &entry->dvo_timing;
-
-       panel_fixed_mode = kzalloc(sizeof(*panel_fixed_mode),
-                                     GFP_KERNEL);
-       if (panel_fixed_mode == NULL) {
-               dev_err(dev_priv->dev->dev, "out of memory for fixed panel mode\n");
-               return;
-       }
-
-       dev_priv->lvds_vbt = 1;
-       fill_detail_timing_data(panel_fixed_mode, dvo_timing);
-
-       if (panel_fixed_mode->htotal > 0 && panel_fixed_mode->vtotal > 0) {
-               dev_priv->lfp_lvds_vbt_mode = panel_fixed_mode;
-               drm_mode_debug_printmodeline(panel_fixed_mode);
-       } else {
-               dev_dbg(dev_priv->dev->dev, "ignoring invalid LVDS VBT\n");
-               dev_priv->lvds_vbt = 0;
-               kfree(panel_fixed_mode);
-       }
-       return;
-}
-
-/* Try to find sdvo panel data */
-static void parse_sdvo_panel_data(struct drm_psb_private *dev_priv,
-                     struct bdb_header *bdb)
-{
-       struct bdb_sdvo_lvds_options *sdvo_lvds_options;
-       struct lvds_dvo_timing *dvo_timing;
-       struct drm_display_mode *panel_fixed_mode;
-
-       dev_priv->sdvo_lvds_vbt_mode = NULL;
-
-       sdvo_lvds_options = find_section(bdb, BDB_SDVO_LVDS_OPTIONS);
-       if (!sdvo_lvds_options)
-               return;
-
-       dvo_timing = find_section(bdb, BDB_SDVO_PANEL_DTDS);
-       if (!dvo_timing)
-               return;
-
-       panel_fixed_mode = kzalloc(sizeof(*panel_fixed_mode), GFP_KERNEL);
-
-       if (!panel_fixed_mode)
-               return;
-
-       fill_detail_timing_data(panel_fixed_mode,
-                       dvo_timing + sdvo_lvds_options->panel_type);
-
-       dev_priv->sdvo_lvds_vbt_mode = panel_fixed_mode;
-
-       return;
-}
-
-static void parse_general_features(struct drm_psb_private *dev_priv,
-                      struct bdb_header *bdb)
-{
-       struct bdb_general_features *general;
-
-       /* Set sensible defaults in case we can't find the general block */
-       dev_priv->int_tv_support = 1;
-       dev_priv->int_crt_support = 1;
-
-       general = find_section(bdb, BDB_GENERAL_FEATURES);
-       if (general) {
-               dev_priv->int_tv_support = general->int_tv_support;
-               dev_priv->int_crt_support = general->int_crt_support;
-               dev_priv->lvds_use_ssc = general->enable_ssc;
-
-               if (dev_priv->lvds_use_ssc) {
-                       dev_priv->lvds_ssc_freq
-                               = general->ssc_freq ? 100 : 96;
-               }
-       }
-}
-
-/**
- * psb_intel_init_bios - initialize VBIOS settings & find VBT
- * @dev: DRM device
- *
- * Loads the Video BIOS and checks that the VBT exists.  Sets scratch registers
- * to appropriate values.
- *
- * VBT existence is a sanity check that is relied on by other i830_bios.c code.
- * Note that it would be better to use a BIOS call to get the VBT, as BIOSes may
- * feed an updated VBT back through that, compared to what we'll fetch using
- * this method of groping around in the BIOS data.
- *
- * Returns 0 on success, nonzero on failure.
- */
-bool psb_intel_init_bios(struct drm_device *dev)
-{
-       struct drm_psb_private *dev_priv = dev->dev_private;
-       struct pci_dev *pdev = dev->pdev;
-       struct vbt_header *vbt = NULL;
-       struct bdb_header *bdb;
-       u8 __iomem *bios;
-       size_t size;
-       int i;
-
-       bios = pci_map_rom(pdev, &size);
-       if (!bios)
-               return -1;
-
-       /* Scour memory looking for the VBT signature */
-       for (i = 0; i + 4 < size; i++) {
-               if (!memcmp(bios + i, "$VBT", 4)) {
-                       vbt = (struct vbt_header *)(bios + i);
-                       break;
-               }
-       }
-
-       if (!vbt) {
-               dev_err(dev->dev, "VBT signature missing\n");
-               pci_unmap_rom(pdev, bios);
-               return -1;
-       }
-
-       bdb = (struct bdb_header *)(bios + i + vbt->bdb_offset);
-
-       /* Grab useful general definitions */
-       parse_general_features(dev_priv, bdb);
-       parse_lfp_panel_data(dev_priv, bdb);
-       parse_sdvo_panel_data(dev_priv, bdb);
-       parse_backlight_data(dev_priv, bdb);
-
-       pci_unmap_rom(pdev, bios);
-
-       return 0;
-}
-
-/**
- * Destroy and free VBT data
- */
-void psb_intel_destroy_bios(struct drm_device *dev)
-{
-       struct drm_psb_private *dev_priv = dev->dev_private;
-       struct drm_display_mode *sdvo_lvds_vbt_mode =
-                               dev_priv->sdvo_lvds_vbt_mode;
-       struct drm_display_mode *lfp_lvds_vbt_mode =
-                               dev_priv->lfp_lvds_vbt_mode;
-       struct bdb_lvds_backlight *lvds_bl =
-                               dev_priv->lvds_bl;
-
-       /*free sdvo panel mode*/
-       if (sdvo_lvds_vbt_mode) {
-               dev_priv->sdvo_lvds_vbt_mode = NULL;
-               kfree(sdvo_lvds_vbt_mode);
-       }
-
-       if (lfp_lvds_vbt_mode) {
-               dev_priv->lfp_lvds_vbt_mode = NULL;
-               kfree(lfp_lvds_vbt_mode);
-       }
-
-       if (lvds_bl) {
-               dev_priv->lvds_bl = NULL;
-               kfree(lvds_bl);
-       }
-}
diff --git a/drivers/staging/gma500/intel_bios.h b/drivers/staging/gma500/intel_bios.h
deleted file mode 100644 (file)
index 70f1bf0..0000000
+++ /dev/null
@@ -1,430 +0,0 @@
-/*
- * Copyright (c) 2006 Intel Corporation
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Authors:
- *    Eric Anholt <eric@anholt.net>
- *
- */
-
-#ifndef _I830_BIOS_H_
-#define _I830_BIOS_H_
-
-#include <drm/drmP.h>
-
-struct vbt_header {
-       u8 signature[20];               /**< Always starts with 'VBT$' */
-       u16 version;                    /**< decimal */
-       u16 header_size;                /**< in bytes */
-       u16 vbt_size;                   /**< in bytes */
-       u8 vbt_checksum;
-       u8 reserved0;
-       u32 bdb_offset;                 /**< from beginning of VBT */
-       u32 aim_offset[4];              /**< from beginning of VBT */
-} __attribute__((packed));
-
-
-struct bdb_header {
-       u8 signature[16];               /**< Always 'BIOS_DATA_BLOCK' */
-       u16 version;                    /**< decimal */
-       u16 header_size;                /**< in bytes */
-       u16 bdb_size;                   /**< in bytes */
-};
-
-/* strictly speaking, this is a "skip" block, but it has interesting info */
-struct vbios_data {
-       u8 type; /* 0 == desktop, 1 == mobile */
-       u8 relstage;
-       u8 chipset;
-       u8 lvds_present:1;
-       u8 tv_present:1;
-       u8 rsvd2:6; /* finish byte */
-       u8 rsvd3[4];
-       u8 signon[155];
-       u8 copyright[61];
-       u16 code_segment;
-       u8 dos_boot_mode;
-       u8 bandwidth_percent;
-       u8 rsvd4; /* popup memory size */
-       u8 resize_pci_bios;
-       u8 rsvd5; /* is crt already on ddc2 */
-} __attribute__((packed));
-
-/*
- * There are several types of BIOS data blocks (BDBs), each block has
- * an ID and size in the first 3 bytes (ID in first, size in next 2).
- * Known types are listed below.
- */
-#define BDB_GENERAL_FEATURES     1
-#define BDB_GENERAL_DEFINITIONS          2
-#define BDB_OLD_TOGGLE_LIST      3
-#define BDB_MODE_SUPPORT_LIST    4
-#define BDB_GENERIC_MODE_TABLE   5
-#define BDB_EXT_MMIO_REGS        6
-#define BDB_SWF_IO               7
-#define BDB_SWF_MMIO             8
-#define BDB_DOT_CLOCK_TABLE      9
-#define BDB_MODE_REMOVAL_TABLE  10
-#define BDB_CHILD_DEVICE_TABLE  11
-#define BDB_DRIVER_FEATURES     12
-#define BDB_DRIVER_PERSISTENCE  13
-#define BDB_EXT_TABLE_PTRS      14
-#define BDB_DOT_CLOCK_OVERRIDE  15
-#define BDB_DISPLAY_SELECT      16
-/* 17 rsvd */
-#define BDB_DRIVER_ROTATION     18
-#define BDB_DISPLAY_REMOVE      19
-#define BDB_OEM_CUSTOM          20
-#define BDB_EFP_LIST            21 /* workarounds for VGA hsync/vsync */
-#define BDB_SDVO_LVDS_OPTIONS   22
-#define BDB_SDVO_PANEL_DTDS     23
-#define BDB_SDVO_LVDS_PNP_IDS   24
-#define BDB_SDVO_LVDS_POWER_SEQ         25
-#define BDB_TV_OPTIONS          26
-#define BDB_LVDS_OPTIONS        40
-#define BDB_LVDS_LFP_DATA_PTRS  41
-#define BDB_LVDS_LFP_DATA       42
-#define BDB_LVDS_BACKLIGHT      43
-#define BDB_LVDS_POWER          44
-#define BDB_SKIP               254 /* VBIOS private block, ignore */
-
-struct bdb_general_features {
-       /* bits 1 */
-       u8 panel_fitting:2;
-       u8 flexaim:1;
-       u8 msg_enable:1;
-       u8 clear_screen:3;
-       u8 color_flip:1;
-
-       /* bits 2 */
-       u8 download_ext_vbt:1;
-       u8 enable_ssc:1;
-       u8 ssc_freq:1;
-       u8 enable_lfp_on_override:1;
-       u8 disable_ssc_ddt:1;
-       u8 rsvd8:3; /* finish byte */
-
-       /* bits 3 */
-       u8 disable_smooth_vision:1;
-       u8 single_dvi:1;
-       u8 rsvd9:6; /* finish byte */
-
-       /* bits 4 */
-       u8 legacy_monitor_detect;
-
-       /* bits 5 */
-       u8 int_crt_support:1;
-       u8 int_tv_support:1;
-       u8 rsvd11:6; /* finish byte */
-} __attribute__((packed));
-
-struct bdb_general_definitions {
-       /* DDC GPIO */
-       u8 crt_ddc_gmbus_pin;
-
-       /* DPMS bits */
-       u8 dpms_acpi:1;
-       u8 skip_boot_crt_detect:1;
-       u8 dpms_aim:1;
-       u8 rsvd1:5; /* finish byte */
-
-       /* boot device bits */
-       u8 boot_display[2];
-       u8 child_dev_size;
-
-       /* device info */
-       u8 tv_or_lvds_info[33];
-       u8 dev1[33];
-       u8 dev2[33];
-       u8 dev3[33];
-       u8 dev4[33];
-       /* may be another device block here on some platforms */
-};
-
-struct bdb_lvds_options {
-       u8 panel_type;
-       u8 rsvd1;
-       /* LVDS capabilities, stored in a dword */
-       u8 pfit_mode:2;
-       u8 pfit_text_mode_enhanced:1;
-       u8 pfit_gfx_mode_enhanced:1;
-       u8 pfit_ratio_auto:1;
-       u8 pixel_dither:1;
-       u8 lvds_edid:1;
-       u8 rsvd2:1;
-       u8 rsvd4;
-} __attribute__((packed));
-
-struct bdb_lvds_backlight {
-       u8 type:2;
-       u8 pol:1;
-       u8 gpio:3;
-       u8 gmbus:2;
-       u16 freq;
-       u8 minbrightness;
-       u8 i2caddr;
-       u8 brightnesscmd;
-       /*FIXME: more...*/
-} __attribute__((packed));
-
-/* LFP pointer table contains entries to the struct below */
-struct bdb_lvds_lfp_data_ptr {
-       u16 fp_timing_offset; /* offsets are from start of bdb */
-       u8 fp_table_size;
-       u16 dvo_timing_offset;
-       u8 dvo_table_size;
-       u16 panel_pnp_id_offset;
-       u8 pnp_table_size;
-} __attribute__((packed));
-
-struct bdb_lvds_lfp_data_ptrs {
-       u8 lvds_entries; /* followed by one or more lvds_data_ptr structs */
-       struct bdb_lvds_lfp_data_ptr ptr[16];
-} __attribute__((packed));
-
-/* LFP data has 3 blocks per entry */
-struct lvds_fp_timing {
-       u16 x_res;
-       u16 y_res;
-       u32 lvds_reg;
-       u32 lvds_reg_val;
-       u32 pp_on_reg;
-       u32 pp_on_reg_val;
-       u32 pp_off_reg;
-       u32 pp_off_reg_val;
-       u32 pp_cycle_reg;
-       u32 pp_cycle_reg_val;
-       u32 pfit_reg;
-       u32 pfit_reg_val;
-       u16 terminator;
-} __attribute__((packed));
-
-struct lvds_dvo_timing {
-       u16 clock;              /**< In 10khz */
-       u8 hactive_lo;
-       u8 hblank_lo;
-       u8 hblank_hi:4;
-       u8 hactive_hi:4;
-       u8 vactive_lo;
-       u8 vblank_lo;
-       u8 vblank_hi:4;
-       u8 vactive_hi:4;
-       u8 hsync_off_lo;
-       u8 hsync_pulse_width;
-       u8 vsync_pulse_width:4;
-       u8 vsync_off:4;
-       u8 rsvd0:6;
-       u8 hsync_off_hi:2;
-       u8 h_image;
-       u8 v_image;
-       u8 max_hv;
-       u8 h_border;
-       u8 v_border;
-       u8 rsvd1:3;
-       u8 digital:2;
-       u8 vsync_positive:1;
-       u8 hsync_positive:1;
-       u8 rsvd2:1;
-} __attribute__((packed));
-
-struct lvds_pnp_id {
-       u16 mfg_name;
-       u16 product_code;
-       u32 serial;
-       u8 mfg_week;
-       u8 mfg_year;
-} __attribute__((packed));
-
-struct bdb_lvds_lfp_data_entry {
-       struct lvds_fp_timing fp_timing;
-       struct lvds_dvo_timing dvo_timing;
-       struct lvds_pnp_id pnp_id;
-} __attribute__((packed));
-
-struct bdb_lvds_lfp_data {
-       struct bdb_lvds_lfp_data_entry data[16];
-} __attribute__((packed));
-
-struct aimdb_header {
-       char signature[16];
-       char oem_device[20];
-       u16 aimdb_version;
-       u16 aimdb_header_size;
-       u16 aimdb_size;
-} __attribute__((packed));
-
-struct aimdb_block {
-       u8 aimdb_id;
-       u16 aimdb_size;
-} __attribute__((packed));
-
-struct vch_panel_data {
-       u16 fp_timing_offset;
-       u8 fp_timing_size;
-       u16 dvo_timing_offset;
-       u8 dvo_timing_size;
-       u16 text_fitting_offset;
-       u8 text_fitting_size;
-       u16 graphics_fitting_offset;
-       u8 graphics_fitting_size;
-} __attribute__((packed));
-
-struct vch_bdb_22 {
-       struct aimdb_block aimdb_block;
-       struct vch_panel_data panels[16];
-} __attribute__((packed));
-
-struct bdb_sdvo_lvds_options {
-       u8 panel_backlight;
-       u8 h40_set_panel_type;
-       u8 panel_type;
-       u8 ssc_clk_freq;
-       u16 als_low_trip;
-       u16 als_high_trip;
-       u8 sclalarcoeff_tab_row_num;
-       u8 sclalarcoeff_tab_row_size;
-       u8 coefficient[8];
-       u8 panel_misc_bits_1;
-       u8 panel_misc_bits_2;
-       u8 panel_misc_bits_3;
-       u8 panel_misc_bits_4;
-} __attribute__((packed));
-
-
-extern bool psb_intel_init_bios(struct drm_device *dev);
-extern void psb_intel_destroy_bios(struct drm_device *dev);
-
-/*
- * Driver<->VBIOS interaction occurs through scratch bits in
- * GR18 & SWF*.
- */
-
-/* GR18 bits are set on display switch and hotkey events */
-#define GR18_DRIVER_SWITCH_EN  (1<<7) /* 0: VBIOS control, 1: driver control */
-#define GR18_HOTKEY_MASK       0x78 /* See also SWF4 15:0 */
-#define   GR18_HK_NONE         (0x0<<3)
-#define   GR18_HK_LFP_STRETCH  (0x1<<3)
-#define   GR18_HK_TOGGLE_DISP  (0x2<<3)
-#define   GR18_HK_DISP_SWITCH  (0x4<<3) /* see SWF14 15:0 for what to enable */
-#define   GR18_HK_POPUP_DISABLED (0x6<<3)
-#define   GR18_HK_POPUP_ENABLED        (0x7<<3)
-#define   GR18_HK_PFIT         (0x8<<3)
-#define   GR18_HK_APM_CHANGE   (0xa<<3)
-#define   GR18_HK_MULTIPLE     (0xc<<3)
-#define GR18_USER_INT_EN       (1<<2)
-#define GR18_A0000_FLUSH_EN    (1<<1)
-#define GR18_SMM_EN            (1<<0)
-
-/* Set by driver, cleared by VBIOS */
-#define SWF00_YRES_SHIFT       16
-#define SWF00_XRES_SHIFT       0
-#define SWF00_RES_MASK         0xffff
-
-/* Set by VBIOS at boot time and driver at runtime */
-#define SWF01_TV2_FORMAT_SHIFT 8
-#define SWF01_TV1_FORMAT_SHIFT 0
-#define SWF01_TV_FORMAT_MASK   0xffff
-
-#define SWF10_VBIOS_BLC_I2C_EN (1<<29)
-#define SWF10_GTT_OVERRIDE_EN  (1<<28)
-#define SWF10_LFP_DPMS_OVR     (1<<27) /* override DPMS on display switch */
-#define SWF10_ACTIVE_TOGGLE_LIST_MASK (7<<24)
-#define   SWF10_OLD_TOGGLE     0x0
-#define   SWF10_TOGGLE_LIST_1  0x1
-#define   SWF10_TOGGLE_LIST_2  0x2
-#define   SWF10_TOGGLE_LIST_3  0x3
-#define   SWF10_TOGGLE_LIST_4  0x4
-#define SWF10_PANNING_EN       (1<<23)
-#define SWF10_DRIVER_LOADED    (1<<22)
-#define SWF10_EXTENDED_DESKTOP (1<<21)
-#define SWF10_EXCLUSIVE_MODE   (1<<20)
-#define SWF10_OVERLAY_EN       (1<<19)
-#define SWF10_PLANEB_HOLDOFF   (1<<18)
-#define SWF10_PLANEA_HOLDOFF   (1<<17)
-#define SWF10_VGA_HOLDOFF      (1<<16)
-#define SWF10_ACTIVE_DISP_MASK 0xffff
-#define   SWF10_PIPEB_LFP2     (1<<15)
-#define   SWF10_PIPEB_EFP2     (1<<14)
-#define   SWF10_PIPEB_TV2      (1<<13)
-#define   SWF10_PIPEB_CRT2     (1<<12)
-#define   SWF10_PIPEB_LFP      (1<<11)
-#define   SWF10_PIPEB_EFP      (1<<10)
-#define   SWF10_PIPEB_TV       (1<<9)
-#define   SWF10_PIPEB_CRT      (1<<8)
-#define   SWF10_PIPEA_LFP2     (1<<7)
-#define   SWF10_PIPEA_EFP2     (1<<6)
-#define   SWF10_PIPEA_TV2      (1<<5)
-#define   SWF10_PIPEA_CRT2     (1<<4)
-#define   SWF10_PIPEA_LFP      (1<<3)
-#define   SWF10_PIPEA_EFP      (1<<2)
-#define   SWF10_PIPEA_TV       (1<<1)
-#define   SWF10_PIPEA_CRT      (1<<0)
-
-#define SWF11_MEMORY_SIZE_SHIFT        16
-#define SWF11_SV_TEST_EN       (1<<15)
-#define SWF11_IS_AGP           (1<<14)
-#define SWF11_DISPLAY_HOLDOFF  (1<<13)
-#define SWF11_DPMS_REDUCED     (1<<12)
-#define SWF11_IS_VBE_MODE      (1<<11)
-#define SWF11_PIPEB_ACCESS     (1<<10) /* 0 here means pipe a */
-#define SWF11_DPMS_MASK                0x07
-#define   SWF11_DPMS_OFF       (1<<2)
-#define   SWF11_DPMS_SUSPEND   (1<<1)
-#define   SWF11_DPMS_STANDBY   (1<<0)
-#define   SWF11_DPMS_ON                0
-
-#define SWF14_GFX_PFIT_EN      (1<<31)
-#define SWF14_TEXT_PFIT_EN     (1<<30)
-#define SWF14_LID_STATUS_CLOSED        (1<<29) /* 0 here means open */
-#define SWF14_POPUP_EN         (1<<28)
-#define SWF14_DISPLAY_HOLDOFF  (1<<27)
-#define SWF14_DISP_DETECT_EN   (1<<26)
-#define SWF14_DOCKING_STATUS_DOCKED (1<<25) /* 0 here means undocked */
-#define SWF14_DRIVER_STATUS    (1<<24)
-#define SWF14_OS_TYPE_WIN9X    (1<<23)
-#define SWF14_OS_TYPE_WINNT    (1<<22)
-/* 21:19 rsvd */
-#define SWF14_PM_TYPE_MASK     0x00070000
-#define   SWF14_PM_ACPI_VIDEO  (0x4 << 16)
-#define   SWF14_PM_ACPI                (0x3 << 16)
-#define   SWF14_PM_APM_12      (0x2 << 16)
-#define   SWF14_PM_APM_11      (0x1 << 16)
-#define SWF14_HK_REQUEST_MASK  0x0000ffff /* see GR18 6:3 for event type */
-         /* if GR18 indicates a display switch */
-#define   SWF14_DS_PIPEB_LFP2_EN (1<<15)
-#define   SWF14_DS_PIPEB_EFP2_EN (1<<14)
-#define   SWF14_DS_PIPEB_TV2_EN  (1<<13)
-#define   SWF14_DS_PIPEB_CRT2_EN (1<<12)
-#define   SWF14_DS_PIPEB_LFP_EN  (1<<11)
-#define   SWF14_DS_PIPEB_EFP_EN  (1<<10)
-#define   SWF14_DS_PIPEB_TV_EN  (1<<9)
-#define   SWF14_DS_PIPEB_CRT_EN  (1<<8)
-#define   SWF14_DS_PIPEA_LFP2_EN (1<<7)
-#define   SWF14_DS_PIPEA_EFP2_EN (1<<6)
-#define   SWF14_DS_PIPEA_TV2_EN  (1<<5)
-#define   SWF14_DS_PIPEA_CRT2_EN (1<<4)
-#define   SWF14_DS_PIPEA_LFP_EN  (1<<3)
-#define   SWF14_DS_PIPEA_EFP_EN  (1<<2)
-#define   SWF14_DS_PIPEA_TV_EN  (1<<1)
-#define   SWF14_DS_PIPEA_CRT_EN  (1<<0)
-         /* if GR18 indicates a panel fitting request */
-#define   SWF14_PFIT_EN                (1<<0) /* 0 means disable */
-         /* if GR18 indicates an APM change request */
-#define   SWF14_APM_HIBERNATE  0x4
-#define   SWF14_APM_SUSPEND    0x3
-#define   SWF14_APM_STANDBY    0x1
-#define   SWF14_APM_RESTORE    0x0
-
-#endif /* _I830_BIOS_H_ */
diff --git a/drivers/staging/gma500/intel_i2c.c b/drivers/staging/gma500/intel_i2c.c
deleted file mode 100644 (file)
index 51cbf65..0000000
+++ /dev/null
@@ -1,170 +0,0 @@
-/*
- * Copyright Â© 2006-2007 Intel Corporation
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Authors:
- *     Eric Anholt <eric@anholt.net>
- */
-
-#include <linux/i2c.h>
-#include <linux/i2c-algo-bit.h>
-#include <linux/export.h>
-
-#include "psb_drv.h"
-#include "psb_intel_reg.h"
-
-/*
- * Intel GPIO access functions
- */
-
-#define I2C_RISEFALL_TIME 20
-
-static int get_clock(void *data)
-{
-       struct psb_intel_i2c_chan *chan = data;
-       struct drm_device *dev = chan->drm_dev;
-       u32 val;
-
-       val = REG_READ(chan->reg);
-       return (val & GPIO_CLOCK_VAL_IN) != 0;
-}
-
-static int get_data(void *data)
-{
-       struct psb_intel_i2c_chan *chan = data;
-       struct drm_device *dev = chan->drm_dev;
-       u32 val;
-
-       val = REG_READ(chan->reg);
-       return (val & GPIO_DATA_VAL_IN) != 0;
-}
-
-static void set_clock(void *data, int state_high)
-{
-       struct psb_intel_i2c_chan *chan = data;
-       struct drm_device *dev = chan->drm_dev;
-       u32 reserved = 0, clock_bits;
-
-       /* On most chips, these bits must be preserved in software. */
-       reserved =
-                   REG_READ(chan->reg) & (GPIO_DATA_PULLUP_DISABLE |
-                                          GPIO_CLOCK_PULLUP_DISABLE);
-
-       if (state_high)
-               clock_bits = GPIO_CLOCK_DIR_IN | GPIO_CLOCK_DIR_MASK;
-       else
-               clock_bits = GPIO_CLOCK_DIR_OUT | GPIO_CLOCK_DIR_MASK |
-                   GPIO_CLOCK_VAL_MASK;
-       REG_WRITE(chan->reg, reserved | clock_bits);
-       udelay(I2C_RISEFALL_TIME);      /* wait for the line to change state */
-}
-
-static void set_data(void *data, int state_high)
-{
-       struct psb_intel_i2c_chan *chan = data;
-       struct drm_device *dev = chan->drm_dev;
-       u32 reserved = 0, data_bits;
-
-       /* On most chips, these bits must be preserved in software. */
-       reserved =
-                   REG_READ(chan->reg) & (GPIO_DATA_PULLUP_DISABLE |
-                                          GPIO_CLOCK_PULLUP_DISABLE);
-
-       if (state_high)
-               data_bits = GPIO_DATA_DIR_IN | GPIO_DATA_DIR_MASK;
-       else
-               data_bits =
-                   GPIO_DATA_DIR_OUT | GPIO_DATA_DIR_MASK |
-                   GPIO_DATA_VAL_MASK;
-
-       REG_WRITE(chan->reg, reserved | data_bits);
-       udelay(I2C_RISEFALL_TIME);      /* wait for the line to change state */
-}
-
-/**
- * psb_intel_i2c_create - instantiate an Intel i2c bus using the specified GPIO reg
- * @dev: DRM device
- * @output: driver specific output device
- * @reg: GPIO reg to use
- * @name: name for this bus
- *
- * Creates and registers a new i2c bus with the Linux i2c layer, for use
- * in output probing and control (e.g. DDC or SDVO control functions).
- *
- * Possible values for @reg include:
- *   %GPIOA
- *   %GPIOB
- *   %GPIOC
- *   %GPIOD
- *   %GPIOE
- *   %GPIOF
- *   %GPIOG
- *   %GPIOH
- * see PRM for details on how these different busses are used.
- */
-struct psb_intel_i2c_chan *psb_intel_i2c_create(struct drm_device *dev,
-                                       const u32 reg, const char *name)
-{
-       struct psb_intel_i2c_chan *chan;
-
-       chan = kzalloc(sizeof(struct psb_intel_i2c_chan), GFP_KERNEL);
-       if (!chan)
-               goto out_free;
-
-       chan->drm_dev = dev;
-       chan->reg = reg;
-       snprintf(chan->adapter.name, I2C_NAME_SIZE, "intel drm %s", name);
-       chan->adapter.owner = THIS_MODULE;
-       chan->adapter.algo_data = &chan->algo;
-       chan->adapter.dev.parent = &dev->pdev->dev;
-       chan->algo.setsda = set_data;
-       chan->algo.setscl = set_clock;
-       chan->algo.getsda = get_data;
-       chan->algo.getscl = get_clock;
-       chan->algo.udelay = 20;
-       chan->algo.timeout = usecs_to_jiffies(2200);
-       chan->algo.data = chan;
-
-       i2c_set_adapdata(&chan->adapter, chan);
-
-       if (i2c_bit_add_bus(&chan->adapter))
-               goto out_free;
-
-       /* JJJ:  raise SCL and SDA? */
-       set_data(chan, 1);
-       set_clock(chan, 1);
-       udelay(20);
-
-       return chan;
-
-out_free:
-       kfree(chan);
-       return NULL;
-}
-
-/**
- * psb_intel_i2c_destroy - unregister and free i2c bus resources
- * @output: channel to free
- *
- * Unregister the adapter from the i2c layer, then free the structure.
- */
-void psb_intel_i2c_destroy(struct psb_intel_i2c_chan *chan)
-{
-       if (!chan)
-               return;
-
-       i2c_del_adapter(&chan->adapter);
-       kfree(chan);
-}
diff --git a/drivers/staging/gma500/intel_opregion.c b/drivers/staging/gma500/intel_opregion.c
deleted file mode 100644 (file)
index d946bc1..0000000
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright 2010 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * FIXME: resolve with the i915 version
- */
-
-#include "psb_drv.h"
-
-struct opregion_header {
-       u8 signature[16];
-       u32 size;
-       u32 opregion_ver;
-       u8 bios_ver[32];
-       u8 vbios_ver[16];
-       u8 driver_ver[16];
-       u32 mboxes;
-       u8 reserved[164];
-} __packed;
-
-struct opregion_apci {
-       /*FIXME: add it later*/
-} __packed;
-
-struct opregion_swsci {
-       /*FIXME: add it later*/
-} __packed;
-
-struct opregion_acpi {
-       /*FIXME: add it later*/
-} __packed;
-
-int gma_intel_opregion_init(struct drm_device *dev)
-{
-       struct drm_psb_private *dev_priv = dev->dev_private;
-       u32 opregion_phy;
-       void *base;
-       u32 *lid_state;
-
-       dev_priv->lid_state = NULL;
-
-       pci_read_config_dword(dev->pdev, 0xfc, &opregion_phy);
-       if (opregion_phy == 0)
-               return -ENOTSUPP;
-
-       base = ioremap(opregion_phy, 8*1024);
-       if (!base)
-               return -ENOMEM;
-
-       lid_state = base + 0x01ac;
-
-       dev_priv->lid_state = lid_state;
-       dev_priv->lid_last_state = readl(lid_state);
-       return 0;
-}
-
-int gma_intel_opregion_exit(struct drm_device *dev)
-{
-       struct drm_psb_private *dev_priv = dev->dev_private;
-       if (dev_priv->lid_state)
-               iounmap(dev_priv->lid_state);
-       return 0;
-}
diff --git a/drivers/staging/gma500/mdfld_device.c b/drivers/staging/gma500/mdfld_device.c
deleted file mode 100644 (file)
index f47aeb7..0000000
+++ /dev/null
@@ -1,714 +0,0 @@
-/**************************************************************************
- * Copyright (c) 2011, Intel Corporation.
- * All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- **************************************************************************/
-
-#include <linux/backlight.h>
-#include <drm/drmP.h>
-#include <drm/drm.h>
-#include "psb_reg.h"
-#include "psb_intel_reg.h"
-#include "psb_drm.h"
-#include "psb_drv.h"
-#include "mdfld_output.h"
-#include "mdfld_dsi_output.h"
-#include "mid_bios.h"
-
-/*
- *     Provide the Medfield specific backlight management
- */
-
-#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
-
-static int mdfld_brightness;
-struct backlight_device *mdfld_backlight_device;
-
-static int mfld_set_brightness(struct backlight_device *bd)
-{
-       struct drm_device *dev = bl_get_data(mdfld_backlight_device);
-       struct drm_psb_private *dev_priv = dev->dev_private;
-       int level = bd->props.brightness;
-
-       /* Percentage 1-100% being valid */
-       if (level < 1)
-               level = 1;
-
-       if (gma_power_begin(dev, 0)) {
-               /* Calculate and set the brightness value */
-               u32 adjusted_level;
-
-               /* Adjust the backlight level with the percent in
-                * dev_priv->blc_adj2;
-                */
-               adjusted_level = level * dev_priv->blc_adj2;
-               adjusted_level = adjusted_level / 100;
-#if 0
-#ifndef CONFIG_MDFLD_DSI_DPU
-               if(!(dev_priv->dsr_fb_update & MDFLD_DSR_MIPI_CONTROL) && 
-                       (dev_priv->dbi_panel_on || dev_priv->dbi_panel_on2)){
-                       mdfld_dsi_dbi_exit_dsr(dev,MDFLD_DSR_MIPI_CONTROL, 0, 0);
-                       dev_dbg(dev->dev, "Out of DSR before set brightness to %d.\n",adjusted_level);
-               }
-#endif
-               mdfld_dsi_brightness_control(dev, 0, adjusted_level);
-
-               if ((dev_priv->dbi_panel_on2) || (dev_priv->dpi_panel_on2))
-                       mdfld_dsi_brightness_control(dev, 2, adjusted_level);
-#endif
-               gma_power_end(dev);
-       }
-       mdfld_brightness = level;
-       return 0;
-}
-
-int psb_get_brightness(struct backlight_device *bd)
-{
-       /* return locally cached var instead of HW read (due to DPST etc.) */
-       /* FIXME: ideally return actual value in case firmware fiddled with
-          it */
-       return mdfld_brightness;
-}
-
-static const struct backlight_ops mfld_ops = {
-       .get_brightness = psb_get_brightness,
-       .update_status  = mfld_set_brightness,
-};
-
-static int mdfld_backlight_init(struct drm_device *dev)
-{
-       struct drm_psb_private *dev_priv = dev->dev_private;
-       struct backlight_properties props;
-       memset(&props, 0, sizeof(struct backlight_properties));
-       props.max_brightness = 100;
-       props.type = BACKLIGHT_PLATFORM;
-
-       mdfld_backlight_device = backlight_device_register("mfld-bl",
-                                       NULL, (void *)dev, &mfld_ops, &props);
-                                       
-       if (IS_ERR(mdfld_backlight_device))
-               return PTR_ERR(mdfld_backlight_device);
-
-       dev_priv->blc_adj1 = 100;
-       dev_priv->blc_adj2 = 100;
-       mdfld_backlight_device->props.brightness = 100;
-       mdfld_backlight_device->props.max_brightness = 100;
-       backlight_update_status(mdfld_backlight_device);
-       dev_priv->backlight_device = mdfld_backlight_device;
-       return 0;
-}
-
-#endif
-
-/*
- *     Provide the Medfield specific chip logic and low level methods for
- *     power management.
- */
-
-static void mdfld_init_pm(struct drm_device *dev)
-{
-       /* No work needed here yet */
-}
-
-/**
- * mdfld_save_display_registers        -       save registers for pipe
- * @dev: our device
- * @pipe: pipe to save
- *
- * Save the pipe state of the device before we power it off. Keep everything
- * we need to put it back again
- */
-static int mdfld_save_display_registers(struct drm_device *dev, int pipe)
-{
-       struct drm_psb_private *dev_priv = dev->dev_private;
-       int i;
-
-       /* register */
-       u32 dpll_reg = MRST_DPLL_A;
-       u32 fp_reg = MRST_FPA0;
-       u32 pipeconf_reg = PIPEACONF;
-       u32 htot_reg = HTOTAL_A;
-       u32 hblank_reg = HBLANK_A;
-       u32 hsync_reg = HSYNC_A;
-       u32 vtot_reg = VTOTAL_A;
-       u32 vblank_reg = VBLANK_A;
-       u32 vsync_reg = VSYNC_A;
-       u32 pipesrc_reg = PIPEASRC;
-       u32 dspstride_reg = DSPASTRIDE;
-       u32 dsplinoff_reg = DSPALINOFF;
-       u32 dsptileoff_reg = DSPATILEOFF;
-       u32 dspsize_reg = DSPASIZE;
-       u32 dsppos_reg = DSPAPOS;
-       u32 dspsurf_reg = DSPASURF;
-       u32 mipi_reg = MIPI;
-       u32 dspcntr_reg = DSPACNTR;
-       u32 dspstatus_reg = PIPEASTAT;
-       u32 palette_reg = PALETTE_A;
-
-       /* pointer to values */
-       u32 *dpll_val = &dev_priv->saveDPLL_A;
-       u32 *fp_val = &dev_priv->saveFPA0;
-       u32 *pipeconf_val = &dev_priv->savePIPEACONF;
-       u32 *htot_val = &dev_priv->saveHTOTAL_A;
-       u32 *hblank_val = &dev_priv->saveHBLANK_A;
-       u32 *hsync_val = &dev_priv->saveHSYNC_A;
-       u32 *vtot_val = &dev_priv->saveVTOTAL_A;
-       u32 *vblank_val = &dev_priv->saveVBLANK_A;
-       u32 *vsync_val = &dev_priv->saveVSYNC_A;
-       u32 *pipesrc_val = &dev_priv->savePIPEASRC;
-       u32 *dspstride_val = &dev_priv->saveDSPASTRIDE;
-       u32 *dsplinoff_val = &dev_priv->saveDSPALINOFF;
-       u32 *dsptileoff_val = &dev_priv->saveDSPATILEOFF;
-       u32 *dspsize_val = &dev_priv->saveDSPASIZE;
-       u32 *dsppos_val = &dev_priv->saveDSPAPOS;
-       u32 *dspsurf_val = &dev_priv->saveDSPASURF;
-       u32 *mipi_val = &dev_priv->saveMIPI;
-       u32 *dspcntr_val = &dev_priv->saveDSPACNTR;
-       u32 *dspstatus_val = &dev_priv->saveDSPASTATUS;
-       u32 *palette_val = dev_priv->save_palette_a;
-
-       switch (pipe) {
-       case 0:
-               break;
-       case 1:
-               /* register */
-               dpll_reg = MDFLD_DPLL_B;
-               fp_reg = MDFLD_DPLL_DIV0;
-               pipeconf_reg = PIPEBCONF;
-               htot_reg = HTOTAL_B;
-               hblank_reg = HBLANK_B;
-               hsync_reg = HSYNC_B;
-               vtot_reg = VTOTAL_B;
-               vblank_reg = VBLANK_B;
-               vsync_reg = VSYNC_B;
-               pipesrc_reg = PIPEBSRC;
-               dspstride_reg = DSPBSTRIDE;
-               dsplinoff_reg = DSPBLINOFF;
-               dsptileoff_reg = DSPBTILEOFF;
-               dspsize_reg = DSPBSIZE;
-               dsppos_reg = DSPBPOS;
-               dspsurf_reg = DSPBSURF;
-               dspcntr_reg = DSPBCNTR;
-               dspstatus_reg = PIPEBSTAT;
-               palette_reg = PALETTE_B;
-
-               /* values */
-               dpll_val = &dev_priv->saveDPLL_B;
-               fp_val = &dev_priv->saveFPB0;
-               pipeconf_val = &dev_priv->savePIPEBCONF;
-               htot_val = &dev_priv->saveHTOTAL_B;
-               hblank_val = &dev_priv->saveHBLANK_B;
-               hsync_val = &dev_priv->saveHSYNC_B;
-               vtot_val = &dev_priv->saveVTOTAL_B;
-               vblank_val = &dev_priv->saveVBLANK_B;
-               vsync_val = &dev_priv->saveVSYNC_B;
-               pipesrc_val = &dev_priv->savePIPEBSRC;
-               dspstride_val = &dev_priv->saveDSPBSTRIDE;
-               dsplinoff_val = &dev_priv->saveDSPBLINOFF;
-               dsptileoff_val = &dev_priv->saveDSPBTILEOFF;
-               dspsize_val = &dev_priv->saveDSPBSIZE;
-               dsppos_val = &dev_priv->saveDSPBPOS;
-               dspsurf_val = &dev_priv->saveDSPBSURF;
-               dspcntr_val = &dev_priv->saveDSPBCNTR;
-               dspstatus_val = &dev_priv->saveDSPBSTATUS;
-               palette_val = dev_priv->save_palette_b;
-               break;
-       case 2:
-               /* register */
-               pipeconf_reg = PIPECCONF;
-               htot_reg = HTOTAL_C;
-               hblank_reg = HBLANK_C;
-               hsync_reg = HSYNC_C;
-               vtot_reg = VTOTAL_C;
-               vblank_reg = VBLANK_C;
-               vsync_reg = VSYNC_C;
-               pipesrc_reg = PIPECSRC;
-               dspstride_reg = DSPCSTRIDE;
-               dsplinoff_reg = DSPCLINOFF;
-               dsptileoff_reg = DSPCTILEOFF;
-               dspsize_reg = DSPCSIZE;
-               dsppos_reg = DSPCPOS;
-               dspsurf_reg = DSPCSURF;
-               mipi_reg = MIPI_C;
-               dspcntr_reg = DSPCCNTR;
-               dspstatus_reg = PIPECSTAT;
-               palette_reg = PALETTE_C;
-
-               /* pointer to values */
-               pipeconf_val = &dev_priv->savePIPECCONF;
-               htot_val = &dev_priv->saveHTOTAL_C;
-               hblank_val = &dev_priv->saveHBLANK_C;
-               hsync_val = &dev_priv->saveHSYNC_C;
-               vtot_val = &dev_priv->saveVTOTAL_C;
-               vblank_val = &dev_priv->saveVBLANK_C;
-               vsync_val = &dev_priv->saveVSYNC_C;
-               pipesrc_val = &dev_priv->savePIPECSRC;
-               dspstride_val = &dev_priv->saveDSPCSTRIDE;
-               dsplinoff_val = &dev_priv->saveDSPCLINOFF;
-               dsptileoff_val = &dev_priv->saveDSPCTILEOFF;
-               dspsize_val = &dev_priv->saveDSPCSIZE;
-               dsppos_val = &dev_priv->saveDSPCPOS;
-               dspsurf_val = &dev_priv->saveDSPCSURF;
-               mipi_val = &dev_priv->saveMIPI_C;
-               dspcntr_val = &dev_priv->saveDSPCCNTR;
-               dspstatus_val = &dev_priv->saveDSPCSTATUS;
-               palette_val = dev_priv->save_palette_c;
-               break;
-       default:
-               DRM_ERROR("%s, invalid pipe number.\n", __func__);
-               return -EINVAL;
-       }
-
-       /* Pipe & plane A info */
-       *dpll_val = PSB_RVDC32(dpll_reg);
-       *fp_val = PSB_RVDC32(fp_reg);
-       *pipeconf_val = PSB_RVDC32(pipeconf_reg);
-       *htot_val = PSB_RVDC32(htot_reg);
-       *hblank_val = PSB_RVDC32(hblank_reg);
-       *hsync_val = PSB_RVDC32(hsync_reg);
-       *vtot_val = PSB_RVDC32(vtot_reg);
-       *vblank_val = PSB_RVDC32(vblank_reg);
-       *vsync_val = PSB_RVDC32(vsync_reg);
-       *pipesrc_val = PSB_RVDC32(pipesrc_reg);
-       *dspstride_val = PSB_RVDC32(dspstride_reg);
-       *dsplinoff_val = PSB_RVDC32(dsplinoff_reg);
-       *dsptileoff_val = PSB_RVDC32(dsptileoff_reg);
-       *dspsize_val = PSB_RVDC32(dspsize_reg);
-       *dsppos_val = PSB_RVDC32(dsppos_reg);
-       *dspsurf_val = PSB_RVDC32(dspsurf_reg);
-       *dspcntr_val = PSB_RVDC32(dspcntr_reg);
-       *dspstatus_val = PSB_RVDC32(dspstatus_reg);
-
-       /*save palette (gamma) */
-       for (i = 0; i < 256; i++)
-               palette_val[i] = PSB_RVDC32(palette_reg + (i<<2));
-
-       if (pipe == 1) {
-               dev_priv->savePFIT_CONTROL = PSB_RVDC32(PFIT_CONTROL);
-               dev_priv->savePFIT_PGM_RATIOS = PSB_RVDC32(PFIT_PGM_RATIOS);
-               dev_priv->saveHDMIPHYMISCCTL = PSB_RVDC32(HDMIPHYMISCCTL);
-               dev_priv->saveHDMIB_CONTROL = PSB_RVDC32(HDMIB_CONTROL);
-               return 0;
-       }
-       *mipi_val = PSB_RVDC32(mipi_reg);
-       return 0;
-}
-
-/**
- * mdfld_save_cursor_overlay_registers -       save cursor overlay info
- * @dev: our device
- *
- * Save the cursor and overlay register state
- */
-static int mdfld_save_cursor_overlay_registers(struct drm_device *dev)
-{
-       struct drm_psb_private *dev_priv = dev->dev_private;
-
-       /* Save cursor regs */
-       dev_priv->saveDSPACURSOR_CTRL = PSB_RVDC32(CURACNTR);
-       dev_priv->saveDSPACURSOR_BASE = PSB_RVDC32(CURABASE);
-       dev_priv->saveDSPACURSOR_POS = PSB_RVDC32(CURAPOS);
-
-       dev_priv->saveDSPBCURSOR_CTRL = PSB_RVDC32(CURBCNTR);
-       dev_priv->saveDSPBCURSOR_BASE = PSB_RVDC32(CURBBASE);
-       dev_priv->saveDSPBCURSOR_POS = PSB_RVDC32(CURBPOS);
-
-       dev_priv->saveDSPCCURSOR_CTRL = PSB_RVDC32(CURCCNTR);
-       dev_priv->saveDSPCCURSOR_BASE = PSB_RVDC32(CURCBASE);
-       dev_priv->saveDSPCCURSOR_POS = PSB_RVDC32(CURCPOS);
-
-       /* HW overlay */
-       dev_priv->saveOV_OVADD = PSB_RVDC32(OV_OVADD);
-       dev_priv->saveOV_OGAMC0 = PSB_RVDC32(OV_OGAMC0);
-       dev_priv->saveOV_OGAMC1 = PSB_RVDC32(OV_OGAMC1);
-       dev_priv->saveOV_OGAMC2 = PSB_RVDC32(OV_OGAMC2);
-       dev_priv->saveOV_OGAMC3 = PSB_RVDC32(OV_OGAMC3);
-       dev_priv->saveOV_OGAMC4 = PSB_RVDC32(OV_OGAMC4);
-       dev_priv->saveOV_OGAMC5 = PSB_RVDC32(OV_OGAMC5);
-
-       dev_priv->saveOV_OVADD_C = PSB_RVDC32(OV_OVADD + OV_C_OFFSET);
-       dev_priv->saveOV_OGAMC0_C = PSB_RVDC32(OV_OGAMC0 + OV_C_OFFSET);
-       dev_priv->saveOV_OGAMC1_C = PSB_RVDC32(OV_OGAMC1 + OV_C_OFFSET);
-       dev_priv->saveOV_OGAMC2_C = PSB_RVDC32(OV_OGAMC2 + OV_C_OFFSET);
-       dev_priv->saveOV_OGAMC3_C = PSB_RVDC32(OV_OGAMC3 + OV_C_OFFSET);
-       dev_priv->saveOV_OGAMC4_C = PSB_RVDC32(OV_OGAMC4 + OV_C_OFFSET);
-       dev_priv->saveOV_OGAMC5_C = PSB_RVDC32(OV_OGAMC5 + OV_C_OFFSET);
-
-       return 0;
-}
-/*
- * mdfld_restore_display_registers     -       restore the state of a pipe
- * @dev: our device
- * @pipe: the pipe to restore
- *
- * Restore the state of a pipe to that which was saved by the register save
- * functions.
- */
-static int mdfld_restore_display_registers(struct drm_device *dev, int pipe)
-{
-       /* To get  panel out of ULPS mode */
-       struct drm_psb_private *dev_priv = dev->dev_private;
-       struct mdfld_dsi_config *dsi_config = NULL;
-       u32 i = 0;
-       u32 dpll = 0;
-       u32 timeout = 0;
-       u32 reg_offset = 0;
-
-       /* register */
-       u32 dpll_reg = MRST_DPLL_A;
-       u32 fp_reg = MRST_FPA0;
-       u32 pipeconf_reg = PIPEACONF;
-       u32 htot_reg = HTOTAL_A;
-       u32 hblank_reg = HBLANK_A;
-       u32 hsync_reg = HSYNC_A;
-       u32 vtot_reg = VTOTAL_A;
-       u32 vblank_reg = VBLANK_A;
-       u32 vsync_reg = VSYNC_A;
-       u32 pipesrc_reg = PIPEASRC;
-       u32 dspstride_reg = DSPASTRIDE;
-       u32 dsplinoff_reg = DSPALINOFF;
-       u32 dsptileoff_reg = DSPATILEOFF;
-       u32 dspsize_reg = DSPASIZE;
-       u32 dsppos_reg = DSPAPOS;
-       u32 dspsurf_reg = DSPASURF;
-       u32 dspstatus_reg = PIPEASTAT;
-       u32 mipi_reg = MIPI;
-       u32 dspcntr_reg = DSPACNTR;
-       u32 palette_reg = PALETTE_A;
-
-       /* values */
-       u32 dpll_val = dev_priv->saveDPLL_A & ~DPLL_VCO_ENABLE;
-       u32 fp_val = dev_priv->saveFPA0;
-       u32 pipeconf_val = dev_priv->savePIPEACONF;
-       u32 htot_val = dev_priv->saveHTOTAL_A;
-       u32 hblank_val = dev_priv->saveHBLANK_A;
-       u32 hsync_val = dev_priv->saveHSYNC_A;
-       u32 vtot_val = dev_priv->saveVTOTAL_A;
-       u32 vblank_val = dev_priv->saveVBLANK_A;
-       u32 vsync_val = dev_priv->saveVSYNC_A;
-       u32 pipesrc_val = dev_priv->savePIPEASRC;
-       u32 dspstride_val = dev_priv->saveDSPASTRIDE;
-       u32 dsplinoff_val = dev_priv->saveDSPALINOFF;
-       u32 dsptileoff_val = dev_priv->saveDSPATILEOFF;
-       u32 dspsize_val = dev_priv->saveDSPASIZE;
-       u32 dsppos_val = dev_priv->saveDSPAPOS;
-       u32 dspsurf_val = dev_priv->saveDSPASURF;
-       u32 dspstatus_val = dev_priv->saveDSPASTATUS;
-       u32 mipi_val = dev_priv->saveMIPI;
-       u32 dspcntr_val = dev_priv->saveDSPACNTR;
-       u32 *palette_val = dev_priv->save_palette_a;
-
-       switch (pipe) {
-       case 0:
-               dsi_config = dev_priv->dsi_configs[0];
-               break;
-       case 1:
-               /* register */
-               dpll_reg = MDFLD_DPLL_B;
-               fp_reg = MDFLD_DPLL_DIV0;
-               pipeconf_reg = PIPEBCONF;
-               htot_reg = HTOTAL_B;
-               hblank_reg = HBLANK_B;
-               hsync_reg = HSYNC_B;
-               vtot_reg = VTOTAL_B;
-               vblank_reg = VBLANK_B;
-               vsync_reg = VSYNC_B;
-               pipesrc_reg = PIPEBSRC;
-               dspstride_reg = DSPBSTRIDE;
-               dsplinoff_reg = DSPBLINOFF;
-               dsptileoff_reg = DSPBTILEOFF;
-               dspsize_reg = DSPBSIZE;
-               dsppos_reg = DSPBPOS;
-               dspsurf_reg = DSPBSURF;
-               dspcntr_reg = DSPBCNTR;
-               palette_reg = PALETTE_B;
-               dspstatus_reg = PIPEBSTAT;
-
-               /* values */
-               dpll_val = dev_priv->saveDPLL_B & ~DPLL_VCO_ENABLE;
-               fp_val = dev_priv->saveFPB0;
-               pipeconf_val = dev_priv->savePIPEBCONF;
-               htot_val = dev_priv->saveHTOTAL_B;
-               hblank_val = dev_priv->saveHBLANK_B;
-               hsync_val = dev_priv->saveHSYNC_B;
-               vtot_val = dev_priv->saveVTOTAL_B;
-               vblank_val = dev_priv->saveVBLANK_B;
-               vsync_val = dev_priv->saveVSYNC_B;
-               pipesrc_val = dev_priv->savePIPEBSRC;
-               dspstride_val = dev_priv->saveDSPBSTRIDE;
-               dsplinoff_val = dev_priv->saveDSPBLINOFF;
-               dsptileoff_val = dev_priv->saveDSPBTILEOFF;
-               dspsize_val = dev_priv->saveDSPBSIZE;
-               dsppos_val = dev_priv->saveDSPBPOS;
-               dspsurf_val = dev_priv->saveDSPBSURF;
-               dspcntr_val = dev_priv->saveDSPBCNTR;
-               dspstatus_val = dev_priv->saveDSPBSTATUS;
-               palette_val = dev_priv->save_palette_b;
-               break;
-       case 2:
-               reg_offset = MIPIC_REG_OFFSET;
-
-               /* register */
-               pipeconf_reg = PIPECCONF;
-               htot_reg = HTOTAL_C;
-               hblank_reg = HBLANK_C;
-               hsync_reg = HSYNC_C;
-               vtot_reg = VTOTAL_C;
-               vblank_reg = VBLANK_C;
-               vsync_reg = VSYNC_C;
-               pipesrc_reg = PIPECSRC;
-               dspstride_reg = DSPCSTRIDE;
-               dsplinoff_reg = DSPCLINOFF;
-               dsptileoff_reg = DSPCTILEOFF;
-               dspsize_reg = DSPCSIZE;
-               dsppos_reg = DSPCPOS;
-               dspsurf_reg = DSPCSURF;
-               mipi_reg = MIPI_C;
-               dspcntr_reg = DSPCCNTR;
-               palette_reg = PALETTE_C;
-               dspstatus_reg = PIPECSTAT;
-
-               /* values */
-               pipeconf_val = dev_priv->savePIPECCONF;
-               htot_val = dev_priv->saveHTOTAL_C;
-               hblank_val = dev_priv->saveHBLANK_C;
-               hsync_val = dev_priv->saveHSYNC_C;
-               vtot_val = dev_priv->saveVTOTAL_C;
-               vblank_val = dev_priv->saveVBLANK_C;
-               vsync_val = dev_priv->saveVSYNC_C;
-               pipesrc_val = dev_priv->savePIPECSRC;
-               dspstride_val = dev_priv->saveDSPCSTRIDE;
-               dsplinoff_val = dev_priv->saveDSPCLINOFF;
-               dsptileoff_val = dev_priv->saveDSPCTILEOFF;
-               dspsize_val = dev_priv->saveDSPCSIZE;
-               dsppos_val = dev_priv->saveDSPCPOS;
-               dspsurf_val = dev_priv->saveDSPCSURF;
-               dspstatus_val = dev_priv->saveDSPCSTATUS;
-               mipi_val = dev_priv->saveMIPI_C;
-               dspcntr_val = dev_priv->saveDSPCCNTR;
-               palette_val = dev_priv->save_palette_c;
-
-               dsi_config = dev_priv->dsi_configs[1];
-               break;
-       default:
-               DRM_ERROR("%s, invalid pipe number.\n", __func__);
-               return -EINVAL;
-       }
-
-       /* Make sure VGA plane is off. it initializes to on after reset!*/
-       PSB_WVDC32(0x80000000, VGACNTRL);
-       if (pipe == 1) {
-               PSB_WVDC32(dpll_val & ~DPLL_VCO_ENABLE, dpll_reg);
-               PSB_RVDC32(dpll_reg);
-
-               PSB_WVDC32(fp_val, fp_reg);
-       } else {
-               dpll = PSB_RVDC32(dpll_reg);
-
-               if (!(dpll & DPLL_VCO_ENABLE)) {
-
-                       /* When ungating power of DPLL, needs to wait 0.5us before enable the VCO */
-                       if (dpll & MDFLD_PWR_GATE_EN) {
-                               dpll &= ~MDFLD_PWR_GATE_EN;
-                               PSB_WVDC32(dpll, dpll_reg);
-                               udelay(500);    /* FIXME: 1 ? */
-                       }
-
-                       PSB_WVDC32(fp_val, fp_reg);
-                       PSB_WVDC32(dpll_val, dpll_reg);
-                       /* FIXME_MDFLD PO - change 500 to 1 after PO */
-                       udelay(500);
-
-                       dpll_val |= DPLL_VCO_ENABLE;
-                       PSB_WVDC32(dpll_val, dpll_reg);
-                       PSB_RVDC32(dpll_reg);
-
-                       /* wait for DSI PLL to lock */
-                       while ((timeout < 20000) && !(PSB_RVDC32(pipeconf_reg) & PIPECONF_DSIPLL_LOCK)) {
-                               udelay(150);
-                               timeout++;
-                       }
-
-                       if (timeout == 20000) {
-                               DRM_ERROR("%s, can't lock DSIPLL.\n",
-                                                       __func__);
-                               return -EINVAL;
-                       }
-               }
-       }
-       /* Restore mode */
-       PSB_WVDC32(htot_val, htot_reg);
-       PSB_WVDC32(hblank_val, hblank_reg);
-       PSB_WVDC32(hsync_val, hsync_reg);
-       PSB_WVDC32(vtot_val, vtot_reg);
-       PSB_WVDC32(vblank_val, vblank_reg);
-       PSB_WVDC32(vsync_val, vsync_reg);
-       PSB_WVDC32(pipesrc_val, pipesrc_reg);
-       PSB_WVDC32(dspstatus_val, dspstatus_reg);
-
-       /* Set up the plane */
-       PSB_WVDC32(dspstride_val, dspstride_reg);
-       PSB_WVDC32(dsplinoff_val, dsplinoff_reg);
-       PSB_WVDC32(dsptileoff_val, dsptileoff_reg);
-       PSB_WVDC32(dspsize_val, dspsize_reg);
-       PSB_WVDC32(dsppos_val, dsppos_reg);
-       PSB_WVDC32(dspsurf_val, dspsurf_reg);
-
-       if (pipe == 1) {
-               PSB_WVDC32(dev_priv->savePFIT_CONTROL, PFIT_CONTROL);
-               PSB_WVDC32(dev_priv->savePFIT_PGM_RATIOS, PFIT_PGM_RATIOS);
-               PSB_WVDC32(dev_priv->saveHDMIPHYMISCCTL, HDMIPHYMISCCTL);
-               PSB_WVDC32(dev_priv->saveHDMIB_CONTROL, HDMIB_CONTROL);
-
-       } else {
-               /* Set up pipe related registers */
-               PSB_WVDC32(mipi_val, mipi_reg);
-               /* Setup MIPI adapter + MIPI IP registers */
-               mdfld_dsi_controller_init(dsi_config, pipe);
-               msleep(20);
-       }
-       /* Enable the plane */
-       PSB_WVDC32(dspcntr_val, dspcntr_reg);
-       msleep(20);
-       /* Enable the pipe */
-       PSB_WVDC32(pipeconf_val, pipeconf_reg);
-
-       for (i = 0; i < 256; i++)
-               PSB_WVDC32(palette_val[i], palette_reg + (i<<2));
-       if (pipe == 1)
-               return 0;
-       if (!mdfld_panel_dpi(dev))
-               mdfld_enable_te(dev, pipe);
-       return 0;
-}
-
-/**
- * mdfld_restore_cursor_overlay_registers      -       restore cursor
- * @dev: our device
- *
- * Restore the cursor and overlay state that was saved earlier
- */
-static int mdfld_restore_cursor_overlay_registers(struct drm_device *dev)
-{
-       struct drm_psb_private *dev_priv = dev->dev_private;
-
-       /* Enable Cursor A */
-       PSB_WVDC32(dev_priv->saveDSPACURSOR_CTRL, CURACNTR);
-       PSB_WVDC32(dev_priv->saveDSPACURSOR_POS, CURAPOS);
-       PSB_WVDC32(dev_priv->saveDSPACURSOR_BASE, CURABASE);
-
-       PSB_WVDC32(dev_priv->saveDSPBCURSOR_CTRL, CURBCNTR);
-       PSB_WVDC32(dev_priv->saveDSPBCURSOR_POS, CURBPOS);
-       PSB_WVDC32(dev_priv->saveDSPBCURSOR_BASE, CURBBASE);
-
-       PSB_WVDC32(dev_priv->saveDSPCCURSOR_CTRL, CURCCNTR);
-       PSB_WVDC32(dev_priv->saveDSPCCURSOR_POS, CURCPOS);
-       PSB_WVDC32(dev_priv->saveDSPCCURSOR_BASE, CURCBASE);
-
-       /* Restore HW overlay */
-       PSB_WVDC32(dev_priv->saveOV_OVADD, OV_OVADD);
-       PSB_WVDC32(dev_priv->saveOV_OGAMC0, OV_OGAMC0);
-       PSB_WVDC32(dev_priv->saveOV_OGAMC1, OV_OGAMC1);
-       PSB_WVDC32(dev_priv->saveOV_OGAMC2, OV_OGAMC2);
-       PSB_WVDC32(dev_priv->saveOV_OGAMC3, OV_OGAMC3);
-       PSB_WVDC32(dev_priv->saveOV_OGAMC4, OV_OGAMC4);
-       PSB_WVDC32(dev_priv->saveOV_OGAMC5, OV_OGAMC5);
-
-       PSB_WVDC32(dev_priv->saveOV_OVADD_C, OV_OVADD + OV_C_OFFSET);
-       PSB_WVDC32(dev_priv->saveOV_OGAMC0_C, OV_OGAMC0 + OV_C_OFFSET);
-       PSB_WVDC32(dev_priv->saveOV_OGAMC1_C, OV_OGAMC1 + OV_C_OFFSET);
-       PSB_WVDC32(dev_priv->saveOV_OGAMC2_C, OV_OGAMC2 + OV_C_OFFSET);
-       PSB_WVDC32(dev_priv->saveOV_OGAMC3_C, OV_OGAMC3 + OV_C_OFFSET);
-       PSB_WVDC32(dev_priv->saveOV_OGAMC4_C, OV_OGAMC4 + OV_C_OFFSET);
-       PSB_WVDC32(dev_priv->saveOV_OGAMC5_C, OV_OGAMC5 + OV_C_OFFSET);
-
-       return 0;
-}
-
-/**
- *     mdfld_save_display_registers    -       save registers lost on suspend
- *     @dev: our DRM device
- *
- *     Save the state we need in order to be able to restore the interface
- *     upon resume from suspend
- */
-static int mdfld_save_registers(struct drm_device *dev)
-{
-       /* FIXME: We need to shut down panels here if using them
-          and once the right bits are merged */
-       mdfld_save_cursor_overlay_registers(dev);
-       mdfld_save_display_registers(dev, 0);
-       mdfld_save_display_registers(dev, 0);
-       mdfld_save_display_registers(dev, 2);
-       mdfld_save_display_registers(dev, 1);
-       mdfld_disable_crtc(dev, 0);
-       mdfld_disable_crtc(dev, 2);
-       mdfld_disable_crtc(dev, 1);
-       return 0;
-}
-
-/**
- *     mdfld_restore_display_registers -       restore lost register state
- *     @dev: our DRM device
- *
- *     Restore register state that was lost during suspend and resume.
- */
-static int mdfld_restore_registers(struct drm_device *dev)
-{
-       mdfld_restore_display_registers(dev, 1);
-       mdfld_restore_display_registers(dev, 0);
-       mdfld_restore_display_registers(dev, 2);
-       mdfld_restore_cursor_overlay_registers(dev);
-       return 0;
-}
-
-static int mdfld_power_down(struct drm_device *dev)
-{
-       /* FIXME */
-       return 0;
-}
-
-static int mdfld_power_up(struct drm_device *dev)
-{
-       /* FIXME */
-       return 0;
-}
-
-const struct psb_ops mdfld_chip_ops = {
-       .name = "Medfield",
-       .accel_2d = 0,
-       .pipes = 3,
-       .crtcs = 2,
-       .sgx_offset = MRST_SGX_OFFSET,
-
-       .chip_setup = mid_chip_setup,
-
-       .crtc_helper = &mdfld_helper_funcs,
-       .crtc_funcs = &mdfld_intel_crtc_funcs,
-
-       .output_init = mdfld_output_init,
-
-#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
-       .backlight_init = mdfld_backlight_init,
-#endif
-
-       .init_pm = mdfld_init_pm,
-       .save_regs = mdfld_save_registers,
-       .restore_regs = mdfld_restore_registers,
-       .power_down = mdfld_power_down,
-       .power_up = mdfld_power_up,
-};
-
diff --git a/drivers/staging/gma500/mdfld_dsi_dbi.c b/drivers/staging/gma500/mdfld_dsi_dbi.c
deleted file mode 100644 (file)
index fd211f3..0000000
+++ /dev/null
@@ -1,761 +0,0 @@
-/*
- * Copyright Â© 2010 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Authors:
- *  jim liu <jim.liu@intel.com>
- *  Jackie Li<yaodong.li@intel.com>
- */
-
-#include "mdfld_dsi_dbi.h"
-#include "mdfld_dsi_dbi_dpu.h"
-#include "mdfld_dsi_pkg_sender.h"
-
-#include "power.h"
-#include <linux/pm_runtime.h>
-
-int enable_gfx_rtpm;
-
-extern struct drm_device *gpDrmDevice;
-extern int gfxrtdelay;
-int enter_dsr;
-struct mdfld_dsi_dbi_output *gdbi_output;
-extern bool gbgfxsuspended;
-extern int enable_gfx_rtpm;
-extern int gfxrtdelay;
-
-#define MDFLD_DSR_MAX_IDLE_COUNT       2
-
-/*
- * set refreshing area
- */
-int mdfld_dsi_dbi_update_area(struct mdfld_dsi_dbi_output *dbi_output,
-                               u16 x1, u16 y1, u16 x2, u16 y2)
-{
-       struct mdfld_dsi_pkg_sender *sender =
-               mdfld_dsi_encoder_get_pkg_sender(&dbi_output->base);
-       u8 param[4];
-       u8 cmd;
-       int err;
-
-       if (!sender) {
-               WARN_ON(1);
-               return -EINVAL;
-       }
-
-       /* Set column */
-       cmd = DCS_SET_COLUMN_ADDRESS;
-       param[0] = x1 >> 8;
-       param[1] = x1;
-       param[2] = x2 >> 8;
-       param[3] = x2;
-
-       err = mdfld_dsi_send_dcs(sender,
-                                cmd,
-                                param,
-                                4,
-                                CMD_DATA_SRC_SYSTEM_MEM,
-                                MDFLD_DSI_QUEUE_PACKAGE);
-       if (err) {
-               dev_err(sender->dev->dev, "DCS 0x%x sent failed\n", cmd);
-               goto err_out;
-       }
-
-       /* Set page */
-       cmd = DCS_SET_PAGE_ADDRESS;
-       param[0] = y1 >> 8;
-       param[1] = y1;
-       param[2] = y2 >> 8;
-       param[3] = y2;
-
-       err = mdfld_dsi_send_dcs(sender,
-                                cmd,
-                                param,
-                                4,
-                                CMD_DATA_SRC_SYSTEM_MEM,
-                                MDFLD_DSI_QUEUE_PACKAGE);
-       if (err) {
-               dev_err(sender->dev->dev, "DCS 0x%x sent failed\n", cmd);
-               goto err_out;
-       }
-
-       /*update screen*/
-       err = mdfld_dsi_send_dcs(sender,
-                                write_mem_start,
-                                NULL,
-                                0,
-                                CMD_DATA_SRC_PIPE,
-                                MDFLD_DSI_QUEUE_PACKAGE);
-       if (err) {
-               dev_err(sender->dev->dev, "DCS 0x%x sent failed\n", cmd);
-               goto err_out;
-       }
-       mdfld_dsi_cmds_kick_out(sender);
-err_out:
-       return err;
-}
-
-/*
- * set panel's power state
- */
-int mdfld_dsi_dbi_update_power(struct mdfld_dsi_dbi_output *dbi_output,
-                                                               int mode)
-{
-       struct drm_device *dev = dbi_output->dev;
-       struct mdfld_dsi_pkg_sender *sender =
-               mdfld_dsi_encoder_get_pkg_sender(&dbi_output->base);
-       u8 param = 0;
-       u32 err = 0;
-
-       if (!sender) {
-               WARN_ON(1);
-               return -EINVAL;
-       }
-
-       if (mode == DRM_MODE_DPMS_ON) {
-               /* Exit sleep mode */
-               err = mdfld_dsi_send_dcs(sender,
-                                        DCS_EXIT_SLEEP_MODE,
-                                        NULL,
-                                        0,
-                                        CMD_DATA_SRC_SYSTEM_MEM,
-                                        MDFLD_DSI_QUEUE_PACKAGE);
-               if (err) {
-                       dev_err(dev->dev, "DCS 0x%x sent failed\n",
-                                               DCS_EXIT_SLEEP_MODE);
-                       goto power_err;
-               }
-
-               /* Set display on */
-               err = mdfld_dsi_send_dcs(sender,
-                                        DCS_SET_DISPLAY_ON,
-                                        NULL,
-                                        0,
-                                        CMD_DATA_SRC_SYSTEM_MEM,
-                                        MDFLD_DSI_QUEUE_PACKAGE);
-               if (err) {
-                       dev_err(dev->dev, "DCS 0x%x sent failed\n",
-                                                       DCS_SET_DISPLAY_ON);
-                       goto power_err;
-               }
-
-               /* set tear effect on */
-               err = mdfld_dsi_send_dcs(sender,
-                                        DCS_SET_TEAR_ON,
-                                        &param,
-                                        1,
-                                        CMD_DATA_SRC_SYSTEM_MEM,
-                                        MDFLD_DSI_QUEUE_PACKAGE);
-               if (err) {
-                       dev_err(dev->dev, "DCS 0x%x sent failed\n",
-                                                       set_tear_on);
-                       goto power_err;
-               }
-
-               /**
-                * FIXME: remove this later
-                */
-               err = mdfld_dsi_send_dcs(sender,
-                                        DCS_WRITE_MEM_START,
-                                        NULL,
-                                        0,
-                                        CMD_DATA_SRC_PIPE,
-                                        MDFLD_DSI_QUEUE_PACKAGE);
-               if (err) {
-                       dev_err(dev->dev, "DCS 0x%x sent failed\n",
-                                               DCS_WRITE_MEM_START);
-                       goto power_err;
-               }
-       } else {
-               /* Set tear effect off */
-               err = mdfld_dsi_send_dcs(sender,
-                                        DCS_SET_TEAR_OFF,
-                                        NULL,
-                                        0,
-                                        CMD_DATA_SRC_SYSTEM_MEM,
-                                        MDFLD_DSI_QUEUE_PACKAGE);
-               if (err) {
-                       dev_err(dev->dev, "DCS 0x%x sent failed\n",
-                                                       DCS_SET_TEAR_OFF);
-                       goto power_err;
-               }
-
-               /* Turn display off */
-               err = mdfld_dsi_send_dcs(sender,
-                                        DCS_SET_DISPLAY_OFF,
-                                        NULL,
-                                        0,
-                                        CMD_DATA_SRC_SYSTEM_MEM,
-                                        MDFLD_DSI_QUEUE_PACKAGE);
-               if (err) {
-                       dev_err(dev->dev, "DCS 0x%x sent failed\n",
-                                               DCS_SET_DISPLAY_OFF);
-                       goto power_err;
-               }
-
-               /* Now enter sleep mode */
-               err = mdfld_dsi_send_dcs(sender,
-                                        DCS_ENTER_SLEEP_MODE,
-                                        NULL,
-                                        0,
-                                        CMD_DATA_SRC_SYSTEM_MEM,
-                                        MDFLD_DSI_QUEUE_PACKAGE);
-               if (err) {
-                       dev_err(dev->dev, "DCS 0x%x sent failed\n",
-                                                       DCS_ENTER_SLEEP_MODE);
-                       goto power_err;
-               }
-       }
-       mdfld_dsi_cmds_kick_out(sender);
-power_err:
-       return err;
-}
-
-/*
- * send a generic DCS command with a parameter list
- */
-int mdfld_dsi_dbi_send_dcs(struct mdfld_dsi_dbi_output *dbi_output,
-                       u8 dcs,  u8 *param, u32 num, u8 data_src)
-{
-       struct mdfld_dsi_pkg_sender *sender =
-               mdfld_dsi_encoder_get_pkg_sender(&dbi_output->base);
-       int ret;
-
-       if (!sender) {
-               WARN_ON(1);
-               return -EINVAL;
-       }
-
-       ret = mdfld_dsi_send_dcs(sender,
-                                dcs,
-                                param,
-                                num,
-                                data_src,
-                                MDFLD_DSI_SEND_PACKAGE);
-
-       return ret;
-}
-
-/*
- * Enter DSR
- */
-void mdfld_dsi_dbi_enter_dsr(struct mdfld_dsi_dbi_output *dbi_output, int pipe)
-{
-       u32 reg_val;
-       struct drm_device *dev = dbi_output->dev;
-       struct drm_psb_private *dev_priv = dev->dev_private;
-       struct drm_crtc *crtc = dbi_output->base.base.crtc;
-       struct psb_intel_crtc *psb_crtc = (crtc) ?
-                                       to_psb_intel_crtc(crtc) : NULL;
-       u32 dpll_reg = MRST_DPLL_A;
-       u32 pipeconf_reg = PIPEACONF;
-       u32 dspcntr_reg = DSPACNTR;
-
-       if (!dbi_output)
-               return;
-
-       /* FIXME check if can go */
-       dev_priv->is_in_idle = true;
-
-       gdbi_output = dbi_output;
-       if ((dbi_output->mode_flags & MODE_SETTING_ON_GOING) ||
-               (psb_crtc && psb_crtc->mode_flags & MODE_SETTING_ON_GOING))
-               return;
-
-       if (pipe == 2) {
-               dpll_reg = MRST_DPLL_A;
-               pipeconf_reg = PIPECCONF;
-               dspcntr_reg = DSPCCNTR;
-       }
-
-       if (!gma_power_begin(dev, true)) {
-               dev_err(dev->dev, "hw begin failed\n");
-               return;
-       }
-       /* Disable te interrupts */
-       mdfld_disable_te(dev, pipe);
-
-       /* Disable plane */
-       reg_val = REG_READ(dspcntr_reg);
-       if (!(reg_val & DISPLAY_PLANE_ENABLE)) {
-               REG_WRITE(dspcntr_reg, reg_val & ~DISPLAY_PLANE_ENABLE);
-               REG_READ(dspcntr_reg);
-       }
-
-       /* Disable pipe */
-       reg_val = REG_READ(pipeconf_reg);
-       if (!(reg_val & DISPLAY_PLANE_ENABLE)) {
-               reg_val &= ~DISPLAY_PLANE_ENABLE;
-               reg_val |= (PIPECONF_PLANE_OFF | PIPECONF_CURSOR_OFF);
-               REG_WRITE(pipeconf_reg, reg_val);
-               REG_READ(pipeconf_reg);
-               mdfldWaitForPipeDisable(dev, pipe);
-       }
-
-       /* Disable DPLL */
-       reg_val = REG_READ(dpll_reg);
-       if (!(reg_val & DPLL_VCO_ENABLE)) {
-               reg_val &= ~DPLL_VCO_ENABLE;
-               REG_WRITE(dpll_reg, reg_val);
-               REG_READ(dpll_reg);
-               udelay(500);
-       }
-
-       gma_power_end(dev);
-       dbi_output->mode_flags |= MODE_SETTING_IN_DSR;
-       if (pipe == 2) {
-               enter_dsr = 1;
-               /* pm_schedule_suspend(&dev->pdev->dev, gfxrtdelay); */
-       }
-}
-
-static void mdfld_dbi_output_exit_dsr(struct mdfld_dsi_dbi_output *dbi_output,
-                       int pipe)
-{
-       struct drm_device *dev = dbi_output->dev;
-       struct drm_crtc *crtc = dbi_output->base.base.crtc;
-       struct psb_intel_crtc *psb_crtc = (crtc) ?
-                                       to_psb_intel_crtc(crtc) : NULL;
-       u32 reg_val;
-       u32 dpll_reg = MRST_DPLL_A;
-       u32 pipeconf_reg = PIPEACONF;
-       u32 dspcntr_reg = DSPACNTR;
-       u32 reg_offset = 0;
-
-       /*if mode setting on-going, back off*/
-       if ((dbi_output->mode_flags & MODE_SETTING_ON_GOING) ||
-               (psb_crtc && psb_crtc->mode_flags & MODE_SETTING_ON_GOING))
-               return;
-
-       if (pipe == 2) {
-               dpll_reg = MRST_DPLL_A;
-               pipeconf_reg = PIPECCONF;
-               dspcntr_reg = DSPCCNTR;
-               reg_offset = MIPIC_REG_OFFSET;
-       }
-
-       if (!gma_power_begin(dev, true)) {
-               dev_err(dev->dev, "hw begin failed\n");
-               return;
-       }
-
-       /* Enable DPLL */
-       reg_val = REG_READ(dpll_reg);
-       if (!(reg_val & DPLL_VCO_ENABLE)) {
-               if (reg_val & MDFLD_PWR_GATE_EN) {
-                       reg_val &= ~MDFLD_PWR_GATE_EN;
-                       REG_WRITE(dpll_reg, reg_val);
-                       REG_READ(dpll_reg);
-                       udelay(500);
-               }
-
-               reg_val |= DPLL_VCO_ENABLE;
-               REG_WRITE(dpll_reg, reg_val);
-               REG_READ(dpll_reg);
-               udelay(500);
-
-               /* Add timeout */
-               while (!(REG_READ(pipeconf_reg) & PIPECONF_DSIPLL_LOCK))
-                       cpu_relax();
-       }
-
-       /* Enable pipe */
-       reg_val = REG_READ(pipeconf_reg);
-       if (!(reg_val & PIPEACONF_ENABLE)) {
-               reg_val |= PIPEACONF_ENABLE;
-               REG_WRITE(pipeconf_reg, reg_val);
-               REG_READ(pipeconf_reg);
-               udelay(500);
-               mdfldWaitForPipeEnable(dev, pipe);
-       }
-
-       /* Enable plane */
-       reg_val = REG_READ(dspcntr_reg);
-       if (!(reg_val & DISPLAY_PLANE_ENABLE)) {
-               reg_val |= DISPLAY_PLANE_ENABLE;
-               REG_WRITE(dspcntr_reg, reg_val);
-               REG_READ(dspcntr_reg);
-               udelay(500);
-       }
-
-       /* Enable TE interrupt on this pipe */
-       mdfld_enable_te(dev, pipe);
-       gma_power_end(dev);
-
-       /*clean IN_DSR flag*/
-       dbi_output->mode_flags &= ~MODE_SETTING_IN_DSR;
-}
-
-/*
- * Exit from DSR
- */
-void mdfld_dsi_dbi_exit_dsr(struct drm_device *dev, u32 update_src)
-{
-       struct drm_psb_private *dev_priv = dev->dev_private;
-       struct mdfld_dbi_dsr_info *dsr_info = dev_priv->dbi_dsr_info;
-       struct mdfld_dsi_dbi_output **dbi_output;
-       int i;
-       int pipe;
-
-       /* FIXME can go ? */
-       dev_priv->is_in_idle = false;
-       dbi_output = dsr_info->dbi_outputs;
-
-#ifdef CONFIG_PM_RUNTIME
-        if (!enable_gfx_rtpm) {
-/*                pm_runtime_allow(&gpDrmDevice->pdev->dev); */
-/*             schedule_delayed_work(&rtpm_work, 30 * 1000);*/ /* FIXME: HZ ? */
-       }
-#endif
-
-       /* For each output, exit dsr */
-       for (i = 0; i < dsr_info->dbi_output_num; i++) {
-               /* If panel has been turned off, skip */
-               if (!dbi_output[i] || !dbi_output[i]->dbi_panel_on)
-                       continue;
-               pipe = dbi_output[i]->channel_num ? 2 : 0;
-               enter_dsr = 0;
-               mdfld_dbi_output_exit_dsr(dbi_output[i], pipe);
-       }
-       dev_priv->dsr_fb_update |= update_src;
-}
-
-static bool mdfld_dbi_is_in_dsr(struct drm_device *dev)
-{
-       if (REG_READ(MRST_DPLL_A) & DPLL_VCO_ENABLE)
-               return false;
-       if ((REG_READ(PIPEACONF) & PIPEACONF_ENABLE) ||
-          (REG_READ(PIPECCONF) & PIPEACONF_ENABLE))
-               return false;
-       if ((REG_READ(DSPACNTR) & DISPLAY_PLANE_ENABLE) ||
-          (REG_READ(DSPCCNTR) & DISPLAY_PLANE_ENABLE))
-               return false;
-
-       return true;
-}
-
-/* Periodically update dbi panel */
-void mdfld_dbi_update_panel(struct drm_device *dev, int pipe)
-{
-       struct drm_psb_private *dev_priv = dev->dev_private;
-       struct mdfld_dbi_dsr_info *dsr_info = dev_priv->dbi_dsr_info;
-       struct mdfld_dsi_dbi_output **dbi_outputs;
-       struct mdfld_dsi_dbi_output *dbi_output;
-       int i;
-       int can_enter_dsr = 0;
-       u32 damage_mask;
-
-       dbi_outputs = dsr_info->dbi_outputs;
-       dbi_output = pipe ? dbi_outputs[1] : dbi_outputs[0];
-
-       if (!dbi_output)
-               return;
-
-       if (pipe == 0)
-               damage_mask = dev_priv->dsr_fb_update & MDFLD_DSR_DAMAGE_MASK_0;
-       else if (pipe == 2)
-               damage_mask = dev_priv->dsr_fb_update & MDFLD_DSR_DAMAGE_MASK_2;
-       else
-               return;
-
-       /* If FB is damaged and panel is on update on-panel FB */
-       if (damage_mask && dbi_output->dbi_panel_on) {
-               dbi_output->dsr_fb_update_done = false;
-
-               if (dbi_output->p_funcs->update_fb)
-                       dbi_output->p_funcs->update_fb(dbi_output, pipe);
-
-               if (dev_priv->dsr_enable && dbi_output->dsr_fb_update_done)
-                       dev_priv->dsr_fb_update &= ~damage_mask;
-
-               /*clean IN_DSR flag*/
-               dbi_output->mode_flags &= ~MODE_SETTING_IN_DSR;
-
-               dbi_output->dsr_idle_count = 0;
-       } else {
-               dbi_output->dsr_idle_count++;
-       }
-
-       switch (dsr_info->dbi_output_num) {
-       case 1:
-               if (dbi_output->dsr_idle_count > MDFLD_DSR_MAX_IDLE_COUNT)
-                       can_enter_dsr = 1;
-               break;
-       case 2:
-               if (dbi_outputs[0]->dsr_idle_count > MDFLD_DSR_MAX_IDLE_COUNT
-                  && dbi_outputs[1]->dsr_idle_count > MDFLD_DSR_MAX_IDLE_COUNT)
-                       can_enter_dsr = 1;
-               break;
-       default:
-               DRM_ERROR("Wrong DBI output number\n");
-       }
-
-       /* Try to enter DSR */
-       if (can_enter_dsr) {
-               for (i = 0; i < dsr_info->dbi_output_num; i++) {
-                       if (!mdfld_dbi_is_in_dsr(dev) && dbi_outputs[i] &&
-                          !(dbi_outputs[i]->mode_flags & MODE_SETTING_ON_GOING)) {
-                               mdfld_dsi_dbi_enter_dsr(dbi_outputs[i],
-                                       dbi_outputs[i]->channel_num ? 2 : 0);
-#if 0
-                               enter_dsr = 1;
-                               pr_err("%s: enter_dsr = 1\n", __func__);
-#endif
-                       }
-               }
-       /*schedule rpm suspend after gfxrtdelay*/
-#ifdef CONFIG_GFX_RTPM
-               if (!dev_priv->rpm_enabled
-                       || !enter_dsr
-       /*              || (REG_READ(HDMIB_CONTROL) & HDMIB_PORT_EN) */
-                       || pm_schedule_suspend(&dev->pdev->dev, gfxrtdelay))
-                       dev_warn(dev->dev,
-                               "Runtime PM schedule suspend failed, rpm %d\n",
-                                       dev_priv->rpm_enabled);
-#endif
-       }
-}
-
-int mdfld_dbi_dsr_init(struct drm_device *dev)
-{
-       struct drm_psb_private *dev_priv = dev->dev_private;
-       struct mdfld_dbi_dsr_info *dsr_info = dev_priv->dbi_dsr_info;
-
-       if (!dsr_info || IS_ERR(dsr_info)) {
-               dsr_info = kzalloc(sizeof(struct mdfld_dbi_dsr_info),
-                                                               GFP_KERNEL);
-               if (!dsr_info) {
-                       dev_err(dev->dev, "No memory\n");
-                       return -ENOMEM;
-               }
-               dev_priv->dbi_dsr_info = dsr_info;
-       }
-       return 0;
-}
-
-void mdfld_dbi_dsr_exit(struct drm_device *dev)
-{
-       struct drm_psb_private *dev_priv = dev->dev_private;
-       struct mdfld_dbi_dsr_info *dsr_info = dev_priv->dbi_dsr_info;
-
-       if (dsr_info) {
-               kfree(dsr_info);
-               dev_priv->dbi_dsr_info = NULL;
-       }
-}
-
-void mdfld_dsi_controller_dbi_init(struct mdfld_dsi_config *dsi_config,
-                                                               int pipe)
-{
-       struct drm_device *dev = dsi_config->dev;
-       u32 reg_offset = pipe ? MIPIC_REG_OFFSET : 0;
-       int lane_count = dsi_config->lane_count;
-       u32 val = 0;
-
-       dev_dbg(dev->dev, "Init DBI interface on pipe %d...\n", pipe);
-
-       /* Un-ready device */
-       REG_WRITE((MIPIA_DEVICE_READY_REG + reg_offset), 0x00000000);
-
-       /* Init dsi adapter before kicking off */
-       REG_WRITE((MIPIA_CONTROL_REG + reg_offset), 0x00000018);
-
-       /* TODO: figure out how to setup these registers */
-       REG_WRITE((MIPIA_DPHY_PARAM_REG + reg_offset), 0x150c3408);
-       REG_WRITE((MIPIA_CLK_LANE_SWITCH_TIME_CNT_REG + reg_offset),
-                                                       0x000a0014);
-       REG_WRITE((MIPIA_DBI_BW_CTRL_REG + reg_offset), 0x00000400);
-       REG_WRITE((MIPIA_DBI_FIFO_THROTTLE_REG + reg_offset), 0x00000001);
-       REG_WRITE((MIPIA_HS_LS_DBI_ENABLE_REG + reg_offset), 0x00000000);
-
-       /* Enable all interrupts */
-       REG_WRITE((MIPIA_INTR_EN_REG + reg_offset), 0xffffffff);
-       /* Max value: 20 clock cycles of txclkesc */
-       REG_WRITE((MIPIA_TURN_AROUND_TIMEOUT_REG + reg_offset), 0x0000001f);
-       /* Min 21 txclkesc, max: ffffh */
-       REG_WRITE((MIPIA_DEVICE_RESET_TIMER_REG + reg_offset), 0x0000ffff);
-       /* Min: 7d0 max: 4e20 */
-       REG_WRITE((MIPIA_INIT_COUNT_REG + reg_offset), 0x00000fa0);
-
-       /* Set up func_prg */
-       val |= lane_count;
-       val |= (dsi_config->channel_num << DSI_DBI_VIRT_CHANNEL_OFFSET);
-       val |= DSI_DBI_COLOR_FORMAT_OPTION2;
-       REG_WRITE((MIPIA_DSI_FUNC_PRG_REG + reg_offset), val);
-
-       REG_WRITE((MIPIA_HS_TX_TIMEOUT_REG + reg_offset), 0x3fffff);
-       REG_WRITE((MIPIA_LP_RX_TIMEOUT_REG + reg_offset), 0xffff);
-
-       /* De-assert dbi_stall when half of DBI FIFO is empty */
-       /* REG_WRITE((MIPIA_DBI_FIFO_THROTTLE_REG + reg_offset), 0x00000000); */
-
-       REG_WRITE((MIPIA_HIGH_LOW_SWITCH_COUNT_REG + reg_offset), 0x46);
-       REG_WRITE((MIPIA_EOT_DISABLE_REG + reg_offset), 0x00000000);
-       REG_WRITE((MIPIA_LP_BYTECLK_REG + reg_offset), 0x00000004);
-       REG_WRITE((MIPIA_DEVICE_READY_REG + reg_offset), 0x00000001);
-}
-
-#if 0
-/*DBI encoder helper funcs*/
-static const struct drm_encoder_helper_funcs mdfld_dsi_dbi_helper_funcs = {
-       .dpms = mdfld_dsi_dbi_dpms,
-       .mode_fixup = mdfld_dsi_dbi_mode_fixup,
-       .prepare = mdfld_dsi_dbi_prepare,
-       .mode_set = mdfld_dsi_dbi_mode_set,
-       .commit = mdfld_dsi_dbi_commit,
-};
-
-/*DBI encoder funcs*/
-static const struct drm_encoder_funcs mdfld_dsi_dbi_encoder_funcs = {
-       .destroy = drm_encoder_cleanup,
-};
-
-#endif
-
-/*
- * Init DSI DBI encoder.
- * Allocate an mdfld_dsi_encoder and attach it to given @dsi_connector
- * return pointer of newly allocated DBI encoder, NULL on error
- */
-struct mdfld_dsi_encoder *mdfld_dsi_dbi_init(struct drm_device *dev,
-                               struct mdfld_dsi_connector *dsi_connector,
-                               struct panel_funcs *p_funcs)
-{
-       struct drm_psb_private *dev_priv = dev->dev_private;
-       struct mdfld_dsi_dbi_output *dbi_output = NULL;
-       struct mdfld_dsi_config *dsi_config;
-       struct drm_connector *connector = NULL;
-       struct drm_encoder *encoder = NULL;
-       struct drm_display_mode *fixed_mode = NULL;
-       struct psb_gtt *pg = dev_priv ? (&dev_priv->gtt) : NULL;
-       struct mdfld_dbi_dpu_info *dpu_info = dev_priv ? (dev_priv->dbi_dpu_info) : NULL;
-       struct mdfld_dbi_dsr_info *dsr_info = dev_priv ? (dev_priv->dbi_dsr_info) : NULL;
-       u32 data = 0;
-       int pipe;
-       int ret;
-
-       if (!pg || !dsi_connector || !p_funcs) {
-               WARN_ON(1);
-               return NULL;
-       }
-
-       dsi_config = mdfld_dsi_get_config(dsi_connector);
-       pipe = dsi_connector->pipe;
-
-       /*panel hard-reset*/
-       if (p_funcs->reset) {
-               ret = p_funcs->reset(pipe);
-               if (ret) {
-                       DRM_ERROR("Panel %d hard-reset failed\n", pipe);
-                       return NULL;
-               }
-       }
-       /* Panel drvIC init */
-       if (p_funcs->drv_ic_init)
-               p_funcs->drv_ic_init(dsi_config, pipe);
-
-       /* Panel power mode detect */
-       ret = mdfld_dsi_get_power_mode(dsi_config,
-                                      &data,
-                                      MDFLD_DSI_HS_TRANSMISSION);
-       if (ret) {
-               DRM_ERROR("Panel %d get power mode failed\n", pipe);
-               dsi_connector->status = connector_status_disconnected;
-       } else {
-               DRM_INFO("pipe %d power mode 0x%x\n", pipe, data);
-               dsi_connector->status = connector_status_connected;
-       }
-
-       /*TODO: get panel info from DDB*/
-
-       dbi_output = kzalloc(sizeof(struct mdfld_dsi_dbi_output), GFP_KERNEL);
-       if (!dbi_output) {
-               dev_err(dev->dev, "No memory\n");
-               return NULL;
-       }
-
-       if (dsi_connector->pipe == 0) {
-               dbi_output->channel_num = 0;
-               dev_priv->dbi_output = dbi_output;
-       } else if (dsi_connector->pipe == 2) {
-               dbi_output->channel_num = 1;
-               dev_priv->dbi_output2 = dbi_output;
-       } else {
-               dev_err(dev->dev, "only support 2 DSI outputs\n");
-               goto out_err1;
-       }
-
-       dbi_output->dev = dev;
-       dbi_output->p_funcs = p_funcs;
-       fixed_mode = dsi_config->fixed_mode;
-       dbi_output->panel_fixed_mode = fixed_mode;
-
-       /* Create drm encoder object */
-       connector = &dsi_connector->base.base;
-       encoder = &dbi_output->base.base;
-       /* Review this if we ever get MIPI-HDMI bridges or similar */
-       drm_encoder_init(dev,
-                       encoder,
-                       p_funcs->encoder_funcs,
-                       DRM_MODE_ENCODER_LVDS);
-       drm_encoder_helper_add(encoder, p_funcs->encoder_helper_funcs);
-
-       /* Attach to given connector */
-       drm_mode_connector_attach_encoder(connector, encoder);
-
-       /* Set possible CRTCs and clones */
-       if (dsi_connector->pipe) {
-               encoder->possible_crtcs = (1 << 2);
-               encoder->possible_clones = (1 << 1);
-       } else {
-               encoder->possible_crtcs = (1 << 0);
-               encoder->possible_clones = (1 << 0);
-       }
-
-       dev_priv->dsr_fb_update = 0;
-       dev_priv->dsr_enable = false;
-       dev_priv->exit_idle = mdfld_dsi_dbi_exit_dsr;
-
-       dbi_output->first_boot = true;
-       dbi_output->mode_flags = MODE_SETTING_IN_ENCODER;
-
-       /* Add this output to dpu_info if in DPU mode */
-       if (dpu_info && dsi_connector->status == connector_status_connected) {
-               if (dsi_connector->pipe == 0)
-                       dpu_info->dbi_outputs[0] = dbi_output;
-               else
-                       dpu_info->dbi_outputs[1] = dbi_output;
-
-               dpu_info->dbi_output_num++;
-       } else if (dsi_connector->status == connector_status_connected) {
-               /* Add this output to dsr_info if not */
-               if (dsi_connector->pipe == 0)
-                       dsr_info->dbi_outputs[0] = dbi_output;
-               else
-                       dsr_info->dbi_outputs[1] = dbi_output;
-
-               dsr_info->dbi_output_num++;
-       }
-       return &dbi_output->base;
-out_err1:
-       kfree(dbi_output);
-       return NULL;
-}
diff --git a/drivers/staging/gma500/mdfld_dsi_dbi.h b/drivers/staging/gma500/mdfld_dsi_dbi.h
deleted file mode 100644 (file)
index f0fa986..0000000
+++ /dev/null
@@ -1,173 +0,0 @@
-/*
- * Copyright Â© 2010 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Authors:
- * jim liu <jim.liu@intel.com>
- * Jackie Li<yaodong.li@intel.com>
- */
-
-#ifndef __MDFLD_DSI_DBI_H__
-#define __MDFLD_DSI_DBI_H__
-
-#include <linux/backlight.h>
-#include <drm/drmP.h>
-#include <drm/drm.h>
-#include <drm/drm_crtc.h>
-#include <drm/drm_edid.h>
-
-#include "psb_drv.h"
-#include "psb_intel_drv.h"
-#include "psb_intel_reg.h"
-#include "power.h"
-
-#include "mdfld_dsi_output.h"
-#include "mdfld_output.h"
-
-/*
- * DBI encoder which inherits from mdfld_dsi_encoder
- */
-struct mdfld_dsi_dbi_output {
-       struct mdfld_dsi_encoder base;
-       struct drm_display_mode *panel_fixed_mode;
-       u8 last_cmd;
-       u8 lane_count;
-       u8 channel_num;
-       struct drm_device *dev;
-
-       /* Backlight operations */
-
-       /* DSR timer */
-       u32 dsr_idle_count;
-       bool dsr_fb_update_done;
-
-       /* Mode setting flags */
-       u32 mode_flags;
-
-       /* Panel status */
-       bool dbi_panel_on;
-       bool first_boot;
-       struct panel_funcs *p_funcs;
-
-       /* DPU */
-       u32 *dbi_cb_addr;
-       u32 dbi_cb_phy;
-       spinlock_t cb_lock;
-       u32 cb_write;
-};
-
-#define MDFLD_DSI_DBI_OUTPUT(dsi_encoder) \
-       container_of(dsi_encoder, struct mdfld_dsi_dbi_output, base)
-
-struct mdfld_dbi_dsr_info {
-       int dbi_output_num;
-       struct mdfld_dsi_dbi_output *dbi_outputs[2];
-
-       u32 dsr_idle_count;
-};
-
-#define DBI_CB_TIMEOUT_COUNT   0xffff
-
-/* Offsets */
-#define CMD_MEM_ADDR_OFFSET    0
-
-#define CMD_DATA_SRC_SYSTEM_MEM        0
-#define CMD_DATA_SRC_PIPE      1
-
-static inline int mdfld_dsi_dbi_fifo_ready(struct mdfld_dsi_dbi_output *dbi_output)
-{
-       struct drm_device *dev = dbi_output->dev;
-       u32 retry = DBI_CB_TIMEOUT_COUNT;
-       int reg_offset = (dbi_output->channel_num == 1) ? MIPIC_REG_OFFSET : 0;
-       int ret = 0;
-
-       /* Query the dbi fifo status*/
-       while (retry--) {
-               if (REG_READ(MIPIA_GEN_FIFO_STAT_REG + reg_offset) & (1 << 27))
-                       break;
-       }
-
-       if (!retry) {
-               DRM_ERROR("Timeout waiting for DBI FIFO empty\n");
-               ret = -EAGAIN;
-       }
-       return ret;
-}
-
-static inline int mdfld_dsi_dbi_cmd_sent(struct mdfld_dsi_dbi_output *dbi_output)
-{
-       struct drm_device *dev = dbi_output->dev;
-       u32 retry = DBI_CB_TIMEOUT_COUNT;
-       int reg_offset = (dbi_output->channel_num == 1) ? MIPIC_REG_OFFSET : 0;
-       int ret = 0;
-
-       /* Query the command execution status */
-       while (retry--)
-               if (!(REG_READ(MIPIA_CMD_ADD_REG + reg_offset) & (1 << 0)))
-                       break;
-
-       if (!retry) {
-               DRM_ERROR("Timeout waiting for DBI command status\n");
-               ret = -EAGAIN;
-       }
-
-       return ret;
-}
-
-static inline int mdfld_dsi_dbi_cb_ready(struct mdfld_dsi_dbi_output *dbi_output)
-{
-       int ret = 0;
-
-       /* Query the command execution status*/
-       ret = mdfld_dsi_dbi_cmd_sent(dbi_output);
-       if (ret) {
-               DRM_ERROR("Peripheral is busy\n");
-               ret = -EAGAIN;
-       }
-       /* Query the dbi fifo status*/
-       ret = mdfld_dsi_dbi_fifo_ready(dbi_output);
-       if (ret) {
-               DRM_ERROR("DBI FIFO is not empty\n");
-               ret = -EAGAIN;
-       }
-       return ret;
-}
-
-extern void mdfld_dsi_dbi_output_init(struct drm_device *dev,
-                       struct psb_intel_mode_device *mode_dev, int pipe);
-extern void mdfld_dsi_dbi_exit_dsr(struct drm_device *dev, u32 update_src);
-extern void mdfld_dsi_dbi_enter_dsr(struct mdfld_dsi_dbi_output *dbi_output,
-                       int pipe);
-extern int mdfld_dbi_dsr_init(struct drm_device *dev);
-extern void mdfld_dbi_dsr_exit(struct drm_device *dev);
-extern struct mdfld_dsi_encoder *mdfld_dsi_dbi_init(struct drm_device *dev,
-                       struct mdfld_dsi_connector *dsi_connector,
-                       struct panel_funcs *p_funcs);
-extern int mdfld_dsi_dbi_send_dcs(struct mdfld_dsi_dbi_output *dbi_output,
-                       u8 dcs, u8 *param, u32 num, u8 data_src);
-extern int mdfld_dsi_dbi_update_area(struct mdfld_dsi_dbi_output *dbi_output,
-                       u16 x1, u16 y1, u16 x2, u16 y2);
-extern int mdfld_dsi_dbi_update_power(struct mdfld_dsi_dbi_output *dbi_output,
-                       int mode);
-extern void mdfld_dsi_controller_dbi_init(struct mdfld_dsi_config *dsi_config,
-                       int pipe);
-
-#endif /*__MDFLD_DSI_DBI_H__*/
diff --git a/drivers/staging/gma500/mdfld_dsi_dbi_dpu.c b/drivers/staging/gma500/mdfld_dsi_dbi_dpu.c
deleted file mode 100644 (file)
index a4e2ff4..0000000
+++ /dev/null
@@ -1,778 +0,0 @@
-/*
- * Copyright Â© 2010-2011 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Authors:
- * Jim Liu <jim.liu@intel.com>
- * Jackie Li<yaodong.li@intel.com>
- */
-
-#include "mdfld_dsi_dbi_dpu.h"
-#include "mdfld_dsi_dbi.h"
-
-/*
- * NOTE: all mdlfd_x_damage funcs should be called by holding dpu_update_lock
- */
-
-static int mdfld_cursor_damage(struct mdfld_dbi_dpu_info *dpu_info,
-                          mdfld_plane_t plane,
-                          struct psb_drm_dpu_rect *damaged_rect)
-{
-       int x, y;
-       int new_x, new_y;
-       struct psb_drm_dpu_rect *rect;
-       struct psb_drm_dpu_rect *pipe_rect;
-       int cursor_size;
-       struct mdfld_cursor_info *cursor;
-       mdfld_plane_t fb_plane;
-
-       if (plane == MDFLD_CURSORA) {
-               cursor = &dpu_info->cursors[0];
-               x = dpu_info->cursors[0].x;
-               y = dpu_info->cursors[0].y;
-               cursor_size = dpu_info->cursors[0].size;
-               pipe_rect = &dpu_info->damage_pipea;
-               fb_plane = MDFLD_PLANEA;
-       } else {
-               cursor = &dpu_info->cursors[1];
-               x = dpu_info->cursors[1].x;
-               y = dpu_info->cursors[1].y;
-               cursor_size = dpu_info->cursors[1].size;
-               pipe_rect = &dpu_info->damage_pipec;
-               fb_plane = MDFLD_PLANEC;
-       }
-       new_x = damaged_rect->x;
-       new_y = damaged_rect->y;
-
-       if (x == new_x && y == new_y)
-               return 0;
-
-       rect = &dpu_info->damaged_rects[plane];
-       /* Move to right */
-       if (new_x >= x) {
-               if (new_y > y) {
-                       rect->x = x;
-                       rect->y = y;
-                       rect->width = (new_x + cursor_size) - x;
-                       rect->height = (new_y + cursor_size) - y;
-                       goto cursor_out;
-               } else {
-                       rect->x = x;
-                       rect->y = new_y;
-                       rect->width = (new_x + cursor_size) - x;
-                       rect->height = (y - new_y);
-                       goto cursor_out;
-               }
-       } else {
-               if (new_y > y) {
-                       rect->x = new_x;
-                       rect->y = y;
-                       rect->width = (x + cursor_size) - new_x;
-                       rect->height = new_y - y;
-                       goto cursor_out;
-               } else {
-                       rect->x = new_x;
-                       rect->y = new_y;
-                       rect->width = (x + cursor_size) - new_x;
-                       rect->height = (y + cursor_size) - new_y;
-               }
-       }
-cursor_out:
-       if (new_x < 0)
-               cursor->x = 0;
-       else if (new_x > 864)
-               cursor->x = 864;
-       else
-               cursor->x = new_x;
-
-       if (new_y < 0)
-               cursor->y = 0;
-       else if (new_y > 480)
-               cursor->y = 480;
-       else
-               cursor->y = new_y;
-
-       /*
-        * FIXME: this is a workaround for cursor plane update,
-        * remove it later!
-        */
-       rect->x = 0;
-       rect->y = 0;
-       rect->width = 864;
-       rect->height = 480;
-
-       mdfld_check_boundary(dpu_info, rect);
-       mdfld_dpu_region_extent(pipe_rect, rect);
-
-       /* Update pending status of dpu_info */
-       dpu_info->pending |= (1 << plane);
-       /* Update fb panel as well */
-       dpu_info->pending |= (1 << fb_plane);
-       return 0;
-}
-
-static int mdfld_fb_damage(struct mdfld_dbi_dpu_info *dpu_info,
-                                  mdfld_plane_t plane,
-                                  struct psb_drm_dpu_rect *damaged_rect)
-{
-       struct psb_drm_dpu_rect *rect;
-
-       if (plane == MDFLD_PLANEA)
-               rect = &dpu_info->damage_pipea;
-       else
-               rect = &dpu_info->damage_pipec;
-
-       mdfld_check_boundary(dpu_info, damaged_rect);
-
-       /* Add fb damage area to this pipe */
-       mdfld_dpu_region_extent(rect, damaged_rect);
-
-       /* Update pending status of dpu_info */
-       dpu_info->pending |= (1 << plane);
-       return 0;
-}
-
-/* Do nothing here, right now */
-static int mdfld_overlay_damage(struct mdfld_dbi_dpu_info *dpu_info,
-                               mdfld_plane_t plane,
-                               struct psb_drm_dpu_rect *damaged_rect)
-{
-       return 0;
-}
-
-int mdfld_dbi_dpu_report_damage(struct drm_device *dev,
-                               mdfld_plane_t plane,
-                               struct psb_drm_dpu_rect *rect)
-{
-       struct drm_psb_private *dev_priv = dev->dev_private;
-       struct mdfld_dbi_dpu_info *dpu_info = dev_priv->dbi_dpu_info;
-       int ret = 0;
-
-       /* DPU not in use, no damage reporting needed */
-       if (dpu_info == NULL)
-               return 0;
-
-       spin_lock(&dpu_info->dpu_update_lock);
-
-       switch (plane) {
-       case MDFLD_PLANEA:
-       case MDFLD_PLANEC:
-               mdfld_fb_damage(dpu_info, plane, rect);
-               break;
-       case MDFLD_CURSORA:
-       case MDFLD_CURSORC:
-               mdfld_cursor_damage(dpu_info, plane, rect);
-               break;
-       case MDFLD_OVERLAYA:
-       case MDFLD_OVERLAYC:
-               mdfld_overlay_damage(dpu_info, plane, rect);
-               break;
-       default:
-               DRM_ERROR("Invalid plane type %d\n", plane);
-               ret = -EINVAL;
-       }
-       spin_unlock(&dpu_info->dpu_update_lock);
-       return ret;
-}
-
-int mdfld_dbi_dpu_report_fullscreen_damage(struct drm_device *dev)
-{
-       struct drm_psb_private *dev_priv;
-       struct mdfld_dbi_dpu_info *dpu_info;
-       struct mdfld_dsi_config  *dsi_config;
-       struct psb_drm_dpu_rect rect;
-       int i;
-
-       if (!dev) {
-               DRM_ERROR("Invalid parameter\n");
-               return -EINVAL;
-       }
-
-       dev_priv = dev->dev_private;
-       dpu_info = dev_priv->dbi_dpu_info;
-
-       /* This is fine - we may be in non DPU mode */
-       if (!dpu_info)
-               return -EINVAL;
-
-       for (i = 0; i < dpu_info->dbi_output_num; i++) {
-               dsi_config = dev_priv->dsi_configs[i];
-               if (dsi_config) {
-                       rect.x = rect.y = 0;
-                       rect.width = dsi_config->fixed_mode->hdisplay;
-                       rect.height = dsi_config->fixed_mode->vdisplay;
-                       mdfld_dbi_dpu_report_damage(dev,
-                                   i ? (MDFLD_PLANEC) : (MDFLD_PLANEA),
-                                   &rect);
-               }
-       }
-       /* Exit DSR state */
-       mdfld_dpu_exit_dsr(dev);
-       return 0;
-}
-
-int mdfld_dsi_dbi_dsr_off(struct drm_device *dev,
-                                       struct psb_drm_dpu_rect *rect)
-{
-       struct drm_psb_private *dev_priv = dev->dev_private;
-       struct mdfld_dbi_dpu_info *dpu_info = dev_priv->dbi_dpu_info;
-
-       mdfld_dbi_dpu_report_damage(dev, MDFLD_PLANEA, rect);
-
-       /* If dual display mode */
-       if (dpu_info->dbi_output_num == 2)
-               mdfld_dbi_dpu_report_damage(dev, MDFLD_PLANEC, rect);
-
-       /* Force dsi to exit DSR mode */
-       mdfld_dpu_exit_dsr(dev);
-       return 0;
-}
-
-static void mdfld_dpu_cursor_plane_flush(struct mdfld_dbi_dpu_info *dpu_info,
-                                                mdfld_plane_t plane)
-{
-       struct drm_device *dev = dpu_info->dev;
-       u32 curpos_reg = CURAPOS;
-       u32 curbase_reg = CURABASE;
-       u32 curcntr_reg = CURACNTR;
-       struct mdfld_cursor_info *cursor = &dpu_info->cursors[0];
-
-       if (plane == MDFLD_CURSORC) {
-               curpos_reg = CURCPOS;
-               curbase_reg = CURCBASE;
-               curcntr_reg = CURCCNTR;
-               cursor = &dpu_info->cursors[1];
-       }
-
-       REG_WRITE(curcntr_reg, REG_READ(curcntr_reg));
-       REG_WRITE(curpos_reg,
-               (((cursor->x & CURSOR_POS_MASK) << CURSOR_X_SHIFT) |
-               ((cursor->y & CURSOR_POS_MASK) << CURSOR_Y_SHIFT)));
-       REG_WRITE(curbase_reg, REG_READ(curbase_reg));
-}
-
-static void mdfld_dpu_fb_plane_flush(struct mdfld_dbi_dpu_info *dpu_info,
-                                                mdfld_plane_t plane)
-{
-       u32 pipesrc_reg = PIPEASRC;
-       u32 dspsize_reg = DSPASIZE;
-       u32 dspoff_reg = DSPALINOFF;
-       u32 dspsurf_reg = DSPASURF;
-       u32 dspstride_reg = DSPASTRIDE;
-       u32 stride;
-       struct psb_drm_dpu_rect *rect = &dpu_info->damage_pipea;
-       struct drm_device *dev = dpu_info->dev;
-
-       if (plane == MDFLD_PLANEC) {
-               pipesrc_reg = PIPECSRC;
-               dspsize_reg = DSPCSIZE;
-               dspoff_reg = DSPCLINOFF;
-               dspsurf_reg = DSPCSURF;
-               dspstride_reg = DSPCSTRIDE;
-               rect = &dpu_info->damage_pipec;
-       }
-
-       stride = REG_READ(dspstride_reg);
-       /* FIXME: should I do the pipe src update here? */
-       REG_WRITE(pipesrc_reg, ((rect->width - 1) << 16) | (rect->height - 1));
-       /* Flush plane */
-       REG_WRITE(dspsize_reg, ((rect->height - 1) << 16) | (rect->width - 1));
-       REG_WRITE(dspoff_reg, ((rect->x * 4) + (rect->y * stride)));
-       REG_WRITE(dspsurf_reg, REG_READ(dspsurf_reg));
-
-       /*
-        * TODO: wait for flip finished and restore the pipesrc reg,
-        * or cursor will be show at a wrong position
-        */
-}
-
-static void mdfld_dpu_overlay_plane_flush(struct mdfld_dbi_dpu_info *dpu_info,
-                                                 mdfld_plane_t plane)
-{
-}
-
-/*
- * TODO: we are still in dbi normal mode now, we will try to use partial
- * mode later.
- */
-static int mdfld_dbi_prepare_cb(struct mdfld_dsi_dbi_output *dbi_output,
-                               struct mdfld_dbi_dpu_info *dpu_info, int pipe)
-{
-       u8 *cb_addr = (u8 *)dbi_output->dbi_cb_addr;
-       u32 *index;
-       struct psb_drm_dpu_rect *rect = pipe ?
-               (&dpu_info->damage_pipec) : (&dpu_info->damage_pipea);
-
-       /* FIXME: lock command buffer, this may lead to a deadlock,
-          as we already hold the dpu_update_lock */
-       if (!spin_trylock(&dbi_output->cb_lock)) {
-               DRM_ERROR("lock command buffer failed, try again\n");
-               return -EAGAIN;
-       }
-
-       index = &dbi_output->cb_write;
-
-       if (*index) {
-               DRM_ERROR("DBI command buffer unclean\n");
-               return -EAGAIN;
-       }
-
-       /* Column address */
-       *(cb_addr + ((*index)++)) = set_column_address;
-       *(cb_addr + ((*index)++)) = rect->x >> 8;
-       *(cb_addr + ((*index)++)) = rect->x;
-       *(cb_addr + ((*index)++)) = (rect->x + rect->width - 1) >> 8;
-       *(cb_addr + ((*index)++)) = (rect->x + rect->width - 1);
-
-       *index = 8;
-
-       /* Page address */
-       *(cb_addr + ((*index)++)) = set_page_addr;
-       *(cb_addr + ((*index)++)) = rect->y >> 8;
-       *(cb_addr + ((*index)++)) = rect->y;
-       *(cb_addr + ((*index)++)) = (rect->y + rect->height - 1) >> 8;
-       *(cb_addr + ((*index)++)) = (rect->y + rect->height - 1);
-
-       *index = 16;
-
-       /*write memory*/
-       *(cb_addr + ((*index)++)) = write_mem_start;
-
-       return 0;
-}
-
-static int mdfld_dbi_flush_cb(struct mdfld_dsi_dbi_output *dbi_output, int pipe)
-{
-       u32 cmd_phy = dbi_output->dbi_cb_phy;
-       u32 *index = &dbi_output->cb_write;
-       int reg_offset = pipe ? MIPIC_REG_OFFSET : 0;
-       struct drm_device *dev = dbi_output->dev;
-
-       if (*index == 0 || !dbi_output)
-               return 0;
-
-       REG_WRITE((MIPIA_CMD_LEN_REG + reg_offset), 0x010505);
-       REG_WRITE((MIPIA_CMD_ADD_REG + reg_offset), cmd_phy | 3);
-
-       *index = 0;
-
-       /* FIXME: unlock command buffer */
-       spin_unlock(&dbi_output->cb_lock);
-       return 0;
-}
-
-static int mdfld_dpu_update_pipe(struct mdfld_dsi_dbi_output *dbi_output,
-                                struct mdfld_dbi_dpu_info *dpu_info, int pipe)
-{
-       struct drm_device *dev =  dbi_output->dev;
-       struct drm_psb_private *dev_priv = dev->dev_private;
-       mdfld_plane_t cursor_plane = MDFLD_CURSORA;
-       mdfld_plane_t fb_plane = MDFLD_PLANEA;
-       mdfld_plane_t overlay_plane = MDFLD_OVERLAYA;
-       int ret = 0;
-       u32 plane_mask = MDFLD_PIPEA_PLANE_MASK;
-
-       /* Damaged rects on this pipe */
-       if (pipe) {
-               cursor_plane = MDFLD_CURSORC;
-               fb_plane = MDFLD_PLANEC;
-               overlay_plane = MDFLD_OVERLAYC;
-               plane_mask = MDFLD_PIPEC_PLANE_MASK;
-       }
-
-       /*update cursor which assigned to @pipe*/
-       if (dpu_info->pending & (1 << cursor_plane))
-               mdfld_dpu_cursor_plane_flush(dpu_info, cursor_plane);
-
-       /*update fb which assigned to @pipe*/
-       if (dpu_info->pending & (1 << fb_plane))
-               mdfld_dpu_fb_plane_flush(dpu_info, fb_plane);
-
-       /* TODO: update overlay */
-       if (dpu_info->pending & (1 << overlay_plane))
-               mdfld_dpu_overlay_plane_flush(dpu_info, overlay_plane);
-
-       /* Flush damage area to panel fb */
-       if (dpu_info->pending & plane_mask) {
-               ret = mdfld_dbi_prepare_cb(dbi_output, dpu_info, pipe);
-               /*
-                * TODO: remove b_dsr_enable later,
-                * added it so that text console could boot smoothly
-                */
-               /* Clean pending flags on this pipe */
-               if (!ret && dev_priv->dsr_enable) {
-                       dpu_info->pending &= ~plane_mask;
-                       /* Reset overlay pipe damage rect */
-                       mdfld_dpu_init_damage(dpu_info, pipe);
-               }
-       }
-       return ret;
-}
-
-static int mdfld_dpu_update_fb(struct drm_device *dev)
-{
-       struct drm_crtc *crtc;
-       struct psb_intel_crtc *psb_crtc;
-       struct mdfld_dsi_dbi_output **dbi_output;
-       struct drm_psb_private *dev_priv = dev->dev_private;
-       struct mdfld_dbi_dpu_info *dpu_info = dev_priv->dbi_dpu_info;
-       bool pipe_updated[2];
-       unsigned long irq_flags;
-       u32 dpll_reg = MRST_DPLL_A;
-       u32 dspcntr_reg = DSPACNTR;
-       u32 pipeconf_reg = PIPEACONF;
-       u32 dsplinoff_reg = DSPALINOFF;
-       u32 dspsurf_reg = DSPASURF;
-       u32 mipi_state_reg = MIPIA_INTR_STAT_REG;
-       u32 reg_offset = 0;
-       int pipe;
-       int i;
-       int ret;
-
-       dbi_output = dpu_info->dbi_outputs;
-       pipe_updated[0] = pipe_updated[1] = false;
-
-       if (!gma_power_begin(dev, true))
-               return -EAGAIN;
-
-       /* Try to prevent any new damage reports */
-       if (!spin_trylock_irqsave(&dpu_info->dpu_update_lock, irq_flags))
-               return -EAGAIN;
-
-       for (i = 0; i < dpu_info->dbi_output_num; i++) {
-               crtc = dbi_output[i]->base.base.crtc;
-               psb_crtc = (crtc) ? to_psb_intel_crtc(crtc) : NULL;
-
-               pipe = dbi_output[i]->channel_num ? 2 : 0;
-
-               if (pipe == 2) {
-                       dspcntr_reg = DSPCCNTR;
-                       pipeconf_reg = PIPECCONF;
-                       dsplinoff_reg = DSPCLINOFF;
-                       dspsurf_reg = DSPCSURF;
-                       reg_offset = MIPIC_REG_OFFSET;
-               }
-
-               if (!(REG_READ((MIPIA_GEN_FIFO_STAT_REG + reg_offset))
-                                                       & (1 << 27)) ||
-                       !(REG_READ(dpll_reg) & DPLL_VCO_ENABLE) ||
-                       !(REG_READ(dspcntr_reg) & DISPLAY_PLANE_ENABLE) ||
-                       !(REG_READ(pipeconf_reg) & DISPLAY_PLANE_ENABLE)) {
-                       dev_err(dev->dev,
-                               "DBI FIFO is busy, DSI %d state %x\n",
-                               pipe,
-                               REG_READ(mipi_state_reg + reg_offset));
-                       continue;
-               }
-
-               /*
-                *      If DBI output is in a exclusive state then the pipe
-                *      change won't be updated
-                */
-               if (dbi_output[i]->dbi_panel_on &&
-                  !(dbi_output[i]->mode_flags & MODE_SETTING_ON_GOING) &&
-                  !(psb_crtc &&
-                       psb_crtc->mode_flags & MODE_SETTING_ON_GOING) &&
-                  !(dbi_output[i]->mode_flags & MODE_SETTING_IN_DSR)) {
-                       ret = mdfld_dpu_update_pipe(dbi_output[i],
-                               dpu_info, dbi_output[i]->channel_num ? 2 : 0);
-                       if (!ret)
-                               pipe_updated[i] = true;
-               }
-       }
-
-       for (i = 0; i < dpu_info->dbi_output_num; i++)
-               if (pipe_updated[i])
-                       mdfld_dbi_flush_cb(dbi_output[i],
-                               dbi_output[i]->channel_num ? 2 : 0);
-
-       spin_unlock_irqrestore(&dpu_info->dpu_update_lock, irq_flags);
-       gma_power_end(dev);
-       return 0;
-}
-
-static int __mdfld_dbi_exit_dsr(struct mdfld_dsi_dbi_output *dbi_output,
-                                                               int pipe)
-{
-       struct drm_device *dev = dbi_output->dev;
-       struct drm_crtc *crtc = dbi_output->base.base.crtc;
-       struct psb_intel_crtc *psb_crtc = (crtc) ? to_psb_intel_crtc(crtc)
-                                                               : NULL;
-       u32 reg_val;
-       u32 dpll_reg = MRST_DPLL_A;
-       u32 pipeconf_reg = PIPEACONF;
-       u32 dspcntr_reg = DSPACNTR;
-       u32 dspbase_reg = DSPABASE;
-       u32 dspsurf_reg = DSPASURF;
-       u32 reg_offset = 0;
-
-       if (!dbi_output)
-               return 0;
-
-       /* If mode setting on-going, back off */
-       if ((dbi_output->mode_flags & MODE_SETTING_ON_GOING) ||
-               (psb_crtc && psb_crtc->mode_flags & MODE_SETTING_ON_GOING))
-               return -EAGAIN;
-
-       if (pipe == 2) {
-               dpll_reg = MRST_DPLL_A;
-               pipeconf_reg = PIPECCONF;
-               dspcntr_reg = DSPCCNTR;
-               dspbase_reg = MDFLD_DSPCBASE;
-               dspsurf_reg = DSPCSURF;
-
-               reg_offset = MIPIC_REG_OFFSET;
-       }
-
-       if (!gma_power_begin(dev, true))
-               return -EAGAIN;
-
-       /* Enable DPLL */
-       reg_val = REG_READ(dpll_reg);
-       if (!(reg_val & DPLL_VCO_ENABLE)) {
-
-               if (reg_val & MDFLD_PWR_GATE_EN) {
-                       reg_val &= ~MDFLD_PWR_GATE_EN;
-                       REG_WRITE(dpll_reg, reg_val);
-                       REG_READ(dpll_reg);
-                       udelay(500);
-               }
-
-               reg_val |= DPLL_VCO_ENABLE;
-               REG_WRITE(dpll_reg, reg_val);
-               REG_READ(dpll_reg);
-               udelay(500);
-
-               /* FIXME: add timeout */
-               while (!(REG_READ(pipeconf_reg) & PIPECONF_DSIPLL_LOCK))
-                       cpu_relax();
-       }
-
-       /* Enable pipe */
-       reg_val = REG_READ(pipeconf_reg);
-       if (!(reg_val & PIPEACONF_ENABLE)) {
-               reg_val |= PIPEACONF_ENABLE;
-               REG_WRITE(pipeconf_reg, reg_val);
-               REG_READ(pipeconf_reg);
-               udelay(500);
-               mdfldWaitForPipeEnable(dev, pipe);
-       }
-
-       /* Enable plane */
-       reg_val = REG_READ(dspcntr_reg);
-       if (!(reg_val & DISPLAY_PLANE_ENABLE)) {
-               reg_val |= DISPLAY_PLANE_ENABLE;
-               REG_WRITE(dspcntr_reg, reg_val);
-               REG_READ(dspcntr_reg);
-               udelay(500);
-       }
-
-       gma_power_end(dev);
-
-       /* Clean IN_DSR flag */
-       dbi_output->mode_flags &= ~MODE_SETTING_IN_DSR;
-
-       return 0;
-}
-
-int mdfld_dpu_exit_dsr(struct drm_device *dev)
-{
-       struct mdfld_dsi_dbi_output **dbi_output;
-       struct drm_psb_private *dev_priv = dev->dev_private;
-       struct mdfld_dbi_dpu_info *dpu_info = dev_priv->dbi_dpu_info;
-       int i;
-       int pipe;
-
-       dbi_output = dpu_info->dbi_outputs;
-
-       for (i = 0; i < dpu_info->dbi_output_num; i++) {
-               /* If this output is not in DSR mode, don't call exit dsr */
-               if (dbi_output[i]->mode_flags & MODE_SETTING_IN_DSR)
-                       __mdfld_dbi_exit_dsr(dbi_output[i],
-                                       dbi_output[i]->channel_num ? 2 : 0);
-       }
-
-       /* Enable TE interrupt */
-       for (i = 0; i < dpu_info->dbi_output_num; i++) {
-               /* If this output is not in DSR mode, don't call exit dsr */
-               pipe = dbi_output[i]->channel_num ? 2 : 0;
-               if (dbi_output[i]->dbi_panel_on && pipe) {
-                       mdfld_disable_te(dev, 0);
-                       mdfld_enable_te(dev, 2);
-               } else if (dbi_output[i]->dbi_panel_on && !pipe) {
-                       mdfld_disable_te(dev, 2);
-                       mdfld_enable_te(dev, 0);
-               }
-       }
-       return 0;
-}
-
-static int mdfld_dpu_enter_dsr(struct drm_device *dev)
-{
-       struct drm_psb_private *dev_priv = dev->dev_private;
-       struct mdfld_dbi_dpu_info *dpu_info = dev_priv->dbi_dpu_info;
-       struct mdfld_dsi_dbi_output **dbi_output;
-       int i;
-
-       dbi_output = dpu_info->dbi_outputs;
-
-       for (i = 0; i < dpu_info->dbi_output_num; i++) {
-               /* If output is off or already in DSR state, don't re-enter */
-               if (dbi_output[i]->dbi_panel_on &&
-                  !(dbi_output[i]->mode_flags & MODE_SETTING_IN_DSR)) {
-                       mdfld_dsi_dbi_enter_dsr(dbi_output[i],
-                               dbi_output[i]->channel_num ? 2 : 0);
-               }
-       }
-
-       return 0;
-}
-
-static void mdfld_dbi_dpu_timer_func(unsigned long data)
-{
-       struct drm_device *dev = (struct drm_device *)data;
-       struct drm_psb_private *dev_priv = dev->dev_private;
-       struct mdfld_dbi_dpu_info *dpu_info = dev_priv->dbi_dpu_info;
-       struct timer_list *dpu_timer = &dpu_info->dpu_timer;
-       unsigned long flags;
-
-       if (dpu_info->pending) {
-               dpu_info->idle_count = 0;
-               /* Update panel fb with damaged area */
-               mdfld_dpu_update_fb(dev);
-       } else {
-               dpu_info->idle_count++;
-       }
-
-       if (dpu_info->idle_count >= MDFLD_MAX_IDLE_COUNT) {
-               mdfld_dpu_enter_dsr(dev);
-               /* Stop timer by return */
-               return;
-       }
-
-       spin_lock_irqsave(&dpu_info->dpu_timer_lock, flags);
-       if (!timer_pending(dpu_timer)) {
-               dpu_timer->expires = jiffies + MDFLD_DSR_DELAY;
-               add_timer(dpu_timer);
-       }
-       spin_unlock_irqrestore(&dpu_info->dpu_timer_lock, flags);
-}
-
-void mdfld_dpu_update_panel(struct drm_device *dev)
-{
-       struct drm_psb_private *dev_priv = dev->dev_private;
-       struct mdfld_dbi_dpu_info *dpu_info = dev_priv->dbi_dpu_info;
-
-       if (dpu_info->pending) {
-               dpu_info->idle_count = 0;
-
-               /*update panel fb with damaged area*/
-               mdfld_dpu_update_fb(dev);
-       } else {
-               dpu_info->idle_count++;
-       }
-
-       if (dpu_info->idle_count >= MDFLD_MAX_IDLE_COUNT) {
-               /*enter dsr*/
-               mdfld_dpu_enter_dsr(dev);
-       }
-}
-
-static int mdfld_dbi_dpu_timer_init(struct drm_device *dev,
-                               struct mdfld_dbi_dpu_info *dpu_info)
-{
-       struct timer_list *dpu_timer = &dpu_info->dpu_timer;
-       unsigned long flags;
-
-       spin_lock_init(&dpu_info->dpu_timer_lock);
-       spin_lock_irqsave(&dpu_info->dpu_timer_lock, flags);
-
-       init_timer(dpu_timer);
-
-       dpu_timer->data = (unsigned long)dev;
-       dpu_timer->function = mdfld_dbi_dpu_timer_func;
-       dpu_timer->expires = jiffies + MDFLD_DSR_DELAY;
-
-       spin_unlock_irqrestore(&dpu_info->dpu_timer_lock, flags);
-
-       return 0;
-}
-
-void mdfld_dbi_dpu_timer_start(struct mdfld_dbi_dpu_info *dpu_info)
-{
-       struct timer_list *dpu_timer = &dpu_info->dpu_timer;
-       unsigned long flags;
-
-       spin_lock_irqsave(&dpu_info->dpu_timer_lock, flags);
-       if (!timer_pending(dpu_timer)) {
-               dpu_timer->expires = jiffies + MDFLD_DSR_DELAY;
-               add_timer(dpu_timer);
-       }
-       spin_unlock_irqrestore(&dpu_info->dpu_timer_lock, flags);
-}
-
-int mdfld_dbi_dpu_init(struct drm_device *dev)
-{
-       struct drm_psb_private *dev_priv = dev->dev_private;
-       struct mdfld_dbi_dpu_info *dpu_info = dev_priv->dbi_dpu_info;
-
-       if (!dpu_info || IS_ERR(dpu_info)) {
-               dpu_info = kzalloc(sizeof(struct mdfld_dbi_dpu_info),
-                                                               GFP_KERNEL);
-               if (!dpu_info) {
-                       DRM_ERROR("No memory\n");
-                       return -ENOMEM;
-               }
-               dev_priv->dbi_dpu_info = dpu_info;
-       }
-
-       dpu_info->dev = dev;
-
-       dpu_info->cursors[0].size = MDFLD_CURSOR_SIZE;
-       dpu_info->cursors[1].size = MDFLD_CURSOR_SIZE;
-
-       /*init dpu_update_lock*/
-       spin_lock_init(&dpu_info->dpu_update_lock);
-
-       /*init dpu refresh timer*/
-       mdfld_dbi_dpu_timer_init(dev, dpu_info);
-
-       /*init pipe damage area*/
-       mdfld_dpu_init_damage(dpu_info, 0);
-       mdfld_dpu_init_damage(dpu_info, 2);
-
-       return 0;
-}
-
-void mdfld_dbi_dpu_exit(struct drm_device *dev)
-{
-       struct drm_psb_private *dev_priv = dev->dev_private;
-       struct mdfld_dbi_dpu_info *dpu_info = dev_priv->dbi_dpu_info;
-
-       if (!dpu_info)
-               return;
-
-       del_timer_sync(&dpu_info->dpu_timer);
-       kfree(dpu_info);
-       dev_priv->dbi_dpu_info = NULL;
-}
-
-
diff --git a/drivers/staging/gma500/mdfld_dsi_dbi_dpu.h b/drivers/staging/gma500/mdfld_dsi_dbi_dpu.h
deleted file mode 100644 (file)
index 42367ed..0000000
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- * Copyright Â© 2010 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Authors:
- * jim liu <jim.liu@intel.com>
- * Jackie Li<yaodong.li@intel.com>
- */
-
-#ifndef __MDFLD_DSI_DBI_DPU_H__
-#define __MDFLD_DSI_DBI_DPU_H__
-
-#include "mdfld_dsi_dbi.h"
-
-typedef enum {
-       MDFLD_PLANEA,
-       MDFLD_PLANEC,
-       MDFLD_CURSORA,
-       MDFLD_CURSORC,
-       MDFLD_OVERLAYA,
-       MDFLD_OVERLAYC,
-       MDFLD_PLANE_NUM,
-} mdfld_plane_t;
-
-#define MDFLD_PIPEA_PLANE_MASK 0x15
-#define MDFLD_PIPEC_PLANE_MASK 0x2A
-
-struct mdfld_cursor_info {
-       int x, y;
-       int size;
-};
-
-#define MDFLD_CURSOR_SIZE      64
-
-/*
- * enter DSR mode if screen has no update for 2 frames.
- */
-#define MDFLD_MAX_IDLE_COUNT   2
-
-struct mdfld_dbi_dpu_info {
-       struct drm_device *dev;
-       /* Lock */
-       spinlock_t dpu_update_lock;
-
-       /* Cursor postion */
-       struct mdfld_cursor_info cursors[2];
-
-       /* Damaged area for each plane */
-       struct psb_drm_dpu_rect damaged_rects[MDFLD_PLANE_NUM];
-
-       /* Final damaged area */
-       struct psb_drm_dpu_rect damage_pipea;
-       struct psb_drm_dpu_rect damage_pipec;
-
-       /* Pending */
-       u32 pending;
-
-       /* DPU timer */
-       struct timer_list dpu_timer;
-       spinlock_t dpu_timer_lock;
-
-       /* DPU idle count */
-       u32 idle_count;
-
-       /* DSI outputs */
-       struct mdfld_dsi_dbi_output *dbi_outputs[2];
-       int dbi_output_num;
-};
-
-static inline int mdfld_dpu_region_extent(struct psb_drm_dpu_rect *origin,
-                        struct psb_drm_dpu_rect *rect)
-{
-       int x1, y1, x2, y2;
-
-       x1 = origin->x + origin->width;
-       y1 = origin->y + origin->height;
-
-       x2 = rect->x + rect->width;
-       y2 = rect->y + rect->height;
-
-       origin->x = min(origin->x, rect->x);
-       origin->y = min(origin->y, rect->y);
-       origin->width = max(x1, x2) - origin->x;
-       origin->height = max(y1, y2) - origin->y;
-
-       return 0;
-}
-
-static inline void mdfld_check_boundary(struct mdfld_dbi_dpu_info *dpu_info,
-                               struct psb_drm_dpu_rect *rect)
-{
-       if (rect->x < 0)
-               rect->x = 0;
-       if (rect->y < 0)
-               rect->y = 0;
-
-       if (rect->x + rect->width > 864)
-               rect->width = 864 - rect->x;
-       if (rect->y + rect->height > 480)
-               rect->height = 480 - rect->height;
-
-       if (!rect->width)
-               rect->width = 1;
-       if (!rect->height)
-               rect->height = 1;
-}
-
-static inline void mdfld_dpu_init_damage(struct mdfld_dbi_dpu_info *dpu_info,
-                               int pipe)
-{
-       struct psb_drm_dpu_rect *rect;
-
-       if (pipe == 0)
-               rect = &dpu_info->damage_pipea;
-       else
-               rect = &dpu_info->damage_pipec;
-
-       rect->x = 864;
-       rect->y = 480;
-       rect->width = -864;
-       rect->height = -480;
-}
-
-extern int mdfld_dsi_dbi_dsr_off(struct drm_device *dev,
-                               struct psb_drm_dpu_rect *rect);
-extern int mdfld_dbi_dpu_report_damage(struct drm_device *dev,
-                               mdfld_plane_t plane,
-                               struct psb_drm_dpu_rect *rect);
-extern int mdfld_dbi_dpu_report_fullscreen_damage(struct drm_device *dev);
-extern int mdfld_dpu_exit_dsr(struct drm_device *dev);
-extern void mdfld_dbi_dpu_timer_start(struct mdfld_dbi_dpu_info *dpu_info);
-extern int mdfld_dbi_dpu_init(struct drm_device *dev);
-extern void mdfld_dbi_dpu_exit(struct drm_device *dev);
-extern void mdfld_dpu_update_panel(struct drm_device *dev);
-
-#endif /*__MDFLD_DSI_DBI_DPU_H__*/
diff --git a/drivers/staging/gma500/mdfld_dsi_dpi.c b/drivers/staging/gma500/mdfld_dsi_dpi.c
deleted file mode 100644 (file)
index e685f12..0000000
+++ /dev/null
@@ -1,805 +0,0 @@
-/*
- * Copyright Â© 2010 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Authors:
- * jim liu <jim.liu@intel.com>
- * Jackie Li<yaodong.li@intel.com>
- */
-
-#include "mdfld_dsi_dpi.h"
-#include "mdfld_output.h"
-#include "mdfld_dsi_pkg_sender.h"
-
-
-static void mdfld_wait_for_HS_DATA_FIFO(struct drm_device *dev, u32 pipe)
-{
-       u32 gen_fifo_stat_reg = MIPIA_GEN_FIFO_STAT_REG;
-       int timeout = 0;
-
-       if (pipe == 2)
-               gen_fifo_stat_reg += MIPIC_REG_OFFSET;
-
-       udelay(500);
-
-       /* This will time out after approximately 2+ seconds */
-       while ((timeout < 20000) && (REG_READ(gen_fifo_stat_reg) & DSI_FIFO_GEN_HS_DATA_FULL)) {
-               udelay(100);
-               timeout++;
-       }
-
-       if (timeout == 20000)
-               dev_warn(dev->dev, "MIPI: HS Data FIFO was never cleared!\n");
-}
-
-static void mdfld_wait_for_HS_CTRL_FIFO(struct drm_device *dev, u32 pipe)
-{
-       u32 gen_fifo_stat_reg = MIPIA_GEN_FIFO_STAT_REG;
-       int timeout = 0;
-
-       if (pipe == 2)
-               gen_fifo_stat_reg += MIPIC_REG_OFFSET;
-
-       udelay(500);
-
-       /* This will time out after approximately 2+ seconds */
-       while ((timeout < 20000) && (REG_READ(gen_fifo_stat_reg) & DSI_FIFO_GEN_HS_CTRL_FULL)) {
-               udelay(100);
-               timeout++;
-       }
-       if (timeout == 20000)
-               dev_warn(dev->dev, "MIPI: HS CMD FIFO was never cleared!\n");
-}
-
-static void mdfld_wait_for_DPI_CTRL_FIFO(struct drm_device *dev, u32 pipe)
-{
-       u32 gen_fifo_stat_reg = MIPIA_GEN_FIFO_STAT_REG;
-        int timeout = 0;
-
-       if (pipe == 2)
-               gen_fifo_stat_reg += MIPIC_REG_OFFSET;
-
-        udelay(500);
-
-        /* This will time out after approximately 2+ seconds */
-        while ((timeout < 20000) && ((REG_READ(gen_fifo_stat_reg) & DPI_FIFO_EMPTY)
-                                                        != DPI_FIFO_EMPTY)) {
-                udelay(100);
-                timeout++;
-        }
-
-        if (timeout == 20000)
-                dev_warn(dev->dev, "MIPI: DPI FIFO was never cleared!\n");
-}
-
-static void mdfld_wait_for_SPL_PKG_SENT(struct drm_device *dev, u32 pipe)
-{
-       u32 intr_stat_reg = MIPIA_INTR_STAT_REG;
-       int timeout = 0;
-
-       if (pipe == 2)
-               intr_stat_reg += MIPIC_REG_OFFSET;
-
-        udelay(500);
-
-        /* This will time out after approximately 2+ seconds */
-        while ((timeout < 20000) && (!(REG_READ(intr_stat_reg) & DSI_INTR_STATE_SPL_PKG_SENT))) {
-                udelay(100);
-                timeout++;
-        }
-
-        if (timeout == 20000)
-                dev_warn(dev->dev, "MIPI: SPL_PKT_SENT_INTERRUPT was not sent successfully!\n");
-}
-
-
-/* ************************************************************************* *\
- * FUNCTION: mdfld_dsi_tpo_ic_init
- *
- * DESCRIPTION:  This function is called only by mrst_dsi_mode_set and
- *               restore_display_registers.  since this function does not
- *               acquire the mutex, it is important that the calling function
- *               does!
-\* ************************************************************************* */
-void mdfld_dsi_tpo_ic_init(struct mdfld_dsi_config *dsi_config, u32 pipe)
-{
-       struct drm_device *dev = dsi_config->dev;
-       u32 dcsChannelNumber = dsi_config->channel_num;
-       u32 gen_data_reg = MIPIA_HS_GEN_DATA_REG; 
-       u32 gen_ctrl_reg = MIPIA_HS_GEN_CTRL_REG;
-       u32 gen_ctrl_val = GEN_LONG_WRITE;
-
-       if (pipe == 2) {
-               gen_data_reg = HS_GEN_DATA_REG + MIPIC_REG_OFFSET; 
-               gen_ctrl_reg = HS_GEN_CTRL_REG + MIPIC_REG_OFFSET;
-       }
-
-       gen_ctrl_val |= dcsChannelNumber << DCS_CHANNEL_NUMBER_POS;
-
-       /* Flip page order */
-       mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
-       REG_WRITE(gen_data_reg, 0x00008036);
-       mdfld_wait_for_HS_CTRL_FIFO(dev, pipe);
-       REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x02 << WORD_COUNTS_POS));
-
-       /* 0xF0 */
-       mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
-       REG_WRITE(gen_data_reg, 0x005a5af0);
-       mdfld_wait_for_HS_CTRL_FIFO(dev, pipe);
-       REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x03 << WORD_COUNTS_POS));
-
-       /* Write protection key */
-       mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
-       REG_WRITE(gen_data_reg, 0x005a5af1);
-       mdfld_wait_for_HS_CTRL_FIFO(dev, pipe);
-       REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x03 << WORD_COUNTS_POS));
-
-       /* 0xFC */
-       mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
-       REG_WRITE(gen_data_reg, 0x005a5afc);
-       mdfld_wait_for_HS_CTRL_FIFO(dev, pipe);
-       REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x03 << WORD_COUNTS_POS));
-
-       /* 0xB7 */
-       mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
-       REG_WRITE(gen_data_reg, 0x770000b7);
-       mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
-       REG_WRITE(gen_data_reg, 0x00000044);
-       mdfld_wait_for_HS_CTRL_FIFO(dev, pipe);
-       REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x05 << WORD_COUNTS_POS));
-
-       /* 0xB6 */
-       mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
-       REG_WRITE(gen_data_reg, 0x000a0ab6);
-       mdfld_wait_for_HS_CTRL_FIFO(dev, pipe);
-       REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x03 << WORD_COUNTS_POS));
-
-       /* 0xF2 */
-       mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
-       REG_WRITE(gen_data_reg, 0x081010f2);
-       mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
-       REG_WRITE(gen_data_reg, 0x4a070708);
-       mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
-       REG_WRITE(gen_data_reg, 0x000000c5);
-       mdfld_wait_for_HS_CTRL_FIFO(dev, pipe);
-       REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x09 << WORD_COUNTS_POS));
-
-       /* 0xF8 */
-       mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
-       REG_WRITE(gen_data_reg, 0x024003f8);
-       mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
-       REG_WRITE(gen_data_reg, 0x01030a04);
-       mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
-       REG_WRITE(gen_data_reg, 0x0e020220);
-       mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
-       REG_WRITE(gen_data_reg, 0x00000004);
-       mdfld_wait_for_HS_CTRL_FIFO(dev, pipe);
-       REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x0d << WORD_COUNTS_POS));
-
-       /* 0xE2 */
-       mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
-       REG_WRITE(gen_data_reg, 0x398fc3e2);
-       mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
-       REG_WRITE(gen_data_reg, 0x0000916f);
-       mdfld_wait_for_HS_CTRL_FIFO(dev, pipe);
-       REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x06 << WORD_COUNTS_POS));
-
-       /* 0xB0 */
-       mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
-       REG_WRITE(gen_data_reg, 0x000000b0);
-       mdfld_wait_for_HS_CTRL_FIFO(dev, pipe);
-       REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x02 << WORD_COUNTS_POS));
-
-       /* 0xF4 */
-       mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
-       REG_WRITE(gen_data_reg, 0x240242f4);
-       mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
-       REG_WRITE(gen_data_reg, 0x78ee2002);
-       mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
-       REG_WRITE(gen_data_reg, 0x2a071050);
-       mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
-       REG_WRITE(gen_data_reg, 0x507fee10);
-       mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
-       REG_WRITE(gen_data_reg, 0x10300710);
-       mdfld_wait_for_HS_CTRL_FIFO(dev, pipe);
-       REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x14 << WORD_COUNTS_POS));
-
-       /* 0xBA */
-       mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
-       REG_WRITE(gen_data_reg, 0x19fe07ba);
-       mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
-       REG_WRITE(gen_data_reg, 0x101c0a31);
-       mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
-       REG_WRITE(gen_data_reg, 0x00000010);
-       mdfld_wait_for_HS_CTRL_FIFO(dev, pipe);
-       REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x09 << WORD_COUNTS_POS));
-
-       /* 0xBB */
-       mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
-       REG_WRITE(gen_data_reg, 0x28ff07bb);
-       mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
-       REG_WRITE(gen_data_reg, 0x24280a31);
-       mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
-       REG_WRITE(gen_data_reg, 0x00000034);
-       mdfld_wait_for_HS_CTRL_FIFO(dev, pipe);
-       REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x09 << WORD_COUNTS_POS));
-
-       /* 0xFB */
-       mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
-       REG_WRITE(gen_data_reg, 0x535d05fb);
-       mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
-       REG_WRITE(gen_data_reg, 0x1b1a2130);
-       mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
-       REG_WRITE(gen_data_reg, 0x221e180e);
-       mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
-       REG_WRITE(gen_data_reg, 0x131d2120);
-       mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
-       REG_WRITE(gen_data_reg, 0x535d0508);
-       mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
-       REG_WRITE(gen_data_reg, 0x1c1a2131);
-       mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
-       REG_WRITE(gen_data_reg, 0x231f160d);
-       mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
-       REG_WRITE(gen_data_reg, 0x111b2220);
-       mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
-       REG_WRITE(gen_data_reg, 0x535c2008);
-       mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
-       REG_WRITE(gen_data_reg, 0x1f1d2433);
-       mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
-       REG_WRITE(gen_data_reg, 0x2c251a10);
-       mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
-       REG_WRITE(gen_data_reg, 0x2c34372d);
-       mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
-       REG_WRITE(gen_data_reg, 0x00000023);
-       mdfld_wait_for_HS_CTRL_FIFO(dev, pipe);
-       REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x31 << WORD_COUNTS_POS));
-
-       /* 0xFA */
-       mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
-       REG_WRITE(gen_data_reg, 0x525c0bfa);
-       mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
-       REG_WRITE(gen_data_reg, 0x1c1c232f);
-       mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
-       REG_WRITE(gen_data_reg, 0x2623190e);
-       mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
-       REG_WRITE(gen_data_reg, 0x18212625);
-       mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
-       REG_WRITE(gen_data_reg, 0x545d0d0e);
-       mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
-       REG_WRITE(gen_data_reg, 0x1e1d2333);
-       mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
-       REG_WRITE(gen_data_reg, 0x26231a10);
-       mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
-       REG_WRITE(gen_data_reg, 0x1a222725);
-       mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
-       REG_WRITE(gen_data_reg, 0x545d280f);
-       mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
-       REG_WRITE(gen_data_reg, 0x21202635);
-       mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
-       REG_WRITE(gen_data_reg, 0x31292013);
-       mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
-       REG_WRITE(gen_data_reg, 0x31393d33);
-       mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
-       REG_WRITE(gen_data_reg, 0x00000029);
-       mdfld_wait_for_HS_CTRL_FIFO(dev, pipe);
-       REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x31 << WORD_COUNTS_POS));
-
-       /* Set DM */
-       mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
-       REG_WRITE(gen_data_reg, 0x000100f7);
-       mdfld_wait_for_HS_CTRL_FIFO(dev, pipe);
-       REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x03 << WORD_COUNTS_POS));
-}
-
-static u16 mdfld_dsi_dpi_to_byte_clock_count(int pixel_clock_count,
-                                               int num_lane, int bpp)
-{
-       return (u16)((pixel_clock_count * bpp) / (num_lane * 8)); 
-}
-
-/*
- * Calculate the dpi time basing on a given drm mode @mode
- * return 0 on success.
- * FIXME: I was using proposed mode value for calculation, may need to 
- * use crtc mode values later 
- */
-int mdfld_dsi_dpi_timing_calculation(struct drm_display_mode *mode, 
-                       struct mdfld_dsi_dpi_timing *dpi_timing,
-                       int num_lane, int bpp)
-{
-       int pclk_hsync, pclk_hfp, pclk_hbp, pclk_hactive;
-       int pclk_vsync, pclk_vfp, pclk_vbp, pclk_vactive;
-       
-       if(!mode || !dpi_timing) {
-               DRM_ERROR("Invalid parameter\n");
-               return -EINVAL;
-       }
-       
-       pclk_hactive = mode->hdisplay;
-       pclk_hfp = mode->hsync_start - mode->hdisplay;
-       pclk_hsync = mode->hsync_end - mode->hsync_start;
-       pclk_hbp = mode->htotal - mode->hsync_end;
-       
-       pclk_vactive = mode->vdisplay;
-       pclk_vfp = mode->vsync_start - mode->vdisplay;
-       pclk_vsync = mode->vsync_end - mode->vsync_start;
-       pclk_vbp = mode->vtotal - mode->vsync_end;
-
-       /*
-        * byte clock counts were calculated by following formula
-        * bclock_count = pclk_count * bpp / num_lane / 8
-        */
-       dpi_timing->hsync_count = mdfld_dsi_dpi_to_byte_clock_count(pclk_hsync, num_lane, bpp);
-       dpi_timing->hbp_count = mdfld_dsi_dpi_to_byte_clock_count(pclk_hbp, num_lane, bpp);
-       dpi_timing->hfp_count = mdfld_dsi_dpi_to_byte_clock_count(pclk_hfp, num_lane, bpp);
-       dpi_timing->hactive_count = mdfld_dsi_dpi_to_byte_clock_count(pclk_hactive, num_lane, bpp);
-       dpi_timing->vsync_count = mdfld_dsi_dpi_to_byte_clock_count(pclk_vsync, num_lane, bpp);
-       dpi_timing->vbp_count = mdfld_dsi_dpi_to_byte_clock_count(pclk_vbp, num_lane, bpp);
-       dpi_timing->vfp_count = mdfld_dsi_dpi_to_byte_clock_count(pclk_vfp, num_lane, bpp);
-
-       return 0; 
-}
-
-void mdfld_dsi_dpi_controller_init(struct mdfld_dsi_config *dsi_config, int pipe)
-{
-       struct drm_device *dev = dsi_config->dev;
-       u32 reg_offset = pipe ? MIPIC_REG_OFFSET : 0;
-       int lane_count = dsi_config->lane_count;
-       struct mdfld_dsi_dpi_timing dpi_timing;
-       struct drm_display_mode *mode = dsi_config->mode;
-       u32 val = 0;
-       
-       /*un-ready device*/
-       REG_WRITE((MIPIA_DEVICE_READY_REG + reg_offset), 0x00000000);
-       
-       /*init dsi adapter before kicking off*/
-       REG_WRITE((MIPIA_CONTROL_REG + reg_offset), 0x00000018);
-       
-       /*enable all interrupts*/
-       REG_WRITE((MIPIA_INTR_EN_REG + reg_offset), 0xffffffff);
-       
-
-       /*set up func_prg*/
-       val |= lane_count;
-       val |= dsi_config->channel_num << DSI_DPI_VIRT_CHANNEL_OFFSET;
-               
-       switch(dsi_config->bpp) {
-       case 16:
-               val |= DSI_DPI_COLOR_FORMAT_RGB565;
-               break;
-       case 18:
-               val |= DSI_DPI_COLOR_FORMAT_RGB666;
-               break;
-       case 24:
-               val |= DSI_DPI_COLOR_FORMAT_RGB888;
-               break;
-       default:
-               DRM_ERROR("unsupported color format, bpp = %d\n", dsi_config->bpp);
-       }
-       REG_WRITE((MIPIA_DSI_FUNC_PRG_REG + reg_offset), val);
-       
-       REG_WRITE((MIPIA_HS_TX_TIMEOUT_REG + reg_offset), 
-                       (mode->vtotal * mode->htotal * dsi_config->bpp / (8 * lane_count)) & DSI_HS_TX_TIMEOUT_MASK);
-       REG_WRITE((MIPIA_LP_RX_TIMEOUT_REG + reg_offset), 0xffff & DSI_LP_RX_TIMEOUT_MASK);
-       
-       /*max value: 20 clock cycles of txclkesc*/
-       REG_WRITE((MIPIA_TURN_AROUND_TIMEOUT_REG + reg_offset), 0x14 & DSI_TURN_AROUND_TIMEOUT_MASK);
-       
-       /*min 21 txclkesc, max: ffffh*/
-       REG_WRITE((MIPIA_DEVICE_RESET_TIMER_REG + reg_offset), 0xffff & DSI_RESET_TIMER_MASK);
-
-       REG_WRITE((MIPIA_DPI_RESOLUTION_REG + reg_offset), mode->vdisplay << 16 | mode->hdisplay);
-       
-       /*set DPI timing registers*/
-       mdfld_dsi_dpi_timing_calculation(mode, &dpi_timing, dsi_config->lane_count, dsi_config->bpp);
-       
-       REG_WRITE((MIPIA_HSYNC_COUNT_REG + reg_offset), dpi_timing.hsync_count & DSI_DPI_TIMING_MASK);
-       REG_WRITE((MIPIA_HBP_COUNT_REG + reg_offset), dpi_timing.hbp_count & DSI_DPI_TIMING_MASK);
-       REG_WRITE((MIPIA_HFP_COUNT_REG + reg_offset), dpi_timing.hfp_count & DSI_DPI_TIMING_MASK);
-       REG_WRITE((MIPIA_HACTIVE_COUNT_REG + reg_offset), dpi_timing.hactive_count & DSI_DPI_TIMING_MASK);
-       REG_WRITE((MIPIA_VSYNC_COUNT_REG + reg_offset), dpi_timing.vsync_count & DSI_DPI_TIMING_MASK);
-       REG_WRITE((MIPIA_VBP_COUNT_REG + reg_offset), dpi_timing.vbp_count & DSI_DPI_TIMING_MASK);
-       REG_WRITE((MIPIA_VFP_COUNT_REG + reg_offset), dpi_timing.vfp_count & DSI_DPI_TIMING_MASK);
-       
-       REG_WRITE((MIPIA_HIGH_LOW_SWITCH_COUNT_REG + reg_offset), 0x46);
-       
-       /*min: 7d0 max: 4e20*/
-       REG_WRITE((MIPIA_INIT_COUNT_REG + reg_offset), 0x000007d0);
-       
-       /*set up video mode*/
-       val = 0;
-       val = dsi_config->video_mode | DSI_DPI_COMPLETE_LAST_LINE;
-       REG_WRITE((MIPIA_VIDEO_MODE_FORMAT_REG + reg_offset), val);
-       
-       REG_WRITE((MIPIA_EOT_DISABLE_REG + reg_offset), 0x00000000);
-       
-       REG_WRITE((MIPIA_LP_BYTECLK_REG + reg_offset), 0x00000004);
-       
-       /*TODO: figure out how to setup these registers*/
-       REG_WRITE((MIPIA_DPHY_PARAM_REG + reg_offset), 0x150c3408);
-       
-       REG_WRITE((MIPIA_CLK_LANE_SWITCH_TIME_CNT_REG + reg_offset), (0xa << 16) | 0x14);
-       /*set device ready*/
-       REG_WRITE((MIPIA_DEVICE_READY_REG + reg_offset), 0x00000001);
-}
-
-void mdfld_dsi_dpi_turn_on(struct mdfld_dsi_dpi_output *output, int pipe)
-{
-       struct drm_device *dev = output->dev;
-       u32 reg_offset = 0;
-       
-       if(output->panel_on) 
-               return;
-               
-       if(pipe) 
-               reg_offset = MIPIC_REG_OFFSET;
-
-       /* clear special packet sent bit */
-       if(REG_READ(MIPIA_INTR_STAT_REG + reg_offset) & DSI_INTR_STATE_SPL_PKG_SENT) {
-               REG_WRITE((MIPIA_INTR_STAT_REG + reg_offset), DSI_INTR_STATE_SPL_PKG_SENT);
-       }
-               
-       /*send turn on package*/
-       REG_WRITE((MIPIA_DPI_CONTROL_REG + reg_offset), DSI_DPI_CTRL_HS_TURN_ON);
-       
-       /*wait for SPL_PKG_SENT interrupt*/
-       mdfld_wait_for_SPL_PKG_SENT(dev, pipe);
-       
-       if(REG_READ(MIPIA_INTR_STAT_REG + reg_offset) & DSI_INTR_STATE_SPL_PKG_SENT) {
-               REG_WRITE((MIPIA_INTR_STAT_REG + reg_offset), DSI_INTR_STATE_SPL_PKG_SENT);
-       }
-
-       output->panel_on = 1;
-
-       /* FIXME the following is disabled to WA the X slow start issue for TMD panel */
-       /* if(pipe == 2) */
-       /*      dev_priv->dpi_panel_on2 = true; */
-       /* else if (pipe == 0) */
-       /*      dev_priv->dpi_panel_on = true; */
-}
-
-static void mdfld_dsi_dpi_shut_down(struct mdfld_dsi_dpi_output *output, int pipe)
-{
-       struct drm_device *dev = output->dev;
-       u32 reg_offset = 0;
-       
-       /*if output is on, or mode setting didn't happen, ignore this*/
-       if((!output->panel_on) || output->first_boot) {
-               output->first_boot = 0; 
-               return;
-       }
-       
-       if(pipe)
-               reg_offset = MIPIC_REG_OFFSET;
-
-       /* Wait for dpi fifo to empty */
-       mdfld_wait_for_DPI_CTRL_FIFO(dev, pipe);
-
-       /* Clear the special packet interrupt bit if set */
-       if(REG_READ(MIPIA_INTR_STAT_REG + reg_offset) & DSI_INTR_STATE_SPL_PKG_SENT) {
-               REG_WRITE((MIPIA_INTR_STAT_REG + reg_offset), DSI_INTR_STATE_SPL_PKG_SENT);
-       }
-       
-       if(REG_READ(MIPIA_DPI_CONTROL_REG + reg_offset) == DSI_DPI_CTRL_HS_SHUTDOWN) {
-               dev_warn(dev->dev, "try to send the same package again, abort!");
-               goto shutdown_out;
-       }
-       
-       REG_WRITE((MIPIA_DPI_CONTROL_REG + reg_offset), DSI_DPI_CTRL_HS_SHUTDOWN);
-
-shutdown_out:
-       output->panel_on = 0;
-       output->first_boot = 0;
-
-       /* FIXME the following is disabled to WA the X slow start issue for TMD panel */
-       /* if(pipe == 2) */
-       /*      dev_priv->dpi_panel_on2 = false; */
-       /* else if (pipe == 0) */
-       /*      dev_priv->dpi_panel_on = false;  */
-       /* #ifdef CONFIG_PM_RUNTIME*/ 
-       /*      if (drm_psb_ospm && !enable_gfx_rtpm) { */
-       /*              pm_runtime_allow(&gpDrmDevice->pdev->dev); */
-       /*      schedule_delayed_work(&dev_priv->rtpm_work, 30 * 1000); */
-       /* } */
-       /*if (enable_gfx_rtpm) */
-       /*              pm_schedule_suspend(&dev->pdev->dev, gfxrtdelay); */
-       /* #endif */
-}
-
-void mdfld_dsi_dpi_set_power(struct drm_encoder *encoder, bool on)
-{
-       struct mdfld_dsi_encoder *dsi_encoder = MDFLD_DSI_ENCODER(encoder);
-       struct mdfld_dsi_dpi_output *dpi_output = MDFLD_DSI_DPI_OUTPUT(dsi_encoder);
-       struct mdfld_dsi_config *dsi_config = mdfld_dsi_encoder_get_config(dsi_encoder);
-       int pipe = mdfld_dsi_encoder_get_pipe(dsi_encoder);
-       struct drm_device *dev = dsi_config->dev;
-       struct drm_psb_private *dev_priv = dev->dev_private;
-       u32 mipi_reg = MIPI;
-       u32 pipeconf_reg = PIPEACONF;
-       
-       if(pipe) {
-               mipi_reg = MIPI_C;
-               pipeconf_reg = PIPECCONF;
-       }
-       
-       /* Start up display island if it was shutdown */
-       if (!gma_power_begin(dev, true))
-               return;
-
-       if(on) {
-               if (mdfld_get_panel_type(dev, pipe) == TMD_VID){
-                       mdfld_dsi_dpi_turn_on(dpi_output, pipe);
-               } else {
-                       /* Enable mipi port */
-                       REG_WRITE(mipi_reg, (REG_READ(mipi_reg) | (1 << 31)));
-                       REG_READ(mipi_reg);
-
-                       mdfld_dsi_dpi_turn_on(dpi_output, pipe);
-                       mdfld_dsi_tpo_ic_init(dsi_config, pipe);
-               }
-
-               if(pipe == 2) {
-                       dev_priv->dpi_panel_on2 = true;
-               }
-               else {
-                       dev_priv->dpi_panel_on  = true;
-               }
-
-       } else {
-               if (mdfld_get_panel_type(dev, pipe) == TMD_VID) {
-                       mdfld_dsi_dpi_shut_down(dpi_output, pipe);
-               } else {
-                       mdfld_dsi_dpi_shut_down(dpi_output, pipe);
-                       /* Disable mipi port */
-                       REG_WRITE(mipi_reg, (REG_READ(mipi_reg) & ~(1<<31)));
-                       REG_READ(mipi_reg);
-               }
-
-               if(pipe == 2)
-                       dev_priv->dpi_panel_on2 = false;
-               else
-                       dev_priv->dpi_panel_on  = false;
-       }
-       gma_power_end(dev);
-}
-
-void mdfld_dsi_dpi_dpms(struct drm_encoder *encoder, int mode)
-{
-       dev_dbg(encoder->dev->dev, "DPMS %s\n",
-                       (mode == DRM_MODE_DPMS_ON ? "on":"off"));
-
-       if (mode == DRM_MODE_DPMS_ON)
-               mdfld_dsi_dpi_set_power(encoder, true);
-       else {
-               mdfld_dsi_dpi_set_power(encoder, false);
-#if 0 /* FIXME */
-#ifdef CONFIG_PM_RUNTIME
-               if (enable_gfx_rtpm)
-                       pm_schedule_suspend(&gpDrmDevice->pdev->dev, gfxrtdelay);
-#endif
-#endif
-       }
-}
-
-bool mdfld_dsi_dpi_mode_fixup(struct drm_encoder *encoder,
-                                    struct drm_display_mode *mode,
-                                    struct drm_display_mode *adjusted_mode)
-{
-       struct mdfld_dsi_encoder *dsi_encoder = MDFLD_DSI_ENCODER(encoder);
-       struct mdfld_dsi_config *dsi_config = mdfld_dsi_encoder_get_config(dsi_encoder);
-       struct drm_display_mode *fixed_mode = dsi_config->fixed_mode;
-
-       if(fixed_mode) {
-               adjusted_mode->hdisplay = fixed_mode->hdisplay;
-               adjusted_mode->hsync_start = fixed_mode->hsync_start;
-               adjusted_mode->hsync_end = fixed_mode->hsync_end;
-               adjusted_mode->htotal = fixed_mode->htotal;
-               adjusted_mode->vdisplay = fixed_mode->vdisplay;
-               adjusted_mode->vsync_start = fixed_mode->vsync_start;
-               adjusted_mode->vsync_end = fixed_mode->vsync_end;
-               adjusted_mode->vtotal = fixed_mode->vtotal;
-               adjusted_mode->clock = fixed_mode->clock;
-               drm_mode_set_crtcinfo(adjusted_mode, CRTC_INTERLACE_HALVE_V);
-       }
-       
-       return true;
-}
-
-void mdfld_dsi_dpi_prepare(struct drm_encoder *encoder) 
-{
-       mdfld_dsi_dpi_set_power(encoder, false);
-}
-
-void mdfld_dsi_dpi_commit(struct drm_encoder *encoder) 
-{
-       mdfld_dsi_dpi_set_power(encoder, true);
-}
-
-void mdfld_dsi_dpi_mode_set(struct drm_encoder *encoder,
-                                  struct drm_display_mode *mode,
-                                  struct drm_display_mode *adjusted_mode)
-{
-       struct mdfld_dsi_encoder *dsi_encoder = MDFLD_DSI_ENCODER(encoder);
-       struct mdfld_dsi_dpi_output *dpi_output = MDFLD_DSI_DPI_OUTPUT(dsi_encoder);
-       struct mdfld_dsi_config *dsi_config = mdfld_dsi_encoder_get_config(dsi_encoder);
-       struct drm_device *dev = dsi_config->dev;
-       struct drm_psb_private *dev_priv = dev->dev_private;
-       int pipe = mdfld_dsi_encoder_get_pipe(dsi_encoder);
-       
-       u32 pipeconf_reg = PIPEACONF;
-       u32 dspcntr_reg = DSPACNTR;
-       u32 mipi_reg = MIPI;
-       u32 reg_offset = 0;
-       
-       u32 pipeconf = dev_priv->pipeconf;
-       u32 dspcntr = dev_priv->dspcntr;
-       u32 mipi = MIPI_PORT_EN | PASS_FROM_SPHY_TO_AFE | SEL_FLOPPED_HSTX;
-       
-       dev_dbg(dev->dev, "set mode %dx%d on pipe %d\n",
-                               mode->hdisplay, mode->vdisplay, pipe);
-
-       if(pipe) {
-               pipeconf_reg = PIPECCONF;
-               dspcntr_reg = DSPCCNTR;
-               mipi_reg = MIPI_C;
-               reg_offset = MIPIC_REG_OFFSET;
-       } else {
-               mipi |= 2;
-       }
-       
-       if (!gma_power_begin(dev, true))
-               return;
-
-       /* Set up mipi port FIXME: do at init time */
-       REG_WRITE(mipi_reg, mipi);
-       REG_READ(mipi_reg);
-
-       /* Set up DSI controller DPI interface */
-       mdfld_dsi_dpi_controller_init(dsi_config, pipe);
-
-       if (mdfld_get_panel_type(dev, pipe) != TMD_VID) {
-               /* Turn on DPI interface */
-               mdfld_dsi_dpi_turn_on(dpi_output, pipe);
-       }
-       
-       /* Set up pipe */
-       REG_WRITE(pipeconf_reg, pipeconf);
-       REG_READ(pipeconf_reg);
-       
-       /* Set up display plane */
-       REG_WRITE(dspcntr_reg, dspcntr);
-       REG_READ(dspcntr_reg);
-       
-       msleep(20); /* FIXME: this should wait for vblank */
-       
-       dev_dbg(dev->dev, "State %x, power %d\n",
-               REG_READ(MIPIA_INTR_STAT_REG + reg_offset),
-               dpi_output->panel_on);
-
-       if (mdfld_get_panel_type(dev, pipe) != TMD_VID) {
-               /* Init driver ic */
-               mdfld_dsi_tpo_ic_init(dsi_config, pipe);
-               /* Init backlight */
-               mdfld_dsi_brightness_init(dsi_config, pipe);
-       }
-       gma_power_end(dev);
-}
-
-
-/*
- * Init DSI DPI encoder. 
- * Allocate an mdfld_dsi_encoder and attach it to given @dsi_connector
- * return pointer of newly allocated DPI encoder, NULL on error
- */ 
-struct mdfld_dsi_encoder *mdfld_dsi_dpi_init(struct drm_device *dev, 
-                               struct mdfld_dsi_connector *dsi_connector,
-                               struct panel_funcs *p_funcs)
-{
-       struct mdfld_dsi_dpi_output *dpi_output = NULL;
-       struct mdfld_dsi_config *dsi_config;
-       struct drm_connector *connector = NULL;
-       struct drm_encoder *encoder = NULL;
-       struct drm_display_mode *fixed_mode = NULL;
-       int pipe;
-       u32 data;
-       int ret;
-
-       if (!dsi_connector || !p_funcs) {
-               WARN_ON(1);
-               return NULL;
-       }
-
-       dsi_config = mdfld_dsi_get_config(dsi_connector);
-       pipe = dsi_connector->pipe;
-
-       /* Panel hard-reset */
-       if (p_funcs->reset) {
-               ret = p_funcs->reset(pipe);
-               if (ret) {
-                       DRM_ERROR("Panel %d hard-reset failed\n", pipe);
-                       return NULL;
-               }
-       }
-
-       /* Panel drvIC init */
-       if (p_funcs->drv_ic_init)
-               p_funcs->drv_ic_init(dsi_config, pipe);
-
-       /* Panel power mode detect */
-       ret = mdfld_dsi_get_power_mode(dsi_config,
-                                       &data,
-                                       MDFLD_DSI_LP_TRANSMISSION);
-       if (ret) {
-               DRM_ERROR("Panel %d get power mode failed\n", pipe);
-               dsi_connector->status = connector_status_disconnected;
-       } else {
-               DRM_INFO("pipe %d power mode 0x%x\n", pipe, data);
-               dsi_connector->status = connector_status_connected;
-       }
-
-       dpi_output = kzalloc(sizeof(struct mdfld_dsi_dpi_output), GFP_KERNEL);
-       if(!dpi_output) {
-               dev_err(dev->dev, "No memory for dsi_dpi_output\n");
-               return NULL;
-       }
-
-       if(dsi_connector->pipe) 
-               dpi_output->panel_on = 0;
-       else
-               dpi_output->panel_on = 0;
-       
-       dpi_output->dev = dev;
-       dpi_output->p_funcs = p_funcs;
-       dpi_output->first_boot = 1;
-       
-       /* Get fixed mode */
-       dsi_config = mdfld_dsi_get_config(dsi_connector);
-       fixed_mode = dsi_config->fixed_mode;
-       
-       /* Create drm encoder object */
-       connector = &dsi_connector->base.base;
-       encoder = &dpi_output->base.base;
-       /*
-        * On existing hardware this will be a panel of some form,
-        * if future devices also have HDMI bridges this will need
-        * revisiting
-        */
-       drm_encoder_init(dev,
-                       encoder,
-                       p_funcs->encoder_funcs,
-                       DRM_MODE_ENCODER_LVDS);
-       drm_encoder_helper_add(encoder,
-                               p_funcs->encoder_helper_funcs);
-       
-       /* Attach to given connector */
-       drm_mode_connector_attach_encoder(connector, encoder);
-       
-       /* Set possible crtcs and clones */
-       if(dsi_connector->pipe) {
-               encoder->possible_crtcs = (1 << 2);
-               encoder->possible_clones = (1 << 1);
-       } else {
-               encoder->possible_crtcs = (1 << 0);
-               encoder->possible_clones = (1 << 0);
-       }
-       return &dpi_output->base;
-}
-
diff --git a/drivers/staging/gma500/mdfld_dsi_dpi.h b/drivers/staging/gma500/mdfld_dsi_dpi.h
deleted file mode 100644 (file)
index ed92d45..0000000
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyright Â© 2010 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Authors:
- * jim liu <jim.liu@intel.com>
- * Jackie Li<yaodong.li@intel.com>
- */
-
-#ifndef __MDFLD_DSI_DPI_H__
-#define __MDFLD_DSI_DPI_H__
-
-#include "mdfld_dsi_output.h"
-#include "mdfld_output.h"
-
-struct mdfld_dsi_dpi_timing {
-       u16 hsync_count;
-       u16 hbp_count;
-       u16 hfp_count;
-       u16 hactive_count;
-       u16 vsync_count;
-       u16 vbp_count;
-       u16 vfp_count;
-};
-
-struct mdfld_dsi_dpi_output {
-       struct mdfld_dsi_encoder base;
-       struct drm_device *dev;
-
-       int panel_on;
-       int first_boot;
-
-       struct panel_funcs *p_funcs;
-};
-
-#define MDFLD_DSI_DPI_OUTPUT(dsi_encoder) \
-       container_of(dsi_encoder, struct mdfld_dsi_dpi_output, base)
-
-extern int mdfld_dsi_dpi_timing_calculation(struct drm_display_mode *mode,
-                       struct mdfld_dsi_dpi_timing *dpi_timing,
-                       int num_lane, int bpp);
-extern struct mdfld_dsi_encoder *mdfld_dsi_dpi_init(struct drm_device *dev,
-                       struct mdfld_dsi_connector *dsi_connector,
-                       struct panel_funcs *p_funcs);
-
-/* Medfield DPI helper functions */
-extern void mdfld_dsi_dpi_dpms(struct drm_encoder *encoder, int mode);
-extern bool mdfld_dsi_dpi_mode_fixup(struct drm_encoder *encoder,
-                       struct drm_display_mode *mode,
-                       struct drm_display_mode *adjusted_mode);
-extern void mdfld_dsi_dpi_prepare(struct drm_encoder *encoder);
-extern void mdfld_dsi_dpi_commit(struct drm_encoder *encoder);
-extern void mdfld_dsi_dpi_mode_set(struct drm_encoder *encoder,
-                       struct drm_display_mode *mode,
-                       struct drm_display_mode *adjusted_mode);
-extern void mdfld_dsi_dpi_turn_on(struct mdfld_dsi_dpi_output *output,
-                       int pipe);
-extern void mdfld_dsi_dpi_controller_init(struct mdfld_dsi_config *si_config,
-                       int pipe);
-#endif /*__MDFLD_DSI_DPI_H__*/
diff --git a/drivers/staging/gma500/mdfld_dsi_output.c b/drivers/staging/gma500/mdfld_dsi_output.c
deleted file mode 100644 (file)
index 3f979db..0000000
+++ /dev/null
@@ -1,1014 +0,0 @@
-/*
- * Copyright Â© 2010 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Authors:
- * jim liu <jim.liu@intel.com>
- * Jackie Li<yaodong.li@intel.com>
- */
-
-#include "mdfld_dsi_output.h"
-#include "mdfld_dsi_dbi.h"
-#include "mdfld_dsi_dpi.h"
-#include "mdfld_output.h"
-#include <asm/intel_scu_ipc.h>
-#include "mdfld_dsi_pkg_sender.h"
-#include <linux/pm_runtime.h>
-#include <linux/moduleparam.h>
-
-#define MDFLD_DSI_BRIGHTNESS_MAX_LEVEL 100
-
-static int CABC_control = 1;
-static int LABC_control = 1;
-
-module_param (CABC_control, int, 0644);
-module_param (LABC_control, int, 0644);
-
-/**
- * make these MCS command global 
- * we don't need 'movl' everytime we send them.
- * FIXME: these datas were provided by OEM, we should get them from GCT.
- **/
-static u32 mdfld_dbi_mcs_hysteresis[] = {
-       0x42000f57, 0x8c006400, 0xff00bf00, 0xffffffff,
-       0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
-       0x38000aff, 0x82005000, 0xff00ab00, 0xffffffff,
-       0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
-       0x000000ff,
-};
-
-static u32 mdfld_dbi_mcs_display_profile[] = {
-       0x50281450, 0x0000c882, 0x00000000, 0x00000000,
-       0x00000000,
-};
-
-static u32 mdfld_dbi_mcs_kbbc_profile[] = {
-       0x00ffcc60, 0x00000000, 0x00000000, 0x00000000,
-}; 
-       
-static u32 mdfld_dbi_mcs_gamma_profile[] = {
-       0x81111158, 0x88888888, 0x88888888,
-}; 
-
-/*
- * write hysteresis values.
- */
-static void mdfld_dsi_write_hysteresis (struct mdfld_dsi_config *dsi_config,
-                                                                int pipe)
-{
-       struct mdfld_dsi_pkg_sender *sender = mdfld_dsi_get_pkg_sender(dsi_config);
-
-       if(!sender) {
-               WARN_ON(1);
-               return;
-       }
-       mdfld_dsi_send_mcs_long_hs(sender,
-                                  mdfld_dbi_mcs_hysteresis,
-                                  17,
-                                  MDFLD_DSI_SEND_PACKAGE);
-}
-
-/*
- * write display profile values.
- */
-static void mdfld_dsi_write_display_profile(struct mdfld_dsi_config *dsi_config, int pipe)
-{
-       struct mdfld_dsi_pkg_sender *sender = mdfld_dsi_get_pkg_sender(dsi_config);
-
-       if(!sender) {
-               WARN_ON(1);
-               return;
-        }
-       mdfld_dsi_send_mcs_long_hs(sender,
-                                  mdfld_dbi_mcs_display_profile,
-                                  5,
-                                  MDFLD_DSI_SEND_PACKAGE);
-}
-
-/*
- * write KBBC profile values.
- */
-static void mdfld_dsi_write_kbbc_profile (struct mdfld_dsi_config * dsi_config, int pipe)
-{
-       struct mdfld_dsi_pkg_sender *sender = mdfld_dsi_get_pkg_sender(dsi_config);
-
-       if(!sender) {
-               WARN_ON(1);
-               return;
-        }
-       mdfld_dsi_send_mcs_long_hs(sender,
-                                  mdfld_dbi_mcs_kbbc_profile,
-                                  4,
-                                  MDFLD_DSI_SEND_PACKAGE);
-}
-
-/*
- * write gamma setting.
- */
-static void mdfld_dsi_write_gamma_setting (struct mdfld_dsi_config *dsi_config, int pipe)
-{
-       struct mdfld_dsi_pkg_sender *sender = mdfld_dsi_get_pkg_sender(dsi_config);
-
-       if(!sender) {
-               WARN_ON(1);
-               return;
-       }
-       mdfld_dsi_send_mcs_long_hs(sender,
-                                  mdfld_dbi_mcs_gamma_profile,
-                                  3,
-                                  MDFLD_DSI_SEND_PACKAGE);
-}
-
-/*
- * Check and see if the generic control or data buffer is empty and ready.
- */
-void mdfld_dsi_gen_fifo_ready (struct drm_device *dev, u32 gen_fifo_stat_reg, u32 fifo_stat)
-{
-       u32 GEN_BF_time_out_count = 0;
-       
-       /* Check MIPI Adatper command registers */
-       for (GEN_BF_time_out_count = 0; GEN_BF_time_out_count < GEN_FB_TIME_OUT; GEN_BF_time_out_count++)
-       {
-               if ((REG_READ(gen_fifo_stat_reg) & fifo_stat) == fifo_stat)
-                       break;
-               udelay (100);
-       }
-
-       if (GEN_BF_time_out_count == GEN_FB_TIME_OUT)
-               dev_err(dev->dev,
-        "mdfld_dsi_gen_fifo_ready, Timeout. gen_fifo_stat_reg = 0x%x. \n",
-                                                gen_fifo_stat_reg);
-}
-
-/*
- * Manage the DSI MIPI keyboard and display brightness.
- * FIXME: this is exported to OSPM code. should work out an specific 
- * display interface to OSPM. 
- */
-void mdfld_dsi_brightness_init(struct mdfld_dsi_config *dsi_config, int pipe)
-{
-       struct mdfld_dsi_pkg_sender *sender = mdfld_dsi_get_pkg_sender(dsi_config);
-       struct drm_device *dev = sender->dev;
-       struct drm_psb_private *dev_priv = dev->dev_private;
-       u32 gen_ctrl_val;
-       
-       if(!sender) {
-               WARN_ON(1);
-               return;
-       }
-       /* Set default display backlight value to 85% (0xd8)*/
-       mdfld_dsi_send_mcs_short_hs(sender,
-                                   write_display_brightness,
-                                   0xd8,
-                                   1,
-                                   MDFLD_DSI_SEND_PACKAGE);
-
-       /* Set minimum brightness setting of CABC function to 20% (0x33)*/
-       mdfld_dsi_send_mcs_short_hs(sender,
-                                   write_cabc_min_bright,
-                                   0x33,
-                                   1,
-                                   MDFLD_DSI_SEND_PACKAGE);
-
-       mdfld_dsi_write_hysteresis(dsi_config, pipe);
-       mdfld_dsi_write_display_profile (dsi_config, pipe);
-       mdfld_dsi_write_kbbc_profile (dsi_config, pipe);
-       mdfld_dsi_write_gamma_setting (dsi_config, pipe);
-
-       /* Enable backlight or/and LABC */
-       gen_ctrl_val = BRIGHT_CNTL_BLOCK_ON | DISPLAY_DIMMING_ON| BACKLIGHT_ON;
-       if (LABC_control == 1 || CABC_control == 1)
-               gen_ctrl_val |= DISPLAY_DIMMING_ON| DISPLAY_BRIGHTNESS_AUTO | GAMMA_AUTO;
-
-       if (LABC_control == 1)
-               gen_ctrl_val |= AMBIENT_LIGHT_SENSE_ON;
-
-       dev_priv->mipi_ctrl_display = gen_ctrl_val;
-
-       mdfld_dsi_send_mcs_short_hs(sender,
-                                   write_ctrl_display,
-                                   (u8)gen_ctrl_val,
-                                   1,
-                                   MDFLD_DSI_SEND_PACKAGE);
-
-       if (CABC_control == 0)
-               return;
-       mdfld_dsi_send_mcs_short_hs(sender,
-                                   write_ctrl_cabc,
-                                   UI_IMAGE,
-                                   1,
-                                   MDFLD_DSI_SEND_PACKAGE);
-}
-
-/*
- * Manage the mipi display brightness.
- * TODO: refine this interface later
- */
-void mdfld_dsi_brightness_control(struct drm_device *dev, int pipe, int level)
-{
-       struct mdfld_dsi_pkg_sender *sender;
-       struct drm_psb_private *dev_priv;
-       struct mdfld_dsi_config *dsi_config;
-       u32 gen_ctrl_val;
-       int p_type;     
-       
-       if (!dev || (pipe != 0 && pipe != 2)) {
-               dev_err(dev->dev, "Invalid parameter\n");
-               return;
-       }
-
-       p_type = mdfld_get_panel_type(dev, 0);
-
-       dev_priv = dev->dev_private;
-
-       if(pipe)
-               dsi_config = dev_priv->dsi_configs[1];
-       else
-               dsi_config = dev_priv->dsi_configs[0];
-
-       sender = mdfld_dsi_get_pkg_sender(dsi_config);
-
-       if(!sender) {
-               WARN_ON(1);
-               return;
-       }
-
-       gen_ctrl_val = ((level * 0xff) / MDFLD_DSI_BRIGHTNESS_MAX_LEVEL) & 0xff;
-
-       dev_dbg(dev->dev,
-                "pipe = %d, gen_ctrl_val = %d.  \n", pipe, gen_ctrl_val);
-       
-       if(p_type == TMD_VID || p_type == TMD_CMD){
-               /* Set display backlight value */
-               mdfld_dsi_send_mcs_short_hs(sender, 
-                                       tmd_write_display_brightness, 
-                                       (u8)gen_ctrl_val, 
-                                        1, 
-                                       MDFLD_DSI_SEND_PACKAGE);                
-       } else {                        
-               /* Set display backlight value */
-               mdfld_dsi_send_mcs_short_hs(sender,
-                                   write_display_brightness,
-                                   (u8)gen_ctrl_val,
-                                    1,
-                                    MDFLD_DSI_SEND_PACKAGE);
-
-
-               /* Enable backlight control */
-               if (level == 0)
-                       gen_ctrl_val = 0;
-               else 
-                       gen_ctrl_val = dev_priv->mipi_ctrl_display;
-
-               mdfld_dsi_send_mcs_short_hs(sender,
-                                    write_ctrl_display,
-                                   (u8)gen_ctrl_val,
-                                   1,
-                                   MDFLD_DSI_SEND_PACKAGE);
-       }
-}
-
-/*
- * shut down DSI controller
- */ 
-void mdfld_dsi_controller_shutdown(struct mdfld_dsi_config * dsi_config, int pipe)
-{
-       struct drm_device * dev;
-       u32 reg_offset = pipe ? MIPIC_REG_OFFSET : 0;
-       int retry = 100;
-       
-       if (!dsi_config) {
-               WARN_ON(1);
-               return;
-       }
-       
-       dev = dsi_config->dev;
-       
-       if (!gma_power_begin(dev, true)) {
-               dev_err(dev->dev, "hw begin failed\n");
-               return;
-       }
-               
-       if(!(REG_READ(MIPIA_DEVICE_READY_REG + reg_offset) &  DSI_DEVICE_READY)) 
-               goto shutdown_out;
-       
-       /* Send shut down package, clean packet send bit first */
-       if(REG_READ(MIPIA_INTR_STAT_REG + reg_offset) & DSI_INTR_STATE_SPL_PKG_SENT) {
-               REG_WRITE((MIPIA_INTR_STAT_REG + reg_offset), 
-                               (REG_READ(MIPIA_INTR_STAT_REG + reg_offset) | DSI_INTR_STATE_SPL_PKG_SENT));
-       }
-       
-       /*send shut down package in HS*/
-       REG_WRITE((MIPIA_DPI_CONTROL_REG + reg_offset), DSI_DPI_CTRL_HS_SHUTDOWN);
-       
-       
-       /*
-        * make sure shut down is sent.
-        * FIXME: add max retry counter
-        */
-       while(!(REG_READ(MIPIA_INTR_STAT_REG + reg_offset) & DSI_INTR_STATE_SPL_PKG_SENT)) {
-               retry--;
-               
-               if(!retry) {
-                       dev_err(dev->dev, "timeout\n");
-                       break;
-               }
-       }
-       
-       /*sleep 1 ms to ensure shutdown finished*/
-       msleep(100);
-       
-       /*un-ready device*/
-       REG_WRITE((MIPIA_DEVICE_READY_REG + reg_offset),
-                          (REG_READ(MIPIA_DEVICE_READY_REG + reg_offset) & ~DSI_DEVICE_READY));
-
-shutdown_out:                     
-       gma_power_end(dev);
-}
-
-void mdfld_dsi_controller_startup(struct mdfld_dsi_config * dsi_config, int pipe)
-{
-       struct drm_device * dev;
-       u32 reg_offset = pipe ? MIPIC_REG_OFFSET : 0;
-       int retry = 100;
-       
-       
-       if (!dsi_config) {
-               WARN_ON(1);
-               return;
-       }
-       
-       dev = dsi_config->dev;
-       dev_dbg(dev->dev, "starting up DSI controller on pipe %d...\n", pipe);
-       
-       if (!gma_power_begin(dev, true)) {
-               dev_err(dev->dev, "hw begin failed\n");
-               return;
-       }
-       
-       if((REG_READ(MIPIA_DEVICE_READY_REG + reg_offset) & DSI_DEVICE_READY)) 
-               goto startup_out;
-       
-       /*if config DPI, turn on DPI interface*/
-       if(dsi_config->type == MDFLD_DSI_ENCODER_DPI) {
-               if(REG_READ(MIPIA_INTR_STAT_REG + reg_offset) & DSI_INTR_STATE_SPL_PKG_SENT) {
-                       REG_WRITE((MIPIA_INTR_STAT_REG + reg_offset), DSI_INTR_STATE_SPL_PKG_SENT);
-               }
-               
-               REG_WRITE((MIPIA_DPI_CONTROL_REG + reg_offset), DSI_DPI_CTRL_HS_TURN_ON);
-               
-               /*
-                * make sure shut down is sent.
-                * FIXME: add max retry counter
-                */
-               while(!(REG_READ(MIPIA_INTR_STAT_REG + reg_offset) & DSI_INTR_STATE_SPL_PKG_SENT)) {
-                       retry--;
-                       if(!retry) {
-                               dev_err(dev->dev, "timeout\n");
-                               break;
-                       }
-               }
-               
-               msleep(100);
-       }
-       
-       /*set device ready*/
-       REG_WRITE((MIPIA_DEVICE_READY_REG + reg_offset),
-                          (REG_READ(MIPIA_DEVICE_READY_REG + reg_offset) | DSI_DEVICE_READY));
-
-startup_out:   
-       gma_power_end(dev);
-}
-
-
-static int mdfld_dsi_get_panel_status(struct mdfld_dsi_config *dsi_config,
-                                       u8 dcs,
-                                       u32 *data,
-                                       u8 transmission)
-{
-       struct mdfld_dsi_pkg_sender *sender
-               = mdfld_dsi_get_pkg_sender(dsi_config);
-
-       if (!sender || !data) {
-               DRM_ERROR("Invalid parameter\n");
-               return -EINVAL;
-       }
-
-       if (transmission == MDFLD_DSI_HS_TRANSMISSION)
-               return mdfld_dsi_read_mcs_hs(sender, dcs, data, 1);
-       else if (transmission == MDFLD_DSI_LP_TRANSMISSION)
-               return mdfld_dsi_read_mcs_lp(sender, dcs, data, 1);
-       else
-               return -EINVAL;
-}
-
-int mdfld_dsi_get_power_mode(struct mdfld_dsi_config *dsi_config,
-                               u32 *mode,
-                               u8 transmission)
-{
-       if (!dsi_config || !mode) {
-               DRM_ERROR("Invalid parameter\n");
-               return -EINVAL;
-       }
-
-       return mdfld_dsi_get_panel_status(dsi_config, 0x0a, mode, transmission);
-}
-
-int mdfld_dsi_get_diagnostic_result(struct mdfld_dsi_config *dsi_config,
-                                       u32 *result,
-                                       u8 transmission)
-{
-       if (!dsi_config || !result) {
-               DRM_ERROR("Invalid parameter\n");
-               return -EINVAL;
-       }
-
-       return mdfld_dsi_get_panel_status(dsi_config, 0x0f, result,
-                                         transmission);
-}
-
-/*
- * NOTE: this function was used by OSPM.
- * TODO: will be removed later, should work out display interfaces for OSPM
- */
-void mdfld_dsi_controller_init(struct mdfld_dsi_config * dsi_config, int pipe)
-{
-       if(!dsi_config || ((pipe != 0) && (pipe != 2))) {
-               WARN_ON(1);
-               return;
-       }
-
-       if(dsi_config->type)
-               mdfld_dsi_dpi_controller_init(dsi_config, pipe);
-       else
-               mdfld_dsi_controller_dbi_init(dsi_config, pipe);
-}
-
-static void mdfld_dsi_connector_save(struct drm_connector * connector)
-{
-}
-
-static void mdfld_dsi_connector_restore(struct drm_connector * connector)
-{
-}
-
-static enum drm_connector_status mdfld_dsi_connector_detect(struct drm_connector * connector, bool force)
-{
-       struct psb_intel_output *psb_output
-                                       = to_psb_intel_output(connector);
-       struct mdfld_dsi_connector *dsi_connector
-                                       = MDFLD_DSI_CONNECTOR(psb_output);
-       return dsi_connector->status;
-}
-
-static int mdfld_dsi_connector_set_property(struct drm_connector *connector,
-                                       struct drm_property *property,
-                                       uint64_t value)
-{
-       struct drm_encoder *encoder = connector->encoder;
-
-       if (!strcmp(property->name, "scaling mode") && encoder) {
-               struct psb_intel_crtc * psb_crtc = to_psb_intel_crtc(encoder->crtc);
-               bool bTransitionFromToCentered;
-               uint64_t curValue;
-
-               if (!psb_crtc)
-                       goto set_prop_error;
-
-               switch (value) {
-               case DRM_MODE_SCALE_FULLSCREEN:
-                       break;
-               case DRM_MODE_SCALE_NO_SCALE:
-                       break;
-               case DRM_MODE_SCALE_ASPECT:
-                       break;
-               default:
-                       goto set_prop_error;
-               }
-
-               if (drm_connector_property_get_value(connector, property, &curValue))
-                       goto set_prop_error;
-
-               if (curValue == value)
-                       goto set_prop_done;
-
-               if (drm_connector_property_set_value(connector, property, value))
-                       goto set_prop_error;
-
-               bTransitionFromToCentered = (curValue == DRM_MODE_SCALE_NO_SCALE) ||
-                       (value == DRM_MODE_SCALE_NO_SCALE);
-
-               if (psb_crtc->saved_mode.hdisplay != 0 &&
-                   psb_crtc->saved_mode.vdisplay != 0) {
-                       if (bTransitionFromToCentered) {
-                               if (!drm_crtc_helper_set_mode(encoder->crtc, &psb_crtc->saved_mode,
-                                           encoder->crtc->x, encoder->crtc->y, encoder->crtc->fb))
-                                       goto set_prop_error;
-                       } else {
-                               struct drm_encoder_helper_funcs *pEncHFuncs  = encoder->helper_private;
-                               pEncHFuncs->mode_set(encoder, &psb_crtc->saved_mode,
-                                                    &psb_crtc->saved_adjusted_mode);
-                       }
-               }
-#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
-       } else if (!strcmp(property->name, "backlight") && encoder) {
-               struct drm_psb_private *dev_priv = encoder->dev->dev_private;
-               struct backlight_device *psb_bd = dev_priv->backlight_device;
-               dev_dbg(encoder->dev->dev, "backlight level = %d\n", (int)value);
-               if (drm_connector_property_set_value(connector, property, value))
-                       goto set_prop_error;
-               else {
-                       dev_dbg(encoder->dev->dev,
-                                       "set brightness to %d", (int)value);
-                       if (psb_bd) {
-                               psb_bd->props.brightness = value;
-                               backlight_update_status(psb_bd);
-                       }
-               }
-#endif
-       }
-set_prop_done:
-    return 0;
-set_prop_error:
-    return -1;
-}
-
-static void mdfld_dsi_connector_destroy(struct drm_connector *connector)
-{
-       struct psb_intel_output * psb_output = to_psb_intel_output(connector);
-       struct mdfld_dsi_connector * dsi_connector = MDFLD_DSI_CONNECTOR(psb_output);
-       struct mdfld_dsi_pkg_sender * sender;
-       
-       if(!dsi_connector)
-               return;
-       
-       drm_sysfs_connector_remove(connector);
-       drm_connector_cleanup(connector);
-       
-       sender = dsi_connector->pkg_sender;
-
-       mdfld_dsi_pkg_sender_destroy(sender);
-
-       kfree(dsi_connector);
-}
-
-static int mdfld_dsi_connector_get_modes(struct drm_connector * connector)
-{
-       struct psb_intel_output * psb_output = to_psb_intel_output(connector);
-       struct mdfld_dsi_connector * dsi_connector = MDFLD_DSI_CONNECTOR(psb_output);
-       struct mdfld_dsi_config * dsi_config = mdfld_dsi_get_config(dsi_connector);
-       struct drm_display_mode * fixed_mode = dsi_config->fixed_mode;
-       struct drm_display_mode * dup_mode = NULL;
-       struct drm_device * dev = connector->dev;
-       
-       connector->display_info.min_vfreq = 0;
-       connector->display_info.max_vfreq = 200;
-       connector->display_info.min_hfreq = 0;
-       connector->display_info.max_hfreq = 200;
-
-       if(fixed_mode) {
-               dev_dbg(dev->dev, "fixed_mode %dx%d\n",
-                       fixed_mode->hdisplay, fixed_mode->vdisplay);
-               
-               dup_mode = drm_mode_duplicate(dev, fixed_mode);
-               drm_mode_probed_add(connector, dup_mode);
-               return 1;
-       }
-       dev_err(dev->dev, "Didn't get any modes!\n");
-       return 0;
-}
-
-static int mdfld_dsi_connector_mode_valid(struct drm_connector * connector, struct drm_display_mode * mode)
-{
-       struct psb_intel_output * psb_output = to_psb_intel_output(connector);
-       struct mdfld_dsi_connector * dsi_connector = MDFLD_DSI_CONNECTOR(psb_output);
-       struct mdfld_dsi_config * dsi_config = mdfld_dsi_get_config(dsi_connector);
-       struct drm_display_mode * fixed_mode = dsi_config->fixed_mode;
-
-       dev_dbg(connector->dev->dev, "mode %p, fixed mode %p\n",
-                                                       mode, fixed_mode);
-
-       if(mode->flags & DRM_MODE_FLAG_DBLSCAN) 
-               return MODE_NO_DBLESCAN;
-
-       if(mode->flags & DRM_MODE_FLAG_INTERLACE)
-               return MODE_NO_INTERLACE;
-
-       /**
-        * FIXME: current DC has no fitting unit, reject any mode setting request
-        * will figure out a way to do up-scaling(pannel fitting) later.  
-        **/
-       if(fixed_mode) {
-               if(mode->hdisplay != fixed_mode->hdisplay)
-                       return MODE_PANEL;
-
-               if(mode->vdisplay != fixed_mode->vdisplay)
-                       return MODE_PANEL;
-       }
-       dev_dbg(connector->dev->dev, "mode ok\n");
-
-       return MODE_OK;
-}
-
-static void mdfld_dsi_connector_dpms(struct drm_connector *connector, int mode)
-{
-#ifdef CONFIG_PM_RUNTIME
-       struct drm_device * dev = connector->dev;
-       struct drm_psb_private * dev_priv = dev->dev_private;
-       bool panel_on, panel_on2;
-#endif
-       /* First, execute DPMS */
-       drm_helper_connector_dpms(connector, mode);
-
-#ifdef CONFIG_PM_RUNTIME
-       if(mdfld_panel_dpi(dev)) {
-               /* DPI panel */
-               panel_on = dev_priv->dpi_panel_on;
-               panel_on2 = dev_priv->dpi_panel_on2;
-       } else {
-               /* DBI panel */
-               panel_on = dev_priv->dbi_panel_on;
-               panel_on2 = dev_priv->dbi_panel_on2;
-       }
-
-       /* Then check all display panels + monitors status */
-       /* Make sure that the Display (B) sub-system status isn't i3 when
-        * R/W the DC register, otherwise "Fabric error" issue would occur
-        * during S0i3 state. */
-       if(!panel_on && !panel_on2 && !(REG_READ(HDMIB_CONTROL)
-                                               & HDMIB_PORT_EN)) {
-               /* Request rpm idle */
-               if(dev_priv->rpm_enabled)
-                       pm_request_idle(&dev->pdev->dev);
-       }
-       /*
-        * if rpm wasn't enabled yet, try to allow it
-        * FIXME: won't enable rpm for DPI since DPI
-        * CRTC setting is a little messy now.
-        * Enable it later!
-        */
-#if 0
-       if(!dev_priv->rpm_enabled && !mdfld_panel_dpi(dev))
-               ospm_runtime_pm_allow(dev);
-#endif
-#endif
-}
-
-static struct drm_encoder *mdfld_dsi_connector_best_encoder(
-                                        struct drm_connector *connector) 
-{
-       struct psb_intel_output * psb_output = to_psb_intel_output(connector);
-       struct mdfld_dsi_connector * dsi_connector = MDFLD_DSI_CONNECTOR(psb_output);
-       struct mdfld_dsi_config * dsi_config = mdfld_dsi_get_config(dsi_connector);
-       struct mdfld_dsi_encoder * encoder = NULL;
-       
-       if(dsi_config->type == MDFLD_DSI_ENCODER_DBI) 
-               encoder = dsi_config->encoders[MDFLD_DSI_ENCODER_DBI];
-       else if (dsi_config->type == MDFLD_DSI_ENCODER_DPI) 
-               encoder = dsi_config->encoders[MDFLD_DSI_ENCODER_DPI];
-       
-       dev_dbg(connector->dev->dev, "get encoder %p\n", encoder);
-       
-       if(!encoder) {
-               dev_err(connector->dev->dev,
-                        "Invalid encoder for type %d\n", dsi_config->type);
-               return NULL;
-       }
-       dsi_config->encoder = encoder;  
-       return &encoder->base;  
-}
-
-/* DSI connector funcs */
-static const struct drm_connector_funcs mdfld_dsi_connector_funcs = {
-       .dpms = /*drm_helper_connector_dpms*/mdfld_dsi_connector_dpms,
-       .save = mdfld_dsi_connector_save,
-       .restore = mdfld_dsi_connector_restore,
-       .detect = mdfld_dsi_connector_detect,
-       .fill_modes = drm_helper_probe_single_connector_modes,
-       .set_property = mdfld_dsi_connector_set_property,
-       .destroy = mdfld_dsi_connector_destroy,
-};
-
-/* DSI connector helper funcs */
-static const struct drm_connector_helper_funcs mdfld_dsi_connector_helper_funcs = {
-       .get_modes = mdfld_dsi_connector_get_modes,
-       .mode_valid = mdfld_dsi_connector_mode_valid,
-       .best_encoder = mdfld_dsi_connector_best_encoder,
-};
-
-static int mdfld_dsi_get_default_config(struct drm_device * dev, 
-                                                                               struct mdfld_dsi_config * config, int pipe)
-{
-       if(!dev || !config) {
-               WARN_ON(1);
-               return -EINVAL;
-       }
-       
-       config->bpp = 24;
-       config->type = mdfld_panel_dpi(dev);
-       config->lane_count = 2;
-       config->channel_num = 0;
-       /*NOTE: video mode is ignored when type is MDFLD_DSI_ENCODER_DBI*/
-       if (mdfld_get_panel_type(dev, pipe) == TMD_VID) {
-               config->video_mode = MDFLD_DSI_VIDEO_NON_BURST_MODE_SYNC_PULSE;
-       } else {
-               config->video_mode = MDFLD_DSI_VIDEO_BURST_MODE;
-       }
-       
-       return 0;
-}
-
-/*
- * Returns the panel fixed mode from configuration. 
- */
-struct drm_display_mode *
-mdfld_dsi_get_configuration_mode(struct mdfld_dsi_config * dsi_config, int pipe)
-{
-       struct drm_device *dev = dsi_config->dev;
-       struct drm_display_mode *mode;
-       struct drm_psb_private *dev_priv = dev->dev_private;
-       struct mrst_timing_info *ti = &dev_priv->gct_data.DTD;
-       bool use_gct = false;
-
-       mode = kzalloc(sizeof(*mode), GFP_KERNEL);
-       if (!mode) {
-               dev_err(dev->dev, "Out of memory for mode\n");
-               return NULL;
-        }
-       if (use_gct) {
-               dev_dbg(dev->dev, "gct find MIPI panel.\n");
-
-               mode->hdisplay = (ti->hactive_hi << 8) | ti->hactive_lo;
-               mode->vdisplay = (ti->vactive_hi << 8) | ti->vactive_lo;
-               mode->hsync_start = mode->hdisplay + \
-                               ((ti->hsync_offset_hi << 8) | \
-                               ti->hsync_offset_lo);
-               mode->hsync_end = mode->hsync_start + \
-                               ((ti->hsync_pulse_width_hi << 8) | \
-                               ti->hsync_pulse_width_lo);
-               mode->htotal = mode->hdisplay + ((ti->hblank_hi << 8) | \
-                                                               ti->hblank_lo);
-               mode->vsync_start = \
-                       mode->vdisplay + ((ti->vsync_offset_hi << 8) | \
-                                               ti->vsync_offset_lo);
-               mode->vsync_end = \
-                       mode->vsync_start + ((ti->vsync_pulse_width_hi << 8) | \
-                                               ti->vsync_pulse_width_lo);
-               mode->vtotal = mode->vdisplay + \
-                               ((ti->vblank_hi << 8) | ti->vblank_lo);
-               mode->clock = ti->pixel_clock * 10;
-       } else {
-               if(dsi_config->type == MDFLD_DSI_ENCODER_DPI) { 
-                       if (mdfld_get_panel_type(dev, pipe) == TMD_VID) {
-                               mode->hdisplay = 480;
-                               mode->vdisplay = 854;
-                               mode->hsync_start = 487;
-                               mode->hsync_end = 490;
-                               mode->htotal = 499;
-                               mode->vsync_start = 861;
-                               mode->vsync_end = 865;
-                               mode->vtotal = 873;
-                               mode->clock = 33264;
-                       } else {
-                               mode->hdisplay = 864;
-                               mode->vdisplay = 480;
-                               mode->hsync_start = 873;
-                               mode->hsync_end = 876;
-                               mode->htotal = 887;
-                               mode->vsync_start = 487;
-                               mode->vsync_end = 490;
-                               mode->vtotal = 499;
-                               mode->clock = 33264;
-                       }
-               } else if(dsi_config->type == MDFLD_DSI_ENCODER_DBI) {
-                       mode->hdisplay = 864;
-                       mode->vdisplay = 480;
-                       mode->hsync_start = 872;
-                       mode->hsync_end = 876;
-                       mode->htotal = 884;
-                       mode->vsync_start = 482;
-                       mode->vsync_end = 494;
-                       mode->vtotal = 486;
-                       mode->clock = 25777;
-                       
-               }
-       }
-
-       drm_mode_set_name(mode);
-       drm_mode_set_crtcinfo(mode, 0);
-       
-       mode->type |= DRM_MODE_TYPE_PREFERRED;
-
-       return mode;
-}
-
-int mdfld_dsi_panel_reset(int pipe)
-{
-       unsigned gpio;
-       int ret = 0;
-
-       switch (pipe) {
-       case 0:
-               gpio = 128;
-               break;
-       case 2:
-               gpio = 34;
-               break;
-       default:
-               DRM_ERROR("Invalid output\n");
-               return -EINVAL;
-       }
-
-       ret = gpio_request(gpio, "gfx");
-       if (ret) {
-               DRM_ERROR("gpio_rqueset failed\n");
-               return ret;
-       }
-
-       ret = gpio_direction_output(gpio, 1);
-       if (ret) {
-               DRM_ERROR("gpio_direction_output failed\n");
-               goto gpio_error;
-       }
-
-       gpio_get_value(128);
-
-gpio_error:
-       if (gpio_is_valid(gpio))
-               gpio_free(gpio);
-
-       return ret;
-}
-
-/*
- * MIPI output init
- * @dev drm device
- * @pipe pipe number. 0 or 2
- * @config 
- * 
- * Do the initialization of a MIPI output, including create DRM mode objects
- * initialization of DSI output on @pipe 
- */
-void mdfld_dsi_output_init(struct drm_device *dev,
-                          int pipe, 
-                          struct mdfld_dsi_config *config,
-                          struct panel_funcs* p_cmd_funcs,
-                          struct panel_funcs* p_vid_funcs)
-{
-       struct mdfld_dsi_config * dsi_config;
-       struct mdfld_dsi_connector * dsi_connector;
-       struct psb_intel_output * psb_output;
-       struct drm_connector * connector;
-       struct mdfld_dsi_encoder * encoder;
-       struct drm_psb_private * dev_priv = dev->dev_private;
-       struct panel_info dsi_panel_info;
-       u32 width_mm, height_mm;
-
-       dev_dbg(dev->dev, "init DSI output on pipe %d\n", pipe);
-       
-       if(!dev || ((pipe != 0) && (pipe != 2))) {
-               WARN_ON(1);
-               return;
-       }
-       
-       /*create a new connetor*/
-       dsi_connector = kzalloc(sizeof(struct mdfld_dsi_connector), GFP_KERNEL);
-       if(!dsi_connector) {
-               DRM_ERROR("No memory");
-               return;
-       }
-       
-       dsi_connector->pipe =  pipe;
-       
-       /*set DSI config*/
-       if(config) { 
-               dsi_config = config;
-       } else {
-               dsi_config = kzalloc(sizeof(struct mdfld_dsi_config), GFP_KERNEL);
-               if(!dsi_config) {
-                       dev_err(dev->dev,
-                               "cannot allocate memory for DSI config\n");
-                       goto dsi_init_err0;
-               }
-               
-               mdfld_dsi_get_default_config(dev, dsi_config, pipe);
-       }
-       
-       dsi_connector->private = dsi_config;
-       
-       dsi_config->changed = 1;
-       dsi_config->dev = dev;
-       
-       /* Init fixed mode basing on DSI config type */
-       if(dsi_config->type == MDFLD_DSI_ENCODER_DBI) {
-               dsi_config->fixed_mode = p_cmd_funcs->get_config_mode(dev);
-               if(p_cmd_funcs->get_panel_info(dev, pipe, &dsi_panel_info))
-                       goto dsi_init_err0;
-       } else if(dsi_config->type == MDFLD_DSI_ENCODER_DPI) {
-               dsi_config->fixed_mode = p_vid_funcs->get_config_mode(dev);
-               if(p_vid_funcs->get_panel_info(dev, pipe, &dsi_panel_info))
-                       goto dsi_init_err0;
-       }
-
-       width_mm = dsi_panel_info.width_mm;
-       height_mm = dsi_panel_info.height_mm;
-
-       dsi_config->mode = dsi_config->fixed_mode;
-       dsi_config->connector = dsi_connector;
-       
-       if(!dsi_config->fixed_mode) {
-               dev_err(dev->dev, "No pannel fixed mode was found\n");
-               goto dsi_init_err0;
-       }
-       
-       if(pipe && dev_priv->dsi_configs[0]) {
-               dsi_config->dvr_ic_inited = 0;
-               dev_priv->dsi_configs[1] = dsi_config;
-       } else if(pipe == 0) {
-               dsi_config->dvr_ic_inited = 1;
-               dev_priv->dsi_configs[0] = dsi_config;
-       } else {
-               dev_err(dev->dev, "Trying to init MIPI1 before MIPI0\n");
-               goto dsi_init_err0;
-       }
-
-       /*init drm connector object*/
-       psb_output = &dsi_connector->base;
-       
-       psb_output->type = (pipe == 0) ? INTEL_OUTPUT_MIPI : INTEL_OUTPUT_MIPI2;
-
-       connector = &psb_output->base;
-       /* Revisit type if MIPI/HDMI bridges ever appear on Medfield */
-       drm_connector_init(dev, connector, &mdfld_dsi_connector_funcs,
-                                               DRM_MODE_CONNECTOR_LVDS);
-       drm_connector_helper_add(connector, &mdfld_dsi_connector_helper_funcs);
-       
-       connector->display_info.subpixel_order = SubPixelHorizontalRGB;
-       connector->display_info.width_mm = width_mm;
-       connector->display_info.height_mm = height_mm;
-       connector->interlace_allowed = false;
-       connector->doublescan_allowed = false;
-       
-       /* Attach properties */
-       drm_connector_attach_property(connector, dev->mode_config.scaling_mode_property, DRM_MODE_SCALE_FULLSCREEN);
-       drm_connector_attach_property(connector, dev_priv->backlight_property, MDFLD_DSI_BRIGHTNESS_MAX_LEVEL);
-
-       /* Init DSI package sender on this output */
-       if (mdfld_dsi_pkg_sender_init(dsi_connector, pipe)) {
-               DRM_ERROR("Package Sender initialization failed on pipe %d\n", pipe);
-               goto dsi_init_err0;
-       }
-
-       /* Init DBI & DPI encoders */
-       if (p_cmd_funcs) {
-               encoder = mdfld_dsi_dbi_init(dev, dsi_connector, p_cmd_funcs);
-               if(!encoder) {
-                       dev_err(dev->dev, "Create DBI encoder failed\n");
-                       goto dsi_init_err1;
-               }
-               encoder->private = dsi_config;
-               dsi_config->encoders[MDFLD_DSI_ENCODER_DBI] = encoder;
-       }
-       
-       if(p_vid_funcs) {
-               encoder = mdfld_dsi_dpi_init(dev, dsi_connector, p_vid_funcs);
-               if(!encoder) {
-                       dev_err(dev->dev, "Create DPI encoder failed\n");
-                       goto dsi_init_err1;
-               }
-               encoder->private = dsi_config;
-               dsi_config->encoders[MDFLD_DSI_ENCODER_DPI] = encoder;
-       }
-       
-       drm_sysfs_connector_add(connector);
-       return;
-       
-       /*TODO: add code to destroy outputs on error*/
-dsi_init_err1:
-       /*destroy sender*/
-       mdfld_dsi_pkg_sender_destroy(dsi_connector->pkg_sender);
-
-       drm_connector_cleanup(connector);
-       kfree(dsi_config->fixed_mode);
-       kfree(dsi_config);
-dsi_init_err0:
-       kfree(dsi_connector);
-}
diff --git a/drivers/staging/gma500/mdfld_dsi_output.h b/drivers/staging/gma500/mdfld_dsi_output.h
deleted file mode 100644 (file)
index 4699267..0000000
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * Copyright Â© 2010 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Authors:
- * jim liu <jim.liu@intel.com>
- * Jackie Li<yaodong.li@intel.com>
- */
-
-#ifndef __MDFLD_DSI_OUTPUT_H__
-#define __MDFLD_DSI_OUTPUT_H__
-
-#include <linux/backlight.h>
-#include <drm/drmP.h>
-#include <drm/drm.h>
-#include <drm/drm_crtc.h>
-#include <drm/drm_edid.h>
-
-#include "psb_drv.h"
-#include "psb_intel_drv.h"
-#include "psb_intel_reg.h"
-#include "power.h"
-#include "mdfld_output.h"
-
-#include <asm/mrst.h>
-
-
-static inline struct mdfld_dsi_config *
-       mdfld_dsi_get_config(struct mdfld_dsi_connector *connector)
-{
-       if (!connector)
-               return NULL;
-       return (struct mdfld_dsi_config *)connector->private;
-}
-
-static inline void *mdfld_dsi_get_pkg_sender(struct mdfld_dsi_config *config)
-{
-       struct mdfld_dsi_connector *dsi_connector;
-
-       if (!config)
-               return NULL;
-
-       dsi_connector = config->connector;
-
-       if (!dsi_connector)
-               return NULL;
-
-       return dsi_connector->pkg_sender;
-}
-
-static inline struct mdfld_dsi_config *
-       mdfld_dsi_encoder_get_config(struct mdfld_dsi_encoder *encoder)
-{
-       if (!encoder)
-               return NULL;
-       return (struct mdfld_dsi_config *)encoder->private;
-}
-
-static inline struct mdfld_dsi_connector *
-       mdfld_dsi_encoder_get_connector(struct mdfld_dsi_encoder *encoder)
-{
-       struct mdfld_dsi_config *config;
-
-       if (!encoder)
-               return NULL;
-
-       config = mdfld_dsi_encoder_get_config(encoder);
-       if (!config)
-               return NULL;
-
-       return config->connector;
-}
-
-static inline void *mdfld_dsi_encoder_get_pkg_sender(
-       struct mdfld_dsi_encoder *encoder)
-{
-       struct mdfld_dsi_config *dsi_config;
-
-       dsi_config = mdfld_dsi_encoder_get_config(encoder);
-       if (!dsi_config)
-               return NULL;
-
-       return mdfld_dsi_get_pkg_sender(dsi_config);
-}
-
-static inline int mdfld_dsi_encoder_get_pipe(struct mdfld_dsi_encoder *encoder)
-{
-       struct mdfld_dsi_connector *connector;
-
-       if (!encoder)
-               return -1;
-
-       connector = mdfld_dsi_encoder_get_connector(encoder);
-       if (!connector)
-               return -1;
-
-       return connector->pipe;
-}
-
-extern void mdfld_dsi_gen_fifo_ready(struct drm_device *dev,
-                               u32 gen_fifo_stat_reg, u32 fifo_stat);
-extern void mdfld_dsi_brightness_init(struct mdfld_dsi_config *dsi_config,
-                               int pipe);
-extern void mdfld_dsi_brightness_control(struct drm_device *dev, int pipe,
-                               int level);
-extern void mdfld_dsi_output_init(struct drm_device *dev, int pipe,
-                               struct mdfld_dsi_config *config,
-                               struct panel_funcs *p_cmd_funcs,
-                               struct panel_funcs *p_vid_funcs);
-extern void mdfld_dsi_controller_init(struct mdfld_dsi_config *dsi_config,
-                               int pipe);
-extern int mdfld_dsi_get_power_mode(struct mdfld_dsi_config *dsi_config,
-                               u32 *mode,
-                               u8 transmission);
-extern int mdfld_dsi_get_diagnostic_result(struct mdfld_dsi_config *dsi_config,
-                               u32 *result,
-                               u8 transmission);
-extern int mdfld_dsi_panel_reset(int pipe);
-
-#endif /*__MDFLD_DSI_OUTPUT_H__*/
diff --git a/drivers/staging/gma500/mdfld_dsi_pkg_sender.c b/drivers/staging/gma500/mdfld_dsi_pkg_sender.c
deleted file mode 100644 (file)
index 9b96a5c..0000000
+++ /dev/null
@@ -1,1484 +0,0 @@
-/*
- * Copyright Â© 2010 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Authors:
- * Jackie Li<yaodong.li@intel.com>
- */
-
-#include <linux/freezer.h>
-
-#include "mdfld_dsi_output.h"
-#include "mdfld_dsi_pkg_sender.h"
-#include "mdfld_dsi_dbi.h"
-#include "mdfld_dsi_dpi.h"
-
-#define MDFLD_DSI_DBI_FIFO_TIMEOUT             100
-#define MDFLD_DSI_MAX_RETURN_PACKET_SIZE       512
-#define MDFLD_DSI_READ_MAX_COUNT               5000
-
-static const char * const dsi_errors[] = {
-       "RX SOT Error",
-       "RX SOT Sync Error",
-       "RX EOT Sync Error",
-       "RX Escape Mode Entry Error",
-       "RX LP TX Sync Error",
-       "RX HS Receive Timeout Error",
-       "RX False Control Error",
-       "RX ECC Single Bit Error",
-       "RX ECC Multibit Error",
-       "RX Checksum Error",
-       "RX DSI Data Type Not Recognised",
-       "RX DSI VC ID Invalid",
-       "TX False Control Error",
-       "TX ECC Single Bit Error",
-       "TX ECC Multibit Error",
-       "TX Checksum Error",
-       "TX DSI Data Type Not Recognised",
-       "TX DSI VC ID invalid",
-       "High Contention",
-       "Low contention",
-       "DPI FIFO Under run",
-       "HS TX Timeout",
-       "LP RX Timeout",
-       "Turn Around ACK Timeout",
-       "ACK With No Error",
-       "RX Invalid TX Length",
-       "RX Prot Violation",
-       "HS Generic Write FIFO Full",
-       "LP Generic Write FIFO Full",
-       "Generic Read Data Avail",
-       "Special Packet Sent",
-       "Tearing Effect",
-};
-
-static int wait_for_gen_fifo_empty(struct mdfld_dsi_pkg_sender *sender,
-                                                               u32 mask)
-{
-       struct drm_device *dev = sender->dev;
-       u32 gen_fifo_stat_reg = sender->mipi_gen_fifo_stat_reg;
-       int retry = 0xffff;
-
-       while (retry--) {
-               if ((mask & REG_READ(gen_fifo_stat_reg)) == mask)
-                       return 0;
-               udelay(100);
-       }
-       dev_err(dev->dev, "fifo is NOT empty 0x%08x\n",
-                                       REG_READ(gen_fifo_stat_reg));
-       return -EIO;
-}
-
-static int wait_for_all_fifos_empty(struct mdfld_dsi_pkg_sender *sender)
-{
-       return wait_for_gen_fifo_empty(sender, (1 << 2) | (1 << 10) | (1 << 18)
-               | (1 << 26) | (1 << 27) | (1 << 28));
-}
-
-static int wait_for_lp_fifos_empty(struct mdfld_dsi_pkg_sender *sender)
-{
-       return wait_for_gen_fifo_empty(sender, (1 << 10) | (1 << 26));
-}
-
-static int wait_for_hs_fifos_empty(struct mdfld_dsi_pkg_sender *sender)
-{
-       return wait_for_gen_fifo_empty(sender, (1 << 2) | (1 << 18));
-}
-
-static int wait_for_dbi_fifo_empty(struct mdfld_dsi_pkg_sender *sender)
-{
-       return wait_for_gen_fifo_empty(sender, (1 << 27));
-}
-
-static int handle_dsi_error(struct mdfld_dsi_pkg_sender *sender, u32 mask)
-{
-       u32 intr_stat_reg = sender->mipi_intr_stat_reg;
-       struct drm_device *dev = sender->dev;
-
-       switch (mask) {
-       case (1 << 0):
-       case (1 << 1):
-       case (1 << 2):
-       case (1 << 3):
-       case (1 << 4):
-       case (1 << 5):
-       case (1 << 6):
-       case (1 << 7):
-       case (1 << 8):
-       case (1 << 9):
-       case (1 << 10):
-       case (1 << 11):
-       case (1 << 12):
-       case (1 << 13):
-               break;
-       case (1 << 14):
-               /*wait for all fifo empty*/
-               /*wait_for_all_fifos_empty(sender)*/;
-               break;
-       case (1 << 15):
-               break;
-       case (1 << 16):
-               break;
-       case (1 << 17):
-               break;
-       case (1 << 18):
-       case (1 << 19):
-               /*wait for contention recovery time*/
-               /*mdelay(10);*/
-               /*wait for all fifo empty*/
-               if (0)
-                       wait_for_all_fifos_empty(sender);
-               break;
-       case (1 << 20):
-               break;
-       case (1 << 21):
-               /*wait for all fifo empty*/
-               /*wait_for_all_fifos_empty(sender);*/
-               break;
-       case (1 << 22):
-               break;
-       case (1 << 23):
-       case (1 << 24):
-       case (1 << 25):
-       case (1 << 26):
-       case (1 << 27):
-               /* HS Gen fifo full */
-               REG_WRITE(intr_stat_reg, mask);
-               wait_for_hs_fifos_empty(sender);
-               break;
-       case (1 << 28):
-               /* LP Gen fifo full\n */
-               REG_WRITE(intr_stat_reg, mask);
-               wait_for_lp_fifos_empty(sender);
-               break;
-       case (1 << 29):
-       case (1 << 30):
-       case (1 << 31):
-               break;
-       }
-
-       if (mask & REG_READ(intr_stat_reg))
-               dev_warn(dev->dev, "Cannot clean interrupt 0x%08x\n", mask);
-
-       return 0;
-}
-
-static int dsi_error_handler(struct mdfld_dsi_pkg_sender *sender)
-{
-       struct drm_device *dev = sender->dev;
-       u32 intr_stat_reg = sender->mipi_intr_stat_reg;
-       u32 mask;
-       u32 intr_stat;
-       int i;
-       int err = 0;
-
-       intr_stat = REG_READ(intr_stat_reg);
-
-       for (i = 0; i < 32; i++) {
-               mask = (0x00000001UL) << i;
-               if (intr_stat & mask) {
-                       dev_dbg(dev->dev, "[DSI]: %s\n", dsi_errors[i]);
-                       err = handle_dsi_error(sender, mask);
-                       if (err)
-                               dev_err(dev->dev, "Cannot handle error\n");
-               }
-       }
-       return err;
-}
-
-static inline int dbi_cmd_sent(struct mdfld_dsi_pkg_sender *sender)
-{
-       struct drm_device *dev = sender->dev;
-       u32 retry = 0xffff;
-       u32 dbi_cmd_addr_reg = sender->mipi_cmd_addr_reg;
-
-       /* Query the command execution status */
-       while (retry--) {
-               if (!(REG_READ(dbi_cmd_addr_reg) & (1 << 0)))
-                       break;
-       }
-
-       if (!retry) {
-               dev_err(dev->dev, "Timeout waiting for DBI Command status\n");
-               return -EAGAIN;
-       }
-       return 0;
-}
-
-/*
- * NOTE: this interface is abandoned expect for write_mem_start DCS
- * other DCS are sent via generic pkg interfaces
- */
-static int send_dcs_pkg(struct mdfld_dsi_pkg_sender *sender,
-                       struct mdfld_dsi_pkg *pkg)
-{
-       struct drm_device *dev = sender->dev;
-       struct mdfld_dsi_dcs_pkg *dcs_pkg = &pkg->pkg.dcs_pkg;
-       u32 dbi_cmd_len_reg = sender->mipi_cmd_len_reg;
-       u32 dbi_cmd_addr_reg = sender->mipi_cmd_addr_reg;
-       u32 cb_phy = sender->dbi_cb_phy;
-       u32 index = 0;
-       u8 *cb = (u8 *)sender->dbi_cb_addr;
-       int i;
-       int ret;
-
-       if (!sender->dbi_pkg_support) {
-               dev_err(dev->dev, "Trying to send DCS on a non DBI output, abort!\n");
-               return -ENOTSUPP;
-       }
-
-       /*wait for DBI fifo empty*/
-       wait_for_dbi_fifo_empty(sender);
-
-       *(cb + (index++)) = dcs_pkg->cmd;
-       if (dcs_pkg->param_num) {
-               for (i = 0; i < dcs_pkg->param_num; i++)
-                       *(cb + (index++)) = *(dcs_pkg->param + i);
-       }
-
-       REG_WRITE(dbi_cmd_len_reg, (1 + dcs_pkg->param_num));
-       REG_WRITE(dbi_cmd_addr_reg,
-               (cb_phy << CMD_MEM_ADDR_OFFSET)
-               | (1 << 0)
-               | ((dcs_pkg->data_src == CMD_DATA_SRC_PIPE) ? (1 << 1) : 0));
-
-       ret = dbi_cmd_sent(sender);
-       if (ret) {
-               dev_err(dev->dev, "command 0x%x not complete\n", dcs_pkg->cmd);
-               return -EAGAIN;
-       }
-       return 0;
-}
-
-static int __send_short_pkg(struct mdfld_dsi_pkg_sender *sender,
-                               struct mdfld_dsi_pkg *pkg)
-{
-       struct drm_device *dev = sender->dev;
-       u32 hs_gen_ctrl_reg = sender->mipi_hs_gen_ctrl_reg;
-       u32 lp_gen_ctrl_reg = sender->mipi_lp_gen_ctrl_reg;
-       u32 gen_ctrl_val = 0;
-       struct mdfld_dsi_gen_short_pkg *short_pkg = &pkg->pkg.short_pkg;
-
-       gen_ctrl_val |= short_pkg->cmd << MCS_COMMANDS_POS;
-       gen_ctrl_val |= 0 << DCS_CHANNEL_NUMBER_POS;
-       gen_ctrl_val |= pkg->pkg_type;
-       gen_ctrl_val |= short_pkg->param << MCS_PARAMETER_POS;
-
-       if (pkg->transmission_type == MDFLD_DSI_HS_TRANSMISSION) {
-               /* wait for hs fifo empty */
-               /* wait_for_hs_fifos_empty(sender); */
-               /* Send pkg */
-               REG_WRITE(hs_gen_ctrl_reg, gen_ctrl_val);
-       } else if (pkg->transmission_type == MDFLD_DSI_LP_TRANSMISSION) {
-               /* wait_for_lp_fifos_empty(sender); */
-               /* Send pkg*/
-               REG_WRITE(lp_gen_ctrl_reg, gen_ctrl_val);
-       } else {
-               dev_err(dev->dev, "Unknown transmission type %d\n",
-                                                       pkg->transmission_type);
-               return -EINVAL;
-       }
-
-       return 0;
-}
-
-static int __send_long_pkg(struct mdfld_dsi_pkg_sender *sender,
-                               struct mdfld_dsi_pkg *pkg)
-{
-       struct drm_device *dev = sender->dev;
-       u32 hs_gen_ctrl_reg = sender->mipi_hs_gen_ctrl_reg;
-       u32 hs_gen_data_reg = sender->mipi_hs_gen_data_reg;
-       u32 lp_gen_ctrl_reg = sender->mipi_lp_gen_ctrl_reg;
-       u32 lp_gen_data_reg = sender->mipi_lp_gen_data_reg;
-       u32 gen_ctrl_val = 0;
-       u32 *dp;
-       int i;
-       struct mdfld_dsi_gen_long_pkg *long_pkg = &pkg->pkg.long_pkg;
-
-       dp = long_pkg->data;
-
-       /*
-        * Set up word count for long pkg
-        * FIXME: double check word count field.
-        * currently, using the byte counts of the payload as the word count.
-        * ------------------------------------------------------------
-        * | DI |   WC   | ECC|         PAYLOAD              |CHECKSUM|
-        * ------------------------------------------------------------
-        */
-       gen_ctrl_val |= (long_pkg->len << 2) << WORD_COUNTS_POS;
-       gen_ctrl_val |= 0 << DCS_CHANNEL_NUMBER_POS;
-       gen_ctrl_val |= pkg->pkg_type;
-
-       if (pkg->transmission_type == MDFLD_DSI_HS_TRANSMISSION) {
-               /* Wait for hs ctrl and data fifos to be empty */
-               /* wait_for_hs_fifos_empty(sender); */
-               for (i = 0; i < long_pkg->len; i++)
-                       REG_WRITE(hs_gen_data_reg, *(dp + i));
-               REG_WRITE(hs_gen_ctrl_reg, gen_ctrl_val);
-       } else if (pkg->transmission_type == MDFLD_DSI_LP_TRANSMISSION) {
-               /* wait_for_lp_fifos_empty(sender); */
-               for (i = 0; i < long_pkg->len; i++)
-                       REG_WRITE(lp_gen_data_reg, *(dp + i));
-               REG_WRITE(lp_gen_ctrl_reg, gen_ctrl_val);
-       } else {
-               dev_err(dev->dev, "Unknown transmission type %d\n",
-                                               pkg->transmission_type);
-               return -EINVAL;
-       }
-
-       return 0;
-
-}
-
-static int send_mcs_short_pkg(struct mdfld_dsi_pkg_sender *sender,
-                               struct mdfld_dsi_pkg *pkg)
-{
-       return __send_short_pkg(sender, pkg);
-}
-
-static int send_mcs_long_pkg(struct mdfld_dsi_pkg_sender *sender,
-                               struct mdfld_dsi_pkg *pkg)
-{
-       return __send_long_pkg(sender, pkg);
-}
-
-static int send_gen_short_pkg(struct mdfld_dsi_pkg_sender *sender,
-                               struct mdfld_dsi_pkg *pkg)
-{
-       return __send_short_pkg(sender, pkg);
-}
-
-static int send_gen_long_pkg(struct mdfld_dsi_pkg_sender *sender,
-                               struct mdfld_dsi_pkg *pkg)
-{
-       return __send_long_pkg(sender, pkg);
-}
-
-static int send_pkg_prepare(struct mdfld_dsi_pkg_sender *sender,
-                               struct mdfld_dsi_pkg *pkg)
-{
-       u8 cmd;
-       u8 *data;
-
-       switch (pkg->pkg_type) {
-       case MDFLD_DSI_PKG_DCS:
-               cmd = pkg->pkg.dcs_pkg.cmd;
-               break;
-       case MDFLD_DSI_PKG_MCS_SHORT_WRITE_0:
-       case MDFLD_DSI_PKG_MCS_SHORT_WRITE_1:
-               cmd = pkg->pkg.short_pkg.cmd;
-               break;
-       case MDFLD_DSI_PKG_MCS_LONG_WRITE:
-               data = (u8 *)pkg->pkg.long_pkg.data;
-               cmd = *data;
-               break;
-       default:
-               return 0;
-       }
-
-       /* This prevents other package sending while doing msleep */
-       sender->status = MDFLD_DSI_PKG_SENDER_BUSY;
-
-       /* Check panel mode v.s. sending command */
-       if ((sender->panel_mode & MDFLD_DSI_PANEL_MODE_SLEEP) &&
-               cmd != exit_sleep_mode) {
-               dev_err(sender->dev->dev,
-                               "sending 0x%x when panel sleep in\n", cmd);
-               sender->status = MDFLD_DSI_PKG_SENDER_FREE;
-               return -EINVAL;
-       }
-
-       /* Wait for 120 milliseconds in case exit_sleep_mode just be sent */
-       if (cmd == DCS_ENTER_SLEEP_MODE) {
-               /*TODO: replace it with msleep later*/
-               mdelay(120);
-       }
-       return 0;
-}
-
-static int send_pkg_done(struct mdfld_dsi_pkg_sender *sender,
-                               struct mdfld_dsi_pkg *pkg)
-{
-       u8 cmd;
-       u8 *data;
-
-       switch (pkg->pkg_type) {
-       case MDFLD_DSI_PKG_DCS:
-               cmd = pkg->pkg.dcs_pkg.cmd;
-               break;
-       case MDFLD_DSI_PKG_MCS_SHORT_WRITE_0:
-       case MDFLD_DSI_PKG_MCS_SHORT_WRITE_1:
-               cmd = pkg->pkg.short_pkg.cmd;
-               break;
-       case MDFLD_DSI_PKG_MCS_LONG_WRITE:
-               data = (u8 *)pkg->pkg.long_pkg.data;
-               cmd = *data;
-               break;
-       default:
-               return 0;
-       }
-
-       /* Update panel status */
-       if (cmd == DCS_ENTER_SLEEP_MODE) {
-               sender->panel_mode |= MDFLD_DSI_PANEL_MODE_SLEEP;
-               /*TODO: replace it with msleep later*/
-               mdelay(120);
-       } else if (cmd == DCS_EXIT_SLEEP_MODE) {
-               sender->panel_mode &= ~MDFLD_DSI_PANEL_MODE_SLEEP;
-               /*TODO: replace it with msleep later*/
-               mdelay(120);
-       } else if (unlikely(cmd == DCS_SOFT_RESET)) {
-               /*TODO: replace it with msleep later*/
-               mdelay(5);
-       }
-       sender->status = MDFLD_DSI_PKG_SENDER_FREE;
-       return 0;
-
-}
-
-static int do_send_pkg(struct mdfld_dsi_pkg_sender *sender,
-                       struct mdfld_dsi_pkg *pkg)
-{
-       int ret;
-
-       if (sender->status == MDFLD_DSI_PKG_SENDER_BUSY) {
-               dev_err(sender->dev->dev, "sender is busy\n");
-               return -EAGAIN;
-       }
-
-       ret = send_pkg_prepare(sender, pkg);
-       if (ret) {
-               dev_err(sender->dev->dev, "send_pkg_prepare error\n");
-               return ret;
-       }
-
-       switch (pkg->pkg_type) {
-       case MDFLD_DSI_PKG_DCS:
-               ret = send_dcs_pkg(sender, pkg);
-               break;
-       case MDFLD_DSI_PKG_GEN_SHORT_WRITE_0:
-       case MDFLD_DSI_PKG_GEN_SHORT_WRITE_1:
-       case MDFLD_DSI_PKG_GEN_SHORT_WRITE_2:
-       case MDFLD_DSI_PKG_GEN_READ_0:
-       case MDFLD_DSI_PKG_GEN_READ_1:
-       case MDFLD_DSI_PKG_GEN_READ_2:
-               ret = send_gen_short_pkg(sender, pkg);
-               break;
-       case MDFLD_DSI_PKG_GEN_LONG_WRITE:
-               ret = send_gen_long_pkg(sender, pkg);
-               break;
-       case MDFLD_DSI_PKG_MCS_SHORT_WRITE_0:
-       case MDFLD_DSI_PKG_MCS_SHORT_WRITE_1:
-       case MDFLD_DSI_PKG_MCS_READ:
-               ret = send_mcs_short_pkg(sender, pkg);
-               break;
-       case MDFLD_DSI_PKG_MCS_LONG_WRITE:
-               ret = send_mcs_long_pkg(sender, pkg);
-               break;
-       default:
-               dev_err(sender->dev->dev, "Invalid pkg type 0x%x\n",
-                                                       pkg->pkg_type);
-               ret = -EINVAL;
-       }
-       send_pkg_done(sender, pkg);
-       return ret;
-}
-
-static int send_pkg(struct mdfld_dsi_pkg_sender *sender,
-                       struct mdfld_dsi_pkg *pkg)
-{
-       int err ;
-
-       /* Handle DSI error */
-       err = dsi_error_handler(sender);
-       if (err) {
-               dev_err(sender->dev->dev, "Error handling failed\n");
-               err = -EAGAIN;
-               goto send_pkg_err;
-       }
-
-       /* Send pkg */
-       err = do_send_pkg(sender, pkg);
-       if (err) {
-               dev_err(sender->dev->dev, "sent pkg failed\n");
-               err = -EAGAIN;
-               goto send_pkg_err;
-       }
-
-       /* FIXME: should I query complete and fifo empty here? */
-send_pkg_err:
-       return err;
-}
-
-static struct mdfld_dsi_pkg *pkg_sender_get_pkg_locked(
-                                       struct mdfld_dsi_pkg_sender *sender)
-{
-       struct mdfld_dsi_pkg *pkg;
-
-       if (list_empty(&sender->free_list)) {
-               dev_err(sender->dev->dev, "No free pkg left\n");
-               return NULL;
-       }
-       pkg = list_first_entry(&sender->free_list, struct mdfld_dsi_pkg, entry);
-       /* Detach from free list */
-       list_del_init(&pkg->entry);
-       return pkg;
-}
-
-static void pkg_sender_put_pkg_locked(struct mdfld_dsi_pkg_sender *sender,
-                                       struct mdfld_dsi_pkg *pkg)
-{
-       memset(pkg, 0, sizeof(struct mdfld_dsi_pkg));
-       INIT_LIST_HEAD(&pkg->entry);
-       list_add_tail(&pkg->entry, &sender->free_list);
-}
-
-static int mdfld_dbi_cb_init(struct mdfld_dsi_pkg_sender *sender,
-                                       struct psb_gtt *pg, int pipe)
-{
-       unsigned long phys;
-       void *virt_addr = NULL;
-
-       switch (pipe) {
-       case 0:
-               /* FIXME: Doesn't this collide with stolen space ? */
-               phys = pg->gtt_phys_start - 0x1000;
-               break;
-       case 2:
-               phys = pg->gtt_phys_start - 0x800;
-               break;
-       default:
-               dev_err(sender->dev->dev, "Unsupported channel %d\n", pipe);
-               return -EINVAL;
-       }
-
-       virt_addr = ioremap_nocache(phys, 0x800);
-       if (!virt_addr) {
-               dev_err(sender->dev->dev, "Map DBI command buffer error\n");
-               return -ENOMEM;
-       }
-       sender->dbi_cb_phy = phys;
-       sender->dbi_cb_addr = virt_addr;
-       return 0;
-}
-
-static void mdfld_dbi_cb_destroy(struct mdfld_dsi_pkg_sender *sender)
-{
-       if (sender && sender->dbi_cb_addr)
-               iounmap(sender->dbi_cb_addr);
-}
-
-static void pkg_sender_queue_pkg(struct mdfld_dsi_pkg_sender *sender,
-                                       struct mdfld_dsi_pkg *pkg,
-                                       int delay)
-{
-       unsigned long flags;
-
-       spin_lock_irqsave(&sender->lock, flags);
-
-       if (!delay) {
-               send_pkg(sender, pkg);
-               pkg_sender_put_pkg_locked(sender, pkg);
-       } else {
-               /* Queue it */
-               list_add_tail(&pkg->entry, &sender->pkg_list);
-       }
-       spin_unlock_irqrestore(&sender->lock, flags);
-}
-
-static void process_pkg_list(struct mdfld_dsi_pkg_sender *sender)
-{
-       struct mdfld_dsi_pkg *pkg;
-       unsigned long flags;
-
-       spin_lock_irqsave(&sender->lock, flags);
-
-       while (!list_empty(&sender->pkg_list)) {
-               pkg = list_first_entry(&sender->pkg_list,
-                                       struct mdfld_dsi_pkg, entry);
-               send_pkg(sender, pkg);
-               list_del_init(&pkg->entry);
-               pkg_sender_put_pkg_locked(sender, pkg);
-       }
-
-       spin_unlock_irqrestore(&sender->lock, flags);
-}
-
-static int mdfld_dsi_send_mcs_long(struct mdfld_dsi_pkg_sender *sender,
-       u32 *data, u32 len, u8 transmission, int delay)
-{
-       struct mdfld_dsi_pkg *pkg;
-       unsigned long flags;
-
-       spin_lock_irqsave(&sender->lock, flags);
-       pkg = pkg_sender_get_pkg_locked(sender);
-       spin_unlock_irqrestore(&sender->lock, flags);
-
-       if (!pkg) {
-               dev_err(sender->dev->dev, "No memory\n");
-               return -ENOMEM;
-       }
-       pkg->pkg_type = MDFLD_DSI_PKG_MCS_LONG_WRITE;
-       pkg->transmission_type = transmission;
-       pkg->pkg.long_pkg.data = data;
-       pkg->pkg.long_pkg.len = len;
-       INIT_LIST_HEAD(&pkg->entry);
-
-       pkg_sender_queue_pkg(sender, pkg, delay);
-       return 0;
-}
-
-static int mdfld_dsi_send_mcs_short(struct mdfld_dsi_pkg_sender *sender,
-                                       u8 cmd, u8 param, u8 param_num,
-                                       u8 transmission,
-                                       int delay)
-{
-       struct mdfld_dsi_pkg *pkg;
-       unsigned long flags;
-
-       spin_lock_irqsave(&sender->lock, flags);
-       pkg = pkg_sender_get_pkg_locked(sender);
-       spin_unlock_irqrestore(&sender->lock, flags);
-
-       if (!pkg) {
-               dev_err(sender->dev->dev, "No memory\n");
-               return -ENOMEM;
-       }
-
-       if (param_num) {
-               pkg->pkg_type = MDFLD_DSI_PKG_MCS_SHORT_WRITE_1;
-               pkg->pkg.short_pkg.param = param;
-       } else {
-               pkg->pkg_type = MDFLD_DSI_PKG_MCS_SHORT_WRITE_0;
-               pkg->pkg.short_pkg.param = 0;
-       }
-       pkg->transmission_type = transmission;
-       pkg->pkg.short_pkg.cmd = cmd;
-       INIT_LIST_HEAD(&pkg->entry);
-
-       pkg_sender_queue_pkg(sender, pkg, delay);
-       return 0;
-}
-
-static int mdfld_dsi_send_gen_short(struct mdfld_dsi_pkg_sender *sender,
-                                       u8 param0, u8 param1, u8 param_num,
-                                       u8 transmission,
-                                       int delay)
-{
-       struct mdfld_dsi_pkg *pkg;
-       unsigned long flags;
-
-       spin_lock_irqsave(&sender->lock, flags);
-       pkg = pkg_sender_get_pkg_locked(sender);
-       spin_unlock_irqrestore(&sender->lock, flags);
-
-       if (!pkg) {
-               dev_err(sender->dev->dev, "No pkg memory\n");
-               return -ENOMEM;
-       }
-
-       switch (param_num) {
-       case 0:
-               pkg->pkg_type = MDFLD_DSI_PKG_GEN_SHORT_WRITE_0;
-               pkg->pkg.short_pkg.cmd = 0;
-               pkg->pkg.short_pkg.param = 0;
-               break;
-       case 1:
-               pkg->pkg_type = MDFLD_DSI_PKG_GEN_SHORT_WRITE_1;
-               pkg->pkg.short_pkg.cmd = param0;
-               pkg->pkg.short_pkg.param = 0;
-               break;
-       case 2:
-               pkg->pkg_type = MDFLD_DSI_PKG_GEN_SHORT_WRITE_2;
-               pkg->pkg.short_pkg.cmd = param0;
-               pkg->pkg.short_pkg.param = param1;
-               break;
-       }
-
-       pkg->transmission_type = transmission;
-       INIT_LIST_HEAD(&pkg->entry);
-
-       pkg_sender_queue_pkg(sender, pkg, delay);
-       return 0;
-}
-
-static int mdfld_dsi_send_gen_long(struct mdfld_dsi_pkg_sender *sender,
-                               u32 *data, u32 len, u8 transmission, int delay)
-{
-       struct mdfld_dsi_pkg *pkg;
-       unsigned long flags;
-
-       spin_lock_irqsave(&sender->lock, flags);
-       pkg = pkg_sender_get_pkg_locked(sender);
-       spin_unlock_irqrestore(&sender->lock, flags);
-
-       if (!pkg) {
-               dev_err(sender->dev->dev, "No pkg memory\n");
-               return -ENOMEM;
-       }
-
-       pkg->pkg_type = MDFLD_DSI_PKG_GEN_LONG_WRITE;
-       pkg->transmission_type = transmission;
-       pkg->pkg.long_pkg.data = data;
-       pkg->pkg.long_pkg.len = len;
-
-       INIT_LIST_HEAD(&pkg->entry);
-
-       pkg_sender_queue_pkg(sender, pkg, delay);
-
-       return 0;
-}
-
-static int __read_panel_data(struct mdfld_dsi_pkg_sender *sender,
-                               struct mdfld_dsi_pkg *pkg,
-                               u32 *data,
-                               u16 len)
-{
-       unsigned long flags;
-       struct drm_device *dev = sender->dev;
-       int i;
-       u32 gen_data_reg;
-       int retry = MDFLD_DSI_READ_MAX_COUNT;
-       u8 transmission = pkg->transmission_type;
-
-       /*
-        * do reading.
-        * 0) send out generic read request
-        * 1) polling read data avail interrupt
-        * 2) read data
-        */
-       spin_lock_irqsave(&sender->lock, flags);
-
-       REG_WRITE(sender->mipi_intr_stat_reg, 1 << 29);
-
-       if ((REG_READ(sender->mipi_intr_stat_reg) & (1 << 29)))
-               DRM_ERROR("Can NOT clean read data valid interrupt\n");
-
-       /*send out read request*/
-       send_pkg(sender, pkg);
-
-       pkg_sender_put_pkg_locked(sender, pkg);
-
-       /*polling read data avail interrupt*/
-       while (retry && !(REG_READ(sender->mipi_intr_stat_reg) & (1 << 29))) {
-               udelay(100);
-               retry--;
-       }
-
-       if (!retry) {
-               spin_unlock_irqrestore(&sender->lock, flags);
-               return -ETIMEDOUT;
-       }
-
-       REG_WRITE(sender->mipi_intr_stat_reg, (1 << 29));
-
-       /*read data*/
-       if (transmission == MDFLD_DSI_HS_TRANSMISSION)
-               gen_data_reg = sender->mipi_hs_gen_data_reg;
-       else if (transmission == MDFLD_DSI_LP_TRANSMISSION)
-               gen_data_reg = sender->mipi_lp_gen_data_reg;
-       else {
-               DRM_ERROR("Unknown transmission");
-               spin_unlock_irqrestore(&sender->lock, flags);
-               return -EINVAL;
-       }
-
-       for (i=0; i<len; i++)
-               *(data + i) = REG_READ(gen_data_reg);
-
-       spin_unlock_irqrestore(&sender->lock, flags);
-       return 0;
-}
-
-static int mdfld_dsi_read_gen(struct mdfld_dsi_pkg_sender *sender,
-                               u8 param0,
-                               u8 param1,
-                               u8 param_num,
-                               u32 *data,
-                               u16 len,
-                               u8 transmission)
-{
-       struct mdfld_dsi_pkg *pkg;
-       unsigned long flags;
-
-       spin_lock_irqsave(&sender->lock, flags);
-
-       pkg = pkg_sender_get_pkg_locked(sender);
-
-       spin_unlock_irqrestore(&sender->lock,flags);
-
-       if (!pkg) {
-               dev_err(sender->dev->dev, "No pkg memory\n");
-               return -ENOMEM;
-       }
-
-       switch (param_num) {
-       case 0:
-               pkg->pkg_type = MDFLD_DSI_PKG_GEN_READ_0;
-               pkg->pkg.short_pkg.cmd = 0;
-               pkg->pkg.short_pkg.param = 0;
-               break;
-       case 1:
-               pkg->pkg_type = MDFLD_DSI_PKG_GEN_READ_1;
-               pkg->pkg.short_pkg.cmd = param0;
-               pkg->pkg.short_pkg.param = 0;
-               break;
-       case 2:
-               pkg->pkg_type = MDFLD_DSI_PKG_GEN_READ_2;
-               pkg->pkg.short_pkg.cmd = param0;
-               pkg->pkg.short_pkg.param = param1;
-               break;
-       }
-
-       pkg->transmission_type = transmission;
-
-       INIT_LIST_HEAD(&pkg->entry);
-
-       return __read_panel_data(sender, pkg, data, len);
-}
-static int mdfld_dsi_read_mcs(struct mdfld_dsi_pkg_sender *sender,
-                               u8 cmd,
-                               u32 *data,
-                               u16 len,
-                               u8 transmission)
-{
-       struct mdfld_dsi_pkg *pkg;
-       unsigned long flags;
-
-       spin_lock_irqsave(&sender->lock, flags);
-
-       pkg = pkg_sender_get_pkg_locked(sender);
-
-       spin_unlock_irqrestore(&sender->lock, flags);
-       if (!pkg) {
-               dev_err(sender->dev->dev, "No pkg memory\n");
-               return -ENOMEM;
-       }
-
-       pkg->pkg_type = MDFLD_DSI_PKG_MCS_READ;
-       pkg->pkg.short_pkg.cmd = cmd;
-       pkg->pkg.short_pkg.param = 0;
-
-       pkg->transmission_type = transmission;
-       INIT_LIST_HEAD(&pkg->entry);
-
-       return __read_panel_data(sender, pkg, data, len);
-}
-
-void dsi_controller_dbi_init(struct mdfld_dsi_config * dsi_config, int pipe)
-{
-       struct drm_device * dev = dsi_config->dev;
-       u32 reg_offset = pipe ? MIPIC_REG_OFFSET : 0;
-       int lane_count = dsi_config->lane_count;
-       u32 val = 0;
-
-       /*un-ready device*/
-       REG_WRITE((MIPIA_DEVICE_READY_REG + reg_offset), 0x00000000);
-
-       /*init dsi adapter before kicking off*/
-       REG_WRITE((MIPIA_CONTROL_REG + reg_offset), 0x00000018);
-
-       /*TODO: figure out how to setup these registers*/
-       REG_WRITE((MIPIA_DPHY_PARAM_REG + reg_offset), 0x150c3408);
-       REG_WRITE((MIPIA_CLK_LANE_SWITCH_TIME_CNT_REG + reg_offset), 0x000a0014);
-       REG_WRITE((MIPIA_DBI_BW_CTRL_REG + reg_offset), 0x00000400);
-       REG_WRITE((MIPIA_DBI_FIFO_THROTTLE_REG + reg_offset), 0x00000001);
-       REG_WRITE((MIPIA_HS_LS_DBI_ENABLE_REG + reg_offset), 0x00000000);
-
-       /*enable all interrupts*/
-       REG_WRITE((MIPIA_INTR_EN_REG + reg_offset), 0xffffffff);
-       /*max value: 20 clock cycles of txclkesc*/
-       REG_WRITE((MIPIA_TURN_AROUND_TIMEOUT_REG + reg_offset), 0x0000001f);
-       /*min 21 txclkesc, max: ffffh*/
-       REG_WRITE((MIPIA_DEVICE_RESET_TIMER_REG + reg_offset), 0x0000ffff);
-       /*min: 7d0 max: 4e20*/
-       REG_WRITE((MIPIA_INIT_COUNT_REG + reg_offset), 0x00000fa0);
-
-       /*set up max return packet size*/
-       REG_WRITE((MIPIA_MAX_RETURN_PACK_SIZE_REG + reg_offset),
-                       MDFLD_DSI_MAX_RETURN_PACKET_SIZE);
-
-       /*set up func_prg*/
-       val |= lane_count;
-       val |= (dsi_config->channel_num << DSI_DBI_VIRT_CHANNEL_OFFSET);
-       val |= DSI_DBI_COLOR_FORMAT_OPTION2;
-       REG_WRITE((MIPIA_DSI_FUNC_PRG_REG + reg_offset), val);
-
-       REG_WRITE((MIPIA_HS_TX_TIMEOUT_REG + reg_offset), 0x3fffff);
-       REG_WRITE((MIPIA_LP_RX_TIMEOUT_REG + reg_offset), 0xffff);
-
-       REG_WRITE((MIPIA_HIGH_LOW_SWITCH_COUNT_REG + reg_offset), 0x46);
-       REG_WRITE((MIPIA_EOT_DISABLE_REG + reg_offset), 0x00000000);
-       REG_WRITE((MIPIA_LP_BYTECLK_REG + reg_offset), 0x00000004);
-       REG_WRITE((MIPIA_DEVICE_READY_REG + reg_offset), 0x00000001);
-}
-
-void dsi_controller_dpi_init(struct mdfld_dsi_config * dsi_config, int pipe)
-{
-       struct drm_device * dev = dsi_config->dev;
-       u32 reg_offset = pipe ? MIPIC_REG_OFFSET : 0;
-       int lane_count = dsi_config->lane_count;
-       struct mdfld_dsi_dpi_timing dpi_timing;
-       struct drm_display_mode * mode = dsi_config->mode;
-       u32 val = 0;
-
-       /*un-ready device*/
-       REG_WRITE((MIPIA_DEVICE_READY_REG + reg_offset), 0x00000000);
-
-       /*init dsi adapter before kicking off*/
-       REG_WRITE((MIPIA_CONTROL_REG + reg_offset), 0x00000018);
-
-       /*enable all interrupts*/
-       REG_WRITE((MIPIA_INTR_EN_REG + reg_offset), 0xffffffff);
-
-       /*set up func_prg*/
-       val |= lane_count;
-       val |= dsi_config->channel_num << DSI_DPI_VIRT_CHANNEL_OFFSET;
-
-       switch(dsi_config->bpp) {
-       case 16:
-               val |= DSI_DPI_COLOR_FORMAT_RGB565;
-               break;
-       case 18:
-               val |= DSI_DPI_COLOR_FORMAT_RGB666;
-               break;
-       case 24:
-               val |= DSI_DPI_COLOR_FORMAT_RGB888;
-               break;
-       default:
-               DRM_ERROR("unsupported color format, bpp = %d\n", dsi_config->bpp);
-       }
-
-       REG_WRITE((MIPIA_DSI_FUNC_PRG_REG + reg_offset), val);
-
-       REG_WRITE((MIPIA_HS_TX_TIMEOUT_REG + reg_offset),
-                       (mode->vtotal * mode->htotal * dsi_config->bpp / (8 * lane_count)) & DSI_HS_TX_TIMEOUT_MASK);
-       REG_WRITE((MIPIA_LP_RX_TIMEOUT_REG + reg_offset), 0xffff & DSI_LP_RX_TIMEOUT_MASK);
-
-       /*max value: 20 clock cycles of txclkesc*/
-       REG_WRITE((MIPIA_TURN_AROUND_TIMEOUT_REG + reg_offset), 0x14 & DSI_TURN_AROUND_TIMEOUT_MASK);
-
-       /*min 21 txclkesc, max: ffffh*/
-       REG_WRITE((MIPIA_DEVICE_RESET_TIMER_REG + reg_offset), 0xffff & DSI_RESET_TIMER_MASK);
-
-       REG_WRITE((MIPIA_DPI_RESOLUTION_REG + reg_offset), mode->vdisplay << 16 | mode->hdisplay);
-
-       /*set DPI timing registers*/
-       mdfld_dsi_dpi_timing_calculation(mode, &dpi_timing, dsi_config->lane_count, dsi_config->bpp);
-
-       REG_WRITE((MIPIA_HSYNC_COUNT_REG + reg_offset), dpi_timing.hsync_count & DSI_DPI_TIMING_MASK);
-       REG_WRITE((MIPIA_HBP_COUNT_REG + reg_offset), dpi_timing.hbp_count & DSI_DPI_TIMING_MASK);
-       REG_WRITE((MIPIA_HFP_COUNT_REG + reg_offset), dpi_timing.hfp_count & DSI_DPI_TIMING_MASK);
-       REG_WRITE((MIPIA_HACTIVE_COUNT_REG + reg_offset), dpi_timing.hactive_count & DSI_DPI_TIMING_MASK);
-       REG_WRITE((MIPIA_VSYNC_COUNT_REG + reg_offset), dpi_timing.vsync_count & DSI_DPI_TIMING_MASK);
-       REG_WRITE((MIPIA_VBP_COUNT_REG + reg_offset), dpi_timing.vbp_count & DSI_DPI_TIMING_MASK);
-       REG_WRITE((MIPIA_VFP_COUNT_REG + reg_offset), dpi_timing.vfp_count & DSI_DPI_TIMING_MASK);
-
-       REG_WRITE((MIPIA_HIGH_LOW_SWITCH_COUNT_REG + reg_offset), 0x46);
-
-       /*min: 7d0 max: 4e20*/
-       REG_WRITE((MIPIA_INIT_COUNT_REG + reg_offset), 0x000007d0);
-
-       /*set up video mode*/
-       val = dsi_config->video_mode | DSI_DPI_COMPLETE_LAST_LINE;
-       REG_WRITE((MIPIA_VIDEO_MODE_FORMAT_REG + reg_offset), val);
-
-       REG_WRITE((MIPIA_EOT_DISABLE_REG + reg_offset), 0x00000000);
-
-       REG_WRITE((MIPIA_LP_BYTECLK_REG + reg_offset), 0x00000004);
-
-       /*TODO: figure out how to setup these registers*/
-       REG_WRITE((MIPIA_DPHY_PARAM_REG + reg_offset), 0x150c3408);
-
-       REG_WRITE((MIPIA_CLK_LANE_SWITCH_TIME_CNT_REG + reg_offset), (0xa << 16) | 0x14);
-
-       /*set device ready*/
-       REG_WRITE((MIPIA_DEVICE_READY_REG + reg_offset), 0x00000001);
-}
-
-static void dsi_controller_init(struct mdfld_dsi_config * dsi_config, int pipe)
-{
-       if (!dsi_config || ((pipe != 0) && (pipe != 2))) {
-               DRM_ERROR("Invalid parameters\n");
-               return;
-       }
-
-       if (dsi_config->type == MDFLD_DSI_ENCODER_DPI)
-               dsi_controller_dpi_init(dsi_config, pipe);
-       else if (dsi_config->type == MDFLD_DSI_ENCODER_DBI)
-               dsi_controller_dbi_init(dsi_config, pipe);
-       else
-               DRM_ERROR("Bad DSI encoder type\n");
-}
-
-void mdfld_dsi_cmds_kick_out(struct mdfld_dsi_pkg_sender *sender)
-{
-       process_pkg_list(sender);
-}
-
-int mdfld_dsi_send_dcs(struct mdfld_dsi_pkg_sender *sender,
-                       u8 dcs, u8 *param, u32 param_num, u8 data_src,
-                       int delay)
-{
-       struct mdfld_dsi_pkg *pkg;
-       u32 cb_phy = sender->dbi_cb_phy;
-       struct drm_device *dev = sender->dev;
-       u32 index = 0;
-       u8 *cb = (u8 *)sender->dbi_cb_addr;
-       unsigned long flags;
-       int retry;
-       u8 *dst = NULL;
-       u32 len;
-
-       if (!sender) {
-               WARN_ON(1);
-               return -EINVAL;
-       }
-
-       if (!sender->dbi_pkg_support) {
-               dev_err(dev->dev, "No DBI pkg sending on this sender\n");
-               return -ENOTSUPP;
-       }
-
-       if (param_num > MDFLD_MAX_DCS_PARAM) {
-               dev_err(dev->dev, "Sender only supports up to %d DCS params\n",
-                                                       MDFLD_MAX_DCS_PARAM);
-               return -EINVAL;
-       }
-
-       /*
-        * If dcs is write_mem_start, send it directly using DSI adapter
-        * interface
-        */
-       if (dcs == DCS_WRITE_MEM_START) {
-               if (!spin_trylock(&sender->lock))
-                       return -EAGAIN;
-
-               /*
-                * query whether DBI FIFO is empty,
-                * if not wait it becoming empty
-                */
-               retry = MDFLD_DSI_DBI_FIFO_TIMEOUT;
-               while (retry &&
-                   !(REG_READ(sender->mipi_gen_fifo_stat_reg) & (1 << 27))) {
-                       udelay(500);
-                       retry--;
-               }
-
-               /* If DBI FIFO timeout, drop this frame */
-               if (!retry) {
-                       spin_unlock(&sender->lock);
-                       return 0;
-               }
-
-               *(cb + (index++)) = write_mem_start;
-
-               REG_WRITE(sender->mipi_cmd_len_reg, 1);
-               REG_WRITE(sender->mipi_cmd_addr_reg,
-                                       cb_phy | (1 << 0) | (1 << 1));
-
-               retry = MDFLD_DSI_DBI_FIFO_TIMEOUT;
-               while (retry &&
-                       (REG_READ(sender->mipi_cmd_addr_reg) & (1 << 0))) {
-                       udelay(1);
-                       retry--;
-               }
-
-               spin_unlock(&sender->lock);
-               return 0;
-       }
-
-       /* Get a free pkg */
-       spin_lock_irqsave(&sender->lock, flags);
-       pkg = pkg_sender_get_pkg_locked(sender);
-       spin_unlock_irqrestore(&sender->lock, flags);
-
-       if (!pkg) {
-               dev_err(dev->dev, "No packages memory\n");
-               return -ENOMEM;
-       }
-
-       dst = pkg->pkg.dcs_pkg.param;
-       memcpy(dst, param, param_num);
-
-       pkg->pkg_type = MDFLD_DSI_PKG_DCS;
-       pkg->transmission_type = MDFLD_DSI_DCS;
-       pkg->pkg.dcs_pkg.cmd = dcs;
-       pkg->pkg.dcs_pkg.param_num = param_num;
-       pkg->pkg.dcs_pkg.data_src = data_src;
-
-       INIT_LIST_HEAD(&pkg->entry);
-
-       if (param_num == 0)
-               return mdfld_dsi_send_mcs_short_hs(sender, dcs, 0, 0, delay);
-       else if (param_num == 1)
-               return mdfld_dsi_send_mcs_short_hs(sender, dcs,
-                                                       param[0], 1, delay);
-       else if (param_num > 1) {
-               len = (param_num + 1) / 4;
-               if ((param_num + 1) % 4)
-                       len++;
-               return mdfld_dsi_send_mcs_long_hs(sender,
-                               (u32 *)&pkg->pkg.dcs_pkg, len, delay);
-       }
-       return 0;
-}
-
-int mdfld_dsi_send_mcs_short_hs(struct mdfld_dsi_pkg_sender *sender,
-                               u8 cmd, u8 param, u8 param_num, int delay)
-{
-       if (!sender) {
-               WARN_ON(1);
-               return -EINVAL;
-       }
-       return mdfld_dsi_send_mcs_short(sender, cmd, param, param_num,
-                                       MDFLD_DSI_HS_TRANSMISSION, delay);
-}
-
-int mdfld_dsi_send_mcs_short_lp(struct mdfld_dsi_pkg_sender *sender,
-                               u8 cmd, u8 param, u8 param_num, int delay)
-{
-       if (!sender) {
-               WARN_ON(1);
-               return -EINVAL;
-       }
-       return mdfld_dsi_send_mcs_short(sender, cmd, param, param_num,
-                                       MDFLD_DSI_LP_TRANSMISSION, delay);
-}
-
-int mdfld_dsi_send_mcs_long_hs(struct mdfld_dsi_pkg_sender *sender,
-                               u32 *data,
-                               u32 len,
-                               int delay)
-{
-       if (!sender || !data || !len) {
-               DRM_ERROR("Invalid parameters\n");
-               return -EINVAL;
-       }
-       return mdfld_dsi_send_mcs_long(sender, data, len,
-                                       MDFLD_DSI_HS_TRANSMISSION, delay);
-}
-
-int mdfld_dsi_send_mcs_long_lp(struct mdfld_dsi_pkg_sender *sender,
-                               u32 *data,
-                               u32 len,
-                               int delay)
-{
-       if (!sender || !data || !len) {
-               WARN_ON(1);
-               return -EINVAL;
-       }
-       return mdfld_dsi_send_mcs_long(sender, data, len,
-                               MDFLD_DSI_LP_TRANSMISSION, delay);
-}
-
-int mdfld_dsi_send_gen_short_hs(struct mdfld_dsi_pkg_sender *sender,
-                               u8 param0, u8 param1, u8 param_num, int delay)
-{
-       if (!sender) {
-               WARN_ON(1);
-               return -EINVAL;
-       }
-       return mdfld_dsi_send_gen_short(sender, param0, param1, param_num,
-                                       MDFLD_DSI_HS_TRANSMISSION, delay);
-}
-
-int mdfld_dsi_send_gen_short_lp(struct mdfld_dsi_pkg_sender *sender,
-                               u8 param0, u8 param1, u8 param_num, int delay)
-{
-       if (!sender || param_num < 0 || param_num > 2) {
-               WARN_ON(1);
-               return -EINVAL;
-       }
-       return mdfld_dsi_send_gen_short(sender, param0, param1, param_num,
-                                       MDFLD_DSI_LP_TRANSMISSION, delay);
-}
-
-int mdfld_dsi_send_gen_long_hs(struct mdfld_dsi_pkg_sender *sender,
-                               u32 *data,
-                               u32 len,
-                               int delay)
-{
-       if (!sender || !data || !len) {
-               WARN_ON(1);
-               return -EINVAL;
-       }
-       return mdfld_dsi_send_gen_long(sender, data, len,
-                                       MDFLD_DSI_HS_TRANSMISSION, delay);
-}
-
-int mdfld_dsi_send_gen_long_lp(struct mdfld_dsi_pkg_sender *sender,
-                               u32 *data,
-                               u32 len,
-                               int delay)
-{
-       if (!sender || !data || !len) {
-               WARN_ON(1);
-               return -EINVAL;
-       }
-       return mdfld_dsi_send_gen_long(sender, data, len,
-                                       MDFLD_DSI_LP_TRANSMISSION, delay);
-}
-
-int mdfld_dsi_read_gen_hs(struct mdfld_dsi_pkg_sender *sender,
-                       u8 param0,
-                       u8 param1,
-                       u8 param_num,
-                       u32 *data,
-                       u16 len)
-{
-       if (!sender || !data || param_num < 0 || param_num > 2
-               || !data || !len) {
-               DRM_ERROR("Invalid parameters\n");
-               return -EINVAL;
-       }
-
-       return mdfld_dsi_read_gen(sender, param0, param1, param_num,
-                               data, len, MDFLD_DSI_HS_TRANSMISSION);
-
-}
-
-int mdfld_dsi_read_gen_lp(struct mdfld_dsi_pkg_sender *sender,
-                       u8 param0,
-                       u8 param1,
-                       u8 param_num,
-                       u32 *data,
-                       u16 len)
-{
-       if (!sender || !data || param_num < 0 || param_num > 2
-               || !data || !len) {
-               DRM_ERROR("Invalid parameters\n");
-               return -EINVAL;
-       }
-
-       return mdfld_dsi_read_gen(sender, param0, param1, param_num,
-                               data, len, MDFLD_DSI_LP_TRANSMISSION);
-}
-
-int mdfld_dsi_read_mcs_hs(struct mdfld_dsi_pkg_sender *sender,
-                       u8 cmd,
-                       u32 *data,
-                       u16 len)
-{
-       if (!sender || !data || !len) {
-               DRM_ERROR("Invalid parameters\n");
-               return -EINVAL;
-       }
-
-       return mdfld_dsi_read_mcs(sender, cmd, data, len,
-                               MDFLD_DSI_HS_TRANSMISSION);
-}
-
-int mdfld_dsi_read_mcs_lp(struct mdfld_dsi_pkg_sender *sender,
-                       u8 cmd,
-                       u32 *data,
-                       u16 len)
-{
-       if (!sender || !data || !len) {
-               WARN_ON(1);
-               return -EINVAL;
-       }
-
-       return mdfld_dsi_read_mcs(sender, cmd, data, len,
-                               MDFLD_DSI_LP_TRANSMISSION);
-}
-int mdfld_dsi_pkg_sender_init(struct mdfld_dsi_connector *dsi_connector,
-                                                               int pipe)
-{
-       int ret;
-       struct mdfld_dsi_pkg_sender *pkg_sender;
-       struct mdfld_dsi_config *dsi_config =
-                                       mdfld_dsi_get_config(dsi_connector);
-       struct drm_device *dev = dsi_config->dev;
-       struct drm_psb_private *dev_priv = dev->dev_private;
-       struct psb_gtt *pg = &dev_priv->gtt;
-       int i;
-       struct mdfld_dsi_pkg *pkg, *tmp;
-       u32 mipi_val = 0;
-
-       if (!dsi_connector) {
-               WARN_ON(1);
-               return -EINVAL;
-       }
-
-       pkg_sender = dsi_connector->pkg_sender;
-
-       if (!pkg_sender || IS_ERR(pkg_sender)) {
-               pkg_sender = kzalloc(sizeof(struct mdfld_dsi_pkg_sender),
-                                                               GFP_KERNEL);
-               if (!pkg_sender) {
-                       dev_err(dev->dev, "Create DSI pkg sender failed\n");
-                       return -ENOMEM;
-               }
-
-               dsi_connector->pkg_sender = (void *)pkg_sender;
-       }
-
-       pkg_sender->dev = dev;
-       pkg_sender->dsi_connector = dsi_connector;
-       pkg_sender->pipe = pipe;
-       pkg_sender->pkg_num = 0;
-       pkg_sender->panel_mode = 0;
-       pkg_sender->status = MDFLD_DSI_PKG_SENDER_FREE;
-
-       /* Init dbi command buffer*/
-
-       if (dsi_config->type == MDFLD_DSI_ENCODER_DBI) {
-               pkg_sender->dbi_pkg_support = 1;
-               ret = mdfld_dbi_cb_init(pkg_sender, pg, pipe);
-               if (ret) {
-                       dev_err(dev->dev, "DBI command buffer map failed\n");
-                       goto mapping_err;
-               }
-       }
-
-       /* Init regs */
-       if (pipe == 0) {
-               pkg_sender->dpll_reg = MRST_DPLL_A;
-               pkg_sender->dspcntr_reg = DSPACNTR;
-               pkg_sender->pipeconf_reg = PIPEACONF;
-               pkg_sender->dsplinoff_reg = DSPALINOFF;
-               pkg_sender->dspsurf_reg = DSPASURF;
-               pkg_sender->pipestat_reg = PIPEASTAT;
-
-               pkg_sender->mipi_intr_stat_reg = MIPIA_INTR_STAT_REG;
-               pkg_sender->mipi_lp_gen_data_reg = MIPIA_LP_GEN_DATA_REG;
-               pkg_sender->mipi_hs_gen_data_reg = MIPIA_HS_GEN_DATA_REG;
-               pkg_sender->mipi_lp_gen_ctrl_reg = MIPIA_LP_GEN_CTRL_REG;
-               pkg_sender->mipi_hs_gen_ctrl_reg = MIPIA_HS_GEN_CTRL_REG;
-               pkg_sender->mipi_gen_fifo_stat_reg = MIPIA_GEN_FIFO_STAT_REG;
-               pkg_sender->mipi_data_addr_reg = MIPIA_DATA_ADD_REG;
-               pkg_sender->mipi_data_len_reg = MIPIA_DATA_LEN_REG;
-               pkg_sender->mipi_cmd_addr_reg = MIPIA_CMD_ADD_REG;
-               pkg_sender->mipi_cmd_len_reg = MIPIA_CMD_LEN_REG;
-       } else if (pipe == 2) {
-               pkg_sender->dpll_reg = MRST_DPLL_A;
-               pkg_sender->dspcntr_reg = DSPCCNTR;
-               pkg_sender->pipeconf_reg = PIPECCONF;
-               pkg_sender->dsplinoff_reg = DSPCLINOFF;
-               pkg_sender->dspsurf_reg = DSPCSURF;
-               pkg_sender->pipestat_reg = PIPECSTAT;
-
-               pkg_sender->mipi_intr_stat_reg =
-                               MIPIA_INTR_STAT_REG + MIPIC_REG_OFFSET;
-               pkg_sender->mipi_lp_gen_data_reg =
-                               MIPIA_LP_GEN_DATA_REG + MIPIC_REG_OFFSET;
-               pkg_sender->mipi_hs_gen_data_reg =
-                               MIPIA_HS_GEN_DATA_REG + MIPIC_REG_OFFSET;
-               pkg_sender->mipi_lp_gen_ctrl_reg =
-                               MIPIA_LP_GEN_CTRL_REG + MIPIC_REG_OFFSET;
-               pkg_sender->mipi_hs_gen_ctrl_reg =
-                               MIPIA_HS_GEN_CTRL_REG + MIPIC_REG_OFFSET;
-               pkg_sender->mipi_gen_fifo_stat_reg =
-                               MIPIA_GEN_FIFO_STAT_REG + MIPIC_REG_OFFSET;
-               pkg_sender->mipi_data_addr_reg =
-                               MIPIA_DATA_ADD_REG + MIPIC_REG_OFFSET;
-               pkg_sender->mipi_data_len_reg =
-                               MIPIA_DATA_LEN_REG + MIPIC_REG_OFFSET;
-               pkg_sender->mipi_cmd_addr_reg =
-                               MIPIA_CMD_ADD_REG + MIPIC_REG_OFFSET;
-               pkg_sender->mipi_cmd_len_reg =
-                               MIPIA_CMD_LEN_REG + MIPIC_REG_OFFSET;
-       }
-
-       /* Init pkg list */
-       INIT_LIST_HEAD(&pkg_sender->pkg_list);
-       INIT_LIST_HEAD(&pkg_sender->free_list);
-
-       spin_lock_init(&pkg_sender->lock);
-
-       /* Allocate free pkg pool */
-       for (i = 0; i < MDFLD_MAX_PKG_NUM; i++) {
-               pkg = kzalloc(sizeof(struct mdfld_dsi_pkg), GFP_KERNEL);
-               if (!pkg) {
-                       dev_err(dev->dev, "Out of memory allocating pkg pool");
-                       ret = -ENOMEM;
-                       goto pkg_alloc_err;
-               }
-               INIT_LIST_HEAD(&pkg->entry);
-               list_add_tail(&pkg->entry, &pkg_sender->free_list);
-       }
-
-       /*
-        * For video mode, don't enable DPI timing output here,
-        * will init the DPI timing output during mode setting.
-        */
-       if (dsi_config->type == MDFLD_DSI_ENCODER_DPI)
-               mipi_val = PASS_FROM_SPHY_TO_AFE | SEL_FLOPPED_HSTX;
-       else if (dsi_config->type == MDFLD_DSI_ENCODER_DBI)
-               mipi_val = PASS_FROM_SPHY_TO_AFE | SEL_FLOPPED_HSTX
-                       | TE_TRIGGER_GPIO_PIN;
-       else
-               DRM_ERROR("Bad DSI encoder type\n");
-
-       if (pipe == 0) {
-               mipi_val |= 0x2;
-               REG_WRITE(MIPI, mipi_val);
-               REG_READ(MIPI);
-       } else if (pipe == 2) {
-               REG_WRITE(MIPI_C, mipi_val);
-               REG_READ(MIPI_C);
-       }
-
-       /*do dsi controller init*/
-       dsi_controller_init(dsi_config, pipe);
-       
-       return 0;
-
-pkg_alloc_err:
-       list_for_each_entry_safe(pkg, tmp, &pkg_sender->free_list, entry) {
-               list_del(&pkg->entry);
-               kfree(pkg);
-       }
-
-       /* Free mapped command buffer */
-       mdfld_dbi_cb_destroy(pkg_sender);
-mapping_err:
-       kfree(pkg_sender);
-       dsi_connector->pkg_sender = NULL;
-       return ret;
-}
-
-void mdfld_dsi_pkg_sender_destroy(struct mdfld_dsi_pkg_sender *sender)
-{
-       struct mdfld_dsi_pkg *pkg, *tmp;
-
-       if (!sender || IS_ERR(sender))
-               return;
-
-       /* Free pkg pool */
-       list_for_each_entry_safe(pkg, tmp, &sender->free_list, entry) {
-               list_del(&pkg->entry);
-               kfree(pkg);
-       }
-       /* Free pkg list */
-       list_for_each_entry_safe(pkg, tmp, &sender->pkg_list, entry) {
-               list_del(&pkg->entry);
-               kfree(pkg);
-       }
-       mdfld_dbi_cb_destroy(sender);   /* free mapped command buffer */
-       kfree(sender);
-}
diff --git a/drivers/staging/gma500/mdfld_dsi_pkg_sender.h b/drivers/staging/gma500/mdfld_dsi_pkg_sender.h
deleted file mode 100644 (file)
index f24abc7..0000000
+++ /dev/null
@@ -1,184 +0,0 @@
-/*
- * Copyright Â© 2010 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Authors:
- * Jackie Li<yaodong.li@intel.com>
- */
-#ifndef __MDFLD_DSI_PKG_SENDER_H__
-#define __MDFLD_DSI_PKG_SENDER_H__
-
-#include <linux/kthread.h>
-
-#define MDFLD_MAX_DCS_PARAM    8
-#define MDFLD_MAX_PKG_NUM      2048
-
-enum {
-       MDFLD_DSI_PKG_DCS,
-       MDFLD_DSI_PKG_GEN_SHORT_WRITE_0 = 0x03,
-       MDFLD_DSI_PKG_GEN_SHORT_WRITE_1 = 0x13,
-       MDFLD_DSI_PKG_GEN_SHORT_WRITE_2 = 0x23,
-       MDFLD_DSI_PKG_GEN_READ_0 = 0x04,
-       MDFLD_DSI_PKG_GEN_READ_1 = 0x14,
-       MDFLD_DSI_PKG_GEN_READ_2 = 0x24,
-       MDFLD_DSI_PKG_GEN_LONG_WRITE = 0x29,
-       MDFLD_DSI_PKG_MCS_SHORT_WRITE_0 = 0x05,
-       MDFLD_DSI_PKG_MCS_SHORT_WRITE_1 = 0x15,
-       MDFLD_DSI_PKG_MCS_READ = 0x06,
-       MDFLD_DSI_PKG_MCS_LONG_WRITE = 0x39,
-};
-
-enum {
-       MDFLD_DSI_LP_TRANSMISSION,
-       MDFLD_DSI_HS_TRANSMISSION,
-       MDFLD_DSI_DCS,
-};
-
-enum {
-       MDFLD_DSI_PANEL_MODE_SLEEP = 0x1,
-};
-
-enum {
-       MDFLD_DSI_PKG_SENDER_FREE = 0x0,
-       MDFLD_DSI_PKG_SENDER_BUSY = 0x1,
-};
-
-enum {
-       MDFLD_DSI_SEND_PACKAGE,
-       MDFLD_DSI_QUEUE_PACKAGE,
-};
-
-struct mdfld_dsi_gen_short_pkg {
-       u8 cmd;
-       u8 param;
-};
-
-struct mdfld_dsi_gen_long_pkg {
-       u32 *data;
-       u32 len;
-};
-
-struct mdfld_dsi_dcs_pkg {
-       u8 cmd;
-       u8 param[MDFLD_MAX_DCS_PARAM];
-       u32 param_num;
-       u8 data_src;
-};
-
-struct mdfld_dsi_pkg {
-       u8 pkg_type;
-       u8 transmission_type;
-
-       union {
-               struct mdfld_dsi_gen_short_pkg short_pkg;
-               struct mdfld_dsi_gen_long_pkg long_pkg;
-               struct mdfld_dsi_dcs_pkg dcs_pkg;
-       } pkg;
-
-       struct list_head entry;
-};
-
-struct mdfld_dsi_pkg_sender {
-       struct drm_device *dev;
-       struct mdfld_dsi_connector *dsi_connector;
-       u32 status;
-
-       u32 panel_mode;
-
-       int pipe;
-
-       spinlock_t lock;
-       struct list_head pkg_list;
-       struct list_head free_list;
-
-       u32 pkg_num;
-
-       int dbi_pkg_support;
-
-       u32 dbi_cb_phy;
-       void *dbi_cb_addr;
-
-       /* Registers */
-       u32 dpll_reg;
-       u32 dspcntr_reg;
-       u32 pipeconf_reg;
-       u32 pipestat_reg;
-       u32 dsplinoff_reg;
-       u32 dspsurf_reg;
-
-       u32 mipi_intr_stat_reg;
-       u32 mipi_lp_gen_data_reg;
-       u32 mipi_hs_gen_data_reg;
-       u32 mipi_lp_gen_ctrl_reg;
-       u32 mipi_hs_gen_ctrl_reg;
-       u32 mipi_gen_fifo_stat_reg;
-       u32 mipi_data_addr_reg;
-       u32 mipi_data_len_reg;
-       u32 mipi_cmd_addr_reg;
-       u32 mipi_cmd_len_reg;
-};
-
-/* DCS definitions */
-#define DCS_SOFT_RESET                 0x01
-#define DCS_ENTER_SLEEP_MODE           0x10
-#define DCS_EXIT_SLEEP_MODE            0x11
-#define DCS_SET_DISPLAY_OFF            0x28
-#define DCS_SET_DISPLAY_ON             0x29
-#define DCS_SET_COLUMN_ADDRESS         0x2a
-#define DCS_SET_PAGE_ADDRESS           0x2b
-#define DCS_WRITE_MEM_START            0x2c
-#define DCS_SET_TEAR_OFF               0x34
-#define DCS_SET_TEAR_ON                0x35
-
-extern int mdfld_dsi_pkg_sender_init(struct mdfld_dsi_connector *dsi_connector,
-                       int pipe);
-extern void mdfld_dsi_pkg_sender_destroy(struct mdfld_dsi_pkg_sender *sender);
-extern int mdfld_dsi_send_dcs(struct mdfld_dsi_pkg_sender *sender, u8 dcs,
-                       u8 *param, u32 param_num, u8 data_src, int delay);
-extern int mdfld_dsi_send_mcs_short_hs(struct mdfld_dsi_pkg_sender *sender,
-                       u8 cmd, u8 param, u8 param_num, int delay);
-extern int mdfld_dsi_send_mcs_short_lp(struct mdfld_dsi_pkg_sender *sender,
-                       u8 cmd, u8 param, u8 param_num, int delay);
-extern int mdfld_dsi_send_mcs_long_hs(struct mdfld_dsi_pkg_sender *sender,
-                       u32 *data, u32 len, int delay);
-extern int mdfld_dsi_send_mcs_long_lp(struct mdfld_dsi_pkg_sender *sender,
-                       u32 *data, u32 len, int delay);
-extern int mdfld_dsi_send_gen_short_hs(struct mdfld_dsi_pkg_sender *sender,
-                       u8 param0, u8 param1, u8 param_num, int delay);
-extern int mdfld_dsi_send_gen_short_lp(struct mdfld_dsi_pkg_sender *sender,
-                       u8 param0, u8 param1, u8 param_num, int delay);
-extern int mdfld_dsi_send_gen_long_hs(struct mdfld_dsi_pkg_sender *sender,
-                       u32 *data, u32 len, int delay);
-extern int mdfld_dsi_send_gen_long_lp(struct mdfld_dsi_pkg_sender *sender,
-                       u32 *data, u32 len, int delay);
-
-extern int mdfld_dsi_read_gen_hs(struct mdfld_dsi_pkg_sender *sender,
-                       u8 param0, u8 param1, u8 param_num, u32 *data, u16 len);
-extern int mdfld_dsi_read_gen_lp(struct mdfld_dsi_pkg_sender *sender,
-                       u8 param0, u8 param1, u8 param_num, u32 *data, u16 len);
-extern int mdfld_dsi_read_mcs_hs(struct mdfld_dsi_pkg_sender *sender,
-                       u8 cmd, u32 *data, u16 len);
-extern int mdfld_dsi_read_mcs_lp(struct mdfld_dsi_pkg_sender *sender,
-                       u8 cmd, u32 *data, u16 len);
-
-extern void mdfld_dsi_cmds_kick_out(struct mdfld_dsi_pkg_sender *sender);
-
-#endif /* __MDFLD_DSI_PKG_SENDER_H__ */
diff --git a/drivers/staging/gma500/mdfld_intel_display.c b/drivers/staging/gma500/mdfld_intel_display.c
deleted file mode 100644 (file)
index 0b37b7b..0000000
+++ /dev/null
@@ -1,1404 +0,0 @@
-/*
- * Copyright Â© 2006-2011 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Authors:
- *     Eric Anholt <eric@anholt.net>
- */
-
-#include "framebuffer.h"
-#include "psb_intel_display.h"
-#include "mdfld_dsi_dbi.h"
-#include "mdfld_dsi_dpi.h"
-#include "mdfld_dsi_dbi_dpu.h"
-
-#include <linux/pm_runtime.h>
-
-#ifdef MIN
-#undef MIN
-#endif
-
-#define MIN(x, y) (((x) < (y)) ? (x) : (y))
-
-/* Hardcoded currently */
-static int ksel = KSEL_CRYSTAL_19;
-
-extern void mdfld_save_display(struct drm_device *dev);
-extern bool gbgfxsuspended;
-
-struct psb_intel_range_t {
-       int min, max;
-};
-
-struct mdfld_limit_t {
-       struct psb_intel_range_t dot, m, p1;
-};
-
-struct mdfld_intel_clock_t {
-       /* given values */
-       int n;
-       int m1, m2;
-       int p1, p2;
-       /* derived values */
-       int dot;
-       int vco;
-       int m;
-       int p;
-};
-
-
-
-#define COUNT_MAX 0x10000000
-
-void mdfldWaitForPipeDisable(struct drm_device *dev, int pipe)
-{
-       int count, temp;
-       u32 pipeconf_reg = PIPEACONF;
-       
-       switch (pipe) {
-       case 0:
-               break;
-       case 1:
-               pipeconf_reg = PIPEBCONF;
-               break;
-       case 2:
-               pipeconf_reg = PIPECCONF;
-               break;
-       default:
-               DRM_ERROR("Illegal Pipe Number. \n");
-               return;
-       }
-
-       /* FIXME JLIU7_PO */
-       psb_intel_wait_for_vblank(dev);
-       return;
-
-       /* Wait for for the pipe disable to take effect. */
-       for (count = 0; count < COUNT_MAX; count++) {
-               temp = REG_READ(pipeconf_reg);
-               if ((temp & PIPEACONF_PIPE_STATE) == 0)
-                       break;
-       }
-}
-
-void mdfldWaitForPipeEnable(struct drm_device *dev, int pipe)
-{
-       int count, temp;
-       u32 pipeconf_reg = PIPEACONF;
-       
-       switch (pipe) {
-       case 0:
-               break;
-       case 1:
-               pipeconf_reg = PIPEBCONF;
-               break;
-       case 2:
-               pipeconf_reg = PIPECCONF;
-               break;
-       default:
-               dev_err(dev->dev, "Illegal Pipe Number.\n");
-               return;
-       }
-
-       /* FIXME JLIU7_PO */
-       psb_intel_wait_for_vblank(dev);
-       return;
-
-       /* Wait for for the pipe enable to take effect. */
-       for (count = 0; count < COUNT_MAX; count++) {
-               temp = REG_READ(pipeconf_reg);
-               if ((temp & PIPEACONF_PIPE_STATE) == 1)
-                       break;
-       }
-}
-
-
-static int mdfld_intel_crtc_cursor_set(struct drm_crtc *crtc,
-                                struct drm_file *file_priv,
-                                uint32_t handle,
-                                uint32_t width, uint32_t height)
-{
-       struct drm_device *dev = crtc->dev;
-       struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
-       int pipe = psb_intel_crtc->pipe;
-       uint32_t control = CURACNTR;
-       uint32_t base = CURABASE;
-       uint32_t temp;
-       size_t addr = 0;
-       struct gtt_range *gt;
-       struct drm_gem_object *obj;
-       int ret;
-
-       switch (pipe) {
-       case 0:
-               break;
-       case 1:
-               control = CURBCNTR;
-               base = CURBBASE;
-               break;
-       case 2:
-               control = CURCCNTR;
-               base = CURCBASE;
-               break;
-       default:
-               dev_err(dev->dev, "Illegal Pipe Number. \n");
-               return -EINVAL;
-       }
-       
-#if 1 /* FIXME_JLIU7 can't enalbe cursorB/C HW issue. need to remove after HW fix */
-       if (pipe != 0)
-               return 0;
-#endif 
-       /* if we want to turn of the cursor ignore width and height */
-       if (!handle) {
-               dev_dbg(dev->dev, "cursor off\n");
-               /* turn off the cursor */
-               temp = 0;
-               temp |= CURSOR_MODE_DISABLE;
-
-               if (gma_power_begin(dev, true)) {
-                       REG_WRITE(control, temp);
-                       REG_WRITE(base, 0);
-                       gma_power_end(dev);
-               }
-               /* Unpin the old GEM object */
-               if (psb_intel_crtc->cursor_obj) {
-                       gt = container_of(psb_intel_crtc->cursor_obj,
-                                                       struct gtt_range, gem);
-                       psb_gtt_unpin(gt);
-                       drm_gem_object_unreference(psb_intel_crtc->cursor_obj);
-                       psb_intel_crtc->cursor_obj = NULL;
-               }
-               return 0;
-       }
-
-       /* Currently we only support 64x64 cursors */
-       if (width != 64 || height != 64) {
-               DRM_ERROR("we currently only support 64x64 cursors\n");
-               return -EINVAL;
-       }
-
-       obj = drm_gem_object_lookup(dev, file_priv, handle);
-       if (!obj)
-               return -ENOENT;
-
-       if (obj->size < width * height * 4) {
-               dev_dbg(dev->dev, "buffer is to small\n");
-               return -ENOMEM;
-       }
-
-       gt = container_of(obj, struct gtt_range, gem);
-
-       /* Pin the memory into the GTT */
-       ret = psb_gtt_pin(gt);
-       if (ret) {
-               dev_err(dev->dev, "Can not pin down handle 0x%x\n", handle);
-               return ret;
-       }
-
-
-       addr = gt->offset;      /* Or resource.start ??? */
-
-       psb_intel_crtc->cursor_addr = addr;
-
-       temp = 0;
-       /* set the pipe for the cursor */
-       temp |= (pipe << 28);
-       temp |= CURSOR_MODE_64_ARGB_AX | MCURSOR_GAMMA_ENABLE;
-
-       if (gma_power_begin(dev, true)) {
-               REG_WRITE(control, temp);
-               REG_WRITE(base, addr);
-               gma_power_end(dev);
-       }
-       /* unpin the old GEM object */
-       if (psb_intel_crtc->cursor_obj) {
-               gt = container_of(psb_intel_crtc->cursor_obj,
-                                                       struct gtt_range, gem);
-               psb_gtt_unpin(gt);
-               drm_gem_object_unreference(psb_intel_crtc->cursor_obj);
-               psb_intel_crtc->cursor_obj = obj;
-       }
-       return 0;
-}
-
-static int mdfld_intel_crtc_cursor_move(struct drm_crtc *crtc, int x, int y)
-{
-       struct drm_device *dev = crtc->dev;
-       struct drm_psb_private * dev_priv = (struct drm_psb_private *)dev->dev_private;
-       struct mdfld_dbi_dpu_info *dpu_info = dev_priv->dbi_dpu_info;
-       struct psb_drm_dpu_rect rect;
-       struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
-       int pipe = psb_intel_crtc->pipe;
-       uint32_t pos = CURAPOS;
-       uint32_t base = CURABASE;
-       uint32_t temp = 0;
-       uint32_t addr;
-
-       switch (pipe) {
-       case 0:
-               if (dpu_info) {
-                       rect.x = x;
-                       rect.y = y;
-               
-                       mdfld_dbi_dpu_report_damage(dev, MDFLD_CURSORA, &rect);
-                       mdfld_dpu_exit_dsr(dev);
-               } else if (!(dev_priv->dsr_fb_update & MDFLD_DSR_CURSOR_0))
-                       mdfld_dsi_dbi_exit_dsr(dev, MDFLD_DSR_CURSOR_0);
-               break;
-       case 1:
-               pos = CURBPOS;
-               base = CURBBASE;
-               break;
-       case 2:
-               if (dpu_info) {
-                       mdfld_dbi_dpu_report_damage(dev, MDFLD_CURSORC, &rect);
-                       mdfld_dpu_exit_dsr(dev);
-               } else if (!(dev_priv->dsr_fb_update & MDFLD_DSR_CURSOR_2))
-                       mdfld_dsi_dbi_exit_dsr(dev, MDFLD_DSR_CURSOR_2);
-               pos = CURCPOS;
-               base = CURCBASE;
-               break;
-       default:
-               DRM_ERROR("Illegal Pipe Number. \n");
-               return -EINVAL;
-       }
-               
-#if 1 /* FIXME_JLIU7 can't enable cursorB/C HW issue. need to remove after HW fix */
-       if (pipe != 0)
-               return 0;
-#endif 
-       if (x < 0) {
-               temp |= (CURSOR_POS_SIGN << CURSOR_X_SHIFT);
-               x = -x;
-       }
-       if (y < 0) {
-               temp |= (CURSOR_POS_SIGN << CURSOR_Y_SHIFT);
-               y = -y;
-       }
-
-       temp |= ((x & CURSOR_POS_MASK) << CURSOR_X_SHIFT);
-       temp |= ((y & CURSOR_POS_MASK) << CURSOR_Y_SHIFT);
-
-       addr = psb_intel_crtc->cursor_addr;
-
-       if (gma_power_begin(dev, true)) {
-               REG_WRITE(pos, temp);
-               REG_WRITE(base, addr);
-               gma_power_end(dev);
-       }
-
-       return 0;
-}
-
-const struct drm_crtc_funcs mdfld_intel_crtc_funcs = {
-       .cursor_set = mdfld_intel_crtc_cursor_set,
-       .cursor_move = mdfld_intel_crtc_cursor_move,
-       .gamma_set = psb_intel_crtc_gamma_set,
-       .set_config = drm_crtc_helper_set_config,
-       .destroy = psb_intel_crtc_destroy,
-};
-
-static struct drm_device globle_dev;
-
-void mdfld__intel_plane_set_alpha(int enable)
-{
-       struct drm_device *dev = &globle_dev;
-       int dspcntr_reg = DSPACNTR;
-       u32 dspcntr;
-
-       dspcntr = REG_READ(dspcntr_reg);
-
-       if (enable) {
-               dspcntr &= ~DISPPLANE_32BPP_NO_ALPHA;
-               dspcntr |= DISPPLANE_32BPP;
-       } else {
-               dspcntr &= ~DISPPLANE_32BPP;
-               dspcntr |= DISPPLANE_32BPP_NO_ALPHA;
-       }
-
-       REG_WRITE(dspcntr_reg, dspcntr);
-}
-
-int mdfld__intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, struct drm_framebuffer *old_fb)
-{
-       struct drm_device *dev = crtc->dev;
-       /* struct drm_i915_master_private *master_priv; */
-       struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
-       struct psb_framebuffer *psbfb = to_psb_fb(crtc->fb);
-       int pipe = psb_intel_crtc->pipe;
-       unsigned long start, offset;
-       int dsplinoff = DSPALINOFF;
-       int dspsurf = DSPASURF;
-       int dspstride = DSPASTRIDE;
-       int dspcntr_reg = DSPACNTR;
-       u32 dspcntr;
-       int ret = 0;
-
-       memcpy(&globle_dev, dev, sizeof(struct drm_device));
-
-       if (!gma_power_begin(dev, true))
-               return 0;
-
-       /* no fb bound */
-       if (!crtc->fb) {
-               dev_err(dev->dev, "No FB bound\n");
-               goto psb_intel_pipe_cleaner;
-       }
-
-       switch (pipe) {
-       case 0:
-               dsplinoff = DSPALINOFF;
-               break;
-       case 1:
-               dsplinoff = DSPBLINOFF;
-               dspsurf = DSPBSURF;
-               dspstride = DSPBSTRIDE;
-               dspcntr_reg = DSPBCNTR;
-               break;
-       case 2:
-               dsplinoff = DSPCLINOFF;
-               dspsurf = DSPCSURF;
-               dspstride = DSPCSTRIDE;
-               dspcntr_reg = DSPCCNTR;
-               break;
-       default:
-               dev_err(dev->dev, "Illegal Pipe Number.\n");
-               return -EINVAL;
-       }
-
-       ret = psb_gtt_pin(psbfb->gtt);
-       if (ret < 0)
-               goto psb_intel_pipe_set_base_exit;
-
-       start = psbfb->gtt->offset;
-       offset = y * crtc->fb->pitches[0] + x * (crtc->fb->bits_per_pixel / 8);
-
-       REG_WRITE(dspstride, crtc->fb->pitches[0]);
-       dspcntr = REG_READ(dspcntr_reg);
-       dspcntr &= ~DISPPLANE_PIXFORMAT_MASK;
-
-       switch (crtc->fb->bits_per_pixel) {
-       case 8:
-               dspcntr |= DISPPLANE_8BPP;
-               break;
-       case 16:
-               if (crtc->fb->depth == 15)
-                       dspcntr |= DISPPLANE_15_16BPP;
-               else
-                       dspcntr |= DISPPLANE_16BPP;
-               break;
-       case 24:
-       case 32:
-               dspcntr |= DISPPLANE_32BPP_NO_ALPHA;
-               break;
-       default:
-               dev_err(dev->dev, "Unknown color depth\n");
-               ret = -EINVAL;
-               goto psb_intel_pipe_set_base_exit;
-       }
-       REG_WRITE(dspcntr_reg, dspcntr);
-
-       dev_dbg(dev->dev, "Writing base %08lX %08lX %d %d\n",
-                                               start, offset, x, y);
-
-       REG_WRITE(dsplinoff, offset);
-       REG_READ(dsplinoff);
-       REG_WRITE(dspsurf, start);
-       REG_READ(dspsurf);
-
-psb_intel_pipe_cleaner:
-       /* If there was a previous display we can now unpin it */
-       if (old_fb)
-               psb_gtt_unpin(to_psb_fb(old_fb)->gtt);
-
-psb_intel_pipe_set_base_exit:
-       gma_power_end(dev);
-       return ret;
-}
-
-/**
- * Disable the pipe, plane and pll.
- *
- */
-void mdfld_disable_crtc (struct drm_device *dev, int pipe)
-{
-       int dpll_reg = MRST_DPLL_A;
-       int dspcntr_reg = DSPACNTR;
-       int dspbase_reg = MRST_DSPABASE;
-       int pipeconf_reg = PIPEACONF;
-       u32 gen_fifo_stat_reg = GEN_FIFO_STAT_REG;
-       u32 temp;
-
-       switch (pipe) {
-       case 0:
-               break;
-       case 1:
-               dpll_reg = MDFLD_DPLL_B;
-               dspcntr_reg = DSPBCNTR;
-               dspbase_reg = DSPBSURF;
-               pipeconf_reg = PIPEBCONF;
-               break;
-       case 2:
-               dpll_reg = MRST_DPLL_A;
-               dspcntr_reg = DSPCCNTR;
-               dspbase_reg = MDFLD_DSPCBASE;
-               pipeconf_reg = PIPECCONF;
-               gen_fifo_stat_reg = GEN_FIFO_STAT_REG + MIPIC_REG_OFFSET;
-               break;
-       default:
-               dev_err(dev->dev, "Illegal Pipe Number. \n");
-               return;
-       }
-
-       if (pipe != 1)
-               mdfld_dsi_gen_fifo_ready (dev, gen_fifo_stat_reg, HS_CTRL_FIFO_EMPTY | HS_DATA_FIFO_EMPTY);
-
-       /* Disable display plane */
-       temp = REG_READ(dspcntr_reg);
-       if ((temp & DISPLAY_PLANE_ENABLE) != 0) {
-               REG_WRITE(dspcntr_reg,
-                         temp & ~DISPLAY_PLANE_ENABLE);
-               /* Flush the plane changes */
-               REG_WRITE(dspbase_reg, REG_READ(dspbase_reg));
-               REG_READ(dspbase_reg);
-       }
-
-       /* FIXME_JLIU7 MDFLD_PO revisit */
-       /* Wait for vblank for the disable to take effect */
-/* MDFLD_PO_JLIU7              psb_intel_wait_for_vblank(dev); */
-
-       /* Next, disable display pipes */
-       temp = REG_READ(pipeconf_reg);
-       if ((temp & PIPEACONF_ENABLE) != 0) {
-               temp &= ~PIPEACONF_ENABLE;
-               temp |= PIPECONF_PLANE_OFF | PIPECONF_CURSOR_OFF;
-               REG_WRITE(pipeconf_reg, temp);
-               REG_READ(pipeconf_reg);
-
-               /* Wait for for the pipe disable to take effect. */
-               mdfldWaitForPipeDisable(dev, pipe);
-       }
-
-       temp = REG_READ(dpll_reg);
-       if (temp & DPLL_VCO_ENABLE) {
-               if (((pipe != 1) && !((REG_READ(PIPEACONF) | REG_READ(PIPECCONF)) & PIPEACONF_ENABLE))
-                               || (pipe == 1)){
-                       temp &= ~(DPLL_VCO_ENABLE);
-                       REG_WRITE(dpll_reg, temp);
-                       REG_READ(dpll_reg);
-                       /* Wait for the clocks to turn off. */
-                       /* FIXME_MDFLD PO may need more delay */
-                       udelay(500);
-
-                       if (!(temp & MDFLD_PWR_GATE_EN)) {
-                               /* gating power of DPLL */
-                               REG_WRITE(dpll_reg, temp | MDFLD_PWR_GATE_EN);
-                               /* FIXME_MDFLD PO - change 500 to 1 after PO */
-                               udelay(5000);
-                       }
-               }
-       }
-
-}
-
-/**
- * Sets the power management mode of the pipe and plane.
- *
- * This code should probably grow support for turning the cursor off and back
- * on appropriately at the same time as we're turning the pipe off/on.
- */
-static void mdfld_crtc_dpms(struct drm_crtc *crtc, int mode)
-{
-       struct drm_device *dev = crtc->dev;
-       struct drm_psb_private *dev_priv = dev->dev_private;
-       struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
-       int pipe = psb_intel_crtc->pipe;
-       int dpll_reg = MRST_DPLL_A;
-       int dspcntr_reg = DSPACNTR;
-       int dspbase_reg = MRST_DSPABASE;
-       int pipeconf_reg = PIPEACONF;
-       u32 pipestat_reg = PIPEASTAT;
-       u32 gen_fifo_stat_reg = GEN_FIFO_STAT_REG;
-       u32 pipeconf = dev_priv->pipeconf;
-       u32 dspcntr = dev_priv->dspcntr;
-       u32 mipi_enable_reg = MIPIA_DEVICE_READY_REG;
-       u32 temp;
-       bool enabled;
-       int timeout = 0;
-
-       if (!gma_power_begin(dev, true))
-               return;
-
-        /* Ignore if system is already in DSR and in suspended state. */
-       if(/*gbgfxsuspended */0 && dev_priv->dispstatus == false && mode == 3){
-           if(dev_priv->rpm_enabled && pipe == 1){
-       //          dev_priv->is_mipi_on = false;
-                 pm_request_idle(&dev->pdev->dev);
-           }
-           return;
-       }else if(mode == 0) {
-               //do not need to set gbdispstatus=true in crtc.
-               //this will be set in encoder such as mdfld_dsi_dbi_dpms
-           //gbdispstatus = true;
-       }
-
-/* FIXME_JLIU7 MDFLD_PO replaced w/ the following function */
-/* mdfld_dbi_dpms (struct drm_device *dev, int pipe, bool enabled) */
-
-       switch (pipe) {
-       case 0:
-               break;
-       case 1:
-               dpll_reg = DPLL_B;
-               dspcntr_reg = DSPBCNTR;
-               dspbase_reg = MRST_DSPBBASE;
-               pipeconf_reg = PIPEBCONF;
-               pipeconf = dev_priv->pipeconf1;
-               dspcntr = dev_priv->dspcntr1;
-               dpll_reg = MDFLD_DPLL_B;
-               break;
-       case 2:
-               dpll_reg = MRST_DPLL_A;
-               dspcntr_reg = DSPCCNTR;
-               dspbase_reg = MDFLD_DSPCBASE;
-               pipeconf_reg = PIPECCONF;
-               pipestat_reg = PIPECSTAT;
-               pipeconf = dev_priv->pipeconf2;
-               dspcntr = dev_priv->dspcntr2;
-               gen_fifo_stat_reg = GEN_FIFO_STAT_REG + MIPIC_REG_OFFSET;
-               mipi_enable_reg = MIPIA_DEVICE_READY_REG + MIPIC_REG_OFFSET;
-               break;
-       default:
-               dev_err(dev->dev, "Illegal Pipe Number.\n");
-               return;
-       }
-
-       /* XXX: When our outputs are all unaware of DPMS modes other than off
-        * and on, we should map those modes to DRM_MODE_DPMS_OFF in the CRTC.
-        */
-       switch (mode) {
-       case DRM_MODE_DPMS_ON:
-       case DRM_MODE_DPMS_STANDBY:
-       case DRM_MODE_DPMS_SUSPEND:
-               /* Enable the DPLL */
-               temp = REG_READ(dpll_reg);
-
-               if ((temp & DPLL_VCO_ENABLE) == 0) {
-                       /* When ungating power of DPLL, needs to wait 0.5us before enable the VCO */
-                       if (temp & MDFLD_PWR_GATE_EN) {
-                               temp &= ~MDFLD_PWR_GATE_EN;
-                               REG_WRITE(dpll_reg, temp);
-                               /* FIXME_MDFLD PO - change 500 to 1 after PO */
-                               udelay(500);
-                       }
-
-                       REG_WRITE(dpll_reg, temp);
-                       REG_READ(dpll_reg);
-                       /* FIXME_MDFLD PO - change 500 to 1 after PO */
-                       udelay(500);
-                       
-                       REG_WRITE(dpll_reg, temp | DPLL_VCO_ENABLE);
-                       REG_READ(dpll_reg);
-
-                       /**
-                        * wait for DSI PLL to lock
-                        * NOTE: only need to poll status of pipe 0 and pipe 1,
-                        * since both MIPI pipes share the same PLL.
-                        */
-                       while ((pipe != 2) && (timeout < 20000) && !(REG_READ(pipeconf_reg) & PIPECONF_DSIPLL_LOCK)) {
-                               udelay(150);
-                               timeout ++;
-                       }
-               }
-
-               /* Enable the plane */
-               temp = REG_READ(dspcntr_reg);
-               if ((temp & DISPLAY_PLANE_ENABLE) == 0) {
-                       REG_WRITE(dspcntr_reg,
-                               temp | DISPLAY_PLANE_ENABLE);
-                       /* Flush the plane changes */
-                       REG_WRITE(dspbase_reg, REG_READ(dspbase_reg));
-               }
-
-               /* Enable the pipe */
-               temp = REG_READ(pipeconf_reg);
-               if ((temp & PIPEACONF_ENABLE) == 0) {
-                       REG_WRITE(pipeconf_reg, pipeconf);
-
-                       /* Wait for for the pipe enable to take effect. */
-                       mdfldWaitForPipeEnable(dev, pipe);
-               }
-
-               /*workaround for sighting 3741701 Random X blank display*/
-               /*perform w/a in video mode only on pipe A or C*/
-               if ((pipe == 0 || pipe == 2) &&
-                       (mdfld_panel_dpi(dev) == true)) {
-                       REG_WRITE(pipestat_reg, REG_READ(pipestat_reg));
-                       msleep(100);
-                       if(PIPE_VBLANK_STATUS & REG_READ(pipestat_reg)) {
-                               printk(KERN_ALERT "OK");
-                       } else {
-                               printk(KERN_ALERT "STUCK!!!!");
-                               /*shutdown controller*/
-                               temp = REG_READ(dspcntr_reg);
-                               REG_WRITE(dspcntr_reg, temp & ~DISPLAY_PLANE_ENABLE);
-                               REG_WRITE(dspbase_reg, REG_READ(dspbase_reg));
-                               /*mdfld_dsi_dpi_shut_down(dev, pipe);*/
-                               REG_WRITE(0xb048, 1);
-                               msleep(100);
-                               temp = REG_READ(pipeconf_reg);
-                               temp &= ~PIPEACONF_ENABLE;
-                               REG_WRITE(pipeconf_reg, temp);
-                               msleep(100); /*wait for pipe disable*/
-                       /*printk(KERN_ALERT "70008 is %x\n", REG_READ(0x70008));
-                       printk(KERN_ALERT "b074 is %x\n", REG_READ(0xb074));*/
-                               REG_WRITE(mipi_enable_reg, 0);
-                               msleep(100);
-                       printk(KERN_ALERT "70008 is %x\n", REG_READ(0x70008));
-                       printk(KERN_ALERT "b074 is %x\n", REG_READ(0xb074));
-                               REG_WRITE(0xb004, REG_READ(0xb004));
-                               /* try to bring the controller back up again*/
-                               REG_WRITE(mipi_enable_reg, 1);
-                               temp = REG_READ(dspcntr_reg);
-                               REG_WRITE(dspcntr_reg, temp | DISPLAY_PLANE_ENABLE);
-                               REG_WRITE(dspbase_reg, REG_READ(dspbase_reg));
-                               /*mdfld_dsi_dpi_turn_on(dev, pipe);*/
-                               REG_WRITE(0xb048, 2);
-                               msleep(100);
-                               temp = REG_READ(pipeconf_reg);
-                               temp |= PIPEACONF_ENABLE;
-                               REG_WRITE(pipeconf_reg, temp);
-                       }
-               }
-
-               psb_intel_crtc_load_lut(crtc);
-
-               /* Give the overlay scaler a chance to enable
-                  if it's on this pipe */
-               /* psb_intel_crtc_dpms_video(crtc, true); TODO */
-
-               break;
-       case DRM_MODE_DPMS_OFF:
-               /* Give the overlay scaler a chance to disable
-                * if it's on this pipe */
-               /* psb_intel_crtc_dpms_video(crtc, FALSE); TODO */
-               if (pipe != 1)
-                       mdfld_dsi_gen_fifo_ready (dev, gen_fifo_stat_reg, HS_CTRL_FIFO_EMPTY | HS_DATA_FIFO_EMPTY);
-
-               /* Disable the VGA plane that we never use */
-               REG_WRITE(VGACNTRL, VGA_DISP_DISABLE);
-
-               /* Disable display plane */
-               temp = REG_READ(dspcntr_reg);
-               if ((temp & DISPLAY_PLANE_ENABLE) != 0) {
-                       REG_WRITE(dspcntr_reg,
-                                 temp & ~DISPLAY_PLANE_ENABLE);
-                       /* Flush the plane changes */
-                       REG_WRITE(dspbase_reg, REG_READ(dspbase_reg));
-                       REG_READ(dspbase_reg);
-               }
-
-               /* FIXME_JLIU7 MDFLD_PO revisit */
-               /* Wait for vblank for the disable to take effect */
-// MDFLD_PO_JLIU7              psb_intel_wait_for_vblank(dev);
-
-               /* Next, disable display pipes */
-               temp = REG_READ(pipeconf_reg);
-               if ((temp & PIPEACONF_ENABLE) != 0) {
-                       temp &= ~PIPEACONF_ENABLE;
-                       temp |= PIPECONF_PLANE_OFF | PIPECONF_CURSOR_OFF;
-                       REG_WRITE(pipeconf_reg, temp);
-//                     REG_WRITE(pipeconf_reg, 0);
-                       REG_READ(pipeconf_reg);
-
-                       /* Wait for for the pipe disable to take effect. */
-                       mdfldWaitForPipeDisable(dev, pipe);
-               }
-
-               temp = REG_READ(dpll_reg);
-               if (temp & DPLL_VCO_ENABLE) {
-                       if (((pipe != 1) && !((REG_READ(PIPEACONF) | REG_READ(PIPECCONF)) & PIPEACONF_ENABLE))
-                                       || (pipe == 1)){
-                               temp &= ~(DPLL_VCO_ENABLE);
-                               REG_WRITE(dpll_reg, temp);
-                               REG_READ(dpll_reg);
-                               /* Wait for the clocks to turn off. */
-                               /* FIXME_MDFLD PO may need more delay */
-                               udelay(500);
-#if 0 /* MDFLD_PO_JLIU7 */     
-               if (!(temp & MDFLD_PWR_GATE_EN)) {
-                       /* gating power of DPLL */
-                       REG_WRITE(dpll_reg, temp | MDFLD_PWR_GATE_EN);
-                       /* FIXME_MDFLD PO - change 500 to 1 after PO */
-                       udelay(5000);
-               }
-#endif  /* MDFLD_PO_JLIU7 */   
-                       }
-               }
-               break;
-       }
-
-       enabled = crtc->enabled && mode != DRM_MODE_DPMS_OFF;
-
-#if 0                          /* JB: Add vblank support later */
-       if (enabled)
-               dev_priv->vblank_pipe |= (1 << pipe);
-       else
-               dev_priv->vblank_pipe &= ~(1 << pipe);
-#endif
-
-       gma_power_end(dev);
-}
-
-
-#define MDFLD_LIMT_DPLL_19         0
-#define MDFLD_LIMT_DPLL_25         1
-#define MDFLD_LIMT_DPLL_83         2
-#define MDFLD_LIMT_DPLL_100        3
-#define MDFLD_LIMT_DSIPLL_19       4
-#define MDFLD_LIMT_DSIPLL_25       5
-#define MDFLD_LIMT_DSIPLL_83       6
-#define MDFLD_LIMT_DSIPLL_100      7
-
-#define MDFLD_DOT_MIN            19750  /* FIXME_MDFLD JLIU7 need to find out  min & max for MDFLD */
-#define MDFLD_DOT_MAX            120000
-#define MDFLD_DPLL_M_MIN_19        113
-#define MDFLD_DPLL_M_MAX_19        155
-#define MDFLD_DPLL_P1_MIN_19       2
-#define MDFLD_DPLL_P1_MAX_19       10
-#define MDFLD_DPLL_M_MIN_25        101
-#define MDFLD_DPLL_M_MAX_25        130
-#define MDFLD_DPLL_P1_MIN_25       2
-#define MDFLD_DPLL_P1_MAX_25       10
-#define MDFLD_DPLL_M_MIN_83        64
-#define MDFLD_DPLL_M_MAX_83        64
-#define MDFLD_DPLL_P1_MIN_83       2
-#define MDFLD_DPLL_P1_MAX_83       2
-#define MDFLD_DPLL_M_MIN_100       64
-#define MDFLD_DPLL_M_MAX_100       64
-#define MDFLD_DPLL_P1_MIN_100      2
-#define MDFLD_DPLL_P1_MAX_100      2
-#define MDFLD_DSIPLL_M_MIN_19      131
-#define MDFLD_DSIPLL_M_MAX_19      175
-#define MDFLD_DSIPLL_P1_MIN_19     3
-#define MDFLD_DSIPLL_P1_MAX_19     8
-#define MDFLD_DSIPLL_M_MIN_25      97
-#define MDFLD_DSIPLL_M_MAX_25      140
-#define MDFLD_DSIPLL_P1_MIN_25     3
-#define MDFLD_DSIPLL_P1_MAX_25     9
-#define MDFLD_DSIPLL_M_MIN_83      33
-#define MDFLD_DSIPLL_M_MAX_83      92
-#define MDFLD_DSIPLL_P1_MIN_83     2
-#define MDFLD_DSIPLL_P1_MAX_83     3
-#define MDFLD_DSIPLL_M_MIN_100     97
-#define MDFLD_DSIPLL_M_MAX_100     140
-#define MDFLD_DSIPLL_P1_MIN_100            3
-#define MDFLD_DSIPLL_P1_MAX_100            9
-
-static const struct mdfld_limit_t mdfld_limits[] = {
-       {                       /* MDFLD_LIMT_DPLL_19 */
-        .dot = {.min = MDFLD_DOT_MIN, .max = MDFLD_DOT_MAX},
-        .m = {.min = MDFLD_DPLL_M_MIN_19, .max = MDFLD_DPLL_M_MAX_19},
-        .p1 = {.min = MDFLD_DPLL_P1_MIN_19, .max = MDFLD_DPLL_P1_MAX_19},
-        },
-       {                       /* MDFLD_LIMT_DPLL_25 */
-        .dot = {.min = MDFLD_DOT_MIN, .max = MDFLD_DOT_MAX},
-        .m = {.min = MDFLD_DPLL_M_MIN_25, .max = MDFLD_DPLL_M_MAX_25},
-        .p1 = {.min = MDFLD_DPLL_P1_MIN_25, .max = MDFLD_DPLL_P1_MAX_25},
-        },
-       {                       /* MDFLD_LIMT_DPLL_83 */
-        .dot = {.min = MDFLD_DOT_MIN, .max = MDFLD_DOT_MAX},
-        .m = {.min = MDFLD_DPLL_M_MIN_83, .max = MDFLD_DPLL_M_MAX_83},
-        .p1 = {.min = MDFLD_DPLL_P1_MIN_83, .max = MDFLD_DPLL_P1_MAX_83},
-        },
-       {                       /* MDFLD_LIMT_DPLL_100 */
-        .dot = {.min = MDFLD_DOT_MIN, .max = MDFLD_DOT_MAX},
-        .m = {.min = MDFLD_DPLL_M_MIN_100, .max = MDFLD_DPLL_M_MAX_100},
-        .p1 = {.min = MDFLD_DPLL_P1_MIN_100, .max = MDFLD_DPLL_P1_MAX_100},
-        },
-       {                       /* MDFLD_LIMT_DSIPLL_19 */
-        .dot = {.min = MDFLD_DOT_MIN, .max = MDFLD_DOT_MAX},
-        .m = {.min = MDFLD_DSIPLL_M_MIN_19, .max = MDFLD_DSIPLL_M_MAX_19},
-        .p1 = {.min = MDFLD_DSIPLL_P1_MIN_19, .max = MDFLD_DSIPLL_P1_MAX_19},
-        },
-       {                       /* MDFLD_LIMT_DSIPLL_25 */
-        .dot = {.min = MDFLD_DOT_MIN, .max = MDFLD_DOT_MAX},
-        .m = {.min = MDFLD_DSIPLL_M_MIN_25, .max = MDFLD_DSIPLL_M_MAX_25},
-        .p1 = {.min = MDFLD_DSIPLL_P1_MIN_25, .max = MDFLD_DSIPLL_P1_MAX_25},
-        },
-       {                       /* MDFLD_LIMT_DSIPLL_83 */
-        .dot = {.min = MDFLD_DOT_MIN, .max = MDFLD_DOT_MAX},
-        .m = {.min = MDFLD_DSIPLL_M_MIN_83, .max = MDFLD_DSIPLL_M_MAX_83},
-        .p1 = {.min = MDFLD_DSIPLL_P1_MIN_83, .max = MDFLD_DSIPLL_P1_MAX_83},
-        },
-       {                       /* MDFLD_LIMT_DSIPLL_100 */
-        .dot = {.min = MDFLD_DOT_MIN, .max = MDFLD_DOT_MAX},
-        .m = {.min = MDFLD_DSIPLL_M_MIN_100, .max = MDFLD_DSIPLL_M_MAX_100},
-        .p1 = {.min = MDFLD_DSIPLL_P1_MIN_100, .max = MDFLD_DSIPLL_P1_MAX_100},
-        },
-};
-
-#define MDFLD_M_MIN        21
-#define MDFLD_M_MAX        180
-static const u32 mdfld_m_converts[] = {
-/* M configuration table from 9-bit LFSR table */
-       224, 368, 440, 220, 366, 439, 219, 365, 182, 347, /* 21 - 30 */
-       173, 342, 171, 85, 298, 149, 74, 37, 18, 265,   /* 31 - 40 */
-       388, 194, 353, 432, 216, 108, 310, 155, 333, 166, /* 41 - 50 */
-       83, 41, 276, 138, 325, 162, 337, 168, 340, 170, /* 51 - 60 */
-       341, 426, 469, 234, 373, 442, 221, 110, 311, 411, /* 61 - 70 */
-       461, 486, 243, 377, 188, 350, 175, 343, 427, 213, /* 71 - 80 */
-       106, 53, 282, 397, 354, 227, 113, 56, 284, 142, /* 81 - 90 */
-       71, 35, 273, 136, 324, 418, 465, 488, 500, 506, /* 91 - 100 */
-       253, 126, 63, 287, 399, 455, 483, 241, 376, 444, /* 101 - 110 */
-       478, 495, 503, 251, 381, 446, 479, 239, 375, 443, /* 111 - 120 */
-       477, 238, 119, 315, 157, 78, 295, 147, 329, 420, /* 121 - 130 */
-       210, 105, 308, 154, 77, 38, 275, 137, 68, 290, /* 131 - 140 */
-       145, 328, 164, 82, 297, 404, 458, 485, 498, 249, /* 141 - 150 */
-       380, 190, 351, 431, 471, 235, 117, 314, 413, 206, /* 151 - 160 */
-       103, 51, 25, 12, 262, 387, 193, 96, 48, 280, /* 161 - 170 */
-       396, 198, 99, 305, 152, 76, 294, 403, 457, 228, /* 171 - 180 */
-};
-
-static const struct mdfld_limit_t *mdfld_limit(struct drm_crtc *crtc)
-{
-       const struct mdfld_limit_t *limit = NULL;
-       struct drm_device *dev = crtc->dev;
-       struct drm_psb_private *dev_priv = dev->dev_private;
-
-       if (psb_intel_pipe_has_type(crtc, INTEL_OUTPUT_MIPI)
-           || psb_intel_pipe_has_type(crtc, INTEL_OUTPUT_MIPI2)) {
-               if ((ksel == KSEL_CRYSTAL_19) || (ksel == KSEL_BYPASS_19))
-                       limit = &mdfld_limits[MDFLD_LIMT_DSIPLL_19];
-               else if (ksel == KSEL_BYPASS_25) 
-                       limit = &mdfld_limits[MDFLD_LIMT_DSIPLL_25];
-               else if ((ksel == KSEL_BYPASS_83_100) && (dev_priv->core_freq == 166))
-                       limit = &mdfld_limits[MDFLD_LIMT_DSIPLL_83];
-               else if ((ksel == KSEL_BYPASS_83_100) &&
-                        (dev_priv->core_freq == 100 || dev_priv->core_freq == 200))
-                       limit = &mdfld_limits[MDFLD_LIMT_DSIPLL_100];
-       } else if (psb_intel_pipe_has_type(crtc, INTEL_OUTPUT_HDMI)) {
-               if ((ksel == KSEL_CRYSTAL_19) || (ksel == KSEL_BYPASS_19))
-                       limit = &mdfld_limits[MDFLD_LIMT_DPLL_19];
-               else if (ksel == KSEL_BYPASS_25) 
-                       limit = &mdfld_limits[MDFLD_LIMT_DPLL_25];
-               else if ((ksel == KSEL_BYPASS_83_100) && (dev_priv->core_freq == 166))
-                       limit = &mdfld_limits[MDFLD_LIMT_DPLL_83];
-               else if ((ksel == KSEL_BYPASS_83_100) &&
-                        (dev_priv->core_freq == 100 || dev_priv->core_freq == 200))
-                       limit = &mdfld_limits[MDFLD_LIMT_DPLL_100];
-       } else {
-               limit = NULL;
-               dev_err(dev->dev, "mdfld_limit Wrong display type.\n");
-       }
-
-       return limit;
-}
-
-/** Derive the pixel clock for the given refclk and divisors for 8xx chips. */
-static void mdfld_clock(int refclk, struct mdfld_intel_clock_t *clock)
-{
-       clock->dot = (refclk * clock->m) / clock->p1;
-}
-
-/**
- * Returns a set of divisors for the desired target clock with the given refclk,
- * or FALSE.  Divisor values are the actual divisors for
- */
-static bool
-mdfldFindBestPLL(struct drm_crtc *crtc, int target, int refclk,
-               struct mdfld_intel_clock_t *best_clock)
-{
-       struct mdfld_intel_clock_t clock;
-       const struct mdfld_limit_t *limit = mdfld_limit(crtc);
-       int err = target;
-
-       memset(best_clock, 0, sizeof(*best_clock));
-
-       for (clock.m = limit->m.min; clock.m <= limit->m.max; clock.m++) {
-               for (clock.p1 = limit->p1.min; clock.p1 <= limit->p1.max;
-                    clock.p1++) {
-                       int this_err;
-
-                       mdfld_clock(refclk, &clock);
-
-                       this_err = abs(clock.dot - target);
-                       if (this_err < err) {
-                               *best_clock = clock;
-                               err = this_err;
-                       }
-               }
-       }
-       return err != target;
-}
-
-/**
- * Return the pipe currently connected to the panel fitter,
- * or -1 if the panel fitter is not present or not in use
- */
-static int mdfld_panel_fitter_pipe(struct drm_device *dev)
-{
-       u32 pfit_control;
-
-       pfit_control = REG_READ(PFIT_CONTROL);
-
-       /* See if the panel fitter is in use */
-       if ((pfit_control & PFIT_ENABLE) == 0)
-               return -1;
-       return (pfit_control >> 29) & 3;
-}
-
-static int mdfld_crtc_mode_set(struct drm_crtc *crtc,
-                             struct drm_display_mode *mode,
-                             struct drm_display_mode *adjusted_mode,
-                             int x, int y,
-                             struct drm_framebuffer *old_fb)
-{
-       struct drm_device *dev = crtc->dev;
-       struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
-       struct drm_psb_private *dev_priv = dev->dev_private;
-       int pipe = psb_intel_crtc->pipe;
-       int fp_reg = MRST_FPA0;
-       int dpll_reg = MRST_DPLL_A;
-       int dspcntr_reg = DSPACNTR;
-       int pipeconf_reg = PIPEACONF;
-       int htot_reg = HTOTAL_A;
-       int hblank_reg = HBLANK_A;
-       int hsync_reg = HSYNC_A;
-       int vtot_reg = VTOTAL_A;
-       int vblank_reg = VBLANK_A;
-       int vsync_reg = VSYNC_A;
-       int dspsize_reg = DSPASIZE; 
-       int dsppos_reg = DSPAPOS; 
-       int pipesrc_reg = PIPEASRC;
-       u32 *pipeconf = &dev_priv->pipeconf;
-       u32 *dspcntr = &dev_priv->dspcntr;
-       int refclk = 0;
-       int clk_n = 0, clk_p2 = 0, clk_byte = 1, clk = 0, m_conv = 0, clk_tmp = 0;
-       struct mdfld_intel_clock_t clock;
-       bool ok;
-       u32 dpll = 0, fp = 0;
-       bool is_crt = false, is_lvds = false, is_tv = false;
-       bool is_mipi = false, is_mipi2 = false, is_hdmi = false;
-       struct drm_mode_config *mode_config = &dev->mode_config;
-       struct psb_intel_output *psb_intel_output = NULL;
-       uint64_t scalingType = DRM_MODE_SCALE_FULLSCREEN;
-       struct drm_encoder *encoder;
-       struct drm_connector *connector;
-       int timeout = 0;
-
-       dev_dbg(dev->dev, "pipe = 0x%x \n", pipe);
-
-       switch (pipe) {
-       case 0:
-               break;
-       case 1:
-               fp_reg = FPB0;
-               dpll_reg = DPLL_B;
-               dspcntr_reg = DSPBCNTR;
-               pipeconf_reg = PIPEBCONF;
-               htot_reg = HTOTAL_B;
-               hblank_reg = HBLANK_B;
-               hsync_reg = HSYNC_B;
-               vtot_reg = VTOTAL_B;
-               vblank_reg = VBLANK_B;
-               vsync_reg = VSYNC_B;
-               dspsize_reg = DSPBSIZE; 
-               dsppos_reg = DSPBPOS; 
-               pipesrc_reg = PIPEBSRC;
-               pipeconf = &dev_priv->pipeconf1;
-               dspcntr = &dev_priv->dspcntr1;
-               fp_reg = MDFLD_DPLL_DIV0;
-               dpll_reg = MDFLD_DPLL_B;
-               break;
-       case 2:
-               dpll_reg = MRST_DPLL_A;
-               dspcntr_reg = DSPCCNTR;
-               pipeconf_reg = PIPECCONF;
-               htot_reg = HTOTAL_C;
-               hblank_reg = HBLANK_C;
-               hsync_reg = HSYNC_C;
-               vtot_reg = VTOTAL_C;
-               vblank_reg = VBLANK_C;
-               vsync_reg = VSYNC_C;
-               dspsize_reg = DSPCSIZE; 
-               dsppos_reg = DSPCPOS; 
-               pipesrc_reg = PIPECSRC;
-               pipeconf = &dev_priv->pipeconf2;
-               dspcntr = &dev_priv->dspcntr2;
-               break;
-       default:
-               DRM_ERROR("Illegal Pipe Number. \n");
-               return 0;
-       }
-
-       dev_dbg(dev->dev, "adjusted_hdisplay = %d\n",
-                adjusted_mode->hdisplay);
-       dev_dbg(dev->dev, "adjusted_vdisplay = %d\n",
-                adjusted_mode->vdisplay);
-       dev_dbg(dev->dev, "adjusted_hsync_start = %d\n",
-                adjusted_mode->hsync_start);
-       dev_dbg(dev->dev, "adjusted_hsync_end = %d\n",
-                adjusted_mode->hsync_end);
-       dev_dbg(dev->dev, "adjusted_htotal = %d\n",
-                adjusted_mode->htotal);
-       dev_dbg(dev->dev, "adjusted_vsync_start = %d\n",
-                adjusted_mode->vsync_start);
-       dev_dbg(dev->dev, "adjusted_vsync_end = %d\n",
-                adjusted_mode->vsync_end);
-       dev_dbg(dev->dev, "adjusted_vtotal = %d\n",
-                adjusted_mode->vtotal);
-       dev_dbg(dev->dev, "adjusted_clock = %d\n",
-                adjusted_mode->clock);
-       dev_dbg(dev->dev, "hdisplay = %d\n",
-                mode->hdisplay);
-       dev_dbg(dev->dev, "vdisplay = %d\n",
-                mode->vdisplay);
-
-       if (!gma_power_begin(dev, true))
-               return 0;
-
-       memcpy(&psb_intel_crtc->saved_mode, mode, sizeof(struct drm_display_mode));
-       memcpy(&psb_intel_crtc->saved_adjusted_mode, adjusted_mode, sizeof(struct drm_display_mode));
-
-       list_for_each_entry(connector, &mode_config->connector_list, head) {
-                       
-               encoder = connector->encoder;
-               
-               if(!encoder)
-                       continue;
-
-               if (encoder->crtc != crtc)
-                       continue;
-
-               psb_intel_output = to_psb_intel_output(connector);
-               
-               dev_dbg(dev->dev, "output->type = 0x%x \n", psb_intel_output->type);
-
-               switch (psb_intel_output->type) {
-               case INTEL_OUTPUT_LVDS:
-                       is_lvds = true;
-                       break;
-               case INTEL_OUTPUT_TVOUT:
-                       is_tv = true;
-                       break;
-               case INTEL_OUTPUT_ANALOG:
-                       is_crt = true;
-                       break;
-               case INTEL_OUTPUT_MIPI:
-                       is_mipi = true;
-                       break;
-               case INTEL_OUTPUT_MIPI2:
-                       is_mipi2 = true;
-                       break;
-               case INTEL_OUTPUT_HDMI:
-                       is_hdmi = true;
-                       break;
-               }
-       }
-
-       /* Disable the VGA plane that we never use */
-       REG_WRITE(VGACNTRL, VGA_DISP_DISABLE);
-
-       /* Disable the panel fitter if it was on our pipe */
-       if (mdfld_panel_fitter_pipe(dev) == pipe)
-               REG_WRITE(PFIT_CONTROL, 0);
-
-       /* pipesrc and dspsize control the size that is scaled from,
-        * which should always be the user's requested size.
-        */
-       if (pipe == 1) {
-               /* FIXME: To make HDMI display with 864x480 (TPO), 480x864 (PYR) or 480x854 (TMD), set the sprite
-                * width/height and souce image size registers with the adjusted mode for pipe B. */
-
-               /* The defined sprite rectangle must always be completely contained within the displayable
-                * area of the screen image (frame buffer). */
-               REG_WRITE(dspsize_reg, ((MIN(mode->crtc_vdisplay, adjusted_mode->crtc_vdisplay) - 1) << 16)
-                               | (MIN(mode->crtc_hdisplay, adjusted_mode->crtc_hdisplay) - 1));
-               /* Set the CRTC with encoder mode. */
-               REG_WRITE(pipesrc_reg, ((mode->crtc_hdisplay - 1) << 16)
-                                | (mode->crtc_vdisplay - 1));
-       } else {
-               REG_WRITE(dspsize_reg, ((mode->crtc_vdisplay - 1) << 16) | (mode->crtc_hdisplay - 1));
-               REG_WRITE(pipesrc_reg, ((mode->crtc_hdisplay - 1) << 16) | (mode->crtc_vdisplay - 1));
-       }
-
-       REG_WRITE(dsppos_reg, 0);
-
-       if (psb_intel_output)
-               drm_connector_property_get_value(&psb_intel_output->base,
-                       dev->mode_config.scaling_mode_property, &scalingType);
-
-       if (scalingType == DRM_MODE_SCALE_NO_SCALE) {
-               /*
-                *      Medfield doesn't have register support for centering so
-                *      we need to mess with the h/vblank and h/vsync start and
-                *      ends to get central
-                */
-               int offsetX = 0, offsetY = 0;
-
-               offsetX = (adjusted_mode->crtc_hdisplay - mode->crtc_hdisplay) / 2;
-               offsetY = (adjusted_mode->crtc_vdisplay - mode->crtc_vdisplay) / 2;
-
-               REG_WRITE(htot_reg, (mode->crtc_hdisplay - 1) |
-                       ((adjusted_mode->crtc_htotal - 1) << 16));
-               REG_WRITE(vtot_reg, (mode->crtc_vdisplay - 1) |
-                       ((adjusted_mode->crtc_vtotal - 1) << 16));
-               REG_WRITE(hblank_reg, (adjusted_mode->crtc_hblank_start - offsetX - 1) |
-                       ((adjusted_mode->crtc_hblank_end - offsetX - 1) << 16));
-               REG_WRITE(hsync_reg, (adjusted_mode->crtc_hsync_start - offsetX - 1) |
-                       ((adjusted_mode->crtc_hsync_end - offsetX - 1) << 16));
-               REG_WRITE(vblank_reg, (adjusted_mode->crtc_vblank_start - offsetY - 1) |
-                       ((adjusted_mode->crtc_vblank_end - offsetY - 1) << 16));
-               REG_WRITE(vsync_reg, (adjusted_mode->crtc_vsync_start - offsetY - 1) |
-                       ((adjusted_mode->crtc_vsync_end - offsetY - 1) << 16));
-       } else {
-               REG_WRITE(htot_reg, (adjusted_mode->crtc_hdisplay - 1) |
-                       ((adjusted_mode->crtc_htotal - 1) << 16));
-               REG_WRITE(vtot_reg, (adjusted_mode->crtc_vdisplay - 1) |
-                       ((adjusted_mode->crtc_vtotal - 1) << 16));
-               REG_WRITE(hblank_reg, (adjusted_mode->crtc_hblank_start - 1) |
-                       ((adjusted_mode->crtc_hblank_end - 1) << 16));
-               REG_WRITE(hsync_reg, (adjusted_mode->crtc_hsync_start - 1) |
-                       ((adjusted_mode->crtc_hsync_end - 1) << 16));
-               REG_WRITE(vblank_reg, (adjusted_mode->crtc_vblank_start - 1) |
-                       ((adjusted_mode->crtc_vblank_end - 1) << 16));
-               REG_WRITE(vsync_reg, (adjusted_mode->crtc_vsync_start - 1) |
-                       ((adjusted_mode->crtc_vsync_end - 1) << 16));
-       }
-
-       /* Flush the plane changes */
-       {
-               struct drm_crtc_helper_funcs *crtc_funcs =
-                   crtc->helper_private;
-               crtc_funcs->mode_set_base(crtc, x, y, old_fb);
-       }
-
-       /* setup pipeconf */
-       *pipeconf = PIPEACONF_ENABLE; /* FIXME_JLIU7 REG_READ(pipeconf_reg); */
-
-       /* Set up the display plane register */
-       *dspcntr = REG_READ(dspcntr_reg);
-       *dspcntr |= pipe << DISPPLANE_SEL_PIPE_POS;
-       *dspcntr |= DISPLAY_PLANE_ENABLE;
-/* MDFLD_PO_JLIU7      dspcntr |= DISPPLANE_BOTTOM; */
-/* MDFLD_PO_JLIU7      dspcntr |= DISPPLANE_GAMMA_ENABLE; */
-
-       if (is_mipi2)
-       {
-               goto mrst_crtc_mode_set_exit;
-       }
-/* FIXME JLIU7 Add MDFLD HDMI supports */
-/* FIXME_MDFLD JLIU7 DSIPLL clock *= 8? */
-/* FIXME_MDFLD JLIU7 need to revist for dual MIPI supports */
-       clk = adjusted_mode->clock;
-
-       if (is_hdmi) {
-               if ((ksel == KSEL_CRYSTAL_19) || (ksel == KSEL_BYPASS_19))
-               {
-                       refclk = 19200;
-
-                       if (is_mipi || is_mipi2)
-                       {
-                               clk_n = 1, clk_p2 = 8;
-                       } else if (is_hdmi) {
-                               clk_n = 1, clk_p2 = 10;
-                       }
-               } else if (ksel == KSEL_BYPASS_25) { 
-                       refclk = 25000;
-
-                       if (is_mipi || is_mipi2)
-                       {
-                               clk_n = 1, clk_p2 = 8;
-                       } else if (is_hdmi) {
-                               clk_n = 1, clk_p2 = 10;
-                       }
-               } else if ((ksel == KSEL_BYPASS_83_100) && (dev_priv->core_freq == 166)) {
-                       refclk = 83000;
-
-                       if (is_mipi || is_mipi2)
-                       {
-                               clk_n = 4, clk_p2 = 8;
-                       } else if (is_hdmi) {
-                               clk_n = 4, clk_p2 = 10;
-                       }
-               } else if ((ksel == KSEL_BYPASS_83_100) &&
-                          (dev_priv->core_freq == 100 || dev_priv->core_freq == 200)) {
-                       refclk = 100000;
-                       if (is_mipi || is_mipi2)
-                       {
-                               clk_n = 4, clk_p2 = 8;
-                       } else if (is_hdmi) {
-                               clk_n = 4, clk_p2 = 10;
-                       }
-               }
-
-               if (is_mipi)
-                       clk_byte = dev_priv->bpp / 8;
-               else if (is_mipi2)
-                       clk_byte = dev_priv->bpp2 / 8;
-       
-               clk_tmp = clk * clk_n * clk_p2 * clk_byte;
-
-               dev_dbg(dev->dev, "clk = %d, clk_n = %d, clk_p2 = %d. \n", clk, clk_n, clk_p2);
-               dev_dbg(dev->dev, "adjusted_mode->clock = %d, clk_tmp = %d. \n", adjusted_mode->clock, clk_tmp);
-
-               ok = mdfldFindBestPLL(crtc, clk_tmp, refclk, &clock);
-
-               if (!ok) {
-                       dev_err(dev->dev, 
-                          "mdfldFindBestPLL fail in mdfld_crtc_mode_set. \n");
-               } else {
-                       m_conv = mdfld_m_converts[(clock.m - MDFLD_M_MIN)];
-
-                       dev_dbg(dev->dev, "dot clock = %d,"
-                                "m = %d, p1 = %d, m_conv = %d. \n", clock.dot, clock.m,
-                                clock.p1, m_conv);
-               }
-
-               dpll = REG_READ(dpll_reg);
-
-               if (dpll & DPLL_VCO_ENABLE) {
-                       dpll &= ~DPLL_VCO_ENABLE;
-                       REG_WRITE(dpll_reg, dpll);
-                       REG_READ(dpll_reg);
-
-                       /* FIXME jliu7 check the DPLL lock bit PIPEACONF[29] */
-                       /* FIXME_MDFLD PO - change 500 to 1 after PO */
-                       udelay(500);
-
-                       /* reset M1, N1 & P1 */
-                       REG_WRITE(fp_reg, 0);
-                       dpll &= ~MDFLD_P1_MASK;
-                       REG_WRITE(dpll_reg, dpll);
-                       /* FIXME_MDFLD PO - change 500 to 1 after PO */
-                       udelay(500);
-               }
-
-               /* When ungating power of DPLL, needs to wait 0.5us before enable the VCO */
-               if (dpll & MDFLD_PWR_GATE_EN) {
-                       dpll &= ~MDFLD_PWR_GATE_EN;
-                       REG_WRITE(dpll_reg, dpll);
-                       /* FIXME_MDFLD PO - change 500 to 1 after PO */
-                       udelay(500);
-               }       
-
-               dpll = 0; 
-
-#if 0 /* FIXME revisit later */
-               if ((ksel == KSEL_CRYSTAL_19) || (ksel == KSEL_BYPASS_19) || (ksel == KSEL_BYPASS_25)) {
-                       dpll &= ~MDFLD_INPUT_REF_SEL;   
-               } else if (ksel == KSEL_BYPASS_83_100) { 
-                       dpll |= MDFLD_INPUT_REF_SEL;    
-               }
-#endif /* FIXME revisit later */
-
-               if (is_hdmi)
-                       dpll |= MDFLD_VCO_SEL;  
-
-               fp = (clk_n / 2) << 16;
-               fp |= m_conv; 
-
-               /* compute bitmask from p1 value */
-               dpll |= (1 << (clock.p1 - 2)) << 17;
-
-#if 0 /* 1080p30 & 720p */
-               dpll = 0x00050000;
-               fp = 0x000001be;
-#endif 
-#if 0 /* 480p */
-               dpll = 0x02010000;
-               fp = 0x000000d2;
-#endif 
-       } else {
-#if 0 /*DBI_TPO_480x864*/
-               dpll = 0x00020000;
-               fp = 0x00000156; 
-#endif /* DBI_TPO_480x864 */ /* get from spec. */
-
-               dpll = 0x00800000;
-               fp = 0x000000c1;
-}
-
-       REG_WRITE(fp_reg, fp);
-       REG_WRITE(dpll_reg, dpll);
-       /* FIXME_MDFLD PO - change 500 to 1 after PO */
-       udelay(500);
-
-       dpll |= DPLL_VCO_ENABLE;
-       REG_WRITE(dpll_reg, dpll);
-       REG_READ(dpll_reg);
-
-       /* wait for DSI PLL to lock */
-       while ((timeout < 20000) && !(REG_READ(pipeconf_reg) & PIPECONF_DSIPLL_LOCK)) {
-               udelay(150);
-               timeout ++;
-       }
-
-       if (is_mipi)
-               goto mrst_crtc_mode_set_exit;
-
-       dev_dbg(dev->dev, "is_mipi = 0x%x \n", is_mipi);
-
-       REG_WRITE(pipeconf_reg, *pipeconf);
-       REG_READ(pipeconf_reg);
-
-       /* Wait for for the pipe enable to take effect. */
-//FIXME_JLIU7 HDMI     mrstWaitForPipeEnable(dev);
-
-       REG_WRITE(dspcntr_reg, *dspcntr);
-       psb_intel_wait_for_vblank(dev);
-
-mrst_crtc_mode_set_exit:
-
-       gma_power_end(dev);
-
-       return 0;
-}
-
-static void mdfld_crtc_prepare(struct drm_crtc *crtc)
-{
-       struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
-       crtc_funcs->dpms(crtc, DRM_MODE_DPMS_OFF);
-}
-
-static void mdfld_crtc_commit(struct drm_crtc *crtc)
-{
-       struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
-       crtc_funcs->dpms(crtc, DRM_MODE_DPMS_ON);
-}
-
-static bool mdfld_crtc_mode_fixup(struct drm_crtc *crtc,
-                                 struct drm_display_mode *mode,
-                                 struct drm_display_mode *adjusted_mode)
-{
-       return true;
-}
-
-const struct drm_crtc_helper_funcs mdfld_helper_funcs = {
-       .dpms = mdfld_crtc_dpms,
-       .mode_fixup = mdfld_crtc_mode_fixup,
-       .mode_set = mdfld_crtc_mode_set,
-       .mode_set_base = mdfld__intel_pipe_set_base,
-       .prepare = mdfld_crtc_prepare,
-       .commit = mdfld_crtc_commit,
-};
diff --git a/drivers/staging/gma500/mdfld_msic.h b/drivers/staging/gma500/mdfld_msic.h
deleted file mode 100644 (file)
index a7ad654..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright Â© 2010 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Authors:
- *     Jim Liu <jim.liu@intel.com>
- */
-
-#define MSIC_PCI_DEVICE_ID     0x831
-
-int msic_regsiter_driver(void);
-int msic_unregister_driver(void);
-extern void hpd_notify_um(void);
diff --git a/drivers/staging/gma500/mdfld_output.c b/drivers/staging/gma500/mdfld_output.c
deleted file mode 100644 (file)
index eabf53d..0000000
+++ /dev/null
@@ -1,171 +0,0 @@
-/*
- * Copyright (c)  2010 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicensen
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Authors:
- * Thomas Eaton <thomas.g.eaton@intel.com>
- * Scott Rowe <scott.m.rowe@intel.com>
-*/
-
-#include <linux/init.h>
-#include <linux/moduleparam.h>
-#include "mdfld_dsi_dbi.h"
-#include "mdfld_dsi_dpi.h"
-#include "mdfld_dsi_output.h"
-#include "mdfld_output.h"
-#include "mdfld_dsi_dbi_dpu.h"
-
-#include "displays/tpo_cmd.h"
-#include "displays/tpo_vid.h"
-#include "displays/tmd_cmd.h"
-#include "displays/tmd_vid.h"
-#include "displays/pyr_cmd.h"
-#include "displays/pyr_vid.h"
-/* #include "displays/hdmi.h" */
-
-static int mdfld_dual_mipi;
-static int mdfld_hdmi;
-static int mdfld_dpu;
-
-module_param(mdfld_dual_mipi, int, 0600);
-MODULE_PARM_DESC(mdfld_dual_mipi, "Enable dual MIPI configuration");
-module_param(mdfld_hdmi, int, 0600);
-MODULE_PARM_DESC(mdfld_hdmi, "Enable Medfield HDMI");
-module_param(mdfld_dpu, int, 0600);
-MODULE_PARM_DESC(mdfld_dpu, "Enable Medfield DPU");
-
-/* For now a single type per device is all we cope with */
-int mdfld_get_panel_type(struct drm_device *dev, int pipe)
-{
-       struct drm_psb_private *dev_priv = dev->dev_private;
-       return dev_priv->panel_id;
-}
-
-int mdfld_panel_dpi(struct drm_device *dev)
-{
-       struct drm_psb_private *dev_priv = dev->dev_private;
-
-       switch (dev_priv->panel_id) {
-       case TMD_VID:
-       case TPO_VID:
-       case PYR_VID:
-               return true;
-       case TMD_CMD:
-       case TPO_CMD:
-       case PYR_CMD:
-       default:
-               return false;
-       }
-}
-
-static int init_panel(struct drm_device *dev, int mipi_pipe, int p_type)
-{
-       struct panel_funcs *p_cmd_funcs;
-       struct panel_funcs *p_vid_funcs;
-
-       /* Oh boy ... FIXME */
-       p_cmd_funcs = kzalloc(sizeof(struct panel_funcs), GFP_KERNEL);
-       if (p_cmd_funcs == NULL)
-               return -ENODEV;
-       p_vid_funcs = kzalloc(sizeof(struct panel_funcs), GFP_KERNEL);
-       if (p_vid_funcs == NULL) {
-               kfree(p_cmd_funcs);
-               return -ENODEV;
-       }
-
-       switch (p_type) {
-       case TPO_CMD:
-               tpo_cmd_init(dev, p_cmd_funcs);
-               mdfld_dsi_output_init(dev, mipi_pipe, NULL, p_cmd_funcs, NULL);
-               break;
-       case TPO_VID:
-               tpo_vid_init(dev, p_vid_funcs);
-               mdfld_dsi_output_init(dev, mipi_pipe, NULL, NULL, p_vid_funcs);
-               break;
-       case TMD_CMD:
-               /*tmd_cmd_init(dev, p_cmd_funcs); */
-               mdfld_dsi_output_init(dev, mipi_pipe, NULL, p_cmd_funcs, NULL);
-               break;
-       case TMD_VID:
-               tmd_vid_init(dev, p_vid_funcs);
-               mdfld_dsi_output_init(dev, mipi_pipe, NULL, NULL, p_vid_funcs);
-               break;
-       case PYR_CMD:
-               pyr_cmd_init(dev, p_cmd_funcs);
-               mdfld_dsi_output_init(dev, mipi_pipe, NULL, p_cmd_funcs, NULL);
-               break;
-       case PYR_VID:
-               mdfld_dsi_output_init(dev, mipi_pipe, NULL, NULL, p_vid_funcs);
-               break;
-       case TPO:       /* TPO panel supports both cmd & vid interfaces */
-               tpo_cmd_init(dev, p_cmd_funcs);
-               tpo_vid_init(dev, p_vid_funcs);
-               mdfld_dsi_output_init(dev, mipi_pipe, NULL, p_cmd_funcs,
-                                     p_vid_funcs);
-               break;
-       case TMD:
-               break;
-       case PYR:
-               break;
-#if 0
-       case HDMI:
-               dev_dbg(dev->dev, "Initializing HDMI");
-               mdfld_hdmi_init(dev, &dev_priv->mode_dev);
-               break;
-#endif
-       default:
-               dev_err(dev->dev, "Unsupported interface %d", p_type);
-               return -ENODEV;
-       }
-       return 0;
-}
-
-int mdfld_output_init(struct drm_device *dev)
-{
-       int type;
-
-       /* MIPI panel 1 */
-       type = mdfld_get_panel_type(dev, 0);
-       dev_info(dev->dev, "panel 1: type is %d\n", type);
-       init_panel(dev, 0, type);
-
-       if (mdfld_dual_mipi) {
-               /* MIPI panel 2 */
-               type = mdfld_get_panel_type(dev, 2);
-               dev_info(dev->dev, "panel 2: type is %d\n", type);
-               init_panel(dev, 2, type);
-       }
-       if (mdfld_hdmi)
-               /* HDMI panel */
-               init_panel(dev, 0, HDMI);
-       return 0;
-}
-
-void mdfld_output_setup(struct drm_device *dev)
-{
-       /* FIXME: this is not the right place for this stuff ! */
-       if (IS_MFLD(dev)) {
-               if (mdfld_dpu)
-                       mdfld_dbi_dpu_init(dev);
-               else
-                       mdfld_dbi_dsr_init(dev);
-       }
-}
diff --git a/drivers/staging/gma500/mdfld_output.h b/drivers/staging/gma500/mdfld_output.h
deleted file mode 100644 (file)
index daf33e7..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (c)  2010 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicensen
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Authors:
- * Thomas Eaton <thomas.g.eaton@intel.com>
- * Scott Rowe <scott.m.rowe@intel.com>
-*/
-
-#ifndef MDFLD_OUTPUT_H
-#define MDFLD_OUTPUT_H
-
-int mdfld_output_init(struct drm_device *dev);
-int mdfld_panel_dpi(struct drm_device *dev);
-int mdfld_get_panel_type(struct drm_device *dev, int pipe);
-void mdfld_disable_crtc (struct drm_device *dev, int pipe);
-
-extern const struct drm_crtc_helper_funcs mdfld_helper_funcs;
-extern const struct drm_crtc_funcs mdfld_intel_crtc_funcs;
-
-extern void mdfld_output_setup(struct drm_device *dev);
-
-#endif
diff --git a/drivers/staging/gma500/mdfld_pyr_cmd.c b/drivers/staging/gma500/mdfld_pyr_cmd.c
deleted file mode 100644 (file)
index 523f2d8..0000000
+++ /dev/null
@@ -1,558 +0,0 @@
-/*
- * Copyright (c)  2010 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicensen
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Authors:
- * Thomas Eaton <thomas.g.eaton@intel.com>
- * Scott Rowe <scott.m.rowe@intel.com>
-*/
-
-#include "mdfld_dsi_dbi.h"
-#include "mdfld_dsi_dpi.h"
-#include "mdfld_dsi_output.h"
-#include "mdfld_output.h"
-#include "mdfld_dsi_dbi_dpu.h"
-#include "mdfld_dsi_pkg_sender.h"
-
-#include "displays/pyr_cmd.h"
-
-static struct drm_display_mode *pyr_cmd_get_config_mode(struct drm_device *dev)
-{
-       struct drm_display_mode *mode;
-
-       mode = kzalloc(sizeof(*mode), GFP_KERNEL);
-       if (!mode) {
-               dev_err(dev->dev, "Out of memory\n");
-               return NULL;
-       }
-
-       dev_dbg(dev->dev, "hdisplay is %d\n", mode->hdisplay);
-       dev_dbg(dev->dev, "vdisplay is %d\n", mode->vdisplay);
-       dev_dbg(dev->dev, "HSS is %d\n", mode->hsync_start);
-       dev_dbg(dev->dev, "HSE is %d\n", mode->hsync_end);
-       dev_dbg(dev->dev, "htotal is %d\n", mode->htotal);
-       dev_dbg(dev->dev, "VSS is %d\n", mode->vsync_start);
-       dev_dbg(dev->dev, "VSE is %d\n", mode->vsync_end);
-       dev_dbg(dev->dev, "vtotal is %d\n", mode->vtotal);
-       dev_dbg(dev->dev, "clock is %d\n", mode->clock);
-
-       mode->hdisplay = 480;
-       mode->vdisplay = 864;
-       mode->hsync_start = 487;
-       mode->hsync_end = 490;
-       mode->htotal = 499;
-       mode->vsync_start = 874;
-       mode->vsync_end = 878;
-       mode->vtotal = 886;
-       mode->clock = 25777;
-
-       drm_mode_set_name(mode);
-       drm_mode_set_crtcinfo(mode, 0);
-
-       mode->type |= DRM_MODE_TYPE_PREFERRED;
-
-       return mode;
-}
-
-static bool pyr_dsi_dbi_mode_fixup(struct drm_encoder *encoder,
-                               struct drm_display_mode *mode,
-                               struct drm_display_mode *adjusted_mode)
-{
-       struct drm_device *dev = encoder->dev;
-       struct drm_display_mode *fixed_mode = pyr_cmd_get_config_mode(dev);
-
-       if (fixed_mode) {
-               adjusted_mode->hdisplay = fixed_mode->hdisplay;
-               adjusted_mode->hsync_start = fixed_mode->hsync_start;
-               adjusted_mode->hsync_end = fixed_mode->hsync_end;
-               adjusted_mode->htotal = fixed_mode->htotal;
-               adjusted_mode->vdisplay = fixed_mode->vdisplay;
-               adjusted_mode->vsync_start = fixed_mode->vsync_start;
-               adjusted_mode->vsync_end = fixed_mode->vsync_end;
-               adjusted_mode->vtotal = fixed_mode->vtotal;
-               adjusted_mode->clock = fixed_mode->clock;
-               drm_mode_set_crtcinfo(adjusted_mode, CRTC_INTERLACE_HALVE_V);
-               kfree(fixed_mode);
-       }
-       return true;
-}
-
-static void pyr_dsi_dbi_set_power(struct drm_encoder *encoder, bool on)
-{
-       int ret = 0;
-       struct mdfld_dsi_encoder *dsi_encoder = MDFLD_DSI_ENCODER(encoder);
-       struct mdfld_dsi_dbi_output *dbi_output =
-                               MDFLD_DSI_DBI_OUTPUT(dsi_encoder);
-       struct drm_device *dev = encoder->dev;
-       struct drm_psb_private *dev_priv = dev->dev_private;
-       u32 reg_offset = 0;
-       int pipe = (dbi_output->channel_num == 0) ? 0 : 2;
-
-       dev_dbg(dev->dev, "pipe %d : %s, panel on: %s\n", pipe,
-                       on ? "On" : "Off",
-                       dbi_output->dbi_panel_on ? "True" : "False");
-
-       if (pipe == 2) {
-               if (on)
-                       dev_priv->dual_mipi = true;
-               else
-                       dev_priv->dual_mipi = false;
-
-               reg_offset = MIPIC_REG_OFFSET;
-       } else {
-               if (!on)
-                       dev_priv->dual_mipi = false;
-       }
-
-       if (!gma_power_begin(dev, true)) {
-               dev_err(dev->dev, "hw begin failed\n");
-               return;
-       }
-
-
-       if (on) {
-               if (dbi_output->dbi_panel_on)
-                       goto out_err;
-
-               ret = mdfld_dsi_dbi_update_power(dbi_output, DRM_MODE_DPMS_ON);
-               if (ret) {
-                       dev_err(dev->dev, "power on error\n");
-                       goto out_err;
-               }
-
-               dbi_output->dbi_panel_on = true;
-
-               if (pipe == 2) {
-                       dev_priv->dbi_panel_on2 = true;
-               } else {
-                       dev_priv->dbi_panel_on = true;
-                       mdfld_enable_te(dev, 0);
-               }
-       } else {
-               if (!dbi_output->dbi_panel_on && !dbi_output->first_boot)
-                       goto out_err;
-
-               dbi_output->dbi_panel_on = false;
-               dbi_output->first_boot = false;
-
-               if (pipe == 2) {
-                       dev_priv->dbi_panel_on2 = false;
-                       mdfld_disable_te(dev, 2);
-               } else {
-                       dev_priv->dbi_panel_on = false;
-                       mdfld_disable_te(dev, 0);
-
-                       if (dev_priv->dbi_panel_on2)
-                               mdfld_enable_te(dev, 2);
-               }
-
-               ret = mdfld_dsi_dbi_update_power(dbi_output, DRM_MODE_DPMS_OFF);
-               if (ret) {
-                       dev_err(dev->dev, "power on error\n");
-                       goto out_err;
-               }
-       }
-
-out_err:
-       gma_power_end(dev);
-
-       if (ret)
-               dev_err(dev->dev, "failed\n");
-}
-
-static void pyr_dsi_controller_dbi_init(struct mdfld_dsi_config *dsi_config,
-                                                               int pipe)
-{
-       struct drm_device *dev = dsi_config->dev;
-       u32 reg_offset = pipe ? MIPIC_REG_OFFSET : 0;
-       int lane_count = dsi_config->lane_count;
-       u32 val = 0;
-
-       dev_dbg(dev->dev, "Init DBI interface on pipe %d...\n", pipe);
-
-       /* Un-ready device */
-       REG_WRITE((MIPIA_DEVICE_READY_REG + reg_offset), 0x00000000);
-
-       /* Init dsi adapter before kicking off */
-       REG_WRITE((MIPIA_CONTROL_REG + reg_offset), 0x00000018);
-
-       /* TODO: figure out how to setup these registers */
-       REG_WRITE((MIPIA_DPHY_PARAM_REG + reg_offset), 0x150c600F);
-       REG_WRITE((MIPIA_CLK_LANE_SWITCH_TIME_CNT_REG + reg_offset),
-                                                               0x000a0014);
-       REG_WRITE((MIPIA_DBI_BW_CTRL_REG + reg_offset), 0x00000400);
-       REG_WRITE((MIPIA_HS_LS_DBI_ENABLE_REG + reg_offset), 0x00000000);
-
-       /* Enable all interrupts */
-       REG_WRITE((MIPIA_INTR_EN_REG + reg_offset), 0xffffffff);
-       /* Max value: 20 clock cycles of txclkesc */
-       REG_WRITE((MIPIA_TURN_AROUND_TIMEOUT_REG + reg_offset), 0x0000001f);
-       /* Min 21 txclkesc, max: ffffh */
-       REG_WRITE((MIPIA_DEVICE_RESET_TIMER_REG + reg_offset), 0x0000ffff);
-       /* Min: 7d0 max: 4e20 */
-       REG_WRITE((MIPIA_INIT_COUNT_REG + reg_offset), 0x00000fa0);
-
-       /* Set up func_prg */
-       val |= lane_count;
-       val |= (dsi_config->channel_num << DSI_DBI_VIRT_CHANNEL_OFFSET);
-       val |= DSI_DBI_COLOR_FORMAT_OPTION2;
-       REG_WRITE((MIPIA_DSI_FUNC_PRG_REG + reg_offset), val);
-
-       REG_WRITE((MIPIA_HS_TX_TIMEOUT_REG + reg_offset), 0x3fffff);
-       REG_WRITE((MIPIA_LP_RX_TIMEOUT_REG + reg_offset), 0xffff);
-
-       /* De-assert dbi_stall when half of DBI FIFO is empty */
-       /* REG_WRITE((MIPIA_DBI_FIFO_THROTTLE_REG + reg_offset), 0x00000000); */
-
-       REG_WRITE((MIPIA_HIGH_LOW_SWITCH_COUNT_REG + reg_offset), 0x46);
-       REG_WRITE((MIPIA_EOT_DISABLE_REG + reg_offset), 0x00000002);
-       REG_WRITE((MIPIA_LP_BYTECLK_REG + reg_offset), 0x00000004);
-       REG_WRITE((MIPIA_DEVICE_READY_REG + reg_offset), 0x00000001);
-}
-
-static void pyr_dsi_dbi_mode_set(struct drm_encoder *encoder,
-                               struct drm_display_mode *mode,
-                               struct drm_display_mode *adjusted_mode)
-{
-       int ret = 0;
-       struct drm_device *dev = encoder->dev;
-       struct drm_psb_private *dev_priv = dev->dev_private;
-       struct mdfld_dsi_encoder *dsi_encoder = MDFLD_DSI_ENCODER(encoder);
-       struct mdfld_dsi_dbi_output *dsi_output =
-                                       MDFLD_DSI_DBI_OUTPUT(dsi_encoder);
-       struct mdfld_dsi_config *dsi_config =
-                               mdfld_dsi_encoder_get_config(dsi_encoder);
-       struct mdfld_dsi_connector *dsi_connector = dsi_config->connector;
-       int pipe = dsi_connector->pipe;
-       u8 param = 0;
-
-       /* Regs */
-       u32 mipi_reg = MIPI;
-       u32 dspcntr_reg = DSPACNTR;
-       u32 pipeconf_reg = PIPEACONF;
-       u32 reg_offset = 0;
-
-       /* Values */
-       u32 dspcntr_val = dev_priv->dspcntr;
-       u32 pipeconf_val = dev_priv->pipeconf;
-       u32 h_active_area = mode->hdisplay;
-       u32 v_active_area = mode->vdisplay;
-       u32 mipi_val = (PASS_FROM_SPHY_TO_AFE | SEL_FLOPPED_HSTX |
-                                                       TE_TRIGGER_GPIO_PIN);
-
-       dev_dbg(dev->dev, "mipi_val =0x%x\n", mipi_val);
-
-       dev_dbg(dev->dev, "type %s\n", (pipe == 2) ? "MIPI2" : "MIPI");
-       dev_dbg(dev->dev, "h %d v %d\n", mode->hdisplay, mode->vdisplay);
-
-       if (pipe == 2) {
-               mipi_reg = MIPI_C;
-               dspcntr_reg = DSPCCNTR;
-               pipeconf_reg = PIPECCONF;
-
-               reg_offset = MIPIC_REG_OFFSET;
-
-               dspcntr_val = dev_priv->dspcntr2;
-               pipeconf_val = dev_priv->pipeconf2;
-       } else {
-               mipi_val |= 0x2; /* Two lanes for port A and C respectively */
-       }
-
-       if (!gma_power_begin(dev, true)) {
-               dev_err(dev->dev, "hw begin failed\n");
-               return;
-       }
-
-       /* Set up pipe related registers */
-       REG_WRITE(mipi_reg, mipi_val);
-       REG_READ(mipi_reg);
-
-       pyr_dsi_controller_dbi_init(dsi_config, pipe);
-
-       msleep(20);
-
-       REG_WRITE(dspcntr_reg, dspcntr_val);
-       REG_READ(dspcntr_reg);
-
-       /* 20ms delay before sending exit_sleep_mode */
-       msleep(20);
-
-       /* Send exit_sleep_mode DCS */
-       ret = mdfld_dsi_dbi_send_dcs(dsi_output, exit_sleep_mode, NULL,
-                                               0, CMD_DATA_SRC_SYSTEM_MEM);
-       if (ret) {
-               dev_err(dev->dev, "sent exit_sleep_mode faild\n");
-               goto out_err;
-       }
-
-       /*send set_tear_on DCS*/
-       ret = mdfld_dsi_dbi_send_dcs(dsi_output, set_tear_on,
-                                       &param, 1, CMD_DATA_SRC_SYSTEM_MEM);
-       if (ret) {
-               dev_err(dev->dev, "%s - sent set_tear_on faild\n", __func__);
-               goto out_err;
-       }
-
-       /* Do some init stuff */
-       mdfld_dsi_brightness_init(dsi_config, pipe);
-       mdfld_dsi_gen_fifo_ready(dev, (MIPIA_GEN_FIFO_STAT_REG + reg_offset),
-                               HS_CTRL_FIFO_EMPTY | HS_DATA_FIFO_EMPTY);
-
-       REG_WRITE(pipeconf_reg, pipeconf_val | PIPEACONF_DSR);
-       REG_READ(pipeconf_reg);
-
-       /* TODO: this looks ugly, try to move it to CRTC mode setting */
-       if (pipe == 2)
-               dev_priv->pipeconf2 |= PIPEACONF_DSR;
-       else
-               dev_priv->pipeconf |= PIPEACONF_DSR;
-
-       dev_dbg(dev->dev, "pipeconf %x\n",  REG_READ(pipeconf_reg));
-
-       ret = mdfld_dsi_dbi_update_area(dsi_output, 0, 0,
-                               h_active_area - 1, v_active_area - 1);
-       if (ret) {
-               dev_err(dev->dev, "update area failed\n");
-               goto out_err;
-       }
-
-out_err:
-       gma_power_end(dev);
-
-       if (ret)
-               dev_err(dev->dev, "mode set failed\n");
-       else
-               dev_dbg(dev->dev, "mode set done successfully\n");
-}
-
-static void pyr_dsi_dbi_prepare(struct drm_encoder *encoder)
-{
-       struct mdfld_dsi_encoder *dsi_encoder = MDFLD_DSI_ENCODER(encoder);
-       struct mdfld_dsi_dbi_output *dbi_output =
-                                       MDFLD_DSI_DBI_OUTPUT(dsi_encoder);
-
-       dbi_output->mode_flags |= MODE_SETTING_IN_ENCODER;
-       dbi_output->mode_flags &= ~MODE_SETTING_ENCODER_DONE;
-
-       pyr_dsi_dbi_set_power(encoder, false);
-}
-
-static void pyr_dsi_dbi_commit(struct drm_encoder *encoder)
-{
-       struct mdfld_dsi_encoder *dsi_encoder = MDFLD_DSI_ENCODER(encoder);
-       struct mdfld_dsi_dbi_output *dbi_output =
-                                       MDFLD_DSI_DBI_OUTPUT(dsi_encoder);
-       struct drm_device *dev = dbi_output->dev;
-       struct drm_psb_private *dev_priv = dev->dev_private;
-       struct psb_drm_dpu_rect rect;
-
-       pyr_dsi_dbi_set_power(encoder, true);
-
-       dbi_output->mode_flags &= ~MODE_SETTING_IN_ENCODER;
-
-       rect.x = rect.y = 0;
-       rect.width = 864;
-       rect.height = 480;
-
-       if (dbi_output->channel_num == 1) {
-               dev_priv->dsr_fb_update |= MDFLD_DSR_2D_3D_2;
-               /* If DPU enabled report a fullscreen damage */
-               mdfld_dbi_dpu_report_damage(dev, MDFLD_PLANEC, &rect);
-       } else {
-               dev_priv->dsr_fb_update |= MDFLD_DSR_2D_3D_0;
-               mdfld_dbi_dpu_report_damage(dev, MDFLD_PLANEA, &rect);
-       }
-       dbi_output->mode_flags |= MODE_SETTING_ENCODER_DONE;
-}
-
-static void pyr_dsi_dbi_dpms(struct drm_encoder *encoder, int mode)
-{
-       struct mdfld_dsi_encoder *dsi_encoder = MDFLD_DSI_ENCODER(encoder);
-       struct mdfld_dsi_dbi_output *dbi_output =
-                                       MDFLD_DSI_DBI_OUTPUT(dsi_encoder);
-       struct drm_device *dev = dbi_output->dev;
-
-       dev_dbg(dev->dev, "%s\n",  (mode == DRM_MODE_DPMS_ON ? "on" : "off"));
-
-       if (mode == DRM_MODE_DPMS_ON)
-               pyr_dsi_dbi_set_power(encoder, true);
-       else
-               pyr_dsi_dbi_set_power(encoder, false);
-}
-
-/*
- * Update the DBI MIPI Panel Frame Buffer.
- */
-static void pyr_dsi_dbi_update_fb(struct mdfld_dsi_dbi_output *dbi_output,
-                                                               int pipe)
-{
-       struct mdfld_dsi_pkg_sender *sender =
-               mdfld_dsi_encoder_get_pkg_sender(&dbi_output->base);
-       struct drm_device *dev = dbi_output->dev;
-       struct drm_crtc *crtc = dbi_output->base.base.crtc;
-       struct psb_intel_crtc *psb_crtc = (crtc) ?
-                               to_psb_intel_crtc(crtc) : NULL;
-
-       u32 dpll_reg = MRST_DPLL_A;
-       u32 dspcntr_reg = DSPACNTR;
-       u32 pipeconf_reg = PIPEACONF;
-       u32 dsplinoff_reg = DSPALINOFF;
-       u32 dspsurf_reg = DSPASURF;
-       u32 hs_gen_ctrl_reg = HS_GEN_CTRL_REG;
-       u32 gen_fifo_stat_reg = GEN_FIFO_STAT_REG;
-       u32 reg_offset = 0;
-
-       u32 intr_status;
-       u32 fifo_stat_reg_val;
-       u32 dpll_reg_val;
-       u32 dspcntr_reg_val;
-       u32 pipeconf_reg_val;
-
-       /* If mode setting on-going, back off */
-       if ((dbi_output->mode_flags & MODE_SETTING_ON_GOING) ||
-               (psb_crtc && psb_crtc->mode_flags & MODE_SETTING_ON_GOING) ||
-               !(dbi_output->mode_flags & MODE_SETTING_ENCODER_DONE))
-               return;
-
-       /*
-        * Look for errors here.  In particular we're checking for whatever
-        * error status might have appeared during the last frame transmit
-        * (memory write).
-        *
-        * Normally, the bits we're testing here would be set infrequently,
-        * if at all.  However, one panel (at least) returns at least one
-        * error bit on most frames.  So we've disabled the kernel message
-        * for now.
-        *
-        * Still clear whatever error bits are set, except don't clear the
-        * ones that would make the Penwell DSI controller reset if we
-        * cleared them.
-        */
-       intr_status = REG_READ(INTR_STAT_REG);
-       if ((intr_status & 0x26FFFFFF) != 0) {
-               /* dev_err(dev->dev, "DSI status: 0x%08X\n", intr_status); */
-               intr_status &= 0x26F3FFFF;
-               REG_WRITE(INTR_STAT_REG, intr_status);
-       }
-
-       if (pipe == 2) {
-               dspcntr_reg = DSPCCNTR;
-               pipeconf_reg = PIPECCONF;
-               dsplinoff_reg = DSPCLINOFF;
-               dspsurf_reg = DSPCSURF;
-
-               hs_gen_ctrl_reg = HS_GEN_CTRL_REG + MIPIC_REG_OFFSET;
-               gen_fifo_stat_reg = GEN_FIFO_STAT_REG + MIPIC_REG_OFFSET,
-
-               reg_offset = MIPIC_REG_OFFSET;
-       }
-
-       if (!gma_power_begin(dev, true)) {
-               dev_err(dev->dev, "hw begin failed\n");
-               return;
-       }
-
-       fifo_stat_reg_val = REG_READ(MIPIA_GEN_FIFO_STAT_REG + reg_offset);
-       dpll_reg_val = REG_READ(dpll_reg);
-       dspcntr_reg_val = REG_READ(dspcntr_reg);
-       pipeconf_reg_val = REG_READ(pipeconf_reg);
-
-       if (!(fifo_stat_reg_val & (1 << 27)) ||
-               (dpll_reg_val & DPLL_VCO_ENABLE) ||
-               !(dspcntr_reg_val & DISPLAY_PLANE_ENABLE) ||
-               !(pipeconf_reg_val & DISPLAY_PLANE_ENABLE)) {
-               goto update_fb_out0;
-       }
-
-       /* Refresh plane changes */
-       REG_WRITE(dsplinoff_reg, REG_READ(dsplinoff_reg));
-       REG_WRITE(dspsurf_reg, REG_READ(dspsurf_reg));
-       REG_READ(dspsurf_reg);
-
-       mdfld_dsi_send_dcs(sender,
-                          write_mem_start,
-                          NULL,
-                          0,
-                          CMD_DATA_SRC_PIPE,
-                          MDFLD_DSI_SEND_PACKAGE);
-
-       /*
-        * The idea here is to transmit a Generic Read command after the
-        * Write Memory Start/Continue commands finish.  This asks for
-        * the panel to return an "ACK No Errors," or (if it has errors
-        * to report) an Error Report.  This allows us to monitor the
-        * panel's perception of the health of the DSI.
-        */
-       mdfld_dsi_gen_fifo_ready(dev, gen_fifo_stat_reg,
-                               HS_CTRL_FIFO_EMPTY | HS_DATA_FIFO_EMPTY);
-       REG_WRITE(hs_gen_ctrl_reg, (1 << WORD_COUNTS_POS) | GEN_READ_0);
-
-       dbi_output->dsr_fb_update_done = true;
-update_fb_out0:
-       gma_power_end(dev);
-}
-
-/*
- * TODO: will be removed later, should work out display interfaces for power
- */
-void pyr_dsi_adapter_init(struct mdfld_dsi_config *dsi_config, int pipe)
-{
-       if (!dsi_config || (pipe != 0 && pipe != 2)) {
-               WARN_ON(1);
-               return;
-       }
-       pyr_dsi_controller_dbi_init(dsi_config, pipe);
-}
-
-static int pyr_cmd_get_panel_info(struct drm_device *dev, int pipe,
-                                                       struct panel_info *pi)
-{
-       if (!dev || !pi)
-               return -EINVAL;
-
-       pi->width_mm = PYR_PANEL_WIDTH;
-       pi->height_mm = PYR_PANEL_HEIGHT;
-
-       return 0;
-}
-
-/* PYR DBI encoder helper funcs */
-static const struct drm_encoder_helper_funcs pyr_dsi_dbi_helper_funcs = {
-       .dpms = pyr_dsi_dbi_dpms,
-       .mode_fixup = pyr_dsi_dbi_mode_fixup,
-       .prepare = pyr_dsi_dbi_prepare,
-       .mode_set = pyr_dsi_dbi_mode_set,
-       .commit = pyr_dsi_dbi_commit,
-};
-
-/* PYR DBI encoder funcs */
-static const struct drm_encoder_funcs mdfld_dsi_dbi_encoder_funcs = {
-       .destroy = drm_encoder_cleanup,
-};
-
-void pyr_cmd_init(struct drm_device *dev, struct panel_funcs *p_funcs)
-{
-       p_funcs->encoder_funcs = &mdfld_dsi_dbi_encoder_funcs;
-       p_funcs->encoder_helper_funcs = &pyr_dsi_dbi_helper_funcs;
-       p_funcs->get_config_mode = &pyr_cmd_get_config_mode;
-       p_funcs->update_fb = pyr_dsi_dbi_update_fb;
-       p_funcs->get_panel_info = pyr_cmd_get_panel_info;
-}
diff --git a/drivers/staging/gma500/mdfld_tmd_vid.c b/drivers/staging/gma500/mdfld_tmd_vid.c
deleted file mode 100644 (file)
index affdc09..0000000
+++ /dev/null
@@ -1,206 +0,0 @@
-/*
- * Copyright Â© 2010 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Authors:
- * Jim Liu <jim.liu@intel.com>
- * Jackie Li<yaodong.li@intel.com>
- * Gideon Eaton <eaton.
- * Scott Rowe <scott.m.rowe@intel.com>
- */
-
-#include "mdfld_dsi_dbi.h"
-#include "mdfld_dsi_dpi.h"
-#include "mdfld_dsi_output.h"
-#include "mdfld_output.h"
-
-#include "mdfld_dsi_pkg_sender.h"
-
-#include "displays/tmd_vid.h"
-
-/* FIXME: static ? */
-struct drm_display_mode *tmd_vid_get_config_mode(struct drm_device *dev)
-{
-       struct drm_display_mode *mode;
-       struct drm_psb_private *dev_priv = dev->dev_private;
-       struct mrst_timing_info *ti = &dev_priv->gct_data.DTD;
-       bool use_gct = false; /*Disable GCT for now*/
-
-       mode = kzalloc(sizeof(*mode), GFP_KERNEL);
-       if (!mode) {
-               dev_err(dev->dev, "Out of memory\n");
-               return NULL;
-       }
-
-       if (use_gct) {
-               dev_dbg(dev->dev, "gct find MIPI panel.\n");
-
-               mode->hdisplay = (ti->hactive_hi << 8) | ti->hactive_lo;
-               mode->vdisplay = (ti->vactive_hi << 8) | ti->vactive_lo;
-               mode->hsync_start = mode->hdisplay +
-                               ((ti->hsync_offset_hi << 8) |
-                               ti->hsync_offset_lo);
-               mode->hsync_end = mode->hsync_start +
-                               ((ti->hsync_pulse_width_hi << 8) |
-                               ti->hsync_pulse_width_lo);
-               mode->htotal = mode->hdisplay + ((ti->hblank_hi << 8) |
-                                                               ti->hblank_lo);
-               mode->vsync_start = \
-                       mode->vdisplay + ((ti->vsync_offset_hi << 8) |
-                                               ti->vsync_offset_lo);
-               mode->vsync_end = \
-                       mode->vsync_start + ((ti->vsync_pulse_width_hi << 8) | \
-                                               ti->vsync_pulse_width_lo);
-               mode->vtotal = mode->vdisplay +
-                               ((ti->vblank_hi << 8) | ti->vblank_lo);
-               mode->clock = ti->pixel_clock * 10;
-
-               dev_dbg(dev->dev, "hdisplay is %d\n", mode->hdisplay);
-               dev_dbg(dev->dev, "vdisplay is %d\n", mode->vdisplay);
-               dev_dbg(dev->dev, "HSS is %d\n", mode->hsync_start);
-               dev_dbg(dev->dev, "HSE is %d\n", mode->hsync_end);
-               dev_dbg(dev->dev, "htotal is %d\n", mode->htotal);
-               dev_dbg(dev->dev, "VSS is %d\n", mode->vsync_start);
-               dev_dbg(dev->dev, "VSE is %d\n", mode->vsync_end);
-               dev_dbg(dev->dev, "vtotal is %d\n", mode->vtotal);
-               dev_dbg(dev->dev, "clock is %d\n", mode->clock);
-       } else {
-               mode->hdisplay = 480;
-               mode->vdisplay = 854;
-               mode->hsync_start = 487;
-               mode->hsync_end = 490;
-               mode->htotal = 499;
-               mode->vsync_start = 861;
-               mode->vsync_end = 865;
-               mode->vtotal = 873;
-               mode->clock = 33264;
-       }
-       drm_mode_set_name(mode);
-       drm_mode_set_crtcinfo(mode, 0);
-
-       mode->type |= DRM_MODE_TYPE_PREFERRED;
-
-       return mode;
-}
-
-static int tmd_vid_get_panel_info(struct drm_device *dev,
-                               int pipe,
-                               struct panel_info *pi)
-{
-       if (!dev || !pi)
-               return -EINVAL;
-
-       pi->width_mm = TMD_PANEL_WIDTH;
-       pi->height_mm = TMD_PANEL_HEIGHT;
-
-       return 0;
-}
-
-/*
- *     mdfld_init_TMD_MIPI     -       initialise a TMD interface
- *     @dsi_config: configuration
- *     @pipe: pipe to configure
- *
- *     This function is called only by mrst_dsi_mode_set and
- *     restore_display_registers.  since this function does not
- *     acquire the mutex, it is important that the calling function
- *     does!
- */
-
-
-static void mdfld_dsi_tmd_drv_ic_init(struct mdfld_dsi_config *dsi_config,
-                                     int pipe)
-{
-       static u32 tmd_cmd_mcap_off[] = {0x000000b2};
-       static u32 tmd_cmd_enable_lane_switch[] = {0x000101ef};
-       static u32 tmd_cmd_set_lane_num[] = {0x006360ef};
-       static u32 tmd_cmd_pushing_clock0[] = {0x00cc2fef};
-       static u32 tmd_cmd_pushing_clock1[] = {0x00dd6eef};
-       static u32 tmd_cmd_set_mode[] = {0x000000b3};
-       static u32 tmd_cmd_set_sync_pulse_mode[] = {0x000961ef};
-       static u32 tmd_cmd_set_column[] = {0x0100002a, 0x000000df};
-       static u32 tmd_cmd_set_page[] = {0x0300002b, 0x00000055};
-       static u32 tmd_cmd_set_video_mode[] = {0x00000153};
-       /*no auto_bl,need add in furture*/
-       static u32 tmd_cmd_enable_backlight[] = {0x00005ab4};
-       static u32 tmd_cmd_set_backlight_dimming[] = {0x00000ebd};
-
-       struct mdfld_dsi_pkg_sender *sender
-                       = mdfld_dsi_get_pkg_sender(dsi_config);
-
-       DRM_INFO("Enter mdfld init TMD MIPI display.\n");
-
-       if (!sender) {
-               DRM_ERROR("Cannot get sender\n");
-               return;
-       }
-
-       if (dsi_config->dvr_ic_inited)
-               return;
-
-       msleep(3);
-
-       mdfld_dsi_send_gen_long_lp(sender, tmd_cmd_mcap_off, 1, 0);
-       mdfld_dsi_send_gen_long_lp(sender, tmd_cmd_enable_lane_switch, 1, 0);
-       mdfld_dsi_send_gen_long_lp(sender, tmd_cmd_set_lane_num, 1, 0);
-       mdfld_dsi_send_gen_long_lp(sender, tmd_cmd_pushing_clock0, 1, 0);
-       mdfld_dsi_send_gen_long_lp(sender, tmd_cmd_pushing_clock1, 1, 0);
-       mdfld_dsi_send_gen_long_lp(sender, tmd_cmd_set_mode, 1, 0);
-       mdfld_dsi_send_gen_long_lp(sender, tmd_cmd_set_sync_pulse_mode, 1, 0);
-       mdfld_dsi_send_mcs_long_lp(sender, tmd_cmd_set_column, 2, 0);
-       mdfld_dsi_send_mcs_long_lp(sender, tmd_cmd_set_page, 2, 0);
-       mdfld_dsi_send_gen_long_lp(sender, tmd_cmd_set_video_mode, 1, 0);
-       mdfld_dsi_send_gen_long_lp(sender, tmd_cmd_enable_backlight, 1, 0);
-       mdfld_dsi_send_gen_long_lp(sender, tmd_cmd_set_backlight_dimming, 1, 0);
-
-       dsi_config->dvr_ic_inited = 1;
-}
-
-/* TMD DPI encoder helper funcs */
-static const struct drm_encoder_helper_funcs
-                                       mdfld_tpo_dpi_encoder_helper_funcs = {
-       .dpms = mdfld_dsi_dpi_dpms,
-       .mode_fixup = mdfld_dsi_dpi_mode_fixup,
-       .prepare = mdfld_dsi_dpi_prepare,
-       .mode_set = mdfld_dsi_dpi_mode_set,
-       .commit = mdfld_dsi_dpi_commit,
-};
-
-/* TMD DPI encoder funcs */
-static const struct drm_encoder_funcs mdfld_tpo_dpi_encoder_funcs = {
-       .destroy = drm_encoder_cleanup,
-};
-
-void tmd_vid_init(struct drm_device *dev, struct panel_funcs *p_funcs)
-{
-       if (!dev || !p_funcs) {
-               dev_err(dev->dev, "Invalid parameters\n");
-               return;
-       }
-
-       p_funcs->encoder_funcs = &mdfld_tpo_dpi_encoder_funcs;
-       p_funcs->encoder_helper_funcs = &mdfld_tpo_dpi_encoder_helper_funcs;
-       p_funcs->get_config_mode = &tmd_vid_get_config_mode;
-       p_funcs->update_fb = NULL;
-       p_funcs->get_panel_info = tmd_vid_get_panel_info;
-       p_funcs->reset = mdfld_dsi_panel_reset;
-       p_funcs->drv_ic_init = mdfld_dsi_tmd_drv_ic_init;
-}
diff --git a/drivers/staging/gma500/mdfld_tpo_cmd.c b/drivers/staging/gma500/mdfld_tpo_cmd.c
deleted file mode 100644 (file)
index c7f7c9c..0000000
+++ /dev/null
@@ -1,509 +0,0 @@
-/*
- * Copyright (c)  2010 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicensen
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Authors:
- * Thomas Eaton <thomas.g.eaton@intel.com>
- * Scott Rowe <scott.m.rowe@intel.com>
- */
-
-#include "mdfld_dsi_dbi.h"
-#include "mdfld_dsi_dpi.h"
-#include "mdfld_dsi_output.h"
-#include "mdfld_output.h"
-#include "mdfld_dsi_dbi_dpu.h"
-#include "mdfld_dsi_pkg_sender.h"
-
-#include "displays/tpo_cmd.h"
-
-static struct drm_display_mode *tpo_cmd_get_config_mode(struct drm_device *dev)
-{
-       struct drm_display_mode *mode;
-       struct drm_psb_private *dev_priv = dev->dev_private;
-       struct mrst_timing_info *ti = &dev_priv->gct_data.DTD;
-       bool use_gct = false;
-
-       mode = kzalloc(sizeof(*mode), GFP_KERNEL);
-       if (!mode)
-               return NULL;
-
-       if (use_gct) {
-               dev_dbg(dev->dev, "gct find MIPI panel.\n");
-
-               mode->hdisplay = (ti->hactive_hi << 8) | ti->hactive_lo;
-               mode->vdisplay = (ti->vactive_hi << 8) | ti->vactive_lo;
-               mode->hsync_start = mode->hdisplay + \
-                               ((ti->hsync_offset_hi << 8) | \
-                               ti->hsync_offset_lo);
-               mode->hsync_end = mode->hsync_start + \
-                               ((ti->hsync_pulse_width_hi << 8) | \
-                               ti->hsync_pulse_width_lo);
-               mode->htotal = mode->hdisplay + ((ti->hblank_hi << 8) | \
-                                                               ti->hblank_lo);
-               mode->vsync_start = \
-                       mode->vdisplay + ((ti->vsync_offset_hi << 8) | \
-                                               ti->vsync_offset_lo);
-               mode->vsync_end = \
-                       mode->vsync_start + ((ti->vsync_pulse_width_hi << 8) | \
-                                               ti->vsync_pulse_width_lo);
-               mode->vtotal = mode->vdisplay + \
-                               ((ti->vblank_hi << 8) | ti->vblank_lo);
-               mode->clock = ti->pixel_clock * 10;
-
-               dev_dbg(dev->dev, "hdisplay is %d\n", mode->hdisplay);
-               dev_dbg(dev->dev, "vdisplay is %d\n", mode->vdisplay);
-               dev_dbg(dev->dev, "HSS is %d\n", mode->hsync_start);
-               dev_dbg(dev->dev, "HSE is %d\n", mode->hsync_end);
-               dev_dbg(dev->dev, "htotal is %d\n", mode->htotal);
-               dev_dbg(dev->dev, "VSS is %d\n", mode->vsync_start);
-               dev_dbg(dev->dev, "VSE is %d\n", mode->vsync_end);
-               dev_dbg(dev->dev, "vtotal is %d\n", mode->vtotal);
-               dev_dbg(dev->dev, "clock is %d\n", mode->clock);
-       } else {
-               mode->hdisplay = 864;
-               mode->vdisplay = 480;
-               mode->hsync_start = 872;
-               mode->hsync_end = 876;
-               mode->htotal = 884;
-               mode->vsync_start = 482;
-               mode->vsync_end = 494;
-               mode->vtotal = 486;
-               mode->clock = 25777;
-       }
-
-       drm_mode_set_name(mode);
-       drm_mode_set_crtcinfo(mode, 0);
-
-       mode->type |= DRM_MODE_TYPE_PREFERRED;
-
-       return mode;
-}
-
-static bool mdfld_dsi_dbi_mode_fixup(struct drm_encoder *encoder,
-                                    struct drm_display_mode *mode,
-                                    struct drm_display_mode *adjusted_mode)
-{
-       struct drm_device *dev = encoder->dev;
-       struct drm_display_mode *fixed_mode = tpo_cmd_get_config_mode(dev);
-
-       if (fixed_mode) {
-               adjusted_mode->hdisplay = fixed_mode->hdisplay;
-               adjusted_mode->hsync_start = fixed_mode->hsync_start;
-               adjusted_mode->hsync_end = fixed_mode->hsync_end;
-               adjusted_mode->htotal = fixed_mode->htotal;
-               adjusted_mode->vdisplay = fixed_mode->vdisplay;
-               adjusted_mode->vsync_start = fixed_mode->vsync_start;
-               adjusted_mode->vsync_end = fixed_mode->vsync_end;
-               adjusted_mode->vtotal = fixed_mode->vtotal;
-               adjusted_mode->clock = fixed_mode->clock;
-               drm_mode_set_crtcinfo(adjusted_mode, CRTC_INTERLACE_HALVE_V);
-               kfree(fixed_mode);
-       }
-       return true;
-}
-
-static void mdfld_dsi_dbi_set_power(struct drm_encoder *encoder, bool on)
-{
-       int ret = 0;
-       struct mdfld_dsi_encoder *dsi_encoder = MDFLD_DSI_ENCODER(encoder);
-       struct mdfld_dsi_dbi_output *dbi_output =
-                               MDFLD_DSI_DBI_OUTPUT(dsi_encoder);
-       struct mdfld_dsi_config *dsi_config =
-               mdfld_dsi_encoder_get_config(dsi_encoder);
-       struct mdfld_dsi_pkg_sender *sender =
-               mdfld_dsi_encoder_get_pkg_sender(dsi_encoder);
-       struct drm_device *dev = encoder->dev;
-       struct drm_psb_private *dev_priv = dev->dev_private;
-       u32 reg_offset = 0;
-       int pipe = (dbi_output->channel_num == 0) ? 0 : 2;
-       u32 data = 0;
-
-       dev_dbg(dev->dev, "pipe %d : %s, panel on: %s\n",
-                       pipe, on ? "On" : "Off",
-                       dbi_output->dbi_panel_on ? "True" : "False");
-
-       if (pipe == 2) {
-               if (on)
-                       dev_priv->dual_mipi = true;
-               else
-                       dev_priv->dual_mipi = false;
-               reg_offset = MIPIC_REG_OFFSET;
-       } else {
-               if (!on)
-                       dev_priv->dual_mipi = false;
-       }
-
-       if (!gma_power_begin(dev, true)) {
-               dev_err(dev->dev, "hw begin failed\n");
-               return;
-       }
-
-       if (on) {
-               if (dbi_output->dbi_panel_on)
-                       goto out_err;
-
-               ret = mdfld_dsi_dbi_update_power(dbi_output, DRM_MODE_DPMS_ON);
-               if (ret) {
-                       dev_err(dev->dev, "power on error\n");
-                       goto out_err;
-               }
-
-               dbi_output->dbi_panel_on = true;
-
-               if (pipe == 2)
-                       dev_priv->dbi_panel_on2 = true;
-               else
-                       dev_priv->dbi_panel_on = true;
-               mdfld_enable_te(dev, pipe);
-       } else {
-               if (!dbi_output->dbi_panel_on && !dbi_output->first_boot)
-                       goto out_err;
-
-               dbi_output->dbi_panel_on = false;
-               dbi_output->first_boot = false;
-
-               if (pipe == 2)
-                       dev_priv->dbi_panel_on2 = false;
-               else
-                       dev_priv->dbi_panel_on = false;
-
-               mdfld_disable_te(dev, pipe);
-
-               ret = mdfld_dsi_dbi_update_power(dbi_output, DRM_MODE_DPMS_OFF);
-               if (ret) {
-                       dev_err(dev->dev, "power on error\n");
-                       goto out_err;
-               }
-       }
-
-       /*
-        * FIXME: this is a WA for TPO panel crash on DPMS on & off around
-        * 83 times. the root cause of this issue is that Booster in
-        * drvIC crashed. Add this WA so that we can resume the driver IC
-        * once we found that booster has a fault
-        */
-       mdfld_dsi_get_power_mode(dsi_config,
-                               &data,
-                               MDFLD_DSI_HS_TRANSMISSION);
-
-       if (on && data && !(data & (1 << 7))) {
-               /* Soft reset */
-               mdfld_dsi_send_dcs(sender,
-                                  DCS_SOFT_RESET,
-                                  NULL,
-                                  0,
-                                  CMD_DATA_SRC_PIPE,
-                                  MDFLD_DSI_SEND_PACKAGE);
-
-               /* Init drvIC */
-               if (dbi_output->p_funcs->drv_ic_init)
-                       dbi_output->p_funcs->drv_ic_init(dsi_config,
-                                                        pipe);
-       }
-out_err:
-       gma_power_end(dev);
-       if (ret)
-               dev_err(dev->dev, "failed\n");
-}
-
-
-static void mdfld_dsi_dbi_mode_set(struct drm_encoder *encoder,
-                                  struct drm_display_mode *mode,
-                                  struct drm_display_mode *adjusted_mode)
-{
-       int ret = 0;
-       struct drm_device *dev = encoder->dev;
-       struct drm_psb_private *dev_priv = dev->dev_private;
-       struct mdfld_dsi_encoder *dsi_encoder = MDFLD_DSI_ENCODER(encoder);
-       struct mdfld_dsi_dbi_output *dsi_output =
-                                       MDFLD_DSI_DBI_OUTPUT(dsi_encoder);
-       struct mdfld_dsi_config *dsi_config =
-                               mdfld_dsi_encoder_get_config(dsi_encoder);
-       struct mdfld_dsi_connector *dsi_connector = dsi_config->connector;
-       int pipe = dsi_connector->pipe;
-       u8 param = 0;
-
-       /* Regs */
-       u32 mipi_reg = MIPI;
-       u32 dspcntr_reg = DSPACNTR;
-       u32 pipeconf_reg = PIPEACONF;
-       u32 reg_offset = 0;
-
-       /* Values */
-       u32 dspcntr_val = dev_priv->dspcntr;
-       u32 pipeconf_val = dev_priv->pipeconf;
-       u32 h_active_area = mode->hdisplay;
-       u32 v_active_area = mode->vdisplay;
-       u32 mipi_val;
-
-       mipi_val = (PASS_FROM_SPHY_TO_AFE | SEL_FLOPPED_HSTX |
-                                               TE_TRIGGER_GPIO_PIN);
-
-       dev_dbg(dev->dev, "mipi_val =0x%x\n", mipi_val);
-
-       dev_dbg(dev->dev, "type %s\n", (pipe == 2) ? "MIPI2" : "MIPI");
-       dev_dbg(dev->dev, "h %d v %d\n", mode->hdisplay, mode->vdisplay);
-
-       if (pipe == 2) {
-               mipi_reg = MIPI_C;
-               dspcntr_reg = DSPCCNTR;
-               pipeconf_reg = PIPECCONF;
-
-               reg_offset = MIPIC_REG_OFFSET;
-
-               dspcntr_val = dev_priv->dspcntr2;
-               pipeconf_val = dev_priv->pipeconf2;
-       } else {
-               mipi_val |= 0x2; /*two lanes for port A and C respectively*/
-       }
-
-       if (!gma_power_begin(dev, true)) {
-               dev_err(dev->dev, "hw begin failed\n");
-               return;
-       }
-
-       REG_WRITE(dspcntr_reg, dspcntr_val);
-       REG_READ(dspcntr_reg);
-
-       /* 20ms delay before sending exit_sleep_mode */
-       msleep(20);
-
-       /* Send exit_sleep_mode DCS */
-       ret = mdfld_dsi_dbi_send_dcs(dsi_output, DCS_EXIT_SLEEP_MODE,
-                                       NULL, 0, CMD_DATA_SRC_SYSTEM_MEM);
-       if (ret) {
-               dev_err(dev->dev, "sent exit_sleep_mode faild\n");
-               goto out_err;
-       }
-
-       /* Send set_tear_on DCS */
-       ret = mdfld_dsi_dbi_send_dcs(dsi_output, DCS_SET_TEAR_ON,
-                                       &param, 1, CMD_DATA_SRC_SYSTEM_MEM);
-       if (ret) {
-               dev_err(dev->dev, "%s - sent set_tear_on faild\n", __func__);
-               goto out_err;
-       }
-
-       /* Do some init stuff */
-       REG_WRITE(pipeconf_reg, pipeconf_val | PIPEACONF_DSR);
-       REG_READ(pipeconf_reg);
-
-       /* TODO: this looks ugly, try to move it to CRTC mode setting*/
-       if (pipe == 2)
-               dev_priv->pipeconf2 |= PIPEACONF_DSR;
-       else
-               dev_priv->pipeconf |= PIPEACONF_DSR;
-
-       dev_dbg(dev->dev, "pipeconf %x\n",  REG_READ(pipeconf_reg));
-
-       ret = mdfld_dsi_dbi_update_area(dsi_output, 0, 0,
-                               h_active_area - 1, v_active_area - 1);
-       if (ret) {
-               dev_err(dev->dev, "update area failed\n");
-               goto out_err;
-       }
-
-out_err:
-       gma_power_end(dev);
-
-       if (ret)
-               dev_err(dev->dev, "mode set failed\n");
-}
-
-static void mdfld_dsi_dbi_prepare(struct drm_encoder *encoder)
-{
-       struct mdfld_dsi_encoder *dsi_encoder = MDFLD_DSI_ENCODER(encoder);
-       struct mdfld_dsi_dbi_output *dbi_output
-                               = MDFLD_DSI_DBI_OUTPUT(dsi_encoder);
-
-       dbi_output->mode_flags |= MODE_SETTING_IN_ENCODER;
-       dbi_output->mode_flags &= ~MODE_SETTING_ENCODER_DONE;
-
-       mdfld_dsi_dbi_set_power(encoder, false);
-}
-
-static void mdfld_dsi_dbi_commit(struct drm_encoder *encoder)
-{
-       struct mdfld_dsi_encoder *dsi_encoder = MDFLD_DSI_ENCODER(encoder);
-       struct mdfld_dsi_dbi_output *dbi_output =
-                                       MDFLD_DSI_DBI_OUTPUT(dsi_encoder);
-       struct drm_device *dev = dbi_output->dev;
-       struct drm_psb_private *dev_priv = dev->dev_private;
-       struct psb_drm_dpu_rect rect;
-
-       mdfld_dsi_dbi_set_power(encoder, true);
-       dbi_output->mode_flags &= ~MODE_SETTING_IN_ENCODER;
-
-       rect.x = rect.y = 0;
-       rect.width = 864;
-       rect.height = 480;
-
-       if (dbi_output->channel_num == 1) {
-               dev_priv->dsr_fb_update |= MDFLD_DSR_2D_3D_2;
-               /*if dpu enabled report a fullscreen damage*/
-               mdfld_dbi_dpu_report_damage(dev, MDFLD_PLANEC, &rect);
-       } else {
-               dev_priv->dsr_fb_update |= MDFLD_DSR_2D_3D_0;
-               mdfld_dbi_dpu_report_damage(dev, MDFLD_PLANEA, &rect);
-       }
-       dbi_output->mode_flags |= MODE_SETTING_ENCODER_DONE;
-}
-
-static void mdfld_dsi_dbi_dpms(struct drm_encoder *encoder, int mode)
-{
-       struct mdfld_dsi_encoder *dsi_encoder = MDFLD_DSI_ENCODER(encoder);
-       struct mdfld_dsi_dbi_output *dbi_output
-                               = MDFLD_DSI_DBI_OUTPUT(dsi_encoder);
-       struct drm_device *dev = dbi_output->dev;
-       struct drm_psb_private *dev_priv = dev->dev_private;
-       static bool bdispoff;
-
-       dev_dbg(dev->dev, "%s\n", (mode == DRM_MODE_DPMS_ON ? "on" : "off"));
-
-       if (mode == DRM_MODE_DPMS_ON) {
-               /*
-                * FIXME: in case I am wrong!
-                * we don't need to exit dsr here to wake up plane/pipe/pll
-                * if everything goes right, hw_begin will resume them all
-                * during set_power.
-                */
-               if (bdispoff /* FIXME && gbgfxsuspended */) {
-                       mdfld_dsi_dbi_exit_dsr(dev, MDFLD_DSR_2D_3D);
-                       bdispoff = false;
-                       dev_priv->dispstatus = true;
-               }
-
-               mdfld_dsi_dbi_set_power(encoder, true);
-               /* FIXME if (gbgfxsuspended)
-                       gbgfxsuspended = false; */
-       } else {
-               /*
-                * I am not sure whether this is the perfect place to
-                * turn rpm on since we still have a lot of CRTC turnning
-                * on work to do.
-                */
-               bdispoff = true;
-               dev_priv->dispstatus = false;
-               mdfld_dsi_dbi_set_power(encoder, false);
-       }
-}
-
-
-/*
- * Update the DBI MIPI Panel Frame Buffer.
- */
-static void mdfld_dsi_dbi_update_fb(struct mdfld_dsi_dbi_output *dbi_output,
-                                                               int pipe)
-{
-       struct mdfld_dsi_pkg_sender *sender =
-               mdfld_dsi_encoder_get_pkg_sender(&dbi_output->base);
-       struct drm_device *dev = dbi_output->dev;
-       struct drm_crtc *crtc = dbi_output->base.base.crtc;
-       struct psb_intel_crtc *psb_crtc = (crtc) ?
-                                       to_psb_intel_crtc(crtc) : NULL;
-       u32 dpll_reg = MRST_DPLL_A;
-       u32 dspcntr_reg = DSPACNTR;
-       u32 pipeconf_reg = PIPEACONF;
-       u32 dsplinoff_reg = DSPALINOFF;
-       u32 dspsurf_reg = DSPASURF;
-       u32 reg_offset = 0;
-
-       /* If mode setting on-going, back off */
-       if ((dbi_output->mode_flags & MODE_SETTING_ON_GOING) ||
-               (psb_crtc && psb_crtc->mode_flags & MODE_SETTING_ON_GOING) ||
-               !(dbi_output->mode_flags & MODE_SETTING_ENCODER_DONE))
-               return;
-
-       if (pipe == 2) {
-               dspcntr_reg = DSPCCNTR;
-               pipeconf_reg = PIPECCONF;
-               dsplinoff_reg = DSPCLINOFF;
-               dspsurf_reg = DSPCSURF;
-               reg_offset = MIPIC_REG_OFFSET;
-       }
-
-       if (!gma_power_begin(dev, true)) {
-               dev_err(dev->dev, "hw begin failed\n");
-               return;
-       }
-
-       /* Check DBI FIFO status */
-       if (!(REG_READ(dpll_reg) & DPLL_VCO_ENABLE) ||
-          !(REG_READ(dspcntr_reg) & DISPLAY_PLANE_ENABLE) ||
-          !(REG_READ(pipeconf_reg) & DISPLAY_PLANE_ENABLE))
-               goto update_fb_out0;
-
-       /* Refresh plane changes */
-       REG_WRITE(dsplinoff_reg, REG_READ(dsplinoff_reg));
-       REG_WRITE(dspsurf_reg, REG_READ(dspsurf_reg));
-       REG_READ(dspsurf_reg);
-
-       mdfld_dsi_send_dcs(sender,
-                          DCS_WRITE_MEM_START,
-                          NULL,
-                          0,
-                          CMD_DATA_SRC_PIPE,
-                          MDFLD_DSI_SEND_PACKAGE);
-
-       dbi_output->dsr_fb_update_done = true;
-update_fb_out0:
-       gma_power_end(dev);
-}
-
-static int tpo_cmd_get_panel_info(struct drm_device *dev,
-                               int pipe,
-                               struct panel_info *pi)
-{
-       if (!dev || !pi)
-               return -EINVAL;
-
-       pi->width_mm = TPO_PANEL_WIDTH;
-       pi->height_mm = TPO_PANEL_HEIGHT;
-
-       return 0;
-}
-
-
-/* TPO DBI encoder helper funcs */
-static const struct drm_encoder_helper_funcs mdfld_dsi_dbi_helper_funcs = {
-       .dpms = mdfld_dsi_dbi_dpms,
-       .mode_fixup = mdfld_dsi_dbi_mode_fixup,
-       .prepare = mdfld_dsi_dbi_prepare,
-       .mode_set = mdfld_dsi_dbi_mode_set,
-       .commit = mdfld_dsi_dbi_commit,
-};
-
-/* TPO DBI encoder funcs */
-static const struct drm_encoder_funcs mdfld_dsi_dbi_encoder_funcs = {
-       .destroy = drm_encoder_cleanup,
-};
-
-void tpo_cmd_init(struct drm_device *dev, struct panel_funcs *p_funcs)
-{
-       p_funcs->encoder_funcs = &mdfld_dsi_dbi_encoder_funcs;
-       p_funcs->encoder_helper_funcs = &mdfld_dsi_dbi_helper_funcs;
-       p_funcs->get_config_mode = &tpo_cmd_get_config_mode;
-       p_funcs->update_fb = mdfld_dsi_dbi_update_fb;
-       p_funcs->get_panel_info = tpo_cmd_get_panel_info;
-       p_funcs->reset = mdfld_dsi_panel_reset;
-       p_funcs->drv_ic_init = mdfld_dsi_brightness_init;
-}
diff --git a/drivers/staging/gma500/mdfld_tpo_vid.c b/drivers/staging/gma500/mdfld_tpo_vid.c
deleted file mode 100644 (file)
index 9549017..0000000
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- * Copyright Â© 2010 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Authors:
- * jim liu <jim.liu@intel.com>
- * Jackie Li<yaodong.li@intel.com>
- */
-
-#include "mdfld_dsi_dbi.h"
-#include "mdfld_dsi_dpi.h"
-#include "mdfld_dsi_output.h"
-#include "mdfld_output.h"
-
-#include "mdfld_dsi_pkg_sender.h"
-
-#include "displays/tpo_vid.h"
-
-static struct drm_display_mode *tpo_vid_get_config_mode(struct drm_device *dev)
-{
-       struct drm_display_mode *mode;
-       struct drm_psb_private *dev_priv = dev->dev_private;
-       struct mrst_timing_info *ti = &dev_priv->gct_data.DTD;
-       bool use_gct = false;
-
-       mode = kzalloc(sizeof(*mode), GFP_KERNEL);
-       if (!mode) {
-               dev_err(dev->dev, "out of memory\n");
-               return NULL;
-       }
-
-       if (use_gct) {
-               mode->hdisplay = (ti->hactive_hi << 8) | ti->hactive_lo;
-               mode->vdisplay = (ti->vactive_hi << 8) | ti->vactive_lo;
-               mode->hsync_start = mode->hdisplay + \
-                               ((ti->hsync_offset_hi << 8) | \
-                               ti->hsync_offset_lo);
-               mode->hsync_end = mode->hsync_start + \
-                               ((ti->hsync_pulse_width_hi << 8) | \
-                               ti->hsync_pulse_width_lo);
-               mode->htotal = mode->hdisplay + ((ti->hblank_hi << 8) | \
-                                                               ti->hblank_lo);
-               mode->vsync_start = \
-                       mode->vdisplay + ((ti->vsync_offset_hi << 8) | \
-                                               ti->vsync_offset_lo);
-               mode->vsync_end = \
-                       mode->vsync_start + ((ti->vsync_pulse_width_hi << 8) | \
-                                               ti->vsync_pulse_width_lo);
-               mode->vtotal = mode->vdisplay + \
-                               ((ti->vblank_hi << 8) | ti->vblank_lo);
-               mode->clock = ti->pixel_clock * 10;
-
-               dev_dbg(dev->dev, "hdisplay is %d\n", mode->hdisplay);
-               dev_dbg(dev->dev, "vdisplay is %d\n", mode->vdisplay);
-               dev_dbg(dev->dev, "HSS is %d\n", mode->hsync_start);
-               dev_dbg(dev->dev, "HSE is %d\n", mode->hsync_end);
-               dev_dbg(dev->dev, "htotal is %d\n", mode->htotal);
-               dev_dbg(dev->dev, "VSS is %d\n", mode->vsync_start);
-               dev_dbg(dev->dev, "VSE is %d\n", mode->vsync_end);
-               dev_dbg(dev->dev, "vtotal is %d\n", mode->vtotal);
-               dev_dbg(dev->dev, "clock is %d\n", mode->clock);
-       } else {
-               mode->hdisplay = 864;
-               mode->vdisplay = 480;
-               mode->hsync_start = 873;
-               mode->hsync_end = 876;
-               mode->htotal = 887;
-               mode->vsync_start = 487;
-               mode->vsync_end = 490;
-               mode->vtotal = 499;
-               mode->clock = 33264;
-       }
-
-       drm_mode_set_name(mode);
-       drm_mode_set_crtcinfo(mode, 0);
-
-       mode->type |= DRM_MODE_TYPE_PREFERRED;
-
-       return mode;
-}
-
-static int tpo_vid_get_panel_info(struct drm_device *dev,
-                               int pipe,
-                               struct panel_info *pi)
-{
-       if (!dev || !pi)
-               return -EINVAL;
-
-       pi->width_mm = TPO_PANEL_WIDTH;
-       pi->height_mm = TPO_PANEL_HEIGHT;
-
-       return 0;
-}
-
-/*TPO DPI encoder helper funcs*/
-static const struct drm_encoder_helper_funcs
-                                       mdfld_tpo_dpi_encoder_helper_funcs = {
-       .dpms = mdfld_dsi_dpi_dpms,
-       .mode_fixup = mdfld_dsi_dpi_mode_fixup,
-       .prepare = mdfld_dsi_dpi_prepare,
-       .mode_set = mdfld_dsi_dpi_mode_set,
-       .commit = mdfld_dsi_dpi_commit,
-};
-
-/*TPO DPI encoder funcs*/
-static const struct drm_encoder_funcs mdfld_tpo_dpi_encoder_funcs = {
-       .destroy = drm_encoder_cleanup,
-};
-
-void tpo_vid_init(struct drm_device *dev, struct panel_funcs *p_funcs)
-{
-       if (!dev || !p_funcs) {
-               dev_err(dev->dev, "tpo_vid_init: Invalid parameters\n");
-               return;
-       }
-
-       p_funcs->encoder_funcs = &mdfld_tpo_dpi_encoder_funcs;
-       p_funcs->encoder_helper_funcs = &mdfld_tpo_dpi_encoder_helper_funcs;
-       p_funcs->get_config_mode = &tpo_vid_get_config_mode;
-       p_funcs->update_fb = NULL;
-       p_funcs->get_panel_info = tpo_vid_get_panel_info;
-}
diff --git a/drivers/staging/gma500/medfield.h b/drivers/staging/gma500/medfield.h
deleted file mode 100644 (file)
index 09e9687..0000000
+++ /dev/null
@@ -1,268 +0,0 @@
-/*
- * Copyright Â© 2011 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
-
-/* Medfield DSI controller registers */
-
-#define MIPIA_DEVICE_READY_REG                         0xb000
-#define MIPIA_INTR_STAT_REG                            0xb004
-#define MIPIA_INTR_EN_REG                              0xb008
-#define MIPIA_DSI_FUNC_PRG_REG                         0xb00c
-#define MIPIA_HS_TX_TIMEOUT_REG                                0xb010
-#define MIPIA_LP_RX_TIMEOUT_REG                                0xb014
-#define MIPIA_TURN_AROUND_TIMEOUT_REG                  0xb018
-#define MIPIA_DEVICE_RESET_TIMER_REG                   0xb01c
-#define MIPIA_DPI_RESOLUTION_REG                       0xb020
-#define MIPIA_DBI_FIFO_THROTTLE_REG                    0xb024
-#define MIPIA_HSYNC_COUNT_REG                          0xb028
-#define MIPIA_HBP_COUNT_REG                            0xb02c
-#define MIPIA_HFP_COUNT_REG                            0xb030
-#define MIPIA_HACTIVE_COUNT_REG                                0xb034
-#define MIPIA_VSYNC_COUNT_REG                          0xb038
-#define MIPIA_VBP_COUNT_REG                            0xb03c
-#define MIPIA_VFP_COUNT_REG                            0xb040
-#define MIPIA_HIGH_LOW_SWITCH_COUNT_REG                        0xb044
-#define MIPIA_DPI_CONTROL_REG                          0xb048
-#define MIPIA_DPI_DATA_REG                             0xb04c
-#define MIPIA_INIT_COUNT_REG                           0xb050
-#define MIPIA_MAX_RETURN_PACK_SIZE_REG                 0xb054
-#define MIPIA_VIDEO_MODE_FORMAT_REG                    0xb058
-#define MIPIA_EOT_DISABLE_REG                          0xb05c
-#define MIPIA_LP_BYTECLK_REG                           0xb060
-#define MIPIA_LP_GEN_DATA_REG                          0xb064
-#define MIPIA_HS_GEN_DATA_REG                          0xb068
-#define MIPIA_LP_GEN_CTRL_REG                          0xb06c
-#define MIPIA_HS_GEN_CTRL_REG                          0xb070
-#define MIPIA_GEN_FIFO_STAT_REG                                0xb074
-#define MIPIA_HS_LS_DBI_ENABLE_REG                     0xb078
-#define MIPIA_DPHY_PARAM_REG                           0xb080
-#define MIPIA_DBI_BW_CTRL_REG                          0xb084
-#define MIPIA_CLK_LANE_SWITCH_TIME_CNT_REG             0xb088
-
-#define DSI_DEVICE_READY                               (0x1)
-#define DSI_POWER_STATE_ULPS_ENTER                     (0x2 << 1)
-#define DSI_POWER_STATE_ULPS_EXIT                      (0x1 << 1)
-#define DSI_POWER_STATE_ULPS_OFFSET                    (0x1)
-
-
-#define DSI_ONE_DATA_LANE                              (0x1)
-#define DSI_TWO_DATA_LANE                              (0x2)
-#define DSI_THREE_DATA_LANE                            (0X3)
-#define DSI_FOUR_DATA_LANE                             (0x4)
-#define DSI_DPI_VIRT_CHANNEL_OFFSET                    (0x3)
-#define DSI_DBI_VIRT_CHANNEL_OFFSET                    (0x5)
-#define DSI_DPI_COLOR_FORMAT_RGB565                    (0x01 << 7)
-#define DSI_DPI_COLOR_FORMAT_RGB666                    (0x02 << 7)
-#define DSI_DPI_COLOR_FORMAT_RGB666_UNPACK             (0x03 << 7)
-#define DSI_DPI_COLOR_FORMAT_RGB888                    (0x04 << 7)
-#define DSI_DBI_COLOR_FORMAT_OPTION2                   (0x05 << 13)
-
-#define DSI_INTR_STATE_RXSOTERROR                      1
-
-#define DSI_INTR_STATE_SPL_PKG_SENT                    (1 << 30)
-#define DSI_INTR_STATE_TE                              (1 << 31)
-
-#define DSI_HS_TX_TIMEOUT_MASK                         (0xffffff)
-
-#define DSI_LP_RX_TIMEOUT_MASK                         (0xffffff)
-
-#define DSI_TURN_AROUND_TIMEOUT_MASK                   (0x3f)
-
-#define DSI_RESET_TIMER_MASK                           (0xffff)
-
-#define DSI_DBI_FIFO_WM_HALF                           (0x0)
-#define DSI_DBI_FIFO_WM_QUARTER                                (0x1)
-#define DSI_DBI_FIFO_WM_LOW                            (0x2)
-
-#define DSI_DPI_TIMING_MASK                            (0xffff)
-
-#define DSI_INIT_TIMER_MASK                            (0xffff)
-
-#define DSI_DBI_RETURN_PACK_SIZE_MASK                  (0x3ff)
-
-#define DSI_LP_BYTECLK_MASK                            (0x0ffff)
-
-#define DSI_HS_CTRL_GEN_SHORT_W0                       (0x03)
-#define DSI_HS_CTRL_GEN_SHORT_W1                       (0x13)
-#define DSI_HS_CTRL_GEN_SHORT_W2                       (0x23)
-#define DSI_HS_CTRL_GEN_R0                             (0x04)
-#define DSI_HS_CTRL_GEN_R1                             (0x14)
-#define DSI_HS_CTRL_GEN_R2                             (0x24)
-#define DSI_HS_CTRL_GEN_LONG_W                         (0x29)
-#define DSI_HS_CTRL_MCS_SHORT_W0                       (0x05)
-#define DSI_HS_CTRL_MCS_SHORT_W1                       (0x15)
-#define DSI_HS_CTRL_MCS_R0                             (0x06)
-#define DSI_HS_CTRL_MCS_LONG_W                         (0x39)
-#define DSI_HS_CTRL_VC_OFFSET                          (0x06)
-#define DSI_HS_CTRL_WC_OFFSET                          (0x08)
-
-#define        DSI_FIFO_GEN_HS_DATA_FULL                       (1 << 0)
-#define DSI_FIFO_GEN_HS_DATA_HALF_EMPTY                        (1 << 1)
-#define DSI_FIFO_GEN_HS_DATA_EMPTY                     (1 << 2)
-#define DSI_FIFO_GEN_LP_DATA_FULL                      (1 << 8)
-#define DSI_FIFO_GEN_LP_DATA_HALF_EMPTY                        (1 << 9)
-#define DSI_FIFO_GEN_LP_DATA_EMPTY                     (1 << 10)
-#define DSI_FIFO_GEN_HS_CTRL_FULL                      (1 << 16)
-#define DSI_FIFO_GEN_HS_CTRL_HALF_EMPTY                        (1 << 17)
-#define DSI_FIFO_GEN_HS_CTRL_EMPTY                     (1 << 18)
-#define DSI_FIFO_GEN_LP_CTRL_FULL                      (1 << 24)
-#define DSI_FIFO_GEN_LP_CTRL_HALF_EMPTY                        (1 << 25)
-#define DSI_FIFO_GEN_LP_CTRL_EMPTY                     (1 << 26)
-#define DSI_FIFO_DBI_EMPTY                             (1 << 27)
-#define DSI_FIFO_DPI_EMPTY                             (1 << 28)
-
-#define DSI_DBI_HS_LP_SWITCH_MASK                      (0x1)
-
-#define DSI_HS_LP_SWITCH_COUNTER_OFFSET                        (0x0)
-#define DSI_LP_HS_SWITCH_COUNTER_OFFSET                        (0x16)
-
-#define DSI_DPI_CTRL_HS_SHUTDOWN                       (0x00000001)
-#define DSI_DPI_CTRL_HS_TURN_ON                                (0x00000002)
-
-/* Medfield DSI adapter registers */
-#define MIPIA_CONTROL_REG                              0xb104
-#define MIPIA_DATA_ADD_REG                             0xb108
-#define MIPIA_DATA_LEN_REG                             0xb10c
-#define MIPIA_CMD_ADD_REG                              0xb110
-#define MIPIA_CMD_LEN_REG                              0xb114
-
-/*dsi power modes*/
-#define DSI_POWER_MODE_DISPLAY_ON      (1 << 2)
-#define DSI_POWER_MODE_NORMAL_ON       (1 << 3)
-#define DSI_POWER_MODE_SLEEP_OUT       (1 << 4)
-#define DSI_POWER_MODE_PARTIAL_ON      (1 << 5)
-#define DSI_POWER_MODE_IDLE_ON         (1 << 6)
-
-enum {
-       MDFLD_DSI_ENCODER_DBI = 0,
-       MDFLD_DSI_ENCODER_DPI,
-};
-
-enum {
-       MDFLD_DSI_VIDEO_NON_BURST_MODE_SYNC_PULSE = 1,
-       MDFLD_DSI_VIDEO_NON_BURST_MODE_SYNC_EVENTS = 2,
-       MDFLD_DSI_VIDEO_BURST_MODE = 3,
-};
-
-#define DSI_DPI_COMPLETE_LAST_LINE                     (1 << 2)
-#define DSI_DPI_DISABLE_BTA                            (1 << 3)
-/* Panel types */
-enum {
-       TPO_CMD,
-       TPO_VID,
-       TMD_CMD,
-       TMD_VID,
-       PYR_CMD,
-       PYR_VID,
-       TPO,
-       TMD,
-       PYR,
-       HDMI,
-       GCT_DETECT
-};
-
-/* Junk that belongs elsewhere */
-#define TPO_PANEL_WIDTH                84
-#define TPO_PANEL_HEIGHT       46
-#define TMD_PANEL_WIDTH                39
-#define TMD_PANEL_HEIGHT       71
-#define PYR_PANEL_WIDTH                53
-#define PYR_PANEL_HEIGHT       95
-
-/* Panel interface */
-struct panel_info {
-       u32 width_mm;
-       u32 height_mm;
-};
-
-struct mdfld_dsi_dbi_output;
-
-struct mdfld_dsi_connector_state {
-       u32 mipi_ctrl_reg;
-};
-
-struct mdfld_dsi_encoder_state {
-
-};
-
-struct mdfld_dsi_connector {
-       /*
-        * This is ugly, but I have to use connector in it! :-(
-        * FIXME: use drm_connector instead.
-        */
-       struct psb_intel_output base;
-
-       int pipe;
-       void *private;
-       void *pkg_sender;
-
-       /* Connection status */
-       enum drm_connector_status status;
-};
-
-struct mdfld_dsi_encoder {
-       struct drm_encoder base;
-       void *private;
-};
-
-/*
- * DSI config, consists of one DSI connector, two DSI encoders.
- * DRM will pick up on DSI encoder basing on differents configs.
- */
-struct mdfld_dsi_config {
-       struct drm_device *dev;
-       struct drm_display_mode *fixed_mode;
-       struct drm_display_mode *mode;
-
-       struct mdfld_dsi_connector *connector;
-       struct mdfld_dsi_encoder *encoders[DRM_CONNECTOR_MAX_ENCODER];
-       struct mdfld_dsi_encoder *encoder;
-
-       int changed;
-
-       int bpp;
-       int type;
-       int lane_count;
-       /*Virtual channel number for this encoder*/
-       int channel_num;
-       /*video mode configure*/
-       int video_mode;
-
-       int dvr_ic_inited;
-};
-
-#define MDFLD_DSI_CONNECTOR(psb_output) \
-               (container_of(psb_output, struct mdfld_dsi_connector, base))
-
-#define MDFLD_DSI_ENCODER(encoder) \
-               (container_of(encoder, struct mdfld_dsi_encoder, base))
-
-struct panel_funcs {
-       const struct drm_encoder_funcs *encoder_funcs;
-       const struct drm_encoder_helper_funcs *encoder_helper_funcs;
-       struct drm_display_mode *(*get_config_mode) (struct drm_device *);
-       void (*update_fb) (struct mdfld_dsi_dbi_output *, int);
-       int (*get_panel_info) (struct drm_device *, int, struct panel_info *);
-       int (*reset)(int pipe);
-       void (*drv_ic_init)(struct mdfld_dsi_config *dsi_config, int pipe);
-};
-
diff --git a/drivers/staging/gma500/mid_bios.c b/drivers/staging/gma500/mid_bios.c
deleted file mode 100644 (file)
index ee3c036..0000000
+++ /dev/null
@@ -1,270 +0,0 @@
-/**************************************************************************
- * Copyright (c) 2011, Intel Corporation.
- * All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- **************************************************************************/
-
-/* TODO
- * - Split functions by vbt type
- * - Make them all take drm_device
- * - Check ioremap failures
- */
-
-#include <linux/moduleparam.h>
-#include <drm/drmP.h>
-#include <drm/drm.h>
-#include "psb_drm.h"
-#include "psb_drv.h"
-#include "mid_bios.h"
-#include "mdfld_output.h"
-
-static int panel_id = GCT_DETECT;
-module_param_named(panel_id, panel_id, int, 0600);
-MODULE_PARM_DESC(panel_id, "Panel Identifier");
-
-
-static void mid_get_fuse_settings(struct drm_device *dev)
-{
-       struct drm_psb_private *dev_priv = dev->dev_private;
-       struct pci_dev *pci_root = pci_get_bus_and_slot(0, 0);
-       uint32_t fuse_value = 0;
-       uint32_t fuse_value_tmp = 0;
-
-#define FB_REG06 0xD0810600
-#define FB_MIPI_DISABLE  (1 << 11)
-#define FB_REG09 0xD0810900
-#define FB_REG09 0xD0810900
-#define FB_SKU_MASK  0x7000
-#define FB_SKU_SHIFT 12
-#define FB_SKU_100 0
-#define FB_SKU_100L 1
-#define FB_SKU_83 2
-       pci_write_config_dword(pci_root, 0xD0, FB_REG06);
-       pci_read_config_dword(pci_root, 0xD4, &fuse_value);
-
-       /* FB_MIPI_DISABLE doesn't mean LVDS on with Medfield */
-       if (IS_MRST(dev))
-               dev_priv->iLVDS_enable = fuse_value & FB_MIPI_DISABLE;
-
-       DRM_INFO("internal display is %s\n",
-                dev_priv->iLVDS_enable ? "LVDS display" : "MIPI display");
-
-        /* Prevent runtime suspend at start*/
-        if (dev_priv->iLVDS_enable) {
-               dev_priv->is_lvds_on = true;
-               dev_priv->is_mipi_on = false;
-       } else {
-               dev_priv->is_mipi_on = true;
-               dev_priv->is_lvds_on = false;
-       }
-
-       dev_priv->video_device_fuse = fuse_value;
-
-       pci_write_config_dword(pci_root, 0xD0, FB_REG09);
-       pci_read_config_dword(pci_root, 0xD4, &fuse_value);
-
-       dev_dbg(dev->dev, "SKU values is 0x%x.\n", fuse_value);
-       fuse_value_tmp = (fuse_value & FB_SKU_MASK) >> FB_SKU_SHIFT;
-
-       dev_priv->fuse_reg_value = fuse_value;
-
-       switch (fuse_value_tmp) {
-       case FB_SKU_100:
-               dev_priv->core_freq = 200;
-               break;
-       case FB_SKU_100L:
-               dev_priv->core_freq = 100;
-               break;
-       case FB_SKU_83:
-               dev_priv->core_freq = 166;
-               break;
-       default:
-               dev_warn(dev->dev, "Invalid SKU values, SKU value = 0x%08x\n",
-                                                               fuse_value_tmp);
-               dev_priv->core_freq = 0;
-       }
-       dev_dbg(dev->dev, "LNC core clk is %dMHz.\n", dev_priv->core_freq);
-       pci_dev_put(pci_root);
-}
-
-/*
- *     Get the revison ID, B0:D2:F0;0x08
- */
-static void mid_get_pci_revID(struct drm_psb_private *dev_priv)
-{
-       uint32_t platform_rev_id = 0;
-       struct pci_dev *pci_gfx_root = pci_get_bus_and_slot(0, PCI_DEVFN(2, 0));
-
-       pci_read_config_dword(pci_gfx_root, 0x08, &platform_rev_id);
-       dev_priv->platform_rev_id = (uint8_t) platform_rev_id;
-       pci_dev_put(pci_gfx_root);
-       dev_dbg(dev_priv->dev->dev, "platform_rev_id is %x\n",
-                                       dev_priv->platform_rev_id);
-}
-
-static void mid_get_vbt_data(struct drm_psb_private *dev_priv)
-{
-       struct drm_device *dev = dev_priv->dev;
-       struct mrst_vbt *vbt = &dev_priv->vbt_data;
-       u32 addr;
-       u16 new_size;
-       u8 *vbt_virtual;
-       u8 bpi;
-       u8 number_desc = 0;
-       struct mrst_timing_info *dp_ti = &dev_priv->gct_data.DTD;
-       struct gct_r10_timing_info ti;
-       void *pGCT;
-       struct pci_dev *pci_gfx_root = pci_get_bus_and_slot(0, PCI_DEVFN(2, 0));
-
-       /* Get the address of the platform config vbt, B0:D2:F0;0xFC */
-       pci_read_config_dword(pci_gfx_root, 0xFC, &addr);
-       pci_dev_put(pci_gfx_root);
-
-       dev_dbg(dev->dev, "drm platform config address is %x\n", addr);
-
-       /* check for platform config address == 0. */
-       /* this means fw doesn't support vbt */
-
-       if (addr == 0) {
-               vbt->size = 0;
-               return;
-       }
-
-       /* get the virtual address of the vbt */
-       vbt_virtual = ioremap(addr, sizeof(*vbt));
-
-       memcpy(vbt, vbt_virtual, sizeof(*vbt));
-       iounmap(vbt_virtual); /* Free virtual address space */
-
-       dev_dbg(dev->dev, "GCT revision is %x\n", vbt->revision);
-
-       switch (vbt->revision) {
-       case 0:
-               vbt->mrst_gct = ioremap(addr + sizeof(*vbt) - 4,
-                                       vbt->size - sizeof(*vbt) + 4);
-               pGCT = vbt->mrst_gct;
-               bpi = ((struct mrst_gct_v1 *)pGCT)->PD.BootPanelIndex;
-               dev_priv->gct_data.bpi = bpi;
-               dev_priv->gct_data.pt =
-                       ((struct mrst_gct_v1 *)pGCT)->PD.PanelType;
-               memcpy(&dev_priv->gct_data.DTD,
-                       &((struct mrst_gct_v1 *)pGCT)->panel[bpi].DTD,
-                               sizeof(struct mrst_timing_info));
-               dev_priv->gct_data.Panel_Port_Control =
-                 ((struct mrst_gct_v1 *)pGCT)->panel[bpi].Panel_Port_Control;
-               dev_priv->gct_data.Panel_MIPI_Display_Descriptor =
-                       ((struct mrst_gct_v1 *)pGCT)->panel[bpi].Panel_MIPI_Display_Descriptor;
-               break;
-       case 1:
-               vbt->mrst_gct = ioremap(addr + sizeof(*vbt) - 4,
-                                       vbt->size - sizeof(*vbt) + 4);
-               pGCT = vbt->mrst_gct;
-               bpi = ((struct mrst_gct_v2 *)pGCT)->PD.BootPanelIndex;
-               dev_priv->gct_data.bpi = bpi;
-               dev_priv->gct_data.pt =
-                       ((struct mrst_gct_v2 *)pGCT)->PD.PanelType;
-               memcpy(&dev_priv->gct_data.DTD,
-                       &((struct mrst_gct_v2 *)pGCT)->panel[bpi].DTD,
-                               sizeof(struct mrst_timing_info));
-               dev_priv->gct_data.Panel_Port_Control =
-                 ((struct mrst_gct_v2 *)pGCT)->panel[bpi].Panel_Port_Control;
-               dev_priv->gct_data.Panel_MIPI_Display_Descriptor =
-                       ((struct mrst_gct_v2 *)pGCT)->panel[bpi].Panel_MIPI_Display_Descriptor;
-               break;
-       case 0x10:
-               /*header definition changed from rev 01 (v2) to rev 10h. */
-               /*so, some values have changed location*/
-               new_size = vbt->checksum; /*checksum contains lo size byte*/
-               /*LSB of mrst_gct contains hi size byte*/
-               new_size |= ((0xff & (unsigned int)vbt->mrst_gct)) << 8;
-
-               vbt->checksum = vbt->size; /*size contains the checksum*/
-               if (new_size > 0xff)
-                       vbt->size = 0xff; /*restrict size to 255*/
-               else
-                       vbt->size = new_size;
-
-               /* number of descriptors defined in the GCT */
-               number_desc = ((0xff00 & (unsigned int)vbt->mrst_gct)) >> 8;
-               bpi = ((0xff0000 & (unsigned int)vbt->mrst_gct)) >> 16;
-               vbt->mrst_gct = ioremap(addr + GCT_R10_HEADER_SIZE,
-                               GCT_R10_DISPLAY_DESC_SIZE * number_desc);
-               pGCT = vbt->mrst_gct;
-               pGCT = (u8 *)pGCT + (bpi*GCT_R10_DISPLAY_DESC_SIZE);
-               dev_priv->gct_data.bpi = bpi; /*save boot panel id*/
-
-               /*copy the GCT display timings into a temp structure*/
-               memcpy(&ti, pGCT, sizeof(struct gct_r10_timing_info));
-
-               /*now copy the temp struct into the dev_priv->gct_data*/
-               dp_ti->pixel_clock = ti.pixel_clock;
-               dp_ti->hactive_hi = ti.hactive_hi;
-               dp_ti->hactive_lo = ti.hactive_lo;
-               dp_ti->hblank_hi = ti.hblank_hi;
-               dp_ti->hblank_lo = ti.hblank_lo;
-               dp_ti->hsync_offset_hi = ti.hsync_offset_hi;
-               dp_ti->hsync_offset_lo = ti.hsync_offset_lo;
-               dp_ti->hsync_pulse_width_hi = ti.hsync_pulse_width_hi;
-               dp_ti->hsync_pulse_width_lo = ti.hsync_pulse_width_lo;
-               dp_ti->vactive_hi = ti.vactive_hi;
-               dp_ti->vactive_lo = ti.vactive_lo;
-               dp_ti->vblank_hi = ti.vblank_hi;
-               dp_ti->vblank_lo = ti.vblank_lo;
-               dp_ti->vsync_offset_hi = ti.vsync_offset_hi;
-               dp_ti->vsync_offset_lo = ti.vsync_offset_lo;
-               dp_ti->vsync_pulse_width_hi = ti.vsync_pulse_width_hi;
-               dp_ti->vsync_pulse_width_lo = ti.vsync_pulse_width_lo;
-
-               /* Move the MIPI_Display_Descriptor data from GCT to dev priv */
-               dev_priv->gct_data.Panel_MIPI_Display_Descriptor =
-                                                       *((u8 *)pGCT + 0x0d);
-               dev_priv->gct_data.Panel_MIPI_Display_Descriptor |=
-                                               (*((u8 *)pGCT + 0x0e)) << 8;
-               break;
-       default:
-               dev_err(dev->dev, "Unknown revision of GCT!\n");
-               vbt->size = 0;
-       }
-       if (IS_MFLD(dev_priv->dev)) {
-               if (panel_id == GCT_DETECT) {
-                       if (dev_priv->gct_data.bpi == 2) {
-                               dev_info(dev->dev, "[GFX] PYR Panel Detected\n");
-                               dev_priv->panel_id = PYR_CMD;
-                               panel_id = PYR_CMD;
-                       } else if (dev_priv->gct_data.bpi == 0) {
-                               dev_info(dev->dev, "[GFX] TMD Panel Detected.\n");
-                               dev_priv->panel_id = TMD_VID;
-                               panel_id = TMD_VID;
-                       } else {
-                               dev_info(dev->dev, "[GFX] Default Panel (TPO)\n");
-                               dev_priv->panel_id = TPO_CMD;
-                               panel_id = TPO_CMD;
-                       }
-               } else {
-                       dev_info(dev->dev, "[GFX] Panel Parameter Passed in through cmd line\n");
-                       dev_priv->panel_id = panel_id;
-               }
-       }
-}
-
-int mid_chip_setup(struct drm_device *dev)
-{
-       struct drm_psb_private *dev_priv = dev->dev_private;
-       mid_get_fuse_settings(dev);
-       mid_get_vbt_data(dev_priv);
-       mid_get_pci_revID(dev_priv);
-       return 0;
-}
diff --git a/drivers/staging/gma500/mid_bios.h b/drivers/staging/gma500/mid_bios.h
deleted file mode 100644 (file)
index 00e7d56..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-/**************************************************************************
- * Copyright (c) 2011, Intel Corporation.
- * All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- **************************************************************************/
-
-extern int mid_chip_setup(struct drm_device *dev);
-
diff --git a/drivers/staging/gma500/mmu.c b/drivers/staging/gma500/mmu.c
deleted file mode 100644 (file)
index c904d73..0000000
+++ /dev/null
@@ -1,858 +0,0 @@
-/**************************************************************************
- * Copyright (c) 2007, Intel Corporation.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- **************************************************************************/
-#include <drm/drmP.h>
-#include "psb_drv.h"
-#include "psb_reg.h"
-
-/*
- * Code for the SGX MMU:
- */
-
-/*
- * clflush on one processor only:
- * clflush should apparently flush the cache line on all processors in an
- * SMP system.
- */
-
-/*
- * kmap atomic:
- * The usage of the slots must be completely encapsulated within a spinlock, and
- * no other functions that may be using the locks for other purposed may be
- * called from within the locked region.
- * Since the slots are per processor, this will guarantee that we are the only
- * user.
- */
-
-/*
- * TODO: Inserting ptes from an interrupt handler:
- * This may be desirable for some SGX functionality where the GPU can fault in
- * needed pages. For that, we need to make an atomic insert_pages function, that
- * may fail.
- * If it fails, the caller need to insert the page using a workqueue function,
- * but on average it should be fast.
- */
-
-struct psb_mmu_driver {
-       /* protects driver- and pd structures. Always take in read mode
-        * before taking the page table spinlock.
-        */
-       struct rw_semaphore sem;
-
-       /* protects page tables, directory tables and pt tables.
-        * and pt structures.
-        */
-       spinlock_t lock;
-
-       atomic_t needs_tlbflush;
-
-       uint8_t __iomem *register_map;
-       struct psb_mmu_pd *default_pd;
-       /*uint32_t bif_ctrl;*/
-       int has_clflush;
-       int clflush_add;
-       unsigned long clflush_mask;
-
-       struct drm_psb_private *dev_priv;
-};
-
-struct psb_mmu_pd;
-
-struct psb_mmu_pt {
-       struct psb_mmu_pd *pd;
-       uint32_t index;
-       uint32_t count;
-       struct page *p;
-       uint32_t *v;
-};
-
-struct psb_mmu_pd {
-       struct psb_mmu_driver *driver;
-       int hw_context;
-       struct psb_mmu_pt **tables;
-       struct page *p;
-       struct page *dummy_pt;
-       struct page *dummy_page;
-       uint32_t pd_mask;
-       uint32_t invalid_pde;
-       uint32_t invalid_pte;
-};
-
-static inline uint32_t psb_mmu_pt_index(uint32_t offset)
-{
-       return (offset >> PSB_PTE_SHIFT) & 0x3FF;
-}
-
-static inline uint32_t psb_mmu_pd_index(uint32_t offset)
-{
-       return offset >> PSB_PDE_SHIFT;
-}
-
-static inline void psb_clflush(void *addr)
-{
-       __asm__ __volatile__("clflush (%0)\n" : : "r"(addr) : "memory");
-}
-
-static inline void psb_mmu_clflush(struct psb_mmu_driver *driver,
-                                  void *addr)
-{
-       if (!driver->has_clflush)
-               return;
-
-       mb();
-       psb_clflush(addr);
-       mb();
-}
-
-static void psb_page_clflush(struct psb_mmu_driver *driver, struct page* page)
-{
-       uint32_t clflush_add = driver->clflush_add >> PAGE_SHIFT;
-       uint32_t clflush_count = PAGE_SIZE / clflush_add;
-       int i;
-       uint8_t *clf;
-
-       clf = kmap_atomic(page, KM_USER0);
-       mb();
-       for (i = 0; i < clflush_count; ++i) {
-               psb_clflush(clf);
-               clf += clflush_add;
-       }
-       mb();
-       kunmap_atomic(clf, KM_USER0);
-}
-
-static void psb_pages_clflush(struct psb_mmu_driver *driver,
-                               struct page *page[], unsigned long num_pages)
-{
-       int i;
-
-       if (!driver->has_clflush)
-               return ;
-
-       for (i = 0; i < num_pages; i++)
-               psb_page_clflush(driver, *page++);
-}
-
-static void psb_mmu_flush_pd_locked(struct psb_mmu_driver *driver,
-                                   int force)
-{
-       atomic_set(&driver->needs_tlbflush, 0);
-}
-
-static void psb_mmu_flush_pd(struct psb_mmu_driver *driver, int force)
-{
-       down_write(&driver->sem);
-       psb_mmu_flush_pd_locked(driver, force);
-       up_write(&driver->sem);
-}
-
-void psb_mmu_flush(struct psb_mmu_driver *driver, int rc_prot)
-{
-       if (rc_prot)
-               down_write(&driver->sem);
-       if (rc_prot)
-               up_write(&driver->sem);
-}
-
-void psb_mmu_set_pd_context(struct psb_mmu_pd *pd, int hw_context)
-{
-       /*ttm_tt_cache_flush(&pd->p, 1);*/
-       psb_pages_clflush(pd->driver, &pd->p, 1);
-       down_write(&pd->driver->sem);
-       wmb();
-       psb_mmu_flush_pd_locked(pd->driver, 1);
-       pd->hw_context = hw_context;
-       up_write(&pd->driver->sem);
-
-}
-
-static inline unsigned long psb_pd_addr_end(unsigned long addr,
-                                           unsigned long end)
-{
-
-       addr = (addr + PSB_PDE_MASK + 1) & ~PSB_PDE_MASK;
-       return (addr < end) ? addr : end;
-}
-
-static inline uint32_t psb_mmu_mask_pte(uint32_t pfn, int type)
-{
-       uint32_t mask = PSB_PTE_VALID;
-
-       if (type & PSB_MMU_CACHED_MEMORY)
-               mask |= PSB_PTE_CACHED;
-       if (type & PSB_MMU_RO_MEMORY)
-               mask |= PSB_PTE_RO;
-       if (type & PSB_MMU_WO_MEMORY)
-               mask |= PSB_PTE_WO;
-
-       return (pfn << PAGE_SHIFT) | mask;
-}
-
-struct psb_mmu_pd *psb_mmu_alloc_pd(struct psb_mmu_driver *driver,
-                                   int trap_pagefaults, int invalid_type)
-{
-       struct psb_mmu_pd *pd = kmalloc(sizeof(*pd), GFP_KERNEL);
-       uint32_t *v;
-       int i;
-
-       if (!pd)
-               return NULL;
-
-       pd->p = alloc_page(GFP_DMA32);
-       if (!pd->p)
-               goto out_err1;
-       pd->dummy_pt = alloc_page(GFP_DMA32);
-       if (!pd->dummy_pt)
-               goto out_err2;
-       pd->dummy_page = alloc_page(GFP_DMA32);
-       if (!pd->dummy_page)
-               goto out_err3;
-
-       if (!trap_pagefaults) {
-               pd->invalid_pde =
-                   psb_mmu_mask_pte(page_to_pfn(pd->dummy_pt),
-                                    invalid_type);
-               pd->invalid_pte =
-                   psb_mmu_mask_pte(page_to_pfn(pd->dummy_page),
-                                    invalid_type);
-       } else {
-               pd->invalid_pde = 0;
-               pd->invalid_pte = 0;
-       }
-
-       v = kmap(pd->dummy_pt);
-       for (i = 0; i < (PAGE_SIZE / sizeof(uint32_t)); ++i)
-               v[i] = pd->invalid_pte;
-
-       kunmap(pd->dummy_pt);
-
-       v = kmap(pd->p);
-       for (i = 0; i < (PAGE_SIZE / sizeof(uint32_t)); ++i)
-               v[i] = pd->invalid_pde;
-
-       kunmap(pd->p);
-
-       clear_page(kmap(pd->dummy_page));
-       kunmap(pd->dummy_page);
-
-       pd->tables = vmalloc_user(sizeof(struct psb_mmu_pt *) * 1024);
-       if (!pd->tables)
-               goto out_err4;
-
-       pd->hw_context = -1;
-       pd->pd_mask = PSB_PTE_VALID;
-       pd->driver = driver;
-
-       return pd;
-
-out_err4:
-       __free_page(pd->dummy_page);
-out_err3:
-       __free_page(pd->dummy_pt);
-out_err2:
-       __free_page(pd->p);
-out_err1:
-       kfree(pd);
-       return NULL;
-}
-
-void psb_mmu_free_pt(struct psb_mmu_pt *pt)
-{
-       __free_page(pt->p);
-       kfree(pt);
-}
-
-void psb_mmu_free_pagedir(struct psb_mmu_pd *pd)
-{
-       struct psb_mmu_driver *driver = pd->driver;
-       struct psb_mmu_pt *pt;
-       int i;
-
-       down_write(&driver->sem);
-       if (pd->hw_context != -1)
-               psb_mmu_flush_pd_locked(driver, 1);
-
-       /* Should take the spinlock here, but we don't need to do that
-          since we have the semaphore in write mode. */
-
-       for (i = 0; i < 1024; ++i) {
-               pt = pd->tables[i];
-               if (pt)
-                       psb_mmu_free_pt(pt);
-       }
-
-       vfree(pd->tables);
-       __free_page(pd->dummy_page);
-       __free_page(pd->dummy_pt);
-       __free_page(pd->p);
-       kfree(pd);
-       up_write(&driver->sem);
-}
-
-static struct psb_mmu_pt *psb_mmu_alloc_pt(struct psb_mmu_pd *pd)
-{
-       struct psb_mmu_pt *pt = kmalloc(sizeof(*pt), GFP_KERNEL);
-       void *v;
-       uint32_t clflush_add = pd->driver->clflush_add >> PAGE_SHIFT;
-       uint32_t clflush_count = PAGE_SIZE / clflush_add;
-       spinlock_t *lock = &pd->driver->lock;
-       uint8_t *clf;
-       uint32_t *ptes;
-       int i;
-
-       if (!pt)
-               return NULL;
-
-       pt->p = alloc_page(GFP_DMA32);
-       if (!pt->p) {
-               kfree(pt);
-               return NULL;
-       }
-
-       spin_lock(lock);
-
-       v = kmap_atomic(pt->p, KM_USER0);
-       clf = (uint8_t *) v;
-       ptes = (uint32_t *) v;
-       for (i = 0; i < (PAGE_SIZE / sizeof(uint32_t)); ++i)
-               *ptes++ = pd->invalid_pte;
-
-
-       if (pd->driver->has_clflush && pd->hw_context != -1) {
-               mb();
-               for (i = 0; i < clflush_count; ++i) {
-                       psb_clflush(clf);
-                       clf += clflush_add;
-               }
-               mb();
-       }
-
-       kunmap_atomic(v, KM_USER0);
-       spin_unlock(lock);
-
-       pt->count = 0;
-       pt->pd = pd;
-       pt->index = 0;
-
-       return pt;
-}
-
-struct psb_mmu_pt *psb_mmu_pt_alloc_map_lock(struct psb_mmu_pd *pd,
-                                            unsigned long addr)
-{
-       uint32_t index = psb_mmu_pd_index(addr);
-       struct psb_mmu_pt *pt;
-       uint32_t *v;
-       spinlock_t *lock = &pd->driver->lock;
-
-       spin_lock(lock);
-       pt = pd->tables[index];
-       while (!pt) {
-               spin_unlock(lock);
-               pt = psb_mmu_alloc_pt(pd);
-               if (!pt)
-                       return NULL;
-               spin_lock(lock);
-
-               if (pd->tables[index]) {
-                       spin_unlock(lock);
-                       psb_mmu_free_pt(pt);
-                       spin_lock(lock);
-                       pt = pd->tables[index];
-                       continue;
-               }
-
-               v = kmap_atomic(pd->p, KM_USER0);
-               pd->tables[index] = pt;
-               v[index] = (page_to_pfn(pt->p) << 12) | pd->pd_mask;
-               pt->index = index;
-               kunmap_atomic((void *) v, KM_USER0);
-
-               if (pd->hw_context != -1) {
-                       psb_mmu_clflush(pd->driver, (void *) &v[index]);
-                       atomic_set(&pd->driver->needs_tlbflush, 1);
-               }
-       }
-       pt->v = kmap_atomic(pt->p, KM_USER0);
-       return pt;
-}
-
-static struct psb_mmu_pt *psb_mmu_pt_map_lock(struct psb_mmu_pd *pd,
-                                             unsigned long addr)
-{
-       uint32_t index = psb_mmu_pd_index(addr);
-       struct psb_mmu_pt *pt;
-       spinlock_t *lock = &pd->driver->lock;
-
-       spin_lock(lock);
-       pt = pd->tables[index];
-       if (!pt) {
-               spin_unlock(lock);
-               return NULL;
-       }
-       pt->v = kmap_atomic(pt->p, KM_USER0);
-       return pt;
-}
-
-static void psb_mmu_pt_unmap_unlock(struct psb_mmu_pt *pt)
-{
-       struct psb_mmu_pd *pd = pt->pd;
-       uint32_t *v;
-
-       kunmap_atomic(pt->v, KM_USER0);
-       if (pt->count == 0) {
-               v = kmap_atomic(pd->p, KM_USER0);
-               v[pt->index] = pd->invalid_pde;
-               pd->tables[pt->index] = NULL;
-
-               if (pd->hw_context != -1) {
-                       psb_mmu_clflush(pd->driver,
-                                       (void *) &v[pt->index]);
-                       atomic_set(&pd->driver->needs_tlbflush, 1);
-               }
-               kunmap_atomic(pt->v, KM_USER0);
-               spin_unlock(&pd->driver->lock);
-               psb_mmu_free_pt(pt);
-               return;
-       }
-       spin_unlock(&pd->driver->lock);
-}
-
-static inline void psb_mmu_set_pte(struct psb_mmu_pt *pt,
-                                  unsigned long addr, uint32_t pte)
-{
-       pt->v[psb_mmu_pt_index(addr)] = pte;
-}
-
-static inline void psb_mmu_invalidate_pte(struct psb_mmu_pt *pt,
-                                         unsigned long addr)
-{
-       pt->v[psb_mmu_pt_index(addr)] = pt->pd->invalid_pte;
-}
-
-
-void psb_mmu_mirror_gtt(struct psb_mmu_pd *pd,
-                       uint32_t mmu_offset, uint32_t gtt_start,
-                       uint32_t gtt_pages)
-{
-       uint32_t *v;
-       uint32_t start = psb_mmu_pd_index(mmu_offset);
-       struct psb_mmu_driver *driver = pd->driver;
-       int num_pages = gtt_pages;
-
-       down_read(&driver->sem);
-       spin_lock(&driver->lock);
-
-       v = kmap_atomic(pd->p, KM_USER0);
-       v += start;
-
-       while (gtt_pages--) {
-               *v++ = gtt_start | pd->pd_mask;
-               gtt_start += PAGE_SIZE;
-       }
-
-       /*ttm_tt_cache_flush(&pd->p, num_pages);*/
-       psb_pages_clflush(pd->driver, &pd->p, num_pages);
-       kunmap_atomic(v, KM_USER0);
-       spin_unlock(&driver->lock);
-
-       if (pd->hw_context != -1)
-               atomic_set(&pd->driver->needs_tlbflush, 1);
-
-       up_read(&pd->driver->sem);
-       psb_mmu_flush_pd(pd->driver, 0);
-}
-
-struct psb_mmu_pd *psb_mmu_get_default_pd(struct psb_mmu_driver *driver)
-{
-       struct psb_mmu_pd *pd;
-
-       /* down_read(&driver->sem); */
-       pd = driver->default_pd;
-       /* up_read(&driver->sem); */
-
-       return pd;
-}
-
-/* Returns the physical address of the PD shared by sgx/msvdx */
-uint32_t psb_get_default_pd_addr(struct psb_mmu_driver *driver)
-{
-       struct psb_mmu_pd *pd;
-
-       pd = psb_mmu_get_default_pd(driver);
-       return page_to_pfn(pd->p) << PAGE_SHIFT;
-}
-
-void psb_mmu_driver_takedown(struct psb_mmu_driver *driver)
-{
-       psb_mmu_free_pagedir(driver->default_pd);
-       kfree(driver);
-}
-
-struct psb_mmu_driver *psb_mmu_driver_init(uint8_t __iomem * registers,
-                                       int trap_pagefaults,
-                                       int invalid_type,
-                                       struct drm_psb_private *dev_priv)
-{
-       struct psb_mmu_driver *driver;
-
-       driver = kmalloc(sizeof(*driver), GFP_KERNEL);
-
-       if (!driver)
-               return NULL;
-       driver->dev_priv = dev_priv;
-
-       driver->default_pd = psb_mmu_alloc_pd(driver, trap_pagefaults,
-                                             invalid_type);
-       if (!driver->default_pd)
-               goto out_err1;
-
-       spin_lock_init(&driver->lock);
-       init_rwsem(&driver->sem);
-       down_write(&driver->sem);
-       driver->register_map = registers;
-       atomic_set(&driver->needs_tlbflush, 1);
-
-       driver->has_clflush = 0;
-
-       if (boot_cpu_has(X86_FEATURE_CLFLSH)) {
-               uint32_t tfms, misc, cap0, cap4, clflush_size;
-
-               /*
-                * clflush size is determined at kernel setup for x86_64
-                *  but not for i386. We have to do it here.
-                */
-
-               cpuid(0x00000001, &tfms, &misc, &cap0, &cap4);
-               clflush_size = ((misc >> 8) & 0xff) * 8;
-               driver->has_clflush = 1;
-               driver->clflush_add =
-                   PAGE_SIZE * clflush_size / sizeof(uint32_t);
-               driver->clflush_mask = driver->clflush_add - 1;
-               driver->clflush_mask = ~driver->clflush_mask;
-       }
-
-       up_write(&driver->sem);
-       return driver;
-
-out_err1:
-       kfree(driver);
-       return NULL;
-}
-
-static void psb_mmu_flush_ptes(struct psb_mmu_pd *pd,
-                              unsigned long address, uint32_t num_pages,
-                              uint32_t desired_tile_stride,
-                              uint32_t hw_tile_stride)
-{
-       struct psb_mmu_pt *pt;
-       uint32_t rows = 1;
-       uint32_t i;
-       unsigned long addr;
-       unsigned long end;
-       unsigned long next;
-       unsigned long add;
-       unsigned long row_add;
-       unsigned long clflush_add = pd->driver->clflush_add;
-       unsigned long clflush_mask = pd->driver->clflush_mask;
-
-       if (!pd->driver->has_clflush) {
-               /*ttm_tt_cache_flush(&pd->p, num_pages);*/
-               psb_pages_clflush(pd->driver, &pd->p, num_pages);
-               return;
-       }
-
-       if (hw_tile_stride)
-               rows = num_pages / desired_tile_stride;
-       else
-               desired_tile_stride = num_pages;
-
-       add = desired_tile_stride << PAGE_SHIFT;
-       row_add = hw_tile_stride << PAGE_SHIFT;
-       mb();
-       for (i = 0; i < rows; ++i) {
-
-               addr = address;
-               end = addr + add;
-
-               do {
-                       next = psb_pd_addr_end(addr, end);
-                       pt = psb_mmu_pt_map_lock(pd, addr);
-                       if (!pt)
-                               continue;
-                       do {
-                               psb_clflush(&pt->v
-                                           [psb_mmu_pt_index(addr)]);
-                       } while (addr +=
-                                clflush_add,
-                                (addr & clflush_mask) < next);
-
-                       psb_mmu_pt_unmap_unlock(pt);
-               } while (addr = next, next != end);
-               address += row_add;
-       }
-       mb();
-}
-
-void psb_mmu_remove_pfn_sequence(struct psb_mmu_pd *pd,
-                                unsigned long address, uint32_t num_pages)
-{
-       struct psb_mmu_pt *pt;
-       unsigned long addr;
-       unsigned long end;
-       unsigned long next;
-       unsigned long f_address = address;
-
-       down_read(&pd->driver->sem);
-
-       addr = address;
-       end = addr + (num_pages << PAGE_SHIFT);
-
-       do {
-               next = psb_pd_addr_end(addr, end);
-               pt = psb_mmu_pt_alloc_map_lock(pd, addr);
-               if (!pt)
-                       goto out;
-               do {
-                       psb_mmu_invalidate_pte(pt, addr);
-                       --pt->count;
-               } while (addr += PAGE_SIZE, addr < next);
-               psb_mmu_pt_unmap_unlock(pt);
-
-       } while (addr = next, next != end);
-
-out:
-       if (pd->hw_context != -1)
-               psb_mmu_flush_ptes(pd, f_address, num_pages, 1, 1);
-
-       up_read(&pd->driver->sem);
-
-       if (pd->hw_context != -1)
-               psb_mmu_flush(pd->driver, 0);
-
-       return;
-}
-
-void psb_mmu_remove_pages(struct psb_mmu_pd *pd, unsigned long address,
-                         uint32_t num_pages, uint32_t desired_tile_stride,
-                         uint32_t hw_tile_stride)
-{
-       struct psb_mmu_pt *pt;
-       uint32_t rows = 1;
-       uint32_t i;
-       unsigned long addr;
-       unsigned long end;
-       unsigned long next;
-       unsigned long add;
-       unsigned long row_add;
-       unsigned long f_address = address;
-
-       if (hw_tile_stride)
-               rows = num_pages / desired_tile_stride;
-       else
-               desired_tile_stride = num_pages;
-
-       add = desired_tile_stride << PAGE_SHIFT;
-       row_add = hw_tile_stride << PAGE_SHIFT;
-
-       /* down_read(&pd->driver->sem); */
-
-       /* Make sure we only need to flush this processor's cache */
-
-       for (i = 0; i < rows; ++i) {
-
-               addr = address;
-               end = addr + add;
-
-               do {
-                       next = psb_pd_addr_end(addr, end);
-                       pt = psb_mmu_pt_map_lock(pd, addr);
-                       if (!pt)
-                               continue;
-                       do {
-                               psb_mmu_invalidate_pte(pt, addr);
-                               --pt->count;
-
-                       } while (addr += PAGE_SIZE, addr < next);
-                       psb_mmu_pt_unmap_unlock(pt);
-
-               } while (addr = next, next != end);
-               address += row_add;
-       }
-       if (pd->hw_context != -1)
-               psb_mmu_flush_ptes(pd, f_address, num_pages,
-                                  desired_tile_stride, hw_tile_stride);
-
-       /* up_read(&pd->driver->sem); */
-
-       if (pd->hw_context != -1)
-               psb_mmu_flush(pd->driver, 0);
-}
-
-int psb_mmu_insert_pfn_sequence(struct psb_mmu_pd *pd, uint32_t start_pfn,
-                               unsigned long address, uint32_t num_pages,
-                               int type)
-{
-       struct psb_mmu_pt *pt;
-       uint32_t pte;
-       unsigned long addr;
-       unsigned long end;
-       unsigned long next;
-       unsigned long f_address = address;
-       int ret = 0;
-
-       down_read(&pd->driver->sem);
-
-       addr = address;
-       end = addr + (num_pages << PAGE_SHIFT);
-
-       do {
-               next = psb_pd_addr_end(addr, end);
-               pt = psb_mmu_pt_alloc_map_lock(pd, addr);
-               if (!pt) {
-                       ret = -ENOMEM;
-                       goto out;
-               }
-               do {
-                       pte = psb_mmu_mask_pte(start_pfn++, type);
-                       psb_mmu_set_pte(pt, addr, pte);
-                       pt->count++;
-               } while (addr += PAGE_SIZE, addr < next);
-               psb_mmu_pt_unmap_unlock(pt);
-
-       } while (addr = next, next != end);
-
-out:
-       if (pd->hw_context != -1)
-               psb_mmu_flush_ptes(pd, f_address, num_pages, 1, 1);
-
-       up_read(&pd->driver->sem);
-
-       if (pd->hw_context != -1)
-               psb_mmu_flush(pd->driver, 1);
-
-       return ret;
-}
-
-int psb_mmu_insert_pages(struct psb_mmu_pd *pd, struct page **pages,
-                        unsigned long address, uint32_t num_pages,
-                        uint32_t desired_tile_stride,
-                        uint32_t hw_tile_stride, int type)
-{
-       struct psb_mmu_pt *pt;
-       uint32_t rows = 1;
-       uint32_t i;
-       uint32_t pte;
-       unsigned long addr;
-       unsigned long end;
-       unsigned long next;
-       unsigned long add;
-       unsigned long row_add;
-       unsigned long f_address = address;
-       int ret = 0;
-
-       if (hw_tile_stride) {
-               if (num_pages % desired_tile_stride != 0)
-                       return -EINVAL;
-               rows = num_pages / desired_tile_stride;
-       } else {
-               desired_tile_stride = num_pages;
-       }
-
-       add = desired_tile_stride << PAGE_SHIFT;
-       row_add = hw_tile_stride << PAGE_SHIFT;
-
-       down_read(&pd->driver->sem);
-
-       for (i = 0; i < rows; ++i) {
-
-               addr = address;
-               end = addr + add;
-
-               do {
-                       next = psb_pd_addr_end(addr, end);
-                       pt = psb_mmu_pt_alloc_map_lock(pd, addr);
-                       if (!pt) {
-                               ret = -ENOMEM;
-                               goto out;
-                       }
-                       do {
-                               pte =
-                                   psb_mmu_mask_pte(page_to_pfn(*pages++),
-                                                    type);
-                               psb_mmu_set_pte(pt, addr, pte);
-                               pt->count++;
-                       } while (addr += PAGE_SIZE, addr < next);
-                       psb_mmu_pt_unmap_unlock(pt);
-
-               } while (addr = next, next != end);
-
-               address += row_add;
-       }
-out:
-       if (pd->hw_context != -1)
-               psb_mmu_flush_ptes(pd, f_address, num_pages,
-                                  desired_tile_stride, hw_tile_stride);
-
-       up_read(&pd->driver->sem);
-
-       if (pd->hw_context != -1)
-               psb_mmu_flush(pd->driver, 1);
-
-       return ret;
-}
-
-int psb_mmu_virtual_to_pfn(struct psb_mmu_pd *pd, uint32_t virtual,
-                          unsigned long *pfn)
-{
-       int ret;
-       struct psb_mmu_pt *pt;
-       uint32_t tmp;
-       spinlock_t *lock = &pd->driver->lock;
-
-       down_read(&pd->driver->sem);
-       pt = psb_mmu_pt_map_lock(pd, virtual);
-       if (!pt) {
-               uint32_t *v;
-
-               spin_lock(lock);
-               v = kmap_atomic(pd->p, KM_USER0);
-               tmp = v[psb_mmu_pd_index(virtual)];
-               kunmap_atomic(v, KM_USER0);
-               spin_unlock(lock);
-
-               if (tmp != pd->invalid_pde || !(tmp & PSB_PTE_VALID) ||
-                   !(pd->invalid_pte & PSB_PTE_VALID)) {
-                       ret = -EINVAL;
-                       goto out;
-               }
-               ret = 0;
-               *pfn = pd->invalid_pte >> PAGE_SHIFT;
-               goto out;
-       }
-       tmp = pt->v[psb_mmu_pt_index(virtual)];
-       if (!(tmp & PSB_PTE_VALID)) {
-               ret = -EINVAL;
-       } else {
-               ret = 0;
-               *pfn = tmp >> PAGE_SHIFT;
-       }
-       psb_mmu_pt_unmap_unlock(pt);
-out:
-       up_read(&pd->driver->sem);
-       return ret;
-}
diff --git a/drivers/staging/gma500/mrst.h b/drivers/staging/gma500/mrst.h
deleted file mode 100644 (file)
index b563dbc..0000000
+++ /dev/null
@@ -1,252 +0,0 @@
-/**************************************************************************
- * Copyright (c) 2007-2011, Intel Corporation.
- * All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- **************************************************************************/
-
-/* MID device specific descriptors */
-
-struct mrst_vbt {
-       s8 signature[4];        /*4 bytes,"$GCT" */
-       u8 revision;
-       u8 size;
-       u8 checksum;
-       void *mrst_gct;
-} __packed;
-
-struct mrst_timing_info {
-       u16 pixel_clock;
-       u8 hactive_lo;
-       u8 hblank_lo;
-       u8 hblank_hi:4;
-       u8 hactive_hi:4;
-       u8 vactive_lo;
-       u8 vblank_lo;
-       u8 vblank_hi:4;
-       u8 vactive_hi:4;
-       u8 hsync_offset_lo;
-       u8 hsync_pulse_width_lo;
-       u8 vsync_pulse_width_lo:4;
-       u8 vsync_offset_lo:4;
-       u8 vsync_pulse_width_hi:2;
-       u8 vsync_offset_hi:2;
-       u8 hsync_pulse_width_hi:2;
-       u8 hsync_offset_hi:2;
-       u8 width_mm_lo;
-       u8 height_mm_lo;
-       u8 height_mm_hi:4;
-       u8 width_mm_hi:4;
-       u8 hborder;
-       u8 vborder;
-       u8 unknown0:1;
-       u8 hsync_positive:1;
-       u8 vsync_positive:1;
-       u8 separate_sync:2;
-       u8 stereo:1;
-       u8 unknown6:1;
-       u8 interlaced:1;
-} __packed;
-
-struct gct_r10_timing_info {
-       u16 pixel_clock;
-       u32 hactive_lo:8;
-       u32 hactive_hi:4;
-       u32 hblank_lo:8;
-       u32 hblank_hi:4;
-       u32 hsync_offset_lo:8;
-       u16 hsync_offset_hi:2;
-       u16 hsync_pulse_width_lo:8;
-       u16 hsync_pulse_width_hi:2;
-       u16 hsync_positive:1;
-       u16 rsvd_1:3;
-       u8  vactive_lo:8;
-       u16 vactive_hi:4;
-       u16 vblank_lo:8;
-       u16 vblank_hi:4;
-       u16 vsync_offset_lo:4;
-       u16 vsync_offset_hi:2;
-       u16 vsync_pulse_width_lo:4;
-       u16 vsync_pulse_width_hi:2;
-       u16 vsync_positive:1;
-       u16 rsvd_2:3;
-} __packed;
-
-struct mrst_panel_descriptor_v1 {
-       u32 Panel_Port_Control; /* 1 dword, Register 0x61180 if LVDS */
-                               /* 0x61190 if MIPI */
-       u32 Panel_Power_On_Sequencing;/*1 dword,Register 0x61208,*/
-       u32 Panel_Power_Off_Sequencing;/*1 dword,Register 0x6120C,*/
-       u32 Panel_Power_Cycle_Delay_and_Reference_Divisor;/* 1 dword */
-                                               /* Register 0x61210 */
-       struct mrst_timing_info DTD;/*18 bytes, Standard definition */
-       u16 Panel_Backlight_Inverter_Descriptor;/* 16 bits, as follows */
-                               /* Bit 0, Frequency, 15 bits,0 - 32767Hz */
-                       /* Bit 15, Polarity, 1 bit, 0: Normal, 1: Inverted */
-       u16 Panel_MIPI_Display_Descriptor;
-                       /*16 bits, Defined as follows: */
-                       /* if MIPI, 0x0000 if LVDS */
-                       /* Bit 0, Type, 2 bits, */
-                       /* 0: Type-1, */
-                       /* 1: Type-2, */
-                       /* 2: Type-3, */
-                       /* 3: Type-4 */
-                       /* Bit 2, Pixel Format, 4 bits */
-                       /* Bit0: 16bpp (not supported in LNC), */
-                       /* Bit1: 18bpp loosely packed, */
-                       /* Bit2: 18bpp packed, */
-                       /* Bit3: 24bpp */
-                       /* Bit 6, Reserved, 2 bits, 00b */
-                       /* Bit 8, Minimum Supported Frame Rate, 6 bits, 0 - 63Hz */
-                       /* Bit 14, Reserved, 2 bits, 00b */
-} __packed;
-
-struct mrst_panel_descriptor_v2 {
-       u32 Panel_Port_Control; /* 1 dword, Register 0x61180 if LVDS */
-                               /* 0x61190 if MIPI */
-       u32 Panel_Power_On_Sequencing;/*1 dword,Register 0x61208,*/
-       u32 Panel_Power_Off_Sequencing;/*1 dword,Register 0x6120C,*/
-       u8 Panel_Power_Cycle_Delay_and_Reference_Divisor;/* 1 byte */
-                                               /* Register 0x61210 */
-       struct mrst_timing_info DTD;/*18 bytes, Standard definition */
-       u16 Panel_Backlight_Inverter_Descriptor;/*16 bits, as follows*/
-                               /*Bit 0, Frequency, 16 bits, 0 - 32767Hz*/
-       u8 Panel_Initial_Brightness;/* [7:0] 0 - 100% */
-                       /*Bit 7, Polarity, 1 bit,0: Normal, 1: Inverted*/
-       u16 Panel_MIPI_Display_Descriptor;
-                       /*16 bits, Defined as follows: */
-                       /* if MIPI, 0x0000 if LVDS */
-                       /* Bit 0, Type, 2 bits, */
-                       /* 0: Type-1, */
-                       /* 1: Type-2, */
-                       /* 2: Type-3, */
-                       /* 3: Type-4 */
-                       /* Bit 2, Pixel Format, 4 bits */
-                       /* Bit0: 16bpp (not supported in LNC), */
-                       /* Bit1: 18bpp loosely packed, */
-                       /* Bit2: 18bpp packed, */
-                       /* Bit3: 24bpp */
-                       /* Bit 6, Reserved, 2 bits, 00b */
-                       /* Bit 8, Minimum Supported Frame Rate, 6 bits, 0 - 63Hz */
-                       /* Bit 14, Reserved, 2 bits, 00b */
-} __packed;
-
-union mrst_panel_rx {
-       struct {
-               u16 NumberOfLanes:2; /*Num of Lanes, 2 bits,0 = 1 lane,*/
-                       /* 1 = 2 lanes, 2 = 3 lanes, 3 = 4 lanes. */
-               u16 MaxLaneFreq:3; /* 0: 100MHz, 1: 200MHz, 2: 300MHz, */
-               /*3: 400MHz, 4: 500MHz, 5: 600MHz, 6: 700MHz, 7: 800MHz.*/
-               u16 SupportedVideoTransferMode:2; /*0: Non-burst only */
-                                       /* 1: Burst and non-burst */
-                                       /* 2/3: Reserved */
-               u16 HSClkBehavior:1; /*0: Continuous, 1: Non-continuous*/
-               u16 DuoDisplaySupport:1; /*1 bit,0: No, 1: Yes*/
-               u16 ECC_ChecksumCapabilities:1;/*1 bit,0: No, 1: Yes*/
-               u16 BidirectionalCommunication:1;/*1 bit,0: No, 1: Yes */
-               u16 Rsvd:5;/*5 bits,00000b */
-       } panelrx;
-       u16 panel_receiver;
-} __packed;
-
-struct mrst_gct_v1 {
-       union { /*8 bits,Defined as follows: */
-               struct {
-                       u8 PanelType:4; /*4 bits, Bit field for panels*/
-                                       /* 0 - 3: 0 = LVDS, 1 = MIPI*/
-                                       /*2 bits,Specifies which of the*/
-                       u8 BootPanelIndex:2;
-                                       /* 4 panels to use by default*/
-                       u8 BootMIPI_DSI_RxIndex:2;/*Specifies which of*/
-                                       /* the 4 MIPI DSI receivers to use*/
-               } PD;
-               u8 PanelDescriptor;
-       };
-       struct mrst_panel_descriptor_v1 panel[4];/*panel descrs,38 bytes each*/
-       union mrst_panel_rx panelrx[4]; /* panel receivers*/
-} __packed;
-
-struct mrst_gct_v2 {
-       union { /*8 bits,Defined as follows: */
-               struct {
-                       u8 PanelType:4; /*4 bits, Bit field for panels*/
-                                       /* 0 - 3: 0 = LVDS, 1 = MIPI*/
-                                       /*2 bits,Specifies which of the*/
-                       u8 BootPanelIndex:2;
-                                       /* 4 panels to use by default*/
-                       u8 BootMIPI_DSI_RxIndex:2;/*Specifies which of*/
-                                       /* the 4 MIPI DSI receivers to use*/
-               } PD;
-               u8 PanelDescriptor;
-       };
-       struct mrst_panel_descriptor_v2 panel[4];/*panel descrs,38 bytes each*/
-       union mrst_panel_rx panelrx[4]; /* panel receivers*/
-} __packed;
-
-struct mrst_gct_data {
-       u8 bpi; /* boot panel index, number of panel used during boot */
-       u8 pt; /* panel type, 4 bit field, 0=lvds, 1=mipi */
-       struct mrst_timing_info DTD; /* timing info for the selected panel */
-       u32 Panel_Port_Control;
-       u32 PP_On_Sequencing;/*1 dword,Register 0x61208,*/
-       u32 PP_Off_Sequencing;/*1 dword,Register 0x6120C,*/
-       u32 PP_Cycle_Delay;
-       u16 Panel_Backlight_Inverter_Descriptor;
-       u16 Panel_MIPI_Display_Descriptor;
-} __packed;
-
-#define MODE_SETTING_IN_CRTC           0x1
-#define MODE_SETTING_IN_ENCODER                0x2
-#define MODE_SETTING_ON_GOING          0x3
-#define MODE_SETTING_IN_DSR            0x4
-#define MODE_SETTING_ENCODER_DONE      0x8
-
-#define GCT_R10_HEADER_SIZE            16
-#define GCT_R10_DISPLAY_DESC_SIZE      28
-
-/*
- *     Moorestown HDMI interfaces
- */
-
-struct mrst_hdmi_dev {
-       struct pci_dev *dev;
-       void __iomem *regs;
-       unsigned int mmio, mmio_len;
-       int dpms_mode;
-       struct hdmi_i2c_dev *i2c_dev;
-
-       /* register state */
-       u32 saveDPLL_CTRL;
-       u32 saveDPLL_DIV_CTRL;
-       u32 saveDPLL_ADJUST;
-       u32 saveDPLL_UPDATE;
-       u32 saveDPLL_CLK_ENABLE;
-       u32 savePCH_HTOTAL_B;
-       u32 savePCH_HBLANK_B;
-       u32 savePCH_HSYNC_B;
-       u32 savePCH_VTOTAL_B;
-       u32 savePCH_VBLANK_B;
-       u32 savePCH_VSYNC_B;
-       u32 savePCH_PIPEBCONF;
-       u32 savePCH_PIPEBSRC;
-};
-
-extern void mrst_hdmi_setup(struct drm_device *dev);
-extern void mrst_hdmi_teardown(struct drm_device *dev);
-extern int  mrst_hdmi_i2c_init(struct pci_dev *dev);
-extern void mrst_hdmi_i2c_exit(struct pci_dev *dev);
-extern void mrst_hdmi_save(struct drm_device *dev);
-extern void mrst_hdmi_restore(struct drm_device *dev);
-extern void mrst_hdmi_init(struct drm_device *dev, struct psb_intel_mode_device *mode_dev);
diff --git a/drivers/staging/gma500/mrst_crtc.c b/drivers/staging/gma500/mrst_crtc.c
deleted file mode 100644 (file)
index 980837e..0000000
+++ /dev/null
@@ -1,604 +0,0 @@
-/*
- * Copyright Â© 2009 Intel Corporation
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#include <linux/i2c.h>
-#include <linux/pm_runtime.h>
-
-#include <drm/drmP.h>
-#include "framebuffer.h"
-#include "psb_drv.h"
-#include "psb_intel_drv.h"
-#include "psb_intel_reg.h"
-#include "psb_intel_display.h"
-#include "power.h"
-
-struct psb_intel_range_t {
-       int min, max;
-};
-
-struct mrst_limit_t {
-       struct psb_intel_range_t dot, m, p1;
-};
-
-struct mrst_clock_t {
-       /* derived values */
-       int dot;
-       int m;
-       int p1;
-};
-
-#define MRST_LIMIT_LVDS_100L       0
-#define MRST_LIMIT_LVDS_83         1
-#define MRST_LIMIT_LVDS_100        2
-
-#define MRST_DOT_MIN             19750
-#define MRST_DOT_MAX             120000
-#define MRST_M_MIN_100L                    20
-#define MRST_M_MIN_100             10
-#define MRST_M_MIN_83              12
-#define MRST_M_MAX_100L                    34
-#define MRST_M_MAX_100             17
-#define MRST_M_MAX_83              20
-#define MRST_P1_MIN                2
-#define MRST_P1_MAX_0              7
-#define MRST_P1_MAX_1              8
-
-static const struct mrst_limit_t mrst_limits[] = {
-       {                       /* MRST_LIMIT_LVDS_100L */
-        .dot = {.min = MRST_DOT_MIN, .max = MRST_DOT_MAX},
-        .m = {.min = MRST_M_MIN_100L, .max = MRST_M_MAX_100L},
-        .p1 = {.min = MRST_P1_MIN, .max = MRST_P1_MAX_1},
-        },
-       {                       /* MRST_LIMIT_LVDS_83L */
-        .dot = {.min = MRST_DOT_MIN, .max = MRST_DOT_MAX},
-        .m = {.min = MRST_M_MIN_83, .max = MRST_M_MAX_83},
-        .p1 = {.min = MRST_P1_MIN, .max = MRST_P1_MAX_0},
-        },
-       {                       /* MRST_LIMIT_LVDS_100 */
-        .dot = {.min = MRST_DOT_MIN, .max = MRST_DOT_MAX},
-        .m = {.min = MRST_M_MIN_100, .max = MRST_M_MAX_100},
-        .p1 = {.min = MRST_P1_MIN, .max = MRST_P1_MAX_1},
-        },
-};
-
-#define MRST_M_MIN         10
-static const u32 mrst_m_converts[] = {
-       0x2B, 0x15, 0x2A, 0x35, 0x1A, 0x0D, 0x26, 0x33, 0x19, 0x2C,
-       0x36, 0x3B, 0x1D, 0x2E, 0x37, 0x1B, 0x2D, 0x16, 0x0B, 0x25,
-       0x12, 0x09, 0x24, 0x32, 0x39, 0x1c,
-};
-
-static const struct mrst_limit_t *mrst_limit(struct drm_crtc *crtc)
-{
-       const struct mrst_limit_t *limit = NULL;
-       struct drm_device *dev = crtc->dev;
-       struct drm_psb_private *dev_priv = dev->dev_private;
-
-       if (psb_intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)
-           || psb_intel_pipe_has_type(crtc, INTEL_OUTPUT_MIPI)) {
-               switch (dev_priv->core_freq) {
-               case 100:
-                       limit = &mrst_limits[MRST_LIMIT_LVDS_100L];
-                       break;
-               case 166:
-                       limit = &mrst_limits[MRST_LIMIT_LVDS_83];
-                       break;
-               case 200:
-                       limit = &mrst_limits[MRST_LIMIT_LVDS_100];
-                       break;
-               }
-       } else {
-               limit = NULL;
-               dev_err(dev->dev, "mrst_limit Wrong display type.\n");
-       }
-
-       return limit;
-}
-
-/** Derive the pixel clock for the given refclk and divisors for 8xx chips. */
-static void mrst_clock(int refclk, struct mrst_clock_t *clock)
-{
-       clock->dot = (refclk * clock->m) / (14 * clock->p1);
-}
-
-void mrstPrintPll(char *prefix, struct mrst_clock_t *clock)
-{
-       pr_debug("%s: dotclock = %d,  m = %d, p1 = %d.\n",
-            prefix, clock->dot, clock->m, clock->p1);
-}
-
-/**
- * Returns a set of divisors for the desired target clock with the given refclk,
- * or FALSE.  Divisor values are the actual divisors for
- */
-static bool
-mrstFindBestPLL(struct drm_crtc *crtc, int target, int refclk,
-               struct mrst_clock_t *best_clock)
-{
-       struct mrst_clock_t clock;
-       const struct mrst_limit_t *limit = mrst_limit(crtc);
-       int err = target;
-
-       memset(best_clock, 0, sizeof(*best_clock));
-
-       for (clock.m = limit->m.min; clock.m <= limit->m.max; clock.m++) {
-               for (clock.p1 = limit->p1.min; clock.p1 <= limit->p1.max;
-                    clock.p1++) {
-                       int this_err;
-
-                       mrst_clock(refclk, &clock);
-
-                       this_err = abs(clock.dot - target);
-                       if (this_err < err) {
-                               *best_clock = clock;
-                               err = this_err;
-                       }
-               }
-       }
-       dev_dbg(crtc->dev->dev, "mrstFindBestPLL err = %d.\n", err);
-       return err != target;
-}
-
-/**
- * Sets the power management mode of the pipe and plane.
- *
- * This code should probably grow support for turning the cursor off and back
- * on appropriately at the same time as we're turning the pipe off/on.
- */
-static void mrst_crtc_dpms(struct drm_crtc *crtc, int mode)
-{
-       struct drm_device *dev = crtc->dev;
-       struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
-       int pipe = psb_intel_crtc->pipe;
-       int dpll_reg = (pipe == 0) ? MRST_DPLL_A : DPLL_B;
-       int dspcntr_reg = (pipe == 0) ? DSPACNTR : DSPBCNTR;
-       int dspbase_reg = (pipe == 0) ? MRST_DSPABASE : DSPBBASE;
-       int pipeconf_reg = (pipe == 0) ? PIPEACONF : PIPEBCONF;
-       u32 temp;
-       bool enabled;
-
-       if (!gma_power_begin(dev, true))
-               return;
-
-       /* XXX: When our outputs are all unaware of DPMS modes other than off
-        * and on, we should map those modes to DRM_MODE_DPMS_OFF in the CRTC.
-        */
-       switch (mode) {
-       case DRM_MODE_DPMS_ON:
-       case DRM_MODE_DPMS_STANDBY:
-       case DRM_MODE_DPMS_SUSPEND:
-               /* Enable the DPLL */
-               temp = REG_READ(dpll_reg);
-               if ((temp & DPLL_VCO_ENABLE) == 0) {
-                       REG_WRITE(dpll_reg, temp);
-                       REG_READ(dpll_reg);
-                       /* Wait for the clocks to stabilize. */
-                       udelay(150);
-                       REG_WRITE(dpll_reg, temp | DPLL_VCO_ENABLE);
-                       REG_READ(dpll_reg);
-                       /* Wait for the clocks to stabilize. */
-                       udelay(150);
-                       REG_WRITE(dpll_reg, temp | DPLL_VCO_ENABLE);
-                       REG_READ(dpll_reg);
-                       /* Wait for the clocks to stabilize. */
-                       udelay(150);
-               }
-               /* Enable the pipe */
-               temp = REG_READ(pipeconf_reg);
-               if ((temp & PIPEACONF_ENABLE) == 0)
-                       REG_WRITE(pipeconf_reg, temp | PIPEACONF_ENABLE);
-               /* Enable the plane */
-               temp = REG_READ(dspcntr_reg);
-               if ((temp & DISPLAY_PLANE_ENABLE) == 0) {
-                       REG_WRITE(dspcntr_reg,
-                                 temp | DISPLAY_PLANE_ENABLE);
-                       /* Flush the plane changes */
-                       REG_WRITE(dspbase_reg, REG_READ(dspbase_reg));
-               }
-
-               psb_intel_crtc_load_lut(crtc);
-
-               /* Give the overlay scaler a chance to enable
-                  if it's on this pipe */
-               /* psb_intel_crtc_dpms_video(crtc, true); TODO */
-               break;
-       case DRM_MODE_DPMS_OFF:
-               /* Give the overlay scaler a chance to disable
-                * if it's on this pipe */
-               /* psb_intel_crtc_dpms_video(crtc, FALSE); TODO */
-
-               /* Disable the VGA plane that we never use */
-               REG_WRITE(VGACNTRL, VGA_DISP_DISABLE);
-               /* Disable display plane */
-               temp = REG_READ(dspcntr_reg);
-               if ((temp & DISPLAY_PLANE_ENABLE) != 0) {
-                       REG_WRITE(dspcntr_reg,
-                                 temp & ~DISPLAY_PLANE_ENABLE);
-                       /* Flush the plane changes */
-                       REG_WRITE(dspbase_reg, REG_READ(dspbase_reg));
-                       REG_READ(dspbase_reg);
-               }
-
-               /* Next, disable display pipes */
-               temp = REG_READ(pipeconf_reg);
-               if ((temp & PIPEACONF_ENABLE) != 0) {
-                       REG_WRITE(pipeconf_reg, temp & ~PIPEACONF_ENABLE);
-                       REG_READ(pipeconf_reg);
-               }
-               /* Wait for for the pipe disable to take effect. */
-               psb_intel_wait_for_vblank(dev);
-
-               temp = REG_READ(dpll_reg);
-               if ((temp & DPLL_VCO_ENABLE) != 0) {
-                       REG_WRITE(dpll_reg, temp & ~DPLL_VCO_ENABLE);
-                       REG_READ(dpll_reg);
-               }
-
-               /* Wait for the clocks to turn off. */
-               udelay(150);
-               break;
-       }
-
-       enabled = crtc->enabled && mode != DRM_MODE_DPMS_OFF;
-
-       /*Set FIFO Watermarks*/
-       REG_WRITE(DSPARB, 0x3FFF);
-       REG_WRITE(DSPFW1, 0x3F88080A);
-       REG_WRITE(DSPFW2, 0x0b060808);
-       REG_WRITE(DSPFW3, 0x0);
-       REG_WRITE(DSPFW4, 0x08030404);
-       REG_WRITE(DSPFW5, 0x04040404);
-       REG_WRITE(DSPFW6, 0x78);
-       REG_WRITE(0x70400, REG_READ(0x70400) | 0x4000);
-       /* Must write Bit 14 of the Chicken Bit Register */
-
-       gma_power_end(dev);
-}
-
-/**
- * Return the pipe currently connected to the panel fitter,
- * or -1 if the panel fitter is not present or not in use
- */
-static int mrst_panel_fitter_pipe(struct drm_device *dev)
-{
-       u32 pfit_control;
-
-       pfit_control = REG_READ(PFIT_CONTROL);
-
-       /* See if the panel fitter is in use */
-       if ((pfit_control & PFIT_ENABLE) == 0)
-               return -1;
-       return (pfit_control >> 29) & 3;
-}
-
-static int mrst_crtc_mode_set(struct drm_crtc *crtc,
-                             struct drm_display_mode *mode,
-                             struct drm_display_mode *adjusted_mode,
-                             int x, int y,
-                             struct drm_framebuffer *old_fb)
-{
-       struct drm_device *dev = crtc->dev;
-       struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
-       struct drm_psb_private *dev_priv = dev->dev_private;
-       int pipe = psb_intel_crtc->pipe;
-       int fp_reg = (pipe == 0) ? MRST_FPA0 : FPB0;
-       int dpll_reg = (pipe == 0) ? MRST_DPLL_A : DPLL_B;
-       int dspcntr_reg = (pipe == 0) ? DSPACNTR : DSPBCNTR;
-       int pipeconf_reg = (pipe == 0) ? PIPEACONF : PIPEBCONF;
-       int htot_reg = (pipe == 0) ? HTOTAL_A : HTOTAL_B;
-       int hblank_reg = (pipe == 0) ? HBLANK_A : HBLANK_B;
-       int hsync_reg = (pipe == 0) ? HSYNC_A : HSYNC_B;
-       int vtot_reg = (pipe == 0) ? VTOTAL_A : VTOTAL_B;
-       int vblank_reg = (pipe == 0) ? VBLANK_A : VBLANK_B;
-       int vsync_reg = (pipe == 0) ? VSYNC_A : VSYNC_B;
-       int pipesrc_reg = (pipe == 0) ? PIPEASRC : PIPEBSRC;
-       int refclk = 0;
-       struct mrst_clock_t clock;
-       u32 dpll = 0, fp = 0, dspcntr, pipeconf;
-       bool ok, is_sdvo = false;
-       bool is_crt = false, is_lvds = false, is_tv = false;
-       bool is_mipi = false;
-       struct drm_mode_config *mode_config = &dev->mode_config;
-       struct psb_intel_output *psb_intel_output = NULL;
-       uint64_t scalingType = DRM_MODE_SCALE_FULLSCREEN;
-       struct drm_encoder *encoder;
-
-       if (!gma_power_begin(dev, true))
-               return 0;
-
-       memcpy(&psb_intel_crtc->saved_mode,
-               mode,
-               sizeof(struct drm_display_mode));
-       memcpy(&psb_intel_crtc->saved_adjusted_mode,
-               adjusted_mode,
-               sizeof(struct drm_display_mode));
-
-       list_for_each_entry(encoder, &mode_config->encoder_list, head) {
-
-               if (encoder->crtc != crtc)
-                       continue;
-
-               psb_intel_output = enc_to_psb_intel_output(encoder);
-               switch (psb_intel_output->type) {
-               case INTEL_OUTPUT_LVDS:
-                       is_lvds = true;
-                       break;
-               case INTEL_OUTPUT_SDVO:
-                       is_sdvo = true;
-                       break;
-               case INTEL_OUTPUT_TVOUT:
-                       is_tv = true;
-                       break;
-               case INTEL_OUTPUT_ANALOG:
-                       is_crt = true;
-                       break;
-               case INTEL_OUTPUT_MIPI:
-                       is_mipi = true;
-                       break;
-               }
-       }
-
-       /* Disable the VGA plane that we never use */
-       REG_WRITE(VGACNTRL, VGA_DISP_DISABLE);
-
-       /* Disable the panel fitter if it was on our pipe */
-       if (mrst_panel_fitter_pipe(dev) == pipe)
-               REG_WRITE(PFIT_CONTROL, 0);
-
-       REG_WRITE(pipesrc_reg,
-                 ((mode->crtc_hdisplay - 1) << 16) |
-                 (mode->crtc_vdisplay - 1));
-
-       if (psb_intel_output)
-               drm_connector_property_get_value(&psb_intel_output->base,
-                       dev->mode_config.scaling_mode_property, &scalingType);
-
-       if (scalingType == DRM_MODE_SCALE_NO_SCALE) {
-               /* Moorestown doesn't have register support for centering so
-                * we need to mess with the h/vblank and h/vsync start and
-                * ends to get centering */
-               int offsetX = 0, offsetY = 0;
-
-               offsetX = (adjusted_mode->crtc_hdisplay -
-                          mode->crtc_hdisplay) / 2;
-               offsetY = (adjusted_mode->crtc_vdisplay -
-                          mode->crtc_vdisplay) / 2;
-
-               REG_WRITE(htot_reg, (mode->crtc_hdisplay - 1) |
-                       ((adjusted_mode->crtc_htotal - 1) << 16));
-               REG_WRITE(vtot_reg, (mode->crtc_vdisplay - 1) |
-                       ((adjusted_mode->crtc_vtotal - 1) << 16));
-               REG_WRITE(hblank_reg,
-                       (adjusted_mode->crtc_hblank_start - offsetX - 1) |
-                       ((adjusted_mode->crtc_hblank_end - offsetX - 1) << 16));
-               REG_WRITE(hsync_reg,
-                       (adjusted_mode->crtc_hsync_start - offsetX - 1) |
-                       ((adjusted_mode->crtc_hsync_end - offsetX - 1) << 16));
-               REG_WRITE(vblank_reg,
-                       (adjusted_mode->crtc_vblank_start - offsetY - 1) |
-                       ((adjusted_mode->crtc_vblank_end - offsetY - 1) << 16));
-               REG_WRITE(vsync_reg,
-                       (adjusted_mode->crtc_vsync_start - offsetY - 1) |
-                       ((adjusted_mode->crtc_vsync_end - offsetY - 1) << 16));
-       } else {
-               REG_WRITE(htot_reg, (adjusted_mode->crtc_hdisplay - 1) |
-                       ((adjusted_mode->crtc_htotal - 1) << 16));
-               REG_WRITE(vtot_reg, (adjusted_mode->crtc_vdisplay - 1) |
-                       ((adjusted_mode->crtc_vtotal - 1) << 16));
-               REG_WRITE(hblank_reg, (adjusted_mode->crtc_hblank_start - 1) |
-                       ((adjusted_mode->crtc_hblank_end - 1) << 16));
-               REG_WRITE(hsync_reg, (adjusted_mode->crtc_hsync_start - 1) |
-                       ((adjusted_mode->crtc_hsync_end - 1) << 16));
-               REG_WRITE(vblank_reg, (adjusted_mode->crtc_vblank_start - 1) |
-                       ((adjusted_mode->crtc_vblank_end - 1) << 16));
-               REG_WRITE(vsync_reg, (adjusted_mode->crtc_vsync_start - 1) |
-                       ((adjusted_mode->crtc_vsync_end - 1) << 16));
-       }
-
-       /* Flush the plane changes */
-       {
-               struct drm_crtc_helper_funcs *crtc_funcs =
-                   crtc->helper_private;
-               crtc_funcs->mode_set_base(crtc, x, y, old_fb);
-       }
-
-       /* setup pipeconf */
-       pipeconf = REG_READ(pipeconf_reg);
-
-       /* Set up the display plane register */
-       dspcntr = REG_READ(dspcntr_reg);
-       dspcntr |= DISPPLANE_GAMMA_ENABLE;
-
-       if (pipe == 0)
-               dspcntr |= DISPPLANE_SEL_PIPE_A;
-       else
-               dspcntr |= DISPPLANE_SEL_PIPE_B;
-
-       dev_priv->dspcntr = dspcntr |= DISPLAY_PLANE_ENABLE;
-       dev_priv->pipeconf = pipeconf |= PIPEACONF_ENABLE;
-
-       if (is_mipi)
-               goto mrst_crtc_mode_set_exit;
-
-       refclk = dev_priv->core_freq * 1000;
-
-       dpll = 0;               /*BIT16 = 0 for 100MHz reference */
-
-       ok = mrstFindBestPLL(crtc, adjusted_mode->clock, refclk, &clock);
-
-       if (!ok) {
-               dev_dbg(dev->dev, "mrstFindBestPLL fail in mrst_crtc_mode_set.\n");
-       } else {
-               dev_dbg(dev->dev, "mrst_crtc_mode_set pixel clock = %d,"
-                        "m = %x, p1 = %x.\n", clock.dot, clock.m,
-                        clock.p1);
-       }
-
-       fp = mrst_m_converts[(clock.m - MRST_M_MIN)] << 8;
-
-       dpll |= DPLL_VGA_MODE_DIS;
-
-
-       dpll |= DPLL_VCO_ENABLE;
-
-       if (is_lvds)
-               dpll |= DPLLA_MODE_LVDS;
-       else
-               dpll |= DPLLB_MODE_DAC_SERIAL;
-
-       if (is_sdvo) {
-               int sdvo_pixel_multiply =
-                   adjusted_mode->clock / mode->clock;
-
-               dpll |= DPLL_DVO_HIGH_SPEED;
-               dpll |=
-                   (sdvo_pixel_multiply -
-                    1) << SDVO_MULTIPLIER_SHIFT_HIRES;
-       }
-
-
-       /* compute bitmask from p1 value */
-       dpll |= (1 << (clock.p1 - 2)) << 17;
-
-       dpll |= DPLL_VCO_ENABLE;
-
-       mrstPrintPll("chosen", &clock);
-
-       if (dpll & DPLL_VCO_ENABLE) {
-               REG_WRITE(fp_reg, fp);
-               REG_WRITE(dpll_reg, dpll & ~DPLL_VCO_ENABLE);
-               REG_READ(dpll_reg);
-               /* Check the DPLLA lock bit PIPEACONF[29] */
-               udelay(150);
-       }
-
-       REG_WRITE(fp_reg, fp);
-       REG_WRITE(dpll_reg, dpll);
-       REG_READ(dpll_reg);
-       /* Wait for the clocks to stabilize. */
-       udelay(150);
-
-       /* write it again -- the BIOS does, after all */
-       REG_WRITE(dpll_reg, dpll);
-       REG_READ(dpll_reg);
-       /* Wait for the clocks to stabilize. */
-       udelay(150);
-
-       REG_WRITE(pipeconf_reg, pipeconf);
-       REG_READ(pipeconf_reg);
-       psb_intel_wait_for_vblank(dev);
-
-       REG_WRITE(dspcntr_reg, dspcntr);
-       psb_intel_wait_for_vblank(dev);
-
-mrst_crtc_mode_set_exit:
-       gma_power_end(dev);
-       return 0;
-}
-
-static bool mrst_crtc_mode_fixup(struct drm_crtc *crtc,
-                                 struct drm_display_mode *mode,
-                                 struct drm_display_mode *adjusted_mode)
-{
-       return true;
-}
-
-int mrst_pipe_set_base(struct drm_crtc *crtc,
-                           int x, int y, struct drm_framebuffer *old_fb)
-{
-       struct drm_device *dev = crtc->dev;
-       struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
-       struct psb_framebuffer *psbfb = to_psb_fb(crtc->fb);
-       int pipe = psb_intel_crtc->pipe;
-       unsigned long start, offset;
-
-       int dspbase = (pipe == 0 ? DSPALINOFF : DSPBBASE);
-       int dspsurf = (pipe == 0 ? DSPASURF : DSPBSURF);
-       int dspstride = (pipe == 0) ? DSPASTRIDE : DSPBSTRIDE;
-       int dspcntr_reg = (pipe == 0) ? DSPACNTR : DSPBCNTR;
-       u32 dspcntr;
-       int ret = 0;
-
-       /* no fb bound */
-       if (!crtc->fb) {
-               dev_dbg(dev->dev, "No FB bound\n");
-               return 0;
-       }
-
-       if (!gma_power_begin(dev, true))
-               return 0;
-
-       start = psbfb->gtt->offset;
-       offset = y * crtc->fb->pitches[0] + x * (crtc->fb->bits_per_pixel / 8);
-
-       REG_WRITE(dspstride, crtc->fb->pitches[0]);
-
-       dspcntr = REG_READ(dspcntr_reg);
-       dspcntr &= ~DISPPLANE_PIXFORMAT_MASK;
-
-       switch (crtc->fb->bits_per_pixel) {
-       case 8:
-               dspcntr |= DISPPLANE_8BPP;
-               break;
-       case 16:
-               if (crtc->fb->depth == 15)
-                       dspcntr |= DISPPLANE_15_16BPP;
-               else
-                       dspcntr |= DISPPLANE_16BPP;
-               break;
-       case 24:
-       case 32:
-               dspcntr |= DISPPLANE_32BPP_NO_ALPHA;
-               break;
-       default:
-               dev_err(dev->dev, "Unknown color depth\n");
-               ret = -EINVAL;
-               goto pipe_set_base_exit;
-       }
-       REG_WRITE(dspcntr_reg, dspcntr);
-
-       REG_WRITE(dspbase, offset);
-       REG_READ(dspbase);
-       REG_WRITE(dspsurf, start);
-       REG_READ(dspsurf);
-
-pipe_set_base_exit:
-       gma_power_end(dev);
-       return ret;
-}
-
-static void mrst_crtc_prepare(struct drm_crtc *crtc)
-{
-       struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
-       crtc_funcs->dpms(crtc, DRM_MODE_DPMS_OFF);
-}
-
-static void mrst_crtc_commit(struct drm_crtc *crtc)
-{
-       struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
-       crtc_funcs->dpms(crtc, DRM_MODE_DPMS_ON);
-}
-
-const struct drm_crtc_helper_funcs mrst_helper_funcs = {
-       .dpms = mrst_crtc_dpms,
-       .mode_fixup = mrst_crtc_mode_fixup,
-       .mode_set = mrst_crtc_mode_set,
-       .mode_set_base = mrst_pipe_set_base,
-       .prepare = mrst_crtc_prepare,
-       .commit = mrst_crtc_commit,
-};
-
diff --git a/drivers/staging/gma500/mrst_device.c b/drivers/staging/gma500/mrst_device.c
deleted file mode 100644 (file)
index 6707faf..0000000
+++ /dev/null
@@ -1,634 +0,0 @@
-/**************************************************************************
- * Copyright (c) 2011, Intel Corporation.
- * All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- **************************************************************************/
-
-#include <linux/backlight.h>
-#include <linux/module.h>
-#include <linux/dmi.h>
-#include <drm/drmP.h>
-#include <drm/drm.h>
-#include "psb_drm.h"
-#include "psb_drv.h"
-#include "psb_reg.h"
-#include "psb_intel_reg.h"
-#include <asm/mrst.h>
-#include <asm/intel_scu_ipc.h>
-#include "mid_bios.h"
-
-static int devtype;
-
-module_param_named(type, devtype, int, 0600);
-MODULE_PARM_DESC(type, "Moorestown/Oaktrail device type");
-
-#define DEVICE_MOORESTOWN              1
-#define DEVICE_OAKTRAIL                        2
-#define DEVICE_MOORESTOWN_MM           3
-
-static int mrst_device_ident(struct drm_device *dev)
-{
-       /* User forced */
-       if (devtype)
-               return devtype;
-       if (dmi_match(DMI_PRODUCT_NAME, "OakTrail") ||
-               dmi_match(DMI_PRODUCT_NAME, "OakTrail platform"))
-               return DEVICE_OAKTRAIL;
-#if defined(CONFIG_X86_MRST)
-       if (dmi_match(DMI_PRODUCT_NAME, "MM") ||
-               dmi_match(DMI_PRODUCT_NAME, "MM 10"))
-               return DEVICE_MOORESTOWN_MM;
-       if (mrst_identify_cpu())
-               return DEVICE_MOORESTOWN;
-#endif
-       return DEVICE_OAKTRAIL;
-}
-
-
-/* IPC message and command defines used to enable/disable mipi panel voltages */
-#define IPC_MSG_PANEL_ON_OFF    0xE9
-#define IPC_CMD_PANEL_ON        1
-#define IPC_CMD_PANEL_OFF       0
-
-static int mrst_output_init(struct drm_device *dev)
-{
-       struct drm_psb_private *dev_priv = dev->dev_private;
-       if (dev_priv->iLVDS_enable)
-               mrst_lvds_init(dev, &dev_priv->mode_dev);
-       else
-               dev_err(dev->dev, "DSI is not supported\n");
-       if (dev_priv->hdmi_priv)
-               mrst_hdmi_init(dev, &dev_priv->mode_dev);
-       return 0;
-}
-
-/*
- *     Provide the low level interfaces for the Moorestown backlight
- */
-
-#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
-
-#define MRST_BLC_MAX_PWM_REG_FREQ          0xFFFF
-#define BLC_PWM_PRECISION_FACTOR 100   /* 10000000 */
-#define BLC_PWM_FREQ_CALC_CONSTANT 32
-#define MHz 1000000
-#define BLC_ADJUSTMENT_MAX 100
-
-static struct backlight_device *mrst_backlight_device;
-static int mrst_brightness;
-
-static int mrst_set_brightness(struct backlight_device *bd)
-{
-       struct drm_device *dev = bl_get_data(mrst_backlight_device);
-       struct drm_psb_private *dev_priv = dev->dev_private;
-       int level = bd->props.brightness;
-       u32 blc_pwm_ctl;
-       u32 max_pwm_blc;
-
-       /* Percentage 1-100% being valid */
-       if (level < 1)
-               level = 1;
-
-       if (gma_power_begin(dev, 0)) {
-               /* Calculate and set the brightness value */
-               max_pwm_blc = REG_READ(BLC_PWM_CTL) >> 16;
-               blc_pwm_ctl = level * max_pwm_blc / 100;
-
-               /* Adjust the backlight level with the percent in
-                * dev_priv->blc_adj1;
-                */
-               blc_pwm_ctl = blc_pwm_ctl * dev_priv->blc_adj1;
-               blc_pwm_ctl = blc_pwm_ctl / 100;
-
-               /* Adjust the backlight level with the percent in
-                * dev_priv->blc_adj2;
-                */
-               blc_pwm_ctl = blc_pwm_ctl * dev_priv->blc_adj2;
-               blc_pwm_ctl = blc_pwm_ctl / 100;
-
-               /* force PWM bit on */
-               REG_WRITE(BLC_PWM_CTL2, (0x80000000 | REG_READ(BLC_PWM_CTL2)));
-               REG_WRITE(BLC_PWM_CTL, (max_pwm_blc << 16) | blc_pwm_ctl);
-               gma_power_end(dev);
-       }
-       mrst_brightness = level;
-       return 0;
-}
-
-static int mrst_get_brightness(struct backlight_device *bd)
-{
-       /* return locally cached var instead of HW read (due to DPST etc.) */
-       /* FIXME: ideally return actual value in case firmware fiddled with
-          it */
-       return mrst_brightness;
-}
-
-static int device_backlight_init(struct drm_device *dev)
-{
-       struct drm_psb_private *dev_priv = dev->dev_private;
-       unsigned long core_clock;
-       u16 bl_max_freq;
-       uint32_t value;
-       uint32_t blc_pwm_precision_factor;
-
-       dev_priv->blc_adj1 = BLC_ADJUSTMENT_MAX;
-       dev_priv->blc_adj2 = BLC_ADJUSTMENT_MAX;
-       bl_max_freq = 256;
-       /* this needs to be set elsewhere */
-       blc_pwm_precision_factor = BLC_PWM_PRECISION_FACTOR;
-
-       core_clock = dev_priv->core_freq;
-
-       value = (core_clock * MHz) / BLC_PWM_FREQ_CALC_CONSTANT;
-       value *= blc_pwm_precision_factor;
-       value /= bl_max_freq;
-       value /= blc_pwm_precision_factor;
-
-       if (value > (unsigned long long)MRST_BLC_MAX_PWM_REG_FREQ)
-                       return -ERANGE;
-
-       if (gma_power_begin(dev, false)) {
-               REG_WRITE(BLC_PWM_CTL2, (0x80000000 | REG_READ(BLC_PWM_CTL2)));
-               REG_WRITE(BLC_PWM_CTL, value | (value << 16));
-               gma_power_end(dev);
-       }
-       return 0;
-}
-
-static const struct backlight_ops mrst_ops = {
-       .get_brightness = mrst_get_brightness,
-       .update_status  = mrst_set_brightness,
-};
-
-int mrst_backlight_init(struct drm_device *dev)
-{
-       struct drm_psb_private *dev_priv = dev->dev_private;
-       int ret;
-       struct backlight_properties props;
-
-       memset(&props, 0, sizeof(struct backlight_properties));
-       props.max_brightness = 100;
-       props.type = BACKLIGHT_PLATFORM;
-
-       mrst_backlight_device = backlight_device_register("mrst-bl",
-                                       NULL, (void *)dev, &mrst_ops, &props);
-
-       if (IS_ERR(mrst_backlight_device))
-               return PTR_ERR(mrst_backlight_device);
-
-       ret = device_backlight_init(dev);
-       if (ret < 0) {
-               backlight_device_unregister(mrst_backlight_device);
-               return ret;
-       }
-       mrst_backlight_device->props.brightness = 100;
-       mrst_backlight_device->props.max_brightness = 100;
-       backlight_update_status(mrst_backlight_device);
-       dev_priv->backlight_device = mrst_backlight_device;
-       return 0;
-}
-
-#endif
-
-/*
- *     Provide the Moorestown specific chip logic and low level methods
- *     for power management
- */
-
-static void mrst_init_pm(struct drm_device *dev)
-{
-}
-
-/**
- *     mrst_save_display_registers     -       save registers lost on suspend
- *     @dev: our DRM device
- *
- *     Save the state we need in order to be able to restore the interface
- *     upon resume from suspend
- */
-static int mrst_save_display_registers(struct drm_device *dev)
-{
-       struct drm_psb_private *dev_priv = dev->dev_private;
-       int i;
-       u32 pp_stat;
-
-       /* Display arbitration control + watermarks */
-       dev_priv->saveDSPARB = PSB_RVDC32(DSPARB);
-       dev_priv->saveDSPFW1 = PSB_RVDC32(DSPFW1);
-       dev_priv->saveDSPFW2 = PSB_RVDC32(DSPFW2);
-       dev_priv->saveDSPFW3 = PSB_RVDC32(DSPFW3);
-       dev_priv->saveDSPFW4 = PSB_RVDC32(DSPFW4);
-       dev_priv->saveDSPFW5 = PSB_RVDC32(DSPFW5);
-       dev_priv->saveDSPFW6 = PSB_RVDC32(DSPFW6);
-       dev_priv->saveCHICKENBIT = PSB_RVDC32(DSPCHICKENBIT);
-
-       /* Pipe & plane A info */
-       dev_priv->savePIPEACONF = PSB_RVDC32(PIPEACONF);
-       dev_priv->savePIPEASRC = PSB_RVDC32(PIPEASRC);
-       dev_priv->saveFPA0 = PSB_RVDC32(MRST_FPA0);
-       dev_priv->saveFPA1 = PSB_RVDC32(MRST_FPA1);
-       dev_priv->saveDPLL_A = PSB_RVDC32(MRST_DPLL_A);
-       dev_priv->saveHTOTAL_A = PSB_RVDC32(HTOTAL_A);
-       dev_priv->saveHBLANK_A = PSB_RVDC32(HBLANK_A);
-       dev_priv->saveHSYNC_A = PSB_RVDC32(HSYNC_A);
-       dev_priv->saveVTOTAL_A = PSB_RVDC32(VTOTAL_A);
-       dev_priv->saveVBLANK_A = PSB_RVDC32(VBLANK_A);
-       dev_priv->saveVSYNC_A = PSB_RVDC32(VSYNC_A);
-       dev_priv->saveBCLRPAT_A = PSB_RVDC32(BCLRPAT_A);
-       dev_priv->saveDSPACNTR = PSB_RVDC32(DSPACNTR);
-       dev_priv->saveDSPASTRIDE = PSB_RVDC32(DSPASTRIDE);
-       dev_priv->saveDSPAADDR = PSB_RVDC32(DSPABASE);
-       dev_priv->saveDSPASURF = PSB_RVDC32(DSPASURF);
-       dev_priv->saveDSPALINOFF = PSB_RVDC32(DSPALINOFF);
-       dev_priv->saveDSPATILEOFF = PSB_RVDC32(DSPATILEOFF);
-
-       /* Save cursor regs */
-       dev_priv->saveDSPACURSOR_CTRL = PSB_RVDC32(CURACNTR);
-       dev_priv->saveDSPACURSOR_BASE = PSB_RVDC32(CURABASE);
-       dev_priv->saveDSPACURSOR_POS = PSB_RVDC32(CURAPOS);
-
-       /* Save palette (gamma) */
-       for (i = 0; i < 256; i++)
-               dev_priv->save_palette_a[i] = PSB_RVDC32(PALETTE_A + (i << 2));
-
-       if (dev_priv->hdmi_priv)
-               mrst_hdmi_save(dev);
-
-       /* Save performance state */
-       dev_priv->savePERF_MODE = PSB_RVDC32(MRST_PERF_MODE);
-
-       /* LVDS state */
-       dev_priv->savePP_CONTROL = PSB_RVDC32(PP_CONTROL);
-       dev_priv->savePFIT_PGM_RATIOS = PSB_RVDC32(PFIT_PGM_RATIOS);
-       dev_priv->savePFIT_AUTO_RATIOS = PSB_RVDC32(PFIT_AUTO_RATIOS);
-       dev_priv->saveBLC_PWM_CTL = PSB_RVDC32(BLC_PWM_CTL);
-       dev_priv->saveBLC_PWM_CTL2 = PSB_RVDC32(BLC_PWM_CTL2);
-       dev_priv->saveLVDS = PSB_RVDC32(LVDS);
-       dev_priv->savePFIT_CONTROL = PSB_RVDC32(PFIT_CONTROL);
-       dev_priv->savePP_ON_DELAYS = PSB_RVDC32(LVDSPP_ON);
-       dev_priv->savePP_OFF_DELAYS = PSB_RVDC32(LVDSPP_OFF);
-       dev_priv->savePP_DIVISOR = PSB_RVDC32(PP_CYCLE);
-
-       /* HW overlay */
-       dev_priv->saveOV_OVADD = PSB_RVDC32(OV_OVADD);
-       dev_priv->saveOV_OGAMC0 = PSB_RVDC32(OV_OGAMC0);
-       dev_priv->saveOV_OGAMC1 = PSB_RVDC32(OV_OGAMC1);
-       dev_priv->saveOV_OGAMC2 = PSB_RVDC32(OV_OGAMC2);
-       dev_priv->saveOV_OGAMC3 = PSB_RVDC32(OV_OGAMC3);
-       dev_priv->saveOV_OGAMC4 = PSB_RVDC32(OV_OGAMC4);
-       dev_priv->saveOV_OGAMC5 = PSB_RVDC32(OV_OGAMC5);
-
-       /* DPST registers */
-       dev_priv->saveHISTOGRAM_INT_CONTROL_REG =
-                                       PSB_RVDC32(HISTOGRAM_INT_CONTROL);
-       dev_priv->saveHISTOGRAM_LOGIC_CONTROL_REG =
-                                       PSB_RVDC32(HISTOGRAM_LOGIC_CONTROL);
-       dev_priv->savePWM_CONTROL_LOGIC = PSB_RVDC32(PWM_CONTROL_LOGIC);
-
-       if (dev_priv->iLVDS_enable) {
-               /* Shut down the panel */
-               PSB_WVDC32(0, PP_CONTROL);
-
-               do {
-                       pp_stat = PSB_RVDC32(PP_STATUS);
-               } while (pp_stat & 0x80000000);
-
-               /* Turn off the plane */
-               PSB_WVDC32(0x58000000, DSPACNTR);
-               /* Trigger the plane disable */
-               PSB_WVDC32(0, DSPASURF);
-
-               /* Wait ~4 ticks */
-               msleep(4);
-
-               /* Turn off pipe */
-               PSB_WVDC32(0x0, PIPEACONF);
-               /* Wait ~8 ticks */
-               msleep(8);
-
-               /* Turn off PLLs */
-               PSB_WVDC32(0, MRST_DPLL_A);
-       }
-       return 0;
-}
-
-/**
- *     mrst_restore_display_registers  -       restore lost register state
- *     @dev: our DRM device
- *
- *     Restore register state that was lost during suspend and resume.
- */
-static int mrst_restore_display_registers(struct drm_device *dev)
-{
-       struct drm_psb_private *dev_priv = dev->dev_private;
-       u32 pp_stat;
-       int i;
-
-       /* Display arbitration + watermarks */
-       PSB_WVDC32(dev_priv->saveDSPARB, DSPARB);
-       PSB_WVDC32(dev_priv->saveDSPFW1, DSPFW1);
-       PSB_WVDC32(dev_priv->saveDSPFW2, DSPFW2);
-       PSB_WVDC32(dev_priv->saveDSPFW3, DSPFW3);
-       PSB_WVDC32(dev_priv->saveDSPFW4, DSPFW4);
-       PSB_WVDC32(dev_priv->saveDSPFW5, DSPFW5);
-       PSB_WVDC32(dev_priv->saveDSPFW6, DSPFW6);
-       PSB_WVDC32(dev_priv->saveCHICKENBIT, DSPCHICKENBIT);
-
-       /* Make sure VGA plane is off. it initializes to on after reset!*/
-       PSB_WVDC32(0x80000000, VGACNTRL);
-
-       /* set the plls */
-       PSB_WVDC32(dev_priv->saveFPA0, MRST_FPA0);
-       PSB_WVDC32(dev_priv->saveFPA1, MRST_FPA1);
-
-       /* Actually enable it */
-       PSB_WVDC32(dev_priv->saveDPLL_A, MRST_DPLL_A);
-       DRM_UDELAY(150);
-
-       /* Restore mode */
-       PSB_WVDC32(dev_priv->saveHTOTAL_A, HTOTAL_A);
-       PSB_WVDC32(dev_priv->saveHBLANK_A, HBLANK_A);
-       PSB_WVDC32(dev_priv->saveHSYNC_A, HSYNC_A);
-       PSB_WVDC32(dev_priv->saveVTOTAL_A, VTOTAL_A);
-       PSB_WVDC32(dev_priv->saveVBLANK_A, VBLANK_A);
-       PSB_WVDC32(dev_priv->saveVSYNC_A, VSYNC_A);
-       PSB_WVDC32(dev_priv->savePIPEASRC, PIPEASRC);
-       PSB_WVDC32(dev_priv->saveBCLRPAT_A, BCLRPAT_A);
-
-       /* Restore performance mode*/
-       PSB_WVDC32(dev_priv->savePERF_MODE, MRST_PERF_MODE);
-
-       /* Enable the pipe*/
-       if (dev_priv->iLVDS_enable)
-               PSB_WVDC32(dev_priv->savePIPEACONF, PIPEACONF);
-
-       /* Set up the plane*/
-       PSB_WVDC32(dev_priv->saveDSPALINOFF, DSPALINOFF);
-       PSB_WVDC32(dev_priv->saveDSPASTRIDE, DSPASTRIDE);
-       PSB_WVDC32(dev_priv->saveDSPATILEOFF, DSPATILEOFF);
-
-       /* Enable the plane */
-       PSB_WVDC32(dev_priv->saveDSPACNTR, DSPACNTR);
-       PSB_WVDC32(dev_priv->saveDSPASURF, DSPASURF);
-
-       /* Enable Cursor A */
-       PSB_WVDC32(dev_priv->saveDSPACURSOR_CTRL, CURACNTR);
-       PSB_WVDC32(dev_priv->saveDSPACURSOR_POS, CURAPOS);
-       PSB_WVDC32(dev_priv->saveDSPACURSOR_BASE, CURABASE);
-
-       /* Restore palette (gamma) */
-       for (i = 0; i < 256; i++)
-               PSB_WVDC32(dev_priv->save_palette_a[i], PALETTE_A + (i << 2));
-
-       if (dev_priv->hdmi_priv)
-               mrst_hdmi_restore(dev);
-
-       if (dev_priv->iLVDS_enable) {
-               PSB_WVDC32(dev_priv->saveBLC_PWM_CTL2, BLC_PWM_CTL2);
-               PSB_WVDC32(dev_priv->saveLVDS, LVDS); /*port 61180h*/
-               PSB_WVDC32(dev_priv->savePFIT_CONTROL, PFIT_CONTROL);
-               PSB_WVDC32(dev_priv->savePFIT_PGM_RATIOS, PFIT_PGM_RATIOS);
-               PSB_WVDC32(dev_priv->savePFIT_AUTO_RATIOS, PFIT_AUTO_RATIOS);
-               PSB_WVDC32(dev_priv->saveBLC_PWM_CTL, BLC_PWM_CTL);
-               PSB_WVDC32(dev_priv->savePP_ON_DELAYS, LVDSPP_ON);
-               PSB_WVDC32(dev_priv->savePP_OFF_DELAYS, LVDSPP_OFF);
-               PSB_WVDC32(dev_priv->savePP_DIVISOR, PP_CYCLE);
-               PSB_WVDC32(dev_priv->savePP_CONTROL, PP_CONTROL);
-       }
-
-       /* Wait for cycle delay */
-       do {
-               pp_stat = PSB_RVDC32(PP_STATUS);
-       } while (pp_stat & 0x08000000);
-
-       /* Wait for panel power up */
-       do {
-               pp_stat = PSB_RVDC32(PP_STATUS);
-       } while (pp_stat & 0x10000000);
-
-       /* Restore HW overlay */
-       PSB_WVDC32(dev_priv->saveOV_OVADD, OV_OVADD);
-       PSB_WVDC32(dev_priv->saveOV_OGAMC0, OV_OGAMC0);
-       PSB_WVDC32(dev_priv->saveOV_OGAMC1, OV_OGAMC1);
-       PSB_WVDC32(dev_priv->saveOV_OGAMC2, OV_OGAMC2);
-       PSB_WVDC32(dev_priv->saveOV_OGAMC3, OV_OGAMC3);
-       PSB_WVDC32(dev_priv->saveOV_OGAMC4, OV_OGAMC4);
-       PSB_WVDC32(dev_priv->saveOV_OGAMC5, OV_OGAMC5);
-
-       /* DPST registers */
-       PSB_WVDC32(dev_priv->saveHISTOGRAM_INT_CONTROL_REG,
-                                               HISTOGRAM_INT_CONTROL);
-       PSB_WVDC32(dev_priv->saveHISTOGRAM_LOGIC_CONTROL_REG,
-                                               HISTOGRAM_LOGIC_CONTROL);
-       PSB_WVDC32(dev_priv->savePWM_CONTROL_LOGIC, PWM_CONTROL_LOGIC);
-
-       return 0;
-}
-
-/**
- *     mrst_power_down -       power down the display island
- *     @dev: our DRM device
- *
- *     Power down the display interface of our device
- */
-static int mrst_power_down(struct drm_device *dev)
-{
-       struct drm_psb_private *dev_priv = dev->dev_private;
-       u32 pwr_mask ;
-       u32 pwr_sts;
-
-       pwr_mask = PSB_PWRGT_DISPLAY_MASK;
-       outl(pwr_mask, dev_priv->ospm_base + PSB_PM_SSC);
-
-       while (true) {
-               pwr_sts = inl(dev_priv->ospm_base + PSB_PM_SSS);
-               if ((pwr_sts & pwr_mask) == pwr_mask)
-                       break;
-               else
-                       udelay(10);
-       }
-       return 0;
-}
-
-/*
- * mrst_power_up
- *
- * Restore power to the specified island(s) (powergating)
- */
-static int mrst_power_up(struct drm_device *dev)
-{
-       struct drm_psb_private *dev_priv = dev->dev_private;
-       u32 pwr_mask = PSB_PWRGT_DISPLAY_MASK;
-       u32 pwr_sts, pwr_cnt;
-
-       pwr_cnt = inl(dev_priv->ospm_base + PSB_PM_SSC);
-       pwr_cnt &= ~pwr_mask;
-       outl(pwr_cnt, (dev_priv->ospm_base + PSB_PM_SSC));
-
-       while (true) {
-               pwr_sts = inl(dev_priv->ospm_base + PSB_PM_SSS);
-               if ((pwr_sts & pwr_mask) == 0)
-                       break;
-               else
-                       udelay(10);
-       }
-       return 0;
-}
-
-#if defined(CONFIG_X86_MRST)
-static void mrst_lvds_cache_bl(struct drm_device *dev)
-{
-       struct drm_psb_private *dev_priv = dev->dev_private;
-
-       intel_scu_ipc_ioread8(0x28, &(dev_priv->saveBKLTCNT));
-       intel_scu_ipc_ioread8(0x29, &(dev_priv->saveBKLTREQ));
-       intel_scu_ipc_ioread8(0x2A, &(dev_priv->saveBKLTBRTL));
-}
-
-static void mrst_mm_bl_power(struct drm_device *dev, bool on)
-{
-       struct drm_psb_private *dev_priv = dev->dev_private;
-
-       if (on) {
-               intel_scu_ipc_iowrite8(0x2A, dev_priv->saveBKLTBRTL);
-               intel_scu_ipc_iowrite8(0x28, dev_priv->saveBKLTCNT);
-               intel_scu_ipc_iowrite8(0x29, dev_priv->saveBKLTREQ);
-       } else {
-               intel_scu_ipc_iowrite8(0x2A, 0);
-               intel_scu_ipc_iowrite8(0x28, 0);
-               intel_scu_ipc_iowrite8(0x29, 0);
-       }
-}
-
-static const struct psb_ops mrst_mm_chip_ops = {
-       .name = "Moorestown MM ",
-       .accel_2d = 1,
-       .pipes = 1,
-       .crtcs = 1,
-       .sgx_offset = MRST_SGX_OFFSET,
-
-       .crtc_helper = &mrst_helper_funcs,
-       .crtc_funcs = &psb_intel_crtc_funcs,
-
-       .output_init = mrst_output_init,
-
-       .lvds_bl_power = mrst_mm_bl_power,
-#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
-       .backlight_init = mrst_backlight_init,
-#endif
-
-       .init_pm = mrst_init_pm,
-       .save_regs = mrst_save_display_registers,
-       .restore_regs = mrst_restore_display_registers,
-       .power_down = mrst_power_down,
-       .power_up = mrst_power_up,
-
-       .i2c_bus = 0,
-};
-
-#endif
-
-static void oaktrail_teardown(struct drm_device *dev)
-{
-       mrst_hdmi_teardown(dev);
-}
-
-static const struct psb_ops oaktrail_chip_ops = {
-       .name = "Oaktrail",
-       .accel_2d = 1,
-       .pipes = 2,
-       .crtcs = 2,
-       .sgx_offset = MRST_SGX_OFFSET,
-
-       .chip_setup = mid_chip_setup,
-       .chip_teardown = oaktrail_teardown,
-       .crtc_helper = &mrst_helper_funcs,
-       .crtc_funcs = &psb_intel_crtc_funcs,
-
-       .output_init = mrst_output_init,
-
-#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
-       .backlight_init = mrst_backlight_init,
-#endif
-
-       .init_pm = mrst_init_pm,
-       .save_regs = mrst_save_display_registers,
-       .restore_regs = mrst_restore_display_registers,
-       .power_down = mrst_power_down,
-       .power_up = mrst_power_up,
-
-       .i2c_bus = 1,
-};
-
-/**
- *     mrst_chip_setup         -       perform the initial chip init
- *     @dev: Our drm_device
- *
- *     Figure out which incarnation we are and then scan the firmware for
- *     tables and information.
- */
-static int mrst_chip_setup(struct drm_device *dev)
-{
-       struct drm_psb_private *dev_priv = dev->dev_private;
-
-       switch (mrst_device_ident(dev)) {
-       case DEVICE_OAKTRAIL:
-               /* Dual CRTC, PC compatible, HDMI, I2C #2 */
-               dev_priv->ops = &oaktrail_chip_ops;
-               mrst_hdmi_setup(dev);
-               return mid_chip_setup(dev);
-#if defined(CONFIG_X86_MRST)
-       case DEVICE_MOORESTOWN_MM:
-               /* Single CRTC, No HDMI, I2C #0, BL control */
-               mrst_lvds_cache_bl(dev);
-               dev_priv->ops = &mrst_mm_chip_ops;
-               return mid_chip_setup(dev);
-       case DEVICE_MOORESTOWN:
-               /* Dual CRTC, No HDMI(?), I2C #1 */
-               return mid_chip_setup(dev);
-#endif
-       default:
-               dev_err(dev->dev, "unsupported device type.\n");
-               return -ENODEV;
-       }
-}
-
-const struct psb_ops mrst_chip_ops = {
-       .name = "Moorestown",
-       .accel_2d = 1,
-       .pipes = 2,
-       .crtcs = 2,
-       .sgx_offset = MRST_SGX_OFFSET,
-
-       .chip_setup = mrst_chip_setup,
-       .crtc_helper = &mrst_helper_funcs,
-       .crtc_funcs = &psb_intel_crtc_funcs,
-
-       .output_init = mrst_output_init,
-
-#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
-       .backlight_init = mrst_backlight_init,
-#endif
-
-       .init_pm = mrst_init_pm,
-       .save_regs = mrst_save_display_registers,
-       .restore_regs = mrst_restore_display_registers,
-       .power_down = mrst_power_down,
-       .power_up = mrst_power_up,
-
-       .i2c_bus = 2,
-};
-
diff --git a/drivers/staging/gma500/mrst_hdmi.c b/drivers/staging/gma500/mrst_hdmi.c
deleted file mode 100644 (file)
index e66607e..0000000
+++ /dev/null
@@ -1,852 +0,0 @@
-/*
- * Copyright Â© 2010 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Authors:
- *     Li Peng <peng.li@intel.com>
- */
-
-#include <drm/drmP.h>
-#include <drm/drm.h>
-#include "psb_intel_drv.h"
-#include "psb_intel_reg.h"
-#include "psb_drv.h"
-
-#define HDMI_READ(reg)         readl(hdmi_dev->regs + (reg))
-#define HDMI_WRITE(reg, val)   writel(val, hdmi_dev->regs + (reg))
-
-#define HDMI_HCR       0x1000
-#define HCR_ENABLE_HDCP                (1 << 5)
-#define HCR_ENABLE_AUDIO       (1 << 2)
-#define HCR_ENABLE_PIXEL       (1 << 1)
-#define HCR_ENABLE_TMDS                (1 << 0)
-
-#define HDMI_HICR      0x1004
-#define HDMI_HSR       0x1008
-#define HDMI_HISR      0x100C
-#define HDMI_DETECT_HDP                (1 << 0)
-
-#define HDMI_VIDEO_REG 0x3000
-#define HDMI_UNIT_EN           (1 << 7)
-#define HDMI_MODE_OUTPUT       (1 << 0)
-#define HDMI_HBLANK_A  0x3100
-
-#define HDMI_AUDIO_CTRL        0x4000
-#define HDMI_ENABLE_AUDIO      (1 << 0)
-
-#define PCH_HTOTAL_B   0x3100
-#define PCH_HBLANK_B   0x3104
-#define PCH_HSYNC_B    0x3108
-#define PCH_VTOTAL_B   0x310C
-#define PCH_VBLANK_B   0x3110
-#define PCH_VSYNC_B    0x3114
-#define PCH_PIPEBSRC   0x311C
-
-#define PCH_PIPEB_DSL  0x3800
-#define PCH_PIPEB_SLC  0x3804
-#define PCH_PIPEBCONF  0x3808
-#define PCH_PIPEBSTAT  0x3824
-
-#define CDVO_DFT       0x5000
-#define CDVO_SLEWRATE  0x5004
-#define CDVO_STRENGTH  0x5008
-#define CDVO_RCOMP     0x500C
-
-#define DPLL_CTRL       0x6000
-#define DPLL_PDIV_SHIFT                16
-#define DPLL_PDIV_MASK         (0xf << 16)
-#define DPLL_PWRDN             (1 << 4)
-#define DPLL_RESET             (1 << 3)
-#define DPLL_FASTEN            (1 << 2)
-#define DPLL_ENSTAT            (1 << 1)
-#define DPLL_DITHEN            (1 << 0)
-
-#define DPLL_DIV_CTRL   0x6004
-#define DPLL_CLKF_MASK         0xffffffc0
-#define DPLL_CLKR_MASK         (0x3f)
-
-#define DPLL_CLK_ENABLE 0x6008
-#define DPLL_EN_DISP           (1 << 31)
-#define DPLL_SEL_HDMI          (1 << 8)
-#define DPLL_EN_HDMI           (1 << 1)
-#define DPLL_EN_VGA            (1 << 0)
-
-#define DPLL_ADJUST     0x600C
-#define DPLL_STATUS     0x6010
-#define DPLL_UPDATE     0x6014
-#define DPLL_DFT        0x6020
-
-struct intel_range {
-       int     min, max;
-};
-
-struct mrst_hdmi_limit {
-       struct intel_range vco, np, nr, nf;
-};
-
-struct mrst_hdmi_clock {
-       int np;
-       int nr;
-       int nf;
-       int dot;
-};
-
-#define VCO_MIN                320000
-#define VCO_MAX                1650000
-#define        NP_MIN          1
-#define        NP_MAX          15
-#define        NR_MIN          1
-#define        NR_MAX          64
-#define NF_MIN         2
-#define NF_MAX         4095
-
-static const struct mrst_hdmi_limit mrst_hdmi_limit = {
-       .vco = { .min = VCO_MIN,                .max = VCO_MAX },
-       .np  = { .min = NP_MIN,                 .max = NP_MAX  },
-       .nr  = { .min = NR_MIN,                 .max = NR_MAX  },
-       .nf  = { .min = NF_MIN,                 .max = NF_MAX  },
-};
-
-static void wait_for_vblank(struct drm_device *dev)
-{
-       /* FIXME: Can we do this as a sleep ? */
-       /* Wait for 20ms, i.e. one cycle at 50hz. */
-       mdelay(20);
-}
-
-static void scu_busy_loop(void *scu_base)
-{
-       u32 status = 0;
-       u32 loop_count = 0;
-
-       status = readl(scu_base + 0x04);
-       while (status & 1) {
-               udelay(1); /* scu processing time is in few u secods */
-               status = readl(scu_base + 0x04);
-               loop_count++;
-               /* break if scu doesn't reset busy bit after huge retry */
-               if (loop_count > 1000) {
-                       DRM_DEBUG_KMS("SCU IPC timed out");
-                       return;
-               }
-       }
-}
-
-static void mrst_hdmi_reset(struct drm_device *dev)
-{
-       void *base;
-       /* FIXME: at least make these defines */
-       unsigned int scu_ipc_mmio = 0xff11c000;
-       int scu_len = 1024;
-
-       base = ioremap((resource_size_t)scu_ipc_mmio, scu_len);
-       if (base == NULL) {
-               DRM_ERROR("failed to map SCU mmio\n");
-               return;
-       }
-
-       /* scu ipc: assert hdmi controller reset */
-       writel(0xff11d118, base + 0x0c);
-       writel(0x7fffffdf, base + 0x80);
-       writel(0x42005, base + 0x0);
-       scu_busy_loop(base);
-
-       /* scu ipc: de-assert hdmi controller reset */
-       writel(0xff11d118, base + 0x0c);
-       writel(0x7fffffff, base + 0x80);
-       writel(0x42005, base + 0x0);
-       scu_busy_loop(base);
-
-       iounmap(base);
-}
-
-static void mrst_hdmi_audio_enable(struct drm_device *dev)
-{
-       struct drm_psb_private *dev_priv = dev->dev_private;
-       struct mrst_hdmi_dev *hdmi_dev = dev_priv->hdmi_priv;
-
-       HDMI_WRITE(HDMI_HCR, 0x67);
-       HDMI_READ(HDMI_HCR);
-
-       HDMI_WRITE(0x51a8, 0x10);
-       HDMI_READ(0x51a8);
-
-       HDMI_WRITE(HDMI_AUDIO_CTRL, 0x1);
-       HDMI_READ(HDMI_AUDIO_CTRL);
-}
-
-static void mrst_hdmi_audio_disable(struct drm_device *dev)
-{
-       struct drm_psb_private *dev_priv = dev->dev_private;
-       struct mrst_hdmi_dev *hdmi_dev = dev_priv->hdmi_priv;
-
-       HDMI_WRITE(0x51a8, 0x0);
-       HDMI_READ(0x51a8);
-
-       HDMI_WRITE(HDMI_AUDIO_CTRL, 0x0);
-       HDMI_READ(HDMI_AUDIO_CTRL);
-
-       HDMI_WRITE(HDMI_HCR, 0x47);
-       HDMI_READ(HDMI_HCR);
-}
-
-void mrst_crtc_hdmi_dpms(struct drm_crtc *crtc, int mode)
-{
-       struct drm_device *dev = crtc->dev;
-       u32 temp;
-
-       switch (mode) {
-       case DRM_MODE_DPMS_OFF:
-               /* Disable VGACNTRL */
-               REG_WRITE(VGACNTRL, 0x80000000);
-
-               /* Disable plane */
-               temp = REG_READ(DSPBCNTR);
-               if ((temp & DISPLAY_PLANE_ENABLE) != 0) {
-                       REG_WRITE(DSPBCNTR, temp & ~DISPLAY_PLANE_ENABLE);
-                       REG_READ(DSPBCNTR);
-                       /* Flush the plane changes */
-                       REG_WRITE(DSPBSURF, REG_READ(DSPBSURF));
-                       REG_READ(DSPBSURF);
-               }
-
-               /* Disable pipe B */
-               temp = REG_READ(PIPEBCONF);
-               if ((temp & PIPEACONF_ENABLE) != 0) {
-                       REG_WRITE(PIPEBCONF, temp & ~PIPEACONF_ENABLE);
-                       REG_READ(PIPEBCONF);
-               }
-
-               /* Disable LNW Pipes, etc */
-               temp = REG_READ(PCH_PIPEBCONF);
-               if ((temp & PIPEACONF_ENABLE) != 0) {
-                       REG_WRITE(PCH_PIPEBCONF, temp & ~PIPEACONF_ENABLE);
-                       REG_READ(PCH_PIPEBCONF);
-               }
-               /* wait for pipe off */
-               udelay(150);
-               /* Disable dpll */
-               temp = REG_READ(DPLL_CTRL);
-               if ((temp & DPLL_PWRDN) == 0) {
-                       REG_WRITE(DPLL_CTRL, temp | (DPLL_PWRDN | DPLL_RESET));
-                       REG_WRITE(DPLL_STATUS, 0x1);
-               }
-               /* wait for dpll off */
-               udelay(150);
-               break;
-       case DRM_MODE_DPMS_ON:
-       case DRM_MODE_DPMS_STANDBY:
-       case DRM_MODE_DPMS_SUSPEND:
-               /* Enable dpll */
-               temp = REG_READ(DPLL_CTRL);
-               if ((temp & DPLL_PWRDN) != 0) {
-                       REG_WRITE(DPLL_CTRL, temp & ~(DPLL_PWRDN | DPLL_RESET));
-                       temp = REG_READ(DPLL_CLK_ENABLE);
-                       REG_WRITE(DPLL_CLK_ENABLE, temp | DPLL_EN_DISP | DPLL_SEL_HDMI | DPLL_EN_HDMI);
-                       REG_READ(DPLL_CLK_ENABLE);
-               }
-               /* wait for dpll warm up */
-               udelay(150);
-
-               /* Enable pipe B */
-               temp = REG_READ(PIPEBCONF);
-               if ((temp & PIPEACONF_ENABLE) == 0) {
-                       REG_WRITE(PIPEBCONF, temp | PIPEACONF_ENABLE);
-                       REG_READ(PIPEBCONF);
-               }
-
-               /* Enable LNW Pipe B */
-               temp = REG_READ(PCH_PIPEBCONF);
-               if ((temp & PIPEACONF_ENABLE) == 0) {
-                       REG_WRITE(PCH_PIPEBCONF, temp | PIPEACONF_ENABLE);
-                       REG_READ(PCH_PIPEBCONF);
-               }
-               wait_for_vblank(dev);
-
-               /* Enable plane */
-               temp = REG_READ(DSPBCNTR);
-               if ((temp & DISPLAY_PLANE_ENABLE) == 0) {
-                       REG_WRITE(DSPBCNTR, temp | DISPLAY_PLANE_ENABLE);
-                       /* Flush the plane changes */
-                       REG_WRITE(DSPBSURF, REG_READ(DSPBSURF));
-                       REG_READ(DSPBSURF);
-               }
-               psb_intel_crtc_load_lut(crtc);
-       }
-       /* DSPARB */
-       REG_WRITE(DSPARB, 0x00003fbf);
-       /* FW1 */
-       REG_WRITE(0x70034, 0x3f880a0a);
-       /* FW2 */
-       REG_WRITE(0x70038, 0x0b060808);
-       /* FW4 */
-       REG_WRITE(0x70050, 0x08030404);
-       /* FW5 */
-       REG_WRITE(0x70054, 0x04040404);
-       /* LNC Chicken Bits */
-       REG_WRITE(0x70400, 0x4000);
-}
-
-
-static void mrst_hdmi_dpms(struct drm_encoder *encoder, int mode)
-{
-       static int dpms_mode = -1;
-
-       struct drm_device *dev = encoder->dev;
-       struct drm_psb_private *dev_priv = dev->dev_private;
-       struct mrst_hdmi_dev *hdmi_dev = dev_priv->hdmi_priv;
-       u32 temp;
-
-       if (dpms_mode == mode)
-               return;
-
-       if (mode != DRM_MODE_DPMS_ON)
-               temp = 0x0;
-       else
-               temp = 0x99;
-
-       dpms_mode = mode;
-       HDMI_WRITE(HDMI_VIDEO_REG, temp);
-}
-
-static unsigned int htotal_calculate(struct drm_display_mode *mode)
-{
-       u32 htotal, new_crtc_htotal;
-
-       htotal = (mode->crtc_hdisplay - 1) | ((mode->crtc_htotal - 1) << 16);
-
-       /*
-        * 1024 x 768  new_crtc_htotal = 0x1024;
-        * 1280 x 1024 new_crtc_htotal = 0x0c34;
-        */
-       new_crtc_htotal = (mode->crtc_htotal - 1) * 200 * 1000 / mode->clock;
-
-       return (mode->crtc_hdisplay - 1) | (new_crtc_htotal << 16);
-}
-
-static void mrst_hdmi_find_dpll(struct drm_crtc *crtc, int target,
-                               int refclk, struct mrst_hdmi_clock *best_clock)
-{
-       int np_min, np_max, nr_min, nr_max;
-       int np, nr, nf;
-
-       np_min = DIV_ROUND_UP(mrst_hdmi_limit.vco.min, target * 10);
-       np_max = mrst_hdmi_limit.vco.max / (target * 10);
-       if (np_min < mrst_hdmi_limit.np.min)
-               np_min = mrst_hdmi_limit.np.min;
-       if (np_max > mrst_hdmi_limit.np.max)
-               np_max = mrst_hdmi_limit.np.max;
-
-       nr_min = DIV_ROUND_UP((refclk * 1000), (target * 10 * np_max));
-       nr_max = DIV_ROUND_UP((refclk * 1000), (target * 10 * np_min));
-       if (nr_min < mrst_hdmi_limit.nr.min)
-               nr_min = mrst_hdmi_limit.nr.min;
-       if (nr_max > mrst_hdmi_limit.nr.max)
-               nr_max = mrst_hdmi_limit.nr.max;
-
-       np = DIV_ROUND_UP((refclk * 1000), (target * 10 * nr_max));
-       nr = DIV_ROUND_UP((refclk * 1000), (target * 10 * np));
-       nf = DIV_ROUND_CLOSEST((target * 10 * np * nr), refclk);
-       DRM_DEBUG_KMS("np, nr, nf %d %d %d\n", np, nr, nf);
-
-       /*
-        * 1024 x 768  np = 1; nr = 0x26; nf = 0x0fd8000;
-        * 1280 x 1024 np = 1; nr = 0x17; nf = 0x1034000;
-        */
-       best_clock->np = np;
-       best_clock->nr = nr - 1;
-       best_clock->nf = (nf << 14);
-}
-
-int mrst_crtc_hdmi_mode_set(struct drm_crtc *crtc,
-                           struct drm_display_mode *mode,
-                           struct drm_display_mode *adjusted_mode,
-                           int x, int y,
-                           struct drm_framebuffer *old_fb)
-{
-       struct drm_device *dev = crtc->dev;
-       struct drm_psb_private *dev_priv = dev->dev_private;
-       struct mrst_hdmi_dev *hdmi_dev = dev_priv->hdmi_priv;
-       int pipe = 1;
-       int htot_reg = (pipe == 0) ? HTOTAL_A : HTOTAL_B;
-       int hblank_reg = (pipe == 0) ? HBLANK_A : HBLANK_B;
-       int hsync_reg = (pipe == 0) ? HSYNC_A : HSYNC_B;
-       int vtot_reg = (pipe == 0) ? VTOTAL_A : VTOTAL_B;
-       int vblank_reg = (pipe == 0) ? VBLANK_A : VBLANK_B;
-       int vsync_reg = (pipe == 0) ? VSYNC_A : VSYNC_B;
-       int dspsize_reg = (pipe == 0) ? DSPASIZE : DSPBSIZE;
-       int dsppos_reg = (pipe == 0) ? DSPAPOS : DSPBPOS;
-       int pipesrc_reg = (pipe == 0) ? PIPEASRC : PIPEBSRC;
-       int pipeconf_reg = (pipe == 0) ? PIPEACONF : PIPEBCONF;
-       int refclk;
-       struct mrst_hdmi_clock clock;
-       u32 dspcntr, pipeconf, dpll, temp;
-       int dspcntr_reg = DSPBCNTR;
-
-       /* Disable the VGA plane that we never use */
-       REG_WRITE(VGACNTRL, VGA_DISP_DISABLE);
-
-       /* XXX: Disable the panel fitter if it was on our pipe */
-
-       /* Disable dpll if necessary */
-       dpll = REG_READ(DPLL_CTRL);
-       if ((dpll & DPLL_PWRDN) == 0) {
-               REG_WRITE(DPLL_CTRL, dpll | (DPLL_PWRDN | DPLL_RESET));
-               REG_WRITE(DPLL_DIV_CTRL, 0x00000000);
-               REG_WRITE(DPLL_STATUS, 0x1);
-       }
-       udelay(150);
-
-       /* reset controller: FIXME - can we sort out the ioremap mess ? */
-       iounmap(hdmi_dev->regs);
-       mrst_hdmi_reset(dev);
-
-       /* program and enable dpll */
-       refclk = 25000;
-       mrst_hdmi_find_dpll(crtc, adjusted_mode->clock, refclk, &clock);
-
-       /* Setting DPLL */
-       dpll = REG_READ(DPLL_CTRL);
-       dpll &= ~DPLL_PDIV_MASK;
-       dpll &= ~(DPLL_PWRDN | DPLL_RESET);
-       REG_WRITE(DPLL_CTRL, 0x00000008);
-       REG_WRITE(DPLL_DIV_CTRL, ((clock.nf << 6) | clock.nr));
-       REG_WRITE(DPLL_ADJUST, ((clock.nf >> 14) - 1));
-       REG_WRITE(DPLL_CTRL, (dpll | (clock.np << DPLL_PDIV_SHIFT) | DPLL_ENSTAT | DPLL_DITHEN));
-       REG_WRITE(DPLL_UPDATE, 0x80000000);
-       REG_WRITE(DPLL_CLK_ENABLE, 0x80050102);
-       udelay(150);
-
-       hdmi_dev->regs = ioremap(hdmi_dev->mmio, hdmi_dev->mmio_len);
-       if (hdmi_dev->regs == NULL) {
-               DRM_ERROR("failed to do hdmi mmio mapping\n");
-               return -ENOMEM;
-       }
-
-       /* configure HDMI */
-       HDMI_WRITE(0x1004, 0x1fd);
-       HDMI_WRITE(0x2000, 0x1);
-       HDMI_WRITE(0x2008, 0x0);
-       HDMI_WRITE(0x3130, 0x8);
-       HDMI_WRITE(0x101c, 0x1800810);
-
-       temp = htotal_calculate(adjusted_mode);
-       REG_WRITE(htot_reg, temp);
-       REG_WRITE(hblank_reg, (adjusted_mode->crtc_hblank_start - 1) | ((adjusted_mode->crtc_hblank_end - 1) << 16));
-       REG_WRITE(hsync_reg, (adjusted_mode->crtc_hsync_start - 1) | ((adjusted_mode->crtc_hsync_end - 1) << 16));
-       REG_WRITE(vtot_reg, (adjusted_mode->crtc_vdisplay - 1) | ((adjusted_mode->crtc_vtotal - 1) << 16));
-       REG_WRITE(vblank_reg, (adjusted_mode->crtc_vblank_start - 1) | ((adjusted_mode->crtc_vblank_end - 1) << 16));
-       REG_WRITE(vsync_reg, (adjusted_mode->crtc_vsync_start - 1) | ((adjusted_mode->crtc_vsync_end - 1) << 16));
-       REG_WRITE(pipesrc_reg,
-               ((mode->crtc_hdisplay - 1) << 16) |  (mode->crtc_vdisplay - 1));
-
-       REG_WRITE(PCH_HTOTAL_B, (adjusted_mode->crtc_hdisplay - 1) | ((adjusted_mode->crtc_htotal - 1) << 16));
-       REG_WRITE(PCH_HBLANK_B, (adjusted_mode->crtc_hblank_start - 1) | ((adjusted_mode->crtc_hblank_end - 1) << 16));
-       REG_WRITE(PCH_HSYNC_B, (adjusted_mode->crtc_hsync_start - 1) | ((adjusted_mode->crtc_hsync_end - 1) << 16));
-       REG_WRITE(PCH_VTOTAL_B, (adjusted_mode->crtc_vdisplay - 1) | ((adjusted_mode->crtc_vtotal - 1) << 16));
-       REG_WRITE(PCH_VBLANK_B, (adjusted_mode->crtc_vblank_start - 1) | ((adjusted_mode->crtc_vblank_end - 1) << 16));
-       REG_WRITE(PCH_VSYNC_B, (adjusted_mode->crtc_vsync_start - 1) | ((adjusted_mode->crtc_vsync_end - 1) << 16));
-       REG_WRITE(PCH_PIPEBSRC,
-               ((mode->crtc_hdisplay - 1) << 16) |  (mode->crtc_vdisplay - 1));
-
-       temp = adjusted_mode->crtc_hblank_end - adjusted_mode->crtc_hblank_start;
-       HDMI_WRITE(HDMI_HBLANK_A, ((adjusted_mode->crtc_hdisplay - 1) << 16) |  temp);
-
-       REG_WRITE(dspsize_reg,
-                       ((mode->vdisplay - 1) << 16) | (mode->hdisplay - 1));
-       REG_WRITE(dsppos_reg, 0);
-
-       /* Flush the plane changes */
-       {
-               struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
-               crtc_funcs->mode_set_base(crtc, x, y, old_fb);
-       }
-
-       /* Set up the display plane register */
-       dspcntr = REG_READ(dspcntr_reg);
-       dspcntr |= DISPPLANE_GAMMA_ENABLE;
-       dspcntr |= DISPPLANE_SEL_PIPE_B;
-       dspcntr |= DISPLAY_PLANE_ENABLE;
-
-       /* setup pipeconf */
-       pipeconf = REG_READ(pipeconf_reg);
-       pipeconf |= PIPEACONF_ENABLE;
-
-       REG_WRITE(pipeconf_reg, pipeconf);
-       REG_READ(pipeconf_reg);
-
-       REG_WRITE(PCH_PIPEBCONF, pipeconf);
-       REG_READ(PCH_PIPEBCONF);
-       wait_for_vblank(dev);
-
-       REG_WRITE(dspcntr_reg, dspcntr);
-       wait_for_vblank(dev);
-
-       return 0;
-}
-
-static int mrst_hdmi_mode_valid(struct drm_connector *connector,
-                               struct drm_display_mode *mode)
-{
-       if (mode->clock > 165000)
-               return MODE_CLOCK_HIGH;
-       if (mode->clock < 20000)
-               return MODE_CLOCK_LOW;
-
-       if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
-               return MODE_NO_DBLESCAN;
-
-       return MODE_OK;
-}
-
-static bool mrst_hdmi_mode_fixup(struct drm_encoder *encoder,
-                                struct drm_display_mode *mode,
-                                struct drm_display_mode *adjusted_mode)
-{
-       return true;
-}
-
-static enum drm_connector_status
-mrst_hdmi_detect(struct drm_connector *connector, bool force)
-{
-       enum drm_connector_status status;
-       struct drm_device *dev = connector->dev;
-       struct drm_psb_private *dev_priv = dev->dev_private;
-       struct mrst_hdmi_dev *hdmi_dev = dev_priv->hdmi_priv;
-       u32 temp;
-
-       temp = HDMI_READ(HDMI_HSR);
-       DRM_DEBUG_KMS("HDMI_HSR %x\n", temp);
-
-       if ((temp & HDMI_DETECT_HDP) != 0)
-               status = connector_status_connected;
-       else
-               status = connector_status_disconnected;
-
-       return status;
-}
-
-static const unsigned char raw_edid[] = {
-       0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x10, 0xac, 0x2f, 0xa0,
-       0x53, 0x55, 0x33, 0x30, 0x16, 0x13, 0x01, 0x03, 0x0e, 0x3a, 0x24, 0x78,
-       0xea, 0xe9, 0xf5, 0xac, 0x51, 0x30, 0xb4, 0x25, 0x11, 0x50, 0x54, 0xa5,
-       0x4b, 0x00, 0x81, 0x80, 0xa9, 0x40, 0x71, 0x4f, 0xb3, 0x00, 0x01, 0x01,
-       0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x28, 0x3c, 0x80, 0xa0, 0x70, 0xb0,
-       0x23, 0x40, 0x30, 0x20, 0x36, 0x00, 0x46, 0x6c, 0x21, 0x00, 0x00, 0x1a,
-       0x00, 0x00, 0x00, 0xff, 0x00, 0x47, 0x4e, 0x37, 0x32, 0x31, 0x39, 0x35,
-       0x52, 0x30, 0x33, 0x55, 0x53, 0x0a, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x44,
-       0x45, 0x4c, 0x4c, 0x20, 0x32, 0x37, 0x30, 0x39, 0x57, 0x0a, 0x20, 0x20,
-       0x00, 0x00, 0x00, 0xfd, 0x00, 0x38, 0x4c, 0x1e, 0x53, 0x11, 0x00, 0x0a,
-       0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x8d
-};
-
-static int mrst_hdmi_get_modes(struct drm_connector *connector)
-{
-       struct drm_device *dev = connector->dev;
-       struct drm_psb_private *dev_priv = dev->dev_private;
-       struct i2c_adapter *i2c_adap;
-       struct edid *edid;
-       struct drm_display_mode *mode, *t;
-       int i = 0, ret = 0;
-
-       i2c_adap = i2c_get_adapter(3);
-       if (i2c_adap == NULL) {
-               DRM_ERROR("No ddc adapter available!\n");
-               edid = (struct edid *)raw_edid;
-       } else {
-               edid = (struct edid *)raw_edid;
-               /* FIXME ? edid = drm_get_edid(connector, i2c_adap); */
-       }
-
-       if (edid) {
-               drm_mode_connector_update_edid_property(connector, edid);
-               ret = drm_add_edid_modes(connector, edid);
-               connector->display_info.raw_edid = NULL;
-       }
-
-       /*
-        * prune modes that require frame buffer bigger than stolen mem
-        */
-       list_for_each_entry_safe(mode, t, &connector->probed_modes, head) {
-               if ((mode->hdisplay * mode->vdisplay * 4) >= dev_priv->vram_stolen_size) {
-                       i++;
-                       drm_mode_remove(connector, mode);
-               }
-       }
-       return ret - i;
-}
-
-static void mrst_hdmi_mode_set(struct drm_encoder *encoder,
-                              struct drm_display_mode *mode,
-                              struct drm_display_mode *adjusted_mode)
-{
-       struct drm_device *dev = encoder->dev;
-
-       mrst_hdmi_audio_enable(dev);
-       return;
-}
-
-static void mrst_hdmi_destroy(struct drm_connector *connector)
-{
-       return;
-}
-
-static const struct drm_encoder_helper_funcs mrst_hdmi_helper_funcs = {
-       .dpms = mrst_hdmi_dpms,
-       .mode_fixup = mrst_hdmi_mode_fixup,
-       .prepare = psb_intel_encoder_prepare,
-       .mode_set = mrst_hdmi_mode_set,
-       .commit = psb_intel_encoder_commit,
-};
-
-static const struct drm_connector_helper_funcs
-                                       mrst_hdmi_connector_helper_funcs = {
-       .get_modes = mrst_hdmi_get_modes,
-       .mode_valid = mrst_hdmi_mode_valid,
-       .best_encoder = psb_intel_best_encoder,
-};
-
-static const struct drm_connector_funcs mrst_hdmi_connector_funcs = {
-       .dpms = drm_helper_connector_dpms,
-       .detect = mrst_hdmi_detect,
-       .fill_modes = drm_helper_probe_single_connector_modes,
-       .destroy = mrst_hdmi_destroy,
-};
-
-static void mrst_hdmi_enc_destroy(struct drm_encoder *encoder)
-{
-       drm_encoder_cleanup(encoder);
-}
-
-static const struct drm_encoder_funcs mrst_hdmi_enc_funcs = {
-       .destroy = mrst_hdmi_enc_destroy,
-};
-
-void mrst_hdmi_init(struct drm_device *dev,
-                                       struct psb_intel_mode_device *mode_dev)
-{
-       struct psb_intel_output *psb_intel_output;
-       struct drm_connector *connector;
-       struct drm_encoder *encoder;
-
-       psb_intel_output = kzalloc(sizeof(struct psb_intel_output), GFP_KERNEL);
-       if (!psb_intel_output)
-               return;
-
-       psb_intel_output->mode_dev = mode_dev;
-       connector = &psb_intel_output->base;
-       encoder = &psb_intel_output->enc;
-       drm_connector_init(dev, &psb_intel_output->base,
-                          &mrst_hdmi_connector_funcs,
-                          DRM_MODE_CONNECTOR_DVID);
-
-       drm_encoder_init(dev, &psb_intel_output->enc,
-                        &mrst_hdmi_enc_funcs,
-                        DRM_MODE_ENCODER_TMDS);
-
-       drm_mode_connector_attach_encoder(&psb_intel_output->base,
-                                         &psb_intel_output->enc);
-
-       psb_intel_output->type = INTEL_OUTPUT_HDMI;
-       drm_encoder_helper_add(encoder, &mrst_hdmi_helper_funcs);
-       drm_connector_helper_add(connector, &mrst_hdmi_connector_helper_funcs);
-
-       connector->display_info.subpixel_order = SubPixelHorizontalRGB;
-       connector->interlace_allowed = false;
-       connector->doublescan_allowed = false;
-       drm_sysfs_connector_add(connector);
-
-       return;
-}
-
-static DEFINE_PCI_DEVICE_TABLE(hdmi_ids) = {
-       { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x080d) },
-       {}
-};
-
-void mrst_hdmi_setup(struct drm_device *dev)
-{
-       struct drm_psb_private *dev_priv = dev->dev_private;
-       struct pci_dev *pdev;
-       struct mrst_hdmi_dev *hdmi_dev;
-       int ret;
-
-       pdev = pci_get_device(PCI_VENDOR_ID_INTEL, 0x080d, NULL);
-       if (!pdev)
-               return;
-
-       hdmi_dev = kzalloc(sizeof(struct mrst_hdmi_dev), GFP_KERNEL);
-       if (!hdmi_dev) {
-               dev_err(dev->dev, "failed to allocate memory\n");
-               goto out;
-       }
-
-
-       ret = pci_enable_device(pdev);
-       if (ret) {
-               dev_err(dev->dev, "failed to enable hdmi controller\n");
-               goto free;
-       }
-
-       hdmi_dev->mmio = pci_resource_start(pdev, 0);
-       hdmi_dev->mmio_len = pci_resource_len(pdev, 0);
-       hdmi_dev->regs = ioremap(hdmi_dev->mmio, hdmi_dev->mmio_len);
-       if (!hdmi_dev->regs) {
-               dev_err(dev->dev, "failed to map hdmi mmio\n");
-               goto free;
-       }
-
-       hdmi_dev->dev = pdev;
-       pci_set_drvdata(pdev, hdmi_dev);
-
-       /* Initialize i2c controller */
-       ret = mrst_hdmi_i2c_init(hdmi_dev->dev);
-       if (ret)
-               dev_err(dev->dev, "HDMI I2C initialization failed\n");
-
-       dev_priv->hdmi_priv = hdmi_dev;
-       mrst_hdmi_audio_disable(dev);
-       return;
-
-free:
-       kfree(hdmi_dev);
-out:
-       return;
-}
-
-void mrst_hdmi_teardown(struct drm_device *dev)
-{
-       struct drm_psb_private *dev_priv = dev->dev_private;
-       struct mrst_hdmi_dev *hdmi_dev = dev_priv->hdmi_priv;
-       struct pci_dev *pdev;
-
-       if (hdmi_dev) {
-               pdev = hdmi_dev->dev;
-               pci_set_drvdata(pdev, NULL);
-               mrst_hdmi_i2c_exit(pdev);
-               iounmap(hdmi_dev->regs);
-               kfree(hdmi_dev);
-               pci_dev_put(pdev);
-       }
-}
-
-/* save HDMI register state */
-void mrst_hdmi_save(struct drm_device *dev)
-{
-       struct drm_psb_private *dev_priv = dev->dev_private;
-       struct mrst_hdmi_dev *hdmi_dev = dev_priv->hdmi_priv;
-       int i;
-
-       /* dpll */
-       hdmi_dev->saveDPLL_CTRL = PSB_RVDC32(DPLL_CTRL);
-       hdmi_dev->saveDPLL_DIV_CTRL = PSB_RVDC32(DPLL_DIV_CTRL);
-       hdmi_dev->saveDPLL_ADJUST = PSB_RVDC32(DPLL_ADJUST);
-       hdmi_dev->saveDPLL_UPDATE = PSB_RVDC32(DPLL_UPDATE);
-       hdmi_dev->saveDPLL_CLK_ENABLE = PSB_RVDC32(DPLL_CLK_ENABLE);
-
-       /* pipe B */
-       dev_priv->savePIPEBCONF = PSB_RVDC32(PIPEBCONF);
-       dev_priv->savePIPEBSRC  = PSB_RVDC32(PIPEBSRC);
-       dev_priv->saveHTOTAL_B  = PSB_RVDC32(HTOTAL_B);
-       dev_priv->saveHBLANK_B  = PSB_RVDC32(HBLANK_B);
-       dev_priv->saveHSYNC_B   = PSB_RVDC32(HSYNC_B);
-       dev_priv->saveVTOTAL_B  = PSB_RVDC32(VTOTAL_B);
-       dev_priv->saveVBLANK_B  = PSB_RVDC32(VBLANK_B);
-       dev_priv->saveVSYNC_B   = PSB_RVDC32(VSYNC_B);
-
-       hdmi_dev->savePCH_PIPEBCONF = PSB_RVDC32(PCH_PIPEBCONF);
-       hdmi_dev->savePCH_PIPEBSRC = PSB_RVDC32(PCH_PIPEBSRC);
-       hdmi_dev->savePCH_HTOTAL_B = PSB_RVDC32(PCH_HTOTAL_B);
-       hdmi_dev->savePCH_HBLANK_B = PSB_RVDC32(PCH_HBLANK_B);
-       hdmi_dev->savePCH_HSYNC_B  = PSB_RVDC32(PCH_HSYNC_B);
-       hdmi_dev->savePCH_VTOTAL_B = PSB_RVDC32(PCH_VTOTAL_B);
-       hdmi_dev->savePCH_VBLANK_B = PSB_RVDC32(PCH_VBLANK_B);
-       hdmi_dev->savePCH_VSYNC_B  = PSB_RVDC32(PCH_VSYNC_B);
-
-       /* plane */
-       dev_priv->saveDSPBCNTR = PSB_RVDC32(DSPBCNTR);
-       dev_priv->saveDSPBSTRIDE = PSB_RVDC32(DSPBSTRIDE);
-       dev_priv->saveDSPBADDR = PSB_RVDC32(DSPBBASE);
-       dev_priv->saveDSPBSURF = PSB_RVDC32(DSPBSURF);
-       dev_priv->saveDSPBLINOFF = PSB_RVDC32(DSPBLINOFF);
-       dev_priv->saveDSPBTILEOFF = PSB_RVDC32(DSPBTILEOFF);
-
-       /* cursor B */
-       dev_priv->saveDSPBCURSOR_CTRL = PSB_RVDC32(CURBCNTR);
-       dev_priv->saveDSPBCURSOR_BASE = PSB_RVDC32(CURBBASE);
-       dev_priv->saveDSPBCURSOR_POS = PSB_RVDC32(CURBPOS);
-
-       /* save palette */
-       for (i = 0; i < 256; i++)
-               dev_priv->save_palette_b[i] = PSB_RVDC32(PALETTE_B + (i << 2));
-}
-
-/* restore HDMI register state */
-void mrst_hdmi_restore(struct drm_device *dev)
-{
-       struct drm_psb_private *dev_priv = dev->dev_private;
-       struct mrst_hdmi_dev *hdmi_dev = dev_priv->hdmi_priv;
-       int i;
-
-       /* dpll */
-       PSB_WVDC32(hdmi_dev->saveDPLL_CTRL, DPLL_CTRL);
-       PSB_WVDC32(hdmi_dev->saveDPLL_DIV_CTRL, DPLL_DIV_CTRL);
-       PSB_WVDC32(hdmi_dev->saveDPLL_ADJUST, DPLL_ADJUST);
-       PSB_WVDC32(hdmi_dev->saveDPLL_UPDATE, DPLL_UPDATE);
-       PSB_WVDC32(hdmi_dev->saveDPLL_CLK_ENABLE, DPLL_CLK_ENABLE);
-       DRM_UDELAY(150);
-
-       /* pipe */
-       PSB_WVDC32(dev_priv->savePIPEBSRC, PIPEBSRC);
-       PSB_WVDC32(dev_priv->saveHTOTAL_B, HTOTAL_B);
-       PSB_WVDC32(dev_priv->saveHBLANK_B, HBLANK_B);
-       PSB_WVDC32(dev_priv->saveHSYNC_B,  HSYNC_B);
-       PSB_WVDC32(dev_priv->saveVTOTAL_B, VTOTAL_B);
-       PSB_WVDC32(dev_priv->saveVBLANK_B, VBLANK_B);
-       PSB_WVDC32(dev_priv->saveVSYNC_B,  VSYNC_B);
-
-       PSB_WVDC32(hdmi_dev->savePCH_PIPEBSRC, PCH_PIPEBSRC);
-       PSB_WVDC32(hdmi_dev->savePCH_HTOTAL_B, PCH_HTOTAL_B);
-       PSB_WVDC32(hdmi_dev->savePCH_HBLANK_B, PCH_HBLANK_B);
-       PSB_WVDC32(hdmi_dev->savePCH_HSYNC_B,  PCH_HSYNC_B);
-       PSB_WVDC32(hdmi_dev->savePCH_VTOTAL_B, PCH_VTOTAL_B);
-       PSB_WVDC32(hdmi_dev->savePCH_VBLANK_B, PCH_VBLANK_B);
-       PSB_WVDC32(hdmi_dev->savePCH_VSYNC_B,  PCH_VSYNC_B);
-
-       PSB_WVDC32(dev_priv->savePIPEBCONF, PIPEBCONF);
-       PSB_WVDC32(hdmi_dev->savePCH_PIPEBCONF, PCH_PIPEBCONF);
-
-       /* plane */
-       PSB_WVDC32(dev_priv->saveDSPBLINOFF, DSPBLINOFF);
-       PSB_WVDC32(dev_priv->saveDSPBSTRIDE, DSPBSTRIDE);
-       PSB_WVDC32(dev_priv->saveDSPBTILEOFF, DSPBTILEOFF);
-       PSB_WVDC32(dev_priv->saveDSPBCNTR, DSPBCNTR);
-       PSB_WVDC32(dev_priv->saveDSPBSURF, DSPBSURF);
-
-       /* cursor B */
-       PSB_WVDC32(dev_priv->saveDSPBCURSOR_CTRL, CURBCNTR);
-       PSB_WVDC32(dev_priv->saveDSPBCURSOR_POS, CURBPOS);
-       PSB_WVDC32(dev_priv->saveDSPBCURSOR_BASE, CURBBASE);
-
-       /* restore palette */
-       for (i = 0; i < 256; i++)
-               PSB_WVDC32(dev_priv->save_palette_b[i], PALETTE_B + (i << 2));
-}
diff --git a/drivers/staging/gma500/mrst_hdmi_i2c.c b/drivers/staging/gma500/mrst_hdmi_i2c.c
deleted file mode 100644 (file)
index 36e7edc..0000000
+++ /dev/null
@@ -1,328 +0,0 @@
-/*
- * Copyright Â© 2010 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Authors:
- *     Li Peng <peng.li@intel.com>
- */
-
-#include <linux/mutex.h>
-#include <linux/pci.h>
-#include <linux/i2c.h>
-#include <linux/interrupt.h>
-#include <linux/delay.h>
-#include <linux/export.h>
-#include "psb_drv.h"
-
-#define HDMI_READ(reg)         readl(hdmi_dev->regs + (reg))
-#define HDMI_WRITE(reg, val)   writel(val, hdmi_dev->regs + (reg))
-
-#define HDMI_HCR       0x1000
-#define HCR_DETECT_HDP         (1 << 6)
-#define HCR_ENABLE_HDCP                (1 << 5)
-#define HCR_ENABLE_AUDIO       (1 << 2)
-#define HCR_ENABLE_PIXEL       (1 << 1)
-#define HCR_ENABLE_TMDS                (1 << 0)
-#define HDMI_HICR      0x1004
-#define HDMI_INTR_I2C_ERROR    (1 << 4)
-#define HDMI_INTR_I2C_FULL     (1 << 3)
-#define HDMI_INTR_I2C_DONE     (1 << 2)
-#define HDMI_INTR_HPD          (1 << 0)
-#define HDMI_HSR       0x1008
-#define HDMI_HISR      0x100C
-#define HDMI_HI2CRDB0  0x1200
-#define HDMI_HI2CHCR   0x1240
-#define HI2C_HDCP_WRITE                (0 << 2)
-#define HI2C_HDCP_RI_READ      (1 << 2)
-#define HI2C_HDCP_READ         (2 << 2)
-#define HI2C_EDID_READ         (3 << 2)
-#define HI2C_READ_CONTINUE     (1 << 1)
-#define HI2C_ENABLE_TRANSACTION        (1 << 0)
-
-#define HDMI_ICRH      0x1100
-#define HDMI_HI2CTDR0  0x1244
-#define HDMI_HI2CTDR1  0x1248
-
-#define I2C_STAT_INIT          0
-#define I2C_READ_DONE          1
-#define I2C_TRANSACTION_DONE   2
-
-struct hdmi_i2c_dev {
-       struct i2c_adapter *adap;
-       struct mutex i2c_lock;
-       struct completion complete;
-       int status;
-       struct i2c_msg *msg;
-       int buf_offset;
-};
-
-static void hdmi_i2c_irq_enable(struct mrst_hdmi_dev *hdmi_dev)
-{
-       u32 temp;
-
-       temp = HDMI_READ(HDMI_HICR);
-       temp |= (HDMI_INTR_I2C_ERROR | HDMI_INTR_I2C_FULL | HDMI_INTR_I2C_DONE);
-       HDMI_WRITE(HDMI_HICR, temp);
-       HDMI_READ(HDMI_HICR);
-}
-
-static void hdmi_i2c_irq_disable(struct mrst_hdmi_dev *hdmi_dev)
-{
-       HDMI_WRITE(HDMI_HICR, 0x0);
-       HDMI_READ(HDMI_HICR);
-}
-
-static int xfer_read(struct i2c_adapter *adap, struct i2c_msg *pmsg)
-{
-       struct mrst_hdmi_dev *hdmi_dev = i2c_get_adapdata(adap);
-       struct hdmi_i2c_dev *i2c_dev = hdmi_dev->i2c_dev;
-       u32 temp;
-
-       i2c_dev->status = I2C_STAT_INIT;
-       i2c_dev->msg = pmsg;
-       i2c_dev->buf_offset = 0;
-       INIT_COMPLETION(i2c_dev->complete);
-
-       /* Enable I2C transaction */
-       temp = ((pmsg->len) << 20) | HI2C_EDID_READ | HI2C_ENABLE_TRANSACTION;
-       HDMI_WRITE(HDMI_HI2CHCR, temp);
-       HDMI_READ(HDMI_HI2CHCR);
-
-       while (i2c_dev->status != I2C_TRANSACTION_DONE)
-               wait_for_completion_interruptible_timeout(&i2c_dev->complete,
-                                                               10 * HZ);
-
-       return 0;
-}
-
-static int xfer_write(struct i2c_adapter *adap, struct i2c_msg *pmsg)
-{
-       /*
-        * XXX: i2c write seems isn't useful for EDID probe, don't do anything
-        */
-       return 0;
-}
-
-static int mrst_hdmi_i2c_access(struct i2c_adapter *adap,
-                               struct i2c_msg *pmsg,
-                               int num)
-{
-       struct mrst_hdmi_dev *hdmi_dev = i2c_get_adapdata(adap);
-       struct hdmi_i2c_dev *i2c_dev = hdmi_dev->i2c_dev;
-       int i, err = 0;
-
-       mutex_lock(&i2c_dev->i2c_lock);
-
-       /* Enable i2c unit */
-       HDMI_WRITE(HDMI_ICRH, 0x00008760);
-
-       /* Enable irq */
-       hdmi_i2c_irq_enable(hdmi_dev);
-       for (i = 0; i < num; i++) {
-               if (pmsg->len && pmsg->buf) {
-                       if (pmsg->flags & I2C_M_RD)
-                               err = xfer_read(adap, pmsg);
-                       else
-                               err = xfer_write(adap, pmsg);
-               }
-               pmsg++;         /* next message */
-       }
-
-       /* Disable irq */
-       hdmi_i2c_irq_disable(hdmi_dev);
-
-       mutex_unlock(&i2c_dev->i2c_lock);
-
-       return i;
-}
-
-static u32 mrst_hdmi_i2c_func(struct i2c_adapter *adapter)
-{
-       return I2C_FUNC_I2C | I2C_FUNC_10BIT_ADDR;
-}
-
-static const struct i2c_algorithm mrst_hdmi_i2c_algorithm = {
-       .master_xfer    = mrst_hdmi_i2c_access,
-       .functionality  = mrst_hdmi_i2c_func,
-};
-
-static struct i2c_adapter mrst_hdmi_i2c_adapter = {
-       .name           = "mrst_hdmi_i2c",
-       .nr             = 3,
-       .owner          = THIS_MODULE,
-       .class          = I2C_CLASS_DDC,
-       .algo           = &mrst_hdmi_i2c_algorithm,
-};
-
-static void hdmi_i2c_read(struct mrst_hdmi_dev *hdmi_dev)
-{
-       struct hdmi_i2c_dev *i2c_dev = hdmi_dev->i2c_dev;
-       struct i2c_msg *msg = i2c_dev->msg;
-       u8 *buf = msg->buf;
-       u32 temp;
-       int i, offset;
-
-       offset = i2c_dev->buf_offset;
-       for (i = 0; i < 0x10; i++) {
-               temp = HDMI_READ(HDMI_HI2CRDB0 + (i * 4));
-               memcpy(buf + (offset + i * 4), &temp, 4);
-       }
-       i2c_dev->buf_offset += (0x10 * 4);
-
-       /* clearing read buffer full intr */
-       temp = HDMI_READ(HDMI_HISR);
-       HDMI_WRITE(HDMI_HISR, temp | HDMI_INTR_I2C_FULL);
-       HDMI_READ(HDMI_HISR);
-
-       /* continue read transaction */
-       temp = HDMI_READ(HDMI_HI2CHCR);
-       HDMI_WRITE(HDMI_HI2CHCR, temp | HI2C_READ_CONTINUE);
-       HDMI_READ(HDMI_HI2CHCR);
-
-       i2c_dev->status = I2C_READ_DONE;
-       return;
-}
-
-static void hdmi_i2c_transaction_done(struct mrst_hdmi_dev *hdmi_dev)
-{
-       struct hdmi_i2c_dev *i2c_dev = hdmi_dev->i2c_dev;
-       u32 temp;
-
-       /* clear transaction done intr */
-       temp = HDMI_READ(HDMI_HISR);
-       HDMI_WRITE(HDMI_HISR, temp | HDMI_INTR_I2C_DONE);
-       HDMI_READ(HDMI_HISR);
-
-
-       temp = HDMI_READ(HDMI_HI2CHCR);
-       HDMI_WRITE(HDMI_HI2CHCR, temp & ~HI2C_ENABLE_TRANSACTION);
-       HDMI_READ(HDMI_HI2CHCR);
-
-       i2c_dev->status = I2C_TRANSACTION_DONE;
-       return;
-}
-
-static irqreturn_t mrst_hdmi_i2c_handler(int this_irq, void *dev)
-{
-       struct mrst_hdmi_dev *hdmi_dev = dev;
-       struct hdmi_i2c_dev *i2c_dev = hdmi_dev->i2c_dev;
-       u32 stat;
-
-       stat = HDMI_READ(HDMI_HISR);
-
-       if (stat & HDMI_INTR_HPD) {
-               HDMI_WRITE(HDMI_HISR, stat | HDMI_INTR_HPD);
-               HDMI_READ(HDMI_HISR);
-       }
-
-       if (stat & HDMI_INTR_I2C_FULL)
-               hdmi_i2c_read(hdmi_dev);
-
-       if (stat & HDMI_INTR_I2C_DONE)
-               hdmi_i2c_transaction_done(hdmi_dev);
-
-       complete(&i2c_dev->complete);
-
-       return IRQ_HANDLED;
-}
-
-/*
- * choose alternate function 2 of GPIO pin 52, 53,
- * which is used by HDMI I2C logic
- */
-static void mrst_hdmi_i2c_gpio_fix(void)
-{
-       void *base;
-       unsigned int gpio_base = 0xff12c000;
-       int gpio_len = 0x1000;
-       u32 temp;
-
-       base = ioremap((resource_size_t)gpio_base, gpio_len);
-       if (base == NULL) {
-               DRM_ERROR("gpio ioremap fail\n");
-               return;
-       }
-
-       temp = readl(base + 0x44);
-       DRM_DEBUG_DRIVER("old gpio val %x\n", temp);
-       writel((temp | 0x00000a00), (base +  0x44));
-       temp = readl(base + 0x44);
-       DRM_DEBUG_DRIVER("new gpio val %x\n", temp);
-
-       iounmap(base);
-}
-
-int mrst_hdmi_i2c_init(struct pci_dev *dev)
-{
-       struct mrst_hdmi_dev *hdmi_dev;
-       struct hdmi_i2c_dev *i2c_dev;
-       int ret;
-
-       hdmi_dev = pci_get_drvdata(dev);
-
-       i2c_dev = kzalloc(sizeof(struct hdmi_i2c_dev), GFP_KERNEL);
-       if (i2c_dev == NULL) {
-               DRM_ERROR("Can't allocate interface\n");
-               ret = -ENOMEM;
-               goto exit;
-       }
-
-       i2c_dev->adap = &mrst_hdmi_i2c_adapter;
-       i2c_dev->status = I2C_STAT_INIT;
-       init_completion(&i2c_dev->complete);
-       mutex_init(&i2c_dev->i2c_lock);
-       i2c_set_adapdata(&mrst_hdmi_i2c_adapter, hdmi_dev);
-       hdmi_dev->i2c_dev = i2c_dev;
-
-       /* Enable HDMI I2C function on gpio */
-       mrst_hdmi_i2c_gpio_fix();
-
-       /* request irq */
-       ret = request_irq(dev->irq, mrst_hdmi_i2c_handler, IRQF_SHARED,
-                         mrst_hdmi_i2c_adapter.name, hdmi_dev);
-       if (ret) {
-               DRM_ERROR("Failed to request IRQ for I2C controller\n");
-               goto err;
-       }
-
-       /* Adapter registration */
-       ret = i2c_add_numbered_adapter(&mrst_hdmi_i2c_adapter);
-       return ret;
-
-err:
-       kfree(i2c_dev);
-exit:
-       return ret;
-}
-
-void mrst_hdmi_i2c_exit(struct pci_dev *dev)
-{
-       struct mrst_hdmi_dev *hdmi_dev;
-       struct hdmi_i2c_dev *i2c_dev;
-
-       hdmi_dev = pci_get_drvdata(dev);
-       if (i2c_del_adapter(&mrst_hdmi_i2c_adapter))
-               DRM_DEBUG_DRIVER("Failed to delete hdmi-i2c adapter\n");
-
-       i2c_dev = hdmi_dev->i2c_dev;
-       kfree(i2c_dev);
-       free_irq(dev->irq, hdmi_dev);
-}
diff --git a/drivers/staging/gma500/mrst_lvds.c b/drivers/staging/gma500/mrst_lvds.c
deleted file mode 100644 (file)
index e7999a2..0000000
+++ /dev/null
@@ -1,407 +0,0 @@
-/*
- * Copyright Â© 2006-2009 Intel Corporation
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Authors:
- *     Eric Anholt <eric@anholt.net>
- *     Dave Airlie <airlied@linux.ie>
- *     Jesse Barnes <jesse.barnes@intel.com>
- */
-
-#include <linux/i2c.h>
-#include <drm/drmP.h>
-#include <asm/mrst.h>
-
-#include "intel_bios.h"
-#include "psb_drv.h"
-#include "psb_intel_drv.h"
-#include "psb_intel_reg.h"
-#include "power.h"
-#include <linux/pm_runtime.h>
-
-/* The max/min PWM frequency in BPCR[31:17] - */
-/* The smallest number is 1 (not 0) that can fit in the
- * 15-bit field of the and then*/
-/* shifts to the left by one bit to get the actual 16-bit
- * value that the 15-bits correspond to.*/
-#define MRST_BLC_MAX_PWM_REG_FREQ          0xFFFF
-#define BRIGHTNESS_MAX_LEVEL 100
-
-/**
- * Sets the power state for the panel.
- */
-static void mrst_lvds_set_power(struct drm_device *dev,
-                               struct psb_intel_output *output, bool on)
-{
-       u32 pp_status;
-       struct drm_psb_private *dev_priv = dev->dev_private;
-
-       if (!gma_power_begin(dev, true))
-               return;
-
-       if (on) {
-               REG_WRITE(PP_CONTROL, REG_READ(PP_CONTROL) |
-                         POWER_TARGET_ON);
-               do {
-                       pp_status = REG_READ(PP_STATUS);
-               } while ((pp_status & (PP_ON | PP_READY)) == PP_READY);
-               dev_priv->is_lvds_on = true;
-               if (dev_priv->ops->lvds_bl_power)
-                       dev_priv->ops->lvds_bl_power(dev, true);
-       } else {
-               if (dev_priv->ops->lvds_bl_power)
-                       dev_priv->ops->lvds_bl_power(dev, false);
-               REG_WRITE(PP_CONTROL, REG_READ(PP_CONTROL) &
-                         ~POWER_TARGET_ON);
-               do {
-                       pp_status = REG_READ(PP_STATUS);
-               } while (pp_status & PP_ON);
-               dev_priv->is_lvds_on = false;
-               pm_request_idle(&dev->pdev->dev);
-       }
-       gma_power_end(dev);
-}
-
-static void mrst_lvds_dpms(struct drm_encoder *encoder, int mode)
-{
-       struct drm_device *dev = encoder->dev;
-       struct psb_intel_output *output = enc_to_psb_intel_output(encoder);
-
-       if (mode == DRM_MODE_DPMS_ON)
-               mrst_lvds_set_power(dev, output, true);
-       else
-               mrst_lvds_set_power(dev, output, false);
-
-       /* XXX: We never power down the LVDS pairs. */
-}
-
-static void mrst_lvds_mode_set(struct drm_encoder *encoder,
-                              struct drm_display_mode *mode,
-                              struct drm_display_mode *adjusted_mode)
-{
-       struct psb_intel_mode_device *mode_dev =
-                               enc_to_psb_intel_output(encoder)->mode_dev;
-       struct drm_device *dev = encoder->dev;
-       struct drm_psb_private *dev_priv = dev->dev_private;
-       u32 lvds_port;
-       uint64_t v = DRM_MODE_SCALE_FULLSCREEN;
-
-       if (!gma_power_begin(dev, true))
-               return;
-
-       /*
-        * The LVDS pin pair will already have been turned on in the
-        * psb_intel_crtc_mode_set since it has a large impact on the DPLL
-        * settings.
-        */
-       lvds_port = (REG_READ(LVDS) &
-                   (~LVDS_PIPEB_SELECT)) |
-                   LVDS_PORT_EN |
-                   LVDS_BORDER_EN;
-
-       /* If the firmware says dither on Moorestown, or the BIOS does
-          on Oaktrail then enable dithering */
-       if (mode_dev->panel_wants_dither || dev_priv->lvds_dither)
-               lvds_port |= MRST_PANEL_8TO6_DITHER_ENABLE;
-
-       REG_WRITE(LVDS, lvds_port);
-
-       drm_connector_property_get_value(
-               &enc_to_psb_intel_output(encoder)->base,
-               dev->mode_config.scaling_mode_property,
-               &v);
-
-       if (v == DRM_MODE_SCALE_NO_SCALE)
-               REG_WRITE(PFIT_CONTROL, 0);
-       else if (v == DRM_MODE_SCALE_ASPECT) {
-               if ((mode->vdisplay != adjusted_mode->crtc_vdisplay) ||
-                   (mode->hdisplay != adjusted_mode->crtc_hdisplay)) {
-                       if ((adjusted_mode->crtc_hdisplay * mode->vdisplay) ==
-                           (mode->hdisplay * adjusted_mode->crtc_vdisplay))
-                               REG_WRITE(PFIT_CONTROL, PFIT_ENABLE);
-                       else if ((adjusted_mode->crtc_hdisplay *
-                               mode->vdisplay) > (mode->hdisplay *
-                               adjusted_mode->crtc_vdisplay))
-                               REG_WRITE(PFIT_CONTROL, PFIT_ENABLE |
-                                         PFIT_SCALING_MODE_PILLARBOX);
-                       else
-                               REG_WRITE(PFIT_CONTROL, PFIT_ENABLE |
-                                         PFIT_SCALING_MODE_LETTERBOX);
-               } else
-                       REG_WRITE(PFIT_CONTROL, PFIT_ENABLE);
-       } else /*(v == DRM_MODE_SCALE_FULLSCREEN)*/
-               REG_WRITE(PFIT_CONTROL, PFIT_ENABLE);
-
-       gma_power_end(dev);
-}
-
-static void mrst_lvds_prepare(struct drm_encoder *encoder)
-{
-       struct drm_device *dev = encoder->dev;
-       struct psb_intel_output *output = enc_to_psb_intel_output(encoder);
-       struct psb_intel_mode_device *mode_dev = output->mode_dev;
-
-       if (!gma_power_begin(dev, true))
-               return;
-
-       mode_dev->saveBLC_PWM_CTL = REG_READ(BLC_PWM_CTL);
-       mode_dev->backlight_duty_cycle = (mode_dev->saveBLC_PWM_CTL &
-                                         BACKLIGHT_DUTY_CYCLE_MASK);
-       mrst_lvds_set_power(dev, output, false);
-       gma_power_end(dev);
-}
-
-static u32 mrst_lvds_get_max_backlight(struct drm_device *dev)
-{
-       struct drm_psb_private *dev_priv = dev->dev_private;
-       u32 ret;
-
-       if (gma_power_begin(dev, false)) {
-               ret = ((REG_READ(BLC_PWM_CTL) &
-                         BACKLIGHT_MODULATION_FREQ_MASK) >>
-                         BACKLIGHT_MODULATION_FREQ_SHIFT) * 2;
-
-               gma_power_end(dev);
-       } else
-               ret = ((dev_priv->saveBLC_PWM_CTL &
-                         BACKLIGHT_MODULATION_FREQ_MASK) >>
-                         BACKLIGHT_MODULATION_FREQ_SHIFT) * 2;
-
-       return ret;
-}
-
-static void mrst_lvds_commit(struct drm_encoder *encoder)
-{
-       struct drm_device *dev = encoder->dev;
-       struct psb_intel_output *output = enc_to_psb_intel_output(encoder);
-       struct psb_intel_mode_device *mode_dev = output->mode_dev;
-
-       if (mode_dev->backlight_duty_cycle == 0)
-               mode_dev->backlight_duty_cycle =
-                                       mrst_lvds_get_max_backlight(dev);
-       mrst_lvds_set_power(dev, output, true);
-}
-
-static const struct drm_encoder_helper_funcs mrst_lvds_helper_funcs = {
-       .dpms = mrst_lvds_dpms,
-       .mode_fixup = psb_intel_lvds_mode_fixup,
-       .prepare = mrst_lvds_prepare,
-       .mode_set = mrst_lvds_mode_set,
-       .commit = mrst_lvds_commit,
-};
-
-static struct drm_display_mode lvds_configuration_modes[] = {
-       /* hard coded fixed mode for TPO LTPS LPJ040K001A */
-       { DRM_MODE("800x480",  DRM_MODE_TYPE_DRIVER, 33264, 800, 836,
-                  846, 1056, 0, 480, 489, 491, 525, 0, 0) },
-       /* hard coded fixed mode for LVDS 800x480 */
-       { DRM_MODE("800x480",  DRM_MODE_TYPE_DRIVER, 30994, 800, 801,
-                  802, 1024, 0, 480, 481, 482, 525, 0, 0) },
-       /* hard coded fixed mode for Samsung 480wsvga LVDS 1024x600@75 */
-       { DRM_MODE("1024x600", DRM_MODE_TYPE_DRIVER, 53990, 1024, 1072,
-                  1104, 1184, 0, 600, 603, 604, 608, 0, 0) },
-       /* hard coded fixed mode for Samsung 480wsvga LVDS 1024x600@75 */
-       { DRM_MODE("1024x600", DRM_MODE_TYPE_DRIVER, 53990, 1024, 1104,
-                  1136, 1184, 0, 600, 603, 604, 608, 0, 0) },
-       /* hard coded fixed mode for Sharp wsvga LVDS 1024x600 */
-       { DRM_MODE("1024x600", DRM_MODE_TYPE_DRIVER, 48885, 1024, 1124,
-                  1204, 1312, 0, 600, 607, 610, 621, 0, 0) },
-       /* hard coded fixed mode for LVDS 1024x768 */
-       { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 65000, 1024, 1048,
-                  1184, 1344, 0, 768, 771, 777, 806, 0, 0) },
-       /* hard coded fixed mode for LVDS 1366x768 */
-       { DRM_MODE("1366x768", DRM_MODE_TYPE_DRIVER, 77500, 1366, 1430,
-                  1558, 1664, 0, 768, 769, 770, 776, 0, 0) },
-};
-
-/* Returns the panel fixed mode from configuration. */
-
-static struct drm_display_mode *
-mrst_lvds_get_configuration_mode(struct drm_device *dev)
-{
-       struct drm_display_mode *mode = NULL;
-       struct drm_psb_private *dev_priv = dev->dev_private;
-       struct mrst_timing_info *ti = &dev_priv->gct_data.DTD;
-
-       if (dev_priv->vbt_data.size != 0x00) { /*if non-zero, then use vbt*/
-               mode = kzalloc(sizeof(*mode), GFP_KERNEL);
-               if (!mode)
-                       return NULL;
-
-               mode->hdisplay = (ti->hactive_hi << 8) | ti->hactive_lo;
-               mode->vdisplay = (ti->vactive_hi << 8) | ti->vactive_lo;
-               mode->hsync_start = mode->hdisplay + \
-                               ((ti->hsync_offset_hi << 8) | \
-                               ti->hsync_offset_lo);
-               mode->hsync_end = mode->hsync_start + \
-                               ((ti->hsync_pulse_width_hi << 8) | \
-                               ti->hsync_pulse_width_lo);
-               mode->htotal = mode->hdisplay + ((ti->hblank_hi << 8) | \
-                                                       ti->hblank_lo);
-               mode->vsync_start = \
-                       mode->vdisplay + ((ti->vsync_offset_hi << 4) | \
-                                               ti->vsync_offset_lo);
-               mode->vsync_end = \
-                       mode->vsync_start + ((ti->vsync_pulse_width_hi << 4) | \
-                                               ti->vsync_pulse_width_lo);
-               mode->vtotal = mode->vdisplay + \
-                               ((ti->vblank_hi << 8) | ti->vblank_lo);
-               mode->clock = ti->pixel_clock * 10;
-#if 0
-               printk(KERN_INFO "hdisplay is %d\n", mode->hdisplay);
-               printk(KERN_INFO "vdisplay is %d\n", mode->vdisplay);
-               printk(KERN_INFO "HSS is %d\n", mode->hsync_start);
-               printk(KERN_INFO "HSE is %d\n", mode->hsync_end);
-               printk(KERN_INFO "htotal is %d\n", mode->htotal);
-               printk(KERN_INFO "VSS is %d\n", mode->vsync_start);
-               printk(KERN_INFO "VSE is %d\n", mode->vsync_end);
-               printk(KERN_INFO "vtotal is %d\n", mode->vtotal);
-               printk(KERN_INFO "clock is %d\n", mode->clock);
-#endif
-       } else
-               mode = drm_mode_duplicate(dev, &lvds_configuration_modes[2]);
-
-       drm_mode_set_name(mode);
-       drm_mode_set_crtcinfo(mode, 0);
-
-       return mode;
-}
-
-/**
- * mrst_lvds_init - setup LVDS connectors on this device
- * @dev: drm device
- *
- * Create the connector, register the LVDS DDC bus, and try to figure out what
- * modes we can display on the LVDS panel (if present).
- */
-void mrst_lvds_init(struct drm_device *dev,
-                   struct psb_intel_mode_device *mode_dev)
-{
-       struct psb_intel_output *psb_intel_output;
-       struct drm_connector *connector;
-       struct drm_encoder *encoder;
-       struct drm_psb_private *dev_priv =
-                               (struct drm_psb_private *) dev->dev_private;
-       struct edid *edid;
-       int ret = 0;
-       struct i2c_adapter *i2c_adap;
-       struct drm_display_mode *scan;  /* *modes, *bios_mode; */
-
-       psb_intel_output = kzalloc(sizeof(struct psb_intel_output), GFP_KERNEL);
-       if (!psb_intel_output)
-               return;
-
-       psb_intel_output->mode_dev = mode_dev;
-       connector = &psb_intel_output->base;
-       encoder = &psb_intel_output->enc;
-       dev_priv->is_lvds_on = true;
-       drm_connector_init(dev, &psb_intel_output->base,
-                          &psb_intel_lvds_connector_funcs,
-                          DRM_MODE_CONNECTOR_LVDS);
-
-       drm_encoder_init(dev, &psb_intel_output->enc, &psb_intel_lvds_enc_funcs,
-                        DRM_MODE_ENCODER_LVDS);
-
-       drm_mode_connector_attach_encoder(&psb_intel_output->base,
-                                         &psb_intel_output->enc);
-       psb_intel_output->type = INTEL_OUTPUT_LVDS;
-
-       drm_encoder_helper_add(encoder, &mrst_lvds_helper_funcs);
-       drm_connector_helper_add(connector,
-                                &psb_intel_lvds_connector_helper_funcs);
-       connector->display_info.subpixel_order = SubPixelHorizontalRGB;
-       connector->interlace_allowed = false;
-       connector->doublescan_allowed = false;
-
-       drm_connector_attach_property(connector,
-                                       dev->mode_config.scaling_mode_property,
-                                       DRM_MODE_SCALE_FULLSCREEN);
-       drm_connector_attach_property(connector,
-                                       dev_priv->backlight_property,
-                                       BRIGHTNESS_MAX_LEVEL);
-
-       mode_dev->panel_wants_dither = false;
-       if (dev_priv->vbt_data.size != 0x00)
-               mode_dev->panel_wants_dither = (dev_priv->gct_data.
-                       Panel_Port_Control & MRST_PANEL_8TO6_DITHER_ENABLE);
-
-       /*
-        * LVDS discovery:
-        * 1) check for EDID on DDC
-        * 2) check for VBT data
-        * 3) check to see if LVDS is already on
-        *    if none of the above, no panel
-        * 4) make sure lid is open
-        *    if closed, act like it's not there for now
-        */
-
-       i2c_adap = i2c_get_adapter(dev_priv->ops->i2c_bus);
-
-       if (i2c_adap == NULL)
-               dev_err(dev->dev, "No ddc adapter available!\n");
-       /*
-        * Attempt to get the fixed panel mode from DDC.  Assume that the
-        * preferred mode is the right one.
-        */
-       if (i2c_adap) {
-               edid = drm_get_edid(connector, i2c_adap);
-               if (edid) {
-                       drm_mode_connector_update_edid_property(connector,
-                                                                       edid);
-                       ret = drm_add_edid_modes(connector, edid);
-                       kfree(edid);
-               }
-
-               list_for_each_entry(scan, &connector->probed_modes, head) {
-                       if (scan->type & DRM_MODE_TYPE_PREFERRED) {
-                               mode_dev->panel_fixed_mode =
-                                   drm_mode_duplicate(dev, scan);
-                               goto out;       /* FIXME: check for quirks */
-                       }
-               }
-       }
-       /*
-        * If we didn't get EDID, try geting panel timing
-        * from configuration data
-        */
-       mode_dev->panel_fixed_mode = mrst_lvds_get_configuration_mode(dev);
-
-       if (mode_dev->panel_fixed_mode) {
-               mode_dev->panel_fixed_mode->type |= DRM_MODE_TYPE_PREFERRED;
-               goto out;       /* FIXME: check for quirks */
-       }
-
-       /* If we still don't have a mode after all that, give up. */
-       if (!mode_dev->panel_fixed_mode) {
-               dev_err(dev->dev, "Found no modes on the lvds, ignoring the LVDS\n");
-               goto failed_find;
-       }
-
-out:
-       drm_sysfs_connector_add(connector);
-       return;
-
-failed_find:
-       dev_dbg(dev->dev, "No LVDS modes found, disabling.\n");
-       if (psb_intel_output->ddc_bus)
-               psb_intel_i2c_destroy(psb_intel_output->ddc_bus);
-
-/* failed_ddc: */
-
-       drm_encoder_cleanup(encoder);
-       drm_connector_cleanup(connector);
-       kfree(connector);
-}
-
diff --git a/drivers/staging/gma500/power.c b/drivers/staging/gma500/power.c
deleted file mode 100644 (file)
index 4082570..0000000
+++ /dev/null
@@ -1,318 +0,0 @@
-/**************************************************************************
- * Copyright (c) 2009-2011, Intel Corporation.
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Authors:
- *    Benjamin Defnet <benjamin.r.defnet@intel.com>
- *    Rajesh Poornachandran <rajesh.poornachandran@intel.com>
- * Massively reworked
- *    Alan Cox <alan@linux.intel.com>
- */
-
-#include "power.h"
-#include "psb_drv.h"
-#include "psb_reg.h"
-#include "psb_intel_reg.h"
-#include <linux/mutex.h>
-#include <linux/pm_runtime.h>
-
-static struct mutex power_mutex;       /* Serialize power ops */
-static spinlock_t power_ctrl_lock;     /* Serialize power claim */
-
-/**
- *     gma_power_init          -       initialise power manager
- *     @dev: our device
- *
- *     Set up for power management tracking of our hardware.
- */
-void gma_power_init(struct drm_device *dev)
-{
-       struct drm_psb_private *dev_priv = dev->dev_private;
-
-       /* FIXME: Move APM/OSPM base into relevant device code */
-       dev_priv->apm_base = dev_priv->apm_reg & 0xffff;
-       dev_priv->ospm_base &= 0xffff;
-
-       dev_priv->display_power = true; /* We start active */
-       dev_priv->display_count = 0;    /* Currently no users */
-       dev_priv->suspended = false;    /* And not suspended */
-       spin_lock_init(&power_ctrl_lock);
-       mutex_init(&power_mutex);
-
-       dev_priv->ops->init_pm(dev);
-}
-
-/**
- *     gma_power_uninit        -       end power manager
- *     @dev: device to end for
- *
- *     Undo the effects of gma_power_init
- */
-void gma_power_uninit(struct drm_device *dev)
-{
-       pm_runtime_disable(&dev->pdev->dev);
-       pm_runtime_set_suspended(&dev->pdev->dev);
-}
-
-/**
- *     gma_suspend_display     -       suspend the display logic
- *     @dev: our DRM device
- *
- *     Suspend the display logic of the graphics interface
- */
-static void gma_suspend_display(struct drm_device *dev)
-{
-       struct drm_psb_private *dev_priv = dev->dev_private;
-
-       if (!dev_priv->display_power)
-               return;
-       dev_priv->ops->save_regs(dev);
-       dev_priv->ops->power_down(dev);
-       dev_priv->display_power = false;
-}
-
-/**
- *     gma_resume_display      -       resume display side logic
- *
- *     Resume the display hardware restoring state and enabling
- *     as necessary.
- */
-static void gma_resume_display(struct pci_dev *pdev)
-{
-       struct drm_device *dev = pci_get_drvdata(pdev);
-       struct drm_psb_private *dev_priv = dev->dev_private;
-
-       if (dev_priv->display_power)
-               return;
-
-       /* turn on the display power island */
-       dev_priv->ops->power_up(dev);
-       dev_priv->suspended = false;
-       dev_priv->display_power = true;
-
-       PSB_WVDC32(dev_priv->pge_ctl | _PSB_PGETBL_ENABLED, PSB_PGETBL_CTL);
-       pci_write_config_word(pdev, PSB_GMCH_CTRL,
-                       dev_priv->gmch_ctrl | _PSB_GMCH_ENABLED);
-       dev_priv->ops->restore_regs(dev);
-}
-
-/**
- *     gma_suspend_pci         -       suspend PCI side
- *     @pdev: PCI device
- *
- *     Perform the suspend processing on our PCI device state
- */
-static void gma_suspend_pci(struct pci_dev *pdev)
-{
-       struct drm_device *dev = pci_get_drvdata(pdev);
-       struct drm_psb_private *dev_priv = dev->dev_private;
-       int bsm, vbt;
-
-       if (dev_priv->suspended)
-               return;
-
-       pci_save_state(pdev);
-       pci_read_config_dword(pdev, 0x5C, &bsm);
-       dev_priv->saveBSM = bsm;
-       pci_read_config_dword(pdev, 0xFC, &vbt);
-       dev_priv->saveVBT = vbt;
-       pci_read_config_dword(pdev, PSB_PCIx_MSI_ADDR_LOC, &dev_priv->msi_addr);
-       pci_read_config_dword(pdev, PSB_PCIx_MSI_DATA_LOC, &dev_priv->msi_data);
-
-       pci_disable_device(pdev);
-       pci_set_power_state(pdev, PCI_D3hot);
-
-       dev_priv->suspended = true;
-}
-
-/**
- *     gma_resume_pci          -       resume helper
- *     @dev: our PCI device
- *
- *     Perform the resume processing on our PCI device state - rewrite
- *     register state and re-enable the PCI device
- */
-static bool gma_resume_pci(struct pci_dev *pdev)
-{
-       struct drm_device *dev = pci_get_drvdata(pdev);
-       struct drm_psb_private *dev_priv = dev->dev_private;
-       int ret;
-
-       if (!dev_priv->suspended)
-               return true;
-
-       pci_set_power_state(pdev, PCI_D0);
-       pci_restore_state(pdev);
-       pci_write_config_dword(pdev, 0x5c, dev_priv->saveBSM);
-       pci_write_config_dword(pdev, 0xFC, dev_priv->saveVBT);
-       /* restoring MSI address and data in PCIx space */
-       pci_write_config_dword(pdev, PSB_PCIx_MSI_ADDR_LOC, dev_priv->msi_addr);
-       pci_write_config_dword(pdev, PSB_PCIx_MSI_DATA_LOC, dev_priv->msi_data);
-       ret = pci_enable_device(pdev);
-
-       if (ret != 0)
-               dev_err(&pdev->dev, "pci_enable failed: %d\n", ret);
-       else
-               dev_priv->suspended = false;
-       return !dev_priv->suspended;
-}
-
-/**
- *     gma_power_suspend               -       bus callback for suspend
- *     @pdev: our PCI device
- *     @state: suspend type
- *
- *     Called back by the PCI layer during a suspend of the system. We
- *     perform the necessary shut down steps and save enough state that
- *     we can undo this when resume is called.
- */
-int gma_power_suspend(struct device *_dev)
-{
-       struct pci_dev *pdev = container_of(_dev, struct pci_dev, dev);
-       struct drm_device *dev = pci_get_drvdata(pdev);
-       struct drm_psb_private *dev_priv = dev->dev_private;
-
-       mutex_lock(&power_mutex);
-       if (!dev_priv->suspended) {
-               if (dev_priv->display_count) {
-                       mutex_unlock(&power_mutex);
-                       return -EBUSY;
-               }
-               psb_irq_uninstall(dev);
-               gma_suspend_display(dev);
-               gma_suspend_pci(pdev);
-       }
-       mutex_unlock(&power_mutex);
-       return 0;
-}
-
-/**
- *     gma_power_resume                -       resume power
- *     @pdev: PCI device
- *
- *     Resume the PCI side of the graphics and then the displays
- */
-int gma_power_resume(struct device *_dev)
-{
-       struct pci_dev *pdev = container_of(_dev, struct pci_dev, dev);
-       struct drm_device *dev = pci_get_drvdata(pdev);
-
-       mutex_lock(&power_mutex);
-       gma_resume_pci(pdev);
-       gma_resume_display(pdev);
-       psb_irq_preinstall(dev);
-       psb_irq_postinstall(dev);
-       mutex_unlock(&power_mutex);
-       return 0;
-}
-
-/**
- *     gma_power_is_on         -       returne true if power is on
- *     @dev: our DRM device
- *
- *     Returns true if the display island power is on at this moment
- */
-bool gma_power_is_on(struct drm_device *dev)
-{
-       struct drm_psb_private *dev_priv = dev->dev_private;
-       return dev_priv->display_power;
-}
-
-/**
- *     gma_power_begin         -       begin requiring power
- *     @dev: our DRM device
- *     @force_on: true to force power on
- *
- *     Begin an action that requires the display power island is enabled.
- *     We refcount the islands.
- */
-bool gma_power_begin(struct drm_device *dev, bool force_on)
-{
-       struct drm_psb_private *dev_priv = dev->dev_private;
-       int ret;
-       unsigned long flags;
-
-       spin_lock_irqsave(&power_ctrl_lock, flags);
-       /* Power already on ? */
-       if (dev_priv->display_power) {
-               dev_priv->display_count++;
-               pm_runtime_get(&dev->pdev->dev);
-               spin_unlock_irqrestore(&power_ctrl_lock, flags);
-               return true;
-       }
-       if (force_on == false)
-               goto out_false;
-
-       /* Ok power up needed */
-       ret = gma_resume_pci(dev->pdev);
-       if (ret == 0) {
-               /* FIXME: we want to defer this for Medfield/Oaktrail */
-               gma_resume_display(dev->pdev);
-               psb_irq_preinstall(dev);
-               psb_irq_postinstall(dev);
-               pm_runtime_get(&dev->pdev->dev);
-               dev_priv->display_count++;
-               spin_unlock_irqrestore(&power_ctrl_lock, flags);
-               return true;
-       }
-out_false:
-       spin_unlock_irqrestore(&power_ctrl_lock, flags);
-       return false;
-}
-
-/**
- *     gma_power_end           -       end use of power
- *     @dev: Our DRM device
- *
- *     Indicate that one of our gma_power_begin() requested periods when
- *     the diplay island power is needed has completed.
- */
-void gma_power_end(struct drm_device *dev)
-{
-       struct drm_psb_private *dev_priv = dev->dev_private;
-       unsigned long flags;
-       spin_lock_irqsave(&power_ctrl_lock, flags);
-       dev_priv->display_count--;
-       WARN_ON(dev_priv->display_count < 0);
-       spin_unlock_irqrestore(&power_ctrl_lock, flags);
-       pm_runtime_put(&dev->pdev->dev);
-}
-
-int psb_runtime_suspend(struct device *dev)
-{
-       return gma_power_suspend(dev);
-}
-
-int psb_runtime_resume(struct device *dev)
-{
-       return gma_power_resume(dev);;
-}
-
-int psb_runtime_idle(struct device *dev)
-{
-       struct drm_device *drmdev = pci_get_drvdata(to_pci_dev(dev));
-       struct drm_psb_private *dev_priv = drmdev->dev_private;
-       if (dev_priv->display_count)
-               return 0;
-       else
-               return 1;
-}
diff --git a/drivers/staging/gma500/power.h b/drivers/staging/gma500/power.h
deleted file mode 100644 (file)
index 1969d2e..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-/**************************************************************************
- * Copyright (c) 2009-2011, Intel Corporation.
- * All Rights Reserved.
-
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Authors:
- *    Benjamin Defnet <benjamin.r.defnet@intel.com>
- *    Rajesh Poornachandran <rajesh.poornachandran@intel.com>
- * Massively reworked
- *    Alan Cox <alan@linux.intel.com>
- */
-#ifndef _PSB_POWERMGMT_H_
-#define _PSB_POWERMGMT_H_
-
-#include <linux/pci.h>
-#include <drm/drmP.h>
-
-void gma_power_init(struct drm_device *dev);
-void gma_power_uninit(struct drm_device *dev);
-
-/*
- * The kernel bus power management  will call these functions
- */
-int gma_power_suspend(struct device *dev);
-int gma_power_resume(struct device *dev);
-
-/*
- * These are the functions the driver should use to wrap all hw access
- * (i.e. register reads and writes)
- */
-bool gma_power_begin(struct drm_device *dev, bool force);
-void gma_power_end(struct drm_device *dev);
-
-/*
- * Use this function to do an instantaneous check for if the hw is on.
- * Only use this in cases where you know the mutex is already held such
- * as in irq install/uninstall and you need to
- * prevent a deadlock situation.  Otherwise use gma_power_begin().
- */
-bool gma_power_is_on(struct drm_device *dev);
-
-/*
- * GFX-Runtime PM callbacks
- */
-int psb_runtime_suspend(struct device *dev);
-int psb_runtime_resume(struct device *dev);
-int psb_runtime_idle(struct device *dev);
-
-#endif /*_PSB_POWERMGMT_H_*/
diff --git a/drivers/staging/gma500/psb_device.c b/drivers/staging/gma500/psb_device.c
deleted file mode 100644 (file)
index b97aa78..0000000
+++ /dev/null
@@ -1,321 +0,0 @@
-/**************************************************************************
- * Copyright (c) 2011, Intel Corporation.
- * All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- **************************************************************************/
-
-#include <linux/backlight.h>
-#include <drm/drmP.h>
-#include <drm/drm.h>
-#include "psb_drm.h"
-#include "psb_drv.h"
-#include "psb_reg.h"
-#include "psb_intel_reg.h"
-#include "intel_bios.h"
-
-
-static int psb_output_init(struct drm_device *dev)
-{
-       struct drm_psb_private *dev_priv = dev->dev_private;
-       psb_intel_lvds_init(dev, &dev_priv->mode_dev);
-       psb_intel_sdvo_init(dev, SDVOB);
-       return 0;
-}
-
-#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
-
-/*
- *     Poulsbo Backlight Interfaces
- */
-
-#define BLC_PWM_PRECISION_FACTOR 100   /* 10000000 */
-#define BLC_PWM_FREQ_CALC_CONSTANT 32
-#define MHz 1000000
-
-#define PSB_BLC_PWM_PRECISION_FACTOR    10
-#define PSB_BLC_MAX_PWM_REG_FREQ        0xFFFE
-#define PSB_BLC_MIN_PWM_REG_FREQ        0x2
-
-#define PSB_BACKLIGHT_PWM_POLARITY_BIT_CLEAR (0xFFFE)
-#define PSB_BACKLIGHT_PWM_CTL_SHIFT    (16)
-
-static int psb_brightness;
-static struct backlight_device *psb_backlight_device;
-
-static int psb_get_brightness(struct backlight_device *bd)
-{
-       /* return locally cached var instead of HW read (due to DPST etc.) */
-       /* FIXME: ideally return actual value in case firmware fiddled with
-          it */
-       return psb_brightness;
-}
-
-
-static int psb_backlight_setup(struct drm_device *dev)
-{
-       struct drm_psb_private *dev_priv = dev->dev_private;
-       unsigned long core_clock;
-       /* u32 bl_max_freq; */
-       /* unsigned long value; */
-       u16 bl_max_freq;
-       uint32_t value;
-       uint32_t blc_pwm_precision_factor;
-
-       /* get bl_max_freq and pol from dev_priv*/
-       if (!dev_priv->lvds_bl) {
-               dev_err(dev->dev, "Has no valid LVDS backlight info\n");
-               return -ENOENT;
-       }
-       bl_max_freq = dev_priv->lvds_bl->freq;
-       blc_pwm_precision_factor = PSB_BLC_PWM_PRECISION_FACTOR;
-
-       core_clock = dev_priv->core_freq;
-
-       value = (core_clock * MHz) / BLC_PWM_FREQ_CALC_CONSTANT;
-       value *= blc_pwm_precision_factor;
-       value /= bl_max_freq;
-       value /= blc_pwm_precision_factor;
-
-       if (value > (unsigned long long)PSB_BLC_MAX_PWM_REG_FREQ ||
-                value < (unsigned long long)PSB_BLC_MIN_PWM_REG_FREQ)
-                               return -ERANGE;
-       else {
-               value &= PSB_BACKLIGHT_PWM_POLARITY_BIT_CLEAR;
-               REG_WRITE(BLC_PWM_CTL,
-                       (value << PSB_BACKLIGHT_PWM_CTL_SHIFT) | (value));
-       }
-       return 0;
-}
-
-static int psb_set_brightness(struct backlight_device *bd)
-{
-       struct drm_device *dev = bl_get_data(psb_backlight_device);
-       int level = bd->props.brightness;
-
-       /* Percentage 1-100% being valid */
-       if (level < 1)
-               level = 1;
-
-       psb_intel_lvds_set_brightness(dev, level);
-       psb_brightness = level;
-       return 0;
-}
-
-static const struct backlight_ops psb_ops = {
-       .get_brightness = psb_get_brightness,
-       .update_status  = psb_set_brightness,
-};
-
-static int psb_backlight_init(struct drm_device *dev)
-{
-       struct drm_psb_private *dev_priv = dev->dev_private;
-       int ret;
-       struct backlight_properties props;
-
-       memset(&props, 0, sizeof(struct backlight_properties));
-       props.max_brightness = 100;
-       props.type = BACKLIGHT_PLATFORM;
-
-       psb_backlight_device = backlight_device_register("psb-bl",
-                                       NULL, (void *)dev, &psb_ops, &props);
-       if (IS_ERR(psb_backlight_device))
-               return PTR_ERR(psb_backlight_device);
-
-       ret = psb_backlight_setup(dev);
-       if (ret < 0) {
-               backlight_device_unregister(psb_backlight_device);
-               psb_backlight_device = NULL;
-               return ret;
-       }
-       psb_backlight_device->props.brightness = 100;
-       psb_backlight_device->props.max_brightness = 100;
-       backlight_update_status(psb_backlight_device);
-       dev_priv->backlight_device = psb_backlight_device;
-       return 0;
-}
-
-#endif
-
-/*
- *     Provide the Poulsbo specific chip logic and low level methods
- *     for power management
- */
-
-static void psb_init_pm(struct drm_device *dev)
-{
-       struct drm_psb_private *dev_priv = dev->dev_private;
-
-       u32 gating = PSB_RSGX32(PSB_CR_CLKGATECTL);
-       gating &= ~3;   /* Disable 2D clock gating */
-       gating |= 1;
-       PSB_WSGX32(gating, PSB_CR_CLKGATECTL);
-       PSB_RSGX32(PSB_CR_CLKGATECTL);
-}
-
-/**
- *     psb_save_display_registers      -       save registers lost on suspend
- *     @dev: our DRM device
- *
- *     Save the state we need in order to be able to restore the interface
- *     upon resume from suspend
- */
-static int psb_save_display_registers(struct drm_device *dev)
-{
-       struct drm_psb_private *dev_priv = dev->dev_private;
-       struct drm_crtc *crtc;
-       struct drm_connector *connector;
-
-       /* Display arbitration control + watermarks */
-       dev_priv->saveDSPARB = PSB_RVDC32(DSPARB);
-       dev_priv->saveDSPFW1 = PSB_RVDC32(DSPFW1);
-       dev_priv->saveDSPFW2 = PSB_RVDC32(DSPFW2);
-       dev_priv->saveDSPFW3 = PSB_RVDC32(DSPFW3);
-       dev_priv->saveDSPFW4 = PSB_RVDC32(DSPFW4);
-       dev_priv->saveDSPFW5 = PSB_RVDC32(DSPFW5);
-       dev_priv->saveDSPFW6 = PSB_RVDC32(DSPFW6);
-       dev_priv->saveCHICKENBIT = PSB_RVDC32(DSPCHICKENBIT);
-
-       /* Save crtc and output state */
-       mutex_lock(&dev->mode_config.mutex);
-       list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
-               if (drm_helper_crtc_in_use(crtc))
-                       crtc->funcs->save(crtc);
-       }
-
-       list_for_each_entry(connector, &dev->mode_config.connector_list, head)
-               connector->funcs->save(connector);
-
-       mutex_unlock(&dev->mode_config.mutex);
-       return 0;
-}
-
-/**
- *     psb_restore_display_registers   -       restore lost register state
- *     @dev: our DRM device
- *
- *     Restore register state that was lost during suspend and resume.
- */
-static int psb_restore_display_registers(struct drm_device *dev)
-{
-       struct drm_psb_private *dev_priv = dev->dev_private;
-       struct drm_crtc *crtc;
-       struct drm_connector *connector;
-
-       /* Display arbitration + watermarks */
-       PSB_WVDC32(dev_priv->saveDSPARB, DSPARB);
-       PSB_WVDC32(dev_priv->saveDSPFW1, DSPFW1);
-       PSB_WVDC32(dev_priv->saveDSPFW2, DSPFW2);
-       PSB_WVDC32(dev_priv->saveDSPFW3, DSPFW3);
-       PSB_WVDC32(dev_priv->saveDSPFW4, DSPFW4);
-       PSB_WVDC32(dev_priv->saveDSPFW5, DSPFW5);
-       PSB_WVDC32(dev_priv->saveDSPFW6, DSPFW6);
-       PSB_WVDC32(dev_priv->saveCHICKENBIT, DSPCHICKENBIT);
-
-       /*make sure VGA plane is off. it initializes to on after reset!*/
-       PSB_WVDC32(0x80000000, VGACNTRL);
-
-       mutex_lock(&dev->mode_config.mutex);
-       list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
-               if (drm_helper_crtc_in_use(crtc))
-                       crtc->funcs->restore(crtc);
-
-       list_for_each_entry(connector, &dev->mode_config.connector_list, head)
-               connector->funcs->restore(connector);
-
-       mutex_unlock(&dev->mode_config.mutex);
-       return 0;
-}
-
-static int psb_power_down(struct drm_device *dev)
-{
-       return 0;
-}
-
-static int psb_power_up(struct drm_device *dev)
-{
-       return 0;
-}
-
-static void psb_get_core_freq(struct drm_device *dev)
-{
-       uint32_t clock;
-       struct pci_dev *pci_root = pci_get_bus_and_slot(0, 0);
-       struct drm_psb_private *dev_priv = dev->dev_private;
-
-       /*pci_write_config_dword(pci_root, 0xD4, 0x00C32004);*/
-       /*pci_write_config_dword(pci_root, 0xD0, 0xE0033000);*/
-
-       pci_write_config_dword(pci_root, 0xD0, 0xD0050300);
-       pci_read_config_dword(pci_root, 0xD4, &clock);
-       pci_dev_put(pci_root);
-
-       switch (clock & 0x07) {
-       case 0:
-               dev_priv->core_freq = 100;
-               break;
-       case 1:
-               dev_priv->core_freq = 133;
-               break;
-       case 2:
-               dev_priv->core_freq = 150;
-               break;
-       case 3:
-               dev_priv->core_freq = 178;
-               break;
-       case 4:
-               dev_priv->core_freq = 200;
-               break;
-       case 5:
-       case 6:
-       case 7:
-               dev_priv->core_freq = 266;
-       default:
-               dev_priv->core_freq = 0;
-       }
-}
-
-static int psb_chip_setup(struct drm_device *dev)
-{
-       psb_get_core_freq(dev);
-       gma_intel_opregion_init(dev);
-       psb_intel_init_bios(dev);
-       return 0;
-}
-
-const struct psb_ops psb_chip_ops = {
-       .name = "Poulsbo",
-       .accel_2d = 1,
-       .pipes = 2,
-       .crtcs = 2,
-       .sgx_offset = PSB_SGX_OFFSET,
-       .chip_setup = psb_chip_setup,
-
-       .crtc_helper = &psb_intel_helper_funcs,
-       .crtc_funcs = &psb_intel_crtc_funcs,
-
-       .output_init = psb_output_init,
-
-#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
-       .backlight_init = psb_backlight_init,
-#endif
-
-       .init_pm = psb_init_pm,
-       .save_regs = psb_save_display_registers,
-       .restore_regs = psb_restore_display_registers,
-       .power_down = psb_power_down,
-       .power_up = psb_power_up,
-};
-
diff --git a/drivers/staging/gma500/psb_drm.h b/drivers/staging/gma500/psb_drm.h
deleted file mode 100644 (file)
index 0da8468..0000000
+++ /dev/null
@@ -1,219 +0,0 @@
-/**************************************************************************
- * Copyright (c) 2007-2011, Intel Corporation.
- * All Rights Reserved.
- * Copyright (c) 2008, Tungsten Graphics Inc.  Cedar Park, TX., USA.
- * All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- **************************************************************************/
-
-#ifndef _PSB_DRM_H_
-#define _PSB_DRM_H_
-
-#define PSB_NUM_PIPE 3
-
-#define PSB_GPU_ACCESS_READ         (1ULL << 32)
-#define PSB_GPU_ACCESS_WRITE        (1ULL << 33)
-#define PSB_GPU_ACCESS_MASK         (PSB_GPU_ACCESS_READ | PSB_GPU_ACCESS_WRITE)
-
-#define PSB_BO_FLAG_COMMAND         (1ULL << 52)
-
-/*
- * Feedback components:
- */
-
-struct drm_psb_sizes_arg {
-       u32 ta_mem_size;
-       u32 mmu_size;
-       u32 pds_size;
-       u32 rastgeom_size;
-       u32 tt_size;
-       u32 vram_size;
-};
-
-struct drm_psb_dpst_lut_arg {
-       uint8_t lut[256];
-       int output_id;
-};
-
-#define PSB_DC_CRTC_SAVE 0x01
-#define PSB_DC_CRTC_RESTORE 0x02
-#define PSB_DC_OUTPUT_SAVE 0x04
-#define PSB_DC_OUTPUT_RESTORE 0x08
-#define PSB_DC_CRTC_MASK 0x03
-#define PSB_DC_OUTPUT_MASK 0x0C
-
-struct drm_psb_dc_state_arg {
-       u32 flags;
-       u32 obj_id;
-};
-
-struct drm_psb_mode_operation_arg {
-       u32 obj_id;
-       u16 operation;
-       struct drm_mode_modeinfo mode;
-       void *data;
-};
-
-struct drm_psb_stolen_memory_arg {
-       u32 base;
-       u32 size;
-};
-
-/*Display Register Bits*/
-#define REGRWBITS_PFIT_CONTROLS                        (1 << 0)
-#define REGRWBITS_PFIT_AUTOSCALE_RATIOS                (1 << 1)
-#define REGRWBITS_PFIT_PROGRAMMED_SCALE_RATIOS (1 << 2)
-#define REGRWBITS_PIPEASRC                     (1 << 3)
-#define REGRWBITS_PIPEBSRC                     (1 << 4)
-#define REGRWBITS_VTOTAL_A                     (1 << 5)
-#define REGRWBITS_VTOTAL_B                     (1 << 6)
-#define REGRWBITS_DSPACNTR     (1 << 8)
-#define REGRWBITS_DSPBCNTR     (1 << 9)
-#define REGRWBITS_DSPCCNTR     (1 << 10)
-
-/*Overlay Register Bits*/
-#define OV_REGRWBITS_OVADD                     (1 << 0)
-#define OV_REGRWBITS_OGAM_ALL                  (1 << 1)
-
-#define OVC_REGRWBITS_OVADD                  (1 << 2)
-#define OVC_REGRWBITS_OGAM_ALL                 (1 << 3)
-
-struct drm_psb_register_rw_arg {
-       u32 b_force_hw_on;
-
-       u32 display_read_mask;
-       u32 display_write_mask;
-
-       struct {
-               u32 pfit_controls;
-               u32 pfit_autoscale_ratios;
-               u32 pfit_programmed_scale_ratios;
-               u32 pipeasrc;
-               u32 pipebsrc;
-               u32 vtotal_a;
-               u32 vtotal_b;
-       } display;
-
-       u32 overlay_read_mask;
-       u32 overlay_write_mask;
-
-       struct {
-               u32 OVADD;
-               u32 OGAMC0;
-               u32 OGAMC1;
-               u32 OGAMC2;
-               u32 OGAMC3;
-               u32 OGAMC4;
-               u32 OGAMC5;
-               u32 IEP_ENABLED;
-               u32 IEP_BLE_MINMAX;
-               u32 IEP_BSSCC_CONTROL;
-               u32 b_wait_vblank;
-       } overlay;
-
-       u32 sprite_enable_mask;
-       u32 sprite_disable_mask;
-
-       struct {
-               u32 dspa_control;
-               u32 dspa_key_value;
-               u32 dspa_key_mask;
-               u32 dspc_control;
-               u32 dspc_stride;
-               u32 dspc_position;
-               u32 dspc_linear_offset;
-               u32 dspc_size;
-               u32 dspc_surface;
-       } sprite;
-
-       u32 subpicture_enable_mask;
-       u32 subpicture_disable_mask;
-};
-
-/* Controlling the kernel modesetting buffers */
-
-#define DRM_PSB_SIZES           0x07
-#define DRM_PSB_FUSE_REG       0x08
-#define DRM_PSB_DC_STATE       0x0A
-#define DRM_PSB_ADB            0x0B
-#define DRM_PSB_MODE_OPERATION 0x0C
-#define DRM_PSB_STOLEN_MEMORY  0x0D
-#define DRM_PSB_REGISTER_RW    0x0E
-
-/*
- * NOTE: Add new commands here, but increment
- * the values below and increment their
- * corresponding defines where they're
- * defined elsewhere.
- */
-
-#define DRM_PSB_GEM_CREATE     0x10
-#define DRM_PSB_2D_OP          0x11
-#define DRM_PSB_GEM_MMAP       0x12
-#define DRM_PSB_DPST           0x1B
-#define DRM_PSB_GAMMA          0x1C
-#define DRM_PSB_DPST_BL                0x1D
-#define DRM_PSB_GET_PIPE_FROM_CRTC_ID 0x1F
-
-#define PSB_MODE_OPERATION_MODE_VALID  0x01
-#define PSB_MODE_OPERATION_SET_DC_BASE  0x02
-
-struct drm_psb_get_pipe_from_crtc_id_arg {
-       /** ID of CRTC being requested **/
-       u32 crtc_id;
-
-       /** pipe of requested CRTC **/
-       u32 pipe;
-};
-
-/* FIXME: move this into a medfield header once we are sure it isn't needed for an
-   ioctl  */
-struct psb_drm_dpu_rect {  
-       int x, y;             
-       int width, height;    
-};  
-
-struct drm_psb_gem_create {
-       __u64 size;
-       __u32 handle;
-       __u32 flags;
-#define PSB_GEM_CREATE_STOLEN          1       /* Stolen memory can be used */
-};
-
-#define PSB_2D_OP_BUFLEN               16
-
-struct drm_psb_2d_op {
-       __u32 src;              /* Handles, only src supported right now */
-       __u32 dst;
-       __u32 mask;
-       __u32 pat;
-       __u32 size;             /* In dwords of command */
-       __u32 spare;            /* And bumps array to u64 align */
-       __u32 cmd[PSB_2D_OP_BUFLEN];
-};
-
-struct drm_psb_gem_mmap {
-       __u32 handle;
-       __u32 pad;
-       /**
-        * Fake offset to use for subsequent mmap call
-        *
-        * This is a fixed-size type for 32/64 compatibility.
-        */
-       __u64 offset;
-};
-
-#endif
diff --git a/drivers/staging/gma500/psb_drv.c b/drivers/staging/gma500/psb_drv.c
deleted file mode 100644 (file)
index 9581680..0000000
+++ /dev/null
@@ -1,1230 +0,0 @@
-/**************************************************************************
- * Copyright (c) 2007-2011, Intel Corporation.
- * All Rights Reserved.
- * Copyright (c) 2008, Tungsten Graphics, Inc. Cedar Park, TX., USA.
- * All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- **************************************************************************/
-
-#include <drm/drmP.h>
-#include <drm/drm.h>
-#include "psb_drm.h"
-#include "psb_drv.h"
-#include "framebuffer.h"
-#include "psb_reg.h"
-#include "psb_intel_reg.h"
-#include "intel_bios.h"
-#include "mid_bios.h"
-#include "mdfld_dsi_dbi.h"
-#include <drm/drm_pciids.h>
-#include "power.h"
-#include <linux/cpu.h>
-#include <linux/notifier.h>
-#include <linux/spinlock.h>
-#include <linux/pm_runtime.h>
-#include <linux/module.h>
-#include <acpi/video.h>
-
-static int drm_psb_trap_pagefaults;
-
-int drm_psb_no_fb;
-
-static int psb_probe(struct pci_dev *pdev, const struct pci_device_id *ent);
-
-MODULE_PARM_DESC(no_fb, "Disable FBdev");
-MODULE_PARM_DESC(trap_pagefaults, "Error and reset on MMU pagefaults");
-module_param_named(no_fb, drm_psb_no_fb, int, 0600);
-module_param_named(trap_pagefaults, drm_psb_trap_pagefaults, int, 0600);
-
-
-static DEFINE_PCI_DEVICE_TABLE(pciidlist) = {
-       { 0x8086, 0x8108, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &psb_chip_ops },
-       { 0x8086, 0x8109, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &psb_chip_ops },
-#if defined(CONFIG_DRM_PSB_MRST)
-       { 0x8086, 0x4100, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &mrst_chip_ops},
-       { 0x8086, 0x4101, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &mrst_chip_ops},
-       { 0x8086, 0x4102, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &mrst_chip_ops},
-       { 0x8086, 0x4103, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &mrst_chip_ops},
-       { 0x8086, 0x4104, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &mrst_chip_ops},
-       { 0x8086, 0x4105, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &mrst_chip_ops},
-       { 0x8086, 0x4106, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &mrst_chip_ops},
-       { 0x8086, 0x4107, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &mrst_chip_ops},
-#endif
-#if defined(CONFIG_DRM_PSB_MFLD)
-       { 0x8086, 0x0130, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &mdfld_chip_ops},
-       { 0x8086, 0x0131, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &mdfld_chip_ops},
-       { 0x8086, 0x0132, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &mdfld_chip_ops},
-       { 0x8086, 0x0133, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &mdfld_chip_ops},
-       { 0x8086, 0x0134, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &mdfld_chip_ops},
-       { 0x8086, 0x0135, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &mdfld_chip_ops},
-       { 0x8086, 0x0136, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &mdfld_chip_ops},
-       { 0x8086, 0x0137, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &mdfld_chip_ops},
-#endif
-#if defined(CONFIG_DRM_PSB_CDV)
-       { 0x8086, 0x0be0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &cdv_chip_ops},
-       { 0x8086, 0x0be1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &cdv_chip_ops},
-       { 0x8086, 0x0be2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &cdv_chip_ops},
-       { 0x8086, 0x0be3, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &cdv_chip_ops},
-       { 0x8086, 0x0be4, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &cdv_chip_ops},
-       { 0x8086, 0x0be5, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &cdv_chip_ops},
-       { 0x8086, 0x0be6, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &cdv_chip_ops},
-       { 0x8086, 0x0be7, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &cdv_chip_ops},
-#endif
-       { 0, 0, 0}
-};
-MODULE_DEVICE_TABLE(pci, pciidlist);
-
-/*
- * Standard IOCTLs.
- */
-
-#define DRM_IOCTL_PSB_SIZES    \
-               DRM_IOR(DRM_PSB_SIZES + DRM_COMMAND_BASE, \
-                       struct drm_psb_sizes_arg)
-#define DRM_IOCTL_PSB_FUSE_REG \
-               DRM_IOWR(DRM_PSB_FUSE_REG + DRM_COMMAND_BASE, uint32_t)
-#define DRM_IOCTL_PSB_DC_STATE \
-               DRM_IOW(DRM_PSB_DC_STATE + DRM_COMMAND_BASE, \
-                       struct drm_psb_dc_state_arg)
-#define DRM_IOCTL_PSB_ADB      \
-               DRM_IOWR(DRM_PSB_ADB + DRM_COMMAND_BASE, uint32_t)
-#define DRM_IOCTL_PSB_MODE_OPERATION   \
-               DRM_IOWR(DRM_PSB_MODE_OPERATION + DRM_COMMAND_BASE, \
-                        struct drm_psb_mode_operation_arg)
-#define DRM_IOCTL_PSB_STOLEN_MEMORY    \
-               DRM_IOWR(DRM_PSB_STOLEN_MEMORY + DRM_COMMAND_BASE, \
-                        struct drm_psb_stolen_memory_arg)
-#define DRM_IOCTL_PSB_REGISTER_RW      \
-               DRM_IOWR(DRM_PSB_REGISTER_RW + DRM_COMMAND_BASE, \
-                        struct drm_psb_register_rw_arg)
-#define DRM_IOCTL_PSB_DPST     \
-               DRM_IOWR(DRM_PSB_DPST + DRM_COMMAND_BASE, \
-                        uint32_t)
-#define DRM_IOCTL_PSB_GAMMA    \
-               DRM_IOWR(DRM_PSB_GAMMA + DRM_COMMAND_BASE, \
-                        struct drm_psb_dpst_lut_arg)
-#define DRM_IOCTL_PSB_DPST_BL  \
-               DRM_IOWR(DRM_PSB_DPST_BL + DRM_COMMAND_BASE, \
-                        uint32_t)
-#define DRM_IOCTL_PSB_GET_PIPE_FROM_CRTC_ID    \
-               DRM_IOWR(DRM_PSB_GET_PIPE_FROM_CRTC_ID + DRM_COMMAND_BASE, \
-                        struct drm_psb_get_pipe_from_crtc_id_arg)
-#define DRM_IOCTL_PSB_GEM_CREATE       \
-               DRM_IOWR(DRM_PSB_GEM_CREATE + DRM_COMMAND_BASE, \
-                        struct drm_psb_gem_create)
-#define DRM_IOCTL_PSB_2D_OP    \
-               DRM_IOW(DRM_PSB_2D_OP + DRM_COMMAND_BASE, \
-                        struct drm_psb_2d_op)
-#define DRM_IOCTL_PSB_GEM_MMAP \
-               DRM_IOWR(DRM_PSB_GEM_MMAP + DRM_COMMAND_BASE, \
-                        struct drm_psb_gem_mmap)
-
-static int psb_sizes_ioctl(struct drm_device *dev, void *data,
-                          struct drm_file *file_priv);
-static int psb_dc_state_ioctl(struct drm_device *dev, void * data,
-                             struct drm_file *file_priv);
-static int psb_adb_ioctl(struct drm_device *dev, void *data,
-                        struct drm_file *file_priv);
-static int psb_mode_operation_ioctl(struct drm_device *dev, void *data,
-                                   struct drm_file *file_priv);
-static int psb_stolen_memory_ioctl(struct drm_device *dev, void *data,
-                                  struct drm_file *file_priv);
-static int psb_register_rw_ioctl(struct drm_device *dev, void *data,
-                                struct drm_file *file_priv);
-static int psb_dpst_ioctl(struct drm_device *dev, void *data,
-                         struct drm_file *file_priv);
-static int psb_gamma_ioctl(struct drm_device *dev, void *data,
-                          struct drm_file *file_priv);
-static int psb_dpst_bl_ioctl(struct drm_device *dev, void *data,
-                            struct drm_file *file_priv);
-
-#define PSB_IOCTL_DEF(ioctl, func, flags) \
-       [DRM_IOCTL_NR(ioctl) - DRM_COMMAND_BASE] = {ioctl, flags, func}
-
-static struct drm_ioctl_desc psb_ioctls[] = {
-       PSB_IOCTL_DEF(DRM_IOCTL_PSB_SIZES, psb_sizes_ioctl, DRM_AUTH),
-       PSB_IOCTL_DEF(DRM_IOCTL_PSB_DC_STATE, psb_dc_state_ioctl, DRM_AUTH),
-       PSB_IOCTL_DEF(DRM_IOCTL_PSB_ADB, psb_adb_ioctl, DRM_AUTH),
-       PSB_IOCTL_DEF(DRM_IOCTL_PSB_MODE_OPERATION, psb_mode_operation_ioctl,
-                     DRM_AUTH),
-       PSB_IOCTL_DEF(DRM_IOCTL_PSB_STOLEN_MEMORY, psb_stolen_memory_ioctl,
-                     DRM_AUTH),
-       PSB_IOCTL_DEF(DRM_IOCTL_PSB_REGISTER_RW, psb_register_rw_ioctl,
-                     DRM_AUTH),
-       PSB_IOCTL_DEF(DRM_IOCTL_PSB_DPST, psb_dpst_ioctl, DRM_AUTH),
-       PSB_IOCTL_DEF(DRM_IOCTL_PSB_GAMMA, psb_gamma_ioctl, DRM_AUTH),
-       PSB_IOCTL_DEF(DRM_IOCTL_PSB_DPST_BL, psb_dpst_bl_ioctl, DRM_AUTH),
-       PSB_IOCTL_DEF(DRM_IOCTL_PSB_GET_PIPE_FROM_CRTC_ID,
-                                       psb_intel_get_pipe_from_crtc_id, 0),
-       PSB_IOCTL_DEF(DRM_IOCTL_PSB_GEM_CREATE, psb_gem_create_ioctl,
-                                               DRM_UNLOCKED | DRM_AUTH),
-       PSB_IOCTL_DEF(DRM_IOCTL_PSB_2D_OP, psb_accel_ioctl,
-                                               DRM_UNLOCKED| DRM_AUTH),
-       PSB_IOCTL_DEF(DRM_IOCTL_PSB_GEM_MMAP, psb_gem_mmap_ioctl,
-                                               DRM_UNLOCKED | DRM_AUTH),
-};
-
-static void psb_lastclose(struct drm_device *dev)
-{
-       return;
-}
-
-static void psb_do_takedown(struct drm_device *dev)
-{
-}
-
-static int psb_do_init(struct drm_device *dev)
-{
-       struct drm_psb_private *dev_priv = dev->dev_private;
-       struct psb_gtt *pg = &dev_priv->gtt;
-
-       uint32_t stolen_gtt;
-
-       int ret = -ENOMEM;
-
-       if (pg->mmu_gatt_start & 0x0FFFFFFF) {
-               dev_err(dev->dev, "Gatt must be 256M aligned. This is a bug.\n");
-               ret = -EINVAL;
-               goto out_err;
-       }
-
-
-       stolen_gtt = (pg->stolen_size >> PAGE_SHIFT) * 4;
-       stolen_gtt = (stolen_gtt + PAGE_SIZE - 1) >> PAGE_SHIFT;
-       stolen_gtt =
-           (stolen_gtt < pg->gtt_pages) ? stolen_gtt : pg->gtt_pages;
-
-       dev_priv->gatt_free_offset = pg->mmu_gatt_start +
-           (stolen_gtt << PAGE_SHIFT) * 1024;
-
-       if (1 || drm_debug) {
-               uint32_t core_id = PSB_RSGX32(PSB_CR_CORE_ID);
-               uint32_t core_rev = PSB_RSGX32(PSB_CR_CORE_REVISION);
-               DRM_INFO("SGX core id = 0x%08x\n", core_id);
-               DRM_INFO("SGX core rev major = 0x%02x, minor = 0x%02x\n",
-                        (core_rev & _PSB_CC_REVISION_MAJOR_MASK) >>
-                        _PSB_CC_REVISION_MAJOR_SHIFT,
-                        (core_rev & _PSB_CC_REVISION_MINOR_MASK) >>
-                        _PSB_CC_REVISION_MINOR_SHIFT);
-               DRM_INFO
-                   ("SGX core rev maintenance = 0x%02x, designer = 0x%02x\n",
-                    (core_rev & _PSB_CC_REVISION_MAINTENANCE_MASK) >>
-                    _PSB_CC_REVISION_MAINTENANCE_SHIFT,
-                    (core_rev & _PSB_CC_REVISION_DESIGNER_MASK) >>
-                    _PSB_CC_REVISION_DESIGNER_SHIFT);
-       }
-
-
-       spin_lock_init(&dev_priv->irqmask_lock);
-       spin_lock_init(&dev_priv->lock_2d);
-
-       PSB_WSGX32(0x00000000, PSB_CR_BIF_BANK0);
-       PSB_WSGX32(0x00000000, PSB_CR_BIF_BANK1);
-       PSB_RSGX32(PSB_CR_BIF_BANK1);
-       PSB_WSGX32(PSB_RSGX32(PSB_CR_BIF_CTRL) | _PSB_MMU_ER_MASK,
-                                                       PSB_CR_BIF_CTRL);
-       psb_spank(dev_priv);
-
-       /* mmu_gatt ?? */
-       PSB_WSGX32(pg->gatt_start, PSB_CR_BIF_TWOD_REQ_BASE);
-       return 0;
-out_err:
-       psb_do_takedown(dev);
-       return ret;
-}
-
-static int psb_driver_unload(struct drm_device *dev)
-{
-       struct drm_psb_private *dev_priv = dev->dev_private;
-
-       /* Kill vblank etc here */
-
-       gma_backlight_exit(dev);
-
-       if (drm_psb_no_fb == 0)
-               psb_modeset_cleanup(dev);
-
-       if (dev_priv) {
-               psb_lid_timer_takedown(dev_priv);
-               gma_intel_opregion_exit(dev);
-
-               if (dev_priv->ops->chip_teardown)
-                       dev_priv->ops->chip_teardown(dev);
-               psb_do_takedown(dev);
-
-
-               if (dev_priv->pf_pd) {
-                       psb_mmu_free_pagedir(dev_priv->pf_pd);
-                       dev_priv->pf_pd = NULL;
-               }
-               if (dev_priv->mmu) {
-                       struct psb_gtt *pg = &dev_priv->gtt;
-
-                       down_read(&pg->sem);
-                       psb_mmu_remove_pfn_sequence(
-                               psb_mmu_get_default_pd
-                               (dev_priv->mmu),
-                               pg->mmu_gatt_start,
-                               dev_priv->vram_stolen_size >> PAGE_SHIFT);
-                       up_read(&pg->sem);
-                       psb_mmu_driver_takedown(dev_priv->mmu);
-                       dev_priv->mmu = NULL;
-               }
-               psb_gtt_takedown(dev);
-               if (dev_priv->scratch_page) {
-                       __free_page(dev_priv->scratch_page);
-                       dev_priv->scratch_page = NULL;
-               }
-               if (dev_priv->vdc_reg) {
-                       iounmap(dev_priv->vdc_reg);
-                       dev_priv->vdc_reg = NULL;
-               }
-               if (dev_priv->sgx_reg) {
-                       iounmap(dev_priv->sgx_reg);
-                       dev_priv->sgx_reg = NULL;
-               }
-
-               kfree(dev_priv);
-               dev->dev_private = NULL;
-
-               /*destroy VBT data*/
-               psb_intel_destroy_bios(dev);
-       }
-
-       gma_power_uninit(dev);
-
-       return 0;
-}
-
-
-static int psb_driver_load(struct drm_device *dev, unsigned long chipset)
-{
-       struct drm_psb_private *dev_priv;
-       unsigned long resource_start;
-       struct psb_gtt *pg;
-       unsigned long irqflags;
-       int ret = -ENOMEM;
-       uint32_t tt_pages;
-       struct drm_connector *connector;
-       struct psb_intel_output *psb_intel_output;
-
-       dev_priv = kzalloc(sizeof(*dev_priv), GFP_KERNEL);
-       if (dev_priv == NULL)
-               return -ENOMEM;
-
-       dev_priv->ops = (struct psb_ops *)chipset;
-       dev_priv->dev = dev;
-       dev->dev_private = (void *) dev_priv;
-
-       if (!IS_PSB(dev)) {
-               if (pci_enable_msi(dev->pdev))
-                       dev_warn(dev->dev, "Enabling MSI failed!\n");
-       }
-
-       dev_priv->num_pipe = dev_priv->ops->pipes;
-
-       resource_start = pci_resource_start(dev->pdev, PSB_MMIO_RESOURCE);
-
-       dev_priv->vdc_reg =
-           ioremap(resource_start + PSB_VDC_OFFSET, PSB_VDC_SIZE);
-       if (!dev_priv->vdc_reg)
-               goto out_err;
-
-       dev_priv->sgx_reg = ioremap(resource_start + dev_priv->ops->sgx_offset,
-                                                       PSB_SGX_SIZE);
-       if (!dev_priv->sgx_reg)
-               goto out_err;
-
-       ret = dev_priv->ops->chip_setup(dev);
-       if (ret)
-               goto out_err;
-
-       /* Init OSPM support */
-       gma_power_init(dev);
-
-       ret = -ENOMEM;
-
-       dev_priv->scratch_page = alloc_page(GFP_DMA32 | __GFP_ZERO);
-       if (!dev_priv->scratch_page)
-               goto out_err;
-
-       set_pages_uc(dev_priv->scratch_page, 1);
-
-       ret = psb_gtt_init(dev, 0);
-       if (ret)
-               goto out_err;
-
-       dev_priv->mmu = psb_mmu_driver_init((void *)0,
-                                       drm_psb_trap_pagefaults, 0,
-                                       dev_priv);
-       if (!dev_priv->mmu)
-               goto out_err;
-
-       pg = &dev_priv->gtt;
-
-       tt_pages = (pg->gatt_pages < PSB_TT_PRIV0_PLIMIT) ?
-               (pg->gatt_pages) : PSB_TT_PRIV0_PLIMIT;
-
-
-       dev_priv->pf_pd = psb_mmu_alloc_pd(dev_priv->mmu, 1, 0);
-       if (!dev_priv->pf_pd)
-               goto out_err;
-
-       psb_mmu_set_pd_context(psb_mmu_get_default_pd(dev_priv->mmu), 0);
-       psb_mmu_set_pd_context(dev_priv->pf_pd, 1);
-
-       ret = psb_do_init(dev);
-       if (ret)
-               return ret;
-
-       PSB_WSGX32(0x20000000, PSB_CR_PDS_EXEC_BASE);
-       PSB_WSGX32(0x30000000, PSB_CR_BIF_3D_REQ_BASE);
-
-/*     igd_opregion_init(&dev_priv->opregion_dev); */
-       acpi_video_register();
-       if (dev_priv->lid_state)
-               psb_lid_timer_init(dev_priv);
-
-       ret = drm_vblank_init(dev, dev_priv->num_pipe);
-       if (ret)
-               goto out_err;
-
-       /*
-        * Install interrupt handlers prior to powering off SGX or else we will
-        * crash.
-        */
-       dev_priv->vdc_irq_mask = 0;
-       dev_priv->pipestat[0] = 0;
-       dev_priv->pipestat[1] = 0;
-       dev_priv->pipestat[2] = 0;
-       spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags);
-       PSB_WVDC32(0xFFFFFFFF, PSB_HWSTAM);
-       PSB_WVDC32(0x00000000, PSB_INT_ENABLE_R);
-       PSB_WVDC32(0xFFFFFFFF, PSB_INT_MASK_R);
-       spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags);
-       if (IS_PSB(dev) && drm_core_check_feature(dev, DRIVER_MODESET))
-               drm_irq_install(dev);
-
-       dev->vblank_disable_allowed = 1;
-
-       dev->max_vblank_count = 0xffffff; /* only 24 bits of frame count */
-
-       dev->driver->get_vblank_counter = psb_get_vblank_counter;
-
-#if defined(CONFIG_DRM_PSB_MFLD)
-       /* FIXME: this is not the right place for this stuff ! */
-       mdfld_output_setup(dev);
-#endif
-       if (drm_psb_no_fb == 0) {
-               psb_modeset_init(dev);
-               psb_fbdev_init(dev);
-               drm_kms_helper_poll_init(dev);
-       }
-
-       /* Only add backlight support if we have LVDS output */
-       list_for_each_entry(connector, &dev->mode_config.connector_list,
-                           head) {
-               psb_intel_output = to_psb_intel_output(connector);
-
-               switch (psb_intel_output->type) {
-               case INTEL_OUTPUT_LVDS:
-               case INTEL_OUTPUT_MIPI:
-                       ret = gma_backlight_init(dev);
-                       break;
-               }
-       }
-
-       if (ret)
-               return ret;
-
-       /* Enable runtime pm at last */
-       pm_runtime_set_active(&dev->pdev->dev);
-       return 0;
-out_err:
-       psb_driver_unload(dev);
-       return ret;
-}
-
-int psb_driver_device_is_agp(struct drm_device *dev)
-{
-       return 0;
-}
-
-
-static int psb_sizes_ioctl(struct drm_device *dev, void *data,
-                          struct drm_file *file_priv)
-{
-       struct drm_psb_private *dev_priv = psb_priv(dev);
-       struct drm_psb_sizes_arg *arg = data;
-
-       *arg = dev_priv->sizes;
-       return 0;
-}
-
-static int psb_dc_state_ioctl(struct drm_device *dev, void *data,
-                               struct drm_file *file_priv)
-{
-       uint32_t flags;
-       uint32_t obj_id;
-       struct drm_mode_object *obj;
-       struct drm_connector *connector;
-       struct drm_crtc *crtc;
-       struct drm_psb_dc_state_arg *arg = data;
-
-
-       /* Double check MRST case */
-       if (IS_MRST(dev) || IS_MFLD(dev))
-               return -EOPNOTSUPP;
-
-       flags = arg->flags;
-       obj_id = arg->obj_id;
-
-       if (flags & PSB_DC_CRTC_MASK) {
-               obj = drm_mode_object_find(dev, obj_id,
-                               DRM_MODE_OBJECT_CRTC);
-               if (!obj) {
-                       dev_dbg(dev->dev, "Invalid CRTC object.\n");
-                       return -EINVAL;
-               }
-
-               crtc = obj_to_crtc(obj);
-
-               mutex_lock(&dev->mode_config.mutex);
-               if (drm_helper_crtc_in_use(crtc)) {
-                       if (flags & PSB_DC_CRTC_SAVE)
-                               crtc->funcs->save(crtc);
-                       else
-                               crtc->funcs->restore(crtc);
-               }
-               mutex_unlock(&dev->mode_config.mutex);
-
-               return 0;
-       } else if (flags & PSB_DC_OUTPUT_MASK) {
-               obj = drm_mode_object_find(dev, obj_id,
-                               DRM_MODE_OBJECT_CONNECTOR);
-               if (!obj) {
-                       dev_dbg(dev->dev, "Invalid connector id.\n");
-                       return -EINVAL;
-               }
-
-               connector = obj_to_connector(obj);
-               if (flags & PSB_DC_OUTPUT_SAVE)
-                       connector->funcs->save(connector);
-               else
-                       connector->funcs->restore(connector);
-
-               return 0;
-       }
-       return -EINVAL;
-}
-
-static inline void get_brightness(struct backlight_device *bd)
-{
-#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
-       if (bd) {
-               bd->props.brightness = bd->ops->get_brightness(bd);
-               backlight_update_status(bd);
-       }
-#endif
-}
-
-static int psb_dpst_bl_ioctl(struct drm_device *dev, void *data,
-                      struct drm_file *file_priv)
-{
-       struct drm_psb_private *dev_priv = psb_priv(dev);
-       uint32_t *arg = data;
-
-       dev_priv->blc_adj2 = *arg;
-       get_brightness(dev_priv->backlight_device);
-       return 0;
-}
-
-static int psb_adb_ioctl(struct drm_device *dev, void *data,
-                       struct drm_file *file_priv)
-{
-       struct drm_psb_private *dev_priv = psb_priv(dev);
-       uint32_t *arg = data;
-
-       dev_priv->blc_adj1 = *arg;
-       get_brightness(dev_priv->backlight_device);
-       return 0;
-}
-
-/* return the current mode to the dpst module */
-static int psb_dpst_ioctl(struct drm_device *dev, void *data,
-                         struct drm_file *file_priv)
-{
-       struct drm_psb_private *dev_priv = psb_priv(dev);
-       uint32_t *arg = data;
-       uint32_t x;
-       uint32_t y;
-       uint32_t reg;
-
-       if (!gma_power_begin(dev, 0))
-               return -EIO;
-
-       reg = PSB_RVDC32(PIPEASRC);
-
-       gma_power_end(dev);
-
-       /* horizontal is the left 16 bits */
-       x = reg >> 16;
-       /* vertical is the right 16 bits */
-       y = reg & 0x0000ffff;
-
-       /* the values are the image size minus one */
-       x++;
-       y++;
-
-       *arg = (x << 16) | y;
-
-       return 0;
-}
-static int psb_gamma_ioctl(struct drm_device *dev, void *data,
-                          struct drm_file *file_priv)
-{
-       struct drm_psb_dpst_lut_arg *lut_arg = data;
-       struct drm_mode_object *obj;
-       struct drm_crtc *crtc;
-       struct drm_connector *connector;
-       struct psb_intel_crtc *psb_intel_crtc;
-       int i = 0;
-       int32_t obj_id;
-
-       obj_id = lut_arg->output_id;
-       obj = drm_mode_object_find(dev, obj_id, DRM_MODE_OBJECT_CONNECTOR);
-       if (!obj) {
-               dev_dbg(dev->dev, "Invalid Connector object.\n");
-               return -EINVAL;
-       }
-
-       connector = obj_to_connector(obj);
-       crtc = connector->encoder->crtc;
-       psb_intel_crtc = to_psb_intel_crtc(crtc);
-
-       for (i = 0; i < 256; i++)
-               psb_intel_crtc->lut_adj[i] = lut_arg->lut[i];
-
-       psb_intel_crtc_load_lut(crtc);
-
-       return 0;
-}
-
-static int psb_mode_operation_ioctl(struct drm_device *dev, void *data,
-                               struct drm_file *file_priv)
-{
-       uint32_t obj_id;
-       uint16_t op;
-       struct drm_mode_modeinfo *umode;
-       struct drm_display_mode *mode = NULL;
-       struct drm_psb_mode_operation_arg *arg;
-       struct drm_mode_object *obj;
-       struct drm_connector *connector;
-       struct drm_framebuffer *drm_fb;
-       struct psb_framebuffer *psb_fb;
-       struct drm_connector_helper_funcs *connector_funcs;
-       int ret = 0;
-       int resp = MODE_OK;
-       struct drm_psb_private *dev_priv = psb_priv(dev);
-
-       arg = (struct drm_psb_mode_operation_arg *)data;
-       obj_id = arg->obj_id;
-       op = arg->operation;
-
-       switch (op) {
-       case PSB_MODE_OPERATION_SET_DC_BASE:
-               obj = drm_mode_object_find(dev, obj_id, DRM_MODE_OBJECT_FB);
-               if (!obj) {
-                       dev_dbg(dev->dev, "Invalid FB id %d\n", obj_id);
-                       return -EINVAL;
-               }
-
-               drm_fb = obj_to_fb(obj);
-               psb_fb = to_psb_fb(drm_fb);
-
-               if (gma_power_begin(dev, 0)) {
-                       REG_WRITE(DSPASURF, psb_fb->gtt->offset);
-                       REG_READ(DSPASURF);
-                       gma_power_end(dev);
-               } else {
-                       dev_priv->saveDSPASURF = psb_fb->gtt->offset;
-               }
-
-               return 0;
-       case PSB_MODE_OPERATION_MODE_VALID:
-               umode = &arg->mode;
-
-               mutex_lock(&dev->mode_config.mutex);
-
-               obj = drm_mode_object_find(dev, obj_id,
-                                       DRM_MODE_OBJECT_CONNECTOR);
-               if (!obj) {
-                       ret = -EINVAL;
-                       goto mode_op_out;
-               }
-
-               connector = obj_to_connector(obj);
-
-               mode = drm_mode_create(dev);
-               if (!mode) {
-                       ret = -ENOMEM;
-                       goto mode_op_out;
-               }
-
-               /* drm_crtc_convert_umode(mode, umode); */
-               {
-                       mode->clock = umode->clock;
-                       mode->hdisplay = umode->hdisplay;
-                       mode->hsync_start = umode->hsync_start;
-                       mode->hsync_end = umode->hsync_end;
-                       mode->htotal = umode->htotal;
-                       mode->hskew = umode->hskew;
-                       mode->vdisplay = umode->vdisplay;
-                       mode->vsync_start = umode->vsync_start;
-                       mode->vsync_end = umode->vsync_end;
-                       mode->vtotal = umode->vtotal;
-                       mode->vscan = umode->vscan;
-                       mode->vrefresh = umode->vrefresh;
-                       mode->flags = umode->flags;
-                       mode->type = umode->type;
-                       strncpy(mode->name, umode->name, DRM_DISPLAY_MODE_LEN);
-                       mode->name[DRM_DISPLAY_MODE_LEN-1] = 0;
-               }
-
-               connector_funcs = (struct drm_connector_helper_funcs *)
-                                  connector->helper_private;
-
-               if (connector_funcs->mode_valid) {
-                       resp = connector_funcs->mode_valid(connector, mode);
-                       arg->data = (void *)resp;
-               }
-
-               /*do some clean up work*/
-               if (mode)
-                       drm_mode_destroy(dev, mode);
-mode_op_out:
-               mutex_unlock(&dev->mode_config.mutex);
-               return ret;
-
-       default:
-               dev_dbg(dev->dev, "Unsupported psb mode operation\n");
-               return -EOPNOTSUPP;
-       }
-
-       return 0;
-}
-
-static int psb_stolen_memory_ioctl(struct drm_device *dev, void *data,
-                                  struct drm_file *file_priv)
-{
-       struct drm_psb_private *dev_priv = psb_priv(dev);
-       struct drm_psb_stolen_memory_arg *arg = data;
-
-       arg->base = dev_priv->stolen_base;
-       arg->size = dev_priv->vram_stolen_size;
-
-       return 0;
-}
-
-/* FIXME: needs Medfield changes */
-static int psb_register_rw_ioctl(struct drm_device *dev, void *data,
-                                struct drm_file *file_priv)
-{
-       struct drm_psb_private *dev_priv = psb_priv(dev);
-       struct drm_psb_register_rw_arg *arg = data;
-       bool usage = arg->b_force_hw_on ? true : false;
-
-       if (arg->display_write_mask != 0) {
-               if (gma_power_begin(dev, usage)) {
-                       if (arg->display_write_mask & REGRWBITS_PFIT_CONTROLS)
-                               PSB_WVDC32(arg->display.pfit_controls,
-                                          PFIT_CONTROL);
-                       if (arg->display_write_mask &
-                           REGRWBITS_PFIT_AUTOSCALE_RATIOS)
-                               PSB_WVDC32(arg->display.pfit_autoscale_ratios,
-                                          PFIT_AUTO_RATIOS);
-                       if (arg->display_write_mask &
-                           REGRWBITS_PFIT_PROGRAMMED_SCALE_RATIOS)
-                               PSB_WVDC32(
-                                  arg->display.pfit_programmed_scale_ratios,
-                                  PFIT_PGM_RATIOS);
-                       if (arg->display_write_mask & REGRWBITS_PIPEASRC)
-                               PSB_WVDC32(arg->display.pipeasrc,
-                                          PIPEASRC);
-                       if (arg->display_write_mask & REGRWBITS_PIPEBSRC)
-                               PSB_WVDC32(arg->display.pipebsrc,
-                                          PIPEBSRC);
-                       if (arg->display_write_mask & REGRWBITS_VTOTAL_A)
-                               PSB_WVDC32(arg->display.vtotal_a,
-                                          VTOTAL_A);
-                       if (arg->display_write_mask & REGRWBITS_VTOTAL_B)
-                               PSB_WVDC32(arg->display.vtotal_b,
-                                          VTOTAL_B);
-                       gma_power_end(dev);
-               } else {
-                       if (arg->display_write_mask & REGRWBITS_PFIT_CONTROLS)
-                               dev_priv->savePFIT_CONTROL =
-                                               arg->display.pfit_controls;
-                       if (arg->display_write_mask &
-                           REGRWBITS_PFIT_AUTOSCALE_RATIOS)
-                               dev_priv->savePFIT_AUTO_RATIOS =
-                                       arg->display.pfit_autoscale_ratios;
-                       if (arg->display_write_mask &
-                           REGRWBITS_PFIT_PROGRAMMED_SCALE_RATIOS)
-                               dev_priv->savePFIT_PGM_RATIOS =
-                                  arg->display.pfit_programmed_scale_ratios;
-                       if (arg->display_write_mask & REGRWBITS_PIPEASRC)
-                               dev_priv->savePIPEASRC = arg->display.pipeasrc;
-                       if (arg->display_write_mask & REGRWBITS_PIPEBSRC)
-                               dev_priv->savePIPEBSRC = arg->display.pipebsrc;
-                       if (arg->display_write_mask & REGRWBITS_VTOTAL_A)
-                               dev_priv->saveVTOTAL_A = arg->display.vtotal_a;
-                       if (arg->display_write_mask & REGRWBITS_VTOTAL_B)
-                               dev_priv->saveVTOTAL_B = arg->display.vtotal_b;
-               }
-       }
-
-       if (arg->display_read_mask != 0) {
-               if (gma_power_begin(dev, usage)) {
-                       if (arg->display_read_mask &
-                           REGRWBITS_PFIT_CONTROLS)
-                               arg->display.pfit_controls =
-                                               PSB_RVDC32(PFIT_CONTROL);
-                       if (arg->display_read_mask &
-                           REGRWBITS_PFIT_AUTOSCALE_RATIOS)
-                               arg->display.pfit_autoscale_ratios =
-                                               PSB_RVDC32(PFIT_AUTO_RATIOS);
-                       if (arg->display_read_mask &
-                           REGRWBITS_PFIT_PROGRAMMED_SCALE_RATIOS)
-                               arg->display.pfit_programmed_scale_ratios =
-                                               PSB_RVDC32(PFIT_PGM_RATIOS);
-                       if (arg->display_read_mask & REGRWBITS_PIPEASRC)
-                               arg->display.pipeasrc = PSB_RVDC32(PIPEASRC);
-                       if (arg->display_read_mask & REGRWBITS_PIPEBSRC)
-                               arg->display.pipebsrc = PSB_RVDC32(PIPEBSRC);
-                       if (arg->display_read_mask & REGRWBITS_VTOTAL_A)
-                               arg->display.vtotal_a = PSB_RVDC32(VTOTAL_A);
-                       if (arg->display_read_mask & REGRWBITS_VTOTAL_B)
-                               arg->display.vtotal_b = PSB_RVDC32(VTOTAL_B);
-                       gma_power_end(dev);
-               } else {
-                       if (arg->display_read_mask &
-                           REGRWBITS_PFIT_CONTROLS)
-                               arg->display.pfit_controls =
-                                               dev_priv->savePFIT_CONTROL;
-                       if (arg->display_read_mask &
-                           REGRWBITS_PFIT_AUTOSCALE_RATIOS)
-                               arg->display.pfit_autoscale_ratios =
-                                               dev_priv->savePFIT_AUTO_RATIOS;
-                       if (arg->display_read_mask &
-                           REGRWBITS_PFIT_PROGRAMMED_SCALE_RATIOS)
-                               arg->display.pfit_programmed_scale_ratios =
-                                               dev_priv->savePFIT_PGM_RATIOS;
-                       if (arg->display_read_mask & REGRWBITS_PIPEASRC)
-                               arg->display.pipeasrc = dev_priv->savePIPEASRC;
-                       if (arg->display_read_mask & REGRWBITS_PIPEBSRC)
-                               arg->display.pipebsrc = dev_priv->savePIPEBSRC;
-                       if (arg->display_read_mask & REGRWBITS_VTOTAL_A)
-                               arg->display.vtotal_a = dev_priv->saveVTOTAL_A;
-                       if (arg->display_read_mask & REGRWBITS_VTOTAL_B)
-                               arg->display.vtotal_b = dev_priv->saveVTOTAL_B;
-               }
-       }
-
-       if (arg->overlay_write_mask != 0) {
-               if (gma_power_begin(dev, usage)) {
-                       if (arg->overlay_write_mask & OV_REGRWBITS_OGAM_ALL) {
-                               PSB_WVDC32(arg->overlay.OGAMC5, OV_OGAMC5);
-                               PSB_WVDC32(arg->overlay.OGAMC4, OV_OGAMC4);
-                               PSB_WVDC32(arg->overlay.OGAMC3, OV_OGAMC3);
-                               PSB_WVDC32(arg->overlay.OGAMC2, OV_OGAMC2);
-                               PSB_WVDC32(arg->overlay.OGAMC1, OV_OGAMC1);
-                               PSB_WVDC32(arg->overlay.OGAMC0, OV_OGAMC0);
-                       }
-                       if (arg->overlay_write_mask & OVC_REGRWBITS_OGAM_ALL) {
-                               PSB_WVDC32(arg->overlay.OGAMC5, OVC_OGAMC5);
-                               PSB_WVDC32(arg->overlay.OGAMC4, OVC_OGAMC4);
-                               PSB_WVDC32(arg->overlay.OGAMC3, OVC_OGAMC3);
-                               PSB_WVDC32(arg->overlay.OGAMC2, OVC_OGAMC2);
-                               PSB_WVDC32(arg->overlay.OGAMC1, OVC_OGAMC1);
-                               PSB_WVDC32(arg->overlay.OGAMC0, OVC_OGAMC0);
-                       }
-
-                       if (arg->overlay_write_mask & OV_REGRWBITS_OVADD) {
-                               PSB_WVDC32(arg->overlay.OVADD, OV_OVADD);
-
-                               if (arg->overlay.b_wait_vblank) {
-                                       /* Wait for 20ms.*/
-                                       unsigned long vblank_timeout = jiffies
-                                                               + HZ/50;
-                                       uint32_t temp;
-                                       while (time_before_eq(jiffies,
-                                                       vblank_timeout)) {
-                                               temp = PSB_RVDC32(OV_DOVASTA);
-                                               if ((temp & (0x1 << 31)) != 0)
-                                                       break;
-                                               cpu_relax();
-                                       }
-                               }
-                       }
-                       if (arg->overlay_write_mask & OVC_REGRWBITS_OVADD) {
-                               PSB_WVDC32(arg->overlay.OVADD, OVC_OVADD);
-                               if (arg->overlay.b_wait_vblank) {
-                                       /* Wait for 20ms.*/
-                                       unsigned long vblank_timeout =
-                                                       jiffies + HZ/50;
-                                       uint32_t temp;
-                                       while (time_before_eq(jiffies,
-                                                       vblank_timeout)) {
-                                               temp = PSB_RVDC32(OVC_DOVCSTA);
-                                               if ((temp & (0x1 << 31)) != 0)
-                                                       break;
-                                               cpu_relax();
-                                       }
-                               }
-                       }
-                       gma_power_end(dev);
-               } else {
-                       if (arg->overlay_write_mask & OV_REGRWBITS_OGAM_ALL) {
-                               dev_priv->saveOV_OGAMC5 = arg->overlay.OGAMC5;
-                               dev_priv->saveOV_OGAMC4 = arg->overlay.OGAMC4;
-                               dev_priv->saveOV_OGAMC3 = arg->overlay.OGAMC3;
-                               dev_priv->saveOV_OGAMC2 = arg->overlay.OGAMC2;
-                               dev_priv->saveOV_OGAMC1 = arg->overlay.OGAMC1;
-                               dev_priv->saveOV_OGAMC0 = arg->overlay.OGAMC0;
-                       }
-                       if (arg->overlay_write_mask & OVC_REGRWBITS_OGAM_ALL) {
-                               dev_priv->saveOVC_OGAMC5 = arg->overlay.OGAMC5;
-                               dev_priv->saveOVC_OGAMC4 = arg->overlay.OGAMC4;
-                               dev_priv->saveOVC_OGAMC3 = arg->overlay.OGAMC3;
-                               dev_priv->saveOVC_OGAMC2 = arg->overlay.OGAMC2;
-                               dev_priv->saveOVC_OGAMC1 = arg->overlay.OGAMC1;
-                               dev_priv->saveOVC_OGAMC0 = arg->overlay.OGAMC0;
-                       }
-                       if (arg->overlay_write_mask & OV_REGRWBITS_OVADD)
-                               dev_priv->saveOV_OVADD = arg->overlay.OVADD;
-                       if (arg->overlay_write_mask & OVC_REGRWBITS_OVADD)
-                               dev_priv->saveOVC_OVADD = arg->overlay.OVADD;
-               }
-       }
-
-       if (arg->overlay_read_mask != 0) {
-               if (gma_power_begin(dev, usage)) {
-                       if (arg->overlay_read_mask & OV_REGRWBITS_OGAM_ALL) {
-                               arg->overlay.OGAMC5 = PSB_RVDC32(OV_OGAMC5);
-                               arg->overlay.OGAMC4 = PSB_RVDC32(OV_OGAMC4);
-                               arg->overlay.OGAMC3 = PSB_RVDC32(OV_OGAMC3);
-                               arg->overlay.OGAMC2 = PSB_RVDC32(OV_OGAMC2);
-                               arg->overlay.OGAMC1 = PSB_RVDC32(OV_OGAMC1);
-                               arg->overlay.OGAMC0 = PSB_RVDC32(OV_OGAMC0);
-                       }
-                       if (arg->overlay_read_mask & OVC_REGRWBITS_OGAM_ALL) {
-                               arg->overlay.OGAMC5 = PSB_RVDC32(OVC_OGAMC5);
-                               arg->overlay.OGAMC4 = PSB_RVDC32(OVC_OGAMC4);
-                               arg->overlay.OGAMC3 = PSB_RVDC32(OVC_OGAMC3);
-                               arg->overlay.OGAMC2 = PSB_RVDC32(OVC_OGAMC2);
-                               arg->overlay.OGAMC1 = PSB_RVDC32(OVC_OGAMC1);
-                               arg->overlay.OGAMC0 = PSB_RVDC32(OVC_OGAMC0);
-                       }
-                       if (arg->overlay_read_mask & OV_REGRWBITS_OVADD)
-                               arg->overlay.OVADD = PSB_RVDC32(OV_OVADD);
-                       if (arg->overlay_read_mask & OVC_REGRWBITS_OVADD)
-                               arg->overlay.OVADD = PSB_RVDC32(OVC_OVADD);
-                       gma_power_end(dev);
-               } else {
-                       if (arg->overlay_read_mask & OV_REGRWBITS_OGAM_ALL) {
-                               arg->overlay.OGAMC5 = dev_priv->saveOV_OGAMC5;
-                               arg->overlay.OGAMC4 = dev_priv->saveOV_OGAMC4;
-                               arg->overlay.OGAMC3 = dev_priv->saveOV_OGAMC3;
-                               arg->overlay.OGAMC2 = dev_priv->saveOV_OGAMC2;
-                               arg->overlay.OGAMC1 = dev_priv->saveOV_OGAMC1;
-                               arg->overlay.OGAMC0 = dev_priv->saveOV_OGAMC0;
-                       }
-                       if (arg->overlay_read_mask & OVC_REGRWBITS_OGAM_ALL) {
-                               arg->overlay.OGAMC5 = dev_priv->saveOVC_OGAMC5;
-                               arg->overlay.OGAMC4 = dev_priv->saveOVC_OGAMC4;
-                               arg->overlay.OGAMC3 = dev_priv->saveOVC_OGAMC3;
-                               arg->overlay.OGAMC2 = dev_priv->saveOVC_OGAMC2;
-                               arg->overlay.OGAMC1 = dev_priv->saveOVC_OGAMC1;
-                               arg->overlay.OGAMC0 = dev_priv->saveOVC_OGAMC0;
-                       }
-                       if (arg->overlay_read_mask & OV_REGRWBITS_OVADD)
-                               arg->overlay.OVADD = dev_priv->saveOV_OVADD;
-                       if (arg->overlay_read_mask & OVC_REGRWBITS_OVADD)
-                               arg->overlay.OVADD = dev_priv->saveOVC_OVADD;
-               }
-       }
-
-       if (arg->sprite_enable_mask != 0) {
-               if (gma_power_begin(dev, usage)) {
-                       PSB_WVDC32(0x1F3E, DSPARB);
-                       PSB_WVDC32(arg->sprite.dspa_control
-                                       | PSB_RVDC32(DSPACNTR), DSPACNTR);
-                       PSB_WVDC32(arg->sprite.dspa_key_value, DSPAKEYVAL);
-                       PSB_WVDC32(arg->sprite.dspa_key_mask, DSPAKEYMASK);
-                       PSB_WVDC32(PSB_RVDC32(DSPASURF), DSPASURF);
-                       PSB_RVDC32(DSPASURF);
-                       PSB_WVDC32(arg->sprite.dspc_control, DSPCCNTR);
-                       PSB_WVDC32(arg->sprite.dspc_stride, DSPCSTRIDE);
-                       PSB_WVDC32(arg->sprite.dspc_position, DSPCPOS);
-                       PSB_WVDC32(arg->sprite.dspc_linear_offset, DSPCLINOFF);
-                       PSB_WVDC32(arg->sprite.dspc_size, DSPCSIZE);
-                       PSB_WVDC32(arg->sprite.dspc_surface, DSPCSURF);
-                       PSB_RVDC32(DSPCSURF);
-                       gma_power_end(dev);
-               }
-       }
-
-       if (arg->sprite_disable_mask != 0) {
-               if (gma_power_begin(dev, usage)) {
-                       PSB_WVDC32(0x3F3E, DSPARB);
-                       PSB_WVDC32(0x0, DSPCCNTR);
-                       PSB_WVDC32(arg->sprite.dspc_surface, DSPCSURF);
-                       PSB_RVDC32(DSPCSURF);
-                       gma_power_end(dev);
-               }
-       }
-
-       if (arg->subpicture_enable_mask != 0) {
-               if (gma_power_begin(dev, usage)) {
-                       uint32_t temp;
-                       if (arg->subpicture_enable_mask & REGRWBITS_DSPACNTR) {
-                               temp =  PSB_RVDC32(DSPACNTR);
-                               temp &= ~DISPPLANE_PIXFORMAT_MASK;
-                               temp &= ~DISPPLANE_BOTTOM;
-                               temp |= DISPPLANE_32BPP;
-                               PSB_WVDC32(temp, DSPACNTR);
-
-                               temp =  PSB_RVDC32(DSPABASE);
-                               PSB_WVDC32(temp, DSPABASE);
-                               PSB_RVDC32(DSPABASE);
-                               temp =  PSB_RVDC32(DSPASURF);
-                               PSB_WVDC32(temp, DSPASURF);
-                               PSB_RVDC32(DSPASURF);
-                       }
-                       if (arg->subpicture_enable_mask & REGRWBITS_DSPBCNTR) {
-                               temp =  PSB_RVDC32(DSPBCNTR);
-                               temp &= ~DISPPLANE_PIXFORMAT_MASK;
-                               temp &= ~DISPPLANE_BOTTOM;
-                               temp |= DISPPLANE_32BPP;
-                               PSB_WVDC32(temp, DSPBCNTR);
-
-                               temp =  PSB_RVDC32(DSPBBASE);
-                               PSB_WVDC32(temp, DSPBBASE);
-                               PSB_RVDC32(DSPBBASE);
-                               temp =  PSB_RVDC32(DSPBSURF);
-                               PSB_WVDC32(temp, DSPBSURF);
-                               PSB_RVDC32(DSPBSURF);
-                       }
-                       if (arg->subpicture_enable_mask & REGRWBITS_DSPCCNTR) {
-                               temp =  PSB_RVDC32(DSPCCNTR);
-                               temp &= ~DISPPLANE_PIXFORMAT_MASK;
-                               temp &= ~DISPPLANE_BOTTOM;
-                               temp |= DISPPLANE_32BPP;
-                               PSB_WVDC32(temp, DSPCCNTR);
-
-                               temp =  PSB_RVDC32(DSPCBASE);
-                               PSB_WVDC32(temp, DSPCBASE);
-                               PSB_RVDC32(DSPCBASE);
-                               temp =  PSB_RVDC32(DSPCSURF);
-                               PSB_WVDC32(temp, DSPCSURF);
-                               PSB_RVDC32(DSPCSURF);
-                       }
-                       gma_power_end(dev);
-               }
-       }
-
-       if (arg->subpicture_disable_mask != 0) {
-               if (gma_power_begin(dev, usage)) {
-                       uint32_t temp;
-                       if (arg->subpicture_disable_mask & REGRWBITS_DSPACNTR) {
-                               temp =  PSB_RVDC32(DSPACNTR);
-                               temp &= ~DISPPLANE_PIXFORMAT_MASK;
-                               temp |= DISPPLANE_32BPP_NO_ALPHA;
-                               PSB_WVDC32(temp, DSPACNTR);
-
-                               temp =  PSB_RVDC32(DSPABASE);
-                               PSB_WVDC32(temp, DSPABASE);
-                               PSB_RVDC32(DSPABASE);
-                               temp =  PSB_RVDC32(DSPASURF);
-                               PSB_WVDC32(temp, DSPASURF);
-                               PSB_RVDC32(DSPASURF);
-                       }
-                       if (arg->subpicture_disable_mask & REGRWBITS_DSPBCNTR) {
-                               temp =  PSB_RVDC32(DSPBCNTR);
-                               temp &= ~DISPPLANE_PIXFORMAT_MASK;
-                               temp |= DISPPLANE_32BPP_NO_ALPHA;
-                               PSB_WVDC32(temp, DSPBCNTR);
-
-                               temp =  PSB_RVDC32(DSPBBASE);
-                               PSB_WVDC32(temp, DSPBBASE);
-                               PSB_RVDC32(DSPBBASE);
-                               temp =  PSB_RVDC32(DSPBSURF);
-                               PSB_WVDC32(temp, DSPBSURF);
-                               PSB_RVDC32(DSPBSURF);
-                       }
-                       if (arg->subpicture_disable_mask & REGRWBITS_DSPCCNTR) {
-                               temp =  PSB_RVDC32(DSPCCNTR);
-                               temp &= ~DISPPLANE_PIXFORMAT_MASK;
-                               temp |= DISPPLANE_32BPP_NO_ALPHA;
-                               PSB_WVDC32(temp, DSPCCNTR);
-
-                               temp =  PSB_RVDC32(DSPCBASE);
-                               PSB_WVDC32(temp, DSPCBASE);
-                               PSB_RVDC32(DSPCBASE);
-                               temp =  PSB_RVDC32(DSPCSURF);
-                               PSB_WVDC32(temp, DSPCSURF);
-                               PSB_RVDC32(DSPCSURF);
-                       }
-                       gma_power_end(dev);
-               }
-       }
-
-       return 0;
-}
-
-static int psb_driver_open(struct drm_device *dev, struct drm_file *priv)
-{
-       return 0;
-}
-
-static void psb_driver_close(struct drm_device *dev, struct drm_file *priv)
-{
-}
-
-static long psb_unlocked_ioctl(struct file *filp, unsigned int cmd,
-                              unsigned long arg)
-{
-       struct drm_file *file_priv = filp->private_data;
-       struct drm_device *dev = file_priv->minor->dev;
-       int ret;
-       
-       pm_runtime_forbid(dev->dev);
-       ret = drm_ioctl(filp, cmd, arg);
-       pm_runtime_allow(dev->dev);
-       return ret;
-       /* FIXME: do we need to wrap the other side of this */
-}
-
-
-/* When a client dies:
- *    - Check for and clean up flipped page state
- */
-void psb_driver_preclose(struct drm_device *dev, struct drm_file *priv)
-{
-}
-
-static void psb_remove(struct pci_dev *pdev)
-{
-       struct drm_device *dev = pci_get_drvdata(pdev);
-       drm_put_dev(dev);
-}
-
-static const struct dev_pm_ops psb_pm_ops = {
-       .suspend = gma_power_suspend,
-       .resume = gma_power_resume,
-       .freeze = gma_power_suspend,
-       .thaw = gma_power_resume,
-       .poweroff = gma_power_suspend,
-       .restore = gma_power_resume,
-       .runtime_suspend = psb_runtime_suspend,
-       .runtime_resume = psb_runtime_resume,
-       .runtime_idle = psb_runtime_idle,
-};
-
-static struct vm_operations_struct psb_gem_vm_ops = {
-       .fault = psb_gem_fault,
-       .open = drm_gem_vm_open,
-       .close = drm_gem_vm_close,
-};
-
-static const struct file_operations gma500_driver_fops = {
-       .owner = THIS_MODULE,
-       .open = drm_open,
-       .release = drm_release,
-       .unlocked_ioctl = psb_unlocked_ioctl,
-       .mmap = drm_gem_mmap,
-       .poll = drm_poll,
-       .fasync = drm_fasync,
-       .read = drm_read,
-};
-
-static struct drm_driver driver = {
-       .driver_features = DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | \
-                          DRIVER_IRQ_VBL | DRIVER_MODESET | DRIVER_GEM ,
-       .load = psb_driver_load,
-       .unload = psb_driver_unload,
-
-       .ioctls = psb_ioctls,
-       .num_ioctls = DRM_ARRAY_SIZE(psb_ioctls),
-       .device_is_agp = psb_driver_device_is_agp,
-       .irq_preinstall = psb_irq_preinstall,
-       .irq_postinstall = psb_irq_postinstall,
-       .irq_uninstall = psb_irq_uninstall,
-       .irq_handler = psb_irq_handler,
-       .enable_vblank = psb_enable_vblank,
-       .disable_vblank = psb_disable_vblank,
-       .get_vblank_counter = psb_get_vblank_counter,
-       .lastclose = psb_lastclose,
-       .open = psb_driver_open,
-       .preclose = psb_driver_preclose,
-       .postclose = psb_driver_close,
-       .reclaim_buffers = drm_core_reclaim_buffers,
-
-       .gem_init_object = psb_gem_init_object,
-       .gem_free_object = psb_gem_free_object,
-       .gem_vm_ops = &psb_gem_vm_ops,
-       .dumb_create = psb_gem_dumb_create,
-       .dumb_map_offset = psb_gem_dumb_map_gtt,
-       .dumb_destroy = psb_gem_dumb_destroy,
-       .fops = &gma500_driver_fops,
-       .name = DRIVER_NAME,
-       .desc = DRIVER_DESC,
-       .date = PSB_DRM_DRIVER_DATE,
-       .major = PSB_DRM_DRIVER_MAJOR,
-       .minor = PSB_DRM_DRIVER_MINOR,
-       .patchlevel = PSB_DRM_DRIVER_PATCHLEVEL
-};
-
-static struct pci_driver psb_pci_driver = {
-       .name = DRIVER_NAME,
-       .id_table = pciidlist,
-       .probe = psb_probe,
-       .remove = psb_remove,
-       .driver.pm = &psb_pm_ops,
-};
-
-static int psb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
-{
-       return drm_get_pci_dev(pdev, ent, &driver);
-}
-
-static int __init psb_init(void)
-{
-       return drm_pci_init(&driver, &psb_pci_driver);
-}
-
-static void __exit psb_exit(void)
-{
-       drm_pci_exit(&driver, &psb_pci_driver);
-}
-
-late_initcall(psb_init);
-module_exit(psb_exit);
-
-MODULE_AUTHOR("Alan Cox <alan@linux.intel.com> and others");
-MODULE_DESCRIPTION(DRIVER_DESC);
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/gma500/psb_drv.h b/drivers/staging/gma500/psb_drv.h
deleted file mode 100644 (file)
index 11d963a..0000000
+++ /dev/null
@@ -1,952 +0,0 @@
-/**************************************************************************
- * Copyright (c) 2007-2011, Intel Corporation.
- * All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- **************************************************************************/
-
-#ifndef _PSB_DRV_H_
-#define _PSB_DRV_H_
-
-#include <linux/kref.h>
-
-#include <drm/drmP.h>
-#include "drm_global.h"
-#include "gem_glue.h"
-#include "psb_drm.h"
-#include "psb_reg.h"
-#include "psb_intel_drv.h"
-#include "gtt.h"
-#include "power.h"
-#include "mrst.h"
-#include "medfield.h"
-
-/* Append new drm mode definition here, align with libdrm definition */
-#define DRM_MODE_SCALE_NO_SCALE        2
-
-enum {
-       CHIP_PSB_8108 = 0,              /* Poulsbo */
-       CHIP_PSB_8109 = 1,              /* Poulsbo */
-       CHIP_MRST_4100 = 2,             /* Moorestown/Oaktrail */
-       CHIP_MFLD_0130 = 3,             /* Medfield */
-};
-
-#define IS_PSB(dev) (((dev)->pci_device & 0xfffe) == 0x8108)
-#define IS_MRST(dev) (((dev)->pci_device & 0xfffc) == 0x4100)
-#define IS_MFLD(dev) (((dev)->pci_device & 0xfff8) == 0x0130)
-
-/*
- * Driver definitions
- */
-
-#define DRIVER_NAME "gma500"
-#define DRIVER_DESC "DRM driver for the Intel GMA500"
-
-#define PSB_DRM_DRIVER_DATE "2011-06-06"
-#define PSB_DRM_DRIVER_MAJOR 1
-#define PSB_DRM_DRIVER_MINOR 0
-#define PSB_DRM_DRIVER_PATCHLEVEL 0
-
-/*
- *     Hardware offsets
- */
-#define PSB_VDC_OFFSET          0x00000000
-#define PSB_VDC_SIZE            0x000080000
-#define MRST_MMIO_SIZE          0x0000C0000
-#define MDFLD_MMIO_SIZE          0x000100000
-#define PSB_SGX_SIZE            0x8000
-#define PSB_SGX_OFFSET          0x00040000
-#define MRST_SGX_OFFSET                 0x00080000
-/*
- *     PCI resource identifiers
- */
-#define PSB_MMIO_RESOURCE       0
-#define PSB_GATT_RESOURCE       2
-#define PSB_GTT_RESOURCE        3
-/*
- *     PCI configuration
- */
-#define PSB_GMCH_CTRL           0x52
-#define PSB_BSM                         0x5C
-#define _PSB_GMCH_ENABLED       0x4
-#define PSB_PGETBL_CTL          0x2020
-#define _PSB_PGETBL_ENABLED     0x00000001
-#define PSB_SGX_2D_SLAVE_PORT   0x4000
-
-/* To get rid of */
-#define PSB_TT_PRIV0_LIMIT      (256*1024*1024)
-#define PSB_TT_PRIV0_PLIMIT     (PSB_TT_PRIV0_LIMIT >> PAGE_SHIFT)
-
-/*
- *     SGX side MMU definitions (these can probably go)
- */
-
-/*
- *     Flags for external memory type field.
- */
-#define PSB_MMU_CACHED_MEMORY    0x0001        /* Bind to MMU only */
-#define PSB_MMU_RO_MEMORY        0x0002        /* MMU RO memory */
-#define PSB_MMU_WO_MEMORY        0x0004        /* MMU WO memory */
-/*
- *     PTE's and PDE's
- */
-#define PSB_PDE_MASK             0x003FFFFF
-#define PSB_PDE_SHIFT            22
-#define PSB_PTE_SHIFT            12
-/*
- *     Cache control
- */
-#define PSB_PTE_VALID            0x0001        /* PTE / PDE valid */
-#define PSB_PTE_WO               0x0002        /* Write only */
-#define PSB_PTE_RO               0x0004        /* Read only */
-#define PSB_PTE_CACHED           0x0008        /* CPU cache coherent */
-
-/*
- *     VDC registers and bits
- */
-#define PSB_MSVDX_CLOCKGATING    0x2064
-#define PSB_TOPAZ_CLOCKGATING    0x2068
-#define PSB_HWSTAM               0x2098
-#define PSB_INSTPM               0x20C0
-#define PSB_INT_IDENTITY_R        0x20A4
-#define _MDFLD_PIPEC_EVENT_FLAG   (1<<2)
-#define _MDFLD_PIPEC_VBLANK_FLAG  (1<<3)
-#define _PSB_DPST_PIPEB_FLAG      (1<<4)
-#define _MDFLD_PIPEB_EVENT_FLAG   (1<<4)
-#define _PSB_VSYNC_PIPEB_FLAG    (1<<5)
-#define _PSB_DPST_PIPEA_FLAG      (1<<6)
-#define _PSB_PIPEA_EVENT_FLAG     (1<<6)
-#define _PSB_VSYNC_PIPEA_FLAG    (1<<7)
-#define _MDFLD_MIPIA_FLAG        (1<<16)
-#define _MDFLD_MIPIC_FLAG        (1<<17)
-#define _PSB_IRQ_SGX_FLAG        (1<<18)
-#define _PSB_IRQ_MSVDX_FLAG      (1<<19)
-#define _LNC_IRQ_TOPAZ_FLAG      (1<<20)
-
-#define _PSB_PIPE_EVENT_FLAG   (_PSB_VSYNC_PIPEA_FLAG | \
-                                _PSB_VSYNC_PIPEB_FLAG)
-
-/* This flag includes all the display IRQ bits excepts the vblank irqs. */
-#define _MDFLD_DISP_ALL_IRQ_FLAG (_MDFLD_PIPEC_EVENT_FLAG | \
-                                 _MDFLD_PIPEB_EVENT_FLAG | \
-                                 _PSB_PIPEA_EVENT_FLAG | \
-                                 _PSB_VSYNC_PIPEA_FLAG | \
-                                 _MDFLD_MIPIA_FLAG | \
-                                 _MDFLD_MIPIC_FLAG)
-#define PSB_INT_IDENTITY_R       0x20A4
-#define PSB_INT_MASK_R           0x20A8
-#define PSB_INT_ENABLE_R         0x20A0
-
-#define _PSB_MMU_ER_MASK      0x0001FF00
-#define _PSB_MMU_ER_HOST      (1 << 16)
-#define GPIOA                  0x5010
-#define GPIOB                  0x5014
-#define GPIOC                  0x5018
-#define GPIOD                  0x501c
-#define GPIOE                  0x5020
-#define GPIOF                  0x5024
-#define GPIOG                  0x5028
-#define GPIOH                  0x502c
-#define GPIO_CLOCK_DIR_MASK            (1 << 0)
-#define GPIO_CLOCK_DIR_IN              (0 << 1)
-#define GPIO_CLOCK_DIR_OUT             (1 << 1)
-#define GPIO_CLOCK_VAL_MASK            (1 << 2)
-#define GPIO_CLOCK_VAL_OUT             (1 << 3)
-#define GPIO_CLOCK_VAL_IN              (1 << 4)
-#define GPIO_CLOCK_PULLUP_DISABLE      (1 << 5)
-#define GPIO_DATA_DIR_MASK             (1 << 8)
-#define GPIO_DATA_DIR_IN               (0 << 9)
-#define GPIO_DATA_DIR_OUT              (1 << 9)
-#define GPIO_DATA_VAL_MASK             (1 << 10)
-#define GPIO_DATA_VAL_OUT              (1 << 11)
-#define GPIO_DATA_VAL_IN               (1 << 12)
-#define GPIO_DATA_PULLUP_DISABLE       (1 << 13)
-
-#define VCLK_DIVISOR_VGA0   0x6000
-#define VCLK_DIVISOR_VGA1   0x6004
-#define VCLK_POST_DIV      0x6010
-
-#define PSB_COMM_2D (PSB_ENGINE_2D << 4)
-#define PSB_COMM_3D (PSB_ENGINE_3D << 4)
-#define PSB_COMM_TA (PSB_ENGINE_TA << 4)
-#define PSB_COMM_HP (PSB_ENGINE_HP << 4)
-#define PSB_COMM_USER_IRQ (1024 >> 2)
-#define PSB_COMM_USER_IRQ_LOST (PSB_COMM_USER_IRQ + 1)
-#define PSB_COMM_FW (2048 >> 2)
-
-#define PSB_UIRQ_VISTEST              1
-#define PSB_UIRQ_OOM_REPLY            2
-#define PSB_UIRQ_FIRE_TA_REPLY        3
-#define PSB_UIRQ_FIRE_RASTER_REPLY     4
-
-#define PSB_2D_SIZE (256*1024*1024)
-#define PSB_MAX_RELOC_PAGES 1024
-
-#define PSB_LOW_REG_OFFS 0x0204
-#define PSB_HIGH_REG_OFFS 0x0600
-
-#define PSB_NUM_VBLANKS 2
-
-
-#define PSB_2D_SIZE (256*1024*1024)
-#define PSB_MAX_RELOC_PAGES 1024
-
-#define PSB_LOW_REG_OFFS 0x0204
-#define PSB_HIGH_REG_OFFS 0x0600
-
-#define PSB_NUM_VBLANKS 2
-#define PSB_WATCHDOG_DELAY (DRM_HZ * 2)
-#define PSB_LID_DELAY (DRM_HZ / 10)
-
-#define MDFLD_PNW_B0 0x04
-#define MDFLD_PNW_C0 0x08
-
-#define MDFLD_DSR_2D_3D_0      (1 << 0)
-#define MDFLD_DSR_2D_3D_2      (1 << 1)
-#define MDFLD_DSR_CURSOR_0     (1 << 2)
-#define MDFLD_DSR_CURSOR_2     (1 << 3)
-#define MDFLD_DSR_OVERLAY_0    (1 << 4)
-#define MDFLD_DSR_OVERLAY_2    (1 << 5)
-#define MDFLD_DSR_MIPI_CONTROL (1 << 6)
-#define MDFLD_DSR_DAMAGE_MASK_0        ((1 << 0) | (1 << 2) | (1 << 4))
-#define MDFLD_DSR_DAMAGE_MASK_2        ((1 << 1) | (1 << 3) | (1 << 5))
-#define MDFLD_DSR_2D_3D        (MDFLD_DSR_2D_3D_0 | MDFLD_DSR_2D_3D_2)
-
-#define MDFLD_DSR_RR           45
-#define MDFLD_DPU_ENABLE       (1 << 31)
-#define MDFLD_DSR_FULLSCREEN   (1 << 30)
-#define MDFLD_DSR_DELAY                (DRM_HZ / MDFLD_DSR_RR)
-
-#define PSB_PWR_STATE_ON               1
-#define PSB_PWR_STATE_OFF              2
-
-#define PSB_PMPOLICY_NOPM              0
-#define PSB_PMPOLICY_CLOCKGATING       1
-#define PSB_PMPOLICY_POWERDOWN         2
-
-#define PSB_PMSTATE_POWERUP            0
-#define PSB_PMSTATE_CLOCKGATED         1
-#define PSB_PMSTATE_POWERDOWN          2
-#define PSB_PCIx_MSI_ADDR_LOC          0x94
-#define PSB_PCIx_MSI_DATA_LOC          0x98
-
-/* Medfield crystal settings */
-#define KSEL_CRYSTAL_19 1
-#define KSEL_BYPASS_19 5
-#define KSEL_BYPASS_25 6
-#define KSEL_BYPASS_83_100 7
-
-struct opregion_header;
-struct opregion_acpi;
-struct opregion_swsci;
-struct opregion_asle;
-
-struct psb_intel_opregion {
-       struct opregion_header *header;
-       struct opregion_acpi *acpi;
-       struct opregion_swsci *swsci;
-       struct opregion_asle *asle;
-       int enabled;
-};
-
-struct psb_ops;
-
-struct drm_psb_private {
-       struct drm_device *dev;
-       const struct psb_ops *ops;
-
-       struct psb_gtt gtt;
-
-       /* GTT Memory manager */
-       struct psb_gtt_mm *gtt_mm;
-       struct page *scratch_page;
-       u32 *gtt_map;
-       uint32_t stolen_base;
-       void *vram_addr;
-       unsigned long vram_stolen_size;
-       int gtt_initialized;
-       u16 gmch_ctrl;          /* Saved GTT setup */
-       u32 pge_ctl;
-
-       struct mutex gtt_mutex;
-       struct resource *gtt_mem;       /* Our PCI resource */
-
-       struct psb_mmu_driver *mmu;
-       struct psb_mmu_pd *pf_pd;
-
-       /*
-        * Register base
-        */
-
-       uint8_t *sgx_reg;
-       uint8_t *vdc_reg;
-       uint32_t gatt_free_offset;
-
-       /*
-        * Fencing / irq.
-        */
-
-       uint32_t vdc_irq_mask;
-       uint32_t pipestat[PSB_NUM_PIPE];
-
-       spinlock_t irqmask_lock;
-
-       /*
-        * Power
-        */
-
-       bool suspended;
-       bool display_power;
-       int display_count;
-
-       /*
-        * Modesetting
-        */
-       struct psb_intel_mode_device mode_dev;
-
-       struct drm_crtc *plane_to_crtc_mapping[PSB_NUM_PIPE];
-       struct drm_crtc *pipe_to_crtc_mapping[PSB_NUM_PIPE];
-       uint32_t num_pipe;
-
-       /*
-        * OSPM info (Power management base) (can go ?)
-        */
-       uint32_t ospm_base;
-
-       /*
-        * Sizes info
-        */
-
-       struct drm_psb_sizes_arg sizes;
-
-       u32 fuse_reg_value;
-       u32 video_device_fuse;
-
-       /* PCI revision ID for B0:D2:F0 */
-       uint8_t platform_rev_id;
-
-       /*
-        * LVDS info
-        */
-       int backlight_duty_cycle;       /* restore backlight to this value */
-       bool panel_wants_dither;
-       struct drm_display_mode *panel_fixed_mode;
-       struct drm_display_mode *lfp_lvds_vbt_mode;
-       struct drm_display_mode *sdvo_lvds_vbt_mode;
-
-       struct bdb_lvds_backlight *lvds_bl; /* LVDS backlight info from VBT */
-       struct psb_intel_i2c_chan *lvds_i2c_bus;
-
-       /* Feature bits from the VBIOS */
-       unsigned int int_tv_support:1;
-       unsigned int lvds_dither:1;
-       unsigned int lvds_vbt:1;
-       unsigned int int_crt_support:1;
-       unsigned int lvds_use_ssc:1;
-       int lvds_ssc_freq;
-       bool is_lvds_on;
-       bool is_mipi_on;
-       u32 mipi_ctrl_display;
-
-       unsigned int core_freq;
-       uint32_t iLVDS_enable;
-
-       /* Runtime PM state */
-       int rpm_enabled;
-
-       /* MID specific */
-       struct mrst_vbt vbt_data;
-       struct mrst_gct_data gct_data;
-
-       /* MIPI Panel type etc */
-       int panel_id;
-       bool dual_mipi;         /* dual display - DPI & DBI */
-       bool dpi_panel_on;      /* The DPI panel power is on */
-       bool dpi_panel_on2;     /* The DPI panel power is on */
-       bool dbi_panel_on;      /* The DBI panel power is on */
-       bool dbi_panel_on2;     /* The DBI panel power is on */
-       u32 dsr_fb_update;      /* DSR FB update counter */
-
-       /* Moorestown HDMI state */
-       struct mrst_hdmi_dev *hdmi_priv;
-
-       /* Moorestown pipe config register value cache */
-       uint32_t pipeconf;
-       uint32_t pipeconf1;
-       uint32_t pipeconf2;
-
-       /* Moorestown plane control register value cache */
-       uint32_t dspcntr;
-       uint32_t dspcntr1;
-       uint32_t dspcntr2;
-
-       /* Moorestown MM backlight cache */
-       uint8_t saveBKLTCNT;
-       uint8_t saveBKLTREQ;
-       uint8_t saveBKLTBRTL;
-
-       /*
-        * Register state
-        */
-       uint32_t saveDSPACNTR;
-       uint32_t saveDSPBCNTR;
-       uint32_t savePIPEACONF;
-       uint32_t savePIPEBCONF;
-       uint32_t savePIPEASRC;
-       uint32_t savePIPEBSRC;
-       uint32_t saveFPA0;
-       uint32_t saveFPA1;
-       uint32_t saveDPLL_A;
-       uint32_t saveDPLL_A_MD;
-       uint32_t saveHTOTAL_A;
-       uint32_t saveHBLANK_A;
-       uint32_t saveHSYNC_A;
-       uint32_t saveVTOTAL_A;
-       uint32_t saveVBLANK_A;
-       uint32_t saveVSYNC_A;
-       uint32_t saveDSPASTRIDE;
-       uint32_t saveDSPASIZE;
-       uint32_t saveDSPAPOS;
-       uint32_t saveDSPABASE;
-       uint32_t saveDSPASURF;
-       uint32_t saveDSPASTATUS;
-       uint32_t saveFPB0;
-       uint32_t saveFPB1;
-       uint32_t saveDPLL_B;
-       uint32_t saveDPLL_B_MD;
-       uint32_t saveHTOTAL_B;
-       uint32_t saveHBLANK_B;
-       uint32_t saveHSYNC_B;
-       uint32_t saveVTOTAL_B;
-       uint32_t saveVBLANK_B;
-       uint32_t saveVSYNC_B;
-       uint32_t saveDSPBSTRIDE;
-       uint32_t saveDSPBSIZE;
-       uint32_t saveDSPBPOS;
-       uint32_t saveDSPBBASE;
-       uint32_t saveDSPBSURF;
-       uint32_t saveDSPBSTATUS;
-       uint32_t saveVCLK_DIVISOR_VGA0;
-       uint32_t saveVCLK_DIVISOR_VGA1;
-       uint32_t saveVCLK_POST_DIV;
-       uint32_t saveVGACNTRL;
-       uint32_t saveADPA;
-       uint32_t saveLVDS;
-       uint32_t saveDVOA;
-       uint32_t saveDVOB;
-       uint32_t saveDVOC;
-       uint32_t savePP_ON;
-       uint32_t savePP_OFF;
-       uint32_t savePP_CONTROL;
-       uint32_t savePP_CYCLE;
-       uint32_t savePFIT_CONTROL;
-       uint32_t savePaletteA[256];
-       uint32_t savePaletteB[256];
-       uint32_t saveBLC_PWM_CTL2;
-       uint32_t saveBLC_PWM_CTL;
-       uint32_t saveCLOCKGATING;
-       uint32_t saveDSPARB;
-       uint32_t saveDSPATILEOFF;
-       uint32_t saveDSPBTILEOFF;
-       uint32_t saveDSPAADDR;
-       uint32_t saveDSPBADDR;
-       uint32_t savePFIT_AUTO_RATIOS;
-       uint32_t savePFIT_PGM_RATIOS;
-       uint32_t savePP_ON_DELAYS;
-       uint32_t savePP_OFF_DELAYS;
-       uint32_t savePP_DIVISOR;
-       uint32_t saveBSM;
-       uint32_t saveVBT;
-       uint32_t saveBCLRPAT_A;
-       uint32_t saveBCLRPAT_B;
-       uint32_t saveDSPALINOFF;
-       uint32_t saveDSPBLINOFF;
-       uint32_t savePERF_MODE;
-       uint32_t saveDSPFW1;
-       uint32_t saveDSPFW2;
-       uint32_t saveDSPFW3;
-       uint32_t saveDSPFW4;
-       uint32_t saveDSPFW5;
-       uint32_t saveDSPFW6;
-       uint32_t saveCHICKENBIT;
-       uint32_t saveDSPACURSOR_CTRL;
-       uint32_t saveDSPBCURSOR_CTRL;
-       uint32_t saveDSPACURSOR_BASE;
-       uint32_t saveDSPBCURSOR_BASE;
-       uint32_t saveDSPACURSOR_POS;
-       uint32_t saveDSPBCURSOR_POS;
-       uint32_t save_palette_a[256];
-       uint32_t save_palette_b[256];
-       uint32_t saveOV_OVADD;
-       uint32_t saveOV_OGAMC0;
-       uint32_t saveOV_OGAMC1;
-       uint32_t saveOV_OGAMC2;
-       uint32_t saveOV_OGAMC3;
-       uint32_t saveOV_OGAMC4;
-       uint32_t saveOV_OGAMC5;
-       uint32_t saveOVC_OVADD;
-       uint32_t saveOVC_OGAMC0;
-       uint32_t saveOVC_OGAMC1;
-       uint32_t saveOVC_OGAMC2;
-       uint32_t saveOVC_OGAMC3;
-       uint32_t saveOVC_OGAMC4;
-       uint32_t saveOVC_OGAMC5;
-
-       /* MSI reg save */
-       uint32_t msi_addr;
-       uint32_t msi_data;
-
-       /* Medfield specific register save state */
-       uint32_t saveHDMIPHYMISCCTL;
-       uint32_t saveHDMIB_CONTROL;
-       uint32_t saveDSPCCNTR;
-       uint32_t savePIPECCONF;
-       uint32_t savePIPECSRC;
-       uint32_t saveHTOTAL_C;
-       uint32_t saveHBLANK_C;
-       uint32_t saveHSYNC_C;
-       uint32_t saveVTOTAL_C;
-       uint32_t saveVBLANK_C;
-       uint32_t saveVSYNC_C;
-       uint32_t saveDSPCSTRIDE;
-       uint32_t saveDSPCSIZE;
-       uint32_t saveDSPCPOS;
-       uint32_t saveDSPCSURF;
-       uint32_t saveDSPCSTATUS;
-       uint32_t saveDSPCLINOFF;
-       uint32_t saveDSPCTILEOFF;
-       uint32_t saveDSPCCURSOR_CTRL;
-       uint32_t saveDSPCCURSOR_BASE;
-       uint32_t saveDSPCCURSOR_POS;
-       uint32_t save_palette_c[256];
-       uint32_t saveOV_OVADD_C;
-       uint32_t saveOV_OGAMC0_C;
-       uint32_t saveOV_OGAMC1_C;
-       uint32_t saveOV_OGAMC2_C;
-       uint32_t saveOV_OGAMC3_C;
-       uint32_t saveOV_OGAMC4_C;
-       uint32_t saveOV_OGAMC5_C;
-
-       /* DSI register save */
-       uint32_t saveDEVICE_READY_REG;
-       uint32_t saveINTR_EN_REG;
-       uint32_t saveDSI_FUNC_PRG_REG;
-       uint32_t saveHS_TX_TIMEOUT_REG;
-       uint32_t saveLP_RX_TIMEOUT_REG;
-       uint32_t saveTURN_AROUND_TIMEOUT_REG;
-       uint32_t saveDEVICE_RESET_REG;
-       uint32_t saveDPI_RESOLUTION_REG;
-       uint32_t saveHORIZ_SYNC_PAD_COUNT_REG;
-       uint32_t saveHORIZ_BACK_PORCH_COUNT_REG;
-       uint32_t saveHORIZ_FRONT_PORCH_COUNT_REG;
-       uint32_t saveHORIZ_ACTIVE_AREA_COUNT_REG;
-       uint32_t saveVERT_SYNC_PAD_COUNT_REG;
-       uint32_t saveVERT_BACK_PORCH_COUNT_REG;
-       uint32_t saveVERT_FRONT_PORCH_COUNT_REG;
-       uint32_t saveHIGH_LOW_SWITCH_COUNT_REG;
-       uint32_t saveINIT_COUNT_REG;
-       uint32_t saveMAX_RET_PAK_REG;
-       uint32_t saveVIDEO_FMT_REG;
-       uint32_t saveEOT_DISABLE_REG;
-       uint32_t saveLP_BYTECLK_REG;
-       uint32_t saveHS_LS_DBI_ENABLE_REG;
-       uint32_t saveTXCLKESC_REG;
-       uint32_t saveDPHY_PARAM_REG;
-       uint32_t saveMIPI_CONTROL_REG;
-       uint32_t saveMIPI;
-       uint32_t saveMIPI_C;
-
-       /* DPST register save */
-       uint32_t saveHISTOGRAM_INT_CONTROL_REG;
-       uint32_t saveHISTOGRAM_LOGIC_CONTROL_REG;
-       uint32_t savePWM_CONTROL_LOGIC;
-
-       /*
-        * DSI info. 
-        */
-       void * dbi_dsr_info;    
-       void * dbi_dpu_info;
-       void * dsi_configs[2];
-       /*
-        * LID-Switch
-        */
-       spinlock_t lid_lock;
-       struct timer_list lid_timer;
-       struct psb_intel_opregion opregion;
-       u32 *lid_state;
-       u32 lid_last_state;
-
-       /*
-        * Watchdog
-        */
-
-       uint32_t apm_reg;
-       uint16_t apm_base;
-
-       /*
-        * Used for modifying backlight from
-        * xrandr -- consider removing and using HAL instead
-        */
-       struct backlight_device *backlight_device;
-       struct drm_property *backlight_property;
-       uint32_t blc_adj1;
-       uint32_t blc_adj2;
-
-       void *fbdev;
-       /* DPST state */
-       uint32_t dsr_idle_count;
-       bool is_in_idle;
-       bool dsr_enable;
-       void (*exit_idle)(struct drm_device *dev, u32 update_src);
-
-       /* 2D acceleration */
-       spinlock_t lock_2d;
-
-       /* FIXME: Arrays anyone ? */
-       struct mdfld_dsi_encoder *encoder0;     
-       struct mdfld_dsi_encoder *encoder2;     
-       struct mdfld_dsi_dbi_output * dbi_output;
-       struct mdfld_dsi_dbi_output * dbi_output2;
-       u32 bpp;
-       u32 bpp2;
-       
-       bool dispstatus;
-};
-
-
-/*
- *     Operations for each board type
- */
-struct psb_ops {
-       const char *name;
-       unsigned int accel_2d:1;
-       int pipes;              /* Number of output pipes */
-       int crtcs;              /* Number of CRTCs */
-       int sgx_offset;         /* Base offset of SGX device */
-
-       /* Sub functions */
-       struct drm_crtc_helper_funcs const *crtc_helper;
-       struct drm_crtc_funcs const *crtc_funcs;
-
-       /* Setup hooks */
-       int (*chip_setup)(struct drm_device *dev);
-       void (*chip_teardown)(struct drm_device *dev);
-
-       /* Display management hooks */
-       int (*output_init)(struct drm_device *dev);
-       /* Power management hooks */
-       void (*init_pm)(struct drm_device *dev);
-       int (*save_regs)(struct drm_device *dev);
-       int (*restore_regs)(struct drm_device *dev);
-       int (*power_up)(struct drm_device *dev);
-       int (*power_down)(struct drm_device *dev);
-
-       void (*lvds_bl_power)(struct drm_device *dev, bool on);
-#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
-       /* Backlight */
-       int (*backlight_init)(struct drm_device *dev);
-#endif
-       int i2c_bus;            /* I2C bus identifier for Moorestown */
-};
-
-
-
-struct psb_mmu_driver;
-
-extern int drm_crtc_probe_output_modes(struct drm_device *dev, int, int);
-extern int drm_pick_crtcs(struct drm_device *dev);
-
-static inline struct drm_psb_private *psb_priv(struct drm_device *dev)
-{
-       return (struct drm_psb_private *) dev->dev_private;
-}
-
-/*
- * MMU stuff.
- */
-
-extern struct psb_mmu_driver *psb_mmu_driver_init(uint8_t __iomem * registers,
-                                       int trap_pagefaults,
-                                       int invalid_type,
-                                       struct drm_psb_private *dev_priv);
-extern void psb_mmu_driver_takedown(struct psb_mmu_driver *driver);
-extern struct psb_mmu_pd *psb_mmu_get_default_pd(struct psb_mmu_driver
-                                                *driver);
-extern void psb_mmu_mirror_gtt(struct psb_mmu_pd *pd, uint32_t mmu_offset,
-                              uint32_t gtt_start, uint32_t gtt_pages);
-extern struct psb_mmu_pd *psb_mmu_alloc_pd(struct psb_mmu_driver *driver,
-                                          int trap_pagefaults,
-                                          int invalid_type);
-extern void psb_mmu_free_pagedir(struct psb_mmu_pd *pd);
-extern void psb_mmu_flush(struct psb_mmu_driver *driver, int rc_prot);
-extern void psb_mmu_remove_pfn_sequence(struct psb_mmu_pd *pd,
-                                       unsigned long address,
-                                       uint32_t num_pages);
-extern int psb_mmu_insert_pfn_sequence(struct psb_mmu_pd *pd,
-                                      uint32_t start_pfn,
-                                      unsigned long address,
-                                      uint32_t num_pages, int type);
-extern int psb_mmu_virtual_to_pfn(struct psb_mmu_pd *pd, uint32_t virtual,
-                                 unsigned long *pfn);
-
-/*
- * Enable / disable MMU for different requestors.
- */
-
-
-extern void psb_mmu_set_pd_context(struct psb_mmu_pd *pd, int hw_context);
-extern int psb_mmu_insert_pages(struct psb_mmu_pd *pd, struct page **pages,
-                               unsigned long address, uint32_t num_pages,
-                               uint32_t desired_tile_stride,
-                               uint32_t hw_tile_stride, int type);
-extern void psb_mmu_remove_pages(struct psb_mmu_pd *pd,
-                                unsigned long address, uint32_t num_pages,
-                                uint32_t desired_tile_stride,
-                                uint32_t hw_tile_stride);
-/*
- *psb_irq.c
- */
-
-extern irqreturn_t psb_irq_handler(DRM_IRQ_ARGS);
-extern int psb_irq_enable_dpst(struct drm_device *dev);
-extern int psb_irq_disable_dpst(struct drm_device *dev);
-extern void psb_irq_preinstall(struct drm_device *dev);
-extern int psb_irq_postinstall(struct drm_device *dev);
-extern void psb_irq_uninstall(struct drm_device *dev);
-extern void psb_irq_turn_on_dpst(struct drm_device *dev);
-extern void psb_irq_turn_off_dpst(struct drm_device *dev);
-
-extern void psb_irq_uninstall_islands(struct drm_device *dev, int hw_islands);
-extern int psb_vblank_wait2(struct drm_device *dev, unsigned int *sequence);
-extern int psb_vblank_wait(struct drm_device *dev, unsigned int *sequence);
-extern int psb_enable_vblank(struct drm_device *dev, int crtc);
-extern void psb_disable_vblank(struct drm_device *dev, int crtc);
-void
-psb_enable_pipestat(struct drm_psb_private *dev_priv, int pipe, u32 mask);
-
-void
-psb_disable_pipestat(struct drm_psb_private *dev_priv, int pipe, u32 mask);
-
-extern u32 psb_get_vblank_counter(struct drm_device *dev, int crtc);
-
-extern int mdfld_enable_te(struct drm_device *dev, int pipe);
-extern void mdfld_disable_te(struct drm_device *dev, int pipe);
-
-/*
- * intel_opregion.c
- */
-extern int gma_intel_opregion_init(struct drm_device *dev);
-extern int gma_intel_opregion_exit(struct drm_device *dev);
-
-/*
- * framebuffer.c
- */
-extern int psbfb_probed(struct drm_device *dev);
-extern int psbfb_remove(struct drm_device *dev,
-                       struct drm_framebuffer *fb);
-/*
- * accel_2d.c
- */
-extern void psbfb_copyarea(struct fb_info *info,
-                                       const struct fb_copyarea *region);
-extern int psbfb_sync(struct fb_info *info);
-extern void psb_spank(struct drm_psb_private *dev_priv);
-extern int psb_accel_ioctl(struct drm_device *dev, void *data,
-                                                       struct drm_file *file);
-
-/*
- * psb_reset.c
- */
-
-extern void psb_lid_timer_init(struct drm_psb_private *dev_priv);
-extern void psb_lid_timer_takedown(struct drm_psb_private *dev_priv);
-extern void psb_print_pagefault(struct drm_psb_private *dev_priv);
-
-/* modesetting */
-extern void psb_modeset_init(struct drm_device *dev);
-extern void psb_modeset_cleanup(struct drm_device *dev);
-extern int psb_fbdev_init(struct drm_device *dev);
-
-/* backlight.c */
-int gma_backlight_init(struct drm_device *dev);
-void gma_backlight_exit(struct drm_device *dev);
-
-/* mrst_crtc.c */
-extern const struct drm_crtc_helper_funcs mrst_helper_funcs;
-
-/* mrst_lvds.c */
-extern void mrst_lvds_init(struct drm_device *dev,
-                   struct psb_intel_mode_device *mode_dev);
-
-/* psb_intel_display.c */
-extern const struct drm_crtc_helper_funcs psb_intel_helper_funcs;
-extern const struct drm_crtc_funcs psb_intel_crtc_funcs;
-
-/* psb_intel_lvds.c */
-extern const struct drm_connector_helper_funcs
-                                       psb_intel_lvds_connector_helper_funcs;
-extern const struct drm_connector_funcs psb_intel_lvds_connector_funcs;
-
-/* gem.c */
-extern int psb_gem_init_object(struct drm_gem_object *obj);
-extern void psb_gem_free_object(struct drm_gem_object *obj);
-extern int psb_gem_get_aperture(struct drm_device *dev, void *data,
-                       struct drm_file *file);
-extern int psb_gem_dumb_create(struct drm_file *file, struct drm_device *dev,
-                       struct drm_mode_create_dumb *args);
-extern int psb_gem_dumb_destroy(struct drm_file *file, struct drm_device *dev,
-                       uint32_t handle);
-extern int psb_gem_dumb_map_gtt(struct drm_file *file, struct drm_device *dev,
-                       uint32_t handle, uint64_t *offset);
-extern int psb_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf);
-extern int psb_gem_create_ioctl(struct drm_device *dev, void *data,
-                       struct drm_file *file);
-extern int psb_gem_mmap_ioctl(struct drm_device *dev, void *data,
-                                       struct drm_file *file);
-
-/* psb_device.c */
-extern const struct psb_ops psb_chip_ops;
-
-/* mrst_device.c */
-extern const struct psb_ops mrst_chip_ops;
-
-/* mdfld_device.c */
-extern const struct psb_ops mdfld_chip_ops;
-
-/* cdv_device.c */
-extern const struct psb_ops cdv_chip_ops;
-
-/*
- * Debug print bits setting
- */
-#define PSB_D_GENERAL (1 << 0)
-#define PSB_D_INIT    (1 << 1)
-#define PSB_D_IRQ     (1 << 2)
-#define PSB_D_ENTRY   (1 << 3)
-/* debug the get H/V BP/FP count */
-#define PSB_D_HV      (1 << 4)
-#define PSB_D_DBI_BF  (1 << 5)
-#define PSB_D_PM      (1 << 6)
-#define PSB_D_RENDER  (1 << 7)
-#define PSB_D_REG     (1 << 8)
-#define PSB_D_MSVDX   (1 << 9)
-#define PSB_D_TOPAZ   (1 << 10)
-
-extern int drm_psb_no_fb;
-extern int drm_idle_check_interval;
-
-/*
- *     Utilities
- */
-
-static inline u32 MRST_MSG_READ32(uint port, uint offset)
-{
-       int mcr = (0xD0<<24) | (port << 16) | (offset << 8);
-       uint32_t ret_val = 0;
-       struct pci_dev *pci_root = pci_get_bus_and_slot(0, 0);
-       pci_write_config_dword(pci_root, 0xD0, mcr);
-       pci_read_config_dword(pci_root, 0xD4, &ret_val);
-       pci_dev_put(pci_root);
-       return ret_val;
-}
-static inline void MRST_MSG_WRITE32(uint port, uint offset, u32 value)
-{
-       int mcr = (0xE0<<24) | (port << 16) | (offset << 8) | 0xF0;
-       struct pci_dev *pci_root = pci_get_bus_and_slot(0, 0);
-       pci_write_config_dword(pci_root, 0xD4, value);
-       pci_write_config_dword(pci_root, 0xD0, mcr);
-       pci_dev_put(pci_root);
-}
-static inline u32 MDFLD_MSG_READ32(uint port, uint offset)
-{
-       int mcr = (0x10<<24) | (port << 16) | (offset << 8);
-       uint32_t ret_val = 0;
-       struct pci_dev *pci_root = pci_get_bus_and_slot(0, 0);
-       pci_write_config_dword(pci_root, 0xD0, mcr);
-       pci_read_config_dword(pci_root, 0xD4, &ret_val);
-       pci_dev_put(pci_root);
-       return ret_val;
-}
-static inline void MDFLD_MSG_WRITE32(uint port, uint offset, u32 value)
-{
-       int mcr = (0x11<<24) | (port << 16) | (offset << 8) | 0xF0;
-       struct pci_dev *pci_root = pci_get_bus_and_slot(0, 0);
-       pci_write_config_dword(pci_root, 0xD4, value);
-       pci_write_config_dword(pci_root, 0xD0, mcr);
-       pci_dev_put(pci_root);
-}
-
-static inline uint32_t REGISTER_READ(struct drm_device *dev, uint32_t reg)
-{
-       struct drm_psb_private *dev_priv = dev->dev_private;
-       return ioread32(dev_priv->vdc_reg + reg);
-}
-
-#define REG_READ(reg)         REGISTER_READ(dev, (reg))
-
-static inline void REGISTER_WRITE(struct drm_device *dev, uint32_t reg,
-                                     uint32_t val)
-{
-       struct drm_psb_private *dev_priv = dev->dev_private;
-       iowrite32((val), dev_priv->vdc_reg + (reg));
-}
-
-#define REG_WRITE(reg, val)    REGISTER_WRITE(dev, (reg), (val))
-
-static inline void REGISTER_WRITE16(struct drm_device *dev,
-                                       uint32_t reg, uint32_t val)
-{
-       struct drm_psb_private *dev_priv = dev->dev_private;
-       iowrite16((val), dev_priv->vdc_reg + (reg));
-}
-
-#define REG_WRITE16(reg, val)    REGISTER_WRITE16(dev, (reg), (val))
-
-static inline void REGISTER_WRITE8(struct drm_device *dev,
-                                      uint32_t reg, uint32_t val)
-{
-       struct drm_psb_private *dev_priv = dev->dev_private;
-       iowrite8((val), dev_priv->vdc_reg + (reg));
-}
-
-#define REG_WRITE8(reg, val)           REGISTER_WRITE8(dev, (reg), (val))
-
-#define PSB_WVDC32(_val, _offs)                iowrite32(_val, dev_priv->vdc_reg + (_offs))
-#define PSB_RVDC32(_offs)              ioread32(dev_priv->vdc_reg + (_offs))
-
-/* #define TRAP_SGX_PM_FAULT 1 */
-#ifdef TRAP_SGX_PM_FAULT
-#define PSB_RSGX32(_offs)                                              \
-({                                                                     \
-       if (inl(dev_priv->apm_base + PSB_APM_STS) & 0x3) {              \
-               printk(KERN_ERR                                         \
-                       "access sgx when it's off!! (READ) %s, %d\n",   \
-              __FILE__, __LINE__);                                     \
-               melay(1000);                                            \
-       }                                                               \
-       ioread32(dev_priv->sgx_reg + (_offs));                          \
-})
-#else
-#define PSB_RSGX32(_offs)              ioread32(dev_priv->sgx_reg + (_offs))
-#endif
-#define PSB_WSGX32(_val, _offs)                iowrite32(_val, dev_priv->sgx_reg + (_offs))
-
-#define MSVDX_REG_DUMP 0
-
-#define PSB_WMSVDX32(_val, _offs)      iowrite32(_val, dev_priv->msvdx_reg + (_offs))
-#define PSB_RMSVDX32(_offs)            ioread32(dev_priv->msvdx_reg + (_offs))
-
-#endif
diff --git a/drivers/staging/gma500/psb_intel_display.c b/drivers/staging/gma500/psb_intel_display.c
deleted file mode 100644 (file)
index 8565961..0000000
+++ /dev/null
@@ -1,1429 +0,0 @@
-/*
- * Copyright Ã‚© 2006-2011 Intel Corporation
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Authors:
- *     Eric Anholt <eric@anholt.net>
- */
-
-#include <linux/i2c.h>
-#include <linux/pm_runtime.h>
-
-#include <drm/drmP.h>
-#include "framebuffer.h"
-#include "psb_drv.h"
-#include "psb_intel_drv.h"
-#include "psb_intel_reg.h"
-#include "psb_intel_display.h"
-#include "power.h"
-
-#include "mdfld_output.h"
-
-struct psb_intel_clock_t {
-       /* given values */
-       int n;
-       int m1, m2;
-       int p1, p2;
-       /* derived values */
-       int dot;
-       int vco;
-       int m;
-       int p;
-};
-
-struct psb_intel_range_t {
-       int min, max;
-};
-
-struct psb_intel_p2_t {
-       int dot_limit;
-       int p2_slow, p2_fast;
-};
-
-#define INTEL_P2_NUM                 2
-
-struct psb_intel_limit_t {
-       struct psb_intel_range_t dot, vco, n, m, m1, m2, p, p1;
-       struct psb_intel_p2_t p2;
-};
-
-#define I8XX_DOT_MIN             25000
-#define I8XX_DOT_MAX            350000
-#define I8XX_VCO_MIN            930000
-#define I8XX_VCO_MAX           1400000
-#define I8XX_N_MIN                   3
-#define I8XX_N_MAX                  16
-#define I8XX_M_MIN                  96
-#define I8XX_M_MAX                 140
-#define I8XX_M1_MIN                 18
-#define I8XX_M1_MAX                 26
-#define I8XX_M2_MIN                  6
-#define I8XX_M2_MAX                 16
-#define I8XX_P_MIN                   4
-#define I8XX_P_MAX                 128
-#define I8XX_P1_MIN                  2
-#define I8XX_P1_MAX                 33
-#define I8XX_P1_LVDS_MIN             1
-#define I8XX_P1_LVDS_MAX             6
-#define I8XX_P2_SLOW                 4
-#define I8XX_P2_FAST                 2
-#define I8XX_P2_LVDS_SLOW            14
-#define I8XX_P2_LVDS_FAST            14        /* No fast option */
-#define I8XX_P2_SLOW_LIMIT      165000
-
-#define I9XX_DOT_MIN             20000
-#define I9XX_DOT_MAX            400000
-#define I9XX_VCO_MIN           1400000
-#define I9XX_VCO_MAX           2800000
-#define I9XX_N_MIN                   3
-#define I9XX_N_MAX                   8
-#define I9XX_M_MIN                  70
-#define I9XX_M_MAX                 120
-#define I9XX_M1_MIN                 10
-#define I9XX_M1_MAX                 20
-#define I9XX_M2_MIN                  5
-#define I9XX_M2_MAX                  9
-#define I9XX_P_SDVO_DAC_MIN          5
-#define I9XX_P_SDVO_DAC_MAX         80
-#define I9XX_P_LVDS_MIN                      7
-#define I9XX_P_LVDS_MAX                     98
-#define I9XX_P1_MIN                  1
-#define I9XX_P1_MAX                  8
-#define I9XX_P2_SDVO_DAC_SLOW               10
-#define I9XX_P2_SDVO_DAC_FAST                5
-#define I9XX_P2_SDVO_DAC_SLOW_LIMIT     200000
-#define I9XX_P2_LVDS_SLOW                   14
-#define I9XX_P2_LVDS_FAST                    7
-#define I9XX_P2_LVDS_SLOW_LIMIT                 112000
-
-#define INTEL_LIMIT_I8XX_DVO_DAC    0
-#define INTEL_LIMIT_I8XX_LVDS      1
-#define INTEL_LIMIT_I9XX_SDVO_DAC   2
-#define INTEL_LIMIT_I9XX_LVDS      3
-
-static const struct psb_intel_limit_t psb_intel_limits[] = {
-       {                       /* INTEL_LIMIT_I8XX_DVO_DAC */
-        .dot = {.min = I8XX_DOT_MIN, .max = I8XX_DOT_MAX},
-        .vco = {.min = I8XX_VCO_MIN, .max = I8XX_VCO_MAX},
-        .n = {.min = I8XX_N_MIN, .max = I8XX_N_MAX},
-        .m = {.min = I8XX_M_MIN, .max = I8XX_M_MAX},
-        .m1 = {.min = I8XX_M1_MIN, .max = I8XX_M1_MAX},
-        .m2 = {.min = I8XX_M2_MIN, .max = I8XX_M2_MAX},
-        .p = {.min = I8XX_P_MIN, .max = I8XX_P_MAX},
-        .p1 = {.min = I8XX_P1_MIN, .max = I8XX_P1_MAX},
-        .p2 = {.dot_limit = I8XX_P2_SLOW_LIMIT,
-               .p2_slow = I8XX_P2_SLOW, .p2_fast = I8XX_P2_FAST},
-        },
-       {                       /* INTEL_LIMIT_I8XX_LVDS */
-        .dot = {.min = I8XX_DOT_MIN, .max = I8XX_DOT_MAX},
-        .vco = {.min = I8XX_VCO_MIN, .max = I8XX_VCO_MAX},
-        .n = {.min = I8XX_N_MIN, .max = I8XX_N_MAX},
-        .m = {.min = I8XX_M_MIN, .max = I8XX_M_MAX},
-        .m1 = {.min = I8XX_M1_MIN, .max = I8XX_M1_MAX},
-        .m2 = {.min = I8XX_M2_MIN, .max = I8XX_M2_MAX},
-        .p = {.min = I8XX_P_MIN, .max = I8XX_P_MAX},
-        .p1 = {.min = I8XX_P1_LVDS_MIN, .max = I8XX_P1_LVDS_MAX},
-        .p2 = {.dot_limit = I8XX_P2_SLOW_LIMIT,
-               .p2_slow = I8XX_P2_LVDS_SLOW, .p2_fast = I8XX_P2_LVDS_FAST},
-        },
-       {                       /* INTEL_LIMIT_I9XX_SDVO_DAC */
-        .dot = {.min = I9XX_DOT_MIN, .max = I9XX_DOT_MAX},
-        .vco = {.min = I9XX_VCO_MIN, .max = I9XX_VCO_MAX},
-        .n = {.min = I9XX_N_MIN, .max = I9XX_N_MAX},
-        .m = {.min = I9XX_M_MIN, .max = I9XX_M_MAX},
-        .m1 = {.min = I9XX_M1_MIN, .max = I9XX_M1_MAX},
-        .m2 = {.min = I9XX_M2_MIN, .max = I9XX_M2_MAX},
-        .p = {.min = I9XX_P_SDVO_DAC_MIN, .max = I9XX_P_SDVO_DAC_MAX},
-        .p1 = {.min = I9XX_P1_MIN, .max = I9XX_P1_MAX},
-        .p2 = {.dot_limit = I9XX_P2_SDVO_DAC_SLOW_LIMIT,
-               .p2_slow = I9XX_P2_SDVO_DAC_SLOW, .p2_fast =
-               I9XX_P2_SDVO_DAC_FAST},
-        },
-       {                       /* INTEL_LIMIT_I9XX_LVDS */
-        .dot = {.min = I9XX_DOT_MIN, .max = I9XX_DOT_MAX},
-        .vco = {.min = I9XX_VCO_MIN, .max = I9XX_VCO_MAX},
-        .n = {.min = I9XX_N_MIN, .max = I9XX_N_MAX},
-        .m = {.min = I9XX_M_MIN, .max = I9XX_M_MAX},
-        .m1 = {.min = I9XX_M1_MIN, .max = I9XX_M1_MAX},
-        .m2 = {.min = I9XX_M2_MIN, .max = I9XX_M2_MAX},
-        .p = {.min = I9XX_P_LVDS_MIN, .max = I9XX_P_LVDS_MAX},
-        .p1 = {.min = I9XX_P1_MIN, .max = I9XX_P1_MAX},
-        /* The single-channel range is 25-112Mhz, and dual-channel
-         * is 80-224Mhz.  Prefer single channel as much as possible.
-         */
-        .p2 = {.dot_limit = I9XX_P2_LVDS_SLOW_LIMIT,
-               .p2_slow = I9XX_P2_LVDS_SLOW, .p2_fast = I9XX_P2_LVDS_FAST},
-        },
-};
-
-static const struct psb_intel_limit_t *psb_intel_limit(struct drm_crtc *crtc)
-{
-       const struct psb_intel_limit_t *limit;
-
-       if (psb_intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS))
-               limit = &psb_intel_limits[INTEL_LIMIT_I9XX_LVDS];
-       else
-               limit = &psb_intel_limits[INTEL_LIMIT_I9XX_SDVO_DAC];
-       return limit;
-}
-
-/** Derive the pixel clock for the given refclk and divisors for 8xx chips. */
-
-static void i8xx_clock(int refclk, struct psb_intel_clock_t *clock)
-{
-       clock->m = 5 * (clock->m1 + 2) + (clock->m2 + 2);
-       clock->p = clock->p1 * clock->p2;
-       clock->vco = refclk * clock->m / (clock->n + 2);
-       clock->dot = clock->vco / clock->p;
-}
-
-/** Derive the pixel clock for the given refclk and divisors for 9xx chips. */
-
-static void i9xx_clock(int refclk, struct psb_intel_clock_t *clock)
-{
-       clock->m = 5 * (clock->m1 + 2) + (clock->m2 + 2);
-       clock->p = clock->p1 * clock->p2;
-       clock->vco = refclk * clock->m / (clock->n + 2);
-       clock->dot = clock->vco / clock->p;
-}
-
-static void psb_intel_clock(struct drm_device *dev, int refclk,
-                       struct psb_intel_clock_t *clock)
-{
-       return i9xx_clock(refclk, clock);
-}
-
-/**
- * Returns whether any output on the specified pipe is of the specified type
- */
-bool psb_intel_pipe_has_type(struct drm_crtc *crtc, int type)
-{
-       struct drm_device *dev = crtc->dev;
-       struct drm_mode_config *mode_config = &dev->mode_config;
-       struct drm_connector *l_entry;
-
-       list_for_each_entry(l_entry, &mode_config->connector_list, head) {
-               if (l_entry->encoder && l_entry->encoder->crtc == crtc) {
-                       struct psb_intel_output *psb_intel_output =
-                           to_psb_intel_output(l_entry);
-                       if (psb_intel_output->type == type)
-                               return true;
-               }
-       }
-       return false;
-}
-
-#define INTELPllInvalid(s)   { /* ErrorF (s) */; return false; }
-/**
- * Returns whether the given set of divisors are valid for a given refclk with
- * the given connectors.
- */
-
-static bool psb_intel_PLL_is_valid(struct drm_crtc *crtc,
-                              struct psb_intel_clock_t *clock)
-{
-       const struct psb_intel_limit_t *limit = psb_intel_limit(crtc);
-
-       if (clock->p1 < limit->p1.min || limit->p1.max < clock->p1)
-               INTELPllInvalid("p1 out of range\n");
-       if (clock->p < limit->p.min || limit->p.max < clock->p)
-               INTELPllInvalid("p out of range\n");
-       if (clock->m2 < limit->m2.min || limit->m2.max < clock->m2)
-               INTELPllInvalid("m2 out of range\n");
-       if (clock->m1 < limit->m1.min || limit->m1.max < clock->m1)
-               INTELPllInvalid("m1 out of range\n");
-       if (clock->m1 <= clock->m2)
-               INTELPllInvalid("m1 <= m2\n");
-       if (clock->m < limit->m.min || limit->m.max < clock->m)
-               INTELPllInvalid("m out of range\n");
-       if (clock->n < limit->n.min || limit->n.max < clock->n)
-               INTELPllInvalid("n out of range\n");
-       if (clock->vco < limit->vco.min || limit->vco.max < clock->vco)
-               INTELPllInvalid("vco out of range\n");
-       /* XXX: We may need to be checking "Dot clock"
-        * depending on the multiplier, connector, etc.,
-        * rather than just a single range.
-        */
-       if (clock->dot < limit->dot.min || limit->dot.max < clock->dot)
-               INTELPllInvalid("dot out of range\n");
-
-       return true;
-}
-
-/**
- * Returns a set of divisors for the desired target clock with the given
- * refclk, or FALSE.  The returned values represent the clock equation:
- * reflck * (5 * (m1 + 2) + (m2 + 2)) / (n + 2) / p1 / p2.
- */
-static bool psb_intel_find_best_PLL(struct drm_crtc *crtc, int target,
-                               int refclk,
-                               struct psb_intel_clock_t *best_clock)
-{
-       struct drm_device *dev = crtc->dev;
-       struct psb_intel_clock_t clock;
-       const struct psb_intel_limit_t *limit = psb_intel_limit(crtc);
-       int err = target;
-
-       if (psb_intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) &&
-           (REG_READ(LVDS) & LVDS_PORT_EN) != 0) {
-               /*
-                * For LVDS, if the panel is on, just rely on its current
-                * settings for dual-channel.  We haven't figured out how to
-                * reliably set up different single/dual channel state, if we
-                * even can.
-                */
-               if ((REG_READ(LVDS) & LVDS_CLKB_POWER_MASK) ==
-                   LVDS_CLKB_POWER_UP)
-                       clock.p2 = limit->p2.p2_fast;
-               else
-                       clock.p2 = limit->p2.p2_slow;
-       } else {
-               if (target < limit->p2.dot_limit)
-                       clock.p2 = limit->p2.p2_slow;
-               else
-                       clock.p2 = limit->p2.p2_fast;
-       }
-
-       memset(best_clock, 0, sizeof(*best_clock));
-
-       for (clock.m1 = limit->m1.min; clock.m1 <= limit->m1.max;
-            clock.m1++) {
-               for (clock.m2 = limit->m2.min;
-                    clock.m2 < clock.m1 && clock.m2 <= limit->m2.max;
-                    clock.m2++) {
-                       for (clock.n = limit->n.min;
-                            clock.n <= limit->n.max; clock.n++) {
-                               for (clock.p1 = limit->p1.min;
-                                    clock.p1 <= limit->p1.max;
-                                    clock.p1++) {
-                                       int this_err;
-
-                                       psb_intel_clock(dev, refclk, &clock);
-
-                                       if (!psb_intel_PLL_is_valid
-                                           (crtc, &clock))
-                                               continue;
-
-                                       this_err = abs(clock.dot - target);
-                                       if (this_err < err) {
-                                               *best_clock = clock;
-                                               err = this_err;
-                                       }
-                               }
-                       }
-               }
-       }
-
-       return err != target;
-}
-
-void psb_intel_wait_for_vblank(struct drm_device *dev)
-{
-       /* Wait for 20ms, i.e. one cycle at 50hz. */
-       mdelay(20);
-}
-
-int psb_intel_pipe_set_base(struct drm_crtc *crtc,
-                           int x, int y, struct drm_framebuffer *old_fb)
-{
-       struct drm_device *dev = crtc->dev;
-       /* struct drm_i915_master_private *master_priv; */
-       struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
-       struct psb_framebuffer *psbfb = to_psb_fb(crtc->fb);
-       int pipe = psb_intel_crtc->pipe;
-       unsigned long start, offset;
-       int dspbase = (pipe == 0 ? DSPABASE : DSPBBASE);
-       int dspsurf = (pipe == 0 ? DSPASURF : DSPBSURF);
-       int dspstride = (pipe == 0) ? DSPASTRIDE : DSPBSTRIDE;
-       int dspcntr_reg = (pipe == 0) ? DSPACNTR : DSPBCNTR;
-       u32 dspcntr;
-       int ret = 0;
-
-       if (!gma_power_begin(dev, true))
-               return 0;
-
-       /* no fb bound */
-       if (!crtc->fb) {
-               dev_dbg(dev->dev, "No FB bound\n");
-               goto psb_intel_pipe_cleaner;
-       }
-
-       /* We are displaying this buffer, make sure it is actually loaded
-          into the GTT */
-       ret = psb_gtt_pin(psbfb->gtt);
-       if (ret < 0)
-               goto psb_intel_pipe_set_base_exit;
-       start = psbfb->gtt->offset;
-
-       offset = y * crtc->fb->pitches[0] + x * (crtc->fb->bits_per_pixel / 8);
-
-       REG_WRITE(dspstride, crtc->fb->pitches[0]);
-
-       dspcntr = REG_READ(dspcntr_reg);
-       dspcntr &= ~DISPPLANE_PIXFORMAT_MASK;
-
-       switch (crtc->fb->bits_per_pixel) {
-       case 8:
-               dspcntr |= DISPPLANE_8BPP;
-               break;
-       case 16:
-               if (crtc->fb->depth == 15)
-                       dspcntr |= DISPPLANE_15_16BPP;
-               else
-                       dspcntr |= DISPPLANE_16BPP;
-               break;
-       case 24:
-       case 32:
-               dspcntr |= DISPPLANE_32BPP_NO_ALPHA;
-               break;
-       default:
-               dev_err(dev->dev, "Unknown color depth\n");
-               ret = -EINVAL;
-               psb_gtt_unpin(psbfb->gtt);
-               goto psb_intel_pipe_set_base_exit;
-       }
-       REG_WRITE(dspcntr_reg, dspcntr);
-
-
-       if (0 /* FIXMEAC - check what PSB needs */) {
-               REG_WRITE(dspbase, offset);
-               REG_READ(dspbase);
-               REG_WRITE(dspsurf, start);
-               REG_READ(dspsurf);
-       } else {
-               REG_WRITE(dspbase, start + offset);
-               REG_READ(dspbase);
-       }
-
-psb_intel_pipe_cleaner:
-       /* If there was a previous display we can now unpin it */
-       if (old_fb)
-               psb_gtt_unpin(to_psb_fb(old_fb)->gtt);
-
-psb_intel_pipe_set_base_exit:
-       gma_power_end(dev);
-       return ret;
-}
-
-/**
- * Sets the power management mode of the pipe and plane.
- *
- * This code should probably grow support for turning the cursor off and back
- * on appropriately at the same time as we're turning the pipe off/on.
- */
-static void psb_intel_crtc_dpms(struct drm_crtc *crtc, int mode)
-{
-       struct drm_device *dev = crtc->dev;
-       /* struct drm_i915_master_private *master_priv; */
-       /* struct drm_i915_private *dev_priv = dev->dev_private; */
-       struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
-       int pipe = psb_intel_crtc->pipe;
-       int dpll_reg = (pipe == 0) ? DPLL_A : DPLL_B;
-       int dspcntr_reg = (pipe == 0) ? DSPACNTR : DSPBCNTR;
-       int dspbase_reg = (pipe == 0) ? DSPABASE : DSPBBASE;
-       int pipeconf_reg = (pipe == 0) ? PIPEACONF : PIPEBCONF;
-       u32 temp;
-       bool enabled;
-
-       /* XXX: When our outputs are all unaware of DPMS modes other than off
-        * and on, we should map those modes to DRM_MODE_DPMS_OFF in the CRTC.
-        */
-       switch (mode) {
-       case DRM_MODE_DPMS_ON:
-       case DRM_MODE_DPMS_STANDBY:
-       case DRM_MODE_DPMS_SUSPEND:
-               /* Enable the DPLL */
-               temp = REG_READ(dpll_reg);
-               if ((temp & DPLL_VCO_ENABLE) == 0) {
-                       REG_WRITE(dpll_reg, temp);
-                       REG_READ(dpll_reg);
-                       /* Wait for the clocks to stabilize. */
-                       udelay(150);
-                       REG_WRITE(dpll_reg, temp | DPLL_VCO_ENABLE);
-                       REG_READ(dpll_reg);
-                       /* Wait for the clocks to stabilize. */
-                       udelay(150);
-                       REG_WRITE(dpll_reg, temp | DPLL_VCO_ENABLE);
-                       REG_READ(dpll_reg);
-                       /* Wait for the clocks to stabilize. */
-                       udelay(150);
-               }
-
-               /* Enable the pipe */
-               temp = REG_READ(pipeconf_reg);
-               if ((temp & PIPEACONF_ENABLE) == 0)
-                       REG_WRITE(pipeconf_reg, temp | PIPEACONF_ENABLE);
-
-               /* Enable the plane */
-               temp = REG_READ(dspcntr_reg);
-               if ((temp & DISPLAY_PLANE_ENABLE) == 0) {
-                       REG_WRITE(dspcntr_reg,
-                                 temp | DISPLAY_PLANE_ENABLE);
-                       /* Flush the plane changes */
-                       REG_WRITE(dspbase_reg, REG_READ(dspbase_reg));
-               }
-
-               psb_intel_crtc_load_lut(crtc);
-
-               /* Give the overlay scaler a chance to enable
-                * if it's on this pipe */
-               /* psb_intel_crtc_dpms_video(crtc, true); TODO */
-               break;
-       case DRM_MODE_DPMS_OFF:
-               /* Give the overlay scaler a chance to disable
-                * if it's on this pipe */
-               /* psb_intel_crtc_dpms_video(crtc, FALSE); TODO */
-
-               /* Disable the VGA plane that we never use */
-               REG_WRITE(VGACNTRL, VGA_DISP_DISABLE);
-
-               /* Disable display plane */
-               temp = REG_READ(dspcntr_reg);
-               if ((temp & DISPLAY_PLANE_ENABLE) != 0) {
-                       REG_WRITE(dspcntr_reg,
-                                 temp & ~DISPLAY_PLANE_ENABLE);
-                       /* Flush the plane changes */
-                       REG_WRITE(dspbase_reg, REG_READ(dspbase_reg));
-                       REG_READ(dspbase_reg);
-               }
-
-               /* Next, disable display pipes */
-               temp = REG_READ(pipeconf_reg);
-               if ((temp & PIPEACONF_ENABLE) != 0) {
-                       REG_WRITE(pipeconf_reg, temp & ~PIPEACONF_ENABLE);
-                       REG_READ(pipeconf_reg);
-               }
-
-               /* Wait for vblank for the disable to take effect. */
-               psb_intel_wait_for_vblank(dev);
-
-               temp = REG_READ(dpll_reg);
-               if ((temp & DPLL_VCO_ENABLE) != 0) {
-                       REG_WRITE(dpll_reg, temp & ~DPLL_VCO_ENABLE);
-                       REG_READ(dpll_reg);
-               }
-
-               /* Wait for the clocks to turn off. */
-               udelay(150);
-               break;
-       }
-
-       enabled = crtc->enabled && mode != DRM_MODE_DPMS_OFF;
-
-       /*Set FIFO Watermarks*/
-       REG_WRITE(DSPARB, 0x3F3E);
-}
-
-static void psb_intel_crtc_prepare(struct drm_crtc *crtc)
-{
-       struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
-       crtc_funcs->dpms(crtc, DRM_MODE_DPMS_OFF);
-}
-
-static void psb_intel_crtc_commit(struct drm_crtc *crtc)
-{
-       struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
-       crtc_funcs->dpms(crtc, DRM_MODE_DPMS_ON);
-}
-
-void psb_intel_encoder_prepare(struct drm_encoder *encoder)
-{
-       struct drm_encoder_helper_funcs *encoder_funcs =
-           encoder->helper_private;
-       /* lvds has its own version of prepare see psb_intel_lvds_prepare */
-       encoder_funcs->dpms(encoder, DRM_MODE_DPMS_OFF);
-}
-
-void psb_intel_encoder_commit(struct drm_encoder *encoder)
-{
-       struct drm_encoder_helper_funcs *encoder_funcs =
-           encoder->helper_private;
-       /* lvds has its own version of commit see psb_intel_lvds_commit */
-       encoder_funcs->dpms(encoder, DRM_MODE_DPMS_ON);
-}
-
-static bool psb_intel_crtc_mode_fixup(struct drm_crtc *crtc,
-                                 struct drm_display_mode *mode,
-                                 struct drm_display_mode *adjusted_mode)
-{
-       return true;
-}
-
-
-/**
- * Return the pipe currently connected to the panel fitter,
- * or -1 if the panel fitter is not present or not in use
- */
-static int psb_intel_panel_fitter_pipe(struct drm_device *dev)
-{
-       u32 pfit_control;
-
-       pfit_control = REG_READ(PFIT_CONTROL);
-
-       /* See if the panel fitter is in use */
-       if ((pfit_control & PFIT_ENABLE) == 0)
-               return -1;
-       /* Must be on PIPE 1 for PSB */
-       return 1;
-}
-
-static int psb_intel_crtc_mode_set(struct drm_crtc *crtc,
-                              struct drm_display_mode *mode,
-                              struct drm_display_mode *adjusted_mode,
-                              int x, int y,
-                              struct drm_framebuffer *old_fb)
-{
-       struct drm_device *dev = crtc->dev;
-       struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
-       struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
-       int pipe = psb_intel_crtc->pipe;
-       int fp_reg = (pipe == 0) ? FPA0 : FPB0;
-       int dpll_reg = (pipe == 0) ? DPLL_A : DPLL_B;
-       int dspcntr_reg = (pipe == 0) ? DSPACNTR : DSPBCNTR;
-       int pipeconf_reg = (pipe == 0) ? PIPEACONF : PIPEBCONF;
-       int htot_reg = (pipe == 0) ? HTOTAL_A : HTOTAL_B;
-       int hblank_reg = (pipe == 0) ? HBLANK_A : HBLANK_B;
-       int hsync_reg = (pipe == 0) ? HSYNC_A : HSYNC_B;
-       int vtot_reg = (pipe == 0) ? VTOTAL_A : VTOTAL_B;
-       int vblank_reg = (pipe == 0) ? VBLANK_A : VBLANK_B;
-       int vsync_reg = (pipe == 0) ? VSYNC_A : VSYNC_B;
-       int dspsize_reg = (pipe == 0) ? DSPASIZE : DSPBSIZE;
-       int dsppos_reg = (pipe == 0) ? DSPAPOS : DSPBPOS;
-       int pipesrc_reg = (pipe == 0) ? PIPEASRC : PIPEBSRC;
-       int refclk;
-       struct psb_intel_clock_t clock;
-       u32 dpll = 0, fp = 0, dspcntr, pipeconf;
-       bool ok, is_sdvo = false, is_dvo = false;
-       bool is_crt = false, is_lvds = false, is_tv = false;
-       struct drm_mode_config *mode_config = &dev->mode_config;
-       struct drm_connector *connector;
-
-       /* No scan out no play */
-       if (crtc->fb == NULL) {
-               crtc_funcs->mode_set_base(crtc, x, y, old_fb);
-               return 0;
-       }
-
-       list_for_each_entry(connector, &mode_config->connector_list, head) {
-               struct psb_intel_output *psb_intel_output =
-                   to_psb_intel_output(connector);
-
-               if (!connector->encoder
-                   || connector->encoder->crtc != crtc)
-                       continue;
-
-               switch (psb_intel_output->type) {
-               case INTEL_OUTPUT_LVDS:
-                       is_lvds = true;
-                       break;
-               case INTEL_OUTPUT_SDVO:
-                       is_sdvo = true;
-                       break;
-               case INTEL_OUTPUT_DVO:
-                       is_dvo = true;
-                       break;
-               case INTEL_OUTPUT_TVOUT:
-                       is_tv = true;
-                       break;
-               case INTEL_OUTPUT_ANALOG:
-                       is_crt = true;
-                       break;
-               }
-       }
-
-       refclk = 96000;
-
-       ok = psb_intel_find_best_PLL(crtc, adjusted_mode->clock, refclk,
-                                &clock);
-       if (!ok) {
-               dev_err(dev->dev, "Couldn't find PLL settings for mode!\n");
-               return 0;
-       }
-
-       fp = clock.n << 16 | clock.m1 << 8 | clock.m2;
-
-       dpll = DPLL_VGA_MODE_DIS;
-       if (is_lvds) {
-               dpll |= DPLLB_MODE_LVDS;
-               dpll |= DPLL_DVO_HIGH_SPEED;
-       } else
-               dpll |= DPLLB_MODE_DAC_SERIAL;
-       if (is_sdvo) {
-               int sdvo_pixel_multiply =
-                           adjusted_mode->clock / mode->clock;
-               dpll |= DPLL_DVO_HIGH_SPEED;
-               dpll |=
-                   (sdvo_pixel_multiply - 1) << SDVO_MULTIPLIER_SHIFT_HIRES;
-       }
-
-       /* compute bitmask from p1 value */
-       dpll |= (1 << (clock.p1 - 1)) << 16;
-       switch (clock.p2) {
-       case 5:
-               dpll |= DPLL_DAC_SERIAL_P2_CLOCK_DIV_5;
-               break;
-       case 7:
-               dpll |= DPLLB_LVDS_P2_CLOCK_DIV_7;
-               break;
-       case 10:
-               dpll |= DPLL_DAC_SERIAL_P2_CLOCK_DIV_10;
-               break;
-       case 14:
-               dpll |= DPLLB_LVDS_P2_CLOCK_DIV_14;
-               break;
-       }
-
-       if (is_tv) {
-               /* XXX: just matching BIOS for now */
-/*     dpll |= PLL_REF_INPUT_TVCLKINBC; */
-               dpll |= 3;
-       }
-       dpll |= PLL_REF_INPUT_DREFCLK;
-
-       /* setup pipeconf */
-       pipeconf = REG_READ(pipeconf_reg);
-
-       /* Set up the display plane register */
-       dspcntr = DISPPLANE_GAMMA_ENABLE;
-
-       if (pipe == 0)
-               dspcntr |= DISPPLANE_SEL_PIPE_A;
-       else
-               dspcntr |= DISPPLANE_SEL_PIPE_B;
-
-       dspcntr |= DISPLAY_PLANE_ENABLE;
-       pipeconf |= PIPEACONF_ENABLE;
-       dpll |= DPLL_VCO_ENABLE;
-
-
-       /* Disable the panel fitter if it was on our pipe */
-       if (psb_intel_panel_fitter_pipe(dev) == pipe)
-               REG_WRITE(PFIT_CONTROL, 0);
-
-       drm_mode_debug_printmodeline(mode);
-
-       if (dpll & DPLL_VCO_ENABLE) {
-               REG_WRITE(fp_reg, fp);
-               REG_WRITE(dpll_reg, dpll & ~DPLL_VCO_ENABLE);
-               REG_READ(dpll_reg);
-               udelay(150);
-       }
-
-       /* The LVDS pin pair needs to be on before the DPLLs are enabled.
-        * This is an exception to the general rule that mode_set doesn't turn
-        * things on.
-        */
-       if (is_lvds) {
-               u32 lvds = REG_READ(LVDS);
-
-               lvds &= ~LVDS_PIPEB_SELECT;
-               if (pipe == 1)
-                       lvds |= LVDS_PIPEB_SELECT;
-
-               lvds |= LVDS_PORT_EN | LVDS_A0A2_CLKA_POWER_UP;
-               /* Set the B0-B3 data pairs corresponding to
-                * whether we're going to
-                * set the DPLLs for dual-channel mode or not.
-                */
-               lvds &= ~(LVDS_B0B3_POWER_UP | LVDS_CLKB_POWER_UP);
-               if (clock.p2 == 7)
-                       lvds |= LVDS_B0B3_POWER_UP | LVDS_CLKB_POWER_UP;
-
-               /* It would be nice to set 24 vs 18-bit mode (LVDS_A3_POWER_UP)
-                * appropriately here, but we need to look more
-                * thoroughly into how panels behave in the two modes.
-                */
-
-               REG_WRITE(LVDS, lvds);
-               REG_READ(LVDS);
-       }
-
-       REG_WRITE(fp_reg, fp);
-       REG_WRITE(dpll_reg, dpll);
-       REG_READ(dpll_reg);
-       /* Wait for the clocks to stabilize. */
-       udelay(150);
-
-       /* write it again -- the BIOS does, after all */
-       REG_WRITE(dpll_reg, dpll);
-
-       REG_READ(dpll_reg);
-       /* Wait for the clocks to stabilize. */
-       udelay(150);
-
-       REG_WRITE(htot_reg, (adjusted_mode->crtc_hdisplay - 1) |
-                 ((adjusted_mode->crtc_htotal - 1) << 16));
-       REG_WRITE(hblank_reg, (adjusted_mode->crtc_hblank_start - 1) |
-                 ((adjusted_mode->crtc_hblank_end - 1) << 16));
-       REG_WRITE(hsync_reg, (adjusted_mode->crtc_hsync_start - 1) |
-                 ((adjusted_mode->crtc_hsync_end - 1) << 16));
-       REG_WRITE(vtot_reg, (adjusted_mode->crtc_vdisplay - 1) |
-                 ((adjusted_mode->crtc_vtotal - 1) << 16));
-       REG_WRITE(vblank_reg, (adjusted_mode->crtc_vblank_start - 1) |
-                 ((adjusted_mode->crtc_vblank_end - 1) << 16));
-       REG_WRITE(vsync_reg, (adjusted_mode->crtc_vsync_start - 1) |
-                 ((adjusted_mode->crtc_vsync_end - 1) << 16));
-       /* pipesrc and dspsize control the size that is scaled from,
-        * which should always be the user's requested size.
-        */
-       REG_WRITE(dspsize_reg,
-                 ((mode->vdisplay - 1) << 16) | (mode->hdisplay - 1));
-       REG_WRITE(dsppos_reg, 0);
-       REG_WRITE(pipesrc_reg,
-                 ((mode->hdisplay - 1) << 16) | (mode->vdisplay - 1));
-       REG_WRITE(pipeconf_reg, pipeconf);
-       REG_READ(pipeconf_reg);
-
-       psb_intel_wait_for_vblank(dev);
-
-       REG_WRITE(dspcntr_reg, dspcntr);
-
-       /* Flush the plane changes */
-       crtc_funcs->mode_set_base(crtc, x, y, old_fb);
-
-       psb_intel_wait_for_vblank(dev);
-
-       return 0;
-}
-
-/** Loads the palette/gamma unit for the CRTC with the prepared values */
-void psb_intel_crtc_load_lut(struct drm_crtc *crtc)
-{
-       struct drm_device *dev = crtc->dev;
-       struct drm_psb_private *dev_priv =
-                               (struct drm_psb_private *)dev->dev_private;
-       struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
-       int palreg = PALETTE_A;
-       int i;
-
-       /* The clocks have to be on to load the palette. */
-       if (!crtc->enabled)
-               return;
-
-       switch (psb_intel_crtc->pipe) {
-       case 0:
-               break;
-       case 1:
-               palreg = PALETTE_B;
-               break;
-       case 2:
-               palreg = PALETTE_C;
-               break;
-       default:
-               dev_err(dev->dev, "Illegal Pipe Number.\n");
-               return;
-       }
-
-       if (gma_power_begin(dev, false)) {
-               for (i = 0; i < 256; i++) {
-                       REG_WRITE(palreg + 4 * i,
-                                 ((psb_intel_crtc->lut_r[i] +
-                                 psb_intel_crtc->lut_adj[i]) << 16) |
-                                 ((psb_intel_crtc->lut_g[i] +
-                                 psb_intel_crtc->lut_adj[i]) << 8) |
-                                 (psb_intel_crtc->lut_b[i] +
-                                 psb_intel_crtc->lut_adj[i]));
-               }
-               gma_power_end(dev);
-       } else {
-               for (i = 0; i < 256; i++) {
-                       dev_priv->save_palette_a[i] =
-                                 ((psb_intel_crtc->lut_r[i] +
-                                 psb_intel_crtc->lut_adj[i]) << 16) |
-                                 ((psb_intel_crtc->lut_g[i] +
-                                 psb_intel_crtc->lut_adj[i]) << 8) |
-                                 (psb_intel_crtc->lut_b[i] +
-                                 psb_intel_crtc->lut_adj[i]);
-               }
-
-       }
-}
-
-/**
- * Save HW states of giving crtc
- */
-static void psb_intel_crtc_save(struct drm_crtc *crtc)
-{
-       struct drm_device *dev = crtc->dev;
-       /* struct drm_psb_private *dev_priv =
-                       (struct drm_psb_private *)dev->dev_private; */
-       struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
-       struct psb_intel_crtc_state *crtc_state = psb_intel_crtc->crtc_state;
-       int pipeA = (psb_intel_crtc->pipe == 0);
-       uint32_t paletteReg;
-       int i;
-
-       if (!crtc_state) {
-               dev_err(dev->dev, "No CRTC state found\n");
-               return;
-       }
-
-       crtc_state->saveDSPCNTR = REG_READ(pipeA ? DSPACNTR : DSPBCNTR);
-       crtc_state->savePIPECONF = REG_READ(pipeA ? PIPEACONF : PIPEBCONF);
-       crtc_state->savePIPESRC = REG_READ(pipeA ? PIPEASRC : PIPEBSRC);
-       crtc_state->saveFP0 = REG_READ(pipeA ? FPA0 : FPB0);
-       crtc_state->saveFP1 = REG_READ(pipeA ? FPA1 : FPB1);
-       crtc_state->saveDPLL = REG_READ(pipeA ? DPLL_A : DPLL_B);
-       crtc_state->saveHTOTAL = REG_READ(pipeA ? HTOTAL_A : HTOTAL_B);
-       crtc_state->saveHBLANK = REG_READ(pipeA ? HBLANK_A : HBLANK_B);
-       crtc_state->saveHSYNC = REG_READ(pipeA ? HSYNC_A : HSYNC_B);
-       crtc_state->saveVTOTAL = REG_READ(pipeA ? VTOTAL_A : VTOTAL_B);
-       crtc_state->saveVBLANK = REG_READ(pipeA ? VBLANK_A : VBLANK_B);
-       crtc_state->saveVSYNC = REG_READ(pipeA ? VSYNC_A : VSYNC_B);
-       crtc_state->saveDSPSTRIDE = REG_READ(pipeA ? DSPASTRIDE : DSPBSTRIDE);
-
-       /*NOTE: DSPSIZE DSPPOS only for psb*/
-       crtc_state->saveDSPSIZE = REG_READ(pipeA ? DSPASIZE : DSPBSIZE);
-       crtc_state->saveDSPPOS = REG_READ(pipeA ? DSPAPOS : DSPBPOS);
-
-       crtc_state->saveDSPBASE = REG_READ(pipeA ? DSPABASE : DSPBBASE);
-
-       paletteReg = pipeA ? PALETTE_A : PALETTE_B;
-       for (i = 0; i < 256; ++i)
-               crtc_state->savePalette[i] = REG_READ(paletteReg + (i << 2));
-}
-
-/**
- * Restore HW states of giving crtc
- */
-static void psb_intel_crtc_restore(struct drm_crtc *crtc)
-{
-       struct drm_device *dev = crtc->dev;
-       /* struct drm_psb_private * dev_priv =
-                               (struct drm_psb_private *)dev->dev_private; */
-       struct psb_intel_crtc *psb_intel_crtc =  to_psb_intel_crtc(crtc);
-       struct psb_intel_crtc_state *crtc_state = psb_intel_crtc->crtc_state;
-       /* struct drm_crtc_helper_funcs * crtc_funcs = crtc->helper_private; */
-       int pipeA = (psb_intel_crtc->pipe == 0);
-       uint32_t paletteReg;
-       int i;
-
-       if (!crtc_state) {
-               dev_err(dev->dev, "No crtc state\n");
-               return;
-       }
-
-       if (crtc_state->saveDPLL & DPLL_VCO_ENABLE) {
-               REG_WRITE(pipeA ? DPLL_A : DPLL_B,
-                       crtc_state->saveDPLL & ~DPLL_VCO_ENABLE);
-               REG_READ(pipeA ? DPLL_A : DPLL_B);
-               udelay(150);
-       }
-
-       REG_WRITE(pipeA ? FPA0 : FPB0, crtc_state->saveFP0);
-       REG_READ(pipeA ? FPA0 : FPB0);
-
-       REG_WRITE(pipeA ? FPA1 : FPB1, crtc_state->saveFP1);
-       REG_READ(pipeA ? FPA1 : FPB1);
-
-       REG_WRITE(pipeA ? DPLL_A : DPLL_B, crtc_state->saveDPLL);
-       REG_READ(pipeA ? DPLL_A : DPLL_B);
-       udelay(150);
-
-       REG_WRITE(pipeA ? HTOTAL_A : HTOTAL_B, crtc_state->saveHTOTAL);
-       REG_WRITE(pipeA ? HBLANK_A : HBLANK_B, crtc_state->saveHBLANK);
-       REG_WRITE(pipeA ? HSYNC_A : HSYNC_B, crtc_state->saveHSYNC);
-       REG_WRITE(pipeA ? VTOTAL_A : VTOTAL_B, crtc_state->saveVTOTAL);
-       REG_WRITE(pipeA ? VBLANK_A : VBLANK_B, crtc_state->saveVBLANK);
-       REG_WRITE(pipeA ? VSYNC_A : VSYNC_B, crtc_state->saveVSYNC);
-       REG_WRITE(pipeA ? DSPASTRIDE : DSPBSTRIDE, crtc_state->saveDSPSTRIDE);
-
-       REG_WRITE(pipeA ? DSPASIZE : DSPBSIZE, crtc_state->saveDSPSIZE);
-       REG_WRITE(pipeA ? DSPAPOS : DSPBPOS, crtc_state->saveDSPPOS);
-
-       REG_WRITE(pipeA ? PIPEASRC : PIPEBSRC, crtc_state->savePIPESRC);
-       REG_WRITE(pipeA ? DSPABASE : DSPBBASE, crtc_state->saveDSPBASE);
-       REG_WRITE(pipeA ? PIPEACONF : PIPEBCONF, crtc_state->savePIPECONF);
-
-       psb_intel_wait_for_vblank(dev);
-
-       REG_WRITE(pipeA ? DSPACNTR : DSPBCNTR, crtc_state->saveDSPCNTR);
-       REG_WRITE(pipeA ? DSPABASE : DSPBBASE, crtc_state->saveDSPBASE);
-
-       psb_intel_wait_for_vblank(dev);
-
-       paletteReg = pipeA ? PALETTE_A : PALETTE_B;
-       for (i = 0; i < 256; ++i)
-               REG_WRITE(paletteReg + (i << 2), crtc_state->savePalette[i]);
-}
-
-static int psb_intel_crtc_cursor_set(struct drm_crtc *crtc,
-                                struct drm_file *file_priv,
-                                uint32_t handle,
-                                uint32_t width, uint32_t height)
-{
-       struct drm_device *dev = crtc->dev;
-       struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
-       int pipe = psb_intel_crtc->pipe;
-       uint32_t control = (pipe == 0) ? CURACNTR : CURBCNTR;
-       uint32_t base = (pipe == 0) ? CURABASE : CURBBASE;
-       uint32_t temp;
-       size_t addr = 0;
-       struct gtt_range *gt;
-       struct drm_gem_object *obj;
-       int ret;
-
-       /* if we want to turn of the cursor ignore width and height */
-       if (!handle) {
-               /* turn off the cursor */
-               temp = CURSOR_MODE_DISABLE;
-
-               if (gma_power_begin(dev, false)) {
-                       REG_WRITE(control, temp);
-                       REG_WRITE(base, 0);
-                       gma_power_end(dev);
-               }
-
-               /* Unpin the old GEM object */
-               if (psb_intel_crtc->cursor_obj) {
-                       gt = container_of(psb_intel_crtc->cursor_obj,
-                                                       struct gtt_range, gem);
-                       psb_gtt_unpin(gt);
-                       drm_gem_object_unreference(psb_intel_crtc->cursor_obj);
-                       psb_intel_crtc->cursor_obj = NULL;
-               }
-
-               return 0;
-       }
-
-       /* Currently we only support 64x64 cursors */
-       if (width != 64 || height != 64) {
-               dev_dbg(dev->dev, "we currently only support 64x64 cursors\n");
-               return -EINVAL;
-       }
-
-       obj = drm_gem_object_lookup(dev, file_priv, handle);
-       if (!obj)
-               return -ENOENT;
-
-       if (obj->size < width * height * 4) {
-               dev_dbg(dev->dev, "buffer is to small\n");
-               return -ENOMEM;
-       }
-
-       gt = container_of(obj, struct gtt_range, gem);
-
-       /* Pin the memory into the GTT */
-       ret = psb_gtt_pin(gt);
-       if (ret) {
-               dev_err(dev->dev, "Can not pin down handle 0x%x\n", handle);
-               return ret;
-       }
-
-
-       addr = gt->offset;      /* Or resource.start ??? */
-
-       psb_intel_crtc->cursor_addr = addr;
-
-       temp = 0;
-       /* set the pipe for the cursor */
-       temp |= (pipe << 28);
-       temp |= CURSOR_MODE_64_ARGB_AX | MCURSOR_GAMMA_ENABLE;
-
-       if (gma_power_begin(dev, false)) {
-               REG_WRITE(control, temp);
-               REG_WRITE(base, addr);
-               gma_power_end(dev);
-       }
-
-       /* unpin the old bo */
-       if (psb_intel_crtc->cursor_obj) {
-               gt = container_of(psb_intel_crtc->cursor_obj,
-                                                       struct gtt_range, gem);
-               psb_gtt_unpin(gt);
-               drm_gem_object_unreference(psb_intel_crtc->cursor_obj);
-               psb_intel_crtc->cursor_obj = obj;
-       }
-       return 0;
-}
-
-static int psb_intel_crtc_cursor_move(struct drm_crtc *crtc, int x, int y)
-{
-       struct drm_device *dev = crtc->dev;
-       struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
-       int pipe = psb_intel_crtc->pipe;
-       uint32_t temp = 0;
-       uint32_t addr;
-
-
-       if (x < 0) {
-               temp |= (CURSOR_POS_SIGN << CURSOR_X_SHIFT);
-               x = -x;
-       }
-       if (y < 0) {
-               temp |= (CURSOR_POS_SIGN << CURSOR_Y_SHIFT);
-               y = -y;
-       }
-
-       temp |= ((x & CURSOR_POS_MASK) << CURSOR_X_SHIFT);
-       temp |= ((y & CURSOR_POS_MASK) << CURSOR_Y_SHIFT);
-
-       addr = psb_intel_crtc->cursor_addr;
-
-       if (gma_power_begin(dev, false)) {
-               REG_WRITE((pipe == 0) ? CURAPOS : CURBPOS, temp);
-               REG_WRITE((pipe == 0) ? CURABASE : CURBBASE, addr);
-               gma_power_end(dev);
-       }
-       return 0;
-}
-
-void psb_intel_crtc_gamma_set(struct drm_crtc *crtc, u16 *red,
-                        u16 *green, u16 *blue, uint32_t type, uint32_t size)
-{
-       struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
-       int i;
-
-       if (size != 256)
-               return;
-
-       for (i = 0; i < 256; i++) {
-               psb_intel_crtc->lut_r[i] = red[i] >> 8;
-               psb_intel_crtc->lut_g[i] = green[i] >> 8;
-               psb_intel_crtc->lut_b[i] = blue[i] >> 8;
-       }
-
-       psb_intel_crtc_load_lut(crtc);
-}
-
-static int psb_crtc_set_config(struct drm_mode_set *set)
-{
-       int ret;
-       struct drm_device *dev = set->crtc->dev;
-
-       pm_runtime_forbid(&dev->pdev->dev);
-       ret = drm_crtc_helper_set_config(set);
-       pm_runtime_allow(&dev->pdev->dev);
-       return ret;
-}
-
-/* Returns the clock of the currently programmed mode of the given pipe. */
-static int psb_intel_crtc_clock_get(struct drm_device *dev,
-                               struct drm_crtc *crtc)
-{
-       struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
-       int pipe = psb_intel_crtc->pipe;
-       u32 dpll;
-       u32 fp;
-       struct psb_intel_clock_t clock;
-       bool is_lvds;
-       struct drm_psb_private *dev_priv = dev->dev_private;
-
-       if (gma_power_begin(dev, false)) {
-               dpll = REG_READ((pipe == 0) ? DPLL_A : DPLL_B);
-               if ((dpll & DISPLAY_RATE_SELECT_FPA1) == 0)
-                       fp = REG_READ((pipe == 0) ? FPA0 : FPB0);
-               else
-                       fp = REG_READ((pipe == 0) ? FPA1 : FPB1);
-               is_lvds = (pipe == 1) && (REG_READ(LVDS) & LVDS_PORT_EN);
-               gma_power_end(dev);
-       } else {
-               dpll = (pipe == 0) ?
-                       dev_priv->saveDPLL_A : dev_priv->saveDPLL_B;
-
-               if ((dpll & DISPLAY_RATE_SELECT_FPA1) == 0)
-                       fp = (pipe == 0) ?
-                               dev_priv->saveFPA0 :
-                               dev_priv->saveFPB0;
-               else
-                       fp = (pipe == 0) ?
-                               dev_priv->saveFPA1 :
-                               dev_priv->saveFPB1;
-
-               is_lvds = (pipe == 1) && (dev_priv->saveLVDS & LVDS_PORT_EN);
-       }
-
-       clock.m1 = (fp & FP_M1_DIV_MASK) >> FP_M1_DIV_SHIFT;
-       clock.m2 = (fp & FP_M2_DIV_MASK) >> FP_M2_DIV_SHIFT;
-       clock.n = (fp & FP_N_DIV_MASK) >> FP_N_DIV_SHIFT;
-
-       if (is_lvds) {
-               clock.p1 =
-                   ffs((dpll &
-                        DPLL_FPA01_P1_POST_DIV_MASK_I830_LVDS) >>
-                       DPLL_FPA01_P1_POST_DIV_SHIFT);
-               clock.p2 = 14;
-
-               if ((dpll & PLL_REF_INPUT_MASK) ==
-                   PLLB_REF_INPUT_SPREADSPECTRUMIN) {
-                       /* XXX: might not be 66MHz */
-                       i8xx_clock(66000, &clock);
-               } else
-                       i8xx_clock(48000, &clock);
-       } else {
-               if (dpll & PLL_P1_DIVIDE_BY_TWO)
-                       clock.p1 = 2;
-               else {
-                       clock.p1 =
-                           ((dpll &
-                             DPLL_FPA01_P1_POST_DIV_MASK_I830) >>
-                            DPLL_FPA01_P1_POST_DIV_SHIFT) + 2;
-               }
-               if (dpll & PLL_P2_DIVIDE_BY_4)
-                       clock.p2 = 4;
-               else
-                       clock.p2 = 2;
-
-               i8xx_clock(48000, &clock);
-       }
-
-       /* XXX: It would be nice to validate the clocks, but we can't reuse
-        * i830PllIsValid() because it relies on the xf86_config connector
-        * configuration being accurate, which it isn't necessarily.
-        */
-
-       return clock.dot;
-}
-
-/** Returns the currently programmed mode of the given pipe. */
-struct drm_display_mode *psb_intel_crtc_mode_get(struct drm_device *dev,
-                                            struct drm_crtc *crtc)
-{
-       struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
-       int pipe = psb_intel_crtc->pipe;
-       struct drm_display_mode *mode;
-       int htot;
-       int hsync;
-       int vtot;
-       int vsync;
-       struct drm_psb_private *dev_priv = dev->dev_private;
-
-       if (gma_power_begin(dev, false)) {
-               htot = REG_READ((pipe == 0) ? HTOTAL_A : HTOTAL_B);
-               hsync = REG_READ((pipe == 0) ? HSYNC_A : HSYNC_B);
-               vtot = REG_READ((pipe == 0) ? VTOTAL_A : VTOTAL_B);
-               vsync = REG_READ((pipe == 0) ? VSYNC_A : VSYNC_B);
-               gma_power_end(dev);
-       } else {
-               htot = (pipe == 0) ?
-                       dev_priv->saveHTOTAL_A : dev_priv->saveHTOTAL_B;
-               hsync = (pipe == 0) ?
-                       dev_priv->saveHSYNC_A : dev_priv->saveHSYNC_B;
-               vtot = (pipe == 0) ?
-                       dev_priv->saveVTOTAL_A : dev_priv->saveVTOTAL_B;
-               vsync = (pipe == 0) ?
-                       dev_priv->saveVSYNC_A : dev_priv->saveVSYNC_B;
-       }
-
-       mode = kzalloc(sizeof(*mode), GFP_KERNEL);
-       if (!mode)
-               return NULL;
-
-       mode->clock = psb_intel_crtc_clock_get(dev, crtc);
-       mode->hdisplay = (htot & 0xffff) + 1;
-       mode->htotal = ((htot & 0xffff0000) >> 16) + 1;
-       mode->hsync_start = (hsync & 0xffff) + 1;
-       mode->hsync_end = ((hsync & 0xffff0000) >> 16) + 1;
-       mode->vdisplay = (vtot & 0xffff) + 1;
-       mode->vtotal = ((vtot & 0xffff0000) >> 16) + 1;
-       mode->vsync_start = (vsync & 0xffff) + 1;
-       mode->vsync_end = ((vsync & 0xffff0000) >> 16) + 1;
-
-       drm_mode_set_name(mode);
-       drm_mode_set_crtcinfo(mode, 0);
-
-       return mode;
-}
-
-void psb_intel_crtc_destroy(struct drm_crtc *crtc)
-{
-       struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
-       struct gtt_range *gt;
-
-       /* Unpin the old GEM object */
-       if (psb_intel_crtc->cursor_obj) {
-               gt = container_of(psb_intel_crtc->cursor_obj,
-                                               struct gtt_range, gem);
-               psb_gtt_unpin(gt);
-               drm_gem_object_unreference(psb_intel_crtc->cursor_obj);
-               psb_intel_crtc->cursor_obj = NULL;
-       }
-       kfree(psb_intel_crtc->crtc_state);
-       drm_crtc_cleanup(crtc);
-       kfree(psb_intel_crtc);
-}
-
-const struct drm_crtc_helper_funcs psb_intel_helper_funcs = {
-       .dpms = psb_intel_crtc_dpms,
-       .mode_fixup = psb_intel_crtc_mode_fixup,
-       .mode_set = psb_intel_crtc_mode_set,
-       .mode_set_base = psb_intel_pipe_set_base,
-       .prepare = psb_intel_crtc_prepare,
-       .commit = psb_intel_crtc_commit,
-};
-
-const struct drm_crtc_funcs psb_intel_crtc_funcs = {
-       .save = psb_intel_crtc_save,
-       .restore = psb_intel_crtc_restore,
-       .cursor_set = psb_intel_crtc_cursor_set,
-       .cursor_move = psb_intel_crtc_cursor_move,
-       .gamma_set = psb_intel_crtc_gamma_set,
-       .set_config = psb_crtc_set_config,
-       .destroy = psb_intel_crtc_destroy,
-};
-
-/*
- * Set the default value of cursor control and base register
- * to zero. This is a workaround for h/w defect on Oaktrail
- */
-static void psb_intel_cursor_init(struct drm_device *dev, int pipe)
-{
-       u32 control[3] = { CURACNTR, CURBCNTR, CURCCNTR };
-       u32 base[3] = { CURABASE, CURBBASE, CURCBASE };
-
-       REG_WRITE(control[pipe], 0);
-       REG_WRITE(base[pipe], 0);
-}
-
-void psb_intel_crtc_init(struct drm_device *dev, int pipe,
-                    struct psb_intel_mode_device *mode_dev)
-{
-       struct drm_psb_private *dev_priv = dev->dev_private;
-       struct psb_intel_crtc *psb_intel_crtc;
-       int i;
-       uint16_t *r_base, *g_base, *b_base;
-
-       /* We allocate a extra array of drm_connector pointers
-        * for fbdev after the crtc */
-       psb_intel_crtc =
-           kzalloc(sizeof(struct psb_intel_crtc) +
-                   (INTELFB_CONN_LIMIT * sizeof(struct drm_connector *)),
-                   GFP_KERNEL);
-       if (psb_intel_crtc == NULL)
-               return;
-
-       psb_intel_crtc->crtc_state =
-               kzalloc(sizeof(struct psb_intel_crtc_state), GFP_KERNEL);
-       if (!psb_intel_crtc->crtc_state) {
-               dev_err(dev->dev, "Crtc state error: No memory\n");
-               kfree(psb_intel_crtc);
-               return;
-       }
-
-       /* Set the CRTC operations from the chip specific data */
-       drm_crtc_init(dev, &psb_intel_crtc->base, dev_priv->ops->crtc_funcs);
-
-       drm_mode_crtc_set_gamma_size(&psb_intel_crtc->base, 256);
-       psb_intel_crtc->pipe = pipe;
-       psb_intel_crtc->plane = pipe;
-
-       r_base = psb_intel_crtc->base.gamma_store;
-       g_base = r_base + 256;
-       b_base = g_base + 256;
-       for (i = 0; i < 256; i++) {
-               psb_intel_crtc->lut_r[i] = i;
-               psb_intel_crtc->lut_g[i] = i;
-               psb_intel_crtc->lut_b[i] = i;
-               r_base[i] = i << 8;
-               g_base[i] = i << 8;
-               b_base[i] = i << 8;
-
-               psb_intel_crtc->lut_adj[i] = 0;
-       }
-
-       psb_intel_crtc->mode_dev = mode_dev;
-       psb_intel_crtc->cursor_addr = 0;
-
-       drm_crtc_helper_add(&psb_intel_crtc->base,
-                                               dev_priv->ops->crtc_helper);
-
-       /* Setup the array of drm_connector pointer array */
-       psb_intel_crtc->mode_set.crtc = &psb_intel_crtc->base;
-       BUG_ON(pipe >= ARRAY_SIZE(dev_priv->plane_to_crtc_mapping) ||
-              dev_priv->plane_to_crtc_mapping[psb_intel_crtc->plane] != NULL);
-       dev_priv->plane_to_crtc_mapping[psb_intel_crtc->plane] =
-                                                       &psb_intel_crtc->base;
-       dev_priv->pipe_to_crtc_mapping[psb_intel_crtc->pipe] =
-                                                       &psb_intel_crtc->base;
-       psb_intel_crtc->mode_set.connectors =
-           (struct drm_connector **) (psb_intel_crtc + 1);
-       psb_intel_crtc->mode_set.num_connectors = 0;
-       psb_intel_cursor_init(dev, pipe);
-}
-
-int psb_intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data,
-                               struct drm_file *file_priv)
-{
-       struct drm_psb_private *dev_priv = dev->dev_private;
-       struct drm_psb_get_pipe_from_crtc_id_arg *pipe_from_crtc_id = data;
-       struct drm_mode_object *drmmode_obj;
-       struct psb_intel_crtc *crtc;
-
-       if (!dev_priv) {
-               dev_err(dev->dev, "called with no initialization\n");
-               return -EINVAL;
-       }
-
-       drmmode_obj = drm_mode_object_find(dev, pipe_from_crtc_id->crtc_id,
-                       DRM_MODE_OBJECT_CRTC);
-
-       if (!drmmode_obj) {
-               dev_err(dev->dev, "no such CRTC id\n");
-               return -EINVAL;
-       }
-
-       crtc = to_psb_intel_crtc(obj_to_crtc(drmmode_obj));
-       pipe_from_crtc_id->pipe = crtc->pipe;
-
-       return 0;
-}
-
-struct drm_crtc *psb_intel_get_crtc_from_pipe(struct drm_device *dev, int pipe)
-{
-       struct drm_crtc *crtc = NULL;
-
-       list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
-               struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
-               if (psb_intel_crtc->pipe == pipe)
-                       break;
-       }
-       return crtc;
-}
-
-int psb_intel_connector_clones(struct drm_device *dev, int type_mask)
-{
-       int index_mask = 0;
-       struct drm_connector *connector;
-       int entry = 0;
-
-       list_for_each_entry(connector, &dev->mode_config.connector_list,
-                           head) {
-               struct psb_intel_output *psb_intel_output =
-                   to_psb_intel_output(connector);
-               if (type_mask & (1 << psb_intel_output->type))
-                       index_mask |= (1 << entry);
-               entry++;
-       }
-       return index_mask;
-}
-
-
-void psb_intel_modeset_cleanup(struct drm_device *dev)
-{
-       drm_mode_config_cleanup(dev);
-}
-
-
-/* current intel driver doesn't take advantage of encoders
-   always give back the encoder for the connector
-*/
-struct drm_encoder *psb_intel_best_encoder(struct drm_connector *connector)
-{
-       struct psb_intel_output *psb_intel_output =
-                                       to_psb_intel_output(connector);
-
-       return &psb_intel_output->enc;
-}
-
diff --git a/drivers/staging/gma500/psb_intel_display.h b/drivers/staging/gma500/psb_intel_display.h
deleted file mode 100644 (file)
index 535b49a..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-/* copyright (c) 2008, Intel Corporation
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Authors:
- * Eric Anholt <eric@anholt.net>
- */
-
-#ifndef _INTEL_DISPLAY_H_
-#define _INTEL_DISPLAY_H_
-
-bool psb_intel_pipe_has_type(struct drm_crtc *crtc, int type);
-void psb_intel_crtc_gamma_set(struct drm_crtc *crtc, u16 *red,
-                        u16 *green, u16 *blue, uint32_t type, uint32_t size);
-void psb_intel_crtc_destroy(struct drm_crtc *crtc);
-
-#endif
diff --git a/drivers/staging/gma500/psb_intel_drv.h b/drivers/staging/gma500/psb_intel_drv.h
deleted file mode 100644 (file)
index 36b554b..0000000
+++ /dev/null
@@ -1,230 +0,0 @@
-/*
- * Copyright (c) 2009-2011, Intel Corporation.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-
-#ifndef __INTEL_DRV_H__
-#define __INTEL_DRV_H__
-
-#include <linux/i2c.h>
-#include <linux/i2c-algo-bit.h>
-#include <drm/drm_crtc.h>
-#include <drm/drm_crtc_helper.h>
-#include <linux/gpio.h>
-
-/*
- * Display related stuff
- */
-
-/* store information about an Ixxx DVO */
-/* The i830->i865 use multiple DVOs with multiple i2cs */
-/* the i915, i945 have a single sDVO i2c bus - which is different */
-#define MAX_OUTPUTS 6
-/* maximum connectors per crtcs in the mode set */
-#define INTELFB_CONN_LIMIT 4
-
-#define INTEL_I2C_BUS_DVO 1
-#define INTEL_I2C_BUS_SDVO 2
-
-/* these are outputs from the chip - integrated only
- * external chips are via DVO or SDVO output */
-#define INTEL_OUTPUT_UNUSED 0
-#define INTEL_OUTPUT_ANALOG 1
-#define INTEL_OUTPUT_DVO 2
-#define INTEL_OUTPUT_SDVO 3
-#define INTEL_OUTPUT_LVDS 4
-#define INTEL_OUTPUT_TVOUT 5
-#define INTEL_OUTPUT_HDMI 6
-#define INTEL_OUTPUT_MIPI 7
-#define INTEL_OUTPUT_MIPI2 8
-
-#define INTEL_DVO_CHIP_NONE 0
-#define INTEL_DVO_CHIP_LVDS 1
-#define INTEL_DVO_CHIP_TMDS 2
-#define INTEL_DVO_CHIP_TVOUT 4
-
-/*
- * Hold information useally put on the device driver privates here,
- * since it needs to be shared across multiple of devices drivers privates.
- */
-struct psb_intel_mode_device {
-
-       /*
-        * Abstracted memory manager operations
-        */
-        size_t(*bo_offset) (struct drm_device *dev, void *bo);
-
-       /*
-        * Cursor (Can go ?)
-        */
-       int cursor_needs_physical;
-
-       /*
-        * LVDS info
-        */
-       int backlight_duty_cycle;       /* restore backlight to this value */
-       bool panel_wants_dither;
-       struct drm_display_mode *panel_fixed_mode;
-       struct drm_display_mode *panel_fixed_mode2;
-       struct drm_display_mode *vbt_mode;      /* if any */
-
-       uint32_t saveBLC_PWM_CTL;
-};
-
-struct psb_intel_i2c_chan {
-       /* for getting at dev. private (mmio etc.) */
-       struct drm_device *drm_dev;
-       u32 reg;                /* GPIO reg */
-       struct i2c_adapter adapter;
-       struct i2c_algo_bit_data algo;
-       u8 slave_addr;
-};
-
-struct psb_intel_output {
-       struct drm_connector base;
-
-       struct drm_encoder enc;
-       int type;
-
-       struct psb_intel_i2c_chan *i2c_bus;     /* for control functions */
-       struct psb_intel_i2c_chan *ddc_bus;     /* for DDC only stuff */
-       bool load_detect_temp;
-       void *dev_priv;
-
-       struct psb_intel_mode_device *mode_dev;
-       struct i2c_adapter *hdmi_i2c_adapter;   /* for control functions */
-};
-
-struct psb_intel_crtc_state {
-       uint32_t saveDSPCNTR;
-       uint32_t savePIPECONF;
-       uint32_t savePIPESRC;
-       uint32_t saveDPLL;
-       uint32_t saveFP0;
-       uint32_t saveFP1;
-       uint32_t saveHTOTAL;
-       uint32_t saveHBLANK;
-       uint32_t saveHSYNC;
-       uint32_t saveVTOTAL;
-       uint32_t saveVBLANK;
-       uint32_t saveVSYNC;
-       uint32_t saveDSPSTRIDE;
-       uint32_t saveDSPSIZE;
-       uint32_t saveDSPPOS;
-       uint32_t saveDSPBASE;
-       uint32_t savePalette[256];
-};
-
-struct psb_intel_crtc {
-       struct drm_crtc base;
-       int pipe;
-       int plane;
-       uint32_t cursor_addr;
-       u8 lut_r[256], lut_g[256], lut_b[256];
-       u8 lut_adj[256];
-       struct psb_intel_framebuffer *fbdev_fb;
-       /* a mode_set for fbdev users on this crtc */
-       struct drm_mode_set mode_set;
-
-       /* GEM object that holds our cursor */
-       struct drm_gem_object *cursor_obj;
-
-       struct drm_display_mode saved_mode;
-       struct drm_display_mode saved_adjusted_mode;
-
-       struct psb_intel_mode_device *mode_dev;
-
-       /*crtc mode setting flags*/
-       u32 mode_flags;
-
-       /* Saved Crtc HW states */
-       struct psb_intel_crtc_state *crtc_state;
-};
-
-#define to_psb_intel_crtc(x)   \
-               container_of(x, struct psb_intel_crtc, base)
-#define to_psb_intel_output(x) \
-               container_of(x, struct psb_intel_output, base)
-#define enc_to_psb_intel_output(x)     \
-               container_of(x, struct psb_intel_output, enc)
-#define to_psb_intel_framebuffer(x)    \
-               container_of(x, struct psb_intel_framebuffer, base)
-
-struct psb_intel_i2c_chan *psb_intel_i2c_create(struct drm_device *dev,
-                                       const u32 reg, const char *name);
-void psb_intel_i2c_destroy(struct psb_intel_i2c_chan *chan);
-int psb_intel_ddc_get_modes(struct psb_intel_output *psb_intel_output);
-extern bool psb_intel_ddc_probe(struct psb_intel_output *psb_intel_output);
-
-extern void psb_intel_crtc_init(struct drm_device *dev, int pipe,
-                           struct psb_intel_mode_device *mode_dev);
-extern void psb_intel_crt_init(struct drm_device *dev);
-extern void psb_intel_sdvo_init(struct drm_device *dev, int output_device);
-extern void psb_intel_dvo_init(struct drm_device *dev);
-extern void psb_intel_tv_init(struct drm_device *dev);
-extern void psb_intel_lvds_init(struct drm_device *dev,
-                           struct psb_intel_mode_device *mode_dev);
-extern void psb_intel_lvds_set_brightness(struct drm_device *dev, int level);
-extern void mrst_lvds_init(struct drm_device *dev,
-                          struct psb_intel_mode_device *mode_dev);
-extern void mrst_wait_for_INTR_PKT_SENT(struct drm_device *dev);
-extern void mrst_dsi_init(struct drm_device *dev,
-                          struct psb_intel_mode_device *mode_dev);
-extern void mid_dsi_init(struct drm_device *dev,
-                   struct psb_intel_mode_device *mode_dev, int dsi_num);
-
-extern void psb_intel_crtc_load_lut(struct drm_crtc *crtc);
-extern void psb_intel_encoder_prepare(struct drm_encoder *encoder);
-extern void psb_intel_encoder_commit(struct drm_encoder *encoder);
-
-extern struct drm_encoder *psb_intel_best_encoder(struct drm_connector
-                                             *connector);
-
-extern struct drm_display_mode *psb_intel_crtc_mode_get(struct drm_device *dev,
-                                                   struct drm_crtc *crtc);
-extern void psb_intel_wait_for_vblank(struct drm_device *dev);
-extern int psb_intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data,
-                               struct drm_file *file_priv);
-extern struct drm_crtc *psb_intel_get_crtc_from_pipe(struct drm_device *dev,
-                                                int pipe);
-extern struct drm_connector *psb_intel_sdvo_find(struct drm_device *dev,
-                                            int sdvoB);
-extern int psb_intel_sdvo_supports_hotplug(struct drm_connector *connector);
-extern void psb_intel_sdvo_set_hotplug(struct drm_connector *connector,
-                                  int enable);
-extern int intelfb_probe(struct drm_device *dev);
-extern int intelfb_remove(struct drm_device *dev,
-                         struct drm_framebuffer *fb);
-extern struct drm_framebuffer *psb_intel_framebuffer_create(struct drm_device
-                                                       *dev, struct
-                                                       drm_mode_fb_cmd
-                                                       *mode_cmd,
-                                                       void *mm_private);
-extern bool psb_intel_lvds_mode_fixup(struct drm_encoder *encoder,
-                                     struct drm_display_mode *mode,
-                                     struct drm_display_mode *adjusted_mode);
-extern int psb_intel_lvds_mode_valid(struct drm_connector *connector,
-                                    struct drm_display_mode *mode);
-extern int psb_intel_lvds_set_property(struct drm_connector *connector,
-                                       struct drm_property *property,
-                                       uint64_t value);
-extern void psb_intel_lvds_destroy(struct drm_connector *connector);
-extern const struct drm_encoder_funcs psb_intel_lvds_enc_funcs;
-
-extern void mdfldWaitForPipeDisable(struct drm_device *dev, int pipe);
-extern void mdfldWaitForPipeEnable(struct drm_device *dev, int pipe);
-
-#endif                         /* __INTEL_DRV_H__ */
diff --git a/drivers/staging/gma500/psb_intel_lvds.c b/drivers/staging/gma500/psb_intel_lvds.c
deleted file mode 100644 (file)
index 21022e1..0000000
+++ /dev/null
@@ -1,854 +0,0 @@
-/*
- * Copyright Â© 2006-2007 Intel Corporation
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Authors:
- *     Eric Anholt <eric@anholt.net>
- *     Dave Airlie <airlied@linux.ie>
- *     Jesse Barnes <jesse.barnes@intel.com>
- */
-
-#include <linux/i2c.h>
-#include <drm/drmP.h>
-
-#include "intel_bios.h"
-#include "psb_drv.h"
-#include "psb_intel_drv.h"
-#include "psb_intel_reg.h"
-#include "power.h"
-#include <linux/pm_runtime.h>
-
-/*
- * LVDS I2C backlight control macros
- */
-#define BRIGHTNESS_MAX_LEVEL 100
-#define BRIGHTNESS_MASK 0xFF
-#define BLC_I2C_TYPE   0x01
-#define BLC_PWM_TYPT   0x02
-
-#define BLC_POLARITY_NORMAL 0
-#define BLC_POLARITY_INVERSE 1
-
-#define PSB_BLC_MAX_PWM_REG_FREQ       (0xFFFE)
-#define PSB_BLC_MIN_PWM_REG_FREQ       (0x2)
-#define PSB_BLC_PWM_PRECISION_FACTOR   (10)
-#define PSB_BACKLIGHT_PWM_CTL_SHIFT    (16)
-#define PSB_BACKLIGHT_PWM_POLARITY_BIT_CLEAR (0xFFFE)
-
-struct psb_intel_lvds_priv {
-       /*
-        * Saved LVDO output states
-        */
-       uint32_t savePP_ON;
-       uint32_t savePP_OFF;
-       uint32_t saveLVDS;
-       uint32_t savePP_CONTROL;
-       uint32_t savePP_CYCLE;
-       uint32_t savePFIT_CONTROL;
-       uint32_t savePFIT_PGM_RATIOS;
-       uint32_t saveBLC_PWM_CTL;
-};
-
-
-/*
- * Returns the maximum level of the backlight duty cycle field.
- */
-static u32 psb_intel_lvds_get_max_backlight(struct drm_device *dev)
-{
-       struct drm_psb_private *dev_priv = dev->dev_private;
-       u32 ret;
-
-       if (gma_power_begin(dev, false)) {
-               ret = REG_READ(BLC_PWM_CTL);
-               gma_power_end(dev);
-       } else /* Powered off, use the saved value */
-               ret = dev_priv->saveBLC_PWM_CTL;
-
-       /* Top 15bits hold the frequency mask */
-       ret = (ret &  BACKLIGHT_MODULATION_FREQ_MASK) >>
-                                       BACKLIGHT_MODULATION_FREQ_SHIFT;
-
-        ret *= 2;      /* Return a 16bit range as needed for setting */
-        if (ret == 0)
-                dev_err(dev->dev, "BL bug: Reg %08x save %08X\n",
-                        REG_READ(BLC_PWM_CTL), dev_priv->saveBLC_PWM_CTL);
-       return ret;
-}
-
-/*
- * Set LVDS backlight level by I2C command
- *
- * FIXME: at some point we need to both track this for PM and also
- * disable runtime pm on MRST if the brightness is nil (ie blanked)
- */
-static int psb_lvds_i2c_set_brightness(struct drm_device *dev,
-                                       unsigned int level)
-{
-       struct drm_psb_private *dev_priv =
-               (struct drm_psb_private *)dev->dev_private;
-
-       struct psb_intel_i2c_chan *lvds_i2c_bus = dev_priv->lvds_i2c_bus;
-       u8 out_buf[2];
-       unsigned int blc_i2c_brightness;
-
-       struct i2c_msg msgs[] = {
-               {
-                       .addr = lvds_i2c_bus->slave_addr,
-                       .flags = 0,
-                       .len = 2,
-                       .buf = out_buf,
-               }
-       };
-
-       blc_i2c_brightness = BRIGHTNESS_MASK & ((unsigned int)level *
-                            BRIGHTNESS_MASK /
-                            BRIGHTNESS_MAX_LEVEL);
-
-       if (dev_priv->lvds_bl->pol == BLC_POLARITY_INVERSE)
-               blc_i2c_brightness = BRIGHTNESS_MASK - blc_i2c_brightness;
-
-       out_buf[0] = dev_priv->lvds_bl->brightnesscmd;
-       out_buf[1] = (u8)blc_i2c_brightness;
-
-       if (i2c_transfer(&lvds_i2c_bus->adapter, msgs, 1) == 1) {
-               dev_dbg(dev->dev, "I2C set brightness.(command, value) (%d, %d)\n",
-                       dev_priv->lvds_bl->brightnesscmd,
-                       blc_i2c_brightness);
-               return 0;
-       }
-
-       dev_err(dev->dev, "I2C transfer error\n");
-       return -1;
-}
-
-
-static int psb_lvds_pwm_set_brightness(struct drm_device *dev, int level)
-{
-       struct drm_psb_private *dev_priv =
-                       (struct drm_psb_private *)dev->dev_private;
-
-       u32 max_pwm_blc;
-       u32 blc_pwm_duty_cycle;
-
-       max_pwm_blc = psb_intel_lvds_get_max_backlight(dev);
-
-       /*BLC_PWM_CTL Should be initiated while backlight device init*/
-       BUG_ON(max_pwm_blc == 0);
-
-       blc_pwm_duty_cycle = level * max_pwm_blc / BRIGHTNESS_MAX_LEVEL;
-
-       if (dev_priv->lvds_bl->pol == BLC_POLARITY_INVERSE)
-               blc_pwm_duty_cycle = max_pwm_blc - blc_pwm_duty_cycle;
-
-       blc_pwm_duty_cycle &= PSB_BACKLIGHT_PWM_POLARITY_BIT_CLEAR;
-       REG_WRITE(BLC_PWM_CTL,
-                 (max_pwm_blc << PSB_BACKLIGHT_PWM_CTL_SHIFT) |
-                 (blc_pwm_duty_cycle));
-
-        dev_info(dev->dev, "Backlight lvds set brightness %08x\n",
-                 (max_pwm_blc << PSB_BACKLIGHT_PWM_CTL_SHIFT) |
-                 (blc_pwm_duty_cycle));
-
-       return 0;
-}
-
-/*
- * Set LVDS backlight level either by I2C or PWM
- */
-void psb_intel_lvds_set_brightness(struct drm_device *dev, int level)
-{
-       struct drm_psb_private *dev_priv = dev->dev_private;
-
-       dev_dbg(dev->dev, "backlight level is %d\n", level);
-
-       if (!dev_priv->lvds_bl) {
-               dev_err(dev->dev, "NO LVDS backlight info\n");
-               return;
-       }
-
-       if (dev_priv->lvds_bl->type == BLC_I2C_TYPE)
-               psb_lvds_i2c_set_brightness(dev, level);
-       else
-               psb_lvds_pwm_set_brightness(dev, level);
-}
-
-/*
- * Sets the backlight level.
- *
- * level: backlight level, from 0 to psb_intel_lvds_get_max_backlight().
- */
-static void psb_intel_lvds_set_backlight(struct drm_device *dev, int level)
-{
-       struct drm_psb_private *dev_priv = dev->dev_private;
-       u32 blc_pwm_ctl;
-
-       if (gma_power_begin(dev, false)) {
-               blc_pwm_ctl = REG_READ(BLC_PWM_CTL);
-               blc_pwm_ctl &= ~BACKLIGHT_DUTY_CYCLE_MASK;
-               REG_WRITE(BLC_PWM_CTL,
-                               (blc_pwm_ctl |
-                               (level << BACKLIGHT_DUTY_CYCLE_SHIFT)));
-               dev_priv->saveBLC_PWM_CTL = (blc_pwm_ctl |
-                                       (level << BACKLIGHT_DUTY_CYCLE_SHIFT));
-               gma_power_end(dev);
-       } else {
-               blc_pwm_ctl = dev_priv->saveBLC_PWM_CTL &
-                               ~BACKLIGHT_DUTY_CYCLE_MASK;
-               dev_priv->saveBLC_PWM_CTL = (blc_pwm_ctl |
-                                       (level << BACKLIGHT_DUTY_CYCLE_SHIFT));
-       }
-}
-
-/*
- * Sets the power state for the panel.
- */
-static void psb_intel_lvds_set_power(struct drm_device *dev,
-                                struct psb_intel_output *output, bool on)
-{
-       u32 pp_status;
-
-       if (!gma_power_begin(dev, true)) {
-               dev_err(dev->dev, "set power, chip off!\n");
-               return;
-        }
-        
-       if (on) {
-               REG_WRITE(PP_CONTROL, REG_READ(PP_CONTROL) |
-                         POWER_TARGET_ON);
-               do {
-                       pp_status = REG_READ(PP_STATUS);
-               } while ((pp_status & PP_ON) == 0);
-
-               psb_intel_lvds_set_backlight(dev,
-                                        output->
-                                        mode_dev->backlight_duty_cycle);
-       } else {
-               psb_intel_lvds_set_backlight(dev, 0);
-
-               REG_WRITE(PP_CONTROL, REG_READ(PP_CONTROL) &
-                         ~POWER_TARGET_ON);
-               do {
-                       pp_status = REG_READ(PP_STATUS);
-               } while (pp_status & PP_ON);
-       }
-
-       gma_power_end(dev);
-}
-
-static void psb_intel_lvds_encoder_dpms(struct drm_encoder *encoder, int mode)
-{
-       struct drm_device *dev = encoder->dev;
-       struct psb_intel_output *output = enc_to_psb_intel_output(encoder);
-
-       if (mode == DRM_MODE_DPMS_ON)
-               psb_intel_lvds_set_power(dev, output, true);
-       else
-               psb_intel_lvds_set_power(dev, output, false);
-
-       /* XXX: We never power down the LVDS pairs. */
-}
-
-static void psb_intel_lvds_save(struct drm_connector *connector)
-{
-       struct drm_device *dev = connector->dev;
-       struct drm_psb_private *dev_priv =
-               (struct drm_psb_private *)dev->dev_private;
-       struct psb_intel_output *psb_intel_output =
-               to_psb_intel_output(connector);
-       struct psb_intel_lvds_priv *lvds_priv =
-               (struct psb_intel_lvds_priv *)psb_intel_output->dev_priv;
-
-       lvds_priv->savePP_ON = REG_READ(LVDSPP_ON);
-       lvds_priv->savePP_OFF = REG_READ(LVDSPP_OFF);
-       lvds_priv->saveLVDS = REG_READ(LVDS);
-       lvds_priv->savePP_CONTROL = REG_READ(PP_CONTROL);
-       lvds_priv->savePP_CYCLE = REG_READ(PP_CYCLE);
-       /*lvds_priv->savePP_DIVISOR = REG_READ(PP_DIVISOR);*/
-       lvds_priv->saveBLC_PWM_CTL = REG_READ(BLC_PWM_CTL);
-       lvds_priv->savePFIT_CONTROL = REG_READ(PFIT_CONTROL);
-       lvds_priv->savePFIT_PGM_RATIOS = REG_READ(PFIT_PGM_RATIOS);
-
-       /*TODO: move backlight_duty_cycle to psb_intel_lvds_priv*/
-       dev_priv->backlight_duty_cycle = (dev_priv->saveBLC_PWM_CTL &
-                                               BACKLIGHT_DUTY_CYCLE_MASK);
-
-       /*
-        * If the light is off at server startup,
-        * just make it full brightness
-        */
-       if (dev_priv->backlight_duty_cycle == 0)
-               dev_priv->backlight_duty_cycle =
-               psb_intel_lvds_get_max_backlight(dev);
-
-       dev_dbg(dev->dev, "(0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x)\n",
-                       lvds_priv->savePP_ON,
-                       lvds_priv->savePP_OFF,
-                       lvds_priv->saveLVDS,
-                       lvds_priv->savePP_CONTROL,
-                       lvds_priv->savePP_CYCLE,
-                       lvds_priv->saveBLC_PWM_CTL);
-}
-
-static void psb_intel_lvds_restore(struct drm_connector *connector)
-{
-       struct drm_device *dev = connector->dev;
-       u32 pp_status;
-       struct psb_intel_output *psb_intel_output =
-                                       to_psb_intel_output(connector);
-       struct psb_intel_lvds_priv *lvds_priv =
-               (struct psb_intel_lvds_priv *)psb_intel_output->dev_priv;
-
-       dev_dbg(dev->dev, "(0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x)\n",
-                       lvds_priv->savePP_ON,
-                       lvds_priv->savePP_OFF,
-                       lvds_priv->saveLVDS,
-                       lvds_priv->savePP_CONTROL,
-                       lvds_priv->savePP_CYCLE,
-                       lvds_priv->saveBLC_PWM_CTL);
-
-       REG_WRITE(BLC_PWM_CTL, lvds_priv->saveBLC_PWM_CTL);
-       REG_WRITE(PFIT_CONTROL, lvds_priv->savePFIT_CONTROL);
-       REG_WRITE(PFIT_PGM_RATIOS, lvds_priv->savePFIT_PGM_RATIOS);
-       REG_WRITE(LVDSPP_ON, lvds_priv->savePP_ON);
-       REG_WRITE(LVDSPP_OFF, lvds_priv->savePP_OFF);
-       /*REG_WRITE(PP_DIVISOR, lvds_priv->savePP_DIVISOR);*/
-       REG_WRITE(PP_CYCLE, lvds_priv->savePP_CYCLE);
-       REG_WRITE(PP_CONTROL, lvds_priv->savePP_CONTROL);
-       REG_WRITE(LVDS, lvds_priv->saveLVDS);
-
-       if (lvds_priv->savePP_CONTROL & POWER_TARGET_ON) {
-               REG_WRITE(PP_CONTROL, REG_READ(PP_CONTROL) |
-                       POWER_TARGET_ON);
-               do {
-                       pp_status = REG_READ(PP_STATUS);
-               } while ((pp_status & PP_ON) == 0);
-       } else {
-               REG_WRITE(PP_CONTROL, REG_READ(PP_CONTROL) &
-                       ~POWER_TARGET_ON);
-               do {
-                       pp_status = REG_READ(PP_STATUS);
-               } while (pp_status & PP_ON);
-       }
-}
-
-int psb_intel_lvds_mode_valid(struct drm_connector *connector,
-                                struct drm_display_mode *mode)
-{
-       struct psb_intel_output *psb_intel_output =
-                               to_psb_intel_output(connector);
-       struct drm_display_mode *fixed_mode =
-           psb_intel_output->mode_dev->panel_fixed_mode;
-
-       if (psb_intel_output->type == INTEL_OUTPUT_MIPI2)
-               fixed_mode = psb_intel_output->mode_dev->panel_fixed_mode2;
-
-       /* just in case */
-       if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
-               return MODE_NO_DBLESCAN;
-
-       /* just in case */
-       if (mode->flags & DRM_MODE_FLAG_INTERLACE)
-               return MODE_NO_INTERLACE;
-
-       if (fixed_mode) {
-               if (mode->hdisplay > fixed_mode->hdisplay)
-                       return MODE_PANEL;
-               if (mode->vdisplay > fixed_mode->vdisplay)
-                       return MODE_PANEL;
-       }
-       return MODE_OK;
-}
-
-bool psb_intel_lvds_mode_fixup(struct drm_encoder *encoder,
-                                 struct drm_display_mode *mode,
-                                 struct drm_display_mode *adjusted_mode)
-{
-       struct psb_intel_mode_device *mode_dev =
-           enc_to_psb_intel_output(encoder)->mode_dev;
-       struct drm_device *dev = encoder->dev;
-       struct psb_intel_crtc *psb_intel_crtc =
-                               to_psb_intel_crtc(encoder->crtc);
-       struct drm_encoder *tmp_encoder;
-       struct drm_display_mode *panel_fixed_mode = mode_dev->panel_fixed_mode;
-       struct psb_intel_output *psb_intel_output =
-                                       enc_to_psb_intel_output(encoder);
-
-       if (psb_intel_output->type == INTEL_OUTPUT_MIPI2)
-               panel_fixed_mode = mode_dev->panel_fixed_mode2;
-
-       /* PSB requires the LVDS is on pipe B, MRST has only one pipe anyway */
-       if (!IS_MRST(dev) && psb_intel_crtc->pipe == 0) {
-               printk(KERN_ERR "Can't support LVDS on pipe A\n");
-               return false;
-       }
-       if (IS_MRST(dev) && psb_intel_crtc->pipe != 0) {
-               printk(KERN_ERR "Must use PIPE A\n");
-               return false;
-       }
-       /* Should never happen!! */
-       list_for_each_entry(tmp_encoder, &dev->mode_config.encoder_list,
-                           head) {
-               if (tmp_encoder != encoder
-                   && tmp_encoder->crtc == encoder->crtc) {
-                       printk(KERN_ERR "Can't enable LVDS and another "
-                              "encoder on the same pipe\n");
-                       return false;
-               }
-       }
-
-       /*
-        * If we have timings from the BIOS for the panel, put them in
-        * to the adjusted mode.  The CRTC will be set up for this mode,
-        * with the panel scaling set up to source from the H/VDisplay
-        * of the original mode.
-        */
-       if (panel_fixed_mode != NULL) {
-               adjusted_mode->hdisplay = panel_fixed_mode->hdisplay;
-               adjusted_mode->hsync_start = panel_fixed_mode->hsync_start;
-               adjusted_mode->hsync_end = panel_fixed_mode->hsync_end;
-               adjusted_mode->htotal = panel_fixed_mode->htotal;
-               adjusted_mode->vdisplay = panel_fixed_mode->vdisplay;
-               adjusted_mode->vsync_start = panel_fixed_mode->vsync_start;
-               adjusted_mode->vsync_end = panel_fixed_mode->vsync_end;
-               adjusted_mode->vtotal = panel_fixed_mode->vtotal;
-               adjusted_mode->clock = panel_fixed_mode->clock;
-               drm_mode_set_crtcinfo(adjusted_mode,
-                                     CRTC_INTERLACE_HALVE_V);
-       }
-
-       /*
-        * XXX: It would be nice to support lower refresh rates on the
-        * panels to reduce power consumption, and perhaps match the
-        * user's requested refresh rate.
-        */
-
-       return true;
-}
-
-static void psb_intel_lvds_prepare(struct drm_encoder *encoder)
-{
-       struct drm_device *dev = encoder->dev;
-       struct psb_intel_output *output = enc_to_psb_intel_output(encoder);
-       struct psb_intel_mode_device *mode_dev = output->mode_dev;
-
-       if (!gma_power_begin(dev, true))
-               return;
-
-       mode_dev->saveBLC_PWM_CTL = REG_READ(BLC_PWM_CTL);
-       mode_dev->backlight_duty_cycle = (mode_dev->saveBLC_PWM_CTL &
-                                         BACKLIGHT_DUTY_CYCLE_MASK);
-
-       psb_intel_lvds_set_power(dev, output, false);
-
-       gma_power_end(dev);
-}
-
-static void psb_intel_lvds_commit(struct drm_encoder *encoder)
-{
-       struct drm_device *dev = encoder->dev;
-       struct psb_intel_output *output = enc_to_psb_intel_output(encoder);
-       struct psb_intel_mode_device *mode_dev = output->mode_dev;
-
-       if (mode_dev->backlight_duty_cycle == 0)
-               mode_dev->backlight_duty_cycle =
-                   psb_intel_lvds_get_max_backlight(dev);
-
-       psb_intel_lvds_set_power(dev, output, true);
-}
-
-static void psb_intel_lvds_mode_set(struct drm_encoder *encoder,
-                               struct drm_display_mode *mode,
-                               struct drm_display_mode *adjusted_mode)
-{
-       struct drm_device *dev = encoder->dev;
-       struct drm_psb_private *dev_priv = dev->dev_private;
-       u32 pfit_control;
-
-       /*
-        * The LVDS pin pair will already have been turned on in the
-        * psb_intel_crtc_mode_set since it has a large impact on the DPLL
-        * settings.
-        */
-
-       /*
-        * Enable automatic panel scaling so that non-native modes fill the
-        * screen.  Should be enabled before the pipe is enabled, according to
-        * register description and PRM.
-        */
-       if (mode->hdisplay != adjusted_mode->hdisplay ||
-           mode->vdisplay != adjusted_mode->vdisplay)
-               pfit_control = (PFIT_ENABLE | VERT_AUTO_SCALE |
-                               HORIZ_AUTO_SCALE | VERT_INTERP_BILINEAR |
-                               HORIZ_INTERP_BILINEAR);
-       else
-               pfit_control = 0;
-
-       if (dev_priv->lvds_dither)
-               pfit_control |= PANEL_8TO6_DITHER_ENABLE;
-
-       REG_WRITE(PFIT_CONTROL, pfit_control);
-}
-
-/*
- * Detect the LVDS connection.
- *
- * This always returns CONNECTOR_STATUS_CONNECTED.
- * This connector should only have
- * been set up if the LVDS was actually connected anyway.
- */
-static enum drm_connector_status psb_intel_lvds_detect(struct drm_connector
-                                                  *connector, bool force)
-{
-       return connector_status_connected;
-}
-
-/*
- * Return the list of DDC modes if available, or the BIOS fixed mode otherwise.
- */
-static int psb_intel_lvds_get_modes(struct drm_connector *connector)
-{
-       struct drm_device *dev = connector->dev;
-       struct psb_intel_output *psb_intel_output =
-                                       to_psb_intel_output(connector);
-       struct psb_intel_mode_device *mode_dev =
-                                       psb_intel_output->mode_dev;
-       int ret = 0;
-
-       if (!IS_MRST(dev))
-               ret = psb_intel_ddc_get_modes(psb_intel_output);
-
-       if (ret)
-               return ret;
-
-       /* Didn't get an EDID, so
-        * Set wide sync ranges so we get all modes
-        * handed to valid_mode for checking
-        */
-       connector->display_info.min_vfreq = 0;
-       connector->display_info.max_vfreq = 200;
-       connector->display_info.min_hfreq = 0;
-       connector->display_info.max_hfreq = 200;
-
-       if (mode_dev->panel_fixed_mode != NULL) {
-               struct drm_display_mode *mode =
-                   drm_mode_duplicate(dev, mode_dev->panel_fixed_mode);
-               drm_mode_probed_add(connector, mode);
-               return 1;
-       }
-
-       return 0;
-}
-
-/**
- * psb_intel_lvds_destroy - unregister and free LVDS structures
- * @connector: connector to free
- *
- * Unregister the DDC bus for this connector then free the driver private
- * structure.
- */
-void psb_intel_lvds_destroy(struct drm_connector *connector)
-{
-       struct psb_intel_output *psb_intel_output =
-                                       to_psb_intel_output(connector);
-
-       if (psb_intel_output->ddc_bus)
-               psb_intel_i2c_destroy(psb_intel_output->ddc_bus);
-       drm_sysfs_connector_remove(connector);
-       drm_connector_cleanup(connector);
-       kfree(connector);
-}
-
-int psb_intel_lvds_set_property(struct drm_connector *connector,
-                                      struct drm_property *property,
-                                      uint64_t value)
-{
-       struct drm_encoder *encoder = connector->encoder;
-
-       if (!encoder)
-               return -1;
-
-       if (!strcmp(property->name, "scaling mode")) {
-               struct psb_intel_crtc *crtc =
-                                       to_psb_intel_crtc(encoder->crtc);
-               uint64_t curval;
-
-               if (!crtc)
-                       goto set_prop_error;
-
-               switch (value) {
-               case DRM_MODE_SCALE_FULLSCREEN:
-                       break;
-               case DRM_MODE_SCALE_NO_SCALE:
-                       break;
-               case DRM_MODE_SCALE_ASPECT:
-                       break;
-               default:
-                       goto set_prop_error;
-               }
-
-               if (drm_connector_property_get_value(connector,
-                                                    property,
-                                                    &curval))
-                       goto set_prop_error;
-
-               if (curval == value)
-                       goto set_prop_done;
-
-               if (drm_connector_property_set_value(connector,
-                                                       property,
-                                                       value))
-                       goto set_prop_error;
-
-               if (crtc->saved_mode.hdisplay != 0 &&
-                   crtc->saved_mode.vdisplay != 0) {
-                       if (!drm_crtc_helper_set_mode(encoder->crtc,
-                                                     &crtc->saved_mode,
-                                                     encoder->crtc->x,
-                                                     encoder->crtc->y,
-                                                     encoder->crtc->fb))
-                               goto set_prop_error;
-               }
-       } else if (!strcmp(property->name, "backlight")) {
-               if (drm_connector_property_set_value(connector,
-                                                       property,
-                                                       value))
-                       goto set_prop_error;
-               else {
-#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
-                       struct drm_psb_private *devp =
-                                               encoder->dev->dev_private;
-                       struct backlight_device *bd = devp->backlight_device;
-                       if (bd) {
-                               bd->props.brightness = value;
-                               backlight_update_status(bd);
-                       }
-#endif
-               }
-       } else if (!strcmp(property->name, "DPMS")) {
-               struct drm_encoder_helper_funcs *hfuncs
-                                               = encoder->helper_private;
-               hfuncs->dpms(encoder, value);
-       }
-
-set_prop_done:
-       return 0;
-set_prop_error:
-       return -1;
-}
-
-static const struct drm_encoder_helper_funcs psb_intel_lvds_helper_funcs = {
-       .dpms = psb_intel_lvds_encoder_dpms,
-       .mode_fixup = psb_intel_lvds_mode_fixup,
-       .prepare = psb_intel_lvds_prepare,
-       .mode_set = psb_intel_lvds_mode_set,
-       .commit = psb_intel_lvds_commit,
-};
-
-const struct drm_connector_helper_funcs
-                               psb_intel_lvds_connector_helper_funcs = {
-       .get_modes = psb_intel_lvds_get_modes,
-       .mode_valid = psb_intel_lvds_mode_valid,
-       .best_encoder = psb_intel_best_encoder,
-};
-
-const struct drm_connector_funcs psb_intel_lvds_connector_funcs = {
-       .dpms = drm_helper_connector_dpms,
-       .save = psb_intel_lvds_save,
-       .restore = psb_intel_lvds_restore,
-       .detect = psb_intel_lvds_detect,
-       .fill_modes = drm_helper_probe_single_connector_modes,
-       .set_property = psb_intel_lvds_set_property,
-       .destroy = psb_intel_lvds_destroy,
-};
-
-
-static void psb_intel_lvds_enc_destroy(struct drm_encoder *encoder)
-{
-       drm_encoder_cleanup(encoder);
-}
-
-const struct drm_encoder_funcs psb_intel_lvds_enc_funcs = {
-       .destroy = psb_intel_lvds_enc_destroy,
-};
-
-
-
-/**
- * psb_intel_lvds_init - setup LVDS connectors on this device
- * @dev: drm device
- *
- * Create the connector, register the LVDS DDC bus, and try to figure out what
- * modes we can display on the LVDS panel (if present).
- */
-void psb_intel_lvds_init(struct drm_device *dev,
-                    struct psb_intel_mode_device *mode_dev)
-{
-       struct psb_intel_output *psb_intel_output;
-       struct psb_intel_lvds_priv *lvds_priv;
-       struct drm_connector *connector;
-       struct drm_encoder *encoder;
-       struct drm_display_mode *scan;  /* *modes, *bios_mode; */
-       struct drm_crtc *crtc;
-       struct drm_psb_private *dev_priv = dev->dev_private;
-       u32 lvds;
-       int pipe;
-
-       psb_intel_output = kzalloc(sizeof(struct psb_intel_output), GFP_KERNEL);
-       if (!psb_intel_output)
-               return;
-
-       lvds_priv = kzalloc(sizeof(struct psb_intel_lvds_priv), GFP_KERNEL);
-       if (!lvds_priv) {
-               kfree(psb_intel_output);
-               dev_err(dev->dev, "LVDS private allocation error\n");
-               return;
-       }
-
-       psb_intel_output->dev_priv = lvds_priv;
-       psb_intel_output->mode_dev = mode_dev;
-
-       connector = &psb_intel_output->base;
-       encoder = &psb_intel_output->enc;
-       drm_connector_init(dev, &psb_intel_output->base,
-                          &psb_intel_lvds_connector_funcs,
-                          DRM_MODE_CONNECTOR_LVDS);
-
-       drm_encoder_init(dev, &psb_intel_output->enc,
-                        &psb_intel_lvds_enc_funcs,
-                        DRM_MODE_ENCODER_LVDS);
-
-       drm_mode_connector_attach_encoder(&psb_intel_output->base,
-                                         &psb_intel_output->enc);
-       psb_intel_output->type = INTEL_OUTPUT_LVDS;
-
-       drm_encoder_helper_add(encoder, &psb_intel_lvds_helper_funcs);
-       drm_connector_helper_add(connector,
-                                &psb_intel_lvds_connector_helper_funcs);
-       connector->display_info.subpixel_order = SubPixelHorizontalRGB;
-       connector->interlace_allowed = false;
-       connector->doublescan_allowed = false;
-
-       /*Attach connector properties*/
-       drm_connector_attach_property(connector,
-                                     dev->mode_config.scaling_mode_property,
-                                     DRM_MODE_SCALE_FULLSCREEN);
-       drm_connector_attach_property(connector,
-                                     dev_priv->backlight_property,
-                                     BRIGHTNESS_MAX_LEVEL);
-
-       /*
-        * Set up I2C bus
-        * FIXME: distroy i2c_bus when exit
-        */
-       psb_intel_output->i2c_bus = psb_intel_i2c_create(dev,
-                                                        GPIOB,
-                                                        "LVDSBLC_B");
-       if (!psb_intel_output->i2c_bus) {
-               dev_printk(KERN_ERR,
-                       &dev->pdev->dev, "I2C bus registration failed.\n");
-               goto failed_blc_i2c;
-       }
-       psb_intel_output->i2c_bus->slave_addr = 0x2C;
-       dev_priv->lvds_i2c_bus =  psb_intel_output->i2c_bus;
-
-       /*
-        * LVDS discovery:
-        * 1) check for EDID on DDC
-        * 2) check for VBT data
-        * 3) check to see if LVDS is already on
-        *    if none of the above, no panel
-        * 4) make sure lid is open
-        *    if closed, act like it's not there for now
-        */
-
-       /* Set up the DDC bus. */
-       psb_intel_output->ddc_bus = psb_intel_i2c_create(dev,
-                                                        GPIOC,
-                                                        "LVDSDDC_C");
-       if (!psb_intel_output->ddc_bus) {
-               dev_printk(KERN_ERR, &dev->pdev->dev,
-                          "DDC bus registration " "failed.\n");
-               goto failed_ddc;
-       }
-
-       /*
-        * Attempt to get the fixed panel mode from DDC.  Assume that the
-        * preferred mode is the right one.
-        */
-       psb_intel_ddc_get_modes(psb_intel_output);
-       list_for_each_entry(scan, &connector->probed_modes, head) {
-               if (scan->type & DRM_MODE_TYPE_PREFERRED) {
-                       mode_dev->panel_fixed_mode =
-                           drm_mode_duplicate(dev, scan);
-                       goto out;       /* FIXME: check for quirks */
-               }
-       }
-
-       /* Failed to get EDID, what about VBT? do we need this? */
-       if (mode_dev->vbt_mode)
-               mode_dev->panel_fixed_mode =
-                   drm_mode_duplicate(dev, mode_dev->vbt_mode);
-
-       if (!mode_dev->panel_fixed_mode)
-               if (dev_priv->lfp_lvds_vbt_mode)
-                       mode_dev->panel_fixed_mode =
-                               drm_mode_duplicate(dev,
-                                       dev_priv->lfp_lvds_vbt_mode);
-
-       /*
-        * If we didn't get EDID, try checking if the panel is already turned
-        * on.  If so, assume that whatever is currently programmed is the
-        * correct mode.
-        */
-       lvds = REG_READ(LVDS);
-       pipe = (lvds & LVDS_PIPEB_SELECT) ? 1 : 0;
-       crtc = psb_intel_get_crtc_from_pipe(dev, pipe);
-
-       if (crtc && (lvds & LVDS_PORT_EN)) {
-               mode_dev->panel_fixed_mode =
-                   psb_intel_crtc_mode_get(dev, crtc);
-               if (mode_dev->panel_fixed_mode) {
-                       mode_dev->panel_fixed_mode->type |=
-                           DRM_MODE_TYPE_PREFERRED;
-                       goto out;       /* FIXME: check for quirks */
-               }
-       }
-
-       /* If we still don't have a mode after all that, give up. */
-       if (!mode_dev->panel_fixed_mode) {
-               dev_err(dev->dev, "Found no modes on the lvds, ignoring the LVDS\n");
-               goto failed_find;
-       }
-
-       /*
-        * Blacklist machines with BIOSes that list an LVDS panel without
-        * actually having one.
-        */
-out:
-       drm_sysfs_connector_add(connector);
-       return;
-
-failed_find:
-       if (psb_intel_output->ddc_bus)
-               psb_intel_i2c_destroy(psb_intel_output->ddc_bus);
-failed_ddc:
-       if (psb_intel_output->i2c_bus)
-               psb_intel_i2c_destroy(psb_intel_output->i2c_bus);
-failed_blc_i2c:
-       drm_encoder_cleanup(encoder);
-       drm_connector_cleanup(connector);
-       kfree(connector);
-}
-
diff --git a/drivers/staging/gma500/psb_intel_modes.c b/drivers/staging/gma500/psb_intel_modes.c
deleted file mode 100644 (file)
index bde1aff..0000000
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright (c) 2007 Intel Corporation
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Authers: Jesse Barnes <jesse.barnes@intel.com>
- */
-
-#include <linux/i2c.h>
-#include <linux/fb.h>
-#include <drm/drmP.h>
-#include "psb_intel_drv.h"
-
-/**
- * psb_intel_ddc_probe
- *
- */
-bool psb_intel_ddc_probe(struct psb_intel_output *psb_intel_output)
-{
-       u8 out_buf[] = { 0x0, 0x0 };
-       u8 buf[2];
-       int ret;
-       struct i2c_msg msgs[] = {
-               {
-                .addr = 0x50,
-                .flags = 0,
-                .len = 1,
-                .buf = out_buf,
-                },
-               {
-                .addr = 0x50,
-                .flags = I2C_M_RD,
-                .len = 1,
-                .buf = buf,
-                }
-       };
-
-       ret = i2c_transfer(&psb_intel_output->ddc_bus->adapter, msgs, 2);
-       if (ret == 2)
-               return true;
-
-       return false;
-}
-
-/**
- * psb_intel_ddc_get_modes - get modelist from monitor
- * @connector: DRM connector device to use
- *
- * Fetch the EDID information from @connector using the DDC bus.
- */
-int psb_intel_ddc_get_modes(struct psb_intel_output *psb_intel_output)
-{
-       struct edid *edid;
-       int ret = 0;
-
-       edid =
-           drm_get_edid(&psb_intel_output->base,
-                        &psb_intel_output->ddc_bus->adapter);
-       if (edid) {
-               drm_mode_connector_update_edid_property(&psb_intel_output->
-                                                       base, edid);
-               ret = drm_add_edid_modes(&psb_intel_output->base, edid);
-               kfree(edid);
-       }
-       return ret;
-}
diff --git a/drivers/staging/gma500/psb_intel_reg.h b/drivers/staging/gma500/psb_intel_reg.h
deleted file mode 100644 (file)
index 1ac16aa..0000000
+++ /dev/null
@@ -1,1235 +0,0 @@
-/*
- * Copyright (c) 2009, Intel Corporation.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- */
-#ifndef __PSB_INTEL_REG_H__
-#define __PSB_INTEL_REG_H__
-
-#define BLC_PWM_CTL            0x61254
-#define BLC_PWM_CTL2           0x61250
-#define BLC_PWM_CTL_C          0x62254
-#define BLC_PWM_CTL2_C         0x62250
-#define BACKLIGHT_MODULATION_FREQ_SHIFT                (17)
-/*
- * This is the most significant 15 bits of the number of backlight cycles in a
- * complete cycle of the modulated backlight control.
- *
- * The actual value is this field multiplied by two.
- */
-#define BACKLIGHT_MODULATION_FREQ_MASK (0x7fff << 17)
-#define BLM_LEGACY_MODE                        (1 << 16)
-/*
- * This is the number of cycles out of the backlight modulation cycle for which
- * the backlight is on.
- *
- * This field must be no greater than the number of cycles in the complete
- * backlight modulation cycle.
- */
-#define BACKLIGHT_DUTY_CYCLE_SHIFT     (0)
-#define BACKLIGHT_DUTY_CYCLE_MASK      (0xffff)
-
-#define I915_GCFGC                     0xf0
-#define I915_LOW_FREQUENCY_ENABLE      (1 << 7)
-#define I915_DISPLAY_CLOCK_190_200_MHZ (0 << 4)
-#define I915_DISPLAY_CLOCK_333_MHZ     (4 << 4)
-#define I915_DISPLAY_CLOCK_MASK                (7 << 4)
-
-#define I855_HPLLCC                    0xc0
-#define I855_CLOCK_CONTROL_MASK                (3 << 0)
-#define I855_CLOCK_133_200             (0 << 0)
-#define I855_CLOCK_100_200             (1 << 0)
-#define I855_CLOCK_100_133             (2 << 0)
-#define I855_CLOCK_166_250             (3 << 0)
-
-/* I830 CRTC registers */
-#define HTOTAL_A               0x60000
-#define HBLANK_A               0x60004
-#define HSYNC_A                        0x60008
-#define VTOTAL_A               0x6000c
-#define VBLANK_A               0x60010
-#define VSYNC_A                        0x60014
-#define PIPEASRC               0x6001c
-#define BCLRPAT_A              0x60020
-#define VSYNCSHIFT_A           0x60028
-
-#define HTOTAL_B               0x61000
-#define HBLANK_B               0x61004
-#define HSYNC_B                        0x61008
-#define VTOTAL_B               0x6100c
-#define VBLANK_B               0x61010
-#define VSYNC_B                        0x61014
-#define PIPEBSRC               0x6101c
-#define BCLRPAT_B              0x61020
-#define VSYNCSHIFT_B           0x61028
-
-#define HTOTAL_C               0x62000
-#define HBLANK_C               0x62004
-#define HSYNC_C                        0x62008
-#define VTOTAL_C               0x6200c
-#define VBLANK_C               0x62010
-#define VSYNC_C                        0x62014
-#define PIPECSRC               0x6201c
-#define BCLRPAT_C              0x62020
-#define VSYNCSHIFT_C           0x62028
-
-#define PP_STATUS              0x61200
-# define PP_ON                         (1 << 31)
-/*
- * Indicates that all dependencies of the panel are on:
- *
- * - PLL enabled
- * - pipe enabled
- * - LVDS/DVOB/DVOC on
- */
-#define PP_READY                       (1 << 30)
-#define PP_SEQUENCE_NONE               (0 << 28)
-#define PP_SEQUENCE_ON                 (1 << 28)
-#define PP_SEQUENCE_OFF                        (2 << 28)
-#define PP_SEQUENCE_MASK               0x30000000
-#define PP_CONTROL             0x61204
-#define POWER_TARGET_ON                        (1 << 0)
-
-#define LVDSPP_ON              0x61208
-#define LVDSPP_OFF             0x6120c
-#define PP_CYCLE               0x61210
-
-#define PFIT_CONTROL           0x61230
-#define PFIT_ENABLE                    (1 << 31)
-#define PFIT_PIPE_MASK                 (3 << 29)
-#define PFIT_PIPE_SHIFT                        29
-#define PFIT_SCALING_MODE_PILLARBOX    (1 << 27)
-#define PFIT_SCALING_MODE_LETTERBOX    (3 << 26)
-#define VERT_INTERP_DISABLE            (0 << 10)
-#define VERT_INTERP_BILINEAR           (1 << 10)
-#define VERT_INTERP_MASK               (3 << 10)
-#define VERT_AUTO_SCALE                        (1 << 9)
-#define HORIZ_INTERP_DISABLE           (0 << 6)
-#define HORIZ_INTERP_BILINEAR          (1 << 6)
-#define HORIZ_INTERP_MASK              (3 << 6)
-#define HORIZ_AUTO_SCALE               (1 << 5)
-#define PANEL_8TO6_DITHER_ENABLE       (1 << 3)
-
-#define PFIT_PGM_RATIOS                0x61234
-#define PFIT_VERT_SCALE_MASK                   0xfff00000
-#define PFIT_HORIZ_SCALE_MASK                  0x0000fff0
-
-#define PFIT_AUTO_RATIOS       0x61238
-
-#define DPLL_A                 0x06014
-#define DPLL_B                 0x06018
-#define DPLL_VCO_ENABLE                        (1 << 31)
-#define DPLL_DVO_HIGH_SPEED            (1 << 30)
-#define DPLL_SYNCLOCK_ENABLE           (1 << 29)
-#define DPLL_VGA_MODE_DIS              (1 << 28)
-#define DPLLB_MODE_DAC_SERIAL          (1 << 26)       /* i915 */
-#define DPLLB_MODE_LVDS                        (2 << 26)       /* i915 */
-#define DPLL_MODE_MASK                 (3 << 26)
-#define DPLL_DAC_SERIAL_P2_CLOCK_DIV_10        (0 << 24)       /* i915 */
-#define DPLL_DAC_SERIAL_P2_CLOCK_DIV_5 (1 << 24)       /* i915 */
-#define DPLLB_LVDS_P2_CLOCK_DIV_14     (0 << 24)       /* i915 */
-#define DPLLB_LVDS_P2_CLOCK_DIV_7      (1 << 24)       /* i915 */
-#define DPLL_P2_CLOCK_DIV_MASK         0x03000000      /* i915 */
-#define DPLL_FPA01_P1_POST_DIV_MASK    0x00ff0000      /* i915 */
-#define DPLL_LOCK                      (1 << 15)       /* CDV */
-
-/*
- *  The i830 generation, in DAC/serial mode, defines p1 as two plus this
- * bitfield, or just 2 if PLL_P1_DIVIDE_BY_TWO is set.
- */
-# define DPLL_FPA01_P1_POST_DIV_MASK_I830      0x001f0000
-/*
- * The i830 generation, in LVDS mode, defines P1 as the bit number set within
- * this field (only one bit may be set).
- */
-#define DPLL_FPA01_P1_POST_DIV_MASK_I830_LVDS  0x003f0000
-#define DPLL_FPA01_P1_POST_DIV_SHIFT   16
-#define PLL_P2_DIVIDE_BY_4             (1 << 23)       /* i830, required
-                                                        * in DVO non-gang */
-# define PLL_P1_DIVIDE_BY_TWO          (1 << 21)       /* i830 */
-#define PLL_REF_INPUT_DREFCLK          (0 << 13)
-#define PLL_REF_INPUT_TVCLKINA         (1 << 13)       /* i830 */
-#define PLL_REF_INPUT_TVCLKINBC                (2 << 13)       /* SDVO
-                                                                * TVCLKIN */
-#define PLLB_REF_INPUT_SPREADSPECTRUMIN        (3 << 13)
-#define PLL_REF_INPUT_MASK             (3 << 13)
-#define PLL_LOAD_PULSE_PHASE_SHIFT     9
-/*
- * Parallel to Serial Load Pulse phase selection.
- * Selects the phase for the 10X DPLL clock for the PCIe
- * digital display port. The range is 4 to 13; 10 or more
- * is just a flip delay. The default is 6
- */
-#define PLL_LOAD_PULSE_PHASE_MASK      (0xf << PLL_LOAD_PULSE_PHASE_SHIFT)
-#define DISPLAY_RATE_SELECT_FPA1       (1 << 8)
-
-/*
- * SDVO multiplier for 945G/GM. Not used on 965.
- *
- * DPLL_MD_UDI_MULTIPLIER_MASK
- */
-#define SDVO_MULTIPLIER_MASK           0x000000ff
-#define SDVO_MULTIPLIER_SHIFT_HIRES    4
-#define SDVO_MULTIPLIER_SHIFT_VGA      0
-
-/*
- * PLL_MD
- */
-/* Pipe A SDVO/UDI clock multiplier/divider register for G965. */
-#define DPLL_A_MD              0x0601c
-/* Pipe B SDVO/UDI clock multiplier/divider register for G965. */
-#define DPLL_B_MD              0x06020
-/*
- * UDI pixel divider, controlling how many pixels are stuffed into a packet.
- *
- * Value is pixels minus 1.  Must be set to 1 pixel for SDVO.
- */
-#define DPLL_MD_UDI_DIVIDER_MASK       0x3f000000
-#define DPLL_MD_UDI_DIVIDER_SHIFT      24
-/* UDI pixel divider for VGA, same as DPLL_MD_UDI_DIVIDER_MASK. */
-#define DPLL_MD_VGA_UDI_DIVIDER_MASK   0x003f0000
-#define DPLL_MD_VGA_UDI_DIVIDER_SHIFT  16
-/*
- * SDVO/UDI pixel multiplier.
- *
- * SDVO requires that the bus clock rate be between 1 and 2 Ghz, and the bus
- * clock rate is 10 times the DPLL clock.  At low resolution/refresh rate
- * modes, the bus rate would be below the limits, so SDVO allows for stuffing
- * dummy bytes in the datastream at an increased clock rate, with both sides of
- * the link knowing how many bytes are fill.
- *
- * So, for a mode with a dotclock of 65Mhz, we would want to double the clock
- * rate to 130Mhz to get a bus rate of 1.30Ghz.  The DPLL clock rate would be
- * set to 130Mhz, and the SDVO multiplier set to 2x in this register and
- * through an SDVO command.
- *
- * This register field has values of multiplication factor minus 1, with
- * a maximum multiplier of 5 for SDVO.
- */
-#define DPLL_MD_UDI_MULTIPLIER_MASK    0x00003f00
-#define DPLL_MD_UDI_MULTIPLIER_SHIFT   8
-/*
- * SDVO/UDI pixel multiplier for VGA, same as DPLL_MD_UDI_MULTIPLIER_MASK.
- * This best be set to the default value (3) or the CRT won't work. No,
- * I don't entirely understand what this does...
- */
-#define DPLL_MD_VGA_UDI_MULTIPLIER_MASK        0x0000003f
-#define DPLL_MD_VGA_UDI_MULTIPLIER_SHIFT 0
-
-#define DPLL_TEST              0x606c
-#define DPLLB_TEST_SDVO_DIV_1          (0 << 22)
-#define DPLLB_TEST_SDVO_DIV_2          (1 << 22)
-#define DPLLB_TEST_SDVO_DIV_4          (2 << 22)
-#define DPLLB_TEST_SDVO_DIV_MASK       (3 << 22)
-#define DPLLB_TEST_N_BYPASS            (1 << 19)
-#define DPLLB_TEST_M_BYPASS            (1 << 18)
-#define DPLLB_INPUT_BUFFER_ENABLE      (1 << 16)
-#define DPLLA_TEST_N_BYPASS            (1 << 3)
-#define DPLLA_TEST_M_BYPASS            (1 << 2)
-#define DPLLA_INPUT_BUFFER_ENABLE      (1 << 0)
-
-#define ADPA                   0x61100
-#define ADPA_DAC_ENABLE                        (1 << 31)
-#define ADPA_DAC_DISABLE               0
-#define ADPA_PIPE_SELECT_MASK          (1 << 30)
-#define ADPA_PIPE_A_SELECT             0
-#define ADPA_PIPE_B_SELECT             (1 << 30)
-#define ADPA_USE_VGA_HVPOLARITY                (1 << 15)
-#define ADPA_SETS_HVPOLARITY           0
-#define ADPA_VSYNC_CNTL_DISABLE                (1 << 11)
-#define ADPA_VSYNC_CNTL_ENABLE         0
-#define ADPA_HSYNC_CNTL_DISABLE                (1 << 10)
-#define ADPA_HSYNC_CNTL_ENABLE         0
-#define ADPA_VSYNC_ACTIVE_HIGH         (1 << 4)
-#define ADPA_VSYNC_ACTIVE_LOW          0
-#define ADPA_HSYNC_ACTIVE_HIGH         (1 << 3)
-#define ADPA_HSYNC_ACTIVE_LOW          0
-
-#define FPA0                   0x06040
-#define FPA1                   0x06044
-#define FPB0                   0x06048
-#define FPB1                   0x0604c
-#define FP_N_DIV_MASK                  0x003f0000
-#define FP_N_DIV_SHIFT                 16
-#define FP_M1_DIV_MASK                 0x00003f00
-#define FP_M1_DIV_SHIFT                        8
-#define FP_M2_DIV_MASK                 0x0000003f
-#define FP_M2_DIV_SHIFT                        0
-
-#define PORT_HOTPLUG_EN                0x61110
-#define SDVOB_HOTPLUG_INT_EN           (1 << 26)
-#define SDVOC_HOTPLUG_INT_EN           (1 << 25)
-#define TV_HOTPLUG_INT_EN              (1 << 18)
-#define CRT_HOTPLUG_INT_EN             (1 << 9)
-#define CRT_HOTPLUG_FORCE_DETECT       (1 << 3)
-/* CDV.. */
-#define CRT_HOTPLUG_ACTIVATION_PERIOD_64       (1 << 8)
-#define CRT_HOTPLUG_DAC_ON_TIME_2M             (0 << 7)
-#define CRT_HOTPLUG_DAC_ON_TIME_4M             (1 << 7)
-#define CRT_HOTPLUG_VOLTAGE_COMPARE_40         (0 << 5)
-#define CRT_HOTPLUG_VOLTAGE_COMPARE_50         (1 << 5)
-#define CRT_HOTPLUG_VOLTAGE_COMPARE_60         (2 << 5)
-#define CRT_HOTPLUG_VOLTAGE_COMPARE_70         (3 << 5)
-#define CRT_HOTPLUG_VOLTAGE_COMPARE_MASK       (3 << 5)
-#define CRT_HOTPLUG_DETECT_DELAY_1G            (0 << 4)
-#define CRT_HOTPLUG_DETECT_DELAY_2G            (1 << 4)
-#define CRT_HOTPLUG_DETECT_VOLTAGE_325MV       (0 << 2)
-#define CRT_HOTPLUG_DETECT_VOLTAGE_475MV       (1 << 2)
-#define CRT_HOTPLUG_DETECT_MASK                        0x000000F8
-
-#define PORT_HOTPLUG_STAT      0x61114
-#define CRT_HOTPLUG_INT_STATUS         (1 << 11)
-#define TV_HOTPLUG_INT_STATUS          (1 << 10)
-#define CRT_HOTPLUG_MONITOR_MASK       (3 << 8)
-#define CRT_HOTPLUG_MONITOR_COLOR      (3 << 8)
-#define CRT_HOTPLUG_MONITOR_MONO       (2 << 8)
-#define CRT_HOTPLUG_MONITOR_NONE       (0 << 8)
-#define SDVOC_HOTPLUG_INT_STATUS       (1 << 7)
-#define SDVOB_HOTPLUG_INT_STATUS       (1 << 6)
-
-#define SDVOB                  0x61140
-#define SDVOC                  0x61160
-#define SDVO_ENABLE                    (1 << 31)
-#define SDVO_PIPE_B_SELECT             (1 << 30)
-#define SDVO_STALL_SELECT              (1 << 29)
-#define SDVO_INTERRUPT_ENABLE          (1 << 26)
-
-/**
- * 915G/GM SDVO pixel multiplier.
- *
- * Programmed value is multiplier - 1, up to 5x.
- *
- * DPLL_MD_UDI_MULTIPLIER_MASK
- */
-#define SDVO_PORT_MULTIPLY_MASK                (7 << 23)
-#define SDVO_PORT_MULTIPLY_SHIFT       23
-#define SDVO_PHASE_SELECT_MASK         (15 << 19)
-#define SDVO_PHASE_SELECT_DEFAULT      (6 << 19)
-#define SDVO_CLOCK_OUTPUT_INVERT       (1 << 18)
-#define SDVOC_GANG_MODE                        (1 << 16)
-#define SDVO_BORDER_ENABLE             (1 << 7)
-#define SDVOB_PCIE_CONCURRENCY         (1 << 3)
-#define SDVO_DETECTED                  (1 << 2)
-/* Bits to be preserved when writing */
-#define SDVOB_PRESERVE_MASK            ((1 << 17) | (1 << 16) | (1 << 14))
-#define SDVOC_PRESERVE_MASK            (1 << 17)
-
-/*
- * This register controls the LVDS output enable, pipe selection, and data
- * format selection.
- *
- * All of the clock/data pairs are force powered down by power sequencing.
- */
-#define LVDS                   0x61180
-/*
- * Enables the LVDS port.  This bit must be set before DPLLs are enabled, as
- * the DPLL semantics change when the LVDS is assigned to that pipe.
- */
-#define LVDS_PORT_EN                   (1 << 31)
-/* Selects pipe B for LVDS data.  Must be set on pre-965. */
-#define LVDS_PIPEB_SELECT              (1 << 30)
-
-/* Turns on border drawing to allow centered display. */
-#define LVDS_BORDER_EN                 (1 << 15)
-
-/*
- * Enables the A0-A2 data pairs and CLKA, containing 18 bits of color data per
- * pixel.
- */
-#define LVDS_A0A2_CLKA_POWER_MASK      (3 << 8)
-#define LVDS_A0A2_CLKA_POWER_DOWN      (0 << 8)
-#define LVDS_A0A2_CLKA_POWER_UP                (3 << 8)
-/*
- * Controls the A3 data pair, which contains the additional LSBs for 24 bit
- * mode.  Only enabled if LVDS_A0A2_CLKA_POWER_UP also indicates it should be
- * on.
- */
-#define LVDS_A3_POWER_MASK             (3 << 6)
-#define LVDS_A3_POWER_DOWN             (0 << 6)
-#define LVDS_A3_POWER_UP               (3 << 6)
-/*
- * Controls the CLKB pair.  This should only be set when LVDS_B0B3_POWER_UP
- * is set.
- */
-#define LVDS_CLKB_POWER_MASK           (3 << 4)
-#define LVDS_CLKB_POWER_DOWN           (0 << 4)
-#define LVDS_CLKB_POWER_UP             (3 << 4)
-/*
- * Controls the B0-B3 data pairs.  This must be set to match the DPLL p2
- * setting for whether we are in dual-channel mode.  The B3 pair will
- * additionally only be powered up when LVDS_A3_POWER_UP is set.
- */
-#define LVDS_B0B3_POWER_MASK           (3 << 2)
-#define LVDS_B0B3_POWER_DOWN           (0 << 2)
-#define LVDS_B0B3_POWER_UP             (3 << 2)
-
-#define PIPEACONF              0x70008
-#define PIPEACONF_ENABLE               (1 << 31)
-#define PIPEACONF_DISABLE              0
-#define PIPEACONF_DOUBLE_WIDE          (1 << 30)
-#define PIPECONF_ACTIVE                        (1 << 30)
-#define I965_PIPECONF_ACTIVE           (1 << 30)
-#define PIPECONF_DSIPLL_LOCK           (1 << 29)
-#define PIPEACONF_SINGLE_WIDE          0
-#define PIPEACONF_PIPE_UNLOCKED                0
-#define PIPEACONF_DSR                  (1 << 26)
-#define PIPEACONF_PIPE_LOCKED          (1 << 25)
-#define PIPEACONF_PALETTE              0
-#define PIPECONF_FORCE_BORDER          (1 << 25)
-#define PIPEACONF_GAMMA                        (1 << 24)
-#define PIPECONF_PROGRESSIVE           (0 << 21)
-#define PIPECONF_INTERLACE_W_FIELD_INDICATION  (6 << 21)
-#define PIPECONF_INTERLACE_FIELD_0_ONLY                (7 << 21)
-#define PIPECONF_PLANE_OFF             (1 << 19)
-#define PIPECONF_CURSOR_OFF            (1 << 18)
-
-#define PIPEBCONF              0x71008
-#define PIPEBCONF_ENABLE               (1 << 31)
-#define PIPEBCONF_DISABLE              0
-#define PIPEBCONF_DOUBLE_WIDE          (1 << 30)
-#define PIPEBCONF_DISABLE              0
-#define PIPEBCONF_GAMMA                        (1 << 24)
-#define PIPEBCONF_PALETTE              0
-
-#define PIPECCONF              0x72008
-
-#define PIPEBGCMAXRED          0x71010
-#define PIPEBGCMAXGREEN                0x71014
-#define PIPEBGCMAXBLUE         0x71018
-
-#define PIPEASTAT              0x70024
-#define PIPEBSTAT              0x71024
-#define PIPECSTAT              0x72024
-#define PIPE_VBLANK_INTERRUPT_STATUS           (1UL << 1)
-#define PIPE_START_VBLANK_INTERRUPT_STATUS     (1UL << 2)
-#define PIPE_VBLANK_CLEAR                      (1 << 1)
-#define PIPE_VBLANK_STATUS                     (1 << 1)
-#define PIPE_TE_STATUS                         (1UL << 6)
-#define PIPE_DPST_EVENT_STATUS                 (1UL << 7)
-#define PIPE_VSYNC_CLEAR                       (1UL << 9)
-#define PIPE_VSYNC_STATUS                      (1UL << 9)
-#define PIPE_HDMI_AUDIO_UNDERRUN_STATUS                (1UL << 10)
-#define PIPE_HDMI_AUDIO_BUFFER_DONE_STATUS     (1UL << 11)
-#define PIPE_VBLANK_INTERRUPT_ENABLE           (1UL << 17)
-#define PIPE_START_VBLANK_INTERRUPT_ENABLE     (1UL << 18)
-#define PIPE_TE_ENABLE                         (1UL << 22)
-#define PIPE_DPST_EVENT_ENABLE                 (1UL << 23)
-#define PIPE_VSYNC_ENABL                       (1UL << 25)
-#define PIPE_HDMI_AUDIO_UNDERRUN               (1UL << 26)
-#define PIPE_HDMI_AUDIO_BUFFER_DONE            (1UL << 27)
-#define PIPE_HDMI_AUDIO_INT_MASK               (PIPE_HDMI_AUDIO_UNDERRUN | \
-                                               PIPE_HDMI_AUDIO_BUFFER_DONE)
-#define PIPE_EVENT_MASK ((1 << 29)|(1 << 28)|(1 << 27)|(1 << 26)|(1 << 24)|(1 << 23)|(1 << 22)|(1 << 21)|(1 << 20)|(1 << 16))
-#define PIPE_VBLANK_MASK ((1 << 25)|(1 << 24)|(1 << 18)|(1 << 17))
-#define HISTOGRAM_INT_CONTROL          0x61268
-#define HISTOGRAM_BIN_DATA             0X61264
-#define HISTOGRAM_LOGIC_CONTROL                0x61260
-#define PWM_CONTROL_LOGIC              0x61250
-#define PIPE_HOTPLUG_INTERRUPT_STATUS          (1UL << 10)
-#define HISTOGRAM_INTERRUPT_ENABLE             (1UL << 31)
-#define HISTOGRAM_LOGIC_ENABLE                 (1UL << 31)
-#define PWM_LOGIC_ENABLE                       (1UL << 31)
-#define PWM_PHASEIN_ENABLE                     (1UL << 25)
-#define PWM_PHASEIN_INT_ENABLE                 (1UL << 24)
-#define PWM_PHASEIN_VB_COUNT                   0x00001f00
-#define PWM_PHASEIN_INC                                0x0000001f
-#define HISTOGRAM_INT_CTRL_CLEAR               (1UL << 30)
-#define DPST_YUV_LUMA_MODE                     0
-
-struct dpst_ie_histogram_control {
-       union {
-               uint32_t data;
-               struct {
-                       uint32_t bin_reg_index:7;
-                       uint32_t reserved:4;
-                       uint32_t bin_reg_func_select:1;
-                       uint32_t sync_to_phase_in:1;
-                       uint32_t alt_enhancement_mode:2;
-                       uint32_t reserved1:1;
-                       uint32_t sync_to_phase_in_count:8;
-                       uint32_t histogram_mode_select:1;
-                       uint32_t reserved2:4;
-                       uint32_t ie_pipe_assignment:1;
-                       uint32_t ie_mode_table_enabled:1;
-                       uint32_t ie_histogram_enable:1;
-               };
-       };
-};
-
-struct dpst_guardband {
-       union {
-               uint32_t data;
-               struct {
-                       uint32_t guardband:22;
-                       uint32_t guardband_interrupt_delay:8;
-                       uint32_t interrupt_status:1;
-                       uint32_t interrupt_enable:1;
-               };
-       };
-};
-
-#define PIPEAFRAMEHIGH         0x70040
-#define PIPEAFRAMEPIXEL                0x70044
-#define PIPEBFRAMEHIGH         0x71040
-#define PIPEBFRAMEPIXEL                0x71044
-#define PIPECFRAMEHIGH         0x72040
-#define PIPECFRAMEPIXEL                0x72044
-#define PIPE_FRAME_HIGH_MASK   0x0000ffff
-#define PIPE_FRAME_HIGH_SHIFT  0
-#define PIPE_FRAME_LOW_MASK    0xff000000
-#define PIPE_FRAME_LOW_SHIFT   24
-#define PIPE_PIXEL_MASK                0x00ffffff
-#define PIPE_PIXEL_SHIFT       0
-
-#define DSPARB                 0x70030
-#define DSPFW1                 0x70034
-#define DSPFW2                 0x70038
-#define DSPFW3                 0x7003c
-#define DSPFW4                 0x70050
-#define DSPFW5                 0x70054
-#define DSPFW6                 0x70058
-#define DSPCHICKENBIT          0x70400
-#define DSPACNTR               0x70180
-#define DSPBCNTR               0x71180
-#define DSPCCNTR               0x72180
-#define DISPLAY_PLANE_ENABLE                   (1 << 31)
-#define DISPLAY_PLANE_DISABLE                  0
-#define DISPPLANE_GAMMA_ENABLE                 (1 << 30)
-#define DISPPLANE_GAMMA_DISABLE                        0
-#define DISPPLANE_PIXFORMAT_MASK               (0xf << 26)
-#define DISPPLANE_8BPP                         (0x2 << 26)
-#define DISPPLANE_15_16BPP                     (0x4 << 26)
-#define DISPPLANE_16BPP                                (0x5 << 26)
-#define DISPPLANE_32BPP_NO_ALPHA               (0x6 << 26)
-#define DISPPLANE_32BPP                                (0x7 << 26)
-#define DISPPLANE_STEREO_ENABLE                        (1 << 25)
-#define DISPPLANE_STEREO_DISABLE               0
-#define DISPPLANE_SEL_PIPE_MASK                        (1 << 24)
-#define DISPPLANE_SEL_PIPE_POS                 24
-#define DISPPLANE_SEL_PIPE_A                   0
-#define DISPPLANE_SEL_PIPE_B                   (1 << 24)
-#define DISPPLANE_SRC_KEY_ENABLE               (1 << 22)
-#define DISPPLANE_SRC_KEY_DISABLE              0
-#define DISPPLANE_LINE_DOUBLE                  (1 << 20)
-#define DISPPLANE_NO_LINE_DOUBLE               0
-#define DISPPLANE_STEREO_POLARITY_FIRST                0
-#define DISPPLANE_STEREO_POLARITY_SECOND       (1 << 18)
-/* plane B only */
-#define DISPPLANE_ALPHA_TRANS_ENABLE           (1 << 15)
-#define DISPPLANE_ALPHA_TRANS_DISABLE          0
-#define DISPPLANE_SPRITE_ABOVE_DISPLAYA                0
-#define DISPPLANE_SPRITE_ABOVE_OVERLAY         (1)
-#define DISPPLANE_BOTTOM                       (4)
-
-#define DSPABASE               0x70184
-#define DSPALINOFF             0x70184
-#define DSPASTRIDE             0x70188
-
-#define DSPBBASE               0x71184
-#define DSPBLINOFF             0X71184
-#define DSPBADDR               DSPBBASE
-#define DSPBSTRIDE             0x71188
-
-#define DSPCBASE               0x72184
-#define DSPCLINOFF             0x72184
-#define DSPCSTRIDE             0x72188
-
-#define DSPAKEYVAL             0x70194
-#define DSPAKEYMASK            0x70198
-
-#define DSPAPOS                        0x7018C /* reserved */
-#define DSPASIZE               0x70190
-#define DSPBPOS                        0x7118C
-#define DSPBSIZE               0x71190
-#define DSPCPOS                        0x7218C
-#define DSPCSIZE               0x72190
-
-#define DSPASURF               0x7019C
-#define DSPATILEOFF            0x701A4
-
-#define DSPBSURF               0x7119C
-#define DSPBTILEOFF            0x711A4
-
-#define DSPCSURF               0x7219C
-#define DSPCTILEOFF            0x721A4
-#define DSPCKEYMAXVAL          0x721A0
-#define DSPCKEYMINVAL          0x72194
-#define DSPCKEYMSK             0x72198
-
-#define VGACNTRL               0x71400
-#define VGA_DISP_DISABLE               (1 << 31)
-#define VGA_2X_MODE                    (1 << 30)
-#define VGA_PIPE_B_SELECT              (1 << 29)
-
-/*
- * Overlay registers
- */
-#define OV_C_OFFSET            0x08000
-#define OV_OVADD               0x30000
-#define OV_DOVASTA             0x30008
-# define OV_PIPE_SELECT                        ((1 << 6)|(1 << 7))
-# define OV_PIPE_SELECT_POS            6
-# define OV_PIPE_A                     0
-# define OV_PIPE_C                     1
-#define OV_OGAMC5              0x30010
-#define OV_OGAMC4              0x30014
-#define OV_OGAMC3              0x30018
-#define OV_OGAMC2              0x3001C
-#define OV_OGAMC1              0x30020
-#define OV_OGAMC0              0x30024
-#define OVC_OVADD              0x38000
-#define OVC_DOVCSTA            0x38008
-#define OVC_OGAMC5             0x38010
-#define OVC_OGAMC4             0x38014
-#define OVC_OGAMC3             0x38018
-#define OVC_OGAMC2             0x3801C
-#define OVC_OGAMC1             0x38020
-#define OVC_OGAMC0             0x38024
-
-/*
- * Some BIOS scratch area registers.  The 845 (and 830?) store the amount
- * of video memory available to the BIOS in SWF1.
- */
-#define SWF0                   0x71410
-#define SWF1                   0x71414
-#define SWF2                   0x71418
-#define SWF3                   0x7141c
-#define SWF4                   0x71420
-#define SWF5                   0x71424
-#define SWF6                   0x71428
-
-/*
- * 855 scratch registers.
- */
-#define SWF00                  0x70410
-#define SWF01                  0x70414
-#define SWF02                  0x70418
-#define SWF03                  0x7041c
-#define SWF04                  0x70420
-#define SWF05                  0x70424
-#define SWF06                  0x70428
-
-#define SWF10                  SWF0
-#define SWF11                  SWF1
-#define SWF12                  SWF2
-#define SWF13                  SWF3
-#define SWF14                  SWF4
-#define SWF15                  SWF5
-#define SWF16                  SWF6
-
-#define SWF30                  0x72414
-#define SWF31                  0x72418
-#define SWF32                  0x7241c
-
-
-/*
- * Palette registers
- */
-#define PALETTE_A              0x0a000
-#define PALETTE_B              0x0a800
-#define PALETTE_C              0x0ac00
-
-/* Cursor A & B regs */
-#define CURACNTR               0x70080
-#define CURSOR_MODE_DISABLE            0x00
-#define CURSOR_MODE_64_32B_AX          0x07
-#define CURSOR_MODE_64_ARGB_AX         ((1 << 5) | CURSOR_MODE_64_32B_AX)
-#define MCURSOR_GAMMA_ENABLE           (1 << 26)
-#define CURABASE               0x70084
-#define CURAPOS                        0x70088
-#define CURSOR_POS_MASK                        0x007FF
-#define CURSOR_POS_SIGN                        0x8000
-#define CURSOR_X_SHIFT                 0
-#define CURSOR_Y_SHIFT                 16
-#define CURBCNTR               0x700c0
-#define CURBBASE               0x700c4
-#define CURBPOS                        0x700c8
-#define CURCCNTR               0x700e0
-#define CURCBASE               0x700e4
-#define CURCPOS                        0x700e8
-
-/*
- * Interrupt Registers
- */
-#define IER                    0x020a0
-#define IIR                    0x020a4
-#define IMR                    0x020a8
-#define ISR                    0x020ac
-
-/*
- * MOORESTOWN delta registers
- */
-#define MRST_DPLL_A            0x0f014
-#define MDFLD_DPLL_B           0x0f018
-#define MDFLD_INPUT_REF_SEL            (1 << 14)
-#define MDFLD_VCO_SEL                  (1 << 16)
-#define DPLLA_MODE_LVDS                        (2 << 26)       /* mrst */
-#define MDFLD_PLL_LATCHEN              (1 << 28)
-#define MDFLD_PWR_GATE_EN              (1 << 30)
-#define MDFLD_P1_MASK                  (0x1FF << 17)
-#define MRST_FPA0              0x0f040
-#define MRST_FPA1              0x0f044
-#define MDFLD_DPLL_DIV0                0x0f048
-#define MDFLD_DPLL_DIV1                0x0f04c
-#define MRST_PERF_MODE         0x020f4
-
-/*
- * MEDFIELD HDMI registers
- */
-#define HDMIPHYMISCCTL         0x61134
-#define HDMI_PHY_POWER_DOWN            0x7f
-#define HDMIB_CONTROL          0x61140
-#define HDMIB_PORT_EN                  (1 << 31)
-#define HDMIB_PIPE_B_SELECT            (1 << 30)
-#define HDMIB_NULL_PACKET              (1 << 9)
-#define HDMIB_HDCP_PORT                        (1 << 5)
-
-/* #define LVDS                        0x61180 */
-#define MRST_PANEL_8TO6_DITHER_ENABLE  (1 << 25)
-#define MRST_PANEL_24_DOT_1_FORMAT     (1 << 24)
-#define LVDS_A3_POWER_UP_0_OUTPUT      (1 << 6)
-
-#define MIPI                   0x61190
-#define MIPI_C                 0x62190
-#define MIPI_PORT_EN                   (1 << 31)
-/* Turns on border drawing to allow centered display. */
-#define SEL_FLOPPED_HSTX               (1 << 23)
-#define PASS_FROM_SPHY_TO_AFE          (1 << 16)
-#define MIPI_BORDER_EN                 (1 << 15)
-#define MIPIA_3LANE_MIPIC_1LANE                0x1
-#define MIPIA_2LANE_MIPIC_2LANE                0x2
-#define TE_TRIGGER_DSI_PROTOCOL                (1 << 2)
-#define TE_TRIGGER_GPIO_PIN            (1 << 3)
-#define MIPI_TE_COUNT          0x61194
-
-/* #define PP_CONTROL  0x61204 */
-#define POWER_DOWN_ON_RESET            (1 << 1)
-
-/* #define PFIT_CONTROL        0x61230 */
-#define PFIT_PIPE_SELECT               (3 << 29)
-#define PFIT_PIPE_SELECT_SHIFT         (29)
-
-/* #define BLC_PWM_CTL         0x61254 */
-#define MRST_BACKLIGHT_MODULATION_FREQ_SHIFT   (16)
-#define MRST_BACKLIGHT_MODULATION_FREQ_MASK    (0xffff << 16)
-
-/* #define PIPEACONF 0x70008 */
-#define PIPEACONF_PIPE_STATE           (1 << 30)
-/* #define DSPACNTR            0x70180 */
-
-#define MRST_DSPABASE          0x7019c
-#define MRST_DSPBBASE          0x7119c
-#define MDFLD_DSPCBASE         0x7219c
-
-/*
- * Moorestown registers.
- */
-
-/*
- *     MIPI IP registers
- */
-#define MIPIC_REG_OFFSET               0x800
-
-#define DEVICE_READY_REG               0xb000
-#define LP_OUTPUT_HOLD                         (1 << 16)
-#define EXIT_ULPS_DEV_READY                    0x3
-#define LP_OUTPUT_HOLD_RELEASE                 0x810000
-# define ENTERING_ULPS                         (2 << 1)
-# define EXITING_ULPS                          (1 << 1)
-# define ULPS_MASK                             (3 << 1)
-# define BUS_POSSESSION                                (1 << 3)
-#define INTR_STAT_REG                  0xb004
-#define RX_SOT_ERROR                           (1 << 0)
-#define RX_SOT_SYNC_ERROR                      (1 << 1)
-#define RX_ESCAPE_MODE_ENTRY_ERROR             (1 << 3)
-#define RX_LP_TX_SYNC_ERROR                    (1 << 4)
-#define RX_HS_RECEIVE_TIMEOUT_ERROR            (1 << 5)
-#define RX_FALSE_CONTROL_ERROR                 (1 << 6)
-#define RX_ECC_SINGLE_BIT_ERROR                        (1 << 7)
-#define RX_ECC_MULTI_BIT_ERROR                 (1 << 8)
-#define RX_CHECKSUM_ERROR                      (1 << 9)
-#define RX_DSI_DATA_TYPE_NOT_RECOGNIZED                (1 << 10)
-#define RX_DSI_VC_ID_INVALID                   (1 << 11)
-#define TX_FALSE_CONTROL_ERROR                 (1 << 12)
-#define TX_ECC_SINGLE_BIT_ERROR                        (1 << 13)
-#define TX_ECC_MULTI_BIT_ERROR                 (1 << 14)
-#define TX_CHECKSUM_ERROR                      (1 << 15)
-#define TX_DSI_DATA_TYPE_NOT_RECOGNIZED                (1 << 16)
-#define TX_DSI_VC_ID_INVALID                   (1 << 17)
-#define HIGH_CONTENTION                                (1 << 18)
-#define LOW_CONTENTION                         (1 << 19)
-#define DPI_FIFO_UNDER_RUN                     (1 << 20)
-#define HS_TX_TIMEOUT                          (1 << 21)
-#define LP_RX_TIMEOUT                          (1 << 22)
-#define TURN_AROUND_ACK_TIMEOUT                        (1 << 23)
-#define ACK_WITH_NO_ERROR                      (1 << 24)
-#define HS_GENERIC_WR_FIFO_FULL                        (1 << 27)
-#define LP_GENERIC_WR_FIFO_FULL                        (1 << 28)
-#define SPL_PKT_SENT                           (1 << 30)
-#define INTR_EN_REG                    0xb008
-#define DSI_FUNC_PRG_REG               0xb00c
-#define DPI_CHANNEL_NUMBER_POS                 0x03
-#define DBI_CHANNEL_NUMBER_POS                 0x05
-#define FMT_DPI_POS                            0x07
-#define FMT_DBI_POS                            0x0A
-#define DBI_DATA_WIDTH_POS                     0x0D
-
-/* DPI PIXEL FORMATS */
-#define RGB_565_FMT                            0x01    /* RGB 565 FORMAT */
-#define RGB_666_FMT                            0x02    /* RGB 666 FORMAT */
-#define LRGB_666_FMT                           0x03    /* RGB LOOSELY PACKED
-                                                        * 666 FORMAT
-                                                        */
-#define RGB_888_FMT                            0x04    /* RGB 888 FORMAT */
-#define VIRTUAL_CHANNEL_NUMBER_0               0x00    /* Virtual channel 0 */
-#define VIRTUAL_CHANNEL_NUMBER_1               0x01    /* Virtual channel 1 */
-#define VIRTUAL_CHANNEL_NUMBER_2               0x02    /* Virtual channel 2 */
-#define VIRTUAL_CHANNEL_NUMBER_3               0x03    /* Virtual channel 3 */
-
-#define DBI_NOT_SUPPORTED                      0x00    /* command mode
-                                                        * is not supported
-                                                        */
-#define DBI_DATA_WIDTH_16BIT                   0x01    /* 16 bit data */
-#define DBI_DATA_WIDTH_9BIT                    0x02    /* 9 bit data */
-#define DBI_DATA_WIDTH_8BIT                    0x03    /* 8 bit data */
-#define DBI_DATA_WIDTH_OPT1                    0x04    /* option 1 */
-#define DBI_DATA_WIDTH_OPT2                    0x05    /* option 2 */
-
-#define HS_TX_TIMEOUT_REG              0xb010
-#define LP_RX_TIMEOUT_REG              0xb014
-#define TURN_AROUND_TIMEOUT_REG                0xb018
-#define DEVICE_RESET_REG               0xb01C
-#define DPI_RESOLUTION_REG             0xb020
-#define RES_V_POS                              0x10
-#define DBI_RESOLUTION_REG             0xb024 /* Reserved for MDFLD */
-#define HORIZ_SYNC_PAD_COUNT_REG       0xb028
-#define HORIZ_BACK_PORCH_COUNT_REG     0xb02C
-#define HORIZ_FRONT_PORCH_COUNT_REG    0xb030
-#define HORIZ_ACTIVE_AREA_COUNT_REG    0xb034
-#define VERT_SYNC_PAD_COUNT_REG                0xb038
-#define VERT_BACK_PORCH_COUNT_REG      0xb03c
-#define VERT_FRONT_PORCH_COUNT_REG     0xb040
-#define HIGH_LOW_SWITCH_COUNT_REG      0xb044
-#define DPI_CONTROL_REG                        0xb048
-#define DPI_SHUT_DOWN                          (1 << 0)
-#define DPI_TURN_ON                            (1 << 1)
-#define DPI_COLOR_MODE_ON                      (1 << 2)
-#define DPI_COLOR_MODE_OFF                     (1 << 3)
-#define DPI_BACK_LIGHT_ON                      (1 << 4)
-#define DPI_BACK_LIGHT_OFF                     (1 << 5)
-#define DPI_LP                                 (1 << 6)
-#define DPI_DATA_REG                   0xb04c
-#define DPI_BACK_LIGHT_ON_DATA                 0x07
-#define DPI_BACK_LIGHT_OFF_DATA                        0x17
-#define INIT_COUNT_REG                 0xb050
-#define MAX_RET_PAK_REG                        0xb054
-#define VIDEO_FMT_REG                  0xb058
-#define COMPLETE_LAST_PCKT                     (1 << 2)
-#define EOT_DISABLE_REG                        0xb05c
-#define ENABLE_CLOCK_STOPPING                  (1 << 1)
-#define LP_BYTECLK_REG                 0xb060
-#define LP_GEN_DATA_REG                        0xb064
-#define HS_GEN_DATA_REG                        0xb068
-#define LP_GEN_CTRL_REG                        0xb06C
-#define HS_GEN_CTRL_REG                        0xb070
-#define DCS_CHANNEL_NUMBER_POS         0x6
-#define MCS_COMMANDS_POS               0x8
-#define WORD_COUNTS_POS                        0x8
-#define MCS_PARAMETER_POS                      0x10
-#define GEN_FIFO_STAT_REG              0xb074
-#define HS_DATA_FIFO_FULL                      (1 << 0)
-#define HS_DATA_FIFO_HALF_EMPTY                        (1 << 1)
-#define HS_DATA_FIFO_EMPTY                     (1 << 2)
-#define LP_DATA_FIFO_FULL                      (1 << 8)
-#define LP_DATA_FIFO_HALF_EMPTY                        (1 << 9)
-#define LP_DATA_FIFO_EMPTY                     (1 << 10)
-#define HS_CTRL_FIFO_FULL                      (1 << 16)
-#define HS_CTRL_FIFO_HALF_EMPTY                        (1 << 17)
-#define HS_CTRL_FIFO_EMPTY                     (1 << 18)
-#define LP_CTRL_FIFO_FULL                      (1 << 24)
-#define LP_CTRL_FIFO_HALF_EMPTY                        (1 << 25)
-#define LP_CTRL_FIFO_EMPTY                     (1 << 26)
-#define DBI_FIFO_EMPTY                         (1 << 27)
-#define DPI_FIFO_EMPTY                         (1 << 28)
-#define HS_LS_DBI_ENABLE_REG           0xb078
-#define TXCLKESC_REG                   0xb07c
-#define DPHY_PARAM_REG                 0xb080
-#define DBI_BW_CTRL_REG                        0xb084
-#define CLK_LANE_SWT_REG               0xb088
-
-/*
- * MIPI Adapter registers
- */
-#define MIPI_CONTROL_REG               0xb104
-#define MIPI_2X_CLOCK_BITS                     ((1 << 0) | (1 << 1))
-#define MIPI_DATA_ADDRESS_REG          0xb108
-#define MIPI_DATA_LENGTH_REG           0xb10C
-#define MIPI_COMMAND_ADDRESS_REG       0xb110
-#define MIPI_COMMAND_LENGTH_REG                0xb114
-#define MIPI_READ_DATA_RETURN_REG0     0xb118
-#define MIPI_READ_DATA_RETURN_REG1     0xb11C
-#define MIPI_READ_DATA_RETURN_REG2     0xb120
-#define MIPI_READ_DATA_RETURN_REG3     0xb124
-#define MIPI_READ_DATA_RETURN_REG4     0xb128
-#define MIPI_READ_DATA_RETURN_REG5     0xb12C
-#define MIPI_READ_DATA_RETURN_REG6     0xb130
-#define MIPI_READ_DATA_RETURN_REG7     0xb134
-#define MIPI_READ_DATA_VALID_REG       0xb138
-
-/* DBI COMMANDS */
-#define soft_reset                     0x01
-/*
- *     The display module performs a software reset.
- *     Registers are written with their SW Reset default values.
- */
-#define get_power_mode                 0x0a
-/*
- *     The display module returns the current power mode
- */
-#define get_address_mode               0x0b
-/*
- *     The display module returns the current status.
- */
-#define get_pixel_format               0x0c
-/*
- *     This command gets the pixel format for the RGB image data
- *     used by the interface.
- */
-#define get_display_mode               0x0d
-/*
- *     The display module returns the Display Image Mode status.
- */
-#define get_signal_mode                        0x0e
-/*
- *     The display module returns the Display Signal Mode.
- */
-#define get_diagnostic_result          0x0f
-/*
- *     The display module returns the self-diagnostic results following
- *     a Sleep Out command.
- */
-#define enter_sleep_mode               0x10
-/*
- *     This command causes the display module to enter the Sleep mode.
- *     In this mode, all unnecessary blocks inside the display module are
- *     disabled except interface communication. This is the lowest power
- *     mode the display module supports.
- */
-#define exit_sleep_mode                        0x11
-/*
- *     This command causes the display module to exit Sleep mode.
- *     All blocks inside the display module are enabled.
- */
-#define enter_partial_mode             0x12
-/*
- *     This command causes the display module to enter the Partial Display
- *     Mode. The Partial Display Mode window is described by the
- *     set_partial_area command.
- */
-#define enter_normal_mode              0x13
-/*
- *     This command causes the display module to enter the Normal mode.
- *     Normal Mode is defined as Partial Display mode and Scroll mode are off
- */
-#define exit_invert_mode               0x20
-/*
- *     This command causes the display module to stop inverting the image
- *     data on the display device. The frame memory contents remain unchanged.
- *     No status bits are changed.
- */
-#define enter_invert_mode              0x21
-/*
- *     This command causes the display module to invert the image data only on
- *     the display device. The frame memory contents remain unchanged.
- *     No status bits are changed.
- */
-#define set_gamma_curve                        0x26
-/*
- *     This command selects the desired gamma curve for the display device.
- *     Four fixed gamma curves are defined in section DCS spec.
- */
-#define set_display_off                        0x28
-/* ************************************************************************* *\
-This command causes the display module to stop displaying the image data
-on the display device. The frame memory contents remain unchanged.
-No status bits are changed.
-\* ************************************************************************* */
-#define set_display_on                 0x29
-/* ************************************************************************* *\
-This command causes the display module to start displaying the image data
-on the display device. The frame memory contents remain unchanged.
-No status bits are changed.
-\* ************************************************************************* */
-#define set_column_address             0x2a
-/*
- *     This command defines the column extent of the frame memory accessed by
- *     the hostprocessor with the read_memory_continue and
- *     write_memory_continue commands.
- *     No status bits are changed.
- */
-#define set_page_addr                  0x2b
-/*
- *     This command defines the page extent of the frame memory accessed by
- *     the host processor with the write_memory_continue and
- *     read_memory_continue command.
- *     No status bits are changed.
- */
-#define write_mem_start                        0x2c
-/*
- *     This command transfers image data from the host processor to the
- *     display modules frame memory starting at the pixel location specified
- *     by preceding set_column_address and set_page_address commands.
- */
-#define set_partial_area               0x30
-/*
- *     This command defines the Partial Display mode s display area.
- *     There are two parameters associated with this command, the first
- *     defines the Start Row (SR) and the second the End Row (ER). SR and ER
- *     refer to the Frame Memory Line Pointer.
- */
-#define set_scroll_area                        0x33
-/*
- *     This command defines the display modules Vertical Scrolling Area.
- */
-#define set_tear_off                   0x34
-/*
- *     This command turns off the display modules Tearing Effect output
- *     signal on the TE signal line.
- */
-#define set_tear_on                    0x35
-/*
- *     This command turns on the display modules Tearing Effect output signal
- *     on the TE signal line.
- */
-#define set_address_mode               0x36
-/*
- *     This command sets the data order for transfers from the host processor
- *     to display modules frame memory,bits B[7:5] and B3, and from the
- *     display modules frame memory to the display device, bits B[2:0] and B4.
- */
-#define set_scroll_start               0x37
-/*
- *     This command sets the start of the vertical scrolling area in the frame
- *     memory. The vertical scrolling area is fully defined when this command
- *     is used with the set_scroll_area command The set_scroll_start command
- *     has one parameter, the Vertical Scroll Pointer. The VSP defines the
- *     line in the frame memory that is written to the display device as the
- *     first line of the vertical scroll area.
- */
-#define exit_idle_mode                 0x38
-/*
- *     This command causes the display module to exit Idle mode.
- */
-#define enter_idle_mode                        0x39
-/*
- *     This command causes the display module to enter Idle Mode.
- *     In Idle Mode, color expression is reduced. Colors are shown on the
- *     display device using the MSB of each of the R, G and B color
- *     components in the frame memory
- */
-#define set_pixel_format               0x3a
-/*
- *     This command sets the pixel format for the RGB image data used by the
- *     interface.
- *     Bits D[6:4]  DPI Pixel Format Definition
- *     Bits D[2:0]  DBI Pixel Format Definition
- *     Bits D7 and D3 are not used.
- */
-#define DCS_PIXEL_FORMAT_3bpp          0x1
-#define DCS_PIXEL_FORMAT_8bpp          0x2
-#define DCS_PIXEL_FORMAT_12bpp         0x3
-#define DCS_PIXEL_FORMAT_16bpp         0x5
-#define DCS_PIXEL_FORMAT_18bpp         0x6
-#define DCS_PIXEL_FORMAT_24bpp         0x7
-
-#define write_mem_cont                 0x3c
-
-/*
- *     This command transfers image data from the host processor to the
- *     display module's frame memory continuing from the pixel location
- *     following the previous write_memory_continue or write_memory_start
- *     command.
- */
-#define set_tear_scanline              0x44
-/*
- *     This command turns on the display modules Tearing Effect output signal
- *     on the TE signal line when the display module reaches line N.
- */
-#define get_scanline                   0x45
-/*
- *     The display module returns the current scanline, N, used to update the
- *      display device. The total number of scanlines on a display device is
- *     defined as VSYNC + VBP + VACT + VFP.The first scanline is defined as
- *     the first line of V Sync and is denoted as Line 0.
- *     When in Sleep Mode, the value returned by get_scanline is undefined.
- */
-
-/* MCS or Generic COMMANDS */
-/* MCS/generic data type */
-#define GEN_SHORT_WRITE_0      0x03  /* generic short write, no parameters */
-#define GEN_SHORT_WRITE_1      0x13  /* generic short write, 1 parameters */
-#define GEN_SHORT_WRITE_2      0x23  /* generic short write, 2 parameters */
-#define GEN_READ_0             0x04  /* generic read, no parameters */
-#define GEN_READ_1             0x14  /* generic read, 1 parameters */
-#define GEN_READ_2             0x24  /* generic read, 2 parameters */
-#define GEN_LONG_WRITE         0x29  /* generic long write */
-#define MCS_SHORT_WRITE_0      0x05  /* MCS short write, no parameters */
-#define MCS_SHORT_WRITE_1      0x15  /* MCS short write, 1 parameters */
-#define MCS_READ               0x06  /* MCS read, no parameters */
-#define MCS_LONG_WRITE         0x39  /* MCS long write */
-/* MCS/generic commands */
-/* TPO MCS */
-#define write_display_profile          0x50
-#define write_display_brightness       0x51
-#define write_ctrl_display             0x53
-#define write_ctrl_cabc                        0x55
-  #define UI_IMAGE             0x01
-  #define STILL_IMAGE          0x02
-  #define MOVING_IMAGE         0x03
-#define write_hysteresis               0x57
-#define write_gamma_setting            0x58
-#define write_cabc_min_bright          0x5e
-#define write_kbbc_profile             0x60
-/* TMD MCS */
-#define tmd_write_display_brightness 0x8c
-
-/*
- *     This command is used to control ambient light, panel backlight
- *     brightness and gamma settings.
- */
-#define BRIGHT_CNTL_BLOCK_ON   (1 << 5)
-#define AMBIENT_LIGHT_SENSE_ON (1 << 4)
-#define DISPLAY_DIMMING_ON     (1 << 3)
-#define BACKLIGHT_ON           (1 << 2)
-#define DISPLAY_BRIGHTNESS_AUTO        (1 << 1)
-#define GAMMA_AUTO             (1 << 0)
-
-/* DCS Interface Pixel Formats */
-#define DCS_PIXEL_FORMAT_3BPP  0x1
-#define DCS_PIXEL_FORMAT_8BPP  0x2
-#define DCS_PIXEL_FORMAT_12BPP 0x3
-#define DCS_PIXEL_FORMAT_16BPP 0x5
-#define DCS_PIXEL_FORMAT_18BPP 0x6
-#define DCS_PIXEL_FORMAT_24BPP 0x7
-/* ONE PARAMETER READ DATA */
-#define addr_mode_data         0xfc
-#define diag_res_data          0x00
-#define disp_mode_data         0x23
-#define pxl_fmt_data           0x77
-#define pwr_mode_data          0x74
-#define sig_mode_data          0x00
-/* TWO PARAMETERS READ DATA */
-#define scanline_data1         0xff
-#define scanline_data2         0xff
-#define NON_BURST_MODE_SYNC_PULSE      0x01    /* Non Burst Mode
-                                                * with Sync Pulse
-                                                */
-#define NON_BURST_MODE_SYNC_EVENTS     0x02    /* Non Burst Mode
-                                                * with Sync events
-                                                */
-#define BURST_MODE                     0x03    /* Burst Mode */
-#define DBI_COMMAND_BUFFER_SIZE                0x240   /* 0x32 */    /* 0x120 */
-                                               /* Allocate at least
-                                                * 0x100 Byte with 32
-                                                * byte alignment
-                                                */
-#define DBI_DATA_BUFFER_SIZE           0x120   /* Allocate at least
-                                                * 0x100 Byte with 32
-                                                * byte alignment
-                                                */
-#define DBI_CB_TIME_OUT                        0xFFFF
-
-#define GEN_FB_TIME_OUT                        2000
-
-#define SKU_83                         0x01
-#define SKU_100                                0x02
-#define SKU_100L                       0x04
-#define SKU_BYPASS                     0x08
-
-/* Some handy macros for playing with bitfields. */
-#define PSB_MASK(high, low) (((1<<((high)-(low)+1))-1)<<(low))
-#define SET_FIELD(value, field) (((value) << field ## _SHIFT) & field ## _MASK)
-#define GET_FIELD(word, field) (((word)  & field ## _MASK) >> field ## _SHIFT)
-
-#define _PIPE(pipe, a, b) ((a) + (pipe)*((b)-(a)))
-
-/* PCI config space */
-
-#define SB_PCKT         0x02100 /* cedarview */
-# define SB_OPCODE_MASK                         PSB_MASK(31, 16)
-# define SB_OPCODE_SHIFT                        16
-# define SB_OPCODE_READ                         0
-# define SB_OPCODE_WRITE                        1
-# define SB_DEST_MASK                           PSB_MASK(15, 8)
-# define SB_DEST_SHIFT                          8
-# define SB_DEST_DPLL                           0x88
-# define SB_BYTE_ENABLE_MASK                    PSB_MASK(7, 4)
-# define SB_BYTE_ENABLE_SHIFT                   4
-# define SB_BUSY                                (1 << 0)
-
-
-/* 32-bit value read/written from the DPIO reg. */
-#define SB_DATA                0x02104 /* cedarview */
-/* 32-bit address of the DPIO reg to be read/written. */
-#define SB_ADDR                0x02108 /* cedarview */
-#define DPIO_CFG       0x02110 /* cedarview */
-# define DPIO_MODE_SELECT_1                    (1 << 3)
-# define DPIO_MODE_SELECT_0                    (1 << 2)
-# define DPIO_SFR_BYPASS                       (1 << 1)
-/* reset is active low */
-# define DPIO_CMN_RESET_N                      (1 << 0)
-
-/* Cedarview sideband registers */
-#define _SB_M_A                        0x8008
-#define _SB_M_B                        0x8028
-#define SB_M(pipe) _PIPE(pipe, _SB_M_A, _SB_M_B)
-# define SB_M_DIVIDER_MASK                     (0xFF << 24)
-# define SB_M_DIVIDER_SHIFT                    24
-
-#define _SB_N_VCO_A            0x8014
-#define _SB_N_VCO_B            0x8034
-#define SB_N_VCO(pipe) _PIPE(pipe, _SB_N_VCO_A, _SB_N_VCO_B)
-#define SB_N_VCO_SEL_MASK                      PSB_MASK(31, 30)
-#define SB_N_VCO_SEL_SHIFT                     30
-#define SB_N_DIVIDER_MASK                      PSB_MASK(29, 26)
-#define SB_N_DIVIDER_SHIFT                     26
-#define SB_N_CB_TUNE_MASK                      PSB_MASK(25, 24)
-#define SB_N_CB_TUNE_SHIFT                     24
-
-#define _SB_REF_A              0x8018
-#define _SB_REF_B              0x8038
-#define SB_REF_SFR(pipe)       _PIPE(pipe, _SB_REF_A, _SB_REF_B)
-
-#define _SB_P_A                        0x801c
-#define _SB_P_B                        0x803c
-#define SB_P(pipe) _PIPE(pipe, _SB_P_A, _SB_P_B)
-#define SB_P2_DIVIDER_MASK                     PSB_MASK(31, 30)
-#define SB_P2_DIVIDER_SHIFT                    30
-#define SB_P2_10                               0 /* HDMI, DP, DAC */
-#define SB_P2_5                                1 /* DAC */
-#define SB_P2_14                               2 /* LVDS single */
-#define SB_P2_7                                3 /* LVDS double */
-#define SB_P1_DIVIDER_MASK                     PSB_MASK(15, 12)
-#define SB_P1_DIVIDER_SHIFT                    12
-
-#define PSB_LANE0              0x120
-#define PSB_LANE1              0x220
-#define PSB_LANE2              0x2320
-#define PSB_LANE3              0x2420
-
-#define LANE_PLL_MASK          (0x7 << 20)
-#define LANE_PLL_ENABLE                (0x3 << 20)
-
-
-#endif
diff --git a/drivers/staging/gma500/psb_intel_sdvo.c b/drivers/staging/gma500/psb_intel_sdvo.c
deleted file mode 100644 (file)
index a4bad1a..0000000
+++ /dev/null
@@ -1,1293 +0,0 @@
-/*
- * Copyright (c) 2006-2007 Intel Corporation
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Authors:
- *     Eric Anholt <eric@anholt.net>
- */
-
-#include <linux/i2c.h>
-#include <linux/delay.h>
-/* #include <drm/drm_crtc.h> */
-#include <drm/drmP.h>
-#include "psb_drv.h"
-#include "psb_intel_drv.h"
-#include "psb_intel_reg.h"
-#include "psb_intel_sdvo_regs.h"
-
-struct psb_intel_sdvo_priv {
-       struct psb_intel_i2c_chan *i2c_bus;
-       int slaveaddr;
-       int output_device;
-
-       u16 active_outputs;
-
-       struct psb_intel_sdvo_caps caps;
-       int pixel_clock_min, pixel_clock_max;
-
-       int save_sdvo_mult;
-       u16 save_active_outputs;
-       struct psb_intel_sdvo_dtd save_input_dtd_1, save_input_dtd_2;
-       struct psb_intel_sdvo_dtd save_output_dtd[16];
-       u32 save_SDVOX;
-       u8 in_out_map[4];
-
-       u8 by_input_wiring;
-       u32 active_device;
-};
-
-/**
- * Writes the SDVOB or SDVOC with the given value, but always writes both
- * SDVOB and SDVOC to work around apparent hardware issues (according to
- * comments in the BIOS).
- */
-void psb_intel_sdvo_write_sdvox(struct psb_intel_output *psb_intel_output,
-                               u32 val)
-{
-       struct drm_device *dev = psb_intel_output->base.dev;
-       struct psb_intel_sdvo_priv *sdvo_priv = psb_intel_output->dev_priv;
-       u32 bval = val, cval = val;
-       int i;
-
-       if (sdvo_priv->output_device == SDVOB)
-               cval = REG_READ(SDVOC);
-       else
-               bval = REG_READ(SDVOB);
-       /*
-        * Write the registers twice for luck. Sometimes,
-        * writing them only once doesn't appear to 'stick'.
-        * The BIOS does this too. Yay, magic
-        */
-       for (i = 0; i < 2; i++) {
-               REG_WRITE(SDVOB, bval);
-               REG_READ(SDVOB);
-               REG_WRITE(SDVOC, cval);
-               REG_READ(SDVOC);
-       }
-}
-
-static bool psb_intel_sdvo_read_byte(
-                               struct psb_intel_output *psb_intel_output,
-                               u8 addr, u8 *ch)
-{
-       struct psb_intel_sdvo_priv *sdvo_priv = psb_intel_output->dev_priv;
-       u8 out_buf[2];
-       u8 buf[2];
-       int ret;
-
-       struct i2c_msg msgs[] = {
-               {
-                .addr = sdvo_priv->i2c_bus->slave_addr,
-                .flags = 0,
-                .len = 1,
-                .buf = out_buf,
-                },
-               {
-                .addr = sdvo_priv->i2c_bus->slave_addr,
-                .flags = I2C_M_RD,
-                .len = 1,
-                .buf = buf,
-                }
-       };
-
-       out_buf[0] = addr;
-       out_buf[1] = 0;
-
-       ret = i2c_transfer(&sdvo_priv->i2c_bus->adapter, msgs, 2);
-       if (ret == 2) {
-               *ch = buf[0];
-               return true;
-       }
-
-       return false;
-}
-
-static bool psb_intel_sdvo_write_byte(
-                       struct psb_intel_output *psb_intel_output,
-                       int addr, u8 ch)
-{
-       u8 out_buf[2];
-       struct i2c_msg msgs[] = {
-               {
-                .addr = psb_intel_output->i2c_bus->slave_addr,
-                .flags = 0,
-                .len = 2,
-                .buf = out_buf,
-                }
-       };
-
-       out_buf[0] = addr;
-       out_buf[1] = ch;
-
-       if (i2c_transfer(&psb_intel_output->i2c_bus->adapter, msgs, 1) == 1)
-               return true;
-       return false;
-}
-
-#define SDVO_CMD_NAME_ENTRY(cmd) {cmd, #cmd}
-/** Mapping of command numbers to names, for debug output */
-static const struct _sdvo_cmd_name {
-       u8 cmd;
-       char *name;
-} sdvo_cmd_names[] = {
-SDVO_CMD_NAME_ENTRY(SDVO_CMD_RESET),
-           SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_DEVICE_CAPS),
-           SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_FIRMWARE_REV),
-           SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_TRAINED_INPUTS),
-           SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_ACTIVE_OUTPUTS),
-           SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_ACTIVE_OUTPUTS),
-           SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_IN_OUT_MAP),
-           SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_IN_OUT_MAP),
-           SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_ATTACHED_DISPLAYS),
-           SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_HOT_PLUG_SUPPORT),
-           SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_ACTIVE_HOT_PLUG),
-           SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_ACTIVE_HOT_PLUG),
-           SDVO_CMD_NAME_ENTRY
-           (SDVO_CMD_GET_INTERRUPT_EVENT_SOURCE),
-           SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_TARGET_INPUT),
-           SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_TARGET_OUTPUT),
-           SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_INPUT_TIMINGS_PART1),
-           SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_INPUT_TIMINGS_PART2),
-           SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_INPUT_TIMINGS_PART1),
-           SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_INPUT_TIMINGS_PART2),
-           SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_INPUT_TIMINGS_PART1),
-           SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_OUTPUT_TIMINGS_PART1),
-           SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_OUTPUT_TIMINGS_PART2),
-           SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_OUTPUT_TIMINGS_PART1),
-           SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_OUTPUT_TIMINGS_PART2),
-           SDVO_CMD_NAME_ENTRY
-           (SDVO_CMD_CREATE_PREFERRED_INPUT_TIMING),
-           SDVO_CMD_NAME_ENTRY
-           (SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART1),
-           SDVO_CMD_NAME_ENTRY
-           (SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART2),
-           SDVO_CMD_NAME_ENTRY
-           (SDVO_CMD_GET_INPUT_PIXEL_CLOCK_RANGE),
-           SDVO_CMD_NAME_ENTRY
-           (SDVO_CMD_GET_OUTPUT_PIXEL_CLOCK_RANGE),
-           SDVO_CMD_NAME_ENTRY
-           (SDVO_CMD_GET_SUPPORTED_CLOCK_RATE_MULTS),
-           SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_CLOCK_RATE_MULT),
-           SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_CLOCK_RATE_MULT),
-           SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SUPPORTED_TV_FORMATS),
-           SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_TV_FORMAT),
-           SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_TV_FORMAT),
-           SDVO_CMD_NAME_ENTRY
-           (SDVO_CMD_SET_TV_RESOLUTION_SUPPORT),
-           SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_CONTROL_BUS_SWITCH),};
-
-#define SDVO_NAME(dev_priv) \
-                ((dev_priv)->output_device == SDVOB ? "SDVOB" : "SDVOC")
-#define SDVO_PRIV(output)   ((struct psb_intel_sdvo_priv *) (output)->dev_priv)
-
-static void psb_intel_sdvo_write_cmd(struct psb_intel_output *psb_intel_output,
-                                    u8 cmd,
-                                    void *args,
-                                    int args_len)
-{
-       struct psb_intel_sdvo_priv *sdvo_priv = psb_intel_output->dev_priv;
-       int i;
-
-       if (0) {
-               printk(KERN_DEBUG "%s: W: %02X ", SDVO_NAME(sdvo_priv), cmd);
-               for (i = 0; i < args_len; i++)
-                       printk(KERN_CONT "%02X ", ((u8 *) args)[i]);
-               for (; i < 8; i++)
-                       printk(KERN_CONT "   ");
-               for (i = 0;
-                    i <
-                    sizeof(sdvo_cmd_names) / sizeof(sdvo_cmd_names[0]);
-                    i++) {
-                       if (cmd == sdvo_cmd_names[i].cmd) {
-                               printk(KERN_CONT
-                                       "(%s)", sdvo_cmd_names[i].name);
-                               break;
-                       }
-               }
-               if (i ==
-                   sizeof(sdvo_cmd_names) / sizeof(sdvo_cmd_names[0]))
-                       printk(KERN_CONT "(%02X)", cmd);
-               printk(KERN_CONT "\n");
-       }
-
-       for (i = 0; i < args_len; i++) {
-               psb_intel_sdvo_write_byte(psb_intel_output,
-                                       SDVO_I2C_ARG_0 - i,
-                                       ((u8 *) args)[i]);
-       }
-
-       psb_intel_sdvo_write_byte(psb_intel_output, SDVO_I2C_OPCODE, cmd);
-}
-
-static const char *const cmd_status_names[] = {
-       "Power on",
-       "Success",
-       "Not supported",
-       "Invalid arg",
-       "Pending",
-       "Target not specified",
-       "Scaling not supported"
-};
-
-static u8 psb_intel_sdvo_read_response(
-                               struct psb_intel_output *psb_intel_output,
-                               void *response, int response_len)
-{
-       struct psb_intel_sdvo_priv *sdvo_priv = psb_intel_output->dev_priv;
-       int i;
-       u8 status;
-       u8 retry = 50;
-
-       while (retry--) {
-               /* Read the command response */
-               for (i = 0; i < response_len; i++) {
-                       psb_intel_sdvo_read_byte(psb_intel_output,
-                                            SDVO_I2C_RETURN_0 + i,
-                                            &((u8 *) response)[i]);
-               }
-
-               /* read the return status */
-               psb_intel_sdvo_read_byte(psb_intel_output,
-                                        SDVO_I2C_CMD_STATUS,
-                                        &status);
-
-               if (0) {
-                       pr_debug("%s: R: ", SDVO_NAME(sdvo_priv));
-                       for (i = 0; i < response_len; i++)
-                               printk(KERN_CONT "%02X ", ((u8 *) response)[i]);
-                       for (; i < 8; i++)
-                               printk("   ");
-                       if (status <= SDVO_CMD_STATUS_SCALING_NOT_SUPP)
-                               printk(KERN_CONT "(%s)",
-                                        cmd_status_names[status]);
-                       else
-                               printk(KERN_CONT "(??? %d)", status);
-                       printk(KERN_CONT "\n");
-               }
-
-               if (status != SDVO_CMD_STATUS_PENDING)
-                       return status;
-
-               mdelay(50);
-       }
-
-       return status;
-}
-
-int psb_intel_sdvo_get_pixel_multiplier(struct drm_display_mode *mode)
-{
-       if (mode->clock >= 100000)
-               return 1;
-       else if (mode->clock >= 50000)
-               return 2;
-       else
-               return 4;
-}
-
-/**
- * Don't check status code from this as it switches the bus back to the
- * SDVO chips which defeats the purpose of doing a bus switch in the first
- * place.
- */
-void psb_intel_sdvo_set_control_bus_switch(
-                               struct psb_intel_output *psb_intel_output,
-                               u8 target)
-{
-       psb_intel_sdvo_write_cmd(psb_intel_output,
-                                SDVO_CMD_SET_CONTROL_BUS_SWITCH,
-                                &target,
-                                1);
-}
-
-static bool psb_intel_sdvo_set_target_input(
-                               struct psb_intel_output *psb_intel_output,
-                               bool target_0, bool target_1)
-{
-       struct psb_intel_sdvo_set_target_input_args targets = { 0 };
-       u8 status;
-
-       if (target_0 && target_1)
-               return SDVO_CMD_STATUS_NOTSUPP;
-
-       if (target_1)
-               targets.target_1 = 1;
-
-       psb_intel_sdvo_write_cmd(psb_intel_output, SDVO_CMD_SET_TARGET_INPUT,
-                            &targets, sizeof(targets));
-
-       status = psb_intel_sdvo_read_response(psb_intel_output, NULL, 0);
-
-       return status == SDVO_CMD_STATUS_SUCCESS;
-}
-
-/**
- * Return whether each input is trained.
- *
- * This function is making an assumption about the layout of the response,
- * which should be checked against the docs.
- */
-static bool psb_intel_sdvo_get_trained_inputs(struct psb_intel_output
-                                         *psb_intel_output, bool *input_1,
-                                         bool *input_2)
-{
-       struct psb_intel_sdvo_get_trained_inputs_response response;
-       u8 status;
-
-       psb_intel_sdvo_write_cmd(psb_intel_output, SDVO_CMD_GET_TRAINED_INPUTS,
-                            NULL, 0);
-       status =
-           psb_intel_sdvo_read_response(psb_intel_output, &response,
-                                    sizeof(response));
-       if (status != SDVO_CMD_STATUS_SUCCESS)
-               return false;
-
-       *input_1 = response.input0_trained;
-       *input_2 = response.input1_trained;
-       return true;
-}
-
-static bool psb_intel_sdvo_get_active_outputs(struct psb_intel_output
-                                         *psb_intel_output, u16 *outputs)
-{
-       u8 status;
-
-       psb_intel_sdvo_write_cmd(psb_intel_output, SDVO_CMD_GET_ACTIVE_OUTPUTS,
-                            NULL, 0);
-       status =
-           psb_intel_sdvo_read_response(psb_intel_output, outputs,
-                                    sizeof(*outputs));
-
-       return status == SDVO_CMD_STATUS_SUCCESS;
-}
-
-static bool psb_intel_sdvo_set_active_outputs(struct psb_intel_output
-                                         *psb_intel_output, u16 outputs)
-{
-       u8 status;
-
-       psb_intel_sdvo_write_cmd(psb_intel_output, SDVO_CMD_SET_ACTIVE_OUTPUTS,
-                            &outputs, sizeof(outputs));
-       status = psb_intel_sdvo_read_response(psb_intel_output, NULL, 0);
-       return status == SDVO_CMD_STATUS_SUCCESS;
-}
-
-static bool psb_intel_sdvo_set_encoder_power_state(struct psb_intel_output
-                                              *psb_intel_output, int mode)
-{
-       u8 status, state = SDVO_ENCODER_STATE_ON;
-
-       switch (mode) {
-       case DRM_MODE_DPMS_ON:
-               state = SDVO_ENCODER_STATE_ON;
-               break;
-       case DRM_MODE_DPMS_STANDBY:
-               state = SDVO_ENCODER_STATE_STANDBY;
-               break;
-       case DRM_MODE_DPMS_SUSPEND:
-               state = SDVO_ENCODER_STATE_SUSPEND;
-               break;
-       case DRM_MODE_DPMS_OFF:
-               state = SDVO_ENCODER_STATE_OFF;
-               break;
-       }
-
-       psb_intel_sdvo_write_cmd(psb_intel_output,
-                            SDVO_CMD_SET_ENCODER_POWER_STATE, &state,
-                            sizeof(state));
-       status = psb_intel_sdvo_read_response(psb_intel_output, NULL, 0);
-
-       return status == SDVO_CMD_STATUS_SUCCESS;
-}
-
-static bool psb_intel_sdvo_get_input_pixel_clock_range(struct psb_intel_output
-                                                  *psb_intel_output,
-                                                  int *clock_min,
-                                                  int *clock_max)
-{
-       struct psb_intel_sdvo_pixel_clock_range clocks;
-       u8 status;
-
-       psb_intel_sdvo_write_cmd(psb_intel_output,
-                            SDVO_CMD_GET_INPUT_PIXEL_CLOCK_RANGE, NULL,
-                            0);
-
-       status =
-           psb_intel_sdvo_read_response(psb_intel_output, &clocks,
-                                    sizeof(clocks));
-
-       if (status != SDVO_CMD_STATUS_SUCCESS)
-               return false;
-
-       /* Convert the values from units of 10 kHz to kHz. */
-       *clock_min = clocks.min * 10;
-       *clock_max = clocks.max * 10;
-
-       return true;
-}
-
-static bool psb_intel_sdvo_set_target_output(
-                               struct psb_intel_output *psb_intel_output,
-                               u16 outputs)
-{
-       u8 status;
-
-       psb_intel_sdvo_write_cmd(psb_intel_output, SDVO_CMD_SET_TARGET_OUTPUT,
-                            &outputs, sizeof(outputs));
-
-       status = psb_intel_sdvo_read_response(psb_intel_output, NULL, 0);
-       return status == SDVO_CMD_STATUS_SUCCESS;
-}
-
-static bool psb_intel_sdvo_get_timing(struct psb_intel_output *psb_intel_output,
-                                 u8 cmd, struct psb_intel_sdvo_dtd *dtd)
-{
-       u8 status;
-
-       psb_intel_sdvo_write_cmd(psb_intel_output, cmd, NULL, 0);
-       status = psb_intel_sdvo_read_response(psb_intel_output, &dtd->part1,
-                                         sizeof(dtd->part1));
-       if (status != SDVO_CMD_STATUS_SUCCESS)
-               return false;
-
-       psb_intel_sdvo_write_cmd(psb_intel_output, cmd + 1, NULL, 0);
-       status = psb_intel_sdvo_read_response(psb_intel_output, &dtd->part2,
-                                         sizeof(dtd->part2));
-       if (status != SDVO_CMD_STATUS_SUCCESS)
-               return false;
-
-       return true;
-}
-
-static bool psb_intel_sdvo_get_input_timing(
-                               struct psb_intel_output *psb_intel_output,
-                               struct psb_intel_sdvo_dtd *dtd)
-{
-       return psb_intel_sdvo_get_timing(psb_intel_output,
-                                    SDVO_CMD_GET_INPUT_TIMINGS_PART1,
-                                    dtd);
-}
-
-static bool psb_intel_sdvo_set_timing(
-                               struct psb_intel_output *psb_intel_output,
-                               u8 cmd,
-                               struct psb_intel_sdvo_dtd *dtd)
-{
-       u8 status;
-
-       psb_intel_sdvo_write_cmd(psb_intel_output, cmd, &dtd->part1,
-                            sizeof(dtd->part1));
-       status = psb_intel_sdvo_read_response(psb_intel_output, NULL, 0);
-       if (status != SDVO_CMD_STATUS_SUCCESS)
-               return false;
-
-       psb_intel_sdvo_write_cmd(psb_intel_output, cmd + 1, &dtd->part2,
-                            sizeof(dtd->part2));
-       status = psb_intel_sdvo_read_response(psb_intel_output, NULL, 0);
-       if (status != SDVO_CMD_STATUS_SUCCESS)
-               return false;
-
-       return true;
-}
-
-static bool psb_intel_sdvo_set_input_timing(
-                               struct psb_intel_output *psb_intel_output,
-                               struct psb_intel_sdvo_dtd *dtd)
-{
-       return psb_intel_sdvo_set_timing(psb_intel_output,
-                                    SDVO_CMD_SET_INPUT_TIMINGS_PART1,
-                                    dtd);
-}
-
-static bool psb_intel_sdvo_set_output_timing(
-                               struct psb_intel_output *psb_intel_output,
-                               struct psb_intel_sdvo_dtd *dtd)
-{
-       return psb_intel_sdvo_set_timing(psb_intel_output,
-                                    SDVO_CMD_SET_OUTPUT_TIMINGS_PART1,
-                                    dtd);
-}
-
-static int psb_intel_sdvo_get_clock_rate_mult(struct psb_intel_output
-                                               *psb_intel_output)
-{
-       u8 response, status;
-
-       psb_intel_sdvo_write_cmd(psb_intel_output,
-                                SDVO_CMD_GET_CLOCK_RATE_MULT,
-                                NULL,
-                                0);
-
-       status = psb_intel_sdvo_read_response(psb_intel_output, &response, 1);
-
-       if (status != SDVO_CMD_STATUS_SUCCESS) {
-               DRM_DEBUG("Couldn't get SDVO clock rate multiplier\n");
-               return SDVO_CLOCK_RATE_MULT_1X;
-       } else {
-               DRM_DEBUG("Current clock rate multiplier: %d\n", response);
-       }
-
-       return response;
-}
-
-static bool psb_intel_sdvo_set_clock_rate_mult(struct psb_intel_output
-                                               *psb_intel_output, u8 val)
-{
-       u8 status;
-
-       psb_intel_sdvo_write_cmd(psb_intel_output,
-                               SDVO_CMD_SET_CLOCK_RATE_MULT,
-                               &val,
-                               1);
-
-       status = psb_intel_sdvo_read_response(psb_intel_output, NULL, 0);
-       if (status != SDVO_CMD_STATUS_SUCCESS)
-               return false;
-
-       return true;
-}
-
-static bool psb_sdvo_set_current_inoutmap(struct psb_intel_output *output,
-                                         u32 in0outputmask,
-                                         u32 in1outputmask)
-{
-       u8 byArgs[4];
-       u8 status;
-       int i;
-       struct psb_intel_sdvo_priv *sdvo_priv = output->dev_priv;
-
-       /* Make all fields of the  args/ret to zero */
-       memset(byArgs, 0, sizeof(byArgs));
-
-       /* Fill up the argument values; */
-       byArgs[0] = (u8) (in0outputmask & 0xFF);
-       byArgs[1] = (u8) ((in0outputmask >> 8) & 0xFF);
-       byArgs[2] = (u8) (in1outputmask & 0xFF);
-       byArgs[3] = (u8) ((in1outputmask >> 8) & 0xFF);
-
-
-       /*save inoutmap arg here*/
-       for (i = 0; i < 4; i++)
-               sdvo_priv->in_out_map[i] = byArgs[0];
-
-       psb_intel_sdvo_write_cmd(output, SDVO_CMD_SET_IN_OUT_MAP, byArgs, 4);
-       status = psb_intel_sdvo_read_response(output, NULL, 0);
-
-       if (status != SDVO_CMD_STATUS_SUCCESS)
-               return false;
-       return true;
-}
-
-
-static void psb_intel_sdvo_set_iomap(struct psb_intel_output *output)
-{
-       u32 dwCurrentSDVOIn0 = 0;
-       u32 dwCurrentSDVOIn1 = 0;
-       u32 dwDevMask = 0;
-
-
-       struct psb_intel_sdvo_priv *sdvo_priv = output->dev_priv;
-
-       /* Please DO NOT change the following code. */
-       /* SDVOB_IN0 or SDVOB_IN1 ==> sdvo_in0 */
-       /* SDVOC_IN0 or SDVOC_IN1 ==> sdvo_in1 */
-       if (sdvo_priv->by_input_wiring & (SDVOB_IN0 | SDVOC_IN0)) {
-               switch (sdvo_priv->active_device) {
-               case SDVO_DEVICE_LVDS:
-                       dwDevMask = SDVO_OUTPUT_LVDS0 | SDVO_OUTPUT_LVDS1;
-                       break;
-               case SDVO_DEVICE_TMDS:
-                       dwDevMask = SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_TMDS1;
-                       break;
-               case SDVO_DEVICE_TV:
-                       dwDevMask =
-                       SDVO_OUTPUT_YPRPB0 | SDVO_OUTPUT_SVID0 |
-                       SDVO_OUTPUT_CVBS0 | SDVO_OUTPUT_YPRPB1 |
-                       SDVO_OUTPUT_SVID1 | SDVO_OUTPUT_CVBS1 |
-                       SDVO_OUTPUT_SCART0 | SDVO_OUTPUT_SCART1;
-                       break;
-               case SDVO_DEVICE_CRT:
-                       dwDevMask = SDVO_OUTPUT_RGB0 | SDVO_OUTPUT_RGB1;
-                       break;
-               }
-               dwCurrentSDVOIn0 = (sdvo_priv->active_outputs & dwDevMask);
-       } else if (sdvo_priv->by_input_wiring & (SDVOB_IN1 | SDVOC_IN1)) {
-               switch (sdvo_priv->active_device) {
-               case SDVO_DEVICE_LVDS:
-                       dwDevMask = SDVO_OUTPUT_LVDS0 | SDVO_OUTPUT_LVDS1;
-                       break;
-               case SDVO_DEVICE_TMDS:
-                       dwDevMask = SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_TMDS1;
-                       break;
-               case SDVO_DEVICE_TV:
-                       dwDevMask =
-                       SDVO_OUTPUT_YPRPB0 | SDVO_OUTPUT_SVID0 |
-                       SDVO_OUTPUT_CVBS0 | SDVO_OUTPUT_YPRPB1 |
-                       SDVO_OUTPUT_SVID1 | SDVO_OUTPUT_CVBS1 |
-                       SDVO_OUTPUT_SCART0 | SDVO_OUTPUT_SCART1;
-                       break;
-               case SDVO_DEVICE_CRT:
-                       dwDevMask = SDVO_OUTPUT_RGB0 | SDVO_OUTPUT_RGB1;
-                       break;
-               }
-               dwCurrentSDVOIn1 = (sdvo_priv->active_outputs & dwDevMask);
-       }
-
-       psb_sdvo_set_current_inoutmap(output, dwCurrentSDVOIn0,
-                                         dwCurrentSDVOIn1);
-}
-
-
-static bool psb_intel_sdvo_mode_fixup(struct drm_encoder *encoder,
-                                 struct drm_display_mode *mode,
-                                 struct drm_display_mode *adjusted_mode)
-{
-       /* Make the CRTC code factor in the SDVO pixel multiplier.  The SDVO
-        * device will be told of the multiplier during mode_set.
-        */
-       adjusted_mode->clock *= psb_intel_sdvo_get_pixel_multiplier(mode);
-       return true;
-}
-
-static void psb_intel_sdvo_mode_set(struct drm_encoder *encoder,
-                               struct drm_display_mode *mode,
-                               struct drm_display_mode *adjusted_mode)
-{
-       struct drm_device *dev = encoder->dev;
-       struct drm_crtc *crtc = encoder->crtc;
-       struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
-       struct psb_intel_output *psb_intel_output =
-                                       enc_to_psb_intel_output(encoder);
-       struct psb_intel_sdvo_priv *sdvo_priv = psb_intel_output->dev_priv;
-       u16 width, height;
-       u16 h_blank_len, h_sync_len, v_blank_len, v_sync_len;
-       u16 h_sync_offset, v_sync_offset;
-       u32 sdvox;
-       struct psb_intel_sdvo_dtd output_dtd;
-       int sdvo_pixel_multiply;
-
-       if (!mode)
-               return;
-
-       psb_intel_sdvo_set_target_output(psb_intel_output, 0);
-
-       width = mode->crtc_hdisplay;
-       height = mode->crtc_vdisplay;
-
-       /* do some mode translations */
-       h_blank_len = mode->crtc_hblank_end - mode->crtc_hblank_start;
-       h_sync_len = mode->crtc_hsync_end - mode->crtc_hsync_start;
-
-       v_blank_len = mode->crtc_vblank_end - mode->crtc_vblank_start;
-       v_sync_len = mode->crtc_vsync_end - mode->crtc_vsync_start;
-
-       h_sync_offset = mode->crtc_hsync_start - mode->crtc_hblank_start;
-       v_sync_offset = mode->crtc_vsync_start - mode->crtc_vblank_start;
-
-       output_dtd.part1.clock = mode->clock / 10;
-       output_dtd.part1.h_active = width & 0xff;
-       output_dtd.part1.h_blank = h_blank_len & 0xff;
-       output_dtd.part1.h_high = (((width >> 8) & 0xf) << 4) |
-           ((h_blank_len >> 8) & 0xf);
-       output_dtd.part1.v_active = height & 0xff;
-       output_dtd.part1.v_blank = v_blank_len & 0xff;
-       output_dtd.part1.v_high = (((height >> 8) & 0xf) << 4) |
-           ((v_blank_len >> 8) & 0xf);
-
-       output_dtd.part2.h_sync_off = h_sync_offset;
-       output_dtd.part2.h_sync_width = h_sync_len & 0xff;
-       output_dtd.part2.v_sync_off_width = (v_sync_offset & 0xf) << 4 |
-           (v_sync_len & 0xf);
-       output_dtd.part2.sync_off_width_high =
-           ((h_sync_offset & 0x300) >> 2) | ((h_sync_len & 0x300) >> 4) |
-           ((v_sync_offset & 0x30) >> 2) | ((v_sync_len & 0x30) >> 4);
-
-       output_dtd.part2.dtd_flags = 0x18;
-       if (mode->flags & DRM_MODE_FLAG_PHSYNC)
-               output_dtd.part2.dtd_flags |= 0x2;
-       if (mode->flags & DRM_MODE_FLAG_PVSYNC)
-               output_dtd.part2.dtd_flags |= 0x4;
-
-       output_dtd.part2.sdvo_flags = 0;
-       output_dtd.part2.v_sync_off_high = v_sync_offset & 0xc0;
-       output_dtd.part2.reserved = 0;
-
-       /* Set the output timing to the screen */
-       psb_intel_sdvo_set_target_output(psb_intel_output,
-                                    sdvo_priv->active_outputs);
-
-       /* Set the input timing to the screen. Assume always input 0. */
-       psb_intel_sdvo_set_target_input(psb_intel_output, true, false);
-
-       psb_intel_sdvo_set_output_timing(psb_intel_output, &output_dtd);
-
-       /* We would like to use i830_sdvo_create_preferred_input_timing() to
-        * provide the device with a timing it can support, if it supports that
-        * feature.  However, presumably we would need to adjust the CRTC to
-        * output the preferred timing, and we don't support that currently.
-        */
-       psb_intel_sdvo_set_input_timing(psb_intel_output, &output_dtd);
-
-       switch (psb_intel_sdvo_get_pixel_multiplier(mode)) {
-       case 1:
-               psb_intel_sdvo_set_clock_rate_mult(psb_intel_output,
-                                              SDVO_CLOCK_RATE_MULT_1X);
-               break;
-       case 2:
-               psb_intel_sdvo_set_clock_rate_mult(psb_intel_output,
-                                              SDVO_CLOCK_RATE_MULT_2X);
-               break;
-       case 4:
-               psb_intel_sdvo_set_clock_rate_mult(psb_intel_output,
-                                              SDVO_CLOCK_RATE_MULT_4X);
-               break;
-       }
-
-       /* Set the SDVO control regs. */
-       sdvox = REG_READ(sdvo_priv->output_device);
-       switch (sdvo_priv->output_device) {
-       case SDVOB:
-               sdvox &= SDVOB_PRESERVE_MASK;
-               break;
-       case SDVOC:
-               sdvox &= SDVOC_PRESERVE_MASK;
-               break;
-       }
-       sdvox |= (9 << 19) | SDVO_BORDER_ENABLE;
-       if (psb_intel_crtc->pipe == 1)
-               sdvox |= SDVO_PIPE_B_SELECT;
-
-       sdvo_pixel_multiply = psb_intel_sdvo_get_pixel_multiplier(mode);
-
-       psb_intel_sdvo_write_sdvox(psb_intel_output, sdvox);
-
-        psb_intel_sdvo_set_iomap(psb_intel_output);
-}
-
-static void psb_intel_sdvo_dpms(struct drm_encoder *encoder, int mode)
-{
-       struct drm_device *dev = encoder->dev;
-       struct psb_intel_output *psb_intel_output =
-                                       enc_to_psb_intel_output(encoder);
-       struct psb_intel_sdvo_priv *sdvo_priv = psb_intel_output->dev_priv;
-       u32 temp;
-
-       if (mode != DRM_MODE_DPMS_ON) {
-               psb_intel_sdvo_set_active_outputs(psb_intel_output, 0);
-               if (0)
-                       psb_intel_sdvo_set_encoder_power_state(
-                                                       psb_intel_output,
-                                                       mode);
-
-               if (mode == DRM_MODE_DPMS_OFF) {
-                       temp = REG_READ(sdvo_priv->output_device);
-                       if ((temp & SDVO_ENABLE) != 0) {
-                               psb_intel_sdvo_write_sdvox(psb_intel_output,
-                                                      temp &
-                                                      ~SDVO_ENABLE);
-                       }
-               }
-       } else {
-               bool input1, input2;
-               int i;
-               u8 status;
-
-               temp = REG_READ(sdvo_priv->output_device);
-               if ((temp & SDVO_ENABLE) == 0)
-                       psb_intel_sdvo_write_sdvox(psb_intel_output,
-                                              temp | SDVO_ENABLE);
-               for (i = 0; i < 2; i++)
-                       psb_intel_wait_for_vblank(dev);
-
-               status =
-                   psb_intel_sdvo_get_trained_inputs(psb_intel_output,
-                                                       &input1,
-                                                       &input2);
-
-
-               /* Warn if the device reported failure to sync.
-                * A lot of SDVO devices fail to notify of sync, but it's
-                * a given it the status is a success, we succeeded.
-                */
-               if (status == SDVO_CMD_STATUS_SUCCESS && !input1) {
-                       DRM_DEBUG
-                           ("First %s output reported failure to sync\n",
-                            SDVO_NAME(sdvo_priv));
-               }
-
-               if (0)
-                       psb_intel_sdvo_set_encoder_power_state(
-                                                       psb_intel_output,
-                                                       mode);
-               psb_intel_sdvo_set_active_outputs(psb_intel_output,
-                                             sdvo_priv->active_outputs);
-       }
-       return;
-}
-
-static void psb_intel_sdvo_save(struct drm_connector *connector)
-{
-       struct drm_device *dev = connector->dev;
-       struct psb_intel_output *psb_intel_output =
-                                       to_psb_intel_output(connector);
-       struct psb_intel_sdvo_priv *sdvo_priv = psb_intel_output->dev_priv;
-       /*int o;*/
-
-       sdvo_priv->save_sdvo_mult =
-           psb_intel_sdvo_get_clock_rate_mult(psb_intel_output);
-       psb_intel_sdvo_get_active_outputs(psb_intel_output,
-                                     &sdvo_priv->save_active_outputs);
-
-       if (sdvo_priv->caps.sdvo_inputs_mask & 0x1) {
-               psb_intel_sdvo_set_target_input(psb_intel_output,
-                                               true,
-                                               false);
-               psb_intel_sdvo_get_input_timing(psb_intel_output,
-                                           &sdvo_priv->save_input_dtd_1);
-       }
-
-       if (sdvo_priv->caps.sdvo_inputs_mask & 0x2) {
-               psb_intel_sdvo_set_target_input(psb_intel_output,
-                                               false,
-                                               true);
-               psb_intel_sdvo_get_input_timing(psb_intel_output,
-                                           &sdvo_priv->save_input_dtd_2);
-       }
-       sdvo_priv->save_SDVOX = REG_READ(sdvo_priv->output_device);
-
-       /*TODO: save the in_out_map state*/
-}
-
-static void psb_intel_sdvo_restore(struct drm_connector *connector)
-{
-       struct drm_device *dev = connector->dev;
-       struct psb_intel_output *psb_intel_output =
-                                       to_psb_intel_output(connector);
-       struct psb_intel_sdvo_priv *sdvo_priv = psb_intel_output->dev_priv;
-       /*int o;*/
-       int i;
-       bool input1, input2;
-       u8 status;
-
-       psb_intel_sdvo_set_active_outputs(psb_intel_output, 0);
-
-       if (sdvo_priv->caps.sdvo_inputs_mask & 0x1) {
-               psb_intel_sdvo_set_target_input(psb_intel_output, true, false);
-               psb_intel_sdvo_set_input_timing(psb_intel_output,
-                                           &sdvo_priv->save_input_dtd_1);
-       }
-
-       if (sdvo_priv->caps.sdvo_inputs_mask & 0x2) {
-               psb_intel_sdvo_set_target_input(psb_intel_output, false, true);
-               psb_intel_sdvo_set_input_timing(psb_intel_output,
-                                           &sdvo_priv->save_input_dtd_2);
-       }
-
-       psb_intel_sdvo_set_clock_rate_mult(psb_intel_output,
-                                      sdvo_priv->save_sdvo_mult);
-
-       REG_WRITE(sdvo_priv->output_device, sdvo_priv->save_SDVOX);
-
-       if (sdvo_priv->save_SDVOX & SDVO_ENABLE) {
-               for (i = 0; i < 2; i++)
-                       psb_intel_wait_for_vblank(dev);
-               status =
-                   psb_intel_sdvo_get_trained_inputs(psb_intel_output,
-                                                       &input1,
-                                                       &input2);
-               if (status == SDVO_CMD_STATUS_SUCCESS && !input1)
-                       DRM_DEBUG
-                           ("First %s output reported failure to sync\n",
-                            SDVO_NAME(sdvo_priv));
-       }
-
-       psb_intel_sdvo_set_active_outputs(psb_intel_output,
-                                     sdvo_priv->save_active_outputs);
-
-       /*TODO: restore in_out_map*/
-       psb_intel_sdvo_write_cmd(psb_intel_output,
-                                SDVO_CMD_SET_IN_OUT_MAP,
-                                sdvo_priv->in_out_map,
-                                4);
-
-       psb_intel_sdvo_read_response(psb_intel_output, NULL, 0);
-}
-
-static int psb_intel_sdvo_mode_valid(struct drm_connector *connector,
-                                struct drm_display_mode *mode)
-{
-       struct psb_intel_output *psb_intel_output =
-                               to_psb_intel_output(connector);
-       struct psb_intel_sdvo_priv *sdvo_priv = psb_intel_output->dev_priv;
-
-       if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
-               return MODE_NO_DBLESCAN;
-
-       if (sdvo_priv->pixel_clock_min > mode->clock)
-               return MODE_CLOCK_LOW;
-
-       if (sdvo_priv->pixel_clock_max < mode->clock)
-               return MODE_CLOCK_HIGH;
-
-       return MODE_OK;
-}
-
-static bool psb_intel_sdvo_get_capabilities(
-                               struct psb_intel_output *psb_intel_output,
-                               struct psb_intel_sdvo_caps *caps)
-{
-       u8 status;
-
-       psb_intel_sdvo_write_cmd(psb_intel_output,
-                                SDVO_CMD_GET_DEVICE_CAPS,
-                                NULL,
-                                0);
-       status = psb_intel_sdvo_read_response(psb_intel_output,
-                                               caps,
-                                               sizeof(*caps));
-       if (status != SDVO_CMD_STATUS_SUCCESS)
-               return false;
-
-       return true;
-}
-
-struct drm_connector *psb_intel_sdvo_find(struct drm_device *dev, int sdvoB)
-{
-       struct drm_connector *connector = NULL;
-       struct psb_intel_output *iout = NULL;
-       struct psb_intel_sdvo_priv *sdvo;
-
-       /* find the sdvo connector */
-       list_for_each_entry(connector, &dev->mode_config.connector_list,
-                           head) {
-               iout = to_psb_intel_output(connector);
-
-               if (iout->type != INTEL_OUTPUT_SDVO)
-                       continue;
-
-               sdvo = iout->dev_priv;
-
-               if (sdvo->output_device == SDVOB && sdvoB)
-                       return connector;
-
-               if (sdvo->output_device == SDVOC && !sdvoB)
-                       return connector;
-
-       }
-
-       return NULL;
-}
-
-int psb_intel_sdvo_supports_hotplug(struct drm_connector *connector)
-{
-       u8 response[2];
-       u8 status;
-       struct psb_intel_output *psb_intel_output;
-
-       if (!connector)
-               return 0;
-
-       psb_intel_output = to_psb_intel_output(connector);
-
-       psb_intel_sdvo_write_cmd(psb_intel_output,
-                                SDVO_CMD_GET_HOT_PLUG_SUPPORT,
-                                NULL,
-                                0);
-       status = psb_intel_sdvo_read_response(psb_intel_output,
-                                               &response,
-                                               2);
-
-       if (response[0] != 0)
-               return 1;
-
-       return 0;
-}
-
-void psb_intel_sdvo_set_hotplug(struct drm_connector *connector, int on)
-{
-       u8 response[2];
-       u8 status;
-       struct psb_intel_output *psb_intel_output =
-                                       to_psb_intel_output(connector);
-
-       psb_intel_sdvo_write_cmd(psb_intel_output,
-                                SDVO_CMD_GET_ACTIVE_HOT_PLUG,
-                                NULL,
-                                0);
-       psb_intel_sdvo_read_response(psb_intel_output, &response, 2);
-
-       if (on) {
-               psb_intel_sdvo_write_cmd(psb_intel_output,
-                                    SDVO_CMD_GET_HOT_PLUG_SUPPORT, NULL,
-                                    0);
-               status = psb_intel_sdvo_read_response(psb_intel_output,
-                                                     &response,
-                                                     2);
-
-               psb_intel_sdvo_write_cmd(psb_intel_output,
-                                    SDVO_CMD_SET_ACTIVE_HOT_PLUG,
-                                    &response, 2);
-       } else {
-               response[0] = 0;
-               response[1] = 0;
-               psb_intel_sdvo_write_cmd(psb_intel_output,
-                                    SDVO_CMD_SET_ACTIVE_HOT_PLUG,
-                                    &response, 2);
-       }
-
-       psb_intel_sdvo_write_cmd(psb_intel_output,
-                                SDVO_CMD_GET_ACTIVE_HOT_PLUG,
-                                NULL,
-                                0);
-       psb_intel_sdvo_read_response(psb_intel_output, &response, 2);
-}
-
-static enum drm_connector_status psb_intel_sdvo_detect(struct drm_connector
-                                                  *connector, bool force)
-{
-       u8 response[2];
-       u8 status;
-       struct psb_intel_output *psb_intel_output =
-                                       to_psb_intel_output(connector);
-
-       psb_intel_sdvo_write_cmd(psb_intel_output,
-                                SDVO_CMD_GET_ATTACHED_DISPLAYS,
-                                NULL,
-                                0);
-       status = psb_intel_sdvo_read_response(psb_intel_output, &response, 2);
-
-       DRM_DEBUG("SDVO response %d %d\n", response[0], response[1]);
-       if ((response[0] != 0) || (response[1] != 0))
-               return connector_status_connected;
-       else
-               return connector_status_disconnected;
-}
-
-static int psb_intel_sdvo_get_modes(struct drm_connector *connector)
-{
-       struct psb_intel_output *psb_intel_output =
-                                       to_psb_intel_output(connector);
-
-       /* set the bus switch and get the modes */
-       psb_intel_sdvo_set_control_bus_switch(psb_intel_output,
-                                         SDVO_CONTROL_BUS_DDC2);
-       psb_intel_ddc_get_modes(psb_intel_output);
-
-       if (list_empty(&connector->probed_modes))
-               return 0;
-       return 1;
-}
-
-static void psb_intel_sdvo_destroy(struct drm_connector *connector)
-{
-       struct psb_intel_output *psb_intel_output =
-                               to_psb_intel_output(connector);
-
-       if (psb_intel_output->i2c_bus)
-               psb_intel_i2c_destroy(psb_intel_output->i2c_bus);
-       drm_sysfs_connector_remove(connector);
-       drm_connector_cleanup(connector);
-       kfree(psb_intel_output);
-}
-
-static const struct drm_encoder_helper_funcs psb_intel_sdvo_helper_funcs = {
-       .dpms = psb_intel_sdvo_dpms,
-       .mode_fixup = psb_intel_sdvo_mode_fixup,
-       .prepare = psb_intel_encoder_prepare,
-       .mode_set = psb_intel_sdvo_mode_set,
-       .commit = psb_intel_encoder_commit,
-};
-
-static const struct drm_connector_funcs psb_intel_sdvo_connector_funcs = {
-       .dpms = drm_helper_connector_dpms,
-       .save = psb_intel_sdvo_save,
-       .restore = psb_intel_sdvo_restore,
-       .detect = psb_intel_sdvo_detect,
-       .fill_modes = drm_helper_probe_single_connector_modes,
-       .destroy = psb_intel_sdvo_destroy,
-};
-
-static const struct drm_connector_helper_funcs
-                               psb_intel_sdvo_connector_helper_funcs = {
-       .get_modes = psb_intel_sdvo_get_modes,
-       .mode_valid = psb_intel_sdvo_mode_valid,
-       .best_encoder = psb_intel_best_encoder,
-};
-
-void psb_intel_sdvo_enc_destroy(struct drm_encoder *encoder)
-{
-       drm_encoder_cleanup(encoder);
-}
-
-static const struct drm_encoder_funcs psb_intel_sdvo_enc_funcs = {
-       .destroy = psb_intel_sdvo_enc_destroy,
-};
-
-
-void psb_intel_sdvo_init(struct drm_device *dev, int output_device)
-{
-       struct drm_connector *connector;
-       struct psb_intel_output *psb_intel_output;
-       struct psb_intel_sdvo_priv *sdvo_priv;
-       struct psb_intel_i2c_chan *i2cbus = NULL;
-       int connector_type;
-       u8 ch[0x40];
-       int i;
-       int encoder_type, output_id;
-
-       psb_intel_output =
-           kcalloc(sizeof(struct psb_intel_output) +
-                   sizeof(struct psb_intel_sdvo_priv), 1, GFP_KERNEL);
-       if (!psb_intel_output)
-               return;
-
-       connector = &psb_intel_output->base;
-
-       drm_connector_init(dev, connector, &psb_intel_sdvo_connector_funcs,
-                          DRM_MODE_CONNECTOR_Unknown);
-       drm_connector_helper_add(connector,
-                                &psb_intel_sdvo_connector_helper_funcs);
-       sdvo_priv = (struct psb_intel_sdvo_priv *) (psb_intel_output + 1);
-       psb_intel_output->type = INTEL_OUTPUT_SDVO;
-
-       connector->interlace_allowed = 0;
-       connector->doublescan_allowed = 0;
-
-       /* setup the DDC bus. */
-       if (output_device == SDVOB)
-               i2cbus =
-                   psb_intel_i2c_create(dev, GPIOE, "SDVOCTRL_E for SDVOB");
-       else
-               i2cbus =
-                   psb_intel_i2c_create(dev, GPIOE, "SDVOCTRL_E for SDVOC");
-
-       if (!i2cbus)
-               goto err_connector;
-
-       sdvo_priv->i2c_bus = i2cbus;
-
-       if (output_device == SDVOB) {
-               output_id = 1;
-               sdvo_priv->by_input_wiring = SDVOB_IN0;
-               sdvo_priv->i2c_bus->slave_addr = 0x38;
-       } else {
-               output_id = 2;
-               sdvo_priv->i2c_bus->slave_addr = 0x39;
-       }
-
-       sdvo_priv->output_device = output_device;
-       psb_intel_output->i2c_bus = i2cbus;
-       psb_intel_output->dev_priv = sdvo_priv;
-
-
-       /* Read the regs to test if we can talk to the device */
-       for (i = 0; i < 0x40; i++) {
-               if (!psb_intel_sdvo_read_byte(psb_intel_output, i, &ch[i])) {
-                       dev_dbg(dev->dev, "No SDVO device found on SDVO%c\n",
-                                 output_device == SDVOB ? 'B' : 'C');
-                       goto err_i2c;
-               }
-       }
-
-       psb_intel_sdvo_get_capabilities(psb_intel_output, &sdvo_priv->caps);
-
-       memset(&sdvo_priv->active_outputs, 0,
-              sizeof(sdvo_priv->active_outputs));
-
-       /* TODO, CVBS, SVID, YPRPB & SCART outputs. */
-       if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_RGB0) {
-               sdvo_priv->active_outputs = SDVO_OUTPUT_RGB0;
-               sdvo_priv->active_device = SDVO_DEVICE_CRT;
-               connector->display_info.subpixel_order =
-                   SubPixelHorizontalRGB;
-               encoder_type = DRM_MODE_ENCODER_DAC;
-               connector_type = DRM_MODE_CONNECTOR_VGA;
-       } else if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_RGB1) {
-               sdvo_priv->active_outputs = SDVO_OUTPUT_RGB1;
-               sdvo_priv->active_outputs = SDVO_DEVICE_CRT;
-               connector->display_info.subpixel_order =
-                   SubPixelHorizontalRGB;
-               encoder_type = DRM_MODE_ENCODER_DAC;
-               connector_type = DRM_MODE_CONNECTOR_VGA;
-       } else if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_TMDS0) {
-               sdvo_priv->active_outputs = SDVO_OUTPUT_TMDS0;
-               sdvo_priv->active_device = SDVO_DEVICE_TMDS;
-               connector->display_info.subpixel_order =
-                   SubPixelHorizontalRGB;
-               encoder_type = DRM_MODE_ENCODER_TMDS;
-               connector_type = DRM_MODE_CONNECTOR_DVID;
-       } else if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_TMDS1) {
-               sdvo_priv->active_outputs = SDVO_OUTPUT_TMDS1;
-               sdvo_priv->active_device = SDVO_DEVICE_TMDS;
-               connector->display_info.subpixel_order =
-                   SubPixelHorizontalRGB;
-               encoder_type = DRM_MODE_ENCODER_TMDS;
-               connector_type = DRM_MODE_CONNECTOR_DVID;
-       } else {
-               unsigned char bytes[2];
-
-               memcpy(bytes, &sdvo_priv->caps.output_flags, 2);
-               dev_dbg(dev->dev, "%s: No active RGB or TMDS outputs (0x%02x%02x)\n",
-                    SDVO_NAME(sdvo_priv), bytes[0], bytes[1]);
-               goto err_i2c;
-       }
-
-       drm_encoder_init(dev, &psb_intel_output->enc, &psb_intel_sdvo_enc_funcs,
-                        encoder_type);
-       drm_encoder_helper_add(&psb_intel_output->enc,
-                              &psb_intel_sdvo_helper_funcs);
-       connector->connector_type = connector_type;
-
-       drm_mode_connector_attach_encoder(&psb_intel_output->base,
-                                         &psb_intel_output->enc);
-       drm_sysfs_connector_add(connector);
-
-       /* Set the input timing to the screen. Assume always input 0. */
-       psb_intel_sdvo_set_target_input(psb_intel_output, true, false);
-
-       psb_intel_sdvo_get_input_pixel_clock_range(psb_intel_output,
-                                              &sdvo_priv->pixel_clock_min,
-                                              &sdvo_priv->
-                                              pixel_clock_max);
-
-
-       dev_dbg(dev->dev, "%s device VID/DID: %02X:%02X.%02X, "
-                 "clock range %dMHz - %dMHz, "
-                 "input 1: %c, input 2: %c, "
-                 "output 1: %c, output 2: %c\n",
-                 SDVO_NAME(sdvo_priv),
-                 sdvo_priv->caps.vendor_id, sdvo_priv->caps.device_id,
-                 sdvo_priv->caps.device_rev_id,
-                 sdvo_priv->pixel_clock_min / 1000,
-                 sdvo_priv->pixel_clock_max / 1000,
-                 (sdvo_priv->caps.sdvo_inputs_mask & 0x1) ? 'Y' : 'N',
-                 (sdvo_priv->caps.sdvo_inputs_mask & 0x2) ? 'Y' : 'N',
-                 /* check currently supported outputs */
-                 sdvo_priv->caps.output_flags &
-                 (SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_RGB0) ? 'Y' : 'N',
-                 sdvo_priv->caps.output_flags &
-                 (SDVO_OUTPUT_TMDS1 | SDVO_OUTPUT_RGB1) ? 'Y' : 'N');
-
-       psb_intel_output->ddc_bus = i2cbus;
-
-       return;
-
-err_i2c:
-       psb_intel_i2c_destroy(psb_intel_output->i2c_bus);
-err_connector:
-       drm_connector_cleanup(connector);
-       kfree(psb_intel_output);
-
-       return;
-}
diff --git a/drivers/staging/gma500/psb_intel_sdvo_regs.h b/drivers/staging/gma500/psb_intel_sdvo_regs.h
deleted file mode 100644 (file)
index 96862ea..0000000
+++ /dev/null
@@ -1,338 +0,0 @@
-/*
- * SDVO command definitions and structures.
- *
- * Copyright (c) 2008, Intel Corporation
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Authors:
- *     Eric Anholt <eric@anholt.net>
- */
-
-#define SDVO_OUTPUT_FIRST   (0)
-#define SDVO_OUTPUT_TMDS0   (1 << 0)
-#define SDVO_OUTPUT_RGB0    (1 << 1)
-#define SDVO_OUTPUT_CVBS0   (1 << 2)
-#define SDVO_OUTPUT_SVID0   (1 << 3)
-#define SDVO_OUTPUT_YPRPB0  (1 << 4)
-#define SDVO_OUTPUT_SCART0  (1 << 5)
-#define SDVO_OUTPUT_LVDS0   (1 << 6)
-#define SDVO_OUTPUT_TMDS1   (1 << 8)
-#define SDVO_OUTPUT_RGB1    (1 << 9)
-#define SDVO_OUTPUT_CVBS1   (1 << 10)
-#define SDVO_OUTPUT_SVID1   (1 << 11)
-#define SDVO_OUTPUT_YPRPB1  (1 << 12)
-#define SDVO_OUTPUT_SCART1  (1 << 13)
-#define SDVO_OUTPUT_LVDS1   (1 << 14)
-#define SDVO_OUTPUT_LAST    (14)
-
-struct psb_intel_sdvo_caps {
-       u8 vendor_id;
-       u8 device_id;
-       u8 device_rev_id;
-       u8 sdvo_version_major;
-       u8 sdvo_version_minor;
-       unsigned int sdvo_inputs_mask:2;
-       unsigned int smooth_scaling:1;
-       unsigned int sharp_scaling:1;
-       unsigned int up_scaling:1;
-       unsigned int down_scaling:1;
-       unsigned int stall_support:1;
-       unsigned int pad:1;
-       u16 output_flags;
-} __packed;
-
-/** This matches the EDID DTD structure, more or less */
-struct psb_intel_sdvo_dtd {
-       struct {
-               u16 clock;      /**< pixel clock, in 10kHz units */
-               u8 h_active;    /**< lower 8 bits (pixels) */
-               u8 h_blank;     /**< lower 8 bits (pixels) */
-               u8 h_high;      /**< upper 4 bits each h_active, h_blank */
-               u8 v_active;    /**< lower 8 bits (lines) */
-               u8 v_blank;     /**< lower 8 bits (lines) */
-               u8 v_high;      /**< upper 4 bits each v_active, v_blank */
-       } part1;
-
-       struct {
-               u8 h_sync_off;
-                       /**< lower 8 bits, from hblank start */
-               u8 h_sync_width;/**< lower 8 bits (pixels) */
-       /** lower 4 bits each vsync offset, vsync width */
-               u8 v_sync_off_width;
-       /**
-        * 2 high bits of hsync offset, 2 high bits of hsync width,
-        * bits 4-5 of vsync offset, and 2 high bits of vsync width.
-        */
-               u8 sync_off_width_high;
-               u8 dtd_flags;
-               u8 sdvo_flags;
-       /** bits 6-7 of vsync offset at bits 6-7 */
-               u8 v_sync_off_high;
-               u8 reserved;
-       } part2;
-} __packed;
-
-struct psb_intel_sdvo_pixel_clock_range {
-       u16 min;                /**< pixel clock, in 10kHz units */
-       u16 max;                /**< pixel clock, in 10kHz units */
-} __packed;
-
-struct psb_intel_sdvo_preferred_input_timing_args {
-       u16 clock;
-       u16 width;
-       u16 height;
-} __packed;
-
-/* I2C registers for SDVO */
-#define SDVO_I2C_ARG_0                         0x07
-#define SDVO_I2C_ARG_1                         0x06
-#define SDVO_I2C_ARG_2                         0x05
-#define SDVO_I2C_ARG_3                         0x04
-#define SDVO_I2C_ARG_4                         0x03
-#define SDVO_I2C_ARG_5                         0x02
-#define SDVO_I2C_ARG_6                         0x01
-#define SDVO_I2C_ARG_7                         0x00
-#define SDVO_I2C_OPCODE                                0x08
-#define SDVO_I2C_CMD_STATUS                    0x09
-#define SDVO_I2C_RETURN_0                      0x0a
-#define SDVO_I2C_RETURN_1                      0x0b
-#define SDVO_I2C_RETURN_2                      0x0c
-#define SDVO_I2C_RETURN_3                      0x0d
-#define SDVO_I2C_RETURN_4                      0x0e
-#define SDVO_I2C_RETURN_5                      0x0f
-#define SDVO_I2C_RETURN_6                      0x10
-#define SDVO_I2C_RETURN_7                      0x11
-#define SDVO_I2C_VENDOR_BEGIN                  0x20
-
-/* Status results */
-#define SDVO_CMD_STATUS_POWER_ON               0x0
-#define SDVO_CMD_STATUS_SUCCESS                        0x1
-#define SDVO_CMD_STATUS_NOTSUPP                        0x2
-#define SDVO_CMD_STATUS_INVALID_ARG            0x3
-#define SDVO_CMD_STATUS_PENDING                        0x4
-#define SDVO_CMD_STATUS_TARGET_NOT_SPECIFIED   0x5
-#define SDVO_CMD_STATUS_SCALING_NOT_SUPP       0x6
-
-/* SDVO commands, argument/result registers */
-
-#define SDVO_CMD_RESET                                 0x01
-
-/** Returns a struct psb_intel_sdvo_caps */
-#define SDVO_CMD_GET_DEVICE_CAPS                       0x02
-
-#define SDVO_CMD_GET_FIRMWARE_REV                      0x86
-# define SDVO_DEVICE_FIRMWARE_MINOR                    SDVO_I2C_RETURN_0
-# define SDVO_DEVICE_FIRMWARE_MAJOR                    SDVO_I2C_RETURN_1
-# define SDVO_DEVICE_FIRMWARE_PATCH                    SDVO_I2C_RETURN_2
-
-/**
- * Reports which inputs are trained (managed to sync).
- *
- * Devices must have trained within 2 vsyncs of a mode change.
- */
-#define SDVO_CMD_GET_TRAINED_INPUTS                    0x03
-struct psb_intel_sdvo_get_trained_inputs_response {
-       unsigned int input0_trained:1;
-       unsigned int input1_trained:1;
-       unsigned int pad:6;
-} __packed;
-
-/** Returns a struct psb_intel_sdvo_output_flags of active outputs. */
-#define SDVO_CMD_GET_ACTIVE_OUTPUTS                    0x04
-
-/**
- * Sets the current set of active outputs.
- *
- * Takes a struct psb_intel_sdvo_output_flags.
- * Must be preceded by a SET_IN_OUT_MAP
- * on multi-output devices.
- */
-#define SDVO_CMD_SET_ACTIVE_OUTPUTS                    0x05
-
-/**
- * Returns the current mapping of SDVO inputs to outputs on the device.
- *
- * Returns two struct psb_intel_sdvo_output_flags structures.
- */
-#define SDVO_CMD_GET_IN_OUT_MAP                                0x06
-
-/**
- * Sets the current mapping of SDVO inputs to outputs on the device.
- *
- * Takes two struct i380_sdvo_output_flags structures.
- */
-#define SDVO_CMD_SET_IN_OUT_MAP                                0x07
-
-/**
- * Returns a struct psb_intel_sdvo_output_flags of attached displays.
- */
-#define SDVO_CMD_GET_ATTACHED_DISPLAYS                 0x0b
-
-/**
- * Returns a struct psb_intel_sdvo_ouptut_flags of displays supporting hot plugging.
- */
-#define SDVO_CMD_GET_HOT_PLUG_SUPPORT                  0x0c
-
-/**
- * Takes a struct psb_intel_sdvo_output_flags.
- */
-#define SDVO_CMD_SET_ACTIVE_HOT_PLUG                   0x0d
-
-/**
- * Returns a struct psb_intel_sdvo_output_flags of displays with hot plug
- * interrupts enabled.
- */
-#define SDVO_CMD_GET_ACTIVE_HOT_PLUG                   0x0e
-
-#define SDVO_CMD_GET_INTERRUPT_EVENT_SOURCE            0x0f
-struct psb_intel_sdvo_get_interrupt_event_source_response {
-       u16 interrupt_status;
-       unsigned int ambient_light_interrupt:1;
-       unsigned int pad:7;
-} __packed;
-
-/**
- * Selects which input is affected by future input commands.
- *
- * Commands affected include SET_INPUT_TIMINGS_PART[12],
- * GET_INPUT_TIMINGS_PART[12], GET_PREFERRED_INPUT_TIMINGS_PART[12],
- * GET_INPUT_PIXEL_CLOCK_RANGE, and CREATE_PREFERRED_INPUT_TIMINGS.
- */
-#define SDVO_CMD_SET_TARGET_INPUT                      0x10
-struct psb_intel_sdvo_set_target_input_args {
-       unsigned int target_1:1;
-       unsigned int pad:7;
-} __packed;
-
-/**
- * Takes a struct psb_intel_sdvo_output_flags of which outputs are targeted by
- * future output commands.
- *
- * Affected commands inclue SET_OUTPUT_TIMINGS_PART[12],
- * GET_OUTPUT_TIMINGS_PART[12], and GET_OUTPUT_PIXEL_CLOCK_RANGE.
- */
-#define SDVO_CMD_SET_TARGET_OUTPUT                     0x11
-
-#define SDVO_CMD_GET_INPUT_TIMINGS_PART1               0x12
-#define SDVO_CMD_GET_INPUT_TIMINGS_PART2               0x13
-#define SDVO_CMD_SET_INPUT_TIMINGS_PART1               0x14
-#define SDVO_CMD_SET_INPUT_TIMINGS_PART2               0x15
-#define SDVO_CMD_SET_OUTPUT_TIMINGS_PART1              0x16
-#define SDVO_CMD_SET_OUTPUT_TIMINGS_PART2              0x17
-#define SDVO_CMD_GET_OUTPUT_TIMINGS_PART1              0x18
-#define SDVO_CMD_GET_OUTPUT_TIMINGS_PART2              0x19
-/* Part 1 */
-# define SDVO_DTD_CLOCK_LOW                            SDVO_I2C_ARG_0
-# define SDVO_DTD_CLOCK_HIGH                           SDVO_I2C_ARG_1
-# define SDVO_DTD_H_ACTIVE                             SDVO_I2C_ARG_2
-# define SDVO_DTD_H_BLANK                              SDVO_I2C_ARG_3
-# define SDVO_DTD_H_HIGH                               SDVO_I2C_ARG_4
-# define SDVO_DTD_V_ACTIVE                             SDVO_I2C_ARG_5
-# define SDVO_DTD_V_BLANK                              SDVO_I2C_ARG_6
-# define SDVO_DTD_V_HIGH                               SDVO_I2C_ARG_7
-/* Part 2 */
-# define SDVO_DTD_HSYNC_OFF                            SDVO_I2C_ARG_0
-# define SDVO_DTD_HSYNC_WIDTH                          SDVO_I2C_ARG_1
-# define SDVO_DTD_VSYNC_OFF_WIDTH                      SDVO_I2C_ARG_2
-# define SDVO_DTD_SYNC_OFF_WIDTH_HIGH                  SDVO_I2C_ARG_3
-# define SDVO_DTD_DTD_FLAGS                            SDVO_I2C_ARG_4
-# define SDVO_DTD_DTD_FLAG_INTERLACED                          (1 << 7)
-# define SDVO_DTD_DTD_FLAG_STEREO_MASK                         (3 << 5)
-# define SDVO_DTD_DTD_FLAG_INPUT_MASK                          (3 << 3)
-# define SDVO_DTD_DTD_FLAG_SYNC_MASK                           (3 << 1)
-# define SDVO_DTD_SDVO_FLAS                            SDVO_I2C_ARG_5
-# define SDVO_DTD_SDVO_FLAG_STALL                              (1 << 7)
-# define SDVO_DTD_SDVO_FLAG_CENTERED                           (0 << 6)
-# define SDVO_DTD_SDVO_FLAG_UPPER_LEFT                         (1 << 6)
-# define SDVO_DTD_SDVO_FLAG_SCALING_MASK                       (3 << 4)
-# define SDVO_DTD_SDVO_FLAG_SCALING_NONE                       (0 << 4)
-# define SDVO_DTD_SDVO_FLAG_SCALING_SHARP                      (1 << 4)
-# define SDVO_DTD_SDVO_FLAG_SCALING_SMOOTH                     (2 << 4)
-# define SDVO_DTD_VSYNC_OFF_HIGH                       SDVO_I2C_ARG_6
-
-/**
- * Generates a DTD based on the given width, height, and flags.
- *
- * This will be supported by any device supporting scaling or interlaced
- * modes.
- */
-#define SDVO_CMD_CREATE_PREFERRED_INPUT_TIMING         0x1a
-# define SDVO_PREFERRED_INPUT_TIMING_CLOCK_LOW         SDVO_I2C_ARG_0
-# define SDVO_PREFERRED_INPUT_TIMING_CLOCK_HIGH                SDVO_I2C_ARG_1
-# define SDVO_PREFERRED_INPUT_TIMING_WIDTH_LOW         SDVO_I2C_ARG_2
-# define SDVO_PREFERRED_INPUT_TIMING_WIDTH_HIGH                SDVO_I2C_ARG_3
-# define SDVO_PREFERRED_INPUT_TIMING_HEIGHT_LOW                SDVO_I2C_ARG_4
-# define SDVO_PREFERRED_INPUT_TIMING_HEIGHT_HIGH       SDVO_I2C_ARG_5
-# define SDVO_PREFERRED_INPUT_TIMING_FLAGS             SDVO_I2C_ARG_6
-# define SDVO_PREFERRED_INPUT_TIMING_FLAGS_INTERLACED          (1 << 0)
-# define SDVO_PREFERRED_INPUT_TIMING_FLAGS_SCALED              (1 << 1)
-
-#define SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART1      0x1b
-#define SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART2      0x1c
-
-/** Returns a struct psb_intel_sdvo_pixel_clock_range */
-#define SDVO_CMD_GET_INPUT_PIXEL_CLOCK_RANGE           0x1d
-/** Returns a struct psb_intel_sdvo_pixel_clock_range */
-#define SDVO_CMD_GET_OUTPUT_PIXEL_CLOCK_RANGE          0x1e
-
-/** Returns a byte bitfield containing SDVO_CLOCK_RATE_MULT_* flags */
-#define SDVO_CMD_GET_SUPPORTED_CLOCK_RATE_MULTS                0x1f
-
-/** Returns a byte containing a SDVO_CLOCK_RATE_MULT_* flag */
-#define SDVO_CMD_GET_CLOCK_RATE_MULT                   0x20
-/** Takes a byte containing a SDVO_CLOCK_RATE_MULT_* flag */
-#define SDVO_CMD_SET_CLOCK_RATE_MULT                   0x21
-# define SDVO_CLOCK_RATE_MULT_1X                               (1 << 0)
-# define SDVO_CLOCK_RATE_MULT_2X                               (1 << 1)
-# define SDVO_CLOCK_RATE_MULT_4X                               (1 << 3)
-
-#define SDVO_CMD_GET_SUPPORTED_TV_FORMATS              0x27
-
-#define SDVO_CMD_GET_TV_FORMAT                         0x28
-
-#define SDVO_CMD_SET_TV_FORMAT                         0x29
-
-#define SDVO_CMD_GET_SUPPORTED_POWER_STATES            0x2a
-#define SDVO_CMD_GET_ENCODER_POWER_STATE               0x2b
-#define SDVO_CMD_SET_ENCODER_POWER_STATE               0x2c
-# define SDVO_ENCODER_STATE_ON                                 (1 << 0)
-# define SDVO_ENCODER_STATE_STANDBY                            (1 << 1)
-# define SDVO_ENCODER_STATE_SUSPEND                            (1 << 2)
-# define SDVO_ENCODER_STATE_OFF                                        (1 << 3)
-
-#define SDVO_CMD_SET_TV_RESOLUTION_SUPPORT             0x93
-
-#define SDVO_CMD_SET_CONTROL_BUS_SWITCH                        0x7a
-# define SDVO_CONTROL_BUS_PROM                         0x0
-# define SDVO_CONTROL_BUS_DDC1                         0x1
-# define SDVO_CONTROL_BUS_DDC2                         0x2
-# define SDVO_CONTROL_BUS_DDC3                         0x3
-
-/* SDVO Bus & SDVO Inputs wiring details*/
-/* Bit 0: Is SDVOB connected to In0 (1 = yes, 0 = no*/
-/* Bit 1: Is SDVOB connected to In1 (1 = yes, 0 = no*/
-/* Bit 2: Is SDVOC connected to In0 (1 = yes, 0 = no*/
-/* Bit 3: Is SDVOC connected to In1 (1 = yes, 0 = no*/
-#define SDVOB_IN0 0x01
-#define SDVOB_IN1 0x02
-#define SDVOC_IN0 0x04
-#define SDVOC_IN1 0x08
-
-#define SDVO_DEVICE_NONE 0x00
-#define        SDVO_DEVICE_CRT 0x01
-#define        SDVO_DEVICE_TV 0x02
-#define        SDVO_DEVICE_LVDS 0x04
-#define        SDVO_DEVICE_TMDS 0x08
-
diff --git a/drivers/staging/gma500/psb_irq.c b/drivers/staging/gma500/psb_irq.c
deleted file mode 100644 (file)
index 36dd630..0000000
+++ /dev/null
@@ -1,627 +0,0 @@
-/**************************************************************************
- * Copyright (c) 2007, Intel Corporation.
- * All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
- * develop this driver.
- *
- **************************************************************************/
-/*
- */
-
-#include <drm/drmP.h>
-#include "psb_drv.h"
-#include "psb_reg.h"
-#include "psb_intel_reg.h"
-#include "power.h"
-#include "mdfld_output.h"
-
-/*
- * inline functions
- */
-
-static inline u32
-psb_pipestat(int pipe)
-{
-       if (pipe == 0)
-               return PIPEASTAT;
-       if (pipe == 1)
-               return PIPEBSTAT;
-       if (pipe == 2)
-               return PIPECSTAT;
-       BUG();
-}
-
-static inline u32
-mid_pipe_event(int pipe)
-{
-       if (pipe == 0)
-               return _PSB_PIPEA_EVENT_FLAG;
-       if (pipe == 1)
-               return _MDFLD_PIPEB_EVENT_FLAG;
-       if (pipe == 2)
-               return _MDFLD_PIPEC_EVENT_FLAG;
-       BUG();
-}
-
-static inline u32
-mid_pipe_vsync(int pipe)
-{
-       if (pipe == 0)
-               return _PSB_VSYNC_PIPEA_FLAG;
-       if (pipe == 1)
-               return _PSB_VSYNC_PIPEB_FLAG;
-       if (pipe == 2)
-               return _MDFLD_PIPEC_VBLANK_FLAG;
-       BUG();
-}
-
-static inline u32
-mid_pipeconf(int pipe)
-{
-       if (pipe == 0)
-               return PIPEACONF;
-       if (pipe == 1)
-               return PIPEBCONF;
-       if (pipe == 2)
-               return PIPECCONF;
-       BUG();
-}
-
-void
-psb_enable_pipestat(struct drm_psb_private *dev_priv, int pipe, u32 mask)
-{
-       if ((dev_priv->pipestat[pipe] & mask) != mask) {
-               u32 reg = psb_pipestat(pipe);
-               dev_priv->pipestat[pipe] |= mask;
-               /* Enable the interrupt, clear any pending status */
-               if (gma_power_begin(dev_priv->dev, false)) {
-                       u32 writeVal = PSB_RVDC32(reg);
-                       writeVal |= (mask | (mask >> 16));
-                       PSB_WVDC32(writeVal, reg);
-                       (void) PSB_RVDC32(reg);
-                       gma_power_end(dev_priv->dev);
-               }
-       }
-}
-
-void
-psb_disable_pipestat(struct drm_psb_private *dev_priv, int pipe, u32 mask)
-{
-       if ((dev_priv->pipestat[pipe] & mask) != 0) {
-               u32 reg = psb_pipestat(pipe);
-               dev_priv->pipestat[pipe] &= ~mask;
-               if (gma_power_begin(dev_priv->dev, false)) {
-                       u32 writeVal = PSB_RVDC32(reg);
-                       writeVal &= ~mask;
-                       PSB_WVDC32(writeVal, reg);
-                       (void) PSB_RVDC32(reg);
-                       gma_power_end(dev_priv->dev);
-               }
-       }
-}
-
-void mid_enable_pipe_event(struct drm_psb_private *dev_priv, int pipe)
-{
-       if (gma_power_begin(dev_priv->dev, false)) {
-               u32 pipe_event = mid_pipe_event(pipe);
-               dev_priv->vdc_irq_mask |= pipe_event;
-               PSB_WVDC32(~dev_priv->vdc_irq_mask, PSB_INT_MASK_R);
-               PSB_WVDC32(dev_priv->vdc_irq_mask, PSB_INT_ENABLE_R);
-               gma_power_end(dev_priv->dev);
-       }
-}
-
-void mid_disable_pipe_event(struct drm_psb_private *dev_priv, int pipe)
-{
-       if (dev_priv->pipestat[pipe] == 0) {
-               if (gma_power_begin(dev_priv->dev, false)) {
-                       u32 pipe_event = mid_pipe_event(pipe);
-                       dev_priv->vdc_irq_mask &= ~pipe_event;
-                       PSB_WVDC32(~dev_priv->vdc_irq_mask, PSB_INT_MASK_R);
-                       PSB_WVDC32(dev_priv->vdc_irq_mask, PSB_INT_ENABLE_R);
-                       gma_power_end(dev_priv->dev);
-               }
-       }
-}
-
-/**
- * Display controller interrupt handler for pipe event.
- *
- */
-static void mid_pipe_event_handler(struct drm_device *dev, int pipe)
-{
-       struct drm_psb_private *dev_priv =
-           (struct drm_psb_private *) dev->dev_private;
-
-       uint32_t pipe_stat_val = 0;
-       uint32_t pipe_stat_reg = psb_pipestat(pipe);
-       uint32_t pipe_enable = dev_priv->pipestat[pipe];
-       uint32_t pipe_status = dev_priv->pipestat[pipe] >> 16;
-       uint32_t pipe_clear;
-       uint32_t i = 0;
-
-       spin_lock(&dev_priv->irqmask_lock);
-
-       pipe_stat_val = PSB_RVDC32(pipe_stat_reg);
-       pipe_stat_val &= pipe_enable | pipe_status;
-       pipe_stat_val &= pipe_stat_val >> 16;
-
-       spin_unlock(&dev_priv->irqmask_lock);
-
-       /* Clear the 2nd level interrupt status bits
-        * Sometimes the bits are very sticky so we repeat until they unstick */
-       for (i = 0; i < 0xffff; i++) {
-               PSB_WVDC32(PSB_RVDC32(pipe_stat_reg), pipe_stat_reg);
-               pipe_clear = PSB_RVDC32(pipe_stat_reg) & pipe_status;
-
-               if (pipe_clear == 0)
-                       break;
-       }
-
-       if (pipe_clear)
-               dev_err(dev->dev,
-               "%s, can't clear status bits for pipe %d, its value = 0x%x.\n",
-               __func__, pipe, PSB_RVDC32(pipe_stat_reg));
-
-       if (pipe_stat_val & PIPE_VBLANK_STATUS)
-               drm_handle_vblank(dev, pipe);
-
-       if (pipe_stat_val & PIPE_TE_STATUS)
-               drm_handle_vblank(dev, pipe);
-}
-
-/*
- * Display controller interrupt handler.
- */
-static void psb_vdc_interrupt(struct drm_device *dev, uint32_t vdc_stat)
-{
-       if (vdc_stat & _PSB_VSYNC_PIPEA_FLAG)
-               mid_pipe_event_handler(dev, 0);
-
-       if (vdc_stat & _PSB_VSYNC_PIPEB_FLAG)
-               mid_pipe_event_handler(dev, 1);
-}
-
-irqreturn_t psb_irq_handler(DRM_IRQ_ARGS)
-{
-       struct drm_device *dev = (struct drm_device *) arg;
-       struct drm_psb_private *dev_priv =
-           (struct drm_psb_private *) dev->dev_private;
-
-       uint32_t vdc_stat, dsp_int = 0, sgx_int = 0;
-       int handled = 0;
-
-       spin_lock(&dev_priv->irqmask_lock);
-
-       vdc_stat = PSB_RVDC32(PSB_INT_IDENTITY_R);
-
-       if (vdc_stat & _PSB_PIPE_EVENT_FLAG)
-               dsp_int = 1;
-
-       /* FIXME: Handle Medfield
-       if (vdc_stat & _MDFLD_DISP_ALL_IRQ_FLAG)
-               dsp_int = 1;
-       */
-
-       if (vdc_stat & _PSB_IRQ_SGX_FLAG)
-               sgx_int = 1;
-
-       vdc_stat &= dev_priv->vdc_irq_mask;
-       spin_unlock(&dev_priv->irqmask_lock);
-
-       if (dsp_int && gma_power_is_on(dev)) {
-               psb_vdc_interrupt(dev, vdc_stat);
-               handled = 1;
-       }
-
-       if (sgx_int) {
-               /* Not expected - we have it masked, shut it up */
-               u32 s, s2;
-               s = PSB_RSGX32(PSB_CR_EVENT_STATUS);
-               s2 = PSB_RSGX32(PSB_CR_EVENT_STATUS2);
-               PSB_WSGX32(s, PSB_CR_EVENT_HOST_CLEAR);
-               PSB_WSGX32(s2, PSB_CR_EVENT_HOST_CLEAR2);
-               /* if s & _PSB_CE_TWOD_COMPLETE we have 2D done but
-                  we may as well poll even if we add that ! */
-               handled = 1;
-       }
-
-       PSB_WVDC32(vdc_stat, PSB_INT_IDENTITY_R);
-       (void) PSB_RVDC32(PSB_INT_IDENTITY_R);
-       DRM_READMEMORYBARRIER();
-
-       if (!handled)
-               return IRQ_NONE;
-
-       return IRQ_HANDLED;
-}
-
-void psb_irq_preinstall(struct drm_device *dev)
-{
-       struct drm_psb_private *dev_priv =
-           (struct drm_psb_private *) dev->dev_private;
-       unsigned long irqflags;
-
-       spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags);
-
-       if (gma_power_is_on(dev))
-               PSB_WVDC32(0xFFFFFFFF, PSB_HWSTAM);
-       if (dev->vblank_enabled[0])
-               dev_priv->vdc_irq_mask |= _PSB_VSYNC_PIPEA_FLAG;
-       if (dev->vblank_enabled[1])
-               dev_priv->vdc_irq_mask |= _PSB_VSYNC_PIPEB_FLAG;
-
-       /* FIXME: Handle Medfield irq mask
-       if (dev->vblank_enabled[1])
-               dev_priv->vdc_irq_mask |= _MDFLD_PIPEB_EVENT_FLAG;
-       if (dev->vblank_enabled[2])
-               dev_priv->vdc_irq_mask |= _MDFLD_PIPEC_EVENT_FLAG;
-       */
-
-       /* This register is safe even if display island is off */
-       PSB_WVDC32(~dev_priv->vdc_irq_mask, PSB_INT_MASK_R);
-       spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags);
-}
-
-int psb_irq_postinstall(struct drm_device *dev)
-{
-       struct drm_psb_private *dev_priv =
-           (struct drm_psb_private *) dev->dev_private;
-       unsigned long irqflags;
-
-       spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags);
-
-       /* This register is safe even if display island is off */
-       PSB_WVDC32(dev_priv->vdc_irq_mask, PSB_INT_ENABLE_R);
-       PSB_WVDC32(0xFFFFFFFF, PSB_HWSTAM);
-
-       if (dev->vblank_enabled[0])
-               psb_enable_pipestat(dev_priv, 0, PIPE_VBLANK_INTERRUPT_ENABLE);
-       else
-               psb_disable_pipestat(dev_priv, 0, PIPE_VBLANK_INTERRUPT_ENABLE);
-
-       if (dev->vblank_enabled[1])
-               psb_enable_pipestat(dev_priv, 1, PIPE_VBLANK_INTERRUPT_ENABLE);
-       else
-               psb_disable_pipestat(dev_priv, 1, PIPE_VBLANK_INTERRUPT_ENABLE);
-
-       if (dev->vblank_enabled[2])
-               psb_enable_pipestat(dev_priv, 2, PIPE_VBLANK_INTERRUPT_ENABLE);
-       else
-               psb_disable_pipestat(dev_priv, 2, PIPE_VBLANK_INTERRUPT_ENABLE);
-
-       spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags);
-       return 0;
-}
-
-void psb_irq_uninstall(struct drm_device *dev)
-{
-       struct drm_psb_private *dev_priv =
-           (struct drm_psb_private *) dev->dev_private;
-       unsigned long irqflags;
-
-       spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags);
-
-       PSB_WVDC32(0xFFFFFFFF, PSB_HWSTAM);
-
-       if (dev->vblank_enabled[0])
-               psb_disable_pipestat(dev_priv, 0, PIPE_VBLANK_INTERRUPT_ENABLE);
-
-       if (dev->vblank_enabled[1])
-               psb_disable_pipestat(dev_priv, 1, PIPE_VBLANK_INTERRUPT_ENABLE);
-
-       if (dev->vblank_enabled[2])
-               psb_disable_pipestat(dev_priv, 2, PIPE_VBLANK_INTERRUPT_ENABLE);
-
-       dev_priv->vdc_irq_mask &= _PSB_IRQ_SGX_FLAG |
-                                 _PSB_IRQ_MSVDX_FLAG |
-                                 _LNC_IRQ_TOPAZ_FLAG;
-
-       /* These two registers are safe even if display island is off */
-       PSB_WVDC32(~dev_priv->vdc_irq_mask, PSB_INT_MASK_R);
-       PSB_WVDC32(dev_priv->vdc_irq_mask, PSB_INT_ENABLE_R);
-
-       wmb();
-
-       /* This register is safe even if display island is off */
-       PSB_WVDC32(PSB_RVDC32(PSB_INT_IDENTITY_R), PSB_INT_IDENTITY_R);
-       spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags);
-}
-
-void psb_irq_turn_on_dpst(struct drm_device *dev)
-{
-       struct drm_psb_private *dev_priv =
-               (struct drm_psb_private *) dev->dev_private;
-       u32 hist_reg;
-       u32 pwm_reg;
-
-       if (gma_power_begin(dev, false)) {
-               PSB_WVDC32(1 << 31, HISTOGRAM_LOGIC_CONTROL);
-               hist_reg = PSB_RVDC32(HISTOGRAM_LOGIC_CONTROL);
-               PSB_WVDC32(1 << 31, HISTOGRAM_INT_CONTROL);
-               hist_reg = PSB_RVDC32(HISTOGRAM_INT_CONTROL);
-
-               PSB_WVDC32(0x80010100, PWM_CONTROL_LOGIC);
-               pwm_reg = PSB_RVDC32(PWM_CONTROL_LOGIC);
-               PSB_WVDC32(pwm_reg | PWM_PHASEIN_ENABLE
-                                               | PWM_PHASEIN_INT_ENABLE,
-                                                          PWM_CONTROL_LOGIC);
-               pwm_reg = PSB_RVDC32(PWM_CONTROL_LOGIC);
-
-               psb_enable_pipestat(dev_priv, 0, PIPE_DPST_EVENT_ENABLE);
-
-               hist_reg = PSB_RVDC32(HISTOGRAM_INT_CONTROL);
-               PSB_WVDC32(hist_reg | HISTOGRAM_INT_CTRL_CLEAR,
-                                                       HISTOGRAM_INT_CONTROL);
-               pwm_reg = PSB_RVDC32(PWM_CONTROL_LOGIC);
-               PSB_WVDC32(pwm_reg | 0x80010100 | PWM_PHASEIN_ENABLE,
-                                                       PWM_CONTROL_LOGIC);
-
-               gma_power_end(dev);
-       }
-}
-
-int psb_irq_enable_dpst(struct drm_device *dev)
-{
-       struct drm_psb_private *dev_priv =
-               (struct drm_psb_private *) dev->dev_private;
-       unsigned long irqflags;
-
-       spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags);
-
-       /* enable DPST */
-       mid_enable_pipe_event(dev_priv, 0);
-       psb_irq_turn_on_dpst(dev);
-
-       spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags);
-       return 0;
-}
-
-void psb_irq_turn_off_dpst(struct drm_device *dev)
-{
-       struct drm_psb_private *dev_priv =
-           (struct drm_psb_private *) dev->dev_private;
-       u32 hist_reg;
-       u32 pwm_reg;
-
-       if (gma_power_begin(dev, false)) {
-               PSB_WVDC32(0x00000000, HISTOGRAM_INT_CONTROL);
-               hist_reg = PSB_RVDC32(HISTOGRAM_INT_CONTROL);
-
-               psb_disable_pipestat(dev_priv, 0, PIPE_DPST_EVENT_ENABLE);
-
-               pwm_reg = PSB_RVDC32(PWM_CONTROL_LOGIC);
-               PSB_WVDC32(pwm_reg & !(PWM_PHASEIN_INT_ENABLE),
-                                                       PWM_CONTROL_LOGIC);
-               pwm_reg = PSB_RVDC32(PWM_CONTROL_LOGIC);
-
-               gma_power_end(dev);
-       }
-}
-
-int psb_irq_disable_dpst(struct drm_device *dev)
-{
-       struct drm_psb_private *dev_priv =
-           (struct drm_psb_private *) dev->dev_private;
-       unsigned long irqflags;
-
-       spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags);
-
-       mid_disable_pipe_event(dev_priv, 0);
-       psb_irq_turn_off_dpst(dev);
-
-       spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags);
-
-       return 0;
-}
-
-#ifdef PSB_FIXME
-static int psb_vblank_do_wait(struct drm_device *dev,
-                             unsigned int *sequence, atomic_t *counter)
-{
-       unsigned int cur_vblank;
-       int ret = 0;
-       DRM_WAIT_ON(ret, dev->vbl_queue, 3 * DRM_HZ,
-                   (((cur_vblank = atomic_read(counter))
-                     - *sequence) <= (1 << 23)));
-       *sequence = cur_vblank;
-
-       return ret;
-}
-#endif
-
-/*
- * It is used to enable VBLANK interrupt
- */
-int psb_enable_vblank(struct drm_device *dev, int pipe)
-{
-       struct drm_psb_private *dev_priv = dev->dev_private;
-       unsigned long irqflags;
-       uint32_t reg_val = 0;
-       uint32_t pipeconf_reg = mid_pipeconf(pipe);
-
-#if defined(CONFIG_DRM_PSB_MFLD)
-       /* Medfield is different - we should perhaps extract out vblank
-          and blacklight etc ops */
-       if (IS_MFLD(dev) && !mdfld_panel_dpi(dev))
-               return mdfld_enable_te(dev, pipe);
-#endif
-       if (gma_power_begin(dev, false)) {
-               reg_val = REG_READ(pipeconf_reg);
-               gma_power_end(dev);
-       }
-
-       if (!(reg_val & PIPEACONF_ENABLE))
-               return -EINVAL;
-
-       spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags);
-
-       if (pipe == 0)
-               dev_priv->vdc_irq_mask |= _PSB_VSYNC_PIPEA_FLAG;
-       else if (pipe == 1)
-               dev_priv->vdc_irq_mask |= _PSB_VSYNC_PIPEB_FLAG;
-
-       PSB_WVDC32(~dev_priv->vdc_irq_mask, PSB_INT_MASK_R);
-       PSB_WVDC32(dev_priv->vdc_irq_mask, PSB_INT_ENABLE_R);
-       psb_enable_pipestat(dev_priv, pipe, PIPE_VBLANK_INTERRUPT_ENABLE);
-
-       spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags);
-
-       return 0;
-}
-
-/*
- * It is used to disable VBLANK interrupt
- */
-void psb_disable_vblank(struct drm_device *dev, int pipe)
-{
-       struct drm_psb_private *dev_priv = dev->dev_private;
-       unsigned long irqflags;
-
-#if defined(CONFIG_DRM_PSB_MFLD)
-       if (IS_MFLD(dev) && !mdfld_panel_dpi(dev))
-               mdfld_disable_te(dev, pipe);
-#endif
-       spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags);
-
-       if (pipe == 0)
-               dev_priv->vdc_irq_mask &= ~_PSB_VSYNC_PIPEA_FLAG;
-       else if (pipe == 1)
-               dev_priv->vdc_irq_mask &= ~_PSB_VSYNC_PIPEB_FLAG;
-
-       PSB_WVDC32(~dev_priv->vdc_irq_mask, PSB_INT_MASK_R);
-       PSB_WVDC32(dev_priv->vdc_irq_mask, PSB_INT_ENABLE_R);
-       psb_disable_pipestat(dev_priv, pipe, PIPE_VBLANK_INTERRUPT_ENABLE);
-
-       spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags);
-}
-
-/**
- *     mdfld_enable_te         -       enable TE events
- *     @dev: our DRM device
- *     @pipe: which pipe to work on
- *
- *     Enable TE events on a Medfield display pipe. Medfield specific.
- */
-int mdfld_enable_te(struct drm_device *dev, int pipe)
-{
-       struct drm_psb_private *dev_priv = dev->dev_private;
-       unsigned long flags;
-       uint32_t reg_val = 0;
-       uint32_t pipeconf_reg = mid_pipeconf(pipe);
-
-       if (gma_power_begin(dev, false)) {
-               reg_val = REG_READ(pipeconf_reg);
-               gma_power_end(dev);
-       }
-
-       if (!(reg_val & PIPEACONF_ENABLE))
-               return -EINVAL;
-
-       spin_lock_irqsave(&dev_priv->irqmask_lock, flags);
-
-       mid_enable_pipe_event(dev_priv, pipe);
-       psb_enable_pipestat(dev_priv, pipe, PIPE_TE_ENABLE);
-
-       spin_unlock_irqrestore(&dev_priv->irqmask_lock, flags);
-
-       return 0;
-}
-
-/**
- *     mdfld_disable_te                -       disable TE events
- *     @dev: our DRM device
- *     @pipe: which pipe to work on
- *
- *     Disable TE events on a Medfield display pipe. Medfield specific.
- */
-void mdfld_disable_te(struct drm_device *dev, int pipe)
-{
-       struct drm_psb_private *dev_priv = dev->dev_private;
-       unsigned long flags;
-
-       spin_lock_irqsave(&dev_priv->irqmask_lock, flags);
-
-       mid_disable_pipe_event(dev_priv, pipe);
-       psb_disable_pipestat(dev_priv, pipe, PIPE_TE_ENABLE);
-
-       spin_unlock_irqrestore(&dev_priv->irqmask_lock, flags);
-}
-
-/* Called from drm generic code, passed a 'crtc', which
- * we use as a pipe index
- */
-u32 psb_get_vblank_counter(struct drm_device *dev, int pipe)
-{
-       uint32_t high_frame = PIPEAFRAMEHIGH;
-       uint32_t low_frame = PIPEAFRAMEPIXEL;
-       uint32_t pipeconf_reg = PIPEACONF;
-       uint32_t reg_val = 0;
-       uint32_t high1 = 0, high2 = 0, low = 0, count = 0;
-
-       switch (pipe) {
-       case 0:
-               break;
-       case 1:
-               high_frame = PIPEBFRAMEHIGH;
-               low_frame = PIPEBFRAMEPIXEL;
-               pipeconf_reg = PIPEBCONF;
-               break;
-       case 2:
-               high_frame = PIPECFRAMEHIGH;
-               low_frame = PIPECFRAMEPIXEL;
-               pipeconf_reg = PIPECCONF;
-               break;
-       default:
-               dev_err(dev->dev, "%s, invalid pipe.\n", __func__);
-               return 0;
-       }
-
-       if (!gma_power_begin(dev, false))
-               return 0;
-
-       reg_val = REG_READ(pipeconf_reg);
-
-       if (!(reg_val & PIPEACONF_ENABLE)) {
-               dev_err(dev->dev, "trying to get vblank count for disabled pipe %d\n",
-                                                               pipe);
-               goto psb_get_vblank_counter_exit;
-       }
-
-       /*
-        * High & low register fields aren't synchronized, so make sure
-        * we get a low value that's stable across two reads of the high
-        * register.
-        */
-       do {
-               high1 = ((REG_READ(high_frame) & PIPE_FRAME_HIGH_MASK) >>
-                        PIPE_FRAME_HIGH_SHIFT);
-               low =  ((REG_READ(low_frame) & PIPE_FRAME_LOW_MASK) >>
-                       PIPE_FRAME_LOW_SHIFT);
-               high2 = ((REG_READ(high_frame) & PIPE_FRAME_HIGH_MASK) >>
-                        PIPE_FRAME_HIGH_SHIFT);
-       } while (high1 != high2);
-
-       count = (high1 << 8) | low;
-
-psb_get_vblank_counter_exit:
-
-       gma_power_end(dev);
-
-       return count;
-}
-
diff --git a/drivers/staging/gma500/psb_irq.h b/drivers/staging/gma500/psb_irq.h
deleted file mode 100644 (file)
index 216fda3..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-/**************************************************************************
- * Copyright (c) 2009-2011, Intel Corporation.
- * All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Authors:
- *    Benjamin Defnet <benjamin.r.defnet@intel.com>
- *    Rajesh Poornachandran <rajesh.poornachandran@intel.com>
- *
- **************************************************************************/
-
-#ifndef _SYSIRQ_H_
-#define _SYSIRQ_H_
-
-#include <drm/drmP.h>
-
-bool sysirq_init(struct drm_device *dev);
-void sysirq_uninit(struct drm_device *dev);
-
-void psb_irq_preinstall(struct drm_device *dev);
-int  psb_irq_postinstall(struct drm_device *dev);
-void psb_irq_uninstall(struct drm_device *dev);
-irqreturn_t psb_irq_handler(DRM_IRQ_ARGS);
-
-int psb_irq_enable_dpst(struct drm_device *dev);
-int psb_irq_disable_dpst(struct drm_device *dev);
-void psb_irq_turn_on_dpst(struct drm_device *dev);
-void psb_irq_turn_off_dpst(struct drm_device *dev);
-int  psb_enable_vblank(struct drm_device *dev, int pipe);
-void psb_disable_vblank(struct drm_device *dev, int pipe);
-u32  psb_get_vblank_counter(struct drm_device *dev, int pipe);
-
-#endif /* _SYSIRQ_H_ */
diff --git a/drivers/staging/gma500/psb_lid.c b/drivers/staging/gma500/psb_lid.c
deleted file mode 100644 (file)
index b867aab..0000000
+++ /dev/null
@@ -1,88 +0,0 @@
-/**************************************************************************
- * Copyright (c) 2007, Intel Corporation.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Authors: Thomas Hellstrom <thomas-at-tungstengraphics-dot-com>
- **************************************************************************/
-
-#include <drm/drmP.h>
-#include "psb_drv.h"
-#include "psb_reg.h"
-#include "psb_intel_reg.h"
-#include <linux/spinlock.h>
-
-static void psb_lid_timer_func(unsigned long data)
-{
-       struct drm_psb_private * dev_priv = (struct drm_psb_private *)data;
-       struct drm_device *dev = (struct drm_device *)dev_priv->dev;
-       struct timer_list *lid_timer = &dev_priv->lid_timer;
-       unsigned long irq_flags;
-       u32 *lid_state = dev_priv->lid_state;
-       u32 pp_status;
-
-       if (readl(lid_state) == dev_priv->lid_last_state)
-               goto lid_timer_schedule;
-
-       if ((readl(lid_state)) & 0x01) {
-               /*lid state is open*/
-               REG_WRITE(PP_CONTROL, REG_READ(PP_CONTROL) | POWER_TARGET_ON);
-               do {
-                       pp_status = REG_READ(PP_STATUS);
-               } while ((pp_status & PP_ON) == 0);
-
-               /*FIXME: should be backlight level before*/
-               psb_intel_lvds_set_brightness(dev, 100);
-       } else {
-               psb_intel_lvds_set_brightness(dev, 0);
-
-               REG_WRITE(PP_CONTROL, REG_READ(PP_CONTROL) & ~POWER_TARGET_ON);
-               do {
-                       pp_status = REG_READ(PP_STATUS);
-               } while ((pp_status & PP_ON) == 0);
-       }
-       dev_priv->lid_last_state =  readl(lid_state);
-
-lid_timer_schedule:
-       spin_lock_irqsave(&dev_priv->lid_lock, irq_flags);
-       if (!timer_pending(lid_timer)) {
-               lid_timer->expires = jiffies + PSB_LID_DELAY;
-               add_timer(lid_timer);
-       }
-       spin_unlock_irqrestore(&dev_priv->lid_lock, irq_flags);
-}
-
-void psb_lid_timer_init(struct drm_psb_private *dev_priv)
-{
-       struct timer_list *lid_timer = &dev_priv->lid_timer;
-       unsigned long irq_flags;
-
-       spin_lock_init(&dev_priv->lid_lock);
-       spin_lock_irqsave(&dev_priv->lid_lock, irq_flags);
-
-       init_timer(lid_timer);
-
-       lid_timer->data = (unsigned long)dev_priv;
-       lid_timer->function = psb_lid_timer_func;
-       lid_timer->expires = jiffies + PSB_LID_DELAY;
-
-       add_timer(lid_timer);
-       spin_unlock_irqrestore(&dev_priv->lid_lock, irq_flags);
-}
-
-void psb_lid_timer_takedown(struct drm_psb_private *dev_priv)
-{
-       del_timer_sync(&dev_priv->lid_timer);
-}
-
diff --git a/drivers/staging/gma500/psb_reg.h b/drivers/staging/gma500/psb_reg.h
deleted file mode 100644 (file)
index b81c7c1..0000000
+++ /dev/null
@@ -1,582 +0,0 @@
-/**************************************************************************
- *
- * Copyright (c) (2005-2007) Imagination Technologies Limited.
- * Copyright (c) 2007, Intel Corporation.
- * All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA..
- *
- **************************************************************************/
-
-#ifndef _PSB_REG_H_
-#define _PSB_REG_H_
-
-#define PSB_CR_CLKGATECTL              0x0000
-#define _PSB_C_CLKGATECTL_AUTO_MAN_REG         (1 << 24)
-#define _PSB_C_CLKGATECTL_USE_CLKG_SHIFT       (20)
-#define _PSB_C_CLKGATECTL_USE_CLKG_MASK                (0x3 << 20)
-#define _PSB_C_CLKGATECTL_DPM_CLKG_SHIFT       (16)
-#define _PSB_C_CLKGATECTL_DPM_CLKG_MASK                (0x3 << 16)
-#define _PSB_C_CLKGATECTL_TA_CLKG_SHIFT                (12)
-#define _PSB_C_CLKGATECTL_TA_CLKG_MASK         (0x3 << 12)
-#define _PSB_C_CLKGATECTL_TSP_CLKG_SHIFT       (8)
-#define _PSB_C_CLKGATECTL_TSP_CLKG_MASK                (0x3 << 8)
-#define _PSB_C_CLKGATECTL_ISP_CLKG_SHIFT       (4)
-#define _PSB_C_CLKGATECTL_ISP_CLKG_MASK                (0x3 << 4)
-#define _PSB_C_CLKGATECTL_2D_CLKG_SHIFT                (0)
-#define _PSB_C_CLKGATECTL_2D_CLKG_MASK         (0x3 << 0)
-#define _PSB_C_CLKGATECTL_CLKG_ENABLED         (0)
-#define _PSB_C_CLKGATECTL_CLKG_DISABLED                (1)
-#define _PSB_C_CLKGATECTL_CLKG_AUTO            (2)
-
-#define PSB_CR_CORE_ID                 0x0010
-#define _PSB_CC_ID_ID_SHIFT                    (16)
-#define _PSB_CC_ID_ID_MASK                     (0xFFFF << 16)
-#define _PSB_CC_ID_CONFIG_SHIFT                        (0)
-#define _PSB_CC_ID_CONFIG_MASK                 (0xFFFF << 0)
-
-#define PSB_CR_CORE_REVISION           0x0014
-#define _PSB_CC_REVISION_DESIGNER_SHIFT                (24)
-#define _PSB_CC_REVISION_DESIGNER_MASK         (0xFF << 24)
-#define _PSB_CC_REVISION_MAJOR_SHIFT           (16)
-#define _PSB_CC_REVISION_MAJOR_MASK            (0xFF << 16)
-#define _PSB_CC_REVISION_MINOR_SHIFT           (8)
-#define _PSB_CC_REVISION_MINOR_MASK            (0xFF << 8)
-#define _PSB_CC_REVISION_MAINTENANCE_SHIFT     (0)
-#define _PSB_CC_REVISION_MAINTENANCE_MASK      (0xFF << 0)
-
-#define PSB_CR_DESIGNER_REV_FIELD1     0x0018
-
-#define PSB_CR_SOFT_RESET              0x0080
-#define _PSB_CS_RESET_TSP_RESET                (1 << 6)
-#define _PSB_CS_RESET_ISP_RESET                (1 << 5)
-#define _PSB_CS_RESET_USE_RESET                (1 << 4)
-#define _PSB_CS_RESET_TA_RESET         (1 << 3)
-#define _PSB_CS_RESET_DPM_RESET                (1 << 2)
-#define _PSB_CS_RESET_TWOD_RESET       (1 << 1)
-#define _PSB_CS_RESET_BIF_RESET                        (1 << 0)
-
-#define PSB_CR_DESIGNER_REV_FIELD2     0x001C
-
-#define PSB_CR_EVENT_HOST_ENABLE2      0x0110
-
-#define PSB_CR_EVENT_STATUS2           0x0118
-
-#define PSB_CR_EVENT_HOST_CLEAR2       0x0114
-#define _PSB_CE2_BIF_REQUESTER_FAULT           (1 << 4)
-
-#define PSB_CR_EVENT_STATUS            0x012C
-
-#define PSB_CR_EVENT_HOST_ENABLE       0x0130
-
-#define PSB_CR_EVENT_HOST_CLEAR                0x0134
-#define _PSB_CE_MASTER_INTERRUPT               (1 << 31)
-#define _PSB_CE_TA_DPM_FAULT                   (1 << 28)
-#define _PSB_CE_TWOD_COMPLETE                  (1 << 27)
-#define _PSB_CE_DPM_OUT_OF_MEMORY_ZLS          (1 << 25)
-#define _PSB_CE_DPM_TA_MEM_FREE                        (1 << 24)
-#define _PSB_CE_PIXELBE_END_RENDER             (1 << 18)
-#define _PSB_CE_SW_EVENT                       (1 << 14)
-#define _PSB_CE_TA_FINISHED                    (1 << 13)
-#define _PSB_CE_TA_TERMINATE                   (1 << 12)
-#define _PSB_CE_DPM_REACHED_MEM_THRESH         (1 << 3)
-#define _PSB_CE_DPM_OUT_OF_MEMORY_GBL          (1 << 2)
-#define _PSB_CE_DPM_OUT_OF_MEMORY_MT           (1 << 1)
-#define _PSB_CE_DPM_3D_MEM_FREE                        (1 << 0)
-
-
-#define PSB_USE_OFFSET_MASK            0x0007FFFF
-#define PSB_USE_OFFSET_SIZE            (PSB_USE_OFFSET_MASK + 1)
-#define PSB_CR_USE_CODE_BASE0          0x0A0C
-#define PSB_CR_USE_CODE_BASE1          0x0A10
-#define PSB_CR_USE_CODE_BASE2          0x0A14
-#define PSB_CR_USE_CODE_BASE3          0x0A18
-#define PSB_CR_USE_CODE_BASE4          0x0A1C
-#define PSB_CR_USE_CODE_BASE5          0x0A20
-#define PSB_CR_USE_CODE_BASE6          0x0A24
-#define PSB_CR_USE_CODE_BASE7          0x0A28
-#define PSB_CR_USE_CODE_BASE8          0x0A2C
-#define PSB_CR_USE_CODE_BASE9          0x0A30
-#define PSB_CR_USE_CODE_BASE10         0x0A34
-#define PSB_CR_USE_CODE_BASE11         0x0A38
-#define PSB_CR_USE_CODE_BASE12         0x0A3C
-#define PSB_CR_USE_CODE_BASE13         0x0A40
-#define PSB_CR_USE_CODE_BASE14         0x0A44
-#define PSB_CR_USE_CODE_BASE15         0x0A48
-#define PSB_CR_USE_CODE_BASE(_i)       (0x0A0C + ((_i) << 2))
-#define _PSB_CUC_BASE_DM_SHIFT                 (25)
-#define _PSB_CUC_BASE_DM_MASK                  (0x3 << 25)
-#define _PSB_CUC_BASE_ADDR_SHIFT               (0)     /* 1024-bit aligned address? */
-#define _PSB_CUC_BASE_ADDR_ALIGNSHIFT          (7)
-#define _PSB_CUC_BASE_ADDR_MASK                        (0x1FFFFFF << 0)
-#define _PSB_CUC_DM_VERTEX                     (0)
-#define _PSB_CUC_DM_PIXEL                      (1)
-#define _PSB_CUC_DM_RESERVED                   (2)
-#define _PSB_CUC_DM_EDM                                (3)
-
-#define PSB_CR_PDS_EXEC_BASE           0x0AB8
-#define _PSB_CR_PDS_EXEC_BASE_ADDR_SHIFT       (20)    /* 1MB aligned address */
-#define _PSB_CR_PDS_EXEC_BASE_ADDR_ALIGNSHIFT  (20)
-
-#define PSB_CR_EVENT_KICKER            0x0AC4
-#define _PSB_CE_KICKER_ADDRESS_SHIFT           (4)     /* 128-bit aligned address */
-
-#define PSB_CR_EVENT_KICK              0x0AC8
-#define _PSB_CE_KICK_NOW                       (1 << 0)
-
-#define PSB_CR_BIF_DIR_LIST_BASE1      0x0C38
-
-#define PSB_CR_BIF_CTRL                        0x0C00
-#define _PSB_CB_CTRL_CLEAR_FAULT               (1 << 4)
-#define _PSB_CB_CTRL_INVALDC                   (1 << 3)
-#define _PSB_CB_CTRL_FLUSH                     (1 << 2)
-
-#define PSB_CR_BIF_INT_STAT            0x0C04
-
-#define PSB_CR_BIF_FAULT               0x0C08
-#define _PSB_CBI_STAT_PF_N_RW                  (1 << 14)
-#define _PSB_CBI_STAT_FAULT_SHIFT              (0)
-#define _PSB_CBI_STAT_FAULT_MASK               (0x3FFF << 0)
-#define _PSB_CBI_STAT_FAULT_CACHE              (1 << 1)
-#define _PSB_CBI_STAT_FAULT_TA                 (1 << 2)
-#define _PSB_CBI_STAT_FAULT_VDM                        (1 << 3)
-#define _PSB_CBI_STAT_FAULT_2D                 (1 << 4)
-#define _PSB_CBI_STAT_FAULT_PBE                        (1 << 5)
-#define _PSB_CBI_STAT_FAULT_TSP                        (1 << 6)
-#define _PSB_CBI_STAT_FAULT_ISP                        (1 << 7)
-#define _PSB_CBI_STAT_FAULT_USSEPDS            (1 << 8)
-#define _PSB_CBI_STAT_FAULT_HOST               (1 << 9)
-
-#define PSB_CR_BIF_BANK0               0x0C78
-#define PSB_CR_BIF_BANK1               0x0C7C
-#define PSB_CR_BIF_DIR_LIST_BASE0      0x0C84
-#define PSB_CR_BIF_TWOD_REQ_BASE       0x0C88
-#define PSB_CR_BIF_3D_REQ_BASE         0x0CAC
-
-#define PSB_CR_2D_SOCIF                        0x0E18
-#define _PSB_C2_SOCIF_FREESPACE_SHIFT          (0)
-#define _PSB_C2_SOCIF_FREESPACE_MASK           (0xFF << 0)
-#define _PSB_C2_SOCIF_EMPTY                    (0x80 << 0)
-
-#define PSB_CR_2D_BLIT_STATUS          0x0E04
-#define _PSB_C2B_STATUS_BUSY                   (1 << 24)
-#define _PSB_C2B_STATUS_COMPLETE_SHIFT         (0)
-#define _PSB_C2B_STATUS_COMPLETE_MASK          (0xFFFFFF << 0)
-
-/*
- * 2D defs.
- */
-
-/*
- * 2D Slave Port Data : Block Header's Object Type
- */
-
-#define        PSB_2D_CLIP_BH                  (0x00000000)
-#define        PSB_2D_PAT_BH                   (0x10000000)
-#define        PSB_2D_CTRL_BH                  (0x20000000)
-#define        PSB_2D_SRC_OFF_BH               (0x30000000)
-#define        PSB_2D_MASK_OFF_BH              (0x40000000)
-#define        PSB_2D_RESERVED1_BH             (0x50000000)
-#define        PSB_2D_RESERVED2_BH             (0x60000000)
-#define        PSB_2D_FENCE_BH                 (0x70000000)
-#define        PSB_2D_BLIT_BH                  (0x80000000)
-#define        PSB_2D_SRC_SURF_BH              (0x90000000)
-#define        PSB_2D_DST_SURF_BH              (0xA0000000)
-#define        PSB_2D_PAT_SURF_BH              (0xB0000000)
-#define        PSB_2D_SRC_PAL_BH               (0xC0000000)
-#define        PSB_2D_PAT_PAL_BH               (0xD0000000)
-#define        PSB_2D_MASK_SURF_BH             (0xE0000000)
-#define        PSB_2D_FLUSH_BH                 (0xF0000000)
-
-/*
- * Clip Definition block (PSB_2D_CLIP_BH)
- */
-#define PSB_2D_CLIPCOUNT_MAX           (1)
-#define PSB_2D_CLIPCOUNT_MASK          (0x00000000)
-#define PSB_2D_CLIPCOUNT_CLRMASK       (0xFFFFFFFF)
-#define PSB_2D_CLIPCOUNT_SHIFT         (0)
-/* clip rectangle min & max */
-#define PSB_2D_CLIP_XMAX_MASK          (0x00FFF000)
-#define PSB_2D_CLIP_XMAX_CLRMASK       (0xFF000FFF)
-#define PSB_2D_CLIP_XMAX_SHIFT         (12)
-#define PSB_2D_CLIP_XMIN_MASK          (0x00000FFF)
-#define PSB_2D_CLIP_XMIN_CLRMASK       (0x00FFF000)
-#define PSB_2D_CLIP_XMIN_SHIFT         (0)
-/* clip rectangle offset */
-#define PSB_2D_CLIP_YMAX_MASK          (0x00FFF000)
-#define PSB_2D_CLIP_YMAX_CLRMASK       (0xFF000FFF)
-#define PSB_2D_CLIP_YMAX_SHIFT         (12)
-#define PSB_2D_CLIP_YMIN_MASK          (0x00000FFF)
-#define PSB_2D_CLIP_YMIN_CLRMASK       (0x00FFF000)
-#define PSB_2D_CLIP_YMIN_SHIFT         (0)
-
-/*
- * Pattern Control (PSB_2D_PAT_BH)
- */
-#define PSB_2D_PAT_HEIGHT_MASK         (0x0000001F)
-#define PSB_2D_PAT_HEIGHT_SHIFT                (0)
-#define PSB_2D_PAT_WIDTH_MASK          (0x000003E0)
-#define PSB_2D_PAT_WIDTH_SHIFT         (5)
-#define PSB_2D_PAT_YSTART_MASK         (0x00007C00)
-#define PSB_2D_PAT_YSTART_SHIFT                (10)
-#define PSB_2D_PAT_XSTART_MASK         (0x000F8000)
-#define PSB_2D_PAT_XSTART_SHIFT                (15)
-
-/*
- * 2D Control block (PSB_2D_CTRL_BH)
- */
-/* Present Flags */
-#define PSB_2D_SRCCK_CTRL              (0x00000001)
-#define PSB_2D_DSTCK_CTRL              (0x00000002)
-#define PSB_2D_ALPHA_CTRL              (0x00000004)
-/* Colour Key Colour (SRC/DST)*/
-#define PSB_2D_CK_COL_MASK             (0xFFFFFFFF)
-#define PSB_2D_CK_COL_CLRMASK          (0x00000000)
-#define PSB_2D_CK_COL_SHIFT            (0)
-/* Colour Key Mask (SRC/DST)*/
-#define PSB_2D_CK_MASK_MASK            (0xFFFFFFFF)
-#define PSB_2D_CK_MASK_CLRMASK         (0x00000000)
-#define PSB_2D_CK_MASK_SHIFT           (0)
-/* Alpha Control (Alpha/RGB)*/
-#define PSB_2D_GBLALPHA_MASK           (0x000FF000)
-#define PSB_2D_GBLALPHA_CLRMASK                (0xFFF00FFF)
-#define PSB_2D_GBLALPHA_SHIFT          (12)
-#define PSB_2D_SRCALPHA_OP_MASK                (0x00700000)
-#define PSB_2D_SRCALPHA_OP_CLRMASK     (0xFF8FFFFF)
-#define PSB_2D_SRCALPHA_OP_SHIFT       (20)
-#define PSB_2D_SRCALPHA_OP_ONE         (0x00000000)
-#define PSB_2D_SRCALPHA_OP_SRC         (0x00100000)
-#define PSB_2D_SRCALPHA_OP_DST         (0x00200000)
-#define PSB_2D_SRCALPHA_OP_SG          (0x00300000)
-#define PSB_2D_SRCALPHA_OP_DG          (0x00400000)
-#define PSB_2D_SRCALPHA_OP_GBL         (0x00500000)
-#define PSB_2D_SRCALPHA_OP_ZERO                (0x00600000)
-#define PSB_2D_SRCALPHA_INVERT         (0x00800000)
-#define PSB_2D_SRCALPHA_INVERT_CLR     (0xFF7FFFFF)
-#define PSB_2D_DSTALPHA_OP_MASK                (0x07000000)
-#define PSB_2D_DSTALPHA_OP_CLRMASK     (0xF8FFFFFF)
-#define PSB_2D_DSTALPHA_OP_SHIFT       (24)
-#define PSB_2D_DSTALPHA_OP_ONE         (0x00000000)
-#define PSB_2D_DSTALPHA_OP_SRC         (0x01000000)
-#define PSB_2D_DSTALPHA_OP_DST         (0x02000000)
-#define PSB_2D_DSTALPHA_OP_SG          (0x03000000)
-#define PSB_2D_DSTALPHA_OP_DG          (0x04000000)
-#define PSB_2D_DSTALPHA_OP_GBL         (0x05000000)
-#define PSB_2D_DSTALPHA_OP_ZERO                (0x06000000)
-#define PSB_2D_DSTALPHA_INVERT         (0x08000000)
-#define PSB_2D_DSTALPHA_INVERT_CLR     (0xF7FFFFFF)
-
-#define PSB_2D_PRE_MULTIPLICATION_ENABLE       (0x10000000)
-#define PSB_2D_PRE_MULTIPLICATION_CLRMASK      (0xEFFFFFFF)
-#define PSB_2D_ZERO_SOURCE_ALPHA_ENABLE                (0x20000000)
-#define PSB_2D_ZERO_SOURCE_ALPHA_CLRMASK       (0xDFFFFFFF)
-
-/*
- *Source Offset (PSB_2D_SRC_OFF_BH)
- */
-#define PSB_2D_SRCOFF_XSTART_MASK      ((0x00000FFF) << 12)
-#define PSB_2D_SRCOFF_XSTART_SHIFT     (12)
-#define PSB_2D_SRCOFF_YSTART_MASK      (0x00000FFF)
-#define PSB_2D_SRCOFF_YSTART_SHIFT     (0)
-
-/*
- * Mask Offset (PSB_2D_MASK_OFF_BH)
- */
-#define PSB_2D_MASKOFF_XSTART_MASK     ((0x00000FFF) << 12)
-#define PSB_2D_MASKOFF_XSTART_SHIFT    (12)
-#define PSB_2D_MASKOFF_YSTART_MASK     (0x00000FFF)
-#define PSB_2D_MASKOFF_YSTART_SHIFT    (0)
-
-/*
- * 2D Fence (see PSB_2D_FENCE_BH): bits 0:27 are ignored
- */
-
-/*
- *Blit Rectangle (PSB_2D_BLIT_BH)
- */
-
-#define PSB_2D_ROT_MASK                        (3 << 25)
-#define PSB_2D_ROT_CLRMASK             (~PSB_2D_ROT_MASK)
-#define PSB_2D_ROT_NONE                        (0 << 25)
-#define PSB_2D_ROT_90DEGS              (1 << 25)
-#define PSB_2D_ROT_180DEGS             (2 << 25)
-#define PSB_2D_ROT_270DEGS             (3 << 25)
-
-#define PSB_2D_COPYORDER_MASK          (3 << 23)
-#define PSB_2D_COPYORDER_CLRMASK       (~PSB_2D_COPYORDER_MASK)
-#define PSB_2D_COPYORDER_TL2BR         (0 << 23)
-#define PSB_2D_COPYORDER_BR2TL         (1 << 23)
-#define PSB_2D_COPYORDER_TR2BL         (2 << 23)
-#define PSB_2D_COPYORDER_BL2TR         (3 << 23)
-
-#define PSB_2D_DSTCK_CLRMASK           (0xFF9FFFFF)
-#define PSB_2D_DSTCK_DISABLE           (0x00000000)
-#define PSB_2D_DSTCK_PASS              (0x00200000)
-#define PSB_2D_DSTCK_REJECT            (0x00400000)
-
-#define PSB_2D_SRCCK_CLRMASK           (0xFFE7FFFF)
-#define PSB_2D_SRCCK_DISABLE           (0x00000000)
-#define PSB_2D_SRCCK_PASS              (0x00080000)
-#define PSB_2D_SRCCK_REJECT            (0x00100000)
-
-#define PSB_2D_CLIP_ENABLE             (0x00040000)
-
-#define PSB_2D_ALPHA_ENABLE            (0x00020000)
-
-#define PSB_2D_PAT_CLRMASK             (0xFFFEFFFF)
-#define PSB_2D_PAT_MASK                        (0x00010000)
-#define PSB_2D_USE_PAT                 (0x00010000)
-#define PSB_2D_USE_FILL                        (0x00000000)
-/*
- * Tungsten Graphics note on rop codes: If rop A and rop B are
- * identical, the mask surface will not be read and need not be
- * set up.
- */
-
-#define PSB_2D_ROP3B_MASK              (0x0000FF00)
-#define PSB_2D_ROP3B_CLRMASK           (0xFFFF00FF)
-#define PSB_2D_ROP3B_SHIFT             (8)
-/* rop code A */
-#define PSB_2D_ROP3A_MASK              (0x000000FF)
-#define PSB_2D_ROP3A_CLRMASK           (0xFFFFFF00)
-#define PSB_2D_ROP3A_SHIFT             (0)
-
-#define PSB_2D_ROP4_MASK               (0x0000FFFF)
-/*
- *     DWORD0: (Only pass if Pattern control == Use Fill Colour)
- *     Fill Colour RGBA8888
- */
-#define PSB_2D_FILLCOLOUR_MASK         (0xFFFFFFFF)
-#define PSB_2D_FILLCOLOUR_SHIFT                (0)
-/*
- *     DWORD1: (Always Present)
- *     X Start (Dest)
- *     Y Start (Dest)
- */
-#define PSB_2D_DST_XSTART_MASK         (0x00FFF000)
-#define PSB_2D_DST_XSTART_CLRMASK      (0xFF000FFF)
-#define PSB_2D_DST_XSTART_SHIFT                (12)
-#define PSB_2D_DST_YSTART_MASK         (0x00000FFF)
-#define PSB_2D_DST_YSTART_CLRMASK      (0xFFFFF000)
-#define PSB_2D_DST_YSTART_SHIFT                (0)
-/*
- *     DWORD2: (Always Present)
- *     X Size (Dest)
- *     Y Size (Dest)
- */
-#define PSB_2D_DST_XSIZE_MASK          (0x00FFF000)
-#define PSB_2D_DST_XSIZE_CLRMASK       (0xFF000FFF)
-#define PSB_2D_DST_XSIZE_SHIFT         (12)
-#define PSB_2D_DST_YSIZE_MASK          (0x00000FFF)
-#define PSB_2D_DST_YSIZE_CLRMASK       (0xFFFFF000)
-#define PSB_2D_DST_YSIZE_SHIFT         (0)
-
-/*
- * Source Surface (PSB_2D_SRC_SURF_BH)
- */
-/*
- * WORD 0
- */
-
-#define PSB_2D_SRC_FORMAT_MASK         (0x00078000)
-#define PSB_2D_SRC_1_PAL               (0x00000000)
-#define PSB_2D_SRC_2_PAL               (0x00008000)
-#define PSB_2D_SRC_4_PAL               (0x00010000)
-#define PSB_2D_SRC_8_PAL               (0x00018000)
-#define PSB_2D_SRC_8_ALPHA             (0x00020000)
-#define PSB_2D_SRC_4_ALPHA             (0x00028000)
-#define PSB_2D_SRC_332RGB              (0x00030000)
-#define PSB_2D_SRC_4444ARGB            (0x00038000)
-#define PSB_2D_SRC_555RGB              (0x00040000)
-#define PSB_2D_SRC_1555ARGB            (0x00048000)
-#define PSB_2D_SRC_565RGB              (0x00050000)
-#define PSB_2D_SRC_0888ARGB            (0x00058000)
-#define PSB_2D_SRC_8888ARGB            (0x00060000)
-#define PSB_2D_SRC_8888UYVY            (0x00068000)
-#define PSB_2D_SRC_RESERVED            (0x00070000)
-#define PSB_2D_SRC_1555ARGB_LOOKUP     (0x00078000)
-
-
-#define PSB_2D_SRC_STRIDE_MASK         (0x00007FFF)
-#define PSB_2D_SRC_STRIDE_CLRMASK      (0xFFFF8000)
-#define PSB_2D_SRC_STRIDE_SHIFT                (0)
-/*
- *  WORD 1 - Base Address
- */
-#define PSB_2D_SRC_ADDR_MASK           (0x0FFFFFFC)
-#define PSB_2D_SRC_ADDR_CLRMASK                (0x00000003)
-#define PSB_2D_SRC_ADDR_SHIFT          (2)
-#define PSB_2D_SRC_ADDR_ALIGNSHIFT     (2)
-
-/*
- * Pattern Surface (PSB_2D_PAT_SURF_BH)
- */
-/*
- *  WORD 0
- */
-
-#define PSB_2D_PAT_FORMAT_MASK         (0x00078000)
-#define PSB_2D_PAT_1_PAL               (0x00000000)
-#define PSB_2D_PAT_2_PAL               (0x00008000)
-#define PSB_2D_PAT_4_PAL               (0x00010000)
-#define PSB_2D_PAT_8_PAL               (0x00018000)
-#define PSB_2D_PAT_8_ALPHA             (0x00020000)
-#define PSB_2D_PAT_4_ALPHA             (0x00028000)
-#define PSB_2D_PAT_332RGB              (0x00030000)
-#define PSB_2D_PAT_4444ARGB            (0x00038000)
-#define PSB_2D_PAT_555RGB              (0x00040000)
-#define PSB_2D_PAT_1555ARGB            (0x00048000)
-#define PSB_2D_PAT_565RGB              (0x00050000)
-#define PSB_2D_PAT_0888ARGB            (0x00058000)
-#define PSB_2D_PAT_8888ARGB            (0x00060000)
-
-#define PSB_2D_PAT_STRIDE_MASK         (0x00007FFF)
-#define PSB_2D_PAT_STRIDE_CLRMASK      (0xFFFF8000)
-#define PSB_2D_PAT_STRIDE_SHIFT                (0)
-/*
- *  WORD 1 - Base Address
- */
-#define PSB_2D_PAT_ADDR_MASK           (0x0FFFFFFC)
-#define PSB_2D_PAT_ADDR_CLRMASK                (0x00000003)
-#define PSB_2D_PAT_ADDR_SHIFT          (2)
-#define PSB_2D_PAT_ADDR_ALIGNSHIFT     (2)
-
-/*
- * Destination Surface (PSB_2D_DST_SURF_BH)
- */
-/*
- * WORD 0
- */
-
-#define PSB_2D_DST_FORMAT_MASK         (0x00078000)
-#define PSB_2D_DST_332RGB              (0x00030000)
-#define PSB_2D_DST_4444ARGB            (0x00038000)
-#define PSB_2D_DST_555RGB              (0x00040000)
-#define PSB_2D_DST_1555ARGB            (0x00048000)
-#define PSB_2D_DST_565RGB              (0x00050000)
-#define PSB_2D_DST_0888ARGB            (0x00058000)
-#define PSB_2D_DST_8888ARGB            (0x00060000)
-#define PSB_2D_DST_8888AYUV            (0x00070000)
-
-#define PSB_2D_DST_STRIDE_MASK         (0x00007FFF)
-#define PSB_2D_DST_STRIDE_CLRMASK      (0xFFFF8000)
-#define PSB_2D_DST_STRIDE_SHIFT                (0)
-/*
- * WORD 1 - Base Address
- */
-#define PSB_2D_DST_ADDR_MASK           (0x0FFFFFFC)
-#define PSB_2D_DST_ADDR_CLRMASK                (0x00000003)
-#define PSB_2D_DST_ADDR_SHIFT          (2)
-#define PSB_2D_DST_ADDR_ALIGNSHIFT     (2)
-
-/*
- * Mask Surface (PSB_2D_MASK_SURF_BH)
- */
-/*
- * WORD 0
- */
-#define PSB_2D_MASK_STRIDE_MASK                (0x00007FFF)
-#define PSB_2D_MASK_STRIDE_CLRMASK     (0xFFFF8000)
-#define PSB_2D_MASK_STRIDE_SHIFT       (0)
-/*
- *  WORD 1 - Base Address
- */
-#define PSB_2D_MASK_ADDR_MASK          (0x0FFFFFFC)
-#define PSB_2D_MASK_ADDR_CLRMASK       (0x00000003)
-#define PSB_2D_MASK_ADDR_SHIFT         (2)
-#define PSB_2D_MASK_ADDR_ALIGNSHIFT    (2)
-
-/*
- * Source Palette (PSB_2D_SRC_PAL_BH)
- */
-
-#define PSB_2D_SRCPAL_ADDR_SHIFT       (0)
-#define PSB_2D_SRCPAL_ADDR_CLRMASK     (0xF0000007)
-#define PSB_2D_SRCPAL_ADDR_MASK                (0x0FFFFFF8)
-#define PSB_2D_SRCPAL_BYTEALIGN                (1024)
-
-/*
- * Pattern Palette (PSB_2D_PAT_PAL_BH)
- */
-
-#define PSB_2D_PATPAL_ADDR_SHIFT       (0)
-#define PSB_2D_PATPAL_ADDR_CLRMASK     (0xF0000007)
-#define PSB_2D_PATPAL_ADDR_MASK                (0x0FFFFFF8)
-#define PSB_2D_PATPAL_BYTEALIGN                (1024)
-
-/*
- * Rop3 Codes (2 LS bytes)
- */
-
-#define PSB_2D_ROP3_SRCCOPY            (0xCCCC)
-#define PSB_2D_ROP3_PATCOPY            (0xF0F0)
-#define PSB_2D_ROP3_WHITENESS          (0xFFFF)
-#define PSB_2D_ROP3_BLACKNESS          (0x0000)
-#define PSB_2D_ROP3_SRC                        (0xCC)
-#define PSB_2D_ROP3_PAT                        (0xF0)
-#define PSB_2D_ROP3_DST                        (0xAA)
-
-/*
- * Sizes.
- */
-
-#define PSB_SCENE_HW_COOKIE_SIZE       16
-#define PSB_TA_MEM_HW_COOKIE_SIZE      16
-
-/*
- * Scene stuff.
- */
-
-#define PSB_NUM_HW_SCENES              2
-
-/*
- * Scheduler completion actions.
- */
-
-#define PSB_RASTER_BLOCK               0
-#define PSB_RASTER                     1
-#define PSB_RETURN                     2
-#define PSB_TA                         3
-
-/* Power management */
-#define PSB_PUNIT_PORT                 0x04
-#define PSB_OSPMBA                     0x78
-#define PSB_APMBA                      0x7a
-#define PSB_APM_CMD                    0x0
-#define PSB_APM_STS                    0x04
-#define PSB_PWRGT_VID_ENC_MASK         0x30
-#define PSB_PWRGT_VID_DEC_MASK         0xc
-#define PSB_PWRGT_GL3_MASK             0xc0
-
-#define PSB_PM_SSC                     0x20
-#define PSB_PM_SSS                     0x30
-#define PSB_PWRGT_DISPLAY_MASK         0xc /*on a different BA than video/gfx*/
-#define MDFLD_PWRGT_DISPLAY_A_CNTR     0x0000000c
-#define MDFLD_PWRGT_DISPLAY_B_CNTR     0x0000c000
-#define MDFLD_PWRGT_DISPLAY_C_CNTR     0x00030000
-#define MDFLD_PWRGT_DISP_MIPI_CNTR     0x000c0000
-#define MDFLD_PWRGT_DISPLAY_CNTR    (MDFLD_PWRGT_DISPLAY_A_CNTR | MDFLD_PWRGT_DISPLAY_B_CNTR | MDFLD_PWRGT_DISPLAY_C_CNTR | MDFLD_PWRGT_DISP_MIPI_CNTR) /* 0x000fc00c */
-/* Display SSS register bits are different in A0 vs. B0 */
-#define PSB_PWRGT_GFX_MASK             0x3
-#define MDFLD_PWRGT_DISPLAY_A_STS      0x000000c0
-#define MDFLD_PWRGT_DISPLAY_B_STS      0x00000300
-#define MDFLD_PWRGT_DISPLAY_C_STS      0x00000c00
-#define PSB_PWRGT_GFX_MASK_B0          0xc3
-#define MDFLD_PWRGT_DISPLAY_A_STS_B0   0x0000000c
-#define MDFLD_PWRGT_DISPLAY_B_STS_B0   0x0000c000
-#define MDFLD_PWRGT_DISPLAY_C_STS_B0   0x00030000
-#define MDFLD_PWRGT_DISP_MIPI_STS      0x000c0000
-#define MDFLD_PWRGT_DISPLAY_STS_A0    (MDFLD_PWRGT_DISPLAY_A_STS | MDFLD_PWRGT_DISPLAY_B_STS | MDFLD_PWRGT_DISPLAY_C_STS | MDFLD_PWRGT_DISP_MIPI_STS) /* 0x000fc00c */
-#define MDFLD_PWRGT_DISPLAY_STS_B0    (MDFLD_PWRGT_DISPLAY_A_STS_B0 | MDFLD_PWRGT_DISPLAY_B_STS_B0 | MDFLD_PWRGT_DISPLAY_C_STS_B0 | MDFLD_PWRGT_DISP_MIPI_STS) /* 0x000fc00c */
-#endif
index 70e006b..5443e25 100644 (file)
@@ -1279,3 +1279,4 @@ static struct usb_driver go7007_usb_driver = {
 };
 
 module_usb_driver(go7007_usb_driver);
+MODULE_LICENSE("GPL v2");
index 592cf69..d9cdc12 100644 (file)
@@ -7,6 +7,7 @@ ccflags-y := -Iinclude/drm -Werror
 omapdrm-y := omap_drv.o \
        omap_debugfs.o \
        omap_crtc.o \
+       omap_plane.o \
        omap_encoder.o \
        omap_connector.o \
        omap_fb.o \
index cffdf5e..17ca163 100644 (file)
 
 struct omap_crtc {
        struct drm_crtc base;
-       struct omap_overlay *ovl;
-       struct omap_overlay_info info;
+       struct drm_plane *plane;
+       const char *name;
        int id;
 
-       /* if there is a pending flip, this will be non-null: */
+       /* if there is a pending flip, these will be non-null: */
        struct drm_pending_vblank_event *event;
+       struct drm_framebuffer *old_fb;
 };
 
-/* push changes down to dss2 */
-static int commit(struct drm_crtc *crtc)
-{
-       struct drm_device *dev = crtc->dev;
-       struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
-       struct omap_overlay *ovl = omap_crtc->ovl;
-       struct omap_overlay_info *info = &omap_crtc->info;
-       int ret;
-
-       DBG("%s", omap_crtc->ovl->name);
-       DBG("%dx%d -> %dx%d (%d)", info->width, info->height, info->out_width,
-                       info->out_height, info->screen_width);
-       DBG("%d,%d %08x", info->pos_x, info->pos_y, info->paddr);
-
-       /* NOTE: do we want to do this at all here, or just wait
-        * for dpms(ON) since other CRTC's may not have their mode
-        * set yet, so fb dimensions may still change..
-        */
-       ret = ovl->set_overlay_info(ovl, info);
-       if (ret) {
-               dev_err(dev->dev, "could not set overlay info\n");
-               return ret;
-       }
-
-       /* our encoder doesn't necessarily get a commit() after this, in
-        * particular in the dpms() and mode_set_base() cases, so force the
-        * manager to update:
-        *
-        * could this be in the encoder somehow?
-        */
-       if (ovl->manager) {
-               ret = ovl->manager->apply(ovl->manager);
-               if (ret) {
-                       dev_err(dev->dev, "could not apply settings\n");
-                       return ret;
-               }
-       }
-
-       if (info->enabled) {
-               omap_framebuffer_flush(crtc->fb, crtc->x, crtc->y,
-                               crtc->fb->width, crtc->fb->height);
-       }
-
-       return 0;
-}
-
-/* update parameters that are dependent on the framebuffer dimensions and
- * position within the fb that this crtc scans out from. This is called
- * when framebuffer dimensions or x,y base may have changed, either due
- * to our mode, or a change in another crtc that is scanning out of the
- * same fb.
- */
-static void update_scanout(struct drm_crtc *crtc)
-{
-       struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
-       dma_addr_t paddr;
-       unsigned int screen_width;
-
-       omap_framebuffer_get_buffer(crtc->fb, crtc->x, crtc->y,
-                       NULL, &paddr, &screen_width);
-
-       DBG("%s: %d,%d: %08x (%d)", omap_crtc->ovl->name,
-                       crtc->x, crtc->y, (u32)paddr, screen_width);
-
-       omap_crtc->info.paddr = paddr;
-       omap_crtc->info.screen_width = screen_width;
-}
-
 static void omap_crtc_gamma_set(struct drm_crtc *crtc,
                u16 *red, u16 *green, u16 *blue, uint32_t start, uint32_t size)
 {
-       struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
-       DBG("%s", omap_crtc->ovl->name);
+       /* not supported.. at least not yet */
 }
 
 static void omap_crtc_destroy(struct drm_crtc *crtc)
 {
        struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
-       DBG("%s", omap_crtc->ovl->name);
+       omap_crtc->plane->funcs->destroy(omap_crtc->plane);
        drm_crtc_cleanup(crtc);
        kfree(omap_crtc);
 }
 
 static void omap_crtc_dpms(struct drm_crtc *crtc, int mode)
 {
+       struct omap_drm_private *priv = crtc->dev->dev_private;
        struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
+       int i;
 
-       DBG("%s: %d", omap_crtc->ovl->name, mode);
+       WARN_ON(omap_plane_dpms(omap_crtc->plane, mode));
 
-       if (mode == DRM_MODE_DPMS_ON) {
-               update_scanout(crtc);
-               omap_crtc->info.enabled = true;
-       } else {
-               omap_crtc->info.enabled = false;
+       for (i = 0; i < priv->num_planes; i++) {
+               struct drm_plane *plane = priv->planes[i];
+               if (plane->crtc == crtc)
+                       WARN_ON(omap_plane_dpms(plane, mode));
        }
-
-       WARN_ON(commit(crtc));
 }
 
 static bool omap_crtc_mode_fixup(struct drm_crtc *crtc,
-                                 struct drm_display_mode *mode,
-                                 struct drm_display_mode *adjusted_mode)
+               struct drm_display_mode *mode,
+               struct drm_display_mode *adjusted_mode)
 {
-       struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
-       DBG("%s", omap_crtc->ovl->name);
        return true;
 }
 
 static int omap_crtc_mode_set(struct drm_crtc *crtc,
-                              struct drm_display_mode *mode,
-                              struct drm_display_mode *adjusted_mode,
-                              int x, int y,
-                              struct drm_framebuffer *old_fb)
+               struct drm_display_mode *mode,
+               struct drm_display_mode *adjusted_mode,
+               int x, int y,
+               struct drm_framebuffer *old_fb)
 {
        struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
+       struct drm_plane *plane = omap_crtc->plane;
 
-       DBG("%s: %d,%d: %dx%d", omap_crtc->ovl->name, x, y,
-                       mode->hdisplay, mode->vdisplay);
-
-       /* just use adjusted mode */
-       mode = adjusted_mode;
-
-       omap_crtc->info.width = mode->hdisplay;
-       omap_crtc->info.height = mode->vdisplay;
-       omap_crtc->info.out_width = mode->hdisplay;
-       omap_crtc->info.out_height = mode->vdisplay;
-       omap_crtc->info.color_mode = OMAP_DSS_COLOR_RGB24U;
-       omap_crtc->info.rotation_type = OMAP_DSS_ROT_DMA;
-       omap_crtc->info.rotation = OMAP_DSS_ROT_0;
-       omap_crtc->info.global_alpha = 0xff;
-       omap_crtc->info.mirror = 0;
-       omap_crtc->info.mirror = 0;
-       omap_crtc->info.pos_x = 0;
-       omap_crtc->info.pos_y = 0;
-#if 0 /* re-enable when these are available in DSS2 driver */
-       omap_crtc->info.zorder = 3;        /* GUI in the front, video behind */
-       omap_crtc->info.min_x_decim = 1;
-       omap_crtc->info.max_x_decim = 1;
-       omap_crtc->info.min_y_decim = 1;
-       omap_crtc->info.max_y_decim = 1;
-#endif
-
-       update_scanout(crtc);
-
-       return 0;
+       return omap_plane_mode_set(plane, crtc, crtc->fb,
+                       0, 0, mode->hdisplay, mode->vdisplay,
+                       x << 16, y << 16,
+                       mode->hdisplay << 16, mode->vdisplay << 16);
 }
 
 static void omap_crtc_prepare(struct drm_crtc *crtc)
 {
        struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
-       struct omap_overlay *ovl = omap_crtc->ovl;
-
-       DBG("%s", omap_crtc->ovl->name);
-
-       ovl->get_overlay_info(ovl, &omap_crtc->info);
-
+       DBG("%s", omap_crtc->name);
        omap_crtc_dpms(crtc, DRM_MODE_DPMS_OFF);
 }
 
 static void omap_crtc_commit(struct drm_crtc *crtc)
 {
        struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
-       DBG("%s", omap_crtc->ovl->name);
+       DBG("%s", omap_crtc->name);
        omap_crtc_dpms(crtc, DRM_MODE_DPMS_ON);
 }
 
 static int omap_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
-                   struct drm_framebuffer *old_fb)
+               struct drm_framebuffer *old_fb)
 {
        struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
+       struct drm_plane *plane = omap_crtc->plane;
+       struct drm_display_mode *mode = &crtc->mode;
 
-       DBG("%s %d,%d: fb=%p", omap_crtc->ovl->name, x, y, old_fb);
-
-       update_scanout(crtc);
-
-       return commit(crtc);
+       return plane->funcs->update_plane(plane, crtc, crtc->fb,
+                       0, 0, mode->hdisplay, mode->vdisplay,
+                       x << 16, y << 16,
+                       mode->hdisplay << 16, mode->vdisplay << 16);
 }
 
 static void omap_crtc_load_lut(struct drm_crtc *crtc)
 {
-       struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
-       DBG("%s", omap_crtc->ovl->name);
 }
 
 static void page_flip_cb(void *arg)
@@ -225,15 +124,16 @@ static void page_flip_cb(void *arg)
        struct drm_device *dev = crtc->dev;
        struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
        struct drm_pending_vblank_event *event = omap_crtc->event;
+       struct drm_framebuffer *old_fb = omap_crtc->old_fb;
        struct timeval now;
        unsigned long flags;
 
        WARN_ON(!event);
 
        omap_crtc->event = NULL;
+       omap_crtc->old_fb = NULL;
 
-       update_scanout(crtc);
-       WARN_ON(commit(crtc));
+       omap_crtc_mode_set_base(crtc, crtc->x, crtc->y, old_fb);
 
        /* wakeup userspace */
        /* TODO: this should happen *after* flip in vsync IRQ handler */
@@ -264,10 +164,11 @@ static int omap_crtc_page_flip_locked(struct drm_crtc *crtc,
                return -EINVAL;
        }
 
-       crtc->fb = fb;
+       omap_crtc->old_fb = crtc->fb;
        omap_crtc->event = event;
+       crtc->fb = fb;
 
-       omap_gem_op_async(omap_framebuffer_bo(fb), OMAP_GEM_READ,
+       omap_gem_op_async(omap_framebuffer_bo(fb, 0), OMAP_GEM_READ,
                        page_flip_cb, crtc);
 
        return 0;
@@ -290,12 +191,6 @@ static const struct drm_crtc_helper_funcs omap_crtc_helper_funcs = {
        .load_lut = omap_crtc_load_lut,
 };
 
-struct omap_overlay *omap_crtc_get_overlay(struct drm_crtc *crtc)
-{
-       struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
-       return omap_crtc->ovl;
-}
-
 /* initialize crtc */
 struct drm_crtc *omap_crtc_init(struct drm_device *dev,
                struct omap_overlay *ovl, int id)
@@ -310,9 +205,13 @@ struct drm_crtc *omap_crtc_init(struct drm_device *dev,
                goto fail;
        }
 
-       omap_crtc->ovl = ovl;
-       omap_crtc->id = id;
        crtc = &omap_crtc->base;
+
+       omap_crtc->plane = omap_plane_init(dev, ovl, (1 << id), true);
+       omap_crtc->plane->crtc = crtc;
+       omap_crtc->name = ovl->name;
+       omap_crtc->id = id;
+
        drm_crtc_init(dev, crtc, &omap_crtc_funcs);
        drm_crtc_helper_add(crtc, &omap_crtc_helper_funcs);
 
index 602aa2d..3bbea9a 100644 (file)
@@ -204,12 +204,6 @@ static int create_crtc(struct drm_device *dev, struct omap_overlay *ovl,
        struct omap_overlay_manager *mgr = NULL;
        struct drm_crtc *crtc;
 
-       if (ovl->manager) {
-               DBG("disconnecting %s from %s", ovl->name,
-                                       ovl->manager->name);
-               ovl->unset_manager(ovl);
-       }
-
        /* find next best connector, ones with detected connection first
         */
        while (*j < priv->num_connectors && !mgr) {
@@ -245,11 +239,6 @@ static int create_crtc(struct drm_device *dev, struct omap_overlay *ovl,
                (*j)++;
        }
 
-       if (mgr) {
-               DBG("connecting %s to %s", ovl->name, mgr->name);
-               ovl->set_manager(ovl, mgr);
-       }
-
        crtc = omap_crtc_init(dev, ovl, priv->num_crtcs);
 
        if (!crtc) {
@@ -265,6 +254,26 @@ static int create_crtc(struct drm_device *dev, struct omap_overlay *ovl,
        return 0;
 }
 
+static int create_plane(struct drm_device *dev, struct omap_overlay *ovl,
+               unsigned int possible_crtcs)
+{
+       struct omap_drm_private *priv = dev->dev_private;
+       struct drm_plane *plane =
+                       omap_plane_init(dev, ovl, possible_crtcs, false);
+
+       if (!plane) {
+               dev_err(dev->dev, "could not create plane: %s\n",
+                               ovl->name);
+               return -ENOMEM;
+       }
+
+       BUG_ON(priv->num_planes >= ARRAY_SIZE(priv->planes));
+
+       priv->planes[priv->num_planes++] = plane;
+
+       return 0;
+}
+
 static int match_dev_name(struct omap_dss_device *dssdev, void *data)
 {
        return !strcmp(dssdev->name, data);
@@ -332,6 +341,12 @@ static int omap_modeset_init(struct drm_device *dev)
                                omap_dss_get_overlay(kms_pdata->ovl_ids[i]);
                        create_crtc(dev, ovl, &j, connected_connectors);
                }
+
+               for (i = 0; i < kms_pdata->pln_cnt; i++) {
+                       struct omap_overlay *ovl =
+                               omap_dss_get_overlay(kms_pdata->pln_ids[i]);
+                       create_plane(dev, ovl, (1 << priv->num_crtcs) - 1);
+               }
        } else {
                /* otherwise just grab up to CONFIG_DRM_OMAP_NUM_CRTCS and try
                 * to make educated guesses about everything else
@@ -353,6 +368,12 @@ static int omap_modeset_init(struct drm_device *dev)
                        create_crtc(dev, omap_dss_get_overlay(i),
                                        &j, connected_connectors);
                }
+
+               /* use any remaining overlays as drm planes */
+               for (; i < omap_dss_get_num_overlays(); i++) {
+                       struct omap_overlay *ovl = omap_dss_get_overlay(i);
+                       create_plane(dev, ovl, (1 << priv->num_crtcs) - 1);
+               }
        }
 
        /* for now keep the mapping of CRTCs and encoders static.. */
@@ -361,15 +382,7 @@ static int omap_modeset_init(struct drm_device *dev)
                struct omap_overlay_manager *mgr =
                                omap_encoder_get_manager(encoder);
 
-               encoder->possible_crtcs = 0;
-
-               for (j = 0; j < priv->num_crtcs; j++) {
-                       struct omap_overlay *ovl =
-                                       omap_crtc_get_overlay(priv->crtcs[j]);
-                       if (ovl->manager == mgr) {
-                               encoder->possible_crtcs |= (1 << j);
-                       }
-               }
+               encoder->possible_crtcs = (1 << priv->num_crtcs) - 1;
 
                DBG("%s: possible_crtcs=%08x", mgr->name,
                                        encoder->possible_crtcs);
@@ -377,8 +390,8 @@ static int omap_modeset_init(struct drm_device *dev)
 
        dump_video_chains();
 
-       dev->mode_config.min_width = 256;
-       dev->mode_config.min_height = 256;
+       dev->mode_config.min_width = 32;
+       dev->mode_config.min_height = 32;
 
        /* note: eventually will need some cpu_is_omapXYZ() type stuff here
         * to fill in these limits properly on different OMAP generations..
@@ -708,6 +721,18 @@ static struct vm_operations_struct omap_gem_vm_ops = {
        .close = drm_gem_vm_close,
 };
 
+static const struct file_operations omapdriver_fops = {
+               .owner = THIS_MODULE,
+               .open = drm_open,
+               .unlocked_ioctl = drm_ioctl,
+               .release = drm_release,
+               .mmap = omap_gem_mmap,
+               .poll = drm_poll,
+               .fasync = drm_fasync,
+               .read = drm_read,
+               .llseek = noop_llseek,
+};
+
 static struct drm_driver omap_drm_driver = {
                .driver_features =
                                DRIVER_HAVE_IRQ | DRIVER_MODESET | DRIVER_GEM,
@@ -738,17 +763,7 @@ static struct drm_driver omap_drm_driver = {
                .dumb_destroy = omap_gem_dumb_destroy,
                .ioctls = ioctls,
                .num_ioctls = DRM_OMAP_NUM_IOCTLS,
-               .fops = {
-                               .owner = THIS_MODULE,
-                               .open = drm_open,
-                               .unlocked_ioctl = drm_ioctl,
-                               .release = drm_release,
-                               .mmap = omap_gem_mmap,
-                               .poll = drm_poll,
-                               .fasync = drm_fasync,
-                               .read = drm_read,
-                               .llseek = noop_llseek,
-               },
+               .fops = &omapdriver_fops,
                .name = DRIVER_NAME,
                .desc = DRIVER_DESC,
                .date = DRIVER_DATE,
index 76c4251..61fe022 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/module.h>
 #include <linux/types.h>
 #include <drm/drmP.h>
+#include <drm/drm_crtc_helper.h>
 #include "omap_drm.h"
 #include "omap_priv.h"
 
@@ -41,6 +42,8 @@
 struct omap_drm_private {
        unsigned int num_crtcs;
        struct drm_crtc *crtcs[8];
+       unsigned int num_planes;
+       struct drm_plane *planes[8];
        unsigned int num_encoders;
        struct drm_encoder *encoders[8];
        unsigned int num_connectors;
@@ -61,7 +64,17 @@ void omap_fbdev_free(struct drm_device *dev);
 
 struct drm_crtc *omap_crtc_init(struct drm_device *dev,
                struct omap_overlay *ovl, int id);
-struct omap_overlay *omap_crtc_get_overlay(struct drm_crtc *crtc);
+
+struct drm_plane *omap_plane_init(struct drm_device *dev,
+               struct omap_overlay *ovl, unsigned int possible_crtcs,
+               bool priv);
+int omap_plane_dpms(struct drm_plane *plane, int mode);
+int omap_plane_mode_set(struct drm_plane *plane,
+               struct drm_crtc *crtc, struct drm_framebuffer *fb,
+               int crtc_x, int crtc_y,
+               unsigned int crtc_w, unsigned int crtc_h,
+               uint32_t src_x, uint32_t src_y,
+               uint32_t src_w, uint32_t src_h);
 
 struct drm_encoder *omap_encoder_init(struct drm_device *dev,
                struct omap_overlay_manager *mgr);
@@ -80,12 +93,14 @@ void omap_connector_flush(struct drm_connector *connector,
                int x, int y, int w, int h);
 
 struct drm_framebuffer *omap_framebuffer_create(struct drm_device *dev,
-               struct drm_file *file, struct drm_mode_fb_cmd *mode_cmd);
+               struct drm_file *file, struct drm_mode_fb_cmd2 *mode_cmd);
 struct drm_framebuffer *omap_framebuffer_init(struct drm_device *dev,
-               struct drm_mode_fb_cmd *mode_cmd, struct drm_gem_object *bo);
-struct drm_gem_object *omap_framebuffer_bo(struct drm_framebuffer *fb);
-int omap_framebuffer_get_buffer(struct drm_framebuffer *fb, int x, int y,
-               void **vaddr, dma_addr_t *paddr, unsigned int *screen_width);
+               struct drm_mode_fb_cmd2 *mode_cmd, struct drm_gem_object **bos);
+struct drm_gem_object *omap_framebuffer_bo(struct drm_framebuffer *fb, int p);
+int omap_framebuffer_pin(struct drm_framebuffer *fb);
+void omap_framebuffer_unpin(struct drm_framebuffer *fb);
+void omap_framebuffer_update_scanout(struct drm_framebuffer *fb, int x, int y,
+               struct omap_overlay_info *info);
 struct drm_connector *omap_framebuffer_get_next_connector(
                struct drm_framebuffer *fb, struct drm_connector *from);
 void omap_framebuffer_flush(struct drm_framebuffer *fb,
@@ -132,4 +147,29 @@ static inline int align_pitch(int pitch, int width, int bpp)
        return ALIGN(pitch, 8 * bytespp);
 }
 
+/* should these be made into common util helpers?
+ */
+
+static inline int objects_lookup(struct drm_device *dev,
+               struct drm_file *filp, uint32_t pixel_format,
+               struct drm_gem_object **bos, uint32_t *handles)
+{
+       int i, n = drm_format_num_planes(pixel_format);
+
+       for (i = 0; i < n; i++) {
+               bos[i] = drm_gem_object_lookup(dev, filp, handles[i]);
+               if (!bos[i]) {
+                       goto fail;
+               }
+       }
+
+       return 0;
+
+fail:
+       while (--i > 0) {
+               drm_gem_object_unreference_unlocked(bos[i]);
+       }
+       return -ENOENT;
+}
+
 #endif /* __OMAP_DRV_H__ */
index 0b50c5b..d021a7e 100644 (file)
 #include "drm_crtc.h"
 #include "drm_crtc_helper.h"
 
-
 /*
  * framebuffer funcs
  */
 
+/* per-format info: */
+struct format {
+       enum omap_color_mode dss_format;
+       uint32_t pixel_format;
+       struct {
+               int stride_bpp;           /* this times width is stride */
+               int sub_y;                /* sub-sample in y dimension */
+       } planes[4];
+       bool yuv;
+};
+
+static const struct format formats[] = {
+       /* 16bpp [A]RGB: */
+       { OMAP_DSS_COLOR_RGB16,       DRM_FORMAT_RGB565,   {{2, 1}}, false }, /* RGB16-565 */
+       { OMAP_DSS_COLOR_RGB12U,      DRM_FORMAT_RGBX4444, {{2, 1}}, false }, /* RGB12x-4444 */
+       { OMAP_DSS_COLOR_RGBX16,      DRM_FORMAT_XRGB4444, {{2, 1}}, false }, /* xRGB12-4444 */
+       { OMAP_DSS_COLOR_RGBA16,      DRM_FORMAT_RGBA4444, {{2, 1}}, false }, /* RGBA12-4444 */
+       { OMAP_DSS_COLOR_ARGB16,      DRM_FORMAT_ARGB4444, {{2, 1}}, false }, /* ARGB16-4444 */
+       { OMAP_DSS_COLOR_XRGB16_1555, DRM_FORMAT_XRGB1555, {{2, 1}}, false }, /* xRGB15-1555 */
+       { OMAP_DSS_COLOR_ARGB16_1555, DRM_FORMAT_ARGB1555, {{2, 1}}, false }, /* ARGB16-1555 */
+       /* 24bpp RGB: */
+       { OMAP_DSS_COLOR_RGB24P,      DRM_FORMAT_RGB888,   {{3, 1}}, false }, /* RGB24-888 */
+       /* 32bpp [A]RGB: */
+       { OMAP_DSS_COLOR_RGBX32,      DRM_FORMAT_RGBX8888, {{4, 1}}, false }, /* RGBx24-8888 */
+       { OMAP_DSS_COLOR_RGB24U,      DRM_FORMAT_XRGB8888, {{4, 1}}, false }, /* xRGB24-8888 */
+       { OMAP_DSS_COLOR_RGBA32,      DRM_FORMAT_RGBA8888, {{4, 1}}, false }, /* RGBA32-8888 */
+       { OMAP_DSS_COLOR_ARGB32,      DRM_FORMAT_ARGB8888, {{4, 1}}, false }, /* ARGB32-8888 */
+       /* YUV: */
+       { OMAP_DSS_COLOR_NV12,        DRM_FORMAT_NV12,     {{1, 1}, {1, 2}}, true },
+       { OMAP_DSS_COLOR_YUV2,        DRM_FORMAT_YUYV,     {{2, 1}}, true },
+       { OMAP_DSS_COLOR_UYVY,        DRM_FORMAT_UYVY,     {{2, 1}}, true },
+};
+
+/* per-plane info for the fb: */
+struct plane {
+       struct drm_gem_object *bo;
+       uint32_t pitch;
+       uint32_t offset;
+       dma_addr_t paddr;
+};
+
 #define to_omap_framebuffer(x) container_of(x, struct omap_framebuffer, base)
 
 struct omap_framebuffer {
        struct drm_framebuffer base;
-       struct drm_gem_object *bo;
-       int size;
-       dma_addr_t paddr;
+       const struct format *format;
+       struct plane planes[4];
 };
 
 static int omap_framebuffer_create_handle(struct drm_framebuffer *fb,
@@ -41,22 +80,23 @@ static int omap_framebuffer_create_handle(struct drm_framebuffer *fb,
                unsigned int *handle)
 {
        struct omap_framebuffer *omap_fb = to_omap_framebuffer(fb);
-    return drm_gem_handle_create(file_priv, omap_fb->bo, handle);
+       return drm_gem_handle_create(file_priv,
+                       omap_fb->planes[0].bo, handle);
 }
 
 static void omap_framebuffer_destroy(struct drm_framebuffer *fb)
 {
-       struct drm_device *dev = fb->dev;
        struct omap_framebuffer *omap_fb = to_omap_framebuffer(fb);
+       int i, n = drm_format_num_planes(omap_fb->format->pixel_format);
 
        DBG("destroy: FB ID: %d (%p)", fb->base.id, fb);
 
        drm_framebuffer_cleanup(fb);
 
-       if (omap_fb->bo) {
-               if (omap_fb->paddr && omap_gem_put_paddr(omap_fb->bo))
-                       dev_err(dev->dev, "could not unmap!\n");
-               drm_gem_object_unreference_unlocked(omap_fb->bo);
+       for (i = 0; i < n; i++) {
+               struct plane *plane = &omap_fb->planes[i];
+               if (plane->bo)
+                       drm_gem_object_unreference_unlocked(plane->bo);
        }
 
        kfree(omap_fb);
@@ -83,37 +123,76 @@ static const struct drm_framebuffer_funcs omap_framebuffer_funcs = {
        .dirty = omap_framebuffer_dirty,
 };
 
-/* returns the buffer size */
-int omap_framebuffer_get_buffer(struct drm_framebuffer *fb, int x, int y,
-               void **vaddr, dma_addr_t *paddr, unsigned int *screen_width)
+/* pins buffer in preparation for scanout */
+int omap_framebuffer_pin(struct drm_framebuffer *fb)
 {
        struct omap_framebuffer *omap_fb = to_omap_framebuffer(fb);
-       int bpp = fb->bits_per_pixel / 8;
-       unsigned long offset;
+       int ret, i, n = drm_format_num_planes(omap_fb->format->pixel_format);
 
-       offset = (x * bpp) + (y * fb->pitch);
+       for (i = 0; i < n; i++) {
+               struct plane *plane = &omap_fb->planes[i];
+               ret = omap_gem_get_paddr(plane->bo, &plane->paddr, true);
+               if (ret)
+                       goto fail;
+       }
 
-       if (vaddr) {
-               void *bo_vaddr = omap_gem_vaddr(omap_fb->bo);
-               /* note: we can only count on having a vaddr for buffers that
-                * are allocated physically contiguously to begin with (ie.
-                * dma_alloc_coherent()).  But this should be ok because it
-                * is only used by legacy fbdev
-                */
-               BUG_ON(IS_ERR_OR_NULL(bo_vaddr));
-               *vaddr = bo_vaddr + offset;
+       return 0;
+
+fail:
+       while (--i > 0) {
+               struct plane *plane = &omap_fb->planes[i];
+               omap_gem_put_paddr(plane->bo);
        }
+       return ret;
+}
 
-       *paddr = omap_fb->paddr + offset;
-       *screen_width = fb->pitch / bpp;
+/* releases buffer when done with scanout */
+void omap_framebuffer_unpin(struct drm_framebuffer *fb)
+{
+       struct omap_framebuffer *omap_fb = to_omap_framebuffer(fb);
+       int i, n = drm_format_num_planes(omap_fb->format->pixel_format);
 
-       return omap_fb->size - offset;
+       for (i = 0; i < n; i++) {
+               struct plane *plane = &omap_fb->planes[i];
+               omap_gem_put_paddr(plane->bo);
+       }
 }
 
-struct drm_gem_object *omap_framebuffer_bo(struct drm_framebuffer *fb)
+/* update ovl info for scanout, handles cases of multi-planar fb's, etc.
+ */
+void omap_framebuffer_update_scanout(struct drm_framebuffer *fb, int x, int y,
+               struct omap_overlay_info *info)
 {
        struct omap_framebuffer *omap_fb = to_omap_framebuffer(fb);
-       return omap_fb->bo;
+       const struct format *format = omap_fb->format;
+       struct plane *plane = &omap_fb->planes[0];
+       unsigned int offset;
+
+       offset = plane->offset +
+                       (x * format->planes[0].stride_bpp) +
+                       (y * plane->pitch / format->planes[0].sub_y);
+
+       info->color_mode   = format->dss_format;
+       info->paddr        = plane->paddr + offset;
+       info->screen_width = plane->pitch / format->planes[0].stride_bpp;
+
+       if (format->dss_format == OMAP_DSS_COLOR_NV12) {
+               plane = &omap_fb->planes[1];
+               offset = plane->offset +
+                               (x * format->planes[1].stride_bpp) +
+                               (y * plane->pitch / format->planes[1].sub_y);
+               info->p_uv_addr = plane->paddr + offset;
+       } else {
+               info->p_uv_addr = 0;
+       }
+}
+
+struct drm_gem_object *omap_framebuffer_bo(struct drm_framebuffer *fb, int p)
+{
+       struct omap_framebuffer *omap_fb = to_omap_framebuffer(fb);
+       if (p >= drm_format_num_planes(omap_fb->format->pixel_format))
+               return NULL;
+       return omap_fb->planes[p].bo;
 }
 
 /* iterate thru all the connectors, returning ones that are attached
@@ -171,39 +250,57 @@ void omap_framebuffer_flush(struct drm_framebuffer *fb,
 }
 
 struct drm_framebuffer *omap_framebuffer_create(struct drm_device *dev,
-               struct drm_file *file, struct drm_mode_fb_cmd *mode_cmd)
+               struct drm_file *file, struct drm_mode_fb_cmd2 *mode_cmd)
 {
-       struct drm_gem_object *bo;
+       struct drm_gem_object *bos[4];
        struct drm_framebuffer *fb;
-       bo = drm_gem_object_lookup(dev, file, mode_cmd->handle);
-       if (!bo) {
-               return ERR_PTR(-ENOENT);
-       }
-       fb = omap_framebuffer_init(dev, mode_cmd, bo);
-       if (!fb) {
-               return ERR_PTR(-ENOMEM);
+       int ret;
+
+       ret = objects_lookup(dev, file, mode_cmd->pixel_format,
+                       bos, mode_cmd->handles);
+       if (ret)
+               return ERR_PTR(ret);
+
+       fb = omap_framebuffer_init(dev, mode_cmd, bos);
+       if (IS_ERR(fb)) {
+               int i, n = drm_format_num_planes(mode_cmd->pixel_format);
+               for (i = 0; i < n; i++)
+                       drm_gem_object_unreference_unlocked(bos[i]);
+               return fb;
        }
        return fb;
 }
 
 struct drm_framebuffer *omap_framebuffer_init(struct drm_device *dev,
-               struct drm_mode_fb_cmd *mode_cmd, struct drm_gem_object *bo)
+               struct drm_mode_fb_cmd2 *mode_cmd, struct drm_gem_object **bos)
 {
        struct omap_framebuffer *omap_fb;
        struct drm_framebuffer *fb = NULL;
-       int size, ret;
+       const struct format *format = NULL;
+       int ret, i, n = drm_format_num_planes(mode_cmd->pixel_format);
 
-       DBG("create framebuffer: dev=%p, mode_cmd=%p (%dx%d@%d)",
+       DBG("create framebuffer: dev=%p, mode_cmd=%p (%dx%d@%4.4s)",
                        dev, mode_cmd, mode_cmd->width, mode_cmd->height,
-                       mode_cmd->bpp);
+                       (char *)&mode_cmd->pixel_format);
+
+       for (i = 0; i < ARRAY_SIZE(formats); i++) {
+               if (formats[i].pixel_format == mode_cmd->pixel_format) {
+                       format = &formats[i];
+                       break;
+               }
+       }
 
-       /* in case someone tries to feed us a completely bogus stride: */
-       mode_cmd->pitch = align_pitch(mode_cmd->pitch,
-                       mode_cmd->width, mode_cmd->bpp);
+       if (!format) {
+               dev_err(dev->dev, "unsupported pixel format: %4.4s\n",
+                               (char *)&mode_cmd->pixel_format);
+               ret = -EINVAL;
+               goto fail;
+       }
 
        omap_fb = kzalloc(sizeof(*omap_fb), GFP_KERNEL);
        if (!omap_fb) {
                dev_err(dev->dev, "could not allocate fb\n");
+               ret = -ENOMEM;
                goto fail;
        }
 
@@ -216,19 +313,32 @@ struct drm_framebuffer *omap_framebuffer_init(struct drm_device *dev,
 
        DBG("create: FB ID: %d (%p)", fb->base.id, fb);
 
-       size = PAGE_ALIGN(mode_cmd->pitch * mode_cmd->height);
+       omap_fb->format = format;
 
-       if (size > bo->size) {
-               dev_err(dev->dev, "provided buffer object is too small!\n");
-               goto fail;
-       }
+       for (i = 0; i < n; i++) {
+               struct plane *plane = &omap_fb->planes[i];
+               int size, pitch = mode_cmd->pitches[i];
+
+               if (pitch < (mode_cmd->width * format->planes[i].stride_bpp)) {
+                       dev_err(dev->dev, "provided buffer pitch is too small! %d < %d\n",
+                                       pitch, mode_cmd->width * format->planes[i].stride_bpp);
+                       ret = -EINVAL;
+                       goto fail;
+               }
 
-       omap_fb->bo = bo;
-       omap_fb->size = size;
+               size = pitch * mode_cmd->height / format->planes[i].sub_y;
 
-       if (omap_gem_get_paddr(bo, &omap_fb->paddr, true)) {
-               dev_err(dev->dev, "could not map (paddr)!\n");
-               goto fail;
+               if (size > (bos[i]->size - mode_cmd->offsets[i])) {
+                       dev_err(dev->dev, "provided buffer object is too small! %d < %d\n",
+                                       bos[i]->size - mode_cmd->offsets[i], size);
+                       ret = -EINVAL;
+                       goto fail;
+               }
+
+               plane->bo     = bos[i];
+               plane->offset = mode_cmd->offsets[i];
+               plane->pitch  = mode_cmd->pitches[i];
+               plane->paddr  = pitch;
        }
 
        drm_helper_mode_fill_fb_struct(fb, mode_cmd);
@@ -239,5 +349,5 @@ fail:
        if (fb) {
                omap_framebuffer_destroy(fb);
        }
-       return NULL;
+       return ERR_PTR(ret);
 }
index 093ae2f..96940bb 100644 (file)
@@ -129,10 +129,8 @@ static int omap_fbdev_create(struct drm_fb_helper *helper,
        struct drm_framebuffer *fb = NULL;
        union omap_gem_size gsize;
        struct fb_info *fbi = NULL;
-       struct drm_mode_fb_cmd mode_cmd = {0};
+       struct drm_mode_fb_cmd2 mode_cmd = {0};
        dma_addr_t paddr;
-       void __iomem *vaddr;
-       int size, screen_width;
        int ret;
 
        /* only doing ARGB32 since this is what is needed to alpha-blend
@@ -145,36 +143,56 @@ static int omap_fbdev_create(struct drm_fb_helper *helper,
                        sizes->surface_height, sizes->surface_bpp,
                        sizes->fb_width, sizes->fb_height);
 
+       mode_cmd.pixel_format = drm_mode_legacy_fb_format(sizes->surface_bpp,
+                       sizes->surface_depth);
+
        mode_cmd.width = sizes->surface_width;
        mode_cmd.height = sizes->surface_height;
 
-       mode_cmd.bpp = sizes->surface_bpp;
-       mode_cmd.depth = sizes->surface_depth;
-
-       mode_cmd.pitch = align_pitch(
-                       mode_cmd.width * ((mode_cmd.bpp + 7) / 8),
-                       mode_cmd.width, mode_cmd.bpp);
+       mode_cmd.pitches[0] = align_pitch(
+                       mode_cmd.width * ((sizes->surface_bpp + 7) / 8),
+                       mode_cmd.width, sizes->surface_bpp);
 
        fbdev->ywrap_enabled = priv->has_dmm && ywrap_enabled;
        if (fbdev->ywrap_enabled) {
                /* need to align pitch to page size if using DMM scrolling */
-               mode_cmd.pitch = ALIGN(mode_cmd.pitch, PAGE_SIZE);
+               mode_cmd.pitches[0] = ALIGN(mode_cmd.pitches[0], PAGE_SIZE);
        }
 
        /* allocate backing bo */
        gsize = (union omap_gem_size){
-               .bytes = PAGE_ALIGN(mode_cmd.pitch * mode_cmd.height),
+               .bytes = PAGE_ALIGN(mode_cmd.pitches[0] * mode_cmd.height),
        };
        DBG("allocating %d bytes for fb %d", gsize.bytes, dev->primary->index);
        fbdev->bo = omap_gem_new(dev, gsize, OMAP_BO_SCANOUT | OMAP_BO_WC);
        if (!fbdev->bo) {
                dev_err(dev->dev, "failed to allocate buffer object\n");
+               ret = -ENOMEM;
                goto fail;
        }
 
-       fb = omap_framebuffer_init(dev, &mode_cmd, fbdev->bo);
-       if (!fb) {
+       fb = omap_framebuffer_init(dev, &mode_cmd, &fbdev->bo);
+       if (IS_ERR(fb)) {
                dev_err(dev->dev, "failed to allocate fb\n");
+               /* note: if fb creation failed, we can't rely on fb destroy
+                * to unref the bo:
+                */
+               drm_gem_object_unreference(fbdev->bo);
+               ret = PTR_ERR(fb);
+               goto fail;
+       }
+
+       /* note: this keeps the bo pinned.. which is perhaps not ideal,
+        * but is needed as long as we use fb_mmap() to mmap to userspace
+        * (since this happens using fix.smem_start).  Possibly we could
+        * implement our own mmap using GEM mmap support to avoid this
+        * (non-tiled buffer doesn't need to be pinned for fbcon to write
+        * to it).  Then we just need to be sure that we are able to re-
+        * pin it in case of an opps.
+        */
+       ret = omap_gem_get_paddr(fbdev->bo, &paddr, true);
+       if (ret) {
+               dev_err(dev->dev, "could not map (paddr)!\n");
                ret = -ENOMEM;
                goto fail;
        }
@@ -206,18 +224,15 @@ static int omap_fbdev_create(struct drm_fb_helper *helper,
                goto fail_unlock;
        }
 
-       drm_fb_helper_fill_fix(fbi, fb->pitch, fb->depth);
+       drm_fb_helper_fill_fix(fbi, fb->pitches[0], fb->depth);
        drm_fb_helper_fill_var(fbi, helper, sizes->fb_width, sizes->fb_height);
 
-       size = omap_framebuffer_get_buffer(fb, 0, 0,
-                       &vaddr, &paddr, &screen_width);
-
        dev->mode_config.fb_base = paddr;
 
-       fbi->screen_base = vaddr;
-       fbi->screen_size = size;
+       fbi->screen_base = omap_gem_vaddr(fbdev->bo);
+       fbi->screen_size = fbdev->bo->size;
        fbi->fix.smem_start = paddr;
-       fbi->fix.smem_len = size;
+       fbi->fix.smem_len = fbdev->bo->size;
 
        /* if we have DMM, then we can use it for scrolling by just
         * shuffling pages around in DMM rather than doing sw blit.
@@ -362,11 +377,11 @@ void omap_fbdev_free(struct drm_device *dev)
 
        fbdev = to_omap_fbdev(priv->fbdev);
 
-       kfree(fbdev);
-
        /* this will free the backing object */
        if (fbdev->fb)
                fbdev->fb->funcs->destroy(fbdev->fb);
 
+       kfree(fbdev);
+
        priv->fbdev = NULL;
 }
index e0ebd1d..b7d6f88 100644 (file)
@@ -116,6 +116,9 @@ struct omap_gem_object {
        } *sync;
 };
 
+static int get_pages(struct drm_gem_object *obj, struct page ***pages);
+static uint64_t mmap_offset(struct drm_gem_object *obj);
+
 /* To deal with userspace mmap'ings of 2d tiled buffers, which (a) are
  * not necessarily pinned in TILER all the time, and (b) when they are
  * they are not necessarily page aligned, we reserve one or more small
@@ -149,7 +152,7 @@ static void evict_entry(struct drm_gem_object *obj,
 {
        if (obj->dev->dev_mapping) {
                size_t size = PAGE_SIZE * usergart[fmt].height;
-               loff_t off = omap_gem_mmap_offset(obj) +
+               loff_t off = mmap_offset(obj) +
                                (entry->obj_pgoff << PAGE_SHIFT);
                unmap_mapping_range(obj->dev->dev_mapping, off, size, 1);
        }
@@ -189,8 +192,6 @@ static inline bool is_shmem(struct drm_gem_object *obj)
        return obj->filp != NULL;
 }
 
-static int get_pages(struct drm_gem_object *obj, struct page ***pages);
-
 static DEFINE_SPINLOCK(sync_lock);
 
 /** ensure backing pages are allocated */
@@ -251,7 +252,7 @@ static void omap_gem_detach_pages(struct drm_gem_object *obj)
 }
 
 /** get mmap offset */
-uint64_t omap_gem_mmap_offset(struct drm_gem_object *obj)
+static uint64_t mmap_offset(struct drm_gem_object *obj)
 {
        if (!obj->map_list.map) {
                /* Make it mmapable */
@@ -267,6 +268,15 @@ uint64_t omap_gem_mmap_offset(struct drm_gem_object *obj)
        return (uint64_t)obj->map_list.hash.key << PAGE_SHIFT;
 }
 
+uint64_t omap_gem_mmap_offset(struct drm_gem_object *obj)
+{
+       uint64_t offset;
+       mutex_lock(&obj->dev->struct_mutex);
+       offset = mmap_offset(obj);
+       mutex_unlock(&obj->dev->struct_mutex);
+       return offset;
+}
+
 /** get mmap size */
 size_t omap_gem_mmap_size(struct drm_gem_object *obj)
 {
@@ -1034,6 +1044,11 @@ void omap_gem_free_object(struct drm_gem_object *obj)
                drm_gem_free_mmap_offset(obj);
        }
 
+       /* this means the object is still pinned.. which really should
+        * not happen.  I think..
+        */
+       WARN_ON(omap_obj->paddr_cnt > 0);
+
        /* don't free externally allocated backing memory */
        if (!(omap_obj->flags & OMAP_BO_EXT_MEM)) {
                if (omap_obj->pages) {
diff --git a/drivers/staging/omapdrm/omap_plane.c b/drivers/staging/omapdrm/omap_plane.c
new file mode 100644 (file)
index 0000000..9790912
--- /dev/null
@@ -0,0 +1,344 @@
+/*
+ * drivers/staging/omapdrm/omap_plane.c
+ *
+ * Copyright (C) 2011 Texas Instruments
+ * Author: Rob Clark <rob.clark@linaro.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "omap_drv.h"
+
+/* some hackery because omapdss has an 'enum omap_plane' (which would be
+ * better named omap_plane_id).. and compiler seems unhappy about having
+ * both a 'struct omap_plane' and 'enum omap_plane'
+ */
+#define omap_plane _omap_plane
+
+/*
+ * plane funcs
+ */
+
+#define to_omap_plane(x) container_of(x, struct omap_plane, base)
+
+struct omap_plane {
+       struct drm_plane base;
+       struct omap_overlay *ovl;
+       struct omap_overlay_info info;
+
+       /* Source values, converted to integers because we don't support
+        * fractional positions:
+        */
+       unsigned int src_x, src_y;
+
+       /* last fb that we pinned: */
+       struct drm_framebuffer *pinned_fb;
+};
+
+
+/* push changes down to dss2 */
+static int commit(struct drm_plane *plane)
+{
+       struct drm_device *dev = plane->dev;
+       struct omap_plane *omap_plane = to_omap_plane(plane);
+       struct omap_overlay *ovl = omap_plane->ovl;
+       struct omap_overlay_info *info = &omap_plane->info;
+       int ret;
+
+       DBG("%s", ovl->name);
+       DBG("%dx%d -> %dx%d (%d)", info->width, info->height, info->out_width,
+                       info->out_height, info->screen_width);
+       DBG("%d,%d %08x %08x", info->pos_x, info->pos_y,
+                       info->paddr, info->p_uv_addr);
+
+       /* NOTE: do we want to do this at all here, or just wait
+        * for dpms(ON) since other CRTC's may not have their mode
+        * set yet, so fb dimensions may still change..
+        */
+       ret = ovl->set_overlay_info(ovl, info);
+       if (ret) {
+               dev_err(dev->dev, "could not set overlay info\n");
+               return ret;
+       }
+
+       /* our encoder doesn't necessarily get a commit() after this, in
+        * particular in the dpms() and mode_set_base() cases, so force the
+        * manager to update:
+        *
+        * could this be in the encoder somehow?
+        */
+       if (ovl->manager) {
+               ret = ovl->manager->apply(ovl->manager);
+               if (ret) {
+                       dev_err(dev->dev, "could not apply settings\n");
+                       return ret;
+               }
+       }
+
+       if (ovl->is_enabled(ovl)) {
+               omap_framebuffer_flush(plane->fb, info->pos_x, info->pos_y,
+                               info->out_width, info->out_height);
+       }
+
+       return 0;
+}
+
+/* when CRTC that we are attached to has potentially changed, this checks
+ * if we are attached to proper manager, and if necessary updates.
+ */
+static void update_manager(struct drm_plane *plane)
+{
+       struct omap_drm_private *priv = plane->dev->dev_private;
+       struct omap_plane *omap_plane = to_omap_plane(plane);
+       struct omap_overlay *ovl = omap_plane->ovl;
+       struct omap_overlay_manager *mgr = NULL;
+       int i;
+
+       if (plane->crtc) {
+               for (i = 0; i < priv->num_encoders; i++) {
+                       struct drm_encoder *encoder = priv->encoders[i];
+                       if (encoder->crtc == plane->crtc) {
+                               mgr = omap_encoder_get_manager(encoder);
+                               break;
+                       }
+               }
+       }
+
+       if (ovl->manager != mgr) {
+               bool enabled = ovl->is_enabled(ovl);
+
+               /* don't switch things around with enabled overlays: */
+               if (enabled)
+                       omap_plane_dpms(plane, DRM_MODE_DPMS_OFF);
+
+               if (ovl->manager) {
+                       DBG("disconnecting %s from %s", ovl->name,
+                                       ovl->manager->name);
+                       ovl->unset_manager(ovl);
+               }
+
+               if (mgr) {
+                       DBG("connecting %s to %s", ovl->name, mgr->name);
+                       ovl->set_manager(ovl, mgr);
+               }
+
+               if (enabled && mgr)
+                       omap_plane_dpms(plane, DRM_MODE_DPMS_ON);
+       }
+}
+
+/* update which fb (if any) is pinned for scanout */
+static int update_pin(struct drm_plane *plane, struct drm_framebuffer *fb)
+{
+       struct omap_plane *omap_plane = to_omap_plane(plane);
+       int ret = 0;
+
+       if (omap_plane->pinned_fb != fb) {
+               if (omap_plane->pinned_fb)
+                       omap_framebuffer_unpin(omap_plane->pinned_fb);
+               omap_plane->pinned_fb = fb;
+               if (fb)
+                       ret = omap_framebuffer_pin(fb);
+       }
+
+       return ret;
+}
+
+/* update parameters that are dependent on the framebuffer dimensions and
+ * position within the fb that this plane scans out from. This is called
+ * when framebuffer or x,y base may have changed.
+ */
+static void update_scanout(struct drm_plane *plane)
+{
+       struct omap_plane *omap_plane = to_omap_plane(plane);
+       struct omap_overlay_info *info = &omap_plane->info;
+       int ret;
+
+       ret = update_pin(plane, plane->fb);
+       if (ret) {
+               dev_err(plane->dev->dev,
+                       "could not pin fb: %d\n", ret);
+               omap_plane_dpms(plane, DRM_MODE_DPMS_OFF);
+               return;
+       }
+
+       omap_framebuffer_update_scanout(plane->fb,
+                       omap_plane->src_x, omap_plane->src_y, info);
+
+       DBG("%s: %d,%d: %08x %08x (%d)", omap_plane->ovl->name,
+                       omap_plane->src_x, omap_plane->src_y,
+                       (u32)info->paddr, (u32)info->p_uv_addr,
+                       info->screen_width);
+}
+
+int omap_plane_mode_set(struct drm_plane *plane,
+               struct drm_crtc *crtc, struct drm_framebuffer *fb,
+               int crtc_x, int crtc_y,
+               unsigned int crtc_w, unsigned int crtc_h,
+               uint32_t src_x, uint32_t src_y,
+               uint32_t src_w, uint32_t src_h)
+{
+       struct omap_plane *omap_plane = to_omap_plane(plane);
+
+       /* src values are in Q16 fixed point, convert to integer: */
+       src_x = src_x >> 16;
+       src_y = src_y >> 16;
+       src_w = src_w >> 16;
+       src_h = src_h >> 16;
+
+       omap_plane->info.pos_x = crtc_x;
+       omap_plane->info.pos_y = crtc_y;
+       omap_plane->info.out_width = crtc_w;
+       omap_plane->info.out_height = crtc_h;
+       omap_plane->info.width = src_w;
+       omap_plane->info.height = src_h;
+       omap_plane->src_x = src_x;
+       omap_plane->src_y = src_y;
+
+       /* note: this is done after this fxn returns.. but if we need
+        * to do a commit/update_scanout, etc before this returns we
+        * need the current value.
+        */
+       plane->fb = fb;
+       plane->crtc = crtc;
+
+       update_scanout(plane);
+       update_manager(plane);
+
+       return 0;
+}
+
+static int omap_plane_update(struct drm_plane *plane,
+               struct drm_crtc *crtc, struct drm_framebuffer *fb,
+               int crtc_x, int crtc_y,
+               unsigned int crtc_w, unsigned int crtc_h,
+               uint32_t src_x, uint32_t src_y,
+               uint32_t src_w, uint32_t src_h)
+{
+       omap_plane_mode_set(plane, crtc, fb, crtc_x, crtc_y, crtc_w, crtc_h,
+                       src_x, src_y, src_w, src_h);
+       return omap_plane_dpms(plane, DRM_MODE_DPMS_ON);
+}
+
+static int omap_plane_disable(struct drm_plane *plane)
+{
+       return omap_plane_dpms(plane, DRM_MODE_DPMS_OFF);
+}
+
+static void omap_plane_destroy(struct drm_plane *plane)
+{
+       struct omap_plane *omap_plane = to_omap_plane(plane);
+       DBG("%s", omap_plane->ovl->name);
+       omap_plane_disable(plane);
+       drm_plane_cleanup(plane);
+       kfree(omap_plane);
+}
+
+int omap_plane_dpms(struct drm_plane *plane, int mode)
+{
+       struct omap_plane *omap_plane = to_omap_plane(plane);
+       struct omap_overlay *ovl = omap_plane->ovl;
+       int r;
+
+       DBG("%s: %d", omap_plane->ovl->name, mode);
+
+       if (mode == DRM_MODE_DPMS_ON) {
+               update_scanout(plane);
+               r = commit(plane);
+               if (!r)
+                       r = ovl->enable(ovl);
+       } else {
+               r = ovl->disable(ovl);
+               update_pin(plane, NULL);
+       }
+
+       return r;
+}
+
+static const struct drm_plane_funcs omap_plane_funcs = {
+               .update_plane = omap_plane_update,
+               .disable_plane = omap_plane_disable,
+               .destroy = omap_plane_destroy,
+};
+
+static const uint32_t formats[] = {
+               DRM_FORMAT_RGB565,
+               DRM_FORMAT_RGBX4444,
+               DRM_FORMAT_XRGB4444,
+               DRM_FORMAT_RGBA4444,
+               DRM_FORMAT_ABGR4444,
+               DRM_FORMAT_XRGB1555,
+               DRM_FORMAT_ARGB1555,
+               DRM_FORMAT_RGB888,
+               DRM_FORMAT_RGBX8888,
+               DRM_FORMAT_XRGB8888,
+               DRM_FORMAT_RGBA8888,
+               DRM_FORMAT_ARGB8888,
+               DRM_FORMAT_NV12,
+               DRM_FORMAT_YUYV,
+               DRM_FORMAT_UYVY,
+};
+
+/* initialize plane */
+struct drm_plane *omap_plane_init(struct drm_device *dev,
+               struct omap_overlay *ovl, unsigned int possible_crtcs,
+               bool priv)
+{
+       struct drm_plane *plane = NULL;
+       struct omap_plane *omap_plane;
+
+       DBG("%s: possible_crtcs=%08x, priv=%d", ovl->name,
+                       possible_crtcs, priv);
+
+       omap_plane = kzalloc(sizeof(*omap_plane), GFP_KERNEL);
+       if (!omap_plane) {
+               dev_err(dev->dev, "could not allocate plane\n");
+               goto fail;
+       }
+
+       omap_plane->ovl = ovl;
+       plane = &omap_plane->base;
+
+       drm_plane_init(dev, plane, possible_crtcs, &omap_plane_funcs,
+                       formats, ARRAY_SIZE(formats), priv);
+
+       /* get our starting configuration, set defaults for parameters
+        * we don't currently use, etc:
+        */
+       ovl->get_overlay_info(ovl, &omap_plane->info);
+       omap_plane->info.rotation_type = OMAP_DSS_ROT_DMA;
+       omap_plane->info.rotation = OMAP_DSS_ROT_0;
+       omap_plane->info.global_alpha = 0xff;
+       omap_plane->info.mirror = 0;
+       omap_plane->info.mirror = 0;
+
+       /* Set defaults depending on whether we are a CRTC or overlay
+        * layer.
+        * TODO add ioctl to give userspace an API to change this.. this
+        * will come in a subsequent patch.
+        */
+       if (priv)
+               omap_plane->info.zorder = 0;
+       else
+               omap_plane->info.zorder = 1;
+
+       update_manager(plane);
+
+       return plane;
+
+fail:
+       if (plane) {
+               omap_plane_destroy(plane);
+       }
+       return NULL;
+}
index c324709..ef64414 100644 (file)
  * pipes/overlays/CRTCs are used.. if this is not provided, then instead the
  * first CONFIG_DRM_OMAP_NUM_CRTCS are used, and they are each connected to
  * one manager, with priority given to managers that are connected to
- * detected devices.  This should be a good default behavior for most cases,
- * but yet there still might be times when you wish to do something different.
+ * detected devices.  Remaining overlays are used as video planes.  This
+ * should be a good default behavior for most cases, but yet there still
+ * might be times when you wish to do something different.
  */
 struct omap_kms_platform_data {
+       /* overlays to use as CRTCs: */
        int ovl_cnt;
        const int *ovl_ids;
+
+       /* overlays to use as video planes: */
+       int pln_cnt;
+       const int *pln_ids;
+
        int mgr_cnt;
        const int *mgr_ids;
+
        int dev_cnt;
        const char **dev_names;
 };
diff --git a/drivers/staging/pohmelfs/Kconfig b/drivers/staging/pohmelfs/Kconfig
deleted file mode 100644 (file)
index 8d53b1a..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-config POHMELFS
-       tristate "POHMELFS filesystem support"
-       depends on NET
-       select CONNECTOR
-       select CRYPTO
-       select CRYPTO_BLKCIPHER
-       select CRYPTO_HMAC
-       help
-         POHMELFS stands for Parallel Optimized Host Message Exchange Layered
-         File System.  This is a network filesystem which supports coherent
-         caching of data and metadata on clients.
-
-config POHMELFS_DEBUG
-       bool "POHMELFS debugging"
-       depends on POHMELFS
-       default n
-       help
-         Turns on excessive POHMELFS debugging facilities.
-         You usually do not want to slow things down noticeably and get really
-         lots of kernel messages in syslog.
diff --git a/drivers/staging/pohmelfs/Makefile b/drivers/staging/pohmelfs/Makefile
deleted file mode 100644 (file)
index 196561c..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-obj-$(CONFIG_POHMELFS) += pohmelfs.o
-
-pohmelfs-y := inode.o config.o dir.o net.o path_entry.o trans.o crypto.o lock.o mcache.o
diff --git a/drivers/staging/pohmelfs/config.c b/drivers/staging/pohmelfs/config.c
deleted file mode 100644 (file)
index b6c42cb..0000000
+++ /dev/null
@@ -1,611 +0,0 @@
-/*
- * 2007+ Copyright (c) Evgeniy Polyakov <zbr@ioremap.net>
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- */
-
-#include <linux/kernel.h>
-#include <linux/connector.h>
-#include <linux/crypto.h>
-#include <linux/list.h>
-#include <linux/mutex.h>
-#include <linux/string.h>
-#include <linux/in.h>
-#include <linux/slab.h>
-
-#include "netfs.h"
-
-/*
- * Global configuration list.
- * Each client can be asked to get one of them.
- *
- * Allows to provide remote server address (ipv4/v6/whatever), port
- * and so on via kernel connector.
- */
-
-static struct cb_id pohmelfs_cn_id = {.idx = POHMELFS_CN_IDX, .val = POHMELFS_CN_VAL};
-static LIST_HEAD(pohmelfs_config_list);
-static DEFINE_MUTEX(pohmelfs_config_lock);
-
-static inline int pohmelfs_config_eql(struct pohmelfs_ctl *sc, struct pohmelfs_ctl *ctl)
-{
-       if (sc->idx == ctl->idx && sc->type == ctl->type &&
-                       sc->proto == ctl->proto &&
-                       sc->addrlen == ctl->addrlen &&
-                       !memcmp(&sc->addr, &ctl->addr, ctl->addrlen))
-               return 1;
-
-       return 0;
-}
-
-static struct pohmelfs_config_group *pohmelfs_find_config_group(unsigned int idx)
-{
-       struct pohmelfs_config_group *g, *group = NULL;
-
-       list_for_each_entry(g, &pohmelfs_config_list, group_entry) {
-               if (g->idx == idx) {
-                       group = g;
-                       break;
-               }
-       }
-
-       return group;
-}
-
-static struct pohmelfs_config_group *pohmelfs_find_create_config_group(unsigned int idx)
-{
-       struct pohmelfs_config_group *g;
-
-       g = pohmelfs_find_config_group(idx);
-       if (g)
-               return g;
-
-       g = kzalloc(sizeof(struct pohmelfs_config_group), GFP_KERNEL);
-       if (!g)
-               return NULL;
-
-       INIT_LIST_HEAD(&g->config_list);
-       g->idx = idx;
-       g->num_entry = 0;
-
-       list_add_tail(&g->group_entry, &pohmelfs_config_list);
-
-       return g;
-}
-
-static inline void pohmelfs_insert_config_entry(struct pohmelfs_sb *psb, struct pohmelfs_config *dst)
-{
-       struct pohmelfs_config *tmp;
-
-       INIT_LIST_HEAD(&dst->config_entry);
-
-       list_for_each_entry(tmp, &psb->state_list, config_entry) {
-               if (dst->state.ctl.prio > tmp->state.ctl.prio)
-                       list_add_tail(&dst->config_entry, &tmp->config_entry);
-       }
-       if (list_empty(&dst->config_entry))
-               list_add_tail(&dst->config_entry, &psb->state_list);
-}
-
-static int pohmelfs_move_config_entry(struct pohmelfs_sb *psb,
-               struct pohmelfs_config *dst, struct pohmelfs_config *new)
-{
-       if ((dst->state.ctl.prio == new->state.ctl.prio) &&
-               (dst->state.ctl.perm == new->state.ctl.perm))
-               return 0;
-
-       dprintk("%s: dst: prio: %d, perm: %x, new: prio: %d, perm: %d.\n",
-                       __func__, dst->state.ctl.prio, dst->state.ctl.perm,
-                       new->state.ctl.prio, new->state.ctl.perm);
-       dst->state.ctl.prio = new->state.ctl.prio;
-       dst->state.ctl.perm = new->state.ctl.perm;
-
-       list_del_init(&dst->config_entry);
-       pohmelfs_insert_config_entry(psb, dst);
-       return 0;
-}
-
-/*
- * pohmelfs_copy_config() is used to copy new state configs from the
- * config group (controlled by the netlink messages) into the superblock.
- * This happens either at startup time where no transactions can access
- * the list of the configs (and thus list of the network states), or at
- * run-time, where it is protected by the psb->state_lock.
- */
-int pohmelfs_copy_config(struct pohmelfs_sb *psb)
-{
-       struct pohmelfs_config_group *g;
-       struct pohmelfs_config *c, *dst;
-       int err = -ENODEV;
-
-       mutex_lock(&pohmelfs_config_lock);
-
-       g = pohmelfs_find_config_group(psb->idx);
-       if (!g)
-               goto out_unlock;
-
-       /*
-        * Run over all entries in given config group and try to create and
-        * initialize those, which do not exist in superblock list.
-        * Skip all existing entries.
-        */
-
-       list_for_each_entry(c, &g->config_list, config_entry) {
-               err = 0;
-               list_for_each_entry(dst, &psb->state_list, config_entry) {
-                       if (pohmelfs_config_eql(&dst->state.ctl, &c->state.ctl)) {
-                               err = pohmelfs_move_config_entry(psb, dst, c);
-                               if (!err)
-                                       err = -EEXIST;
-                               break;
-                       }
-               }
-
-               if (err)
-                       continue;
-
-               dst = kzalloc(sizeof(struct pohmelfs_config), GFP_KERNEL);
-               if (!dst) {
-                       err = -ENOMEM;
-                       break;
-               }
-
-               memcpy(&dst->state.ctl, &c->state.ctl, sizeof(struct pohmelfs_ctl));
-
-               pohmelfs_insert_config_entry(psb, dst);
-
-               err = pohmelfs_state_init_one(psb, dst);
-               if (err) {
-                       list_del(&dst->config_entry);
-                       kfree(dst);
-               }
-
-               err = 0;
-       }
-
-out_unlock:
-       mutex_unlock(&pohmelfs_config_lock);
-
-       return err;
-}
-
-int pohmelfs_copy_crypto(struct pohmelfs_sb *psb)
-{
-       struct pohmelfs_config_group *g;
-       int err = -ENOENT;
-
-       mutex_lock(&pohmelfs_config_lock);
-       g = pohmelfs_find_config_group(psb->idx);
-       if (!g)
-               goto err_out_exit;
-
-       if (g->hash_string) {
-               err = -ENOMEM;
-               psb->hash_string = kstrdup(g->hash_string, GFP_KERNEL);
-               if (!psb->hash_string)
-                       goto err_out_exit;
-               psb->hash_strlen = g->hash_strlen;
-       }
-
-       if (g->cipher_string) {
-               psb->cipher_string = kstrdup(g->cipher_string, GFP_KERNEL);
-               if (!psb->cipher_string)
-                       goto err_out_free_hash_string;
-               psb->cipher_strlen = g->cipher_strlen;
-       }
-
-       if (g->hash_keysize) {
-               psb->hash_key = kmemdup(g->hash_key, g->hash_keysize,
-                                       GFP_KERNEL);
-               if (!psb->hash_key)
-                       goto err_out_free_cipher_string;
-               psb->hash_keysize = g->hash_keysize;
-       }
-
-       if (g->cipher_keysize) {
-               psb->cipher_key = kmemdup(g->cipher_key, g->cipher_keysize,
-                                         GFP_KERNEL);
-               if (!psb->cipher_key)
-                       goto err_out_free_hash;
-               psb->cipher_keysize = g->cipher_keysize;
-       }
-
-       mutex_unlock(&pohmelfs_config_lock);
-
-       return 0;
-
-err_out_free_hash:
-       kfree(psb->hash_key);
-err_out_free_cipher_string:
-       kfree(psb->cipher_string);
-err_out_free_hash_string:
-       kfree(psb->hash_string);
-err_out_exit:
-       mutex_unlock(&pohmelfs_config_lock);
-       return err;
-}
-
-static int pohmelfs_send_reply(int err, int msg_num, int action, struct cn_msg *msg, struct pohmelfs_ctl *ctl)
-{
-       struct pohmelfs_cn_ack *ack;
-
-       ack = kzalloc(sizeof(struct pohmelfs_cn_ack), GFP_KERNEL);
-       if (!ack)
-               return -ENOMEM;
-
-       memcpy(&ack->msg, msg, sizeof(struct cn_msg));
-
-       if (action == POHMELFS_CTLINFO_ACK)
-               memcpy(&ack->ctl, ctl, sizeof(struct pohmelfs_ctl));
-
-       ack->msg.len = sizeof(struct pohmelfs_cn_ack) - sizeof(struct cn_msg);
-       ack->msg.ack = msg->ack + 1;
-       ack->error = err;
-       ack->msg_num = msg_num;
-
-       cn_netlink_send(&ack->msg, 0, GFP_KERNEL);
-       kfree(ack);
-       return 0;
-}
-
-static int pohmelfs_cn_disp(struct cn_msg *msg)
-{
-       struct pohmelfs_config_group *g;
-       struct pohmelfs_ctl *ctl = (struct pohmelfs_ctl *)msg->data;
-       struct pohmelfs_config *c, *tmp;
-       int err = 0, i = 1;
-
-       if (msg->len != sizeof(struct pohmelfs_ctl))
-               return -EBADMSG;
-
-       mutex_lock(&pohmelfs_config_lock);
-
-       g = pohmelfs_find_config_group(ctl->idx);
-       if (!g) {
-               pohmelfs_send_reply(err, 0, POHMELFS_NOINFO_ACK, msg, NULL);
-               goto out_unlock;
-       }
-
-       list_for_each_entry_safe(c, tmp, &g->config_list, config_entry) {
-               struct pohmelfs_ctl *sc = &c->state.ctl;
-               if (pohmelfs_send_reply(err, g->num_entry - i, POHMELFS_CTLINFO_ACK, msg, sc)) {
-                       err = -ENOMEM;
-                       goto out_unlock;
-               }
-               i += 1;
-       }
-
- out_unlock:
-       mutex_unlock(&pohmelfs_config_lock);
-       return err;
-}
-
-static int pohmelfs_cn_dump(struct cn_msg *msg)
-{
-       struct pohmelfs_config_group *g;
-       struct pohmelfs_config *c, *tmp;
-       int err = 0, i = 1;
-       int total_msg = 0;
-
-       if (msg->len != sizeof(struct pohmelfs_ctl))
-               return -EBADMSG;
-
-       mutex_lock(&pohmelfs_config_lock);
-
-       list_for_each_entry(g, &pohmelfs_config_list, group_entry)
-               total_msg += g->num_entry;
-       if (total_msg == 0) {
-               if (pohmelfs_send_reply(err, 0, POHMELFS_NOINFO_ACK, msg, NULL))
-                       err = -ENOMEM;
-               goto out_unlock;
-       }
-
-       list_for_each_entry(g, &pohmelfs_config_list, group_entry) {
-               list_for_each_entry_safe(c, tmp, &g->config_list,
-                                        config_entry) {
-                       struct pohmelfs_ctl *sc = &c->state.ctl;
-                       if (pohmelfs_send_reply(err, total_msg - i,
-                                               POHMELFS_CTLINFO_ACK, msg,
-                                               sc)) {
-                               err = -ENOMEM;
-                               goto out_unlock;
-                       }
-                       i += 1;
-               }
-       }
-
-out_unlock:
-       mutex_unlock(&pohmelfs_config_lock);
-       return err;
-}
-
-static int pohmelfs_cn_flush(struct cn_msg *msg)
-{
-       struct pohmelfs_config_group *g;
-       struct pohmelfs_ctl *ctl = (struct pohmelfs_ctl *)msg->data;
-       struct pohmelfs_config *c, *tmp;
-       int err = 0;
-
-       if (msg->len != sizeof(struct pohmelfs_ctl))
-               return -EBADMSG;
-
-       mutex_lock(&pohmelfs_config_lock);
-
-       if (ctl->idx != POHMELFS_NULL_IDX) {
-               g = pohmelfs_find_config_group(ctl->idx);
-
-               if (!g)
-                       goto out_unlock;
-
-               list_for_each_entry_safe(c, tmp, &g->config_list, config_entry) {
-                       list_del(&c->config_entry);
-                       g->num_entry--;
-                       kfree(c);
-               }
-       } else {
-               list_for_each_entry(g, &pohmelfs_config_list, group_entry) {
-                       list_for_each_entry_safe(c, tmp, &g->config_list,
-                                                config_entry) {
-                               list_del(&c->config_entry);
-                               g->num_entry--;
-                               kfree(c);
-                       }
-               }
-       }
-
-out_unlock:
-       mutex_unlock(&pohmelfs_config_lock);
-       pohmelfs_cn_dump(msg);
-
-       return err;
-}
-
-static int pohmelfs_modify_config(struct pohmelfs_ctl *old, struct pohmelfs_ctl *new)
-{
-       old->perm = new->perm;
-       old->prio = new->prio;
-       return 0;
-}
-
-static int pohmelfs_cn_ctl(struct cn_msg *msg, int action)
-{
-       struct pohmelfs_config_group *g;
-       struct pohmelfs_ctl *ctl = (struct pohmelfs_ctl *)msg->data;
-       struct pohmelfs_config *c, *tmp;
-       int err = 0;
-
-       if (msg->len != sizeof(struct pohmelfs_ctl))
-               return -EBADMSG;
-
-       mutex_lock(&pohmelfs_config_lock);
-
-       g = pohmelfs_find_create_config_group(ctl->idx);
-       if (!g) {
-               err = -ENOMEM;
-               goto out_unlock;
-       }
-
-       list_for_each_entry_safe(c, tmp, &g->config_list, config_entry) {
-               struct pohmelfs_ctl *sc = &c->state.ctl;
-
-               if (pohmelfs_config_eql(sc, ctl)) {
-                       if (action == POHMELFS_FLAGS_ADD) {
-                               err = -EEXIST;
-                               goto out_unlock;
-                       } else if (action == POHMELFS_FLAGS_DEL) {
-                               list_del(&c->config_entry);
-                               g->num_entry--;
-                               kfree(c);
-                               goto out_unlock;
-                       } else if (action == POHMELFS_FLAGS_MODIFY) {
-                               err = pohmelfs_modify_config(sc, ctl);
-                               goto out_unlock;
-                       } else {
-                               err = -EEXIST;
-                               goto out_unlock;
-                       }
-               }
-       }
-       if (action == POHMELFS_FLAGS_DEL) {
-               err = -EBADMSG;
-               goto out_unlock;
-       }
-
-       c = kzalloc(sizeof(struct pohmelfs_config), GFP_KERNEL);
-       if (!c) {
-               err = -ENOMEM;
-               goto out_unlock;
-       }
-       memcpy(&c->state.ctl, ctl, sizeof(struct pohmelfs_ctl));
-       g->num_entry++;
-
-       list_add_tail(&c->config_entry, &g->config_list);
-
- out_unlock:
-       mutex_unlock(&pohmelfs_config_lock);
-       if (pohmelfs_send_reply(err, 0, POHMELFS_NOINFO_ACK, msg, NULL))
-               err = -ENOMEM;
-
-       return err;
-}
-
-static int pohmelfs_crypto_hash_init(struct pohmelfs_config_group *g, struct pohmelfs_crypto *c)
-{
-       char *algo = (char *)c->data;
-       u8 *key = (u8 *)(algo + c->strlen);
-
-       if (g->hash_string)
-               return -EEXIST;
-
-       g->hash_string = kstrdup(algo, GFP_KERNEL);
-       if (!g->hash_string)
-               return -ENOMEM;
-       g->hash_strlen = c->strlen;
-       g->hash_keysize = c->keysize;
-
-       g->hash_key = kmemdup(key, c->keysize, GFP_KERNEL);
-       if (!g->hash_key) {
-               kfree(g->hash_string);
-               return -ENOMEM;
-       }
-
-       return 0;
-}
-
-static int pohmelfs_crypto_cipher_init(struct pohmelfs_config_group *g, struct pohmelfs_crypto *c)
-{
-       char *algo = (char *)c->data;
-       u8 *key = (u8 *)(algo + c->strlen);
-
-       if (g->cipher_string)
-               return -EEXIST;
-
-       g->cipher_string = kstrdup(algo, GFP_KERNEL);
-       if (!g->cipher_string)
-               return -ENOMEM;
-       g->cipher_strlen = c->strlen;
-       g->cipher_keysize = c->keysize;
-
-       g->cipher_key = kmemdup(key, c->keysize, GFP_KERNEL);
-       if (!g->cipher_key) {
-               kfree(g->cipher_string);
-               return -ENOMEM;
-       }
-
-       return 0;
-}
-
-static int pohmelfs_cn_crypto(struct cn_msg *msg)
-{
-       struct pohmelfs_crypto *crypto = (struct pohmelfs_crypto *)msg->data;
-       struct pohmelfs_config_group *g;
-       int err = 0;
-
-       dprintk("%s: idx: %u, strlen: %u, type: %u, keysize: %u, algo: %s.\n",
-                       __func__, crypto->idx, crypto->strlen, crypto->type,
-                       crypto->keysize, (char *)crypto->data);
-
-       mutex_lock(&pohmelfs_config_lock);
-       g = pohmelfs_find_create_config_group(crypto->idx);
-       if (!g) {
-               err = -ENOMEM;
-               goto out_unlock;
-       }
-
-       switch (crypto->type) {
-       case POHMELFS_CRYPTO_HASH:
-                       err = pohmelfs_crypto_hash_init(g, crypto);
-                       break;
-       case POHMELFS_CRYPTO_CIPHER:
-                       err = pohmelfs_crypto_cipher_init(g, crypto);
-                       break;
-       default:
-                       err = -ENOTSUPP;
-                       break;
-       }
-
-out_unlock:
-       mutex_unlock(&pohmelfs_config_lock);
-       if (pohmelfs_send_reply(err, 0, POHMELFS_NOINFO_ACK, msg, NULL))
-               err = -ENOMEM;
-
-       return err;
-}
-
-static void pohmelfs_cn_callback(struct cn_msg *msg, struct netlink_skb_parms *nsp)
-{
-       int err;
-
-       if (!cap_raised(current_cap(), CAP_SYS_ADMIN))
-               return;
-
-       switch (msg->flags) {
-       case POHMELFS_FLAGS_ADD:
-       case POHMELFS_FLAGS_DEL:
-       case POHMELFS_FLAGS_MODIFY:
-                       err = pohmelfs_cn_ctl(msg, msg->flags);
-                       break;
-       case POHMELFS_FLAGS_FLUSH:
-                       err = pohmelfs_cn_flush(msg);
-                       break;
-       case POHMELFS_FLAGS_SHOW:
-                       err = pohmelfs_cn_disp(msg);
-                       break;
-       case POHMELFS_FLAGS_DUMP:
-                       err = pohmelfs_cn_dump(msg);
-                       break;
-       case POHMELFS_FLAGS_CRYPTO:
-                       err = pohmelfs_cn_crypto(msg);
-                       break;
-       default:
-                       err = -ENOSYS;
-                       break;
-       }
-}
-
-int pohmelfs_config_check(struct pohmelfs_config *config, int idx)
-{
-       struct pohmelfs_ctl *ctl = &config->state.ctl;
-       struct pohmelfs_config *tmp;
-       int err = -ENOENT;
-       struct pohmelfs_ctl *sc;
-       struct pohmelfs_config_group *g;
-
-       mutex_lock(&pohmelfs_config_lock);
-
-       g = pohmelfs_find_config_group(ctl->idx);
-       if (g) {
-               list_for_each_entry(tmp, &g->config_list, config_entry) {
-                       sc = &tmp->state.ctl;
-
-                       if (pohmelfs_config_eql(sc, ctl)) {
-                               err = 0;
-                               break;
-                       }
-               }
-       }
-
-       mutex_unlock(&pohmelfs_config_lock);
-
-       return err;
-}
-
-int __init pohmelfs_config_init(void)
-{
-       /* XXX remove (void *) cast when vanilla connector got synced */
-       return cn_add_callback(&pohmelfs_cn_id, "pohmelfs", (void *)pohmelfs_cn_callback);
-}
-
-void pohmelfs_config_exit(void)
-{
-       struct pohmelfs_config *c, *tmp;
-       struct pohmelfs_config_group *g, *gtmp;
-
-       cn_del_callback(&pohmelfs_cn_id);
-
-       mutex_lock(&pohmelfs_config_lock);
-       list_for_each_entry_safe(g, gtmp, &pohmelfs_config_list, group_entry) {
-               list_for_each_entry_safe(c, tmp, &g->config_list, config_entry) {
-                       list_del(&c->config_entry);
-                       kfree(c);
-               }
-
-               list_del(&g->group_entry);
-
-               kfree(g->hash_string);
-
-               kfree(g->cipher_string);
-
-               kfree(g);
-       }
-       mutex_unlock(&pohmelfs_config_lock);
-}
diff --git a/drivers/staging/pohmelfs/crypto.c b/drivers/staging/pohmelfs/crypto.c
deleted file mode 100644 (file)
index ad92771..0000000
+++ /dev/null
@@ -1,878 +0,0 @@
-/*
- * 2007+ Copyright (c) Evgeniy Polyakov <zbr@ioremap.net>
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- */
-
-#include <linux/crypto.h>
-#include <linux/highmem.h>
-#include <linux/kthread.h>
-#include <linux/pagemap.h>
-#include <linux/scatterlist.h>
-#include <linux/slab.h>
-
-#include "netfs.h"
-
-static struct crypto_hash *pohmelfs_init_hash(struct pohmelfs_sb *psb)
-{
-       int err;
-       struct crypto_hash *hash;
-
-       hash = crypto_alloc_hash(psb->hash_string, 0, CRYPTO_ALG_ASYNC);
-       if (IS_ERR(hash)) {
-               err = PTR_ERR(hash);
-               dprintk("%s: idx: %u: failed to allocate hash '%s', err: %d.\n",
-                               __func__, psb->idx, psb->hash_string, err);
-               goto err_out_exit;
-       }
-
-       psb->crypto_attached_size = crypto_hash_digestsize(hash);
-
-       if (!psb->hash_keysize)
-               return hash;
-
-       err = crypto_hash_setkey(hash, psb->hash_key, psb->hash_keysize);
-       if (err) {
-               dprintk("%s: idx: %u: failed to set key for hash '%s', err: %d.\n",
-                               __func__, psb->idx, psb->hash_string, err);
-               goto err_out_free;
-       }
-
-       return hash;
-
-err_out_free:
-       crypto_free_hash(hash);
-err_out_exit:
-       return ERR_PTR(err);
-}
-
-static struct crypto_ablkcipher *pohmelfs_init_cipher(struct pohmelfs_sb *psb)
-{
-       int err = -EINVAL;
-       struct crypto_ablkcipher *cipher;
-
-       if (!psb->cipher_keysize)
-               goto err_out_exit;
-
-       cipher = crypto_alloc_ablkcipher(psb->cipher_string, 0, 0);
-       if (IS_ERR(cipher)) {
-               err = PTR_ERR(cipher);
-               dprintk("%s: idx: %u: failed to allocate cipher '%s', err: %d.\n",
-                               __func__, psb->idx, psb->cipher_string, err);
-               goto err_out_exit;
-       }
-
-       crypto_ablkcipher_clear_flags(cipher, ~0);
-
-       err = crypto_ablkcipher_setkey(cipher, psb->cipher_key, psb->cipher_keysize);
-       if (err) {
-               dprintk("%s: idx: %u: failed to set key for cipher '%s', err: %d.\n",
-                               __func__, psb->idx, psb->cipher_string, err);
-               goto err_out_free;
-       }
-
-       return cipher;
-
-err_out_free:
-       crypto_free_ablkcipher(cipher);
-err_out_exit:
-       return ERR_PTR(err);
-}
-
-int pohmelfs_crypto_engine_init(struct pohmelfs_crypto_engine *e, struct pohmelfs_sb *psb)
-{
-       int err;
-
-       e->page_num = 0;
-
-       e->size = PAGE_SIZE;
-       e->data = kmalloc(e->size, GFP_KERNEL);
-       if (!e->data) {
-               err = -ENOMEM;
-               goto err_out_exit;
-       }
-
-       if (psb->hash_string) {
-               e->hash = pohmelfs_init_hash(psb);
-               if (IS_ERR(e->hash)) {
-                       err = PTR_ERR(e->hash);
-                       e->hash = NULL;
-                       goto err_out_free;
-               }
-       }
-
-       if (psb->cipher_string) {
-               e->cipher = pohmelfs_init_cipher(psb);
-               if (IS_ERR(e->cipher)) {
-                       err = PTR_ERR(e->cipher);
-                       e->cipher = NULL;
-                       goto err_out_free_hash;
-               }
-       }
-
-       return 0;
-
-err_out_free_hash:
-       crypto_free_hash(e->hash);
-err_out_free:
-       kfree(e->data);
-err_out_exit:
-       return err;
-}
-
-void pohmelfs_crypto_engine_exit(struct pohmelfs_crypto_engine *e)
-{
-       crypto_free_hash(e->hash);
-       crypto_free_ablkcipher(e->cipher);
-       kfree(e->data);
-}
-
-static void pohmelfs_crypto_complete(struct crypto_async_request *req, int err)
-{
-       struct pohmelfs_crypto_completion *c = req->data;
-
-       if (err == -EINPROGRESS)
-               return;
-
-       dprintk("%s: req: %p, err: %d.\n", __func__, req, err);
-       c->error = err;
-       complete(&c->complete);
-}
-
-static int pohmelfs_crypto_process(struct ablkcipher_request *req,
-               struct scatterlist *sg_dst, struct scatterlist *sg_src,
-               void *iv, int enc, unsigned long timeout)
-{
-       struct pohmelfs_crypto_completion complete;
-       int err;
-
-       init_completion(&complete.complete);
-       complete.error = -EINPROGRESS;
-
-       ablkcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
-                                       pohmelfs_crypto_complete, &complete);
-
-       ablkcipher_request_set_crypt(req, sg_src, sg_dst, sg_src->length, iv);
-
-       if (enc)
-               err = crypto_ablkcipher_encrypt(req);
-       else
-               err = crypto_ablkcipher_decrypt(req);
-
-       switch (err) {
-       case -EINPROGRESS:
-       case -EBUSY:
-               err = wait_for_completion_interruptible_timeout(&complete.complete,
-                                       timeout);
-               if (!err)
-                       err = -ETIMEDOUT;
-               else if (err > 0)
-                       err = complete.error;
-               break;
-       default:
-               break;
-       }
-
-       return err;
-}
-
-int pohmelfs_crypto_process_input_data(struct pohmelfs_crypto_engine *e, u64 cmd_iv,
-               void *data, struct page *page, unsigned int size)
-{
-       int err;
-       struct scatterlist sg;
-
-       if (!e->cipher && !e->hash)
-               return 0;
-
-       dprintk("%s: eng: %p, iv: %llx, data: %p, page: %p/%lu, size: %u.\n",
-               __func__, e, cmd_iv, data, page, (page) ? page->index : 0, size);
-
-       if (data) {
-               sg_init_one(&sg, data, size);
-       } else {
-               sg_init_table(&sg, 1);
-               sg_set_page(&sg, page, size, 0);
-       }
-
-       if (e->cipher) {
-               struct ablkcipher_request *req = e->data + crypto_hash_digestsize(e->hash);
-               u8 iv[32];
-
-               memset(iv, 0, sizeof(iv));
-               memcpy(iv, &cmd_iv, sizeof(cmd_iv));
-
-               ablkcipher_request_set_tfm(req, e->cipher);
-
-               err = pohmelfs_crypto_process(req, &sg, &sg, iv, 0, e->timeout);
-               if (err)
-                       goto err_out_exit;
-       }
-
-       if (e->hash) {
-               struct hash_desc desc;
-               void *dst = e->data + e->size/2;
-
-               desc.tfm = e->hash;
-               desc.flags = 0;
-
-               err = crypto_hash_init(&desc);
-               if (err)
-                       goto err_out_exit;
-
-               err = crypto_hash_update(&desc, &sg, size);
-               if (err)
-                       goto err_out_exit;
-
-               err = crypto_hash_final(&desc, dst);
-               if (err)
-                       goto err_out_exit;
-
-               err = !!memcmp(dst, e->data, crypto_hash_digestsize(e->hash));
-
-               if (err) {
-#ifdef CONFIG_POHMELFS_DEBUG
-                       unsigned int i;
-                       unsigned char *recv = e->data, *calc = dst;
-
-                       dprintk("%s: eng: %p, hash: %p, cipher: %p: iv : %llx, hash mismatch (recv/calc): ",
-                                       __func__, e, e->hash, e->cipher, cmd_iv);
-                       for (i = 0; i < crypto_hash_digestsize(e->hash); ++i) {
-#if 0
-                               dprintka("%02x ", recv[i]);
-                               if (recv[i] != calc[i]) {
-                                       dprintka("| calc byte: %02x.\n", calc[i]);
-                                       break;
-                               }
-#else
-                               dprintka("%02x/%02x ", recv[i], calc[i]);
-#endif
-                       }
-                       dprintk("\n");
-#endif
-                       goto err_out_exit;
-               } else {
-                       dprintk("%s: eng: %p, hash: %p, cipher: %p: hashes matched.\n",
-                                       __func__, e, e->hash, e->cipher);
-               }
-       }
-
-       dprintk("%s: eng: %p, size: %u, hash: %p, cipher: %p: completed.\n",
-                       __func__, e, e->size, e->hash, e->cipher);
-
-       return 0;
-
-err_out_exit:
-       dprintk("%s: eng: %p, hash: %p, cipher: %p: err: %d.\n",
-                       __func__, e, e->hash, e->cipher, err);
-       return err;
-}
-
-static int pohmelfs_trans_iter(struct netfs_trans *t, struct pohmelfs_crypto_engine *e,
-               int (*iterator) (struct pohmelfs_crypto_engine *e,
-                                 struct scatterlist *dst,
-                                 struct scatterlist *src))
-{
-       void *data = t->iovec.iov_base + sizeof(struct netfs_cmd) + t->psb->crypto_attached_size;
-       unsigned int size = t->iovec.iov_len - sizeof(struct netfs_cmd) - t->psb->crypto_attached_size;
-       struct netfs_cmd *cmd = data;
-       unsigned int sz, pages = t->attached_pages, i, csize, cmd_cmd, dpage_idx;
-       struct scatterlist sg_src, sg_dst;
-       int err;
-
-       while (size) {
-               cmd = data;
-               cmd_cmd = __be16_to_cpu(cmd->cmd);
-               csize = __be32_to_cpu(cmd->size);
-               cmd->iv = __cpu_to_be64(e->iv);
-
-               if (cmd_cmd == NETFS_READ_PAGES || cmd_cmd == NETFS_READ_PAGE)
-                       csize = __be16_to_cpu(cmd->ext);
-
-               sz = csize + __be16_to_cpu(cmd->cpad) + sizeof(struct netfs_cmd);
-
-               dprintk("%s: size: %u, sz: %u, cmd_size: %u, cmd_cpad: %u.\n",
-                               __func__, size, sz, __be32_to_cpu(cmd->size), __be16_to_cpu(cmd->cpad));
-
-               data += sz;
-               size -= sz;
-
-               sg_init_one(&sg_src, cmd->data, sz - sizeof(struct netfs_cmd));
-               sg_init_one(&sg_dst, cmd->data, sz - sizeof(struct netfs_cmd));
-
-               err = iterator(e, &sg_dst, &sg_src);
-               if (err)
-                       return err;
-       }
-
-       if (!pages)
-               return 0;
-
-       dpage_idx = 0;
-       for (i = 0; i < t->page_num; ++i) {
-               struct page *page = t->pages[i];
-               struct page *dpage = e->pages[dpage_idx];
-
-               if (!page)
-                       continue;
-
-               sg_init_table(&sg_src, 1);
-               sg_init_table(&sg_dst, 1);
-               sg_set_page(&sg_src, page, page_private(page), 0);
-               sg_set_page(&sg_dst, dpage, page_private(page), 0);
-
-               err = iterator(e, &sg_dst, &sg_src);
-               if (err)
-                       return err;
-
-               pages--;
-               if (!pages)
-                       break;
-               dpage_idx++;
-       }
-
-       return 0;
-}
-
-static int pohmelfs_encrypt_iterator(struct pohmelfs_crypto_engine *e,
-               struct scatterlist *sg_dst, struct scatterlist *sg_src)
-{
-       struct ablkcipher_request *req = e->data;
-       u8 iv[32];
-
-       memset(iv, 0, sizeof(iv));
-
-       memcpy(iv, &e->iv, sizeof(e->iv));
-
-       return pohmelfs_crypto_process(req, sg_dst, sg_src, iv, 1, e->timeout);
-}
-
-static int pohmelfs_encrypt(struct pohmelfs_crypto_thread *tc)
-{
-       struct netfs_trans *t = tc->trans;
-       struct pohmelfs_crypto_engine *e = &tc->eng;
-       struct ablkcipher_request *req = e->data;
-
-       memset(req, 0, sizeof(struct ablkcipher_request));
-       ablkcipher_request_set_tfm(req, e->cipher);
-
-       e->iv = pohmelfs_gen_iv(t);
-
-       return pohmelfs_trans_iter(t, e, pohmelfs_encrypt_iterator);
-}
-
-static int pohmelfs_hash_iterator(struct pohmelfs_crypto_engine *e,
-               struct scatterlist *sg_dst, struct scatterlist *sg_src)
-{
-       return crypto_hash_update(e->data, sg_src, sg_src->length);
-}
-
-static int pohmelfs_hash(struct pohmelfs_crypto_thread *tc)
-{
-       struct pohmelfs_crypto_engine *e = &tc->eng;
-       struct hash_desc *desc = e->data;
-       unsigned char *dst = tc->trans->iovec.iov_base + sizeof(struct netfs_cmd);
-       int err;
-
-       desc->tfm = e->hash;
-       desc->flags = 0;
-
-       err = crypto_hash_init(desc);
-       if (err)
-               return err;
-
-       err = pohmelfs_trans_iter(tc->trans, e, pohmelfs_hash_iterator);
-       if (err)
-               return err;
-
-       err = crypto_hash_final(desc, dst);
-       if (err)
-               return err;
-
-       {
-               unsigned int i;
-               dprintk("%s: ", __func__);
-               for (i = 0; i < tc->psb->crypto_attached_size; ++i)
-                       dprintka("%02x ", dst[i]);
-               dprintka("\n");
-       }
-
-       return 0;
-}
-
-static void pohmelfs_crypto_pages_free(struct pohmelfs_crypto_engine *e)
-{
-       unsigned int i;
-
-       for (i = 0; i < e->page_num; ++i)
-               __free_page(e->pages[i]);
-       kfree(e->pages);
-}
-
-static int pohmelfs_crypto_pages_alloc(struct pohmelfs_crypto_engine *e, struct pohmelfs_sb *psb)
-{
-       unsigned int i;
-
-       e->pages = kmalloc(psb->trans_max_pages * sizeof(struct page *), GFP_KERNEL);
-       if (!e->pages)
-               return -ENOMEM;
-
-       for (i = 0; i < psb->trans_max_pages; ++i) {
-               e->pages[i] = alloc_page(GFP_KERNEL);
-               if (!e->pages[i])
-                       break;
-       }
-
-       e->page_num = i;
-       if (!e->page_num)
-               goto err_out_free;
-
-       return 0;
-
-err_out_free:
-       kfree(e->pages);
-       return -ENOMEM;
-}
-
-static void pohmelfs_sys_crypto_exit_one(struct pohmelfs_crypto_thread *t)
-{
-       struct pohmelfs_sb *psb = t->psb;
-
-       if (t->thread)
-               kthread_stop(t->thread);
-
-       mutex_lock(&psb->crypto_thread_lock);
-       list_del(&t->thread_entry);
-       psb->crypto_thread_num--;
-       mutex_unlock(&psb->crypto_thread_lock);
-
-       pohmelfs_crypto_engine_exit(&t->eng);
-       pohmelfs_crypto_pages_free(&t->eng);
-       kfree(t);
-}
-
-static int pohmelfs_crypto_finish(struct netfs_trans *t, struct pohmelfs_sb *psb, int err)
-{
-       struct netfs_cmd *cmd = t->iovec.iov_base;
-       netfs_convert_cmd(cmd);
-
-       if (likely(!err))
-               err = netfs_trans_finish_send(t, psb);
-
-       t->result = err;
-       netfs_trans_put(t);
-
-       return err;
-}
-
-void pohmelfs_crypto_thread_make_ready(struct pohmelfs_crypto_thread *th)
-{
-       struct pohmelfs_sb *psb = th->psb;
-
-       th->page = NULL;
-       th->trans = NULL;
-
-       mutex_lock(&psb->crypto_thread_lock);
-       list_move_tail(&th->thread_entry, &psb->crypto_ready_list);
-       mutex_unlock(&psb->crypto_thread_lock);
-       wake_up(&psb->wait);
-}
-
-static int pohmelfs_crypto_thread_trans(struct pohmelfs_crypto_thread *t)
-{
-       struct netfs_trans *trans;
-       int err = 0;
-
-       trans = t->trans;
-       trans->eng = NULL;
-
-       if (t->eng.hash) {
-               err = pohmelfs_hash(t);
-               if (err)
-                       goto out_complete;
-       }
-
-       if (t->eng.cipher) {
-               err = pohmelfs_encrypt(t);
-               if (err)
-                       goto out_complete;
-               trans->eng = &t->eng;
-       }
-
-out_complete:
-       t->page = NULL;
-       t->trans = NULL;
-
-       if (!trans->eng)
-               pohmelfs_crypto_thread_make_ready(t);
-
-       pohmelfs_crypto_finish(trans, t->psb, err);
-       return err;
-}
-
-static int pohmelfs_crypto_thread_page(struct pohmelfs_crypto_thread *t)
-{
-       struct pohmelfs_crypto_engine *e = &t->eng;
-       struct page *page = t->page;
-       int err;
-
-       WARN_ON(!PageChecked(page));
-
-       err = pohmelfs_crypto_process_input_data(e, e->iv, NULL, page, t->size);
-       if (!err)
-               SetPageUptodate(page);
-       else
-               SetPageError(page);
-       unlock_page(page);
-       page_cache_release(page);
-
-       pohmelfs_crypto_thread_make_ready(t);
-
-       return err;
-}
-
-static int pohmelfs_crypto_thread_func(void *data)
-{
-       struct pohmelfs_crypto_thread *t = data;
-
-       while (!kthread_should_stop()) {
-               wait_event_interruptible(t->wait, kthread_should_stop() ||
-                               t->trans || t->page);
-
-               if (kthread_should_stop())
-                       break;
-
-               if (!t->trans && !t->page)
-                       continue;
-
-               dprintk("%s: thread: %p, trans: %p, page: %p.\n",
-                               __func__, t, t->trans, t->page);
-
-               if (t->trans)
-                       pohmelfs_crypto_thread_trans(t);
-               else if (t->page)
-                       pohmelfs_crypto_thread_page(t);
-       }
-
-       return 0;
-}
-
-static void pohmelfs_crypto_flush(struct pohmelfs_sb *psb, struct list_head *head)
-{
-       while (!list_empty(head)) {
-               struct pohmelfs_crypto_thread *t = NULL;
-
-               mutex_lock(&psb->crypto_thread_lock);
-               if (!list_empty(head)) {
-                       t = list_first_entry(head, struct pohmelfs_crypto_thread, thread_entry);
-                       list_del_init(&t->thread_entry);
-               }
-               mutex_unlock(&psb->crypto_thread_lock);
-
-               if (t)
-                       pohmelfs_sys_crypto_exit_one(t);
-       }
-}
-
-static void pohmelfs_sys_crypto_exit(struct pohmelfs_sb *psb)
-{
-       while (!list_empty(&psb->crypto_active_list) || !list_empty(&psb->crypto_ready_list)) {
-               dprintk("%s: crypto_thread_num: %u.\n", __func__, psb->crypto_thread_num);
-               pohmelfs_crypto_flush(psb, &psb->crypto_active_list);
-               pohmelfs_crypto_flush(psb, &psb->crypto_ready_list);
-       }
-}
-
-static int pohmelfs_sys_crypto_init(struct pohmelfs_sb *psb)
-{
-       unsigned int i;
-       struct pohmelfs_crypto_thread *t;
-       struct pohmelfs_config *c;
-       struct netfs_state *st;
-       int err;
-
-       list_for_each_entry(c, &psb->state_list, config_entry) {
-               st = &c->state;
-
-               err = pohmelfs_crypto_engine_init(&st->eng, psb);
-               if (err)
-                       goto err_out_exit;
-
-               dprintk("%s: st: %p, eng: %p, hash: %p, cipher: %p.\n",
-                               __func__, st, &st->eng, &st->eng.hash, &st->eng.cipher);
-       }
-
-       for (i = 0; i < psb->crypto_thread_num; ++i) {
-               err = -ENOMEM;
-               t = kzalloc(sizeof(struct pohmelfs_crypto_thread), GFP_KERNEL);
-               if (!t)
-                       goto err_out_free_state_engines;
-
-               init_waitqueue_head(&t->wait);
-
-               t->psb = psb;
-               t->trans = NULL;
-               t->eng.thread = t;
-
-               err = pohmelfs_crypto_engine_init(&t->eng, psb);
-               if (err)
-                       goto err_out_free_state_engines;
-
-               err = pohmelfs_crypto_pages_alloc(&t->eng, psb);
-               if (err)
-                       goto err_out_free;
-
-               t->thread = kthread_run(pohmelfs_crypto_thread_func, t,
-                               "pohmelfs-crypto-%d-%d", psb->idx, i);
-               if (IS_ERR(t->thread)) {
-                       err = PTR_ERR(t->thread);
-                       t->thread = NULL;
-                       goto err_out_free;
-               }
-
-               if (t->eng.cipher)
-                       psb->crypto_align_size = crypto_ablkcipher_blocksize(t->eng.cipher);
-
-               mutex_lock(&psb->crypto_thread_lock);
-               list_add_tail(&t->thread_entry, &psb->crypto_ready_list);
-               mutex_unlock(&psb->crypto_thread_lock);
-       }
-
-       psb->crypto_thread_num = i;
-       return 0;
-
-err_out_free:
-       pohmelfs_sys_crypto_exit_one(t);
-err_out_free_state_engines:
-       list_for_each_entry(c, &psb->state_list, config_entry) {
-               st = &c->state;
-               pohmelfs_crypto_engine_exit(&st->eng);
-       }
-err_out_exit:
-       pohmelfs_sys_crypto_exit(psb);
-       return err;
-}
-
-void pohmelfs_crypto_exit(struct pohmelfs_sb *psb)
-{
-       pohmelfs_sys_crypto_exit(psb);
-
-       kfree(psb->hash_string);
-       kfree(psb->cipher_string);
-}
-
-static int pohmelfs_crypt_init_complete(struct page **pages, unsigned int page_num,
-               void *private, int err)
-{
-       struct pohmelfs_sb *psb = private;
-
-       psb->flags = -err;
-       dprintk("%s: err: %d.\n", __func__, err);
-
-       wake_up(&psb->wait);
-
-       return err;
-}
-
-static int pohmelfs_crypto_init_handshake(struct pohmelfs_sb *psb)
-{
-       struct netfs_trans *t;
-       struct netfs_crypto_capabilities *cap;
-       struct netfs_cmd *cmd;
-       char *str;
-       int err = -ENOMEM, size;
-
-       size = sizeof(struct netfs_crypto_capabilities) +
-               psb->cipher_strlen + psb->hash_strlen + 2; /* 0 bytes */
-
-       t = netfs_trans_alloc(psb, size, 0, 0);
-       if (!t)
-               goto err_out_exit;
-
-       t->complete = pohmelfs_crypt_init_complete;
-       t->private = psb;
-
-       cmd = netfs_trans_current(t);
-       cap = (struct netfs_crypto_capabilities *)(cmd + 1);
-       str = (char *)(cap + 1);
-
-       cmd->cmd = NETFS_CAPABILITIES;
-       cmd->id = POHMELFS_CRYPTO_CAPABILITIES;
-       cmd->size = size;
-       cmd->start = 0;
-       cmd->ext = 0;
-       cmd->csize = 0;
-
-       netfs_convert_cmd(cmd);
-       netfs_trans_update(cmd, t, size);
-
-       cap->hash_strlen = psb->hash_strlen;
-       if (cap->hash_strlen) {
-               sprintf(str, "%s", psb->hash_string);
-               str += cap->hash_strlen;
-       }
-
-       cap->cipher_strlen = psb->cipher_strlen;
-       cap->cipher_keysize = psb->cipher_keysize;
-       if (cap->cipher_strlen)
-               sprintf(str, "%s", psb->cipher_string);
-
-       netfs_convert_crypto_capabilities(cap);
-
-       psb->flags = ~0;
-       err = netfs_trans_finish(t, psb);
-       if (err)
-               goto err_out_exit;
-
-       err = wait_event_interruptible_timeout(psb->wait, (psb->flags != ~0),
-                       psb->wait_on_page_timeout);
-       if (!err)
-               err = -ETIMEDOUT;
-       else if (err > 0)
-               err = -psb->flags;
-
-       if (!err)
-               psb->perform_crypto = 1;
-       psb->flags = 0;
-
-       /*
-        * At this point NETFS_CAPABILITIES response command
-        * should setup superblock in a way, which is acceptable
-        * for both client and server, so if server refuses connection,
-        * it will send error in transaction response.
-        */
-
-       if (err)
-               goto err_out_exit;
-
-       return 0;
-
-err_out_exit:
-       return err;
-}
-
-int pohmelfs_crypto_init(struct pohmelfs_sb *psb)
-{
-       int err;
-
-       if (!psb->cipher_string && !psb->hash_string)
-               return 0;
-
-       err = pohmelfs_crypto_init_handshake(psb);
-       if (err)
-               return err;
-
-       err = pohmelfs_sys_crypto_init(psb);
-       if (err)
-               return err;
-
-       return 0;
-}
-
-static int pohmelfs_crypto_thread_get(struct pohmelfs_sb *psb,
-               int (*action)(struct pohmelfs_crypto_thread *t, void *data), void *data)
-{
-       struct pohmelfs_crypto_thread *t = NULL;
-       int err;
-
-       while (!t) {
-               err = wait_event_interruptible_timeout(psb->wait,
-                               !list_empty(&psb->crypto_ready_list),
-                               psb->wait_on_page_timeout);
-
-               t = NULL;
-               err = 0;
-               mutex_lock(&psb->crypto_thread_lock);
-               if (!list_empty(&psb->crypto_ready_list)) {
-                       t = list_entry(psb->crypto_ready_list.prev,
-                                       struct pohmelfs_crypto_thread,
-                                       thread_entry);
-
-                       list_move_tail(&t->thread_entry,
-                                       &psb->crypto_active_list);
-
-                       action(t, data);
-                       wake_up(&t->wait);
-
-               }
-               mutex_unlock(&psb->crypto_thread_lock);
-       }
-
-       return err;
-}
-
-static int pohmelfs_trans_crypt_action(struct pohmelfs_crypto_thread *t, void *data)
-{
-       struct netfs_trans *trans = data;
-
-       netfs_trans_get(trans);
-       t->trans = trans;
-
-       dprintk("%s: t: %p, gen: %u, thread: %p.\n", __func__, trans, trans->gen, t);
-       return 0;
-}
-
-int pohmelfs_trans_crypt(struct netfs_trans *trans, struct pohmelfs_sb *psb)
-{
-       if ((!psb->hash_string && !psb->cipher_string) || !psb->perform_crypto) {
-               netfs_trans_get(trans);
-               return pohmelfs_crypto_finish(trans, psb, 0);
-       }
-
-       return pohmelfs_crypto_thread_get(psb, pohmelfs_trans_crypt_action, trans);
-}
-
-struct pohmelfs_crypto_input_action_data {
-       struct page                     *page;
-       struct pohmelfs_crypto_engine   *e;
-       u64                             iv;
-       unsigned int                    size;
-};
-
-static int pohmelfs_crypt_input_page_action(struct pohmelfs_crypto_thread *t, void *data)
-{
-       struct pohmelfs_crypto_input_action_data *act = data;
-
-       memcpy(t->eng.data, act->e->data, t->psb->crypto_attached_size);
-
-       t->size = act->size;
-       t->eng.iv = act->iv;
-
-       t->page = act->page;
-       return 0;
-}
-
-int pohmelfs_crypto_process_input_page(struct pohmelfs_crypto_engine *e,
-               struct page *page, unsigned int size, u64 iv)
-{
-       struct inode *inode = page->mapping->host;
-       struct pohmelfs_crypto_input_action_data act;
-       int err = -ENOENT;
-
-       act.page = page;
-       act.e = e;
-       act.size = size;
-       act.iv = iv;
-
-       err = pohmelfs_crypto_thread_get(POHMELFS_SB(inode->i_sb),
-                       pohmelfs_crypt_input_page_action, &act);
-       if (err)
-               goto err_out_exit;
-
-       return 0;
-
-err_out_exit:
-       SetPageUptodate(page);
-       page_cache_release(page);
-
-       return err;
-}
diff --git a/drivers/staging/pohmelfs/dir.c b/drivers/staging/pohmelfs/dir.c
deleted file mode 100644 (file)
index 2ee4491..0000000
+++ /dev/null
@@ -1,1102 +0,0 @@
-/*
- * 2007+ Copyright (c) Evgeniy Polyakov <zbr@ioremap.net>
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- */
-
-#include <linux/kernel.h>
-#include <linux/fs.h>
-#include <linux/jhash.h>
-#include <linux/namei.h>
-#include <linux/slab.h>
-#include <linux/pagemap.h>
-
-#include "netfs.h"
-
-static int pohmelfs_cmp_hash(struct pohmelfs_name *n, u32 hash)
-{
-       if (n->hash > hash)
-               return -1;
-       if (n->hash < hash)
-               return 1;
-
-       return 0;
-}
-
-static struct pohmelfs_name *pohmelfs_search_hash_unprecise(struct pohmelfs_inode *pi, u32 hash)
-{
-       struct rb_node *n = pi->hash_root.rb_node;
-       struct pohmelfs_name *tmp = NULL;
-       int cmp;
-
-       while (n) {
-               tmp = rb_entry(n, struct pohmelfs_name, hash_node);
-
-               cmp = pohmelfs_cmp_hash(tmp, hash);
-               if (cmp < 0)
-                       n = n->rb_left;
-               else if (cmp > 0)
-                       n = n->rb_right;
-               else
-                       break;
-
-       }
-
-       return tmp;
-}
-
-struct pohmelfs_name *pohmelfs_search_hash(struct pohmelfs_inode *pi, u32 hash)
-{
-       struct pohmelfs_name *tmp;
-
-       tmp = pohmelfs_search_hash_unprecise(pi, hash);
-       if (tmp && (tmp->hash == hash))
-               return tmp;
-
-       return NULL;
-}
-
-static void __pohmelfs_name_del(struct pohmelfs_inode *parent, struct pohmelfs_name *node)
-{
-       rb_erase(&node->hash_node, &parent->hash_root);
-}
-
-/*
- * Remove name cache entry from its caches and free it.
- */
-static void pohmelfs_name_free(struct pohmelfs_inode *parent, struct pohmelfs_name *node)
-{
-       __pohmelfs_name_del(parent, node);
-       list_del(&node->sync_create_entry);
-       kfree(node);
-}
-
-static struct pohmelfs_name *pohmelfs_insert_hash(struct pohmelfs_inode *pi,
-               struct pohmelfs_name *new)
-{
-       struct rb_node **n = &pi->hash_root.rb_node, *parent = NULL;
-       struct pohmelfs_name *ret = NULL, *tmp;
-       int cmp;
-
-       while (*n) {
-               parent = *n;
-
-               tmp = rb_entry(parent, struct pohmelfs_name, hash_node);
-
-               cmp = pohmelfs_cmp_hash(tmp, new->hash);
-               if (cmp < 0)
-                       n = &parent->rb_left;
-               else if (cmp > 0)
-                       n = &parent->rb_right;
-               else {
-                       ret = tmp;
-                       break;
-               }
-       }
-
-       if (ret) {
-               printk("%s: exist: parent: %llu, ino: %llu, hash: %x, len: %u, data: '%s', "
-                                       "new: ino: %llu, hash: %x, len: %u, data: '%s'.\n",
-                               __func__, pi->ino,
-                               ret->ino, ret->hash, ret->len, ret->data,
-                               new->ino, new->hash, new->len, new->data);
-               ret->ino = new->ino;
-               return ret;
-       }
-
-       rb_link_node(&new->hash_node, parent, n);
-       rb_insert_color(&new->hash_node, &pi->hash_root);
-
-       return NULL;
-}
-
-/*
- * Free name cache for given inode.
- */
-void pohmelfs_free_names(struct pohmelfs_inode *parent)
-{
-       struct rb_node *rb_node;
-       struct pohmelfs_name *n;
-
-       for (rb_node = rb_first(&parent->hash_root); rb_node;) {
-               n = rb_entry(rb_node, struct pohmelfs_name, hash_node);
-               rb_node = rb_next(rb_node);
-
-               pohmelfs_name_free(parent, n);
-       }
-}
-
-static void pohmelfs_fix_offset(struct pohmelfs_inode *parent, struct pohmelfs_name *node)
-{
-       parent->total_len -= node->len;
-}
-
-/*
- * Free name cache entry helper.
- */
-void pohmelfs_name_del(struct pohmelfs_inode *parent, struct pohmelfs_name *node)
-{
-       pohmelfs_fix_offset(parent, node);
-       pohmelfs_name_free(parent, node);
-}
-
-/*
- * Insert new name cache entry into all hash cache.
- */
-static int pohmelfs_insert_name(struct pohmelfs_inode *parent, struct pohmelfs_name *n)
-{
-       struct pohmelfs_name *name;
-
-       name = pohmelfs_insert_hash(parent, n);
-       if (name)
-               return -EEXIST;
-
-       parent->total_len += n->len;
-       list_add_tail(&n->sync_create_entry, &parent->sync_create_list);
-
-       return 0;
-}
-
-/*
- * Allocate new name cache entry.
- */
-static struct pohmelfs_name *pohmelfs_name_alloc(unsigned int len)
-{
-       struct pohmelfs_name *n;
-
-       n = kzalloc(sizeof(struct pohmelfs_name) + len, GFP_KERNEL);
-       if (!n)
-               return NULL;
-
-       INIT_LIST_HEAD(&n->sync_create_entry);
-
-       n->data = (char *)(n+1);
-
-       return n;
-}
-
-/*
- * Add new name entry into directory's cache.
- */
-static int pohmelfs_add_dir(struct pohmelfs_sb *psb, struct pohmelfs_inode *parent,
-               struct pohmelfs_inode *npi, struct qstr *str, unsigned int mode, int link)
-{
-       int err = -ENOMEM;
-       struct pohmelfs_name *n;
-
-       n = pohmelfs_name_alloc(str->len + 1);
-       if (!n)
-               goto err_out_exit;
-
-       n->ino = npi->ino;
-       n->mode = mode;
-       n->len = str->len;
-       n->hash = str->hash;
-       sprintf(n->data, "%s", str->name);
-
-       mutex_lock(&parent->offset_lock);
-       err = pohmelfs_insert_name(parent, n);
-       mutex_unlock(&parent->offset_lock);
-
-       if (err) {
-               if (err != -EEXIST)
-                       goto err_out_free;
-               kfree(n);
-       }
-
-       return 0;
-
-err_out_free:
-       kfree(n);
-err_out_exit:
-       return err;
-}
-
-/*
- * Create new inode for given parameters (name, inode info, parent).
- * This does not create object on the server, it will be synced there during writeback.
- */
-struct pohmelfs_inode *pohmelfs_new_inode(struct pohmelfs_sb *psb,
-               struct pohmelfs_inode *parent, struct qstr *str,
-               struct netfs_inode_info *info, int link)
-{
-       struct inode *new = NULL;
-       struct pohmelfs_inode *npi;
-       int err = -EEXIST;
-
-       dprintk("%s: creating inode: parent: %llu, ino: %llu, str: %p.\n",
-                       __func__, (parent) ? parent->ino : 0, info->ino, str);
-
-       err = -ENOMEM;
-       new = iget_locked(psb->sb, info->ino);
-       if (!new)
-               goto err_out_exit;
-
-       npi = POHMELFS_I(new);
-       npi->ino = info->ino;
-       err = 0;
-
-       if (new->i_state & I_NEW) {
-               dprintk("%s: filling VFS inode: %lu/%llu.\n",
-                               __func__, new->i_ino, info->ino);
-               pohmelfs_fill_inode(new, info);
-
-               if (S_ISDIR(info->mode)) {
-                       struct qstr s;
-
-                       s.name = ".";
-                       s.len = 1;
-                       s.hash = jhash(s.name, s.len, 0);
-
-                       err = pohmelfs_add_dir(psb, npi, npi, &s, info->mode, 0);
-                       if (err)
-                               goto err_out_put;
-
-                       s.name = "..";
-                       s.len = 2;
-                       s.hash = jhash(s.name, s.len, 0);
-
-                       err = pohmelfs_add_dir(psb, npi, (parent) ? parent : npi, &s,
-                                       (parent) ? parent->vfs_inode.i_mode : npi->vfs_inode.i_mode, 0);
-                       if (err)
-                               goto err_out_put;
-               }
-       }
-
-       if (str) {
-               if (parent) {
-                       err = pohmelfs_add_dir(psb, parent, npi, str, info->mode, link);
-
-                       dprintk("%s: %s inserted name: '%s', new_offset: %llu, ino: %llu, parent: %llu.\n",
-                                       __func__, (err) ? "unsuccessfully" : "successfully",
-                                       str->name, parent->total_len, info->ino, parent->ino);
-
-                       if (err && err != -EEXIST)
-                               goto err_out_put;
-               }
-       }
-
-       if (new->i_state & I_NEW) {
-               if (parent)
-                       mark_inode_dirty(&parent->vfs_inode);
-               mark_inode_dirty(new);
-       }
-
-       set_bit(NETFS_INODE_OWNED, &npi->state);
-       npi->lock_type = POHMELFS_WRITE_LOCK;
-       unlock_new_inode(new);
-
-       return npi;
-
-err_out_put:
-       printk("%s: putting inode: %p, npi: %p, error: %d.\n", __func__, new, npi, err);
-       iput(new);
-err_out_exit:
-       return ERR_PTR(err);
-}
-
-static int pohmelfs_remote_sync_complete(struct page **pages, unsigned int page_num,
-               void *private, int err)
-{
-       struct pohmelfs_inode *pi = private;
-       struct pohmelfs_sb *psb = POHMELFS_SB(pi->vfs_inode.i_sb);
-
-       dprintk("%s: ino: %llu, err: %d.\n", __func__, pi->ino, err);
-
-       if (err)
-               pi->error = err;
-       wake_up(&psb->wait);
-       pohmelfs_put_inode(pi);
-
-       return err;
-}
-
-/*
- * Receive directory content from the server.
- * This should be only done for objects, which were not created locally,
- * and which were not synced previously.
- */
-static int pohmelfs_sync_remote_dir(struct pohmelfs_inode *pi)
-{
-       struct inode *inode = &pi->vfs_inode;
-       struct pohmelfs_sb *psb = POHMELFS_SB(inode->i_sb);
-       long ret = psb->wait_on_page_timeout;
-       int err;
-
-       dprintk("%s: dir: %llu, state: %lx: remote_synced: %d.\n",
-               __func__, pi->ino, pi->state, test_bit(NETFS_INODE_REMOTE_SYNCED, &pi->state));
-
-       if (test_bit(NETFS_INODE_REMOTE_DIR_SYNCED, &pi->state))
-               return 0;
-
-       if (!igrab(inode)) {
-               err = -ENOENT;
-               goto err_out_exit;
-       }
-
-       err = pohmelfs_meta_command(pi, NETFS_READDIR, NETFS_TRANS_SINGLE_DST,
-                       pohmelfs_remote_sync_complete, pi, 0);
-       if (err)
-               goto err_out_exit;
-
-       pi->error = 0;
-       ret = wait_event_interruptible_timeout(psb->wait,
-                       test_bit(NETFS_INODE_REMOTE_DIR_SYNCED, &pi->state) || pi->error, ret);
-       dprintk("%s: awake dir: %llu, ret: %ld, err: %d.\n", __func__, pi->ino, ret, pi->error);
-       if (ret <= 0) {
-               err = ret;
-               if (!err)
-                       err = -ETIMEDOUT;
-               goto err_out_exit;
-       }
-
-       if (pi->error)
-               return pi->error;
-
-       return 0;
-
-err_out_exit:
-       clear_bit(NETFS_INODE_REMOTE_SYNCED, &pi->state);
-
-       return err;
-}
-
-static int pohmelfs_dir_open(struct inode *inode, struct file *file)
-{
-       file->private_data = NULL;
-       return 0;
-}
-
-/*
- * VFS readdir callback. Syncs directory content from server if needed,
- * and provides direntry info to the userspace.
- */
-static int pohmelfs_readdir(struct file *file, void *dirent, filldir_t filldir)
-{
-       struct inode *inode = file->f_path.dentry->d_inode;
-       struct pohmelfs_inode *pi = POHMELFS_I(inode);
-       struct pohmelfs_name *n;
-       struct rb_node *rb_node;
-       int err = 0, mode;
-       u64 len;
-
-       dprintk("%s: parent: %llu, fpos: %llu, hash: %08lx.\n",
-                       __func__, pi->ino, (u64)file->f_pos,
-                       (unsigned long)file->private_data);
-#if 0
-       err = pohmelfs_data_lock(pi, 0, ~0, POHMELFS_READ_LOCK);
-       if (err)
-               return err;
-#endif
-       err = pohmelfs_sync_remote_dir(pi);
-       if (err)
-               return err;
-
-       if (file->private_data && (file->private_data == (void *)(unsigned long)file->f_pos))
-               return 0;
-
-       mutex_lock(&pi->offset_lock);
-       n = pohmelfs_search_hash_unprecise(pi, (unsigned long)file->private_data);
-
-       while (n) {
-               mode = (n->mode >> 12) & 15;
-
-               dprintk("%s: offset: %llu, parent ino: %llu, name: '%s', len: %u, ino: %llu, "
-                               "mode: %o/%o, fpos: %llu, hash: %08x.\n",
-                               __func__, file->f_pos, pi->ino, n->data, n->len,
-                               n->ino, n->mode, mode, file->f_pos, n->hash);
-
-               file->private_data = (void *)(unsigned long)n->hash;
-
-               len = n->len;
-               err = filldir(dirent, n->data, n->len, file->f_pos, n->ino, mode);
-
-               if (err < 0) {
-                       dprintk("%s: err: %d.\n", __func__, err);
-                       err = 0;
-                       break;
-               }
-
-               file->f_pos += len;
-
-               rb_node = rb_next(&n->hash_node);
-
-               if (!rb_node || (rb_node == &n->hash_node)) {
-                       file->private_data = (void *)(unsigned long)file->f_pos;
-                       break;
-               }
-
-               n = rb_entry(rb_node, struct pohmelfs_name, hash_node);
-       }
-       mutex_unlock(&pi->offset_lock);
-
-       return err;
-}
-
-static loff_t pohmelfs_dir_lseek(struct file *file, loff_t offset, int origin)
-{
-       file->f_pos = offset;
-       file->private_data = NULL;
-       return offset;
-}
-
-const struct file_operations pohmelfs_dir_fops = {
-       .open = pohmelfs_dir_open,
-       .read = generic_read_dir,
-       .llseek = pohmelfs_dir_lseek,
-       .readdir = pohmelfs_readdir,
-};
-
-/*
- * Lookup single object on server.
- */
-static int pohmelfs_lookup_single(struct pohmelfs_inode *parent,
-               struct qstr *str, u64 ino)
-{
-       struct pohmelfs_sb *psb = POHMELFS_SB(parent->vfs_inode.i_sb);
-       long ret = msecs_to_jiffies(5000);
-       int err;
-
-       set_bit(NETFS_COMMAND_PENDING, &parent->state);
-       err = pohmelfs_meta_command_data(parent, parent->ino, NETFS_LOOKUP,
-                       (char *)str->name, NETFS_TRANS_SINGLE_DST, NULL, NULL, ino);
-       if (err)
-               goto err_out_exit;
-
-       err = 0;
-       ret = wait_event_interruptible_timeout(psb->wait,
-                       !test_bit(NETFS_COMMAND_PENDING, &parent->state), ret);
-       if (ret <= 0) {
-               err = ret;
-               if (!err)
-                       err = -ETIMEDOUT;
-       }
-
-       if (err)
-               goto err_out_exit;
-
-       return 0;
-
-err_out_exit:
-       clear_bit(NETFS_COMMAND_PENDING, &parent->state);
-
-       printk("%s: failed: parent: %llu, ino: %llu, name: '%s', err: %d.\n",
-                       __func__, parent->ino, ino, str->name, err);
-
-       return err;
-}
-
-/*
- * VFS lookup callback.
- * We first try to get inode number from local name cache, if we have one,
- * then inode can be found in inode cache. If there is no inode or no object in
- * local cache, try to lookup it on server. This only should be done for directories,
- * which were not created locally, otherwise remote server does not know about dir at all,
- * so no need to try to know that.
- */
-struct dentry *pohmelfs_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
-{
-       struct pohmelfs_inode *parent = POHMELFS_I(dir);
-       struct pohmelfs_name *n;
-       struct inode *inode = NULL;
-       unsigned long ino = 0;
-       int err, lock_type = POHMELFS_READ_LOCK, need_lock = 1;
-       struct qstr str = dentry->d_name;
-
-       if ((nd->intent.open.flags & O_ACCMODE) != O_RDONLY)
-               lock_type = POHMELFS_WRITE_LOCK;
-
-       if (test_bit(NETFS_INODE_OWNED, &parent->state)) {
-               if (lock_type == parent->lock_type)
-                       need_lock = 0;
-               if ((lock_type == POHMELFS_READ_LOCK) && (parent->lock_type == POHMELFS_WRITE_LOCK))
-                       need_lock = 0;
-       }
-
-       if ((lock_type == POHMELFS_READ_LOCK) && !test_bit(NETFS_INODE_REMOTE_DIR_SYNCED, &parent->state))
-               need_lock = 1;
-
-       str.hash = jhash(dentry->d_name.name, dentry->d_name.len, 0);
-
-       mutex_lock(&parent->offset_lock);
-       n = pohmelfs_search_hash(parent, str.hash);
-       if (n)
-               ino = n->ino;
-       mutex_unlock(&parent->offset_lock);
-
-       dprintk("%s: start ino: %lu, inode: %p, name: '%s', hash: %x, parent_state: %lx, need_lock: %d.\n",
-                       __func__, ino, inode, str.name, str.hash, parent->state, need_lock);
-
-       if (ino) {
-               inode = ilookup(dir->i_sb, ino);
-               if (inode)
-                       goto out;
-       }
-
-       dprintk("%s: no inode dir: %p, dir_ino: %llu, name: '%s', len: %u, dir_state: %lx, ino: %lu.\n",
-                       __func__, dir, parent->ino,
-                       str.name, str.len, parent->state, ino);
-
-       if (!ino) {
-               if (!need_lock)
-                       goto out;
-       }
-
-       err = pohmelfs_data_lock(parent, 0, ~0, lock_type);
-       if (err)
-               goto out;
-
-       err = pohmelfs_lookup_single(parent, &str, ino);
-       if (err)
-               goto out;
-
-       if (!ino) {
-               mutex_lock(&parent->offset_lock);
-               n = pohmelfs_search_hash(parent, str.hash);
-               if (n)
-                       ino = n->ino;
-               mutex_unlock(&parent->offset_lock);
-       }
-
-       if (ino) {
-               inode = ilookup(dir->i_sb, ino);
-               dprintk("%s: second lookup ino: %lu, inode: %p, name: '%s', hash: %x.\n",
-                               __func__, ino, inode, str.name, str.hash);
-               if (!inode) {
-                       dprintk("%s: No inode for ino: %lu, name: '%s', hash: %x.\n",
-                               __func__, ino, str.name, str.hash);
-                       /* return NULL; */
-                       return ERR_PTR(-EACCES);
-               }
-       } else {
-               printk("%s: No inode number : name: '%s', hash: %x.\n",
-                       __func__, str.name, str.hash);
-       }
-out:
-       return d_splice_alias(inode, dentry);
-}
-
-/*
- * Create new object in local cache. Object will be synced to server
- * during writeback for given inode.
- */
-struct pohmelfs_inode *pohmelfs_create_entry_local(struct pohmelfs_sb *psb,
-       struct pohmelfs_inode *parent, struct qstr *str, u64 start, umode_t mode)
-{
-       struct pohmelfs_inode *npi;
-       int err = -ENOMEM;
-       struct netfs_inode_info info;
-
-       dprintk("%s: name: '%s', mode: %ho, start: %llu.\n",
-                       __func__, str->name, mode, start);
-
-       info.mode = mode;
-       info.ino = start;
-
-       if (!start)
-               info.ino = pohmelfs_new_ino(psb);
-
-       info.nlink = S_ISDIR(mode) ? 2 : 1;
-       info.uid = current_fsuid();
-       info.gid = current_fsgid();
-       info.size = 0;
-       info.blocksize = 512;
-       info.blocks = 0;
-       info.rdev = 0;
-       info.version = 0;
-
-       npi = pohmelfs_new_inode(psb, parent, str, &info, !!start);
-       if (IS_ERR(npi)) {
-               err = PTR_ERR(npi);
-               goto err_out_unlock;
-       }
-
-       return npi;
-
-err_out_unlock:
-       dprintk("%s: err: %d.\n", __func__, err);
-       return ERR_PTR(err);
-}
-
-/*
- * Create local object and bind it to dentry.
- */
-static int pohmelfs_create_entry(struct inode *dir, struct dentry *dentry,
-                                u64 start, umode_t mode)
-{
-       struct pohmelfs_sb *psb = POHMELFS_SB(dir->i_sb);
-       struct pohmelfs_inode *npi, *parent;
-       struct qstr str = dentry->d_name;
-       int err;
-
-       parent = POHMELFS_I(dir);
-
-       err = pohmelfs_data_lock(parent, 0, ~0, POHMELFS_WRITE_LOCK);
-       if (err)
-               return err;
-
-       str.hash = jhash(dentry->d_name.name, dentry->d_name.len, 0);
-
-       npi = pohmelfs_create_entry_local(psb, parent, &str, start, mode);
-       if (IS_ERR(npi))
-               return PTR_ERR(npi);
-
-       d_instantiate(dentry, &npi->vfs_inode);
-
-       dprintk("%s: parent: %llu, inode: %llu, name: '%s', parent_nlink: %d, nlink: %d.\n",
-                       __func__, parent->ino, npi->ino, dentry->d_name.name,
-                       (signed)dir->i_nlink, (signed)npi->vfs_inode.i_nlink);
-
-       return 0;
-}
-
-/*
- * VFS create and mkdir callbacks.
- */
-static int pohmelfs_create(struct inode *dir, struct dentry *dentry, umode_t mode,
-               struct nameidata *nd)
-{
-       return pohmelfs_create_entry(dir, dentry, 0, mode);
-}
-
-static int pohmelfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
-{
-       int err;
-
-       inode_inc_link_count(dir);
-       err = pohmelfs_create_entry(dir, dentry, 0, mode | S_IFDIR);
-       if (err)
-               inode_dec_link_count(dir);
-
-       return err;
-}
-
-static int pohmelfs_remove_entry(struct inode *dir, struct dentry *dentry)
-{
-       struct pohmelfs_sb *psb = POHMELFS_SB(dir->i_sb);
-       struct inode *inode = dentry->d_inode;
-       struct pohmelfs_inode *parent = POHMELFS_I(dir), *pi = POHMELFS_I(inode);
-       struct pohmelfs_name *n;
-       int err = -ENOENT;
-       struct qstr str = dentry->d_name;
-
-       err = pohmelfs_data_lock(parent, 0, ~0, POHMELFS_WRITE_LOCK);
-       if (err)
-               return err;
-
-       str.hash = jhash(dentry->d_name.name, dentry->d_name.len, 0);
-
-       dprintk("%s: dir_ino: %llu, inode: %llu, name: '%s', nlink: %d.\n",
-                       __func__, parent->ino, pi->ino,
-                       str.name, (signed)inode->i_nlink);
-
-       BUG_ON(!inode);
-
-       mutex_lock(&parent->offset_lock);
-       n = pohmelfs_search_hash(parent, str.hash);
-       if (n) {
-               pohmelfs_fix_offset(parent, n);
-               if (test_bit(NETFS_INODE_REMOTE_SYNCED, &pi->state))
-                       pohmelfs_remove_child(pi, n);
-
-               pohmelfs_name_free(parent, n);
-               err = 0;
-       }
-       mutex_unlock(&parent->offset_lock);
-
-       if (!err) {
-               psb->avail_size += inode->i_size;
-
-               pohmelfs_inode_del_inode(psb, pi);
-
-               mark_inode_dirty(dir);
-
-               inode->i_ctime = dir->i_ctime;
-               if (inode->i_nlink)
-                       inode_dec_link_count(inode);
-       }
-
-       return err;
-}
-
-/*
- * Unlink and rmdir VFS callbacks.
- */
-static int pohmelfs_unlink(struct inode *dir, struct dentry *dentry)
-{
-       return pohmelfs_remove_entry(dir, dentry);
-}
-
-static int pohmelfs_rmdir(struct inode *dir, struct dentry *dentry)
-{
-       int err;
-       struct inode *inode = dentry->d_inode;
-
-       dprintk("%s: parent: %llu, inode: %llu, name: '%s', parent_nlink: %d, nlink: %d.\n",
-                       __func__, POHMELFS_I(dir)->ino, POHMELFS_I(inode)->ino,
-                       dentry->d_name.name, (signed)dir->i_nlink, (signed)inode->i_nlink);
-
-       err = pohmelfs_remove_entry(dir, dentry);
-       if (!err) {
-               inode_dec_link_count(dir);
-               inode_dec_link_count(inode);
-       }
-
-       return err;
-}
-
-/*
- * Link creation is synchronous.
- * I'm lazy.
- * Earth is somewhat round.
- */
-static int pohmelfs_create_link(struct pohmelfs_inode *parent, struct qstr *obj,
-               struct pohmelfs_inode *target, struct qstr *tstr)
-{
-       struct super_block *sb = parent->vfs_inode.i_sb;
-       struct pohmelfs_sb *psb = POHMELFS_SB(sb);
-       struct netfs_cmd *cmd;
-       struct netfs_trans *t;
-       void *data;
-       int err, parent_len, target_len = 0, cur_len, path_size = 0;
-
-       err = pohmelfs_data_lock(parent, 0, ~0, POHMELFS_WRITE_LOCK);
-       if (err)
-               return err;
-
-       err = sb->s_op->write_inode(&parent->vfs_inode, 0);
-       if (err)
-               goto err_out_exit;
-
-       if (tstr)
-               target_len = tstr->len;
-
-       parent_len = pohmelfs_path_length(parent);
-       if (target)
-               target_len += pohmelfs_path_length(target);
-
-       if (parent_len < 0) {
-               err = parent_len;
-               goto err_out_exit;
-       }
-
-       if (target_len < 0) {
-               err = target_len;
-               goto err_out_exit;
-       }
-
-       t = netfs_trans_alloc(psb, parent_len + target_len + obj->len + 2, 0, 0);
-       if (!t) {
-               err = -ENOMEM;
-               goto err_out_exit;
-       }
-       cur_len = netfs_trans_cur_len(t);
-
-       cmd = netfs_trans_current(t);
-       if (IS_ERR(cmd)) {
-               err = PTR_ERR(cmd);
-               goto err_out_free;
-       }
-
-       data = (void *)(cmd + 1);
-       cur_len -= sizeof(struct netfs_cmd);
-
-       err = pohmelfs_construct_path_string(parent, data, parent_len);
-       if (err > 0) {
-               /* Do not place null-byte before the slash */
-               path_size = err - 1;
-               cur_len -= path_size;
-
-               err = snprintf(data + path_size, cur_len, "/%s|", obj->name);
-
-               path_size += err;
-               cur_len -= err;
-
-               cmd->ext = path_size - 1; /* No | symbol */
-
-               if (target) {
-                       err = pohmelfs_construct_path_string(target, data + path_size, target_len);
-                       if (err > 0) {
-                               path_size += err;
-                               cur_len -= err;
-                       }
-               }
-       }
-
-       if (err < 0)
-               goto err_out_free;
-
-       cmd->start = 0;
-
-       if (!target && tstr) {
-               if (tstr->len > cur_len - 1) {
-                       err = -ENAMETOOLONG;
-                       goto err_out_free;
-               }
-
-               err = snprintf(data + path_size, cur_len, "%s", tstr->name) + 1; /* 0-byte */
-               path_size += err;
-               cur_len -= err;
-               cmd->start = 1;
-       }
-
-       dprintk("%s: parent: %llu, obj: '%s', target_inode: %llu, target_str: '%s', full: '%s'.\n",
-                       __func__, parent->ino, obj->name, (target) ? target->ino : 0, (tstr) ? tstr->name : NULL,
-                       (char *)data);
-
-       cmd->cmd = NETFS_LINK;
-       cmd->size = path_size;
-       cmd->id = parent->ino;
-
-       netfs_convert_cmd(cmd);
-
-       netfs_trans_update(cmd, t, path_size);
-
-       err = netfs_trans_finish(t, psb);
-       if (err)
-               goto err_out_exit;
-
-       return 0;
-
-err_out_free:
-       t->result = err;
-       netfs_trans_put(t);
-err_out_exit:
-       return err;
-}
-
-/*
- *  VFS hard and soft link callbacks.
- */
-static int pohmelfs_link(struct dentry *old_dentry, struct inode *dir,
-       struct dentry *dentry)
-{
-       struct inode *inode = old_dentry->d_inode;
-       struct pohmelfs_inode *pi = POHMELFS_I(inode);
-       int err;
-       struct qstr str = dentry->d_name;
-
-       str.hash = jhash(dentry->d_name.name, dentry->d_name.len, 0);
-
-       err = inode->i_sb->s_op->write_inode(inode, 0);
-       if (err)
-               return err;
-
-       err = pohmelfs_create_link(POHMELFS_I(dir), &str, pi, NULL);
-       if (err)
-               return err;
-
-       return pohmelfs_create_entry(dir, dentry, pi->ino, inode->i_mode);
-}
-
-static int pohmelfs_symlink(struct inode *dir, struct dentry *dentry, const char *symname)
-{
-       struct qstr sym_str;
-       struct qstr str = dentry->d_name;
-       struct inode *inode;
-       int err;
-
-       str.hash = jhash(dentry->d_name.name, dentry->d_name.len, 0);
-
-       sym_str.name = symname;
-       sym_str.len = strlen(symname);
-
-       err = pohmelfs_create_link(POHMELFS_I(dir), &str, NULL, &sym_str);
-       if (err)
-               goto err_out_exit;
-
-       err = pohmelfs_create_entry(dir, dentry, 0, S_IFLNK | S_IRWXU | S_IRWXG | S_IRWXO);
-       if (err)
-               goto err_out_exit;
-
-       inode = dentry->d_inode;
-
-       err = page_symlink(inode, symname, sym_str.len + 1);
-       if (err)
-               goto err_out_put;
-
-       return 0;
-
-err_out_put:
-       iput(inode);
-err_out_exit:
-       return err;
-}
-
-static int pohmelfs_send_rename(struct pohmelfs_inode *pi, struct pohmelfs_inode *parent,
-               struct qstr *str)
-{
-       int path_len, err, total_len = 0, inode_len, parent_len;
-       char *path;
-       struct netfs_trans *t;
-       struct netfs_cmd *cmd;
-       struct pohmelfs_sb *psb = POHMELFS_SB(pi->vfs_inode.i_sb);
-
-       parent_len = pohmelfs_path_length(parent);
-       inode_len = pohmelfs_path_length(pi);
-
-       if (parent_len < 0 || inode_len < 0)
-               return -EINVAL;
-
-       path_len = parent_len + inode_len + str->len + 3;
-
-       t = netfs_trans_alloc(psb, path_len, 0, 0);
-       if (!t)
-               return -ENOMEM;
-
-       cmd = netfs_trans_current(t);
-       path = (char *)(cmd + 1);
-
-       err = pohmelfs_construct_path_string(pi, path, inode_len);
-       if (err < 0)
-               goto err_out_unlock;
-
-       cmd->ext = err;
-
-       path += err;
-       total_len += err;
-       path_len -= err;
-
-       *path = '|';
-       path++;
-       total_len++;
-       path_len--;
-
-       err = pohmelfs_construct_path_string(parent, path, parent_len);
-       if (err < 0)
-               goto err_out_unlock;
-
-       /*
-        * Do not place a null-byte before the final slash and the name.
-        */
-       err--;
-       path += err;
-       total_len += err;
-       path_len -= err;
-
-       err = snprintf(path, path_len - 1, "/%s", str->name);
-
-       total_len += err + 1; /* 0 symbol */
-       path_len -= err + 1;
-
-       cmd->cmd = NETFS_RENAME;
-       cmd->id = pi->ino;
-       cmd->start = parent->ino;
-       cmd->size = total_len;
-
-       netfs_convert_cmd(cmd);
-
-       netfs_trans_update(cmd, t, total_len);
-
-       return netfs_trans_finish(t, psb);
-
-err_out_unlock:
-       netfs_trans_free(t);
-       return err;
-}
-
-static int pohmelfs_rename(struct inode *old_dir, struct dentry *old_dentry,
-                       struct inode *new_dir, struct dentry *new_dentry)
-{
-       struct inode *inode = old_dentry->d_inode;
-       struct pohmelfs_inode *old_parent, *pi, *new_parent;
-       struct qstr str = new_dentry->d_name;
-       struct pohmelfs_name *n;
-       unsigned int old_hash;
-       int err = -ENOENT;
-
-       pi = POHMELFS_I(inode);
-       old_parent = POHMELFS_I(old_dir);
-
-       if (new_dir)
-               new_dir->i_sb->s_op->write_inode(new_dir, 0);
-
-       old_hash = jhash(old_dentry->d_name.name, old_dentry->d_name.len, 0);
-       str.hash = jhash(new_dentry->d_name.name, new_dentry->d_name.len, 0);
-
-       str.len = new_dentry->d_name.len;
-       str.name = new_dentry->d_name.name;
-       str.hash = jhash(new_dentry->d_name.name, new_dentry->d_name.len, 0);
-
-       if (new_dir) {
-               new_parent = POHMELFS_I(new_dir);
-               err = -ENOTEMPTY;
-
-               if (S_ISDIR(inode->i_mode) &&
-                               new_parent->total_len <= 3)
-                       goto err_out_exit;
-       } else {
-               new_parent = old_parent;
-       }
-
-       dprintk("%s: ino: %llu, parent: %llu, name: '%s' -> parent: %llu, name: '%s', i_size: %llu.\n",
-                       __func__, pi->ino, old_parent->ino, old_dentry->d_name.name,
-                       new_parent->ino, new_dentry->d_name.name, inode->i_size);
-
-       if (test_bit(NETFS_INODE_REMOTE_SYNCED, &pi->state) &&
-                       test_bit(NETFS_INODE_OWNED, &pi->state)) {
-               err = pohmelfs_send_rename(pi, new_parent, &str);
-               if (err)
-                       goto err_out_exit;
-       }
-
-       n = pohmelfs_name_alloc(str.len + 1);
-       if (!n)
-               goto err_out_exit;
-
-       mutex_lock(&new_parent->offset_lock);
-       n->ino = pi->ino;
-       n->mode = inode->i_mode;
-       n->len = str.len;
-       n->hash = str.hash;
-       sprintf(n->data, "%s", str.name);
-
-       err = pohmelfs_insert_name(new_parent, n);
-       mutex_unlock(&new_parent->offset_lock);
-
-       if (err)
-               goto err_out_exit;
-
-       mutex_lock(&old_parent->offset_lock);
-       n = pohmelfs_search_hash(old_parent, old_hash);
-       if (n)
-               pohmelfs_name_del(old_parent, n);
-       mutex_unlock(&old_parent->offset_lock);
-
-       mark_inode_dirty(inode);
-       mark_inode_dirty(&new_parent->vfs_inode);
-
-       WARN_ON_ONCE(list_empty(&inode->i_dentry));
-
-       return 0;
-
-err_out_exit:
-
-       clear_bit(NETFS_INODE_REMOTE_SYNCED, &pi->state);
-
-       return err;
-}
-
-/*
- * POHMELFS directory inode operations.
- */
-const struct inode_operations pohmelfs_dir_inode_ops = {
-       .link           = pohmelfs_link,
-       .symlink        = pohmelfs_symlink,
-       .unlink         = pohmelfs_unlink,
-       .mkdir          = pohmelfs_mkdir,
-       .rmdir          = pohmelfs_rmdir,
-       .create         = pohmelfs_create,
-       .lookup         = pohmelfs_lookup,
-       .setattr        = pohmelfs_setattr,
-       .rename         = pohmelfs_rename,
-};
diff --git a/drivers/staging/pohmelfs/inode.c b/drivers/staging/pohmelfs/inode.c
deleted file mode 100644 (file)
index 807e3f3..0000000
+++ /dev/null
@@ -1,2055 +0,0 @@
-/*
- * 2007+ Copyright (c) Evgeniy Polyakov <zbr@ioremap.net>
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- */
-
-#include <linux/module.h>
-#include <linux/backing-dev.h>
-#include <linux/crypto.h>
-#include <linux/fs.h>
-#include <linux/jhash.h>
-#include <linux/hash.h>
-#include <linux/ktime.h>
-#include <linux/mm.h>
-#include <linux/mount.h>
-#include <linux/pagemap.h>
-#include <linux/pagevec.h>
-#include <linux/parser.h>
-#include <linux/swap.h>
-#include <linux/slab.h>
-#include <linux/statfs.h>
-#include <linux/writeback.h>
-#include <linux/prefetch.h>
-
-#include "netfs.h"
-
-#define POHMELFS_MAGIC_NUM     0x504f482e
-
-static struct kmem_cache *pohmelfs_inode_cache;
-static atomic_t psb_bdi_num = ATOMIC_INIT(0);
-
-/*
- * Removes inode from all trees, drops local name cache and removes all queued
- * requests for object removal.
- */
-void pohmelfs_inode_del_inode(struct pohmelfs_sb *psb, struct pohmelfs_inode *pi)
-{
-       mutex_lock(&pi->offset_lock);
-       pohmelfs_free_names(pi);
-       mutex_unlock(&pi->offset_lock);
-
-       dprintk("%s: deleted stuff in ino: %llu.\n", __func__, pi->ino);
-}
-
-/*
- * Sync inode to server.
- * Returns zero in success and negative error value otherwise.
- * It will gather path to root directory into structures containing
- * creation mode, permissions and names, so that the whole path
- * to given inode could be created using only single network command.
- */
-int pohmelfs_write_inode_create(struct inode *inode, struct netfs_trans *trans)
-{
-       struct pohmelfs_inode *pi = POHMELFS_I(inode);
-       int err = -ENOMEM, size;
-       struct netfs_cmd *cmd;
-       void *data;
-       int cur_len = netfs_trans_cur_len(trans);
-
-       if (unlikely(cur_len < 0))
-               return -ETOOSMALL;
-
-       cmd = netfs_trans_current(trans);
-       cur_len -= sizeof(struct netfs_cmd);
-
-       data = (void *)(cmd + 1);
-
-       err = pohmelfs_construct_path_string(pi, data, cur_len);
-       if (err < 0)
-               goto err_out_exit;
-
-       size = err;
-
-       cmd->start = i_size_read(inode);
-       cmd->cmd = NETFS_CREATE;
-       cmd->size = size;
-       cmd->id = pi->ino;
-       cmd->ext = inode->i_mode;
-
-       netfs_convert_cmd(cmd);
-
-       netfs_trans_update(cmd, trans, size);
-
-       return 0;
-
-err_out_exit:
-       printk("%s: completed ino: %llu, err: %d.\n", __func__, pi->ino, err);
-       return err;
-}
-
-static int pohmelfs_write_trans_complete(struct page **pages, unsigned int page_num,
-               void *private, int err)
-{
-       unsigned i;
-
-       dprintk("%s: pages: %lu-%lu, page_num: %u, err: %d.\n",
-                       __func__, pages[0]->index, pages[page_num-1]->index,
-                       page_num, err);
-
-       for (i = 0; i < page_num; i++) {
-               struct page *page = pages[i];
-
-               if (!page)
-                       continue;
-
-               end_page_writeback(page);
-
-               if (err < 0) {
-                       SetPageError(page);
-                       set_page_dirty(page);
-               }
-
-               unlock_page(page);
-               page_cache_release(page);
-
-               /* dprintk("%s: %3u/%u: page: %p.\n", __func__, i, page_num, page); */
-       }
-       return err;
-}
-
-static int pohmelfs_inode_has_dirty_pages(struct address_space *mapping, pgoff_t index)
-{
-       int ret;
-       struct page *page;
-
-       rcu_read_lock();
-       ret = radix_tree_gang_lookup_tag(&mapping->page_tree,
-                               (void **)&page, index, 1, PAGECACHE_TAG_DIRTY);
-       rcu_read_unlock();
-       return ret;
-}
-
-static int pohmelfs_writepages(struct address_space *mapping, struct writeback_control *wbc)
-{
-       struct inode *inode = mapping->host;
-       struct pohmelfs_inode *pi = POHMELFS_I(inode);
-       struct pohmelfs_sb *psb = POHMELFS_SB(inode->i_sb);
-       int err = 0;
-       int done = 0;
-       int nr_pages;
-       pgoff_t index;
-       pgoff_t end;            /* Inclusive */
-       int scanned = 0;
-       int range_whole = 0;
-
-       if (wbc->range_cyclic) {
-               index = mapping->writeback_index; /* Start from prev offset */
-               end = -1;
-       } else {
-               index = wbc->range_start >> PAGE_CACHE_SHIFT;
-               end = wbc->range_end >> PAGE_CACHE_SHIFT;
-               if (wbc->range_start == 0 && wbc->range_end == LLONG_MAX)
-                       range_whole = 1;
-               scanned = 1;
-       }
-retry:
-       while (!done && (index <= end)) {
-               unsigned int i = min(end - index, (pgoff_t)psb->trans_max_pages);
-               int path_len;
-               struct netfs_trans *trans;
-
-               err = pohmelfs_inode_has_dirty_pages(mapping, index);
-               if (!err)
-                       break;
-
-               err = pohmelfs_path_length(pi);
-               if (err < 0)
-                       break;
-
-               path_len = err;
-
-               if (path_len <= 2) {
-                       err = -ENOENT;
-                       break;
-               }
-
-               trans = netfs_trans_alloc(psb, path_len, 0, i);
-               if (!trans) {
-                       err = -ENOMEM;
-                       break;
-               }
-               trans->complete = &pohmelfs_write_trans_complete;
-
-               trans->page_num = nr_pages = find_get_pages_tag(mapping, &index,
-                               PAGECACHE_TAG_DIRTY, trans->page_num,
-                               trans->pages);
-
-               dprintk("%s: t: %p, nr_pages: %u, end: %lu, index: %lu, max: %u.\n",
-                               __func__, trans, nr_pages, end, index, trans->page_num);
-
-               if (!nr_pages)
-                       goto err_out_reset;
-
-               err = pohmelfs_write_inode_create(inode, trans);
-               if (err)
-                       goto err_out_reset;
-
-               err = 0;
-               scanned = 1;
-
-               for (i = 0; i < trans->page_num; i++) {
-                       struct page *page = trans->pages[i];
-
-                       lock_page(page);
-
-                       if (unlikely(page->mapping != mapping))
-                               goto out_continue;
-
-                       if (!wbc->range_cyclic && page->index > end) {
-                               done = 1;
-                               goto out_continue;
-                       }
-
-                       if (wbc->sync_mode != WB_SYNC_NONE)
-                               wait_on_page_writeback(page);
-
-                       if (PageWriteback(page) ||
-                           !clear_page_dirty_for_io(page)) {
-                               dprintk("%s: not clear for io page: %p, writeback: %d.\n",
-                                               __func__, page, PageWriteback(page));
-                               goto out_continue;
-                       }
-
-                       set_page_writeback(page);
-
-                       trans->attached_size += page_private(page);
-                       trans->attached_pages++;
-#if 0
-                       dprintk("%s: %u/%u added trans: %p, gen: %u, page: %p, [High: %d], size: %lu, idx: %lu.\n",
-                                       __func__, i, trans->page_num, trans, trans->gen, page,
-                                       !!PageHighMem(page), page_private(page), page->index);
-#endif
-                       wbc->nr_to_write--;
-
-                       if (wbc->nr_to_write <= 0)
-                               done = 1;
-
-                       continue;
-out_continue:
-                       unlock_page(page);
-                       trans->pages[i] = NULL;
-               }
-
-               err = netfs_trans_finish(trans, psb);
-               if (err)
-                       break;
-
-               continue;
-
-err_out_reset:
-               trans->result = err;
-               netfs_trans_reset(trans);
-               netfs_trans_put(trans);
-               break;
-       }
-
-       if (!scanned && !done) {
-               /*
-                * We hit the last page and there is more work to be done: wrap
-                * back to the start of the file
-                */
-               scanned = 1;
-               index = 0;
-               goto retry;
-       }
-
-       if (wbc->range_cyclic || (range_whole && wbc->nr_to_write > 0))
-               mapping->writeback_index = index;
-
-       return err;
-}
-
-/*
- * Inode writeback creation completion callback.
- * Only invoked for just created inodes, which do not have pages attached,
- * like dirs and empty files.
- */
-static int pohmelfs_write_inode_complete(struct page **pages, unsigned int page_num,
-               void *private, int err)
-{
-       struct inode *inode = private;
-       struct pohmelfs_inode *pi = POHMELFS_I(inode);
-
-       if (inode) {
-               if (err) {
-                       mark_inode_dirty(inode);
-                       clear_bit(NETFS_INODE_REMOTE_SYNCED, &pi->state);
-               } else {
-                       set_bit(NETFS_INODE_REMOTE_SYNCED, &pi->state);
-               }
-
-               pohmelfs_put_inode(pi);
-       }
-
-       return err;
-}
-
-int pohmelfs_write_create_inode(struct pohmelfs_inode *pi)
-{
-       struct netfs_trans *t;
-       struct inode *inode = &pi->vfs_inode;
-       struct pohmelfs_sb *psb = POHMELFS_SB(inode->i_sb);
-       int err;
-
-       if (test_bit(NETFS_INODE_REMOTE_SYNCED, &pi->state))
-               return 0;
-
-       dprintk("%s: started ino: %llu.\n", __func__, pi->ino);
-
-       err = pohmelfs_path_length(pi);
-       if (err < 0)
-               goto err_out_exit;
-
-       t = netfs_trans_alloc(psb, err + 1, 0, 0);
-       if (!t) {
-               err = -ENOMEM;
-               goto err_out_exit;
-       }
-       t->complete = pohmelfs_write_inode_complete;
-       t->private = igrab(inode);
-       if (!t->private) {
-               err = -ENOENT;
-               goto err_out_put;
-       }
-
-       err = pohmelfs_write_inode_create(inode, t);
-       if (err)
-               goto err_out_put;
-
-       netfs_trans_finish(t, POHMELFS_SB(inode->i_sb));
-
-       return 0;
-
-err_out_put:
-       t->result = err;
-       netfs_trans_put(t);
-err_out_exit:
-       return err;
-}
-
-/*
- * Sync all not-yet-created children in given directory to the server.
- */
-static int pohmelfs_write_inode_create_children(struct inode *inode)
-{
-       struct pohmelfs_inode *parent = POHMELFS_I(inode);
-       struct super_block *sb = inode->i_sb;
-       struct pohmelfs_name *n;
-
-       while (!list_empty(&parent->sync_create_list)) {
-               n = NULL;
-               mutex_lock(&parent->offset_lock);
-               if (!list_empty(&parent->sync_create_list)) {
-                       n = list_first_entry(&parent->sync_create_list,
-                               struct pohmelfs_name, sync_create_entry);
-                       list_del_init(&n->sync_create_entry);
-               }
-               mutex_unlock(&parent->offset_lock);
-
-               if (!n)
-                       break;
-
-               inode = ilookup(sb, n->ino);
-
-               dprintk("%s: parent: %llu, ino: %llu, inode: %p.\n",
-                               __func__, parent->ino, n->ino, inode);
-
-               if (inode && (inode->i_state & I_DIRTY)) {
-                       struct pohmelfs_inode *pi = POHMELFS_I(inode);
-                       pohmelfs_write_create_inode(pi);
-                       /* pohmelfs_meta_command(pi, NETFS_INODE_INFO, 0, NULL, NULL, 0); */
-                       iput(inode);
-               }
-       }
-
-       return 0;
-}
-
-/*
- * Removes given child from given inode on server.
- */
-int pohmelfs_remove_child(struct pohmelfs_inode *pi, struct pohmelfs_name *n)
-{
-       return pohmelfs_meta_command_data(pi, pi->ino, NETFS_REMOVE, NULL, 0, NULL, NULL, 0);
-}
-
-/*
- * Writeback for given inode.
- */
-static int pohmelfs_write_inode(struct inode *inode,
-                               struct writeback_control *wbc)
-{
-       struct pohmelfs_inode *pi = POHMELFS_I(inode);
-
-       pohmelfs_write_create_inode(pi);
-       pohmelfs_write_inode_create_children(inode);
-
-       return 0;
-}
-
-/*
- * It is not exported, sorry...
- */
-static inline wait_queue_head_t *page_waitqueue(struct page *page)
-{
-       const struct zone *zone = page_zone(page);
-
-       return &zone->wait_table[hash_ptr(page, zone->wait_table_bits)];
-}
-
-static int pohmelfs_wait_on_page_locked(struct page *page)
-{
-       struct pohmelfs_sb *psb = POHMELFS_SB(page->mapping->host->i_sb);
-       long ret = psb->wait_on_page_timeout;
-       DEFINE_WAIT_BIT(wait, &page->flags, PG_locked);
-       int err = 0;
-
-       if (!PageLocked(page))
-               return 0;
-
-       for (;;) {
-               prepare_to_wait(page_waitqueue(page),
-                               &wait.wait, TASK_INTERRUPTIBLE);
-
-               dprintk("%s: page: %p, locked: %d, uptodate: %d, error: %d, flags: %lx.\n",
-                               __func__, page, PageLocked(page), PageUptodate(page),
-                               PageError(page), page->flags);
-
-               if (!PageLocked(page))
-                       break;
-
-               if (!signal_pending(current)) {
-                       ret = schedule_timeout(ret);
-                       if (!ret)
-                               break;
-                       continue;
-               }
-               ret = -ERESTARTSYS;
-               break;
-       }
-       finish_wait(page_waitqueue(page), &wait.wait);
-
-       if (!ret)
-               err = -ETIMEDOUT;
-
-
-       if (!err)
-               SetPageUptodate(page);
-
-       if (err)
-               printk("%s: page: %p, uptodate: %d, locked: %d, err: %d.\n",
-                       __func__, page, PageUptodate(page), PageLocked(page), err);
-
-       return err;
-}
-
-static int pohmelfs_read_page_complete(struct page **pages, unsigned int page_num,
-               void *private, int err)
-{
-       struct page *page = private;
-
-       if (PageChecked(page))
-               return err;
-
-       if (err < 0) {
-               dprintk("%s: page: %p, err: %d.\n", __func__, page, err);
-               SetPageError(page);
-       }
-
-       unlock_page(page);
-
-       return err;
-}
-
-/*
- * Read a page from remote server.
- * Function will wait until page is unlocked.
- */
-static int pohmelfs_readpage(struct file *file, struct page *page)
-{
-       struct inode *inode = page->mapping->host;
-       struct pohmelfs_sb *psb = POHMELFS_SB(inode->i_sb);
-       struct pohmelfs_inode *pi = POHMELFS_I(inode);
-       struct netfs_trans *t;
-       struct netfs_cmd *cmd;
-       int err, path_len;
-       void *data;
-       u64 isize;
-
-       err = pohmelfs_data_lock(pi, page->index << PAGE_CACHE_SHIFT,
-                       PAGE_SIZE, POHMELFS_READ_LOCK);
-       if (err)
-               goto err_out_exit;
-
-       isize = i_size_read(inode);
-       if (isize <= page->index << PAGE_CACHE_SHIFT) {
-               SetPageUptodate(page);
-               unlock_page(page);
-               return 0;
-       }
-
-       path_len = pohmelfs_path_length(pi);
-       if (path_len < 0) {
-               err = path_len;
-               goto err_out_exit;
-       }
-
-       t = netfs_trans_alloc(psb, path_len, NETFS_TRANS_SINGLE_DST, 0);
-       if (!t) {
-               err = -ENOMEM;
-               goto err_out_exit;
-       }
-
-       t->complete = pohmelfs_read_page_complete;
-       t->private = page;
-
-       cmd = netfs_trans_current(t);
-       data = (void *)(cmd + 1);
-
-       err = pohmelfs_construct_path_string(pi, data, path_len);
-       if (err < 0)
-               goto err_out_free;
-
-       path_len = err;
-
-       cmd->id = pi->ino;
-       cmd->start = page->index;
-       cmd->start <<= PAGE_CACHE_SHIFT;
-       cmd->size = PAGE_CACHE_SIZE + path_len;
-       cmd->cmd = NETFS_READ_PAGE;
-       cmd->ext = path_len;
-
-       dprintk("%s: path: '%s', page: %p, ino: %llu, start: %llu, size: %lu.\n",
-                       __func__, (char *)data, page, pi->ino, cmd->start, PAGE_CACHE_SIZE);
-
-       netfs_convert_cmd(cmd);
-       netfs_trans_update(cmd, t, path_len);
-
-       err = netfs_trans_finish(t, psb);
-       if (err)
-               goto err_out_return;
-
-       return pohmelfs_wait_on_page_locked(page);
-
-err_out_free:
-       t->result = err;
-       netfs_trans_put(t);
-err_out_exit:
-       SetPageError(page);
-       if (PageLocked(page))
-               unlock_page(page);
-err_out_return:
-       printk("%s: page: %p, start: %lu, size: %lu, err: %d.\n",
-               __func__, page, page->index << PAGE_CACHE_SHIFT, PAGE_CACHE_SIZE, err);
-
-       return err;
-}
-
-/*
- * Write begin/end magic.
- * Allocates a page and writes inode if it was not synced to server before.
- */
-static int pohmelfs_write_begin(struct file *file, struct address_space *mapping,
-               loff_t pos, unsigned len, unsigned flags,
-               struct page **pagep, void **fsdata)
-{
-       struct inode *inode = mapping->host;
-       struct page *page;
-       pgoff_t index;
-       unsigned start, end;
-       int err;
-
-       *pagep = NULL;
-
-       index = pos >> PAGE_CACHE_SHIFT;
-       start = pos & (PAGE_CACHE_SIZE - 1);
-       end = start + len;
-
-       page = grab_cache_page(mapping, index);
-#if 0
-       dprintk("%s: page: %p pos: %llu, len: %u, index: %lu, start: %u, end: %u, uptodate: %d.\n",
-                       __func__, page, pos, len, index, start, end, PageUptodate(page));
-#endif
-       if (!page) {
-               err = -ENOMEM;
-               goto err_out_exit;
-       }
-
-       while (!PageUptodate(page)) {
-               if (start && test_bit(NETFS_INODE_REMOTE_SYNCED, &POHMELFS_I(inode)->state)) {
-                       err = pohmelfs_readpage(file, page);
-                       if (err)
-                               goto err_out_exit;
-
-                       lock_page(page);
-                       continue;
-               }
-
-               if (len != PAGE_CACHE_SIZE) {
-                       void *kaddr = kmap_atomic(page, KM_USER0);
-
-                       memset(kaddr + start, 0, PAGE_CACHE_SIZE - start);
-                       flush_dcache_page(page);
-                       kunmap_atomic(kaddr, KM_USER0);
-               }
-               SetPageUptodate(page);
-       }
-
-       set_page_private(page, end);
-
-       *pagep = page;
-
-       return 0;
-
-err_out_exit:
-       page_cache_release(page);
-       *pagep = NULL;
-
-       return err;
-}
-
-static int pohmelfs_write_end(struct file *file, struct address_space *mapping,
-                       loff_t pos, unsigned len, unsigned copied,
-                       struct page *page, void *fsdata)
-{
-       struct inode *inode = mapping->host;
-
-       if (copied != len) {
-               unsigned from = pos & (PAGE_CACHE_SIZE - 1);
-               void *kaddr = kmap_atomic(page, KM_USER0);
-
-               memset(kaddr + from + copied, 0, len - copied);
-               flush_dcache_page(page);
-               kunmap_atomic(kaddr, KM_USER0);
-       }
-
-       SetPageUptodate(page);
-       set_page_dirty(page);
-#if 0
-       dprintk("%s: page: %p [U: %d, D: %d, L: %d], pos: %llu, len: %u, copied: %u.\n",
-                       __func__, page,
-                       PageUptodate(page), PageDirty(page), PageLocked(page),
-                       pos, len, copied);
-#endif
-       flush_dcache_page(page);
-
-       unlock_page(page);
-       page_cache_release(page);
-
-       if (pos + copied > inode->i_size) {
-               struct pohmelfs_sb *psb = POHMELFS_SB(inode->i_sb);
-
-               psb->avail_size -= pos + copied - inode->i_size;
-
-               i_size_write(inode, pos + copied);
-       }
-
-       return copied;
-}
-
-static int pohmelfs_readpages_trans_complete(struct page **__pages, unsigned int page_num,
-               void *private, int err)
-{
-       struct pohmelfs_inode *pi = private;
-       unsigned int i, num;
-       struct page **pages, *page = (struct page *)__pages;
-       loff_t index = page->index;
-
-       pages = kzalloc(sizeof(void *) * page_num, GFP_NOIO);
-       if (!pages)
-               return -ENOMEM;
-
-       num = find_get_pages_contig(pi->vfs_inode.i_mapping, index, page_num, pages);
-       if (num <= 0) {
-               err = num;
-               goto err_out_free;
-       }
-
-       for (i = 0; i < num; ++i) {
-               page = pages[i];
-
-               if (err)
-                       printk("%s: %u/%u: page: %p, index: %lu, uptodate: %d, locked: %d, err: %d.\n",
-                               __func__, i, num, page, page->index,
-                               PageUptodate(page), PageLocked(page), err);
-
-               if (!PageChecked(page)) {
-                       if (err < 0)
-                               SetPageError(page);
-                       unlock_page(page);
-               }
-               page_cache_release(page);
-               page_cache_release(page);
-       }
-
-err_out_free:
-       kfree(pages);
-       return err;
-}
-
-static int pohmelfs_send_readpages(struct pohmelfs_inode *pi, struct page *first, unsigned int num)
-{
-       struct netfs_trans *t;
-       struct netfs_cmd *cmd;
-       struct pohmelfs_sb *psb = POHMELFS_SB(pi->vfs_inode.i_sb);
-       int err, path_len;
-       void *data;
-
-       err = pohmelfs_data_lock(pi, first->index << PAGE_CACHE_SHIFT,
-                       num * PAGE_SIZE, POHMELFS_READ_LOCK);
-       if (err)
-               goto err_out_exit;
-
-       path_len = pohmelfs_path_length(pi);
-       if (path_len < 0) {
-               err = path_len;
-               goto err_out_exit;
-       }
-
-       t = netfs_trans_alloc(psb, path_len, NETFS_TRANS_SINGLE_DST, 0);
-       if (!t) {
-               err = -ENOMEM;
-               goto err_out_exit;
-       }
-
-       cmd = netfs_trans_current(t);
-       data = (void *)(cmd + 1);
-
-       t->complete = pohmelfs_readpages_trans_complete;
-       t->private = pi;
-       t->page_num = num;
-       t->pages = (struct page **)first;
-
-       err = pohmelfs_construct_path_string(pi, data, path_len);
-       if (err < 0)
-               goto err_out_put;
-
-       path_len = err;
-
-       cmd->cmd = NETFS_READ_PAGES;
-       cmd->start = first->index;
-       cmd->start <<= PAGE_CACHE_SHIFT;
-       cmd->size = (num << 8 | PAGE_CACHE_SHIFT);
-       cmd->id = pi->ino;
-       cmd->ext = path_len;
-
-       dprintk("%s: t: %p, gen: %u, path: '%s', path_len: %u, "
-                       "start: %lu, num: %u.\n",
-                       __func__, t, t->gen, (char *)data, path_len,
-                       first->index, num);
-
-       netfs_convert_cmd(cmd);
-       netfs_trans_update(cmd, t, path_len);
-
-       return netfs_trans_finish(t, psb);
-
-err_out_put:
-       netfs_trans_free(t);
-err_out_exit:
-       pohmelfs_readpages_trans_complete((struct page **)first, num, pi, err);
-       return err;
-}
-
-#define list_to_page(head) (list_entry((head)->prev, struct page, lru))
-
-static int pohmelfs_readpages(struct file *file, struct address_space *mapping,
-                       struct list_head *pages, unsigned nr_pages)
-{
-       unsigned int page_idx, num = 0;
-       struct page *page = NULL, *first = NULL;
-
-       for (page_idx = 0; page_idx < nr_pages; page_idx++) {
-               page = list_to_page(pages);
-
-               prefetchw(&page->flags);
-               list_del(&page->lru);
-
-               if (!add_to_page_cache_lru(page, mapping,
-                                       page->index, GFP_KERNEL)) {
-
-                       if (!num) {
-                               num = 1;
-                               first = page;
-                               continue;
-                       }
-
-                       dprintk("%s: added to lru page: %p, page_index: %lu, first_index: %lu.\n",
-                                       __func__, page, page->index, first->index);
-
-                       if (unlikely(first->index + num != page->index) || (num > 500)) {
-                               pohmelfs_send_readpages(POHMELFS_I(mapping->host),
-                                               first, num);
-                               first = page;
-                               num = 0;
-                       }
-
-                       num++;
-               }
-       }
-       pohmelfs_send_readpages(POHMELFS_I(mapping->host), first, num);
-
-       /*
-        * This will be sync read, so when last page is processed,
-        * all previous are alerady unlocked and ready to be used.
-        */
-       return 0;
-}
-
-/*
- * Small address space operations for POHMELFS.
- */
-const struct address_space_operations pohmelfs_aops = {
-       .readpage               = pohmelfs_readpage,
-       .readpages              = pohmelfs_readpages,
-       .writepages             = pohmelfs_writepages,
-       .write_begin            = pohmelfs_write_begin,
-       .write_end              = pohmelfs_write_end,
-       .set_page_dirty         = __set_page_dirty_nobuffers,
-};
-
-static void pohmelfs_i_callback(struct rcu_head *head)
-{
-       struct inode *inode = container_of(head, struct inode, i_rcu);
-       kmem_cache_free(pohmelfs_inode_cache, POHMELFS_I(inode));
-}
-
-/*
- * ->destroy_inode() callback. Deletes inode from the caches
- *  and frees private data.
- */
-static void pohmelfs_destroy_inode(struct inode *inode)
-{
-       struct super_block *sb = inode->i_sb;
-       struct pohmelfs_sb *psb = POHMELFS_SB(sb);
-       struct pohmelfs_inode *pi = POHMELFS_I(inode);
-
-       /* pohmelfs_data_unlock(pi, 0, inode->i_size, POHMELFS_READ_LOCK); */
-
-       pohmelfs_inode_del_inode(psb, pi);
-
-       dprintk("%s: pi: %p, inode: %p, ino: %llu.\n",
-               __func__, pi, &pi->vfs_inode, pi->ino);
-       atomic_long_dec(&psb->total_inodes);
-       call_rcu(&inode->i_rcu, pohmelfs_i_callback);
-}
-
-/*
- * ->alloc_inode() callback. Allocates inode and initializes private data.
- */
-static struct inode *pohmelfs_alloc_inode(struct super_block *sb)
-{
-       struct pohmelfs_inode *pi;
-
-       pi = kmem_cache_alloc(pohmelfs_inode_cache, GFP_NOIO);
-       if (!pi)
-               return NULL;
-
-       pi->hash_root = RB_ROOT;
-       mutex_init(&pi->offset_lock);
-
-       INIT_LIST_HEAD(&pi->sync_create_list);
-
-       INIT_LIST_HEAD(&pi->inode_entry);
-
-       pi->lock_type = 0;
-       pi->state = 0;
-       pi->total_len = 0;
-       pi->drop_count = 0;
-
-       dprintk("%s: pi: %p, inode: %p.\n", __func__, pi, &pi->vfs_inode);
-
-       atomic_long_inc(&POHMELFS_SB(sb)->total_inodes);
-
-       return &pi->vfs_inode;
-}
-
-/*
- * We want fsync() to work on POHMELFS.
- */
-static int pohmelfs_fsync(struct file *file, loff_t start, loff_t end, int datasync)
-{
-       struct inode *inode = file->f_mapping->host;
-       int err = filemap_write_and_wait_range(inode->i_mapping, start, end);
-       if (!err) {
-               mutex_lock(&inode->i_mutex);
-               err = sync_inode_metadata(inode, 1);
-               mutex_unlock(&inode->i_mutex);
-       }
-       return err;
-}
-
-ssize_t pohmelfs_write(struct file *file, const char __user *buf,
-               size_t len, loff_t *ppos)
-{
-       struct address_space *mapping = file->f_mapping;
-       struct inode *inode = mapping->host;
-       struct pohmelfs_inode *pi = POHMELFS_I(inode);
-       struct iovec iov = { .iov_base = (void __user *)buf, .iov_len = len };
-       struct kiocb kiocb;
-       ssize_t ret;
-       loff_t pos = *ppos;
-
-       init_sync_kiocb(&kiocb, file);
-       kiocb.ki_pos = pos;
-       kiocb.ki_left = len;
-
-       dprintk("%s: len: %zu, pos: %llu.\n", __func__, len, pos);
-
-       mutex_lock(&inode->i_mutex);
-       ret = pohmelfs_data_lock(pi, pos, len, POHMELFS_WRITE_LOCK);
-       if (ret)
-               goto err_out_unlock;
-
-       ret = __generic_file_aio_write(&kiocb, &iov, 1, &kiocb.ki_pos);
-       *ppos = kiocb.ki_pos;
-
-       mutex_unlock(&inode->i_mutex);
-       WARN_ON(ret < 0);
-
-       if (ret > 0) {
-               ssize_t err;
-
-               err = generic_write_sync(file, pos, ret);
-               if (err < 0)
-                       ret = err;
-               WARN_ON(ret < 0);
-       }
-
-       return ret;
-
-err_out_unlock:
-       mutex_unlock(&inode->i_mutex);
-       return ret;
-}
-
-static const struct file_operations pohmelfs_file_ops = {
-       .open           = generic_file_open,
-       .fsync          = pohmelfs_fsync,
-
-       .llseek         = generic_file_llseek,
-
-       .read           = do_sync_read,
-       .aio_read       = generic_file_aio_read,
-
-       .mmap           = generic_file_mmap,
-
-       .splice_read    = generic_file_splice_read,
-       .splice_write   = generic_file_splice_write,
-
-       .write          = pohmelfs_write,
-       .aio_write      = generic_file_aio_write,
-};
-
-const struct inode_operations pohmelfs_symlink_inode_operations = {
-       .readlink       = generic_readlink,
-       .follow_link    = page_follow_link_light,
-       .put_link       = page_put_link,
-};
-
-int pohmelfs_setattr_raw(struct inode *inode, struct iattr *attr)
-{
-       int err;
-
-       err = inode_change_ok(inode, attr);
-       if (err) {
-               dprintk("%s: ino: %llu, inode changes are not allowed.\n", __func__, POHMELFS_I(inode)->ino);
-               goto err_out_exit;
-       }
-
-       if ((attr->ia_valid & ATTR_SIZE) &&
-           attr->ia_size != i_size_read(inode)) {
-               err = vmtruncate(inode, attr->ia_size);
-               if (err) {
-                       dprintk("%s: ino: %llu, failed to set the attributes.\n", __func__, POHMELFS_I(inode)->ino);
-                       goto err_out_exit;
-               }
-       }
-
-       setattr_copy(inode, attr);
-       mark_inode_dirty(inode);
-
-       dprintk("%s: ino: %llu, mode: %o -> %o, uid: %u -> %u, gid: %u -> %u, size: %llu -> %llu.\n",
-                       __func__, POHMELFS_I(inode)->ino, inode->i_mode, attr->ia_mode,
-                       inode->i_uid, attr->ia_uid, inode->i_gid, attr->ia_gid, inode->i_size, attr->ia_size);
-
-       return 0;
-
-err_out_exit:
-       return err;
-}
-
-int pohmelfs_setattr(struct dentry *dentry, struct iattr *attr)
-{
-       struct inode *inode = dentry->d_inode;
-       struct pohmelfs_inode *pi = POHMELFS_I(inode);
-       int err;
-
-       err = pohmelfs_data_lock(pi, 0, ~0, POHMELFS_WRITE_LOCK);
-       if (err)
-               goto err_out_exit;
-
-       err = security_inode_setattr(dentry, attr);
-       if (err)
-               goto err_out_exit;
-
-       err = pohmelfs_setattr_raw(inode, attr);
-       if (err)
-               goto err_out_exit;
-
-       return 0;
-
-err_out_exit:
-       return err;
-}
-
-static int pohmelfs_send_xattr_req(struct pohmelfs_inode *pi, u64 id, u64 start,
-               const char *name, const void *value, size_t attrsize, int command)
-{
-       struct pohmelfs_sb *psb = POHMELFS_SB(pi->vfs_inode.i_sb);
-       int err, path_len, namelen = strlen(name) + 1; /* 0-byte */
-       struct netfs_trans *t;
-       struct netfs_cmd *cmd;
-       void *data;
-
-       dprintk("%s: id: %llu, start: %llu, name: '%s', attrsize: %zu, cmd: %d.\n",
-                       __func__, id, start, name, attrsize, command);
-
-       path_len = pohmelfs_path_length(pi);
-       if (path_len < 0) {
-               err = path_len;
-               goto err_out_exit;
-       }
-
-       t = netfs_trans_alloc(psb, namelen + path_len + attrsize, 0, 0);
-       if (!t) {
-               err = -ENOMEM;
-               goto err_out_exit;
-       }
-
-       cmd = netfs_trans_current(t);
-       data = cmd + 1;
-
-       path_len = pohmelfs_construct_path_string(pi, data, path_len);
-       if (path_len < 0) {
-               err = path_len;
-               goto err_out_put;
-       }
-       data += path_len;
-
-       /*
-        * 'name' is a NUL-terminated string already and
-        * 'namelen' includes 0-byte.
-        */
-       memcpy(data, name, namelen);
-       data += namelen;
-
-       memcpy(data, value, attrsize);
-
-       cmd->cmd = command;
-       cmd->id = id;
-       cmd->start = start;
-       cmd->size = attrsize + namelen + path_len;
-       cmd->ext = path_len;
-       cmd->csize = 0;
-       cmd->cpad = 0;
-
-       netfs_convert_cmd(cmd);
-       netfs_trans_update(cmd, t, namelen + path_len + attrsize);
-
-       return netfs_trans_finish(t, psb);
-
-err_out_put:
-       t->result = err;
-       netfs_trans_put(t);
-err_out_exit:
-       return err;
-}
-
-static int pohmelfs_setxattr(struct dentry *dentry, const char *name,
-               const void *value, size_t attrsize, int flags)
-{
-       struct inode *inode = dentry->d_inode;
-       struct pohmelfs_inode *pi = POHMELFS_I(inode);
-       struct pohmelfs_sb *psb = POHMELFS_SB(inode->i_sb);
-
-       if (!(psb->state_flags & POHMELFS_FLAGS_XATTR))
-               return -EOPNOTSUPP;
-
-       return pohmelfs_send_xattr_req(pi, flags, attrsize, name,
-                       value, attrsize, NETFS_XATTR_SET);
-}
-
-static ssize_t pohmelfs_getxattr(struct dentry *dentry, const char *name,
-               void *value, size_t attrsize)
-{
-       struct inode *inode = dentry->d_inode;
-       struct pohmelfs_inode *pi = POHMELFS_I(inode);
-       struct pohmelfs_sb *psb = POHMELFS_SB(inode->i_sb);
-       struct pohmelfs_mcache *m;
-       int err;
-       long timeout = psb->mcache_timeout;
-
-       if (!(psb->state_flags & POHMELFS_FLAGS_XATTR))
-               return -EOPNOTSUPP;
-
-       m = pohmelfs_mcache_alloc(psb, 0, attrsize, value);
-       if (IS_ERR(m))
-               return PTR_ERR(m);
-
-       dprintk("%s: ino: %llu, name: '%s', size: %zu.\n",
-                       __func__, pi->ino, name, attrsize);
-
-       err = pohmelfs_send_xattr_req(pi, m->gen, attrsize, name, value, 0, NETFS_XATTR_GET);
-       if (err)
-               goto err_out_put;
-
-       do {
-               err = wait_for_completion_timeout(&m->complete, timeout);
-               if (err) {
-                       err = m->err;
-                       break;
-               }
-
-               /*
-                * This loop is a bit ugly, since it waits until reference counter
-                * hits 1 and then puts the object here. Main goal is to prevent race with
-                * the network thread, when it can start processing the given request, i.e.
-                * increase its reference counter but yet not complete it, while
-                * we will exit from ->getxattr() with timeout, and although request
-                * will not be freed (its reference counter was increased by network
-                * thread), data pointer provided by user may be released, so we will
-                * overwrite an already freed area in the network thread.
-                *
-                * Now after timeout we remove request from the cache, so it can not be
-                * found by network thread, and wait for its reference counter to hit 1,
-                * i.e. if network thread already started to process this request, we wait
-                * for it to finish, and then free object locally. If reference counter is
-                * already 1, i.e. request is not used by anyone else, we can free it without
-                * problem.
-                */
-               err = -ETIMEDOUT;
-               timeout = HZ;
-
-               pohmelfs_mcache_remove_locked(psb, m);
-       } while (atomic_read(&m->refcnt) != 1);
-
-       pohmelfs_mcache_put(psb, m);
-
-       dprintk("%s: ino: %llu, err: %d.\n", __func__, pi->ino, err);
-
-       return err;
-
-err_out_put:
-       pohmelfs_mcache_put(psb, m);
-       return err;
-}
-
-static int pohmelfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
-{
-       struct inode *inode = dentry->d_inode;
-#if 0
-       struct pohmelfs_inode *pi = POHMELFS_I(inode);
-       int err;
-
-       err = pohmelfs_data_lock(pi, 0, ~0, POHMELFS_READ_LOCK);
-       if (err)
-               return err;
-       dprintk("%s: ino: %llu, mode: %o, uid: %u, gid: %u, size: %llu.\n",
-                       __func__, pi->ino, inode->i_mode, inode->i_uid,
-                       inode->i_gid, inode->i_size);
-#endif
-
-       generic_fillattr(inode, stat);
-       return 0;
-}
-
-const struct inode_operations pohmelfs_file_inode_operations = {
-       .setattr        = pohmelfs_setattr,
-       .getattr        = pohmelfs_getattr,
-       .setxattr       = pohmelfs_setxattr,
-       .getxattr       = pohmelfs_getxattr,
-};
-
-/*
- * Fill inode data: mode, size, operation callbacks and so on...
- */
-void pohmelfs_fill_inode(struct inode *inode, struct netfs_inode_info *info)
-{
-       inode->i_mode = info->mode;
-       set_nlink(inode, info->nlink);
-       inode->i_uid = info->uid;
-       inode->i_gid = info->gid;
-       inode->i_blocks = info->blocks;
-       inode->i_rdev = info->rdev;
-       inode->i_size = info->size;
-       inode->i_version = info->version;
-       inode->i_blkbits = ffs(info->blocksize);
-
-       dprintk("%s: inode: %p, num: %lu/%llu inode is regular: %d, dir: %d, link: %d, mode: %o, size: %llu.\n",
-                       __func__, inode, inode->i_ino, info->ino,
-                       S_ISREG(inode->i_mode), S_ISDIR(inode->i_mode),
-                       S_ISLNK(inode->i_mode), inode->i_mode, inode->i_size);
-
-       inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME_SEC;
-
-       /*
-        * i_mapping is a pointer to i_data during inode initialization.
-        */
-       inode->i_data.a_ops = &pohmelfs_aops;
-
-       if (S_ISREG(inode->i_mode)) {
-               inode->i_fop = &pohmelfs_file_ops;
-               inode->i_op = &pohmelfs_file_inode_operations;
-       } else if (S_ISDIR(inode->i_mode)) {
-               inode->i_fop = &pohmelfs_dir_fops;
-               inode->i_op = &pohmelfs_dir_inode_ops;
-       } else if (S_ISLNK(inode->i_mode)) {
-               inode->i_op = &pohmelfs_symlink_inode_operations;
-               inode->i_fop = &pohmelfs_file_ops;
-       } else {
-               inode->i_fop = &generic_ro_fops;
-       }
-}
-
-static int pohmelfs_drop_inode(struct inode *inode)
-{
-       struct pohmelfs_sb *psb = POHMELFS_SB(inode->i_sb);
-       struct pohmelfs_inode *pi = POHMELFS_I(inode);
-
-       spin_lock(&psb->ino_lock);
-       list_del_init(&pi->inode_entry);
-       spin_unlock(&psb->ino_lock);
-
-       return generic_drop_inode(inode);
-}
-
-static struct pohmelfs_inode *pohmelfs_get_inode_from_list(struct pohmelfs_sb *psb,
-               struct list_head *head, unsigned int *count)
-{
-       struct pohmelfs_inode *pi = NULL;
-
-       spin_lock(&psb->ino_lock);
-       if (!list_empty(head)) {
-               pi = list_entry(head->next, struct pohmelfs_inode,
-                                       inode_entry);
-               list_del_init(&pi->inode_entry);
-               *count = pi->drop_count;
-               pi->drop_count = 0;
-       }
-       spin_unlock(&psb->ino_lock);
-
-       return pi;
-}
-
-static void pohmelfs_flush_transactions(struct pohmelfs_sb *psb)
-{
-       struct pohmelfs_config *c;
-
-       mutex_lock(&psb->state_lock);
-       list_for_each_entry(c, &psb->state_list, config_entry) {
-               pohmelfs_state_flush_transactions(&c->state);
-       }
-       mutex_unlock(&psb->state_lock);
-}
-
-/*
- * ->put_super() callback. Invoked before superblock is destroyed,
- *  so it has to clean all private data.
- */
-static void pohmelfs_put_super(struct super_block *sb)
-{
-       struct pohmelfs_sb *psb = POHMELFS_SB(sb);
-       struct pohmelfs_inode *pi;
-       unsigned int count = 0;
-       unsigned int in_drop_list = 0;
-       struct inode *inode, *tmp;
-
-       dprintk("%s.\n", __func__);
-
-       /*
-        * Kill pending transactions, which could affect inodes in-flight.
-        */
-       pohmelfs_flush_transactions(psb);
-
-       while ((pi = pohmelfs_get_inode_from_list(psb, &psb->drop_list, &count))) {
-               inode = &pi->vfs_inode;
-
-               dprintk("%s: ino: %llu, pi: %p, inode: %p, count: %u.\n",
-                               __func__, pi->ino, pi, inode, count);
-
-               if (atomic_read(&inode->i_count) != count) {
-                       printk("%s: ino: %llu, pi: %p, inode: %p, count: %u, i_count: %d.\n",
-                                       __func__, pi->ino, pi, inode, count,
-                                       atomic_read(&inode->i_count));
-                       count = atomic_read(&inode->i_count);
-                       in_drop_list++;
-               }
-
-               while (count--)
-                       iput(&pi->vfs_inode);
-       }
-
-       list_for_each_entry_safe(inode, tmp, &sb->s_inodes, i_sb_list) {
-               pi = POHMELFS_I(inode);
-
-               dprintk("%s: ino: %llu, pi: %p, inode: %p, i_count: %u.\n",
-                               __func__, pi->ino, pi, inode, atomic_read(&inode->i_count));
-
-               /*
-                * These are special inodes, they were created during
-                * directory reading or lookup, and were not bound to dentry,
-                * so they live here with reference counter being 1 and prevent
-                * umount from succeed since it believes that they are busy.
-                */
-               count = atomic_read(&inode->i_count);
-               if (count) {
-                       list_del_init(&inode->i_sb_list);
-                       while (count--)
-                               iput(&pi->vfs_inode);
-               }
-       }
-
-       psb->trans_scan_timeout = psb->drop_scan_timeout = 0;
-       cancel_delayed_work_sync(&psb->dwork);
-       cancel_delayed_work_sync(&psb->drop_dwork);
-       flush_scheduled_work();
-
-       dprintk("%s: stopped workqueues.\n", __func__);
-
-       pohmelfs_crypto_exit(psb);
-       pohmelfs_state_exit(psb);
-
-       bdi_destroy(&psb->bdi);
-
-       kfree(psb);
-       sb->s_fs_info = NULL;
-}
-
-static int pohmelfs_statfs(struct dentry *dentry, struct kstatfs *buf)
-{
-       struct super_block *sb = dentry->d_sb;
-       struct pohmelfs_sb *psb = POHMELFS_SB(sb);
-
-       /*
-        * There are no filesystem size limits yet.
-        */
-       memset(buf, 0, sizeof(struct kstatfs));
-
-       buf->f_type = POHMELFS_MAGIC_NUM; /* 'POH.' */
-       buf->f_bsize = sb->s_blocksize;
-       buf->f_files = psb->ino;
-       buf->f_namelen = 255;
-       buf->f_files = atomic_long_read(&psb->total_inodes);
-       buf->f_bfree = buf->f_bavail = psb->avail_size >> PAGE_SHIFT;
-       buf->f_blocks = psb->total_size >> PAGE_SHIFT;
-
-       dprintk("%s: total: %llu, avail: %llu, inodes: %llu, bsize: %lu.\n",
-               __func__, psb->total_size, psb->avail_size, buf->f_files, sb->s_blocksize);
-
-       return 0;
-}
-
-static int pohmelfs_show_options(struct seq_file *seq, struct dentry *root)
-{
-       struct pohmelfs_sb *psb = POHMELFS_SB(root->d_sb);
-
-       seq_printf(seq, ",idx=%u", psb->idx);
-       seq_printf(seq, ",trans_scan_timeout=%u", jiffies_to_msecs(psb->trans_scan_timeout));
-       seq_printf(seq, ",drop_scan_timeout=%u", jiffies_to_msecs(psb->drop_scan_timeout));
-       seq_printf(seq, ",wait_on_page_timeout=%u", jiffies_to_msecs(psb->wait_on_page_timeout));
-       seq_printf(seq, ",trans_retries=%u", psb->trans_retries);
-       seq_printf(seq, ",crypto_thread_num=%u", psb->crypto_thread_num);
-       seq_printf(seq, ",trans_max_pages=%u", psb->trans_max_pages);
-       seq_printf(seq, ",mcache_timeout=%u", jiffies_to_msecs(psb->mcache_timeout));
-       if (psb->crypto_fail_unsupported)
-               seq_printf(seq, ",crypto_fail_unsupported");
-
-       return 0;
-}
-
-enum {
-       pohmelfs_opt_idx,
-       pohmelfs_opt_crypto_thread_num,
-       pohmelfs_opt_trans_max_pages,
-       pohmelfs_opt_crypto_fail_unsupported,
-
-       /* Remountable options */
-       pohmelfs_opt_trans_scan_timeout,
-       pohmelfs_opt_drop_scan_timeout,
-       pohmelfs_opt_wait_on_page_timeout,
-       pohmelfs_opt_trans_retries,
-       pohmelfs_opt_mcache_timeout,
-};
-
-static struct match_token pohmelfs_tokens[] = {
-       {pohmelfs_opt_idx, "idx=%u"},
-       {pohmelfs_opt_crypto_thread_num, "crypto_thread_num=%u"},
-       {pohmelfs_opt_trans_max_pages, "trans_max_pages=%u"},
-       {pohmelfs_opt_crypto_fail_unsupported, "crypto_fail_unsupported"},
-       {pohmelfs_opt_trans_scan_timeout, "trans_scan_timeout=%u"},
-       {pohmelfs_opt_drop_scan_timeout, "drop_scan_timeout=%u"},
-       {pohmelfs_opt_wait_on_page_timeout, "wait_on_page_timeout=%u"},
-       {pohmelfs_opt_trans_retries, "trans_retries=%u"},
-       {pohmelfs_opt_mcache_timeout, "mcache_timeout=%u"},
-};
-
-static int pohmelfs_parse_options(char *options, struct pohmelfs_sb *psb, int remount)
-{
-       char *p;
-       substring_t args[MAX_OPT_ARGS];
-       int option, err;
-
-       if (!options)
-               return 0;
-
-       while ((p = strsep(&options, ",")) != NULL) {
-               int token;
-               if (!*p)
-                       continue;
-
-               token = match_token(p, pohmelfs_tokens, args);
-
-               err = match_int(&args[0], &option);
-               if (err)
-                       return err;
-
-               if (remount && token <= pohmelfs_opt_crypto_fail_unsupported)
-                       continue;
-
-               switch (token) {
-               case pohmelfs_opt_idx:
-                       psb->idx = option;
-                       break;
-               case pohmelfs_opt_trans_scan_timeout:
-                       psb->trans_scan_timeout = msecs_to_jiffies(option);
-                       break;
-               case pohmelfs_opt_drop_scan_timeout:
-                       psb->drop_scan_timeout = msecs_to_jiffies(option);
-                       break;
-               case pohmelfs_opt_wait_on_page_timeout:
-                       psb->wait_on_page_timeout = msecs_to_jiffies(option);
-                       break;
-               case pohmelfs_opt_mcache_timeout:
-                       psb->mcache_timeout = msecs_to_jiffies(option);
-                       break;
-               case pohmelfs_opt_trans_retries:
-                       psb->trans_retries = option;
-                       break;
-               case pohmelfs_opt_crypto_thread_num:
-                       psb->crypto_thread_num = option;
-                       break;
-               case pohmelfs_opt_trans_max_pages:
-                       psb->trans_max_pages = option;
-                       break;
-               case pohmelfs_opt_crypto_fail_unsupported:
-                       psb->crypto_fail_unsupported = 1;
-                       break;
-               default:
-                       return -EINVAL;
-               }
-       }
-
-       return 0;
-}
-
-static int pohmelfs_remount(struct super_block *sb, int *flags, char *data)
-{
-       int err;
-       struct pohmelfs_sb *psb = POHMELFS_SB(sb);
-       unsigned long old_sb_flags = sb->s_flags;
-
-       err = pohmelfs_parse_options(data, psb, 1);
-       if (err)
-               goto err_out_restore;
-
-       if (!(*flags & MS_RDONLY))
-               sb->s_flags &= ~MS_RDONLY;
-       return 0;
-
-err_out_restore:
-       sb->s_flags = old_sb_flags;
-       return err;
-}
-
-static void pohmelfs_flush_inode(struct pohmelfs_inode *pi, unsigned int count)
-{
-       struct inode *inode = &pi->vfs_inode;
-
-       dprintk("%s: %p: ino: %llu, owned: %d.\n",
-               __func__, inode, pi->ino, test_bit(NETFS_INODE_OWNED, &pi->state));
-
-       mutex_lock(&inode->i_mutex);
-       if (test_and_clear_bit(NETFS_INODE_OWNED, &pi->state)) {
-               filemap_fdatawrite(inode->i_mapping);
-               inode->i_sb->s_op->write_inode(inode, 0);
-       }
-
-#ifdef POHMELFS_TRUNCATE_ON_INODE_FLUSH
-       truncate_inode_pages(inode->i_mapping, 0);
-#endif
-
-       pohmelfs_data_unlock(pi, 0, ~0, POHMELFS_WRITE_LOCK);
-       mutex_unlock(&inode->i_mutex);
-}
-
-static void pohmelfs_put_inode_count(struct pohmelfs_inode *pi, unsigned int count)
-{
-       dprintk("%s: ino: %llu, pi: %p, inode: %p, count: %u.\n",
-                       __func__, pi->ino, pi, &pi->vfs_inode, count);
-
-       if (test_and_clear_bit(NETFS_INODE_NEED_FLUSH, &pi->state))
-               pohmelfs_flush_inode(pi, count);
-
-       while (count--)
-               iput(&pi->vfs_inode);
-}
-
-static void pohmelfs_drop_scan(struct work_struct *work)
-{
-       struct pohmelfs_sb *psb =
-               container_of(work, struct pohmelfs_sb, drop_dwork.work);
-       struct pohmelfs_inode *pi;
-       unsigned int count = 0;
-
-       while ((pi = pohmelfs_get_inode_from_list(psb, &psb->drop_list, &count)))
-               pohmelfs_put_inode_count(pi, count);
-
-       pohmelfs_check_states(psb);
-
-       if (psb->drop_scan_timeout)
-               schedule_delayed_work(&psb->drop_dwork, psb->drop_scan_timeout);
-}
-
-/*
- * Run through all transactions starting from the oldest,
- * drop transaction from current state and try to send it
- * to all remote nodes, which are currently installed.
- */
-static void pohmelfs_trans_scan_state(struct netfs_state *st)
-{
-       struct rb_node *rb_node;
-       struct netfs_trans_dst *dst;
-       struct pohmelfs_sb *psb = st->psb;
-       unsigned int timeout = psb->trans_scan_timeout;
-       struct netfs_trans *t;
-       int err;
-
-       mutex_lock(&st->trans_lock);
-       for (rb_node = rb_first(&st->trans_root); rb_node; ) {
-               dst = rb_entry(rb_node, struct netfs_trans_dst, state_entry);
-               t = dst->trans;
-
-               if (timeout && time_after(dst->send_time + timeout, jiffies)
-                               && dst->retries == 0)
-                       break;
-
-               dprintk("%s: t: %p, gen: %u, st: %p, retries: %u, max: %u.\n",
-                       __func__, t, t->gen, st, dst->retries, psb->trans_retries);
-               netfs_trans_get(t);
-
-               rb_node = rb_next(rb_node);
-
-               err = -ETIMEDOUT;
-               if (timeout && (++dst->retries < psb->trans_retries))
-                       err = netfs_trans_resend(t, psb);
-
-               if (err || (t->flags & NETFS_TRANS_SINGLE_DST)) {
-                       if (netfs_trans_remove_nolock(dst, st))
-                               netfs_trans_drop_dst_nostate(dst);
-               }
-
-               t->result = err;
-               netfs_trans_put(t);
-       }
-       mutex_unlock(&st->trans_lock);
-}
-
-/*
- * Walk through all installed network states and resend all
- * transactions, which are old enough.
- */
-static void pohmelfs_trans_scan(struct work_struct *work)
-{
-       struct pohmelfs_sb *psb =
-               container_of(work, struct pohmelfs_sb, dwork.work);
-       struct netfs_state *st;
-       struct pohmelfs_config *c;
-
-       mutex_lock(&psb->state_lock);
-       list_for_each_entry(c, &psb->state_list, config_entry) {
-               st = &c->state;
-
-               pohmelfs_trans_scan_state(st);
-       }
-       mutex_unlock(&psb->state_lock);
-
-       /*
-        * If no timeout specified then system is in the middle of umount process,
-        * so no need to reschedule scanning process again.
-        */
-       if (psb->trans_scan_timeout)
-               schedule_delayed_work(&psb->dwork, psb->trans_scan_timeout);
-}
-
-int pohmelfs_meta_command_data(struct pohmelfs_inode *pi, u64 id, unsigned int cmd_op, char *addon,
-               unsigned int flags, netfs_trans_complete_t complete, void *priv, u64 start)
-{
-       struct inode *inode = &pi->vfs_inode;
-       struct pohmelfs_sb *psb = POHMELFS_SB(inode->i_sb);
-       int err = 0, sz;
-       struct netfs_trans *t;
-       int path_len, addon_len = 0;
-       void *data;
-       struct netfs_inode_info *info;
-       struct netfs_cmd *cmd;
-
-       dprintk("%s: ino: %llu, cmd: %u, addon: %p.\n", __func__, pi->ino, cmd_op, addon);
-
-       path_len = pohmelfs_path_length(pi);
-       if (path_len < 0) {
-               err = path_len;
-               goto err_out_exit;
-       }
-
-       if (addon)
-               addon_len = strlen(addon) + 1; /* 0-byte */
-       sz = addon_len;
-
-       if (cmd_op == NETFS_INODE_INFO)
-               sz += sizeof(struct netfs_inode_info);
-
-       t = netfs_trans_alloc(psb, sz + path_len, flags, 0);
-       if (!t) {
-               err = -ENOMEM;
-               goto err_out_exit;
-       }
-       t->complete = complete;
-       t->private = priv;
-
-       cmd = netfs_trans_current(t);
-       data = (void *)(cmd + 1);
-
-       if (cmd_op == NETFS_INODE_INFO) {
-               info = (struct netfs_inode_info *)(cmd + 1);
-               data = (void *)(info + 1);
-
-               /*
-                * We are under i_mutex, can read and change whatever we want...
-                */
-               info->mode = inode->i_mode;
-               info->nlink = inode->i_nlink;
-               info->uid = inode->i_uid;
-               info->gid = inode->i_gid;
-               info->blocks = inode->i_blocks;
-               info->rdev = inode->i_rdev;
-               info->size = inode->i_size;
-               info->version = inode->i_version;
-
-               netfs_convert_inode_info(info);
-       }
-
-       path_len = pohmelfs_construct_path_string(pi, data, path_len);
-       if (path_len < 0)
-               goto err_out_free;
-
-       dprintk("%s: path_len: %d.\n", __func__, path_len);
-
-       if (addon) {
-               path_len--; /* Do not place null-byte before the addon */
-               path_len += sprintf(data + path_len, "/%s", addon) + 1; /* 0 - byte */
-       }
-
-       sz += path_len;
-
-       cmd->cmd = cmd_op;
-       cmd->ext = path_len;
-       cmd->size = sz;
-       cmd->id = id;
-       cmd->start = start;
-
-       netfs_convert_cmd(cmd);
-       netfs_trans_update(cmd, t, sz);
-
-       /*
-        * Note, that it is possible to leak error here: transaction callback will not
-        * be invoked for allocation path failure.
-        */
-       return netfs_trans_finish(t, psb);
-
-err_out_free:
-       netfs_trans_free(t);
-err_out_exit:
-       if (complete)
-               complete(NULL, 0, priv, err);
-       return err;
-}
-
-int pohmelfs_meta_command(struct pohmelfs_inode *pi, unsigned int cmd_op, unsigned int flags,
-               netfs_trans_complete_t complete, void *priv, u64 start)
-{
-       return pohmelfs_meta_command_data(pi, pi->ino, cmd_op, NULL, flags, complete, priv, start);
-}
-
-/*
- * Send request and wait for POHMELFS root capabilities response,
- * which will update server's informaion about size of the export,
- * permissions, number of objects, available size and so on.
- */
-static int pohmelfs_root_handshake(struct pohmelfs_sb *psb)
-{
-       struct netfs_trans *t;
-       struct netfs_cmd *cmd;
-       int err = -ENOMEM;
-
-       t = netfs_trans_alloc(psb, 0, 0, 0);
-       if (!t)
-               goto err_out_exit;
-
-       cmd = netfs_trans_current(t);
-
-       cmd->cmd = NETFS_CAPABILITIES;
-       cmd->id = POHMELFS_ROOT_CAPABILITIES;
-       cmd->size = 0;
-       cmd->start = 0;
-       cmd->ext = 0;
-       cmd->csize = 0;
-
-       netfs_convert_cmd(cmd);
-       netfs_trans_update(cmd, t, 0);
-
-       err = netfs_trans_finish(t, psb);
-       if (err)
-               goto err_out_exit;
-
-       psb->flags = ~0;
-       err = wait_event_interruptible_timeout(psb->wait,
-                       (psb->flags != ~0),
-                       psb->wait_on_page_timeout);
-       if (!err)
-               err = -ETIMEDOUT;
-       else if (err > 0)
-               err = -psb->flags;
-
-       if (err)
-               goto err_out_exit;
-
-       return 0;
-
-err_out_exit:
-       return err;
-}
-
-static int pohmelfs_show_stats(struct seq_file *m, struct dentry *root)
-{
-       struct netfs_state *st;
-       struct pohmelfs_ctl *ctl;
-       struct pohmelfs_sb *psb = POHMELFS_SB(root->d_sb);
-       struct pohmelfs_config *c;
-
-       mutex_lock(&psb->state_lock);
-
-       seq_printf(m, "\nidx addr(:port) socket_type protocol active priority permissions\n");
-
-       list_for_each_entry(c, &psb->state_list, config_entry) {
-               st = &c->state;
-               ctl = &st->ctl;
-
-               seq_printf(m, "%u ", ctl->idx);
-               if (ctl->addr.sa_family == AF_INET) {
-                       struct sockaddr_in *sin = (struct sockaddr_in *)&st->ctl.addr;
-                       seq_printf(m, "%pI4:%u", &sin->sin_addr.s_addr, ntohs(sin->sin_port));
-               } else if (ctl->addr.sa_family == AF_INET6) {
-                       struct sockaddr_in6 *sin = (struct sockaddr_in6 *)&st->ctl.addr;
-                       seq_printf(m, "%pi6:%u", &sin->sin6_addr, ntohs(sin->sin6_port));
-               } else {
-                       unsigned int i;
-                       for (i = 0; i < ctl->addrlen; ++i)
-                               seq_printf(m, "%02x.", ctl->addr.addr[i]);
-               }
-
-               seq_printf(m, " %u %u %d %u %x\n",
-                               ctl->type, ctl->proto,
-                               st->socket != NULL,
-                               ctl->prio, ctl->perm);
-       }
-       mutex_unlock(&psb->state_lock);
-
-       return 0;
-}
-
-static const struct super_operations pohmelfs_sb_ops = {
-       .alloc_inode    = pohmelfs_alloc_inode,
-       .destroy_inode  = pohmelfs_destroy_inode,
-       .drop_inode     = pohmelfs_drop_inode,
-       .write_inode    = pohmelfs_write_inode,
-       .put_super      = pohmelfs_put_super,
-       .remount_fs     = pohmelfs_remount,
-       .statfs         = pohmelfs_statfs,
-       .show_options   = pohmelfs_show_options,
-       .show_stats     = pohmelfs_show_stats,
-};
-
-/*
- * Allocate private superblock and create root dir.
- */
-static int pohmelfs_fill_super(struct super_block *sb, void *data, int silent)
-{
-       struct pohmelfs_sb *psb;
-       int err = -ENOMEM;
-       struct inode *root;
-       struct pohmelfs_inode *npi;
-       struct qstr str;
-
-       psb = kzalloc(sizeof(struct pohmelfs_sb), GFP_KERNEL);
-       if (!psb)
-               goto err_out_exit;
-
-       err = bdi_init(&psb->bdi);
-       if (err)
-               goto err_out_free_sb;
-
-       err = bdi_register(&psb->bdi, NULL, "pfs-%d", atomic_inc_return(&psb_bdi_num));
-       if (err) {
-               bdi_destroy(&psb->bdi);
-               goto err_out_free_sb;
-       }
-
-       sb->s_fs_info = psb;
-       sb->s_op = &pohmelfs_sb_ops;
-       sb->s_magic = POHMELFS_MAGIC_NUM;
-       sb->s_maxbytes = MAX_LFS_FILESIZE;
-       sb->s_blocksize = PAGE_SIZE;
-       sb->s_bdi = &psb->bdi;
-
-       psb->sb = sb;
-
-       psb->ino = 2;
-       psb->idx = 0;
-       psb->active_state = NULL;
-       psb->trans_retries = 5;
-       psb->trans_data_size = PAGE_SIZE;
-       psb->drop_scan_timeout = msecs_to_jiffies(1000);
-       psb->trans_scan_timeout = msecs_to_jiffies(5000);
-       psb->wait_on_page_timeout = msecs_to_jiffies(5000);
-       init_waitqueue_head(&psb->wait);
-
-       spin_lock_init(&psb->ino_lock);
-
-       INIT_LIST_HEAD(&psb->drop_list);
-
-       mutex_init(&psb->mcache_lock);
-       psb->mcache_root = RB_ROOT;
-       psb->mcache_timeout = msecs_to_jiffies(5000);
-       atomic_long_set(&psb->mcache_gen, 0);
-
-       psb->trans_max_pages = 100;
-
-       psb->crypto_align_size = 16;
-       psb->crypto_attached_size = 0;
-       psb->hash_strlen = 0;
-       psb->cipher_strlen = 0;
-       psb->perform_crypto = 0;
-       psb->crypto_thread_num = 2;
-       psb->crypto_fail_unsupported = 0;
-       mutex_init(&psb->crypto_thread_lock);
-       INIT_LIST_HEAD(&psb->crypto_ready_list);
-       INIT_LIST_HEAD(&psb->crypto_active_list);
-
-       atomic_set(&psb->trans_gen, 1);
-       atomic_long_set(&psb->total_inodes, 0);
-
-       mutex_init(&psb->state_lock);
-       INIT_LIST_HEAD(&psb->state_list);
-
-       err = pohmelfs_parse_options((char *) data, psb, 0);
-       if (err)
-               goto err_out_free_bdi;
-
-       err = pohmelfs_copy_crypto(psb);
-       if (err)
-               goto err_out_free_bdi;
-
-       err = pohmelfs_state_init(psb);
-       if (err)
-               goto err_out_free_strings;
-
-       err = pohmelfs_crypto_init(psb);
-       if (err)
-               goto err_out_state_exit;
-
-       err = pohmelfs_root_handshake(psb);
-       if (err)
-               goto err_out_crypto_exit;
-
-       str.name = "/";
-       str.hash = jhash("/", 1, 0);
-       str.len = 1;
-
-       npi = pohmelfs_create_entry_local(psb, NULL, &str, 0, 0755|S_IFDIR);
-       if (IS_ERR(npi)) {
-               err = PTR_ERR(npi);
-               goto err_out_crypto_exit;
-       }
-       set_bit(NETFS_INODE_REMOTE_SYNCED, &npi->state);
-       clear_bit(NETFS_INODE_OWNED, &npi->state);
-
-       root = &npi->vfs_inode;
-
-       sb->s_root = d_alloc_root(root);
-       if (!sb->s_root)
-               goto err_out_put_root;
-
-       INIT_DELAYED_WORK(&psb->drop_dwork, pohmelfs_drop_scan);
-       schedule_delayed_work(&psb->drop_dwork, psb->drop_scan_timeout);
-
-       INIT_DELAYED_WORK(&psb->dwork, pohmelfs_trans_scan);
-       schedule_delayed_work(&psb->dwork, psb->trans_scan_timeout);
-
-       return 0;
-
-err_out_put_root:
-       iput(root);
-err_out_crypto_exit:
-       pohmelfs_crypto_exit(psb);
-err_out_state_exit:
-       pohmelfs_state_exit(psb);
-err_out_free_strings:
-       kfree(psb->cipher_string);
-       kfree(psb->hash_string);
-err_out_free_bdi:
-       bdi_destroy(&psb->bdi);
-err_out_free_sb:
-       kfree(psb);
-err_out_exit:
-
-       dprintk("%s: err: %d.\n", __func__, err);
-       return err;
-}
-
-/*
- * Some VFS magic here...
- */
-static struct dentry *pohmelfs_mount(struct file_system_type *fs_type,
-       int flags, const char *dev_name, void *data)
-{
-       return mount_nodev(fs_type, flags, data, pohmelfs_fill_super);
-}
-
-/*
- * We need this to sync all inodes earlier, since when writeback
- * is invoked from the umount/mntput path dcache is already shrunk,
- * see generic_shutdown_super(), and no inodes can access the path.
- */
-static void pohmelfs_kill_super(struct super_block *sb)
-{
-       sync_inodes_sb(sb);
-       kill_anon_super(sb);
-}
-
-static struct file_system_type pohmel_fs_type = {
-       .owner          = THIS_MODULE,
-       .name           = "pohmel",
-       .mount          = pohmelfs_mount,
-       .kill_sb        = pohmelfs_kill_super,
-};
-
-/*
- * Cache and module initializations and freeing routings.
- */
-static void pohmelfs_init_once(void *data)
-{
-       struct pohmelfs_inode *pi = data;
-
-       inode_init_once(&pi->vfs_inode);
-}
-
-static int __init pohmelfs_init_inodecache(void)
-{
-       pohmelfs_inode_cache = kmem_cache_create("pohmelfs_inode_cache",
-                               sizeof(struct pohmelfs_inode),
-                               0, (SLAB_RECLAIM_ACCOUNT|SLAB_MEM_SPREAD),
-                               pohmelfs_init_once);
-       if (!pohmelfs_inode_cache)
-               return -ENOMEM;
-
-       return 0;
-}
-
-static void pohmelfs_destroy_inodecache(void)
-{
-       kmem_cache_destroy(pohmelfs_inode_cache);
-}
-
-static int __init init_pohmel_fs(void)
-{
-       int err;
-
-       err = pohmelfs_config_init();
-       if (err)
-               goto err_out_exit;
-
-       err = pohmelfs_init_inodecache();
-       if (err)
-               goto err_out_config_exit;
-
-       err = pohmelfs_mcache_init();
-       if (err)
-               goto err_out_destroy;
-
-       err = netfs_trans_init();
-       if (err)
-               goto err_out_mcache_exit;
-
-       err = register_filesystem(&pohmel_fs_type);
-       if (err)
-               goto err_out_trans;
-
-       return 0;
-
-err_out_trans:
-       netfs_trans_exit();
-err_out_mcache_exit:
-       pohmelfs_mcache_exit();
-err_out_destroy:
-       pohmelfs_destroy_inodecache();
-err_out_config_exit:
-       pohmelfs_config_exit();
-err_out_exit:
-       return err;
-}
-
-static void __exit exit_pohmel_fs(void)
-{
-       unregister_filesystem(&pohmel_fs_type);
-       pohmelfs_destroy_inodecache();
-       pohmelfs_mcache_exit();
-       pohmelfs_config_exit();
-       netfs_trans_exit();
-}
-
-module_init(init_pohmel_fs);
-module_exit(exit_pohmel_fs);
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Evgeniy Polyakov <zbr@ioremap.net>");
-MODULE_DESCRIPTION("Pohmel filesystem");
diff --git a/drivers/staging/pohmelfs/lock.c b/drivers/staging/pohmelfs/lock.c
deleted file mode 100644 (file)
index 6710114..0000000
+++ /dev/null
@@ -1,182 +0,0 @@
-/*
- * 2007+ Copyright (c) Evgeniy Polyakov <zbr@ioremap.net>
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- */
-
-#include <linux/module.h>
-#include <linux/backing-dev.h>
-#include <linux/fs.h>
-#include <linux/fsnotify.h>
-#include <linux/mempool.h>
-
-#include "netfs.h"
-
-static int pohmelfs_send_lock_trans(struct pohmelfs_inode *pi,
-               u64 id, u64 start, u32 size, int type)
-{
-       struct inode *inode = &pi->vfs_inode;
-       struct pohmelfs_sb *psb = POHMELFS_SB(inode->i_sb);
-       struct netfs_trans *t;
-       struct netfs_cmd *cmd;
-       int path_len, err;
-       void *data;
-       struct netfs_lock *l;
-       int isize = (type & POHMELFS_LOCK_GRAB) ? 0 : sizeof(struct netfs_inode_info);
-
-       err = pohmelfs_path_length(pi);
-       if (err < 0)
-               goto err_out_exit;
-
-       path_len = err;
-
-       err = -ENOMEM;
-       t = netfs_trans_alloc(psb, path_len + sizeof(struct netfs_lock) + isize,
-                       NETFS_TRANS_SINGLE_DST, 0);
-       if (!t)
-               goto err_out_exit;
-
-       cmd = netfs_trans_current(t);
-       data = cmd + 1;
-
-       err = pohmelfs_construct_path_string(pi, data, path_len);
-       if (err < 0)
-               goto err_out_free;
-       path_len = err;
-
-       l = data + path_len;
-
-       l->start = start;
-       l->size = size;
-       l->type = type;
-       l->ino = pi->ino;
-
-       cmd->cmd = NETFS_LOCK;
-       cmd->start = 0;
-       cmd->id = id;
-       cmd->size = sizeof(struct netfs_lock) + path_len + isize;
-       cmd->ext = path_len;
-       cmd->csize = 0;
-
-       netfs_convert_cmd(cmd);
-       netfs_convert_lock(l);
-
-       if (isize) {
-               struct netfs_inode_info *info = (struct netfs_inode_info *)(l + 1);
-
-               info->mode = inode->i_mode;
-               info->nlink = inode->i_nlink;
-               info->uid = inode->i_uid;
-               info->gid = inode->i_gid;
-               info->blocks = inode->i_blocks;
-               info->rdev = inode->i_rdev;
-               info->size = inode->i_size;
-               info->version = inode->i_version;
-
-               netfs_convert_inode_info(info);
-       }
-
-       netfs_trans_update(cmd, t, path_len + sizeof(struct netfs_lock) + isize);
-
-       return netfs_trans_finish(t, psb);
-
-err_out_free:
-       netfs_trans_free(t);
-err_out_exit:
-       printk("%s: err: %d.\n", __func__, err);
-       return err;
-}
-
-int pohmelfs_data_lock(struct pohmelfs_inode *pi, u64 start, u32 size, int type)
-{
-       struct pohmelfs_sb *psb = POHMELFS_SB(pi->vfs_inode.i_sb);
-       struct pohmelfs_mcache *m;
-       int err = -ENOMEM;
-       struct iattr iattr;
-       struct inode *inode = &pi->vfs_inode;
-
-       dprintk("%s: %p: ino: %llu, start: %llu, size: %u, "
-                       "type: %d, locked as: %d, owned: %d.\n",
-                       __func__, &pi->vfs_inode, pi->ino,
-                       start, size, type, pi->lock_type,
-                       !!test_bit(NETFS_INODE_OWNED, &pi->state));
-
-       if (!pohmelfs_need_lock(pi, type))
-               return 0;
-
-       m = pohmelfs_mcache_alloc(psb, start, size, NULL);
-       if (IS_ERR(m))
-               return PTR_ERR(m);
-
-       err = pohmelfs_send_lock_trans(pi, m->gen, start, size,
-                       type | POHMELFS_LOCK_GRAB);
-       if (err)
-               goto err_out_put;
-
-       err = wait_for_completion_timeout(&m->complete, psb->mcache_timeout);
-       if (err)
-               err = m->err;
-       else
-               err = -ETIMEDOUT;
-
-       if (err) {
-               printk("%s: %p: ino: %llu, mgen: %llu, start: %llu, size: %u, err: %d.\n",
-                       __func__, &pi->vfs_inode, pi->ino, m->gen, start, size, err);
-       }
-
-       if (err && (err != -ENOENT))
-               goto err_out_put;
-
-       if (!err) {
-               netfs_convert_inode_info(&m->info);
-
-               iattr.ia_valid = ATTR_MODE | ATTR_UID | ATTR_GID | ATTR_SIZE | ATTR_ATIME;
-               iattr.ia_mode = m->info.mode;
-               iattr.ia_uid = m->info.uid;
-               iattr.ia_gid = m->info.gid;
-               iattr.ia_size = m->info.size;
-               iattr.ia_atime = CURRENT_TIME;
-
-               dprintk("%s: %p: ino: %llu, mgen: %llu, start: %llu, isize: %llu -> %llu.\n",
-                       __func__, &pi->vfs_inode, pi->ino, m->gen, start, inode->i_size, m->info.size);
-
-               err = pohmelfs_setattr_raw(inode, &iattr);
-               if (!err) {
-                       struct dentry *dentry = d_find_alias(inode);
-                       if (dentry) {
-                               fsnotify_change(dentry, iattr.ia_valid);
-                               dput(dentry);
-                       }
-               }
-       }
-
-       pi->lock_type = type;
-       set_bit(NETFS_INODE_OWNED, &pi->state);
-
-       pohmelfs_mcache_put(psb, m);
-
-       return 0;
-
-err_out_put:
-       pohmelfs_mcache_put(psb, m);
-       return err;
-}
-
-int pohmelfs_data_unlock(struct pohmelfs_inode *pi, u64 start, u32 size, int type)
-{
-       dprintk("%s: %p: ino: %llu, start: %llu, size: %u, type: %d.\n",
-                       __func__, &pi->vfs_inode, pi->ino, start, size, type);
-       pi->lock_type = 0;
-       clear_bit(NETFS_INODE_REMOTE_DIR_SYNCED, &pi->state);
-       clear_bit(NETFS_INODE_OWNED, &pi->state);
-       return pohmelfs_send_lock_trans(pi, pi->ino, start, size, type);
-}
diff --git a/drivers/staging/pohmelfs/mcache.c b/drivers/staging/pohmelfs/mcache.c
deleted file mode 100644 (file)
index e22665c..0000000
+++ /dev/null
@@ -1,171 +0,0 @@
-/*
- * 2007+ Copyright (c) Evgeniy Polyakov <zbr@ioremap.net>
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- */
-
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/mempool.h>
-
-#include "netfs.h"
-
-static struct kmem_cache *pohmelfs_mcache_cache;
-static mempool_t *pohmelfs_mcache_pool;
-
-static inline int pohmelfs_mcache_cmp(u64 gen, u64 new)
-{
-       if (gen < new)
-               return 1;
-       if (gen > new)
-               return -1;
-       return 0;
-}
-
-struct pohmelfs_mcache *pohmelfs_mcache_search(struct pohmelfs_sb *psb, u64 gen)
-{
-       struct rb_root *root = &psb->mcache_root;
-       struct rb_node *n = root->rb_node;
-       struct pohmelfs_mcache *tmp, *ret = NULL;
-       int cmp;
-
-       while (n) {
-               tmp = rb_entry(n, struct pohmelfs_mcache, mcache_entry);
-
-               cmp = pohmelfs_mcache_cmp(tmp->gen, gen);
-               if (cmp < 0)
-                       n = n->rb_left;
-               else if (cmp > 0)
-                       n = n->rb_right;
-               else {
-                       ret = tmp;
-                       pohmelfs_mcache_get(ret);
-                       break;
-               }
-       }
-
-       return ret;
-}
-
-static int pohmelfs_mcache_insert(struct pohmelfs_sb *psb, struct pohmelfs_mcache *m)
-{
-       struct rb_root *root = &psb->mcache_root;
-       struct rb_node **n = &root->rb_node, *parent = NULL;
-       struct pohmelfs_mcache *ret = NULL, *tmp;
-       int cmp;
-
-       while (*n) {
-               parent = *n;
-
-               tmp = rb_entry(parent, struct pohmelfs_mcache, mcache_entry);
-
-               cmp = pohmelfs_mcache_cmp(tmp->gen, m->gen);
-               if (cmp < 0)
-                       n = &parent->rb_left;
-               else if (cmp > 0)
-                       n = &parent->rb_right;
-               else {
-                       ret = tmp;
-                       break;
-               }
-       }
-
-       if (ret)
-               return -EEXIST;
-
-       rb_link_node(&m->mcache_entry, parent, n);
-       rb_insert_color(&m->mcache_entry, root);
-
-       return 0;
-}
-
-static int pohmelfs_mcache_remove(struct pohmelfs_sb *psb, struct pohmelfs_mcache *m)
-{
-       if (m && m->mcache_entry.rb_parent_color) {
-               rb_erase(&m->mcache_entry, &psb->mcache_root);
-               m->mcache_entry.rb_parent_color = 0;
-               return 1;
-       }
-       return 0;
-}
-
-void pohmelfs_mcache_remove_locked(struct pohmelfs_sb *psb, struct pohmelfs_mcache *m)
-{
-       mutex_lock(&psb->mcache_lock);
-       pohmelfs_mcache_remove(psb, m);
-       mutex_unlock(&psb->mcache_lock);
-}
-
-struct pohmelfs_mcache *pohmelfs_mcache_alloc(struct pohmelfs_sb *psb, u64 start,
-               unsigned int size, void *data)
-{
-       struct pohmelfs_mcache *m;
-       int err = -ENOMEM;
-
-       m = mempool_alloc(pohmelfs_mcache_pool, GFP_KERNEL);
-       if (!m)
-               goto err_out_exit;
-
-       init_completion(&m->complete);
-       m->err = 0;
-       atomic_set(&m->refcnt, 1);
-       m->data = data;
-       m->start = start;
-       m->size = size;
-       m->gen = atomic_long_inc_return(&psb->mcache_gen);
-
-       mutex_lock(&psb->mcache_lock);
-       err = pohmelfs_mcache_insert(psb, m);
-       mutex_unlock(&psb->mcache_lock);
-       if (err)
-               goto err_out_free;
-
-       return m;
-
-err_out_free:
-       mempool_free(m, pohmelfs_mcache_pool);
-err_out_exit:
-       return ERR_PTR(err);
-}
-
-void pohmelfs_mcache_free(struct pohmelfs_sb *psb, struct pohmelfs_mcache *m)
-{
-       pohmelfs_mcache_remove_locked(psb, m);
-
-       mempool_free(m, pohmelfs_mcache_pool);
-}
-
-int __init pohmelfs_mcache_init(void)
-{
-       pohmelfs_mcache_cache = kmem_cache_create("pohmelfs_mcache_cache",
-                               sizeof(struct pohmelfs_mcache),
-                               0, (SLAB_RECLAIM_ACCOUNT|SLAB_MEM_SPREAD), NULL);
-       if (!pohmelfs_mcache_cache)
-               goto err_out_exit;
-
-       pohmelfs_mcache_pool = mempool_create_slab_pool(256, pohmelfs_mcache_cache);
-       if (!pohmelfs_mcache_pool)
-               goto err_out_free;
-
-       return 0;
-
-err_out_free:
-       kmem_cache_destroy(pohmelfs_mcache_cache);
-err_out_exit:
-       return -ENOMEM;
-}
-
-void pohmelfs_mcache_exit(void)
-{
-       mempool_destroy(pohmelfs_mcache_pool);
-       kmem_cache_destroy(pohmelfs_mcache_cache);
-}
diff --git a/drivers/staging/pohmelfs/net.c b/drivers/staging/pohmelfs/net.c
deleted file mode 100644 (file)
index b2e9186..0000000
+++ /dev/null
@@ -1,1209 +0,0 @@
-/*
- * 2007+ Copyright (c) Evgeniy Polyakov <zbr@ioremap.net>
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- */
-
-#include <linux/fsnotify.h>
-#include <linux/jhash.h>
-#include <linux/in.h>
-#include <linux/in6.h>
-#include <linux/kthread.h>
-#include <linux/pagemap.h>
-#include <linux/poll.h>
-#include <linux/slab.h>
-#include <linux/swap.h>
-#include <linux/syscalls.h>
-#include <linux/vmalloc.h>
-
-#include "netfs.h"
-
-/*
- * Async machinery lives here.
- * All commands being sent to server do _not_ require sync reply,
- * instead, if it is really needed, like readdir or readpage, caller
- * sleeps waiting for data, which will be placed into provided buffer
- * and caller will be awakened.
- *
- * Every command response can come without some listener. For example
- * readdir response will add new objects into cache without appropriate
- * request from userspace. This is used in cache coherency.
- *
- * If object is not found for given data, it is discarded.
- *
- * All requests are received by dedicated kernel thread.
- */
-
-/*
- * Basic network sending/receiving functions.
- * Blocked mode is used.
- */
-static int netfs_data_recv(struct netfs_state *st, void *buf, u64 size)
-{
-       struct msghdr msg;
-       struct kvec iov;
-       int err;
-
-       BUG_ON(!size);
-
-       iov.iov_base = buf;
-       iov.iov_len = size;
-
-       msg.msg_iov = (struct iovec *)&iov;
-       msg.msg_iovlen = 1;
-       msg.msg_name = NULL;
-       msg.msg_namelen = 0;
-       msg.msg_control = NULL;
-       msg.msg_controllen = 0;
-       msg.msg_flags = MSG_DONTWAIT;
-
-       err = kernel_recvmsg(st->socket, &msg, &iov, 1, iov.iov_len,
-                       msg.msg_flags);
-       if (err <= 0) {
-               printk("%s: failed to recv data: size: %llu, err: %d.\n", __func__, size, err);
-               if (err == 0)
-                       err = -ECONNRESET;
-       }
-
-       return err;
-}
-
-static int pohmelfs_data_recv(struct netfs_state *st, void *data, unsigned int size)
-{
-       unsigned int revents = 0;
-       unsigned int err_mask = POLLERR | POLLHUP | POLLRDHUP;
-       unsigned int mask = err_mask | POLLIN;
-       int err = 0;
-
-       while (size && !err) {
-               revents = netfs_state_poll(st);
-
-               if (!(revents & mask)) {
-                       DEFINE_WAIT(wait);
-
-                       for (;;) {
-                               prepare_to_wait(&st->thread_wait, &wait, TASK_INTERRUPTIBLE);
-                               if (kthread_should_stop())
-                                       break;
-
-                               revents = netfs_state_poll(st);
-
-                               if (revents & mask)
-                                       break;
-
-                               if (signal_pending(current))
-                                       break;
-
-                               schedule();
-                               continue;
-                       }
-                       finish_wait(&st->thread_wait, &wait);
-               }
-
-               err = 0;
-               netfs_state_lock(st);
-               if (st->socket && (st->read_socket == st->socket) && (revents & POLLIN)) {
-                       err = netfs_data_recv(st, data, size);
-                       if (err > 0) {
-                               data += err;
-                               size -= err;
-                               err = 0;
-                       } else if (err == 0)
-                               err = -ECONNRESET;
-               }
-
-               if (revents & err_mask) {
-                       printk("%s: revents: %x, socket: %p, size: %u, err: %d.\n",
-                                       __func__, revents, st->socket, size, err);
-                       err = -ECONNRESET;
-               }
-               netfs_state_unlock(st);
-
-               if (err < 0) {
-                       if (netfs_state_trylock_send(st)) {
-                               netfs_state_exit(st);
-                               err = netfs_state_init(st);
-                               if (!err)
-                                       err = -EAGAIN;
-                               netfs_state_unlock_send(st);
-                       } else {
-                               st->need_reset = 1;
-                       }
-               }
-
-               if (kthread_should_stop())
-                       err = -ENODEV;
-
-               if (err)
-                       printk("%s: socket: %p, read_socket: %p, revents: %x, rev_error: %d, "
-                                       "should_stop: %d, size: %u, err: %d.\n",
-                               __func__, st->socket, st->read_socket,
-                               revents, revents & err_mask, kthread_should_stop(), size, err);
-       }
-
-       return err;
-}
-
-int pohmelfs_data_recv_and_check(struct netfs_state *st, void *data, unsigned int size)
-{
-       struct netfs_cmd *cmd = &st->cmd;
-       int err;
-
-       err = pohmelfs_data_recv(st, data, size);
-       if (err)
-               return err;
-
-       return pohmelfs_crypto_process_input_data(&st->eng, cmd->iv, data, NULL, size);
-}
-
-/*
- * Polling machinery.
- */
-
-struct netfs_poll_helper {
-       poll_table              pt;
-       struct netfs_state      *st;
-};
-
-static int netfs_queue_wake(wait_queue_t *wait, unsigned mode, int sync, void *key)
-{
-       struct netfs_state *st = container_of(wait, struct netfs_state, wait);
-
-       wake_up(&st->thread_wait);
-       return 1;
-}
-
-static void netfs_queue_func(struct file *file, wait_queue_head_t *whead,
-                                poll_table *pt)
-{
-       struct netfs_state *st = container_of(pt, struct netfs_poll_helper, pt)->st;
-
-       st->whead = whead;
-       init_waitqueue_func_entry(&st->wait, netfs_queue_wake);
-       add_wait_queue(whead, &st->wait);
-}
-
-static void netfs_poll_exit(struct netfs_state *st)
-{
-       if (st->whead) {
-               remove_wait_queue(st->whead, &st->wait);
-               st->whead = NULL;
-       }
-}
-
-static int netfs_poll_init(struct netfs_state *st)
-{
-       struct netfs_poll_helper ph;
-
-       ph.st = st;
-       init_poll_funcptr(&ph.pt, &netfs_queue_func);
-
-       st->socket->ops->poll(NULL, st->socket, &ph.pt);
-       return 0;
-}
-
-/*
- * Get response for readpage command. We search inode and page in its mapping
- * and copy data into. If it was async request, then we queue page into shared
- * data and wakeup listener, who will copy it to userspace.
- *
- * There is a work in progress of allowing to call copy_to_user() directly from
- * async receiving kernel thread.
- */
-static int pohmelfs_read_page_response(struct netfs_state *st)
-{
-       struct pohmelfs_sb *psb = st->psb;
-       struct netfs_cmd *cmd = &st->cmd;
-       struct inode *inode;
-       struct page *page;
-       int err = 0;
-
-       if (cmd->size > PAGE_CACHE_SIZE) {
-               err = -EINVAL;
-               goto err_out_exit;
-       }
-
-       inode = ilookup(st->psb->sb, cmd->id);
-       if (!inode) {
-               printk("%s: failed to find inode: id: %llu.\n", __func__, cmd->id);
-               err = -ENOENT;
-               goto err_out_exit;
-       }
-
-       page = find_get_page(inode->i_mapping, cmd->start >> PAGE_CACHE_SHIFT);
-       if (!page || !PageLocked(page)) {
-               printk("%s: failed to find/lock page: page: %p, id: %llu, start: %llu, index: %llu.\n",
-                               __func__, page, cmd->id, cmd->start, cmd->start >> PAGE_CACHE_SHIFT);
-
-               while (cmd->size) {
-                       unsigned int sz = min(cmd->size, st->size);
-
-                       err = pohmelfs_data_recv(st, st->data, sz);
-                       if (err)
-                               break;
-
-                       cmd->size -= sz;
-               }
-
-               err = -ENODEV;
-               if (page)
-                       goto err_out_page_put;
-               goto err_out_put;
-       }
-
-       if (cmd->size) {
-               void *addr;
-
-               addr = kmap(page);
-               err = pohmelfs_data_recv(st, addr, cmd->size);
-               kunmap(page);
-
-               if (err)
-                       goto err_out_page_unlock;
-       }
-
-       dprintk("%s: page: %p, start: %llu, size: %u, locked: %d.\n",
-               __func__, page, cmd->start, cmd->size, PageLocked(page));
-
-       SetPageChecked(page);
-       if ((psb->hash_string || psb->cipher_string) && psb->perform_crypto && cmd->size) {
-               err = pohmelfs_crypto_process_input_page(&st->eng, page, cmd->size, cmd->iv);
-               if (err < 0)
-                       goto err_out_page_unlock;
-       } else {
-               SetPageUptodate(page);
-               unlock_page(page);
-               page_cache_release(page);
-       }
-
-       pohmelfs_put_inode(POHMELFS_I(inode));
-       wake_up(&st->psb->wait);
-
-       return 0;
-
-err_out_page_unlock:
-       SetPageError(page);
-       unlock_page(page);
-err_out_page_put:
-       page_cache_release(page);
-err_out_put:
-       pohmelfs_put_inode(POHMELFS_I(inode));
-err_out_exit:
-       wake_up(&st->psb->wait);
-       return err;
-}
-
-static int pohmelfs_check_name(struct pohmelfs_inode *parent, struct qstr *str,
-               struct netfs_inode_info *info)
-{
-       struct inode *inode;
-       struct pohmelfs_name *n;
-       int err = 0;
-       u64 ino = 0;
-
-       mutex_lock(&parent->offset_lock);
-       n = pohmelfs_search_hash(parent, str->hash);
-       if (n)
-               ino = n->ino;
-       mutex_unlock(&parent->offset_lock);
-
-       if (!ino)
-               goto out;
-
-       inode = ilookup(parent->vfs_inode.i_sb, ino);
-       if (!inode)
-               goto out;
-
-       dprintk("%s: parent: %llu, inode: %llu.\n", __func__, parent->ino, ino);
-
-       pohmelfs_fill_inode(inode, info);
-       pohmelfs_put_inode(POHMELFS_I(inode));
-       err = -EEXIST;
-out:
-       return err;
-}
-
-/*
- * Readdir response from server. If special field is set, we wakeup
- * listener (readdir() call), which will copy data to userspace.
- */
-static int pohmelfs_readdir_response(struct netfs_state *st)
-{
-       struct inode *inode;
-       struct netfs_cmd *cmd = &st->cmd;
-       struct netfs_inode_info *info;
-       struct pohmelfs_inode *parent = NULL, *npi;
-       int err = 0, last = cmd->ext;
-       struct qstr str;
-
-       if (cmd->size > st->size)
-               return -EINVAL;
-
-       inode = ilookup(st->psb->sb, cmd->id);
-       if (!inode) {
-               printk("%s: failed to find inode: id: %llu.\n", __func__, cmd->id);
-               return -ENOENT;
-       }
-       parent = POHMELFS_I(inode);
-
-       if (!cmd->size && cmd->start) {
-               err = -cmd->start;
-               goto out;
-       }
-
-       if (cmd->size) {
-               char *name;
-
-               err = pohmelfs_data_recv_and_check(st, st->data, cmd->size);
-               if (err)
-                       goto err_out_put;
-
-               info = (struct netfs_inode_info *)(st->data);
-
-               name = (char *)(info + 1);
-               str.len = cmd->size - sizeof(struct netfs_inode_info) - 1 - cmd->cpad;
-               name[str.len] = 0;
-               str.name = name;
-               str.hash = jhash(str.name, str.len, 0);
-
-               netfs_convert_inode_info(info);
-
-               if (parent) {
-                       err = pohmelfs_check_name(parent, &str, info);
-                       if (err) {
-                               if (err == -EEXIST)
-                                       err = 0;
-                               goto out;
-                       }
-               }
-
-               info->ino = cmd->start;
-               if (!info->ino)
-                       info->ino = pohmelfs_new_ino(st->psb);
-
-               dprintk("%s: parent: %llu, ino: %llu, name: '%s', hash: %x, len: %u, mode: %o.\n",
-                               __func__, parent->ino, info->ino, str.name, str.hash, str.len,
-                               info->mode);
-
-               npi = pohmelfs_new_inode(st->psb, parent, &str, info, 0);
-               if (IS_ERR(npi)) {
-                       err = PTR_ERR(npi);
-
-                       if (err != -EEXIST)
-                               goto err_out_put;
-               } else {
-                       struct dentry *dentry, *alias, *pd;
-
-                       set_bit(NETFS_INODE_REMOTE_SYNCED, &npi->state);
-                       clear_bit(NETFS_INODE_OWNED, &npi->state);
-
-                       pd = d_find_alias(&parent->vfs_inode);
-                       if (pd) {
-                               str.hash = full_name_hash(str.name, str.len);
-                               dentry = d_alloc(pd, &str);
-                               if (dentry) {
-                                       alias = d_materialise_unique(dentry, &npi->vfs_inode);
-                                       if (alias)
-                                               dput(alias);
-                               }
-
-                               dput(dentry);
-                               dput(pd);
-                       }
-               }
-       }
-out:
-       if (last) {
-               set_bit(NETFS_INODE_REMOTE_DIR_SYNCED, &parent->state);
-               set_bit(NETFS_INODE_REMOTE_SYNCED, &parent->state);
-               wake_up(&st->psb->wait);
-       }
-       pohmelfs_put_inode(parent);
-
-       return err;
-
-err_out_put:
-       clear_bit(NETFS_INODE_REMOTE_DIR_SYNCED, &parent->state);
-       printk("%s: parent: %llu, ino: %llu, cmd_id: %llu.\n", __func__, parent->ino, cmd->start, cmd->id);
-       pohmelfs_put_inode(parent);
-       wake_up(&st->psb->wait);
-       return err;
-}
-
-/*
- * Lookup command response.
- * It searches for inode to be looked at (if it exists) and substitutes
- * its inode information (size, permission, mode and so on), if inode does
- * not exist, new one will be created and inserted into caches.
- */
-static int pohmelfs_lookup_response(struct netfs_state *st)
-{
-       struct inode *inode = NULL;
-       struct netfs_cmd *cmd = &st->cmd;
-       struct netfs_inode_info *info;
-       struct pohmelfs_inode *parent = NULL, *npi;
-       int err = -EINVAL;
-       char *name;
-
-       inode = ilookup(st->psb->sb, cmd->id);
-       if (!inode) {
-               printk("%s: lookup response: id: %llu, start: %llu, size: %u.\n",
-                               __func__, cmd->id, cmd->start, cmd->size);
-               err = -ENOENT;
-               goto err_out_exit;
-       }
-       parent = POHMELFS_I(inode);
-
-       if (!cmd->size) {
-               err = -cmd->start;
-               goto err_out_put;
-       }
-
-       if (cmd->size < sizeof(struct netfs_inode_info)) {
-               printk("%s: broken lookup response: id: %llu, start: %llu, size: %u.\n",
-                               __func__, cmd->id, cmd->start, cmd->size);
-               err = -EINVAL;
-               goto err_out_put;
-       }
-
-       err = pohmelfs_data_recv_and_check(st, st->data, cmd->size);
-       if (err)
-               goto err_out_put;
-
-       info = (struct netfs_inode_info *)(st->data);
-       name = (char *)(info + 1);
-
-       netfs_convert_inode_info(info);
-
-       info->ino = cmd->start;
-       if (!info->ino)
-               info->ino = pohmelfs_new_ino(st->psb);
-
-       dprintk("%s: parent: %llu, ino: %llu, name: '%s', start: %llu.\n",
-                       __func__, parent->ino, info->ino, name, cmd->start);
-
-       if (cmd->start)
-               npi = pohmelfs_new_inode(st->psb, parent, NULL, info, 0);
-       else {
-               struct qstr str;
-
-               str.name = name;
-               str.len = cmd->size - sizeof(struct netfs_inode_info) - 1 - cmd->cpad;
-               str.hash = jhash(name, str.len, 0);
-
-               npi = pohmelfs_new_inode(st->psb, parent, &str, info, 0);
-       }
-       if (IS_ERR(npi)) {
-               err = PTR_ERR(npi);
-
-               if (err != -EEXIST)
-                       goto err_out_put;
-       } else {
-               set_bit(NETFS_INODE_REMOTE_SYNCED, &npi->state);
-               clear_bit(NETFS_INODE_OWNED, &npi->state);
-       }
-
-       clear_bit(NETFS_COMMAND_PENDING, &parent->state);
-       pohmelfs_put_inode(parent);
-
-       wake_up(&st->psb->wait);
-
-       return 0;
-
-err_out_put:
-       pohmelfs_put_inode(parent);
-err_out_exit:
-       clear_bit(NETFS_COMMAND_PENDING, &parent->state);
-       wake_up(&st->psb->wait);
-       printk("%s: inode: %p, id: %llu, start: %llu, size: %u, err: %d.\n",
-                       __func__, inode, cmd->id, cmd->start, cmd->size, err);
-       return err;
-}
-
-/*
- * Create response, just marks local inode as 'created', so that writeback
- * for any of its children (or own) would not try to sync it again.
- */
-static int pohmelfs_create_response(struct netfs_state *st)
-{
-       struct inode *inode;
-       struct netfs_cmd *cmd = &st->cmd;
-       struct pohmelfs_inode *pi;
-
-       inode = ilookup(st->psb->sb, cmd->id);
-       if (!inode) {
-               printk("%s: failed to find inode: id: %llu, start: %llu.\n",
-                               __func__, cmd->id, cmd->start);
-               goto err_out_exit;
-       }
-
-       pi = POHMELFS_I(inode);
-
-       /*
-        * To lock or not to lock?
-        * We actually do not care if it races...
-        */
-       if (cmd->start)
-               make_bad_inode(inode);
-       set_bit(NETFS_INODE_REMOTE_SYNCED, &pi->state);
-
-       pohmelfs_put_inode(pi);
-
-       wake_up(&st->psb->wait);
-       return 0;
-
-err_out_exit:
-       wake_up(&st->psb->wait);
-       return -ENOENT;
-}
-
-/*
- * Object remove response. Just says that remove request has been received.
- * Used in cache coherency protocol.
- */
-static int pohmelfs_remove_response(struct netfs_state *st)
-{
-       struct netfs_cmd *cmd = &st->cmd;
-       int err;
-
-       err = pohmelfs_data_recv_and_check(st, st->data, cmd->size);
-       if (err)
-               return err;
-
-       dprintk("%s: parent: %llu, path: '%s'.\n", __func__, cmd->id, (char *)st->data);
-
-       return 0;
-}
-
-/*
- * Transaction reply processing.
- *
- * Find transaction based on its generation number, bump its reference counter,
- * so that none could free it under us, drop from the trees and lists and
- * drop reference counter. When it hits zero (when all destinations replied
- * and all timeout handled by async scanning code), completion will be called
- * and transaction will be freed.
- */
-static int pohmelfs_transaction_response(struct netfs_state *st)
-{
-       struct netfs_trans_dst *dst;
-       struct netfs_trans *t = NULL;
-       struct netfs_cmd *cmd = &st->cmd;
-       short err = (signed)cmd->ext;
-
-       mutex_lock(&st->trans_lock);
-       dst = netfs_trans_search(st, cmd->start);
-       if (dst) {
-               netfs_trans_remove_nolock(dst, st);
-               t = dst->trans;
-       }
-       mutex_unlock(&st->trans_lock);
-
-       if (!t) {
-               printk("%s: failed to find transaction: start: %llu: id: %llu, size: %u, ext: %u.\n",
-                               __func__, cmd->start, cmd->id, cmd->size, cmd->ext);
-               err = -EINVAL;
-               goto out;
-       }
-
-       t->result = err;
-       netfs_trans_drop_dst_nostate(dst);
-
-out:
-       wake_up(&st->psb->wait);
-       return err;
-}
-
-/*
- * Inode metadata cache coherency message.
- */
-static int pohmelfs_page_cache_response(struct netfs_state *st)
-{
-       struct netfs_cmd *cmd = &st->cmd;
-       struct inode *inode;
-
-       dprintk("%s: st: %p, id: %llu, start: %llu, size: %u.\n", __func__, st, cmd->id, cmd->start, cmd->size);
-
-       inode = ilookup(st->psb->sb, cmd->id);
-       if (!inode) {
-               printk("%s: failed to find inode: id: %llu.\n", __func__, cmd->id);
-               return -ENOENT;
-       }
-
-       set_bit(NETFS_INODE_NEED_FLUSH, &POHMELFS_I(inode)->state);
-       pohmelfs_put_inode(POHMELFS_I(inode));
-
-       return 0;
-}
-
-/*
- * Root capabilities response: export statistics
- * like used and available size, number of files and dirs,
- * permissions.
- */
-static int pohmelfs_root_cap_response(struct netfs_state *st)
-{
-       struct netfs_cmd *cmd = &st->cmd;
-       struct netfs_root_capabilities *cap;
-       struct pohmelfs_sb *psb = st->psb;
-
-       if (cmd->size != sizeof(struct netfs_root_capabilities)) {
-               psb->flags = EPROTO;
-               wake_up(&psb->wait);
-               return -EPROTO;
-       }
-
-       cap = st->data;
-
-       netfs_convert_root_capabilities(cap);
-
-       if (psb->total_size < cap->used + cap->avail)
-               psb->total_size = cap->used + cap->avail;
-       if (cap->avail)
-               psb->avail_size = cap->avail;
-       psb->state_flags = cap->flags;
-
-       if (psb->state_flags & POHMELFS_FLAGS_RO) {
-               psb->sb->s_flags |= MS_RDONLY;
-               printk(KERN_INFO "Mounting POHMELFS (%d) read-only.\n", psb->idx);
-       }
-
-       if (psb->state_flags & POHMELFS_FLAGS_XATTR)
-               printk(KERN_INFO "Mounting POHMELFS (%d) "
-                       "with extended attributes support.\n", psb->idx);
-
-       if (atomic_long_read(&psb->total_inodes) <= 1)
-               atomic_long_set(&psb->total_inodes, cap->nr_files);
-
-       dprintk("%s: total: %llu, avail: %llu, flags: %llx, inodes: %llu.\n",
-               __func__, psb->total_size, psb->avail_size, psb->state_flags, cap->nr_files);
-
-       psb->flags = 0;
-       wake_up(&psb->wait);
-       return 0;
-}
-
-/*
- * Crypto capabilities of the server, where it says that
- * it supports or does not requested hash/cipher algorithms.
- */
-static int pohmelfs_crypto_cap_response(struct netfs_state *st)
-{
-       struct netfs_cmd *cmd = &st->cmd;
-       struct netfs_crypto_capabilities *cap;
-       struct pohmelfs_sb *psb = st->psb;
-       int err = 0;
-
-       if (cmd->size != sizeof(struct netfs_crypto_capabilities)) {
-               psb->flags = EPROTO;
-               wake_up(&psb->wait);
-               return -EPROTO;
-       }
-
-       cap = st->data;
-
-       dprintk("%s: cipher '%s': %s, hash: '%s': %s.\n",
-                       __func__,
-                       psb->cipher_string, (cap->cipher_strlen) ? "SUPPORTED" : "NOT SUPPORTED",
-                       psb->hash_string, (cap->hash_strlen) ? "SUPPORTED" : "NOT SUPPORTED");
-
-       if (!cap->hash_strlen) {
-               if (psb->hash_strlen && psb->crypto_fail_unsupported)
-                       err = -ENOTSUPP;
-               psb->hash_strlen = 0;
-               kfree(psb->hash_string);
-               psb->hash_string = NULL;
-       }
-
-       if (!cap->cipher_strlen) {
-               if (psb->cipher_strlen && psb->crypto_fail_unsupported)
-                       err = -ENOTSUPP;
-               psb->cipher_strlen = 0;
-               kfree(psb->cipher_string);
-               psb->cipher_string = NULL;
-       }
-
-       return err;
-}
-
-/*
- * Capabilities handshake response.
- */
-static int pohmelfs_capabilities_response(struct netfs_state *st)
-{
-       struct netfs_cmd *cmd = &st->cmd;
-       int err = 0;
-
-       err = pohmelfs_data_recv(st, st->data, cmd->size);
-       if (err)
-               return err;
-
-       switch (cmd->id) {
-       case POHMELFS_CRYPTO_CAPABILITIES:
-                       return pohmelfs_crypto_cap_response(st);
-       case POHMELFS_ROOT_CAPABILITIES:
-                       return pohmelfs_root_cap_response(st);
-       default:
-                       break;
-       }
-       return -EINVAL;
-}
-
-/*
- * Receiving extended attribute.
- * Does not work properly if received size is more than requested one,
- * it should not happen with current request/reply model though.
- */
-static int pohmelfs_getxattr_response(struct netfs_state *st)
-{
-       struct pohmelfs_sb *psb = st->psb;
-       struct netfs_cmd *cmd = &st->cmd;
-       struct pohmelfs_mcache *m;
-       short error = (signed short)cmd->ext, err;
-       unsigned int sz, total_size;
-
-       m = pohmelfs_mcache_search(psb, cmd->id);
-
-       dprintk("%s: id: %llu, gen: %llu, err: %d.\n",
-               __func__, cmd->id, (m) ? m->gen : 0, error);
-
-       if (!m) {
-               printk("%s: failed to find getxattr cache entry: id: %llu.\n", __func__, cmd->id);
-               return -ENOENT;
-       }
-
-       if (cmd->size) {
-               sz = min_t(unsigned int, cmd->size, m->size);
-               err = pohmelfs_data_recv_and_check(st, m->data, sz);
-               if (err) {
-                       error = err;
-                       goto out;
-               }
-
-               m->size = sz;
-               total_size = cmd->size - sz;
-
-               while (total_size) {
-                       sz = min(total_size, st->size);
-
-                       err = pohmelfs_data_recv_and_check(st, st->data, sz);
-                       if (err) {
-                               error = err;
-                               break;
-                       }
-
-                       total_size -= sz;
-               }
-       }
-
-out:
-       m->err = error;
-       complete(&m->complete);
-       pohmelfs_mcache_put(psb, m);
-
-       return error;
-}
-
-int pohmelfs_data_lock_response(struct netfs_state *st)
-{
-       struct pohmelfs_sb *psb = st->psb;
-       struct netfs_cmd *cmd = &st->cmd;
-       struct pohmelfs_mcache *m;
-       short err = (signed short)cmd->ext;
-       u64 id = cmd->id;
-
-       m = pohmelfs_mcache_search(psb, id);
-
-       dprintk("%s: id: %llu, gen: %llu, err: %d.\n",
-               __func__, cmd->id, (m) ? m->gen : 0, err);
-
-       if (!m) {
-               pohmelfs_data_recv(st, st->data, cmd->size);
-               printk("%s: failed to find data lock response: id: %llu.\n", __func__, cmd->id);
-               return -ENOENT;
-       }
-
-       if (cmd->size)
-               err = pohmelfs_data_recv_and_check(st, &m->info, cmd->size);
-
-       m->err = err;
-       complete(&m->complete);
-       pohmelfs_mcache_put(psb, m);
-
-       return err;
-}
-
-static void __inline__ netfs_state_reset(struct netfs_state *st)
-{
-       netfs_state_lock_send(st);
-       netfs_state_exit(st);
-       netfs_state_init(st);
-       netfs_state_unlock_send(st);
-}
-
-/*
- * Main receiving function, called from dedicated kernel thread.
- */
-static int pohmelfs_recv(void *data)
-{
-       int err = -EINTR;
-       struct netfs_state *st = data;
-       struct netfs_cmd *cmd = &st->cmd;
-
-       while (!kthread_should_stop()) {
-               /*
-                * If socket will be reset after this statement, then
-                * pohmelfs_data_recv() will just fail and loop will
-                * start again, so it can be done without any locks.
-                *
-                * st->read_socket is needed to prevents state machine
-                * breaking between this data reading and subsequent one
-                * in protocol specific functions during connection reset.
-                * In case of reset we have to read next command and do
-                * not expect data for old command to magically appear in
-                * new connection.
-                */
-               st->read_socket = st->socket;
-               err = pohmelfs_data_recv(st, cmd, sizeof(struct netfs_cmd));
-               if (err) {
-                       msleep(1000);
-                       continue;
-               }
-
-               netfs_convert_cmd(cmd);
-
-               dprintk("%s: cmd: %u, id: %llu, start: %llu, size: %u, "
-                               "ext: %u, csize: %u, cpad: %u.\n",
-                               __func__, cmd->cmd, cmd->id, cmd->start,
-                               cmd->size, cmd->ext, cmd->csize, cmd->cpad);
-
-               if (cmd->csize) {
-                       struct pohmelfs_crypto_engine *e = &st->eng;
-
-                       if (unlikely(cmd->csize > e->size/2)) {
-                               netfs_state_reset(st);
-                               continue;
-                       }
-
-                       if (e->hash && unlikely(cmd->csize != st->psb->crypto_attached_size)) {
-                               dprintk("%s: cmd: cmd: %u, id: %llu, start: %llu, size: %u, "
-                                               "csize: %u != digest size %u.\n",
-                                               __func__, cmd->cmd, cmd->id, cmd->start, cmd->size,
-                                               cmd->csize, st->psb->crypto_attached_size);
-                               netfs_state_reset(st);
-                               continue;
-                       }
-
-                       err = pohmelfs_data_recv(st, e->data, cmd->csize);
-                       if (err) {
-                               netfs_state_reset(st);
-                               continue;
-                       }
-
-#ifdef CONFIG_POHMELFS_DEBUG
-                       {
-                               unsigned int i;
-                               unsigned char *hash = e->data;
-
-                               dprintk("%s: received hash: ", __func__);
-                               for (i = 0; i < cmd->csize; ++i)
-                                       printk("%02x ", hash[i]);
-
-                               printk("\n");
-                       }
-#endif
-                       cmd->size -= cmd->csize;
-               }
-
-               /*
-                * This should catch protocol breakage and random garbage instead of commands.
-                */
-               if (unlikely((cmd->size > st->size) && (cmd->cmd != NETFS_XATTR_GET))) {
-                       netfs_state_reset(st);
-                       continue;
-               }
-
-               switch (cmd->cmd) {
-               case NETFS_READ_PAGE:
-                               err = pohmelfs_read_page_response(st);
-                               break;
-               case NETFS_READDIR:
-                               err = pohmelfs_readdir_response(st);
-                               break;
-               case NETFS_LOOKUP:
-                               err = pohmelfs_lookup_response(st);
-                               break;
-               case NETFS_CREATE:
-                               err = pohmelfs_create_response(st);
-                               break;
-               case NETFS_REMOVE:
-                               err = pohmelfs_remove_response(st);
-                               break;
-               case NETFS_TRANS:
-                               err = pohmelfs_transaction_response(st);
-                               break;
-               case NETFS_PAGE_CACHE:
-                               err = pohmelfs_page_cache_response(st);
-                               break;
-               case NETFS_CAPABILITIES:
-                               err = pohmelfs_capabilities_response(st);
-                               break;
-               case NETFS_LOCK:
-                               err = pohmelfs_data_lock_response(st);
-                               break;
-               case NETFS_XATTR_GET:
-                               err = pohmelfs_getxattr_response(st);
-                               break;
-               default:
-                               printk("%s: wrong cmd: %u, id: %llu, start: %llu, size: %u, ext: %u.\n",
-                                       __func__, cmd->cmd, cmd->id, cmd->start, cmd->size, cmd->ext);
-                               netfs_state_reset(st);
-                               break;
-               }
-       }
-
-       while (!kthread_should_stop())
-               schedule_timeout_uninterruptible(msecs_to_jiffies(10));
-
-       return err;
-}
-
-int netfs_state_init(struct netfs_state *st)
-{
-       int err;
-       struct pohmelfs_ctl *ctl = &st->ctl;
-
-       err = sock_create(ctl->addr.sa_family, ctl->type, ctl->proto, &st->socket);
-       if (err) {
-               printk("%s: failed to create a socket: family: %d, type: %d, proto: %d, err: %d.\n",
-                               __func__, ctl->addr.sa_family, ctl->type, ctl->proto, err);
-               goto err_out_exit;
-       }
-
-       st->socket->sk->sk_allocation = GFP_NOIO;
-       st->socket->sk->sk_sndtimeo = st->socket->sk->sk_rcvtimeo = msecs_to_jiffies(60000);
-
-       err = kernel_connect(st->socket, (struct sockaddr *)&ctl->addr, ctl->addrlen, 0);
-       if (err) {
-               printk("%s: failed to connect to server: idx: %u, err: %d.\n",
-                               __func__, st->psb->idx, err);
-               goto err_out_release;
-       }
-       st->socket->sk->sk_sndtimeo = st->socket->sk->sk_rcvtimeo = msecs_to_jiffies(60000);
-
-       err = netfs_poll_init(st);
-       if (err)
-               goto err_out_release;
-
-       if (st->socket->ops->family == AF_INET) {
-               struct sockaddr_in *sin = (struct sockaddr_in *)&ctl->addr;
-               printk(KERN_INFO "%s: (re)connected to peer %pi4:%d.\n", __func__,
-                       &sin->sin_addr.s_addr, ntohs(sin->sin_port));
-       } else if (st->socket->ops->family == AF_INET6) {
-               struct sockaddr_in6 *sin = (struct sockaddr_in6 *)&ctl->addr;
-               printk(KERN_INFO "%s: (re)connected to peer %pi6:%d", __func__,
-                               &sin->sin6_addr, ntohs(sin->sin6_port));
-       }
-
-       return 0;
-
-err_out_release:
-       sock_release(st->socket);
-err_out_exit:
-       st->socket = NULL;
-       return err;
-}
-
-void netfs_state_exit(struct netfs_state *st)
-{
-       if (st->socket) {
-               netfs_poll_exit(st);
-               st->socket->ops->shutdown(st->socket, 2);
-
-               if (st->socket->ops->family == AF_INET) {
-                       struct sockaddr_in *sin = (struct sockaddr_in *)&st->ctl.addr;
-                       printk(KERN_INFO "%s: disconnected from peer %pi4:%d.\n", __func__,
-                               &sin->sin_addr.s_addr, ntohs(sin->sin_port));
-               } else if (st->socket->ops->family == AF_INET6) {
-                       struct sockaddr_in6 *sin = (struct sockaddr_in6 *)&st->ctl.addr;
-                       printk(KERN_INFO "%s: disconnected from peer %pi6:%d", __func__,
-                               &sin->sin6_addr, ntohs(sin->sin6_port));
-               }
-
-               sock_release(st->socket);
-               st->socket = NULL;
-               st->read_socket = NULL;
-               st->need_reset = 0;
-       }
-}
-
-int pohmelfs_state_init_one(struct pohmelfs_sb *psb, struct pohmelfs_config *conf)
-{
-       struct netfs_state *st = &conf->state;
-       int err = -ENOMEM;
-
-       mutex_init(&st->__state_lock);
-       mutex_init(&st->__state_send_lock);
-       init_waitqueue_head(&st->thread_wait);
-
-       st->psb = psb;
-       st->trans_root = RB_ROOT;
-       mutex_init(&st->trans_lock);
-
-       st->size = psb->trans_data_size;
-       st->data = kmalloc(st->size, GFP_KERNEL);
-       if (!st->data)
-               goto err_out_exit;
-
-       if (psb->perform_crypto) {
-               err = pohmelfs_crypto_engine_init(&st->eng, psb);
-               if (err)
-                       goto err_out_free_data;
-       }
-
-       err = netfs_state_init(st);
-       if (err)
-               goto err_out_free_engine;
-
-       st->thread = kthread_run(pohmelfs_recv, st, "pohmelfs/%u", psb->idx);
-       if (IS_ERR(st->thread)) {
-               err = PTR_ERR(st->thread);
-               goto err_out_netfs_exit;
-       }
-
-       if (!psb->active_state)
-               psb->active_state = conf;
-
-       dprintk("%s: conf: %p, st: %p, socket: %p.\n",
-                       __func__, conf, st, st->socket);
-       return 0;
-
-err_out_netfs_exit:
-       netfs_state_exit(st);
-err_out_free_engine:
-       pohmelfs_crypto_engine_exit(&st->eng);
-err_out_free_data:
-       kfree(st->data);
-err_out_exit:
-       return err;
-
-}
-
-void pohmelfs_state_flush_transactions(struct netfs_state *st)
-{
-       struct rb_node *rb_node;
-       struct netfs_trans_dst *dst;
-
-       mutex_lock(&st->trans_lock);
-       for (rb_node = rb_first(&st->trans_root); rb_node; ) {
-               dst = rb_entry(rb_node, struct netfs_trans_dst, state_entry);
-               rb_node = rb_next(rb_node);
-
-               dst->trans->result = -EINVAL;
-               netfs_trans_remove_nolock(dst, st);
-               netfs_trans_drop_dst_nostate(dst);
-       }
-       mutex_unlock(&st->trans_lock);
-}
-
-static void pohmelfs_state_exit_one(struct pohmelfs_config *c)
-{
-       struct netfs_state *st = &c->state;
-
-       dprintk("%s: exiting, st: %p.\n", __func__, st);
-       if (st->thread) {
-               kthread_stop(st->thread);
-               st->thread = NULL;
-       }
-
-       netfs_state_lock_send(st);
-       netfs_state_exit(st);
-       netfs_state_unlock_send(st);
-
-       pohmelfs_state_flush_transactions(st);
-
-       pohmelfs_crypto_engine_exit(&st->eng);
-       kfree(st->data);
-
-       kfree(c);
-}
-
-/*
- * Initialize network stack. It searches for given ID in global
- * configuration table, this contains information of the remote server
- * (address (any supported by socket interface) and port, protocol and so on).
- */
-int pohmelfs_state_init(struct pohmelfs_sb *psb)
-{
-       int err = -ENOMEM;
-
-       err = pohmelfs_copy_config(psb);
-       if (err) {
-               pohmelfs_state_exit(psb);
-               return err;
-       }
-
-       return 0;
-}
-
-void pohmelfs_state_exit(struct pohmelfs_sb *psb)
-{
-       struct pohmelfs_config *c, *tmp;
-
-       list_for_each_entry_safe(c, tmp, &psb->state_list, config_entry) {
-               list_del(&c->config_entry);
-               pohmelfs_state_exit_one(c);
-       }
-}
-
-void pohmelfs_switch_active(struct pohmelfs_sb *psb)
-{
-       struct pohmelfs_config *c = psb->active_state;
-
-       if (!list_empty(&psb->state_list)) {
-               if (c->config_entry.next != &psb->state_list) {
-                       psb->active_state = list_entry(c->config_entry.next,
-                               struct pohmelfs_config, config_entry);
-               } else {
-                       psb->active_state = list_entry(psb->state_list.next,
-                               struct pohmelfs_config, config_entry);
-               }
-
-               dprintk("%s: empty: %d, active %p -> %p.\n",
-                       __func__, list_empty(&psb->state_list), c,
-                       psb->active_state);
-       } else
-               psb->active_state = NULL;
-}
-
-void pohmelfs_check_states(struct pohmelfs_sb *psb)
-{
-       struct pohmelfs_config *c, *tmp;
-       LIST_HEAD(delete_list);
-
-       mutex_lock(&psb->state_lock);
-       list_for_each_entry_safe(c, tmp, &psb->state_list, config_entry) {
-               if (pohmelfs_config_check(c, psb->idx)) {
-
-                       if (psb->active_state == c)
-                               pohmelfs_switch_active(psb);
-                       list_move(&c->config_entry, &delete_list);
-               }
-       }
-       pohmelfs_copy_config(psb);
-       mutex_unlock(&psb->state_lock);
-
-       list_for_each_entry_safe(c, tmp, &delete_list, config_entry) {
-               list_del(&c->config_entry);
-               pohmelfs_state_exit_one(c);
-       }
-}
diff --git a/drivers/staging/pohmelfs/netfs.h b/drivers/staging/pohmelfs/netfs.h
deleted file mode 100644 (file)
index f26894f..0000000
+++ /dev/null
@@ -1,919 +0,0 @@
-/*
- * 2007+ Copyright (c) Evgeniy Polyakov <zbr@ioremap.net>
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- */
-
-#ifndef __NETFS_H
-#define __NETFS_H
-
-#include <linux/types.h>
-#include <linux/connector.h>
-#include <linux/backing-dev.h>
-
-#define POHMELFS_CN_IDX                        5
-#define POHMELFS_CN_VAL                        0
-
-#define POHMELFS_CTLINFO_ACK           1
-#define POHMELFS_NOINFO_ACK            2
-
-#define POHMELFS_NULL_IDX              65535
-
-/*
- * Network command structure.
- * Will be extended.
- */
-struct netfs_cmd {
-       __u16                   cmd;    /* Command number */
-       __u16                   csize;  /* Attached crypto information size */
-       __u16                   cpad;   /* Attached padding size */
-       __u16                   ext;    /* External flags */
-       __u32                   size;   /* Size of the attached data */
-       __u32                   trans;  /* Transaction id */
-       __u64                   id;     /* Object ID to operate on. Used for feedback.*/
-       __u64                   start;  /* Start of the object. */
-       __u64                   iv;     /* IV sequence */
-       __u8                    data[0];
-};
-
-static inline void netfs_convert_cmd(struct netfs_cmd *cmd)
-{
-       cmd->id = __be64_to_cpu(cmd->id);
-       cmd->start = __be64_to_cpu(cmd->start);
-       cmd->iv = __be64_to_cpu(cmd->iv);
-       cmd->cmd = __be16_to_cpu(cmd->cmd);
-       cmd->ext = __be16_to_cpu(cmd->ext);
-       cmd->csize = __be16_to_cpu(cmd->csize);
-       cmd->cpad = __be16_to_cpu(cmd->cpad);
-       cmd->size = __be32_to_cpu(cmd->size);
-}
-
-#define NETFS_TRANS_SINGLE_DST         (1<<0)
-
-enum {
-       NETFS_READDIR   = 1,    /* Read directory for given inode number */
-       NETFS_READ_PAGE,        /* Read data page from the server */
-       NETFS_WRITE_PAGE,       /* Write data page to the server */
-       NETFS_CREATE,           /* Create directory entry */
-       NETFS_REMOVE,           /* Remove directory entry */
-
-       NETFS_LOOKUP,           /* Lookup single object */
-       NETFS_LINK,             /* Create a link */
-       NETFS_TRANS,            /* Transaction */
-       NETFS_OPEN,             /* Open intent */
-       NETFS_INODE_INFO,       /* Metadata cache coherency synchronization message */
-
-       NETFS_PAGE_CACHE,       /* Page cache invalidation message */
-       NETFS_READ_PAGES,       /* Read multiple contiguous pages in one go */
-       NETFS_RENAME,           /* Rename object */
-       NETFS_CAPABILITIES,     /* Capabilities of the client, for example supported crypto */
-       NETFS_LOCK,             /* Distributed lock message */
-
-       NETFS_XATTR_SET,        /* Set extended attribute */
-       NETFS_XATTR_GET,        /* Get extended attribute */
-       NETFS_CMD_MAX
-};
-
-enum {
-       POHMELFS_FLAGS_ADD = 0, /* Network state control message for ADD */
-       POHMELFS_FLAGS_DEL,     /* Network state control message for DEL */
-       POHMELFS_FLAGS_SHOW,    /* Network state control message for SHOW */
-       POHMELFS_FLAGS_CRYPTO,  /* Crypto data control message */
-       POHMELFS_FLAGS_MODIFY,  /* Network state modification message */
-       POHMELFS_FLAGS_DUMP,    /* Network state control message for SHOW ALL */
-       POHMELFS_FLAGS_FLUSH,   /* Network state control message for FLUSH */
-};
-
-/*
- * Always wanted to copy it from socket headers into public one,
- * since they are __KERNEL__ protected there.
- */
-#define _K_SS_MAXSIZE  128
-
-struct saddr {
-       unsigned short          sa_family;
-       char                    addr[_K_SS_MAXSIZE];
-};
-
-enum {
-       POHMELFS_CRYPTO_HASH = 0,
-       POHMELFS_CRYPTO_CIPHER,
-};
-
-struct pohmelfs_crypto {
-       unsigned int            idx;            /* Config index */
-       unsigned short          strlen;         /* Size of the attached crypto string including 0-byte
-                                                * "cbc(aes)" for example */
-       unsigned short          type;           /* HMAC, cipher, both */
-       unsigned int            keysize;        /* Key size */
-       unsigned char           data[0];        /* Algorithm string, key and IV */
-};
-
-#define POHMELFS_IO_PERM_READ          (1<<0)
-#define POHMELFS_IO_PERM_WRITE         (1<<1)
-
-/*
- * Configuration command used to create table of different remote servers.
- */
-struct pohmelfs_ctl {
-       __u32                   idx;            /* Config index */
-       __u32                   type;           /* Socket type */
-       __u32                   proto;          /* Socket protocol */
-       __u16                   addrlen;        /* Size of the address */
-       __u16                   perm;           /* IO permission */
-       __u16                   prio;           /* IO priority */
-       struct saddr            addr;           /* Remote server address */
-};
-
-/*
- * Ack for userspace about requested command.
- */
-struct pohmelfs_cn_ack {
-       struct cn_msg           msg;
-       int                     error;
-       int                     msg_num;
-       int                     unused[3];
-       struct pohmelfs_ctl     ctl;
-};
-
-/*
- * Inode info structure used to sync with server.
- * Check what stat() returns.
- */
-struct netfs_inode_info {
-       unsigned int            mode;
-       unsigned int            nlink;
-       unsigned int            uid;
-       unsigned int            gid;
-       unsigned int            blocksize;
-       unsigned int            padding;
-       __u64                   ino;
-       __u64                   blocks;
-       __u64                   rdev;
-       __u64                   size;
-       __u64                   version;
-};
-
-static inline void netfs_convert_inode_info(struct netfs_inode_info *info)
-{
-       info->mode = __cpu_to_be32(info->mode);
-       info->nlink = __cpu_to_be32(info->nlink);
-       info->uid = __cpu_to_be32(info->uid);
-       info->gid = __cpu_to_be32(info->gid);
-       info->blocksize = __cpu_to_be32(info->blocksize);
-       info->blocks = __cpu_to_be64(info->blocks);
-       info->rdev = __cpu_to_be64(info->rdev);
-       info->size = __cpu_to_be64(info->size);
-       info->version = __cpu_to_be64(info->version);
-       info->ino = __cpu_to_be64(info->ino);
-}
-
-/*
- * Cache state machine.
- */
-enum {
-       NETFS_COMMAND_PENDING = 0,      /* Command is being executed */
-       NETFS_INODE_REMOTE_SYNCED,      /* Inode was synced to server */
-       NETFS_INODE_REMOTE_DIR_SYNCED,  /* Inode (directory) was synced from the server */
-       NETFS_INODE_OWNED,              /* Inode is owned by given host */
-       NETFS_INODE_NEED_FLUSH,         /* Inode has to be flushed to the server */
-};
-
-/*
- * POHMELFS capabilities: information about supported
- * crypto operations (hash/cipher, modes, key sizes and so on),
- * root information (used/available size, number of objects, permissions)
- */
-enum pohmelfs_capabilities {
-       POHMELFS_CRYPTO_CAPABILITIES = 0,
-       POHMELFS_ROOT_CAPABILITIES,
-};
-
-/* Read-only mount */
-#define POHMELFS_FLAGS_RO              (1<<0)
-/* Extended attributes support on/off */
-#define POHMELFS_FLAGS_XATTR           (1<<1)
-
-struct netfs_root_capabilities {
-       __u64                   nr_files;
-       __u64                   used, avail;
-       __u64                   flags;
-};
-
-static inline void netfs_convert_root_capabilities(struct netfs_root_capabilities *cap)
-{
-       cap->nr_files = __cpu_to_be64(cap->nr_files);
-       cap->used = __cpu_to_be64(cap->used);
-       cap->avail = __cpu_to_be64(cap->avail);
-       cap->flags = __cpu_to_be64(cap->flags);
-}
-
-struct netfs_crypto_capabilities {
-       unsigned short          hash_strlen;    /* Hash string length, like "hmac(sha1) including 0 byte "*/
-       unsigned short          cipher_strlen;  /* Cipher string length with the same format */
-       unsigned int            cipher_keysize; /* Cipher key size */
-};
-
-static inline void netfs_convert_crypto_capabilities(struct netfs_crypto_capabilities *cap)
-{
-       cap->hash_strlen = __cpu_to_be16(cap->hash_strlen);
-       cap->cipher_strlen = __cpu_to_be16(cap->cipher_strlen);
-       cap->cipher_keysize = __cpu_to_be32(cap->cipher_keysize);
-}
-
-enum pohmelfs_lock_type {
-       POHMELFS_LOCK_GRAB      = (1<<15),
-
-       POHMELFS_READ_LOCK      = 0,
-       POHMELFS_WRITE_LOCK,
-};
-
-struct netfs_lock {
-       __u64                   start;
-       __u64                   ino;
-       __u32                   size;
-       __u32                   type;
-};
-
-static inline void netfs_convert_lock(struct netfs_lock *lock)
-{
-       lock->start = __cpu_to_be64(lock->start);
-       lock->ino = __cpu_to_be64(lock->ino);
-       lock->size = __cpu_to_be32(lock->size);
-       lock->type = __cpu_to_be32(lock->type);
-}
-
-#ifdef __KERNEL__
-
-#include <linux/kernel.h>
-#include <linux/completion.h>
-#include <linux/rbtree.h>
-#include <linux/net.h>
-#include <linux/poll.h>
-
-/*
- * Private POHMELFS cache of objects in directory.
- */
-struct pohmelfs_name {
-       struct rb_node          hash_node;
-
-       struct list_head        sync_create_entry;
-
-       u64                     ino;
-
-       u32                     hash;
-       u32                     mode;
-       u32                     len;
-
-       char                    *data;
-};
-
-/*
- * POHMELFS inode. Main object.
- */
-struct pohmelfs_inode {
-       struct list_head        inode_entry;            /* Entry in superblock list.
-                                                        * Objects which are not bound to dentry require to be dropped
-                                                        * in ->put_super()
-                                                        */
-       struct rb_root          hash_root;              /* The same, but indexed by name hash and len */
-       struct mutex            offset_lock;            /* Protect both above trees */
-
-       struct list_head        sync_create_list;       /* List of created but not yet synced to the server children */
-
-       unsigned int            drop_count;
-
-       int                     lock_type;              /* How this inode is locked: read or write */
-
-       int                     error;                  /* Transaction error for given inode */
-
-       long                    state;                  /* State machine above */
-
-       u64                     ino;                    /* Inode number */
-       u64                     total_len;              /* Total length of all children names, used to create offsets */
-
-       struct inode            vfs_inode;
-};
-
-struct netfs_trans;
-typedef int (*netfs_trans_complete_t)(struct page **pages, unsigned int page_num,
-               void *private, int err);
-
-struct netfs_state;
-struct pohmelfs_sb;
-
-struct netfs_trans {
-       /*
-        * Transaction header and attached contiguous data live here.
-        */
-       struct iovec                    iovec;
-
-       /*
-        * Pages attached to transaction.
-        */
-       struct page                     **pages;
-
-       /*
-        * List and protecting lock for transaction destination
-        * network states.
-        */
-       spinlock_t                      dst_lock;
-       struct list_head                dst_list;
-
-       /*
-        * Number of users for given transaction.
-        * For example each network state attached to transaction
-        * via dst_list increases it.
-        */
-       atomic_t                        refcnt;
-
-       /*
-        * Number of pages attached to given transaction.
-        * Some slots in above page array can be NULL, since
-        * for example page can be under writeback already,
-        * so we skip it in this transaction.
-        */
-       unsigned int                    page_num;
-
-       /*
-        * Transaction flags: single dst or broadcast and so on.
-        */
-       unsigned int                    flags;
-
-       /*
-        * Size of the data, which can be placed into
-        * iovec.iov_base area.
-        */
-       unsigned int                    total_size;
-
-       /*
-        * Number of pages to be sent to remote server.
-        * Usually equal to above page_num, but in case of partial
-        * writeback it can accumulate only pages already completed
-        * previous writeback.
-        */
-       unsigned int                    attached_pages;
-
-       /*
-        * Attached number of bytes in all above pages.
-        */
-       unsigned int                    attached_size;
-
-       /*
-        * Unique transacton generation number.
-        * Used as identity in the network state tree of transactions.
-        */
-       unsigned int                    gen;
-
-       /*
-        * Transaction completion status.
-        */
-       int                             result;
-
-       /*
-        * Superblock this transaction belongs to
-        */
-       struct pohmelfs_sb              *psb;
-
-       /*
-        * Crypto engine, which processed this transaction.
-        * Can be not NULL only if crypto engine holds encrypted pages.
-        */
-       struct pohmelfs_crypto_engine   *eng;
-
-       /* Private data */
-       void                            *private;
-
-       /* Completion callback, invoked just before transaction is destroyed */
-       netfs_trans_complete_t          complete;
-};
-
-static inline int netfs_trans_cur_len(struct netfs_trans *t)
-{
-       return (signed)(t->total_size - t->iovec.iov_len);
-}
-
-static inline void *netfs_trans_current(struct netfs_trans *t)
-{
-       return t->iovec.iov_base + t->iovec.iov_len;
-}
-
-struct netfs_trans *netfs_trans_alloc(struct pohmelfs_sb *psb, unsigned int size,
-               unsigned int flags, unsigned int nr);
-void netfs_trans_free(struct netfs_trans *t);
-int netfs_trans_finish(struct netfs_trans *t, struct pohmelfs_sb *psb);
-int netfs_trans_finish_send(struct netfs_trans *t, struct pohmelfs_sb *psb);
-
-static inline void netfs_trans_reset(struct netfs_trans *t)
-{
-       t->complete = NULL;
-}
-
-struct netfs_trans_dst {
-       struct list_head                trans_entry;
-       struct rb_node                  state_entry;
-
-       unsigned long                   send_time;
-
-       /*
-        * Times this transaction was resent to its old or new,
-        * depending on flags, destinations. When it reaches maximum
-        * allowed number, specified in superblock->trans_retries,
-        * transaction will be freed with ETIMEDOUT error.
-        */
-       unsigned int                    retries;
-
-       struct netfs_trans              *trans;
-       struct netfs_state              *state;
-};
-
-struct netfs_trans_dst *netfs_trans_search(struct netfs_state *st, unsigned int gen);
-void netfs_trans_drop_dst(struct netfs_trans_dst *dst);
-void netfs_trans_drop_dst_nostate(struct netfs_trans_dst *dst);
-void netfs_trans_drop_trans(struct netfs_trans *t, struct netfs_state *st);
-void netfs_trans_drop_last(struct netfs_trans *t, struct netfs_state *st);
-int netfs_trans_resend(struct netfs_trans *t, struct pohmelfs_sb *psb);
-int netfs_trans_remove_nolock(struct netfs_trans_dst *dst, struct netfs_state *st);
-
-int netfs_trans_init(void);
-void netfs_trans_exit(void);
-
-struct pohmelfs_crypto_engine {
-       u64                             iv;             /* Crypto IV for current operation */
-       unsigned long                   timeout;        /* Crypto waiting timeout */
-       unsigned int                    size;           /* Size of crypto scratchpad */
-       void                            *data;          /* Temporal crypto scratchpad */
-       /*
-        * Crypto operations performed on objects.
-        */
-       struct crypto_hash              *hash;
-       struct crypto_ablkcipher        *cipher;
-
-       struct pohmelfs_crypto_thread   *thread;        /* Crypto thread which hosts this engine */
-
-       struct page                     **pages;
-       unsigned int                    page_num;
-};
-
-struct pohmelfs_crypto_thread {
-       struct list_head                thread_entry;
-
-       struct task_struct              *thread;
-       struct pohmelfs_sb              *psb;
-
-       struct pohmelfs_crypto_engine   eng;
-
-       struct netfs_trans              *trans;
-
-       wait_queue_head_t               wait;
-       int                             error;
-
-       unsigned int                    size;
-       struct page                     *page;
-};
-
-void pohmelfs_crypto_thread_make_ready(struct pohmelfs_crypto_thread *th);
-
-/*
- * Network state, attached to one server.
- */
-struct netfs_state {
-       struct mutex            __state_lock;           /* Can not allow to use the same socket simultaneously */
-       struct mutex            __state_send_lock;
-       struct netfs_cmd        cmd;                    /* Cached command */
-       struct netfs_inode_info info;                   /* Cached inode info */
-
-       void                    *data;                  /* Cached some data */
-       unsigned int            size;                   /* Size of that data */
-
-       struct pohmelfs_sb      *psb;                   /* Superblock */
-
-       struct task_struct      *thread;                /* Async receiving thread */
-
-       /* Waiting/polling machinery */
-       wait_queue_t            wait;
-       wait_queue_head_t       *whead;
-       wait_queue_head_t       thread_wait;
-
-       struct mutex            trans_lock;
-       struct rb_root          trans_root;
-
-       struct pohmelfs_ctl     ctl;                    /* Remote peer */
-
-       struct socket           *socket;                /* Socket object */
-       struct socket           *read_socket;           /* Cached pointer to socket object.
-                                                        * Used to determine if between lock drops socket was changed.
-                                                        * Never used to read data or any kind of access.
-                                                        */
-       /*
-        * Crypto engines to process incoming data.
-        */
-       struct pohmelfs_crypto_engine   eng;
-
-       int                     need_reset;
-};
-
-int netfs_state_init(struct netfs_state *st);
-void netfs_state_exit(struct netfs_state *st);
-
-static inline void netfs_state_lock_send(struct netfs_state *st)
-{
-       mutex_lock(&st->__state_send_lock);
-}
-
-static inline int netfs_state_trylock_send(struct netfs_state *st)
-{
-       return mutex_trylock(&st->__state_send_lock);
-}
-
-static inline void netfs_state_unlock_send(struct netfs_state *st)
-{
-       BUG_ON(!mutex_is_locked(&st->__state_send_lock));
-
-       mutex_unlock(&st->__state_send_lock);
-}
-
-static inline void netfs_state_lock(struct netfs_state *st)
-{
-       mutex_lock(&st->__state_lock);
-}
-
-static inline void netfs_state_unlock(struct netfs_state *st)
-{
-       BUG_ON(!mutex_is_locked(&st->__state_lock));
-
-       mutex_unlock(&st->__state_lock);
-}
-
-static inline unsigned int netfs_state_poll(struct netfs_state *st)
-{
-       unsigned int revents = POLLHUP | POLLERR;
-
-       netfs_state_lock(st);
-       if (st->socket)
-               revents = st->socket->ops->poll(NULL, st->socket, NULL);
-       netfs_state_unlock(st);
-
-       return revents;
-}
-
-struct pohmelfs_config;
-
-struct pohmelfs_sb {
-       struct rb_root          mcache_root;
-       struct mutex            mcache_lock;
-       atomic_long_t           mcache_gen;
-       unsigned long           mcache_timeout;
-
-       unsigned int            idx;
-
-       unsigned int            trans_retries;
-
-       atomic_t                trans_gen;
-
-       unsigned int            crypto_attached_size;
-       unsigned int            crypto_align_size;
-
-       unsigned int            crypto_fail_unsupported;
-
-       unsigned int            crypto_thread_num;
-       struct list_head        crypto_active_list, crypto_ready_list;
-       struct mutex            crypto_thread_lock;
-
-       unsigned int            trans_max_pages;
-       unsigned long           trans_data_size;
-       unsigned long           trans_timeout;
-
-       unsigned long           drop_scan_timeout;
-       unsigned long           trans_scan_timeout;
-
-       unsigned long           wait_on_page_timeout;
-
-       struct list_head        flush_list;
-       struct list_head        drop_list;
-       spinlock_t              ino_lock;
-       u64                     ino;
-
-       /*
-        * Remote nodes POHMELFS connected to.
-        */
-       struct list_head        state_list;
-       struct mutex            state_lock;
-
-       /*
-        * Currently active state to request data from.
-        */
-       struct pohmelfs_config  *active_state;
-
-
-       wait_queue_head_t       wait;
-
-       /*
-        * Timed checks: stale transactions, inodes to be freed and so on.
-        */
-       struct delayed_work     dwork;
-       struct delayed_work     drop_dwork;
-
-       struct super_block      *sb;
-
-       struct backing_dev_info bdi;
-
-       /*
-        * Algorithm strings.
-        */
-       char                    *hash_string;
-       char                    *cipher_string;
-
-       u8                      *hash_key;
-       u8                      *cipher_key;
-
-       /*
-        * Algorithm string lengths.
-        */
-       unsigned int            hash_strlen;
-       unsigned int            cipher_strlen;
-       unsigned int            hash_keysize;
-       unsigned int            cipher_keysize;
-
-       /*
-        * Controls whether to perfrom crypto processing or not.
-        */
-       int                     perform_crypto;
-
-       /*
-        * POHMELFS statistics.
-        */
-       u64                     total_size;
-       u64                     avail_size;
-       atomic_long_t           total_inodes;
-
-       /*
-        * Xattr support, read-only and so on.
-        */
-       u64                     state_flags;
-
-       /*
-        * Temporary storage to detect changes in the wait queue.
-        */
-       long                    flags;
-};
-
-static inline void netfs_trans_update(struct netfs_cmd *cmd,
-               struct netfs_trans *t, unsigned int size)
-{
-       unsigned int sz = ALIGN(size, t->psb->crypto_align_size);
-
-       t->iovec.iov_len += sizeof(struct netfs_cmd) + sz;
-       cmd->cpad = __cpu_to_be16(sz - size);
-}
-
-static inline struct pohmelfs_sb *POHMELFS_SB(struct super_block *sb)
-{
-       return sb->s_fs_info;
-}
-
-static inline struct pohmelfs_inode *POHMELFS_I(struct inode *inode)
-{
-       return container_of(inode, struct pohmelfs_inode, vfs_inode);
-}
-
-static inline u64 pohmelfs_new_ino(struct pohmelfs_sb *psb)
-{
-       u64 ino;
-
-       spin_lock(&psb->ino_lock);
-       ino = psb->ino++;
-       spin_unlock(&psb->ino_lock);
-
-       return ino;
-}
-
-static inline void pohmelfs_put_inode(struct pohmelfs_inode *pi)
-{
-       struct pohmelfs_sb *psb = POHMELFS_SB(pi->vfs_inode.i_sb);
-
-       spin_lock(&psb->ino_lock);
-       list_move_tail(&pi->inode_entry, &psb->drop_list);
-       pi->drop_count++;
-       spin_unlock(&psb->ino_lock);
-}
-
-struct pohmelfs_config {
-       struct list_head        config_entry;
-
-       struct netfs_state      state;
-};
-
-struct pohmelfs_config_group {
-       /*
-        * Entry in the global config group list.
-        */
-       struct list_head        group_entry;
-
-       /*
-        * Index of the current group.
-        */
-       unsigned int            idx;
-       /*
-        * Number of config_list entries in this group entry.
-        */
-       unsigned int            num_entry;
-       /*
-        * Algorithm strings.
-        */
-       char                    *hash_string;
-       char                    *cipher_string;
-
-       /*
-        * Algorithm string lengths.
-        */
-       unsigned int            hash_strlen;
-       unsigned int            cipher_strlen;
-
-       /*
-        * Key and its size.
-        */
-       unsigned int            hash_keysize;
-       unsigned int            cipher_keysize;
-       u8                      *hash_key;
-       u8                      *cipher_key;
-
-       /*
-        * List of config entries (network state info) for given idx.
-        */
-       struct list_head        config_list;
-};
-
-int __init pohmelfs_config_init(void);
-void pohmelfs_config_exit(void);
-int pohmelfs_copy_config(struct pohmelfs_sb *psb);
-int pohmelfs_copy_crypto(struct pohmelfs_sb *psb);
-int pohmelfs_config_check(struct pohmelfs_config *config, int idx);
-int pohmelfs_state_init_one(struct pohmelfs_sb *psb, struct pohmelfs_config *conf);
-
-extern const struct file_operations pohmelfs_dir_fops;
-extern const struct inode_operations pohmelfs_dir_inode_ops;
-
-int pohmelfs_state_init(struct pohmelfs_sb *psb);
-void pohmelfs_state_exit(struct pohmelfs_sb *psb);
-void pohmelfs_state_flush_transactions(struct netfs_state *st);
-
-void pohmelfs_fill_inode(struct inode *inode, struct netfs_inode_info *info);
-
-void pohmelfs_name_del(struct pohmelfs_inode *parent, struct pohmelfs_name *n);
-void pohmelfs_free_names(struct pohmelfs_inode *parent);
-struct pohmelfs_name *pohmelfs_search_hash(struct pohmelfs_inode *pi, u32 hash);
-
-void pohmelfs_inode_del_inode(struct pohmelfs_sb *psb, struct pohmelfs_inode *pi);
-
-struct pohmelfs_inode *pohmelfs_create_entry_local(struct pohmelfs_sb *psb,
-       struct pohmelfs_inode *parent, struct qstr *str, u64 start, umode_t mode);
-
-int pohmelfs_write_create_inode(struct pohmelfs_inode *pi);
-
-int pohmelfs_write_inode_create(struct inode *inode, struct netfs_trans *trans);
-int pohmelfs_remove_child(struct pohmelfs_inode *parent, struct pohmelfs_name *n);
-
-struct pohmelfs_inode *pohmelfs_new_inode(struct pohmelfs_sb *psb,
-               struct pohmelfs_inode *parent, struct qstr *str,
-               struct netfs_inode_info *info, int link);
-
-int pohmelfs_setattr(struct dentry *dentry, struct iattr *attr);
-int pohmelfs_setattr_raw(struct inode *inode, struct iattr *attr);
-
-int pohmelfs_meta_command(struct pohmelfs_inode *pi, unsigned int cmd_op, unsigned int flags,
-               netfs_trans_complete_t complete, void *priv, u64 start);
-int pohmelfs_meta_command_data(struct pohmelfs_inode *pi, u64 id, unsigned int cmd_op, char *addon,
-               unsigned int flags, netfs_trans_complete_t complete, void *priv, u64 start);
-
-void pohmelfs_check_states(struct pohmelfs_sb *psb);
-void pohmelfs_switch_active(struct pohmelfs_sb *psb);
-
-int pohmelfs_construct_path_string(struct pohmelfs_inode *pi, void *data, int len);
-int pohmelfs_path_length(struct pohmelfs_inode *pi);
-
-struct pohmelfs_crypto_completion {
-       struct completion       complete;
-       int                     error;
-};
-
-int pohmelfs_trans_crypt(struct netfs_trans *t, struct pohmelfs_sb *psb);
-void pohmelfs_crypto_exit(struct pohmelfs_sb *psb);
-int pohmelfs_crypto_init(struct pohmelfs_sb *psb);
-
-int pohmelfs_crypto_engine_init(struct pohmelfs_crypto_engine *e, struct pohmelfs_sb *psb);
-void pohmelfs_crypto_engine_exit(struct pohmelfs_crypto_engine *e);
-
-int pohmelfs_crypto_process_input_data(struct pohmelfs_crypto_engine *e, u64 iv,
-               void *data, struct page *page, unsigned int size);
-int pohmelfs_crypto_process_input_page(struct pohmelfs_crypto_engine *e,
-               struct page *page, unsigned int size, u64 iv);
-
-static inline u64 pohmelfs_gen_iv(struct netfs_trans *t)
-{
-       u64 iv = t->gen;
-
-       iv <<= 32;
-       iv |= ((unsigned long)t) & 0xffffffff;
-
-       return iv;
-}
-
-int pohmelfs_data_lock(struct pohmelfs_inode *pi, u64 start, u32 size, int type);
-int pohmelfs_data_unlock(struct pohmelfs_inode *pi, u64 start, u32 size, int type);
-int pohmelfs_data_lock_response(struct netfs_state *st);
-
-static inline int pohmelfs_need_lock(struct pohmelfs_inode *pi, int type)
-{
-       if (test_bit(NETFS_INODE_OWNED, &pi->state)) {
-               if (type == pi->lock_type)
-                       return 0;
-               if ((type == POHMELFS_READ_LOCK) && (pi->lock_type == POHMELFS_WRITE_LOCK))
-                       return 0;
-       }
-
-       if (!test_bit(NETFS_INODE_REMOTE_SYNCED, &pi->state))
-               return 0;
-
-       return 1;
-}
-
-int __init pohmelfs_mcache_init(void);
-void pohmelfs_mcache_exit(void);
-
-/* #define CONFIG_POHMELFS_DEBUG */
-
-#ifdef CONFIG_POHMELFS_DEBUG
-#define dprintka(f, a...) printk(f, ##a)
-#define dprintk(f, a...) printk("%d: " f, task_pid_vnr(current), ##a)
-#else
-#define dprintka(f, a...) do {} while (0)
-#define dprintk(f, a...) do {} while (0)
-#endif
-
-static inline void netfs_trans_get(struct netfs_trans *t)
-{
-       atomic_inc(&t->refcnt);
-}
-
-static inline void netfs_trans_put(struct netfs_trans *t)
-{
-       if (atomic_dec_and_test(&t->refcnt)) {
-               dprintk("%s: t: %p, gen: %u, err: %d.\n",
-                       __func__, t, t->gen, t->result);
-               if (t->complete)
-                       t->complete(t->pages, t->page_num,
-                               t->private, t->result);
-               netfs_trans_free(t);
-       }
-}
-
-struct pohmelfs_mcache {
-       struct rb_node                  mcache_entry;
-       struct completion               complete;
-
-       atomic_t                        refcnt;
-
-       u64                             gen;
-
-       void                            *data;
-       u64                             start;
-       u32                             size;
-       int                             err;
-
-       struct netfs_inode_info         info;
-};
-
-struct pohmelfs_mcache *pohmelfs_mcache_alloc(struct pohmelfs_sb *psb, u64 start,
-               unsigned int size, void *data);
-void pohmelfs_mcache_free(struct pohmelfs_sb *psb, struct pohmelfs_mcache *m);
-struct pohmelfs_mcache *pohmelfs_mcache_search(struct pohmelfs_sb *psb, u64 gen);
-void pohmelfs_mcache_remove_locked(struct pohmelfs_sb *psb, struct pohmelfs_mcache *m);
-
-static inline void pohmelfs_mcache_get(struct pohmelfs_mcache *m)
-{
-       atomic_inc(&m->refcnt);
-}
-
-static inline void pohmelfs_mcache_put(struct pohmelfs_sb *psb,
-               struct pohmelfs_mcache *m)
-{
-       if (atomic_dec_and_test(&m->refcnt))
-               pohmelfs_mcache_free(psb, m);
-}
-
-/*#define POHMELFS_TRUNCATE_ON_INODE_FLUSH
- */
-
-#endif /* __KERNEL__*/
-
-#endif /* __NETFS_H */
diff --git a/drivers/staging/pohmelfs/path_entry.c b/drivers/staging/pohmelfs/path_entry.c
deleted file mode 100644 (file)
index 400a9fc..0000000
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * 2007+ Copyright (c) Evgeniy Polyakov <zbr@ioremap.net>
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- */
-
-#include <linux/module.h>
-#include <linux/fs.h>
-#include <linux/ktime.h>
-#include <linux/fs_struct.h>
-#include <linux/pagemap.h>
-#include <linux/writeback.h>
-#include <linux/mount.h>
-#include <linux/mm.h>
-
-#include "netfs.h"
-
-#define UNHASHED_OBSCURE_STRING_SIZE           sizeof(" (deleted)")
-
-/*
- * Create path from root for given inode.
- * Path is formed as set of stuctures, containing name of the object
- * and its inode data (mode, permissions and so on).
- */
-int pohmelfs_construct_path_string(struct pohmelfs_inode *pi, void *data, int len)
-{
-       struct path path;
-       struct dentry *d;
-       char *ptr;
-       int err = 0, strlen, reduce = 0;
-
-       d = d_find_alias(&pi->vfs_inode);
-       if (!d) {
-               printk("%s: no alias, list_empty: %d.\n", __func__, list_empty(&pi->vfs_inode.i_dentry));
-               return -ENOENT;
-       }
-
-       spin_lock(&current->fs->lock);
-       path.mnt = mntget(current->fs->root.mnt);
-       spin_unlock(&current->fs->lock);
-
-       path.dentry = d;
-
-       if (!IS_ROOT(d) && d_unhashed(d))
-               reduce = 1;
-
-       ptr = d_path(&path, data, len);
-       if (IS_ERR(ptr)) {
-               err = PTR_ERR(ptr);
-               goto out;
-       }
-
-       if (reduce && len >= UNHASHED_OBSCURE_STRING_SIZE) {
-               char *end = data + len - UNHASHED_OBSCURE_STRING_SIZE;
-               *end = '\0';
-       }
-
-       strlen = len - (ptr - (char *)data);
-       memmove(data, ptr, strlen);
-       ptr = data;
-
-       err = strlen;
-
-       dprintk("%s: dname: '%s', len: %u, maxlen: %u, name: '%s', strlen: %d.\n",
-                       __func__, d->d_name.name, d->d_name.len, len, ptr, strlen);
-
-out:
-       dput(d);
-       mntput(path.mnt);
-
-       return err;
-}
-
-int pohmelfs_path_length(struct pohmelfs_inode *pi)
-{
-       struct dentry *d, *root, *first;
-       int len;
-       unsigned seq;
-
-       first = d_find_alias(&pi->vfs_inode);
-       if (!first) {
-               dprintk("%s: ino: %llu, mode: %o.\n", __func__, pi->ino, pi->vfs_inode.i_mode);
-               return -ENOENT;
-       }
-
-       spin_lock(&current->fs->lock);
-       root = dget(current->fs->root.dentry);
-       spin_unlock(&current->fs->lock);
-
-rename_retry:
-       len = 1; /* Root slash */
-       d = first;
-       seq = read_seqbegin(&rename_lock);
-       rcu_read_lock();
-
-       if (!IS_ROOT(d) && d_unhashed(d))
-               len += UNHASHED_OBSCURE_STRING_SIZE; /* Obscure " (deleted)" string */
-
-       while (d && d != root && !IS_ROOT(d)) {
-               len += d->d_name.len + 1; /* Plus slash */
-               d = d->d_parent;
-       }
-       rcu_read_unlock();
-       if (read_seqretry(&rename_lock, seq))
-               goto rename_retry;
-
-       dput(root);
-       dput(first);
-
-       return len + 1; /* Including zero-byte */
-}
diff --git a/drivers/staging/pohmelfs/trans.c b/drivers/staging/pohmelfs/trans.c
deleted file mode 100644 (file)
index 06c1a74..0000000
+++ /dev/null
@@ -1,706 +0,0 @@
-/*
- * 2007+ Copyright (c) Evgeniy Polyakov <zbr@ioremap.net>
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- */
-
-#include <linux/module.h>
-#include <linux/crypto.h>
-#include <linux/fs.h>
-#include <linux/jhash.h>
-#include <linux/hash.h>
-#include <linux/ktime.h>
-#include <linux/mempool.h>
-#include <linux/mm.h>
-#include <linux/mount.h>
-#include <linux/pagemap.h>
-#include <linux/parser.h>
-#include <linux/poll.h>
-#include <linux/swap.h>
-#include <linux/slab.h>
-#include <linux/statfs.h>
-#include <linux/writeback.h>
-
-#include "netfs.h"
-
-static struct kmem_cache *netfs_trans_dst;
-static mempool_t *netfs_trans_dst_pool;
-
-static void netfs_trans_init_static(struct netfs_trans *t, int num, int size)
-{
-       t->page_num = num;
-       t->total_size = size;
-       atomic_set(&t->refcnt, 1);
-
-       spin_lock_init(&t->dst_lock);
-       INIT_LIST_HEAD(&t->dst_list);
-}
-
-static int netfs_trans_send_pages(struct netfs_trans *t, struct netfs_state *st)
-{
-       int err = 0;
-       unsigned int i, attached_pages = t->attached_pages, ci;
-       struct msghdr msg;
-       struct page **pages = (t->eng) ? t->eng->pages : t->pages;
-       struct page *p;
-       unsigned int size;
-
-       msg.msg_name = NULL;
-       msg.msg_namelen = 0;
-       msg.msg_control = NULL;
-       msg.msg_controllen = 0;
-       msg.msg_flags = MSG_WAITALL | MSG_MORE;
-
-       ci = 0;
-       for (i = 0; i < t->page_num; ++i) {
-               struct page *page = pages[ci];
-               struct netfs_cmd cmd;
-               struct iovec io;
-
-               p = t->pages[i];
-
-               if (!p)
-                       continue;
-
-               size = page_private(p);
-
-               io.iov_base = &cmd;
-               io.iov_len = sizeof(struct netfs_cmd);
-
-               cmd.cmd = NETFS_WRITE_PAGE;
-               cmd.ext = 0;
-               cmd.id = 0;
-               cmd.size = size;
-               cmd.start = p->index;
-               cmd.start <<= PAGE_CACHE_SHIFT;
-               cmd.csize = 0;
-               cmd.cpad = 0;
-               cmd.iv = pohmelfs_gen_iv(t);
-
-               netfs_convert_cmd(&cmd);
-
-               msg.msg_iov = &io;
-               msg.msg_iovlen = 1;
-               msg.msg_flags = MSG_WAITALL | MSG_MORE;
-
-               err = kernel_sendmsg(st->socket, &msg, (struct kvec *)msg.msg_iov, 1, sizeof(struct netfs_cmd));
-               if (err <= 0) {
-                       printk("%s: %d/%d failed to send transaction header: t: %p, gen: %u, err: %d.\n",
-                                       __func__, i, t->page_num, t, t->gen, err);
-                       if (err == 0)
-                               err = -ECONNRESET;
-                       goto err_out;
-               }
-
-               msg.msg_flags = MSG_WAITALL | (attached_pages == 1 ? 0 :
-                               MSG_MORE);
-
-               err = kernel_sendpage(st->socket, page, 0, size, msg.msg_flags);
-               if (err <= 0) {
-                       printk("%s: %d/%d failed to send transaction page: t: %p, gen: %u, size: %u, err: %d.\n",
-                                       __func__, i, t->page_num, t, t->gen, size, err);
-                       if (err == 0)
-                               err = -ECONNRESET;
-                       goto err_out;
-               }
-
-               dprintk("%s: %d/%d sent t: %p, gen: %u, page: %p/%p, size: %u.\n",
-                       __func__, i, t->page_num, t, t->gen, page, p, size);
-
-               err = 0;
-               attached_pages--;
-               if (!attached_pages)
-                       break;
-               ci++;
-
-               continue;
-
-err_out:
-               printk("%s: t: %p, gen: %u, err: %d.\n", __func__, t, t->gen, err);
-               netfs_state_exit(st);
-               break;
-       }
-
-       return err;
-}
-
-int netfs_trans_send(struct netfs_trans *t, struct netfs_state *st)
-{
-       int err;
-       struct msghdr msg;
-
-       BUG_ON(!t->iovec.iov_len);
-       BUG_ON(t->iovec.iov_len > 1024*1024*1024);
-
-       netfs_state_lock_send(st);
-       if (!st->socket) {
-               err = netfs_state_init(st);
-               if (err)
-                       goto err_out_unlock_return;
-       }
-
-       msg.msg_iov = &t->iovec;
-       msg.msg_iovlen = 1;
-       msg.msg_name = NULL;
-       msg.msg_namelen = 0;
-       msg.msg_control = NULL;
-       msg.msg_controllen = 0;
-       msg.msg_flags = MSG_WAITALL;
-
-       if (t->attached_pages)
-               msg.msg_flags |= MSG_MORE;
-
-       err = kernel_sendmsg(st->socket, &msg, (struct kvec *)msg.msg_iov, 1, t->iovec.iov_len);
-       if (err <= 0) {
-               printk("%s: failed to send contig transaction: t: %p, gen: %u, size: %zu, err: %d.\n",
-                               __func__, t, t->gen, t->iovec.iov_len, err);
-               if (err == 0)
-                       err = -ECONNRESET;
-               goto err_out_unlock_return;
-       }
-
-       dprintk("%s: sent %s transaction: t: %p, gen: %u, size: %zu, page_num: %u.\n",
-                       __func__, (t->page_num) ? "partial" : "full",
-                       t, t->gen, t->iovec.iov_len, t->page_num);
-
-       err = 0;
-       if (t->attached_pages)
-               err = netfs_trans_send_pages(t, st);
-
-err_out_unlock_return:
-
-       if (st->need_reset)
-               netfs_state_exit(st);
-
-       netfs_state_unlock_send(st);
-
-       dprintk("%s: t: %p, gen: %u, err: %d.\n",
-               __func__, t, t->gen, err);
-
-       t->result = err;
-       return err;
-}
-
-static inline int netfs_trans_cmp(unsigned int gen, unsigned int new)
-{
-       if (gen < new)
-               return 1;
-       if (gen > new)
-               return -1;
-       return 0;
-}
-
-struct netfs_trans_dst *netfs_trans_search(struct netfs_state *st, unsigned int gen)
-{
-       struct rb_root *root = &st->trans_root;
-       struct rb_node *n = root->rb_node;
-       struct netfs_trans_dst *tmp, *ret = NULL;
-       struct netfs_trans *t;
-       int cmp;
-
-       while (n) {
-               tmp = rb_entry(n, struct netfs_trans_dst, state_entry);
-               t = tmp->trans;
-
-               cmp = netfs_trans_cmp(t->gen, gen);
-               if (cmp < 0)
-                       n = n->rb_left;
-               else if (cmp > 0)
-                       n = n->rb_right;
-               else {
-                       ret = tmp;
-                       break;
-               }
-       }
-
-       return ret;
-}
-
-static int netfs_trans_insert(struct netfs_trans_dst *ndst, struct netfs_state *st)
-{
-       struct rb_root *root = &st->trans_root;
-       struct rb_node **n = &root->rb_node, *parent = NULL;
-       struct netfs_trans_dst *ret = NULL, *tmp;
-       struct netfs_trans *t = NULL, *new = ndst->trans;
-       int cmp;
-
-       while (*n) {
-               parent = *n;
-
-               tmp = rb_entry(parent, struct netfs_trans_dst, state_entry);
-               t = tmp->trans;
-
-               cmp = netfs_trans_cmp(t->gen, new->gen);
-               if (cmp < 0)
-                       n = &parent->rb_left;
-               else if (cmp > 0)
-                       n = &parent->rb_right;
-               else {
-                       ret = tmp;
-                       break;
-               }
-       }
-
-       if (ret) {
-               printk("%s: exist: old: gen: %u, flags: %x, send_time: %lu, "
-                               "new: gen: %u, flags: %x, send_time: %lu.\n",
-                       __func__, t->gen, t->flags, ret->send_time,
-                       new->gen, new->flags, ndst->send_time);
-               return -EEXIST;
-       }
-
-       rb_link_node(&ndst->state_entry, parent, n);
-       rb_insert_color(&ndst->state_entry, root);
-       ndst->send_time = jiffies;
-
-       return 0;
-}
-
-int netfs_trans_remove_nolock(struct netfs_trans_dst *dst, struct netfs_state *st)
-{
-       if (dst && dst->state_entry.rb_parent_color) {
-               rb_erase(&dst->state_entry, &st->trans_root);
-               dst->state_entry.rb_parent_color = 0;
-               return 1;
-       }
-       return 0;
-}
-
-static int netfs_trans_remove_state(struct netfs_trans_dst *dst)
-{
-       int ret;
-       struct netfs_state *st = dst->state;
-
-       mutex_lock(&st->trans_lock);
-       ret = netfs_trans_remove_nolock(dst, st);
-       mutex_unlock(&st->trans_lock);
-
-       return ret;
-}
-
-/*
- * Create new destination for given transaction associated with given network state.
- * Transaction's reference counter is bumped and will be dropped when either
- * reply is received or when async timeout detection task will fail resending
- * and drop transaction.
- */
-static int netfs_trans_push_dst(struct netfs_trans *t, struct netfs_state *st)
-{
-       struct netfs_trans_dst *dst;
-       int err;
-
-       dst = mempool_alloc(netfs_trans_dst_pool, GFP_KERNEL);
-       if (!dst)
-               return -ENOMEM;
-
-       dst->retries = 0;
-       dst->send_time = 0;
-       dst->state = st;
-       dst->trans = t;
-       netfs_trans_get(t);
-
-       mutex_lock(&st->trans_lock);
-       err = netfs_trans_insert(dst, st);
-       mutex_unlock(&st->trans_lock);
-
-       if (err)
-               goto err_out_free;
-
-       spin_lock(&t->dst_lock);
-       list_add_tail(&dst->trans_entry, &t->dst_list);
-       spin_unlock(&t->dst_lock);
-
-       return 0;
-
-err_out_free:
-       t->result = err;
-       netfs_trans_put(t);
-       mempool_free(dst, netfs_trans_dst_pool);
-       return err;
-}
-
-static void netfs_trans_free_dst(struct netfs_trans_dst *dst)
-{
-       netfs_trans_put(dst->trans);
-       mempool_free(dst, netfs_trans_dst_pool);
-}
-
-static void netfs_trans_remove_dst(struct netfs_trans_dst *dst)
-{
-       if (netfs_trans_remove_state(dst))
-               netfs_trans_free_dst(dst);
-}
-
-/*
- * Drop destination transaction entry when we know it.
- */
-void netfs_trans_drop_dst(struct netfs_trans_dst *dst)
-{
-       struct netfs_trans *t = dst->trans;
-
-       spin_lock(&t->dst_lock);
-       list_del_init(&dst->trans_entry);
-       spin_unlock(&t->dst_lock);
-
-       netfs_trans_remove_dst(dst);
-}
-
-/*
- * Drop destination transaction entry when we know it and when we
- * already removed dst from state tree.
- */
-void netfs_trans_drop_dst_nostate(struct netfs_trans_dst *dst)
-{
-       struct netfs_trans *t = dst->trans;
-
-       spin_lock(&t->dst_lock);
-       list_del_init(&dst->trans_entry);
-       spin_unlock(&t->dst_lock);
-
-       netfs_trans_free_dst(dst);
-}
-
-/*
- * This drops destination transaction entry from appropriate network state
- * tree and drops related reference counter. It is possible that transaction
- * will be freed here if its reference counter hits zero.
- * Destination transaction entry will be freed.
- */
-void netfs_trans_drop_trans(struct netfs_trans *t, struct netfs_state *st)
-{
-       struct netfs_trans_dst *dst, *tmp, *ret = NULL;
-
-       spin_lock(&t->dst_lock);
-       list_for_each_entry_safe(dst, tmp, &t->dst_list, trans_entry) {
-               if (dst->state == st) {
-                       ret = dst;
-                       list_del(&dst->trans_entry);
-                       break;
-               }
-       }
-       spin_unlock(&t->dst_lock);
-
-       if (ret)
-               netfs_trans_remove_dst(ret);
-}
-
-/*
- * This drops destination transaction entry from appropriate network state
- * tree and drops related reference counter. It is possible that transaction
- * will be freed here if its reference counter hits zero.
- * Destination transaction entry will be freed.
- */
-void netfs_trans_drop_last(struct netfs_trans *t, struct netfs_state *st)
-{
-       struct netfs_trans_dst *dst, *tmp, *ret;
-
-       spin_lock(&t->dst_lock);
-       ret = list_entry(t->dst_list.prev, struct netfs_trans_dst, trans_entry);
-       if (ret->state != st) {
-               ret = NULL;
-               list_for_each_entry_safe(dst, tmp, &t->dst_list, trans_entry) {
-                       if (dst->state == st) {
-                               ret = dst;
-                               list_del_init(&dst->trans_entry);
-                               break;
-                       }
-               }
-       } else {
-               list_del(&ret->trans_entry);
-       }
-       spin_unlock(&t->dst_lock);
-
-       if (ret)
-               netfs_trans_remove_dst(ret);
-}
-
-static int netfs_trans_push(struct netfs_trans *t, struct netfs_state *st)
-{
-       int err;
-
-       err = netfs_trans_push_dst(t, st);
-       if (err)
-               return err;
-
-       err = netfs_trans_send(t, st);
-       if (err)
-               goto err_out_free;
-
-       if (t->flags & NETFS_TRANS_SINGLE_DST)
-               pohmelfs_switch_active(st->psb);
-
-       return 0;
-
-err_out_free:
-       t->result = err;
-       netfs_trans_drop_last(t, st);
-
-       return err;
-}
-
-int netfs_trans_finish_send(struct netfs_trans *t, struct pohmelfs_sb *psb)
-{
-       struct pohmelfs_config *c;
-       int err = -ENODEV;
-       struct netfs_state *st;
-#if 0
-       dprintk("%s: t: %p, gen: %u, size: %u, page_num: %u, active: %p.\n",
-               __func__, t, t->gen, t->iovec.iov_len, t->page_num, psb->active_state);
-#endif
-       mutex_lock(&psb->state_lock);
-       list_for_each_entry(c, &psb->state_list, config_entry) {
-               st = &c->state;
-
-               if (t->flags & NETFS_TRANS_SINGLE_DST) {
-                       if (!(st->ctl.perm & POHMELFS_IO_PERM_READ))
-                               continue;
-               } else {
-                       if (!(st->ctl.perm & POHMELFS_IO_PERM_WRITE))
-                               continue;
-               }
-
-               if (psb->active_state && (psb->active_state->state.ctl.prio >= st->ctl.prio) &&
-                               (t->flags & NETFS_TRANS_SINGLE_DST))
-                       st = &psb->active_state->state;
-
-               err = netfs_trans_push(t, st);
-               if (!err && (t->flags & NETFS_TRANS_SINGLE_DST))
-                       break;
-       }
-
-       mutex_unlock(&psb->state_lock);
-#if 0
-       dprintk("%s: fully sent t: %p, gen: %u, size: %u, page_num: %u, err: %d.\n",
-               __func__, t, t->gen, t->iovec.iov_len, t->page_num, err);
-#endif
-       if (err)
-               t->result = err;
-       return err;
-}
-
-int netfs_trans_finish(struct netfs_trans *t, struct pohmelfs_sb *psb)
-{
-       int err;
-       struct netfs_cmd *cmd = t->iovec.iov_base;
-
-       t->gen = atomic_inc_return(&psb->trans_gen);
-
-       cmd->size = t->iovec.iov_len - sizeof(struct netfs_cmd) +
-               t->attached_size + t->attached_pages * sizeof(struct netfs_cmd);
-       cmd->cmd = NETFS_TRANS;
-       cmd->start = t->gen;
-       cmd->id = 0;
-
-       if (psb->perform_crypto) {
-               cmd->ext = psb->crypto_attached_size;
-               cmd->csize = psb->crypto_attached_size;
-       }
-
-       dprintk("%s: t: %u, size: %u, iov_len: %zu, attached_size: %u, attached_pages: %u.\n",
-                       __func__, t->gen, cmd->size, t->iovec.iov_len, t->attached_size, t->attached_pages);
-       err = pohmelfs_trans_crypt(t, psb);
-       if (err) {
-               t->result = err;
-               netfs_convert_cmd(cmd);
-               dprintk("%s: trans: %llu, crypto_attached_size: %u, attached_size: %u, attached_pages: %d, trans_size: %u, err: %d.\n",
-                       __func__, cmd->start, psb->crypto_attached_size, t->attached_size, t->attached_pages, cmd->size, err);
-       }
-       netfs_trans_put(t);
-       return err;
-}
-
-/*
- * Resend transaction to remote server(s).
- * If new servers were added into superblock, we can try to send data
- * to them too.
- *
- * It is called under superblock's state_lock, so we can safely
- * dereference psb->state_list. Also, transaction's reference counter is
- * bumped, so it can not go away under us, thus we can safely access all
- * its members. State is locked.
- *
- * This function returns 0 if transaction was successfully sent to at
- * least one destination target.
- */
-int netfs_trans_resend(struct netfs_trans *t, struct pohmelfs_sb *psb)
-{
-       struct netfs_trans_dst *dst;
-       struct netfs_state *st;
-       struct pohmelfs_config *c;
-       int err, exist, error = -ENODEV;
-
-       list_for_each_entry(c, &psb->state_list, config_entry) {
-               st = &c->state;
-
-               exist = 0;
-               spin_lock(&t->dst_lock);
-               list_for_each_entry(dst, &t->dst_list, trans_entry) {
-                       if (st == dst->state) {
-                               exist = 1;
-                               break;
-                       }
-               }
-               spin_unlock(&t->dst_lock);
-
-               if (exist) {
-                       if (!(t->flags & NETFS_TRANS_SINGLE_DST) ||
-                                       (c->config_entry.next == &psb->state_list)) {
-                               dprintk("%s: resending st: %p, t: %p, gen: %u.\n",
-                                               __func__, st, t, t->gen);
-                               err = netfs_trans_send(t, st);
-                               if (!err)
-                                       error = 0;
-                       }
-                       continue;
-               }
-
-               dprintk("%s: pushing/resending st: %p, t: %p, gen: %u.\n",
-                               __func__, st, t, t->gen);
-               err = netfs_trans_push(t, st);
-               if (err)
-                       continue;
-               error = 0;
-               if (t->flags & NETFS_TRANS_SINGLE_DST)
-                       break;
-       }
-
-       t->result = error;
-       return error;
-}
-
-void *netfs_trans_add(struct netfs_trans *t, unsigned int size)
-{
-       struct iovec *io = &t->iovec;
-       void *ptr;
-
-       if (size > t->total_size) {
-               ptr = ERR_PTR(-EINVAL);
-               goto out;
-       }
-
-       if (io->iov_len + size > t->total_size) {
-               dprintk("%s: too big size t: %p, gen: %u, iov_len: %zu, size: %u, total: %u.\n",
-                               __func__, t, t->gen, io->iov_len, size, t->total_size);
-               ptr = ERR_PTR(-E2BIG);
-               goto out;
-       }
-
-       ptr = io->iov_base + io->iov_len;
-       io->iov_len += size;
-
-out:
-       dprintk("%s: t: %p, gen: %u, size: %u, total: %zu.\n",
-               __func__, t, t->gen, size, io->iov_len);
-       return ptr;
-}
-
-void netfs_trans_free(struct netfs_trans *t)
-{
-       if (t->eng)
-               pohmelfs_crypto_thread_make_ready(t->eng->thread);
-       kfree(t);
-}
-
-struct netfs_trans *netfs_trans_alloc(struct pohmelfs_sb *psb, unsigned int size,
-               unsigned int flags, unsigned int nr)
-{
-       struct netfs_trans *t;
-       unsigned int num, cont, pad, size_no_trans;
-       unsigned int crypto_added = 0;
-       struct netfs_cmd *cmd;
-
-       if (psb->perform_crypto)
-               crypto_added = psb->crypto_attached_size;
-
-       /*
-        * |sizeof(struct netfs_trans)|
-        * |sizeof(struct netfs_cmd)| - transaction header
-        * |size| - buffer with requested size
-        * |padding| - crypto padding, zero bytes
-        * |nr * sizeof(struct page *)| - array of page pointers
-        *
-        * Overall size should be less than PAGE_SIZE for guaranteed allocation.
-        */
-
-       cont = size;
-       size = ALIGN(size, psb->crypto_align_size);
-       pad = size - cont;
-
-       size_no_trans = size + sizeof(struct netfs_cmd) * 2 + crypto_added;
-
-       cont = sizeof(struct netfs_trans) + size_no_trans;
-
-       num = (PAGE_SIZE - cont)/sizeof(struct page *);
-
-       if (nr > num)
-               nr = num;
-
-       t = kzalloc(cont + nr*sizeof(struct page *), GFP_NOIO);
-       if (!t)
-               goto err_out_exit;
-
-       t->iovec.iov_base = (void *)(t + 1);
-       t->pages = (struct page **)(t->iovec.iov_base + size_no_trans);
-
-       /*
-        * Reserving space for transaction header.
-        */
-       t->iovec.iov_len = sizeof(struct netfs_cmd) + crypto_added;
-
-       netfs_trans_init_static(t, nr, size_no_trans);
-
-       t->flags = flags;
-       t->psb = psb;
-
-       cmd = (struct netfs_cmd *)t->iovec.iov_base;
-
-       cmd->size = size;
-       cmd->cpad = pad;
-       cmd->csize = crypto_added;
-
-       dprintk("%s: t: %p, gen: %u, size: %u, padding: %u, align_size: %u, flags: %x, "
-                       "page_num: %u, base: %p, pages: %p.\n",
-                       __func__, t, t->gen, size, pad, psb->crypto_align_size, flags, nr,
-                       t->iovec.iov_base, t->pages);
-
-       return t;
-
-err_out_exit:
-       return NULL;
-}
-
-int netfs_trans_init(void)
-{
-       int err = -ENOMEM;
-
-       netfs_trans_dst = kmem_cache_create("netfs_trans_dst", sizeof(struct netfs_trans_dst),
-                       0, 0, NULL);
-       if (!netfs_trans_dst)
-               goto err_out_exit;
-
-       netfs_trans_dst_pool = mempool_create_slab_pool(256, netfs_trans_dst);
-       if (!netfs_trans_dst_pool)
-               goto err_out_free;
-
-       return 0;
-
-err_out_free:
-       kmem_cache_destroy(netfs_trans_dst);
-err_out_exit:
-       return err;
-}
-
-void netfs_trans_exit(void)
-{
-       mempool_destroy(netfs_trans_dst_pool);
-       kmem_cache_destroy(netfs_trans_dst);
-}
index 9b5d771..ed85b44 100644 (file)
@@ -37,6 +37,8 @@ struct _adapter;
 #include "wlan_bssdef.h"
 #include "rtl8712_spec.h"
 #include "rtl8712_hal.h"
+#include <linux/mutex.h>
+#include <linux/completion.h>
 
 enum _NIC_VERSION {
        RTL8711_NIC,
@@ -168,6 +170,7 @@ struct _adapter {
        s32     bSurpriseRemoved;
        u32     IsrContent;
        u32     ImrContent;
+       bool    fw_found;
        u8      EepromAddressSize;
        u8      hw_init_completed;
        struct task_struct *cmdThread;
@@ -184,6 +187,10 @@ struct _adapter {
        _workitem wkFilterRxFF0;
        u8 blnEnableRxFF0Filter;
        spinlock_t lockRxFF0Filter;
+       const struct firmware *fw;
+       struct usb_interface *pusb_intf;
+       struct mutex mutex_start;
+       struct completion rtl8712_fw_ready;
 };
 
 static inline u8 *myid(struct eeprom_priv *peepriv)
index d0029aa..cc893c0 100644 (file)
 #define FWBUFF_ALIGN_SZ 512
 #define MAX_DUMP_FWSZ  49152 /*default = 49152 (48k)*/
 
-static u32 rtl871x_open_fw(struct _adapter *padapter, void **pphfwfile_hdl,
-                   const u8 **ppmappedfw)
+static void rtl871x_load_fw_cb(const struct firmware *firmware, void *context)
 {
+       struct _adapter *padapter = context;
+
+       complete(&padapter->rtl8712_fw_ready);
+       if (!firmware) {
+               struct usb_device *udev = padapter->dvobjpriv.pusbdev;
+               struct usb_interface *pusb_intf = padapter->pusb_intf;
+               printk(KERN_ERR "r8712u: Firmware request failed\n");
+               padapter->fw_found = false;
+               usb_put_dev(udev);
+               usb_set_intfdata(pusb_intf, NULL);
+               return;
+       }
+       padapter->fw = firmware;
+       padapter->fw_found = true;
+       /* firmware available - start netdev */
+       register_netdev(padapter->pnetdev);
+}
+
+static const char firmware_file[] = "rtlwifi/rtl8712u.bin";
+
+int rtl871x_load_fw(struct _adapter *padapter)
+{
+       struct device *dev = &padapter->dvobjpriv.pusbdev->dev;
        int rc;
-       const char firmware_file[] = "rtlwifi/rtl8712u.bin";
-       const struct firmware **praw = (const struct firmware **)
-                                      (pphfwfile_hdl);
-       struct dvobj_priv *pdvobjpriv = (struct dvobj_priv *)
-                                       (&padapter->dvobjpriv);
-       struct usb_device *pusbdev = pdvobjpriv->pusbdev;
 
+       init_completion(&padapter->rtl8712_fw_ready);
        printk(KERN_INFO "r8712u: Loading firmware from \"%s\"\n",
               firmware_file);
-       rc = request_firmware(praw, firmware_file, &pusbdev->dev);
-       if (rc < 0) {
-               printk(KERN_ERR "r8712u: Unable to load firmware\n");
-               printk(KERN_ERR "r8712u: Install latest linux-firmware\n");
+       rc = request_firmware_nowait(THIS_MODULE, 1, firmware_file, dev,
+                                    GFP_KERNEL, padapter, rtl871x_load_fw_cb);
+       if (rc)
+               printk(KERN_ERR "r8712u: Firmware request error %d\n", rc);
+       return rc;
+}
+MODULE_FIRMWARE("rtlwifi/rtl8712u.bin");
+
+static u32 rtl871x_open_fw(struct _adapter *padapter, const u8 **ppmappedfw)
+{
+       const struct firmware **praw = &padapter->fw;
+
+       if (padapter->fw->size > 200000) {
+               printk(KERN_ERR "r8172u: Badfw->size of %d\n",
+                      (int)padapter->fw->size);
                return 0;
        }
        *ppmappedfw = (u8 *)((*praw)->data);
        return (*praw)->size;
 }
-MODULE_FIRMWARE("rtlwifi/rtl8712u.bin");
 
 static void fill_fwpriv(struct _adapter *padapter, struct fw_priv *pfwpriv)
 {
@@ -142,18 +169,17 @@ static u8 rtl8712_dl_fw(struct _adapter *padapter)
        uint dump_imem_sz, imem_sz, dump_emem_sz, emem_sz; /* max = 49152; */
        struct fw_hdr fwhdr;
        u32 ulfilelength;       /* FW file size */
-       void *phfwfile_hdl = NULL;
        const u8 *pmappedfw = NULL;
        u8 *ptmpchar = NULL, *ppayload, *ptr;
        struct tx_desc *ptx_desc;
        u32 txdscp_sz = sizeof(struct tx_desc);
        u8 ret = _FAIL;
 
-       ulfilelength = rtl871x_open_fw(padapter, &phfwfile_hdl, &pmappedfw);
+       ulfilelength = rtl871x_open_fw(padapter, &pmappedfw);
        if (pmappedfw && (ulfilelength > 0)) {
                update_fwhdr(&fwhdr, pmappedfw);
                if (chk_fwhdr(&fwhdr, ulfilelength) == _FAIL)
-                       goto firmware_rel;
+                       return ret;
                fill_fwpriv(padapter, &fwhdr.fwpriv);
                /* firmware check ok */
                maxlen = (fwhdr.img_IMEM_size > fwhdr.img_SRAM_size) ?
@@ -161,7 +187,7 @@ static u8 rtl8712_dl_fw(struct _adapter *padapter)
                maxlen += txdscp_sz;
                ptmpchar = _malloc(maxlen + FWBUFF_ALIGN_SZ);
                if (ptmpchar == NULL)
-                       goto firmware_rel;
+                       return ret;
 
                ptx_desc = (struct tx_desc *)(ptmpchar + FWBUFF_ALIGN_SZ -
                            ((addr_t)(ptmpchar) & (FWBUFF_ALIGN_SZ - 1)));
@@ -297,8 +323,6 @@ static u8 rtl8712_dl_fw(struct _adapter *padapter)
 
 exit_fail:
        kfree(ptmpchar);
-firmware_rel:
-       release_firmware((struct firmware *)phfwfile_hdl);
        return ret;
 }
 
index 9a75c6d..98a3d68 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/kthread.h>
+#include <linux/firmware.h>
 #include "osdep_service.h"
 #include "drv_types.h"
 #include "xmit_osdep.h"
@@ -264,12 +265,12 @@ static void start_drv_timers(struct _adapter *padapter)
 void r8712_stop_drv_timers(struct _adapter *padapter)
 {
        _cancel_timer_ex(&padapter->mlmepriv.assoc_timer);
-       _cancel_timer_ex(&padapter->mlmepriv.sitesurveyctrl.
-                        sitesurvey_ctrl_timer);
        _cancel_timer_ex(&padapter->securitypriv.tkip_timer);
        _cancel_timer_ex(&padapter->mlmepriv.scan_to_timer);
        _cancel_timer_ex(&padapter->mlmepriv.dhcp_timer);
        _cancel_timer_ex(&padapter->mlmepriv.wdg_timer);
+       _cancel_timer_ex(&padapter->mlmepriv.sitesurveyctrl.
+                        sitesurvey_ctrl_timer);
 }
 
 static u8 init_default_value(struct _adapter *padapter)
@@ -347,7 +348,8 @@ u8 r8712_free_drv_sw(struct _adapter *padapter)
        r8712_free_mlme_priv(&padapter->mlmepriv);
        r8712_free_io_queue(padapter);
        _free_xmit_priv(&padapter->xmitpriv);
-       _r8712_free_sta_priv(&padapter->stapriv);
+       if (padapter->fw_found)
+               _r8712_free_sta_priv(&padapter->stapriv);
        _r8712_free_recv_priv(&padapter->recvpriv);
        mp871xdeinit(padapter);
        if (pnetdev)
@@ -388,6 +390,7 @@ static int netdev_open(struct net_device *pnetdev)
 {
        struct _adapter *padapter = (struct _adapter *)netdev_priv(pnetdev);
 
+       mutex_lock(&padapter->mutex_start);
        if (padapter->bup == false) {
                padapter->bDriverStopped = false;
                padapter->bSurpriseRemoved = false;
@@ -435,11 +438,13 @@ static int netdev_open(struct net_device *pnetdev)
        /* start driver mlme relation timer */
        start_drv_timers(padapter);
        padapter->ledpriv.LedControlHandler(padapter, LED_CTL_NO_LINK);
+       mutex_unlock(&padapter->mutex_start);
        return 0;
 netdev_open_error:
        padapter->bup = false;
        netif_carrier_off(pnetdev);
        netif_stop_queue(pnetdev);
+       mutex_unlock(&padapter->mutex_start);
        return -1;
 }
 
@@ -473,6 +478,9 @@ static int netdev_close(struct net_device *pnetdev)
        r8712_free_network_queue(padapter);
        /* The interface is no longer Up: */
        padapter->bup = false;
+       release_firmware(padapter->fw);
+       /* never exit with a firmware callback pending */
+       wait_for_completion(&padapter->rtl8712_fw_ready);
        return 0;
 }
 
index 665e718..d19865a 100644 (file)
@@ -145,5 +145,6 @@ struct hal_priv {
 };
 
 uint    rtl8712_hal_init(struct _adapter *padapter);
+int rtl871x_load_fw(struct _adapter *padapter);
 
 #endif
index 64f5696..81bde80 100644 (file)
@@ -43,6 +43,7 @@ static void _init_stainfo(struct sta_info *psta)
        _r8712_init_sta_xmit_priv(&psta->sta_xmitpriv);
        _r8712_init_sta_recv_priv(&psta->sta_recvpriv);
 #ifdef CONFIG_R8712_AP
+       _init_listhead(&psta->asoc_list);
        _init_listhead(&psta->auth_list);
 #endif
 }
index 5385da2..9bade18 100644 (file)
@@ -89,6 +89,7 @@ static struct usb_device_id rtl871x_usb_id_tbl[] = {
        {USB_DEVICE(0x0DF6, 0x0045)},
        {USB_DEVICE(0x0DF6, 0x0059)}, /* 11n mode disable */
        {USB_DEVICE(0x0DF6, 0x004B)},
+       {USB_DEVICE(0x0DF6, 0x005B)},
        {USB_DEVICE(0x0DF6, 0x005D)},
        {USB_DEVICE(0x0DF6, 0x0063)},
        /* Sweex */
@@ -389,6 +390,7 @@ static int r871xu_drv_init(struct usb_interface *pusb_intf,
        pdvobjpriv = &padapter->dvobjpriv;
        pdvobjpriv->padapter = padapter;
        padapter->dvobjpriv.pusbdev = udev;
+       padapter->pusb_intf = pusb_intf;
        usb_set_intfdata(pusb_intf, pnetdev);
        SET_NETDEV_DEV(pnetdev, &pusb_intf->dev);
        /* step 2. */
@@ -595,10 +597,11 @@ static int r871xu_drv_init(struct usb_interface *pusb_intf,
                               "%pM\n", mac);
                memcpy(pnetdev->dev_addr, mac, ETH_ALEN);
        }
-       /* step 6. Tell the network stack we exist */
-       if (register_netdev(pnetdev) != 0)
+       /* step 6. Load the firmware asynchronously */
+       if (rtl871x_load_fw(padapter))
                goto error;
        spin_lock_init(&padapter->lockRxFF0Filter);
+       mutex_init(&padapter->mutex_start);
        return 0;
 error:
        usb_put_dev(udev);
@@ -629,7 +632,8 @@ static void r871xu_dev_remove(struct usb_interface *pusb_intf)
                flush_scheduled_work();
                udelay(1);
                /*Stop driver mlme relation timer */
-               r8712_stop_drv_timers(padapter);
+               if (padapter->fw_found)
+                       r8712_stop_drv_timers(padapter);
                r871x_dev_unload(padapter);
                r8712_free_drv_sw(padapter);
        }
index e1c4492..dde559d 100644 (file)
@@ -1046,8 +1046,6 @@ static int bridge_dev_destroy(struct bridge_dev_context *dev_ctxt)
 
        /* Free the driver's device context: */
        kfree(drv_datap->base_img);
-       kfree(drv_datap);
-       dev_set_drvdata(bridge, NULL);
        kfree((void *)dev_ctxt);
        return status;
 }
index 76cfc6e..385740b 100644 (file)
@@ -410,6 +410,9 @@ static int __devexit omap34_xx_bridge_remove(struct platform_device *pdev)
                DBC_ASSERT(ret == true);
        }
 
+       kfree(drv_datap);
+       dev_set_drvdata(bridge, NULL);
+
 func_cont:
        mem_ext_phys_pool_release();
 
@@ -500,35 +503,42 @@ static int bridge_open(struct inode *ip, struct file *filp)
        }
 #endif
        pr_ctxt = kzalloc(sizeof(struct process_context), GFP_KERNEL);
-       if (pr_ctxt) {
-               pr_ctxt->res_state = PROC_RES_ALLOCATED;
-               spin_lock_init(&pr_ctxt->dmm_map_lock);
-               INIT_LIST_HEAD(&pr_ctxt->dmm_map_list);
-               spin_lock_init(&pr_ctxt->dmm_rsv_lock);
-               INIT_LIST_HEAD(&pr_ctxt->dmm_rsv_list);
-
-               pr_ctxt->node_id = kzalloc(sizeof(struct idr), GFP_KERNEL);
-               if (pr_ctxt->node_id) {
-                       idr_init(pr_ctxt->node_id);
-               } else {
-                       status = -ENOMEM;
-                       goto err;
-               }
+       if (!pr_ctxt)
+               return -ENOMEM;
+
+       pr_ctxt->res_state = PROC_RES_ALLOCATED;
+       spin_lock_init(&pr_ctxt->dmm_map_lock);
+       INIT_LIST_HEAD(&pr_ctxt->dmm_map_list);
+       spin_lock_init(&pr_ctxt->dmm_rsv_lock);
+       INIT_LIST_HEAD(&pr_ctxt->dmm_rsv_list);
 
-               pr_ctxt->stream_id = kzalloc(sizeof(struct idr), GFP_KERNEL);
-               if (pr_ctxt->stream_id)
-                       idr_init(pr_ctxt->stream_id);
-               else
-                       status = -ENOMEM;
-       } else {
+       pr_ctxt->node_id = kzalloc(sizeof(struct idr), GFP_KERNEL);
+       if (!pr_ctxt->node_id) {
                status = -ENOMEM;
+               goto err1;
        }
-err:
+
+       idr_init(pr_ctxt->node_id);
+
+       pr_ctxt->stream_id = kzalloc(sizeof(struct idr), GFP_KERNEL);
+       if (!pr_ctxt->stream_id) {
+               status = -ENOMEM;
+               goto err2;
+       }
+
+       idr_init(pr_ctxt->stream_id);
+
        filp->private_data = pr_ctxt;
+
 #ifdef CONFIG_TIDSPBRIDGE_RECOVERY
-       if (!status)
-               atomic_inc(&bridge_cref);
+       atomic_inc(&bridge_cref);
 #endif
+       return 0;
+
+err2:
+       kfree(pr_ctxt->node_id);
+err1:
+       kfree(pr_ctxt);
        return status;
 }
 
@@ -550,6 +560,8 @@ static int bridge_release(struct inode *ip, struct file *filp)
        flush_signals(current);
        drv_remove_all_resources(pr_ctxt);
        proc_detach(pr_ctxt);
+       kfree(pr_ctxt->node_id);
+       kfree(pr_ctxt->stream_id);
        kfree(pr_ctxt);
 
        filp->private_data = NULL;
index 2d63178..705a9e5 100644 (file)
@@ -246,8 +246,9 @@ static int __init usbip_host_init(void)
 {
        int ret;
 
-       stub_priv_cache = KMEM_CACHE(stub_priv, SLAB_HWCACHE_ALIGN);
+       init_busid_table();
 
+       stub_priv_cache = KMEM_CACHE(stub_priv, SLAB_HWCACHE_ALIGN);
        if (!stub_priv_cache) {
                pr_err("kmem_cache_create failed\n");
                return -ENOMEM;
@@ -266,7 +267,6 @@ static int __init usbip_host_init(void)
                goto err_create_file;
        }
 
-       init_busid_table();
        pr_info(DRIVER_DESC " v" USBIP_VERSION "\n");
        return ret;
 
index 642840c..ef7c52b 100644 (file)
@@ -358,8 +358,8 @@ static struct zbud_hdr *zbud_create(uint16_t client_id, uint16_t pool_id,
        if (unlikely(zbpg == NULL))
                goto out;
        /* ok, have a page, now compress the data before taking locks */
-       spin_lock(&zbpg->lock);
        spin_lock(&zbud_budlists_spinlock);
+       spin_lock(&zbpg->lock);
        list_add_tail(&zbpg->bud_list, &zbud_unbuddied[nchunks].list);
        zbud_unbuddied[nchunks].count++;
        zh = &zbpg->buddy[0];
@@ -389,12 +389,11 @@ init_zh:
        zh->oid = *oid;
        zh->pool_id = pool_id;
        zh->client_id = client_id;
-       /* can wait to copy the data until the list locks are dropped */
-       spin_unlock(&zbud_budlists_spinlock);
-
        to = zbud_data(zh, size);
        memcpy(to, cdata, size);
        spin_unlock(&zbpg->lock);
+       spin_unlock(&zbud_budlists_spinlock);
+
        zbud_cumul_chunk_counts[nchunks]++;
        atomic_inc(&zcache_zbud_curr_zpages);
        zcache_zbud_cumul_zpages++;
@@ -655,8 +654,8 @@ static unsigned int zv_max_zsize = (PAGE_SIZE / 8) * 7;
  */
 static unsigned int zv_max_mean_zsize = (PAGE_SIZE / 8) * 5;
 
-static unsigned long zv_curr_dist_counts[NCHUNKS];
-static unsigned long zv_cumul_dist_counts[NCHUNKS];
+static atomic_t zv_curr_dist_counts[NCHUNKS];
+static atomic_t zv_cumul_dist_counts[NCHUNKS];
 
 static struct zv_hdr *zv_create(struct xv_pool *xvpool, uint32_t pool_id,
                                struct tmem_oid *oid, uint32_t index,
@@ -675,8 +674,8 @@ static struct zv_hdr *zv_create(struct xv_pool *xvpool, uint32_t pool_id,
                        &page, &offset, ZCACHE_GFP_MASK);
        if (unlikely(ret))
                goto out;
-       zv_curr_dist_counts[chunks]++;
-       zv_cumul_dist_counts[chunks]++;
+       atomic_inc(&zv_curr_dist_counts[chunks]);
+       atomic_inc(&zv_cumul_dist_counts[chunks]);
        zv = kmap_atomic(page, KM_USER0) + offset;
        zv->index = index;
        zv->oid = *oid;
@@ -698,7 +697,7 @@ static void zv_free(struct xv_pool *xvpool, struct zv_hdr *zv)
 
        ASSERT_SENTINEL(zv, ZVH);
        BUG_ON(chunks >= NCHUNKS);
-       zv_curr_dist_counts[chunks]--;
+       atomic_dec(&zv_curr_dist_counts[chunks]);
        size -= sizeof(*zv);
        BUG_ON(size == 0);
        INVERT_SENTINEL(zv, ZVH);
@@ -738,7 +737,7 @@ static int zv_curr_dist_counts_show(char *buf)
        char *p = buf;
 
        for (i = 0; i < NCHUNKS; i++) {
-               n = zv_curr_dist_counts[i];
+               n = atomic_read(&zv_curr_dist_counts[i]);
                p += sprintf(p, "%lu ", n);
                chunks += n;
                sum_total_chunks += i * n;
@@ -754,7 +753,7 @@ static int zv_cumul_dist_counts_show(char *buf)
        char *p = buf;
 
        for (i = 0; i < NCHUNKS; i++) {
-               n = zv_cumul_dist_counts[i];
+               n = atomic_read(&zv_cumul_dist_counts[i]);
                p += sprintf(p, "%lu ", n);
                chunks += n;
                sum_total_chunks += i * n;
@@ -1782,9 +1781,9 @@ static int zcache_frontswap_poolid = -1;
  * Swizzling increases objects per swaptype, increasing tmem concurrency
  * for heavy swaploads.  Later, larger nr_cpus -> larger SWIZ_BITS
  * Setting SWIZ_BITS to 27 basically reconstructs the swap entry from
- * frontswap_get_page()
+ * frontswap_get_page(), but has side-effects. Hence using 8.
  */
-#define SWIZ_BITS              27
+#define SWIZ_BITS              8
 #define SWIZ_MASK              ((1 << SWIZ_BITS) - 1)
 #define _oswiz(_type, _ind)    ((_type << SWIZ_BITS) | (_ind & SWIZ_MASK))
 #define iswiz(_ind)            (_ind >> SWIZ_BITS)
index ac44af1..4426290 100644 (file)
@@ -1061,7 +1061,7 @@ attach_cmd:
        if (ret < 0)
                return iscsit_add_reject_from_cmd(
                                ISCSI_REASON_BOOKMARK_NO_RESOURCES,
-                               1, 1, buf, cmd);
+                               1, 0, buf, cmd);
        /*
         * Check the CmdSN against ExpCmdSN/MaxCmdSN here if
         * the Immediate Bit is not set, and no Immediate
@@ -3164,6 +3164,30 @@ static int iscsit_send_task_mgt_rsp(
        return 0;
 }
 
+static bool iscsit_check_inaddr_any(struct iscsi_np *np)
+{
+       bool ret = false;
+
+       if (np->np_sockaddr.ss_family == AF_INET6) {
+               const struct sockaddr_in6 sin6 = {
+                       .sin6_addr = IN6ADDR_ANY_INIT };
+               struct sockaddr_in6 *sock_in6 =
+                        (struct sockaddr_in6 *)&np->np_sockaddr;
+
+               if (!memcmp(sock_in6->sin6_addr.s6_addr,
+                               sin6.sin6_addr.s6_addr, 16))
+                       ret = true;
+       } else {
+               struct sockaddr_in * sock_in =
+                       (struct sockaddr_in *)&np->np_sockaddr;
+
+               if (sock_in->sin_addr.s_addr == INADDR_ANY)
+                       ret = true;
+       }
+
+       return ret;
+}
+
 static int iscsit_build_sendtargets_response(struct iscsi_cmd *cmd)
 {
        char *payload = NULL;
@@ -3213,12 +3237,17 @@ static int iscsit_build_sendtargets_response(struct iscsi_cmd *cmd)
                        spin_lock(&tpg->tpg_np_lock);
                        list_for_each_entry(tpg_np, &tpg->tpg_gnp_list,
                                                tpg_np_list) {
+                               struct iscsi_np *np = tpg_np->tpg_np;
+                               bool inaddr_any = iscsit_check_inaddr_any(np);
+
                                len = sprintf(buf, "TargetAddress="
                                        "%s%s%s:%hu,%hu",
-                                       (tpg_np->tpg_np->np_sockaddr.ss_family == AF_INET6) ?
-                                       "[" : "", tpg_np->tpg_np->np_ip,
-                                       (tpg_np->tpg_np->np_sockaddr.ss_family == AF_INET6) ?
-                                       "]" : "", tpg_np->tpg_np->np_port,
+                                       (np->np_sockaddr.ss_family == AF_INET6) ?
+                                       "[" : "", (inaddr_any == false) ?
+                                               np->np_ip : conn->local_ip,
+                                       (np->np_sockaddr.ss_family == AF_INET6) ?
+                                       "]" : "", (inaddr_any == false) ?
+                                               np->np_port : conn->local_port,
                                        tpg->tpgt);
                                len += 1;
 
index 3468caa..6b35b37 100644 (file)
@@ -21,6 +21,7 @@
 
 #include <linux/configfs.h>
 #include <linux/export.h>
+#include <linux/inet.h>
 #include <target/target_core_base.h>
 #include <target/target_core_fabric.h>
 #include <target/target_core_fabric_configfs.h>
index f1a02da..0ec3b77 100644 (file)
@@ -508,6 +508,7 @@ struct iscsi_conn {
        u16                     cid;
        /* Remote TCP Port */
        u16                     login_port;
+       u16                     local_port;
        int                     net_size;
        u32                     auth_id;
 #define CONNFLAG_SCTP_STRUCT_FILE                      0x01
@@ -527,6 +528,7 @@ struct iscsi_conn {
        unsigned char           bad_hdr[ISCSI_HDR_LEN];
 #define IPV6_ADDRESS_SPACE                             48
        unsigned char           login_ip[IPV6_ADDRESS_SPACE];
+       unsigned char           local_ip[IPV6_ADDRESS_SPACE];
        int                     conn_usage_count;
        int                     conn_waiting_on_uc;
        atomic_t                check_immediate_queue;
@@ -561,8 +563,8 @@ struct iscsi_conn {
        struct hash_desc        conn_tx_hash;
        /* Used for scheduling TX and RX connection kthreads */
        cpumask_var_t           conn_cpumask;
-       int                     conn_rx_reset_cpumask:1;
-       int                     conn_tx_reset_cpumask:1;
+       unsigned int            conn_rx_reset_cpumask:1;
+       unsigned int            conn_tx_reset_cpumask:1;
        /* list_head of struct iscsi_cmd for this connection */
        struct list_head        conn_cmd_list;
        struct list_head        immed_queue_list;
index 255c0d6..27901e3 100644 (file)
@@ -1238,7 +1238,7 @@ void iscsit_mod_dataout_timer(struct iscsi_cmd *cmd)
 {
        struct iscsi_conn *conn = cmd->conn;
        struct iscsi_session *sess = conn->sess;
-       struct iscsi_node_attrib *na = na = iscsit_tpg_get_node_attrib(sess);
+       struct iscsi_node_attrib *na = iscsit_tpg_get_node_attrib(sess);
 
        spin_lock_bh(&cmd->dataout_timeout_lock);
        if (!(cmd->dataout_timer_flags & ISCSI_TF_RUNNING)) {
@@ -1261,7 +1261,7 @@ void iscsit_start_dataout_timer(
        struct iscsi_conn *conn)
 {
        struct iscsi_session *sess = conn->sess;
-       struct iscsi_node_attrib *na = na = iscsit_tpg_get_node_attrib(sess);
+       struct iscsi_node_attrib *na = iscsit_tpg_get_node_attrib(sess);
 
        if (cmd->dataout_timer_flags & ISCSI_TF_RUNNING)
                return;
index 373b0cc..38cb7ce 100644 (file)
@@ -615,8 +615,8 @@ static int iscsi_post_login_handler(
                }
 
                pr_debug("iSCSI Login successful on CID: %hu from %s to"
-                       " %s:%hu,%hu\n", conn->cid, conn->login_ip, np->np_ip,
-                               np->np_port, tpg->tpgt);
+                       " %s:%hu,%hu\n", conn->cid, conn->login_ip,
+                       conn->local_ip, conn->local_port, tpg->tpgt);
 
                list_add_tail(&conn->conn_list, &sess->sess_conn_list);
                atomic_inc(&sess->nconn);
@@ -658,7 +658,8 @@ static int iscsi_post_login_handler(
        sess->session_state = TARG_SESS_STATE_LOGGED_IN;
 
        pr_debug("iSCSI Login successful on CID: %hu from %s to %s:%hu,%hu\n",
-               conn->cid, conn->login_ip, np->np_ip, np->np_port, tpg->tpgt);
+               conn->cid, conn->login_ip, conn->local_ip, conn->local_port,
+               tpg->tpgt);
 
        spin_lock_bh(&sess->conn_lock);
        list_add_tail(&conn->conn_list, &sess->sess_conn_list);
@@ -841,6 +842,14 @@ int iscsi_target_setup_login_socket(
                goto fail;
        }
 
+       ret = kernel_setsockopt(sock, IPPROTO_IP, IP_FREEBIND,
+                       (char *)&opt, sizeof(opt));
+       if (ret < 0) {
+               pr_err("kernel_setsockopt() for IP_FREEBIND"
+                       " failed\n");
+               goto fail;
+       }
+
        ret = kernel_bind(sock, (struct sockaddr *)&np->np_sockaddr, len);
        if (ret < 0) {
                pr_err("kernel_bind() failed: %d\n", ret);
@@ -1020,6 +1029,18 @@ static int __iscsi_target_login_thread(struct iscsi_np *np)
                snprintf(conn->login_ip, sizeof(conn->login_ip), "%pI6c",
                                &sock_in6.sin6_addr.in6_u);
                conn->login_port = ntohs(sock_in6.sin6_port);
+
+               if (conn->sock->ops->getname(conn->sock,
+                               (struct sockaddr *)&sock_in6, &err, 0) < 0) {
+                       pr_err("sock_ops->getname() failed.\n");
+                       iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
+                                       ISCSI_LOGIN_STATUS_TARGET_ERROR);
+                       goto new_sess_out;
+               }
+               snprintf(conn->local_ip, sizeof(conn->local_ip), "%pI6c",
+                               &sock_in6.sin6_addr.in6_u);
+               conn->local_port = ntohs(sock_in6.sin6_port);
+
        } else {
                memset(&sock_in, 0, sizeof(struct sockaddr_in));
 
@@ -1032,6 +1053,16 @@ static int __iscsi_target_login_thread(struct iscsi_np *np)
                }
                sprintf(conn->login_ip, "%pI4", &sock_in.sin_addr.s_addr);
                conn->login_port = ntohs(sock_in.sin_port);
+
+               if (conn->sock->ops->getname(conn->sock,
+                               (struct sockaddr *)&sock_in, &err, 0) < 0) {
+                       pr_err("sock_ops->getname() failed.\n");
+                       iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
+                                       ISCSI_LOGIN_STATUS_TARGET_ERROR);
+                       goto new_sess_out;
+               }
+               sprintf(conn->local_ip, "%pI4", &sock_in.sin_addr.s_addr);
+               conn->local_port = ntohs(sock_in.sin_port);
        }
 
        conn->network_transport = np->np_network_transport;
@@ -1039,7 +1070,7 @@ static int __iscsi_target_login_thread(struct iscsi_np *np)
        pr_debug("Received iSCSI login request from %s on %s Network"
                        " Portal %s:%hu\n", conn->login_ip,
                (conn->network_transport == ISCSI_TCP) ? "TCP" : "SCTP",
-                       np->np_ip, np->np_port);
+                       conn->local_ip, conn->local_port);
 
        pr_debug("Moving to TARG_CONN_STATE_IN_LOGIN.\n");
        conn->conn_state        = TARG_CONN_STATE_IN_LOGIN;
index a05ca1c..11287e1 100644 (file)
@@ -849,6 +849,17 @@ void iscsit_free_cmd(struct iscsi_cmd *cmd)
        case ISCSI_OP_SCSI_TMFUNC:
                transport_generic_free_cmd(&cmd->se_cmd, 1);
                break;
+       case ISCSI_OP_REJECT:
+               /*
+                * Handle special case for REJECT when iscsi_add_reject*() has
+                * overwritten the original iscsi_opcode assignment, and the
+                * associated cmd->se_cmd needs to be released.
+                */
+               if (cmd->se_cmd.se_tfo != NULL) {
+                       transport_generic_free_cmd(&cmd->se_cmd, 1);
+                       break;
+               }
+               /* Fall-through */
        default:
                iscsit_release_cmd(cmd);
                break;
index 1b1edd1..01a2691 100644 (file)
@@ -78,7 +78,7 @@ int target_emulate_report_target_port_groups(struct se_task *task)
                return -EINVAL;
        }
 
-       buf = transport_kmap_first_data_page(cmd);
+       buf = transport_kmap_data_sg(cmd);
 
        spin_lock(&su_dev->t10_alua.tg_pt_gps_lock);
        list_for_each_entry(tg_pt_gp, &su_dev->t10_alua.tg_pt_gps_list,
@@ -163,7 +163,7 @@ int target_emulate_report_target_port_groups(struct se_task *task)
        buf[2] = ((rd_len >> 8) & 0xff);
        buf[3] = (rd_len & 0xff);
 
-       transport_kunmap_first_data_page(cmd);
+       transport_kunmap_data_sg(cmd);
 
        task->task_scsi_status = GOOD;
        transport_complete_task(task, 1);
@@ -194,7 +194,7 @@ int target_emulate_set_target_port_groups(struct se_task *task)
                cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
                return -EINVAL;
        }
-       buf = transport_kmap_first_data_page(cmd);
+       buf = transport_kmap_data_sg(cmd);
 
        /*
         * Determine if explict ALUA via SET_TARGET_PORT_GROUPS is allowed
@@ -351,7 +351,7 @@ int target_emulate_set_target_port_groups(struct se_task *task)
        }
 
 out:
-       transport_kunmap_first_data_page(cmd);
+       transport_kunmap_data_sg(cmd);
        task->task_scsi_status = GOOD;
        transport_complete_task(task, 1);
        return 0;
index 2f2235e..f3d71fa 100644 (file)
@@ -83,7 +83,7 @@ target_emulate_inquiry_std(struct se_cmd *cmd)
                return -EINVAL;
        }
 
-       buf = transport_kmap_first_data_page(cmd);
+       buf = transport_kmap_data_sg(cmd);
 
        if (dev == tpg->tpg_virt_lun0.lun_se_dev) {
                buf[0] = 0x3f; /* Not connected */
@@ -134,7 +134,7 @@ target_emulate_inquiry_std(struct se_cmd *cmd)
        buf[4] = 31; /* Set additional length to 31 */
 
 out:
-       transport_kunmap_first_data_page(cmd);
+       transport_kunmap_data_sg(cmd);
        return 0;
 }
 
@@ -698,6 +698,13 @@ int target_emulate_inquiry(struct se_task *task)
        int p, ret;
 
        if (!(cdb[1] & 0x1)) {
+               if (cdb[2]) {
+                       pr_err("INQUIRY with EVPD==0 but PAGE CODE=%02x\n",
+                              cdb[2]);
+                       cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD;
+                       return -EINVAL;
+               }
+
                ret = target_emulate_inquiry_std(cmd);
                goto out;
        }
@@ -716,7 +723,7 @@ int target_emulate_inquiry(struct se_task *task)
                return -EINVAL;
        }
 
-       buf = transport_kmap_first_data_page(cmd);
+       buf = transport_kmap_data_sg(cmd);
 
        buf[0] = dev->transport->get_device_type(dev);
 
@@ -729,11 +736,11 @@ int target_emulate_inquiry(struct se_task *task)
        }
 
        pr_err("Unknown VPD Code: 0x%02x\n", cdb[2]);
-       cmd->scsi_sense_reason = TCM_UNSUPPORTED_SCSI_OPCODE;
+       cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD;
        ret = -EINVAL;
 
 out_unmap:
-       transport_kunmap_first_data_page(cmd);
+       transport_kunmap_data_sg(cmd);
 out:
        if (!ret) {
                task->task_scsi_status = GOOD;
@@ -755,7 +762,7 @@ int target_emulate_readcapacity(struct se_task *task)
        else
                blocks = (u32)blocks_long;
 
-       buf = transport_kmap_first_data_page(cmd);
+       buf = transport_kmap_data_sg(cmd);
 
        buf[0] = (blocks >> 24) & 0xff;
        buf[1] = (blocks >> 16) & 0xff;
@@ -771,7 +778,7 @@ int target_emulate_readcapacity(struct se_task *task)
        if (dev->se_sub_dev->se_dev_attrib.emulate_tpu || dev->se_sub_dev->se_dev_attrib.emulate_tpws)
                put_unaligned_be32(0xFFFFFFFF, &buf[0]);
 
-       transport_kunmap_first_data_page(cmd);
+       transport_kunmap_data_sg(cmd);
 
        task->task_scsi_status = GOOD;
        transport_complete_task(task, 1);
@@ -785,7 +792,7 @@ int target_emulate_readcapacity_16(struct se_task *task)
        unsigned char *buf;
        unsigned long long blocks = dev->transport->get_blocks(dev);
 
-       buf = transport_kmap_first_data_page(cmd);
+       buf = transport_kmap_data_sg(cmd);
 
        buf[0] = (blocks >> 56) & 0xff;
        buf[1] = (blocks >> 48) & 0xff;
@@ -806,7 +813,7 @@ int target_emulate_readcapacity_16(struct se_task *task)
        if (dev->se_sub_dev->se_dev_attrib.emulate_tpu || dev->se_sub_dev->se_dev_attrib.emulate_tpws)
                buf[14] = 0x80;
 
-       transport_kunmap_first_data_page(cmd);
+       transport_kunmap_data_sg(cmd);
 
        task->task_scsi_status = GOOD;
        transport_complete_task(task, 1);
@@ -1019,9 +1026,9 @@ int target_emulate_modesense(struct se_task *task)
                        offset = cmd->data_length;
        }
 
-       rbuf = transport_kmap_first_data_page(cmd);
+       rbuf = transport_kmap_data_sg(cmd);
        memcpy(rbuf, buf, offset);
-       transport_kunmap_first_data_page(cmd);
+       transport_kunmap_data_sg(cmd);
 
        task->task_scsi_status = GOOD;
        transport_complete_task(task, 1);
@@ -1043,7 +1050,7 @@ int target_emulate_request_sense(struct se_task *task)
                return -ENOSYS;
        }
 
-       buf = transport_kmap_first_data_page(cmd);
+       buf = transport_kmap_data_sg(cmd);
 
        if (!core_scsi3_ua_clear_for_request_sense(cmd, &ua_asc, &ua_ascq)) {
                /*
@@ -1051,11 +1058,8 @@ int target_emulate_request_sense(struct se_task *task)
                 */
                buf[0] = 0x70;
                buf[SPC_SENSE_KEY_OFFSET] = UNIT_ATTENTION;
-               /*
-                * Make sure request data length is enough for additional
-                * sense data.
-                */
-               if (cmd->data_length <= 18) {
+
+               if (cmd->data_length < 18) {
                        buf[7] = 0x00;
                        err = -EINVAL;
                        goto end;
@@ -1072,11 +1076,8 @@ int target_emulate_request_sense(struct se_task *task)
                 */
                buf[0] = 0x70;
                buf[SPC_SENSE_KEY_OFFSET] = NO_SENSE;
-               /*
-                * Make sure request data length is enough for additional
-                * sense data.
-                */
-               if (cmd->data_length <= 18) {
+
+               if (cmd->data_length < 18) {
                        buf[7] = 0x00;
                        err = -EINVAL;
                        goto end;
@@ -1089,7 +1090,7 @@ int target_emulate_request_sense(struct se_task *task)
        }
 
 end:
-       transport_kunmap_first_data_page(cmd);
+       transport_kunmap_data_sg(cmd);
        task->task_scsi_status = GOOD;
        transport_complete_task(task, 1);
        return 0;
@@ -1123,7 +1124,7 @@ int target_emulate_unmap(struct se_task *task)
        dl = get_unaligned_be16(&cdb[0]);
        bd_dl = get_unaligned_be16(&cdb[2]);
 
-       buf = transport_kmap_first_data_page(cmd);
+       buf = transport_kmap_data_sg(cmd);
 
        ptr = &buf[offset];
        pr_debug("UNMAP: Sub: %s Using dl: %hu bd_dl: %hu size: %hu"
@@ -1147,7 +1148,7 @@ int target_emulate_unmap(struct se_task *task)
        }
 
 err:
-       transport_kunmap_first_data_page(cmd);
+       transport_kunmap_data_sg(cmd);
        if (!ret) {
                task->task_scsi_status = GOOD;
                transport_complete_task(task, 1);
index 0955bb8..6e043ee 100644 (file)
@@ -1704,13 +1704,15 @@ static ssize_t target_core_store_dev_alias(
                return -EINVAL;
        }
 
-       se_dev->su_dev_flags |= SDF_USING_ALIAS;
        read_bytes = snprintf(&se_dev->se_dev_alias[0], SE_DEV_ALIAS_LEN,
                        "%s", page);
-
+       if (!read_bytes)
+               return -EINVAL;
        if (se_dev->se_dev_alias[read_bytes - 1] == '\n')
                se_dev->se_dev_alias[read_bytes - 1] = '\0';
 
+       se_dev->su_dev_flags |= SDF_USING_ALIAS;
+
        pr_debug("Target_Core_ConfigFS: %s/%s set alias: %s\n",
                config_item_name(&hba->hba_group.cg_item),
                config_item_name(&se_dev->se_dev_group.cg_item),
@@ -1753,13 +1755,15 @@ static ssize_t target_core_store_dev_udev_path(
                return -EINVAL;
        }
 
-       se_dev->su_dev_flags |= SDF_USING_UDEV_PATH;
        read_bytes = snprintf(&se_dev->se_dev_udev_path[0], SE_UDEV_PATH_LEN,
                        "%s", page);
-
+       if (!read_bytes)
+               return -EINVAL;
        if (se_dev->se_dev_udev_path[read_bytes - 1] == '\n')
                se_dev->se_dev_udev_path[read_bytes - 1] = '\0';
 
+       se_dev->su_dev_flags |= SDF_USING_UDEV_PATH;
+
        pr_debug("Target_Core_ConfigFS: %s/%s set udev_path: %s\n",
                config_item_name(&hba->hba_group.cg_item),
                config_item_name(&se_dev->se_dev_group.cg_item),
index 0c5992f..edbcabb 100644 (file)
@@ -320,11 +320,12 @@ int core_free_device_list_for_node(
 void core_dec_lacl_count(struct se_node_acl *se_nacl, struct se_cmd *se_cmd)
 {
        struct se_dev_entry *deve;
+       unsigned long flags;
 
-       spin_lock_irq(&se_nacl->device_list_lock);
+       spin_lock_irqsave(&se_nacl->device_list_lock, flags);
        deve = &se_nacl->device_list[se_cmd->orig_fe_lun];
        deve->deve_cmds--;
-       spin_unlock_irq(&se_nacl->device_list_lock);
+       spin_unlock_irqrestore(&se_nacl->device_list_lock, flags);
 }
 
 void core_update_device_list_access(
@@ -656,7 +657,7 @@ int target_report_luns(struct se_task *se_task)
        unsigned char *buf;
        u32 cdb_offset = 0, lun_count = 0, offset = 8, i;
 
-       buf = transport_kmap_first_data_page(se_cmd);
+       buf = (unsigned char *) transport_kmap_data_sg(se_cmd);
 
        /*
         * If no struct se_session pointer is present, this struct se_cmd is
@@ -694,7 +695,7 @@ int target_report_luns(struct se_task *se_task)
         * See SPC3 r07, page 159.
         */
 done:
-       transport_kunmap_first_data_page(se_cmd);
+       transport_kunmap_data_sg(se_cmd);
        lun_count *= 8;
        buf[0] = ((lun_count >> 24) & 0xff);
        buf[1] = ((lun_count >> 16) & 0xff);
@@ -1294,24 +1295,26 @@ struct se_lun *core_dev_add_lun(
 {
        struct se_lun *lun_p;
        u32 lun_access = 0;
+       int rc;
 
        if (atomic_read(&dev->dev_access_obj.obj_access_count) != 0) {
                pr_err("Unable to export struct se_device while dev_access_obj: %d\n",
                        atomic_read(&dev->dev_access_obj.obj_access_count));
-               return NULL;
+               return ERR_PTR(-EACCES);
        }
 
        lun_p = core_tpg_pre_addlun(tpg, lun);
-       if ((IS_ERR(lun_p)) || !lun_p)
-               return NULL;
+       if (IS_ERR(lun_p))
+               return lun_p;
 
        if (dev->dev_flags & DF_READ_ONLY)
                lun_access = TRANSPORT_LUNFLAGS_READ_ONLY;
        else
                lun_access = TRANSPORT_LUNFLAGS_READ_WRITE;
 
-       if (core_tpg_post_addlun(tpg, lun_p, lun_access, dev) < 0)
-               return NULL;
+       rc = core_tpg_post_addlun(tpg, lun_p, lun_access, dev);
+       if (rc < 0)
+               return ERR_PTR(rc);
 
        pr_debug("%s_TPG[%u]_LUN[%u] - Activated %s Logical Unit from"
                " CORE HBA: %u\n", tpg->se_tpg_tfo->get_fabric_name(),
@@ -1348,11 +1351,10 @@ int core_dev_del_lun(
        u32 unpacked_lun)
 {
        struct se_lun *lun;
-       int ret = 0;
 
-       lun = core_tpg_pre_dellun(tpg, unpacked_lun, &ret);
-       if (!lun)
-               return ret;
+       lun = core_tpg_pre_dellun(tpg, unpacked_lun);
+       if (IS_ERR(lun))
+               return PTR_ERR(lun);
 
        core_tpg_post_dellun(tpg, lun);
 
index 4f77cce..9a2ce11 100644 (file)
@@ -766,9 +766,9 @@ static int target_fabric_port_link(
 
        lun_p = core_dev_add_lun(se_tpg, dev->se_hba, dev,
                                lun->unpacked_lun);
-       if (IS_ERR(lun_p) || !lun_p) {
+       if (IS_ERR(lun_p)) {
                pr_err("core_dev_add_lun() failed\n");
-               ret = -EINVAL;
+               ret = PTR_ERR(lun_p);
                goto out;
        }
 
index cc8e6b5..8572eae 100644 (file)
@@ -129,7 +129,7 @@ static struct se_device *iblock_create_virtdevice(
        /*
         * These settings need to be made tunable..
         */
-       ib_dev->ibd_bio_set = bioset_create(32, 64);
+       ib_dev->ibd_bio_set = bioset_create(32, 0);
        if (!ib_dev->ibd_bio_set) {
                pr_err("IBLOCK: Unable to create bioset()\n");
                return ERR_PTR(-ENOMEM);
@@ -181,7 +181,7 @@ static struct se_device *iblock_create_virtdevice(
                 */
                dev->se_sub_dev->se_dev_attrib.max_unmap_block_desc_count = 1;
                dev->se_sub_dev->se_dev_attrib.unmap_granularity =
-                               q->limits.discard_granularity;
+                               q->limits.discard_granularity >> 9;
                dev->se_sub_dev->se_dev_attrib.unmap_granularity_alignment =
                                q->limits.discard_alignment;
 
@@ -488,6 +488,13 @@ iblock_get_bio(struct se_task *task, sector_t lba, u32 sg_num)
        struct iblock_req *ib_req = IBLOCK_REQ(task);
        struct bio *bio;
 
+       /*
+        * Only allocate as many vector entries as the bio code allows us to,
+        * we'll loop later on until we have handled the whole request.
+        */
+       if (sg_num > BIO_MAX_PAGES)
+               sg_num = BIO_MAX_PAGES;
+
        bio = bio_alloc_bioset(GFP_NOIO, sg_num, ib_dev->ibd_bio_set);
        if (!bio) {
                pr_err("Unable to allocate memory for bio\n");
index 26f135e..4500136 100644 (file)
@@ -90,7 +90,7 @@ void  core_tpg_wait_for_nacl_pr_ref(struct se_node_acl *);
 struct se_lun *core_tpg_pre_addlun(struct se_portal_group *, u32);
 int    core_tpg_post_addlun(struct se_portal_group *, struct se_lun *,
                u32, void *);
-struct se_lun *core_tpg_pre_dellun(struct se_portal_group *, u32, int *);
+struct se_lun *core_tpg_pre_dellun(struct se_portal_group *, u32 unpacked_lun);
 int    core_tpg_post_dellun(struct se_portal_group *, struct se_lun *);
 
 /* target_core_transport.c */
index 429ad72..b7c7793 100644 (file)
@@ -478,6 +478,7 @@ static int core_scsi3_pr_seq_non_holder(
        case READ_MEDIA_SERIAL_NUMBER:
        case REPORT_LUNS:
        case REQUEST_SENSE:
+       case PERSISTENT_RESERVE_IN:
                ret = 0; /*/ Allowed CDBs */
                break;
        default:
@@ -1534,7 +1535,7 @@ static int core_scsi3_decode_spec_i_port(
        tidh_new->dest_local_nexus = 1;
        list_add_tail(&tidh_new->dest_list, &tid_dest_list);
 
-       buf = transport_kmap_first_data_page(cmd);
+       buf = transport_kmap_data_sg(cmd);
        /*
         * For a PERSISTENT RESERVE OUT specify initiator ports payload,
         * first extract TransportID Parameter Data Length, and make sure
@@ -1785,7 +1786,7 @@ static int core_scsi3_decode_spec_i_port(
 
        }
 
-       transport_kunmap_first_data_page(cmd);
+       transport_kunmap_data_sg(cmd);
 
        /*
         * Go ahead and create a registrations from tid_dest_list for the
@@ -1833,7 +1834,7 @@ static int core_scsi3_decode_spec_i_port(
 
        return 0;
 out:
-       transport_kunmap_first_data_page(cmd);
+       transport_kunmap_data_sg(cmd);
        /*
         * For the failure case, release everything from tid_dest_list
         * including *dest_pr_reg and the configfs dependances..
@@ -3120,7 +3121,7 @@ static int core_scsi3_pro_preempt(
                        if (!calling_it_nexus)
                                core_scsi3_ua_allocate(pr_reg_nacl,
                                        pr_res_mapped_lun, 0x2A,
-                                       ASCQ_2AH_RESERVATIONS_PREEMPTED);
+                                       ASCQ_2AH_REGISTRATIONS_PREEMPTED);
                }
                spin_unlock(&pr_tmpl->registration_lock);
                /*
@@ -3233,7 +3234,7 @@ static int core_scsi3_pro_preempt(
                 *    additional sense code set to REGISTRATIONS PREEMPTED;
                 */
                core_scsi3_ua_allocate(pr_reg_nacl, pr_res_mapped_lun, 0x2A,
-                               ASCQ_2AH_RESERVATIONS_PREEMPTED);
+                               ASCQ_2AH_REGISTRATIONS_PREEMPTED);
        }
        spin_unlock(&pr_tmpl->registration_lock);
        /*
@@ -3410,14 +3411,14 @@ static int core_scsi3_emulate_pro_register_and_move(
         * will be moved to for the TransportID containing SCSI initiator WWN
         * information.
         */
-       buf = transport_kmap_first_data_page(cmd);
+       buf = transport_kmap_data_sg(cmd);
        rtpi = (buf[18] & 0xff) << 8;
        rtpi |= buf[19] & 0xff;
        tid_len = (buf[20] & 0xff) << 24;
        tid_len |= (buf[21] & 0xff) << 16;
        tid_len |= (buf[22] & 0xff) << 8;
        tid_len |= buf[23] & 0xff;
-       transport_kunmap_first_data_page(cmd);
+       transport_kunmap_data_sg(cmd);
        buf = NULL;
 
        if ((tid_len + 24) != cmd->data_length) {
@@ -3469,7 +3470,7 @@ static int core_scsi3_emulate_pro_register_and_move(
                return -EINVAL;
        }
 
-       buf = transport_kmap_first_data_page(cmd);
+       buf = transport_kmap_data_sg(cmd);
        proto_ident = (buf[24] & 0x0f);
 #if 0
        pr_debug("SPC-3 PR REGISTER_AND_MOVE: Extracted Protocol Identifier:"
@@ -3503,7 +3504,7 @@ static int core_scsi3_emulate_pro_register_and_move(
                goto out;
        }
 
-       transport_kunmap_first_data_page(cmd);
+       transport_kunmap_data_sg(cmd);
        buf = NULL;
 
        pr_debug("SPC-3 PR [%s] Extracted initiator %s identifier: %s"
@@ -3768,13 +3769,13 @@ after_iport_check:
                                        " REGISTER_AND_MOVE\n");
        }
 
-       transport_kunmap_first_data_page(cmd);
+       transport_kunmap_data_sg(cmd);
 
        core_scsi3_put_pr_reg(dest_pr_reg);
        return 0;
 out:
        if (buf)
-               transport_kunmap_first_data_page(cmd);
+               transport_kunmap_data_sg(cmd);
        if (dest_se_deve)
                core_scsi3_lunacl_undepend_item(dest_se_deve);
        if (dest_node_acl)
@@ -3848,7 +3849,7 @@ int target_scsi3_emulate_pr_out(struct se_task *task)
        scope = (cdb[2] & 0xf0);
        type = (cdb[2] & 0x0f);
 
-       buf = transport_kmap_first_data_page(cmd);
+       buf = transport_kmap_data_sg(cmd);
        /*
         * From PERSISTENT_RESERVE_OUT parameter list (payload)
         */
@@ -3866,7 +3867,7 @@ int target_scsi3_emulate_pr_out(struct se_task *task)
                aptpl = (buf[17] & 0x01);
                unreg = (buf[17] & 0x02);
        }
-       transport_kunmap_first_data_page(cmd);
+       transport_kunmap_data_sg(cmd);
        buf = NULL;
 
        /*
@@ -3966,7 +3967,7 @@ static int core_scsi3_pri_read_keys(struct se_cmd *cmd)
                return -EINVAL;
        }
 
-       buf = transport_kmap_first_data_page(cmd);
+       buf = transport_kmap_data_sg(cmd);
        buf[0] = ((su_dev->t10_pr.pr_generation >> 24) & 0xff);
        buf[1] = ((su_dev->t10_pr.pr_generation >> 16) & 0xff);
        buf[2] = ((su_dev->t10_pr.pr_generation >> 8) & 0xff);
@@ -4000,7 +4001,7 @@ static int core_scsi3_pri_read_keys(struct se_cmd *cmd)
        buf[6] = ((add_len >> 8) & 0xff);
        buf[7] = (add_len & 0xff);
 
-       transport_kunmap_first_data_page(cmd);
+       transport_kunmap_data_sg(cmd);
 
        return 0;
 }
@@ -4026,7 +4027,7 @@ static int core_scsi3_pri_read_reservation(struct se_cmd *cmd)
                return -EINVAL;
        }
 
-       buf = transport_kmap_first_data_page(cmd);
+       buf = transport_kmap_data_sg(cmd);
        buf[0] = ((su_dev->t10_pr.pr_generation >> 24) & 0xff);
        buf[1] = ((su_dev->t10_pr.pr_generation >> 16) & 0xff);
        buf[2] = ((su_dev->t10_pr.pr_generation >> 8) & 0xff);
@@ -4085,7 +4086,7 @@ static int core_scsi3_pri_read_reservation(struct se_cmd *cmd)
 
 err:
        spin_unlock(&se_dev->dev_reservation_lock);
-       transport_kunmap_first_data_page(cmd);
+       transport_kunmap_data_sg(cmd);
 
        return 0;
 }
@@ -4109,7 +4110,7 @@ static int core_scsi3_pri_report_capabilities(struct se_cmd *cmd)
                return -EINVAL;
        }
 
-       buf = transport_kmap_first_data_page(cmd);
+       buf = transport_kmap_data_sg(cmd);
 
        buf[0] = ((add_len << 8) & 0xff);
        buf[1] = (add_len & 0xff);
@@ -4141,7 +4142,7 @@ static int core_scsi3_pri_report_capabilities(struct se_cmd *cmd)
        buf[4] |= 0x02; /* PR_TYPE_WRITE_EXCLUSIVE */
        buf[5] |= 0x01; /* PR_TYPE_EXCLUSIVE_ACCESS_ALLREG */
 
-       transport_kunmap_first_data_page(cmd);
+       transport_kunmap_data_sg(cmd);
 
        return 0;
 }
@@ -4171,7 +4172,7 @@ static int core_scsi3_pri_read_full_status(struct se_cmd *cmd)
                return -EINVAL;
        }
 
-       buf = transport_kmap_first_data_page(cmd);
+       buf = transport_kmap_data_sg(cmd);
 
        buf[0] = ((su_dev->t10_pr.pr_generation >> 24) & 0xff);
        buf[1] = ((su_dev->t10_pr.pr_generation >> 16) & 0xff);
@@ -4292,7 +4293,7 @@ static int core_scsi3_pri_read_full_status(struct se_cmd *cmd)
        buf[6] = ((add_len >> 8) & 0xff);
        buf[7] = (add_len & 0xff);
 
-       transport_kunmap_first_data_page(cmd);
+       transport_kunmap_data_sg(cmd);
 
        return 0;
 }
index d35467d..8d4def3 100644 (file)
@@ -693,7 +693,7 @@ static int pscsi_transport_complete(struct se_task *task)
 
                if (task->task_se_cmd->se_deve->lun_flags &
                                TRANSPORT_LUNFLAGS_READ_ONLY) {
-                       unsigned char *buf = transport_kmap_first_data_page(task->task_se_cmd);
+                       unsigned char *buf = transport_kmap_data_sg(task->task_se_cmd);
 
                        if (cdb[0] == MODE_SENSE_10) {
                                if (!(buf[3] & 0x80))
@@ -703,7 +703,7 @@ static int pscsi_transport_complete(struct se_task *task)
                                        buf[2] |= 0x80;
                        }
 
-                       transport_kunmap_first_data_page(task->task_se_cmd);
+                       transport_kunmap_data_sg(task->task_se_cmd);
                }
        }
 after_mode_sense:
index b766802..06336ec 100644 (file)
@@ -807,8 +807,7 @@ static void core_tpg_shutdown_lun(
 
 struct se_lun *core_tpg_pre_dellun(
        struct se_portal_group *tpg,
-       u32 unpacked_lun,
-       int *ret)
+       u32 unpacked_lun)
 {
        struct se_lun *lun;
 
index d3ddd13..58cea07 100644 (file)
@@ -1255,32 +1255,34 @@ static void core_setup_task_attr_emulation(struct se_device *dev)
 static void scsi_dump_inquiry(struct se_device *dev)
 {
        struct t10_wwn *wwn = &dev->se_sub_dev->t10_wwn;
+       char buf[17];
        int i, device_type;
        /*
         * Print Linux/SCSI style INQUIRY formatting to the kernel ring buffer
         */
-       pr_debug("  Vendor: ");
        for (i = 0; i < 8; i++)
                if (wwn->vendor[i] >= 0x20)
-                       pr_debug("%c", wwn->vendor[i]);
+                       buf[i] = wwn->vendor[i];
                else
-                       pr_debug(" ");
+                       buf[i] = ' ';
+       buf[i] = '\0';
+       pr_debug("  Vendor: %s\n", buf);
 
-       pr_debug("  Model: ");
        for (i = 0; i < 16; i++)
                if (wwn->model[i] >= 0x20)
-                       pr_debug("%c", wwn->model[i]);
+                       buf[i] = wwn->model[i];
                else
-                       pr_debug(" ");
+                       buf[i] = ' ';
+       buf[i] = '\0';
+       pr_debug("  Model: %s\n", buf);
 
-       pr_debug("  Revision: ");
        for (i = 0; i < 4; i++)
                if (wwn->revision[i] >= 0x20)
-                       pr_debug("%c", wwn->revision[i]);
+                       buf[i] = wwn->revision[i];
                else
-                       pr_debug(" ");
-
-       pr_debug("\n");
+                       buf[i] = ' ';
+       buf[i] = '\0';
+       pr_debug("  Revision: %s\n", buf);
 
        device_type = dev->transport->get_device_type(dev);
        pr_debug("  Type:   %s ", scsi_device_type(device_type));
@@ -1655,7 +1657,7 @@ EXPORT_SYMBOL(transport_handle_cdb_direct);
  * This may only be called from process context, and also currently
  * assumes internal allocation of fabric payload buffer by target-core.
  **/
-int target_submit_cmd(struct se_cmd *se_cmd, struct se_session *se_sess,
+void target_submit_cmd(struct se_cmd *se_cmd, struct se_session *se_sess,
                unsigned char *cdb, unsigned char *sense, u32 unpacked_lun,
                u32 data_length, int task_attr, int data_dir, int flags)
 {
@@ -1688,15 +1690,21 @@ int target_submit_cmd(struct se_cmd *se_cmd, struct se_session *se_sess,
        /*
         * Locate se_lun pointer and attach it to struct se_cmd
         */
-       if (transport_lookup_cmd_lun(se_cmd, unpacked_lun) < 0)
-               goto out_check_cond;
+       if (transport_lookup_cmd_lun(se_cmd, unpacked_lun) < 0) {
+               transport_send_check_condition_and_sense(se_cmd,
+                               se_cmd->scsi_sense_reason, 0);
+               target_put_sess_cmd(se_sess, se_cmd);
+               return;
+       }
        /*
         * Sanitize CDBs via transport_generic_cmd_sequencer() and
         * allocate the necessary tasks to complete the received CDB+data
         */
        rc = transport_generic_allocate_tasks(se_cmd, cdb);
-       if (rc != 0)
-               goto out_check_cond;
+       if (rc != 0) {
+               transport_generic_request_failure(se_cmd);
+               return;
+       }
        /*
         * Dispatch se_cmd descriptor to se_lun->lun_se_dev backend
         * for immediate execution of READs, otherwise wait for
@@ -1704,12 +1712,7 @@ int target_submit_cmd(struct se_cmd *se_cmd, struct se_session *se_sess,
         * when fabric has filled the incoming buffer.
         */
        transport_handle_cdb_direct(se_cmd);
-       return 0;
-
-out_check_cond:
-       transport_send_check_condition_and_sense(se_cmd,
-                               se_cmd->scsi_sense_reason, 0);
-       return 0;
+       return;
 }
 EXPORT_SYMBOL(target_submit_cmd);
 
@@ -2694,7 +2697,7 @@ static int transport_generic_cmd_sequencer(
                        cmd->se_cmd_flags |= SCF_SCSI_CONTROL_SG_IO_CDB;
 
                        if (target_check_write_same_discard(&cdb[10], dev) < 0)
-                               goto out_invalid_cdb_field;
+                               goto out_unsupported_cdb;
                        if (!passthrough)
                                cmd->execute_task = target_emulate_write_same;
                        break;
@@ -2977,7 +2980,7 @@ static int transport_generic_cmd_sequencer(
                cmd->se_cmd_flags |= SCF_SCSI_CONTROL_SG_IO_CDB;
 
                if (target_check_write_same_discard(&cdb[1], dev) < 0)
-                       goto out_invalid_cdb_field;
+                       goto out_unsupported_cdb;
                if (!passthrough)
                        cmd->execute_task = target_emulate_write_same;
                break;
@@ -3000,7 +3003,7 @@ static int transport_generic_cmd_sequencer(
                 * of byte 1 bit 3 UNMAP instead of original reserved field
                 */
                if (target_check_write_same_discard(&cdb[1], dev) < 0)
-                       goto out_invalid_cdb_field;
+                       goto out_unsupported_cdb;
                if (!passthrough)
                        cmd->execute_task = target_emulate_write_same;
                break;
@@ -3082,11 +3085,6 @@ static int transport_generic_cmd_sequencer(
             (cmd->se_cmd_flags & SCF_SCSI_DATA_SG_IO_CDB)))
                goto out_unsupported_cdb;
 
-       /* Let's limit control cdbs to a page, for simplicity's sake. */
-       if ((cmd->se_cmd_flags & SCF_SCSI_CONTROL_SG_IO_CDB) &&
-           size > PAGE_SIZE)
-               goto out_invalid_cdb_field;
-
        transport_set_supported_SAM_opcode(cmd);
        return ret;
 
@@ -3490,9 +3488,11 @@ int transport_generic_map_mem_to_cmd(
 }
 EXPORT_SYMBOL(transport_generic_map_mem_to_cmd);
 
-void *transport_kmap_first_data_page(struct se_cmd *cmd)
+void *transport_kmap_data_sg(struct se_cmd *cmd)
 {
        struct scatterlist *sg = cmd->t_data_sg;
+       struct page **pages;
+       int i;
 
        BUG_ON(!sg);
        /*
@@ -3500,15 +3500,41 @@ void *transport_kmap_first_data_page(struct se_cmd *cmd)
         * tcm_loop who may be using a contig buffer from the SCSI midlayer for
         * control CDBs passed as SGLs via transport_generic_map_mem_to_cmd()
         */
-       return kmap(sg_page(sg)) + sg->offset;
+       if (!cmd->t_data_nents)
+               return NULL;
+       else if (cmd->t_data_nents == 1)
+               return kmap(sg_page(sg)) + sg->offset;
+
+       /* >1 page. use vmap */
+       pages = kmalloc(sizeof(*pages) * cmd->t_data_nents, GFP_KERNEL);
+       if (!pages)
+               return NULL;
+
+       /* convert sg[] to pages[] */
+       for_each_sg(cmd->t_data_sg, sg, cmd->t_data_nents, i) {
+               pages[i] = sg_page(sg);
+       }
+
+       cmd->t_data_vmap = vmap(pages, cmd->t_data_nents,  VM_MAP, PAGE_KERNEL);
+       kfree(pages);
+       if (!cmd->t_data_vmap)
+               return NULL;
+
+       return cmd->t_data_vmap + cmd->t_data_sg[0].offset;
 }
-EXPORT_SYMBOL(transport_kmap_first_data_page);
+EXPORT_SYMBOL(transport_kmap_data_sg);
 
-void transport_kunmap_first_data_page(struct se_cmd *cmd)
+void transport_kunmap_data_sg(struct se_cmd *cmd)
 {
-       kunmap(sg_page(cmd->t_data_sg));
+       if (!cmd->t_data_nents)
+               return;
+       else if (cmd->t_data_nents == 1)
+               kunmap(sg_page(cmd->t_data_sg));
+
+       vunmap(cmd->t_data_vmap);
+       cmd->t_data_vmap = NULL;
 }
-EXPORT_SYMBOL(transport_kunmap_first_data_page);
+EXPORT_SYMBOL(transport_kunmap_data_sg);
 
 static int
 transport_generic_get_mem(struct se_cmd *cmd)
@@ -3516,6 +3542,7 @@ transport_generic_get_mem(struct se_cmd *cmd)
        u32 length = cmd->data_length;
        unsigned int nents;
        struct page *page;
+       gfp_t zero_flag;
        int i = 0;
 
        nents = DIV_ROUND_UP(length, PAGE_SIZE);
@@ -3526,9 +3553,11 @@ transport_generic_get_mem(struct se_cmd *cmd)
        cmd->t_data_nents = nents;
        sg_init_table(cmd->t_data_sg, nents);
 
+       zero_flag = cmd->se_cmd_flags & SCF_SCSI_DATA_SG_IO_CDB ? 0 : __GFP_ZERO;
+
        while (length) {
                u32 page_len = min_t(u32, length, PAGE_SIZE);
-               page = alloc_page(GFP_KERNEL | __GFP_ZERO);
+               page = alloc_page(GFP_KERNEL | zero_flag);
                if (!page)
                        goto out;
 
@@ -3756,6 +3785,11 @@ transport_allocate_control_task(struct se_cmd *cmd)
        struct se_task *task;
        unsigned long flags;
 
+       /* Workaround for handling zero-length control CDBs */
+       if ((cmd->se_cmd_flags & SCF_SCSI_CONTROL_SG_IO_CDB) &&
+           !cmd->data_length)
+               return 0;
+
        task = transport_generic_get_task(cmd, cmd->data_direction);
        if (!task)
                return -ENOMEM;
@@ -3827,6 +3861,14 @@ int transport_generic_new_cmd(struct se_cmd *cmd)
        else if (!task_cdbs && (cmd->se_cmd_flags & SCF_SCSI_DATA_SG_IO_CDB)) {
                cmd->t_state = TRANSPORT_COMPLETE;
                atomic_set(&cmd->t_transport_active, 1);
+
+               if (cmd->t_task_cdb[0] == REQUEST_SENSE) {
+                       u8 ua_asc = 0, ua_ascq = 0;
+
+                       core_scsi3_ua_clear_for_request_sense(cmd,
+                                       &ua_asc, &ua_ascq);
+               }
+
                INIT_WORK(&cmd->work, target_complete_ok_work);
                queue_work(target_completion_wq, &cmd->work);
                return 0;
@@ -4448,8 +4490,8 @@ int transport_send_check_condition_and_sense(
                /* CURRENT ERROR */
                buffer[offset] = 0x70;
                buffer[offset+SPC_ADD_SENSE_LEN_OFFSET] = 10;
-               /* ABORTED COMMAND */
-               buffer[offset+SPC_SENSE_KEY_OFFSET] = ABORTED_COMMAND;
+               /* ILLEGAL REQUEST */
+               buffer[offset+SPC_SENSE_KEY_OFFSET] = ILLEGAL_REQUEST;
                /* INVALID FIELD IN CDB */
                buffer[offset+SPC_ASC_KEY_OFFSET] = 0x24;
                break;
@@ -4457,8 +4499,8 @@ int transport_send_check_condition_and_sense(
                /* CURRENT ERROR */
                buffer[offset] = 0x70;
                buffer[offset+SPC_ADD_SENSE_LEN_OFFSET] = 10;
-               /* ABORTED COMMAND */
-               buffer[offset+SPC_SENSE_KEY_OFFSET] = ABORTED_COMMAND;
+               /* ILLEGAL REQUEST */
+               buffer[offset+SPC_SENSE_KEY_OFFSET] = ILLEGAL_REQUEST;
                /* INVALID FIELD IN PARAMETER LIST */
                buffer[offset+SPC_ASC_KEY_OFFSET] = 0x26;
                break;
index addc18f..9e7e26c 100644 (file)
@@ -540,7 +540,6 @@ static void ft_send_work(struct work_struct *work)
        int data_dir = 0;
        u32 data_len;
        int task_attr;
-       int ret;
 
        fcp = fc_frame_payload_get(cmd->req_frame, sizeof(*fcp));
        if (!fcp)
@@ -603,14 +602,10 @@ static void ft_send_work(struct work_struct *work)
         * Use a single se_cmd->cmd_kref as we expect to release se_cmd
         * directly from ft_check_stop_free callback in response path.
         */
-       ret = target_submit_cmd(&cmd->se_cmd, cmd->sess->se_sess, cmd->cdb,
+       target_submit_cmd(&cmd->se_cmd, cmd->sess->se_sess, cmd->cdb,
                                &cmd->ft_sense_buffer[0], cmd->lun, data_len,
                                task_attr, data_dir, 0);
-       pr_debug("r_ctl %x alloc target_submit_cmd %d\n", fh->fh_r_ctl, ret);
-       if (ret < 0) {
-               ft_dump_cmd(cmd, __func__);
-               return;
-       }
+       pr_debug("r_ctl %x alloc target_submit_cmd\n", fh->fh_r_ctl);
        return;
 
 err:
diff --git a/drivers/tty/serial/8250.c b/drivers/tty/serial/8250.c
deleted file mode 100644 (file)
index 9f50c4e..0000000
+++ /dev/null
@@ -1,3357 +0,0 @@
-/*
- *  Driver for 8250/16550-type serial ports
- *
- *  Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o.
- *
- *  Copyright (C) 2001 Russell King.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * A note about mapbase / membase
- *
- *  mapbase is the physical address of the IO port.
- *  membase is an 'ioremapped' cookie.
- */
-
-#if defined(CONFIG_SERIAL_8250_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
-#define SUPPORT_SYSRQ
-#endif
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/ioport.h>
-#include <linux/init.h>
-#include <linux/console.h>
-#include <linux/sysrq.h>
-#include <linux/delay.h>
-#include <linux/platform_device.h>
-#include <linux/tty.h>
-#include <linux/ratelimit.h>
-#include <linux/tty_flip.h>
-#include <linux/serial_reg.h>
-#include <linux/serial_core.h>
-#include <linux/serial.h>
-#include <linux/serial_8250.h>
-#include <linux/nmi.h>
-#include <linux/mutex.h>
-#include <linux/slab.h>
-
-#include <asm/io.h>
-#include <asm/irq.h>
-
-#include "8250.h"
-
-#ifdef CONFIG_SPARC
-#include "suncore.h"
-#endif
-
-/*
- * Configuration:
- *   share_irqs - whether we pass IRQF_SHARED to request_irq().  This option
- *                is unsafe when used on edge-triggered interrupts.
- */
-static unsigned int share_irqs = SERIAL8250_SHARE_IRQS;
-
-static unsigned int nr_uarts = CONFIG_SERIAL_8250_RUNTIME_UARTS;
-
-static struct uart_driver serial8250_reg;
-
-static int serial_index(struct uart_port *port)
-{
-       return (serial8250_reg.minor - 64) + port->line;
-}
-
-static unsigned int skip_txen_test; /* force skip of txen test at init time */
-
-/*
- * Debugging.
- */
-#if 0
-#define DEBUG_AUTOCONF(fmt...) printk(fmt)
-#else
-#define DEBUG_AUTOCONF(fmt...) do { } while (0)
-#endif
-
-#if 0
-#define DEBUG_INTR(fmt...)     printk(fmt)
-#else
-#define DEBUG_INTR(fmt...)     do { } while (0)
-#endif
-
-#define PASS_LIMIT     512
-
-#define BOTH_EMPTY     (UART_LSR_TEMT | UART_LSR_THRE)
-
-
-/*
- * We default to IRQ0 for the "no irq" hack.   Some
- * machine types want others as well - they're free
- * to redefine this in their header file.
- */
-#define is_real_interrupt(irq) ((irq) != 0)
-
-#ifdef CONFIG_SERIAL_8250_DETECT_IRQ
-#define CONFIG_SERIAL_DETECT_IRQ 1
-#endif
-#ifdef CONFIG_SERIAL_8250_MANY_PORTS
-#define CONFIG_SERIAL_MANY_PORTS 1
-#endif
-
-/*
- * HUB6 is always on.  This will be removed once the header
- * files have been cleaned.
- */
-#define CONFIG_HUB6 1
-
-#include <asm/serial.h>
-/*
- * SERIAL_PORT_DFNS tells us about built-in ports that have no
- * standard enumeration mechanism.   Platforms that can find all
- * serial ports via mechanisms like ACPI or PCI need not supply it.
- */
-#ifndef SERIAL_PORT_DFNS
-#define SERIAL_PORT_DFNS
-#endif
-
-static const struct old_serial_port old_serial_port[] = {
-       SERIAL_PORT_DFNS /* defined in asm/serial.h */
-};
-
-#define UART_NR        CONFIG_SERIAL_8250_NR_UARTS
-
-#ifdef CONFIG_SERIAL_8250_RSA
-
-#define PORT_RSA_MAX 4
-static unsigned long probe_rsa[PORT_RSA_MAX];
-static unsigned int probe_rsa_count;
-#endif /* CONFIG_SERIAL_8250_RSA  */
-
-struct irq_info {
-       struct                  hlist_node node;
-       int                     irq;
-       spinlock_t              lock;   /* Protects list not the hash */
-       struct list_head        *head;
-};
-
-#define NR_IRQ_HASH            32      /* Can be adjusted later */
-static struct hlist_head irq_lists[NR_IRQ_HASH];
-static DEFINE_MUTEX(hash_mutex);       /* Used to walk the hash */
-
-/*
- * Here we define the default xmit fifo size used for each type of UART.
- */
-static const struct serial8250_config uart_config[] = {
-       [PORT_UNKNOWN] = {
-               .name           = "unknown",
-               .fifo_size      = 1,
-               .tx_loadsz      = 1,
-       },
-       [PORT_8250] = {
-               .name           = "8250",
-               .fifo_size      = 1,
-               .tx_loadsz      = 1,
-       },
-       [PORT_16450] = {
-               .name           = "16450",
-               .fifo_size      = 1,
-               .tx_loadsz      = 1,
-       },
-       [PORT_16550] = {
-               .name           = "16550",
-               .fifo_size      = 1,
-               .tx_loadsz      = 1,
-       },
-       [PORT_16550A] = {
-               .name           = "16550A",
-               .fifo_size      = 16,
-               .tx_loadsz      = 16,
-               .fcr            = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10,
-               .flags          = UART_CAP_FIFO,
-       },
-       [PORT_CIRRUS] = {
-               .name           = "Cirrus",
-               .fifo_size      = 1,
-               .tx_loadsz      = 1,
-       },
-       [PORT_16650] = {
-               .name           = "ST16650",
-               .fifo_size      = 1,
-               .tx_loadsz      = 1,
-               .flags          = UART_CAP_FIFO | UART_CAP_EFR | UART_CAP_SLEEP,
-       },
-       [PORT_16650V2] = {
-               .name           = "ST16650V2",
-               .fifo_size      = 32,
-               .tx_loadsz      = 16,
-               .fcr            = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_01 |
-                                 UART_FCR_T_TRIG_00,
-               .flags          = UART_CAP_FIFO | UART_CAP_EFR | UART_CAP_SLEEP,
-       },
-       [PORT_16750] = {
-               .name           = "TI16750",
-               .fifo_size      = 64,
-               .tx_loadsz      = 64,
-               .fcr            = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10 |
-                                 UART_FCR7_64BYTE,
-               .flags          = UART_CAP_FIFO | UART_CAP_SLEEP | UART_CAP_AFE,
-       },
-       [PORT_STARTECH] = {
-               .name           = "Startech",
-               .fifo_size      = 1,
-               .tx_loadsz      = 1,
-       },
-       [PORT_16C950] = {
-               .name           = "16C950/954",
-               .fifo_size      = 128,
-               .tx_loadsz      = 128,
-               .fcr            = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10,
-               /* UART_CAP_EFR breaks billionon CF bluetooth card. */
-               .flags          = UART_CAP_FIFO | UART_CAP_SLEEP,
-       },
-       [PORT_16654] = {
-               .name           = "ST16654",
-               .fifo_size      = 64,
-               .tx_loadsz      = 32,
-               .fcr            = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_01 |
-                                 UART_FCR_T_TRIG_10,
-               .flags          = UART_CAP_FIFO | UART_CAP_EFR | UART_CAP_SLEEP,
-       },
-       [PORT_16850] = {
-               .name           = "XR16850",
-               .fifo_size      = 128,
-               .tx_loadsz      = 128,
-               .fcr            = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10,
-               .flags          = UART_CAP_FIFO | UART_CAP_EFR | UART_CAP_SLEEP,
-       },
-       [PORT_RSA] = {
-               .name           = "RSA",
-               .fifo_size      = 2048,
-               .tx_loadsz      = 2048,
-               .fcr            = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_11,
-               .flags          = UART_CAP_FIFO,
-       },
-       [PORT_NS16550A] = {
-               .name           = "NS16550A",
-               .fifo_size      = 16,
-               .tx_loadsz      = 16,
-               .fcr            = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10,
-               .flags          = UART_CAP_FIFO | UART_NATSEMI,
-       },
-       [PORT_XSCALE] = {
-               .name           = "XScale",
-               .fifo_size      = 32,
-               .tx_loadsz      = 32,
-               .fcr            = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10,
-               .flags          = UART_CAP_FIFO | UART_CAP_UUE | UART_CAP_RTOIE,
-       },
-       [PORT_RM9000] = {
-               .name           = "RM9000",
-               .fifo_size      = 16,
-               .tx_loadsz      = 16,
-               .fcr            = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10,
-               .flags          = UART_CAP_FIFO,
-       },
-       [PORT_OCTEON] = {
-               .name           = "OCTEON",
-               .fifo_size      = 64,
-               .tx_loadsz      = 64,
-               .fcr            = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10,
-               .flags          = UART_CAP_FIFO,
-       },
-       [PORT_AR7] = {
-               .name           = "AR7",
-               .fifo_size      = 16,
-               .tx_loadsz      = 16,
-               .fcr            = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_00,
-               .flags          = UART_CAP_FIFO | UART_CAP_AFE,
-       },
-       [PORT_U6_16550A] = {
-               .name           = "U6_16550A",
-               .fifo_size      = 64,
-               .tx_loadsz      = 64,
-               .fcr            = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10,
-               .flags          = UART_CAP_FIFO | UART_CAP_AFE,
-       },
-       [PORT_TEGRA] = {
-               .name           = "Tegra",
-               .fifo_size      = 32,
-               .tx_loadsz      = 8,
-               .fcr            = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_01 |
-                                 UART_FCR_T_TRIG_01,
-               .flags          = UART_CAP_FIFO | UART_CAP_RTOIE,
-       },
-       [PORT_XR17D15X] = {
-               .name           = "XR17D15X",
-               .fifo_size      = 64,
-               .tx_loadsz      = 64,
-               .fcr            = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10,
-               .flags          = UART_CAP_FIFO | UART_CAP_AFE | UART_CAP_EFR,
-       },
-};
-
-#if defined(CONFIG_MIPS_ALCHEMY)
-
-/* Au1x00 UART hardware has a weird register layout */
-static const u8 au_io_in_map[] = {
-       [UART_RX]  = 0,
-       [UART_IER] = 2,
-       [UART_IIR] = 3,
-       [UART_LCR] = 5,
-       [UART_MCR] = 6,
-       [UART_LSR] = 7,
-       [UART_MSR] = 8,
-};
-
-static const u8 au_io_out_map[] = {
-       [UART_TX]  = 1,
-       [UART_IER] = 2,
-       [UART_FCR] = 4,
-       [UART_LCR] = 5,
-       [UART_MCR] = 6,
-};
-
-/* sane hardware needs no mapping */
-static inline int map_8250_in_reg(struct uart_port *p, int offset)
-{
-       if (p->iotype != UPIO_AU)
-               return offset;
-       return au_io_in_map[offset];
-}
-
-static inline int map_8250_out_reg(struct uart_port *p, int offset)
-{
-       if (p->iotype != UPIO_AU)
-               return offset;
-       return au_io_out_map[offset];
-}
-
-#elif defined(CONFIG_SERIAL_8250_RM9K)
-
-static const u8
-       regmap_in[8] = {
-               [UART_RX]       = 0x00,
-               [UART_IER]      = 0x0c,
-               [UART_IIR]      = 0x14,
-               [UART_LCR]      = 0x1c,
-               [UART_MCR]      = 0x20,
-               [UART_LSR]      = 0x24,
-               [UART_MSR]      = 0x28,
-               [UART_SCR]      = 0x2c
-       },
-       regmap_out[8] = {
-               [UART_TX]       = 0x04,
-               [UART_IER]      = 0x0c,
-               [UART_FCR]      = 0x18,
-               [UART_LCR]      = 0x1c,
-               [UART_MCR]      = 0x20,
-               [UART_LSR]      = 0x24,
-               [UART_MSR]      = 0x28,
-               [UART_SCR]      = 0x2c
-       };
-
-static inline int map_8250_in_reg(struct uart_port *p, int offset)
-{
-       if (p->iotype != UPIO_RM9000)
-               return offset;
-       return regmap_in[offset];
-}
-
-static inline int map_8250_out_reg(struct uart_port *p, int offset)
-{
-       if (p->iotype != UPIO_RM9000)
-               return offset;
-       return regmap_out[offset];
-}
-
-#else
-
-/* sane hardware needs no mapping */
-#define map_8250_in_reg(up, offset) (offset)
-#define map_8250_out_reg(up, offset) (offset)
-
-#endif
-
-static unsigned int hub6_serial_in(struct uart_port *p, int offset)
-{
-       offset = map_8250_in_reg(p, offset) << p->regshift;
-       outb(p->hub6 - 1 + offset, p->iobase);
-       return inb(p->iobase + 1);
-}
-
-static void hub6_serial_out(struct uart_port *p, int offset, int value)
-{
-       offset = map_8250_out_reg(p, offset) << p->regshift;
-       outb(p->hub6 - 1 + offset, p->iobase);
-       outb(value, p->iobase + 1);
-}
-
-static unsigned int mem_serial_in(struct uart_port *p, int offset)
-{
-       offset = map_8250_in_reg(p, offset) << p->regshift;
-       return readb(p->membase + offset);
-}
-
-static void mem_serial_out(struct uart_port *p, int offset, int value)
-{
-       offset = map_8250_out_reg(p, offset) << p->regshift;
-       writeb(value, p->membase + offset);
-}
-
-static void mem32_serial_out(struct uart_port *p, int offset, int value)
-{
-       offset = map_8250_out_reg(p, offset) << p->regshift;
-       writel(value, p->membase + offset);
-}
-
-static unsigned int mem32_serial_in(struct uart_port *p, int offset)
-{
-       offset = map_8250_in_reg(p, offset) << p->regshift;
-       return readl(p->membase + offset);
-}
-
-static unsigned int au_serial_in(struct uart_port *p, int offset)
-{
-       offset = map_8250_in_reg(p, offset) << p->regshift;
-       return __raw_readl(p->membase + offset);
-}
-
-static void au_serial_out(struct uart_port *p, int offset, int value)
-{
-       offset = map_8250_out_reg(p, offset) << p->regshift;
-       __raw_writel(value, p->membase + offset);
-}
-
-static unsigned int io_serial_in(struct uart_port *p, int offset)
-{
-       offset = map_8250_in_reg(p, offset) << p->regshift;
-       return inb(p->iobase + offset);
-}
-
-static void io_serial_out(struct uart_port *p, int offset, int value)
-{
-       offset = map_8250_out_reg(p, offset) << p->regshift;
-       outb(value, p->iobase + offset);
-}
-
-static int serial8250_default_handle_irq(struct uart_port *port);
-
-static void set_io_from_upio(struct uart_port *p)
-{
-       struct uart_8250_port *up =
-               container_of(p, struct uart_8250_port, port);
-       switch (p->iotype) {
-       case UPIO_HUB6:
-               p->serial_in = hub6_serial_in;
-               p->serial_out = hub6_serial_out;
-               break;
-
-       case UPIO_MEM:
-               p->serial_in = mem_serial_in;
-               p->serial_out = mem_serial_out;
-               break;
-
-       case UPIO_RM9000:
-       case UPIO_MEM32:
-               p->serial_in = mem32_serial_in;
-               p->serial_out = mem32_serial_out;
-               break;
-
-       case UPIO_AU:
-               p->serial_in = au_serial_in;
-               p->serial_out = au_serial_out;
-               break;
-
-       default:
-               p->serial_in = io_serial_in;
-               p->serial_out = io_serial_out;
-               break;
-       }
-       /* Remember loaded iotype */
-       up->cur_iotype = p->iotype;
-       p->handle_irq = serial8250_default_handle_irq;
-}
-
-static void
-serial_out_sync(struct uart_8250_port *up, int offset, int value)
-{
-       struct uart_port *p = &up->port;
-       switch (p->iotype) {
-       case UPIO_MEM:
-       case UPIO_MEM32:
-       case UPIO_AU:
-               p->serial_out(p, offset, value);
-               p->serial_in(p, UART_LCR);      /* safe, no side-effects */
-               break;
-       default:
-               p->serial_out(p, offset, value);
-       }
-}
-
-#define serial_in(up, offset)          \
-       (up->port.serial_in(&(up)->port, (offset)))
-#define serial_out(up, offset, value)  \
-       (up->port.serial_out(&(up)->port, (offset), (value)))
-/*
- * We used to support using pause I/O for certain machines.  We
- * haven't supported this for a while, but just in case it's badly
- * needed for certain old 386 machines, I've left these #define's
- * in....
- */
-#define serial_inp(up, offset)         serial_in(up, offset)
-#define serial_outp(up, offset, value) serial_out(up, offset, value)
-
-/* Uart divisor latch read */
-static inline int _serial_dl_read(struct uart_8250_port *up)
-{
-       return serial_inp(up, UART_DLL) | serial_inp(up, UART_DLM) << 8;
-}
-
-/* Uart divisor latch write */
-static inline void _serial_dl_write(struct uart_8250_port *up, int value)
-{
-       serial_outp(up, UART_DLL, value & 0xff);
-       serial_outp(up, UART_DLM, value >> 8 & 0xff);
-}
-
-#if defined(CONFIG_MIPS_ALCHEMY)
-/* Au1x00 haven't got a standard divisor latch */
-static int serial_dl_read(struct uart_8250_port *up)
-{
-       if (up->port.iotype == UPIO_AU)
-               return __raw_readl(up->port.membase + 0x28);
-       else
-               return _serial_dl_read(up);
-}
-
-static void serial_dl_write(struct uart_8250_port *up, int value)
-{
-       if (up->port.iotype == UPIO_AU)
-               __raw_writel(value, up->port.membase + 0x28);
-       else
-               _serial_dl_write(up, value);
-}
-#elif defined(CONFIG_SERIAL_8250_RM9K)
-static int serial_dl_read(struct uart_8250_port *up)
-{
-       return  (up->port.iotype == UPIO_RM9000) ?
-               (((__raw_readl(up->port.membase + 0x10) << 8) |
-               (__raw_readl(up->port.membase + 0x08) & 0xff)) & 0xffff) :
-               _serial_dl_read(up);
-}
-
-static void serial_dl_write(struct uart_8250_port *up, int value)
-{
-       if (up->port.iotype == UPIO_RM9000) {
-               __raw_writel(value, up->port.membase + 0x08);
-               __raw_writel(value >> 8, up->port.membase + 0x10);
-       } else {
-               _serial_dl_write(up, value);
-       }
-}
-#else
-#define serial_dl_read(up) _serial_dl_read(up)
-#define serial_dl_write(up, value) _serial_dl_write(up, value)
-#endif
-
-/*
- * For the 16C950
- */
-static void serial_icr_write(struct uart_8250_port *up, int offset, int value)
-{
-       serial_out(up, UART_SCR, offset);
-       serial_out(up, UART_ICR, value);
-}
-
-static unsigned int serial_icr_read(struct uart_8250_port *up, int offset)
-{
-       unsigned int value;
-
-       serial_icr_write(up, UART_ACR, up->acr | UART_ACR_ICRRD);
-       serial_out(up, UART_SCR, offset);
-       value = serial_in(up, UART_ICR);
-       serial_icr_write(up, UART_ACR, up->acr);
-
-       return value;
-}
-
-/*
- * FIFO support.
- */
-static void serial8250_clear_fifos(struct uart_8250_port *p)
-{
-       if (p->capabilities & UART_CAP_FIFO) {
-               serial_outp(p, UART_FCR, UART_FCR_ENABLE_FIFO);
-               serial_outp(p, UART_FCR, UART_FCR_ENABLE_FIFO |
-                              UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT);
-               serial_outp(p, UART_FCR, 0);
-       }
-}
-
-/*
- * IER sleep support.  UARTs which have EFRs need the "extended
- * capability" bit enabled.  Note that on XR16C850s, we need to
- * reset LCR to write to IER.
- */
-static void serial8250_set_sleep(struct uart_8250_port *p, int sleep)
-{
-       if (p->capabilities & UART_CAP_SLEEP) {
-               if (p->capabilities & UART_CAP_EFR) {
-                       serial_outp(p, UART_LCR, UART_LCR_CONF_MODE_B);
-                       serial_outp(p, UART_EFR, UART_EFR_ECB);
-                       serial_outp(p, UART_LCR, 0);
-               }
-               serial_outp(p, UART_IER, sleep ? UART_IERX_SLEEP : 0);
-               if (p->capabilities & UART_CAP_EFR) {
-                       serial_outp(p, UART_LCR, UART_LCR_CONF_MODE_B);
-                       serial_outp(p, UART_EFR, 0);
-                       serial_outp(p, UART_LCR, 0);
-               }
-       }
-}
-
-#ifdef CONFIG_SERIAL_8250_RSA
-/*
- * Attempts to turn on the RSA FIFO.  Returns zero on failure.
- * We set the port uart clock rate if we succeed.
- */
-static int __enable_rsa(struct uart_8250_port *up)
-{
-       unsigned char mode;
-       int result;
-
-       mode = serial_inp(up, UART_RSA_MSR);
-       result = mode & UART_RSA_MSR_FIFO;
-
-       if (!result) {
-               serial_outp(up, UART_RSA_MSR, mode | UART_RSA_MSR_FIFO);
-               mode = serial_inp(up, UART_RSA_MSR);
-               result = mode & UART_RSA_MSR_FIFO;
-       }
-
-       if (result)
-               up->port.uartclk = SERIAL_RSA_BAUD_BASE * 16;
-
-       return result;
-}
-
-static void enable_rsa(struct uart_8250_port *up)
-{
-       if (up->port.type == PORT_RSA) {
-               if (up->port.uartclk != SERIAL_RSA_BAUD_BASE * 16) {
-                       spin_lock_irq(&up->port.lock);
-                       __enable_rsa(up);
-                       spin_unlock_irq(&up->port.lock);
-               }
-               if (up->port.uartclk == SERIAL_RSA_BAUD_BASE * 16)
-                       serial_outp(up, UART_RSA_FRR, 0);
-       }
-}
-
-/*
- * Attempts to turn off the RSA FIFO.  Returns zero on failure.
- * It is unknown why interrupts were disabled in here.  However,
- * the caller is expected to preserve this behaviour by grabbing
- * the spinlock before calling this function.
- */
-static void disable_rsa(struct uart_8250_port *up)
-{
-       unsigned char mode;
-       int result;
-
-       if (up->port.type == PORT_RSA &&
-           up->port.uartclk == SERIAL_RSA_BAUD_BASE * 16) {
-               spin_lock_irq(&up->port.lock);
-
-               mode = serial_inp(up, UART_RSA_MSR);
-               result = !(mode & UART_RSA_MSR_FIFO);
-
-               if (!result) {
-                       serial_outp(up, UART_RSA_MSR, mode & ~UART_RSA_MSR_FIFO);
-                       mode = serial_inp(up, UART_RSA_MSR);
-                       result = !(mode & UART_RSA_MSR_FIFO);
-               }
-
-               if (result)
-                       up->port.uartclk = SERIAL_RSA_BAUD_BASE_LO * 16;
-               spin_unlock_irq(&up->port.lock);
-       }
-}
-#endif /* CONFIG_SERIAL_8250_RSA */
-
-/*
- * This is a quickie test to see how big the FIFO is.
- * It doesn't work at all the time, more's the pity.
- */
-static int size_fifo(struct uart_8250_port *up)
-{
-       unsigned char old_fcr, old_mcr, old_lcr;
-       unsigned short old_dl;
-       int count;
-
-       old_lcr = serial_inp(up, UART_LCR);
-       serial_outp(up, UART_LCR, 0);
-       old_fcr = serial_inp(up, UART_FCR);
-       old_mcr = serial_inp(up, UART_MCR);
-       serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO |
-                   UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT);
-       serial_outp(up, UART_MCR, UART_MCR_LOOP);
-       serial_outp(up, UART_LCR, UART_LCR_CONF_MODE_A);
-       old_dl = serial_dl_read(up);
-       serial_dl_write(up, 0x0001);
-       serial_outp(up, UART_LCR, 0x03);
-       for (count = 0; count < 256; count++)
-               serial_outp(up, UART_TX, count);
-       mdelay(20);/* FIXME - schedule_timeout */
-       for (count = 0; (serial_inp(up, UART_LSR) & UART_LSR_DR) &&
-            (count < 256); count++)
-               serial_inp(up, UART_RX);
-       serial_outp(up, UART_FCR, old_fcr);
-       serial_outp(up, UART_MCR, old_mcr);
-       serial_outp(up, UART_LCR, UART_LCR_CONF_MODE_A);
-       serial_dl_write(up, old_dl);
-       serial_outp(up, UART_LCR, old_lcr);
-
-       return count;
-}
-
-/*
- * Read UART ID using the divisor method - set DLL and DLM to zero
- * and the revision will be in DLL and device type in DLM.  We
- * preserve the device state across this.
- */
-static unsigned int autoconfig_read_divisor_id(struct uart_8250_port *p)
-{
-       unsigned char old_dll, old_dlm, old_lcr;
-       unsigned int id;
-
-       old_lcr = serial_inp(p, UART_LCR);
-       serial_outp(p, UART_LCR, UART_LCR_CONF_MODE_A);
-
-       old_dll = serial_inp(p, UART_DLL);
-       old_dlm = serial_inp(p, UART_DLM);
-
-       serial_outp(p, UART_DLL, 0);
-       serial_outp(p, UART_DLM, 0);
-
-       id = serial_inp(p, UART_DLL) | serial_inp(p, UART_DLM) << 8;
-
-       serial_outp(p, UART_DLL, old_dll);
-       serial_outp(p, UART_DLM, old_dlm);
-       serial_outp(p, UART_LCR, old_lcr);
-
-       return id;
-}
-
-/*
- * This is a helper routine to autodetect StarTech/Exar/Oxsemi UART's.
- * When this function is called we know it is at least a StarTech
- * 16650 V2, but it might be one of several StarTech UARTs, or one of
- * its clones.  (We treat the broken original StarTech 16650 V1 as a
- * 16550, and why not?  Startech doesn't seem to even acknowledge its
- * existence.)
- *
- * What evil have men's minds wrought...
- */
-static void autoconfig_has_efr(struct uart_8250_port *up)
-{
-       unsigned int id1, id2, id3, rev;
-
-       /*
-        * Everything with an EFR has SLEEP
-        */
-       up->capabilities |= UART_CAP_EFR | UART_CAP_SLEEP;
-
-       /*
-        * First we check to see if it's an Oxford Semiconductor UART.
-        *
-        * If we have to do this here because some non-National
-        * Semiconductor clone chips lock up if you try writing to the
-        * LSR register (which serial_icr_read does)
-        */
-
-       /*
-        * Check for Oxford Semiconductor 16C950.
-        *
-        * EFR [4] must be set else this test fails.
-        *
-        * This shouldn't be necessary, but Mike Hudson (Exoray@isys.ca)
-        * claims that it's needed for 952 dual UART's (which are not
-        * recommended for new designs).
-        */
-       up->acr = 0;
-       serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B);
-       serial_out(up, UART_EFR, UART_EFR_ECB);
-       serial_out(up, UART_LCR, 0x00);
-       id1 = serial_icr_read(up, UART_ID1);
-       id2 = serial_icr_read(up, UART_ID2);
-       id3 = serial_icr_read(up, UART_ID3);
-       rev = serial_icr_read(up, UART_REV);
-
-       DEBUG_AUTOCONF("950id=%02x:%02x:%02x:%02x ", id1, id2, id3, rev);
-
-       if (id1 == 0x16 && id2 == 0xC9 &&
-           (id3 == 0x50 || id3 == 0x52 || id3 == 0x54)) {
-               up->port.type = PORT_16C950;
-
-               /*
-                * Enable work around for the Oxford Semiconductor 952 rev B
-                * chip which causes it to seriously miscalculate baud rates
-                * when DLL is 0.
-                */
-               if (id3 == 0x52 && rev == 0x01)
-                       up->bugs |= UART_BUG_QUOT;
-               return;
-       }
-
-       /*
-        * We check for a XR16C850 by setting DLL and DLM to 0, and then
-        * reading back DLL and DLM.  The chip type depends on the DLM
-        * value read back:
-        *  0x10 - XR16C850 and the DLL contains the chip revision.
-        *  0x12 - XR16C2850.
-        *  0x14 - XR16C854.
-        */
-       id1 = autoconfig_read_divisor_id(up);
-       DEBUG_AUTOCONF("850id=%04x ", id1);
-
-       id2 = id1 >> 8;
-       if (id2 == 0x10 || id2 == 0x12 || id2 == 0x14) {
-               up->port.type = PORT_16850;
-               return;
-       }
-
-       /*
-        * It wasn't an XR16C850.
-        *
-        * We distinguish between the '654 and the '650 by counting
-        * how many bytes are in the FIFO.  I'm using this for now,
-        * since that's the technique that was sent to me in the
-        * serial driver update, but I'm not convinced this works.
-        * I've had problems doing this in the past.  -TYT
-        */
-       if (size_fifo(up) == 64)
-               up->port.type = PORT_16654;
-       else
-               up->port.type = PORT_16650V2;
-}
-
-/*
- * We detected a chip without a FIFO.  Only two fall into
- * this category - the original 8250 and the 16450.  The
- * 16450 has a scratch register (accessible with LCR=0)
- */
-static void autoconfig_8250(struct uart_8250_port *up)
-{
-       unsigned char scratch, status1, status2;
-
-       up->port.type = PORT_8250;
-
-       scratch = serial_in(up, UART_SCR);
-       serial_outp(up, UART_SCR, 0xa5);
-       status1 = serial_in(up, UART_SCR);
-       serial_outp(up, UART_SCR, 0x5a);
-       status2 = serial_in(up, UART_SCR);
-       serial_outp(up, UART_SCR, scratch);
-
-       if (status1 == 0xa5 && status2 == 0x5a)
-               up->port.type = PORT_16450;
-}
-
-static int broken_efr(struct uart_8250_port *up)
-{
-       /*
-        * Exar ST16C2550 "A2" devices incorrectly detect as
-        * having an EFR, and report an ID of 0x0201.  See
-        * http://linux.derkeiler.com/Mailing-Lists/Kernel/2004-11/4812.html 
-        */
-       if (autoconfig_read_divisor_id(up) == 0x0201 && size_fifo(up) == 16)
-               return 1;
-
-       return 0;
-}
-
-static inline int ns16550a_goto_highspeed(struct uart_8250_port *up)
-{
-       unsigned char status;
-
-       status = serial_in(up, 0x04); /* EXCR2 */
-#define PRESL(x) ((x) & 0x30)
-       if (PRESL(status) == 0x10) {
-               /* already in high speed mode */
-               return 0;
-       } else {
-               status &= ~0xB0; /* Disable LOCK, mask out PRESL[01] */
-               status |= 0x10;  /* 1.625 divisor for baud_base --> 921600 */
-               serial_outp(up, 0x04, status);
-       }
-       return 1;
-}
-
-/*
- * We know that the chip has FIFOs.  Does it have an EFR?  The
- * EFR is located in the same register position as the IIR and
- * we know the top two bits of the IIR are currently set.  The
- * EFR should contain zero.  Try to read the EFR.
- */
-static void autoconfig_16550a(struct uart_8250_port *up)
-{
-       unsigned char status1, status2;
-       unsigned int iersave;
-
-       up->port.type = PORT_16550A;
-       up->capabilities |= UART_CAP_FIFO;
-
-       /*
-        * Check for presence of the EFR when DLAB is set.
-        * Only ST16C650V1 UARTs pass this test.
-        */
-       serial_outp(up, UART_LCR, UART_LCR_CONF_MODE_A);
-       if (serial_in(up, UART_EFR) == 0) {
-               serial_outp(up, UART_EFR, 0xA8);
-               if (serial_in(up, UART_EFR) != 0) {
-                       DEBUG_AUTOCONF("EFRv1 ");
-                       up->port.type = PORT_16650;
-                       up->capabilities |= UART_CAP_EFR | UART_CAP_SLEEP;
-               } else {
-                       DEBUG_AUTOCONF("Motorola 8xxx DUART ");
-               }
-               serial_outp(up, UART_EFR, 0);
-               return;
-       }
-
-       /*
-        * Maybe it requires 0xbf to be written to the LCR.
-        * (other ST16C650V2 UARTs, TI16C752A, etc)
-        */
-       serial_outp(up, UART_LCR, UART_LCR_CONF_MODE_B);
-       if (serial_in(up, UART_EFR) == 0 && !broken_efr(up)) {
-               DEBUG_AUTOCONF("EFRv2 ");
-               autoconfig_has_efr(up);
-               return;
-       }
-
-       /*
-        * Check for a National Semiconductor SuperIO chip.
-        * Attempt to switch to bank 2, read the value of the LOOP bit
-        * from EXCR1. Switch back to bank 0, change it in MCR. Then
-        * switch back to bank 2, read it from EXCR1 again and check
-        * it's changed. If so, set baud_base in EXCR2 to 921600. -- dwmw2
-        */
-       serial_outp(up, UART_LCR, 0);
-       status1 = serial_in(up, UART_MCR);
-       serial_outp(up, UART_LCR, 0xE0);
-       status2 = serial_in(up, 0x02); /* EXCR1 */
-
-       if (!((status2 ^ status1) & UART_MCR_LOOP)) {
-               serial_outp(up, UART_LCR, 0);
-               serial_outp(up, UART_MCR, status1 ^ UART_MCR_LOOP);
-               serial_outp(up, UART_LCR, 0xE0);
-               status2 = serial_in(up, 0x02); /* EXCR1 */
-               serial_outp(up, UART_LCR, 0);
-               serial_outp(up, UART_MCR, status1);
-
-               if ((status2 ^ status1) & UART_MCR_LOOP) {
-                       unsigned short quot;
-
-                       serial_outp(up, UART_LCR, 0xE0);
-
-                       quot = serial_dl_read(up);
-                       quot <<= 3;
-
-                       if (ns16550a_goto_highspeed(up))
-                               serial_dl_write(up, quot);
-
-                       serial_outp(up, UART_LCR, 0);
-
-                       up->port.uartclk = 921600*16;
-                       up->port.type = PORT_NS16550A;
-                       up->capabilities |= UART_NATSEMI;
-                       return;
-               }
-       }
-
-       /*
-        * No EFR.  Try to detect a TI16750, which only sets bit 5 of
-        * the IIR when 64 byte FIFO mode is enabled when DLAB is set.
-        * Try setting it with and without DLAB set.  Cheap clones
-        * set bit 5 without DLAB set.
-        */
-       serial_outp(up, UART_LCR, 0);
-       serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO | UART_FCR7_64BYTE);
-       status1 = serial_in(up, UART_IIR) >> 5;
-       serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO);
-       serial_outp(up, UART_LCR, UART_LCR_CONF_MODE_A);
-       serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO | UART_FCR7_64BYTE);
-       status2 = serial_in(up, UART_IIR) >> 5;
-       serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO);
-       serial_outp(up, UART_LCR, 0);
-
-       DEBUG_AUTOCONF("iir1=%d iir2=%d ", status1, status2);
-
-       if (status1 == 6 && status2 == 7) {
-               up->port.type = PORT_16750;
-               up->capabilities |= UART_CAP_AFE | UART_CAP_SLEEP;
-               return;
-       }
-
-       /*
-        * Try writing and reading the UART_IER_UUE bit (b6).
-        * If it works, this is probably one of the Xscale platform's
-        * internal UARTs.
-        * We're going to explicitly set the UUE bit to 0 before
-        * trying to write and read a 1 just to make sure it's not
-        * already a 1 and maybe locked there before we even start start.
-        */
-       iersave = serial_in(up, UART_IER);
-       serial_outp(up, UART_IER, iersave & ~UART_IER_UUE);
-       if (!(serial_in(up, UART_IER) & UART_IER_UUE)) {
-               /*
-                * OK it's in a known zero state, try writing and reading
-                * without disturbing the current state of the other bits.
-                */
-               serial_outp(up, UART_IER, iersave | UART_IER_UUE);
-               if (serial_in(up, UART_IER) & UART_IER_UUE) {
-                       /*
-                        * It's an Xscale.
-                        * We'll leave the UART_IER_UUE bit set to 1 (enabled).
-                        */
-                       DEBUG_AUTOCONF("Xscale ");
-                       up->port.type = PORT_XSCALE;
-                       up->capabilities |= UART_CAP_UUE | UART_CAP_RTOIE;
-                       return;
-               }
-       } else {
-               /*
-                * If we got here we couldn't force the IER_UUE bit to 0.
-                * Log it and continue.
-                */
-               DEBUG_AUTOCONF("Couldn't force IER_UUE to 0 ");
-       }
-       serial_outp(up, UART_IER, iersave);
-
-       /*
-        * Exar uarts have EFR in a weird location
-        */
-       if (up->port.flags & UPF_EXAR_EFR) {
-               up->port.type = PORT_XR17D15X;
-               up->capabilities |= UART_CAP_AFE | UART_CAP_EFR;
-       }
-
-       /*
-        * We distinguish between 16550A and U6 16550A by counting
-        * how many bytes are in the FIFO.
-        */
-       if (up->port.type == PORT_16550A && size_fifo(up) == 64) {
-               up->port.type = PORT_U6_16550A;
-               up->capabilities |= UART_CAP_AFE;
-       }
-}
-
-/*
- * This routine is called by rs_init() to initialize a specific serial
- * port.  It determines what type of UART chip this serial port is
- * using: 8250, 16450, 16550, 16550A.  The important question is
- * whether or not this UART is a 16550A or not, since this will
- * determine whether or not we can use its FIFO features or not.
- */
-static void autoconfig(struct uart_8250_port *up, unsigned int probeflags)
-{
-       unsigned char status1, scratch, scratch2, scratch3;
-       unsigned char save_lcr, save_mcr;
-       unsigned long flags;
-
-       if (!up->port.iobase && !up->port.mapbase && !up->port.membase)
-               return;
-
-       DEBUG_AUTOCONF("ttyS%d: autoconf (0x%04lx, 0x%p): ",
-                      serial_index(&up->port), up->port.iobase, up->port.membase);
-
-       /*
-        * We really do need global IRQs disabled here - we're going to
-        * be frobbing the chips IRQ enable register to see if it exists.
-        */
-       spin_lock_irqsave(&up->port.lock, flags);
-
-       up->capabilities = 0;
-       up->bugs = 0;
-
-       if (!(up->port.flags & UPF_BUGGY_UART)) {
-               /*
-                * Do a simple existence test first; if we fail this,
-                * there's no point trying anything else.
-                *
-                * 0x80 is used as a nonsense port to prevent against
-                * false positives due to ISA bus float.  The
-                * assumption is that 0x80 is a non-existent port;
-                * which should be safe since include/asm/io.h also
-                * makes this assumption.
-                *
-                * Note: this is safe as long as MCR bit 4 is clear
-                * and the device is in "PC" mode.
-                */
-               scratch = serial_inp(up, UART_IER);
-               serial_outp(up, UART_IER, 0);
-#ifdef __i386__
-               outb(0xff, 0x080);
-#endif
-               /*
-                * Mask out IER[7:4] bits for test as some UARTs (e.g. TL
-                * 16C754B) allow only to modify them if an EFR bit is set.
-                */
-               scratch2 = serial_inp(up, UART_IER) & 0x0f;
-               serial_outp(up, UART_IER, 0x0F);
-#ifdef __i386__
-               outb(0, 0x080);
-#endif
-               scratch3 = serial_inp(up, UART_IER) & 0x0f;
-               serial_outp(up, UART_IER, scratch);
-               if (scratch2 != 0 || scratch3 != 0x0F) {
-                       /*
-                        * We failed; there's nothing here
-                        */
-                       DEBUG_AUTOCONF("IER test failed (%02x, %02x) ",
-                                      scratch2, scratch3);
-                       goto out;
-               }
-       }
-
-       save_mcr = serial_in(up, UART_MCR);
-       save_lcr = serial_in(up, UART_LCR);
-
-       /*
-        * Check to see if a UART is really there.  Certain broken
-        * internal modems based on the Rockwell chipset fail this
-        * test, because they apparently don't implement the loopback
-        * test mode.  So this test is skipped on the COM 1 through
-        * COM 4 ports.  This *should* be safe, since no board
-        * manufacturer would be stupid enough to design a board
-        * that conflicts with COM 1-4 --- we hope!
-        */
-       if (!(up->port.flags & UPF_SKIP_TEST)) {
-               serial_outp(up, UART_MCR, UART_MCR_LOOP | 0x0A);
-               status1 = serial_inp(up, UART_MSR) & 0xF0;
-               serial_outp(up, UART_MCR, save_mcr);
-               if (status1 != 0x90) {
-                       DEBUG_AUTOCONF("LOOP test failed (%02x) ",
-                                      status1);
-                       goto out;
-               }
-       }
-
-       /*
-        * We're pretty sure there's a port here.  Lets find out what
-        * type of port it is.  The IIR top two bits allows us to find
-        * out if it's 8250 or 16450, 16550, 16550A or later.  This
-        * determines what we test for next.
-        *
-        * We also initialise the EFR (if any) to zero for later.  The
-        * EFR occupies the same register location as the FCR and IIR.
-        */
-       serial_outp(up, UART_LCR, UART_LCR_CONF_MODE_B);
-       serial_outp(up, UART_EFR, 0);
-       serial_outp(up, UART_LCR, 0);
-
-       serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO);
-       scratch = serial_in(up, UART_IIR) >> 6;
-
-       DEBUG_AUTOCONF("iir=%d ", scratch);
-
-       switch (scratch) {
-       case 0:
-               autoconfig_8250(up);
-               break;
-       case 1:
-               up->port.type = PORT_UNKNOWN;
-               break;
-       case 2:
-               up->port.type = PORT_16550;
-               break;
-       case 3:
-               autoconfig_16550a(up);
-               break;
-       }
-
-#ifdef CONFIG_SERIAL_8250_RSA
-       /*
-        * Only probe for RSA ports if we got the region.
-        */
-       if (up->port.type == PORT_16550A && probeflags & PROBE_RSA) {
-               int i;
-
-               for (i = 0 ; i < probe_rsa_count; ++i) {
-                       if (probe_rsa[i] == up->port.iobase &&
-                           __enable_rsa(up)) {
-                               up->port.type = PORT_RSA;
-                               break;
-                       }
-               }
-       }
-#endif
-
-       serial_outp(up, UART_LCR, save_lcr);
-
-       if (up->capabilities != uart_config[up->port.type].flags) {
-               printk(KERN_WARNING
-                      "ttyS%d: detected caps %08x should be %08x\n",
-                      serial_index(&up->port), up->capabilities,
-                      uart_config[up->port.type].flags);
-       }
-
-       up->port.fifosize = uart_config[up->port.type].fifo_size;
-       up->capabilities = uart_config[up->port.type].flags;
-       up->tx_loadsz = uart_config[up->port.type].tx_loadsz;
-
-       if (up->port.type == PORT_UNKNOWN)
-               goto out;
-
-       /*
-        * Reset the UART.
-        */
-#ifdef CONFIG_SERIAL_8250_RSA
-       if (up->port.type == PORT_RSA)
-               serial_outp(up, UART_RSA_FRR, 0);
-#endif
-       serial_outp(up, UART_MCR, save_mcr);
-       serial8250_clear_fifos(up);
-       serial_in(up, UART_RX);
-       if (up->capabilities & UART_CAP_UUE)
-               serial_outp(up, UART_IER, UART_IER_UUE);
-       else
-               serial_outp(up, UART_IER, 0);
-
- out:
-       spin_unlock_irqrestore(&up->port.lock, flags);
-       DEBUG_AUTOCONF("type=%s\n", uart_config[up->port.type].name);
-}
-
-static void autoconfig_irq(struct uart_8250_port *up)
-{
-       unsigned char save_mcr, save_ier;
-       unsigned char save_ICP = 0;
-       unsigned int ICP = 0;
-       unsigned long irqs;
-       int irq;
-
-       if (up->port.flags & UPF_FOURPORT) {
-               ICP = (up->port.iobase & 0xfe0) | 0x1f;
-               save_ICP = inb_p(ICP);
-               outb_p(0x80, ICP);
-               (void) inb_p(ICP);
-       }
-
-       /* forget possible initially masked and pending IRQ */
-       probe_irq_off(probe_irq_on());
-       save_mcr = serial_inp(up, UART_MCR);
-       save_ier = serial_inp(up, UART_IER);
-       serial_outp(up, UART_MCR, UART_MCR_OUT1 | UART_MCR_OUT2);
-
-       irqs = probe_irq_on();
-       serial_outp(up, UART_MCR, 0);
-       udelay(10);
-       if (up->port.flags & UPF_FOURPORT) {
-               serial_outp(up, UART_MCR,
-                           UART_MCR_DTR | UART_MCR_RTS);
-       } else {
-               serial_outp(up, UART_MCR,
-                           UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2);
-       }
-       serial_outp(up, UART_IER, 0x0f);        /* enable all intrs */
-       (void)serial_inp(up, UART_LSR);
-       (void)serial_inp(up, UART_RX);
-       (void)serial_inp(up, UART_IIR);
-       (void)serial_inp(up, UART_MSR);
-       serial_outp(up, UART_TX, 0xFF);
-       udelay(20);
-       irq = probe_irq_off(irqs);
-
-       serial_outp(up, UART_MCR, save_mcr);
-       serial_outp(up, UART_IER, save_ier);
-
-       if (up->port.flags & UPF_FOURPORT)
-               outb_p(save_ICP, ICP);
-
-       up->port.irq = (irq > 0) ? irq : 0;
-}
-
-static inline void __stop_tx(struct uart_8250_port *p)
-{
-       if (p->ier & UART_IER_THRI) {
-               p->ier &= ~UART_IER_THRI;
-               serial_out(p, UART_IER, p->ier);
-       }
-}
-
-static void serial8250_stop_tx(struct uart_port *port)
-{
-       struct uart_8250_port *up =
-               container_of(port, struct uart_8250_port, port);
-
-       __stop_tx(up);
-
-       /*
-        * We really want to stop the transmitter from sending.
-        */
-       if (up->port.type == PORT_16C950) {
-               up->acr |= UART_ACR_TXDIS;
-               serial_icr_write(up, UART_ACR, up->acr);
-       }
-}
-
-static void serial8250_start_tx(struct uart_port *port)
-{
-       struct uart_8250_port *up =
-               container_of(port, struct uart_8250_port, port);
-
-       if (!(up->ier & UART_IER_THRI)) {
-               up->ier |= UART_IER_THRI;
-               serial_out(up, UART_IER, up->ier);
-
-               if (up->bugs & UART_BUG_TXEN) {
-                       unsigned char lsr;
-                       lsr = serial_in(up, UART_LSR);
-                       up->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS;
-                       if ((up->port.type == PORT_RM9000) ?
-                               (lsr & UART_LSR_THRE) :
-                               (lsr & UART_LSR_TEMT))
-                               serial8250_tx_chars(up);
-               }
-       }
-
-       /*
-        * Re-enable the transmitter if we disabled it.
-        */
-       if (up->port.type == PORT_16C950 && up->acr & UART_ACR_TXDIS) {
-               up->acr &= ~UART_ACR_TXDIS;
-               serial_icr_write(up, UART_ACR, up->acr);
-       }
-}
-
-static void serial8250_stop_rx(struct uart_port *port)
-{
-       struct uart_8250_port *up =
-               container_of(port, struct uart_8250_port, port);
-
-       up->ier &= ~UART_IER_RLSI;
-       up->port.read_status_mask &= ~UART_LSR_DR;
-       serial_out(up, UART_IER, up->ier);
-}
-
-static void serial8250_enable_ms(struct uart_port *port)
-{
-       struct uart_8250_port *up =
-               container_of(port, struct uart_8250_port, port);
-
-       /* no MSR capabilities */
-       if (up->bugs & UART_BUG_NOMSR)
-               return;
-
-       up->ier |= UART_IER_MSI;
-       serial_out(up, UART_IER, up->ier);
-}
-
-/*
- * Clear the Tegra rx fifo after a break
- *
- * FIXME: This needs to become a port specific callback once we have a
- * framework for this
- */
-static void clear_rx_fifo(struct uart_8250_port *up)
-{
-       unsigned int status, tmout = 10000;
-       do {
-               status = serial_in(up, UART_LSR);
-               if (status & (UART_LSR_FIFOE | UART_LSR_BRK_ERROR_BITS))
-                       status = serial_in(up, UART_RX);
-               else
-                       break;
-               if (--tmout == 0)
-                       break;
-               udelay(1);
-       } while (1);
-}
-
-/*
- * serial8250_rx_chars: processes according to the passed in LSR
- * value, and returns the remaining LSR bits not handled
- * by this Rx routine.
- */
-unsigned char
-serial8250_rx_chars(struct uart_8250_port *up, unsigned char lsr)
-{
-       struct tty_struct *tty = up->port.state->port.tty;
-       unsigned char ch;
-       int max_count = 256;
-       char flag;
-
-       do {
-               if (likely(lsr & UART_LSR_DR))
-                       ch = serial_inp(up, UART_RX);
-               else
-                       /*
-                        * Intel 82571 has a Serial Over Lan device that will
-                        * set UART_LSR_BI without setting UART_LSR_DR when
-                        * it receives a break. To avoid reading from the
-                        * receive buffer without UART_LSR_DR bit set, we
-                        * just force the read character to be 0
-                        */
-                       ch = 0;
-
-               flag = TTY_NORMAL;
-               up->port.icount.rx++;
-
-               lsr |= up->lsr_saved_flags;
-               up->lsr_saved_flags = 0;
-
-               if (unlikely(lsr & UART_LSR_BRK_ERROR_BITS)) {
-                       /*
-                        * For statistics only
-                        */
-                       if (lsr & UART_LSR_BI) {
-                               lsr &= ~(UART_LSR_FE | UART_LSR_PE);
-                               up->port.icount.brk++;
-                               /*
-                                * If tegra port then clear the rx fifo to
-                                * accept another break/character.
-                                */
-                               if (up->port.type == PORT_TEGRA)
-                                       clear_rx_fifo(up);
-
-                               /*
-                                * We do the SysRQ and SAK checking
-                                * here because otherwise the break
-                                * may get masked by ignore_status_mask
-                                * or read_status_mask.
-                                */
-                               if (uart_handle_break(&up->port))
-                                       goto ignore_char;
-                       } else if (lsr & UART_LSR_PE)
-                               up->port.icount.parity++;
-                       else if (lsr & UART_LSR_FE)
-                               up->port.icount.frame++;
-                       if (lsr & UART_LSR_OE)
-                               up->port.icount.overrun++;
-
-                       /*
-                        * Mask off conditions which should be ignored.
-                        */
-                       lsr &= up->port.read_status_mask;
-
-                       if (lsr & UART_LSR_BI) {
-                               DEBUG_INTR("handling break....");
-                               flag = TTY_BREAK;
-                       } else if (lsr & UART_LSR_PE)
-                               flag = TTY_PARITY;
-                       else if (lsr & UART_LSR_FE)
-                               flag = TTY_FRAME;
-               }
-               if (uart_handle_sysrq_char(&up->port, ch))
-                       goto ignore_char;
-
-               uart_insert_char(&up->port, lsr, UART_LSR_OE, ch, flag);
-
-ignore_char:
-               lsr = serial_inp(up, UART_LSR);
-       } while ((lsr & (UART_LSR_DR | UART_LSR_BI)) && (max_count-- > 0));
-       spin_unlock(&up->port.lock);
-       tty_flip_buffer_push(tty);
-       spin_lock(&up->port.lock);
-       return lsr;
-}
-EXPORT_SYMBOL_GPL(serial8250_rx_chars);
-
-void serial8250_tx_chars(struct uart_8250_port *up)
-{
-       struct circ_buf *xmit = &up->port.state->xmit;
-       int count;
-
-       if (up->port.x_char) {
-               serial_outp(up, UART_TX, up->port.x_char);
-               up->port.icount.tx++;
-               up->port.x_char = 0;
-               return;
-       }
-       if (uart_tx_stopped(&up->port)) {
-               serial8250_stop_tx(&up->port);
-               return;
-       }
-       if (uart_circ_empty(xmit)) {
-               __stop_tx(up);
-               return;
-       }
-
-       count = up->tx_loadsz;
-       do {
-               serial_out(up, UART_TX, xmit->buf[xmit->tail]);
-               xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
-               up->port.icount.tx++;
-               if (uart_circ_empty(xmit))
-                       break;
-       } while (--count > 0);
-
-       if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
-               uart_write_wakeup(&up->port);
-
-       DEBUG_INTR("THRE...");
-
-       if (uart_circ_empty(xmit))
-               __stop_tx(up);
-}
-EXPORT_SYMBOL_GPL(serial8250_tx_chars);
-
-unsigned int serial8250_modem_status(struct uart_8250_port *up)
-{
-       unsigned int status = serial_in(up, UART_MSR);
-
-       status |= up->msr_saved_flags;
-       up->msr_saved_flags = 0;
-       if (status & UART_MSR_ANY_DELTA && up->ier & UART_IER_MSI &&
-           up->port.state != NULL) {
-               if (status & UART_MSR_TERI)
-                       up->port.icount.rng++;
-               if (status & UART_MSR_DDSR)
-                       up->port.icount.dsr++;
-               if (status & UART_MSR_DDCD)
-                       uart_handle_dcd_change(&up->port, status & UART_MSR_DCD);
-               if (status & UART_MSR_DCTS)
-                       uart_handle_cts_change(&up->port, status & UART_MSR_CTS);
-
-               wake_up_interruptible(&up->port.state->port.delta_msr_wait);
-       }
-
-       return status;
-}
-EXPORT_SYMBOL_GPL(serial8250_modem_status);
-
-/*
- * This handles the interrupt from one port.
- */
-int serial8250_handle_irq(struct uart_port *port, unsigned int iir)
-{
-       unsigned char status;
-       unsigned long flags;
-       struct uart_8250_port *up =
-               container_of(port, struct uart_8250_port, port);
-
-       if (iir & UART_IIR_NO_INT)
-               return 0;
-
-       spin_lock_irqsave(&up->port.lock, flags);
-
-       status = serial_inp(up, UART_LSR);
-
-       DEBUG_INTR("status = %x...", status);
-
-       if (status & (UART_LSR_DR | UART_LSR_BI))
-               status = serial8250_rx_chars(up, status);
-       serial8250_modem_status(up);
-       if (status & UART_LSR_THRE)
-               serial8250_tx_chars(up);
-
-       spin_unlock_irqrestore(&up->port.lock, flags);
-       return 1;
-}
-EXPORT_SYMBOL_GPL(serial8250_handle_irq);
-
-static int serial8250_default_handle_irq(struct uart_port *port)
-{
-       struct uart_8250_port *up =
-               container_of(port, struct uart_8250_port, port);
-       unsigned int iir = serial_in(up, UART_IIR);
-
-       return serial8250_handle_irq(port, iir);
-}
-
-/*
- * This is the serial driver's interrupt routine.
- *
- * Arjan thinks the old way was overly complex, so it got simplified.
- * Alan disagrees, saying that need the complexity to handle the weird
- * nature of ISA shared interrupts.  (This is a special exception.)
- *
- * In order to handle ISA shared interrupts properly, we need to check
- * that all ports have been serviced, and therefore the ISA interrupt
- * line has been de-asserted.
- *
- * This means we need to loop through all ports. checking that they
- * don't have an interrupt pending.
- */
-static irqreturn_t serial8250_interrupt(int irq, void *dev_id)
-{
-       struct irq_info *i = dev_id;
-       struct list_head *l, *end = NULL;
-       int pass_counter = 0, handled = 0;
-
-       DEBUG_INTR("serial8250_interrupt(%d)...", irq);
-
-       spin_lock(&i->lock);
-
-       l = i->head;
-       do {
-               struct uart_8250_port *up;
-               struct uart_port *port;
-               bool skip;
-
-               up = list_entry(l, struct uart_8250_port, list);
-               port = &up->port;
-               skip = pass_counter && up->port.flags & UPF_IIR_ONCE;
-
-               if (!skip && port->handle_irq(port)) {
-                       handled = 1;
-                       end = NULL;
-               } else if (end == NULL)
-                       end = l;
-
-               l = l->next;
-
-               if (l == i->head && pass_counter++ > PASS_LIMIT) {
-                       /* If we hit this, we're dead. */
-                       printk_ratelimited(KERN_ERR
-                               "serial8250: too much work for irq%d\n", irq);
-                       break;
-               }
-       } while (l != end);
-
-       spin_unlock(&i->lock);
-
-       DEBUG_INTR("end.\n");
-
-       return IRQ_RETVAL(handled);
-}
-
-/*
- * To support ISA shared interrupts, we need to have one interrupt
- * handler that ensures that the IRQ line has been deasserted
- * before returning.  Failing to do this will result in the IRQ
- * line being stuck active, and, since ISA irqs are edge triggered,
- * no more IRQs will be seen.
- */
-static void serial_do_unlink(struct irq_info *i, struct uart_8250_port *up)
-{
-       spin_lock_irq(&i->lock);
-
-       if (!list_empty(i->head)) {
-               if (i->head == &up->list)
-                       i->head = i->head->next;
-               list_del(&up->list);
-       } else {
-               BUG_ON(i->head != &up->list);
-               i->head = NULL;
-       }
-       spin_unlock_irq(&i->lock);
-       /* List empty so throw away the hash node */
-       if (i->head == NULL) {
-               hlist_del(&i->node);
-               kfree(i);
-       }
-}
-
-static int serial_link_irq_chain(struct uart_8250_port *up)
-{
-       struct hlist_head *h;
-       struct hlist_node *n;
-       struct irq_info *i;
-       int ret, irq_flags = up->port.flags & UPF_SHARE_IRQ ? IRQF_SHARED : 0;
-
-       mutex_lock(&hash_mutex);
-
-       h = &irq_lists[up->port.irq % NR_IRQ_HASH];
-
-       hlist_for_each(n, h) {
-               i = hlist_entry(n, struct irq_info, node);
-               if (i->irq == up->port.irq)
-                       break;
-       }
-
-       if (n == NULL) {
-               i = kzalloc(sizeof(struct irq_info), GFP_KERNEL);
-               if (i == NULL) {
-                       mutex_unlock(&hash_mutex);
-                       return -ENOMEM;
-               }
-               spin_lock_init(&i->lock);
-               i->irq = up->port.irq;
-               hlist_add_head(&i->node, h);
-       }
-       mutex_unlock(&hash_mutex);
-
-       spin_lock_irq(&i->lock);
-
-       if (i->head) {
-               list_add(&up->list, i->head);
-               spin_unlock_irq(&i->lock);
-
-               ret = 0;
-       } else {
-               INIT_LIST_HEAD(&up->list);
-               i->head = &up->list;
-               spin_unlock_irq(&i->lock);
-               irq_flags |= up->port.irqflags;
-               ret = request_irq(up->port.irq, serial8250_interrupt,
-                                 irq_flags, "serial", i);
-               if (ret < 0)
-                       serial_do_unlink(i, up);
-       }
-
-       return ret;
-}
-
-static void serial_unlink_irq_chain(struct uart_8250_port *up)
-{
-       struct irq_info *i;
-       struct hlist_node *n;
-       struct hlist_head *h;
-
-       mutex_lock(&hash_mutex);
-
-       h = &irq_lists[up->port.irq % NR_IRQ_HASH];
-
-       hlist_for_each(n, h) {
-               i = hlist_entry(n, struct irq_info, node);
-               if (i->irq == up->port.irq)
-                       break;
-       }
-
-       BUG_ON(n == NULL);
-       BUG_ON(i->head == NULL);
-
-       if (list_empty(i->head))
-               free_irq(up->port.irq, i);
-
-       serial_do_unlink(i, up);
-       mutex_unlock(&hash_mutex);
-}
-
-/*
- * This function is used to handle ports that do not have an
- * interrupt.  This doesn't work very well for 16450's, but gives
- * barely passable results for a 16550A.  (Although at the expense
- * of much CPU overhead).
- */
-static void serial8250_timeout(unsigned long data)
-{
-       struct uart_8250_port *up = (struct uart_8250_port *)data;
-
-       up->port.handle_irq(&up->port);
-       mod_timer(&up->timer, jiffies + uart_poll_timeout(&up->port));
-}
-
-static void serial8250_backup_timeout(unsigned long data)
-{
-       struct uart_8250_port *up = (struct uart_8250_port *)data;
-       unsigned int iir, ier = 0, lsr;
-       unsigned long flags;
-
-       spin_lock_irqsave(&up->port.lock, flags);
-
-       /*
-        * Must disable interrupts or else we risk racing with the interrupt
-        * based handler.
-        */
-       if (is_real_interrupt(up->port.irq)) {
-               ier = serial_in(up, UART_IER);
-               serial_out(up, UART_IER, 0);
-       }
-
-       iir = serial_in(up, UART_IIR);
-
-       /*
-        * This should be a safe test for anyone who doesn't trust the
-        * IIR bits on their UART, but it's specifically designed for
-        * the "Diva" UART used on the management processor on many HP
-        * ia64 and parisc boxes.
-        */
-       lsr = serial_in(up, UART_LSR);
-       up->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS;
-       if ((iir & UART_IIR_NO_INT) && (up->ier & UART_IER_THRI) &&
-           (!uart_circ_empty(&up->port.state->xmit) || up->port.x_char) &&
-           (lsr & UART_LSR_THRE)) {
-               iir &= ~(UART_IIR_ID | UART_IIR_NO_INT);
-               iir |= UART_IIR_THRI;
-       }
-
-       if (!(iir & UART_IIR_NO_INT))
-               serial8250_tx_chars(up);
-
-       if (is_real_interrupt(up->port.irq))
-               serial_out(up, UART_IER, ier);
-
-       spin_unlock_irqrestore(&up->port.lock, flags);
-
-       /* Standard timer interval plus 0.2s to keep the port running */
-       mod_timer(&up->timer,
-               jiffies + uart_poll_timeout(&up->port) + HZ / 5);
-}
-
-static unsigned int serial8250_tx_empty(struct uart_port *port)
-{
-       struct uart_8250_port *up =
-               container_of(port, struct uart_8250_port, port);
-       unsigned long flags;
-       unsigned int lsr;
-
-       spin_lock_irqsave(&up->port.lock, flags);
-       lsr = serial_in(up, UART_LSR);
-       up->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS;
-       spin_unlock_irqrestore(&up->port.lock, flags);
-
-       return (lsr & BOTH_EMPTY) == BOTH_EMPTY ? TIOCSER_TEMT : 0;
-}
-
-static unsigned int serial8250_get_mctrl(struct uart_port *port)
-{
-       struct uart_8250_port *up =
-               container_of(port, struct uart_8250_port, port);
-       unsigned int status;
-       unsigned int ret;
-
-       status = serial8250_modem_status(up);
-
-       ret = 0;
-       if (status & UART_MSR_DCD)
-               ret |= TIOCM_CAR;
-       if (status & UART_MSR_RI)
-               ret |= TIOCM_RNG;
-       if (status & UART_MSR_DSR)
-               ret |= TIOCM_DSR;
-       if (status & UART_MSR_CTS)
-               ret |= TIOCM_CTS;
-       return ret;
-}
-
-static void serial8250_set_mctrl(struct uart_port *port, unsigned int mctrl)
-{
-       struct uart_8250_port *up =
-               container_of(port, struct uart_8250_port, port);
-       unsigned char mcr = 0;
-
-       if (mctrl & TIOCM_RTS)
-               mcr |= UART_MCR_RTS;
-       if (mctrl & TIOCM_DTR)
-               mcr |= UART_MCR_DTR;
-       if (mctrl & TIOCM_OUT1)
-               mcr |= UART_MCR_OUT1;
-       if (mctrl & TIOCM_OUT2)
-               mcr |= UART_MCR_OUT2;
-       if (mctrl & TIOCM_LOOP)
-               mcr |= UART_MCR_LOOP;
-
-       mcr = (mcr & up->mcr_mask) | up->mcr_force | up->mcr;
-
-       serial_out(up, UART_MCR, mcr);
-}
-
-static void serial8250_break_ctl(struct uart_port *port, int break_state)
-{
-       struct uart_8250_port *up =
-               container_of(port, struct uart_8250_port, port);
-       unsigned long flags;
-
-       spin_lock_irqsave(&up->port.lock, flags);
-       if (break_state == -1)
-               up->lcr |= UART_LCR_SBC;
-       else
-               up->lcr &= ~UART_LCR_SBC;
-       serial_out(up, UART_LCR, up->lcr);
-       spin_unlock_irqrestore(&up->port.lock, flags);
-}
-
-/*
- *     Wait for transmitter & holding register to empty
- */
-static void wait_for_xmitr(struct uart_8250_port *up, int bits)
-{
-       unsigned int status, tmout = 10000;
-
-       /* Wait up to 10ms for the character(s) to be sent. */
-       for (;;) {
-               status = serial_in(up, UART_LSR);
-
-               up->lsr_saved_flags |= status & LSR_SAVE_FLAGS;
-
-               if ((status & bits) == bits)
-                       break;
-               if (--tmout == 0)
-                       break;
-               udelay(1);
-       }
-
-       /* Wait up to 1s for flow control if necessary */
-       if (up->port.flags & UPF_CONS_FLOW) {
-               unsigned int tmout;
-               for (tmout = 1000000; tmout; tmout--) {
-                       unsigned int msr = serial_in(up, UART_MSR);
-                       up->msr_saved_flags |= msr & MSR_SAVE_FLAGS;
-                       if (msr & UART_MSR_CTS)
-                               break;
-                       udelay(1);
-                       touch_nmi_watchdog();
-               }
-       }
-}
-
-#ifdef CONFIG_CONSOLE_POLL
-/*
- * Console polling routines for writing and reading from the uart while
- * in an interrupt or debug context.
- */
-
-static int serial8250_get_poll_char(struct uart_port *port)
-{
-       struct uart_8250_port *up =
-               container_of(port, struct uart_8250_port, port);
-       unsigned char lsr = serial_inp(up, UART_LSR);
-
-       if (!(lsr & UART_LSR_DR))
-               return NO_POLL_CHAR;
-
-       return serial_inp(up, UART_RX);
-}
-
-
-static void serial8250_put_poll_char(struct uart_port *port,
-                        unsigned char c)
-{
-       unsigned int ier;
-       struct uart_8250_port *up =
-               container_of(port, struct uart_8250_port, port);
-
-       /*
-        *      First save the IER then disable the interrupts
-        */
-       ier = serial_in(up, UART_IER);
-       if (up->capabilities & UART_CAP_UUE)
-               serial_out(up, UART_IER, UART_IER_UUE);
-       else
-               serial_out(up, UART_IER, 0);
-
-       wait_for_xmitr(up, BOTH_EMPTY);
-       /*
-        *      Send the character out.
-        *      If a LF, also do CR...
-        */
-       serial_out(up, UART_TX, c);
-       if (c == 10) {
-               wait_for_xmitr(up, BOTH_EMPTY);
-               serial_out(up, UART_TX, 13);
-       }
-
-       /*
-        *      Finally, wait for transmitter to become empty
-        *      and restore the IER
-        */
-       wait_for_xmitr(up, BOTH_EMPTY);
-       serial_out(up, UART_IER, ier);
-}
-
-#endif /* CONFIG_CONSOLE_POLL */
-
-static int serial8250_startup(struct uart_port *port)
-{
-       struct uart_8250_port *up =
-               container_of(port, struct uart_8250_port, port);
-       unsigned long flags;
-       unsigned char lsr, iir;
-       int retval;
-
-       up->port.fifosize = uart_config[up->port.type].fifo_size;
-       up->tx_loadsz = uart_config[up->port.type].tx_loadsz;
-       up->capabilities = uart_config[up->port.type].flags;
-       up->mcr = 0;
-
-       if (up->port.iotype != up->cur_iotype)
-               set_io_from_upio(port);
-
-       if (up->port.type == PORT_16C950) {
-               /* Wake up and initialize UART */
-               up->acr = 0;
-               serial_outp(up, UART_LCR, UART_LCR_CONF_MODE_B);
-               serial_outp(up, UART_EFR, UART_EFR_ECB);
-               serial_outp(up, UART_IER, 0);
-               serial_outp(up, UART_LCR, 0);
-               serial_icr_write(up, UART_CSR, 0); /* Reset the UART */
-               serial_outp(up, UART_LCR, UART_LCR_CONF_MODE_B);
-               serial_outp(up, UART_EFR, UART_EFR_ECB);
-               serial_outp(up, UART_LCR, 0);
-       }
-
-#ifdef CONFIG_SERIAL_8250_RSA
-       /*
-        * If this is an RSA port, see if we can kick it up to the
-        * higher speed clock.
-        */
-       enable_rsa(up);
-#endif
-
-       /*
-        * Clear the FIFO buffers and disable them.
-        * (they will be reenabled in set_termios())
-        */
-       serial8250_clear_fifos(up);
-
-       /*
-        * Clear the interrupt registers.
-        */
-       (void) serial_inp(up, UART_LSR);
-       (void) serial_inp(up, UART_RX);
-       (void) serial_inp(up, UART_IIR);
-       (void) serial_inp(up, UART_MSR);
-
-       /*
-        * At this point, there's no way the LSR could still be 0xff;
-        * if it is, then bail out, because there's likely no UART
-        * here.
-        */
-       if (!(up->port.flags & UPF_BUGGY_UART) &&
-           (serial_inp(up, UART_LSR) == 0xff)) {
-               printk_ratelimited(KERN_INFO "ttyS%d: LSR safety check engaged!\n",
-                                  serial_index(&up->port));
-               return -ENODEV;
-       }
-
-       /*
-        * For a XR16C850, we need to set the trigger levels
-        */
-       if (up->port.type == PORT_16850) {
-               unsigned char fctr;
-
-               serial_outp(up, UART_LCR, UART_LCR_CONF_MODE_B);
-
-               fctr = serial_inp(up, UART_FCTR) & ~(UART_FCTR_RX|UART_FCTR_TX);
-               serial_outp(up, UART_FCTR, fctr | UART_FCTR_TRGD | UART_FCTR_RX);
-               serial_outp(up, UART_TRG, UART_TRG_96);
-               serial_outp(up, UART_FCTR, fctr | UART_FCTR_TRGD | UART_FCTR_TX);
-               serial_outp(up, UART_TRG, UART_TRG_96);
-
-               serial_outp(up, UART_LCR, 0);
-       }
-
-       if (is_real_interrupt(up->port.irq)) {
-               unsigned char iir1;
-               /*
-                * Test for UARTs that do not reassert THRE when the
-                * transmitter is idle and the interrupt has already
-                * been cleared.  Real 16550s should always reassert
-                * this interrupt whenever the transmitter is idle and
-                * the interrupt is enabled.  Delays are necessary to
-                * allow register changes to become visible.
-                */
-               spin_lock_irqsave(&up->port.lock, flags);
-               if (up->port.irqflags & IRQF_SHARED)
-                       disable_irq_nosync(up->port.irq);
-
-               wait_for_xmitr(up, UART_LSR_THRE);
-               serial_out_sync(up, UART_IER, UART_IER_THRI);
-               udelay(1); /* allow THRE to set */
-               iir1 = serial_in(up, UART_IIR);
-               serial_out(up, UART_IER, 0);
-               serial_out_sync(up, UART_IER, UART_IER_THRI);
-               udelay(1); /* allow a working UART time to re-assert THRE */
-               iir = serial_in(up, UART_IIR);
-               serial_out(up, UART_IER, 0);
-
-               if (up->port.irqflags & IRQF_SHARED)
-                       enable_irq(up->port.irq);
-               spin_unlock_irqrestore(&up->port.lock, flags);
-
-               /*
-                * If the interrupt is not reasserted, setup a timer to
-                * kick the UART on a regular basis.
-                */
-               if (!(iir1 & UART_IIR_NO_INT) && (iir & UART_IIR_NO_INT)) {
-                       up->bugs |= UART_BUG_THRE;
-                       pr_debug("ttyS%d - using backup timer\n",
-                                serial_index(port));
-               }
-       }
-
-       /*
-        * The above check will only give an accurate result the first time
-        * the port is opened so this value needs to be preserved.
-        */
-       if (up->bugs & UART_BUG_THRE) {
-               up->timer.function = serial8250_backup_timeout;
-               up->timer.data = (unsigned long)up;
-               mod_timer(&up->timer, jiffies +
-                       uart_poll_timeout(port) + HZ / 5);
-       }
-
-       /*
-        * If the "interrupt" for this port doesn't correspond with any
-        * hardware interrupt, we use a timer-based system.  The original
-        * driver used to do this with IRQ0.
-        */
-       if (!is_real_interrupt(up->port.irq)) {
-               up->timer.data = (unsigned long)up;
-               mod_timer(&up->timer, jiffies + uart_poll_timeout(port));
-       } else {
-               retval = serial_link_irq_chain(up);
-               if (retval)
-                       return retval;
-       }
-
-       /*
-        * Now, initialize the UART
-        */
-       serial_outp(up, UART_LCR, UART_LCR_WLEN8);
-
-       spin_lock_irqsave(&up->port.lock, flags);
-       if (up->port.flags & UPF_FOURPORT) {
-               if (!is_real_interrupt(up->port.irq))
-                       up->port.mctrl |= TIOCM_OUT1;
-       } else
-               /*
-                * Most PC uarts need OUT2 raised to enable interrupts.
-                */
-               if (is_real_interrupt(up->port.irq))
-                       up->port.mctrl |= TIOCM_OUT2;
-
-       serial8250_set_mctrl(&up->port, up->port.mctrl);
-
-       /* Serial over Lan (SoL) hack:
-          Intel 8257x Gigabit ethernet chips have a
-          16550 emulation, to be used for Serial Over Lan.
-          Those chips take a longer time than a normal
-          serial device to signalize that a transmission
-          data was queued. Due to that, the above test generally
-          fails. One solution would be to delay the reading of
-          iir. However, this is not reliable, since the timeout
-          is variable. So, let's just don't test if we receive
-          TX irq. This way, we'll never enable UART_BUG_TXEN.
-        */
-       if (skip_txen_test || up->port.flags & UPF_NO_TXEN_TEST)
-               goto dont_test_tx_en;
-
-       /*
-        * Do a quick test to see if we receive an
-        * interrupt when we enable the TX irq.
-        */
-       serial_outp(up, UART_IER, UART_IER_THRI);
-       lsr = serial_in(up, UART_LSR);
-       iir = serial_in(up, UART_IIR);
-       serial_outp(up, UART_IER, 0);
-
-       if (lsr & UART_LSR_TEMT && iir & UART_IIR_NO_INT) {
-               if (!(up->bugs & UART_BUG_TXEN)) {
-                       up->bugs |= UART_BUG_TXEN;
-                       pr_debug("ttyS%d - enabling bad tx status workarounds\n",
-                                serial_index(port));
-               }
-       } else {
-               up->bugs &= ~UART_BUG_TXEN;
-       }
-
-dont_test_tx_en:
-       spin_unlock_irqrestore(&up->port.lock, flags);
-
-       /*
-        * Clear the interrupt registers again for luck, and clear the
-        * saved flags to avoid getting false values from polling
-        * routines or the previous session.
-        */
-       serial_inp(up, UART_LSR);
-       serial_inp(up, UART_RX);
-       serial_inp(up, UART_IIR);
-       serial_inp(up, UART_MSR);
-       up->lsr_saved_flags = 0;
-       up->msr_saved_flags = 0;
-
-       /*
-        * Finally, enable interrupts.  Note: Modem status interrupts
-        * are set via set_termios(), which will be occurring imminently
-        * anyway, so we don't enable them here.
-        */
-       up->ier = UART_IER_RLSI | UART_IER_RDI;
-       serial_outp(up, UART_IER, up->ier);
-
-       if (up->port.flags & UPF_FOURPORT) {
-               unsigned int icp;
-               /*
-                * Enable interrupts on the AST Fourport board
-                */
-               icp = (up->port.iobase & 0xfe0) | 0x01f;
-               outb_p(0x80, icp);
-               (void) inb_p(icp);
-       }
-
-       return 0;
-}
-
-static void serial8250_shutdown(struct uart_port *port)
-{
-       struct uart_8250_port *up =
-               container_of(port, struct uart_8250_port, port);
-       unsigned long flags;
-
-       /*
-        * Disable interrupts from this port
-        */
-       up->ier = 0;
-       serial_outp(up, UART_IER, 0);
-
-       spin_lock_irqsave(&up->port.lock, flags);
-       if (up->port.flags & UPF_FOURPORT) {
-               /* reset interrupts on the AST Fourport board */
-               inb((up->port.iobase & 0xfe0) | 0x1f);
-               up->port.mctrl |= TIOCM_OUT1;
-       } else
-               up->port.mctrl &= ~TIOCM_OUT2;
-
-       serial8250_set_mctrl(&up->port, up->port.mctrl);
-       spin_unlock_irqrestore(&up->port.lock, flags);
-
-       /*
-        * Disable break condition and FIFOs
-        */
-       serial_out(up, UART_LCR, serial_inp(up, UART_LCR) & ~UART_LCR_SBC);
-       serial8250_clear_fifos(up);
-
-#ifdef CONFIG_SERIAL_8250_RSA
-       /*
-        * Reset the RSA board back to 115kbps compat mode.
-        */
-       disable_rsa(up);
-#endif
-
-       /*
-        * Read data port to reset things, and then unlink from
-        * the IRQ chain.
-        */
-       (void) serial_in(up, UART_RX);
-
-       del_timer_sync(&up->timer);
-       up->timer.function = serial8250_timeout;
-       if (is_real_interrupt(up->port.irq))
-               serial_unlink_irq_chain(up);
-}
-
-static unsigned int serial8250_get_divisor(struct uart_port *port, unsigned int baud)
-{
-       unsigned int quot;
-
-       /*
-        * Handle magic divisors for baud rates above baud_base on
-        * SMSC SuperIO chips.
-        */
-       if ((port->flags & UPF_MAGIC_MULTIPLIER) &&
-           baud == (port->uartclk/4))
-               quot = 0x8001;
-       else if ((port->flags & UPF_MAGIC_MULTIPLIER) &&
-                baud == (port->uartclk/8))
-               quot = 0x8002;
-       else
-               quot = uart_get_divisor(port, baud);
-
-       return quot;
-}
-
-void
-serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios,
-                         struct ktermios *old)
-{
-       struct uart_8250_port *up =
-               container_of(port, struct uart_8250_port, port);
-       unsigned char cval, fcr = 0;
-       unsigned long flags;
-       unsigned int baud, quot;
-
-       switch (termios->c_cflag & CSIZE) {
-       case CS5:
-               cval = UART_LCR_WLEN5;
-               break;
-       case CS6:
-               cval = UART_LCR_WLEN6;
-               break;
-       case CS7:
-               cval = UART_LCR_WLEN7;
-               break;
-       default:
-       case CS8:
-               cval = UART_LCR_WLEN8;
-               break;
-       }
-
-       if (termios->c_cflag & CSTOPB)
-               cval |= UART_LCR_STOP;
-       if (termios->c_cflag & PARENB)
-               cval |= UART_LCR_PARITY;
-       if (!(termios->c_cflag & PARODD))
-               cval |= UART_LCR_EPAR;
-#ifdef CMSPAR
-       if (termios->c_cflag & CMSPAR)
-               cval |= UART_LCR_SPAR;
-#endif
-
-       /*
-        * Ask the core to calculate the divisor for us.
-        */
-       baud = uart_get_baud_rate(port, termios, old,
-                                 port->uartclk / 16 / 0xffff,
-                                 port->uartclk / 16);
-       quot = serial8250_get_divisor(port, baud);
-
-       /*
-        * Oxford Semi 952 rev B workaround
-        */
-       if (up->bugs & UART_BUG_QUOT && (quot & 0xff) == 0)
-               quot++;
-
-       if (up->capabilities & UART_CAP_FIFO && up->port.fifosize > 1) {
-               if (baud < 2400)
-                       fcr = UART_FCR_ENABLE_FIFO | UART_FCR_TRIGGER_1;
-               else
-                       fcr = uart_config[up->port.type].fcr;
-       }
-
-       /*
-        * MCR-based auto flow control.  When AFE is enabled, RTS will be
-        * deasserted when the receive FIFO contains more characters than
-        * the trigger, or the MCR RTS bit is cleared.  In the case where
-        * the remote UART is not using CTS auto flow control, we must
-        * have sufficient FIFO entries for the latency of the remote
-        * UART to respond.  IOW, at least 32 bytes of FIFO.
-        */
-       if (up->capabilities & UART_CAP_AFE && up->port.fifosize >= 32) {
-               up->mcr &= ~UART_MCR_AFE;
-               if (termios->c_cflag & CRTSCTS)
-                       up->mcr |= UART_MCR_AFE;
-       }
-
-       /*
-        * Ok, we're now changing the port state.  Do it with
-        * interrupts disabled.
-        */
-       spin_lock_irqsave(&up->port.lock, flags);
-
-       /*
-        * Update the per-port timeout.
-        */
-       uart_update_timeout(port, termios->c_cflag, baud);
-
-       up->port.read_status_mask = UART_LSR_OE | UART_LSR_THRE | UART_LSR_DR;
-       if (termios->c_iflag & INPCK)
-               up->port.read_status_mask |= UART_LSR_FE | UART_LSR_PE;
-       if (termios->c_iflag & (BRKINT | PARMRK))
-               up->port.read_status_mask |= UART_LSR_BI;
-
-       /*
-        * Characteres to ignore
-        */
-       up->port.ignore_status_mask = 0;
-       if (termios->c_iflag & IGNPAR)
-               up->port.ignore_status_mask |= UART_LSR_PE | UART_LSR_FE;
-       if (termios->c_iflag & IGNBRK) {
-               up->port.ignore_status_mask |= UART_LSR_BI;
-               /*
-                * If we're ignoring parity and break indicators,
-                * ignore overruns too (for real raw support).
-                */
-               if (termios->c_iflag & IGNPAR)
-                       up->port.ignore_status_mask |= UART_LSR_OE;
-       }
-
-       /*
-        * ignore all characters if CREAD is not set
-        */
-       if ((termios->c_cflag & CREAD) == 0)
-               up->port.ignore_status_mask |= UART_LSR_DR;
-
-       /*
-        * CTS flow control flag and modem status interrupts
-        */
-       up->ier &= ~UART_IER_MSI;
-       if (!(up->bugs & UART_BUG_NOMSR) &&
-                       UART_ENABLE_MS(&up->port, termios->c_cflag))
-               up->ier |= UART_IER_MSI;
-       if (up->capabilities & UART_CAP_UUE)
-               up->ier |= UART_IER_UUE;
-       if (up->capabilities & UART_CAP_RTOIE)
-               up->ier |= UART_IER_RTOIE;
-
-       serial_out(up, UART_IER, up->ier);
-
-       if (up->capabilities & UART_CAP_EFR) {
-               unsigned char efr = 0;
-               /*
-                * TI16C752/Startech hardware flow control.  FIXME:
-                * - TI16C752 requires control thresholds to be set.
-                * - UART_MCR_RTS is ineffective if auto-RTS mode is enabled.
-                */
-               if (termios->c_cflag & CRTSCTS)
-                       efr |= UART_EFR_CTS;
-
-               serial_outp(up, UART_LCR, UART_LCR_CONF_MODE_B);
-               if (up->port.flags & UPF_EXAR_EFR)
-                       serial_outp(up, UART_XR_EFR, efr);
-               else
-                       serial_outp(up, UART_EFR, efr);
-       }
-
-#ifdef CONFIG_ARCH_OMAP
-       /* Workaround to enable 115200 baud on OMAP1510 internal ports */
-       if (cpu_is_omap1510() && is_omap_port(up)) {
-               if (baud == 115200) {
-                       quot = 1;
-                       serial_out(up, UART_OMAP_OSC_12M_SEL, 1);
-               } else
-                       serial_out(up, UART_OMAP_OSC_12M_SEL, 0);
-       }
-#endif
-
-       if (up->capabilities & UART_NATSEMI) {
-               /* Switch to bank 2 not bank 1, to avoid resetting EXCR2 */
-               serial_outp(up, UART_LCR, 0xe0);
-       } else {
-               serial_outp(up, UART_LCR, cval | UART_LCR_DLAB);/* set DLAB */
-       }
-
-       serial_dl_write(up, quot);
-
-       /*
-        * LCR DLAB must be set to enable 64-byte FIFO mode. If the FCR
-        * is written without DLAB set, this mode will be disabled.
-        */
-       if (up->port.type == PORT_16750)
-               serial_outp(up, UART_FCR, fcr);
-
-       serial_outp(up, UART_LCR, cval);                /* reset DLAB */
-       up->lcr = cval;                                 /* Save LCR */
-       if (up->port.type != PORT_16750) {
-               if (fcr & UART_FCR_ENABLE_FIFO) {
-                       /* emulated UARTs (Lucent Venus 167x) need two steps */
-                       serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO);
-               }
-               serial_outp(up, UART_FCR, fcr);         /* set fcr */
-       }
-       serial8250_set_mctrl(&up->port, up->port.mctrl);
-       spin_unlock_irqrestore(&up->port.lock, flags);
-       /* Don't rewrite B0 */
-       if (tty_termios_baud_rate(termios))
-               tty_termios_encode_baud_rate(termios, baud, baud);
-}
-EXPORT_SYMBOL(serial8250_do_set_termios);
-
-static void
-serial8250_set_termios(struct uart_port *port, struct ktermios *termios,
-                      struct ktermios *old)
-{
-       if (port->set_termios)
-               port->set_termios(port, termios, old);
-       else
-               serial8250_do_set_termios(port, termios, old);
-}
-
-static void
-serial8250_set_ldisc(struct uart_port *port, int new)
-{
-       if (new == N_PPS) {
-               port->flags |= UPF_HARDPPS_CD;
-               serial8250_enable_ms(port);
-       } else
-               port->flags &= ~UPF_HARDPPS_CD;
-}
-
-
-void serial8250_do_pm(struct uart_port *port, unsigned int state,
-                     unsigned int oldstate)
-{
-       struct uart_8250_port *p =
-               container_of(port, struct uart_8250_port, port);
-
-       serial8250_set_sleep(p, state != 0);
-}
-EXPORT_SYMBOL(serial8250_do_pm);
-
-static void
-serial8250_pm(struct uart_port *port, unsigned int state,
-             unsigned int oldstate)
-{
-       if (port->pm)
-               port->pm(port, state, oldstate);
-       else
-               serial8250_do_pm(port, state, oldstate);
-}
-
-static unsigned int serial8250_port_size(struct uart_8250_port *pt)
-{
-       if (pt->port.iotype == UPIO_AU)
-               return 0x1000;
-#ifdef CONFIG_ARCH_OMAP
-       if (is_omap_port(pt))
-               return 0x16 << pt->port.regshift;
-#endif
-       return 8 << pt->port.regshift;
-}
-
-/*
- * Resource handling.
- */
-static int serial8250_request_std_resource(struct uart_8250_port *up)
-{
-       unsigned int size = serial8250_port_size(up);
-       int ret = 0;
-
-       switch (up->port.iotype) {
-       case UPIO_AU:
-       case UPIO_TSI:
-       case UPIO_MEM32:
-       case UPIO_MEM:
-               if (!up->port.mapbase)
-                       break;
-
-               if (!request_mem_region(up->port.mapbase, size, "serial")) {
-                       ret = -EBUSY;
-                       break;
-               }
-
-               if (up->port.flags & UPF_IOREMAP) {
-                       up->port.membase = ioremap_nocache(up->port.mapbase,
-                                                                       size);
-                       if (!up->port.membase) {
-                               release_mem_region(up->port.mapbase, size);
-                               ret = -ENOMEM;
-                       }
-               }
-               break;
-
-       case UPIO_HUB6:
-       case UPIO_PORT:
-               if (!request_region(up->port.iobase, size, "serial"))
-                       ret = -EBUSY;
-               break;
-       }
-       return ret;
-}
-
-static void serial8250_release_std_resource(struct uart_8250_port *up)
-{
-       unsigned int size = serial8250_port_size(up);
-
-       switch (up->port.iotype) {
-       case UPIO_AU:
-       case UPIO_TSI:
-       case UPIO_MEM32:
-       case UPIO_MEM:
-               if (!up->port.mapbase)
-                       break;
-
-               if (up->port.flags & UPF_IOREMAP) {
-                       iounmap(up->port.membase);
-                       up->port.membase = NULL;
-               }
-
-               release_mem_region(up->port.mapbase, size);
-               break;
-
-       case UPIO_HUB6:
-       case UPIO_PORT:
-               release_region(up->port.iobase, size);
-               break;
-       }
-}
-
-static int serial8250_request_rsa_resource(struct uart_8250_port *up)
-{
-       unsigned long start = UART_RSA_BASE << up->port.regshift;
-       unsigned int size = 8 << up->port.regshift;
-       int ret = -EINVAL;
-
-       switch (up->port.iotype) {
-       case UPIO_HUB6:
-       case UPIO_PORT:
-               start += up->port.iobase;
-               if (request_region(start, size, "serial-rsa"))
-                       ret = 0;
-               else
-                       ret = -EBUSY;
-               break;
-       }
-
-       return ret;
-}
-
-static void serial8250_release_rsa_resource(struct uart_8250_port *up)
-{
-       unsigned long offset = UART_RSA_BASE << up->port.regshift;
-       unsigned int size = 8 << up->port.regshift;
-
-       switch (up->port.iotype) {
-       case UPIO_HUB6:
-       case UPIO_PORT:
-               release_region(up->port.iobase + offset, size);
-               break;
-       }
-}
-
-static void serial8250_release_port(struct uart_port *port)
-{
-       struct uart_8250_port *up =
-               container_of(port, struct uart_8250_port, port);
-
-       serial8250_release_std_resource(up);
-       if (up->port.type == PORT_RSA)
-               serial8250_release_rsa_resource(up);
-}
-
-static int serial8250_request_port(struct uart_port *port)
-{
-       struct uart_8250_port *up =
-               container_of(port, struct uart_8250_port, port);
-       int ret = 0;
-
-       ret = serial8250_request_std_resource(up);
-       if (ret == 0 && up->port.type == PORT_RSA) {
-               ret = serial8250_request_rsa_resource(up);
-               if (ret < 0)
-                       serial8250_release_std_resource(up);
-       }
-
-       return ret;
-}
-
-static void serial8250_config_port(struct uart_port *port, int flags)
-{
-       struct uart_8250_port *up =
-               container_of(port, struct uart_8250_port, port);
-       int probeflags = PROBE_ANY;
-       int ret;
-
-       /*
-        * Find the region that we can probe for.  This in turn
-        * tells us whether we can probe for the type of port.
-        */
-       ret = serial8250_request_std_resource(up);
-       if (ret < 0)
-               return;
-
-       ret = serial8250_request_rsa_resource(up);
-       if (ret < 0)
-               probeflags &= ~PROBE_RSA;
-
-       if (up->port.iotype != up->cur_iotype)
-               set_io_from_upio(port);
-
-       if (flags & UART_CONFIG_TYPE)
-               autoconfig(up, probeflags);
-
-       /* if access method is AU, it is a 16550 with a quirk */
-       if (up->port.type == PORT_16550A && up->port.iotype == UPIO_AU)
-               up->bugs |= UART_BUG_NOMSR;
-
-       if (up->port.type != PORT_UNKNOWN && flags & UART_CONFIG_IRQ)
-               autoconfig_irq(up);
-
-       if (up->port.type != PORT_RSA && probeflags & PROBE_RSA)
-               serial8250_release_rsa_resource(up);
-       if (up->port.type == PORT_UNKNOWN)
-               serial8250_release_std_resource(up);
-}
-
-static int
-serial8250_verify_port(struct uart_port *port, struct serial_struct *ser)
-{
-       if (ser->irq >= nr_irqs || ser->irq < 0 ||
-           ser->baud_base < 9600 || ser->type < PORT_UNKNOWN ||
-           ser->type >= ARRAY_SIZE(uart_config) || ser->type == PORT_CIRRUS ||
-           ser->type == PORT_STARTECH)
-               return -EINVAL;
-       return 0;
-}
-
-static const char *
-serial8250_type(struct uart_port *port)
-{
-       int type = port->type;
-
-       if (type >= ARRAY_SIZE(uart_config))
-               type = 0;
-       return uart_config[type].name;
-}
-
-static struct uart_ops serial8250_pops = {
-       .tx_empty       = serial8250_tx_empty,
-       .set_mctrl      = serial8250_set_mctrl,
-       .get_mctrl      = serial8250_get_mctrl,
-       .stop_tx        = serial8250_stop_tx,
-       .start_tx       = serial8250_start_tx,
-       .stop_rx        = serial8250_stop_rx,
-       .enable_ms      = serial8250_enable_ms,
-       .break_ctl      = serial8250_break_ctl,
-       .startup        = serial8250_startup,
-       .shutdown       = serial8250_shutdown,
-       .set_termios    = serial8250_set_termios,
-       .set_ldisc      = serial8250_set_ldisc,
-       .pm             = serial8250_pm,
-       .type           = serial8250_type,
-       .release_port   = serial8250_release_port,
-       .request_port   = serial8250_request_port,
-       .config_port    = serial8250_config_port,
-       .verify_port    = serial8250_verify_port,
-#ifdef CONFIG_CONSOLE_POLL
-       .poll_get_char = serial8250_get_poll_char,
-       .poll_put_char = serial8250_put_poll_char,
-#endif
-};
-
-static struct uart_8250_port serial8250_ports[UART_NR];
-
-static void (*serial8250_isa_config)(int port, struct uart_port *up,
-       unsigned short *capabilities);
-
-void serial8250_set_isa_configurator(
-       void (*v)(int port, struct uart_port *up, unsigned short *capabilities))
-{
-       serial8250_isa_config = v;
-}
-EXPORT_SYMBOL(serial8250_set_isa_configurator);
-
-static void __init serial8250_isa_init_ports(void)
-{
-       struct uart_8250_port *up;
-       static int first = 1;
-       int i, irqflag = 0;
-
-       if (!first)
-               return;
-       first = 0;
-
-       for (i = 0; i < nr_uarts; i++) {
-               struct uart_8250_port *up = &serial8250_ports[i];
-
-               up->port.line = i;
-               spin_lock_init(&up->port.lock);
-
-               init_timer(&up->timer);
-               up->timer.function = serial8250_timeout;
-
-               /*
-                * ALPHA_KLUDGE_MCR needs to be killed.
-                */
-               up->mcr_mask = ~ALPHA_KLUDGE_MCR;
-               up->mcr_force = ALPHA_KLUDGE_MCR;
-
-               up->port.ops = &serial8250_pops;
-       }
-
-       if (share_irqs)
-               irqflag = IRQF_SHARED;
-
-       for (i = 0, up = serial8250_ports;
-            i < ARRAY_SIZE(old_serial_port) && i < nr_uarts;
-            i++, up++) {
-               up->port.iobase   = old_serial_port[i].port;
-               up->port.irq      = irq_canonicalize(old_serial_port[i].irq);
-               up->port.irqflags = old_serial_port[i].irqflags;
-               up->port.uartclk  = old_serial_port[i].baud_base * 16;
-               up->port.flags    = old_serial_port[i].flags;
-               up->port.hub6     = old_serial_port[i].hub6;
-               up->port.membase  = old_serial_port[i].iomem_base;
-               up->port.iotype   = old_serial_port[i].io_type;
-               up->port.regshift = old_serial_port[i].iomem_reg_shift;
-               set_io_from_upio(&up->port);
-               up->port.irqflags |= irqflag;
-               if (serial8250_isa_config != NULL)
-                       serial8250_isa_config(i, &up->port, &up->capabilities);
-
-       }
-}
-
-static void
-serial8250_init_fixed_type_port(struct uart_8250_port *up, unsigned int type)
-{
-       up->port.type = type;
-       up->port.fifosize = uart_config[type].fifo_size;
-       up->capabilities = uart_config[type].flags;
-       up->tx_loadsz = uart_config[type].tx_loadsz;
-}
-
-static void __init
-serial8250_register_ports(struct uart_driver *drv, struct device *dev)
-{
-       int i;
-
-       for (i = 0; i < nr_uarts; i++) {
-               struct uart_8250_port *up = &serial8250_ports[i];
-               up->cur_iotype = 0xFF;
-       }
-
-       serial8250_isa_init_ports();
-
-       for (i = 0; i < nr_uarts; i++) {
-               struct uart_8250_port *up = &serial8250_ports[i];
-
-               up->port.dev = dev;
-
-               if (up->port.flags & UPF_FIXED_TYPE)
-                       serial8250_init_fixed_type_port(up, up->port.type);
-
-               uart_add_one_port(drv, &up->port);
-       }
-}
-
-#ifdef CONFIG_SERIAL_8250_CONSOLE
-
-static void serial8250_console_putchar(struct uart_port *port, int ch)
-{
-       struct uart_8250_port *up =
-               container_of(port, struct uart_8250_port, port);
-
-       wait_for_xmitr(up, UART_LSR_THRE);
-       serial_out(up, UART_TX, ch);
-}
-
-/*
- *     Print a string to the serial port trying not to disturb
- *     any possible real use of the port...
- *
- *     The console_lock must be held when we get here.
- */
-static void
-serial8250_console_write(struct console *co, const char *s, unsigned int count)
-{
-       struct uart_8250_port *up = &serial8250_ports[co->index];
-       unsigned long flags;
-       unsigned int ier;
-       int locked = 1;
-
-       touch_nmi_watchdog();
-
-       local_irq_save(flags);
-       if (up->port.sysrq) {
-               /* serial8250_handle_irq() already took the lock */
-               locked = 0;
-       } else if (oops_in_progress) {
-               locked = spin_trylock(&up->port.lock);
-       } else
-               spin_lock(&up->port.lock);
-
-       /*
-        *      First save the IER then disable the interrupts
-        */
-       ier = serial_in(up, UART_IER);
-
-       if (up->capabilities & UART_CAP_UUE)
-               serial_out(up, UART_IER, UART_IER_UUE);
-       else
-               serial_out(up, UART_IER, 0);
-
-       uart_console_write(&up->port, s, count, serial8250_console_putchar);
-
-       /*
-        *      Finally, wait for transmitter to become empty
-        *      and restore the IER
-        */
-       wait_for_xmitr(up, BOTH_EMPTY);
-       serial_out(up, UART_IER, ier);
-
-       /*
-        *      The receive handling will happen properly because the
-        *      receive ready bit will still be set; it is not cleared
-        *      on read.  However, modem control will not, we must
-        *      call it if we have saved something in the saved flags
-        *      while processing with interrupts off.
-        */
-       if (up->msr_saved_flags)
-               serial8250_modem_status(up);
-
-       if (locked)
-               spin_unlock(&up->port.lock);
-       local_irq_restore(flags);
-}
-
-static int __init serial8250_console_setup(struct console *co, char *options)
-{
-       struct uart_port *port;
-       int baud = 9600;
-       int bits = 8;
-       int parity = 'n';
-       int flow = 'n';
-
-       /*
-        * 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 >= nr_uarts)
-               co->index = 0;
-       port = &serial8250_ports[co->index].port;
-       if (!port->iobase && !port->membase)
-               return -ENODEV;
-
-       if (options)
-               uart_parse_options(options, &baud, &parity, &bits, &flow);
-
-       return uart_set_options(port, co, baud, parity, bits, flow);
-}
-
-static int serial8250_console_early_setup(void)
-{
-       return serial8250_find_port_for_earlycon();
-}
-
-static struct console serial8250_console = {
-       .name           = "ttyS",
-       .write          = serial8250_console_write,
-       .device         = uart_console_device,
-       .setup          = serial8250_console_setup,
-       .early_setup    = serial8250_console_early_setup,
-       .flags          = CON_PRINTBUFFER | CON_ANYTIME,
-       .index          = -1,
-       .data           = &serial8250_reg,
-};
-
-static int __init serial8250_console_init(void)
-{
-       if (nr_uarts > UART_NR)
-               nr_uarts = UART_NR;
-
-       serial8250_isa_init_ports();
-       register_console(&serial8250_console);
-       return 0;
-}
-console_initcall(serial8250_console_init);
-
-int serial8250_find_port(struct uart_port *p)
-{
-       int line;
-       struct uart_port *port;
-
-       for (line = 0; line < nr_uarts; line++) {
-               port = &serial8250_ports[line].port;
-               if (uart_match_port(p, port))
-                       return line;
-       }
-       return -ENODEV;
-}
-
-#define SERIAL8250_CONSOLE     &serial8250_console
-#else
-#define SERIAL8250_CONSOLE     NULL
-#endif
-
-static struct uart_driver serial8250_reg = {
-       .owner                  = THIS_MODULE,
-       .driver_name            = "serial",
-       .dev_name               = "ttyS",
-       .major                  = TTY_MAJOR,
-       .minor                  = 64,
-       .cons                   = SERIAL8250_CONSOLE,
-};
-
-/*
- * early_serial_setup - early registration for 8250 ports
- *
- * Setup an 8250 port structure prior to console initialisation.  Use
- * after console initialisation will cause undefined behaviour.
- */
-int __init early_serial_setup(struct uart_port *port)
-{
-       struct uart_port *p;
-
-       if (port->line >= ARRAY_SIZE(serial8250_ports))
-               return -ENODEV;
-
-       serial8250_isa_init_ports();
-       p = &serial8250_ports[port->line].port;
-       p->iobase       = port->iobase;
-       p->membase      = port->membase;
-       p->irq          = port->irq;
-       p->irqflags     = port->irqflags;
-       p->uartclk      = port->uartclk;
-       p->fifosize     = port->fifosize;
-       p->regshift     = port->regshift;
-       p->iotype       = port->iotype;
-       p->flags        = port->flags;
-       p->mapbase      = port->mapbase;
-       p->private_data = port->private_data;
-       p->type         = port->type;
-       p->line         = port->line;
-
-       set_io_from_upio(p);
-       if (port->serial_in)
-               p->serial_in = port->serial_in;
-       if (port->serial_out)
-               p->serial_out = port->serial_out;
-       if (port->handle_irq)
-               p->handle_irq = port->handle_irq;
-       else
-               p->handle_irq = serial8250_default_handle_irq;
-
-       return 0;
-}
-
-/**
- *     serial8250_suspend_port - suspend one serial port
- *     @line:  serial line number
- *
- *     Suspend one serial port.
- */
-void serial8250_suspend_port(int line)
-{
-       uart_suspend_port(&serial8250_reg, &serial8250_ports[line].port);
-}
-
-/**
- *     serial8250_resume_port - resume one serial port
- *     @line:  serial line number
- *
- *     Resume one serial port.
- */
-void serial8250_resume_port(int line)
-{
-       struct uart_8250_port *up = &serial8250_ports[line];
-
-       if (up->capabilities & UART_NATSEMI) {
-               /* Ensure it's still in high speed mode */
-               serial_outp(up, UART_LCR, 0xE0);
-
-               ns16550a_goto_highspeed(up);
-
-               serial_outp(up, UART_LCR, 0);
-               up->port.uartclk = 921600*16;
-       }
-       uart_resume_port(&serial8250_reg, &up->port);
-}
-
-/*
- * Register a set of serial devices attached to a platform device.  The
- * list is terminated with a zero flags entry, which means we expect
- * all entries to have at least UPF_BOOT_AUTOCONF set.
- */
-static int __devinit serial8250_probe(struct platform_device *dev)
-{
-       struct plat_serial8250_port *p = dev->dev.platform_data;
-       struct uart_port port;
-       int ret, i, irqflag = 0;
-
-       memset(&port, 0, sizeof(struct uart_port));
-
-       if (share_irqs)
-               irqflag = IRQF_SHARED;
-
-       for (i = 0; p && p->flags != 0; p++, i++) {
-               port.iobase             = p->iobase;
-               port.membase            = p->membase;
-               port.irq                = p->irq;
-               port.irqflags           = p->irqflags;
-               port.uartclk            = p->uartclk;
-               port.regshift           = p->regshift;
-               port.iotype             = p->iotype;
-               port.flags              = p->flags;
-               port.mapbase            = p->mapbase;
-               port.hub6               = p->hub6;
-               port.private_data       = p->private_data;
-               port.type               = p->type;
-               port.serial_in          = p->serial_in;
-               port.serial_out         = p->serial_out;
-               port.handle_irq         = p->handle_irq;
-               port.set_termios        = p->set_termios;
-               port.pm                 = p->pm;
-               port.dev                = &dev->dev;
-               port.irqflags           |= irqflag;
-               ret = serial8250_register_port(&port);
-               if (ret < 0) {
-                       dev_err(&dev->dev, "unable to register port at index %d "
-                               "(IO%lx MEM%llx IRQ%d): %d\n", i,
-                               p->iobase, (unsigned long long)p->mapbase,
-                               p->irq, ret);
-               }
-       }
-       return 0;
-}
-
-/*
- * Remove serial ports registered against a platform device.
- */
-static int __devexit serial8250_remove(struct platform_device *dev)
-{
-       int i;
-
-       for (i = 0; i < nr_uarts; i++) {
-               struct uart_8250_port *up = &serial8250_ports[i];
-
-               if (up->port.dev == &dev->dev)
-                       serial8250_unregister_port(i);
-       }
-       return 0;
-}
-
-static int serial8250_suspend(struct platform_device *dev, pm_message_t state)
-{
-       int i;
-
-       for (i = 0; i < UART_NR; i++) {
-               struct uart_8250_port *up = &serial8250_ports[i];
-
-               if (up->port.type != PORT_UNKNOWN && up->port.dev == &dev->dev)
-                       uart_suspend_port(&serial8250_reg, &up->port);
-       }
-
-       return 0;
-}
-
-static int serial8250_resume(struct platform_device *dev)
-{
-       int i;
-
-       for (i = 0; i < UART_NR; i++) {
-               struct uart_8250_port *up = &serial8250_ports[i];
-
-               if (up->port.type != PORT_UNKNOWN && up->port.dev == &dev->dev)
-                       serial8250_resume_port(i);
-       }
-
-       return 0;
-}
-
-static struct platform_driver serial8250_isa_driver = {
-       .probe          = serial8250_probe,
-       .remove         = __devexit_p(serial8250_remove),
-       .suspend        = serial8250_suspend,
-       .resume         = serial8250_resume,
-       .driver         = {
-               .name   = "serial8250",
-               .owner  = THIS_MODULE,
-       },
-};
-
-/*
- * This "device" covers _all_ ISA 8250-compatible serial devices listed
- * in the table in include/asm/serial.h
- */
-static struct platform_device *serial8250_isa_devs;
-
-/*
- * serial8250_register_port and serial8250_unregister_port allows for
- * 16x50 serial ports to be configured at run-time, to support PCMCIA
- * modems and PCI multiport cards.
- */
-static DEFINE_MUTEX(serial_mutex);
-
-static struct uart_8250_port *serial8250_find_match_or_unused(struct uart_port *port)
-{
-       int i;
-
-       /*
-        * First, find a port entry which matches.
-        */
-       for (i = 0; i < nr_uarts; i++)
-               if (uart_match_port(&serial8250_ports[i].port, port))
-                       return &serial8250_ports[i];
-
-       /*
-        * We didn't find a matching entry, so look for the first
-        * free entry.  We look for one which hasn't been previously
-        * used (indicated by zero iobase).
-        */
-       for (i = 0; i < nr_uarts; i++)
-               if (serial8250_ports[i].port.type == PORT_UNKNOWN &&
-                   serial8250_ports[i].port.iobase == 0)
-                       return &serial8250_ports[i];
-
-       /*
-        * That also failed.  Last resort is to find any entry which
-        * doesn't have a real port associated with it.
-        */
-       for (i = 0; i < nr_uarts; i++)
-               if (serial8250_ports[i].port.type == PORT_UNKNOWN)
-                       return &serial8250_ports[i];
-
-       return NULL;
-}
-
-/**
- *     serial8250_register_port - register a serial port
- *     @port: serial port template
- *
- *     Configure the serial port specified by the request. If the
- *     port exists and is in use, it is hung up and unregistered
- *     first.
- *
- *     The port is then probed and if necessary the IRQ is autodetected
- *     If this fails an error is returned.
- *
- *     On success the port is ready to use and the line number is returned.
- */
-int serial8250_register_port(struct uart_port *port)
-{
-       struct uart_8250_port *uart;
-       int ret = -ENOSPC;
-
-       if (port->uartclk == 0)
-               return -EINVAL;
-
-       mutex_lock(&serial_mutex);
-
-       uart = serial8250_find_match_or_unused(port);
-       if (uart) {
-               uart_remove_one_port(&serial8250_reg, &uart->port);
-
-               uart->port.iobase       = port->iobase;
-               uart->port.membase      = port->membase;
-               uart->port.irq          = port->irq;
-               uart->port.irqflags     = port->irqflags;
-               uart->port.uartclk      = port->uartclk;
-               uart->port.fifosize     = port->fifosize;
-               uart->port.regshift     = port->regshift;
-               uart->port.iotype       = port->iotype;
-               uart->port.flags        = port->flags | UPF_BOOT_AUTOCONF;
-               uart->port.mapbase      = port->mapbase;
-               uart->port.private_data = port->private_data;
-               if (port->dev)
-                       uart->port.dev = port->dev;
-
-               if (port->flags & UPF_FIXED_TYPE)
-                       serial8250_init_fixed_type_port(uart, port->type);
-
-               set_io_from_upio(&uart->port);
-               /* Possibly override default I/O functions.  */
-               if (port->serial_in)
-                       uart->port.serial_in = port->serial_in;
-               if (port->serial_out)
-                       uart->port.serial_out = port->serial_out;
-               if (port->handle_irq)
-                       uart->port.handle_irq = port->handle_irq;
-               /*  Possibly override set_termios call */
-               if (port->set_termios)
-                       uart->port.set_termios = port->set_termios;
-               if (port->pm)
-                       uart->port.pm = port->pm;
-
-               if (serial8250_isa_config != NULL)
-                       serial8250_isa_config(0, &uart->port,
-                                       &uart->capabilities);
-
-               ret = uart_add_one_port(&serial8250_reg, &uart->port);
-               if (ret == 0)
-                       ret = uart->port.line;
-       }
-       mutex_unlock(&serial_mutex);
-
-       return ret;
-}
-EXPORT_SYMBOL(serial8250_register_port);
-
-/**
- *     serial8250_unregister_port - remove a 16x50 serial port at runtime
- *     @line: serial line number
- *
- *     Remove one serial port.  This may not be called from interrupt
- *     context.  We hand the port back to the our control.
- */
-void serial8250_unregister_port(int line)
-{
-       struct uart_8250_port *uart = &serial8250_ports[line];
-
-       mutex_lock(&serial_mutex);
-       uart_remove_one_port(&serial8250_reg, &uart->port);
-       if (serial8250_isa_devs) {
-               uart->port.flags &= ~UPF_BOOT_AUTOCONF;
-               uart->port.type = PORT_UNKNOWN;
-               uart->port.dev = &serial8250_isa_devs->dev;
-               uart->capabilities = uart_config[uart->port.type].flags;
-               uart_add_one_port(&serial8250_reg, &uart->port);
-       } else {
-               uart->port.dev = NULL;
-       }
-       mutex_unlock(&serial_mutex);
-}
-EXPORT_SYMBOL(serial8250_unregister_port);
-
-static int __init serial8250_init(void)
-{
-       int ret;
-
-       if (nr_uarts > UART_NR)
-               nr_uarts = UART_NR;
-
-       printk(KERN_INFO "Serial: 8250/16550 driver, "
-               "%d ports, IRQ sharing %sabled\n", nr_uarts,
-               share_irqs ? "en" : "dis");
-
-#ifdef CONFIG_SPARC
-       ret = sunserial_register_minors(&serial8250_reg, UART_NR);
-#else
-       serial8250_reg.nr = UART_NR;
-       ret = uart_register_driver(&serial8250_reg);
-#endif
-       if (ret)
-               goto out;
-
-       serial8250_isa_devs = platform_device_alloc("serial8250",
-                                                   PLAT8250_DEV_LEGACY);
-       if (!serial8250_isa_devs) {
-               ret = -ENOMEM;
-               goto unreg_uart_drv;
-       }
-
-       ret = platform_device_add(serial8250_isa_devs);
-       if (ret)
-               goto put_dev;
-
-       serial8250_register_ports(&serial8250_reg, &serial8250_isa_devs->dev);
-
-       ret = platform_driver_register(&serial8250_isa_driver);
-       if (ret == 0)
-               goto out;
-
-       platform_device_del(serial8250_isa_devs);
-put_dev:
-       platform_device_put(serial8250_isa_devs);
-unreg_uart_drv:
-#ifdef CONFIG_SPARC
-       sunserial_unregister_minors(&serial8250_reg, UART_NR);
-#else
-       uart_unregister_driver(&serial8250_reg);
-#endif
-out:
-       return ret;
-}
-
-static void __exit serial8250_exit(void)
-{
-       struct platform_device *isa_dev = serial8250_isa_devs;
-
-       /*
-        * This tells serial8250_unregister_port() not to re-register
-        * the ports (thereby making serial8250_isa_driver permanently
-        * in use.)
-        */
-       serial8250_isa_devs = NULL;
-
-       platform_driver_unregister(&serial8250_isa_driver);
-       platform_device_unregister(isa_dev);
-
-#ifdef CONFIG_SPARC
-       sunserial_unregister_minors(&serial8250_reg, UART_NR);
-#else
-       uart_unregister_driver(&serial8250_reg);
-#endif
-}
-
-module_init(serial8250_init);
-module_exit(serial8250_exit);
-
-EXPORT_SYMBOL(serial8250_suspend_port);
-EXPORT_SYMBOL(serial8250_resume_port);
-
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("Generic 8250/16x50 serial driver");
-
-module_param(share_irqs, uint, 0644);
-MODULE_PARM_DESC(share_irqs, "Share IRQs with other non-8250/16x50 devices"
-       " (unsafe)");
-
-module_param(nr_uarts, uint, 0644);
-MODULE_PARM_DESC(nr_uarts, "Maximum number of UARTs supported. (1-" __MODULE_STRING(CONFIG_SERIAL_8250_NR_UARTS) ")");
-
-module_param(skip_txen_test, uint, 0644);
-MODULE_PARM_DESC(skip_txen_test, "Skip checking for the TXEN bug at init time");
-
-#ifdef CONFIG_SERIAL_8250_RSA
-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);
diff --git a/drivers/tty/serial/8250.h b/drivers/tty/serial/8250.h
deleted file mode 100644 (file)
index ae027be..0000000
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- *  Driver for 8250/16550-type serial ports
- *
- *  Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o.
- *
- *  Copyright (C) 2001 Russell King.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-#include <linux/serial_8250.h>
-
-struct uart_8250_port {
-       struct uart_port        port;
-       struct timer_list       timer;          /* "no irq" timer */
-       struct list_head        list;           /* ports on this IRQ */
-       unsigned short          capabilities;   /* port capabilities */
-       unsigned short          bugs;           /* port bugs */
-       unsigned int            tx_loadsz;      /* transmit fifo load size */
-       unsigned char           acr;
-       unsigned char           ier;
-       unsigned char           lcr;
-       unsigned char           mcr;
-       unsigned char           mcr_mask;       /* mask of user bits */
-       unsigned char           mcr_force;      /* mask of forced bits */
-       unsigned char           cur_iotype;     /* Running I/O type */
-
-       /*
-        * Some bits in registers are cleared on a read, so they must
-        * be saved whenever the register is read but the bits will not
-        * be immediately processed.
-        */
-#define LSR_SAVE_FLAGS UART_LSR_BRK_ERROR_BITS
-       unsigned char           lsr_saved_flags;
-#define MSR_SAVE_FLAGS UART_MSR_ANY_DELTA
-       unsigned char           msr_saved_flags;
-};
-
-struct old_serial_port {
-       unsigned int uart;
-       unsigned int baud_base;
-       unsigned int port;
-       unsigned int irq;
-       unsigned int flags;
-       unsigned char hub6;
-       unsigned char io_type;
-       unsigned char *iomem_base;
-       unsigned short iomem_reg_shift;
-       unsigned long irqflags;
-};
-
-/*
- * This replaces serial_uart_config in include/linux/serial.h
- */
-struct serial8250_config {
-       const char      *name;
-       unsigned short  fifo_size;
-       unsigned short  tx_loadsz;
-       unsigned char   fcr;
-       unsigned int    flags;
-};
-
-#define UART_CAP_FIFO  (1 << 8)        /* UART has FIFO */
-#define UART_CAP_EFR   (1 << 9)        /* UART has EFR */
-#define UART_CAP_SLEEP (1 << 10)       /* UART has IER sleep */
-#define UART_CAP_AFE   (1 << 11)       /* MCR-based hw flow control */
-#define UART_CAP_UUE   (1 << 12)       /* UART needs IER bit 6 set (Xscale) */
-#define UART_CAP_RTOIE (1 << 13)       /* UART needs IER bit 4 set (Xscale, Tegra) */
-
-#define UART_BUG_QUOT  (1 << 0)        /* UART has buggy quot LSB */
-#define UART_BUG_TXEN  (1 << 1)        /* UART has buggy TX IIR status */
-#define UART_BUG_NOMSR (1 << 2)        /* UART has buggy MSR status bits (Au1x00) */
-#define UART_BUG_THRE  (1 << 3)        /* UART has buggy THRE reassertion */
-
-#define PROBE_RSA      (1 << 0)
-#define PROBE_ANY      (~0)
-
-#define HIGH_BITS_OFFSET ((sizeof(long)-sizeof(int))*8)
-
-#ifdef CONFIG_SERIAL_8250_SHARE_IRQ
-#define SERIAL8250_SHARE_IRQS 1
-#else
-#define SERIAL8250_SHARE_IRQS 0
-#endif
-
-#if defined(__alpha__) && !defined(CONFIG_PCI)
-/*
- * Digital did something really horribly wrong with the OUT1 and OUT2
- * lines on at least some ALPHA's.  The failure mode is that if either
- * is cleared, the machine locks up with endless interrupts.
- */
-#define ALPHA_KLUDGE_MCR  (UART_MCR_OUT2 | UART_MCR_OUT1)
-#elif defined(CONFIG_SBC8560)
-/*
- * WindRiver did something similarly broken on their SBC8560 board. The
- * UART tristates its IRQ output while OUT2 is clear, but they pulled
- * the interrupt line _up_ instead of down, so if we register the IRQ
- * while the UART is in that state, we die in an IRQ storm. */
-#define ALPHA_KLUDGE_MCR (UART_MCR_OUT2)
-#else
-#define ALPHA_KLUDGE_MCR 0
-#endif
diff --git a/drivers/tty/serial/8250/8250.c b/drivers/tty/serial/8250/8250.c
new file mode 100644 (file)
index 0000000..9b7336f
--- /dev/null
@@ -0,0 +1,3357 @@
+/*
+ *  Driver for 8250/16550-type serial ports
+ *
+ *  Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o.
+ *
+ *  Copyright (C) 2001 Russell King.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * A note about mapbase / membase
+ *
+ *  mapbase is the physical address of the IO port.
+ *  membase is an 'ioremapped' cookie.
+ */
+
+#if defined(CONFIG_SERIAL_8250_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
+#define SUPPORT_SYSRQ
+#endif
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/ioport.h>
+#include <linux/init.h>
+#include <linux/console.h>
+#include <linux/sysrq.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/tty.h>
+#include <linux/ratelimit.h>
+#include <linux/tty_flip.h>
+#include <linux/serial_reg.h>
+#include <linux/serial_core.h>
+#include <linux/serial.h>
+#include <linux/serial_8250.h>
+#include <linux/nmi.h>
+#include <linux/mutex.h>
+#include <linux/slab.h>
+
+#include <asm/io.h>
+#include <asm/irq.h>
+
+#include "8250.h"
+
+#ifdef CONFIG_SPARC
+#include "../suncore.h"
+#endif
+
+/*
+ * Configuration:
+ *   share_irqs - whether we pass IRQF_SHARED to request_irq().  This option
+ *                is unsafe when used on edge-triggered interrupts.
+ */
+static unsigned int share_irqs = SERIAL8250_SHARE_IRQS;
+
+static unsigned int nr_uarts = CONFIG_SERIAL_8250_RUNTIME_UARTS;
+
+static struct uart_driver serial8250_reg;
+
+static int serial_index(struct uart_port *port)
+{
+       return (serial8250_reg.minor - 64) + port->line;
+}
+
+static unsigned int skip_txen_test; /* force skip of txen test at init time */
+
+/*
+ * Debugging.
+ */
+#if 0
+#define DEBUG_AUTOCONF(fmt...) printk(fmt)
+#else
+#define DEBUG_AUTOCONF(fmt...) do { } while (0)
+#endif
+
+#if 0
+#define DEBUG_INTR(fmt...)     printk(fmt)
+#else
+#define DEBUG_INTR(fmt...)     do { } while (0)
+#endif
+
+#define PASS_LIMIT     512
+
+#define BOTH_EMPTY     (UART_LSR_TEMT | UART_LSR_THRE)
+
+
+/*
+ * We default to IRQ0 for the "no irq" hack.   Some
+ * machine types want others as well - they're free
+ * to redefine this in their header file.
+ */
+#define is_real_interrupt(irq) ((irq) != 0)
+
+#ifdef CONFIG_SERIAL_8250_DETECT_IRQ
+#define CONFIG_SERIAL_DETECT_IRQ 1
+#endif
+#ifdef CONFIG_SERIAL_8250_MANY_PORTS
+#define CONFIG_SERIAL_MANY_PORTS 1
+#endif
+
+/*
+ * HUB6 is always on.  This will be removed once the header
+ * files have been cleaned.
+ */
+#define CONFIG_HUB6 1
+
+#include <asm/serial.h>
+/*
+ * SERIAL_PORT_DFNS tells us about built-in ports that have no
+ * standard enumeration mechanism.   Platforms that can find all
+ * serial ports via mechanisms like ACPI or PCI need not supply it.
+ */
+#ifndef SERIAL_PORT_DFNS
+#define SERIAL_PORT_DFNS
+#endif
+
+static const struct old_serial_port old_serial_port[] = {
+       SERIAL_PORT_DFNS /* defined in asm/serial.h */
+};
+
+#define UART_NR        CONFIG_SERIAL_8250_NR_UARTS
+
+#ifdef CONFIG_SERIAL_8250_RSA
+
+#define PORT_RSA_MAX 4
+static unsigned long probe_rsa[PORT_RSA_MAX];
+static unsigned int probe_rsa_count;
+#endif /* CONFIG_SERIAL_8250_RSA  */
+
+struct irq_info {
+       struct                  hlist_node node;
+       int                     irq;
+       spinlock_t              lock;   /* Protects list not the hash */
+       struct list_head        *head;
+};
+
+#define NR_IRQ_HASH            32      /* Can be adjusted later */
+static struct hlist_head irq_lists[NR_IRQ_HASH];
+static DEFINE_MUTEX(hash_mutex);       /* Used to walk the hash */
+
+/*
+ * Here we define the default xmit fifo size used for each type of UART.
+ */
+static const struct serial8250_config uart_config[] = {
+       [PORT_UNKNOWN] = {
+               .name           = "unknown",
+               .fifo_size      = 1,
+               .tx_loadsz      = 1,
+       },
+       [PORT_8250] = {
+               .name           = "8250",
+               .fifo_size      = 1,
+               .tx_loadsz      = 1,
+       },
+       [PORT_16450] = {
+               .name           = "16450",
+               .fifo_size      = 1,
+               .tx_loadsz      = 1,
+       },
+       [PORT_16550] = {
+               .name           = "16550",
+               .fifo_size      = 1,
+               .tx_loadsz      = 1,
+       },
+       [PORT_16550A] = {
+               .name           = "16550A",
+               .fifo_size      = 16,
+               .tx_loadsz      = 16,
+               .fcr            = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10,
+               .flags          = UART_CAP_FIFO,
+       },
+       [PORT_CIRRUS] = {
+               .name           = "Cirrus",
+               .fifo_size      = 1,
+               .tx_loadsz      = 1,
+       },
+       [PORT_16650] = {
+               .name           = "ST16650",
+               .fifo_size      = 1,
+               .tx_loadsz      = 1,
+               .flags          = UART_CAP_FIFO | UART_CAP_EFR | UART_CAP_SLEEP,
+       },
+       [PORT_16650V2] = {
+               .name           = "ST16650V2",
+               .fifo_size      = 32,
+               .tx_loadsz      = 16,
+               .fcr            = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_01 |
+                                 UART_FCR_T_TRIG_00,
+               .flags          = UART_CAP_FIFO | UART_CAP_EFR | UART_CAP_SLEEP,
+       },
+       [PORT_16750] = {
+               .name           = "TI16750",
+               .fifo_size      = 64,
+               .tx_loadsz      = 64,
+               .fcr            = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10 |
+                                 UART_FCR7_64BYTE,
+               .flags          = UART_CAP_FIFO | UART_CAP_SLEEP | UART_CAP_AFE,
+       },
+       [PORT_STARTECH] = {
+               .name           = "Startech",
+               .fifo_size      = 1,
+               .tx_loadsz      = 1,
+       },
+       [PORT_16C950] = {
+               .name           = "16C950/954",
+               .fifo_size      = 128,
+               .tx_loadsz      = 128,
+               .fcr            = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10,
+               /* UART_CAP_EFR breaks billionon CF bluetooth card. */
+               .flags          = UART_CAP_FIFO | UART_CAP_SLEEP,
+       },
+       [PORT_16654] = {
+               .name           = "ST16654",
+               .fifo_size      = 64,
+               .tx_loadsz      = 32,
+               .fcr            = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_01 |
+                                 UART_FCR_T_TRIG_10,
+               .flags          = UART_CAP_FIFO | UART_CAP_EFR | UART_CAP_SLEEP,
+       },
+       [PORT_16850] = {
+               .name           = "XR16850",
+               .fifo_size      = 128,
+               .tx_loadsz      = 128,
+               .fcr            = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10,
+               .flags          = UART_CAP_FIFO | UART_CAP_EFR | UART_CAP_SLEEP,
+       },
+       [PORT_RSA] = {
+               .name           = "RSA",
+               .fifo_size      = 2048,
+               .tx_loadsz      = 2048,
+               .fcr            = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_11,
+               .flags          = UART_CAP_FIFO,
+       },
+       [PORT_NS16550A] = {
+               .name           = "NS16550A",
+               .fifo_size      = 16,
+               .tx_loadsz      = 16,
+               .fcr            = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10,
+               .flags          = UART_CAP_FIFO | UART_NATSEMI,
+       },
+       [PORT_XSCALE] = {
+               .name           = "XScale",
+               .fifo_size      = 32,
+               .tx_loadsz      = 32,
+               .fcr            = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10,
+               .flags          = UART_CAP_FIFO | UART_CAP_UUE | UART_CAP_RTOIE,
+       },
+       [PORT_RM9000] = {
+               .name           = "RM9000",
+               .fifo_size      = 16,
+               .tx_loadsz      = 16,
+               .fcr            = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10,
+               .flags          = UART_CAP_FIFO,
+       },
+       [PORT_OCTEON] = {
+               .name           = "OCTEON",
+               .fifo_size      = 64,
+               .tx_loadsz      = 64,
+               .fcr            = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10,
+               .flags          = UART_CAP_FIFO,
+       },
+       [PORT_AR7] = {
+               .name           = "AR7",
+               .fifo_size      = 16,
+               .tx_loadsz      = 16,
+               .fcr            = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_00,
+               .flags          = UART_CAP_FIFO | UART_CAP_AFE,
+       },
+       [PORT_U6_16550A] = {
+               .name           = "U6_16550A",
+               .fifo_size      = 64,
+               .tx_loadsz      = 64,
+               .fcr            = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10,
+               .flags          = UART_CAP_FIFO | UART_CAP_AFE,
+       },
+       [PORT_TEGRA] = {
+               .name           = "Tegra",
+               .fifo_size      = 32,
+               .tx_loadsz      = 8,
+               .fcr            = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_01 |
+                                 UART_FCR_T_TRIG_01,
+               .flags          = UART_CAP_FIFO | UART_CAP_RTOIE,
+       },
+       [PORT_XR17D15X] = {
+               .name           = "XR17D15X",
+               .fifo_size      = 64,
+               .tx_loadsz      = 64,
+               .fcr            = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10,
+               .flags          = UART_CAP_FIFO | UART_CAP_AFE | UART_CAP_EFR,
+       },
+};
+
+#if defined(CONFIG_MIPS_ALCHEMY)
+
+/* Au1x00 UART hardware has a weird register layout */
+static const u8 au_io_in_map[] = {
+       [UART_RX]  = 0,
+       [UART_IER] = 2,
+       [UART_IIR] = 3,
+       [UART_LCR] = 5,
+       [UART_MCR] = 6,
+       [UART_LSR] = 7,
+       [UART_MSR] = 8,
+};
+
+static const u8 au_io_out_map[] = {
+       [UART_TX]  = 1,
+       [UART_IER] = 2,
+       [UART_FCR] = 4,
+       [UART_LCR] = 5,
+       [UART_MCR] = 6,
+};
+
+/* sane hardware needs no mapping */
+static inline int map_8250_in_reg(struct uart_port *p, int offset)
+{
+       if (p->iotype != UPIO_AU)
+               return offset;
+       return au_io_in_map[offset];
+}
+
+static inline int map_8250_out_reg(struct uart_port *p, int offset)
+{
+       if (p->iotype != UPIO_AU)
+               return offset;
+       return au_io_out_map[offset];
+}
+
+#elif defined(CONFIG_SERIAL_8250_RM9K)
+
+static const u8
+       regmap_in[8] = {
+               [UART_RX]       = 0x00,
+               [UART_IER]      = 0x0c,
+               [UART_IIR]      = 0x14,
+               [UART_LCR]      = 0x1c,
+               [UART_MCR]      = 0x20,
+               [UART_LSR]      = 0x24,
+               [UART_MSR]      = 0x28,
+               [UART_SCR]      = 0x2c
+       },
+       regmap_out[8] = {
+               [UART_TX]       = 0x04,
+               [UART_IER]      = 0x0c,
+               [UART_FCR]      = 0x18,
+               [UART_LCR]      = 0x1c,
+               [UART_MCR]      = 0x20,
+               [UART_LSR]      = 0x24,
+               [UART_MSR]      = 0x28,
+               [UART_SCR]      = 0x2c
+       };
+
+static inline int map_8250_in_reg(struct uart_port *p, int offset)
+{
+       if (p->iotype != UPIO_RM9000)
+               return offset;
+       return regmap_in[offset];
+}
+
+static inline int map_8250_out_reg(struct uart_port *p, int offset)
+{
+       if (p->iotype != UPIO_RM9000)
+               return offset;
+       return regmap_out[offset];
+}
+
+#else
+
+/* sane hardware needs no mapping */
+#define map_8250_in_reg(up, offset) (offset)
+#define map_8250_out_reg(up, offset) (offset)
+
+#endif
+
+static unsigned int hub6_serial_in(struct uart_port *p, int offset)
+{
+       offset = map_8250_in_reg(p, offset) << p->regshift;
+       outb(p->hub6 - 1 + offset, p->iobase);
+       return inb(p->iobase + 1);
+}
+
+static void hub6_serial_out(struct uart_port *p, int offset, int value)
+{
+       offset = map_8250_out_reg(p, offset) << p->regshift;
+       outb(p->hub6 - 1 + offset, p->iobase);
+       outb(value, p->iobase + 1);
+}
+
+static unsigned int mem_serial_in(struct uart_port *p, int offset)
+{
+       offset = map_8250_in_reg(p, offset) << p->regshift;
+       return readb(p->membase + offset);
+}
+
+static void mem_serial_out(struct uart_port *p, int offset, int value)
+{
+       offset = map_8250_out_reg(p, offset) << p->regshift;
+       writeb(value, p->membase + offset);
+}
+
+static void mem32_serial_out(struct uart_port *p, int offset, int value)
+{
+       offset = map_8250_out_reg(p, offset) << p->regshift;
+       writel(value, p->membase + offset);
+}
+
+static unsigned int mem32_serial_in(struct uart_port *p, int offset)
+{
+       offset = map_8250_in_reg(p, offset) << p->regshift;
+       return readl(p->membase + offset);
+}
+
+static unsigned int au_serial_in(struct uart_port *p, int offset)
+{
+       offset = map_8250_in_reg(p, offset) << p->regshift;
+       return __raw_readl(p->membase + offset);
+}
+
+static void au_serial_out(struct uart_port *p, int offset, int value)
+{
+       offset = map_8250_out_reg(p, offset) << p->regshift;
+       __raw_writel(value, p->membase + offset);
+}
+
+static unsigned int io_serial_in(struct uart_port *p, int offset)
+{
+       offset = map_8250_in_reg(p, offset) << p->regshift;
+       return inb(p->iobase + offset);
+}
+
+static void io_serial_out(struct uart_port *p, int offset, int value)
+{
+       offset = map_8250_out_reg(p, offset) << p->regshift;
+       outb(value, p->iobase + offset);
+}
+
+static int serial8250_default_handle_irq(struct uart_port *port);
+
+static void set_io_from_upio(struct uart_port *p)
+{
+       struct uart_8250_port *up =
+               container_of(p, struct uart_8250_port, port);
+       switch (p->iotype) {
+       case UPIO_HUB6:
+               p->serial_in = hub6_serial_in;
+               p->serial_out = hub6_serial_out;
+               break;
+
+       case UPIO_MEM:
+               p->serial_in = mem_serial_in;
+               p->serial_out = mem_serial_out;
+               break;
+
+       case UPIO_RM9000:
+       case UPIO_MEM32:
+               p->serial_in = mem32_serial_in;
+               p->serial_out = mem32_serial_out;
+               break;
+
+       case UPIO_AU:
+               p->serial_in = au_serial_in;
+               p->serial_out = au_serial_out;
+               break;
+
+       default:
+               p->serial_in = io_serial_in;
+               p->serial_out = io_serial_out;
+               break;
+       }
+       /* Remember loaded iotype */
+       up->cur_iotype = p->iotype;
+       p->handle_irq = serial8250_default_handle_irq;
+}
+
+static void
+serial_out_sync(struct uart_8250_port *up, int offset, int value)
+{
+       struct uart_port *p = &up->port;
+       switch (p->iotype) {
+       case UPIO_MEM:
+       case UPIO_MEM32:
+       case UPIO_AU:
+               p->serial_out(p, offset, value);
+               p->serial_in(p, UART_LCR);      /* safe, no side-effects */
+               break;
+       default:
+               p->serial_out(p, offset, value);
+       }
+}
+
+#define serial_in(up, offset)          \
+       (up->port.serial_in(&(up)->port, (offset)))
+#define serial_out(up, offset, value)  \
+       (up->port.serial_out(&(up)->port, (offset), (value)))
+/*
+ * We used to support using pause I/O for certain machines.  We
+ * haven't supported this for a while, but just in case it's badly
+ * needed for certain old 386 machines, I've left these #define's
+ * in....
+ */
+#define serial_inp(up, offset)         serial_in(up, offset)
+#define serial_outp(up, offset, value) serial_out(up, offset, value)
+
+/* Uart divisor latch read */
+static inline int _serial_dl_read(struct uart_8250_port *up)
+{
+       return serial_inp(up, UART_DLL) | serial_inp(up, UART_DLM) << 8;
+}
+
+/* Uart divisor latch write */
+static inline void _serial_dl_write(struct uart_8250_port *up, int value)
+{
+       serial_outp(up, UART_DLL, value & 0xff);
+       serial_outp(up, UART_DLM, value >> 8 & 0xff);
+}
+
+#if defined(CONFIG_MIPS_ALCHEMY)
+/* Au1x00 haven't got a standard divisor latch */
+static int serial_dl_read(struct uart_8250_port *up)
+{
+       if (up->port.iotype == UPIO_AU)
+               return __raw_readl(up->port.membase + 0x28);
+       else
+               return _serial_dl_read(up);
+}
+
+static void serial_dl_write(struct uart_8250_port *up, int value)
+{
+       if (up->port.iotype == UPIO_AU)
+               __raw_writel(value, up->port.membase + 0x28);
+       else
+               _serial_dl_write(up, value);
+}
+#elif defined(CONFIG_SERIAL_8250_RM9K)
+static int serial_dl_read(struct uart_8250_port *up)
+{
+       return  (up->port.iotype == UPIO_RM9000) ?
+               (((__raw_readl(up->port.membase + 0x10) << 8) |
+               (__raw_readl(up->port.membase + 0x08) & 0xff)) & 0xffff) :
+               _serial_dl_read(up);
+}
+
+static void serial_dl_write(struct uart_8250_port *up, int value)
+{
+       if (up->port.iotype == UPIO_RM9000) {
+               __raw_writel(value, up->port.membase + 0x08);
+               __raw_writel(value >> 8, up->port.membase + 0x10);
+       } else {
+               _serial_dl_write(up, value);
+       }
+}
+#else
+#define serial_dl_read(up) _serial_dl_read(up)
+#define serial_dl_write(up, value) _serial_dl_write(up, value)
+#endif
+
+/*
+ * For the 16C950
+ */
+static void serial_icr_write(struct uart_8250_port *up, int offset, int value)
+{
+       serial_out(up, UART_SCR, offset);
+       serial_out(up, UART_ICR, value);
+}
+
+static unsigned int serial_icr_read(struct uart_8250_port *up, int offset)
+{
+       unsigned int value;
+
+       serial_icr_write(up, UART_ACR, up->acr | UART_ACR_ICRRD);
+       serial_out(up, UART_SCR, offset);
+       value = serial_in(up, UART_ICR);
+       serial_icr_write(up, UART_ACR, up->acr);
+
+       return value;
+}
+
+/*
+ * FIFO support.
+ */
+static void serial8250_clear_fifos(struct uart_8250_port *p)
+{
+       if (p->capabilities & UART_CAP_FIFO) {
+               serial_outp(p, UART_FCR, UART_FCR_ENABLE_FIFO);
+               serial_outp(p, UART_FCR, UART_FCR_ENABLE_FIFO |
+                              UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT);
+               serial_outp(p, UART_FCR, 0);
+       }
+}
+
+/*
+ * IER sleep support.  UARTs which have EFRs need the "extended
+ * capability" bit enabled.  Note that on XR16C850s, we need to
+ * reset LCR to write to IER.
+ */
+static void serial8250_set_sleep(struct uart_8250_port *p, int sleep)
+{
+       if (p->capabilities & UART_CAP_SLEEP) {
+               if (p->capabilities & UART_CAP_EFR) {
+                       serial_outp(p, UART_LCR, UART_LCR_CONF_MODE_B);
+                       serial_outp(p, UART_EFR, UART_EFR_ECB);
+                       serial_outp(p, UART_LCR, 0);
+               }
+               serial_outp(p, UART_IER, sleep ? UART_IERX_SLEEP : 0);
+               if (p->capabilities & UART_CAP_EFR) {
+                       serial_outp(p, UART_LCR, UART_LCR_CONF_MODE_B);
+                       serial_outp(p, UART_EFR, 0);
+                       serial_outp(p, UART_LCR, 0);
+               }
+       }
+}
+
+#ifdef CONFIG_SERIAL_8250_RSA
+/*
+ * Attempts to turn on the RSA FIFO.  Returns zero on failure.
+ * We set the port uart clock rate if we succeed.
+ */
+static int __enable_rsa(struct uart_8250_port *up)
+{
+       unsigned char mode;
+       int result;
+
+       mode = serial_inp(up, UART_RSA_MSR);
+       result = mode & UART_RSA_MSR_FIFO;
+
+       if (!result) {
+               serial_outp(up, UART_RSA_MSR, mode | UART_RSA_MSR_FIFO);
+               mode = serial_inp(up, UART_RSA_MSR);
+               result = mode & UART_RSA_MSR_FIFO;
+       }
+
+       if (result)
+               up->port.uartclk = SERIAL_RSA_BAUD_BASE * 16;
+
+       return result;
+}
+
+static void enable_rsa(struct uart_8250_port *up)
+{
+       if (up->port.type == PORT_RSA) {
+               if (up->port.uartclk != SERIAL_RSA_BAUD_BASE * 16) {
+                       spin_lock_irq(&up->port.lock);
+                       __enable_rsa(up);
+                       spin_unlock_irq(&up->port.lock);
+               }
+               if (up->port.uartclk == SERIAL_RSA_BAUD_BASE * 16)
+                       serial_outp(up, UART_RSA_FRR, 0);
+       }
+}
+
+/*
+ * Attempts to turn off the RSA FIFO.  Returns zero on failure.
+ * It is unknown why interrupts were disabled in here.  However,
+ * the caller is expected to preserve this behaviour by grabbing
+ * the spinlock before calling this function.
+ */
+static void disable_rsa(struct uart_8250_port *up)
+{
+       unsigned char mode;
+       int result;
+
+       if (up->port.type == PORT_RSA &&
+           up->port.uartclk == SERIAL_RSA_BAUD_BASE * 16) {
+               spin_lock_irq(&up->port.lock);
+
+               mode = serial_inp(up, UART_RSA_MSR);
+               result = !(mode & UART_RSA_MSR_FIFO);
+
+               if (!result) {
+                       serial_outp(up, UART_RSA_MSR, mode & ~UART_RSA_MSR_FIFO);
+                       mode = serial_inp(up, UART_RSA_MSR);
+                       result = !(mode & UART_RSA_MSR_FIFO);
+               }
+
+               if (result)
+                       up->port.uartclk = SERIAL_RSA_BAUD_BASE_LO * 16;
+               spin_unlock_irq(&up->port.lock);
+       }
+}
+#endif /* CONFIG_SERIAL_8250_RSA */
+
+/*
+ * This is a quickie test to see how big the FIFO is.
+ * It doesn't work at all the time, more's the pity.
+ */
+static int size_fifo(struct uart_8250_port *up)
+{
+       unsigned char old_fcr, old_mcr, old_lcr;
+       unsigned short old_dl;
+       int count;
+
+       old_lcr = serial_inp(up, UART_LCR);
+       serial_outp(up, UART_LCR, 0);
+       old_fcr = serial_inp(up, UART_FCR);
+       old_mcr = serial_inp(up, UART_MCR);
+       serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO |
+                   UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT);
+       serial_outp(up, UART_MCR, UART_MCR_LOOP);
+       serial_outp(up, UART_LCR, UART_LCR_CONF_MODE_A);
+       old_dl = serial_dl_read(up);
+       serial_dl_write(up, 0x0001);
+       serial_outp(up, UART_LCR, 0x03);
+       for (count = 0; count < 256; count++)
+               serial_outp(up, UART_TX, count);
+       mdelay(20);/* FIXME - schedule_timeout */
+       for (count = 0; (serial_inp(up, UART_LSR) & UART_LSR_DR) &&
+            (count < 256); count++)
+               serial_inp(up, UART_RX);
+       serial_outp(up, UART_FCR, old_fcr);
+       serial_outp(up, UART_MCR, old_mcr);
+       serial_outp(up, UART_LCR, UART_LCR_CONF_MODE_A);
+       serial_dl_write(up, old_dl);
+       serial_outp(up, UART_LCR, old_lcr);
+
+       return count;
+}
+
+/*
+ * Read UART ID using the divisor method - set DLL and DLM to zero
+ * and the revision will be in DLL and device type in DLM.  We
+ * preserve the device state across this.
+ */
+static unsigned int autoconfig_read_divisor_id(struct uart_8250_port *p)
+{
+       unsigned char old_dll, old_dlm, old_lcr;
+       unsigned int id;
+
+       old_lcr = serial_inp(p, UART_LCR);
+       serial_outp(p, UART_LCR, UART_LCR_CONF_MODE_A);
+
+       old_dll = serial_inp(p, UART_DLL);
+       old_dlm = serial_inp(p, UART_DLM);
+
+       serial_outp(p, UART_DLL, 0);
+       serial_outp(p, UART_DLM, 0);
+
+       id = serial_inp(p, UART_DLL) | serial_inp(p, UART_DLM) << 8;
+
+       serial_outp(p, UART_DLL, old_dll);
+       serial_outp(p, UART_DLM, old_dlm);
+       serial_outp(p, UART_LCR, old_lcr);
+
+       return id;
+}
+
+/*
+ * This is a helper routine to autodetect StarTech/Exar/Oxsemi UART's.
+ * When this function is called we know it is at least a StarTech
+ * 16650 V2, but it might be one of several StarTech UARTs, or one of
+ * its clones.  (We treat the broken original StarTech 16650 V1 as a
+ * 16550, and why not?  Startech doesn't seem to even acknowledge its
+ * existence.)
+ *
+ * What evil have men's minds wrought...
+ */
+static void autoconfig_has_efr(struct uart_8250_port *up)
+{
+       unsigned int id1, id2, id3, rev;
+
+       /*
+        * Everything with an EFR has SLEEP
+        */
+       up->capabilities |= UART_CAP_EFR | UART_CAP_SLEEP;
+
+       /*
+        * First we check to see if it's an Oxford Semiconductor UART.
+        *
+        * If we have to do this here because some non-National
+        * Semiconductor clone chips lock up if you try writing to the
+        * LSR register (which serial_icr_read does)
+        */
+
+       /*
+        * Check for Oxford Semiconductor 16C950.
+        *
+        * EFR [4] must be set else this test fails.
+        *
+        * This shouldn't be necessary, but Mike Hudson (Exoray@isys.ca)
+        * claims that it's needed for 952 dual UART's (which are not
+        * recommended for new designs).
+        */
+       up->acr = 0;
+       serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B);
+       serial_out(up, UART_EFR, UART_EFR_ECB);
+       serial_out(up, UART_LCR, 0x00);
+       id1 = serial_icr_read(up, UART_ID1);
+       id2 = serial_icr_read(up, UART_ID2);
+       id3 = serial_icr_read(up, UART_ID3);
+       rev = serial_icr_read(up, UART_REV);
+
+       DEBUG_AUTOCONF("950id=%02x:%02x:%02x:%02x ", id1, id2, id3, rev);
+
+       if (id1 == 0x16 && id2 == 0xC9 &&
+           (id3 == 0x50 || id3 == 0x52 || id3 == 0x54)) {
+               up->port.type = PORT_16C950;
+
+               /*
+                * Enable work around for the Oxford Semiconductor 952 rev B
+                * chip which causes it to seriously miscalculate baud rates
+                * when DLL is 0.
+                */
+               if (id3 == 0x52 && rev == 0x01)
+                       up->bugs |= UART_BUG_QUOT;
+               return;
+       }
+
+       /*
+        * We check for a XR16C850 by setting DLL and DLM to 0, and then
+        * reading back DLL and DLM.  The chip type depends on the DLM
+        * value read back:
+        *  0x10 - XR16C850 and the DLL contains the chip revision.
+        *  0x12 - XR16C2850.
+        *  0x14 - XR16C854.
+        */
+       id1 = autoconfig_read_divisor_id(up);
+       DEBUG_AUTOCONF("850id=%04x ", id1);
+
+       id2 = id1 >> 8;
+       if (id2 == 0x10 || id2 == 0x12 || id2 == 0x14) {
+               up->port.type = PORT_16850;
+               return;
+       }
+
+       /*
+        * It wasn't an XR16C850.
+        *
+        * We distinguish between the '654 and the '650 by counting
+        * how many bytes are in the FIFO.  I'm using this for now,
+        * since that's the technique that was sent to me in the
+        * serial driver update, but I'm not convinced this works.
+        * I've had problems doing this in the past.  -TYT
+        */
+       if (size_fifo(up) == 64)
+               up->port.type = PORT_16654;
+       else
+               up->port.type = PORT_16650V2;
+}
+
+/*
+ * We detected a chip without a FIFO.  Only two fall into
+ * this category - the original 8250 and the 16450.  The
+ * 16450 has a scratch register (accessible with LCR=0)
+ */
+static void autoconfig_8250(struct uart_8250_port *up)
+{
+       unsigned char scratch, status1, status2;
+
+       up->port.type = PORT_8250;
+
+       scratch = serial_in(up, UART_SCR);
+       serial_outp(up, UART_SCR, 0xa5);
+       status1 = serial_in(up, UART_SCR);
+       serial_outp(up, UART_SCR, 0x5a);
+       status2 = serial_in(up, UART_SCR);
+       serial_outp(up, UART_SCR, scratch);
+
+       if (status1 == 0xa5 && status2 == 0x5a)
+               up->port.type = PORT_16450;
+}
+
+static int broken_efr(struct uart_8250_port *up)
+{
+       /*
+        * Exar ST16C2550 "A2" devices incorrectly detect as
+        * having an EFR, and report an ID of 0x0201.  See
+        * http://linux.derkeiler.com/Mailing-Lists/Kernel/2004-11/4812.html 
+        */
+       if (autoconfig_read_divisor_id(up) == 0x0201 && size_fifo(up) == 16)
+               return 1;
+
+       return 0;
+}
+
+static inline int ns16550a_goto_highspeed(struct uart_8250_port *up)
+{
+       unsigned char status;
+
+       status = serial_in(up, 0x04); /* EXCR2 */
+#define PRESL(x) ((x) & 0x30)
+       if (PRESL(status) == 0x10) {
+               /* already in high speed mode */
+               return 0;
+       } else {
+               status &= ~0xB0; /* Disable LOCK, mask out PRESL[01] */
+               status |= 0x10;  /* 1.625 divisor for baud_base --> 921600 */
+               serial_outp(up, 0x04, status);
+       }
+       return 1;
+}
+
+/*
+ * We know that the chip has FIFOs.  Does it have an EFR?  The
+ * EFR is located in the same register position as the IIR and
+ * we know the top two bits of the IIR are currently set.  The
+ * EFR should contain zero.  Try to read the EFR.
+ */
+static void autoconfig_16550a(struct uart_8250_port *up)
+{
+       unsigned char status1, status2;
+       unsigned int iersave;
+
+       up->port.type = PORT_16550A;
+       up->capabilities |= UART_CAP_FIFO;
+
+       /*
+        * Check for presence of the EFR when DLAB is set.
+        * Only ST16C650V1 UARTs pass this test.
+        */
+       serial_outp(up, UART_LCR, UART_LCR_CONF_MODE_A);
+       if (serial_in(up, UART_EFR) == 0) {
+               serial_outp(up, UART_EFR, 0xA8);
+               if (serial_in(up, UART_EFR) != 0) {
+                       DEBUG_AUTOCONF("EFRv1 ");
+                       up->port.type = PORT_16650;
+                       up->capabilities |= UART_CAP_EFR | UART_CAP_SLEEP;
+               } else {
+                       DEBUG_AUTOCONF("Motorola 8xxx DUART ");
+               }
+               serial_outp(up, UART_EFR, 0);
+               return;
+       }
+
+       /*
+        * Maybe it requires 0xbf to be written to the LCR.
+        * (other ST16C650V2 UARTs, TI16C752A, etc)
+        */
+       serial_outp(up, UART_LCR, UART_LCR_CONF_MODE_B);
+       if (serial_in(up, UART_EFR) == 0 && !broken_efr(up)) {
+               DEBUG_AUTOCONF("EFRv2 ");
+               autoconfig_has_efr(up);
+               return;
+       }
+
+       /*
+        * Check for a National Semiconductor SuperIO chip.
+        * Attempt to switch to bank 2, read the value of the LOOP bit
+        * from EXCR1. Switch back to bank 0, change it in MCR. Then
+        * switch back to bank 2, read it from EXCR1 again and check
+        * it's changed. If so, set baud_base in EXCR2 to 921600. -- dwmw2
+        */
+       serial_outp(up, UART_LCR, 0);
+       status1 = serial_in(up, UART_MCR);
+       serial_outp(up, UART_LCR, 0xE0);
+       status2 = serial_in(up, 0x02); /* EXCR1 */
+
+       if (!((status2 ^ status1) & UART_MCR_LOOP)) {
+               serial_outp(up, UART_LCR, 0);
+               serial_outp(up, UART_MCR, status1 ^ UART_MCR_LOOP);
+               serial_outp(up, UART_LCR, 0xE0);
+               status2 = serial_in(up, 0x02); /* EXCR1 */
+               serial_outp(up, UART_LCR, 0);
+               serial_outp(up, UART_MCR, status1);
+
+               if ((status2 ^ status1) & UART_MCR_LOOP) {
+                       unsigned short quot;
+
+                       serial_outp(up, UART_LCR, 0xE0);
+
+                       quot = serial_dl_read(up);
+                       quot <<= 3;
+
+                       if (ns16550a_goto_highspeed(up))
+                               serial_dl_write(up, quot);
+
+                       serial_outp(up, UART_LCR, 0);
+
+                       up->port.uartclk = 921600*16;
+                       up->port.type = PORT_NS16550A;
+                       up->capabilities |= UART_NATSEMI;
+                       return;
+               }
+       }
+
+       /*
+        * No EFR.  Try to detect a TI16750, which only sets bit 5 of
+        * the IIR when 64 byte FIFO mode is enabled when DLAB is set.
+        * Try setting it with and without DLAB set.  Cheap clones
+        * set bit 5 without DLAB set.
+        */
+       serial_outp(up, UART_LCR, 0);
+       serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO | UART_FCR7_64BYTE);
+       status1 = serial_in(up, UART_IIR) >> 5;
+       serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO);
+       serial_outp(up, UART_LCR, UART_LCR_CONF_MODE_A);
+       serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO | UART_FCR7_64BYTE);
+       status2 = serial_in(up, UART_IIR) >> 5;
+       serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO);
+       serial_outp(up, UART_LCR, 0);
+
+       DEBUG_AUTOCONF("iir1=%d iir2=%d ", status1, status2);
+
+       if (status1 == 6 && status2 == 7) {
+               up->port.type = PORT_16750;
+               up->capabilities |= UART_CAP_AFE | UART_CAP_SLEEP;
+               return;
+       }
+
+       /*
+        * Try writing and reading the UART_IER_UUE bit (b6).
+        * If it works, this is probably one of the Xscale platform's
+        * internal UARTs.
+        * We're going to explicitly set the UUE bit to 0 before
+        * trying to write and read a 1 just to make sure it's not
+        * already a 1 and maybe locked there before we even start start.
+        */
+       iersave = serial_in(up, UART_IER);
+       serial_outp(up, UART_IER, iersave & ~UART_IER_UUE);
+       if (!(serial_in(up, UART_IER) & UART_IER_UUE)) {
+               /*
+                * OK it's in a known zero state, try writing and reading
+                * without disturbing the current state of the other bits.
+                */
+               serial_outp(up, UART_IER, iersave | UART_IER_UUE);
+               if (serial_in(up, UART_IER) & UART_IER_UUE) {
+                       /*
+                        * It's an Xscale.
+                        * We'll leave the UART_IER_UUE bit set to 1 (enabled).
+                        */
+                       DEBUG_AUTOCONF("Xscale ");
+                       up->port.type = PORT_XSCALE;
+                       up->capabilities |= UART_CAP_UUE | UART_CAP_RTOIE;
+                       return;
+               }
+       } else {
+               /*
+                * If we got here we couldn't force the IER_UUE bit to 0.
+                * Log it and continue.
+                */
+               DEBUG_AUTOCONF("Couldn't force IER_UUE to 0 ");
+       }
+       serial_outp(up, UART_IER, iersave);
+
+       /*
+        * Exar uarts have EFR in a weird location
+        */
+       if (up->port.flags & UPF_EXAR_EFR) {
+               up->port.type = PORT_XR17D15X;
+               up->capabilities |= UART_CAP_AFE | UART_CAP_EFR;
+       }
+
+       /*
+        * We distinguish between 16550A and U6 16550A by counting
+        * how many bytes are in the FIFO.
+        */
+       if (up->port.type == PORT_16550A && size_fifo(up) == 64) {
+               up->port.type = PORT_U6_16550A;
+               up->capabilities |= UART_CAP_AFE;
+       }
+}
+
+/*
+ * This routine is called by rs_init() to initialize a specific serial
+ * port.  It determines what type of UART chip this serial port is
+ * using: 8250, 16450, 16550, 16550A.  The important question is
+ * whether or not this UART is a 16550A or not, since this will
+ * determine whether or not we can use its FIFO features or not.
+ */
+static void autoconfig(struct uart_8250_port *up, unsigned int probeflags)
+{
+       unsigned char status1, scratch, scratch2, scratch3;
+       unsigned char save_lcr, save_mcr;
+       unsigned long flags;
+
+       if (!up->port.iobase && !up->port.mapbase && !up->port.membase)
+               return;
+
+       DEBUG_AUTOCONF("ttyS%d: autoconf (0x%04lx, 0x%p): ",
+                      serial_index(&up->port), up->port.iobase, up->port.membase);
+
+       /*
+        * We really do need global IRQs disabled here - we're going to
+        * be frobbing the chips IRQ enable register to see if it exists.
+        */
+       spin_lock_irqsave(&up->port.lock, flags);
+
+       up->capabilities = 0;
+       up->bugs = 0;
+
+       if (!(up->port.flags & UPF_BUGGY_UART)) {
+               /*
+                * Do a simple existence test first; if we fail this,
+                * there's no point trying anything else.
+                *
+                * 0x80 is used as a nonsense port to prevent against
+                * false positives due to ISA bus float.  The
+                * assumption is that 0x80 is a non-existent port;
+                * which should be safe since include/asm/io.h also
+                * makes this assumption.
+                *
+                * Note: this is safe as long as MCR bit 4 is clear
+                * and the device is in "PC" mode.
+                */
+               scratch = serial_inp(up, UART_IER);
+               serial_outp(up, UART_IER, 0);
+#ifdef __i386__
+               outb(0xff, 0x080);
+#endif
+               /*
+                * Mask out IER[7:4] bits for test as some UARTs (e.g. TL
+                * 16C754B) allow only to modify them if an EFR bit is set.
+                */
+               scratch2 = serial_inp(up, UART_IER) & 0x0f;
+               serial_outp(up, UART_IER, 0x0F);
+#ifdef __i386__
+               outb(0, 0x080);
+#endif
+               scratch3 = serial_inp(up, UART_IER) & 0x0f;
+               serial_outp(up, UART_IER, scratch);
+               if (scratch2 != 0 || scratch3 != 0x0F) {
+                       /*
+                        * We failed; there's nothing here
+                        */
+                       DEBUG_AUTOCONF("IER test failed (%02x, %02x) ",
+                                      scratch2, scratch3);
+                       goto out;
+               }
+       }
+
+       save_mcr = serial_in(up, UART_MCR);
+       save_lcr = serial_in(up, UART_LCR);
+
+       /*
+        * Check to see if a UART is really there.  Certain broken
+        * internal modems based on the Rockwell chipset fail this
+        * test, because they apparently don't implement the loopback
+        * test mode.  So this test is skipped on the COM 1 through
+        * COM 4 ports.  This *should* be safe, since no board
+        * manufacturer would be stupid enough to design a board
+        * that conflicts with COM 1-4 --- we hope!
+        */
+       if (!(up->port.flags & UPF_SKIP_TEST)) {
+               serial_outp(up, UART_MCR, UART_MCR_LOOP | 0x0A);
+               status1 = serial_inp(up, UART_MSR) & 0xF0;
+               serial_outp(up, UART_MCR, save_mcr);
+               if (status1 != 0x90) {
+                       DEBUG_AUTOCONF("LOOP test failed (%02x) ",
+                                      status1);
+                       goto out;
+               }
+       }
+
+       /*
+        * We're pretty sure there's a port here.  Lets find out what
+        * type of port it is.  The IIR top two bits allows us to find
+        * out if it's 8250 or 16450, 16550, 16550A or later.  This
+        * determines what we test for next.
+        *
+        * We also initialise the EFR (if any) to zero for later.  The
+        * EFR occupies the same register location as the FCR and IIR.
+        */
+       serial_outp(up, UART_LCR, UART_LCR_CONF_MODE_B);
+       serial_outp(up, UART_EFR, 0);
+       serial_outp(up, UART_LCR, 0);
+
+       serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO);
+       scratch = serial_in(up, UART_IIR) >> 6;
+
+       DEBUG_AUTOCONF("iir=%d ", scratch);
+
+       switch (scratch) {
+       case 0:
+               autoconfig_8250(up);
+               break;
+       case 1:
+               up->port.type = PORT_UNKNOWN;
+               break;
+       case 2:
+               up->port.type = PORT_16550;
+               break;
+       case 3:
+               autoconfig_16550a(up);
+               break;
+       }
+
+#ifdef CONFIG_SERIAL_8250_RSA
+       /*
+        * Only probe for RSA ports if we got the region.
+        */
+       if (up->port.type == PORT_16550A && probeflags & PROBE_RSA) {
+               int i;
+
+               for (i = 0 ; i < probe_rsa_count; ++i) {
+                       if (probe_rsa[i] == up->port.iobase &&
+                           __enable_rsa(up)) {
+                               up->port.type = PORT_RSA;
+                               break;
+                       }
+               }
+       }
+#endif
+
+       serial_outp(up, UART_LCR, save_lcr);
+
+       if (up->capabilities != uart_config[up->port.type].flags) {
+               printk(KERN_WARNING
+                      "ttyS%d: detected caps %08x should be %08x\n",
+                      serial_index(&up->port), up->capabilities,
+                      uart_config[up->port.type].flags);
+       }
+
+       up->port.fifosize = uart_config[up->port.type].fifo_size;
+       up->capabilities = uart_config[up->port.type].flags;
+       up->tx_loadsz = uart_config[up->port.type].tx_loadsz;
+
+       if (up->port.type == PORT_UNKNOWN)
+               goto out;
+
+       /*
+        * Reset the UART.
+        */
+#ifdef CONFIG_SERIAL_8250_RSA
+       if (up->port.type == PORT_RSA)
+               serial_outp(up, UART_RSA_FRR, 0);
+#endif
+       serial_outp(up, UART_MCR, save_mcr);
+       serial8250_clear_fifos(up);
+       serial_in(up, UART_RX);
+       if (up->capabilities & UART_CAP_UUE)
+               serial_outp(up, UART_IER, UART_IER_UUE);
+       else
+               serial_outp(up, UART_IER, 0);
+
+ out:
+       spin_unlock_irqrestore(&up->port.lock, flags);
+       DEBUG_AUTOCONF("type=%s\n", uart_config[up->port.type].name);
+}
+
+static void autoconfig_irq(struct uart_8250_port *up)
+{
+       unsigned char save_mcr, save_ier;
+       unsigned char save_ICP = 0;
+       unsigned int ICP = 0;
+       unsigned long irqs;
+       int irq;
+
+       if (up->port.flags & UPF_FOURPORT) {
+               ICP = (up->port.iobase & 0xfe0) | 0x1f;
+               save_ICP = inb_p(ICP);
+               outb_p(0x80, ICP);
+               (void) inb_p(ICP);
+       }
+
+       /* forget possible initially masked and pending IRQ */
+       probe_irq_off(probe_irq_on());
+       save_mcr = serial_inp(up, UART_MCR);
+       save_ier = serial_inp(up, UART_IER);
+       serial_outp(up, UART_MCR, UART_MCR_OUT1 | UART_MCR_OUT2);
+
+       irqs = probe_irq_on();
+       serial_outp(up, UART_MCR, 0);
+       udelay(10);
+       if (up->port.flags & UPF_FOURPORT) {
+               serial_outp(up, UART_MCR,
+                           UART_MCR_DTR | UART_MCR_RTS);
+       } else {
+               serial_outp(up, UART_MCR,
+                           UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2);
+       }
+       serial_outp(up, UART_IER, 0x0f);        /* enable all intrs */
+       (void)serial_inp(up, UART_LSR);
+       (void)serial_inp(up, UART_RX);
+       (void)serial_inp(up, UART_IIR);
+       (void)serial_inp(up, UART_MSR);
+       serial_outp(up, UART_TX, 0xFF);
+       udelay(20);
+       irq = probe_irq_off(irqs);
+
+       serial_outp(up, UART_MCR, save_mcr);
+       serial_outp(up, UART_IER, save_ier);
+
+       if (up->port.flags & UPF_FOURPORT)
+               outb_p(save_ICP, ICP);
+
+       up->port.irq = (irq > 0) ? irq : 0;
+}
+
+static inline void __stop_tx(struct uart_8250_port *p)
+{
+       if (p->ier & UART_IER_THRI) {
+               p->ier &= ~UART_IER_THRI;
+               serial_out(p, UART_IER, p->ier);
+       }
+}
+
+static void serial8250_stop_tx(struct uart_port *port)
+{
+       struct uart_8250_port *up =
+               container_of(port, struct uart_8250_port, port);
+
+       __stop_tx(up);
+
+       /*
+        * We really want to stop the transmitter from sending.
+        */
+       if (up->port.type == PORT_16C950) {
+               up->acr |= UART_ACR_TXDIS;
+               serial_icr_write(up, UART_ACR, up->acr);
+       }
+}
+
+static void serial8250_start_tx(struct uart_port *port)
+{
+       struct uart_8250_port *up =
+               container_of(port, struct uart_8250_port, port);
+
+       if (!(up->ier & UART_IER_THRI)) {
+               up->ier |= UART_IER_THRI;
+               serial_out(up, UART_IER, up->ier);
+
+               if (up->bugs & UART_BUG_TXEN) {
+                       unsigned char lsr;
+                       lsr = serial_in(up, UART_LSR);
+                       up->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS;
+                       if ((up->port.type == PORT_RM9000) ?
+                               (lsr & UART_LSR_THRE) :
+                               (lsr & UART_LSR_TEMT))
+                               serial8250_tx_chars(up);
+               }
+       }
+
+       /*
+        * Re-enable the transmitter if we disabled it.
+        */
+       if (up->port.type == PORT_16C950 && up->acr & UART_ACR_TXDIS) {
+               up->acr &= ~UART_ACR_TXDIS;
+               serial_icr_write(up, UART_ACR, up->acr);
+       }
+}
+
+static void serial8250_stop_rx(struct uart_port *port)
+{
+       struct uart_8250_port *up =
+               container_of(port, struct uart_8250_port, port);
+
+       up->ier &= ~UART_IER_RLSI;
+       up->port.read_status_mask &= ~UART_LSR_DR;
+       serial_out(up, UART_IER, up->ier);
+}
+
+static void serial8250_enable_ms(struct uart_port *port)
+{
+       struct uart_8250_port *up =
+               container_of(port, struct uart_8250_port, port);
+
+       /* no MSR capabilities */
+       if (up->bugs & UART_BUG_NOMSR)
+               return;
+
+       up->ier |= UART_IER_MSI;
+       serial_out(up, UART_IER, up->ier);
+}
+
+/*
+ * Clear the Tegra rx fifo after a break
+ *
+ * FIXME: This needs to become a port specific callback once we have a
+ * framework for this
+ */
+static void clear_rx_fifo(struct uart_8250_port *up)
+{
+       unsigned int status, tmout = 10000;
+       do {
+               status = serial_in(up, UART_LSR);
+               if (status & (UART_LSR_FIFOE | UART_LSR_BRK_ERROR_BITS))
+                       status = serial_in(up, UART_RX);
+               else
+                       break;
+               if (--tmout == 0)
+                       break;
+               udelay(1);
+       } while (1);
+}
+
+/*
+ * serial8250_rx_chars: processes according to the passed in LSR
+ * value, and returns the remaining LSR bits not handled
+ * by this Rx routine.
+ */
+unsigned char
+serial8250_rx_chars(struct uart_8250_port *up, unsigned char lsr)
+{
+       struct tty_struct *tty = up->port.state->port.tty;
+       unsigned char ch;
+       int max_count = 256;
+       char flag;
+
+       do {
+               if (likely(lsr & UART_LSR_DR))
+                       ch = serial_inp(up, UART_RX);
+               else
+                       /*
+                        * Intel 82571 has a Serial Over Lan device that will
+                        * set UART_LSR_BI without setting UART_LSR_DR when
+                        * it receives a break. To avoid reading from the
+                        * receive buffer without UART_LSR_DR bit set, we
+                        * just force the read character to be 0
+                        */
+                       ch = 0;
+
+               flag = TTY_NORMAL;
+               up->port.icount.rx++;
+
+               lsr |= up->lsr_saved_flags;
+               up->lsr_saved_flags = 0;
+
+               if (unlikely(lsr & UART_LSR_BRK_ERROR_BITS)) {
+                       /*
+                        * For statistics only
+                        */
+                       if (lsr & UART_LSR_BI) {
+                               lsr &= ~(UART_LSR_FE | UART_LSR_PE);
+                               up->port.icount.brk++;
+                               /*
+                                * If tegra port then clear the rx fifo to
+                                * accept another break/character.
+                                */
+                               if (up->port.type == PORT_TEGRA)
+                                       clear_rx_fifo(up);
+
+                               /*
+                                * We do the SysRQ and SAK checking
+                                * here because otherwise the break
+                                * may get masked by ignore_status_mask
+                                * or read_status_mask.
+                                */
+                               if (uart_handle_break(&up->port))
+                                       goto ignore_char;
+                       } else if (lsr & UART_LSR_PE)
+                               up->port.icount.parity++;
+                       else if (lsr & UART_LSR_FE)
+                               up->port.icount.frame++;
+                       if (lsr & UART_LSR_OE)
+                               up->port.icount.overrun++;
+
+                       /*
+                        * Mask off conditions which should be ignored.
+                        */
+                       lsr &= up->port.read_status_mask;
+
+                       if (lsr & UART_LSR_BI) {
+                               DEBUG_INTR("handling break....");
+                               flag = TTY_BREAK;
+                       } else if (lsr & UART_LSR_PE)
+                               flag = TTY_PARITY;
+                       else if (lsr & UART_LSR_FE)
+                               flag = TTY_FRAME;
+               }
+               if (uart_handle_sysrq_char(&up->port, ch))
+                       goto ignore_char;
+
+               uart_insert_char(&up->port, lsr, UART_LSR_OE, ch, flag);
+
+ignore_char:
+               lsr = serial_inp(up, UART_LSR);
+       } while ((lsr & (UART_LSR_DR | UART_LSR_BI)) && (max_count-- > 0));
+       spin_unlock(&up->port.lock);
+       tty_flip_buffer_push(tty);
+       spin_lock(&up->port.lock);
+       return lsr;
+}
+EXPORT_SYMBOL_GPL(serial8250_rx_chars);
+
+void serial8250_tx_chars(struct uart_8250_port *up)
+{
+       struct circ_buf *xmit = &up->port.state->xmit;
+       int count;
+
+       if (up->port.x_char) {
+               serial_outp(up, UART_TX, up->port.x_char);
+               up->port.icount.tx++;
+               up->port.x_char = 0;
+               return;
+       }
+       if (uart_tx_stopped(&up->port)) {
+               serial8250_stop_tx(&up->port);
+               return;
+       }
+       if (uart_circ_empty(xmit)) {
+               __stop_tx(up);
+               return;
+       }
+
+       count = up->tx_loadsz;
+       do {
+               serial_out(up, UART_TX, xmit->buf[xmit->tail]);
+               xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
+               up->port.icount.tx++;
+               if (uart_circ_empty(xmit))
+                       break;
+       } while (--count > 0);
+
+       if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+               uart_write_wakeup(&up->port);
+
+       DEBUG_INTR("THRE...");
+
+       if (uart_circ_empty(xmit))
+               __stop_tx(up);
+}
+EXPORT_SYMBOL_GPL(serial8250_tx_chars);
+
+unsigned int serial8250_modem_status(struct uart_8250_port *up)
+{
+       unsigned int status = serial_in(up, UART_MSR);
+
+       status |= up->msr_saved_flags;
+       up->msr_saved_flags = 0;
+       if (status & UART_MSR_ANY_DELTA && up->ier & UART_IER_MSI &&
+           up->port.state != NULL) {
+               if (status & UART_MSR_TERI)
+                       up->port.icount.rng++;
+               if (status & UART_MSR_DDSR)
+                       up->port.icount.dsr++;
+               if (status & UART_MSR_DDCD)
+                       uart_handle_dcd_change(&up->port, status & UART_MSR_DCD);
+               if (status & UART_MSR_DCTS)
+                       uart_handle_cts_change(&up->port, status & UART_MSR_CTS);
+
+               wake_up_interruptible(&up->port.state->port.delta_msr_wait);
+       }
+
+       return status;
+}
+EXPORT_SYMBOL_GPL(serial8250_modem_status);
+
+/*
+ * This handles the interrupt from one port.
+ */
+int serial8250_handle_irq(struct uart_port *port, unsigned int iir)
+{
+       unsigned char status;
+       unsigned long flags;
+       struct uart_8250_port *up =
+               container_of(port, struct uart_8250_port, port);
+
+       if (iir & UART_IIR_NO_INT)
+               return 0;
+
+       spin_lock_irqsave(&up->port.lock, flags);
+
+       status = serial_inp(up, UART_LSR);
+
+       DEBUG_INTR("status = %x...", status);
+
+       if (status & (UART_LSR_DR | UART_LSR_BI))
+               status = serial8250_rx_chars(up, status);
+       serial8250_modem_status(up);
+       if (status & UART_LSR_THRE)
+               serial8250_tx_chars(up);
+
+       spin_unlock_irqrestore(&up->port.lock, flags);
+       return 1;
+}
+EXPORT_SYMBOL_GPL(serial8250_handle_irq);
+
+static int serial8250_default_handle_irq(struct uart_port *port)
+{
+       struct uart_8250_port *up =
+               container_of(port, struct uart_8250_port, port);
+       unsigned int iir = serial_in(up, UART_IIR);
+
+       return serial8250_handle_irq(port, iir);
+}
+
+/*
+ * This is the serial driver's interrupt routine.
+ *
+ * Arjan thinks the old way was overly complex, so it got simplified.
+ * Alan disagrees, saying that need the complexity to handle the weird
+ * nature of ISA shared interrupts.  (This is a special exception.)
+ *
+ * In order to handle ISA shared interrupts properly, we need to check
+ * that all ports have been serviced, and therefore the ISA interrupt
+ * line has been de-asserted.
+ *
+ * This means we need to loop through all ports. checking that they
+ * don't have an interrupt pending.
+ */
+static irqreturn_t serial8250_interrupt(int irq, void *dev_id)
+{
+       struct irq_info *i = dev_id;
+       struct list_head *l, *end = NULL;
+       int pass_counter = 0, handled = 0;
+
+       DEBUG_INTR("serial8250_interrupt(%d)...", irq);
+
+       spin_lock(&i->lock);
+
+       l = i->head;
+       do {
+               struct uart_8250_port *up;
+               struct uart_port *port;
+               bool skip;
+
+               up = list_entry(l, struct uart_8250_port, list);
+               port = &up->port;
+               skip = pass_counter && up->port.flags & UPF_IIR_ONCE;
+
+               if (!skip && port->handle_irq(port)) {
+                       handled = 1;
+                       end = NULL;
+               } else if (end == NULL)
+                       end = l;
+
+               l = l->next;
+
+               if (l == i->head && pass_counter++ > PASS_LIMIT) {
+                       /* If we hit this, we're dead. */
+                       printk_ratelimited(KERN_ERR
+                               "serial8250: too much work for irq%d\n", irq);
+                       break;
+               }
+       } while (l != end);
+
+       spin_unlock(&i->lock);
+
+       DEBUG_INTR("end.\n");
+
+       return IRQ_RETVAL(handled);
+}
+
+/*
+ * To support ISA shared interrupts, we need to have one interrupt
+ * handler that ensures that the IRQ line has been deasserted
+ * before returning.  Failing to do this will result in the IRQ
+ * line being stuck active, and, since ISA irqs are edge triggered,
+ * no more IRQs will be seen.
+ */
+static void serial_do_unlink(struct irq_info *i, struct uart_8250_port *up)
+{
+       spin_lock_irq(&i->lock);
+
+       if (!list_empty(i->head)) {
+               if (i->head == &up->list)
+                       i->head = i->head->next;
+               list_del(&up->list);
+       } else {
+               BUG_ON(i->head != &up->list);
+               i->head = NULL;
+       }
+       spin_unlock_irq(&i->lock);
+       /* List empty so throw away the hash node */
+       if (i->head == NULL) {
+               hlist_del(&i->node);
+               kfree(i);
+       }
+}
+
+static int serial_link_irq_chain(struct uart_8250_port *up)
+{
+       struct hlist_head *h;
+       struct hlist_node *n;
+       struct irq_info *i;
+       int ret, irq_flags = up->port.flags & UPF_SHARE_IRQ ? IRQF_SHARED : 0;
+
+       mutex_lock(&hash_mutex);
+
+       h = &irq_lists[up->port.irq % NR_IRQ_HASH];
+
+       hlist_for_each(n, h) {
+               i = hlist_entry(n, struct irq_info, node);
+               if (i->irq == up->port.irq)
+                       break;
+       }
+
+       if (n == NULL) {
+               i = kzalloc(sizeof(struct irq_info), GFP_KERNEL);
+               if (i == NULL) {
+                       mutex_unlock(&hash_mutex);
+                       return -ENOMEM;
+               }
+               spin_lock_init(&i->lock);
+               i->irq = up->port.irq;
+               hlist_add_head(&i->node, h);
+       }
+       mutex_unlock(&hash_mutex);
+
+       spin_lock_irq(&i->lock);
+
+       if (i->head) {
+               list_add(&up->list, i->head);
+               spin_unlock_irq(&i->lock);
+
+               ret = 0;
+       } else {
+               INIT_LIST_HEAD(&up->list);
+               i->head = &up->list;
+               spin_unlock_irq(&i->lock);
+               irq_flags |= up->port.irqflags;
+               ret = request_irq(up->port.irq, serial8250_interrupt,
+                                 irq_flags, "serial", i);
+               if (ret < 0)
+                       serial_do_unlink(i, up);
+       }
+
+       return ret;
+}
+
+static void serial_unlink_irq_chain(struct uart_8250_port *up)
+{
+       struct irq_info *i;
+       struct hlist_node *n;
+       struct hlist_head *h;
+
+       mutex_lock(&hash_mutex);
+
+       h = &irq_lists[up->port.irq % NR_IRQ_HASH];
+
+       hlist_for_each(n, h) {
+               i = hlist_entry(n, struct irq_info, node);
+               if (i->irq == up->port.irq)
+                       break;
+       }
+
+       BUG_ON(n == NULL);
+       BUG_ON(i->head == NULL);
+
+       if (list_empty(i->head))
+               free_irq(up->port.irq, i);
+
+       serial_do_unlink(i, up);
+       mutex_unlock(&hash_mutex);
+}
+
+/*
+ * This function is used to handle ports that do not have an
+ * interrupt.  This doesn't work very well for 16450's, but gives
+ * barely passable results for a 16550A.  (Although at the expense
+ * of much CPU overhead).
+ */
+static void serial8250_timeout(unsigned long data)
+{
+       struct uart_8250_port *up = (struct uart_8250_port *)data;
+
+       up->port.handle_irq(&up->port);
+       mod_timer(&up->timer, jiffies + uart_poll_timeout(&up->port));
+}
+
+static void serial8250_backup_timeout(unsigned long data)
+{
+       struct uart_8250_port *up = (struct uart_8250_port *)data;
+       unsigned int iir, ier = 0, lsr;
+       unsigned long flags;
+
+       spin_lock_irqsave(&up->port.lock, flags);
+
+       /*
+        * Must disable interrupts or else we risk racing with the interrupt
+        * based handler.
+        */
+       if (is_real_interrupt(up->port.irq)) {
+               ier = serial_in(up, UART_IER);
+               serial_out(up, UART_IER, 0);
+       }
+
+       iir = serial_in(up, UART_IIR);
+
+       /*
+        * This should be a safe test for anyone who doesn't trust the
+        * IIR bits on their UART, but it's specifically designed for
+        * the "Diva" UART used on the management processor on many HP
+        * ia64 and parisc boxes.
+        */
+       lsr = serial_in(up, UART_LSR);
+       up->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS;
+       if ((iir & UART_IIR_NO_INT) && (up->ier & UART_IER_THRI) &&
+           (!uart_circ_empty(&up->port.state->xmit) || up->port.x_char) &&
+           (lsr & UART_LSR_THRE)) {
+               iir &= ~(UART_IIR_ID | UART_IIR_NO_INT);
+               iir |= UART_IIR_THRI;
+       }
+
+       if (!(iir & UART_IIR_NO_INT))
+               serial8250_tx_chars(up);
+
+       if (is_real_interrupt(up->port.irq))
+               serial_out(up, UART_IER, ier);
+
+       spin_unlock_irqrestore(&up->port.lock, flags);
+
+       /* Standard timer interval plus 0.2s to keep the port running */
+       mod_timer(&up->timer,
+               jiffies + uart_poll_timeout(&up->port) + HZ / 5);
+}
+
+static unsigned int serial8250_tx_empty(struct uart_port *port)
+{
+       struct uart_8250_port *up =
+               container_of(port, struct uart_8250_port, port);
+       unsigned long flags;
+       unsigned int lsr;
+
+       spin_lock_irqsave(&up->port.lock, flags);
+       lsr = serial_in(up, UART_LSR);
+       up->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS;
+       spin_unlock_irqrestore(&up->port.lock, flags);
+
+       return (lsr & BOTH_EMPTY) == BOTH_EMPTY ? TIOCSER_TEMT : 0;
+}
+
+static unsigned int serial8250_get_mctrl(struct uart_port *port)
+{
+       struct uart_8250_port *up =
+               container_of(port, struct uart_8250_port, port);
+       unsigned int status;
+       unsigned int ret;
+
+       status = serial8250_modem_status(up);
+
+       ret = 0;
+       if (status & UART_MSR_DCD)
+               ret |= TIOCM_CAR;
+       if (status & UART_MSR_RI)
+               ret |= TIOCM_RNG;
+       if (status & UART_MSR_DSR)
+               ret |= TIOCM_DSR;
+       if (status & UART_MSR_CTS)
+               ret |= TIOCM_CTS;
+       return ret;
+}
+
+static void serial8250_set_mctrl(struct uart_port *port, unsigned int mctrl)
+{
+       struct uart_8250_port *up =
+               container_of(port, struct uart_8250_port, port);
+       unsigned char mcr = 0;
+
+       if (mctrl & TIOCM_RTS)
+               mcr |= UART_MCR_RTS;
+       if (mctrl & TIOCM_DTR)
+               mcr |= UART_MCR_DTR;
+       if (mctrl & TIOCM_OUT1)
+               mcr |= UART_MCR_OUT1;
+       if (mctrl & TIOCM_OUT2)
+               mcr |= UART_MCR_OUT2;
+       if (mctrl & TIOCM_LOOP)
+               mcr |= UART_MCR_LOOP;
+
+       mcr = (mcr & up->mcr_mask) | up->mcr_force | up->mcr;
+
+       serial_out(up, UART_MCR, mcr);
+}
+
+static void serial8250_break_ctl(struct uart_port *port, int break_state)
+{
+       struct uart_8250_port *up =
+               container_of(port, struct uart_8250_port, port);
+       unsigned long flags;
+
+       spin_lock_irqsave(&up->port.lock, flags);
+       if (break_state == -1)
+               up->lcr |= UART_LCR_SBC;
+       else
+               up->lcr &= ~UART_LCR_SBC;
+       serial_out(up, UART_LCR, up->lcr);
+       spin_unlock_irqrestore(&up->port.lock, flags);
+}
+
+/*
+ *     Wait for transmitter & holding register to empty
+ */
+static void wait_for_xmitr(struct uart_8250_port *up, int bits)
+{
+       unsigned int status, tmout = 10000;
+
+       /* Wait up to 10ms for the character(s) to be sent. */
+       for (;;) {
+               status = serial_in(up, UART_LSR);
+
+               up->lsr_saved_flags |= status & LSR_SAVE_FLAGS;
+
+               if ((status & bits) == bits)
+                       break;
+               if (--tmout == 0)
+                       break;
+               udelay(1);
+       }
+
+       /* Wait up to 1s for flow control if necessary */
+       if (up->port.flags & UPF_CONS_FLOW) {
+               unsigned int tmout;
+               for (tmout = 1000000; tmout; tmout--) {
+                       unsigned int msr = serial_in(up, UART_MSR);
+                       up->msr_saved_flags |= msr & MSR_SAVE_FLAGS;
+                       if (msr & UART_MSR_CTS)
+                               break;
+                       udelay(1);
+                       touch_nmi_watchdog();
+               }
+       }
+}
+
+#ifdef CONFIG_CONSOLE_POLL
+/*
+ * Console polling routines for writing and reading from the uart while
+ * in an interrupt or debug context.
+ */
+
+static int serial8250_get_poll_char(struct uart_port *port)
+{
+       struct uart_8250_port *up =
+               container_of(port, struct uart_8250_port, port);
+       unsigned char lsr = serial_inp(up, UART_LSR);
+
+       if (!(lsr & UART_LSR_DR))
+               return NO_POLL_CHAR;
+
+       return serial_inp(up, UART_RX);
+}
+
+
+static void serial8250_put_poll_char(struct uart_port *port,
+                        unsigned char c)
+{
+       unsigned int ier;
+       struct uart_8250_port *up =
+               container_of(port, struct uart_8250_port, port);
+
+       /*
+        *      First save the IER then disable the interrupts
+        */
+       ier = serial_in(up, UART_IER);
+       if (up->capabilities & UART_CAP_UUE)
+               serial_out(up, UART_IER, UART_IER_UUE);
+       else
+               serial_out(up, UART_IER, 0);
+
+       wait_for_xmitr(up, BOTH_EMPTY);
+       /*
+        *      Send the character out.
+        *      If a LF, also do CR...
+        */
+       serial_out(up, UART_TX, c);
+       if (c == 10) {
+               wait_for_xmitr(up, BOTH_EMPTY);
+               serial_out(up, UART_TX, 13);
+       }
+
+       /*
+        *      Finally, wait for transmitter to become empty
+        *      and restore the IER
+        */
+       wait_for_xmitr(up, BOTH_EMPTY);
+       serial_out(up, UART_IER, ier);
+}
+
+#endif /* CONFIG_CONSOLE_POLL */
+
+static int serial8250_startup(struct uart_port *port)
+{
+       struct uart_8250_port *up =
+               container_of(port, struct uart_8250_port, port);
+       unsigned long flags;
+       unsigned char lsr, iir;
+       int retval;
+
+       up->port.fifosize = uart_config[up->port.type].fifo_size;
+       up->tx_loadsz = uart_config[up->port.type].tx_loadsz;
+       up->capabilities = uart_config[up->port.type].flags;
+       up->mcr = 0;
+
+       if (up->port.iotype != up->cur_iotype)
+               set_io_from_upio(port);
+
+       if (up->port.type == PORT_16C950) {
+               /* Wake up and initialize UART */
+               up->acr = 0;
+               serial_outp(up, UART_LCR, UART_LCR_CONF_MODE_B);
+               serial_outp(up, UART_EFR, UART_EFR_ECB);
+               serial_outp(up, UART_IER, 0);
+               serial_outp(up, UART_LCR, 0);
+               serial_icr_write(up, UART_CSR, 0); /* Reset the UART */
+               serial_outp(up, UART_LCR, UART_LCR_CONF_MODE_B);
+               serial_outp(up, UART_EFR, UART_EFR_ECB);
+               serial_outp(up, UART_LCR, 0);
+       }
+
+#ifdef CONFIG_SERIAL_8250_RSA
+       /*
+        * If this is an RSA port, see if we can kick it up to the
+        * higher speed clock.
+        */
+       enable_rsa(up);
+#endif
+
+       /*
+        * Clear the FIFO buffers and disable them.
+        * (they will be reenabled in set_termios())
+        */
+       serial8250_clear_fifos(up);
+
+       /*
+        * Clear the interrupt registers.
+        */
+       (void) serial_inp(up, UART_LSR);
+       (void) serial_inp(up, UART_RX);
+       (void) serial_inp(up, UART_IIR);
+       (void) serial_inp(up, UART_MSR);
+
+       /*
+        * At this point, there's no way the LSR could still be 0xff;
+        * if it is, then bail out, because there's likely no UART
+        * here.
+        */
+       if (!(up->port.flags & UPF_BUGGY_UART) &&
+           (serial_inp(up, UART_LSR) == 0xff)) {
+               printk_ratelimited(KERN_INFO "ttyS%d: LSR safety check engaged!\n",
+                                  serial_index(&up->port));
+               return -ENODEV;
+       }
+
+       /*
+        * For a XR16C850, we need to set the trigger levels
+        */
+       if (up->port.type == PORT_16850) {
+               unsigned char fctr;
+
+               serial_outp(up, UART_LCR, UART_LCR_CONF_MODE_B);
+
+               fctr = serial_inp(up, UART_FCTR) & ~(UART_FCTR_RX|UART_FCTR_TX);
+               serial_outp(up, UART_FCTR, fctr | UART_FCTR_TRGD | UART_FCTR_RX);
+               serial_outp(up, UART_TRG, UART_TRG_96);
+               serial_outp(up, UART_FCTR, fctr | UART_FCTR_TRGD | UART_FCTR_TX);
+               serial_outp(up, UART_TRG, UART_TRG_96);
+
+               serial_outp(up, UART_LCR, 0);
+       }
+
+       if (is_real_interrupt(up->port.irq)) {
+               unsigned char iir1;
+               /*
+                * Test for UARTs that do not reassert THRE when the
+                * transmitter is idle and the interrupt has already
+                * been cleared.  Real 16550s should always reassert
+                * this interrupt whenever the transmitter is idle and
+                * the interrupt is enabled.  Delays are necessary to
+                * allow register changes to become visible.
+                */
+               spin_lock_irqsave(&up->port.lock, flags);
+               if (up->port.irqflags & IRQF_SHARED)
+                       disable_irq_nosync(up->port.irq);
+
+               wait_for_xmitr(up, UART_LSR_THRE);
+               serial_out_sync(up, UART_IER, UART_IER_THRI);
+               udelay(1); /* allow THRE to set */
+               iir1 = serial_in(up, UART_IIR);
+               serial_out(up, UART_IER, 0);
+               serial_out_sync(up, UART_IER, UART_IER_THRI);
+               udelay(1); /* allow a working UART time to re-assert THRE */
+               iir = serial_in(up, UART_IIR);
+               serial_out(up, UART_IER, 0);
+
+               if (up->port.irqflags & IRQF_SHARED)
+                       enable_irq(up->port.irq);
+               spin_unlock_irqrestore(&up->port.lock, flags);
+
+               /*
+                * If the interrupt is not reasserted, setup a timer to
+                * kick the UART on a regular basis.
+                */
+               if (!(iir1 & UART_IIR_NO_INT) && (iir & UART_IIR_NO_INT)) {
+                       up->bugs |= UART_BUG_THRE;
+                       pr_debug("ttyS%d - using backup timer\n",
+                                serial_index(port));
+               }
+       }
+
+       /*
+        * The above check will only give an accurate result the first time
+        * the port is opened so this value needs to be preserved.
+        */
+       if (up->bugs & UART_BUG_THRE) {
+               up->timer.function = serial8250_backup_timeout;
+               up->timer.data = (unsigned long)up;
+               mod_timer(&up->timer, jiffies +
+                       uart_poll_timeout(port) + HZ / 5);
+       }
+
+       /*
+        * If the "interrupt" for this port doesn't correspond with any
+        * hardware interrupt, we use a timer-based system.  The original
+        * driver used to do this with IRQ0.
+        */
+       if (!is_real_interrupt(up->port.irq)) {
+               up->timer.data = (unsigned long)up;
+               mod_timer(&up->timer, jiffies + uart_poll_timeout(port));
+       } else {
+               retval = serial_link_irq_chain(up);
+               if (retval)
+                       return retval;
+       }
+
+       /*
+        * Now, initialize the UART
+        */
+       serial_outp(up, UART_LCR, UART_LCR_WLEN8);
+
+       spin_lock_irqsave(&up->port.lock, flags);
+       if (up->port.flags & UPF_FOURPORT) {
+               if (!is_real_interrupt(up->port.irq))
+                       up->port.mctrl |= TIOCM_OUT1;
+       } else
+               /*
+                * Most PC uarts need OUT2 raised to enable interrupts.
+                */
+               if (is_real_interrupt(up->port.irq))
+                       up->port.mctrl |= TIOCM_OUT2;
+
+       serial8250_set_mctrl(&up->port, up->port.mctrl);
+
+       /* Serial over Lan (SoL) hack:
+          Intel 8257x Gigabit ethernet chips have a
+          16550 emulation, to be used for Serial Over Lan.
+          Those chips take a longer time than a normal
+          serial device to signalize that a transmission
+          data was queued. Due to that, the above test generally
+          fails. One solution would be to delay the reading of
+          iir. However, this is not reliable, since the timeout
+          is variable. So, let's just don't test if we receive
+          TX irq. This way, we'll never enable UART_BUG_TXEN.
+        */
+       if (skip_txen_test || up->port.flags & UPF_NO_TXEN_TEST)
+               goto dont_test_tx_en;
+
+       /*
+        * Do a quick test to see if we receive an
+        * interrupt when we enable the TX irq.
+        */
+       serial_outp(up, UART_IER, UART_IER_THRI);
+       lsr = serial_in(up, UART_LSR);
+       iir = serial_in(up, UART_IIR);
+       serial_outp(up, UART_IER, 0);
+
+       if (lsr & UART_LSR_TEMT && iir & UART_IIR_NO_INT) {
+               if (!(up->bugs & UART_BUG_TXEN)) {
+                       up->bugs |= UART_BUG_TXEN;
+                       pr_debug("ttyS%d - enabling bad tx status workarounds\n",
+                                serial_index(port));
+               }
+       } else {
+               up->bugs &= ~UART_BUG_TXEN;
+       }
+
+dont_test_tx_en:
+       spin_unlock_irqrestore(&up->port.lock, flags);
+
+       /*
+        * Clear the interrupt registers again for luck, and clear the
+        * saved flags to avoid getting false values from polling
+        * routines or the previous session.
+        */
+       serial_inp(up, UART_LSR);
+       serial_inp(up, UART_RX);
+       serial_inp(up, UART_IIR);
+       serial_inp(up, UART_MSR);
+       up->lsr_saved_flags = 0;
+       up->msr_saved_flags = 0;
+
+       /*
+        * Finally, enable interrupts.  Note: Modem status interrupts
+        * are set via set_termios(), which will be occurring imminently
+        * anyway, so we don't enable them here.
+        */
+       up->ier = UART_IER_RLSI | UART_IER_RDI;
+       serial_outp(up, UART_IER, up->ier);
+
+       if (up->port.flags & UPF_FOURPORT) {
+               unsigned int icp;
+               /*
+                * Enable interrupts on the AST Fourport board
+                */
+               icp = (up->port.iobase & 0xfe0) | 0x01f;
+               outb_p(0x80, icp);
+               (void) inb_p(icp);
+       }
+
+       return 0;
+}
+
+static void serial8250_shutdown(struct uart_port *port)
+{
+       struct uart_8250_port *up =
+               container_of(port, struct uart_8250_port, port);
+       unsigned long flags;
+
+       /*
+        * Disable interrupts from this port
+        */
+       up->ier = 0;
+       serial_outp(up, UART_IER, 0);
+
+       spin_lock_irqsave(&up->port.lock, flags);
+       if (up->port.flags & UPF_FOURPORT) {
+               /* reset interrupts on the AST Fourport board */
+               inb((up->port.iobase & 0xfe0) | 0x1f);
+               up->port.mctrl |= TIOCM_OUT1;
+       } else
+               up->port.mctrl &= ~TIOCM_OUT2;
+
+       serial8250_set_mctrl(&up->port, up->port.mctrl);
+       spin_unlock_irqrestore(&up->port.lock, flags);
+
+       /*
+        * Disable break condition and FIFOs
+        */
+       serial_out(up, UART_LCR, serial_inp(up, UART_LCR) & ~UART_LCR_SBC);
+       serial8250_clear_fifos(up);
+
+#ifdef CONFIG_SERIAL_8250_RSA
+       /*
+        * Reset the RSA board back to 115kbps compat mode.
+        */
+       disable_rsa(up);
+#endif
+
+       /*
+        * Read data port to reset things, and then unlink from
+        * the IRQ chain.
+        */
+       (void) serial_in(up, UART_RX);
+
+       del_timer_sync(&up->timer);
+       up->timer.function = serial8250_timeout;
+       if (is_real_interrupt(up->port.irq))
+               serial_unlink_irq_chain(up);
+}
+
+static unsigned int serial8250_get_divisor(struct uart_port *port, unsigned int baud)
+{
+       unsigned int quot;
+
+       /*
+        * Handle magic divisors for baud rates above baud_base on
+        * SMSC SuperIO chips.
+        */
+       if ((port->flags & UPF_MAGIC_MULTIPLIER) &&
+           baud == (port->uartclk/4))
+               quot = 0x8001;
+       else if ((port->flags & UPF_MAGIC_MULTIPLIER) &&
+                baud == (port->uartclk/8))
+               quot = 0x8002;
+       else
+               quot = uart_get_divisor(port, baud);
+
+       return quot;
+}
+
+void
+serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios,
+                         struct ktermios *old)
+{
+       struct uart_8250_port *up =
+               container_of(port, struct uart_8250_port, port);
+       unsigned char cval, fcr = 0;
+       unsigned long flags;
+       unsigned int baud, quot;
+
+       switch (termios->c_cflag & CSIZE) {
+       case CS5:
+               cval = UART_LCR_WLEN5;
+               break;
+       case CS6:
+               cval = UART_LCR_WLEN6;
+               break;
+       case CS7:
+               cval = UART_LCR_WLEN7;
+               break;
+       default:
+       case CS8:
+               cval = UART_LCR_WLEN8;
+               break;
+       }
+
+       if (termios->c_cflag & CSTOPB)
+               cval |= UART_LCR_STOP;
+       if (termios->c_cflag & PARENB)
+               cval |= UART_LCR_PARITY;
+       if (!(termios->c_cflag & PARODD))
+               cval |= UART_LCR_EPAR;
+#ifdef CMSPAR
+       if (termios->c_cflag & CMSPAR)
+               cval |= UART_LCR_SPAR;
+#endif
+
+       /*
+        * Ask the core to calculate the divisor for us.
+        */
+       baud = uart_get_baud_rate(port, termios, old,
+                                 port->uartclk / 16 / 0xffff,
+                                 port->uartclk / 16);
+       quot = serial8250_get_divisor(port, baud);
+
+       /*
+        * Oxford Semi 952 rev B workaround
+        */
+       if (up->bugs & UART_BUG_QUOT && (quot & 0xff) == 0)
+               quot++;
+
+       if (up->capabilities & UART_CAP_FIFO && up->port.fifosize > 1) {
+               if (baud < 2400)
+                       fcr = UART_FCR_ENABLE_FIFO | UART_FCR_TRIGGER_1;
+               else
+                       fcr = uart_config[up->port.type].fcr;
+       }
+
+       /*
+        * MCR-based auto flow control.  When AFE is enabled, RTS will be
+        * deasserted when the receive FIFO contains more characters than
+        * the trigger, or the MCR RTS bit is cleared.  In the case where
+        * the remote UART is not using CTS auto flow control, we must
+        * have sufficient FIFO entries for the latency of the remote
+        * UART to respond.  IOW, at least 32 bytes of FIFO.
+        */
+       if (up->capabilities & UART_CAP_AFE && up->port.fifosize >= 32) {
+               up->mcr &= ~UART_MCR_AFE;
+               if (termios->c_cflag & CRTSCTS)
+                       up->mcr |= UART_MCR_AFE;
+       }
+
+       /*
+        * Ok, we're now changing the port state.  Do it with
+        * interrupts disabled.
+        */
+       spin_lock_irqsave(&up->port.lock, flags);
+
+       /*
+        * Update the per-port timeout.
+        */
+       uart_update_timeout(port, termios->c_cflag, baud);
+
+       up->port.read_status_mask = UART_LSR_OE | UART_LSR_THRE | UART_LSR_DR;
+       if (termios->c_iflag & INPCK)
+               up->port.read_status_mask |= UART_LSR_FE | UART_LSR_PE;
+       if (termios->c_iflag & (BRKINT | PARMRK))
+               up->port.read_status_mask |= UART_LSR_BI;
+
+       /*
+        * Characteres to ignore
+        */
+       up->port.ignore_status_mask = 0;
+       if (termios->c_iflag & IGNPAR)
+               up->port.ignore_status_mask |= UART_LSR_PE | UART_LSR_FE;
+       if (termios->c_iflag & IGNBRK) {
+               up->port.ignore_status_mask |= UART_LSR_BI;
+               /*
+                * If we're ignoring parity and break indicators,
+                * ignore overruns too (for real raw support).
+                */
+               if (termios->c_iflag & IGNPAR)
+                       up->port.ignore_status_mask |= UART_LSR_OE;
+       }
+
+       /*
+        * ignore all characters if CREAD is not set
+        */
+       if ((termios->c_cflag & CREAD) == 0)
+               up->port.ignore_status_mask |= UART_LSR_DR;
+
+       /*
+        * CTS flow control flag and modem status interrupts
+        */
+       up->ier &= ~UART_IER_MSI;
+       if (!(up->bugs & UART_BUG_NOMSR) &&
+                       UART_ENABLE_MS(&up->port, termios->c_cflag))
+               up->ier |= UART_IER_MSI;
+       if (up->capabilities & UART_CAP_UUE)
+               up->ier |= UART_IER_UUE;
+       if (up->capabilities & UART_CAP_RTOIE)
+               up->ier |= UART_IER_RTOIE;
+
+       serial_out(up, UART_IER, up->ier);
+
+       if (up->capabilities & UART_CAP_EFR) {
+               unsigned char efr = 0;
+               /*
+                * TI16C752/Startech hardware flow control.  FIXME:
+                * - TI16C752 requires control thresholds to be set.
+                * - UART_MCR_RTS is ineffective if auto-RTS mode is enabled.
+                */
+               if (termios->c_cflag & CRTSCTS)
+                       efr |= UART_EFR_CTS;
+
+               serial_outp(up, UART_LCR, UART_LCR_CONF_MODE_B);
+               if (up->port.flags & UPF_EXAR_EFR)
+                       serial_outp(up, UART_XR_EFR, efr);
+               else
+                       serial_outp(up, UART_EFR, efr);
+       }
+
+#ifdef CONFIG_ARCH_OMAP
+       /* Workaround to enable 115200 baud on OMAP1510 internal ports */
+       if (cpu_is_omap1510() && is_omap_port(up)) {
+               if (baud == 115200) {
+                       quot = 1;
+                       serial_out(up, UART_OMAP_OSC_12M_SEL, 1);
+               } else
+                       serial_out(up, UART_OMAP_OSC_12M_SEL, 0);
+       }
+#endif
+
+       if (up->capabilities & UART_NATSEMI) {
+               /* Switch to bank 2 not bank 1, to avoid resetting EXCR2 */
+               serial_outp(up, UART_LCR, 0xe0);
+       } else {
+               serial_outp(up, UART_LCR, cval | UART_LCR_DLAB);/* set DLAB */
+       }
+
+       serial_dl_write(up, quot);
+
+       /*
+        * LCR DLAB must be set to enable 64-byte FIFO mode. If the FCR
+        * is written without DLAB set, this mode will be disabled.
+        */
+       if (up->port.type == PORT_16750)
+               serial_outp(up, UART_FCR, fcr);
+
+       serial_outp(up, UART_LCR, cval);                /* reset DLAB */
+       up->lcr = cval;                                 /* Save LCR */
+       if (up->port.type != PORT_16750) {
+               if (fcr & UART_FCR_ENABLE_FIFO) {
+                       /* emulated UARTs (Lucent Venus 167x) need two steps */
+                       serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO);
+               }
+               serial_outp(up, UART_FCR, fcr);         /* set fcr */
+       }
+       serial8250_set_mctrl(&up->port, up->port.mctrl);
+       spin_unlock_irqrestore(&up->port.lock, flags);
+       /* Don't rewrite B0 */
+       if (tty_termios_baud_rate(termios))
+               tty_termios_encode_baud_rate(termios, baud, baud);
+}
+EXPORT_SYMBOL(serial8250_do_set_termios);
+
+static void
+serial8250_set_termios(struct uart_port *port, struct ktermios *termios,
+                      struct ktermios *old)
+{
+       if (port->set_termios)
+               port->set_termios(port, termios, old);
+       else
+               serial8250_do_set_termios(port, termios, old);
+}
+
+static void
+serial8250_set_ldisc(struct uart_port *port, int new)
+{
+       if (new == N_PPS) {
+               port->flags |= UPF_HARDPPS_CD;
+               serial8250_enable_ms(port);
+       } else
+               port->flags &= ~UPF_HARDPPS_CD;
+}
+
+
+void serial8250_do_pm(struct uart_port *port, unsigned int state,
+                     unsigned int oldstate)
+{
+       struct uart_8250_port *p =
+               container_of(port, struct uart_8250_port, port);
+
+       serial8250_set_sleep(p, state != 0);
+}
+EXPORT_SYMBOL(serial8250_do_pm);
+
+static void
+serial8250_pm(struct uart_port *port, unsigned int state,
+             unsigned int oldstate)
+{
+       if (port->pm)
+               port->pm(port, state, oldstate);
+       else
+               serial8250_do_pm(port, state, oldstate);
+}
+
+static unsigned int serial8250_port_size(struct uart_8250_port *pt)
+{
+       if (pt->port.iotype == UPIO_AU)
+               return 0x1000;
+#ifdef CONFIG_ARCH_OMAP
+       if (is_omap_port(pt))
+               return 0x16 << pt->port.regshift;
+#endif
+       return 8 << pt->port.regshift;
+}
+
+/*
+ * Resource handling.
+ */
+static int serial8250_request_std_resource(struct uart_8250_port *up)
+{
+       unsigned int size = serial8250_port_size(up);
+       int ret = 0;
+
+       switch (up->port.iotype) {
+       case UPIO_AU:
+       case UPIO_TSI:
+       case UPIO_MEM32:
+       case UPIO_MEM:
+               if (!up->port.mapbase)
+                       break;
+
+               if (!request_mem_region(up->port.mapbase, size, "serial")) {
+                       ret = -EBUSY;
+                       break;
+               }
+
+               if (up->port.flags & UPF_IOREMAP) {
+                       up->port.membase = ioremap_nocache(up->port.mapbase,
+                                                                       size);
+                       if (!up->port.membase) {
+                               release_mem_region(up->port.mapbase, size);
+                               ret = -ENOMEM;
+                       }
+               }
+               break;
+
+       case UPIO_HUB6:
+       case UPIO_PORT:
+               if (!request_region(up->port.iobase, size, "serial"))
+                       ret = -EBUSY;
+               break;
+       }
+       return ret;
+}
+
+static void serial8250_release_std_resource(struct uart_8250_port *up)
+{
+       unsigned int size = serial8250_port_size(up);
+
+       switch (up->port.iotype) {
+       case UPIO_AU:
+       case UPIO_TSI:
+       case UPIO_MEM32:
+       case UPIO_MEM:
+               if (!up->port.mapbase)
+                       break;
+
+               if (up->port.flags & UPF_IOREMAP) {
+                       iounmap(up->port.membase);
+                       up->port.membase = NULL;
+               }
+
+               release_mem_region(up->port.mapbase, size);
+               break;
+
+       case UPIO_HUB6:
+       case UPIO_PORT:
+               release_region(up->port.iobase, size);
+               break;
+       }
+}
+
+static int serial8250_request_rsa_resource(struct uart_8250_port *up)
+{
+       unsigned long start = UART_RSA_BASE << up->port.regshift;
+       unsigned int size = 8 << up->port.regshift;
+       int ret = -EINVAL;
+
+       switch (up->port.iotype) {
+       case UPIO_HUB6:
+       case UPIO_PORT:
+               start += up->port.iobase;
+               if (request_region(start, size, "serial-rsa"))
+                       ret = 0;
+               else
+                       ret = -EBUSY;
+               break;
+       }
+
+       return ret;
+}
+
+static void serial8250_release_rsa_resource(struct uart_8250_port *up)
+{
+       unsigned long offset = UART_RSA_BASE << up->port.regshift;
+       unsigned int size = 8 << up->port.regshift;
+
+       switch (up->port.iotype) {
+       case UPIO_HUB6:
+       case UPIO_PORT:
+               release_region(up->port.iobase + offset, size);
+               break;
+       }
+}
+
+static void serial8250_release_port(struct uart_port *port)
+{
+       struct uart_8250_port *up =
+               container_of(port, struct uart_8250_port, port);
+
+       serial8250_release_std_resource(up);
+       if (up->port.type == PORT_RSA)
+               serial8250_release_rsa_resource(up);
+}
+
+static int serial8250_request_port(struct uart_port *port)
+{
+       struct uart_8250_port *up =
+               container_of(port, struct uart_8250_port, port);
+       int ret = 0;
+
+       ret = serial8250_request_std_resource(up);
+       if (ret == 0 && up->port.type == PORT_RSA) {
+               ret = serial8250_request_rsa_resource(up);
+               if (ret < 0)
+                       serial8250_release_std_resource(up);
+       }
+
+       return ret;
+}
+
+static void serial8250_config_port(struct uart_port *port, int flags)
+{
+       struct uart_8250_port *up =
+               container_of(port, struct uart_8250_port, port);
+       int probeflags = PROBE_ANY;
+       int ret;
+
+       /*
+        * Find the region that we can probe for.  This in turn
+        * tells us whether we can probe for the type of port.
+        */
+       ret = serial8250_request_std_resource(up);
+       if (ret < 0)
+               return;
+
+       ret = serial8250_request_rsa_resource(up);
+       if (ret < 0)
+               probeflags &= ~PROBE_RSA;
+
+       if (up->port.iotype != up->cur_iotype)
+               set_io_from_upio(port);
+
+       if (flags & UART_CONFIG_TYPE)
+               autoconfig(up, probeflags);
+
+       /* if access method is AU, it is a 16550 with a quirk */
+       if (up->port.type == PORT_16550A && up->port.iotype == UPIO_AU)
+               up->bugs |= UART_BUG_NOMSR;
+
+       if (up->port.type != PORT_UNKNOWN && flags & UART_CONFIG_IRQ)
+               autoconfig_irq(up);
+
+       if (up->port.type != PORT_RSA && probeflags & PROBE_RSA)
+               serial8250_release_rsa_resource(up);
+       if (up->port.type == PORT_UNKNOWN)
+               serial8250_release_std_resource(up);
+}
+
+static int
+serial8250_verify_port(struct uart_port *port, struct serial_struct *ser)
+{
+       if (ser->irq >= nr_irqs || ser->irq < 0 ||
+           ser->baud_base < 9600 || ser->type < PORT_UNKNOWN ||
+           ser->type >= ARRAY_SIZE(uart_config) || ser->type == PORT_CIRRUS ||
+           ser->type == PORT_STARTECH)
+               return -EINVAL;
+       return 0;
+}
+
+static const char *
+serial8250_type(struct uart_port *port)
+{
+       int type = port->type;
+
+       if (type >= ARRAY_SIZE(uart_config))
+               type = 0;
+       return uart_config[type].name;
+}
+
+static struct uart_ops serial8250_pops = {
+       .tx_empty       = serial8250_tx_empty,
+       .set_mctrl      = serial8250_set_mctrl,
+       .get_mctrl      = serial8250_get_mctrl,
+       .stop_tx        = serial8250_stop_tx,
+       .start_tx       = serial8250_start_tx,
+       .stop_rx        = serial8250_stop_rx,
+       .enable_ms      = serial8250_enable_ms,
+       .break_ctl      = serial8250_break_ctl,
+       .startup        = serial8250_startup,
+       .shutdown       = serial8250_shutdown,
+       .set_termios    = serial8250_set_termios,
+       .set_ldisc      = serial8250_set_ldisc,
+       .pm             = serial8250_pm,
+       .type           = serial8250_type,
+       .release_port   = serial8250_release_port,
+       .request_port   = serial8250_request_port,
+       .config_port    = serial8250_config_port,
+       .verify_port    = serial8250_verify_port,
+#ifdef CONFIG_CONSOLE_POLL
+       .poll_get_char = serial8250_get_poll_char,
+       .poll_put_char = serial8250_put_poll_char,
+#endif
+};
+
+static struct uart_8250_port serial8250_ports[UART_NR];
+
+static void (*serial8250_isa_config)(int port, struct uart_port *up,
+       unsigned short *capabilities);
+
+void serial8250_set_isa_configurator(
+       void (*v)(int port, struct uart_port *up, unsigned short *capabilities))
+{
+       serial8250_isa_config = v;
+}
+EXPORT_SYMBOL(serial8250_set_isa_configurator);
+
+static void __init serial8250_isa_init_ports(void)
+{
+       struct uart_8250_port *up;
+       static int first = 1;
+       int i, irqflag = 0;
+
+       if (!first)
+               return;
+       first = 0;
+
+       for (i = 0; i < nr_uarts; i++) {
+               struct uart_8250_port *up = &serial8250_ports[i];
+
+               up->port.line = i;
+               spin_lock_init(&up->port.lock);
+
+               init_timer(&up->timer);
+               up->timer.function = serial8250_timeout;
+
+               /*
+                * ALPHA_KLUDGE_MCR needs to be killed.
+                */
+               up->mcr_mask = ~ALPHA_KLUDGE_MCR;
+               up->mcr_force = ALPHA_KLUDGE_MCR;
+
+               up->port.ops = &serial8250_pops;
+       }
+
+       if (share_irqs)
+               irqflag = IRQF_SHARED;
+
+       for (i = 0, up = serial8250_ports;
+            i < ARRAY_SIZE(old_serial_port) && i < nr_uarts;
+            i++, up++) {
+               up->port.iobase   = old_serial_port[i].port;
+               up->port.irq      = irq_canonicalize(old_serial_port[i].irq);
+               up->port.irqflags = old_serial_port[i].irqflags;
+               up->port.uartclk  = old_serial_port[i].baud_base * 16;
+               up->port.flags    = old_serial_port[i].flags;
+               up->port.hub6     = old_serial_port[i].hub6;
+               up->port.membase  = old_serial_port[i].iomem_base;
+               up->port.iotype   = old_serial_port[i].io_type;
+               up->port.regshift = old_serial_port[i].iomem_reg_shift;
+               set_io_from_upio(&up->port);
+               up->port.irqflags |= irqflag;
+               if (serial8250_isa_config != NULL)
+                       serial8250_isa_config(i, &up->port, &up->capabilities);
+
+       }
+}
+
+static void
+serial8250_init_fixed_type_port(struct uart_8250_port *up, unsigned int type)
+{
+       up->port.type = type;
+       up->port.fifosize = uart_config[type].fifo_size;
+       up->capabilities = uart_config[type].flags;
+       up->tx_loadsz = uart_config[type].tx_loadsz;
+}
+
+static void __init
+serial8250_register_ports(struct uart_driver *drv, struct device *dev)
+{
+       int i;
+
+       for (i = 0; i < nr_uarts; i++) {
+               struct uart_8250_port *up = &serial8250_ports[i];
+               up->cur_iotype = 0xFF;
+       }
+
+       serial8250_isa_init_ports();
+
+       for (i = 0; i < nr_uarts; i++) {
+               struct uart_8250_port *up = &serial8250_ports[i];
+
+               up->port.dev = dev;
+
+               if (up->port.flags & UPF_FIXED_TYPE)
+                       serial8250_init_fixed_type_port(up, up->port.type);
+
+               uart_add_one_port(drv, &up->port);
+       }
+}
+
+#ifdef CONFIG_SERIAL_8250_CONSOLE
+
+static void serial8250_console_putchar(struct uart_port *port, int ch)
+{
+       struct uart_8250_port *up =
+               container_of(port, struct uart_8250_port, port);
+
+       wait_for_xmitr(up, UART_LSR_THRE);
+       serial_out(up, UART_TX, ch);
+}
+
+/*
+ *     Print a string to the serial port trying not to disturb
+ *     any possible real use of the port...
+ *
+ *     The console_lock must be held when we get here.
+ */
+static void
+serial8250_console_write(struct console *co, const char *s, unsigned int count)
+{
+       struct uart_8250_port *up = &serial8250_ports[co->index];
+       unsigned long flags;
+       unsigned int ier;
+       int locked = 1;
+
+       touch_nmi_watchdog();
+
+       local_irq_save(flags);
+       if (up->port.sysrq) {
+               /* serial8250_handle_irq() already took the lock */
+               locked = 0;
+       } else if (oops_in_progress) {
+               locked = spin_trylock(&up->port.lock);
+       } else
+               spin_lock(&up->port.lock);
+
+       /*
+        *      First save the IER then disable the interrupts
+        */
+       ier = serial_in(up, UART_IER);
+
+       if (up->capabilities & UART_CAP_UUE)
+               serial_out(up, UART_IER, UART_IER_UUE);
+       else
+               serial_out(up, UART_IER, 0);
+
+       uart_console_write(&up->port, s, count, serial8250_console_putchar);
+
+       /*
+        *      Finally, wait for transmitter to become empty
+        *      and restore the IER
+        */
+       wait_for_xmitr(up, BOTH_EMPTY);
+       serial_out(up, UART_IER, ier);
+
+       /*
+        *      The receive handling will happen properly because the
+        *      receive ready bit will still be set; it is not cleared
+        *      on read.  However, modem control will not, we must
+        *      call it if we have saved something in the saved flags
+        *      while processing with interrupts off.
+        */
+       if (up->msr_saved_flags)
+               serial8250_modem_status(up);
+
+       if (locked)
+               spin_unlock(&up->port.lock);
+       local_irq_restore(flags);
+}
+
+static int __init serial8250_console_setup(struct console *co, char *options)
+{
+       struct uart_port *port;
+       int baud = 9600;
+       int bits = 8;
+       int parity = 'n';
+       int flow = 'n';
+
+       /*
+        * 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 >= nr_uarts)
+               co->index = 0;
+       port = &serial8250_ports[co->index].port;
+       if (!port->iobase && !port->membase)
+               return -ENODEV;
+
+       if (options)
+               uart_parse_options(options, &baud, &parity, &bits, &flow);
+
+       return uart_set_options(port, co, baud, parity, bits, flow);
+}
+
+static int serial8250_console_early_setup(void)
+{
+       return serial8250_find_port_for_earlycon();
+}
+
+static struct console serial8250_console = {
+       .name           = "ttyS",
+       .write          = serial8250_console_write,
+       .device         = uart_console_device,
+       .setup          = serial8250_console_setup,
+       .early_setup    = serial8250_console_early_setup,
+       .flags          = CON_PRINTBUFFER | CON_ANYTIME,
+       .index          = -1,
+       .data           = &serial8250_reg,
+};
+
+static int __init serial8250_console_init(void)
+{
+       if (nr_uarts > UART_NR)
+               nr_uarts = UART_NR;
+
+       serial8250_isa_init_ports();
+       register_console(&serial8250_console);
+       return 0;
+}
+console_initcall(serial8250_console_init);
+
+int serial8250_find_port(struct uart_port *p)
+{
+       int line;
+       struct uart_port *port;
+
+       for (line = 0; line < nr_uarts; line++) {
+               port = &serial8250_ports[line].port;
+               if (uart_match_port(p, port))
+                       return line;
+       }
+       return -ENODEV;
+}
+
+#define SERIAL8250_CONSOLE     &serial8250_console
+#else
+#define SERIAL8250_CONSOLE     NULL
+#endif
+
+static struct uart_driver serial8250_reg = {
+       .owner                  = THIS_MODULE,
+       .driver_name            = "serial",
+       .dev_name               = "ttyS",
+       .major                  = TTY_MAJOR,
+       .minor                  = 64,
+       .cons                   = SERIAL8250_CONSOLE,
+};
+
+/*
+ * early_serial_setup - early registration for 8250 ports
+ *
+ * Setup an 8250 port structure prior to console initialisation.  Use
+ * after console initialisation will cause undefined behaviour.
+ */
+int __init early_serial_setup(struct uart_port *port)
+{
+       struct uart_port *p;
+
+       if (port->line >= ARRAY_SIZE(serial8250_ports))
+               return -ENODEV;
+
+       serial8250_isa_init_ports();
+       p = &serial8250_ports[port->line].port;
+       p->iobase       = port->iobase;
+       p->membase      = port->membase;
+       p->irq          = port->irq;
+       p->irqflags     = port->irqflags;
+       p->uartclk      = port->uartclk;
+       p->fifosize     = port->fifosize;
+       p->regshift     = port->regshift;
+       p->iotype       = port->iotype;
+       p->flags        = port->flags;
+       p->mapbase      = port->mapbase;
+       p->private_data = port->private_data;
+       p->type         = port->type;
+       p->line         = port->line;
+
+       set_io_from_upio(p);
+       if (port->serial_in)
+               p->serial_in = port->serial_in;
+       if (port->serial_out)
+               p->serial_out = port->serial_out;
+       if (port->handle_irq)
+               p->handle_irq = port->handle_irq;
+       else
+               p->handle_irq = serial8250_default_handle_irq;
+
+       return 0;
+}
+
+/**
+ *     serial8250_suspend_port - suspend one serial port
+ *     @line:  serial line number
+ *
+ *     Suspend one serial port.
+ */
+void serial8250_suspend_port(int line)
+{
+       uart_suspend_port(&serial8250_reg, &serial8250_ports[line].port);
+}
+
+/**
+ *     serial8250_resume_port - resume one serial port
+ *     @line:  serial line number
+ *
+ *     Resume one serial port.
+ */
+void serial8250_resume_port(int line)
+{
+       struct uart_8250_port *up = &serial8250_ports[line];
+
+       if (up->capabilities & UART_NATSEMI) {
+               /* Ensure it's still in high speed mode */
+               serial_outp(up, UART_LCR, 0xE0);
+
+               ns16550a_goto_highspeed(up);
+
+               serial_outp(up, UART_LCR, 0);
+               up->port.uartclk = 921600*16;
+       }
+       uart_resume_port(&serial8250_reg, &up->port);
+}
+
+/*
+ * Register a set of serial devices attached to a platform device.  The
+ * list is terminated with a zero flags entry, which means we expect
+ * all entries to have at least UPF_BOOT_AUTOCONF set.
+ */
+static int __devinit serial8250_probe(struct platform_device *dev)
+{
+       struct plat_serial8250_port *p = dev->dev.platform_data;
+       struct uart_port port;
+       int ret, i, irqflag = 0;
+
+       memset(&port, 0, sizeof(struct uart_port));
+
+       if (share_irqs)
+               irqflag = IRQF_SHARED;
+
+       for (i = 0; p && p->flags != 0; p++, i++) {
+               port.iobase             = p->iobase;
+               port.membase            = p->membase;
+               port.irq                = p->irq;
+               port.irqflags           = p->irqflags;
+               port.uartclk            = p->uartclk;
+               port.regshift           = p->regshift;
+               port.iotype             = p->iotype;
+               port.flags              = p->flags;
+               port.mapbase            = p->mapbase;
+               port.hub6               = p->hub6;
+               port.private_data       = p->private_data;
+               port.type               = p->type;
+               port.serial_in          = p->serial_in;
+               port.serial_out         = p->serial_out;
+               port.handle_irq         = p->handle_irq;
+               port.set_termios        = p->set_termios;
+               port.pm                 = p->pm;
+               port.dev                = &dev->dev;
+               port.irqflags           |= irqflag;
+               ret = serial8250_register_port(&port);
+               if (ret < 0) {
+                       dev_err(&dev->dev, "unable to register port at index %d "
+                               "(IO%lx MEM%llx IRQ%d): %d\n", i,
+                               p->iobase, (unsigned long long)p->mapbase,
+                               p->irq, ret);
+               }
+       }
+       return 0;
+}
+
+/*
+ * Remove serial ports registered against a platform device.
+ */
+static int __devexit serial8250_remove(struct platform_device *dev)
+{
+       int i;
+
+       for (i = 0; i < nr_uarts; i++) {
+               struct uart_8250_port *up = &serial8250_ports[i];
+
+               if (up->port.dev == &dev->dev)
+                       serial8250_unregister_port(i);
+       }
+       return 0;
+}
+
+static int serial8250_suspend(struct platform_device *dev, pm_message_t state)
+{
+       int i;
+
+       for (i = 0; i < UART_NR; i++) {
+               struct uart_8250_port *up = &serial8250_ports[i];
+
+               if (up->port.type != PORT_UNKNOWN && up->port.dev == &dev->dev)
+                       uart_suspend_port(&serial8250_reg, &up->port);
+       }
+
+       return 0;
+}
+
+static int serial8250_resume(struct platform_device *dev)
+{
+       int i;
+
+       for (i = 0; i < UART_NR; i++) {
+               struct uart_8250_port *up = &serial8250_ports[i];
+
+               if (up->port.type != PORT_UNKNOWN && up->port.dev == &dev->dev)
+                       serial8250_resume_port(i);
+       }
+
+       return 0;
+}
+
+static struct platform_driver serial8250_isa_driver = {
+       .probe          = serial8250_probe,
+       .remove         = __devexit_p(serial8250_remove),
+       .suspend        = serial8250_suspend,
+       .resume         = serial8250_resume,
+       .driver         = {
+               .name   = "serial8250",
+               .owner  = THIS_MODULE,
+       },
+};
+
+/*
+ * This "device" covers _all_ ISA 8250-compatible serial devices listed
+ * in the table in include/asm/serial.h
+ */
+static struct platform_device *serial8250_isa_devs;
+
+/*
+ * serial8250_register_port and serial8250_unregister_port allows for
+ * 16x50 serial ports to be configured at run-time, to support PCMCIA
+ * modems and PCI multiport cards.
+ */
+static DEFINE_MUTEX(serial_mutex);
+
+static struct uart_8250_port *serial8250_find_match_or_unused(struct uart_port *port)
+{
+       int i;
+
+       /*
+        * First, find a port entry which matches.
+        */
+       for (i = 0; i < nr_uarts; i++)
+               if (uart_match_port(&serial8250_ports[i].port, port))
+                       return &serial8250_ports[i];
+
+       /*
+        * We didn't find a matching entry, so look for the first
+        * free entry.  We look for one which hasn't been previously
+        * used (indicated by zero iobase).
+        */
+       for (i = 0; i < nr_uarts; i++)
+               if (serial8250_ports[i].port.type == PORT_UNKNOWN &&
+                   serial8250_ports[i].port.iobase == 0)
+                       return &serial8250_ports[i];
+
+       /*
+        * That also failed.  Last resort is to find any entry which
+        * doesn't have a real port associated with it.
+        */
+       for (i = 0; i < nr_uarts; i++)
+               if (serial8250_ports[i].port.type == PORT_UNKNOWN)
+                       return &serial8250_ports[i];
+
+       return NULL;
+}
+
+/**
+ *     serial8250_register_port - register a serial port
+ *     @port: serial port template
+ *
+ *     Configure the serial port specified by the request. If the
+ *     port exists and is in use, it is hung up and unregistered
+ *     first.
+ *
+ *     The port is then probed and if necessary the IRQ is autodetected
+ *     If this fails an error is returned.
+ *
+ *     On success the port is ready to use and the line number is returned.
+ */
+int serial8250_register_port(struct uart_port *port)
+{
+       struct uart_8250_port *uart;
+       int ret = -ENOSPC;
+
+       if (port->uartclk == 0)
+               return -EINVAL;
+
+       mutex_lock(&serial_mutex);
+
+       uart = serial8250_find_match_or_unused(port);
+       if (uart) {
+               uart_remove_one_port(&serial8250_reg, &uart->port);
+
+               uart->port.iobase       = port->iobase;
+               uart->port.membase      = port->membase;
+               uart->port.irq          = port->irq;
+               uart->port.irqflags     = port->irqflags;
+               uart->port.uartclk      = port->uartclk;
+               uart->port.fifosize     = port->fifosize;
+               uart->port.regshift     = port->regshift;
+               uart->port.iotype       = port->iotype;
+               uart->port.flags        = port->flags | UPF_BOOT_AUTOCONF;
+               uart->port.mapbase      = port->mapbase;
+               uart->port.private_data = port->private_data;
+               if (port->dev)
+                       uart->port.dev = port->dev;
+
+               if (port->flags & UPF_FIXED_TYPE)
+                       serial8250_init_fixed_type_port(uart, port->type);
+
+               set_io_from_upio(&uart->port);
+               /* Possibly override default I/O functions.  */
+               if (port->serial_in)
+                       uart->port.serial_in = port->serial_in;
+               if (port->serial_out)
+                       uart->port.serial_out = port->serial_out;
+               if (port->handle_irq)
+                       uart->port.handle_irq = port->handle_irq;
+               /*  Possibly override set_termios call */
+               if (port->set_termios)
+                       uart->port.set_termios = port->set_termios;
+               if (port->pm)
+                       uart->port.pm = port->pm;
+
+               if (serial8250_isa_config != NULL)
+                       serial8250_isa_config(0, &uart->port,
+                                       &uart->capabilities);
+
+               ret = uart_add_one_port(&serial8250_reg, &uart->port);
+               if (ret == 0)
+                       ret = uart->port.line;
+       }
+       mutex_unlock(&serial_mutex);
+
+       return ret;
+}
+EXPORT_SYMBOL(serial8250_register_port);
+
+/**
+ *     serial8250_unregister_port - remove a 16x50 serial port at runtime
+ *     @line: serial line number
+ *
+ *     Remove one serial port.  This may not be called from interrupt
+ *     context.  We hand the port back to the our control.
+ */
+void serial8250_unregister_port(int line)
+{
+       struct uart_8250_port *uart = &serial8250_ports[line];
+
+       mutex_lock(&serial_mutex);
+       uart_remove_one_port(&serial8250_reg, &uart->port);
+       if (serial8250_isa_devs) {
+               uart->port.flags &= ~UPF_BOOT_AUTOCONF;
+               uart->port.type = PORT_UNKNOWN;
+               uart->port.dev = &serial8250_isa_devs->dev;
+               uart->capabilities = uart_config[uart->port.type].flags;
+               uart_add_one_port(&serial8250_reg, &uart->port);
+       } else {
+               uart->port.dev = NULL;
+       }
+       mutex_unlock(&serial_mutex);
+}
+EXPORT_SYMBOL(serial8250_unregister_port);
+
+static int __init serial8250_init(void)
+{
+       int ret;
+
+       if (nr_uarts > UART_NR)
+               nr_uarts = UART_NR;
+
+       printk(KERN_INFO "Serial: 8250/16550 driver, "
+               "%d ports, IRQ sharing %sabled\n", nr_uarts,
+               share_irqs ? "en" : "dis");
+
+#ifdef CONFIG_SPARC
+       ret = sunserial_register_minors(&serial8250_reg, UART_NR);
+#else
+       serial8250_reg.nr = UART_NR;
+       ret = uart_register_driver(&serial8250_reg);
+#endif
+       if (ret)
+               goto out;
+
+       serial8250_isa_devs = platform_device_alloc("serial8250",
+                                                   PLAT8250_DEV_LEGACY);
+       if (!serial8250_isa_devs) {
+               ret = -ENOMEM;
+               goto unreg_uart_drv;
+       }
+
+       ret = platform_device_add(serial8250_isa_devs);
+       if (ret)
+               goto put_dev;
+
+       serial8250_register_ports(&serial8250_reg, &serial8250_isa_devs->dev);
+
+       ret = platform_driver_register(&serial8250_isa_driver);
+       if (ret == 0)
+               goto out;
+
+       platform_device_del(serial8250_isa_devs);
+put_dev:
+       platform_device_put(serial8250_isa_devs);
+unreg_uart_drv:
+#ifdef CONFIG_SPARC
+       sunserial_unregister_minors(&serial8250_reg, UART_NR);
+#else
+       uart_unregister_driver(&serial8250_reg);
+#endif
+out:
+       return ret;
+}
+
+static void __exit serial8250_exit(void)
+{
+       struct platform_device *isa_dev = serial8250_isa_devs;
+
+       /*
+        * This tells serial8250_unregister_port() not to re-register
+        * the ports (thereby making serial8250_isa_driver permanently
+        * in use.)
+        */
+       serial8250_isa_devs = NULL;
+
+       platform_driver_unregister(&serial8250_isa_driver);
+       platform_device_unregister(isa_dev);
+
+#ifdef CONFIG_SPARC
+       sunserial_unregister_minors(&serial8250_reg, UART_NR);
+#else
+       uart_unregister_driver(&serial8250_reg);
+#endif
+}
+
+module_init(serial8250_init);
+module_exit(serial8250_exit);
+
+EXPORT_SYMBOL(serial8250_suspend_port);
+EXPORT_SYMBOL(serial8250_resume_port);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Generic 8250/16x50 serial driver");
+
+module_param(share_irqs, uint, 0644);
+MODULE_PARM_DESC(share_irqs, "Share IRQs with other non-8250/16x50 devices"
+       " (unsafe)");
+
+module_param(nr_uarts, uint, 0644);
+MODULE_PARM_DESC(nr_uarts, "Maximum number of UARTs supported. (1-" __MODULE_STRING(CONFIG_SERIAL_8250_NR_UARTS) ")");
+
+module_param(skip_txen_test, uint, 0644);
+MODULE_PARM_DESC(skip_txen_test, "Skip checking for the TXEN bug at init time");
+
+#ifdef CONFIG_SERIAL_8250_RSA
+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);
diff --git a/drivers/tty/serial/8250/8250.h b/drivers/tty/serial/8250/8250.h
new file mode 100644 (file)
index 0000000..ae027be
--- /dev/null
@@ -0,0 +1,105 @@
+/*
+ *  Driver for 8250/16550-type serial ports
+ *
+ *  Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o.
+ *
+ *  Copyright (C) 2001 Russell King.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/serial_8250.h>
+
+struct uart_8250_port {
+       struct uart_port        port;
+       struct timer_list       timer;          /* "no irq" timer */
+       struct list_head        list;           /* ports on this IRQ */
+       unsigned short          capabilities;   /* port capabilities */
+       unsigned short          bugs;           /* port bugs */
+       unsigned int            tx_loadsz;      /* transmit fifo load size */
+       unsigned char           acr;
+       unsigned char           ier;
+       unsigned char           lcr;
+       unsigned char           mcr;
+       unsigned char           mcr_mask;       /* mask of user bits */
+       unsigned char           mcr_force;      /* mask of forced bits */
+       unsigned char           cur_iotype;     /* Running I/O type */
+
+       /*
+        * Some bits in registers are cleared on a read, so they must
+        * be saved whenever the register is read but the bits will not
+        * be immediately processed.
+        */
+#define LSR_SAVE_FLAGS UART_LSR_BRK_ERROR_BITS
+       unsigned char           lsr_saved_flags;
+#define MSR_SAVE_FLAGS UART_MSR_ANY_DELTA
+       unsigned char           msr_saved_flags;
+};
+
+struct old_serial_port {
+       unsigned int uart;
+       unsigned int baud_base;
+       unsigned int port;
+       unsigned int irq;
+       unsigned int flags;
+       unsigned char hub6;
+       unsigned char io_type;
+       unsigned char *iomem_base;
+       unsigned short iomem_reg_shift;
+       unsigned long irqflags;
+};
+
+/*
+ * This replaces serial_uart_config in include/linux/serial.h
+ */
+struct serial8250_config {
+       const char      *name;
+       unsigned short  fifo_size;
+       unsigned short  tx_loadsz;
+       unsigned char   fcr;
+       unsigned int    flags;
+};
+
+#define UART_CAP_FIFO  (1 << 8)        /* UART has FIFO */
+#define UART_CAP_EFR   (1 << 9)        /* UART has EFR */
+#define UART_CAP_SLEEP (1 << 10)       /* UART has IER sleep */
+#define UART_CAP_AFE   (1 << 11)       /* MCR-based hw flow control */
+#define UART_CAP_UUE   (1 << 12)       /* UART needs IER bit 6 set (Xscale) */
+#define UART_CAP_RTOIE (1 << 13)       /* UART needs IER bit 4 set (Xscale, Tegra) */
+
+#define UART_BUG_QUOT  (1 << 0)        /* UART has buggy quot LSB */
+#define UART_BUG_TXEN  (1 << 1)        /* UART has buggy TX IIR status */
+#define UART_BUG_NOMSR (1 << 2)        /* UART has buggy MSR status bits (Au1x00) */
+#define UART_BUG_THRE  (1 << 3)        /* UART has buggy THRE reassertion */
+
+#define PROBE_RSA      (1 << 0)
+#define PROBE_ANY      (~0)
+
+#define HIGH_BITS_OFFSET ((sizeof(long)-sizeof(int))*8)
+
+#ifdef CONFIG_SERIAL_8250_SHARE_IRQ
+#define SERIAL8250_SHARE_IRQS 1
+#else
+#define SERIAL8250_SHARE_IRQS 0
+#endif
+
+#if defined(__alpha__) && !defined(CONFIG_PCI)
+/*
+ * Digital did something really horribly wrong with the OUT1 and OUT2
+ * lines on at least some ALPHA's.  The failure mode is that if either
+ * is cleared, the machine locks up with endless interrupts.
+ */
+#define ALPHA_KLUDGE_MCR  (UART_MCR_OUT2 | UART_MCR_OUT1)
+#elif defined(CONFIG_SBC8560)
+/*
+ * WindRiver did something similarly broken on their SBC8560 board. The
+ * UART tristates its IRQ output while OUT2 is clear, but they pulled
+ * the interrupt line _up_ instead of down, so if we register the IRQ
+ * while the UART is in that state, we die in an IRQ storm. */
+#define ALPHA_KLUDGE_MCR (UART_MCR_OUT2)
+#else
+#define ALPHA_KLUDGE_MCR 0
+#endif
diff --git a/drivers/tty/serial/8250/8250_accent.c b/drivers/tty/serial/8250/8250_accent.c
new file mode 100644 (file)
index 0000000..34b51c6
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ *  Copyright (C) 2005 Russell King.
+ *  Data taken from include/asm-i386/serial.h
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/serial_8250.h>
+
+#define PORT(_base,_irq)                               \
+       {                                               \
+               .iobase         = _base,                \
+               .irq            = _irq,                 \
+               .uartclk        = 1843200,              \
+               .iotype         = UPIO_PORT,            \
+               .flags          = UPF_BOOT_AUTOCONF,    \
+       }
+
+static struct plat_serial8250_port accent_data[] = {
+       PORT(0x330, 4),
+       PORT(0x338, 4),
+       { },
+};
+
+static struct platform_device accent_device = {
+       .name                   = "serial8250",
+       .id                     = PLAT8250_DEV_ACCENT,
+       .dev                    = {
+               .platform_data  = accent_data,
+       },
+};
+
+static int __init accent_init(void)
+{
+       return platform_device_register(&accent_device);
+}
+
+module_init(accent_init);
+
+MODULE_AUTHOR("Russell King");
+MODULE_DESCRIPTION("8250 serial probe module for Accent Async cards");
+MODULE_LICENSE("GPL");
diff --git a/drivers/tty/serial/8250/8250_acorn.c b/drivers/tty/serial/8250/8250_acorn.c
new file mode 100644 (file)
index 0000000..b0ce8c5
--- /dev/null
@@ -0,0 +1,141 @@
+/*
+ *  linux/drivers/serial/acorn.c
+ *
+ *  Copyright (C) 1996-2003 Russell King.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/tty.h>
+#include <linux/serial_core.h>
+#include <linux/errno.h>
+#include <linux/ioport.h>
+#include <linux/slab.h>
+#include <linux/device.h>
+#include <linux/init.h>
+
+#include <asm/io.h>
+#include <asm/ecard.h>
+#include <asm/string.h>
+
+#include "8250.h"
+
+#define MAX_PORTS      3
+
+struct serial_card_type {
+       unsigned int    num_ports;
+       unsigned int    uartclk;
+       unsigned int    type;
+       unsigned int    offset[MAX_PORTS];
+};
+
+struct serial_card_info {
+       unsigned int    num_ports;
+       int             ports[MAX_PORTS];
+       void __iomem *vaddr;
+};
+
+static int __devinit
+serial_card_probe(struct expansion_card *ec, const struct ecard_id *id)
+{
+       struct serial_card_info *info;
+       struct serial_card_type *type = id->data;
+       struct uart_port port;
+       unsigned long bus_addr;
+       unsigned int i;
+
+       info = kzalloc(sizeof(struct serial_card_info), GFP_KERNEL);
+       if (!info)
+               return -ENOMEM;
+
+       info->num_ports = type->num_ports;
+
+       bus_addr = ecard_resource_start(ec, type->type);
+       info->vaddr = ecardm_iomap(ec, type->type, 0, 0);
+       if (!info->vaddr) {
+               kfree(info);
+               return -ENOMEM;
+       }
+
+       ecard_set_drvdata(ec, info);
+
+       memset(&port, 0, sizeof(struct uart_port));
+       port.irq        = ec->irq;
+       port.flags      = UPF_BOOT_AUTOCONF | UPF_SHARE_IRQ;
+       port.uartclk    = type->uartclk;
+       port.iotype     = UPIO_MEM;
+       port.regshift   = 2;
+       port.dev        = &ec->dev;
+
+       for (i = 0; i < info->num_ports; i ++) {
+               port.membase = info->vaddr + type->offset[i];
+               port.mapbase = bus_addr + type->offset[i];
+
+               info->ports[i] = serial8250_register_port(&port);
+       }
+
+       return 0;
+}
+
+static void __devexit serial_card_remove(struct expansion_card *ec)
+{
+       struct serial_card_info *info = ecard_get_drvdata(ec);
+       int i;
+
+       ecard_set_drvdata(ec, NULL);
+
+       for (i = 0; i < info->num_ports; i++)
+               if (info->ports[i] > 0)
+                       serial8250_unregister_port(info->ports[i]);
+
+       kfree(info);
+}
+
+static struct serial_card_type atomwide_type = {
+       .num_ports      = 3,
+       .uartclk        = 7372800,
+       .type           = ECARD_RES_IOCSLOW,
+       .offset         = { 0x2800, 0x2400, 0x2000 },
+};
+
+static struct serial_card_type serport_type = {
+       .num_ports      = 2,
+       .uartclk        = 3686400,
+       .type           = ECARD_RES_IOCSLOW,
+       .offset         = { 0x2000, 0x2020 },
+};
+
+static const struct ecard_id serial_cids[] = {
+       { MANU_ATOMWIDE,        PROD_ATOMWIDE_3PSERIAL, &atomwide_type  },
+       { MANU_SERPORT,         PROD_SERPORT_DSPORT,    &serport_type   },
+       { 0xffff, 0xffff }
+};
+
+static struct ecard_driver serial_card_driver = {
+       .probe          = serial_card_probe,
+       .remove         = __devexit_p(serial_card_remove),
+       .id_table       = serial_cids,
+       .drv = {
+               .name   = "8250_acorn",
+       },
+};
+
+static int __init serial_card_init(void)
+{
+       return ecard_register_driver(&serial_card_driver);
+}
+
+static void __exit serial_card_exit(void)
+{
+       ecard_remove_driver(&serial_card_driver);
+}
+
+MODULE_AUTHOR("Russell King");
+MODULE_DESCRIPTION("Acorn 8250-compatible serial port expansion card driver");
+MODULE_LICENSE("GPL");
+
+module_init(serial_card_init);
+module_exit(serial_card_exit);
diff --git a/drivers/tty/serial/8250/8250_boca.c b/drivers/tty/serial/8250/8250_boca.c
new file mode 100644 (file)
index 0000000..d125dc1
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ *  Copyright (C) 2005 Russell King.
+ *  Data taken from include/asm-i386/serial.h
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/serial_8250.h>
+
+#define PORT(_base,_irq)                               \
+       {                                               \
+               .iobase         = _base,                \
+               .irq            = _irq,                 \
+               .uartclk        = 1843200,              \
+               .iotype         = UPIO_PORT,            \
+               .flags          = UPF_BOOT_AUTOCONF,    \
+       }
+
+static struct plat_serial8250_port boca_data[] = {
+       PORT(0x100, 12),
+       PORT(0x108, 12),
+       PORT(0x110, 12),
+       PORT(0x118, 12),
+       PORT(0x120, 12),
+       PORT(0x128, 12),
+       PORT(0x130, 12),
+       PORT(0x138, 12),
+       PORT(0x140, 12),
+       PORT(0x148, 12),
+       PORT(0x150, 12),
+       PORT(0x158, 12),
+       PORT(0x160, 12),
+       PORT(0x168, 12),
+       PORT(0x170, 12),
+       PORT(0x178, 12),
+       { },
+};
+
+static struct platform_device boca_device = {
+       .name                   = "serial8250",
+       .id                     = PLAT8250_DEV_BOCA,
+       .dev                    = {
+               .platform_data  = boca_data,
+       },
+};
+
+static int __init boca_init(void)
+{
+       return platform_device_register(&boca_device);
+}
+
+module_init(boca_init);
+
+MODULE_AUTHOR("Russell King");
+MODULE_DESCRIPTION("8250 serial probe module for Boca cards");
+MODULE_LICENSE("GPL");
diff --git a/drivers/tty/serial/8250/8250_dw.c b/drivers/tty/serial/8250/8250_dw.c
new file mode 100644 (file)
index 0000000..f574eef
--- /dev/null
@@ -0,0 +1,184 @@
+/*
+ * Synopsys DesignWare 8250 driver.
+ *
+ * Copyright 2011 Picochip, Jamie Iles.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * The Synopsys DesignWare 8250 has an extra feature whereby it detects if the
+ * LCR is written whilst busy.  If it is, then a busy detect interrupt is
+ * raised, the LCR needs to be rewritten and the uart status register read.
+ */
+#include <linux/device.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/serial_8250.h>
+#include <linux/serial_core.h>
+#include <linux/serial_reg.h>
+#include <linux/of.h>
+#include <linux/of_irq.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+struct dw8250_data {
+       int     last_lcr;
+       int     line;
+};
+
+static void dw8250_serial_out(struct uart_port *p, int offset, int value)
+{
+       struct dw8250_data *d = p->private_data;
+
+       if (offset == UART_LCR)
+               d->last_lcr = value;
+
+       offset <<= p->regshift;
+       writeb(value, p->membase + offset);
+}
+
+static unsigned int dw8250_serial_in(struct uart_port *p, int offset)
+{
+       offset <<= p->regshift;
+
+       return readb(p->membase + offset);
+}
+
+static void dw8250_serial_out32(struct uart_port *p, int offset, int value)
+{
+       struct dw8250_data *d = p->private_data;
+
+       if (offset == UART_LCR)
+               d->last_lcr = value;
+
+       offset <<= p->regshift;
+       writel(value, p->membase + offset);
+}
+
+static unsigned int dw8250_serial_in32(struct uart_port *p, int offset)
+{
+       offset <<= p->regshift;
+
+       return readl(p->membase + offset);
+}
+
+/* Offset for the DesignWare's UART Status Register. */
+#define UART_USR       0x1f
+
+static int dw8250_handle_irq(struct uart_port *p)
+{
+       struct dw8250_data *d = p->private_data;
+       unsigned int iir = p->serial_in(p, UART_IIR);
+
+       if (serial8250_handle_irq(p, iir)) {
+               return 1;
+       } else if ((iir & UART_IIR_BUSY) == UART_IIR_BUSY) {
+               /* Clear the USR and write the LCR again. */
+               (void)p->serial_in(p, UART_USR);
+               p->serial_out(p, d->last_lcr, UART_LCR);
+
+               return 1;
+       }
+
+       return 0;
+}
+
+static int __devinit dw8250_probe(struct platform_device *pdev)
+{
+       struct uart_port port = {};
+       struct resource *regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       struct resource *irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+       struct device_node *np = pdev->dev.of_node;
+       u32 val;
+       struct dw8250_data *data;
+
+       if (!regs || !irq) {
+               dev_err(&pdev->dev, "no registers/irq defined\n");
+               return -EINVAL;
+       }
+
+       data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
+       if (!data)
+               return -ENOMEM;
+       port.private_data = data;
+
+       spin_lock_init(&port.lock);
+       port.mapbase = regs->start;
+       port.irq = irq->start;
+       port.handle_irq = dw8250_handle_irq;
+       port.type = PORT_8250;
+       port.flags = UPF_SHARE_IRQ | UPF_BOOT_AUTOCONF | UPF_IOREMAP |
+               UPF_FIXED_PORT | UPF_FIXED_TYPE;
+       port.dev = &pdev->dev;
+
+       port.iotype = UPIO_MEM;
+       port.serial_in = dw8250_serial_in;
+       port.serial_out = dw8250_serial_out;
+       if (!of_property_read_u32(np, "reg-io-width", &val)) {
+               switch (val) {
+               case 1:
+                       break;
+               case 4:
+                       port.iotype = UPIO_MEM32;
+                       port.serial_in = dw8250_serial_in32;
+                       port.serial_out = dw8250_serial_out32;
+                       break;
+               default:
+                       dev_err(&pdev->dev, "unsupported reg-io-width (%u)\n",
+                               val);
+                       return -EINVAL;
+               }
+       }
+
+       if (!of_property_read_u32(np, "reg-shift", &val))
+               port.regshift = val;
+
+       if (of_property_read_u32(np, "clock-frequency", &val)) {
+               dev_err(&pdev->dev, "no clock-frequency property set\n");
+               return -EINVAL;
+       }
+       port.uartclk = val;
+
+       data->line = serial8250_register_port(&port);
+       if (data->line < 0)
+               return data->line;
+
+       platform_set_drvdata(pdev, data);
+
+       return 0;
+}
+
+static int __devexit dw8250_remove(struct platform_device *pdev)
+{
+       struct dw8250_data *data = platform_get_drvdata(pdev);
+
+       serial8250_unregister_port(data->line);
+
+       return 0;
+}
+
+static const struct of_device_id dw8250_match[] = {
+       { .compatible = "snps,dw-apb-uart" },
+       { /* Sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, dw8250_match);
+
+static struct platform_driver dw8250_platform_driver = {
+       .driver = {
+               .name           = "dw-apb-uart",
+               .owner          = THIS_MODULE,
+               .of_match_table = dw8250_match,
+       },
+       .probe                  = dw8250_probe,
+       .remove                 = __devexit_p(dw8250_remove),
+};
+
+module_platform_driver(dw8250_platform_driver);
+
+MODULE_AUTHOR("Jamie Iles");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Synopsys DesignWare 8250 serial port driver");
diff --git a/drivers/tty/serial/8250/8250_early.c b/drivers/tty/serial/8250/8250_early.c
new file mode 100644 (file)
index 0000000..eaafb98
--- /dev/null
@@ -0,0 +1,287 @@
+/*
+ * Early serial console for 8250/16550 devices
+ *
+ * (c) Copyright 2004 Hewlett-Packard Development Company, L.P.
+ *     Bjorn Helgaas <bjorn.helgaas@hp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Based on the 8250.c serial driver, Copyright (C) 2001 Russell King,
+ * and on early_printk.c by Andi Kleen.
+ *
+ * This is for use before the serial driver has initialized, in
+ * particular, before the UARTs have been discovered and named.
+ * Instead of specifying the console device as, e.g., "ttyS0",
+ * we locate the device directly by its MMIO or I/O port address.
+ *
+ * The user can specify the device directly, e.g.,
+ *     earlycon=uart8250,io,0x3f8,9600n8
+ *     earlycon=uart8250,mmio,0xff5e0000,115200n8
+ *     earlycon=uart8250,mmio32,0xff5e0000,115200n8
+ * or
+ *     console=uart8250,io,0x3f8,9600n8
+ *     console=uart8250,mmio,0xff5e0000,115200n8
+ *     console=uart8250,mmio32,0xff5e0000,115200n8
+ */
+
+#include <linux/tty.h>
+#include <linux/init.h>
+#include <linux/console.h>
+#include <linux/serial_core.h>
+#include <linux/serial_reg.h>
+#include <linux/serial.h>
+#include <linux/serial_8250.h>
+#include <asm/io.h>
+#include <asm/serial.h>
+#ifdef CONFIG_FIX_EARLYCON_MEM
+#include <asm/pgtable.h>
+#include <asm/fixmap.h>
+#endif
+
+struct early_serial8250_device {
+       struct uart_port port;
+       char options[16];               /* e.g., 115200n8 */
+       unsigned int baud;
+};
+
+static struct early_serial8250_device early_device;
+
+static unsigned int __init serial_in(struct uart_port *port, int offset)
+{
+       switch (port->iotype) {
+       case UPIO_MEM:
+               return readb(port->membase + offset);
+       case UPIO_MEM32:
+               return readl(port->membase + (offset << 2));
+       case UPIO_PORT:
+               return inb(port->iobase + offset);
+       default:
+               return 0;
+       }
+}
+
+static void __init serial_out(struct uart_port *port, int offset, int value)
+{
+       switch (port->iotype) {
+       case UPIO_MEM:
+               writeb(value, port->membase + offset);
+               break;
+       case UPIO_MEM32:
+               writel(value, port->membase + (offset << 2));
+               break;
+       case UPIO_PORT:
+               outb(value, port->iobase + offset);
+               break;
+       }
+}
+
+#define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE)
+
+static void __init wait_for_xmitr(struct uart_port *port)
+{
+       unsigned int status;
+
+       for (;;) {
+               status = serial_in(port, UART_LSR);
+               if ((status & BOTH_EMPTY) == BOTH_EMPTY)
+                       return;
+               cpu_relax();
+       }
+}
+
+static void __init serial_putc(struct uart_port *port, int c)
+{
+       wait_for_xmitr(port);
+       serial_out(port, UART_TX, c);
+}
+
+static void __init early_serial8250_write(struct console *console,
+                                       const char *s, unsigned int count)
+{
+       struct uart_port *port = &early_device.port;
+       unsigned int ier;
+
+       /* Save the IER and disable interrupts */
+       ier = serial_in(port, UART_IER);
+       serial_out(port, UART_IER, 0);
+
+       uart_console_write(port, s, count, serial_putc);
+
+       /* Wait for transmitter to become empty and restore the IER */
+       wait_for_xmitr(port);
+       serial_out(port, UART_IER, ier);
+}
+
+static unsigned int __init probe_baud(struct uart_port *port)
+{
+       unsigned char lcr, dll, dlm;
+       unsigned int quot;
+
+       lcr = serial_in(port, UART_LCR);
+       serial_out(port, UART_LCR, lcr | UART_LCR_DLAB);
+       dll = serial_in(port, UART_DLL);
+       dlm = serial_in(port, UART_DLM);
+       serial_out(port, UART_LCR, lcr);
+
+       quot = (dlm << 8) | dll;
+       return (port->uartclk / 16) / quot;
+}
+
+static void __init init_port(struct early_serial8250_device *device)
+{
+       struct uart_port *port = &device->port;
+       unsigned int divisor;
+       unsigned char c;
+
+       serial_out(port, UART_LCR, 0x3);        /* 8n1 */
+       serial_out(port, UART_IER, 0);          /* no interrupt */
+       serial_out(port, UART_FCR, 0);          /* no fifo */
+       serial_out(port, UART_MCR, 0x3);        /* DTR + RTS */
+
+       divisor = port->uartclk / (16 * device->baud);
+       c = serial_in(port, UART_LCR);
+       serial_out(port, UART_LCR, c | UART_LCR_DLAB);
+       serial_out(port, UART_DLL, divisor & 0xff);
+       serial_out(port, UART_DLM, (divisor >> 8) & 0xff);
+       serial_out(port, UART_LCR, c & ~UART_LCR_DLAB);
+}
+
+static int __init parse_options(struct early_serial8250_device *device,
+                                                               char *options)
+{
+       struct uart_port *port = &device->port;
+       int mmio, mmio32, length;
+
+       if (!options)
+               return -ENODEV;
+
+       port->uartclk = BASE_BAUD * 16;
+
+       mmio = !strncmp(options, "mmio,", 5);
+       mmio32 = !strncmp(options, "mmio32,", 7);
+       if (mmio || mmio32) {
+               port->iotype = (mmio ? UPIO_MEM : UPIO_MEM32);
+               port->mapbase = simple_strtoul(options + (mmio ? 5 : 7),
+                                              &options, 0);
+               if (mmio32)
+                       port->regshift = 2;
+#ifdef CONFIG_FIX_EARLYCON_MEM
+               set_fixmap_nocache(FIX_EARLYCON_MEM_BASE,
+                                       port->mapbase & PAGE_MASK);
+               port->membase =
+                       (void __iomem *)__fix_to_virt(FIX_EARLYCON_MEM_BASE);
+               port->membase += port->mapbase & ~PAGE_MASK;
+#else
+               port->membase = ioremap_nocache(port->mapbase, 64);
+               if (!port->membase) {
+                       printk(KERN_ERR "%s: Couldn't ioremap 0x%llx\n",
+                               __func__,
+                              (unsigned long long) port->mapbase);
+                       return -ENOMEM;
+               }
+#endif
+       } else if (!strncmp(options, "io,", 3)) {
+               port->iotype = UPIO_PORT;
+               port->iobase = simple_strtoul(options + 3, &options, 0);
+               mmio = 0;
+       } else
+               return -EINVAL;
+
+       options = strchr(options, ',');
+       if (options) {
+               options++;
+               device->baud = simple_strtoul(options, NULL, 0);
+               length = min(strcspn(options, " "), sizeof(device->options));
+               strncpy(device->options, options, length);
+       } else {
+               device->baud = probe_baud(port);
+               snprintf(device->options, sizeof(device->options), "%u",
+                       device->baud);
+       }
+
+       if (mmio || mmio32)
+               printk(KERN_INFO
+                      "Early serial console at MMIO%s 0x%llx (options '%s')\n",
+                       mmio32 ? "32" : "",
+                       (unsigned long long)port->mapbase,
+                       device->options);
+       else
+               printk(KERN_INFO
+                     "Early serial console at I/O port 0x%lx (options '%s')\n",
+                       port->iobase,
+                       device->options);
+
+       return 0;
+}
+
+static struct console early_serial8250_console __initdata = {
+       .name   = "uart",
+       .write  = early_serial8250_write,
+       .flags  = CON_PRINTBUFFER | CON_BOOT,
+       .index  = -1,
+};
+
+static int __init early_serial8250_setup(char *options)
+{
+       struct early_serial8250_device *device = &early_device;
+       int err;
+
+       if (device->port.membase || device->port.iobase)
+               return 0;
+
+       err = parse_options(device, options);
+       if (err < 0)
+               return err;
+
+       init_port(device);
+       return 0;
+}
+
+int __init setup_early_serial8250_console(char *cmdline)
+{
+       char *options;
+       int err;
+
+       options = strstr(cmdline, "uart8250,");
+       if (!options) {
+               options = strstr(cmdline, "uart,");
+               if (!options)
+                       return 0;
+       }
+
+       options = strchr(cmdline, ',') + 1;
+       err = early_serial8250_setup(options);
+       if (err < 0)
+               return err;
+
+       register_console(&early_serial8250_console);
+
+       return 0;
+}
+
+int serial8250_find_port_for_earlycon(void)
+{
+       struct early_serial8250_device *device = &early_device;
+       struct uart_port *port = &device->port;
+       int line;
+       int ret;
+
+       if (!device->port.membase && !device->port.iobase)
+               return -ENODEV;
+
+       line = serial8250_find_port(port);
+       if (line < 0)
+               return -ENODEV;
+
+       ret = update_console_cmdline("uart", 8250,
+                            "ttyS", line, device->options);
+       if (ret < 0)
+               ret = update_console_cmdline("uart", 0,
+                                    "ttyS", line, device->options);
+
+       return ret;
+}
+
+early_param("earlycon", setup_early_serial8250_console);
diff --git a/drivers/tty/serial/8250/8250_exar_st16c554.c b/drivers/tty/serial/8250/8250_exar_st16c554.c
new file mode 100644 (file)
index 0000000..bf53aab
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ *  Written by Paul B Schroeder < pschroeder "at" uplogix "dot" com >
+ *  Based on 8250_boca.
+ *
+ *  Copyright (C) 2005 Russell King.
+ *  Data taken from include/asm-i386/serial.h
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/serial_8250.h>
+
+#define PORT(_base,_irq)                               \
+       {                                               \
+               .iobase         = _base,                \
+               .irq            = _irq,                 \
+               .uartclk        = 1843200,              \
+               .iotype         = UPIO_PORT,            \
+               .flags          = UPF_BOOT_AUTOCONF,    \
+       }
+
+static struct plat_serial8250_port exar_data[] = {
+       PORT(0x100, 5),
+       PORT(0x108, 5),
+       PORT(0x110, 5),
+       PORT(0x118, 5),
+       { },
+};
+
+static struct platform_device exar_device = {
+       .name                   = "serial8250",
+       .id                     = PLAT8250_DEV_EXAR_ST16C554,
+       .dev                    = {
+               .platform_data  = exar_data,
+       },
+};
+
+static int __init exar_init(void)
+{
+       return platform_device_register(&exar_device);
+}
+
+module_init(exar_init);
+
+MODULE_AUTHOR("Paul B Schroeder");
+MODULE_DESCRIPTION("8250 serial probe module for Exar cards");
+MODULE_LICENSE("GPL");
diff --git a/drivers/tty/serial/8250/8250_fourport.c b/drivers/tty/serial/8250/8250_fourport.c
new file mode 100644 (file)
index 0000000..be15826
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ *  Copyright (C) 2005 Russell King.
+ *  Data taken from include/asm-i386/serial.h
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/serial_8250.h>
+
+#define PORT(_base,_irq)                                               \
+       {                                                               \
+               .iobase         = _base,                                \
+               .irq            = _irq,                                 \
+               .uartclk        = 1843200,                              \
+               .iotype         = UPIO_PORT,                            \
+               .flags          = UPF_BOOT_AUTOCONF | UPF_FOURPORT,     \
+       }
+
+static struct plat_serial8250_port fourport_data[] = {
+       PORT(0x1a0, 9),
+       PORT(0x1a8, 9),
+       PORT(0x1b0, 9),
+       PORT(0x1b8, 9),
+       PORT(0x2a0, 5),
+       PORT(0x2a8, 5),
+       PORT(0x2b0, 5),
+       PORT(0x2b8, 5),
+       { },
+};
+
+static struct platform_device fourport_device = {
+       .name                   = "serial8250",
+       .id                     = PLAT8250_DEV_FOURPORT,
+       .dev                    = {
+               .platform_data  = fourport_data,
+       },
+};
+
+static int __init fourport_init(void)
+{
+       return platform_device_register(&fourport_device);
+}
+
+module_init(fourport_init);
+
+MODULE_AUTHOR("Russell King");
+MODULE_DESCRIPTION("8250 serial probe module for AST Fourport cards");
+MODULE_LICENSE("GPL");
diff --git a/drivers/tty/serial/8250/8250_fsl.c b/drivers/tty/serial/8250/8250_fsl.c
new file mode 100644 (file)
index 0000000..f4d3c47
--- /dev/null
@@ -0,0 +1,63 @@
+#include <linux/serial_reg.h>
+#include <linux/serial_8250.h>
+
+#include "8250.h"
+
+/*
+ * Freescale 16550 UART "driver", Copyright (C) 2011 Paul Gortmaker.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This isn't a full driver; it just provides an alternate IRQ
+ * handler to deal with an errata.  Everything else is just
+ * using the bog standard 8250 support.
+ *
+ * We follow code flow of serial8250_default_handle_irq() but add
+ * a check for a break and insert a dummy read on the Rx for the
+ * immediately following IRQ event.
+ *
+ * We re-use the already existing "bug handling" lsr_saved_flags
+ * field to carry the "what we just did" information from the one
+ * IRQ event to the next one.
+ */
+
+int fsl8250_handle_irq(struct uart_port *port)
+{
+       unsigned char lsr, orig_lsr;
+       unsigned long flags;
+       unsigned int iir;
+       struct uart_8250_port *up =
+               container_of(port, struct uart_8250_port, port);
+
+       spin_lock_irqsave(&up->port.lock, flags);
+
+       iir = port->serial_in(port, UART_IIR);
+       if (iir & UART_IIR_NO_INT) {
+               spin_unlock_irqrestore(&up->port.lock, flags);
+               return 0;
+       }
+
+       /* This is the WAR; if last event was BRK, then read and return */
+       if (unlikely(up->lsr_saved_flags & UART_LSR_BI)) {
+               up->lsr_saved_flags &= ~UART_LSR_BI;
+               port->serial_in(port, UART_RX);
+               spin_unlock_irqrestore(&up->port.lock, flags);
+               return 1;
+       }
+
+       lsr = orig_lsr = up->port.serial_in(&up->port, UART_LSR);
+
+       if (lsr & (UART_LSR_DR | UART_LSR_BI))
+               lsr = serial8250_rx_chars(up, lsr);
+
+       serial8250_modem_status(up);
+
+       if (lsr & UART_LSR_THRE)
+               serial8250_tx_chars(up);
+
+       up->lsr_saved_flags = orig_lsr;
+       spin_unlock_irqrestore(&up->port.lock, flags);
+       return 1;
+}
diff --git a/drivers/tty/serial/8250/8250_gsc.c b/drivers/tty/serial/8250/8250_gsc.c
new file mode 100644 (file)
index 0000000..d8c0ffb
--- /dev/null
@@ -0,0 +1,122 @@
+/*
+ *     Serial Device Initialisation for Lasi/Asp/Wax/Dino
+ *
+ *     (c) Copyright Matthew Wilcox <willy@debian.org> 2001-2002
+ *
+ *     This program is free software; you can redistribute it and/or modify
+ *     it under the terms of the GNU General Public License as published by
+ *      the Free Software Foundation; either version 2 of the License, or
+ *      (at your option) any later version.
+ */
+
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/module.h>
+#include <linux/serial_core.h>
+#include <linux/signal.h>
+#include <linux/types.h>
+
+#include <asm/hardware.h>
+#include <asm/parisc-device.h>
+#include <asm/io.h>
+
+#include "8250.h"
+
+static int __init serial_init_chip(struct parisc_device *dev)
+{
+       struct uart_port port;
+       unsigned long address;
+       int err;
+
+       if (!dev->irq) {
+               /* We find some unattached serial ports by walking native
+                * busses.  These should be silently ignored.  Otherwise,
+                * what we have here is a missing parent device, so tell
+                * the user what they're missing.
+                */
+               if (parisc_parent(dev)->id.hw_type != HPHW_IOA)
+                       printk(KERN_INFO
+                               "Serial: device 0x%llx not configured.\n"
+                               "Enable support for Wax, Lasi, Asp or Dino.\n",
+                               (unsigned long long)dev->hpa.start);
+               return -ENODEV;
+       }
+
+       address = dev->hpa.start;
+       if (dev->id.sversion != 0x8d)
+               address += 0x800;
+
+       memset(&port, 0, sizeof(port));
+       port.iotype     = UPIO_MEM;
+       /* 7.272727MHz on Lasi.  Assumed the same for Dino, Wax and Timi. */
+       port.uartclk    = 7272727;
+       port.mapbase    = address;
+       port.membase    = ioremap_nocache(address, 16);
+       port.irq        = dev->irq;
+       port.flags      = UPF_BOOT_AUTOCONF;
+       port.dev        = &dev->dev;
+
+       err = serial8250_register_port(&port);
+       if (err < 0) {
+               printk(KERN_WARNING
+                       "serial8250_register_port returned error %d\n", err);
+               iounmap(port.membase);
+               return err;
+       }
+
+       return 0;
+}
+
+static struct parisc_device_id serial_tbl[] = {
+       { HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x00075 },
+       { HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x0008c },
+       { HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x0008d },
+       { 0 }
+};
+
+/* Hack.  Some machines have SERIAL_0 attached to Lasi and SERIAL_1
+ * attached to Dino.  Unfortunately, Dino appears before Lasi in the device
+ * tree.  To ensure that ttyS0 == SERIAL_0, we register two drivers; one
+ * which only knows about Lasi and then a second which will find all the
+ * other serial ports.  HPUX ignores this problem.
+ */
+static struct parisc_device_id lasi_tbl[] = {
+       { HPHW_FIO, HVERSION_REV_ANY_ID, 0x03B, 0x0008C }, /* C1xx/C1xxL */
+       { HPHW_FIO, HVERSION_REV_ANY_ID, 0x03C, 0x0008C }, /* B132L */
+       { HPHW_FIO, HVERSION_REV_ANY_ID, 0x03D, 0x0008C }, /* B160L */
+       { HPHW_FIO, HVERSION_REV_ANY_ID, 0x03E, 0x0008C }, /* B132L+ */
+       { HPHW_FIO, HVERSION_REV_ANY_ID, 0x03F, 0x0008C }, /* B180L+ */
+       { HPHW_FIO, HVERSION_REV_ANY_ID, 0x046, 0x0008C }, /* Rocky2 120 */
+       { HPHW_FIO, HVERSION_REV_ANY_ID, 0x047, 0x0008C }, /* Rocky2 150 */
+       { HPHW_FIO, HVERSION_REV_ANY_ID, 0x04E, 0x0008C }, /* Kiji L2 132 */
+       { HPHW_FIO, HVERSION_REV_ANY_ID, 0x056, 0x0008C }, /* Raven+ */
+       { 0 }
+};
+
+
+MODULE_DEVICE_TABLE(parisc, serial_tbl);
+
+static struct parisc_driver lasi_driver = {
+       .name           = "serial_1",
+       .id_table       = lasi_tbl,
+       .probe          = serial_init_chip,
+};
+
+static struct parisc_driver serial_driver = {
+       .name           = "serial",
+       .id_table       = serial_tbl,
+       .probe          = serial_init_chip,
+};
+
+static int __init probe_serial_gsc(void)
+{
+       register_parisc_driver(&lasi_driver);
+       register_parisc_driver(&serial_driver);
+       return 0;
+}
+
+module_init(probe_serial_gsc);
+
+MODULE_LICENSE("GPL");
diff --git a/drivers/tty/serial/8250/8250_hp300.c b/drivers/tty/serial/8250/8250_hp300.c
new file mode 100644 (file)
index 0000000..c13438c
--- /dev/null
@@ -0,0 +1,327 @@
+/*
+ * Driver for the 98626/98644/internal serial interface on hp300/hp400
+ * (based on the National Semiconductor INS8250/NS16550AF/WD16C552 UARTs)
+ *
+ * Ported from 2.2 and modified to use the normal 8250 driver
+ * by Kars de Jong <jongk@linux-m68k.org>, May 2004.
+ */
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/string.h>
+#include <linux/kernel.h>
+#include <linux/serial.h>
+#include <linux/serial_core.h>
+#include <linux/serial_8250.h>
+#include <linux/delay.h>
+#include <linux/dio.h>
+#include <linux/console.h>
+#include <linux/slab.h>
+#include <asm/io.h>
+
+#include "8250.h"
+
+#if !defined(CONFIG_HPDCA) && !defined(CONFIG_HPAPCI)
+#warning CONFIG_8250 defined but neither CONFIG_HPDCA nor CONFIG_HPAPCI defined, are you sure?
+#endif
+
+#ifdef CONFIG_HPAPCI
+struct hp300_port
+{
+       struct hp300_port *next;        /* next port */
+       int line;                       /* line (tty) number */
+};
+
+static struct hp300_port *hp300_ports;
+#endif
+
+#ifdef CONFIG_HPDCA
+
+static int __devinit hpdca_init_one(struct dio_dev *d,
+                                       const struct dio_device_id *ent);
+static void __devexit hpdca_remove_one(struct dio_dev *d);
+
+static struct dio_device_id hpdca_dio_tbl[] = {
+       { DIO_ID_DCA0 },
+       { DIO_ID_DCA0REM },
+       { DIO_ID_DCA1 },
+       { DIO_ID_DCA1REM },
+       { 0 }
+};
+
+static struct dio_driver hpdca_driver = {
+       .name      = "hpdca",
+       .id_table  = hpdca_dio_tbl,
+       .probe     = hpdca_init_one,
+       .remove    = __devexit_p(hpdca_remove_one),
+};
+
+#endif
+
+static unsigned int num_ports;
+
+extern int hp300_uart_scode;
+
+/* Offset to UART registers from base of DCA */
+#define UART_OFFSET    17
+
+#define DCA_ID         0x01    /* ID (read), reset (write) */
+#define DCA_IC         0x03    /* Interrupt control        */
+
+/* Interrupt control */
+#define DCA_IC_IE      0x80    /* Master interrupt enable  */
+
+#define HPDCA_BAUD_BASE 153600
+
+/* Base address of the Frodo part */
+#define FRODO_BASE     (0x41c000)
+
+/*
+ * Where we find the 8250-like APCI ports, and how far apart they are.
+ */
+#define FRODO_APCIBASE         0x0
+#define FRODO_APCISPACE                0x20
+#define FRODO_APCI_OFFSET(x)   (FRODO_APCIBASE + ((x) * FRODO_APCISPACE))
+
+#define HPAPCI_BAUD_BASE 500400
+
+#ifdef CONFIG_SERIAL_8250_CONSOLE
+/*
+ * Parse the bootinfo to find descriptions for headless console and
+ * debug serial ports and register them with the 8250 driver.
+ * This function should be called before serial_console_init() is called
+ * to make sure the serial console will be available for use. IA-64 kernel
+ * calls this function from setup_arch() after the EFI and ACPI tables have
+ * been parsed.
+ */
+int __init hp300_setup_serial_console(void)
+{
+       int scode;
+       struct uart_port port;
+
+       memset(&port, 0, sizeof(port));
+
+       if (hp300_uart_scode < 0 || hp300_uart_scode > DIO_SCMAX)
+               return 0;
+
+       if (DIO_SCINHOLE(hp300_uart_scode))
+               return 0;
+
+       scode = hp300_uart_scode;
+
+       /* Memory mapped I/O */
+       port.iotype = UPIO_MEM;
+       port.flags = UPF_SKIP_TEST | UPF_SHARE_IRQ | UPF_BOOT_AUTOCONF;
+       port.type = PORT_UNKNOWN;
+
+       /* Check for APCI console */
+       if (scode == 256) {
+#ifdef CONFIG_HPAPCI
+               printk(KERN_INFO "Serial console is HP APCI 1\n");
+
+               port.uartclk = HPAPCI_BAUD_BASE * 16;
+               port.mapbase = (FRODO_BASE + FRODO_APCI_OFFSET(1));
+               port.membase = (char *)(port.mapbase + DIO_VIRADDRBASE);
+               port.regshift = 2;
+               add_preferred_console("ttyS", port.line, "9600n8");
+#else
+               printk(KERN_WARNING "Serial console is APCI but support is disabled (CONFIG_HPAPCI)!\n");
+               return 0;
+#endif
+       } else {
+#ifdef CONFIG_HPDCA
+               unsigned long pa = dio_scodetophysaddr(scode);
+               if (!pa)
+                       return 0;
+
+               printk(KERN_INFO "Serial console is HP DCA at select code %d\n", scode);
+
+               port.uartclk = HPDCA_BAUD_BASE * 16;
+               port.mapbase = (pa + UART_OFFSET);
+               port.membase = (char *)(port.mapbase + DIO_VIRADDRBASE);
+               port.regshift = 1;
+               port.irq = DIO_IPL(pa + DIO_VIRADDRBASE);
+
+               /* Enable board-interrupts */
+               out_8(pa + DIO_VIRADDRBASE + DCA_IC, DCA_IC_IE);
+
+               if (DIO_ID(pa + DIO_VIRADDRBASE) & 0x80)
+                       add_preferred_console("ttyS", port.line, "9600n8");
+#else
+               printk(KERN_WARNING "Serial console is DCA but support is disabled (CONFIG_HPDCA)!\n");
+               return 0;
+#endif
+       }
+
+       if (early_serial_setup(&port) < 0)
+               printk(KERN_WARNING "hp300_setup_serial_console(): early_serial_setup() failed.\n");
+       return 0;
+}
+#endif /* CONFIG_SERIAL_8250_CONSOLE */
+
+#ifdef CONFIG_HPDCA
+static int __devinit hpdca_init_one(struct dio_dev *d,
+                               const struct dio_device_id *ent)
+{
+       struct uart_port port;
+       int line;
+
+#ifdef CONFIG_SERIAL_8250_CONSOLE
+       if (hp300_uart_scode == d->scode) {
+               /* Already got it. */
+               return 0;
+       }
+#endif
+       memset(&port, 0, sizeof(struct uart_port));
+
+       /* Memory mapped I/O */
+       port.iotype = UPIO_MEM;
+       port.flags = UPF_SKIP_TEST | UPF_SHARE_IRQ | UPF_BOOT_AUTOCONF;
+       port.irq = d->ipl;
+       port.uartclk = HPDCA_BAUD_BASE * 16;
+       port.mapbase = (d->resource.start + UART_OFFSET);
+       port.membase = (char *)(port.mapbase + DIO_VIRADDRBASE);
+       port.regshift = 1;
+       port.dev = &d->dev;
+       line = serial8250_register_port(&port);
+
+       if (line < 0) {
+               printk(KERN_NOTICE "8250_hp300: register_serial() DCA scode %d"
+                      " irq %d failed\n", d->scode, port.irq);
+               return -ENOMEM;
+       }
+
+       /* Enable board-interrupts */
+       out_8(d->resource.start + DIO_VIRADDRBASE + DCA_IC, DCA_IC_IE);
+       dio_set_drvdata(d, (void *)line);
+
+       /* Reset the DCA */
+       out_8(d->resource.start + DIO_VIRADDRBASE + DCA_ID, 0xff);
+       udelay(100);
+
+       num_ports++;
+
+       return 0;
+}
+#endif
+
+static int __init hp300_8250_init(void)
+{
+       static int called;
+#ifdef CONFIG_HPAPCI
+       int line;
+       unsigned long base;
+       struct uart_port uport;
+       struct hp300_port *port;
+       int i;
+#endif
+       if (called)
+               return -ENODEV;
+       called = 1;
+
+       if (!MACH_IS_HP300)
+               return -ENODEV;
+
+#ifdef CONFIG_HPDCA
+       dio_register_driver(&hpdca_driver);
+#endif
+#ifdef CONFIG_HPAPCI
+       if (hp300_model < HP_400) {
+               if (!num_ports)
+                       return -ENODEV;
+               return 0;
+       }
+       /* These models have the Frodo chip.
+        * Port 0 is reserved for the Apollo Domain keyboard.
+        * Port 1 is either the console or the DCA.
+        */
+       for (i = 1; i < 4; i++) {
+               /* Port 1 is the console on a 425e, on other machines it's
+                * mapped to DCA.
+                */
+#ifdef CONFIG_SERIAL_8250_CONSOLE
+               if (i == 1)
+                       continue;
+#endif
+
+               /* Create new serial device */
+               port = kmalloc(sizeof(struct hp300_port), GFP_KERNEL);
+               if (!port)
+                       return -ENOMEM;
+
+               memset(&uport, 0, sizeof(struct uart_port));
+
+               base = (FRODO_BASE + FRODO_APCI_OFFSET(i));
+
+               /* Memory mapped I/O */
+               uport.iotype = UPIO_MEM;
+               uport.flags = UPF_SKIP_TEST | UPF_SHARE_IRQ \
+                             | UPF_BOOT_AUTOCONF;
+               /* XXX - no interrupt support yet */
+               uport.irq = 0;
+               uport.uartclk = HPAPCI_BAUD_BASE * 16;
+               uport.mapbase = base;
+               uport.membase = (char *)(base + DIO_VIRADDRBASE);
+               uport.regshift = 2;
+
+               line = serial8250_register_port(&uport);
+
+               if (line < 0) {
+                       printk(KERN_NOTICE "8250_hp300: register_serial() APCI"
+                              " %d irq %d failed\n", i, uport.irq);
+                       kfree(port);
+                       continue;
+               }
+
+               port->line = line;
+               port->next = hp300_ports;
+               hp300_ports = port;
+
+               num_ports++;
+       }
+#endif
+
+       /* Any boards found? */
+       if (!num_ports)
+               return -ENODEV;
+
+       return 0;
+}
+
+#ifdef CONFIG_HPDCA
+static void __devexit hpdca_remove_one(struct dio_dev *d)
+{
+       int line;
+
+       line = (int) dio_get_drvdata(d);
+       if (d->resource.start) {
+               /* Disable board-interrupts */
+               out_8(d->resource.start + DIO_VIRADDRBASE + DCA_IC, 0);
+       }
+       serial8250_unregister_port(line);
+}
+#endif
+
+static void __exit hp300_8250_exit(void)
+{
+#ifdef CONFIG_HPAPCI
+       struct hp300_port *port, *to_free;
+
+       for (port = hp300_ports; port; ) {
+               serial8250_unregister_port(port->line);
+               to_free = port;
+               port = port->next;
+               kfree(to_free);
+       }
+
+       hp300_ports = NULL;
+#endif
+#ifdef CONFIG_HPDCA
+       dio_unregister_driver(&hpdca_driver);
+#endif
+}
+
+module_init(hp300_8250_init);
+module_exit(hp300_8250_exit);
+MODULE_DESCRIPTION("HP DCA/APCI serial driver");
+MODULE_AUTHOR("Kars de Jong <jongk@linux-m68k.org>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/tty/serial/8250/8250_hub6.c b/drivers/tty/serial/8250/8250_hub6.c
new file mode 100644 (file)
index 0000000..a5c778e
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ *  Copyright (C) 2005 Russell King.
+ *  Data taken from include/asm-i386/serial.h
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/serial_8250.h>
+
+#define HUB6(card,port)                                                        \
+       {                                                               \
+               .iobase         = 0x302,                                \
+               .irq            = 3,                                    \
+               .uartclk        = 1843200,                              \
+               .iotype         = UPIO_HUB6,                            \
+               .flags          = UPF_BOOT_AUTOCONF,                    \
+               .hub6           = (card) << 6 | (port) << 3 | 1,        \
+       }
+
+static struct plat_serial8250_port hub6_data[] = {
+       HUB6(0, 0),
+       HUB6(0, 1),
+       HUB6(0, 2),
+       HUB6(0, 3),
+       HUB6(0, 4),
+       HUB6(0, 5),
+       HUB6(1, 0),
+       HUB6(1, 1),
+       HUB6(1, 2),
+       HUB6(1, 3),
+       HUB6(1, 4),
+       HUB6(1, 5),
+       { },
+};
+
+static struct platform_device hub6_device = {
+       .name                   = "serial8250",
+       .id                     = PLAT8250_DEV_HUB6,
+       .dev                    = {
+               .platform_data  = hub6_data,
+       },
+};
+
+static int __init hub6_init(void)
+{
+       return platform_device_register(&hub6_device);
+}
+
+module_init(hub6_init);
+
+MODULE_AUTHOR("Russell King");
+MODULE_DESCRIPTION("8250 serial probe module for Hub6 cards");
+MODULE_LICENSE("GPL");
diff --git a/drivers/tty/serial/8250/8250_mca.c b/drivers/tty/serial/8250/8250_mca.c
new file mode 100644 (file)
index 0000000..d20abf0
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ *  Copyright (C) 2005 Russell King.
+ *  Data taken from include/asm-i386/serial.h
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/mca.h>
+#include <linux/serial_8250.h>
+
+/*
+ * FIXME: Should we be doing AUTO_IRQ here?
+ */
+#ifdef CONFIG_SERIAL_8250_DETECT_IRQ
+#define MCA_FLAGS      UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_AUTO_IRQ
+#else
+#define MCA_FLAGS      UPF_BOOT_AUTOCONF | UPF_SKIP_TEST
+#endif
+
+#define PORT(_base,_irq)                       \
+       {                                       \
+               .iobase         = _base,        \
+               .irq            = _irq,         \
+               .uartclk        = 1843200,      \
+               .iotype         = UPIO_PORT,    \
+               .flags          = MCA_FLAGS,    \
+       }
+
+static struct plat_serial8250_port mca_data[] = {
+       PORT(0x3220, 3),
+       PORT(0x3228, 3),
+       PORT(0x4220, 3),
+       PORT(0x4228, 3),
+       PORT(0x5220, 3),
+       PORT(0x5228, 3),
+       { },
+};
+
+static struct platform_device mca_device = {
+       .name                   = "serial8250",
+       .id                     = PLAT8250_DEV_MCA,
+       .dev                    = {
+               .platform_data  = mca_data,
+       },
+};
+
+static int __init mca_init(void)
+{
+       if (!MCA_bus)
+               return -ENODEV;
+       return platform_device_register(&mca_device);
+}
+
+module_init(mca_init);
+
+MODULE_AUTHOR("Russell King");
+MODULE_DESCRIPTION("8250 serial probe module for MCA ports");
+MODULE_LICENSE("GPL");
diff --git a/drivers/tty/serial/8250/8250_pci.c b/drivers/tty/serial/8250/8250_pci.c
new file mode 100644 (file)
index 0000000..da2b0b0
--- /dev/null
@@ -0,0 +1,4223 @@
+/*
+ *  Probe module for 8250/16550-type PCI serial ports.
+ *
+ *  Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o.
+ *
+ *  Copyright (C) 2001 Russell King, All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License.
+ */
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/string.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/tty.h>
+#include <linux/serial_core.h>
+#include <linux/8250_pci.h>
+#include <linux/bitops.h>
+
+#include <asm/byteorder.h>
+#include <asm/io.h>
+
+#include "8250.h"
+
+#undef SERIAL_DEBUG_PCI
+
+/*
+ * init function returns:
+ *  > 0 - number of ports
+ *  = 0 - use board->num_ports
+ *  < 0 - error
+ */
+struct pci_serial_quirk {
+       u32     vendor;
+       u32     device;
+       u32     subvendor;
+       u32     subdevice;
+       int     (*probe)(struct pci_dev *dev);
+       int     (*init)(struct pci_dev *dev);
+       int     (*setup)(struct serial_private *,
+                        const struct pciserial_board *,
+                        struct uart_port *, int);
+       void    (*exit)(struct pci_dev *dev);
+};
+
+#define PCI_NUM_BAR_RESOURCES  6
+
+struct serial_private {
+       struct pci_dev          *dev;
+       unsigned int            nr;
+       void __iomem            *remapped_bar[PCI_NUM_BAR_RESOURCES];
+       struct pci_serial_quirk *quirk;
+       int                     line[0];
+};
+
+static int pci_default_setup(struct serial_private*,
+         const struct pciserial_board*, struct uart_port*, int);
+
+static void moan_device(const char *str, struct pci_dev *dev)
+{
+       printk(KERN_WARNING
+              "%s: %s\n"
+              "Please send the output of lspci -vv, this\n"
+              "message (0x%04x,0x%04x,0x%04x,0x%04x), the\n"
+              "manufacturer and name of serial board or\n"
+              "modem board to rmk+serial@arm.linux.org.uk.\n",
+              pci_name(dev), str, dev->vendor, dev->device,
+              dev->subsystem_vendor, dev->subsystem_device);
+}
+
+static int
+setup_port(struct serial_private *priv, struct uart_port *port,
+          int bar, int offset, int regshift)
+{
+       struct pci_dev *dev = priv->dev;
+       unsigned long base, len;
+
+       if (bar >= PCI_NUM_BAR_RESOURCES)
+               return -EINVAL;
+
+       base = pci_resource_start(dev, bar);
+
+       if (pci_resource_flags(dev, bar) & IORESOURCE_MEM) {
+               len =  pci_resource_len(dev, bar);
+
+               if (!priv->remapped_bar[bar])
+                       priv->remapped_bar[bar] = ioremap_nocache(base, len);
+               if (!priv->remapped_bar[bar])
+                       return -ENOMEM;
+
+               port->iotype = UPIO_MEM;
+               port->iobase = 0;
+               port->mapbase = base + offset;
+               port->membase = priv->remapped_bar[bar] + offset;
+               port->regshift = regshift;
+       } else {
+               port->iotype = UPIO_PORT;
+               port->iobase = base + offset;
+               port->mapbase = 0;
+               port->membase = NULL;
+               port->regshift = 0;
+       }
+       return 0;
+}
+
+/*
+ * ADDI-DATA GmbH communication cards <info@addi-data.com>
+ */
+static int addidata_apci7800_setup(struct serial_private *priv,
+                               const struct pciserial_board *board,
+                               struct uart_port *port, int idx)
+{
+       unsigned int bar = 0, offset = board->first_offset;
+       bar = FL_GET_BASE(board->flags);
+
+       if (idx < 2) {
+               offset += idx * board->uart_offset;
+       } else if ((idx >= 2) && (idx < 4)) {
+               bar += 1;
+               offset += ((idx - 2) * board->uart_offset);
+       } else if ((idx >= 4) && (idx < 6)) {
+               bar += 2;
+               offset += ((idx - 4) * board->uart_offset);
+       } else if (idx >= 6) {
+               bar += 3;
+               offset += ((idx - 6) * board->uart_offset);
+       }
+
+       return setup_port(priv, port, bar, offset, board->reg_shift);
+}
+
+/*
+ * AFAVLAB uses a different mixture of BARs and offsets
+ * Not that ugly ;) -- HW
+ */
+static int
+afavlab_setup(struct serial_private *priv, const struct pciserial_board *board,
+             struct uart_port *port, int idx)
+{
+       unsigned int bar, offset = board->first_offset;
+
+       bar = FL_GET_BASE(board->flags);
+       if (idx < 4)
+               bar += idx;
+       else {
+               bar = 4;
+               offset += (idx - 4) * board->uart_offset;
+       }
+
+       return setup_port(priv, port, bar, offset, board->reg_shift);
+}
+
+/*
+ * HP's Remote Management Console.  The Diva chip came in several
+ * different versions.  N-class, L2000 and A500 have two Diva chips, each
+ * with 3 UARTs (the third UART on the second chip is unused).  Superdome
+ * and Keystone have one Diva chip with 3 UARTs.  Some later machines have
+ * one Diva chip, but it has been expanded to 5 UARTs.
+ */
+static int pci_hp_diva_init(struct pci_dev *dev)
+{
+       int rc = 0;
+
+       switch (dev->subsystem_device) {
+       case PCI_DEVICE_ID_HP_DIVA_TOSCA1:
+       case PCI_DEVICE_ID_HP_DIVA_HALFDOME:
+       case PCI_DEVICE_ID_HP_DIVA_KEYSTONE:
+       case PCI_DEVICE_ID_HP_DIVA_EVEREST:
+               rc = 3;
+               break;
+       case PCI_DEVICE_ID_HP_DIVA_TOSCA2:
+               rc = 2;
+               break;
+       case PCI_DEVICE_ID_HP_DIVA_MAESTRO:
+               rc = 4;
+               break;
+       case PCI_DEVICE_ID_HP_DIVA_POWERBAR:
+       case PCI_DEVICE_ID_HP_DIVA_HURRICANE:
+               rc = 1;
+               break;
+       }
+
+       return rc;
+}
+
+/*
+ * HP's Diva chip puts the 4th/5th serial port further out, and
+ * some serial ports are supposed to be hidden on certain models.
+ */
+static int
+pci_hp_diva_setup(struct serial_private *priv,
+               const struct pciserial_board *board,
+               struct uart_port *port, int idx)
+{
+       unsigned int offset = board->first_offset;
+       unsigned int bar = FL_GET_BASE(board->flags);
+
+       switch (priv->dev->subsystem_device) {
+       case PCI_DEVICE_ID_HP_DIVA_MAESTRO:
+               if (idx == 3)
+                       idx++;
+               break;
+       case PCI_DEVICE_ID_HP_DIVA_EVEREST:
+               if (idx > 0)
+                       idx++;
+               if (idx > 2)
+                       idx++;
+               break;
+       }
+       if (idx > 2)
+               offset = 0x18;
+
+       offset += idx * board->uart_offset;
+
+       return setup_port(priv, port, bar, offset, board->reg_shift);
+}
+
+/*
+ * Added for EKF Intel i960 serial boards
+ */
+static int pci_inteli960ni_init(struct pci_dev *dev)
+{
+       unsigned long oldval;
+
+       if (!(dev->subsystem_device & 0x1000))
+               return -ENODEV;
+
+       /* is firmware started? */
+       pci_read_config_dword(dev, 0x44, (void *)&oldval);
+       if (oldval == 0x00001000L) { /* RESET value */
+               printk(KERN_DEBUG "Local i960 firmware missing");
+               return -ENODEV;
+       }
+       return 0;
+}
+
+/*
+ * Some PCI serial cards using the PLX 9050 PCI interface chip require
+ * that the card interrupt be explicitly enabled or disabled.  This
+ * seems to be mainly needed on card using the PLX which also use I/O
+ * mapped memory.
+ */
+static int pci_plx9050_init(struct pci_dev *dev)
+{
+       u8 irq_config;
+       void __iomem *p;
+
+       if ((pci_resource_flags(dev, 0) & IORESOURCE_MEM) == 0) {
+               moan_device("no memory in bar 0", dev);
+               return 0;
+       }
+
+       irq_config = 0x41;
+       if (dev->vendor == PCI_VENDOR_ID_PANACOM ||
+           dev->subsystem_vendor == PCI_SUBVENDOR_ID_EXSYS)
+               irq_config = 0x43;
+
+       if ((dev->vendor == PCI_VENDOR_ID_PLX) &&
+           (dev->device == PCI_DEVICE_ID_PLX_ROMULUS))
+               /*
+                * As the megawolf cards have the int pins active
+                * high, and have 2 UART chips, both ints must be
+                * enabled on the 9050. Also, the UARTS are set in
+                * 16450 mode by default, so we have to enable the
+                * 16C950 'enhanced' mode so that we can use the
+                * deep FIFOs
+                */
+               irq_config = 0x5b;
+       /*
+        * enable/disable interrupts
+        */
+       p = ioremap_nocache(pci_resource_start(dev, 0), 0x80);
+       if (p == NULL)
+               return -ENOMEM;
+       writel(irq_config, p + 0x4c);
+
+       /*
+        * Read the register back to ensure that it took effect.
+        */
+       readl(p + 0x4c);
+       iounmap(p);
+
+       return 0;
+}
+
+static void __devexit pci_plx9050_exit(struct pci_dev *dev)
+{
+       u8 __iomem *p;
+
+       if ((pci_resource_flags(dev, 0) & IORESOURCE_MEM) == 0)
+               return;
+
+       /*
+        * disable interrupts
+        */
+       p = ioremap_nocache(pci_resource_start(dev, 0), 0x80);
+       if (p != NULL) {
+               writel(0, p + 0x4c);
+
+               /*
+                * Read the register back to ensure that it took effect.
+                */
+               readl(p + 0x4c);
+               iounmap(p);
+       }
+}
+
+#define NI8420_INT_ENABLE_REG  0x38
+#define NI8420_INT_ENABLE_BIT  0x2000
+
+static void __devexit pci_ni8420_exit(struct pci_dev *dev)
+{
+       void __iomem *p;
+       unsigned long base, len;
+       unsigned int bar = 0;
+
+       if ((pci_resource_flags(dev, bar) & IORESOURCE_MEM) == 0) {
+               moan_device("no memory in bar", dev);
+               return;
+       }
+
+       base = pci_resource_start(dev, bar);
+       len =  pci_resource_len(dev, bar);
+       p = ioremap_nocache(base, len);
+       if (p == NULL)
+               return;
+
+       /* Disable the CPU Interrupt */
+       writel(readl(p + NI8420_INT_ENABLE_REG) & ~(NI8420_INT_ENABLE_BIT),
+              p + NI8420_INT_ENABLE_REG);
+       iounmap(p);
+}
+
+
+/* MITE registers */
+#define MITE_IOWBSR1   0xc4
+#define MITE_IOWCR1    0xf4
+#define MITE_LCIMR1    0x08
+#define MITE_LCIMR2    0x10
+
+#define MITE_LCIMR2_CLR_CPU_IE (1 << 30)
+
+static void __devexit pci_ni8430_exit(struct pci_dev *dev)
+{
+       void __iomem *p;
+       unsigned long base, len;
+       unsigned int bar = 0;
+
+       if ((pci_resource_flags(dev, bar) & IORESOURCE_MEM) == 0) {
+               moan_device("no memory in bar", dev);
+               return;
+       }
+
+       base = pci_resource_start(dev, bar);
+       len =  pci_resource_len(dev, bar);
+       p = ioremap_nocache(base, len);
+       if (p == NULL)
+               return;
+
+       /* Disable the CPU Interrupt */
+       writel(MITE_LCIMR2_CLR_CPU_IE, p + MITE_LCIMR2);
+       iounmap(p);
+}
+
+/* SBS Technologies Inc. PMC-OCTPRO and P-OCTAL cards */
+static int
+sbs_setup(struct serial_private *priv, const struct pciserial_board *board,
+               struct uart_port *port, int idx)
+{
+       unsigned int bar, offset = board->first_offset;
+
+       bar = 0;
+
+       if (idx < 4) {
+               /* first four channels map to 0, 0x100, 0x200, 0x300 */
+               offset += idx * board->uart_offset;
+       } else if (idx < 8) {
+               /* last four channels map to 0x1000, 0x1100, 0x1200, 0x1300 */
+               offset += idx * board->uart_offset + 0xC00;
+       } else /* we have only 8 ports on PMC-OCTALPRO */
+               return 1;
+
+       return setup_port(priv, port, bar, offset, board->reg_shift);
+}
+
+/*
+* This does initialization for PMC OCTALPRO cards:
+* maps the device memory, resets the UARTs (needed, bc
+* if the module is removed and inserted again, the card
+* is in the sleep mode) and enables global interrupt.
+*/
+
+/* global control register offset for SBS PMC-OctalPro */
+#define OCT_REG_CR_OFF         0x500
+
+static int sbs_init(struct pci_dev *dev)
+{
+       u8 __iomem *p;
+
+       p = pci_ioremap_bar(dev, 0);
+
+       if (p == NULL)
+               return -ENOMEM;
+       /* Set bit-4 Control Register (UART RESET) in to reset the uarts */
+       writeb(0x10, p + OCT_REG_CR_OFF);
+       udelay(50);
+       writeb(0x0, p + OCT_REG_CR_OFF);
+
+       /* Set bit-2 (INTENABLE) of Control Register */
+       writeb(0x4, p + OCT_REG_CR_OFF);
+       iounmap(p);
+
+       return 0;
+}
+
+/*
+ * Disables the global interrupt of PMC-OctalPro
+ */
+
+static void __devexit sbs_exit(struct pci_dev *dev)
+{
+       u8 __iomem *p;
+
+       p = pci_ioremap_bar(dev, 0);
+       /* FIXME: What if resource_len < OCT_REG_CR_OFF */
+       if (p != NULL)
+               writeb(0, p + OCT_REG_CR_OFF);
+       iounmap(p);
+}
+
+/*
+ * SIIG serial cards have an PCI interface chip which also controls
+ * the UART clocking frequency. Each UART can be clocked independently
+ * (except cards equipped with 4 UARTs) and initial clocking settings
+ * are stored in the EEPROM chip. It can cause problems because this
+ * version of serial driver doesn't support differently clocked UART's
+ * on single PCI card. To prevent this, initialization functions set
+ * high frequency clocking for all UART's on given card. It is safe (I
+ * hope) because it doesn't touch EEPROM settings to prevent conflicts
+ * with other OSes (like M$ DOS).
+ *
+ *  SIIG support added by Andrey Panin <pazke@donpac.ru>, 10/1999
+ *
+ * There is two family of SIIG serial cards with different PCI
+ * interface chip and different configuration methods:
+ *     - 10x cards have control registers in IO and/or memory space;
+ *     - 20x cards have control registers in standard PCI configuration space.
+ *
+ * Note: all 10x cards have PCI device ids 0x10..
+ *       all 20x cards have PCI device ids 0x20..
+ *
+ * There are also Quartet Serial cards which use Oxford Semiconductor
+ * 16954 quad UART PCI chip clocked by 18.432 MHz quartz.
+ *
+ * Note: some SIIG cards are probed by the parport_serial object.
+ */
+
+#define PCI_DEVICE_ID_SIIG_1S_10x (PCI_DEVICE_ID_SIIG_1S_10x_550 & 0xfffc)
+#define PCI_DEVICE_ID_SIIG_2S_10x (PCI_DEVICE_ID_SIIG_2S_10x_550 & 0xfff8)
+
+static int pci_siig10x_init(struct pci_dev *dev)
+{
+       u16 data;
+       void __iomem *p;
+
+       switch (dev->device & 0xfff8) {
+       case PCI_DEVICE_ID_SIIG_1S_10x: /* 1S */
+               data = 0xffdf;
+               break;
+       case PCI_DEVICE_ID_SIIG_2S_10x: /* 2S, 2S1P */
+               data = 0xf7ff;
+               break;
+       default:                        /* 1S1P, 4S */
+               data = 0xfffb;
+               break;
+       }
+
+       p = ioremap_nocache(pci_resource_start(dev, 0), 0x80);
+       if (p == NULL)
+               return -ENOMEM;
+
+       writew(readw(p + 0x28) & data, p + 0x28);
+       readw(p + 0x28);
+       iounmap(p);
+       return 0;
+}
+
+#define PCI_DEVICE_ID_SIIG_2S_20x (PCI_DEVICE_ID_SIIG_2S_20x_550 & 0xfffc)
+#define PCI_DEVICE_ID_SIIG_2S1P_20x (PCI_DEVICE_ID_SIIG_2S1P_20x_550 & 0xfffc)
+
+static int pci_siig20x_init(struct pci_dev *dev)
+{
+       u8 data;
+
+       /* Change clock frequency for the first UART. */
+       pci_read_config_byte(dev, 0x6f, &data);
+       pci_write_config_byte(dev, 0x6f, data & 0xef);
+
+       /* If this card has 2 UART, we have to do the same with second UART. */
+       if (((dev->device & 0xfffc) == PCI_DEVICE_ID_SIIG_2S_20x) ||
+           ((dev->device & 0xfffc) == PCI_DEVICE_ID_SIIG_2S1P_20x)) {
+               pci_read_config_byte(dev, 0x73, &data);
+               pci_write_config_byte(dev, 0x73, data & 0xef);
+       }
+       return 0;
+}
+
+static int pci_siig_init(struct pci_dev *dev)
+{
+       unsigned int type = dev->device & 0xff00;
+
+       if (type == 0x1000)
+               return pci_siig10x_init(dev);
+       else if (type == 0x2000)
+               return pci_siig20x_init(dev);
+
+       moan_device("Unknown SIIG card", dev);
+       return -ENODEV;
+}
+
+static int pci_siig_setup(struct serial_private *priv,
+                         const struct pciserial_board *board,
+                         struct uart_port *port, int idx)
+{
+       unsigned int bar = FL_GET_BASE(board->flags) + idx, offset = 0;
+
+       if (idx > 3) {
+               bar = 4;
+               offset = (idx - 4) * 8;
+       }
+
+       return setup_port(priv, port, bar, offset, 0);
+}
+
+/*
+ * Timedia has an explosion of boards, and to avoid the PCI table from
+ * growing *huge*, we use this function to collapse some 70 entries
+ * in the PCI table into one, for sanity's and compactness's sake.
+ */
+static const unsigned short timedia_single_port[] = {
+       0x4025, 0x4027, 0x4028, 0x5025, 0x5027, 0
+};
+
+static const unsigned short timedia_dual_port[] = {
+       0x0002, 0x4036, 0x4037, 0x4038, 0x4078, 0x4079, 0x4085,
+       0x4088, 0x4089, 0x5037, 0x5078, 0x5079, 0x5085, 0x6079,
+       0x7079, 0x8079, 0x8137, 0x8138, 0x8237, 0x8238, 0x9079,
+       0x9137, 0x9138, 0x9237, 0x9238, 0xA079, 0xB079, 0xC079,
+       0xD079, 0
+};
+
+static const unsigned short timedia_quad_port[] = {
+       0x4055, 0x4056, 0x4095, 0x4096, 0x5056, 0x8156, 0x8157,
+       0x8256, 0x8257, 0x9056, 0x9156, 0x9157, 0x9158, 0x9159,
+       0x9256, 0x9257, 0xA056, 0xA157, 0xA158, 0xA159, 0xB056,
+       0xB157, 0
+};
+
+static const unsigned short timedia_eight_port[] = {
+       0x4065, 0x4066, 0x5065, 0x5066, 0x8166, 0x9066, 0x9166,
+       0x9167, 0x9168, 0xA066, 0xA167, 0xA168, 0
+};
+
+static const struct timedia_struct {
+       int num;
+       const unsigned short *ids;
+} timedia_data[] = {
+       { 1, timedia_single_port },
+       { 2, timedia_dual_port },
+       { 4, timedia_quad_port },
+       { 8, timedia_eight_port }
+};
+
+/*
+ * There are nearly 70 different Timedia/SUNIX PCI serial devices.  Instead of
+ * listing them individually, this driver merely grabs them all with
+ * PCI_ANY_ID.  Some of these devices, however, also feature a parallel port,
+ * and should be left free to be claimed by parport_serial instead.
+ */
+static int pci_timedia_probe(struct pci_dev *dev)
+{
+       /*
+        * Check the third digit of the subdevice ID
+        * (0,2,3,5,6: serial only -- 7,8,9: serial + parallel)
+        */
+       if ((dev->subsystem_device & 0x00f0) >= 0x70) {
+               dev_info(&dev->dev,
+                       "ignoring Timedia subdevice %04x for parport_serial\n",
+                       dev->subsystem_device);
+               return -ENODEV;
+       }
+
+       return 0;
+}
+
+static int pci_timedia_init(struct pci_dev *dev)
+{
+       const unsigned short *ids;
+       int i, j;
+
+       for (i = 0; i < ARRAY_SIZE(timedia_data); i++) {
+               ids = timedia_data[i].ids;
+               for (j = 0; ids[j]; j++)
+                       if (dev->subsystem_device == ids[j])
+                               return timedia_data[i].num;
+       }
+       return 0;
+}
+
+/*
+ * Timedia/SUNIX uses a mixture of BARs and offsets
+ * Ugh, this is ugly as all hell --- TYT
+ */
+static int
+pci_timedia_setup(struct serial_private *priv,
+                 const struct pciserial_board *board,
+                 struct uart_port *port, int idx)
+{
+       unsigned int bar = 0, offset = board->first_offset;
+
+       switch (idx) {
+       case 0:
+               bar = 0;
+               break;
+       case 1:
+               offset = board->uart_offset;
+               bar = 0;
+               break;
+       case 2:
+               bar = 1;
+               break;
+       case 3:
+               offset = board->uart_offset;
+               /* FALLTHROUGH */
+       case 4: /* BAR 2 */
+       case 5: /* BAR 3 */
+       case 6: /* BAR 4 */
+       case 7: /* BAR 5 */
+               bar = idx - 2;
+       }
+
+       return setup_port(priv, port, bar, offset, board->reg_shift);
+}
+
+/*
+ * Some Titan cards are also a little weird
+ */
+static int
+titan_400l_800l_setup(struct serial_private *priv,
+                     const struct pciserial_board *board,
+                     struct uart_port *port, int idx)
+{
+       unsigned int bar, offset = board->first_offset;
+
+       switch (idx) {
+       case 0:
+               bar = 1;
+               break;
+       case 1:
+               bar = 2;
+               break;
+       default:
+               bar = 4;
+               offset = (idx - 2) * board->uart_offset;
+       }
+
+       return setup_port(priv, port, bar, offset, board->reg_shift);
+}
+
+static int pci_xircom_init(struct pci_dev *dev)
+{
+       msleep(100);
+       return 0;
+}
+
+static int pci_ni8420_init(struct pci_dev *dev)
+{
+       void __iomem *p;
+       unsigned long base, len;
+       unsigned int bar = 0;
+
+       if ((pci_resource_flags(dev, bar) & IORESOURCE_MEM) == 0) {
+               moan_device("no memory in bar", dev);
+               return 0;
+       }
+
+       base = pci_resource_start(dev, bar);
+       len =  pci_resource_len(dev, bar);
+       p = ioremap_nocache(base, len);
+       if (p == NULL)
+               return -ENOMEM;
+
+       /* Enable CPU Interrupt */
+       writel(readl(p + NI8420_INT_ENABLE_REG) | NI8420_INT_ENABLE_BIT,
+              p + NI8420_INT_ENABLE_REG);
+
+       iounmap(p);
+       return 0;
+}
+
+#define MITE_IOWBSR1_WSIZE     0xa
+#define MITE_IOWBSR1_WIN_OFFSET        0x800
+#define MITE_IOWBSR1_WENAB     (1 << 7)
+#define MITE_LCIMR1_IO_IE_0    (1 << 24)
+#define MITE_LCIMR2_SET_CPU_IE (1 << 31)
+#define MITE_IOWCR1_RAMSEL_MASK        0xfffffffe
+
+static int pci_ni8430_init(struct pci_dev *dev)
+{
+       void __iomem *p;
+       unsigned long base, len;
+       u32 device_window;
+       unsigned int bar = 0;
+
+       if ((pci_resource_flags(dev, bar) & IORESOURCE_MEM) == 0) {
+               moan_device("no memory in bar", dev);
+               return 0;
+       }
+
+       base = pci_resource_start(dev, bar);
+       len =  pci_resource_len(dev, bar);
+       p = ioremap_nocache(base, len);
+       if (p == NULL)
+               return -ENOMEM;
+
+       /* Set device window address and size in BAR0 */
+       device_window = ((base + MITE_IOWBSR1_WIN_OFFSET) & 0xffffff00)
+                       | MITE_IOWBSR1_WENAB | MITE_IOWBSR1_WSIZE;
+       writel(device_window, p + MITE_IOWBSR1);
+
+       /* Set window access to go to RAMSEL IO address space */
+       writel((readl(p + MITE_IOWCR1) & MITE_IOWCR1_RAMSEL_MASK),
+              p + MITE_IOWCR1);
+
+       /* Enable IO Bus Interrupt 0 */
+       writel(MITE_LCIMR1_IO_IE_0, p + MITE_LCIMR1);
+
+       /* Enable CPU Interrupt */
+       writel(MITE_LCIMR2_SET_CPU_IE, p + MITE_LCIMR2);
+
+       iounmap(p);
+       return 0;
+}
+
+/* UART Port Control Register */
+#define NI8430_PORTCON 0x0f
+#define NI8430_PORTCON_TXVR_ENABLE     (1 << 3)
+
+static int
+pci_ni8430_setup(struct serial_private *priv,
+                const struct pciserial_board *board,
+                struct uart_port *port, int idx)
+{
+       void __iomem *p;
+       unsigned long base, len;
+       unsigned int bar, offset = board->first_offset;
+
+       if (idx >= board->num_ports)
+               return 1;
+
+       bar = FL_GET_BASE(board->flags);
+       offset += idx * board->uart_offset;
+
+       base = pci_resource_start(priv->dev, bar);
+       len =  pci_resource_len(priv->dev, bar);
+       p = ioremap_nocache(base, len);
+
+       /* enable the transceiver */
+       writeb(readb(p + offset + NI8430_PORTCON) | NI8430_PORTCON_TXVR_ENABLE,
+              p + offset + NI8430_PORTCON);
+
+       iounmap(p);
+
+       return setup_port(priv, port, bar, offset, board->reg_shift);
+}
+
+static int pci_netmos_9900_setup(struct serial_private *priv,
+                               const struct pciserial_board *board,
+                               struct uart_port *port, int idx)
+{
+       unsigned int bar;
+
+       if ((priv->dev->subsystem_device & 0xff00) == 0x3000) {
+               /* netmos apparently orders BARs by datasheet layout, so serial
+                * ports get BARs 0 and 3 (or 1 and 4 for memmapped)
+                */
+               bar = 3 * idx;
+
+               return setup_port(priv, port, bar, 0, board->reg_shift);
+       } else {
+               return pci_default_setup(priv, board, port, idx);
+       }
+}
+
+/* the 99xx series comes with a range of device IDs and a variety
+ * of capabilities:
+ *
+ * 9900 has varying capabilities and can cascade to sub-controllers
+ *   (cascading should be purely internal)
+ * 9904 is hardwired with 4 serial ports
+ * 9912 and 9922 are hardwired with 2 serial ports
+ */
+static int pci_netmos_9900_numports(struct pci_dev *dev)
+{
+       unsigned int c = dev->class;
+       unsigned int pi;
+       unsigned short sub_serports;
+
+       pi = (c & 0xff);
+
+       if (pi == 2) {
+               return 1;
+       } else if ((pi == 0) &&
+                          (dev->device == PCI_DEVICE_ID_NETMOS_9900)) {
+               /* two possibilities: 0x30ps encodes number of parallel and
+                * serial ports, or 0x1000 indicates *something*. This is not
+                * immediately obvious, since the 2s1p+4s configuration seems
+                * to offer all functionality on functions 0..2, while still
+                * advertising the same function 3 as the 4s+2s1p config.
+                */
+               sub_serports = dev->subsystem_device & 0xf;
+               if (sub_serports > 0) {
+                       return sub_serports;
+               } else {
+                       printk(KERN_NOTICE "NetMos/Mostech serial driver ignoring port on ambiguous config.\n");
+                       return 0;
+               }
+       }
+
+       moan_device("unknown NetMos/Mostech program interface", dev);
+       return 0;
+}
+
+static int pci_netmos_init(struct pci_dev *dev)
+{
+       /* subdevice 0x00PS means <P> parallel, <S> serial */
+       unsigned int num_serial = dev->subsystem_device & 0xf;
+
+       if ((dev->device == PCI_DEVICE_ID_NETMOS_9901) ||
+               (dev->device == PCI_DEVICE_ID_NETMOS_9865))
+               return 0;
+
+       if (dev->subsystem_vendor == PCI_VENDOR_ID_IBM &&
+                       dev->subsystem_device == 0x0299)
+               return 0;
+
+       switch (dev->device) { /* FALLTHROUGH on all */
+               case PCI_DEVICE_ID_NETMOS_9904:
+               case PCI_DEVICE_ID_NETMOS_9912:
+               case PCI_DEVICE_ID_NETMOS_9922:
+               case PCI_DEVICE_ID_NETMOS_9900:
+                       num_serial = pci_netmos_9900_numports(dev);
+                       break;
+
+               default:
+                       if (num_serial == 0 ) {
+                               moan_device("unknown NetMos/Mostech device", dev);
+                       }
+       }
+
+       if (num_serial == 0)
+               return -ENODEV;
+
+       return num_serial;
+}
+
+/*
+ * These chips are available with optionally one parallel port and up to
+ * two serial ports. Unfortunately they all have the same product id.
+ *
+ * Basic configuration is done over a region of 32 I/O ports. The base
+ * ioport is called INTA or INTC, depending on docs/other drivers.
+ *
+ * The region of the 32 I/O ports is configured in POSIO0R...
+ */
+
+/* registers */
+#define ITE_887x_MISCR         0x9c
+#define ITE_887x_INTCBAR       0x78
+#define ITE_887x_UARTBAR       0x7c
+#define ITE_887x_PS0BAR                0x10
+#define ITE_887x_POSIO0                0x60
+
+/* I/O space size */
+#define ITE_887x_IOSIZE                32
+/* I/O space size (bits 26-24; 8 bytes = 011b) */
+#define ITE_887x_POSIO_IOSIZE_8                (3 << 24)
+/* I/O space size (bits 26-24; 32 bytes = 101b) */
+#define ITE_887x_POSIO_IOSIZE_32       (5 << 24)
+/* Decoding speed (1 = slow, 2 = medium, 3 = fast) */
+#define ITE_887x_POSIO_SPEED           (3 << 29)
+/* enable IO_Space bit */
+#define ITE_887x_POSIO_ENABLE          (1 << 31)
+
+static int pci_ite887x_init(struct pci_dev *dev)
+{
+       /* inta_addr are the configuration addresses of the ITE */
+       static const short inta_addr[] = { 0x2a0, 0x2c0, 0x220, 0x240, 0x1e0,
+                                                       0x200, 0x280, 0 };
+       int ret, i, type;
+       struct resource *iobase = NULL;
+       u32 miscr, uartbar, ioport;
+
+       /* search for the base-ioport */
+       i = 0;
+       while (inta_addr[i] && iobase == NULL) {
+               iobase = request_region(inta_addr[i], ITE_887x_IOSIZE,
+                                                               "ite887x");
+               if (iobase != NULL) {
+                       /* write POSIO0R - speed | size | ioport */
+                       pci_write_config_dword(dev, ITE_887x_POSIO0,
+                               ITE_887x_POSIO_ENABLE | ITE_887x_POSIO_SPEED |
+                               ITE_887x_POSIO_IOSIZE_32 | inta_addr[i]);
+                       /* write INTCBAR - ioport */
+                       pci_write_config_dword(dev, ITE_887x_INTCBAR,
+                                                               inta_addr[i]);
+                       ret = inb(inta_addr[i]);
+                       if (ret != 0xff) {
+                               /* ioport connected */
+                               break;
+                       }
+                       release_region(iobase->start, ITE_887x_IOSIZE);
+                       iobase = NULL;
+               }
+               i++;
+       }
+
+       if (!inta_addr[i]) {
+               printk(KERN_ERR "ite887x: could not find iobase\n");
+               return -ENODEV;
+       }
+
+       /* start of undocumented type checking (see parport_pc.c) */
+       type = inb(iobase->start + 0x18) & 0x0f;
+
+       switch (type) {
+       case 0x2:       /* ITE8871 (1P) */
+       case 0xa:       /* ITE8875 (1P) */
+               ret = 0;
+               break;
+       case 0xe:       /* ITE8872 (2S1P) */
+               ret = 2;
+               break;
+       case 0x6:       /* ITE8873 (1S) */
+               ret = 1;
+               break;
+       case 0x8:       /* ITE8874 (2S) */
+               ret = 2;
+               break;
+       default:
+               moan_device("Unknown ITE887x", dev);
+               ret = -ENODEV;
+       }
+
+       /* configure all serial ports */
+       for (i = 0; i < ret; i++) {
+               /* read the I/O port from the device */
+               pci_read_config_dword(dev, ITE_887x_PS0BAR + (0x4 * (i + 1)),
+                                                               &ioport);
+               ioport &= 0x0000FF00;   /* the actual base address */
+               pci_write_config_dword(dev, ITE_887x_POSIO0 + (0x4 * (i + 1)),
+                       ITE_887x_POSIO_ENABLE | ITE_887x_POSIO_SPEED |
+                       ITE_887x_POSIO_IOSIZE_8 | ioport);
+
+               /* write the ioport to the UARTBAR */
+               pci_read_config_dword(dev, ITE_887x_UARTBAR, &uartbar);
+               uartbar &= ~(0xffff << (16 * i));       /* clear half the reg */
+               uartbar |= (ioport << (16 * i));        /* set the ioport */
+               pci_write_config_dword(dev, ITE_887x_UARTBAR, uartbar);
+
+               /* get current config */
+               pci_read_config_dword(dev, ITE_887x_MISCR, &miscr);
+               /* disable interrupts (UARTx_Routing[3:0]) */
+               miscr &= ~(0xf << (12 - 4 * i));
+               /* activate the UART (UARTx_En) */
+               miscr |= 1 << (23 - i);
+               /* write new config with activated UART */
+               pci_write_config_dword(dev, ITE_887x_MISCR, miscr);
+       }
+
+       if (ret <= 0) {
+               /* the device has no UARTs if we get here */
+               release_region(iobase->start, ITE_887x_IOSIZE);
+       }
+
+       return ret;
+}
+
+static void __devexit pci_ite887x_exit(struct pci_dev *dev)
+{
+       u32 ioport;
+       /* the ioport is bit 0-15 in POSIO0R */
+       pci_read_config_dword(dev, ITE_887x_POSIO0, &ioport);
+       ioport &= 0xffff;
+       release_region(ioport, ITE_887x_IOSIZE);
+}
+
+/*
+ * Oxford Semiconductor Inc.
+ * Check that device is part of the Tornado range of devices, then determine
+ * the number of ports available on the device.
+ */
+static int pci_oxsemi_tornado_init(struct pci_dev *dev)
+{
+       u8 __iomem *p;
+       unsigned long deviceID;
+       unsigned int  number_uarts = 0;
+
+       /* OxSemi Tornado devices are all 0xCxxx */
+       if (dev->vendor == PCI_VENDOR_ID_OXSEMI &&
+           (dev->device & 0xF000) != 0xC000)
+               return 0;
+
+       p = pci_iomap(dev, 0, 5);
+       if (p == NULL)
+               return -ENOMEM;
+
+       deviceID = ioread32(p);
+       /* Tornado device */
+       if (deviceID == 0x07000200) {
+               number_uarts = ioread8(p + 4);
+               printk(KERN_DEBUG
+                       "%d ports detected on Oxford PCI Express device\n",
+                                                               number_uarts);
+       }
+       pci_iounmap(dev, p);
+       return number_uarts;
+}
+
+static int
+pci_default_setup(struct serial_private *priv,
+                 const struct pciserial_board *board,
+                 struct uart_port *port, int idx)
+{
+       unsigned int bar, offset = board->first_offset, maxnr;
+
+       bar = FL_GET_BASE(board->flags);
+       if (board->flags & FL_BASE_BARS)
+               bar += idx;
+       else
+               offset += idx * board->uart_offset;
+
+       maxnr = (pci_resource_len(priv->dev, bar) - board->first_offset) >>
+               (board->reg_shift + 3);
+
+       if (board->flags & FL_REGION_SZ_CAP && idx >= maxnr)
+               return 1;
+
+       return setup_port(priv, port, bar, offset, board->reg_shift);
+}
+
+static int
+ce4100_serial_setup(struct serial_private *priv,
+                 const struct pciserial_board *board,
+                 struct uart_port *port, int idx)
+{
+       int ret;
+
+       ret = setup_port(priv, port, 0, 0, board->reg_shift);
+       port->iotype = UPIO_MEM32;
+       port->type = PORT_XSCALE;
+       port->flags = (port->flags | UPF_FIXED_PORT | UPF_FIXED_TYPE);
+       port->regshift = 2;
+
+       return ret;
+}
+
+static int
+pci_omegapci_setup(struct serial_private *priv,
+                     const struct pciserial_board *board,
+                     struct uart_port *port, int idx)
+{
+       return setup_port(priv, port, 2, idx * 8, 0);
+}
+
+static int skip_tx_en_setup(struct serial_private *priv,
+                       const struct pciserial_board *board,
+                       struct uart_port *port, int idx)
+{
+       port->flags |= UPF_NO_TXEN_TEST;
+       printk(KERN_DEBUG "serial8250: skipping TxEn test for device "
+                         "[%04x:%04x] subsystem [%04x:%04x]\n",
+                         priv->dev->vendor,
+                         priv->dev->device,
+                         priv->dev->subsystem_vendor,
+                         priv->dev->subsystem_device);
+
+       return pci_default_setup(priv, board, port, idx);
+}
+
+static int kt_serial_setup(struct serial_private *priv,
+                          const struct pciserial_board *board,
+                          struct uart_port *port, int idx)
+{
+       port->flags |= UPF_IIR_ONCE;
+       return skip_tx_en_setup(priv, board, port, idx);
+}
+
+static int pci_eg20t_init(struct pci_dev *dev)
+{
+#if defined(CONFIG_SERIAL_PCH_UART) || defined(CONFIG_SERIAL_PCH_UART_MODULE)
+       return -ENODEV;
+#else
+       return 0;
+#endif
+}
+
+static int
+pci_xr17c154_setup(struct serial_private *priv,
+                 const struct pciserial_board *board,
+                 struct uart_port *port, int idx)
+{
+       port->flags |= UPF_EXAR_EFR;
+       return pci_default_setup(priv, board, port, idx);
+}
+
+static int try_enable_msi(struct pci_dev *dev)
+{
+       /* use msi if available, but fallback to legacy otherwise */
+       pci_enable_msi(dev);
+       return 0;
+}
+
+static void disable_msi(struct pci_dev *dev)
+{
+       pci_disable_msi(dev);
+}
+
+#define PCI_VENDOR_ID_SBSMODULARIO     0x124B
+#define PCI_SUBVENDOR_ID_SBSMODULARIO  0x124B
+#define PCI_DEVICE_ID_OCTPRO           0x0001
+#define PCI_SUBDEVICE_ID_OCTPRO232     0x0108
+#define PCI_SUBDEVICE_ID_OCTPRO422     0x0208
+#define PCI_SUBDEVICE_ID_POCTAL232     0x0308
+#define PCI_SUBDEVICE_ID_POCTAL422     0x0408
+#define PCI_VENDOR_ID_ADVANTECH                0x13fe
+#define PCI_DEVICE_ID_INTEL_CE4100_UART 0x2e66
+#define PCI_DEVICE_ID_ADVANTECH_PCI3620        0x3620
+#define PCI_DEVICE_ID_TITAN_200I       0x8028
+#define PCI_DEVICE_ID_TITAN_400I       0x8048
+#define PCI_DEVICE_ID_TITAN_800I       0x8088
+#define PCI_DEVICE_ID_TITAN_800EH      0xA007
+#define PCI_DEVICE_ID_TITAN_800EHB     0xA008
+#define PCI_DEVICE_ID_TITAN_400EH      0xA009
+#define PCI_DEVICE_ID_TITAN_100E       0xA010
+#define PCI_DEVICE_ID_TITAN_200E       0xA012
+#define PCI_DEVICE_ID_TITAN_400E       0xA013
+#define PCI_DEVICE_ID_TITAN_800E       0xA014
+#define PCI_DEVICE_ID_TITAN_200EI      0xA016
+#define PCI_DEVICE_ID_TITAN_200EISI    0xA017
+#define PCI_DEVICE_ID_TITAN_400V3      0xA310
+#define PCI_DEVICE_ID_TITAN_410V3      0xA312
+#define PCI_DEVICE_ID_TITAN_800V3      0xA314
+#define PCI_DEVICE_ID_TITAN_800V3B     0xA315
+#define PCI_DEVICE_ID_OXSEMI_16PCI958  0x9538
+#define PCIE_DEVICE_ID_NEO_2_OX_IBM    0x00F6
+#define PCI_DEVICE_ID_PLX_CRONYX_OMEGA 0xc001
+#define PCI_DEVICE_ID_INTEL_PATSBURG_KT 0x1d3d
+
+/* Unknown vendors/cards - this should not be in linux/pci_ids.h */
+#define PCI_SUBDEVICE_ID_UNKNOWN_0x1584        0x1584
+
+/*
+ * Master list of serial port init/setup/exit quirks.
+ * This does not describe the general nature of the port.
+ * (ie, baud base, number and location of ports, etc)
+ *
+ * This list is ordered alphabetically by vendor then device.
+ * Specific entries must come before more generic entries.
+ */
+static struct pci_serial_quirk pci_serial_quirks[] __refdata = {
+       /*
+       * ADDI-DATA GmbH communication cards <info@addi-data.com>
+       */
+       {
+               .vendor         = PCI_VENDOR_ID_ADDIDATA_OLD,
+               .device         = PCI_DEVICE_ID_ADDIDATA_APCI7800,
+               .subvendor      = PCI_ANY_ID,
+               .subdevice      = PCI_ANY_ID,
+               .setup          = addidata_apci7800_setup,
+       },
+       /*
+        * AFAVLAB cards - these may be called via parport_serial
+        *  It is not clear whether this applies to all products.
+        */
+       {
+               .vendor         = PCI_VENDOR_ID_AFAVLAB,
+               .device         = PCI_ANY_ID,
+               .subvendor      = PCI_ANY_ID,
+               .subdevice      = PCI_ANY_ID,
+               .setup          = afavlab_setup,
+       },
+       /*
+        * HP Diva
+        */
+       {
+               .vendor         = PCI_VENDOR_ID_HP,
+               .device         = PCI_DEVICE_ID_HP_DIVA,
+               .subvendor      = PCI_ANY_ID,
+               .subdevice      = PCI_ANY_ID,
+               .init           = pci_hp_diva_init,
+               .setup          = pci_hp_diva_setup,
+       },
+       /*
+        * Intel
+        */
+       {
+               .vendor         = PCI_VENDOR_ID_INTEL,
+               .device         = PCI_DEVICE_ID_INTEL_80960_RP,
+               .subvendor      = 0xe4bf,
+               .subdevice      = PCI_ANY_ID,
+               .init           = pci_inteli960ni_init,
+               .setup          = pci_default_setup,
+       },
+       {
+               .vendor         = PCI_VENDOR_ID_INTEL,
+               .device         = PCI_DEVICE_ID_INTEL_8257X_SOL,
+               .subvendor      = PCI_ANY_ID,
+               .subdevice      = PCI_ANY_ID,
+               .setup          = skip_tx_en_setup,
+       },
+       {
+               .vendor         = PCI_VENDOR_ID_INTEL,
+               .device         = PCI_DEVICE_ID_INTEL_82573L_SOL,
+               .subvendor      = PCI_ANY_ID,
+               .subdevice      = PCI_ANY_ID,
+               .setup          = skip_tx_en_setup,
+       },
+       {
+               .vendor         = PCI_VENDOR_ID_INTEL,
+               .device         = PCI_DEVICE_ID_INTEL_82573E_SOL,
+               .subvendor      = PCI_ANY_ID,
+               .subdevice      = PCI_ANY_ID,
+               .setup          = skip_tx_en_setup,
+       },
+       {
+               .vendor         = PCI_VENDOR_ID_INTEL,
+               .device         = PCI_DEVICE_ID_INTEL_CE4100_UART,
+               .subvendor      = PCI_ANY_ID,
+               .subdevice      = PCI_ANY_ID,
+               .setup          = ce4100_serial_setup,
+       },
+       {
+               .vendor         = PCI_VENDOR_ID_INTEL,
+               .device         = PCI_DEVICE_ID_INTEL_PATSBURG_KT,
+               .subvendor      = PCI_ANY_ID,
+               .subdevice      = PCI_ANY_ID,
+               .init           = try_enable_msi,
+               .setup          = kt_serial_setup,
+               .exit           = disable_msi,
+       },
+       /*
+        * ITE
+        */
+       {
+               .vendor         = PCI_VENDOR_ID_ITE,
+               .device         = PCI_DEVICE_ID_ITE_8872,
+               .subvendor      = PCI_ANY_ID,
+               .subdevice      = PCI_ANY_ID,
+               .init           = pci_ite887x_init,
+               .setup          = pci_default_setup,
+               .exit           = __devexit_p(pci_ite887x_exit),
+       },
+       /*
+        * National Instruments
+        */
+       {
+               .vendor         = PCI_VENDOR_ID_NI,
+               .device         = PCI_DEVICE_ID_NI_PCI23216,
+               .subvendor      = PCI_ANY_ID,
+               .subdevice      = PCI_ANY_ID,
+               .init           = pci_ni8420_init,
+               .setup          = pci_default_setup,
+               .exit           = __devexit_p(pci_ni8420_exit),
+       },
+       {
+               .vendor         = PCI_VENDOR_ID_NI,
+               .device         = PCI_DEVICE_ID_NI_PCI2328,
+               .subvendor      = PCI_ANY_ID,
+               .subdevice      = PCI_ANY_ID,
+               .init           = pci_ni8420_init,
+               .setup          = pci_default_setup,
+               .exit           = __devexit_p(pci_ni8420_exit),
+       },
+       {
+               .vendor         = PCI_VENDOR_ID_NI,
+               .device         = PCI_DEVICE_ID_NI_PCI2324,
+               .subvendor      = PCI_ANY_ID,
+               .subdevice      = PCI_ANY_ID,
+               .init           = pci_ni8420_init,
+               .setup          = pci_default_setup,
+               .exit           = __devexit_p(pci_ni8420_exit),
+       },
+       {
+               .vendor         = PCI_VENDOR_ID_NI,
+               .device         = PCI_DEVICE_ID_NI_PCI2322,
+               .subvendor      = PCI_ANY_ID,
+               .subdevice      = PCI_ANY_ID,
+               .init           = pci_ni8420_init,
+               .setup          = pci_default_setup,
+               .exit           = __devexit_p(pci_ni8420_exit),
+       },
+       {
+               .vendor         = PCI_VENDOR_ID_NI,
+               .device         = PCI_DEVICE_ID_NI_PCI2324I,
+               .subvendor      = PCI_ANY_ID,
+               .subdevice      = PCI_ANY_ID,
+               .init           = pci_ni8420_init,
+               .setup          = pci_default_setup,
+               .exit           = __devexit_p(pci_ni8420_exit),
+       },
+       {
+               .vendor         = PCI_VENDOR_ID_NI,
+               .device         = PCI_DEVICE_ID_NI_PCI2322I,
+               .subvendor      = PCI_ANY_ID,
+               .subdevice      = PCI_ANY_ID,
+               .init           = pci_ni8420_init,
+               .setup          = pci_default_setup,
+               .exit           = __devexit_p(pci_ni8420_exit),
+       },
+       {
+               .vendor         = PCI_VENDOR_ID_NI,
+               .device         = PCI_DEVICE_ID_NI_PXI8420_23216,
+               .subvendor      = PCI_ANY_ID,
+               .subdevice      = PCI_ANY_ID,
+               .init           = pci_ni8420_init,
+               .setup          = pci_default_setup,
+               .exit           = __devexit_p(pci_ni8420_exit),
+       },
+       {
+               .vendor         = PCI_VENDOR_ID_NI,
+               .device         = PCI_DEVICE_ID_NI_PXI8420_2328,
+               .subvendor      = PCI_ANY_ID,
+               .subdevice      = PCI_ANY_ID,
+               .init           = pci_ni8420_init,
+               .setup          = pci_default_setup,
+               .exit           = __devexit_p(pci_ni8420_exit),
+       },
+       {
+               .vendor         = PCI_VENDOR_ID_NI,
+               .device         = PCI_DEVICE_ID_NI_PXI8420_2324,
+               .subvendor      = PCI_ANY_ID,
+               .subdevice      = PCI_ANY_ID,
+               .init           = pci_ni8420_init,
+               .setup          = pci_default_setup,
+               .exit           = __devexit_p(pci_ni8420_exit),
+       },
+       {
+               .vendor         = PCI_VENDOR_ID_NI,
+               .device         = PCI_DEVICE_ID_NI_PXI8420_2322,
+               .subvendor      = PCI_ANY_ID,
+               .subdevice      = PCI_ANY_ID,
+               .init           = pci_ni8420_init,
+               .setup          = pci_default_setup,
+               .exit           = __devexit_p(pci_ni8420_exit),
+       },
+       {
+               .vendor         = PCI_VENDOR_ID_NI,
+               .device         = PCI_DEVICE_ID_NI_PXI8422_2324,
+               .subvendor      = PCI_ANY_ID,
+               .subdevice      = PCI_ANY_ID,
+               .init           = pci_ni8420_init,
+               .setup          = pci_default_setup,
+               .exit           = __devexit_p(pci_ni8420_exit),
+       },
+       {
+               .vendor         = PCI_VENDOR_ID_NI,
+               .device         = PCI_DEVICE_ID_NI_PXI8422_2322,
+               .subvendor      = PCI_ANY_ID,
+               .subdevice      = PCI_ANY_ID,
+               .init           = pci_ni8420_init,
+               .setup          = pci_default_setup,
+               .exit           = __devexit_p(pci_ni8420_exit),
+       },
+       {
+               .vendor         = PCI_VENDOR_ID_NI,
+               .device         = PCI_ANY_ID,
+               .subvendor      = PCI_ANY_ID,
+               .subdevice      = PCI_ANY_ID,
+               .init           = pci_ni8430_init,
+               .setup          = pci_ni8430_setup,
+               .exit           = __devexit_p(pci_ni8430_exit),
+       },
+       /*
+        * Panacom
+        */
+       {
+               .vendor         = PCI_VENDOR_ID_PANACOM,
+               .device         = PCI_DEVICE_ID_PANACOM_QUADMODEM,
+               .subvendor      = PCI_ANY_ID,
+               .subdevice      = PCI_ANY_ID,
+               .init           = pci_plx9050_init,
+               .setup          = pci_default_setup,
+               .exit           = __devexit_p(pci_plx9050_exit),
+       },
+       {
+               .vendor         = PCI_VENDOR_ID_PANACOM,
+               .device         = PCI_DEVICE_ID_PANACOM_DUALMODEM,
+               .subvendor      = PCI_ANY_ID,
+               .subdevice      = PCI_ANY_ID,
+               .init           = pci_plx9050_init,
+               .setup          = pci_default_setup,
+               .exit           = __devexit_p(pci_plx9050_exit),
+       },
+       /*
+        * PLX
+        */
+       {
+               .vendor         = PCI_VENDOR_ID_PLX,
+               .device         = PCI_DEVICE_ID_PLX_9030,
+               .subvendor      = PCI_SUBVENDOR_ID_PERLE,
+               .subdevice      = PCI_ANY_ID,
+               .setup          = pci_default_setup,
+       },
+       {
+               .vendor         = PCI_VENDOR_ID_PLX,
+               .device         = PCI_DEVICE_ID_PLX_9050,
+               .subvendor      = PCI_SUBVENDOR_ID_EXSYS,
+               .subdevice      = PCI_SUBDEVICE_ID_EXSYS_4055,
+               .init           = pci_plx9050_init,
+               .setup          = pci_default_setup,
+               .exit           = __devexit_p(pci_plx9050_exit),
+       },
+       {
+               .vendor         = PCI_VENDOR_ID_PLX,
+               .device         = PCI_DEVICE_ID_PLX_9050,
+               .subvendor      = PCI_SUBVENDOR_ID_KEYSPAN,
+               .subdevice      = PCI_SUBDEVICE_ID_KEYSPAN_SX2,
+               .init           = pci_plx9050_init,
+               .setup          = pci_default_setup,
+               .exit           = __devexit_p(pci_plx9050_exit),
+       },
+       {
+               .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           = __devexit_p(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,
+               .init           = pci_plx9050_init,
+               .setup          = pci_default_setup,
+               .exit           = __devexit_p(pci_plx9050_exit),
+       },
+       /*
+        * SBS Technologies, Inc., PMC-OCTALPRO 232
+        */
+       {
+               .vendor         = PCI_VENDOR_ID_SBSMODULARIO,
+               .device         = PCI_DEVICE_ID_OCTPRO,
+               .subvendor      = PCI_SUBVENDOR_ID_SBSMODULARIO,
+               .subdevice      = PCI_SUBDEVICE_ID_OCTPRO232,
+               .init           = sbs_init,
+               .setup          = sbs_setup,
+               .exit           = __devexit_p(sbs_exit),
+       },
+       /*
+        * SBS Technologies, Inc., PMC-OCTALPRO 422
+        */
+       {
+               .vendor         = PCI_VENDOR_ID_SBSMODULARIO,
+               .device         = PCI_DEVICE_ID_OCTPRO,
+               .subvendor      = PCI_SUBVENDOR_ID_SBSMODULARIO,
+               .subdevice      = PCI_SUBDEVICE_ID_OCTPRO422,
+               .init           = sbs_init,
+               .setup          = sbs_setup,
+               .exit           = __devexit_p(sbs_exit),
+       },
+       /*
+        * SBS Technologies, Inc., P-Octal 232
+        */
+       {
+               .vendor         = PCI_VENDOR_ID_SBSMODULARIO,
+               .device         = PCI_DEVICE_ID_OCTPRO,
+               .subvendor      = PCI_SUBVENDOR_ID_SBSMODULARIO,
+               .subdevice      = PCI_SUBDEVICE_ID_POCTAL232,
+               .init           = sbs_init,
+               .setup          = sbs_setup,
+               .exit           = __devexit_p(sbs_exit),
+       },
+       /*
+        * SBS Technologies, Inc., P-Octal 422
+        */
+       {
+               .vendor         = PCI_VENDOR_ID_SBSMODULARIO,
+               .device         = PCI_DEVICE_ID_OCTPRO,
+               .subvendor      = PCI_SUBVENDOR_ID_SBSMODULARIO,
+               .subdevice      = PCI_SUBDEVICE_ID_POCTAL422,
+               .init           = sbs_init,
+               .setup          = sbs_setup,
+               .exit           = __devexit_p(sbs_exit),
+       },
+       /*
+        * SIIG cards - these may be called via parport_serial
+        */
+       {
+               .vendor         = PCI_VENDOR_ID_SIIG,
+               .device         = PCI_ANY_ID,
+               .subvendor      = PCI_ANY_ID,
+               .subdevice      = PCI_ANY_ID,
+               .init           = pci_siig_init,
+               .setup          = pci_siig_setup,
+       },
+       /*
+        * Titan cards
+        */
+       {
+               .vendor         = PCI_VENDOR_ID_TITAN,
+               .device         = PCI_DEVICE_ID_TITAN_400L,
+               .subvendor      = PCI_ANY_ID,
+               .subdevice      = PCI_ANY_ID,
+               .setup          = titan_400l_800l_setup,
+       },
+       {
+               .vendor         = PCI_VENDOR_ID_TITAN,
+               .device         = PCI_DEVICE_ID_TITAN_800L,
+               .subvendor      = PCI_ANY_ID,
+               .subdevice      = PCI_ANY_ID,
+               .setup          = titan_400l_800l_setup,
+       },
+       /*
+        * Timedia cards
+        */
+       {
+               .vendor         = PCI_VENDOR_ID_TIMEDIA,
+               .device         = PCI_DEVICE_ID_TIMEDIA_1889,
+               .subvendor      = PCI_VENDOR_ID_TIMEDIA,
+               .subdevice      = PCI_ANY_ID,
+               .probe          = pci_timedia_probe,
+               .init           = pci_timedia_init,
+               .setup          = pci_timedia_setup,
+       },
+       {
+               .vendor         = PCI_VENDOR_ID_TIMEDIA,
+               .device         = PCI_ANY_ID,
+               .subvendor      = PCI_ANY_ID,
+               .subdevice      = PCI_ANY_ID,
+               .setup          = pci_timedia_setup,
+       },
+       /*
+        * Exar cards
+        */
+       {
+               .vendor = PCI_VENDOR_ID_EXAR,
+               .device = PCI_DEVICE_ID_EXAR_XR17C152,
+               .subvendor      = PCI_ANY_ID,
+               .subdevice      = PCI_ANY_ID,
+               .setup          = pci_xr17c154_setup,
+       },
+       {
+               .vendor = PCI_VENDOR_ID_EXAR,
+               .device = PCI_DEVICE_ID_EXAR_XR17C154,
+               .subvendor      = PCI_ANY_ID,
+               .subdevice      = PCI_ANY_ID,
+               .setup          = pci_xr17c154_setup,
+       },
+       {
+               .vendor = PCI_VENDOR_ID_EXAR,
+               .device = PCI_DEVICE_ID_EXAR_XR17C158,
+               .subvendor      = PCI_ANY_ID,
+               .subdevice      = PCI_ANY_ID,
+               .setup          = pci_xr17c154_setup,
+       },
+       /*
+        * Xircom cards
+        */
+       {
+               .vendor         = PCI_VENDOR_ID_XIRCOM,
+               .device         = PCI_DEVICE_ID_XIRCOM_X3201_MDM,
+               .subvendor      = PCI_ANY_ID,
+               .subdevice      = PCI_ANY_ID,
+               .init           = pci_xircom_init,
+               .setup          = pci_default_setup,
+       },
+       /*
+        * Netmos cards - these may be called via parport_serial
+        */
+       {
+               .vendor         = PCI_VENDOR_ID_NETMOS,
+               .device         = PCI_ANY_ID,
+               .subvendor      = PCI_ANY_ID,
+               .subdevice      = PCI_ANY_ID,
+               .init           = pci_netmos_init,
+               .setup          = pci_netmos_9900_setup,
+       },
+       /*
+        * For Oxford Semiconductor Tornado based devices
+        */
+       {
+               .vendor         = PCI_VENDOR_ID_OXSEMI,
+               .device         = PCI_ANY_ID,
+               .subvendor      = PCI_ANY_ID,
+               .subdevice      = PCI_ANY_ID,
+               .init           = pci_oxsemi_tornado_init,
+               .setup          = pci_default_setup,
+       },
+       {
+               .vendor         = PCI_VENDOR_ID_MAINPINE,
+               .device         = PCI_ANY_ID,
+               .subvendor      = PCI_ANY_ID,
+               .subdevice      = PCI_ANY_ID,
+               .init           = pci_oxsemi_tornado_init,
+               .setup          = pci_default_setup,
+       },
+       {
+               .vendor         = PCI_VENDOR_ID_DIGI,
+               .device         = PCIE_DEVICE_ID_NEO_2_OX_IBM,
+               .subvendor              = PCI_SUBVENDOR_ID_IBM,
+               .subdevice              = PCI_ANY_ID,
+               .init                   = pci_oxsemi_tornado_init,
+               .setup          = pci_default_setup,
+       },
+       {
+               .vendor         = PCI_VENDOR_ID_INTEL,
+               .device         = 0x8811,
+               .init           = pci_eg20t_init,
+               .setup          = pci_default_setup,
+       },
+       {
+               .vendor         = PCI_VENDOR_ID_INTEL,
+               .device         = 0x8812,
+               .init           = pci_eg20t_init,
+               .setup          = pci_default_setup,
+       },
+       {
+               .vendor         = PCI_VENDOR_ID_INTEL,
+               .device         = 0x8813,
+               .init           = pci_eg20t_init,
+               .setup          = pci_default_setup,
+       },
+       {
+               .vendor         = PCI_VENDOR_ID_INTEL,
+               .device         = 0x8814,
+               .init           = pci_eg20t_init,
+               .setup          = pci_default_setup,
+       },
+       {
+               .vendor         = 0x10DB,
+               .device         = 0x8027,
+               .init           = pci_eg20t_init,
+               .setup          = pci_default_setup,
+       },
+       {
+               .vendor         = 0x10DB,
+               .device         = 0x8028,
+               .init           = pci_eg20t_init,
+               .setup          = pci_default_setup,
+       },
+       {
+               .vendor         = 0x10DB,
+               .device         = 0x8029,
+               .init           = pci_eg20t_init,
+               .setup          = pci_default_setup,
+       },
+       {
+               .vendor         = 0x10DB,
+               .device         = 0x800C,
+               .init           = pci_eg20t_init,
+               .setup          = pci_default_setup,
+       },
+       {
+               .vendor         = 0x10DB,
+               .device         = 0x800D,
+               .init           = pci_eg20t_init,
+               .setup          = pci_default_setup,
+       },
+       /*
+        * Cronyx Omega PCI (PLX-chip based)
+        */
+       {
+               .vendor         = PCI_VENDOR_ID_PLX,
+               .device         = PCI_DEVICE_ID_PLX_CRONYX_OMEGA,
+               .subvendor      = PCI_ANY_ID,
+               .subdevice      = PCI_ANY_ID,
+               .setup          = pci_omegapci_setup,
+        },
+       /*
+        * Default "match everything" terminator entry
+        */
+       {
+               .vendor         = PCI_ANY_ID,
+               .device         = PCI_ANY_ID,
+               .subvendor      = PCI_ANY_ID,
+               .subdevice      = PCI_ANY_ID,
+               .setup          = pci_default_setup,
+       }
+};
+
+static inline int quirk_id_matches(u32 quirk_id, u32 dev_id)
+{
+       return quirk_id == PCI_ANY_ID || quirk_id == dev_id;
+}
+
+static struct pci_serial_quirk *find_quirk(struct pci_dev *dev)
+{
+       struct pci_serial_quirk *quirk;
+
+       for (quirk = pci_serial_quirks; ; quirk++)
+               if (quirk_id_matches(quirk->vendor, dev->vendor) &&
+                   quirk_id_matches(quirk->device, dev->device) &&
+                   quirk_id_matches(quirk->subvendor, dev->subsystem_vendor) &&
+                   quirk_id_matches(quirk->subdevice, dev->subsystem_device))
+                       break;
+       return quirk;
+}
+
+static inline int get_pci_irq(struct pci_dev *dev,
+                               const struct pciserial_board *board)
+{
+       if (board->flags & FL_NOIRQ)
+               return 0;
+       else
+               return dev->irq;
+}
+
+/*
+ * This is the configuration table for all of the PCI serial boards
+ * which we support.  It is directly indexed by the pci_board_num_t enum
+ * value, which is encoded in the pci_device_id PCI probe table's
+ * driver_data member.
+ *
+ * The makeup of these names are:
+ *  pbn_bn{_bt}_n_baud{_offsetinhex}
+ *
+ *  bn         = PCI BAR number
+ *  bt         = Index using PCI BARs
+ *  n          = number of serial ports
+ *  baud       = baud rate
+ *  offsetinhex        = offset for each sequential port (in hex)
+ *
+ * This table is sorted by (in order): bn, bt, baud, offsetindex, n.
+ *
+ * Please note: in theory if n = 1, _bt infix should make no difference.
+ * ie, pbn_b0_1_115200 is the same as pbn_b0_bt_1_115200
+ */
+enum pci_board_num_t {
+       pbn_default = 0,
+
+       pbn_b0_1_115200,
+       pbn_b0_2_115200,
+       pbn_b0_4_115200,
+       pbn_b0_5_115200,
+       pbn_b0_8_115200,
+
+       pbn_b0_1_921600,
+       pbn_b0_2_921600,
+       pbn_b0_4_921600,
+
+       pbn_b0_2_1130000,
+
+       pbn_b0_4_1152000,
+
+       pbn_b0_2_1843200,
+       pbn_b0_4_1843200,
+
+       pbn_b0_2_1843200_200,
+       pbn_b0_4_1843200_200,
+       pbn_b0_8_1843200_200,
+
+       pbn_b0_1_4000000,
+
+       pbn_b0_bt_1_115200,
+       pbn_b0_bt_2_115200,
+       pbn_b0_bt_4_115200,
+       pbn_b0_bt_8_115200,
+
+       pbn_b0_bt_1_460800,
+       pbn_b0_bt_2_460800,
+       pbn_b0_bt_4_460800,
+
+       pbn_b0_bt_1_921600,
+       pbn_b0_bt_2_921600,
+       pbn_b0_bt_4_921600,
+       pbn_b0_bt_8_921600,
+
+       pbn_b1_1_115200,
+       pbn_b1_2_115200,
+       pbn_b1_4_115200,
+       pbn_b1_8_115200,
+       pbn_b1_16_115200,
+
+       pbn_b1_1_921600,
+       pbn_b1_2_921600,
+       pbn_b1_4_921600,
+       pbn_b1_8_921600,
+
+       pbn_b1_2_1250000,
+
+       pbn_b1_bt_1_115200,
+       pbn_b1_bt_2_115200,
+       pbn_b1_bt_4_115200,
+
+       pbn_b1_bt_2_921600,
+
+       pbn_b1_1_1382400,
+       pbn_b1_2_1382400,
+       pbn_b1_4_1382400,
+       pbn_b1_8_1382400,
+
+       pbn_b2_1_115200,
+       pbn_b2_2_115200,
+       pbn_b2_4_115200,
+       pbn_b2_8_115200,
+
+       pbn_b2_1_460800,
+       pbn_b2_4_460800,
+       pbn_b2_8_460800,
+       pbn_b2_16_460800,
+
+       pbn_b2_1_921600,
+       pbn_b2_4_921600,
+       pbn_b2_8_921600,
+
+       pbn_b2_8_1152000,
+
+       pbn_b2_bt_1_115200,
+       pbn_b2_bt_2_115200,
+       pbn_b2_bt_4_115200,
+
+       pbn_b2_bt_2_921600,
+       pbn_b2_bt_4_921600,
+
+       pbn_b3_2_115200,
+       pbn_b3_4_115200,
+       pbn_b3_8_115200,
+
+       pbn_b4_bt_2_921600,
+       pbn_b4_bt_4_921600,
+       pbn_b4_bt_8_921600,
+
+       /*
+        * Board-specific versions.
+        */
+       pbn_panacom,
+       pbn_panacom2,
+       pbn_panacom4,
+       pbn_exsys_4055,
+       pbn_plx_romulus,
+       pbn_oxsemi,
+       pbn_oxsemi_1_4000000,
+       pbn_oxsemi_2_4000000,
+       pbn_oxsemi_4_4000000,
+       pbn_oxsemi_8_4000000,
+       pbn_intel_i960,
+       pbn_sgi_ioc3,
+       pbn_computone_4,
+       pbn_computone_6,
+       pbn_computone_8,
+       pbn_sbsxrsio,
+       pbn_exar_XR17C152,
+       pbn_exar_XR17C154,
+       pbn_exar_XR17C158,
+       pbn_exar_ibm_saturn,
+       pbn_pasemi_1682M,
+       pbn_ni8430_2,
+       pbn_ni8430_4,
+       pbn_ni8430_8,
+       pbn_ni8430_16,
+       pbn_ADDIDATA_PCIe_1_3906250,
+       pbn_ADDIDATA_PCIe_2_3906250,
+       pbn_ADDIDATA_PCIe_4_3906250,
+       pbn_ADDIDATA_PCIe_8_3906250,
+       pbn_ce4100_1_115200,
+       pbn_omegapci,
+       pbn_NETMOS9900_2s_115200,
+};
+
+/*
+ * uart_offset - the space between channels
+ * reg_shift   - describes how the UART registers are mapped
+ *               to PCI memory by the card.
+ * For example IER register on SBS, Inc. PMC-OctPro is located at
+ * offset 0x10 from the UART base, while UART_IER is defined as 1
+ * in include/linux/serial_reg.h,
+ * see first lines of serial_in() and serial_out() in 8250.c
+*/
+
+static struct pciserial_board pci_boards[] __devinitdata = {
+       [pbn_default] = {
+               .flags          = FL_BASE0,
+               .num_ports      = 1,
+               .base_baud      = 115200,
+               .uart_offset    = 8,
+       },
+       [pbn_b0_1_115200] = {
+               .flags          = FL_BASE0,
+               .num_ports      = 1,
+               .base_baud      = 115200,
+               .uart_offset    = 8,
+       },
+       [pbn_b0_2_115200] = {
+               .flags          = FL_BASE0,
+               .num_ports      = 2,
+               .base_baud      = 115200,
+               .uart_offset    = 8,
+       },
+       [pbn_b0_4_115200] = {
+               .flags          = FL_BASE0,
+               .num_ports      = 4,
+               .base_baud      = 115200,
+               .uart_offset    = 8,
+       },
+       [pbn_b0_5_115200] = {
+               .flags          = FL_BASE0,
+               .num_ports      = 5,
+               .base_baud      = 115200,
+               .uart_offset    = 8,
+       },
+       [pbn_b0_8_115200] = {
+               .flags          = FL_BASE0,
+               .num_ports      = 8,
+               .base_baud      = 115200,
+               .uart_offset    = 8,
+       },
+       [pbn_b0_1_921600] = {
+               .flags          = FL_BASE0,
+               .num_ports      = 1,
+               .base_baud      = 921600,
+               .uart_offset    = 8,
+       },
+       [pbn_b0_2_921600] = {
+               .flags          = FL_BASE0,
+               .num_ports      = 2,
+               .base_baud      = 921600,
+               .uart_offset    = 8,
+       },
+       [pbn_b0_4_921600] = {
+               .flags          = FL_BASE0,
+               .num_ports      = 4,
+               .base_baud      = 921600,
+               .uart_offset    = 8,
+       },
+
+       [pbn_b0_2_1130000] = {
+               .flags          = FL_BASE0,
+               .num_ports      = 2,
+               .base_baud      = 1130000,
+               .uart_offset    = 8,
+       },
+
+       [pbn_b0_4_1152000] = {
+               .flags          = FL_BASE0,
+               .num_ports      = 4,
+               .base_baud      = 1152000,
+               .uart_offset    = 8,
+       },
+
+       [pbn_b0_2_1843200] = {
+               .flags          = FL_BASE0,
+               .num_ports      = 2,
+               .base_baud      = 1843200,
+               .uart_offset    = 8,
+       },
+       [pbn_b0_4_1843200] = {
+               .flags          = FL_BASE0,
+               .num_ports      = 4,
+               .base_baud      = 1843200,
+               .uart_offset    = 8,
+       },
+
+       [pbn_b0_2_1843200_200] = {
+               .flags          = FL_BASE0,
+               .num_ports      = 2,
+               .base_baud      = 1843200,
+               .uart_offset    = 0x200,
+       },
+       [pbn_b0_4_1843200_200] = {
+               .flags          = FL_BASE0,
+               .num_ports      = 4,
+               .base_baud      = 1843200,
+               .uart_offset    = 0x200,
+       },
+       [pbn_b0_8_1843200_200] = {
+               .flags          = FL_BASE0,
+               .num_ports      = 8,
+               .base_baud      = 1843200,
+               .uart_offset    = 0x200,
+       },
+       [pbn_b0_1_4000000] = {
+               .flags          = FL_BASE0,
+               .num_ports      = 1,
+               .base_baud      = 4000000,
+               .uart_offset    = 8,
+       },
+
+       [pbn_b0_bt_1_115200] = {
+               .flags          = FL_BASE0|FL_BASE_BARS,
+               .num_ports      = 1,
+               .base_baud      = 115200,
+               .uart_offset    = 8,
+       },
+       [pbn_b0_bt_2_115200] = {
+               .flags          = FL_BASE0|FL_BASE_BARS,
+               .num_ports      = 2,
+               .base_baud      = 115200,
+               .uart_offset    = 8,
+       },
+       [pbn_b0_bt_4_115200] = {
+               .flags          = FL_BASE0|FL_BASE_BARS,
+               .num_ports      = 4,
+               .base_baud      = 115200,
+               .uart_offset    = 8,
+       },
+       [pbn_b0_bt_8_115200] = {
+               .flags          = FL_BASE0|FL_BASE_BARS,
+               .num_ports      = 8,
+               .base_baud      = 115200,
+               .uart_offset    = 8,
+       },
+
+       [pbn_b0_bt_1_460800] = {
+               .flags          = FL_BASE0|FL_BASE_BARS,
+               .num_ports      = 1,
+               .base_baud      = 460800,
+               .uart_offset    = 8,
+       },
+       [pbn_b0_bt_2_460800] = {
+               .flags          = FL_BASE0|FL_BASE_BARS,
+               .num_ports      = 2,
+               .base_baud      = 460800,
+               .uart_offset    = 8,
+       },
+       [pbn_b0_bt_4_460800] = {
+               .flags          = FL_BASE0|FL_BASE_BARS,
+               .num_ports      = 4,
+               .base_baud      = 460800,
+               .uart_offset    = 8,
+       },
+
+       [pbn_b0_bt_1_921600] = {
+               .flags          = FL_BASE0|FL_BASE_BARS,
+               .num_ports      = 1,
+               .base_baud      = 921600,
+               .uart_offset    = 8,
+       },
+       [pbn_b0_bt_2_921600] = {
+               .flags          = FL_BASE0|FL_BASE_BARS,
+               .num_ports      = 2,
+               .base_baud      = 921600,
+               .uart_offset    = 8,
+       },
+       [pbn_b0_bt_4_921600] = {
+               .flags          = FL_BASE0|FL_BASE_BARS,
+               .num_ports      = 4,
+               .base_baud      = 921600,
+               .uart_offset    = 8,
+       },
+       [pbn_b0_bt_8_921600] = {
+               .flags          = FL_BASE0|FL_BASE_BARS,
+               .num_ports      = 8,
+               .base_baud      = 921600,
+               .uart_offset    = 8,
+       },
+
+       [pbn_b1_1_115200] = {
+               .flags          = FL_BASE1,
+               .num_ports      = 1,
+               .base_baud      = 115200,
+               .uart_offset    = 8,
+       },
+       [pbn_b1_2_115200] = {
+               .flags          = FL_BASE1,
+               .num_ports      = 2,
+               .base_baud      = 115200,
+               .uart_offset    = 8,
+       },
+       [pbn_b1_4_115200] = {
+               .flags          = FL_BASE1,
+               .num_ports      = 4,
+               .base_baud      = 115200,
+               .uart_offset    = 8,
+       },
+       [pbn_b1_8_115200] = {
+               .flags          = FL_BASE1,
+               .num_ports      = 8,
+               .base_baud      = 115200,
+               .uart_offset    = 8,
+       },
+       [pbn_b1_16_115200] = {
+               .flags          = FL_BASE1,
+               .num_ports      = 16,
+               .base_baud      = 115200,
+               .uart_offset    = 8,
+       },
+
+       [pbn_b1_1_921600] = {
+               .flags          = FL_BASE1,
+               .num_ports      = 1,
+               .base_baud      = 921600,
+               .uart_offset    = 8,
+       },
+       [pbn_b1_2_921600] = {
+               .flags          = FL_BASE1,
+               .num_ports      = 2,
+               .base_baud      = 921600,
+               .uart_offset    = 8,
+       },
+       [pbn_b1_4_921600] = {
+               .flags          = FL_BASE1,
+               .num_ports      = 4,
+               .base_baud      = 921600,
+               .uart_offset    = 8,
+       },
+       [pbn_b1_8_921600] = {
+               .flags          = FL_BASE1,
+               .num_ports      = 8,
+               .base_baud      = 921600,
+               .uart_offset    = 8,
+       },
+       [pbn_b1_2_1250000] = {
+               .flags          = FL_BASE1,
+               .num_ports      = 2,
+               .base_baud      = 1250000,
+               .uart_offset    = 8,
+       },
+
+       [pbn_b1_bt_1_115200] = {
+               .flags          = FL_BASE1|FL_BASE_BARS,
+               .num_ports      = 1,
+               .base_baud      = 115200,
+               .uart_offset    = 8,
+       },
+       [pbn_b1_bt_2_115200] = {
+               .flags          = FL_BASE1|FL_BASE_BARS,
+               .num_ports      = 2,
+               .base_baud      = 115200,
+               .uart_offset    = 8,
+       },
+       [pbn_b1_bt_4_115200] = {
+               .flags          = FL_BASE1|FL_BASE_BARS,
+               .num_ports      = 4,
+               .base_baud      = 115200,
+               .uart_offset    = 8,
+       },
+
+       [pbn_b1_bt_2_921600] = {
+               .flags          = FL_BASE1|FL_BASE_BARS,
+               .num_ports      = 2,
+               .base_baud      = 921600,
+               .uart_offset    = 8,
+       },
+
+       [pbn_b1_1_1382400] = {
+               .flags          = FL_BASE1,
+               .num_ports      = 1,
+               .base_baud      = 1382400,
+               .uart_offset    = 8,
+       },
+       [pbn_b1_2_1382400] = {
+               .flags          = FL_BASE1,
+               .num_ports      = 2,
+               .base_baud      = 1382400,
+               .uart_offset    = 8,
+       },
+       [pbn_b1_4_1382400] = {
+               .flags          = FL_BASE1,
+               .num_ports      = 4,
+               .base_baud      = 1382400,
+               .uart_offset    = 8,
+       },
+       [pbn_b1_8_1382400] = {
+               .flags          = FL_BASE1,
+               .num_ports      = 8,
+               .base_baud      = 1382400,
+               .uart_offset    = 8,
+       },
+
+       [pbn_b2_1_115200] = {
+               .flags          = FL_BASE2,
+               .num_ports      = 1,
+               .base_baud      = 115200,
+               .uart_offset    = 8,
+       },
+       [pbn_b2_2_115200] = {
+               .flags          = FL_BASE2,
+               .num_ports      = 2,
+               .base_baud      = 115200,
+               .uart_offset    = 8,
+       },
+       [pbn_b2_4_115200] = {
+               .flags          = FL_BASE2,
+               .num_ports      = 4,
+               .base_baud      = 115200,
+               .uart_offset    = 8,
+       },
+       [pbn_b2_8_115200] = {
+               .flags          = FL_BASE2,
+               .num_ports      = 8,
+               .base_baud      = 115200,
+               .uart_offset    = 8,
+       },
+
+       [pbn_b2_1_460800] = {
+               .flags          = FL_BASE2,
+               .num_ports      = 1,
+               .base_baud      = 460800,
+               .uart_offset    = 8,
+       },
+       [pbn_b2_4_460800] = {
+               .flags          = FL_BASE2,
+               .num_ports      = 4,
+               .base_baud      = 460800,
+               .uart_offset    = 8,
+       },
+       [pbn_b2_8_460800] = {
+               .flags          = FL_BASE2,
+               .num_ports      = 8,
+               .base_baud      = 460800,
+               .uart_offset    = 8,
+       },
+       [pbn_b2_16_460800] = {
+               .flags          = FL_BASE2,
+               .num_ports      = 16,
+               .base_baud      = 460800,
+               .uart_offset    = 8,
+        },
+
+       [pbn_b2_1_921600] = {
+               .flags          = FL_BASE2,
+               .num_ports      = 1,
+               .base_baud      = 921600,
+               .uart_offset    = 8,
+       },
+       [pbn_b2_4_921600] = {
+               .flags          = FL_BASE2,
+               .num_ports      = 4,
+               .base_baud      = 921600,
+               .uart_offset    = 8,
+       },
+       [pbn_b2_8_921600] = {
+               .flags          = FL_BASE2,
+               .num_ports      = 8,
+               .base_baud      = 921600,
+               .uart_offset    = 8,
+       },
+
+       [pbn_b2_8_1152000] = {
+               .flags          = FL_BASE2,
+               .num_ports      = 8,
+               .base_baud      = 1152000,
+               .uart_offset    = 8,
+       },
+
+       [pbn_b2_bt_1_115200] = {
+               .flags          = FL_BASE2|FL_BASE_BARS,
+               .num_ports      = 1,
+               .base_baud      = 115200,
+               .uart_offset    = 8,
+       },
+       [pbn_b2_bt_2_115200] = {
+               .flags          = FL_BASE2|FL_BASE_BARS,
+               .num_ports      = 2,
+               .base_baud      = 115200,
+               .uart_offset    = 8,
+       },
+       [pbn_b2_bt_4_115200] = {
+               .flags          = FL_BASE2|FL_BASE_BARS,
+               .num_ports      = 4,
+               .base_baud      = 115200,
+               .uart_offset    = 8,
+       },
+
+       [pbn_b2_bt_2_921600] = {
+               .flags          = FL_BASE2|FL_BASE_BARS,
+               .num_ports      = 2,
+               .base_baud      = 921600,
+               .uart_offset    = 8,
+       },
+       [pbn_b2_bt_4_921600] = {
+               .flags          = FL_BASE2|FL_BASE_BARS,
+               .num_ports      = 4,
+               .base_baud      = 921600,
+               .uart_offset    = 8,
+       },
+
+       [pbn_b3_2_115200] = {
+               .flags          = FL_BASE3,
+               .num_ports      = 2,
+               .base_baud      = 115200,
+               .uart_offset    = 8,
+       },
+       [pbn_b3_4_115200] = {
+               .flags          = FL_BASE3,
+               .num_ports      = 4,
+               .base_baud      = 115200,
+               .uart_offset    = 8,
+       },
+       [pbn_b3_8_115200] = {
+               .flags          = FL_BASE3,
+               .num_ports      = 8,
+               .base_baud      = 115200,
+               .uart_offset    = 8,
+       },
+
+       [pbn_b4_bt_2_921600] = {
+               .flags          = FL_BASE4,
+               .num_ports      = 2,
+               .base_baud      = 921600,
+               .uart_offset    = 8,
+       },
+       [pbn_b4_bt_4_921600] = {
+               .flags          = FL_BASE4,
+               .num_ports      = 4,
+               .base_baud      = 921600,
+               .uart_offset    = 8,
+       },
+       [pbn_b4_bt_8_921600] = {
+               .flags          = FL_BASE4,
+               .num_ports      = 8,
+               .base_baud      = 921600,
+               .uart_offset    = 8,
+       },
+
+       /*
+        * Entries following this are board-specific.
+        */
+
+       /*
+        * Panacom - IOMEM
+        */
+       [pbn_panacom] = {
+               .flags          = FL_BASE2,
+               .num_ports      = 2,
+               .base_baud      = 921600,
+               .uart_offset    = 0x400,
+               .reg_shift      = 7,
+       },
+       [pbn_panacom2] = {
+               .flags          = FL_BASE2|FL_BASE_BARS,
+               .num_ports      = 2,
+               .base_baud      = 921600,
+               .uart_offset    = 0x400,
+               .reg_shift      = 7,
+       },
+       [pbn_panacom4] = {
+               .flags          = FL_BASE2|FL_BASE_BARS,
+               .num_ports      = 4,
+               .base_baud      = 921600,
+               .uart_offset    = 0x400,
+               .reg_shift      = 7,
+       },
+
+       [pbn_exsys_4055] = {
+               .flags          = FL_BASE2,
+               .num_ports      = 4,
+               .base_baud      = 115200,
+               .uart_offset    = 8,
+       },
+
+       /* I think this entry is broken - the first_offset looks wrong --rmk */
+       [pbn_plx_romulus] = {
+               .flags          = FL_BASE2,
+               .num_ports      = 4,
+               .base_baud      = 921600,
+               .uart_offset    = 8 << 2,
+               .reg_shift      = 2,
+               .first_offset   = 0x03,
+       },
+
+       /*
+        * This board uses the size of PCI Base region 0 to
+        * signal now many ports are available
+        */
+       [pbn_oxsemi] = {
+               .flags          = FL_BASE0|FL_REGION_SZ_CAP,
+               .num_ports      = 32,
+               .base_baud      = 115200,
+               .uart_offset    = 8,
+       },
+       [pbn_oxsemi_1_4000000] = {
+               .flags          = FL_BASE0,
+               .num_ports      = 1,
+               .base_baud      = 4000000,
+               .uart_offset    = 0x200,
+               .first_offset   = 0x1000,
+       },
+       [pbn_oxsemi_2_4000000] = {
+               .flags          = FL_BASE0,
+               .num_ports      = 2,
+               .base_baud      = 4000000,
+               .uart_offset    = 0x200,
+               .first_offset   = 0x1000,
+       },
+       [pbn_oxsemi_4_4000000] = {
+               .flags          = FL_BASE0,
+               .num_ports      = 4,
+               .base_baud      = 4000000,
+               .uart_offset    = 0x200,
+               .first_offset   = 0x1000,
+       },
+       [pbn_oxsemi_8_4000000] = {
+               .flags          = FL_BASE0,
+               .num_ports      = 8,
+               .base_baud      = 4000000,
+               .uart_offset    = 0x200,
+               .first_offset   = 0x1000,
+       },
+
+
+       /*
+        * EKF addition for i960 Boards form EKF with serial port.
+        * Max 256 ports.
+        */
+       [pbn_intel_i960] = {
+               .flags          = FL_BASE0,
+               .num_ports      = 32,
+               .base_baud      = 921600,
+               .uart_offset    = 8 << 2,
+               .reg_shift      = 2,
+               .first_offset   = 0x10000,
+       },
+       [pbn_sgi_ioc3] = {
+               .flags          = FL_BASE0|FL_NOIRQ,
+               .num_ports      = 1,
+               .base_baud      = 458333,
+               .uart_offset    = 8,
+               .reg_shift      = 0,
+               .first_offset   = 0x20178,
+       },
+
+       /*
+        * Computone - uses IOMEM.
+        */
+       [pbn_computone_4] = {
+               .flags          = FL_BASE0,
+               .num_ports      = 4,
+               .base_baud      = 921600,
+               .uart_offset    = 0x40,
+               .reg_shift      = 2,
+               .first_offset   = 0x200,
+       },
+       [pbn_computone_6] = {
+               .flags          = FL_BASE0,
+               .num_ports      = 6,
+               .base_baud      = 921600,
+               .uart_offset    = 0x40,
+               .reg_shift      = 2,
+               .first_offset   = 0x200,
+       },
+       [pbn_computone_8] = {
+               .flags          = FL_BASE0,
+               .num_ports      = 8,
+               .base_baud      = 921600,
+               .uart_offset    = 0x40,
+               .reg_shift      = 2,
+               .first_offset   = 0x200,
+       },
+       [pbn_sbsxrsio] = {
+               .flags          = FL_BASE0,
+               .num_ports      = 8,
+               .base_baud      = 460800,
+               .uart_offset    = 256,
+               .reg_shift      = 4,
+       },
+       /*
+        * Exar Corp. XR17C15[248] Dual/Quad/Octal UART
+        *  Only basic 16550A support.
+        *  XR17C15[24] are not tested, but they should work.
+        */
+       [pbn_exar_XR17C152] = {
+               .flags          = FL_BASE0,
+               .num_ports      = 2,
+               .base_baud      = 921600,
+               .uart_offset    = 0x200,
+       },
+       [pbn_exar_XR17C154] = {
+               .flags          = FL_BASE0,
+               .num_ports      = 4,
+               .base_baud      = 921600,
+               .uart_offset    = 0x200,
+       },
+       [pbn_exar_XR17C158] = {
+               .flags          = FL_BASE0,
+               .num_ports      = 8,
+               .base_baud      = 921600,
+               .uart_offset    = 0x200,
+       },
+       [pbn_exar_ibm_saturn] = {
+               .flags          = FL_BASE0,
+               .num_ports      = 1,
+               .base_baud      = 921600,
+               .uart_offset    = 0x200,
+       },
+
+       /*
+        * PA Semi PWRficient PA6T-1682M on-chip UART
+        */
+       [pbn_pasemi_1682M] = {
+               .flags          = FL_BASE0,
+               .num_ports      = 1,
+               .base_baud      = 8333333,
+       },
+       /*
+        * National Instruments 843x
+        */
+       [pbn_ni8430_16] = {
+               .flags          = FL_BASE0,
+               .num_ports      = 16,
+               .base_baud      = 3686400,
+               .uart_offset    = 0x10,
+               .first_offset   = 0x800,
+       },
+       [pbn_ni8430_8] = {
+               .flags          = FL_BASE0,
+               .num_ports      = 8,
+               .base_baud      = 3686400,
+               .uart_offset    = 0x10,
+               .first_offset   = 0x800,
+       },
+       [pbn_ni8430_4] = {
+               .flags          = FL_BASE0,
+               .num_ports      = 4,
+               .base_baud      = 3686400,
+               .uart_offset    = 0x10,
+               .first_offset   = 0x800,
+       },
+       [pbn_ni8430_2] = {
+               .flags          = FL_BASE0,
+               .num_ports      = 2,
+               .base_baud      = 3686400,
+               .uart_offset    = 0x10,
+               .first_offset   = 0x800,
+       },
+       /*
+        * ADDI-DATA GmbH PCI-Express communication cards <info@addi-data.com>
+        */
+       [pbn_ADDIDATA_PCIe_1_3906250] = {
+               .flags          = FL_BASE0,
+               .num_ports      = 1,
+               .base_baud      = 3906250,
+               .uart_offset    = 0x200,
+               .first_offset   = 0x1000,
+       },
+       [pbn_ADDIDATA_PCIe_2_3906250] = {
+               .flags          = FL_BASE0,
+               .num_ports      = 2,
+               .base_baud      = 3906250,
+               .uart_offset    = 0x200,
+               .first_offset   = 0x1000,
+       },
+       [pbn_ADDIDATA_PCIe_4_3906250] = {
+               .flags          = FL_BASE0,
+               .num_ports      = 4,
+               .base_baud      = 3906250,
+               .uart_offset    = 0x200,
+               .first_offset   = 0x1000,
+       },
+       [pbn_ADDIDATA_PCIe_8_3906250] = {
+               .flags          = FL_BASE0,
+               .num_ports      = 8,
+               .base_baud      = 3906250,
+               .uart_offset    = 0x200,
+               .first_offset   = 0x1000,
+       },
+       [pbn_ce4100_1_115200] = {
+               .flags          = FL_BASE0,
+               .num_ports      = 1,
+               .base_baud      = 921600,
+               .reg_shift      = 2,
+       },
+       [pbn_omegapci] = {
+               .flags          = FL_BASE0,
+               .num_ports      = 8,
+               .base_baud      = 115200,
+               .uart_offset    = 0x200,
+       },
+       [pbn_NETMOS9900_2s_115200] = {
+               .flags          = FL_BASE0,
+               .num_ports      = 2,
+               .base_baud      = 115200,
+       },
+};
+
+static const struct pci_device_id softmodem_blacklist[] = {
+       { PCI_VDEVICE(AL, 0x5457), }, /* ALi Corporation M5457 AC'97 Modem */
+       { PCI_VDEVICE(MOTOROLA, 0x3052), }, /* Motorola Si3052-based modem */
+       { PCI_DEVICE(0x1543, 0x3052), }, /* Si3052-based modem, default IDs */
+};
+
+/*
+ * Given a complete unknown PCI device, try to use some heuristics to
+ * guess what the configuration might be, based on the pitiful PCI
+ * serial specs.  Returns 0 on success, 1 on failure.
+ */
+static int __devinit
+serial_pci_guess_board(struct pci_dev *dev, struct pciserial_board *board)
+{
+       const struct pci_device_id *blacklist;
+       int num_iomem, num_port, first_port = -1, i;
+
+       /*
+        * If it is not a communications device or the programming
+        * interface is greater than 6, give up.
+        *
+        * (Should we try to make guesses for multiport serial devices
+        * later?)
+        */
+       if ((((dev->class >> 8) != PCI_CLASS_COMMUNICATION_SERIAL) &&
+            ((dev->class >> 8) != PCI_CLASS_COMMUNICATION_MODEM)) ||
+           (dev->class & 0xff) > 6)
+               return -ENODEV;
+
+       /*
+        * Do not access blacklisted devices that are known not to
+        * feature serial ports.
+        */
+       for (blacklist = softmodem_blacklist;
+            blacklist < softmodem_blacklist + ARRAY_SIZE(softmodem_blacklist);
+            blacklist++) {
+               if (dev->vendor == blacklist->vendor &&
+                   dev->device == blacklist->device)
+                       return -ENODEV;
+       }
+
+       num_iomem = num_port = 0;
+       for (i = 0; i < PCI_NUM_BAR_RESOURCES; i++) {
+               if (pci_resource_flags(dev, i) & IORESOURCE_IO) {
+                       num_port++;
+                       if (first_port == -1)
+                               first_port = i;
+               }
+               if (pci_resource_flags(dev, i) & IORESOURCE_MEM)
+                       num_iomem++;
+       }
+
+       /*
+        * If there is 1 or 0 iomem regions, and exactly one port,
+        * use it.  We guess the number of ports based on the IO
+        * region size.
+        */
+       if (num_iomem <= 1 && num_port == 1) {
+               board->flags = first_port;
+               board->num_ports = pci_resource_len(dev, first_port) / 8;
+               return 0;
+       }
+
+       /*
+        * Now guess if we've got a board which indexes by BARs.
+        * Each IO BAR should be 8 bytes, and they should follow
+        * consecutively.
+        */
+       first_port = -1;
+       num_port = 0;
+       for (i = 0; i < PCI_NUM_BAR_RESOURCES; i++) {
+               if (pci_resource_flags(dev, i) & IORESOURCE_IO &&
+                   pci_resource_len(dev, i) == 8 &&
+                   (first_port == -1 || (first_port + num_port) == i)) {
+                       num_port++;
+                       if (first_port == -1)
+                               first_port = i;
+               }
+       }
+
+       if (num_port > 1) {
+               board->flags = first_port | FL_BASE_BARS;
+               board->num_ports = num_port;
+               return 0;
+       }
+
+       return -ENODEV;
+}
+
+static inline int
+serial_pci_matches(const struct pciserial_board *board,
+                  const struct pciserial_board *guessed)
+{
+       return
+           board->num_ports == guessed->num_ports &&
+           board->base_baud == guessed->base_baud &&
+           board->uart_offset == guessed->uart_offset &&
+           board->reg_shift == guessed->reg_shift &&
+           board->first_offset == guessed->first_offset;
+}
+
+struct serial_private *
+pciserial_init_ports(struct pci_dev *dev, const struct pciserial_board *board)
+{
+       struct uart_port serial_port;
+       struct serial_private *priv;
+       struct pci_serial_quirk *quirk;
+       int rc, nr_ports, i;
+
+       nr_ports = board->num_ports;
+
+       /*
+        * Find an init and setup quirks.
+        */
+       quirk = find_quirk(dev);
+
+       /*
+        * Run the new-style initialization function.
+        * The initialization function returns:
+        *  <0  - error
+        *   0  - use board->num_ports
+        *  >0  - number of ports
+        */
+       if (quirk->init) {
+               rc = quirk->init(dev);
+               if (rc < 0) {
+                       priv = ERR_PTR(rc);
+                       goto err_out;
+               }
+               if (rc)
+                       nr_ports = rc;
+       }
+
+       priv = kzalloc(sizeof(struct serial_private) +
+                      sizeof(unsigned int) * nr_ports,
+                      GFP_KERNEL);
+       if (!priv) {
+               priv = ERR_PTR(-ENOMEM);
+               goto err_deinit;
+       }
+
+       priv->dev = dev;
+       priv->quirk = quirk;
+
+       memset(&serial_port, 0, sizeof(struct uart_port));
+       serial_port.flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF | UPF_SHARE_IRQ;
+       serial_port.uartclk = board->base_baud * 16;
+       serial_port.irq = get_pci_irq(dev, board);
+       serial_port.dev = &dev->dev;
+
+       for (i = 0; i < nr_ports; i++) {
+               if (quirk->setup(priv, board, &serial_port, i))
+                       break;
+
+#ifdef SERIAL_DEBUG_PCI
+               printk(KERN_DEBUG "Setup PCI port: port %lx, irq %d, type %d\n",
+                      serial_port.iobase, serial_port.irq, serial_port.iotype);
+#endif
+
+               priv->line[i] = serial8250_register_port(&serial_port);
+               if (priv->line[i] < 0) {
+                       printk(KERN_WARNING "Couldn't register serial port %s: %d\n", pci_name(dev), priv->line[i]);
+                       break;
+               }
+       }
+       priv->nr = i;
+       return priv;
+
+err_deinit:
+       if (quirk->exit)
+               quirk->exit(dev);
+err_out:
+       return priv;
+}
+EXPORT_SYMBOL_GPL(pciserial_init_ports);
+
+void pciserial_remove_ports(struct serial_private *priv)
+{
+       struct pci_serial_quirk *quirk;
+       int i;
+
+       for (i = 0; i < priv->nr; i++)
+               serial8250_unregister_port(priv->line[i]);
+
+       for (i = 0; i < PCI_NUM_BAR_RESOURCES; i++) {
+               if (priv->remapped_bar[i])
+                       iounmap(priv->remapped_bar[i]);
+               priv->remapped_bar[i] = NULL;
+       }
+
+       /*
+        * Find the exit quirks.
+        */
+       quirk = find_quirk(priv->dev);
+       if (quirk->exit)
+               quirk->exit(priv->dev);
+
+       kfree(priv);
+}
+EXPORT_SYMBOL_GPL(pciserial_remove_ports);
+
+void pciserial_suspend_ports(struct serial_private *priv)
+{
+       int i;
+
+       for (i = 0; i < priv->nr; i++)
+               if (priv->line[i] >= 0)
+                       serial8250_suspend_port(priv->line[i]);
+}
+EXPORT_SYMBOL_GPL(pciserial_suspend_ports);
+
+void pciserial_resume_ports(struct serial_private *priv)
+{
+       int i;
+
+       /*
+        * Ensure that the board is correctly configured.
+        */
+       if (priv->quirk->init)
+               priv->quirk->init(priv->dev);
+
+       for (i = 0; i < priv->nr; i++)
+               if (priv->line[i] >= 0)
+                       serial8250_resume_port(priv->line[i]);
+}
+EXPORT_SYMBOL_GPL(pciserial_resume_ports);
+
+/*
+ * Probe one serial board.  Unfortunately, there is no rhyme nor reason
+ * to the arrangement of serial ports on a PCI card.
+ */
+static int __devinit
+pciserial_init_one(struct pci_dev *dev, const struct pci_device_id *ent)
+{
+       struct pci_serial_quirk *quirk;
+       struct serial_private *priv;
+       const struct pciserial_board *board;
+       struct pciserial_board tmp;
+       int rc;
+
+       quirk = find_quirk(dev);
+       if (quirk->probe) {
+               rc = quirk->probe(dev);
+               if (rc)
+                       return rc;
+       }
+
+       if (ent->driver_data >= ARRAY_SIZE(pci_boards)) {
+               printk(KERN_ERR "pci_init_one: invalid driver_data: %ld\n",
+                       ent->driver_data);
+               return -EINVAL;
+       }
+
+       board = &pci_boards[ent->driver_data];
+
+       rc = pci_enable_device(dev);
+       pci_save_state(dev);
+       if (rc)
+               return rc;
+
+       if (ent->driver_data == pbn_default) {
+               /*
+                * Use a copy of the pci_board entry for this;
+                * avoid changing entries in the table.
+                */
+               memcpy(&tmp, board, sizeof(struct pciserial_board));
+               board = &tmp;
+
+               /*
+                * We matched one of our class entries.  Try to
+                * determine the parameters of this board.
+                */
+               rc = serial_pci_guess_board(dev, &tmp);
+               if (rc)
+                       goto disable;
+       } else {
+               /*
+                * We matched an explicit entry.  If we are able to
+                * detect this boards settings with our heuristic,
+                * then we no longer need this entry.
+                */
+               memcpy(&tmp, &pci_boards[pbn_default],
+                      sizeof(struct pciserial_board));
+               rc = serial_pci_guess_board(dev, &tmp);
+               if (rc == 0 && serial_pci_matches(board, &tmp))
+                       moan_device("Redundant entry in serial pci_table.",
+                                   dev);
+       }
+
+       priv = pciserial_init_ports(dev, board);
+       if (!IS_ERR(priv)) {
+               pci_set_drvdata(dev, priv);
+               return 0;
+       }
+
+       rc = PTR_ERR(priv);
+
+ disable:
+       pci_disable_device(dev);
+       return rc;
+}
+
+static void __devexit pciserial_remove_one(struct pci_dev *dev)
+{
+       struct serial_private *priv = pci_get_drvdata(dev);
+
+       pci_set_drvdata(dev, NULL);
+
+       pciserial_remove_ports(priv);
+
+       pci_disable_device(dev);
+}
+
+#ifdef CONFIG_PM
+static int pciserial_suspend_one(struct pci_dev *dev, pm_message_t state)
+{
+       struct serial_private *priv = pci_get_drvdata(dev);
+
+       if (priv)
+               pciserial_suspend_ports(priv);
+
+       pci_save_state(dev);
+       pci_set_power_state(dev, pci_choose_state(dev, state));
+       return 0;
+}
+
+static int pciserial_resume_one(struct pci_dev *dev)
+{
+       int err;
+       struct serial_private *priv = pci_get_drvdata(dev);
+
+       pci_set_power_state(dev, PCI_D0);
+       pci_restore_state(dev);
+
+       if (priv) {
+               /*
+                * The device may have been disabled.  Re-enable it.
+                */
+               err = pci_enable_device(dev);
+               /* FIXME: We cannot simply error out here */
+               if (err)
+                       printk(KERN_ERR "pciserial: Unable to re-enable ports, trying to continue.\n");
+               pciserial_resume_ports(priv);
+       }
+       return 0;
+}
+#endif
+
+static struct pci_device_id serial_pci_tbl[] = {
+       /* Advantech use PCI_DEVICE_ID_ADVANTECH_PCI3620 (0x3620) as 'PCI_SUBVENDOR_ID' */
+       {       PCI_VENDOR_ID_ADVANTECH, PCI_DEVICE_ID_ADVANTECH_PCI3620,
+               PCI_DEVICE_ID_ADVANTECH_PCI3620, 0x0001, 0, 0,
+               pbn_b2_8_921600 },
+       {       PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V960,
+               PCI_SUBVENDOR_ID_CONNECT_TECH,
+               PCI_SUBDEVICE_ID_CONNECT_TECH_BH8_232, 0, 0,
+               pbn_b1_8_1382400 },
+       {       PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V960,
+               PCI_SUBVENDOR_ID_CONNECT_TECH,
+               PCI_SUBDEVICE_ID_CONNECT_TECH_BH4_232, 0, 0,
+               pbn_b1_4_1382400 },
+       {       PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V960,
+               PCI_SUBVENDOR_ID_CONNECT_TECH,
+               PCI_SUBDEVICE_ID_CONNECT_TECH_BH2_232, 0, 0,
+               pbn_b1_2_1382400 },
+       {       PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V351,
+               PCI_SUBVENDOR_ID_CONNECT_TECH,
+               PCI_SUBDEVICE_ID_CONNECT_TECH_BH8_232, 0, 0,
+               pbn_b1_8_1382400 },
+       {       PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V351,
+               PCI_SUBVENDOR_ID_CONNECT_TECH,
+               PCI_SUBDEVICE_ID_CONNECT_TECH_BH4_232, 0, 0,
+               pbn_b1_4_1382400 },
+       {       PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V351,
+               PCI_SUBVENDOR_ID_CONNECT_TECH,
+               PCI_SUBDEVICE_ID_CONNECT_TECH_BH2_232, 0, 0,
+               pbn_b1_2_1382400 },
+       {       PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V351,
+               PCI_SUBVENDOR_ID_CONNECT_TECH,
+               PCI_SUBDEVICE_ID_CONNECT_TECH_BH8_485, 0, 0,
+               pbn_b1_8_921600 },
+       {       PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V351,
+               PCI_SUBVENDOR_ID_CONNECT_TECH,
+               PCI_SUBDEVICE_ID_CONNECT_TECH_BH8_485_4_4, 0, 0,
+               pbn_b1_8_921600 },
+       {       PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V351,
+               PCI_SUBVENDOR_ID_CONNECT_TECH,
+               PCI_SUBDEVICE_ID_CONNECT_TECH_BH4_485, 0, 0,
+               pbn_b1_4_921600 },
+       {       PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V351,
+               PCI_SUBVENDOR_ID_CONNECT_TECH,
+               PCI_SUBDEVICE_ID_CONNECT_TECH_BH4_485_2_2, 0, 0,
+               pbn_b1_4_921600 },
+       {       PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V351,
+               PCI_SUBVENDOR_ID_CONNECT_TECH,
+               PCI_SUBDEVICE_ID_CONNECT_TECH_BH2_485, 0, 0,
+               pbn_b1_2_921600 },
+       {       PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V351,
+               PCI_SUBVENDOR_ID_CONNECT_TECH,
+               PCI_SUBDEVICE_ID_CONNECT_TECH_BH8_485_2_6, 0, 0,
+               pbn_b1_8_921600 },
+       {       PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V351,
+               PCI_SUBVENDOR_ID_CONNECT_TECH,
+               PCI_SUBDEVICE_ID_CONNECT_TECH_BH081101V1, 0, 0,
+               pbn_b1_8_921600 },
+       {       PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V351,
+               PCI_SUBVENDOR_ID_CONNECT_TECH,
+               PCI_SUBDEVICE_ID_CONNECT_TECH_BH041101V1, 0, 0,
+               pbn_b1_4_921600 },
+       {       PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V351,
+               PCI_SUBVENDOR_ID_CONNECT_TECH,
+               PCI_SUBDEVICE_ID_CONNECT_TECH_BH2_20MHZ, 0, 0,
+               pbn_b1_2_1250000 },
+       {       PCI_VENDOR_ID_OXSEMI, PCI_DEVICE_ID_OXSEMI_16PCI954,
+               PCI_SUBVENDOR_ID_CONNECT_TECH,
+               PCI_SUBDEVICE_ID_CONNECT_TECH_TITAN_2, 0, 0,
+               pbn_b0_2_1843200 },
+       {       PCI_VENDOR_ID_OXSEMI, PCI_DEVICE_ID_OXSEMI_16PCI954,
+               PCI_SUBVENDOR_ID_CONNECT_TECH,
+               PCI_SUBDEVICE_ID_CONNECT_TECH_TITAN_4, 0, 0,
+               pbn_b0_4_1843200 },
+       {       PCI_VENDOR_ID_OXSEMI, PCI_DEVICE_ID_OXSEMI_16PCI954,
+               PCI_VENDOR_ID_AFAVLAB,
+               PCI_SUBDEVICE_ID_AFAVLAB_P061, 0, 0,
+               pbn_b0_4_1152000 },
+       {       PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17C152,
+               PCI_SUBVENDOR_ID_CONNECT_TECH,
+               PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_2_232, 0, 0,
+               pbn_b0_2_1843200_200 },
+       {       PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17C154,
+               PCI_SUBVENDOR_ID_CONNECT_TECH,
+               PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_4_232, 0, 0,
+               pbn_b0_4_1843200_200 },
+       {       PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17C158,
+               PCI_SUBVENDOR_ID_CONNECT_TECH,
+               PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_8_232, 0, 0,
+               pbn_b0_8_1843200_200 },
+       {       PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17C152,
+               PCI_SUBVENDOR_ID_CONNECT_TECH,
+               PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_1_1, 0, 0,
+               pbn_b0_2_1843200_200 },
+       {       PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17C154,
+               PCI_SUBVENDOR_ID_CONNECT_TECH,
+               PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_2_2, 0, 0,
+               pbn_b0_4_1843200_200 },
+       {       PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17C158,
+               PCI_SUBVENDOR_ID_CONNECT_TECH,
+               PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_4_4, 0, 0,
+               pbn_b0_8_1843200_200 },
+       {       PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17C152,
+               PCI_SUBVENDOR_ID_CONNECT_TECH,
+               PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_2, 0, 0,
+               pbn_b0_2_1843200_200 },
+       {       PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17C154,
+               PCI_SUBVENDOR_ID_CONNECT_TECH,
+               PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_4, 0, 0,
+               pbn_b0_4_1843200_200 },
+       {       PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17C158,
+               PCI_SUBVENDOR_ID_CONNECT_TECH,
+               PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_8, 0, 0,
+               pbn_b0_8_1843200_200 },
+       {       PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17C152,
+               PCI_SUBVENDOR_ID_CONNECT_TECH,
+               PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_2_485, 0, 0,
+               pbn_b0_2_1843200_200 },
+       {       PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17C154,
+               PCI_SUBVENDOR_ID_CONNECT_TECH,
+               PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_4_485, 0, 0,
+               pbn_b0_4_1843200_200 },
+       {       PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17C158,
+               PCI_SUBVENDOR_ID_CONNECT_TECH,
+               PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_8_485, 0, 0,
+               pbn_b0_8_1843200_200 },
+       {       PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17C152,
+               PCI_VENDOR_ID_IBM, PCI_SUBDEVICE_ID_IBM_SATURN_SERIAL_ONE_PORT,
+               0, 0, pbn_exar_ibm_saturn },
+
+       {       PCI_VENDOR_ID_SEALEVEL, PCI_DEVICE_ID_SEALEVEL_U530,
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_b2_bt_1_115200 },
+       {       PCI_VENDOR_ID_SEALEVEL, PCI_DEVICE_ID_SEALEVEL_UCOMM2,
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_b2_bt_2_115200 },
+       {       PCI_VENDOR_ID_SEALEVEL, PCI_DEVICE_ID_SEALEVEL_UCOMM422,
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_b2_bt_4_115200 },
+       {       PCI_VENDOR_ID_SEALEVEL, PCI_DEVICE_ID_SEALEVEL_UCOMM232,
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_b2_bt_2_115200 },
+       {       PCI_VENDOR_ID_SEALEVEL, PCI_DEVICE_ID_SEALEVEL_COMM4,
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_b2_bt_4_115200 },
+       {       PCI_VENDOR_ID_SEALEVEL, PCI_DEVICE_ID_SEALEVEL_COMM8,
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_b2_8_115200 },
+       {       PCI_VENDOR_ID_SEALEVEL, PCI_DEVICE_ID_SEALEVEL_7803,
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_b2_8_460800 },
+       {       PCI_VENDOR_ID_SEALEVEL, PCI_DEVICE_ID_SEALEVEL_UCOMM8,
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_b2_8_115200 },
+
+       {       PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_GTEK_SERIAL2,
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_b2_bt_2_115200 },
+       {       PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_SPCOM200,
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_b2_bt_2_921600 },
+       /*
+        * VScom SPCOM800, from sl@s.pl
+        */
+       {       PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_SPCOM800,
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_b2_8_921600 },
+       {       PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_1077,
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_b2_4_921600 },
+       /* Unknown card - subdevice 0x1584 */
+       {       PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050,
+               PCI_VENDOR_ID_PLX,
+               PCI_SUBDEVICE_ID_UNKNOWN_0x1584, 0, 0,
+               pbn_b0_4_115200 },
+       {       PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050,
+               PCI_SUBVENDOR_ID_KEYSPAN,
+               PCI_SUBDEVICE_ID_KEYSPAN_SX2, 0, 0,
+               pbn_panacom },
+       {       PCI_VENDOR_ID_PANACOM, PCI_DEVICE_ID_PANACOM_QUADMODEM,
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_panacom4 },
+       {       PCI_VENDOR_ID_PANACOM, PCI_DEVICE_ID_PANACOM_DUALMODEM,
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_panacom2 },
+       {       PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9030,
+               PCI_VENDOR_ID_ESDGMBH,
+               PCI_DEVICE_ID_ESDGMBH_CPCIASIO4, 0, 0,
+               pbn_b2_4_115200 },
+       {       PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050,
+               PCI_SUBVENDOR_ID_CHASE_PCIFAST,
+               PCI_SUBDEVICE_ID_CHASE_PCIFAST4, 0, 0,
+               pbn_b2_4_460800 },
+       {       PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050,
+               PCI_SUBVENDOR_ID_CHASE_PCIFAST,
+               PCI_SUBDEVICE_ID_CHASE_PCIFAST8, 0, 0,
+               pbn_b2_8_460800 },
+       {       PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050,
+               PCI_SUBVENDOR_ID_CHASE_PCIFAST,
+               PCI_SUBDEVICE_ID_CHASE_PCIFAST16, 0, 0,
+               pbn_b2_16_460800 },
+       {       PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050,
+               PCI_SUBVENDOR_ID_CHASE_PCIFAST,
+               PCI_SUBDEVICE_ID_CHASE_PCIFAST16FMC, 0, 0,
+               pbn_b2_16_460800 },
+       {       PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050,
+               PCI_SUBVENDOR_ID_CHASE_PCIRAS,
+               PCI_SUBDEVICE_ID_CHASE_PCIRAS4, 0, 0,
+               pbn_b2_4_460800 },
+       {       PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050,
+               PCI_SUBVENDOR_ID_CHASE_PCIRAS,
+               PCI_SUBDEVICE_ID_CHASE_PCIRAS8, 0, 0,
+               pbn_b2_8_460800 },
+       {       PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050,
+               PCI_SUBVENDOR_ID_EXSYS,
+               PCI_SUBDEVICE_ID_EXSYS_4055, 0, 0,
+               pbn_exsys_4055 },
+       /*
+        * Megawolf Romulus PCI Serial Card, from Mike Hudson
+        * (Exoray@isys.ca)
+        */
+       {       PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_ROMULUS,
+               0x10b5, 0x106a, 0, 0,
+               pbn_plx_romulus },
+       {       PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_QSC100,
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_b1_4_115200 },
+       {       PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_DSC100,
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_b1_2_115200 },
+       {       PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_ESC100D,
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_b1_8_115200 },
+       {       PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_ESC100M,
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_b1_8_115200 },
+       {       PCI_VENDOR_ID_SPECIALIX, PCI_DEVICE_ID_OXSEMI_16PCI954,
+               PCI_VENDOR_ID_SPECIALIX, PCI_SUBDEVICE_ID_SPECIALIX_SPEED4,
+               0, 0,
+               pbn_b0_4_921600 },
+       {       PCI_VENDOR_ID_OXSEMI, PCI_DEVICE_ID_OXSEMI_16PCI954,
+               PCI_SUBVENDOR_ID_SIIG, PCI_SUBDEVICE_ID_SIIG_QUARTET_SERIAL,
+               0, 0,
+               pbn_b0_4_1152000 },
+       {       PCI_VENDOR_ID_OXSEMI, 0x9505,
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_b0_bt_2_921600 },
+
+               /*
+                * The below card is a little controversial since it is the
+                * subject of a PCI vendor/device ID clash.  (See
+                * www.ussg.iu.edu/hypermail/linux/kernel/0303.1/0516.html).
+                * For now just used the hex ID 0x950a.
+                */
+       {       PCI_VENDOR_ID_OXSEMI, 0x950a,
+               PCI_SUBVENDOR_ID_SIIG, PCI_SUBDEVICE_ID_SIIG_DUAL_SERIAL, 0, 0,
+               pbn_b0_2_115200 },
+       {       PCI_VENDOR_ID_OXSEMI, 0x950a,
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_b0_2_1130000 },
+       {       PCI_VENDOR_ID_OXSEMI, PCI_DEVICE_ID_OXSEMI_C950,
+               PCI_VENDOR_ID_OXSEMI, PCI_SUBDEVICE_ID_OXSEMI_C950, 0, 0,
+               pbn_b0_1_921600 },
+       {       PCI_VENDOR_ID_OXSEMI, PCI_DEVICE_ID_OXSEMI_16PCI954,
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_b0_4_115200 },
+       {       PCI_VENDOR_ID_OXSEMI, PCI_DEVICE_ID_OXSEMI_16PCI952,
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_b0_bt_2_921600 },
+       {       PCI_VENDOR_ID_OXSEMI, PCI_DEVICE_ID_OXSEMI_16PCI958,
+               PCI_ANY_ID , PCI_ANY_ID, 0, 0,
+               pbn_b2_8_1152000 },
+
+       /*
+        * Oxford Semiconductor Inc. Tornado PCI express device range.
+        */
+       {       PCI_VENDOR_ID_OXSEMI, 0xc101,    /* OXPCIe952 1 Legacy UART */
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_b0_1_4000000 },
+       {       PCI_VENDOR_ID_OXSEMI, 0xc105,    /* OXPCIe952 1 Legacy UART */
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_b0_1_4000000 },
+       {       PCI_VENDOR_ID_OXSEMI, 0xc11b,    /* OXPCIe952 1 Native UART */
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_oxsemi_1_4000000 },
+       {       PCI_VENDOR_ID_OXSEMI, 0xc11f,    /* OXPCIe952 1 Native UART */
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_oxsemi_1_4000000 },
+       {       PCI_VENDOR_ID_OXSEMI, 0xc120,    /* OXPCIe952 1 Legacy UART */
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_b0_1_4000000 },
+       {       PCI_VENDOR_ID_OXSEMI, 0xc124,    /* OXPCIe952 1 Legacy UART */
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_b0_1_4000000 },
+       {       PCI_VENDOR_ID_OXSEMI, 0xc138,    /* OXPCIe952 1 Native UART */
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_oxsemi_1_4000000 },
+       {       PCI_VENDOR_ID_OXSEMI, 0xc13d,    /* OXPCIe952 1 Native UART */
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_oxsemi_1_4000000 },
+       {       PCI_VENDOR_ID_OXSEMI, 0xc140,    /* OXPCIe952 1 Legacy UART */
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_b0_1_4000000 },
+       {       PCI_VENDOR_ID_OXSEMI, 0xc141,    /* OXPCIe952 1 Legacy UART */
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_b0_1_4000000 },
+       {       PCI_VENDOR_ID_OXSEMI, 0xc144,    /* OXPCIe952 1 Legacy UART */
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_b0_1_4000000 },
+       {       PCI_VENDOR_ID_OXSEMI, 0xc145,    /* OXPCIe952 1 Legacy UART */
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_b0_1_4000000 },
+       {       PCI_VENDOR_ID_OXSEMI, 0xc158,    /* OXPCIe952 2 Native UART */
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_oxsemi_2_4000000 },
+       {       PCI_VENDOR_ID_OXSEMI, 0xc15d,    /* OXPCIe952 2 Native UART */
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_oxsemi_2_4000000 },
+       {       PCI_VENDOR_ID_OXSEMI, 0xc208,    /* OXPCIe954 4 Native UART */
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_oxsemi_4_4000000 },
+       {       PCI_VENDOR_ID_OXSEMI, 0xc20d,    /* OXPCIe954 4 Native UART */
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_oxsemi_4_4000000 },
+       {       PCI_VENDOR_ID_OXSEMI, 0xc308,    /* OXPCIe958 8 Native UART */
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_oxsemi_8_4000000 },
+       {       PCI_VENDOR_ID_OXSEMI, 0xc30d,    /* OXPCIe958 8 Native UART */
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_oxsemi_8_4000000 },
+       {       PCI_VENDOR_ID_OXSEMI, 0xc40b,    /* OXPCIe200 1 Native UART */
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_oxsemi_1_4000000 },
+       {       PCI_VENDOR_ID_OXSEMI, 0xc40f,    /* OXPCIe200 1 Native UART */
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_oxsemi_1_4000000 },
+       {       PCI_VENDOR_ID_OXSEMI, 0xc41b,    /* OXPCIe200 1 Native UART */
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_oxsemi_1_4000000 },
+       {       PCI_VENDOR_ID_OXSEMI, 0xc41f,    /* OXPCIe200 1 Native UART */
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_oxsemi_1_4000000 },
+       {       PCI_VENDOR_ID_OXSEMI, 0xc42b,    /* OXPCIe200 1 Native UART */
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_oxsemi_1_4000000 },
+       {       PCI_VENDOR_ID_OXSEMI, 0xc42f,    /* OXPCIe200 1 Native UART */
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_oxsemi_1_4000000 },
+       {       PCI_VENDOR_ID_OXSEMI, 0xc43b,    /* OXPCIe200 1 Native UART */
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_oxsemi_1_4000000 },
+       {       PCI_VENDOR_ID_OXSEMI, 0xc43f,    /* OXPCIe200 1 Native UART */
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_oxsemi_1_4000000 },
+       {       PCI_VENDOR_ID_OXSEMI, 0xc44b,    /* OXPCIe200 1 Native UART */
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_oxsemi_1_4000000 },
+       {       PCI_VENDOR_ID_OXSEMI, 0xc44f,    /* OXPCIe200 1 Native UART */
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_oxsemi_1_4000000 },
+       {       PCI_VENDOR_ID_OXSEMI, 0xc45b,    /* OXPCIe200 1 Native UART */
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_oxsemi_1_4000000 },
+       {       PCI_VENDOR_ID_OXSEMI, 0xc45f,    /* OXPCIe200 1 Native UART */
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_oxsemi_1_4000000 },
+       {       PCI_VENDOR_ID_OXSEMI, 0xc46b,    /* OXPCIe200 1 Native UART */
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_oxsemi_1_4000000 },
+       {       PCI_VENDOR_ID_OXSEMI, 0xc46f,    /* OXPCIe200 1 Native UART */
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_oxsemi_1_4000000 },
+       {       PCI_VENDOR_ID_OXSEMI, 0xc47b,    /* OXPCIe200 1 Native UART */
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_oxsemi_1_4000000 },
+       {       PCI_VENDOR_ID_OXSEMI, 0xc47f,    /* OXPCIe200 1 Native UART */
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_oxsemi_1_4000000 },
+       {       PCI_VENDOR_ID_OXSEMI, 0xc48b,    /* OXPCIe200 1 Native UART */
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_oxsemi_1_4000000 },
+       {       PCI_VENDOR_ID_OXSEMI, 0xc48f,    /* OXPCIe200 1 Native UART */
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_oxsemi_1_4000000 },
+       {       PCI_VENDOR_ID_OXSEMI, 0xc49b,    /* OXPCIe200 1 Native UART */
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_oxsemi_1_4000000 },
+       {       PCI_VENDOR_ID_OXSEMI, 0xc49f,    /* OXPCIe200 1 Native UART */
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_oxsemi_1_4000000 },
+       {       PCI_VENDOR_ID_OXSEMI, 0xc4ab,    /* OXPCIe200 1 Native UART */
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_oxsemi_1_4000000 },
+       {       PCI_VENDOR_ID_OXSEMI, 0xc4af,    /* OXPCIe200 1 Native UART */
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_oxsemi_1_4000000 },
+       {       PCI_VENDOR_ID_OXSEMI, 0xc4bb,    /* OXPCIe200 1 Native UART */
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_oxsemi_1_4000000 },
+       {       PCI_VENDOR_ID_OXSEMI, 0xc4bf,    /* OXPCIe200 1 Native UART */
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_oxsemi_1_4000000 },
+       {       PCI_VENDOR_ID_OXSEMI, 0xc4cb,    /* OXPCIe200 1 Native UART */
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_oxsemi_1_4000000 },
+       {       PCI_VENDOR_ID_OXSEMI, 0xc4cf,    /* OXPCIe200 1 Native UART */
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_oxsemi_1_4000000 },
+       /*
+        * Mainpine Inc. IQ Express "Rev3" utilizing OxSemi Tornado
+        */
+       {       PCI_VENDOR_ID_MAINPINE, 0x4000, /* IQ Express 1 Port V.34 Super-G3 Fax */
+               PCI_VENDOR_ID_MAINPINE, 0x4001, 0, 0,
+               pbn_oxsemi_1_4000000 },
+       {       PCI_VENDOR_ID_MAINPINE, 0x4000, /* IQ Express 2 Port V.34 Super-G3 Fax */
+               PCI_VENDOR_ID_MAINPINE, 0x4002, 0, 0,
+               pbn_oxsemi_2_4000000 },
+       {       PCI_VENDOR_ID_MAINPINE, 0x4000, /* IQ Express 4 Port V.34 Super-G3 Fax */
+               PCI_VENDOR_ID_MAINPINE, 0x4004, 0, 0,
+               pbn_oxsemi_4_4000000 },
+       {       PCI_VENDOR_ID_MAINPINE, 0x4000, /* IQ Express 8 Port V.34 Super-G3 Fax */
+               PCI_VENDOR_ID_MAINPINE, 0x4008, 0, 0,
+               pbn_oxsemi_8_4000000 },
+
+       /*
+        * Digi/IBM PCIe 2-port Async EIA-232 Adapter utilizing OxSemi Tornado
+        */
+       {       PCI_VENDOR_ID_DIGI, PCIE_DEVICE_ID_NEO_2_OX_IBM,
+               PCI_SUBVENDOR_ID_IBM, PCI_ANY_ID, 0, 0,
+               pbn_oxsemi_2_4000000 },
+
+       /*
+        * SBS Technologies, Inc. P-Octal and PMC-OCTPRO cards,
+        * from skokodyn@yahoo.com
+        */
+       {       PCI_VENDOR_ID_SBSMODULARIO, PCI_DEVICE_ID_OCTPRO,
+               PCI_SUBVENDOR_ID_SBSMODULARIO, PCI_SUBDEVICE_ID_OCTPRO232, 0, 0,
+               pbn_sbsxrsio },
+       {       PCI_VENDOR_ID_SBSMODULARIO, PCI_DEVICE_ID_OCTPRO,
+               PCI_SUBVENDOR_ID_SBSMODULARIO, PCI_SUBDEVICE_ID_OCTPRO422, 0, 0,
+               pbn_sbsxrsio },
+       {       PCI_VENDOR_ID_SBSMODULARIO, PCI_DEVICE_ID_OCTPRO,
+               PCI_SUBVENDOR_ID_SBSMODULARIO, PCI_SUBDEVICE_ID_POCTAL232, 0, 0,
+               pbn_sbsxrsio },
+       {       PCI_VENDOR_ID_SBSMODULARIO, PCI_DEVICE_ID_OCTPRO,
+               PCI_SUBVENDOR_ID_SBSMODULARIO, PCI_SUBDEVICE_ID_POCTAL422, 0, 0,
+               pbn_sbsxrsio },
+
+       /*
+        * Digitan DS560-558, from jimd@esoft.com
+        */
+       {       PCI_VENDOR_ID_ATT, PCI_DEVICE_ID_ATT_VENUS_MODEM,
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_b1_1_115200 },
+
+       /*
+        * Titan Electronic cards
+        *  The 400L and 800L have a custom setup quirk.
+        */
+       {       PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_100,
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_b0_1_921600 },
+       {       PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_200,
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_b0_2_921600 },
+       {       PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_400,
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_b0_4_921600 },
+       {       PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_800B,
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_b0_4_921600 },
+       {       PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_100L,
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_b1_1_921600 },
+       {       PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_200L,
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_b1_bt_2_921600 },
+       {       PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_400L,
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_b0_bt_4_921600 },
+       {       PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_800L,
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_b0_bt_8_921600 },
+       {       PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_200I,
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_b4_bt_2_921600 },
+       {       PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_400I,
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_b4_bt_4_921600 },
+       {       PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_800I,
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_b4_bt_8_921600 },
+       {       PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_400EH,
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_b0_4_921600 },
+       {       PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_800EH,
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_b0_4_921600 },
+       {       PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_800EHB,
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_b0_4_921600 },
+       {       PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_100E,
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_oxsemi_1_4000000 },
+       {       PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_200E,
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_oxsemi_2_4000000 },
+       {       PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_400E,
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_oxsemi_4_4000000 },
+       {       PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_800E,
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_oxsemi_8_4000000 },
+       {       PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_200EI,
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_oxsemi_2_4000000 },
+       {       PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_200EISI,
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_oxsemi_2_4000000 },
+       {       PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_400V3,
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_b0_4_921600 },
+       {       PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_410V3,
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_b0_4_921600 },
+       {       PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_800V3,
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_b0_4_921600 },
+       {       PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_800V3B,
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_b0_4_921600 },
+
+       {       PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S_10x_550,
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_b2_1_460800 },
+       {       PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S_10x_650,
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_b2_1_460800 },
+       {       PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S_10x_850,
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_b2_1_460800 },
+       {       PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S_10x_550,
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_b2_bt_2_921600 },
+       {       PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S_10x_650,
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_b2_bt_2_921600 },
+       {       PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S_10x_850,
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_b2_bt_2_921600 },
+       {       PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_4S_10x_550,
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_b2_bt_4_921600 },
+       {       PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_4S_10x_650,
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_b2_bt_4_921600 },
+       {       PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_4S_10x_850,
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_b2_bt_4_921600 },
+       {       PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S_20x_550,
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_b0_1_921600 },
+       {       PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S_20x_650,
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_b0_1_921600 },
+       {       PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S_20x_850,
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_b0_1_921600 },
+       {       PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S_20x_550,
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_b0_bt_2_921600 },
+       {       PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S_20x_650,
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_b0_bt_2_921600 },
+       {       PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S_20x_850,
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_b0_bt_2_921600 },
+       {       PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_4S_20x_550,
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_b0_bt_4_921600 },
+       {       PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_4S_20x_650,
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_b0_bt_4_921600 },
+       {       PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_4S_20x_850,
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_b0_bt_4_921600 },
+       {       PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_8S_20x_550,
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_b0_bt_8_921600 },
+       {       PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_8S_20x_650,
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_b0_bt_8_921600 },
+       {       PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_8S_20x_850,
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_b0_bt_8_921600 },
+
+       /*
+        * Computone devices submitted by Doug McNash dmcnash@computone.com
+        */
+       {       PCI_VENDOR_ID_COMPUTONE, PCI_DEVICE_ID_COMPUTONE_PG,
+               PCI_SUBVENDOR_ID_COMPUTONE, PCI_SUBDEVICE_ID_COMPUTONE_PG4,
+               0, 0, pbn_computone_4 },
+       {       PCI_VENDOR_ID_COMPUTONE, PCI_DEVICE_ID_COMPUTONE_PG,
+               PCI_SUBVENDOR_ID_COMPUTONE, PCI_SUBDEVICE_ID_COMPUTONE_PG8,
+               0, 0, pbn_computone_8 },
+       {       PCI_VENDOR_ID_COMPUTONE, PCI_DEVICE_ID_COMPUTONE_PG,
+               PCI_SUBVENDOR_ID_COMPUTONE, PCI_SUBDEVICE_ID_COMPUTONE_PG6,
+               0, 0, pbn_computone_6 },
+
+       {       PCI_VENDOR_ID_OXSEMI, PCI_DEVICE_ID_OXSEMI_16PCI95N,
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_oxsemi },
+       {       PCI_VENDOR_ID_TIMEDIA, PCI_DEVICE_ID_TIMEDIA_1889,
+               PCI_VENDOR_ID_TIMEDIA, PCI_ANY_ID, 0, 0,
+               pbn_b0_bt_1_921600 },
+
+       /*
+        * AFAVLAB serial card, from Harald Welte <laforge@gnumonks.org>
+        */
+       {       PCI_VENDOR_ID_AFAVLAB, PCI_DEVICE_ID_AFAVLAB_P028,
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_b0_bt_8_115200 },
+       {       PCI_VENDOR_ID_AFAVLAB, PCI_DEVICE_ID_AFAVLAB_P030,
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_b0_bt_8_115200 },
+
+       {       PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_DSERIAL,
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_b0_bt_2_115200 },
+       {       PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_QUATRO_A,
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_b0_bt_2_115200 },
+       {       PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_QUATRO_B,
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_b0_bt_2_115200 },
+       {       PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_QUATTRO_A,
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_b0_bt_2_115200 },
+       {       PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_QUATTRO_B,
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_b0_bt_2_115200 },
+       {       PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_OCTO_A,
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_b0_bt_4_460800 },
+       {       PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_OCTO_B,
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_b0_bt_4_460800 },
+       {       PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_PORT_PLUS,
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_b0_bt_2_460800 },
+       {       PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_QUAD_A,
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_b0_bt_2_460800 },
+       {       PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_QUAD_B,
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_b0_bt_2_460800 },
+       {       PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_SSERIAL,
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_b0_bt_1_115200 },
+       {       PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_PORT_650,
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_b0_bt_1_460800 },
+
+       /*
+        * Korenix Jetcard F0/F1 cards (JC1204, JC1208, JC1404, JC1408).
+        * Cards are identified by their subsystem vendor IDs, which
+        * (in hex) match the model number.
+        *
+        * Note that JC140x are RS422/485 cards which require ox950
+        * ACR = 0x10, and as such are not currently fully supported.
+        */
+       {       PCI_VENDOR_ID_KORENIX, PCI_DEVICE_ID_KORENIX_JETCARDF0,
+               0x1204, 0x0004, 0, 0,
+               pbn_b0_4_921600 },
+       {       PCI_VENDOR_ID_KORENIX, PCI_DEVICE_ID_KORENIX_JETCARDF0,
+               0x1208, 0x0004, 0, 0,
+               pbn_b0_4_921600 },
+/*     {       PCI_VENDOR_ID_KORENIX, PCI_DEVICE_ID_KORENIX_JETCARDF0,
+               0x1402, 0x0002, 0, 0,
+               pbn_b0_2_921600 }, */
+/*     {       PCI_VENDOR_ID_KORENIX, PCI_DEVICE_ID_KORENIX_JETCARDF0,
+               0x1404, 0x0004, 0, 0,
+               pbn_b0_4_921600 }, */
+       {       PCI_VENDOR_ID_KORENIX, PCI_DEVICE_ID_KORENIX_JETCARDF1,
+               0x1208, 0x0004, 0, 0,
+               pbn_b0_4_921600 },
+
+       {       PCI_VENDOR_ID_KORENIX, PCI_DEVICE_ID_KORENIX_JETCARDF2,
+               0x1204, 0x0004, 0, 0,
+               pbn_b0_4_921600 },
+       {       PCI_VENDOR_ID_KORENIX, PCI_DEVICE_ID_KORENIX_JETCARDF2,
+               0x1208, 0x0004, 0, 0,
+               pbn_b0_4_921600 },
+       {       PCI_VENDOR_ID_KORENIX, PCI_DEVICE_ID_KORENIX_JETCARDF3,
+               0x1208, 0x0004, 0, 0,
+               pbn_b0_4_921600 },
+       /*
+        * Dell Remote Access Card 4 - Tim_T_Murphy@Dell.com
+        */
+       {       PCI_VENDOR_ID_DELL, PCI_DEVICE_ID_DELL_RAC4,
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_b1_1_1382400 },
+
+       /*
+        * Dell Remote Access Card III - Tim_T_Murphy@Dell.com
+        */
+       {       PCI_VENDOR_ID_DELL, PCI_DEVICE_ID_DELL_RACIII,
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_b1_1_1382400 },
+
+       /*
+        * RAStel 2 port modem, gerg@moreton.com.au
+        */
+       {       PCI_VENDOR_ID_MORETON, PCI_DEVICE_ID_RASTEL_2PORT,
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_b2_bt_2_115200 },
+
+       /*
+        * EKF addition for i960 Boards form EKF with serial port
+        */
+       {       PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_80960_RP,
+               0xE4BF, PCI_ANY_ID, 0, 0,
+               pbn_intel_i960 },
+
+       /*
+        * Xircom Cardbus/Ethernet combos
+        */
+       {       PCI_VENDOR_ID_XIRCOM, PCI_DEVICE_ID_XIRCOM_X3201_MDM,
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_b0_1_115200 },
+       /*
+        * Xircom RBM56G cardbus modem - Dirk Arnold (temp entry)
+        */
+       {       PCI_VENDOR_ID_XIRCOM, PCI_DEVICE_ID_XIRCOM_RBM56G,
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_b0_1_115200 },
+
+       /*
+        * Untested PCI modems, sent in from various folks...
+        */
+
+       /*
+        * Elsa Model 56K PCI Modem, from Andreas Rath <arh@01019freenet.de>
+        */
+       {       PCI_VENDOR_ID_ROCKWELL, 0x1004,
+               0x1048, 0x1500, 0, 0,
+               pbn_b1_1_115200 },
+
+       {       PCI_VENDOR_ID_SGI, PCI_DEVICE_ID_SGI_IOC3,
+               0xFF00, 0, 0, 0,
+               pbn_sgi_ioc3 },
+
+       /*
+        * HP Diva card
+        */
+       {       PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_DIVA,
+               PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_DIVA_RMP3, 0, 0,
+               pbn_b1_1_115200 },
+       {       PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_DIVA,
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_b0_5_115200 },
+       {       PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_DIVA_AUX,
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_b2_1_115200 },
+
+       {       PCI_VENDOR_ID_DCI, PCI_DEVICE_ID_DCI_PCCOM2,
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_b3_2_115200 },
+       {       PCI_VENDOR_ID_DCI, PCI_DEVICE_ID_DCI_PCCOM4,
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_b3_4_115200 },
+       {       PCI_VENDOR_ID_DCI, PCI_DEVICE_ID_DCI_PCCOM8,
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_b3_8_115200 },
+
+       /*
+        * Exar Corp. XR17C15[248] Dual/Quad/Octal UART
+        */
+       {       PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17C152,
+               PCI_ANY_ID, PCI_ANY_ID,
+               0,
+               0, pbn_exar_XR17C152 },
+       {       PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17C154,
+               PCI_ANY_ID, PCI_ANY_ID,
+               0,
+               0, pbn_exar_XR17C154 },
+       {       PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17C158,
+               PCI_ANY_ID, PCI_ANY_ID,
+               0,
+               0, pbn_exar_XR17C158 },
+
+       /*
+        * Topic TP560 Data/Fax/Voice 56k modem (reported by Evan Clarke)
+        */
+       {       PCI_VENDOR_ID_TOPIC, PCI_DEVICE_ID_TOPIC_TP560,
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_b0_1_115200 },
+       /*
+        * ITE
+        */
+       {       PCI_VENDOR_ID_ITE, PCI_DEVICE_ID_ITE_8872,
+               PCI_ANY_ID, PCI_ANY_ID,
+               0, 0,
+               pbn_b1_bt_1_115200 },
+
+       /*
+        * IntaShield IS-200
+        */
+       {       PCI_VENDOR_ID_INTASHIELD, PCI_DEVICE_ID_INTASHIELD_IS200,
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,   /* 135a.0811 */
+               pbn_b2_2_115200 },
+       /*
+        * IntaShield IS-400
+        */
+       {       PCI_VENDOR_ID_INTASHIELD, PCI_DEVICE_ID_INTASHIELD_IS400,
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,    /* 135a.0dc0 */
+               pbn_b2_4_115200 },
+       /*
+        * Perle PCI-RAS cards
+        */
+       {       PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9030,
+               PCI_SUBVENDOR_ID_PERLE, PCI_SUBDEVICE_ID_PCI_RAS4,
+               0, 0, pbn_b2_4_921600 },
+       {       PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9030,
+               PCI_SUBVENDOR_ID_PERLE, PCI_SUBDEVICE_ID_PCI_RAS8,
+               0, 0, pbn_b2_8_921600 },
+
+       /*
+        * Mainpine series cards: Fairly standard layout but fools
+        * parts of the autodetect in some cases and uses otherwise
+        * unmatched communications subclasses in the PCI Express case
+        */
+
+       {       /* RockForceDUO */
+               PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
+               PCI_VENDOR_ID_MAINPINE, 0x0200,
+               0, 0, pbn_b0_2_115200 },
+       {       /* RockForceQUATRO */
+               PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
+               PCI_VENDOR_ID_MAINPINE, 0x0300,
+               0, 0, pbn_b0_4_115200 },
+       {       /* RockForceDUO+ */
+               PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
+               PCI_VENDOR_ID_MAINPINE, 0x0400,
+               0, 0, pbn_b0_2_115200 },
+       {       /* RockForceQUATRO+ */
+               PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
+               PCI_VENDOR_ID_MAINPINE, 0x0500,
+               0, 0, pbn_b0_4_115200 },
+       {       /* RockForce+ */
+               PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
+               PCI_VENDOR_ID_MAINPINE, 0x0600,
+               0, 0, pbn_b0_2_115200 },
+       {       /* RockForce+ */
+               PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
+               PCI_VENDOR_ID_MAINPINE, 0x0700,
+               0, 0, pbn_b0_4_115200 },
+       {       /* RockForceOCTO+ */
+               PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
+               PCI_VENDOR_ID_MAINPINE, 0x0800,
+               0, 0, pbn_b0_8_115200 },
+       {       /* RockForceDUO+ */
+               PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
+               PCI_VENDOR_ID_MAINPINE, 0x0C00,
+               0, 0, pbn_b0_2_115200 },
+       {       /* RockForceQUARTRO+ */
+               PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
+               PCI_VENDOR_ID_MAINPINE, 0x0D00,
+               0, 0, pbn_b0_4_115200 },
+       {       /* RockForceOCTO+ */
+               PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
+               PCI_VENDOR_ID_MAINPINE, 0x1D00,
+               0, 0, pbn_b0_8_115200 },
+       {       /* RockForceD1 */
+               PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
+               PCI_VENDOR_ID_MAINPINE, 0x2000,
+               0, 0, pbn_b0_1_115200 },
+       {       /* RockForceF1 */
+               PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
+               PCI_VENDOR_ID_MAINPINE, 0x2100,
+               0, 0, pbn_b0_1_115200 },
+       {       /* RockForceD2 */
+               PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
+               PCI_VENDOR_ID_MAINPINE, 0x2200,
+               0, 0, pbn_b0_2_115200 },
+       {       /* RockForceF2 */
+               PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
+               PCI_VENDOR_ID_MAINPINE, 0x2300,
+               0, 0, pbn_b0_2_115200 },
+       {       /* RockForceD4 */
+               PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
+               PCI_VENDOR_ID_MAINPINE, 0x2400,
+               0, 0, pbn_b0_4_115200 },
+       {       /* RockForceF4 */
+               PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
+               PCI_VENDOR_ID_MAINPINE, 0x2500,
+               0, 0, pbn_b0_4_115200 },
+       {       /* RockForceD8 */
+               PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
+               PCI_VENDOR_ID_MAINPINE, 0x2600,
+               0, 0, pbn_b0_8_115200 },
+       {       /* RockForceF8 */
+               PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
+               PCI_VENDOR_ID_MAINPINE, 0x2700,
+               0, 0, pbn_b0_8_115200 },
+       {       /* IQ Express D1 */
+               PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
+               PCI_VENDOR_ID_MAINPINE, 0x3000,
+               0, 0, pbn_b0_1_115200 },
+       {       /* IQ Express F1 */
+               PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
+               PCI_VENDOR_ID_MAINPINE, 0x3100,
+               0, 0, pbn_b0_1_115200 },
+       {       /* IQ Express D2 */
+               PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
+               PCI_VENDOR_ID_MAINPINE, 0x3200,
+               0, 0, pbn_b0_2_115200 },
+       {       /* IQ Express F2 */
+               PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
+               PCI_VENDOR_ID_MAINPINE, 0x3300,
+               0, 0, pbn_b0_2_115200 },
+       {       /* IQ Express D4 */
+               PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
+               PCI_VENDOR_ID_MAINPINE, 0x3400,
+               0, 0, pbn_b0_4_115200 },
+       {       /* IQ Express F4 */
+               PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
+               PCI_VENDOR_ID_MAINPINE, 0x3500,
+               0, 0, pbn_b0_4_115200 },
+       {       /* IQ Express D8 */
+               PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
+               PCI_VENDOR_ID_MAINPINE, 0x3C00,
+               0, 0, pbn_b0_8_115200 },
+       {       /* IQ Express F8 */
+               PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
+               PCI_VENDOR_ID_MAINPINE, 0x3D00,
+               0, 0, pbn_b0_8_115200 },
+
+
+       /*
+        * PA Semi PA6T-1682M on-chip UART
+        */
+       {       PCI_VENDOR_ID_PASEMI, 0xa004,
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_pasemi_1682M },
+
+       /*
+        * National Instruments
+        */
+       {       PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PCI23216,
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_b1_16_115200 },
+       {       PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PCI2328,
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_b1_8_115200 },
+       {       PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PCI2324,
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_b1_bt_4_115200 },
+       {       PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PCI2322,
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_b1_bt_2_115200 },
+       {       PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PCI2324I,
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_b1_bt_4_115200 },
+       {       PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PCI2322I,
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_b1_bt_2_115200 },
+       {       PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PXI8420_23216,
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_b1_16_115200 },
+       {       PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PXI8420_2328,
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_b1_8_115200 },
+       {       PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PXI8420_2324,
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_b1_bt_4_115200 },
+       {       PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PXI8420_2322,
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_b1_bt_2_115200 },
+       {       PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PXI8422_2324,
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_b1_bt_4_115200 },
+       {       PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PXI8422_2322,
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_b1_bt_2_115200 },
+       {       PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PXI8430_2322,
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_ni8430_2 },
+       {       PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PCI8430_2322,
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_ni8430_2 },
+       {       PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PXI8430_2324,
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_ni8430_4 },
+       {       PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PCI8430_2324,
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_ni8430_4 },
+       {       PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PXI8430_2328,
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_ni8430_8 },
+       {       PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PCI8430_2328,
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_ni8430_8 },
+       {       PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PXI8430_23216,
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_ni8430_16 },
+       {       PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PCI8430_23216,
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_ni8430_16 },
+       {       PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PXI8432_2322,
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_ni8430_2 },
+       {       PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PCI8432_2322,
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_ni8430_2 },
+       {       PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PXI8432_2324,
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_ni8430_4 },
+       {       PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PCI8432_2324,
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_ni8430_4 },
+
+       /*
+       * ADDI-DATA GmbH communication cards <info@addi-data.com>
+       */
+       {       PCI_VENDOR_ID_ADDIDATA,
+               PCI_DEVICE_ID_ADDIDATA_APCI7500,
+               PCI_ANY_ID,
+               PCI_ANY_ID,
+               0,
+               0,
+               pbn_b0_4_115200 },
+
+       {       PCI_VENDOR_ID_ADDIDATA,
+               PCI_DEVICE_ID_ADDIDATA_APCI7420,
+               PCI_ANY_ID,
+               PCI_ANY_ID,
+               0,
+               0,
+               pbn_b0_2_115200 },
+
+       {       PCI_VENDOR_ID_ADDIDATA,
+               PCI_DEVICE_ID_ADDIDATA_APCI7300,
+               PCI_ANY_ID,
+               PCI_ANY_ID,
+               0,
+               0,
+               pbn_b0_1_115200 },
+
+       {       PCI_VENDOR_ID_ADDIDATA_OLD,
+               PCI_DEVICE_ID_ADDIDATA_APCI7800,
+               PCI_ANY_ID,
+               PCI_ANY_ID,
+               0,
+               0,
+               pbn_b1_8_115200 },
+
+       {       PCI_VENDOR_ID_ADDIDATA,
+               PCI_DEVICE_ID_ADDIDATA_APCI7500_2,
+               PCI_ANY_ID,
+               PCI_ANY_ID,
+               0,
+               0,
+               pbn_b0_4_115200 },
+
+       {       PCI_VENDOR_ID_ADDIDATA,
+               PCI_DEVICE_ID_ADDIDATA_APCI7420_2,
+               PCI_ANY_ID,
+               PCI_ANY_ID,
+               0,
+               0,
+               pbn_b0_2_115200 },
+
+       {       PCI_VENDOR_ID_ADDIDATA,
+               PCI_DEVICE_ID_ADDIDATA_APCI7300_2,
+               PCI_ANY_ID,
+               PCI_ANY_ID,
+               0,
+               0,
+               pbn_b0_1_115200 },
+
+       {       PCI_VENDOR_ID_ADDIDATA,
+               PCI_DEVICE_ID_ADDIDATA_APCI7500_3,
+               PCI_ANY_ID,
+               PCI_ANY_ID,
+               0,
+               0,
+               pbn_b0_4_115200 },
+
+       {       PCI_VENDOR_ID_ADDIDATA,
+               PCI_DEVICE_ID_ADDIDATA_APCI7420_3,
+               PCI_ANY_ID,
+               PCI_ANY_ID,
+               0,
+               0,
+               pbn_b0_2_115200 },
+
+       {       PCI_VENDOR_ID_ADDIDATA,
+               PCI_DEVICE_ID_ADDIDATA_APCI7300_3,
+               PCI_ANY_ID,
+               PCI_ANY_ID,
+               0,
+               0,
+               pbn_b0_1_115200 },
+
+       {       PCI_VENDOR_ID_ADDIDATA,
+               PCI_DEVICE_ID_ADDIDATA_APCI7800_3,
+               PCI_ANY_ID,
+               PCI_ANY_ID,
+               0,
+               0,
+               pbn_b0_8_115200 },
+
+       {       PCI_VENDOR_ID_ADDIDATA,
+               PCI_DEVICE_ID_ADDIDATA_APCIe7500,
+               PCI_ANY_ID,
+               PCI_ANY_ID,
+               0,
+               0,
+               pbn_ADDIDATA_PCIe_4_3906250 },
+
+       {       PCI_VENDOR_ID_ADDIDATA,
+               PCI_DEVICE_ID_ADDIDATA_APCIe7420,
+               PCI_ANY_ID,
+               PCI_ANY_ID,
+               0,
+               0,
+               pbn_ADDIDATA_PCIe_2_3906250 },
+
+       {       PCI_VENDOR_ID_ADDIDATA,
+               PCI_DEVICE_ID_ADDIDATA_APCIe7300,
+               PCI_ANY_ID,
+               PCI_ANY_ID,
+               0,
+               0,
+               pbn_ADDIDATA_PCIe_1_3906250 },
+
+       {       PCI_VENDOR_ID_ADDIDATA,
+               PCI_DEVICE_ID_ADDIDATA_APCIe7800,
+               PCI_ANY_ID,
+               PCI_ANY_ID,
+               0,
+               0,
+               pbn_ADDIDATA_PCIe_8_3906250 },
+
+       {       PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9835,
+               PCI_VENDOR_ID_IBM, 0x0299,
+               0, 0, pbn_b0_bt_2_115200 },
+
+       {       PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9901,
+               0xA000, 0x1000,
+               0, 0, pbn_b0_1_115200 },
+
+       /* the 9901 is a rebranded 9912 */
+       {       PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9912,
+               0xA000, 0x1000,
+               0, 0, pbn_b0_1_115200 },
+
+       {       PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9922,
+               0xA000, 0x1000,
+               0, 0, pbn_b0_1_115200 },
+
+       {       PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9904,
+               0xA000, 0x1000,
+               0, 0, pbn_b0_1_115200 },
+
+       {       PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9900,
+               0xA000, 0x1000,
+               0, 0, pbn_b0_1_115200 },
+
+       {       PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9900,
+               0xA000, 0x3002,
+               0, 0, pbn_NETMOS9900_2s_115200 },
+
+       /*
+        * Best Connectivity and Rosewill PCI Multi I/O cards
+        */
+
+       {       PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9865,
+               0xA000, 0x1000,
+               0, 0, pbn_b0_1_115200 },
+
+       {       PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9865,
+               0xA000, 0x3002,
+               0, 0, pbn_b0_bt_2_115200 },
+
+       {       PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9865,
+               0xA000, 0x3004,
+               0, 0, pbn_b0_bt_4_115200 },
+       /* Intel CE4100 */
+       {       PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_CE4100_UART,
+               PCI_ANY_ID,  PCI_ANY_ID, 0, 0,
+               pbn_ce4100_1_115200 },
+
+       /*
+        * Cronyx Omega PCI
+        */
+       {       PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_CRONYX_OMEGA,
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_omegapci },
+
+       /*
+        * These entries match devices with class COMMUNICATION_SERIAL,
+        * COMMUNICATION_MODEM or COMMUNICATION_MULTISERIAL
+        */
+       {       PCI_ANY_ID, PCI_ANY_ID,
+               PCI_ANY_ID, PCI_ANY_ID,
+               PCI_CLASS_COMMUNICATION_SERIAL << 8,
+               0xffff00, pbn_default },
+       {       PCI_ANY_ID, PCI_ANY_ID,
+               PCI_ANY_ID, PCI_ANY_ID,
+               PCI_CLASS_COMMUNICATION_MODEM << 8,
+               0xffff00, pbn_default },
+       {       PCI_ANY_ID, PCI_ANY_ID,
+               PCI_ANY_ID, PCI_ANY_ID,
+               PCI_CLASS_COMMUNICATION_MULTISERIAL << 8,
+               0xffff00, pbn_default },
+       { 0, }
+};
+
+static pci_ers_result_t serial8250_io_error_detected(struct pci_dev *dev,
+                                               pci_channel_state_t state)
+{
+       struct serial_private *priv = pci_get_drvdata(dev);
+
+       if (state == pci_channel_io_perm_failure)
+               return PCI_ERS_RESULT_DISCONNECT;
+
+       if (priv)
+               pciserial_suspend_ports(priv);
+
+       pci_disable_device(dev);
+
+       return PCI_ERS_RESULT_NEED_RESET;
+}
+
+static pci_ers_result_t serial8250_io_slot_reset(struct pci_dev *dev)
+{
+       int rc;
+
+       rc = pci_enable_device(dev);
+
+       if (rc)
+               return PCI_ERS_RESULT_DISCONNECT;
+
+       pci_restore_state(dev);
+       pci_save_state(dev);
+
+       return PCI_ERS_RESULT_RECOVERED;
+}
+
+static void serial8250_io_resume(struct pci_dev *dev)
+{
+       struct serial_private *priv = pci_get_drvdata(dev);
+
+       if (priv)
+               pciserial_resume_ports(priv);
+}
+
+static struct pci_error_handlers serial8250_err_handler = {
+       .error_detected = serial8250_io_error_detected,
+       .slot_reset = serial8250_io_slot_reset,
+       .resume = serial8250_io_resume,
+};
+
+static struct pci_driver serial_pci_driver = {
+       .name           = "serial",
+       .probe          = pciserial_init_one,
+       .remove         = __devexit_p(pciserial_remove_one),
+#ifdef CONFIG_PM
+       .suspend        = pciserial_suspend_one,
+       .resume         = pciserial_resume_one,
+#endif
+       .id_table       = serial_pci_tbl,
+       .err_handler    = &serial8250_err_handler,
+};
+
+static int __init serial8250_pci_init(void)
+{
+       return pci_register_driver(&serial_pci_driver);
+}
+
+static void __exit serial8250_pci_exit(void)
+{
+       pci_unregister_driver(&serial_pci_driver);
+}
+
+module_init(serial8250_pci_init);
+module_exit(serial8250_pci_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Generic 8250/16x50 PCI serial probe module");
+MODULE_DEVICE_TABLE(pci, serial_pci_tbl);
diff --git a/drivers/tty/serial/8250/8250_pnp.c b/drivers/tty/serial/8250/8250_pnp.c
new file mode 100644 (file)
index 0000000..a2f2365
--- /dev/null
@@ -0,0 +1,524 @@
+/*
+ *  Probe module for 8250/16550-type ISAPNP serial ports.
+ *
+ *  Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o.
+ *
+ *  Copyright (C) 2001 Russell King, All Rights Reserved.
+ *
+ *  Ported to the Linux PnP Layer - (C) Adam Belay.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License.
+ */
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/pnp.h>
+#include <linux/string.h>
+#include <linux/kernel.h>
+#include <linux/serial_core.h>
+#include <linux/bitops.h>
+
+#include <asm/byteorder.h>
+
+#include "8250.h"
+
+#define UNKNOWN_DEV 0x3000
+
+
+static const struct pnp_device_id pnp_dev_table[] = {
+       /* Archtek America Corp. */
+       /* Archtek SmartLink Modem 3334BT Plug & Play */
+       {       "AAC000F",              0       },
+       /* Anchor Datacomm BV */
+       /* SXPro 144 External Data Fax Modem Plug & Play */
+       {       "ADC0001",              0       },
+       /* SXPro 288 External Data Fax Modem Plug & Play */
+       {       "ADC0002",              0       },
+       /* PROLiNK 1456VH ISA PnP K56flex Fax Modem */
+       {       "AEI0250",              0       },
+       /* Actiontec ISA PNP 56K X2 Fax Modem */
+       {       "AEI1240",              0       },
+       /* Rockwell 56K ACF II Fax+Data+Voice Modem */
+       {       "AKY1021",              0 /*SPCI_FL_NO_SHIRQ*/  },
+       /* AZT3005 PnP SOUND DEVICE */
+       {       "AZT4001",              0       },
+       /* Best Data Products Inc. Smart One 336F PnP Modem */
+       {       "BDP3336",              0       },
+       /*  Boca Research */
+       /* Boca Complete Ofc Communicator 14.4 Data-FAX */
+       {       "BRI0A49",              0       },
+       /* Boca Research 33,600 ACF Modem */
+       {       "BRI1400",              0       },
+       /* Boca 33.6 Kbps Internal FD34FSVD */
+       {       "BRI3400",              0       },
+       /* Boca 33.6 Kbps Internal FD34FSVD */
+       {       "BRI0A49",              0       },
+       /* Best Data Products Inc. Smart One 336F PnP Modem */
+       {       "BDP3336",              0       },
+       /* Computer Peripherals Inc */
+       /* EuroViVa CommCenter-33.6 SP PnP */
+       {       "CPI4050",              0       },
+       /* Creative Labs */
+       /* Creative Labs Phone Blaster 28.8 DSVD PnP Voice */
+       {       "CTL3001",              0       },
+       /* Creative Labs Modem Blaster 28.8 DSVD PnP Voice */
+       {       "CTL3011",              0       },
+       /* Davicom ISA 33.6K Modem */
+       {       "DAV0336",              0       },
+       /* Creative */
+       /* Creative Modem Blaster Flash56 DI5601-1 */
+       {       "DMB1032",              0       },
+       /* Creative Modem Blaster V.90 DI5660 */
+       {       "DMB2001",              0       },
+       /* E-Tech */
+       /* E-Tech CyberBULLET PC56RVP */
+       {       "ETT0002",              0       },
+       /* FUJITSU */
+       /* Fujitsu 33600 PnP-I2 R Plug & Play */
+       {       "FUJ0202",              0       },
+       /* Fujitsu FMV-FX431 Plug & Play */
+       {       "FUJ0205",              0       },
+       /* Fujitsu 33600 PnP-I4 R Plug & Play */
+       {       "FUJ0206",              0       },
+       /* Fujitsu Fax Voice 33600 PNP-I5 R Plug & Play */
+       {       "FUJ0209",              0       },
+       /* Archtek America Corp. */
+       /* Archtek SmartLink Modem 3334BT Plug & Play */
+       {       "GVC000F",              0       },
+       /* Archtek SmartLink Modem 3334BRV 33.6K Data Fax Voice */
+       {       "GVC0303",              0       },
+       /* Hayes */
+       /* Hayes Optima 288 V.34-V.FC + FAX + Voice Plug & Play */
+       {       "HAY0001",              0       },
+       /* Hayes Optima 336 V.34 + FAX + Voice PnP */
+       {       "HAY000C",              0       },
+       /* Hayes Optima 336B V.34 + FAX + Voice PnP */
+       {       "HAY000D",              0       },
+       /* Hayes Accura 56K Ext Fax Modem PnP */
+       {       "HAY5670",              0       },
+       /* Hayes Accura 56K Ext Fax Modem PnP */
+       {       "HAY5674",              0       },
+       /* Hayes Accura 56K Fax Modem PnP */
+       {       "HAY5675",              0       },
+       /* Hayes 288, V.34 + FAX */
+       {       "HAYF000",              0       },
+       /* Hayes Optima 288 V.34 + FAX + Voice, Plug & Play */
+       {       "HAYF001",              0       },
+       /* IBM */
+       /* IBM Thinkpad 701 Internal Modem Voice */
+       {       "IBM0033",              0       },
+       /* Intermec */
+       /* Intermec CV60 touchscreen port */
+       {       "PNP4972",              0       },
+       /* Intertex */
+       /* Intertex 28k8 33k6 Voice EXT PnP */
+       {       "IXDC801",              0       },
+       /* Intertex 33k6 56k Voice EXT PnP */
+       {       "IXDC901",              0       },
+       /* Intertex 28k8 33k6 Voice SP EXT PnP */
+       {       "IXDD801",              0       },
+       /* Intertex 33k6 56k Voice SP EXT PnP */
+       {       "IXDD901",              0       },
+       /* Intertex 28k8 33k6 Voice SP INT PnP */
+       {       "IXDF401",              0       },
+       /* Intertex 28k8 33k6 Voice SP EXT PnP */
+       {       "IXDF801",              0       },
+       /* Intertex 33k6 56k Voice SP EXT PnP */
+       {       "IXDF901",              0       },
+       /* Kortex International */
+       /* KORTEX 28800 Externe PnP */
+       {       "KOR4522",              0       },
+       /* KXPro 33.6 Vocal ASVD PnP */
+       {       "KORF661",              0       },
+       /* Lasat */
+       /* LASAT Internet 33600 PnP */
+       {       "LAS4040",              0       },
+       /* Lasat Safire 560 PnP */
+       {       "LAS4540",              0       },
+       /* Lasat Safire 336  PnP */
+       {       "LAS5440",              0       },
+       /* Microcom, Inc. */
+       /* Microcom TravelPorte FAST V.34 Plug & Play */
+       {       "MNP0281",              0       },
+       /* Microcom DeskPorte V.34 FAST or FAST+ Plug & Play */
+       {       "MNP0336",              0       },
+       /* Microcom DeskPorte FAST EP 28.8 Plug & Play */
+       {       "MNP0339",              0       },
+       /* Microcom DeskPorte 28.8P Plug & Play */
+       {       "MNP0342",              0       },
+       /* Microcom DeskPorte FAST ES 28.8 Plug & Play */
+       {       "MNP0500",              0       },
+       /* Microcom DeskPorte FAST ES 28.8 Plug & Play */
+       {       "MNP0501",              0       },
+       /* Microcom DeskPorte 28.8S Internal Plug & Play */
+       {       "MNP0502",              0       },
+       /* Motorola */
+       /* Motorola BitSURFR Plug & Play */
+       {       "MOT1105",              0       },
+       /* Motorola TA210 Plug & Play */
+       {       "MOT1111",              0       },
+       /* Motorola HMTA 200 (ISDN) Plug & Play */
+       {       "MOT1114",              0       },
+       /* Motorola BitSURFR Plug & Play */
+       {       "MOT1115",              0       },
+       /* Motorola Lifestyle 28.8 Internal */
+       {       "MOT1190",              0       },
+       /* Motorola V.3400 Plug & Play */
+       {       "MOT1501",              0       },
+       /* Motorola Lifestyle 28.8 V.34 Plug & Play */
+       {       "MOT1502",              0       },
+       /* Motorola Power 28.8 V.34 Plug & Play */
+       {       "MOT1505",              0       },
+       /* Motorola ModemSURFR External 28.8 Plug & Play */
+       {       "MOT1509",              0       },
+       /* Motorola Premier 33.6 Desktop Plug & Play */
+       {       "MOT150A",              0       },
+       /* Motorola VoiceSURFR 56K External PnP */
+       {       "MOT150F",              0       },
+       /* Motorola ModemSURFR 56K External PnP */
+       {       "MOT1510",              0       },
+       /* Motorola ModemSURFR 56K Internal PnP */
+       {       "MOT1550",              0       },
+       /* Motorola ModemSURFR Internal 28.8 Plug & Play */
+       {       "MOT1560",              0       },
+       /* Motorola Premier 33.6 Internal Plug & Play */
+       {       "MOT1580",              0       },
+       /* Motorola OnlineSURFR 28.8 Internal Plug & Play */
+       {       "MOT15B0",              0       },
+       /* Motorola VoiceSURFR 56K Internal PnP */
+       {       "MOT15F0",              0       },
+       /* Com 1 */
+       /*  Deskline K56 Phone System PnP */
+       {       "MVX00A1",              0       },
+       /* PC Rider K56 Phone System PnP */
+       {       "MVX00F2",              0       },
+       /* NEC 98NOTE SPEAKER PHONE FAX MODEM(33600bps) */
+       {       "nEC8241",              0       },
+       /* Pace 56 Voice Internal Plug & Play Modem */
+       {       "PMC2430",              0       },
+       /* Generic */
+       /* Generic standard PC COM port  */
+       {       "PNP0500",              0       },
+       /* Generic 16550A-compatible COM port */
+       {       "PNP0501",              0       },
+       /* Compaq 14400 Modem */
+       {       "PNPC000",              0       },
+       /* Compaq 2400/9600 Modem */
+       {       "PNPC001",              0       },
+       /* Dial-Up Networking Serial Cable between 2 PCs */
+       {       "PNPC031",              0       },
+       /* Dial-Up Networking Parallel Cable between 2 PCs */
+       {       "PNPC032",              0       },
+       /* Standard 9600 bps Modem */
+       {       "PNPC100",              0       },
+       /* Standard 14400 bps Modem */
+       {       "PNPC101",              0       },
+       /*  Standard 28800 bps Modem*/
+       {       "PNPC102",              0       },
+       /*  Standard Modem*/
+       {       "PNPC103",              0       },
+       /*  Standard 9600 bps Modem*/
+       {       "PNPC104",              0       },
+       /*  Standard 14400 bps Modem*/
+       {       "PNPC105",              0       },
+       /*  Standard 28800 bps Modem*/
+       {       "PNPC106",              0       },
+       /*  Standard Modem */
+       {       "PNPC107",              0       },
+       /* Standard 9600 bps Modem */
+       {       "PNPC108",              0       },
+       /* Standard 14400 bps Modem */
+       {       "PNPC109",              0       },
+       /* Standard 28800 bps Modem */
+       {       "PNPC10A",              0       },
+       /* Standard Modem */
+       {       "PNPC10B",              0       },
+       /* Standard 9600 bps Modem */
+       {       "PNPC10C",              0       },
+       /* Standard 14400 bps Modem */
+       {       "PNPC10D",              0       },
+       /* Standard 28800 bps Modem */
+       {       "PNPC10E",              0       },
+       /* Standard Modem */
+       {       "PNPC10F",              0       },
+       /* Standard PCMCIA Card Modem */
+       {       "PNP2000",              0       },
+       /* Rockwell */
+       /* Modular Technology */
+       /* Rockwell 33.6 DPF Internal PnP */
+       /* Modular Technology 33.6 Internal PnP */
+       {       "ROK0030",              0       },
+       /* Kortex International */
+       /* KORTEX 14400 Externe PnP */
+       {       "ROK0100",              0       },
+       /* Rockwell 28.8 */
+       {       "ROK4120",              0       },
+       /* Viking Components, Inc */
+       /* Viking 28.8 INTERNAL Fax+Data+Voice PnP */
+       {       "ROK4920",              0       },
+       /* Rockwell */
+       /* British Telecom */
+       /* Modular Technology */
+       /* Rockwell 33.6 DPF External PnP */
+       /* BT Prologue 33.6 External PnP */
+       /* Modular Technology 33.6 External PnP */
+       {       "RSS00A0",              0       },
+       /* Viking 56K FAX INT */
+       {       "RSS0262",              0       },
+       /* K56 par,VV,Voice,Speakphone,AudioSpan,PnP */
+       {       "RSS0250",              0       },
+       /* SupraExpress 28.8 Data/Fax PnP modem */
+       {       "SUP1310",              0       },
+       /* SupraExpress 336i PnP Voice Modem */
+       {       "SUP1381",              0       },
+       /* SupraExpress 33.6 Data/Fax PnP modem */
+       {       "SUP1421",              0       },
+       /* SupraExpress 33.6 Data/Fax PnP modem */
+       {       "SUP1590",              0       },
+       /* SupraExpress 336i Sp ASVD */
+       {       "SUP1620",              0       },
+       /* SupraExpress 33.6 Data/Fax PnP modem */
+       {       "SUP1760",              0       },
+       /* SupraExpress 56i Sp Intl */
+       {       "SUP2171",              0       },
+       /* Phoebe Micro */
+       /* Phoebe Micro 33.6 Data Fax 1433VQH Plug & Play */
+       {       "TEX0011",              0       },
+       /* Archtek America Corp. */
+       /* Archtek SmartLink Modem 3334BT Plug & Play */
+       {       "UAC000F",              0       },
+       /* 3Com Corp. */
+       /* Gateway Telepath IIvi 33.6 */
+       {       "USR0000",              0       },
+       /* U.S. Robotics Sporster 33.6K Fax INT PnP */
+       {       "USR0002",              0       },
+       /*  Sportster Vi 14.4 PnP FAX Voicemail */
+       {       "USR0004",              0       },
+       /* U.S. Robotics 33.6K Voice INT PnP */
+       {       "USR0006",              0       },
+       /* U.S. Robotics 33.6K Voice EXT PnP */
+       {       "USR0007",              0       },
+       /* U.S. Robotics Courier V.Everything INT PnP */
+       {       "USR0009",              0       },
+       /* U.S. Robotics 33.6K Voice INT PnP */
+       {       "USR2002",              0       },
+       /* U.S. Robotics 56K Voice INT PnP */
+       {       "USR2070",              0       },
+       /* U.S. Robotics 56K Voice EXT PnP */
+       {       "USR2080",              0       },
+       /* U.S. Robotics 56K FAX INT */
+       {       "USR3031",              0       },
+       /* U.S. Robotics 56K FAX INT */
+       {       "USR3050",              0       },
+       /* U.S. Robotics 56K Voice INT PnP */
+       {       "USR3070",              0       },
+       /* U.S. Robotics 56K Voice EXT PnP */
+       {       "USR3080",              0       },
+       /* U.S. Robotics 56K Voice INT PnP */
+       {       "USR3090",              0       },
+       /* U.S. Robotics 56K Message  */
+       {       "USR9100",              0       },
+       /* U.S. Robotics 56K FAX EXT PnP*/
+       {       "USR9160",              0       },
+       /* U.S. Robotics 56K FAX INT PnP*/
+       {       "USR9170",              0       },
+       /* U.S. Robotics 56K Voice EXT PnP*/
+       {       "USR9180",              0       },
+       /* U.S. Robotics 56K Voice INT PnP*/
+       {       "USR9190",              0       },
+       /* Wacom tablets */
+       {       "WACFXXX",              0       },
+       /* Compaq touchscreen */
+       {       "FPI2002",              0 },
+       /* Fujitsu Stylistic touchscreens */
+       {       "FUJ02B2",              0 },
+       {       "FUJ02B3",              0 },
+       /* Fujitsu Stylistic LT touchscreens */
+       {       "FUJ02B4",              0 },
+       /* Passive Fujitsu Stylistic touchscreens */
+       {       "FUJ02B6",              0 },
+       {       "FUJ02B7",              0 },
+       {       "FUJ02B8",              0 },
+       {       "FUJ02B9",              0 },
+       {       "FUJ02BC",              0 },
+       /* Fujitsu Wacom Tablet PC device */
+       {       "FUJ02E5",              0       },
+       /* Fujitsu P-series tablet PC device */
+       {       "FUJ02E6",              0       },
+       /* Fujitsu Wacom 2FGT Tablet PC device */
+       {       "FUJ02E7",              0       },
+       /* Fujitsu Wacom 1FGT Tablet PC device */
+       {       "FUJ02E9",              0       },
+       /*
+        * LG C1 EXPRESS DUAL (C1-PB11A3) touch screen (actually a FUJ02E6 in
+        * disguise)
+        */
+       {       "LTS0001",              0       },
+       /* Rockwell's (PORALiNK) 33600 INT PNP */
+       {       "WCI0003",              0       },
+       /* Unknown PnP modems */
+       {       "PNPCXXX",              UNKNOWN_DEV     },
+       /* More unknown PnP modems */
+       {       "PNPDXXX",              UNKNOWN_DEV     },
+       {       "",                     0       }
+};
+
+MODULE_DEVICE_TABLE(pnp, pnp_dev_table);
+
+static char *modem_names[] __devinitdata = {
+       "MODEM", "Modem", "modem", "FAX", "Fax", "fax",
+       "56K", "56k", "K56", "33.6", "28.8", "14.4",
+       "33,600", "28,800", "14,400", "33.600", "28.800", "14.400",
+       "33600", "28800", "14400", "V.90", "V.34", "V.32", NULL
+};
+
+static int __devinit check_name(char *name)
+{
+       char **tmp;
+
+       for (tmp = modem_names; *tmp; tmp++)
+               if (strstr(name, *tmp))
+                       return 1;
+
+       return 0;
+}
+
+static int __devinit check_resources(struct pnp_dev *dev)
+{
+       resource_size_t base[] = {0x2f8, 0x3f8, 0x2e8, 0x3e8};
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(base); i++) {
+               if (pnp_possible_config(dev, IORESOURCE_IO, base[i], 8))
+                       return 1;
+       }
+
+       return 0;
+}
+
+/*
+ * Given a complete unknown PnP device, try to use some heuristics to
+ * detect modems. Currently use such heuristic set:
+ *     - dev->name or dev->bus->name must contain "modem" substring;
+ *     - device must have only one IO region (8 byte long) with base address
+ *       0x2e8, 0x3e8, 0x2f8 or 0x3f8.
+ *
+ * Such detection looks very ugly, but can detect at least some of numerous
+ * PnP modems, alternatively we must hardcode all modems in pnp_devices[]
+ * table.
+ */
+static int __devinit serial_pnp_guess_board(struct pnp_dev *dev, int *flags)
+{
+       if (!(check_name(pnp_dev_name(dev)) ||
+               (dev->card && check_name(dev->card->name))))
+                       return -ENODEV;
+
+       if (check_resources(dev))
+               return 0;
+
+       return -ENODEV;
+}
+
+static int __devinit
+serial_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id *dev_id)
+{
+       struct uart_port port;
+       int ret, line, flags = dev_id->driver_data;
+
+       if (flags & UNKNOWN_DEV) {
+               ret = serial_pnp_guess_board(dev, &flags);
+               if (ret < 0)
+                       return ret;
+       }
+
+       memset(&port, 0, sizeof(struct uart_port));
+       if (pnp_irq_valid(dev, 0))
+               port.irq = pnp_irq(dev, 0);
+       if (pnp_port_valid(dev, 0)) {
+               port.iobase = pnp_port_start(dev, 0);
+               port.iotype = UPIO_PORT;
+       } else if (pnp_mem_valid(dev, 0)) {
+               port.mapbase = pnp_mem_start(dev, 0);
+               port.iotype = UPIO_MEM;
+               port.flags = UPF_IOREMAP;
+       } else
+               return -ENODEV;
+
+#ifdef SERIAL_DEBUG_PNP
+       printk(KERN_DEBUG
+               "Setup PNP port: port %x, mem 0x%lx, irq %d, type %d\n",
+                      port.iobase, port.mapbase, port.irq, port.iotype);
+#endif
+
+       port.flags |= UPF_SKIP_TEST | UPF_BOOT_AUTOCONF;
+       if (pnp_irq_flags(dev, 0) & IORESOURCE_IRQ_SHAREABLE)
+               port.flags |= UPF_SHARE_IRQ;
+       port.uartclk = 1843200;
+       port.dev = &dev->dev;
+
+       line = serial8250_register_port(&port);
+       if (line < 0)
+               return -ENODEV;
+
+       pnp_set_drvdata(dev, (void *)((long)line + 1));
+       return 0;
+}
+
+static void __devexit serial_pnp_remove(struct pnp_dev *dev)
+{
+       long line = (long)pnp_get_drvdata(dev);
+       if (line)
+               serial8250_unregister_port(line - 1);
+}
+
+#ifdef CONFIG_PM
+static int serial_pnp_suspend(struct pnp_dev *dev, pm_message_t state)
+{
+       long line = (long)pnp_get_drvdata(dev);
+
+       if (!line)
+               return -ENODEV;
+       serial8250_suspend_port(line - 1);
+       return 0;
+}
+
+static int serial_pnp_resume(struct pnp_dev *dev)
+{
+       long line = (long)pnp_get_drvdata(dev);
+
+       if (!line)
+               return -ENODEV;
+       serial8250_resume_port(line - 1);
+       return 0;
+}
+#else
+#define serial_pnp_suspend NULL
+#define serial_pnp_resume NULL
+#endif /* CONFIG_PM */
+
+static struct pnp_driver serial_pnp_driver = {
+       .name           = "serial",
+       .probe          = serial_pnp_probe,
+       .remove         = __devexit_p(serial_pnp_remove),
+       .suspend        = serial_pnp_suspend,
+       .resume         = serial_pnp_resume,
+       .id_table       = pnp_dev_table,
+};
+
+static int __init serial8250_pnp_init(void)
+{
+       return pnp_register_driver(&serial_pnp_driver);
+}
+
+static void __exit serial8250_pnp_exit(void)
+{
+       pnp_unregister_driver(&serial_pnp_driver);
+}
+
+module_init(serial8250_pnp_init);
+module_exit(serial8250_pnp_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Generic 8250/16x50 PnP serial driver");
diff --git a/drivers/tty/serial/8250/Kconfig b/drivers/tty/serial/8250/Kconfig
new file mode 100644 (file)
index 0000000..591f801
--- /dev/null
@@ -0,0 +1,280 @@
+#
+# The 8250/16550 serial drivers.  You shouldn't be in this list unless
+# you somehow have an implicit or explicit dependency on SERIAL_8250.
+#
+
+config SERIAL_8250
+       tristate "8250/16550 and compatible serial support"
+       select SERIAL_CORE
+       ---help---
+         This selects whether you want to include the driver for the standard
+         serial ports.  The standard answer is Y.  People who might say N
+         here are those that are setting up dedicated Ethernet WWW/FTP
+         servers, or users that have one of the various bus mice instead of a
+         serial mouse and don't intend to use their machine's standard serial
+         port for anything.  (Note that the Cyclades and Stallion multi
+         serial port drivers do not need this driver built in for them to
+         work.)
+
+         To compile this driver as a module, choose M here: the
+         module will be called 8250.
+         [WARNING: Do not compile this driver as a module if you are using
+         non-standard serial ports, since the configuration information will
+         be lost when the driver is unloaded.  This limitation may be lifted
+         in the future.]
+
+         BTW1: If you have a mouseman serial mouse which is not recognized by
+         the X window system, try running gpm first.
+
+         BTW2: If you intend to use a software modem (also called Winmodem)
+         under Linux, forget it.  These modems are crippled and require
+         proprietary drivers which are only available under Windows.
+
+         Most people will say Y or M here, so that they can use serial mice,
+         modems and similar devices connecting to the standard serial ports.
+
+config SERIAL_8250_CONSOLE
+       bool "Console on 8250/16550 and compatible serial port"
+       depends on SERIAL_8250=y
+       select SERIAL_CORE_CONSOLE
+       ---help---
+         If you say Y here, it will be possible to use a serial port as the
+         system console (the system console is the device which receives all
+         kernel messages and warnings and which allows logins in single user
+         mode). This could be useful if some terminal or printer is connected
+         to that serial port.
+
+         Even if you say Y here, the currently visible virtual console
+         (/dev/tty0) will still be used as the system console by default, but
+         you can alter that using a kernel command line option such as
+         "console=ttyS1". (Try "man bootparam" or see the documentation of
+         your boot loader (grub or lilo or loadlin) about how to pass options
+         to the kernel at boot time.)
+
+         If you don't have a VGA card installed and you say Y here, the
+         kernel will automatically use the first serial line, /dev/ttyS0, as
+         system console.
+
+         You can set that using a kernel command line option such as
+         "console=uart8250,io,0x3f8,9600n8"
+         "console=uart8250,mmio,0xff5e0000,115200n8".
+         and it will switch to normal serial console when the corresponding
+         port is ready.
+         "earlycon=uart8250,io,0x3f8,9600n8"
+         "earlycon=uart8250,mmio,0xff5e0000,115200n8".
+         it will not only setup early console.
+
+         If unsure, say N.
+
+config FIX_EARLYCON_MEM
+       bool
+       depends on X86
+       default y
+
+config SERIAL_8250_GSC
+       tristate
+       depends on SERIAL_8250 && GSC
+       default SERIAL_8250
+
+config SERIAL_8250_PCI
+       tristate "8250/16550 PCI device support" if EXPERT
+       depends on SERIAL_8250 && PCI
+       default SERIAL_8250
+       help
+         This builds standard PCI serial support. You may be able to
+         disable this feature if you only need legacy serial support.
+         Saves about 9K.
+
+config SERIAL_8250_PNP
+       tristate "8250/16550 PNP device support" if EXPERT
+       depends on SERIAL_8250 && PNP
+       default SERIAL_8250
+       help
+         This builds standard PNP serial support. You may be able to
+         disable this feature if you only need legacy serial support.
+
+config SERIAL_8250_HP300
+       tristate
+       depends on SERIAL_8250 && HP300
+       default SERIAL_8250
+
+config SERIAL_8250_CS
+       tristate "8250/16550 PCMCIA device support"
+       depends on PCMCIA && SERIAL_8250
+       ---help---
+         Say Y here to enable support for 16-bit PCMCIA serial devices,
+         including serial port cards, modems, and the modem functions of
+         multi-function Ethernet/modem cards. (PCMCIA- or PC-cards are
+         credit-card size devices often used with laptops.)
+
+         To compile this driver as a module, choose M here: the
+         module will be called serial_cs.
+
+         If unsure, say N.
+
+config SERIAL_8250_NR_UARTS
+       int "Maximum number of 8250/16550 serial ports"
+       depends on SERIAL_8250
+       default "4"
+       help
+         Set this to the number of serial ports you want the driver
+         to support.  This includes any ports discovered via ACPI or
+         PCI enumeration and any ports that may be added at run-time
+         via hot-plug, or any ISA multi-port serial cards.
+
+config SERIAL_8250_RUNTIME_UARTS
+       int "Number of 8250/16550 serial ports to register at runtime"
+       depends on SERIAL_8250
+       range 0 SERIAL_8250_NR_UARTS
+       default "4"
+       help
+         Set this to the maximum number of serial ports you want
+         the kernel to register at boot time.  This can be overridden
+         with the module parameter "nr_uarts", or boot-time parameter
+         8250.nr_uarts
+
+config SERIAL_8250_EXTENDED
+       bool "Extended 8250/16550 serial driver options"
+       depends on SERIAL_8250
+       help
+         If you wish to use any non-standard features of the standard "dumb"
+         driver, say Y here. This includes HUB6 support, shared serial
+         interrupts, special multiport support, support for more than the
+         four COM 1/2/3/4 boards, etc.
+
+         Note that the answer to this question won't directly affect the
+         kernel: saying N will just cause the configurator to skip all
+         the questions about serial driver options. If unsure, say N.
+
+config SERIAL_8250_MANY_PORTS
+       bool "Support more than 4 legacy serial ports"
+       depends on SERIAL_8250_EXTENDED && !IA64
+       help
+         Say Y here if you have dumb serial boards other than the four
+         standard COM 1/2/3/4 ports. This may happen if you have an AST
+         FourPort, Accent Async, Boca (read the Boca mini-HOWTO, available
+         from <http://www.tldp.org/docs.html#howto>), or other custom
+         serial port hardware which acts similar to standard serial port
+         hardware. If you only use the standard COM 1/2/3/4 ports, you can
+         say N here to save some memory. You can also say Y if you have an
+         "intelligent" multiport card such as Cyclades, Digiboards, etc.
+
+#
+# Multi-port serial cards
+#
+
+config SERIAL_8250_FOURPORT
+       tristate "Support Fourport cards"
+       depends on SERIAL_8250 != n && ISA && SERIAL_8250_MANY_PORTS
+       help
+         Say Y here if you have an AST FourPort serial board.
+
+         To compile this driver as a module, choose M here: the module
+         will be called 8250_fourport.
+
+config SERIAL_8250_ACCENT
+       tristate "Support Accent cards"
+       depends on SERIAL_8250 != n && ISA && SERIAL_8250_MANY_PORTS
+       help
+         Say Y here if you have an Accent Async serial board.
+
+         To compile this driver as a module, choose M here: the module
+         will be called 8250_accent.
+
+config SERIAL_8250_BOCA
+       tristate "Support Boca cards"
+       depends on SERIAL_8250 != n && ISA && SERIAL_8250_MANY_PORTS
+       help
+         Say Y here if you have a Boca serial board.  Please read the Boca
+         mini-HOWTO, available from <http://www.tldp.org/docs.html#howto>
+
+         To compile this driver as a module, choose M here: the module
+         will be called 8250_boca.
+
+config SERIAL_8250_EXAR_ST16C554
+       tristate "Support Exar ST16C554/554D Quad UART"
+       depends on SERIAL_8250 != n && ISA && SERIAL_8250_MANY_PORTS
+       help
+         The Uplogix Envoy TU301 uses this Exar Quad UART.  If you are
+         tinkering with your Envoy TU301, or have a machine with this UART,
+         say Y here.
+
+         To compile this driver as a module, choose M here: the module
+         will be called 8250_exar_st16c554.
+
+config SERIAL_8250_HUB6
+       tristate "Support Hub6 cards"
+       depends on SERIAL_8250 != n && ISA && SERIAL_8250_MANY_PORTS
+       help
+         Say Y here if you have a HUB6 serial board.
+
+         To compile this driver as a module, choose M here: the module
+         will be called 8250_hub6.
+
+#
+# Misc. options/drivers.
+#
+
+config SERIAL_8250_SHARE_IRQ
+       bool "Support for sharing serial interrupts"
+       depends on SERIAL_8250_EXTENDED
+       help
+         Some serial boards have hardware support which allows multiple dumb
+         serial ports on the same board to share a single IRQ. To enable
+         support for this in the serial driver, say Y here.
+
+config SERIAL_8250_DETECT_IRQ
+       bool "Autodetect IRQ on standard ports (unsafe)"
+       depends on SERIAL_8250_EXTENDED
+       help
+         Say Y here if you want the kernel to try to guess which IRQ
+         to use for your serial port.
+
+         This is considered unsafe; it is far better to configure the IRQ in
+         a boot script using the setserial command.
+
+         If unsure, say N.
+
+config SERIAL_8250_RSA
+       bool "Support RSA serial ports"
+       depends on SERIAL_8250_EXTENDED
+       help
+         ::: To be written :::
+
+config SERIAL_8250_MCA
+       tristate "Support 8250-type ports on MCA buses"
+       depends on SERIAL_8250 != n && MCA
+       help
+         Say Y here if you have a MCA serial ports.
+
+         To compile this driver as a module, choose M here: the module
+         will be called 8250_mca.
+
+config SERIAL_8250_ACORN
+       tristate "Acorn expansion card serial port support"
+       depends on ARCH_ACORN && SERIAL_8250
+       help
+         If you have an Atomwide Serial card or Serial Port card for an Acorn
+         system, say Y to this option.  The driver can handle 1, 2, or 3 port
+         cards.  If unsure, say N.
+
+config SERIAL_8250_RM9K
+       bool "Support for MIPS RM9xxx integrated serial port"
+       depends on SERIAL_8250 != n && SERIAL_RM9000
+       select SERIAL_8250_SHARE_IRQ
+       help
+         Selecting this option will add support for the integrated serial
+         port hardware found on MIPS RM9122 and similar processors.
+         If unsure, say N.
+
+config SERIAL_8250_FSL
+       bool
+       depends on SERIAL_8250_CONSOLE && PPC_UDBG_16550
+       default PPC
+
+config SERIAL_8250_DW
+       tristate "Support for Synopsys DesignWare 8250 quirks"
+       depends on SERIAL_8250 && OF
+       help
+         Selecting this option will enable handling of the extra features
+         present in the Synopsys DesignWare APB UART.
diff --git a/drivers/tty/serial/8250/Makefile b/drivers/tty/serial/8250/Makefile
new file mode 100644 (file)
index 0000000..867bba7
--- /dev/null
@@ -0,0 +1,20 @@
+#
+# Makefile for the 8250 serial device drivers.
+#
+
+obj-$(CONFIG_SERIAL_8250)              += 8250.o
+obj-$(CONFIG_SERIAL_8250_PNP)          += 8250_pnp.o
+obj-$(CONFIG_SERIAL_8250_GSC)          += 8250_gsc.o
+obj-$(CONFIG_SERIAL_8250_PCI)          += 8250_pci.o
+obj-$(CONFIG_SERIAL_8250_HP300)                += 8250_hp300.o
+obj-$(CONFIG_SERIAL_8250_CS)           += serial_cs.o
+obj-$(CONFIG_SERIAL_8250_ACORN)                += 8250_acorn.o
+obj-$(CONFIG_SERIAL_8250_CONSOLE)      += 8250_early.o
+obj-$(CONFIG_SERIAL_8250_FOURPORT)     += 8250_fourport.o
+obj-$(CONFIG_SERIAL_8250_ACCENT)       += 8250_accent.o
+obj-$(CONFIG_SERIAL_8250_BOCA)         += 8250_boca.o
+obj-$(CONFIG_SERIAL_8250_EXAR_ST16C554)        += 8250_exar_st16c554.o
+obj-$(CONFIG_SERIAL_8250_HUB6)         += 8250_hub6.o
+obj-$(CONFIG_SERIAL_8250_MCA)          += 8250_mca.o
+obj-$(CONFIG_SERIAL_8250_FSL)          += 8250_fsl.o
+obj-$(CONFIG_SERIAL_8250_DW)           += 8250_dw.o
diff --git a/drivers/tty/serial/8250/serial_cs.c b/drivers/tty/serial/8250/serial_cs.c
new file mode 100644 (file)
index 0000000..8609060
--- /dev/null
@@ -0,0 +1,870 @@
+/*======================================================================
+
+    A driver for PCMCIA serial devices
+
+    serial_cs.c 1.134 2002/05/04 05:48:53
+
+    The contents of this file are subject to the Mozilla Public
+    License Version 1.1 (the "License"); you may not use this file
+    except in compliance with the License. You may obtain a copy of
+    the License at http://www.mozilla.org/MPL/
+
+    Software distributed under the License is distributed on an "AS
+    IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+    implied. See the License for the specific language governing
+    rights and limitations under the License.
+
+    The initial developer of the original code is David A. Hinds
+    <dahinds@users.sourceforge.net>.  Portions created by David A. Hinds
+    are Copyright (C) 1999 David A. Hinds.  All Rights Reserved.
+
+    Alternatively, the contents of this file may be used under the
+    terms of the GNU General Public License version 2 (the "GPL"), in which
+    case the provisions of the GPL are applicable instead of the
+    above.  If you wish to allow the use of your version of this file
+    only under the terms of the GPL and not to allow others to use
+    your version of this file under the MPL, indicate your decision
+    by deleting the provisions above and replace them with the notice
+    and other provisions required by the GPL.  If you do not delete
+    the provisions above, a recipient may use your version of this
+    file under either the MPL or the GPL.
+    
+======================================================================*/
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/ptrace.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <linux/timer.h>
+#include <linux/serial_core.h>
+#include <linux/delay.h>
+#include <linux/major.h>
+#include <asm/io.h>
+#include <asm/system.h>
+
+#include <pcmcia/cistpl.h>
+#include <pcmcia/ciscode.h>
+#include <pcmcia/ds.h>
+#include <pcmcia/cisreg.h>
+
+#include "8250.h"
+
+
+/*====================================================================*/
+
+/* Parameters that can be set with 'insmod' */
+
+/* Enable the speaker? */
+static int do_sound = 1;
+/* Skip strict UART tests? */
+static int buggy_uart;
+
+module_param(do_sound, int, 0444);
+module_param(buggy_uart, int, 0444);
+
+/*====================================================================*/
+
+/* Table of multi-port card ID's */
+
+struct serial_quirk {
+       unsigned int manfid;
+       unsigned int prodid;
+       int multi;              /* 1 = multifunction, > 1 = # ports */
+       void (*config)(struct pcmcia_device *);
+       void (*setup)(struct pcmcia_device *, struct uart_port *);
+       void (*wakeup)(struct pcmcia_device *);
+       int (*post)(struct pcmcia_device *);
+};
+
+struct serial_info {
+       struct pcmcia_device    *p_dev;
+       int                     ndev;
+       int                     multi;
+       int                     slave;
+       int                     manfid;
+       int                     prodid;
+       int                     c950ctrl;
+       int                     line[4];
+       const struct serial_quirk *quirk;
+};
+
+struct serial_cfg_mem {
+       tuple_t tuple;
+       cisparse_t parse;
+       u_char buf[256];
+};
+
+/*
+ * vers_1 5.0, "Brain Boxes", "2-Port RS232 card", "r6"
+ * manfid 0x0160, 0x0104
+ * This card appears to have a 14.7456MHz clock.
+ */
+/* Generic Modem: MD55x (GPRS/EDGE) have
+ * Elan VPU16551 UART with 14.7456MHz oscillator
+ * manfid 0x015D, 0x4C45
+ */
+static void quirk_setup_brainboxes_0104(struct pcmcia_device *link, struct uart_port *port)
+{
+       port->uartclk = 14745600;
+}
+
+static int quirk_post_ibm(struct pcmcia_device *link)
+{
+       u8 val;
+       int ret;
+
+       ret = pcmcia_read_config_byte(link, 0x800, &val);
+       if (ret)
+               goto failed;
+
+       ret = pcmcia_write_config_byte(link, 0x800, val | 1);
+       if (ret)
+               goto failed;
+       return 0;
+
+ failed:
+       return -ENODEV;
+}
+
+/*
+ * Nokia cards are not really multiport cards.  Shouldn't this
+ * be handled by setting the quirk entry .multi = 0 | 1 ?
+ */
+static void quirk_config_nokia(struct pcmcia_device *link)
+{
+       struct serial_info *info = link->priv;
+
+       if (info->multi > 1)
+               info->multi = 1;
+}
+
+static void quirk_wakeup_oxsemi(struct pcmcia_device *link)
+{
+       struct serial_info *info = link->priv;
+
+       if (info->c950ctrl)
+               outb(12, info->c950ctrl + 1);
+}
+
+/* request_region? oxsemi branch does no request_region too... */
+/*
+ * This sequence is needed to properly initialize MC45 attached to OXCF950.
+ * I tried decreasing these msleep()s, but it worked properly (survived
+ * 1000 stop/start operations) with these timeouts (or bigger).
+ */
+static void quirk_wakeup_possio_gcc(struct pcmcia_device *link)
+{
+       struct serial_info *info = link->priv;
+       unsigned int ctrl = info->c950ctrl;
+
+       outb(0xA, ctrl + 1);
+       msleep(100);
+       outb(0xE, ctrl + 1);
+       msleep(300);
+       outb(0xC, ctrl + 1);
+       msleep(100);
+       outb(0xE, ctrl + 1);
+       msleep(200);
+       outb(0xF, ctrl + 1);
+       msleep(100);
+       outb(0xE, ctrl + 1);
+       msleep(100);
+       outb(0xC, ctrl + 1);
+}
+
+/*
+ * Socket Dual IO: this enables irq's for second port
+ */
+static void quirk_config_socket(struct pcmcia_device *link)
+{
+       struct serial_info *info = link->priv;
+
+       if (info->multi)
+               link->config_flags |= CONF_ENABLE_ESR;
+}
+
+static const struct serial_quirk quirks[] = {
+       {
+               .manfid = 0x0160,
+               .prodid = 0x0104,
+               .multi  = -1,
+               .setup  = quirk_setup_brainboxes_0104,
+       }, {
+               .manfid = 0x015D,
+               .prodid = 0x4C45,
+               .multi  = -1,
+               .setup  = quirk_setup_brainboxes_0104,
+       }, {
+               .manfid = MANFID_IBM,
+               .prodid = ~0,
+               .multi  = -1,
+               .post   = quirk_post_ibm,
+       }, {
+               .manfid = MANFID_INTEL,
+               .prodid = PRODID_INTEL_DUAL_RS232,
+               .multi  = 2,
+       }, {
+               .manfid = MANFID_NATINST,
+               .prodid = PRODID_NATINST_QUAD_RS232,
+               .multi  = 4,
+       }, {
+               .manfid = MANFID_NOKIA,
+               .prodid = ~0,
+               .multi  = -1,
+               .config = quirk_config_nokia,
+       }, {
+               .manfid = MANFID_OMEGA,
+               .prodid = PRODID_OMEGA_QSP_100,
+               .multi  = 4,
+       }, {
+               .manfid = MANFID_OXSEMI,
+               .prodid = ~0,
+               .multi  = -1,
+               .wakeup = quirk_wakeup_oxsemi,
+       }, {
+               .manfid = MANFID_POSSIO,
+               .prodid = PRODID_POSSIO_GCC,
+               .multi  = -1,
+               .wakeup = quirk_wakeup_possio_gcc,
+       }, {
+               .manfid = MANFID_QUATECH,
+               .prodid = PRODID_QUATECH_DUAL_RS232,
+               .multi  = 2,
+       }, {
+               .manfid = MANFID_QUATECH,
+               .prodid = PRODID_QUATECH_DUAL_RS232_D1,
+               .multi  = 2,
+       }, {
+               .manfid = MANFID_QUATECH,
+               .prodid = PRODID_QUATECH_DUAL_RS232_G,
+               .multi  = 2,
+       }, {
+               .manfid = MANFID_QUATECH,
+               .prodid = PRODID_QUATECH_QUAD_RS232,
+               .multi  = 4,
+       }, {
+               .manfid = MANFID_SOCKET,
+               .prodid = PRODID_SOCKET_DUAL_RS232,
+               .multi  = 2,
+               .config = quirk_config_socket,
+       }, {
+               .manfid = MANFID_SOCKET,
+               .prodid = ~0,
+               .multi  = -1,
+               .config = quirk_config_socket,
+       }
+};
+
+
+static int serial_config(struct pcmcia_device * link);
+
+
+static void serial_remove(struct pcmcia_device *link)
+{
+       struct serial_info *info = link->priv;
+       int i;
+
+       dev_dbg(&link->dev, "serial_release\n");
+
+       /*
+        * Recheck to see if the device is still configured.
+        */
+       for (i = 0; i < info->ndev; i++)
+               serial8250_unregister_port(info->line[i]);
+
+       if (!info->slave)
+               pcmcia_disable_device(link);
+}
+
+static int serial_suspend(struct pcmcia_device *link)
+{
+       struct serial_info *info = link->priv;
+       int i;
+
+       for (i = 0; i < info->ndev; i++)
+               serial8250_suspend_port(info->line[i]);
+
+       return 0;
+}
+
+static int serial_resume(struct pcmcia_device *link)
+{
+       struct serial_info *info = link->priv;
+       int i;
+
+       for (i = 0; i < info->ndev; i++)
+               serial8250_resume_port(info->line[i]);
+
+       if (info->quirk && info->quirk->wakeup)
+               info->quirk->wakeup(link);
+
+       return 0;
+}
+
+static int serial_probe(struct pcmcia_device *link)
+{
+       struct serial_info *info;
+
+       dev_dbg(&link->dev, "serial_attach()\n");
+
+       /* Create new serial device */
+       info = kzalloc(sizeof (*info), GFP_KERNEL);
+       if (!info)
+               return -ENOMEM;
+       info->p_dev = link;
+       link->priv = info;
+
+       link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IO;
+       if (do_sound)
+               link->config_flags |= CONF_ENABLE_SPKR;
+
+       return serial_config(link);
+}
+
+static void serial_detach(struct pcmcia_device *link)
+{
+       struct serial_info *info = link->priv;
+
+       dev_dbg(&link->dev, "serial_detach\n");
+
+       /*
+        * Ensure that the ports have been released.
+        */
+       serial_remove(link);
+
+       /* free bits */
+       kfree(info);
+}
+
+/*====================================================================*/
+
+static int setup_serial(struct pcmcia_device *handle, struct serial_info * info,
+                       unsigned int iobase, int irq)
+{
+       struct uart_port port;
+       int line;
+
+       memset(&port, 0, sizeof (struct uart_port));
+       port.iobase = iobase;
+       port.irq = irq;
+       port.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_SHARE_IRQ;
+       port.uartclk = 1843200;
+       port.dev = &handle->dev;
+       if (buggy_uart)
+               port.flags |= UPF_BUGGY_UART;
+
+       if (info->quirk && info->quirk->setup)
+               info->quirk->setup(handle, &port);
+
+       line = serial8250_register_port(&port);
+       if (line < 0) {
+               printk(KERN_NOTICE "serial_cs: serial8250_register_port() at "
+                      "0x%04lx, irq %d failed\n", (u_long)iobase, irq);
+               return -EINVAL;
+       }
+
+       info->line[info->ndev] = line;
+       info->ndev++;
+
+       return 0;
+}
+
+/*====================================================================*/
+
+static int pfc_config(struct pcmcia_device *p_dev)
+{
+       unsigned int port = 0;
+       struct serial_info *info = p_dev->priv;
+
+       if ((p_dev->resource[1]->end != 0) &&
+               (resource_size(p_dev->resource[1]) == 8)) {
+               port = p_dev->resource[1]->start;
+               info->slave = 1;
+       } else if ((info->manfid == MANFID_OSITECH) &&
+               (resource_size(p_dev->resource[0]) == 0x40)) {
+               port = p_dev->resource[0]->start + 0x28;
+               info->slave = 1;
+       }
+       if (info->slave)
+               return setup_serial(p_dev, info, port, p_dev->irq);
+
+       dev_warn(&p_dev->dev, "no usable port range found, giving up\n");
+       return -ENODEV;
+}
+
+static int simple_config_check(struct pcmcia_device *p_dev, void *priv_data)
+{
+       static const int size_table[2] = { 8, 16 };
+       int *try = priv_data;
+
+       if (p_dev->resource[0]->start == 0)
+               return -ENODEV;
+
+       if ((*try & 0x1) == 0)
+               p_dev->io_lines = 16;
+
+       if (p_dev->resource[0]->end != size_table[(*try >> 1)])
+               return -ENODEV;
+
+       p_dev->resource[0]->end = 8;
+       p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
+       p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_8;
+
+       return pcmcia_request_io(p_dev);
+}
+
+static int simple_config_check_notpicky(struct pcmcia_device *p_dev,
+                                       void *priv_data)
+{
+       static const unsigned int base[5] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, 0x0 };
+       int j;
+
+       if (p_dev->io_lines > 3)
+               return -ENODEV;
+
+       p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
+       p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_8;
+       p_dev->resource[0]->end = 8;
+
+       for (j = 0; j < 5; j++) {
+               p_dev->resource[0]->start = base[j];
+               p_dev->io_lines = base[j] ? 16 : 3;
+               if (!pcmcia_request_io(p_dev))
+                       return 0;
+       }
+       return -ENODEV;
+}
+
+static int simple_config(struct pcmcia_device *link)
+{
+       struct serial_info *info = link->priv;
+       int i = -ENODEV, try;
+
+       /* First pass: look for a config entry that looks normal.
+        * Two tries: without IO aliases, then with aliases */
+       link->config_flags |= CONF_AUTO_SET_VPP;
+       for (try = 0; try < 4; try++)
+               if (!pcmcia_loop_config(link, simple_config_check, &try))
+                       goto found_port;
+
+       /* Second pass: try to find an entry that isn't picky about
+          its base address, then try to grab any standard serial port
+          address, and finally try to get any free port. */
+       if (!pcmcia_loop_config(link, simple_config_check_notpicky, NULL))
+               goto found_port;
+
+       dev_warn(&link->dev, "no usable port range found, giving up\n");
+       return -1;
+
+found_port:
+       if (info->multi && (info->manfid == MANFID_3COM))
+               link->config_index &= ~(0x08);
+
+       /*
+        * Apply any configuration quirks.
+        */
+       if (info->quirk && info->quirk->config)
+               info->quirk->config(link);
+
+       i = pcmcia_enable_device(link);
+       if (i != 0)
+               return -1;
+       return setup_serial(link, info, link->resource[0]->start, link->irq);
+}
+
+static int multi_config_check(struct pcmcia_device *p_dev, void *priv_data)
+{
+       int *multi = priv_data;
+
+       if (p_dev->resource[1]->end)
+               return -EINVAL;
+
+       /* The quad port cards have bad CIS's, so just look for a
+          window larger than 8 ports and assume it will be right */
+       if (p_dev->resource[0]->end <= 8)
+               return -EINVAL;
+
+       p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
+       p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_8;
+       p_dev->resource[0]->end = *multi * 8;
+
+       if (pcmcia_request_io(p_dev))
+               return -ENODEV;
+       return 0;
+}
+
+static int multi_config_check_notpicky(struct pcmcia_device *p_dev,
+                                      void *priv_data)
+{
+       int *base2 = priv_data;
+
+       if (!p_dev->resource[0]->end || !p_dev->resource[1]->end ||
+               p_dev->resource[0]->start + 8 != p_dev->resource[1]->start)
+               return -ENODEV;
+
+       p_dev->resource[0]->end = p_dev->resource[1]->end = 8;
+       p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
+       p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_8;
+
+       if (pcmcia_request_io(p_dev))
+               return -ENODEV;
+
+       *base2 = p_dev->resource[0]->start + 8;
+       return 0;
+}
+
+static int multi_config(struct pcmcia_device *link)
+{
+       struct serial_info *info = link->priv;
+       int i, base2 = 0;
+
+       /* First, look for a generic full-sized window */
+       if (!pcmcia_loop_config(link, multi_config_check, &info->multi))
+               base2 = link->resource[0]->start + 8;
+       else {
+               /* If that didn't work, look for two windows */
+               info->multi = 2;
+               if (pcmcia_loop_config(link, multi_config_check_notpicky,
+                                      &base2)) {
+                       dev_warn(&link->dev, "no usable port range "
+                              "found, giving up\n");
+                       return -ENODEV;
+               }
+       }
+
+       if (!link->irq)
+               dev_warn(&link->dev, "no usable IRQ found, continuing...\n");
+
+       /*
+        * Apply any configuration quirks.
+        */
+       if (info->quirk && info->quirk->config)
+               info->quirk->config(link);
+
+       i = pcmcia_enable_device(link);
+       if (i != 0)
+               return -ENODEV;
+
+       /* The Oxford Semiconductor OXCF950 cards are in fact single-port:
+        * 8 registers are for the UART, the others are extra registers.
+        * Siemen's MC45 PCMCIA (Possio's GCC) is OXCF950 based too.
+        */
+       if (info->manfid == MANFID_OXSEMI || (info->manfid == MANFID_POSSIO &&
+                               info->prodid == PRODID_POSSIO_GCC)) {
+               int err;
+
+               if (link->config_index == 1 ||
+                   link->config_index == 3) {
+                       err = setup_serial(link, info, base2,
+                                       link->irq);
+                       base2 = link->resource[0]->start;
+               } else {
+                       err = setup_serial(link, info, link->resource[0]->start,
+                                       link->irq);
+               }
+               info->c950ctrl = base2;
+
+               /*
+                * FIXME: We really should wake up the port prior to
+                * handing it over to the serial layer.
+                */
+               if (info->quirk && info->quirk->wakeup)
+                       info->quirk->wakeup(link);
+
+               return 0;
+       }
+
+       setup_serial(link, info, link->resource[0]->start, link->irq);
+       for (i = 0; i < info->multi - 1; i++)
+               setup_serial(link, info, base2 + (8 * i),
+                               link->irq);
+       return 0;
+}
+
+static int serial_check_for_multi(struct pcmcia_device *p_dev,  void *priv_data)
+{
+       struct serial_info *info = p_dev->priv;
+
+       if (!p_dev->resource[0]->end)
+               return -EINVAL;
+
+       if ((!p_dev->resource[1]->end) && (p_dev->resource[0]->end % 8 == 0))
+               info->multi = p_dev->resource[0]->end >> 3;
+
+       if ((p_dev->resource[1]->end) && (p_dev->resource[0]->end == 8)
+               && (p_dev->resource[1]->end == 8))
+               info->multi = 2;
+
+       return 0; /* break */
+}
+
+
+static int serial_config(struct pcmcia_device * link)
+{
+       struct serial_info *info = link->priv;
+       int i;
+
+       dev_dbg(&link->dev, "serial_config\n");
+
+       /* Is this a compliant multifunction card? */
+       info->multi = (link->socket->functions > 1);
+
+       /* Is this a multiport card? */
+       info->manfid = link->manf_id;
+       info->prodid = link->card_id;
+
+       for (i = 0; i < ARRAY_SIZE(quirks); i++)
+               if ((quirks[i].manfid == ~0 ||
+                    quirks[i].manfid == info->manfid) &&
+                   (quirks[i].prodid == ~0 ||
+                    quirks[i].prodid == info->prodid)) {
+                       info->quirk = &quirks[i];
+                       break;
+               }
+
+       /* Another check for dual-serial cards: look for either serial or
+          multifunction cards that ask for appropriate IO port ranges */
+       if ((info->multi == 0) &&
+           (link->has_func_id) &&
+           (link->socket->pcmcia_pfc == 0) &&
+           ((link->func_id == CISTPL_FUNCID_MULTI) ||
+            (link->func_id == CISTPL_FUNCID_SERIAL)))
+               pcmcia_loop_config(link, serial_check_for_multi, info);
+
+       /*
+        * Apply any multi-port quirk.
+        */
+       if (info->quirk && info->quirk->multi != -1)
+               info->multi = info->quirk->multi;
+
+       dev_info(&link->dev,
+               "trying to set up [0x%04x:0x%04x] (pfc: %d, multi: %d, quirk: %p)\n",
+               link->manf_id, link->card_id,
+               link->socket->pcmcia_pfc, info->multi, info->quirk);
+       if (link->socket->pcmcia_pfc)
+               i = pfc_config(link);
+       else if (info->multi > 1)
+               i = multi_config(link);
+       else
+               i = simple_config(link);
+
+       if (i || info->ndev == 0)
+               goto failed;
+
+       /*
+        * Apply any post-init quirk.  FIXME: This should really happen
+        * before we register the port, since it might already be in use.
+        */
+       if (info->quirk && info->quirk->post)
+               if (info->quirk->post(link))
+                       goto failed;
+
+       return 0;
+
+failed:
+       dev_warn(&link->dev, "failed to initialize\n");
+       serial_remove(link);
+       return -ENODEV;
+}
+
+static const struct pcmcia_device_id serial_ids[] = {
+       PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0057, 0x0021),
+       PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0089, 0x110a),
+       PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0104, 0x000a),
+       PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0105, 0x0d0a),
+       PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0105, 0x0e0a),
+       PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0105, 0xea15),
+       PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0109, 0x0501),
+       PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0138, 0x110a),
+       PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0140, 0x000a),
+       PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0143, 0x3341),
+       PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0143, 0xc0ab),
+       PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x016c, 0x0081),
+       PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x021b, 0x0101),
+       PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x08a1, 0xc0ab),
+       PCMCIA_PFC_DEVICE_PROD_ID123(1, "MEGAHERTZ", "CC/XJEM3288", "DATA/FAX/CELL ETHERNET MODEM", 0xf510db04, 0x04cd2988, 0x46a52d63),
+       PCMCIA_PFC_DEVICE_PROD_ID123(1, "MEGAHERTZ", "CC/XJEM3336", "DATA/FAX/CELL ETHERNET MODEM", 0xf510db04, 0x0143b773, 0x46a52d63),
+       PCMCIA_PFC_DEVICE_PROD_ID123(1, "MEGAHERTZ", "EM1144T", "PCMCIA MODEM", 0xf510db04, 0x856d66c8, 0xbd6c43ef),
+       PCMCIA_PFC_DEVICE_PROD_ID123(1, "MEGAHERTZ", "XJEM1144/CCEM1144", "PCMCIA MODEM", 0xf510db04, 0x52d21e1e, 0xbd6c43ef),
+       PCMCIA_PFC_DEVICE_PROD_ID13(1, "Xircom", "CEM28", 0x2e3ee845, 0x0ea978ea),
+       PCMCIA_PFC_DEVICE_PROD_ID13(1, "Xircom", "CEM33", 0x2e3ee845, 0x80609023),
+       PCMCIA_PFC_DEVICE_PROD_ID13(1, "Xircom", "CEM56", 0x2e3ee845, 0xa650c32a),
+       PCMCIA_PFC_DEVICE_PROD_ID13(1, "Xircom", "REM10", 0x2e3ee845, 0x76df1d29),
+       PCMCIA_PFC_DEVICE_PROD_ID13(1, "Xircom", "XEM5600", 0x2e3ee845, 0xf1403719),
+       PCMCIA_PFC_DEVICE_PROD_ID12(1, "AnyCom", "Fast Ethernet + 56K COMBO", 0x578ba6e7, 0xb0ac62c4),
+       PCMCIA_PFC_DEVICE_PROD_ID12(1, "ATKK", "LM33-PCM-T", 0xba9eb7e2, 0x077c174e),
+       PCMCIA_PFC_DEVICE_PROD_ID12(1, "D-Link", "DME336T", 0x1a424a1c, 0xb23897ff),
+       PCMCIA_PFC_DEVICE_PROD_ID12(1, "Gateway 2000", "XJEM3336", 0xdd9989be, 0x662c394c),
+       PCMCIA_PFC_DEVICE_PROD_ID12(1, "Grey Cell", "GCS3000", 0x2a151fac, 0x48b932ae),
+       PCMCIA_PFC_DEVICE_PROD_ID12(1, "Linksys", "EtherFast 10&100 + 56K PC Card (PCMLM56)", 0x0733cc81, 0xb3765033),
+       PCMCIA_PFC_DEVICE_PROD_ID12(1, "LINKSYS", "PCMLM336", 0xf7cb0b07, 0x7a821b58),
+       PCMCIA_PFC_DEVICE_PROD_ID12(1, "MEGAHERTZ", "XJEM1144/CCEM1144", 0xf510db04, 0x52d21e1e),
+       PCMCIA_PFC_DEVICE_PROD_ID12(1, "MICRO RESEARCH", "COMBO-L/M-336", 0xb2ced065, 0x3ced0555),
+       PCMCIA_PFC_DEVICE_PROD_ID12(1, "NEC", "PK-UG-J001" ,0x18df0ba0 ,0x831b1064),
+       PCMCIA_PFC_DEVICE_PROD_ID12(1, "Ositech", "Trumpcard:Jack of Diamonds Modem+Ethernet", 0xc2f80cd, 0x656947b9),
+       PCMCIA_PFC_DEVICE_PROD_ID12(1, "Ositech", "Trumpcard:Jack of Hearts Modem+Ethernet", 0xc2f80cd, 0xdc9ba5ed),
+       PCMCIA_PFC_DEVICE_PROD_ID12(1, "PCMCIAs", "ComboCard", 0xdcfe12d3, 0xcd8906cc),
+       PCMCIA_PFC_DEVICE_PROD_ID12(1, "PCMCIAs", "LanModem", 0xdcfe12d3, 0xc67c648f),
+       PCMCIA_PFC_DEVICE_PROD_ID12(1, "TDK", "GlobalNetworker 3410/3412", 0x1eae9475, 0xd9a93bed),
+       PCMCIA_PFC_DEVICE_PROD_ID12(1, "Xircom", "CreditCard Ethernet+Modem II", 0x2e3ee845, 0xeca401bf),
+       PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0032, 0x0e01),
+       PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0032, 0x0a05),
+       PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0032, 0x0b05),
+       PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0032, 0x1101),
+       PCMCIA_MFC_DEVICE_MANF_CARD(0, 0x0104, 0x0070),
+       PCMCIA_MFC_DEVICE_MANF_CARD(1, 0x0101, 0x0562),
+       PCMCIA_MFC_DEVICE_MANF_CARD(1, 0x0104, 0x0070),
+       PCMCIA_MFC_DEVICE_MANF_CARD(1, 0x016c, 0x0020),
+       PCMCIA_MFC_DEVICE_PROD_ID123(1, "APEX DATA", "MULTICARD", "ETHERNET-MODEM", 0x11c2da09, 0x7289dc5d, 0xaad95e1f),
+       PCMCIA_MFC_DEVICE_PROD_ID12(1, "IBM", "Home and Away 28.8 PC Card       ", 0xb569a6e5, 0x5bd4ff2c),
+       PCMCIA_MFC_DEVICE_PROD_ID12(1, "IBM", "Home and Away Credit Card Adapter", 0xb569a6e5, 0x4bdf15c3),
+       PCMCIA_MFC_DEVICE_PROD_ID12(1, "IBM", "w95 Home and Away Credit Card ", 0xb569a6e5, 0xae911c15),
+       PCMCIA_MFC_DEVICE_PROD_ID1(1, "Motorola MARQUIS", 0xf03e4e77),
+       PCMCIA_MFC_DEVICE_PROD_ID2(1, "FAX/Modem/Ethernet Combo Card ", 0x1ed59302),
+       PCMCIA_DEVICE_MANF_CARD(0x0089, 0x0301),
+       PCMCIA_DEVICE_MANF_CARD(0x00a4, 0x0276),
+       PCMCIA_DEVICE_MANF_CARD(0x0101, 0x0039),
+       PCMCIA_DEVICE_MANF_CARD(0x0104, 0x0006),
+       PCMCIA_DEVICE_MANF_CARD(0x0105, 0x0101), /* TDK DF2814 */
+       PCMCIA_DEVICE_MANF_CARD(0x0105, 0x100a), /* Xircom CM-56G */
+       PCMCIA_DEVICE_MANF_CARD(0x0105, 0x3e0a), /* TDK DF5660 */
+       PCMCIA_DEVICE_MANF_CARD(0x0105, 0x410a),
+       PCMCIA_DEVICE_MANF_CARD(0x0107, 0x0002), /* USRobotics 14,400 */
+       PCMCIA_DEVICE_MANF_CARD(0x010b, 0x0d50),
+       PCMCIA_DEVICE_MANF_CARD(0x010b, 0x0d51),
+       PCMCIA_DEVICE_MANF_CARD(0x010b, 0x0d52),
+       PCMCIA_DEVICE_MANF_CARD(0x010b, 0x0d53),
+       PCMCIA_DEVICE_MANF_CARD(0x010b, 0xd180),
+       PCMCIA_DEVICE_MANF_CARD(0x0115, 0x3330), /* USRobotics/SUN 14,400 */
+       PCMCIA_DEVICE_MANF_CARD(0x0124, 0x0100), /* Nokia DTP-2 ver II */
+       PCMCIA_DEVICE_MANF_CARD(0x0134, 0x5600), /* LASAT COMMUNICATIONS A/S */
+       PCMCIA_DEVICE_MANF_CARD(0x0137, 0x000e),
+       PCMCIA_DEVICE_MANF_CARD(0x0137, 0x001b),
+       PCMCIA_DEVICE_MANF_CARD(0x0137, 0x0025),
+       PCMCIA_DEVICE_MANF_CARD(0x0137, 0x0045),
+       PCMCIA_DEVICE_MANF_CARD(0x0137, 0x0052),
+       PCMCIA_DEVICE_MANF_CARD(0x016c, 0x0006), /* Psion 56K+Fax */
+       PCMCIA_DEVICE_MANF_CARD(0x0200, 0x0001), /* MultiMobile */
+       PCMCIA_DEVICE_PROD_ID134("ADV", "TECH", "COMpad-32/85", 0x67459937, 0x916d02ba, 0x8fbe92ae),
+       PCMCIA_DEVICE_PROD_ID124("GATEWAY2000", "CC3144", "PCMCIA MODEM", 0x506bccae, 0xcb3685f1, 0xbd6c43ef),
+       PCMCIA_DEVICE_PROD_ID14("MEGAHERTZ", "PCMCIA MODEM", 0xf510db04, 0xbd6c43ef),
+       PCMCIA_DEVICE_PROD_ID124("TOSHIBA", "T144PF", "PCMCIA MODEM", 0xb4585a1a, 0x7271409c, 0xbd6c43ef),
+       PCMCIA_DEVICE_PROD_ID123("FUJITSU", "FC14F ", "MBH10213", 0x6ee5a3d8, 0x30ead12b, 0xb00f05a0),
+       PCMCIA_DEVICE_PROD_ID123("Novatel Wireless", "Merlin UMTS Modem", "U630", 0x32607776, 0xd9e73b13, 0xe87332e),
+       PCMCIA_DEVICE_PROD_ID13("MEGAHERTZ", "V.34 PCMCIA MODEM", 0xf510db04, 0xbb2cce4a),
+       PCMCIA_DEVICE_PROD_ID12("Brain Boxes", "Bluetooth PC Card", 0xee138382, 0xd4ce9b02),
+       PCMCIA_DEVICE_PROD_ID12("CIRRUS LOGIC", "FAX MODEM", 0xe625f451, 0xcecd6dfa),
+       PCMCIA_DEVICE_PROD_ID12("COMPAQ", "PCMCIA 28800 FAX/DATA MODEM", 0xa3a3062c, 0x8cbd7c76),
+       PCMCIA_DEVICE_PROD_ID12("COMPAQ", "PCMCIA 33600 FAX/DATA MODEM", 0xa3a3062c, 0x5a00ce95),
+       PCMCIA_DEVICE_PROD_ID12("Computerboards, Inc.", "PCM-COM422", 0xd0b78f51, 0x7e2d49ed),
+       PCMCIA_DEVICE_PROD_ID12("Dr. Neuhaus", "FURY CARD 14K4", 0x76942813, 0x8b96ce65),
+       PCMCIA_DEVICE_PROD_ID12("IBM", "ISDN/56K/GSM", 0xb569a6e5, 0xfee5297b),
+       PCMCIA_DEVICE_PROD_ID12("Intelligent", "ANGIA FAX/MODEM", 0xb496e65e, 0xf31602a6),
+       PCMCIA_DEVICE_PROD_ID12("Intel", "MODEM 2400+", 0x816cc815, 0x412729fb),
+       PCMCIA_DEVICE_PROD_ID12("Intertex", "IX34-PCMCIA", 0xf8a097e3, 0x97880447),
+       PCMCIA_DEVICE_PROD_ID12("IOTech Inc ", "PCMCIA Dual RS-232 Serial Port Card", 0x3bd2d898, 0x92abc92f),
+       PCMCIA_DEVICE_PROD_ID12("MACRONIX", "FAX/MODEM", 0x668388b3, 0x3f9bdf2f),
+       PCMCIA_DEVICE_PROD_ID12("Multi-Tech", "MT1432LT", 0x5f73be51, 0x0b3e2383),
+       PCMCIA_DEVICE_PROD_ID12("Multi-Tech", "MT2834LT", 0x5f73be51, 0x4cd7c09e),
+       PCMCIA_DEVICE_PROD_ID12("OEM      ", "C288MX     ", 0xb572d360, 0xd2385b7a),
+       PCMCIA_DEVICE_PROD_ID12("Option International", "V34bis GSM/PSTN Data/Fax Modem", 0x9d7cd6f5, 0x5cb8bf41),
+       PCMCIA_DEVICE_PROD_ID12("PCMCIA   ", "C336MX     ", 0x99bcafe9, 0xaa25bcab),
+       PCMCIA_DEVICE_PROD_ID12("Quatech Inc", "PCMCIA Dual RS-232 Serial Port Card", 0xc4420b35, 0x92abc92f),
+       PCMCIA_DEVICE_PROD_ID12("Quatech Inc", "Dual RS-232 Serial Port PC Card", 0xc4420b35, 0x031a380d),
+       PCMCIA_DEVICE_PROD_ID12("Telia", "SurfinBird 560P/A+", 0xe2cdd5e, 0xc9314b38),
+       PCMCIA_DEVICE_PROD_ID1("Smart Serial Port", 0x2d8ce292),
+       PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "PCMCIA", "EN2218-LAN/MODEM", 0x281f1c5d, 0x570f348e, "cis/PCMLM28.cis"),
+       PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "PCMCIA", "UE2218-LAN/MODEM", 0x281f1c5d, 0x6fdcacee, "cis/PCMLM28.cis"),
+       PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "Psion Dacom", "Gold Card V34 Ethernet", 0xf5f025c2, 0x338e8155, "cis/PCMLM28.cis"),
+       PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "Psion Dacom", "Gold Card V34 Ethernet GSM", 0xf5f025c2, 0x4ae85d35, "cis/PCMLM28.cis"),
+       PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "LINKSYS", "PCMLM28", 0xf7cb0b07, 0x66881874, "cis/PCMLM28.cis"),
+       PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "TOSHIBA", "Modem/LAN Card", 0xb4585a1a, 0x53f922f8, "cis/PCMLM28.cis"),
+       PCMCIA_MFC_DEVICE_CIS_PROD_ID12(1, "DAYNA COMMUNICATIONS", "LAN AND MODEM MULTIFUNCTION", 0x8fdf8f89, 0xdd5ed9e8, "cis/DP83903.cis"),
+       PCMCIA_MFC_DEVICE_CIS_PROD_ID4(1, "NSC MF LAN/Modem", 0x58fc6056, "cis/DP83903.cis"),
+       PCMCIA_MFC_DEVICE_CIS_MANF_CARD(1, 0x0101, 0x0556, "cis/3CCFEM556.cis"),
+       PCMCIA_MFC_DEVICE_CIS_MANF_CARD(1, 0x0175, 0x0000, "cis/DP83903.cis"),
+       PCMCIA_MFC_DEVICE_CIS_MANF_CARD(1, 0x0101, 0x0035, "cis/3CXEM556.cis"),
+       PCMCIA_MFC_DEVICE_CIS_MANF_CARD(1, 0x0101, 0x003d, "cis/3CXEM556.cis"),
+       PCMCIA_DEVICE_CIS_PROD_ID12("Sierra Wireless", "AC850", 0xd85f6206, 0x42a2c018, "cis/SW_8xx_SER.cis"), /* Sierra Wireless AC850 3G Network Adapter R1 */
+       PCMCIA_DEVICE_CIS_PROD_ID12("Sierra Wireless", "AC860", 0xd85f6206, 0x698f93db, "cis/SW_8xx_SER.cis"), /* Sierra Wireless AC860 3G Network Adapter R1 */
+       PCMCIA_DEVICE_CIS_PROD_ID12("Sierra Wireless", "AC710/AC750", 0xd85f6206, 0x761b11e0, "cis/SW_7xx_SER.cis"),  /* Sierra Wireless AC710/AC750 GPRS Network Adapter R1 */
+       PCMCIA_DEVICE_CIS_MANF_CARD(0x0192, 0xa555, "cis/SW_555_SER.cis"),  /* Sierra Aircard 555 CDMA 1xrtt Modem -- pre update */
+       PCMCIA_DEVICE_CIS_MANF_CARD(0x013f, 0xa555, "cis/SW_555_SER.cis"),  /* Sierra Aircard 555 CDMA 1xrtt Modem -- post update */
+       PCMCIA_DEVICE_CIS_PROD_ID12("MultiTech", "PCMCIA 56K DataFax", 0x842047ee, 0xc2efcf03, "cis/MT5634ZLX.cis"),
+       PCMCIA_DEVICE_CIS_PROD_ID12("ADVANTECH", "COMpad-32/85B-2", 0x96913a85, 0x27ab5437, "cis/COMpad2.cis"),
+       PCMCIA_DEVICE_CIS_PROD_ID12("ADVANTECH", "COMpad-32/85B-4", 0x96913a85, 0xcec8f102, "cis/COMpad4.cis"),
+       PCMCIA_DEVICE_CIS_PROD_ID123("ADVANTECH", "COMpad-32/85", "1.0", 0x96913a85, 0x8fbe92ae, 0x0877b627, "cis/COMpad2.cis"),
+       PCMCIA_DEVICE_CIS_PROD_ID2("RS-COM 2P", 0xad20b156, "cis/RS-COM-2P.cis"),
+       PCMCIA_DEVICE_CIS_MANF_CARD(0x0013, 0x0000, "cis/GLOBETROTTER.cis"),
+       PCMCIA_DEVICE_PROD_ID12("ELAN DIGITAL SYSTEMS LTD, c1997.","SERIAL CARD: SL100  1.00.",0x19ca78af,0xf964f42b),
+       PCMCIA_DEVICE_PROD_ID12("ELAN DIGITAL SYSTEMS LTD, c1997.","SERIAL CARD: SL100",0x19ca78af,0x71d98e83),
+       PCMCIA_DEVICE_PROD_ID12("ELAN DIGITAL SYSTEMS LTD, c1997.","SERIAL CARD: SL232  1.00.",0x19ca78af,0x69fb7490),
+       PCMCIA_DEVICE_PROD_ID12("ELAN DIGITAL SYSTEMS LTD, c1997.","SERIAL CARD: SL232",0x19ca78af,0xb6bc0235),
+       PCMCIA_DEVICE_PROD_ID12("ELAN DIGITAL SYSTEMS LTD, c2000.","SERIAL CARD: CF232",0x63f2e0bd,0xb9e175d3),
+       PCMCIA_DEVICE_PROD_ID12("ELAN DIGITAL SYSTEMS LTD, c2000.","SERIAL CARD: CF232-5",0x63f2e0bd,0xfce33442),
+       PCMCIA_DEVICE_PROD_ID12("Elan","Serial Port: CF232",0x3beb8cf2,0x171e7190),
+       PCMCIA_DEVICE_PROD_ID12("Elan","Serial Port: CF232-5",0x3beb8cf2,0x20da4262),
+       PCMCIA_DEVICE_PROD_ID12("Elan","Serial Port: CF428",0x3beb8cf2,0xea5dd57d),
+       PCMCIA_DEVICE_PROD_ID12("Elan","Serial Port: CF500",0x3beb8cf2,0xd77255fa),
+       PCMCIA_DEVICE_PROD_ID12("Elan","Serial Port: IC232",0x3beb8cf2,0x6a709903),
+       PCMCIA_DEVICE_PROD_ID12("Elan","Serial Port: SL232",0x3beb8cf2,0x18430676),
+       PCMCIA_DEVICE_PROD_ID12("Elan","Serial Port: XL232",0x3beb8cf2,0x6f933767),
+       PCMCIA_MFC_DEVICE_PROD_ID12(0,"Elan","Serial Port: CF332",0x3beb8cf2,0x16dc1ba7),
+       PCMCIA_MFC_DEVICE_PROD_ID12(0,"Elan","Serial Port: SL332",0x3beb8cf2,0x19816c41),
+       PCMCIA_MFC_DEVICE_PROD_ID12(0,"Elan","Serial Port: SL385",0x3beb8cf2,0x64112029),
+       PCMCIA_MFC_DEVICE_PROD_ID12(0,"Elan","Serial Port: SL432",0x3beb8cf2,0x1cce7ac4),
+       PCMCIA_MFC_DEVICE_PROD_ID12(0,"Elan","Serial+Parallel Port: SP230",0x3beb8cf2,0xdb9e58bc),
+       PCMCIA_MFC_DEVICE_PROD_ID12(1,"Elan","Serial Port: CF332",0x3beb8cf2,0x16dc1ba7),
+       PCMCIA_MFC_DEVICE_PROD_ID12(1,"Elan","Serial Port: SL332",0x3beb8cf2,0x19816c41),
+       PCMCIA_MFC_DEVICE_PROD_ID12(1,"Elan","Serial Port: SL385",0x3beb8cf2,0x64112029),
+       PCMCIA_MFC_DEVICE_PROD_ID12(1,"Elan","Serial Port: SL432",0x3beb8cf2,0x1cce7ac4),
+       PCMCIA_MFC_DEVICE_PROD_ID12(2,"Elan","Serial Port: SL432",0x3beb8cf2,0x1cce7ac4),
+       PCMCIA_MFC_DEVICE_PROD_ID12(3,"Elan","Serial Port: SL432",0x3beb8cf2,0x1cce7ac4),
+       PCMCIA_DEVICE_MANF_CARD(0x0279, 0x950b),
+       /* too generic */
+       /* PCMCIA_MFC_DEVICE_MANF_CARD(0, 0x0160, 0x0002), */
+       /* PCMCIA_MFC_DEVICE_MANF_CARD(1, 0x0160, 0x0002), */
+       PCMCIA_DEVICE_FUNC_ID(2),
+       PCMCIA_DEVICE_NULL,
+};
+MODULE_DEVICE_TABLE(pcmcia, serial_ids);
+
+MODULE_FIRMWARE("cis/PCMLM28.cis");
+MODULE_FIRMWARE("cis/DP83903.cis");
+MODULE_FIRMWARE("cis/3CCFEM556.cis");
+MODULE_FIRMWARE("cis/3CXEM556.cis");
+MODULE_FIRMWARE("cis/SW_8xx_SER.cis");
+MODULE_FIRMWARE("cis/SW_7xx_SER.cis");
+MODULE_FIRMWARE("cis/SW_555_SER.cis");
+MODULE_FIRMWARE("cis/MT5634ZLX.cis");
+MODULE_FIRMWARE("cis/COMpad2.cis");
+MODULE_FIRMWARE("cis/COMpad4.cis");
+MODULE_FIRMWARE("cis/RS-COM-2P.cis");
+
+static struct pcmcia_driver serial_cs_driver = {
+       .owner          = THIS_MODULE,
+       .name           = "serial_cs",
+       .probe          = serial_probe,
+       .remove         = serial_detach,
+       .id_table       = serial_ids,
+       .suspend        = serial_suspend,
+       .resume         = serial_resume,
+};
+
+static int __init init_serial_cs(void)
+{
+       return pcmcia_register_driver(&serial_cs_driver);
+}
+
+static void __exit exit_serial_cs(void)
+{
+       pcmcia_unregister_driver(&serial_cs_driver);
+}
+
+module_init(init_serial_cs);
+module_exit(exit_serial_cs);
+
+MODULE_LICENSE("GPL");
diff --git a/drivers/tty/serial/8250_accent.c b/drivers/tty/serial/8250_accent.c
deleted file mode 100644 (file)
index 34b51c6..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- *  Copyright (C) 2005 Russell King.
- *  Data taken from include/asm-i386/serial.h
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/serial_8250.h>
-
-#define PORT(_base,_irq)                               \
-       {                                               \
-               .iobase         = _base,                \
-               .irq            = _irq,                 \
-               .uartclk        = 1843200,              \
-               .iotype         = UPIO_PORT,            \
-               .flags          = UPF_BOOT_AUTOCONF,    \
-       }
-
-static struct plat_serial8250_port accent_data[] = {
-       PORT(0x330, 4),
-       PORT(0x338, 4),
-       { },
-};
-
-static struct platform_device accent_device = {
-       .name                   = "serial8250",
-       .id                     = PLAT8250_DEV_ACCENT,
-       .dev                    = {
-               .platform_data  = accent_data,
-       },
-};
-
-static int __init accent_init(void)
-{
-       return platform_device_register(&accent_device);
-}
-
-module_init(accent_init);
-
-MODULE_AUTHOR("Russell King");
-MODULE_DESCRIPTION("8250 serial probe module for Accent Async cards");
-MODULE_LICENSE("GPL");
diff --git a/drivers/tty/serial/8250_acorn.c b/drivers/tty/serial/8250_acorn.c
deleted file mode 100644 (file)
index b0ce8c5..0000000
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- *  linux/drivers/serial/acorn.c
- *
- *  Copyright (C) 1996-2003 Russell King.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/tty.h>
-#include <linux/serial_core.h>
-#include <linux/errno.h>
-#include <linux/ioport.h>
-#include <linux/slab.h>
-#include <linux/device.h>
-#include <linux/init.h>
-
-#include <asm/io.h>
-#include <asm/ecard.h>
-#include <asm/string.h>
-
-#include "8250.h"
-
-#define MAX_PORTS      3
-
-struct serial_card_type {
-       unsigned int    num_ports;
-       unsigned int    uartclk;
-       unsigned int    type;
-       unsigned int    offset[MAX_PORTS];
-};
-
-struct serial_card_info {
-       unsigned int    num_ports;
-       int             ports[MAX_PORTS];
-       void __iomem *vaddr;
-};
-
-static int __devinit
-serial_card_probe(struct expansion_card *ec, const struct ecard_id *id)
-{
-       struct serial_card_info *info;
-       struct serial_card_type *type = id->data;
-       struct uart_port port;
-       unsigned long bus_addr;
-       unsigned int i;
-
-       info = kzalloc(sizeof(struct serial_card_info), GFP_KERNEL);
-       if (!info)
-               return -ENOMEM;
-
-       info->num_ports = type->num_ports;
-
-       bus_addr = ecard_resource_start(ec, type->type);
-       info->vaddr = ecardm_iomap(ec, type->type, 0, 0);
-       if (!info->vaddr) {
-               kfree(info);
-               return -ENOMEM;
-       }
-
-       ecard_set_drvdata(ec, info);
-
-       memset(&port, 0, sizeof(struct uart_port));
-       port.irq        = ec->irq;
-       port.flags      = UPF_BOOT_AUTOCONF | UPF_SHARE_IRQ;
-       port.uartclk    = type->uartclk;
-       port.iotype     = UPIO_MEM;
-       port.regshift   = 2;
-       port.dev        = &ec->dev;
-
-       for (i = 0; i < info->num_ports; i ++) {
-               port.membase = info->vaddr + type->offset[i];
-               port.mapbase = bus_addr + type->offset[i];
-
-               info->ports[i] = serial8250_register_port(&port);
-       }
-
-       return 0;
-}
-
-static void __devexit serial_card_remove(struct expansion_card *ec)
-{
-       struct serial_card_info *info = ecard_get_drvdata(ec);
-       int i;
-
-       ecard_set_drvdata(ec, NULL);
-
-       for (i = 0; i < info->num_ports; i++)
-               if (info->ports[i] > 0)
-                       serial8250_unregister_port(info->ports[i]);
-
-       kfree(info);
-}
-
-static struct serial_card_type atomwide_type = {
-       .num_ports      = 3,
-       .uartclk        = 7372800,
-       .type           = ECARD_RES_IOCSLOW,
-       .offset         = { 0x2800, 0x2400, 0x2000 },
-};
-
-static struct serial_card_type serport_type = {
-       .num_ports      = 2,
-       .uartclk        = 3686400,
-       .type           = ECARD_RES_IOCSLOW,
-       .offset         = { 0x2000, 0x2020 },
-};
-
-static const struct ecard_id serial_cids[] = {
-       { MANU_ATOMWIDE,        PROD_ATOMWIDE_3PSERIAL, &atomwide_type  },
-       { MANU_SERPORT,         PROD_SERPORT_DSPORT,    &serport_type   },
-       { 0xffff, 0xffff }
-};
-
-static struct ecard_driver serial_card_driver = {
-       .probe          = serial_card_probe,
-       .remove         = __devexit_p(serial_card_remove),
-       .id_table       = serial_cids,
-       .drv = {
-               .name   = "8250_acorn",
-       },
-};
-
-static int __init serial_card_init(void)
-{
-       return ecard_register_driver(&serial_card_driver);
-}
-
-static void __exit serial_card_exit(void)
-{
-       ecard_remove_driver(&serial_card_driver);
-}
-
-MODULE_AUTHOR("Russell King");
-MODULE_DESCRIPTION("Acorn 8250-compatible serial port expansion card driver");
-MODULE_LICENSE("GPL");
-
-module_init(serial_card_init);
-module_exit(serial_card_exit);
diff --git a/drivers/tty/serial/8250_boca.c b/drivers/tty/serial/8250_boca.c
deleted file mode 100644 (file)
index d125dc1..0000000
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- *  Copyright (C) 2005 Russell King.
- *  Data taken from include/asm-i386/serial.h
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/serial_8250.h>
-
-#define PORT(_base,_irq)                               \
-       {                                               \
-               .iobase         = _base,                \
-               .irq            = _irq,                 \
-               .uartclk        = 1843200,              \
-               .iotype         = UPIO_PORT,            \
-               .flags          = UPF_BOOT_AUTOCONF,    \
-       }
-
-static struct plat_serial8250_port boca_data[] = {
-       PORT(0x100, 12),
-       PORT(0x108, 12),
-       PORT(0x110, 12),
-       PORT(0x118, 12),
-       PORT(0x120, 12),
-       PORT(0x128, 12),
-       PORT(0x130, 12),
-       PORT(0x138, 12),
-       PORT(0x140, 12),
-       PORT(0x148, 12),
-       PORT(0x150, 12),
-       PORT(0x158, 12),
-       PORT(0x160, 12),
-       PORT(0x168, 12),
-       PORT(0x170, 12),
-       PORT(0x178, 12),
-       { },
-};
-
-static struct platform_device boca_device = {
-       .name                   = "serial8250",
-       .id                     = PLAT8250_DEV_BOCA,
-       .dev                    = {
-               .platform_data  = boca_data,
-       },
-};
-
-static int __init boca_init(void)
-{
-       return platform_device_register(&boca_device);
-}
-
-module_init(boca_init);
-
-MODULE_AUTHOR("Russell King");
-MODULE_DESCRIPTION("8250 serial probe module for Boca cards");
-MODULE_LICENSE("GPL");
diff --git a/drivers/tty/serial/8250_dw.c b/drivers/tty/serial/8250_dw.c
deleted file mode 100644 (file)
index f574eef..0000000
+++ /dev/null
@@ -1,184 +0,0 @@
-/*
- * Synopsys DesignWare 8250 driver.
- *
- * Copyright 2011 Picochip, Jamie Iles.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * The Synopsys DesignWare 8250 has an extra feature whereby it detects if the
- * LCR is written whilst busy.  If it is, then a busy detect interrupt is
- * raised, the LCR needs to be rewritten and the uart status register read.
- */
-#include <linux/device.h>
-#include <linux/init.h>
-#include <linux/io.h>
-#include <linux/module.h>
-#include <linux/serial_8250.h>
-#include <linux/serial_core.h>
-#include <linux/serial_reg.h>
-#include <linux/of.h>
-#include <linux/of_irq.h>
-#include <linux/of_platform.h>
-#include <linux/platform_device.h>
-#include <linux/slab.h>
-
-struct dw8250_data {
-       int     last_lcr;
-       int     line;
-};
-
-static void dw8250_serial_out(struct uart_port *p, int offset, int value)
-{
-       struct dw8250_data *d = p->private_data;
-
-       if (offset == UART_LCR)
-               d->last_lcr = value;
-
-       offset <<= p->regshift;
-       writeb(value, p->membase + offset);
-}
-
-static unsigned int dw8250_serial_in(struct uart_port *p, int offset)
-{
-       offset <<= p->regshift;
-
-       return readb(p->membase + offset);
-}
-
-static void dw8250_serial_out32(struct uart_port *p, int offset, int value)
-{
-       struct dw8250_data *d = p->private_data;
-
-       if (offset == UART_LCR)
-               d->last_lcr = value;
-
-       offset <<= p->regshift;
-       writel(value, p->membase + offset);
-}
-
-static unsigned int dw8250_serial_in32(struct uart_port *p, int offset)
-{
-       offset <<= p->regshift;
-
-       return readl(p->membase + offset);
-}
-
-/* Offset for the DesignWare's UART Status Register. */
-#define UART_USR       0x1f
-
-static int dw8250_handle_irq(struct uart_port *p)
-{
-       struct dw8250_data *d = p->private_data;
-       unsigned int iir = p->serial_in(p, UART_IIR);
-
-       if (serial8250_handle_irq(p, iir)) {
-               return 1;
-       } else if ((iir & UART_IIR_BUSY) == UART_IIR_BUSY) {
-               /* Clear the USR and write the LCR again. */
-               (void)p->serial_in(p, UART_USR);
-               p->serial_out(p, d->last_lcr, UART_LCR);
-
-               return 1;
-       }
-
-       return 0;
-}
-
-static int __devinit dw8250_probe(struct platform_device *pdev)
-{
-       struct uart_port port = {};
-       struct resource *regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       struct resource *irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
-       struct device_node *np = pdev->dev.of_node;
-       u32 val;
-       struct dw8250_data *data;
-
-       if (!regs || !irq) {
-               dev_err(&pdev->dev, "no registers/irq defined\n");
-               return -EINVAL;
-       }
-
-       data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
-       if (!data)
-               return -ENOMEM;
-       port.private_data = data;
-
-       spin_lock_init(&port.lock);
-       port.mapbase = regs->start;
-       port.irq = irq->start;
-       port.handle_irq = dw8250_handle_irq;
-       port.type = PORT_8250;
-       port.flags = UPF_SHARE_IRQ | UPF_BOOT_AUTOCONF | UPF_IOREMAP |
-               UPF_FIXED_PORT | UPF_FIXED_TYPE;
-       port.dev = &pdev->dev;
-
-       port.iotype = UPIO_MEM;
-       port.serial_in = dw8250_serial_in;
-       port.serial_out = dw8250_serial_out;
-       if (!of_property_read_u32(np, "reg-io-width", &val)) {
-               switch (val) {
-               case 1:
-                       break;
-               case 4:
-                       port.iotype = UPIO_MEM32;
-                       port.serial_in = dw8250_serial_in32;
-                       port.serial_out = dw8250_serial_out32;
-                       break;
-               default:
-                       dev_err(&pdev->dev, "unsupported reg-io-width (%u)\n",
-                               val);
-                       return -EINVAL;
-               }
-       }
-
-       if (!of_property_read_u32(np, "reg-shift", &val))
-               port.regshift = val;
-
-       if (of_property_read_u32(np, "clock-frequency", &val)) {
-               dev_err(&pdev->dev, "no clock-frequency property set\n");
-               return -EINVAL;
-       }
-       port.uartclk = val;
-
-       data->line = serial8250_register_port(&port);
-       if (data->line < 0)
-               return data->line;
-
-       platform_set_drvdata(pdev, data);
-
-       return 0;
-}
-
-static int __devexit dw8250_remove(struct platform_device *pdev)
-{
-       struct dw8250_data *data = platform_get_drvdata(pdev);
-
-       serial8250_unregister_port(data->line);
-
-       return 0;
-}
-
-static const struct of_device_id dw8250_match[] = {
-       { .compatible = "snps,dw-apb-uart" },
-       { /* Sentinel */ }
-};
-MODULE_DEVICE_TABLE(of, dw8250_match);
-
-static struct platform_driver dw8250_platform_driver = {
-       .driver = {
-               .name           = "dw-apb-uart",
-               .owner          = THIS_MODULE,
-               .of_match_table = dw8250_match,
-       },
-       .probe                  = dw8250_probe,
-       .remove                 = __devexit_p(dw8250_remove),
-};
-
-module_platform_driver(dw8250_platform_driver);
-
-MODULE_AUTHOR("Jamie Iles");
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("Synopsys DesignWare 8250 serial port driver");
diff --git a/drivers/tty/serial/8250_early.c b/drivers/tty/serial/8250_early.c
deleted file mode 100644 (file)
index eaafb98..0000000
+++ /dev/null
@@ -1,287 +0,0 @@
-/*
- * Early serial console for 8250/16550 devices
- *
- * (c) Copyright 2004 Hewlett-Packard Development Company, L.P.
- *     Bjorn Helgaas <bjorn.helgaas@hp.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * Based on the 8250.c serial driver, Copyright (C) 2001 Russell King,
- * and on early_printk.c by Andi Kleen.
- *
- * This is for use before the serial driver has initialized, in
- * particular, before the UARTs have been discovered and named.
- * Instead of specifying the console device as, e.g., "ttyS0",
- * we locate the device directly by its MMIO or I/O port address.
- *
- * The user can specify the device directly, e.g.,
- *     earlycon=uart8250,io,0x3f8,9600n8
- *     earlycon=uart8250,mmio,0xff5e0000,115200n8
- *     earlycon=uart8250,mmio32,0xff5e0000,115200n8
- * or
- *     console=uart8250,io,0x3f8,9600n8
- *     console=uart8250,mmio,0xff5e0000,115200n8
- *     console=uart8250,mmio32,0xff5e0000,115200n8
- */
-
-#include <linux/tty.h>
-#include <linux/init.h>
-#include <linux/console.h>
-#include <linux/serial_core.h>
-#include <linux/serial_reg.h>
-#include <linux/serial.h>
-#include <linux/serial_8250.h>
-#include <asm/io.h>
-#include <asm/serial.h>
-#ifdef CONFIG_FIX_EARLYCON_MEM
-#include <asm/pgtable.h>
-#include <asm/fixmap.h>
-#endif
-
-struct early_serial8250_device {
-       struct uart_port port;
-       char options[16];               /* e.g., 115200n8 */
-       unsigned int baud;
-};
-
-static struct early_serial8250_device early_device;
-
-static unsigned int __init serial_in(struct uart_port *port, int offset)
-{
-       switch (port->iotype) {
-       case UPIO_MEM:
-               return readb(port->membase + offset);
-       case UPIO_MEM32:
-               return readl(port->membase + (offset << 2));
-       case UPIO_PORT:
-               return inb(port->iobase + offset);
-       default:
-               return 0;
-       }
-}
-
-static void __init serial_out(struct uart_port *port, int offset, int value)
-{
-       switch (port->iotype) {
-       case UPIO_MEM:
-               writeb(value, port->membase + offset);
-               break;
-       case UPIO_MEM32:
-               writel(value, port->membase + (offset << 2));
-               break;
-       case UPIO_PORT:
-               outb(value, port->iobase + offset);
-               break;
-       }
-}
-
-#define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE)
-
-static void __init wait_for_xmitr(struct uart_port *port)
-{
-       unsigned int status;
-
-       for (;;) {
-               status = serial_in(port, UART_LSR);
-               if ((status & BOTH_EMPTY) == BOTH_EMPTY)
-                       return;
-               cpu_relax();
-       }
-}
-
-static void __init serial_putc(struct uart_port *port, int c)
-{
-       wait_for_xmitr(port);
-       serial_out(port, UART_TX, c);
-}
-
-static void __init early_serial8250_write(struct console *console,
-                                       const char *s, unsigned int count)
-{
-       struct uart_port *port = &early_device.port;
-       unsigned int ier;
-
-       /* Save the IER and disable interrupts */
-       ier = serial_in(port, UART_IER);
-       serial_out(port, UART_IER, 0);
-
-       uart_console_write(port, s, count, serial_putc);
-
-       /* Wait for transmitter to become empty and restore the IER */
-       wait_for_xmitr(port);
-       serial_out(port, UART_IER, ier);
-}
-
-static unsigned int __init probe_baud(struct uart_port *port)
-{
-       unsigned char lcr, dll, dlm;
-       unsigned int quot;
-
-       lcr = serial_in(port, UART_LCR);
-       serial_out(port, UART_LCR, lcr | UART_LCR_DLAB);
-       dll = serial_in(port, UART_DLL);
-       dlm = serial_in(port, UART_DLM);
-       serial_out(port, UART_LCR, lcr);
-
-       quot = (dlm << 8) | dll;
-       return (port->uartclk / 16) / quot;
-}
-
-static void __init init_port(struct early_serial8250_device *device)
-{
-       struct uart_port *port = &device->port;
-       unsigned int divisor;
-       unsigned char c;
-
-       serial_out(port, UART_LCR, 0x3);        /* 8n1 */
-       serial_out(port, UART_IER, 0);          /* no interrupt */
-       serial_out(port, UART_FCR, 0);          /* no fifo */
-       serial_out(port, UART_MCR, 0x3);        /* DTR + RTS */
-
-       divisor = port->uartclk / (16 * device->baud);
-       c = serial_in(port, UART_LCR);
-       serial_out(port, UART_LCR, c | UART_LCR_DLAB);
-       serial_out(port, UART_DLL, divisor & 0xff);
-       serial_out(port, UART_DLM, (divisor >> 8) & 0xff);
-       serial_out(port, UART_LCR, c & ~UART_LCR_DLAB);
-}
-
-static int __init parse_options(struct early_serial8250_device *device,
-                                                               char *options)
-{
-       struct uart_port *port = &device->port;
-       int mmio, mmio32, length;
-
-       if (!options)
-               return -ENODEV;
-
-       port->uartclk = BASE_BAUD * 16;
-
-       mmio = !strncmp(options, "mmio,", 5);
-       mmio32 = !strncmp(options, "mmio32,", 7);
-       if (mmio || mmio32) {
-               port->iotype = (mmio ? UPIO_MEM : UPIO_MEM32);
-               port->mapbase = simple_strtoul(options + (mmio ? 5 : 7),
-                                              &options, 0);
-               if (mmio32)
-                       port->regshift = 2;
-#ifdef CONFIG_FIX_EARLYCON_MEM
-               set_fixmap_nocache(FIX_EARLYCON_MEM_BASE,
-                                       port->mapbase & PAGE_MASK);
-               port->membase =
-                       (void __iomem *)__fix_to_virt(FIX_EARLYCON_MEM_BASE);
-               port->membase += port->mapbase & ~PAGE_MASK;
-#else
-               port->membase = ioremap_nocache(port->mapbase, 64);
-               if (!port->membase) {
-                       printk(KERN_ERR "%s: Couldn't ioremap 0x%llx\n",
-                               __func__,
-                              (unsigned long long) port->mapbase);
-                       return -ENOMEM;
-               }
-#endif
-       } else if (!strncmp(options, "io,", 3)) {
-               port->iotype = UPIO_PORT;
-               port->iobase = simple_strtoul(options + 3, &options, 0);
-               mmio = 0;
-       } else
-               return -EINVAL;
-
-       options = strchr(options, ',');
-       if (options) {
-               options++;
-               device->baud = simple_strtoul(options, NULL, 0);
-               length = min(strcspn(options, " "), sizeof(device->options));
-               strncpy(device->options, options, length);
-       } else {
-               device->baud = probe_baud(port);
-               snprintf(device->options, sizeof(device->options), "%u",
-                       device->baud);
-       }
-
-       if (mmio || mmio32)
-               printk(KERN_INFO
-                      "Early serial console at MMIO%s 0x%llx (options '%s')\n",
-                       mmio32 ? "32" : "",
-                       (unsigned long long)port->mapbase,
-                       device->options);
-       else
-               printk(KERN_INFO
-                     "Early serial console at I/O port 0x%lx (options '%s')\n",
-                       port->iobase,
-                       device->options);
-
-       return 0;
-}
-
-static struct console early_serial8250_console __initdata = {
-       .name   = "uart",
-       .write  = early_serial8250_write,
-       .flags  = CON_PRINTBUFFER | CON_BOOT,
-       .index  = -1,
-};
-
-static int __init early_serial8250_setup(char *options)
-{
-       struct early_serial8250_device *device = &early_device;
-       int err;
-
-       if (device->port.membase || device->port.iobase)
-               return 0;
-
-       err = parse_options(device, options);
-       if (err < 0)
-               return err;
-
-       init_port(device);
-       return 0;
-}
-
-int __init setup_early_serial8250_console(char *cmdline)
-{
-       char *options;
-       int err;
-
-       options = strstr(cmdline, "uart8250,");
-       if (!options) {
-               options = strstr(cmdline, "uart,");
-               if (!options)
-                       return 0;
-       }
-
-       options = strchr(cmdline, ',') + 1;
-       err = early_serial8250_setup(options);
-       if (err < 0)
-               return err;
-
-       register_console(&early_serial8250_console);
-
-       return 0;
-}
-
-int serial8250_find_port_for_earlycon(void)
-{
-       struct early_serial8250_device *device = &early_device;
-       struct uart_port *port = &device->port;
-       int line;
-       int ret;
-
-       if (!device->port.membase && !device->port.iobase)
-               return -ENODEV;
-
-       line = serial8250_find_port(port);
-       if (line < 0)
-               return -ENODEV;
-
-       ret = update_console_cmdline("uart", 8250,
-                            "ttyS", line, device->options);
-       if (ret < 0)
-               ret = update_console_cmdline("uart", 0,
-                                    "ttyS", line, device->options);
-
-       return ret;
-}
-
-early_param("earlycon", setup_early_serial8250_console);
diff --git a/drivers/tty/serial/8250_exar_st16c554.c b/drivers/tty/serial/8250_exar_st16c554.c
deleted file mode 100644 (file)
index bf53aab..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- *  Written by Paul B Schroeder < pschroeder "at" uplogix "dot" com >
- *  Based on 8250_boca.
- *
- *  Copyright (C) 2005 Russell King.
- *  Data taken from include/asm-i386/serial.h
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/serial_8250.h>
-
-#define PORT(_base,_irq)                               \
-       {                                               \
-               .iobase         = _base,                \
-               .irq            = _irq,                 \
-               .uartclk        = 1843200,              \
-               .iotype         = UPIO_PORT,            \
-               .flags          = UPF_BOOT_AUTOCONF,    \
-       }
-
-static struct plat_serial8250_port exar_data[] = {
-       PORT(0x100, 5),
-       PORT(0x108, 5),
-       PORT(0x110, 5),
-       PORT(0x118, 5),
-       { },
-};
-
-static struct platform_device exar_device = {
-       .name                   = "serial8250",
-       .id                     = PLAT8250_DEV_EXAR_ST16C554,
-       .dev                    = {
-               .platform_data  = exar_data,
-       },
-};
-
-static int __init exar_init(void)
-{
-       return platform_device_register(&exar_device);
-}
-
-module_init(exar_init);
-
-MODULE_AUTHOR("Paul B Schroeder");
-MODULE_DESCRIPTION("8250 serial probe module for Exar cards");
-MODULE_LICENSE("GPL");
diff --git a/drivers/tty/serial/8250_fourport.c b/drivers/tty/serial/8250_fourport.c
deleted file mode 100644 (file)
index be15826..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- *  Copyright (C) 2005 Russell King.
- *  Data taken from include/asm-i386/serial.h
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/serial_8250.h>
-
-#define PORT(_base,_irq)                                               \
-       {                                                               \
-               .iobase         = _base,                                \
-               .irq            = _irq,                                 \
-               .uartclk        = 1843200,                              \
-               .iotype         = UPIO_PORT,                            \
-               .flags          = UPF_BOOT_AUTOCONF | UPF_FOURPORT,     \
-       }
-
-static struct plat_serial8250_port fourport_data[] = {
-       PORT(0x1a0, 9),
-       PORT(0x1a8, 9),
-       PORT(0x1b0, 9),
-       PORT(0x1b8, 9),
-       PORT(0x2a0, 5),
-       PORT(0x2a8, 5),
-       PORT(0x2b0, 5),
-       PORT(0x2b8, 5),
-       { },
-};
-
-static struct platform_device fourport_device = {
-       .name                   = "serial8250",
-       .id                     = PLAT8250_DEV_FOURPORT,
-       .dev                    = {
-               .platform_data  = fourport_data,
-       },
-};
-
-static int __init fourport_init(void)
-{
-       return platform_device_register(&fourport_device);
-}
-
-module_init(fourport_init);
-
-MODULE_AUTHOR("Russell King");
-MODULE_DESCRIPTION("8250 serial probe module for AST Fourport cards");
-MODULE_LICENSE("GPL");
diff --git a/drivers/tty/serial/8250_fsl.c b/drivers/tty/serial/8250_fsl.c
deleted file mode 100644 (file)
index f4d3c47..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-#include <linux/serial_reg.h>
-#include <linux/serial_8250.h>
-
-#include "8250.h"
-
-/*
- * Freescale 16550 UART "driver", Copyright (C) 2011 Paul Gortmaker.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This isn't a full driver; it just provides an alternate IRQ
- * handler to deal with an errata.  Everything else is just
- * using the bog standard 8250 support.
- *
- * We follow code flow of serial8250_default_handle_irq() but add
- * a check for a break and insert a dummy read on the Rx for the
- * immediately following IRQ event.
- *
- * We re-use the already existing "bug handling" lsr_saved_flags
- * field to carry the "what we just did" information from the one
- * IRQ event to the next one.
- */
-
-int fsl8250_handle_irq(struct uart_port *port)
-{
-       unsigned char lsr, orig_lsr;
-       unsigned long flags;
-       unsigned int iir;
-       struct uart_8250_port *up =
-               container_of(port, struct uart_8250_port, port);
-
-       spin_lock_irqsave(&up->port.lock, flags);
-
-       iir = port->serial_in(port, UART_IIR);
-       if (iir & UART_IIR_NO_INT) {
-               spin_unlock_irqrestore(&up->port.lock, flags);
-               return 0;
-       }
-
-       /* This is the WAR; if last event was BRK, then read and return */
-       if (unlikely(up->lsr_saved_flags & UART_LSR_BI)) {
-               up->lsr_saved_flags &= ~UART_LSR_BI;
-               port->serial_in(port, UART_RX);
-               spin_unlock_irqrestore(&up->port.lock, flags);
-               return 1;
-       }
-
-       lsr = orig_lsr = up->port.serial_in(&up->port, UART_LSR);
-
-       if (lsr & (UART_LSR_DR | UART_LSR_BI))
-               lsr = serial8250_rx_chars(up, lsr);
-
-       serial8250_modem_status(up);
-
-       if (lsr & UART_LSR_THRE)
-               serial8250_tx_chars(up);
-
-       up->lsr_saved_flags = orig_lsr;
-       spin_unlock_irqrestore(&up->port.lock, flags);
-       return 1;
-}
diff --git a/drivers/tty/serial/8250_gsc.c b/drivers/tty/serial/8250_gsc.c
deleted file mode 100644 (file)
index d8c0ffb..0000000
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- *     Serial Device Initialisation for Lasi/Asp/Wax/Dino
- *
- *     (c) Copyright Matthew Wilcox <willy@debian.org> 2001-2002
- *
- *     This program is free software; you can redistribute it and/or modify
- *     it under the terms of the GNU General Public License as published by
- *      the Free Software Foundation; either version 2 of the License, or
- *      (at your option) any later version.
- */
-
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/ioport.h>
-#include <linux/module.h>
-#include <linux/serial_core.h>
-#include <linux/signal.h>
-#include <linux/types.h>
-
-#include <asm/hardware.h>
-#include <asm/parisc-device.h>
-#include <asm/io.h>
-
-#include "8250.h"
-
-static int __init serial_init_chip(struct parisc_device *dev)
-{
-       struct uart_port port;
-       unsigned long address;
-       int err;
-
-       if (!dev->irq) {
-               /* We find some unattached serial ports by walking native
-                * busses.  These should be silently ignored.  Otherwise,
-                * what we have here is a missing parent device, so tell
-                * the user what they're missing.
-                */
-               if (parisc_parent(dev)->id.hw_type != HPHW_IOA)
-                       printk(KERN_INFO
-                               "Serial: device 0x%llx not configured.\n"
-                               "Enable support for Wax, Lasi, Asp or Dino.\n",
-                               (unsigned long long)dev->hpa.start);
-               return -ENODEV;
-       }
-
-       address = dev->hpa.start;
-       if (dev->id.sversion != 0x8d)
-               address += 0x800;
-
-       memset(&port, 0, sizeof(port));
-       port.iotype     = UPIO_MEM;
-       /* 7.272727MHz on Lasi.  Assumed the same for Dino, Wax and Timi. */
-       port.uartclk    = 7272727;
-       port.mapbase    = address;
-       port.membase    = ioremap_nocache(address, 16);
-       port.irq        = dev->irq;
-       port.flags      = UPF_BOOT_AUTOCONF;
-       port.dev        = &dev->dev;
-
-       err = serial8250_register_port(&port);
-       if (err < 0) {
-               printk(KERN_WARNING
-                       "serial8250_register_port returned error %d\n", err);
-               iounmap(port.membase);
-               return err;
-       }
-
-       return 0;
-}
-
-static struct parisc_device_id serial_tbl[] = {
-       { HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x00075 },
-       { HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x0008c },
-       { HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x0008d },
-       { 0 }
-};
-
-/* Hack.  Some machines have SERIAL_0 attached to Lasi and SERIAL_1
- * attached to Dino.  Unfortunately, Dino appears before Lasi in the device
- * tree.  To ensure that ttyS0 == SERIAL_0, we register two drivers; one
- * which only knows about Lasi and then a second which will find all the
- * other serial ports.  HPUX ignores this problem.
- */
-static struct parisc_device_id lasi_tbl[] = {
-       { HPHW_FIO, HVERSION_REV_ANY_ID, 0x03B, 0x0008C }, /* C1xx/C1xxL */
-       { HPHW_FIO, HVERSION_REV_ANY_ID, 0x03C, 0x0008C }, /* B132L */
-       { HPHW_FIO, HVERSION_REV_ANY_ID, 0x03D, 0x0008C }, /* B160L */
-       { HPHW_FIO, HVERSION_REV_ANY_ID, 0x03E, 0x0008C }, /* B132L+ */
-       { HPHW_FIO, HVERSION_REV_ANY_ID, 0x03F, 0x0008C }, /* B180L+ */
-       { HPHW_FIO, HVERSION_REV_ANY_ID, 0x046, 0x0008C }, /* Rocky2 120 */
-       { HPHW_FIO, HVERSION_REV_ANY_ID, 0x047, 0x0008C }, /* Rocky2 150 */
-       { HPHW_FIO, HVERSION_REV_ANY_ID, 0x04E, 0x0008C }, /* Kiji L2 132 */
-       { HPHW_FIO, HVERSION_REV_ANY_ID, 0x056, 0x0008C }, /* Raven+ */
-       { 0 }
-};
-
-
-MODULE_DEVICE_TABLE(parisc, serial_tbl);
-
-static struct parisc_driver lasi_driver = {
-       .name           = "serial_1",
-       .id_table       = lasi_tbl,
-       .probe          = serial_init_chip,
-};
-
-static struct parisc_driver serial_driver = {
-       .name           = "serial",
-       .id_table       = serial_tbl,
-       .probe          = serial_init_chip,
-};
-
-static int __init probe_serial_gsc(void)
-{
-       register_parisc_driver(&lasi_driver);
-       register_parisc_driver(&serial_driver);
-       return 0;
-}
-
-module_init(probe_serial_gsc);
-
-MODULE_LICENSE("GPL");
diff --git a/drivers/tty/serial/8250_hp300.c b/drivers/tty/serial/8250_hp300.c
deleted file mode 100644 (file)
index c13438c..0000000
+++ /dev/null
@@ -1,327 +0,0 @@
-/*
- * Driver for the 98626/98644/internal serial interface on hp300/hp400
- * (based on the National Semiconductor INS8250/NS16550AF/WD16C552 UARTs)
- *
- * Ported from 2.2 and modified to use the normal 8250 driver
- * by Kars de Jong <jongk@linux-m68k.org>, May 2004.
- */
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/string.h>
-#include <linux/kernel.h>
-#include <linux/serial.h>
-#include <linux/serial_core.h>
-#include <linux/serial_8250.h>
-#include <linux/delay.h>
-#include <linux/dio.h>
-#include <linux/console.h>
-#include <linux/slab.h>
-#include <asm/io.h>
-
-#include "8250.h"
-
-#if !defined(CONFIG_HPDCA) && !defined(CONFIG_HPAPCI)
-#warning CONFIG_8250 defined but neither CONFIG_HPDCA nor CONFIG_HPAPCI defined, are you sure?
-#endif
-
-#ifdef CONFIG_HPAPCI
-struct hp300_port
-{
-       struct hp300_port *next;        /* next port */
-       int line;                       /* line (tty) number */
-};
-
-static struct hp300_port *hp300_ports;
-#endif
-
-#ifdef CONFIG_HPDCA
-
-static int __devinit hpdca_init_one(struct dio_dev *d,
-                                       const struct dio_device_id *ent);
-static void __devexit hpdca_remove_one(struct dio_dev *d);
-
-static struct dio_device_id hpdca_dio_tbl[] = {
-       { DIO_ID_DCA0 },
-       { DIO_ID_DCA0REM },
-       { DIO_ID_DCA1 },
-       { DIO_ID_DCA1REM },
-       { 0 }
-};
-
-static struct dio_driver hpdca_driver = {
-       .name      = "hpdca",
-       .id_table  = hpdca_dio_tbl,
-       .probe     = hpdca_init_one,
-       .remove    = __devexit_p(hpdca_remove_one),
-};
-
-#endif
-
-static unsigned int num_ports;
-
-extern int hp300_uart_scode;
-
-/* Offset to UART registers from base of DCA */
-#define UART_OFFSET    17
-
-#define DCA_ID         0x01    /* ID (read), reset (write) */
-#define DCA_IC         0x03    /* Interrupt control        */
-
-/* Interrupt control */
-#define DCA_IC_IE      0x80    /* Master interrupt enable  */
-
-#define HPDCA_BAUD_BASE 153600
-
-/* Base address of the Frodo part */
-#define FRODO_BASE     (0x41c000)
-
-/*
- * Where we find the 8250-like APCI ports, and how far apart they are.
- */
-#define FRODO_APCIBASE         0x0
-#define FRODO_APCISPACE                0x20
-#define FRODO_APCI_OFFSET(x)   (FRODO_APCIBASE + ((x) * FRODO_APCISPACE))
-
-#define HPAPCI_BAUD_BASE 500400
-
-#ifdef CONFIG_SERIAL_8250_CONSOLE
-/*
- * Parse the bootinfo to find descriptions for headless console and
- * debug serial ports and register them with the 8250 driver.
- * This function should be called before serial_console_init() is called
- * to make sure the serial console will be available for use. IA-64 kernel
- * calls this function from setup_arch() after the EFI and ACPI tables have
- * been parsed.
- */
-int __init hp300_setup_serial_console(void)
-{
-       int scode;
-       struct uart_port port;
-
-       memset(&port, 0, sizeof(port));
-
-       if (hp300_uart_scode < 0 || hp300_uart_scode > DIO_SCMAX)
-               return 0;
-
-       if (DIO_SCINHOLE(hp300_uart_scode))
-               return 0;
-
-       scode = hp300_uart_scode;
-
-       /* Memory mapped I/O */
-       port.iotype = UPIO_MEM;
-       port.flags = UPF_SKIP_TEST | UPF_SHARE_IRQ | UPF_BOOT_AUTOCONF;
-       port.type = PORT_UNKNOWN;
-
-       /* Check for APCI console */
-       if (scode == 256) {
-#ifdef CONFIG_HPAPCI
-               printk(KERN_INFO "Serial console is HP APCI 1\n");
-
-               port.uartclk = HPAPCI_BAUD_BASE * 16;
-               port.mapbase = (FRODO_BASE + FRODO_APCI_OFFSET(1));
-               port.membase = (char *)(port.mapbase + DIO_VIRADDRBASE);
-               port.regshift = 2;
-               add_preferred_console("ttyS", port.line, "9600n8");
-#else
-               printk(KERN_WARNING "Serial console is APCI but support is disabled (CONFIG_HPAPCI)!\n");
-               return 0;
-#endif
-       } else {
-#ifdef CONFIG_HPDCA
-               unsigned long pa = dio_scodetophysaddr(scode);
-               if (!pa)
-                       return 0;
-
-               printk(KERN_INFO "Serial console is HP DCA at select code %d\n", scode);
-
-               port.uartclk = HPDCA_BAUD_BASE * 16;
-               port.mapbase = (pa + UART_OFFSET);
-               port.membase = (char *)(port.mapbase + DIO_VIRADDRBASE);
-               port.regshift = 1;
-               port.irq = DIO_IPL(pa + DIO_VIRADDRBASE);
-
-               /* Enable board-interrupts */
-               out_8(pa + DIO_VIRADDRBASE + DCA_IC, DCA_IC_IE);
-
-               if (DIO_ID(pa + DIO_VIRADDRBASE) & 0x80)
-                       add_preferred_console("ttyS", port.line, "9600n8");
-#else
-               printk(KERN_WARNING "Serial console is DCA but support is disabled (CONFIG_HPDCA)!\n");
-               return 0;
-#endif
-       }
-
-       if (early_serial_setup(&port) < 0)
-               printk(KERN_WARNING "hp300_setup_serial_console(): early_serial_setup() failed.\n");
-       return 0;
-}
-#endif /* CONFIG_SERIAL_8250_CONSOLE */
-
-#ifdef CONFIG_HPDCA
-static int __devinit hpdca_init_one(struct dio_dev *d,
-                               const struct dio_device_id *ent)
-{
-       struct uart_port port;
-       int line;
-
-#ifdef CONFIG_SERIAL_8250_CONSOLE
-       if (hp300_uart_scode == d->scode) {
-               /* Already got it. */
-               return 0;
-       }
-#endif
-       memset(&port, 0, sizeof(struct uart_port));
-
-       /* Memory mapped I/O */
-       port.iotype = UPIO_MEM;
-       port.flags = UPF_SKIP_TEST | UPF_SHARE_IRQ | UPF_BOOT_AUTOCONF;
-       port.irq = d->ipl;
-       port.uartclk = HPDCA_BAUD_BASE * 16;
-       port.mapbase = (d->resource.start + UART_OFFSET);
-       port.membase = (char *)(port.mapbase + DIO_VIRADDRBASE);
-       port.regshift = 1;
-       port.dev = &d->dev;
-       line = serial8250_register_port(&port);
-
-       if (line < 0) {
-               printk(KERN_NOTICE "8250_hp300: register_serial() DCA scode %d"
-                      " irq %d failed\n", d->scode, port.irq);
-               return -ENOMEM;
-       }
-
-       /* Enable board-interrupts */
-       out_8(d->resource.start + DIO_VIRADDRBASE + DCA_IC, DCA_IC_IE);
-       dio_set_drvdata(d, (void *)line);
-
-       /* Reset the DCA */
-       out_8(d->resource.start + DIO_VIRADDRBASE + DCA_ID, 0xff);
-       udelay(100);
-
-       num_ports++;
-
-       return 0;
-}
-#endif
-
-static int __init hp300_8250_init(void)
-{
-       static int called;
-#ifdef CONFIG_HPAPCI
-       int line;
-       unsigned long base;
-       struct uart_port uport;
-       struct hp300_port *port;
-       int i;
-#endif
-       if (called)
-               return -ENODEV;
-       called = 1;
-
-       if (!MACH_IS_HP300)
-               return -ENODEV;
-
-#ifdef CONFIG_HPDCA
-       dio_register_driver(&hpdca_driver);
-#endif
-#ifdef CONFIG_HPAPCI
-       if (hp300_model < HP_400) {
-               if (!num_ports)
-                       return -ENODEV;
-               return 0;
-       }
-       /* These models have the Frodo chip.
-        * Port 0 is reserved for the Apollo Domain keyboard.
-        * Port 1 is either the console or the DCA.
-        */
-       for (i = 1; i < 4; i++) {
-               /* Port 1 is the console on a 425e, on other machines it's
-                * mapped to DCA.
-                */
-#ifdef CONFIG_SERIAL_8250_CONSOLE
-               if (i == 1)
-                       continue;
-#endif
-
-               /* Create new serial device */
-               port = kmalloc(sizeof(struct hp300_port), GFP_KERNEL);
-               if (!port)
-                       return -ENOMEM;
-
-               memset(&uport, 0, sizeof(struct uart_port));
-
-               base = (FRODO_BASE + FRODO_APCI_OFFSET(i));
-
-               /* Memory mapped I/O */
-               uport.iotype = UPIO_MEM;
-               uport.flags = UPF_SKIP_TEST | UPF_SHARE_IRQ \
-                             | UPF_BOOT_AUTOCONF;
-               /* XXX - no interrupt support yet */
-               uport.irq = 0;
-               uport.uartclk = HPAPCI_BAUD_BASE * 16;
-               uport.mapbase = base;
-               uport.membase = (char *)(base + DIO_VIRADDRBASE);
-               uport.regshift = 2;
-
-               line = serial8250_register_port(&uport);
-
-               if (line < 0) {
-                       printk(KERN_NOTICE "8250_hp300: register_serial() APCI"
-                              " %d irq %d failed\n", i, uport.irq);
-                       kfree(port);
-                       continue;
-               }
-
-               port->line = line;
-               port->next = hp300_ports;
-               hp300_ports = port;
-
-               num_ports++;
-       }
-#endif
-
-       /* Any boards found? */
-       if (!num_ports)
-               return -ENODEV;
-
-       return 0;
-}
-
-#ifdef CONFIG_HPDCA
-static void __devexit hpdca_remove_one(struct dio_dev *d)
-{
-       int line;
-
-       line = (int) dio_get_drvdata(d);
-       if (d->resource.start) {
-               /* Disable board-interrupts */
-               out_8(d->resource.start + DIO_VIRADDRBASE + DCA_IC, 0);
-       }
-       serial8250_unregister_port(line);
-}
-#endif
-
-static void __exit hp300_8250_exit(void)
-{
-#ifdef CONFIG_HPAPCI
-       struct hp300_port *port, *to_free;
-
-       for (port = hp300_ports; port; ) {
-               serial8250_unregister_port(port->line);
-               to_free = port;
-               port = port->next;
-               kfree(to_free);
-       }
-
-       hp300_ports = NULL;
-#endif
-#ifdef CONFIG_HPDCA
-       dio_unregister_driver(&hpdca_driver);
-#endif
-}
-
-module_init(hp300_8250_init);
-module_exit(hp300_8250_exit);
-MODULE_DESCRIPTION("HP DCA/APCI serial driver");
-MODULE_AUTHOR("Kars de Jong <jongk@linux-m68k.org>");
-MODULE_LICENSE("GPL");
diff --git a/drivers/tty/serial/8250_hub6.c b/drivers/tty/serial/8250_hub6.c
deleted file mode 100644 (file)
index a5c778e..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- *  Copyright (C) 2005 Russell King.
- *  Data taken from include/asm-i386/serial.h
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/serial_8250.h>
-
-#define HUB6(card,port)                                                        \
-       {                                                               \
-               .iobase         = 0x302,                                \
-               .irq            = 3,                                    \
-               .uartclk        = 1843200,                              \
-               .iotype         = UPIO_HUB6,                            \
-               .flags          = UPF_BOOT_AUTOCONF,                    \
-               .hub6           = (card) << 6 | (port) << 3 | 1,        \
-       }
-
-static struct plat_serial8250_port hub6_data[] = {
-       HUB6(0, 0),
-       HUB6(0, 1),
-       HUB6(0, 2),
-       HUB6(0, 3),
-       HUB6(0, 4),
-       HUB6(0, 5),
-       HUB6(1, 0),
-       HUB6(1, 1),
-       HUB6(1, 2),
-       HUB6(1, 3),
-       HUB6(1, 4),
-       HUB6(1, 5),
-       { },
-};
-
-static struct platform_device hub6_device = {
-       .name                   = "serial8250",
-       .id                     = PLAT8250_DEV_HUB6,
-       .dev                    = {
-               .platform_data  = hub6_data,
-       },
-};
-
-static int __init hub6_init(void)
-{
-       return platform_device_register(&hub6_device);
-}
-
-module_init(hub6_init);
-
-MODULE_AUTHOR("Russell King");
-MODULE_DESCRIPTION("8250 serial probe module for Hub6 cards");
-MODULE_LICENSE("GPL");
diff --git a/drivers/tty/serial/8250_mca.c b/drivers/tty/serial/8250_mca.c
deleted file mode 100644 (file)
index d20abf0..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- *  Copyright (C) 2005 Russell King.
- *  Data taken from include/asm-i386/serial.h
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/mca.h>
-#include <linux/serial_8250.h>
-
-/*
- * FIXME: Should we be doing AUTO_IRQ here?
- */
-#ifdef CONFIG_SERIAL_8250_DETECT_IRQ
-#define MCA_FLAGS      UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_AUTO_IRQ
-#else
-#define MCA_FLAGS      UPF_BOOT_AUTOCONF | UPF_SKIP_TEST
-#endif
-
-#define PORT(_base,_irq)                       \
-       {                                       \
-               .iobase         = _base,        \
-               .irq            = _irq,         \
-               .uartclk        = 1843200,      \
-               .iotype         = UPIO_PORT,    \
-               .flags          = MCA_FLAGS,    \
-       }
-
-static struct plat_serial8250_port mca_data[] = {
-       PORT(0x3220, 3),
-       PORT(0x3228, 3),
-       PORT(0x4220, 3),
-       PORT(0x4228, 3),
-       PORT(0x5220, 3),
-       PORT(0x5228, 3),
-       { },
-};
-
-static struct platform_device mca_device = {
-       .name                   = "serial8250",
-       .id                     = PLAT8250_DEV_MCA,
-       .dev                    = {
-               .platform_data  = mca_data,
-       },
-};
-
-static int __init mca_init(void)
-{
-       if (!MCA_bus)
-               return -ENODEV;
-       return platform_device_register(&mca_device);
-}
-
-module_init(mca_init);
-
-MODULE_AUTHOR("Russell King");
-MODULE_DESCRIPTION("8250 serial probe module for MCA ports");
-MODULE_LICENSE("GPL");
diff --git a/drivers/tty/serial/8250_pci.c b/drivers/tty/serial/8250_pci.c
deleted file mode 100644 (file)
index da2b0b0..0000000
+++ /dev/null
@@ -1,4223 +0,0 @@
-/*
- *  Probe module for 8250/16550-type PCI serial ports.
- *
- *  Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o.
- *
- *  Copyright (C) 2001 Russell King, All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License.
- */
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/pci.h>
-#include <linux/string.h>
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/delay.h>
-#include <linux/tty.h>
-#include <linux/serial_core.h>
-#include <linux/8250_pci.h>
-#include <linux/bitops.h>
-
-#include <asm/byteorder.h>
-#include <asm/io.h>
-
-#include "8250.h"
-
-#undef SERIAL_DEBUG_PCI
-
-/*
- * init function returns:
- *  > 0 - number of ports
- *  = 0 - use board->num_ports
- *  < 0 - error
- */
-struct pci_serial_quirk {
-       u32     vendor;
-       u32     device;
-       u32     subvendor;
-       u32     subdevice;
-       int     (*probe)(struct pci_dev *dev);
-       int     (*init)(struct pci_dev *dev);
-       int     (*setup)(struct serial_private *,
-                        const struct pciserial_board *,
-                        struct uart_port *, int);
-       void    (*exit)(struct pci_dev *dev);
-};
-
-#define PCI_NUM_BAR_RESOURCES  6
-
-struct serial_private {
-       struct pci_dev          *dev;
-       unsigned int            nr;
-       void __iomem            *remapped_bar[PCI_NUM_BAR_RESOURCES];
-       struct pci_serial_quirk *quirk;
-       int                     line[0];
-};
-
-static int pci_default_setup(struct serial_private*,
-         const struct pciserial_board*, struct uart_port*, int);
-
-static void moan_device(const char *str, struct pci_dev *dev)
-{
-       printk(KERN_WARNING
-              "%s: %s\n"
-              "Please send the output of lspci -vv, this\n"
-              "message (0x%04x,0x%04x,0x%04x,0x%04x), the\n"
-              "manufacturer and name of serial board or\n"
-              "modem board to rmk+serial@arm.linux.org.uk.\n",
-              pci_name(dev), str, dev->vendor, dev->device,
-              dev->subsystem_vendor, dev->subsystem_device);
-}
-
-static int
-setup_port(struct serial_private *priv, struct uart_port *port,
-          int bar, int offset, int regshift)
-{
-       struct pci_dev *dev = priv->dev;
-       unsigned long base, len;
-
-       if (bar >= PCI_NUM_BAR_RESOURCES)
-               return -EINVAL;
-
-       base = pci_resource_start(dev, bar);
-
-       if (pci_resource_flags(dev, bar) & IORESOURCE_MEM) {
-               len =  pci_resource_len(dev, bar);
-
-               if (!priv->remapped_bar[bar])
-                       priv->remapped_bar[bar] = ioremap_nocache(base, len);
-               if (!priv->remapped_bar[bar])
-                       return -ENOMEM;
-
-               port->iotype = UPIO_MEM;
-               port->iobase = 0;
-               port->mapbase = base + offset;
-               port->membase = priv->remapped_bar[bar] + offset;
-               port->regshift = regshift;
-       } else {
-               port->iotype = UPIO_PORT;
-               port->iobase = base + offset;
-               port->mapbase = 0;
-               port->membase = NULL;
-               port->regshift = 0;
-       }
-       return 0;
-}
-
-/*
- * ADDI-DATA GmbH communication cards <info@addi-data.com>
- */
-static int addidata_apci7800_setup(struct serial_private *priv,
-                               const struct pciserial_board *board,
-                               struct uart_port *port, int idx)
-{
-       unsigned int bar = 0, offset = board->first_offset;
-       bar = FL_GET_BASE(board->flags);
-
-       if (idx < 2) {
-               offset += idx * board->uart_offset;
-       } else if ((idx >= 2) && (idx < 4)) {
-               bar += 1;
-               offset += ((idx - 2) * board->uart_offset);
-       } else if ((idx >= 4) && (idx < 6)) {
-               bar += 2;
-               offset += ((idx - 4) * board->uart_offset);
-       } else if (idx >= 6) {
-               bar += 3;
-               offset += ((idx - 6) * board->uart_offset);
-       }
-
-       return setup_port(priv, port, bar, offset, board->reg_shift);
-}
-
-/*
- * AFAVLAB uses a different mixture of BARs and offsets
- * Not that ugly ;) -- HW
- */
-static int
-afavlab_setup(struct serial_private *priv, const struct pciserial_board *board,
-             struct uart_port *port, int idx)
-{
-       unsigned int bar, offset = board->first_offset;
-
-       bar = FL_GET_BASE(board->flags);
-       if (idx < 4)
-               bar += idx;
-       else {
-               bar = 4;
-               offset += (idx - 4) * board->uart_offset;
-       }
-
-       return setup_port(priv, port, bar, offset, board->reg_shift);
-}
-
-/*
- * HP's Remote Management Console.  The Diva chip came in several
- * different versions.  N-class, L2000 and A500 have two Diva chips, each
- * with 3 UARTs (the third UART on the second chip is unused).  Superdome
- * and Keystone have one Diva chip with 3 UARTs.  Some later machines have
- * one Diva chip, but it has been expanded to 5 UARTs.
- */
-static int pci_hp_diva_init(struct pci_dev *dev)
-{
-       int rc = 0;
-
-       switch (dev->subsystem_device) {
-       case PCI_DEVICE_ID_HP_DIVA_TOSCA1:
-       case PCI_DEVICE_ID_HP_DIVA_HALFDOME:
-       case PCI_DEVICE_ID_HP_DIVA_KEYSTONE:
-       case PCI_DEVICE_ID_HP_DIVA_EVEREST:
-               rc = 3;
-               break;
-       case PCI_DEVICE_ID_HP_DIVA_TOSCA2:
-               rc = 2;
-               break;
-       case PCI_DEVICE_ID_HP_DIVA_MAESTRO:
-               rc = 4;
-               break;
-       case PCI_DEVICE_ID_HP_DIVA_POWERBAR:
-       case PCI_DEVICE_ID_HP_DIVA_HURRICANE:
-               rc = 1;
-               break;
-       }
-
-       return rc;
-}
-
-/*
- * HP's Diva chip puts the 4th/5th serial port further out, and
- * some serial ports are supposed to be hidden on certain models.
- */
-static int
-pci_hp_diva_setup(struct serial_private *priv,
-               const struct pciserial_board *board,
-               struct uart_port *port, int idx)
-{
-       unsigned int offset = board->first_offset;
-       unsigned int bar = FL_GET_BASE(board->flags);
-
-       switch (priv->dev->subsystem_device) {
-       case PCI_DEVICE_ID_HP_DIVA_MAESTRO:
-               if (idx == 3)
-                       idx++;
-               break;
-       case PCI_DEVICE_ID_HP_DIVA_EVEREST:
-               if (idx > 0)
-                       idx++;
-               if (idx > 2)
-                       idx++;
-               break;
-       }
-       if (idx > 2)
-               offset = 0x18;
-
-       offset += idx * board->uart_offset;
-
-       return setup_port(priv, port, bar, offset, board->reg_shift);
-}
-
-/*
- * Added for EKF Intel i960 serial boards
- */
-static int pci_inteli960ni_init(struct pci_dev *dev)
-{
-       unsigned long oldval;
-
-       if (!(dev->subsystem_device & 0x1000))
-               return -ENODEV;
-
-       /* is firmware started? */
-       pci_read_config_dword(dev, 0x44, (void *)&oldval);
-       if (oldval == 0x00001000L) { /* RESET value */
-               printk(KERN_DEBUG "Local i960 firmware missing");
-               return -ENODEV;
-       }
-       return 0;
-}
-
-/*
- * Some PCI serial cards using the PLX 9050 PCI interface chip require
- * that the card interrupt be explicitly enabled or disabled.  This
- * seems to be mainly needed on card using the PLX which also use I/O
- * mapped memory.
- */
-static int pci_plx9050_init(struct pci_dev *dev)
-{
-       u8 irq_config;
-       void __iomem *p;
-
-       if ((pci_resource_flags(dev, 0) & IORESOURCE_MEM) == 0) {
-               moan_device("no memory in bar 0", dev);
-               return 0;
-       }
-
-       irq_config = 0x41;
-       if (dev->vendor == PCI_VENDOR_ID_PANACOM ||
-           dev->subsystem_vendor == PCI_SUBVENDOR_ID_EXSYS)
-               irq_config = 0x43;
-
-       if ((dev->vendor == PCI_VENDOR_ID_PLX) &&
-           (dev->device == PCI_DEVICE_ID_PLX_ROMULUS))
-               /*
-                * As the megawolf cards have the int pins active
-                * high, and have 2 UART chips, both ints must be
-                * enabled on the 9050. Also, the UARTS are set in
-                * 16450 mode by default, so we have to enable the
-                * 16C950 'enhanced' mode so that we can use the
-                * deep FIFOs
-                */
-               irq_config = 0x5b;
-       /*
-        * enable/disable interrupts
-        */
-       p = ioremap_nocache(pci_resource_start(dev, 0), 0x80);
-       if (p == NULL)
-               return -ENOMEM;
-       writel(irq_config, p + 0x4c);
-
-       /*
-        * Read the register back to ensure that it took effect.
-        */
-       readl(p + 0x4c);
-       iounmap(p);
-
-       return 0;
-}
-
-static void __devexit pci_plx9050_exit(struct pci_dev *dev)
-{
-       u8 __iomem *p;
-
-       if ((pci_resource_flags(dev, 0) & IORESOURCE_MEM) == 0)
-               return;
-
-       /*
-        * disable interrupts
-        */
-       p = ioremap_nocache(pci_resource_start(dev, 0), 0x80);
-       if (p != NULL) {
-               writel(0, p + 0x4c);
-
-               /*
-                * Read the register back to ensure that it took effect.
-                */
-               readl(p + 0x4c);
-               iounmap(p);
-       }
-}
-
-#define NI8420_INT_ENABLE_REG  0x38
-#define NI8420_INT_ENABLE_BIT  0x2000
-
-static void __devexit pci_ni8420_exit(struct pci_dev *dev)
-{
-       void __iomem *p;
-       unsigned long base, len;
-       unsigned int bar = 0;
-
-       if ((pci_resource_flags(dev, bar) & IORESOURCE_MEM) == 0) {
-               moan_device("no memory in bar", dev);
-               return;
-       }
-
-       base = pci_resource_start(dev, bar);
-       len =  pci_resource_len(dev, bar);
-       p = ioremap_nocache(base, len);
-       if (p == NULL)
-               return;
-
-       /* Disable the CPU Interrupt */
-       writel(readl(p + NI8420_INT_ENABLE_REG) & ~(NI8420_INT_ENABLE_BIT),
-              p + NI8420_INT_ENABLE_REG);
-       iounmap(p);
-}
-
-
-/* MITE registers */
-#define MITE_IOWBSR1   0xc4
-#define MITE_IOWCR1    0xf4
-#define MITE_LCIMR1    0x08
-#define MITE_LCIMR2    0x10
-
-#define MITE_LCIMR2_CLR_CPU_IE (1 << 30)
-
-static void __devexit pci_ni8430_exit(struct pci_dev *dev)
-{
-       void __iomem *p;
-       unsigned long base, len;
-       unsigned int bar = 0;
-
-       if ((pci_resource_flags(dev, bar) & IORESOURCE_MEM) == 0) {
-               moan_device("no memory in bar", dev);
-               return;
-       }
-
-       base = pci_resource_start(dev, bar);
-       len =  pci_resource_len(dev, bar);
-       p = ioremap_nocache(base, len);
-       if (p == NULL)
-               return;
-
-       /* Disable the CPU Interrupt */
-       writel(MITE_LCIMR2_CLR_CPU_IE, p + MITE_LCIMR2);
-       iounmap(p);
-}
-
-/* SBS Technologies Inc. PMC-OCTPRO and P-OCTAL cards */
-static int
-sbs_setup(struct serial_private *priv, const struct pciserial_board *board,
-               struct uart_port *port, int idx)
-{
-       unsigned int bar, offset = board->first_offset;
-
-       bar = 0;
-
-       if (idx < 4) {
-               /* first four channels map to 0, 0x100, 0x200, 0x300 */
-               offset += idx * board->uart_offset;
-       } else if (idx < 8) {
-               /* last four channels map to 0x1000, 0x1100, 0x1200, 0x1300 */
-               offset += idx * board->uart_offset + 0xC00;
-       } else /* we have only 8 ports on PMC-OCTALPRO */
-               return 1;
-
-       return setup_port(priv, port, bar, offset, board->reg_shift);
-}
-
-/*
-* This does initialization for PMC OCTALPRO cards:
-* maps the device memory, resets the UARTs (needed, bc
-* if the module is removed and inserted again, the card
-* is in the sleep mode) and enables global interrupt.
-*/
-
-/* global control register offset for SBS PMC-OctalPro */
-#define OCT_REG_CR_OFF         0x500
-
-static int sbs_init(struct pci_dev *dev)
-{
-       u8 __iomem *p;
-
-       p = pci_ioremap_bar(dev, 0);
-
-       if (p == NULL)
-               return -ENOMEM;
-       /* Set bit-4 Control Register (UART RESET) in to reset the uarts */
-       writeb(0x10, p + OCT_REG_CR_OFF);
-       udelay(50);
-       writeb(0x0, p + OCT_REG_CR_OFF);
-
-       /* Set bit-2 (INTENABLE) of Control Register */
-       writeb(0x4, p + OCT_REG_CR_OFF);
-       iounmap(p);
-
-       return 0;
-}
-
-/*
- * Disables the global interrupt of PMC-OctalPro
- */
-
-static void __devexit sbs_exit(struct pci_dev *dev)
-{
-       u8 __iomem *p;
-
-       p = pci_ioremap_bar(dev, 0);
-       /* FIXME: What if resource_len < OCT_REG_CR_OFF */
-       if (p != NULL)
-               writeb(0, p + OCT_REG_CR_OFF);
-       iounmap(p);
-}
-
-/*
- * SIIG serial cards have an PCI interface chip which also controls
- * the UART clocking frequency. Each UART can be clocked independently
- * (except cards equipped with 4 UARTs) and initial clocking settings
- * are stored in the EEPROM chip. It can cause problems because this
- * version of serial driver doesn't support differently clocked UART's
- * on single PCI card. To prevent this, initialization functions set
- * high frequency clocking for all UART's on given card. It is safe (I
- * hope) because it doesn't touch EEPROM settings to prevent conflicts
- * with other OSes (like M$ DOS).
- *
- *  SIIG support added by Andrey Panin <pazke@donpac.ru>, 10/1999
- *
- * There is two family of SIIG serial cards with different PCI
- * interface chip and different configuration methods:
- *     - 10x cards have control registers in IO and/or memory space;
- *     - 20x cards have control registers in standard PCI configuration space.
- *
- * Note: all 10x cards have PCI device ids 0x10..
- *       all 20x cards have PCI device ids 0x20..
- *
- * There are also Quartet Serial cards which use Oxford Semiconductor
- * 16954 quad UART PCI chip clocked by 18.432 MHz quartz.
- *
- * Note: some SIIG cards are probed by the parport_serial object.
- */
-
-#define PCI_DEVICE_ID_SIIG_1S_10x (PCI_DEVICE_ID_SIIG_1S_10x_550 & 0xfffc)
-#define PCI_DEVICE_ID_SIIG_2S_10x (PCI_DEVICE_ID_SIIG_2S_10x_550 & 0xfff8)
-
-static int pci_siig10x_init(struct pci_dev *dev)
-{
-       u16 data;
-       void __iomem *p;
-
-       switch (dev->device & 0xfff8) {
-       case PCI_DEVICE_ID_SIIG_1S_10x: /* 1S */
-               data = 0xffdf;
-               break;
-       case PCI_DEVICE_ID_SIIG_2S_10x: /* 2S, 2S1P */
-               data = 0xf7ff;
-               break;
-       default:                        /* 1S1P, 4S */
-               data = 0xfffb;
-               break;
-       }
-
-       p = ioremap_nocache(pci_resource_start(dev, 0), 0x80);
-       if (p == NULL)
-               return -ENOMEM;
-
-       writew(readw(p + 0x28) & data, p + 0x28);
-       readw(p + 0x28);
-       iounmap(p);
-       return 0;
-}
-
-#define PCI_DEVICE_ID_SIIG_2S_20x (PCI_DEVICE_ID_SIIG_2S_20x_550 & 0xfffc)
-#define PCI_DEVICE_ID_SIIG_2S1P_20x (PCI_DEVICE_ID_SIIG_2S1P_20x_550 & 0xfffc)
-
-static int pci_siig20x_init(struct pci_dev *dev)
-{
-       u8 data;
-
-       /* Change clock frequency for the first UART. */
-       pci_read_config_byte(dev, 0x6f, &data);
-       pci_write_config_byte(dev, 0x6f, data & 0xef);
-
-       /* If this card has 2 UART, we have to do the same with second UART. */
-       if (((dev->device & 0xfffc) == PCI_DEVICE_ID_SIIG_2S_20x) ||
-           ((dev->device & 0xfffc) == PCI_DEVICE_ID_SIIG_2S1P_20x)) {
-               pci_read_config_byte(dev, 0x73, &data);
-               pci_write_config_byte(dev, 0x73, data & 0xef);
-       }
-       return 0;
-}
-
-static int pci_siig_init(struct pci_dev *dev)
-{
-       unsigned int type = dev->device & 0xff00;
-
-       if (type == 0x1000)
-               return pci_siig10x_init(dev);
-       else if (type == 0x2000)
-               return pci_siig20x_init(dev);
-
-       moan_device("Unknown SIIG card", dev);
-       return -ENODEV;
-}
-
-static int pci_siig_setup(struct serial_private *priv,
-                         const struct pciserial_board *board,
-                         struct uart_port *port, int idx)
-{
-       unsigned int bar = FL_GET_BASE(board->flags) + idx, offset = 0;
-
-       if (idx > 3) {
-               bar = 4;
-               offset = (idx - 4) * 8;
-       }
-
-       return setup_port(priv, port, bar, offset, 0);
-}
-
-/*
- * Timedia has an explosion of boards, and to avoid the PCI table from
- * growing *huge*, we use this function to collapse some 70 entries
- * in the PCI table into one, for sanity's and compactness's sake.
- */
-static const unsigned short timedia_single_port[] = {
-       0x4025, 0x4027, 0x4028, 0x5025, 0x5027, 0
-};
-
-static const unsigned short timedia_dual_port[] = {
-       0x0002, 0x4036, 0x4037, 0x4038, 0x4078, 0x4079, 0x4085,
-       0x4088, 0x4089, 0x5037, 0x5078, 0x5079, 0x5085, 0x6079,
-       0x7079, 0x8079, 0x8137, 0x8138, 0x8237, 0x8238, 0x9079,
-       0x9137, 0x9138, 0x9237, 0x9238, 0xA079, 0xB079, 0xC079,
-       0xD079, 0
-};
-
-static const unsigned short timedia_quad_port[] = {
-       0x4055, 0x4056, 0x4095, 0x4096, 0x5056, 0x8156, 0x8157,
-       0x8256, 0x8257, 0x9056, 0x9156, 0x9157, 0x9158, 0x9159,
-       0x9256, 0x9257, 0xA056, 0xA157, 0xA158, 0xA159, 0xB056,
-       0xB157, 0
-};
-
-static const unsigned short timedia_eight_port[] = {
-       0x4065, 0x4066, 0x5065, 0x5066, 0x8166, 0x9066, 0x9166,
-       0x9167, 0x9168, 0xA066, 0xA167, 0xA168, 0
-};
-
-static const struct timedia_struct {
-       int num;
-       const unsigned short *ids;
-} timedia_data[] = {
-       { 1, timedia_single_port },
-       { 2, timedia_dual_port },
-       { 4, timedia_quad_port },
-       { 8, timedia_eight_port }
-};
-
-/*
- * There are nearly 70 different Timedia/SUNIX PCI serial devices.  Instead of
- * listing them individually, this driver merely grabs them all with
- * PCI_ANY_ID.  Some of these devices, however, also feature a parallel port,
- * and should be left free to be claimed by parport_serial instead.
- */
-static int pci_timedia_probe(struct pci_dev *dev)
-{
-       /*
-        * Check the third digit of the subdevice ID
-        * (0,2,3,5,6: serial only -- 7,8,9: serial + parallel)
-        */
-       if ((dev->subsystem_device & 0x00f0) >= 0x70) {
-               dev_info(&dev->dev,
-                       "ignoring Timedia subdevice %04x for parport_serial\n",
-                       dev->subsystem_device);
-               return -ENODEV;
-       }
-
-       return 0;
-}
-
-static int pci_timedia_init(struct pci_dev *dev)
-{
-       const unsigned short *ids;
-       int i, j;
-
-       for (i = 0; i < ARRAY_SIZE(timedia_data); i++) {
-               ids = timedia_data[i].ids;
-               for (j = 0; ids[j]; j++)
-                       if (dev->subsystem_device == ids[j])
-                               return timedia_data[i].num;
-       }
-       return 0;
-}
-
-/*
- * Timedia/SUNIX uses a mixture of BARs and offsets
- * Ugh, this is ugly as all hell --- TYT
- */
-static int
-pci_timedia_setup(struct serial_private *priv,
-                 const struct pciserial_board *board,
-                 struct uart_port *port, int idx)
-{
-       unsigned int bar = 0, offset = board->first_offset;
-
-       switch (idx) {
-       case 0:
-               bar = 0;
-               break;
-       case 1:
-               offset = board->uart_offset;
-               bar = 0;
-               break;
-       case 2:
-               bar = 1;
-               break;
-       case 3:
-               offset = board->uart_offset;
-               /* FALLTHROUGH */
-       case 4: /* BAR 2 */
-       case 5: /* BAR 3 */
-       case 6: /* BAR 4 */
-       case 7: /* BAR 5 */
-               bar = idx - 2;
-       }
-
-       return setup_port(priv, port, bar, offset, board->reg_shift);
-}
-
-/*
- * Some Titan cards are also a little weird
- */
-static int
-titan_400l_800l_setup(struct serial_private *priv,
-                     const struct pciserial_board *board,
-                     struct uart_port *port, int idx)
-{
-       unsigned int bar, offset = board->first_offset;
-
-       switch (idx) {
-       case 0:
-               bar = 1;
-               break;
-       case 1:
-               bar = 2;
-               break;
-       default:
-               bar = 4;
-               offset = (idx - 2) * board->uart_offset;
-       }
-
-       return setup_port(priv, port, bar, offset, board->reg_shift);
-}
-
-static int pci_xircom_init(struct pci_dev *dev)
-{
-       msleep(100);
-       return 0;
-}
-
-static int pci_ni8420_init(struct pci_dev *dev)
-{
-       void __iomem *p;
-       unsigned long base, len;
-       unsigned int bar = 0;
-
-       if ((pci_resource_flags(dev, bar) & IORESOURCE_MEM) == 0) {
-               moan_device("no memory in bar", dev);
-               return 0;
-       }
-
-       base = pci_resource_start(dev, bar);
-       len =  pci_resource_len(dev, bar);
-       p = ioremap_nocache(base, len);
-       if (p == NULL)
-               return -ENOMEM;
-
-       /* Enable CPU Interrupt */
-       writel(readl(p + NI8420_INT_ENABLE_REG) | NI8420_INT_ENABLE_BIT,
-              p + NI8420_INT_ENABLE_REG);
-
-       iounmap(p);
-       return 0;
-}
-
-#define MITE_IOWBSR1_WSIZE     0xa
-#define MITE_IOWBSR1_WIN_OFFSET        0x800
-#define MITE_IOWBSR1_WENAB     (1 << 7)
-#define MITE_LCIMR1_IO_IE_0    (1 << 24)
-#define MITE_LCIMR2_SET_CPU_IE (1 << 31)
-#define MITE_IOWCR1_RAMSEL_MASK        0xfffffffe
-
-static int pci_ni8430_init(struct pci_dev *dev)
-{
-       void __iomem *p;
-       unsigned long base, len;
-       u32 device_window;
-       unsigned int bar = 0;
-
-       if ((pci_resource_flags(dev, bar) & IORESOURCE_MEM) == 0) {
-               moan_device("no memory in bar", dev);
-               return 0;
-       }
-
-       base = pci_resource_start(dev, bar);
-       len =  pci_resource_len(dev, bar);
-       p = ioremap_nocache(base, len);
-       if (p == NULL)
-               return -ENOMEM;
-
-       /* Set device window address and size in BAR0 */
-       device_window = ((base + MITE_IOWBSR1_WIN_OFFSET) & 0xffffff00)
-                       | MITE_IOWBSR1_WENAB | MITE_IOWBSR1_WSIZE;
-       writel(device_window, p + MITE_IOWBSR1);
-
-       /* Set window access to go to RAMSEL IO address space */
-       writel((readl(p + MITE_IOWCR1) & MITE_IOWCR1_RAMSEL_MASK),
-              p + MITE_IOWCR1);
-
-       /* Enable IO Bus Interrupt 0 */
-       writel(MITE_LCIMR1_IO_IE_0, p + MITE_LCIMR1);
-
-       /* Enable CPU Interrupt */
-       writel(MITE_LCIMR2_SET_CPU_IE, p + MITE_LCIMR2);
-
-       iounmap(p);
-       return 0;
-}
-
-/* UART Port Control Register */
-#define NI8430_PORTCON 0x0f
-#define NI8430_PORTCON_TXVR_ENABLE     (1 << 3)
-
-static int
-pci_ni8430_setup(struct serial_private *priv,
-                const struct pciserial_board *board,
-                struct uart_port *port, int idx)
-{
-       void __iomem *p;
-       unsigned long base, len;
-       unsigned int bar, offset = board->first_offset;
-
-       if (idx >= board->num_ports)
-               return 1;
-
-       bar = FL_GET_BASE(board->flags);
-       offset += idx * board->uart_offset;
-
-       base = pci_resource_start(priv->dev, bar);
-       len =  pci_resource_len(priv->dev, bar);
-       p = ioremap_nocache(base, len);
-
-       /* enable the transceiver */
-       writeb(readb(p + offset + NI8430_PORTCON) | NI8430_PORTCON_TXVR_ENABLE,
-              p + offset + NI8430_PORTCON);
-
-       iounmap(p);
-
-       return setup_port(priv, port, bar, offset, board->reg_shift);
-}
-
-static int pci_netmos_9900_setup(struct serial_private *priv,
-                               const struct pciserial_board *board,
-                               struct uart_port *port, int idx)
-{
-       unsigned int bar;
-
-       if ((priv->dev->subsystem_device & 0xff00) == 0x3000) {
-               /* netmos apparently orders BARs by datasheet layout, so serial
-                * ports get BARs 0 and 3 (or 1 and 4 for memmapped)
-                */
-               bar = 3 * idx;
-
-               return setup_port(priv, port, bar, 0, board->reg_shift);
-       } else {
-               return pci_default_setup(priv, board, port, idx);
-       }
-}
-
-/* the 99xx series comes with a range of device IDs and a variety
- * of capabilities:
- *
- * 9900 has varying capabilities and can cascade to sub-controllers
- *   (cascading should be purely internal)
- * 9904 is hardwired with 4 serial ports
- * 9912 and 9922 are hardwired with 2 serial ports
- */
-static int pci_netmos_9900_numports(struct pci_dev *dev)
-{
-       unsigned int c = dev->class;
-       unsigned int pi;
-       unsigned short sub_serports;
-
-       pi = (c & 0xff);
-
-       if (pi == 2) {
-               return 1;
-       } else if ((pi == 0) &&
-                          (dev->device == PCI_DEVICE_ID_NETMOS_9900)) {
-               /* two possibilities: 0x30ps encodes number of parallel and
-                * serial ports, or 0x1000 indicates *something*. This is not
-                * immediately obvious, since the 2s1p+4s configuration seems
-                * to offer all functionality on functions 0..2, while still
-                * advertising the same function 3 as the 4s+2s1p config.
-                */
-               sub_serports = dev->subsystem_device & 0xf;
-               if (sub_serports > 0) {
-                       return sub_serports;
-               } else {
-                       printk(KERN_NOTICE "NetMos/Mostech serial driver ignoring port on ambiguous config.\n");
-                       return 0;
-               }
-       }
-
-       moan_device("unknown NetMos/Mostech program interface", dev);
-       return 0;
-}
-
-static int pci_netmos_init(struct pci_dev *dev)
-{
-       /* subdevice 0x00PS means <P> parallel, <S> serial */
-       unsigned int num_serial = dev->subsystem_device & 0xf;
-
-       if ((dev->device == PCI_DEVICE_ID_NETMOS_9901) ||
-               (dev->device == PCI_DEVICE_ID_NETMOS_9865))
-               return 0;
-
-       if (dev->subsystem_vendor == PCI_VENDOR_ID_IBM &&
-                       dev->subsystem_device == 0x0299)
-               return 0;
-
-       switch (dev->device) { /* FALLTHROUGH on all */
-               case PCI_DEVICE_ID_NETMOS_9904:
-               case PCI_DEVICE_ID_NETMOS_9912:
-               case PCI_DEVICE_ID_NETMOS_9922:
-               case PCI_DEVICE_ID_NETMOS_9900:
-                       num_serial = pci_netmos_9900_numports(dev);
-                       break;
-
-               default:
-                       if (num_serial == 0 ) {
-                               moan_device("unknown NetMos/Mostech device", dev);
-                       }
-       }
-
-       if (num_serial == 0)
-               return -ENODEV;
-
-       return num_serial;
-}
-
-/*
- * These chips are available with optionally one parallel port and up to
- * two serial ports. Unfortunately they all have the same product id.
- *
- * Basic configuration is done over a region of 32 I/O ports. The base
- * ioport is called INTA or INTC, depending on docs/other drivers.
- *
- * The region of the 32 I/O ports is configured in POSIO0R...
- */
-
-/* registers */
-#define ITE_887x_MISCR         0x9c
-#define ITE_887x_INTCBAR       0x78
-#define ITE_887x_UARTBAR       0x7c
-#define ITE_887x_PS0BAR                0x10
-#define ITE_887x_POSIO0                0x60
-
-/* I/O space size */
-#define ITE_887x_IOSIZE                32
-/* I/O space size (bits 26-24; 8 bytes = 011b) */
-#define ITE_887x_POSIO_IOSIZE_8                (3 << 24)
-/* I/O space size (bits 26-24; 32 bytes = 101b) */
-#define ITE_887x_POSIO_IOSIZE_32       (5 << 24)
-/* Decoding speed (1 = slow, 2 = medium, 3 = fast) */
-#define ITE_887x_POSIO_SPEED           (3 << 29)
-/* enable IO_Space bit */
-#define ITE_887x_POSIO_ENABLE          (1 << 31)
-
-static int pci_ite887x_init(struct pci_dev *dev)
-{
-       /* inta_addr are the configuration addresses of the ITE */
-       static const short inta_addr[] = { 0x2a0, 0x2c0, 0x220, 0x240, 0x1e0,
-                                                       0x200, 0x280, 0 };
-       int ret, i, type;
-       struct resource *iobase = NULL;
-       u32 miscr, uartbar, ioport;
-
-       /* search for the base-ioport */
-       i = 0;
-       while (inta_addr[i] && iobase == NULL) {
-               iobase = request_region(inta_addr[i], ITE_887x_IOSIZE,
-                                                               "ite887x");
-               if (iobase != NULL) {
-                       /* write POSIO0R - speed | size | ioport */
-                       pci_write_config_dword(dev, ITE_887x_POSIO0,
-                               ITE_887x_POSIO_ENABLE | ITE_887x_POSIO_SPEED |
-                               ITE_887x_POSIO_IOSIZE_32 | inta_addr[i]);
-                       /* write INTCBAR - ioport */
-                       pci_write_config_dword(dev, ITE_887x_INTCBAR,
-                                                               inta_addr[i]);
-                       ret = inb(inta_addr[i]);
-                       if (ret != 0xff) {
-                               /* ioport connected */
-                               break;
-                       }
-                       release_region(iobase->start, ITE_887x_IOSIZE);
-                       iobase = NULL;
-               }
-               i++;
-       }
-
-       if (!inta_addr[i]) {
-               printk(KERN_ERR "ite887x: could not find iobase\n");
-               return -ENODEV;
-       }
-
-       /* start of undocumented type checking (see parport_pc.c) */
-       type = inb(iobase->start + 0x18) & 0x0f;
-
-       switch (type) {
-       case 0x2:       /* ITE8871 (1P) */
-       case 0xa:       /* ITE8875 (1P) */
-               ret = 0;
-               break;
-       case 0xe:       /* ITE8872 (2S1P) */
-               ret = 2;
-               break;
-       case 0x6:       /* ITE8873 (1S) */
-               ret = 1;
-               break;
-       case 0x8:       /* ITE8874 (2S) */
-               ret = 2;
-               break;
-       default:
-               moan_device("Unknown ITE887x", dev);
-               ret = -ENODEV;
-       }
-
-       /* configure all serial ports */
-       for (i = 0; i < ret; i++) {
-               /* read the I/O port from the device */
-               pci_read_config_dword(dev, ITE_887x_PS0BAR + (0x4 * (i + 1)),
-                                                               &ioport);
-               ioport &= 0x0000FF00;   /* the actual base address */
-               pci_write_config_dword(dev, ITE_887x_POSIO0 + (0x4 * (i + 1)),
-                       ITE_887x_POSIO_ENABLE | ITE_887x_POSIO_SPEED |
-                       ITE_887x_POSIO_IOSIZE_8 | ioport);
-
-               /* write the ioport to the UARTBAR */
-               pci_read_config_dword(dev, ITE_887x_UARTBAR, &uartbar);
-               uartbar &= ~(0xffff << (16 * i));       /* clear half the reg */
-               uartbar |= (ioport << (16 * i));        /* set the ioport */
-               pci_write_config_dword(dev, ITE_887x_UARTBAR, uartbar);
-
-               /* get current config */
-               pci_read_config_dword(dev, ITE_887x_MISCR, &miscr);
-               /* disable interrupts (UARTx_Routing[3:0]) */
-               miscr &= ~(0xf << (12 - 4 * i));
-               /* activate the UART (UARTx_En) */
-               miscr |= 1 << (23 - i);
-               /* write new config with activated UART */
-               pci_write_config_dword(dev, ITE_887x_MISCR, miscr);
-       }
-
-       if (ret <= 0) {
-               /* the device has no UARTs if we get here */
-               release_region(iobase->start, ITE_887x_IOSIZE);
-       }
-
-       return ret;
-}
-
-static void __devexit pci_ite887x_exit(struct pci_dev *dev)
-{
-       u32 ioport;
-       /* the ioport is bit 0-15 in POSIO0R */
-       pci_read_config_dword(dev, ITE_887x_POSIO0, &ioport);
-       ioport &= 0xffff;
-       release_region(ioport, ITE_887x_IOSIZE);
-}
-
-/*
- * Oxford Semiconductor Inc.
- * Check that device is part of the Tornado range of devices, then determine
- * the number of ports available on the device.
- */
-static int pci_oxsemi_tornado_init(struct pci_dev *dev)
-{
-       u8 __iomem *p;
-       unsigned long deviceID;
-       unsigned int  number_uarts = 0;
-
-       /* OxSemi Tornado devices are all 0xCxxx */
-       if (dev->vendor == PCI_VENDOR_ID_OXSEMI &&
-           (dev->device & 0xF000) != 0xC000)
-               return 0;
-
-       p = pci_iomap(dev, 0, 5);
-       if (p == NULL)
-               return -ENOMEM;
-
-       deviceID = ioread32(p);
-       /* Tornado device */
-       if (deviceID == 0x07000200) {
-               number_uarts = ioread8(p + 4);
-               printk(KERN_DEBUG
-                       "%d ports detected on Oxford PCI Express device\n",
-                                                               number_uarts);
-       }
-       pci_iounmap(dev, p);
-       return number_uarts;
-}
-
-static int
-pci_default_setup(struct serial_private *priv,
-                 const struct pciserial_board *board,
-                 struct uart_port *port, int idx)
-{
-       unsigned int bar, offset = board->first_offset, maxnr;
-
-       bar = FL_GET_BASE(board->flags);
-       if (board->flags & FL_BASE_BARS)
-               bar += idx;
-       else
-               offset += idx * board->uart_offset;
-
-       maxnr = (pci_resource_len(priv->dev, bar) - board->first_offset) >>
-               (board->reg_shift + 3);
-
-       if (board->flags & FL_REGION_SZ_CAP && idx >= maxnr)
-               return 1;
-
-       return setup_port(priv, port, bar, offset, board->reg_shift);
-}
-
-static int
-ce4100_serial_setup(struct serial_private *priv,
-                 const struct pciserial_board *board,
-                 struct uart_port *port, int idx)
-{
-       int ret;
-
-       ret = setup_port(priv, port, 0, 0, board->reg_shift);
-       port->iotype = UPIO_MEM32;
-       port->type = PORT_XSCALE;
-       port->flags = (port->flags | UPF_FIXED_PORT | UPF_FIXED_TYPE);
-       port->regshift = 2;
-
-       return ret;
-}
-
-static int
-pci_omegapci_setup(struct serial_private *priv,
-                     const struct pciserial_board *board,
-                     struct uart_port *port, int idx)
-{
-       return setup_port(priv, port, 2, idx * 8, 0);
-}
-
-static int skip_tx_en_setup(struct serial_private *priv,
-                       const struct pciserial_board *board,
-                       struct uart_port *port, int idx)
-{
-       port->flags |= UPF_NO_TXEN_TEST;
-       printk(KERN_DEBUG "serial8250: skipping TxEn test for device "
-                         "[%04x:%04x] subsystem [%04x:%04x]\n",
-                         priv->dev->vendor,
-                         priv->dev->device,
-                         priv->dev->subsystem_vendor,
-                         priv->dev->subsystem_device);
-
-       return pci_default_setup(priv, board, port, idx);
-}
-
-static int kt_serial_setup(struct serial_private *priv,
-                          const struct pciserial_board *board,
-                          struct uart_port *port, int idx)
-{
-       port->flags |= UPF_IIR_ONCE;
-       return skip_tx_en_setup(priv, board, port, idx);
-}
-
-static int pci_eg20t_init(struct pci_dev *dev)
-{
-#if defined(CONFIG_SERIAL_PCH_UART) || defined(CONFIG_SERIAL_PCH_UART_MODULE)
-       return -ENODEV;
-#else
-       return 0;
-#endif
-}
-
-static int
-pci_xr17c154_setup(struct serial_private *priv,
-                 const struct pciserial_board *board,
-                 struct uart_port *port, int idx)
-{
-       port->flags |= UPF_EXAR_EFR;
-       return pci_default_setup(priv, board, port, idx);
-}
-
-static int try_enable_msi(struct pci_dev *dev)
-{
-       /* use msi if available, but fallback to legacy otherwise */
-       pci_enable_msi(dev);
-       return 0;
-}
-
-static void disable_msi(struct pci_dev *dev)
-{
-       pci_disable_msi(dev);
-}
-
-#define PCI_VENDOR_ID_SBSMODULARIO     0x124B
-#define PCI_SUBVENDOR_ID_SBSMODULARIO  0x124B
-#define PCI_DEVICE_ID_OCTPRO           0x0001
-#define PCI_SUBDEVICE_ID_OCTPRO232     0x0108
-#define PCI_SUBDEVICE_ID_OCTPRO422     0x0208
-#define PCI_SUBDEVICE_ID_POCTAL232     0x0308
-#define PCI_SUBDEVICE_ID_POCTAL422     0x0408
-#define PCI_VENDOR_ID_ADVANTECH                0x13fe
-#define PCI_DEVICE_ID_INTEL_CE4100_UART 0x2e66
-#define PCI_DEVICE_ID_ADVANTECH_PCI3620        0x3620
-#define PCI_DEVICE_ID_TITAN_200I       0x8028
-#define PCI_DEVICE_ID_TITAN_400I       0x8048
-#define PCI_DEVICE_ID_TITAN_800I       0x8088
-#define PCI_DEVICE_ID_TITAN_800EH      0xA007
-#define PCI_DEVICE_ID_TITAN_800EHB     0xA008
-#define PCI_DEVICE_ID_TITAN_400EH      0xA009
-#define PCI_DEVICE_ID_TITAN_100E       0xA010
-#define PCI_DEVICE_ID_TITAN_200E       0xA012
-#define PCI_DEVICE_ID_TITAN_400E       0xA013
-#define PCI_DEVICE_ID_TITAN_800E       0xA014
-#define PCI_DEVICE_ID_TITAN_200EI      0xA016
-#define PCI_DEVICE_ID_TITAN_200EISI    0xA017
-#define PCI_DEVICE_ID_TITAN_400V3      0xA310
-#define PCI_DEVICE_ID_TITAN_410V3      0xA312
-#define PCI_DEVICE_ID_TITAN_800V3      0xA314
-#define PCI_DEVICE_ID_TITAN_800V3B     0xA315
-#define PCI_DEVICE_ID_OXSEMI_16PCI958  0x9538
-#define PCIE_DEVICE_ID_NEO_2_OX_IBM    0x00F6
-#define PCI_DEVICE_ID_PLX_CRONYX_OMEGA 0xc001
-#define PCI_DEVICE_ID_INTEL_PATSBURG_KT 0x1d3d
-
-/* Unknown vendors/cards - this should not be in linux/pci_ids.h */
-#define PCI_SUBDEVICE_ID_UNKNOWN_0x1584        0x1584
-
-/*
- * Master list of serial port init/setup/exit quirks.
- * This does not describe the general nature of the port.
- * (ie, baud base, number and location of ports, etc)
- *
- * This list is ordered alphabetically by vendor then device.
- * Specific entries must come before more generic entries.
- */
-static struct pci_serial_quirk pci_serial_quirks[] __refdata = {
-       /*
-       * ADDI-DATA GmbH communication cards <info@addi-data.com>
-       */
-       {
-               .vendor         = PCI_VENDOR_ID_ADDIDATA_OLD,
-               .device         = PCI_DEVICE_ID_ADDIDATA_APCI7800,
-               .subvendor      = PCI_ANY_ID,
-               .subdevice      = PCI_ANY_ID,
-               .setup          = addidata_apci7800_setup,
-       },
-       /*
-        * AFAVLAB cards - these may be called via parport_serial
-        *  It is not clear whether this applies to all products.
-        */
-       {
-               .vendor         = PCI_VENDOR_ID_AFAVLAB,
-               .device         = PCI_ANY_ID,
-               .subvendor      = PCI_ANY_ID,
-               .subdevice      = PCI_ANY_ID,
-               .setup          = afavlab_setup,
-       },
-       /*
-        * HP Diva
-        */
-       {
-               .vendor         = PCI_VENDOR_ID_HP,
-               .device         = PCI_DEVICE_ID_HP_DIVA,
-               .subvendor      = PCI_ANY_ID,
-               .subdevice      = PCI_ANY_ID,
-               .init           = pci_hp_diva_init,
-               .setup          = pci_hp_diva_setup,
-       },
-       /*
-        * Intel
-        */
-       {
-               .vendor         = PCI_VENDOR_ID_INTEL,
-               .device         = PCI_DEVICE_ID_INTEL_80960_RP,
-               .subvendor      = 0xe4bf,
-               .subdevice      = PCI_ANY_ID,
-               .init           = pci_inteli960ni_init,
-               .setup          = pci_default_setup,
-       },
-       {
-               .vendor         = PCI_VENDOR_ID_INTEL,
-               .device         = PCI_DEVICE_ID_INTEL_8257X_SOL,
-               .subvendor      = PCI_ANY_ID,
-               .subdevice      = PCI_ANY_ID,
-               .setup          = skip_tx_en_setup,
-       },
-       {
-               .vendor         = PCI_VENDOR_ID_INTEL,
-               .device         = PCI_DEVICE_ID_INTEL_82573L_SOL,
-               .subvendor      = PCI_ANY_ID,
-               .subdevice      = PCI_ANY_ID,
-               .setup          = skip_tx_en_setup,
-       },
-       {
-               .vendor         = PCI_VENDOR_ID_INTEL,
-               .device         = PCI_DEVICE_ID_INTEL_82573E_SOL,
-               .subvendor      = PCI_ANY_ID,
-               .subdevice      = PCI_ANY_ID,
-               .setup          = skip_tx_en_setup,
-       },
-       {
-               .vendor         = PCI_VENDOR_ID_INTEL,
-               .device         = PCI_DEVICE_ID_INTEL_CE4100_UART,
-               .subvendor      = PCI_ANY_ID,
-               .subdevice      = PCI_ANY_ID,
-               .setup          = ce4100_serial_setup,
-       },
-       {
-               .vendor         = PCI_VENDOR_ID_INTEL,
-               .device         = PCI_DEVICE_ID_INTEL_PATSBURG_KT,
-               .subvendor      = PCI_ANY_ID,
-               .subdevice      = PCI_ANY_ID,
-               .init           = try_enable_msi,
-               .setup          = kt_serial_setup,
-               .exit           = disable_msi,
-       },
-       /*
-        * ITE
-        */
-       {
-               .vendor         = PCI_VENDOR_ID_ITE,
-               .device         = PCI_DEVICE_ID_ITE_8872,
-               .subvendor      = PCI_ANY_ID,
-               .subdevice      = PCI_ANY_ID,
-               .init           = pci_ite887x_init,
-               .setup          = pci_default_setup,
-               .exit           = __devexit_p(pci_ite887x_exit),
-       },
-       /*
-        * National Instruments
-        */
-       {
-               .vendor         = PCI_VENDOR_ID_NI,
-               .device         = PCI_DEVICE_ID_NI_PCI23216,
-               .subvendor      = PCI_ANY_ID,
-               .subdevice      = PCI_ANY_ID,
-               .init           = pci_ni8420_init,
-               .setup          = pci_default_setup,
-               .exit           = __devexit_p(pci_ni8420_exit),
-       },
-       {
-               .vendor         = PCI_VENDOR_ID_NI,
-               .device         = PCI_DEVICE_ID_NI_PCI2328,
-               .subvendor      = PCI_ANY_ID,
-               .subdevice      = PCI_ANY_ID,
-               .init           = pci_ni8420_init,
-               .setup          = pci_default_setup,
-               .exit           = __devexit_p(pci_ni8420_exit),
-       },
-       {
-               .vendor         = PCI_VENDOR_ID_NI,
-               .device         = PCI_DEVICE_ID_NI_PCI2324,
-               .subvendor      = PCI_ANY_ID,
-               .subdevice      = PCI_ANY_ID,
-               .init           = pci_ni8420_init,
-               .setup          = pci_default_setup,
-               .exit           = __devexit_p(pci_ni8420_exit),
-       },
-       {
-               .vendor         = PCI_VENDOR_ID_NI,
-               .device         = PCI_DEVICE_ID_NI_PCI2322,
-               .subvendor      = PCI_ANY_ID,
-               .subdevice      = PCI_ANY_ID,
-               .init           = pci_ni8420_init,
-               .setup          = pci_default_setup,
-               .exit           = __devexit_p(pci_ni8420_exit),
-       },
-       {
-               .vendor         = PCI_VENDOR_ID_NI,
-               .device         = PCI_DEVICE_ID_NI_PCI2324I,
-               .subvendor      = PCI_ANY_ID,
-               .subdevice      = PCI_ANY_ID,
-               .init           = pci_ni8420_init,
-               .setup          = pci_default_setup,
-               .exit           = __devexit_p(pci_ni8420_exit),
-       },
-       {
-               .vendor         = PCI_VENDOR_ID_NI,
-               .device         = PCI_DEVICE_ID_NI_PCI2322I,
-               .subvendor      = PCI_ANY_ID,
-               .subdevice      = PCI_ANY_ID,
-               .init           = pci_ni8420_init,
-               .setup          = pci_default_setup,
-               .exit           = __devexit_p(pci_ni8420_exit),
-       },
-       {
-               .vendor         = PCI_VENDOR_ID_NI,
-               .device         = PCI_DEVICE_ID_NI_PXI8420_23216,
-               .subvendor      = PCI_ANY_ID,
-               .subdevice      = PCI_ANY_ID,
-               .init           = pci_ni8420_init,
-               .setup          = pci_default_setup,
-               .exit           = __devexit_p(pci_ni8420_exit),
-       },
-       {
-               .vendor         = PCI_VENDOR_ID_NI,
-               .device         = PCI_DEVICE_ID_NI_PXI8420_2328,
-               .subvendor      = PCI_ANY_ID,
-               .subdevice      = PCI_ANY_ID,
-               .init           = pci_ni8420_init,
-               .setup          = pci_default_setup,
-               .exit           = __devexit_p(pci_ni8420_exit),
-       },
-       {
-               .vendor         = PCI_VENDOR_ID_NI,
-               .device         = PCI_DEVICE_ID_NI_PXI8420_2324,
-               .subvendor      = PCI_ANY_ID,
-               .subdevice      = PCI_ANY_ID,
-               .init           = pci_ni8420_init,
-               .setup          = pci_default_setup,
-               .exit           = __devexit_p(pci_ni8420_exit),
-       },
-       {
-               .vendor         = PCI_VENDOR_ID_NI,
-               .device         = PCI_DEVICE_ID_NI_PXI8420_2322,
-               .subvendor      = PCI_ANY_ID,
-               .subdevice      = PCI_ANY_ID,
-               .init           = pci_ni8420_init,
-               .setup          = pci_default_setup,
-               .exit           = __devexit_p(pci_ni8420_exit),
-       },
-       {
-               .vendor         = PCI_VENDOR_ID_NI,
-               .device         = PCI_DEVICE_ID_NI_PXI8422_2324,
-               .subvendor      = PCI_ANY_ID,
-               .subdevice      = PCI_ANY_ID,
-               .init           = pci_ni8420_init,
-               .setup          = pci_default_setup,
-               .exit           = __devexit_p(pci_ni8420_exit),
-       },
-       {
-               .vendor         = PCI_VENDOR_ID_NI,
-               .device         = PCI_DEVICE_ID_NI_PXI8422_2322,
-               .subvendor      = PCI_ANY_ID,
-               .subdevice      = PCI_ANY_ID,
-               .init           = pci_ni8420_init,
-               .setup          = pci_default_setup,
-               .exit           = __devexit_p(pci_ni8420_exit),
-       },
-       {
-               .vendor         = PCI_VENDOR_ID_NI,
-               .device         = PCI_ANY_ID,
-               .subvendor      = PCI_ANY_ID,
-               .subdevice      = PCI_ANY_ID,
-               .init           = pci_ni8430_init,
-               .setup          = pci_ni8430_setup,
-               .exit           = __devexit_p(pci_ni8430_exit),
-       },
-       /*
-        * Panacom
-        */
-       {
-               .vendor         = PCI_VENDOR_ID_PANACOM,
-               .device         = PCI_DEVICE_ID_PANACOM_QUADMODEM,
-               .subvendor      = PCI_ANY_ID,
-               .subdevice      = PCI_ANY_ID,
-               .init           = pci_plx9050_init,
-               .setup          = pci_default_setup,
-               .exit           = __devexit_p(pci_plx9050_exit),
-       },
-       {
-               .vendor         = PCI_VENDOR_ID_PANACOM,
-               .device         = PCI_DEVICE_ID_PANACOM_DUALMODEM,
-               .subvendor      = PCI_ANY_ID,
-               .subdevice      = PCI_ANY_ID,
-               .init           = pci_plx9050_init,
-               .setup          = pci_default_setup,
-               .exit           = __devexit_p(pci_plx9050_exit),
-       },
-       /*
-        * PLX
-        */
-       {
-               .vendor         = PCI_VENDOR_ID_PLX,
-               .device         = PCI_DEVICE_ID_PLX_9030,
-               .subvendor      = PCI_SUBVENDOR_ID_PERLE,
-               .subdevice      = PCI_ANY_ID,
-               .setup          = pci_default_setup,
-       },
-       {
-               .vendor         = PCI_VENDOR_ID_PLX,
-               .device         = PCI_DEVICE_ID_PLX_9050,
-               .subvendor      = PCI_SUBVENDOR_ID_EXSYS,
-               .subdevice      = PCI_SUBDEVICE_ID_EXSYS_4055,
-               .init           = pci_plx9050_init,
-               .setup          = pci_default_setup,
-               .exit           = __devexit_p(pci_plx9050_exit),
-       },
-       {
-               .vendor         = PCI_VENDOR_ID_PLX,
-               .device         = PCI_DEVICE_ID_PLX_9050,
-               .subvendor      = PCI_SUBVENDOR_ID_KEYSPAN,
-               .subdevice      = PCI_SUBDEVICE_ID_KEYSPAN_SX2,
-               .init           = pci_plx9050_init,
-               .setup          = pci_default_setup,
-               .exit           = __devexit_p(pci_plx9050_exit),
-       },
-       {
-               .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           = __devexit_p(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,
-               .init           = pci_plx9050_init,
-               .setup          = pci_default_setup,
-               .exit           = __devexit_p(pci_plx9050_exit),
-       },
-       /*
-        * SBS Technologies, Inc., PMC-OCTALPRO 232
-        */
-       {
-               .vendor         = PCI_VENDOR_ID_SBSMODULARIO,
-               .device         = PCI_DEVICE_ID_OCTPRO,
-               .subvendor      = PCI_SUBVENDOR_ID_SBSMODULARIO,
-               .subdevice      = PCI_SUBDEVICE_ID_OCTPRO232,
-               .init           = sbs_init,
-               .setup          = sbs_setup,
-               .exit           = __devexit_p(sbs_exit),
-       },
-       /*
-        * SBS Technologies, Inc., PMC-OCTALPRO 422
-        */
-       {
-               .vendor         = PCI_VENDOR_ID_SBSMODULARIO,
-               .device         = PCI_DEVICE_ID_OCTPRO,
-               .subvendor      = PCI_SUBVENDOR_ID_SBSMODULARIO,
-               .subdevice      = PCI_SUBDEVICE_ID_OCTPRO422,
-               .init           = sbs_init,
-               .setup          = sbs_setup,
-               .exit           = __devexit_p(sbs_exit),
-       },
-       /*
-        * SBS Technologies, Inc., P-Octal 232
-        */
-       {
-               .vendor         = PCI_VENDOR_ID_SBSMODULARIO,
-               .device         = PCI_DEVICE_ID_OCTPRO,
-               .subvendor      = PCI_SUBVENDOR_ID_SBSMODULARIO,
-               .subdevice      = PCI_SUBDEVICE_ID_POCTAL232,
-               .init           = sbs_init,
-               .setup          = sbs_setup,
-               .exit           = __devexit_p(sbs_exit),
-       },
-       /*
-        * SBS Technologies, Inc., P-Octal 422
-        */
-       {
-               .vendor         = PCI_VENDOR_ID_SBSMODULARIO,
-               .device         = PCI_DEVICE_ID_OCTPRO,
-               .subvendor      = PCI_SUBVENDOR_ID_SBSMODULARIO,
-               .subdevice      = PCI_SUBDEVICE_ID_POCTAL422,
-               .init           = sbs_init,
-               .setup          = sbs_setup,
-               .exit           = __devexit_p(sbs_exit),
-       },
-       /*
-        * SIIG cards - these may be called via parport_serial
-        */
-       {
-               .vendor         = PCI_VENDOR_ID_SIIG,
-               .device         = PCI_ANY_ID,
-               .subvendor      = PCI_ANY_ID,
-               .subdevice      = PCI_ANY_ID,
-               .init           = pci_siig_init,
-               .setup          = pci_siig_setup,
-       },
-       /*
-        * Titan cards
-        */
-       {
-               .vendor         = PCI_VENDOR_ID_TITAN,
-               .device         = PCI_DEVICE_ID_TITAN_400L,
-               .subvendor      = PCI_ANY_ID,
-               .subdevice      = PCI_ANY_ID,
-               .setup          = titan_400l_800l_setup,
-       },
-       {
-               .vendor         = PCI_VENDOR_ID_TITAN,
-               .device         = PCI_DEVICE_ID_TITAN_800L,
-               .subvendor      = PCI_ANY_ID,
-               .subdevice      = PCI_ANY_ID,
-               .setup          = titan_400l_800l_setup,
-       },
-       /*
-        * Timedia cards
-        */
-       {
-               .vendor         = PCI_VENDOR_ID_TIMEDIA,
-               .device         = PCI_DEVICE_ID_TIMEDIA_1889,
-               .subvendor      = PCI_VENDOR_ID_TIMEDIA,
-               .subdevice      = PCI_ANY_ID,
-               .probe          = pci_timedia_probe,
-               .init           = pci_timedia_init,
-               .setup          = pci_timedia_setup,
-       },
-       {
-               .vendor         = PCI_VENDOR_ID_TIMEDIA,
-               .device         = PCI_ANY_ID,
-               .subvendor      = PCI_ANY_ID,
-               .subdevice      = PCI_ANY_ID,
-               .setup          = pci_timedia_setup,
-       },
-       /*
-        * Exar cards
-        */
-       {
-               .vendor = PCI_VENDOR_ID_EXAR,
-               .device = PCI_DEVICE_ID_EXAR_XR17C152,
-               .subvendor      = PCI_ANY_ID,
-               .subdevice      = PCI_ANY_ID,
-               .setup          = pci_xr17c154_setup,
-       },
-       {
-               .vendor = PCI_VENDOR_ID_EXAR,
-               .device = PCI_DEVICE_ID_EXAR_XR17C154,
-               .subvendor      = PCI_ANY_ID,
-               .subdevice      = PCI_ANY_ID,
-               .setup          = pci_xr17c154_setup,
-       },
-       {
-               .vendor = PCI_VENDOR_ID_EXAR,
-               .device = PCI_DEVICE_ID_EXAR_XR17C158,
-               .subvendor      = PCI_ANY_ID,
-               .subdevice      = PCI_ANY_ID,
-               .setup          = pci_xr17c154_setup,
-       },
-       /*
-        * Xircom cards
-        */
-       {
-               .vendor         = PCI_VENDOR_ID_XIRCOM,
-               .device         = PCI_DEVICE_ID_XIRCOM_X3201_MDM,
-               .subvendor      = PCI_ANY_ID,
-               .subdevice      = PCI_ANY_ID,
-               .init           = pci_xircom_init,
-               .setup          = pci_default_setup,
-       },
-       /*
-        * Netmos cards - these may be called via parport_serial
-        */
-       {
-               .vendor         = PCI_VENDOR_ID_NETMOS,
-               .device         = PCI_ANY_ID,
-               .subvendor      = PCI_ANY_ID,
-               .subdevice      = PCI_ANY_ID,
-               .init           = pci_netmos_init,
-               .setup          = pci_netmos_9900_setup,
-       },
-       /*
-        * For Oxford Semiconductor Tornado based devices
-        */
-       {
-               .vendor         = PCI_VENDOR_ID_OXSEMI,
-               .device         = PCI_ANY_ID,
-               .subvendor      = PCI_ANY_ID,
-               .subdevice      = PCI_ANY_ID,
-               .init           = pci_oxsemi_tornado_init,
-               .setup          = pci_default_setup,
-       },
-       {
-               .vendor         = PCI_VENDOR_ID_MAINPINE,
-               .device         = PCI_ANY_ID,
-               .subvendor      = PCI_ANY_ID,
-               .subdevice      = PCI_ANY_ID,
-               .init           = pci_oxsemi_tornado_init,
-               .setup          = pci_default_setup,
-       },
-       {
-               .vendor         = PCI_VENDOR_ID_DIGI,
-               .device         = PCIE_DEVICE_ID_NEO_2_OX_IBM,
-               .subvendor              = PCI_SUBVENDOR_ID_IBM,
-               .subdevice              = PCI_ANY_ID,
-               .init                   = pci_oxsemi_tornado_init,
-               .setup          = pci_default_setup,
-       },
-       {
-               .vendor         = PCI_VENDOR_ID_INTEL,
-               .device         = 0x8811,
-               .init           = pci_eg20t_init,
-               .setup          = pci_default_setup,
-       },
-       {
-               .vendor         = PCI_VENDOR_ID_INTEL,
-               .device         = 0x8812,
-               .init           = pci_eg20t_init,
-               .setup          = pci_default_setup,
-       },
-       {
-               .vendor         = PCI_VENDOR_ID_INTEL,
-               .device         = 0x8813,
-               .init           = pci_eg20t_init,
-               .setup          = pci_default_setup,
-       },
-       {
-               .vendor         = PCI_VENDOR_ID_INTEL,
-               .device         = 0x8814,
-               .init           = pci_eg20t_init,
-               .setup          = pci_default_setup,
-       },
-       {
-               .vendor         = 0x10DB,
-               .device         = 0x8027,
-               .init           = pci_eg20t_init,
-               .setup          = pci_default_setup,
-       },
-       {
-               .vendor         = 0x10DB,
-               .device         = 0x8028,
-               .init           = pci_eg20t_init,
-               .setup          = pci_default_setup,
-       },
-       {
-               .vendor         = 0x10DB,
-               .device         = 0x8029,
-               .init           = pci_eg20t_init,
-               .setup          = pci_default_setup,
-       },
-       {
-               .vendor         = 0x10DB,
-               .device         = 0x800C,
-               .init           = pci_eg20t_init,
-               .setup          = pci_default_setup,
-       },
-       {
-               .vendor         = 0x10DB,
-               .device         = 0x800D,
-               .init           = pci_eg20t_init,
-               .setup          = pci_default_setup,
-       },
-       /*
-        * Cronyx Omega PCI (PLX-chip based)
-        */
-       {
-               .vendor         = PCI_VENDOR_ID_PLX,
-               .device         = PCI_DEVICE_ID_PLX_CRONYX_OMEGA,
-               .subvendor      = PCI_ANY_ID,
-               .subdevice      = PCI_ANY_ID,
-               .setup          = pci_omegapci_setup,
-        },
-       /*
-        * Default "match everything" terminator entry
-        */
-       {
-               .vendor         = PCI_ANY_ID,
-               .device         = PCI_ANY_ID,
-               .subvendor      = PCI_ANY_ID,
-               .subdevice      = PCI_ANY_ID,
-               .setup          = pci_default_setup,
-       }
-};
-
-static inline int quirk_id_matches(u32 quirk_id, u32 dev_id)
-{
-       return quirk_id == PCI_ANY_ID || quirk_id == dev_id;
-}
-
-static struct pci_serial_quirk *find_quirk(struct pci_dev *dev)
-{
-       struct pci_serial_quirk *quirk;
-
-       for (quirk = pci_serial_quirks; ; quirk++)
-               if (quirk_id_matches(quirk->vendor, dev->vendor) &&
-                   quirk_id_matches(quirk->device, dev->device) &&
-                   quirk_id_matches(quirk->subvendor, dev->subsystem_vendor) &&
-                   quirk_id_matches(quirk->subdevice, dev->subsystem_device))
-                       break;
-       return quirk;
-}
-
-static inline int get_pci_irq(struct pci_dev *dev,
-                               const struct pciserial_board *board)
-{
-       if (board->flags & FL_NOIRQ)
-               return 0;
-       else
-               return dev->irq;
-}
-
-/*
- * This is the configuration table for all of the PCI serial boards
- * which we support.  It is directly indexed by the pci_board_num_t enum
- * value, which is encoded in the pci_device_id PCI probe table's
- * driver_data member.
- *
- * The makeup of these names are:
- *  pbn_bn{_bt}_n_baud{_offsetinhex}
- *
- *  bn         = PCI BAR number
- *  bt         = Index using PCI BARs
- *  n          = number of serial ports
- *  baud       = baud rate
- *  offsetinhex        = offset for each sequential port (in hex)
- *
- * This table is sorted by (in order): bn, bt, baud, offsetindex, n.
- *
- * Please note: in theory if n = 1, _bt infix should make no difference.
- * ie, pbn_b0_1_115200 is the same as pbn_b0_bt_1_115200
- */
-enum pci_board_num_t {
-       pbn_default = 0,
-
-       pbn_b0_1_115200,
-       pbn_b0_2_115200,
-       pbn_b0_4_115200,
-       pbn_b0_5_115200,
-       pbn_b0_8_115200,
-
-       pbn_b0_1_921600,
-       pbn_b0_2_921600,
-       pbn_b0_4_921600,
-
-       pbn_b0_2_1130000,
-
-       pbn_b0_4_1152000,
-
-       pbn_b0_2_1843200,
-       pbn_b0_4_1843200,
-
-       pbn_b0_2_1843200_200,
-       pbn_b0_4_1843200_200,
-       pbn_b0_8_1843200_200,
-
-       pbn_b0_1_4000000,
-
-       pbn_b0_bt_1_115200,
-       pbn_b0_bt_2_115200,
-       pbn_b0_bt_4_115200,
-       pbn_b0_bt_8_115200,
-
-       pbn_b0_bt_1_460800,
-       pbn_b0_bt_2_460800,
-       pbn_b0_bt_4_460800,
-
-       pbn_b0_bt_1_921600,
-       pbn_b0_bt_2_921600,
-       pbn_b0_bt_4_921600,
-       pbn_b0_bt_8_921600,
-
-       pbn_b1_1_115200,
-       pbn_b1_2_115200,
-       pbn_b1_4_115200,
-       pbn_b1_8_115200,
-       pbn_b1_16_115200,
-
-       pbn_b1_1_921600,
-       pbn_b1_2_921600,
-       pbn_b1_4_921600,
-       pbn_b1_8_921600,
-
-       pbn_b1_2_1250000,
-
-       pbn_b1_bt_1_115200,
-       pbn_b1_bt_2_115200,
-       pbn_b1_bt_4_115200,
-
-       pbn_b1_bt_2_921600,
-
-       pbn_b1_1_1382400,
-       pbn_b1_2_1382400,
-       pbn_b1_4_1382400,
-       pbn_b1_8_1382400,
-
-       pbn_b2_1_115200,
-       pbn_b2_2_115200,
-       pbn_b2_4_115200,
-       pbn_b2_8_115200,
-
-       pbn_b2_1_460800,
-       pbn_b2_4_460800,
-       pbn_b2_8_460800,
-       pbn_b2_16_460800,
-
-       pbn_b2_1_921600,
-       pbn_b2_4_921600,
-       pbn_b2_8_921600,
-
-       pbn_b2_8_1152000,
-
-       pbn_b2_bt_1_115200,
-       pbn_b2_bt_2_115200,
-       pbn_b2_bt_4_115200,
-
-       pbn_b2_bt_2_921600,
-       pbn_b2_bt_4_921600,
-
-       pbn_b3_2_115200,
-       pbn_b3_4_115200,
-       pbn_b3_8_115200,
-
-       pbn_b4_bt_2_921600,
-       pbn_b4_bt_4_921600,
-       pbn_b4_bt_8_921600,
-
-       /*
-        * Board-specific versions.
-        */
-       pbn_panacom,
-       pbn_panacom2,
-       pbn_panacom4,
-       pbn_exsys_4055,
-       pbn_plx_romulus,
-       pbn_oxsemi,
-       pbn_oxsemi_1_4000000,
-       pbn_oxsemi_2_4000000,
-       pbn_oxsemi_4_4000000,
-       pbn_oxsemi_8_4000000,
-       pbn_intel_i960,
-       pbn_sgi_ioc3,
-       pbn_computone_4,
-       pbn_computone_6,
-       pbn_computone_8,
-       pbn_sbsxrsio,
-       pbn_exar_XR17C152,
-       pbn_exar_XR17C154,
-       pbn_exar_XR17C158,
-       pbn_exar_ibm_saturn,
-       pbn_pasemi_1682M,
-       pbn_ni8430_2,
-       pbn_ni8430_4,
-       pbn_ni8430_8,
-       pbn_ni8430_16,
-       pbn_ADDIDATA_PCIe_1_3906250,
-       pbn_ADDIDATA_PCIe_2_3906250,
-       pbn_ADDIDATA_PCIe_4_3906250,
-       pbn_ADDIDATA_PCIe_8_3906250,
-       pbn_ce4100_1_115200,
-       pbn_omegapci,
-       pbn_NETMOS9900_2s_115200,
-};
-
-/*
- * uart_offset - the space between channels
- * reg_shift   - describes how the UART registers are mapped
- *               to PCI memory by the card.
- * For example IER register on SBS, Inc. PMC-OctPro is located at
- * offset 0x10 from the UART base, while UART_IER is defined as 1
- * in include/linux/serial_reg.h,
- * see first lines of serial_in() and serial_out() in 8250.c
-*/
-
-static struct pciserial_board pci_boards[] __devinitdata = {
-       [pbn_default] = {
-               .flags          = FL_BASE0,
-               .num_ports      = 1,
-               .base_baud      = 115200,
-               .uart_offset    = 8,
-       },
-       [pbn_b0_1_115200] = {
-               .flags          = FL_BASE0,
-               .num_ports      = 1,
-               .base_baud      = 115200,
-               .uart_offset    = 8,
-       },
-       [pbn_b0_2_115200] = {
-               .flags          = FL_BASE0,
-               .num_ports      = 2,
-               .base_baud      = 115200,
-               .uart_offset    = 8,
-       },
-       [pbn_b0_4_115200] = {
-               .flags          = FL_BASE0,
-               .num_ports      = 4,
-               .base_baud      = 115200,
-               .uart_offset    = 8,
-       },
-       [pbn_b0_5_115200] = {
-               .flags          = FL_BASE0,
-               .num_ports      = 5,
-               .base_baud      = 115200,
-               .uart_offset    = 8,
-       },
-       [pbn_b0_8_115200] = {
-               .flags          = FL_BASE0,
-               .num_ports      = 8,
-               .base_baud      = 115200,
-               .uart_offset    = 8,
-       },
-       [pbn_b0_1_921600] = {
-               .flags          = FL_BASE0,
-               .num_ports      = 1,
-               .base_baud      = 921600,
-               .uart_offset    = 8,
-       },
-       [pbn_b0_2_921600] = {
-               .flags          = FL_BASE0,
-               .num_ports      = 2,
-               .base_baud      = 921600,
-               .uart_offset    = 8,
-       },
-       [pbn_b0_4_921600] = {
-               .flags          = FL_BASE0,
-               .num_ports      = 4,
-               .base_baud      = 921600,
-               .uart_offset    = 8,
-       },
-
-       [pbn_b0_2_1130000] = {
-               .flags          = FL_BASE0,
-               .num_ports      = 2,
-               .base_baud      = 1130000,
-               .uart_offset    = 8,
-       },
-
-       [pbn_b0_4_1152000] = {
-               .flags          = FL_BASE0,
-               .num_ports      = 4,
-               .base_baud      = 1152000,
-               .uart_offset    = 8,
-       },
-
-       [pbn_b0_2_1843200] = {
-               .flags          = FL_BASE0,
-               .num_ports      = 2,
-               .base_baud      = 1843200,
-               .uart_offset    = 8,
-       },
-       [pbn_b0_4_1843200] = {
-               .flags          = FL_BASE0,
-               .num_ports      = 4,
-               .base_baud      = 1843200,
-               .uart_offset    = 8,
-       },
-
-       [pbn_b0_2_1843200_200] = {
-               .flags          = FL_BASE0,
-               .num_ports      = 2,
-               .base_baud      = 1843200,
-               .uart_offset    = 0x200,
-       },
-       [pbn_b0_4_1843200_200] = {
-               .flags          = FL_BASE0,
-               .num_ports      = 4,
-               .base_baud      = 1843200,
-               .uart_offset    = 0x200,
-       },
-       [pbn_b0_8_1843200_200] = {
-               .flags          = FL_BASE0,
-               .num_ports      = 8,
-               .base_baud      = 1843200,
-               .uart_offset    = 0x200,
-       },
-       [pbn_b0_1_4000000] = {
-               .flags          = FL_BASE0,
-               .num_ports      = 1,
-               .base_baud      = 4000000,
-               .uart_offset    = 8,
-       },
-
-       [pbn_b0_bt_1_115200] = {
-               .flags          = FL_BASE0|FL_BASE_BARS,
-               .num_ports      = 1,
-               .base_baud      = 115200,
-               .uart_offset    = 8,
-       },
-       [pbn_b0_bt_2_115200] = {
-               .flags          = FL_BASE0|FL_BASE_BARS,
-               .num_ports      = 2,
-               .base_baud      = 115200,
-               .uart_offset    = 8,
-       },
-       [pbn_b0_bt_4_115200] = {
-               .flags          = FL_BASE0|FL_BASE_BARS,
-               .num_ports      = 4,
-               .base_baud      = 115200,
-               .uart_offset    = 8,
-       },
-       [pbn_b0_bt_8_115200] = {
-               .flags          = FL_BASE0|FL_BASE_BARS,
-               .num_ports      = 8,
-               .base_baud      = 115200,
-               .uart_offset    = 8,
-       },
-
-       [pbn_b0_bt_1_460800] = {
-               .flags          = FL_BASE0|FL_BASE_BARS,
-               .num_ports      = 1,
-               .base_baud      = 460800,
-               .uart_offset    = 8,
-       },
-       [pbn_b0_bt_2_460800] = {
-               .flags          = FL_BASE0|FL_BASE_BARS,
-               .num_ports      = 2,
-               .base_baud      = 460800,
-               .uart_offset    = 8,
-       },
-       [pbn_b0_bt_4_460800] = {
-               .flags          = FL_BASE0|FL_BASE_BARS,
-               .num_ports      = 4,
-               .base_baud      = 460800,
-               .uart_offset    = 8,
-       },
-
-       [pbn_b0_bt_1_921600] = {
-               .flags          = FL_BASE0|FL_BASE_BARS,
-               .num_ports      = 1,
-               .base_baud      = 921600,
-               .uart_offset    = 8,
-       },
-       [pbn_b0_bt_2_921600] = {
-               .flags          = FL_BASE0|FL_BASE_BARS,
-               .num_ports      = 2,
-               .base_baud      = 921600,
-               .uart_offset    = 8,
-       },
-       [pbn_b0_bt_4_921600] = {
-               .flags          = FL_BASE0|FL_BASE_BARS,
-               .num_ports      = 4,
-               .base_baud      = 921600,
-               .uart_offset    = 8,
-       },
-       [pbn_b0_bt_8_921600] = {
-               .flags          = FL_BASE0|FL_BASE_BARS,
-               .num_ports      = 8,
-               .base_baud      = 921600,
-               .uart_offset    = 8,
-       },
-
-       [pbn_b1_1_115200] = {
-               .flags          = FL_BASE1,
-               .num_ports      = 1,
-               .base_baud      = 115200,
-               .uart_offset    = 8,
-       },
-       [pbn_b1_2_115200] = {
-               .flags          = FL_BASE1,
-               .num_ports      = 2,
-               .base_baud      = 115200,
-               .uart_offset    = 8,
-       },
-       [pbn_b1_4_115200] = {
-               .flags          = FL_BASE1,
-               .num_ports      = 4,
-               .base_baud      = 115200,
-               .uart_offset    = 8,
-       },
-       [pbn_b1_8_115200] = {
-               .flags          = FL_BASE1,
-               .num_ports      = 8,
-               .base_baud      = 115200,
-               .uart_offset    = 8,
-       },
-       [pbn_b1_16_115200] = {
-               .flags          = FL_BASE1,
-               .num_ports      = 16,
-               .base_baud      = 115200,
-               .uart_offset    = 8,
-       },
-
-       [pbn_b1_1_921600] = {
-               .flags          = FL_BASE1,
-               .num_ports      = 1,
-               .base_baud      = 921600,
-               .uart_offset    = 8,
-       },
-       [pbn_b1_2_921600] = {
-               .flags          = FL_BASE1,
-               .num_ports      = 2,
-               .base_baud      = 921600,
-               .uart_offset    = 8,
-       },
-       [pbn_b1_4_921600] = {
-               .flags          = FL_BASE1,
-               .num_ports      = 4,
-               .base_baud      = 921600,
-               .uart_offset    = 8,
-       },
-       [pbn_b1_8_921600] = {
-               .flags          = FL_BASE1,
-               .num_ports      = 8,
-               .base_baud      = 921600,
-               .uart_offset    = 8,
-       },
-       [pbn_b1_2_1250000] = {
-               .flags          = FL_BASE1,
-               .num_ports      = 2,
-               .base_baud      = 1250000,
-               .uart_offset    = 8,
-       },
-
-       [pbn_b1_bt_1_115200] = {
-               .flags          = FL_BASE1|FL_BASE_BARS,
-               .num_ports      = 1,
-               .base_baud      = 115200,
-               .uart_offset    = 8,
-       },
-       [pbn_b1_bt_2_115200] = {
-               .flags          = FL_BASE1|FL_BASE_BARS,
-               .num_ports      = 2,
-               .base_baud      = 115200,
-               .uart_offset    = 8,
-       },
-       [pbn_b1_bt_4_115200] = {
-               .flags          = FL_BASE1|FL_BASE_BARS,
-               .num_ports      = 4,
-               .base_baud      = 115200,
-               .uart_offset    = 8,
-       },
-
-       [pbn_b1_bt_2_921600] = {
-               .flags          = FL_BASE1|FL_BASE_BARS,
-               .num_ports      = 2,
-               .base_baud      = 921600,
-               .uart_offset    = 8,
-       },
-
-       [pbn_b1_1_1382400] = {
-               .flags          = FL_BASE1,
-               .num_ports      = 1,
-               .base_baud      = 1382400,
-               .uart_offset    = 8,
-       },
-       [pbn_b1_2_1382400] = {
-               .flags          = FL_BASE1,
-               .num_ports      = 2,
-               .base_baud      = 1382400,
-               .uart_offset    = 8,
-       },
-       [pbn_b1_4_1382400] = {
-               .flags          = FL_BASE1,
-               .num_ports      = 4,
-               .base_baud      = 1382400,
-               .uart_offset    = 8,
-       },
-       [pbn_b1_8_1382400] = {
-               .flags          = FL_BASE1,
-               .num_ports      = 8,
-               .base_baud      = 1382400,
-               .uart_offset    = 8,
-       },
-
-       [pbn_b2_1_115200] = {
-               .flags          = FL_BASE2,
-               .num_ports      = 1,
-               .base_baud      = 115200,
-               .uart_offset    = 8,
-       },
-       [pbn_b2_2_115200] = {
-               .flags          = FL_BASE2,
-               .num_ports      = 2,
-               .base_baud      = 115200,
-               .uart_offset    = 8,
-       },
-       [pbn_b2_4_115200] = {
-               .flags          = FL_BASE2,
-               .num_ports      = 4,
-               .base_baud      = 115200,
-               .uart_offset    = 8,
-       },
-       [pbn_b2_8_115200] = {
-               .flags          = FL_BASE2,
-               .num_ports      = 8,
-               .base_baud      = 115200,
-               .uart_offset    = 8,
-       },
-
-       [pbn_b2_1_460800] = {
-               .flags          = FL_BASE2,
-               .num_ports      = 1,
-               .base_baud      = 460800,
-               .uart_offset    = 8,
-       },
-       [pbn_b2_4_460800] = {
-               .flags          = FL_BASE2,
-               .num_ports      = 4,
-               .base_baud      = 460800,
-               .uart_offset    = 8,
-       },
-       [pbn_b2_8_460800] = {
-               .flags          = FL_BASE2,
-               .num_ports      = 8,
-               .base_baud      = 460800,
-               .uart_offset    = 8,
-       },
-       [pbn_b2_16_460800] = {
-               .flags          = FL_BASE2,
-               .num_ports      = 16,
-               .base_baud      = 460800,
-               .uart_offset    = 8,
-        },
-
-       [pbn_b2_1_921600] = {
-               .flags          = FL_BASE2,
-               .num_ports      = 1,
-               .base_baud      = 921600,
-               .uart_offset    = 8,
-       },
-       [pbn_b2_4_921600] = {
-               .flags          = FL_BASE2,
-               .num_ports      = 4,
-               .base_baud      = 921600,
-               .uart_offset    = 8,
-       },
-       [pbn_b2_8_921600] = {
-               .flags          = FL_BASE2,
-               .num_ports      = 8,
-               .base_baud      = 921600,
-               .uart_offset    = 8,
-       },
-
-       [pbn_b2_8_1152000] = {
-               .flags          = FL_BASE2,
-               .num_ports      = 8,
-               .base_baud      = 1152000,
-               .uart_offset    = 8,
-       },
-
-       [pbn_b2_bt_1_115200] = {
-               .flags          = FL_BASE2|FL_BASE_BARS,
-               .num_ports      = 1,
-               .base_baud      = 115200,
-               .uart_offset    = 8,
-       },
-       [pbn_b2_bt_2_115200] = {
-               .flags          = FL_BASE2|FL_BASE_BARS,
-               .num_ports      = 2,
-               .base_baud      = 115200,
-               .uart_offset    = 8,
-       },
-       [pbn_b2_bt_4_115200] = {
-               .flags          = FL_BASE2|FL_BASE_BARS,
-               .num_ports      = 4,
-               .base_baud      = 115200,
-               .uart_offset    = 8,
-       },
-
-       [pbn_b2_bt_2_921600] = {
-               .flags          = FL_BASE2|FL_BASE_BARS,
-               .num_ports      = 2,
-               .base_baud      = 921600,
-               .uart_offset    = 8,
-       },
-       [pbn_b2_bt_4_921600] = {
-               .flags          = FL_BASE2|FL_BASE_BARS,
-               .num_ports      = 4,
-               .base_baud      = 921600,
-               .uart_offset    = 8,
-       },
-
-       [pbn_b3_2_115200] = {
-               .flags          = FL_BASE3,
-               .num_ports      = 2,
-               .base_baud      = 115200,
-               .uart_offset    = 8,
-       },
-       [pbn_b3_4_115200] = {
-               .flags          = FL_BASE3,
-               .num_ports      = 4,
-               .base_baud      = 115200,
-               .uart_offset    = 8,
-       },
-       [pbn_b3_8_115200] = {
-               .flags          = FL_BASE3,
-               .num_ports      = 8,
-               .base_baud      = 115200,
-               .uart_offset    = 8,
-       },
-
-       [pbn_b4_bt_2_921600] = {
-               .flags          = FL_BASE4,
-               .num_ports      = 2,
-               .base_baud      = 921600,
-               .uart_offset    = 8,
-       },
-       [pbn_b4_bt_4_921600] = {
-               .flags          = FL_BASE4,
-               .num_ports      = 4,
-               .base_baud      = 921600,
-               .uart_offset    = 8,
-       },
-       [pbn_b4_bt_8_921600] = {
-               .flags          = FL_BASE4,
-               .num_ports      = 8,
-               .base_baud      = 921600,
-               .uart_offset    = 8,
-       },
-
-       /*
-        * Entries following this are board-specific.
-        */
-
-       /*
-        * Panacom - IOMEM
-        */
-       [pbn_panacom] = {
-               .flags          = FL_BASE2,
-               .num_ports      = 2,
-               .base_baud      = 921600,
-               .uart_offset    = 0x400,
-               .reg_shift      = 7,
-       },
-       [pbn_panacom2] = {
-               .flags          = FL_BASE2|FL_BASE_BARS,
-               .num_ports      = 2,
-               .base_baud      = 921600,
-               .uart_offset    = 0x400,
-               .reg_shift      = 7,
-       },
-       [pbn_panacom4] = {
-               .flags          = FL_BASE2|FL_BASE_BARS,
-               .num_ports      = 4,
-               .base_baud      = 921600,
-               .uart_offset    = 0x400,
-               .reg_shift      = 7,
-       },
-
-       [pbn_exsys_4055] = {
-               .flags          = FL_BASE2,
-               .num_ports      = 4,
-               .base_baud      = 115200,
-               .uart_offset    = 8,
-       },
-
-       /* I think this entry is broken - the first_offset looks wrong --rmk */
-       [pbn_plx_romulus] = {
-               .flags          = FL_BASE2,
-               .num_ports      = 4,
-               .base_baud      = 921600,
-               .uart_offset    = 8 << 2,
-               .reg_shift      = 2,
-               .first_offset   = 0x03,
-       },
-
-       /*
-        * This board uses the size of PCI Base region 0 to
-        * signal now many ports are available
-        */
-       [pbn_oxsemi] = {
-               .flags          = FL_BASE0|FL_REGION_SZ_CAP,
-               .num_ports      = 32,
-               .base_baud      = 115200,
-               .uart_offset    = 8,
-       },
-       [pbn_oxsemi_1_4000000] = {
-               .flags          = FL_BASE0,
-               .num_ports      = 1,
-               .base_baud      = 4000000,
-               .uart_offset    = 0x200,
-               .first_offset   = 0x1000,
-       },
-       [pbn_oxsemi_2_4000000] = {
-               .flags          = FL_BASE0,
-               .num_ports      = 2,
-               .base_baud      = 4000000,
-               .uart_offset    = 0x200,
-               .first_offset   = 0x1000,
-       },
-       [pbn_oxsemi_4_4000000] = {
-               .flags          = FL_BASE0,
-               .num_ports      = 4,
-               .base_baud      = 4000000,
-               .uart_offset    = 0x200,
-               .first_offset   = 0x1000,
-       },
-       [pbn_oxsemi_8_4000000] = {
-               .flags          = FL_BASE0,
-               .num_ports      = 8,
-               .base_baud      = 4000000,
-               .uart_offset    = 0x200,
-               .first_offset   = 0x1000,
-       },
-
-
-       /*
-        * EKF addition for i960 Boards form EKF with serial port.
-        * Max 256 ports.
-        */
-       [pbn_intel_i960] = {
-               .flags          = FL_BASE0,
-               .num_ports      = 32,
-               .base_baud      = 921600,
-               .uart_offset    = 8 << 2,
-               .reg_shift      = 2,
-               .first_offset   = 0x10000,
-       },
-       [pbn_sgi_ioc3] = {
-               .flags          = FL_BASE0|FL_NOIRQ,
-               .num_ports      = 1,
-               .base_baud      = 458333,
-               .uart_offset    = 8,
-               .reg_shift      = 0,
-               .first_offset   = 0x20178,
-       },
-
-       /*
-        * Computone - uses IOMEM.
-        */
-       [pbn_computone_4] = {
-               .flags          = FL_BASE0,
-               .num_ports      = 4,
-               .base_baud      = 921600,
-               .uart_offset    = 0x40,
-               .reg_shift      = 2,
-               .first_offset   = 0x200,
-       },
-       [pbn_computone_6] = {
-               .flags          = FL_BASE0,
-               .num_ports      = 6,
-               .base_baud      = 921600,
-               .uart_offset    = 0x40,
-               .reg_shift      = 2,
-               .first_offset   = 0x200,
-       },
-       [pbn_computone_8] = {
-               .flags          = FL_BASE0,
-               .num_ports      = 8,
-               .base_baud      = 921600,
-               .uart_offset    = 0x40,
-               .reg_shift      = 2,
-               .first_offset   = 0x200,
-       },
-       [pbn_sbsxrsio] = {
-               .flags          = FL_BASE0,
-               .num_ports      = 8,
-               .base_baud      = 460800,
-               .uart_offset    = 256,
-               .reg_shift      = 4,
-       },
-       /*
-        * Exar Corp. XR17C15[248] Dual/Quad/Octal UART
-        *  Only basic 16550A support.
-        *  XR17C15[24] are not tested, but they should work.
-        */
-       [pbn_exar_XR17C152] = {
-               .flags          = FL_BASE0,
-               .num_ports      = 2,
-               .base_baud      = 921600,
-               .uart_offset    = 0x200,
-       },
-       [pbn_exar_XR17C154] = {
-               .flags          = FL_BASE0,
-               .num_ports      = 4,
-               .base_baud      = 921600,
-               .uart_offset    = 0x200,
-       },
-       [pbn_exar_XR17C158] = {
-               .flags          = FL_BASE0,
-               .num_ports      = 8,
-               .base_baud      = 921600,
-               .uart_offset    = 0x200,
-       },
-       [pbn_exar_ibm_saturn] = {
-               .flags          = FL_BASE0,
-               .num_ports      = 1,
-               .base_baud      = 921600,
-               .uart_offset    = 0x200,
-       },
-
-       /*
-        * PA Semi PWRficient PA6T-1682M on-chip UART
-        */
-       [pbn_pasemi_1682M] = {
-               .flags          = FL_BASE0,
-               .num_ports      = 1,
-               .base_baud      = 8333333,
-       },
-       /*
-        * National Instruments 843x
-        */
-       [pbn_ni8430_16] = {
-               .flags          = FL_BASE0,
-               .num_ports      = 16,
-               .base_baud      = 3686400,
-               .uart_offset    = 0x10,
-               .first_offset   = 0x800,
-       },
-       [pbn_ni8430_8] = {
-               .flags          = FL_BASE0,
-               .num_ports      = 8,
-               .base_baud      = 3686400,
-               .uart_offset    = 0x10,
-               .first_offset   = 0x800,
-       },
-       [pbn_ni8430_4] = {
-               .flags          = FL_BASE0,
-               .num_ports      = 4,
-               .base_baud      = 3686400,
-               .uart_offset    = 0x10,
-               .first_offset   = 0x800,
-       },
-       [pbn_ni8430_2] = {
-               .flags          = FL_BASE0,
-               .num_ports      = 2,
-               .base_baud      = 3686400,
-               .uart_offset    = 0x10,
-               .first_offset   = 0x800,
-       },
-       /*
-        * ADDI-DATA GmbH PCI-Express communication cards <info@addi-data.com>
-        */
-       [pbn_ADDIDATA_PCIe_1_3906250] = {
-               .flags          = FL_BASE0,
-               .num_ports      = 1,
-               .base_baud      = 3906250,
-               .uart_offset    = 0x200,
-               .first_offset   = 0x1000,
-       },
-       [pbn_ADDIDATA_PCIe_2_3906250] = {
-               .flags          = FL_BASE0,
-               .num_ports      = 2,
-               .base_baud      = 3906250,
-               .uart_offset    = 0x200,
-               .first_offset   = 0x1000,
-       },
-       [pbn_ADDIDATA_PCIe_4_3906250] = {
-               .flags          = FL_BASE0,
-               .num_ports      = 4,
-               .base_baud      = 3906250,
-               .uart_offset    = 0x200,
-               .first_offset   = 0x1000,
-       },
-       [pbn_ADDIDATA_PCIe_8_3906250] = {
-               .flags          = FL_BASE0,
-               .num_ports      = 8,
-               .base_baud      = 3906250,
-               .uart_offset    = 0x200,
-               .first_offset   = 0x1000,
-       },
-       [pbn_ce4100_1_115200] = {
-               .flags          = FL_BASE0,
-               .num_ports      = 1,
-               .base_baud      = 921600,
-               .reg_shift      = 2,
-       },
-       [pbn_omegapci] = {
-               .flags          = FL_BASE0,
-               .num_ports      = 8,
-               .base_baud      = 115200,
-               .uart_offset    = 0x200,
-       },
-       [pbn_NETMOS9900_2s_115200] = {
-               .flags          = FL_BASE0,
-               .num_ports      = 2,
-               .base_baud      = 115200,
-       },
-};
-
-static const struct pci_device_id softmodem_blacklist[] = {
-       { PCI_VDEVICE(AL, 0x5457), }, /* ALi Corporation M5457 AC'97 Modem */
-       { PCI_VDEVICE(MOTOROLA, 0x3052), }, /* Motorola Si3052-based modem */
-       { PCI_DEVICE(0x1543, 0x3052), }, /* Si3052-based modem, default IDs */
-};
-
-/*
- * Given a complete unknown PCI device, try to use some heuristics to
- * guess what the configuration might be, based on the pitiful PCI
- * serial specs.  Returns 0 on success, 1 on failure.
- */
-static int __devinit
-serial_pci_guess_board(struct pci_dev *dev, struct pciserial_board *board)
-{
-       const struct pci_device_id *blacklist;
-       int num_iomem, num_port, first_port = -1, i;
-
-       /*
-        * If it is not a communications device or the programming
-        * interface is greater than 6, give up.
-        *
-        * (Should we try to make guesses for multiport serial devices
-        * later?)
-        */
-       if ((((dev->class >> 8) != PCI_CLASS_COMMUNICATION_SERIAL) &&
-            ((dev->class >> 8) != PCI_CLASS_COMMUNICATION_MODEM)) ||
-           (dev->class & 0xff) > 6)
-               return -ENODEV;
-
-       /*
-        * Do not access blacklisted devices that are known not to
-        * feature serial ports.
-        */
-       for (blacklist = softmodem_blacklist;
-            blacklist < softmodem_blacklist + ARRAY_SIZE(softmodem_blacklist);
-            blacklist++) {
-               if (dev->vendor == blacklist->vendor &&
-                   dev->device == blacklist->device)
-                       return -ENODEV;
-       }
-
-       num_iomem = num_port = 0;
-       for (i = 0; i < PCI_NUM_BAR_RESOURCES; i++) {
-               if (pci_resource_flags(dev, i) & IORESOURCE_IO) {
-                       num_port++;
-                       if (first_port == -1)
-                               first_port = i;
-               }
-               if (pci_resource_flags(dev, i) & IORESOURCE_MEM)
-                       num_iomem++;
-       }
-
-       /*
-        * If there is 1 or 0 iomem regions, and exactly one port,
-        * use it.  We guess the number of ports based on the IO
-        * region size.
-        */
-       if (num_iomem <= 1 && num_port == 1) {
-               board->flags = first_port;
-               board->num_ports = pci_resource_len(dev, first_port) / 8;
-               return 0;
-       }
-
-       /*
-        * Now guess if we've got a board which indexes by BARs.
-        * Each IO BAR should be 8 bytes, and they should follow
-        * consecutively.
-        */
-       first_port = -1;
-       num_port = 0;
-       for (i = 0; i < PCI_NUM_BAR_RESOURCES; i++) {
-               if (pci_resource_flags(dev, i) & IORESOURCE_IO &&
-                   pci_resource_len(dev, i) == 8 &&
-                   (first_port == -1 || (first_port + num_port) == i)) {
-                       num_port++;
-                       if (first_port == -1)
-                               first_port = i;
-               }
-       }
-
-       if (num_port > 1) {
-               board->flags = first_port | FL_BASE_BARS;
-               board->num_ports = num_port;
-               return 0;
-       }
-
-       return -ENODEV;
-}
-
-static inline int
-serial_pci_matches(const struct pciserial_board *board,
-                  const struct pciserial_board *guessed)
-{
-       return
-           board->num_ports == guessed->num_ports &&
-           board->base_baud == guessed->base_baud &&
-           board->uart_offset == guessed->uart_offset &&
-           board->reg_shift == guessed->reg_shift &&
-           board->first_offset == guessed->first_offset;
-}
-
-struct serial_private *
-pciserial_init_ports(struct pci_dev *dev, const struct pciserial_board *board)
-{
-       struct uart_port serial_port;
-       struct serial_private *priv;
-       struct pci_serial_quirk *quirk;
-       int rc, nr_ports, i;
-
-       nr_ports = board->num_ports;
-
-       /*
-        * Find an init and setup quirks.
-        */
-       quirk = find_quirk(dev);
-
-       /*
-        * Run the new-style initialization function.
-        * The initialization function returns:
-        *  <0  - error
-        *   0  - use board->num_ports
-        *  >0  - number of ports
-        */
-       if (quirk->init) {
-               rc = quirk->init(dev);
-               if (rc < 0) {
-                       priv = ERR_PTR(rc);
-                       goto err_out;
-               }
-               if (rc)
-                       nr_ports = rc;
-       }
-
-       priv = kzalloc(sizeof(struct serial_private) +
-                      sizeof(unsigned int) * nr_ports,
-                      GFP_KERNEL);
-       if (!priv) {
-               priv = ERR_PTR(-ENOMEM);
-               goto err_deinit;
-       }
-
-       priv->dev = dev;
-       priv->quirk = quirk;
-
-       memset(&serial_port, 0, sizeof(struct uart_port));
-       serial_port.flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF | UPF_SHARE_IRQ;
-       serial_port.uartclk = board->base_baud * 16;
-       serial_port.irq = get_pci_irq(dev, board);
-       serial_port.dev = &dev->dev;
-
-       for (i = 0; i < nr_ports; i++) {
-               if (quirk->setup(priv, board, &serial_port, i))
-                       break;
-
-#ifdef SERIAL_DEBUG_PCI
-               printk(KERN_DEBUG "Setup PCI port: port %lx, irq %d, type %d\n",
-                      serial_port.iobase, serial_port.irq, serial_port.iotype);
-#endif
-
-               priv->line[i] = serial8250_register_port(&serial_port);
-               if (priv->line[i] < 0) {
-                       printk(KERN_WARNING "Couldn't register serial port %s: %d\n", pci_name(dev), priv->line[i]);
-                       break;
-               }
-       }
-       priv->nr = i;
-       return priv;
-
-err_deinit:
-       if (quirk->exit)
-               quirk->exit(dev);
-err_out:
-       return priv;
-}
-EXPORT_SYMBOL_GPL(pciserial_init_ports);
-
-void pciserial_remove_ports(struct serial_private *priv)
-{
-       struct pci_serial_quirk *quirk;
-       int i;
-
-       for (i = 0; i < priv->nr; i++)
-               serial8250_unregister_port(priv->line[i]);
-
-       for (i = 0; i < PCI_NUM_BAR_RESOURCES; i++) {
-               if (priv->remapped_bar[i])
-                       iounmap(priv->remapped_bar[i]);
-               priv->remapped_bar[i] = NULL;
-       }
-
-       /*
-        * Find the exit quirks.
-        */
-       quirk = find_quirk(priv->dev);
-       if (quirk->exit)
-               quirk->exit(priv->dev);
-
-       kfree(priv);
-}
-EXPORT_SYMBOL_GPL(pciserial_remove_ports);
-
-void pciserial_suspend_ports(struct serial_private *priv)
-{
-       int i;
-
-       for (i = 0; i < priv->nr; i++)
-               if (priv->line[i] >= 0)
-                       serial8250_suspend_port(priv->line[i]);
-}
-EXPORT_SYMBOL_GPL(pciserial_suspend_ports);
-
-void pciserial_resume_ports(struct serial_private *priv)
-{
-       int i;
-
-       /*
-        * Ensure that the board is correctly configured.
-        */
-       if (priv->quirk->init)
-               priv->quirk->init(priv->dev);
-
-       for (i = 0; i < priv->nr; i++)
-               if (priv->line[i] >= 0)
-                       serial8250_resume_port(priv->line[i]);
-}
-EXPORT_SYMBOL_GPL(pciserial_resume_ports);
-
-/*
- * Probe one serial board.  Unfortunately, there is no rhyme nor reason
- * to the arrangement of serial ports on a PCI card.
- */
-static int __devinit
-pciserial_init_one(struct pci_dev *dev, const struct pci_device_id *ent)
-{
-       struct pci_serial_quirk *quirk;
-       struct serial_private *priv;
-       const struct pciserial_board *board;
-       struct pciserial_board tmp;
-       int rc;
-
-       quirk = find_quirk(dev);
-       if (quirk->probe) {
-               rc = quirk->probe(dev);
-               if (rc)
-                       return rc;
-       }
-
-       if (ent->driver_data >= ARRAY_SIZE(pci_boards)) {
-               printk(KERN_ERR "pci_init_one: invalid driver_data: %ld\n",
-                       ent->driver_data);
-               return -EINVAL;
-       }
-
-       board = &pci_boards[ent->driver_data];
-
-       rc = pci_enable_device(dev);
-       pci_save_state(dev);
-       if (rc)
-               return rc;
-
-       if (ent->driver_data == pbn_default) {
-               /*
-                * Use a copy of the pci_board entry for this;
-                * avoid changing entries in the table.
-                */
-               memcpy(&tmp, board, sizeof(struct pciserial_board));
-               board = &tmp;
-
-               /*
-                * We matched one of our class entries.  Try to
-                * determine the parameters of this board.
-                */
-               rc = serial_pci_guess_board(dev, &tmp);
-               if (rc)
-                       goto disable;
-       } else {
-               /*
-                * We matched an explicit entry.  If we are able to
-                * detect this boards settings with our heuristic,
-                * then we no longer need this entry.
-                */
-               memcpy(&tmp, &pci_boards[pbn_default],
-                      sizeof(struct pciserial_board));
-               rc = serial_pci_guess_board(dev, &tmp);
-               if (rc == 0 && serial_pci_matches(board, &tmp))
-                       moan_device("Redundant entry in serial pci_table.",
-                                   dev);
-       }
-
-       priv = pciserial_init_ports(dev, board);
-       if (!IS_ERR(priv)) {
-               pci_set_drvdata(dev, priv);
-               return 0;
-       }
-
-       rc = PTR_ERR(priv);
-
- disable:
-       pci_disable_device(dev);
-       return rc;
-}
-
-static void __devexit pciserial_remove_one(struct pci_dev *dev)
-{
-       struct serial_private *priv = pci_get_drvdata(dev);
-
-       pci_set_drvdata(dev, NULL);
-
-       pciserial_remove_ports(priv);
-
-       pci_disable_device(dev);
-}
-
-#ifdef CONFIG_PM
-static int pciserial_suspend_one(struct pci_dev *dev, pm_message_t state)
-{
-       struct serial_private *priv = pci_get_drvdata(dev);
-
-       if (priv)
-               pciserial_suspend_ports(priv);
-
-       pci_save_state(dev);
-       pci_set_power_state(dev, pci_choose_state(dev, state));
-       return 0;
-}
-
-static int pciserial_resume_one(struct pci_dev *dev)
-{
-       int err;
-       struct serial_private *priv = pci_get_drvdata(dev);
-
-       pci_set_power_state(dev, PCI_D0);
-       pci_restore_state(dev);
-
-       if (priv) {
-               /*
-                * The device may have been disabled.  Re-enable it.
-                */
-               err = pci_enable_device(dev);
-               /* FIXME: We cannot simply error out here */
-               if (err)
-                       printk(KERN_ERR "pciserial: Unable to re-enable ports, trying to continue.\n");
-               pciserial_resume_ports(priv);
-       }
-       return 0;
-}
-#endif
-
-static struct pci_device_id serial_pci_tbl[] = {
-       /* Advantech use PCI_DEVICE_ID_ADVANTECH_PCI3620 (0x3620) as 'PCI_SUBVENDOR_ID' */
-       {       PCI_VENDOR_ID_ADVANTECH, PCI_DEVICE_ID_ADVANTECH_PCI3620,
-               PCI_DEVICE_ID_ADVANTECH_PCI3620, 0x0001, 0, 0,
-               pbn_b2_8_921600 },
-       {       PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V960,
-               PCI_SUBVENDOR_ID_CONNECT_TECH,
-               PCI_SUBDEVICE_ID_CONNECT_TECH_BH8_232, 0, 0,
-               pbn_b1_8_1382400 },
-       {       PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V960,
-               PCI_SUBVENDOR_ID_CONNECT_TECH,
-               PCI_SUBDEVICE_ID_CONNECT_TECH_BH4_232, 0, 0,
-               pbn_b1_4_1382400 },
-       {       PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V960,
-               PCI_SUBVENDOR_ID_CONNECT_TECH,
-               PCI_SUBDEVICE_ID_CONNECT_TECH_BH2_232, 0, 0,
-               pbn_b1_2_1382400 },
-       {       PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V351,
-               PCI_SUBVENDOR_ID_CONNECT_TECH,
-               PCI_SUBDEVICE_ID_CONNECT_TECH_BH8_232, 0, 0,
-               pbn_b1_8_1382400 },
-       {       PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V351,
-               PCI_SUBVENDOR_ID_CONNECT_TECH,
-               PCI_SUBDEVICE_ID_CONNECT_TECH_BH4_232, 0, 0,
-               pbn_b1_4_1382400 },
-       {       PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V351,
-               PCI_SUBVENDOR_ID_CONNECT_TECH,
-               PCI_SUBDEVICE_ID_CONNECT_TECH_BH2_232, 0, 0,
-               pbn_b1_2_1382400 },
-       {       PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V351,
-               PCI_SUBVENDOR_ID_CONNECT_TECH,
-               PCI_SUBDEVICE_ID_CONNECT_TECH_BH8_485, 0, 0,
-               pbn_b1_8_921600 },
-       {       PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V351,
-               PCI_SUBVENDOR_ID_CONNECT_TECH,
-               PCI_SUBDEVICE_ID_CONNECT_TECH_BH8_485_4_4, 0, 0,
-               pbn_b1_8_921600 },
-       {       PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V351,
-               PCI_SUBVENDOR_ID_CONNECT_TECH,
-               PCI_SUBDEVICE_ID_CONNECT_TECH_BH4_485, 0, 0,
-               pbn_b1_4_921600 },
-       {       PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V351,
-               PCI_SUBVENDOR_ID_CONNECT_TECH,
-               PCI_SUBDEVICE_ID_CONNECT_TECH_BH4_485_2_2, 0, 0,
-               pbn_b1_4_921600 },
-       {       PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V351,
-               PCI_SUBVENDOR_ID_CONNECT_TECH,
-               PCI_SUBDEVICE_ID_CONNECT_TECH_BH2_485, 0, 0,
-               pbn_b1_2_921600 },
-       {       PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V351,
-               PCI_SUBVENDOR_ID_CONNECT_TECH,
-               PCI_SUBDEVICE_ID_CONNECT_TECH_BH8_485_2_6, 0, 0,
-               pbn_b1_8_921600 },
-       {       PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V351,
-               PCI_SUBVENDOR_ID_CONNECT_TECH,
-               PCI_SUBDEVICE_ID_CONNECT_TECH_BH081101V1, 0, 0,
-               pbn_b1_8_921600 },
-       {       PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V351,
-               PCI_SUBVENDOR_ID_CONNECT_TECH,
-               PCI_SUBDEVICE_ID_CONNECT_TECH_BH041101V1, 0, 0,
-               pbn_b1_4_921600 },
-       {       PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V351,
-               PCI_SUBVENDOR_ID_CONNECT_TECH,
-               PCI_SUBDEVICE_ID_CONNECT_TECH_BH2_20MHZ, 0, 0,
-               pbn_b1_2_1250000 },
-       {       PCI_VENDOR_ID_OXSEMI, PCI_DEVICE_ID_OXSEMI_16PCI954,
-               PCI_SUBVENDOR_ID_CONNECT_TECH,
-               PCI_SUBDEVICE_ID_CONNECT_TECH_TITAN_2, 0, 0,
-               pbn_b0_2_1843200 },
-       {       PCI_VENDOR_ID_OXSEMI, PCI_DEVICE_ID_OXSEMI_16PCI954,
-               PCI_SUBVENDOR_ID_CONNECT_TECH,
-               PCI_SUBDEVICE_ID_CONNECT_TECH_TITAN_4, 0, 0,
-               pbn_b0_4_1843200 },
-       {       PCI_VENDOR_ID_OXSEMI, PCI_DEVICE_ID_OXSEMI_16PCI954,
-               PCI_VENDOR_ID_AFAVLAB,
-               PCI_SUBDEVICE_ID_AFAVLAB_P061, 0, 0,
-               pbn_b0_4_1152000 },
-       {       PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17C152,
-               PCI_SUBVENDOR_ID_CONNECT_TECH,
-               PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_2_232, 0, 0,
-               pbn_b0_2_1843200_200 },
-       {       PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17C154,
-               PCI_SUBVENDOR_ID_CONNECT_TECH,
-               PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_4_232, 0, 0,
-               pbn_b0_4_1843200_200 },
-       {       PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17C158,
-               PCI_SUBVENDOR_ID_CONNECT_TECH,
-               PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_8_232, 0, 0,
-               pbn_b0_8_1843200_200 },
-       {       PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17C152,
-               PCI_SUBVENDOR_ID_CONNECT_TECH,
-               PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_1_1, 0, 0,
-               pbn_b0_2_1843200_200 },
-       {       PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17C154,
-               PCI_SUBVENDOR_ID_CONNECT_TECH,
-               PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_2_2, 0, 0,
-               pbn_b0_4_1843200_200 },
-       {       PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17C158,
-               PCI_SUBVENDOR_ID_CONNECT_TECH,
-               PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_4_4, 0, 0,
-               pbn_b0_8_1843200_200 },
-       {       PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17C152,
-               PCI_SUBVENDOR_ID_CONNECT_TECH,
-               PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_2, 0, 0,
-               pbn_b0_2_1843200_200 },
-       {       PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17C154,
-               PCI_SUBVENDOR_ID_CONNECT_TECH,
-               PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_4, 0, 0,
-               pbn_b0_4_1843200_200 },
-       {       PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17C158,
-               PCI_SUBVENDOR_ID_CONNECT_TECH,
-               PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_8, 0, 0,
-               pbn_b0_8_1843200_200 },
-       {       PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17C152,
-               PCI_SUBVENDOR_ID_CONNECT_TECH,
-               PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_2_485, 0, 0,
-               pbn_b0_2_1843200_200 },
-       {       PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17C154,
-               PCI_SUBVENDOR_ID_CONNECT_TECH,
-               PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_4_485, 0, 0,
-               pbn_b0_4_1843200_200 },
-       {       PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17C158,
-               PCI_SUBVENDOR_ID_CONNECT_TECH,
-               PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_8_485, 0, 0,
-               pbn_b0_8_1843200_200 },
-       {       PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17C152,
-               PCI_VENDOR_ID_IBM, PCI_SUBDEVICE_ID_IBM_SATURN_SERIAL_ONE_PORT,
-               0, 0, pbn_exar_ibm_saturn },
-
-       {       PCI_VENDOR_ID_SEALEVEL, PCI_DEVICE_ID_SEALEVEL_U530,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_b2_bt_1_115200 },
-       {       PCI_VENDOR_ID_SEALEVEL, PCI_DEVICE_ID_SEALEVEL_UCOMM2,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_b2_bt_2_115200 },
-       {       PCI_VENDOR_ID_SEALEVEL, PCI_DEVICE_ID_SEALEVEL_UCOMM422,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_b2_bt_4_115200 },
-       {       PCI_VENDOR_ID_SEALEVEL, PCI_DEVICE_ID_SEALEVEL_UCOMM232,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_b2_bt_2_115200 },
-       {       PCI_VENDOR_ID_SEALEVEL, PCI_DEVICE_ID_SEALEVEL_COMM4,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_b2_bt_4_115200 },
-       {       PCI_VENDOR_ID_SEALEVEL, PCI_DEVICE_ID_SEALEVEL_COMM8,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_b2_8_115200 },
-       {       PCI_VENDOR_ID_SEALEVEL, PCI_DEVICE_ID_SEALEVEL_7803,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_b2_8_460800 },
-       {       PCI_VENDOR_ID_SEALEVEL, PCI_DEVICE_ID_SEALEVEL_UCOMM8,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_b2_8_115200 },
-
-       {       PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_GTEK_SERIAL2,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_b2_bt_2_115200 },
-       {       PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_SPCOM200,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_b2_bt_2_921600 },
-       /*
-        * VScom SPCOM800, from sl@s.pl
-        */
-       {       PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_SPCOM800,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_b2_8_921600 },
-       {       PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_1077,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_b2_4_921600 },
-       /* Unknown card - subdevice 0x1584 */
-       {       PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050,
-               PCI_VENDOR_ID_PLX,
-               PCI_SUBDEVICE_ID_UNKNOWN_0x1584, 0, 0,
-               pbn_b0_4_115200 },
-       {       PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050,
-               PCI_SUBVENDOR_ID_KEYSPAN,
-               PCI_SUBDEVICE_ID_KEYSPAN_SX2, 0, 0,
-               pbn_panacom },
-       {       PCI_VENDOR_ID_PANACOM, PCI_DEVICE_ID_PANACOM_QUADMODEM,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_panacom4 },
-       {       PCI_VENDOR_ID_PANACOM, PCI_DEVICE_ID_PANACOM_DUALMODEM,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_panacom2 },
-       {       PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9030,
-               PCI_VENDOR_ID_ESDGMBH,
-               PCI_DEVICE_ID_ESDGMBH_CPCIASIO4, 0, 0,
-               pbn_b2_4_115200 },
-       {       PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050,
-               PCI_SUBVENDOR_ID_CHASE_PCIFAST,
-               PCI_SUBDEVICE_ID_CHASE_PCIFAST4, 0, 0,
-               pbn_b2_4_460800 },
-       {       PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050,
-               PCI_SUBVENDOR_ID_CHASE_PCIFAST,
-               PCI_SUBDEVICE_ID_CHASE_PCIFAST8, 0, 0,
-               pbn_b2_8_460800 },
-       {       PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050,
-               PCI_SUBVENDOR_ID_CHASE_PCIFAST,
-               PCI_SUBDEVICE_ID_CHASE_PCIFAST16, 0, 0,
-               pbn_b2_16_460800 },
-       {       PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050,
-               PCI_SUBVENDOR_ID_CHASE_PCIFAST,
-               PCI_SUBDEVICE_ID_CHASE_PCIFAST16FMC, 0, 0,
-               pbn_b2_16_460800 },
-       {       PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050,
-               PCI_SUBVENDOR_ID_CHASE_PCIRAS,
-               PCI_SUBDEVICE_ID_CHASE_PCIRAS4, 0, 0,
-               pbn_b2_4_460800 },
-       {       PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050,
-               PCI_SUBVENDOR_ID_CHASE_PCIRAS,
-               PCI_SUBDEVICE_ID_CHASE_PCIRAS8, 0, 0,
-               pbn_b2_8_460800 },
-       {       PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050,
-               PCI_SUBVENDOR_ID_EXSYS,
-               PCI_SUBDEVICE_ID_EXSYS_4055, 0, 0,
-               pbn_exsys_4055 },
-       /*
-        * Megawolf Romulus PCI Serial Card, from Mike Hudson
-        * (Exoray@isys.ca)
-        */
-       {       PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_ROMULUS,
-               0x10b5, 0x106a, 0, 0,
-               pbn_plx_romulus },
-       {       PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_QSC100,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_b1_4_115200 },
-       {       PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_DSC100,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_b1_2_115200 },
-       {       PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_ESC100D,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_b1_8_115200 },
-       {       PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_ESC100M,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_b1_8_115200 },
-       {       PCI_VENDOR_ID_SPECIALIX, PCI_DEVICE_ID_OXSEMI_16PCI954,
-               PCI_VENDOR_ID_SPECIALIX, PCI_SUBDEVICE_ID_SPECIALIX_SPEED4,
-               0, 0,
-               pbn_b0_4_921600 },
-       {       PCI_VENDOR_ID_OXSEMI, PCI_DEVICE_ID_OXSEMI_16PCI954,
-               PCI_SUBVENDOR_ID_SIIG, PCI_SUBDEVICE_ID_SIIG_QUARTET_SERIAL,
-               0, 0,
-               pbn_b0_4_1152000 },
-       {       PCI_VENDOR_ID_OXSEMI, 0x9505,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_b0_bt_2_921600 },
-
-               /*
-                * The below card is a little controversial since it is the
-                * subject of a PCI vendor/device ID clash.  (See
-                * www.ussg.iu.edu/hypermail/linux/kernel/0303.1/0516.html).
-                * For now just used the hex ID 0x950a.
-                */
-       {       PCI_VENDOR_ID_OXSEMI, 0x950a,
-               PCI_SUBVENDOR_ID_SIIG, PCI_SUBDEVICE_ID_SIIG_DUAL_SERIAL, 0, 0,
-               pbn_b0_2_115200 },
-       {       PCI_VENDOR_ID_OXSEMI, 0x950a,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_b0_2_1130000 },
-       {       PCI_VENDOR_ID_OXSEMI, PCI_DEVICE_ID_OXSEMI_C950,
-               PCI_VENDOR_ID_OXSEMI, PCI_SUBDEVICE_ID_OXSEMI_C950, 0, 0,
-               pbn_b0_1_921600 },
-       {       PCI_VENDOR_ID_OXSEMI, PCI_DEVICE_ID_OXSEMI_16PCI954,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_b0_4_115200 },
-       {       PCI_VENDOR_ID_OXSEMI, PCI_DEVICE_ID_OXSEMI_16PCI952,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_b0_bt_2_921600 },
-       {       PCI_VENDOR_ID_OXSEMI, PCI_DEVICE_ID_OXSEMI_16PCI958,
-               PCI_ANY_ID , PCI_ANY_ID, 0, 0,
-               pbn_b2_8_1152000 },
-
-       /*
-        * Oxford Semiconductor Inc. Tornado PCI express device range.
-        */
-       {       PCI_VENDOR_ID_OXSEMI, 0xc101,    /* OXPCIe952 1 Legacy UART */
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_b0_1_4000000 },
-       {       PCI_VENDOR_ID_OXSEMI, 0xc105,    /* OXPCIe952 1 Legacy UART */
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_b0_1_4000000 },
-       {       PCI_VENDOR_ID_OXSEMI, 0xc11b,    /* OXPCIe952 1 Native UART */
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_oxsemi_1_4000000 },
-       {       PCI_VENDOR_ID_OXSEMI, 0xc11f,    /* OXPCIe952 1 Native UART */
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_oxsemi_1_4000000 },
-       {       PCI_VENDOR_ID_OXSEMI, 0xc120,    /* OXPCIe952 1 Legacy UART */
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_b0_1_4000000 },
-       {       PCI_VENDOR_ID_OXSEMI, 0xc124,    /* OXPCIe952 1 Legacy UART */
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_b0_1_4000000 },
-       {       PCI_VENDOR_ID_OXSEMI, 0xc138,    /* OXPCIe952 1 Native UART */
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_oxsemi_1_4000000 },
-       {       PCI_VENDOR_ID_OXSEMI, 0xc13d,    /* OXPCIe952 1 Native UART */
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_oxsemi_1_4000000 },
-       {       PCI_VENDOR_ID_OXSEMI, 0xc140,    /* OXPCIe952 1 Legacy UART */
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_b0_1_4000000 },
-       {       PCI_VENDOR_ID_OXSEMI, 0xc141,    /* OXPCIe952 1 Legacy UART */
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_b0_1_4000000 },
-       {       PCI_VENDOR_ID_OXSEMI, 0xc144,    /* OXPCIe952 1 Legacy UART */
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_b0_1_4000000 },
-       {       PCI_VENDOR_ID_OXSEMI, 0xc145,    /* OXPCIe952 1 Legacy UART */
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_b0_1_4000000 },
-       {       PCI_VENDOR_ID_OXSEMI, 0xc158,    /* OXPCIe952 2 Native UART */
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_oxsemi_2_4000000 },
-       {       PCI_VENDOR_ID_OXSEMI, 0xc15d,    /* OXPCIe952 2 Native UART */
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_oxsemi_2_4000000 },
-       {       PCI_VENDOR_ID_OXSEMI, 0xc208,    /* OXPCIe954 4 Native UART */
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_oxsemi_4_4000000 },
-       {       PCI_VENDOR_ID_OXSEMI, 0xc20d,    /* OXPCIe954 4 Native UART */
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_oxsemi_4_4000000 },
-       {       PCI_VENDOR_ID_OXSEMI, 0xc308,    /* OXPCIe958 8 Native UART */
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_oxsemi_8_4000000 },
-       {       PCI_VENDOR_ID_OXSEMI, 0xc30d,    /* OXPCIe958 8 Native UART */
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_oxsemi_8_4000000 },
-       {       PCI_VENDOR_ID_OXSEMI, 0xc40b,    /* OXPCIe200 1 Native UART */
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_oxsemi_1_4000000 },
-       {       PCI_VENDOR_ID_OXSEMI, 0xc40f,    /* OXPCIe200 1 Native UART */
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_oxsemi_1_4000000 },
-       {       PCI_VENDOR_ID_OXSEMI, 0xc41b,    /* OXPCIe200 1 Native UART */
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_oxsemi_1_4000000 },
-       {       PCI_VENDOR_ID_OXSEMI, 0xc41f,    /* OXPCIe200 1 Native UART */
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_oxsemi_1_4000000 },
-       {       PCI_VENDOR_ID_OXSEMI, 0xc42b,    /* OXPCIe200 1 Native UART */
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_oxsemi_1_4000000 },
-       {       PCI_VENDOR_ID_OXSEMI, 0xc42f,    /* OXPCIe200 1 Native UART */
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_oxsemi_1_4000000 },
-       {       PCI_VENDOR_ID_OXSEMI, 0xc43b,    /* OXPCIe200 1 Native UART */
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_oxsemi_1_4000000 },
-       {       PCI_VENDOR_ID_OXSEMI, 0xc43f,    /* OXPCIe200 1 Native UART */
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_oxsemi_1_4000000 },
-       {       PCI_VENDOR_ID_OXSEMI, 0xc44b,    /* OXPCIe200 1 Native UART */
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_oxsemi_1_4000000 },
-       {       PCI_VENDOR_ID_OXSEMI, 0xc44f,    /* OXPCIe200 1 Native UART */
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_oxsemi_1_4000000 },
-       {       PCI_VENDOR_ID_OXSEMI, 0xc45b,    /* OXPCIe200 1 Native UART */
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_oxsemi_1_4000000 },
-       {       PCI_VENDOR_ID_OXSEMI, 0xc45f,    /* OXPCIe200 1 Native UART */
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_oxsemi_1_4000000 },
-       {       PCI_VENDOR_ID_OXSEMI, 0xc46b,    /* OXPCIe200 1 Native UART */
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_oxsemi_1_4000000 },
-       {       PCI_VENDOR_ID_OXSEMI, 0xc46f,    /* OXPCIe200 1 Native UART */
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_oxsemi_1_4000000 },
-       {       PCI_VENDOR_ID_OXSEMI, 0xc47b,    /* OXPCIe200 1 Native UART */
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_oxsemi_1_4000000 },
-       {       PCI_VENDOR_ID_OXSEMI, 0xc47f,    /* OXPCIe200 1 Native UART */
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_oxsemi_1_4000000 },
-       {       PCI_VENDOR_ID_OXSEMI, 0xc48b,    /* OXPCIe200 1 Native UART */
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_oxsemi_1_4000000 },
-       {       PCI_VENDOR_ID_OXSEMI, 0xc48f,    /* OXPCIe200 1 Native UART */
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_oxsemi_1_4000000 },
-       {       PCI_VENDOR_ID_OXSEMI, 0xc49b,    /* OXPCIe200 1 Native UART */
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_oxsemi_1_4000000 },
-       {       PCI_VENDOR_ID_OXSEMI, 0xc49f,    /* OXPCIe200 1 Native UART */
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_oxsemi_1_4000000 },
-       {       PCI_VENDOR_ID_OXSEMI, 0xc4ab,    /* OXPCIe200 1 Native UART */
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_oxsemi_1_4000000 },
-       {       PCI_VENDOR_ID_OXSEMI, 0xc4af,    /* OXPCIe200 1 Native UART */
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_oxsemi_1_4000000 },
-       {       PCI_VENDOR_ID_OXSEMI, 0xc4bb,    /* OXPCIe200 1 Native UART */
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_oxsemi_1_4000000 },
-       {       PCI_VENDOR_ID_OXSEMI, 0xc4bf,    /* OXPCIe200 1 Native UART */
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_oxsemi_1_4000000 },
-       {       PCI_VENDOR_ID_OXSEMI, 0xc4cb,    /* OXPCIe200 1 Native UART */
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_oxsemi_1_4000000 },
-       {       PCI_VENDOR_ID_OXSEMI, 0xc4cf,    /* OXPCIe200 1 Native UART */
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_oxsemi_1_4000000 },
-       /*
-        * Mainpine Inc. IQ Express "Rev3" utilizing OxSemi Tornado
-        */
-       {       PCI_VENDOR_ID_MAINPINE, 0x4000, /* IQ Express 1 Port V.34 Super-G3 Fax */
-               PCI_VENDOR_ID_MAINPINE, 0x4001, 0, 0,
-               pbn_oxsemi_1_4000000 },
-       {       PCI_VENDOR_ID_MAINPINE, 0x4000, /* IQ Express 2 Port V.34 Super-G3 Fax */
-               PCI_VENDOR_ID_MAINPINE, 0x4002, 0, 0,
-               pbn_oxsemi_2_4000000 },
-       {       PCI_VENDOR_ID_MAINPINE, 0x4000, /* IQ Express 4 Port V.34 Super-G3 Fax */
-               PCI_VENDOR_ID_MAINPINE, 0x4004, 0, 0,
-               pbn_oxsemi_4_4000000 },
-       {       PCI_VENDOR_ID_MAINPINE, 0x4000, /* IQ Express 8 Port V.34 Super-G3 Fax */
-               PCI_VENDOR_ID_MAINPINE, 0x4008, 0, 0,
-               pbn_oxsemi_8_4000000 },
-
-       /*
-        * Digi/IBM PCIe 2-port Async EIA-232 Adapter utilizing OxSemi Tornado
-        */
-       {       PCI_VENDOR_ID_DIGI, PCIE_DEVICE_ID_NEO_2_OX_IBM,
-               PCI_SUBVENDOR_ID_IBM, PCI_ANY_ID, 0, 0,
-               pbn_oxsemi_2_4000000 },
-
-       /*
-        * SBS Technologies, Inc. P-Octal and PMC-OCTPRO cards,
-        * from skokodyn@yahoo.com
-        */
-       {       PCI_VENDOR_ID_SBSMODULARIO, PCI_DEVICE_ID_OCTPRO,
-               PCI_SUBVENDOR_ID_SBSMODULARIO, PCI_SUBDEVICE_ID_OCTPRO232, 0, 0,
-               pbn_sbsxrsio },
-       {       PCI_VENDOR_ID_SBSMODULARIO, PCI_DEVICE_ID_OCTPRO,
-               PCI_SUBVENDOR_ID_SBSMODULARIO, PCI_SUBDEVICE_ID_OCTPRO422, 0, 0,
-               pbn_sbsxrsio },
-       {       PCI_VENDOR_ID_SBSMODULARIO, PCI_DEVICE_ID_OCTPRO,
-               PCI_SUBVENDOR_ID_SBSMODULARIO, PCI_SUBDEVICE_ID_POCTAL232, 0, 0,
-               pbn_sbsxrsio },
-       {       PCI_VENDOR_ID_SBSMODULARIO, PCI_DEVICE_ID_OCTPRO,
-               PCI_SUBVENDOR_ID_SBSMODULARIO, PCI_SUBDEVICE_ID_POCTAL422, 0, 0,
-               pbn_sbsxrsio },
-
-       /*
-        * Digitan DS560-558, from jimd@esoft.com
-        */
-       {       PCI_VENDOR_ID_ATT, PCI_DEVICE_ID_ATT_VENUS_MODEM,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_b1_1_115200 },
-
-       /*
-        * Titan Electronic cards
-        *  The 400L and 800L have a custom setup quirk.
-        */
-       {       PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_100,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_b0_1_921600 },
-       {       PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_200,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_b0_2_921600 },
-       {       PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_400,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_b0_4_921600 },
-       {       PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_800B,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_b0_4_921600 },
-       {       PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_100L,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_b1_1_921600 },
-       {       PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_200L,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_b1_bt_2_921600 },
-       {       PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_400L,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_b0_bt_4_921600 },
-       {       PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_800L,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_b0_bt_8_921600 },
-       {       PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_200I,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_b4_bt_2_921600 },
-       {       PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_400I,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_b4_bt_4_921600 },
-       {       PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_800I,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_b4_bt_8_921600 },
-       {       PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_400EH,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_b0_4_921600 },
-       {       PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_800EH,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_b0_4_921600 },
-       {       PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_800EHB,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_b0_4_921600 },
-       {       PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_100E,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_oxsemi_1_4000000 },
-       {       PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_200E,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_oxsemi_2_4000000 },
-       {       PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_400E,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_oxsemi_4_4000000 },
-       {       PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_800E,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_oxsemi_8_4000000 },
-       {       PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_200EI,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_oxsemi_2_4000000 },
-       {       PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_200EISI,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_oxsemi_2_4000000 },
-       {       PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_400V3,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_b0_4_921600 },
-       {       PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_410V3,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_b0_4_921600 },
-       {       PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_800V3,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_b0_4_921600 },
-       {       PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_800V3B,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_b0_4_921600 },
-
-       {       PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S_10x_550,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_b2_1_460800 },
-       {       PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S_10x_650,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_b2_1_460800 },
-       {       PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S_10x_850,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_b2_1_460800 },
-       {       PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S_10x_550,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_b2_bt_2_921600 },
-       {       PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S_10x_650,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_b2_bt_2_921600 },
-       {       PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S_10x_850,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_b2_bt_2_921600 },
-       {       PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_4S_10x_550,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_b2_bt_4_921600 },
-       {       PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_4S_10x_650,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_b2_bt_4_921600 },
-       {       PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_4S_10x_850,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_b2_bt_4_921600 },
-       {       PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S_20x_550,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_b0_1_921600 },
-       {       PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S_20x_650,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_b0_1_921600 },
-       {       PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S_20x_850,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_b0_1_921600 },
-       {       PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S_20x_550,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_b0_bt_2_921600 },
-       {       PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S_20x_650,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_b0_bt_2_921600 },
-       {       PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S_20x_850,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_b0_bt_2_921600 },
-       {       PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_4S_20x_550,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_b0_bt_4_921600 },
-       {       PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_4S_20x_650,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_b0_bt_4_921600 },
-       {       PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_4S_20x_850,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_b0_bt_4_921600 },
-       {       PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_8S_20x_550,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_b0_bt_8_921600 },
-       {       PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_8S_20x_650,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_b0_bt_8_921600 },
-       {       PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_8S_20x_850,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_b0_bt_8_921600 },
-
-       /*
-        * Computone devices submitted by Doug McNash dmcnash@computone.com
-        */
-       {       PCI_VENDOR_ID_COMPUTONE, PCI_DEVICE_ID_COMPUTONE_PG,
-               PCI_SUBVENDOR_ID_COMPUTONE, PCI_SUBDEVICE_ID_COMPUTONE_PG4,
-               0, 0, pbn_computone_4 },
-       {       PCI_VENDOR_ID_COMPUTONE, PCI_DEVICE_ID_COMPUTONE_PG,
-               PCI_SUBVENDOR_ID_COMPUTONE, PCI_SUBDEVICE_ID_COMPUTONE_PG8,
-               0, 0, pbn_computone_8 },
-       {       PCI_VENDOR_ID_COMPUTONE, PCI_DEVICE_ID_COMPUTONE_PG,
-               PCI_SUBVENDOR_ID_COMPUTONE, PCI_SUBDEVICE_ID_COMPUTONE_PG6,
-               0, 0, pbn_computone_6 },
-
-       {       PCI_VENDOR_ID_OXSEMI, PCI_DEVICE_ID_OXSEMI_16PCI95N,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_oxsemi },
-       {       PCI_VENDOR_ID_TIMEDIA, PCI_DEVICE_ID_TIMEDIA_1889,
-               PCI_VENDOR_ID_TIMEDIA, PCI_ANY_ID, 0, 0,
-               pbn_b0_bt_1_921600 },
-
-       /*
-        * AFAVLAB serial card, from Harald Welte <laforge@gnumonks.org>
-        */
-       {       PCI_VENDOR_ID_AFAVLAB, PCI_DEVICE_ID_AFAVLAB_P028,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_b0_bt_8_115200 },
-       {       PCI_VENDOR_ID_AFAVLAB, PCI_DEVICE_ID_AFAVLAB_P030,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_b0_bt_8_115200 },
-
-       {       PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_DSERIAL,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_b0_bt_2_115200 },
-       {       PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_QUATRO_A,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_b0_bt_2_115200 },
-       {       PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_QUATRO_B,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_b0_bt_2_115200 },
-       {       PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_QUATTRO_A,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_b0_bt_2_115200 },
-       {       PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_QUATTRO_B,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_b0_bt_2_115200 },
-       {       PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_OCTO_A,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_b0_bt_4_460800 },
-       {       PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_OCTO_B,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_b0_bt_4_460800 },
-       {       PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_PORT_PLUS,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_b0_bt_2_460800 },
-       {       PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_QUAD_A,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_b0_bt_2_460800 },
-       {       PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_QUAD_B,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_b0_bt_2_460800 },
-       {       PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_SSERIAL,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_b0_bt_1_115200 },
-       {       PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_PORT_650,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_b0_bt_1_460800 },
-
-       /*
-        * Korenix Jetcard F0/F1 cards (JC1204, JC1208, JC1404, JC1408).
-        * Cards are identified by their subsystem vendor IDs, which
-        * (in hex) match the model number.
-        *
-        * Note that JC140x are RS422/485 cards which require ox950
-        * ACR = 0x10, and as such are not currently fully supported.
-        */
-       {       PCI_VENDOR_ID_KORENIX, PCI_DEVICE_ID_KORENIX_JETCARDF0,
-               0x1204, 0x0004, 0, 0,
-               pbn_b0_4_921600 },
-       {       PCI_VENDOR_ID_KORENIX, PCI_DEVICE_ID_KORENIX_JETCARDF0,
-               0x1208, 0x0004, 0, 0,
-               pbn_b0_4_921600 },
-/*     {       PCI_VENDOR_ID_KORENIX, PCI_DEVICE_ID_KORENIX_JETCARDF0,
-               0x1402, 0x0002, 0, 0,
-               pbn_b0_2_921600 }, */
-/*     {       PCI_VENDOR_ID_KORENIX, PCI_DEVICE_ID_KORENIX_JETCARDF0,
-               0x1404, 0x0004, 0, 0,
-               pbn_b0_4_921600 }, */
-       {       PCI_VENDOR_ID_KORENIX, PCI_DEVICE_ID_KORENIX_JETCARDF1,
-               0x1208, 0x0004, 0, 0,
-               pbn_b0_4_921600 },
-
-       {       PCI_VENDOR_ID_KORENIX, PCI_DEVICE_ID_KORENIX_JETCARDF2,
-               0x1204, 0x0004, 0, 0,
-               pbn_b0_4_921600 },
-       {       PCI_VENDOR_ID_KORENIX, PCI_DEVICE_ID_KORENIX_JETCARDF2,
-               0x1208, 0x0004, 0, 0,
-               pbn_b0_4_921600 },
-       {       PCI_VENDOR_ID_KORENIX, PCI_DEVICE_ID_KORENIX_JETCARDF3,
-               0x1208, 0x0004, 0, 0,
-               pbn_b0_4_921600 },
-       /*
-        * Dell Remote Access Card 4 - Tim_T_Murphy@Dell.com
-        */
-       {       PCI_VENDOR_ID_DELL, PCI_DEVICE_ID_DELL_RAC4,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_b1_1_1382400 },
-
-       /*
-        * Dell Remote Access Card III - Tim_T_Murphy@Dell.com
-        */
-       {       PCI_VENDOR_ID_DELL, PCI_DEVICE_ID_DELL_RACIII,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_b1_1_1382400 },
-
-       /*
-        * RAStel 2 port modem, gerg@moreton.com.au
-        */
-       {       PCI_VENDOR_ID_MORETON, PCI_DEVICE_ID_RASTEL_2PORT,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_b2_bt_2_115200 },
-
-       /*
-        * EKF addition for i960 Boards form EKF with serial port
-        */
-       {       PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_80960_RP,
-               0xE4BF, PCI_ANY_ID, 0, 0,
-               pbn_intel_i960 },
-
-       /*
-        * Xircom Cardbus/Ethernet combos
-        */
-       {       PCI_VENDOR_ID_XIRCOM, PCI_DEVICE_ID_XIRCOM_X3201_MDM,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_b0_1_115200 },
-       /*
-        * Xircom RBM56G cardbus modem - Dirk Arnold (temp entry)
-        */
-       {       PCI_VENDOR_ID_XIRCOM, PCI_DEVICE_ID_XIRCOM_RBM56G,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_b0_1_115200 },
-
-       /*
-        * Untested PCI modems, sent in from various folks...
-        */
-
-       /*
-        * Elsa Model 56K PCI Modem, from Andreas Rath <arh@01019freenet.de>
-        */
-       {       PCI_VENDOR_ID_ROCKWELL, 0x1004,
-               0x1048, 0x1500, 0, 0,
-               pbn_b1_1_115200 },
-
-       {       PCI_VENDOR_ID_SGI, PCI_DEVICE_ID_SGI_IOC3,
-               0xFF00, 0, 0, 0,
-               pbn_sgi_ioc3 },
-
-       /*
-        * HP Diva card
-        */
-       {       PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_DIVA,
-               PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_DIVA_RMP3, 0, 0,
-               pbn_b1_1_115200 },
-       {       PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_DIVA,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_b0_5_115200 },
-       {       PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_DIVA_AUX,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_b2_1_115200 },
-
-       {       PCI_VENDOR_ID_DCI, PCI_DEVICE_ID_DCI_PCCOM2,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_b3_2_115200 },
-       {       PCI_VENDOR_ID_DCI, PCI_DEVICE_ID_DCI_PCCOM4,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_b3_4_115200 },
-       {       PCI_VENDOR_ID_DCI, PCI_DEVICE_ID_DCI_PCCOM8,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_b3_8_115200 },
-
-       /*
-        * Exar Corp. XR17C15[248] Dual/Quad/Octal UART
-        */
-       {       PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17C152,
-               PCI_ANY_ID, PCI_ANY_ID,
-               0,
-               0, pbn_exar_XR17C152 },
-       {       PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17C154,
-               PCI_ANY_ID, PCI_ANY_ID,
-               0,
-               0, pbn_exar_XR17C154 },
-       {       PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17C158,
-               PCI_ANY_ID, PCI_ANY_ID,
-               0,
-               0, pbn_exar_XR17C158 },
-
-       /*
-        * Topic TP560 Data/Fax/Voice 56k modem (reported by Evan Clarke)
-        */
-       {       PCI_VENDOR_ID_TOPIC, PCI_DEVICE_ID_TOPIC_TP560,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_b0_1_115200 },
-       /*
-        * ITE
-        */
-       {       PCI_VENDOR_ID_ITE, PCI_DEVICE_ID_ITE_8872,
-               PCI_ANY_ID, PCI_ANY_ID,
-               0, 0,
-               pbn_b1_bt_1_115200 },
-
-       /*
-        * IntaShield IS-200
-        */
-       {       PCI_VENDOR_ID_INTASHIELD, PCI_DEVICE_ID_INTASHIELD_IS200,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,   /* 135a.0811 */
-               pbn_b2_2_115200 },
-       /*
-        * IntaShield IS-400
-        */
-       {       PCI_VENDOR_ID_INTASHIELD, PCI_DEVICE_ID_INTASHIELD_IS400,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,    /* 135a.0dc0 */
-               pbn_b2_4_115200 },
-       /*
-        * Perle PCI-RAS cards
-        */
-       {       PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9030,
-               PCI_SUBVENDOR_ID_PERLE, PCI_SUBDEVICE_ID_PCI_RAS4,
-               0, 0, pbn_b2_4_921600 },
-       {       PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9030,
-               PCI_SUBVENDOR_ID_PERLE, PCI_SUBDEVICE_ID_PCI_RAS8,
-               0, 0, pbn_b2_8_921600 },
-
-       /*
-        * Mainpine series cards: Fairly standard layout but fools
-        * parts of the autodetect in some cases and uses otherwise
-        * unmatched communications subclasses in the PCI Express case
-        */
-
-       {       /* RockForceDUO */
-               PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
-               PCI_VENDOR_ID_MAINPINE, 0x0200,
-               0, 0, pbn_b0_2_115200 },
-       {       /* RockForceQUATRO */
-               PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
-               PCI_VENDOR_ID_MAINPINE, 0x0300,
-               0, 0, pbn_b0_4_115200 },
-       {       /* RockForceDUO+ */
-               PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
-               PCI_VENDOR_ID_MAINPINE, 0x0400,
-               0, 0, pbn_b0_2_115200 },
-       {       /* RockForceQUATRO+ */
-               PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
-               PCI_VENDOR_ID_MAINPINE, 0x0500,
-               0, 0, pbn_b0_4_115200 },
-       {       /* RockForce+ */
-               PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
-               PCI_VENDOR_ID_MAINPINE, 0x0600,
-               0, 0, pbn_b0_2_115200 },
-       {       /* RockForce+ */
-               PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
-               PCI_VENDOR_ID_MAINPINE, 0x0700,
-               0, 0, pbn_b0_4_115200 },
-       {       /* RockForceOCTO+ */
-               PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
-               PCI_VENDOR_ID_MAINPINE, 0x0800,
-               0, 0, pbn_b0_8_115200 },
-       {       /* RockForceDUO+ */
-               PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
-               PCI_VENDOR_ID_MAINPINE, 0x0C00,
-               0, 0, pbn_b0_2_115200 },
-       {       /* RockForceQUARTRO+ */
-               PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
-               PCI_VENDOR_ID_MAINPINE, 0x0D00,
-               0, 0, pbn_b0_4_115200 },
-       {       /* RockForceOCTO+ */
-               PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
-               PCI_VENDOR_ID_MAINPINE, 0x1D00,
-               0, 0, pbn_b0_8_115200 },
-       {       /* RockForceD1 */
-               PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
-               PCI_VENDOR_ID_MAINPINE, 0x2000,
-               0, 0, pbn_b0_1_115200 },
-       {       /* RockForceF1 */
-               PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
-               PCI_VENDOR_ID_MAINPINE, 0x2100,
-               0, 0, pbn_b0_1_115200 },
-       {       /* RockForceD2 */
-               PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
-               PCI_VENDOR_ID_MAINPINE, 0x2200,
-               0, 0, pbn_b0_2_115200 },
-       {       /* RockForceF2 */
-               PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
-               PCI_VENDOR_ID_MAINPINE, 0x2300,
-               0, 0, pbn_b0_2_115200 },
-       {       /* RockForceD4 */
-               PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
-               PCI_VENDOR_ID_MAINPINE, 0x2400,
-               0, 0, pbn_b0_4_115200 },
-       {       /* RockForceF4 */
-               PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
-               PCI_VENDOR_ID_MAINPINE, 0x2500,
-               0, 0, pbn_b0_4_115200 },
-       {       /* RockForceD8 */
-               PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
-               PCI_VENDOR_ID_MAINPINE, 0x2600,
-               0, 0, pbn_b0_8_115200 },
-       {       /* RockForceF8 */
-               PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
-               PCI_VENDOR_ID_MAINPINE, 0x2700,
-               0, 0, pbn_b0_8_115200 },
-       {       /* IQ Express D1 */
-               PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
-               PCI_VENDOR_ID_MAINPINE, 0x3000,
-               0, 0, pbn_b0_1_115200 },
-       {       /* IQ Express F1 */
-               PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
-               PCI_VENDOR_ID_MAINPINE, 0x3100,
-               0, 0, pbn_b0_1_115200 },
-       {       /* IQ Express D2 */
-               PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
-               PCI_VENDOR_ID_MAINPINE, 0x3200,
-               0, 0, pbn_b0_2_115200 },
-       {       /* IQ Express F2 */
-               PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
-               PCI_VENDOR_ID_MAINPINE, 0x3300,
-               0, 0, pbn_b0_2_115200 },
-       {       /* IQ Express D4 */
-               PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
-               PCI_VENDOR_ID_MAINPINE, 0x3400,
-               0, 0, pbn_b0_4_115200 },
-       {       /* IQ Express F4 */
-               PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
-               PCI_VENDOR_ID_MAINPINE, 0x3500,
-               0, 0, pbn_b0_4_115200 },
-       {       /* IQ Express D8 */
-               PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
-               PCI_VENDOR_ID_MAINPINE, 0x3C00,
-               0, 0, pbn_b0_8_115200 },
-       {       /* IQ Express F8 */
-               PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
-               PCI_VENDOR_ID_MAINPINE, 0x3D00,
-               0, 0, pbn_b0_8_115200 },
-
-
-       /*
-        * PA Semi PA6T-1682M on-chip UART
-        */
-       {       PCI_VENDOR_ID_PASEMI, 0xa004,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_pasemi_1682M },
-
-       /*
-        * National Instruments
-        */
-       {       PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PCI23216,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_b1_16_115200 },
-       {       PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PCI2328,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_b1_8_115200 },
-       {       PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PCI2324,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_b1_bt_4_115200 },
-       {       PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PCI2322,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_b1_bt_2_115200 },
-       {       PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PCI2324I,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_b1_bt_4_115200 },
-       {       PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PCI2322I,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_b1_bt_2_115200 },
-       {       PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PXI8420_23216,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_b1_16_115200 },
-       {       PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PXI8420_2328,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_b1_8_115200 },
-       {       PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PXI8420_2324,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_b1_bt_4_115200 },
-       {       PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PXI8420_2322,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_b1_bt_2_115200 },
-       {       PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PXI8422_2324,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_b1_bt_4_115200 },
-       {       PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PXI8422_2322,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_b1_bt_2_115200 },
-       {       PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PXI8430_2322,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_ni8430_2 },
-       {       PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PCI8430_2322,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_ni8430_2 },
-       {       PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PXI8430_2324,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_ni8430_4 },
-       {       PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PCI8430_2324,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_ni8430_4 },
-       {       PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PXI8430_2328,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_ni8430_8 },
-       {       PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PCI8430_2328,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_ni8430_8 },
-       {       PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PXI8430_23216,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_ni8430_16 },
-       {       PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PCI8430_23216,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_ni8430_16 },
-       {       PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PXI8432_2322,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_ni8430_2 },
-       {       PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PCI8432_2322,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_ni8430_2 },
-       {       PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PXI8432_2324,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_ni8430_4 },
-       {       PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PCI8432_2324,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_ni8430_4 },
-
-       /*
-       * ADDI-DATA GmbH communication cards <info@addi-data.com>
-       */
-       {       PCI_VENDOR_ID_ADDIDATA,
-               PCI_DEVICE_ID_ADDIDATA_APCI7500,
-               PCI_ANY_ID,
-               PCI_ANY_ID,
-               0,
-               0,
-               pbn_b0_4_115200 },
-
-       {       PCI_VENDOR_ID_ADDIDATA,
-               PCI_DEVICE_ID_ADDIDATA_APCI7420,
-               PCI_ANY_ID,
-               PCI_ANY_ID,
-               0,
-               0,
-               pbn_b0_2_115200 },
-
-       {       PCI_VENDOR_ID_ADDIDATA,
-               PCI_DEVICE_ID_ADDIDATA_APCI7300,
-               PCI_ANY_ID,
-               PCI_ANY_ID,
-               0,
-               0,
-               pbn_b0_1_115200 },
-
-       {       PCI_VENDOR_ID_ADDIDATA_OLD,
-               PCI_DEVICE_ID_ADDIDATA_APCI7800,
-               PCI_ANY_ID,
-               PCI_ANY_ID,
-               0,
-               0,
-               pbn_b1_8_115200 },
-
-       {       PCI_VENDOR_ID_ADDIDATA,
-               PCI_DEVICE_ID_ADDIDATA_APCI7500_2,
-               PCI_ANY_ID,
-               PCI_ANY_ID,
-               0,
-               0,
-               pbn_b0_4_115200 },
-
-       {       PCI_VENDOR_ID_ADDIDATA,
-               PCI_DEVICE_ID_ADDIDATA_APCI7420_2,
-               PCI_ANY_ID,
-               PCI_ANY_ID,
-               0,
-               0,
-               pbn_b0_2_115200 },
-
-       {       PCI_VENDOR_ID_ADDIDATA,
-               PCI_DEVICE_ID_ADDIDATA_APCI7300_2,
-               PCI_ANY_ID,
-               PCI_ANY_ID,
-               0,
-               0,
-               pbn_b0_1_115200 },
-
-       {       PCI_VENDOR_ID_ADDIDATA,
-               PCI_DEVICE_ID_ADDIDATA_APCI7500_3,
-               PCI_ANY_ID,
-               PCI_ANY_ID,
-               0,
-               0,
-               pbn_b0_4_115200 },
-
-       {       PCI_VENDOR_ID_ADDIDATA,
-               PCI_DEVICE_ID_ADDIDATA_APCI7420_3,
-               PCI_ANY_ID,
-               PCI_ANY_ID,
-               0,
-               0,
-               pbn_b0_2_115200 },
-
-       {       PCI_VENDOR_ID_ADDIDATA,
-               PCI_DEVICE_ID_ADDIDATA_APCI7300_3,
-               PCI_ANY_ID,
-               PCI_ANY_ID,
-               0,
-               0,
-               pbn_b0_1_115200 },
-
-       {       PCI_VENDOR_ID_ADDIDATA,
-               PCI_DEVICE_ID_ADDIDATA_APCI7800_3,
-               PCI_ANY_ID,
-               PCI_ANY_ID,
-               0,
-               0,
-               pbn_b0_8_115200 },
-
-       {       PCI_VENDOR_ID_ADDIDATA,
-               PCI_DEVICE_ID_ADDIDATA_APCIe7500,
-               PCI_ANY_ID,
-               PCI_ANY_ID,
-               0,
-               0,
-               pbn_ADDIDATA_PCIe_4_3906250 },
-
-       {       PCI_VENDOR_ID_ADDIDATA,
-               PCI_DEVICE_ID_ADDIDATA_APCIe7420,
-               PCI_ANY_ID,
-               PCI_ANY_ID,
-               0,
-               0,
-               pbn_ADDIDATA_PCIe_2_3906250 },
-
-       {       PCI_VENDOR_ID_ADDIDATA,
-               PCI_DEVICE_ID_ADDIDATA_APCIe7300,
-               PCI_ANY_ID,
-               PCI_ANY_ID,
-               0,
-               0,
-               pbn_ADDIDATA_PCIe_1_3906250 },
-
-       {       PCI_VENDOR_ID_ADDIDATA,
-               PCI_DEVICE_ID_ADDIDATA_APCIe7800,
-               PCI_ANY_ID,
-               PCI_ANY_ID,
-               0,
-               0,
-               pbn_ADDIDATA_PCIe_8_3906250 },
-
-       {       PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9835,
-               PCI_VENDOR_ID_IBM, 0x0299,
-               0, 0, pbn_b0_bt_2_115200 },
-
-       {       PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9901,
-               0xA000, 0x1000,
-               0, 0, pbn_b0_1_115200 },
-
-       /* the 9901 is a rebranded 9912 */
-       {       PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9912,
-               0xA000, 0x1000,
-               0, 0, pbn_b0_1_115200 },
-
-       {       PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9922,
-               0xA000, 0x1000,
-               0, 0, pbn_b0_1_115200 },
-
-       {       PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9904,
-               0xA000, 0x1000,
-               0, 0, pbn_b0_1_115200 },
-
-       {       PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9900,
-               0xA000, 0x1000,
-               0, 0, pbn_b0_1_115200 },
-
-       {       PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9900,
-               0xA000, 0x3002,
-               0, 0, pbn_NETMOS9900_2s_115200 },
-
-       /*
-        * Best Connectivity and Rosewill PCI Multi I/O cards
-        */
-
-       {       PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9865,
-               0xA000, 0x1000,
-               0, 0, pbn_b0_1_115200 },
-
-       {       PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9865,
-               0xA000, 0x3002,
-               0, 0, pbn_b0_bt_2_115200 },
-
-       {       PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9865,
-               0xA000, 0x3004,
-               0, 0, pbn_b0_bt_4_115200 },
-       /* Intel CE4100 */
-       {       PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_CE4100_UART,
-               PCI_ANY_ID,  PCI_ANY_ID, 0, 0,
-               pbn_ce4100_1_115200 },
-
-       /*
-        * Cronyx Omega PCI
-        */
-       {       PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_CRONYX_OMEGA,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_omegapci },
-
-       /*
-        * These entries match devices with class COMMUNICATION_SERIAL,
-        * COMMUNICATION_MODEM or COMMUNICATION_MULTISERIAL
-        */
-       {       PCI_ANY_ID, PCI_ANY_ID,
-               PCI_ANY_ID, PCI_ANY_ID,
-               PCI_CLASS_COMMUNICATION_SERIAL << 8,
-               0xffff00, pbn_default },
-       {       PCI_ANY_ID, PCI_ANY_ID,
-               PCI_ANY_ID, PCI_ANY_ID,
-               PCI_CLASS_COMMUNICATION_MODEM << 8,
-               0xffff00, pbn_default },
-       {       PCI_ANY_ID, PCI_ANY_ID,
-               PCI_ANY_ID, PCI_ANY_ID,
-               PCI_CLASS_COMMUNICATION_MULTISERIAL << 8,
-               0xffff00, pbn_default },
-       { 0, }
-};
-
-static pci_ers_result_t serial8250_io_error_detected(struct pci_dev *dev,
-                                               pci_channel_state_t state)
-{
-       struct serial_private *priv = pci_get_drvdata(dev);
-
-       if (state == pci_channel_io_perm_failure)
-               return PCI_ERS_RESULT_DISCONNECT;
-
-       if (priv)
-               pciserial_suspend_ports(priv);
-
-       pci_disable_device(dev);
-
-       return PCI_ERS_RESULT_NEED_RESET;
-}
-
-static pci_ers_result_t serial8250_io_slot_reset(struct pci_dev *dev)
-{
-       int rc;
-
-       rc = pci_enable_device(dev);
-
-       if (rc)
-               return PCI_ERS_RESULT_DISCONNECT;
-
-       pci_restore_state(dev);
-       pci_save_state(dev);
-
-       return PCI_ERS_RESULT_RECOVERED;
-}
-
-static void serial8250_io_resume(struct pci_dev *dev)
-{
-       struct serial_private *priv = pci_get_drvdata(dev);
-
-       if (priv)
-               pciserial_resume_ports(priv);
-}
-
-static struct pci_error_handlers serial8250_err_handler = {
-       .error_detected = serial8250_io_error_detected,
-       .slot_reset = serial8250_io_slot_reset,
-       .resume = serial8250_io_resume,
-};
-
-static struct pci_driver serial_pci_driver = {
-       .name           = "serial",
-       .probe          = pciserial_init_one,
-       .remove         = __devexit_p(pciserial_remove_one),
-#ifdef CONFIG_PM
-       .suspend        = pciserial_suspend_one,
-       .resume         = pciserial_resume_one,
-#endif
-       .id_table       = serial_pci_tbl,
-       .err_handler    = &serial8250_err_handler,
-};
-
-static int __init serial8250_pci_init(void)
-{
-       return pci_register_driver(&serial_pci_driver);
-}
-
-static void __exit serial8250_pci_exit(void)
-{
-       pci_unregister_driver(&serial_pci_driver);
-}
-
-module_init(serial8250_pci_init);
-module_exit(serial8250_pci_exit);
-
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("Generic 8250/16x50 PCI serial probe module");
-MODULE_DEVICE_TABLE(pci, serial_pci_tbl);
diff --git a/drivers/tty/serial/8250_pnp.c b/drivers/tty/serial/8250_pnp.c
deleted file mode 100644 (file)
index a2f2365..0000000
+++ /dev/null
@@ -1,524 +0,0 @@
-/*
- *  Probe module for 8250/16550-type ISAPNP serial ports.
- *
- *  Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o.
- *
- *  Copyright (C) 2001 Russell King, All Rights Reserved.
- *
- *  Ported to the Linux PnP Layer - (C) Adam Belay.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License.
- */
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/pci.h>
-#include <linux/pnp.h>
-#include <linux/string.h>
-#include <linux/kernel.h>
-#include <linux/serial_core.h>
-#include <linux/bitops.h>
-
-#include <asm/byteorder.h>
-
-#include "8250.h"
-
-#define UNKNOWN_DEV 0x3000
-
-
-static const struct pnp_device_id pnp_dev_table[] = {
-       /* Archtek America Corp. */
-       /* Archtek SmartLink Modem 3334BT Plug & Play */
-       {       "AAC000F",              0       },
-       /* Anchor Datacomm BV */
-       /* SXPro 144 External Data Fax Modem Plug & Play */
-       {       "ADC0001",              0       },
-       /* SXPro 288 External Data Fax Modem Plug & Play */
-       {       "ADC0002",              0       },
-       /* PROLiNK 1456VH ISA PnP K56flex Fax Modem */
-       {       "AEI0250",              0       },
-       /* Actiontec ISA PNP 56K X2 Fax Modem */
-       {       "AEI1240",              0       },
-       /* Rockwell 56K ACF II Fax+Data+Voice Modem */
-       {       "AKY1021",              0 /*SPCI_FL_NO_SHIRQ*/  },
-       /* AZT3005 PnP SOUND DEVICE */
-       {       "AZT4001",              0       },
-       /* Best Data Products Inc. Smart One 336F PnP Modem */
-       {       "BDP3336",              0       },
-       /*  Boca Research */
-       /* Boca Complete Ofc Communicator 14.4 Data-FAX */
-       {       "BRI0A49",              0       },
-       /* Boca Research 33,600 ACF Modem */
-       {       "BRI1400",              0       },
-       /* Boca 33.6 Kbps Internal FD34FSVD */
-       {       "BRI3400",              0       },
-       /* Boca 33.6 Kbps Internal FD34FSVD */
-       {       "BRI0A49",              0       },
-       /* Best Data Products Inc. Smart One 336F PnP Modem */
-       {       "BDP3336",              0       },
-       /* Computer Peripherals Inc */
-       /* EuroViVa CommCenter-33.6 SP PnP */
-       {       "CPI4050",              0       },
-       /* Creative Labs */
-       /* Creative Labs Phone Blaster 28.8 DSVD PnP Voice */
-       {       "CTL3001",              0       },
-       /* Creative Labs Modem Blaster 28.8 DSVD PnP Voice */
-       {       "CTL3011",              0       },
-       /* Davicom ISA 33.6K Modem */
-       {       "DAV0336",              0       },
-       /* Creative */
-       /* Creative Modem Blaster Flash56 DI5601-1 */
-       {       "DMB1032",              0       },
-       /* Creative Modem Blaster V.90 DI5660 */
-       {       "DMB2001",              0       },
-       /* E-Tech */
-       /* E-Tech CyberBULLET PC56RVP */
-       {       "ETT0002",              0       },
-       /* FUJITSU */
-       /* Fujitsu 33600 PnP-I2 R Plug & Play */
-       {       "FUJ0202",              0       },
-       /* Fujitsu FMV-FX431 Plug & Play */
-       {       "FUJ0205",              0       },
-       /* Fujitsu 33600 PnP-I4 R Plug & Play */
-       {       "FUJ0206",              0       },
-       /* Fujitsu Fax Voice 33600 PNP-I5 R Plug & Play */
-       {       "FUJ0209",              0       },
-       /* Archtek America Corp. */
-       /* Archtek SmartLink Modem 3334BT Plug & Play */
-       {       "GVC000F",              0       },
-       /* Archtek SmartLink Modem 3334BRV 33.6K Data Fax Voice */
-       {       "GVC0303",              0       },
-       /* Hayes */
-       /* Hayes Optima 288 V.34-V.FC + FAX + Voice Plug & Play */
-       {       "HAY0001",              0       },
-       /* Hayes Optima 336 V.34 + FAX + Voice PnP */
-       {       "HAY000C",              0       },
-       /* Hayes Optima 336B V.34 + FAX + Voice PnP */
-       {       "HAY000D",              0       },
-       /* Hayes Accura 56K Ext Fax Modem PnP */
-       {       "HAY5670",              0       },
-       /* Hayes Accura 56K Ext Fax Modem PnP */
-       {       "HAY5674",              0       },
-       /* Hayes Accura 56K Fax Modem PnP */
-       {       "HAY5675",              0       },
-       /* Hayes 288, V.34 + FAX */
-       {       "HAYF000",              0       },
-       /* Hayes Optima 288 V.34 + FAX + Voice, Plug & Play */
-       {       "HAYF001",              0       },
-       /* IBM */
-       /* IBM Thinkpad 701 Internal Modem Voice */
-       {       "IBM0033",              0       },
-       /* Intermec */
-       /* Intermec CV60 touchscreen port */
-       {       "PNP4972",              0       },
-       /* Intertex */
-       /* Intertex 28k8 33k6 Voice EXT PnP */
-       {       "IXDC801",              0       },
-       /* Intertex 33k6 56k Voice EXT PnP */
-       {       "IXDC901",              0       },
-       /* Intertex 28k8 33k6 Voice SP EXT PnP */
-       {       "IXDD801",              0       },
-       /* Intertex 33k6 56k Voice SP EXT PnP */
-       {       "IXDD901",              0       },
-       /* Intertex 28k8 33k6 Voice SP INT PnP */
-       {       "IXDF401",              0       },
-       /* Intertex 28k8 33k6 Voice SP EXT PnP */
-       {       "IXDF801",              0       },
-       /* Intertex 33k6 56k Voice SP EXT PnP */
-       {       "IXDF901",              0       },
-       /* Kortex International */
-       /* KORTEX 28800 Externe PnP */
-       {       "KOR4522",              0       },
-       /* KXPro 33.6 Vocal ASVD PnP */
-       {       "KORF661",              0       },
-       /* Lasat */
-       /* LASAT Internet 33600 PnP */
-       {       "LAS4040",              0       },
-       /* Lasat Safire 560 PnP */
-       {       "LAS4540",              0       },
-       /* Lasat Safire 336  PnP */
-       {       "LAS5440",              0       },
-       /* Microcom, Inc. */
-       /* Microcom TravelPorte FAST V.34 Plug & Play */
-       {       "MNP0281",              0       },
-       /* Microcom DeskPorte V.34 FAST or FAST+ Plug & Play */
-       {       "MNP0336",              0       },
-       /* Microcom DeskPorte FAST EP 28.8 Plug & Play */
-       {       "MNP0339",              0       },
-       /* Microcom DeskPorte 28.8P Plug & Play */
-       {       "MNP0342",              0       },
-       /* Microcom DeskPorte FAST ES 28.8 Plug & Play */
-       {       "MNP0500",              0       },
-       /* Microcom DeskPorte FAST ES 28.8 Plug & Play */
-       {       "MNP0501",              0       },
-       /* Microcom DeskPorte 28.8S Internal Plug & Play */
-       {       "MNP0502",              0       },
-       /* Motorola */
-       /* Motorola BitSURFR Plug & Play */
-       {       "MOT1105",              0       },
-       /* Motorola TA210 Plug & Play */
-       {       "MOT1111",              0       },
-       /* Motorola HMTA 200 (ISDN) Plug & Play */
-       {       "MOT1114",              0       },
-       /* Motorola BitSURFR Plug & Play */
-       {       "MOT1115",              0       },
-       /* Motorola Lifestyle 28.8 Internal */
-       {       "MOT1190",              0       },
-       /* Motorola V.3400 Plug & Play */
-       {       "MOT1501",              0       },
-       /* Motorola Lifestyle 28.8 V.34 Plug & Play */
-       {       "MOT1502",              0       },
-       /* Motorola Power 28.8 V.34 Plug & Play */
-       {       "MOT1505",              0       },
-       /* Motorola ModemSURFR External 28.8 Plug & Play */
-       {       "MOT1509",              0       },
-       /* Motorola Premier 33.6 Desktop Plug & Play */
-       {       "MOT150A",              0       },
-       /* Motorola VoiceSURFR 56K External PnP */
-       {       "MOT150F",              0       },
-       /* Motorola ModemSURFR 56K External PnP */
-       {       "MOT1510",              0       },
-       /* Motorola ModemSURFR 56K Internal PnP */
-       {       "MOT1550",              0       },
-       /* Motorola ModemSURFR Internal 28.8 Plug & Play */
-       {       "MOT1560",              0       },
-       /* Motorola Premier 33.6 Internal Plug & Play */
-       {       "MOT1580",              0       },
-       /* Motorola OnlineSURFR 28.8 Internal Plug & Play */
-       {       "MOT15B0",              0       },
-       /* Motorola VoiceSURFR 56K Internal PnP */
-       {       "MOT15F0",              0       },
-       /* Com 1 */
-       /*  Deskline K56 Phone System PnP */
-       {       "MVX00A1",              0       },
-       /* PC Rider K56 Phone System PnP */
-       {       "MVX00F2",              0       },
-       /* NEC 98NOTE SPEAKER PHONE FAX MODEM(33600bps) */
-       {       "nEC8241",              0       },
-       /* Pace 56 Voice Internal Plug & Play Modem */
-       {       "PMC2430",              0       },
-       /* Generic */
-       /* Generic standard PC COM port  */
-       {       "PNP0500",              0       },
-       /* Generic 16550A-compatible COM port */
-       {       "PNP0501",              0       },
-       /* Compaq 14400 Modem */
-       {       "PNPC000",              0       },
-       /* Compaq 2400/9600 Modem */
-       {       "PNPC001",              0       },
-       /* Dial-Up Networking Serial Cable between 2 PCs */
-       {       "PNPC031",              0       },
-       /* Dial-Up Networking Parallel Cable between 2 PCs */
-       {       "PNPC032",              0       },
-       /* Standard 9600 bps Modem */
-       {       "PNPC100",              0       },
-       /* Standard 14400 bps Modem */
-       {       "PNPC101",              0       },
-       /*  Standard 28800 bps Modem*/
-       {       "PNPC102",              0       },
-       /*  Standard Modem*/
-       {       "PNPC103",              0       },
-       /*  Standard 9600 bps Modem*/
-       {       "PNPC104",              0       },
-       /*  Standard 14400 bps Modem*/
-       {       "PNPC105",              0       },
-       /*  Standard 28800 bps Modem*/
-       {       "PNPC106",              0       },
-       /*  Standard Modem */
-       {       "PNPC107",              0       },
-       /* Standard 9600 bps Modem */
-       {       "PNPC108",              0       },
-       /* Standard 14400 bps Modem */
-       {       "PNPC109",              0       },
-       /* Standard 28800 bps Modem */
-       {       "PNPC10A",              0       },
-       /* Standard Modem */
-       {       "PNPC10B",              0       },
-       /* Standard 9600 bps Modem */
-       {       "PNPC10C",              0       },
-       /* Standard 14400 bps Modem */
-       {       "PNPC10D",              0       },
-       /* Standard 28800 bps Modem */
-       {       "PNPC10E",              0       },
-       /* Standard Modem */
-       {       "PNPC10F",              0       },
-       /* Standard PCMCIA Card Modem */
-       {       "PNP2000",              0       },
-       /* Rockwell */
-       /* Modular Technology */
-       /* Rockwell 33.6 DPF Internal PnP */
-       /* Modular Technology 33.6 Internal PnP */
-       {       "ROK0030",              0       },
-       /* Kortex International */
-       /* KORTEX 14400 Externe PnP */
-       {       "ROK0100",              0       },
-       /* Rockwell 28.8 */
-       {       "ROK4120",              0       },
-       /* Viking Components, Inc */
-       /* Viking 28.8 INTERNAL Fax+Data+Voice PnP */
-       {       "ROK4920",              0       },
-       /* Rockwell */
-       /* British Telecom */
-       /* Modular Technology */
-       /* Rockwell 33.6 DPF External PnP */
-       /* BT Prologue 33.6 External PnP */
-       /* Modular Technology 33.6 External PnP */
-       {       "RSS00A0",              0       },
-       /* Viking 56K FAX INT */
-       {       "RSS0262",              0       },
-       /* K56 par,VV,Voice,Speakphone,AudioSpan,PnP */
-       {       "RSS0250",              0       },
-       /* SupraExpress 28.8 Data/Fax PnP modem */
-       {       "SUP1310",              0       },
-       /* SupraExpress 336i PnP Voice Modem */
-       {       "SUP1381",              0       },
-       /* SupraExpress 33.6 Data/Fax PnP modem */
-       {       "SUP1421",              0       },
-       /* SupraExpress 33.6 Data/Fax PnP modem */
-       {       "SUP1590",              0       },
-       /* SupraExpress 336i Sp ASVD */
-       {       "SUP1620",              0       },
-       /* SupraExpress 33.6 Data/Fax PnP modem */
-       {       "SUP1760",              0       },
-       /* SupraExpress 56i Sp Intl */
-       {       "SUP2171",              0       },
-       /* Phoebe Micro */
-       /* Phoebe Micro 33.6 Data Fax 1433VQH Plug & Play */
-       {       "TEX0011",              0       },
-       /* Archtek America Corp. */
-       /* Archtek SmartLink Modem 3334BT Plug & Play */
-       {       "UAC000F",              0       },
-       /* 3Com Corp. */
-       /* Gateway Telepath IIvi 33.6 */
-       {       "USR0000",              0       },
-       /* U.S. Robotics Sporster 33.6K Fax INT PnP */
-       {       "USR0002",              0       },
-       /*  Sportster Vi 14.4 PnP FAX Voicemail */
-       {       "USR0004",              0       },
-       /* U.S. Robotics 33.6K Voice INT PnP */
-       {       "USR0006",              0       },
-       /* U.S. Robotics 33.6K Voice EXT PnP */
-       {       "USR0007",              0       },
-       /* U.S. Robotics Courier V.Everything INT PnP */
-       {       "USR0009",              0       },
-       /* U.S. Robotics 33.6K Voice INT PnP */
-       {       "USR2002",              0       },
-       /* U.S. Robotics 56K Voice INT PnP */
-       {       "USR2070",              0       },
-       /* U.S. Robotics 56K Voice EXT PnP */
-       {       "USR2080",              0       },
-       /* U.S. Robotics 56K FAX INT */
-       {       "USR3031",              0       },
-       /* U.S. Robotics 56K FAX INT */
-       {       "USR3050",              0       },
-       /* U.S. Robotics 56K Voice INT PnP */
-       {       "USR3070",              0       },
-       /* U.S. Robotics 56K Voice EXT PnP */
-       {       "USR3080",              0       },
-       /* U.S. Robotics 56K Voice INT PnP */
-       {       "USR3090",              0       },
-       /* U.S. Robotics 56K Message  */
-       {       "USR9100",              0       },
-       /* U.S. Robotics 56K FAX EXT PnP*/
-       {       "USR9160",              0       },
-       /* U.S. Robotics 56K FAX INT PnP*/
-       {       "USR9170",              0       },
-       /* U.S. Robotics 56K Voice EXT PnP*/
-       {       "USR9180",              0       },
-       /* U.S. Robotics 56K Voice INT PnP*/
-       {       "USR9190",              0       },
-       /* Wacom tablets */
-       {       "WACFXXX",              0       },
-       /* Compaq touchscreen */
-       {       "FPI2002",              0 },
-       /* Fujitsu Stylistic touchscreens */
-       {       "FUJ02B2",              0 },
-       {       "FUJ02B3",              0 },
-       /* Fujitsu Stylistic LT touchscreens */
-       {       "FUJ02B4",              0 },
-       /* Passive Fujitsu Stylistic touchscreens */
-       {       "FUJ02B6",              0 },
-       {       "FUJ02B7",              0 },
-       {       "FUJ02B8",              0 },
-       {       "FUJ02B9",              0 },
-       {       "FUJ02BC",              0 },
-       /* Fujitsu Wacom Tablet PC device */
-       {       "FUJ02E5",              0       },
-       /* Fujitsu P-series tablet PC device */
-       {       "FUJ02E6",              0       },
-       /* Fujitsu Wacom 2FGT Tablet PC device */
-       {       "FUJ02E7",              0       },
-       /* Fujitsu Wacom 1FGT Tablet PC device */
-       {       "FUJ02E9",              0       },
-       /*
-        * LG C1 EXPRESS DUAL (C1-PB11A3) touch screen (actually a FUJ02E6 in
-        * disguise)
-        */
-       {       "LTS0001",              0       },
-       /* Rockwell's (PORALiNK) 33600 INT PNP */
-       {       "WCI0003",              0       },
-       /* Unknown PnP modems */
-       {       "PNPCXXX",              UNKNOWN_DEV     },
-       /* More unknown PnP modems */
-       {       "PNPDXXX",              UNKNOWN_DEV     },
-       {       "",                     0       }
-};
-
-MODULE_DEVICE_TABLE(pnp, pnp_dev_table);
-
-static char *modem_names[] __devinitdata = {
-       "MODEM", "Modem", "modem", "FAX", "Fax", "fax",
-       "56K", "56k", "K56", "33.6", "28.8", "14.4",
-       "33,600", "28,800", "14,400", "33.600", "28.800", "14.400",
-       "33600", "28800", "14400", "V.90", "V.34", "V.32", NULL
-};
-
-static int __devinit check_name(char *name)
-{
-       char **tmp;
-
-       for (tmp = modem_names; *tmp; tmp++)
-               if (strstr(name, *tmp))
-                       return 1;
-
-       return 0;
-}
-
-static int __devinit check_resources(struct pnp_dev *dev)
-{
-       resource_size_t base[] = {0x2f8, 0x3f8, 0x2e8, 0x3e8};
-       int i;
-
-       for (i = 0; i < ARRAY_SIZE(base); i++) {
-               if (pnp_possible_config(dev, IORESOURCE_IO, base[i], 8))
-                       return 1;
-       }
-
-       return 0;
-}
-
-/*
- * Given a complete unknown PnP device, try to use some heuristics to
- * detect modems. Currently use such heuristic set:
- *     - dev->name or dev->bus->name must contain "modem" substring;
- *     - device must have only one IO region (8 byte long) with base address
- *       0x2e8, 0x3e8, 0x2f8 or 0x3f8.
- *
- * Such detection looks very ugly, but can detect at least some of numerous
- * PnP modems, alternatively we must hardcode all modems in pnp_devices[]
- * table.
- */
-static int __devinit serial_pnp_guess_board(struct pnp_dev *dev, int *flags)
-{
-       if (!(check_name(pnp_dev_name(dev)) ||
-               (dev->card && check_name(dev->card->name))))
-                       return -ENODEV;
-
-       if (check_resources(dev))
-               return 0;
-
-       return -ENODEV;
-}
-
-static int __devinit
-serial_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id *dev_id)
-{
-       struct uart_port port;
-       int ret, line, flags = dev_id->driver_data;
-
-       if (flags & UNKNOWN_DEV) {
-               ret = serial_pnp_guess_board(dev, &flags);
-               if (ret < 0)
-                       return ret;
-       }
-
-       memset(&port, 0, sizeof(struct uart_port));
-       if (pnp_irq_valid(dev, 0))
-               port.irq = pnp_irq(dev, 0);
-       if (pnp_port_valid(dev, 0)) {
-               port.iobase = pnp_port_start(dev, 0);
-               port.iotype = UPIO_PORT;
-       } else if (pnp_mem_valid(dev, 0)) {
-               port.mapbase = pnp_mem_start(dev, 0);
-               port.iotype = UPIO_MEM;
-               port.flags = UPF_IOREMAP;
-       } else
-               return -ENODEV;
-
-#ifdef SERIAL_DEBUG_PNP
-       printk(KERN_DEBUG
-               "Setup PNP port: port %x, mem 0x%lx, irq %d, type %d\n",
-                      port.iobase, port.mapbase, port.irq, port.iotype);
-#endif
-
-       port.flags |= UPF_SKIP_TEST | UPF_BOOT_AUTOCONF;
-       if (pnp_irq_flags(dev, 0) & IORESOURCE_IRQ_SHAREABLE)
-               port.flags |= UPF_SHARE_IRQ;
-       port.uartclk = 1843200;
-       port.dev = &dev->dev;
-
-       line = serial8250_register_port(&port);
-       if (line < 0)
-               return -ENODEV;
-
-       pnp_set_drvdata(dev, (void *)((long)line + 1));
-       return 0;
-}
-
-static void __devexit serial_pnp_remove(struct pnp_dev *dev)
-{
-       long line = (long)pnp_get_drvdata(dev);
-       if (line)
-               serial8250_unregister_port(line - 1);
-}
-
-#ifdef CONFIG_PM
-static int serial_pnp_suspend(struct pnp_dev *dev, pm_message_t state)
-{
-       long line = (long)pnp_get_drvdata(dev);
-
-       if (!line)
-               return -ENODEV;
-       serial8250_suspend_port(line - 1);
-       return 0;
-}
-
-static int serial_pnp_resume(struct pnp_dev *dev)
-{
-       long line = (long)pnp_get_drvdata(dev);
-
-       if (!line)
-               return -ENODEV;
-       serial8250_resume_port(line - 1);
-       return 0;
-}
-#else
-#define serial_pnp_suspend NULL
-#define serial_pnp_resume NULL
-#endif /* CONFIG_PM */
-
-static struct pnp_driver serial_pnp_driver = {
-       .name           = "serial",
-       .probe          = serial_pnp_probe,
-       .remove         = __devexit_p(serial_pnp_remove),
-       .suspend        = serial_pnp_suspend,
-       .resume         = serial_pnp_resume,
-       .id_table       = pnp_dev_table,
-};
-
-static int __init serial8250_pnp_init(void)
-{
-       return pnp_register_driver(&serial_pnp_driver);
-}
-
-static void __exit serial8250_pnp_exit(void)
-{
-       pnp_unregister_driver(&serial_pnp_driver);
-}
-
-module_init(serial8250_pnp_init);
-module_exit(serial8250_pnp_exit);
-
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("Generic 8250/16x50 PnP serial driver");
index aca2386..2de9924 100644 (file)
@@ -5,279 +5,7 @@
 menu "Serial drivers"
        depends on HAS_IOMEM
 
-#
-# The new 8250/16550 serial drivers
-config SERIAL_8250
-       tristate "8250/16550 and compatible serial support"
-       select SERIAL_CORE
-       ---help---
-         This selects whether you want to include the driver for the standard
-         serial ports.  The standard answer is Y.  People who might say N
-         here are those that are setting up dedicated Ethernet WWW/FTP
-         servers, or users that have one of the various bus mice instead of a
-         serial mouse and don't intend to use their machine's standard serial
-         port for anything.  (Note that the Cyclades and Stallion multi
-         serial port drivers do not need this driver built in for them to
-         work.)
-
-         To compile this driver as a module, choose M here: the
-         module will be called 8250.
-         [WARNING: Do not compile this driver as a module if you are using
-         non-standard serial ports, since the configuration information will
-         be lost when the driver is unloaded.  This limitation may be lifted
-         in the future.]
-
-         BTW1: If you have a mouseman serial mouse which is not recognized by
-         the X window system, try running gpm first.
-
-         BTW2: If you intend to use a software modem (also called Winmodem)
-         under Linux, forget it.  These modems are crippled and require
-         proprietary drivers which are only available under Windows.
-
-         Most people will say Y or M here, so that they can use serial mice,
-         modems and similar devices connecting to the standard serial ports.
-
-config SERIAL_8250_CONSOLE
-       bool "Console on 8250/16550 and compatible serial port"
-       depends on SERIAL_8250=y
-       select SERIAL_CORE_CONSOLE
-       ---help---
-         If you say Y here, it will be possible to use a serial port as the
-         system console (the system console is the device which receives all
-         kernel messages and warnings and which allows logins in single user
-         mode). This could be useful if some terminal or printer is connected
-         to that serial port.
-
-         Even if you say Y here, the currently visible virtual console
-         (/dev/tty0) will still be used as the system console by default, but
-         you can alter that using a kernel command line option such as
-         "console=ttyS1". (Try "man bootparam" or see the documentation of
-         your boot loader (grub or lilo or loadlin) about how to pass options
-         to the kernel at boot time.)
-
-         If you don't have a VGA card installed and you say Y here, the
-         kernel will automatically use the first serial line, /dev/ttyS0, as
-         system console.
-
-         You can set that using a kernel command line option such as
-         "console=uart8250,io,0x3f8,9600n8"
-         "console=uart8250,mmio,0xff5e0000,115200n8".
-         and it will switch to normal serial console when the corresponding 
-         port is ready.
-         "earlycon=uart8250,io,0x3f8,9600n8"
-         "earlycon=uart8250,mmio,0xff5e0000,115200n8".
-         it will not only setup early console.
-
-         If unsure, say N.
-
-config FIX_EARLYCON_MEM
-       bool
-       depends on X86
-       default y
-
-config SERIAL_8250_GSC
-       tristate
-       depends on SERIAL_8250 && GSC
-       default SERIAL_8250
-
-config SERIAL_8250_PCI
-       tristate "8250/16550 PCI device support" if EXPERT
-       depends on SERIAL_8250 && PCI
-       default SERIAL_8250
-       help
-         This builds standard PCI serial support. You may be able to
-         disable this feature if you only need legacy serial support.
-         Saves about 9K.
-
-config SERIAL_8250_PNP
-       tristate "8250/16550 PNP device support" if EXPERT
-       depends on SERIAL_8250 && PNP
-       default SERIAL_8250
-       help
-         This builds standard PNP serial support. You may be able to
-         disable this feature if you only need legacy serial support.
-
-config SERIAL_8250_FSL
-       bool
-       depends on SERIAL_8250_CONSOLE && PPC_UDBG_16550
-       default PPC
-
-config SERIAL_8250_HP300
-       tristate
-       depends on SERIAL_8250 && HP300
-       default SERIAL_8250
-
-config SERIAL_8250_CS
-       tristate "8250/16550 PCMCIA device support"
-       depends on PCMCIA && SERIAL_8250
-       ---help---
-         Say Y here to enable support for 16-bit PCMCIA serial devices,
-         including serial port cards, modems, and the modem functions of
-         multi-function Ethernet/modem cards. (PCMCIA- or PC-cards are
-         credit-card size devices often used with laptops.)
-
-         To compile this driver as a module, choose M here: the
-         module will be called serial_cs.
-
-         If unsure, say N.
-
-config SERIAL_8250_NR_UARTS
-       int "Maximum number of 8250/16550 serial ports"
-       depends on SERIAL_8250
-       default "4"
-       help
-         Set this to the number of serial ports you want the driver
-         to support.  This includes any ports discovered via ACPI or
-         PCI enumeration and any ports that may be added at run-time
-         via hot-plug, or any ISA multi-port serial cards.
-
-config SERIAL_8250_RUNTIME_UARTS
-       int "Number of 8250/16550 serial ports to register at runtime"
-       depends on SERIAL_8250
-       range 0 SERIAL_8250_NR_UARTS
-       default "4"
-       help
-         Set this to the maximum number of serial ports you want
-         the kernel to register at boot time.  This can be overridden
-         with the module parameter "nr_uarts", or boot-time parameter
-         8250.nr_uarts
-
-config SERIAL_8250_EXTENDED
-       bool "Extended 8250/16550 serial driver options"
-       depends on SERIAL_8250
-       help
-         If you wish to use any non-standard features of the standard "dumb"
-         driver, say Y here. This includes HUB6 support, shared serial
-         interrupts, special multiport support, support for more than the
-         four COM 1/2/3/4 boards, etc.
-
-         Note that the answer to this question won't directly affect the
-         kernel: saying N will just cause the configurator to skip all
-         the questions about serial driver options. If unsure, say N.
-
-config SERIAL_8250_MANY_PORTS
-       bool "Support more than 4 legacy serial ports"
-       depends on SERIAL_8250_EXTENDED && !IA64
-       help
-         Say Y here if you have dumb serial boards other than the four
-         standard COM 1/2/3/4 ports. This may happen if you have an AST
-         FourPort, Accent Async, Boca (read the Boca mini-HOWTO, available
-         from <http://www.tldp.org/docs.html#howto>), or other custom
-         serial port hardware which acts similar to standard serial port
-         hardware. If you only use the standard COM 1/2/3/4 ports, you can
-         say N here to save some memory. You can also say Y if you have an
-         "intelligent" multiport card such as Cyclades, Digiboards, etc.
-
-#
-# Multi-port serial cards
-#
-
-config SERIAL_8250_FOURPORT
-       tristate "Support Fourport cards"
-       depends on SERIAL_8250 != n && ISA && SERIAL_8250_MANY_PORTS
-       help
-         Say Y here if you have an AST FourPort serial board.
-
-         To compile this driver as a module, choose M here: the module
-         will be called 8250_fourport.
-
-config SERIAL_8250_ACCENT
-       tristate "Support Accent cards"
-       depends on SERIAL_8250 != n && ISA && SERIAL_8250_MANY_PORTS
-       help
-         Say Y here if you have an Accent Async serial board.
-
-         To compile this driver as a module, choose M here: the module
-         will be called 8250_accent.
-
-config SERIAL_8250_BOCA
-       tristate "Support Boca cards"
-       depends on SERIAL_8250 != n && ISA && SERIAL_8250_MANY_PORTS
-       help
-         Say Y here if you have a Boca serial board.  Please read the Boca
-         mini-HOWTO, available from <http://www.tldp.org/docs.html#howto>
-
-         To compile this driver as a module, choose M here: the module
-         will be called 8250_boca.
-
-config SERIAL_8250_EXAR_ST16C554
-       tristate "Support Exar ST16C554/554D Quad UART"
-       depends on SERIAL_8250 != n && ISA && SERIAL_8250_MANY_PORTS
-       help
-         The Uplogix Envoy TU301 uses this Exar Quad UART.  If you are
-         tinkering with your Envoy TU301, or have a machine with this UART,
-         say Y here.
-
-         To compile this driver as a module, choose M here: the module
-         will be called 8250_exar_st16c554.
-
-config SERIAL_8250_HUB6
-       tristate "Support Hub6 cards"
-       depends on SERIAL_8250 != n && ISA && SERIAL_8250_MANY_PORTS
-       help
-         Say Y here if you have a HUB6 serial board.
-
-         To compile this driver as a module, choose M here: the module
-         will be called 8250_hub6.
-
-config SERIAL_8250_SHARE_IRQ
-       bool "Support for sharing serial interrupts"
-       depends on SERIAL_8250_EXTENDED
-       help
-         Some serial boards have hardware support which allows multiple dumb
-         serial ports on the same board to share a single IRQ. To enable
-         support for this in the serial driver, say Y here.
-
-config SERIAL_8250_DETECT_IRQ
-       bool "Autodetect IRQ on standard ports (unsafe)"
-       depends on SERIAL_8250_EXTENDED
-       help
-         Say Y here if you want the kernel to try to guess which IRQ
-         to use for your serial port.
-
-         This is considered unsafe; it is far better to configure the IRQ in
-         a boot script using the setserial command.
-
-         If unsure, say N.
-
-config SERIAL_8250_RSA
-       bool "Support RSA serial ports"
-       depends on SERIAL_8250_EXTENDED
-       help
-         ::: To be written :::
-
-config SERIAL_8250_MCA
-       tristate "Support 8250-type ports on MCA buses"
-       depends on SERIAL_8250 != n && MCA
-       help
-         Say Y here if you have a MCA serial ports.
-
-         To compile this driver as a module, choose M here: the module
-         will be called 8250_mca.
-
-config SERIAL_8250_ACORN
-       tristate "Acorn expansion card serial port support"
-       depends on ARCH_ACORN && SERIAL_8250
-       help
-         If you have an Atomwide Serial card or Serial Port card for an Acorn
-         system, say Y to this option.  The driver can handle 1, 2, or 3 port
-         cards.  If unsure, say N.
-
-config SERIAL_8250_RM9K
-       bool "Support for MIPS RM9xxx integrated serial port"
-       depends on SERIAL_8250 != n && SERIAL_RM9000
-       select SERIAL_8250_SHARE_IRQ
-       help
-         Selecting this option will add support for the integrated serial
-         port hardware found on MIPS RM9122 and similar processors.
-         If unsure, say N.
-
-config SERIAL_8250_DW
-       tristate "Support for Synopsys DesignWare 8250 quirks"
-       depends on SERIAL_8250 && OF
-       help
-         Selecting this option will enable handling of the extra features
-         present in the Synopsys DesignWare APB UART.
+source "drivers/tty/serial/8250/Kconfig"
 
 comment "Non-8250 serial port support"
 
@@ -536,15 +264,6 @@ config SERIAL_MAX3107
        help
          MAX3107 chip support
 
-config SERIAL_MAX3107_AAVA
-       tristate "MAX3107 AAVA platform support"
-       depends on X86_MRST && SERIAL_MAX3107 && GPIOLIB
-       select SERIAL_CORE
-       help
-         Support for the MAX3107 chip configuration found on the AAVA
-         platform. Includes the extra initialisation and GPIO support
-         neded for this device.
-
 config SERIAL_DZ
        bool "DECstation DZ serial driver"
        depends on MACH_DECSTATION && 32BIT
index f5b01f2..fef32e1 100644 (file)
@@ -14,22 +14,9 @@ obj-$(CONFIG_SERIAL_SUNZILOG) += sunzilog.o
 obj-$(CONFIG_SERIAL_SUNSU) += sunsu.o
 obj-$(CONFIG_SERIAL_SUNSAB) += sunsab.o
 
-obj-$(CONFIG_SERIAL_8250) += 8250.o
-obj-$(CONFIG_SERIAL_8250_PNP) += 8250_pnp.o
-obj-$(CONFIG_SERIAL_8250_GSC) += 8250_gsc.o
-obj-$(CONFIG_SERIAL_8250_PCI) += 8250_pci.o
-obj-$(CONFIG_SERIAL_8250_HP300) += 8250_hp300.o
-obj-$(CONFIG_SERIAL_8250_CS) += serial_cs.o
-obj-$(CONFIG_SERIAL_8250_ACORN) += 8250_acorn.o
-obj-$(CONFIG_SERIAL_8250_CONSOLE) += 8250_early.o
-obj-$(CONFIG_SERIAL_8250_FOURPORT) += 8250_fourport.o
-obj-$(CONFIG_SERIAL_8250_ACCENT) += 8250_accent.o
-obj-$(CONFIG_SERIAL_8250_BOCA) += 8250_boca.o
-obj-$(CONFIG_SERIAL_8250_EXAR_ST16C554) += 8250_exar_st16c554.o
-obj-$(CONFIG_SERIAL_8250_HUB6) += 8250_hub6.o
-obj-$(CONFIG_SERIAL_8250_MCA) += 8250_mca.o
-obj-$(CONFIG_SERIAL_8250_FSL) += 8250_fsl.o
-obj-$(CONFIG_SERIAL_8250_DW) += 8250_dw.o
+# Now bring in any enabled 8250/16450/16550 type drivers.
+obj-$(CONFIG_SERIAL_8250) += 8250/
+
 obj-$(CONFIG_SERIAL_AMBA_PL010) += amba-pl010.o
 obj-$(CONFIG_SERIAL_AMBA_PL011) += amba-pl011.o
 obj-$(CONFIG_SERIAL_CLPS711X) += clps711x.o
@@ -42,7 +29,6 @@ obj-$(CONFIG_SERIAL_BFIN_SPORT) += bfin_sport_uart.o
 obj-$(CONFIG_SERIAL_SAMSUNG) += samsung.o
 obj-$(CONFIG_SERIAL_MAX3100) += max3100.o
 obj-$(CONFIG_SERIAL_MAX3107) += max3107.o
-obj-$(CONFIG_SERIAL_MAX3107_AAVA) += max3107-aava.o
 obj-$(CONFIG_SERIAL_IP22_ZILOG) += ip22zilog.o
 obj-$(CONFIG_SERIAL_MUX) += mux.o
 obj-$(CONFIG_SERIAL_68328) += 68328serial.o
index 9ae0240..6800f5f 100644 (file)
@@ -159,6 +159,7 @@ struct uart_amba_port {
        unsigned int            fifosize;       /* vendor-specific */
        unsigned int            lcrh_tx;        /* vendor-specific */
        unsigned int            lcrh_rx;        /* vendor-specific */
+       unsigned int            old_cr;         /* state during shutdown */
        bool                    autorts;
        char                    type[12];
        bool                    interrupt_may_hang; /* vendor-specific */
@@ -1411,7 +1412,9 @@ static int pl011_startup(struct uart_port *port)
        while (readw(uap->port.membase + UART01x_FR) & UART01x_FR_BUSY)
                barrier();
 
-       cr = UART01x_CR_UARTEN | UART011_CR_RXE | UART011_CR_TXE;
+       /* restore RTS and DTR */
+       cr = uap->old_cr & (UART011_CR_RTS | UART011_CR_DTR);
+       cr |= UART01x_CR_UARTEN | UART011_CR_RXE | UART011_CR_TXE;
        writew(cr, uap->port.membase + UART011_CR);
 
        /* Clear pending error interrupts */
@@ -1469,6 +1472,7 @@ static void pl011_shutdown_channel(struct uart_amba_port *uap,
 static void pl011_shutdown(struct uart_port *port)
 {
        struct uart_amba_port *uap = (struct uart_amba_port *)port;
+       unsigned int cr;
 
        /*
         * disable all interrupts
@@ -1488,9 +1492,16 @@ static void pl011_shutdown(struct uart_port *port)
 
        /*
         * disable the port
+        * disable the port. It should not disable RTS and DTR.
+        * Also RTS and DTR state should be preserved to restore
+        * it during startup().
         */
        uap->autorts = false;
-       writew(UART01x_CR_UARTEN | UART011_CR_TXE, uap->port.membase + UART011_CR);
+       cr = readw(uap->port.membase + UART011_CR);
+       uap->old_cr = cr;
+       cr &= UART011_CR_RTS | UART011_CR_DTR;
+       cr |= UART01x_CR_UARTEN | UART011_CR_TXE;
+       writew(cr, uap->port.membase + UART011_CR);
 
        /*
         * disable break condition and fifos
@@ -1740,9 +1751,19 @@ pl011_console_write(struct console *co, const char *s, unsigned int count)
 {
        struct uart_amba_port *uap = amba_ports[co->index];
        unsigned int status, old_cr, new_cr;
+       unsigned long flags;
+       int locked = 1;
 
        clk_enable(uap->clk);
 
+       local_irq_save(flags);
+       if (uap->port.sysrq)
+               locked = 0;
+       else if (oops_in_progress)
+               locked = spin_trylock(&uap->port.lock);
+       else
+               spin_lock(&uap->port.lock);
+
        /*
         *      First save the CR then disable the interrupts
         */
@@ -1762,6 +1783,10 @@ pl011_console_write(struct console *co, const char *s, unsigned int count)
        } while (status & UART01x_FR_BUSY);
        writew(old_cr, uap->port.membase + UART011_CR);
 
+       if (locked)
+               spin_unlock(&uap->port.lock);
+       local_irq_restore(flags);
+
        clk_disable(uap->clk);
 }
 
@@ -1905,6 +1930,7 @@ static int pl011_probe(struct amba_device *dev, const struct amba_id *id)
        uap->vendor = vendor;
        uap->lcrh_rx = vendor->lcrh_rx;
        uap->lcrh_tx = vendor->lcrh_tx;
+       uap->old_cr = 0;
        uap->fifosize = vendor->fifosize;
        uap->interrupt_may_hang = vendor->interrupt_may_hang;
        uap->port.dev = &dev->dev;
index 7c867a0..7545fe1 100644 (file)
@@ -251,6 +251,7 @@ static void jsm_io_resume(struct pci_dev *pdev)
        struct jsm_board *brd = pci_get_drvdata(pdev);
 
        pci_restore_state(pdev);
+       pci_save_state(pdev);
 
        jsm_uart_port_init(brd);
 }
diff --git a/drivers/tty/serial/max3107-aava.c b/drivers/tty/serial/max3107-aava.c
deleted file mode 100644 (file)
index aae772a..0000000
+++ /dev/null
@@ -1,344 +0,0 @@
-/*
- *  max3107.c - spi uart protocol driver for Maxim 3107
- *  Based on max3100.c
- *     by Christian Pellegrin <chripell@evolware.org>
- *  and        max3110.c
- *     by Feng Tang <feng.tang@intel.com>
- *
- *  Copyright (C) Aavamobile 2009
- *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- */
-
-#include <linux/delay.h>
-#include <linux/device.h>
-#include <linux/serial_core.h>
-#include <linux/serial.h>
-#include <linux/spi/spi.h>
-#include <linux/freezer.h>
-#include <linux/platform_device.h>
-#include <linux/gpio.h>
-#include <linux/sfi.h>
-#include <linux/module.h>
-#include <asm/mrst.h>
-#include "max3107.h"
-
-/* GPIO direction to input function */
-static int max3107_gpio_direction_in(struct gpio_chip *chip, unsigned offset)
-{
-       struct max3107_port *s = container_of(chip, struct max3107_port, chip);
-       u16 buf[1];             /* Buffer for SPI transfer */
-
-       if (offset >= MAX3107_GPIO_COUNT) {
-               dev_err(&s->spi->dev, "Invalid GPIO\n");
-               return -EINVAL;
-       }
-
-       /* Read current GPIO configuration register */
-       buf[0] = MAX3107_GPIOCFG_REG;
-       /* Perform SPI transfer */
-       if (max3107_rw(s, (u8 *)buf, (u8 *)buf, 2)) {
-               dev_err(&s->spi->dev, "SPI transfer GPIO read failed\n");
-               return -EIO;
-       }
-       buf[0] &= MAX3107_SPI_RX_DATA_MASK;
-
-       /* Set GPIO to input */
-       buf[0] &= ~(0x0001 << offset);
-
-       /* Write new GPIO configuration register value */
-       buf[0] |= (MAX3107_WRITE_BIT | MAX3107_GPIOCFG_REG);
-       /* Perform SPI transfer */
-       if (max3107_rw(s, (u8 *)buf, NULL, 2)) {
-               dev_err(&s->spi->dev, "SPI transfer GPIO write failed\n");
-               return -EIO;
-       }
-       return 0;
-}
-
-/* GPIO direction to output function */
-static int max3107_gpio_direction_out(struct gpio_chip *chip, unsigned offset,
-                                       int value)
-{
-       struct max3107_port *s = container_of(chip, struct max3107_port, chip);
-       u16 buf[2];     /* Buffer for SPI transfers */
-
-       if (offset >= MAX3107_GPIO_COUNT) {
-               dev_err(&s->spi->dev, "Invalid GPIO\n");
-               return -EINVAL;
-       }
-
-       /* Read current GPIO configuration and data registers */
-       buf[0] = MAX3107_GPIOCFG_REG;
-       buf[1] = MAX3107_GPIODATA_REG;
-       /* Perform SPI transfer */
-       if (max3107_rw(s, (u8 *)buf, (u8 *)buf, 4)) {
-               dev_err(&s->spi->dev, "SPI transfer gpio failed\n");
-               return -EIO;
-       }
-       buf[0] &= MAX3107_SPI_RX_DATA_MASK;
-       buf[1] &= MAX3107_SPI_RX_DATA_MASK;
-
-       /* Set GPIO to output */
-       buf[0] |= (0x0001 << offset);
-       /* Set value */
-       if (value)
-               buf[1] |= (0x0001 << offset);
-       else
-               buf[1] &= ~(0x0001 << offset);
-
-       /* Write new GPIO configuration and data register values */
-       buf[0] |= (MAX3107_WRITE_BIT | MAX3107_GPIOCFG_REG);
-       buf[1] |= (MAX3107_WRITE_BIT | MAX3107_GPIODATA_REG);
-       /* Perform SPI transfer */
-       if (max3107_rw(s, (u8 *)buf, NULL, 4)) {
-               dev_err(&s->spi->dev,
-                       "SPI transfer for GPIO conf data w failed\n");
-               return -EIO;
-       }
-       return 0;
-}
-
-/* GPIO value query function */
-static int max3107_gpio_get(struct gpio_chip *chip, unsigned offset)
-{
-       struct max3107_port *s = container_of(chip, struct max3107_port, chip);
-       u16 buf[1];     /* Buffer for SPI transfer */
-
-       if (offset >= MAX3107_GPIO_COUNT) {
-               dev_err(&s->spi->dev, "Invalid GPIO\n");
-               return -EINVAL;
-       }
-
-       /* Read current GPIO data register */
-       buf[0] = MAX3107_GPIODATA_REG;
-       /* Perform SPI transfer */
-       if (max3107_rw(s, (u8 *)buf, (u8 *)buf, 2)) {
-               dev_err(&s->spi->dev, "SPI transfer GPIO data r failed\n");
-               return -EIO;
-       }
-       buf[0] &= MAX3107_SPI_RX_DATA_MASK;
-
-       /* Return value */
-       return buf[0] & (0x0001 << offset);
-}
-
-/* GPIO value set function */
-static void max3107_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
-{
-       struct max3107_port *s = container_of(chip, struct max3107_port, chip);
-       u16 buf[2];     /* Buffer for SPI transfers */
-
-       if (offset >= MAX3107_GPIO_COUNT) {
-               dev_err(&s->spi->dev, "Invalid GPIO\n");
-               return;
-       }
-
-       /* Read current GPIO configuration registers*/
-       buf[0] = MAX3107_GPIODATA_REG;
-       buf[1] = MAX3107_GPIOCFG_REG;
-       /* Perform SPI transfer */
-       if (max3107_rw(s, (u8 *)buf, (u8 *)buf, 4)) {
-               dev_err(&s->spi->dev,
-                       "SPI transfer for GPIO data and config read failed\n");
-               return;
-       }
-       buf[0] &= MAX3107_SPI_RX_DATA_MASK;
-       buf[1] &= MAX3107_SPI_RX_DATA_MASK;
-
-       if (!(buf[1] & (0x0001 << offset))) {
-               /* Configured as input, can't set value */
-               dev_warn(&s->spi->dev,
-                               "Trying to set value for input GPIO\n");
-               return;
-       }
-
-       /* Set value */
-       if (value)
-               buf[0] |= (0x0001 << offset);
-       else
-               buf[0] &= ~(0x0001 << offset);
-
-       /* Write new GPIO data register value */
-       buf[0] |= (MAX3107_WRITE_BIT | MAX3107_GPIODATA_REG);
-       /* Perform SPI transfer */
-       if (max3107_rw(s, (u8 *)buf, NULL, 2))
-               dev_err(&s->spi->dev, "SPI transfer GPIO data w failed\n");
-}
-
-/* GPIO chip data */
-static struct gpio_chip max3107_gpio_chip = {
-       .owner                  = THIS_MODULE,
-       .direction_input        = max3107_gpio_direction_in,
-       .direction_output       = max3107_gpio_direction_out,
-       .get                    = max3107_gpio_get,
-       .set                    = max3107_gpio_set,
-       .can_sleep              = 1,
-       .base                   = MAX3107_GPIO_BASE,
-       .ngpio                  = MAX3107_GPIO_COUNT,
-};
-
-/**
- *     max3107_aava_reset      -       reset on AAVA systems
- *     @spi: The SPI device we are probing
- *
- *     Reset the device ready for probing.
- */
-
-static int max3107_aava_reset(struct spi_device *spi)
-{
-       /* Reset the chip */
-       if (gpio_request(MAX3107_RESET_GPIO, "max3107")) {
-               pr_err("Requesting RESET GPIO failed\n");
-               return -EIO;
-       }
-       if (gpio_direction_output(MAX3107_RESET_GPIO, 0)) {
-               pr_err("Setting RESET GPIO to 0 failed\n");
-               gpio_free(MAX3107_RESET_GPIO);
-               return -EIO;
-       }
-       msleep(MAX3107_RESET_DELAY);
-       if (gpio_direction_output(MAX3107_RESET_GPIO, 1)) {
-               pr_err("Setting RESET GPIO to 1 failed\n");
-               gpio_free(MAX3107_RESET_GPIO);
-               return -EIO;
-       }
-       gpio_free(MAX3107_RESET_GPIO);
-       msleep(MAX3107_WAKEUP_DELAY);
-       return 0;
-}
-
-static int max3107_aava_configure(struct max3107_port *s)
-{
-       int retval;
-
-       /* Initialize GPIO chip data */
-       s->chip = max3107_gpio_chip;
-       s->chip.label = s->spi->modalias;
-       s->chip.dev = &s->spi->dev;
-
-       /* Add GPIO chip */
-       retval = gpiochip_add(&s->chip);
-       if (retval) {
-               dev_err(&s->spi->dev, "Adding GPIO chip failed\n");
-               return retval;
-       }
-
-       /* Temporary fix for EV2 boot problems, set modem reset to 0 */
-       max3107_gpio_direction_out(&s->chip, 3, 0);
-       return 0;
-}
-
-#if 0
-/* This will get enabled once we have the board stuff merged for this
-   specific case */
-
-static const struct baud_table brg13_ext[] = {
-       { 300,    MAX3107_BRG13_B300 },
-       { 600,    MAX3107_BRG13_B600 },
-       { 1200,   MAX3107_BRG13_B1200 },
-       { 2400,   MAX3107_BRG13_B2400 },
-       { 4800,   MAX3107_BRG13_B4800 },
-       { 9600,   MAX3107_BRG13_B9600 },
-       { 19200,  MAX3107_BRG13_B19200 },
-       { 57600,  MAX3107_BRG13_B57600 },
-       { 115200, MAX3107_BRG13_B115200 },
-       { 230400, MAX3107_BRG13_B230400 },
-       { 460800, MAX3107_BRG13_B460800 },
-       { 921600, MAX3107_BRG13_B921600 },
-       { 0, 0 }
-};
-
-static void max3107_aava_init(struct max3107_port *s)
-{
-       /*override for AAVA SC specific*/
-       if (mrst_platform_id() == MRST_PLATFORM_AAVA_SC) {
-               if (get_koski_build_id() <= KOSKI_EV2)
-                       if (s->ext_clk) {
-                               s->brg_cfg = MAX3107_BRG13_B9600;
-                               s->baud_tbl = (struct baud_table *)brg13_ext;
-                       }
-       }
-}
-#endif
-
-static int __devexit max3107_aava_remove(struct spi_device *spi)
-{
-       struct max3107_port *s = dev_get_drvdata(&spi->dev);
-
-       /* Remove GPIO chip */
-       if (gpiochip_remove(&s->chip))
-               dev_warn(&spi->dev, "Removing GPIO chip failed\n");
-
-       /* Then do the default remove */
-       return max3107_remove(spi);
-}
-
-/* Platform data */
-static struct max3107_plat aava_plat_data = {
-       .loopback               = 0,
-       .ext_clk                = 1,
-/*     .init                   = max3107_aava_init, */
-       .configure              = max3107_aava_configure,
-       .hw_suspend             = max3107_hw_susp,
-       .polled_mode            = 0,
-       .poll_time              = 0,
-};
-
-
-static int __devinit max3107_probe_aava(struct spi_device *spi)
-{
-       int err = max3107_aava_reset(spi);
-       if (err < 0)
-               return err;
-       return max3107_probe(spi, &aava_plat_data);
-}
-
-/* Spi driver data */
-static struct spi_driver max3107_driver = {
-       .driver = {
-               .name           = "aava-max3107",
-               .owner          = THIS_MODULE,
-       },
-       .probe          = max3107_probe_aava,
-       .remove         = __devexit_p(max3107_aava_remove),
-       .suspend        = max3107_suspend,
-       .resume         = max3107_resume,
-};
-
-/* Driver init function */
-static int __init max3107_init(void)
-{
-       return spi_register_driver(&max3107_driver);
-}
-
-/* Driver exit function */
-static void __exit max3107_exit(void)
-{
-       spi_unregister_driver(&max3107_driver);
-}
-
-module_init(max3107_init);
-module_exit(max3107_exit);
-
-MODULE_DESCRIPTION("MAX3107 driver");
-MODULE_AUTHOR("Aavamobile");
-MODULE_ALIAS("spi:aava-max3107");
-MODULE_LICENSE("GPL v2");
index d192dcb..f809041 100644 (file)
 
 #define DEFAULT_CLK_SPEED 48000000 /* 48Mhz*/
 
+/* SCR register bitmasks */
+#define OMAP_UART_SCR_RX_TRIG_GRANU1_MASK              (1 << 7)
+
+/* FCR register bitmasks */
+#define OMAP_UART_FCR_RX_FIFO_TRIG_SHIFT               6
+#define OMAP_UART_FCR_RX_FIFO_TRIG_MASK                        (0x3 << 6)
+
 static struct uart_omap_port *ui[OMAP_MAX_HSUART_PORTS];
 
 /* Forward declaration of functions */
@@ -129,6 +136,7 @@ static void serial_omap_enable_ms(struct uart_port *port)
 static void serial_omap_stop_tx(struct uart_port *port)
 {
        struct uart_omap_port *up = (struct uart_omap_port *)port;
+       struct omap_uart_port_info *pdata = up->pdev->dev.platform_data;
 
        if (up->use_dma &&
                up->uart_dma.tx_dma_channel != OMAP_UART_DMA_CH_FREE) {
@@ -151,6 +159,9 @@ static void serial_omap_stop_tx(struct uart_port *port)
                serial_out(up, UART_IER, up->ier);
        }
 
+       if (!up->use_dma && pdata->set_forceidle)
+               pdata->set_forceidle(up->pdev);
+
        pm_runtime_mark_last_busy(&up->pdev->dev);
        pm_runtime_put_autosuspend(&up->pdev->dev);
 }
@@ -279,6 +290,7 @@ static inline void serial_omap_enable_ier_thri(struct uart_omap_port *up)
 static void serial_omap_start_tx(struct uart_port *port)
 {
        struct uart_omap_port *up = (struct uart_omap_port *)port;
+       struct omap_uart_port_info *pdata = up->pdev->dev.platform_data;
        struct circ_buf *xmit;
        unsigned int start;
        int ret = 0;
@@ -286,6 +298,8 @@ static void serial_omap_start_tx(struct uart_port *port)
        if (!up->use_dma) {
                pm_runtime_get_sync(&up->pdev->dev);
                serial_omap_enable_ier_thri(up);
+               if (pdata->set_noidle)
+                       pdata->set_noidle(up->pdev);
                pm_runtime_mark_last_busy(&up->pdev->dev);
                pm_runtime_put_autosuspend(&up->pdev->dev);
                return;
@@ -726,8 +740,7 @@ serial_omap_set_termios(struct uart_port *port, struct ktermios *termios,
        quot = serial_omap_get_divisor(port, baud);
 
        /* calculate wakeup latency constraint */
-       up->calc_latency = (1000000 * up->port.fifosize) /
-                               (1000 * baud / 8);
+       up->calc_latency = (USEC_PER_SEC * up->port.fifosize) / (baud / 8);
        up->latency = up->calc_latency;
        schedule_work(&up->qos_work);
 
@@ -811,14 +824,21 @@ serial_omap_set_termios(struct uart_port *port, struct ktermios *termios,
        up->mcr = serial_in(up, UART_MCR);
        serial_out(up, UART_MCR, up->mcr | UART_MCR_TCRTLR);
        /* FIFO ENABLE, DMA MODE */
-       serial_out(up, UART_FCR, up->fcr);
-       serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B);
+
+       up->scr |= OMAP_UART_SCR_RX_TRIG_GRANU1_MASK;
 
        if (up->use_dma) {
                serial_out(up, UART_TI752_TLR, 0);
-               up->scr |= (UART_FCR_TRIGGER_4 | UART_FCR_TRIGGER_8);
+               up->scr |= UART_FCR_TRIGGER_4;
+       } else {
+               /* Set receive FIFO threshold to 1 byte */
+               up->fcr &= ~OMAP_UART_FCR_RX_FIFO_TRIG_MASK;
+               up->fcr |= (0x1 << OMAP_UART_FCR_RX_FIFO_TRIG_SHIFT);
        }
 
+       serial_out(up, UART_FCR, up->fcr);
+       serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B);
+
        serial_out(up, UART_OMAP_SCR, up->scr);
 
        serial_out(up, UART_EFR, up->efr);
@@ -1160,7 +1180,7 @@ static struct uart_driver serial_omap_reg = {
        .cons           = OMAP_CONSOLE,
 };
 
-#ifdef CONFIG_SUSPEND
+#ifdef CONFIG_PM_SLEEP
 static int serial_omap_suspend(struct device *dev)
 {
        struct uart_omap_port *up = dev_get_drvdata(dev);
@@ -1521,6 +1541,7 @@ static void serial_omap_mdr1_errataset(struct uart_omap_port *up, u8 mdr1)
        }
 }
 
+#ifdef CONFIG_PM_RUNTIME
 static void serial_omap_restore_context(struct uart_omap_port *up)
 {
        if (up->errata & UART_ERRATA_i202_MDR1_ACCESS)
@@ -1550,7 +1571,6 @@ static void serial_omap_restore_context(struct uart_omap_port *up)
                serial_out(up, UART_OMAP_MDR1, up->mdr1);
 }
 
-#ifdef CONFIG_PM_RUNTIME
 static int serial_omap_runtime_suspend(struct device *dev)
 {
        struct uart_omap_port *up = dev_get_drvdata(dev);
index f96f37b..c55e5fb 100644 (file)
@@ -1593,7 +1593,8 @@ static struct s3c24xx_serial_drv_data s5pv210_serial_drv_data = {
 #define S5PV210_SERIAL_DRV_DATA        (kernel_ulong_t)NULL
 #endif
 
-#ifdef CONFIG_CPU_EXYNOS4210
+#if defined(CONFIG_CPU_EXYNOS4210) || defined(CONFIG_SOC_EXYNOS4212) || \
+       defined(CONFIG_SOC_EXYNOS4412) || defined(CONFIG_SOC_EXYNOS5250)
 static struct s3c24xx_serial_drv_data exynos4210_serial_drv_data = {
        .info = &(struct s3c24xx_uart_info) {
                .name           = "Samsung Exynos4 UART",
index c7bf31a..1305618 100644 (file)
@@ -2348,11 +2348,11 @@ int uart_add_one_port(struct uart_driver *drv, struct uart_port *uport)
         */
        tty_dev = tty_register_device(drv->tty_driver, uport->line, uport->dev);
        if (likely(!IS_ERR(tty_dev))) {
-               device_init_wakeup(tty_dev, 1);
-               device_set_wakeup_enable(tty_dev, 0);
-       } else
+               device_set_wakeup_capable(tty_dev, 1);
+       } else {
                printk(KERN_ERR "Cannot register tty device on line %d\n",
                       uport->line);
+       }
 
        /*
         * Ensure UPF_DEAD is not set.
diff --git a/drivers/tty/serial/serial_cs.c b/drivers/tty/serial/serial_cs.c
deleted file mode 100644 (file)
index 8609060..0000000
+++ /dev/null
@@ -1,870 +0,0 @@
-/*======================================================================
-
-    A driver for PCMCIA serial devices
-
-    serial_cs.c 1.134 2002/05/04 05:48:53
-
-    The contents of this file are subject to the Mozilla Public
-    License Version 1.1 (the "License"); you may not use this file
-    except in compliance with the License. You may obtain a copy of
-    the License at http://www.mozilla.org/MPL/
-
-    Software distributed under the License is distributed on an "AS
-    IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
-    implied. See the License for the specific language governing
-    rights and limitations under the License.
-
-    The initial developer of the original code is David A. Hinds
-    <dahinds@users.sourceforge.net>.  Portions created by David A. Hinds
-    are Copyright (C) 1999 David A. Hinds.  All Rights Reserved.
-
-    Alternatively, the contents of this file may be used under the
-    terms of the GNU General Public License version 2 (the "GPL"), in which
-    case the provisions of the GPL are applicable instead of the
-    above.  If you wish to allow the use of your version of this file
-    only under the terms of the GPL and not to allow others to use
-    your version of this file under the MPL, indicate your decision
-    by deleting the provisions above and replace them with the notice
-    and other provisions required by the GPL.  If you do not delete
-    the provisions above, a recipient may use your version of this
-    file under either the MPL or the GPL.
-    
-======================================================================*/
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/ptrace.h>
-#include <linux/slab.h>
-#include <linux/string.h>
-#include <linux/timer.h>
-#include <linux/serial_core.h>
-#include <linux/delay.h>
-#include <linux/major.h>
-#include <asm/io.h>
-#include <asm/system.h>
-
-#include <pcmcia/cistpl.h>
-#include <pcmcia/ciscode.h>
-#include <pcmcia/ds.h>
-#include <pcmcia/cisreg.h>
-
-#include "8250.h"
-
-
-/*====================================================================*/
-
-/* Parameters that can be set with 'insmod' */
-
-/* Enable the speaker? */
-static int do_sound = 1;
-/* Skip strict UART tests? */
-static int buggy_uart;
-
-module_param(do_sound, int, 0444);
-module_param(buggy_uart, int, 0444);
-
-/*====================================================================*/
-
-/* Table of multi-port card ID's */
-
-struct serial_quirk {
-       unsigned int manfid;
-       unsigned int prodid;
-       int multi;              /* 1 = multifunction, > 1 = # ports */
-       void (*config)(struct pcmcia_device *);
-       void (*setup)(struct pcmcia_device *, struct uart_port *);
-       void (*wakeup)(struct pcmcia_device *);
-       int (*post)(struct pcmcia_device *);
-};
-
-struct serial_info {
-       struct pcmcia_device    *p_dev;
-       int                     ndev;
-       int                     multi;
-       int                     slave;
-       int                     manfid;
-       int                     prodid;
-       int                     c950ctrl;
-       int                     line[4];
-       const struct serial_quirk *quirk;
-};
-
-struct serial_cfg_mem {
-       tuple_t tuple;
-       cisparse_t parse;
-       u_char buf[256];
-};
-
-/*
- * vers_1 5.0, "Brain Boxes", "2-Port RS232 card", "r6"
- * manfid 0x0160, 0x0104
- * This card appears to have a 14.7456MHz clock.
- */
-/* Generic Modem: MD55x (GPRS/EDGE) have
- * Elan VPU16551 UART with 14.7456MHz oscillator
- * manfid 0x015D, 0x4C45
- */
-static void quirk_setup_brainboxes_0104(struct pcmcia_device *link, struct uart_port *port)
-{
-       port->uartclk = 14745600;
-}
-
-static int quirk_post_ibm(struct pcmcia_device *link)
-{
-       u8 val;
-       int ret;
-
-       ret = pcmcia_read_config_byte(link, 0x800, &val);
-       if (ret)
-               goto failed;
-
-       ret = pcmcia_write_config_byte(link, 0x800, val | 1);
-       if (ret)
-               goto failed;
-       return 0;
-
- failed:
-       return -ENODEV;
-}
-
-/*
- * Nokia cards are not really multiport cards.  Shouldn't this
- * be handled by setting the quirk entry .multi = 0 | 1 ?
- */
-static void quirk_config_nokia(struct pcmcia_device *link)
-{
-       struct serial_info *info = link->priv;
-
-       if (info->multi > 1)
-               info->multi = 1;
-}
-
-static void quirk_wakeup_oxsemi(struct pcmcia_device *link)
-{
-       struct serial_info *info = link->priv;
-
-       if (info->c950ctrl)
-               outb(12, info->c950ctrl + 1);
-}
-
-/* request_region? oxsemi branch does no request_region too... */
-/*
- * This sequence is needed to properly initialize MC45 attached to OXCF950.
- * I tried decreasing these msleep()s, but it worked properly (survived
- * 1000 stop/start operations) with these timeouts (or bigger).
- */
-static void quirk_wakeup_possio_gcc(struct pcmcia_device *link)
-{
-       struct serial_info *info = link->priv;
-       unsigned int ctrl = info->c950ctrl;
-
-       outb(0xA, ctrl + 1);
-       msleep(100);
-       outb(0xE, ctrl + 1);
-       msleep(300);
-       outb(0xC, ctrl + 1);
-       msleep(100);
-       outb(0xE, ctrl + 1);
-       msleep(200);
-       outb(0xF, ctrl + 1);
-       msleep(100);
-       outb(0xE, ctrl + 1);
-       msleep(100);
-       outb(0xC, ctrl + 1);
-}
-
-/*
- * Socket Dual IO: this enables irq's for second port
- */
-static void quirk_config_socket(struct pcmcia_device *link)
-{
-       struct serial_info *info = link->priv;
-
-       if (info->multi)
-               link->config_flags |= CONF_ENABLE_ESR;
-}
-
-static const struct serial_quirk quirks[] = {
-       {
-               .manfid = 0x0160,
-               .prodid = 0x0104,
-               .multi  = -1,
-               .setup  = quirk_setup_brainboxes_0104,
-       }, {
-               .manfid = 0x015D,
-               .prodid = 0x4C45,
-               .multi  = -1,
-               .setup  = quirk_setup_brainboxes_0104,
-       }, {
-               .manfid = MANFID_IBM,
-               .prodid = ~0,
-               .multi  = -1,
-               .post   = quirk_post_ibm,
-       }, {
-               .manfid = MANFID_INTEL,
-               .prodid = PRODID_INTEL_DUAL_RS232,
-               .multi  = 2,
-       }, {
-               .manfid = MANFID_NATINST,
-               .prodid = PRODID_NATINST_QUAD_RS232,
-               .multi  = 4,
-       }, {
-               .manfid = MANFID_NOKIA,
-               .prodid = ~0,
-               .multi  = -1,
-               .config = quirk_config_nokia,
-       }, {
-               .manfid = MANFID_OMEGA,
-               .prodid = PRODID_OMEGA_QSP_100,
-               .multi  = 4,
-       }, {
-               .manfid = MANFID_OXSEMI,
-               .prodid = ~0,
-               .multi  = -1,
-               .wakeup = quirk_wakeup_oxsemi,
-       }, {
-               .manfid = MANFID_POSSIO,
-               .prodid = PRODID_POSSIO_GCC,
-               .multi  = -1,
-               .wakeup = quirk_wakeup_possio_gcc,
-       }, {
-               .manfid = MANFID_QUATECH,
-               .prodid = PRODID_QUATECH_DUAL_RS232,
-               .multi  = 2,
-       }, {
-               .manfid = MANFID_QUATECH,
-               .prodid = PRODID_QUATECH_DUAL_RS232_D1,
-               .multi  = 2,
-       }, {
-               .manfid = MANFID_QUATECH,
-               .prodid = PRODID_QUATECH_DUAL_RS232_G,
-               .multi  = 2,
-       }, {
-               .manfid = MANFID_QUATECH,
-               .prodid = PRODID_QUATECH_QUAD_RS232,
-               .multi  = 4,
-       }, {
-               .manfid = MANFID_SOCKET,
-               .prodid = PRODID_SOCKET_DUAL_RS232,
-               .multi  = 2,
-               .config = quirk_config_socket,
-       }, {
-               .manfid = MANFID_SOCKET,
-               .prodid = ~0,
-               .multi  = -1,
-               .config = quirk_config_socket,
-       }
-};
-
-
-static int serial_config(struct pcmcia_device * link);
-
-
-static void serial_remove(struct pcmcia_device *link)
-{
-       struct serial_info *info = link->priv;
-       int i;
-
-       dev_dbg(&link->dev, "serial_release\n");
-
-       /*
-        * Recheck to see if the device is still configured.
-        */
-       for (i = 0; i < info->ndev; i++)
-               serial8250_unregister_port(info->line[i]);
-
-       if (!info->slave)
-               pcmcia_disable_device(link);
-}
-
-static int serial_suspend(struct pcmcia_device *link)
-{
-       struct serial_info *info = link->priv;
-       int i;
-
-       for (i = 0; i < info->ndev; i++)
-               serial8250_suspend_port(info->line[i]);
-
-       return 0;
-}
-
-static int serial_resume(struct pcmcia_device *link)
-{
-       struct serial_info *info = link->priv;
-       int i;
-
-       for (i = 0; i < info->ndev; i++)
-               serial8250_resume_port(info->line[i]);
-
-       if (info->quirk && info->quirk->wakeup)
-               info->quirk->wakeup(link);
-
-       return 0;
-}
-
-static int serial_probe(struct pcmcia_device *link)
-{
-       struct serial_info *info;
-
-       dev_dbg(&link->dev, "serial_attach()\n");
-
-       /* Create new serial device */
-       info = kzalloc(sizeof (*info), GFP_KERNEL);
-       if (!info)
-               return -ENOMEM;
-       info->p_dev = link;
-       link->priv = info;
-
-       link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IO;
-       if (do_sound)
-               link->config_flags |= CONF_ENABLE_SPKR;
-
-       return serial_config(link);
-}
-
-static void serial_detach(struct pcmcia_device *link)
-{
-       struct serial_info *info = link->priv;
-
-       dev_dbg(&link->dev, "serial_detach\n");
-
-       /*
-        * Ensure that the ports have been released.
-        */
-       serial_remove(link);
-
-       /* free bits */
-       kfree(info);
-}
-
-/*====================================================================*/
-
-static int setup_serial(struct pcmcia_device *handle, struct serial_info * info,
-                       unsigned int iobase, int irq)
-{
-       struct uart_port port;
-       int line;
-
-       memset(&port, 0, sizeof (struct uart_port));
-       port.iobase = iobase;
-       port.irq = irq;
-       port.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_SHARE_IRQ;
-       port.uartclk = 1843200;
-       port.dev = &handle->dev;
-       if (buggy_uart)
-               port.flags |= UPF_BUGGY_UART;
-
-       if (info->quirk && info->quirk->setup)
-               info->quirk->setup(handle, &port);
-
-       line = serial8250_register_port(&port);
-       if (line < 0) {
-               printk(KERN_NOTICE "serial_cs: serial8250_register_port() at "
-                      "0x%04lx, irq %d failed\n", (u_long)iobase, irq);
-               return -EINVAL;
-       }
-
-       info->line[info->ndev] = line;
-       info->ndev++;
-
-       return 0;
-}
-
-/*====================================================================*/
-
-static int pfc_config(struct pcmcia_device *p_dev)
-{
-       unsigned int port = 0;
-       struct serial_info *info = p_dev->priv;
-
-       if ((p_dev->resource[1]->end != 0) &&
-               (resource_size(p_dev->resource[1]) == 8)) {
-               port = p_dev->resource[1]->start;
-               info->slave = 1;
-       } else if ((info->manfid == MANFID_OSITECH) &&
-               (resource_size(p_dev->resource[0]) == 0x40)) {
-               port = p_dev->resource[0]->start + 0x28;
-               info->slave = 1;
-       }
-       if (info->slave)
-               return setup_serial(p_dev, info, port, p_dev->irq);
-
-       dev_warn(&p_dev->dev, "no usable port range found, giving up\n");
-       return -ENODEV;
-}
-
-static int simple_config_check(struct pcmcia_device *p_dev, void *priv_data)
-{
-       static const int size_table[2] = { 8, 16 };
-       int *try = priv_data;
-
-       if (p_dev->resource[0]->start == 0)
-               return -ENODEV;
-
-       if ((*try & 0x1) == 0)
-               p_dev->io_lines = 16;
-
-       if (p_dev->resource[0]->end != size_table[(*try >> 1)])
-               return -ENODEV;
-
-       p_dev->resource[0]->end = 8;
-       p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
-       p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_8;
-
-       return pcmcia_request_io(p_dev);
-}
-
-static int simple_config_check_notpicky(struct pcmcia_device *p_dev,
-                                       void *priv_data)
-{
-       static const unsigned int base[5] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, 0x0 };
-       int j;
-
-       if (p_dev->io_lines > 3)
-               return -ENODEV;
-
-       p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
-       p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_8;
-       p_dev->resource[0]->end = 8;
-
-       for (j = 0; j < 5; j++) {
-               p_dev->resource[0]->start = base[j];
-               p_dev->io_lines = base[j] ? 16 : 3;
-               if (!pcmcia_request_io(p_dev))
-                       return 0;
-       }
-       return -ENODEV;
-}
-
-static int simple_config(struct pcmcia_device *link)
-{
-       struct serial_info *info = link->priv;
-       int i = -ENODEV, try;
-
-       /* First pass: look for a config entry that looks normal.
-        * Two tries: without IO aliases, then with aliases */
-       link->config_flags |= CONF_AUTO_SET_VPP;
-       for (try = 0; try < 4; try++)
-               if (!pcmcia_loop_config(link, simple_config_check, &try))
-                       goto found_port;
-
-       /* Second pass: try to find an entry that isn't picky about
-          its base address, then try to grab any standard serial port
-          address, and finally try to get any free port. */
-       if (!pcmcia_loop_config(link, simple_config_check_notpicky, NULL))
-               goto found_port;
-
-       dev_warn(&link->dev, "no usable port range found, giving up\n");
-       return -1;
-
-found_port:
-       if (info->multi && (info->manfid == MANFID_3COM))
-               link->config_index &= ~(0x08);
-
-       /*
-        * Apply any configuration quirks.
-        */
-       if (info->quirk && info->quirk->config)
-               info->quirk->config(link);
-
-       i = pcmcia_enable_device(link);
-       if (i != 0)
-               return -1;
-       return setup_serial(link, info, link->resource[0]->start, link->irq);
-}
-
-static int multi_config_check(struct pcmcia_device *p_dev, void *priv_data)
-{
-       int *multi = priv_data;
-
-       if (p_dev->resource[1]->end)
-               return -EINVAL;
-
-       /* The quad port cards have bad CIS's, so just look for a
-          window larger than 8 ports and assume it will be right */
-       if (p_dev->resource[0]->end <= 8)
-               return -EINVAL;
-
-       p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
-       p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_8;
-       p_dev->resource[0]->end = *multi * 8;
-
-       if (pcmcia_request_io(p_dev))
-               return -ENODEV;
-       return 0;
-}
-
-static int multi_config_check_notpicky(struct pcmcia_device *p_dev,
-                                      void *priv_data)
-{
-       int *base2 = priv_data;
-
-       if (!p_dev->resource[0]->end || !p_dev->resource[1]->end ||
-               p_dev->resource[0]->start + 8 != p_dev->resource[1]->start)
-               return -ENODEV;
-
-       p_dev->resource[0]->end = p_dev->resource[1]->end = 8;
-       p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
-       p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_8;
-
-       if (pcmcia_request_io(p_dev))
-               return -ENODEV;
-
-       *base2 = p_dev->resource[0]->start + 8;
-       return 0;
-}
-
-static int multi_config(struct pcmcia_device *link)
-{
-       struct serial_info *info = link->priv;
-       int i, base2 = 0;
-
-       /* First, look for a generic full-sized window */
-       if (!pcmcia_loop_config(link, multi_config_check, &info->multi))
-               base2 = link->resource[0]->start + 8;
-       else {
-               /* If that didn't work, look for two windows */
-               info->multi = 2;
-               if (pcmcia_loop_config(link, multi_config_check_notpicky,
-                                      &base2)) {
-                       dev_warn(&link->dev, "no usable port range "
-                              "found, giving up\n");
-                       return -ENODEV;
-               }
-       }
-
-       if (!link->irq)
-               dev_warn(&link->dev, "no usable IRQ found, continuing...\n");
-
-       /*
-        * Apply any configuration quirks.
-        */
-       if (info->quirk && info->quirk->config)
-               info->quirk->config(link);
-
-       i = pcmcia_enable_device(link);
-       if (i != 0)
-               return -ENODEV;
-
-       /* The Oxford Semiconductor OXCF950 cards are in fact single-port:
-        * 8 registers are for the UART, the others are extra registers.
-        * Siemen's MC45 PCMCIA (Possio's GCC) is OXCF950 based too.
-        */
-       if (info->manfid == MANFID_OXSEMI || (info->manfid == MANFID_POSSIO &&
-                               info->prodid == PRODID_POSSIO_GCC)) {
-               int err;
-
-               if (link->config_index == 1 ||
-                   link->config_index == 3) {
-                       err = setup_serial(link, info, base2,
-                                       link->irq);
-                       base2 = link->resource[0]->start;
-               } else {
-                       err = setup_serial(link, info, link->resource[0]->start,
-                                       link->irq);
-               }
-               info->c950ctrl = base2;
-
-               /*
-                * FIXME: We really should wake up the port prior to
-                * handing it over to the serial layer.
-                */
-               if (info->quirk && info->quirk->wakeup)
-                       info->quirk->wakeup(link);
-
-               return 0;
-       }
-
-       setup_serial(link, info, link->resource[0]->start, link->irq);
-       for (i = 0; i < info->multi - 1; i++)
-               setup_serial(link, info, base2 + (8 * i),
-                               link->irq);
-       return 0;
-}
-
-static int serial_check_for_multi(struct pcmcia_device *p_dev,  void *priv_data)
-{
-       struct serial_info *info = p_dev->priv;
-
-       if (!p_dev->resource[0]->end)
-               return -EINVAL;
-
-       if ((!p_dev->resource[1]->end) && (p_dev->resource[0]->end % 8 == 0))
-               info->multi = p_dev->resource[0]->end >> 3;
-
-       if ((p_dev->resource[1]->end) && (p_dev->resource[0]->end == 8)
-               && (p_dev->resource[1]->end == 8))
-               info->multi = 2;
-
-       return 0; /* break */
-}
-
-
-static int serial_config(struct pcmcia_device * link)
-{
-       struct serial_info *info = link->priv;
-       int i;
-
-       dev_dbg(&link->dev, "serial_config\n");
-
-       /* Is this a compliant multifunction card? */
-       info->multi = (link->socket->functions > 1);
-
-       /* Is this a multiport card? */
-       info->manfid = link->manf_id;
-       info->prodid = link->card_id;
-
-       for (i = 0; i < ARRAY_SIZE(quirks); i++)
-               if ((quirks[i].manfid == ~0 ||
-                    quirks[i].manfid == info->manfid) &&
-                   (quirks[i].prodid == ~0 ||
-                    quirks[i].prodid == info->prodid)) {
-                       info->quirk = &quirks[i];
-                       break;
-               }
-
-       /* Another check for dual-serial cards: look for either serial or
-          multifunction cards that ask for appropriate IO port ranges */
-       if ((info->multi == 0) &&
-           (link->has_func_id) &&
-           (link->socket->pcmcia_pfc == 0) &&
-           ((link->func_id == CISTPL_FUNCID_MULTI) ||
-            (link->func_id == CISTPL_FUNCID_SERIAL)))
-               pcmcia_loop_config(link, serial_check_for_multi, info);
-
-       /*
-        * Apply any multi-port quirk.
-        */
-       if (info->quirk && info->quirk->multi != -1)
-               info->multi = info->quirk->multi;
-
-       dev_info(&link->dev,
-               "trying to set up [0x%04x:0x%04x] (pfc: %d, multi: %d, quirk: %p)\n",
-               link->manf_id, link->card_id,
-               link->socket->pcmcia_pfc, info->multi, info->quirk);
-       if (link->socket->pcmcia_pfc)
-               i = pfc_config(link);
-       else if (info->multi > 1)
-               i = multi_config(link);
-       else
-               i = simple_config(link);
-
-       if (i || info->ndev == 0)
-               goto failed;
-
-       /*
-        * Apply any post-init quirk.  FIXME: This should really happen
-        * before we register the port, since it might already be in use.
-        */
-       if (info->quirk && info->quirk->post)
-               if (info->quirk->post(link))
-                       goto failed;
-
-       return 0;
-
-failed:
-       dev_warn(&link->dev, "failed to initialize\n");
-       serial_remove(link);
-       return -ENODEV;
-}
-
-static const struct pcmcia_device_id serial_ids[] = {
-       PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0057, 0x0021),
-       PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0089, 0x110a),
-       PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0104, 0x000a),
-       PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0105, 0x0d0a),
-       PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0105, 0x0e0a),
-       PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0105, 0xea15),
-       PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0109, 0x0501),
-       PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0138, 0x110a),
-       PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0140, 0x000a),
-       PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0143, 0x3341),
-       PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0143, 0xc0ab),
-       PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x016c, 0x0081),
-       PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x021b, 0x0101),
-       PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x08a1, 0xc0ab),
-       PCMCIA_PFC_DEVICE_PROD_ID123(1, "MEGAHERTZ", "CC/XJEM3288", "DATA/FAX/CELL ETHERNET MODEM", 0xf510db04, 0x04cd2988, 0x46a52d63),
-       PCMCIA_PFC_DEVICE_PROD_ID123(1, "MEGAHERTZ", "CC/XJEM3336", "DATA/FAX/CELL ETHERNET MODEM", 0xf510db04, 0x0143b773, 0x46a52d63),
-       PCMCIA_PFC_DEVICE_PROD_ID123(1, "MEGAHERTZ", "EM1144T", "PCMCIA MODEM", 0xf510db04, 0x856d66c8, 0xbd6c43ef),
-       PCMCIA_PFC_DEVICE_PROD_ID123(1, "MEGAHERTZ", "XJEM1144/CCEM1144", "PCMCIA MODEM", 0xf510db04, 0x52d21e1e, 0xbd6c43ef),
-       PCMCIA_PFC_DEVICE_PROD_ID13(1, "Xircom", "CEM28", 0x2e3ee845, 0x0ea978ea),
-       PCMCIA_PFC_DEVICE_PROD_ID13(1, "Xircom", "CEM33", 0x2e3ee845, 0x80609023),
-       PCMCIA_PFC_DEVICE_PROD_ID13(1, "Xircom", "CEM56", 0x2e3ee845, 0xa650c32a),
-       PCMCIA_PFC_DEVICE_PROD_ID13(1, "Xircom", "REM10", 0x2e3ee845, 0x76df1d29),
-       PCMCIA_PFC_DEVICE_PROD_ID13(1, "Xircom", "XEM5600", 0x2e3ee845, 0xf1403719),
-       PCMCIA_PFC_DEVICE_PROD_ID12(1, "AnyCom", "Fast Ethernet + 56K COMBO", 0x578ba6e7, 0xb0ac62c4),
-       PCMCIA_PFC_DEVICE_PROD_ID12(1, "ATKK", "LM33-PCM-T", 0xba9eb7e2, 0x077c174e),
-       PCMCIA_PFC_DEVICE_PROD_ID12(1, "D-Link", "DME336T", 0x1a424a1c, 0xb23897ff),
-       PCMCIA_PFC_DEVICE_PROD_ID12(1, "Gateway 2000", "XJEM3336", 0xdd9989be, 0x662c394c),
-       PCMCIA_PFC_DEVICE_PROD_ID12(1, "Grey Cell", "GCS3000", 0x2a151fac, 0x48b932ae),
-       PCMCIA_PFC_DEVICE_PROD_ID12(1, "Linksys", "EtherFast 10&100 + 56K PC Card (PCMLM56)", 0x0733cc81, 0xb3765033),
-       PCMCIA_PFC_DEVICE_PROD_ID12(1, "LINKSYS", "PCMLM336", 0xf7cb0b07, 0x7a821b58),
-       PCMCIA_PFC_DEVICE_PROD_ID12(1, "MEGAHERTZ", "XJEM1144/CCEM1144", 0xf510db04, 0x52d21e1e),
-       PCMCIA_PFC_DEVICE_PROD_ID12(1, "MICRO RESEARCH", "COMBO-L/M-336", 0xb2ced065, 0x3ced0555),
-       PCMCIA_PFC_DEVICE_PROD_ID12(1, "NEC", "PK-UG-J001" ,0x18df0ba0 ,0x831b1064),
-       PCMCIA_PFC_DEVICE_PROD_ID12(1, "Ositech", "Trumpcard:Jack of Diamonds Modem+Ethernet", 0xc2f80cd, 0x656947b9),
-       PCMCIA_PFC_DEVICE_PROD_ID12(1, "Ositech", "Trumpcard:Jack of Hearts Modem+Ethernet", 0xc2f80cd, 0xdc9ba5ed),
-       PCMCIA_PFC_DEVICE_PROD_ID12(1, "PCMCIAs", "ComboCard", 0xdcfe12d3, 0xcd8906cc),
-       PCMCIA_PFC_DEVICE_PROD_ID12(1, "PCMCIAs", "LanModem", 0xdcfe12d3, 0xc67c648f),
-       PCMCIA_PFC_DEVICE_PROD_ID12(1, "TDK", "GlobalNetworker 3410/3412", 0x1eae9475, 0xd9a93bed),
-       PCMCIA_PFC_DEVICE_PROD_ID12(1, "Xircom", "CreditCard Ethernet+Modem II", 0x2e3ee845, 0xeca401bf),
-       PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0032, 0x0e01),
-       PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0032, 0x0a05),
-       PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0032, 0x0b05),
-       PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0032, 0x1101),
-       PCMCIA_MFC_DEVICE_MANF_CARD(0, 0x0104, 0x0070),
-       PCMCIA_MFC_DEVICE_MANF_CARD(1, 0x0101, 0x0562),
-       PCMCIA_MFC_DEVICE_MANF_CARD(1, 0x0104, 0x0070),
-       PCMCIA_MFC_DEVICE_MANF_CARD(1, 0x016c, 0x0020),
-       PCMCIA_MFC_DEVICE_PROD_ID123(1, "APEX DATA", "MULTICARD", "ETHERNET-MODEM", 0x11c2da09, 0x7289dc5d, 0xaad95e1f),
-       PCMCIA_MFC_DEVICE_PROD_ID12(1, "IBM", "Home and Away 28.8 PC Card       ", 0xb569a6e5, 0x5bd4ff2c),
-       PCMCIA_MFC_DEVICE_PROD_ID12(1, "IBM", "Home and Away Credit Card Adapter", 0xb569a6e5, 0x4bdf15c3),
-       PCMCIA_MFC_DEVICE_PROD_ID12(1, "IBM", "w95 Home and Away Credit Card ", 0xb569a6e5, 0xae911c15),
-       PCMCIA_MFC_DEVICE_PROD_ID1(1, "Motorola MARQUIS", 0xf03e4e77),
-       PCMCIA_MFC_DEVICE_PROD_ID2(1, "FAX/Modem/Ethernet Combo Card ", 0x1ed59302),
-       PCMCIA_DEVICE_MANF_CARD(0x0089, 0x0301),
-       PCMCIA_DEVICE_MANF_CARD(0x00a4, 0x0276),
-       PCMCIA_DEVICE_MANF_CARD(0x0101, 0x0039),
-       PCMCIA_DEVICE_MANF_CARD(0x0104, 0x0006),
-       PCMCIA_DEVICE_MANF_CARD(0x0105, 0x0101), /* TDK DF2814 */
-       PCMCIA_DEVICE_MANF_CARD(0x0105, 0x100a), /* Xircom CM-56G */
-       PCMCIA_DEVICE_MANF_CARD(0x0105, 0x3e0a), /* TDK DF5660 */
-       PCMCIA_DEVICE_MANF_CARD(0x0105, 0x410a),
-       PCMCIA_DEVICE_MANF_CARD(0x0107, 0x0002), /* USRobotics 14,400 */
-       PCMCIA_DEVICE_MANF_CARD(0x010b, 0x0d50),
-       PCMCIA_DEVICE_MANF_CARD(0x010b, 0x0d51),
-       PCMCIA_DEVICE_MANF_CARD(0x010b, 0x0d52),
-       PCMCIA_DEVICE_MANF_CARD(0x010b, 0x0d53),
-       PCMCIA_DEVICE_MANF_CARD(0x010b, 0xd180),
-       PCMCIA_DEVICE_MANF_CARD(0x0115, 0x3330), /* USRobotics/SUN 14,400 */
-       PCMCIA_DEVICE_MANF_CARD(0x0124, 0x0100), /* Nokia DTP-2 ver II */
-       PCMCIA_DEVICE_MANF_CARD(0x0134, 0x5600), /* LASAT COMMUNICATIONS A/S */
-       PCMCIA_DEVICE_MANF_CARD(0x0137, 0x000e),
-       PCMCIA_DEVICE_MANF_CARD(0x0137, 0x001b),
-       PCMCIA_DEVICE_MANF_CARD(0x0137, 0x0025),
-       PCMCIA_DEVICE_MANF_CARD(0x0137, 0x0045),
-       PCMCIA_DEVICE_MANF_CARD(0x0137, 0x0052),
-       PCMCIA_DEVICE_MANF_CARD(0x016c, 0x0006), /* Psion 56K+Fax */
-       PCMCIA_DEVICE_MANF_CARD(0x0200, 0x0001), /* MultiMobile */
-       PCMCIA_DEVICE_PROD_ID134("ADV", "TECH", "COMpad-32/85", 0x67459937, 0x916d02ba, 0x8fbe92ae),
-       PCMCIA_DEVICE_PROD_ID124("GATEWAY2000", "CC3144", "PCMCIA MODEM", 0x506bccae, 0xcb3685f1, 0xbd6c43ef),
-       PCMCIA_DEVICE_PROD_ID14("MEGAHERTZ", "PCMCIA MODEM", 0xf510db04, 0xbd6c43ef),
-       PCMCIA_DEVICE_PROD_ID124("TOSHIBA", "T144PF", "PCMCIA MODEM", 0xb4585a1a, 0x7271409c, 0xbd6c43ef),
-       PCMCIA_DEVICE_PROD_ID123("FUJITSU", "FC14F ", "MBH10213", 0x6ee5a3d8, 0x30ead12b, 0xb00f05a0),
-       PCMCIA_DEVICE_PROD_ID123("Novatel Wireless", "Merlin UMTS Modem", "U630", 0x32607776, 0xd9e73b13, 0xe87332e),
-       PCMCIA_DEVICE_PROD_ID13("MEGAHERTZ", "V.34 PCMCIA MODEM", 0xf510db04, 0xbb2cce4a),
-       PCMCIA_DEVICE_PROD_ID12("Brain Boxes", "Bluetooth PC Card", 0xee138382, 0xd4ce9b02),
-       PCMCIA_DEVICE_PROD_ID12("CIRRUS LOGIC", "FAX MODEM", 0xe625f451, 0xcecd6dfa),
-       PCMCIA_DEVICE_PROD_ID12("COMPAQ", "PCMCIA 28800 FAX/DATA MODEM", 0xa3a3062c, 0x8cbd7c76),
-       PCMCIA_DEVICE_PROD_ID12("COMPAQ", "PCMCIA 33600 FAX/DATA MODEM", 0xa3a3062c, 0x5a00ce95),
-       PCMCIA_DEVICE_PROD_ID12("Computerboards, Inc.", "PCM-COM422", 0xd0b78f51, 0x7e2d49ed),
-       PCMCIA_DEVICE_PROD_ID12("Dr. Neuhaus", "FURY CARD 14K4", 0x76942813, 0x8b96ce65),
-       PCMCIA_DEVICE_PROD_ID12("IBM", "ISDN/56K/GSM", 0xb569a6e5, 0xfee5297b),
-       PCMCIA_DEVICE_PROD_ID12("Intelligent", "ANGIA FAX/MODEM", 0xb496e65e, 0xf31602a6),
-       PCMCIA_DEVICE_PROD_ID12("Intel", "MODEM 2400+", 0x816cc815, 0x412729fb),
-       PCMCIA_DEVICE_PROD_ID12("Intertex", "IX34-PCMCIA", 0xf8a097e3, 0x97880447),
-       PCMCIA_DEVICE_PROD_ID12("IOTech Inc ", "PCMCIA Dual RS-232 Serial Port Card", 0x3bd2d898, 0x92abc92f),
-       PCMCIA_DEVICE_PROD_ID12("MACRONIX", "FAX/MODEM", 0x668388b3, 0x3f9bdf2f),
-       PCMCIA_DEVICE_PROD_ID12("Multi-Tech", "MT1432LT", 0x5f73be51, 0x0b3e2383),
-       PCMCIA_DEVICE_PROD_ID12("Multi-Tech", "MT2834LT", 0x5f73be51, 0x4cd7c09e),
-       PCMCIA_DEVICE_PROD_ID12("OEM      ", "C288MX     ", 0xb572d360, 0xd2385b7a),
-       PCMCIA_DEVICE_PROD_ID12("Option International", "V34bis GSM/PSTN Data/Fax Modem", 0x9d7cd6f5, 0x5cb8bf41),
-       PCMCIA_DEVICE_PROD_ID12("PCMCIA   ", "C336MX     ", 0x99bcafe9, 0xaa25bcab),
-       PCMCIA_DEVICE_PROD_ID12("Quatech Inc", "PCMCIA Dual RS-232 Serial Port Card", 0xc4420b35, 0x92abc92f),
-       PCMCIA_DEVICE_PROD_ID12("Quatech Inc", "Dual RS-232 Serial Port PC Card", 0xc4420b35, 0x031a380d),
-       PCMCIA_DEVICE_PROD_ID12("Telia", "SurfinBird 560P/A+", 0xe2cdd5e, 0xc9314b38),
-       PCMCIA_DEVICE_PROD_ID1("Smart Serial Port", 0x2d8ce292),
-       PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "PCMCIA", "EN2218-LAN/MODEM", 0x281f1c5d, 0x570f348e, "cis/PCMLM28.cis"),
-       PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "PCMCIA", "UE2218-LAN/MODEM", 0x281f1c5d, 0x6fdcacee, "cis/PCMLM28.cis"),
-       PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "Psion Dacom", "Gold Card V34 Ethernet", 0xf5f025c2, 0x338e8155, "cis/PCMLM28.cis"),
-       PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "Psion Dacom", "Gold Card V34 Ethernet GSM", 0xf5f025c2, 0x4ae85d35, "cis/PCMLM28.cis"),
-       PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "LINKSYS", "PCMLM28", 0xf7cb0b07, 0x66881874, "cis/PCMLM28.cis"),
-       PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "TOSHIBA", "Modem/LAN Card", 0xb4585a1a, 0x53f922f8, "cis/PCMLM28.cis"),
-       PCMCIA_MFC_DEVICE_CIS_PROD_ID12(1, "DAYNA COMMUNICATIONS", "LAN AND MODEM MULTIFUNCTION", 0x8fdf8f89, 0xdd5ed9e8, "cis/DP83903.cis"),
-       PCMCIA_MFC_DEVICE_CIS_PROD_ID4(1, "NSC MF LAN/Modem", 0x58fc6056, "cis/DP83903.cis"),
-       PCMCIA_MFC_DEVICE_CIS_MANF_CARD(1, 0x0101, 0x0556, "cis/3CCFEM556.cis"),
-       PCMCIA_MFC_DEVICE_CIS_MANF_CARD(1, 0x0175, 0x0000, "cis/DP83903.cis"),
-       PCMCIA_MFC_DEVICE_CIS_MANF_CARD(1, 0x0101, 0x0035, "cis/3CXEM556.cis"),
-       PCMCIA_MFC_DEVICE_CIS_MANF_CARD(1, 0x0101, 0x003d, "cis/3CXEM556.cis"),
-       PCMCIA_DEVICE_CIS_PROD_ID12("Sierra Wireless", "AC850", 0xd85f6206, 0x42a2c018, "cis/SW_8xx_SER.cis"), /* Sierra Wireless AC850 3G Network Adapter R1 */
-       PCMCIA_DEVICE_CIS_PROD_ID12("Sierra Wireless", "AC860", 0xd85f6206, 0x698f93db, "cis/SW_8xx_SER.cis"), /* Sierra Wireless AC860 3G Network Adapter R1 */
-       PCMCIA_DEVICE_CIS_PROD_ID12("Sierra Wireless", "AC710/AC750", 0xd85f6206, 0x761b11e0, "cis/SW_7xx_SER.cis"),  /* Sierra Wireless AC710/AC750 GPRS Network Adapter R1 */
-       PCMCIA_DEVICE_CIS_MANF_CARD(0x0192, 0xa555, "cis/SW_555_SER.cis"),  /* Sierra Aircard 555 CDMA 1xrtt Modem -- pre update */
-       PCMCIA_DEVICE_CIS_MANF_CARD(0x013f, 0xa555, "cis/SW_555_SER.cis"),  /* Sierra Aircard 555 CDMA 1xrtt Modem -- post update */
-       PCMCIA_DEVICE_CIS_PROD_ID12("MultiTech", "PCMCIA 56K DataFax", 0x842047ee, 0xc2efcf03, "cis/MT5634ZLX.cis"),
-       PCMCIA_DEVICE_CIS_PROD_ID12("ADVANTECH", "COMpad-32/85B-2", 0x96913a85, 0x27ab5437, "cis/COMpad2.cis"),
-       PCMCIA_DEVICE_CIS_PROD_ID12("ADVANTECH", "COMpad-32/85B-4", 0x96913a85, 0xcec8f102, "cis/COMpad4.cis"),
-       PCMCIA_DEVICE_CIS_PROD_ID123("ADVANTECH", "COMpad-32/85", "1.0", 0x96913a85, 0x8fbe92ae, 0x0877b627, "cis/COMpad2.cis"),
-       PCMCIA_DEVICE_CIS_PROD_ID2("RS-COM 2P", 0xad20b156, "cis/RS-COM-2P.cis"),
-       PCMCIA_DEVICE_CIS_MANF_CARD(0x0013, 0x0000, "cis/GLOBETROTTER.cis"),
-       PCMCIA_DEVICE_PROD_ID12("ELAN DIGITAL SYSTEMS LTD, c1997.","SERIAL CARD: SL100  1.00.",0x19ca78af,0xf964f42b),
-       PCMCIA_DEVICE_PROD_ID12("ELAN DIGITAL SYSTEMS LTD, c1997.","SERIAL CARD: SL100",0x19ca78af,0x71d98e83),
-       PCMCIA_DEVICE_PROD_ID12("ELAN DIGITAL SYSTEMS LTD, c1997.","SERIAL CARD: SL232  1.00.",0x19ca78af,0x69fb7490),
-       PCMCIA_DEVICE_PROD_ID12("ELAN DIGITAL SYSTEMS LTD, c1997.","SERIAL CARD: SL232",0x19ca78af,0xb6bc0235),
-       PCMCIA_DEVICE_PROD_ID12("ELAN DIGITAL SYSTEMS LTD, c2000.","SERIAL CARD: CF232",0x63f2e0bd,0xb9e175d3),
-       PCMCIA_DEVICE_PROD_ID12("ELAN DIGITAL SYSTEMS LTD, c2000.","SERIAL CARD: CF232-5",0x63f2e0bd,0xfce33442),
-       PCMCIA_DEVICE_PROD_ID12("Elan","Serial Port: CF232",0x3beb8cf2,0x171e7190),
-       PCMCIA_DEVICE_PROD_ID12("Elan","Serial Port: CF232-5",0x3beb8cf2,0x20da4262),
-       PCMCIA_DEVICE_PROD_ID12("Elan","Serial Port: CF428",0x3beb8cf2,0xea5dd57d),
-       PCMCIA_DEVICE_PROD_ID12("Elan","Serial Port: CF500",0x3beb8cf2,0xd77255fa),
-       PCMCIA_DEVICE_PROD_ID12("Elan","Serial Port: IC232",0x3beb8cf2,0x6a709903),
-       PCMCIA_DEVICE_PROD_ID12("Elan","Serial Port: SL232",0x3beb8cf2,0x18430676),
-       PCMCIA_DEVICE_PROD_ID12("Elan","Serial Port: XL232",0x3beb8cf2,0x6f933767),
-       PCMCIA_MFC_DEVICE_PROD_ID12(0,"Elan","Serial Port: CF332",0x3beb8cf2,0x16dc1ba7),
-       PCMCIA_MFC_DEVICE_PROD_ID12(0,"Elan","Serial Port: SL332",0x3beb8cf2,0x19816c41),
-       PCMCIA_MFC_DEVICE_PROD_ID12(0,"Elan","Serial Port: SL385",0x3beb8cf2,0x64112029),
-       PCMCIA_MFC_DEVICE_PROD_ID12(0,"Elan","Serial Port: SL432",0x3beb8cf2,0x1cce7ac4),
-       PCMCIA_MFC_DEVICE_PROD_ID12(0,"Elan","Serial+Parallel Port: SP230",0x3beb8cf2,0xdb9e58bc),
-       PCMCIA_MFC_DEVICE_PROD_ID12(1,"Elan","Serial Port: CF332",0x3beb8cf2,0x16dc1ba7),
-       PCMCIA_MFC_DEVICE_PROD_ID12(1,"Elan","Serial Port: SL332",0x3beb8cf2,0x19816c41),
-       PCMCIA_MFC_DEVICE_PROD_ID12(1,"Elan","Serial Port: SL385",0x3beb8cf2,0x64112029),
-       PCMCIA_MFC_DEVICE_PROD_ID12(1,"Elan","Serial Port: SL432",0x3beb8cf2,0x1cce7ac4),
-       PCMCIA_MFC_DEVICE_PROD_ID12(2,"Elan","Serial Port: SL432",0x3beb8cf2,0x1cce7ac4),
-       PCMCIA_MFC_DEVICE_PROD_ID12(3,"Elan","Serial Port: SL432",0x3beb8cf2,0x1cce7ac4),
-       PCMCIA_DEVICE_MANF_CARD(0x0279, 0x950b),
-       /* too generic */
-       /* PCMCIA_MFC_DEVICE_MANF_CARD(0, 0x0160, 0x0002), */
-       /* PCMCIA_MFC_DEVICE_MANF_CARD(1, 0x0160, 0x0002), */
-       PCMCIA_DEVICE_FUNC_ID(2),
-       PCMCIA_DEVICE_NULL,
-};
-MODULE_DEVICE_TABLE(pcmcia, serial_ids);
-
-MODULE_FIRMWARE("cis/PCMLM28.cis");
-MODULE_FIRMWARE("cis/DP83903.cis");
-MODULE_FIRMWARE("cis/3CCFEM556.cis");
-MODULE_FIRMWARE("cis/3CXEM556.cis");
-MODULE_FIRMWARE("cis/SW_8xx_SER.cis");
-MODULE_FIRMWARE("cis/SW_7xx_SER.cis");
-MODULE_FIRMWARE("cis/SW_555_SER.cis");
-MODULE_FIRMWARE("cis/MT5634ZLX.cis");
-MODULE_FIRMWARE("cis/COMpad2.cis");
-MODULE_FIRMWARE("cis/COMpad4.cis");
-MODULE_FIRMWARE("cis/RS-COM-2P.cis");
-
-static struct pcmcia_driver serial_cs_driver = {
-       .owner          = THIS_MODULE,
-       .name           = "serial_cs",
-       .probe          = serial_probe,
-       .remove         = serial_detach,
-       .id_table       = serial_ids,
-       .suspend        = serial_suspend,
-       .resume         = serial_resume,
-};
-
-static int __init init_serial_cs(void)
-{
-       return pcmcia_register_driver(&serial_cs_driver);
-}
-
-static void __exit exit_serial_cs(void)
-{
-       pcmcia_unregister_driver(&serial_cs_driver);
-}
-
-module_init(init_serial_cs);
-module_exit(exit_serial_cs);
-
-MODULE_LICENSE("GPL");
index ef9dd62..bf6e238 100644 (file)
@@ -227,7 +227,6 @@ int tty_port_block_til_ready(struct tty_port *port,
        int do_clocal = 0, retval;
        unsigned long flags;
        DEFINE_WAIT(wait);
-       int cd;
 
        /* block if port is in the process of being closed */
        if (tty_hung_up_p(filp) || port->flags & ASYNC_CLOSING) {
@@ -284,11 +283,14 @@ int tty_port_block_til_ready(struct tty_port *port,
                                retval = -ERESTARTSYS;
                        break;
                }
-               /* Probe the carrier. For devices with no carrier detect this
-                  will always return true */
-               cd = tty_port_carrier_raised(port);
+               /*
+                * Probe the carrier. For devices with no carrier detect
+                * tty_port_carrier_raised will always return true.
+                * Never ask drivers if CLOCAL is set, this causes troubles
+                * on some hardware.
+                */
                if (!(port->flags & ASYNC_CLOSING) &&
-                               (do_clocal || cd))
+                               (do_clocal || tty_port_carrier_raised(port)))
                        break;
                if (signal_pending(current)) {
                        retval = -ERESTARTSYS;
index 5e096f4..65447c5 100644 (file)
@@ -1463,7 +1463,6 @@ compat_kdfontop_ioctl(struct compat_console_font_op __user *fontop,
        if (!perm && op->op != KD_FONT_OP_GET)
                return -EPERM;
        op->data = compat_ptr(((struct compat_console_font_op *)op)->data);
-       op->flags |= KD_FONT_FLAG_OLD;
        i = con_font_op(vc, op);
        if (i)
                return i;
index 1c50baf..d2b3cff 100644 (file)
@@ -57,6 +57,8 @@ MODULE_DEVICE_TABLE (usb, wdm_ids);
 
 #define WDM_MAX                        16
 
+/* CDC-WMC r1.1 requires wMaxCommand to be "at least 256 decimal (0x100)" */
+#define WDM_DEFAULT_BUFSIZE    256
 
 static DEFINE_MUTEX(wdm_mutex);
 
@@ -88,7 +90,8 @@ struct wdm_device {
        int                     count;
        dma_addr_t              shandle;
        dma_addr_t              ihandle;
-       struct mutex            lock;
+       struct mutex            wlock;
+       struct mutex            rlock;
        wait_queue_head_t       wait;
        struct work_struct      rxwork;
        int                     werr;
@@ -323,7 +326,7 @@ static ssize_t wdm_write
        }
 
        /* concurrent writes and disconnect */
-       r = mutex_lock_interruptible(&desc->lock);
+       r = mutex_lock_interruptible(&desc->wlock);
        rv = -ERESTARTSYS;
        if (r) {
                kfree(buf);
@@ -386,7 +389,7 @@ static ssize_t wdm_write
 out:
        usb_autopm_put_interface(desc->intf);
 outnp:
-       mutex_unlock(&desc->lock);
+       mutex_unlock(&desc->wlock);
 outnl:
        return rv < 0 ? rv : count;
 }
@@ -399,7 +402,7 @@ static ssize_t wdm_read
        struct wdm_device *desc = file->private_data;
 
 
-       rv = mutex_lock_interruptible(&desc->lock); /*concurrent reads */
+       rv = mutex_lock_interruptible(&desc->rlock); /*concurrent reads */
        if (rv < 0)
                return -ERESTARTSYS;
 
@@ -467,14 +470,16 @@ retry:
        for (i = 0; i < desc->length - cntr; i++)
                desc->ubuf[i] = desc->ubuf[i + cntr];
 
+       spin_lock_irq(&desc->iuspin);
        desc->length -= cntr;
+       spin_unlock_irq(&desc->iuspin);
        /* in case we had outstanding data */
        if (!desc->length)
                clear_bit(WDM_READ, &desc->flags);
        rv = cntr;
 
 err:
-       mutex_unlock(&desc->lock);
+       mutex_unlock(&desc->rlock);
        return rv;
 }
 
@@ -540,7 +545,8 @@ static int wdm_open(struct inode *inode, struct file *file)
        }
        intf->needs_remote_wakeup = 1;
 
-       mutex_lock(&desc->lock);
+       /* using write lock to protect desc->count */
+       mutex_lock(&desc->wlock);
        if (!desc->count++) {
                desc->werr = 0;
                desc->rerr = 0;
@@ -553,7 +559,7 @@ static int wdm_open(struct inode *inode, struct file *file)
        } else {
                rv = 0;
        }
-       mutex_unlock(&desc->lock);
+       mutex_unlock(&desc->wlock);
        usb_autopm_put_interface(desc->intf);
 out:
        mutex_unlock(&wdm_mutex);
@@ -565,9 +571,11 @@ static int wdm_release(struct inode *inode, struct file *file)
        struct wdm_device *desc = file->private_data;
 
        mutex_lock(&wdm_mutex);
-       mutex_lock(&desc->lock);
+
+       /* using write lock to protect desc->count */
+       mutex_lock(&desc->wlock);
        desc->count--;
-       mutex_unlock(&desc->lock);
+       mutex_unlock(&desc->wlock);
 
        if (!desc->count) {
                dev_dbg(&desc->intf->dev, "wdm_release: cleanup");
@@ -630,7 +638,7 @@ static int wdm_probe(struct usb_interface *intf, const struct usb_device_id *id)
        struct usb_cdc_dmm_desc *dmhd;
        u8 *buffer = intf->altsetting->extra;
        int buflen = intf->altsetting->extralen;
-       u16 maxcom = 0;
+       u16 maxcom = WDM_DEFAULT_BUFSIZE;
 
        if (!buffer)
                goto out;
@@ -665,7 +673,8 @@ next_desc:
        desc = kzalloc(sizeof(struct wdm_device), GFP_KERNEL);
        if (!desc)
                goto out;
-       mutex_init(&desc->lock);
+       mutex_init(&desc->rlock);
+       mutex_init(&desc->wlock);
        spin_lock_init(&desc->iuspin);
        init_waitqueue_head(&desc->wait);
        desc->wMaxCommand = maxcom;
@@ -716,7 +725,7 @@ next_desc:
                goto err;
 
        desc->inbuf = usb_alloc_coherent(interface_to_usbdev(intf),
-                                        desc->bMaxPacketSize0,
+                                        desc->wMaxCommand,
                                         GFP_KERNEL,
                                         &desc->response->transfer_dma);
        if (!desc->inbuf)
@@ -779,11 +788,13 @@ static void wdm_disconnect(struct usb_interface *intf)
        /* to terminate pending flushes */
        clear_bit(WDM_IN_USE, &desc->flags);
        spin_unlock_irqrestore(&desc->iuspin, flags);
-       mutex_lock(&desc->lock);
+       wake_up_all(&desc->wait);
+       mutex_lock(&desc->rlock);
+       mutex_lock(&desc->wlock);
        kill_urbs(desc);
        cancel_work_sync(&desc->rxwork);
-       mutex_unlock(&desc->lock);
-       wake_up_all(&desc->wait);
+       mutex_unlock(&desc->wlock);
+       mutex_unlock(&desc->rlock);
        if (!desc->count)
                cleanup(desc);
        mutex_unlock(&wdm_mutex);
@@ -798,8 +809,10 @@ static int wdm_suspend(struct usb_interface *intf, pm_message_t message)
        dev_dbg(&desc->intf->dev, "wdm%d_suspend\n", intf->minor);
 
        /* if this is an autosuspend the caller does the locking */
-       if (!PMSG_IS_AUTO(message))
-               mutex_lock(&desc->lock);
+       if (!PMSG_IS_AUTO(message)) {
+               mutex_lock(&desc->rlock);
+               mutex_lock(&desc->wlock);
+       }
        spin_lock_irq(&desc->iuspin);
 
        if (PMSG_IS_AUTO(message) &&
@@ -815,8 +828,10 @@ static int wdm_suspend(struct usb_interface *intf, pm_message_t message)
                kill_urbs(desc);
                cancel_work_sync(&desc->rxwork);
        }
-       if (!PMSG_IS_AUTO(message))
-               mutex_unlock(&desc->lock);
+       if (!PMSG_IS_AUTO(message)) {
+               mutex_unlock(&desc->wlock);
+               mutex_unlock(&desc->rlock);
+       }
 
        return rv;
 }
@@ -854,7 +869,8 @@ static int wdm_pre_reset(struct usb_interface *intf)
 {
        struct wdm_device *desc = usb_get_intfdata(intf);
 
-       mutex_lock(&desc->lock);
+       mutex_lock(&desc->rlock);
+       mutex_lock(&desc->wlock);
        kill_urbs(desc);
 
        /*
@@ -876,7 +892,8 @@ static int wdm_post_reset(struct usb_interface *intf)
        int rv;
 
        rv = recover_from_urb_loss(desc);
-       mutex_unlock(&desc->lock);
+       mutex_unlock(&desc->wlock);
+       mutex_unlock(&desc->rlock);
        return 0;
 }
 
index 2f51de5..c8df1dd 100644 (file)
@@ -126,7 +126,6 @@ static int __dwc3_gadget_ep0_queue(struct dwc3_ep *dep,
                struct dwc3_request *req)
 {
        struct dwc3             *dwc = dep->dwc;
-       u32                     type;
        int                     ret = 0;
 
        req->request.actual     = 0;
@@ -149,20 +148,14 @@ static int __dwc3_gadget_ep0_queue(struct dwc3_ep *dep,
 
                direction = !!(dep->flags & DWC3_EP0_DIR_IN);
 
-               if (dwc->ep0state == EP0_STATUS_PHASE) {
-                       type = dwc->three_stage_setup
-                               ? DWC3_TRBCTL_CONTROL_STATUS3
-                               : DWC3_TRBCTL_CONTROL_STATUS2;
-               } else if (dwc->ep0state == EP0_DATA_PHASE) {
-                       type = DWC3_TRBCTL_CONTROL_DATA;
-               } else {
-                       /* should never happen */
-                       WARN_ON(1);
+               if (dwc->ep0state != EP0_DATA_PHASE) {
+                       dev_WARN(dwc->dev, "Unexpected pending request\n");
                        return 0;
                }
 
                ret = dwc3_ep0_start_trans(dwc, direction,
-                               req->request.dma, req->request.length, type);
+                               req->request.dma, req->request.length,
+                               DWC3_TRBCTL_CONTROL_DATA);
                dep->flags &= ~(DWC3_EP_PENDING_REQUEST |
                                DWC3_EP0_DIR_IN);
        } else if (dwc->delayed_status) {
index a696bde..064b6e2 100644 (file)
@@ -101,7 +101,7 @@ void dwc3_unmap_buffer_from_dma(struct dwc3_request *req)
        if (req->request.num_mapped_sgs) {
                req->request.dma = DMA_ADDR_INVALID;
                dma_unmap_sg(dwc->dev, req->request.sg,
-                               req->request.num_sgs,
+                               req->request.num_mapped_sgs,
                                req->direction ? DMA_TO_DEVICE
                                : DMA_FROM_DEVICE);
 
index a95de6a..baaebf2 100644 (file)
@@ -175,13 +175,12 @@ ep_found:
        _ep->comp_desc = comp_desc;
        if (g->speed == USB_SPEED_SUPER) {
                switch (usb_endpoint_type(_ep->desc)) {
-               case USB_ENDPOINT_XFER_BULK:
-               case USB_ENDPOINT_XFER_INT:
-                       _ep->maxburst = comp_desc->bMaxBurst;
-                       break;
                case USB_ENDPOINT_XFER_ISOC:
                        /* mult: bits 1:0 of bmAttributes */
                        _ep->mult = comp_desc->bmAttributes & 0x3;
+               case USB_ENDPOINT_XFER_BULK:
+               case USB_ENDPOINT_XFER_INT:
+                       _ep->maxburst = comp_desc->bMaxBurst;
                        break;
                default:
                        /* Do nothing for control endpoints */
index 753aa06..e0e6375 100644 (file)
@@ -126,7 +126,7 @@ ep_matches (
         * descriptor and see if the EP matches it
         */
        if (usb_endpoint_xfer_bulk(desc)) {
-               if (ep_comp) {
+               if (ep_comp && gadget->max_speed >= USB_SPEED_SUPER) {
                        num_req_streams = ep_comp->bmAttributes & 0x1f;
                        if (num_req_streams > ep->max_streams)
                                return 0;
index 6d87f28..2c0cd82 100644 (file)
@@ -418,7 +418,7 @@ int __init loopback_add(struct usb_composite_dev *cdev, bool autoresume)
 
        /* support autoresume for remote wakeup testing */
        if (autoresume)
-               sourcesink_driver.bmAttributes |= USB_CONFIG_ATT_WAKEUP;
+               loopback_driver.bmAttributes |= USB_CONFIG_ATT_WAKEUP;
 
        /* support OTG systems */
        if (gadget_is_otg(cdev->gadget)) {
index 6353eca..ee8ceec 100644 (file)
@@ -3123,15 +3123,15 @@ fsg_add(struct usb_composite_dev *cdev, struct usb_configuration *c,
 
 struct fsg_module_parameters {
        char            *file[FSG_MAX_LUNS];
-       int             ro[FSG_MAX_LUNS];
-       int             removable[FSG_MAX_LUNS];
-       int             cdrom[FSG_MAX_LUNS];
-       int             nofua[FSG_MAX_LUNS];
+       bool            ro[FSG_MAX_LUNS];
+       bool            removable[FSG_MAX_LUNS];
+       bool            cdrom[FSG_MAX_LUNS];
+       bool            nofua[FSG_MAX_LUNS];
 
        unsigned int    file_count, ro_count, removable_count, cdrom_count;
        unsigned int    nofua_count;
        unsigned int    luns;   /* nluns */
-       int             stall;  /* can_stall */
+       bool            stall;  /* can_stall */
 };
 
 #define _FSG_MODULE_PARAM_ARRAY(prefix, params, name, type, desc)      \
index d7ea6c0..b04712f 100644 (file)
@@ -1430,7 +1430,7 @@ static void setup_received_irq(struct fsl_udc *udc,
                        int pipe = get_pipe_by_windex(wIndex);
                        struct fsl_ep *ep;
 
-                       if (wValue != 0 || wLength != 0 || pipe > udc->max_ep)
+                       if (wValue != 0 || wLength != 0 || pipe >= udc->max_ep)
                                break;
                        ep = get_ep_by_pipe(udc, pipe);
 
@@ -1673,7 +1673,7 @@ static void dtd_complete_irq(struct fsl_udc *udc)
        if (!bit_pos)
                return;
 
-       for (i = 0; i < udc->max_ep * 2; i++) {
+       for (i = 0; i < udc->max_ep; i++) {
                ep_num = i >> 1;
                direction = i % 2;
 
index fa0fcc1..e2293c1 100644 (file)
 /* #undef      DEBUG */
 /* #undef      VERBOSE_DEBUG */
 
-#if defined(CONFIG_USB_LANGWELL_OTG)
-#define        OTG_TRANSCEIVER
-#endif
-
-
 #include <linux/module.h>
 #include <linux/pci.h>
 #include <linux/dma-mapping.h>
@@ -1522,8 +1517,7 @@ static void langwell_udc_stop(struct langwell_udc *dev)
 
 
 /* stop all USB activities */
-static void stop_activity(struct langwell_udc *dev,
-               struct usb_gadget_driver *driver)
+static void stop_activity(struct langwell_udc *dev)
 {
        struct langwell_ep      *ep;
        dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__);
@@ -1535,9 +1529,9 @@ static void stop_activity(struct langwell_udc *dev,
        }
 
        /* report disconnect; the driver is already quiesced */
-       if (driver) {
+       if (dev->driver) {
                spin_unlock(&dev->lock);
-               driver->disconnect(&dev->gadget);
+               dev->driver->disconnect(&dev->gadget);
                spin_lock(&dev->lock);
        }
 
@@ -1925,11 +1919,10 @@ static int langwell_stop(struct usb_gadget *g,
 
        /* stop all usb activities */
        dev->gadget.speed = USB_SPEED_UNKNOWN;
-       stop_activity(dev, driver);
-       spin_unlock_irqrestore(&dev->lock, flags);
-
        dev->gadget.dev.driver = NULL;
        dev->driver = NULL;
+       stop_activity(dev);
+       spin_unlock_irqrestore(&dev->lock, flags);
 
        device_remove_file(&dev->pdev->dev, &dev_attr_function);
 
@@ -2315,13 +2308,9 @@ static void handle_setup_packet(struct langwell_udc *dev,
 
                        if (!gadget_is_otg(&dev->gadget))
                                break;
-                       else if (setup->bRequest == USB_DEVICE_B_HNP_ENABLE) {
+                       else if (setup->bRequest == USB_DEVICE_B_HNP_ENABLE)
                                dev->gadget.b_hnp_enable = 1;
-#ifdef OTG_TRANSCEIVER
-                               if (!dev->lotg->otg.default_a)
-                                       dev->lotg->hsm.b_hnp_enable = 1;
-#endif
-                       } else if (setup->bRequest == USB_DEVICE_A_HNP_SUPPORT)
+                       else if (setup->bRequest == USB_DEVICE_A_HNP_SUPPORT)
                                dev->gadget.a_hnp_support = 1;
                        else if (setup->bRequest ==
                                        USB_DEVICE_A_ALT_HNP_SUPPORT)
@@ -2733,7 +2722,7 @@ static void handle_usb_reset(struct langwell_udc *dev)
                dev->bus_reset = 1;
 
                /* reset all the queues, stop all USB activities */
-               stop_activity(dev, dev->driver);
+               stop_activity(dev);
                dev->usb_state = USB_STATE_DEFAULT;
        } else {
                dev_vdbg(&dev->pdev->dev, "device controller reset\n");
@@ -2741,7 +2730,7 @@ static void handle_usb_reset(struct langwell_udc *dev)
                langwell_udc_reset(dev);
 
                /* reset all the queues, stop all USB activities */
-               stop_activity(dev, dev->driver);
+               stop_activity(dev);
 
                /* reset ep0 dQH and endptctrl */
                ep0_reset(dev);
@@ -2752,12 +2741,6 @@ static void handle_usb_reset(struct langwell_udc *dev)
                dev->usb_state = USB_STATE_ATTACHED;
        }
 
-#ifdef OTG_TRANSCEIVER
-       /* refer to USB OTG 6.6.2.3 b_hnp_en is cleared */
-       if (!dev->lotg->otg.default_a)
-               dev->lotg->hsm.b_hnp_enable = 0;
-#endif
-
        dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
 }
 
@@ -2770,29 +2753,6 @@ static void handle_bus_suspend(struct langwell_udc *dev)
        dev->resume_state = dev->usb_state;
        dev->usb_state = USB_STATE_SUSPENDED;
 
-#ifdef OTG_TRANSCEIVER
-       if (dev->lotg->otg.default_a) {
-               if (dev->lotg->hsm.b_bus_suspend_vld == 1) {
-                       dev->lotg->hsm.b_bus_suspend = 1;
-                       /* notify transceiver the state changes */
-                       if (spin_trylock(&dev->lotg->wq_lock)) {
-                               langwell_update_transceiver();
-                               spin_unlock(&dev->lotg->wq_lock);
-                       }
-               }
-               dev->lotg->hsm.b_bus_suspend_vld++;
-       } else {
-               if (!dev->lotg->hsm.a_bus_suspend) {
-                       dev->lotg->hsm.a_bus_suspend = 1;
-                       /* notify transceiver the state changes */
-                       if (spin_trylock(&dev->lotg->wq_lock)) {
-                               langwell_update_transceiver();
-                               spin_unlock(&dev->lotg->wq_lock);
-                       }
-               }
-       }
-#endif
-
        /* report suspend to the driver */
        if (dev->driver) {
                if (dev->driver->suspend) {
@@ -2823,11 +2783,6 @@ static void handle_bus_resume(struct langwell_udc *dev)
        if (dev->pdev->device != 0x0829)
                langwell_phy_low_power(dev, 0);
 
-#ifdef OTG_TRANSCEIVER
-       if (dev->lotg->otg.default_a == 0)
-               dev->lotg->hsm.a_bus_suspend = 0;
-#endif
-
        /* report resume to the driver */
        if (dev->driver) {
                if (dev->driver->resume) {
@@ -3020,7 +2975,6 @@ static void langwell_udc_remove(struct pci_dev *pdev)
 
        dev->done = &done;
 
-#ifndef        OTG_TRANSCEIVER
        /* free dTD dma_pool and dQH */
        if (dev->dtd_pool)
                dma_pool_destroy(dev->dtd_pool);
@@ -3032,7 +2986,6 @@ static void langwell_udc_remove(struct pci_dev *pdev)
        /* release SRAM caching */
        if (dev->has_sram && dev->got_sram)
                sram_deinit(dev);
-#endif
 
        if (dev->status_req) {
                kfree(dev->status_req->req.buf);
@@ -3045,7 +2998,6 @@ static void langwell_udc_remove(struct pci_dev *pdev)
        if (dev->got_irq)
                free_irq(pdev->irq, dev);
 
-#ifndef        OTG_TRANSCEIVER
        if (dev->cap_regs)
                iounmap(dev->cap_regs);
 
@@ -3055,13 +3007,6 @@ static void langwell_udc_remove(struct pci_dev *pdev)
 
        if (dev->enabled)
                pci_disable_device(pdev);
-#else
-       if (dev->transceiver) {
-               otg_put_transceiver(dev->transceiver);
-               dev->transceiver = NULL;
-               dev->lotg = NULL;
-       }
-#endif
 
        dev->cap_regs = NULL;
 
@@ -3072,9 +3017,7 @@ static void langwell_udc_remove(struct pci_dev *pdev)
        device_remove_file(&pdev->dev, &dev_attr_langwell_udc);
        device_remove_file(&pdev->dev, &dev_attr_remote_wakeup);
 
-#ifndef        OTG_TRANSCEIVER
        pci_set_drvdata(pdev, NULL);
-#endif
 
        /* free dev, wait for the release() finished */
        wait_for_completion(&done);
@@ -3089,9 +3032,7 @@ static int langwell_udc_probe(struct pci_dev *pdev,
                const struct pci_device_id *id)
 {
        struct langwell_udc     *dev;
-#ifndef        OTG_TRANSCEIVER
        unsigned long           resource, len;
-#endif
        void                    __iomem *base = NULL;
        size_t                  size;
        int                     retval;
@@ -3109,16 +3050,6 @@ static int langwell_udc_probe(struct pci_dev *pdev,
        dev->pdev = pdev;
        dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__);
 
-#ifdef OTG_TRANSCEIVER
-       /* PCI device is already enabled by otg_transceiver driver */
-       dev->enabled = 1;
-
-       /* mem region and register base */
-       dev->region = 1;
-       dev->transceiver = otg_get_transceiver();
-       dev->lotg = otg_to_langwell(dev->transceiver);
-       base = dev->lotg->regs;
-#else
        pci_set_drvdata(pdev, dev);
 
        /* now all the pci goodies ... */
@@ -3139,7 +3070,6 @@ static int langwell_udc_probe(struct pci_dev *pdev,
        dev->region = 1;
 
        base = ioremap_nocache(resource, len);
-#endif
        if (base == NULL) {
                dev_err(&dev->pdev->dev, "can't map memory\n");
                retval = -EFAULT;
@@ -3163,7 +3093,6 @@ static int langwell_udc_probe(struct pci_dev *pdev,
        dev->got_sram = 0;
        dev_vdbg(&dev->pdev->dev, "dev->has_sram: %d\n", dev->has_sram);
 
-#ifndef        OTG_TRANSCEIVER
        /* enable SRAM caching if detected */
        if (dev->has_sram && !dev->got_sram)
                sram_init(dev);
@@ -3182,7 +3111,6 @@ static int langwell_udc_probe(struct pci_dev *pdev,
                goto error;
        }
        dev->got_irq = 1;
-#endif
 
        /* set stopped bit */
        dev->stopped = 1;
@@ -3257,10 +3185,8 @@ static int langwell_udc_probe(struct pci_dev *pdev,
        dev->remote_wakeup = 0;
        dev->dev_status = 1 << USB_DEVICE_SELF_POWERED;
 
-#ifndef        OTG_TRANSCEIVER
        /* reset device controller */
        langwell_udc_reset(dev);
-#endif
 
        /* initialize gadget structure */
        dev->gadget.ops = &langwell_ops;        /* usb_gadget_ops */
@@ -3268,9 +3194,6 @@ static int langwell_udc_probe(struct pci_dev *pdev,
        INIT_LIST_HEAD(&dev->gadget.ep_list);   /* ep_list */
        dev->gadget.speed = USB_SPEED_UNKNOWN;  /* speed */
        dev->gadget.max_speed = USB_SPEED_HIGH; /* support dual speed */
-#ifdef OTG_TRANSCEIVER
-       dev->gadget.is_otg = 1;                 /* support otg mode */
-#endif
 
        /* the "gadget" abstracts/virtualizes the controller */
        dev_set_name(&dev->gadget.dev, "gadget");
@@ -3282,10 +3205,8 @@ static int langwell_udc_probe(struct pci_dev *pdev,
        /* controller endpoints reinit */
        eps_reinit(dev);
 
-#ifndef        OTG_TRANSCEIVER
        /* reset ep0 dQH and endptctrl */
        ep0_reset(dev);
-#endif
 
        /* create dTD dma_pool resource */
        dev->dtd_pool = dma_pool_create("langwell_dtd",
@@ -3367,7 +3288,7 @@ static int langwell_udc_suspend(struct pci_dev *pdev, pm_message_t state)
 
        spin_lock_irq(&dev->lock);
        /* stop all usb activities */
-       stop_activity(dev, dev->driver);
+       stop_activity(dev);
        spin_unlock_irq(&dev->lock);
 
        /* free dTD dma_pool and dQH */
@@ -3525,22 +3446,14 @@ static struct pci_driver langwell_pci_driver = {
 
 static int __init init(void)
 {
-#ifdef OTG_TRANSCEIVER
-       return langwell_register_peripheral(&langwell_pci_driver);
-#else
        return pci_register_driver(&langwell_pci_driver);
-#endif
 }
 module_init(init);
 
 
 static void __exit cleanup(void)
 {
-#ifdef OTG_TRANSCEIVER
-       return langwell_unregister_peripheral(&langwell_pci_driver);
-#else
        pci_unregister_driver(&langwell_pci_driver);
-#endif
 }
 module_exit(cleanup);
 
index ef79e24..d6e78ac 100644 (file)
@@ -8,7 +8,6 @@
  */
 
 #include <linux/usb/langwell_udc.h>
-#include <linux/usb/langwell_otg.h>
 
 /*-------------------------------------------------------------------------*/
 
index c7f291a..85ea14e 100644 (file)
@@ -598,16 +598,16 @@ static __maybe_unused struct usb_ss_cap_descriptor fsg_ss_cap_desc = {
                | USB_5GBPS_OPERATION),
        .bFunctionalitySupport = USB_LOW_SPEED_OPERATION,
        .bU1devExitLat =        USB_DEFAULT_U1_DEV_EXIT_LAT,
-       .bU2DevExitLat =        USB_DEFAULT_U2_DEV_EXIT_LAT,
+       .bU2DevExitLat =        cpu_to_le16(USB_DEFAULT_U2_DEV_EXIT_LAT),
 };
 
 static __maybe_unused struct usb_bos_descriptor fsg_bos_desc = {
        .bLength =              USB_DT_BOS_SIZE,
        .bDescriptorType =      USB_DT_BOS,
 
-       .wTotalLength =         USB_DT_BOS_SIZE
+       .wTotalLength =         cpu_to_le16(USB_DT_BOS_SIZE
                                + USB_DT_USB_EXT_CAP_SIZE
-                               + USB_DT_USB_SS_CAP_SIZE,
+                               + USB_DT_USB_SS_CAP_SIZE),
 
        .bNumDeviceCaps =       2,
 };
index 91413ca..353cdd4 100644 (file)
@@ -130,7 +130,7 @@ config USB_FSL_MPH_DR_OF
        tristate
 
 config USB_EHCI_FSL
-       bool "Support for Freescale on-chip EHCI USB controller"
+       bool "Support for Freescale PPC on-chip EHCI USB controller"
        depends on USB_EHCI_HCD && FSL_SOC
        select USB_EHCI_ROOT_HUB_TT
        select USB_FSL_MPH_DR_OF if OF
@@ -138,7 +138,7 @@ config USB_EHCI_FSL
          Variation of ARC USB block used in some Freescale chips.
 
 config USB_EHCI_MXC
-       bool "Support for Freescale on-chip EHCI USB controller"
+       bool "Support for Freescale i.MX on-chip EHCI USB controller"
        depends on USB_EHCI_HCD && ARCH_MXC
        select USB_EHCI_ROOT_HUB_TT
        ---help---
@@ -546,7 +546,7 @@ config USB_RENESAS_USBHS_HCD
 config USB_WHCI_HCD
        tristate "Wireless USB Host Controller Interface (WHCI) driver (EXPERIMENTAL)"
        depends on EXPERIMENTAL
-       depends on PCI && USB
+       depends on PCI && USB && UWB
        select USB_WUSB
        select UWB_WHCI
        help
@@ -559,7 +559,7 @@ config USB_WHCI_HCD
 config USB_HWA_HCD
        tristate "Host Wire Adapter (HWA) driver (EXPERIMENTAL)"
        depends on EXPERIMENTAL
-       depends on USB
+       depends on USB && UWB
        select USB_WUSB
        select UWB_HWA
        help
index e90344a..c26a82e 100644 (file)
@@ -125,7 +125,7 @@ static int usb_hcd_fsl_probe(const struct hc_driver *driver,
         */
        if (pdata->init && pdata->init(pdev)) {
                retval = -ENODEV;
-               goto err3;
+               goto err4;
        }
 
        /* Enable USB controller, 83xx or 8536 */
@@ -239,7 +239,7 @@ static void ehci_fsl_setup_phy(struct ehci_hcd *ehci,
        ehci_writel(ehci, portsc, &ehci->regs->port_status[port_offset]);
 }
 
-static void ehci_fsl_usb_setup(struct ehci_hcd *ehci)
+static int ehci_fsl_usb_setup(struct ehci_hcd *ehci)
 {
        struct usb_hcd *hcd = ehci_to_hcd(ehci);
        struct fsl_usb2_platform_data *pdata;
@@ -299,12 +299,19 @@ static void ehci_fsl_usb_setup(struct ehci_hcd *ehci)
 #endif
                out_be32(non_ehci + FSL_SOC_USB_SICTRL, 0x00000001);
        }
+
+       if (!(in_be32(non_ehci + FSL_SOC_USB_CTRL) & CTRL_PHY_CLK_VALID)) {
+               printk(KERN_WARNING "fsl-ehci: USB PHY clock invalid\n");
+               return -ENODEV;
+       }
+       return 0;
 }
 
 /* called after powerup, by probe or system-pm "wakeup" */
 static int ehci_fsl_reinit(struct ehci_hcd *ehci)
 {
-       ehci_fsl_usb_setup(ehci);
+       if (ehci_fsl_usb_setup(ehci))
+               return -ENODEV;
        ehci_port_power(ehci, 0);
 
        return 0;
index 4918062..bdf43e2 100644 (file)
@@ -45,5 +45,6 @@
 #define FSL_SOC_USB_PRICTRL    0x40c   /* NOTE: big-endian */
 #define FSL_SOC_USB_SICTRL     0x410   /* NOTE: big-endian */
 #define FSL_SOC_USB_CTRL       0x500   /* NOTE: big-endian */
+#define CTRL_PHY_CLK_VALID     (1 << 17)
 #define SNOOP_SIZE_2GB         0x1e
 #endif                         /* _EHCI_FSL_H */
index f4b627d..01bb724 100644 (file)
@@ -276,6 +276,9 @@ static int ehci_pci_setup(struct usb_hcd *hcd)
 
        /* Serial Bus Release Number is at PCI 0x60 offset */
        pci_read_config_byte(pdev, 0x60, &ehci->sbrn);
+       if (pdev->vendor == PCI_VENDOR_ID_STMICRO
+           && pdev->device == PCI_DEVICE_ID_STMICRO_USB_HOST)
+               ehci->sbrn = 0x20; /* ConneXT has no sbrn register */
 
        /* Keep this around for a while just in case some EHCI
         * implementation uses legacy PCI PM support.  This test
@@ -526,6 +529,9 @@ static const struct pci_device_id pci_ids [] = { {
        /* handle any USB 2.0 EHCI controller */
        PCI_DEVICE_CLASS(PCI_CLASS_SERIAL_USB_EHCI, ~0),
        .driver_data =  (unsigned long) &ehci_pci_hc_driver,
+       }, {
+       PCI_VDEVICE(STMICRO, PCI_DEVICE_ID_STMICRO_USB_HOST),
+       .driver_data = (unsigned long) &ehci_pci_hc_driver,
        },
        { /* end: all zeroes */ }
 };
index 5df0b0e..77afabc 100644 (file)
@@ -139,8 +139,23 @@ static int usb_hcd_at91_probe(const struct hc_driver *driver,
        }
 
        iclk = clk_get(&pdev->dev, "ohci_clk");
+       if (IS_ERR(iclk)) {
+               dev_err(&pdev->dev, "failed to get ohci_clk\n");
+               retval = PTR_ERR(iclk);
+               goto err3;
+       }
        fclk = clk_get(&pdev->dev, "uhpck");
+       if (IS_ERR(fclk)) {
+               dev_err(&pdev->dev, "failed to get uhpck\n");
+               retval = PTR_ERR(fclk);
+               goto err4;
+       }
        hclk = clk_get(&pdev->dev, "hclk");
+       if (IS_ERR(hclk)) {
+               dev_err(&pdev->dev, "failed to get hclk\n");
+               retval = PTR_ERR(hclk);
+               goto err5;
+       }
 
        at91_start_hc(pdev);
        ohci_hcd_init(hcd_to_ohci(hcd));
@@ -153,9 +168,12 @@ static int usb_hcd_at91_probe(const struct hc_driver *driver,
        at91_stop_hc(pdev);
 
        clk_put(hclk);
+ err5:
        clk_put(fclk);
+ err4:
        clk_put(iclk);
 
+ err3:
        iounmap(hcd->regs);
 
  err2:
@@ -226,7 +244,8 @@ static void ohci_at91_usb_set_power(struct at91_usbh_data *pdata, int port, int
        if (!gpio_is_valid(pdata->vbus_pin[port]))
                return;
 
-       gpio_set_value(pdata->vbus_pin[port], !pdata->vbus_pin_inverted ^ enable);
+       gpio_set_value(pdata->vbus_pin[port],
+                      !pdata->vbus_pin_active_low[port] ^ enable);
 }
 
 static int ohci_at91_usb_get_power(struct at91_usbh_data *pdata, int port)
@@ -237,7 +256,8 @@ static int ohci_at91_usb_get_power(struct at91_usbh_data *pdata, int port)
        if (!gpio_is_valid(pdata->vbus_pin[port]))
                return -EINVAL;
 
-       return gpio_get_value(pdata->vbus_pin[port]) ^ !pdata->vbus_pin_inverted;
+       return gpio_get_value(pdata->vbus_pin[port]) ^
+               !pdata->vbus_pin_active_low[port];
 }
 
 /*
index 5179fcd..e4bcb62 100644 (file)
@@ -82,6 +82,14 @@ urb_print(struct urb * urb, char * str, int small, int status)
                ohci_dbg(ohci,format, ## arg ); \
        } while (0);
 
+/* Version for use where "next" is the address of a local variable */
+#define ohci_dbg_nosw(ohci, next, size, format, arg...) \
+       do { \
+               unsigned s_len; \
+               s_len = scnprintf(*next, *size, format, ## arg); \
+               *size -= s_len; *next += s_len; \
+       } while (0);
+
 
 static void ohci_dump_intr_mask (
        struct ohci_hcd *ohci,
@@ -653,7 +661,7 @@ static ssize_t fill_registers_buffer(struct debug_buffer *buf)
 
        /* dump driver info, then registers in spec order */
 
-       ohci_dbg_sw (ohci, &next, &size,
+       ohci_dbg_nosw(ohci, &next, &size,
                "bus %s, device %s\n"
                "%s\n"
                "%s\n",
@@ -672,7 +680,7 @@ static ssize_t fill_registers_buffer(struct debug_buffer *buf)
 
        /* hcca */
        if (ohci->hcca)
-               ohci_dbg_sw (ohci, &next, &size,
+               ohci_dbg_nosw(ohci, &next, &size,
                        "hcca frame 0x%04x\n", ohci_frame_no(ohci));
 
        /* other registers mostly affect frame timings */
index 6109810..1843bb6 100644 (file)
@@ -397,6 +397,10 @@ static const struct pci_device_id pci_ids [] = { {
        /* handle any USB OHCI controller */
        PCI_DEVICE_CLASS(PCI_CLASS_SERIAL_USB_OHCI, ~0),
        .driver_data =  (unsigned long) &ohci_pci_hc_driver,
+       }, {
+       /* The device in the ConneXT I/O hub has no class reg */
+       PCI_VDEVICE(STMICRO, PCI_DEVICE_ID_STMICRO_USB_OHCI),
+       .driver_data =  (unsigned long) &ohci_pci_hc_driver,
        }, { /* end: all zeroes */ }
 };
 MODULE_DEVICE_TABLE (pci, pci_ids);
index caf8742..ac53a66 100644 (file)
@@ -867,6 +867,12 @@ hc_init:
 
 static void __devinit quirk_usb_early_handoff(struct pci_dev *pdev)
 {
+       /* Skip Netlogic mips SoC's internal PCI USB controller.
+        * This device does not need/support EHCI/OHCI handoff
+        */
+       if (pdev->vendor == 0x184e)     /* vendor Netlogic */
+               return;
+
        if (pdev->class == PCI_CLASS_SERIAL_USB_UHCI)
                quirk_usb_handoff_uhci(pdev);
        else if (pdev->class == PCI_CLASS_SERIAL_USB_OHCI)
index b90e138..b62037b 100644 (file)
@@ -1204,6 +1204,7 @@ static void handle_vendor_event(struct xhci_hcd *xhci,
  *
  * Returns a zero-based port number, which is suitable for indexing into each of
  * the split roothubs' port arrays and bus state arrays.
+ * Add one to it in order to call xhci_find_slot_id_by_port.
  */
 static unsigned int find_faked_portnum_from_hw_portnum(struct usb_hcd *hcd,
                struct xhci_hcd *xhci, u32 port_id)
@@ -1324,7 +1325,7 @@ static void handle_port_status(struct xhci_hcd *xhci,
                        xhci_set_link_state(xhci, port_array, faked_port_index,
                                                XDEV_U0);
                        slot_id = xhci_find_slot_id_by_port(hcd, xhci,
-                                       faked_port_index);
+                                       faked_port_index + 1);
                        if (!slot_id) {
                                xhci_dbg(xhci, "slot_id is zero\n");
                                goto cleanup;
@@ -3323,7 +3324,8 @@ static int xhci_queue_isoc_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
                /* Check TD length */
                if (running_total != td_len) {
                        xhci_err(xhci, "ISOC TD length unmatch\n");
-                       return -EINVAL;
+                       ret = -EINVAL;
+                       goto cleanup;
                }
        }
 
index d9b6a03..da97dce 100644 (file)
@@ -37,9 +37,6 @@ static int emi26_set_reset(struct usb_device *dev, unsigned char reset_bit);
 static int emi26_load_firmware (struct usb_device *dev);
 static int emi26_probe(struct usb_interface *intf, const struct usb_device_id *id);
 static void emi26_disconnect(struct usb_interface *intf);
-static int __init emi26_init (void);
-static void __exit emi26_exit (void);
-
 
 /* thanks to drivers/usb/serial/keyspan_pda.c code */
 static int emi26_writememory (struct usb_device *dev, int address,
index 9f39062..4e0f167 100644 (file)
@@ -46,9 +46,6 @@ static int emi62_set_reset(struct usb_device *dev, unsigned char reset_bit);
 static int emi62_load_firmware (struct usb_device *dev);
 static int emi62_probe(struct usb_interface *intf, const struct usb_device_id *id);
 static void emi62_disconnect(struct usb_interface *intf);
-static int __init emi62_init (void);
-static void __exit emi62_exit (void);
-
 
 /* thanks to drivers/usb/serial/keyspan_pda.c code */
 static int emi62_writememory(struct usb_device *dev, int address,
index 107bf13..b2d82b9 100644 (file)
@@ -24,7 +24,7 @@
 
 #define VENDOR_ID      0x0fc5
 #define PRODUCT_ID     0x1227
-#define MAXLEN         6
+#define MAXLEN         8
 
 /* table of devices that work with this driver */
 static const struct usb_device_id id_table[] = {
index f9a3f62..7c569f5 100644 (file)
@@ -33,9 +33,6 @@
 #include <linux/platform_device.h>
 #include <linux/dma-mapping.h>
 
-#include <mach/hardware.h>
-#include <mach/memory.h>
-#include <asm/gpio.h>
 #include <mach/cputype.h>
 
 #include <asm/mach-types.h>
index 56cf024..3d11cf6 100644 (file)
@@ -981,6 +981,9 @@ static void musb_shutdown(struct platform_device *pdev)
        unsigned long   flags;
 
        pm_runtime_get_sync(musb->controller);
+
+       musb_gadget_cleanup(musb);
+
        spin_lock_irqsave(&musb->lock, flags);
        musb_platform_disable(musb);
        musb_generic_disable(musb);
@@ -1827,8 +1830,6 @@ static void musb_free(struct musb *musb)
        sysfs_remove_group(&musb->controller->kobj, &musb_attr_group);
 #endif
 
-       musb_gadget_cleanup(musb);
-
        if (musb->nIrq >= 0) {
                if (musb->irq_wake)
                        disable_irq_wake(musb->nIrq);
index e61aa95..1d5eda2 100644 (file)
@@ -39,7 +39,8 @@
 
 #if !defined(CONFIG_ARM) && !defined(CONFIG_SUPERH) \
        && !defined(CONFIG_AVR32) && !defined(CONFIG_PPC32) \
-       && !defined(CONFIG_PPC64) && !defined(CONFIG_BLACKFIN)
+       && !defined(CONFIG_PPC64) && !defined(CONFIG_BLACKFIN) \
+       && !defined(CONFIG_MIPS)
 static inline void readsl(const void __iomem *addr, void *buf, int len)
        { insl((unsigned long)addr, buf, len); }
 static inline void readsw(const void __iomem *addr, void *buf, int len)
index c27bbbf..df719ea 100644 (file)
@@ -222,7 +222,6 @@ static inline void omap2430_low_level_init(struct musb *musb)
        musb_writel(musb->mregs, OTG_FORCESTDBY, l);
 }
 
-/* blocking notifier support */
 static int musb_otg_notifications(struct notifier_block *nb,
                unsigned long event, void *unused)
 {
@@ -231,7 +230,7 @@ static int musb_otg_notifications(struct notifier_block *nb,
        musb->xceiv_event = event;
        schedule_work(&musb->otg_notifier_work);
 
-       return 0;
+       return NOTIFY_OK;
 }
 
 static void musb_otg_notifier_work(struct work_struct *data_notifier_work)
@@ -386,6 +385,7 @@ static void omap2430_musb_disable(struct musb *musb)
 static int omap2430_musb_exit(struct musb *musb)
 {
        del_timer_sync(&musb_idle_timer);
+       cancel_work_sync(&musb->otg_notifier_work);
 
        omap2430_low_level_exit(musb);
        otg_put_transceiver(musb->xceiv);
index 2a25955..735ef4c 100644 (file)
@@ -86,20 +86,6 @@ config NOP_USB_XCEIV
          built-in with usb ip or which are autonomous and doesn't require any
          phy programming such as ISP1x04 etc.
 
-config USB_LANGWELL_OTG
-       tristate "Intel Langwell USB OTG dual-role support"
-       depends on USB && PCI && INTEL_SCU_IPC
-       select USB_OTG
-       select USB_OTG_UTILS
-       help
-         Say Y here if you want to build Intel Langwell USB OTG
-         transciever driver in kernel. This driver implements role
-         switch between EHCI host driver and Langwell USB OTG
-         client driver.
-
-         To compile this driver as a module, choose M here: the
-         module will be called langwell_otg.
-
 config USB_MSM_OTG
        tristate "OTG support for Qualcomm on-chip USB controller"
        depends on (USB || USB_GADGET) && ARCH_MSM
@@ -124,7 +110,7 @@ config AB8500_USB
 
 config FSL_USB2_OTG
        bool "Freescale USB OTG Transceiver Driver"
-       depends on USB_EHCI_FSL && USB_GADGET_FSL_USB2
+       depends on USB_EHCI_FSL && USB_GADGET_FSL_USB2 && USB_SUSPEND
        select USB_OTG
        select USB_OTG_UTILS
        help
@@ -132,7 +118,7 @@ config FSL_USB2_OTG
 
 config USB_MV_OTG
        tristate "Marvell USB OTG support"
-       depends on USB_MV_UDC
+       depends on USB_EHCI_MV && USB_MV_UDC && USB_SUSPEND
        select USB_OTG
        select USB_OTG_UTILS
        help
index b2c5a95..41aa509 100644 (file)
@@ -13,7 +13,6 @@ obj-$(CONFIG_USB_GPIO_VBUS)   += gpio_vbus.o
 obj-$(CONFIG_ISP1301_OMAP)     += isp1301_omap.o
 obj-$(CONFIG_TWL4030_USB)      += twl4030-usb.o
 obj-$(CONFIG_TWL6030_USB)      += twl6030-usb.o
-obj-$(CONFIG_USB_LANGWELL_OTG) += langwell_otg.o
 obj-$(CONFIG_NOP_USB_XCEIV)    += nop-usb-xceiv.o
 obj-$(CONFIG_USB_ULPI)         += ulpi.o
 obj-$(CONFIG_USB_ULPI_VIEWPORT)        += ulpi_viewport.o
diff --git a/drivers/usb/otg/langwell_otg.c b/drivers/usb/otg/langwell_otg.c
deleted file mode 100644 (file)
index f08f784..0000000
+++ /dev/null
@@ -1,2347 +0,0 @@
-/*
- * Intel Langwell USB OTG transceiver driver
- * Copyright (C) 2008 - 2010, Intel Corporation.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-/* This driver helps to switch Langwell OTG controller function between host
- * and peripheral. It works with EHCI driver and Langwell client controller
- * driver together.
- */
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/pci.h>
-#include <linux/errno.h>
-#include <linux/interrupt.h>
-#include <linux/kernel.h>
-#include <linux/device.h>
-#include <linux/moduleparam.h>
-#include <linux/usb/ch9.h>
-#include <linux/usb/gadget.h>
-#include <linux/usb.h>
-#include <linux/usb/otg.h>
-#include <linux/usb/hcd.h>
-#include <linux/notifier.h>
-#include <linux/delay.h>
-#include <asm/intel_scu_ipc.h>
-
-#include <linux/usb/langwell_otg.h>
-
-#define        DRIVER_DESC             "Intel Langwell USB OTG transceiver driver"
-#define        DRIVER_VERSION          "July 10, 2010"
-
-MODULE_DESCRIPTION(DRIVER_DESC);
-MODULE_AUTHOR("Henry Yuan <hang.yuan@intel.com>, Hao Wu <hao.wu@intel.com>");
-MODULE_VERSION(DRIVER_VERSION);
-MODULE_LICENSE("GPL");
-
-static const char driver_name[] = "langwell_otg";
-
-static int langwell_otg_probe(struct pci_dev *pdev,
-                       const struct pci_device_id *id);
-static void langwell_otg_remove(struct pci_dev *pdev);
-static int langwell_otg_suspend(struct pci_dev *pdev, pm_message_t message);
-static int langwell_otg_resume(struct pci_dev *pdev);
-
-static int langwell_otg_set_host(struct otg_transceiver *otg,
-                               struct usb_bus *host);
-static int langwell_otg_set_peripheral(struct otg_transceiver *otg,
-                               struct usb_gadget *gadget);
-static int langwell_otg_start_srp(struct otg_transceiver *otg);
-
-static const struct pci_device_id pci_ids[] = {{
-       .class =        ((PCI_CLASS_SERIAL_USB << 8) | 0xfe),
-       .class_mask =   ~0,
-       .vendor =       0x8086,
-       .device =       0x0811,
-       .subvendor =    PCI_ANY_ID,
-       .subdevice =    PCI_ANY_ID,
-}, { /* end: all zeroes */ }
-};
-
-static struct pci_driver otg_pci_driver = {
-       .name =         (char *) driver_name,
-       .id_table =     pci_ids,
-
-       .probe =        langwell_otg_probe,
-       .remove =       langwell_otg_remove,
-
-       .suspend =      langwell_otg_suspend,
-       .resume =       langwell_otg_resume,
-};
-
-/* HSM timers */
-static inline struct langwell_otg_timer *otg_timer_initializer
-(void (*function)(unsigned long), unsigned long expires, unsigned long data)
-{
-       struct langwell_otg_timer *timer;
-       timer = kmalloc(sizeof(struct langwell_otg_timer), GFP_KERNEL);
-       if (timer == NULL)
-               return timer;
-
-       timer->function = function;
-       timer->expires = expires;
-       timer->data = data;
-       return timer;
-}
-
-static struct langwell_otg_timer *a_wait_vrise_tmr, *a_aidl_bdis_tmr,
-       *b_se0_srp_tmr, *b_srp_init_tmr;
-
-static struct list_head active_timers;
-
-static struct langwell_otg *the_transceiver;
-
-/* host/client notify transceiver when event affects HNP state */
-void langwell_update_transceiver(void)
-{
-       struct langwell_otg *lnw = the_transceiver;
-
-       dev_dbg(lnw->dev, "transceiver is updated\n");
-
-       if (!lnw->qwork)
-               return ;
-
-       queue_work(lnw->qwork, &lnw->work);
-}
-EXPORT_SYMBOL(langwell_update_transceiver);
-
-static int langwell_otg_set_host(struct otg_transceiver *otg,
-                                       struct usb_bus *host)
-{
-       otg->host = host;
-
-       return 0;
-}
-
-static int langwell_otg_set_peripheral(struct otg_transceiver *otg,
-                                       struct usb_gadget *gadget)
-{
-       otg->gadget = gadget;
-
-       return 0;
-}
-
-static int langwell_otg_set_power(struct otg_transceiver *otg,
-                               unsigned mA)
-{
-       return 0;
-}
-
-/* A-device drives vbus, controlled through IPC commands */
-static int langwell_otg_set_vbus(struct otg_transceiver *otg, bool enabled)
-{
-       struct langwell_otg             *lnw = the_transceiver;
-       u8                              sub_id;
-
-       dev_dbg(lnw->dev, "%s <--- %s\n", __func__, enabled ? "on" : "off");
-
-       if (enabled)
-               sub_id = 0x8; /* Turn on the VBus */
-       else
-               sub_id = 0x9; /* Turn off the VBus */
-
-       if (intel_scu_ipc_simple_command(0xef, sub_id)) {
-               dev_dbg(lnw->dev, "Failed to set Vbus via IPC commands\n");
-               return -EBUSY;
-       }
-
-       dev_dbg(lnw->dev, "%s --->\n", __func__);
-
-       return 0;
-}
-
-/* charge vbus or discharge vbus through a resistor to ground */
-static void langwell_otg_chrg_vbus(int on)
-{
-       struct langwell_otg     *lnw = the_transceiver;
-       u32     val;
-
-       val = readl(lnw->iotg.base + CI_OTGSC);
-
-       if (on)
-               writel((val & ~OTGSC_INTSTS_MASK) | OTGSC_VC,
-                               lnw->iotg.base + CI_OTGSC);
-       else
-               writel((val & ~OTGSC_INTSTS_MASK) | OTGSC_VD,
-                               lnw->iotg.base + CI_OTGSC);
-}
-
-/* Start SRP */
-static int langwell_otg_start_srp(struct otg_transceiver *otg)
-{
-       struct langwell_otg             *lnw = the_transceiver;
-       struct intel_mid_otg_xceiv      *iotg = &lnw->iotg;
-       u32                             val;
-
-       dev_dbg(lnw->dev, "%s --->\n", __func__);
-
-       val = readl(iotg->base + CI_OTGSC);
-
-       writel((val & ~OTGSC_INTSTS_MASK) | OTGSC_HADP,
-                               iotg->base + CI_OTGSC);
-
-       /* Check if the data plus is finished or not */
-       msleep(8);
-       val = readl(iotg->base + CI_OTGSC);
-       if (val & (OTGSC_HADP | OTGSC_DP))
-               dev_dbg(lnw->dev, "DataLine SRP Error\n");
-
-       /* Disable interrupt - b_sess_vld */
-       val = readl(iotg->base + CI_OTGSC);
-       val &= (~(OTGSC_BSVIE | OTGSC_BSEIE));
-       writel(val, iotg->base + CI_OTGSC);
-
-       /* Start VBus SRP, drive vbus to generate VBus pulse */
-       iotg->otg.set_vbus(&iotg->otg, true);
-       msleep(15);
-       iotg->otg.set_vbus(&iotg->otg, false);
-
-       /* Enable interrupt - b_sess_vld*/
-       val = readl(iotg->base + CI_OTGSC);
-       dev_dbg(lnw->dev, "after VBUS pulse otgsc = %x\n", val);
-
-       val |= (OTGSC_BSVIE | OTGSC_BSEIE);
-       writel(val, iotg->base + CI_OTGSC);
-
-       /* If Vbus is valid, then update the hsm */
-       if (val & OTGSC_BSV) {
-               dev_dbg(lnw->dev, "no b_sess_vld interrupt\n");
-
-               lnw->iotg.hsm.b_sess_vld = 1;
-               langwell_update_transceiver();
-       }
-
-       dev_dbg(lnw->dev, "%s <---\n", __func__);
-       return 0;
-}
-
-/* stop SOF via bus_suspend */
-static void langwell_otg_loc_sof(int on)
-{
-       struct langwell_otg     *lnw = the_transceiver;
-       struct usb_hcd          *hcd;
-       int                     err;
-
-       dev_dbg(lnw->dev, "%s ---> %s\n", __func__, on ? "suspend" : "resume");
-
-       hcd = bus_to_hcd(lnw->iotg.otg.host);
-       if (on)
-               err = hcd->driver->bus_resume(hcd);
-       else
-               err = hcd->driver->bus_suspend(hcd);
-
-       if (err)
-               dev_dbg(lnw->dev, "Fail to resume/suspend USB bus - %d\n", err);
-
-       dev_dbg(lnw->dev, "%s <---\n", __func__);
-}
-
-static int langwell_otg_check_otgsc(void)
-{
-       struct langwell_otg             *lnw = the_transceiver;
-       u32                             otgsc, usbcfg;
-
-       dev_dbg(lnw->dev, "check sync OTGSC and USBCFG registers\n");
-
-       otgsc = readl(lnw->iotg.base + CI_OTGSC);
-       usbcfg = readl(lnw->usbcfg);
-
-       dev_dbg(lnw->dev, "OTGSC = %08x, USBCFG = %08x\n",
-                                       otgsc, usbcfg);
-       dev_dbg(lnw->dev, "OTGSC_AVV = %d\n", !!(otgsc & OTGSC_AVV));
-       dev_dbg(lnw->dev, "USBCFG.VBUSVAL = %d\n",
-                                       !!(usbcfg & USBCFG_VBUSVAL));
-       dev_dbg(lnw->dev, "OTGSC_ASV = %d\n", !!(otgsc & OTGSC_ASV));
-       dev_dbg(lnw->dev, "USBCFG.AVALID = %d\n",
-                                       !!(usbcfg & USBCFG_AVALID));
-       dev_dbg(lnw->dev, "OTGSC_BSV = %d\n", !!(otgsc & OTGSC_BSV));
-       dev_dbg(lnw->dev, "USBCFG.BVALID = %d\n",
-                                       !!(usbcfg & USBCFG_BVALID));
-       dev_dbg(lnw->dev, "OTGSC_BSE = %d\n", !!(otgsc & OTGSC_BSE));
-       dev_dbg(lnw->dev, "USBCFG.SESEND = %d\n",
-                                       !!(usbcfg & USBCFG_SESEND));
-
-       /* Check USBCFG VBusValid/AValid/BValid/SessEnd */
-       if (!!(otgsc & OTGSC_AVV) ^ !!(usbcfg & USBCFG_VBUSVAL)) {
-               dev_dbg(lnw->dev, "OTGSC.AVV != USBCFG.VBUSVAL\n");
-               goto err;
-       }
-       if (!!(otgsc & OTGSC_ASV) ^ !!(usbcfg & USBCFG_AVALID)) {
-               dev_dbg(lnw->dev, "OTGSC.ASV != USBCFG.AVALID\n");
-               goto err;
-       }
-       if (!!(otgsc & OTGSC_BSV) ^ !!(usbcfg & USBCFG_BVALID)) {
-               dev_dbg(lnw->dev, "OTGSC.BSV != USBCFG.BVALID\n");
-               goto err;
-       }
-       if (!!(otgsc & OTGSC_BSE) ^ !!(usbcfg & USBCFG_SESEND)) {
-               dev_dbg(lnw->dev, "OTGSC.BSE != USBCFG.SESSEN\n");
-               goto err;
-       }
-
-       dev_dbg(lnw->dev, "OTGSC and USBCFG are synced\n");
-
-       return 0;
-
-err:
-       dev_warn(lnw->dev, "OTGSC isn't equal to USBCFG\n");
-       return -EPIPE;
-}
-
-
-static void langwell_otg_phy_low_power(int on)
-{
-       struct langwell_otg             *lnw = the_transceiver;
-       struct intel_mid_otg_xceiv      *iotg = &lnw->iotg;
-       u8                              val, phcd;
-       int                             retval;
-
-       dev_dbg(lnw->dev, "%s ---> %s mode\n",
-                       __func__, on ? "Low power" : "Normal");
-
-       phcd = 0x40;
-
-       val = readb(iotg->base + CI_HOSTPC1 + 2);
-
-       if (on) {
-               /* Due to hardware issue, after set PHCD, sync will failed
-                * between USBCFG and OTGSC, so before set PHCD, check if
-                * sync is in process now. If the answer is "yes", then do
-                * not touch PHCD bit */
-               retval = langwell_otg_check_otgsc();
-               if (retval) {
-                       dev_dbg(lnw->dev, "Skip PHCD programming..\n");
-                       return ;
-               }
-
-               writeb(val | phcd, iotg->base + CI_HOSTPC1 + 2);
-       } else
-               writeb(val & ~phcd, iotg->base + CI_HOSTPC1 + 2);
-
-       dev_dbg(lnw->dev, "%s <--- done\n", __func__);
-}
-
-/* After drv vbus, add 5 ms delay to set PHCD */
-static void langwell_otg_phy_low_power_wait(int on)
-{
-       struct langwell_otg     *lnw = the_transceiver;
-
-       dev_dbg(lnw->dev, "add 5ms delay before programing PHCD\n");
-
-       mdelay(5);
-       langwell_otg_phy_low_power(on);
-}
-
-/* Enable/Disable OTG interrupt */
-static void langwell_otg_intr(int on)
-{
-       struct langwell_otg             *lnw = the_transceiver;
-       struct intel_mid_otg_xceiv      *iotg = &lnw->iotg;
-       u32                             val;
-
-       dev_dbg(lnw->dev, "%s ---> %s\n", __func__, on ? "on" : "off");
-
-       val = readl(iotg->base + CI_OTGSC);
-
-       /* OTGSC_INT_MASK doesn't contains 1msInt */
-       if (on) {
-               val = val | (OTGSC_INT_MASK);
-               writel(val, iotg->base + CI_OTGSC);
-       } else {
-               val = val & ~(OTGSC_INT_MASK);
-               writel(val, iotg->base + CI_OTGSC);
-       }
-
-       dev_dbg(lnw->dev, "%s <---\n", __func__);
-}
-
-/* set HAAR: Hardware Assist Auto-Reset */
-static void langwell_otg_HAAR(int on)
-{
-       struct langwell_otg             *lnw = the_transceiver;
-       struct intel_mid_otg_xceiv      *iotg = &lnw->iotg;
-       u32                             val;
-
-       dev_dbg(lnw->dev, "%s ---> %s\n", __func__, on ? "on" : "off");
-
-       val = readl(iotg->base + CI_OTGSC);
-       if (on)
-               writel((val & ~OTGSC_INTSTS_MASK) | OTGSC_HAAR,
-                                       iotg->base + CI_OTGSC);
-       else
-               writel((val & ~OTGSC_INTSTS_MASK) & ~OTGSC_HAAR,
-                                       iotg->base + CI_OTGSC);
-
-       dev_dbg(lnw->dev, "%s <---\n", __func__);
-}
-
-/* set HABA: Hardware Assist B-Disconnect to A-Connect */
-static void langwell_otg_HABA(int on)
-{
-       struct langwell_otg             *lnw = the_transceiver;
-       struct intel_mid_otg_xceiv      *iotg = &lnw->iotg;
-       u32                             val;
-
-       dev_dbg(lnw->dev, "%s ---> %s\n", __func__, on ? "on" : "off");
-
-       val = readl(iotg->base + CI_OTGSC);
-       if (on)
-               writel((val & ~OTGSC_INTSTS_MASK) | OTGSC_HABA,
-                                       iotg->base + CI_OTGSC);
-       else
-               writel((val & ~OTGSC_INTSTS_MASK) & ~OTGSC_HABA,
-                                       iotg->base + CI_OTGSC);
-
-       dev_dbg(lnw->dev, "%s <---\n", __func__);
-}
-
-static int langwell_otg_check_se0_srp(int on)
-{
-       struct langwell_otg     *lnw = the_transceiver;
-       int                     delay_time = TB_SE0_SRP * 10;
-       u32                     val;
-
-       dev_dbg(lnw->dev, "%s --->\n", __func__);
-
-       do {
-               udelay(100);
-               if (!delay_time--)
-                       break;
-               val = readl(lnw->iotg.base + CI_PORTSC1);
-               val &= PORTSC_LS;
-       } while (!val);
-
-       dev_dbg(lnw->dev, "%s <---\n", __func__);
-       return val;
-}
-
-/* The timeout callback function to set time out bit */
-static void set_tmout(unsigned long indicator)
-{
-       *(int *)indicator = 1;
-}
-
-void langwell_otg_nsf_msg(unsigned long indicator)
-{
-       struct langwell_otg     *lnw = the_transceiver;
-
-       switch (indicator) {
-       case 2:
-       case 4:
-       case 6:
-       case 7:
-               dev_warn(lnw->dev,
-                       "OTG:NSF-%lu - deivce not responding\n", indicator);
-               break;
-       case 3:
-               dev_warn(lnw->dev,
-                       "OTG:NSF-%lu - deivce not supported\n", indicator);
-               break;
-       default:
-               dev_warn(lnw->dev, "Do not have this kind of NSF\n");
-               break;
-       }
-}
-
-/* Initialize timers */
-static int langwell_otg_init_timers(struct otg_hsm *hsm)
-{
-       /* HSM used timers */
-       a_wait_vrise_tmr = otg_timer_initializer(&set_tmout, TA_WAIT_VRISE,
-                               (unsigned long)&hsm->a_wait_vrise_tmout);
-       if (a_wait_vrise_tmr == NULL)
-               return -ENOMEM;
-       a_aidl_bdis_tmr = otg_timer_initializer(&set_tmout, TA_AIDL_BDIS,
-                               (unsigned long)&hsm->a_aidl_bdis_tmout);
-       if (a_aidl_bdis_tmr == NULL)
-               return -ENOMEM;
-       b_se0_srp_tmr = otg_timer_initializer(&set_tmout, TB_SE0_SRP,
-                               (unsigned long)&hsm->b_se0_srp);
-       if (b_se0_srp_tmr == NULL)
-               return -ENOMEM;
-       b_srp_init_tmr = otg_timer_initializer(&set_tmout, TB_SRP_INIT,
-                               (unsigned long)&hsm->b_srp_init_tmout);
-       if (b_srp_init_tmr == NULL)
-               return -ENOMEM;
-
-       return 0;
-}
-
-/* Free timers */
-static void langwell_otg_free_timers(void)
-{
-       kfree(a_wait_vrise_tmr);
-       kfree(a_aidl_bdis_tmr);
-       kfree(b_se0_srp_tmr);
-       kfree(b_srp_init_tmr);
-}
-
-/* The timeout callback function to set time out bit */
-static void langwell_otg_timer_fn(unsigned long indicator)
-{
-       struct langwell_otg *lnw = the_transceiver;
-
-       *(int *)indicator = 1;
-
-       dev_dbg(lnw->dev, "kernel timer - timeout\n");
-
-       langwell_update_transceiver();
-}
-
-/* kernel timer used instead of HW based interrupt */
-static void langwell_otg_add_ktimer(enum langwell_otg_timer_type timers)
-{
-       struct langwell_otg             *lnw = the_transceiver;
-       struct intel_mid_otg_xceiv      *iotg = &lnw->iotg;
-       unsigned long           j = jiffies;
-       unsigned long           data, time;
-
-       switch (timers) {
-       case TA_WAIT_VRISE_TMR:
-               iotg->hsm.a_wait_vrise_tmout = 0;
-               data = (unsigned long)&iotg->hsm.a_wait_vrise_tmout;
-               time = TA_WAIT_VRISE;
-               break;
-       case TA_WAIT_BCON_TMR:
-               iotg->hsm.a_wait_bcon_tmout = 0;
-               data = (unsigned long)&iotg->hsm.a_wait_bcon_tmout;
-               time = TA_WAIT_BCON;
-               break;
-       case TA_AIDL_BDIS_TMR:
-               iotg->hsm.a_aidl_bdis_tmout = 0;
-               data = (unsigned long)&iotg->hsm.a_aidl_bdis_tmout;
-               time = TA_AIDL_BDIS;
-               break;
-       case TB_ASE0_BRST_TMR:
-               iotg->hsm.b_ase0_brst_tmout = 0;
-               data = (unsigned long)&iotg->hsm.b_ase0_brst_tmout;
-               time = TB_ASE0_BRST;
-               break;
-       case TB_SRP_INIT_TMR:
-               iotg->hsm.b_srp_init_tmout = 0;
-               data = (unsigned long)&iotg->hsm.b_srp_init_tmout;
-               time = TB_SRP_INIT;
-               break;
-       case TB_SRP_FAIL_TMR:
-               iotg->hsm.b_srp_fail_tmout = 0;
-               data = (unsigned long)&iotg->hsm.b_srp_fail_tmout;
-               time = TB_SRP_FAIL;
-               break;
-       case TB_BUS_SUSPEND_TMR:
-               iotg->hsm.b_bus_suspend_tmout = 0;
-               data = (unsigned long)&iotg->hsm.b_bus_suspend_tmout;
-               time = TB_BUS_SUSPEND;
-               break;
-       default:
-               dev_dbg(lnw->dev, "unknown timer, cannot enable it\n");
-               return;
-       }
-
-       lnw->hsm_timer.data = data;
-       lnw->hsm_timer.function = langwell_otg_timer_fn;
-       lnw->hsm_timer.expires = j + time * HZ / 1000; /* milliseconds */
-
-       add_timer(&lnw->hsm_timer);
-
-       dev_dbg(lnw->dev, "add timer successfully\n");
-}
-
-/* Add timer to timer list */
-static void langwell_otg_add_timer(void *gtimer)
-{
-       struct langwell_otg_timer *timer = (struct langwell_otg_timer *)gtimer;
-       struct langwell_otg_timer *tmp_timer;
-       struct intel_mid_otg_xceiv *iotg = &the_transceiver->iotg;
-       u32     val32;
-
-       /* Check if the timer is already in the active list,
-        * if so update timer count
-        */
-       list_for_each_entry(tmp_timer, &active_timers, list)
-               if (tmp_timer == timer) {
-                       timer->count = timer->expires;
-                       return;
-               }
-       timer->count = timer->expires;
-
-       if (list_empty(&active_timers)) {
-               val32 = readl(iotg->base + CI_OTGSC);
-               writel(val32 | OTGSC_1MSE, iotg->base + CI_OTGSC);
-       }
-
-       list_add_tail(&timer->list, &active_timers);
-}
-
-/* Remove timer from the timer list; clear timeout status */
-static void langwell_otg_del_timer(void *gtimer)
-{
-       struct langwell_otg *lnw = the_transceiver;
-       struct langwell_otg_timer *timer = (struct langwell_otg_timer *)gtimer;
-       struct langwell_otg_timer *tmp_timer, *del_tmp;
-       u32 val32;
-
-       list_for_each_entry_safe(tmp_timer, del_tmp, &active_timers, list)
-               if (tmp_timer == timer)
-                       list_del(&timer->list);
-
-       if (list_empty(&active_timers)) {
-               val32 = readl(lnw->iotg.base + CI_OTGSC);
-               writel(val32 & ~OTGSC_1MSE, lnw->iotg.base + CI_OTGSC);
-       }
-}
-
-/* Reduce timer count by 1, and find timeout conditions.*/
-static int langwell_otg_tick_timer(u32 *int_sts)
-{
-       struct langwell_otg     *lnw = the_transceiver;
-       struct langwell_otg_timer *tmp_timer, *del_tmp;
-       int expired = 0;
-
-       list_for_each_entry_safe(tmp_timer, del_tmp, &active_timers, list) {
-               tmp_timer->count--;
-               /* check if timer expires */
-               if (!tmp_timer->count) {
-                       list_del(&tmp_timer->list);
-                       tmp_timer->function(tmp_timer->data);
-                       expired = 1;
-               }
-       }
-
-       if (list_empty(&active_timers)) {
-               dev_dbg(lnw->dev, "tick timer: disable 1ms int\n");
-               *int_sts = *int_sts & ~OTGSC_1MSE;
-       }
-       return expired;
-}
-
-static void reset_otg(void)
-{
-       struct langwell_otg     *lnw = the_transceiver;
-       int                     delay_time = 1000;
-       u32                     val;
-
-       dev_dbg(lnw->dev, "reseting OTG controller ...\n");
-       val = readl(lnw->iotg.base + CI_USBCMD);
-       writel(val | USBCMD_RST, lnw->iotg.base + CI_USBCMD);
-       do {
-               udelay(100);
-               if (!delay_time--)
-                       dev_dbg(lnw->dev, "reset timeout\n");
-               val = readl(lnw->iotg.base + CI_USBCMD);
-               val &= USBCMD_RST;
-       } while (val != 0);
-       dev_dbg(lnw->dev, "reset done.\n");
-}
-
-static void set_host_mode(void)
-{
-       struct langwell_otg     *lnw = the_transceiver;
-       u32                     val;
-
-       reset_otg();
-       val = readl(lnw->iotg.base + CI_USBMODE);
-       val = (val & (~USBMODE_CM)) | USBMODE_HOST;
-       writel(val, lnw->iotg.base + CI_USBMODE);
-}
-
-static void set_client_mode(void)
-{
-       struct langwell_otg     *lnw = the_transceiver;
-       u32                     val;
-
-       reset_otg();
-       val = readl(lnw->iotg.base + CI_USBMODE);
-       val = (val & (~USBMODE_CM)) | USBMODE_DEVICE;
-       writel(val, lnw->iotg.base + CI_USBMODE);
-}
-
-static void init_hsm(void)
-{
-       struct langwell_otg             *lnw = the_transceiver;
-       struct intel_mid_otg_xceiv      *iotg = &lnw->iotg;
-       u32                             val32;
-
-       /* read OTGSC after reset */
-       val32 = readl(lnw->iotg.base + CI_OTGSC);
-       dev_dbg(lnw->dev, "%s: OTGSC init value = 0x%x\n", __func__, val32);
-
-       /* set init state */
-       if (val32 & OTGSC_ID) {
-               iotg->hsm.id = 1;
-               iotg->otg.default_a = 0;
-               set_client_mode();
-               iotg->otg.state = OTG_STATE_B_IDLE;
-       } else {
-               iotg->hsm.id = 0;
-               iotg->otg.default_a = 1;
-               set_host_mode();
-               iotg->otg.state = OTG_STATE_A_IDLE;
-       }
-
-       /* set session indicator */
-       if (val32 & OTGSC_BSE)
-               iotg->hsm.b_sess_end = 1;
-       if (val32 & OTGSC_BSV)
-               iotg->hsm.b_sess_vld = 1;
-       if (val32 & OTGSC_ASV)
-               iotg->hsm.a_sess_vld = 1;
-       if (val32 & OTGSC_AVV)
-               iotg->hsm.a_vbus_vld = 1;
-
-       /* defautly power the bus */
-       iotg->hsm.a_bus_req = 1;
-       iotg->hsm.a_bus_drop = 0;
-       /* defautly don't request bus as B device */
-       iotg->hsm.b_bus_req = 0;
-       /* no system error */
-       iotg->hsm.a_clr_err = 0;
-
-       langwell_otg_phy_low_power_wait(1);
-}
-
-static void update_hsm(void)
-{
-       struct langwell_otg             *lnw = the_transceiver;
-       struct intel_mid_otg_xceiv      *iotg = &lnw->iotg;
-       u32                             val32;
-
-       /* read OTGSC */
-       val32 = readl(lnw->iotg.base + CI_OTGSC);
-       dev_dbg(lnw->dev, "%s: OTGSC value = 0x%x\n", __func__, val32);
-
-       iotg->hsm.id = !!(val32 & OTGSC_ID);
-       iotg->hsm.b_sess_end = !!(val32 & OTGSC_BSE);
-       iotg->hsm.b_sess_vld = !!(val32 & OTGSC_BSV);
-       iotg->hsm.a_sess_vld = !!(val32 & OTGSC_ASV);
-       iotg->hsm.a_vbus_vld = !!(val32 & OTGSC_AVV);
-}
-
-static irqreturn_t otg_dummy_irq(int irq, void *_dev)
-{
-       struct langwell_otg     *lnw = the_transceiver;
-       void __iomem            *reg_base = _dev;
-       u32                     val;
-       u32                     int_mask = 0;
-
-       val = readl(reg_base + CI_USBMODE);
-       if ((val & USBMODE_CM) != USBMODE_DEVICE)
-               return IRQ_NONE;
-
-       val = readl(reg_base + CI_USBSTS);
-       int_mask = val & INTR_DUMMY_MASK;
-
-       if (int_mask == 0)
-               return IRQ_NONE;
-
-       /* clear hsm.b_conn here since host driver can't detect it
-       *  otg_dummy_irq called means B-disconnect happened.
-       */
-       if (lnw->iotg.hsm.b_conn) {
-               lnw->iotg.hsm.b_conn = 0;
-               if (spin_trylock(&lnw->wq_lock)) {
-                       langwell_update_transceiver();
-                       spin_unlock(&lnw->wq_lock);
-               }
-       }
-
-       /* Clear interrupts */
-       writel(int_mask, reg_base + CI_USBSTS);
-       return IRQ_HANDLED;
-}
-
-static irqreturn_t otg_irq(int irq, void *_dev)
-{
-       struct langwell_otg             *lnw = _dev;
-       struct intel_mid_otg_xceiv      *iotg = &lnw->iotg;
-       u32                             int_sts, int_en;
-       u32                             int_mask = 0;
-       int                             flag = 0;
-
-       int_sts = readl(lnw->iotg.base + CI_OTGSC);
-       int_en = (int_sts & OTGSC_INTEN_MASK) >> 8;
-       int_mask = int_sts & int_en;
-       if (int_mask == 0)
-               return IRQ_NONE;
-
-       if (int_mask & OTGSC_IDIS) {
-               dev_dbg(lnw->dev, "%s: id change int\n", __func__);
-               iotg->hsm.id = (int_sts & OTGSC_ID) ? 1 : 0;
-               dev_dbg(lnw->dev, "id = %d\n", iotg->hsm.id);
-               flag = 1;
-       }
-       if (int_mask & OTGSC_DPIS) {
-               dev_dbg(lnw->dev, "%s: data pulse int\n", __func__);
-               iotg->hsm.a_srp_det = (int_sts & OTGSC_DPS) ? 1 : 0;
-               dev_dbg(lnw->dev, "data pulse = %d\n", iotg->hsm.a_srp_det);
-               flag = 1;
-       }
-       if (int_mask & OTGSC_BSEIS) {
-               dev_dbg(lnw->dev, "%s: b session end int\n", __func__);
-               iotg->hsm.b_sess_end = (int_sts & OTGSC_BSE) ? 1 : 0;
-               dev_dbg(lnw->dev, "b_sess_end = %d\n", iotg->hsm.b_sess_end);
-               flag = 1;
-       }
-       if (int_mask & OTGSC_BSVIS) {
-               dev_dbg(lnw->dev, "%s: b session valid int\n", __func__);
-               iotg->hsm.b_sess_vld = (int_sts & OTGSC_BSV) ? 1 : 0;
-               dev_dbg(lnw->dev, "b_sess_vld = %d\n", iotg->hsm.b_sess_end);
-               flag = 1;
-       }
-       if (int_mask & OTGSC_ASVIS) {
-               dev_dbg(lnw->dev, "%s: a session valid int\n", __func__);
-               iotg->hsm.a_sess_vld = (int_sts & OTGSC_ASV) ? 1 : 0;
-               dev_dbg(lnw->dev, "a_sess_vld = %d\n", iotg->hsm.a_sess_vld);
-               flag = 1;
-       }
-       if (int_mask & OTGSC_AVVIS) {
-               dev_dbg(lnw->dev, "%s: a vbus valid int\n", __func__);
-               iotg->hsm.a_vbus_vld = (int_sts & OTGSC_AVV) ? 1 : 0;
-               dev_dbg(lnw->dev, "a_vbus_vld = %d\n", iotg->hsm.a_vbus_vld);
-               flag = 1;
-       }
-
-       if (int_mask & OTGSC_1MSS) {
-               /* need to schedule otg_work if any timer is expired */
-               if (langwell_otg_tick_timer(&int_sts))
-                       flag = 1;
-       }
-
-       writel((int_sts & ~OTGSC_INTSTS_MASK) | int_mask,
-                                       lnw->iotg.base + CI_OTGSC);
-       if (flag)
-               langwell_update_transceiver();
-
-       return IRQ_HANDLED;
-}
-
-static int langwell_otg_iotg_notify(struct notifier_block *nb,
-                               unsigned long action, void *data)
-{
-       struct langwell_otg             *lnw = the_transceiver;
-       struct intel_mid_otg_xceiv      *iotg = data;
-       int                             flag = 0;
-
-       if (iotg == NULL)
-               return NOTIFY_BAD;
-
-       if (lnw == NULL)
-               return NOTIFY_BAD;
-
-       switch (action) {
-       case MID_OTG_NOTIFY_CONNECT:
-               dev_dbg(lnw->dev, "Lnw OTG Notify Connect Event\n");
-               if (iotg->otg.default_a == 1)
-                       iotg->hsm.b_conn = 1;
-               else
-                       iotg->hsm.a_conn = 1;
-               flag = 1;
-               break;
-       case MID_OTG_NOTIFY_DISCONN:
-               dev_dbg(lnw->dev, "Lnw OTG Notify Disconnect Event\n");
-               if (iotg->otg.default_a == 1)
-                       iotg->hsm.b_conn = 0;
-               else
-                       iotg->hsm.a_conn = 0;
-               flag = 1;
-               break;
-       case MID_OTG_NOTIFY_HSUSPEND:
-               dev_dbg(lnw->dev, "Lnw OTG Notify Host Bus suspend Event\n");
-               if (iotg->otg.default_a == 1)
-                       iotg->hsm.a_suspend_req = 1;
-               else
-                       iotg->hsm.b_bus_req = 0;
-               flag = 1;
-               break;
-       case MID_OTG_NOTIFY_HRESUME:
-               dev_dbg(lnw->dev, "Lnw OTG Notify Host Bus resume Event\n");
-               if (iotg->otg.default_a == 1)
-                       iotg->hsm.b_bus_resume = 1;
-               flag = 1;
-               break;
-       case MID_OTG_NOTIFY_CSUSPEND:
-               dev_dbg(lnw->dev, "Lnw OTG Notify Client Bus suspend Event\n");
-               if (iotg->otg.default_a == 1) {
-                       if (iotg->hsm.b_bus_suspend_vld == 2) {
-                               iotg->hsm.b_bus_suspend = 1;
-                               iotg->hsm.b_bus_suspend_vld = 0;
-                               flag = 1;
-                       } else {
-                               iotg->hsm.b_bus_suspend_vld++;
-                               flag = 0;
-                       }
-               } else {
-                       if (iotg->hsm.a_bus_suspend == 0) {
-                               iotg->hsm.a_bus_suspend = 1;
-                               flag = 1;
-                       }
-               }
-               break;
-       case MID_OTG_NOTIFY_CRESUME:
-               dev_dbg(lnw->dev, "Lnw OTG Notify Client Bus resume Event\n");
-               if (iotg->otg.default_a == 0)
-                       iotg->hsm.a_bus_suspend = 0;
-               flag = 0;
-               break;
-       case MID_OTG_NOTIFY_HOSTADD:
-               dev_dbg(lnw->dev, "Lnw OTG Nofity Host Driver Add\n");
-               flag = 1;
-               break;
-       case MID_OTG_NOTIFY_HOSTREMOVE:
-               dev_dbg(lnw->dev, "Lnw OTG Nofity Host Driver remove\n");
-               flag = 1;
-               break;
-       case MID_OTG_NOTIFY_CLIENTADD:
-               dev_dbg(lnw->dev, "Lnw OTG Nofity Client Driver Add\n");
-               flag = 1;
-               break;
-       case MID_OTG_NOTIFY_CLIENTREMOVE:
-               dev_dbg(lnw->dev, "Lnw OTG Nofity Client Driver remove\n");
-               flag = 1;
-               break;
-       default:
-               dev_dbg(lnw->dev, "Lnw OTG Nofity unknown notify message\n");
-               return NOTIFY_DONE;
-       }
-
-       if (flag)
-               langwell_update_transceiver();
-
-       return NOTIFY_OK;
-}
-
-static void langwell_otg_work(struct work_struct *work)
-{
-       struct langwell_otg             *lnw;
-       struct intel_mid_otg_xceiv      *iotg;
-       int                             retval;
-       struct pci_dev                  *pdev;
-
-       lnw = container_of(work, struct langwell_otg, work);
-       iotg = &lnw->iotg;
-       pdev = to_pci_dev(lnw->dev);
-
-       dev_dbg(lnw->dev, "%s: old state = %s\n", __func__,
-                       otg_state_string(iotg->otg.state));
-
-       switch (iotg->otg.state) {
-       case OTG_STATE_UNDEFINED:
-       case OTG_STATE_B_IDLE:
-               if (!iotg->hsm.id) {
-                       langwell_otg_del_timer(b_srp_init_tmr);
-                       del_timer_sync(&lnw->hsm_timer);
-
-                       iotg->otg.default_a = 1;
-                       iotg->hsm.a_srp_det = 0;
-
-                       langwell_otg_chrg_vbus(0);
-                       set_host_mode();
-                       langwell_otg_phy_low_power(1);
-
-                       iotg->otg.state = OTG_STATE_A_IDLE;
-                       langwell_update_transceiver();
-               } else if (iotg->hsm.b_sess_vld) {
-                       langwell_otg_del_timer(b_srp_init_tmr);
-                       del_timer_sync(&lnw->hsm_timer);
-                       iotg->hsm.b_sess_end = 0;
-                       iotg->hsm.a_bus_suspend = 0;
-                       langwell_otg_chrg_vbus(0);
-
-                       if (lnw->iotg.start_peripheral) {
-                               lnw->iotg.start_peripheral(&lnw->iotg);
-                               iotg->otg.state = OTG_STATE_B_PERIPHERAL;
-                       } else
-                               dev_dbg(lnw->dev, "client driver not loaded\n");
-
-               } else if (iotg->hsm.b_srp_init_tmout) {
-                       iotg->hsm.b_srp_init_tmout = 0;
-                       dev_warn(lnw->dev, "SRP init timeout\n");
-               } else if (iotg->hsm.b_srp_fail_tmout) {
-                       iotg->hsm.b_srp_fail_tmout = 0;
-                       iotg->hsm.b_bus_req = 0;
-
-                       /* No silence failure */
-                       langwell_otg_nsf_msg(6);
-               } else if (iotg->hsm.b_bus_req && iotg->hsm.b_sess_end) {
-                       del_timer_sync(&lnw->hsm_timer);
-                       /* workaround for b_se0_srp detection */
-                       retval = langwell_otg_check_se0_srp(0);
-                       if (retval) {
-                               iotg->hsm.b_bus_req = 0;
-                               dev_dbg(lnw->dev, "LS isn't SE0, try later\n");
-                       } else {
-                               /* clear the PHCD before start srp */
-                               langwell_otg_phy_low_power(0);
-
-                               /* Start SRP */
-                               langwell_otg_add_timer(b_srp_init_tmr);
-                               iotg->otg.start_srp(&iotg->otg);
-                               langwell_otg_del_timer(b_srp_init_tmr);
-                               langwell_otg_add_ktimer(TB_SRP_FAIL_TMR);
-
-                               /* reset PHY low power mode here */
-                               langwell_otg_phy_low_power_wait(1);
-                       }
-               }
-               break;
-       case OTG_STATE_B_SRP_INIT:
-               if (!iotg->hsm.id) {
-                       iotg->otg.default_a = 1;
-                       iotg->hsm.a_srp_det = 0;
-
-                       /* Turn off VBus */
-                       iotg->otg.set_vbus(&iotg->otg, false);
-                       langwell_otg_chrg_vbus(0);
-                       set_host_mode();
-                       langwell_otg_phy_low_power(1);
-                       iotg->otg.state = OTG_STATE_A_IDLE;
-                       langwell_update_transceiver();
-               } else if (iotg->hsm.b_sess_vld) {
-                       langwell_otg_chrg_vbus(0);
-                       if (lnw->iotg.start_peripheral) {
-                               lnw->iotg.start_peripheral(&lnw->iotg);
-                               iotg->otg.state = OTG_STATE_B_PERIPHERAL;
-                       } else
-                               dev_dbg(lnw->dev, "client driver not loaded\n");
-               }
-               break;
-       case OTG_STATE_B_PERIPHERAL:
-               if (!iotg->hsm.id) {
-                       iotg->otg.default_a = 1;
-                       iotg->hsm.a_srp_det = 0;
-
-                       langwell_otg_chrg_vbus(0);
-
-                       if (lnw->iotg.stop_peripheral)
-                               lnw->iotg.stop_peripheral(&lnw->iotg);
-                       else
-                               dev_dbg(lnw->dev,
-                                       "client driver has been removed.\n");
-
-                       set_host_mode();
-                       langwell_otg_phy_low_power(1);
-                       iotg->otg.state = OTG_STATE_A_IDLE;
-                       langwell_update_transceiver();
-               } else if (!iotg->hsm.b_sess_vld) {
-                       iotg->hsm.b_hnp_enable = 0;
-
-                       if (lnw->iotg.stop_peripheral)
-                               lnw->iotg.stop_peripheral(&lnw->iotg);
-                       else
-                               dev_dbg(lnw->dev,
-                                       "client driver has been removed.\n");
-
-                       iotg->otg.state = OTG_STATE_B_IDLE;
-               } else if (iotg->hsm.b_bus_req && iotg->otg.gadget &&
-                                       iotg->otg.gadget->b_hnp_enable &&
-                                       iotg->hsm.a_bus_suspend) {
-
-                       if (lnw->iotg.stop_peripheral)
-                               lnw->iotg.stop_peripheral(&lnw->iotg);
-                       else
-                               dev_dbg(lnw->dev,
-                                       "client driver has been removed.\n");
-
-                       langwell_otg_HAAR(1);
-                       iotg->hsm.a_conn = 0;
-
-                       if (lnw->iotg.start_host) {
-                               lnw->iotg.start_host(&lnw->iotg);
-                               iotg->otg.state = OTG_STATE_B_WAIT_ACON;
-                       } else
-                               dev_dbg(lnw->dev,
-                                               "host driver not loaded.\n");
-
-                       iotg->hsm.a_bus_resume = 0;
-                       langwell_otg_add_ktimer(TB_ASE0_BRST_TMR);
-               }
-               break;
-
-       case OTG_STATE_B_WAIT_ACON:
-               if (!iotg->hsm.id) {
-                       /* delete hsm timer for b_ase0_brst_tmr */
-                       del_timer_sync(&lnw->hsm_timer);
-
-                       iotg->otg.default_a = 1;
-                       iotg->hsm.a_srp_det = 0;
-
-                       langwell_otg_chrg_vbus(0);
-
-                       langwell_otg_HAAR(0);
-                       if (lnw->iotg.stop_host)
-                               lnw->iotg.stop_host(&lnw->iotg);
-                       else
-                               dev_dbg(lnw->dev,
-                                       "host driver has been removed.\n");
-
-                       set_host_mode();
-                       langwell_otg_phy_low_power(1);
-                       iotg->otg.state = OTG_STATE_A_IDLE;
-                       langwell_update_transceiver();
-               } else if (!iotg->hsm.b_sess_vld) {
-                       /* delete hsm timer for b_ase0_brst_tmr */
-                       del_timer_sync(&lnw->hsm_timer);
-
-                       iotg->hsm.b_hnp_enable = 0;
-                       iotg->hsm.b_bus_req = 0;
-
-                       langwell_otg_chrg_vbus(0);
-                       langwell_otg_HAAR(0);
-
-                       if (lnw->iotg.stop_host)
-                               lnw->iotg.stop_host(&lnw->iotg);
-                       else
-                               dev_dbg(lnw->dev,
-                                       "host driver has been removed.\n");
-
-                       set_client_mode();
-                       langwell_otg_phy_low_power(1);
-                       iotg->otg.state = OTG_STATE_B_IDLE;
-               } else if (iotg->hsm.a_conn) {
-                       /* delete hsm timer for b_ase0_brst_tmr */
-                       del_timer_sync(&lnw->hsm_timer);
-
-                       langwell_otg_HAAR(0);
-                       iotg->otg.state = OTG_STATE_B_HOST;
-                       langwell_update_transceiver();
-               } else if (iotg->hsm.a_bus_resume ||
-                               iotg->hsm.b_ase0_brst_tmout) {
-                       /* delete hsm timer for b_ase0_brst_tmr */
-                       del_timer_sync(&lnw->hsm_timer);
-
-                       langwell_otg_HAAR(0);
-                       langwell_otg_nsf_msg(7);
-
-                       if (lnw->iotg.stop_host)
-                               lnw->iotg.stop_host(&lnw->iotg);
-                       else
-                               dev_dbg(lnw->dev,
-                                       "host driver has been removed.\n");
-
-                       iotg->hsm.a_bus_suspend = 0;
-                       iotg->hsm.b_bus_req = 0;
-
-                       if (lnw->iotg.start_peripheral)
-                               lnw->iotg.start_peripheral(&lnw->iotg);
-                       else
-                               dev_dbg(lnw->dev,
-                                       "client driver not loaded.\n");
-
-                       iotg->otg.state = OTG_STATE_B_PERIPHERAL;
-               }
-               break;
-
-       case OTG_STATE_B_HOST:
-               if (!iotg->hsm.id) {
-                       iotg->otg.default_a = 1;
-                       iotg->hsm.a_srp_det = 0;
-
-                       langwell_otg_chrg_vbus(0);
-
-                       if (lnw->iotg.stop_host)
-                               lnw->iotg.stop_host(&lnw->iotg);
-                       else
-                               dev_dbg(lnw->dev,
-                                       "host driver has been removed.\n");
-
-                       set_host_mode();
-                       langwell_otg_phy_low_power(1);
-                       iotg->otg.state = OTG_STATE_A_IDLE;
-                       langwell_update_transceiver();
-               } else if (!iotg->hsm.b_sess_vld) {
-                       iotg->hsm.b_hnp_enable = 0;
-                       iotg->hsm.b_bus_req = 0;
-
-                       langwell_otg_chrg_vbus(0);
-                       if (lnw->iotg.stop_host)
-                               lnw->iotg.stop_host(&lnw->iotg);
-                       else
-                               dev_dbg(lnw->dev,
-                                       "host driver has been removed.\n");
-
-                       set_client_mode();
-                       langwell_otg_phy_low_power(1);
-                       iotg->otg.state = OTG_STATE_B_IDLE;
-               } else if ((!iotg->hsm.b_bus_req) ||
-                               (!iotg->hsm.a_conn)) {
-                       iotg->hsm.b_bus_req = 0;
-                       langwell_otg_loc_sof(0);
-
-                       if (lnw->iotg.stop_host)
-                               lnw->iotg.stop_host(&lnw->iotg);
-                       else
-                               dev_dbg(lnw->dev,
-                                       "host driver has been removed.\n");
-
-                       iotg->hsm.a_bus_suspend = 0;
-
-                       if (lnw->iotg.start_peripheral)
-                               lnw->iotg.start_peripheral(&lnw->iotg);
-                       else
-                               dev_dbg(lnw->dev,
-                                               "client driver not loaded.\n");
-
-                       iotg->otg.state = OTG_STATE_B_PERIPHERAL;
-               }
-               break;
-
-       case OTG_STATE_A_IDLE:
-               iotg->otg.default_a = 1;
-               if (iotg->hsm.id) {
-                       iotg->otg.default_a = 0;
-                       iotg->hsm.b_bus_req = 0;
-                       iotg->hsm.vbus_srp_up = 0;
-
-                       langwell_otg_chrg_vbus(0);
-                       set_client_mode();
-                       langwell_otg_phy_low_power(1);
-                       iotg->otg.state = OTG_STATE_B_IDLE;
-                       langwell_update_transceiver();
-               } else if (!iotg->hsm.a_bus_drop &&
-                       (iotg->hsm.a_srp_det || iotg->hsm.a_bus_req)) {
-                       langwell_otg_phy_low_power(0);
-
-                       /* Turn on VBus */
-                       iotg->otg.set_vbus(&iotg->otg, true);
-
-                       iotg->hsm.vbus_srp_up = 0;
-                       iotg->hsm.a_wait_vrise_tmout = 0;
-                       langwell_otg_add_timer(a_wait_vrise_tmr);
-                       iotg->otg.state = OTG_STATE_A_WAIT_VRISE;
-                       langwell_update_transceiver();
-               } else if (!iotg->hsm.a_bus_drop && iotg->hsm.a_sess_vld) {
-                       iotg->hsm.vbus_srp_up = 1;
-               } else if (!iotg->hsm.a_sess_vld && iotg->hsm.vbus_srp_up) {
-                       msleep(10);
-                       langwell_otg_phy_low_power(0);
-
-                       /* Turn on VBus */
-                       iotg->otg.set_vbus(&iotg->otg, true);
-                       iotg->hsm.a_srp_det = 1;
-                       iotg->hsm.vbus_srp_up = 0;
-                       iotg->hsm.a_wait_vrise_tmout = 0;
-                       langwell_otg_add_timer(a_wait_vrise_tmr);
-                       iotg->otg.state = OTG_STATE_A_WAIT_VRISE;
-                       langwell_update_transceiver();
-               } else if (!iotg->hsm.a_sess_vld &&
-                               !iotg->hsm.vbus_srp_up) {
-                       langwell_otg_phy_low_power(1);
-               }
-               break;
-       case OTG_STATE_A_WAIT_VRISE:
-               if (iotg->hsm.id) {
-                       langwell_otg_del_timer(a_wait_vrise_tmr);
-                       iotg->hsm.b_bus_req = 0;
-                       iotg->otg.default_a = 0;
-
-                       /* Turn off VBus */
-                       iotg->otg.set_vbus(&iotg->otg, false);
-                       set_client_mode();
-                       langwell_otg_phy_low_power_wait(1);
-                       iotg->otg.state = OTG_STATE_B_IDLE;
-               } else if (iotg->hsm.a_vbus_vld) {
-                       langwell_otg_del_timer(a_wait_vrise_tmr);
-                       iotg->hsm.b_conn = 0;
-                       if (lnw->iotg.start_host)
-                               lnw->iotg.start_host(&lnw->iotg);
-                       else {
-                               dev_dbg(lnw->dev, "host driver not loaded.\n");
-                               break;
-                       }
-
-                       langwell_otg_add_ktimer(TA_WAIT_BCON_TMR);
-                       iotg->otg.state = OTG_STATE_A_WAIT_BCON;
-               } else if (iotg->hsm.a_wait_vrise_tmout) {
-                       iotg->hsm.b_conn = 0;
-                       if (iotg->hsm.a_vbus_vld) {
-                               if (lnw->iotg.start_host)
-                                       lnw->iotg.start_host(&lnw->iotg);
-                               else {
-                                       dev_dbg(lnw->dev,
-                                               "host driver not loaded.\n");
-                                       break;
-                               }
-                               langwell_otg_add_ktimer(TA_WAIT_BCON_TMR);
-                               iotg->otg.state = OTG_STATE_A_WAIT_BCON;
-                       } else {
-
-                               /* Turn off VBus */
-                               iotg->otg.set_vbus(&iotg->otg, false);
-                               langwell_otg_phy_low_power_wait(1);
-                               iotg->otg.state = OTG_STATE_A_VBUS_ERR;
-                       }
-               }
-               break;
-       case OTG_STATE_A_WAIT_BCON:
-               if (iotg->hsm.id) {
-                       /* delete hsm timer for a_wait_bcon_tmr */
-                       del_timer_sync(&lnw->hsm_timer);
-
-                       iotg->otg.default_a = 0;
-                       iotg->hsm.b_bus_req = 0;
-
-                       if (lnw->iotg.stop_host)
-                               lnw->iotg.stop_host(&lnw->iotg);
-                       else
-                               dev_dbg(lnw->dev,
-                                       "host driver has been removed.\n");
-
-                       /* Turn off VBus */
-                       iotg->otg.set_vbus(&iotg->otg, false);
-                       set_client_mode();
-                       langwell_otg_phy_low_power_wait(1);
-                       iotg->otg.state = OTG_STATE_B_IDLE;
-                       langwell_update_transceiver();
-               } else if (!iotg->hsm.a_vbus_vld) {
-                       /* delete hsm timer for a_wait_bcon_tmr */
-                       del_timer_sync(&lnw->hsm_timer);
-
-                       if (lnw->iotg.stop_host)
-                               lnw->iotg.stop_host(&lnw->iotg);
-                       else
-                               dev_dbg(lnw->dev,
-                                       "host driver has been removed.\n");
-
-                       /* Turn off VBus */
-                       iotg->otg.set_vbus(&iotg->otg, false);
-                       langwell_otg_phy_low_power_wait(1);
-                       iotg->otg.state = OTG_STATE_A_VBUS_ERR;
-               } else if (iotg->hsm.a_bus_drop ||
-                               (iotg->hsm.a_wait_bcon_tmout &&
-                               !iotg->hsm.a_bus_req)) {
-                       /* delete hsm timer for a_wait_bcon_tmr */
-                       del_timer_sync(&lnw->hsm_timer);
-
-                       if (lnw->iotg.stop_host)
-                               lnw->iotg.stop_host(&lnw->iotg);
-                       else
-                               dev_dbg(lnw->dev,
-                                       "host driver has been removed.\n");
-
-                       /* Turn off VBus */
-                       iotg->otg.set_vbus(&iotg->otg, false);
-                       iotg->otg.state = OTG_STATE_A_WAIT_VFALL;
-               } else if (iotg->hsm.b_conn) {
-                       /* delete hsm timer for a_wait_bcon_tmr */
-                       del_timer_sync(&lnw->hsm_timer);
-
-                       iotg->hsm.a_suspend_req = 0;
-                       iotg->otg.state = OTG_STATE_A_HOST;
-                       if (iotg->hsm.a_srp_det && iotg->otg.host &&
-                                       !iotg->otg.host->b_hnp_enable) {
-                               /* SRP capable peripheral-only device */
-                               iotg->hsm.a_bus_req = 1;
-                               iotg->hsm.a_srp_det = 0;
-                       } else if (!iotg->hsm.a_bus_req && iotg->otg.host &&
-                                       iotg->otg.host->b_hnp_enable) {
-                               /* It is not safe enough to do a fast
-                                * transition from A_WAIT_BCON to
-                                * A_SUSPEND */
-                               msleep(10000);
-                               if (iotg->hsm.a_bus_req)
-                                       break;
-
-                               if (request_irq(pdev->irq,
-                                       otg_dummy_irq, IRQF_SHARED,
-                                       driver_name, iotg->base) != 0) {
-                                       dev_dbg(lnw->dev,
-                                               "request interrupt %d fail\n",
-                                               pdev->irq);
-                               }
-
-                               langwell_otg_HABA(1);
-                               iotg->hsm.b_bus_resume = 0;
-                               iotg->hsm.a_aidl_bdis_tmout = 0;
-
-                               langwell_otg_loc_sof(0);
-                               /* clear PHCD to enable HW timer */
-                               langwell_otg_phy_low_power(0);
-                               langwell_otg_add_timer(a_aidl_bdis_tmr);
-                               iotg->otg.state = OTG_STATE_A_SUSPEND;
-                       } else if (!iotg->hsm.a_bus_req && iotg->otg.host &&
-                               !iotg->otg.host->b_hnp_enable) {
-                               if (lnw->iotg.stop_host)
-                                       lnw->iotg.stop_host(&lnw->iotg);
-                               else
-                                       dev_dbg(lnw->dev,
-                                               "host driver removed.\n");
-
-                               /* Turn off VBus */
-                               iotg->otg.set_vbus(&iotg->otg, false);
-                               iotg->otg.state = OTG_STATE_A_WAIT_VFALL;
-                       }
-               }
-               break;
-       case OTG_STATE_A_HOST:
-               if (iotg->hsm.id) {
-                       iotg->otg.default_a = 0;
-                       iotg->hsm.b_bus_req = 0;
-
-                       if (lnw->iotg.stop_host)
-                               lnw->iotg.stop_host(&lnw->iotg);
-                       else
-                               dev_dbg(lnw->dev,
-                                       "host driver has been removed.\n");
-
-                       /* Turn off VBus */
-                       iotg->otg.set_vbus(&iotg->otg, false);
-                       set_client_mode();
-                       langwell_otg_phy_low_power_wait(1);
-                       iotg->otg.state = OTG_STATE_B_IDLE;
-                       langwell_update_transceiver();
-               } else if (iotg->hsm.a_bus_drop ||
-                               (iotg->otg.host &&
-                               !iotg->otg.host->b_hnp_enable &&
-                                       !iotg->hsm.a_bus_req)) {
-                       if (lnw->iotg.stop_host)
-                               lnw->iotg.stop_host(&lnw->iotg);
-                       else
-                               dev_dbg(lnw->dev,
-                                       "host driver has been removed.\n");
-
-                       /* Turn off VBus */
-                       iotg->otg.set_vbus(&iotg->otg, false);
-                       iotg->otg.state = OTG_STATE_A_WAIT_VFALL;
-               } else if (!iotg->hsm.a_vbus_vld) {
-                       if (lnw->iotg.stop_host)
-                               lnw->iotg.stop_host(&lnw->iotg);
-                       else
-                               dev_dbg(lnw->dev,
-                                       "host driver has been removed.\n");
-
-                       /* Turn off VBus */
-                       iotg->otg.set_vbus(&iotg->otg, false);
-                       langwell_otg_phy_low_power_wait(1);
-                       iotg->otg.state = OTG_STATE_A_VBUS_ERR;
-               } else if (iotg->otg.host &&
-                               iotg->otg.host->b_hnp_enable &&
-                               !iotg->hsm.a_bus_req) {
-                       /* Set HABA to enable hardware assistance to signal
-                        *  A-connect after receiver B-disconnect. Hardware
-                        *  will then set client mode and enable URE, SLE and
-                        *  PCE after the assistance. otg_dummy_irq is used to
-                        *  clean these ints when client driver is not resumed.
-                        */
-                       if (request_irq(pdev->irq, otg_dummy_irq, IRQF_SHARED,
-                                       driver_name, iotg->base) != 0) {
-                               dev_dbg(lnw->dev,
-                                       "request interrupt %d failed\n",
-                                               pdev->irq);
-                       }
-
-                       /* set HABA */
-                       langwell_otg_HABA(1);
-                       iotg->hsm.b_bus_resume = 0;
-                       iotg->hsm.a_aidl_bdis_tmout = 0;
-                       langwell_otg_loc_sof(0);
-                       /* clear PHCD to enable HW timer */
-                       langwell_otg_phy_low_power(0);
-                       langwell_otg_add_timer(a_aidl_bdis_tmr);
-                       iotg->otg.state = OTG_STATE_A_SUSPEND;
-               } else if (!iotg->hsm.b_conn || !iotg->hsm.a_bus_req) {
-                       langwell_otg_add_ktimer(TA_WAIT_BCON_TMR);
-                       iotg->otg.state = OTG_STATE_A_WAIT_BCON;
-               }
-               break;
-       case OTG_STATE_A_SUSPEND:
-               if (iotg->hsm.id) {
-                       langwell_otg_del_timer(a_aidl_bdis_tmr);
-                       langwell_otg_HABA(0);
-                       free_irq(pdev->irq, iotg->base);
-                       iotg->otg.default_a = 0;
-                       iotg->hsm.b_bus_req = 0;
-
-                       if (lnw->iotg.stop_host)
-                               lnw->iotg.stop_host(&lnw->iotg);
-                       else
-                               dev_dbg(lnw->dev,
-                                       "host driver has been removed.\n");
-
-                       /* Turn off VBus */
-                       iotg->otg.set_vbus(&iotg->otg, false);
-                       set_client_mode();
-                       langwell_otg_phy_low_power(1);
-                       iotg->otg.state = OTG_STATE_B_IDLE;
-                       langwell_update_transceiver();
-               } else if (iotg->hsm.a_bus_req ||
-                               iotg->hsm.b_bus_resume) {
-                       langwell_otg_del_timer(a_aidl_bdis_tmr);
-                       langwell_otg_HABA(0);
-                       free_irq(pdev->irq, iotg->base);
-                       iotg->hsm.a_suspend_req = 0;
-                       langwell_otg_loc_sof(1);
-                       iotg->otg.state = OTG_STATE_A_HOST;
-               } else if (iotg->hsm.a_aidl_bdis_tmout ||
-                               iotg->hsm.a_bus_drop) {
-                       langwell_otg_del_timer(a_aidl_bdis_tmr);
-                       langwell_otg_HABA(0);
-                       free_irq(pdev->irq, iotg->base);
-                       if (lnw->iotg.stop_host)
-                               lnw->iotg.stop_host(&lnw->iotg);
-                       else
-                               dev_dbg(lnw->dev,
-                                       "host driver has been removed.\n");
-
-                       /* Turn off VBus */
-                       iotg->otg.set_vbus(&iotg->otg, false);
-                       iotg->otg.state = OTG_STATE_A_WAIT_VFALL;
-               } else if (!iotg->hsm.b_conn && iotg->otg.host &&
-                               iotg->otg.host->b_hnp_enable) {
-                       langwell_otg_del_timer(a_aidl_bdis_tmr);
-                       langwell_otg_HABA(0);
-                       free_irq(pdev->irq, iotg->base);
-
-                       if (lnw->iotg.stop_host)
-                               lnw->iotg.stop_host(&lnw->iotg);
-                       else
-                               dev_dbg(lnw->dev,
-                                       "host driver has been removed.\n");
-
-                       iotg->hsm.b_bus_suspend = 0;
-                       iotg->hsm.b_bus_suspend_vld = 0;
-
-                       /* msleep(200); */
-                       if (lnw->iotg.start_peripheral)
-                               lnw->iotg.start_peripheral(&lnw->iotg);
-                       else
-                               dev_dbg(lnw->dev,
-                                       "client driver not loaded.\n");
-
-                       langwell_otg_add_ktimer(TB_BUS_SUSPEND_TMR);
-                       iotg->otg.state = OTG_STATE_A_PERIPHERAL;
-                       break;
-               } else if (!iotg->hsm.a_vbus_vld) {
-                       langwell_otg_del_timer(a_aidl_bdis_tmr);
-                       langwell_otg_HABA(0);
-                       free_irq(pdev->irq, iotg->base);
-                       if (lnw->iotg.stop_host)
-                               lnw->iotg.stop_host(&lnw->iotg);
-                       else
-                               dev_dbg(lnw->dev,
-                                       "host driver has been removed.\n");
-
-                       /* Turn off VBus */
-                       iotg->otg.set_vbus(&iotg->otg, false);
-                       langwell_otg_phy_low_power_wait(1);
-                       iotg->otg.state = OTG_STATE_A_VBUS_ERR;
-               }
-               break;
-       case OTG_STATE_A_PERIPHERAL:
-               if (iotg->hsm.id) {
-                       /* delete hsm timer for b_bus_suspend_tmr */
-                       del_timer_sync(&lnw->hsm_timer);
-                       iotg->otg.default_a = 0;
-                       iotg->hsm.b_bus_req = 0;
-                       if (lnw->iotg.stop_peripheral)
-                               lnw->iotg.stop_peripheral(&lnw->iotg);
-                       else
-                               dev_dbg(lnw->dev,
-                                       "client driver has been removed.\n");
-
-                       /* Turn off VBus */
-                       iotg->otg.set_vbus(&iotg->otg, false);
-                       set_client_mode();
-                       langwell_otg_phy_low_power_wait(1);
-                       iotg->otg.state = OTG_STATE_B_IDLE;
-                       langwell_update_transceiver();
-               } else if (!iotg->hsm.a_vbus_vld) {
-                       /* delete hsm timer for b_bus_suspend_tmr */
-                       del_timer_sync(&lnw->hsm_timer);
-
-                       if (lnw->iotg.stop_peripheral)
-                               lnw->iotg.stop_peripheral(&lnw->iotg);
-                       else
-                               dev_dbg(lnw->dev,
-                                       "client driver has been removed.\n");
-
-                       /* Turn off VBus */
-                       iotg->otg.set_vbus(&iotg->otg, false);
-                       langwell_otg_phy_low_power_wait(1);
-                       iotg->otg.state = OTG_STATE_A_VBUS_ERR;
-               } else if (iotg->hsm.a_bus_drop) {
-                       /* delete hsm timer for b_bus_suspend_tmr */
-                       del_timer_sync(&lnw->hsm_timer);
-
-                       if (lnw->iotg.stop_peripheral)
-                               lnw->iotg.stop_peripheral(&lnw->iotg);
-                       else
-                               dev_dbg(lnw->dev,
-                                       "client driver has been removed.\n");
-
-                       /* Turn off VBus */
-                       iotg->otg.set_vbus(&iotg->otg, false);
-                       iotg->otg.state = OTG_STATE_A_WAIT_VFALL;
-               } else if (iotg->hsm.b_bus_suspend) {
-                       /* delete hsm timer for b_bus_suspend_tmr */
-                       del_timer_sync(&lnw->hsm_timer);
-
-                       if (lnw->iotg.stop_peripheral)
-                               lnw->iotg.stop_peripheral(&lnw->iotg);
-                       else
-                               dev_dbg(lnw->dev,
-                                       "client driver has been removed.\n");
-
-                       if (lnw->iotg.start_host)
-                               lnw->iotg.start_host(&lnw->iotg);
-                       else
-                               dev_dbg(lnw->dev,
-                                               "host driver not loaded.\n");
-                       langwell_otg_add_ktimer(TA_WAIT_BCON_TMR);
-                       iotg->otg.state = OTG_STATE_A_WAIT_BCON;
-               } else if (iotg->hsm.b_bus_suspend_tmout) {
-                       u32     val;
-                       val = readl(lnw->iotg.base + CI_PORTSC1);
-                       if (!(val & PORTSC_SUSP))
-                               break;
-
-                       if (lnw->iotg.stop_peripheral)
-                               lnw->iotg.stop_peripheral(&lnw->iotg);
-                       else
-                               dev_dbg(lnw->dev,
-                                       "client driver has been removed.\n");
-
-                       if (lnw->iotg.start_host)
-                               lnw->iotg.start_host(&lnw->iotg);
-                       else
-                               dev_dbg(lnw->dev,
-                                               "host driver not loaded.\n");
-                       langwell_otg_add_ktimer(TA_WAIT_BCON_TMR);
-                       iotg->otg.state = OTG_STATE_A_WAIT_BCON;
-               }
-               break;
-       case OTG_STATE_A_VBUS_ERR:
-               if (iotg->hsm.id) {
-                       iotg->otg.default_a = 0;
-                       iotg->hsm.a_clr_err = 0;
-                       iotg->hsm.a_srp_det = 0;
-                       set_client_mode();
-                       langwell_otg_phy_low_power(1);
-                       iotg->otg.state = OTG_STATE_B_IDLE;
-                       langwell_update_transceiver();
-               } else if (iotg->hsm.a_clr_err) {
-                       iotg->hsm.a_clr_err = 0;
-                       iotg->hsm.a_srp_det = 0;
-                       reset_otg();
-                       init_hsm();
-                       if (iotg->otg.state == OTG_STATE_A_IDLE)
-                               langwell_update_transceiver();
-               } else {
-                       /* FW will clear PHCD bit when any VBus
-                        * event detected. Reset PHCD to 1 again */
-                       langwell_otg_phy_low_power(1);
-               }
-               break;
-       case OTG_STATE_A_WAIT_VFALL:
-               if (iotg->hsm.id) {
-                       iotg->otg.default_a = 0;
-                       set_client_mode();
-                       langwell_otg_phy_low_power(1);
-                       iotg->otg.state = OTG_STATE_B_IDLE;
-                       langwell_update_transceiver();
-               } else if (iotg->hsm.a_bus_req) {
-
-                       /* Turn on VBus */
-                       iotg->otg.set_vbus(&iotg->otg, true);
-                       iotg->hsm.a_wait_vrise_tmout = 0;
-                       langwell_otg_add_timer(a_wait_vrise_tmr);
-                       iotg->otg.state = OTG_STATE_A_WAIT_VRISE;
-               } else if (!iotg->hsm.a_sess_vld) {
-                       iotg->hsm.a_srp_det = 0;
-                       set_host_mode();
-                       langwell_otg_phy_low_power(1);
-                       iotg->otg.state = OTG_STATE_A_IDLE;
-               }
-               break;
-       default:
-               ;
-       }
-
-       dev_dbg(lnw->dev, "%s: new state = %s\n", __func__,
-                       otg_state_string(iotg->otg.state));
-}
-
-static ssize_t
-show_registers(struct device *_dev, struct device_attribute *attr, char *buf)
-{
-       struct langwell_otg     *lnw = the_transceiver;
-       char                    *next;
-       unsigned                size, t;
-
-       next = buf;
-       size = PAGE_SIZE;
-
-       t = scnprintf(next, size,
-               "\n"
-               "USBCMD = 0x%08x\n"
-               "USBSTS = 0x%08x\n"
-               "USBINTR = 0x%08x\n"
-               "ASYNCLISTADDR = 0x%08x\n"
-               "PORTSC1 = 0x%08x\n"
-               "HOSTPC1 = 0x%08x\n"
-               "OTGSC = 0x%08x\n"
-               "USBMODE = 0x%08x\n",
-               readl(lnw->iotg.base + 0x30),
-               readl(lnw->iotg.base + 0x34),
-               readl(lnw->iotg.base + 0x38),
-               readl(lnw->iotg.base + 0x48),
-               readl(lnw->iotg.base + 0x74),
-               readl(lnw->iotg.base + 0xb4),
-               readl(lnw->iotg.base + 0xf4),
-               readl(lnw->iotg.base + 0xf8)
-            );
-       size -= t;
-       next += t;
-
-       return PAGE_SIZE - size;
-}
-static DEVICE_ATTR(registers, S_IRUGO, show_registers, NULL);
-
-static ssize_t
-show_hsm(struct device *_dev, struct device_attribute *attr, char *buf)
-{
-       struct langwell_otg             *lnw = the_transceiver;
-       struct intel_mid_otg_xceiv      *iotg = &lnw->iotg;
-       char                            *next;
-       unsigned                        size, t;
-
-       next = buf;
-       size = PAGE_SIZE;
-
-       if (iotg->otg.host)
-               iotg->hsm.a_set_b_hnp_en = iotg->otg.host->b_hnp_enable;
-
-       if (iotg->otg.gadget)
-               iotg->hsm.b_hnp_enable = iotg->otg.gadget->b_hnp_enable;
-
-       t = scnprintf(next, size,
-               "\n"
-               "current state = %s\n"
-               "a_bus_resume = \t%d\n"
-               "a_bus_suspend = \t%d\n"
-               "a_conn = \t%d\n"
-               "a_sess_vld = \t%d\n"
-               "a_srp_det = \t%d\n"
-               "a_vbus_vld = \t%d\n"
-               "b_bus_resume = \t%d\n"
-               "b_bus_suspend = \t%d\n"
-               "b_conn = \t%d\n"
-               "b_se0_srp = \t%d\n"
-               "b_sess_end = \t%d\n"
-               "b_sess_vld = \t%d\n"
-               "id = \t%d\n"
-               "a_set_b_hnp_en = \t%d\n"
-               "b_srp_done = \t%d\n"
-               "b_hnp_enable = \t%d\n"
-               "a_wait_vrise_tmout = \t%d\n"
-               "a_wait_bcon_tmout = \t%d\n"
-               "a_aidl_bdis_tmout = \t%d\n"
-               "b_ase0_brst_tmout = \t%d\n"
-               "a_bus_drop = \t%d\n"
-               "a_bus_req = \t%d\n"
-               "a_clr_err = \t%d\n"
-               "a_suspend_req = \t%d\n"
-               "b_bus_req = \t%d\n"
-               "b_bus_suspend_tmout = \t%d\n"
-               "b_bus_suspend_vld = \t%d\n",
-               otg_state_string(iotg->otg.state),
-               iotg->hsm.a_bus_resume,
-               iotg->hsm.a_bus_suspend,
-               iotg->hsm.a_conn,
-               iotg->hsm.a_sess_vld,
-               iotg->hsm.a_srp_det,
-               iotg->hsm.a_vbus_vld,
-               iotg->hsm.b_bus_resume,
-               iotg->hsm.b_bus_suspend,
-               iotg->hsm.b_conn,
-               iotg->hsm.b_se0_srp,
-               iotg->hsm.b_sess_end,
-               iotg->hsm.b_sess_vld,
-               iotg->hsm.id,
-               iotg->hsm.a_set_b_hnp_en,
-               iotg->hsm.b_srp_done,
-               iotg->hsm.b_hnp_enable,
-               iotg->hsm.a_wait_vrise_tmout,
-               iotg->hsm.a_wait_bcon_tmout,
-               iotg->hsm.a_aidl_bdis_tmout,
-               iotg->hsm.b_ase0_brst_tmout,
-               iotg->hsm.a_bus_drop,
-               iotg->hsm.a_bus_req,
-               iotg->hsm.a_clr_err,
-               iotg->hsm.a_suspend_req,
-               iotg->hsm.b_bus_req,
-               iotg->hsm.b_bus_suspend_tmout,
-               iotg->hsm.b_bus_suspend_vld
-               );
-       size -= t;
-       next += t;
-
-       return PAGE_SIZE - size;
-}
-static DEVICE_ATTR(hsm, S_IRUGO, show_hsm, NULL);
-
-static ssize_t
-get_a_bus_req(struct device *dev, struct device_attribute *attr, char *buf)
-{
-       struct langwell_otg     *lnw = the_transceiver;
-       char                    *next;
-       unsigned                size, t;
-
-       next = buf;
-       size = PAGE_SIZE;
-
-       t = scnprintf(next, size, "%d", lnw->iotg.hsm.a_bus_req);
-       size -= t;
-       next += t;
-
-       return PAGE_SIZE - size;
-}
-
-static ssize_t
-set_a_bus_req(struct device *dev, struct device_attribute *attr,
-               const char *buf, size_t count)
-{
-       struct langwell_otg             *lnw = the_transceiver;
-       struct intel_mid_otg_xceiv      *iotg = &lnw->iotg;
-
-       if (!iotg->otg.default_a)
-               return -1;
-       if (count > 2)
-               return -1;
-
-       if (buf[0] == '0') {
-               iotg->hsm.a_bus_req = 0;
-               dev_dbg(lnw->dev, "User request: a_bus_req = 0\n");
-       } else if (buf[0] == '1') {
-               /* If a_bus_drop is TRUE, a_bus_req can't be set */
-               if (iotg->hsm.a_bus_drop)
-                       return -1;
-               iotg->hsm.a_bus_req = 1;
-               dev_dbg(lnw->dev, "User request: a_bus_req = 1\n");
-       }
-       if (spin_trylock(&lnw->wq_lock)) {
-               langwell_update_transceiver();
-               spin_unlock(&lnw->wq_lock);
-       }
-       return count;
-}
-static DEVICE_ATTR(a_bus_req, S_IRUGO | S_IWUSR, get_a_bus_req, set_a_bus_req);
-
-static ssize_t
-get_a_bus_drop(struct device *dev, struct device_attribute *attr, char *buf)
-{
-       struct langwell_otg     *lnw = the_transceiver;
-       char                    *next;
-       unsigned                size, t;
-
-       next = buf;
-       size = PAGE_SIZE;
-
-       t = scnprintf(next, size, "%d", lnw->iotg.hsm.a_bus_drop);
-       size -= t;
-       next += t;
-
-       return PAGE_SIZE - size;
-}
-
-static ssize_t
-set_a_bus_drop(struct device *dev, struct device_attribute *attr,
-               const char *buf, size_t count)
-{
-       struct langwell_otg             *lnw = the_transceiver;
-       struct intel_mid_otg_xceiv      *iotg = &lnw->iotg;
-
-       if (!iotg->otg.default_a)
-               return -1;
-       if (count > 2)
-               return -1;
-
-       if (buf[0] == '0') {
-               iotg->hsm.a_bus_drop = 0;
-               dev_dbg(lnw->dev, "User request: a_bus_drop = 0\n");
-       } else if (buf[0] == '1') {
-               iotg->hsm.a_bus_drop = 1;
-               iotg->hsm.a_bus_req = 0;
-               dev_dbg(lnw->dev, "User request: a_bus_drop = 1\n");
-               dev_dbg(lnw->dev, "User request: and a_bus_req = 0\n");
-       }
-       if (spin_trylock(&lnw->wq_lock)) {
-               langwell_update_transceiver();
-               spin_unlock(&lnw->wq_lock);
-       }
-       return count;
-}
-static DEVICE_ATTR(a_bus_drop, S_IRUGO | S_IWUSR, get_a_bus_drop, set_a_bus_drop);
-
-static ssize_t
-get_b_bus_req(struct device *dev, struct device_attribute *attr, char *buf)
-{
-       struct langwell_otg     *lnw = the_transceiver;
-       char                    *next;
-       unsigned                size, t;
-
-       next = buf;
-       size = PAGE_SIZE;
-
-       t = scnprintf(next, size, "%d", lnw->iotg.hsm.b_bus_req);
-       size -= t;
-       next += t;
-
-       return PAGE_SIZE - size;
-}
-
-static ssize_t
-set_b_bus_req(struct device *dev, struct device_attribute *attr,
-               const char *buf, size_t count)
-{
-       struct langwell_otg             *lnw = the_transceiver;
-       struct intel_mid_otg_xceiv      *iotg = &lnw->iotg;
-
-       if (iotg->otg.default_a)
-               return -1;
-
-       if (count > 2)
-               return -1;
-
-       if (buf[0] == '0') {
-               iotg->hsm.b_bus_req = 0;
-               dev_dbg(lnw->dev, "User request: b_bus_req = 0\n");
-       } else if (buf[0] == '1') {
-               iotg->hsm.b_bus_req = 1;
-               dev_dbg(lnw->dev, "User request: b_bus_req = 1\n");
-       }
-       if (spin_trylock(&lnw->wq_lock)) {
-               langwell_update_transceiver();
-               spin_unlock(&lnw->wq_lock);
-       }
-       return count;
-}
-static DEVICE_ATTR(b_bus_req, S_IRUGO | S_IWUSR, get_b_bus_req, set_b_bus_req);
-
-static ssize_t
-set_a_clr_err(struct device *dev, struct device_attribute *attr,
-               const char *buf, size_t count)
-{
-       struct langwell_otg             *lnw = the_transceiver;
-       struct intel_mid_otg_xceiv      *iotg = &lnw->iotg;
-
-       if (!iotg->otg.default_a)
-               return -1;
-       if (count > 2)
-               return -1;
-
-       if (buf[0] == '1') {
-               iotg->hsm.a_clr_err = 1;
-               dev_dbg(lnw->dev, "User request: a_clr_err = 1\n");
-       }
-       if (spin_trylock(&lnw->wq_lock)) {
-               langwell_update_transceiver();
-               spin_unlock(&lnw->wq_lock);
-       }
-       return count;
-}
-static DEVICE_ATTR(a_clr_err, S_IWUSR, NULL, set_a_clr_err);
-
-static struct attribute *inputs_attrs[] = {
-       &dev_attr_a_bus_req.attr,
-       &dev_attr_a_bus_drop.attr,
-       &dev_attr_b_bus_req.attr,
-       &dev_attr_a_clr_err.attr,
-       NULL,
-};
-
-static struct attribute_group debug_dev_attr_group = {
-       .name = "inputs",
-       .attrs = inputs_attrs,
-};
-
-static int langwell_otg_probe(struct pci_dev *pdev,
-               const struct pci_device_id *id)
-{
-       unsigned long           resource, len;
-       void __iomem            *base = NULL;
-       int                     retval;
-       u32                     val32;
-       struct langwell_otg     *lnw;
-       char                    qname[] = "langwell_otg_queue";
-
-       retval = 0;
-       dev_dbg(&pdev->dev, "\notg controller is detected.\n");
-       if (pci_enable_device(pdev) < 0) {
-               retval = -ENODEV;
-               goto done;
-       }
-
-       lnw = kzalloc(sizeof *lnw, GFP_KERNEL);
-       if (lnw == NULL) {
-               retval = -ENOMEM;
-               goto done;
-       }
-       the_transceiver = lnw;
-
-       /* control register: BAR 0 */
-       resource = pci_resource_start(pdev, 0);
-       len = pci_resource_len(pdev, 0);
-       if (!request_mem_region(resource, len, driver_name)) {
-               retval = -EBUSY;
-               goto err;
-       }
-       lnw->region = 1;
-
-       base = ioremap_nocache(resource, len);
-       if (base == NULL) {
-               retval = -EFAULT;
-               goto err;
-       }
-       lnw->iotg.base = base;
-
-       if (!request_mem_region(USBCFG_ADDR, USBCFG_LEN, driver_name)) {
-               retval = -EBUSY;
-               goto err;
-       }
-       lnw->cfg_region = 1;
-
-       /* For the SCCB.USBCFG register */
-       base = ioremap_nocache(USBCFG_ADDR, USBCFG_LEN);
-       if (base == NULL) {
-               retval = -EFAULT;
-               goto err;
-       }
-       lnw->usbcfg = base;
-
-       if (!pdev->irq) {
-               dev_dbg(&pdev->dev, "No IRQ.\n");
-               retval = -ENODEV;
-               goto err;
-       }
-
-       lnw->qwork = create_singlethread_workqueue(qname);
-       if (!lnw->qwork) {
-               dev_dbg(&pdev->dev, "cannot create workqueue %s\n", qname);
-               retval = -ENOMEM;
-               goto err;
-       }
-       INIT_WORK(&lnw->work, langwell_otg_work);
-
-       /* OTG common part */
-       lnw->dev = &pdev->dev;
-       lnw->iotg.otg.dev = lnw->dev;
-       lnw->iotg.otg.label = driver_name;
-       lnw->iotg.otg.set_host = langwell_otg_set_host;
-       lnw->iotg.otg.set_peripheral = langwell_otg_set_peripheral;
-       lnw->iotg.otg.set_power = langwell_otg_set_power;
-       lnw->iotg.otg.set_vbus = langwell_otg_set_vbus;
-       lnw->iotg.otg.start_srp = langwell_otg_start_srp;
-       lnw->iotg.otg.state = OTG_STATE_UNDEFINED;
-
-       if (otg_set_transceiver(&lnw->iotg.otg)) {
-               dev_dbg(lnw->dev, "can't set transceiver\n");
-               retval = -EBUSY;
-               goto err;
-       }
-
-       reset_otg();
-       init_hsm();
-
-       spin_lock_init(&lnw->lock);
-       spin_lock_init(&lnw->wq_lock);
-       INIT_LIST_HEAD(&active_timers);
-       retval = langwell_otg_init_timers(&lnw->iotg.hsm);
-       if (retval) {
-               dev_dbg(&pdev->dev, "Failed to init timers\n");
-               goto err;
-       }
-
-       init_timer(&lnw->hsm_timer);
-       ATOMIC_INIT_NOTIFIER_HEAD(&lnw->iotg.iotg_notifier);
-
-       lnw->iotg_notifier.notifier_call = langwell_otg_iotg_notify;
-
-       retval = intel_mid_otg_register_notifier(&lnw->iotg,
-                                               &lnw->iotg_notifier);
-       if (retval) {
-               dev_dbg(lnw->dev, "Failed to register notifier\n");
-               goto err;
-       }
-
-       if (request_irq(pdev->irq, otg_irq, IRQF_SHARED,
-                               driver_name, lnw) != 0) {
-               dev_dbg(lnw->dev, "request interrupt %d failed\n", pdev->irq);
-               retval = -EBUSY;
-               goto err;
-       }
-
-       /* enable OTGSC int */
-       val32 = OTGSC_DPIE | OTGSC_BSEIE | OTGSC_BSVIE |
-               OTGSC_ASVIE | OTGSC_AVVIE | OTGSC_IDIE | OTGSC_IDPU;
-       writel(val32, lnw->iotg.base + CI_OTGSC);
-
-       retval = device_create_file(&pdev->dev, &dev_attr_registers);
-       if (retval < 0) {
-               dev_dbg(lnw->dev,
-                       "Can't register sysfs attribute: %d\n", retval);
-               goto err;
-       }
-
-       retval = device_create_file(&pdev->dev, &dev_attr_hsm);
-       if (retval < 0) {
-               dev_dbg(lnw->dev, "Can't hsm sysfs attribute: %d\n", retval);
-               goto err;
-       }
-
-       retval = sysfs_create_group(&pdev->dev.kobj, &debug_dev_attr_group);
-       if (retval < 0) {
-               dev_dbg(lnw->dev,
-                       "Can't register sysfs attr group: %d\n", retval);
-               goto err;
-       }
-
-       if (lnw->iotg.otg.state == OTG_STATE_A_IDLE)
-               langwell_update_transceiver();
-
-       return 0;
-
-err:
-       if (the_transceiver)
-               langwell_otg_remove(pdev);
-done:
-       return retval;
-}
-
-static void langwell_otg_remove(struct pci_dev *pdev)
-{
-       struct langwell_otg *lnw = the_transceiver;
-
-       if (lnw->qwork) {
-               flush_workqueue(lnw->qwork);
-               destroy_workqueue(lnw->qwork);
-       }
-       intel_mid_otg_unregister_notifier(&lnw->iotg, &lnw->iotg_notifier);
-       langwell_otg_free_timers();
-
-       /* disable OTGSC interrupt as OTGSC doesn't change in reset */
-       writel(0, lnw->iotg.base + CI_OTGSC);
-
-       if (pdev->irq)
-               free_irq(pdev->irq, lnw);
-       if (lnw->usbcfg)
-               iounmap(lnw->usbcfg);
-       if (lnw->cfg_region)
-               release_mem_region(USBCFG_ADDR, USBCFG_LEN);
-       if (lnw->iotg.base)
-               iounmap(lnw->iotg.base);
-       if (lnw->region)
-               release_mem_region(pci_resource_start(pdev, 0),
-                               pci_resource_len(pdev, 0));
-
-       otg_set_transceiver(NULL);
-       pci_disable_device(pdev);
-       sysfs_remove_group(&pdev->dev.kobj, &debug_dev_attr_group);
-       device_remove_file(&pdev->dev, &dev_attr_hsm);
-       device_remove_file(&pdev->dev, &dev_attr_registers);
-       kfree(lnw);
-       lnw = NULL;
-}
-
-static void transceiver_suspend(struct pci_dev *pdev)
-{
-       pci_save_state(pdev);
-       pci_set_power_state(pdev, PCI_D3hot);
-       langwell_otg_phy_low_power(1);
-}
-
-static int langwell_otg_suspend(struct pci_dev *pdev, pm_message_t message)
-{
-       struct langwell_otg             *lnw = the_transceiver;
-       struct intel_mid_otg_xceiv      *iotg = &lnw->iotg;
-       int                             ret = 0;
-
-       /* Disbale OTG interrupts */
-       langwell_otg_intr(0);
-
-       if (pdev->irq)
-               free_irq(pdev->irq, lnw);
-
-       /* Prevent more otg_work */
-       flush_workqueue(lnw->qwork);
-       destroy_workqueue(lnw->qwork);
-       lnw->qwork = NULL;
-
-       /* start actions */
-       switch (iotg->otg.state) {
-       case OTG_STATE_A_WAIT_VFALL:
-               iotg->otg.state = OTG_STATE_A_IDLE;
-       case OTG_STATE_A_IDLE:
-       case OTG_STATE_B_IDLE:
-       case OTG_STATE_A_VBUS_ERR:
-               transceiver_suspend(pdev);
-               break;
-       case OTG_STATE_A_WAIT_VRISE:
-               langwell_otg_del_timer(a_wait_vrise_tmr);
-               iotg->hsm.a_srp_det = 0;
-
-               /* Turn off VBus */
-               iotg->otg.set_vbus(&iotg->otg, false);
-               iotg->otg.state = OTG_STATE_A_IDLE;
-               transceiver_suspend(pdev);
-               break;
-       case OTG_STATE_A_WAIT_BCON:
-               del_timer_sync(&lnw->hsm_timer);
-               if (lnw->iotg.stop_host)
-                       lnw->iotg.stop_host(&lnw->iotg);
-               else
-                       dev_dbg(&pdev->dev, "host driver has been removed.\n");
-
-               iotg->hsm.a_srp_det = 0;
-
-               /* Turn off VBus */
-               iotg->otg.set_vbus(&iotg->otg, false);
-               iotg->otg.state = OTG_STATE_A_IDLE;
-               transceiver_suspend(pdev);
-               break;
-       case OTG_STATE_A_HOST:
-               if (lnw->iotg.stop_host)
-                       lnw->iotg.stop_host(&lnw->iotg);
-               else
-                       dev_dbg(&pdev->dev, "host driver has been removed.\n");
-
-               iotg->hsm.a_srp_det = 0;
-
-               /* Turn off VBus */
-               iotg->otg.set_vbus(&iotg->otg, false);
-
-               iotg->otg.state = OTG_STATE_A_IDLE;
-               transceiver_suspend(pdev);
-               break;
-       case OTG_STATE_A_SUSPEND:
-               langwell_otg_del_timer(a_aidl_bdis_tmr);
-               langwell_otg_HABA(0);
-               if (lnw->iotg.stop_host)
-                       lnw->iotg.stop_host(&lnw->iotg);
-               else
-                       dev_dbg(lnw->dev, "host driver has been removed.\n");
-               iotg->hsm.a_srp_det = 0;
-
-               /* Turn off VBus */
-               iotg->otg.set_vbus(&iotg->otg, false);
-               iotg->otg.state = OTG_STATE_A_IDLE;
-               transceiver_suspend(pdev);
-               break;
-       case OTG_STATE_A_PERIPHERAL:
-               del_timer_sync(&lnw->hsm_timer);
-
-               if (lnw->iotg.stop_peripheral)
-                       lnw->iotg.stop_peripheral(&lnw->iotg);
-               else
-                       dev_dbg(&pdev->dev,
-                               "client driver has been removed.\n");
-               iotg->hsm.a_srp_det = 0;
-
-               /* Turn off VBus */
-               iotg->otg.set_vbus(&iotg->otg, false);
-               iotg->otg.state = OTG_STATE_A_IDLE;
-               transceiver_suspend(pdev);
-               break;
-       case OTG_STATE_B_HOST:
-               if (lnw->iotg.stop_host)
-                       lnw->iotg.stop_host(&lnw->iotg);
-               else
-                       dev_dbg(&pdev->dev, "host driver has been removed.\n");
-               iotg->hsm.b_bus_req = 0;
-               iotg->otg.state = OTG_STATE_B_IDLE;
-               transceiver_suspend(pdev);
-               break;
-       case OTG_STATE_B_PERIPHERAL:
-               if (lnw->iotg.stop_peripheral)
-                       lnw->iotg.stop_peripheral(&lnw->iotg);
-               else
-                       dev_dbg(&pdev->dev,
-                               "client driver has been removed.\n");
-               iotg->otg.state = OTG_STATE_B_IDLE;
-               transceiver_suspend(pdev);
-               break;
-       case OTG_STATE_B_WAIT_ACON:
-               /* delete hsm timer for b_ase0_brst_tmr */
-               del_timer_sync(&lnw->hsm_timer);
-
-               langwell_otg_HAAR(0);
-
-               if (lnw->iotg.stop_host)
-                       lnw->iotg.stop_host(&lnw->iotg);
-               else
-                       dev_dbg(&pdev->dev, "host driver has been removed.\n");
-               iotg->hsm.b_bus_req = 0;
-               iotg->otg.state = OTG_STATE_B_IDLE;
-               transceiver_suspend(pdev);
-               break;
-       default:
-               dev_dbg(lnw->dev, "error state before suspend\n");
-               break;
-       }
-
-       return ret;
-}
-
-static void transceiver_resume(struct pci_dev *pdev)
-{
-       pci_restore_state(pdev);
-       pci_set_power_state(pdev, PCI_D0);
-}
-
-static int langwell_otg_resume(struct pci_dev *pdev)
-{
-       struct langwell_otg     *lnw = the_transceiver;
-       int                     ret = 0;
-
-       transceiver_resume(pdev);
-
-       lnw->qwork = create_singlethread_workqueue("langwell_otg_queue");
-       if (!lnw->qwork) {
-               dev_dbg(&pdev->dev, "cannot create langwell otg workqueuen");
-               ret = -ENOMEM;
-               goto error;
-       }
-
-       if (request_irq(pdev->irq, otg_irq, IRQF_SHARED,
-                               driver_name, lnw) != 0) {
-               dev_dbg(&pdev->dev, "request interrupt %d failed\n", pdev->irq);
-               ret = -EBUSY;
-               goto error;
-       }
-
-       /* enable OTG interrupts */
-       langwell_otg_intr(1);
-
-       update_hsm();
-
-       langwell_update_transceiver();
-
-       return ret;
-error:
-       langwell_otg_intr(0);
-       transceiver_suspend(pdev);
-       return ret;
-}
-
-static int __init langwell_otg_init(void)
-{
-       return pci_register_driver(&otg_pci_driver);
-}
-module_init(langwell_otg_init);
-
-static void __exit langwell_otg_cleanup(void)
-{
-       pci_unregister_driver(&otg_pci_driver);
-}
-module_exit(langwell_otg_cleanup);
index db0d4fc..b5fbe14 100644 (file)
@@ -202,6 +202,7 @@ static void mv_otg_init_irq(struct mv_otg *mvotg)
 
 static void mv_otg_start_host(struct mv_otg *mvotg, int on)
 {
+#ifdef CONFIG_USB
        struct otg_transceiver *otg = &mvotg->otg;
        struct usb_hcd *hcd;
 
@@ -216,6 +217,7 @@ static void mv_otg_start_host(struct mv_otg *mvotg, int on)
                usb_add_hcd(hcd, hcd->irq, IRQF_SHARED);
        else
                usb_remove_hcd(hcd);
+#endif /* CONFIG_USB */
 }
 
 static void mv_otg_start_periphrals(struct mv_otg *mvotg, int on)
index 528691d..7542aa9 100644 (file)
@@ -425,7 +425,7 @@ static int usbhsg_recip_run_handle(struct usbhs_priv *priv,
        struct usbhs_pipe *pipe;
        int recip = ctrl->bRequestType & USB_RECIP_MASK;
        int nth = le16_to_cpu(ctrl->wIndex) & USB_ENDPOINT_NUMBER_MASK;
-       int ret;
+       int ret = 0;
        int (*func)(struct usbhs_priv *priv, struct usbhsg_uep *uep,
                    struct usb_ctrlrequest *ctrl);
        char *msg;
index fba1147..8dbf51a 100644 (file)
@@ -39,6 +39,8 @@ static void cp210x_get_termios(struct tty_struct *,
        struct usb_serial_port *port);
 static void cp210x_get_termios_port(struct usb_serial_port *port,
        unsigned int *cflagp, unsigned int *baudp);
+static void cp210x_change_speed(struct tty_struct *, struct usb_serial_port *,
+                                                       struct ktermios *);
 static void cp210x_set_termios(struct tty_struct *, struct usb_serial_port *,
                                                        struct ktermios*);
 static int cp210x_tiocmget(struct tty_struct *);
@@ -138,6 +140,7 @@ static const struct usb_device_id id_table[] = {
        { USB_DEVICE(0x1843, 0x0200) }, /* Vaisala USB Instrument Cable */
        { USB_DEVICE(0x18EF, 0xE00F) }, /* ELV USB-I2C-Interface */
        { USB_DEVICE(0x1BE3, 0x07A6) }, /* WAGO 750-923 USB Service Cable */
+       { USB_DEVICE(0x3195, 0xF190) }, /* Link Instruments MSO-19 */
        { USB_DEVICE(0x413C, 0x9500) }, /* DW700 GPS USB interface */
        { } /* Terminating Entry */
 };
@@ -201,6 +204,8 @@ static struct usb_serial_driver cp210x_device = {
 #define CP210X_EMBED_EVENTS    0x15
 #define CP210X_GET_EVENTSTATE  0x16
 #define CP210X_SET_CHARS       0x19
+#define CP210X_GET_BAUDRATE    0x1D
+#define CP210X_SET_BAUDRATE    0x1E
 
 /* CP210X_IFC_ENABLE */
 #define UART_ENABLE            0x0001
@@ -360,8 +365,8 @@ static inline int cp210x_set_config_single(struct usb_serial_port *port,
  * Quantises the baud rate as per AN205 Table 1
  */
 static unsigned int cp210x_quantise_baudrate(unsigned int baud) {
-       if      (baud <= 56)       baud = 0;
-       else if (baud <= 300)      baud = 300;
+       if (baud <= 300)
+               baud = 300;
        else if (baud <= 600)      baud = 600;
        else if (baud <= 1200)     baud = 1200;
        else if (baud <= 1800)     baud = 1800;
@@ -389,10 +394,10 @@ static unsigned int cp210x_quantise_baudrate(unsigned int baud) {
        else if (baud <= 491520)   baud = 460800;
        else if (baud <= 567138)   baud = 500000;
        else if (baud <= 670254)   baud = 576000;
-       else if (baud <= 1053257)  baud = 921600;
-       else if (baud <= 1474560)  baud = 1228800;
-       else if (baud <= 2457600)  baud = 1843200;
-       else                       baud = 3686400;
+       else if (baud < 1000000)
+               baud = 921600;
+       else if (baud > 2000000)
+               baud = 2000000;
        return baud;
 }
 
@@ -409,13 +414,14 @@ static int cp210x_open(struct tty_struct *tty, struct usb_serial_port *port)
                return result;
        }
 
-       result = usb_serial_generic_open(tty, port);
-       if (result)
-               return result;
-
        /* Configure the termios structure */
        cp210x_get_termios(tty, port);
-       return 0;
+
+       /* The baud rate must be initialised on cp2104 */
+       if (tty)
+               cp210x_change_speed(tty, port, NULL);
+
+       return usb_serial_generic_open(tty, port);
 }
 
 static void cp210x_close(struct usb_serial_port *port)
@@ -467,10 +473,7 @@ static void cp210x_get_termios_port(struct usb_serial_port *port,
 
        dbg("%s - port %d", __func__, port->number);
 
-       cp210x_get_config(port, CP210X_GET_BAUDDIV, &baud, 2);
-       /* Convert to baudrate */
-       if (baud)
-               baud = cp210x_quantise_baudrate((BAUD_RATE_GEN_FREQ + baud/2)/ baud);
+       cp210x_get_config(port, CP210X_GET_BAUDRATE, &baud, 4);
 
        dbg("%s - baud rate = %d", __func__, baud);
        *baudp = baud;
@@ -579,11 +582,64 @@ static void cp210x_get_termios_port(struct usb_serial_port *port,
        *cflagp = cflag;
 }
 
+/*
+ * CP2101 supports the following baud rates:
+ *
+ *     300, 600, 1200, 1800, 2400, 4800, 7200, 9600, 14400, 19200, 28800,
+ *     38400, 56000, 57600, 115200, 128000, 230400, 460800, 921600
+ *
+ * CP2102 and CP2103 support the following additional rates:
+ *
+ *     4000, 16000, 51200, 64000, 76800, 153600, 250000, 256000, 500000,
+ *     576000
+ *
+ * The device will map a requested rate to a supported one, but the result
+ * of requests for rates greater than 1053257 is undefined (see AN205).
+ *
+ * CP2104, CP2105 and CP2110 support most rates up to 2M, 921k and 1M baud,
+ * respectively, with an error less than 1%. The actual rates are determined
+ * by
+ *
+ *     div = round(freq / (2 x prescale x request))
+ *     actual = freq / (2 x prescale x div)
+ *
+ * For CP2104 and CP2105 freq is 48Mhz and prescale is 4 for request <= 365bps
+ * or 1 otherwise.
+ * For CP2110 freq is 24Mhz and prescale is 4 for request <= 300bps or 1
+ * otherwise.
+ */
+static void cp210x_change_speed(struct tty_struct *tty,
+               struct usb_serial_port *port, struct ktermios *old_termios)
+{
+       u32 baud;
+
+       baud = tty->termios->c_ospeed;
+
+       /* This maps the requested rate to a rate valid on cp2102 or cp2103,
+        * or to an arbitrary rate in [1M,2M].
+        *
+        * NOTE: B0 is not implemented.
+        */
+       baud = cp210x_quantise_baudrate(baud);
+
+       dbg("%s - setting baud rate to %u", __func__, baud);
+       if (cp210x_set_config(port, CP210X_SET_BAUDRATE, &baud,
+                                                       sizeof(baud))) {
+               dev_warn(&port->dev, "failed to set baud rate to %u\n", baud);
+               if (old_termios)
+                       baud = old_termios->c_ospeed;
+               else
+                       baud = 9600;
+       }
+
+       tty_encode_baud_rate(tty, baud, baud);
+}
+
 static void cp210x_set_termios(struct tty_struct *tty,
                struct usb_serial_port *port, struct ktermios *old_termios)
 {
        unsigned int cflag, old_cflag;
-       unsigned int baud = 0, bits;
+       unsigned int bits;
        unsigned int modem_ctl[4];
 
        dbg("%s - port %d", __func__, port->number);
@@ -593,20 +649,9 @@ static void cp210x_set_termios(struct tty_struct *tty,
 
        cflag = tty->termios->c_cflag;
        old_cflag = old_termios->c_cflag;
-       baud = cp210x_quantise_baudrate(tty_get_baud_rate(tty));
-
-       /* If the baud rate is to be updated*/
-       if (baud != tty_termios_baud_rate(old_termios) && baud != 0) {
-               dbg("%s - Setting baud rate to %d baud", __func__,
-                               baud);
-               if (cp210x_set_config_single(port, CP210X_SET_BAUDDIV,
-                                       ((BAUD_RATE_GEN_FREQ + baud/2) / baud))) {
-                       dbg("Baud rate requested not supported by device");
-                       baud = tty_termios_baud_rate(old_termios);
-               }
-       }
-       /* Report back the resulting baud rate */
-       tty_encode_baud_rate(tty, baud, baud);
+
+       if (tty->termios->c_ospeed != old_termios->c_ospeed)
+               cp210x_change_speed(tty, port, old_termios);
 
        /* If the number of data bits is to be updated */
        if ((cflag & CSIZE) != (old_cflag & CSIZE)) {
index 01b6404..f770415 100644 (file)
@@ -797,6 +797,7 @@ static struct usb_device_id id_table_combined [] = {
                .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
        { USB_DEVICE(ADI_VID, ADI_GNICEPLUS_PID),
                .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
+       { USB_DEVICE(HORNBY_VID, HORNBY_ELITE_PID) },
        { USB_DEVICE(JETI_VID, JETI_SPC1201_PID) },
        { USB_DEVICE(MARVELL_VID, MARVELL_SHEEVAPLUG_PID),
                .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
@@ -805,6 +806,8 @@ static struct usb_device_id id_table_combined [] = {
        { USB_DEVICE(BAYER_VID, BAYER_CONTOUR_CABLE_PID) },
        { USB_DEVICE(FTDI_VID, MARVELL_OPENRD_PID),
                .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
+       { USB_DEVICE(FTDI_VID, TI_XDS100V2_PID),
+               .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
        { USB_DEVICE(FTDI_VID, HAMEG_HO820_PID) },
        { USB_DEVICE(FTDI_VID, HAMEG_HO720_PID) },
        { USB_DEVICE(FTDI_VID, HAMEG_HO730_PID) },
@@ -836,11 +839,13 @@ static struct usb_device_id id_table_combined [] = {
        { USB_DEVICE(FTDI_VID, FTDI_SCIENCESCOPE_LOGBOOKML_PID) },
        { USB_DEVICE(FTDI_VID, FTDI_SCIENCESCOPE_LS_LOGBOOK_PID) },
        { USB_DEVICE(FTDI_VID, FTDI_SCIENCESCOPE_HS_LOGBOOK_PID) },
+       { USB_DEVICE(FTDI_VID, FTDI_CINTERION_MC55I_PID) },
        { 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_STMCLT1030_PID),
                .driver_info = (kernel_ulong_t)&ftdi_stmclite_quirk },
+       { USB_DEVICE(FTDI_VID, FTDI_RF_R106) },
        { },                                    /* Optional parameter entry */
        { }                                     /* Terminating entry */
 };
@@ -1333,8 +1338,7 @@ static int set_serial_info(struct tty_struct *tty,
                goto check_and_exit;
        }
 
-       if ((new_serial.baud_base != priv->baud_base) &&
-           (new_serial.baud_base < 9600)) {
+       if (new_serial.baud_base != priv->baud_base) {
                mutex_unlock(&priv->cfg_lock);
                return -EINVAL;
        }
@@ -1824,6 +1828,7 @@ static int ftdi_sio_port_remove(struct usb_serial_port *port)
 
 static int ftdi_open(struct tty_struct *tty, struct usb_serial_port *port)
 {
+       struct ktermios dummy;
        struct usb_device *dev = port->serial->dev;
        struct ftdi_private *priv = usb_get_serial_port_data(port);
        int result;
@@ -1842,8 +1847,10 @@ static int ftdi_open(struct tty_struct *tty, struct usb_serial_port *port)
           This is same behaviour as serial.c/rs_open() - Kuba */
 
        /* ftdi_set_termios  will send usb control messages */
-       if (tty)
-               ftdi_set_termios(tty, port, tty->termios);
+       if (tty) {
+               memset(&dummy, 0, sizeof(dummy));
+               ftdi_set_termios(tty, port, &dummy);
+       }
 
        /* Start reading from the device */
        result = usb_serial_generic_open(tty, port);
index df1d7da..6f6058f 100644 (file)
 /* www.candapter.com Ewert Energy Systems CANdapter device */
 #define FTDI_CANDAPTER_PID 0x9F80 /* Product Id */
 
+/*
+ * Texas Instruments XDS100v2 JTAG / BeagleBone A3
+ * http://processors.wiki.ti.com/index.php/XDS100
+ * http://beagleboard.org/bone
+ */
+#define TI_XDS100V2_PID                0xa6d0
+
 #define FTDI_NXTCAM_PID                0xABB8 /* NXTCam for Mindstorms NXT */
 
 /* US Interface Navigator (http://www.usinterface.com/) */
 #define ADI_GNICE_PID          0xF000
 #define ADI_GNICEPLUS_PID      0xF001
 
+/*
+ * Hornby Elite
+ */
+#define HORNBY_VID             0x04D8
+#define HORNBY_ELITE_PID       0x000A
+
 /*
  * RATOC REX-USB60F
  */
  */
 /* TagTracer MIFARE*/
 #define FTDI_ZEITCONTROL_TAGTRACE_MIFARE_PID   0xF7C0
+
+/*
+ * Rainforest Automation
+ */
+/* ZigBee controller */
+#define FTDI_RF_R106           0x8A28
+
+/*
+ * Product: HCP HIT GPRS modem
+ * Manufacturer: HCP d.o.o.
+ * ATI command output: Cinterion MC55i
+ */
+#define FTDI_CINTERION_MC55I_PID       0xA951
index 65bf06a..5818bfc 100644 (file)
@@ -2657,15 +2657,7 @@ cleanup:
 
 static void edge_disconnect(struct usb_serial *serial)
 {
-       int i;
-       struct edgeport_port *edge_port;
-
        dbg("%s", __func__);
-
-       for (i = 0; i < serial->num_ports; ++i) {
-               edge_port = usb_get_serial_port_data(serial->port[i]);
-               edge_remove_sysfs_attrs(edge_port->port);
-       }
 }
 
 static void edge_release(struct usb_serial *serial)
@@ -2744,6 +2736,7 @@ static struct usb_serial_driver edgeport_1port_device = {
        .disconnect             = edge_disconnect,
        .release                = edge_release,
        .port_probe             = edge_create_sysfs_attrs,
+       .port_remove            = edge_remove_sysfs_attrs,
        .ioctl                  = edge_ioctl,
        .set_termios            = edge_set_termios,
        .tiocmget               = edge_tiocmget,
@@ -2775,6 +2768,7 @@ static struct usb_serial_driver edgeport_2port_device = {
        .disconnect             = edge_disconnect,
        .release                = edge_release,
        .port_probe             = edge_create_sysfs_attrs,
+       .port_remove            = edge_remove_sysfs_attrs,
        .ioctl                  = edge_ioctl,
        .set_termios            = edge_set_termios,
        .tiocmget               = edge_tiocmget,
index 5d3beee..a92a3ef 100644 (file)
@@ -38,7 +38,7 @@
 #include <linux/ioctl.h>
 #include "kobil_sct.h"
 
-static int debug;
+static bool debug;
 
 /* Version Information */
 #define DRIVER_VERSION "21/05/2004"
index 420d985..39ed1f4 100644 (file)
@@ -480,6 +480,10 @@ static void option_instat_callback(struct urb *urb);
 #define ZD_VENDOR_ID                           0x0685
 #define ZD_PRODUCT_7000                                0x7000
 
+/* LG products */
+#define LG_VENDOR_ID                           0x1004
+#define LG_PRODUCT_L02C                                0x618f
+
 /* some devices interfaces need special handling due to a number of reasons */
 enum option_blacklist_reason {
                OPTION_BLACKLIST_NONE = 0,
@@ -851,6 +855,18 @@ static const struct usb_device_id option_ids[] = {
        { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0083, 0xff, 0xff, 0xff) },
        { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0086, 0xff, 0xff, 0xff) },
        { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0087, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0088, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0089, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0090, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0091, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0092, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0093, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0094, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0095, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0096, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0097, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0098, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0099, 0xff, 0xff, 0xff) },
        { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0104, 0xff, 0xff, 0xff),
                .driver_info = (kernel_ulong_t)&net_intf4_blacklist },
        { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0105, 0xff, 0xff, 0xff) },
@@ -879,7 +895,6 @@ static const struct usb_device_id option_ids[] = {
        { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0151, 0xff, 0xff, 0xff) },
        { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0152, 0xff, 0xff, 0xff) },
        { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0153, 0xff, 0xff, 0xff) },
-       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0154, 0xff, 0xff, 0xff) },
        { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0155, 0xff, 0xff, 0xff) },
        { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0156, 0xff, 0xff, 0xff) },
        { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0157, 0xff, 0xff, 0xff) },
@@ -888,6 +903,12 @@ static const struct usb_device_id option_ids[] = {
        { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0160, 0xff, 0xff, 0xff) },
        { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0161, 0xff, 0xff, 0xff) },
        { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0162, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0164, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0165, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0168, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0170, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0176, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0178, 0xff, 0xff, 0xff) },
        { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1008, 0xff, 0xff, 0xff) },
        { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1010, 0xff, 0xff, 0xff) },
        { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1012, 0xff, 0xff, 0xff) },
@@ -1062,6 +1083,116 @@ static const struct usb_device_id option_ids[] = {
        { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1298, 0xff, 0xff, 0xff) },
        { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1299, 0xff, 0xff, 0xff) },
        { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1300, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1401, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1402, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1403, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1404, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1405, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1406, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1407, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1408, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1409, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1410, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1411, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1412, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1413, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1414, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1415, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1416, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1417, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1418, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1419, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1420, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1421, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1422, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1423, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1424, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1425, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1426, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1427, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1428, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1429, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1430, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1431, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1432, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1433, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1434, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1435, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1436, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1437, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1438, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1439, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1440, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1441, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1442, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1443, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1444, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1445, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1446, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1447, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1448, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1449, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1450, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1451, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1452, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1453, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1454, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1455, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1456, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1457, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1458, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1459, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1460, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1461, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1462, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1463, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1464, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1465, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1466, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1467, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1468, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1469, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1470, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1471, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1472, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1473, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1474, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1475, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1476, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1477, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1478, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1479, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1480, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1481, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1482, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1483, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1484, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1485, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1486, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1487, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1488, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1489, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1490, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1491, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1492, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1493, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1494, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1495, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1496, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1497, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1498, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1499, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1500, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1501, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1502, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1503, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1504, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1505, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1506, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1507, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1508, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1509, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1510, 0xff, 0xff, 0xff) },
        { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0014, 0xff, 0xff, 0xff) }, /* ZTE CDMA products */
        { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0027, 0xff, 0xff, 0xff) },
        { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0059, 0xff, 0xff, 0xff) },
@@ -1183,6 +1314,7 @@ static const struct usb_device_id option_ids[] = {
        { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CLU526) },
        { USB_DEVICE_AND_INTERFACE_INFO(VIETTEL_VENDOR_ID, VIETTEL_PRODUCT_VT1000, 0xff, 0xff, 0xff) },
        { USB_DEVICE_AND_INTERFACE_INFO(ZD_VENDOR_ID, ZD_PRODUCT_7000, 0xff, 0xff, 0xff) },
+       { USB_DEVICE(LG_VENDOR_ID, LG_PRODUCT_L02C) }, /* docomo L-02C modem */
        { } /* Terminating entry */
 };
 MODULE_DEVICE_TABLE(usb, option_ids);
index 30b73e6..a348198 100644 (file)
@@ -36,6 +36,7 @@
 #define UTSTARCOM_PRODUCT_UM175_V1             0x3712
 #define UTSTARCOM_PRODUCT_UM175_V2             0x3714
 #define UTSTARCOM_PRODUCT_UM175_ALLTEL         0x3715
+#define PANTECH_PRODUCT_UML190_VZW             0x3716
 #define PANTECH_PRODUCT_UML290_VZW             0x3718
 
 /* CMOTECH devices */
@@ -67,7 +68,11 @@ static struct usb_device_id id_table[] = {
        { USB_DEVICE_AND_INTERFACE_INFO(LG_VENDOR_ID, LG_PRODUCT_VX4400_6000, 0xff, 0xff, 0x00) },
        { USB_DEVICE_AND_INTERFACE_INFO(SANYO_VENDOR_ID, SANYO_PRODUCT_KATANA_LX, 0xff, 0xff, 0x00) },
        { USB_DEVICE_AND_INTERFACE_INFO(SAMSUNG_VENDOR_ID, SAMSUNG_PRODUCT_U520, 0xff, 0x00, 0x00) },
-       { USB_DEVICE_AND_INTERFACE_INFO(UTSTARCOM_VENDOR_ID, PANTECH_PRODUCT_UML290_VZW, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(UTSTARCOM_VENDOR_ID, PANTECH_PRODUCT_UML190_VZW, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(UTSTARCOM_VENDOR_ID, PANTECH_PRODUCT_UML190_VZW, 0xff, 0xfe, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(UTSTARCOM_VENDOR_ID, PANTECH_PRODUCT_UML290_VZW, 0xff, 0xfd, 0xff) },  /* NMEA */
+       { USB_DEVICE_AND_INTERFACE_INFO(UTSTARCOM_VENDOR_ID, PANTECH_PRODUCT_UML290_VZW, 0xff, 0xfe, 0xff) },  /* WMC */
+       { USB_DEVICE_AND_INTERFACE_INFO(UTSTARCOM_VENDOR_ID, PANTECH_PRODUCT_UML290_VZW, 0xff, 0xff, 0xff) },  /* DIAG */
        { },
 };
 MODULE_DEVICE_TABLE(usb, id_table);
index 1d5deee..f98800f 100644 (file)
@@ -36,6 +36,11 @@ static const struct usb_device_id id_table[] = {
        {USB_DEVICE(0x413c, 0x8171)},   /* Dell Gobi QDL device */
        {USB_DEVICE(0x1410, 0xa001)},   /* Novatel Gobi Modem device */
        {USB_DEVICE(0x1410, 0xa008)},   /* Novatel Gobi QDL device */
+       {USB_DEVICE(0x1410, 0xa010)},   /* Novatel Gobi QDL device */
+       {USB_DEVICE(0x1410, 0xa011)},   /* Novatel Gobi QDL device */
+       {USB_DEVICE(0x1410, 0xa012)},   /* Novatel Gobi QDL device */
+       {USB_DEVICE(0x1410, 0xa013)},   /* Novatel Gobi QDL device */
+       {USB_DEVICE(0x1410, 0xa014)},   /* Novatel Gobi QDL device */
        {USB_DEVICE(0x0b05, 0x1776)},   /* Asus Gobi Modem device */
        {USB_DEVICE(0x0b05, 0x1774)},   /* Asus Gobi QDL device */
        {USB_DEVICE(0x19d2, 0xfff3)},   /* ONDA Gobi Modem device */
@@ -86,7 +91,16 @@ static const struct usb_device_id id_table[] = {
        {USB_DEVICE(0x16d8, 0x8002)},   /* CMDTech Gobi 2000 Modem device (VU922) */
        {USB_DEVICE(0x05c6, 0x9204)},   /* Gobi 2000 QDL device */
        {USB_DEVICE(0x05c6, 0x9205)},   /* Gobi 2000 Modem device */
+
+       {USB_DEVICE(0x05c6, 0x920c)},   /* Gobi 3000 QDL */
+       {USB_DEVICE(0x05c6, 0x920d)},   /* Gobi 3000 Composite */
+       {USB_DEVICE(0x1410, 0xa020)},   /* Novatel Gobi 3000 QDL */
+       {USB_DEVICE(0x1410, 0xa021)},   /* Novatel Gobi 3000 Composite */
+       {USB_DEVICE(0x413c, 0x8193)},   /* Dell Gobi 3000 QDL */
+       {USB_DEVICE(0x413c, 0x8194)},   /* Dell Gobi 3000 Composite */
        {USB_DEVICE(0x1199, 0x9013)},   /* Sierra Wireless Gobi 3000 Modem device (MC8355) */
+       {USB_DEVICE(0x12D1, 0x14F0)},   /* Sony Gobi 3000 QDL */
+       {USB_DEVICE(0x12D1, 0x14F1)},   /* Sony Gobi 3000 Composite */
        { }                             /* Terminating entry */
 };
 MODULE_DEVICE_TABLE(usb, id_table);
@@ -123,8 +137,6 @@ static int qcprobe(struct usb_serial *serial, const struct usb_device_id *id)
 
        spin_lock_init(&data->susp_lock);
 
-       usb_enable_autosuspend(serial->dev);
-
        switch (nintf) {
        case 1:
                /* QDL mode */
index 1f62723..d32f720 100644 (file)
@@ -789,7 +789,7 @@ static void rts51x_suspend_timer_fn(unsigned long data)
                        rts51x_set_stat(chip, RTS51X_STAT_SS);
                        /* ignore mass storage interface's children */
                        pm_suspend_ignore_children(&us->pusb_intf->dev, true);
-                       usb_autopm_put_interface(us->pusb_intf);
+                       usb_autopm_put_interface_async(us->pusb_intf);
                        US_DEBUGP("%s: RTS51X_STAT_SS 01,"
                                "intf->pm_usage_cnt:%d, power.usage:%d\n",
                                __func__,
index 8efeae2..b4a7167 100644 (file)
@@ -27,8 +27,6 @@
 #define USB_SKEL_VENDOR_ID     0xfff0
 #define USB_SKEL_PRODUCT_ID    0xfff0
 
-static DEFINE_MUTEX(skel_mutex);
-
 /* table of devices that work with this driver */
 static const struct usb_device_id skel_table[] = {
        { USB_DEVICE(USB_SKEL_VENDOR_ID, USB_SKEL_PRODUCT_ID) },
@@ -101,25 +99,18 @@ static int skel_open(struct inode *inode, struct file *file)
                goto exit;
        }
 
-       mutex_lock(&skel_mutex);
        dev = usb_get_intfdata(interface);
        if (!dev) {
-               mutex_unlock(&skel_mutex);
                retval = -ENODEV;
                goto exit;
        }
 
        /* increment our usage count for the device */
        kref_get(&dev->kref);
-       mutex_unlock(&skel_mutex);
 
        /* lock the device to allow correctly handling errors
         * in resumption */
        mutex_lock(&dev->io_mutex);
-       if (!dev->interface) {
-               retval = -ENODEV;
-               goto out_err;
-       }
 
        retval = usb_autopm_get_interface(interface);
        if (retval)
@@ -127,11 +118,7 @@ static int skel_open(struct inode *inode, struct file *file)
 
        /* save our object in the file's private structure */
        file->private_data = dev;
-
-out_err:
        mutex_unlock(&dev->io_mutex);
-       if (retval)
-               kref_put(&dev->kref, skel_delete);
 
 exit:
        return retval;
@@ -611,6 +598,7 @@ static void skel_disconnect(struct usb_interface *interface)
        int minor = interface->minor;
 
        dev = usb_get_intfdata(interface);
+       usb_set_intfdata(interface, NULL);
 
        /* give back our minor */
        usb_deregister_dev(interface, &skel_class);
@@ -622,12 +610,8 @@ static void skel_disconnect(struct usb_interface *interface)
 
        usb_kill_anchored_urbs(&dev->submitted);
 
-       mutex_lock(&skel_mutex);
-       usb_set_intfdata(interface, NULL);
-
        /* decrement our usage count */
        kref_put(&dev->kref, skel_delete);
-       mutex_unlock(&skel_mutex);
 
        dev_info(&interface->dev, "USB Skeleton #%d now disconnected", minor);
 }
index 0ead882..f29fdd7 100644 (file)
@@ -6,7 +6,7 @@ config USB_WUSB
        depends on EXPERIMENTAL
        depends on USB
        depends on PCI
-        select UWB
+       depends on UWB
         select CRYPTO
         select CRYPTO_BLKCIPHER
         select CRYPTO_CBC
index 0d7b20d..e40c00f 100644 (file)
@@ -1108,7 +1108,7 @@ static int atmel_lcdfb_suspend(struct platform_device *pdev, pm_message_t mesg)
         */
        lcdc_writel(sinfo, ATMEL_LCDC_IDR, ~0UL);
 
-       sinfo->saved_lcdcon = lcdc_readl(sinfo, ATMEL_LCDC_CONTRAST_VAL);
+       sinfo->saved_lcdcon = lcdc_readl(sinfo, ATMEL_LCDC_CONTRAST_CTR);
        lcdc_writel(sinfo, ATMEL_LCDC_CONTRAST_CTR, 0);
        if (sinfo->atmel_lcdfb_power_control)
                sinfo->atmel_lcdfb_power_control(0);
index acf292b..6af3f16 100644 (file)
@@ -1432,7 +1432,7 @@ static int fsl_diu_suspend(struct platform_device *ofdev, pm_message_t state)
        struct fsl_diu_data *data;
 
        data = dev_get_drvdata(&ofdev->dev);
-       disable_lcdc(data->fsl_diu_info[0]);
+       disable_lcdc(data->fsl_diu_info);
 
        return 0;
 }
@@ -1442,7 +1442,7 @@ static int fsl_diu_resume(struct platform_device *ofdev)
        struct fsl_diu_data *data;
 
        data = dev_get_drvdata(&ofdev->dev);
-       enable_lcdc(data->fsl_diu_info[0]);
+       enable_lcdc(data->fsl_diu_info);
 
        return 0;
 }
index c6afa33..02fd226 100644 (file)
@@ -529,7 +529,6 @@ static int __devinit intelfb_pci_register(struct pci_dev *pdev,
        if (fb_alloc_cmap(&info->cmap, 256, 1) < 0) {
                ERR_MSG("Could not allocate cmap for intelfb_info.\n");
                goto err_out_cmap;
-               return -ENODEV;
        }
 
        dinfo = info->par;
index a5ec7f3..e1626a1 100644 (file)
@@ -401,7 +401,7 @@ void dispc_runtime_put(void)
 
        DSSDBG("dispc_runtime_put\n");
 
-       r = pm_runtime_put(&dispc.pdev->dev);
+       r = pm_runtime_put_sync(&dispc.pdev->dev);
        WARN_ON(r < 0);
 }
 
index 395d658..faaf305 100644 (file)
@@ -180,6 +180,11 @@ int omapdss_dpi_display_enable(struct omap_dss_device *dssdev)
 {
        int r;
 
+       if (cpu_is_omap34xx() && !dpi.vdds_dsi_reg) {
+               DSSERR("no VDSS_DSI regulator\n");
+               return -ENODEV;
+       }
+
        if (dssdev->manager == NULL) {
                DSSERR("failed to enable display: no manager\n");
                return -ENODEV;
index d4d676c..52f36ec 100644 (file)
@@ -1079,7 +1079,7 @@ void dsi_runtime_put(struct platform_device *dsidev)
 
        DSSDBG("dsi_runtime_put\n");
 
-       r = pm_runtime_put(&dsi->pdev->dev);
+       r = pm_runtime_put_sync(&dsi->pdev->dev);
        WARN_ON(r < 0);
 }
 
index 1703345..77c2b5a 100644 (file)
@@ -720,7 +720,7 @@ void dss_runtime_put(void)
 
        DSSDBG("dss_runtime_put\n");
 
-       r = pm_runtime_put(&dss.pdev->dev);
+       r = pm_runtime_put_sync(&dss.pdev->dev);
        WARN_ON(r < 0);
 }
 
index b4c270e..d7aa3b0 100644 (file)
@@ -176,7 +176,7 @@ static void hdmi_runtime_put(void)
 
        DSSDBG("hdmi_runtime_put\n");
 
-       r = pm_runtime_put(&hdmi.pdev->dev);
+       r = pm_runtime_put_sync(&hdmi.pdev->dev);
        WARN_ON(r < 0);
 }
 
@@ -497,6 +497,7 @@ bool omapdss_hdmi_detect(void)
 
 int omapdss_hdmi_display_enable(struct omap_dss_device *dssdev)
 {
+       struct omap_dss_hdmi_data *priv = dssdev->data;
        int r = 0;
 
        DSSDBG("ENTER hdmi_display_enable\n");
@@ -509,6 +510,8 @@ int omapdss_hdmi_display_enable(struct omap_dss_device *dssdev)
                goto err0;
        }
 
+       hdmi.ip_data.hpd_gpio = priv->hpd_gpio;
+
        r = omap_dss_start_device(dssdev);
        if (r) {
                DSSERR("failed to start device\n");
index 814bb95..55f3980 100644 (file)
@@ -140,7 +140,7 @@ static void rfbi_runtime_put(void)
 
        DSSDBG("rfbi_runtime_put\n");
 
-       r = pm_runtime_put(&rfbi.pdev->dev);
+       r = pm_runtime_put_sync(&rfbi.pdev->dev);
        WARN_ON(r < 0);
 }
 
index 7503f7f..50dadba 100644 (file)
@@ -126,6 +126,10 @@ struct hdmi_ip_data {
        const struct ti_hdmi_ip_ops *ops;
        struct hdmi_config cfg;
        struct hdmi_pll_info pll_data;
+
+       /* ti_hdmi_4xxx_ip private data. These should be in a separate struct */
+       int hpd_gpio;
+       bool phy_tx_enabled;
 };
 int ti_hdmi_4xxx_phy_enable(struct hdmi_ip_data *ip_data);
 void ti_hdmi_4xxx_phy_disable(struct hdmi_ip_data *ip_data);
index 9af81f1..2d72334 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/delay.h>
 #include <linux/string.h>
 #include <linux/seq_file.h>
+#include <linux/gpio.h>
 
 #include "ti_hdmi_4xxx_ip.h"
 #include "dss.h"
@@ -223,6 +224,49 @@ void ti_hdmi_4xxx_pll_disable(struct hdmi_ip_data *ip_data)
        hdmi_set_pll_pwr(ip_data, HDMI_PLLPWRCMD_ALLOFF);
 }
 
+static int hdmi_check_hpd_state(struct hdmi_ip_data *ip_data)
+{
+       unsigned long flags;
+       bool hpd;
+       int r;
+       /* this should be in ti_hdmi_4xxx_ip private data */
+       static DEFINE_SPINLOCK(phy_tx_lock);
+
+       spin_lock_irqsave(&phy_tx_lock, flags);
+
+       hpd = gpio_get_value(ip_data->hpd_gpio);
+
+       if (hpd == ip_data->phy_tx_enabled) {
+               spin_unlock_irqrestore(&phy_tx_lock, flags);
+               return 0;
+       }
+
+       if (hpd)
+               r = hdmi_set_phy_pwr(ip_data, HDMI_PHYPWRCMD_TXON);
+       else
+               r = hdmi_set_phy_pwr(ip_data, HDMI_PHYPWRCMD_LDOON);
+
+       if (r) {
+               DSSERR("Failed to %s PHY TX power\n",
+                               hpd ? "enable" : "disable");
+               goto err;
+       }
+
+       ip_data->phy_tx_enabled = hpd;
+err:
+       spin_unlock_irqrestore(&phy_tx_lock, flags);
+       return r;
+}
+
+static irqreturn_t hpd_irq_handler(int irq, void *data)
+{
+       struct hdmi_ip_data *ip_data = data;
+
+       hdmi_check_hpd_state(ip_data);
+
+       return IRQ_HANDLED;
+}
+
 int ti_hdmi_4xxx_phy_enable(struct hdmi_ip_data *ip_data)
 {
        u16 r = 0;
@@ -232,10 +276,6 @@ int ti_hdmi_4xxx_phy_enable(struct hdmi_ip_data *ip_data)
        if (r)
                return r;
 
-       r = hdmi_set_phy_pwr(ip_data, HDMI_PHYPWRCMD_TXON);
-       if (r)
-               return r;
-
        /*
         * Read address 0 in order to get the SCP reset done completed
         * Dummy access performed to make sure reset is done
@@ -257,12 +297,32 @@ int ti_hdmi_4xxx_phy_enable(struct hdmi_ip_data *ip_data)
        /* Write to phy address 3 to change the polarity control */
        REG_FLD_MOD(phy_base, HDMI_TXPHY_PAD_CFG_CTRL, 0x1, 27, 27);
 
+       r = request_threaded_irq(gpio_to_irq(ip_data->hpd_gpio),
+                       NULL, hpd_irq_handler,
+                       IRQF_DISABLED | IRQF_TRIGGER_RISING |
+                       IRQF_TRIGGER_FALLING, "hpd", ip_data);
+       if (r) {
+               DSSERR("HPD IRQ request failed\n");
+               hdmi_set_phy_pwr(ip_data, HDMI_PHYPWRCMD_OFF);
+               return r;
+       }
+
+       r = hdmi_check_hpd_state(ip_data);
+       if (r) {
+               free_irq(gpio_to_irq(ip_data->hpd_gpio), ip_data);
+               hdmi_set_phy_pwr(ip_data, HDMI_PHYPWRCMD_OFF);
+               return r;
+       }
+
        return 0;
 }
 
 void ti_hdmi_4xxx_phy_disable(struct hdmi_ip_data *ip_data)
 {
+       free_irq(gpio_to_irq(ip_data->hpd_gpio), ip_data);
+
        hdmi_set_phy_pwr(ip_data, HDMI_PHYPWRCMD_OFF);
+       ip_data->phy_tx_enabled = false;
 }
 
 static int hdmi_core_ddc_init(struct hdmi_ip_data *ip_data)
index b3e9f90..5c3d0f9 100644 (file)
@@ -401,7 +401,7 @@ static void venc_runtime_put(void)
 
        DSSDBG("venc_runtime_put\n");
 
-       r = pm_runtime_put(&venc.pdev->dev);
+       r = pm_runtime_put_sync(&venc.pdev->dev);
        WARN_ON(r < 0);
 }
 
index 79e1b29..5aa43c3 100644 (file)
@@ -35,7 +35,7 @@
 #define virtio_rmb(vq) \
        do { if ((vq)->weak_barriers) smp_rmb(); else rmb(); } while(0)
 #define virtio_wmb(vq) \
-       do { if ((vq)->weak_barriers) smp_rmb(); else rmb(); } while(0)
+       do { if ((vq)->weak_barriers) smp_wmb(); else wmb(); } while(0)
 #else
 /* We must force memory ordering even if guest is UP since host could be
  * running on another CPU, but SMP barriers are defined to barrier() in that
@@ -308,9 +308,9 @@ bool virtqueue_kick_prepare(struct virtqueue *_vq)
        bool needs_kick;
 
        START_USE(vq);
-       /* Descriptors and available array need to be set before we expose the
-        * new available array entries. */
-       virtio_wmb(vq);
+       /* We need to expose available array entries before checking avail
+        * event. */
+       virtio_mb(vq);
 
        old = vq->vring.avail->idx - vq->num_added;
        new = vq->vring.avail->idx;
index 1b0e3dd..63d7b58 100644 (file)
@@ -300,11 +300,7 @@ static int __devinit dw_wdt_drv_probe(struct platform_device *pdev)
        if (!mem)
                return -EINVAL;
 
-       if (!devm_request_mem_region(&pdev->dev, mem->start, resource_size(mem),
-                                    "dw_wdt"))
-               return -ENOMEM;
-
-       dw_wdt.regs = devm_ioremap(&pdev->dev, mem->start, resource_size(mem));
+       dw_wdt.regs = devm_request_and_ioremap(&pdev->dev, mem);
        if (!dw_wdt.regs)
                return -ENOMEM;
 
index 99796c5..bdf401b 100644 (file)
@@ -36,6 +36,7 @@
  *     document number TBD                   : Patsburg (PBG)
  *     document number TBD                   : DH89xxCC
  *     document number TBD                   : Panther Point
+ *     document number TBD                   : Lynx Point
  */
 
 /*
@@ -126,6 +127,7 @@ enum iTCO_chipsets {
        TCO_PBG,        /* Patsburg */
        TCO_DH89XXCC,   /* DH89xxCC */
        TCO_PPT,        /* Panther Point */
+       TCO_LPT,        /* Lynx Point */
 };
 
 static struct {
@@ -189,6 +191,7 @@ static struct {
        {"Patsburg", 2},
        {"DH89xxCC", 2},
        {"Panther Point", 2},
+       {"Lynx Point", 2},
        {NULL, 0}
 };
 
@@ -331,6 +334,38 @@ static DEFINE_PCI_DEVICE_TABLE(iTCO_wdt_pci_tbl) = {
        { PCI_VDEVICE(INTEL, 0x1e5d), TCO_PPT},
        { PCI_VDEVICE(INTEL, 0x1e5e), TCO_PPT},
        { PCI_VDEVICE(INTEL, 0x1e5f), TCO_PPT},
+       { PCI_VDEVICE(INTEL, 0x8c40), TCO_LPT},
+       { PCI_VDEVICE(INTEL, 0x8c41), TCO_LPT},
+       { PCI_VDEVICE(INTEL, 0x8c42), TCO_LPT},
+       { PCI_VDEVICE(INTEL, 0x8c43), TCO_LPT},
+       { PCI_VDEVICE(INTEL, 0x8c44), TCO_LPT},
+       { PCI_VDEVICE(INTEL, 0x8c45), TCO_LPT},
+       { PCI_VDEVICE(INTEL, 0x8c46), TCO_LPT},
+       { PCI_VDEVICE(INTEL, 0x8c47), TCO_LPT},
+       { PCI_VDEVICE(INTEL, 0x8c48), TCO_LPT},
+       { PCI_VDEVICE(INTEL, 0x8c49), TCO_LPT},
+       { PCI_VDEVICE(INTEL, 0x8c4a), TCO_LPT},
+       { PCI_VDEVICE(INTEL, 0x8c4b), TCO_LPT},
+       { PCI_VDEVICE(INTEL, 0x8c4c), TCO_LPT},
+       { PCI_VDEVICE(INTEL, 0x8c4d), TCO_LPT},
+       { PCI_VDEVICE(INTEL, 0x8c4e), TCO_LPT},
+       { PCI_VDEVICE(INTEL, 0x8c4f), TCO_LPT},
+       { PCI_VDEVICE(INTEL, 0x8c50), TCO_LPT},
+       { PCI_VDEVICE(INTEL, 0x8c51), TCO_LPT},
+       { PCI_VDEVICE(INTEL, 0x8c52), TCO_LPT},
+       { PCI_VDEVICE(INTEL, 0x8c53), TCO_LPT},
+       { PCI_VDEVICE(INTEL, 0x8c54), TCO_LPT},
+       { PCI_VDEVICE(INTEL, 0x8c55), TCO_LPT},
+       { PCI_VDEVICE(INTEL, 0x8c56), TCO_LPT},
+       { PCI_VDEVICE(INTEL, 0x8c57), TCO_LPT},
+       { PCI_VDEVICE(INTEL, 0x8c58), TCO_LPT},
+       { PCI_VDEVICE(INTEL, 0x8c59), TCO_LPT},
+       { PCI_VDEVICE(INTEL, 0x8c5a), TCO_LPT},
+       { PCI_VDEVICE(INTEL, 0x8c5b), TCO_LPT},
+       { PCI_VDEVICE(INTEL, 0x8c5c), TCO_LPT},
+       { PCI_VDEVICE(INTEL, 0x8c5d), TCO_LPT},
+       { PCI_VDEVICE(INTEL, 0x8c5e), TCO_LPT},
+       { PCI_VDEVICE(INTEL, 0x8c5f), TCO_LPT},
        { 0, },                 /* End of list */
 };
 MODULE_DEVICE_TABLE(pci, iTCO_wdt_pci_tbl);
index b8ef2c6..c44c333 100644 (file)
@@ -247,7 +247,6 @@ static struct miscdevice imx2_wdt_miscdev = {
 static int __init imx2_wdt_probe(struct platform_device *pdev)
 {
        int ret;
-       int res_size;
        struct resource *res;
 
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -256,15 +255,7 @@ static int __init imx2_wdt_probe(struct platform_device *pdev)
                return -ENODEV;
        }
 
-       res_size = resource_size(res);
-       if (!devm_request_mem_region(&pdev->dev, res->start, res_size,
-               res->name)) {
-               dev_err(&pdev->dev, "can't allocate %d bytes at %d address\n",
-                       res_size, res->start);
-               return -ENOMEM;
-       }
-
-       imx2_wdt.base = devm_ioremap_nocache(&pdev->dev, res->start, res_size);
+       imx2_wdt.base = devm_request_and_ioremap(&pdev->dev, res);
        if (!imx2_wdt.base) {
                dev_err(&pdev->dev, "ioremap failed\n");
                return -ENOMEM;
index 50359ba..529085b 100644 (file)
@@ -72,7 +72,7 @@ struct nuc900_wdt {
 };
 
 static unsigned long nuc900wdt_busy;
-struct nuc900_wdt *nuc900_wdt;
+static struct nuc900_wdt *nuc900_wdt;
 
 static inline void nuc900_wdt_keepalive(void)
 {
@@ -287,7 +287,8 @@ static int __devinit nuc900wdt_probe(struct platform_device *pdev)
 
        setup_timer(&nuc900_wdt->timer, nuc900_wdt_timer_ping, 0);
 
-       if (misc_register(&nuc900wdt_miscdev)) {
+       ret = misc_register(&nuc900wdt_miscdev);
+       if (ret) {
                dev_err(&pdev->dev, "err register miscdev on minor=%d (%d)\n",
                        WATCHDOG_MINOR, ret);
                goto err_clk;
index 4b33e3f..d19ff51 100644 (file)
@@ -339,6 +339,7 @@ static int __devinit omap_wdt_probe(struct platform_device *pdev)
        return 0;
 
 err_misc:
+       pm_runtime_disable(wdev->dev);
        platform_set_drvdata(pdev, NULL);
        iounmap(wdev->base);
 
@@ -371,6 +372,7 @@ static int __devexit omap_wdt_remove(struct platform_device *pdev)
        struct omap_wdt_dev *wdev = platform_get_drvdata(pdev);
        struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 
+       pm_runtime_disable(wdev->dev);
        if (!res)
                return -ENOENT;
 
index bd143c9..8e210aa 100644 (file)
@@ -226,7 +226,7 @@ static long pnx4008_wdt_ioctl(struct file *file, unsigned int cmd,
 static int pnx4008_wdt_release(struct inode *inode, struct file *file)
 {
        if (!test_bit(WDT_OK_TO_CLOSE, &wdt_status))
-               printk(KERN_WARNING "WATCHDOG: Device closed unexpectdly\n");
+               printk(KERN_WARNING "WATCHDOG: Device closed unexpectedly\n");
 
        wdt_disable();
        clk_disable(wdt_clk);
index 4c2a4e8..e37d811 100644 (file)
@@ -174,7 +174,7 @@ static int stmp3xxx_wdt_release(struct inode *inode, struct file *file)
        if (!nowayout) {
                if (!test_bit(WDT_OK_TO_CLOSE, &wdt_status)) {
                        wdt_ping();
-                       pr_debug("%s: Device closed unexpectdly\n", __func__);
+                       pr_debug("%s: Device closed unexpectedly\n", __func__);
                        ret = -EINVAL;
                } else {
                        wdt_disable();
index 026b4bb..8f07dd4 100644 (file)
@@ -124,8 +124,6 @@ static int wdt_stop(struct watchdog_device *wdd)
 static int wdt_set_timeout(struct watchdog_device *wdd,
                           unsigned int new_timeout)
 {
-       if (new_timeout < 1 || new_timeout > WDT_TIMEOUT_MAX)
-               return -EINVAL;
        writel(new_timeout, wdt_mem + VIA_WDT_COUNT);
        timeout = new_timeout;
        return 0;
@@ -150,6 +148,8 @@ static const struct watchdog_ops wdt_ops = {
 static struct watchdog_device wdt_dev = {
        .info =         &wdt_info,
        .ops =          &wdt_ops,
+       .min_timeout =  1,
+       .max_timeout =  WDT_TIMEOUT_MAX,
 };
 
 static int __devinit wdt_probe(struct pci_dev *pdev,
@@ -233,7 +233,7 @@ static void __devexit wdt_remove(struct pci_dev *pdev)
        pci_disable_device(pdev);
 }
 
-DEFINE_PCI_DEVICE_TABLE(wdt_pci_table) = {
+static DEFINE_PCI_DEVICE_TABLE(wdt_pci_table) = {
        { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_CX700) },
        { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_VX800) },
        { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_VX855) },
index 42e940c..c3c3188 100644 (file)
@@ -152,12 +152,12 @@ static long wafwdt_ioctl(struct file *file, unsigned int cmd,
                        return -EFAULT;
 
                if (options & WDIOS_DISABLECARD) {
-                       wafwdt_start();
+                       wafwdt_stop();
                        retval = 0;
                }
 
                if (options & WDIOS_ENABLECARD) {
-                       wafwdt_stop();
+                       wafwdt_start();
                        retval = 0;
                }
 
index 909c786..5d7113c 100644 (file)
@@ -212,10 +212,10 @@ static long wm8350_wdt_ioctl(struct file *file, unsigned int cmd,
 
                /* Setting both simultaneously means at least one must fail */
                if (options == WDIOS_DISABLECARD)
-                       ret = wm8350_wdt_start(wm8350);
+                       ret = wm8350_wdt_stop(wm8350);
 
                if (options == WDIOS_ENABLECARD)
-                       ret = wm8350_wdt_stop(wm8350);
+                       ret = wm8350_wdt_start(wm8350);
                break;
        }
 
index 14e2d99..4dcfced 100644 (file)
@@ -30,7 +30,8 @@ static int vcpu_online(unsigned int cpu)
        sprintf(dir, "cpu/%u", cpu);
        err = xenbus_scanf(XBT_NIL, dir, "availability", "%s", state);
        if (err != 1) {
-               printk(KERN_ERR "XENBUS: Unable to read cpu state\n");
+               if (!xen_initial_domain())
+                       printk(KERN_ERR "XENBUS: Unable to read cpu state\n");
                return err;
        }
 
index 1cd94da..b4d4eac 100644 (file)
@@ -948,9 +948,12 @@ static void gnttab_request_version(void)
        int rc;
        struct gnttab_set_version gsv;
 
-       gsv.version = 2;
+       if (xen_hvm_domain())
+               gsv.version = 1;
+       else
+               gsv.version = 2;
        rc = HYPERVISOR_grant_table_op(GNTTABOP_set_version, &gsv, 1);
-       if (rc == 0) {
+       if (rc == 0 && gsv.version == 2) {
                grant_table_version = 2;
                gnttab_interface = &gnttab_v2_ops;
        } else if (grant_table_version == 2) {
index 7944a17..19834d1 100644 (file)
@@ -884,7 +884,7 @@ static inline int str_to_quirk(const char *buf, int *domain, int *bus, int
        int err;
 
        err =
-           sscanf(buf, " %04x:%02x:%02x.%1x-%08x:%1x:%08x", domain, bus, slot,
+           sscanf(buf, " %04x:%02x:%02x.%d-%08x:%1x:%08x", domain, bus, slot,
                   func, reg, size, mask);
        if (err == 7)
                return 0;
@@ -904,7 +904,7 @@ static int pcistub_device_id_add(int domain, int bus, int slot, int func)
        pci_dev_id->bus = bus;
        pci_dev_id->devfn = PCI_DEVFN(slot, func);
 
-       pr_debug(DRV_NAME ": wants to seize %04x:%02x:%02x.%01x\n",
+       pr_debug(DRV_NAME ": wants to seize %04x:%02x:%02x.%d\n",
                 domain, bus, slot, func);
 
        spin_lock_irqsave(&device_ids_lock, flags);
@@ -934,7 +934,7 @@ static int pcistub_device_id_remove(int domain, int bus, int slot, int func)
 
                        err = 0;
 
-                       pr_debug(DRV_NAME ": removed %04x:%02x:%02x.%01x from "
+                       pr_debug(DRV_NAME ": removed %04x:%02x:%02x.%d from "
                                 "seize list\n", domain, bus, slot, func);
                }
        }
@@ -1029,7 +1029,7 @@ static ssize_t pcistub_slot_show(struct device_driver *drv, char *buf)
                        break;
 
                count += scnprintf(buf + count, PAGE_SIZE - count,
-                                  "%04x:%02x:%02x.%01x\n",
+                                  "%04x:%02x:%02x.%d\n",
                                   pci_dev_id->domain, pci_dev_id->bus,
                                   PCI_SLOT(pci_dev_id->devfn),
                                   PCI_FUNC(pci_dev_id->devfn));
index d5dcf8d..64b11f9 100644 (file)
@@ -206,6 +206,7 @@ static int xen_pcibk_publish_pci_dev(struct xen_pcibk_device *pdev,
                goto out;
        }
 
+       /* Note: The PV protocol uses %02x, don't change it */
        err = xenbus_printf(XBT_NIL, pdev->xdev->nodename, str,
                            "%04x:%02x:%02x.%02x", domain, bus,
                            PCI_SLOT(devfn), PCI_FUNC(devfn));
@@ -229,7 +230,7 @@ static int xen_pcibk_export_device(struct xen_pcibk_device *pdev,
                err = -EINVAL;
                xenbus_dev_fatal(pdev->xdev, err,
                                 "Couldn't locate PCI device "
-                                "(%04x:%02x:%02x.%01x)! "
+                                "(%04x:%02x:%02x.%d)! "
                                 "perhaps already in-use?",
                                 domain, bus, slot, func);
                goto out;
@@ -274,7 +275,7 @@ static int xen_pcibk_remove_device(struct xen_pcibk_device *pdev,
        if (!dev) {
                err = -EINVAL;
                dev_dbg(&pdev->xdev->dev, "Couldn't locate PCI device "
-                       "(%04x:%02x:%02x.%01x)! not owned by this domain\n",
+                       "(%04x:%02x:%02x.%d)! not owned by this domain\n",
                        domain, bus, slot, func);
                goto out;
        }
index 527dc2a..89f7625 100644 (file)
@@ -369,6 +369,10 @@ static int xenbus_write_watch(unsigned msg_type, struct xenbus_file_priv *u)
                goto out;
        }
        token++;
+       if (memchr(token, 0, u->u.msg.len - (token - path)) == NULL) {
+               rc = -EILSEQ;
+               goto out;
+       }
 
        if (msg_type == XS_WATCH) {
                watch = alloc_watch_adapter(path, token);
index b1fe82c..b980ecd 100644 (file)
--- a/fs/bio.c
+++ b/fs/bio.c
@@ -505,13 +505,9 @@ EXPORT_SYMBOL(bio_clone);
 int bio_get_nr_vecs(struct block_device *bdev)
 {
        struct request_queue *q = bdev_get_queue(bdev);
-       int nr_pages;
-
-       nr_pages = ((queue_max_sectors(q) << 9) + PAGE_SIZE - 1) >> PAGE_SHIFT;
-       if (nr_pages > queue_max_segments(q))
-               nr_pages = queue_max_segments(q);
-
-       return nr_pages;
+       return min_t(unsigned,
+                    queue_max_segments(q),
+                    queue_max_sectors(q) / (PAGE_SIZE >> 9) + 1);
 }
 EXPORT_SYMBOL(bio_get_nr_vecs);
 
index b9a8432..633c701 100644 (file)
@@ -297,7 +297,7 @@ static int __add_delayed_refs(struct btrfs_delayed_ref_head *head, u64 seq,
        struct btrfs_delayed_extent_op *extent_op = head->extent_op;
        struct rb_node *n = &head->node.rb_node;
        int sgn;
-       int ret;
+       int ret = 0;
 
        if (extent_op && extent_op->update_key)
                btrfs_disk_key_to_cpu(info_key, &extent_op->key);
@@ -392,7 +392,7 @@ static int __add_inline_refs(struct btrfs_fs_info *fs_info,
                             struct btrfs_key *info_key, int *info_level,
                             struct list_head *prefs)
 {
-       int ret;
+       int ret = 0;
        int slot;
        struct extent_buffer *leaf;
        struct btrfs_key key;
index ad0b3ba..b669a7d 100644 (file)
@@ -1662,7 +1662,7 @@ static void btrfsic_process_written_block(struct btrfsic_dev_state *dev_state,
        block = btrfsic_block_hashtable_lookup(bdev, dev_bytenr,
                                               &state->block_hashtable);
        if (NULL != block) {
-               u64 bytenr;
+               u64 bytenr = 0;
                struct list_head *elem_ref_to;
                struct list_head *tmp_ref_to;
 
@@ -2777,9 +2777,10 @@ int btrfsic_submit_bh(int rw, struct buffer_head *bh)
                        printk(KERN_INFO
                               "submit_bh(rw=0x%x, blocknr=%lu (bytenr %llu),"
                               " size=%lu, data=%p, bdev=%p)\n",
-                              rw, bh->b_blocknr,
-                              (unsigned long long)dev_bytenr, bh->b_size,
-                              bh->b_data, bh->b_bdev);
+                              rw, (unsigned long)bh->b_blocknr,
+                              (unsigned long long)dev_bytenr,
+                              (unsigned long)bh->b_size, bh->b_data,
+                              bh->b_bdev);
                btrfsic_process_written_block(dev_state, dev_bytenr,
                                              bh->b_data, bh->b_size, NULL,
                                              NULL, bh, rw);
@@ -2844,7 +2845,7 @@ void btrfsic_submit_bio(int rw, struct bio *bio)
                        printk(KERN_INFO
                               "submit_bio(rw=0x%x, bi_vcnt=%u,"
                               " bi_sector=%lu (bytenr %llu), bi_bdev=%p)\n",
-                              rw, bio->bi_vcnt, bio->bi_sector,
+                              rw, bio->bi_vcnt, (unsigned long)bio->bi_sector,
                               (unsigned long long)dev_bytenr,
                               bio->bi_bdev);
 
index 7aa9cd3..811d9f9 100644 (file)
@@ -962,6 +962,13 @@ static int btree_releasepage(struct page *page, gfp_t gfp_flags)
        tree = &BTRFS_I(page->mapping->host)->io_tree;
        map = &BTRFS_I(page->mapping->host)->extent_tree;
 
+       /*
+        * We need to mask out eg. __GFP_HIGHMEM and __GFP_DMA32 as we're doing
+        * slab allocation from alloc_extent_state down the callchain where
+        * it'd hit a BUG_ON as those flags are not allowed.
+        */
+       gfp_flags &= ~GFP_SLAB_BUG_MASK;
+
        ret = try_release_extent_state(map, tree, page, gfp_flags);
        if (!ret)
                return 0;
index 700879e..283af7a 100644 (file)
 #include "locking.h"
 #include "free-space-cache.h"
 
-/* control flags for do_chunk_alloc's force field
+/*
+ * control flags for do_chunk_alloc's force field
  * CHUNK_ALLOC_NO_FORCE means to only allocate a chunk
  * if we really need one.
  *
- * CHUNK_ALLOC_FORCE means it must try to allocate one
- *
  * CHUNK_ALLOC_LIMITED means to only try and allocate one
  * if we have very few chunks already allocated.  This is
  * used as part of the clustering code to help make sure
  * we have a good pool of storage to cluster in, without
  * filling the FS with empty chunks
  *
+ * CHUNK_ALLOC_FORCE means it must try to allocate one
+ *
  */
 enum {
        CHUNK_ALLOC_NO_FORCE = 0,
-       CHUNK_ALLOC_FORCE = 1,
-       CHUNK_ALLOC_LIMITED = 2,
+       CHUNK_ALLOC_LIMITED = 1,
+       CHUNK_ALLOC_FORCE = 2,
 };
 
 /*
@@ -3414,7 +3415,7 @@ static int do_chunk_alloc(struct btrfs_trans_handle *trans,
 
 again:
        spin_lock(&space_info->lock);
-       if (space_info->force_alloc)
+       if (force < space_info->force_alloc)
                force = space_info->force_alloc;
        if (space_info->full) {
                spin_unlock(&space_info->lock);
@@ -5794,6 +5795,7 @@ int btrfs_reserve_extent(struct btrfs_trans_handle *trans,
                         u64 search_end, struct btrfs_key *ins,
                         u64 data)
 {
+       bool final_tried = false;
        int ret;
        u64 search_start = 0;
 
@@ -5813,22 +5815,25 @@ again:
                               search_start, search_end, hint_byte,
                               ins, data);
 
-       if (ret == -ENOSPC && num_bytes > min_alloc_size) {
-               num_bytes = num_bytes >> 1;
-               num_bytes = num_bytes & ~(root->sectorsize - 1);
-               num_bytes = max(num_bytes, min_alloc_size);
-               do_chunk_alloc(trans, root->fs_info->extent_root,
-                              num_bytes, data, CHUNK_ALLOC_FORCE);
-               goto again;
-       }
-       if (ret == -ENOSPC && btrfs_test_opt(root, ENOSPC_DEBUG)) {
-               struct btrfs_space_info *sinfo;
-
-               sinfo = __find_space_info(root->fs_info, data);
-               printk(KERN_ERR "btrfs allocation failed flags %llu, "
-                      "wanted %llu\n", (unsigned long long)data,
-                      (unsigned long long)num_bytes);
-               dump_space_info(sinfo, num_bytes, 1);
+       if (ret == -ENOSPC) {
+               if (!final_tried) {
+                       num_bytes = num_bytes >> 1;
+                       num_bytes = num_bytes & ~(root->sectorsize - 1);
+                       num_bytes = max(num_bytes, min_alloc_size);
+                       do_chunk_alloc(trans, root->fs_info->extent_root,
+                                      num_bytes, data, CHUNK_ALLOC_FORCE);
+                       if (num_bytes == min_alloc_size)
+                               final_tried = true;
+                       goto again;
+               } else if (btrfs_test_opt(root, ENOSPC_DEBUG)) {
+                       struct btrfs_space_info *sinfo;
+
+                       sinfo = __find_space_info(root->fs_info, data);
+                       printk(KERN_ERR "btrfs allocation failed flags %llu, "
+                              "wanted %llu\n", (unsigned long long)data,
+                              (unsigned long long)num_bytes);
+                       dump_space_info(sinfo, num_bytes, 1);
+               }
        }
 
        trace_btrfs_reserved_extent_alloc(root, ins->objectid, ins->offset);
index 9d09a4f..fcf77e1 100644 (file)
@@ -3909,6 +3909,8 @@ int extent_range_uptodate(struct extent_io_tree *tree,
        while (start <= end) {
                index = start >> PAGE_CACHE_SHIFT;
                page = find_get_page(tree->mapping, index);
+               if (!page)
+                       return 1;
                uptodate = PageUptodate(page);
                page_cache_release(page);
                if (!uptodate) {
index d20ff87..c2f2059 100644 (file)
@@ -2242,7 +2242,7 @@ u64 btrfs_alloc_from_cluster(struct btrfs_block_group_cache *block_group,
                if (entry->bitmap) {
                        ret = btrfs_alloc_from_bitmap(block_group,
                                                      cluster, entry, bytes,
-                                                     min_start);
+                                                     cluster->window_start);
                        if (ret == 0) {
                                node = rb_next(&entry->offset_index);
                                if (!node)
@@ -2251,6 +2251,7 @@ u64 btrfs_alloc_from_cluster(struct btrfs_block_group_cache *block_group,
                                                 offset_index);
                                continue;
                        }
+                       cluster->window_start += bytes;
                } else {
                        ret = entry->offset;
 
@@ -2475,7 +2476,7 @@ setup_cluster_bitmap(struct btrfs_block_group_cache *block_group,
        }
 
        list_for_each_entry(entry, bitmaps, list) {
-               if (entry->bytes < min_bytes)
+               if (entry->bytes < bytes)
                        continue;
                ret = btrfs_bitmap_cluster(block_group, entry, cluster, offset,
                                           bytes, cont1_bytes, min_bytes);
index 0da19a0..32214fe 100644 (file)
@@ -6401,18 +6401,23 @@ int btrfs_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
        unsigned long zero_start;
        loff_t size;
        int ret;
+       int reserved = 0;
        u64 page_start;
        u64 page_end;
 
        ret  = btrfs_delalloc_reserve_space(inode, PAGE_CACHE_SIZE);
-       if (!ret)
+       if (!ret) {
                ret = btrfs_update_time(vma->vm_file);
+               reserved = 1;
+       }
        if (ret) {
                if (ret == -ENOMEM)
                        ret = VM_FAULT_OOM;
                else /* -ENOSPC, -EIO, etc */
                        ret = VM_FAULT_SIGBUS;
-               goto out;
+               if (reserved)
+                       goto out;
+               goto out_noreserve;
        }
 
        ret = VM_FAULT_NOPAGE; /* make the VM retry the fault */
@@ -6495,6 +6500,7 @@ out_unlock:
        unlock_page(page);
 out:
        btrfs_delalloc_release_space(inode, PAGE_CACHE_SIZE);
+out_noreserve:
        return ret;
 }
 
index ab62001..03bb62a 100644 (file)
@@ -1065,7 +1065,7 @@ int btrfs_defrag_file(struct inode *inode, struct file *file,
                i = range->start >> PAGE_CACHE_SHIFT;
        }
        if (!max_to_defrag)
-               max_to_defrag = last_index;
+               max_to_defrag = last_index + 1;
 
        /*
         * make writeback starts from i, so the defrag range can be
index cb877e0..966cc74 100644 (file)
@@ -1957,7 +1957,8 @@ static int wait_log_commit(struct btrfs_trans_handle *trans,
 
                finish_wait(&root->log_commit_wait[index], &wait);
                mutex_lock(&root->log_mutex);
-       } while (root->log_transid < transid + 2 &&
+       } while (root->fs_info->last_trans_log_full_commit !=
+                trans->transid && root->log_transid < transid + 2 &&
                 atomic_read(&root->log_commit[index]));
        return 0;
 }
@@ -1966,7 +1967,8 @@ static int wait_for_writer(struct btrfs_trans_handle *trans,
                           struct btrfs_root *root)
 {
        DEFINE_WAIT(wait);
-       while (atomic_read(&root->log_writers)) {
+       while (root->fs_info->last_trans_log_full_commit !=
+              trans->transid && atomic_read(&root->log_writers)) {
                prepare_to_wait(&root->log_writer_wait,
                                &wait, TASK_UNINTERRUPTIBLE);
                mutex_unlock(&root->log_mutex);
index b60fc8b..620daad 100644 (file)
@@ -641,10 +641,10 @@ static int __cap_is_valid(struct ceph_cap *cap)
        unsigned long ttl;
        u32 gen;
 
-       spin_lock(&cap->session->s_cap_lock);
+       spin_lock(&cap->session->s_gen_ttl_lock);
        gen = cap->session->s_cap_gen;
        ttl = cap->session->s_cap_ttl;
-       spin_unlock(&cap->session->s_cap_lock);
+       spin_unlock(&cap->session->s_gen_ttl_lock);
 
        if (cap->cap_gen < gen || time_after_eq(jiffies, ttl)) {
                dout("__cap_is_valid %p cap %p issued %s "
index 618246b..3e8094b 100644 (file)
@@ -975,10 +975,10 @@ static int dentry_lease_is_valid(struct dentry *dentry)
        di = ceph_dentry(dentry);
        if (di->lease_session) {
                s = di->lease_session;
-               spin_lock(&s->s_cap_lock);
+               spin_lock(&s->s_gen_ttl_lock);
                gen = s->s_cap_gen;
                ttl = s->s_cap_ttl;
-               spin_unlock(&s->s_cap_lock);
+               spin_unlock(&s->s_gen_ttl_lock);
 
                if (di->lease_gen == gen &&
                    time_before(jiffies, dentry->d_time) &&
index 23ab6a3..866e8d7 100644 (file)
@@ -262,6 +262,7 @@ static int parse_reply_info(struct ceph_msg *msg,
        /* trace */
        ceph_decode_32_safe(&p, end, len, bad);
        if (len > 0) {
+               ceph_decode_need(&p, end, len, bad);
                err = parse_reply_info_trace(&p, p+len, info, features);
                if (err < 0)
                        goto out_bad;
@@ -270,6 +271,7 @@ static int parse_reply_info(struct ceph_msg *msg,
        /* extra */
        ceph_decode_32_safe(&p, end, len, bad);
        if (len > 0) {
+               ceph_decode_need(&p, end, len, bad);
                err = parse_reply_info_extra(&p, p+len, info, features);
                if (err < 0)
                        goto out_bad;
@@ -398,9 +400,11 @@ static struct ceph_mds_session *register_session(struct ceph_mds_client *mdsc,
        s->s_con.peer_name.type = CEPH_ENTITY_TYPE_MDS;
        s->s_con.peer_name.num = cpu_to_le64(mds);
 
-       spin_lock_init(&s->s_cap_lock);
+       spin_lock_init(&s->s_gen_ttl_lock);
        s->s_cap_gen = 0;
        s->s_cap_ttl = 0;
+
+       spin_lock_init(&s->s_cap_lock);
        s->s_renew_requested = 0;
        s->s_renew_seq = 0;
        INIT_LIST_HEAD(&s->s_caps);
@@ -2326,10 +2330,10 @@ static void handle_session(struct ceph_mds_session *session,
        case CEPH_SESSION_STALE:
                pr_info("mds%d caps went stale, renewing\n",
                        session->s_mds);
-               spin_lock(&session->s_cap_lock);
+               spin_lock(&session->s_gen_ttl_lock);
                session->s_cap_gen++;
                session->s_cap_ttl = 0;
-               spin_unlock(&session->s_cap_lock);
+               spin_unlock(&session->s_gen_ttl_lock);
                send_renew_caps(mdsc, session);
                break;
 
index a50ca0e..8c7c04e 100644 (file)
@@ -117,10 +117,13 @@ struct ceph_mds_session {
        void             *s_authorizer_buf, *s_authorizer_reply_buf;
        size_t            s_authorizer_buf_len, s_authorizer_reply_buf_len;
 
-       /* protected by s_cap_lock */
-       spinlock_t        s_cap_lock;
+       /* protected by s_gen_ttl_lock */
+       spinlock_t        s_gen_ttl_lock;
        u32               s_cap_gen;  /* inc each time we get mds stale msg */
        unsigned long     s_cap_ttl;  /* when session caps expire */
+
+       /* protected by s_cap_lock */
+       spinlock_t        s_cap_lock;
        struct list_head  s_caps;     /* all caps issued by this session */
        int               s_nr_caps, s_trim_caps;
        int               s_num_cap_releases;
index 857214a..a76f697 100644 (file)
@@ -111,8 +111,10 @@ static size_t ceph_vxattrcb_layout(struct ceph_inode_info *ci, char *val,
 }
 
 static struct ceph_vxattr_cb ceph_file_vxattrs[] = {
+       { true, "ceph.file.layout", ceph_vxattrcb_layout},
+       /* The following extended attribute name is deprecated */
        { true, "ceph.layout", ceph_vxattrcb_layout},
-       { NULL, NULL }
+       { true, NULL, NULL }
 };
 
 static struct ceph_vxattr_cb *ceph_inode_vxattrs(struct inode *inode)
index 0554b00..2b243af 100644 (file)
@@ -139,7 +139,7 @@ config CIFS_DFS_UPCALL
            points. If unsure, say N.
 
 config CIFS_FSCACHE
-         bool "Provide CIFS client caching support (EXPERIMENTAL)"
+         bool "Provide CIFS client caching support"
          depends on CIFS=m && FSCACHE || CIFS=y && FSCACHE=y
          help
            Makes CIFS FS-Cache capable. Say Y here if you want your CIFS data
@@ -147,7 +147,7 @@ config CIFS_FSCACHE
            manager. If unsure, say N.
 
 config CIFS_ACL
-         bool "Provide CIFS ACL support (EXPERIMENTAL)"
+         bool "Provide CIFS ACL support"
          depends on CIFS_XATTR && KEYS
          help
            Allows to fetch CIFS/NTFS ACL from the server.  The DACL blob
index 986709a..602f77c 100644 (file)
@@ -773,10 +773,11 @@ standard_receive3(struct TCP_Server_Info *server, struct mid_q_entry *mid)
                cifs_dump_mem("Bad SMB: ", buf,
                        min_t(unsigned int, server->total_read, 48));
 
-       if (mid)
-               handle_mid(mid, server, smb_buffer, length);
+       if (!mid)
+               return length;
 
-       return length;
+       handle_mid(mid, server, smb_buffer, length);
+       return 0;
 }
 
 static int
@@ -2125,7 +2126,7 @@ cifs_set_cifscreds(struct smb_vol *vol, struct cifs_ses *ses)
        down_read(&key->sem);
        upayload = key->payload.data;
        if (IS_ERR_OR_NULL(upayload)) {
-               rc = PTR_ERR(key);
+               rc = upayload ? PTR_ERR(upayload) : -EINVAL;
                goto out_key_put;
        }
 
@@ -2142,14 +2143,14 @@ cifs_set_cifscreds(struct smb_vol *vol, struct cifs_ses *ses)
 
        len = delim - payload;
        if (len > MAX_USERNAME_SIZE || len <= 0) {
-               cFYI(1, "Bad value from username search (len=%ld)", len);
+               cFYI(1, "Bad value from username search (len=%zd)", len);
                rc = -EINVAL;
                goto out_key_put;
        }
 
        vol->username = kstrndup(payload, len, GFP_KERNEL);
        if (!vol->username) {
-               cFYI(1, "Unable to allocate %ld bytes for username", len);
+               cFYI(1, "Unable to allocate %zd bytes for username", len);
                rc = -ENOMEM;
                goto out_key_put;
        }
@@ -2157,7 +2158,7 @@ cifs_set_cifscreds(struct smb_vol *vol, struct cifs_ses *ses)
 
        len = key->datalen - (len + 1);
        if (len > MAX_PASSWORD_SIZE || len <= 0) {
-               cFYI(1, "Bad len for password search (len=%ld)", len);
+               cFYI(1, "Bad len for password search (len=%zd)", len);
                rc = -EINVAL;
                kfree(vol->username);
                vol->username = NULL;
@@ -2167,7 +2168,7 @@ cifs_set_cifscreds(struct smb_vol *vol, struct cifs_ses *ses)
        ++delim;
        vol->password = kstrndup(delim, len, GFP_KERNEL);
        if (!vol->password) {
-               cFYI(1, "Unable to allocate %ld bytes for password", len);
+               cFYI(1, "Unable to allocate %zd bytes for password", len);
                rc = -ENOMEM;
                kfree(vol->username);
                vol->username = NULL;
@@ -3857,10 +3858,8 @@ cifs_construct_tcon(struct cifs_sb_info *cifs_sb, uid_t fsuid)
        struct smb_vol *vol_info;
 
        vol_info = kzalloc(sizeof(*vol_info), GFP_KERNEL);
-       if (vol_info == NULL) {
-               tcon = ERR_PTR(-ENOMEM);
-               goto out;
-       }
+       if (vol_info == NULL)
+               return ERR_PTR(-ENOMEM);
 
        vol_info->local_nls = cifs_sb->local_nls;
        vol_info->linux_uid = fsuid;
index df8fecb..63a196b 100644 (file)
@@ -492,7 +492,7 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
 {
        int xid;
        int rc = 0; /* to get around spurious gcc warning, set to zero here */
-       __u32 oplock = 0;
+       __u32 oplock = enable_oplocks ? REQ_OPLOCK : 0;
        __u16 fileHandle = 0;
        bool posix_open = false;
        struct cifs_sb_info *cifs_sb;
index d85efad..551d0c2 100644 (file)
@@ -246,16 +246,15 @@ static void ascii_ssetup_strings(char **pbcc_area, struct cifs_ses *ses,
        /* copy user */
        /* BB what about null user mounts - check that we do this BB */
        /* copy user */
-       if (ses->user_name != NULL)
+       if (ses->user_name != NULL) {
                strncpy(bcc_ptr, ses->user_name, MAX_USERNAME_SIZE);
+               bcc_ptr += strnlen(ses->user_name, MAX_USERNAME_SIZE);
+       }
        /* else null user mount */
-
-       bcc_ptr += strnlen(ses->user_name, MAX_USERNAME_SIZE);
        *bcc_ptr = 0;
        bcc_ptr++; /* account for null termination */
 
        /* copy domain */
-
        if (ses->domainName != NULL) {
                strncpy(bcc_ptr, ses->domainName, 256);
                bcc_ptr += strnlen(ses->domainName, 256);
@@ -395,6 +394,10 @@ static int decode_ntlmssp_challenge(char *bcc_ptr, int blob_len,
        ses->ntlmssp->server_flags = le32_to_cpu(pblob->NegotiateFlags);
        tioffset = le32_to_cpu(pblob->TargetInfoArray.BufferOffset);
        tilen = le16_to_cpu(pblob->TargetInfoArray.Length);
+       if (tioffset > blob_len || tioffset + tilen > blob_len) {
+               cERROR(1, "tioffset + tilen too high %u + %u", tioffset, tilen);
+               return -EINVAL;
+       }
        if (tilen) {
                ses->auth_key.response = kmalloc(tilen, GFP_KERNEL);
                if (!ses->auth_key.response) {
index aeb135c..92ce83a 100644 (file)
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -1071,6 +1071,21 @@ void set_task_comm(struct task_struct *tsk, char *buf)
        perf_event_comm(tsk);
 }
 
+static void filename_to_taskname(char *tcomm, const char *fn, unsigned int len)
+{
+       int i, ch;
+
+       /* Copies the binary name from after last slash */
+       for (i = 0; (ch = *(fn++)) != '\0';) {
+               if (ch == '/')
+                       i = 0; /* overwrite what we wrote */
+               else
+                       if (i < len - 1)
+                               tcomm[i++] = ch;
+       }
+       tcomm[i] = '\0';
+}
+
 int flush_old_exec(struct linux_binprm * bprm)
 {
        int retval;
@@ -1085,6 +1100,7 @@ int flush_old_exec(struct linux_binprm * bprm)
 
        set_mm_exe_file(bprm->mm, bprm->file);
 
+       filename_to_taskname(bprm->tcomm, bprm->filename, sizeof(bprm->tcomm));
        /*
         * Release all of the old mmap stuff
         */
@@ -1116,10 +1132,6 @@ EXPORT_SYMBOL(would_dump);
 
 void setup_new_exec(struct linux_binprm * bprm)
 {
-       int i, ch;
-       const char *name;
-       char tcomm[sizeof(current->comm)];
-
        arch_pick_mmap_layout(current->mm);
 
        /* This is the point of no return */
@@ -1130,18 +1142,7 @@ void setup_new_exec(struct linux_binprm * bprm)
        else
                set_dumpable(current->mm, suid_dumpable);
 
-       name = bprm->filename;
-
-       /* Copies the binary name from after last slash */
-       for (i=0; (ch = *(name++)) != '\0';) {
-               if (ch == '/')
-                       i = 0; /* overwrite what we wrote */
-               else
-                       if (i < (sizeof(tcomm) - 1))
-                               tcomm[i++] = ch;
-       }
-       tcomm[i] = '\0';
-       set_task_comm(current, tcomm);
+       set_task_comm(current, bprm->tcomm);
 
        /* Set the new mm task size. We have to do that late because it may
         * depend on TIF_32BIT which is only updated in flush_thread() on
index f855916..5b4a936 100644 (file)
@@ -52,14 +52,6 @@ struct wb_writeback_work {
        struct completion *done;        /* set if the caller waits */
 };
 
-/*
- * Include the creation of the trace points after defining the
- * wb_writeback_work structure so that the definition remains local to this
- * file.
- */
-#define CREATE_TRACE_POINTS
-#include <trace/events/writeback.h>
-
 /*
  * We don't actually have pdflush, but this one is exported though /proc...
  */
@@ -92,6 +84,14 @@ static inline struct inode *wb_inode(struct list_head *head)
        return list_entry(head, struct inode, i_wb_list);
 }
 
+/*
+ * Include the creation of the trace points after defining the
+ * wb_writeback_work structure and inline functions so that the definition
+ * remains local to this file.
+ */
+#define CREATE_TRACE_POINTS
+#include <trace/events/writeback.h>
+
 /* Wakeup flusher thread or forker thread to fork it. Requires bdi->wb_lock. */
 static void bdi_wakeup_flusher(struct backing_dev_info *bdi)
 {
index f84b380..0f1b951 100644 (file)
@@ -51,7 +51,7 @@ int set_task_ioprio(struct task_struct *task, int ioprio)
        ioc = get_task_io_context(task, GFP_ATOMIC, NUMA_NO_NODE);
        if (ioc) {
                ioc_ioprio_changed(ioc, ioprio);
-               put_io_context(ioc, NULL);
+               put_io_context(ioc);
        }
 
        return err;
index a01cdad..eafb8d3 100644 (file)
@@ -335,7 +335,7 @@ static int jffs2_block_check_erase(struct jffs2_sb_info *c, struct jffs2_erasebl
        void *ebuf;
        uint32_t ofs;
        size_t retlen;
-       int ret = -EIO;
+       int ret;
        unsigned long *wordebuf;
 
        ret = mtd_point(c->mtd, jeb->offset, c->sector_size, &retlen,
index e97404d..9c50144 100644 (file)
@@ -152,9 +152,6 @@ static struct page *logfs_mtd_find_first_sb(struct super_block *sb, u64 *ofs)
        filler_t *filler = logfs_mtd_readpage;
        struct mtd_info *mtd = super->s_mtd;
 
-       if (!mtd_can_have_bb(mtd))
-               return NULL;
-
        *ofs = 0;
        while (mtd_block_isbad(mtd, *ofs)) {
                *ofs += mtd->erasesize;
@@ -172,9 +169,6 @@ static struct page *logfs_mtd_find_last_sb(struct super_block *sb, u64 *ofs)
        filler_t *filler = logfs_mtd_readpage;
        struct mtd_info *mtd = super->s_mtd;
 
-       if (!mtd_can_have_bb(mtd))
-               return NULL;
-
        *ofs = mtd->size - mtd->erasesize;
        while (mtd_block_isbad(mtd, *ofs)) {
                *ofs -= mtd->erasesize;
index 501043e..3de7a32 100644 (file)
@@ -71,7 +71,7 @@ static int write_dir(struct inode *dir, struct logfs_disk_dentry *dd,
 
 static int write_inode(struct inode *inode)
 {
-       return __logfs_write_inode(inode, WF_LOCK);
+       return __logfs_write_inode(inode, NULL, WF_LOCK);
 }
 
 static s64 dir_seek_data(struct inode *inode, s64 pos)
index b548c87..3886cde 100644 (file)
@@ -230,7 +230,9 @@ int logfs_fsync(struct file *file, loff_t start, loff_t end, int datasync)
                return ret;
 
        mutex_lock(&inode->i_mutex);
+       logfs_get_wblocks(sb, NULL, WF_LOCK);
        logfs_write_anchor(sb);
+       logfs_put_wblocks(sb, NULL, WF_LOCK);
        mutex_unlock(&inode->i_mutex);
 
        return 0;
index caa4419..d4efb06 100644 (file)
@@ -367,7 +367,7 @@ static struct gc_candidate *get_candidate(struct super_block *sb)
        int i, max_dist;
        struct gc_candidate *cand = NULL, *this;
 
-       max_dist = min(no_free_segments(sb), LOGFS_NO_AREAS);
+       max_dist = min(no_free_segments(sb), LOGFS_NO_AREAS - 1);
 
        for (i = max_dist; i >= 0; i--) {
                this = first_in_list(&super->s_low_list[i]);
index 388df1a..a422f42 100644 (file)
@@ -286,7 +286,7 @@ static int logfs_write_inode(struct inode *inode, struct writeback_control *wbc)
        if (logfs_inode(inode)->li_flags & LOGFS_IF_STILLBORN)
                return 0;
 
-       ret = __logfs_write_inode(inode, flags);
+       ret = __logfs_write_inode(inode, NULL, flags);
        LOGFS_BUG_ON(ret, inode->i_sb);
        return ret;
 }
@@ -363,7 +363,9 @@ static void logfs_init_once(void *_li)
 
 static int logfs_sync_fs(struct super_block *sb, int wait)
 {
+       logfs_get_wblocks(sb, NULL, WF_LOCK);
        logfs_write_anchor(sb);
+       logfs_put_wblocks(sb, NULL, WF_LOCK);
        return 0;
 }
 
index 9da2970..1e1c369 100644 (file)
@@ -612,7 +612,6 @@ static size_t __logfs_write_je(struct super_block *sb, void *buf, u16 type,
        if (len == 0)
                return logfs_write_header(super, header, 0, type);
 
-       BUG_ON(len > sb->s_blocksize);
        compr_len = logfs_compress(buf, data, len, sb->s_blocksize);
        if (compr_len < 0 || type == JE_ANCHOR) {
                memcpy(data, buf, len);
index 9263738..5f09376 100644 (file)
@@ -528,7 +528,7 @@ void logfs_destroy_inode_cache(void);
 void logfs_set_blocks(struct inode *inode, u64 no);
 /* these logically belong into inode.c but actually reside in readwrite.c */
 int logfs_read_inode(struct inode *inode);
-int __logfs_write_inode(struct inode *inode, long flags);
+int __logfs_write_inode(struct inode *inode, struct page *, long flags);
 void logfs_evict_inode(struct inode *inode);
 
 /* journal.c */
@@ -577,6 +577,8 @@ void initialize_block_counters(struct page *page, struct logfs_block *block,
                __be64 *array, int page_is_empty);
 int logfs_exist_block(struct inode *inode, u64 bix);
 int get_page_reserve(struct inode *inode, struct page *page);
+void logfs_get_wblocks(struct super_block *sb, struct page *page, int lock);
+void logfs_put_wblocks(struct super_block *sb, struct page *page, int lock);
 extern struct logfs_block_ops indirect_block_ops;
 
 /* segment.c */
@@ -594,6 +596,7 @@ int logfs_init_mapping(struct super_block *sb);
 void logfs_sync_area(struct logfs_area *area);
 void logfs_sync_segments(struct super_block *sb);
 void freeseg(struct super_block *sb, u32 segno);
+void free_areas(struct super_block *sb);
 
 /* area handling */
 int logfs_init_areas(struct super_block *sb);
index 2ac4217..4153e65 100644 (file)
@@ -244,8 +244,7 @@ static void preunlock_page(struct super_block *sb, struct page *page, int lock)
  * is waiting for s_write_mutex.  We annotate this fact by setting PG_pre_locked
  * in addition to PG_locked.
  */
-static void logfs_get_wblocks(struct super_block *sb, struct page *page,
-               int lock)
+void logfs_get_wblocks(struct super_block *sb, struct page *page, int lock)
 {
        struct logfs_super *super = logfs_super(sb);
 
@@ -260,8 +259,7 @@ static void logfs_get_wblocks(struct super_block *sb, struct page *page,
        }
 }
 
-static void logfs_put_wblocks(struct super_block *sb, struct page *page,
-               int lock)
+void logfs_put_wblocks(struct super_block *sb, struct page *page, int lock)
 {
        struct logfs_super *super = logfs_super(sb);
 
@@ -424,7 +422,7 @@ static void inode_write_block(struct logfs_block *block)
        if (inode->i_ino == LOGFS_INO_MASTER)
                logfs_write_anchor(inode->i_sb);
        else {
-               ret = __logfs_write_inode(inode, 0);
+               ret = __logfs_write_inode(inode, NULL, 0);
                /* see indirect_write_block comment */
                BUG_ON(ret);
        }
@@ -560,8 +558,13 @@ static void inode_free_block(struct super_block *sb, struct logfs_block *block)
 static void indirect_free_block(struct super_block *sb,
                struct logfs_block *block)
 {
-       ClearPagePrivate(block->page);
-       block->page->private = 0;
+       struct page *page = block->page;
+
+       if (PagePrivate(page)) {
+               ClearPagePrivate(page);
+               page_cache_release(page);
+               set_page_private(page, 0);
+       }
        __free_block(sb, block);
 }
 
@@ -650,8 +653,11 @@ static void alloc_data_block(struct inode *inode, struct page *page)
        logfs_unpack_index(page->index, &bix, &level);
        block = __alloc_block(inode->i_sb, inode->i_ino, bix, level);
        block->page = page;
+
        SetPagePrivate(page);
-       page->private = (unsigned long)block;
+       page_cache_get(page);
+       set_page_private(page, (unsigned long) block);
+
        block->ops = &indirect_block_ops;
 }
 
@@ -1570,11 +1576,15 @@ int logfs_write_buf(struct inode *inode, struct page *page, long flags)
 static int __logfs_delete(struct inode *inode, struct page *page)
 {
        long flags = WF_DELETE;
+       int err;
 
        inode->i_ctime = inode->i_mtime = CURRENT_TIME;
 
        if (page->index < I0_BLOCKS)
                return logfs_write_direct(inode, page, flags);
+       err = grow_inode(inode, page->index, 0);
+       if (err)
+               return err;
        return logfs_write_rec(inode, page, page->index, 0, flags);
 }
 
@@ -1623,7 +1633,7 @@ int logfs_rewrite_block(struct inode *inode, u64 bix, u64 ofs,
                        if (inode->i_ino == LOGFS_INO_MASTER)
                                logfs_write_anchor(inode->i_sb);
                        else {
-                               err = __logfs_write_inode(inode, flags);
+                               err = __logfs_write_inode(inode, page, flags);
                        }
                }
        }
@@ -1873,7 +1883,7 @@ int logfs_truncate(struct inode *inode, u64 target)
                logfs_get_wblocks(sb, NULL, 1);
                err = __logfs_truncate(inode, size);
                if (!err)
-                       err = __logfs_write_inode(inode, 0);
+                       err = __logfs_write_inode(inode, NULL, 0);
                logfs_put_wblocks(sb, NULL, 1);
        }
 
@@ -1901,8 +1911,11 @@ static void move_page_to_inode(struct inode *inode, struct page *page)
        li->li_block = block;
 
        block->page = NULL;
-       page->private = 0;
-       ClearPagePrivate(page);
+       if (PagePrivate(page)) {
+               ClearPagePrivate(page);
+               page_cache_release(page);
+               set_page_private(page, 0);
+       }
 }
 
 static void move_inode_to_page(struct page *page, struct inode *inode)
@@ -1918,8 +1931,12 @@ static void move_inode_to_page(struct page *page, struct inode *inode)
        BUG_ON(PagePrivate(page));
        block->ops = &indirect_block_ops;
        block->page = page;
-       page->private = (unsigned long)block;
-       SetPagePrivate(page);
+
+       if (!PagePrivate(page)) {
+               SetPagePrivate(page);
+               page_cache_get(page);
+               set_page_private(page, (unsigned long) block);
+       }
 
        block->inode = NULL;
        li->li_block = NULL;
@@ -2106,14 +2123,14 @@ void logfs_set_segment_unreserved(struct super_block *sb, u32 segno, u32 ec)
                        ec_level);
 }
 
-int __logfs_write_inode(struct inode *inode, long flags)
+int __logfs_write_inode(struct inode *inode, struct page *page, long flags)
 {
        struct super_block *sb = inode->i_sb;
        int ret;
 
-       logfs_get_wblocks(sb, NULL, flags & WF_LOCK);
+       logfs_get_wblocks(sb, page, flags & WF_LOCK);
        ret = do_write_inode(inode);
-       logfs_put_wblocks(sb, NULL, flags & WF_LOCK);
+       logfs_put_wblocks(sb, page, flags & WF_LOCK);
        return ret;
 }
 
index 9d51873..ab798ed 100644 (file)
@@ -86,7 +86,11 @@ int __logfs_buf_write(struct logfs_area *area, u64 ofs, void *buf, size_t len,
                BUG_ON(!page); /* FIXME: reserve a pool */
                SetPageUptodate(page);
                memcpy(page_address(page) + offset, buf, copylen);
-               SetPagePrivate(page);
+
+               if (!PagePrivate(page)) {
+                       SetPagePrivate(page);
+                       page_cache_get(page);
+               }
                page_cache_release(page);
 
                buf += copylen;
@@ -110,7 +114,10 @@ static void pad_partial_page(struct logfs_area *area)
                page = get_mapping_page(sb, index, 0);
                BUG_ON(!page); /* FIXME: reserve a pool */
                memset(page_address(page) + offset, 0xff, len);
-               SetPagePrivate(page);
+               if (!PagePrivate(page)) {
+                       SetPagePrivate(page);
+                       page_cache_get(page);
+               }
                page_cache_release(page);
        }
 }
@@ -130,7 +137,10 @@ static void pad_full_pages(struct logfs_area *area)
                BUG_ON(!page); /* FIXME: reserve a pool */
                SetPageUptodate(page);
                memset(page_address(page), 0xff, PAGE_CACHE_SIZE);
-               SetPagePrivate(page);
+               if (!PagePrivate(page)) {
+                       SetPagePrivate(page);
+                       page_cache_get(page);
+               }
                page_cache_release(page);
                index++;
                no_indizes--;
@@ -485,8 +495,12 @@ static void move_btree_to_page(struct inode *inode, struct page *page,
                mempool_free(item, super->s_alias_pool);
        }
        block->page = page;
-       SetPagePrivate(page);
-       page->private = (unsigned long)block;
+
+       if (!PagePrivate(page)) {
+               SetPagePrivate(page);
+               page_cache_get(page);
+               set_page_private(page, (unsigned long) block);
+       }
        block->ops = &indirect_block_ops;
        initialize_block_counters(page, block, data, 0);
 }
@@ -536,8 +550,12 @@ void move_page_to_btree(struct page *page)
                list_add(&item->list, &block->item_list);
        }
        block->page = NULL;
-       ClearPagePrivate(page);
-       page->private = 0;
+
+       if (PagePrivate(page)) {
+               ClearPagePrivate(page);
+               page_cache_release(page);
+               set_page_private(page, 0);
+       }
        block->ops = &btree_block_ops;
        err = alias_tree_insert(block->sb, block->ino, block->bix, block->level,
                        block);
@@ -702,7 +720,10 @@ void freeseg(struct super_block *sb, u32 segno)
                page = find_get_page(mapping, ofs >> PAGE_SHIFT);
                if (!page)
                        continue;
-               ClearPagePrivate(page);
+               if (PagePrivate(page)) {
+                       ClearPagePrivate(page);
+                       page_cache_release(page);
+               }
                page_cache_release(page);
        }
 }
@@ -841,6 +862,16 @@ static void free_area(struct logfs_area *area)
        kfree(area);
 }
 
+void free_areas(struct super_block *sb)
+{
+       struct logfs_super *super = logfs_super(sb);
+       int i;
+
+       for_each_area(i)
+               free_area(super->s_area[i]);
+       free_area(super->s_journal_area);
+}
+
 static struct logfs_area *alloc_area(struct super_block *sb)
 {
        struct logfs_area *area;
@@ -923,10 +954,6 @@ err:
 void logfs_cleanup_areas(struct super_block *sb)
 {
        struct logfs_super *super = logfs_super(sb);
-       int i;
 
        btree_grim_visitor128(&super->s_object_alias_tree, 0, kill_alias);
-       for_each_area(i)
-               free_area(super->s_area[i]);
-       free_area(super->s_journal_area);
 }
index e795c23..c9ee7f5 100644 (file)
@@ -486,14 +486,15 @@ static void logfs_kill_sb(struct super_block *sb)
        /* Alias entries slow down mount, so evict as many as possible */
        sync_filesystem(sb);
        logfs_write_anchor(sb);
+       free_areas(sb);
 
        /*
         * From this point on alias entries are simply dropped - and any
         * writes to the object store are considered bugs.
         */
-       super->s_flags |= LOGFS_SB_FLAG_SHUTDOWN;
        log_super("LogFS: Now in shutdown\n");
        generic_shutdown_super(sb);
+       super->s_flags |= LOGFS_SB_FLAG_SHUTDOWN;
 
        BUG_ON(super->s_dirty_used_bytes || super->s_dirty_free_bytes);
 
index 8866496..2a70fce 100644 (file)
@@ -603,6 +603,8 @@ static int nilfs_ioctl_clean_segments(struct inode *inode, struct file *filp,
        nsegs = argv[4].v_nmembs;
        if (argv[4].v_size != argsz[4])
                goto out;
+       if (nsegs > UINT_MAX / sizeof(__u64))
+               goto out;
 
        /*
         * argv[4] points to segment numbers this ioctl cleans.  We
index 9cde9ed..d4548dd 100644 (file)
@@ -198,26 +198,6 @@ static int proc_root_link(struct dentry *dentry, struct path *path)
        return result;
 }
 
-static struct mm_struct *mm_access(struct task_struct *task, unsigned int mode)
-{
-       struct mm_struct *mm;
-       int err;
-
-       err =  mutex_lock_killable(&task->signal->cred_guard_mutex);
-       if (err)
-               return ERR_PTR(err);
-
-       mm = get_task_mm(task);
-       if (mm && mm != current->mm &&
-                       !ptrace_may_access(task, mode)) {
-               mmput(mm);
-               mm = ERR_PTR(-EACCES);
-       }
-       mutex_unlock(&task->signal->cred_guard_mutex);
-
-       return mm;
-}
-
 struct mm_struct *mm_for_maps(struct task_struct *task)
 {
        return mm_access(task, PTRACE_MODE_READ);
@@ -711,6 +691,13 @@ static int mem_open(struct inode* inode, struct file* file)
        if (IS_ERR(mm))
                return PTR_ERR(mm);
 
+       if (mm) {
+               /* ensure this mm_struct can't be freed */
+               atomic_inc(&mm->mm_count);
+               /* but do not pin its memory */
+               mmput(mm);
+       }
+
        /* OK to pass negative loff_t, we can catch out-of-range */
        file->f_mode |= FMODE_UNSIGNED_OFFSET;
        file->private_data = mm;
@@ -718,57 +705,13 @@ static int mem_open(struct inode* inode, struct file* file)
        return 0;
 }
 
-static ssize_t mem_read(struct file * file, char __user * buf,
-                       size_t count, loff_t *ppos)
+static ssize_t mem_rw(struct file *file, char __user *buf,
+                       size_t count, loff_t *ppos, int write)
 {
-       int ret;
-       char *page;
-       unsigned long src = *ppos;
        struct mm_struct *mm = file->private_data;
-
-       if (!mm)
-               return 0;
-
-       page = (char *)__get_free_page(GFP_TEMPORARY);
-       if (!page)
-               return -ENOMEM;
-
-       ret = 0;
-       while (count > 0) {
-               int this_len, retval;
-
-               this_len = (count > PAGE_SIZE) ? PAGE_SIZE : count;
-               retval = access_remote_vm(mm, src, page, this_len, 0);
-               if (!retval) {
-                       if (!ret)
-                               ret = -EIO;
-                       break;
-               }
-
-               if (copy_to_user(buf, page, retval)) {
-                       ret = -EFAULT;
-                       break;
-               }
-               ret += retval;
-               src += retval;
-               buf += retval;
-               count -= retval;
-       }
-       *ppos = src;
-
-       free_page((unsigned long) page);
-       return ret;
-}
-
-static ssize_t mem_write(struct file * file, const char __user *buf,
-                        size_t count, loff_t *ppos)
-{
-       int copied;
+       unsigned long addr = *ppos;
+       ssize_t copied;
        char *page;
-       unsigned long dst = *ppos;
-       struct mm_struct *mm = file->private_data;
 
        if (!mm)
                return 0;
@@ -778,31 +721,54 @@ static ssize_t mem_write(struct file * file, const char __user *buf,
                return -ENOMEM;
 
        copied = 0;
+       if (!atomic_inc_not_zero(&mm->mm_users))
+               goto free;
+
        while (count > 0) {
-               int this_len, retval;
+               int this_len = min_t(int, count, PAGE_SIZE);
 
-               this_len = (count > PAGE_SIZE) ? PAGE_SIZE : count;
-               if (copy_from_user(page, buf, this_len)) {
+               if (write && copy_from_user(page, buf, this_len)) {
                        copied = -EFAULT;
                        break;
                }
-               retval = access_remote_vm(mm, dst, page, this_len, 1);
-               if (!retval) {
+
+               this_len = access_remote_vm(mm, addr, page, this_len, write);
+               if (!this_len) {
                        if (!copied)
                                copied = -EIO;
                        break;
                }
-               copied += retval;
-               buf += retval;
-               dst += retval;
-               count -= retval;                        
+
+               if (!write && copy_to_user(buf, page, this_len)) {
+                       copied = -EFAULT;
+                       break;
+               }
+
+               buf += this_len;
+               addr += this_len;
+               copied += this_len;
+               count -= this_len;
        }
-       *ppos = dst;
+       *ppos = addr;
 
+       mmput(mm);
+free:
        free_page((unsigned long) page);
        return copied;
 }
 
+static ssize_t mem_read(struct file *file, char __user *buf,
+                       size_t count, loff_t *ppos)
+{
+       return mem_rw(file, buf, count, ppos, 0);
+}
+
+static ssize_t mem_write(struct file *file, const char __user *buf,
+                        size_t count, loff_t *ppos)
+{
+       return mem_rw(file, (char __user*)buf, count, ppos, 1);
+}
+
 loff_t mem_lseek(struct file *file, loff_t offset, int orig)
 {
        switch (orig) {
@@ -822,8 +788,8 @@ loff_t mem_lseek(struct file *file, loff_t offset, int orig)
 static int mem_release(struct inode *inode, struct file *file)
 {
        struct mm_struct *mm = file->private_data;
-
-       mmput(mm);
+       if (mm)
+               mmdrop(mm);
        return 0;
 }
 
index 62f4fb3..00012e3 100644 (file)
@@ -493,6 +493,12 @@ int sysfs_attr_ns(struct kobject *kobj, const struct attribute *attr,
        const void *ns = NULL;
        int err;
 
+       if (!dir_sd) {
+               WARN(1, KERN_ERR "sysfs: kobject %s without dirent\n",
+                       kobject_name(kobj));
+               return -ENOENT;
+       }
+
        err = 0;
        if (!sysfs_ns_type(dir_sd))
                goto out;
index 4a802b4..85eb816 100644 (file)
@@ -318,8 +318,11 @@ int sysfs_hash_and_remove(struct sysfs_dirent *dir_sd, const void *ns, const cha
        struct sysfs_addrm_cxt acxt;
        struct sysfs_dirent *sd;
 
-       if (!dir_sd)
+       if (!dir_sd) {
+               WARN(1, KERN_WARNING "sysfs: can not remove '%s', no directory\n",
+                       name);
                return -ENOENT;
+       }
 
        sysfs_addrm_start(&acxt, dir_sd);
 
index 292eff1..ab7c53f 100644 (file)
@@ -110,10 +110,4 @@ kmem_zone_destroy(kmem_zone_t *zone)
 extern void *kmem_zone_alloc(kmem_zone_t *, unsigned int __nocast);
 extern void *kmem_zone_zalloc(kmem_zone_t *, unsigned int __nocast);
 
-static inline int
-kmem_shake_allow(gfp_t gfp_mask)
-{
-       return ((gfp_mask & __GFP_WAIT) && (gfp_mask & __GFP_FS));
-}
-
 #endif /* __XFS_SUPPORT_KMEM_H__ */
index b4ff40b..cbcb7be 100644 (file)
@@ -62,82 +62,6 @@ int xfs_dqerror_mod = 33;
 
 static struct lock_class_key xfs_dquot_other_class;
 
-/*
- * Allocate and initialize a dquot. We don't always allocate fresh memory;
- * we try to reclaim a free dquot if the number of incore dquots are above
- * a threshold.
- * The only field inside the core that gets initialized at this point
- * is the d_id field. The idea is to fill in the entire q_core
- * when we read in the on disk dquot.
- */
-STATIC xfs_dquot_t *
-xfs_qm_dqinit(
-       xfs_mount_t  *mp,
-       xfs_dqid_t   id,
-       uint         type)
-{
-       xfs_dquot_t     *dqp;
-       boolean_t       brandnewdquot;
-
-       brandnewdquot = xfs_qm_dqalloc_incore(&dqp);
-       dqp->dq_flags = type;
-       dqp->q_core.d_id = cpu_to_be32(id);
-       dqp->q_mount = mp;
-
-       /*
-        * No need to re-initialize these if this is a reclaimed dquot.
-        */
-       if (brandnewdquot) {
-               INIT_LIST_HEAD(&dqp->q_freelist);
-               mutex_init(&dqp->q_qlock);
-               init_waitqueue_head(&dqp->q_pinwait);
-
-               /*
-                * Because we want to use a counting completion, complete
-                * the flush completion once to allow a single access to
-                * the flush completion without blocking.
-                */
-               init_completion(&dqp->q_flush);
-               complete(&dqp->q_flush);
-
-               trace_xfs_dqinit(dqp);
-       } else {
-               /*
-                * Only the q_core portion was zeroed in dqreclaim_one().
-                * So, we need to reset others.
-                */
-               dqp->q_nrefs = 0;
-               dqp->q_blkno = 0;
-               INIT_LIST_HEAD(&dqp->q_mplist);
-               INIT_LIST_HEAD(&dqp->q_hashlist);
-               dqp->q_bufoffset = 0;
-               dqp->q_fileoffset = 0;
-               dqp->q_transp = NULL;
-               dqp->q_gdquot = NULL;
-               dqp->q_res_bcount = 0;
-               dqp->q_res_icount = 0;
-               dqp->q_res_rtbcount = 0;
-               atomic_set(&dqp->q_pincount, 0);
-               dqp->q_hash = NULL;
-               ASSERT(list_empty(&dqp->q_freelist));
-
-               trace_xfs_dqreuse(dqp);
-       }
-
-       /*
-        * In either case we need to make sure group quotas have a different
-        * lock class than user quotas, to make sure lockdep knows we can
-        * locks of one of each at the same time.
-        */
-       if (!(type & XFS_DQ_USER))
-               lockdep_set_class(&dqp->q_qlock, &xfs_dquot_other_class);
-
-       /*
-        * log item gets initialized later
-        */
-       return (dqp);
-}
-
 /*
  * This is called to free all the memory associated with a dquot
  */
@@ -567,7 +491,32 @@ xfs_qm_dqread(
        int                     error;
        int                     cancelflags = 0;
 
-       dqp = xfs_qm_dqinit(mp, id, type);
+
+       dqp = kmem_zone_zalloc(xfs_Gqm->qm_dqzone, KM_SLEEP);
+
+       dqp->dq_flags = type;
+       dqp->q_core.d_id = cpu_to_be32(id);
+       dqp->q_mount = mp;
+       INIT_LIST_HEAD(&dqp->q_freelist);
+       mutex_init(&dqp->q_qlock);
+       init_waitqueue_head(&dqp->q_pinwait);
+
+       /*
+        * Because we want to use a counting completion, complete
+        * the flush completion once to allow a single access to
+        * the flush completion without blocking.
+        */
+       init_completion(&dqp->q_flush);
+       complete(&dqp->q_flush);
+
+       /*
+        * Make sure group quotas have a different lock class than user
+        * quotas.
+        */
+       if (!(type & XFS_DQ_USER))
+               lockdep_set_class(&dqp->q_qlock, &xfs_dquot_other_class);
+
+       atomic_inc(&xfs_Gqm->qm_totaldquots);
 
        trace_xfs_dqread(dqp);
 
index 541a508..15ff539 100644 (file)
@@ -1489,7 +1489,7 @@ xlog_recover_add_to_cont_trans(
        old_ptr = item->ri_buf[item->ri_cnt-1].i_addr;
        old_len = item->ri_buf[item->ri_cnt-1].i_len;
 
-       ptr = kmem_realloc(old_ptr, len+old_len, old_len, 0u);
+       ptr = kmem_realloc(old_ptr, len+old_len, old_len, KM_SLEEP);
        memcpy(&ptr[old_len], dp, len); /* d, s, l */
        item->ri_buf[item->ri_cnt-1].i_len += len;
        item->ri_buf[item->ri_cnt-1].i_addr = ptr;
index 671f37e..c436def 100644 (file)
@@ -50,7 +50,6 @@
  */
 struct mutex   xfs_Gqm_lock;
 struct xfs_qm  *xfs_Gqm;
-uint           ndquot;
 
 kmem_zone_t    *qm_dqzone;
 kmem_zone_t    *qm_dqtrxzone;
@@ -93,7 +92,6 @@ xfs_Gqm_init(void)
                goto out_free_udqhash;
 
        hsize /= sizeof(xfs_dqhash_t);
-       ndquot = hsize << 8;
 
        xqm = kmem_zalloc(sizeof(xfs_qm_t), KM_SLEEP);
        xqm->qm_dqhashmask = hsize - 1;
@@ -137,7 +135,6 @@ xfs_Gqm_init(void)
                xqm->qm_dqtrxzone = qm_dqtrxzone;
 
        atomic_set(&xqm->qm_totaldquots, 0);
-       xqm->qm_dqfree_ratio = XFS_QM_DQFREE_RATIO;
        xqm->qm_nrefs = 0;
        return xqm;
 
@@ -1600,216 +1597,150 @@ xfs_qm_init_quotainos(
        return 0;
 }
 
+STATIC void
+xfs_qm_dqfree_one(
+       struct xfs_dquot        *dqp)
+{
+       struct xfs_mount        *mp = dqp->q_mount;
+       struct xfs_quotainfo    *qi = mp->m_quotainfo;
 
+       mutex_lock(&dqp->q_hash->qh_lock);
+       list_del_init(&dqp->q_hashlist);
+       dqp->q_hash->qh_version++;
+       mutex_unlock(&dqp->q_hash->qh_lock);
 
-/*
- * Pop the least recently used dquot off the freelist and recycle it.
- */
-STATIC struct xfs_dquot *
-xfs_qm_dqreclaim_one(void)
+       mutex_lock(&qi->qi_dqlist_lock);
+       list_del_init(&dqp->q_mplist);
+       qi->qi_dquots--;
+       qi->qi_dqreclaims++;
+       mutex_unlock(&qi->qi_dqlist_lock);
+
+       xfs_qm_dqdestroy(dqp);
+}
+
+STATIC void
+xfs_qm_dqreclaim_one(
+       struct xfs_dquot        *dqp,
+       struct list_head        *dispose_list)
 {
-       struct xfs_dquot        *dqp;
-       int                     restarts = 0;
+       struct xfs_mount        *mp = dqp->q_mount;
+       int                     error;
 
-       mutex_lock(&xfs_Gqm->qm_dqfrlist_lock);
-restart:
-       list_for_each_entry(dqp, &xfs_Gqm->qm_dqfrlist, q_freelist) {
-               struct xfs_mount *mp = dqp->q_mount;
+       if (!xfs_dqlock_nowait(dqp))
+               goto out_busy;
 
-               if (!xfs_dqlock_nowait(dqp))
-                       continue;
+       /*
+        * This dquot has acquired a reference in the meantime remove it from
+        * the freelist and try again.
+        */
+       if (dqp->q_nrefs) {
+               xfs_dqunlock(dqp);
 
-               /*
-                * This dquot has already been grabbed by dqlookup.
-                * Remove it from the freelist and try again.
-                */
-               if (dqp->q_nrefs) {
-                       trace_xfs_dqreclaim_want(dqp);
-                       XQM_STATS_INC(xqmstats.xs_qm_dqwants);
-
-                       list_del_init(&dqp->q_freelist);
-                       xfs_Gqm->qm_dqfrlist_cnt--;
-                       restarts++;
-                       goto dqunlock;
-               }
+               trace_xfs_dqreclaim_want(dqp);
+               XQM_STATS_INC(xqmstats.xs_qm_dqwants);
 
-               ASSERT(dqp->q_hash);
-               ASSERT(!list_empty(&dqp->q_mplist));
+               list_del_init(&dqp->q_freelist);
+               xfs_Gqm->qm_dqfrlist_cnt--;
+               return;
+       }
 
-               /*
-                * Try to grab the flush lock. If this dquot is in the process
-                * of getting flushed to disk, we don't want to reclaim it.
-                */
-               if (!xfs_dqflock_nowait(dqp))
-                       goto dqunlock;
+       ASSERT(dqp->q_hash);
+       ASSERT(!list_empty(&dqp->q_mplist));
 
-               /*
-                * We have the flush lock so we know that this is not in the
-                * process of being flushed. So, if this is dirty, flush it
-                * DELWRI so that we don't get a freelist infested with
-                * dirty dquots.
-                */
-               if (XFS_DQ_IS_DIRTY(dqp)) {
-                       int     error;
+       /*
+        * Try to grab the flush lock. If this dquot is in the process of
+        * getting flushed to disk, we don't want to reclaim it.
+        */
+       if (!xfs_dqflock_nowait(dqp))
+               goto out_busy;
 
-                       trace_xfs_dqreclaim_dirty(dqp);
+       /*
+        * We have the flush lock so we know that this is not in the
+        * process of being flushed. So, if this is dirty, flush it
+        * DELWRI so that we don't get a freelist infested with
+        * dirty dquots.
+        */
+       if (XFS_DQ_IS_DIRTY(dqp)) {
+               trace_xfs_dqreclaim_dirty(dqp);
 
-                       /*
-                        * We flush it delayed write, so don't bother
-                        * releasing the freelist lock.
-                        */
-                       error = xfs_qm_dqflush(dqp, SYNC_TRYLOCK);
-                       if (error) {
-                               xfs_warn(mp, "%s: dquot %p flush failed",
-                                       __func__, dqp);
-                       }
-                       goto dqunlock;
+               /*
+                * We flush it delayed write, so don't bother releasing the
+                * freelist lock.
+                */
+               error = xfs_qm_dqflush(dqp, 0);
+               if (error) {
+                       xfs_warn(mp, "%s: dquot %p flush failed",
+                                __func__, dqp);
                }
-               xfs_dqfunlock(dqp);
 
                /*
-                * Prevent lookup now that we are going to reclaim the dquot.
-                * Once XFS_DQ_FREEING is set lookup won't touch the dquot,
-                * thus we can drop the lock now.
+                * Give the dquot another try on the freelist, as the
+                * flushing will take some time.
                 */
-               dqp->dq_flags |= XFS_DQ_FREEING;
-               xfs_dqunlock(dqp);
-
-               mutex_lock(&dqp->q_hash->qh_lock);
-               list_del_init(&dqp->q_hashlist);
-               dqp->q_hash->qh_version++;
-               mutex_unlock(&dqp->q_hash->qh_lock);
-
-               mutex_lock(&mp->m_quotainfo->qi_dqlist_lock);
-               list_del_init(&dqp->q_mplist);
-               mp->m_quotainfo->qi_dquots--;
-               mp->m_quotainfo->qi_dqreclaims++;
-               mutex_unlock(&mp->m_quotainfo->qi_dqlist_lock);
+               goto out_busy;
+       }
+       xfs_dqfunlock(dqp);
 
-               ASSERT(dqp->q_nrefs == 0);
-               list_del_init(&dqp->q_freelist);
-               xfs_Gqm->qm_dqfrlist_cnt--;
+       /*
+        * Prevent lookups now that we are past the point of no return.
+        */
+       dqp->dq_flags |= XFS_DQ_FREEING;
+       xfs_dqunlock(dqp);
 
-               mutex_unlock(&xfs_Gqm->qm_dqfrlist_lock);
-               return dqp;
-dqunlock:
-               xfs_dqunlock(dqp);
-               if (restarts >= XFS_QM_RECLAIM_MAX_RESTARTS)
-                       break;
-               goto restart;
-       }
+       ASSERT(dqp->q_nrefs == 0);
+       list_move_tail(&dqp->q_freelist, dispose_list);
+       xfs_Gqm->qm_dqfrlist_cnt--;
 
-       mutex_unlock(&xfs_Gqm->qm_dqfrlist_lock);
-       return NULL;
-}
+       trace_xfs_dqreclaim_done(dqp);
+       XQM_STATS_INC(xqmstats.xs_qm_dqreclaims);
+       return;
 
-/*
- * Traverse the freelist of dquots and attempt to reclaim a maximum of
- * 'howmany' dquots. This operation races with dqlookup(), and attempts to
- * favor the lookup function ...
- */
-STATIC int
-xfs_qm_shake_freelist(
-       int     howmany)
-{
-       int             nreclaimed = 0;
-       xfs_dquot_t     *dqp;
+out_busy:
+       xfs_dqunlock(dqp);
 
-       if (howmany <= 0)
-               return 0;
+       /*
+        * Move the dquot to the tail of the list so that we don't spin on it.
+        */
+       list_move_tail(&dqp->q_freelist, &xfs_Gqm->qm_dqfrlist);
 
-       while (nreclaimed < howmany) {
-               dqp = xfs_qm_dqreclaim_one();
-               if (!dqp)
-                       return nreclaimed;
-               xfs_qm_dqdestroy(dqp);
-               nreclaimed++;
-       }
-       return nreclaimed;
+       trace_xfs_dqreclaim_busy(dqp);
+       XQM_STATS_INC(xqmstats.xs_qm_dqreclaim_misses);
 }
 
-/*
- * The kmem_shake interface is invoked when memory is running low.
- */
-/* ARGSUSED */
 STATIC int
 xfs_qm_shake(
-       struct shrinker *shrink,
-       struct shrink_control *sc)
+       struct shrinker         *shrink,
+       struct shrink_control   *sc)
 {
-       int     ndqused, nfree, n;
-       gfp_t gfp_mask = sc->gfp_mask;
-
-       if (!kmem_shake_allow(gfp_mask))
-               return 0;
-       if (!xfs_Gqm)
-               return 0;
-
-       nfree = xfs_Gqm->qm_dqfrlist_cnt; /* free dquots */
-       /* incore dquots in all f/s's */
-       ndqused = atomic_read(&xfs_Gqm->qm_totaldquots) - nfree;
-
-       ASSERT(ndqused >= 0);
+       int                     nr_to_scan = sc->nr_to_scan;
+       LIST_HEAD               (dispose_list);
+       struct xfs_dquot        *dqp;
 
-       if (nfree <= ndqused && nfree < ndquot)
+       if ((sc->gfp_mask & (__GFP_FS|__GFP_WAIT)) != (__GFP_FS|__GFP_WAIT))
                return 0;
+       if (!nr_to_scan)
+               goto out;
 
-       ndqused *= xfs_Gqm->qm_dqfree_ratio;    /* target # of free dquots */
-       n = nfree - ndqused - ndquot;           /* # over target */
-
-       return xfs_qm_shake_freelist(MAX(nfree, n));
-}
-
-
-/*------------------------------------------------------------------*/
-
-/*
- * Return a new incore dquot. Depending on the number of
- * dquots in the system, we either allocate a new one on the kernel heap,
- * or reclaim a free one.
- * Return value is B_TRUE if we allocated a new dquot, B_FALSE if we managed
- * to reclaim an existing one from the freelist.
- */
-boolean_t
-xfs_qm_dqalloc_incore(
-       xfs_dquot_t **O_dqpp)
-{
-       xfs_dquot_t     *dqp;
-
-       /*
-        * Check against high water mark to see if we want to pop
-        * a nincompoop dquot off the freelist.
-        */
-       if (atomic_read(&xfs_Gqm->qm_totaldquots) >= ndquot) {
-               /*
-                * Try to recycle a dquot from the freelist.
-                */
-               if ((dqp = xfs_qm_dqreclaim_one())) {
-                       XQM_STATS_INC(xqmstats.xs_qm_dqreclaims);
-                       /*
-                        * Just zero the core here. The rest will get
-                        * reinitialized by caller. XXX we shouldn't even
-                        * do this zero ...
-                        */
-                       memset(&dqp->q_core, 0, sizeof(dqp->q_core));
-                       *O_dqpp = dqp;
-                       return B_FALSE;
-               }
-               XQM_STATS_INC(xqmstats.xs_qm_dqreclaim_misses);
+       mutex_lock(&xfs_Gqm->qm_dqfrlist_lock);
+       while (!list_empty(&xfs_Gqm->qm_dqfrlist)) {
+               if (nr_to_scan-- <= 0)
+                       break;
+               dqp = list_first_entry(&xfs_Gqm->qm_dqfrlist, struct xfs_dquot,
+                                      q_freelist);
+               xfs_qm_dqreclaim_one(dqp, &dispose_list);
        }
+       mutex_unlock(&xfs_Gqm->qm_dqfrlist_lock);
 
-       /*
-        * Allocate a brand new dquot on the kernel heap and return it
-        * to the caller to initialize.
-        */
-       ASSERT(xfs_Gqm->qm_dqzone != NULL);
-       *O_dqpp = kmem_zone_zalloc(xfs_Gqm->qm_dqzone, KM_SLEEP);
-       atomic_inc(&xfs_Gqm->qm_totaldquots);
-
-       return B_TRUE;
+       while (!list_empty(&dispose_list)) {
+               dqp = list_first_entry(&dispose_list, struct xfs_dquot,
+                                      q_freelist);
+               list_del_init(&dqp->q_freelist);
+               xfs_qm_dqfree_one(dqp);
+       }
+out:
+       return (xfs_Gqm->qm_dqfrlist_cnt / 100) * sysctl_vfs_cache_pressure;
 }
 
-
 /*
  * Start a transaction and write the incore superblock changes to
  * disk. flags parameter indicates which fields have changed.
index 9b4f3ad..9a9b997 100644 (file)
 struct xfs_qm;
 struct xfs_inode;
 
-extern uint            ndquot;
 extern struct mutex    xfs_Gqm_lock;
 extern struct xfs_qm   *xfs_Gqm;
 extern kmem_zone_t     *qm_dqzone;
 extern kmem_zone_t     *qm_dqtrxzone;
 
-/*
- * Ditto, for xfs_qm_dqreclaim_one.
- */
-#define XFS_QM_RECLAIM_MAX_RESTARTS    4
-
-/*
- * Ideal ratio of free to in use dquots. Quota manager makes an attempt
- * to keep this balance.
- */
-#define XFS_QM_DQFREE_RATIO            2
-
 /*
  * Dquot hashtable constants/threshold values.
  */
@@ -74,7 +62,6 @@ typedef struct xfs_qm {
        int              qm_dqfrlist_cnt;
        atomic_t         qm_totaldquots; /* total incore dquots */
        uint             qm_nrefs;       /* file systems with quota on */
-       int              qm_dqfree_ratio;/* ratio of free to inuse dquots */
        kmem_zone_t     *qm_dqzone;      /* dquot mem-alloc zone */
        kmem_zone_t     *qm_dqtrxzone;   /* t_dqinfo of transactions */
 } xfs_qm_t;
@@ -143,7 +130,6 @@ extern int          xfs_qm_quotacheck(xfs_mount_t *);
 extern int             xfs_qm_write_sb_changes(xfs_mount_t *, __int64_t);
 
 /* dquot stuff */
-extern boolean_t       xfs_qm_dqalloc_incore(xfs_dquot_t **);
 extern int             xfs_qm_dqpurge_all(xfs_mount_t *, uint);
 extern void            xfs_qm_dqrele_all_inodes(xfs_mount_t *, uint);
 
index 8671a0b..5729ba5 100644 (file)
@@ -42,9 +42,9 @@ static int xqm_proc_show(struct seq_file *m, void *v)
 {
        /* maximum; incore; ratio free to inuse; freelist */
        seq_printf(m, "%d\t%d\t%d\t%u\n",
-                       ndquot,
+                       0,
                        xfs_Gqm? atomic_read(&xfs_Gqm->qm_totaldquots) : 0,
-                       xfs_Gqm? xfs_Gqm->qm_dqfree_ratio : 0,
+                       0,
                        xfs_Gqm? xfs_Gqm->qm_dqfrlist_cnt : 0);
        return 0;
 }
index 6b6df58..bb134a8 100644 (file)
@@ -733,11 +733,10 @@ DEFINE_EVENT(xfs_dquot_class, name, \
 DEFINE_DQUOT_EVENT(xfs_dqadjust);
 DEFINE_DQUOT_EVENT(xfs_dqreclaim_want);
 DEFINE_DQUOT_EVENT(xfs_dqreclaim_dirty);
-DEFINE_DQUOT_EVENT(xfs_dqreclaim_unlink);
+DEFINE_DQUOT_EVENT(xfs_dqreclaim_busy);
+DEFINE_DQUOT_EVENT(xfs_dqreclaim_done);
 DEFINE_DQUOT_EVENT(xfs_dqattach_found);
 DEFINE_DQUOT_EVENT(xfs_dqattach_get);
-DEFINE_DQUOT_EVENT(xfs_dqinit);
-DEFINE_DQUOT_EVENT(xfs_dqreuse);
 DEFINE_DQUOT_EVENT(xfs_dqalloc);
 DEFINE_DQUOT_EVENT(xfs_dqtobp_read);
 DEFINE_DQUOT_EVENT(xfs_dqread);
index 8de4b73..e58fcf8 100644 (file)
@@ -15,6 +15,16 @@ struct pci_dev;
 #ifdef CONFIG_PCI
 /* Create a virtual mapping cookie for a PCI BAR (memory or IO) */
 extern void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long max);
+/* Create a virtual mapping cookie for a port on a given PCI device.
+ * Do not call this directly, it exists to make it easier for architectures
+ * to override */
+#ifdef CONFIG_NO_GENERIC_PCI_IOPORT_MAP
+extern void __iomem *__pci_ioport_map(struct pci_dev *dev, unsigned long port,
+                                     unsigned int nr);
+#else
+#define __pci_ioport_map(dev, port, nr) ioport_map((port), (nr))
+#endif
+
 #else
 static inline void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long max)
 {
index fd88a39..0092102 100644 (file)
@@ -18,7 +18,7 @@ struct pt_regs;
 #define BINPRM_BUF_SIZE 128
 
 #ifdef __KERNEL__
-#include <linux/list.h>
+#include <linux/sched.h>
 
 #define CORENAME_MAX_SIZE 128
 
@@ -58,6 +58,7 @@ struct linux_binprm {
        unsigned interp_flags;
        unsigned interp_data;
        unsigned long loader, exec;
+       char tcomm[TASK_COMM_LEN];
 };
 
 #define BINPRM_FLAGS_ENFORCE_NONDUMP_BIT 0
index 3c1063a..94300fe 100644 (file)
@@ -55,6 +55,26 @@ static inline unsigned long hweight_long(unsigned long w)
        return sizeof(w) == 4 ? hweight32(w) : hweight64(w);
 }
 
+/**
+ * rol64 - rotate a 64-bit value left
+ * @word: value to rotate
+ * @shift: bits to roll
+ */
+static inline __u64 rol64(__u64 word, unsigned int shift)
+{
+       return (word << shift) | (word >> (64 - shift));
+}
+
+/**
+ * ror64 - rotate a 64-bit value right
+ * @word: value to rotate
+ * @shift: bits to roll
+ */
+static inline __u64 ror64(__u64 word, unsigned int shift)
+{
+       return (word >> shift) | (word << (64 - shift));
+}
+
 /**
  * rol32 - rotate a 32-bit value left
  * @word: value to rotate
index 6c6a1f0..606cf33 100644 (file)
@@ -399,9 +399,6 @@ struct request_queue {
        /* Throttle data */
        struct throtl_data *td;
 #endif
-#ifdef CONFIG_LOCKDEP
-       int                     ioc_release_depth;
-#endif
 };
 
 #define QUEUE_FLAG_QUEUED      1       /* uses generic tag queueing */
index 35eae4b..7c48029 100644 (file)
@@ -952,7 +952,8 @@ struct cdrom_device_info {
        char name[20];                  /* name of the device type */
 /* per-device flags */
         __u8 sanyo_slot                : 2;    /* Sanyo 3 CD changer support */
-        __u8 reserved          : 6;    /* not used yet */
+        __u8 keeplocked                : 1;    /* CDROM_LOCKDOOR status */
+        __u8 reserved          : 5;    /* not used yet */
        int cdda_method;                /* see flags */
        __u8 last_sense;
        __u8 media_written;             /* dirty flag, DVD+RW bookkeeping */
index c24f3d7..7d4e035 100644 (file)
@@ -42,12 +42,6 @@ struct elevator_ops
        elevator_merged_fn *elevator_merged_fn;
        elevator_merge_req_fn *elevator_merge_req_fn;
        elevator_allow_merge_fn *elevator_allow_merge_fn;
-
-       /*
-        * Used for both plugged list and elevator merging and in the
-        * former case called without queue_lock.  Read comment on top of
-        * attempt_plug_merge() for details.
-        */
        elevator_bio_merged_fn *elevator_bio_merged_fn;
 
        elevator_dispatch_fn *elevator_dispatch_fn;
@@ -122,7 +116,6 @@ extern void elv_dispatch_add_tail(struct request_queue *, struct request *);
 extern void elv_add_request(struct request_queue *, struct request *, int);
 extern void __elv_add_request(struct request_queue *, struct request *, int);
 extern int elv_merge(struct request_queue *, struct request **, struct bio *);
-extern int elv_try_merge(struct request *, struct bio *);
 extern void elv_merge_requests(struct request_queue *, struct request *,
                               struct request *);
 extern void elv_merged_request(struct request_queue *, struct request *, int);
@@ -155,7 +148,7 @@ extern ssize_t elv_iosched_store(struct request_queue *, const char *, size_t);
 extern int elevator_init(struct request_queue *, char *);
 extern void elevator_exit(struct elevator_queue *);
 extern int elevator_change(struct request_queue *, const char *);
-extern int elv_rq_merge_ok(struct request *, struct bio *);
+extern bool elv_rq_merge_ok(struct request *, struct bio *);
 
 /*
  * Helper functions.
index 0ab54e1..d09af4b 100644 (file)
@@ -39,6 +39,7 @@ extern bool __refrigerator(bool check_kthr_stop);
 extern int freeze_processes(void);
 extern int freeze_kernel_threads(void);
 extern void thaw_processes(void);
+extern void thaw_kernel_threads(void);
 
 static inline bool try_to_freeze(void)
 {
@@ -174,6 +175,7 @@ static inline bool __refrigerator(bool check_kthr_stop) { return false; }
 static inline int freeze_processes(void) { return -ENOSYS; }
 static inline int freeze_kernel_threads(void) { return -ENOSYS; }
 static inline void thaw_processes(void) {}
+static inline void thaw_kernel_threads(void) {}
 
 static inline bool try_to_freeze(void) { return false; }
 
index b5ca4b2..004ff33 100644 (file)
@@ -1,6 +1,8 @@
 #ifndef _GPIO_KEYS_H
 #define _GPIO_KEYS_H
 
+struct device;
+
 struct gpio_keys_button {
        /* Configuration parameters */
        unsigned int code;      /* input event code (KEY_*, SW_*) */
index 62b908e..0ae065a 100644 (file)
@@ -35,7 +35,7 @@
 #include <linux/mod_devicetable.h>
 
 
-#define MAX_PAGE_BUFFER_COUNT                          18
+#define MAX_PAGE_BUFFER_COUNT                          19
 #define MAX_MULTIPAGE_BUFFER_COUNT                     32 /* 128K */
 
 #pragma pack(push, 1)
index 7e1371c..119773e 100644 (file)
@@ -133,7 +133,7 @@ static inline struct io_context *ioc_task_link(struct io_context *ioc)
 
 struct task_struct;
 #ifdef CONFIG_BLOCK
-void put_io_context(struct io_context *ioc, struct request_queue *locked_q);
+void put_io_context(struct io_context *ioc);
 void exit_io_context(struct task_struct *task);
 struct io_context *get_task_io_context(struct task_struct *task,
                                       gfp_t gfp_flags, int node);
@@ -141,8 +141,7 @@ void ioc_ioprio_changed(struct io_context *ioc, int ioprio);
 void ioc_cgroup_changed(struct io_context *ioc);
 #else
 struct io_context;
-static inline void put_io_context(struct io_context *ioc,
-                                 struct request_queue *locked_q) { }
+static inline void put_io_context(struct io_context *ioc) { }
 static inline void exit_io_context(struct task_struct *task) { }
 #endif
 
old mode 100755 (executable)
new mode 100644 (file)
index 1515e64..f88c1cc 100644 (file)
@@ -10,7 +10,6 @@
 #ifndef MCP_H
 #define MCP_H
 
-#include <linux/mod_devicetable.h>
 #include <mach/dma.h>
 
 struct mcp_ops;
@@ -27,7 +26,7 @@ struct mcp {
        dma_device_t    dma_telco_rd;
        dma_device_t    dma_telco_wr;
        struct device   attached_device;
-       const char      *codec;
+       int             gpio_base;
 };
 
 struct mcp_ops {
@@ -45,11 +44,10 @@ void mcp_reg_write(struct mcp *, unsigned int, unsigned int);
 unsigned int mcp_reg_read(struct mcp *, unsigned int);
 void mcp_enable(struct mcp *);
 void mcp_disable(struct mcp *);
-const struct mcp_device_id *mcp_get_device_id(const struct mcp *mcp);
 #define mcp_get_sclk_rate(mcp) ((mcp)->sclk_rate)
 
 struct mcp *mcp_host_alloc(struct device *, size_t);
-int mcp_host_register(struct mcp *, void *);
+int mcp_host_register(struct mcp *);
 void mcp_host_unregister(struct mcp *);
 
 struct mcp_driver {
@@ -58,7 +56,6 @@ struct mcp_driver {
        void (*remove)(struct mcp *);
        int (*suspend)(struct mcp *, pm_message_t);
        int (*resume)(struct mcp *);
-       const struct mcp_device_id *id_table;
 };
 
 int mcp_driver_register(struct mcp_driver *);
@@ -67,6 +64,9 @@ void mcp_driver_unregister(struct mcp_driver *);
 #define mcp_get_drvdata(mcp)   dev_get_drvdata(&(mcp)->attached_device)
 #define mcp_set_drvdata(mcp,d) dev_set_drvdata(&(mcp)->attached_device, d)
 
-#define mcp_priv(mcp)          ((void *)((mcp)+1))
+static inline void *mcp_priv(struct mcp *mcp)
+{
+       return mcp + 1;
+}
 
 #endif
index 2463c26..9bc9ac6 100644 (file)
@@ -187,8 +187,10 @@ struct twl6040 {
        int rev;
        u8 vibra_ctrl_cache[2];
 
+       /* PLL configuration */
        int pll;
        unsigned int sysclk;
+       unsigned int mclk;
 
        unsigned int irq;
        unsigned int irq_base;
index bc19e5f..4321f04 100644 (file)
 #define UCB_MODE_DYN_VFLAG_ENA (1 << 12)
 #define UCB_MODE_AUD_OFF_CAN   (1 << 13)
 
-struct ucb1x00_plat_data {
-       int             gpio_base;
-};
 
 struct ucb1x00_irq {
        void *devid;
@@ -119,7 +116,7 @@ struct ucb1x00 {
        unsigned int            irq;
        struct semaphore        adc_sem;
        spinlock_t              io_lock;
-       const struct mcp_device_id *id;
+       u16                     id;
        u16                     io_dir;
        u16                     io_out;
        u16                     adc_cr;
index 9f22ba5..19a41d1 100644 (file)
@@ -217,6 +217,7 @@ struct mmc_card {
 #define MMC_CARD_SDXC          (1<<6)          /* card is SDXC */
 #define MMC_CARD_REMOVED       (1<<7)          /* card has been removed */
 #define MMC_STATE_HIGHSPEED_200        (1<<8)          /* card is in HS200 mode */
+#define MMC_STATE_SLEEP                (1<<9)          /* card is in sleep state */
        unsigned int            quirks;         /* card quirks */
 #define MMC_QUIRK_LENIENT_FN0  (1<<0)          /* allow SDIO FN0 writes outside of the VS CCCR range */
 #define MMC_QUIRK_BLKSZ_FOR_BYTE_MODE (1<<1)   /* use func->cur_blksize */
@@ -382,6 +383,7 @@ static inline void __maybe_unused remove_quirk(struct mmc_card *card, int data)
 #define mmc_sd_card_uhs(c)     ((c)->state & MMC_STATE_ULTRAHIGHSPEED)
 #define mmc_card_ext_capacity(c) ((c)->state & MMC_CARD_SDXC)
 #define mmc_card_removed(c)    ((c) && ((c)->state & MMC_CARD_REMOVED))
+#define mmc_card_is_sleep(c)   ((c)->state & MMC_STATE_SLEEP)
 
 #define mmc_card_set_present(c)        ((c)->state |= MMC_STATE_PRESENT)
 #define mmc_card_set_readonly(c) ((c)->state |= MMC_STATE_READONLY)
@@ -393,7 +395,9 @@ static inline void __maybe_unused remove_quirk(struct mmc_card *card, int data)
 #define mmc_sd_card_set_uhs(c) ((c)->state |= MMC_STATE_ULTRAHIGHSPEED)
 #define mmc_card_set_ext_capacity(c) ((c)->state |= MMC_CARD_SDXC)
 #define mmc_card_set_removed(c) ((c)->state |= MMC_CARD_REMOVED)
+#define mmc_card_set_sleep(c)  ((c)->state |= MMC_STATE_SLEEP)
 
+#define mmc_card_clr_sleep(c)  ((c)->state &= ~MMC_STATE_SLEEP)
 /*
  * Quirk add/remove for MMC products.
  */
index e8779c6..aae5d1f 100644 (file)
@@ -14,6 +14,8 @@
 #ifndef LINUX_MMC_DW_MMC_H
 #define LINUX_MMC_DW_MMC_H
 
+#include <linux/scatterlist.h>
+
 #define MAX_MCI_SLOTS  2
 
 enum dw_mci_state {
@@ -40,7 +42,7 @@ struct mmc_data;
  * @lock: Spinlock protecting the queue and associated data.
  * @regs: Pointer to MMIO registers.
  * @sg: Scatterlist entry currently being processed by PIO code, if any.
- * @pio_offset: Offset into the current scatterlist entry.
+ * @sg_miter: PIO mapping scatterlist iterator.
  * @cur_slot: The slot which is currently using the controller.
  * @mrq: The request currently being processed on @cur_slot,
  *     or NULL if the controller is idle.
@@ -115,7 +117,7 @@ struct dw_mci {
        void __iomem            *regs;
 
        struct scatterlist      *sg;
-       unsigned int            pio_offset;
+       struct sg_mapping_iter  sg_miter;
 
        struct dw_mci_slot      *cur_slot;
        struct mmc_request      *mrq;
index 0beba1e..ee2b036 100644 (file)
@@ -257,6 +257,7 @@ struct mmc_host {
 #define MMC_CAP2_HS200_1_2V_SDR        (1 << 6)        /* can support */
 #define MMC_CAP2_HS200         (MMC_CAP2_HS200_1_8V_SDR | \
                                 MMC_CAP2_HS200_1_2V_SDR)
+#define MMC_CAP2_BROKEN_VOLTAGE        (1 << 7)        /* Use the broken voltage */
 
        mmc_pm_flag_t           pm_caps;        /* supported pm features */
        unsigned int        power_notify_type;
@@ -444,4 +445,23 @@ static inline int mmc_boot_partition_access(struct mmc_host *host)
        return !(host->caps2 & MMC_CAP2_BOOTPART_NOACC);
 }
 
+#ifdef CONFIG_MMC_CLKGATE
+void mmc_host_clk_hold(struct mmc_host *host);
+void mmc_host_clk_release(struct mmc_host *host);
+unsigned int mmc_host_clk_rate(struct mmc_host *host);
+
+#else
+static inline void mmc_host_clk_hold(struct mmc_host *host)
+{
+}
+
+static inline void mmc_host_clk_release(struct mmc_host *host)
+{
+}
+
+static inline unsigned int mmc_host_clk_rate(struct mmc_host *host)
+{
+       return host->ios.clock;
+}
+#endif
 #endif /* LINUX_MMC_HOST_H */
index b29e7f6..83ac071 100644 (file)
@@ -436,17 +436,6 @@ struct spi_device_id {
                        __attribute__((aligned(sizeof(kernel_ulong_t))));
 };
 
-/* mcp */
-
-#define MCP_NAME_SIZE  20
-#define MCP_MODULE_PREFIX "mcp:"
-
-struct mcp_device_id {
-       char name[MCP_NAME_SIZE];
-       kernel_ulong_t driver_data      /* Data private to the driver */
-                       __attribute__((aligned(sizeof(kernel_ulong_t))));
-};
-
 /* dmi */
 enum dmi_field {
        DMI_NONE,
index 06f8899..d02cca6 100644 (file)
@@ -57,8 +57,6 @@ struct gcry_mpi {
 
 typedef struct gcry_mpi *MPI;
 
-#define MPI_NULL NULL
-
 #define mpi_get_nlimbs(a)     ((a)->nlimbs)
 #define mpi_is_neg(a)        ((a)->sign)
 
index 1a81fde..d43dc25 100644 (file)
@@ -427,9 +427,7 @@ static inline int mtd_is_locked(struct mtd_info *mtd, loff_t ofs, uint64_t len)
 
 static inline int mtd_suspend(struct mtd_info *mtd)
 {
-       if (!mtd->suspend)
-               return -EOPNOTSUPP;
-       return mtd->suspend(mtd);
+       return mtd->suspend ? mtd->suspend(mtd) : 0;
 }
 
 static inline void mtd_resume(struct mtd_info *mtd)
@@ -441,7 +439,7 @@ static inline void mtd_resume(struct mtd_info *mtd)
 static inline int mtd_block_isbad(struct mtd_info *mtd, loff_t ofs)
 {
        if (!mtd->block_isbad)
-               return -EOPNOTSUPP;
+               return 0;
        return mtd->block_isbad(mtd, ofs);
 }
 
index 0885561..abb2776 100644 (file)
@@ -587,6 +587,7 @@ struct hw_perf_event {
        u64                             sample_period;
        u64                             last_period;
        local64_t                       period_left;
+       u64                             interrupts_seq;
        u64                             interrupts;
 
        u64                             freq_time_stamp;
index e5bbcba..4d99e4e 100644 (file)
@@ -110,7 +110,19 @@ static inline void pm_qos_remove_request(struct pm_qos_request *req)
                        { return; }
 
 static inline int pm_qos_request(int pm_qos_class)
-                       { return 0; }
+{
+       switch (pm_qos_class) {
+       case PM_QOS_CPU_DMA_LATENCY:
+               return PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE;
+       case PM_QOS_NETWORK_LATENCY:
+               return PM_QOS_NETWORK_LAT_DEFAULT_VALUE;
+       case PM_QOS_NETWORK_THROUGHPUT:
+               return PM_QOS_NETWORK_THROUGHPUT_DEFAULT_VALUE;
+       default:
+               return PM_QOS_DEFAULT_VALUE;
+       }
+}
+
 static inline int pm_qos_add_notifier(int pm_qos_class,
                                      struct notifier_block *notifier)
                        { return 0; }
index ef35bb7..26a8a4e 100644 (file)
@@ -81,7 +81,11 @@ void prop_inc_percpu(struct prop_descriptor *pd, struct prop_local_percpu *pl)
  * Limit the time part in order to ensure there are some bits left for the
  * cycle counter and fraction multiply.
  */
+#if BITS_PER_LONG == 32
 #define PROP_MAX_SHIFT (3*BITS_PER_LONG/4)
+#else
+#define PROP_MAX_SHIFT (BITS_PER_LONG/2)
+#endif
 
 #define PROP_FRAC_SHIFT                (BITS_PER_LONG - PROP_MAX_SHIFT - 1)
 #define PROP_FRAC_BASE         (1UL << PROP_FRAC_SHIFT)
index 2234985..7d379a6 100644 (file)
@@ -2259,6 +2259,12 @@ static inline void mmdrop(struct mm_struct * mm)
 extern void mmput(struct mm_struct *);
 /* Grab a reference to a task's mm, if it is not already going away */
 extern struct mm_struct *get_task_mm(struct task_struct *task);
+/*
+ * Grab a reference to a task's mm, if it is not already going away
+ * and ptrace_may_access with the mode parameter passed to it
+ * succeeds.
+ */
+extern struct mm_struct *mm_access(struct task_struct *task, unsigned int mode);
 /* Remove the current tasks stale references to the old mm_struct */
 extern void mm_release(struct task_struct *, struct mm_struct *);
 /* Allocate a new mm structure and copy contents from tsk->mm */
index 8cd7fe5..425450b 100644 (file)
@@ -70,6 +70,7 @@ struct sh_dmae_pdata {
        unsigned int needs_tend_set:1;
        unsigned int no_dmars:1;
        unsigned int chclr_present:1;
+       unsigned int slave_only:1;
 };
 
 /* DMA register */
diff --git a/include/linux/sysdev.h b/include/linux/sysdev.h
deleted file mode 100644 (file)
index 20f63d3..0000000
+++ /dev/null
@@ -1,164 +0,0 @@
-/**
- * System devices follow a slightly different driver model. 
- * They don't need to do dynammic driver binding, can't be probed, 
- * and don't reside on any type of peripheral bus. 
- * So, we represent and treat them a little differently.
- * 
- * We still have a notion of a driver for a system device, because we still
- * want to perform basic operations on these devices. 
- *
- * We also support auxiliary drivers binding to devices of a certain class.
- * 
- * This allows configurable drivers to register themselves for devices of
- * a certain type. And, it allows class definitions to reside in generic
- * code while arch-specific code can register specific drivers.
- *
- * Auxiliary drivers registered with a NULL cls are registered as drivers
- * for all system devices, and get notification calls for each device. 
- */
-
-
-#ifndef _SYSDEV_H_
-#define _SYSDEV_H_
-
-#include <linux/kobject.h>
-#include <linux/pm.h>
-
-
-struct sys_device;
-struct sysdev_class_attribute;
-
-struct sysdev_class {
-       const char *name;
-       struct list_head        drivers;
-       struct sysdev_class_attribute **attrs;
-       struct kset             kset;
-};
-
-struct sysdev_class_attribute {
-       struct attribute attr;
-       ssize_t (*show)(struct sysdev_class *, struct sysdev_class_attribute *,
-                       char *);
-       ssize_t (*store)(struct sysdev_class *, struct sysdev_class_attribute *,
-                        const char *, size_t);
-};
-
-#define _SYSDEV_CLASS_ATTR(_name,_mode,_show,_store)           \
-{                                                              \
-       .attr = {.name = __stringify(_name), .mode = _mode },   \
-       .show   = _show,                                        \
-       .store  = _store,                                       \
-}
-
-#define SYSDEV_CLASS_ATTR(_name,_mode,_show,_store)            \
-       struct sysdev_class_attribute attr_##_name =            \
-               _SYSDEV_CLASS_ATTR(_name,_mode,_show,_store)
-
-
-extern int sysdev_class_register(struct sysdev_class *);
-extern void sysdev_class_unregister(struct sysdev_class *);
-
-extern int sysdev_class_create_file(struct sysdev_class *,
-       struct sysdev_class_attribute *);
-extern void sysdev_class_remove_file(struct sysdev_class *,
-       struct sysdev_class_attribute *);
-/**
- * Auxiliary system device drivers.
- */
-
-struct sysdev_driver {
-       struct list_head        entry;
-       int     (*add)(struct sys_device *);
-       int     (*remove)(struct sys_device *);
-};
-
-
-extern int sysdev_driver_register(struct sysdev_class *, struct sysdev_driver *);
-extern void sysdev_driver_unregister(struct sysdev_class *, struct sysdev_driver *);
-
-
-/**
- * sys_devices can be simplified a lot from regular devices, because they're
- * simply not as versatile. 
- */
-
-struct sys_device {
-       u32             id;
-       struct sysdev_class     * cls;
-       struct kobject          kobj;
-};
-
-extern int sysdev_register(struct sys_device *);
-extern void sysdev_unregister(struct sys_device *);
-
-
-struct sysdev_attribute { 
-       struct attribute        attr;
-       ssize_t (*show)(struct sys_device *, struct sysdev_attribute *, char *);
-       ssize_t (*store)(struct sys_device *, struct sysdev_attribute *,
-                        const char *, size_t);
-};
-
-
-#define _SYSDEV_ATTR(_name, _mode, _show, _store)              \
-{                                                              \
-       .attr = { .name = __stringify(_name), .mode = _mode },  \
-       .show   = _show,                                        \
-       .store  = _store,                                       \
-}
-
-#define SYSDEV_ATTR(_name, _mode, _show, _store)               \
-       struct sysdev_attribute attr_##_name =                  \
-               _SYSDEV_ATTR(_name, _mode, _show, _store);
-
-extern int sysdev_create_file(struct sys_device *, struct sysdev_attribute *);
-extern void sysdev_remove_file(struct sys_device *, struct sysdev_attribute *);
-
-/* Create/remove NULL terminated attribute list */
-static inline int
-sysdev_create_files(struct sys_device *d, struct sysdev_attribute **a)
-{
-       return sysfs_create_files(&d->kobj, (const struct attribute **)a);
-}
-
-static inline void
-sysdev_remove_files(struct sys_device *d, struct sysdev_attribute **a)
-{
-       return sysfs_remove_files(&d->kobj, (const struct attribute **)a);
-}
-
-struct sysdev_ext_attribute {
-       struct sysdev_attribute attr;
-       void *var;
-};
-
-/*
- * Support for simple variable sysdev attributes.
- * The pointer to the variable is stored in a sysdev_ext_attribute
- */
-
-/* Add more types as needed */
-
-extern ssize_t sysdev_show_ulong(struct sys_device *, struct sysdev_attribute *,
-                               char *);
-extern ssize_t sysdev_store_ulong(struct sys_device *,
-                       struct sysdev_attribute *, const char *, size_t);
-extern ssize_t sysdev_show_int(struct sys_device *, struct sysdev_attribute *,
-                               char *);
-extern ssize_t sysdev_store_int(struct sys_device *,
-                       struct sysdev_attribute *, const char *, size_t);
-
-#define _SYSDEV_ULONG_ATTR(_name, _mode, _var)                         \
-       { _SYSDEV_ATTR(_name, _mode, sysdev_show_ulong, sysdev_store_ulong), \
-         &(_var) }
-#define SYSDEV_ULONG_ATTR(_name, _mode, _var)                  \
-       struct sysdev_ext_attribute attr_##_name =              \
-               _SYSDEV_ULONG_ATTR(_name, _mode, _var);
-#define _SYSDEV_INT_ATTR(_name, _mode, _var)                           \
-       { _SYSDEV_ATTR(_name, _mode, sysdev_show_int, sysdev_store_int), \
-         &(_var) }
-#define SYSDEV_INT_ATTR(_name, _mode, _var)                    \
-       struct sysdev_ext_attribute attr_##_name =              \
-               _SYSDEV_INT_ATTR(_name, _mode, _var);
-
-#endif /* _SYSDEV_H_ */
index 61b2905..3b6f628 100644 (file)
@@ -589,7 +589,7 @@ static inline int usb_endpoint_is_isoc_out(
  */
 static inline int usb_endpoint_maxp(const struct usb_endpoint_descriptor *epd)
 {
-       return le16_to_cpu(epd->wMaxPacketSize);
+       return __le16_to_cpu(epd->wMaxPacketSize);
 }
 
 /*-------------------------------------------------------------------------*/
diff --git a/include/linux/usb/langwell_otg.h b/include/linux/usb/langwell_otg.h
deleted file mode 100644 (file)
index 51f17b1..0000000
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * Intel Langwell USB OTG transceiver driver
- * Copyright (C) 2008 - 2010, Intel Corporation.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-
-#ifndef __LANGWELL_OTG_H
-#define __LANGWELL_OTG_H
-
-#include <linux/usb/intel_mid_otg.h>
-
-#define CI_USBCMD              0x30
-#      define USBCMD_RST               BIT(1)
-#      define USBCMD_RS                BIT(0)
-#define CI_USBSTS              0x34
-#      define USBSTS_SLI               BIT(8)
-#      define USBSTS_URI               BIT(6)
-#      define USBSTS_PCI               BIT(2)
-#define CI_PORTSC1             0x74
-#      define PORTSC_PP                BIT(12)
-#      define PORTSC_LS                (BIT(11) | BIT(10))
-#      define PORTSC_SUSP              BIT(7)
-#      define PORTSC_CCS               BIT(0)
-#define CI_HOSTPC1             0xb4
-#      define HOSTPC1_PHCD             BIT(22)
-#define CI_OTGSC               0xf4
-#      define OTGSC_DPIE               BIT(30)
-#      define OTGSC_1MSE               BIT(29)
-#      define OTGSC_BSEIE              BIT(28)
-#      define OTGSC_BSVIE              BIT(27)
-#      define OTGSC_ASVIE              BIT(26)
-#      define OTGSC_AVVIE              BIT(25)
-#      define OTGSC_IDIE               BIT(24)
-#      define OTGSC_DPIS               BIT(22)
-#      define OTGSC_1MSS               BIT(21)
-#      define OTGSC_BSEIS              BIT(20)
-#      define OTGSC_BSVIS              BIT(19)
-#      define OTGSC_ASVIS              BIT(18)
-#      define OTGSC_AVVIS              BIT(17)
-#      define OTGSC_IDIS               BIT(16)
-#      define OTGSC_DPS                BIT(14)
-#      define OTGSC_1MST               BIT(13)
-#      define OTGSC_BSE                BIT(12)
-#      define OTGSC_BSV                BIT(11)
-#      define OTGSC_ASV                BIT(10)
-#      define OTGSC_AVV                BIT(9)
-#      define OTGSC_ID                 BIT(8)
-#      define OTGSC_HABA               BIT(7)
-#      define OTGSC_HADP               BIT(6)
-#      define OTGSC_IDPU               BIT(5)
-#      define OTGSC_DP                 BIT(4)
-#      define OTGSC_OT                 BIT(3)
-#      define OTGSC_HAAR               BIT(2)
-#      define OTGSC_VC                 BIT(1)
-#      define OTGSC_VD                 BIT(0)
-#      define OTGSC_INTEN_MASK         (0x7f << 24)
-#      define OTGSC_INT_MASK           (0x5f << 24)
-#      define OTGSC_INTSTS_MASK        (0x7f << 16)
-#define CI_USBMODE             0xf8
-#      define USBMODE_CM               (BIT(1) | BIT(0))
-#      define USBMODE_IDLE             0
-#      define USBMODE_DEVICE           0x2
-#      define USBMODE_HOST             0x3
-#define USBCFG_ADDR                    0xff10801c
-#define USBCFG_LEN                     4
-#      define USBCFG_VBUSVAL           BIT(14)
-#      define USBCFG_AVALID            BIT(13)
-#      define USBCFG_BVALID            BIT(12)
-#      define USBCFG_SESEND            BIT(11)
-
-#define INTR_DUMMY_MASK (USBSTS_SLI | USBSTS_URI | USBSTS_PCI)
-
-enum langwell_otg_timer_type {
-       TA_WAIT_VRISE_TMR,
-       TA_WAIT_BCON_TMR,
-       TA_AIDL_BDIS_TMR,
-       TB_ASE0_BRST_TMR,
-       TB_SE0_SRP_TMR,
-       TB_SRP_INIT_TMR,
-       TB_SRP_FAIL_TMR,
-       TB_BUS_SUSPEND_TMR
-};
-
-#define TA_WAIT_VRISE  100
-#define TA_WAIT_BCON   30000
-#define TA_AIDL_BDIS   15000
-#define TB_ASE0_BRST   5000
-#define TB_SE0_SRP     2
-#define TB_SRP_INIT    100
-#define TB_SRP_FAIL    5500
-#define TB_BUS_SUSPEND 500
-
-struct langwell_otg_timer {
-       unsigned long expires;  /* Number of count increase to timeout */
-       unsigned long count;    /* Tick counter */
-       void (*function)(unsigned long);        /* Timeout function */
-       unsigned long data;     /* Data passed to function */
-       struct list_head list;
-};
-
-struct langwell_otg {
-       struct intel_mid_otg_xceiv      iotg;
-       struct device                   *dev;
-
-       void __iomem                    *usbcfg;        /* SCCBUSB config Reg */
-
-       unsigned                        region;
-       unsigned                        cfg_region;
-
-       struct work_struct              work;
-       struct workqueue_struct         *qwork;
-       struct timer_list               hsm_timer;
-
-       spinlock_t                      lock;
-       spinlock_t                      wq_lock;
-
-       struct notifier_block           iotg_notifier;
-};
-
-static inline
-struct langwell_otg *mid_xceiv_to_lnw(struct intel_mid_otg_xceiv *iotg)
-{
-       return container_of(iotg, struct langwell_otg, iotg);
-}
-
-#endif /* __LANGWELL_OTG_H__ */
index 9b58243..6c469db 100644 (file)
@@ -93,6 +93,16 @@ static inline void flowi4_init_output(struct flowi4 *fl4, int oif,
        fl4->fl4_dport = dport;
        fl4->fl4_sport = sport;
 }
+
+/* Reset some input parameters after previous lookup */
+static inline void flowi4_update_output(struct flowi4 *fl4, int oif, __u8 tos,
+                                       __be32 daddr, __be32 saddr)
+{
+       fl4->flowi4_oif = oif;
+       fl4->flowi4_tos = tos;
+       fl4->daddr = daddr;
+       fl4->saddr = saddr;
+}
                                      
 
 struct flowi6 {
index 3419bf5..d55f434 100644 (file)
@@ -41,6 +41,7 @@ static inline void *net_generic(const struct net *net, int id)
        ptr = ng->ptr[id - 1];
        rcu_read_unlock();
 
+       BUG_ON(!ptr);
        return ptr;
 }
 #endif
index 7b2d431..d58fdec 100644 (file)
@@ -37,19 +37,51 @@ extern int net_prio_subsys_id;
 
 extern void sock_update_netprioidx(struct sock *sk);
 
-static inline struct cgroup_netprio_state
-               *task_netprio_state(struct task_struct *p)
+#if IS_BUILTIN(CONFIG_NETPRIO_CGROUP)
+
+static inline u32 task_netprioidx(struct task_struct *p)
 {
-#if IS_ENABLED(CONFIG_NETPRIO_CGROUP)
-       return container_of(task_subsys_state(p, net_prio_subsys_id),
-                           struct cgroup_netprio_state, css);
-#else
-       return NULL;
-#endif
+       struct cgroup_netprio_state *state;
+       u32 idx;
+
+       rcu_read_lock();
+       state = container_of(task_subsys_state(p, net_prio_subsys_id),
+                            struct cgroup_netprio_state, css);
+       idx = state->prioidx;
+       rcu_read_unlock();
+       return idx;
+}
+
+#elif IS_MODULE(CONFIG_NETPRIO_CGROUP)
+
+static inline u32 task_netprioidx(struct task_struct *p)
+{
+       struct cgroup_netprio_state *state;
+       int subsys_id;
+       u32 idx = 0;
+
+       rcu_read_lock();
+       subsys_id = rcu_dereference_index_check(net_prio_subsys_id,
+                                               rcu_read_lock_held());
+       if (subsys_id >= 0) {
+               state = container_of(task_subsys_state(p, subsys_id),
+                                    struct cgroup_netprio_state, css);
+               idx = state->prioidx;
+       }
+       rcu_read_unlock();
+       return idx;
 }
 
 #else
 
+static inline u32 task_netprioidx(struct task_struct *p)
+{
+       return 0;
+}
+
+#endif /* CONFIG_NETPRIO_CGROUP */
+
+#else
 #define sock_update_netprioidx(sk)
 #endif
 
index 91855d1..b1c0d5b 100644 (file)
@@ -270,6 +270,7 @@ static inline struct rtable *ip_route_connect(struct flowi4 *fl4,
                if (IS_ERR(rt))
                        return rt;
                ip_rt_put(rt);
+               flowi4_update_output(fl4, oif, tos, fl4->daddr, fl4->saddr);
        }
        security_sk_classify_flow(sk, flowi4_to_flowi(fl4));
        return ip_route_output_flow(net, fl4, sk);
@@ -284,6 +285,9 @@ static inline struct rtable *ip_route_newports(struct flowi4 *fl4, struct rtable
                fl4->fl4_dport = dport;
                fl4->fl4_sport = sport;
                ip_rt_put(rt);
+               flowi4_update_output(fl4, sk->sk_bound_dev_if,
+                                    RT_CONN_FLAGS(sk), fl4->daddr,
+                                    fl4->saddr);
                security_sk_classify_flow(sk, flowi4_to_flowi(fl4));
                return ip_route_output_flow(sock_net(sk), fl4, sk);
        }
index f6bb08b..55ce96b 100644 (file)
@@ -220,9 +220,16 @@ struct tcf_proto {
 
 struct qdisc_skb_cb {
        unsigned int            pkt_len;
-       long                    data[];
+       unsigned char           data[24];
 };
 
+static inline void qdisc_cb_private_validate(const struct sk_buff *skb, int sz)
+{
+       struct qdisc_skb_cb *qcb;
+       BUILD_BUG_ON(sizeof(skb->cb) < sizeof(unsigned int) + sz);
+       BUILD_BUG_ON(sizeof(qcb->data) < sz);
+}
+
 static inline int qdisc_qlen(const struct Qdisc *q)
 {
        return q->q.qlen;
index 4c69ac1..91c1c8b 100644 (file)
@@ -55,6 +55,7 @@
 #include <linux/uaccess.h>
 #include <linux/memcontrol.h>
 #include <linux/res_counter.h>
+#include <linux/jump_label.h>
 
 #include <linux/filter.h>
 #include <linux/rculist_nulls.h>
index 0118ea9..42c29bf 100644 (file)
@@ -273,6 +273,14 @@ static inline int between(__u32 seq1, __u32 seq2, __u32 seq3)
        return seq3 - seq2 >= seq1 - seq2;
 }
 
+static inline bool tcp_out_of_memory(struct sock *sk)
+{
+       if (sk->sk_wmem_queued > SOCK_MIN_SNDBUF &&
+           sk_memory_allocated(sk) > sk_prot_mem_limits(sk, 2))
+               return true;
+       return false;
+}
+
 static inline bool tcp_too_many_orphans(struct sock *sk, int shift)
 {
        struct percpu_counter *ocp = sk->sk_prot->orphan_count;
@@ -283,13 +291,11 @@ static inline bool tcp_too_many_orphans(struct sock *sk, int shift)
                if (orphans << shift > sysctl_tcp_max_orphans)
                        return true;
        }
-
-       if (sk->sk_wmem_queued > SOCK_MIN_SNDBUF &&
-           sk_memory_allocated(sk) > sk_prot_mem_limits(sk, 2))
-               return true;
        return false;
 }
 
+extern bool tcp_check_oom(struct sock *sk, int shift);
+
 /* syncookies: remember time of last synqueue overflow */
 static inline void tcp_synq_overflow(struct sock *sk)
 {
@@ -311,6 +317,8 @@ extern struct proto tcp_prot;
 #define TCP_ADD_STATS_USER(net, field, val) SNMP_ADD_STATS_USER((net)->mib.tcp_statistics, field, val)
 #define TCP_ADD_STATS(net, field, val) SNMP_ADD_STATS((net)->mib.tcp_statistics, field, val)
 
+extern void tcp_init_mem(struct net *net);
+
 extern void tcp_v4_err(struct sk_buff *skb, u32);
 
 extern void tcp_shutdown (struct sock *sk, int how);
index 5ab255f..cea1b54 100644 (file)
@@ -417,6 +417,7 @@ static inline int __snd_bug_on(int cond)
 #define gameport_get_port_data(gp) (gp)->port_data
 #endif
 
+#ifdef CONFIG_PCI
 /* PCI quirk list helper */
 struct snd_pci_quirk {
        unsigned short subvendor;       /* PCI subvendor ID */
@@ -456,5 +457,6 @@ snd_pci_quirk_lookup(struct pci_dev *pci, const struct snd_pci_quirk *list);
 const struct snd_pci_quirk *
 snd_pci_quirk_lookup_id(u16 vendor, u16 device,
                        const struct snd_pci_quirk *list);
+#endif
 
 #endif /* __SOUND_CORE_H */
index 4866499..e5e6ff9 100644 (file)
@@ -59,7 +59,7 @@ int   transport_set_vpd_ident_type(struct t10_vpd *, unsigned char *);
 int    transport_set_vpd_ident(struct t10_vpd *, unsigned char *);
 
 /* core helpers also used by command snooping in pscsi */
-void   *transport_kmap_first_data_page(struct se_cmd *);
-void   transport_kunmap_first_data_page(struct se_cmd *);
+void   *transport_kmap_data_sg(struct se_cmd *);
+void   transport_kunmap_data_sg(struct se_cmd *);
 
 #endif /* TARGET_CORE_BACKEND_H */
index daf532b..dc4e345 100644 (file)
@@ -582,6 +582,7 @@ struct se_cmd {
 
        struct scatterlist      *t_data_sg;
        unsigned int            t_data_nents;
+       void                    *t_data_vmap;
        struct scatterlist      *t_bidi_data_sg;
        unsigned int            t_bidi_data_nents;
 
index 523e8bc..d36fad3 100644 (file)
@@ -114,7 +114,7 @@ void        transport_init_se_cmd(struct se_cmd *, struct target_core_fabric_ops *,
                struct se_session *, u32, int, int, unsigned char *);
 int    transport_lookup_cmd_lun(struct se_cmd *, u32);
 int    transport_generic_allocate_tasks(struct se_cmd *, unsigned char *);
-int    target_submit_cmd(struct se_cmd *, struct se_session *, unsigned char *,
+void   target_submit_cmd(struct se_cmd *, struct se_session *, unsigned char *,
                unsigned char *, u32, u32, int, int, int);
 int    transport_handle_cdb_direct(struct se_cmd *);
 int    transport_generic_handle_cdb_map(struct se_cmd *);
index 8588a89..5973410 100644 (file)
@@ -47,7 +47,10 @@ DECLARE_EVENT_CLASS(writeback_work_class,
                __field(int, reason)
        ),
        TP_fast_assign(
-               strncpy(__entry->name, dev_name(bdi->dev), 32);
+               struct device *dev = bdi->dev;
+               if (!dev)
+                       dev = default_backing_dev_info.dev;
+               strncpy(__entry->name, dev_name(dev), 32);
                __entry->nr_pages = work->nr_pages;
                __entry->sb_dev = work->sb ? work->sb->s_dev : 0;
                __entry->sync_mode = work->sync_mode;
@@ -426,7 +429,7 @@ DECLARE_EVENT_CLASS(writeback_single_inode_template,
 
        TP_fast_assign(
                strncpy(__entry->name,
-                       dev_name(inode->i_mapping->backing_dev_info->dev), 32);
+                       dev_name(inode_to_bdi(inode)->dev), 32);
                __entry->ino            = inode->i_ino;
                __entry->state          = inode->i_state;
                __entry->dirtied_when   = inode->dirtied_when;
index 062b3b2..483f67c 100644 (file)
@@ -590,6 +590,11 @@ struct omap_dss_device {
        int (*get_backlight)(struct omap_dss_device *dssdev);
 };
 
+struct omap_dss_hdmi_data
+{
+       int hpd_gpio;
+};
+
 struct omap_dss_driver {
        struct device_driver driver;
 
index 32b48c8..1b5c081 100644 (file)
@@ -2300,7 +2300,10 @@ do {                                     \
        return div64_u64(dividend, divisor);
 }
 
-static void perf_adjust_period(struct perf_event *event, u64 nsec, u64 count)
+static DEFINE_PER_CPU(int, perf_throttled_count);
+static DEFINE_PER_CPU(u64, perf_throttled_seq);
+
+static void perf_adjust_period(struct perf_event *event, u64 nsec, u64 count, bool disable)
 {
        struct hw_perf_event *hwc = &event->hw;
        s64 period, sample_period;
@@ -2319,22 +2322,40 @@ static void perf_adjust_period(struct perf_event *event, u64 nsec, u64 count)
        hwc->sample_period = sample_period;
 
        if (local64_read(&hwc->period_left) > 8*sample_period) {
-               event->pmu->stop(event, PERF_EF_UPDATE);
+               if (disable)
+                       event->pmu->stop(event, PERF_EF_UPDATE);
+
                local64_set(&hwc->period_left, 0);
-               event->pmu->start(event, PERF_EF_RELOAD);
+
+               if (disable)
+                       event->pmu->start(event, PERF_EF_RELOAD);
        }
 }
 
-static void perf_ctx_adjust_freq(struct perf_event_context *ctx, u64 period)
+/*
+ * combine freq adjustment with unthrottling to avoid two passes over the
+ * events. At the same time, make sure, having freq events does not change
+ * the rate of unthrottling as that would introduce bias.
+ */
+static void perf_adjust_freq_unthr_context(struct perf_event_context *ctx,
+                                          int needs_unthr)
 {
        struct perf_event *event;
        struct hw_perf_event *hwc;
-       u64 interrupts, now;
+       u64 now, period = TICK_NSEC;
        s64 delta;
 
-       if (!ctx->nr_freq)
+       /*
+        * only need to iterate over all events iff:
+        * - context have events in frequency mode (needs freq adjust)
+        * - there are events to unthrottle on this cpu
+        */
+       if (!(ctx->nr_freq || needs_unthr))
                return;
 
+       raw_spin_lock(&ctx->lock);
+       perf_pmu_disable(ctx->pmu);
+
        list_for_each_entry_rcu(event, &ctx->event_list, event_entry) {
                if (event->state != PERF_EVENT_STATE_ACTIVE)
                        continue;
@@ -2344,13 +2365,8 @@ static void perf_ctx_adjust_freq(struct perf_event_context *ctx, u64 period)
 
                hwc = &event->hw;
 
-               interrupts = hwc->interrupts;
-               hwc->interrupts = 0;
-
-               /*
-                * unthrottle events on the tick
-                */
-               if (interrupts == MAX_INTERRUPTS) {
+               if (needs_unthr && hwc->interrupts == MAX_INTERRUPTS) {
+                       hwc->interrupts = 0;
                        perf_log_throttle(event, 1);
                        event->pmu->start(event, 0);
                }
@@ -2358,14 +2374,30 @@ static void perf_ctx_adjust_freq(struct perf_event_context *ctx, u64 period)
                if (!event->attr.freq || !event->attr.sample_freq)
                        continue;
 
-               event->pmu->read(event);
+               /*
+                * stop the event and update event->count
+                */
+               event->pmu->stop(event, PERF_EF_UPDATE);
+
                now = local64_read(&event->count);
                delta = now - hwc->freq_count_stamp;
                hwc->freq_count_stamp = now;
 
+               /*
+                * restart the event
+                * reload only if value has changed
+                * we have stopped the event so tell that
+                * to perf_adjust_period() to avoid stopping it
+                * twice.
+                */
                if (delta > 0)
-                       perf_adjust_period(event, period, delta);
+                       perf_adjust_period(event, period, delta, false);
+
+               event->pmu->start(event, delta > 0 ? PERF_EF_RELOAD : 0);
        }
+
+       perf_pmu_enable(ctx->pmu);
+       raw_spin_unlock(&ctx->lock);
 }
 
 /*
@@ -2388,16 +2420,13 @@ static void rotate_ctx(struct perf_event_context *ctx)
  */
 static void perf_rotate_context(struct perf_cpu_context *cpuctx)
 {
-       u64 interval = (u64)cpuctx->jiffies_interval * TICK_NSEC;
        struct perf_event_context *ctx = NULL;
-       int rotate = 0, remove = 1, freq = 0;
+       int rotate = 0, remove = 1;
 
        if (cpuctx->ctx.nr_events) {
                remove = 0;
                if (cpuctx->ctx.nr_events != cpuctx->ctx.nr_active)
                        rotate = 1;
-               if (cpuctx->ctx.nr_freq)
-                       freq = 1;
        }
 
        ctx = cpuctx->task_ctx;
@@ -2405,37 +2434,26 @@ static void perf_rotate_context(struct perf_cpu_context *cpuctx)
                remove = 0;
                if (ctx->nr_events != ctx->nr_active)
                        rotate = 1;
-               if (ctx->nr_freq)
-                       freq = 1;
        }
 
-       if (!rotate && !freq)
+       if (!rotate)
                goto done;
 
        perf_ctx_lock(cpuctx, cpuctx->task_ctx);
        perf_pmu_disable(cpuctx->ctx.pmu);
 
-       if (freq) {
-               perf_ctx_adjust_freq(&cpuctx->ctx, interval);
-               if (ctx)
-                       perf_ctx_adjust_freq(ctx, interval);
-       }
-
-       if (rotate) {
-               cpu_ctx_sched_out(cpuctx, EVENT_FLEXIBLE);
-               if (ctx)
-                       ctx_sched_out(ctx, cpuctx, EVENT_FLEXIBLE);
+       cpu_ctx_sched_out(cpuctx, EVENT_FLEXIBLE);
+       if (ctx)
+               ctx_sched_out(ctx, cpuctx, EVENT_FLEXIBLE);
 
-               rotate_ctx(&cpuctx->ctx);
-               if (ctx)
-                       rotate_ctx(ctx);
+       rotate_ctx(&cpuctx->ctx);
+       if (ctx)
+               rotate_ctx(ctx);
 
-               perf_event_sched_in(cpuctx, ctx, current);
-       }
+       perf_event_sched_in(cpuctx, ctx, current);
 
        perf_pmu_enable(cpuctx->ctx.pmu);
        perf_ctx_unlock(cpuctx, cpuctx->task_ctx);
-
 done:
        if (remove)
                list_del_init(&cpuctx->rotation_list);
@@ -2445,10 +2463,22 @@ void perf_event_task_tick(void)
 {
        struct list_head *head = &__get_cpu_var(rotation_list);
        struct perf_cpu_context *cpuctx, *tmp;
+       struct perf_event_context *ctx;
+       int throttled;
 
        WARN_ON(!irqs_disabled());
 
+       __this_cpu_inc(perf_throttled_seq);
+       throttled = __this_cpu_xchg(perf_throttled_count, 0);
+
        list_for_each_entry_safe(cpuctx, tmp, head, rotation_list) {
+               ctx = &cpuctx->ctx;
+               perf_adjust_freq_unthr_context(ctx, throttled);
+
+               ctx = cpuctx->task_ctx;
+               if (ctx)
+                       perf_adjust_freq_unthr_context(ctx, throttled);
+
                if (cpuctx->jiffies_interval == 1 ||
                                !(jiffies % cpuctx->jiffies_interval))
                        perf_rotate_context(cpuctx);
@@ -4509,6 +4539,7 @@ static int __perf_event_overflow(struct perf_event *event,
 {
        int events = atomic_read(&event->event_limit);
        struct hw_perf_event *hwc = &event->hw;
+       u64 seq;
        int ret = 0;
 
        /*
@@ -4518,14 +4549,20 @@ static int __perf_event_overflow(struct perf_event *event,
        if (unlikely(!is_sampling_event(event)))
                return 0;
 
-       if (unlikely(hwc->interrupts >= max_samples_per_tick)) {
-               if (throttle) {
+       seq = __this_cpu_read(perf_throttled_seq);
+       if (seq != hwc->interrupts_seq) {
+               hwc->interrupts_seq = seq;
+               hwc->interrupts = 1;
+       } else {
+               hwc->interrupts++;
+               if (unlikely(throttle
+                            && hwc->interrupts >= max_samples_per_tick)) {
+                       __this_cpu_inc(perf_throttled_count);
                        hwc->interrupts = MAX_INTERRUPTS;
                        perf_log_throttle(event, 0);
                        ret = 1;
                }
-       } else
-               hwc->interrupts++;
+       }
 
        if (event->attr.freq) {
                u64 now = perf_clock();
@@ -4534,7 +4571,7 @@ static int __perf_event_overflow(struct perf_event *event,
                hwc->freq_time_stamp = now;
 
                if (delta > 0 && delta < 2*TICK_NSEC)
-                       perf_adjust_period(event, delta, hwc->last_period);
+                       perf_adjust_period(event, delta, hwc->last_period, true);
        }
 
        /*
index 294b170..4b4042f 100644 (file)
@@ -1038,6 +1038,22 @@ void do_exit(long code)
        if (tsk->nr_dirtied)
                __this_cpu_add(dirty_throttle_leaks, tsk->nr_dirtied);
        exit_rcu();
+
+       /*
+        * The setting of TASK_RUNNING by try_to_wake_up() may be delayed
+        * when the following two conditions become true.
+        *   - There is race condition of mmap_sem (It is acquired by
+        *     exit_mm()), and
+        *   - SMI occurs before setting TASK_RUNINNG.
+        *     (or hypervisor of virtual machine switches to other guest)
+        *  As a result, we may become TASK_RUNNING after becoming TASK_DEAD
+        *
+        * To avoid it, we have to wait for releasing tsk->pi_lock which
+        * is held by try_to_wake_up()
+        */
+       smp_mb();
+       raw_spin_unlock_wait(&tsk->pi_lock);
+
        /* causes final put_task_struct in finish_task_switch(). */
        tsk->state = TASK_DEAD;
        tsk->flags |= PF_NOFREEZE;      /* tell freezer to ignore us */
index 051f090..b77fd55 100644 (file)
@@ -647,6 +647,26 @@ struct mm_struct *get_task_mm(struct task_struct *task)
 }
 EXPORT_SYMBOL_GPL(get_task_mm);
 
+struct mm_struct *mm_access(struct task_struct *task, unsigned int mode)
+{
+       struct mm_struct *mm;
+       int err;
+
+       err =  mutex_lock_killable(&task->signal->cred_guard_mutex);
+       if (err)
+               return ERR_PTR(err);
+
+       mm = get_task_mm(task);
+       if (mm && mm != current->mm &&
+                       !ptrace_may_access(task, mode)) {
+               mmput(mm);
+               mm = ERR_PTR(-EACCES);
+       }
+       mutex_unlock(&task->signal->cred_guard_mutex);
+
+       return mm;
+}
+
 /* Please note the differences between mmput and mm_release.
  * mmput is called whenever we stop holding onto a mm_struct,
  * error success whatever.
@@ -890,7 +910,7 @@ static int copy_io(unsigned long clone_flags, struct task_struct *tsk)
                        return -ENOMEM;
 
                new_ioc->ioprio = ioc->ioprio;
-               put_io_context(new_ioc, NULL);
+               put_io_context(new_ioc);
        }
 #endif
        return 0;
index 29f5b65..9788c0e 100644 (file)
@@ -1673,8 +1673,12 @@ static int __kprobes pre_handler_kretprobe(struct kprobe *p,
                ri->rp = rp;
                ri->task = current;
 
-               if (rp->entry_handler && rp->entry_handler(ri, regs))
+               if (rp->entry_handler && rp->entry_handler(ri, regs)) {
+                       raw_spin_lock_irqsave(&rp->lock, flags);
+                       hlist_add_head(&ri->hlist, &rp->free_instances);
+                       raw_spin_unlock_irqrestore(&rp->lock, flags);
                        return 0;
+               }
 
                arch_prepare_kretprobe(ri, regs);
 
index 32ee043..4bc965d 100644 (file)
@@ -97,7 +97,8 @@ static int parse_one(char *param,
        for (i = 0; i < num_params; i++) {
                if (parameq(param, params[i].name)) {
                        /* No one handled NULL, so do it here. */
-                       if (!val && params[i].ops->set != param_set_bool)
+                       if (!val && params[i].ops->set != param_set_bool
+                           && params[i].ops->set != param_set_bint)
                                return -EINVAL;
                        pr_debug("They are equal!  Calling %p\n",
                               params[i].ops->set);
index 0c4defe..21724ee 100644 (file)
@@ -231,8 +231,28 @@ extern int pm_test_level;
 #ifdef CONFIG_SUSPEND_FREEZER
 static inline int suspend_freeze_processes(void)
 {
-       int error = freeze_processes();
-       return error ? : freeze_kernel_threads();
+       int error;
+
+       error = freeze_processes();
+
+       /*
+        * freeze_processes() automatically thaws every task if freezing
+        * fails. So we need not do anything extra upon error.
+        */
+       if (error)
+               goto Finish;
+
+       error = freeze_kernel_threads();
+
+       /*
+        * freeze_kernel_threads() thaws only kernel threads upon freezing
+        * failure. So we have to thaw the userspace tasks ourselves.
+        */
+       if (error)
+               thaw_processes();
+
+ Finish:
+       return error;
 }
 
 static inline void suspend_thaw_processes(void)
index 77274c9..7e42645 100644 (file)
@@ -143,7 +143,10 @@ int freeze_processes(void)
 /**
  * freeze_kernel_threads - Make freezable kernel threads go to the refrigerator.
  *
- * On success, returns 0.  On failure, -errno and system is fully thawed.
+ * On success, returns 0.  On failure, -errno and only the kernel threads are
+ * thawed, so as to give a chance to the caller to do additional cleanups
+ * (if any) before thawing the userspace tasks. So, it is the responsibility
+ * of the caller to thaw the userspace tasks, when the time is right.
  */
 int freeze_kernel_threads(void)
 {
@@ -159,7 +162,7 @@ int freeze_kernel_threads(void)
        BUG_ON(in_atomic());
 
        if (error)
-               thaw_processes();
+               thaw_kernel_threads();
        return error;
 }
 
@@ -188,3 +191,22 @@ void thaw_processes(void)
        printk("done.\n");
 }
 
+void thaw_kernel_threads(void)
+{
+       struct task_struct *g, *p;
+
+       pm_nosig_freezing = false;
+       printk("Restarting kernel threads ... ");
+
+       thaw_workqueues();
+
+       read_lock(&tasklist_lock);
+       do_each_thread(g, p) {
+               if (p->flags & (PF_KTHREAD | PF_WQ_WORKER))
+                       __thaw_task(p);
+       } while_each_thread(g, p);
+       read_unlock(&tasklist_lock);
+
+       schedule();
+       printk("done.\n");
+}
index 6b1ab7a..3e10007 100644 (file)
@@ -249,13 +249,15 @@ static long snapshot_ioctl(struct file *filp, unsigned int cmd,
                }
                pm_restore_gfp_mask();
                error = hibernation_snapshot(data->platform_support);
-               if (!error) {
+               if (error) {
+                       thaw_kernel_threads();
+               } else {
                        error = put_user(in_suspend, (int __user *)arg);
                        if (!error && !freezer_test_done)
                                data->ready = 1;
                        if (freezer_test_done) {
                                freezer_test_done = false;
-                               thaw_processes();
+                               thaw_kernel_threads();
                        }
                }
                break;
@@ -274,6 +276,15 @@ static long snapshot_ioctl(struct file *filp, unsigned int cmd,
                swsusp_free();
                memset(&data->handle, 0, sizeof(struct snapshot_handle));
                data->ready = 0;
+               /*
+                * It is necessary to thaw kernel threads here, because
+                * SNAPSHOT_CREATE_IMAGE may be invoked directly after
+                * SNAPSHOT_FREE.  In that case, if kernel threads were not
+                * thawed, the preallocation of memory carried out by
+                * hibernation_snapshot() might run into problems (i.e. it
+                * might fail or even deadlock).
+                */
+               thaw_kernel_threads();
                break;
 
        case SNAPSHOT_PREF_IMAGE_SIZE:
index 4335e1d..ab56a17 100644 (file)
@@ -164,10 +164,14 @@ depopulate:
  */
 static struct rchan_buf *relay_create_buf(struct rchan *chan)
 {
-       struct rchan_buf *buf = kzalloc(sizeof(struct rchan_buf), GFP_KERNEL);
-       if (!buf)
+       struct rchan_buf *buf;
+
+       if (chan->n_subbufs > UINT_MAX / sizeof(size_t *))
                return NULL;
 
+       buf = kzalloc(sizeof(struct rchan_buf), GFP_KERNEL);
+       if (!buf)
+               return NULL;
        buf->padding = kmalloc(chan->n_subbufs * sizeof(size_t *), GFP_KERNEL);
        if (!buf->padding)
                goto free_buf;
@@ -574,6 +578,8 @@ struct rchan *relay_open(const char *base_filename,
 
        if (!(subbuf_size && n_subbufs))
                return NULL;
+       if (subbuf_size > UINT_MAX / n_subbufs)
+               return NULL;
 
        chan = kzalloc(sizeof(struct rchan), GFP_KERNEL);
        if (!chan)
index df00cb0..5255c9d 100644 (file)
@@ -74,6 +74,7 @@
 
 #include <asm/tlb.h>
 #include <asm/irq_regs.h>
+#include <asm/mutex.h>
 #ifdef CONFIG_PARAVIRT
 #include <asm/paravirt.h>
 #endif
@@ -723,9 +724,6 @@ static void dequeue_task(struct rq *rq, struct task_struct *p, int flags)
        p->sched_class->dequeue_task(rq, p, flags);
 }
 
-/*
- * activate_task - move a task to the runqueue.
- */
 void activate_task(struct rq *rq, struct task_struct *p, int flags)
 {
        if (task_contributes_to_load(p))
@@ -734,9 +732,6 @@ void activate_task(struct rq *rq, struct task_struct *p, int flags)
        enqueue_task(rq, p, flags);
 }
 
-/*
- * deactivate_task - remove a task from the runqueue.
- */
 void deactivate_task(struct rq *rq, struct task_struct *p, int flags)
 {
        if (task_contributes_to_load(p))
@@ -4134,7 +4129,7 @@ recheck:
        on_rq = p->on_rq;
        running = task_current(rq, p);
        if (on_rq)
-               deactivate_task(rq, p, 0);
+               dequeue_task(rq, p, 0);
        if (running)
                p->sched_class->put_prev_task(rq, p);
 
@@ -4147,7 +4142,7 @@ recheck:
        if (running)
                p->sched_class->set_curr_task(rq);
        if (on_rq)
-               activate_task(rq, p, 0);
+               enqueue_task(rq, p, 0);
 
        check_class_changed(rq, p, prev_class, oldprio);
        task_rq_unlock(rq, p, &flags);
@@ -4998,9 +4993,9 @@ static int __migrate_task(struct task_struct *p, int src_cpu, int dest_cpu)
         * placed properly.
         */
        if (p->on_rq) {
-               deactivate_task(rq_src, p, 0);
+               dequeue_task(rq_src, p, 0);
                set_task_cpu(p, dest_cpu);
-               activate_task(rq_dest, p, 0);
+               enqueue_task(rq_dest, p, 0);
                check_preempt_curr(rq_dest, p, 0);
        }
 done:
@@ -7032,10 +7027,10 @@ static void normalize_task(struct rq *rq, struct task_struct *p)
 
        on_rq = p->on_rq;
        if (on_rq)
-               deactivate_task(rq, p, 0);
+               dequeue_task(rq, p, 0);
        __setscheduler(rq, p, SCHED_NORMAL, 0);
        if (on_rq) {
-               activate_task(rq, p, 0);
+               enqueue_task(rq, p, 0);
                resched_task(rq->curr);
        }
 
index 84adb2d..7c6414f 100644 (file)
@@ -4866,6 +4866,15 @@ static void nohz_balancer_kick(int cpu)
        return;
 }
 
+static inline void clear_nohz_tick_stopped(int cpu)
+{
+       if (unlikely(test_bit(NOHZ_TICK_STOPPED, nohz_flags(cpu)))) {
+               cpumask_clear_cpu(cpu, nohz.idle_cpus_mask);
+               atomic_dec(&nohz.nr_cpus);
+               clear_bit(NOHZ_TICK_STOPPED, nohz_flags(cpu));
+       }
+}
+
 static inline void set_cpu_sd_state_busy(void)
 {
        struct sched_domain *sd;
@@ -4904,6 +4913,12 @@ void select_nohz_load_balancer(int stop_tick)
 {
        int cpu = smp_processor_id();
 
+       /*
+        * If this cpu is going down, then nothing needs to be done.
+        */
+       if (!cpu_active(cpu))
+               return;
+
        if (stop_tick) {
                if (test_bit(NOHZ_TICK_STOPPED, nohz_flags(cpu)))
                        return;
@@ -4914,6 +4929,18 @@ void select_nohz_load_balancer(int stop_tick)
        }
        return;
 }
+
+static int __cpuinit sched_ilb_notifier(struct notifier_block *nfb,
+                                       unsigned long action, void *hcpu)
+{
+       switch (action & ~CPU_TASKS_FROZEN) {
+       case CPU_DYING:
+               clear_nohz_tick_stopped(smp_processor_id());
+               return NOTIFY_OK;
+       default:
+               return NOTIFY_DONE;
+       }
+}
 #endif
 
 static DEFINE_SPINLOCK(balancing);
@@ -5070,11 +5097,7 @@ static inline int nohz_kick_needed(struct rq *rq, int cpu)
        * busy tick after returning from idle, we will update the busy stats.
        */
        set_cpu_sd_state_busy();
-       if (unlikely(test_bit(NOHZ_TICK_STOPPED, nohz_flags(cpu)))) {
-               clear_bit(NOHZ_TICK_STOPPED, nohz_flags(cpu));
-               cpumask_clear_cpu(cpu, nohz.idle_cpus_mask);
-               atomic_dec(&nohz.nr_cpus);
-       }
+       clear_nohz_tick_stopped(cpu);
 
        /*
         * None are in tickless mode and hence no need for NOHZ idle load
@@ -5590,6 +5613,7 @@ __init void init_sched_fair_class(void)
 
 #ifdef CONFIG_NO_HZ
        zalloc_cpumask_var(&nohz.idle_cpus_mask, GFP_NOWAIT);
+       cpu_notifier(sched_ilb_notifier, 0);
 #endif
 #endif /* SMP */
 
index 3640ebb..f42ae7f 100644 (file)
@@ -1587,6 +1587,11 @@ static int push_rt_task(struct rq *rq)
        if (!next_task)
                return 0;
 
+#ifdef __ARCH_WANT_INTERRUPTS_ON_CTXSW
+       if (unlikely(task_running(rq, next_task)))
+               return 0;
+#endif
+
 retry:
        if (unlikely(next_task == rq->curr)) {
                WARN_ON(1);
index 1d7bca7..d117262 100644 (file)
@@ -296,7 +296,7 @@ static enum hrtimer_restart watchdog_timer_fn(struct hrtimer *hrtimer)
                if (__this_cpu_read(soft_watchdog_warn) == true)
                        return HRTIMER_RESTART;
 
-               printk(KERN_ERR "BUG: soft lockup - CPU#%d stuck for %us! [%s:%d]\n",
+               printk(KERN_EMERG "BUG: soft lockup - CPU#%d stuck for %us! [%s:%d]\n",
                        smp_processor_id(), duration,
                        current->comm, task_pid_nr(current));
                print_modules();
index 169eb7c..028aba9 100644 (file)
@@ -19,6 +19,9 @@ config RATIONAL
 config GENERIC_FIND_FIRST_BIT
        bool
 
+config NO_GENERIC_PCI_IOPORT_MAP
+       bool
+
 config GENERIC_PCI_IOMAP
        bool
 
@@ -279,6 +282,9 @@ config AVERAGE
 
          If unsure, say N.
 
+config CLZ_TAB
+       bool
+
 config CORDIC
        tristate "CORDIC algorithm"
        help
@@ -287,6 +293,7 @@ config CORDIC
 
 config MPILIB
        tristate
+       select CLZ_TAB
        help
          Multiprecision maths library from GnuPG.
          It is used to implement RSA digital signature verification,
index d71aae1..18515f0 100644 (file)
@@ -121,6 +121,8 @@ obj-$(CONFIG_DQL) += dynamic_queue_limits.o
 obj-$(CONFIG_MPILIB) += mpi/
 obj-$(CONFIG_SIGNATURE) += digsig.o
 
+obj-$(CONFIG_CLZ_TAB) += clz_tab.o
+
 hostprogs-y    := gen_crc32table
 clean-files    := crc32table.h
 
index 1955209..a28c141 100644 (file)
--- a/lib/bug.c
+++ b/lib/bug.c
@@ -169,7 +169,7 @@ enum bug_trap_type report_bug(unsigned long bugaddr, struct pt_regs *regs)
                return BUG_TRAP_TYPE_WARN;
        }
 
-       printk(KERN_EMERG "------------[ cut here ]------------\n");
+       printk(KERN_DEFAULT "------------[ cut here ]------------\n");
 
        if (file)
                printk(KERN_CRIT "kernel BUG at %s:%u!\n",
diff --git a/lib/clz_tab.c b/lib/clz_tab.c
new file mode 100644 (file)
index 0000000..7287b4a
--- /dev/null
@@ -0,0 +1,18 @@
+const unsigned char __clz_tab[] = {
+       0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5,
+           5, 5, 5, 5, 5, 5, 5, 5,
+       6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+           6, 6, 6, 6, 6, 6, 6, 6,
+       7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+           7, 7, 7, 7, 7, 7, 7, 7,
+       7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+           7, 7, 7, 7, 7, 7, 7, 7,
+       8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+           8, 8, 8, 8, 8, 8, 8, 8,
+       8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+           8, 8, 8, 8, 8, 8, 8, 8,
+       8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+           8, 8, 8, 8, 8, 8, 8, 8,
+       8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+           8, 8, 8, 8, 8, 8, 8, 8,
+};
index fd2402f..286d558 100644 (file)
@@ -34,14 +34,9 @@ static int pkcs_1_v1_5_decode_emsa(const unsigned char *msg,
                        unsigned long  msglen,
                        unsigned long  modulus_bitlen,
                        unsigned char *out,
-                       unsigned long *outlen,
-                       int *is_valid)
+                       unsigned long *outlen)
 {
        unsigned long modulus_len, ps_len, i;
-       int result;
-
-       /* default to invalid packet */
-       *is_valid = 0;
 
        modulus_len = (modulus_bitlen >> 3) + (modulus_bitlen & 7 ? 1 : 0);
 
@@ -50,39 +45,30 @@ static int pkcs_1_v1_5_decode_emsa(const unsigned char *msg,
                return -EINVAL;
 
        /* separate encoded message */
-       if ((msg[0] != 0x00) || (msg[1] != (unsigned char)1)) {
-               result = -EINVAL;
-               goto bail;
-       }
+       if ((msg[0] != 0x00) || (msg[1] != (unsigned char)1))
+               return -EINVAL;
 
        for (i = 2; i < modulus_len - 1; i++)
                if (msg[i] != 0xFF)
                        break;
 
        /* separator check */
-       if (msg[i] != 0) {
+       if (msg[i] != 0)
                /* There was no octet with hexadecimal value 0x00
                to separate ps from m. */
-               result = -EINVAL;
-               goto bail;
-       }
+               return -EINVAL;
 
        ps_len = i - 2;
 
        if (*outlen < (msglen - (2 + ps_len + 1))) {
                *outlen = msglen - (2 + ps_len + 1);
-               result = -EOVERFLOW;
-               goto bail;
+               return -EOVERFLOW;
        }
 
        *outlen = (msglen - (2 + ps_len + 1));
        memcpy(out, &msg[2 + ps_len + 1], *outlen);
 
-       /* valid packet */
-       *is_valid = 1;
-       result    = 0;
-bail:
-       return result;
+       return 0;
 }
 
 /*
@@ -96,7 +82,7 @@ static int digsig_verify_rsa(struct key *key,
        unsigned long len;
        unsigned long mlen, mblen;
        unsigned nret, l;
-       int valid, head, i;
+       int head, i;
        unsigned char *out1 = NULL, *out2 = NULL;
        MPI in = NULL, res = NULL, pkey[2];
        uint8_t *p, *datap, *endp;
@@ -105,6 +91,10 @@ static int digsig_verify_rsa(struct key *key,
 
        down_read(&key->sem);
        ukp = key->payload.data;
+
+       if (ukp->datalen < sizeof(*pkh))
+               goto err1;
+
        pkh = (struct pubkey_hdr *)ukp->data;
 
        if (pkh->version != 1)
@@ -117,18 +107,23 @@ static int digsig_verify_rsa(struct key *key,
                goto err1;
 
        datap = pkh->mpi;
-       endp = datap + ukp->datalen;
+       endp = ukp->data + ukp->datalen;
+
+       err = -ENOMEM;
 
        for (i = 0; i < pkh->nmpi; i++) {
                unsigned int remaining = endp - datap;
                pkey[i] = mpi_read_from_buffer(datap, &remaining);
+               if (!pkey[i])
+                       goto err;
                datap += remaining;
        }
 
        mblen = mpi_get_nbits(pkey[0]);
        mlen = (mblen + 7)/8;
 
-       err = -ENOMEM;
+       if (mlen == 0)
+               goto err;
 
        out1 = kzalloc(mlen, GFP_KERNEL);
        if (!out1)
@@ -167,10 +162,9 @@ static int digsig_verify_rsa(struct key *key,
        memset(out1, 0, head);
        memcpy(out1 + head, p, l);
 
-       err = -EINVAL;
-       pkcs_1_v1_5_decode_emsa(out1, len, mblen, out2, &len, &valid);
+       err = pkcs_1_v1_5_decode_emsa(out1, len, mblen, out2, &len);
 
-       if (valid && len == hlen)
+       if (!err && len == hlen)
                err = memcmp(out2, h, hlen);
 
 err:
@@ -178,8 +172,8 @@ err:
        mpi_free(res);
        kfree(out1);
        kfree(out2);
-       mpi_free(pkey[0]);
-       mpi_free(pkey[1]);
+       while (--i >= 0)
+               mpi_free(pkey[i]);
 err1:
        up_read(&key->sem);
 
index 7a94c8f..b1dd3e7 100644 (file)
@@ -44,12 +44,13 @@ const char *_parse_integer_fixup_radix(const char *s, unsigned int *base)
  *
  * Don't you dare use this function.
  */
-unsigned int _parse_integer(const char *s, unsigned int base, unsigned long long *res)
+unsigned int _parse_integer(const char *s, unsigned int base, unsigned long long *p)
 {
+       unsigned long long res;
        unsigned int rv;
        int overflow;
 
-       *res = 0;
+       res = 0;
        rv = 0;
        overflow = 0;
        while (*s) {
@@ -64,12 +65,19 @@ unsigned int _parse_integer(const char *s, unsigned int base, unsigned long long
 
                if (val >= base)
                        break;
-               if (*res > div_u64(ULLONG_MAX - val, base))
-                       overflow = 1;
-               *res = *res * base + val;
+               /*
+                * Check for overflow only if we are within range of
+                * it in the max base we support (16)
+                */
+               if (unlikely(res & (~0ull << 60))) {
+                       if (res > div_u64(ULLONG_MAX - val, base))
+                               overflow = 1;
+               }
+               res = res * base + val;
                rv++;
                s++;
        }
+       *p = res;
        if (overflow)
                rv |= KSTRTOX_OVERFLOW;
        return rv;
index b87487b..29f9862 100644 (file)
@@ -1200,18 +1200,40 @@ do { \
        "r" ((USItype)(v)) \
        : "%g1", "%g2" __AND_CLOBBER_CC)
 #define UMUL_TIME 39           /* 39 instructions */
-#endif
-#ifndef udiv_qrnnd
-#ifndef LONGLONG_STANDALONE
+/* It's quite necessary to add this much assembler for the sparc.
+   The default udiv_qrnnd (in C) is more than 10 times slower!  */
 #define udiv_qrnnd(q, r, n1, n0, d) \
-do { USItype __r; \
-       (q) = __udiv_qrnnd(&__r, (n1), (n0), (d)); \
-       (r) = __r; \
-} while (0)
-       extern USItype __udiv_qrnnd();
-#define UDIV_TIME 140
-#endif /* LONGLONG_STANDALONE */
-#endif /* udiv_qrnnd */
+  __asm__ ("! Inlined udiv_qrnnd\n\t"                                  \
+          "mov 32,%%g1\n\t"                                            \
+          "subcc       %1,%2,%%g0\n\t"                                 \
+          "1:  bcs     5f\n\t"                                         \
+          "addxcc %0,%0,%0     ! shift n1n0 and a q-bit in lsb\n\t"    \
+          "sub %1,%2,%1        ! this kills msb of n\n\t"              \
+          "addx        %1,%1,%1        ! so this can't give carry\n\t" \
+          "subcc       %%g1,1,%%g1\n\t"                                \
+          "2:  bne     1b\n\t"                                         \
+          "subcc       %1,%2,%%g0\n\t"                                 \
+          "bcs 3f\n\t"                                                 \
+          "addxcc %0,%0,%0     ! shift n1n0 and a q-bit in lsb\n\t"    \
+          "b           3f\n\t"                                         \
+          "sub %1,%2,%1        ! this kills msb of n\n\t"              \
+          "4:  sub     %1,%2,%1\n\t"                                   \
+          "5:  addxcc  %1,%1,%1\n\t"                                   \
+          "bcc 2b\n\t"                                                 \
+          "subcc       %%g1,1,%%g1\n\t"                                \
+          "! Got carry from n.  Subtract next step to cancel this carry.\n\t" \
+          "bne 4b\n\t"                                                 \
+          "addcc       %0,%0,%0        ! shift n1n0 and a 0-bit in lsb\n\t" \
+          "sub %1,%2,%1\n\t"                                           \
+          "3:  xnor    %0,0,%0\n\t"                                    \
+          "! End of inline udiv_qrnnd\n"                               \
+          : "=&r" ((USItype)(q)),                                      \
+            "=&r" ((USItype)(r))                                       \
+          : "r" ((USItype)(d)),                                        \
+            "1" ((USItype)(n1)),                                       \
+            "0" ((USItype)(n0)) : "%g1", "cc")
+#define UDIV_TIME (3+7*32)      /* 7 instructions/iteration. 32 iterations.  */
+#endif
 #endif /* __sparc__ */
 
 /***************************************
index 854c9c6..2f52662 100644 (file)
 #include "mpi-internal.h"
 #include "longlong.h"
 
-const unsigned char __clz_tab[] = {
-       0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5,
-           5, 5, 5, 5, 5, 5, 5, 5,
-       6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
-           6, 6, 6, 6, 6, 6, 6, 6,
-       7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
-           7, 7, 7, 7, 7, 7, 7, 7,
-       7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
-           7, 7, 7, 7, 7, 7, 7, 7,
-       8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
-           8, 8, 8, 8, 8, 8, 8, 8,
-       8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
-           8, 8, 8, 8, 8, 8, 8, 8,
-       8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
-           8, 8, 8, 8, 8, 8, 8, 8,
-       8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
-           8, 8, 8, 8, 8, 8, 8, 8,
-};
-
 #define A_LIMB_1 ((mpi_limb_t) 1)
 
 /****************
index c3087d1..f68cbbb 100644 (file)
@@ -149,6 +149,9 @@ int mpi_tdiv_qr(MPI quot, MPI rem, MPI num, MPI den)
        mpi_ptr_t marker[5];
        int markidx = 0;
 
+       if (!dsize)
+               return -EINVAL;
+
        memset(marker, 0, sizeof(marker));
 
        /* Ensure space is enough for quotient and remainder.
@@ -207,6 +210,8 @@ int mpi_tdiv_qr(MPI quot, MPI rem, MPI num, MPI den)
                 * numerator would be gradually overwritten by the quotient limbs.  */
                if (qp == np) { /* Copy NP object to temporary space.  */
                        np = marker[markidx++] = mpi_alloc_limb_space(nsize);
+                       if (!np)
+                               goto nomem;
                        MPN_COPY(np, qp, nsize);
                }
        } else                  /* Put quotient at top of remainder. */
index b04a3cf..67f3e79 100644 (file)
@@ -59,7 +59,7 @@ int mpi_powm(MPI res, MPI base, MPI exp, MPI mod)
        ep = exp->d;
 
        if (!msize)
-               msize = 1 / msize;      /* provoke a signal */
+               return -EINVAL;
 
        if (!esize) {
                /* Exponent is zero, result is 1 mod MOD, i.e., 1 or 0
index 716802b..f26b41f 100644 (file)
 
 #include "mpi-internal.h"
 
-#define DIM(v) (sizeof(v)/sizeof((v)[0]))
 #define MAX_EXTERN_MPI_BITS 16384
 
-static uint8_t asn[15] =       /* Object ID is 1.3.14.3.2.26 */
-{ 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03,
-       0x02, 0x1a, 0x05, 0x00, 0x04, 0x14
-};
-
-MPI do_encode_md(const void *sha_buffer, unsigned nbits)
-{
-       int nframe = (nbits + 7) / 8;
-       uint8_t *frame, *fr_pt;
-       int i = 0, n;
-       size_t asnlen = DIM(asn);
-       MPI a = MPI_NULL;
-
-       if (SHA1_DIGEST_LENGTH + asnlen + 4 > nframe)
-               pr_info("MPI: can't encode a %d bit MD into a %d bits frame\n",
-                      (int)(SHA1_DIGEST_LENGTH * 8), (int)nbits);
-
-       /* We encode the MD in this way:
-        *
-        *       0  A PAD(n bytes)   0  ASN(asnlen bytes)  MD(len bytes)
-        *
-        * PAD consists of FF bytes.
-        */
-       frame = kmalloc(nframe, GFP_KERNEL);
-       if (!frame)
-               return MPI_NULL;
-       n = 0;
-       frame[n++] = 0;
-       frame[n++] = 1;         /* block type */
-       i = nframe - SHA1_DIGEST_LENGTH - asnlen - 3;
-
-       if (i <= 1) {
-               pr_info("MPI: message digest encoding failed\n");
-               kfree(frame);
-               return a;
-       }
-
-       memset(frame + n, 0xff, i);
-       n += i;
-       frame[n++] = 0;
-       memcpy(frame + n, &asn, asnlen);
-       n += asnlen;
-       memcpy(frame + n, sha_buffer, SHA1_DIGEST_LENGTH);
-       n += SHA1_DIGEST_LENGTH;
-
-       i = nframe;
-       fr_pt = frame;
-
-       if (n != nframe) {
-               printk
-                   ("MPI: message digest encoding failed, frame length is wrong\n");
-               kfree(frame);
-               return a;
-       }
-
-       a = mpi_alloc((nframe + BYTES_PER_MPI_LIMB - 1) / BYTES_PER_MPI_LIMB);
-       mpi_set_buffer(a, frame, nframe, 0);
-       kfree(frame);
-
-       return a;
-}
-
 MPI mpi_read_from_buffer(const void *xbuffer, unsigned *ret_nread)
 {
        const uint8_t *buffer = xbuffer;
        int i, j;
        unsigned nbits, nbytes, nlimbs, nread = 0;
        mpi_limb_t a;
-       MPI val = MPI_NULL;
+       MPI val = NULL;
 
        if (*ret_nread < 2)
                goto leave;
@@ -108,7 +45,7 @@ MPI mpi_read_from_buffer(const void *xbuffer, unsigned *ret_nread)
        nlimbs = (nbytes + BYTES_PER_MPI_LIMB - 1) / BYTES_PER_MPI_LIMB;
        val = mpi_alloc(nlimbs);
        if (!val)
-               return MPI_NULL;
+               return NULL;
        i = BYTES_PER_MPI_LIMB - nbytes % BYTES_PER_MPI_LIMB;
        i %= BYTES_PER_MPI_LIMB;
        val->nbits = nbits;
@@ -211,30 +148,6 @@ int mpi_fromstr(MPI val, const char *str)
 }
 EXPORT_SYMBOL_GPL(mpi_fromstr);
 
-/****************
- * Special function to get the low 8 bytes from an mpi.
- * This can be used as a keyid; KEYID is an 2 element array.
- * Return the low 4 bytes.
- */
-u32 mpi_get_keyid(const MPI a, u32 *keyid)
-{
-#if BYTES_PER_MPI_LIMB == 4
-       if (keyid) {
-               keyid[0] = a->nlimbs >= 2 ? a->d[1] : 0;
-               keyid[1] = a->nlimbs >= 1 ? a->d[0] : 0;
-       }
-       return a->nlimbs >= 1 ? a->d[0] : 0;
-#elif BYTES_PER_MPI_LIMB == 8
-       if (keyid) {
-               keyid[0] = a->nlimbs ? (u32) (a->d[0] >> 32) : 0;
-               keyid[1] = a->nlimbs ? (u32) (a->d[0] & 0xffffffff) : 0;
-       }
-       return a->nlimbs ? (u32) (a->d[0] & 0xffffffff) : 0;
-#else
-#error Make this function work with other LIMB sizes
-#endif
-}
-
 /****************
  * Return an allocated buffer with the MPI (msb first).
  * NBYTES receives the length of this buffer. Caller must free the
index 87ede16..cde1aae 100644 (file)
@@ -217,6 +217,10 @@ mpihelp_divrem(mpi_ptr_t qp, mpi_size_t qextra_limbs,
        case 0:
                /* We are asked to divide by zero, so go ahead and do it!  (To make
                   the compiler not remove this statement, return the value.)  */
+               /*
+                * existing clients of this function have been modified
+                * not to call it with dsize == 0, so this should not happen
+                */
                return 1 / dsize;
 
        case 1:
index eefc55d..26e4ed3 100644 (file)
@@ -58,6 +58,9 @@ mpi_ptr_t mpi_alloc_limb_space(unsigned nlimbs)
 {
        size_t len = nlimbs * sizeof(mpi_limb_t);
 
+       if (!len)
+               return NULL;
+
        return kmalloc(len, GFP_KERNEL);
 }
 
@@ -135,7 +138,7 @@ int mpi_copy(MPI *copied, const MPI a)
        size_t i;
        MPI b;
 
-       *copied = MPI_NULL;
+       *copied = NULL;
 
        if (a) {
                b = mpi_alloc(a->nlimbs);
index 4b0fdc2..0d83ea8 100644 (file)
@@ -34,7 +34,7 @@ void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long maxlen)
        if (maxlen && len > maxlen)
                len = maxlen;
        if (flags & IORESOURCE_IO)
-               return ioport_map(start, len);
+               return __pci_ioport_map(dev, start, len);
        if (flags & IORESOURCE_MEM) {
                if (flags & IORESOURCE_CACHEABLE)
                        return ioremap(start, len);
index 7ba8fea..dd8e2aa 100644 (file)
@@ -318,7 +318,7 @@ static void wakeup_timer_fn(unsigned long data)
        if (bdi->wb.task) {
                trace_writeback_wake_thread(bdi);
                wake_up_process(bdi->wb.task);
-       } else {
+       } else if (bdi->dev) {
                /*
                 * When bdi tasks are inactive for long time, they are killed.
                 * In this case we have to wake-up the forker thread which
@@ -584,6 +584,8 @@ EXPORT_SYMBOL(bdi_register_dev);
  */
 static void bdi_wb_shutdown(struct backing_dev_info *bdi)
 {
+       struct task_struct *task;
+
        if (!bdi_cap_writeback_dirty(bdi))
                return;
 
@@ -602,8 +604,13 @@ static void bdi_wb_shutdown(struct backing_dev_info *bdi)
         * Finally, kill the kernel thread. We don't need to be RCU
         * safe anymore, since the bdi is gone from visibility.
         */
-       if (bdi->wb.task)
-               kthread_stop(bdi->wb.task);
+       spin_lock_bh(&bdi->wb_lock);
+       task = bdi->wb.task;
+       bdi->wb.task = NULL;
+       spin_unlock_bh(&bdi->wb_lock);
+
+       if (task)
+               kthread_stop(task);
 }
 
 /*
@@ -623,7 +630,9 @@ static void bdi_prune_sb(struct backing_dev_info *bdi)
 
 void bdi_unregister(struct backing_dev_info *bdi)
 {
-       if (bdi->dev) {
+       struct device *dev = bdi->dev;
+
+       if (dev) {
                bdi_set_min_ratio(bdi, 0);
                trace_writeback_bdi_unregister(bdi);
                bdi_prune_sb(bdi);
@@ -632,8 +641,12 @@ void bdi_unregister(struct backing_dev_info *bdi)
                if (!bdi_cap_flush_forker(bdi))
                        bdi_wb_shutdown(bdi);
                bdi_debug_unregister(bdi);
-               device_unregister(bdi->dev);
+
+               spin_lock_bh(&bdi->wb_lock);
                bdi->dev = NULL;
+               spin_unlock_bh(&bdi->wb_lock);
+
+               device_unregister(dev);
        }
 }
 EXPORT_SYMBOL(bdi_unregister);
index 71a58f6..d9ebebe 100644 (file)
@@ -313,12 +313,34 @@ static isolate_migrate_t isolate_migratepages(struct zone *zone,
                } else if (!locked)
                        spin_lock_irq(&zone->lru_lock);
 
+               /*
+                * migrate_pfn does not necessarily start aligned to a
+                * pageblock. Ensure that pfn_valid is called when moving
+                * into a new MAX_ORDER_NR_PAGES range in case of large
+                * memory holes within the zone
+                */
+               if ((low_pfn & (MAX_ORDER_NR_PAGES - 1)) == 0) {
+                       if (!pfn_valid(low_pfn)) {
+                               low_pfn += MAX_ORDER_NR_PAGES - 1;
+                               continue;
+                       }
+               }
+
                if (!pfn_valid_within(low_pfn))
                        continue;
                nr_scanned++;
 
-               /* Get the page and skip if free */
+               /*
+                * Get the page and ensure the page is within the same zone.
+                * See the comment in isolate_freepages about overlapping
+                * nodes. It is deliberate that the new zone lock is not taken
+                * as memory compaction should not move pages between nodes.
+                */
                page = pfn_to_page(low_pfn);
+               if (page_zone(page) != zone)
+                       continue;
+
+               /* Skip if free */
                if (PageBuddy(page))
                        continue;
 
index 97f49ed..b662757 100644 (file)
@@ -1400,15 +1400,12 @@ generic_file_aio_read(struct kiocb *iocb, const struct iovec *iov,
        unsigned long seg = 0;
        size_t count;
        loff_t *ppos = &iocb->ki_pos;
-       struct blk_plug plug;
 
        count = 0;
        retval = generic_segment_checks(iov, &nr_segs, &count, VERIFY_WRITE);
        if (retval)
                return retval;
 
-       blk_start_plug(&plug);
-
        /* coalesce the iovecs and go direct-to-BIO for O_DIRECT */
        if (filp->f_flags & O_DIRECT) {
                loff_t size;
@@ -1424,8 +1421,12 @@ generic_file_aio_read(struct kiocb *iocb, const struct iovec *iov,
                        retval = filemap_write_and_wait_range(mapping, pos,
                                        pos + iov_length(iov, nr_segs) - 1);
                        if (!retval) {
+                               struct blk_plug plug;
+
+                               blk_start_plug(&plug);
                                retval = mapping->a_ops->direct_IO(READ, iocb,
                                                        iov, pos, nr_segs);
+                               blk_finish_plug(&plug);
                        }
                        if (retval > 0) {
                                *ppos = pos + retval;
@@ -1481,7 +1482,6 @@ generic_file_aio_read(struct kiocb *iocb, const struct iovec *iov,
                        break;
        }
 out:
-       blk_finish_plug(&plug);
        return retval;
 }
 EXPORT_SYMBOL(generic_file_aio_read);
index f91b2f6..a4eb311 100644 (file)
@@ -263,7 +263,12 @@ found:
                                                        xip_pfn);
                if (err == -ENOMEM)
                        return VM_FAULT_OOM;
-               BUG_ON(err);
+               /*
+                * err == -EBUSY is fine, we've raced against another thread
+                * that faulted-in the same page
+                */
+               if (err != -EBUSY)
+                       BUG_ON(err);
                return VM_FAULT_NOPAGE;
        } else {
                int err, ret = VM_FAULT_OOM;
index b3ffc21..91d3efb 100644 (file)
@@ -2083,7 +2083,7 @@ static void collect_mm_slot(struct mm_slot *mm_slot)
 {
        struct mm_struct *mm = mm_slot->mm;
 
-       VM_BUG_ON(!spin_is_locked(&khugepaged_mm_lock));
+       VM_BUG_ON(NR_CPUS != 1 && !spin_is_locked(&khugepaged_mm_lock));
 
        if (khugepaged_test_exit(mm)) {
                /* free mm_slot */
@@ -2113,7 +2113,7 @@ static unsigned int khugepaged_scan_mm_slot(unsigned int pages,
        int progress = 0;
 
        VM_BUG_ON(!pages);
-       VM_BUG_ON(!spin_is_locked(&khugepaged_mm_lock));
+       VM_BUG_ON(NR_CPUS != 1 && !spin_is_locked(&khugepaged_mm_lock));
 
        if (khugepaged_scan.mm_slot)
                mm_slot = khugepaged_scan.mm_slot;
index c833add..45eb621 100644 (file)
@@ -1036,7 +1036,7 @@ void __ref kmemleak_scan_area(const void *ptr, size_t size, gfp_t gfp)
 {
        pr_debug("%s(0x%p)\n", __func__, ptr);
 
-       if (atomic_read(&kmemleak_enabled) && ptr && !IS_ERR(ptr))
+       if (atomic_read(&kmemleak_enabled) && ptr && size && !IS_ERR(ptr))
                add_scan_area((unsigned long)ptr, size, gfp);
        else if (atomic_read(&kmemleak_early_log))
                log_early(KMEMLEAK_SCAN_AREA, ptr, size, 0);
@@ -1757,6 +1757,7 @@ void __init kmemleak_init(void)
 
 #ifdef CONFIG_DEBUG_KMEMLEAK_DEFAULT_OFF
        if (!kmemleak_skip_disable) {
+               atomic_set(&kmemleak_early_log, 0);
                kmemleak_disable();
                return;
        }
index 556859f..6728a7a 100644 (file)
@@ -776,7 +776,8 @@ static void memcg_check_events(struct mem_cgroup *memcg, struct page *page)
        /* threshold event is triggered in finer grain than soft limit */
        if (unlikely(mem_cgroup_event_ratelimit(memcg,
                                                MEM_CGROUP_TARGET_THRESH))) {
-               bool do_softlimit, do_numainfo;
+               bool do_softlimit;
+               bool do_numainfo __maybe_unused;
 
                do_softlimit = mem_cgroup_event_ratelimit(memcg,
                                                MEM_CGROUP_TARGET_SOFTLIMIT);
index 9871a56..df141f6 100644 (file)
@@ -445,7 +445,6 @@ void migrate_page_copy(struct page *newpage, struct page *page)
        ClearPageSwapCache(page);
        ClearPagePrivate(page);
        set_page_private(page, 0);
-       page->mapping = NULL;
 
        /*
         * If any waiters have accumulated on the new page then
@@ -667,6 +666,7 @@ static int move_to_new_page(struct page *newpage, struct page *page,
        } else {
                if (remap_swapcache)
                        remove_migration_ptes(page, newpage);
+               page->mapping = NULL;
        }
 
        unlock_page(newpage);
index e920aa3..c20ff48 100644 (file)
@@ -298,23 +298,18 @@ static ssize_t process_vm_rw_core(pid_t pid, const struct iovec *lvec,
                goto free_proc_pages;
        }
 
-       task_lock(task);
-       if (__ptrace_may_access(task, PTRACE_MODE_ATTACH)) {
-               task_unlock(task);
-               rc = -EPERM;
-               goto put_task_struct;
-       }
-       mm = task->mm;
-
-       if (!mm || (task->flags & PF_KTHREAD)) {
-               task_unlock(task);
-               rc = -EINVAL;
+       mm = mm_access(task, PTRACE_MODE_ATTACH);
+       if (!mm || IS_ERR(mm)) {
+               rc = IS_ERR(mm) ? PTR_ERR(mm) : -ESRCH;
+               /*
+                * Explicitly map EACCES to EPERM as EPERM is a more a
+                * appropriate error code for process_vw_readv/writev
+                */
+               if (rc == -EACCES)
+                       rc = -EPERM;
                goto put_task_struct;
        }
 
-       atomic_inc(&mm->mm_users);
-       task_unlock(task);
-
        for (i = 0; i < riovcnt && iov_l_curr_idx < liovcnt; i++) {
                rc = process_vm_rw_single_vec(
                        (unsigned long)rvec[i].iov_base, rvec[i].iov_len,
index b0f529b..fff1ff7 100644 (file)
--- a/mm/swap.c
+++ b/mm/swap.c
@@ -659,7 +659,7 @@ void lru_add_page_tail(struct zone* zone,
        VM_BUG_ON(!PageHead(page));
        VM_BUG_ON(PageCompound(page_tail));
        VM_BUG_ON(PageLRU(page_tail));
-       VM_BUG_ON(!spin_is_locked(&zone->lru_lock));
+       VM_BUG_ON(NR_CPUS != 1 && !spin_is_locked(&zone->lru_lock));
 
        SetPageLRU(page_tail);
 
index 673728a..82c5706 100644 (file)
@@ -59,8 +59,6 @@ struct cfcnfg *get_cfcnfg(struct net *net)
 {
        struct caif_net *caifn;
        caifn = net_generic(net, caif_net_id);
-       if (!caifn)
-               return NULL;
        return caifn->cfg;
 }
 EXPORT_SYMBOL(get_cfcnfg);
@@ -69,8 +67,6 @@ static struct caif_device_entry_list *caif_device_list(struct net *net)
 {
        struct caif_net *caifn;
        caifn = net_generic(net, caif_net_id);
-       if (!caifn)
-               return NULL;
        return &caifn->caifdevs;
 }
 
@@ -99,8 +95,6 @@ static struct caif_device_entry *caif_device_alloc(struct net_device *dev)
        struct caif_device_entry *caifd;
 
        caifdevs = caif_device_list(dev_net(dev));
-       if (!caifdevs)
-               return NULL;
 
        caifd = kzalloc(sizeof(*caifd), GFP_KERNEL);
        if (!caifd)
@@ -120,8 +114,6 @@ static struct caif_device_entry *caif_get(struct net_device *dev)
        struct caif_device_entry_list *caifdevs =
            caif_device_list(dev_net(dev));
        struct caif_device_entry *caifd;
-       if (!caifdevs)
-               return NULL;
 
        list_for_each_entry_rcu(caifd, &caifdevs->list, list) {
                if (caifd->netdev == dev)
@@ -321,8 +313,6 @@ void caif_enroll_dev(struct net_device *dev, struct caif_dev_common *caifdev,
        struct caif_device_entry_list *caifdevs;
 
        caifdevs = caif_device_list(dev_net(dev));
-       if (!cfg || !caifdevs)
-               return;
        caifd = caif_device_alloc(dev);
        if (!caifd)
                return;
@@ -374,8 +364,6 @@ static int caif_device_notify(struct notifier_block *me, unsigned long what,
 
        cfg = get_cfcnfg(dev_net(dev));
        caifdevs = caif_device_list(dev_net(dev));
-       if (!cfg || !caifdevs)
-               return 0;
 
        caifd = caif_get(dev);
        if (caifd == NULL && dev->type != ARPHRD_CAIF)
@@ -507,9 +495,6 @@ static struct notifier_block caif_device_notifier = {
 static int caif_init_net(struct net *net)
 {
        struct caif_net *caifn = net_generic(net, caif_net_id);
-       if (WARN_ON(!caifn))
-               return -EINVAL;
-
        INIT_LIST_HEAD(&caifn->caifdevs.list);
        mutex_init(&caifn->caifdevs.lock);
 
@@ -527,9 +512,6 @@ static void caif_exit_net(struct net *net)
            caif_device_list(net);
        struct cfcnfg *cfg =  get_cfcnfg(net);
 
-       if (!cfg || !caifdevs)
-               return;
-
        rtnl_lock();
        mutex_lock(&caifdevs->lock);
 
@@ -569,7 +551,7 @@ static int __init caif_device_init(void)
 {
        int result;
 
-       result = register_pernet_device(&caif_net_ops);
+       result = register_pernet_subsys(&caif_net_ops);
 
        if (result)
                return result;
@@ -582,7 +564,7 @@ static int __init caif_device_init(void)
 
 static void __exit caif_device_exit(void)
 {
-       unregister_pernet_device(&caif_net_ops);
+       unregister_pernet_subsys(&caif_net_ops);
        unregister_netdevice_notifier(&caif_device_notifier);
        dev_remove_pack(&caif_packet_type);
 }
index a986280..a97d97a 100644 (file)
@@ -539,8 +539,10 @@ static int transmit_skb(struct sk_buff *skb, struct caifsock *cf_sk,
        pkt = cfpkt_fromnative(CAIF_DIR_OUT, skb);
        memset(skb->cb, 0, sizeof(struct caif_payload_info));
 
-       if (cf_sk->layer.dn == NULL)
+       if (cf_sk->layer.dn == NULL) {
+               kfree_skb(skb);
                return -EINVAL;
+       }
 
        return cf_sk->layer.dn->transmit(cf_sk->layer.dn, pkt);
 }
@@ -683,10 +685,10 @@ static int caif_stream_sendmsg(struct kiocb *kiocb, struct socket *sock,
                }
                err = transmit_skb(skb, cf_sk,
                                msg->msg_flags&MSG_DONTWAIT, timeo);
-               if (err < 0) {
-                       kfree_skb(skb);
+               if (err < 0)
+                       /* skb is already freed */
                        goto pipe_err;
-               }
+
                sent += size;
        }
 
index 598aafb..ba9cfd4 100644 (file)
@@ -309,7 +309,6 @@ int caif_connect_client(struct net *net, struct caif_connect_request *conn_req,
        int err;
        struct cfctrl_link_param param;
        struct cfcnfg *cfg = get_cfcnfg(net);
-       caif_assert(cfg != NULL);
 
        rcu_read_lock();
        err = caif_connect_req_to_link_param(cfg, conn_req, &param);
index b36f24a..94b0861 100644 (file)
@@ -248,7 +248,6 @@ static void cfmuxl_ctrlcmd(struct cflayer *layr, enum caif_ctrlcmd ctrl,
 {
        struct cfmuxl *muxl = container_obj(layr);
        struct cflayer *layer;
-       int idx;
 
        rcu_read_lock();
        list_for_each_entry_rcu(layer, &muxl->srvl_list, node) {
@@ -257,14 +256,9 @@ static void cfmuxl_ctrlcmd(struct cflayer *layr, enum caif_ctrlcmd ctrl,
 
                        if ((ctrl == _CAIF_CTRLCMD_PHYIF_DOWN_IND ||
                                ctrl == CAIF_CTRLCMD_REMOTE_SHUTDOWN_IND) &&
-                                       layer->id != 0) {
-
-                               idx = layer->id % UP_CACHE_SIZE;
-                               spin_lock_bh(&muxl->receive_lock);
-                               RCU_INIT_POINTER(muxl->up_cache[idx], NULL);
-                               list_del_rcu(&layer->node);
-                               spin_unlock_bh(&muxl->receive_lock);
-                       }
+                                       layer->id != 0)
+                               cfmuxl_remove_uplayer(layr, layer->id);
+
                        /* NOTE: ctrlcmd is not allowed to block */
                        layer->ctrlcmd(layer, ctrl, phyid);
                }
index 97f70e5..761ad9d 100644 (file)
@@ -85,8 +85,6 @@ int ceph_check_fsid(struct ceph_client *client, struct ceph_fsid *fsid)
        } else {
                pr_info("client%lld fsid %pU\n", ceph_client_id(client), fsid);
                memcpy(&client->fsid, fsid, sizeof(*fsid));
-               ceph_debugfs_client_init(client);
-               client->have_fsid = true;
        }
        return 0;
 }
index 0b62dea..1845cde 100644 (file)
@@ -8,8 +8,8 @@
 
 #include <linux/ceph/mon_client.h>
 #include <linux/ceph/libceph.h>
+#include <linux/ceph/debugfs.h>
 #include <linux/ceph/decode.h>
-
 #include <linux/ceph/auth.h>
 
 /*
@@ -340,8 +340,19 @@ static void ceph_monc_handle_map(struct ceph_mon_client *monc,
        client->monc.monmap = monmap;
        kfree(old);
 
+       if (!client->have_fsid) {
+               client->have_fsid = true;
+               mutex_unlock(&monc->mutex);
+               /*
+                * do debugfs initialization without mutex to avoid
+                * creating a locking dependency
+                */
+               ceph_debugfs_client_init(client);
+               goto out_unlocked;
+       }
 out:
        mutex_unlock(&monc->mutex);
+out_unlocked:
        wake_up_all(&client->auth_wq);
 }
 
index 115dee1..6ca32f6 100644 (file)
@@ -3500,14 +3500,20 @@ static inline gro_result_t
 __napi_gro_receive(struct napi_struct *napi, struct sk_buff *skb)
 {
        struct sk_buff *p;
+       unsigned int maclen = skb->dev->hard_header_len;
 
        for (p = napi->gro_list; p; p = p->next) {
                unsigned long diffs;
 
                diffs = (unsigned long)p->dev ^ (unsigned long)skb->dev;
                diffs |= p->vlan_tci ^ skb->vlan_tci;
-               diffs |= compare_ether_header(skb_mac_header(p),
-                                             skb_gro_mac_header(skb));
+               if (maclen == ETH_HLEN)
+                       diffs |= compare_ether_header(skb_mac_header(p),
+                                                     skb_gro_mac_header(skb));
+               else if (!diffs)
+                       diffs = memcmp(skb_mac_header(p),
+                                      skb_gro_mac_header(skb),
+                                      maclen);
                NAPI_GRO_CB(p)->same_flow = !diffs;
                NAPI_GRO_CB(p)->flush = 0;
        }
index 369b418..3f79db1 100644 (file)
@@ -1190,6 +1190,8 @@ static noinline_for_stack int ethtool_flash_device(struct net_device *dev,
        if (!dev->ethtool_ops->flash_device)
                return -EOPNOTSUPP;
 
+       efl.data[ETHTOOL_FLASH_MAX_FILENAME - 1] = 0;
+
        return dev->ethtool_ops->flash_device(dev, &efl);
 }
 
index aefcd7a..0e950fd 100644 (file)
@@ -30,6 +30,20 @@ EXPORT_SYMBOL(init_net);
 
 #define INITIAL_NET_GEN_PTRS   13 /* +1 for len +2 for rcu_head */
 
+static unsigned int max_gen_ptrs = INITIAL_NET_GEN_PTRS;
+
+static struct net_generic *net_alloc_generic(void)
+{
+       struct net_generic *ng;
+       size_t generic_size = offsetof(struct net_generic, ptr[max_gen_ptrs]);
+
+       ng = kzalloc(generic_size, GFP_KERNEL);
+       if (ng)
+               ng->len = max_gen_ptrs;
+
+       return ng;
+}
+
 static int net_assign_generic(struct net *net, int id, void *data)
 {
        struct net_generic *ng, *old_ng;
@@ -43,8 +57,7 @@ static int net_assign_generic(struct net *net, int id, void *data)
        if (old_ng->len >= id)
                goto assign;
 
-       ng = kzalloc(sizeof(struct net_generic) +
-                       id * sizeof(void *), GFP_KERNEL);
+       ng = net_alloc_generic();
        if (ng == NULL)
                return -ENOMEM;
 
@@ -59,7 +72,6 @@ static int net_assign_generic(struct net *net, int id, void *data)
         * the old copy for kfree after a grace period.
         */
 
-       ng->len = id;
        memcpy(&ng->ptr, &old_ng->ptr, old_ng->len * sizeof(void*));
 
        rcu_assign_pointer(net->gen, ng);
@@ -161,18 +173,6 @@ out_undo:
        goto out;
 }
 
-static struct net_generic *net_alloc_generic(void)
-{
-       struct net_generic *ng;
-       size_t generic_size = sizeof(struct net_generic) +
-               INITIAL_NET_GEN_PTRS * sizeof(void *);
-
-       ng = kzalloc(generic_size, GFP_KERNEL);
-       if (ng)
-               ng->len = INITIAL_NET_GEN_PTRS;
-
-       return ng;
-}
 
 #ifdef CONFIG_NET_NS
 static struct kmem_cache *net_cachep;
@@ -483,6 +483,7 @@ again:
                        }
                        return error;
                }
+               max_gen_ptrs = max_t(unsigned int, max_gen_ptrs, *ops->id);
        }
        error = __register_pernet_operations(list, ops);
        if (error) {
index 3a9fd48..4dacc44 100644 (file)
@@ -58,11 +58,12 @@ static int get_prioidx(u32 *prio)
 
        spin_lock_irqsave(&prioidx_map_lock, flags);
        prioidx = find_first_zero_bit(prioidx_map, sizeof(unsigned long) * PRIOIDX_SZ);
+       if (prioidx == sizeof(unsigned long) * PRIOIDX_SZ) {
+               spin_unlock_irqrestore(&prioidx_map_lock, flags);
+               return -ENOSPC;
+       }
        set_bit(prioidx, prioidx_map);
        spin_unlock_irqrestore(&prioidx_map_lock, flags);
-       if (prioidx == sizeof(unsigned long) * PRIOIDX_SZ)
-               return -ENOSPC;
-
        atomic_set(&max_prioidx, prioidx);
        *prio = prioidx;
        return 0;
@@ -107,7 +108,7 @@ static void extend_netdev_table(struct net_device *dev, u32 new_len)
 static void update_netdev_tables(void)
 {
        struct net_device *dev;
-       u32 max_len = atomic_read(&max_prioidx);
+       u32 max_len = atomic_read(&max_prioidx) + 1;
        struct netprio_map *map;
 
        rtnl_lock();
@@ -270,7 +271,6 @@ static int netprio_device_event(struct notifier_block *unused,
 {
        struct net_device *dev = ptr;
        struct netprio_map *old;
-       u32 max_len = atomic_read(&max_prioidx);
 
        /*
         * Note this is called with rtnl_lock held so we have update side
@@ -278,11 +278,6 @@ static int netprio_device_event(struct notifier_block *unused,
         */
 
        switch (event) {
-
-       case NETDEV_REGISTER:
-               if (max_len)
-                       extend_netdev_table(dev, max_len);
-               break;
        case NETDEV_UNREGISTER:
                old = rtnl_dereference(dev->priomap);
                RCU_INIT_POINTER(dev->priomap, NULL);
index f16444b..65aebd4 100644 (file)
@@ -1509,6 +1509,9 @@ errout:
 
        if (send_addr_notify)
                call_netdevice_notifiers(NETDEV_CHANGEADDR, dev);
+       min_ifinfo_dump_size = max_t(u16, if_nlmsg_size(dev),
+                                    min_ifinfo_dump_size);
+
        return err;
 }
 
index 3e81fd2..02f8dfe 100644 (file)
@@ -1171,13 +1171,10 @@ EXPORT_SYMBOL(sock_update_classid);
 
 void sock_update_netprioidx(struct sock *sk)
 {
-       struct cgroup_netprio_state *state;
        if (in_interrupt())
                return;
-       rcu_read_lock();
-       state = task_netprio_state(current);
-       sk->sk_cgrp_prioidx = state ? state->prioidx : 0;
-       rcu_read_unlock();
+
+       sk->sk_cgrp_prioidx = task_netprioidx(current);
 }
 EXPORT_SYMBOL_GPL(sock_update_netprioidx);
 #endif
index aa2a2c7..d183262 100644 (file)
@@ -409,7 +409,7 @@ config INET_TCP_DIAG
 
 config INET_UDP_DIAG
        tristate "UDP: socket monitoring interface"
-       depends on INET_DIAG
+       depends on INET_DIAG && (IPV6 || IPV6=n)
        default n
        ---help---
          Support for UDP socket monitoring interface used by the ss tool.
index 59402be..63e4989 100644 (file)
@@ -863,7 +863,8 @@ static int arp_process(struct sk_buff *skb)
                        if (addr_type == RTN_UNICAST  &&
                            (arp_fwd_proxy(in_dev, dev, rt) ||
                             arp_fwd_pvlan(in_dev, dev, rt, sip, tip) ||
-                            pneigh_lookup(&arp_tbl, net, &tip, dev, 0))) {
+                            (rt->dst.dev != dev &&
+                             pneigh_lookup(&arp_tbl, net, &tip, dev, 0)))) {
                                n = neigh_event_ns(&arp_tbl, sha, &sip, dev);
                                if (n)
                                        neigh_release(n);
index 2e4e244..19d66ce 100644 (file)
@@ -123,11 +123,14 @@ again:
                                                smallest_size = tb->num_owners;
                                                smallest_rover = rover;
                                                if (atomic_read(&hashinfo->bsockets) > (high - low) + 1) {
-                                                       spin_unlock(&head->lock);
                                                        snum = smallest_rover;
-                                                       goto have_snum;
+                                                       goto tb_found;
                                                }
                                        }
+                                       if (!inet_csk(sk)->icsk_af_ops->bind_conflict(sk, tb)) {
+                                               snum = rover;
+                                               goto tb_found;
+                                       }
                                        goto next;
                                }
                        break;
index 2b53a1f..6b3ca5b 100644 (file)
@@ -422,6 +422,10 @@ static struct ip_tunnel *ipgre_tunnel_locate(struct net *net,
        if (register_netdevice(dev) < 0)
                goto failed_free;
 
+       /* Can use a lockless transmit, unless we generate output sequences */
+       if (!(nt->parms.o_flags & GRE_SEQ))
+               dev->features |= NETIF_F_LLTX;
+
        dev_hold(dev);
        ipgre_tunnel_link(ign, nt);
        return nt;
index 1e60f76..42dd1a9 100644 (file)
@@ -573,8 +573,8 @@ void ip_forward_options(struct sk_buff *skb)
                }
                if (srrptr + 3 <= srrspace) {
                        opt->is_changed = 1;
-                       ip_rt_get_source(&optptr[srrptr-1], skb, rt);
                        ip_hdr(skb)->daddr = opt->nexthop;
+                       ip_rt_get_source(&optptr[srrptr-1], skb, rt);
                        optptr[2] = srrptr+4;
                } else if (net_ratelimit())
                        printk(KERN_CRIT "ip_forward(): Argh! Destination lost!\n");
index 4aa7e9d..7a7724d 100644 (file)
@@ -778,7 +778,6 @@ EXPORT_SYMBOL_GPL(net_ipv4_ctl_path);
 static __net_init int ipv4_sysctl_init_net(struct net *net)
 {
        struct ctl_table *table;
-       unsigned long limit;
 
        table = ipv4_net_table;
        if (!net_eq(net, &init_net)) {
@@ -814,11 +813,7 @@ static __net_init int ipv4_sysctl_init_net(struct net *net)
 
        net->ipv4.sysctl_rt_cache_rebuild_count = 4;
 
-       limit = nr_free_buffer_pages() / 8;
-       limit = max(limit, 128UL);
-       net->ipv4.sysctl_tcp_mem[0] = limit / 4 * 3;
-       net->ipv4.sysctl_tcp_mem[1] = limit;
-       net->ipv4.sysctl_tcp_mem[2] = net->ipv4.sysctl_tcp_mem[0] * 2;
+       tcp_init_mem(net);
 
        net->ipv4.ipv4_hdr = register_net_sysctl_table(net,
                        net_ipv4_ctl_path, table);
index 9bcdec3..37755cc 100644 (file)
@@ -1876,6 +1876,20 @@ void tcp_shutdown(struct sock *sk, int how)
 }
 EXPORT_SYMBOL(tcp_shutdown);
 
+bool tcp_check_oom(struct sock *sk, int shift)
+{
+       bool too_many_orphans, out_of_socket_memory;
+
+       too_many_orphans = tcp_too_many_orphans(sk, shift);
+       out_of_socket_memory = tcp_out_of_memory(sk);
+
+       if (too_many_orphans && net_ratelimit())
+               pr_info("TCP: too many orphaned sockets\n");
+       if (out_of_socket_memory && net_ratelimit())
+               pr_info("TCP: out of memory -- consider tuning tcp_mem\n");
+       return too_many_orphans || out_of_socket_memory;
+}
+
 void tcp_close(struct sock *sk, long timeout)
 {
        struct sk_buff *skb;
@@ -2015,10 +2029,7 @@ adjudge_to_death:
        }
        if (sk->sk_state != TCP_CLOSE) {
                sk_mem_reclaim(sk);
-               if (tcp_too_many_orphans(sk, 0)) {
-                       if (net_ratelimit())
-                               printk(KERN_INFO "TCP: too many of orphaned "
-                                      "sockets\n");
+               if (tcp_check_oom(sk, 0)) {
                        tcp_set_state(sk, TCP_CLOSE);
                        tcp_send_active_reset(sk, GFP_ATOMIC);
                        NET_INC_STATS_BH(sock_net(sk),
@@ -3216,6 +3227,15 @@ static int __init set_thash_entries(char *str)
 }
 __setup("thash_entries=", set_thash_entries);
 
+void tcp_init_mem(struct net *net)
+{
+       unsigned long limit = nr_free_buffer_pages() / 8;
+       limit = max(limit, 128UL);
+       net->ipv4.sysctl_tcp_mem[0] = limit / 4 * 3;
+       net->ipv4.sysctl_tcp_mem[1] = limit;
+       net->ipv4.sysctl_tcp_mem[2] = net->ipv4.sysctl_tcp_mem[0] * 2;
+}
+
 void __init tcp_init(void)
 {
        struct sk_buff *skb = NULL;
@@ -3276,9 +3296,10 @@ void __init tcp_init(void)
        sysctl_tcp_max_orphans = cnt / 2;
        sysctl_max_syn_backlog = max(128, cnt / 256);
 
+       tcp_init_mem(&init_net);
        /* Set per-socket limits to no more than 1/128 the pressure threshold */
-       limit = ((unsigned long)init_net.ipv4.sysctl_tcp_mem[1])
-               << (PAGE_SHIFT - 7);
+       limit = nr_free_buffer_pages() << (PAGE_SHIFT - 10);
+       limit = max(limit, 128UL);
        max_share = min(4UL*1024*1024, limit);
 
        sysctl_tcp_wmem[0] = SK_MEM_QUANTUM;
index 337ba4c..94d683a 100644 (file)
@@ -651,6 +651,11 @@ static void tcp_v4_send_reset(struct sock *sk, struct sk_buff *skb)
                                      arg.iov[0].iov_len, IPPROTO_TCP, 0);
        arg.csumoffset = offsetof(struct tcphdr, check) / 2;
        arg.flags = (sk && inet_sk(sk)->transparent) ? IP_REPLY_ARG_NOSRCCHECK : 0;
+       /* When socket is gone, all binding information is lost.
+        * routing might fail in this case. using iif for oif to
+        * make sure we can deliver it
+        */
+       arg.bound_dev_if = sk ? sk->sk_bound_dev_if : inet_iif(skb);
 
        net = dev_net(skb_dst(skb)->dev);
        arg.tos = ip_hdr(skb)->tos;
index 8c8de27..4ff3b6d 100644 (file)
@@ -1141,11 +1141,9 @@ int tcp_trim_head(struct sock *sk, struct sk_buff *skb, u32 len)
        sk_mem_uncharge(sk, len);
        sock_set_flag(sk, SOCK_QUEUE_SHRUNK);
 
-       /* Any change of skb->len requires recalculation of tso
-        * factor and mss.
-        */
+       /* Any change of skb->len requires recalculation of tso factor. */
        if (tcp_skb_pcount(skb) > 1)
-               tcp_set_skb_tso_segs(sk, skb, tcp_current_mss(sk));
+               tcp_set_skb_tso_segs(sk, skb, tcp_skb_mss(skb));
 
        return 0;
 }
index a516d1e..cd2e072 100644 (file)
@@ -77,10 +77,7 @@ static int tcp_out_of_resources(struct sock *sk, int do_reset)
        if (sk->sk_err_soft)
                shift++;
 
-       if (tcp_too_many_orphans(sk, shift)) {
-               if (net_ratelimit())
-                       printk(KERN_INFO "Out of socket memory\n");
-
+       if (tcp_check_oom(sk, shift)) {
                /* Catch exceptional cases, when connection requires reset.
                 *      1. Last segment was sent recently. */
                if ((s32)(tcp_time_stamp - tp->lsndtime) <= TCP_TIMEWAIT_LEN ||
index d21e7eb..55670ec 100644 (file)
@@ -393,11 +393,6 @@ static int l2tp_ip_backlog_recv(struct sock *sk, struct sk_buff *skb)
 {
        int rc;
 
-       if (!xfrm4_policy_check(sk, XFRM_POLICY_IN, skb))
-               goto drop;
-
-       nf_reset(skb);
-
        /* Charge it to the socket, dropping if the queue is full. */
        rc = sock_queue_rcv_skb(sk, skb);
        if (rc < 0)
index b3d76b7..a464396 100644 (file)
@@ -106,6 +106,7 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
 
        sdata->drop_unencrypted = capability & WLAN_CAPABILITY_PRIVACY ? 1 : 0;
 
+       local->oper_channel = chan;
        channel_type = ifibss->channel_type;
        if (channel_type > NL80211_CHAN_HT20 &&
            !cfg80211_can_beacon_sec_chan(local->hw.wiphy, chan, channel_type))
index e47768c..01a21c2 100644 (file)
@@ -1314,6 +1314,7 @@ u32 __ieee80211_recalc_idle(struct ieee80211_local *local)
                        continue;
                }
                /* count everything else */
+               sdata->vif.bss_conf.idle = false;
                count++;
        }
 
index 7514091..5a5e504 100644 (file)
@@ -611,7 +611,7 @@ static void ieee80211_sta_reorder_release(struct ieee80211_hw *hw,
        index = seq_sub(tid_agg_rx->head_seq_num, tid_agg_rx->ssn) %
                                                tid_agg_rx->buf_size;
        if (!tid_agg_rx->reorder_buf[index] &&
-           tid_agg_rx->stored_mpdu_num > 1) {
+           tid_agg_rx->stored_mpdu_num) {
                /*
                 * No buffers ready to be released, but check whether any
                 * frames in the reorder buffer have timed out.
index e465064..7e267d7 100644 (file)
@@ -148,8 +148,7 @@ struct choke_skb_cb {
 
 static inline struct choke_skb_cb *choke_skb_cb(const struct sk_buff *skb)
 {
-       BUILD_BUG_ON(sizeof(skb->cb) <
-               sizeof(struct qdisc_skb_cb) + sizeof(struct choke_skb_cb));
+       qdisc_cb_private_validate(skb, sizeof(struct choke_skb_cb));
        return (struct choke_skb_cb *)qdisc_skb_cb(skb)->data;
 }
 
index 2776012..e83d61c 100644 (file)
@@ -130,8 +130,7 @@ struct netem_skb_cb {
 
 static inline struct netem_skb_cb *netem_skb_cb(struct sk_buff *skb)
 {
-       BUILD_BUG_ON(sizeof(skb->cb) <
-               sizeof(struct qdisc_skb_cb) + sizeof(struct netem_skb_cb));
+       qdisc_cb_private_validate(skb, sizeof(struct netem_skb_cb));
        return (struct netem_skb_cb *)qdisc_skb_cb(skb)->data;
 }
 
index 96e42ca..d7eea99 100644 (file)
@@ -94,8 +94,7 @@ struct sfb_skb_cb {
 
 static inline struct sfb_skb_cb *sfb_skb_cb(const struct sk_buff *skb)
 {
-       BUILD_BUG_ON(sizeof(skb->cb) <
-               sizeof(struct qdisc_skb_cb) + sizeof(struct sfb_skb_cb));
+       qdisc_cb_private_validate(skb, sizeof(struct sfb_skb_cb));
        return (struct sfb_skb_cb *)qdisc_skb_cb(skb)->data;
 }
 
index 67494ae..60d4718 100644 (file)
@@ -166,9 +166,8 @@ struct sfq_skb_cb {
 
 static inline struct sfq_skb_cb *sfq_skb_cb(const struct sk_buff *skb)
 {
-       BUILD_BUG_ON(sizeof(skb->cb) <
-               sizeof(struct qdisc_skb_cb) + sizeof(struct sfq_skb_cb));
-       return (struct sfq_skb_cb *)qdisc_skb_cb(skb)->data;
+       qdisc_cb_private_validate(skb, sizeof(struct sfq_skb_cb));
+       return (struct sfq_skb_cb *)qdisc_skb_cb(skb)->data;
 }
 
 static unsigned int sfq_hash(const struct sfq_sched_data *q,
index 1426ec3..75762f3 100644 (file)
@@ -92,6 +92,7 @@ generic_create_cred(struct rpc_auth *auth, struct auth_cred *acred, int flags)
        if (gcred->acred.group_info != NULL)
                get_group_info(gcred->acred.group_info);
        gcred->acred.machine_cred = acred->machine_cred;
+       gcred->acred.principal = acred->principal;
 
        dprintk("RPC:       allocated %s cred %p for uid %d gid %d\n",
                        gcred->acred.machine_cred ? "machine" : "generic",
@@ -123,6 +124,17 @@ generic_destroy_cred(struct rpc_cred *cred)
        call_rcu(&cred->cr_rcu, generic_free_cred_callback);
 }
 
+static int
+machine_cred_match(struct auth_cred *acred, struct generic_cred *gcred, int flags)
+{
+       if (!gcred->acred.machine_cred ||
+           gcred->acred.principal != acred->principal ||
+           gcred->acred.uid != acred->uid ||
+           gcred->acred.gid != acred->gid)
+               return 0;
+       return 1;
+}
+
 /*
  * Match credentials against current process creds.
  */
@@ -132,9 +144,12 @@ generic_match(struct auth_cred *acred, struct rpc_cred *cred, int flags)
        struct generic_cred *gcred = container_of(cred, struct generic_cred, gc_base);
        int i;
 
+       if (acred->machine_cred)
+               return machine_cred_match(acred, gcred, flags);
+
        if (gcred->acred.uid != acred->uid ||
            gcred->acred.gid != acred->gid ||
-           gcred->acred.machine_cred != acred->machine_cred)
+           gcred->acred.machine_cred != 0)
                goto out_nomatch;
 
        /* Optimisation in the case where pointers are identical... */
index aad8fb6..85d3bb7 100644 (file)
@@ -1918,7 +1918,7 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock,
                struct sk_buff *skb;
 
                unix_state_lock(sk);
-               skb = skb_dequeue(&sk->sk_receive_queue);
+               skb = skb_peek(&sk->sk_receive_queue);
                if (skb == NULL) {
                        unix_sk(sk)->recursion_level = 0;
                        if (copied >= target)
@@ -1958,11 +1958,8 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock,
                if (check_creds) {
                        /* Never glue messages from different writers */
                        if ((UNIXCB(skb).pid  != siocb->scm->pid) ||
-                           (UNIXCB(skb).cred != siocb->scm->cred)) {
-                               skb_queue_head(&sk->sk_receive_queue, skb);
-                               sk->sk_data_ready(sk, skb->len);
+                           (UNIXCB(skb).cred != siocb->scm->cred))
                                break;
-                       }
                } else {
                        /* Copy credentials */
                        scm_set_cred(siocb->scm, UNIXCB(skb).pid, UNIXCB(skb).cred);
@@ -1977,8 +1974,6 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock,
 
                chunk = min_t(unsigned int, skb->len, size);
                if (memcpy_toiovec(msg->msg_iov, skb->data, chunk)) {
-                       skb_queue_head(&sk->sk_receive_queue, skb);
-                       sk->sk_data_ready(sk, skb->len);
                        if (copied == 0)
                                copied = -EFAULT;
                        break;
@@ -1993,13 +1988,10 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock,
                        if (UNIXCB(skb).fp)
                                unix_detach_fds(siocb->scm, skb);
 
-                       /* put the skb back if we didn't use it up.. */
-                       if (skb->len) {
-                               skb_queue_head(&sk->sk_receive_queue, skb);
-                               sk->sk_data_ready(sk, skb->len);
+                       if (skb->len)
                                break;
-                       }
 
+                       skb_unlink(skb, &sk->sk_receive_queue);
                        consume_skb(skb);
 
                        if (siocb->scm->fp)
@@ -2010,9 +2002,6 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock,
                        if (UNIXCB(skb).fp)
                                siocb->scm->fp = scm_fp_dup(UNIXCB(skb).fp);
 
-                       /* put message back and return */
-                       skb_queue_head(&sk->sk_receive_queue, skb);
-                       sk->sk_data_ready(sk, skb->len);
                        break;
                }
        } while (size);
index e3bfcbe..a3b9782 100755 (executable)
@@ -1924,6 +1924,12 @@ sub process {
                        my $pre_ctx = "$1$2";
 
                        my ($level, @ctx) = ctx_statement_level($linenr, $realcnt, 0);
+
+                       if ($line =~ /^\+\t{6,}/) {
+                               WARN("DEEP_INDENTATION",
+                                    "Too many leading tabs - consider code refactoring\n" . $herecurr);
+                       }
+
                        my $ctx_cnt = $realcnt - $#ctx - 1;
                        my $ctx = join("\n", @ctx);
 
index c0e14b3..d0de2a2 100644 (file)
@@ -823,16 +823,6 @@ static int do_spi_entry(const char *filename, struct spi_device_id *id,
 }
 ADD_TO_DEVTABLE("spi", struct spi_device_id, do_spi_entry);
 
-/* Looks like: mcp:S */
-static int do_mcp_entry(const char *filename, struct mcp_device_id *id,
-                       char *alias)
-{
-       sprintf(alias, MCP_MODULE_PREFIX "%s", id->name);
-
-       return 1;
-}
-ADD_TO_DEVTABLE("mcp", struct mcp_device_id, do_mcp_entry); 
-
 static const struct dmifield {
        const char *prefix;
        int field;
@@ -942,7 +932,7 @@ static int do_isapnp_entry(const char *filename,
                (id->function >> 12) & 0x0f, (id->function >> 8) & 0x0f);
        return 1;
 }
-ADD_TO_DEVTABLE("isa", struct isapnp_device_id, do_isapnp_entry);
+ADD_TO_DEVTABLE("isapnp", struct isapnp_device_id, do_isapnp_entry);
 
 /*
  * Append a match expression for a single masked hex digit.
index e09f144..c99c607 100644 (file)
@@ -22,7 +22,6 @@
 #include "emu8000_local.h"
 #include <asm/uaccess.h>
 #include <linux/moduleparam.h>
-#include <linux/moduleparam.h>
 
 static int emu8000_reset_addr;
 module_param(emu8000_reset_addr, int, 0444);
index 4df72c0..c2c65f6 100644 (file)
@@ -1447,7 +1447,7 @@ void snd_hda_codec_setup_stream(struct hda_codec *codec, hda_nid_t nid,
                for (i = 0; i < c->cvt_setups.used; i++) {
                        p = snd_array_elem(&c->cvt_setups, i);
                        if (!p->active && p->stream_tag == stream_tag &&
-                           get_wcaps_type(get_wcaps(codec, p->nid)) == type)
+                           get_wcaps_type(get_wcaps(c, p->nid)) == type)
                                p->dirty = 1;
                }
        }
index d8a35da..9d819c4 100644 (file)
@@ -282,7 +282,8 @@ int snd_hda_jack_add_kctl(struct hda_codec *codec, hda_nid_t nid,
 EXPORT_SYMBOL_HDA(snd_hda_jack_add_kctl);
 
 static int add_jack_kctl(struct hda_codec *codec, hda_nid_t nid,
-                        const struct auto_pin_cfg *cfg)
+                        const struct auto_pin_cfg *cfg,
+                        char *lastname, int *lastidx)
 {
        unsigned int def_conf, conn;
        char name[44];
@@ -298,6 +299,10 @@ static int add_jack_kctl(struct hda_codec *codec, hda_nid_t nid,
                return 0;
 
        snd_hda_get_pin_label(codec, nid, cfg, name, sizeof(name), &idx);
+       if (!strcmp(name, lastname) && idx == *lastidx)
+               idx++;
+       strncpy(lastname, name, 44);
+       *lastidx = idx;
        err = snd_hda_jack_add_kctl(codec, nid, name, idx);
        if (err < 0)
                return err;
@@ -311,41 +316,42 @@ int snd_hda_jack_add_kctls(struct hda_codec *codec,
                           const struct auto_pin_cfg *cfg)
 {
        const hda_nid_t *p;
-       int i, err;
+       int i, err, lastidx = 0;
+       char lastname[44] = "";
 
        for (i = 0, p = cfg->line_out_pins; i < cfg->line_outs; i++, p++) {
-               err = add_jack_kctl(codec, *p, cfg);
+               err = add_jack_kctl(codec, *p, cfg, lastname, &lastidx);
                if (err < 0)
                        return err;
        }
        for (i = 0, p = cfg->hp_pins; i < cfg->hp_outs; i++, p++) {
                if (*p == *cfg->line_out_pins) /* might be duplicated */
                        break;
-               err = add_jack_kctl(codec, *p, cfg);
+               err = add_jack_kctl(codec, *p, cfg, lastname, &lastidx);
                if (err < 0)
                        return err;
        }
        for (i = 0, p = cfg->speaker_pins; i < cfg->speaker_outs; i++, p++) {
                if (*p == *cfg->line_out_pins) /* might be duplicated */
                        break;
-               err = add_jack_kctl(codec, *p, cfg);
+               err = add_jack_kctl(codec, *p, cfg, lastname, &lastidx);
                if (err < 0)
                        return err;
        }
        for (i = 0; i < cfg->num_inputs; i++) {
-               err = add_jack_kctl(codec, cfg->inputs[i].pin, cfg);
+               err = add_jack_kctl(codec, cfg->inputs[i].pin, cfg, lastname, &lastidx);
                if (err < 0)
                        return err;
        }
        for (i = 0, p = cfg->dig_out_pins; i < cfg->dig_outs; i++, p++) {
-               err = add_jack_kctl(codec, *p, cfg);
+               err = add_jack_kctl(codec, *p, cfg, lastname, &lastidx);
                if (err < 0)
                        return err;
        }
-       err = add_jack_kctl(codec, cfg->dig_in_pin, cfg);
+       err = add_jack_kctl(codec, cfg->dig_in_pin, cfg, lastname, &lastidx);
        if (err < 0)
                return err;
-       err = add_jack_kctl(codec, cfg->mono_out_pin, cfg);
+       err = add_jack_kctl(codec, cfg->mono_out_pin, cfg, lastname, &lastidx);
        if (err < 0)
                return err;
        return 0;
index 35abe3c..21d91d5 100644 (file)
@@ -728,18 +728,19 @@ static int ca0132_hp_switch_put(struct snd_kcontrol *kcontrol,
 
        err = chipio_read(codec, REG_CODEC_MUTE, &data);
        if (err < 0)
-               return err;
+               goto exit;
 
        /* *valp 0 is mute, 1 is unmute */
        data = (data & 0x7f) | (*valp ? 0 : 0x80);
-       chipio_write(codec, REG_CODEC_MUTE, data);
+       err = chipio_write(codec, REG_CODEC_MUTE, data);
        if (err < 0)
-               return err;
+               goto exit;
 
        spec->curr_hp_switch = *valp;
 
+ exit:
        snd_hda_power_down(codec);
-       return 1;
+       return err < 0 ? err : 1;
 }
 
 static int ca0132_speaker_switch_get(struct snd_kcontrol *kcontrol,
@@ -770,18 +771,19 @@ static int ca0132_speaker_switch_put(struct snd_kcontrol *kcontrol,
 
        err = chipio_read(codec, REG_CODEC_MUTE, &data);
        if (err < 0)
-               return err;
+               goto exit;
 
        /* *valp 0 is mute, 1 is unmute */
        data = (data & 0xef) | (*valp ? 0 : 0x10);
-       chipio_write(codec, REG_CODEC_MUTE, data);
+       err = chipio_write(codec, REG_CODEC_MUTE, data);
        if (err < 0)
-               return err;
+               goto exit;
 
        spec->curr_speaker_switch = *valp;
 
+ exit:
        snd_hda_power_down(codec);
-       return 1;
+       return err < 0 ? err : 1;
 }
 
 static int ca0132_hp_volume_get(struct snd_kcontrol *kcontrol,
@@ -819,25 +821,26 @@ static int ca0132_hp_volume_put(struct snd_kcontrol *kcontrol,
 
        err = chipio_read(codec, REG_CODEC_HP_VOL_L, &data);
        if (err < 0)
-               return err;
+               goto exit;
 
        val = 31 - left_vol;
        data = (data & 0xe0) | val;
-       chipio_write(codec, REG_CODEC_HP_VOL_L, data);
+       err = chipio_write(codec, REG_CODEC_HP_VOL_L, data);
        if (err < 0)
-               return err;
+               goto exit;
 
        val = 31 - right_vol;
        data = (data & 0xe0) | val;
-       chipio_write(codec, REG_CODEC_HP_VOL_R, data);
+       err = chipio_write(codec, REG_CODEC_HP_VOL_R, data);
        if (err < 0)
-               return err;
+               goto exit;
 
        spec->curr_hp_volume[0] = left_vol;
        spec->curr_hp_volume[1] = right_vol;
 
+ exit:
        snd_hda_power_down(codec);
-       return 1;
+       return err < 0 ? err : 1;
 }
 
 static int add_hp_switch(struct hda_codec *codec, hda_nid_t nid)
@@ -936,6 +939,8 @@ static int ca0132_build_controls(struct hda_codec *codec)
                if (err < 0)
                        return err;
                err = add_in_volume(codec, spec->dig_in, "IEC958");
+               if (err < 0)
+                       return err;
        }
        return 0;
 }
index 0e99357..bc5a993 100644 (file)
@@ -988,8 +988,10 @@ static void cs_automic(struct hda_codec *codec)
                        change_cur_input(codec, !spec->automic_idx, 0);
        } else {
                if (present) {
-                       spec->last_input = spec->cur_input;
-                       spec->cur_input = spec->automic_idx;
+                       if (spec->cur_input != spec->automic_idx) {
+                               spec->last_input = spec->cur_input;
+                               spec->cur_input = spec->automic_idx;
+                       }
                } else  {
                        spec->cur_input = spec->last_input;
                }
index 0db1dc4..1358987 100644 (file)
@@ -177,6 +177,7 @@ struct alc_spec {
        unsigned int detect_lo:1;       /* Line-out detection enabled */
        unsigned int automute_speaker_possible:1; /* there are speakers and either LO or HP */
        unsigned int automute_lo_possible:1;      /* there are line outs and HP */
+       unsigned int keep_vref_in_automute:1; /* Don't clear VREF in automute */
 
        /* other flags */
        unsigned int no_analog :1; /* digital I/O only */
@@ -495,13 +496,24 @@ static void do_automute(struct hda_codec *codec, int num_pins, hda_nid_t *pins,
 
        for (i = 0; i < num_pins; i++) {
                hda_nid_t nid = pins[i];
+               unsigned int val;
                if (!nid)
                        break;
                switch (spec->automute_mode) {
                case ALC_AUTOMUTE_PIN:
+                       /* don't reset VREF value in case it's controlling
+                        * the amp (see alc861_fixup_asus_amp_vref_0f())
+                        */
+                       if (spec->keep_vref_in_automute) {
+                               val = snd_hda_codec_read(codec, nid, 0,
+                                       AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
+                               val &= ~PIN_HP;
+                       } else
+                               val = 0;
+                       val |= pin_bits;
                        snd_hda_codec_write(codec, nid, 0,
                                            AC_VERB_SET_PIN_WIDGET_CONTROL,
-                                           pin_bits);
+                                           val);
                        break;
                case ALC_AUTOMUTE_AMP:
                        snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
@@ -1843,6 +1855,8 @@ static const char * const alc_slave_vols[] = {
        "Speaker Playback Volume",
        "Mono Playback Volume",
        "Line-Out Playback Volume",
+       "CLFE Playback Volume",
+       "Bass Speaker Playback Volume",
        "PCM Playback Volume",
        NULL,
 };
@@ -1858,6 +1872,8 @@ static const char * const alc_slave_sws[] = {
        "Mono Playback Switch",
        "IEC958 Playback Switch",
        "Line-Out Playback Switch",
+       "CLFE Playback Switch",
+       "Bass Speaker Playback Switch",
        "PCM Playback Switch",
        NULL,
 };
@@ -2306,7 +2322,7 @@ static int alc_build_pcms(struct hda_codec *codec)
                 "%s Analog", codec->chip_name);
        info->name = spec->stream_name_analog;
 
-       if (spec->multiout.dac_nids > 0) {
+       if (spec->multiout.num_dacs > 0) {
                p = spec->stream_analog_playback;
                if (!p)
                        p = &alc_pcm_analog_playback;
@@ -4358,6 +4374,7 @@ enum {
        ALC882_FIXUP_ACER_ASPIRE_8930G,
        ALC882_FIXUP_ASPIRE_8930G_VERBS,
        ALC885_FIXUP_MACPRO_GPIO,
+       ALC889_FIXUP_DAC_ROUTE,
 };
 
 static void alc889_fixup_coef(struct hda_codec *codec,
@@ -4411,6 +4428,23 @@ static void alc885_fixup_macpro_gpio(struct hda_codec *codec,
        alc882_gpio_mute(codec, 1, 0);
 }
 
+/* Fix the connection of some pins for ALC889:
+ * At least, Acer Aspire 5935 shows the connections to DAC3/4 don't
+ * work correctly (bko#42740)
+ */
+static void alc889_fixup_dac_route(struct hda_codec *codec,
+                                  const struct alc_fixup *fix, int action)
+{
+       if (action == ALC_FIXUP_ACT_PRE_PROBE) {
+               hda_nid_t conn1[2] = { 0x0c, 0x0d };
+               hda_nid_t conn2[2] = { 0x0e, 0x0f };
+               snd_hda_override_conn_list(codec, 0x14, 2, conn1);
+               snd_hda_override_conn_list(codec, 0x15, 2, conn1);
+               snd_hda_override_conn_list(codec, 0x18, 2, conn2);
+               snd_hda_override_conn_list(codec, 0x1a, 2, conn2);
+       }
+}
+
 static const struct alc_fixup alc882_fixups[] = {
        [ALC882_FIXUP_ABIT_AW9D_MAX] = {
                .type = ALC_FIXUP_PINS,
@@ -4558,6 +4592,10 @@ static const struct alc_fixup alc882_fixups[] = {
                .type = ALC_FIXUP_FUNC,
                .v.func = alc885_fixup_macpro_gpio,
        },
+       [ALC889_FIXUP_DAC_ROUTE] = {
+               .type = ALC_FIXUP_FUNC,
+               .v.func = alc889_fixup_dac_route,
+       },
 };
 
 static const struct snd_pci_quirk alc882_fixup_tbl[] = {
@@ -4582,6 +4620,7 @@ static const struct snd_pci_quirk alc882_fixup_tbl[] = {
        SND_PCI_QUIRK(0x1025, 0x0142, "Acer Aspire 7730G",
                      ALC882_FIXUP_ACER_ASPIRE_4930G),
        SND_PCI_QUIRK(0x1025, 0x0155, "Packard-Bell M5120", ALC882_FIXUP_PB_M5210),
+       SND_PCI_QUIRK(0x1025, 0x0259, "Acer Aspire 5935", ALC889_FIXUP_DAC_ROUTE),
        SND_PCI_QUIRK(0x1025, 0x0296, "Acer Aspire 7736z", ALC882_FIXUP_ACER_ASPIRE_7736),
        SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_FIXUP_EAPD),
        SND_PCI_QUIRK(0x1043, 0x1873, "ASUS W90V", ALC882_FIXUP_ASUS_W90V),
@@ -4735,7 +4774,6 @@ enum {
        ALC262_FIXUP_FSC_H270,
        ALC262_FIXUP_HP_Z200,
        ALC262_FIXUP_TYAN,
-       ALC262_FIXUP_TOSHIBA_RX1,
        ALC262_FIXUP_LENOVO_3000,
        ALC262_FIXUP_BENQ,
        ALC262_FIXUP_BENQ_T31,
@@ -4765,16 +4803,6 @@ static const struct alc_fixup alc262_fixups[] = {
                        { }
                }
        },
-       [ALC262_FIXUP_TOSHIBA_RX1] = {
-               .type = ALC_FIXUP_PINS,
-               .v.pins = (const struct alc_pincfg[]) {
-                       { 0x14, 0x90170110 }, /* speaker */
-                       { 0x15, 0x0421101f }, /* HP */
-                       { 0x1a, 0x40f000f0 }, /* N/A */
-                       { 0x1b, 0x40f000f0 }, /* N/A */
-                       { 0x1e, 0x40f000f0 }, /* N/A */
-               }
-       },
        [ALC262_FIXUP_LENOVO_3000] = {
                .type = ALC_FIXUP_VERBS,
                .v.verbs = (const struct hda_verb[]) {
@@ -4807,8 +4835,6 @@ static const struct snd_pci_quirk alc262_fixup_tbl[] = {
        SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FIXUP_BENQ),
        SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FIXUP_BENQ),
        SND_PCI_QUIRK(0x10f1, 0x2915, "Tyan Thunder n6650W", ALC262_FIXUP_TYAN),
-       SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1",
-                     ALC262_FIXUP_TOSHIBA_RX1),
        SND_PCI_QUIRK(0x1734, 0x1147, "FSC Celsius H270", ALC262_FIXUP_FSC_H270),
        SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000", ALC262_FIXUP_LENOVO_3000),
        SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_FIXUP_BENQ),
@@ -5377,7 +5403,6 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
        SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
                      ALC269_FIXUP_AMIC),
        SND_PCI_QUIRK(0x1043, 0x1013, "ASUS N61Da", ALC269_FIXUP_AMIC),
-       SND_PCI_QUIRK(0x1043, 0x1113, "ASUS N63Jn", ALC269_FIXUP_AMIC),
        SND_PCI_QUIRK(0x1043, 0x1143, "ASUS B53f", ALC269_FIXUP_AMIC),
        SND_PCI_QUIRK(0x1043, 0x1133, "ASUS UJ20ft", ALC269_FIXUP_AMIC),
        SND_PCI_QUIRK(0x1043, 0x1183, "ASUS K72DR", ALC269_FIXUP_AMIC),
@@ -5589,6 +5614,25 @@ enum {
        PINFIX_ASUS_A6RP,
 };
 
+/* On some laptops, VREF of pin 0x0f is abused for controlling the main amp */
+static void alc861_fixup_asus_amp_vref_0f(struct hda_codec *codec,
+                       const struct alc_fixup *fix, int action)
+{
+       struct alc_spec *spec = codec->spec;
+       unsigned int val;
+
+       if (action != ALC_FIXUP_ACT_INIT)
+               return;
+       val = snd_hda_codec_read(codec, 0x0f, 0,
+                                AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
+       if (!(val & (AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN)))
+               val |= AC_PINCTL_IN_EN;
+       val |= AC_PINCTL_VREF_50;
+       snd_hda_codec_write(codec, 0x0f, 0,
+                           AC_VERB_SET_PIN_WIDGET_CONTROL, val);
+       spec->keep_vref_in_automute = 1;
+}
+
 static const struct alc_fixup alc861_fixups[] = {
        [PINFIX_FSC_AMILO_PI1505] = {
                .type = ALC_FIXUP_PINS,
@@ -5599,17 +5643,14 @@ static const struct alc_fixup alc861_fixups[] = {
                }
        },
        [PINFIX_ASUS_A6RP] = {
-               .type = ALC_FIXUP_VERBS,
-               .v.verbs = (const struct hda_verb[]) {
-                       /* node 0x0f VREF seems controlling the master output */
-                       { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50 },
-                       { }
-               },
+               .type = ALC_FIXUP_FUNC,
+               .v.func = alc861_fixup_asus_amp_vref_0f,
        },
 };
 
 static const struct snd_pci_quirk alc861_fixup_tbl[] = {
-       SND_PCI_QUIRK(0x1043, 0x1393, "ASUS A6Rp", PINFIX_ASUS_A6RP),
+       SND_PCI_QUIRK_VENDOR(0x1043, "ASUS laptop", PINFIX_ASUS_A6RP),
+       SND_PCI_QUIRK(0x1584, 0x0000, "Uniwill ECS M31EI", PINFIX_ASUS_A6RP),   
        SND_PCI_QUIRK(0x1584, 0x2b01, "Haier W18", PINFIX_ASUS_A6RP),
        SND_PCI_QUIRK(0x1734, 0x10c7, "FSC Amilo Pi1505", PINFIX_FSC_AMILO_PI1505),
        {}
index 948f0be..6345df1 100644 (file)
@@ -5078,9 +5078,9 @@ static int stac92xx_update_led_status(struct hda_codec *codec)
                                spec->gpio_dir, spec->gpio_data);
        } else {
                notmtd_lvl = spec->gpio_led_polarity ?
-                               AC_PINCTL_VREF_HIZ : AC_PINCTL_VREF_GRD;
+                               AC_PINCTL_VREF_50 : AC_PINCTL_VREF_GRD;
                muted_lvl = spec->gpio_led_polarity ?
-                               AC_PINCTL_VREF_GRD : AC_PINCTL_VREF_HIZ;
+                               AC_PINCTL_VREF_GRD : AC_PINCTL_VREF_50;
                spec->vref_led = muted ? muted_lvl : notmtd_lvl;
                stac_vrefout_set(codec, spec->vref_mute_led_nid,
                                 spec->vref_led);
index 03e63fe..dff9a00 100644 (file)
@@ -199,6 +199,9 @@ struct via_spec {
        unsigned int no_pin_power_ctl;
        enum VIA_HDA_CODEC codec_type;
 
+       /* analog low-power control */
+       bool alc_mode;
+
        /* smart51 setup */
        unsigned int smart51_nums;
        hda_nid_t smart51_pins[2];
@@ -663,6 +666,9 @@ static void via_auto_init_analog_input(struct hda_codec *codec)
        /* init input-src */
        for (i = 0; i < spec->num_adc_nids; i++) {
                int adc_idx = spec->inputs[spec->cur_mux[i]].adc_idx;
+               /* secondary ADCs must have the unique MUX */
+               if (i > 0 && !spec->mux_nids[i])
+                       break;
                if (spec->mux_nids[adc_idx]) {
                        int mux_idx = spec->inputs[spec->cur_mux[i]].mux_idx;
                        snd_hda_codec_write(codec, spec->mux_nids[adc_idx], 0,
@@ -687,6 +693,15 @@ static void via_auto_init_analog_input(struct hda_codec *codec)
        }
 }
 
+static void update_power_state(struct hda_codec *codec, hda_nid_t nid,
+                              unsigned int parm)
+{
+       if (snd_hda_codec_read(codec, nid, 0,
+                              AC_VERB_GET_POWER_STATE, 0) == parm)
+               return;
+       snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_POWER_STATE, parm);
+}
+
 static void set_pin_power_state(struct hda_codec *codec, hda_nid_t nid,
                                unsigned int *affected_parm)
 {
@@ -709,7 +724,7 @@ static void set_pin_power_state(struct hda_codec *codec, hda_nid_t nid,
        } else
                parm = AC_PWRST_D3;
 
-       snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_POWER_STATE, parm);
+       update_power_state(codec, nid, parm);
 }
 
 static int via_pin_power_ctl_info(struct snd_kcontrol *kcontrol,
@@ -749,6 +764,7 @@ static int via_pin_power_ctl_put(struct snd_kcontrol *kcontrol,
                return 0;
        spec->no_pin_power_ctl = val;
        set_widgets_power_state(codec);
+       analog_low_current_mode(codec);
        return 1;
 }
 
@@ -1036,13 +1052,19 @@ static bool is_aa_path_mute(struct hda_codec *codec)
 }
 
 /* enter/exit analog low-current mode */
-static void analog_low_current_mode(struct hda_codec *codec)
+static void __analog_low_current_mode(struct hda_codec *codec, bool force)
 {
        struct via_spec *spec = codec->spec;
        bool enable;
        unsigned int verb, parm;
 
-       enable = is_aa_path_mute(codec) && (spec->opened_streams != 0);
+       if (spec->no_pin_power_ctl)
+               enable = false;
+       else
+               enable = is_aa_path_mute(codec) && !spec->opened_streams;
+       if (enable == spec->alc_mode && !force)
+               return;
+       spec->alc_mode = enable;
 
        /* decide low current mode's verb & parameter */
        switch (spec->codec_type) {
@@ -1074,6 +1096,11 @@ static void analog_low_current_mode(struct hda_codec *codec)
        snd_hda_codec_write(codec, codec->afg, 0, verb, parm);
 }
 
+static void analog_low_current_mode(struct hda_codec *codec)
+{
+       return __analog_low_current_mode(codec, false);
+}
+
 /*
  * generic initialization of ADC, input mixers and output mixers
  */
@@ -1446,6 +1473,7 @@ static int via_build_controls(struct hda_codec *codec)
        struct snd_kcontrol *kctl;
        int err, i;
 
+       spec->no_pin_power_ctl = 1;
        if (spec->set_widgets_power_state)
                if (!via_clone_control(spec, &via_pin_power_ctl_enum))
                        return -ENOMEM;
@@ -1499,10 +1527,6 @@ static int via_build_controls(struct hda_codec *codec)
                        return err;
        }
 
-       /* init power states */
-       set_widgets_power_state(codec);
-       analog_low_current_mode(codec);
-
        via_free_kctls(codec); /* no longer needed */
 
        err = snd_hda_jack_add_kctls(codec, &spec->autocfg);
@@ -2295,10 +2319,7 @@ static int via_mux_enum_put(struct snd_kcontrol *kcontrol,
 
        if (mux) {
                /* switch to D0 beofre change index */
-               if (snd_hda_codec_read(codec, mux, 0,
-                              AC_VERB_GET_POWER_STATE, 0x00) != AC_PWRST_D0)
-                       snd_hda_codec_write(codec, mux, 0,
-                                   AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
+               update_power_state(codec, mux, AC_PWRST_D0);
                snd_hda_codec_write(codec, mux, 0,
                                    AC_VERB_SET_CONNECT_SEL,
                                    spec->inputs[cur].mux_idx);
@@ -2776,6 +2797,10 @@ static int via_init(struct hda_codec *codec)
        for (i = 0; i < spec->num_iverbs; i++)
                snd_hda_sequence_write(codec, spec->init_verbs[i]);
 
+       /* init power states */
+       set_widgets_power_state(codec);
+       __analog_low_current_mode(codec, true);
+
        via_auto_init_multi_out(codec);
        via_auto_init_hp_out(codec);
        via_auto_init_speaker_out(codec);
@@ -2922,9 +2947,9 @@ static void set_widgets_power_state_vt1708B(struct hda_codec *codec)
        if (imux_is_smixer)
                parm = AC_PWRST_D0;
        /* SW0 (17h), AIW 0/1 (13h/14h) */
-       snd_hda_codec_write(codec, 0x17, 0, AC_VERB_SET_POWER_STATE, parm);
-       snd_hda_codec_write(codec, 0x13, 0, AC_VERB_SET_POWER_STATE, parm);
-       snd_hda_codec_write(codec, 0x14, 0, AC_VERB_SET_POWER_STATE, parm);
+       update_power_state(codec, 0x17, parm);
+       update_power_state(codec, 0x13, parm);
+       update_power_state(codec, 0x14, parm);
 
        /* outputs */
        /* PW0 (19h), SW1 (18h), AOW1 (11h) */
@@ -2932,8 +2957,8 @@ static void set_widgets_power_state_vt1708B(struct hda_codec *codec)
        set_pin_power_state(codec, 0x19, &parm);
        if (spec->smart51_enabled)
                set_pin_power_state(codec, 0x1b, &parm);
-       snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_POWER_STATE, parm);
-       snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_POWER_STATE, parm);
+       update_power_state(codec, 0x18, parm);
+       update_power_state(codec, 0x11, parm);
 
        /* PW6 (22h), SW2 (26h), AOW2 (24h) */
        if (is_8ch) {
@@ -2941,20 +2966,16 @@ static void set_widgets_power_state_vt1708B(struct hda_codec *codec)
                set_pin_power_state(codec, 0x22, &parm);
                if (spec->smart51_enabled)
                        set_pin_power_state(codec, 0x1a, &parm);
-               snd_hda_codec_write(codec, 0x26, 0,
-                                   AC_VERB_SET_POWER_STATE, parm);
-               snd_hda_codec_write(codec, 0x24, 0,
-                                   AC_VERB_SET_POWER_STATE, parm);
+               update_power_state(codec, 0x26, parm);
+               update_power_state(codec, 0x24, parm);
        } else if (codec->vendor_id == 0x11064397) {
                /* PW7(23h), SW2(27h), AOW2(25h) */
                parm = AC_PWRST_D3;
                set_pin_power_state(codec, 0x23, &parm);
                if (spec->smart51_enabled)
                        set_pin_power_state(codec, 0x1a, &parm);
-               snd_hda_codec_write(codec, 0x27, 0,
-                                   AC_VERB_SET_POWER_STATE, parm);
-               snd_hda_codec_write(codec, 0x25, 0,
-                                   AC_VERB_SET_POWER_STATE, parm);
+               update_power_state(codec, 0x27, parm);
+               update_power_state(codec, 0x25, parm);
        }
 
        /* PW 3/4/7 (1ch/1dh/23h) */
@@ -2966,17 +2987,13 @@ static void set_widgets_power_state_vt1708B(struct hda_codec *codec)
                set_pin_power_state(codec, 0x23, &parm);
 
        /* MW0 (16h), Sw3 (27h), AOW 0/3 (10h/25h) */
-       snd_hda_codec_write(codec, 0x16, 0, AC_VERB_SET_POWER_STATE,
-                           imux_is_smixer ? AC_PWRST_D0 : parm);
-       snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE, parm);
+       update_power_state(codec, 0x16, imux_is_smixer ? AC_PWRST_D0 : parm);
+       update_power_state(codec, 0x10, parm);
        if (is_8ch) {
-               snd_hda_codec_write(codec, 0x25, 0,
-                                   AC_VERB_SET_POWER_STATE, parm);
-               snd_hda_codec_write(codec, 0x27, 0,
-                                   AC_VERB_SET_POWER_STATE, parm);
+               update_power_state(codec, 0x25, parm);
+               update_power_state(codec, 0x27, parm);
        } else if (codec->vendor_id == 0x11064397 && spec->hp_independent_mode)
-               snd_hda_codec_write(codec, 0x25, 0,
-                                   AC_VERB_SET_POWER_STATE, parm);
+               update_power_state(codec, 0x25, parm);
 }
 
 static int patch_vt1708S(struct hda_codec *codec);
@@ -3149,10 +3166,10 @@ static void set_widgets_power_state_vt1702(struct hda_codec *codec)
        if (imux_is_smixer)
                parm = AC_PWRST_D0; /* SW0 (13h) = stereo mixer (idx 3) */
        /* SW0 (13h), AIW 0/1/2 (12h/1fh/20h) */
-       snd_hda_codec_write(codec, 0x13, 0, AC_VERB_SET_POWER_STATE, parm);
-       snd_hda_codec_write(codec, 0x12, 0, AC_VERB_SET_POWER_STATE, parm);
-       snd_hda_codec_write(codec, 0x1f, 0, AC_VERB_SET_POWER_STATE, parm);
-       snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_POWER_STATE, parm);
+       update_power_state(codec, 0x13, parm);
+       update_power_state(codec, 0x12, parm);
+       update_power_state(codec, 0x1f, parm);
+       update_power_state(codec, 0x20, parm);
 
        /* outputs */
        /* PW 3/4 (16h/17h) */
@@ -3160,10 +3177,9 @@ static void set_widgets_power_state_vt1702(struct hda_codec *codec)
        set_pin_power_state(codec, 0x17, &parm);
        set_pin_power_state(codec, 0x16, &parm);
        /* MW0 (1ah), AOW 0/1 (10h/1dh) */
-       snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_POWER_STATE,
-                           imux_is_smixer ? AC_PWRST_D0 : parm);
-       snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE, parm);
-       snd_hda_codec_write(codec, 0x1d, 0, AC_VERB_SET_POWER_STATE, parm);
+       update_power_state(codec, 0x1a, imux_is_smixer ? AC_PWRST_D0 : parm);
+       update_power_state(codec, 0x10, parm);
+       update_power_state(codec, 0x1d, parm);
 }
 
 static int patch_vt1702(struct hda_codec *codec)
@@ -3228,52 +3244,48 @@ static void set_widgets_power_state_vt1718S(struct hda_codec *codec)
        if (imux_is_smixer)
                parm = AC_PWRST_D0;
        /* MUX6/7 (1eh/1fh), AIW 0/1 (10h/11h) */
-       snd_hda_codec_write(codec, 0x1e, 0, AC_VERB_SET_POWER_STATE, parm);
-       snd_hda_codec_write(codec, 0x1f, 0, AC_VERB_SET_POWER_STATE, parm);
-       snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE, parm);
-       snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_POWER_STATE, parm);
+       update_power_state(codec, 0x1e, parm);
+       update_power_state(codec, 0x1f, parm);
+       update_power_state(codec, 0x10, parm);
+       update_power_state(codec, 0x11, parm);
 
        /* outputs */
        /* PW3 (27h), MW2 (1ah), AOW3 (bh) */
        parm = AC_PWRST_D3;
        set_pin_power_state(codec, 0x27, &parm);
-       snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_POWER_STATE, parm);
-       snd_hda_codec_write(codec, 0xb, 0, AC_VERB_SET_POWER_STATE, parm);
+       update_power_state(codec, 0x1a, parm);
+       update_power_state(codec, 0xb, parm);
 
        /* PW2 (26h), AOW2 (ah) */
        parm = AC_PWRST_D3;
        set_pin_power_state(codec, 0x26, &parm);
        if (spec->smart51_enabled)
                set_pin_power_state(codec, 0x2b, &parm);
-       snd_hda_codec_write(codec, 0xa, 0, AC_VERB_SET_POWER_STATE, parm);
+       update_power_state(codec, 0xa, parm);
 
        /* PW0 (24h), AOW0 (8h) */
        parm = AC_PWRST_D3;
        set_pin_power_state(codec, 0x24, &parm);
        if (!spec->hp_independent_mode) /* check for redirected HP */
                set_pin_power_state(codec, 0x28, &parm);
-       snd_hda_codec_write(codec, 0x8, 0, AC_VERB_SET_POWER_STATE, parm);
+       update_power_state(codec, 0x8, parm);
        /* MW9 (21h), Mw2 (1ah), AOW0 (8h) */
-       snd_hda_codec_write(codec, 0x21, 0, AC_VERB_SET_POWER_STATE,
-                           imux_is_smixer ? AC_PWRST_D0 : parm);
+       update_power_state(codec, 0x21, imux_is_smixer ? AC_PWRST_D0 : parm);
 
        /* PW1 (25h), AOW1 (9h) */
        parm = AC_PWRST_D3;
        set_pin_power_state(codec, 0x25, &parm);
        if (spec->smart51_enabled)
                set_pin_power_state(codec, 0x2a, &parm);
-       snd_hda_codec_write(codec, 0x9, 0, AC_VERB_SET_POWER_STATE, parm);
+       update_power_state(codec, 0x9, parm);
 
        if (spec->hp_independent_mode) {
                /* PW4 (28h), MW3 (1bh), MUX1(34h), AOW4 (ch) */
                parm = AC_PWRST_D3;
                set_pin_power_state(codec, 0x28, &parm);
-               snd_hda_codec_write(codec, 0x1b, 0,
-                                   AC_VERB_SET_POWER_STATE, parm);
-               snd_hda_codec_write(codec, 0x34, 0,
-                                   AC_VERB_SET_POWER_STATE, parm);
-               snd_hda_codec_write(codec, 0xc, 0,
-                                   AC_VERB_SET_POWER_STATE, parm);
+               update_power_state(codec, 0x1b, parm);
+               update_power_state(codec, 0x34, parm);
+               update_power_state(codec, 0xc, parm);
        }
 }
 
@@ -3433,8 +3445,8 @@ static void set_widgets_power_state_vt1716S(struct hda_codec *codec)
        if (imux_is_smixer)
                parm = AC_PWRST_D0;
        /* SW0 (17h), AIW0(13h) */
-       snd_hda_codec_write(codec, 0x17, 0, AC_VERB_SET_POWER_STATE, parm);
-       snd_hda_codec_write(codec, 0x13, 0, AC_VERB_SET_POWER_STATE, parm);
+       update_power_state(codec, 0x17, parm);
+       update_power_state(codec, 0x13, parm);
 
        parm = AC_PWRST_D3;
        set_pin_power_state(codec, 0x1e, &parm);
@@ -3442,12 +3454,11 @@ static void set_widgets_power_state_vt1716S(struct hda_codec *codec)
        if (spec->dmic_enabled)
                set_pin_power_state(codec, 0x22, &parm);
        else
-               snd_hda_codec_write(codec, 0x22, 0,
-                                   AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
+               update_power_state(codec, 0x22, AC_PWRST_D3);
 
        /* SW2(26h), AIW1(14h) */
-       snd_hda_codec_write(codec, 0x26, 0, AC_VERB_SET_POWER_STATE, parm);
-       snd_hda_codec_write(codec, 0x14, 0, AC_VERB_SET_POWER_STATE, parm);
+       update_power_state(codec, 0x26, parm);
+       update_power_state(codec, 0x14, parm);
 
        /* outputs */
        /* PW0 (19h), SW1 (18h), AOW1 (11h) */
@@ -3456,8 +3467,8 @@ static void set_widgets_power_state_vt1716S(struct hda_codec *codec)
        /* Smart 5.1 PW2(1bh) */
        if (spec->smart51_enabled)
                set_pin_power_state(codec, 0x1b, &parm);
-       snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_POWER_STATE, parm);
-       snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_POWER_STATE, parm);
+       update_power_state(codec, 0x18, parm);
+       update_power_state(codec, 0x11, parm);
 
        /* PW7 (23h), SW3 (27h), AOW3 (25h) */
        parm = AC_PWRST_D3;
@@ -3465,12 +3476,12 @@ static void set_widgets_power_state_vt1716S(struct hda_codec *codec)
        /* Smart 5.1 PW1(1ah) */
        if (spec->smart51_enabled)
                set_pin_power_state(codec, 0x1a, &parm);
-       snd_hda_codec_write(codec, 0x27, 0, AC_VERB_SET_POWER_STATE, parm);
+       update_power_state(codec, 0x27, parm);
 
        /* Smart 5.1 PW5(1eh) */
        if (spec->smart51_enabled)
                set_pin_power_state(codec, 0x1e, &parm);
-       snd_hda_codec_write(codec, 0x25, 0, AC_VERB_SET_POWER_STATE, parm);
+       update_power_state(codec, 0x25, parm);
 
        /* Mono out */
        /* SW4(28h)->MW1(29h)-> PW12 (2ah)*/
@@ -3486,9 +3497,9 @@ static void set_widgets_power_state_vt1716S(struct hda_codec *codec)
                        mono_out = 1;
        }
        parm = mono_out ? AC_PWRST_D0 : AC_PWRST_D3;
-       snd_hda_codec_write(codec, 0x28, 0, AC_VERB_SET_POWER_STATE, parm);
-       snd_hda_codec_write(codec, 0x29, 0, AC_VERB_SET_POWER_STATE, parm);
-       snd_hda_codec_write(codec, 0x2a, 0, AC_VERB_SET_POWER_STATE, parm);
+       update_power_state(codec, 0x28, parm);
+       update_power_state(codec, 0x29, parm);
+       update_power_state(codec, 0x2a, parm);
 
        /* PW 3/4 (1ch/1dh) */
        parm = AC_PWRST_D3;
@@ -3496,15 +3507,12 @@ static void set_widgets_power_state_vt1716S(struct hda_codec *codec)
        set_pin_power_state(codec, 0x1d, &parm);
        /* HP Independent Mode, power on AOW3 */
        if (spec->hp_independent_mode)
-               snd_hda_codec_write(codec, 0x25, 0,
-                                   AC_VERB_SET_POWER_STATE, parm);
+               update_power_state(codec, 0x25, parm);
 
        /* force to D0 for internal Speaker */
        /* MW0 (16h), AOW0 (10h) */
-       snd_hda_codec_write(codec, 0x16, 0, AC_VERB_SET_POWER_STATE,
-                           imux_is_smixer ? AC_PWRST_D0 : parm);
-       snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE,
-                           mono_out ? AC_PWRST_D0 : parm);
+       update_power_state(codec, 0x16, imux_is_smixer ? AC_PWRST_D0 : parm);
+       update_power_state(codec, 0x10, mono_out ? AC_PWRST_D0 : parm);
 }
 
 static int patch_vt1716S(struct hda_codec *codec)
@@ -3580,54 +3588,45 @@ static void set_widgets_power_state_vt2002P(struct hda_codec *codec)
        set_pin_power_state(codec, 0x2b, &parm);
        parm = AC_PWRST_D0;
        /* MUX9/10 (1eh/1fh), AIW 0/1 (10h/11h) */
-       snd_hda_codec_write(codec, 0x1e, 0, AC_VERB_SET_POWER_STATE, parm);
-       snd_hda_codec_write(codec, 0x1f, 0, AC_VERB_SET_POWER_STATE, parm);
-       snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE, parm);
-       snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_POWER_STATE, parm);
+       update_power_state(codec, 0x1e, parm);
+       update_power_state(codec, 0x1f, parm);
+       update_power_state(codec, 0x10, parm);
+       update_power_state(codec, 0x11, parm);
 
        /* outputs */
        /* AOW0 (8h)*/
-       snd_hda_codec_write(codec, 0x8, 0, AC_VERB_SET_POWER_STATE, parm);
+       update_power_state(codec, 0x8, parm);
 
        if (spec->codec_type == VT1802) {
                /* PW4 (28h), MW4 (18h), MUX4(38h) */
                parm = AC_PWRST_D3;
                set_pin_power_state(codec, 0x28, &parm);
-               snd_hda_codec_write(codec, 0x18, 0,
-                                   AC_VERB_SET_POWER_STATE, parm);
-               snd_hda_codec_write(codec, 0x38, 0,
-                                   AC_VERB_SET_POWER_STATE, parm);
+               update_power_state(codec, 0x18, parm);
+               update_power_state(codec, 0x38, parm);
        } else {
                /* PW4 (26h), MW4 (1ch), MUX4(37h) */
                parm = AC_PWRST_D3;
                set_pin_power_state(codec, 0x26, &parm);
-               snd_hda_codec_write(codec, 0x1c, 0,
-                                   AC_VERB_SET_POWER_STATE, parm);
-               snd_hda_codec_write(codec, 0x37, 0,
-                                   AC_VERB_SET_POWER_STATE, parm);
+               update_power_state(codec, 0x1c, parm);
+               update_power_state(codec, 0x37, parm);
        }
 
        if (spec->codec_type == VT1802) {
                /* PW1 (25h), MW1 (15h), MUX1(35h), AOW1 (9h) */
                parm = AC_PWRST_D3;
                set_pin_power_state(codec, 0x25, &parm);
-               snd_hda_codec_write(codec, 0x15, 0,
-                                   AC_VERB_SET_POWER_STATE, parm);
-               snd_hda_codec_write(codec, 0x35, 0,
-                                   AC_VERB_SET_POWER_STATE, parm);
+               update_power_state(codec, 0x15, parm);
+               update_power_state(codec, 0x35, parm);
        } else {
                /* PW1 (25h), MW1 (19h), MUX1(35h), AOW1 (9h) */
                parm = AC_PWRST_D3;
                set_pin_power_state(codec, 0x25, &parm);
-               snd_hda_codec_write(codec, 0x19, 0,
-                                   AC_VERB_SET_POWER_STATE, parm);
-               snd_hda_codec_write(codec, 0x35, 0,
-                                   AC_VERB_SET_POWER_STATE, parm);
+               update_power_state(codec, 0x19, parm);
+               update_power_state(codec, 0x35, parm);
        }
 
        if (spec->hp_independent_mode)
-               snd_hda_codec_write(codec, 0x9, 0,
-                                   AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
+               update_power_state(codec, 0x9, AC_PWRST_D0);
 
        /* Class-D */
        /* PW0 (24h), MW0(18h/14h), MUX0(34h) */
@@ -3637,12 +3636,10 @@ static void set_widgets_power_state_vt2002P(struct hda_codec *codec)
        set_pin_power_state(codec, 0x24, &parm);
        parm = present ? AC_PWRST_D3 : AC_PWRST_D0;
        if (spec->codec_type == VT1802)
-               snd_hda_codec_write(codec, 0x14, 0,
-                                   AC_VERB_SET_POWER_STATE, parm);
+               update_power_state(codec, 0x14, parm);
        else
-               snd_hda_codec_write(codec, 0x18, 0,
-                                   AC_VERB_SET_POWER_STATE, parm);
-       snd_hda_codec_write(codec, 0x34, 0, AC_VERB_SET_POWER_STATE, parm);
+               update_power_state(codec, 0x18, parm);
+       update_power_state(codec, 0x34, parm);
 
        /* Mono Out */
        present = snd_hda_jack_detect(codec, 0x26);
@@ -3650,28 +3647,20 @@ static void set_widgets_power_state_vt2002P(struct hda_codec *codec)
        parm = present ? AC_PWRST_D3 : AC_PWRST_D0;
        if (spec->codec_type == VT1802) {
                /* PW15 (33h), MW8(1ch), MUX8(3ch) */
-               snd_hda_codec_write(codec, 0x33, 0,
-                                   AC_VERB_SET_POWER_STATE, parm);
-               snd_hda_codec_write(codec, 0x1c, 0,
-                                   AC_VERB_SET_POWER_STATE, parm);
-               snd_hda_codec_write(codec, 0x3c, 0,
-                                   AC_VERB_SET_POWER_STATE, parm);
+               update_power_state(codec, 0x33, parm);
+               update_power_state(codec, 0x1c, parm);
+               update_power_state(codec, 0x3c, parm);
        } else {
                /* PW15 (31h), MW8(17h), MUX8(3bh) */
-               snd_hda_codec_write(codec, 0x31, 0,
-                                   AC_VERB_SET_POWER_STATE, parm);
-               snd_hda_codec_write(codec, 0x17, 0,
-                                   AC_VERB_SET_POWER_STATE, parm);
-               snd_hda_codec_write(codec, 0x3b, 0,
-                                   AC_VERB_SET_POWER_STATE, parm);
+               update_power_state(codec, 0x31, parm);
+               update_power_state(codec, 0x17, parm);
+               update_power_state(codec, 0x3b, parm);
        }
        /* MW9 (21h) */
        if (imux_is_smixer || !is_aa_path_mute(codec))
-               snd_hda_codec_write(codec, 0x21, 0,
-                                   AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
+               update_power_state(codec, 0x21, AC_PWRST_D0);
        else
-               snd_hda_codec_write(codec, 0x21, 0,
-                                   AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
+               update_power_state(codec, 0x21, AC_PWRST_D3);
 }
 
 /* patch for vt2002P */
@@ -3731,30 +3720,28 @@ static void set_widgets_power_state_vt1812(struct hda_codec *codec)
        set_pin_power_state(codec, 0x2b, &parm);
        parm = AC_PWRST_D0;
        /* MUX10/11 (1eh/1fh), AIW 0/1 (10h/11h) */
-       snd_hda_codec_write(codec, 0x1e, 0, AC_VERB_SET_POWER_STATE, parm);
-       snd_hda_codec_write(codec, 0x1f, 0, AC_VERB_SET_POWER_STATE, parm);
-       snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE, parm);
-       snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_POWER_STATE, parm);
+       update_power_state(codec, 0x1e, parm);
+       update_power_state(codec, 0x1f, parm);
+       update_power_state(codec, 0x10, parm);
+       update_power_state(codec, 0x11, parm);
 
        /* outputs */
        /* AOW0 (8h)*/
-       snd_hda_codec_write(codec, 0x8, 0,
-                           AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
+       update_power_state(codec, 0x8, AC_PWRST_D0);
 
        /* PW4 (28h), MW4 (18h), MUX4(38h) */
        parm = AC_PWRST_D3;
        set_pin_power_state(codec, 0x28, &parm);
-       snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_POWER_STATE, parm);
-       snd_hda_codec_write(codec, 0x38, 0, AC_VERB_SET_POWER_STATE, parm);
+       update_power_state(codec, 0x18, parm);
+       update_power_state(codec, 0x38, parm);
 
        /* PW1 (25h), MW1 (15h), MUX1(35h), AOW1 (9h) */
        parm = AC_PWRST_D3;
        set_pin_power_state(codec, 0x25, &parm);
-       snd_hda_codec_write(codec, 0x15, 0, AC_VERB_SET_POWER_STATE, parm);
-       snd_hda_codec_write(codec, 0x35, 0, AC_VERB_SET_POWER_STATE, parm);
+       update_power_state(codec, 0x15, parm);
+       update_power_state(codec, 0x35, parm);
        if (spec->hp_independent_mode)
-               snd_hda_codec_write(codec, 0x9, 0,
-                                   AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
+               update_power_state(codec, 0x9, AC_PWRST_D0);
 
        /* Internal Speaker */
        /* PW0 (24h), MW0(14h), MUX0(34h) */
@@ -3763,15 +3750,11 @@ static void set_widgets_power_state_vt1812(struct hda_codec *codec)
        parm = AC_PWRST_D3;
        set_pin_power_state(codec, 0x24, &parm);
        if (present) {
-               snd_hda_codec_write(codec, 0x14, 0,
-                                   AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
-               snd_hda_codec_write(codec, 0x34, 0,
-                                   AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
+               update_power_state(codec, 0x14, AC_PWRST_D3);
+               update_power_state(codec, 0x34, AC_PWRST_D3);
        } else {
-               snd_hda_codec_write(codec, 0x14, 0,
-                                   AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
-               snd_hda_codec_write(codec, 0x34, 0,
-                                   AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
+               update_power_state(codec, 0x14, AC_PWRST_D0);
+               update_power_state(codec, 0x34, AC_PWRST_D0);
        }
 
 
@@ -3782,26 +3765,20 @@ static void set_widgets_power_state_vt1812(struct hda_codec *codec)
        parm = AC_PWRST_D3;
        set_pin_power_state(codec, 0x31, &parm);
        if (present) {
-               snd_hda_codec_write(codec, 0x1c, 0,
-                                   AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
-               snd_hda_codec_write(codec, 0x3c, 0,
-                                   AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
-               snd_hda_codec_write(codec, 0x3e, 0,
-                                   AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
+               update_power_state(codec, 0x1c, AC_PWRST_D3);
+               update_power_state(codec, 0x3c, AC_PWRST_D3);
+               update_power_state(codec, 0x3e, AC_PWRST_D3);
        } else {
-               snd_hda_codec_write(codec, 0x1c, 0,
-                                   AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
-               snd_hda_codec_write(codec, 0x3c, 0,
-                                   AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
-               snd_hda_codec_write(codec, 0x3e, 0,
-                                   AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
+               update_power_state(codec, 0x1c, AC_PWRST_D0);
+               update_power_state(codec, 0x3c, AC_PWRST_D0);
+               update_power_state(codec, 0x3e, AC_PWRST_D0);
        }
 
        /* PW15 (33h), MW15 (1dh), MUX15(3dh) */
        parm = AC_PWRST_D3;
        set_pin_power_state(codec, 0x33, &parm);
-       snd_hda_codec_write(codec, 0x1d, 0, AC_VERB_SET_POWER_STATE, parm);
-       snd_hda_codec_write(codec, 0x3d, 0, AC_VERB_SET_POWER_STATE, parm);
+       update_power_state(codec, 0x1d, parm);
+       update_power_state(codec, 0x3d, parm);
 
 }
 
index 9f3b01b..e0a4263 100644 (file)
@@ -2100,6 +2100,12 @@ static struct ac97_quirk ac97_quirks[] __devinitdata = {
                .name = "MSI P4 ATX 645 Ultra",
                .type = AC97_TUNE_HP_ONLY
        },
+       {
+               .subvendor = 0x161f,
+               .subdevice = 0x202f,
+               .name = "Gateway M520",
+               .type = AC97_TUNE_INV_EAPD
+       },
        {
                .subvendor = 0x161f,
                .subdevice = 0x203a,
index 26c7e8b..c0dbb52 100644 (file)
@@ -618,9 +618,12 @@ static int ac97_volume_get(struct snd_kcontrol *ctl,
        mutex_lock(&chip->mutex);
        reg = oxygen_read_ac97(chip, codec, index);
        mutex_unlock(&chip->mutex);
-       value->value.integer.value[0] = 31 - (reg & 0x1f);
-       if (stereo)
-               value->value.integer.value[1] = 31 - ((reg >> 8) & 0x1f);
+       if (!stereo) {
+               value->value.integer.value[0] = 31 - (reg & 0x1f);
+       } else {
+               value->value.integer.value[0] = 31 - ((reg >> 8) & 0x1f);
+               value->value.integer.value[1] = 31 - (reg & 0x1f);
+       }
        return 0;
 }
 
@@ -636,14 +639,14 @@ static int ac97_volume_put(struct snd_kcontrol *ctl,
 
        mutex_lock(&chip->mutex);
        oldreg = oxygen_read_ac97(chip, codec, index);
-       newreg = oldreg;
-       newreg = (newreg & ~0x1f) |
-               (31 - (value->value.integer.value[0] & 0x1f));
-       if (stereo)
-               newreg = (newreg & ~0x1f00) |
-                       ((31 - (value->value.integer.value[1] & 0x1f)) << 8);
-       else
-               newreg = (newreg & ~0x1f00) | ((newreg & 0x1f) << 8);
+       if (!stereo) {
+               newreg = oldreg & ~0x1f;
+               newreg |= 31 - (value->value.integer.value[0] & 0x1f);
+       } else {
+               newreg = oldreg & ~0x1f1f;
+               newreg |= (31 - (value->value.integer.value[0] & 0x1f)) << 8;
+               newreg |= 31 - (value->value.integer.value[1] & 0x1f);
+       }
        change = newreg != oldreg;
        if (change)
                oxygen_write_ac97(chip, codec, index, newreg);
index 9d38db8..78979b3 100644 (file)
@@ -1113,7 +1113,7 @@ static int cs42l73_pcm_hw_params(struct snd_pcm_substream *substream,
                priv->config[id].mmcc &= 0xC0;
                priv->config[id].mmcc |= cs42l73_mclk_coeffs[mclk_coeff].mmcc;
                priv->config[id].spc &= 0xFC;
-               priv->config[id].spc &= MCK_SCLK_64FS;
+               priv->config[id].spc |= MCK_SCLK_MCLK;
        } else {
                /* CS42L73 Slave */
                priv->config[id].spc &= 0xFC;
index 66f0611..89f2af7 100644 (file)
@@ -1405,6 +1405,7 @@ static int wm5100_set_bias_level(struct snd_soc_codec *codec,
 
        case SND_SOC_BIAS_OFF:
                regcache_cache_only(wm5100->regmap, true);
+               regcache_mark_dirty(wm5100->regmap);
                if (wm5100->pdata.ldo_ena)
                        gpio_set_value_cansleep(wm5100->pdata.ldo_ena, 0);
                regulator_bulk_disable(ARRAY_SIZE(wm5100->core_supplies),
@@ -2183,6 +2184,7 @@ static void wm5100_micd_irq(struct snd_soc_codec *codec)
                if (wm5100->jack_detecting) {
                        dev_dbg(codec->dev, "Microphone detected\n");
                        wm5100->jack_mic = true;
+                       wm5100->jack_detecting = false;
                        snd_soc_jack_report(wm5100->jack,
                                            SND_JACK_HEADSET,
                                            SND_JACK_HEADSET | SND_JACK_BTN_0);
@@ -2221,6 +2223,7 @@ static void wm5100_micd_irq(struct snd_soc_codec *codec)
                                            SND_JACK_BTN_0);
                } else if (wm5100->jack_detecting) {
                        dev_dbg(codec->dev, "Headphone detected\n");
+                       wm5100->jack_detecting = false;
                        snd_soc_jack_report(wm5100->jack, SND_JACK_HEADPHONE,
                                            SND_JACK_HEADPHONE);
 
@@ -2610,6 +2613,13 @@ static const struct regmap_config wm5100_regmap = {
        .cache_type = REGCACHE_RBTREE,
 };
 
+static const unsigned int wm5100_mic_ctrl_reg[] = {
+       WM5100_IN1L_CONTROL,
+       WM5100_IN2L_CONTROL,
+       WM5100_IN3L_CONTROL,
+       WM5100_IN4L_CONTROL,
+};
+
 static __devinit int wm5100_i2c_probe(struct i2c_client *i2c,
                                      const struct i2c_device_id *id)
 {
@@ -2742,7 +2752,7 @@ static __devinit int wm5100_i2c_probe(struct i2c_client *i2c,
        }
 
        for (i = 0; i < ARRAY_SIZE(wm5100->pdata.in_mode); i++) {
-               regmap_update_bits(wm5100->regmap, WM5100_IN1L_CONTROL,
+               regmap_update_bits(wm5100->regmap, wm5100_mic_ctrl_reg[i],
                                   WM5100_IN1_MODE_MASK |
                                   WM5100_IN1_DMIC_SUP_MASK,
                                   (wm5100->pdata.in_mode[i] <<
index 296de4e..29c4b02 100644 (file)
@@ -96,7 +96,7 @@ static int wm8962_regulator_event_##n(struct notifier_block *nb, \
        struct wm8962_priv *wm8962 = container_of(nb, struct wm8962_priv, \
                                                  disable_nb[n]); \
        if (event & REGULATOR_EVENT_DISABLE) { \
-               regcache_cache_only(wm8962->regmap, true);      \
+               regcache_mark_dirty(wm8962->regmap);    \
        } \
        return 0; \
 }
@@ -3159,13 +3159,13 @@ static int wm8962_hw_params(struct snd_pcm_substream *substream,
        case SNDRV_PCM_FORMAT_S16_LE:
                break;
        case SNDRV_PCM_FORMAT_S20_3LE:
-               aif0 |= 0x40;
+               aif0 |= 0x4;
                break;
        case SNDRV_PCM_FORMAT_S24_LE:
-               aif0 |= 0x80;
+               aif0 |= 0x8;
                break;
        case SNDRV_PCM_FORMAT_S32_LE:
-               aif0 |= 0xc0;
+               aif0 |= 0xc;
                break;
        default:
                return -EINVAL;
index 93d27b6..ec69a6c 100644 (file)
@@ -770,6 +770,8 @@ static void vmid_reference(struct snd_soc_codec *codec)
 {
        struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
 
+       pm_runtime_get_sync(codec->dev);
+
        wm8994->vmid_refcount++;
 
        dev_dbg(codec->dev, "Referencing VMID, refcount is now %d\n",
@@ -783,7 +785,12 @@ static void vmid_reference(struct snd_soc_codec *codec)
                                    WM8994_VMID_RAMP_MASK,
                                    WM8994_STARTUP_BIAS_ENA |
                                    WM8994_VMID_BUF_ENA |
-                                   (0x11 << WM8994_VMID_RAMP_SHIFT));
+                                   (0x3 << WM8994_VMID_RAMP_SHIFT));
+
+               /* Remove discharge for line out */
+               snd_soc_update_bits(codec, WM8994_ANTIPOP_1,
+                                   WM8994_LINEOUT1_DISCH |
+                                   WM8994_LINEOUT2_DISCH, 0);
 
                /* Main bias enable, VMID=2x40k */
                snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_1,
@@ -837,6 +844,8 @@ static void vmid_dereference(struct snd_soc_codec *codec)
                                    WM8994_VMID_BUF_ENA |
                                    WM8994_VMID_RAMP_MASK, 0);
        }
+
+       pm_runtime_put(codec->dev);
 }
 
 static int vmid_event(struct snd_soc_dapm_widget *w,
@@ -2753,11 +2762,6 @@ static int wm8994_resume(struct snd_soc_codec *codec)
                codec->cache_only = 0;
        }
 
-       /* Restore the registers */
-       ret = snd_soc_cache_sync(codec);
-       if (ret != 0)
-               dev_err(codec->dev, "Failed to sync cache: %d\n", ret);
-
        wm8994_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
 
        for (i = 0; i < ARRAY_SIZE(wm8994->fll); i++) {
index 13aa2bd..61f7daa 100644 (file)
@@ -108,7 +108,7 @@ static int wm8996_regulator_event_##n(struct notifier_block *nb, \
        struct wm8996_priv *wm8996 = container_of(nb, struct wm8996_priv, \
                                                  disable_nb[n]); \
        if (event & REGULATOR_EVENT_DISABLE) { \
-               regcache_cache_only(wm8996->regmap, true);      \
+               regcache_mark_dirty(wm8996->regmap);    \
        } \
        return 0; \
 }
index 2a61094..8a68cea 100644 (file)
@@ -586,14 +586,14 @@ SOC_DAPM_SINGLE("Left Output Switch", WM8993_LINE_MIXER1, 0, 1, 0),
 };
 
 static const struct snd_kcontrol_new line2_mix[] = {
-SOC_DAPM_SINGLE("IN2R Switch", WM8993_LINE_MIXER2, 2, 1, 0),
-SOC_DAPM_SINGLE("IN2L Switch", WM8993_LINE_MIXER2, 1, 1, 0),
+SOC_DAPM_SINGLE("IN1L Switch", WM8993_LINE_MIXER2, 2, 1, 0),
+SOC_DAPM_SINGLE("IN1R Switch", WM8993_LINE_MIXER2, 1, 1, 0),
 SOC_DAPM_SINGLE("Output Switch", WM8993_LINE_MIXER2, 0, 1, 0),
 };
 
 static const struct snd_kcontrol_new line2n_mix[] = {
-SOC_DAPM_SINGLE("Left Output Switch", WM8993_LINE_MIXER2, 6, 1, 0),
-SOC_DAPM_SINGLE("Right Output Switch", WM8993_LINE_MIXER2, 5, 1, 0),
+SOC_DAPM_SINGLE("Left Output Switch", WM8993_LINE_MIXER2, 5, 1, 0),
+SOC_DAPM_SINGLE("Right Output Switch", WM8993_LINE_MIXER2, 6, 1, 0),
 };
 
 static const struct snd_kcontrol_new line2p_mix[] = {
@@ -613,6 +613,8 @@ SND_SOC_DAPM_INPUT("IN2RP:VXRP"),
 SND_SOC_DAPM_SUPPLY("MICBIAS2", WM8993_POWER_MANAGEMENT_1, 5, 0, NULL, 0),
 SND_SOC_DAPM_SUPPLY("MICBIAS1", WM8993_POWER_MANAGEMENT_1, 4, 0, NULL, 0),
 
+SND_SOC_DAPM_SUPPLY("LINEOUT_VMID_BUF", WM8993_ANTIPOP1, 7, 0, NULL, 0),
+
 SND_SOC_DAPM_MIXER("IN1L PGA", WM8993_POWER_MANAGEMENT_2, 6, 0,
                   in1l_pga, ARRAY_SIZE(in1l_pga)),
 SND_SOC_DAPM_MIXER("IN1R PGA", WM8993_POWER_MANAGEMENT_2, 4, 0,
@@ -834,9 +836,11 @@ static const struct snd_soc_dapm_route lineout1_diff_routes[] = {
 };
 
 static const struct snd_soc_dapm_route lineout1_se_routes[] = {
+       { "LINEOUT1N Mixer", NULL, "LINEOUT_VMID_BUF" },
        { "LINEOUT1N Mixer", "Left Output Switch", "Left Output PGA" },
        { "LINEOUT1N Mixer", "Right Output Switch", "Right Output PGA" },
 
+       { "LINEOUT1P Mixer", NULL, "LINEOUT_VMID_BUF" },
        { "LINEOUT1P Mixer", "Left Output Switch", "Left Output PGA" },
 
        { "LINEOUT1N Driver", NULL, "LINEOUT1N Mixer" },
@@ -844,8 +848,8 @@ static const struct snd_soc_dapm_route lineout1_se_routes[] = {
 };
 
 static const struct snd_soc_dapm_route lineout2_diff_routes[] = {
-       { "LINEOUT2 Mixer", "IN2L Switch", "IN2L PGA" },
-       { "LINEOUT2 Mixer", "IN2R Switch", "IN2R PGA" },
+       { "LINEOUT2 Mixer", "IN1L Switch", "IN1L PGA" },
+       { "LINEOUT2 Mixer", "IN1R Switch", "IN1R PGA" },
        { "LINEOUT2 Mixer", "Output Switch", "Right Output PGA" },
 
        { "LINEOUT2N Driver", NULL, "LINEOUT2 Mixer" },
@@ -853,9 +857,11 @@ static const struct snd_soc_dapm_route lineout2_diff_routes[] = {
 };
 
 static const struct snd_soc_dapm_route lineout2_se_routes[] = {
+       { "LINEOUT2N Mixer", NULL, "LINEOUT_VMID_BUF" },
        { "LINEOUT2N Mixer", "Left Output Switch", "Left Output PGA" },
        { "LINEOUT2N Mixer", "Right Output Switch", "Right Output PGA" },
 
+       { "LINEOUT2P Mixer", NULL, "LINEOUT_VMID_BUF" },
        { "LINEOUT2P Mixer", "Right Output Switch", "Right Output PGA" },
 
        { "LINEOUT2N Driver", NULL, "LINEOUT2N Mixer" },
index 7ac0ba2..c6012ff 100644 (file)
@@ -230,8 +230,6 @@ static const struct snd_kcontrol_new neo1973_wm8753_controls[] = {
 
 /* GTA02 specific routes and controls */
 
-#ifdef CONFIG_MACH_NEO1973_GTA02
-
 static int gta02_speaker_enabled;
 
 static int lm4853_set_spk(struct snd_kcontrol *kcontrol,
@@ -311,10 +309,6 @@ static int neo1973_gta02_wm8753_init(struct snd_soc_codec *codec)
        return 0;
 }
 
-#else
-static int neo1973_gta02_wm8753_init(struct snd_soc_code *codec) { return 0; }
-#endif
-
 static int neo1973_wm8753_init(struct snd_soc_pcm_runtime *rtd)
 {
        struct snd_soc_codec *codec = rtd->codec;
@@ -322,10 +316,6 @@ static int neo1973_wm8753_init(struct snd_soc_pcm_runtime *rtd)
        int ret;
 
        /* set up NC codec pins */
-       if (machine_is_neo1973_gta01()) {
-               snd_soc_dapm_nc_pin(dapm, "LOUT2");
-               snd_soc_dapm_nc_pin(dapm, "ROUT2");
-       }
        snd_soc_dapm_nc_pin(dapm, "OUT3");
        snd_soc_dapm_nc_pin(dapm, "OUT4");
        snd_soc_dapm_nc_pin(dapm, "LINE1");
@@ -370,50 +360,6 @@ static int neo1973_wm8753_init(struct snd_soc_pcm_runtime *rtd)
        return 0;
 }
 
-/* GTA01 specific controls */
-
-#ifdef CONFIG_MACH_NEO1973_GTA01
-
-static const struct snd_soc_dapm_route neo1973_lm4857_routes[] = {
-       {"Amp IN", NULL, "ROUT1"},
-       {"Amp IN", NULL, "LOUT1"},
-
-       {"Handset Spk", NULL, "Amp EP"},
-       {"Stereo Out", NULL, "Amp LS"},
-       {"Headphone", NULL, "Amp HP"},
-};
-
-static const struct snd_soc_dapm_widget neo1973_lm4857_dapm_widgets[] = {
-       SND_SOC_DAPM_SPK("Handset Spk", NULL),
-       SND_SOC_DAPM_SPK("Stereo Out", NULL),
-       SND_SOC_DAPM_HP("Headphone", NULL),
-};
-
-static int neo1973_lm4857_init(struct snd_soc_dapm_context *dapm)
-{
-       int ret;
-
-       ret = snd_soc_dapm_new_controls(dapm, neo1973_lm4857_dapm_widgets,
-                       ARRAY_SIZE(neo1973_lm4857_dapm_widgets));
-       if (ret)
-               return ret;
-
-       ret = snd_soc_dapm_add_routes(dapm, neo1973_lm4857_routes,
-                       ARRAY_SIZE(neo1973_lm4857_routes));
-       if (ret)
-               return ret;
-
-       snd_soc_dapm_ignore_suspend(dapm, "Stereo Out");
-       snd_soc_dapm_ignore_suspend(dapm, "Handset Spk");
-       snd_soc_dapm_ignore_suspend(dapm, "Headphone");
-
-       return 0;
-}
-
-#else
-static int neo1973_lm4857_init(struct snd_soc_dapm_context *dapm) { return 0; };
-#endif
-
 static struct snd_soc_dai_link neo1973_dai[] = {
 { /* Hifi Playback - for similatious use with voice below */
        .name = "WM8753",
@@ -440,11 +386,6 @@ static struct snd_soc_aux_dev neo1973_aux_devs[] = {
                .name = "dfbmcs320",
                .codec_name = "dfbmcs320.0",
        },
-       {
-               .name = "lm4857",
-               .codec_name = "lm4857.0-007c",
-               .init = neo1973_lm4857_init,
-       },
 };
 
 static struct snd_soc_codec_conf neo1973_codec_conf[] = {
@@ -454,14 +395,10 @@ static struct snd_soc_codec_conf neo1973_codec_conf[] = {
        },
 };
 
-#ifdef CONFIG_MACH_NEO1973_GTA02
 static const struct gpio neo1973_gta02_gpios[] = {
        { GTA02_GPIO_HP_IN, GPIOF_OUT_INIT_HIGH, "GTA02_HP_IN" },
        { GTA02_GPIO_AMP_SHUT, GPIOF_OUT_INIT_HIGH, "GTA02_AMP_SHUT" },
 };
-#else
-static const struct gpio neo1973_gta02_gpios[] = {};
-#endif
 
 static struct snd_soc_card neo1973 = {
        .name = "neo1973",
@@ -480,7 +417,7 @@ static int __init neo1973_init(void)
 {
        int ret;
 
-       if (!machine_is_neo1973_gta01() && !machine_is_neo1973_gta02())
+       if (!machine_is_neo1973_gta02())
                return -ENODEV;
 
        if (machine_is_neo1973_gta02()) {
index db6c89a..ea4a82d 100644 (file)
@@ -1152,12 +1152,8 @@ static snd_pcm_uframes_t fsi_pointer(struct snd_pcm_substream *substream)
 {
        struct fsi_priv *fsi = fsi_get_priv(substream);
        struct fsi_stream *io = fsi_get_stream(fsi, fsi_is_play(substream));
-       int samples_pos = io->buff_sample_pos - 1;
 
-       if (samples_pos < 0)
-               samples_pos = 0;
-
-       return fsi_sample2frame(fsi, samples_pos);
+       return fsi_sample2frame(fsi, io->buff_sample_pos);
 }
 
 static struct snd_pcm_ops fsi_pcm_ops = {
index b5ecf6d..92cee24 100644 (file)
@@ -567,6 +567,17 @@ int snd_soc_suspend(struct device *dev)
                if (!codec->suspended && codec->driver->suspend) {
                        switch (codec->dapm.bias_level) {
                        case SND_SOC_BIAS_STANDBY:
+                               /*
+                                * If the CODEC is capable of idle
+                                * bias off then being in STANDBY
+                                * means it's doing something,
+                                * otherwise fall through.
+                                */
+                               if (codec->dapm.idle_bias_off) {
+                                       dev_dbg(codec->dev,
+                                               "idle_bias_off CODEC on over suspend\n");
+                                       break;
+                               }
                        case SND_SOC_BIAS_OFF:
                                codec->driver->suspend(codec);
                                codec->suspended = 1;
index 8edc503..d89ab4c 100644 (file)
@@ -1617,6 +1617,14 @@ YAMAHA_DEVICE(0x7010, "UB99"),
                }
        }
 },
+{
+       /* Edirol UM-3G */
+       USB_DEVICE_VENDOR_SPEC(0x0582, 0x0108),
+       .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
+               .ifnum = 0,
+               .type = QUIRK_MIDI_STANDARD_INTERFACE
+       }
+},
 {
        /* Boss JS-8 Jam Station  */
        USB_DEVICE(0x0582, 0x0109),
index ac86d67..7c12650 100644 (file)
@@ -104,7 +104,7 @@ endif
 
 CFLAGS = -fno-omit-frame-pointer -ggdb3 -Wall -Wextra -std=gnu99 $(CFLAGS_WERROR) $(CFLAGS_OPTIMIZE) -D_FORTIFY_SOURCE=2 $(EXTRA_WARNINGS) $(EXTRA_CFLAGS)
 EXTLIBS = -lpthread -lrt -lelf -lm
-ALL_CFLAGS = $(CFLAGS) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64
+ALL_CFLAGS = $(CFLAGS) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE
 ALL_LDFLAGS = $(LDFLAGS)
 STRIP ?= strip
 
@@ -168,10 +168,7 @@ endif
 
 ### --- END CONFIGURATION SECTION ---
 
-# Those must not be GNU-specific; they are shared with perl/ which may
-# be built by a different compiler. (Note that this is an artifact now
-# but it still might be nice to keep that distinction.)
-BASIC_CFLAGS = -Iutil/include -Iarch/$(ARCH)/include
+BASIC_CFLAGS = -Iutil/include -Iarch/$(ARCH)/include -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE
 BASIC_LDFLAGS =
 
 # Guard against environment variables
index a57b66e..185a96d 100644 (file)
@@ -1,2 +1,8 @@
 
 #include "../../../arch/x86/lib/memcpy_64.S"
+/*
+ * We need to provide note.GNU-stack section, saying that we want
+ * NOT executable stack. Otherwise the final linking will assume that
+ * the ELF stack should not be restricted at all and set it RWX.
+ */
+.section .note.GNU-stack,"",@progbits
index 59d43ab..fb85661 100644 (file)
@@ -20,7 +20,6 @@
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  *
  */
-#define _GNU_SOURCE
 #include <sys/utsname.h>
 #include <sys/types.h>
 #include <sys/stat.h>
@@ -31,7 +30,6 @@
 #include <stdlib.h>
 #include <string.h>
 
-#undef _GNU_SOURCE
 #include "perf.h"
 #include "builtin.h"
 #include "util/util.h"
index 8f80df8..dd162aa 100644 (file)
@@ -89,8 +89,6 @@ void get_term_dimensions(struct winsize *ws)
 
 static void perf_top__update_print_entries(struct perf_top *top)
 {
-       top->print_entries = top->winsize.ws_row;
-
        if (top->print_entries > 9)
                top->print_entries -= 9;
 }
@@ -100,6 +98,13 @@ static void perf_top__sig_winch(int sig __used, siginfo_t *info __used, void *ar
        struct perf_top *top = arg;
 
        get_term_dimensions(&top->winsize);
+       if (!top->print_entries
+           || (top->print_entries+4) > top->winsize.ws_row) {
+               top->print_entries = top->winsize.ws_row;
+       } else {
+               top->print_entries += 4;
+               top->winsize.ws_row = top->print_entries;
+       }
        perf_top__update_print_entries(top);
 }
 
@@ -453,8 +458,10 @@ static void perf_top__handle_keypress(struct perf_top *top, int c)
                                };
                                perf_top__sig_winch(SIGWINCH, NULL, top);
                                sigaction(SIGWINCH, &act, NULL);
-                       } else
+                       } else {
+                               perf_top__sig_winch(SIGWINCH, NULL, top);
                                signal(SIGWINCH, SIG_DFL);
+                       }
                        break;
                case 'E':
                        if (top->evlist->nr_entries > 1) {
index 73ddaf0..2044324 100644 (file)
@@ -554,7 +554,7 @@ static int perf_event__process_kernel_mmap(struct perf_tool *tool __used,
 
        is_kernel_mmap = memcmp(event->mmap.filename,
                                kmmap_prefix,
-                               strlen(kmmap_prefix)) == 0;
+                               strlen(kmmap_prefix) - 1) == 0;
        if (event->mmap.filename[0] == '/' ||
            (!is_kernel_mmap && event->mmap.filename[0] == '[')) {
 
index 667f3b7..7132ee8 100644 (file)
@@ -463,6 +463,7 @@ int perf_event__parse_sample(const union perf_event *event, u64 type,
        memset(data, 0, sizeof(*data));
        data->cpu = data->pid = data->tid = -1;
        data->stream_id = data->id = data->time = -1ULL;
+       data->period = 1;
 
        if (event->header.type != PERF_RECORD_SAMPLE) {
                if (!sample_id_all)
index 3e7e0b0..ecd7f4d 100644 (file)
@@ -2105,7 +2105,7 @@ int perf_event__synthesize_event_type(struct perf_tool *tool,
        strncpy(ev.event_type.event_type.name, name, MAX_EVENT_NAME - 1);
 
        ev.event_type.header.type = PERF_RECORD_HEADER_EVENT_TYPE;
-       size = strlen(name);
+       size = strlen(ev.event_type.event_type.name);
        size = ALIGN(size, sizeof(u64));
        ev.event_type.header.size = sizeof(ev.event_type) -
                (sizeof(ev.event_type.event_type.name) - size);
index eb25900..29cb654 100644 (file)
@@ -19,7 +19,6 @@
  *
  */
 
-#define _GNU_SOURCE
 #include <sys/utsname.h>
 #include <sys/types.h>
 #include <sys/stat.h>
@@ -33,7 +32,6 @@
 #include <limits.h>
 #include <elf.h>
 
-#undef _GNU_SOURCE
 #include "util.h"
 #include "event.h"
 #include "string.h"
index 215d50f..0975438 100644 (file)
@@ -1,4 +1,3 @@
-#define _GNU_SOURCE
 #include <ctype.h>
 #include <dirent.h>
 #include <errno.h>
index 6c164dc..1a8d4dc 100644 (file)
  *  The parts for function graph printing was taken and modified from the
  *  Linux Kernel that were written by Frederic Weisbecker.
  */
-#define _GNU_SOURCE
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <ctype.h>
 #include <errno.h>
 
-#undef _GNU_SOURCE
 #include "../perf.h"
 #include "util.h"
 #include "trace-event.h"
index 1212a38..e81aef1 100644 (file)
@@ -1,6 +1,4 @@
-#define _GNU_SOURCE
 #include <stdio.h>
-#undef _GNU_SOURCE
 #include "../libslang.h"
 #include <stdlib.h>
 #include <string.h>
index 6ef3c56..4f48f59 100644 (file)
@@ -1,4 +1,3 @@
-#define _GNU_SOURCE
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
index b9c530c..ecf9898 100644 (file)
@@ -40,7 +40,6 @@
 #define decimal_length(x)      ((int)(sizeof(x) * 2.56 + 0.5) + 1)
 
 #define _ALL_SOURCE 1
-#define _GNU_SOURCE 1
 #define _BSD_SOURCE 1
 #define HAS_BOOL
 
index 7287bf5..a91f980 100644 (file)
@@ -1543,7 +1543,7 @@ void mark_page_dirty_in_slot(struct kvm *kvm, struct kvm_memory_slot *memslot,
        if (memslot && memslot->dirty_bitmap) {
                unsigned long rel_gfn = gfn - memslot->base_gfn;
 
-               if (!__test_and_set_bit_le(rel_gfn, memslot->dirty_bitmap))
+               if (!test_and_set_bit_le(rel_gfn, memslot->dirty_bitmap))
                        memslot->nr_dirty_pages++;
        }
 }