commit 4efc3fff0056774a530ef1fda5cbf87fdfcada09
Author: Dave Jones <davej(a)redhat.com>
Date: Thu Jun 30 14:18:36 2011 -0400
2.6.39 rebase
TODO | 61 -
acpi_reboot.patch | 106 -
ahci-add-another-pci-id-for-marvell.patch | 32 -
apple_backlight.patch | 688 --
...disable-fast-channel-switching-by-default.patch | 6 +-
...kdev_get-should-access-bd_disk-only-after.patch | 40 -
block-export-blk_-get-put-_queue.patch | 39 -
block-queue-refcount.patch | 43 -
bonding-incorrect-tx-queue-offset.patch | 54 -
config-arm | 12 +
config-debug | 1 +
config-generic | 226 +-
config-ia64-generic | 5 +
config-nodebug | 1 +
config-powerpc-generic | 14 +
config-powerpc32-generic | 3 +-
config-powerpc64 | 4 +
config-s390x | 5 +
config-x86-generic | 29 +-
config-x86_64-generic | 25 +
cx88-Fix-HVR4000-IR-keymap.patch | 55 -
drm-i915-fix-pipelined-fencing.patch | 80 -
drm-intel-edp-fixes.patch | 14 +-
drm-intel-eeebox-eb1007-quirk.patch | 36 -
drm-intel-restore-mode.patch | 128 -
drm-nouveau-updates.patch | 6777 -----------------
drm-radeon-pageflip-oops-fix.patch | 69 -
drm-radeon-update.patch | 4835 ------------
drm-radeon-update2.patch | 1708 -----
drm-radeon-update3.patch | 820 ---
drm-ttm-move-notify.patch | 40 -
efifb_update.patch | 217 -
...ltitouch-add-support-for-elo-touchsystems.patch | 2234 ++++++-
hid-ntrig-deref-unclaimed-input.patch | 46 -
...com-add-support-for-lenovo-tablet-id-0xe6.patch | 36 -
...omain-check-in-domain_remove_one_dev_info.patch | 37 -
...heck-for-identity-mapping-candidate-using.patch | 53 -
intel-iommu-dont-cache-iova-above-32bit.patch | 60 -
intel-iommu-flush-unmaps-at-domain_exit.patch | 36 -
...mmu-only-unlink-device-domains-from-iommu.patch | 48 -
...-remove-host-bridge-devices-from-identity.patch | 44 -
...eed-up-processing-of-the-identity_mapping.patch | 43 -
...ommu-use-coherent-dma-mask-when-requested.patch | 35 -
...o-self-protection-on-5000-adapters-series.patch | 103 -
kernel.spec | 118 +-
linux-2.6-acpi-debug-infinite-loop.patch | 27 +-
linux-2.6-crash-driver.patch | 22 +-
linux-2.6-debug-always-inline-kzalloc.patch | 25 -
linux-2.6-debug-sizeof-structs.patch | 33 -
linux-2.6-hotfixes.patch | 15 -
linux-2.6-i386-nx-emulation.patch | 14 +-
linux-2.6-netconsole-deadlock.patch | 56 -
linux-2.6-upstream-reverts.patch | 203 -
linux-2.6-utrace-ptrace.patch | 806 +-
linux-2.6-v4l-dvb-experimental.patch | 1326 ----
linux-2.6-v4l-dvb-update.patch | 7725 --------------------
...-configured-for-aspm-under-powersave-mode.patch | 112 -
...ot-mangle-valid-userspace-syslog-prefixes.patch | 214 -
...dh_hp_sw-fix-deadlock-in-start_stop_endio.patch | 32 -
sources | 3 +-
...dump-info-when-frame-pointer-is-available.patch | 352 -
61 files changed, 2950 insertions(+), 27081 deletions(-)
---
diff --git a/ath5k-disable-fast-channel-switching-by-default.patch
b/ath5k-disable-fast-channel-switching-by-default.patch
index 86ebf83..a26eb51 100644
--- a/ath5k-disable-fast-channel-switching-by-default.patch
+++ b/ath5k-disable-fast-channel-switching-by-default.patch
@@ -40,10 +40,10 @@ index 09ae4ef..0fb6333 100644
ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "resetting\n");
-@@ -2685,7 +2691,8 @@ ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel
*chan,
+@@ -2669,7 +2669,8 @@ ath5k_reset(struct ath5k_softc *sc, stru
+ ath5k_drain_tx_buffs(sc);
+ if (chan)
sc->curchan = chan;
- sc->curband = &sc->sbands[chan->band];
- }
- ret = ath5k_hw_reset(ah, sc->opmode, sc->curchan, chan != NULL,
+ fast = ((chan != NULL) && modparam_fastchanswitch) ? 1 : 0;
+ ret = ath5k_hw_reset(ah, sc->opmode, sc->curchan, fast,
diff --git a/config-arm b/config-arm
index 47a024d..dd6f90a 100644
--- a/config-arm
+++ b/config-arm
@@ -135,3 +135,15 @@ CONFIG_STRICT_DEVMEM=y
# CONFIG_HVC_DCC is not set
CONFIG_SPARSE_IRQ=y
+
+# CONFIG_ARM_PATCH_PHYS_VIRT is not set
+
+CONFIG_FTMAC100=m
+
+CONFIG_HWSPINLOCK_OMAP=m
+
+CONFIG_USE_OF=y
+CONFIG_PROC_DEVICETREE=y
+CONFIG_MTD_PHYSMAP_OF=m
+CONFIG_SERIAL_OF_PLATFORM=m
+CONFIG_MMC_SDHCI_OF=m
diff --git a/config-debug b/config-debug
index 7301794..7bbaa0b 100644
--- a/config-debug
+++ b/config-debug
@@ -41,6 +41,7 @@ CONFIG_DEBUG_OBJECTS=y
# CONFIG_DEBUG_OBJECTS_SELFTEST is not set
CONFIG_DEBUG_OBJECTS_FREE=y
CONFIG_DEBUG_OBJECTS_TIMERS=y
+CONFIG_DEBUG_OBJECTS_RCU_HEAD=y
CONFIG_DEBUG_OBJECTS_ENABLE_DEFAULT=1
CONFIG_X86_PTDUMP=y
diff --git a/config-generic b/config-generic
index 6266d37..83a056b 100644
--- a/config-generic
+++ b/config-generic
@@ -6,6 +6,7 @@ CONFIG_SMP=y
CONFIG_HOTPLUG_CPU=y
CONFIG_LOCALVERSION=""
CONFIG_CROSS_COMPILE=""
+CONFIG_DEFAULT_HOSTNAME="(none)"
#
# Code maturity level options
@@ -32,6 +33,7 @@ CONFIG_SWAP=y
CONFIG_SYSVIPC=y
CONFIG_BSD_PROCESS_ACCT=y
# CONFIG_BSD_PROCESS_ACCT_V3 is not set
+CONFIG_FHANDLE=y
CONFIG_TASKSTATS=y
CONFIG_TASK_DELAY_ACCT=y
CONFIG_TASK_XACCT=y
@@ -138,6 +140,7 @@ CONFIG_MMC_SDHCI_PLTFM=m
CONFIG_MMC_CB710=m
CONFIG_MMC_RICOH_MMC=y
CONFIG_MMC_USHC=m
+CONFIG_MMC_VUB300=m
CONFIG_CB710_CORE=m
# CONFIG_CB710_DEBUG is not set
@@ -191,6 +194,7 @@ CONFIG_EXTRA_FIRMWARE=""
#
CONFIG_MTD=m
# CONFIG_MTD_DEBUG is not set
+CONFIG_MTD_SWAP=m
CONFIG_MTD_PARTITIONS=y
CONFIG_MTD_AR7_PARTS=m
CONFIG_MTD_CONCAT=m
@@ -240,6 +244,7 @@ CONFIG_MTD_ABSENT=m
#
CONFIG_MTD_COMPLEX_MAPPINGS=y
# CONFIG_MTD_PHYSMAP is not set
+# CONFIG_MTD_LATCH_ADDR is not set
CONFIG_MTD_SC520CDP=m
CONFIG_MTD_NETSC520=m
# CONFIG_MTD_SBC_GXX is not set
@@ -282,6 +287,7 @@ CONFIG_MTD_NAND=m
# CONFIG_MTD_NAND_MUSEUM_IDS is not set
# CONFIG_MTD_NAND_PLATFORM is not set
# CONFIG_MTD_NAND_VERIFY_WRITE is not set
+# CONFIG_MTD_NAND_ECC_BCH is not set
# CONFIG_MTD_NAND_CAFE is not set
CONFIG_MTD_NAND_IDS=m
CONFIG_MTD_NAND_NANDSIM=m
@@ -569,6 +575,7 @@ CONFIG_SATA_ACARD_AHCI=m
CONFIG_PATA_ACPI=m
CONFIG_PATA_ALI=m
CONFIG_PATA_AMD=m
+CONFIG_PATA_ARASAN_CF=m
CONFIG_PATA_ARTOP=m
CONFIG_PATA_ATIIXP=m
CONFIG_PATA_CMD640_PCI=m
@@ -689,6 +696,7 @@ CONFIG_DM_LOG_USERSPACE=m
CONFIG_DM_MULTIPATH_QL=m
CONFIG_DM_MULTIPATH_ST=m
CONFIG_DM_RAID=m
+CONFIG_DM_FLAKEY=m
#
# Fusion MPT device support
@@ -759,6 +767,7 @@ CONFIG_INET_TUNNEL=m
CONFIG_INET_DIAG=m
CONFIG_IP_MULTICAST=y
CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_IP_FIB_TRIE_STATS=y
CONFIG_IP_MULTIPLE_TABLES=y
CONFIG_IP_ROUTE_MULTIPATH=y
CONFIG_IP_ROUTE_VERBOSE=y
@@ -806,7 +815,7 @@ CONFIG_IP_VS_NQ=m
CONFIG_IP_VS_FTP=m
CONFIG_IP_VS_PE_SIP=m
-CONFIG_IPV6=m
+CONFIG_IPV6=y
CONFIG_IPV6_PRIVACY=y
CONFIG_IPV6_ROUTER_PREF=y
CONFIG_IPV6_ROUTE_INFO=y
@@ -842,11 +851,12 @@ CONFIG_BRIDGE_IGMP_SNOOPING=y
# CONFIG_NETWORK_PHY_TIMESTAMPING is not set
CONFIG_NETFILTER=y
CONFIG_NETFILTER_ADVANCED=y
-CONFIG_NF_CONNTRACK=y
+CONFIG_NF_CONNTRACK=m
CONFIG_NETFILTER_NETLINK=m
CONFIG_NETFILTER_NETLINK_QUEUE=m
CONFIG_NETFILTER_NETLINK_LOG=m
CONFIG_NETFILTER_XTABLES=y
+CONFIG_NETFILTER_XT_SET=m
CONFIG_NETFILTER_XT_MARK=m
CONFIG_NETFILTER_XT_CONNMARK=m
CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
@@ -902,6 +912,9 @@ CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m
CONFIG_NETFILTER_XT_TARGET_IDLETIMER=m
CONFIG_NETFILTER_XT_MATCH_CPU=m
CONFIG_NETFILTER_XT_MATCH_IPVS=m
+CONFIG_NETFILTER_XT_TARGET_AUDIT=m
+CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m
+CONFIG_NETFILTER_XT_MATCH_DEVGROUP=m
# CONFIG_NETFILTER_DEBUG is not set
CONFIG_BRIDGE_NETFILTER=y
@@ -927,6 +940,8 @@ CONFIG_NF_CONNTRACK_SIP=m
CONFIG_NF_CONNTRACK_TFTP=m
CONFIG_NF_CONNTRACK_IPV4=y
CONFIG_NF_CONNTRACK_IPV6=y
+CONFIG_NF_CONNTRACK_TIMESTAMP=y
+CONFIG_NF_CONNTRACK_SNMP=m
CONFIG_NF_NAT=m
CONFIG_NF_NAT_SNMP_BASIC=m
CONFIG_NF_CT_PROTO_DCCP=m
@@ -1016,6 +1031,19 @@ CONFIG_INET6_XFRM_MODE_TUNNEL=m
CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m
CONFIG_INET6_XFRM_MODE_BEET=m
+CONFIG_IP_SET=m
+CONFIG_IP_SET_MAX=256
+CONFIG_IP_SET_BITMAP_IP=m
+CONFIG_IP_SET_BITMAP_IPMAC=m
+CONFIG_IP_SET_BITMAP_PORT=m
+CONFIG_IP_SET_HASH_IP=m
+CONFIG_IP_SET_HASH_IPPORT=m
+CONFIG_IP_SET_HASH_IPPORTIP=m
+CONFIG_IP_SET_HASH_IPPORTNET=m
+CONFIG_IP_SET_HASH_NET=m
+CONFIG_IP_SET_HASH_NETPORT=m
+CONFIG_IP_SET_LIST_SET=m
+
#
# SCTP Configuration (EXPERIMENTAL)
#
@@ -1077,6 +1105,10 @@ CONFIG_NET_SCH_RED=m
CONFIG_NET_SCH_SFQ=m
CONFIG_NET_SCH_TBF=m
CONFIG_NET_SCH_TEQL=m
+CONFIG_NET_SCH_SFB=m
+CONFIG_NET_SCH_MQPRIO=m
+CONFIG_NET_SCH_CHOKE=m
+CONFIG_NET_SCH_QFQ=m
CONFIG_NET_CLS=y
CONFIG_NET_CLS_ACT=y
CONFIG_NET_CLS_BASIC=m
@@ -1421,7 +1453,10 @@ CONFIG_ADM8211=m
CONFIG_ATH_COMMON=m
CONFIG_ATH5K=m
CONFIG_ATH5K_DEBUG=y
+# CONFIG_ATH5K_TRACER is not set
CONFIG_ATH9K=m
+CONFIG_ATH9K_PCI=y
+CONFIG_ATH9K_AHB=y
# CONFIG_ATH9K_DEBUG is not set
CONFIG_ATH9K_DEBUGFS=y
CONFIG_ATH9K_HTC=m
@@ -1479,7 +1514,13 @@ CONFIG_IWLWIFI=m
CONFIG_IWLWIFI_DEBUG=y
CONFIG_IWLWIFI_DEBUGFS=y
CONFIG_IWLWIFI_SPECTRUM_MEASUREMENT=y
+CONFIG_IWLWIFI_DEVICE_SVTOOL=y
+# CONFIG_IWL_P2P is not set
CONFIG_IWLAGN=m
+CONFIG_IWLWIFI_LEGACY=m
+CONFIG_IWLWIFI_LEGACY_DEBUG=y
+CONFIG_IWLWIFI_LEGACY_DEBUGFS=y
+# CONFIG_IWLWIFI_LEGACY_DEVICE_TRACING is not set
CONFIG_IWL4965=y
CONFIG_IWL5000=y
CONFIG_IWL3945=m
@@ -1508,16 +1549,19 @@ CONFIG_RT2500USB=m
CONFIG_RT2800USB=m
CONFIG_RT2800USB_RT33XX=y
CONFIG_RT2800USB_RT35XX=y
+CONFIG_RT2800USB_RT53XX=y
CONFIG_RT2800USB_UNKNOWN=y
CONFIG_RT2800PCI=m
CONFIG_RT2800PCI_RT33XX=y
CONFIG_RT2800PCI_RT35XX=y
+CONFIG_RT2800PCI_RT53XX=y
CONFIG_RT73USB=m
CONFIG_RTL8180=m
CONFIG_RTL8187=m
CONFIG_TMD_HERMES=m
CONFIG_USB_ZD1201=m
CONFIG_USB_NET_RNDIS_WLAN=m
+CONFIG_USB_NET_KALMIA=m
CONFIG_USB_NET_SMSC75XX=m
CONFIG_ZD1211RW=m
# CONFIG_ZD1211RW_DEBUG is not set
@@ -1538,6 +1582,11 @@ CONFIG_WL1271_SDIO=m
CONFIG_WL1271_SPI=m
CONFIG_RTL8192CE=m
+CONFIG_RTL8192SE=m
+CONFIG_RTL8192CU=m
+
+CONFIG_MWIFIEX=m
+CONFIG_MWIFIEX_SDIO=m
#
# Token Ring devices
@@ -1597,6 +1646,8 @@ CONFIG_CAN_TSCAN1=m
CONFIG_CAN_SLCAN=m
CONFIG_CAN_SOFTING=m
CONFIG_CAN_SOFTING_CS=m
+CONFIG_CAN_C_CAN=m
+CONFIG_CAN_C_CAN_PLATFORM=m
# CONFIG_PCH_CAN is not set
CONFIG_NETROM=m
CONFIG_ROSE=m
@@ -1655,9 +1706,9 @@ CONFIG_WINBOND_FIR=m
# Bluetooth support
#
CONFIG_BT=m
-CONFIG_BT_L2CAP=m
+CONFIG_BT_L2CAP=y
CONFIG_BT_L2CAP_EXT_FEATURES=y
-CONFIG_BT_SCO=m
+CONFIG_BT_SCO=y
CONFIG_BT_CMTP=m
CONFIG_BT_RFCOMM=m
CONFIG_BT_RFCOMM_TTY=y
@@ -1689,6 +1740,7 @@ CONFIG_BT_HCIUART_LL=y
CONFIG_BT_MRVL=m
CONFIG_BT_MRVL_SDIO=m
CONFIG_BT_ATH3K=m
+CONFIG_BT_WILINK=m
#
# ISDN subsystem
@@ -1880,12 +1932,14 @@ CONFIG_KEYBOARD_ATKBD=y
# CONFIG_KEYBOARD_STOWAWAY is not set
# CONFIG_KEYBOARD_LKKBD is not set
# CONFIG_KEYBOARD_LM8323 is not set
-# FIXME: Do we really need these keyboards enabled ?
-CONFIG_KEYBOARD_ADP5588=m
-CONFIG_KEYBOARD_MAX7359=m
+# CONFIG_KEYBOARD_ADP5588 is not set
+# CONFIG_KEYBOARD_MAX7359 is not set
+# CONFIG_KEYBOARD_ADP5589 is not set
+# CONFIG_KEYBOARD_MPR121 is not set
+# CONFIG_KEYBOARD_QT1070 is not set
# CONFIG_KEYBOARD_MCS is not set
-CONFIG_KEYBOARD_OPENCORES=m
-CONFIG_KEYBOARD_QT2160=m
+# CONFIG_KEYBOARD_OPENCORES is not set
+# CONFIG_KEYBOARD_QT2160 is not set
# CONFIG_KEYBOARD_TCA6416 is not set
CONFIG_INPUT_MOUSE=y
CONFIG_MOUSE_PS2=y
@@ -1959,6 +2013,8 @@ CONFIG_TOUCHSCREEN_USB_COMPOSITE=m
CONFIG_TOUCHSCREEN_W90X900=m
# CONFIG_TOUCHSCREEN_BU21013 is not set
CONFIG_TOUCHSCREEN_ST1232=m
+CONFIG_TOUCHSCREEN_ATMEL_MXT=m
+# CONFIG_TOUCHSCREEN_MAX11801 is not set
CONFIG_INPUT_MISC=y
CONFIG_INPUT_PCSPKR=m
@@ -1993,6 +2049,7 @@ CONFIG_SYNCLINKMP=m
CONFIG_SYNCLINK_GT=m
CONFIG_N_HDLC=m
CONFIG_N_GSM=m
+# CONFIG_TRACE_SINK is not set
# CONFIG_STALDRV is not set
# CONFIG_IBM_ASM is not set
CONFIG_TIFM_CORE=m
@@ -2041,6 +2098,7 @@ CONFIG_SERIAL_JSM=m
#
CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_XILINX_PS_UART is not set
# CONFIG_SERIAL_TIMBERDALE is not set
CONFIG_UNIX98_PTYS=y
CONFIG_DEVPTS_MULTIPLE_INSTANCES=y
@@ -2113,6 +2171,8 @@ CONFIG_I2C_TINY_USB=m
# CONFIG_I2C_DESIGNWARE is not set
# CONFIG_I2C_XILINX is not set
+CONFIG_I2C_DIOLAN_U2C=m
+
#
# I2C Hardware Sensors Chip support
#
@@ -2219,6 +2279,23 @@ CONFIG_SENSORS_W83795=m
# CONFIG_SENSORS_W83795_FANCTRL is not set
CONFIG_SENSORS_DS620=m
CONFIG_SENSORS_SHT21=m
+CONFIG_SENSORS_LINEAGE=m
+CONFIG_SENSORS_LTC4151=m
+CONFIG_SENSORS_MAX6639=m
+CONFIG_SENSORS_SCH5627=m
+CONFIG_SENSORS_ADS1015=m
+CONFIG_SENSORS_MAX16065=m
+CONFIG_SENSORS_MAX6642=m
+CONFIG_SENSORS_ADM1275=m
+CONFIG_SENSORS_UCD9000=m
+CONFIG_SENSORS_UCD9200=m
+CONFIG_SENSORS_EMC6W201=m
+
+CONFIG_PMBUS=m
+CONFIG_SENSORS_PMBUS=m
+CONFIG_SENSORS_MAX16064=m
+CONFIG_SENSORS_MAX34440=m
+CONFIG_SENSORS_MAX8688=m
# CONFIG_HMC6352 is not set
# CONFIG_BMP085 is not set
@@ -2241,6 +2318,9 @@ CONFIG_W1_SLAVE_DS2433=m
CONFIG_W1_SLAVE_DS2433_CRC=y
CONFIG_W1_SLAVE_DS2760=m
CONFIG_W1_SLAVE_DS2423=m
+CONFIG_W1_SLAVE_DS2408=m
+CONFIG_W1_SLAVE_DS2780=m
+CONFIG_W1_SLAVE_BQ27000=m
#
# Mice
@@ -2342,6 +2422,8 @@ CONFIG_RTC_DRV_WM831X=m
CONFIG_RTC_DRV_BQ32K=m
CONFIG_RTC_DRV_MSM6242=m
CONFIG_RTC_DRV_RP5C01=m
+CONFIG_RTC_DRV_EM3027=m
+CONFIG_RTC_DRV_RV3029C2=m
CONFIG_DTLK=m
CONFIG_R3964=m
@@ -2402,12 +2484,14 @@ CONFIG_HANGCHECK_TIMER=m
# Multimedia devices
#
CONFIG_MEDIA_SUPPORT=m
+CONFIG_MEDIA_CONTROLLER=y
CONFIG_VIDEO_DEV=m
# CONFIG_VIDEO_ADV_DEBUG is not set
CONFIG_VIDEO_HELPER_CHIPS_AUTO=y
CONFIG_VIDEO_ALLOW_V4L1=y
CONFIG_VIDEO_V4L1_COMPAT=y
CONFIG_VIDEO_V4L2=y
+CONFIG_VIDEO_V4L2_SUBDEV_API=y
# CONFIG_VIDEO_VIVI is not set
#
@@ -2424,11 +2508,13 @@ CONFIG_VIDEO_BT848=m
CONFIG_VIDEO_BT848_DVB=y
CONFIG_VIDEO_BWQCAM=m
CONFIG_VIDEO_SR030PC30=m
+CONFIG_VIDEO_NOON010PC30=m
CONFIG_VIDEO_CAFE_CCIC=m
# CONFIG_VIDEO_CPIA is not set
CONFIG_VIDEO_CPIA2=m
CONFIG_VIDEO_CQCAM=m
CONFIG_VIDEO_CX23885=m
+# CONFIG_MEDIA_ALTERA_CI is not set
CONFIG_VIDEO_CX18=m
CONFIG_VIDEO_CX18_ALSA=m
CONFIG_VIDEO_CX88=m
@@ -2473,6 +2559,7 @@ CONFIG_VIDEO_FB_IVTV=m
CONFIG_VIDEO_SAA7164=m
CONFIG_VIDEO_TLG2300=m
# CONFIG_VIDEO_TIMBERDALE is not set
+# CONFIG_VIDEO_M5MOLS is not set
CONFIG_USB_VIDEO_CLASS=m
CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y
@@ -2484,6 +2571,7 @@ CONFIG_RADIO_GEMTEK_PCI=m
CONFIG_RADIO_MAXIRADIO=m
CONFIG_RADIO_MAESTRO=m
CONFIG_RADIO_WL1273=m
+CONFIG_RADIO_WL128X=m
CONFIG_MEDIA_ATTACH=y
CONFIG_MEDIA_TUNER_CUSTOMISE=y
@@ -2503,6 +2591,7 @@ CONFIG_MEDIA_TUNER_MXL5007T=m
CONFIG_MEDIA_TUNER_MC44S803=m
CONFIG_MEDIA_TUNER_MAX2165=m
CONFIG_MEDIA_TUNER_TDA18218=m
+CONFIG_MEDIA_TUNER_TDA18212=m
#
# Digital Video Broadcasting Devices
@@ -2574,6 +2663,8 @@ CONFIG_DVB_ATBM8830=m
CONFIG_DVB_TDA665x=m
CONFIG_DVB_STV0299=m
CONFIG_DVB_MB86A16=m
+CONFIG_DVB_DRXD=m
+CONFIG_DVB_CXD2820R=m
#
# Supported Frontend Modules
@@ -2601,6 +2692,9 @@ CONFIG_DVB_DUMMY_FE=m
CONFIG_DVB_FIREDTV=m
CONFIG_DVB_NGENE=m
CONFIG_DVB_MB86A20S=m
+CONFIG_DVB_USB_TECHNISAT_USB2=m
+CONFIG_DVB_DIB9000=m
+CONFIG_DVB_STV0367=m
#
# Supported SAA7146 based PCI Adapters
@@ -2675,6 +2769,12 @@ CONFIG_IR_JVC_DECODER=m
CONFIG_IR_SONY_DECODER=m
CONFIG_IR_RC5_SZ_DECODER=m
CONFIG_IR_LIRC_CODEC=m
+CONFIG_IR_IMON=m
+CONFIG_IR_MCEUSB=m
+CONFIG_IR_ITE_CIR=m
+CONFIG_IR_NUVOTON=m
+CONFIG_IR_FINTEK=m
+CONFIG_IR_REDRAT3=m
CONFIG_V4L_MEM2MEM_DRIVERS=y
# CONFIG_VIDEO_MEM2MEM_TESTDEV is not set
@@ -2740,6 +2840,7 @@ CONFIG_FB_RIVA=m
# CONFIG_FB_RIVA_I2C is not set
# CONFIG_FB_S1D13XXX is not set
CONFIG_FB_S3=m
+CONFIG_FB_S3_DDC=y
CONFIG_FB_SAVAGE=m
CONFIG_FB_SAVAGE_I2C=y
CONFIG_FB_SAVAGE_ACCEL=y
@@ -2757,11 +2858,13 @@ CONFIG_FB_VOODOO1=m
# CONFIG_FB_VT8623 is not set
CONFIG_FB_EFI=y
CONFIG_FB_VIA=m
+CONFIG_FB_VIA_X_COMPATIBILITY=y
# CONFIG_FB_VIA_DIRECT_PROCFS is not set
CONFIG_FB_METRONOME=m
CONFIG_FB_MB862XX=m
CONFIG_FB_MB862XX_PCI_GDC=y
CONFIG_FB_MB862XX_LIME=y
+CONFIG_FB_MB862XX_I2C=y
# CONFIG_FB_PRE_INIT_FB is not set
# CONFIG_FB_TMIO is not set
# CONFIG_FB_BROADSHEET is not set
@@ -2872,6 +2975,7 @@ CONFIG_SND_ENS1371=m
CONFIG_SND_ES1938=m
CONFIG_SND_ES1968=m
CONFIG_SND_ES1968_INPUT=y
+CONFIG_SND_ES1968_RADIO=y
CONFIG_SND_FM801=m
CONFIG_SND_FM801_TEA575X_BOOL=y
CONFIG_SND_CTXFI=m
@@ -2929,6 +3033,7 @@ CONFIG_SND_VIRTUOSO=m
CONFIG_SND_VX222=m
CONFIG_SND_YMFPCI=m
CONFIG_SND_ASIHPI=m
+CONFIG_SND_LOLA=m
#
# ALSA USB devices
@@ -2940,6 +3045,7 @@ CONFIG_SND_USB_CAIAQ_INPUT=y
CONFIG_SND_USB_USX2Y=m
CONFIG_SND_USB_US122L=m
CONFIG_SND_USB_UA101=m
+CONFIG_SND_USB_6FIRE=m
#
# PCMCIA devices
@@ -2948,6 +3054,10 @@ CONFIG_SND_PCMCIA=y
CONFIG_SND_VXPOCKET=m
CONFIG_SND_PDAUDIOCF=m
+CONFIG_SND_FIREWIRE=y
+CONFIG_SND_FIREWIRE_SPEAKERS=m
+CONFIG_SND_ISIGHT=m
+
#
# Open Sound System
#
@@ -2980,6 +3090,8 @@ CONFIG_USB_EHCI_TT_NEWSCHED=y
CONFIG_USB_OHCI_HCD=y
# CONFIG_USB_OHCI_HCD_SSB is not set
CONFIG_USB_UHCI_HCD=y
+CONFIG_USB_SL811_HCD=m
+CONFIG_USB_SL811_HCD_ISO=y
# CONFIG_USB_SL811_CS is not set
# CONFIG_USB_R8A66597_HCD is not set
CONFIG_USB_XHCI_HCD=m
@@ -3000,17 +3112,19 @@ CONFIG_USB_TMC=m
# CONFIG_BLK_DEV_UB is not set
CONFIG_USB_STORAGE=m
# CONFIG_USB_STORAGE_DEBUG is not set
-CONFIG_USB_STORAGE_CYPRESS_ATACB=y
-CONFIG_USB_STORAGE_DATAFAB=y
-CONFIG_USB_STORAGE_FREECOM=y
-CONFIG_USB_STORAGE_ISD200=y
-CONFIG_USB_STORAGE_SDDR09=y
-CONFIG_USB_STORAGE_SDDR55=y
-CONFIG_USB_STORAGE_JUMPSHOT=y
+CONFIG_USB_STORAGE_CYPRESS_ATACB=m
+CONFIG_USB_STORAGE_DATAFAB=m
+CONFIG_USB_STORAGE_FREECOM=m
+CONFIG_USB_STORAGE_ISD200=m
+CONFIG_USB_STORAGE_SDDR09=m
+CONFIG_USB_STORAGE_SDDR55=m
+CONFIG_USB_STORAGE_JUMPSHOT=m
CONFIG_USB_STORAGE_USBAT=y
-CONFIG_USB_STORAGE_ONETOUCH=y
-CONFIG_USB_STORAGE_ALAUDA=y
-CONFIG_USB_STORAGE_KARMA=y
+CONFIG_USB_STORAGE_ONETOUCH=m
+CONFIG_USB_STORAGE_ALAUDA=m
+CONFIG_USB_STORAGE_KARMA=m
+CONFIG_USB_STORAGE_REALTEK=m
+CONFIG_USB_STORAGE_ENE_UB6250=m
# CONFIG_USB_LIBUSUAL is not set
CONFIG_USB_UAS=m
@@ -3064,12 +3178,10 @@ CONFIG_HID_SONY=m
CONFIG_HID_SUNPLUS=m
CONFIG_HID_GREENASIA=m
CONFIG_HID_SMARTJOYPLUS=m
-CONFIG_HID_TIVO_SLIDE=m
CONFIG_HID_TOPSEED=m
CONFIG_HID_THRUSTMASTER=m
CONFIG_HID_ZEROPLUS=m
CONFIG_HID_ZYDACRON=m
-CONFIG_HID_ACRUX=m
CONFIG_HID_ACRUX_FF=m
CONFIG_HID_EMS_FF=m
CONFIG_HID_ELECOM=m
@@ -3077,6 +3189,11 @@ CONFIG_HID_UCLOGIC=m
CONFIG_HID_WALTOP=m
CONFIG_HID_ROCCAT_PYRA=m
CONFIG_HID_ROCCAT_KONEPLUS=m
+CONFIG_HID_ACRUX=m
+CONFIG_HID_KEYTOUCH=m
+CONFIG_HID_LCPOWER=m
+CONFIG_HID_ROCCAT_ARVO=m
+CONFIG_HID_ROCCAT_KOVAPLUS=m
#
# USB Imaging devices
@@ -3135,6 +3252,9 @@ CONFIG_USB_GSPCA_KONICA=m
CONFIG_USB_GSPCA_XIRLINK_CIT=m
CONFIG_USB_GSPCA_SPCA1528=m
CONFIG_USB_GSPCA_SQ930X=m
+CONFIG_USB_GSPCA_NW80X=m
+CONFIG_USB_GSPCA_VICAM=m
+CONFIG_USB_GSPCA_KINECT=m
CONFIG_USB_IBMCAM=m
CONFIG_USB_KONICAWC=m
@@ -3160,6 +3280,7 @@ CONFIG_SOC_CAMERA_OV9640=m
CONFIG_SOC_CAMERA_OV6650=m
CONFIG_SOC_CAMERA_IMX074=m
CONFIG_SOC_CAMERA_OV2640=m
+CONFIG_SOC_CAMERA_OV9740=m
#
# USB Network adaptors
@@ -3188,6 +3309,7 @@ CONFIG_USB_NET_INT51X1=m
CONFIG_USB_CDC_PHONET=m
CONFIG_USB_IPHETH=m
CONFIG_USB_SIERRA_NET=m
+CONFIG_USB_VL600=m
#
# USB Host-to-Host Cables
@@ -3212,7 +3334,7 @@ CONFIG_USB_USS720=m
#
# USB Serial Converter support
#
-CONFIG_USB_SERIAL=m
+CONFIG_USB_SERIAL=y
CONFIG_USB_SERIAL_GENERIC=y
CONFIG_USB_SERIAL_AIRCABLE=m
CONFIG_USB_SERIAL_ARK3116=m
@@ -3278,6 +3400,8 @@ CONFIG_USB_SERIAL_DEBUG=m
CONFIG_USB_SERIAL_SSU100=m
CONFIG_USB_SERIAL_SAMBA=m
+CONFIG_USB_SERIAL_CONSOLE=y
+
CONFIG_USB_EZUSB=y
CONFIG_USB_EMI62=m
CONFIG_USB_LED=m
@@ -3321,7 +3445,6 @@ CONFIG_USB_PWC_INPUT_EVDEV=y
# CONFIG_USB_PWC_DEBUG is not set
# CONFIG_USB_RIO500 is not set
# CONFIG_USB_QUICKCAM_MESSENGER is not set
-CONFIG_USB_SL811_HCD=m
CONFIG_USB_SISUSBVGA=m
CONFIG_USB_SISUSBVGA_CON=y
CONFIG_RADIO_SI470X=y
@@ -3361,7 +3484,6 @@ CONFIG_PCF50633_GPIO=m
# CONFIG_AB3100_CORE is not set
CONFIG_INPUT_PCF50633_PMU=m
CONFIG_INPUT_GPIO_ROTARY_ENCODER=m
-CONFIG_CHARGER_PCF50633=m
CONFIG_RTC_DRV_PCF50633=m
CONFIG_RTC_DRV_DS3232=m
CONFIG_RTC_DRV_ISL12022=m
@@ -3487,6 +3609,7 @@ CONFIG_PROC_KCORE=y
CONFIG_PROC_VMCORE=y
CONFIG_TMPFS=y
CONFIG_TMPFS_POSIX_ACL=y
+CONFIG_TMPFS_XATTR=y
CONFIG_HUGETLBFS=y
CONFIG_HUGETLB_PAGE=y
CONFIG_DEBUG_FS=y
@@ -3549,9 +3672,10 @@ CONFIG_NFS_FSCACHE=y
# CONFIG_NFS_USE_LEGACY_DNS is not set
# CONFIG_NFS_USE_NEW_IDMAPPER is not set
# CONFIG_NFSD_DEPRECATED is not set
+CONFIG_PNFS_OBJLAYOUT=m
CONFIG_LOCKD=m
CONFIG_LOCKD_V4=y
-CONFIG_EXPORTFS=m
+CONFIG_EXPORTFS=y
CONFIG_SUNRPC=m
CONFIG_SUNRPC_GSS=m
CONFIG_SUNRPC_XPRT_RDMA=m
@@ -3571,6 +3695,7 @@ CONFIG_CIFS_ACL=y
CONFIG_CIFS_WEAK_PW_HASH=y
# CONFIG_CIFS_DEBUG2 is not set
CONFIG_CIFS_DFS_UPCALL=y
+CONFIG_CIFS_NFSD_EXPORT=y
CONFIG_NCP_FS=m
CONFIG_NCPFS_PACKET_SIGNING=y
CONFIG_NCPFS_IOCTL_LOCKING=y
@@ -3825,6 +3950,7 @@ CONFIG_BACKLIGHT_CLASS_DEVICE=m
# CONFIG_BACKLIGHT_GENERIC is not set
CONFIG_BACKLIGHT_PROGEAR=m
# CONFIG_BACKLIGHT_ADP8860 is not set
+# CONFIG_BACKLIGHT_ADP8870 is not set
CONFIG_FB_NVIDIA_BACKLIGHT=y
CONFIG_FB_RIVA_BACKLIGHT=y
CONFIG_FB_RADEON_BACKLIGHT=y
@@ -3857,6 +3983,7 @@ CONFIG_CGROUP_SCHED=y
CONFIG_CGROUP_MEM_RES_CTLR=y
CONFIG_CGROUP_MEM_RES_CTLR_SWAP=y # XXX disabled by default, pass 'swapaccount'
# CONFIG_CGROUP_MEM_RES_CTLR_SWAP_ENABLED is not set
+CONFIG_CGROUP_PERF=y
CONFIG_BLK_CGROUP=y
# CONFIG_DEBUG_BLK_CGROUP is not set
@@ -4068,9 +4195,11 @@ CONFIG_LEDS_TRIGGER_GPIO=m
CONFIG_LEDS_INTEL_SS4200=m
CONFIG_LEDS_LP5521=m
CONFIG_LEDS_LP5523=m
+CONFIG_LEDS_LM3530=m
CONFIG_DMADEVICES=y
CONFIG_DMA_ENGINE=y
+CONFIG_DW_DMAC=m
# CONFIG_TIMB_DMA is not set
CONFIG_NET_DMA=y
# CONFIG_DMATEST is not set
@@ -4122,13 +4251,15 @@ CONFIG_APM_POWER=m
# CONFIG_BATTERY_DS2760 is not set
# CONFIG_BATTERY_DS2782 is not set
# CONFIG_BATTERY_BQ20Z75 is not set
+# CONFIG_BATTERY_DS2780 is not set
# CONFIG_CHARGER_ISP1704 is not set
-CONFIG_BATTERY_PMU=m
+# CONFIG_CHARGER_MAX8903 is not set
# CONFIG_BATTERY_BQ27x00 is not set
# CONFIG_BATTERY_MAX17040 is not set
# CONFIG_PDA_POWER is not set
# CONFIG_CHARGER_GPIO is not set
# CONFIG_BATTERY_MAX17042 is not set
+# CONFIG_CHARGER_PCF50633 is not set
CONFIG_AUXDISPLAY=y
@@ -4172,6 +4303,8 @@ CONFIG_PM_TRACE_RTC=y
CONFIG_R6040=m
CONFIG_BNX2X=m
+CONFIG_SCSI_BNX2X_FCOE=m
+
CONFIG_NOZOMI=m
# CONFIG_TPS65010 is not set
# CONFIG_DEBUG_SECTION_MISMATCH is not set
@@ -4199,6 +4332,7 @@ CONFIG_MEMSTICK=m
CONFIG_MSPRO_BLOCK=m
CONFIG_MEMSTICK_TIFM_MS=m
CONFIG_MEMSTICK_JMICRON_38X=m
+CONFIG_MEMSTICK_R592=m
CONFIG_ACCESSIBILITY=y
CONFIG_A11Y_BRAILLE_CONSOLE=y
@@ -4238,7 +4372,6 @@ CONFIG_PHONET=m
CONFIG_ICS932S401=m
# CONFIG_C2PORT is not set
-CONFIG_W1_SLAVE_BQ27000=m
CONFIG_IT87_WDT=m
@@ -4327,6 +4460,15 @@ CONFIG_USB_ATMEL=m
# CONFIG_DX_SEP is not set
# CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI4 is not set
# CONFIG_TOUCHSCREEN_CLEARPAD_TM1217 is not set
+# CONFIG_RTS_PSTOR is not set
+# CONFIG_DRM_PSB is not set
+# CONFIG_ALTERA_STAPL is not set
+# CONFIG_DVB_CXD2099 is not set
+# CONFIG_USBIP_CORE is not set
+# CONFIG_BRCMSMAC is not set
+# CONFIG_BRCMFMAC is not set
+# CONFIG_INTEL_MEI is not set
+# CONFIG_ZCACHE is not set
#
# Android
@@ -4370,6 +4512,7 @@ CONFIG_STRIP_ASM_SYMS=y
# CONFIG_RCU_FANOUT_EXACT is not set
CONFIG_RCU_FAST_NO_HZ=y
CONFIG_SRCU_SYNCHRONIZE_DELAY=10
+CONFIG_RCU_CPU_STALL_TIMEOUT=60
CONFIG_KSM=y
CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
@@ -4392,6 +4535,8 @@ CONFIG_PPS_CLIENT_PARPORT=m
CONFIG_PPS_GENERATOR_PARPORT=m
CONFIG_NTP_PPS=y
+CONFIG_PTP_1588_CLOCK=m
+
# CONFIG_USB_SERIAL_QUATECH2 is not set
# CONFIG_VT6655 is not set
CONFIG_FB_UDL=m
@@ -4422,12 +4567,14 @@ CONFIG_DETECT_SOFTLOCKUP=y
CONFIG_LOCKUP_DETECTOR=y
# CONFIG_DEBUG_INFO_REDUCED is not set
# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
+# CONFIG_BOOTPARAM_HARDLOCKUP_PANIC is not set
# CONFIG_DETECT_HUNG_TASK is not set
# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
CONFIG_ATOMIC64_SELFTEST=y
CONFIG_MEMORY_FAILURE=y
CONFIG_HWPOISON_INJECT=m
+CONFIG_CLEANCACHE=y
CONFIG_BLK_DEV_DRBD=m
@@ -4448,6 +4595,7 @@ CONFIG_GPIO_SYSFS=y
# CONFIG_GPIO_IT8761E is not set
# CONFIG_GPIO_MAX7300 is not set
# CONFIG_UCB1400_CORE is not set
+# CONFIG_TPS6105X is not set
# CONFIG_RADIO_MIROPCM20 is not set
# CONFIG_USB_GPIO_VBUS is not set
# CONFIG_GPIO_SCH is not set
@@ -4468,10 +4616,6 @@ CONFIG_IR_CORE=m
CONFIG_IR_ENE=m
CONFIG_IR_STREAMZAP=m
CONFIG_IR_WINBOND_CIR=m
-CONFIG_IR_IMON=m
-CONFIG_IR_MCEUSB=m
-CONFIG_IR_NUVOTON=m
-CONFIG_IR_ITE_CIR=m
# CONFIG_GPIO_SX150X is not set
# CONFIG_MFD_STMPE is not set
@@ -4493,8 +4637,28 @@ CONFIG_NFC_DEVICES=y
CONFIG_PN544_NFC=m
CONFIG_TARGET_CORE=m
+CONFIG_LOOPBACK_TARGET=m
+# CONFIG_LOOPBACK_TARGET_CDB_DEBUG is not set
CONFIG_TCM_IBLOCK=m
CONFIG_TCM_FILEIO=m
CONFIG_TCM_PSCSI=m
+CONFIG_TCM_FC=m
+
+CONFIG_HWSPINLOCK=m
+
+CONFIG_PSTORE=y
+
+# CONFIG_AVERAGE is not set
+
+# CONFIG_SIGMA is not set
+
+CONFIG_DEFAULT_MESSAGE_LOGLEVEL=4
CONFIG_TEST_KSTRTOX=m
+
+CONFIG_BCMA=m
+CONFIG_BCMA_HOST_PCI=y
+# CONFIG_BCMA_DEBUG is not set
+
+# CONFIG_GOOGLE_FIRMWARE is not set
+CONFIG_INTEL_MID_PTI=m
diff --git a/config-ia64-generic b/config-ia64-generic
index 5c864b3..704c704 100644
--- a/config-ia64-generic
+++ b/config-ia64-generic
@@ -140,6 +140,8 @@ CONFIG_ACPI_VIDEO=m
CONFIG_ACPI_HED=m
CONFIG_ACPI_EC_DEBUGFS=m
CONFIG_ACPI_IPMI=m
+CONFIG_ACPI_CUSTOM_METHOD=m
+CONFIG_SENSORS_ACPI_POWER=m
CONFIG_PM=y
CONFIG_HOTPLUG_PCI=y
@@ -183,6 +185,7 @@ CONFIG_PROC_VMCORE=y
# CONFIG_IA64_MC_ERR_INJECT is not set
CONFIG_DMIID=y
+CONFIG_DMI_SYSFS=y
CONFIG_SENSORS_I5K_AMB=m
@@ -206,3 +209,5 @@ CONFIG_RCU_FANOUT=64
CONFIG_ACPI_POWER_METER=m
CONFIG_I2C_SCMI=m
+
+# CONFIG_HP_ACCEL is not set
diff --git a/config-nodebug b/config-nodebug
index 7510184..62650aa 100644
--- a/config-nodebug
+++ b/config-nodebug
@@ -41,6 +41,7 @@ CONFIG_CPUMASK_OFFSTACK=y
# CONFIG_DEBUG_OBJECTS_SELFTEST is not set
# CONFIG_DEBUG_OBJECTS_FREE is not set
# CONFIG_DEBUG_OBJECTS_TIMERS is not set
+# CONFIG_DEBUG_OBJECTS_RCU_HEAD is not set
CONFIG_DEBUG_OBJECTS_ENABLE_DEFAULT=1
# CONFIG_X86_PTDUMP is not set
diff --git a/config-powerpc-generic b/config-powerpc-generic
index 3c8d8f0..e47c315 100644
--- a/config-powerpc-generic
+++ b/config-powerpc-generic
@@ -325,6 +325,9 @@ CONFIG_PATA_MACIO=m
CONFIG_SERIAL_GRLIB_GAISLER_APBUART=m
# CONFIG_PMIC_ADP5520 is not set
# CONFIG_MFD_88PM8607 is not set
+# CONFIG_MFD_MAX8997 is not set
+# CONFIG_MFD_TPS65910 is not set
+# CONFIG_MFD_WL1273_CORE is not set
# CONFIG_XPS_USB_HCD_XILINX is not set
# CONFIG_MMC_SDHCI_OF_ESDHC is not set
# CONFIG_MMC_SDHCI_OF_HLWD is not set
@@ -339,5 +342,16 @@ CONFIG_MPC512X_DMA=m
CONFIG_KVM_GUEST=y
+CONFIG_I2C_MPC=m
+
# CONFIG_IMA is not set
# CONFIG_TCG_TPM is not set
+
+CONFIG_RFKILL_GPIO=m
+
+CONFIG_CRYPTO_DEV_FSL_CAAM=m
+CONFIG_CRYPTO_DEV_FSL_CAAM_RINGSIZE=9
+CONFIG_CRYPTO_DEV_FSL_CAAM_INTC=y
+CONFIG_CRYPTO_DEV_FSL_CAAM_INTC_COUNT_THLD=255
+CONFIG_CRYPTO_DEV_FSL_CAAM_INTC_TIME_THLD=2048
+CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API=m
diff --git a/config-powerpc32-generic b/config-powerpc32-generic
index daa06ab..31c399e 100644
--- a/config-powerpc32-generic
+++ b/config-powerpc32-generic
@@ -182,5 +182,6 @@ CONFIG_EVENT_PROFILE=y
CONFIG_KVM_BOOK3S_32=m
-### needs non-existant readq/writeq
# CONFIG_SCSI_QLA_ISCSI is not set
+
+CONFIG_BATTERY_PMU=m
diff --git a/config-powerpc64 b/config-powerpc64
index 2946a06..8866a53 100644
--- a/config-powerpc64
+++ b/config-powerpc64
@@ -184,3 +184,7 @@ CONFIG_CMM=y
# CONFIG_SPARSEMEM_VMEMMAP is not set
CONFIG_PSERIES_ENERGY=m
+
+CONFIG_PPC_ICSWX=y
+CONFIG_IO_EVENT_IRQ=y
+CONFIG_HW_RANDOM_AMD=m
diff --git a/config-s390x b/config-s390x
index 780fc91..da9db13 100644
--- a/config-s390x
+++ b/config-s390x
@@ -233,3 +233,8 @@ CONFIG_SCHED_MC=y
CONFIG_SCHED_BOOK=y
CONFIG_STRICT_DEVMEM=y
+
+# CONFIG_WARN_DYNAMIC_STACK is not set
+
+CONFIG_JUMP_LABEL=y
+CONFIG_CRYPTO_GHASH_S390=m
diff --git a/config-x86-generic b/config-x86-generic
index d6feae8..79a63a8 100644
--- a/config-x86-generic
+++ b/config-x86-generic
@@ -152,9 +152,11 @@ CONFIG_ACPI_POWER_METER=m
CONFIG_ACPI_PROCESSOR_AGGREGATOR=m
CONFIG_ACPI_HED=m
CONFIG_ACPI_APEI=y
+CONFIG_ACPI_APEI_PCIEAER=y
CONFIG_ACPI_APEI_GHES=m
# CONFIG_ACPI_APEI_EINJ is not set
CONFIG_ACPI_IPMI=m
+CONFIG_ACPI_CUSTOM_METHOD=m
#
# CPUFreq processor drivers
@@ -198,7 +200,6 @@ CONFIG_X86_TRAMPOLINE=y
#
CONFIG_NVRAM=y
CONFIG_IBM_ASM=m
-CONFIG_CRYPTO_AES_586=m
CONFIG_CRYPTO_TWOFISH_586=m
CONFIG_CRYPTO_DEV_PADLOCK=m
CONFIG_CRYPTO_DEV_PADLOCK_AES=m
@@ -324,6 +325,11 @@ CONFIG_TC1100_WMI=m
CONFIG_HP_WMI=m
# CONFIG_INTEL_SCU_IPC is not set
CONFIG_DELL_WMI=m
+CONFIG_DELL_WMI_AIO=m
+CONFIG_ASUS_WMI=m
+CONFIG_ASUS_NB_WMI=m
+CONFIG_XO15_EBOOK=m
+CONFIG_INTEL_OAKTRAIL=m
# CONFIG_TOUCHSCREEN_INTEL_MID is not set
@@ -362,6 +368,7 @@ CONFIG_LGUEST_GUEST=y
CONFIG_VMI=y
CONFIG_XEN=y
+# CONFIG_XEN_DEBUG is not set
CONFIG_XEN_MAX_DOMAIN_MEMORY=8
CONFIG_XEN_BALLOON=y
CONFIG_XEN_SCRUB_PAGES=y
@@ -371,13 +378,18 @@ CONFIG_XEN_FBDEV_FRONTEND=y
CONFIG_XEN_KBDDEV_FRONTEND=y
CONFIG_XEN_BLKDEV_FRONTEND=m
CONFIG_XEN_NETDEV_FRONTEND=m
+CONFIG_XEN_NETDEV_BACKEND=m
+CONFIG_XEN_WDT=m
+CONFIG_XEN_GRANT_DEV_ALLOC=m
CONFIG_XEN_PCIDEV_FRONTEND=m
CONFIG_XENFS=m
CONFIG_XEN_COMPAT_XENFS=y
CONFIG_XEN_BACKEND=y
+CONFIG_XEN_BLKDEV_BACKEND=m
CONFIG_XEN_DEBUG_FS=y
CONFIG_XEN_PLATFORM_PCI=m
CONFIG_XEN_GNTDEV=m
+CONFIG_INPUT_XEN_KBDDEV_FRONTEND=m
CONFIG_MTD_ESB2ROM=m
CONFIG_MTD_CK804XROM=m
@@ -400,6 +412,8 @@ CONFIG_THINKPAD_ACPI_ALSA_SUPPORT=y
CONFIG_MACINTOSH_DRIVERS=y
CONFIG_DMIID=y
+CONFIG_DMI_SYSFS=y
+
CONFIG_ISCSI_IBFT_FIND=y
CONFIG_ISCSI_IBFT=m
@@ -407,6 +421,8 @@ CONFIG_DMADEVICES=y
CONFIG_INTEL_IOATDMA=m
CONFIG_SENSORS_I5K_AMB=m
+CONFIG_SENSORS_FAM15H_POWER=m
+CONFIG_SENSORS_ACPI_POWER=m
# CONFIG_CPA_DEBUG is not set
# CONFIG_PROVIDE_OHCI1394_DMA_INIT is not set
@@ -420,6 +436,9 @@ CONFIG_OLPC_OPENFIRMWARE=y
CONFIG_BATTERY_OLPC=y
CONFIG_MOUSE_PS2_OLPC=y
+# staging
+# CONFIG_FB_OLPC_DCON is not set
+
CONFIG_STRICT_DEVMEM=y
# CONFIG_NO_BOOTMEM is not set
@@ -478,6 +497,7 @@ CONFIG_SFI=y
CONFIG_INPUT_WINBOND_CIR=m
CONFIG_I2C_SCMI=m
+CONFIG_I2C_PXA=m
CONFIG_SBC_FITPC2_WATCHDOG=m
CONFIG_EDAC_I3200=m
CONFIG_EDAC_DECODE_MCE=m
@@ -536,7 +556,8 @@ CONFIG_X86_32_IRIS=m
CONFIG_TRANSPARENT_HUGEPAGE=y
-CONFIG_CRYPTO_AES_NI_INTEL=m
+CONFIG_CRYPTO_AES_NI_INTEL=y
+CONFIG_CRYPTO_AES_586=y
CONFIG_MTD_OF_PARTS=m
CONFIG_MTD_PHYSMAP_OF=m
@@ -544,3 +565,7 @@ CONFIG_PROC_DEVICETREE=y
CONFIG_SERIAL_OF_PLATFORM=m
CONFIG_SERIAL_GRLIB_GAISLER_APBUART=m
# CONFIG_MMC_SDHCI_OF is not set
+
+CONFIG_HP_ACCEL=m
+
+# CONFIG_RAPIDIO is not set
diff --git a/config-x86_64-generic b/config-x86_64-generic
index 0154cf1..d4a9a5f 100644
--- a/config-x86_64-generic
+++ b/config-x86_64-generic
@@ -98,9 +98,11 @@ CONFIG_ACPI_POWER_METER=m
CONFIG_ACPI_PROCESSOR_AGGREGATOR=m
CONFIG_ACPI_HED=m
CONFIG_ACPI_APEI=y
+CONFIG_ACPI_APEI_PCIEAER=y
CONFIG_ACPI_APEI_GHES=m
# CONFIG_ACPI_APEI_EINJ is not set
CONFIG_ACPI_IPMI=m
+CONFIG_ACPI_CUSTOM_METHOD=m
CONFIG_X86_PLATFORM_DEVICES=y
CONFIG_ASUS_LAPTOP=m
@@ -118,6 +120,12 @@ CONFIG_ACER_WMI=m
CONFIG_ACERHDF=m
CONFIG_HP_WMI=m
CONFIG_DELL_WMI=m
+CONFIG_DELL_WMI_AIO=m
+CONFIG_ASUS_WMI=m
+CONFIG_ASUS_NB_WMI=m
+# CONFIG_XO15_EBOOK is not set
+CONFIG_INTEL_OAKTRAIL=m
+
# CONFIG_INTEL_SCU_IPC is not set
# CONFIG_TOUCHSCREEN_INTEL_MID is not set
@@ -160,6 +168,7 @@ CONFIG_CRYPTO_DEV_PADLOCK_SHA=m
CONFIG_CRYPTO_AES_X86_64=y
CONFIG_CRYPTO_AES_NI_INTEL=y
+
CONFIG_CRYPTO_TWOFISH_X86_64=m
CONFIG_CRYPTO_SALSA20_X86_64=m
@@ -269,6 +278,8 @@ CONFIG_PROC_VMCORE=y
CONFIG_CRASH=m
CONFIG_DMIID=y
+CONFIG_DMI_SYSFS=y
+
CONFIG_ISCSI_IBFT_FIND=y
CONFIG_ISCSI_IBFT=m
@@ -294,6 +305,7 @@ CONFIG_KVM_GUEST=y
CONFIG_KVM_MMU_AUDIT=y
CONFIG_XEN=y
+# CONFIG_XEN_DEBUG is not set
CONFIG_XEN_MAX_DOMAIN_MEMORY=32
CONFIG_XEN_BALLOON=y
CONFIG_XEN_SCRUB_PAGES=y
@@ -303,20 +315,27 @@ CONFIG_XEN_FBDEV_FRONTEND=y
CONFIG_XEN_KBDDEV_FRONTEND=y
CONFIG_XEN_BLKDEV_FRONTEND=m
CONFIG_XEN_NETDEV_FRONTEND=m
+CONFIG_XEN_NETDEV_BACKEND=m
+CONFIG_XEN_WDT=m
+CONFIG_XEN_GRANT_DEV_ALLOC=m
CONFIG_XEN_PCIDEV_FRONTEND=m
CONFIG_XENFS=m
CONFIG_XEN_COMPAT_XENFS=y
CONFIG_XEN_DEV_EVTCHN=m
CONFIG_XEN_SYS_HYPERVISOR=y
CONFIG_XEN_BACKEND=y
+CONFIG_XEN_BLKDEV_BACKEND=m
CONFIG_XEN_GNTDEV=m
CONFIG_XEN_DEBUG_FS=y
CONFIG_XEN_PLATFORM_PCI=m
+CONFIG_INPUT_XEN_KBDDEV_FRONTEND=m
CONFIG_DMADEVICES=y
CONFIG_INTEL_IOATDMA=m
CONFIG_SENSORS_I5K_AMB=m
+CONFIG_SENSORS_FAM15H_POWER=m
+CONFIG_SENSORS_ACPI_POWER=m
# CONFIG_COMPAT_VDSO is not set
CONFIG_PROVIDE_OHCI1394_DMA_INIT=y
@@ -449,3 +468,9 @@ CONFIG_JUMP_LABEL=y
CONFIG_HP_ILO=m
CONFIG_TRANSPARENT_HUGEPAGE=y
+
+CONFIG_HP_ACCEL=m
+
+# CONFIG_RAPIDIO is not set
+
+CONFIG_BPF_JIT=y
diff --git a/drm-intel-edp-fixes.patch b/drm-intel-edp-fixes.patch
index c77ef11..9e8c829 100644
--- a/drm-intel-edp-fixes.patch
+++ b/drm-intel-edp-fixes.patch
@@ -25,20 +25,12 @@ index 300f64b..2e3db37 100644
if (I915_READ(PCH_PP_STATUS) & PP_ON)
return true;
-@@ -816,7 +817,7 @@ static bool ironlake_edp_panel_on (struct intel_dp *intel_dp)
- */
- msleep(300);
+@@ -851,7 +851,7 @@ static bool ironlake_edp_panel_on (struc
+ I915_WRITE(PCH_PP_CONTROL, pp);
+ POSTING_READ(PCH_PP_CONTROL);
- if (wait_for((I915_READ(PCH_PP_STATUS) & idle_on_mask) == idle_on_mask,
+ if (wait_for((I915_READ(PCH_PP_STATUS) & idle_on_mask) == idle_on,
5000))
DRM_ERROR("panel on wait timed out: 0x%08x\n",
I915_READ(PCH_PP_STATUS));
-@@ -922,6 +923,7 @@ static void intel_dp_prepare(struct drm_encoder *encoder)
-
- if (is_edp(intel_dp)) {
- ironlake_edp_backlight_off(dev);
-+ ironlake_edp_panel_off(dev);
- ironlake_edp_panel_on(intel_dp);
- if (!is_pch_edp(intel_dp))
- ironlake_edp_pll_on(encoder);
diff --git a/drm-nouveau-updates.patch b/drm-nouveau-updates.patch
index 7a703e8..e69de29 100644
--- a/drm-nouveau-updates.patch
+++ b/drm-nouveau-updates.patch
@@ -1,6777 +0,0 @@
-diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.c
b/drivers/gpu/drm/nouveau/nouveau_bios.c
-index 6bdab89..729d5fd 100644
---- a/drivers/gpu/drm/nouveau/nouveau_bios.c
-+++ b/drivers/gpu/drm/nouveau/nouveau_bios.c
-@@ -269,7 +269,7 @@ struct init_tbl_entry {
- int (*handler)(struct nvbios *, uint16_t, struct init_exec *);
- };
-
--static int parse_init_table(struct nvbios *, unsigned int, struct init_exec *);
-+static int parse_init_table(struct nvbios *, uint16_t, struct init_exec *);
-
- #define MACRO_INDEX_SIZE 2
- #define MACRO_SIZE 8
-@@ -282,7 +282,7 @@ static void still_alive(void)
- {
- #if 0
- sync();
-- msleep(2);
-+ mdelay(2);
- #endif
- }
-
-@@ -1904,7 +1904,7 @@ init_condition_time(struct nvbios *bios, uint16_t offset,
- BIOSLOG(bios, "0x%04X: "
- "Condition not met, sleeping for 20ms\n",
- offset);
-- msleep(20);
-+ mdelay(20);
- }
- }
-
-@@ -1938,7 +1938,7 @@ init_ltime(struct nvbios *bios, uint16_t offset, struct init_exec
*iexec)
- BIOSLOG(bios, "0x%04X: Sleeping for 0x%04X milliseconds\n",
- offset, time);
-
-- msleep(time);
-+ mdelay(time);
-
- return 3;
- }
-@@ -2011,6 +2011,27 @@ init_sub_direct(struct nvbios *bios, uint16_t offset, struct
init_exec *iexec)
- }
-
- static int
-+init_jump(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
-+{
-+ /*
-+ * INIT_JUMP opcode: 0x5C ('\')
-+ *
-+ * offset (8 bit): opcode
-+ * offset + 1 (16 bit): offset (in bios)
-+ *
-+ * Continue execution of init table from 'offset'
-+ */
-+
-+ uint16_t jmp_offset = ROM16(bios->data[offset + 1]);
-+
-+ if (!iexec->execute)
-+ return 3;
-+
-+ BIOSLOG(bios, "0x%04X: Jump to 0x%04X\n", offset, jmp_offset);
-+ return jmp_offset - offset;
-+}
-+
-+static int
- init_i2c_if(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
- {
- /*
-@@ -2962,7 +2983,7 @@ init_time(struct nvbios *bios, uint16_t offset, struct init_exec
*iexec)
- if (time < 1000)
- udelay(time);
- else
-- msleep((time + 900) / 1000);
-+ mdelay((time + 900) / 1000);
-
- return 3;
- }
-@@ -3659,6 +3680,7 @@ static struct init_tbl_entry itbl_entry[] = {
- { "INIT_ZM_REG_SEQUENCE" , 0x58, init_zm_reg_sequence
},
- /* INIT_INDIRECT_REG (0x5A, 7, 0, 0) removed due to no example of use */
- { "INIT_SUB_DIRECT" , 0x5B, init_sub_direct
},
-+ { "INIT_JUMP" , 0x5C, init_jump
},
- { "INIT_I2C_IF" , 0x5E, init_i2c_if
},
- { "INIT_COPY_NV_REG" , 0x5F, init_copy_nv_reg
},
- { "INIT_ZM_INDEX_IO" , 0x62, init_zm_index_io
},
-@@ -3700,8 +3722,7 @@ static struct init_tbl_entry itbl_entry[] = {
- #define MAX_TABLE_OPS 1000
-
- static int
--parse_init_table(struct nvbios *bios, unsigned int offset,
-- struct init_exec *iexec)
-+parse_init_table(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
- {
- /*
- * Parses all commands in an init table.
-@@ -3856,7 +3877,7 @@ static int call_lvds_manufacturer_script(struct drm_device *dev,
struct dcb_entr
-
- if (script == LVDS_PANEL_OFF) {
- /* off-on delay in ms */
-- msleep(ROM16(bios->data[bios->fp.xlated_entry + 7]));
-+ mdelay(ROM16(bios->data[bios->fp.xlated_entry + 7]));
- }
- #ifdef __powerpc__
- /* Powerbook specific quirks */
-@@ -5028,11 +5049,7 @@ int get_pll_limits(struct drm_device *dev, uint32_t limit_match,
struct pll_lims
- pll_lim->vco1.max_n = record[11];
- pll_lim->min_p = record[12];
- pll_lim->max_p = record[13];
-- /* where did this go to?? */
-- if ((entry[0] & 0xf0) == 0x80)
-- pll_lim->refclk = 27000;
-- else
-- pll_lim->refclk = 100000;
-+ pll_lim->refclk = ROM16(entry[9]) * 1000;
- }
-
- /*
-@@ -5950,6 +5967,11 @@ apply_dcb_connector_quirks(struct nvbios *bios, int idx)
- }
- }
-
-+static const u8 hpd_gpio[16] = {
-+ 0xff, 0x07, 0x08, 0xff, 0xff, 0x51, 0x52, 0xff,
-+ 0xff, 0xff, 0xff, 0xff, 0xff, 0x5e, 0x5f, 0x60,
-+};
-+
- static void
- parse_dcb_connector_table(struct nvbios *bios)
- {
-@@ -5986,23 +6008,9 @@ parse_dcb_connector_table(struct nvbios *bios)
-
- cte->type = (cte->entry & 0x000000ff) >> 0;
- cte->index2 = (cte->entry & 0x00000f00) >> 8;
-- switch (cte->entry & 0x00033000) {
-- case 0x00001000:
-- cte->gpio_tag = 0x07;
-- break;
-- case 0x00002000:
-- cte->gpio_tag = 0x08;
-- break;
-- case 0x00010000:
-- cte->gpio_tag = 0x51;
-- break;
-- case 0x00020000:
-- cte->gpio_tag = 0x52;
-- break;
-- default:
-- cte->gpio_tag = 0xff;
-- break;
-- }
-+
-+ cte->gpio_tag = ffs((cte->entry & 0x07033000) >> 12);
-+ cte->gpio_tag = hpd_gpio[cte->gpio_tag];
-
- if (cte->type == 0xff)
- continue;
-@@ -6023,6 +6031,7 @@ parse_dcb_connector_table(struct nvbios *bios)
- case DCB_CONNECTOR_DVI_I:
- case DCB_CONNECTOR_DVI_D:
- case DCB_CONNECTOR_LVDS:
-+ case DCB_CONNECTOR_LVDS_SPWG:
- case DCB_CONNECTOR_DP:
- case DCB_CONNECTOR_eDP:
- case DCB_CONNECTOR_HDMI_0:
-@@ -6342,6 +6351,32 @@ apply_dcb_encoder_quirks(struct drm_device *dev, int idx, u32
*conn, u32 *conf)
- }
- }
-
-+ /* XFX GT-240X-YA
-+ *
-+ * So many things wrong here, replace the entire encoder table..
-+ */
-+ if (nv_match_device(dev, 0x0ca3, 0x1682, 0x3003)) {
-+ if (idx == 0) {
-+ *conn = 0x02001300; /* VGA, connector 1 */
-+ *conf = 0x00000028;
-+ } else
-+ if (idx == 1) {
-+ *conn = 0x01010312; /* DVI, connector 0 */
-+ *conf = 0x00020030;
-+ } else
-+ if (idx == 2) {
-+ *conn = 0x01010310; /* VGA, connector 0 */
-+ *conf = 0x00000028;
-+ } else
-+ if (idx == 3) {
-+ *conn = 0x02022362; /* HDMI, connector 2 */
-+ *conf = 0x00020010;
-+ } else {
-+ *conn = 0x0000000e; /* EOL */
-+ *conf = 0x00000000;
-+ }
-+ }
-+
- return true;
- }
-
-@@ -6702,11 +6737,11 @@ nouveau_bios_run_init_table(struct drm_device *dev, uint16_t
table,
- struct nvbios *bios = &dev_priv->vbios;
- struct init_exec iexec = { true, false };
-
-- mutex_lock(&bios->lock);
-+ spin_lock_bh(&bios->lock);
- bios->display.output = dcbent;
- parse_init_table(bios, table, &iexec);
- bios->display.output = NULL;
-- mutex_unlock(&bios->lock);
-+ spin_unlock_bh(&bios->lock);
- }
-
- static bool NVInitVBIOS(struct drm_device *dev)
-@@ -6715,7 +6750,7 @@ static bool NVInitVBIOS(struct drm_device *dev)
- struct nvbios *bios = &dev_priv->vbios;
-
- memset(bios, 0, sizeof(struct nvbios));
-- mutex_init(&bios->lock);
-+ spin_lock_init(&bios->lock);
- bios->dev = dev;
-
- if (!NVShadowVBIOS(dev, bios->data))
-diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.h
b/drivers/gpu/drm/nouveau/nouveau_bios.h
-index 50a648e..050c314 100644
---- a/drivers/gpu/drm/nouveau/nouveau_bios.h
-+++ b/drivers/gpu/drm/nouveau/nouveau_bios.h
-@@ -82,6 +82,7 @@ enum dcb_connector_type {
- DCB_CONNECTOR_DVI_I = 0x30,
- DCB_CONNECTOR_DVI_D = 0x31,
- DCB_CONNECTOR_LVDS = 0x40,
-+ DCB_CONNECTOR_LVDS_SPWG = 0x41,
- DCB_CONNECTOR_DP = 0x46,
- DCB_CONNECTOR_eDP = 0x47,
- DCB_CONNECTOR_HDMI_0 = 0x60,
-@@ -251,7 +252,7 @@ struct nvbios {
- uint8_t digital_min_front_porch;
- bool fp_no_ddc;
-
-- struct mutex lock;
-+ spinlock_t lock;
-
- uint8_t data[NV_PROM_SIZE];
- unsigned int length;
-diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c
-index a521840..2ad49cb 100644
---- a/drivers/gpu/drm/nouveau/nouveau_bo.c
-+++ b/drivers/gpu/drm/nouveau/nouveau_bo.c
-@@ -57,8 +57,8 @@ nouveau_bo_del_ttm(struct ttm_buffer_object *bo)
- }
-
- static void
--nouveau_bo_fixup_align(struct nouveau_bo *nvbo, int *align, int *size,
-- int *page_shift)
-+nouveau_bo_fixup_align(struct nouveau_bo *nvbo, u32 flags,
-+ int *align, int *size, int *page_shift)
- {
- struct drm_nouveau_private *dev_priv = nouveau_bdev(nvbo->bo.bdev);
-
-@@ -83,7 +83,7 @@ nouveau_bo_fixup_align(struct nouveau_bo *nvbo, int *align, int *size,
- }
- } else {
- if (likely(dev_priv->chan_vm)) {
-- if (*size > 256 * 1024)
-+ if (!(flags & TTM_PL_FLAG_TT) && *size > 256 * 1024)
- *page_shift = dev_priv->chan_vm->lpg_shift;
- else
- *page_shift = dev_priv->chan_vm->spg_shift;
-@@ -101,8 +101,7 @@ nouveau_bo_fixup_align(struct nouveau_bo *nvbo, int *align, int
*size,
- int
- nouveau_bo_new(struct drm_device *dev, struct nouveau_channel *chan,
- int size, int align, uint32_t flags, uint32_t tile_mode,
-- uint32_t tile_flags, bool no_vm, bool mappable,
-- struct nouveau_bo **pnvbo)
-+ uint32_t tile_flags, struct nouveau_bo **pnvbo)
- {
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_bo *nvbo;
-@@ -113,16 +112,14 @@ nouveau_bo_new(struct drm_device *dev, struct nouveau_channel
*chan,
- return -ENOMEM;
- INIT_LIST_HEAD(&nvbo->head);
- INIT_LIST_HEAD(&nvbo->entry);
-- nvbo->mappable = mappable;
-- nvbo->no_vm = no_vm;
- nvbo->tile_mode = tile_mode;
- nvbo->tile_flags = tile_flags;
- nvbo->bo.bdev = &dev_priv->ttm.bdev;
-
-- nouveau_bo_fixup_align(nvbo, &align, &size, &page_shift);
-+ nouveau_bo_fixup_align(nvbo, flags, &align, &size, &page_shift);
- align >>= PAGE_SHIFT;
-
-- if (!nvbo->no_vm && dev_priv->chan_vm) {
-+ if (dev_priv->chan_vm) {
- ret = nouveau_vm_get(dev_priv->chan_vm, size, page_shift,
- NV_MEM_ACCESS_RW, &nvbo->vma);
- if (ret) {
-@@ -144,11 +141,8 @@ nouveau_bo_new(struct drm_device *dev, struct nouveau_channel
*chan,
- }
- nvbo->channel = NULL;
-
-- if (nvbo->vma.node) {
-- if (nvbo->bo.mem.mem_type == TTM_PL_VRAM)
-- nvbo->bo.offset = nvbo->vma.offset;
-- }
--
-+ if (nvbo->vma.node)
-+ nvbo->bo.offset = nvbo->vma.offset;
- *pnvbo = nvbo;
- return 0;
- }
-@@ -318,11 +312,8 @@ nouveau_bo_validate(struct nouveau_bo *nvbo, bool interruptible,
- if (ret)
- return ret;
-
-- if (nvbo->vma.node) {
-- if (nvbo->bo.mem.mem_type == TTM_PL_VRAM)
-- nvbo->bo.offset = nvbo->vma.offset;
-- }
--
-+ if (nvbo->vma.node)
-+ nvbo->bo.offset = nvbo->vma.offset;
- return 0;
- }
-
-@@ -385,7 +376,8 @@ nouveau_bo_create_ttm_backend_entry(struct ttm_bo_device *bdev)
- case NOUVEAU_GART_AGP:
- return ttm_agp_backend_init(bdev, dev->agp->bridge);
- #endif
-- case NOUVEAU_GART_SGDMA:
-+ case NOUVEAU_GART_PDMA:
-+ case NOUVEAU_GART_HW:
- return nouveau_sgdma_init_ttm(dev);
- default:
- NV_ERROR(dev, "Unknown GART type %d\n",
-@@ -431,7 +423,10 @@ nouveau_bo_init_mem_type(struct ttm_bo_device *bdev, uint32_t type,
- man->default_caching = TTM_PL_FLAG_WC;
- break;
- case TTM_PL_TT:
-- man->func = &ttm_bo_manager_func;
-+ if (dev_priv->card_type >= NV_50)
-+ man->func = &nouveau_gart_manager;
-+ else
-+ man->func = &ttm_bo_manager_func;
- switch (dev_priv->gart_info.type) {
- case NOUVEAU_GART_AGP:
- man->flags = TTM_MEMTYPE_FLAG_MAPPABLE;
-@@ -439,7 +434,8 @@ nouveau_bo_init_mem_type(struct ttm_bo_device *bdev, uint32_t type,
- TTM_PL_FLAG_WC;
- man->default_caching = TTM_PL_FLAG_WC;
- break;
-- case NOUVEAU_GART_SGDMA:
-+ case NOUVEAU_GART_PDMA:
-+ case NOUVEAU_GART_HW:
- man->flags = TTM_MEMTYPE_FLAG_MAPPABLE |
- TTM_MEMTYPE_FLAG_CMA;
- man->available_caching = TTM_PL_MASK_CACHING;
-@@ -501,45 +497,22 @@ nouveau_bo_move_accel_cleanup(struct nouveau_channel *chan,
- return ret;
- }
-
--static inline uint32_t
--nouveau_bo_mem_ctxdma(struct ttm_buffer_object *bo,
-- struct nouveau_channel *chan, struct ttm_mem_reg *mem)
--{
-- struct nouveau_bo *nvbo = nouveau_bo(bo);
--
-- if (nvbo->no_vm) {
-- if (mem->mem_type == TTM_PL_TT)
-- return NvDmaGART;
-- return NvDmaVRAM;
-- }
--
-- if (mem->mem_type == TTM_PL_TT)
-- return chan->gart_handle;
-- return chan->vram_handle;
--}
--
- static int
- nvc0_bo_move_m2mf(struct nouveau_channel *chan, struct ttm_buffer_object *bo,
- struct ttm_mem_reg *old_mem, struct ttm_mem_reg *new_mem)
- {
-- struct drm_nouveau_private *dev_priv = nouveau_bdev(bo->bdev);
-+ struct nouveau_mem *old_node = old_mem->mm_node;
-+ struct nouveau_mem *new_node = new_mem->mm_node;
- struct nouveau_bo *nvbo = nouveau_bo(bo);
-- u64 src_offset = old_mem->start << PAGE_SHIFT;
-- u64 dst_offset = new_mem->start << PAGE_SHIFT;
- u32 page_count = new_mem->num_pages;
-+ u64 src_offset, dst_offset;
- int ret;
-
-- if (!nvbo->no_vm) {
-- if (old_mem->mem_type == TTM_PL_VRAM)
-- src_offset = nvbo->vma.offset;
-- else
-- src_offset += dev_priv->gart_info.aper_base;
--
-- if (new_mem->mem_type == TTM_PL_VRAM)
-- dst_offset = nvbo->vma.offset;
-- else
-- dst_offset += dev_priv->gart_info.aper_base;
-- }
-+ src_offset = old_node->tmp_vma.offset;
-+ if (new_node->tmp_vma.node)
-+ dst_offset = new_node->tmp_vma.offset;
-+ else
-+ dst_offset = nvbo->vma.offset;
-
- page_count = new_mem->num_pages;
- while (page_count) {
-@@ -574,33 +547,18 @@ static int
- nv50_bo_move_m2mf(struct nouveau_channel *chan, struct ttm_buffer_object *bo,
- struct ttm_mem_reg *old_mem, struct ttm_mem_reg *new_mem)
- {
-- struct drm_nouveau_private *dev_priv = nouveau_bdev(bo->bdev);
-+ struct nouveau_mem *old_node = old_mem->mm_node;
-+ struct nouveau_mem *new_node = new_mem->mm_node;
- struct nouveau_bo *nvbo = nouveau_bo(bo);
- u64 length = (new_mem->num_pages << PAGE_SHIFT);
- u64 src_offset, dst_offset;
- int ret;
-
-- src_offset = old_mem->start << PAGE_SHIFT;
-- dst_offset = new_mem->start << PAGE_SHIFT;
-- if (!nvbo->no_vm) {
-- if (old_mem->mem_type == TTM_PL_VRAM)
-- src_offset = nvbo->vma.offset;
-- else
-- src_offset += dev_priv->gart_info.aper_base;
--
-- if (new_mem->mem_type == TTM_PL_VRAM)
-- dst_offset = nvbo->vma.offset;
-- else
-- dst_offset += dev_priv->gart_info.aper_base;
-- }
--
-- ret = RING_SPACE(chan, 3);
-- if (ret)
-- return ret;
--
-- BEGIN_RING(chan, NvSubM2MF, 0x0184, 2);
-- OUT_RING (chan, nouveau_bo_mem_ctxdma(bo, chan, old_mem));
-- OUT_RING (chan, nouveau_bo_mem_ctxdma(bo, chan, new_mem));
-+ src_offset = old_node->tmp_vma.offset;
-+ if (new_node->tmp_vma.node)
-+ dst_offset = new_node->tmp_vma.offset;
-+ else
-+ dst_offset = nvbo->vma.offset;
-
- while (length) {
- u32 amount, stride, height;
-@@ -681,6 +639,15 @@ nv50_bo_move_m2mf(struct nouveau_channel *chan, struct
ttm_buffer_object *bo,
- return 0;
- }
-
-+static inline uint32_t
-+nouveau_bo_mem_ctxdma(struct ttm_buffer_object *bo,
-+ struct nouveau_channel *chan, struct ttm_mem_reg *mem)
-+{
-+ if (mem->mem_type == TTM_PL_TT)
-+ return chan->gart_handle;
-+ return chan->vram_handle;
-+}
-+
- static int
- nv04_bo_move_m2mf(struct nouveau_channel *chan, struct ttm_buffer_object *bo,
- struct ttm_mem_reg *old_mem, struct ttm_mem_reg *new_mem)
-@@ -734,15 +701,43 @@ nouveau_bo_move_m2mf(struct ttm_buffer_object *bo, int evict, bool
intr,
- {
- struct drm_nouveau_private *dev_priv = nouveau_bdev(bo->bdev);
- struct nouveau_bo *nvbo = nouveau_bo(bo);
-+ struct ttm_mem_reg *old_mem = &bo->mem;
- struct nouveau_channel *chan;
- int ret;
-
- chan = nvbo->channel;
-- if (!chan || nvbo->no_vm) {
-+ if (!chan) {
- chan = dev_priv->channel;
- mutex_lock_nested(&chan->mutex, NOUVEAU_KCHANNEL_MUTEX);
- }
-
-+ /* create temporary vma for old memory, this will get cleaned
-+ * up after ttm destroys the ttm_mem_reg
-+ */
-+ if (dev_priv->card_type >= NV_50) {
-+ struct nouveau_mem *node = old_mem->mm_node;
-+ if (!node->tmp_vma.node) {
-+ u32 page_shift = nvbo->vma.node->type;
-+ if (old_mem->mem_type == TTM_PL_TT)
-+ page_shift = nvbo->vma.vm->spg_shift;
-+
-+ ret = nouveau_vm_get(chan->vm,
-+ old_mem->num_pages << PAGE_SHIFT,
-+ page_shift, NV_MEM_ACCESS_RO,
-+ &node->tmp_vma);
-+ if (ret)
-+ goto out;
-+ }
-+
-+ if (old_mem->mem_type == TTM_PL_VRAM)
-+ nouveau_vm_map(&node->tmp_vma, node);
-+ else {
-+ nouveau_vm_map_sg(&node->tmp_vma, 0,
-+ old_mem->num_pages << PAGE_SHIFT,
-+ node, node->pages);
-+ }
-+ }
-+
- if (dev_priv->card_type < NV_50)
- ret = nv04_bo_move_m2mf(chan, bo, &bo->mem, new_mem);
- else
-@@ -756,6 +751,7 @@ nouveau_bo_move_m2mf(struct ttm_buffer_object *bo, int evict, bool
intr,
- no_wait_gpu, new_mem);
- }
-
-+out:
- if (chan == dev_priv->channel)
- mutex_unlock(&chan->mutex);
- return ret;
-@@ -766,6 +762,7 @@ nouveau_bo_move_flipd(struct ttm_buffer_object *bo, bool evict, bool
intr,
- bool no_wait_reserve, bool no_wait_gpu,
- struct ttm_mem_reg *new_mem)
- {
-+ struct drm_nouveau_private *dev_priv = nouveau_bdev(bo->bdev);
- u32 placement_memtype = TTM_PL_FLAG_TT | TTM_PL_MASK_CACHING;
- struct ttm_placement placement;
- struct ttm_mem_reg tmp_mem;
-@@ -785,7 +782,23 @@ nouveau_bo_move_flipd(struct ttm_buffer_object *bo, bool evict, bool
intr,
- if (ret)
- goto out;
-
-+ if (dev_priv->card_type >= NV_50) {
-+ struct nouveau_bo *nvbo = nouveau_bo(bo);
-+ struct nouveau_mem *node = tmp_mem.mm_node;
-+ struct nouveau_vma *vma = &nvbo->vma;
-+ if (vma->node->type != vma->vm->spg_shift)
-+ vma = &node->tmp_vma;
-+ nouveau_vm_map_sg(vma, 0, tmp_mem.num_pages << PAGE_SHIFT,
-+ node, node->pages);
-+ }
-+
- ret = nouveau_bo_move_m2mf(bo, true, intr, no_wait_reserve, no_wait_gpu,
&tmp_mem);
-+
-+ if (dev_priv->card_type >= NV_50) {
-+ struct nouveau_bo *nvbo = nouveau_bo(bo);
-+ nouveau_vm_unmap(&nvbo->vma);
-+ }
-+
- if (ret)
- goto out;
-
-@@ -828,6 +841,36 @@ out:
- return ret;
- }
-
-+static void
-+nouveau_bo_move_ntfy(struct ttm_buffer_object *bo, struct ttm_mem_reg *new_mem)
-+{
-+ struct drm_nouveau_private *dev_priv = nouveau_bdev(bo->bdev);
-+ struct nouveau_mem *node = new_mem->mm_node;
-+ struct nouveau_bo *nvbo = nouveau_bo(bo);
-+ struct nouveau_vma *vma = &nvbo->vma;
-+ struct nouveau_vm *vm = vma->vm;
-+
-+ if (dev_priv->card_type < NV_50)
-+ return;
-+
-+ switch (new_mem->mem_type) {
-+ case TTM_PL_VRAM:
-+ nouveau_vm_map(vma, node);
-+ break;
-+ case TTM_PL_TT:
-+ if (vma->node->type != vm->spg_shift) {
-+ nouveau_vm_unmap(vma);
-+ vma = &node->tmp_vma;
-+ }
-+ nouveau_vm_map_sg(vma, 0, new_mem->num_pages << PAGE_SHIFT,
-+ node, node->pages);
-+ break;
-+ default:
-+ nouveau_vm_unmap(&nvbo->vma);
-+ break;
-+ }
-+}
-+
- static int
- nouveau_bo_vm_bind(struct ttm_buffer_object *bo, struct ttm_mem_reg *new_mem,
- struct nouveau_tile_reg **new_tile)
-@@ -835,19 +878,13 @@ nouveau_bo_vm_bind(struct ttm_buffer_object *bo, struct ttm_mem_reg
*new_mem,
- struct drm_nouveau_private *dev_priv = nouveau_bdev(bo->bdev);
- struct drm_device *dev = dev_priv->dev;
- struct nouveau_bo *nvbo = nouveau_bo(bo);
-- uint64_t offset;
-+ u64 offset = new_mem->start << PAGE_SHIFT;
-
-- if (nvbo->no_vm || new_mem->mem_type != TTM_PL_VRAM) {
-- /* Nothing to do. */
-- *new_tile = NULL;
-+ *new_tile = NULL;
-+ if (new_mem->mem_type != TTM_PL_VRAM)
- return 0;
-- }
--
-- offset = new_mem->start << PAGE_SHIFT;
-
-- if (dev_priv->chan_vm) {
-- nouveau_vm_map(&nvbo->vma, new_mem->mm_node);
-- } else if (dev_priv->card_type >= NV_10) {
-+ if (dev_priv->card_type >= NV_10) {
- *new_tile = nv10_mem_set_tiling(dev, offset, new_mem->size,
- nvbo->tile_mode,
- nvbo->tile_flags);
-@@ -864,11 +901,8 @@ nouveau_bo_vm_cleanup(struct ttm_buffer_object *bo,
- struct drm_nouveau_private *dev_priv = nouveau_bdev(bo->bdev);
- struct drm_device *dev = dev_priv->dev;
-
-- if (dev_priv->card_type >= NV_10 &&
-- dev_priv->card_type < NV_50) {
-- nv10_mem_put_tile_region(dev, *old_tile, bo->sync_obj);
-- *old_tile = new_tile;
-- }
-+ nv10_mem_put_tile_region(dev, *old_tile, bo->sync_obj);
-+ *old_tile = new_tile;
- }
-
- static int
-@@ -882,9 +916,11 @@ nouveau_bo_move(struct ttm_buffer_object *bo, bool evict, bool
intr,
- struct nouveau_tile_reg *new_tile = NULL;
- int ret = 0;
-
-- ret = nouveau_bo_vm_bind(bo, new_mem, &new_tile);
-- if (ret)
-- return ret;
-+ if (dev_priv->card_type < NV_50) {
-+ ret = nouveau_bo_vm_bind(bo, new_mem, &new_tile);
-+ if (ret)
-+ return ret;
-+ }
-
- /* Fake bo copy. */
- if (old_mem->mem_type == TTM_PL_SYSTEM && !bo->ttm) {
-@@ -915,10 +951,12 @@ nouveau_bo_move(struct ttm_buffer_object *bo, bool evict, bool
intr,
- ret = ttm_bo_move_memcpy(bo, evict, no_wait_reserve, no_wait_gpu, new_mem);
-
- out:
-- if (ret)
-- nouveau_bo_vm_cleanup(bo, NULL, &new_tile);
-- else
-- nouveau_bo_vm_cleanup(bo, new_tile, &nvbo->tile);
-+ if (dev_priv->card_type < NV_50) {
-+ if (ret)
-+ nouveau_bo_vm_cleanup(bo, NULL, &new_tile);
-+ else
-+ nouveau_bo_vm_cleanup(bo, new_tile, &nvbo->tile);
-+ }
-
- return ret;
- }
-@@ -959,7 +997,7 @@ nouveau_ttm_io_mem_reserve(struct ttm_bo_device *bdev, struct
ttm_mem_reg *mem)
- break;
- case TTM_PL_VRAM:
- {
-- struct nouveau_vram *vram = mem->mm_node;
-+ struct nouveau_mem *node = mem->mm_node;
- u8 page_shift;
-
- if (!dev_priv->bar1_vm) {
-@@ -970,23 +1008,23 @@ nouveau_ttm_io_mem_reserve(struct ttm_bo_device *bdev, struct
ttm_mem_reg *mem)
- }
-
- if (dev_priv->card_type == NV_C0)
-- page_shift = vram->page_shift;
-+ page_shift = node->page_shift;
- else
- page_shift = 12;
-
- ret = nouveau_vm_get(dev_priv->bar1_vm, mem->bus.size,
- page_shift, NV_MEM_ACCESS_RW,
-- &vram->bar_vma);
-+ &node->bar_vma);
- if (ret)
- return ret;
-
-- nouveau_vm_map(&vram->bar_vma, vram);
-+ nouveau_vm_map(&node->bar_vma, node);
- if (ret) {
-- nouveau_vm_put(&vram->bar_vma);
-+ nouveau_vm_put(&node->bar_vma);
- return ret;
- }
-
-- mem->bus.offset = vram->bar_vma.offset;
-+ mem->bus.offset = node->bar_vma.offset;
- if (dev_priv->card_type == NV_50) /*XXX*/
- mem->bus.offset -= 0x0020000000ULL;
- mem->bus.base = pci_resource_start(dev->pdev, 1);
-@@ -1003,16 +1041,16 @@ static void
- nouveau_ttm_io_mem_free(struct ttm_bo_device *bdev, struct ttm_mem_reg *mem)
- {
- struct drm_nouveau_private *dev_priv = nouveau_bdev(bdev);
-- struct nouveau_vram *vram = mem->mm_node;
-+ struct nouveau_mem *node = mem->mm_node;
-
- if (!dev_priv->bar1_vm || mem->mem_type != TTM_PL_VRAM)
- return;
-
-- if (!vram->bar_vma.node)
-+ if (!node->bar_vma.node)
- return;
-
-- nouveau_vm_unmap(&vram->bar_vma);
-- nouveau_vm_put(&vram->bar_vma);
-+ nouveau_vm_unmap(&node->bar_vma);
-+ nouveau_vm_put(&node->bar_vma);
- }
-
- static int
-@@ -1062,6 +1100,7 @@ struct ttm_bo_driver nouveau_bo_driver = {
- .invalidate_caches = nouveau_bo_invalidate_caches,
- .init_mem_type = nouveau_bo_init_mem_type,
- .evict_flags = nouveau_bo_evict_flags,
-+ .move_notify = nouveau_bo_move_ntfy,
- .move = nouveau_bo_move,
- .verify_access = nouveau_bo_verify_access,
- .sync_obj_signaled = __nouveau_fence_signalled,
-diff --git a/drivers/gpu/drm/nouveau/nouveau_channel.c
b/drivers/gpu/drm/nouveau/nouveau_channel.c
-index 3960d66..3837090 100644
---- a/drivers/gpu/drm/nouveau/nouveau_channel.c
-+++ b/drivers/gpu/drm/nouveau/nouveau_channel.c
-@@ -35,7 +35,7 @@ nouveau_channel_pushbuf_ctxdma_init(struct nouveau_channel *chan)
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_bo *pb = chan->pushbuf_bo;
- struct nouveau_gpuobj *pushbuf = NULL;
-- int ret;
-+ int ret = 0;
-
- if (dev_priv->card_type >= NV_50) {
- if (dev_priv->card_type < NV_C0) {
-@@ -90,8 +90,7 @@ nouveau_channel_user_pushbuf_alloc(struct drm_device *dev)
- else
- location = TTM_PL_FLAG_TT;
-
-- ret = nouveau_bo_new(dev, NULL, 65536, 0, location, 0, 0x0000, false,
-- true, &pushbuf);
-+ ret = nouveau_bo_new(dev, NULL, 65536, 0, location, 0, 0x0000, &pushbuf);
- if (ret) {
- NV_ERROR(dev, "error allocating DMA push buffer: %d\n", ret);
- return NULL;
-diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c
b/drivers/gpu/drm/nouveau/nouveau_connector.c
-index 390d82c..084c089 100644
---- a/drivers/gpu/drm/nouveau/nouveau_connector.c
-+++ b/drivers/gpu/drm/nouveau/nouveau_connector.c
-@@ -438,7 +438,7 @@ nouveau_connector_set_property(struct drm_connector *connector,
- }
-
- /* LVDS always needs gpu scaling */
-- if (nv_connector->dcb->type == DCB_CONNECTOR_LVDS &&
-+ if (connector->connector_type == DRM_MODE_CONNECTOR_LVDS &&
- value == DRM_MODE_SCALE_NONE)
- return -EINVAL;
-
-@@ -646,6 +646,7 @@ nouveau_connector_get_modes(struct drm_connector *connector)
- ret = get_slave_funcs(encoder)->get_modes(encoder, connector);
-
- if (nv_connector->dcb->type == DCB_CONNECTOR_LVDS ||
-+ nv_connector->dcb->type == DCB_CONNECTOR_LVDS_SPWG ||
- nv_connector->dcb->type == DCB_CONNECTOR_eDP)
- ret += nouveau_connector_scaler_modes_add(connector);
-
-@@ -806,6 +807,7 @@ nouveau_connector_create(struct drm_device *dev, int index)
- type = DRM_MODE_CONNECTOR_HDMIA;
- break;
- case DCB_CONNECTOR_LVDS:
-+ case DCB_CONNECTOR_LVDS_SPWG:
- type = DRM_MODE_CONNECTOR_LVDS;
- funcs = &nouveau_connector_funcs_lvds;
- break;
-@@ -834,7 +836,7 @@ nouveau_connector_create(struct drm_device *dev, int index)
- drm_connector_helper_add(connector, &nouveau_connector_helper_funcs);
-
- /* Check if we need dithering enabled */
-- if (dcb->type == DCB_CONNECTOR_LVDS) {
-+ if (connector->connector_type == DRM_MODE_CONNECTOR_LVDS) {
- bool dummy, is_24bit = false;
-
- ret = nouveau_bios_parse_lvds_table(dev, 0, &dummy, &is_24bit);
-@@ -879,7 +881,7 @@ nouveau_connector_create(struct drm_device *dev, int index)
- nv_connector->use_dithering ?
- DRM_MODE_DITHERING_ON : DRM_MODE_DITHERING_OFF);
-
-- if (dcb->type != DCB_CONNECTOR_LVDS) {
-+ if (connector->connector_type != DRM_MODE_CONNECTOR_LVDS) {
- if (dev_priv->card_type >= NV_50)
- connector->polled = DRM_CONNECTOR_POLL_HPD;
- else
-diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c
b/drivers/gpu/drm/nouveau/nouveau_display.c
-index 505c6bf..764c15d 100644
---- a/drivers/gpu/drm/nouveau/nouveau_display.c
-+++ b/drivers/gpu/drm/nouveau/nouveau_display.c
-@@ -32,6 +32,7 @@
- #include "nouveau_hw.h"
- #include "nouveau_crtc.h"
- #include "nouveau_dma.h"
-+#include "nv50_display.h"
-
- static void
- nouveau_user_framebuffer_destroy(struct drm_framebuffer *drm_fb)
-@@ -61,18 +62,59 @@ static const struct drm_framebuffer_funcs nouveau_framebuffer_funcs =
{
- };
-
- int
--nouveau_framebuffer_init(struct drm_device *dev, struct nouveau_framebuffer
*nouveau_fb,
-- struct drm_mode_fb_cmd *mode_cmd, struct nouveau_bo *nvbo)
-+nouveau_framebuffer_init(struct drm_device *dev,
-+ struct nouveau_framebuffer *nv_fb,
-+ struct drm_mode_fb_cmd *mode_cmd,
-+ struct nouveau_bo *nvbo)
- {
-+ struct drm_nouveau_private *dev_priv = dev->dev_private;
-+ struct drm_framebuffer *fb = &nv_fb->base;
- int ret;
-
-- ret = drm_framebuffer_init(dev, &nouveau_fb->base,
&nouveau_framebuffer_funcs);
-+ ret = drm_framebuffer_init(dev, fb, &nouveau_framebuffer_funcs);
- if (ret) {
- return ret;
- }
-
-- drm_helper_mode_fill_fb_struct(&nouveau_fb->base, mode_cmd);
-- nouveau_fb->nvbo = nvbo;
-+ drm_helper_mode_fill_fb_struct(fb, mode_cmd);
-+ nv_fb->nvbo = nvbo;
-+
-+ if (dev_priv->card_type >= NV_50) {
-+ u32 tile_flags = nouveau_bo_tile_layout(nvbo);
-+ if (tile_flags == 0x7a00 ||
-+ tile_flags == 0xfe00)
-+ nv_fb->r_dma = NvEvoFB32;
-+ else
-+ if (tile_flags == 0x7000)
-+ nv_fb->r_dma = NvEvoFB16;
-+ else
-+ nv_fb->r_dma = NvEvoVRAM_LP;
-+
-+ switch (fb->depth) {
-+ case 8: nv_fb->r_format = NV50_EVO_CRTC_FB_DEPTH_8; break;
-+ case 15: nv_fb->r_format = NV50_EVO_CRTC_FB_DEPTH_15; break;
-+ case 16: nv_fb->r_format = NV50_EVO_CRTC_FB_DEPTH_16; break;
-+ case 24:
-+ case 32: nv_fb->r_format = NV50_EVO_CRTC_FB_DEPTH_24; break;
-+ case 30: nv_fb->r_format = NV50_EVO_CRTC_FB_DEPTH_30; break;
-+ default:
-+ NV_ERROR(dev, "unknown depth %d\n", fb->depth);
-+ return -EINVAL;
-+ }
-+
-+ if (dev_priv->chipset == 0x50)
-+ nv_fb->r_format |= (tile_flags << 8);
-+
-+ if (!tile_flags)
-+ nv_fb->r_pitch = 0x00100000 | fb->pitch;
-+ else {
-+ u32 mode = nvbo->tile_mode;
-+ if (dev_priv->card_type >= NV_C0)
-+ mode >>= 4;
-+ nv_fb->r_pitch = ((fb->pitch / 4) << 4) | mode;
-+ }
-+ }
-+
- return 0;
- }
-
-@@ -182,6 +224,7 @@ nouveau_page_flip_emit(struct nouveau_channel *chan,
- struct nouveau_page_flip_state *s,
- struct nouveau_fence **pfence)
- {
-+ struct drm_nouveau_private *dev_priv = chan->dev->dev_private;
- struct drm_device *dev = chan->dev;
- unsigned long flags;
- int ret;
-@@ -201,9 +244,12 @@ nouveau_page_flip_emit(struct nouveau_channel *chan,
- if (ret)
- goto fail;
-
-- BEGIN_RING(chan, NvSubSw, NV_SW_PAGE_FLIP, 1);
-- OUT_RING(chan, 0);
-- FIRE_RING(chan);
-+ if (dev_priv->card_type < NV_C0)
-+ BEGIN_RING(chan, NvSubSw, NV_SW_PAGE_FLIP, 1);
-+ else
-+ BEGIN_NVC0(chan, 2, NvSubM2MF, 0x0500, 1);
-+ OUT_RING (chan, 0);
-+ FIRE_RING (chan);
-
- ret = nouveau_fence_new(chan, pfence, true);
- if (ret)
-@@ -244,7 +290,7 @@ nouveau_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer
*fb,
-
- /* Initialize a page flip struct */
- *s = (struct nouveau_page_flip_state)
-- { { }, s->event, nouveau_crtc(crtc)->index,
-+ { { }, event, nouveau_crtc(crtc)->index,
- fb->bits_per_pixel, fb->pitch, crtc->x, crtc->y,
- new_bo->bo.offset };
-
-@@ -255,6 +301,14 @@ nouveau_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer
*fb,
- mutex_lock(&chan->mutex);
-
- /* Emit a page flip */
-+ if (dev_priv->card_type >= NV_50) {
-+ ret = nv50_display_flip_next(crtc, fb, chan);
-+ if (ret) {
-+ nouveau_channel_put(&chan);
-+ goto fail_unreserve;
-+ }
-+ }
-+
- ret = nouveau_page_flip_emit(chan, old_bo, new_bo, s, &fence);
- nouveau_channel_put(&chan);
- if (ret)
-@@ -305,7 +359,8 @@ nouveau_finish_page_flip(struct nouveau_channel *chan,
- }
-
- list_del(&s->head);
-- *ps = *s;
-+ if (ps)
-+ *ps = *s;
- kfree(s);
-
- spin_unlock_irqrestore(&dev->event_lock, flags);
-diff --git a/drivers/gpu/drm/nouveau/nouveau_dma.c
b/drivers/gpu/drm/nouveau/nouveau_dma.c
-index b368ed7..568caed 100644
---- a/drivers/gpu/drm/nouveau/nouveau_dma.c
-+++ b/drivers/gpu/drm/nouveau/nouveau_dma.c
-@@ -83,7 +83,7 @@ nouveau_dma_init(struct nouveau_channel *chan)
- return ret;
-
- /* NV_MEMORY_TO_MEMORY_FORMAT requires a notifier object */
-- ret = nouveau_notifier_alloc(chan, NvNotify0, 32, 0xfd0, 0x1000,
-+ ret = nouveau_notifier_alloc(chan, NvNotify0, 32, 0xfe0, 0x1000,
- &chan->m2mf_ntfy);
- if (ret)
- return ret;
-@@ -97,13 +97,15 @@ nouveau_dma_init(struct nouveau_channel *chan)
- OUT_RING(chan, 0);
-
- /* Initialise NV_MEMORY_TO_MEMORY_FORMAT */
-- ret = RING_SPACE(chan, 4);
-+ ret = RING_SPACE(chan, 6);
- if (ret)
- return ret;
- BEGIN_RING(chan, NvSubM2MF, NV_MEMORY_TO_MEMORY_FORMAT_NAME, 1);
-- OUT_RING(chan, NvM2MF);
-- BEGIN_RING(chan, NvSubM2MF, NV_MEMORY_TO_MEMORY_FORMAT_DMA_NOTIFY, 1);
-- OUT_RING(chan, NvNotify0);
-+ OUT_RING (chan, NvM2MF);
-+ BEGIN_RING(chan, NvSubM2MF, NV_MEMORY_TO_MEMORY_FORMAT_DMA_NOTIFY, 3);
-+ OUT_RING (chan, NvNotify0);
-+ OUT_RING (chan, chan->vram_handle);
-+ OUT_RING (chan, chan->gart_handle);
-
- /* Sit back and pray the channel works.. */
- FIRE_RING(chan);
-diff --git a/drivers/gpu/drm/nouveau/nouveau_dma.h
b/drivers/gpu/drm/nouveau/nouveau_dma.h
-index c36f176..23d4edf 100644
---- a/drivers/gpu/drm/nouveau/nouveau_dma.h
-+++ b/drivers/gpu/drm/nouveau/nouveau_dma.h
-@@ -61,8 +61,6 @@ enum {
- NvM2MF = 0x80000001,
- NvDmaFB = 0x80000002,
- NvDmaTT = 0x80000003,
-- NvDmaVRAM = 0x80000004,
-- NvDmaGART = 0x80000005,
- NvNotify0 = 0x80000006,
- Nv2D = 0x80000007,
- NvCtxSurf2D = 0x80000008,
-@@ -73,12 +71,15 @@ enum {
- NvImageBlit = 0x8000000d,
- NvSw = 0x8000000e,
- NvSema = 0x8000000f,
-+ NvEvoSema0 = 0x80000010,
-+ NvEvoSema1 = 0x80000011,
-
- /* G80+ display objects */
- NvEvoVRAM = 0x01000000,
- NvEvoFB16 = 0x01000001,
- NvEvoFB32 = 0x01000002,
-- NvEvoVRAM_LP = 0x01000003
-+ NvEvoVRAM_LP = 0x01000003,
-+ NvEvoSync = 0xcafe0000
- };
-
- #define NV_MEMORY_TO_MEMORY_FORMAT 0x00000039
-diff --git a/drivers/gpu/drm/nouveau/nouveau_dp.c b/drivers/gpu/drm/nouveau/nouveau_dp.c
-index 38d5995..7beb82a 100644
---- a/drivers/gpu/drm/nouveau/nouveau_dp.c
-+++ b/drivers/gpu/drm/nouveau/nouveau_dp.c
-@@ -175,7 +175,6 @@ nouveau_dp_link_train_adjust(struct drm_encoder *encoder, uint8_t
*config)
- {
- struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
- struct drm_device *dev = encoder->dev;
-- struct bit_displayport_encoder_table_entry *dpse;
- struct bit_displayport_encoder_table *dpe;
- int ret, i, dpe_headerlen, vs = 0, pre = 0;
- uint8_t request[2];
-@@ -183,7 +182,6 @@ nouveau_dp_link_train_adjust(struct drm_encoder *encoder, uint8_t
*config)
- dpe = nouveau_bios_dp_table(dev, nv_encoder->dcb, &dpe_headerlen);
- if (!dpe)
- return false;
-- dpse = (void *)((char *)dpe + dpe_headerlen);
-
- ret = auxch_rd(encoder, DP_ADJUST_REQUEST_LANE0_1, request, 2);
- if (ret)
-diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h
b/drivers/gpu/drm/nouveau/nouveau_drv.h
-index 982d70b..b260c55 100644
---- a/drivers/gpu/drm/nouveau/nouveau_drv.h
-+++ b/drivers/gpu/drm/nouveau/nouveau_drv.h
-@@ -57,7 +57,7 @@ struct nouveau_fpriv {
- #include "nouveau_util.h"
-
- struct nouveau_grctx;
--struct nouveau_vram;
-+struct nouveau_mem;
- #include "nouveau_vm.h"
-
- #define MAX_NUM_DCB_ENTRIES 16
-@@ -65,13 +65,16 @@ struct nouveau_vram;
- #define NOUVEAU_MAX_CHANNEL_NR 128
- #define NOUVEAU_MAX_TILE_NR 15
-
--struct nouveau_vram {
-+struct nouveau_mem {
- struct drm_device *dev;
-
- struct nouveau_vma bar_vma;
-+ struct nouveau_vma tmp_vma;
- u8 page_shift;
-
-+ struct drm_mm_node *tag;
- struct list_head regions;
-+ dma_addr_t *pages;
- u32 memtype;
- u64 offset;
- u64 size;
-@@ -90,6 +93,7 @@ struct nouveau_tile_reg {
- struct nouveau_bo {
- struct ttm_buffer_object bo;
- struct ttm_placement placement;
-+ u32 valid_domains;
- u32 placements[3];
- u32 busy_placements[3];
- struct ttm_bo_kmap_obj kmap;
-@@ -104,8 +108,6 @@ struct nouveau_bo {
- struct nouveau_channel *channel;
-
- struct nouveau_vma vma;
-- bool mappable;
-- bool no_vm;
-
- uint32_t tile_mode;
- uint32_t tile_flags;
-@@ -387,6 +389,7 @@ struct nouveau_pgraph_engine {
- };
-
- struct nouveau_display_engine {
-+ void *priv;
- int (*early_init)(struct drm_device *);
- void (*late_takedown)(struct drm_device *);
- int (*create)(struct drm_device *);
-@@ -433,6 +436,7 @@ struct nouveau_pm_level {
- u32 memory;
- u32 shader;
- u32 unk05;
-+ u32 unk0a;
-
- u8 voltage;
- u8 fanspeed;
-@@ -463,6 +467,7 @@ struct nouveau_pm_memtiming {
- u32 reg_100234;
- u32 reg_100238;
- u32 reg_10023c;
-+ u32 reg_100240;
- };
-
- struct nouveau_pm_memtimings {
-@@ -509,8 +514,8 @@ struct nouveau_crypt_engine {
- struct nouveau_vram_engine {
- int (*init)(struct drm_device *);
- int (*get)(struct drm_device *, u64, u32 align, u32 size_nc,
-- u32 type, struct nouveau_vram **);
-- void (*put)(struct drm_device *, struct nouveau_vram **);
-+ u32 type, struct nouveau_mem **);
-+ void (*put)(struct drm_device *, struct nouveau_mem **);
-
- bool (*flags_valid)(struct drm_device *, u32 tile_flags);
- };
-@@ -634,6 +639,7 @@ struct drm_nouveau_private {
- enum nouveau_card_type card_type;
- /* exact chipset, derived from NV_PMC_BOOT_0 */
- int chipset;
-+ int stepping;
- int flags;
-
- void __iomem *mmio;
-@@ -652,8 +658,6 @@ struct drm_nouveau_private {
- /* interrupt handling */
- void (*irq_handler[32])(struct drm_device *);
- bool msi_enabled;
-- struct workqueue_struct *wq;
-- struct work_struct irq_work;
-
- struct list_head vbl_waiting;
-
-@@ -681,6 +685,9 @@ struct drm_nouveau_private {
- /* For PFIFO and PGRAPH. */
- spinlock_t context_switch_lock;
-
-+ /* VM/PRAMIN flush, legacy PRAMIN aperture */
-+ spinlock_t vm_lock;
-+
- /* RAMIN configuration, RAMFC, RAMHT and RAMRO offsets */
- struct nouveau_ramht *ramht;
- struct nouveau_gpuobj *ramfc;
-@@ -691,15 +698,22 @@ struct drm_nouveau_private {
- struct {
- enum {
- NOUVEAU_GART_NONE = 0,
-- NOUVEAU_GART_AGP,
-- NOUVEAU_GART_SGDMA
-+ NOUVEAU_GART_AGP, /* AGP */
-+ NOUVEAU_GART_PDMA, /* paged dma object */
-+ NOUVEAU_GART_HW /* on-chip gart/vm */
- } type;
- uint64_t aper_base;
- uint64_t aper_size;
- uint64_t aper_free;
-
-+ struct ttm_backend_func *func;
-+
-+ struct {
-+ struct page *page;
-+ dma_addr_t addr;
-+ } dummy;
-+
- struct nouveau_gpuobj *sg_ctxdma;
-- struct nouveau_vma vma;
- } gart_info;
-
- /* nv10-nv40 tiling regions */
-@@ -740,14 +754,6 @@ struct drm_nouveau_private {
-
- struct backlight_device *backlight;
-
-- struct nouveau_channel *evo;
-- u32 evo_alloc;
-- struct {
-- struct dcb_entry *dcb;
-- u16 script;
-- u32 pclk;
-- } evo_irq;
--
- struct {
- struct dentry *channel_root;
- } debugfs;
-@@ -847,6 +853,7 @@ extern void nv10_mem_put_tile_region(struct drm_device *dev,
- struct nouveau_tile_reg *tile,
- struct nouveau_fence *fence);
- extern const struct ttm_mem_type_manager_func nouveau_vram_manager;
-+extern const struct ttm_mem_type_manager_func nouveau_gart_manager;
-
- /* nouveau_notifier.c */
- extern int nouveau_notifier_init_channel(struct nouveau_channel *);
-@@ -879,17 +886,17 @@ extern void nouveau_channel_ref(struct nouveau_channel *chan,
- extern void nouveau_channel_idle(struct nouveau_channel *chan);
-
- /* nouveau_object.c */
--#define NVOBJ_CLASS(d,c,e) do { \
-+#define NVOBJ_CLASS(d, c, e) do { \
- int ret = nouveau_gpuobj_class_new((d), (c), NVOBJ_ENGINE_##e); \
- if (ret) \
- return ret; \
--} while(0)
-+} while (0)
-
--#define NVOBJ_MTHD(d,c,m,e) do { \
-+#define NVOBJ_MTHD(d, c, m, e) do { \
- int ret = nouveau_gpuobj_mthd_new((d), (c), (m), (e)); \
- if (ret) \
- return ret; \
--} while(0)
-+} while (0)
-
- extern int nouveau_gpuobj_early_init(struct drm_device *);
- extern int nouveau_gpuobj_init(struct drm_device *);
-@@ -899,7 +906,7 @@ extern void nouveau_gpuobj_resume(struct drm_device *dev);
- extern int nouveau_gpuobj_class_new(struct drm_device *, u32 class, u32 eng);
- extern int nouveau_gpuobj_mthd_new(struct drm_device *, u32 class, u32 mthd,
- int (*exec)(struct nouveau_channel *,
-- u32 class, u32 mthd, u32 data));
-+ u32 class, u32 mthd, u32 data));
- extern int nouveau_gpuobj_mthd_call(struct nouveau_channel *, u32, u32, u32);
- extern int nouveau_gpuobj_mthd_call2(struct drm_device *, int, u32, u32, u32);
- extern int nouveau_gpuobj_channel_init(struct nouveau_channel *,
-@@ -1076,7 +1083,7 @@ extern void nv40_fb_set_tile_region(struct drm_device *dev, int
i);
- /* nv50_fb.c */
- extern int nv50_fb_init(struct drm_device *);
- extern void nv50_fb_takedown(struct drm_device *);
--extern void nv50_fb_vm_trap(struct drm_device *, int display, const char *);
-+extern void nv50_fb_vm_trap(struct drm_device *, int display);
-
- /* nvc0_fb.c */
- extern int nvc0_fb_init(struct drm_device *);
-@@ -1189,7 +1196,7 @@ extern int nv50_graph_load_context(struct nouveau_channel *);
- extern int nv50_graph_unload_context(struct drm_device *);
- extern int nv50_grctx_init(struct nouveau_grctx *);
- extern void nv50_graph_tlb_flush(struct drm_device *dev);
--extern void nv86_graph_tlb_flush(struct drm_device *dev);
-+extern void nv84_graph_tlb_flush(struct drm_device *dev);
- extern struct nouveau_enum nv50_data_error_names[];
-
- /* nvc0_graph.c */
-@@ -1295,7 +1302,7 @@ extern struct ttm_bo_driver nouveau_bo_driver;
- extern int nouveau_bo_new(struct drm_device *, struct nouveau_channel *,
- int size, int align, uint32_t flags,
- uint32_t tile_mode, uint32_t tile_flags,
-- bool no_vm, bool mappable, struct nouveau_bo **);
-+ struct nouveau_bo **);
- extern int nouveau_bo_pin(struct nouveau_bo *, uint32_t flags);
- extern int nouveau_bo_unpin(struct nouveau_bo *);
- extern int nouveau_bo_map(struct nouveau_bo *);
-@@ -1356,9 +1363,9 @@ static inline struct nouveau_fence *nouveau_fence_ref(struct
nouveau_fence *obj)
-
- /* nouveau_gem.c */
- extern int nouveau_gem_new(struct drm_device *, struct nouveau_channel *,
-- int size, int align, uint32_t flags,
-+ int size, int align, uint32_t domain,
- uint32_t tile_mode, uint32_t tile_flags,
-- bool no_vm, bool mappable, struct nouveau_bo **);
-+ struct nouveau_bo **);
- extern int nouveau_gem_object_new(struct drm_gem_object *);
- extern void nouveau_gem_object_del(struct drm_gem_object *);
- extern int nouveau_gem_ioctl_new(struct drm_device *, void *,
-@@ -1398,8 +1405,8 @@ bool nv50_gpio_irq_enable(struct drm_device *, enum dcb_gpio_tag,
bool on);
- /* nv50_calc. */
- int nv50_calc_pll(struct drm_device *, struct pll_lims *, int clk,
- int *N1, int *M1, int *N2, int *M2, int *P);
--int nv50_calc_pll2(struct drm_device *, struct pll_lims *,
-- int clk, int *N, int *fN, int *M, int *P);
-+int nva3_calc_pll(struct drm_device *, struct pll_lims *,
-+ int clk, int *N, int *fN, int *M, int *P);
-
- #ifndef ioread32_native
- #ifdef __BIG_ENDIAN
-diff --git a/drivers/gpu/drm/nouveau/nouveau_fb.h b/drivers/gpu/drm/nouveau/nouveau_fb.h
-index d432134..a3a88ad 100644
---- a/drivers/gpu/drm/nouveau/nouveau_fb.h
-+++ b/drivers/gpu/drm/nouveau/nouveau_fb.h
-@@ -30,6 +30,9 @@
- struct nouveau_framebuffer {
- struct drm_framebuffer base;
- struct nouveau_bo *nvbo;
-+ u32 r_dma;
-+ u32 r_format;
-+ u32 r_pitch;
- };
-
- static inline struct nouveau_framebuffer *
-diff --git a/drivers/gpu/drm/nouveau/nouveau_fbcon.c
b/drivers/gpu/drm/nouveau/nouveau_fbcon.c
-index 7826be0..39aee6d 100644
---- a/drivers/gpu/drm/nouveau/nouveau_fbcon.c
-+++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.c
-@@ -296,8 +296,8 @@ nouveau_fbcon_create(struct nouveau_fbdev *nfbdev,
- size = mode_cmd.pitch * mode_cmd.height;
- size = roundup(size, PAGE_SIZE);
-
-- ret = nouveau_gem_new(dev, dev_priv->channel, size, 0, TTM_PL_FLAG_VRAM,
-- 0, 0x0000, false, true, &nvbo);
-+ ret = nouveau_gem_new(dev, dev_priv->channel, size, 0,
-+ NOUVEAU_GEM_DOMAIN_VRAM, 0, 0x0000, &nvbo);
- if (ret) {
- NV_ERROR(dev, "failed to allocate framebuffer\n");
- goto out;
-diff --git a/drivers/gpu/drm/nouveau/nouveau_fence.c
b/drivers/gpu/drm/nouveau/nouveau_fence.c
-index 221b846..4b9f449 100644
---- a/drivers/gpu/drm/nouveau/nouveau_fence.c
-+++ b/drivers/gpu/drm/nouveau/nouveau_fence.c
-@@ -27,13 +27,15 @@
- #include "drmP.h"
- #include "drm.h"
-
-+#include <linux/ktime.h>
-+#include <linux/hrtimer.h>
-+
- #include "nouveau_drv.h"
- #include "nouveau_ramht.h"
- #include "nouveau_dma.h"
-
- #define USE_REFCNT(dev) (nouveau_private(dev)->chipset >= 0x10)
--#define USE_SEMA(dev) (nouveau_private(dev)->chipset >= 0x17 && \
-- nouveau_private(dev)->card_type < NV_C0)
-+#define USE_SEMA(dev) (nouveau_private(dev)->chipset >= 0x17)
-
- struct nouveau_fence {
- struct nouveau_channel *channel;
-@@ -230,7 +232,8 @@ int
- __nouveau_fence_wait(void *sync_obj, void *sync_arg, bool lazy, bool intr)
- {
- unsigned long timeout = jiffies + (3 * DRM_HZ);
-- unsigned long sleep_time = jiffies + 1;
-+ unsigned long sleep_time = NSEC_PER_MSEC / 1000;
-+ ktime_t t;
- int ret = 0;
-
- while (1) {
-@@ -244,8 +247,13 @@ __nouveau_fence_wait(void *sync_obj, void *sync_arg, bool lazy, bool
intr)
-
- __set_current_state(intr ? TASK_INTERRUPTIBLE
- : TASK_UNINTERRUPTIBLE);
-- if (lazy && time_after_eq(jiffies, sleep_time))
-- schedule_timeout(1);
-+ if (lazy) {
-+ t = ktime_set(0, sleep_time);
-+ schedule_hrtimeout(&t, HRTIMER_MODE_REL);
-+ sleep_time *= 2;
-+ if (sleep_time > NSEC_PER_MSEC)
-+ sleep_time = NSEC_PER_MSEC;
-+ }
-
- if (intr && signal_pending(current)) {
- ret = -ERESTARTSYS;
-@@ -259,11 +267,12 @@ __nouveau_fence_wait(void *sync_obj, void *sync_arg, bool lazy,
bool intr)
- }
-
- static struct nouveau_semaphore *
--alloc_semaphore(struct drm_device *dev)
-+semaphore_alloc(struct drm_device *dev)
- {
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_semaphore *sema;
-- int ret;
-+ int size = (dev_priv->chipset < 0x84) ? 4 : 16;
-+ int ret, i;
-
- if (!USE_SEMA(dev))
- return NULL;
-@@ -277,9 +286,9 @@ alloc_semaphore(struct drm_device *dev)
- goto fail;
-
- spin_lock(&dev_priv->fence.lock);
-- sema->mem = drm_mm_search_free(&dev_priv->fence.heap, 4, 0, 0);
-+ sema->mem = drm_mm_search_free(&dev_priv->fence.heap, size, 0, 0);
- if (sema->mem)
-- sema->mem = drm_mm_get_block_atomic(sema->mem, 4, 0);
-+ sema->mem = drm_mm_get_block_atomic(sema->mem, size, 0);
- spin_unlock(&dev_priv->fence.lock);
-
- if (!sema->mem)
-@@ -287,7 +296,8 @@ alloc_semaphore(struct drm_device *dev)
-
- kref_init(&sema->ref);
- sema->dev = dev;
-- nouveau_bo_wr32(dev_priv->fence.bo, sema->mem->start / 4, 0);
-+ for (i = sema->mem->start; i < sema->mem->start + size; i += 4)
-+ nouveau_bo_wr32(dev_priv->fence.bo, i / 4, 0);
-
- return sema;
- fail:
-@@ -296,7 +306,7 @@ fail:
- }
-
- static void
--free_semaphore(struct kref *ref)
-+semaphore_free(struct kref *ref)
- {
- struct nouveau_semaphore *sema =
- container_of(ref, struct nouveau_semaphore, ref);
-@@ -318,61 +328,107 @@ semaphore_work(void *priv, bool signalled)
- if (unlikely(!signalled))
- nouveau_bo_wr32(dev_priv->fence.bo, sema->mem->start / 4, 1);
-
-- kref_put(&sema->ref, free_semaphore);
-+ kref_put(&sema->ref, semaphore_free);
- }
-
- static int
--emit_semaphore(struct nouveau_channel *chan, int method,
-- struct nouveau_semaphore *sema)
-+semaphore_acquire(struct nouveau_channel *chan, struct nouveau_semaphore *sema)
- {
-- struct drm_nouveau_private *dev_priv = sema->dev->dev_private;
-- struct nouveau_fence *fence;
-- bool smart = (dev_priv->card_type >= NV_50);
-+ struct drm_nouveau_private *dev_priv = chan->dev->dev_private;
-+ struct nouveau_fence *fence = NULL;
- int ret;
-
-- ret = RING_SPACE(chan, smart ? 8 : 4);
-+ if (dev_priv->chipset < 0x84) {
-+ ret = RING_SPACE(chan, 3);
-+ if (ret)
-+ return ret;
-+
-+ BEGIN_RING(chan, NvSubSw, NV_SW_SEMAPHORE_OFFSET, 2);
-+ OUT_RING (chan, sema->mem->start);
-+ OUT_RING (chan, 1);
-+ } else
-+ if (dev_priv->chipset < 0xc0) {
-+ struct nouveau_vma *vma = &dev_priv->fence.bo->vma;
-+ u64 offset = vma->offset + sema->mem->start;
-+
-+ ret = RING_SPACE(chan, 5);
-+ if (ret)
-+ return ret;
-+
-+ BEGIN_RING(chan, NvSubSw, 0x0010, 4);
-+ OUT_RING (chan, upper_32_bits(offset));
-+ OUT_RING (chan, lower_32_bits(offset));
-+ OUT_RING (chan, 1);
-+ OUT_RING (chan, 1); /* ACQUIRE_EQ */
-+ } else {
-+ struct nouveau_vma *vma = &dev_priv->fence.bo->vma;
-+ u64 offset = vma->offset + sema->mem->start;
-+
-+ ret = RING_SPACE(chan, 5);
-+ if (ret)
-+ return ret;
-+
-+ BEGIN_NVC0(chan, 2, NvSubM2MF, 0x0010, 4);
-+ OUT_RING (chan, upper_32_bits(offset));
-+ OUT_RING (chan, lower_32_bits(offset));
-+ OUT_RING (chan, 1);
-+ OUT_RING (chan, 0x1001); /* ACQUIRE_EQ */
-+ }
-+
-+ /* Delay semaphore destruction until its work is done */
-+ ret = nouveau_fence_new(chan, &fence, true);
- if (ret)
- return ret;
-
-- if (smart) {
-- BEGIN_RING(chan, NvSubSw, NV_SW_DMA_SEMAPHORE, 1);
-- OUT_RING(chan, NvSema);
-- }
-- BEGIN_RING(chan, NvSubSw, NV_SW_SEMAPHORE_OFFSET, 1);
-- OUT_RING(chan, sema->mem->start);
--
-- if (smart && method == NV_SW_SEMAPHORE_ACQUIRE) {
-- /*
-- * NV50 tries to be too smart and context-switch
-- * between semaphores instead of doing a "first come,
-- * first served" strategy like previous cards
-- * do.
-- *
-- * That's bad because the ACQUIRE latency can get as
-- * large as the PFIFO context time slice in the
-- * typical DRI2 case where you have several
-- * outstanding semaphores at the same moment.
-- *
-- * If we're going to ACQUIRE, force the card to
-- * context switch before, just in case the matching
-- * RELEASE is already scheduled to be executed in
-- * another channel.
-- */
-- BEGIN_RING(chan, NvSubSw, NV_SW_YIELD, 1);
-- OUT_RING(chan, 0);
-- }
-+ kref_get(&sema->ref);
-+ nouveau_fence_work(fence, semaphore_work, sema);
-+ nouveau_fence_unref(&fence);
-+ return 0;
-+}
-+
-+static int
-+semaphore_release(struct nouveau_channel *chan, struct nouveau_semaphore *sema)
-+{
-+ struct drm_nouveau_private *dev_priv = chan->dev->dev_private;
-+ struct nouveau_fence *fence = NULL;
-+ int ret;
-+
-+ if (dev_priv->chipset < 0x84) {
-+ ret = RING_SPACE(chan, 4);
-+ if (ret)
-+ return ret;
-+
-+ BEGIN_RING(chan, NvSubSw, NV_SW_SEMAPHORE_OFFSET, 1);
-+ OUT_RING (chan, sema->mem->start);
-+ BEGIN_RING(chan, NvSubSw, NV_SW_SEMAPHORE_RELEASE, 1);
-+ OUT_RING (chan, 1);
-+ } else
-+ if (dev_priv->chipset < 0xc0) {
-+ struct nouveau_vma *vma = &dev_priv->fence.bo->vma;
-+ u64 offset = vma->offset + sema->mem->start;
-+
-+ ret = RING_SPACE(chan, 5);
-+ if (ret)
-+ return ret;
-+
-+ BEGIN_RING(chan, NvSubSw, 0x0010, 4);
-+ OUT_RING (chan, upper_32_bits(offset));
-+ OUT_RING (chan, lower_32_bits(offset));
-+ OUT_RING (chan, 1);
-+ OUT_RING (chan, 2); /* RELEASE */
-+ } else {
-+ struct nouveau_vma *vma = &dev_priv->fence.bo->vma;
-+ u64 offset = vma->offset + sema->mem->start;
-
-- BEGIN_RING(chan, NvSubSw, method, 1);
-- OUT_RING(chan, 1);
--
-- if (smart && method == NV_SW_SEMAPHORE_RELEASE) {
-- /*
-- * Force the card to context switch, there may be
-- * another channel waiting for the semaphore we just
-- * released.
-- */
-- BEGIN_RING(chan, NvSubSw, NV_SW_YIELD, 1);
-- OUT_RING(chan, 0);
-+ ret = RING_SPACE(chan, 5);
-+ if (ret)
-+ return ret;
-+
-+ BEGIN_NVC0(chan, 2, NvSubM2MF, 0x0010, 4);
-+ OUT_RING (chan, upper_32_bits(offset));
-+ OUT_RING (chan, lower_32_bits(offset));
-+ OUT_RING (chan, 1);
-+ OUT_RING (chan, 0x1002); /* RELEASE */
- }
-
- /* Delay semaphore destruction until its work is done */
-@@ -383,7 +439,6 @@ emit_semaphore(struct nouveau_channel *chan, int method,
- kref_get(&sema->ref);
- nouveau_fence_work(fence, semaphore_work, sema);
- nouveau_fence_unref(&fence);
--
- return 0;
- }
-
-@@ -400,7 +455,7 @@ nouveau_fence_sync(struct nouveau_fence *fence,
- nouveau_fence_signalled(fence)))
- goto out;
-
-- sema = alloc_semaphore(dev);
-+ sema = semaphore_alloc(dev);
- if (!sema) {
- /* Early card or broken userspace, fall back to
- * software sync. */
-@@ -418,17 +473,17 @@ nouveau_fence_sync(struct nouveau_fence *fence,
- }
-
- /* Make wchan wait until it gets signalled */
-- ret = emit_semaphore(wchan, NV_SW_SEMAPHORE_ACQUIRE, sema);
-+ ret = semaphore_acquire(wchan, sema);
- if (ret)
- goto out_unlock;
-
- /* Signal the semaphore from chan */
-- ret = emit_semaphore(chan, NV_SW_SEMAPHORE_RELEASE, sema);
-+ ret = semaphore_release(chan, sema);
-
- out_unlock:
- mutex_unlock(&chan->mutex);
- out_unref:
-- kref_put(&sema->ref, free_semaphore);
-+ kref_put(&sema->ref, semaphore_free);
- out:
- if (chan)
- nouveau_channel_put_unlocked(&chan);
-@@ -449,22 +504,23 @@ nouveau_fence_channel_init(struct nouveau_channel *chan)
- struct nouveau_gpuobj *obj = NULL;
- int ret;
-
-+ if (dev_priv->card_type >= NV_C0)
-+ goto out_initialised;
-+
- /* Create an NV_SW object for various sync purposes */
- ret = nouveau_gpuobj_gr_new(chan, NvSw, NV_SW);
- if (ret)
- return ret;
-
- /* we leave subchannel empty for nvc0 */
-- if (dev_priv->card_type < NV_C0) {
-- ret = RING_SPACE(chan, 2);
-- if (ret)
-- return ret;
-- BEGIN_RING(chan, NvSubSw, 0, 1);
-- OUT_RING(chan, NvSw);
-- }
-+ ret = RING_SPACE(chan, 2);
-+ if (ret)
-+ return ret;
-+ BEGIN_RING(chan, NvSubSw, 0, 1);
-+ OUT_RING(chan, NvSw);
-
- /* Create a DMA object for the shared cross-channel sync area. */
-- if (USE_SEMA(dev)) {
-+ if (USE_SEMA(dev) && dev_priv->chipset < 0x84) {
- struct ttm_mem_reg *mem = &dev_priv->fence.bo->bo.mem;
-
- ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY,
-@@ -484,14 +540,20 @@ nouveau_fence_channel_init(struct nouveau_channel *chan)
- return ret;
- BEGIN_RING(chan, NvSubSw, NV_SW_DMA_SEMAPHORE, 1);
- OUT_RING(chan, NvSema);
-+ } else {
-+ ret = RING_SPACE(chan, 2);
-+ if (ret)
-+ return ret;
-+ BEGIN_RING(chan, NvSubSw, NV_SW_DMA_SEMAPHORE, 1);
-+ OUT_RING (chan, chan->vram_handle); /* whole VM */
- }
-
- FIRE_RING(chan);
-
-+out_initialised:
- INIT_LIST_HEAD(&chan->fence.pending);
- spin_lock_init(&chan->fence.lock);
- atomic_set(&chan->fence.last_sequence_irq, 0);
--
- return 0;
- }
-
-@@ -519,12 +581,13 @@ int
- nouveau_fence_init(struct drm_device *dev)
- {
- struct drm_nouveau_private *dev_priv = dev->dev_private;
-+ int size = (dev_priv->chipset < 0x84) ? 4096 : 16384;
- int ret;
-
- /* Create a shared VRAM heap for cross-channel sync. */
- if (USE_SEMA(dev)) {
-- ret = nouveau_bo_new(dev, NULL, 4096, 0, TTM_PL_FLAG_VRAM,
-- 0, 0, false, true, &dev_priv->fence.bo);
-+ ret = nouveau_bo_new(dev, NULL, size, 0, TTM_PL_FLAG_VRAM,
-+ 0, 0, &dev_priv->fence.bo);
- if (ret)
- return ret;
-
-diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c
b/drivers/gpu/drm/nouveau/nouveau_gem.c
-index 506c508..e8b04f4 100644
---- a/drivers/gpu/drm/nouveau/nouveau_gem.c
-+++ b/drivers/gpu/drm/nouveau/nouveau_gem.c
-@@ -61,19 +61,36 @@ nouveau_gem_object_del(struct drm_gem_object *gem)
-
- int
- nouveau_gem_new(struct drm_device *dev, struct nouveau_channel *chan,
-- int size, int align, uint32_t flags, uint32_t tile_mode,
-- uint32_t tile_flags, bool no_vm, bool mappable,
-- struct nouveau_bo **pnvbo)
-+ int size, int align, uint32_t domain, uint32_t tile_mode,
-+ uint32_t tile_flags, struct nouveau_bo **pnvbo)
- {
-+ struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_bo *nvbo;
-+ u32 flags = 0;
- int ret;
-
-+ if (domain & NOUVEAU_GEM_DOMAIN_VRAM)
-+ flags |= TTM_PL_FLAG_VRAM;
-+ if (domain & NOUVEAU_GEM_DOMAIN_GART)
-+ flags |= TTM_PL_FLAG_TT;
-+ if (!flags || domain & NOUVEAU_GEM_DOMAIN_CPU)
-+ flags |= TTM_PL_FLAG_SYSTEM;
-+
- ret = nouveau_bo_new(dev, chan, size, align, flags, tile_mode,
-- tile_flags, no_vm, mappable, pnvbo);
-+ tile_flags, pnvbo);
- if (ret)
- return ret;
- nvbo = *pnvbo;
-
-+ /* we restrict allowed domains on nv50+ to only the types
-+ * that were requested at creation time. not possibly on
-+ * earlier chips without busting the ABI.
-+ */
-+ nvbo->valid_domains = NOUVEAU_GEM_DOMAIN_VRAM |
-+ NOUVEAU_GEM_DOMAIN_GART;
-+ if (dev_priv->card_type >= NV_50)
-+ nvbo->valid_domains &= domain;
-+
- nvbo->gem = drm_gem_object_alloc(dev, nvbo->bo.mem.size);
- if (!nvbo->gem) {
- nouveau_bo_ref(NULL, pnvbo);
-@@ -97,7 +114,7 @@ nouveau_gem_info(struct drm_gem_object *gem, struct
drm_nouveau_gem_info *rep)
-
- rep->size = nvbo->bo.mem.num_pages << PAGE_SHIFT;
- rep->offset = nvbo->bo.offset;
-- rep->map_handle = nvbo->mappable ? nvbo->bo.addr_space_offset : 0;
-+ rep->map_handle = nvbo->bo.addr_space_offset;
- rep->tile_mode = nvbo->tile_mode;
- rep->tile_flags = nvbo->tile_flags;
- return 0;
-@@ -111,19 +128,11 @@ nouveau_gem_ioctl_new(struct drm_device *dev, void *data,
- struct drm_nouveau_gem_new *req = data;
- struct nouveau_bo *nvbo = NULL;
- struct nouveau_channel *chan = NULL;
-- uint32_t flags = 0;
- int ret = 0;
-
- if (unlikely(dev_priv->ttm.bdev.dev_mapping == NULL))
- dev_priv->ttm.bdev.dev_mapping = dev_priv->dev->dev_mapping;
-
-- if (req->info.domain & NOUVEAU_GEM_DOMAIN_VRAM)
-- flags |= TTM_PL_FLAG_VRAM;
-- if (req->info.domain & NOUVEAU_GEM_DOMAIN_GART)
-- flags |= TTM_PL_FLAG_TT;
-- if (!flags || req->info.domain & NOUVEAU_GEM_DOMAIN_CPU)
-- flags |= TTM_PL_FLAG_SYSTEM;
--
- if (!dev_priv->engine.vram.flags_valid(dev, req->info.tile_flags)) {
- NV_ERROR(dev, "bad page flags: 0x%08x\n", req->info.tile_flags);
- return -EINVAL;
-@@ -135,10 +144,9 @@ nouveau_gem_ioctl_new(struct drm_device *dev, void *data,
- return PTR_ERR(chan);
- }
-
-- ret = nouveau_gem_new(dev, chan, req->info.size, req->align, flags,
-- req->info.tile_mode, req->info.tile_flags, false,
-- (req->info.domain & NOUVEAU_GEM_DOMAIN_MAPPABLE),
-- &nvbo);
-+ ret = nouveau_gem_new(dev, chan, req->info.size, req->align,
-+ req->info.domain, req->info.tile_mode,
-+ req->info.tile_flags, &nvbo);
- if (chan)
- nouveau_channel_put(&chan);
- if (ret)
-@@ -161,7 +169,7 @@ nouveau_gem_set_domain(struct drm_gem_object *gem, uint32_t
read_domains,
- {
- struct nouveau_bo *nvbo = gem->driver_private;
- struct ttm_buffer_object *bo = &nvbo->bo;
-- uint32_t domains = valid_domains &
-+ uint32_t domains = valid_domains & nvbo->valid_domains &
- (write_domains ? write_domains : read_domains);
- uint32_t pref_flags = 0, valid_flags = 0;
-
-@@ -592,7 +600,7 @@ nouveau_gem_ioctl_pushbuf(struct drm_device *dev, void *data,
- if (push[i].bo_index >= req->nr_buffers) {
- NV_ERROR(dev, "push %d buffer not in list\n", i);
- ret = -EINVAL;
-- goto out;
-+ goto out_prevalid;
- }
-
- bo[push[i].bo_index].read_domains |= (1 << 31);
-@@ -604,7 +612,7 @@ nouveau_gem_ioctl_pushbuf(struct drm_device *dev, void *data,
- if (ret) {
- if (ret != -ERESTARTSYS)
- NV_ERROR(dev, "validate: %d\n", ret);
-- goto out;
-+ goto out_prevalid;
- }
-
- /* Apply any relocations that are required */
-@@ -697,6 +705,8 @@ nouveau_gem_ioctl_pushbuf(struct drm_device *dev, void *data,
- out:
- validate_fini(&op, fence);
- nouveau_fence_unref(&fence);
-+
-+out_prevalid:
- kfree(bo);
- kfree(push);
-
-diff --git a/drivers/gpu/drm/nouveau/nouveau_grctx.h
b/drivers/gpu/drm/nouveau/nouveau_grctx.h
-index 4a8ad13..86c2e37 100644
---- a/drivers/gpu/drm/nouveau/nouveau_grctx.h
-+++ b/drivers/gpu/drm/nouveau/nouveau_grctx.h
-@@ -87,10 +87,10 @@ _cp_bra(struct nouveau_grctx *ctx, u32 mod, int flag, int state, int
name)
- cp_out(ctx, CP_BRA | (mod << 18) | ip | flag |
- (state ? 0 : CP_BRA_IF_CLEAR));
- }
--#define cp_bra(c,f,s,n) _cp_bra((c), 0, CP_FLAG_##f, CP_FLAG_##f##_##s, n)
-+#define cp_bra(c, f, s, n) _cp_bra((c), 0, CP_FLAG_##f, CP_FLAG_##f##_##s, n)
- #ifdef CP_BRA_MOD
--#define cp_cal(c,f,s,n) _cp_bra((c), 1, CP_FLAG_##f, CP_FLAG_##f##_##s, n)
--#define cp_ret(c,f,s) _cp_bra((c), 2, CP_FLAG_##f, CP_FLAG_##f##_##s, 0)
-+#define cp_cal(c, f, s, n) _cp_bra((c), 1, CP_FLAG_##f, CP_FLAG_##f##_##s, n)
-+#define cp_ret(c, f, s) _cp_bra((c), 2, CP_FLAG_##f, CP_FLAG_##f##_##s, 0)
- #endif
-
- static inline void
-@@ -98,14 +98,14 @@ _cp_wait(struct nouveau_grctx *ctx, int flag, int state)
- {
- cp_out(ctx, CP_WAIT | flag | (state ? CP_WAIT_SET : 0));
- }
--#define cp_wait(c,f,s) _cp_wait((c), CP_FLAG_##f, CP_FLAG_##f##_##s)
-+#define cp_wait(c, f, s) _cp_wait((c), CP_FLAG_##f, CP_FLAG_##f##_##s)
-
- static inline void
- _cp_set(struct nouveau_grctx *ctx, int flag, int state)
- {
- cp_out(ctx, CP_SET | flag | (state ? CP_SET_1 : 0));
- }
--#define cp_set(c,f,s) _cp_set((c), CP_FLAG_##f, CP_FLAG_##f##_##s)
-+#define cp_set(c, f, s) _cp_set((c), CP_FLAG_##f, CP_FLAG_##f##_##s)
-
- static inline void
- cp_pos(struct nouveau_grctx *ctx, int offset)
-diff --git a/drivers/gpu/drm/nouveau/nouveau_hw.c b/drivers/gpu/drm/nouveau/nouveau_hw.c
-index 053edf9..ba896e5 100644
---- a/drivers/gpu/drm/nouveau/nouveau_hw.c
-+++ b/drivers/gpu/drm/nouveau/nouveau_hw.c
-@@ -900,6 +900,7 @@ nv_save_state_ext(struct drm_device *dev, int head,
- }
- /* NV11 and NV20 don't have this, they stop at 0x52. */
- if (nv_gf4_disp_arch(dev)) {
-+ rd_cio_state(dev, head, regp, NV_CIO_CRE_42);
- rd_cio_state(dev, head, regp, NV_CIO_CRE_53);
- rd_cio_state(dev, head, regp, NV_CIO_CRE_54);
-
-@@ -1003,6 +1004,7 @@ nv_load_state_ext(struct drm_device *dev, int head,
- nouveau_wait_eq(dev, 650000000, NV_PRMCIO_INP0__COLOR, 0x8, 0x0);
- }
-
-+ wr_cio_state(dev, head, regp, NV_CIO_CRE_42);
- wr_cio_state(dev, head, regp, NV_CIO_CRE_53);
- wr_cio_state(dev, head, regp, NV_CIO_CRE_54);
-
-diff --git a/drivers/gpu/drm/nouveau/nouveau_mem.c
b/drivers/gpu/drm/nouveau/nouveau_mem.c
-index b0fb9bd..4942294 100644
---- a/drivers/gpu/drm/nouveau/nouveau_mem.c
-+++ b/drivers/gpu/drm/nouveau/nouveau_mem.c
-@@ -152,9 +152,6 @@ nouveau_mem_vram_fini(struct drm_device *dev)
- {
- struct drm_nouveau_private *dev_priv = dev->dev_private;
-
-- nouveau_bo_unpin(dev_priv->vga_ram);
-- nouveau_bo_ref(NULL, &dev_priv->vga_ram);
--
- ttm_bo_device_release(&dev_priv->ttm.bdev);
-
- nouveau_ttm_global_release(dev_priv);
-@@ -393,11 +390,17 @@ nouveau_mem_vram_init(struct drm_device *dev)
- struct ttm_bo_device *bdev = &dev_priv->ttm.bdev;
- int ret, dma_bits;
-
-- if (dev_priv->card_type >= NV_50 &&
-- pci_dma_supported(dev->pdev, DMA_BIT_MASK(40)))
-- dma_bits = 40;
-- else
-- dma_bits = 32;
-+ dma_bits = 32;
-+ if (dev_priv->card_type >= NV_50) {
-+ if (pci_dma_supported(dev->pdev, DMA_BIT_MASK(40)))
-+ dma_bits = 40;
-+ } else
-+ if (0 && drm_device_is_pcie(dev) &&
-+ dev_priv->chipset > 0x40 &&
-+ dev_priv->chipset != 0x45) {
-+ if (pci_dma_supported(dev->pdev, DMA_BIT_MASK(39)))
-+ dma_bits = 39;
-+ }
-
- ret = pci_set_dma_mask(dev->pdev, DMA_BIT_MASK(dma_bits));
- if (ret)
-@@ -419,14 +422,32 @@ nouveau_mem_vram_init(struct drm_device *dev)
- }
-
- /* reserve space at end of VRAM for PRAMIN */
-- if (dev_priv->chipset == 0x40 || dev_priv->chipset == 0x47 ||
-- dev_priv->chipset == 0x49 || dev_priv->chipset == 0x4b)
-- dev_priv->ramin_rsvd_vram = (2 * 1024 * 1024);
-- else
-- if (dev_priv->card_type >= NV_40)
-- dev_priv->ramin_rsvd_vram = (1 * 1024 * 1024);
-- else
-- dev_priv->ramin_rsvd_vram = (512 * 1024);
-+ if (dev_priv->card_type >= NV_50) {
-+ dev_priv->ramin_rsvd_vram = 1 * 1024 * 1024;
-+ } else
-+ if (dev_priv->card_type >= NV_40) {
-+ u32 vs = hweight8((nv_rd32(dev, 0x001540) & 0x0000ff00) >> 8);
-+ u32 rsvd;
-+
-+ /* estimate grctx size, the magics come from nv40_grctx.c */
-+ if (dev_priv->chipset == 0x40) rsvd = 0x6aa0 * vs;
-+ else if (dev_priv->chipset < 0x43) rsvd = 0x4f00 * vs;
-+ else if (nv44_graph_class(dev)) rsvd = 0x4980 * vs;
-+ else rsvd = 0x4a40 * vs;
-+ rsvd += 16 * 1024;
-+ rsvd *= dev_priv->engine.fifo.channels;
-+
-+ /* pciegart table */
-+ if (drm_device_is_pcie(dev))
-+ rsvd += 512 * 1024;
-+
-+ /* object storage */
-+ rsvd += 512 * 1024;
-+
-+ dev_priv->ramin_rsvd_vram = round_up(rsvd, 4096);
-+ } else {
-+ dev_priv->ramin_rsvd_vram = 512 * 1024;
-+ }
-
- ret = dev_priv->engine.vram.init(dev);
- if (ret)
-@@ -455,13 +476,17 @@ nouveau_mem_vram_init(struct drm_device *dev)
- return ret;
- }
-
-- ret = nouveau_bo_new(dev, NULL, 256*1024, 0, TTM_PL_FLAG_VRAM,
-- 0, 0, true, true, &dev_priv->vga_ram);
-- if (ret == 0)
-- ret = nouveau_bo_pin(dev_priv->vga_ram, TTM_PL_FLAG_VRAM);
-- if (ret) {
-- NV_WARN(dev, "failed to reserve VGA memory\n");
-- nouveau_bo_ref(NULL, &dev_priv->vga_ram);
-+ if (dev_priv->card_type < NV_50) {
-+ ret = nouveau_bo_new(dev, NULL, 256*1024, 0, TTM_PL_FLAG_VRAM,
-+ 0, 0, &dev_priv->vga_ram);
-+ if (ret == 0)
-+ ret = nouveau_bo_pin(dev_priv->vga_ram,
-+ TTM_PL_FLAG_VRAM);
-+
-+ if (ret) {
-+ NV_WARN(dev, "failed to reserve VGA memory\n");
-+ nouveau_bo_ref(NULL, &dev_priv->vga_ram);
-+ }
- }
-
- dev_priv->fb_mtrr = drm_mtrr_add(pci_resource_start(dev->pdev, 1),
-@@ -525,6 +550,7 @@ nouveau_mem_timing_init(struct drm_device *dev)
- u8 tRC; /* Byte 9 */
- u8 tUNK_10, tUNK_11, tUNK_12, tUNK_13, tUNK_14;
- u8 tUNK_18, tUNK_19, tUNK_20, tUNK_21;
-+ u8 magic_number = 0; /* Yeah... sorry*/
- u8 *mem = NULL, *entry;
- int i, recordlen, entries;
-
-@@ -569,6 +595,12 @@ nouveau_mem_timing_init(struct drm_device *dev)
- if (!memtimings->timing)
- return;
-
-+ /* Get "some number" from the timing reg for NV_40 and NV_50
-+ * Used in calculations later */
-+ if (dev_priv->card_type >= NV_40 && dev_priv->chipset < 0x98) {
-+ magic_number = (nv_rd32(dev, 0x100228) & 0x0f000000) >> 24;
-+ }
-+
- entry = mem + mem[1];
- for (i = 0; i < entries; i++, entry += recordlen) {
- struct nouveau_pm_memtiming *timing = &pm->memtimings.timing[i];
-@@ -608,36 +640,67 @@ nouveau_mem_timing_init(struct drm_device *dev)
-
- /* XXX: I don't trust the -1's and +1's... they must come
- * from somewhere! */
-- timing->reg_100224 = ((tUNK_0 + tUNK_19 + 1) << 24 |
-- tUNK_18 << 16 |
-- (tUNK_1 + tUNK_19 + 1) << 8 |
-- (tUNK_2 - 1));
-+ timing->reg_100224 = (tUNK_0 + tUNK_19 + 1 + magic_number) << 24 |
-+ max(tUNK_18, (u8) 1) << 16 |
-+ (tUNK_1 + tUNK_19 + 1 + magic_number) << 8;
-+ if (dev_priv->chipset == 0xa8) {
-+ timing->reg_100224 |= (tUNK_2 - 1);
-+ } else {
-+ timing->reg_100224 |= (tUNK_2 + 2 - magic_number);
-+ }
-
- timing->reg_100228 = (tUNK_12 << 16 | tUNK_11 << 8 | tUNK_10);
-- if(recordlen > 19) {
-- timing->reg_100228 += (tUNK_19 - 1) << 24;
-- }/* I cannot back-up this else-statement right now
-- else {
-- timing->reg_100228 += tUNK_12 << 24;
-- }*/
--
-- /* XXX: reg_10022c */
-- timing->reg_10022c = tUNK_2 - 1;
--
-- timing->reg_100230 = (tUNK_20 << 24 | tUNK_21 << 16 |
-- tUNK_13 << 8 | tUNK_13);
--
-- /* XXX: +6? */
-- timing->reg_100234 = (tRAS << 24 | (tUNK_19 + 6) << 8 | tRC);
-- timing->reg_100234 += max(tUNK_10,tUNK_11) << 16;
--
-- /* XXX; reg_100238, reg_10023c
-- * reg: 0x00??????
-- * reg_10023c:
-- * 0 for pre-NV50 cards
-- * 0x????0202 for NV50+ cards (empirical evidence) */
-- if(dev_priv->card_type >= NV_50) {
-+ if (dev_priv->chipset >= 0xa3 && dev_priv->chipset < 0xaa)
-+ timing->reg_100228 |= (tUNK_19 - 1) << 24;
-+ else
-+ timing->reg_100228 |= magic_number << 24;
-+
-+ if (dev_priv->card_type == NV_40) {
-+ /* NV40: don't know what the rest of the regs are..
-+ * And don't need to know either */
-+ timing->reg_100228 |= 0x20200000;
-+ } else if (dev_priv->card_type >= NV_50) {
-+ if (dev_priv->chipset < 0x98 ||
-+ (dev_priv->chipset == 0x98 &&
-+ dev_priv->stepping <= 0xa1)) {
-+ timing->reg_10022c = (0x14 + tUNK_2) << 24 |
-+ 0x16 << 16 |
-+ (tUNK_2 - 1) << 8 |
-+ (tUNK_2 - 1);
-+ } else {
-+ /* XXX: reg_10022c for recentish cards */
-+ timing->reg_10022c = tUNK_2 - 1;
-+ }
-+
-+ timing->reg_100230 = (tUNK_20 << 24 | tUNK_21 << 16 |
-+ tUNK_13 << 8 | tUNK_13);
-+
-+ timing->reg_100234 = (tRAS << 24 | tRC);
-+ timing->reg_100234 += max(tUNK_10, tUNK_11) << 16;
-+
-+ if (dev_priv->chipset < 0x98 ||
-+ (dev_priv->chipset == 0x98 &&
-+ dev_priv->stepping <= 0xa1)) {
-+ timing->reg_100234 |= (tUNK_2 + 2) << 8;
-+ } else {
-+ /* XXX: +6? */
-+ timing->reg_100234 |= (tUNK_19 + 6) << 8;
-+ }
-+
-+ /* XXX; reg_100238
-+ * reg_100238: 0x00?????? */
- timing->reg_10023c = 0x202;
-+ if (dev_priv->chipset < 0x98 ||
-+ (dev_priv->chipset == 0x98 &&
-+ dev_priv->stepping <= 0xa1)) {
-+ timing->reg_10023c |= 0x4000000 | (tUNK_2 - 1) << 16;
-+ } else {
-+ /* XXX: reg_10023c
-+ * currently unknown
-+ * 10023c seen as 06xxxxxx, 0bxxxxxx or 0fxxxxxx */
-+ }
-+
-+ /* XXX: reg_100240? */
- }
-
- NV_DEBUG(dev, "Entry %d: 220: %08x %08x %08x %08x\n", i,
-@@ -646,9 +709,10 @@ nouveau_mem_timing_init(struct drm_device *dev)
- NV_DEBUG(dev, " 230: %08x %08x %08x %08x\n",
- timing->reg_100230, timing->reg_100234,
- timing->reg_100238, timing->reg_10023c);
-+ NV_DEBUG(dev, " 240: %08x\n", timing->reg_100240);
- }
-
-- memtimings->nr_timing = entries;
-+ memtimings->nr_timing = entries;
- memtimings->supported = true;
- }
-
-@@ -666,13 +730,14 @@ nouveau_vram_manager_init(struct ttm_mem_type_manager *man,
unsigned long p_size
- {
- struct drm_nouveau_private *dev_priv = nouveau_bdev(man->bdev);
- struct nouveau_mm *mm;
-- u32 b_size;
-+ u64 size, block, rsvd;
- int ret;
-
-- p_size = (p_size << PAGE_SHIFT) >> 12;
-- b_size = dev_priv->vram_rblock_size >> 12;
-+ rsvd = (256 * 1024); /* vga memory */
-+ size = (p_size << PAGE_SHIFT) - rsvd;
-+ block = dev_priv->vram_rblock_size;
-
-- ret = nouveau_mm_init(&mm, 0, p_size, b_size);
-+ ret = nouveau_mm_init(&mm, rsvd >> 12, size >> 12, block >> 12);
- if (ret)
- return ret;
-
-@@ -700,9 +765,15 @@ nouveau_vram_manager_del(struct ttm_mem_type_manager *man,
- {
- struct drm_nouveau_private *dev_priv = nouveau_bdev(man->bdev);
- struct nouveau_vram_engine *vram = &dev_priv->engine.vram;
-+ struct nouveau_mem *node = mem->mm_node;
- struct drm_device *dev = dev_priv->dev;
-
-- vram->put(dev, (struct nouveau_vram **)&mem->mm_node);
-+ if (node->tmp_vma.node) {
-+ nouveau_vm_unmap(&node->tmp_vma);
-+ nouveau_vm_put(&node->tmp_vma);
-+ }
-+
-+ vram->put(dev, (struct nouveau_mem **)&mem->mm_node);
- }
-
- static int
-@@ -715,7 +786,7 @@ nouveau_vram_manager_new(struct ttm_mem_type_manager *man,
- struct nouveau_vram_engine *vram = &dev_priv->engine.vram;
- struct drm_device *dev = dev_priv->dev;
- struct nouveau_bo *nvbo = nouveau_bo(bo);
-- struct nouveau_vram *node;
-+ struct nouveau_mem *node;
- u32 size_nc = 0;
- int ret;
-
-@@ -724,7 +795,7 @@ nouveau_vram_manager_new(struct ttm_mem_type_manager *man,
-
- ret = vram->get(dev, mem->num_pages << PAGE_SHIFT,
- mem->page_alignment << PAGE_SHIFT, size_nc,
-- (nvbo->tile_flags >> 8) & 0xff, &node);
-+ (nvbo->tile_flags >> 8) & 0x3ff, &node);
- if (ret) {
- mem->mm_node = NULL;
- return (ret == -ENOSPC) ? 0 : ret;
-@@ -771,3 +842,84 @@ const struct ttm_mem_type_manager_func nouveau_vram_manager = {
- nouveau_vram_manager_del,
- nouveau_vram_manager_debug
- };
-+
-+static int
-+nouveau_gart_manager_init(struct ttm_mem_type_manager *man, unsigned long psize)
-+{
-+ return 0;
-+}
-+
-+static int
-+nouveau_gart_manager_fini(struct ttm_mem_type_manager *man)
-+{
-+ return 0;
-+}
-+
-+static void
-+nouveau_gart_manager_del(struct ttm_mem_type_manager *man,
-+ struct ttm_mem_reg *mem)
-+{
-+ struct nouveau_mem *node = mem->mm_node;
-+
-+ if (node->tmp_vma.node) {
-+ nouveau_vm_unmap(&node->tmp_vma);
-+ nouveau_vm_put(&node->tmp_vma);
-+ }
-+ mem->mm_node = NULL;
-+}
-+
-+static int
-+nouveau_gart_manager_new(struct ttm_mem_type_manager *man,
-+ struct ttm_buffer_object *bo,
-+ struct ttm_placement *placement,
-+ struct ttm_mem_reg *mem)
-+{
-+ struct drm_nouveau_private *dev_priv = nouveau_bdev(bo->bdev);
-+ struct nouveau_bo *nvbo = nouveau_bo(bo);
-+ struct nouveau_vma *vma = &nvbo->vma;
-+ struct nouveau_vm *vm = vma->vm;
-+ struct nouveau_mem *node;
-+ int ret;
-+
-+ if (unlikely((mem->num_pages << PAGE_SHIFT) >=
-+ dev_priv->gart_info.aper_size))
-+ return -ENOMEM;
-+
-+ node = kzalloc(sizeof(*node), GFP_KERNEL);
-+ if (!node)
-+ return -ENOMEM;
-+
-+ /* This node must be for evicting large-paged VRAM
-+ * to system memory. Due to a nv50 limitation of
-+ * not being able to mix large/small pages within
-+ * the same PDE, we need to create a temporary
-+ * small-paged VMA for the eviction.
-+ */
-+ if (vma->node->type != vm->spg_shift) {
-+ ret = nouveau_vm_get(vm, (u64)vma->node->length << 12,
-+ vm->spg_shift, NV_MEM_ACCESS_RW,
-+ &node->tmp_vma);
-+ if (ret) {
-+ kfree(node);
-+ return ret;
-+ }
-+ }
-+
-+ node->page_shift = nvbo->vma.node->type;
-+ mem->mm_node = node;
-+ mem->start = 0;
-+ return 0;
-+}
-+
-+void
-+nouveau_gart_manager_debug(struct ttm_mem_type_manager *man, const char *prefix)
-+{
-+}
-+
-+const struct ttm_mem_type_manager_func nouveau_gart_manager = {
-+ nouveau_gart_manager_init,
-+ nouveau_gart_manager_fini,
-+ nouveau_gart_manager_new,
-+ nouveau_gart_manager_del,
-+ nouveau_gart_manager_debug
-+};
-diff --git a/drivers/gpu/drm/nouveau/nouveau_mm.h b/drivers/gpu/drm/nouveau/nouveau_mm.h
-index 798eaf3..1f7483a 100644
---- a/drivers/gpu/drm/nouveau/nouveau_mm.h
-+++ b/drivers/gpu/drm/nouveau/nouveau_mm.h
-@@ -53,13 +53,13 @@ void nouveau_mm_put(struct nouveau_mm *, struct nouveau_mm_node *);
-
- int nv50_vram_init(struct drm_device *);
- int nv50_vram_new(struct drm_device *, u64 size, u32 align, u32 size_nc,
-- u32 memtype, struct nouveau_vram **);
--void nv50_vram_del(struct drm_device *, struct nouveau_vram **);
-+ u32 memtype, struct nouveau_mem **);
-+void nv50_vram_del(struct drm_device *, struct nouveau_mem **);
- bool nv50_vram_flags_valid(struct drm_device *, u32 tile_flags);
-
- int nvc0_vram_init(struct drm_device *);
- int nvc0_vram_new(struct drm_device *, u64 size, u32 align, u32 ncmin,
-- u32 memtype, struct nouveau_vram **);
-+ u32 memtype, struct nouveau_mem **);
- bool nvc0_vram_flags_valid(struct drm_device *, u32 tile_flags);
-
- #endif
-diff --git a/drivers/gpu/drm/nouveau/nouveau_notifier.c
b/drivers/gpu/drm/nouveau/nouveau_notifier.c
-index 5ea1676..5b39718 100644
---- a/drivers/gpu/drm/nouveau/nouveau_notifier.c
-+++ b/drivers/gpu/drm/nouveau/nouveau_notifier.c
-@@ -35,20 +35,22 @@ nouveau_notifier_init_channel(struct nouveau_channel *chan)
- {
- struct drm_device *dev = chan->dev;
- struct nouveau_bo *ntfy = NULL;
-- uint32_t flags;
-+ uint32_t flags, ttmpl;
- int ret;
-
-- if (nouveau_vram_notify)
-- flags = TTM_PL_FLAG_VRAM;
-- else
-- flags = TTM_PL_FLAG_TT;
-+ if (nouveau_vram_notify) {
-+ flags = NOUVEAU_GEM_DOMAIN_VRAM;
-+ ttmpl = TTM_PL_FLAG_VRAM;
-+ } else {
-+ flags = NOUVEAU_GEM_DOMAIN_GART;
-+ ttmpl = TTM_PL_FLAG_TT;
-+ }
-
-- ret = nouveau_gem_new(dev, NULL, PAGE_SIZE, 0, flags,
-- 0, 0x0000, false, true, &ntfy);
-+ ret = nouveau_gem_new(dev, NULL, PAGE_SIZE, 0, flags, 0, 0, &ntfy);
- if (ret)
- return ret;
-
-- ret = nouveau_bo_pin(ntfy, flags);
-+ ret = nouveau_bo_pin(ntfy, ttmpl);
- if (ret)
- goto out_err;
-
-@@ -100,6 +102,7 @@ nouveau_notifier_alloc(struct nouveau_channel *chan, uint32_t
handle,
- uint32_t *b_offset)
- {
- struct drm_device *dev = chan->dev;
-+ struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_gpuobj *nobj = NULL;
- struct drm_mm_node *mem;
- uint32_t offset;
-@@ -114,11 +117,16 @@ nouveau_notifier_alloc(struct nouveau_channel *chan, uint32_t
handle,
- return -ENOMEM;
- }
-
-- if (chan->notifier_bo->bo.mem.mem_type == TTM_PL_VRAM)
-- target = NV_MEM_TARGET_VRAM;
-- else
-- target = NV_MEM_TARGET_GART;
-- offset = chan->notifier_bo->bo.mem.start << PAGE_SHIFT;
-+ if (dev_priv->card_type < NV_50) {
-+ if (chan->notifier_bo->bo.mem.mem_type == TTM_PL_VRAM)
-+ target = NV_MEM_TARGET_VRAM;
-+ else
-+ target = NV_MEM_TARGET_GART;
-+ offset = chan->notifier_bo->bo.mem.start << PAGE_SHIFT;
-+ } else {
-+ target = NV_MEM_TARGET_VM;
-+ offset = chan->notifier_bo->vma.offset;
-+ }
- offset += mem->start;
-
- ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY, offset,
-diff --git a/drivers/gpu/drm/nouveau/nouveau_object.c
b/drivers/gpu/drm/nouveau/nouveau_object.c
-index 30b6544..59b446e 100644
---- a/drivers/gpu/drm/nouveau/nouveau_object.c
-+++ b/drivers/gpu/drm/nouveau/nouveau_object.c
-@@ -36,6 +36,7 @@
- #include "nouveau_drm.h"
- #include "nouveau_ramht.h"
- #include "nouveau_vm.h"
-+#include "nv50_display.h"
-
- struct nouveau_gpuobj_method {
- struct list_head head;
-@@ -490,16 +491,22 @@ nouveau_gpuobj_dma_new(struct nouveau_channel *chan, int class, u64
base,
- }
-
- if (target == NV_MEM_TARGET_GART) {
-- if (dev_priv->gart_info.type == NOUVEAU_GART_AGP) {
-- target = NV_MEM_TARGET_PCI_NOSNOOP;
-- base += dev_priv->gart_info.aper_base;
-- } else
-- if (base != 0) {
-- base = nouveau_sgdma_get_physical(dev, base);
-+ struct nouveau_gpuobj *gart = dev_priv->gart_info.sg_ctxdma;
-+
-+ if (dev_priv->gart_info.type == NOUVEAU_GART_PDMA) {
-+ if (base == 0) {
-+ nouveau_gpuobj_ref(gart, pobj);
-+ return 0;
-+ }
-+
-+ base = nouveau_sgdma_get_physical(dev, base);
- target = NV_MEM_TARGET_PCI;
- } else {
-- nouveau_gpuobj_ref(dev_priv->gart_info.sg_ctxdma, pobj);
-- return 0;
-+ base += dev_priv->gart_info.aper_base;
-+ if (dev_priv->gart_info.type == NOUVEAU_GART_AGP)
-+ target = NV_MEM_TARGET_PCI_NOSNOOP;
-+ else
-+ target = NV_MEM_TARGET_PCI;
- }
- }
-
-@@ -776,7 +783,7 @@ nouveau_gpuobj_channel_init(struct nouveau_channel *chan,
- struct drm_device *dev = chan->dev;
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_gpuobj *vram = NULL, *tt = NULL;
-- int ret;
-+ int ret, i;
-
- NV_DEBUG(dev, "ch%d vram=0x%08x tt=0x%08x\n", chan->id, vram_h, tt_h);
-
-@@ -841,6 +848,25 @@ nouveau_gpuobj_channel_init(struct nouveau_channel *chan,
- nouveau_gpuobj_ref(NULL, &ramht);
- if (ret)
- return ret;
-+
-+ /* dma objects for display sync channel semaphore blocks */
-+ for (i = 0; i < 2; i++) {
-+ struct nouveau_gpuobj *sem = NULL;
-+ struct nv50_display_crtc *dispc =
-+ &nv50_display(dev)->crtc[i];
-+ u64 offset = dispc->sem.bo->bo.mem.start << PAGE_SHIFT;
-+
-+ ret = nouveau_gpuobj_dma_new(chan, 0x3d, offset, 0xfff,
-+ NV_MEM_ACCESS_RW,
-+ NV_MEM_TARGET_VRAM, &sem);
-+ if (ret)
-+ return ret;
-+
-+ ret = nouveau_ramht_insert(chan, NvEvoSema0 + i, sem);
-+ nouveau_gpuobj_ref(NULL, &sem);
-+ if (ret)
-+ return ret;
-+ }
- }
-
- /* VRAM ctxdma */
-@@ -1013,19 +1039,20 @@ nv_ro32(struct nouveau_gpuobj *gpuobj, u32 offset)
- {
- struct drm_nouveau_private *dev_priv = gpuobj->dev->dev_private;
- struct drm_device *dev = gpuobj->dev;
-+ unsigned long flags;
-
- if (gpuobj->pinst == ~0 || !dev_priv->ramin_available) {
- u64 ptr = gpuobj->vinst + offset;
- u32 base = ptr >> 16;
- u32 val;
-
-- spin_lock(&dev_priv->ramin_lock);
-+ spin_lock_irqsave(&dev_priv->vm_lock, flags);
- if (dev_priv->ramin_base != base) {
- dev_priv->ramin_base = base;
- nv_wr32(dev, 0x001700, dev_priv->ramin_base);
- }
- val = nv_rd32(dev, 0x700000 + (ptr & 0xffff));
-- spin_unlock(&dev_priv->ramin_lock);
-+ spin_unlock_irqrestore(&dev_priv->vm_lock, flags);
- return val;
- }
-
-@@ -1037,18 +1064,19 @@ nv_wo32(struct nouveau_gpuobj *gpuobj, u32 offset, u32 val)
- {
- struct drm_nouveau_private *dev_priv = gpuobj->dev->dev_private;
- struct drm_device *dev = gpuobj->dev;
-+ unsigned long flags;
-
- if (gpuobj->pinst == ~0 || !dev_priv->ramin_available) {
- u64 ptr = gpuobj->vinst + offset;
- u32 base = ptr >> 16;
-
-- spin_lock(&dev_priv->ramin_lock);
-+ spin_lock_irqsave(&dev_priv->vm_lock, flags);
- if (dev_priv->ramin_base != base) {
- dev_priv->ramin_base = base;
- nv_wr32(dev, 0x001700, dev_priv->ramin_base);
- }
- nv_wr32(dev, 0x700000 + (ptr & 0xffff), val);
-- spin_unlock(&dev_priv->ramin_lock);
-+ spin_unlock_irqrestore(&dev_priv->vm_lock, flags);
- return;
- }
-
-diff --git a/drivers/gpu/drm/nouveau/nouveau_perf.c
b/drivers/gpu/drm/nouveau/nouveau_perf.c
-index ac62a1b..3045566 100644
---- a/drivers/gpu/drm/nouveau/nouveau_perf.c
-+++ b/drivers/gpu/drm/nouveau/nouveau_perf.c
-@@ -134,7 +134,7 @@ nouveau_perf_init(struct drm_device *dev)
- case 0x13:
- case 0x15:
- perflvl->fanspeed = entry[55];
-- perflvl->voltage = entry[56];
-+ perflvl->voltage = (recordlen > 56) ? entry[56] : 0;
- perflvl->core = ROM32(entry[1]) * 10;
- perflvl->memory = ROM32(entry[5]) * 20;
- break;
-@@ -174,9 +174,21 @@ nouveau_perf_init(struct drm_device *dev)
- #define subent(n) entry[perf[2] + ((n) * perf[3])]
- perflvl->fanspeed = 0; /*XXX*/
- perflvl->voltage = entry[2];
-- perflvl->core = (ROM16(subent(0)) & 0xfff) * 1000;
-- perflvl->shader = (ROM16(subent(1)) & 0xfff) * 1000;
-- perflvl->memory = (ROM16(subent(2)) & 0xfff) * 1000;
-+ if (dev_priv->card_type == NV_50) {
-+ perflvl->core = ROM16(subent(0)) & 0xfff;
-+ perflvl->shader = ROM16(subent(1)) & 0xfff;
-+ perflvl->memory = ROM16(subent(2)) & 0xfff;
-+ } else {
-+ perflvl->shader = ROM16(subent(3)) & 0xfff;
-+ perflvl->core = perflvl->shader / 2;
-+ perflvl->unk0a = ROM16(subent(4)) & 0xfff;
-+ perflvl->memory = ROM16(subent(5)) & 0xfff;
-+ }
-+
-+ perflvl->core *= 1000;
-+ perflvl->shader *= 1000;
-+ perflvl->memory *= 1000;
-+ perflvl->unk0a *= 1000;
- break;
- }
-
-diff --git a/drivers/gpu/drm/nouveau/nouveau_pm.c b/drivers/gpu/drm/nouveau/nouveau_pm.c
-index 4399e2f..0b1caeb 100644
---- a/drivers/gpu/drm/nouveau/nouveau_pm.c
-+++ b/drivers/gpu/drm/nouveau/nouveau_pm.c
-@@ -490,6 +490,7 @@ nouveau_pm_init(struct drm_device *dev)
- /* determine current ("boot") performance level */
- ret = nouveau_pm_perflvl_get(dev, &pm->boot);
- if (ret == 0) {
-+ strncpy(pm->boot.name, "boot", 4);
- pm->cur = &pm->boot;
-
- nouveau_pm_perflvl_info(&pm->boot, info, sizeof(info));
-diff --git a/drivers/gpu/drm/nouveau/nouveau_ramht.c
b/drivers/gpu/drm/nouveau/nouveau_ramht.c
-index bef3e69..a24a81f 100644
---- a/drivers/gpu/drm/nouveau/nouveau_ramht.c
-+++ b/drivers/gpu/drm/nouveau/nouveau_ramht.c
-@@ -114,7 +114,9 @@ nouveau_ramht_insert(struct nouveau_channel *chan, u32 handle,
- (gpuobj->engine << NV40_RAMHT_CONTEXT_ENGINE_SHIFT);
- } else {
- if (gpuobj->engine == NVOBJ_ENGINE_DISPLAY) {
-- ctx = (gpuobj->cinst << 10) | chan->id;
-+ ctx = (gpuobj->cinst << 10) |
-+ (chan->id << 28) |
-+ chan->id; /* HASH_TAG */
- } else {
- ctx = (gpuobj->cinst >> 4) |
- ((gpuobj->engine <<
-diff --git a/drivers/gpu/drm/nouveau/nouveau_reg.h
b/drivers/gpu/drm/nouveau/nouveau_reg.h
-index 04e8fb7..f18cdfc 100644
---- a/drivers/gpu/drm/nouveau/nouveau_reg.h
-+++ b/drivers/gpu/drm/nouveau/nouveau_reg.h
-@@ -639,9 +639,9 @@
- # define NV50_PCONNECTOR_I2C_PORT_4 0x0000e240
- # define NV50_PCONNECTOR_I2C_PORT_5 0x0000e258
-
--#define NV50_AUXCH_DATA_OUT(i,n) ((n) * 4 + (i) * 0x50 + 0x0000e4c0)
-+#define NV50_AUXCH_DATA_OUT(i, n) ((n) * 4 + (i) * 0x50 + 0x0000e4c0)
- #define NV50_AUXCH_DATA_OUT__SIZE 4
--#define NV50_AUXCH_DATA_IN(i,n) ((n) * 4 + (i) * 0x50 + 0x0000e4d0)
-+#define NV50_AUXCH_DATA_IN(i, n) ((n) * 4 + (i) * 0x50 + 0x0000e4d0)
- #define NV50_AUXCH_DATA_IN__SIZE 4
- #define NV50_AUXCH_ADDR(i) ((i) * 0x50 + 0x0000e4e0)
- #define NV50_AUXCH_CTRL(i) ((i) * 0x50 + 0x0000e4e4)
-@@ -829,7 +829,7 @@
- #define NV50_PDISPLAY_SOR_BACKLIGHT 0x0061c084
- #define NV50_PDISPLAY_SOR_BACKLIGHT_ENABLE 0x80000000
- #define NV50_PDISPLAY_SOR_BACKLIGHT_LEVEL 0x00000fff
--#define NV50_SOR_DP_CTRL(i,l) (0x0061c10c + (i) * 0x800 + (l) * 0x80)
-+#define NV50_SOR_DP_CTRL(i, l) (0x0061c10c + (i) * 0x800 + (l) * 0x80)
- #define NV50_SOR_DP_CTRL_ENABLED 0x00000001
- #define NV50_SOR_DP_CTRL_ENHANCED_FRAME_ENABLED 0x00004000
- #define NV50_SOR_DP_CTRL_LANE_MASK 0x001f0000
-@@ -841,10 +841,10 @@
- #define NV50_SOR_DP_CTRL_TRAINING_PATTERN_DISABLED 0x00000000
- #define NV50_SOR_DP_CTRL_TRAINING_PATTERN_1 0x01000000
- #define NV50_SOR_DP_CTRL_TRAINING_PATTERN_2 0x02000000
--#define NV50_SOR_DP_UNK118(i,l) (0x0061c118 + (i) * 0x800 + (l) * 0x80)
--#define NV50_SOR_DP_UNK120(i,l) (0x0061c120 + (i) * 0x800 + (l) * 0x80)
--#define NV50_SOR_DP_UNK128(i,l) (0x0061c128 + (i) * 0x800 + (l) * 0x80)
--#define NV50_SOR_DP_UNK130(i,l) (0x0061c130 + (i) * 0x800 + (l) * 0x80)
-+#define NV50_SOR_DP_UNK118(i, l) (0x0061c118 + (i) * 0x800 + (l) * 0x80)
-+#define NV50_SOR_DP_UNK120(i, l) (0x0061c120 + (i) * 0x800 + (l) * 0x80)
-+#define NV50_SOR_DP_UNK128(i, l) (0x0061c128 + (i) * 0x800 + (l) * 0x80)
-+#define NV50_SOR_DP_UNK130(i, l) (0x0061c130 + (i) * 0x800 + (l) * 0x80)
-
- #define NV50_PDISPLAY_USER(i) ((i) * 0x1000 + 0x00640000)
- #define NV50_PDISPLAY_USER_PUT(i) ((i) * 0x1000 + 0x00640000)
-diff --git a/drivers/gpu/drm/nouveau/nouveau_sgdma.c
b/drivers/gpu/drm/nouveau/nouveau_sgdma.c
-index 9a250eb..2bf9686 100644
---- a/drivers/gpu/drm/nouveau/nouveau_sgdma.c
-+++ b/drivers/gpu/drm/nouveau/nouveau_sgdma.c
-@@ -74,8 +74,24 @@ nouveau_sgdma_clear(struct ttm_backend *be)
- }
- }
-
-+static void
-+nouveau_sgdma_destroy(struct ttm_backend *be)
-+{
-+ struct nouveau_sgdma_be *nvbe = (struct nouveau_sgdma_be *)be;
-+
-+ if (be) {
-+ NV_DEBUG(nvbe->dev, "\n");
-+
-+ if (nvbe) {
-+ if (nvbe->pages)
-+ be->func->clear(be);
-+ kfree(nvbe);
-+ }
-+ }
-+}
-+
- static int
--nouveau_sgdma_bind(struct ttm_backend *be, struct ttm_mem_reg *mem)
-+nv04_sgdma_bind(struct ttm_backend *be, struct ttm_mem_reg *mem)
- {
- struct nouveau_sgdma_be *nvbe = (struct nouveau_sgdma_be *)be;
- struct drm_device *dev = nvbe->dev;
-@@ -102,7 +118,7 @@ nouveau_sgdma_bind(struct ttm_backend *be, struct ttm_mem_reg *mem)
- }
-
- static int
--nouveau_sgdma_unbind(struct ttm_backend *be)
-+nv04_sgdma_unbind(struct ttm_backend *be)
- {
- struct nouveau_sgdma_be *nvbe = (struct nouveau_sgdma_be *)be;
- struct drm_device *dev = nvbe->dev;
-@@ -125,59 +141,245 @@ nouveau_sgdma_unbind(struct ttm_backend *be)
- return 0;
- }
-
-+static struct ttm_backend_func nv04_sgdma_backend = {
-+ .populate = nouveau_sgdma_populate,
-+ .clear = nouveau_sgdma_clear,
-+ .bind = nv04_sgdma_bind,
-+ .unbind = nv04_sgdma_unbind,
-+ .destroy = nouveau_sgdma_destroy
-+};
-+
- static void
--nouveau_sgdma_destroy(struct ttm_backend *be)
-+nv41_sgdma_flush(struct nouveau_sgdma_be *nvbe)
-+{
-+ struct drm_device *dev = nvbe->dev;
-+
-+ nv_wr32(dev, 0x100810, 0x00000022);
-+ if (!nv_wait(dev, 0x100810, 0x00000100, 0x00000100))
-+ NV_ERROR(dev, "vm flush timeout: 0x%08x\n",
-+ nv_rd32(dev, 0x100810));
-+ nv_wr32(dev, 0x100810, 0x00000000);
-+}
-+
-+static int
-+nv41_sgdma_bind(struct ttm_backend *be, struct ttm_mem_reg *mem)
- {
- struct nouveau_sgdma_be *nvbe = (struct nouveau_sgdma_be *)be;
-+ struct drm_nouveau_private *dev_priv = nvbe->dev->dev_private;
-+ struct nouveau_gpuobj *pgt = dev_priv->gart_info.sg_ctxdma;
-+ dma_addr_t *list = nvbe->pages;
-+ u32 pte = mem->start << 2;
-+ u32 cnt = nvbe->nr_pages;
-
-- if (be) {
-- NV_DEBUG(nvbe->dev, "\n");
-+ nvbe->offset = mem->start << PAGE_SHIFT;
-
-- if (nvbe) {
-- if (nvbe->pages)
-- be->func->clear(be);
-- kfree(nvbe);
-+ while (cnt--) {
-+ nv_wo32(pgt, pte, (*list++ >> 7) | 1);
-+ pte += 4;
-+ }
-+
-+ nv41_sgdma_flush(nvbe);
-+ nvbe->bound = true;
-+ return 0;
-+}
-+
-+static int
-+nv41_sgdma_unbind(struct ttm_backend *be)
-+{
-+ struct nouveau_sgdma_be *nvbe = (struct nouveau_sgdma_be *)be;
-+ struct drm_nouveau_private *dev_priv = nvbe->dev->dev_private;
-+ struct nouveau_gpuobj *pgt = dev_priv->gart_info.sg_ctxdma;
-+ u32 pte = (nvbe->offset >> 12) << 2;
-+ u32 cnt = nvbe->nr_pages;
-+
-+ while (cnt--) {
-+ nv_wo32(pgt, pte, 0x00000000);
-+ pte += 4;
-+ }
-+
-+ nv41_sgdma_flush(nvbe);
-+ nvbe->bound = false;
-+ return 0;
-+}
-+
-+static struct ttm_backend_func nv41_sgdma_backend = {
-+ .populate = nouveau_sgdma_populate,
-+ .clear = nouveau_sgdma_clear,
-+ .bind = nv41_sgdma_bind,
-+ .unbind = nv41_sgdma_unbind,
-+ .destroy = nouveau_sgdma_destroy
-+};
-+
-+static void
-+nv44_sgdma_flush(struct nouveau_sgdma_be *nvbe)
-+{
-+ struct drm_device *dev = nvbe->dev;
-+
-+ nv_wr32(dev, 0x100814, (nvbe->nr_pages - 1) << 12);
-+ nv_wr32(dev, 0x100808, nvbe->offset | 0x20);
-+ if (!nv_wait(dev, 0x100808, 0x00000001, 0x00000001))
-+ NV_ERROR(dev, "gart flush timeout: 0x%08x\n",
-+ nv_rd32(dev, 0x100808));
-+ nv_wr32(dev, 0x100808, 0x00000000);
-+}
-+
-+static void
-+nv44_sgdma_fill(struct nouveau_gpuobj *pgt, dma_addr_t *list, u32 base, u32 cnt)
-+{
-+ struct drm_nouveau_private *dev_priv = pgt->dev->dev_private;
-+ dma_addr_t dummy = dev_priv->gart_info.dummy.addr;
-+ u32 pte, tmp[4];
-+
-+ pte = base >> 2;
-+ base &= ~0x0000000f;
-+
-+ tmp[0] = nv_ro32(pgt, base + 0x0);
-+ tmp[1] = nv_ro32(pgt, base + 0x4);
-+ tmp[2] = nv_ro32(pgt, base + 0x8);
-+ tmp[3] = nv_ro32(pgt, base + 0xc);
-+ while (cnt--) {
-+ u32 addr = list ? (*list++ >> 12) : (dummy >> 12);
-+ switch (pte++ & 0x3) {
-+ case 0:
-+ tmp[0] &= ~0x07ffffff;
-+ tmp[0] |= addr;
-+ break;
-+ case 1:
-+ tmp[0] &= ~0xf8000000;
-+ tmp[0] |= addr << 27;
-+ tmp[1] &= ~0x003fffff;
-+ tmp[1] |= addr >> 5;
-+ break;
-+ case 2:
-+ tmp[1] &= ~0xffc00000;
-+ tmp[1] |= addr << 22;
-+ tmp[2] &= ~0x0001ffff;
-+ tmp[2] |= addr >> 10;
-+ break;
-+ case 3:
-+ tmp[2] &= ~0xfffe0000;
-+ tmp[2] |= addr << 17;
-+ tmp[3] &= ~0x00000fff;
-+ tmp[3] |= addr >> 15;
-+ break;
- }
- }
-+
-+ tmp[3] |= 0x40000000;
-+
-+ nv_wo32(pgt, base + 0x0, tmp[0]);
-+ nv_wo32(pgt, base + 0x4, tmp[1]);
-+ nv_wo32(pgt, base + 0x8, tmp[2]);
-+ nv_wo32(pgt, base + 0xc, tmp[3]);
- }
-
- static int
--nv50_sgdma_bind(struct ttm_backend *be, struct ttm_mem_reg *mem)
-+nv44_sgdma_bind(struct ttm_backend *be, struct ttm_mem_reg *mem)
- {
- struct nouveau_sgdma_be *nvbe = (struct nouveau_sgdma_be *)be;
- struct drm_nouveau_private *dev_priv = nvbe->dev->dev_private;
-+ struct nouveau_gpuobj *pgt = dev_priv->gart_info.sg_ctxdma;
-+ dma_addr_t *list = nvbe->pages;
-+ u32 pte = mem->start << 2, tmp[4];
-+ u32 cnt = nvbe->nr_pages;
-+ int i;
-
- nvbe->offset = mem->start << PAGE_SHIFT;
-
-- nouveau_vm_map_sg(&dev_priv->gart_info.vma, nvbe->offset,
-- nvbe->nr_pages << PAGE_SHIFT, nvbe->pages);
-+ if (pte & 0x0000000c) {
-+ u32 max = 4 - ((pte >> 2) & 0x3);
-+ u32 part = (cnt > max) ? max : cnt;
-+ nv44_sgdma_fill(pgt, list, pte, part);
-+ pte += (part << 2);
-+ list += part;
-+ cnt -= part;
-+ }
-+
-+ while (cnt >= 4) {
-+ for (i = 0; i < 4; i++)
-+ tmp[i] = *list++ >> 12;
-+ nv_wo32(pgt, pte + 0x0, tmp[0] >> 0 | tmp[1] << 27);
-+ nv_wo32(pgt, pte + 0x4, tmp[1] >> 5 | tmp[2] << 22);
-+ nv_wo32(pgt, pte + 0x8, tmp[2] >> 10 | tmp[3] << 17);
-+ nv_wo32(pgt, pte + 0xc, tmp[3] >> 15 | 0x40000000);
-+ pte += 0x10;
-+ cnt -= 4;
-+ }
-+
-+ if (cnt)
-+ nv44_sgdma_fill(pgt, list, pte, cnt);
-+
-+ nv44_sgdma_flush(nvbe);
- nvbe->bound = true;
- return 0;
- }
-
- static int
--nv50_sgdma_unbind(struct ttm_backend *be)
-+nv44_sgdma_unbind(struct ttm_backend *be)
- {
- struct nouveau_sgdma_be *nvbe = (struct nouveau_sgdma_be *)be;
- struct drm_nouveau_private *dev_priv = nvbe->dev->dev_private;
-+ struct nouveau_gpuobj *pgt = dev_priv->gart_info.sg_ctxdma;
-+ u32 pte = (nvbe->offset >> 12) << 2;
-+ u32 cnt = nvbe->nr_pages;
-+
-+ if (pte & 0x0000000c) {
-+ u32 max = 4 - ((pte >> 2) & 0x3);
-+ u32 part = (cnt > max) ? max : cnt;
-+ nv44_sgdma_fill(pgt, NULL, pte, part);
-+ pte += (part << 2);
-+ cnt -= part;
-+ }
-
-- if (!nvbe->bound)
-- return 0;
-+ while (cnt >= 4) {
-+ nv_wo32(pgt, pte + 0x0, 0x00000000);
-+ nv_wo32(pgt, pte + 0x4, 0x00000000);
-+ nv_wo32(pgt, pte + 0x8, 0x00000000);
-+ nv_wo32(pgt, pte + 0xc, 0x00000000);
-+ pte += 0x10;
-+ cnt -= 4;
-+ }
-
-- nouveau_vm_unmap_at(&dev_priv->gart_info.vma, nvbe->offset,
-- nvbe->nr_pages << PAGE_SHIFT);
-+ if (cnt)
-+ nv44_sgdma_fill(pgt, NULL, pte, cnt);
-+
-+ nv44_sgdma_flush(nvbe);
- nvbe->bound = false;
- return 0;
- }
-
--static struct ttm_backend_func nouveau_sgdma_backend = {
-+static struct ttm_backend_func nv44_sgdma_backend = {
- .populate = nouveau_sgdma_populate,
- .clear = nouveau_sgdma_clear,
-- .bind = nouveau_sgdma_bind,
-- .unbind = nouveau_sgdma_unbind,
-+ .bind = nv44_sgdma_bind,
-+ .unbind = nv44_sgdma_unbind,
- .destroy = nouveau_sgdma_destroy
- };
-
-+static int
-+nv50_sgdma_bind(struct ttm_backend *be, struct ttm_mem_reg *mem)
-+{
-+ struct nouveau_sgdma_be *nvbe = (struct nouveau_sgdma_be *)be;
-+ struct nouveau_mem *node = mem->mm_node;
-+ /* noop: bound in move_notify() */
-+ node->pages = nvbe->pages;
-+ nvbe->pages = (dma_addr_t *)node;
-+ nvbe->bound = true;
-+ return 0;
-+}
-+
-+static int
-+nv50_sgdma_unbind(struct ttm_backend *be)
-+{
-+ struct nouveau_sgdma_be *nvbe = (struct nouveau_sgdma_be *)be;
-+ struct nouveau_mem *node = (struct nouveau_mem *)nvbe->pages;
-+ /* noop: unbound in move_notify() */
-+ nvbe->pages = node->pages;
-+ node->pages = NULL;
-+ nvbe->bound = false;
-+ return 0;
-+}
-+
- static struct ttm_backend_func nv50_sgdma_backend = {
- .populate = nouveau_sgdma_populate,
- .clear = nouveau_sgdma_clear,
-@@ -198,10 +400,7 @@ nouveau_sgdma_init_ttm(struct drm_device *dev)
-
- nvbe->dev = dev;
-
-- if (dev_priv->card_type < NV_50)
-- nvbe->backend.func = &nouveau_sgdma_backend;
-- else
-- nvbe->backend.func = &nv50_sgdma_backend;
-+ nvbe->backend.func = dev_priv->gart_info.func;
- return &nvbe->backend;
- }
-
-@@ -210,21 +409,64 @@ nouveau_sgdma_init(struct drm_device *dev)
- {
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_gpuobj *gpuobj = NULL;
-- uint32_t aper_size, obj_size;
-- int i, ret;
-+ u32 aper_size, align;
-+ int ret;
-
-- if (dev_priv->card_type < NV_50) {
-- if(dev_priv->ramin_rsvd_vram < 2 * 1024 * 1024)
-- aper_size = 64 * 1024 * 1024;
-- else
-- aper_size = 512 * 1024 * 1024;
-+ if (dev_priv->card_type >= NV_40 && drm_device_is_pcie(dev))
-+ aper_size = 512 * 1024 * 1024;
-+ else
-+ aper_size = 64 * 1024 * 1024;
-+
-+ /* Dear NVIDIA, NV44+ would like proper present bits in PTEs for
-+ * christmas. The cards before it have them, the cards after
-+ * it have them, why is NV44 so unloved?
-+ */
-+ dev_priv->gart_info.dummy.page = alloc_page(GFP_DMA32 | GFP_KERNEL);
-+ if (!dev_priv->gart_info.dummy.page)
-+ return -ENOMEM;
-
-- obj_size = (aper_size >> NV_CTXDMA_PAGE_SHIFT) * 4;
-- obj_size += 8; /* ctxdma header */
-+ dev_priv->gart_info.dummy.addr =
-+ pci_map_page(dev->pdev, dev_priv->gart_info.dummy.page,
-+ 0, PAGE_SIZE, PCI_DMA_BIDIRECTIONAL);
-+ if (pci_dma_mapping_error(dev->pdev, dev_priv->gart_info.dummy.addr)) {
-+ NV_ERROR(dev, "error mapping dummy page\n");
-+ __free_page(dev_priv->gart_info.dummy.page);
-+ dev_priv->gart_info.dummy.page = NULL;
-+ return -ENOMEM;
-+ }
-
-- ret = nouveau_gpuobj_new(dev, NULL, obj_size, 16,
-- NVOBJ_FLAG_ZERO_ALLOC |
-- NVOBJ_FLAG_ZERO_FREE, &gpuobj);
-+ if (dev_priv->card_type >= NV_50) {
-+ dev_priv->gart_info.aper_base = 0;
-+ dev_priv->gart_info.aper_size = aper_size;
-+ dev_priv->gart_info.type = NOUVEAU_GART_HW;
-+ dev_priv->gart_info.func = &nv50_sgdma_backend;
-+ } else
-+ if (0 && drm_device_is_pcie(dev) &&
-+ dev_priv->chipset > 0x40 && dev_priv->chipset != 0x45) {
-+ if (nv44_graph_class(dev)) {
-+ dev_priv->gart_info.func = &nv44_sgdma_backend;
-+ align = 512 * 1024;
-+ } else {
-+ dev_priv->gart_info.func = &nv41_sgdma_backend;
-+ align = 16;
-+ }
-+
-+ ret = nouveau_gpuobj_new(dev, NULL, aper_size / 1024, align,
-+ NVOBJ_FLAG_ZERO_ALLOC |
-+ NVOBJ_FLAG_ZERO_FREE, &gpuobj);
-+ if (ret) {
-+ NV_ERROR(dev, "Error creating sgdma object: %d\n", ret);
-+ return ret;
-+ }
-+
-+ dev_priv->gart_info.sg_ctxdma = gpuobj;
-+ dev_priv->gart_info.aper_base = 0;
-+ dev_priv->gart_info.aper_size = aper_size;
-+ dev_priv->gart_info.type = NOUVEAU_GART_HW;
-+ } else {
-+ ret = nouveau_gpuobj_new(dev, NULL, (aper_size / 1024) + 8, 16,
-+ NVOBJ_FLAG_ZERO_ALLOC |
-+ NVOBJ_FLAG_ZERO_FREE, &gpuobj);
- if (ret) {
- NV_ERROR(dev, "Error creating sgdma object: %d\n", ret);
- return ret;
-@@ -236,25 +478,14 @@ nouveau_sgdma_init(struct drm_device *dev)
- (0 << 14) /* RW */ |
- (2 << 16) /* PCI */);
- nv_wo32(gpuobj, 4, aper_size - 1);
-- for (i = 2; i < 2 + (aper_size >> 12); i++)
-- nv_wo32(gpuobj, i * 4, 0x00000000);
-
- dev_priv->gart_info.sg_ctxdma = gpuobj;
- dev_priv->gart_info.aper_base = 0;
- dev_priv->gart_info.aper_size = aper_size;
-- } else
-- if (dev_priv->chan_vm) {
-- ret = nouveau_vm_get(dev_priv->chan_vm, 512 * 1024 * 1024,
-- 12, NV_MEM_ACCESS_RW,
-- &dev_priv->gart_info.vma);
-- if (ret)
-- return ret;
--
-- dev_priv->gart_info.aper_base = dev_priv->gart_info.vma.offset;
-- dev_priv->gart_info.aper_size = 512 * 1024 * 1024;
-+ dev_priv->gart_info.type = NOUVEAU_GART_PDMA;
-+ dev_priv->gart_info.func = &nv04_sgdma_backend;
- }
-
-- dev_priv->gart_info.type = NOUVEAU_GART_SGDMA;
- return 0;
- }
-
-@@ -264,7 +495,13 @@ nouveau_sgdma_takedown(struct drm_device *dev)
- struct drm_nouveau_private *dev_priv = dev->dev_private;
-
- nouveau_gpuobj_ref(NULL, &dev_priv->gart_info.sg_ctxdma);
-- nouveau_vm_put(&dev_priv->gart_info.vma);
-+
-+ if (dev_priv->gart_info.dummy.page) {
-+ pci_unmap_page(dev->pdev, dev_priv->gart_info.dummy.addr,
-+ PAGE_SIZE, PCI_DMA_BIDIRECTIONAL);
-+ __free_page(dev_priv->gart_info.dummy.page);
-+ dev_priv->gart_info.dummy.page = NULL;
-+ }
- }
-
- uint32_t
-diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c
b/drivers/gpu/drm/nouveau/nouveau_state.c
-index a54fc43..adf6dac 100644
---- a/drivers/gpu/drm/nouveau/nouveau_state.c
-+++ b/drivers/gpu/drm/nouveau/nouveau_state.c
-@@ -376,15 +376,11 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
- engine->graph.destroy_context = nv50_graph_destroy_context;
- engine->graph.load_context = nv50_graph_load_context;
- engine->graph.unload_context = nv50_graph_unload_context;
-- if (dev_priv->chipset != 0x86)
-+ if (dev_priv->chipset == 0x50 ||
-+ dev_priv->chipset == 0xac)
- engine->graph.tlb_flush = nv50_graph_tlb_flush;
-- else {
-- /* from what i can see nvidia do this on every
-- * pre-NVA3 board except NVAC, but, we've only
-- * ever seen problems on NV86
-- */
-- engine->graph.tlb_flush = nv86_graph_tlb_flush;
-- }
-+ else
-+ engine->graph.tlb_flush = nv84_graph_tlb_flush;
- engine->fifo.channels = 128;
- engine->fifo.init = nv50_fifo_init;
- engine->fifo.takedown = nv50_fifo_takedown;
-@@ -513,6 +509,7 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
- engine->vram.get = nvc0_vram_new;
- engine->vram.put = nv50_vram_del;
- engine->vram.flags_valid = nvc0_vram_flags_valid;
-+ engine->pm.temp_get = nv84_temp_get;
- break;
- default:
- NV_ERROR(dev, "NV%02x unsupported\n", dev_priv->chipset);
-@@ -544,7 +541,6 @@ static int
- nouveau_card_init_channel(struct drm_device *dev)
- {
- struct drm_nouveau_private *dev_priv = dev->dev_private;
-- struct nouveau_gpuobj *gpuobj = NULL;
- int ret;
-
- ret = nouveau_channel_alloc(dev, &dev_priv->channel,
-@@ -552,41 +548,8 @@ nouveau_card_init_channel(struct drm_device *dev)
- if (ret)
- return ret;
-
-- /* no dma objects on fermi... */
-- if (dev_priv->card_type >= NV_C0)
-- goto out_done;
--
-- ret = nouveau_gpuobj_dma_new(dev_priv->channel, NV_CLASS_DMA_IN_MEMORY,
-- 0, dev_priv->vram_size,
-- NV_MEM_ACCESS_RW, NV_MEM_TARGET_VRAM,
-- &gpuobj);
-- if (ret)
-- goto out_err;
--
-- ret = nouveau_ramht_insert(dev_priv->channel, NvDmaVRAM, gpuobj);
-- nouveau_gpuobj_ref(NULL, &gpuobj);
-- if (ret)
-- goto out_err;
--
-- ret = nouveau_gpuobj_dma_new(dev_priv->channel, NV_CLASS_DMA_IN_MEMORY,
-- 0, dev_priv->gart_info.aper_size,
-- NV_MEM_ACCESS_RW, NV_MEM_TARGET_GART,
-- &gpuobj);
-- if (ret)
-- goto out_err;
--
-- ret = nouveau_ramht_insert(dev_priv->channel, NvDmaGART, gpuobj);
-- nouveau_gpuobj_ref(NULL, &gpuobj);
-- if (ret)
-- goto out_err;
--
--out_done:
- mutex_unlock(&dev_priv->channel->mutex);
- return 0;
--
--out_err:
-- nouveau_channel_put(&dev_priv->channel);
-- return ret;
- }
-
- static void nouveau_switcheroo_set_state(struct pci_dev *pdev,
-@@ -646,6 +609,7 @@ nouveau_card_init(struct drm_device *dev)
- spin_lock_init(&dev_priv->channels.lock);
- spin_lock_init(&dev_priv->tile.lock);
- spin_lock_init(&dev_priv->context_switch_lock);
-+ spin_lock_init(&dev_priv->vm_lock);
-
- /* Make the CRTCs and I2C buses accessible */
- ret = engine->display.early_init(dev);
-@@ -811,6 +775,11 @@ static void nouveau_card_takedown(struct drm_device *dev)
- engine->mc.takedown(dev);
- engine->display.late_takedown(dev);
-
-+ if (dev_priv->vga_ram) {
-+ nouveau_bo_unpin(dev_priv->vga_ram);
-+ nouveau_bo_ref(NULL, &dev_priv->vga_ram);
-+ }
-+
- mutex_lock(&dev->struct_mutex);
- ttm_bo_clean_mm(&dev_priv->ttm.bdev, TTM_PL_VRAM);
- ttm_bo_clean_mm(&dev_priv->ttm.bdev, TTM_PL_TT);
-@@ -904,7 +873,7 @@ static int nouveau_remove_conflicting_drivers(struct drm_device
*dev)
- #ifdef CONFIG_X86
- primary = dev->pdev->resource[PCI_ROM_RESOURCE].flags &
IORESOURCE_ROM_SHADOW;
- #endif
--
-+
- remove_conflicting_framebuffers(dev_priv->apertures, "nouveaufb",
primary);
- return 0;
- }
-@@ -929,12 +898,6 @@ int nouveau_load(struct drm_device *dev, unsigned long flags)
- NV_DEBUG(dev, "vendor: 0x%X device: 0x%X class: 0x%X\n",
- dev->pci_vendor, dev->pci_device, dev->pdev->class);
-
-- dev_priv->wq = create_workqueue("nouveau");
-- if (!dev_priv->wq) {
-- ret = -EINVAL;
-- goto err_priv;
-- }
--
- /* resource 0 is mmio regs */
- /* resource 1 is linear FB */
- /* resource 2 is RAMIN (mmio regs + 0x1000000) */
-@@ -947,7 +910,7 @@ int nouveau_load(struct drm_device *dev, unsigned long flags)
- NV_ERROR(dev, "Unable to initialize the mmio mapping. "
- "Please report your setup to " DRIVER_EMAIL "\n");
- ret = -EINVAL;
-- goto err_wq;
-+ goto err_priv;
- }
- NV_DEBUG(dev, "regs mapped ok at 0x%llx\n",
- (unsigned long long)mmio_start_offs);
-@@ -962,11 +925,13 @@ int nouveau_load(struct drm_device *dev, unsigned long flags)
-
- /* Time to determine the card architecture */
- reg0 = nv_rd32(dev, NV03_PMC_BOOT_0);
-+ dev_priv->stepping = 0; /* XXX: add stepping for pre-NV10? */
-
- /* We're dealing with >=NV10 */
- if ((reg0 & 0x0f000000) > 0) {
- /* Bit 27-20 contain the architecture in hex */
- dev_priv->chipset = (reg0 & 0xff00000) >> 20;
-+ dev_priv->stepping = (reg0 & 0xff);
- /* NV04 or NV05 */
- } else if ((reg0 & 0xff00fff0) == 0x20004000) {
- if (reg0 & 0x00f00000)
-@@ -1054,8 +1019,6 @@ err_ramin:
- iounmap(dev_priv->ramin);
- err_mmio:
- iounmap(dev_priv->mmio);
--err_wq:
-- destroy_workqueue(dev_priv->wq);
- err_priv:
- kfree(dev_priv);
- dev->dev_private = NULL;
-@@ -1126,7 +1089,7 @@ int nouveau_ioctl_getparam(struct drm_device *dev, void *data,
- getparam->value = 1;
- break;
- case NOUVEAU_GETPARAM_HAS_PAGEFLIP:
-- getparam->value = (dev_priv->card_type < NV_50);
-+ getparam->value = 1;
- break;
- case NOUVEAU_GETPARAM_GRAPH_UNITS:
- /* NV40 and NV50 versions are quite different, but register
-diff --git a/drivers/gpu/drm/nouveau/nouveau_temp.c
b/drivers/gpu/drm/nouveau/nouveau_temp.c
-index 8d9968e..649b041 100644
---- a/drivers/gpu/drm/nouveau/nouveau_temp.c
-+++ b/drivers/gpu/drm/nouveau/nouveau_temp.c
-@@ -239,11 +239,9 @@ static bool
- probe_monitoring_device(struct nouveau_i2c_chan *i2c,
- struct i2c_board_info *info)
- {
-- char modalias[16] = "i2c:";
- struct i2c_client *client;
-
-- strlcat(modalias, info->type, sizeof(modalias));
-- request_module(modalias);
-+ request_module("%s%s", I2C_MODULE_PREFIX, info->type);
-
- client = i2c_new_device(&i2c->adapter, info);
- if (!client)
-diff --git a/drivers/gpu/drm/nouveau/nouveau_util.c
b/drivers/gpu/drm/nouveau/nouveau_util.c
-index fbe0fb1..e51b515 100644
---- a/drivers/gpu/drm/nouveau/nouveau_util.c
-+++ b/drivers/gpu/drm/nouveau/nouveau_util.c
-@@ -47,18 +47,27 @@ nouveau_bitfield_print(const struct nouveau_bitfield *bf, u32 value)
- printk(" (unknown bits 0x%08x)", value);
- }
-
--void
--nouveau_enum_print(const struct nouveau_enum *en, u32 value)
-+const struct nouveau_enum *
-+nouveau_enum_find(const struct nouveau_enum *en, u32 value)
- {
- while (en->name) {
-- if (value == en->value) {
-- printk("%s", en->name);
-- return;
-- }
--
-+ if (en->value == value)
-+ return en;
- en++;
- }
-
-+ return NULL;
-+}
-+
-+void
-+nouveau_enum_print(const struct nouveau_enum *en, u32 value)
-+{
-+ en = nouveau_enum_find(en, value);
-+ if (en) {
-+ printk("%s", en->name);
-+ return;
-+ }
-+
- printk("(unknown enum 0x%08x)", value);
- }
-
-diff --git a/drivers/gpu/drm/nouveau/nouveau_util.h
b/drivers/gpu/drm/nouveau/nouveau_util.h
-index d9ceaea..b97719f 100644
---- a/drivers/gpu/drm/nouveau/nouveau_util.h
-+++ b/drivers/gpu/drm/nouveau/nouveau_util.h
-@@ -36,10 +36,14 @@ struct nouveau_bitfield {
- struct nouveau_enum {
- u32 value;
- const char *name;
-+ void *data;
- };
-
- void nouveau_bitfield_print(const struct nouveau_bitfield *, u32 value);
- void nouveau_enum_print(const struct nouveau_enum *, u32 value);
-+const struct nouveau_enum *
-+nouveau_enum_find(const struct nouveau_enum *, u32 value);
-+
- int nouveau_ratelimit(void);
-
- #endif
-diff --git a/drivers/gpu/drm/nouveau/nouveau_vm.c b/drivers/gpu/drm/nouveau/nouveau_vm.c
-index 97d82ae..0059e6f 100644
---- a/drivers/gpu/drm/nouveau/nouveau_vm.c
-+++ b/drivers/gpu/drm/nouveau/nouveau_vm.c
-@@ -28,7 +28,7 @@
- #include "nouveau_vm.h"
-
- void
--nouveau_vm_map_at(struct nouveau_vma *vma, u64 delta, struct nouveau_vram *vram)
-+nouveau_vm_map_at(struct nouveau_vma *vma, u64 delta, struct nouveau_mem *node)
- {
- struct nouveau_vm *vm = vma->vm;
- struct nouveau_mm_node *r;
-@@ -40,7 +40,8 @@ nouveau_vm_map_at(struct nouveau_vma *vma, u64 delta, struct
nouveau_vram *vram)
- u32 max = 1 << (vm->pgt_bits - bits);
- u32 end, len;
-
-- list_for_each_entry(r, &vram->regions, rl_entry) {
-+ delta = 0;
-+ list_for_each_entry(r, &node->regions, rl_entry) {
- u64 phys = (u64)r->offset << 12;
- u32 num = r->length >> bits;
-
-@@ -52,7 +53,7 @@ nouveau_vm_map_at(struct nouveau_vma *vma, u64 delta, struct
nouveau_vram *vram)
- end = max;
- len = end - pte;
-
-- vm->map(vma, pgt, vram, pte, len, phys);
-+ vm->map(vma, pgt, node, pte, len, phys, delta);
-
- num -= len;
- pte += len;
-@@ -60,6 +61,8 @@ nouveau_vm_map_at(struct nouveau_vma *vma, u64 delta, struct
nouveau_vram *vram)
- pde++;
- pte = 0;
- }
-+
-+ delta += (u64)len << vma->node->type;
- }
- }
-
-@@ -67,14 +70,14 @@ nouveau_vm_map_at(struct nouveau_vma *vma, u64 delta, struct
nouveau_vram *vram)
- }
-
- void
--nouveau_vm_map(struct nouveau_vma *vma, struct nouveau_vram *vram)
-+nouveau_vm_map(struct nouveau_vma *vma, struct nouveau_mem *node)
- {
-- nouveau_vm_map_at(vma, 0, vram);
-+ nouveau_vm_map_at(vma, 0, node);
- }
-
- void
- nouveau_vm_map_sg(struct nouveau_vma *vma, u64 delta, u64 length,
-- dma_addr_t *list)
-+ struct nouveau_mem *mem, dma_addr_t *list)
- {
- struct nouveau_vm *vm = vma->vm;
- int big = vma->node->type != vm->spg_shift;
-@@ -94,7 +97,7 @@ nouveau_vm_map_sg(struct nouveau_vma *vma, u64 delta, u64 length,
- end = max;
- len = end - pte;
-
-- vm->map_sg(vma, pgt, pte, list, len);
-+ vm->map_sg(vma, pgt, mem, pte, len, list);
-
- num -= len;
- pte += len;
-@@ -311,18 +314,7 @@ nouveau_vm_new(struct drm_device *dev, u64 offset, u64 length, u64
mm_offset,
- vm->spg_shift = 12;
- vm->lpg_shift = 17;
- pgt_bits = 27;
--
-- /* Should be 4096 everywhere, this is a hack that's
-- * currently necessary to avoid an elusive bug that
-- * causes corruption when mixing small/large pages
-- */
-- if (length < (1ULL << 40))
-- block = 4096;
-- else {
-- block = (1 << pgt_bits);
-- if (length < block)
-- block = length;
-- }
-+ block = 4096;
- } else {
- kfree(vm);
- return -ENOSYS;
-diff --git a/drivers/gpu/drm/nouveau/nouveau_vm.h b/drivers/gpu/drm/nouveau/nouveau_vm.h
-index e119351..2e06b55 100644
---- a/drivers/gpu/drm/nouveau/nouveau_vm.h
-+++ b/drivers/gpu/drm/nouveau/nouveau_vm.h
-@@ -67,9 +67,10 @@ struct nouveau_vm {
- void (*map_pgt)(struct nouveau_gpuobj *pgd, u32 pde,
- struct nouveau_gpuobj *pgt[2]);
- void (*map)(struct nouveau_vma *, struct nouveau_gpuobj *,
-- struct nouveau_vram *, u32 pte, u32 cnt, u64 phys);
-+ struct nouveau_mem *, u32 pte, u32 cnt,
-+ u64 phys, u64 delta);
- void (*map_sg)(struct nouveau_vma *, struct nouveau_gpuobj *,
-- u32 pte, dma_addr_t *, u32 cnt);
-+ struct nouveau_mem *, u32 pte, u32 cnt, dma_addr_t *);
- void (*unmap)(struct nouveau_gpuobj *pgt, u32 pte, u32 cnt);
- void (*flush)(struct nouveau_vm *);
- };
-@@ -82,20 +83,20 @@ int nouveau_vm_ref(struct nouveau_vm *, struct nouveau_vm **,
- int nouveau_vm_get(struct nouveau_vm *, u64 size, u32 page_shift,
- u32 access, struct nouveau_vma *);
- void nouveau_vm_put(struct nouveau_vma *);
--void nouveau_vm_map(struct nouveau_vma *, struct nouveau_vram *);
--void nouveau_vm_map_at(struct nouveau_vma *, u64 offset, struct nouveau_vram *);
-+void nouveau_vm_map(struct nouveau_vma *, struct nouveau_mem *);
-+void nouveau_vm_map_at(struct nouveau_vma *, u64 offset, struct nouveau_mem *);
- void nouveau_vm_unmap(struct nouveau_vma *);
- void nouveau_vm_unmap_at(struct nouveau_vma *, u64 offset, u64 length);
- void nouveau_vm_map_sg(struct nouveau_vma *, u64 offset, u64 length,
-- dma_addr_t *);
-+ struct nouveau_mem *, dma_addr_t *);
-
- /* nv50_vm.c */
- void nv50_vm_map_pgt(struct nouveau_gpuobj *pgd, u32 pde,
- struct nouveau_gpuobj *pgt[2]);
- void nv50_vm_map(struct nouveau_vma *, struct nouveau_gpuobj *,
-- struct nouveau_vram *, u32 pte, u32 cnt, u64 phys);
-+ struct nouveau_mem *, u32 pte, u32 cnt, u64 phys, u64 delta);
- void nv50_vm_map_sg(struct nouveau_vma *, struct nouveau_gpuobj *,
-- u32 pte, dma_addr_t *, u32 cnt);
-+ struct nouveau_mem *, u32 pte, u32 cnt, dma_addr_t *);
- void nv50_vm_unmap(struct nouveau_gpuobj *, u32 pte, u32 cnt);
- void nv50_vm_flush(struct nouveau_vm *);
- void nv50_vm_flush_engine(struct drm_device *, int engine);
-@@ -104,9 +105,9 @@ void nv50_vm_flush_engine(struct drm_device *, int engine);
- void nvc0_vm_map_pgt(struct nouveau_gpuobj *pgd, u32 pde,
- struct nouveau_gpuobj *pgt[2]);
- void nvc0_vm_map(struct nouveau_vma *, struct nouveau_gpuobj *,
-- struct nouveau_vram *, u32 pte, u32 cnt, u64 phys);
-+ struct nouveau_mem *, u32 pte, u32 cnt, u64 phys, u64 delta);
- void nvc0_vm_map_sg(struct nouveau_vma *, struct nouveau_gpuobj *,
-- u32 pte, dma_addr_t *, u32 cnt);
-+ struct nouveau_mem *, u32 pte, u32 cnt, dma_addr_t *);
- void nvc0_vm_unmap(struct nouveau_gpuobj *, u32 pte, u32 cnt);
- void nvc0_vm_flush(struct nouveau_vm *);
-
-diff --git a/drivers/gpu/drm/nouveau/nouveau_volt.c
b/drivers/gpu/drm/nouveau/nouveau_volt.c
-index 04fdc00..75e87274 100644
---- a/drivers/gpu/drm/nouveau/nouveau_volt.c
-+++ b/drivers/gpu/drm/nouveau/nouveau_volt.c
-@@ -159,8 +159,16 @@ nouveau_volt_init(struct drm_device *dev)
- headerlen = volt[1];
- recordlen = volt[2];
- entries = volt[3];
-- vidshift = hweight8(volt[5]);
- vidmask = volt[4];
-+ /* no longer certain what volt[5] is, if it's related to
-+ * the vid shift then it's definitely not a function of
-+ * how many bits are set.
-+ *
-+ * after looking at a number of nva3+ vbios images, they
-+ * all seem likely to have a static shift of 2.. lets
-+ * go with that for now until proven otherwise.
-+ */
-+ vidshift = 2;
- break;
- default:
- NV_WARN(dev, "voltage table 0x%02x unknown\n", volt[0]);
-diff --git a/drivers/gpu/drm/nouveau/nv04_crtc.c b/drivers/gpu/drm/nouveau/nv04_crtc.c
-index 297505e..9eaafcc 100644
---- a/drivers/gpu/drm/nouveau/nv04_crtc.c
-+++ b/drivers/gpu/drm/nouveau/nv04_crtc.c
-@@ -376,7 +376,10 @@ nv_crtc_mode_set_vga(struct drm_crtc *crtc, struct drm_display_mode
*mode)
- */
-
- /* framebuffer can be larger than crtc scanout area. */
-- regp->CRTC[NV_CIO_CRE_RPC0_INDEX] = XLATE(fb->pitch / 8, 8,
NV_CIO_CRE_RPC0_OFFSET_10_8);
-+ regp->CRTC[NV_CIO_CRE_RPC0_INDEX] =
-+ XLATE(fb->pitch / 8, 8, NV_CIO_CRE_RPC0_OFFSET_10_8);
-+ regp->CRTC[NV_CIO_CRE_42] =
-+ XLATE(fb->pitch / 8, 11, NV_CIO_CRE_42_OFFSET_11);
- regp->CRTC[NV_CIO_CRE_RPC1_INDEX] = mode->crtc_hdisplay < 1280 ?
- MASK(NV_CIO_CRE_RPC1_LARGE) : 0x00;
- regp->CRTC[NV_CIO_CRE_LSR_INDEX] = XLATE(horizBlankEnd, 6, NV_CIO_CRE_LSR_HBE_6) |
-@@ -790,8 +793,7 @@ nv04_crtc_do_mode_set_base(struct drm_crtc *crtc,
- if (atomic) {
- drm_fb = passed_fb;
- fb = nouveau_framebuffer(passed_fb);
-- }
-- else {
-+ } else {
- /* If not atomic, we can go ahead and pin, and unpin the
- * old fb we were passed.
- */
-@@ -825,8 +827,11 @@ nv04_crtc_do_mode_set_base(struct drm_crtc *crtc,
- regp->CRTC[NV_CIO_CR_OFFSET_INDEX] = drm_fb->pitch >> 3;
- regp->CRTC[NV_CIO_CRE_RPC0_INDEX] =
- XLATE(drm_fb->pitch >> 3, 8, NV_CIO_CRE_RPC0_OFFSET_10_8);
-+ regp->CRTC[NV_CIO_CRE_42] =
-+ XLATE(drm_fb->pitch / 8, 11, NV_CIO_CRE_42_OFFSET_11);
- crtc_wr_cio_state(crtc, regp, NV_CIO_CRE_RPC0_INDEX);
- crtc_wr_cio_state(crtc, regp, NV_CIO_CR_OFFSET_INDEX);
-+ crtc_wr_cio_state(crtc, regp, NV_CIO_CRE_42);
-
- /* Update the framebuffer location. */
- regp->fb_start = nv_crtc->fb.offset & ~3;
-@@ -944,14 +949,14 @@ nv04_crtc_cursor_set(struct drm_crtc *crtc, struct drm_file
*file_priv,
- struct drm_gem_object *gem;
- int ret = 0;
-
-- if (width != 64 || height != 64)
-- return -EINVAL;
--
- if (!buffer_handle) {
- nv_crtc->cursor.hide(nv_crtc, true);
- return 0;
- }
-
-+ if (width != 64 || height != 64)
-+ return -EINVAL;
-+
- gem = drm_gem_object_lookup(dev, file_priv, buffer_handle);
- if (!gem)
- return -ENOENT;
-@@ -1031,7 +1036,7 @@ nv04_crtc_create(struct drm_device *dev, int crtc_num)
- drm_mode_crtc_set_gamma_size(&nv_crtc->base, 256);
-
- ret = nouveau_bo_new(dev, NULL, 64*64*4, 0x100, TTM_PL_FLAG_VRAM,
-- 0, 0x0000, false, true, &nv_crtc->cursor.nvbo);
-+ 0, 0x0000, &nv_crtc->cursor.nvbo);
- if (!ret) {
- ret = nouveau_bo_pin(nv_crtc->cursor.nvbo, TTM_PL_FLAG_VRAM);
- if (!ret)
-diff --git a/drivers/gpu/drm/nouveau/nv04_dfp.c b/drivers/gpu/drm/nouveau/nv04_dfp.c
-index c82db37..12098bf 100644
---- a/drivers/gpu/drm/nouveau/nv04_dfp.c
-+++ b/drivers/gpu/drm/nouveau/nv04_dfp.c
-@@ -581,12 +581,13 @@ static void nv04_dfp_restore(struct drm_encoder *encoder)
- int head = nv_encoder->restore.head;
-
- if (nv_encoder->dcb->type == OUTPUT_LVDS) {
-- struct drm_display_mode *native_mode =
nouveau_encoder_connector_get(nv_encoder)->native_mode;
-- if (native_mode)
-- call_lvds_script(dev, nv_encoder->dcb, head, LVDS_PANEL_ON,
-- native_mode->clock);
-- else
-- NV_ERROR(dev, "Not restoring LVDS without native mode\n");
-+ struct nouveau_connector *connector =
-+ nouveau_encoder_connector_get(nv_encoder);
-+
-+ if (connector && connector->native_mode)
-+ call_lvds_script(dev, nv_encoder->dcb, head,
-+ LVDS_PANEL_ON,
-+ connector->native_mode->clock);
-
- } else if (nv_encoder->dcb->type == OUTPUT_TMDS) {
- int clock = nouveau_hw_pllvals_to_clk
-diff --git a/drivers/gpu/drm/nouveau/nv04_fifo.c b/drivers/gpu/drm/nouveau/nv04_fifo.c
-index f89d104..db465a3 100644
---- a/drivers/gpu/drm/nouveau/nv04_fifo.c
-+++ b/drivers/gpu/drm/nouveau/nv04_fifo.c
-@@ -379,6 +379,15 @@ out:
- return handled;
- }
-
-+static const char *nv_dma_state_err(u32 state)
-+{
-+ static const char * const desc[] = {
-+ "NONE", "CALL_SUBR_ACTIVE", "INVALID_MTHD",
"RET_SUBR_INACTIVE",
-+ "INVALID_CMD", "IB_EMPTY"/* NV50+ */, "MEM_FAULT",
"UNK"
-+ };
-+ return desc[(state >> 29) & 0x7];
-+}
-+
- void
- nv04_fifo_isr(struct drm_device *dev)
- {
-@@ -460,9 +469,10 @@ nv04_fifo_isr(struct drm_device *dev)
- if (nouveau_ratelimit())
- NV_INFO(dev, "PFIFO_DMA_PUSHER - Ch %d Get 0x%02x%08x "
- "Put 0x%02x%08x IbGet 0x%08x IbPut 0x%08x "
-- "State 0x%08x Push 0x%08x\n",
-+ "State 0x%08x (err: %s) Push 0x%08x\n",
- chid, ho_get, dma_get, ho_put,
- dma_put, ib_get, ib_put, state,
-+ nv_dma_state_err(state),
- push);
-
- /* METHOD_COUNT, in DMA_STATE on earlier chipsets */
-@@ -476,8 +486,9 @@ nv04_fifo_isr(struct drm_device *dev)
- }
- } else {
- NV_INFO(dev, "PFIFO_DMA_PUSHER - Ch %d Get 0x%08x "
-- "Put 0x%08x State 0x%08x Push 0x%08x\n",
-- chid, dma_get, dma_put, state, push);
-+ "Put 0x%08x State 0x%08x (err: %s) Push 0x%08x\n",
-+ chid, dma_get, dma_put, state,
-+ nv_dma_state_err(state), push);
-
- if (dma_get != dma_put)
- nv_wr32(dev, 0x003244, dma_put);
-@@ -505,7 +516,7 @@ nv04_fifo_isr(struct drm_device *dev)
-
- if (dev_priv->card_type == NV_50) {
- if (status & 0x00000010) {
-- nv50_fb_vm_trap(dev, 1, "PFIFO_BAR_FAULT");
-+ nv50_fb_vm_trap(dev, nouveau_ratelimit());
- status &= ~0x00000010;
- nv_wr32(dev, 0x002100, 0x00000010);
- }
-diff --git a/drivers/gpu/drm/nouveau/nv04_graph.c b/drivers/gpu/drm/nouveau/nv04_graph.c
-index af75015..055677a 100644
---- a/drivers/gpu/drm/nouveau/nv04_graph.c
-+++ b/drivers/gpu/drm/nouveau/nv04_graph.c
-@@ -507,7 +507,7 @@ int nv04_graph_init(struct drm_device *dev)
- nv_wr32(dev, NV04_PGRAPH_DEBUG_0, 0x001FFFFF);*/
- nv_wr32(dev, NV04_PGRAPH_DEBUG_0, 0x1231c000);
- /*1231C000 blob, 001 haiku*/
-- //*V_WRITE(NV04_PGRAPH_DEBUG_1, 0xf2d91100);*/
-+ /*V_WRITE(NV04_PGRAPH_DEBUG_1, 0xf2d91100);*/
- nv_wr32(dev, NV04_PGRAPH_DEBUG_1, 0x72111100);
- /*0x72111100 blob , 01 haiku*/
- /*nv_wr32(dev, NV04_PGRAPH_DEBUG_2, 0x11d5f870);*/
-@@ -1232,8 +1232,7 @@ static struct nouveau_bitfield nv04_graph_intr[] = {
- {}
- };
-
--static struct nouveau_bitfield nv04_graph_nstatus[] =
--{
-+static struct nouveau_bitfield nv04_graph_nstatus[] = {
- { NV04_PGRAPH_NSTATUS_STATE_IN_USE, "STATE_IN_USE" },
- { NV04_PGRAPH_NSTATUS_INVALID_STATE, "INVALID_STATE" },
- { NV04_PGRAPH_NSTATUS_BAD_ARGUMENT, "BAD_ARGUMENT" },
-@@ -1241,8 +1240,7 @@ static struct nouveau_bitfield nv04_graph_nstatus[] =
- {}
- };
-
--struct nouveau_bitfield nv04_graph_nsource[] =
--{
-+struct nouveau_bitfield nv04_graph_nsource[] = {
- { NV03_PGRAPH_NSOURCE_NOTIFICATION, "NOTIFICATION" },
- { NV03_PGRAPH_NSOURCE_DATA_ERROR, "DATA_ERROR" },
- { NV03_PGRAPH_NSOURCE_PROTECTION_ERROR, "PROTECTION_ERROR" },
-diff --git a/drivers/gpu/drm/nouveau/nv04_instmem.c
b/drivers/gpu/drm/nouveau/nv04_instmem.c
-index b8e3edb..0671b7f 100644
---- a/drivers/gpu/drm/nouveau/nv04_instmem.c
-+++ b/drivers/gpu/drm/nouveau/nv04_instmem.c
-@@ -95,6 +95,9 @@ nv04_instmem_takedown(struct drm_device *dev)
- nouveau_ramht_ref(NULL, &dev_priv->ramht, NULL);
- nouveau_gpuobj_ref(NULL, &dev_priv->ramro);
- nouveau_gpuobj_ref(NULL, &dev_priv->ramfc);
-+
-+ if (dev_priv->ramin_heap.free_stack.next)
-+ drm_mm_takedown(&dev_priv->ramin_heap);
- }
-
- int
-diff --git a/drivers/gpu/drm/nouveau/nv10_graph.c b/drivers/gpu/drm/nouveau/nv10_graph.c
-index 8c92edb..531d7ba 100644
---- a/drivers/gpu/drm/nouveau/nv10_graph.c
-+++ b/drivers/gpu/drm/nouveau/nv10_graph.c
-@@ -1117,8 +1117,7 @@ struct nouveau_bitfield nv10_graph_intr[] = {
- {}
- };
-
--struct nouveau_bitfield nv10_graph_nstatus[] =
--{
-+struct nouveau_bitfield nv10_graph_nstatus[] = {
- { NV10_PGRAPH_NSTATUS_STATE_IN_USE, "STATE_IN_USE" },
- { NV10_PGRAPH_NSTATUS_INVALID_STATE, "INVALID_STATE" },
- { NV10_PGRAPH_NSTATUS_BAD_ARGUMENT, "BAD_ARGUMENT" },
-diff --git a/drivers/gpu/drm/nouveau/nv40_fb.c b/drivers/gpu/drm/nouveau/nv40_fb.c
-index f3d9c05..f0ac2a7 100644
---- a/drivers/gpu/drm/nouveau/nv40_fb.c
-+++ b/drivers/gpu/drm/nouveau/nv40_fb.c
-@@ -24,6 +24,53 @@ nv40_fb_set_tile_region(struct drm_device *dev, int i)
- }
- }
-
-+static void
-+nv40_fb_init_gart(struct drm_device *dev)
-+{
-+ struct drm_nouveau_private *dev_priv = dev->dev_private;
-+ struct nouveau_gpuobj *gart = dev_priv->gart_info.sg_ctxdma;
-+
-+ if (dev_priv->gart_info.type != NOUVEAU_GART_HW) {
-+ nv_wr32(dev, 0x100800, 0x00000001);
-+ return;
-+ }
-+
-+ nv_wr32(dev, 0x100800, gart->pinst | 0x00000002);
-+ nv_mask(dev, 0x10008c, 0x00000100, 0x00000100);
-+ nv_wr32(dev, 0x100820, 0x00000000);
-+}
-+
-+static void
-+nv44_fb_init_gart(struct drm_device *dev)
-+{
-+ struct drm_nouveau_private *dev_priv = dev->dev_private;
-+ struct nouveau_gpuobj *gart = dev_priv->gart_info.sg_ctxdma;
-+ u32 vinst;
-+
-+ if (dev_priv->gart_info.type != NOUVEAU_GART_HW) {
-+ nv_wr32(dev, 0x100850, 0x80000000);
-+ nv_wr32(dev, 0x100800, 0x00000001);
-+ return;
-+ }
-+
-+ /* calculate vram address of this PRAMIN block, object
-+ * must be allocated on 512KiB alignment, and not exceed
-+ * a total size of 512KiB for this to work correctly
-+ */
-+ vinst = nv_rd32(dev, 0x10020c);
-+ vinst -= ((gart->pinst >> 19) + 1) << 19;
-+
-+ nv_wr32(dev, 0x100850, 0x80000000);
-+ nv_wr32(dev, 0x100818, dev_priv->gart_info.dummy.addr);
-+
-+ nv_wr32(dev, 0x100804, dev_priv->gart_info.aper_size);
-+ nv_wr32(dev, 0x100850, 0x00008000);
-+ nv_mask(dev, 0x10008c, 0x00000200, 0x00000200);
-+ nv_wr32(dev, 0x100820, 0x00000000);
-+ nv_wr32(dev, 0x10082c, 0x00000001);
-+ nv_wr32(dev, 0x100800, vinst | 0x00000010);
-+}
-+
- int
- nv40_fb_init(struct drm_device *dev)
- {
-@@ -32,12 +79,12 @@ nv40_fb_init(struct drm_device *dev)
- uint32_t tmp;
- int i;
-
-- /* This is strictly a NV4x register (don't know about NV5x). */
-- /* The blob sets these to all kinds of values, and they mess up our setup. */
-- /* I got value 0x52802 instead. For some cards the blob even sets it back to 0x1. */
-- /* Note: the blob doesn't read this value, so i'm pretty sure this is safe for
all cards. */
-- /* Any idea what this is? */
-- nv_wr32(dev, NV40_PFB_UNK_800, 0x1);
-+ if (dev_priv->chipset != 0x40 && dev_priv->chipset != 0x45) {
-+ if (nv44_graph_class(dev))
-+ nv44_fb_init_gart(dev);
-+ else
-+ nv40_fb_init_gart(dev);
-+ }
-
- switch (dev_priv->chipset) {
- case 0x40:
-diff --git a/drivers/gpu/drm/nouveau/nv50_calc.c b/drivers/gpu/drm/nouveau/nv50_calc.c
-index de81151..8cf63a8 100644
---- a/drivers/gpu/drm/nouveau/nv50_calc.c
-+++ b/drivers/gpu/drm/nouveau/nv50_calc.c
-@@ -23,7 +23,6 @@
- */
-
- #include "drmP.h"
--#include "drm_fixed.h"
- #include "nouveau_drv.h"
- #include "nouveau_hw.h"
-
-@@ -47,45 +46,52 @@ nv50_calc_pll(struct drm_device *dev, struct pll_lims *pll, int clk,
- }
-
- int
--nv50_calc_pll2(struct drm_device *dev, struct pll_lims *pll, int clk,
-- int *N, int *fN, int *M, int *P)
-+nva3_calc_pll(struct drm_device *dev, struct pll_lims *pll, int clk,
-+ int *pN, int *pfN, int *pM, int *P)
- {
-- fixed20_12 fb_div, a, b;
-- u32 refclk = pll->refclk / 10;
-- u32 max_vco_freq = pll->vco1.maxfreq / 10;
-- u32 max_vco_inputfreq = pll->vco1.max_inputfreq / 10;
-- clk /= 10;
-+ u32 best_err = ~0, err;
-+ int M, lM, hM, N, fN;
-
-- *P = max_vco_freq / clk;
-+ *P = pll->vco1.maxfreq / clk;
- if (*P > pll->max_p)
- *P = pll->max_p;
- if (*P < pll->min_p)
- *P = pll->min_p;
-
-- /* *M = floor((refclk + max_vco_inputfreq) / max_vco_inputfreq); */
-- a.full = dfixed_const(refclk + max_vco_inputfreq);
-- b.full = dfixed_const(max_vco_inputfreq);
-- a.full = dfixed_div(a, b);
-- a.full = dfixed_floor(a);
-- *M = dfixed_trunc(a);
-+ lM = (pll->refclk + pll->vco1.max_inputfreq) / pll->vco1.max_inputfreq;
-+ lM = max(lM, (int)pll->vco1.min_m);
-+ hM = (pll->refclk + pll->vco1.min_inputfreq) / pll->vco1.min_inputfreq;
-+ hM = min(hM, (int)pll->vco1.max_m);
-
-- /* fb_div = (vco * *M) / refclk; */
-- fb_div.full = dfixed_const(clk * *P);
-- fb_div.full = dfixed_mul(fb_div, a);
-- a.full = dfixed_const(refclk);
-- fb_div.full = dfixed_div(fb_div, a);
-+ for (M = lM; M <= hM; M++) {
-+ u32 tmp = clk * *P * M;
-+ N = tmp / pll->refclk;
-+ fN = tmp % pll->refclk;
-+ if (!pfN && fN >= pll->refclk / 2)
-+ N++;
-
-- /* *N = floor(fb_div); */
-- a.full = dfixed_floor(fb_div);
-- *N = dfixed_trunc(fb_div);
-+ if (N < pll->vco1.min_n)
-+ continue;
-+ if (N > pll->vco1.max_n)
-+ break;
-
-- /* *fN = (fmod(fb_div, 1.0) * 8192) - 4096; */
-- b.full = dfixed_const(8192);
-- a.full = dfixed_mul(a, b);
-- fb_div.full = dfixed_mul(fb_div, b);
-- fb_div.full = fb_div.full - a.full;
-- *fN = dfixed_trunc(fb_div) - 4096;
-- *fN &= 0xffff;
-+ err = abs(clk - (pll->refclk * N / M / *P));
-+ if (err < best_err) {
-+ best_err = err;
-+ *pN = N;
-+ *pM = M;
-+ }
-
-- return clk;
-+ if (pfN) {
-+ *pfN = (((fN << 13) / pll->refclk) - 4096) & 0xffff;
-+ return clk;
-+ }
-+ }
-+
-+ if (unlikely(best_err == ~0)) {
-+ NV_ERROR(dev, "unable to find matching pll values\n");
-+ return -EINVAL;
-+ }
-+
-+ return pll->refclk * *pN / *pM / *P;
- }
-diff --git a/drivers/gpu/drm/nouveau/nv50_crtc.c b/drivers/gpu/drm/nouveau/nv50_crtc.c
-index 9023c4d..ebabacf 100644
---- a/drivers/gpu/drm/nouveau/nv50_crtc.c
-+++ b/drivers/gpu/drm/nouveau/nv50_crtc.c
-@@ -65,7 +65,7 @@ nv50_crtc_blank(struct nouveau_crtc *nv_crtc, bool blanked)
- {
- struct drm_device *dev = nv_crtc->base.dev;
- struct drm_nouveau_private *dev_priv = dev->dev_private;
-- struct nouveau_channel *evo = dev_priv->evo;
-+ struct nouveau_channel *evo = nv50_display(dev)->master;
- int index = nv_crtc->index, ret;
-
- NV_DEBUG_KMS(dev, "index %d\n", nv_crtc->index);
-@@ -135,8 +135,7 @@ static int
- nv50_crtc_set_dither(struct nouveau_crtc *nv_crtc, bool on, bool update)
- {
- struct drm_device *dev = nv_crtc->base.dev;
-- struct drm_nouveau_private *dev_priv = dev->dev_private;
-- struct nouveau_channel *evo = dev_priv->evo;
-+ struct nouveau_channel *evo = nv50_display(dev)->master;
- int ret;
-
- NV_DEBUG_KMS(dev, "\n");
-@@ -186,8 +185,7 @@ nv50_crtc_set_scale(struct nouveau_crtc *nv_crtc, int scaling_mode,
bool update)
- struct nouveau_connector *nv_connector =
- nouveau_crtc_connector_get(nv_crtc);
- struct drm_device *dev = nv_crtc->base.dev;
-- struct drm_nouveau_private *dev_priv = dev->dev_private;
-- struct nouveau_channel *evo = dev_priv->evo;
-+ struct nouveau_channel *evo = nv50_display(dev)->master;
- struct drm_display_mode *native_mode = NULL;
- struct drm_display_mode *mode = &nv_crtc->base.mode;
- uint32_t outX, outY, horiz, vert;
-@@ -288,7 +286,7 @@ nv50_crtc_set_clock(struct drm_device *dev, int head, int pclk)
- nv_wr32(dev, pll.reg + 8, reg2 | (P << 28) | (M2 << 16) | N2);
- } else
- if (dev_priv->chipset < NV_C0) {
-- ret = nv50_calc_pll2(dev, &pll, pclk, &N1, &N2, &M1, &P);
-+ ret = nva3_calc_pll(dev, &pll, pclk, &N1, &N2, &M1, &P);
- if (ret <= 0)
- return 0;
-
-@@ -300,7 +298,7 @@ nv50_crtc_set_clock(struct drm_device *dev, int head, int pclk)
- nv_wr32(dev, pll.reg + 4, reg1 | (P << 16) | (M1 << 8) | N1);
- nv_wr32(dev, pll.reg + 8, N2);
- } else {
-- ret = nv50_calc_pll2(dev, &pll, pclk, &N1, &N2, &M1, &P);
-+ ret = nva3_calc_pll(dev, &pll, pclk, &N1, &N2, &M1, &P);
- if (ret <= 0)
- return 0;
-
-@@ -351,14 +349,14 @@ nv50_crtc_cursor_set(struct drm_crtc *crtc, struct drm_file
*file_priv,
- struct drm_gem_object *gem;
- int ret = 0, i;
-
-- if (width != 64 || height != 64)
-- return -EINVAL;
--
- if (!buffer_handle) {
- nv_crtc->cursor.hide(nv_crtc, true);
- return 0;
- }
-
-+ if (width != 64 || height != 64)
-+ return -EINVAL;
-+
- gem = drm_gem_object_lookup(dev, file_priv, buffer_handle);
- if (!gem)
- return -ENOENT;
-@@ -445,6 +443,39 @@ nv50_crtc_dpms(struct drm_crtc *crtc, int mode)
- {
- }
-
-+static int
-+nv50_crtc_wait_complete(struct drm_crtc *crtc)
-+{
-+ struct drm_device *dev = crtc->dev;
-+ struct drm_nouveau_private *dev_priv = dev->dev_private;
-+ struct nouveau_timer_engine *ptimer = &dev_priv->engine.timer;
-+ struct nv50_display *disp = nv50_display(dev);
-+ struct nouveau_channel *evo = disp->master;
-+ u64 start;
-+ int ret;
-+
-+ ret = RING_SPACE(evo, 6);
-+ if (ret)
-+ return ret;
-+ BEGIN_RING(evo, 0, 0x0084, 1);
-+ OUT_RING (evo, 0x80000000);
-+ BEGIN_RING(evo, 0, 0x0080, 1);
-+ OUT_RING (evo, 0);
-+ BEGIN_RING(evo, 0, 0x0084, 1);
-+ OUT_RING (evo, 0x00000000);
-+
-+ nv_wo32(disp->ntfy, 0x000, 0x00000000);
-+ FIRE_RING (evo);
-+
-+ start = ptimer->read(dev);
-+ do {
-+ if (nv_ro32(disp->ntfy, 0x000))
-+ return 0;
-+ } while (ptimer->read(dev) - start < 2000000000ULL);
-+
-+ return -EBUSY;
-+}
-+
- static void
- nv50_crtc_prepare(struct drm_crtc *crtc)
- {
-@@ -453,6 +484,7 @@ nv50_crtc_prepare(struct drm_crtc *crtc)
-
- NV_DEBUG_KMS(dev, "index %d\n", nv_crtc->index);
-
-+ nv50_display_flip_stop(crtc);
- drm_vblank_pre_modeset(dev, nv_crtc->index);
- nv50_crtc_blank(nv_crtc, true);
- }
-@@ -461,24 +493,14 @@ static void
- nv50_crtc_commit(struct drm_crtc *crtc)
- {
- struct drm_device *dev = crtc->dev;
-- struct drm_nouveau_private *dev_priv = dev->dev_private;
-- struct nouveau_channel *evo = dev_priv->evo;
- struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
-- int ret;
-
- NV_DEBUG_KMS(dev, "index %d\n", nv_crtc->index);
-
- nv50_crtc_blank(nv_crtc, false);
- drm_vblank_post_modeset(dev, nv_crtc->index);
--
-- ret = RING_SPACE(evo, 2);
-- if (ret) {
-- NV_ERROR(dev, "no space while committing crtc\n");
-- return;
-- }
-- BEGIN_RING(evo, 0, NV50_EVO_UPDATE, 1);
-- OUT_RING (evo, 0);
-- FIRE_RING (evo);
-+ nv50_crtc_wait_complete(crtc);
-+ nv50_display_flip_next(crtc, crtc->fb, NULL);
- }
-
- static bool
-@@ -491,15 +513,15 @@ nv50_crtc_mode_fixup(struct drm_crtc *crtc, struct drm_display_mode
*mode,
- static int
- nv50_crtc_do_mode_set_base(struct drm_crtc *crtc,
- struct drm_framebuffer *passed_fb,
-- int x, int y, bool update, bool atomic)
-+ int x, int y, bool atomic)
- {
- struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
- struct drm_device *dev = nv_crtc->base.dev;
- struct drm_nouveau_private *dev_priv = dev->dev_private;
-- struct nouveau_channel *evo = dev_priv->evo;
-+ struct nouveau_channel *evo = nv50_display(dev)->master;
- struct drm_framebuffer *drm_fb = nv_crtc->base.fb;
- struct nouveau_framebuffer *fb = nouveau_framebuffer(drm_fb);
-- int ret, format;
-+ int ret;
-
- NV_DEBUG_KMS(dev, "index %d\n", nv_crtc->index);
-
-@@ -510,8 +532,7 @@ nv50_crtc_do_mode_set_base(struct drm_crtc *crtc,
- if (atomic) {
- drm_fb = passed_fb;
- fb = nouveau_framebuffer(passed_fb);
-- }
-- else {
-+ } else {
- /* If not atomic, we can go ahead and pin, and unpin the
- * old fb we were passed.
- */
-@@ -525,28 +546,6 @@ nv50_crtc_do_mode_set_base(struct drm_crtc *crtc,
- }
- }
-
-- switch (drm_fb->depth) {
-- case 8:
-- format = NV50_EVO_CRTC_FB_DEPTH_8;
-- break;
-- case 15:
-- format = NV50_EVO_CRTC_FB_DEPTH_15;
-- break;
-- case 16:
-- format = NV50_EVO_CRTC_FB_DEPTH_16;
-- break;
-- case 24:
-- case 32:
-- format = NV50_EVO_CRTC_FB_DEPTH_24;
-- break;
-- case 30:
-- format = NV50_EVO_CRTC_FB_DEPTH_30;
-- break;
-- default:
-- NV_ERROR(dev, "unknown depth %d\n", drm_fb->depth);
-- return -EINVAL;
-- }
--
- nv_crtc->fb.offset = fb->nvbo->bo.mem.start << PAGE_SHIFT;
- nv_crtc->fb.tile_flags = nouveau_bo_tile_layout(fb->nvbo);
- nv_crtc->fb.cpp = drm_fb->bits_per_pixel / 8;
-@@ -556,14 +555,7 @@ nv50_crtc_do_mode_set_base(struct drm_crtc *crtc,
- return ret;
-
- BEGIN_RING(evo, 0, NV50_EVO_CRTC(nv_crtc->index, FB_DMA), 1);
-- if (nv_crtc->fb.tile_flags == 0x7a00 ||
-- nv_crtc->fb.tile_flags == 0xfe00)
-- OUT_RING(evo, NvEvoFB32);
-- else
-- if (nv_crtc->fb.tile_flags == 0x7000)
-- OUT_RING(evo, NvEvoFB16);
-- else
-- OUT_RING(evo, NvEvoVRAM_LP);
-+ OUT_RING (evo, fb->r_dma);
- }
-
- ret = RING_SPACE(evo, 12);
-@@ -571,45 +563,26 @@ nv50_crtc_do_mode_set_base(struct drm_crtc *crtc,
- return ret;
-
- BEGIN_RING(evo, 0, NV50_EVO_CRTC(nv_crtc->index, FB_OFFSET), 5);
-- OUT_RING(evo, nv_crtc->fb.offset >> 8);
-- OUT_RING(evo, 0);
-- OUT_RING(evo, (drm_fb->height << 16) | drm_fb->width);
-- if (!nv_crtc->fb.tile_flags) {
-- OUT_RING(evo, drm_fb->pitch | (1 << 20));
-- } else {
-- u32 tile_mode = fb->nvbo->tile_mode;
-- if (dev_priv->card_type >= NV_C0)
-- tile_mode >>= 4;
-- OUT_RING(evo, ((drm_fb->pitch / 4) << 4) | tile_mode);
-- }
-- if (dev_priv->chipset == 0x50)
-- OUT_RING(evo, (nv_crtc->fb.tile_flags << 8) | format);
-- else
-- OUT_RING(evo, format);
-+ OUT_RING (evo, nv_crtc->fb.offset >> 8);
-+ OUT_RING (evo, 0);
-+ OUT_RING (evo, (drm_fb->height << 16) | drm_fb->width);
-+ OUT_RING (evo, fb->r_pitch);
-+ OUT_RING (evo, fb->r_format);
-
- BEGIN_RING(evo, 0, NV50_EVO_CRTC(nv_crtc->index, CLUT_MODE), 1);
-- OUT_RING(evo, fb->base.depth == 8 ?
-- NV50_EVO_CRTC_CLUT_MODE_OFF : NV50_EVO_CRTC_CLUT_MODE_ON);
-+ OUT_RING (evo, fb->base.depth == 8 ?
-+ NV50_EVO_CRTC_CLUT_MODE_OFF : NV50_EVO_CRTC_CLUT_MODE_ON);
-
- BEGIN_RING(evo, 0, NV50_EVO_CRTC(nv_crtc->index, COLOR_CTRL), 1);
-- OUT_RING(evo, NV50_EVO_CRTC_COLOR_CTRL_COLOR);
-+ OUT_RING (evo, NV50_EVO_CRTC_COLOR_CTRL_COLOR);
- BEGIN_RING(evo, 0, NV50_EVO_CRTC(nv_crtc->index, FB_POS), 1);
-- OUT_RING(evo, (y << 16) | x);
-+ OUT_RING (evo, (y << 16) | x);
-
- if (nv_crtc->lut.depth != fb->base.depth) {
- nv_crtc->lut.depth = fb->base.depth;
- nv50_crtc_lut_load(crtc);
- }
-
-- if (update) {
-- ret = RING_SPACE(evo, 2);
-- if (ret)
-- return ret;
-- BEGIN_RING(evo, 0, NV50_EVO_UPDATE, 1);
-- OUT_RING(evo, 0);
-- FIRE_RING(evo);
-- }
--
- return 0;
- }
-
-@@ -619,8 +592,7 @@ nv50_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode
*mode,
- struct drm_framebuffer *old_fb)
- {
- struct drm_device *dev = crtc->dev;
-- struct drm_nouveau_private *dev_priv = dev->dev_private;
-- struct nouveau_channel *evo = dev_priv->evo;
-+ struct nouveau_channel *evo = nv50_display(dev)->master;
- struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
- struct nouveau_connector *nv_connector = NULL;
- uint32_t hsync_dur, vsync_dur, hsync_start_to_end, vsync_start_to_end;
-@@ -700,14 +672,25 @@ nv50_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode
*mode,
- nv_crtc->set_dither(nv_crtc, nv_connector->use_dithering, false);
- nv_crtc->set_scale(nv_crtc, nv_connector->scaling_mode, false);
-
-- return nv50_crtc_do_mode_set_base(crtc, old_fb, x, y, false, false);
-+ return nv50_crtc_do_mode_set_base(crtc, old_fb, x, y, false);
- }
-
- static int
- nv50_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
- struct drm_framebuffer *old_fb)
- {
-- return nv50_crtc_do_mode_set_base(crtc, old_fb, x, y, true, false);
-+ int ret;
-+
-+ nv50_display_flip_stop(crtc);
-+ ret = nv50_crtc_do_mode_set_base(crtc, old_fb, x, y, false);
-+ if (ret)
-+ return ret;
-+
-+ ret = nv50_crtc_wait_complete(crtc);
-+ if (ret)
-+ return ret;
-+
-+ return nv50_display_flip_next(crtc, crtc->fb, NULL);
- }
-
- static int
-@@ -715,7 +698,14 @@ nv50_crtc_mode_set_base_atomic(struct drm_crtc *crtc,
- struct drm_framebuffer *fb,
- int x, int y, enum mode_set_atomic state)
- {
-- return nv50_crtc_do_mode_set_base(crtc, fb, x, y, true, true);
-+ int ret;
-+
-+ nv50_display_flip_stop(crtc);
-+ ret = nv50_crtc_do_mode_set_base(crtc, fb, x, y, true);
-+ if (ret)
-+ return ret;
-+
-+ return nv50_crtc_wait_complete(crtc);
- }
-
- static const struct drm_crtc_helper_funcs nv50_crtc_helper_funcs = {
-@@ -758,7 +748,7 @@ nv50_crtc_create(struct drm_device *dev, int index)
- nv_crtc->lut.depth = 0;
-
- ret = nouveau_bo_new(dev, NULL, 4096, 0x100, TTM_PL_FLAG_VRAM,
-- 0, 0x0000, false, true, &nv_crtc->lut.nvbo);
-+ 0, 0x0000, &nv_crtc->lut.nvbo);
- if (!ret) {
- ret = nouveau_bo_pin(nv_crtc->lut.nvbo, TTM_PL_FLAG_VRAM);
- if (!ret)
-@@ -784,7 +774,7 @@ nv50_crtc_create(struct drm_device *dev, int index)
- drm_mode_crtc_set_gamma_size(&nv_crtc->base, 256);
-
- ret = nouveau_bo_new(dev, NULL, 64*64*4, 0x100, TTM_PL_FLAG_VRAM,
-- 0, 0x0000, false, true, &nv_crtc->cursor.nvbo);
-+ 0, 0x0000, &nv_crtc->cursor.nvbo);
- if (!ret) {
- ret = nouveau_bo_pin(nv_crtc->cursor.nvbo, TTM_PL_FLAG_VRAM);
- if (!ret)
-diff --git a/drivers/gpu/drm/nouveau/nv50_cursor.c
b/drivers/gpu/drm/nouveau/nv50_cursor.c
-index 1b9ce30..9752c35 100644
---- a/drivers/gpu/drm/nouveau/nv50_cursor.c
-+++ b/drivers/gpu/drm/nouveau/nv50_cursor.c
-@@ -36,9 +36,9 @@
- static void
- nv50_cursor_show(struct nouveau_crtc *nv_crtc, bool update)
- {
-- struct drm_nouveau_private *dev_priv = nv_crtc->base.dev->dev_private;
-- struct nouveau_channel *evo = dev_priv->evo;
- struct drm_device *dev = nv_crtc->base.dev;
-+ struct drm_nouveau_private *dev_priv = dev->dev_private;
-+ struct nouveau_channel *evo = nv50_display(dev)->master;
- int ret;
-
- NV_DEBUG_KMS(dev, "\n");
-@@ -71,9 +71,9 @@ nv50_cursor_show(struct nouveau_crtc *nv_crtc, bool update)
- static void
- nv50_cursor_hide(struct nouveau_crtc *nv_crtc, bool update)
- {
-- struct drm_nouveau_private *dev_priv = nv_crtc->base.dev->dev_private;
-- struct nouveau_channel *evo = dev_priv->evo;
- struct drm_device *dev = nv_crtc->base.dev;
-+ struct drm_nouveau_private *dev_priv = dev->dev_private;
-+ struct nouveau_channel *evo = nv50_display(dev)->master;
- int ret;
-
- NV_DEBUG_KMS(dev, "\n");
-diff --git a/drivers/gpu/drm/nouveau/nv50_dac.c b/drivers/gpu/drm/nouveau/nv50_dac.c
-index 875414b..808f3ec 100644
---- a/drivers/gpu/drm/nouveau/nv50_dac.c
-+++ b/drivers/gpu/drm/nouveau/nv50_dac.c
-@@ -41,8 +41,7 @@ nv50_dac_disconnect(struct drm_encoder *encoder)
- {
- struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
- struct drm_device *dev = encoder->dev;
-- struct drm_nouveau_private *dev_priv = dev->dev_private;
-- struct nouveau_channel *evo = dev_priv->evo;
-+ struct nouveau_channel *evo = nv50_display(dev)->master;
- int ret;
-
- if (!nv_encoder->crtc)
-@@ -216,8 +215,7 @@ nv50_dac_mode_set(struct drm_encoder *encoder, struct
drm_display_mode *mode,
- {
- struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
- struct drm_device *dev = encoder->dev;
-- struct drm_nouveau_private *dev_priv = dev->dev_private;
-- struct nouveau_channel *evo = dev_priv->evo;
-+ struct nouveau_channel *evo = nv50_display(dev)->master;
- struct nouveau_crtc *crtc = nouveau_crtc(encoder->crtc);
- uint32_t mode_ctl = 0, mode_ctl2 = 0;
- int ret;
-diff --git a/drivers/gpu/drm/nouveau/nv50_display.c
b/drivers/gpu/drm/nouveau/nv50_display.c
-index 7cc94ed..74a3f68 100644
---- a/drivers/gpu/drm/nouveau/nv50_display.c
-+++ b/drivers/gpu/drm/nouveau/nv50_display.c
-@@ -24,6 +24,7 @@
- *
- */
-
-+#define NOUVEAU_DMA_DEBUG (nouveau_reg_debug & NOUVEAU_REG_DEBUG_EVO)
- #include "nv50_display.h"
- #include "nouveau_crtc.h"
- #include "nouveau_encoder.h"
-@@ -34,6 +35,7 @@
- #include "drm_crtc_helper.h"
-
- static void nv50_display_isr(struct drm_device *);
-+static void nv50_display_bh(unsigned long);
-
- static inline int
- nv50_sor_nr(struct drm_device *dev)
-@@ -172,16 +174,16 @@ nv50_display_init(struct drm_device *dev)
- ret = nv50_evo_init(dev);
- if (ret)
- return ret;
-- evo = dev_priv->evo;
-+ evo = nv50_display(dev)->master;
-
- nv_wr32(dev, NV50_PDISPLAY_OBJECTS, (evo->ramin->vinst >> 8) | 9);
-
-- ret = RING_SPACE(evo, 11);
-+ ret = RING_SPACE(evo, 15);
- if (ret)
- return ret;
- BEGIN_RING(evo, 0, NV50_EVO_UNK84, 2);
- OUT_RING(evo, NV50_EVO_UNK84_NOTIFY_DISABLED);
-- OUT_RING(evo, NV50_EVO_DMA_NOTIFY_HANDLE_NONE);
-+ OUT_RING(evo, NvEvoSync);
- BEGIN_RING(evo, 0, NV50_EVO_CRTC(0, FB_DMA), 1);
- OUT_RING(evo, NV50_EVO_CRTC_FB_DMA_HANDLE_NONE);
- BEGIN_RING(evo, 0, NV50_EVO_CRTC(0, UNK0800), 1);
-@@ -190,6 +192,11 @@ nv50_display_init(struct drm_device *dev)
- OUT_RING(evo, 0);
- BEGIN_RING(evo, 0, NV50_EVO_CRTC(0, UNK082C), 1);
- OUT_RING(evo, 0);
-+ /* required to make display sync channels not hate life */
-+ BEGIN_RING(evo, 0, NV50_EVO_CRTC(0, UNK900), 1);
-+ OUT_RING (evo, 0x00000311);
-+ BEGIN_RING(evo, 0, NV50_EVO_CRTC(1, UNK900), 1);
-+ OUT_RING (evo, 0x00000311);
- FIRE_RING(evo);
- if (!nv_wait(dev, 0x640004, 0xffffffff, evo->dma.put << 2))
- NV_ERROR(dev, "evo pushbuf stalled\n");
-@@ -201,6 +208,8 @@ nv50_display_init(struct drm_device *dev)
- static int nv50_display_disable(struct drm_device *dev)
- {
- struct drm_nouveau_private *dev_priv = dev->dev_private;
-+ struct nv50_display *disp = nv50_display(dev);
-+ struct nouveau_channel *evo = disp->master;
- struct drm_crtc *drm_crtc;
- int ret, i;
-
-@@ -212,12 +221,12 @@ static int nv50_display_disable(struct drm_device *dev)
- nv50_crtc_blank(crtc, true);
- }
-
-- ret = RING_SPACE(dev_priv->evo, 2);
-+ ret = RING_SPACE(evo, 2);
- if (ret == 0) {
-- BEGIN_RING(dev_priv->evo, 0, NV50_EVO_UPDATE, 1);
-- OUT_RING(dev_priv->evo, 0);
-+ BEGIN_RING(evo, 0, NV50_EVO_UPDATE, 1);
-+ OUT_RING(evo, 0);
- }
-- FIRE_RING(dev_priv->evo);
-+ FIRE_RING(evo);
-
- /* Almost like ack'ing a vblank interrupt, maybe in the spirit of
- * cleaning up?
-@@ -267,10 +276,16 @@ int nv50_display_create(struct drm_device *dev)
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct dcb_table *dcb = &dev_priv->vbios.dcb;
- struct drm_connector *connector, *ct;
-+ struct nv50_display *priv;
- int ret, i;
-
- NV_DEBUG_KMS(dev, "\n");
-
-+ priv = kzalloc(sizeof(*priv), GFP_KERNEL);
-+ if (!priv)
-+ return -ENOMEM;
-+ dev_priv->engine.display.priv = priv;
-+
- /* init basic kernel modesetting */
- drm_mode_config_init(dev);
-
-@@ -330,7 +345,7 @@ int nv50_display_create(struct drm_device *dev)
- }
- }
-
-- INIT_WORK(&dev_priv->irq_work, nv50_display_irq_handler_bh);
-+ tasklet_init(&priv->tasklet, nv50_display_bh, (unsigned long)dev);
- nouveau_irq_register(dev, 26, nv50_display_isr);
-
- ret = nv50_display_init(dev);
-@@ -345,12 +360,131 @@ int nv50_display_create(struct drm_device *dev)
- void
- nv50_display_destroy(struct drm_device *dev)
- {
-+ struct nv50_display *disp = nv50_display(dev);
-+
- NV_DEBUG_KMS(dev, "\n");
-
- drm_mode_config_cleanup(dev);
-
- nv50_display_disable(dev);
- nouveau_irq_unregister(dev, 26);
-+ kfree(disp);
-+}
-+
-+void
-+nv50_display_flip_stop(struct drm_crtc *crtc)
-+{
-+ struct nv50_display *disp = nv50_display(crtc->dev);
-+ struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
-+ struct nv50_display_crtc *dispc = &disp->crtc[nv_crtc->index];
-+ struct nouveau_channel *evo = dispc->sync;
-+ int ret;
-+
-+ ret = RING_SPACE(evo, 8);
-+ if (ret) {
-+ WARN_ON(1);
-+ return;
-+ }
-+
-+ BEGIN_RING(evo, 0, 0x0084, 1);
-+ OUT_RING (evo, 0x00000000);
-+ BEGIN_RING(evo, 0, 0x0094, 1);
-+ OUT_RING (evo, 0x00000000);
-+ BEGIN_RING(evo, 0, 0x00c0, 1);
-+ OUT_RING (evo, 0x00000000);
-+ BEGIN_RING(evo, 0, 0x0080, 1);
-+ OUT_RING (evo, 0x00000000);
-+ FIRE_RING (evo);
-+}
-+
-+int
-+nv50_display_flip_next(struct drm_crtc *crtc, struct drm_framebuffer *fb,
-+ struct nouveau_channel *chan)
-+{
-+ struct drm_nouveau_private *dev_priv = crtc->dev->dev_private;
-+ struct nouveau_framebuffer *nv_fb = nouveau_framebuffer(fb);
-+ struct nv50_display *disp = nv50_display(crtc->dev);
-+ struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
-+ struct nv50_display_crtc *dispc = &disp->crtc[nv_crtc->index];
-+ struct nouveau_channel *evo = dispc->sync;
-+ int ret;
-+
-+ ret = RING_SPACE(evo, 24);
-+ if (unlikely(ret))
-+ return ret;
-+
-+ /* synchronise with the rendering channel, if necessary */
-+ if (likely(chan)) {
-+ u64 offset = dispc->sem.bo->vma.offset + dispc->sem.offset;
-+
-+ ret = RING_SPACE(chan, 10);
-+ if (ret) {
-+ WIND_RING(evo);
-+ return ret;
-+ }
-+
-+ if (dev_priv->chipset < 0xc0) {
-+ BEGIN_RING(chan, NvSubSw, 0x0060, 2);
-+ OUT_RING (chan, NvEvoSema0 + nv_crtc->index);
-+ OUT_RING (chan, dispc->sem.offset);
-+ BEGIN_RING(chan, NvSubSw, 0x006c, 1);
-+ OUT_RING (chan, 0xf00d0000 | dispc->sem.value);
-+ BEGIN_RING(chan, NvSubSw, 0x0064, 2);
-+ OUT_RING (chan, dispc->sem.offset ^ 0x10);
-+ OUT_RING (chan, 0x74b1e000);
-+ BEGIN_RING(chan, NvSubSw, 0x0060, 1);
-+ if (dev_priv->chipset < 0x84)
-+ OUT_RING (chan, NvSema);
-+ else
-+ OUT_RING (chan, chan->vram_handle);
-+ } else {
-+ BEGIN_NVC0(chan, 2, NvSubM2MF, 0x0010, 4);
-+ OUT_RING (chan, upper_32_bits(offset));
-+ OUT_RING (chan, lower_32_bits(offset));
-+ OUT_RING (chan, 0xf00d0000 | dispc->sem.value);
-+ OUT_RING (chan, 0x1002);
-+ BEGIN_NVC0(chan, 2, NvSubM2MF, 0x0010, 4);
-+ OUT_RING (chan, upper_32_bits(offset));
-+ OUT_RING (chan, lower_32_bits(offset ^ 0x10));
-+ OUT_RING (chan, 0x74b1e000);
-+ OUT_RING (chan, 0x1001);
-+ }
-+ FIRE_RING (chan);
-+ } else {
-+ nouveau_bo_wr32(dispc->sem.bo, dispc->sem.offset / 4,
-+ 0xf00d0000 | dispc->sem.value);
-+ }
-+
-+ /* queue the flip on the crtc's "display sync" channel */
-+ BEGIN_RING(evo, 0, 0x0100, 1);
-+ OUT_RING (evo, 0xfffe0000);
-+ BEGIN_RING(evo, 0, 0x0084, 5);
-+ OUT_RING (evo, chan ? 0x00000100 : 0x00000010);
-+ OUT_RING (evo, dispc->sem.offset);
-+ OUT_RING (evo, 0xf00d0000 | dispc->sem.value);
-+ OUT_RING (evo, 0x74b1e000);
-+ OUT_RING (evo, NvEvoSync);
-+ BEGIN_RING(evo, 0, 0x00a0, 2);
-+ OUT_RING (evo, 0x00000000);
-+ OUT_RING (evo, 0x00000000);
-+ BEGIN_RING(evo, 0, 0x00c0, 1);
-+ OUT_RING (evo, nv_fb->r_dma);
-+ BEGIN_RING(evo, 0, 0x0110, 2);
-+ OUT_RING (evo, 0x00000000);
-+ OUT_RING (evo, 0x00000000);
-+ BEGIN_RING(evo, 0, 0x0800, 5);
-+ OUT_RING (evo, (nv_fb->nvbo->bo.mem.start << PAGE_SHIFT) >> 8);
-+ OUT_RING (evo, 0);
-+ OUT_RING (evo, (fb->height << 16) | fb->width);
-+ OUT_RING (evo, nv_fb->r_pitch);
-+ OUT_RING (evo, nv_fb->r_format);
-+ BEGIN_RING(evo, 0, 0x0080, 1);
-+ OUT_RING (evo, 0x00000000);
-+ FIRE_RING (evo);
-+
-+ dispc->sem.offset ^= 0x10;
-+ dispc->sem.value++;
-+ return 0;
- }
-
- static u16
-@@ -383,13 +517,25 @@ nv50_display_script_select(struct drm_device *dev, struct dcb_entry
*dcb,
- if (bios->fp.if_is_24bit)
- script |= 0x0200;
- } else {
-+ /* determine number of lvds links */
-+ if (nv_connector && nv_connector->edid &&
-+ nv_connector->dcb->type == DCB_CONNECTOR_LVDS_SPWG) {
-+ /*
http://www.spwg.org */
-+ if (((u8 *)nv_connector->edid)[121] == 2)
-+ script |= 0x0100;
-+ } else
- if (pxclk >= bios->fp.duallink_transition_clk) {
- script |= 0x0100;
-+ }
-+
-+ /* determine panel depth */
-+ if (script & 0x0100) {
- if (bios->fp.strapless_is_24bit & 2)
- script |= 0x0200;
-- } else
-- if (bios->fp.strapless_is_24bit & 1)
-- script |= 0x0200;
-+ } else {
-+ if (bios->fp.strapless_is_24bit & 1)
-+ script |= 0x0200;
-+ }
-
- if (nv_connector && nv_connector->edid &&
- (nv_connector->edid->revision >= 4) &&
-@@ -466,11 +612,12 @@ static void
- nv50_display_unk10_handler(struct drm_device *dev)
- {
- struct drm_nouveau_private *dev_priv = dev->dev_private;
-+ struct nv50_display *disp = nv50_display(dev);
- u32 unk30 = nv_rd32(dev, 0x610030), mc;
- int i, crtc, or, type = OUTPUT_ANY;
-
- NV_DEBUG_KMS(dev, "0x610030: 0x%08x\n", unk30);
-- dev_priv->evo_irq.dcb = NULL;
-+ disp->irq.dcb = NULL;
-
- nv_wr32(dev, 0x619494, nv_rd32(dev, 0x619494) & ~8);
-
-@@ -541,7 +688,7 @@ nv50_display_unk10_handler(struct drm_device *dev)
-
- if (dcb->type == type && (dcb->or & (1 << or))) {
- nouveau_bios_run_display_table(dev, dcb, 0, -1);
-- dev_priv->evo_irq.dcb = dcb;
-+ disp->irq.dcb = dcb;
- goto ack;
- }
- }
-@@ -587,15 +734,16 @@ static void
- nv50_display_unk20_handler(struct drm_device *dev)
- {
- struct drm_nouveau_private *dev_priv = dev->dev_private;
-- u32 unk30 = nv_rd32(dev, 0x610030), tmp, pclk, script, mc;
-+ struct nv50_display *disp = nv50_display(dev);
-+ u32 unk30 = nv_rd32(dev, 0x610030), tmp, pclk, script, mc = 0;
- struct dcb_entry *dcb;
- int i, crtc, or, type = OUTPUT_ANY;
-
- NV_DEBUG_KMS(dev, "0x610030: 0x%08x\n", unk30);
-- dcb = dev_priv->evo_irq.dcb;
-+ dcb = disp->irq.dcb;
- if (dcb) {
- nouveau_bios_run_display_table(dev, dcb, 0, -2);
-- dev_priv->evo_irq.dcb = NULL;
-+ disp->irq.dcb = NULL;
- }
-
- /* CRTC clock change requested? */
-@@ -692,9 +840,9 @@ nv50_display_unk20_handler(struct drm_device *dev)
- nv_wr32(dev, NV50_PDISPLAY_DAC_CLK_CTRL2(or), 0);
- }
-
-- dev_priv->evo_irq.dcb = dcb;
-- dev_priv->evo_irq.pclk = pclk;
-- dev_priv->evo_irq.script = script;
-+ disp->irq.dcb = dcb;
-+ disp->irq.pclk = pclk;
-+ disp->irq.script = script;
-
- ack:
- nv_wr32(dev, NV50_PDISPLAY_INTR_1, NV50_PDISPLAY_INTR_1_CLK_UNK20);
-@@ -735,13 +883,13 @@ nv50_display_unk40_dp_set_tmds(struct drm_device *dev, struct
dcb_entry *dcb)
- static void
- nv50_display_unk40_handler(struct drm_device *dev)
- {
-- struct drm_nouveau_private *dev_priv = dev->dev_private;
-- struct dcb_entry *dcb = dev_priv->evo_irq.dcb;
-- u16 script = dev_priv->evo_irq.script;
-- u32 unk30 = nv_rd32(dev, 0x610030), pclk = dev_priv->evo_irq.pclk;
-+ struct nv50_display *disp = nv50_display(dev);
-+ struct dcb_entry *dcb = disp->irq.dcb;
-+ u16 script = disp->irq.script;
-+ u32 unk30 = nv_rd32(dev, 0x610030), pclk = disp->irq.pclk;
-
- NV_DEBUG_KMS(dev, "0x610030: 0x%08x\n", unk30);
-- dev_priv->evo_irq.dcb = NULL;
-+ disp->irq.dcb = NULL;
- if (!dcb)
- goto ack;
-
-@@ -754,12 +902,10 @@ ack:
- nv_wr32(dev, 0x619494, nv_rd32(dev, 0x619494) | 8);
- }
-
--void
--nv50_display_irq_handler_bh(struct work_struct *work)
-+static void
-+nv50_display_bh(unsigned long data)
- {
-- struct drm_nouveau_private *dev_priv =
-- container_of(work, struct drm_nouveau_private, irq_work);
-- struct drm_device *dev = dev_priv->dev;
-+ struct drm_device *dev = (struct drm_device *)data;
-
- for (;;) {
- uint32_t intr0 = nv_rd32(dev, NV50_PDISPLAY_INTR_0);
-@@ -807,7 +953,7 @@ nv50_display_error_handler(struct drm_device *dev)
- static void
- nv50_display_isr(struct drm_device *dev)
- {
-- struct drm_nouveau_private *dev_priv = dev->dev_private;
-+ struct nv50_display *disp = nv50_display(dev);
- uint32_t delayed = 0;
-
- while (nv_rd32(dev, NV50_PMC_INTR_0) & NV50_PMC_INTR_0_DISPLAY) {
-@@ -835,8 +981,7 @@ nv50_display_isr(struct drm_device *dev)
- NV50_PDISPLAY_INTR_1_CLK_UNK40));
- if (clock) {
- nv_wr32(dev, NV03_PMC_INTR_EN_0, 0);
-- if (!work_pending(&dev_priv->irq_work))
-- queue_work(dev_priv->wq, &dev_priv->irq_work);
-+ tasklet_schedule(&disp->tasklet);
- delayed |= clock;
- intr1 &= ~clock;
- }
-diff --git a/drivers/gpu/drm/nouveau/nv50_display.h
b/drivers/gpu/drm/nouveau/nv50_display.h
-index f0e30b78..c2da503 100644
---- a/drivers/gpu/drm/nouveau/nv50_display.h
-+++ b/drivers/gpu/drm/nouveau/nv50_display.h
-@@ -35,7 +35,36 @@
- #include "nouveau_crtc.h"
- #include "nv50_evo.h"
-
--void nv50_display_irq_handler_bh(struct work_struct *work);
-+struct nv50_display_crtc {
-+ struct nouveau_channel *sync;
-+ struct {
-+ struct nouveau_bo *bo;
-+ u32 offset;
-+ u16 value;
-+ } sem;
-+};
-+
-+struct nv50_display {
-+ struct nouveau_channel *master;
-+ struct nouveau_gpuobj *ntfy;
-+
-+ struct nv50_display_crtc crtc[2];
-+
-+ struct tasklet_struct tasklet;
-+ struct {
-+ struct dcb_entry *dcb;
-+ u16 script;
-+ u32 pclk;
-+ } irq;
-+};
-+
-+static inline struct nv50_display *
-+nv50_display(struct drm_device *dev)
-+{
-+ struct drm_nouveau_private *dev_priv = dev->dev_private;
-+ return dev_priv->engine.display.priv;
-+}
-+
- int nv50_display_early_init(struct drm_device *dev);
- void nv50_display_late_takedown(struct drm_device *dev);
- int nv50_display_create(struct drm_device *dev);
-@@ -44,4 +73,15 @@ void nv50_display_destroy(struct drm_device *dev);
- int nv50_crtc_blank(struct nouveau_crtc *, bool blank);
- int nv50_crtc_set_clock(struct drm_device *, int head, int pclk);
-
-+int nv50_display_flip_next(struct drm_crtc *, struct drm_framebuffer *,
-+ struct nouveau_channel *chan);
-+void nv50_display_flip_stop(struct drm_crtc *);
-+
-+int nv50_evo_init(struct drm_device *dev);
-+void nv50_evo_fini(struct drm_device *dev);
-+void nv50_evo_dmaobj_init(struct nouveau_gpuobj *, u32 memtype, u64 base,
-+ u64 size);
-+int nv50_evo_dmaobj_new(struct nouveau_channel *, u32 handle, u32 memtype,
-+ u64 base, u64 size, struct nouveau_gpuobj **);
-+
- #endif /* __NV50_DISPLAY_H__ */
-diff --git a/drivers/gpu/drm/nouveau/nv50_evo.c b/drivers/gpu/drm/nouveau/nv50_evo.c
-index 0ea090f..c8e83c1 100644
---- a/drivers/gpu/drm/nouveau/nv50_evo.c
-+++ b/drivers/gpu/drm/nouveau/nv50_evo.c
-@@ -27,20 +27,17 @@
- #include "nouveau_drv.h"
- #include "nouveau_dma.h"
- #include "nouveau_ramht.h"
-+#include "nv50_display.h"
-
- static void
- nv50_evo_channel_del(struct nouveau_channel **pevo)
- {
-- struct drm_nouveau_private *dev_priv;
- struct nouveau_channel *evo = *pevo;
-
- if (!evo)
- return;
- *pevo = NULL;
-
-- dev_priv = evo->dev->dev_private;
-- dev_priv->evo_alloc &= ~(1 << evo->id);
--
- nouveau_gpuobj_channel_takedown(evo);
- nouveau_bo_unmap(evo->pushbuf_bo);
- nouveau_bo_ref(NULL, &evo->pushbuf_bo);
-@@ -51,42 +48,61 @@ nv50_evo_channel_del(struct nouveau_channel **pevo)
- kfree(evo);
- }
-
-+void
-+nv50_evo_dmaobj_init(struct nouveau_gpuobj *obj, u32 memtype, u64 base, u64 size)
-+{
-+ struct drm_nouveau_private *dev_priv = obj->dev->dev_private;
-+ u32 flags5;
-+
-+ if (dev_priv->chipset < 0xc0) {
-+ /* not supported on 0x50, specified in format mthd */
-+ if (dev_priv->chipset == 0x50)
-+ memtype = 0;
-+ flags5 = 0x00010000;
-+ } else {
-+ if (memtype & 0x80000000)
-+ flags5 = 0x00000000; /* large pages */
-+ else
-+ flags5 = 0x00020000;
-+ }
-+
-+ nv50_gpuobj_dma_init(obj, 0, 0x3d, base, size, NV_MEM_TARGET_VRAM,
-+ NV_MEM_ACCESS_RW, (memtype >> 8) & 0xff, 0);
-+ nv_wo32(obj, 0x14, flags5);
-+ dev_priv->engine.instmem.flush(obj->dev);
-+}
-+
- int
--nv50_evo_dmaobj_new(struct nouveau_channel *evo, u32 class, u32 name,
-- u32 tile_flags, u32 magic_flags, u32 offset, u32 limit,
-- u32 flags5)
-+nv50_evo_dmaobj_new(struct nouveau_channel *evo, u32 handle, u32 memtype,
-+ u64 base, u64 size, struct nouveau_gpuobj **pobj)
- {
-- struct drm_nouveau_private *dev_priv = evo->dev->dev_private;
-- struct drm_device *dev = evo->dev;
-+ struct nv50_display *disp = nv50_display(evo->dev);
- struct nouveau_gpuobj *obj = NULL;
- int ret;
-
-- ret = nouveau_gpuobj_new(dev, dev_priv->evo, 6*4, 32, 0, &obj);
-+ ret = nouveau_gpuobj_new(evo->dev, disp->master, 6*4, 32, 0, &obj);
- if (ret)
- return ret;
- obj->engine = NVOBJ_ENGINE_DISPLAY;
-
-- nv_wo32(obj, 0, (tile_flags << 22) | (magic_flags << 16) | class);
-- nv_wo32(obj, 4, limit);
-- nv_wo32(obj, 8, offset);
-- nv_wo32(obj, 12, 0x00000000);
-- nv_wo32(obj, 16, 0x00000000);
-- nv_wo32(obj, 20, flags5);
-- dev_priv->engine.instmem.flush(dev);
-+ nv50_evo_dmaobj_init(obj, memtype, base, size);
-
-- ret = nouveau_ramht_insert(evo, name, obj);
-- nouveau_gpuobj_ref(NULL, &obj);
-- if (ret) {
-- return ret;
-- }
-+ ret = nouveau_ramht_insert(evo, handle, obj);
-+ if (ret)
-+ goto out;
-
-- return 0;
-+ if (pobj)
-+ nouveau_gpuobj_ref(obj, pobj);
-+out:
-+ nouveau_gpuobj_ref(NULL, &obj);
-+ return ret;
- }
-
- static int
--nv50_evo_channel_new(struct drm_device *dev, struct nouveau_channel **pevo)
-+nv50_evo_channel_new(struct drm_device *dev, int chid,
-+ struct nouveau_channel **pevo)
- {
-- struct drm_nouveau_private *dev_priv = dev->dev_private;
-+ struct nv50_display *disp = nv50_display(dev);
- struct nouveau_channel *evo;
- int ret;
-
-@@ -95,25 +111,13 @@ nv50_evo_channel_new(struct drm_device *dev, struct nouveau_channel
**pevo)
- return -ENOMEM;
- *pevo = evo;
-
-- for (evo->id = 0; evo->id < 5; evo->id++) {
-- if (dev_priv->evo_alloc & (1 << evo->id))
-- continue;
--
-- dev_priv->evo_alloc |= (1 << evo->id);
-- break;
-- }
--
-- if (evo->id == 5) {
-- kfree(evo);
-- return -ENODEV;
-- }
--
-+ evo->id = chid;
- evo->dev = dev;
- evo->user_get = 4;
- evo->user_put = 0;
-
- ret = nouveau_bo_new(dev, NULL, 4096, 0, TTM_PL_FLAG_VRAM, 0, 0,
-- false, true, &evo->pushbuf_bo);
-+ &evo->pushbuf_bo);
- if (ret == 0)
- ret = nouveau_bo_pin(evo->pushbuf_bo, TTM_PL_FLAG_VRAM);
- if (ret) {
-@@ -138,8 +142,8 @@ nv50_evo_channel_new(struct drm_device *dev, struct nouveau_channel
**pevo)
- }
-
- /* bind primary evo channel's ramht to the channel */
-- if (dev_priv->evo && evo != dev_priv->evo)
-- nouveau_ramht_ref(dev_priv->evo->ramht, &evo->ramht, NULL);
-+ if (disp->master && evo != disp->master)
-+ nouveau_ramht_ref(disp->master->ramht, &evo->ramht, NULL);
-
- return 0;
- }
-@@ -182,6 +186,7 @@ nv50_evo_channel_init(struct nouveau_channel *evo)
- nv_mask(dev, 0x610028, 0x00000000, 0x00010001 << id);
-
- evo->dma.max = (4096/4) - 2;
-+ evo->dma.max &= ~7;
- evo->dma.put = 0;
- evo->dma.cur = evo->dma.put;
- evo->dma.free = evo->dma.max - evo->dma.cur;
-@@ -212,21 +217,39 @@ nv50_evo_channel_fini(struct nouveau_channel *evo)
- }
- }
-
-+static void
-+nv50_evo_destroy(struct drm_device *dev)
-+{
-+ struct nv50_display *disp = nv50_display(dev);
-+ int i;
-+
-+ for (i = 0; i < 2; i++) {
-+ if (disp->crtc[i].sem.bo) {
-+ nouveau_bo_unmap(disp->crtc[i].sem.bo);
-+ nouveau_bo_ref(NULL, &disp->crtc[i].sem.bo);
-+ }
-+ nv50_evo_channel_del(&disp->crtc[i].sync);
-+ }
-+ nouveau_gpuobj_ref(NULL, &disp->ntfy);
-+ nv50_evo_channel_del(&disp->master);
-+}
-+
- static int
- nv50_evo_create(struct drm_device *dev)
- {
- struct drm_nouveau_private *dev_priv = dev->dev_private;
-+ struct nv50_display *disp = nv50_display(dev);
- struct nouveau_gpuobj *ramht = NULL;
- struct nouveau_channel *evo;
-- int ret;
-+ int ret, i, j;
-
- /* create primary evo channel, the one we use for modesetting
- * purporses
- */
-- ret = nv50_evo_channel_new(dev, &dev_priv->evo);
-+ ret = nv50_evo_channel_new(dev, 0, &disp->master);
- if (ret)
- return ret;
-- evo = dev_priv->evo;
-+ evo = disp->master;
-
- /* setup object management on it, any other evo channel will
- * use this also as there's no per-channel support on the
-@@ -236,109 +259,167 @@ nv50_evo_create(struct drm_device *dev)
- NVOBJ_FLAG_ZERO_ALLOC, &evo->ramin);
- if (ret) {
- NV_ERROR(dev, "Error allocating EVO channel memory: %d\n", ret);
-- nv50_evo_channel_del(&dev_priv->evo);
-- return ret;
-+ goto err;
- }
-
- ret = drm_mm_init(&evo->ramin_heap, 0, 32768);
- if (ret) {
- NV_ERROR(dev, "Error initialising EVO PRAMIN heap: %d\n", ret);
-- nv50_evo_channel_del(&dev_priv->evo);
-- return ret;
-+ goto err;
- }
-
- ret = nouveau_gpuobj_new(dev, evo, 4096, 16, 0, &ramht);
- if (ret) {
- NV_ERROR(dev, "Unable to allocate EVO RAMHT: %d\n", ret);
-- nv50_evo_channel_del(&dev_priv->evo);
-- return ret;
-+ goto err;
- }
-
- ret = nouveau_ramht_new(dev, ramht, &evo->ramht);
- nouveau_gpuobj_ref(NULL, &ramht);
-- if (ret) {
-- nv50_evo_channel_del(&dev_priv->evo);
-- return ret;
-- }
-+ if (ret)
-+ goto err;
-+
-+ /* not sure exactly what this is..
-+ *
-+ * the first dword of the structure is used by nvidia to wait on
-+ * full completion of an EVO "update" command.
-+ *
-+ * method 0x8c on the master evo channel will fill a lot more of
-+ * this structure with some undefined info
-+ */
-+ ret = nouveau_gpuobj_new(dev, disp->master, 0x1000, 0,
-+ NVOBJ_FLAG_ZERO_ALLOC, &disp->ntfy);
-+ if (ret)
-+ goto err;
-+
-+ ret = nv50_evo_dmaobj_new(disp->master, NvEvoSync, 0x0000,
-+ disp->ntfy->vinst, disp->ntfy->size, NULL);
-+ if (ret)
-+ goto err;
-
- /* create some default objects for the scanout memtypes we support */
-- if (dev_priv->card_type >= NV_C0) {
-- ret = nv50_evo_dmaobj_new(evo, 0x3d, NvEvoFB32, 0xfe, 0x19,
-- 0, 0xffffffff, 0x00000000);
-- if (ret) {
-- nv50_evo_channel_del(&dev_priv->evo);
-- return ret;
-- }
-+ ret = nv50_evo_dmaobj_new(disp->master, NvEvoVRAM, 0x0000,
-+ 0, dev_priv->vram_size, NULL);
-+ if (ret)
-+ goto err;
-
-- ret = nv50_evo_dmaobj_new(evo, 0x3d, NvEvoVRAM, 0, 0x19,
-- 0, dev_priv->vram_size, 0x00020000);
-- if (ret) {
-- nv50_evo_channel_del(&dev_priv->evo);
-- return ret;
-- }
-+ ret = nv50_evo_dmaobj_new(disp->master, NvEvoVRAM_LP, 0x80000000,
-+ 0, dev_priv->vram_size, NULL);
-+ if (ret)
-+ goto err;
-
-- ret = nv50_evo_dmaobj_new(evo, 0x3d, NvEvoVRAM_LP, 0, 0x19,
-- 0, dev_priv->vram_size, 0x00000000);
-- if (ret) {
-- nv50_evo_channel_del(&dev_priv->evo);
-- return ret;
-- }
-- } else {
-- ret = nv50_evo_dmaobj_new(evo, 0x3d, NvEvoFB16, 0x70, 0x19,
-- 0, 0xffffffff, 0x00010000);
-- if (ret) {
-- nv50_evo_channel_del(&dev_priv->evo);
-- return ret;
-- }
-+ ret = nv50_evo_dmaobj_new(disp->master, NvEvoFB32, 0x80000000 |
-+ (dev_priv->chipset < 0xc0 ? 0x7a00 : 0xfe00),
-+ 0, dev_priv->vram_size, NULL);
-+ if (ret)
-+ goto err;
-
-+ ret = nv50_evo_dmaobj_new(disp->master, NvEvoFB16, 0x80000000 |
-+ (dev_priv->chipset < 0xc0 ? 0x7000 : 0xfe00),
-+ 0, dev_priv->vram_size, NULL);
-+ if (ret)
-+ goto err;
-
-- ret = nv50_evo_dmaobj_new(evo, 0x3d, NvEvoFB32, 0x7a, 0x19,
-- 0, 0xffffffff, 0x00010000);
-- if (ret) {
-- nv50_evo_channel_del(&dev_priv->evo);
-- return ret;
-- }
-+ /* create "display sync" channels and other structures we need
-+ * to implement page flipping
-+ */
-+ for (i = 0; i < 2; i++) {
-+ struct nv50_display_crtc *dispc = &disp->crtc[i];
-+ u64 offset;
-
-- ret = nv50_evo_dmaobj_new(evo, 0x3d, NvEvoVRAM, 0, 0x19,
-- 0, dev_priv->vram_size, 0x00010000);
-- if (ret) {
-- nv50_evo_channel_del(&dev_priv->evo);
-- return ret;
-+ ret = nv50_evo_channel_new(dev, 1 + i, &dispc->sync);
-+ if (ret)
-+ goto err;
-+
-+ ret = nouveau_bo_new(dev, NULL, 4096, 0x1000, TTM_PL_FLAG_VRAM,
-+ 0, 0x0000, &dispc->sem.bo);
-+ if (!ret) {
-+ offset = dispc->sem.bo->bo.mem.start << PAGE_SHIFT;
-+
-+ ret = nouveau_bo_pin(dispc->sem.bo, TTM_PL_FLAG_VRAM);
-+ if (!ret)
-+ ret = nouveau_bo_map(dispc->sem.bo);
-+ if (ret)
-+ nouveau_bo_ref(NULL, &dispc->sem.bo);
- }
-
-- ret = nv50_evo_dmaobj_new(evo, 0x3d, NvEvoVRAM_LP, 0, 0x19,
-- 0, dev_priv->vram_size, 0x00010000);
-- if (ret) {
-- nv50_evo_channel_del(&dev_priv->evo);
-- return ret;
-- }
-+ if (ret)
-+ goto err;
-+
-+ ret = nv50_evo_dmaobj_new(dispc->sync, NvEvoSync, 0x0000,
-+ offset, 4096, NULL);
-+ if (ret)
-+ goto err;
-+
-+ ret = nv50_evo_dmaobj_new(dispc->sync, NvEvoVRAM_LP, 0x80000000,
-+ 0, dev_priv->vram_size, NULL);
-+ if (ret)
-+ goto err;
-+
-+ ret = nv50_evo_dmaobj_new(dispc->sync, NvEvoFB32, 0x80000000 |
-+ (dev_priv->chipset < 0xc0 ?
-+ 0x7a00 : 0xfe00),
-+ 0, dev_priv->vram_size, NULL);
-+ if (ret)
-+ goto err;
-+
-+ ret = nv50_evo_dmaobj_new(dispc->sync, NvEvoFB16, 0x80000000 |
-+ (dev_priv->chipset < 0xc0 ?
-+ 0x7000 : 0xfe00),
-+ 0, dev_priv->vram_size, NULL);
-+ if (ret)
-+ goto err;
-+
-+ for (j = 0; j < 4096; j += 4)
-+ nouveau_bo_wr32(dispc->sem.bo, j / 4, 0x74b1e000);
-+ dispc->sem.offset = 0;
- }
-
- return 0;
-+
-+err:
-+ nv50_evo_destroy(dev);
-+ return ret;
- }
-
- int
- nv50_evo_init(struct drm_device *dev)
- {
-- struct drm_nouveau_private *dev_priv = dev->dev_private;
-- int ret;
-+ struct nv50_display *disp = nv50_display(dev);
-+ int ret, i;
-
-- if (!dev_priv->evo) {
-+ if (!disp->master) {
- ret = nv50_evo_create(dev);
- if (ret)
- return ret;
- }
-
-- return nv50_evo_channel_init(dev_priv->evo);
-+ ret = nv50_evo_channel_init(disp->master);
-+ if (ret)
-+ return ret;
-+
-+ for (i = 0; i < 2; i++) {
-+ ret = nv50_evo_channel_init(disp->crtc[i].sync);
-+ if (ret)
-+ return ret;
-+ }
-+
-+ return 0;
- }
-
- void
- nv50_evo_fini(struct drm_device *dev)
- {
-- struct drm_nouveau_private *dev_priv = dev->dev_private;
-+ struct nv50_display *disp = nv50_display(dev);
-+ int i;
-
-- if (dev_priv->evo) {
-- nv50_evo_channel_fini(dev_priv->evo);
-- nv50_evo_channel_del(&dev_priv->evo);
-+ for (i = 0; i < 2; i++) {
-+ if (disp->crtc[i].sync)
-+ nv50_evo_channel_fini(disp->crtc[i].sync);
- }
-+
-+ if (disp->master)
-+ nv50_evo_channel_fini(disp->master);
-+
-+ nv50_evo_destroy(dev);
- }
-diff --git a/drivers/gpu/drm/nouveau/nv50_evo.h b/drivers/gpu/drm/nouveau/nv50_evo.h
-index aa4f0d3..3860ca6 100644
---- a/drivers/gpu/drm/nouveau/nv50_evo.h
-+++ b/drivers/gpu/drm/nouveau/nv50_evo.h
-@@ -27,12 +27,6 @@
- #ifndef __NV50_EVO_H__
- #define __NV50_EVO_H__
-
--int nv50_evo_init(struct drm_device *dev);
--void nv50_evo_fini(struct drm_device *dev);
--int nv50_evo_dmaobj_new(struct nouveau_channel *, u32 class, u32 name,
-- u32 tile_flags, u32 magic_flags,
-- u32 offset, u32 limit);
--
- #define NV50_EVO_UPDATE 0x00000080
- #define NV50_EVO_UNK84 0x00000084
- #define NV50_EVO_UNK84_NOTIFY 0x40000000
-@@ -119,5 +113,7 @@ int nv50_evo_dmaobj_new(struct nouveau_channel *, u32 class, u32
name,
- /* Both of these are needed, otherwise nothing happens. */
- #define NV50_EVO_CRTC_SCALE_RES1 0x000008d8
- #define NV50_EVO_CRTC_SCALE_RES2 0x000008dc
-+#define NV50_EVO_CRTC_UNK900 0x00000900
-+#define NV50_EVO_CRTC_UNK904 0x00000904
-
- #endif
-diff --git a/drivers/gpu/drm/nouveau/nv50_fb.c b/drivers/gpu/drm/nouveau/nv50_fb.c
-index 50290de..ddebd71 100644
---- a/drivers/gpu/drm/nouveau/nv50_fb.c
-+++ b/drivers/gpu/drm/nouveau/nv50_fb.c
-@@ -8,31 +8,61 @@ struct nv50_fb_priv {
- dma_addr_t r100c08;
- };
-
-+static void
-+nv50_fb_destroy(struct drm_device *dev)
-+{
-+ struct drm_nouveau_private *dev_priv = dev->dev_private;
-+ struct nouveau_fb_engine *pfb = &dev_priv->engine.fb;
-+ struct nv50_fb_priv *priv = pfb->priv;
-+
-+ if (pfb->tag_heap.free_stack.next)
-+ drm_mm_takedown(&pfb->tag_heap);
-+
-+ if (priv->r100c08_page) {
-+ pci_unmap_page(dev->pdev, priv->r100c08, PAGE_SIZE,
-+ PCI_DMA_BIDIRECTIONAL);
-+ __free_page(priv->r100c08_page);
-+ }
-+
-+ kfree(priv);
-+ pfb->priv = NULL;
-+}
-+
- static int
- nv50_fb_create(struct drm_device *dev)
- {
- struct drm_nouveau_private *dev_priv = dev->dev_private;
-+ struct nouveau_fb_engine *pfb = &dev_priv->engine.fb;
- struct nv50_fb_priv *priv;
-+ u32 tagmem;
-+ int ret;
-
- priv = kzalloc(sizeof(*priv), GFP_KERNEL);
- if (!priv)
- return -ENOMEM;
-+ pfb->priv = priv;
-
- priv->r100c08_page = alloc_page(GFP_KERNEL | __GFP_ZERO);
- if (!priv->r100c08_page) {
-- kfree(priv);
-+ nv50_fb_destroy(dev);
- return -ENOMEM;
- }
-
- priv->r100c08 = pci_map_page(dev->pdev, priv->r100c08_page, 0,
- PAGE_SIZE, PCI_DMA_BIDIRECTIONAL);
- if (pci_dma_mapping_error(dev->pdev, priv->r100c08)) {
-- __free_page(priv->r100c08_page);
-- kfree(priv);
-+ nv50_fb_destroy(dev);
- return -EFAULT;
- }
-
-- dev_priv->engine.fb.priv = priv;
-+ tagmem = nv_rd32(dev, 0x100320);
-+ NV_DEBUG(dev, "%d tags available\n", tagmem);
-+ ret = drm_mm_init(&pfb->tag_heap, 0, tagmem);
-+ if (ret) {
-+ nv50_fb_destroy(dev);
-+ return ret;
-+ }
-+
- return 0;
- }
-
-@@ -81,26 +111,112 @@ nv50_fb_init(struct drm_device *dev)
- void
- nv50_fb_takedown(struct drm_device *dev)
- {
-- struct drm_nouveau_private *dev_priv = dev->dev_private;
-- struct nv50_fb_priv *priv;
-+ nv50_fb_destroy(dev);
-+}
-
-- priv = dev_priv->engine.fb.priv;
-- if (!priv)
-- return;
-- dev_priv->engine.fb.priv = NULL;
-+static struct nouveau_enum vm_dispatch_subclients[] = {
-+ { 0x00000000, "GRCTX", NULL },
-+ { 0x00000001, "NOTIFY", NULL },
-+ { 0x00000002, "QUERY", NULL },
-+ { 0x00000003, "COND", NULL },
-+ { 0x00000004, "M2M_IN", NULL },
-+ { 0x00000005, "M2M_OUT", NULL },
-+ { 0x00000006, "M2M_NOTIFY", NULL },
-+ {}
-+};
-
-- pci_unmap_page(dev->pdev, priv->r100c08, PAGE_SIZE,
-- PCI_DMA_BIDIRECTIONAL);
-- __free_page(priv->r100c08_page);
-- kfree(priv);
--}
-+static struct nouveau_enum vm_ccache_subclients[] = {
-+ { 0x00000000, "CB", NULL },
-+ { 0x00000001, "TIC", NULL },
-+ { 0x00000002, "TSC", NULL },
-+ {}
-+};
-+
-+static struct nouveau_enum vm_prop_subclients[] = {
-+ { 0x00000000, "RT0", NULL },
-+ { 0x00000001, "RT1", NULL },
-+ { 0x00000002, "RT2", NULL },
-+ { 0x00000003, "RT3", NULL },
-+ { 0x00000004, "RT4", NULL },
-+ { 0x00000005, "RT5", NULL },
-+ { 0x00000006, "RT6", NULL },
-+ { 0x00000007, "RT7", NULL },
-+ { 0x00000008, "ZETA", NULL },
-+ { 0x00000009, "LOCAL", NULL },
-+ { 0x0000000a, "GLOBAL", NULL },
-+ { 0x0000000b, "STACK", NULL },
-+ { 0x0000000c, "DST2D", NULL },
-+ {}
-+};
-+
-+static struct nouveau_enum vm_pfifo_subclients[] = {
-+ { 0x00000000, "PUSHBUF", NULL },
-+ { 0x00000001, "SEMAPHORE", NULL },
-+ {}
-+};
-+
-+static struct nouveau_enum vm_bar_subclients[] = {
-+ { 0x00000000, "FB", NULL },
-+ { 0x00000001, "IN", NULL },
-+ {}
-+};
-+
-+static struct nouveau_enum vm_client[] = {
-+ { 0x00000000, "STRMOUT", NULL },
-+ { 0x00000003, "DISPATCH", vm_dispatch_subclients },
-+ { 0x00000004, "PFIFO_WRITE", NULL },
-+ { 0x00000005, "CCACHE", vm_ccache_subclients },
-+ { 0x00000006, "PPPP", NULL },
-+ { 0x00000007, "CLIPID", NULL },
-+ { 0x00000008, "PFIFO_READ", NULL },
-+ { 0x00000009, "VFETCH", NULL },
-+ { 0x0000000a, "TEXTURE", NULL },
-+ { 0x0000000b, "PROP", vm_prop_subclients },
-+ { 0x0000000c, "PVP", NULL },
-+ { 0x0000000d, "PBSP", NULL },
-+ { 0x0000000e, "PCRYPT", NULL },
-+ { 0x0000000f, "PCOUNTER", NULL },
-+ { 0x00000011, "PDAEMON", NULL },
-+ {}
-+};
-+
-+static struct nouveau_enum vm_engine[] = {
-+ { 0x00000000, "PGRAPH", NULL },
-+ { 0x00000001, "PVP", NULL },
-+ { 0x00000004, "PEEPHOLE", NULL },
-+ { 0x00000005, "PFIFO", vm_pfifo_subclients },
-+ { 0x00000006, "BAR", vm_bar_subclients },
-+ { 0x00000008, "PPPP", NULL },
-+ { 0x00000009, "PBSP", NULL },
-+ { 0x0000000a, "PCRYPT", NULL },
-+ { 0x0000000b, "PCOUNTER", NULL },
-+ { 0x0000000c, "SEMAPHORE_BG", NULL },
-+ { 0x0000000d, "PCOPY", NULL },
-+ { 0x0000000e, "PDAEMON", NULL },
-+ {}
-+};
-+
-+static struct nouveau_enum vm_fault[] = {
-+ { 0x00000000, "PT_NOT_PRESENT", NULL },
-+ { 0x00000001, "PT_TOO_SHORT", NULL },
-+ { 0x00000002, "PAGE_NOT_PRESENT", NULL },
-+ { 0x00000003, "PAGE_SYSTEM_ONLY", NULL },
-+ { 0x00000004, "PAGE_READ_ONLY", NULL },
-+ { 0x00000006, "NULL_DMAOBJ", NULL },
-+ { 0x00000007, "WRONG_MEMTYPE", NULL },
-+ { 0x0000000b, "VRAM_LIMIT", NULL },
-+ { 0x0000000f, "DMAOBJ_LIMIT", NULL },
-+ {}
-+};
-
- void
--nv50_fb_vm_trap(struct drm_device *dev, int display, const char *name)
-+nv50_fb_vm_trap(struct drm_device *dev, int display)
- {
- struct drm_nouveau_private *dev_priv = dev->dev_private;
-+ const struct nouveau_enum *en, *cl;
- unsigned long flags;
- u32 trap[6], idx, chinst;
-+ u8 st0, st1, st2, st3;
- int i, ch;
-
- idx = nv_rd32(dev, 0x100c90);
-@@ -117,8 +233,8 @@ nv50_fb_vm_trap(struct drm_device *dev, int display, const char
*name)
- if (!display)
- return;
-
-+ /* lookup channel id */
- chinst = (trap[2] << 16) | trap[1];
--
- spin_lock_irqsave(&dev_priv->channels.lock, flags);
- for (ch = 0; ch < dev_priv->engine.fifo.channels; ch++) {
- struct nouveau_channel *chan = dev_priv->channels.ptr[ch];
-@@ -131,9 +247,48 @@ nv50_fb_vm_trap(struct drm_device *dev, int display, const char
*name)
- }
- spin_unlock_irqrestore(&dev_priv->channels.lock, flags);
-
-- NV_INFO(dev, "%s - VM: Trapped %s at %02x%04x%04x status %08x "
-- "channel %d (0x%08x)\n",
-- name, (trap[5] & 0x100 ? "read" : "write"),
-- trap[5] & 0xff, trap[4] & 0xffff, trap[3] & 0xffff,
-- trap[0], ch, chinst);
-+ /* decode status bits into something more useful */
-+ if (dev_priv->chipset < 0xa3 ||
-+ dev_priv->chipset == 0xaa || dev_priv->chipset == 0xac) {
-+ st0 = (trap[0] & 0x0000000f) >> 0;
-+ st1 = (trap[0] & 0x000000f0) >> 4;
-+ st2 = (trap[0] & 0x00000f00) >> 8;
-+ st3 = (trap[0] & 0x0000f000) >> 12;
-+ } else {
-+ st0 = (trap[0] & 0x000000ff) >> 0;
-+ st1 = (trap[0] & 0x0000ff00) >> 8;
-+ st2 = (trap[0] & 0x00ff0000) >> 16;
-+ st3 = (trap[0] & 0xff000000) >> 24;
-+ }
-+
-+ NV_INFO(dev, "VM: trapped %s at 0x%02x%04x%04x on ch %d [0x%08x] ",
-+ (trap[5] & 0x00000100) ? "read" : "write",
-+ trap[5] & 0xff, trap[4] & 0xffff, trap[3] & 0xffff, ch, chinst);
-+
-+ en = nouveau_enum_find(vm_engine, st0);
-+ if (en)
-+ printk("%s/", en->name);
-+ else
-+ printk("%02x/", st0);
-+
-+ cl = nouveau_enum_find(vm_client, st2);
-+ if (cl)
-+ printk("%s/", cl->name);
-+ else
-+ printk("%02x/", st2);
-+
-+ if (cl && cl->data) cl = nouveau_enum_find(cl->data, st3);
-+ else if (en && en->data) cl = nouveau_enum_find(en->data, st3);
-+ else cl = NULL;
-+ if (cl)
-+ printk("%s", cl->name);
-+ else
-+ printk("%02x", st3);
-+
-+ printk(" reason: ");
-+ en = nouveau_enum_find(vm_fault, st1);
-+ if (en)
-+ printk("%s\n", en->name);
-+ else
-+ printk("0x%08x\n", st1);
- }
-diff --git a/drivers/gpu/drm/nouveau/nv50_fifo.c b/drivers/gpu/drm/nouveau/nv50_fifo.c
-index 8dd04c5..c34a074 100644
---- a/drivers/gpu/drm/nouveau/nv50_fifo.c
-+++ b/drivers/gpu/drm/nouveau/nv50_fifo.c
-@@ -149,6 +149,7 @@ nv50_fifo_init_regs(struct drm_device *dev)
- nv_wr32(dev, 0x3204, 0);
- nv_wr32(dev, 0x3210, 0);
- nv_wr32(dev, 0x3270, 0);
-+ nv_wr32(dev, 0x2044, 0x01003fff);
-
- /* Enable dummy channels setup by nv50_instmem.c */
- nv50_fifo_channel_enable(dev, 0);
-@@ -273,7 +274,7 @@ nv50_fifo_create_context(struct nouveau_channel *chan)
- nv_wo32(ramfc, 0x80, ((chan->ramht->bits - 9) << 27) |
- (4 << 24) /* SEARCH_FULL */ |
- (chan->ramht->gpuobj->cinst >> 4));
-- nv_wo32(ramfc, 0x44, 0x2101ffff);
-+ nv_wo32(ramfc, 0x44, 0x01003fff);
- nv_wo32(ramfc, 0x60, 0x7fffffff);
- nv_wo32(ramfc, 0x40, 0x00000000);
- nv_wo32(ramfc, 0x7c, 0x30000001);
-diff --git a/drivers/gpu/drm/nouveau/nv50_gpio.c b/drivers/gpu/drm/nouveau/nv50_gpio.c
-index 6b149c0..d4f4206 100644
---- a/drivers/gpu/drm/nouveau/nv50_gpio.c
-+++ b/drivers/gpu/drm/nouveau/nv50_gpio.c
-@@ -137,6 +137,7 @@ nv50_gpio_irq_unregister(struct drm_device *dev, enum dcb_gpio_tag
tag,
- struct nv50_gpio_priv *priv = pgpio->priv;
- struct nv50_gpio_handler *gpioh, *tmp;
- struct dcb_gpio_entry *gpio;
-+ LIST_HEAD(tofree);
- unsigned long flags;
-
- gpio = nouveau_bios_gpio_entry(dev, tag);
-@@ -149,10 +150,14 @@ nv50_gpio_irq_unregister(struct drm_device *dev, enum dcb_gpio_tag
tag,
- gpioh->handler != handler ||
- gpioh->data != data)
- continue;
-- list_del(&gpioh->head);
-- kfree(gpioh);
-+ list_move(&gpioh->head, &tofree);
- }
- spin_unlock_irqrestore(&priv->lock, flags);
-+
-+ list_for_each_entry_safe(gpioh, tmp, &tofree, head) {
-+ flush_work_sync(&gpioh->work);
-+ kfree(gpioh);
-+ }
- }
-
- bool
-@@ -205,7 +210,6 @@ nv50_gpio_init(struct drm_device *dev)
- {
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_gpio_engine *pgpio = &dev_priv->engine.gpio;
-- struct nv50_gpio_priv *priv;
- int ret;
-
- if (!pgpio->priv) {
-@@ -213,7 +217,6 @@ nv50_gpio_init(struct drm_device *dev)
- if (ret)
- return ret;
- }
-- priv = pgpio->priv;
-
- /* disable, and ack any pending gpio interrupts */
- nv_wr32(dev, 0xe050, 0x00000000);
-@@ -293,7 +296,7 @@ nv50_gpio_isr(struct drm_device *dev)
- continue;
- gpioh->inhibit = true;
-
-- queue_work(dev_priv->wq, &gpioh->work);
-+ schedule_work(&gpioh->work);
- }
- spin_unlock(&priv->lock);
- }
-diff --git a/drivers/gpu/drm/nouveau/nv50_graph.c b/drivers/gpu/drm/nouveau/nv50_graph.c
-index 37e21d2..7950bac 100644
---- a/drivers/gpu/drm/nouveau/nv50_graph.c
-+++ b/drivers/gpu/drm/nouveau/nv50_graph.c
-@@ -95,13 +95,41 @@ nv50_graph_init_regs__nv(struct drm_device *dev)
- }
-
- static void
--nv50_graph_init_regs(struct drm_device *dev)
-+nv50_graph_init_zcull(struct drm_device *dev)
- {
-+ struct drm_nouveau_private *dev_priv = dev->dev_private;
-+ int i;
-+
- NV_DEBUG(dev, "\n");
-
-- nv_wr32(dev, NV04_PGRAPH_DEBUG_3,
-- (1 << 2) /* HW_CONTEXT_SWITCH_ENABLED */);
-- nv_wr32(dev, 0x402ca8, 0x800);
-+ switch (dev_priv->chipset & 0xf0) {
-+ case 0x50:
-+ case 0x80:
-+ case 0x90:
-+ nv_wr32(dev, 0x402ca8, 0x00000800);
-+ break;
-+ case 0xa0:
-+ default:
-+ nv_wr32(dev, 0x402cc0, 0x00000000);
-+ if (dev_priv->chipset == 0xa0 ||
-+ dev_priv->chipset == 0xaa ||
-+ dev_priv->chipset == 0xac) {
-+ nv_wr32(dev, 0x402ca8, 0x00000802);
-+ } else {
-+ nv_wr32(dev, 0x402cc0, 0x00000000);
-+ nv_wr32(dev, 0x402ca8, 0x00000002);
-+ }
-+
-+ break;
-+ }
-+
-+ /* zero out zcull regions */
-+ for (i = 0; i < 8; i++) {
-+ nv_wr32(dev, 0x402c20 + (i * 8), 0x00000000);
-+ nv_wr32(dev, 0x402c24 + (i * 8), 0x00000000);
-+ nv_wr32(dev, 0x402c28 + (i * 8), 0x00000000);
-+ nv_wr32(dev, 0x402c2c + (i * 8), 0x00000000);
-+ }
- }
-
- static int
-@@ -136,6 +164,7 @@ nv50_graph_init_ctxctl(struct drm_device *dev)
- }
- kfree(cp);
-
-+ nv_wr32(dev, 0x40008c, 0x00000004); /* HW_CTX_SWITCH_ENABLED */
- nv_wr32(dev, 0x400320, 4);
- nv_wr32(dev, NV40_PGRAPH_CTXCTL_CUR, 0);
- nv_wr32(dev, NV20_PGRAPH_CHANNEL_CTX_POINTER, 0);
-@@ -151,7 +180,7 @@ nv50_graph_init(struct drm_device *dev)
-
- nv50_graph_init_reset(dev);
- nv50_graph_init_regs__nv(dev);
-- nv50_graph_init_regs(dev);
-+ nv50_graph_init_zcull(dev);
-
- ret = nv50_graph_init_ctxctl(dev);
- if (ret)
-@@ -409,12 +438,7 @@ static int
- nv50_graph_nvsw_mthd_page_flip(struct nouveau_channel *chan,
- u32 class, u32 mthd, u32 data)
- {
-- struct nouveau_page_flip_state s;
--
-- if (!nouveau_finish_page_flip(chan, &s)) {
-- /* XXX - Do something here */
-- }
--
-+ nouveau_finish_page_flip(chan, NULL);
- return 0;
- }
-
-@@ -479,7 +503,7 @@ nv50_graph_tlb_flush(struct drm_device *dev)
- }
-
- void
--nv86_graph_tlb_flush(struct drm_device *dev)
-+nv84_graph_tlb_flush(struct drm_device *dev)
- {
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_timer_engine *ptimer = &dev_priv->engine.timer;
-@@ -524,13 +548,12 @@ nv86_graph_tlb_flush(struct drm_device *dev)
- spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags);
- }
-
--static struct nouveau_enum nv50_mp_exec_error_names[] =
--{
-- { 3, "STACK_UNDERFLOW" },
-- { 4, "QUADON_ACTIVE" },
-- { 8, "TIMEOUT" },
-- { 0x10, "INVALID_OPCODE" },
-- { 0x40, "BREAKPOINT" },
-+static struct nouveau_enum nv50_mp_exec_error_names[] = {
-+ { 3, "STACK_UNDERFLOW", NULL },
-+ { 4, "QUADON_ACTIVE", NULL },
-+ { 8, "TIMEOUT", NULL },
-+ { 0x10, "INVALID_OPCODE", NULL },
-+ { 0x40, "BREAKPOINT", NULL },
- {}
- };
-
-@@ -558,47 +581,47 @@ static struct nouveau_bitfield nv50_graph_trap_ccache[] = {
-
- /* There must be a *lot* of these. Will take some time to gather them up. */
- struct nouveau_enum nv50_data_error_names[] = {
-- { 0x00000003, "INVALID_QUERY_OR_TEXTURE" },
-- { 0x00000004, "INVALID_VALUE" },
-- { 0x00000005, "INVALID_ENUM" },
-- { 0x00000008, "INVALID_OBJECT" },
-- { 0x00000009, "READ_ONLY_OBJECT" },
-- { 0x0000000a, "SUPERVISOR_OBJECT" },
-- { 0x0000000b, "INVALID_ADDRESS_ALIGNMENT" },
-- { 0x0000000c, "INVALID_BITFIELD" },
-- { 0x0000000d, "BEGIN_END_ACTIVE" },
-- { 0x0000000e, "SEMANTIC_COLOR_BACK_OVER_LIMIT" },
-- { 0x0000000f, "VIEWPORT_ID_NEEDS_GP" },
-- { 0x00000010, "RT_DOUBLE_BIND" },
-- { 0x00000011, "RT_TYPES_MISMATCH" },
-- { 0x00000012, "RT_LINEAR_WITH_ZETA" },
-- { 0x00000015, "FP_TOO_FEW_REGS" },
-- { 0x00000016, "ZETA_FORMAT_CSAA_MISMATCH" },
-- { 0x00000017, "RT_LINEAR_WITH_MSAA" },
-- { 0x00000018, "FP_INTERPOLANT_START_OVER_LIMIT" },
-- { 0x00000019, "SEMANTIC_LAYER_OVER_LIMIT" },
-- { 0x0000001a, "RT_INVALID_ALIGNMENT" },
-- { 0x0000001b, "SAMPLER_OVER_LIMIT" },
-- { 0x0000001c, "TEXTURE_OVER_LIMIT" },
-- { 0x0000001e, "GP_TOO_MANY_OUTPUTS" },
-- { 0x0000001f, "RT_BPP128_WITH_MS8" },
-- { 0x00000021, "Z_OUT_OF_BOUNDS" },
-- { 0x00000023, "XY_OUT_OF_BOUNDS" },
-- { 0x00000027, "CP_MORE_PARAMS_THAN_SHARED" },
-- { 0x00000028, "CP_NO_REG_SPACE_STRIPED" },
-- { 0x00000029, "CP_NO_REG_SPACE_PACKED" },
-- { 0x0000002a, "CP_NOT_ENOUGH_WARPS" },
-- { 0x0000002b, "CP_BLOCK_SIZE_MISMATCH" },
-- { 0x0000002c, "CP_NOT_ENOUGH_LOCAL_WARPS" },
-- { 0x0000002d, "CP_NOT_ENOUGH_STACK_WARPS" },
-- { 0x0000002e, "CP_NO_BLOCKDIM_LATCH" },
-- { 0x00000031, "ENG2D_FORMAT_MISMATCH" },
-- { 0x0000003f, "PRIMITIVE_ID_NEEDS_GP" },
-- { 0x00000044, "SEMANTIC_VIEWPORT_OVER_LIMIT" },
-- { 0x00000045, "SEMANTIC_COLOR_FRONT_OVER_LIMIT" },
-- { 0x00000046, "LAYER_ID_NEEDS_GP" },
-- { 0x00000047, "SEMANTIC_CLIP_OVER_LIMIT" },
-- { 0x00000048, "SEMANTIC_PTSZ_OVER_LIMIT" },
-+ { 0x00000003, "INVALID_QUERY_OR_TEXTURE", NULL },
-+ { 0x00000004, "INVALID_VALUE", NULL },
-+ { 0x00000005, "INVALID_ENUM", NULL },
-+ { 0x00000008, "INVALID_OBJECT", NULL },
-+ { 0x00000009, "READ_ONLY_OBJECT", NULL },
-+ { 0x0000000a, "SUPERVISOR_OBJECT", NULL },
-+ { 0x0000000b, "INVALID_ADDRESS_ALIGNMENT", NULL },
-+ { 0x0000000c, "INVALID_BITFIELD", NULL },
-+ { 0x0000000d, "BEGIN_END_ACTIVE", NULL },
-+ { 0x0000000e, "SEMANTIC_COLOR_BACK_OVER_LIMIT", NULL },
-+ { 0x0000000f, "VIEWPORT_ID_NEEDS_GP", NULL },
-+ { 0x00000010, "RT_DOUBLE_BIND", NULL },
-+ { 0x00000011, "RT_TYPES_MISMATCH", NULL },
-+ { 0x00000012, "RT_LINEAR_WITH_ZETA", NULL },
-+ { 0x00000015, "FP_TOO_FEW_REGS", NULL },
-+ { 0x00000016, "ZETA_FORMAT_CSAA_MISMATCH", NULL },
-+ { 0x00000017, "RT_LINEAR_WITH_MSAA", NULL },
-+ { 0x00000018, "FP_INTERPOLANT_START_OVER_LIMIT", NULL },
-+ { 0x00000019, "SEMANTIC_LAYER_OVER_LIMIT", NULL },
-+ { 0x0000001a, "RT_INVALID_ALIGNMENT", NULL },
-+ { 0x0000001b, "SAMPLER_OVER_LIMIT", NULL },
-+ { 0x0000001c, "TEXTURE_OVER_LIMIT", NULL },
-+ { 0x0000001e, "GP_TOO_MANY_OUTPUTS", NULL },
-+ { 0x0000001f, "RT_BPP128_WITH_MS8", NULL },
-+ { 0x00000021, "Z_OUT_OF_BOUNDS", NULL },
-+ { 0x00000023, "XY_OUT_OF_BOUNDS", NULL },
-+ { 0x00000027, "CP_MORE_PARAMS_THAN_SHARED", NULL },
-+ { 0x00000028, "CP_NO_REG_SPACE_STRIPED", NULL },
-+ { 0x00000029, "CP_NO_REG_SPACE_PACKED", NULL },
-+ { 0x0000002a, "CP_NOT_ENOUGH_WARPS", NULL },
-+ { 0x0000002b, "CP_BLOCK_SIZE_MISMATCH", NULL },
-+ { 0x0000002c, "CP_NOT_ENOUGH_LOCAL_WARPS", NULL },
-+ { 0x0000002d, "CP_NOT_ENOUGH_STACK_WARPS", NULL },
-+ { 0x0000002e, "CP_NO_BLOCKDIM_LATCH", NULL },
-+ { 0x00000031, "ENG2D_FORMAT_MISMATCH", NULL },
-+ { 0x0000003f, "PRIMITIVE_ID_NEEDS_GP", NULL },
-+ { 0x00000044, "SEMANTIC_VIEWPORT_OVER_LIMIT", NULL },
-+ { 0x00000045, "SEMANTIC_COLOR_FRONT_OVER_LIMIT", NULL },
-+ { 0x00000046, "LAYER_ID_NEEDS_GP", NULL },
-+ { 0x00000047, "SEMANTIC_CLIP_OVER_LIMIT", NULL },
-+ { 0x00000048, "SEMANTIC_PTSZ_OVER_LIMIT", NULL },
- {}
- };
-
-@@ -639,7 +662,7 @@ nv50_pgraph_mp_trap(struct drm_device *dev, int tpid, int display)
- nv_rd32(dev, addr + 0x20);
- pc = nv_rd32(dev, addr + 0x24);
- oplow = nv_rd32(dev, addr + 0x70);
-- ophigh= nv_rd32(dev, addr + 0x74);
-+ ophigh = nv_rd32(dev, addr + 0x74);
- NV_INFO(dev, "PGRAPH_TRAP_MP_EXEC - "
- "TP %d MP %d: ", tpid, i);
- nouveau_enum_print(nv50_mp_exec_error_names, status);
-@@ -678,7 +701,6 @@ nv50_pgraph_tp_trap(struct drm_device *dev, int type, uint32_t
ustatus_old,
- tps++;
- switch (type) {
- case 6: /* texture error... unknown for now */
-- nv50_fb_vm_trap(dev, display, name);
- if (display) {
- NV_ERROR(dev, "magic set %d:\n", i);
- for (r = ustatus_addr + 4; r <= ustatus_addr + 0x10; r += 4)
-@@ -701,7 +723,6 @@ nv50_pgraph_tp_trap(struct drm_device *dev, int type, uint32_t
ustatus_old,
- uint32_t e1c = nv_rd32(dev, ustatus_addr + 0x14);
- uint32_t e20 = nv_rd32(dev, ustatus_addr + 0x18);
- uint32_t e24 = nv_rd32(dev, ustatus_addr + 0x1c);
-- nv50_fb_vm_trap(dev, display, name);
- /* 2d engine destination */
- if (ustatus & 0x00000010) {
- if (display) {
-@@ -912,10 +933,10 @@ nv50_pgraph_trap_handler(struct drm_device *dev, u32 display, u64
inst, u32 chid
- printk("\n");
- NV_INFO(dev, "PGRAPH - TRAP_CCACHE %08x %08x %08x %08x"
- " %08x %08x %08x\n",
-- nv_rd32(dev, 0x405800), nv_rd32(dev, 0x405804),
-- nv_rd32(dev, 0x405808), nv_rd32(dev, 0x40580c),
-- nv_rd32(dev, 0x405810), nv_rd32(dev, 0x405814),
-- nv_rd32(dev, 0x40581c));
-+ nv_rd32(dev, 0x405000), nv_rd32(dev, 0x405004),
-+ nv_rd32(dev, 0x405008), nv_rd32(dev, 0x40500c),
-+ nv_rd32(dev, 0x405010), nv_rd32(dev, 0x405014),
-+ nv_rd32(dev, 0x40501c));
-
- }
-
-@@ -1044,6 +1065,7 @@ nv50_graph_isr(struct drm_device *dev)
- NV_INFO(dev, "PGRAPH - ch %d (0x%010llx) subc %d "
- "class 0x%04x mthd 0x%04x data 0x%08x\n",
- chid, inst, subc, class, mthd, data);
-+ nv50_fb_vm_trap(dev, 1);
- }
- }
-
-diff --git a/drivers/gpu/drm/nouveau/nv50_grctx.c b/drivers/gpu/drm/nouveau/nv50_grctx.c
-index 336aab2..de9abff 100644
---- a/drivers/gpu/drm/nouveau/nv50_grctx.c
-+++ b/drivers/gpu/drm/nouveau/nv50_grctx.c
-@@ -747,7 +747,7 @@ nv50_graph_construct_mmio(struct nouveau_grctx *ctx)
- gr_def(ctx, offset + 0x64, 0x0000001f);
- gr_def(ctx, offset + 0x68, 0x0000000f);
- gr_def(ctx, offset + 0x6c, 0x0000000f);
-- } else if(dev_priv->chipset < 0xa0) {
-+ } else if (dev_priv->chipset < 0xa0) {
- cp_ctx(ctx, offset + 0x50, 1);
- cp_ctx(ctx, offset + 0x70, 1);
- } else {
-@@ -924,7 +924,7 @@ nv50_graph_construct_mmio_ddata(struct nouveau_grctx *ctx)
- dd_emit(ctx, 1, 0); /* 0000007f MULTISAMPLE_SAMPLES_LOG2 */
- } else {
- dd_emit(ctx, 1, 0); /* 0000000f MULTISAMPLE_SAMPLES_LOG2 */
-- }
-+ }
- dd_emit(ctx, 1, 0xc); /* 000000ff SEMANTIC_COLOR.BFC0_ID */
- if (dev_priv->chipset != 0x50)
- dd_emit(ctx, 1, 0); /* 00000001 SEMANTIC_COLOR.CLMP_EN */
-@@ -1803,9 +1803,7 @@ nv50_graph_construct_gene_unk24xx(struct nouveau_grctx *ctx)
- xf_emit(ctx, 1, 0); /* 1ff */
- xf_emit(ctx, 8, 0); /* 0? */
- xf_emit(ctx, 9, 0); /* ffffffff, 7ff */
-- }
-- else
-- {
-+ } else {
- xf_emit(ctx, 0xc, 0); /* RO */
- /* SEEK */
- xf_emit(ctx, 0xe10, 0); /* 190 * 9: 8*ffffffff, 7ff */
-@@ -2836,7 +2834,7 @@ nv50_graph_construct_xfer_tprop(struct nouveau_grctx *ctx)
- xf_emit(ctx, 1, 1); /* 00000001 DST_LINEAR */
- if (IS_NVA3F(dev_priv->chipset))
- xf_emit(ctx, 1, 1); /* 0000001f tesla UNK169C */
-- if(dev_priv->chipset == 0x50)
-+ if (dev_priv->chipset == 0x50)
- xf_emit(ctx, 1, 0); /* ff */
- else
- xf_emit(ctx, 3, 0); /* 1, 7, 3ff */
-diff --git a/drivers/gpu/drm/nouveau/nv50_instmem.c
b/drivers/gpu/drm/nouveau/nv50_instmem.c
-index e57caa2..993ad3f 100644
---- a/drivers/gpu/drm/nouveau/nv50_instmem.c
-+++ b/drivers/gpu/drm/nouveau/nv50_instmem.c
-@@ -300,7 +300,7 @@ nv50_instmem_resume(struct drm_device *dev)
- }
-
- struct nv50_gpuobj_node {
-- struct nouveau_vram *vram;
-+ struct nouveau_mem *vram;
- struct nouveau_vma chan_vma;
- u32 align;
- };
-@@ -404,23 +404,25 @@ void
- nv50_instmem_flush(struct drm_device *dev)
- {
- struct drm_nouveau_private *dev_priv = dev->dev_private;
-+ unsigned long flags;
-
-- spin_lock(&dev_priv->ramin_lock);
-+ spin_lock_irqsave(&dev_priv->vm_lock, flags);
- nv_wr32(dev, 0x00330c, 0x00000001);
- if (!nv_wait(dev, 0x00330c, 0x00000002, 0x00000000))
- NV_ERROR(dev, "PRAMIN flush timeout\n");
-- spin_unlock(&dev_priv->ramin_lock);
-+ spin_unlock_irqrestore(&dev_priv->vm_lock, flags);
- }
-
- void
- nv84_instmem_flush(struct drm_device *dev)
- {
- struct drm_nouveau_private *dev_priv = dev->dev_private;
-+ unsigned long flags;
-
-- spin_lock(&dev_priv->ramin_lock);
-+ spin_lock_irqsave(&dev_priv->vm_lock, flags);
- nv_wr32(dev, 0x070000, 0x00000001);
- if (!nv_wait(dev, 0x070000, 0x00000002, 0x00000000))
- NV_ERROR(dev, "PRAMIN flush timeout\n");
-- spin_unlock(&dev_priv->ramin_lock);
-+ spin_unlock_irqrestore(&dev_priv->vm_lock, flags);
- }
-
-diff --git a/drivers/gpu/drm/nouveau/nv50_sor.c b/drivers/gpu/drm/nouveau/nv50_sor.c
-index b4a5ecb..c25c593 100644
---- a/drivers/gpu/drm/nouveau/nv50_sor.c
-+++ b/drivers/gpu/drm/nouveau/nv50_sor.c
-@@ -41,8 +41,7 @@ nv50_sor_disconnect(struct drm_encoder *encoder)
- {
- struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
- struct drm_device *dev = encoder->dev;
-- struct drm_nouveau_private *dev_priv = dev->dev_private;
-- struct nouveau_channel *evo = dev_priv->evo;
-+ struct nouveau_channel *evo = nv50_display(dev)->master;
- int ret;
-
- if (!nv_encoder->crtc)
-@@ -184,8 +183,7 @@ static void
- nv50_sor_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode,
- struct drm_display_mode *adjusted_mode)
- {
-- struct drm_nouveau_private *dev_priv = encoder->dev->dev_private;
-- struct nouveau_channel *evo = dev_priv->evo;
-+ struct nouveau_channel *evo = nv50_display(encoder->dev)->master;
- struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
- struct drm_device *dev = encoder->dev;
- struct nouveau_crtc *crtc = nouveau_crtc(encoder->crtc);
-diff --git a/drivers/gpu/drm/nouveau/nv50_vm.c b/drivers/gpu/drm/nouveau/nv50_vm.c
-index 6144156..6c26944 100644
---- a/drivers/gpu/drm/nouveau/nv50_vm.c
-+++ b/drivers/gpu/drm/nouveau/nv50_vm.c
-@@ -31,7 +31,6 @@ void
- nv50_vm_map_pgt(struct nouveau_gpuobj *pgd, u32 pde,
- struct nouveau_gpuobj *pgt[2])
- {
-- struct drm_nouveau_private *dev_priv = pgd->dev->dev_private;
- u64 phys = 0xdeadcafe00000000ULL;
- u32 coverage = 0;
-
-@@ -58,10 +57,9 @@ nv50_vm_map_pgt(struct nouveau_gpuobj *pgd, u32 pde,
- }
-
- static inline u64
--nv50_vm_addr(struct nouveau_vma *vma, struct nouveau_gpuobj *pgt,
-- u64 phys, u32 memtype, u32 target)
-+nv50_vm_addr(struct nouveau_vma *vma, u64 phys, u32 memtype, u32 target)
- {
-- struct drm_nouveau_private *dev_priv = pgt->dev->dev_private;
-+ struct drm_nouveau_private *dev_priv = vma->vm->dev->dev_private;
-
- phys |= 1; /* present */
- phys |= (u64)memtype << 40;
-@@ -85,12 +83,13 @@ nv50_vm_addr(struct nouveau_vma *vma, struct nouveau_gpuobj *pgt,
-
- void
- nv50_vm_map(struct nouveau_vma *vma, struct nouveau_gpuobj *pgt,
-- struct nouveau_vram *mem, u32 pte, u32 cnt, u64 phys)
-+ struct nouveau_mem *mem, u32 pte, u32 cnt, u64 phys, u64 delta)
- {
-+ u32 comp = (mem->memtype & 0x180) >> 7;
- u32 block;
- int i;
-
-- phys = nv50_vm_addr(vma, pgt, phys, mem->memtype, 0);
-+ phys = nv50_vm_addr(vma, phys, mem->memtype, 0);
- pte <<= 3;
- cnt <<= 3;
-
-@@ -107,6 +106,11 @@ nv50_vm_map(struct nouveau_vma *vma, struct nouveau_gpuobj *pgt,
-
- phys += block << (vma->node->type - 3);
- cnt -= block;
-+ if (comp) {
-+ u32 tag = mem->tag->start + ((delta >> 16) * comp);
-+ offset_h |= (tag << 17);
-+ delta += block << (vma->node->type - 3);
-+ }
-
- while (block) {
- nv_wo32(pgt, pte + 0, offset_l);
-@@ -119,11 +123,11 @@ nv50_vm_map(struct nouveau_vma *vma, struct nouveau_gpuobj *pgt,
-
- void
- nv50_vm_map_sg(struct nouveau_vma *vma, struct nouveau_gpuobj *pgt,
-- u32 pte, dma_addr_t *list, u32 cnt)
-+ struct nouveau_mem *mem, u32 pte, u32 cnt, dma_addr_t *list)
- {
- pte <<= 3;
- while (cnt--) {
-- u64 phys = nv50_vm_addr(vma, pgt, (u64)*list++, 0, 2);
-+ u64 phys = nv50_vm_addr(vma, (u64)*list++, mem->memtype, 2);
- nv_wo32(pgt, pte + 0, lower_32_bits(phys));
- nv_wo32(pgt, pte + 4, upper_32_bits(phys));
- pte += 8;
-@@ -170,10 +174,11 @@ void
- nv50_vm_flush_engine(struct drm_device *dev, int engine)
- {
- struct drm_nouveau_private *dev_priv = dev->dev_private;
-+ unsigned long flags;
-
-- spin_lock(&dev_priv->ramin_lock);
-+ spin_lock_irqsave(&dev_priv->vm_lock, flags);
- nv_wr32(dev, 0x100c80, (engine << 16) | 1);
- if (!nv_wait(dev, 0x100c80, 0x00000001, 0x00000000))
- NV_ERROR(dev, "vm flush timeout: engine %d\n", engine);
-- spin_unlock(&dev_priv->ramin_lock);
-+ spin_unlock_irqrestore(&dev_priv->vm_lock, flags);
- }
-diff --git a/drivers/gpu/drm/nouveau/nv50_vram.c b/drivers/gpu/drm/nouveau/nv50_vram.c
-index 58e98ad..ffbc3d8 100644
---- a/drivers/gpu/drm/nouveau/nv50_vram.c
-+++ b/drivers/gpu/drm/nouveau/nv50_vram.c
-@@ -48,42 +48,49 @@ nv50_vram_flags_valid(struct drm_device *dev, u32 tile_flags)
- }
-
- void
--nv50_vram_del(struct drm_device *dev, struct nouveau_vram **pvram)
-+nv50_vram_del(struct drm_device *dev, struct nouveau_mem **pmem)
- {
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct ttm_bo_device *bdev = &dev_priv->ttm.bdev;
- struct ttm_mem_type_manager *man = &bdev->man[TTM_PL_VRAM];
- struct nouveau_mm *mm = man->priv;
- struct nouveau_mm_node *this;
-- struct nouveau_vram *vram;
-+ struct nouveau_mem *mem;
-
-- vram = *pvram;
-- *pvram = NULL;
-- if (unlikely(vram == NULL))
-+ mem = *pmem;
-+ *pmem = NULL;
-+ if (unlikely(mem == NULL))
- return;
-
- mutex_lock(&mm->mutex);
-- while (!list_empty(&vram->regions)) {
-- this = list_first_entry(&vram->regions, struct nouveau_mm_node, rl_entry);
-+ while (!list_empty(&mem->regions)) {
-+ this = list_first_entry(&mem->regions, struct nouveau_mm_node, rl_entry);
-
- list_del(&this->rl_entry);
- nouveau_mm_put(mm, this);
- }
-+
-+ if (mem->tag) {
-+ drm_mm_put_block(mem->tag);
-+ mem->tag = NULL;
-+ }
- mutex_unlock(&mm->mutex);
-
-- kfree(vram);
-+ kfree(mem);
- }
-
- int
- nv50_vram_new(struct drm_device *dev, u64 size, u32 align, u32 size_nc,
-- u32 type, struct nouveau_vram **pvram)
-+ u32 memtype, struct nouveau_mem **pmem)
- {
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct ttm_bo_device *bdev = &dev_priv->ttm.bdev;
- struct ttm_mem_type_manager *man = &bdev->man[TTM_PL_VRAM];
- struct nouveau_mm *mm = man->priv;
- struct nouveau_mm_node *r;
-- struct nouveau_vram *vram;
-+ struct nouveau_mem *mem;
-+ int comp = (memtype & 0x300) >> 8;
-+ int type = (memtype & 0x07f);
- int ret;
-
- if (!types[type])
-@@ -92,32 +99,46 @@ nv50_vram_new(struct drm_device *dev, u64 size, u32 align, u32
size_nc,
- align >>= 12;
- size_nc >>= 12;
-
-- vram = kzalloc(sizeof(*vram), GFP_KERNEL);
-- if (!vram)
-+ mem = kzalloc(sizeof(*mem), GFP_KERNEL);
-+ if (!mem)
- return -ENOMEM;
-
-- INIT_LIST_HEAD(&vram->regions);
-- vram->dev = dev_priv->dev;
-- vram->memtype = type;
-- vram->size = size;
--
- mutex_lock(&mm->mutex);
-+ if (comp) {
-+ if (align == 16) {
-+ struct nouveau_fb_engine *pfb = &dev_priv->engine.fb;
-+ int n = (size >> 4) * comp;
-+
-+ mem->tag = drm_mm_search_free(&pfb->tag_heap, n, 0, 0);
-+ if (mem->tag)
-+ mem->tag = drm_mm_get_block(mem->tag, n, 0);
-+ }
-+
-+ if (unlikely(!mem->tag))
-+ comp = 0;
-+ }
-+
-+ INIT_LIST_HEAD(&mem->regions);
-+ mem->dev = dev_priv->dev;
-+ mem->memtype = (comp << 7) | type;
-+ mem->size = size;
-+
- do {
- ret = nouveau_mm_get(mm, types[type], size, size_nc, align, &r);
- if (ret) {
- mutex_unlock(&mm->mutex);
-- nv50_vram_del(dev, &vram);
-+ nv50_vram_del(dev, &mem);
- return ret;
- }
-
-- list_add_tail(&r->rl_entry, &vram->regions);
-+ list_add_tail(&r->rl_entry, &mem->regions);
- size -= r->length;
- } while (size);
- mutex_unlock(&mm->mutex);
-
-- r = list_first_entry(&vram->regions, struct nouveau_mm_node, rl_entry);
-- vram->offset = (u64)r->offset << 12;
-- *pvram = vram;
-+ r = list_first_entry(&mem->regions, struct nouveau_mm_node, rl_entry);
-+ mem->offset = (u64)r->offset << 12;
-+ *pmem = mem;
- return 0;
- }
-
-diff --git a/drivers/gpu/drm/nouveau/nv84_crypt.c b/drivers/gpu/drm/nouveau/nv84_crypt.c
-index ec18ae1..fabc7fd 100644
---- a/drivers/gpu/drm/nouveau/nv84_crypt.c
-+++ b/drivers/gpu/drm/nouveau/nv84_crypt.c
-@@ -136,5 +136,5 @@ nv84_crypt_isr(struct drm_device *dev)
- nv_wr32(dev, 0x102130, stat);
- nv_wr32(dev, 0x10200c, 0x10);
-
-- nv50_fb_vm_trap(dev, show, "PCRYPT");
-+ nv50_fb_vm_trap(dev, show);
- }
-diff --git a/drivers/gpu/drm/nouveau/nva3_pm.c b/drivers/gpu/drm/nouveau/nva3_pm.c
-index dbbafed..e4b2b9e 100644
---- a/drivers/gpu/drm/nouveau/nva3_pm.c
-+++ b/drivers/gpu/drm/nouveau/nva3_pm.c
-@@ -27,32 +27,74 @@
- #include "nouveau_bios.h"
- #include "nouveau_pm.h"
-
--/*XXX: boards using limits 0x40 need fixing, the register layout
-- * is correct here, but, there's some other funny magic
-- * that modifies things, so it's not likely we'll set/read
-- * the correct timings yet.. working on it...
-+/* This is actually a lot more complex than it appears here, but hopefully
-+ * this should be able to deal with what the VBIOS leaves for us..
-+ *
-+ * If not, well, I'll jump off that bridge when I come to it.
- */
-
- struct nva3_pm_state {
-- struct pll_lims pll;
-- int N, M, P;
-+ enum pll_types type;
-+ u32 src0;
-+ u32 src1;
-+ u32 ctrl;
-+ u32 coef;
-+ u32 old_pnm;
-+ u32 new_pnm;
-+ u32 new_div;
- };
-
-+static int
-+nva3_pm_pll_offset(u32 id)
-+{
-+ static const u32 pll_map[] = {
-+ 0x00, PLL_CORE,
-+ 0x01, PLL_SHADER,
-+ 0x02, PLL_MEMORY,
-+ 0x00, 0x00
-+ };
-+ const u32 *map = pll_map;
-+
-+ while (map[1]) {
-+ if (id == map[1])
-+ return map[0];
-+ map += 2;
-+ }
-+
-+ return -ENOENT;
-+}
-+
- int
- nva3_pm_clock_get(struct drm_device *dev, u32 id)
- {
-+ u32 src0, src1, ctrl, coef;
- struct pll_lims pll;
-- int P, N, M, ret;
-- u32 reg;
-+ int ret, off;
-+ int P, N, M;
-
- ret = get_pll_limits(dev, id, &pll);
- if (ret)
- return ret;
-
-- reg = nv_rd32(dev, pll.reg + 4);
-- P = (reg & 0x003f0000) >> 16;
-- N = (reg & 0x0000ff00) >> 8;
-- M = (reg & 0x000000ff);
-+ off = nva3_pm_pll_offset(id);
-+ if (off < 0)
-+ return off;
-+
-+ src0 = nv_rd32(dev, 0x4120 + (off * 4));
-+ src1 = nv_rd32(dev, 0x4160 + (off * 4));
-+ ctrl = nv_rd32(dev, pll.reg + 0);
-+ coef = nv_rd32(dev, pll.reg + 4);
-+ NV_DEBUG(dev, "PLL %02x: 0x%08x 0x%08x 0x%08x 0x%08x\n",
-+ id, src0, src1, ctrl, coef);
-+
-+ if (ctrl & 0x00000008) {
-+ u32 div = ((src1 & 0x003c0000) >> 18) + 1;
-+ return (pll.refclk * 2) / div;
-+ }
-+
-+ P = (coef & 0x003f0000) >> 16;
-+ N = (coef & 0x0000ff00) >> 8;
-+ M = (coef & 0x000000ff);
- return pll.refclk * N / M / P;
- }
-
-@@ -60,36 +102,103 @@ void *
- nva3_pm_clock_pre(struct drm_device *dev, struct nouveau_pm_level *perflvl,
- u32 id, int khz)
- {
-- struct nva3_pm_state *state;
-- int dummy, ret;
-+ struct nva3_pm_state *pll;
-+ struct pll_lims limits;
-+ int N, M, P, diff;
-+ int ret, off;
-+
-+ ret = get_pll_limits(dev, id, &limits);
-+ if (ret < 0)
-+ return (ret == -ENOENT) ? NULL : ERR_PTR(ret);
-+
-+ off = nva3_pm_pll_offset(id);
-+ if (id < 0)
-+ return ERR_PTR(-EINVAL);
-
-- state = kzalloc(sizeof(*state), GFP_KERNEL);
-- if (!state)
-+
-+ pll = kzalloc(sizeof(*pll), GFP_KERNEL);
-+ if (!pll)
- return ERR_PTR(-ENOMEM);
-+ pll->type = id;
-+ pll->src0 = 0x004120 + (off * 4);
-+ pll->src1 = 0x004160 + (off * 4);
-+ pll->ctrl = limits.reg + 0;
-+ pll->coef = limits.reg + 4;
-
-- ret = get_pll_limits(dev, id, &state->pll);
-- if (ret < 0) {
-- kfree(state);
-- return (ret == -ENOENT) ? NULL : ERR_PTR(ret);
-+ /* If target clock is within [-2, 3) MHz of a divisor, we'll
-+ * use that instead of calculating MNP values
-+ */
-+ pll->new_div = min((limits.refclk * 2) / (khz - 2999), 16);
-+ if (pll->new_div) {
-+ diff = khz - ((limits.refclk * 2) / pll->new_div);
-+ if (diff < -2000 || diff >= 3000)
-+ pll->new_div = 0;
- }
-
-- ret = nv50_calc_pll2(dev, &state->pll, khz, &state->N, &dummy,
-- &state->M, &state->P);
-- if (ret < 0) {
-- kfree(state);
-- return ERR_PTR(ret);
-+ if (!pll->new_div) {
-+ ret = nva3_calc_pll(dev, &limits, khz, &N, NULL, &M, &P);
-+ if (ret < 0)
-+ return ERR_PTR(ret);
-+
-+ pll->new_pnm = (P << 16) | (N << 8) | M;
-+ pll->new_div = 2 - 1;
-+ } else {
-+ pll->new_pnm = 0;
-+ pll->new_div--;
- }
-
-- return state;
-+ if ((nv_rd32(dev, pll->src1) & 0x00000101) != 0x00000101)
-+ pll->old_pnm = nv_rd32(dev, pll->coef);
-+ return pll;
- }
-
- void
- nva3_pm_clock_set(struct drm_device *dev, void *pre_state)
- {
-- struct nva3_pm_state *state = pre_state;
-- u32 reg = state->pll.reg;
-+ struct nva3_pm_state *pll = pre_state;
-+ u32 ctrl = 0;
-+
-+ /* For the memory clock, NVIDIA will build a "script" describing
-+ * the reclocking process and ask PDAEMON to execute it.
-+ */
-+ if (pll->type == PLL_MEMORY) {
-+ nv_wr32(dev, 0x100210, 0);
-+ nv_wr32(dev, 0x1002dc, 1);
-+ nv_wr32(dev, 0x004018, 0x00001000);
-+ ctrl = 0x18000100;
-+ }
-+
-+ if (pll->old_pnm || !pll->new_pnm) {
-+ nv_mask(dev, pll->src1, 0x003c0101, 0x00000101 |
-+ (pll->new_div << 18));
-+ nv_wr32(dev, pll->ctrl, 0x0001001d | ctrl);
-+ nv_mask(dev, pll->ctrl, 0x00000001, 0x00000000);
-+ }
-+
-+ if (pll->new_pnm) {
-+ nv_mask(dev, pll->src0, 0x00000101, 0x00000101);
-+ nv_wr32(dev, pll->coef, pll->new_pnm);
-+ nv_wr32(dev, pll->ctrl, 0x0001001d | ctrl);
-+ nv_mask(dev, pll->ctrl, 0x00000010, 0x00000000);
-+ nv_mask(dev, pll->ctrl, 0x00020010, 0x00020010);
-+ nv_wr32(dev, pll->ctrl, 0x00010015 | ctrl);
-+ nv_mask(dev, pll->src1, 0x00000100, 0x00000000);
-+ nv_mask(dev, pll->src1, 0x00000001, 0x00000000);
-+ if (pll->type == PLL_MEMORY)
-+ nv_wr32(dev, 0x4018, 0x10005000);
-+ } else {
-+ nv_mask(dev, pll->ctrl, 0x00000001, 0x00000000);
-+ nv_mask(dev, pll->src0, 0x00000100, 0x00000000);
-+ nv_mask(dev, pll->src0, 0x00000001, 0x00000000);
-+ if (pll->type == PLL_MEMORY)
-+ nv_wr32(dev, 0x4018, 0x1000d000);
-+ }
-+
-+ if (pll->type == PLL_MEMORY) {
-+ nv_wr32(dev, 0x1002dc, 0);
-+ nv_wr32(dev, 0x100210, 0x80000000);
-+ }
-
-- nv_wr32(dev, reg + 4, (state->P << 16) | (state->N << 8) |
state->M);
-- kfree(state);
-+ kfree(pll);
- }
-
-diff --git a/drivers/gpu/drm/nouveau/nvc0_fb.c b/drivers/gpu/drm/nouveau/nvc0_fb.c
-index 26a9960..08e6b11 100644
---- a/drivers/gpu/drm/nouveau/nvc0_fb.c
-+++ b/drivers/gpu/drm/nouveau/nvc0_fb.c
-@@ -1,5 +1,5 @@
- /*
-- * Copyright 2010 Red Hat Inc.
-+ * Copyright 2011 Red Hat Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
-@@ -23,16 +23,80 @@
- */
-
- #include "drmP.h"
--
-+#include "drm.h"
- #include "nouveau_drv.h"
-+#include "nouveau_drm.h"
-+
-+struct nvc0_fb_priv {
-+ struct page *r100c10_page;
-+ dma_addr_t r100c10;
-+};
-+
-+static void
-+nvc0_fb_destroy(struct drm_device *dev)
-+{
-+ struct drm_nouveau_private *dev_priv = dev->dev_private;
-+ struct nouveau_fb_engine *pfb = &dev_priv->engine.fb;
-+ struct nvc0_fb_priv *priv = pfb->priv;
-+
-+ if (priv->r100c10_page) {
-+ pci_unmap_page(dev->pdev, priv->r100c10, PAGE_SIZE,
-+ PCI_DMA_BIDIRECTIONAL);
-+ __free_page(priv->r100c10_page);
-+ }
-+
-+ kfree(priv);
-+ pfb->priv = NULL;
-+}
-+
-+static int
-+nvc0_fb_create(struct drm_device *dev)
-+{
-+ struct drm_nouveau_private *dev_priv = dev->dev_private;
-+ struct nouveau_fb_engine *pfb = &dev_priv->engine.fb;
-+ struct nvc0_fb_priv *priv;
-+
-+ priv = kzalloc(sizeof(*priv), GFP_KERNEL);
-+ if (!priv)
-+ return -ENOMEM;
-+ pfb->priv = priv;
-+
-+ priv->r100c10_page = alloc_page(GFP_KERNEL | __GFP_ZERO);
-+ if (!priv->r100c10_page) {
-+ nvc0_fb_destroy(dev);
-+ return -ENOMEM;
-+ }
-+
-+ priv->r100c10 = pci_map_page(dev->pdev, priv->r100c10_page, 0,
-+ PAGE_SIZE, PCI_DMA_BIDIRECTIONAL);
-+ if (pci_dma_mapping_error(dev->pdev, priv->r100c10)) {
-+ nvc0_fb_destroy(dev);
-+ return -EFAULT;
-+ }
-+
-+ return 0;
-+}
-
- int
- nvc0_fb_init(struct drm_device *dev)
- {
-+ struct drm_nouveau_private *dev_priv = dev->dev_private;
-+ struct nvc0_fb_priv *priv;
-+ int ret;
-+
-+ if (!dev_priv->engine.fb.priv) {
-+ ret = nvc0_fb_create(dev);
-+ if (ret)
-+ return ret;
-+ }
-+ priv = dev_priv->engine.fb.priv;
-+
-+ nv_wr32(dev, 0x100c10, priv->r100c10 >> 8);
- return 0;
- }
-
- void
- nvc0_fb_takedown(struct drm_device *dev)
- {
-+ nvc0_fb_destroy(dev);
- }
-diff --git a/drivers/gpu/drm/nouveau/nvc0_fifo.c b/drivers/gpu/drm/nouveau/nvc0_fifo.c
-index e6f92c5..55a4245 100644
---- a/drivers/gpu/drm/nouveau/nvc0_fifo.c
-+++ b/drivers/gpu/drm/nouveau/nvc0_fifo.c
-@@ -116,7 +116,7 @@ nvc0_fifo_create_context(struct nouveau_channel *chan)
-
- /* allocate vram for control regs, map into polling area */
- ret = nouveau_bo_new(dev, NULL, 0x1000, 0, TTM_PL_FLAG_VRAM,
-- 0, 0, true, true, &fifoch->user);
-+ 0, 0, &fifoch->user);
- if (ret)
- goto error;
-
-@@ -355,19 +355,57 @@ nvc0_fifo_init(struct drm_device *dev)
- }
-
- struct nouveau_enum nvc0_fifo_fault_unit[] = {
-- { 0, "PGRAPH" },
-- { 3, "PEEPHOLE" },
-- { 4, "BAR1" },
-- { 5, "BAR3" },
-- { 7, "PFIFO" },
-+ { 0x00, "PGRAPH" },
-+ { 0x03, "PEEPHOLE" },
-+ { 0x04, "BAR1" },
-+ { 0x05, "BAR3" },
-+ { 0x07, "PFIFO" },
-+ { 0x10, "PBSP" },
-+ { 0x11, "PPPP" },
-+ { 0x13, "PCOUNTER" },
-+ { 0x14, "PVP" },
-+ { 0x15, "PCOPY0" },
-+ { 0x16, "PCOPY1" },
-+ { 0x17, "PDAEMON" },
- {}
- };
-
- struct nouveau_enum nvc0_fifo_fault_reason[] = {
-- { 0, "PT_NOT_PRESENT" },
-- { 1, "PT_TOO_SHORT" },
-- { 2, "PAGE_NOT_PRESENT" },
-- { 3, "VM_LIMIT_EXCEEDED" },
-+ { 0x00, "PT_NOT_PRESENT" },
-+ { 0x01, "PT_TOO_SHORT" },
-+ { 0x02, "PAGE_NOT_PRESENT" },
-+ { 0x03, "VM_LIMIT_EXCEEDED" },
-+ { 0x04, "NO_CHANNEL" },
-+ { 0x05, "PAGE_SYSTEM_ONLY" },
-+ { 0x06, "PAGE_READ_ONLY" },
-+ { 0x0a, "COMPRESSED_SYSRAM" },
-+ { 0x0c, "INVALID_STORAGE_TYPE" },
-+ {}
-+};
-+
-+struct nouveau_enum nvc0_fifo_fault_hubclient[] = {
-+ { 0x01, "PCOPY0" },
-+ { 0x02, "PCOPY1" },
-+ { 0x04, "DISPATCH" },
-+ { 0x05, "CTXCTL" },
-+ { 0x06, "PFIFO" },
-+ { 0x07, "BAR_READ" },
-+ { 0x08, "BAR_WRITE" },
-+ { 0x0b, "PVP" },
-+ { 0x0c, "PPPP" },
-+ { 0x0d, "PBSP" },
-+ { 0x11, "PCOUNTER" },
-+ { 0x12, "PDAEMON" },
-+ { 0x14, "CCACHE" },
-+ { 0x15, "CCACHE_POST" },
-+ {}
-+};
-+
-+struct nouveau_enum nvc0_fifo_fault_gpcclient[] = {
-+ { 0x01, "TEX" },
-+ { 0x0c, "ESETUP" },
-+ { 0x0e, "CTXCTL" },
-+ { 0x0f, "PROP" },
- {}
- };
-
-@@ -385,12 +423,20 @@ nvc0_fifo_isr_vm_fault(struct drm_device *dev, int unit)
- u32 valo = nv_rd32(dev, 0x2804 + (unit * 0x10));
- u32 vahi = nv_rd32(dev, 0x2808 + (unit * 0x10));
- u32 stat = nv_rd32(dev, 0x280c + (unit * 0x10));
-+ u32 client = (stat & 0x00001f00) >> 8;
-
- NV_INFO(dev, "PFIFO: %s fault at 0x%010llx [",
- (stat & 0x00000080) ? "write" : "read", (u64)vahi << 32
| valo);
- nouveau_enum_print(nvc0_fifo_fault_reason, stat & 0x0000000f);
- printk("] from ");
- nouveau_enum_print(nvc0_fifo_fault_unit, unit);
-+ if (stat & 0x00000040) {
-+ printk("/");
-+ nouveau_enum_print(nvc0_fifo_fault_hubclient, client);
-+ } else {
-+ printk("/GPC%d/", (stat & 0x1f000000) >> 24);
-+ nouveau_enum_print(nvc0_fifo_fault_gpcclient, client);
-+ }
- printk(" on channel 0x%010llx\n", (u64)inst << 12);
- }
-
-@@ -418,6 +464,12 @@ nvc0_fifo_isr(struct drm_device *dev)
- {
- u32 stat = nv_rd32(dev, 0x002100);
-
-+ if (stat & 0x00000100) {
-+ NV_INFO(dev, "PFIFO: unknown status 0x00000100\n");
-+ nv_wr32(dev, 0x002100, 0x00000100);
-+ stat &= ~0x00000100;
-+ }
-+
- if (stat & 0x10000000) {
- u32 units = nv_rd32(dev, 0x00259c);
- u32 u = units;
-@@ -446,10 +498,15 @@ nvc0_fifo_isr(struct drm_device *dev)
- stat &= ~0x20000000;
- }
-
-+ if (stat & 0x40000000) {
-+ NV_INFO(dev, "PFIFO: unknown status 0x40000000\n");
-+ nv_mask(dev, 0x002a00, 0x00000000, 0x00000000);
-+ stat &= ~0x40000000;
-+ }
-+
- if (stat) {
- NV_INFO(dev, "PFIFO: unhandled status 0x%08x\n", stat);
- nv_wr32(dev, 0x002100, stat);
-+ nv_wr32(dev, 0x002140, 0);
- }
--
-- nv_wr32(dev, 0x2140, 0);
- }
-diff --git a/drivers/gpu/drm/nouveau/nvc0_graph.c b/drivers/gpu/drm/nouveau/nvc0_graph.c
-index eb18a7e..68f5c3f 100644
---- a/drivers/gpu/drm/nouveau/nvc0_graph.c
-+++ b/drivers/gpu/drm/nouveau/nvc0_graph.c
-@@ -200,15 +200,15 @@ nvc0_graph_create_context(struct nouveau_channel *chan)
- for (i = 0; i < priv->grctx_size; i += 4)
- nv_wo32(grctx, i, priv->grctx_vals[i / 4]);
-
-- nv_wo32(grctx, 0xf4, 0);
-- nv_wo32(grctx, 0xf8, 0);
-- nv_wo32(grctx, 0x10, grch->mmio_nr);
-- nv_wo32(grctx, 0x14, lower_32_bits(grch->mmio->vinst));
-- nv_wo32(grctx, 0x18, upper_32_bits(grch->mmio->vinst));
-- nv_wo32(grctx, 0x1c, 1);
-- nv_wo32(grctx, 0x20, 0);
-- nv_wo32(grctx, 0x28, 0);
-- nv_wo32(grctx, 0x2c, 0);
-+ nv_wo32(grctx, 0xf4, 0);
-+ nv_wo32(grctx, 0xf8, 0);
-+ nv_wo32(grctx, 0x10, grch->mmio_nr);
-+ nv_wo32(grctx, 0x14, lower_32_bits(grch->mmio->vinst));
-+ nv_wo32(grctx, 0x18, upper_32_bits(grch->mmio->vinst));
-+ nv_wo32(grctx, 0x1c, 1);
-+ nv_wo32(grctx, 0x20, 0);
-+ nv_wo32(grctx, 0x28, 0);
-+ nv_wo32(grctx, 0x2c, 0);
- pinstmem->flush(dev);
- return 0;
-
-@@ -299,6 +299,14 @@ nvc0_graph_takedown(struct drm_device *dev)
- }
-
- static int
-+nvc0_graph_mthd_page_flip(struct nouveau_channel *chan,
-+ u32 class, u32 mthd, u32 data)
-+{
-+ nouveau_finish_page_flip(chan, NULL);
-+ return 0;
-+}
-+
-+static int
- nvc0_graph_create(struct drm_device *dev)
- {
- struct drm_nouveau_private *dev_priv = dev->dev_private;
-@@ -395,6 +403,7 @@ nvc0_graph_create(struct drm_device *dev)
- nouveau_irq_register(dev, 25, nvc0_runk140_isr);
- NVOBJ_CLASS(dev, 0x902d, GR); /* 2D */
- NVOBJ_CLASS(dev, 0x9039, GR); /* M2MF */
-+ NVOBJ_MTHD (dev, 0x9039, 0x0500, nvc0_graph_mthd_page_flip);
- NVOBJ_CLASS(dev, 0x9097, GR); /* 3D */
- NVOBJ_CLASS(dev, 0x90c0, GR); /* COMPUTE */
- return 0;
-@@ -443,28 +452,30 @@ nvc0_graph_init_gpc_0(struct drm_device *dev)
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nvc0_graph_priv *priv = dev_priv->engine.graph.priv;
- int gpc;
--
-- // TP ROP UNKVAL(magic_not_rop_nr)
-- // 450: 4/0/0/0 2 3
-- // 460: 3/4/0/0 4 1
-- // 465: 3/4/4/0 4 7
-- // 470: 3/3/4/4 5 5
-- // 480: 3/4/4/4 6 6
--
-- // magicgpc918
-- // 450: 00200000 00000000001000000000000000000000
-- // 460: 00124925 00000000000100100100100100100101
-- // 465: 000ba2e9 00000000000010111010001011101001
-- // 470: 00092493 00000000000010010010010010010011
-- // 480: 00088889 00000000000010001000100010001001
--
-- /* filled values up to tp_total, remainder 0 */
-- // 450: 00003210 00000000 00000000 00000000
-- // 460: 02321100 00000000 00000000 00000000
-- // 465: 22111000 00000233 00000000 00000000
-- // 470: 11110000 00233222 00000000 00000000
-- // 480: 11110000 03332222 00000000 00000000
--
-+
-+ /*
-+ * TP ROP UNKVAL(magic_not_rop_nr)
-+ * 450: 4/0/0/0 2 3
-+ * 460: 3/4/0/0 4 1
-+ * 465: 3/4/4/0 4 7
-+ * 470: 3/3/4/4 5 5
-+ * 480: 3/4/4/4 6 6
-+
-+ * magicgpc918
-+ * 450: 00200000 00000000001000000000000000000000
-+ * 460: 00124925 00000000000100100100100100100101
-+ * 465: 000ba2e9 00000000000010111010001011101001
-+ * 470: 00092493 00000000000010010010010010010011
-+ * 480: 00088889 00000000000010001000100010001001
-+
-+ * filled values up to tp_total, remainder 0
-+ * 450: 00003210 00000000 00000000 00000000
-+ * 460: 02321100 00000000 00000000 00000000
-+ * 465: 22111000 00000233 00000000 00000000
-+ * 470: 11110000 00233222 00000000 00000000
-+ * 480: 11110000 03332222 00000000 00000000
-+ */
-+
- nv_wr32(dev, GPC_BCAST(0x0980), priv->magicgpc980[0]);
- nv_wr32(dev, GPC_BCAST(0x0984), priv->magicgpc980[1]);
- nv_wr32(dev, GPC_BCAST(0x0988), priv->magicgpc980[2]);
-@@ -640,7 +651,6 @@ nvc0_graph_init(struct drm_device *dev)
- {
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
-- struct nvc0_graph_priv *priv;
- int ret;
-
- dev_priv->engine.graph.accel_blocked = true;
-@@ -665,13 +675,12 @@ nvc0_graph_init(struct drm_device *dev)
- if (ret)
- return ret;
- }
-- priv = pgraph->priv;
-
- nvc0_graph_init_obj418880(dev);
- nvc0_graph_init_regs(dev);
-- //nvc0_graph_init_unitplemented_magics(dev);
-+ /*nvc0_graph_init_unitplemented_magics(dev);*/
- nvc0_graph_init_gpc_0(dev);
-- //nvc0_graph_init_unitplemented_c242(dev);
-+ /*nvc0_graph_init_unitplemented_c242(dev);*/
-
- nv_wr32(dev, 0x400500, 0x00010001);
- nv_wr32(dev, 0x400100, 0xffffffff);
-@@ -730,9 +739,12 @@ nvc0_graph_isr(struct drm_device *dev)
- u32 class = nv_rd32(dev, 0x404200 + (subc * 4));
-
- if (stat & 0x00000010) {
-- NV_INFO(dev, "PGRAPH: ILLEGAL_MTHD ch %d [0x%010llx] subc %d "
-- "class 0x%04x mthd 0x%04x data 0x%08x\n",
-- chid, inst, subc, class, mthd, data);
-+ if (nouveau_gpuobj_mthd_call2(dev, chid, class, mthd, data)) {
-+ NV_INFO(dev, "PGRAPH: ILLEGAL_MTHD ch %d [0x%010llx] "
-+ "subc %d class 0x%04x mthd 0x%04x "
-+ "data 0x%08x\n",
-+ chid, inst, subc, class, mthd, data);
-+ }
- nv_wr32(dev, 0x400100, 0x00000010);
- stat &= ~0x00000010;
- }
-diff --git a/drivers/gpu/drm/nouveau/nvc0_graph.h b/drivers/gpu/drm/nouveau/nvc0_graph.h
-index 40e26f9..d32b385 100644
---- a/drivers/gpu/drm/nouveau/nvc0_graph.h
-+++ b/drivers/gpu/drm/nouveau/nvc0_graph.h
-@@ -28,11 +28,11 @@
- #define GPC_MAX 4
- #define TP_MAX 32
-
--#define ROP_BCAST(r) (0x408800 + (r))
--#define ROP_UNIT(u,r) (0x410000 + (u) * 0x400 + (r))
--#define GPC_BCAST(r) (0x418000 + (r))
--#define GPC_UNIT(t,r) (0x500000 + (t) * 0x8000 + (r))
--#define TP_UNIT(t,m,r) (0x504000 + (t) * 0x8000 + (m) * 0x800 + (r))
-+#define ROP_BCAST(r) (0x408800 + (r))
-+#define ROP_UNIT(u, r) (0x410000 + (u) * 0x400 + (r))
-+#define GPC_BCAST(r) (0x418000 + (r))
-+#define GPC_UNIT(t, r) (0x500000 + (t) * 0x8000 + (r))
-+#define TP_UNIT(t, m, r) (0x504000 + (t) * 0x8000 + (m) * 0x800 + (r))
-
- struct nvc0_graph_priv {
- u8 gpc_nr;
-@@ -52,9 +52,9 @@ struct nvc0_graph_priv {
-
- struct nvc0_graph_chan {
- struct nouveau_gpuobj *grctx;
-- struct nouveau_gpuobj *unk408004; // 0x418810 too
-- struct nouveau_gpuobj *unk40800c; // 0x419004 too
-- struct nouveau_gpuobj *unk418810; // 0x419848 too
-+ struct nouveau_gpuobj *unk408004; /* 0x418810 too */
-+ struct nouveau_gpuobj *unk40800c; /* 0x419004 too */
-+ struct nouveau_gpuobj *unk418810; /* 0x419848 too */
- struct nouveau_gpuobj *mmio;
- int mmio_nr;
- };
-diff --git a/drivers/gpu/drm/nouveau/nvc0_grctx.c b/drivers/gpu/drm/nouveau/nvc0_grctx.c
-index f880ff7..6cede9f 100644
---- a/drivers/gpu/drm/nouveau/nvc0_grctx.c
-+++ b/drivers/gpu/drm/nouveau/nvc0_grctx.c
-@@ -1623,7 +1623,7 @@ nvc0_grctx_generate_rop(struct drm_device *dev)
- {
- struct drm_nouveau_private *dev_priv = dev->dev_private;
-
-- // ROPC_BROADCAST
-+ /* ROPC_BROADCAST */
- nv_wr32(dev, 0x408800, 0x02802a3c);
- nv_wr32(dev, 0x408804, 0x00000040);
- nv_wr32(dev, 0x408808, 0x0003e00d);
-@@ -1647,7 +1647,7 @@ nvc0_grctx_generate_gpc(struct drm_device *dev)
- {
- int i;
-
-- // GPC_BROADCAST
-+ /* GPC_BROADCAST */
- nv_wr32(dev, 0x418380, 0x00000016);
- nv_wr32(dev, 0x418400, 0x38004e00);
- nv_wr32(dev, 0x418404, 0x71e0ffff);
-@@ -1728,7 +1728,7 @@ nvc0_grctx_generate_tp(struct drm_device *dev)
- {
- struct drm_nouveau_private *dev_priv = dev->dev_private;
-
-- // GPC_BROADCAST.TP_BROADCAST
-+ /* GPC_BROADCAST.TP_BROADCAST */
- nv_wr32(dev, 0x419848, 0x00000000);
- nv_wr32(dev, 0x419864, 0x0000012a);
- nv_wr32(dev, 0x419888, 0x00000000);
-@@ -1741,7 +1741,7 @@ nvc0_grctx_generate_tp(struct drm_device *dev)
- nv_wr32(dev, 0x419a1c, 0x00000000);
- nv_wr32(dev, 0x419a20, 0x00000800);
- if (dev_priv->chipset != 0xc0)
-- nv_wr32(dev, 0x00419ac4, 0x0007f440); // 0xc3
-+ nv_wr32(dev, 0x00419ac4, 0x0007f440); /* 0xc3 */
- nv_wr32(dev, 0x419b00, 0x0a418820);
- nv_wr32(dev, 0x419b04, 0x062080e6);
- nv_wr32(dev, 0x419b08, 0x020398a4);
-@@ -1912,13 +1912,13 @@ nvc0_grctx_generate(struct nouveau_channel *chan)
- for (i = 1; i < 7; i++)
- data2[1] |= ((1 << (i + 5)) % ntpcv) << ((i - 1) * 5);
-
-- // GPC_BROADCAST
-+ /* GPC_BROADCAST */
- nv_wr32(dev, 0x418bb8, (priv->tp_total << 8) |
- priv->magic_not_rop_nr);
- for (i = 0; i < 6; i++)
- nv_wr32(dev, 0x418b08 + (i * 4), data[i]);
-
-- // GPC_BROADCAST.TP_BROADCAST
-+ /* GPC_BROADCAST.TP_BROADCAST */
- nv_wr32(dev, 0x419bd0, (priv->tp_total << 8) |
- priv->magic_not_rop_nr |
- data2[0]);
-@@ -1926,7 +1926,7 @@ nvc0_grctx_generate(struct nouveau_channel *chan)
- for (i = 0; i < 6; i++)
- nv_wr32(dev, 0x419b00 + (i * 4), data[i]);
-
-- // UNK78xx
-+ /* UNK78xx */
- nv_wr32(dev, 0x4078bc, (priv->tp_total << 8) |
- priv->magic_not_rop_nr);
- for (i = 0; i < 6; i++)
-@@ -1944,7 +1944,7 @@ nvc0_grctx_generate(struct nouveau_channel *chan)
- gpc = -1;
- for (i = 0, gpc = -1; i < 32; i++) {
- int ltp = i * (priv->tp_total - 1) / 32;
--
-+
- do {
- gpc = (gpc + 1) % priv->gpc_nr;
- } while (!tpnr[gpc]);
-diff --git a/drivers/gpu/drm/nouveau/nvc0_vm.c b/drivers/gpu/drm/nouveau/nvc0_vm.c
-index e4e83c2..a179e6c 100644
---- a/drivers/gpu/drm/nouveau/nvc0_vm.c
-+++ b/drivers/gpu/drm/nouveau/nvc0_vm.c
-@@ -59,7 +59,7 @@ nvc0_vm_addr(struct nouveau_vma *vma, u64 phys, u32 memtype, u32
target)
-
- void
- nvc0_vm_map(struct nouveau_vma *vma, struct nouveau_gpuobj *pgt,
-- struct nouveau_vram *mem, u32 pte, u32 cnt, u64 phys)
-+ struct nouveau_mem *mem, u32 pte, u32 cnt, u64 phys, u64 delta)
- {
- u32 next = 1 << (vma->node->type - 8);
-
-@@ -75,11 +75,11 @@ nvc0_vm_map(struct nouveau_vma *vma, struct nouveau_gpuobj *pgt,
-
- void
- nvc0_vm_map_sg(struct nouveau_vma *vma, struct nouveau_gpuobj *pgt,
-- u32 pte, dma_addr_t *list, u32 cnt)
-+ struct nouveau_mem *mem, u32 pte, u32 cnt, dma_addr_t *list)
- {
- pte <<= 3;
- while (cnt--) {
-- u64 phys = nvc0_vm_addr(vma, *list++, 0, 5);
-+ u64 phys = nvc0_vm_addr(vma, *list++, mem->memtype, 5);
- nv_wo32(pgt, pte + 0, lower_32_bits(phys));
- nv_wo32(pgt, pte + 4, upper_32_bits(phys));
- pte += 8;
-@@ -104,20 +104,27 @@ nvc0_vm_flush(struct nouveau_vm *vm)
- struct nouveau_instmem_engine *pinstmem = &dev_priv->engine.instmem;
- struct drm_device *dev = vm->dev;
- struct nouveau_vm_pgd *vpgd;
-- u32 r100c80, engine;
-+ unsigned long flags;
-+ u32 engine = (dev_priv->chan_vm == vm) ? 1 : 5;
-
- pinstmem->flush(vm->dev);
-
-- if (vm == dev_priv->chan_vm)
-- engine = 1;
-- else
-- engine = 5;
--
-+ spin_lock_irqsave(&dev_priv->vm_lock, flags);
- list_for_each_entry(vpgd, &vm->pgd_list, head) {
-- r100c80 = nv_rd32(dev, 0x100c80);
-+ /* looks like maybe a "free flush slots" counter, the
-+ * faster you write to 0x100cbc to more it decreases
-+ */
-+ if (!nv_wait_ne(dev, 0x100c80, 0x00ff0000, 0x00000000)) {
-+ NV_ERROR(dev, "vm timeout 0: 0x%08x %d\n",
-+ nv_rd32(dev, 0x100c80), engine);
-+ }
- nv_wr32(dev, 0x100cb8, vpgd->obj->vinst >> 8);
- nv_wr32(dev, 0x100cbc, 0x80000000 | engine);
-- if (!nv_wait(dev, 0x100c80, 0xffffffff, r100c80))
-- NV_ERROR(dev, "vm flush timeout eng %d\n", engine);
-+ /* wait for flush to be queued? */
-+ if (!nv_wait(dev, 0x100c80, 0x00008000, 0x00008000)) {
-+ NV_ERROR(dev, "vm timeout 1: 0x%08x %d\n",
-+ nv_rd32(dev, 0x100c80), engine);
-+ }
- }
-+ spin_unlock_irqrestore(&dev_priv->vm_lock, flags);
- }
-diff --git a/drivers/gpu/drm/nouveau/nvc0_vram.c b/drivers/gpu/drm/nouveau/nvc0_vram.c
-index 858eda5..67c6ec6 100644
---- a/drivers/gpu/drm/nouveau/nvc0_vram.c
-+++ b/drivers/gpu/drm/nouveau/nvc0_vram.c
-@@ -26,64 +26,78 @@
- #include "nouveau_drv.h"
- #include "nouveau_mm.h"
-
-+/* 0 = unsupported
-+ * 1 = non-compressed
-+ * 3 = compressed
-+ */
-+static const u8 types[256] = {
-+ 1, 1, 3, 3, 3, 3, 0, 3, 3, 3, 3, 0, 0, 0, 0, 0,
-+ 0, 1, 0, 0, 0, 0, 0, 3, 3, 3, 3, 0, 0, 0, 0, 0,
-+ 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,
-+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3,
-+ 3, 3, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-+ 0, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0,
-+ 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 0, 1, 1, 1, 1, 0,
-+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-+ 0, 0, 0, 3, 3, 3, 3, 1, 1, 1, 1, 0, 0, 0, 0, 0,
-+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
-+ 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3,
-+ 3, 3, 0, 0, 0, 0, 0, 0, 3, 0, 0, 3, 0, 3, 0, 3,
-+ 3, 0, 3, 3, 3, 3, 3, 0, 0, 3, 0, 3, 0, 3, 3, 0,
-+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 1, 1, 0
-+};
-+
- bool
- nvc0_vram_flags_valid(struct drm_device *dev, u32 tile_flags)
- {
-- switch (tile_flags & NOUVEAU_GEM_TILE_LAYOUT_MASK) {
-- case 0x0000:
-- case 0xfe00:
-- case 0xdb00:
-- case 0x1100:
-- return true;
-- default:
-- break;
-- }
--
-- return false;
-+ u8 memtype = (tile_flags & NOUVEAU_GEM_TILE_LAYOUT_MASK) >> 8;
-+ return likely((types[memtype] == 1));
- }
-
- int
- nvc0_vram_new(struct drm_device *dev, u64 size, u32 align, u32 ncmin,
-- u32 type, struct nouveau_vram **pvram)
-+ u32 type, struct nouveau_mem **pmem)
- {
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct ttm_bo_device *bdev = &dev_priv->ttm.bdev;
- struct ttm_mem_type_manager *man = &bdev->man[TTM_PL_VRAM];
- struct nouveau_mm *mm = man->priv;
- struct nouveau_mm_node *r;
-- struct nouveau_vram *vram;
-+ struct nouveau_mem *mem;
- int ret;
-
- size >>= 12;
- align >>= 12;
- ncmin >>= 12;
-
-- vram = kzalloc(sizeof(*vram), GFP_KERNEL);
-- if (!vram)
-+ mem = kzalloc(sizeof(*mem), GFP_KERNEL);
-+ if (!mem)
- return -ENOMEM;
-
-- INIT_LIST_HEAD(&vram->regions);
-- vram->dev = dev_priv->dev;
-- vram->memtype = type;
-- vram->size = size;
-+ INIT_LIST_HEAD(&mem->regions);
-+ mem->dev = dev_priv->dev;
-+ mem->memtype = (type & 0xff);
-+ mem->size = size;
-
- mutex_lock(&mm->mutex);
- do {
- ret = nouveau_mm_get(mm, 1, size, ncmin, align, &r);
- if (ret) {
- mutex_unlock(&mm->mutex);
-- nv50_vram_del(dev, &vram);
-+ nv50_vram_del(dev, &mem);
- return ret;
- }
-
-- list_add_tail(&r->rl_entry, &vram->regions);
-+ list_add_tail(&r->rl_entry, &mem->regions);
- size -= r->length;
- } while (size);
- mutex_unlock(&mm->mutex);
-
-- r = list_first_entry(&vram->regions, struct nouveau_mm_node, rl_entry);
-- vram->offset = (u64)r->offset << 12;
-- *pvram = vram;
-+ r = list_first_entry(&mem->regions, struct nouveau_mm_node, rl_entry);
-+ mem->offset = (u64)r->offset << 12;
-+ *pmem = mem;
- return 0;
- }
-
-diff --git a/drivers/gpu/drm/nouveau/nvreg.h b/drivers/gpu/drm/nouveau/nvreg.h
-index fe0f253..bbfb1a6 100644
---- a/drivers/gpu/drm/nouveau/nvreg.h
-+++ b/drivers/gpu/drm/nouveau/nvreg.h
-@@ -277,6 +277,8 @@
- # define NV_CIO_CRE_EBR_VDE_11 2:2
- # define NV_CIO_CRE_EBR_VRS_11 4:4
- # define NV_CIO_CRE_EBR_VBS_11 6:6
-+# define NV_CIO_CRE_42 0x42
-+# define NV_CIO_CRE_42_OFFSET_11 6:6
- # define NV_CIO_CRE_43 0x43
- # define NV_CIO_CRE_44 0x44 /* head control */
- # define NV_CIO_CRE_CSB 0x45 /* colour saturation boost */
diff --git a/hid-multitouch-add-support-for-elo-touchsystems.patch
b/hid-multitouch-add-support-for-elo-touchsystems.patch
index 1294f46..789201f 100644
--- a/hid-multitouch-add-support-for-elo-touchsystems.patch
+++ b/hid-multitouch-add-support-for-elo-touchsystems.patch
@@ -1,30 +1,2205 @@
-From: Benjamin Tissoires <benjamin.tissoires(a)enac.fr>
-Date: Thu, 19 May 2011 09:37:29 +0000 (+0200)
-Subject: HID: hid-multitouch: add support for Elo TouchSystems 2515 IntelliTouch Plus
-X-Git-Url:
http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Fjikos%2Fhid.git;a=commitd...
+commit 9498f954a4ec389806333041a1018909c6fe0518
+Author: Benjamin Tissoires <benjamin.tissoires(a)enac.fr>
+Date: Fri Mar 18 14:27:52 2011 +0100
-HID: hid-multitouch: add support for Elo TouchSystems 2515 IntelliTouch Plus
+ HID: hid-multitouch: Auto detection of maxcontacts
+
+ This patch enables support of autodetection of maxcontacts.
+ When adding support for a new device, one is now able to let
+ the device tell how many contacts it supports, or to manually
+ set the value if the device happens to provide wrong information.
+
+ Signed-off-by: Benjamin Tissoires <benjamin.tissoires(a)enac.fr>
+ Reviewed-by: Stéphane Chatty <chatty(a)enac.fr>
+ Reviewed-by: Henrik Rydberg <rydberg(a)euromail.se>
+ Signed-off-by: Jiri Kosina <jkosina(a)suse.cz>
-This patch adds support for Elo TouchSystems 2515 IntelliTouch Plus
-that can be found in Lenovo A700 all-in-one.
+diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c
+index ee01e65..b9f9eec 100644
+--- a/drivers/hid/hid-multitouch.c
++++ b/drivers/hid/hid-multitouch.c
+@@ -60,8 +60,9 @@ struct mt_device {
+ __s8 inputmode; /* InputMode HID feature, -1 if non-existent */
+ __u8 num_received; /* how many contacts we received */
+ __u8 num_expected; /* expected last contact index */
++ __u8 maxcontacts;
+ bool curvalid; /* is the current contact valid? */
+- struct mt_slot slots[0]; /* first slot */
++ struct mt_slot *slots;
+ };
+
+ struct mt_class {
+@@ -79,6 +80,8 @@ struct mt_class {
+ #define MT_CLS_CYPRESS 4
+ #define MT_CLS_EGALAX 5
+
++#define MT_DEFAULT_MAXCONTACT 10
++
+ /*
+ * these device-dependent functions determine what slot corresponds
+ * to a valid contact that was just read.
+@@ -95,12 +98,12 @@ static int cypress_compute_slot(struct mt_device *td)
+ static int find_slot_from_contactid(struct mt_device *td)
+ {
+ int i;
+- for (i = 0; i < td->mtclass->maxcontacts; ++i) {
++ for (i = 0; i < td->maxcontacts; ++i) {
+ if (td->slots[i].contactid == td->curdata.contactid &&
+ td->slots[i].touch_state)
+ return i;
+ }
+- for (i = 0; i < td->mtclass->maxcontacts; ++i) {
++ for (i = 0; i < td->maxcontacts; ++i) {
+ if (!td->slots[i].seen_in_this_frame &&
+ !td->slots[i].touch_state)
+ return i;
+@@ -113,8 +116,7 @@ static int find_slot_from_contactid(struct mt_device *td)
+
+ struct mt_class mt_classes[] = {
+ { .name = MT_CLS_DEFAULT,
+- .quirks = MT_QUIRK_NOT_SEEN_MEANS_UP,
+- .maxcontacts = 10 },
++ .quirks = MT_QUIRK_NOT_SEEN_MEANS_UP },
+ { .name = MT_CLS_DUAL_INRANGE_CONTACTID,
+ .quirks = MT_QUIRK_VALID_IS_INRANGE |
+ MT_QUIRK_SLOT_IS_CONTACTID,
+@@ -142,9 +144,19 @@ struct mt_class mt_classes[] = {
+ static void mt_feature_mapping(struct hid_device *hdev,
+ struct hid_field *field, struct hid_usage *usage)
+ {
+- if (usage->hid == HID_DG_INPUTMODE) {
+- struct mt_device *td = hid_get_drvdata(hdev);
++ struct mt_device *td = hid_get_drvdata(hdev);
++
++ switch (usage->hid) {
++ case HID_DG_INPUTMODE:
+ td->inputmode = field->report->id;
++ break;
++ case HID_DG_CONTACTMAX:
++ td->maxcontacts = field->value[0];
++ if (td->mtclass->maxcontacts)
++ /* check if the maxcontacts is given by the class */
++ td->maxcontacts = td->mtclass->maxcontacts;
++
++ break;
+ }
+ }
+
+@@ -208,8 +220,7 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input
*hi,
+ td->last_slot_field = usage->hid;
+ return 1;
+ case HID_DG_CONTACTID:
+- input_mt_init_slots(hi->input,
+- td->mtclass->maxcontacts);
++ input_mt_init_slots(hi->input, td->maxcontacts);
+ td->last_slot_field = usage->hid;
+ return 1;
+ case HID_DG_WIDTH:
+@@ -292,7 +303,7 @@ static void mt_complete_slot(struct mt_device *td)
+ if (td->curvalid) {
+ int slotnum = mt_compute_slot(td);
+
+- if (slotnum >= 0 && slotnum < td->mtclass->maxcontacts)
++ if (slotnum >= 0 && slotnum < td->maxcontacts)
+ td->slots[slotnum] = td->curdata;
+ }
+ td->num_received++;
+@@ -307,7 +318,7 @@ static void mt_emit_event(struct mt_device *td, struct input_dev
*input)
+ {
+ int i;
+
+- for (i = 0; i < td->mtclass->maxcontacts; ++i) {
++ for (i = 0; i < td->maxcontacts; ++i) {
+ struct mt_slot *s = &(td->slots[i]);
+ if ((td->mtclass->quirks & MT_QUIRK_NOT_SEEN_MEANS_UP) &&
+ !s->seen_in_this_frame) {
+@@ -341,7 +352,7 @@ static int mt_event(struct hid_device *hid, struct hid_field *field,
+ struct mt_device *td = hid_get_drvdata(hid);
+ __s32 quirks = td->mtclass->quirks;
+
+- if (hid->claimed & HID_CLAIMED_INPUT) {
++ if (hid->claimed & HID_CLAIMED_INPUT && td->slots) {
+ switch (usage->hid) {
+ case HID_DG_INRANGE:
+ if (quirks & MT_QUIRK_VALID_IS_INRANGE)
+@@ -442,9 +453,7 @@ static int mt_probe(struct hid_device *hdev, const struct
hid_device_id *id)
+ */
+ hdev->quirks |= HID_QUIRK_NO_INPUT_SYNC;
+
+- td = kzalloc(sizeof(struct mt_device) +
+- mtclass->maxcontacts * sizeof(struct mt_slot),
+- GFP_KERNEL);
++ td = kzalloc(sizeof(struct mt_device), GFP_KERNEL);
+ if (!td) {
+ dev_err(&hdev->dev, "cannot allocate multitouch data\n");
+ return -ENOMEM;
+@@ -461,6 +470,18 @@ static int mt_probe(struct hid_device *hdev, const struct
hid_device_id *id)
+ if (ret)
+ goto fail;
+
++ if (!td->maxcontacts)
++ td->maxcontacts = MT_DEFAULT_MAXCONTACT;
++
++ td->slots = kzalloc(td->maxcontacts * sizeof(struct mt_slot),
++ GFP_KERNEL);
++ if (!td->slots) {
++ dev_err(&hdev->dev, "cannot allocate multitouch slots\n");
++ hid_hw_stop(hdev);
++ ret = -ENOMEM;
++ goto fail;
++ }
++
+ mt_set_input_mode(hdev);
+
+ return 0;
+@@ -482,6 +503,7 @@ static void mt_remove(struct hid_device *hdev)
+ {
+ struct mt_device *td = hid_get_drvdata(hdev);
+ hid_hw_stop(hdev);
++ kfree(td->slots);
+ kfree(td);
+ hid_set_drvdata(hdev, NULL);
+ }
+commit 043b403aede4a528ed99ceaf050f567f1283a23e
+Author: Benjamin Tissoires <benjamin.tissoires(a)enac.fr>
+Date: Fri Mar 18 14:27:53 2011 +0100
-Signed-off-by: Benjamin Tissoires <benjamin.tissoires(a)enac.fr>
-Tested-by: Bastien Nocera <hadess(a)hadess.net>
-Signed-off-by: Jiri Kosina <jkosina(a)suse.cz>
+ HID: hid-multitouch: migrate support for Stantum panels to the unified driver.
+
+ This patch merges hid-stantum to the generic multitouch driver.
+
+ Signed-off-by: Benjamin Tissoires <benjamin.tissoires(a)enac.fr>
+ Reviewed-by: Stéphane Chatty <chatty(a)enac.fr>
+ Reviewed-by: Henrik Rydberg <rydberg(a)euromail.se>
+ Signed-off-by: Jiri Kosina <jkosina(a)suse.cz>
+diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig
+index b7ec405..3c72f16 100644
--- a/drivers/hid/Kconfig
+++ b/drivers/hid/Kconfig
-@@ -309,6 +309,7 @@ config HID_MULTITOUCH
+@@ -327,6 +327,7 @@ config HID_MULTITOUCH
+ - 'Sensing Win7-TwoFinger' panel by GeneralTouch
+ - eGalax dual-touch panels, including the
+ Joojoo and Wetab tablets
++ - Stantum multitouch panels
+
+ If unsure, say N.
+
+@@ -493,12 +494,6 @@ config HID_SONY
+ ---help---
+ Support for Sony PS3 controller.
+
+-config HID_STANTUM
+- tristate "Stantum multitouch panel"
+- depends on USB_HID
+- ---help---
+- Support for Stantum multitouch panel.
+-
+ config HID_SUNPLUS
+ tristate "Sunplus wireless desktop"
+ depends on USB_HID
+diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile
+index 06c68ae..a13cb4e 100644
+--- a/drivers/hid/Makefile
++++ b/drivers/hid/Makefile
+@@ -66,7 +66,6 @@ obj-$(CONFIG_HID_ROCCAT_PYRA) += hid-roccat-pyra.o
+ obj-$(CONFIG_HID_SAMSUNG) += hid-samsung.o
+ obj-$(CONFIG_HID_SMARTJOYPLUS) += hid-sjoy.o
+ obj-$(CONFIG_HID_SONY) += hid-sony.o
+-obj-$(CONFIG_HID_STANTUM) += hid-stantum.o
+ obj-$(CONFIG_HID_SUNPLUS) += hid-sunplus.o
+ obj-$(CONFIG_HID_GREENASIA) += hid-gaff.o
+ obj-$(CONFIG_HID_THRUSTMASTER) += hid-tmff.o
+diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c
+index b9f9eec..5983e55 100644
+--- a/drivers/hid/hid-multitouch.c
++++ b/drivers/hid/hid-multitouch.c
+@@ -79,6 +79,7 @@ struct mt_class {
+ #define MT_CLS_DUAL_INRANGE_CONTACTNUMBER 3
+ #define MT_CLS_CYPRESS 4
+ #define MT_CLS_EGALAX 5
++#define MT_CLS_STANTUM 6
+
+ #define MT_DEFAULT_MAXCONTACT 10
+
+@@ -138,6 +139,9 @@ struct mt_class mt_classes[] = {
+ .sn_move = 4096,
+ .sn_pressure = 32,
+ },
++ { .name = MT_CLS_STANTUM,
++ .quirks = MT_QUIRK_VALID_IS_CONFIDENCE },
++
+ { }
+ };
+
+@@ -552,6 +556,17 @@ static const struct hid_device_id mt_devices[] = {
+ HID_USB_DEVICE(USB_VENDOR_ID_DWAV,
+ USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH4) },
+
++ /* Stantum panels */
++ { .driver_data = MT_CLS_STANTUM,
++ HID_USB_DEVICE(USB_VENDOR_ID_STANTUM,
++ USB_DEVICE_ID_MTP)},
++ { .driver_data = MT_CLS_STANTUM,
++ HID_USB_DEVICE(USB_VENDOR_ID_STANTUM,
++ USB_DEVICE_ID_MTP_STM)},
++ { .driver_data = MT_CLS_STANTUM,
++ HID_USB_DEVICE(USB_VENDOR_ID_STANTUM,
++ USB_DEVICE_ID_MTP_SITRONIX)},
++
+ { }
+ };
+ MODULE_DEVICE_TABLE(hid, mt_devices);
+diff --git a/drivers/hid/hid-stantum.c b/drivers/hid/hid-stantum.c
+deleted file mode 100644
+index b2be1d1..0000000
+--- a/drivers/hid/hid-stantum.c
++++ /dev/null
+@@ -1,286 +0,0 @@
+-/*
+- * HID driver for Stantum multitouch panels
+- *
+- * Copyright (c) 2009 Stephane Chatty <chatty(a)enac.fr>
+- *
+- */
+-
+-/*
+- * 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/device.h>
+-#include <linux/hid.h>
+-#include <linux/module.h>
+-#include <linux/slab.h>
+-
+-MODULE_AUTHOR("Stephane Chatty <chatty(a)enac.fr>");
+-MODULE_DESCRIPTION("Stantum HID multitouch panels");
+-MODULE_LICENSE("GPL");
+-
+-#include "hid-ids.h"
+-
+-struct stantum_data {
+- __s32 x, y, z, w, h; /* x, y, pressure, width, height */
+- __u16 id; /* touch id */
+- bool valid; /* valid finger data, or just placeholder? */
+- bool first; /* first finger in the HID packet? */
+- bool activity; /* at least one active finger so far? */
+-};
+-
+-static int stantum_input_mapping(struct hid_device *hdev, struct hid_input *hi,
+- struct hid_field *field, struct hid_usage *usage,
+- unsigned long **bit, int *max)
+-{
+- switch (usage->hid & HID_USAGE_PAGE) {
+-
+- case HID_UP_GENDESK:
+- switch (usage->hid) {
+- case HID_GD_X:
+- hid_map_usage(hi, usage, bit, max,
+- EV_ABS, ABS_MT_POSITION_X);
+- /* touchscreen emulation */
+- input_set_abs_params(hi->input, ABS_X,
+- field->logical_minimum,
+- field->logical_maximum, 0, 0);
+- return 1;
+- case HID_GD_Y:
+- hid_map_usage(hi, usage, bit, max,
+- EV_ABS, ABS_MT_POSITION_Y);
+- /* touchscreen emulation */
+- input_set_abs_params(hi->input, ABS_Y,
+- field->logical_minimum,
+- field->logical_maximum, 0, 0);
+- return 1;
+- }
+- return 0;
+-
+- case HID_UP_DIGITIZER:
+- switch (usage->hid) {
+- case HID_DG_INRANGE:
+- case HID_DG_CONFIDENCE:
+- case HID_DG_INPUTMODE:
+- case HID_DG_DEVICEINDEX:
+- case HID_DG_CONTACTCOUNT:
+- case HID_DG_CONTACTMAX:
+- return -1;
+-
+- case HID_DG_TIPSWITCH:
+- /* touchscreen emulation */
+- hid_map_usage(hi, usage, bit, max, EV_KEY, BTN_TOUCH);
+- return 1;
+-
+- case HID_DG_WIDTH:
+- hid_map_usage(hi, usage, bit, max,
+- EV_ABS, ABS_MT_TOUCH_MAJOR);
+- return 1;
+- case HID_DG_HEIGHT:
+- hid_map_usage(hi, usage, bit, max,
+- EV_ABS, ABS_MT_TOUCH_MINOR);
+- input_set_abs_params(hi->input, ABS_MT_ORIENTATION,
+- 1, 1, 0, 0);
+- return 1;
+- case HID_DG_TIPPRESSURE:
+- hid_map_usage(hi, usage, bit, max,
+- EV_ABS, ABS_MT_PRESSURE);
+- return 1;
+-
+- case HID_DG_CONTACTID:
+- hid_map_usage(hi, usage, bit, max,
+- EV_ABS, ABS_MT_TRACKING_ID);
+- return 1;
+-
+- }
+- return 0;
+-
+- case 0xff000000:
+- /* no input-oriented meaning */
+- return -1;
+- }
+-
+- return 0;
+-}
+-
+-static int stantum_input_mapped(struct hid_device *hdev, struct hid_input *hi,
+- struct hid_field *field, struct hid_usage *usage,
+- unsigned long **bit, int *max)
+-{
+- if (usage->type == EV_KEY || usage->type == EV_ABS)
+- clear_bit(usage->code, *bit);
+-
+- return 0;
+-}
+-
+-/*
+- * this function is called when a whole finger has been parsed,
+- * so that it can decide what to send to the input layer.
+- */
+-static void stantum_filter_event(struct stantum_data *sd,
+- struct input_dev *input)
+-{
+- bool wide;
+-
+- if (!sd->valid) {
+- /*
+- * touchscreen emulation: if the first finger is not valid and
+- * there previously was finger activity, this is a release
+- */
+- if (sd->first && sd->activity) {
+- input_event(input, EV_KEY, BTN_TOUCH, 0);
+- sd->activity = false;
+- }
+- return;
+- }
+-
+- input_event(input, EV_ABS, ABS_MT_TRACKING_ID, sd->id);
+- input_event(input, EV_ABS, ABS_MT_POSITION_X, sd->x);
+- input_event(input, EV_ABS, ABS_MT_POSITION_Y, sd->y);
+-
+- wide = (sd->w > sd->h);
+- input_event(input, EV_ABS, ABS_MT_ORIENTATION, wide);
+- input_event(input, EV_ABS, ABS_MT_TOUCH_MAJOR, wide ? sd->w : sd->h);
+- input_event(input, EV_ABS, ABS_MT_TOUCH_MINOR, wide ? sd->h : sd->w);
+-
+- input_event(input, EV_ABS, ABS_MT_PRESSURE, sd->z);
+-
+- input_mt_sync(input);
+- sd->valid = false;
+-
+- /* touchscreen emulation */
+- if (sd->first) {
+- if (!sd->activity) {
+- input_event(input, EV_KEY, BTN_TOUCH, 1);
+- sd->activity = true;
+- }
+- input_event(input, EV_ABS, ABS_X, sd->x);
+- input_event(input, EV_ABS, ABS_Y, sd->y);
+- }
+- sd->first = false;
+-}
+-
+-
+-static int stantum_event(struct hid_device *hid, struct hid_field *field,
+- struct hid_usage *usage, __s32 value)
+-{
+- struct stantum_data *sd = hid_get_drvdata(hid);
+-
+- if (hid->claimed & HID_CLAIMED_INPUT) {
+- struct input_dev *input = field->hidinput->input;
+-
+- switch (usage->hid) {
+- case HID_DG_INRANGE:
+- /* this is the last field in a finger */
+- stantum_filter_event(sd, input);
+- break;
+- case HID_DG_WIDTH:
+- sd->w = value;
+- break;
+- case HID_DG_HEIGHT:
+- sd->h = value;
+- break;
+- case HID_GD_X:
+- sd->x = value;
+- break;
+- case HID_GD_Y:
+- sd->y = value;
+- break;
+- case HID_DG_TIPPRESSURE:
+- sd->z = value;
+- break;
+- case HID_DG_CONTACTID:
+- sd->id = value;
+- break;
+- case HID_DG_CONFIDENCE:
+- sd->valid = !!value;
+- break;
+- case 0xff000002:
+- /* this comes only before the first finger */
+- sd->first = true;
+- break;
+-
+- default:
+- /* ignore the others */
+- return 1;
+- }
+- }
+-
+- /* we have handled the hidinput part, now remains hiddev */
+- if (hid->claimed & HID_CLAIMED_HIDDEV && hid->hiddev_hid_event)
+- hid->hiddev_hid_event(hid, field, usage, value);
+-
+- return 1;
+-}
+-
+-static int stantum_probe(struct hid_device *hdev,
+- const struct hid_device_id *id)
+-{
+- int ret;
+- struct stantum_data *sd;
+-
+- sd = kmalloc(sizeof(struct stantum_data), GFP_KERNEL);
+- if (!sd) {
+- hid_err(hdev, "cannot allocate Stantum data\n");
+- return -ENOMEM;
+- }
+- sd->valid = false;
+- sd->first = false;
+- sd->activity = false;
+- hid_set_drvdata(hdev, sd);
+-
+- ret = hid_parse(hdev);
+- if (!ret)
+- ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
+-
+- if (ret)
+- kfree(sd);
+-
+- return ret;
+-}
+-
+-static void stantum_remove(struct hid_device *hdev)
+-{
+- hid_hw_stop(hdev);
+- kfree(hid_get_drvdata(hdev));
+- hid_set_drvdata(hdev, NULL);
+-}
+-
+-static const struct hid_device_id stantum_devices[] = {
+- { HID_USB_DEVICE(USB_VENDOR_ID_STANTUM, USB_DEVICE_ID_MTP) },
+- { HID_USB_DEVICE(USB_VENDOR_ID_STANTUM_STM, USB_DEVICE_ID_MTP_STM) },
+- { HID_USB_DEVICE(USB_VENDOR_ID_STANTUM_SITRONIX, USB_DEVICE_ID_MTP_SITRONIX) },
+- { }
+-};
+-MODULE_DEVICE_TABLE(hid, stantum_devices);
+-
+-static const struct hid_usage_id stantum_grabbed_usages[] = {
+- { HID_ANY_ID, HID_ANY_ID, HID_ANY_ID },
+- { HID_ANY_ID - 1, HID_ANY_ID - 1, HID_ANY_ID - 1}
+-};
+-
+-static struct hid_driver stantum_driver = {
+- .name = "stantum",
+- .id_table = stantum_devices,
+- .probe = stantum_probe,
+- .remove = stantum_remove,
+- .input_mapping = stantum_input_mapping,
+- .input_mapped = stantum_input_mapped,
+- .usage_table = stantum_grabbed_usages,
+- .event = stantum_event,
+-};
+-
+-static int __init stantum_init(void)
+-{
+- return hid_register_driver(&stantum_driver);
+-}
+-
+-static void __exit stantum_exit(void)
+-{
+- hid_unregister_driver(&stantum_driver);
+-}
+-
+-module_init(stantum_init);
+-module_exit(stantum_exit);
+-
+commit a841b62c5d5f75ce3676fde755696d30cc8de99a
+Author: Benjamin Tissoires <benjamin.tissoires(a)enac.fr>
+Date: Fri Mar 18 14:27:54 2011 +0100
+
+ HID: hid-multitouch: migrate Cando dual touch panels to hid-multitouch
+
+ This patch merges hid-cando into the unified multitouch driver.
+
+ Signed-off-by: Benjamin Tissoires <benjamin.tissoires(a)enac.fr>
+ Reviewed-by: Stéphane Chatty <chatty(a)enac.fr>
+ Reviewed-by: Henrik Rydberg <rydberg(a)euromail.se>
+ Signed-off-by: Jiri Kosina <jkosina(a)suse.cz>
+
+diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig
+index 3c72f16..1edb0bd 100644
+--- a/drivers/hid/Kconfig
++++ b/drivers/hid/Kconfig
+@@ -100,12 +100,6 @@ config HID_BELKIN
+ ---help---
+ Support for Belkin Flip KVM and Wireless keyboard.
+
+-config HID_CANDO
+- tristate "Cando dual touch panel"
+- depends on USB_HID
+- ---help---
+- Support for Cando dual touch panel.
+-
+ config HID_CHERRY
+ tristate "Cherry Cymotion keyboard" if EXPERT
+ depends on USB_HID
+@@ -320,6 +314,7 @@ config HID_MULTITOUCH
+ Generic support for HID multitouch panels.
Say Y here if you have one of the following devices:
++ - Cando dual touch panel
- Cypress TrueTouch panels
-+ - Elo TouchSystems IntelliTouch Plus panels
- Hanvon dual touch panels
+ - IrTouch Infrared USB panels
+diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile
+index a13cb4e..f8b90e4 100644
+--- a/drivers/hid/Makefile
++++ b/drivers/hid/Makefile
+@@ -30,7 +30,6 @@ obj-$(CONFIG_HID_A4TECH) += hid-a4tech.o
+ obj-$(CONFIG_HID_ACRUX) += hid-axff.o
+ obj-$(CONFIG_HID_APPLE) += hid-apple.o
+ obj-$(CONFIG_HID_BELKIN) += hid-belkin.o
+-obj-$(CONFIG_HID_CANDO) += hid-cando.o
+ obj-$(CONFIG_HID_CHERRY) += hid-cherry.o
+ obj-$(CONFIG_HID_CHICONY) += hid-chicony.o
+ obj-$(CONFIG_HID_CYPRESS) += hid-cypress.o
+diff --git a/drivers/hid/hid-cando.c b/drivers/hid/hid-cando.c
+deleted file mode 100644
+index 1ea066c..0000000
+--- a/drivers/hid/hid-cando.c
++++ /dev/null
+@@ -1,276 +0,0 @@
+-/*
+- * HID driver for Cando dual-touch panels
+- *
+- * Copyright (c) 2010 Stephane Chatty <chatty(a)enac.fr>
+- *
+- */
+-
+-/*
+- * 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/device.h>
+-#include <linux/hid.h>
+-#include <linux/module.h>
+-#include <linux/slab.h>
+-
+-MODULE_AUTHOR("Stephane Chatty <chatty(a)enac.fr>");
+-MODULE_DESCRIPTION("Cando dual-touch panel");
+-MODULE_LICENSE("GPL");
+-
+-#include "hid-ids.h"
+-
+-struct cando_data {
+- __u16 x, y;
+- __u8 id;
+- __s8 oldest; /* id of the oldest finger in previous frame */
+- bool valid; /* valid finger data, or just placeholder? */
+- bool first; /* is this the first finger in this frame? */
+- __s8 firstid; /* id of the first finger in the frame */
+- __u16 firstx, firsty; /* (x, y) of the first finger in the frame */
+-};
+-
+-static int cando_input_mapping(struct hid_device *hdev, struct hid_input *hi,
+- struct hid_field *field, struct hid_usage *usage,
+- unsigned long **bit, int *max)
+-{
+- switch (usage->hid & HID_USAGE_PAGE) {
+-
+- case HID_UP_GENDESK:
+- switch (usage->hid) {
+- case HID_GD_X:
+- hid_map_usage(hi, usage, bit, max,
+- EV_ABS, ABS_MT_POSITION_X);
+- /* touchscreen emulation */
+- input_set_abs_params(hi->input, ABS_X,
+- field->logical_minimum,
+- field->logical_maximum, 0, 0);
+- return 1;
+- case HID_GD_Y:
+- hid_map_usage(hi, usage, bit, max,
+- EV_ABS, ABS_MT_POSITION_Y);
+- /* touchscreen emulation */
+- input_set_abs_params(hi->input, ABS_Y,
+- field->logical_minimum,
+- field->logical_maximum, 0, 0);
+- return 1;
+- }
+- return 0;
+-
+- case HID_UP_DIGITIZER:
+- switch (usage->hid) {
+- case HID_DG_TIPSWITCH:
+- case HID_DG_CONTACTMAX:
+- return -1;
+- case HID_DG_INRANGE:
+- /* touchscreen emulation */
+- hid_map_usage(hi, usage, bit, max, EV_KEY, BTN_TOUCH);
+- return 1;
+- case HID_DG_CONTACTID:
+- hid_map_usage(hi, usage, bit, max,
+- EV_ABS, ABS_MT_TRACKING_ID);
+- return 1;
+- }
+- return 0;
+- }
+-
+- return 0;
+-}
+-
+-static int cando_input_mapped(struct hid_device *hdev, struct hid_input *hi,
+- struct hid_field *field, struct hid_usage *usage,
+- unsigned long **bit, int *max)
+-{
+- if (usage->type == EV_KEY || usage->type == EV_ABS)
+- clear_bit(usage->code, *bit);
+-
+- return 0;
+-}
+-
+-/*
+- * this function is called when a whole finger has been parsed,
+- * so that it can decide what to send to the input layer.
+- */
+-static void cando_filter_event(struct cando_data *td, struct input_dev *input)
+-{
+- td->first = !td->first; /* touchscreen emulation */
+-
+- if (!td->valid) {
+- /*
+- * touchscreen emulation: if this is the second finger and
+- * the first was valid, the first was the oldest; if the
+- * first was not valid and there was a valid finger in the
+- * previous frame, this is a release.
+- */
+- if (td->first) {
+- td->firstid = -1;
+- } else if (td->firstid >= 0) {
+- input_event(input, EV_ABS, ABS_X, td->firstx);
+- input_event(input, EV_ABS, ABS_Y, td->firsty);
+- td->oldest = td->firstid;
+- } else if (td->oldest >= 0) {
+- input_event(input, EV_KEY, BTN_TOUCH, 0);
+- td->oldest = -1;
+- }
+-
+- return;
+- }
+-
+- input_event(input, EV_ABS, ABS_MT_TRACKING_ID, td->id);
+- input_event(input, EV_ABS, ABS_MT_POSITION_X, td->x);
+- input_event(input, EV_ABS, ABS_MT_POSITION_Y, td->y);
+-
+- input_mt_sync(input);
+-
+- /*
+- * touchscreen emulation: if there was no touching finger previously,
+- * emit touch event
+- */
+- if (td->oldest < 0) {
+- input_event(input, EV_KEY, BTN_TOUCH, 1);
+- td->oldest = td->id;
+- }
+-
+- /*
+- * touchscreen emulation: if this is the first finger, wait for the
+- * second; the oldest is then the second if it was the oldest already
+- * or if there was no first, the first otherwise.
+- */
+- if (td->first) {
+- td->firstx = td->x;
+- td->firsty = td->y;
+- td->firstid = td->id;
+- } else {
+- int x, y, oldest;
+- if (td->id == td->oldest || td->firstid < 0) {
+- x = td->x;
+- y = td->y;
+- oldest = td->id;
+- } else {
+- x = td->firstx;
+- y = td->firsty;
+- oldest = td->firstid;
+- }
+- input_event(input, EV_ABS, ABS_X, x);
+- input_event(input, EV_ABS, ABS_Y, y);
+- td->oldest = oldest;
+- }
+-}
+-
+-
+-static int cando_event(struct hid_device *hid, struct hid_field *field,
+- struct hid_usage *usage, __s32 value)
+-{
+- struct cando_data *td = hid_get_drvdata(hid);
+-
+- if (hid->claimed & HID_CLAIMED_INPUT) {
+- struct input_dev *input = field->hidinput->input;
+-
+- switch (usage->hid) {
+- case HID_DG_INRANGE:
+- td->valid = value;
+- break;
+- case HID_DG_CONTACTID:
+- td->id = value;
+- break;
+- case HID_GD_X:
+- td->x = value;
+- break;
+- case HID_GD_Y:
+- td->y = value;
+- cando_filter_event(td, input);
+- break;
+- case HID_DG_TIPSWITCH:
+- /* avoid interference from generic hidinput handling */
+- break;
+-
+- default:
+- /* fallback to the generic hidinput handling */
+- return 0;
+- }
+- }
+-
+- /* we have handled the hidinput part, now remains hiddev */
+- if (hid->claimed & HID_CLAIMED_HIDDEV && hid->hiddev_hid_event)
+- hid->hiddev_hid_event(hid, field, usage, value);
+-
+- return 1;
+-}
+-
+-static int cando_probe(struct hid_device *hdev, const struct hid_device_id *id)
+-{
+- int ret;
+- struct cando_data *td;
+-
+- td = kmalloc(sizeof(struct cando_data), GFP_KERNEL);
+- if (!td) {
+- hid_err(hdev, "cannot allocate Cando Touch data\n");
+- return -ENOMEM;
+- }
+- hid_set_drvdata(hdev, td);
+- td->first = false;
+- td->oldest = -1;
+- td->valid = false;
+-
+- ret = hid_parse(hdev);
+- if (!ret)
+- ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
+-
+- if (ret)
+- kfree(td);
+-
+- return ret;
+-}
+-
+-static void cando_remove(struct hid_device *hdev)
+-{
+- hid_hw_stop(hdev);
+- kfree(hid_get_drvdata(hdev));
+- hid_set_drvdata(hdev, NULL);
+-}
+-
+-static const struct hid_device_id cando_devices[] = {
+- { HID_USB_DEVICE(USB_VENDOR_ID_CANDO,
+- USB_DEVICE_ID_CANDO_MULTI_TOUCH) },
+- { HID_USB_DEVICE(USB_VENDOR_ID_CANDO,
+- USB_DEVICE_ID_CANDO_MULTI_TOUCH_10_1) },
+- { HID_USB_DEVICE(USB_VENDOR_ID_CANDO,
+- USB_DEVICE_ID_CANDO_MULTI_TOUCH_11_6) },
+- { HID_USB_DEVICE(USB_VENDOR_ID_CANDO,
+- USB_DEVICE_ID_CANDO_MULTI_TOUCH_15_6) },
+- { }
+-};
+-MODULE_DEVICE_TABLE(hid, cando_devices);
+-
+-static const struct hid_usage_id cando_grabbed_usages[] = {
+- { HID_ANY_ID, HID_ANY_ID, HID_ANY_ID },
+- { HID_ANY_ID - 1, HID_ANY_ID - 1, HID_ANY_ID - 1}
+-};
+-
+-static struct hid_driver cando_driver = {
+- .name = "cando-touch",
+- .id_table = cando_devices,
+- .probe = cando_probe,
+- .remove = cando_remove,
+- .input_mapping = cando_input_mapping,
+- .input_mapped = cando_input_mapped,
+- .usage_table = cando_grabbed_usages,
+- .event = cando_event,
+-};
+-
+-static int __init cando_init(void)
+-{
+- return hid_register_driver(&cando_driver);
+-}
+-
+-static void __exit cando_exit(void)
+-{
+- hid_unregister_driver(&cando_driver);
+-}
+-
+-module_init(cando_init);
+-module_exit(cando_exit);
+-
+diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c
+index 5983e55..e6e1ea2 100644
+--- a/drivers/hid/hid-multitouch.c
++++ b/drivers/hid/hid-multitouch.c
+@@ -514,6 +514,20 @@ static void mt_remove(struct hid_device *hdev)
+
+ static const struct hid_device_id mt_devices[] = {
+
++ /* Cando panels */
++ { .driver_data = MT_CLS_DUAL_INRANGE_CONTACTNUMBER,
++ HID_USB_DEVICE(USB_VENDOR_ID_CANDO,
++ USB_DEVICE_ID_CANDO_MULTI_TOUCH) },
++ { .driver_data = MT_CLS_DUAL_INRANGE_CONTACTNUMBER,
++ HID_USB_DEVICE(USB_VENDOR_ID_CANDO,
++ USB_DEVICE_ID_CANDO_MULTI_TOUCH_10_1) },
++ { .driver_data = MT_CLS_DUAL_INRANGE_CONTACTNUMBER,
++ HID_USB_DEVICE(USB_VENDOR_ID_CANDO,
++ USB_DEVICE_ID_CANDO_MULTI_TOUCH_11_6) },
++ { .driver_data = MT_CLS_DUAL_INRANGE_CONTACTNUMBER,
++ HID_USB_DEVICE(USB_VENDOR_ID_CANDO,
++ USB_DEVICE_ID_CANDO_MULTI_TOUCH_15_6) },
++
+ /* Cypress panel */
+ { .driver_data = MT_CLS_CYPRESS,
+ HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS,
+commit 1e648a13720ef5de51f132501acf3e443d1a36d4
+Author: Benjamin Tissoires <benjamin.tissoires(a)enac.fr>
+Date: Fri Mar 18 14:27:55 2011 +0100
+
+ HID: hid-multitouch: refactor initialization of ABS_MT_ORIENTATION
+
+ The way the input_set_abs_params was called for the new composite field
+ ABS_MT_ORIENTATION was not very clear at second reading. We can remove the
+ non-necessary call to set_abs and use the simple call to input_set_abs_params.
+
+ Signed-off-by: Benjamin Tissoires <benjamin.tissoires(a)enac.fr>
+ Reviewed-by: Stéphane Chatty <chatty(a)enac.fr>
+ Signed-off-by: Jiri Kosina <jkosina(a)suse.cz>
+
+diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c
+index e6e1ea2..d31301e 100644
+--- a/drivers/hid/hid-multitouch.c
++++ b/drivers/hid/hid-multitouch.c
+@@ -235,9 +235,8 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input
*hi,
+ case HID_DG_HEIGHT:
+ hid_map_usage(hi, usage, bit, max,
+ EV_ABS, ABS_MT_TOUCH_MINOR);
+- field->logical_maximum = 1;
+- field->logical_minimum = 0;
+- set_abs(hi->input, ABS_MT_ORIENTATION, field, 0);
++ input_set_abs_params(hi->input,
++ ABS_MT_ORIENTATION, 0, 1, 0, 0);
+ td->last_slot_field = usage->hid;
+ return 1;
+ case HID_DG_TIPPRESSURE:
+commit f786bba4499cf3de20da345ce090457ebcef03b0
+Author: Benjamin Tissoires <benjamin.tissoires(a)enac.fr>
+Date: Tue Mar 22 17:34:01 2011 +0100
+
+ HID: hid-multitouch: migrate 3M PCT touch screens to hid-multitouch
+
+ This patch merges the hid-3m-pct driver into hid-multitouch.
+ To keep devices working the same way they used to with hid-3m-pct,
+ we need to add two signal/noise ratios for width and height.
+ We also need to work on width/height to send proper
+ ABS_MT_ORIENTATION flag.
+
+ Importing 3M into hid-multitouch also solved the bug in which
+ devices handling width and height in their report descriptors
+ did not show ABS_MT_TOUCH_MAJOR and ABS_MT_TOUCH_MINOR.
+
+ Signed-off-by: Benjamin Tissoires <benjamin.tissoires(a)enac.fr>
+ Reviewed-by: Stéphane Chatty <chatty(a)enac.fr>
+ Reviewed-and-tested-by: Henrik Rydberg <rydberg(a)euromail.se>
+ Signed-off-by: Jiri Kosina <jkosina(a)suse.cz>
+
+diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig
+index 1edb0bd..996ae3a 100644
+--- a/drivers/hid/Kconfig
++++ b/drivers/hid/Kconfig
+@@ -55,12 +55,6 @@ source "drivers/hid/usbhid/Kconfig"
+ menu "Special HID drivers"
+ depends on HID
+
+-config HID_3M_PCT
+- tristate "3M PCT touchscreen"
+- depends on USB_HID
+- ---help---
+- Support for 3M PCT touch screens.
+-
+ config HID_A4TECH
+ tristate "A4 tech mice" if EXPERT
+ depends on USB_HID
+@@ -314,6 +308,7 @@ config HID_MULTITOUCH
+ Generic support for HID multitouch panels.
+
+ Say Y here if you have one of the following devices:
++ - 3M PCT touch screens
+ - Cando dual touch panel
+ - Cypress TrueTouch panels
+ - Hanvon dual touch panels
+diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile
+index f8b90e4..11c9f0b 100644
+--- a/drivers/hid/Makefile
++++ b/drivers/hid/Makefile
+@@ -25,7 +25,6 @@ ifdef CONFIG_LOGIWII_FF
+ hid-logitech-y += hid-lg4ff.o
+ endif
+
+-obj-$(CONFIG_HID_3M_PCT) += hid-3m-pct.o
+ obj-$(CONFIG_HID_A4TECH) += hid-a4tech.o
+ obj-$(CONFIG_HID_ACRUX) += hid-axff.o
+ obj-$(CONFIG_HID_APPLE) += hid-apple.o
+diff --git a/drivers/hid/hid-3m-pct.c b/drivers/hid/hid-3m-pct.c
+deleted file mode 100644
+index 5243ae2..0000000
+--- a/drivers/hid/hid-3m-pct.c
++++ /dev/null
+@@ -1,305 +0,0 @@
+-/*
+- * HID driver for 3M PCT multitouch panels
+- *
+- * Copyright (c) 2009-2010 Stephane Chatty <chatty(a)enac.fr>
+- * Copyright (c) 2010 Henrik Rydberg <rydberg(a)euromail.se>
+- * Copyright (c) 2010 Canonical, Ltd.
+- *
+- */
+-
+-/*
+- * 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/device.h>
+-#include <linux/hid.h>
+-#include <linux/module.h>
+-#include <linux/slab.h>
+-#include <linux/usb.h>
+-#include <linux/input/mt.h>
+-
+-MODULE_AUTHOR("Stephane Chatty <chatty(a)enac.fr>");
+-MODULE_DESCRIPTION("3M PCT multitouch panels");
+-MODULE_LICENSE("GPL");
+-
+-#include "hid-ids.h"
+-
+-#define MAX_SLOTS 60
+-
+-/* estimated signal-to-noise ratios */
+-#define SN_MOVE 2048
+-#define SN_WIDTH 128
+-
+-struct mmm_finger {
+- __s32 x, y, w, h;
+- bool touch, valid;
+-};
+-
+-struct mmm_data {
+- struct mmm_finger f[MAX_SLOTS];
+- __u8 curid;
+- __u8 nexp, nreal;
+- bool touch, valid;
+-};
+-
+-static int mmm_input_mapping(struct hid_device *hdev, struct hid_input *hi,
+- struct hid_field *field, struct hid_usage *usage,
+- unsigned long **bit, int *max)
+-{
+- int f1 = field->logical_minimum;
+- int f2 = field->logical_maximum;
+- int df = f2 - f1;
+-
+- switch (usage->hid & HID_USAGE_PAGE) {
+-
+- case HID_UP_BUTTON:
+- return -1;
+-
+- case HID_UP_GENDESK:
+- switch (usage->hid) {
+- case HID_GD_X:
+- hid_map_usage(hi, usage, bit, max,
+- EV_ABS, ABS_MT_POSITION_X);
+- input_set_abs_params(hi->input, ABS_MT_POSITION_X,
+- f1, f2, df / SN_MOVE, 0);
+- /* touchscreen emulation */
+- input_set_abs_params(hi->input, ABS_X,
+- f1, f2, df / SN_MOVE, 0);
+- return 1;
+- case HID_GD_Y:
+- hid_map_usage(hi, usage, bit, max,
+- EV_ABS, ABS_MT_POSITION_Y);
+- input_set_abs_params(hi->input, ABS_MT_POSITION_Y,
+- f1, f2, df / SN_MOVE, 0);
+- /* touchscreen emulation */
+- input_set_abs_params(hi->input, ABS_Y,
+- f1, f2, df / SN_MOVE, 0);
+- return 1;
+- }
+- return 0;
+-
+- case HID_UP_DIGITIZER:
+- switch (usage->hid) {
+- /* we do not want to map these: no input-oriented meaning */
+- case 0x14:
+- case 0x23:
+- case HID_DG_INPUTMODE:
+- case HID_DG_DEVICEINDEX:
+- case HID_DG_CONTACTCOUNT:
+- case HID_DG_CONTACTMAX:
+- case HID_DG_INRANGE:
+- case HID_DG_CONFIDENCE:
+- return -1;
+- case HID_DG_TIPSWITCH:
+- /* touchscreen emulation */
+- hid_map_usage(hi, usage, bit, max, EV_KEY, BTN_TOUCH);
+- input_set_capability(hi->input, EV_KEY, BTN_TOUCH);
+- return 1;
+- case HID_DG_WIDTH:
+- hid_map_usage(hi, usage, bit, max,
+- EV_ABS, ABS_MT_TOUCH_MAJOR);
+- input_set_abs_params(hi->input, ABS_MT_TOUCH_MAJOR,
+- f1, f2, df / SN_WIDTH, 0);
+- return 1;
+- case HID_DG_HEIGHT:
+- hid_map_usage(hi, usage, bit, max,
+- EV_ABS, ABS_MT_TOUCH_MINOR);
+- input_set_abs_params(hi->input, ABS_MT_TOUCH_MINOR,
+- f1, f2, df / SN_WIDTH, 0);
+- input_set_abs_params(hi->input, ABS_MT_ORIENTATION,
+- 0, 1, 0, 0);
+- return 1;
+- case HID_DG_CONTACTID:
+- input_mt_init_slots(hi->input, MAX_SLOTS);
+- return 1;
+- }
+- /* let hid-input decide for the others */
+- return 0;
+-
+- case 0xff000000:
+- /* we do not want to map these: no input-oriented meaning */
+- return -1;
+- }
+-
+- return 0;
+-}
+-
+-static int mmm_input_mapped(struct hid_device *hdev, struct hid_input *hi,
+- struct hid_field *field, struct hid_usage *usage,
+- unsigned long **bit, int *max)
+-{
+- /* tell hid-input to skip setup of these event types */
+- if (usage->type == EV_KEY || usage->type == EV_ABS)
+- set_bit(usage->type, hi->input->evbit);
+- return -1;
+-}
+-
+-/*
+- * this function is called when a whole packet has been received and processed,
+- * so that it can decide what to send to the input layer.
+- */
+-static void mmm_filter_event(struct mmm_data *md, struct input_dev *input)
+-{
+- int i;
+- for (i = 0; i < MAX_SLOTS; ++i) {
+- struct mmm_finger *f = &md->f[i];
+- if (!f->valid) {
+- /* this finger is just placeholder data, ignore */
+- continue;
+- }
+- input_mt_slot(input, i);
+- input_mt_report_slot_state(input, MT_TOOL_FINGER, f->touch);
+- if (f->touch) {
+- /* this finger is on the screen */
+- int wide = (f->w > f->h);
+- /* divided by two to match visual scale of touch */
+- int major = max(f->w, f->h) >> 1;
+- int minor = min(f->w, f->h) >> 1;
+-
+- input_event(input, EV_ABS, ABS_MT_POSITION_X, f->x);
+- input_event(input, EV_ABS, ABS_MT_POSITION_Y, f->y);
+- input_event(input, EV_ABS, ABS_MT_ORIENTATION, wide);
+- input_event(input, EV_ABS, ABS_MT_TOUCH_MAJOR, major);
+- input_event(input, EV_ABS, ABS_MT_TOUCH_MINOR, minor);
+- }
+- f->valid = 0;
+- }
+-
+- input_mt_report_pointer_emulation(input, true);
+- input_sync(input);
+-}
+-
+-/*
+- * this function is called upon all reports
+- * so that we can accumulate contact point information,
+- * and call input_mt_sync after each point.
+- */
+-static int mmm_event(struct hid_device *hid, struct hid_field *field,
+- struct hid_usage *usage, __s32 value)
+-{
+- struct mmm_data *md = hid_get_drvdata(hid);
+- /*
+- * strangely, this function can be called before
+- * field->hidinput is initialized!
+- */
+- if (hid->claimed & HID_CLAIMED_INPUT) {
+- struct input_dev *input = field->hidinput->input;
+- switch (usage->hid) {
+- case HID_DG_TIPSWITCH:
+- md->touch = value;
+- break;
+- case HID_DG_CONFIDENCE:
+- md->valid = value;
+- break;
+- case HID_DG_WIDTH:
+- if (md->valid)
+- md->f[md->curid].w = value;
+- break;
+- case HID_DG_HEIGHT:
+- if (md->valid)
+- md->f[md->curid].h = value;
+- break;
+- case HID_DG_CONTACTID:
+- value = clamp_val(value, 0, MAX_SLOTS - 1);
+- if (md->valid) {
+- md->curid = value;
+- md->f[value].touch = md->touch;
+- md->f[value].valid = 1;
+- md->nreal++;
+- }
+- break;
+- case HID_GD_X:
+- if (md->valid)
+- md->f[md->curid].x = value;
+- break;
+- case HID_GD_Y:
+- if (md->valid)
+- md->f[md->curid].y = value;
+- break;
+- case HID_DG_CONTACTCOUNT:
+- if (value)
+- md->nexp = value;
+- if (md->nreal >= md->nexp) {
+- mmm_filter_event(md, input);
+- md->nreal = 0;
+- }
+- break;
+- }
+- }
+-
+- /* we have handled the hidinput part, now remains hiddev */
+- if (hid->claimed & HID_CLAIMED_HIDDEV && hid->hiddev_hid_event)
+- hid->hiddev_hid_event(hid, field, usage, value);
+-
+- return 1;
+-}
+-
+-static int mmm_probe(struct hid_device *hdev, const struct hid_device_id *id)
+-{
+- int ret;
+- struct mmm_data *md;
+-
+- hdev->quirks |= HID_QUIRK_NO_INPUT_SYNC;
+-
+- md = kzalloc(sizeof(struct mmm_data), GFP_KERNEL);
+- if (!md) {
+- hid_err(hdev, "cannot allocate 3M data\n");
+- return -ENOMEM;
+- }
+- hid_set_drvdata(hdev, md);
+-
+- ret = hid_parse(hdev);
+- if (!ret)
+- ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
+-
+- if (ret)
+- kfree(md);
+- return ret;
+-}
+-
+-static void mmm_remove(struct hid_device *hdev)
+-{
+- hid_hw_stop(hdev);
+- kfree(hid_get_drvdata(hdev));
+- hid_set_drvdata(hdev, NULL);
+-}
+-
+-static const struct hid_device_id mmm_devices[] = {
+- { HID_USB_DEVICE(USB_VENDOR_ID_3M, USB_DEVICE_ID_3M1968) },
+- { HID_USB_DEVICE(USB_VENDOR_ID_3M, USB_DEVICE_ID_3M2256) },
+- { }
+-};
+-MODULE_DEVICE_TABLE(hid, mmm_devices);
+-
+-static const struct hid_usage_id mmm_grabbed_usages[] = {
+- { HID_ANY_ID, HID_ANY_ID, HID_ANY_ID },
+- { HID_ANY_ID - 1, HID_ANY_ID - 1, HID_ANY_ID - 1}
+-};
+-
+-static struct hid_driver mmm_driver = {
+- .name = "3m-pct",
+- .id_table = mmm_devices,
+- .probe = mmm_probe,
+- .remove = mmm_remove,
+- .input_mapping = mmm_input_mapping,
+- .input_mapped = mmm_input_mapped,
+- .usage_table = mmm_grabbed_usages,
+- .event = mmm_event,
+-};
+-
+-static int __init mmm_init(void)
+-{
+- return hid_register_driver(&mmm_driver);
+-}
+-
+-static void __exit mmm_exit(void)
+-{
+- hid_unregister_driver(&mmm_driver);
+-}
+-
+-module_init(mmm_init);
+-module_exit(mmm_exit);
+-
+diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c
+index d31301e..0175f85 100644
+--- a/drivers/hid/hid-multitouch.c
++++ b/drivers/hid/hid-multitouch.c
+@@ -11,6 +11,12 @@
+ * Copyright (c) 2010 Henrik Rydberg <rydberg(a)euromail.se>
+ * Copyright (c) 2010 Canonical, Ltd.
+ *
++ * This code is partly based on hid-3m-pct.c:
++ *
++ * Copyright (c) 2009-2010 Stephane Chatty <chatty(a)enac.fr>
++ * Copyright (c) 2010 Henrik Rydberg <rydberg(a)euromail.se>
++ * Copyright (c) 2010 Canonical, Ltd.
++ *
+ */
+
+ /*
+@@ -69,6 +75,8 @@ struct mt_class {
+ __s32 name; /* MT_CLS */
+ __s32 quirks;
+ __s32 sn_move; /* Signal/noise ratio for move events */
++ __s32 sn_width; /* Signal/noise ratio for width events */
++ __s32 sn_height; /* Signal/noise ratio for height events */
+ __s32 sn_pressure; /* Signal/noise ratio for pressure events */
+ __u8 maxcontacts;
+ };
+@@ -80,6 +88,7 @@ struct mt_class {
+ #define MT_CLS_CYPRESS 4
+ #define MT_CLS_EGALAX 5
+ #define MT_CLS_STANTUM 6
++#define MT_CLS_3M 7
+
+ #define MT_DEFAULT_MAXCONTACT 10
+
+@@ -141,6 +150,12 @@ struct mt_class mt_classes[] = {
+ },
+ { .name = MT_CLS_STANTUM,
+ .quirks = MT_QUIRK_VALID_IS_CONFIDENCE },
++ { .name = MT_CLS_3M,
++ .quirks = MT_QUIRK_VALID_IS_CONFIDENCE |
++ MT_QUIRK_SLOT_IS_CONTACTID,
++ .sn_move = 2048,
++ .sn_width = 128,
++ .sn_height = 128 },
+
+ { }
+ };
+@@ -230,11 +245,15 @@ static int mt_input_mapping(struct hid_device *hdev, struct
hid_input *hi,
+ case HID_DG_WIDTH:
+ hid_map_usage(hi, usage, bit, max,
+ EV_ABS, ABS_MT_TOUCH_MAJOR);
++ set_abs(hi->input, ABS_MT_TOUCH_MAJOR, field,
++ cls->sn_width);
+ td->last_slot_field = usage->hid;
+ return 1;
+ case HID_DG_HEIGHT:
+ hid_map_usage(hi, usage, bit, max,
+ EV_ABS, ABS_MT_TOUCH_MINOR);
++ set_abs(hi->input, ABS_MT_TOUCH_MINOR, field,
++ cls->sn_height);
+ input_set_abs_params(hi->input,
+ ABS_MT_ORIENTATION, 0, 1, 0, 0);
+ td->last_slot_field = usage->hid;
+@@ -332,11 +351,18 @@ static void mt_emit_event(struct mt_device *td, struct input_dev
*input)
+ input_mt_report_slot_state(input, MT_TOOL_FINGER,
+ s->touch_state);
+ if (s->touch_state) {
++ /* this finger is on the screen */
++ int wide = (s->w > s->h);
++ /* divided by two to match visual scale of touch */
++ int major = max(s->w, s->h) >> 1;
++ int minor = min(s->w, s->h) >> 1;
++
+ input_event(input, EV_ABS, ABS_MT_POSITION_X, s->x);
+ input_event(input, EV_ABS, ABS_MT_POSITION_Y, s->y);
++ input_event(input, EV_ABS, ABS_MT_ORIENTATION, wide);
+ input_event(input, EV_ABS, ABS_MT_PRESSURE, s->p);
+- input_event(input, EV_ABS, ABS_MT_TOUCH_MAJOR, s->w);
+- input_event(input, EV_ABS, ABS_MT_TOUCH_MINOR, s->h);
++ input_event(input, EV_ABS, ABS_MT_TOUCH_MAJOR, major);
++ input_event(input, EV_ABS, ABS_MT_TOUCH_MINOR, minor);
+ }
+ s->seen_in_this_frame = false;
+
+@@ -398,6 +424,15 @@ static int mt_event(struct hid_device *hid, struct hid_field
*field,
+ break;
+
+ default:
++ if (td->last_field_index
++ && field->index == td->last_field_index)
++ /* we reach here when the last field in the
++ * report is not related to multitouch.
++ * This is not good. As a temporary solution,
++ * we trigger our mt event completion and
++ * ignore the field.
++ */
++ break;
+ /* fallback to the generic hidinput handling */
+ return 0;
+ }
+@@ -513,6 +548,14 @@ static void mt_remove(struct hid_device *hdev)
+
+ static const struct hid_device_id mt_devices[] = {
+
++ /* 3M panels */
++ { .driver_data = MT_CLS_3M,
++ HID_USB_DEVICE(USB_VENDOR_ID_3M,
++ USB_DEVICE_ID_3M1968) },
++ { .driver_data = MT_CLS_3M,
++ HID_USB_DEVICE(USB_VENDOR_ID_3M,
++ USB_DEVICE_ID_3M2256) },
++
+ /* Cando panels */
+ { .driver_data = MT_CLS_DUAL_INRANGE_CONTACTNUMBER,
+ HID_USB_DEVICE(USB_VENDOR_ID_CANDO,
+commit 2955caed8b9865c1f04fcde6bd7103d5d5ec9415
+Author: Benjamin Tissoires <benjamin.tissoires(a)enac.fr>
+Date: Thu Apr 21 14:15:59 2011 +0200
+
+ HID: hid-multitouch: refactor last_field_index
+
+ the current implementation requires the devices to report
+ HID_DG_CONTACTCOUNT to set the last_field_index value.
+ However, devices reporting in serial mode (DWAV and PenMount)
+ do not send this field.
+ Other devices (3M) add other fields in the reports descriptor
+ that are not multitouch related at the end, thus the need to
+ add a special case in the default case when handling events.
+
+ A first work around has been set up but with PenMount devices,
+ we have reached the limit.
+
+ The idea is to calculate the last_field_index by relying only on
+ multitouch fields the device send. This allows us to remove
+ the handling of non-multitouch events in hid-multitouch, and
+ guarantee that the function mt_emit_event is always called.
+
+ Signed-off-by: Benjamin Tissoires <benjamin.tissoires(a)enac.fr>
+ Reviewed-and-tested-by: Henrik Rydberg <rydberg(a)euromail.se>
+ Signed-off-by: Jiri Kosina <jkosina(a)suse.cz>
+
+diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c
+index 0175f85..6005e78 100644
+--- a/drivers/hid/hid-multitouch.c
++++ b/drivers/hid/hid-multitouch.c
+@@ -210,6 +210,7 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input
*hi,
+ /* touchscreen emulation */
+ set_abs(hi->input, ABS_X, field, cls->sn_move);
+ td->last_slot_field = usage->hid;
++ td->last_field_index = field->index;
+ return 1;
+ case HID_GD_Y:
+ if (quirks & MT_QUIRK_EGALAX_XYZ_FIXUP)
+@@ -221,6 +222,7 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input
*hi,
+ /* touchscreen emulation */
+ set_abs(hi->input, ABS_Y, field, cls->sn_move);
+ td->last_slot_field = usage->hid;
++ td->last_field_index = field->index;
+ return 1;
+ }
+ return 0;
+@@ -229,18 +231,22 @@ static int mt_input_mapping(struct hid_device *hdev, struct
hid_input *hi,
+ switch (usage->hid) {
+ case HID_DG_INRANGE:
+ td->last_slot_field = usage->hid;
++ td->last_field_index = field->index;
+ return 1;
+ case HID_DG_CONFIDENCE:
+ td->last_slot_field = usage->hid;
++ td->last_field_index = field->index;
+ return 1;
+ case HID_DG_TIPSWITCH:
+ hid_map_usage(hi, usage, bit, max, EV_KEY, BTN_TOUCH);
+ input_set_capability(hi->input, EV_KEY, BTN_TOUCH);
+ td->last_slot_field = usage->hid;
++ td->last_field_index = field->index;
+ return 1;
+ case HID_DG_CONTACTID:
+ input_mt_init_slots(hi->input, td->maxcontacts);
+ td->last_slot_field = usage->hid;
++ td->last_field_index = field->index;
+ return 1;
+ case HID_DG_WIDTH:
+ hid_map_usage(hi, usage, bit, max,
+@@ -248,6 +254,7 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input
*hi,
+ set_abs(hi->input, ABS_MT_TOUCH_MAJOR, field,
+ cls->sn_width);
+ td->last_slot_field = usage->hid;
++ td->last_field_index = field->index;
+ return 1;
+ case HID_DG_HEIGHT:
+ hid_map_usage(hi, usage, bit, max,
+@@ -257,6 +264,7 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input
*hi,
+ input_set_abs_params(hi->input,
+ ABS_MT_ORIENTATION, 0, 1, 0, 0);
+ td->last_slot_field = usage->hid;
++ td->last_field_index = field->index;
+ return 1;
+ case HID_DG_TIPPRESSURE:
+ if (quirks & MT_QUIRK_EGALAX_XYZ_FIXUP)
+@@ -269,13 +277,15 @@ static int mt_input_mapping(struct hid_device *hdev, struct
hid_input *hi,
+ set_abs(hi->input, ABS_PRESSURE, field,
+ cls->sn_pressure);
+ td->last_slot_field = usage->hid;
++ td->last_field_index = field->index;
+ return 1;
+ case HID_DG_CONTACTCOUNT:
+- td->last_field_index = field->report->maxfield - 1;
++ td->last_field_index = field->index;
+ return 1;
+ case HID_DG_CONTACTMAX:
+ /* we don't set td->last_slot_field as contactcount and
+ * contact max are global to the report */
++ td->last_field_index = field->index;
+ return -1;
+ }
+ /* let hid-input decide for the others */
+@@ -424,23 +434,12 @@ static int mt_event(struct hid_device *hid, struct hid_field
*field,
+ break;
+
+ default:
+- if (td->last_field_index
+- && field->index == td->last_field_index)
+- /* we reach here when the last field in the
+- * report is not related to multitouch.
+- * This is not good. As a temporary solution,
+- * we trigger our mt event completion and
+- * ignore the field.
+- */
+- break;
+ /* fallback to the generic hidinput handling */
+ return 0;
+ }
+
+ if (usage->hid == td->last_slot_field) {
+ mt_complete_slot(td);
+- if (!td->last_field_index)
+- mt_emit_event(td, field->hidinput->input);
+ }
+
+ if (field->index == td->last_field_index
+commit 6ab3a9a63fc16b04f7de48eb0190d516dd7574df
+Author: John Sung <penmount.touch(a)gmail.com>
+Date: Thu Apr 21 16:21:52 2011 +0200
+
+ HID: hid-multitouch: add support for PenMount dual-touch panel
+
+ This patch adds PenMount support to hid-multitouch. A new class
+ MT_CLS_CONFIDENCE is defined for PenMount, since it uses HID_DG_CONFIDENCE as
+ the valid flag.
+
+ Signed-off-by: John Sung <penmount.touch(a)gmail.com>
+ [benjamin.tissoires(a)enac.fr: rebased on top of last_index_field changes]
+ Signed-off-by: Benjamin Tissoires <benjamin.tissoires(a)enac.fr>
+ Acked-by: Henrik Rydberg <rydberg(a)euromail.se>
+ Signed-off-by: Jiri Kosina <jkosina(a)suse.cz>
+
+diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig
+index 996ae3a..8058cf1 100644
+--- a/drivers/hid/Kconfig
++++ b/drivers/hid/Kconfig
+@@ -313,6 +313,7 @@ config HID_MULTITOUCH
+ - Cypress TrueTouch panels
+ - Hanvon dual touch panels
+ - IrTouch Infrared USB panels
++ - PenMount dual touch panels
+ - Pixcir dual touch panels
+ - 'Sensing Win7-TwoFinger' panel by GeneralTouch
+ - eGalax dual-touch panels, including the
+diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
+index c3d6626..6e31b9f 100644
+--- a/drivers/hid/hid-core.c
++++ b/drivers/hid/hid-core.c
+@@ -1438,6 +1438,7 @@ static const struct hid_device_id hid_have_special_driver[] = {
+ { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_18) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_ORTEK, USB_DEVICE_ID_ORTEK_PKB1700) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_ORTEK, USB_DEVICE_ID_ORTEK_WKB2000) },
++ { HID_USB_DEVICE(USB_VENDOR_ID_PENMOUNT, USB_DEVICE_ID_PENMOUNT_PCI) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_PETALYNX, USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_QUANTA,
USB_DEVICE_ID_PIXART_IMAGING_INC_OPTICAL_TOUCH_SCREEN) },
+diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
+index d485894..252aeba 100644
+--- a/drivers/hid/hid-ids.h
++++ b/drivers/hid/hid-ids.h
+@@ -484,6 +484,9 @@
+ #define USB_VENDOR_ID_PANTHERLORD 0x0810
+ #define USB_DEVICE_ID_PANTHERLORD_TWIN_USB_JOYSTICK 0x0001
+
++#define USB_VENDOR_ID_PENMOUNT 0x14e1
++#define USB_DEVICE_ID_PENMOUNT_PCI 0x3500
++
+ #define USB_VENDOR_ID_PETALYNX 0x18b1
+ #define USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE 0x0037
+
+diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c
+index 6005e78..51b5d27 100644
+--- a/drivers/hid/hid-multitouch.c
++++ b/drivers/hid/hid-multitouch.c
+@@ -89,6 +89,7 @@ struct mt_class {
+ #define MT_CLS_EGALAX 5
+ #define MT_CLS_STANTUM 6
+ #define MT_CLS_3M 7
++#define MT_CLS_CONFIDENCE 8
+
+ #define MT_DEFAULT_MAXCONTACT 10
+
+@@ -156,6 +157,8 @@ struct mt_class mt_classes[] = {
+ .sn_move = 2048,
+ .sn_width = 128,
+ .sn_height = 128 },
++ { .name = MT_CLS_CONFIDENCE,
++ .quirks = MT_QUIRK_VALID_IS_CONFIDENCE },
+
+ { }
+ };
+@@ -584,6 +587,11 @@ static const struct hid_device_id mt_devices[] = {
+ HID_USB_DEVICE(USB_VENDOR_ID_IRTOUCHSYSTEMS,
+ USB_DEVICE_ID_IRTOUCH_INFRARED_USB) },
+
++ /* PenMount panels */
++ { .driver_data = MT_CLS_CONFIDENCE,
++ HID_USB_DEVICE(USB_VENDOR_ID_PENMOUNT,
++ USB_DEVICE_ID_PENMOUNT_PCI) },
++
+ /* PixCir-based panels */
+ { .driver_data = MT_CLS_DUAL_INRANGE_CONTACTID,
+ HID_USB_DEVICE(USB_VENDOR_ID_HANVON,
+commit 4a6ee685fbcba4a440cf86f41557752ba81e2ccf
+Author: Benjamin Tissoires <benjamin.tissoires(a)enac.fr>
+Date: Fri Apr 22 11:51:48 2011 +0200
+
+ HID: hid-multitouch: merge hid-mosart into hid-multitouch
+
+ This patch include MosArt devices into hid-multitouch.
+ MosArt devices now support mt-protocol B.
+
+ We also need to introduce a new quirk for mosart devices to support
+ their contactID.
+
+ Signed-off-by: Benjamin Tissoires <benjamin.tissoires(a)enac.fr>
+ Signed-off-by: Jiri Kosina <jkosina(a)suse.cz>
+
+diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig
+index 8058cf1..d2d4e5f 100644
+--- a/drivers/hid/Kconfig
++++ b/drivers/hid/Kconfig
+@@ -288,12 +288,6 @@ config HID_MICROSOFT
+ ---help---
+ Support for Microsoft devices that are not fully compliant with HID standard.
+
+-config HID_MOSART
+- tristate "MosArt dual-touch panels"
+- depends on USB_HID
+- ---help---
+- Support for MosArt dual-touch panels.
+-
+ config HID_MONTEREY
+ tristate "Monterey Genius KB29E keyboard" if EXPERT
+ depends on USB_HID
+@@ -313,6 +307,7 @@ config HID_MULTITOUCH
+ - Cypress TrueTouch panels
+ - Hanvon dual touch panels
+ - IrTouch Infrared USB panels
++ - MosArt dual-touch panels
+ - PenMount dual touch panels
- Pixcir dual touch panels
- 'Sensing Win7-TwoFinger' panel by GeneralTouch
+diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile
+index 11c9f0b..f8cc4ea 100644
+--- a/drivers/hid/Makefile
++++ b/drivers/hid/Makefile
+@@ -45,7 +45,6 @@ obj-$(CONFIG_HID_LOGITECH) += hid-logitech.o
+ obj-$(CONFIG_HID_MAGICMOUSE) += hid-magicmouse.o
+ obj-$(CONFIG_HID_MICROSOFT) += hid-microsoft.o
+ obj-$(CONFIG_HID_MONTEREY) += hid-monterey.o
+-obj-$(CONFIG_HID_MOSART) += hid-mosart.o
+ obj-$(CONFIG_HID_MULTITOUCH) += hid-multitouch.o
+ obj-$(CONFIG_HID_NTRIG) += hid-ntrig.o
+ obj-$(CONFIG_HID_ORTEK) += hid-ortek.o
+diff --git a/drivers/hid/hid-mosart.c b/drivers/hid/hid-mosart.c
+deleted file mode 100644
+index aed7ffe..0000000
+--- a/drivers/hid/hid-mosart.c
++++ /dev/null
+@@ -1,296 +0,0 @@
+-/*
+- * HID driver for the multitouch panel on the ASUS EeePC T91MT
+- *
+- * Copyright (c) 2009-2010 Stephane Chatty <chatty(a)enac.fr>
+- * Copyright (c) 2010 Teemu Tuominen <teemu.tuominen(a)cybercom.com>
+- *
+- */
+-
+-/*
+- * This program is free software; you can redistribute it and/or modify it
+- * under the terms of the GNU General Public License as published by the Free
+- * Software Foundation; either version 2 of the License, or (at your option)
+- * any later version.
+- */
+-
+-#include <linux/device.h>
+-#include <linux/hid.h>
+-#include <linux/module.h>
+-#include <linux/slab.h>
+-#include <linux/usb.h>
+-#include "usbhid/usbhid.h"
+-
+-MODULE_AUTHOR("Stephane Chatty <chatty(a)enac.fr>");
+-MODULE_DESCRIPTION("MosArt dual-touch panel");
+-MODULE_LICENSE("GPL");
+-
+-#include "hid-ids.h"
+-
+-struct mosart_data {
+- __u16 x, y;
+- __u8 id;
+- bool valid; /* valid finger data, or just placeholder? */
+- bool first; /* is this the first finger in this frame? */
+- bool activity_now; /* at least one active finger in this frame? */
+- bool activity; /* at least one active finger previously? */
+-};
+-
+-static int mosart_input_mapping(struct hid_device *hdev, struct hid_input *hi,
+- struct hid_field *field, struct hid_usage *usage,
+- unsigned long **bit, int *max)
+-{
+- switch (usage->hid & HID_USAGE_PAGE) {
+-
+- case HID_UP_GENDESK:
+- switch (usage->hid) {
+- case HID_GD_X:
+- hid_map_usage(hi, usage, bit, max,
+- EV_ABS, ABS_MT_POSITION_X);
+- /* touchscreen emulation */
+- input_set_abs_params(hi->input, ABS_X,
+- field->logical_minimum,
+- field->logical_maximum, 0, 0);
+- return 1;
+- case HID_GD_Y:
+- hid_map_usage(hi, usage, bit, max,
+- EV_ABS, ABS_MT_POSITION_Y);
+- /* touchscreen emulation */
+- input_set_abs_params(hi->input, ABS_Y,
+- field->logical_minimum,
+- field->logical_maximum, 0, 0);
+- return 1;
+- }
+- return 0;
+-
+- case HID_UP_DIGITIZER:
+- switch (usage->hid) {
+- case HID_DG_CONFIDENCE:
+- case HID_DG_TIPSWITCH:
+- case HID_DG_INPUTMODE:
+- case HID_DG_DEVICEINDEX:
+- case HID_DG_CONTACTCOUNT:
+- case HID_DG_CONTACTMAX:
+- case HID_DG_TIPPRESSURE:
+- case HID_DG_WIDTH:
+- case HID_DG_HEIGHT:
+- return -1;
+- case HID_DG_INRANGE:
+- /* touchscreen emulation */
+- hid_map_usage(hi, usage, bit, max, EV_KEY, BTN_TOUCH);
+- return 1;
+-
+- case HID_DG_CONTACTID:
+- hid_map_usage(hi, usage, bit, max,
+- EV_ABS, ABS_MT_TRACKING_ID);
+- return 1;
+-
+- }
+- return 0;
+-
+- case 0xff000000:
+- /* ignore HID features */
+- return -1;
+-
+- case HID_UP_BUTTON:
+- /* ignore buttons */
+- return -1;
+- }
+-
+- return 0;
+-}
+-
+-static int mosart_input_mapped(struct hid_device *hdev, struct hid_input *hi,
+- struct hid_field *field, struct hid_usage *usage,
+- unsigned long **bit, int *max)
+-{
+- if (usage->type == EV_KEY || usage->type == EV_ABS)
+- clear_bit(usage->code, *bit);
+-
+- return 0;
+-}
+-
+-/*
+- * this function is called when a whole finger has been parsed,
+- * so that it can decide what to send to the input layer.
+- */
+-static void mosart_filter_event(struct mosart_data *td, struct input_dev *input)
+-{
+- td->first = !td->first; /* touchscreen emulation */
+-
+- if (!td->valid) {
+- /*
+- * touchscreen emulation: if no finger in this frame is valid
+- * and there previously was finger activity, this is a release
+- */
+- if (!td->first && !td->activity_now && td->activity) {
+- input_event(input, EV_KEY, BTN_TOUCH, 0);
+- td->activity = false;
+- }
+- return;
+- }
+-
+- input_event(input, EV_ABS, ABS_MT_TRACKING_ID, td->id);
+- input_event(input, EV_ABS, ABS_MT_POSITION_X, td->x);
+- input_event(input, EV_ABS, ABS_MT_POSITION_Y, td->y);
+-
+- input_mt_sync(input);
+- td->valid = false;
+-
+- /* touchscreen emulation: if first active finger in this frame... */
+- if (!td->activity_now) {
+- /* if there was no previous activity, emit touch event */
+- if (!td->activity) {
+- input_event(input, EV_KEY, BTN_TOUCH, 1);
+- td->activity = true;
+- }
+- td->activity_now = true;
+- /* and in any case this is our preferred finger */
+- input_event(input, EV_ABS, ABS_X, td->x);
+- input_event(input, EV_ABS, ABS_Y, td->y);
+- }
+-}
+-
+-
+-static int mosart_event(struct hid_device *hid, struct hid_field *field,
+- struct hid_usage *usage, __s32 value)
+-{
+- struct mosart_data *td = hid_get_drvdata(hid);
+-
+- if (hid->claimed & HID_CLAIMED_INPUT) {
+- struct input_dev *input = field->hidinput->input;
+- switch (usage->hid) {
+- case HID_DG_INRANGE:
+- td->valid = !!value;
+- break;
+- case HID_GD_X:
+- td->x = value;
+- break;
+- case HID_GD_Y:
+- td->y = value;
+- mosart_filter_event(td, input);
+- break;
+- case HID_DG_CONTACTID:
+- td->id = value;
+- break;
+- case HID_DG_CONTACTCOUNT:
+- /* touch emulation: this is the last field in a frame */
+- td->first = false;
+- td->activity_now = false;
+- break;
+- case HID_DG_CONFIDENCE:
+- case HID_DG_TIPSWITCH:
+- /* avoid interference from generic hidinput handling */
+- break;
+-
+- default:
+- /* fallback to the generic hidinput handling */
+- return 0;
+- }
+- }
+-
+- /* we have handled the hidinput part, now remains hiddev */
+- if (hid->claimed & HID_CLAIMED_HIDDEV && hid->hiddev_hid_event)
+- hid->hiddev_hid_event(hid, field, usage, value);
+-
+- return 1;
+-}
+-
+-static int mosart_probe(struct hid_device *hdev, const struct hid_device_id *id)
+-{
+- int ret;
+- struct mosart_data *td;
+-
+-
+- td = kmalloc(sizeof(struct mosart_data), GFP_KERNEL);
+- if (!td) {
+- hid_err(hdev, "cannot allocate MosArt data\n");
+- return -ENOMEM;
+- }
+- td->valid = false;
+- td->activity = false;
+- td->activity_now = false;
+- td->first = false;
+- hid_set_drvdata(hdev, td);
+-
+- /* currently, it's better to have one evdev device only */
+-#if 0
+- hdev->quirks |= HID_QUIRK_MULTI_INPUT;
+-#endif
+-
+- ret = hid_parse(hdev);
+- if (ret == 0)
+- ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
+-
+- if (ret == 0) {
+- struct hid_report_enum *re = hdev->report_enum
+- + HID_FEATURE_REPORT;
+- struct hid_report *r = re->report_id_hash[7];
+-
+- r->field[0]->value[0] = 0x02;
+- usbhid_submit_report(hdev, r, USB_DIR_OUT);
+- } else
+- kfree(td);
+-
+- return ret;
+-}
+-
+-#ifdef CONFIG_PM
+-static int mosart_reset_resume(struct hid_device *hdev)
+-{
+- struct hid_report_enum *re = hdev->report_enum
+- + HID_FEATURE_REPORT;
+- struct hid_report *r = re->report_id_hash[7];
+-
+- r->field[0]->value[0] = 0x02;
+- usbhid_submit_report(hdev, r, USB_DIR_OUT);
+- return 0;
+-}
+-#endif
+-
+-static void mosart_remove(struct hid_device *hdev)
+-{
+- hid_hw_stop(hdev);
+- kfree(hid_get_drvdata(hdev));
+- hid_set_drvdata(hdev, NULL);
+-}
+-
+-static const struct hid_device_id mosart_devices[] = {
+- { HID_USB_DEVICE(USB_VENDOR_ID_ASUS, USB_DEVICE_ID_ASUS_T91MT) },
+- { HID_USB_DEVICE(USB_VENDOR_ID_ASUS, USB_DEVICE_ID_ASUSTEK_MULTITOUCH_YFO) },
+- { HID_USB_DEVICE(USB_VENDOR_ID_TURBOX, USB_DEVICE_ID_TURBOX_TOUCHSCREEN_MOSART) },
+- { }
+-};
+-MODULE_DEVICE_TABLE(hid, mosart_devices);
+-
+-static const struct hid_usage_id mosart_grabbed_usages[] = {
+- { HID_ANY_ID, HID_ANY_ID, HID_ANY_ID },
+- { HID_ANY_ID - 1, HID_ANY_ID - 1, HID_ANY_ID - 1}
+-};
+-
+-static struct hid_driver mosart_driver = {
+- .name = "mosart",
+- .id_table = mosart_devices,
+- .probe = mosart_probe,
+- .remove = mosart_remove,
+- .input_mapping = mosart_input_mapping,
+- .input_mapped = mosart_input_mapped,
+- .usage_table = mosart_grabbed_usages,
+- .event = mosart_event,
+-#ifdef CONFIG_PM
+- .reset_resume = mosart_reset_resume,
+-#endif
+-};
+-
+-static int __init mosart_init(void)
+-{
+- return hid_register_driver(&mosart_driver);
+-}
+-
+-static void __exit mosart_exit(void)
+-{
+- hid_unregister_driver(&mosart_driver);
+-}
+-
+-module_init(mosart_init);
+-module_exit(mosart_exit);
+-
+diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c
+index 51b5d27..bf46804 100644
+--- a/drivers/hid/hid-multitouch.c
++++ b/drivers/hid/hid-multitouch.c
+@@ -50,6 +50,7 @@ MODULE_LICENSE("GPL");
+ #define MT_QUIRK_VALID_IS_INRANGE (1 << 4)
+ #define MT_QUIRK_VALID_IS_CONFIDENCE (1 << 5)
+ #define MT_QUIRK_EGALAX_XYZ_FIXUP (1 << 6)
++#define MT_QUIRK_SLOT_IS_CONTACTID_MINUS_ONE (1 << 7)
+
+ struct mt_slot {
+ __s32 x, y, p, w, h;
+@@ -90,6 +91,7 @@ struct mt_class {
+ #define MT_CLS_STANTUM 6
+ #define MT_CLS_3M 7
+ #define MT_CLS_CONFIDENCE 8
++#define MT_CLS_CONFIDENCE_MINUS_ONE 9
+
+ #define MT_DEFAULT_MAXCONTACT 10
+
+@@ -140,7 +142,9 @@ struct mt_class mt_classes[] = {
+ .quirks = MT_QUIRK_NOT_SEEN_MEANS_UP |
+ MT_QUIRK_CYPRESS,
+ .maxcontacts = 10 },
+-
++ { .name = MT_CLS_CONFIDENCE_MINUS_ONE,
++ .quirks = MT_QUIRK_VALID_IS_CONFIDENCE |
++ MT_QUIRK_SLOT_IS_CONTACTID_MINUS_ONE },
+ { .name = MT_CLS_EGALAX,
+ .quirks = MT_QUIRK_SLOT_IS_CONTACTID |
+ MT_QUIRK_VALID_IS_INRANGE |
+@@ -325,6 +329,9 @@ static int mt_compute_slot(struct mt_device *td)
+ if (quirks & MT_QUIRK_SLOT_IS_CONTACTNUMBER)
+ return td->num_received;
+
++ if (quirks & MT_QUIRK_SLOT_IS_CONTACTID_MINUS_ONE)
++ return td->curdata.contactid - 1;
++
+ return find_slot_from_contactid(td);
+ }
+
+@@ -587,6 +594,17 @@ static const struct hid_device_id mt_devices[] = {
+ HID_USB_DEVICE(USB_VENDOR_ID_IRTOUCHSYSTEMS,
+ USB_DEVICE_ID_IRTOUCH_INFRARED_USB) },
+
++ /* MosArt panels */
++ { .driver_data = MT_CLS_CONFIDENCE_MINUS_ONE,
++ HID_USB_DEVICE(USB_VENDOR_ID_ASUS,
++ USB_DEVICE_ID_ASUS_T91MT)},
++ { .driver_data = MT_CLS_CONFIDENCE_MINUS_ONE,
++ HID_USB_DEVICE(USB_VENDOR_ID_ASUS,
++ USB_DEVICE_ID_ASUSTEK_MULTITOUCH_YFO) },
++ { .driver_data = MT_CLS_CONFIDENCE_MINUS_ONE,
++ HID_USB_DEVICE(USB_VENDOR_ID_TURBOX,
++ USB_DEVICE_ID_TURBOX_TOUCHSCREEN_MOSART) },
++
+ /* PenMount panels */
+ { .driver_data = MT_CLS_CONFIDENCE,
+ HID_USB_DEVICE(USB_VENDOR_ID_PENMOUNT,
+commit 4e61f0d75aa86c9e59451f6bcffcdceb355b4fc4
+Author: Austin Zhang <zhang.austin(a)gmail.com>
+Date: Mon May 9 23:54:14 2011 +0800
+
+ HID: hid-multitouch: add support for Ilitek dual-touch panel
+
+ Added ILITEK hid dual touch panel support into hid-multitouch.
+
+ Signed-off-by: Austin Zhang <zhang.austin(a)gmail.com>
+ Reviewed-by: Benjamin Tissoires <benjamin.tissoires(a)enac.fr>
+ Signed-off-by: Jiri Kosina <jkosina(a)suse.cz>
+
+diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig
+index d2d4e5f..d9635d6 100644
+--- a/drivers/hid/Kconfig
++++ b/drivers/hid/Kconfig
+@@ -306,6 +306,7 @@ config HID_MULTITOUCH
+ - Cando dual touch panel
+ - Cypress TrueTouch panels
+ - Hanvon dual touch panels
++ - Ilitek dual touch panel
+ - IrTouch Infrared USB panels
+ - MosArt dual-touch panels
+ - PenMount dual touch panels
+diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
+index 6e31b9f..c0ea857 100644
+--- a/drivers/hid/hid-core.c
++++ b/drivers/hid/hid-core.c
+@@ -1377,6 +1377,7 @@ static const struct hid_device_id hid_have_special_driver[] = {
+ { HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE_2) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE_3) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_HANVON, USB_DEVICE_ID_HANVON_MULTITOUCH) },
++ { HID_USB_DEVICE(USB_VENDOR_ID_ILITEK, USB_DEVICE_ID_ILITEK_MULTITOUCH) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_IRTOUCHSYSTEMS, USB_DEVICE_ID_IRTOUCH_INFRARED_USB) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_KENSINGTON, USB_DEVICE_ID_KS_SLIMBLADE) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_KEYTOUCH, USB_DEVICE_ID_KEYTOUCH_IEC) },
+diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
+index 252aeba..0f29b3f 100644
+--- a/drivers/hid/hid-ids.h
++++ b/drivers/hid/hid-ids.h
+@@ -330,6 +330,9 @@
+ #define USB_DEVICE_ID_UGCI_FLYING 0x0020
+ #define USB_DEVICE_ID_UGCI_FIGHTING 0x0030
+
++#define USB_VENDOR_ID_ILITEK 0x222a
++#define USB_DEVICE_ID_ILITEK_MULTITOUCH 0x0001
++
+ #define USB_VENDOR_ID_IMATION 0x0718
+ #define USB_DEVICE_ID_DISC_STAKKA 0xd000
+
+diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c
+index bf46804..b21251b 100644
+--- a/drivers/hid/hid-multitouch.c
++++ b/drivers/hid/hid-multitouch.c
+@@ -589,6 +589,11 @@ static const struct hid_device_id mt_devices[] = {
+ HID_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH,
+ USB_DEVICE_ID_GENERAL_TOUCH_WIN7_TWOFINGERS) },
+
++ /* Ilitek dual touch panel */
++ { .driver_data = MT_CLS_DEFAULT,
++ HID_USB_DEVICE(USB_VENDOR_ID_ILITEK,
++ USB_DEVICE_ID_ILITEK_MULTITOUCH) },
++
+ /* IRTOUCH panels */
+ { .driver_data = MT_CLS_DUAL_INRANGE_CONTACTID,
+ HID_USB_DEVICE(USB_VENDOR_ID_IRTOUCHSYSTEMS,
+commit df167c4a0d68a9dbde044a39a77f255ac666f93e
+Author: Benjamin Tissoires <benjamin.tissoires(a)enac.fr>
+Date: Wed May 18 15:27:24 2011 +0200
+
+ HID: hid-multitouch: Add support for Lumio panels
+
+ This patch enables support for Lumio optical devices.
+
+ Signed-off-by: Benjamin Tissoires <benjamin.tissoires(a)enac.fr>
+ Signed-off-by: Jiri Kosina <jkosina(a)suse.cz>
+
+diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig
+index d9635d6..5a54b13 100644
+--- a/drivers/hid/Kconfig
++++ b/drivers/hid/Kconfig
+@@ -308,6 +308,7 @@ config HID_MULTITOUCH
+ - Hanvon dual touch panels
+ - Ilitek dual touch panel
+ - IrTouch Infrared USB panels
++ - Lumio CrystalTouch panels
+ - MosArt dual-touch panels
+ - PenMount dual touch panels
+ - Pixcir dual touch panels
+diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
+index c0ea857..3dad069 100644
+--- a/drivers/hid/hid-core.c
++++ b/drivers/hid/hid-core.c
+@@ -1410,6 +1410,7 @@ static const struct hid_device_id hid_have_special_driver[] = {
+ { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD2) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_SPACETRAVELLER) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_SPACENAVIGATOR) },
++ { HID_USB_DEVICE(USB_VENDOR_ID_LUMIO, USB_DEVICE_ID_CRYSTALTOUCH) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_MICROCHIP, USB_DEVICE_ID_PICOLCD) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_MICROCHIP, USB_DEVICE_ID_PICOLCD_BOOTLOADER) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_SIDEWINDER_GV) },
+diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
+index 0f29b3f..bfbc0d2 100644
+--- a/drivers/hid/hid-ids.h
++++ b/drivers/hid/hid-ids.h
+@@ -410,6 +410,9 @@
+ #define USB_DEVICE_ID_DINOVO_MINI 0xc71f
+ #define USB_DEVICE_ID_LOGITECH_MOMO_WHEEL2 0xca03
+
++#define USB_VENDOR_ID_LUMIO 0x202e
++#define USB_DEVICE_ID_CRYSTALTOUCH 0x0006
++
+ #define USB_VENDOR_ID_MCC 0x09db
+ #define USB_DEVICE_ID_MCC_PMD1024LS 0x0076
+ #define USB_DEVICE_ID_MCC_PMD1208LS 0x007a
+diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c
+index b21251b..ef33e2d 100644
+--- a/drivers/hid/hid-multitouch.c
++++ b/drivers/hid/hid-multitouch.c
+@@ -599,6 +599,11 @@ static const struct hid_device_id mt_devices[] = {
+ HID_USB_DEVICE(USB_VENDOR_ID_IRTOUCHSYSTEMS,
+ USB_DEVICE_ID_IRTOUCH_INFRARED_USB) },
+
++ /* Lumio panels */
++ { .driver_data = MT_CLS_CONFIDENCE_MINUS_ONE,
++ HID_USB_DEVICE(USB_VENDOR_ID_LUMIO,
++ USB_DEVICE_ID_CRYSTALTOUCH) },
++
+ /* MosArt panels */
+ { .driver_data = MT_CLS_CONFIDENCE_MINUS_ONE,
+ HID_USB_DEVICE(USB_VENDOR_ID_ASUS,
+commit c04abeeff9d76a703cac1e6d312853b0fc8136f5
+Author: Benjamin Tissoires <benjamin.tissoires(a)enac.fr>
+Date: Thu May 19 11:37:29 2011 +0200
+
+ HID: hid-multitouch: add support for Elo TouchSystems 2515 IntelliTouch Plus
+
+ This patch adds support for Elo TouchSystems 2515 IntelliTouch Plus
+ that can be found in Lenovo A700 all-in-one.
+
+ Signed-off-by: Benjamin Tissoires <benjamin.tissoires(a)enac.fr>
+ Tested-by: Bastien Nocera <hadess(a)hadess.net>
+ Signed-off-by: Jiri Kosina <jkosina(a)suse.cz>
+
+diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig
+index 5a54b13..1572ff1 100644
+--- a/drivers/hid/Kconfig
++++ b/drivers/hid/Kconfig
+@@ -305,6 +305,7 @@ config HID_MULTITOUCH
+ - 3M PCT touch screens
+ - Cando dual touch panel
+ - Cypress TrueTouch panels
++ - Elo TouchSystems IntelliTouch Plus panels
+ - Hanvon dual touch panels
+ - Ilitek dual touch panel
+ - IrTouch Infrared USB panels
+diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
+index 3dad069..053fc08 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
-@@ -1335,6 +1335,7 @@ static const struct hid_device_id hid_have_special_driver[] = {
+@@ -1366,6 +1366,7 @@ static const struct hid_device_id hid_have_special_driver[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH3) },
{ HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH4) },
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_BM084) },
@@ -32,9 +2207,11 @@ Signed-off-by: Jiri Kosina <jkosina(a)suse.cz>
{ HID_USB_DEVICE(USB_VENDOR_ID_EMS, USB_DEVICE_ID_EMS_TRIO_LINKER_PLUS_II) },
{ HID_USB_DEVICE(USB_VENDOR_ID_EZKEY, USB_DEVICE_ID_BTC_8193) },
{ HID_USB_DEVICE(USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PSX_ADAPTOR) },
+diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
+index bfbc0d2..6c19d1a 100644
--- a/drivers/hid/hid-ids.h
+++ b/drivers/hid/hid-ids.h
-@@ -219,6 +219,7 @@
+@@ -216,6 +216,7 @@
#define USB_VENDOR_ID_DREAM_CHEEKY 0x1d34
#define USB_VENDOR_ID_ELO 0x04E7
@@ -42,29 +2219,30 @@ Signed-off-by: Jiri Kosina <jkosina(a)suse.cz>
#define USB_DEVICE_ID_ELO_TS2700 0x0020
#define USB_VENDOR_ID_EMS 0x2006
+diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c
+index ef33e2d..3bc8de6 100644
--- a/drivers/hid/hid-multitouch.c
+++ b/drivers/hid/hid-multitouch.c
-@@ -69,6 +69,7 @@ struct mt_class {
- #define MT_CLS_DUAL1 2
- #define MT_CLS_DUAL2 3
- #define MT_CLS_CYPRESS 4
-+#define MT_CLS_DUAL_NSMU_CONTACTID 5
+@@ -92,6 +92,7 @@ struct mt_class {
+ #define MT_CLS_3M 7
+ #define MT_CLS_CONFIDENCE 8
+ #define MT_CLS_CONFIDENCE_MINUS_ONE 9
++#define MT_CLS_DUAL_NSMU_CONTACTID 10
- /*
- * these device-dependent functions determine what slot corresponds
-@@ -119,6 +120,11 @@ struct mt_class mt_classes[] = {
- MT_QUIRK_CYPRESS,
- .maxcontacts = 10 },
+ #define MT_DEFAULT_MAXCONTACT 10
+@@ -163,6 +164,10 @@ struct mt_class mt_classes[] = {
+ .sn_height = 128 },
+ { .name = MT_CLS_CONFIDENCE,
+ .quirks = MT_QUIRK_VALID_IS_CONFIDENCE },
+ { .name = MT_CLS_DUAL_NSMU_CONTACTID,
+ .quirks = MT_QUIRK_NOT_SEEN_MEANS_UP |
+ MT_QUIRK_SLOT_IS_CONTACTID,
+ .maxcontacts = 2 },
-+
+
{ }
};
-
-@@ -465,6 +471,11 @@ static const struct hid_device_id mt_devices[] = {
+@@ -584,6 +589,11 @@ static const struct hid_device_id mt_devices[] = {
HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS,
USB_DEVICE_ID_CYPRESS_TRUETOUCH) },
@@ -74,5 +2252,5 @@ Signed-off-by: Jiri Kosina <jkosina(a)suse.cz>
+ USB_DEVICE_ID_ELO_TS2515) },
+
/* GeneralTouch panel */
- { .driver_data = MT_CLS_DUAL2,
+ { .driver_data = MT_CLS_DUAL_INRANGE_CONTACTNUMBER,
HID_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH,
diff --git a/kernel.spec b/kernel.spec
index 5211df6..397f648 100644
--- a/kernel.spec
+++ b/kernel.spec
@@ -51,19 +51,19 @@ Summary: The Linux kernel
# For non-released -rc kernels, this will be prepended with "0.", so
# for example a 3 here will become 0.3
#
-%global baserelease 34
+%global baserelease 1
%global fedora_build %{baserelease}
# base_sublevel is the kernel version we're starting with and patching
# on top of -- for example, 2.6.22-rc7-git1 starts with a 2.6.21 base,
# which yields a base_sublevel of 21.
-%define base_sublevel 38
+%define base_sublevel 39
## If this is a released kernel ##
%if 0%{?released_kernel}
# Do we have a -stable update to apply?
-%define stable_update 8
+%define stable_update 2
# Is it a -stable RC?
%define stable_rc 0
# Set rpm version accordingly
@@ -596,8 +596,6 @@ Patch00: patch-2.6.%{base_sublevel}-git%{gitrev}.bz2
### BRANCH PATCH ###
%endif
-Patch02: git-linus.diff
-
# we also need compile fixes for -vanilla
Patch04: linux-2.6-compile-fixes.patch
@@ -609,10 +607,7 @@ Patch05: linux-2.6-makefile-after_link.patch
# revert upstream patches we get via other methods
Patch09: linux-2.6-upstream-reverts.patch
-# Git trees.
-# Standalone patches
-Patch20: linux-2.6-hotfixes.patch
Patch29: linux-2.6-utrace-revert-make-ptrace-functions-static.patch
Patch30: linux-2.6-tracehook.patch
@@ -627,17 +622,14 @@ Patch150: linux-2.6.29-sparc-IOC_TYPECHECK.patch
Patch160: linux-2.6-32bit-mmap-exec-randomization.patch
Patch161: linux-2.6-i386-nx-emulation.patch
-Patch200: linux-2.6-debug-sizeof-structs.patch
Patch202: linux-2.6-debug-taint-vm.patch
Patch203: linux-2.6-debug-vm-would-have-oomkilled.patch
-Patch204: linux-2.6-debug-always-inline-kzalloc.patch
Patch380: linux-2.6-defaults-pci_no_msi.patch
Patch381: linux-2.6-defaults-pci_use_crs.patch
# ASPM: enable powersave by default
Patch383: linux-2.6-defaults-aspm.patch
-Patch384: pci-pcie-links-may-not-get-configured-for-aspm-under-powersave-mode.patch
Patch385: pci-enable-aspm-state-clearing-regardless-of-policy.patch
Patch389: ima-allow-it-to-be-completely-disabled-and-default-off.patch
@@ -650,8 +642,6 @@ Patch394: linux-2.6-acpi-debug-infinite-loop.patch
Patch450: linux-2.6-input-kill-stupid-messages.patch
Patch452: linux-2.6.30-no-pcspkr-modalias.patch
Patch453: revert-hid-magicmouse-ignore-ivalid-report-id-while-switching.patch
-Patch454: input-wacom-add-support-for-lenovo-tablet-id-0xe6.patch
-Patch455: hid-ntrig-deref-unclaimed-input.patch
Patch456: hid-multitouch-add-support-for-elo-touchsystems.patch
Patch460: linux-2.6-serial-460800.patch
@@ -664,13 +654,9 @@ Patch570: linux-2.6-selinux-mprotect-checks.patch
Patch580: linux-2.6-sparc-selinux-mprotect-checks.patch
# scsi / block
-Patch600: block-queue-refcount.patch
-Patch601: block-export-blk_-get-put-_queue.patch
-Patch602: block-blkdev_get-should-access-bd_disk-only-after.patch
Patch603: cfq-iosched-fix-locking-around-ioc-ioc-data-assignment.patch
# libata
-Patch620: ahci-add-another-pci-id-for-marvell.patch
Patch621: libata-sas-only-set-frozen-flag-if-new-eh-is-supported.patch
Patch650: hda_intel-prealloc-4mb-dmabuffer.patch
@@ -689,35 +675,18 @@ Patch1555: fix_xen_guest_on_old_EC2.patch
# nouveau + drm fixes
Patch1809: drm-nouveau-fixes.patch
Patch1810: drm-nouveau-updates.patch
-Patch1811: drm-ttm-move-notify.patch
Patch1819: drm-intel-big-hammer.patch
# intel drm is all merged upstream
-# fix for 945G corruption will hit stable eventually
-Patch1821: drm-i915-fix-pipelined-fencing.patch
Patch1824: drm-intel-next.patch
# make sure the lvds comes back on lid open
Patch1825: drm-intel-make-lvds-work.patch
Patch1826: drm-intel-edp-fixes.patch
-Patch1828: drm-intel-eeebox-eb1007-quirk.patch
-Patch1829: drm-intel-restore-mode.patch
Patch1830: drm-i915-snb-irq-stalls-fix.patch
Patch1831: drm-i915-apply-hwstam-workaround-for-bsd-ring-on-sandybridge.patch
# radeon - new hw + fixes for fusion and t500 regression
Patch1839: drm-radeon-fix-regression-on-atom-cards-with-hardcoded-EDID-record.patch
-Patch1840: drm-radeon-update.patch
-Patch1841: drm-radeon-update2.patch
-Patch1842: drm-radeon-pageflip-oops-fix.patch
-Patch1843: drm-radeon-update3.patch
Patch1900: linux-2.6-intel-iommu-igfx.patch
-Patch1901: intel-iommu-flush-unmaps-at-domain_exit.patch
-Patch1902: intel-iommu-only-unlink-device-domains-from-iommu.patch
-Patch1903: intel-iommu-check-for-identity-mapping-candidate-using.patch
-Patch1904: intel-iommu-speed-up-processing-of-the-identity_mapping.patch
-Patch1905: intel-iommu-dont-cache-iova-above-32bit.patch
-Patch1906: intel-iommu-use-coherent-dma-mask-when-requested.patch
-Patch1907: intel-iommu-remove-host-bridge-devices-from-identity.patch
-Patch1908: intel-iommu-add-domain-check-in-domain_remove_one_dev_info.patch
# linux1394 git patches
Patch2200: linux-2.6-firewire-git-update.patch
@@ -728,7 +697,6 @@ Patch2201: linux-2.6-firewire-git-pending.patch
Patch2802: linux-2.6-silence-acpi-blacklist.patch
# media patches
-Patch2898: cx88-Fix-HVR4000-IR-keymap.patch
Patch2899: linux-2.6-v4l-dvb-fixes.patch
Patch2900: linux-2.6-v4l-dvb-update.patch
Patch2901: linux-2.6-v4l-dvb-experimental.patch
@@ -745,38 +713,21 @@ Patch12016: disable-i8042-check-on-apple-mac.patch
Patch12018: neuter_intel_microcode_load.patch
-Patch12101: apple_backlight.patch
-Patch12102: efifb_update.patch
-Patch12200: acpi_reboot.patch
-
# Runtime power management
Patch12203: linux-2.6-usb-pci-autosuspend.patch
Patch12204: linux-2.6-enable-more-pci-autosuspend.patch
Patch12303: dmar-disable-when-ricoh-multifunction.patch
-Patch12305: printk-do-not-mangle-valid-userspace-syslog-prefixes.patch
Patch12306: scsi-sd-downgrade-caching-printk-from-error-to-notice.patch
-#netconsole fixes
-Patch12400: linux-2.6-netconsole-deadlock.patch
-
-# CVE-2011-1581
-Patch12402: bonding-incorrect-tx-queue-offset.patch
-
-# Restore reliable stack backtraces, and hopefully fix RHBZ #700718
-Patch12403: x86-dumpstack-correct-stack-dump-info-when-frame-pointer-is-available.patch
-
# Fix breakage of PCI network adapter names on older Dell systems
Patch12404: x86-pci-preserve-existing-pci-bfsort-whitelist-for-dell-systems.patch
-Patch12407: scsi_dh_hp_sw-fix-deadlock-in-start_stop_endio.patch
-
Patch12416: bluetooth-device-ids-for-ath3k-on-pegatron-lucid-tablets.patch
Patch12418: ath5k-disable-fast-channel-switching-by-default.patch
-Patch12419: iwlagn-use-cts-to-self-protection-on-5000-adapters-series.patch
Patch12420: crypto-aesni_intel-merge-with-fpu_ko.patch
@@ -1203,8 +1154,6 @@ do
done
%endif
-ApplyOptionalPatch git-linus.diff
-
ApplyPatch linux-2.6-makefile-after_link.patch
#
@@ -1217,9 +1166,7 @@ ApplyOptionalPatch linux-2.6-compile-fixes.patch
# revert patches from upstream that conflict or that we get via other means
ApplyOptionalPatch linux-2.6-upstream-reverts.patch -R
-ApplyPatch linux-2.6-hotfixes.patch
-
-# Roland's utrace ptrace replacement.
+# utrace
ApplyPatch linux-2.6-utrace-revert-make-ptrace-functions-static.patch
ApplyPatch linux-2.6-tracehook.patch
ApplyPatch linux-2.6-utrace.patch
@@ -1231,22 +1178,6 @@ ApplyPatch
ksm-fix-null-pointer-dereference-in-scan-get-next-rmap-item.patch
# Architecture patches
# x86(-64)
-# Restore reliable stack backtraces, and hopefully
-# fix RHBZ #700718
-ApplyPatch x86-dumpstack-correct-stack-dump-info-when-frame-pointer-is-available.patch
-
-#
-# Intel IOMMU
-#
-# from 2.6.39.2
-ApplyPatch intel-iommu-flush-unmaps-at-domain_exit.patch
-ApplyPatch intel-iommu-only-unlink-device-domains-from-iommu.patch
-ApplyPatch intel-iommu-check-for-identity-mapping-candidate-using.patch
-ApplyPatch intel-iommu-speed-up-processing-of-the-identity_mapping.patch
-ApplyPatch intel-iommu-dont-cache-iova-above-32bit.patch
-ApplyPatch intel-iommu-use-coherent-dma-mask-when-requested.patch
-ApplyPatch intel-iommu-remove-host-bridge-devices-from-identity.patch
-ApplyPatch intel-iommu-add-domain-check-in-domain_remove_one_dev_info.patch
#
# PowerPC
@@ -1289,10 +1220,8 @@ ApplyPatch acpi-ec-add-delay-before-write.patch
ApplyPatch linux-2.6-acpi-debug-infinite-loop.patch
# Various low-impact patches to aid debugging.
-ApplyPatch linux-2.6-debug-sizeof-structs.patch
ApplyPatch linux-2.6-debug-taint-vm.patch
ApplyPatch linux-2.6-debug-vm-would-have-oomkilled.patch
-ApplyPatch linux-2.6-debug-always-inline-kzalloc.patch
#
# PCI
@@ -1302,8 +1231,6 @@ ApplyPatch linux-2.6-defaults-pci_no_msi.patch
ApplyPatch linux-2.6-defaults-pci_use_crs.patch
# enable ASPM by default on hardware we expect to work
ApplyPatch linux-2.6-defaults-aspm.patch
-# fixes for ASPM powersave mode
-ApplyPatch pci-pcie-links-may-not-get-configured-for-aspm-under-powersave-mode.patch
ApplyPatch pci-enable-aspm-state-clearing-regardless-of-policy.patch
# Fix breakage of PCI network adapter names on older Dell systems
ApplyPatch x86-pci-preserve-existing-pci-bfsort-whitelist-for-dell-systems.patch
@@ -1313,14 +1240,10 @@ ApplyPatch
x86-pci-preserve-existing-pci-bfsort-whitelist-for-dell-systems.patch
#
# SCSI / block Bits.
#
-ApplyPatch block-queue-refcount.patch
-ApplyPatch block-export-blk_-get-put-_queue.patch
-ApplyPatch block-blkdev_get-should-access-bd_disk-only-after.patch
# rhbz#577968
ApplyPatch cfq-iosched-fix-locking-around-ioc-ioc-data-assignment.patch
# libata
-ApplyPatch ahci-add-another-pci-id-for-marvell.patch
# Fix drive detection failure on mvsas (rhbz#705019)
ApplyPatch libata-sas-only-set-frozen-flag-if-new-eh-is-supported.patch
@@ -1336,8 +1259,6 @@ ApplyPatch hda_intel-prealloc-4mb-dmabuffer.patch
ApplyPatch linux-2.6-input-kill-stupid-messages.patch
ApplyPatch linux-2.6.30-no-pcspkr-modalias.patch
ApplyPatch revert-hid-magicmouse-ignore-ivalid-report-id-while-switching.patch
-ApplyPatch input-wacom-add-support-for-lenovo-tablet-id-0xe6.patch
-ApplyPatch hid-ntrig-deref-unclaimed-input.patch
ApplyPatch hid-multitouch-add-support-for-elo-touchsystems.patch
# stop floppy.ko from autoloading during udev...
@@ -1375,7 +1296,6 @@ ApplyPatch fix_xen_guest_on_old_EC2.patch
# DRM core
# Nouveau DRM
-ApplyPatch drm-ttm-move-notify.patch
ApplyOptionalPatch drm-nouveau-fixes.patch
ApplyOptionalPatch drm-nouveau-updates.patch
@@ -1385,18 +1305,11 @@ ApplyPatch drm-intel-big-hammer.patch
ApplyPatch drm-intel-make-lvds-work.patch
ApplyPatch linux-2.6-intel-iommu-igfx.patch
ApplyPatch drm-intel-edp-fixes.patch
-ApplyPatch drm-i915-fix-pipelined-fencing.patch
-ApplyPatch drm-intel-eeebox-eb1007-quirk.patch
-ApplyPatch drm-intel-restore-mode.patch
ApplyPatch drm-i915-snb-irq-stalls-fix.patch
ApplyPatch drm-i915-apply-hwstam-workaround-for-bsd-ring-on-sandybridge.patch
# radeon DRM (add cayman support)
ApplyPatch drm-radeon-fix-regression-on-atom-cards-with-hardcoded-EDID-record.patch -R
-ApplyPatch drm-radeon-update.patch
-ApplyPatch drm-radeon-update2.patch
-ApplyPatch drm-radeon-pageflip-oops-fix.patch
-ApplyPatch drm-radeon-update3.patch
# linux1394 git patches
#ApplyPatch linux-2.6-firewire-git-update.patch
@@ -1407,7 +1320,6 @@ ApplyPatch linux-2.6-silence-acpi-blacklist.patch
# V4L/DVB updates/fixes/experimental drivers
# apply if non-empty
-ApplyPatch cx88-Fix-HVR4000-IR-keymap.patch -R
ApplyOptionalPatch linux-2.6-v4l-dvb-fixes.patch
ApplyOptionalPatch linux-2.6-v4l-dvb-update.patch
ApplyOptionalPatch linux-2.6-v4l-dvb-experimental.patch
@@ -1420,11 +1332,6 @@ ApplyPatch add-appleir-usb-driver.patch
ApplyPatch neuter_intel_microcode_load.patch
-# various fixes for Apple and EFI
-ApplyPatch apple_backlight.patch
-ApplyPatch efifb_update.patch
-ApplyPatch acpi_reboot.patch
-
# Runtime PM
#ApplyPatch linux-2.6-usb-pci-autosuspend.patch
### Broken by implicit notify support & ACPICA rebase
@@ -1433,27 +1340,13 @@ ApplyPatch acpi_reboot.patch
# rhbz#605888
ApplyPatch dmar-disable-when-ricoh-multifunction.patch
-# rhbz#691888
-ApplyPatch printk-do-not-mangle-valid-userspace-syslog-prefixes.patch
-
ApplyPatch scsi-sd-downgrade-caching-printk-from-error-to-notice.patch
-#rhbz 668231
-ApplyPatch linux-2.6-netconsole-deadlock.patch
-
-# CVE-2011-1581
-ApplyPatch bonding-incorrect-tx-queue-offset.patch
-
-ApplyPatch scsi_dh_hp_sw-fix-deadlock-in-start_stop_endio.patch
-
ApplyPatch bluetooth-device-ids-for-ath3k-on-pegatron-lucid-tablets.patch
# rhbz#709122
ApplyPatch ath5k-disable-fast-channel-switching-by-default.patch
-# rhbz#648732
-ApplyPatch iwlagn-use-cts-to-self-protection-on-5000-adapters-series.patch
-
# rhbz#589390
ApplyPatch crypto-aesni_intel-merge-with-fpu_ko.patch
@@ -2065,6 +1958,9 @@ fi
# and build.
%changelog
+* Wed Jun 29 2011 Dave Jones <davej(a)redhat.com>
+- 2.6.39
+
* Mon Jun 27 2011 Dave Jones <davej(a)redhat.com>
- Disable CONFIG_CRYPTO_MANAGER_DISABLE_TESTS, as this also disables FIPS (rhbz 716942)
diff --git a/linux-2.6-acpi-debug-infinite-loop.patch
b/linux-2.6-acpi-debug-infinite-loop.patch
index 45cb051..d200252 100644
--- a/linux-2.6-acpi-debug-infinite-loop.patch
+++ b/linux-2.6-acpi-debug-infinite-loop.patch
@@ -1,16 +1,3 @@
---- linux-2.6.34.noarch/drivers/acpi/acpica/dsopcode.c~ 2010-07-01 14:40:44.000000000
-0400
-+++ linux-2.6.34.noarch/drivers/acpi/acpica/dsopcode.c 2010-07-01 14:48:56.000000000
-0400
-@@ -1276,6 +1276,10 @@ acpi_ds_exec_end_control_op(struct acpi_
- * loop does not implement a timeout.
- */
- control_state->control.loop_count++;
-+ if ((control_state->control.loop_count > 1) &&
(control_state->control.loop_count % 0xffff == 0))
-+ printk("ACPI: While loop taking a really long time. loop_count=0x%x\n",
-+ control_state->control.loop_count);
-+
- if (control_state->control.loop_count >
- ACPI_MAX_LOOP_ITERATIONS) {
- status = AE_AML_INFINITE_LOOP;
--- linux-2.6.34.noarch/drivers/acpi/acpica/acconfig.h~ 2010-07-01 14:49:03.000000000
-0400
+++ linux-2.6.34.noarch/drivers/acpi/acpica/acconfig.h 2010-07-01 14:49:17.000000000
-0400
@@ -117,7 +117,7 @@
@@ -22,3 +9,17 @@
/* Maximum sleep allowed via Sleep() operator */
+--- a/drivers/acpi/acpica/dscontrol.c
++++ b/drivers/acpi/acpica/dscontrol.c
+@@ -212,6 +212,11 @@ acpi_ds_exec_end_control_op(struct acpi_walk_state * walk_state,
+ * loop does not implement a timeout.
+ */
+ control_state->control.loop_count++;
++ if ((control_state->control.loop_count > 1) &&
++ (control_state->control.loop_count % 0xffff == 0))
++ printk("ACPI: While loop taking a really long time. loop_count=0x%x\n",
++ control_state->control.loop_count);
++
+ if (control_state->control.loop_count >
+ ACPI_MAX_LOOP_ITERATIONS) {
+ status = AE_AML_INFINITE_LOOP;
diff --git a/linux-2.6-crash-driver.patch b/linux-2.6-crash-driver.patch
index 0f11aba..5127743 100644
--- a/linux-2.6-crash-driver.patch
+++ b/linux-2.6-crash-driver.patch
@@ -220,20 +220,18 @@ index 5eb1ba7..3e525d2 100644
/*
* Fix up the linear direct mapping of the kernel to avoid cache attribute
* conflicts.
-diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig
-index 3141dd3..153658c 100644
---- a/drivers/char/Kconfig
-+++ b/drivers/char/Kconfig
-@@ -471,6 +471,8 @@ config LEGACY_PTYS
- security. This option enables these legacy devices; on most
- systems, it is safe to say N.
+--- linux-2.6.39.noarch/drivers/char/Kconfig~ 2011-06-29 23:41:24.386370545 -0400
++++ linux-2.6.39.noarch/drivers/char/Kconfig 2011-06-29 23:42:11.984193335 -0400
+@@ -15,6 +15,9 @@ config DEVKMEM
+ kind of kernel debugging operations.
+ When in doubt, say "N".
+config CRASH
-+ tristate "Crash Utility memory driver"
-
- config LEGACY_PTY_COUNT
- int "Maximum number of legacy PTY in use"
-
++ tristate "Crash Utility memory driver"
++
+ config STALDRV
+ bool "Stallion multiport serial support"
+ depends on SERIAL_NONSTANDARD
diff --git a/drivers/char/crash.c b/drivers/char/crash.c
new file mode 100644
index 0000000..e5437de
diff --git a/linux-2.6-i386-nx-emulation.patch b/linux-2.6-i386-nx-emulation.patch
index da84cc6..3d2c968 100644
--- a/linux-2.6-i386-nx-emulation.patch
+++ b/linux-2.6-i386-nx-emulation.patch
@@ -46,7 +46,7 @@
#endif /* _ASM_X86_DESC_H */
--- a/arch/x86/include/asm/mmu.h
+++ b/arch/x86/include/asm/mmu.h
-@@ -7,12 +7,19 @@
+@@ -7,18 +7,25 @@
/*
* The x86 doesn't have a mmu context, but
* we put the segment information here.
@@ -59,10 +59,16 @@
int size;
struct mutex lock;
void *vdso;
+
+ #ifdef CONFIG_X86_64
+ /* True if mm supports a task running in 32 bit compatibility mode. */
+ unsigned short ia32_compat;
+ #endif
+#ifdef CONFIG_X86_32
+ struct desc_struct user_cs;
+ unsigned long exec_limit;
+#endif
+
} mm_context_t;
#ifdef CONFIG_SMP
@@ -132,7 +138,7 @@
.store_gdt = native_store_gdt,
--- a/arch/x86/kernel/process_32.c
+++ b/arch/x86/kernel/process_32.c
-@@ -243,7 +243,10 @@ int copy_thread(unsigned long clone_flags, unsigned long sp,
+@@ -243,7 +243,10 @@ int copy_thread(unsigned long clone_flag
void
start_thread(struct pt_regs *regs, unsigned long new_ip, unsigned long new_sp)
{
@@ -141,8 +147,8 @@
set_user_gs(regs, 0);
+
regs->fs = 0;
- set_fs(USER_DS);
regs->ds = __USER_DS;
+ regs->es = __USER_DS;
@@ -252,6 +255,11 @@ start_thread(struct pt_regs *regs, unsigned long new_ip, unsigned
long new_sp)
regs->cs = __USER_CS;
regs->ip = new_ip;
@@ -472,8 +478,8 @@
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -101,6 +101,9 @@ struct bio_list;
- struct fs_struct;
struct perf_event_context;
+ struct blk_plug;
+extern int disable_nx;
+extern int print_fatal_signals;
diff --git a/linux-2.6-upstream-reverts.patch b/linux-2.6-upstream-reverts.patch
index 157205f..e69de29 100644
--- a/linux-2.6-upstream-reverts.patch
+++ b/linux-2.6-upstream-reverts.patch
@@ -1,203 +0,0 @@
-From 97bfd0acd32e9639c9136e03955d574655d5cc2b Mon Sep 17 00:00:00 2001
-From: Dave Airlie <airlied(a)redhat.com>
-Date: Thu, 19 May 2011 14:14:43 +1000
-Subject: drm/radeon/kms: add wait idle ioctl for eg->cayman
-
-From: Dave Airlie <airlied(a)redhat.com>
-
-commit 97bfd0acd32e9639c9136e03955d574655d5cc2b upstream.
-
-None of the latest GPUs had this hooked up, this is necessary for
-correct operation in a lot of cases, however we should test this on a few
-GPUs in these families as we've had problems in this area before.
-
-Reviewed-by: Alex Deucher <alexdeucher(a)gmail.com>
-Signed-off-by: Dave Airlie <airlied(a)redhat.com>
-Signed-off-by: Greg Kroah-Hartman <gregkh(a)suse.de>
-
----
- drivers/gpu/drm/radeon/radeon_asic.c | 4 ++++
- 1 file changed, 4 insertions(+)
-
---- a/drivers/gpu/drm/radeon/radeon_asic.c
-+++ b/drivers/gpu/drm/radeon/radeon_asic.c
-@@ -782,6 +782,7 @@ static struct radeon_asic evergreen_asic
- .hpd_fini = &evergreen_hpd_fini,
- .hpd_sense = &evergreen_hpd_sense,
- .hpd_set_polarity = &evergreen_hpd_set_polarity,
-+ .ioctl_wait_idle = r600_ioctl_wait_idle,
- .gui_idle = &r600_gui_idle,
- .pm_misc = &evergreen_pm_misc,
- .pm_prepare = &evergreen_pm_prepare,
-@@ -828,6 +829,7 @@ static struct radeon_asic sumo_asic = {
- .hpd_fini = &evergreen_hpd_fini,
- .hpd_sense = &evergreen_hpd_sense,
- .hpd_set_polarity = &evergreen_hpd_set_polarity,
-+ .ioctl_wait_idle = r600_ioctl_wait_idle,
- .gui_idle = &r600_gui_idle,
- .pm_misc = &evergreen_pm_misc,
- .pm_prepare = &evergreen_pm_prepare,
-@@ -874,6 +876,8 @@ static struct radeon_asic btc_asic = {
- .hpd_fini = &evergreen_hpd_fini,
- .hpd_sense = &evergreen_hpd_sense,
- .hpd_set_polarity = &evergreen_hpd_set_polarity,
-+ .ioctl_wait_idle = r600_ioctl_wait_idle,
-+ .ioctl_wait_idle = r600_ioctl_wait_idle,
- .gui_idle = &r600_gui_idle,
- .pm_misc = &evergreen_pm_misc,
- .pm_prepare = &evergreen_pm_prepare,
-From f25a5c63bfa017498c9adecb24d649ae96ba5c68 Mon Sep 17 00:00:00 2001
-From: Alex Deucher <alexdeucher(a)gmail.com>
-Date: Thu, 19 May 2011 11:07:57 -0400
-Subject: drm/radeon/evergreen/btc/fusion: setup hdp to invalidate and
- flush when asked
-
-From: Alex Deucher <alexdeucher(a)gmail.com>
-
-commit f25a5c63bfa017498c9adecb24d649ae96ba5c68 upstream.
-
-This needs to be explicitly set on btc. It's set by default
-on evergreen/fusion, so it fine to just unconditionally enable it for
-all chips.
-
-Signed-off-by: Alex Deucher <alexdeucher(a)gmail.com>
-Signed-off-by: Dave Airlie <airlied(a)gmail.com>
-Signed-off-by: Greg Kroah-Hartman <gregkh(a)suse.de>
-
----
- drivers/gpu/drm/radeon/evergreen.c | 6 +++++-
- drivers/gpu/drm/radeon/evergreend.h | 2 ++
- 2 files changed, 7 insertions(+), 1 deletion(-)
-
---- a/drivers/gpu/drm/radeon/evergreen.c
-+++ b/drivers/gpu/drm/radeon/evergreen.c
-@@ -1585,7 +1585,7 @@ static void evergreen_gpu_init(struct ra
- u32 sq_stack_resource_mgmt_2;
- u32 sq_stack_resource_mgmt_3;
- u32 vgt_cache_invalidation;
-- u32 hdp_host_path_cntl;
-+ u32 hdp_host_path_cntl, tmp;
- int i, j, num_shader_engines, ps_thread_count;
-
- switch (rdev->family) {
-@@ -2145,6 +2145,10 @@ static void evergreen_gpu_init(struct ra
- for (i = SQ_ALU_CONST_BUFFER_SIZE_HS_0; i < 0x29000; i += 4)
- WREG32(i, 0);
-
-+ tmp = RREG32(HDP_MISC_CNTL);
-+ tmp |= HDP_FLUSH_INVALIDATE_CACHE;
-+ WREG32(HDP_MISC_CNTL, tmp);
-+
- hdp_host_path_cntl = RREG32(HDP_HOST_PATH_CNTL);
- WREG32(HDP_HOST_PATH_CNTL, hdp_host_path_cntl);
-
---- a/drivers/gpu/drm/radeon/evergreend.h
-+++ b/drivers/gpu/drm/radeon/evergreend.h
-@@ -64,6 +64,8 @@
- #define GB_BACKEND_MAP 0x98FC
- #define DMIF_ADDR_CONFIG 0xBD4
- #define HDP_ADDR_CONFIG 0x2F48
-+#define HDP_MISC_CNTL 0x2F4C
-+#define HDP_FLUSH_INVALIDATE_CACHE (1 << 0)
-
- #define CC_SYS_RB_BACKEND_DISABLE 0x3F88
- #define GC_USER_RB_BACKEND_DISABLE 0x9B7C
-From alexdeucher(a)gmail.com Mon May 9 16:35:34 2011
-From: Alex Deucher <alexdeucher(a)gmail.com>
-Date: Fri, 6 May 2011 14:29:55 -0400
-Subject: [stable] [PATCH] drm/radeon/kms: fix gart setup on fusion parts (v2) backport
-To: stable(a)kernel.org
-Cc: Alex Deucher <alexdeucher(a)gmail.com>, airlied(a)redhat.com, gregkh(a)suse.de
-Message-ID: <1304706595-9781-1-git-send-email-alexdeucher(a)gmail.com>
-
-From: Alex Deucher <alexdeucher(a)gmail.com>
-
-Backport of 8aeb96f80232e9a701b5c4715504f4c9173978bd
-(drm/radeon/kms: fix gart setup on fusion parts (v2))
-to the stable tree.
-
-Out of the entire GART/VM subsystem, the hw designers changed
-the location of 3 regs.
-
-v2: airlied: add parameter for userspace to work from.
-
-Signed-off-by: Alex Deucher <alexdeucher(a)gmail.com>
-Signed-off-by: Jerome Glisse <jglisse(a)redhat.com>
-Signed-off-by: Dave Airlie <airlied(a)redhat.com>
-Signed-off-by: Greg Kroah-Hartman <gregkh(a)suse.de>
----
- drivers/gpu/drm/radeon/evergreen.c | 17 +++++++++--------
- drivers/gpu/drm/radeon/evergreend.h | 5 +++++
- drivers/gpu/drm/radeon/radeon_kms.c | 3 +++
- include/drm/radeon_drm.h | 1 +
- 4 files changed, 18 insertions(+), 8 deletions(-)
-
---- a/drivers/gpu/drm/radeon/evergreen.c
-+++ b/drivers/gpu/drm/radeon/evergreen.c
-@@ -869,9 +869,15 @@ int evergreen_pcie_gart_enable(struct ra
- SYSTEM_ACCESS_MODE_NOT_IN_SYS |
- SYSTEM_APERTURE_UNMAPPED_ACCESS_PASS_THRU |
- EFFECTIVE_L1_TLB_SIZE(5) | EFFECTIVE_L1_QUEUE_SIZE(5);
-- WREG32(MC_VM_MD_L1_TLB0_CNTL, tmp);
-- WREG32(MC_VM_MD_L1_TLB1_CNTL, tmp);
-- WREG32(MC_VM_MD_L1_TLB2_CNTL, tmp);
-+ if (rdev->flags & RADEON_IS_IGP) {
-+ WREG32(FUS_MC_VM_MD_L1_TLB0_CNTL, tmp);
-+ WREG32(FUS_MC_VM_MD_L1_TLB1_CNTL, tmp);
-+ WREG32(FUS_MC_VM_MD_L1_TLB2_CNTL, tmp);
-+ } else {
-+ WREG32(MC_VM_MD_L1_TLB0_CNTL, tmp);
-+ WREG32(MC_VM_MD_L1_TLB1_CNTL, tmp);
-+ WREG32(MC_VM_MD_L1_TLB2_CNTL, tmp);
-+ }
- WREG32(MC_VM_MB_L1_TLB0_CNTL, tmp);
- WREG32(MC_VM_MB_L1_TLB1_CNTL, tmp);
- WREG32(MC_VM_MB_L1_TLB2_CNTL, tmp);
-@@ -2930,11 +2936,6 @@ static int evergreen_startup(struct rade
- rdev->asic->copy = NULL;
- dev_warn(rdev->dev, "failed blitter (%d) falling back to memcpy\n", r);
- }
-- /* XXX: ontario has problems blitting to gart at the moment */
-- if (rdev->family == CHIP_PALM) {
-- rdev->asic->copy = NULL;
-- radeon_ttm_set_active_vram_size(rdev, rdev->mc.visible_vram_size);
-- }
-
- /* allocate wb buffer */
- r = radeon_wb_init(rdev);
---- a/drivers/gpu/drm/radeon/evergreend.h
-+++ b/drivers/gpu/drm/radeon/evergreend.h
-@@ -221,6 +221,11 @@
- #define MC_VM_MD_L1_TLB0_CNTL 0x2654
- #define MC_VM_MD_L1_TLB1_CNTL 0x2658
- #define MC_VM_MD_L1_TLB2_CNTL 0x265C
-+
-+#define FUS_MC_VM_MD_L1_TLB0_CNTL 0x265C
-+#define FUS_MC_VM_MD_L1_TLB1_CNTL 0x2660
-+#define FUS_MC_VM_MD_L1_TLB2_CNTL 0x2664
-+
- #define MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR 0x203C
- #define MC_VM_SYSTEM_APERTURE_HIGH_ADDR 0x2038
- #define MC_VM_SYSTEM_APERTURE_LOW_ADDR 0x2034
---- a/drivers/gpu/drm/radeon/radeon_kms.c
-+++ b/drivers/gpu/drm/radeon/radeon_kms.c
-@@ -205,6 +205,9 @@ int radeon_info_ioctl(struct drm_device
- /* return clock value in KHz */
- value = rdev->clock.spll.reference_freq * 10;
- break;
-+ case RADEON_INFO_FUSION_GART_WORKING:
-+ value = 1;
-+ break;
- default:
- DRM_DEBUG_KMS("Invalid request %d\n", info->request);
- return -EINVAL;
---- a/include/drm/radeon_drm.h
-+++ b/include/drm/radeon_drm.h
-@@ -908,6 +908,7 @@ struct drm_radeon_cs {
- #define RADEON_INFO_WANT_HYPERZ 0x07
- #define RADEON_INFO_WANT_CMASK 0x08 /* get access to CMASK on r300 */
- #define RADEON_INFO_CLOCK_CRYSTAL_FREQ 0x09 /* clock crystal frequency */
-+#define RADEON_INFO_FUSION_GART_WORKING 0x0c /* fusion writes to GTT were broken before
this */
-
- struct drm_radeon_info {
- uint32_t request;
diff --git a/linux-2.6-utrace-ptrace.patch b/linux-2.6-utrace-ptrace.patch
index 367deb9..55c6f61 100644
--- a/linux-2.6-utrace-ptrace.patch
+++ b/linux-2.6-utrace-ptrace.patch
@@ -48,7 +48,7 @@ new file mode 100644
index ...a5bcb9e 100644
--- /dev/null
+++ b/kernel/ptrace-utrace.c
-@@ -0,0 +1,1187 @@
+@@ -0,0 +1,1186 @@
+/*
+ * linux/kernel/ptrace.c
+ *
@@ -65,7 +65,6 @@ index ...a5bcb9e 100644
+#include <linux/mm.h>
+#include <linux/highmem.h>
+#include <linux/pagemap.h>
-+#include <linux/smp_lock.h>
+#include <linux/ptrace.h>
+#include <linux/utrace.h>
+#include <linux/security.h>
@@ -1248,7 +1247,333 @@ index e275608..72ea65c 100644
#include <linux/security.h>
#include <linux/signal.h>
#include <linux/audit.h>
-@@ -24,7 +23,320 @@
+@@ -195,8 +452,6 @@ int ptrace_attach(struct task_struct *ta
+
+ task_lock(task);
+ retval = __ptrace_may_access(task, PTRACE_MODE_ATTACH);
+- if (!retval && exclude_ptrace(task))
+- retval = -EBUSY;
+ task_unlock(task);
+ if (retval)
+ goto unlock_creds;
+@@ -220,91 +475,37 @@ unlock_tasklist:
+ write_unlock_irq(&tasklist_lock);
+ unlock_creds:
+ mutex_unlock(&task->signal->cred_guard_mutex);
+-out:
+- return retval;
+-}
+-
+-/**
+- * ptrace_traceme -- helper for PTRACE_TRACEME
+- *
+- * Performs checks and sets PT_PTRACED.
+- * Should be used by all ptrace implementations for PTRACE_TRACEME.
+- */
+-int ptrace_traceme(void)
+-{
+- int ret = -EPERM;
+-
+- if (exclude_ptrace(current)) /* XXX locking */
+- return -EBUSY;
+-
+- write_lock_irq(&tasklist_lock);
+- /* Are we already being traced? */
+- if (!current->ptrace) {
+- ret = security_ptrace_traceme(current->parent);
+- /*
+- * Check PF_EXITING to ensure ->real_parent has not passed
+- * exit_ptrace(). Otherwise we don't report the error but
+- * pretend ->real_parent untraces us right after return.
+- */
+- if (!ret && !(current->real_parent->flags & PF_EXITING)) {
+- current->ptrace = PT_PTRACED;
+- __ptrace_link(current, current->real_parent);
+- }
+- }
+- write_unlock_irq(&tasklist_lock);
+-
+- return ret;
+-}
+-
+-/*
+- * Called with irqs disabled, returns true if childs should reap themselves.
+- */
+-static int ignoring_children(struct sighand_struct *sigh)
+-{
+- int ret;
+- spin_lock(&sigh->siglock);
+- ret = (sigh->action[SIGCHLD-1].sa.sa_handler == SIG_IGN) ||
+- (sigh->action[SIGCHLD-1].sa.sa_flags & SA_NOCLDWAIT);
+- spin_unlock(&sigh->siglock);
+- return ret;
+-}
+-
+-/*
+- * Called with tasklist_lock held for writing.
+- * Unlink a traced task, and clean it up if it was a traced zombie.
+- * Return true if it needs to be reaped with release_task().
+- * (We can't call release_task() here because we already hold tasklist_lock.)
+- *
+- * If it's a zombie, our attachedness prevented normal parent notification
+- * or self-reaping. Do notification now if it would have happened earlier.
+- * If it should reap itself, return true.
++out:
++ return retval;
++}
++
++/**
++ * ptrace_traceme -- helper for PTRACE_TRACEME
+ *
+- * If it's our own child, there is no notification to do. But if our normal
+- * children self-reap, then this child was prevented by ptrace and we must
+- * reap it now, in that case we must also wake up sub-threads sleeping in
+- * do_wait().
++ * Performs checks and sets PT_PTRACED.
++ * Should be used by all ptrace implementations for PTRACE_TRACEME.
+ */
+-bool __ptrace_detach(struct task_struct *tracer, struct task_struct *p)
++int ptrace_traceme(void)
+ {
+- __ptrace_unlink(p);
++ int ret = -EPERM;
+
+- if (p->exit_state == EXIT_ZOMBIE) {
+- if (!task_detached(p) && thread_group_empty(p)) {
+- if (!same_thread_group(p->real_parent, tracer))
+- do_notify_parent(p, p->exit_signal);
+- else if (ignoring_children(tracer->sighand)) {
+- __wake_up_parent(p, tracer);
+- p->exit_signal = -1;
+- }
+- }
+- if (task_detached(p)) {
+- /* Mark it as in the process of being reaped. */
+- p->exit_state = EXIT_DEAD;
+- return true;
++ write_lock_irq(&tasklist_lock);
++ /* Are we already being traced? */
++ if (!current->ptrace) {
++ ret = security_ptrace_traceme(current->parent);
++ /*
++ * Check PF_EXITING to ensure ->real_parent has not passed
++ * exit_ptrace(). Otherwise we don't report the error but
++ * pretend ->real_parent untraces us right after return.
++ */
++ if (!ret && !(current->real_parent->flags & PF_EXITING)) {
++ current->ptrace = PT_PTRACED;
++ __ptrace_link(current, current->real_parent);
+ }
+ }
++ write_unlock_irq(&tasklist_lock);
+
+- return false;
++ return ret;
+ }
+
+ int ptrace_detach(struct task_struct *child, unsigned int data)
+@@ -368,57 +569,7 @@ void exit_ptrace(struct task_struct *tra
+ write_lock_irq(&tasklist_lock);
+ }
+
+-int ptrace_readdata(struct task_struct *tsk, unsigned long src, char __user *dst, int
len)
+-{
+- int copied = 0;
+-
+- while (len > 0) {
+- char buf[128];
+- int this_len, retval;
+-
+- this_len = (len > sizeof(buf)) ? sizeof(buf) : len;
+- retval = access_process_vm(tsk, src, buf, this_len, 0);
+- if (!retval) {
+- if (copied)
+- break;
+- return -EIO;
+- }
+- if (copy_to_user(dst, buf, retval))
+- return -EFAULT;
+- copied += retval;
+- src += retval;
+- dst += retval;
+- len -= retval;
+- }
+- return copied;
+-}
+-
+-int ptrace_writedata(struct task_struct *tsk, char __user *src, unsigned long dst, int
len)
+-{
+- int copied = 0;
+-
+- while (len > 0) {
+- char buf[128];
+- int this_len, retval;
+-
+- this_len = (len > sizeof(buf)) ? sizeof(buf) : len;
+- if (copy_from_user(buf, src, this_len))
+- return -EFAULT;
+- retval = access_process_vm(tsk, dst, buf, this_len, 1);
+- if (!retval) {
+- if (copied)
+- break;
+- return -EIO;
+- }
+- copied += retval;
+- src += retval;
+- dst += retval;
+- len -= retval;
+- }
+- return copied;
+-}
+-
+-static int ptrace_setoptions(struct task_struct *child, unsigned long data)
++static int ptrace_setoptions(struct task_struct *child, long data)
+ {
+ child->ptrace &= ~PT_TRACE_MASK;
+
+@@ -533,47 +683,6 @@ static int ptrace_resume(struct task_str
+ return 0;
+ }
+
+-#ifdef CONFIG_HAVE_ARCH_TRACEHOOK
+-
+-static const struct user_regset *
+-find_regset(const struct user_regset_view *view, unsigned int type)
+-{
+- const struct user_regset *regset;
+- int n;
+-
+- for (n = 0; n < view->n; ++n) {
+- regset = view->regsets + n;
+- if (regset->core_note_type == type)
+- return regset;
+- }
+-
+- return NULL;
+-}
+-
+-static int ptrace_regset(struct task_struct *task, int req, unsigned int type,
+- struct iovec *kiov)
+-{
+- const struct user_regset_view *view = task_user_regset_view(task);
+- const struct user_regset *regset = find_regset(view, type);
+- int regset_no;
+-
+- if (!regset || (kiov->iov_len % regset->size) != 0)
+- return -EINVAL;
+-
+- regset_no = regset - view->regsets;
+- kiov->iov_len = min(kiov->iov_len,
+- (__kernel_size_t) (regset->n * regset->size));
+-
+- if (req == PTRACE_GETREGSET)
+- return copy_regset_to_user(task, view, regset_no, 0,
+- kiov->iov_len, kiov->iov_base);
+- else
+- return copy_regset_from_user(task, view, regset_no, 0,
+- kiov->iov_len, kiov->iov_base);
+-}
+-
+-#endif
+-
+ int ptrace_request(struct task_struct *child, long request,
+ unsigned long addr, unsigned long data)
+ {
+@@ -689,91 +798,7 @@ int ptrace_request(struct task_struct *c
+ return ret;
+ }
+
+-static struct task_struct *ptrace_get_task_struct(pid_t pid)
+-{
+- struct task_struct *child;
+-
+- rcu_read_lock();
+- child = find_task_by_vpid(pid);
+- if (child)
+- get_task_struct(child);
+- rcu_read_unlock();
+-
+- if (!child)
+- return ERR_PTR(-ESRCH);
+- return child;
+-}
+-
+-#ifndef arch_ptrace_attach
+-#define arch_ptrace_attach(child) do { } while (0)
+-#endif
+-
+-SYSCALL_DEFINE4(ptrace, long, request, long, pid, unsigned long, addr,
+- unsigned long, data)
+-{
+- struct task_struct *child;
+- long ret;
+-
+- if (request == PTRACE_TRACEME) {
+- ret = ptrace_traceme();
+- if (!ret)
+- arch_ptrace_attach(current);
+- goto out;
+- }
+-
+- child = ptrace_get_task_struct(pid);
+- if (IS_ERR(child)) {
+- ret = PTR_ERR(child);
+- goto out;
+- }
+-
+- if (request == PTRACE_ATTACH) {
+- ret = ptrace_attach(child);
+- /*
+- * Some architectures need to do book-keeping after
+- * a ptrace attach.
+- */
+- if (!ret)
+- arch_ptrace_attach(child);
+- goto out_put_task_struct;
+- }
+-
+- ret = ptrace_check_attach(child, request == PTRACE_KILL);
+- if (ret < 0)
+- goto out_put_task_struct;
+-
+- ret = arch_ptrace(child, request, addr, data);
+-
+- out_put_task_struct:
+- put_task_struct(child);
+- out:
+- return ret;
+-}
+-
+-int generic_ptrace_peekdata(struct task_struct *tsk, unsigned long addr,
+- unsigned long data)
+-{
+- unsigned long tmp;
+- int copied;
+-
+- copied = access_process_vm(tsk, addr, &tmp, sizeof(tmp), 0);
+- if (copied != sizeof(tmp))
+- return -EIO;
+- return put_user(tmp, (unsigned long __user *)data);
+-}
+-
+-int generic_ptrace_pokedata(struct task_struct *tsk, unsigned long addr,
+- unsigned long data)
+-{
+- int copied;
+-
+- copied = access_process_vm(tsk, addr, &data, sizeof(data), 1);
+- return (copied == sizeof(data)) ? 0 : -EIO;
+-}
+-
+ #if defined CONFIG_COMPAT
+-#include <linux/compat.h>
+-
+ int compat_ptrace_request(struct task_struct *child, compat_long_t request,
+ compat_ulong_t addr, compat_ulong_t data)
+ {
+--- linux-2.6.39.noarch/kernel/ptrace.c~ 2011-06-30 01:26:39.872164118 -0400
++++ linux-2.6.39.noarch/kernel/ptrace.c 2011-06-30 01:30:09.682400285 -0400
+@@ -24,8 +24,321 @@
#include <linux/regset.h>
#include <linux/hw_breakpoint.h>
@@ -1298,8 +1623,8 @@ index e275608..72ea65c 100644
+ task_unlock(task);
+ return !err;
+}
-+
-+/*
+
+ /*
+ * Called with irqs disabled, returns true if childs should reap themselves.
+ */
+static int ignoring_children(struct sighand_struct *sigh)
@@ -1472,7 +1797,7 @@ index e275608..72ea65c 100644
+ arch_ptrace_attach(current);
+ goto out;
+ }
-
++
+ child = ptrace_get_task_struct(pid);
+ if (IS_ERR(child)) {
+ ret = PTR_ERR(child);
@@ -1544,422 +1869,101 @@ index e275608..72ea65c 100644
+ }
+
+ if (request == PTRACE_ATTACH) {
-+ ret = ptrace_attach(child);
-+ /*
-+ * Some architectures need to do book-keeping after
-+ * a ptrace attach.
-+ */
-+ if (!ret)
-+ arch_ptrace_attach(child);
-+ goto out_put_task_struct;
-+ }
-+
-+ ret = ptrace_check_attach(child, request == PTRACE_KILL);
-+ if (!ret)
-+ ret = compat_arch_ptrace(child, request, addr, data);
-+
-+ out_put_task_struct:
-+ put_task_struct(child);
-+ out:
-+ return ret;
-+}
-+#endif /* CONFIG_COMPAT */
-+
-+#ifndef CONFIG_UTRACE
- /*
- * ptrace a task: make the debugger its new parent and
- * move it to the ptrace list.
-@@ -117,61 +429,6 @@ int ptrace_check_attach(struct task_stru
- return ret;
- }
-
--int __ptrace_may_access(struct task_struct *task, unsigned int mode)
--{
-- const struct cred *cred = current_cred(), *tcred;
--
-- /* May we inspect the given task?
-- * This check is used both for attaching with ptrace
-- * and for allowing access to sensitive information in /proc.
-- *
-- * ptrace_attach denies several cases that /proc allows
-- * because setting up the necessary parent/child relationship
-- * or halting the specified task is impossible.
-- */
-- int dumpable = 0;
-- /* Don't let security modules deny introspection */
-- if (task == current)
-- return 0;
-- rcu_read_lock();
-- tcred = __task_cred(task);
-- if ((cred->uid != tcred->euid ||
-- cred->uid != tcred->suid ||
-- cred->uid != tcred->uid ||
-- cred->gid != tcred->egid ||
-- cred->gid != tcred->sgid ||
-- cred->gid != tcred->gid) &&
-- !capable(CAP_SYS_PTRACE)) {
-- rcu_read_unlock();
-- return -EPERM;
-- }
-- rcu_read_unlock();
-- smp_rmb();
-- if (task->mm)
-- dumpable = get_dumpable(task->mm);
-- if (!dumpable && !capable(CAP_SYS_PTRACE))
-- return -EPERM;
--
-- return security_ptrace_access_check(task, mode);
--}
--
--bool ptrace_may_access(struct task_struct *task, unsigned int mode)
--{
-- int err;
-- task_lock(task);
-- err = __ptrace_may_access(task, mode);
-- task_unlock(task);
-- return !err;
--}
--
--/*
-- * For experimental use of utrace, exclude ptrace on the same task.
-- */
--static inline bool exclude_ptrace(struct task_struct *task)
--{
-- return unlikely(!!task_utrace_flags(task));
--}
--
- int ptrace_attach(struct task_struct *task)
- {
- int retval;
-@@ -195,8 +452,6 @@ int ptrace_attach(struct task_struct *ta
-
- task_lock(task);
- retval = __ptrace_may_access(task, PTRACE_MODE_ATTACH);
-- if (!retval && exclude_ptrace(task))
-- retval = -EBUSY;
- task_unlock(task);
- if (retval)
- goto unlock_creds;
-@@ -220,91 +475,37 @@ unlock_tasklist:
- write_unlock_irq(&tasklist_lock);
- unlock_creds:
- mutex_unlock(&task->signal->cred_guard_mutex);
--out:
-- return retval;
--}
--
--/**
-- * ptrace_traceme -- helper for PTRACE_TRACEME
-- *
-- * Performs checks and sets PT_PTRACED.
-- * Should be used by all ptrace implementations for PTRACE_TRACEME.
-- */
--int ptrace_traceme(void)
--{
-- int ret = -EPERM;
--
-- if (exclude_ptrace(current)) /* XXX locking */
-- return -EBUSY;
--
-- write_lock_irq(&tasklist_lock);
-- /* Are we already being traced? */
-- if (!current->ptrace) {
-- ret = security_ptrace_traceme(current->parent);
-- /*
-- * Check PF_EXITING to ensure ->real_parent has not passed
-- * exit_ptrace(). Otherwise we don't report the error but
-- * pretend ->real_parent untraces us right after return.
-- */
-- if (!ret && !(current->real_parent->flags & PF_EXITING)) {
-- current->ptrace = PT_PTRACED;
-- __ptrace_link(current, current->real_parent);
-- }
-- }
-- write_unlock_irq(&tasklist_lock);
--
-- return ret;
--}
--
--/*
-- * Called with irqs disabled, returns true if childs should reap themselves.
-- */
--static int ignoring_children(struct sighand_struct *sigh)
--{
-- int ret;
-- spin_lock(&sigh->siglock);
-- ret = (sigh->action[SIGCHLD-1].sa.sa_handler == SIG_IGN) ||
-- (sigh->action[SIGCHLD-1].sa.sa_flags & SA_NOCLDWAIT);
-- spin_unlock(&sigh->siglock);
-- return ret;
--}
--
--/*
-- * Called with tasklist_lock held for writing.
-- * Unlink a traced task, and clean it up if it was a traced zombie.
-- * Return true if it needs to be reaped with release_task().
-- * (We can't call release_task() here because we already hold tasklist_lock.)
-- *
-- * If it's a zombie, our attachedness prevented normal parent notification
-- * or self-reaping. Do notification now if it would have happened earlier.
-- * If it should reap itself, return true.
-+out:
-+ return retval;
-+}
-+
-+/**
-+ * ptrace_traceme -- helper for PTRACE_TRACEME
- *
-- * If it's our own child, there is no notification to do. But if our normal
-- * children self-reap, then this child was prevented by ptrace and we must
-- * reap it now, in that case we must also wake up sub-threads sleeping in
-- * do_wait().
-+ * Performs checks and sets PT_PTRACED.
-+ * Should be used by all ptrace implementations for PTRACE_TRACEME.
- */
--bool __ptrace_detach(struct task_struct *tracer, struct task_struct *p)
-+int ptrace_traceme(void)
- {
-- __ptrace_unlink(p);
-+ int ret = -EPERM;
-
-- if (p->exit_state == EXIT_ZOMBIE) {
-- if (!task_detached(p) && thread_group_empty(p)) {
-- if (!same_thread_group(p->real_parent, tracer))
-- do_notify_parent(p, p->exit_signal);
-- else if (ignoring_children(tracer->sighand)) {
-- __wake_up_parent(p, tracer);
-- p->exit_signal = -1;
-- }
-- }
-- if (task_detached(p)) {
-- /* Mark it as in the process of being reaped. */
-- p->exit_state = EXIT_DEAD;
-- return true;
-+ write_lock_irq(&tasklist_lock);
-+ /* Are we already being traced? */
-+ if (!current->ptrace) {
-+ ret = security_ptrace_traceme(current->parent);
++ ret = ptrace_attach(child);
+ /*
-+ * Check PF_EXITING to ensure ->real_parent has not passed
-+ * exit_ptrace(). Otherwise we don't report the error but
-+ * pretend ->real_parent untraces us right after return.
++ * Some architectures need to do book-keeping after
++ * a ptrace attach.
+ */
-+ if (!ret && !(current->real_parent->flags & PF_EXITING)) {
-+ current->ptrace = PT_PTRACED;
-+ __ptrace_link(current, current->real_parent);
- }
- }
-+ write_unlock_irq(&tasklist_lock);
-
-- return false;
++ if (!ret)
++ arch_ptrace_attach(child);
++ goto out_put_task_struct;
++ }
++
++ ret = ptrace_check_attach(child, request == PTRACE_KILL);
++ if (!ret)
++ ret = compat_arch_ptrace(child, request, addr, data);
++
++ out_put_task_struct:
++ put_task_struct(child);
++ out:
+ return ret;
- }
-
- int ptrace_detach(struct task_struct *child, unsigned int data)
-@@ -368,57 +569,7 @@ void exit_ptrace(struct task_struct *tra
- write_lock_irq(&tasklist_lock);
- }
-
--int ptrace_readdata(struct task_struct *tsk, unsigned long src, char __user *dst, int
len)
--{
-- int copied = 0;
--
-- while (len > 0) {
-- char buf[128];
-- int this_len, retval;
--
-- this_len = (len > sizeof(buf)) ? sizeof(buf) : len;
-- retval = access_process_vm(tsk, src, buf, this_len, 0);
-- if (!retval) {
-- if (copied)
-- break;
-- return -EIO;
-- }
-- if (copy_to_user(dst, buf, retval))
-- return -EFAULT;
-- copied += retval;
-- src += retval;
-- dst += retval;
-- len -= retval;
-- }
-- return copied;
--}
--
--int ptrace_writedata(struct task_struct *tsk, char __user *src, unsigned long dst, int
len)
--{
-- int copied = 0;
--
-- while (len > 0) {
-- char buf[128];
-- int this_len, retval;
--
-- this_len = (len > sizeof(buf)) ? sizeof(buf) : len;
-- if (copy_from_user(buf, src, this_len))
-- return -EFAULT;
-- retval = access_process_vm(tsk, dst, buf, this_len, 1);
-- if (!retval) {
-- if (copied)
-- break;
-- return -EIO;
-- }
-- copied += retval;
-- src += retval;
-- dst += retval;
-- len -= retval;
-- }
-- return copied;
--}
--
--static int ptrace_setoptions(struct task_struct *child, unsigned long data)
-+static int ptrace_setoptions(struct task_struct *child, long data)
- {
- child->ptrace &= ~PT_TRACE_MASK;
-
-@@ -533,47 +683,6 @@ static int ptrace_resume(struct task_str
- return 0;
- }
-
--#ifdef CONFIG_HAVE_ARCH_TRACEHOOK
--
--static const struct user_regset *
--find_regset(const struct user_regset_view *view, unsigned int type)
--{
-- const struct user_regset *regset;
-- int n;
--
-- for (n = 0; n < view->n; ++n) {
-- regset = view->regsets + n;
-- if (regset->core_note_type == type)
-- return regset;
-- }
--
-- return NULL;
--}
--
--static int ptrace_regset(struct task_struct *task, int req, unsigned int type,
-- struct iovec *kiov)
--{
-- const struct user_regset_view *view = task_user_regset_view(task);
-- const struct user_regset *regset = find_regset(view, type);
-- int regset_no;
--
-- if (!regset || (kiov->iov_len % regset->size) != 0)
-- return -EINVAL;
--
-- regset_no = regset - view->regsets;
-- kiov->iov_len = min(kiov->iov_len,
-- (__kernel_size_t) (regset->n * regset->size));
--
-- if (req == PTRACE_GETREGSET)
-- return copy_regset_to_user(task, view, regset_no, 0,
-- kiov->iov_len, kiov->iov_base);
-- else
-- return copy_regset_from_user(task, view, regset_no, 0,
-- kiov->iov_len, kiov->iov_base);
--}
--
--#endif
--
- int ptrace_request(struct task_struct *child, long request,
- unsigned long addr, unsigned long data)
- {
-@@ -689,91 +798,7 @@ int ptrace_request(struct task_struct *c
++}
++#endif /* CONFIG_COMPAT */
++
++#ifndef CONFIG_UTRACE
++/*
+ * ptrace a task: make the debugger its new parent and
+ * move it to the ptrace list.
+ *
+@@ -117,64 +430,6 @@ int ptrace_check_attach(struct task_stru
return ret;
}
--static struct task_struct *ptrace_get_task_struct(pid_t pid)
+-int __ptrace_may_access(struct task_struct *task, unsigned int mode)
-{
-- struct task_struct *child;
+- const struct cred *cred = current_cred(), *tcred;
-
+- /* May we inspect the given task?
+- * This check is used both for attaching with ptrace
+- * and for allowing access to sensitive information in /proc.
+- *
+- * ptrace_attach denies several cases that /proc allows
+- * because setting up the necessary parent/child relationship
+- * or halting the specified task is impossible.
+- */
+- int dumpable = 0;
+- /* Don't let security modules deny introspection */
+- if (task == current)
+- return 0;
- rcu_read_lock();
-- child = find_task_by_vpid(pid);
-- if (child)
-- get_task_struct(child);
+- tcred = __task_cred(task);
+- if (cred->user->user_ns == tcred->user->user_ns &&
+- (cred->uid == tcred->euid &&
+- cred->uid == tcred->suid &&
+- cred->uid == tcred->uid &&
+- cred->gid == tcred->egid &&
+- cred->gid == tcred->sgid &&
+- cred->gid == tcred->gid))
+- goto ok;
+- if (ns_capable(tcred->user->user_ns, CAP_SYS_PTRACE))
+- goto ok;
- rcu_read_unlock();
+- return -EPERM;
+-ok:
+- rcu_read_unlock();
+- smp_rmb();
+- if (task->mm)
+- dumpable = get_dumpable(task->mm);
+- if (!dumpable && !task_ns_capable(task, CAP_SYS_PTRACE))
+- return -EPERM;
-
-- if (!child)
-- return ERR_PTR(-ESRCH);
-- return child;
--}
--
--#ifndef arch_ptrace_attach
--#define arch_ptrace_attach(child) do { } while (0)
--#endif
--
--SYSCALL_DEFINE4(ptrace, long, request, long, pid, unsigned long, addr,
-- unsigned long, data)
--{
-- struct task_struct *child;
-- long ret;
--
-- if (request == PTRACE_TRACEME) {
-- ret = ptrace_traceme();
-- if (!ret)
-- arch_ptrace_attach(current);
-- goto out;
-- }
--
-- child = ptrace_get_task_struct(pid);
-- if (IS_ERR(child)) {
-- ret = PTR_ERR(child);
-- goto out;
-- }
--
-- if (request == PTRACE_ATTACH) {
-- ret = ptrace_attach(child);
-- /*
-- * Some architectures need to do book-keeping after
-- * a ptrace attach.
-- */
-- if (!ret)
-- arch_ptrace_attach(child);
-- goto out_put_task_struct;
-- }
--
-- ret = ptrace_check_attach(child, request == PTRACE_KILL);
-- if (ret < 0)
-- goto out_put_task_struct;
--
-- ret = arch_ptrace(child, request, addr, data);
--
-- out_put_task_struct:
-- put_task_struct(child);
-- out:
-- return ret;
+- return security_ptrace_access_check(task, mode);
-}
-
--int generic_ptrace_peekdata(struct task_struct *tsk, unsigned long addr,
-- unsigned long data)
+-bool ptrace_may_access(struct task_struct *task, unsigned int mode)
-{
-- unsigned long tmp;
-- int copied;
--
-- copied = access_process_vm(tsk, addr, &tmp, sizeof(tmp), 0);
-- if (copied != sizeof(tmp))
-- return -EIO;
-- return put_user(tmp, (unsigned long __user *)data);
+- int err;
+- task_lock(task);
+- err = __ptrace_may_access(task, mode);
+- task_unlock(task);
+- return !err;
-}
-
--int generic_ptrace_pokedata(struct task_struct *tsk, unsigned long addr,
-- unsigned long data)
+-/*
+- * For experimental use of utrace, exclude ptrace on the same task.
+- */
+-static inline bool exclude_ptrace(struct task_struct *task)
-{
-- int copied;
--
-- copied = access_process_vm(tsk, addr, &data, sizeof(data), 1);
-- return (copied == sizeof(data)) ? 0 : -EIO;
+- return unlikely(!!task_utrace_flags(task));
-}
-
- #if defined CONFIG_COMPAT
--#include <linux/compat.h>
--
- int compat_ptrace_request(struct task_struct *child, compat_long_t request,
- compat_ulong_t addr, compat_ulong_t data)
+ int ptrace_attach(struct task_struct *task)
{
-@@ -851,45 +876,8 @@ int compat_ptrace_request(struct task_st
-
+ int retval;
+@@ -624,44 +879,8 @@ int compat_ptrace_request(struct task_st
return ret;
}
--
+
-asmlinkage long compat_sys_ptrace(compat_long_t request, compat_long_t pid,
- compat_long_t addr, compat_long_t data)
-{
@@ -1998,7 +2002,7 @@ index e275608..72ea65c 100644
- return ret;
-}
#endif /* CONFIG_COMPAT */
-+#endif /* CONFIG_UTRACE */
++#endif /* CONFIG_UTRACE */
#ifdef CONFIG_HAVE_HW_BREAKPOINT
int ptrace_get_breakpoints(struct task_struct *tsk)
diff --git a/linux-2.6-v4l-dvb-experimental.patch b/linux-2.6-v4l-dvb-experimental.patch
index 308ca63..e69de29 100644
--- a/linux-2.6-v4l-dvb-experimental.patch
+++ b/linux-2.6-v4l-dvb-experimental.patch
@@ -1,1326 +0,0 @@
-commit 9069f7f1ce7309cba021ac9c3527526d8524bd04
-Author: Jarod Wilson <jarod(a)redhat.com>
-Date: Mon Apr 25 13:50:50 2011 -0400
-
- [media] ite-cir: modular build on ppc requires delay.h include
-
- Signed-off-by: Jarod Wilson <jarod(a)redhat.com>
-
-commit 50f19c24801caaa6d846c62cef93ee54f6e6914f
-Author: Jarod Wilson <jarod(a)redhat.com>
-Date: Mon Apr 25 13:48:18 2011 -0400
-
- [media] mceusb: add Dell transceiver ID
-
- Add device ID for a Dell-branded, Philips device ID transceiver reported
- by an OpenELEC user on their forums.
-
-
http://openelec.tv/forum/27-hardware-support/5622-adding-support-for-an-i...
-
- Signed-off-by: Jarod Wilson <jarod(a)redhat.com>
-
-commit d9193f3784352638b355c9a24c16f1a2e14b0548
-Author: Jarod Wilson <jarod(a)redhat.com>
-Date: Thu Apr 21 14:21:47 2011 -0400
-
- [media] nuvoton-cir: minor tweaks to rc dev init
-
- - Set a default timeout (matching mceusb.c) and use
- ir_raw_event_store_with_filter, which leads to better behavior when
- using lirc userspace decoding with this hardware
- - Fill in rx_resolution with the value we're using here (50us)
-
- Signed-off-by: Jarod Wilson <jarod(a)redhat.com>
-
-commit 02210203eb4df7fdf1156b24fcf2b7e2a20bf29c
-Author: Jarod Wilson <jarod(a)redhat.com>
-Date: Tue Apr 19 15:47:34 2011 -0400
-
- [media] mceusb: Formosa e017 device has no tx
-
- Per hardware provided to me, the Formosa Industrial Computing eHome
- Infrared Receiver, 0x147a:0xe017, has no tx capability, it is rx only.
-
- Thanks go to Paul Rae for the hardware.
-
- Signed-off-by: Jarod Wilson <jarod(a)redhat.com>
-
-commit 5919687ea8e0d3ee093b6edc4e24e30c1a8a60dc
-Author: Jarod Wilson <jarod(a)redhat.com>
-Date: Tue Apr 19 14:31:40 2011 -0400
-
- hid: flesh out support for tivo slide remote
-
- This patch finishes off adding full support for the TiVo Slide remote,
- which is a mostly pure HID device from the perspective of the kernel.
- There are a few mappings that use a vendor-specific usage page, and a
- few keys in the consumer usage page that I think make sense to remap
- slightly, to better fit their key labels' intended use. Doing this in a
- stand-alone hid-tivo.c makes the modifications only matter for this
- specific device.
-
- What's actually connected to the computer is a Broadcom-made usb dongle,
- which has an embedded hub, bluetooth adapter, mouse and keyboard
- devices. You pair with the dongle, then the remote sends data that its
- converted into HID on the keyboard interface (the mouse interface
- doesn't do anything interesting, so far as I can tell).
-
- lsusb for this device:
- Bus 004 Device 005: ID 0a5c:2190 Broadcom Corp.
- Bus 004 Device 004: ID 0a5c:4503 Broadcom Corp.
- Bus 004 Device 003: ID 150a:1201
- Bus 004 Device 002: ID 0a5c:4500 Broadcom Corp. BCM2046B1 USB 2.0 Hub (part of
BCM2046 Bluetooth)
-
- Speaking of the keyboard interface, the remote actually does contain a
- keyboard as well. The top slides away, revealing a reasonably functional
- qwerty keyboard (not unlike many slide cell phones), thus the product
- name.
-
- Applies cleanly to hid master, tested w/a 2.6.38.3-based Fedora kernel
- and a 2.6.32-based Red Hat Enterprise Linux 6 kernel.
-
- CC: Jiri Kosina <jkosina(a)suse.cz>
- Signed-off-by: Jarod Wilson <jarod(a)redhat.com>
-
-commit f5d27c83d8b1d1db7d727d4d33ae3df1357c0f03
-Author: Jarod Wilson <jarod(a)redhat.com>
-Date: Thu Mar 24 17:08:00 2011 -0400
-
- rc: add an Apple remote keymap
-
- Signed-off-by: Jarod Wilson <jarod(a)redhat.com>
-
-commit 9942d577525ebac939c155aaeb18e97e1282c923
-Author: Jarod Wilson <jarod(a)redhat.com>
-Date: Tue Apr 12 12:38:27 2011 -0400
-
- [media] rc/nuvoton-cir: enable CIR on w83667hg chip variant
-
- Thanks to some excellent investigative work by Douglas Clowes, it was
- uncovered that the older w83667hg Nuvoton chip functions with this
- driver after actually enabling the CIR function via its multi-function
- chip config register. The CIR and CIR wide-band sensor enable bits are
- just in a different place on this hardware, so we only poke register
- 0x27 on 677 hardware now, and we poke register 0x2c on the 667 now.
-
- Reported-by: Douglas Clowes <dclowes1(a)optusnet.com.au>
- Signed-off-by: Jarod Wilson <jarod(a)redhat.com>
-
-commit 92e839f5added53445aa2c447d69ea1c399e3113
-Author: Jarod Wilson <jarod(a)redhat.com>
-Date: Tue Apr 12 13:00:07 2011 -0400
-
- [media] rc/nuvoton-cir: only warn about unknown chips
-
- There are additional chip IDs that report a PNP ID of NTN0530, which we
- were refusing to load on. Instead, lets just warn if we encounter an
- unknown chip, as there's a chance it will work just fine.
-
- Also, expand the list of known hardware to include both an earlier and a
- later generation chip that this driver should function with. Douglas has
- an older w83667hg variant, that with a touch more work, will be
- supported by this driver, and Lutz has a newer w83677hg variant that
- works without any further modifications to the driver.
-
- Reported-by: Douglas Clowes <dclowes1(a)optusnet.com.au>
- Reported-by: Lutz Sammer <johns98(a)gmx.net>
- Signed-off-by: Jarod Wilson <jarod(a)redhat.com>
-
-commit 8cc98ca72fe0a5c0a5299057edf24690c6940098
-Author: Jarod Wilson <jarod(a)redhat.com>
-Date: Tue Apr 5 17:42:30 2011 -0400
-
- [media] rc: further key name standardization
-
- Use the newly introduced KEY_IMAGES where appropriate, and standardize
- on KEY_MEDIA for media center/application launcher button (such as the
- Windows logo key on the Windows Media Center Ed. remotes).
-
- Signed-off-by: Jarod Wilson <jarod(a)redhat.com>
-
-commit 29d1ac85998862cc4cb7629461358e932363c358
-Author: Jarod Wilson <jarod(a)redhat.com>
-Date: Thu Mar 24 15:43:45 2011 -0400
-
- lirc_sasem: key debug spew off debug modparam
-
- Signed-off-by: Jarod Wilson <jarod(a)redhat.com>
-
-commit 9965e8d8e0035e56e11e1ad6c359877e51749b34
-Author: Jarod Wilson <jarod(a)redhat.com>
-Date: Thu Mar 24 11:56:16 2011 -0400
-
- ttusb-budget: driver has a debug param, use it
-
- Remove DEBUG define, key debug spew off of the module's debug param that
- already exists.
-
- Signed-off-by: Jarod Wilson <jarod(a)redhat.com>
-
-commit 10fabf1f9cf8c1d1b579ab549bf4429ad13e0219
-Author: Jarod Wilson <jarod(a)redhat.com>
-Date: Thu Mar 24 11:54:41 2011 -0400
-
- drx397xD: remove unused DEBUG define
-
- Signed-off-by: Jarod Wilson <jarod(a)redhat.com>
-
-commit aa17ba00097df21cd0392e8aea41e93460e25007
-Author: Jarod Wilson <jarod(a)redhat.com>
-Date: Thu Mar 24 11:59:10 2011 -0400
-
- mceusb: tivo transceiver should default to tivo keymap
-
- Signed-off-by: Jarod Wilson <jarod(a)redhat.com>
-
-commit 02a5f7ed83b1da82f78b759a293cd15170afe611
-Author: Jarod Wilson <jarod(a)redhat.com>
-Date: Thu Mar 24 11:58:48 2011 -0400
-
- rc: add tivo/nero liquidtv keymap
-
- Signed-off-by: Jarod Wilson <jarod(a)redhat.com>
-
-commit db27bf543d740530ca0c1ab9fa7f3386f998e87c
-Author: Jarod Wilson <jarod(a)redhat.com>
-Date: Mon Apr 11 17:33:28 2011 -0400
-
- hid: assorted usage updates from hut 1.12
-
- I've got a Tivo Slide bluetooth remote/dongle, which uses a fair number
- of hid usages that aren't currently mapped in hid-input.c. I'd initially
- written additions to hid-input.c with just this device in mind,
- including some bits that were specific to the device. This go around,
- I'm looking at adding/correcting as many generic HID usages from the HID
- Usage Tables, version 1.12, as I can -- which also serves to enable all
- but four of the buttons on the Tivo Slide remote[*].
-
- Outside of fixing the obviously incorrect mapping of 0xc 0x45 from
- KEY_RADIO to KEY_RIGHT, and making use of the new KEY_IMAGES (just added
- in 2.6.39-rc4) for AL Image Browser instead of KEY_MEDIA, these are
- purely additions, and thus should have no negative impact on any already
- functional HID devices. Most of the added mappings seemed to be
- perfectly logical to me, but there were a few that were mapped on more
- of an "I think this makes the most sense" basis.
-
- [*] I'll handle the last four tivo buttons via an hid-tivo.c follow-up.
-
- CC: Dmitry Torokhov <dmitry.torokhov(a)gmail.com>
- CC: Jiri Kosina <jkosina(a)suse.cz>
- Signed-off-by: Jarod Wilson <jarod(a)redhat.com>
-
-commit 967bc222e57b94cf12cb4ad55383dec885f1755c
-Author: Jarod Wilson <jarod(a)redhat.com>
-Date: Wed Apr 6 09:54:01 2011 -0400
-
- input: add KEY_IMAGES specifically for AL Image Browser
-
- Many media center remotes have buttons intended for jumping straight to
- one type of media browser or another -- commonly, images/photos/pictures,
- audio/music, television, and movies. At present, remotes with an images
- or photos or pictures button use any number of different keycodes which
- sort of maybe fit. I've seen at least KEY_MEDIA, KEY_CAMERA,
- KEY_GRAPHICSEDITOR and KEY_PRESENTATION. None of those seem quite right.
- In my mind, KEY_MEDIA should be something more like a media center
- application launcher (and I'd like to standardize on that for things
- like the windows media center button on the mce remotes). KEY_CAMERA is
- used in a lot of webcams, and typically means "take a picture now".
- KEY_GRAPHICSEDITOR implies an editor, not a browser. KEY_PRESENTATION
- might be the closest fit here, if you think "photo slide show", but it
- may well be more intended for "run application in full-screen
- presentation mode" or to launch something like magicpoint, I dunno.
- And thus, I'd like to have a KEY_IMAGES, which matches the HID Usage AL
- Image Browser, the meaning of which I think is crystal-clear. I believe
- AL Audio Browser is already covered by KEY_AUDIO, and AL Movie Browser
- by KEY_VIDEO, so I'm also adding appropriate comments next to those
- keys.
-
- Signed-off-by: Jarod Wilson <jarod(a)redhat.com>
-
----
- drivers/hid/Kconfig | 6 +
- drivers/hid/Makefile | 1 +
- drivers/hid/hid-ids.h | 3 +
- drivers/hid/hid-input.c | 60 ++++++++++--
- drivers/hid/hid-tivo.c | 89 ++++++++++++++++++
- drivers/media/dvb/dvb-usb/dibusb-common.c | 2 +-
- drivers/media/dvb/dvb-usb/m920x.c | 16 ++--
- drivers/media/dvb/dvb-usb/nova-t-usb2.c | 2 +-
- drivers/media/dvb/frontends/drx397xD.c | 1 -
- drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c | 60 ++++++-------
- drivers/media/rc/keymaps/Makefile | 2 +
- drivers/media/rc/keymaps/rc-apple.c | 55 +++++++++++
- drivers/media/rc/keymaps/rc-avermedia-cardbus.c | 2 +-
- drivers/media/rc/keymaps/rc-imon-mce.c | 2 +-
- drivers/media/rc/keymaps/rc-imon-pad.c | 6 +-
- .../media/rc/keymaps/rc-kworld-plus-tv-analog.c | 2 +-
- drivers/media/rc/keymaps/rc-rc6-mce.c | 4 +-
- drivers/media/rc/keymaps/rc-tivo.c | 98 ++++++++++++++++++++
- drivers/media/rc/mceusb.c | 16 +++-
- drivers/media/rc/nuvoton-cir.c | 62 ++++++++++---
- drivers/media/rc/nuvoton-cir.h | 17 +++-
- drivers/staging/lirc/lirc_sasem.c | 13 ++-
- include/linux/input.h | 5 +-
- include/media/rc-map.h | 2 +
- 24 files changed, 439 insertions(+), 87 deletions(-)
-
-diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig
-index 2560f01..30a8cfd 100644
---- a/drivers/hid/Kconfig
-+++ b/drivers/hid/Kconfig
-@@ -492,6 +492,12 @@ config SMARTJOYPLUS_FF
- Say Y here if you have a SmartJoy PLUS PS2/USB adapter and want to
- enable force feedback support for it.
-
-+config HID_TIVO_SLIDE
-+ tristate "TiVo Slide Bluetooth remote control support"
-+ depends on USB_HID
-+ ---help---
-+ Say Y if you have a TiVo Slide Bluetooth remote control.
-+
- config HID_TOPSEED
- tristate "TopSeed Cyberlink, BTC Emprex, Conceptronic remote control
support"
- depends on USB_HID
-diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile
-index 6efc2a0..7c1efa3 100644
---- a/drivers/hid/Makefile
-+++ b/drivers/hid/Makefile
-@@ -66,6 +66,7 @@ obj-$(CONFIG_HID_STANTUM) += hid-stantum.o
- obj-$(CONFIG_HID_SUNPLUS) += hid-sunplus.o
- obj-$(CONFIG_HID_GREENASIA) += hid-gaff.o
- obj-$(CONFIG_HID_THRUSTMASTER) += hid-tmff.o
-+obj-$(CONFIG_HID_TIVO) += hid-tivo.o
- obj-$(CONFIG_HID_TOPSEED) += hid-topseed.o
- obj-$(CONFIG_HID_TWINHAN) += hid-twinhan.o
- obj-$(CONFIG_HID_UCLOGIC) += hid-uclogic.o
-diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
-index 92a0d61..8ece9eb 100644
---- a/drivers/hid/hid-ids.h
-+++ b/drivers/hid/hid-ids.h
-@@ -533,6 +533,9 @@
-
- #define USB_VENDOR_ID_THRUSTMASTER 0x044f
-
-+#define USB_VENDOR_ID_TIVO 0x150a
-+#define USB_DEVICE_ID_TIVO_SLIDE 0x1201
-+
- #define USB_VENDOR_ID_TOPSEED 0x0766
- #define USB_DEVICE_ID_TOPSEED_CYBERLINK 0x0204
-
-diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c
-index 7f552bf..88d4703 100644
---- a/drivers/hid/hid-input.c
-+++ b/drivers/hid/hid-input.c
-@@ -44,11 +44,11 @@ static const unsigned char hid_keyboard[256] = {
- 72, 73, 82, 83, 86,127,116,117,183,184,185,186,187,188,189,190,
- 191,192,193,194,134,138,130,132,128,129,131,137,133,135,136,113,
- 115,114,unk,unk,unk,121,unk, 89, 93,124, 92, 94, 95,unk,unk,unk,
-- 122,123, 90, 91, 85,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,
-+ 122,123, 90, 91, 85,unk,unk,unk,unk,unk,unk,unk,111,unk,unk,unk,
- unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,
- unk,unk,unk,unk,unk,unk,179,180,unk,unk,unk,unk,unk,unk,unk,unk,
- unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,
-- unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,
-+ unk,unk,unk,unk,unk,unk,unk,unk,111,unk,unk,unk,unk,unk,unk,unk,
- 29, 42, 56,125, 97, 54,100,126,164,166,165,163,161,115,114,113,
- 150,158,159,128,136,177,178,176,142,152,173,140,unk,unk,unk,unk
- };
-@@ -365,6 +365,18 @@ static void hidinput_configure_usage(struct hid_input *hidinput,
struct hid_fiel
- case 0x1: map_key_clear(KEY_POWER); break;
- case 0x2: map_key_clear(KEY_SLEEP); break;
- case 0x3: map_key_clear(KEY_WAKEUP); break;
-+ case 0x4: map_key_clear(KEY_CONTEXT_MENU); break;
-+ case 0x5: map_key_clear(KEY_MENU); break;
-+ case 0x6: map_key_clear(KEY_PROG1); break;
-+ case 0x7: map_key_clear(KEY_HELP); break;
-+ case 0x8: map_key_clear(KEY_EXIT); break;
-+ case 0x9: map_key_clear(KEY_SELECT); break;
-+ case 0xa: map_key_clear(KEY_RIGHT); break;
-+ case 0xb: map_key_clear(KEY_LEFT); break;
-+ case 0xc: map_key_clear(KEY_UP); break;
-+ case 0xd: map_key_clear(KEY_DOWN); break;
-+ case 0xe: map_key_clear(KEY_POWER2); break;
-+ case 0xf: map_key_clear(KEY_RESTART); break;
- default: goto unknown;
- }
- break;
-@@ -474,16 +486,39 @@ static void hidinput_configure_usage(struct hid_input *hidinput,
struct hid_fiel
- }
- break;
-
-- case HID_UP_CONSUMER: /* USB HUT v1.1, pages 56-62 */
-+ case HID_UP_CONSUMER: /* USB HUT v1.12, pages 75-84 */
- switch (usage->hid & HID_USAGE) {
- case 0x000: goto ignore;
-+ case 0x030: map_key_clear(KEY_POWER); break;
-+ case 0x031: map_key_clear(KEY_RESTART); break;
-+ case 0x032: map_key_clear(KEY_SLEEP); break;
- case 0x034: map_key_clear(KEY_SLEEP); break;
-+ case 0x035: map_key_clear(KEY_KBDILLUMTOGGLE); break;
- case 0x036: map_key_clear(BTN_MISC); break;
-
-- case 0x040: map_key_clear(KEY_MENU); break;
-- case 0x045: map_key_clear(KEY_RADIO); break;
--
-+ case 0x040: map_key_clear(KEY_MENU); break; /* Menu */
-+ case 0x041: map_key_clear(KEY_SELECT); break; /* Menu Pick */
-+ case 0x042: map_key_clear(KEY_UP); break; /* Menu Up */
-+ case 0x043: map_key_clear(KEY_DOWN); break; /* Menu Down */
-+ case 0x044: map_key_clear(KEY_LEFT); break; /* Menu Left */
-+ case 0x045: map_key_clear(KEY_RIGHT); break; /* Menu Right */
-+ case 0x046: map_key_clear(KEY_ESC); break; /* Menu Escape */
-+ case 0x047: map_key_clear(KEY_KPPLUS); break; /* Menu Value Increase */
-+ case 0x048: map_key_clear(KEY_KPMINUS); break; /* Menu Value Decrease */
-+
-+ case 0x060: map_key_clear(KEY_INFO); break; /* Data On Screen */
-+ case 0x061: map_key_clear(KEY_SUBTITLE); break; /* Closed Caption */
-+ case 0x063: map_key_clear(KEY_VCR); break; /* VCR/TV */
-+ case 0x065: map_key_clear(KEY_CAMERA); break; /* Snapshot */
-+ case 0x069: map_key_clear(KEY_RED); break;
-+ case 0x06a: map_key_clear(KEY_GREEN); break;
-+ case 0x06b: map_key_clear(KEY_BLUE); break;
-+ case 0x06c: map_key_clear(KEY_YELLOW); break;
-+ case 0x06d: map_key_clear(KEY_ZOOM); break;
-+
-+ case 0x082: map_key_clear(KEY_VIDEO_NEXT); break;
- case 0x083: map_key_clear(KEY_LAST); break;
-+ case 0x084: map_key_clear(KEY_ENTER); break;
- case 0x088: map_key_clear(KEY_PC); break;
- case 0x089: map_key_clear(KEY_TV); break;
- case 0x08a: map_key_clear(KEY_WWW); break;
-@@ -517,6 +552,8 @@ static void hidinput_configure_usage(struct hid_input *hidinput,
struct hid_fiel
- case 0x0b7: map_key_clear(KEY_STOPCD); break;
- case 0x0b8: map_key_clear(KEY_EJECTCD); break;
- case 0x0bc: map_key_clear(KEY_MEDIA_REPEAT); break;
-+ case 0x0b9: map_key_clear(KEY_SHUFFLE); break;
-+ case 0x0bf: map_key_clear(KEY_SLOW); break;
-
- case 0x0cd: map_key_clear(KEY_PLAYPAUSE); break;
- case 0x0e0: map_abs_clear(ABS_VOLUME); break;
-@@ -524,6 +561,7 @@ static void hidinput_configure_usage(struct hid_input *hidinput,
struct hid_fiel
- case 0x0e5: map_key_clear(KEY_BASSBOOST); break;
- case 0x0e9: map_key_clear(KEY_VOLUMEUP); break;
- case 0x0ea: map_key_clear(KEY_VOLUMEDOWN); break;
-+ case 0x0f5: map_key_clear(KEY_SLOW); break;
-
- case 0x182: map_key_clear(KEY_BOOKMARKS); break;
- case 0x183: map_key_clear(KEY_CONFIG); break;
-@@ -540,6 +578,7 @@ static void hidinput_configure_usage(struct hid_input *hidinput,
struct hid_fiel
- case 0x18e: map_key_clear(KEY_CALENDAR); break;
- case 0x191: map_key_clear(KEY_FINANCE); break;
- case 0x192: map_key_clear(KEY_CALC); break;
-+ case 0x193: map_key_clear(KEY_PLAYER); break;
- case 0x194: map_key_clear(KEY_FILE); break;
- case 0x196: map_key_clear(KEY_WWW); break;
- case 0x199: map_key_clear(KEY_CHAT); break;
-@@ -548,8 +587,10 @@ static void hidinput_configure_usage(struct hid_input *hidinput,
struct hid_fiel
- case 0x1a6: map_key_clear(KEY_HELP); break;
- case 0x1a7: map_key_clear(KEY_DOCUMENTS); break;
- case 0x1ab: map_key_clear(KEY_SPELLCHECK); break;
-- case 0x1b6: map_key_clear(KEY_MEDIA); break;
-- case 0x1b7: map_key_clear(KEY_SOUND); break;
-+ case 0x1ae: map_key_clear(KEY_KEYBOARD); break;
-+ case 0x1b6: map_key_clear(KEY_IMAGES); break;
-+ case 0x1b7: map_key_clear(KEY_AUDIO); break;
-+ case 0x1b8: map_key_clear(KEY_VIDEO); break;
- case 0x1bc: map_key_clear(KEY_MESSENGER); break;
- case 0x1bd: map_key_clear(KEY_INFO); break;
- case 0x201: map_key_clear(KEY_NEW); break;
-@@ -578,7 +619,10 @@ static void hidinput_configure_usage(struct hid_input *hidinput,
struct hid_fiel
- case 0x233: map_key_clear(KEY_SCROLLUP); break;
- case 0x234: map_key_clear(KEY_SCROLLDOWN); break;
- case 0x238: map_rel(REL_HWHEEL); break;
-+ case 0x23d: map_key_clear(KEY_EDIT); break;
- case 0x25f: map_key_clear(KEY_CANCEL); break;
-+ case 0x269: map_key_clear(KEY_INSERT); break;
-+ case 0x26a: map_key_clear(KEY_DELETE); break;
- case 0x279: map_key_clear(KEY_REDO); break;
-
- case 0x289: map_key_clear(KEY_REPLY); break;
-diff --git a/drivers/hid/hid-tivo.c b/drivers/hid/hid-tivo.c
-new file mode 100644
-index 0000000..3d43c06
---- /dev/null
-+++ b/drivers/hid/hid-tivo.c
-@@ -0,0 +1,89 @@
-+/*
-+ * HID driver for TiVo Slide Bluetooth remote
-+ *
-+ * Copyright (c) 2011 Jarod Wilson <jarod(a)redhat.com>
-+ * based on the hid-topseed driver, which is in turn, based on hid-cherry...
-+ */
-+
-+/*
-+ * 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/device.h>
-+#include <linux/hid.h>
-+#include <linux/module.h>
-+
-+#include "hid-ids.h"
-+
-+#define HID_UP_TIVOVENDOR 0xffff0000
-+#define tivo_map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, \
-+ EV_KEY, (c))
-+
-+static int tivo_input_mapping(struct hid_device *hdev, struct hid_input *hi,
-+ struct hid_field *field, struct hid_usage *usage,
-+ unsigned long **bit, int *max)
-+{
-+ switch (usage->hid & HID_USAGE_PAGE) {
-+ case HID_UP_TIVOVENDOR:
-+ switch (usage->hid & HID_USAGE) {
-+ /* TiVo button */
-+ case 0x3d: tivo_map_key_clear(KEY_MEDIA); break;
-+ /* Live TV */
-+ case 0x3e: tivo_map_key_clear(KEY_TV); break;
-+ /* Red thumbs down */
-+ case 0x41: tivo_map_key_clear(KEY_KPMINUS); break;
-+ /* Green thumbs up */
-+ case 0x42: tivo_map_key_clear(KEY_KPPLUS); break;
-+ default:
-+ return 0;
-+ }
-+ break;
-+ case HID_UP_CONSUMER:
-+ switch (usage->hid & HID_USAGE) {
-+ /* Enter/Last (default mapping: KEY_LAST) */
-+ case 0x083: tivo_map_key_clear(KEY_ENTER); break;
-+ /* Info (default mapping: KEY_PROPS) */
-+ case 0x209: tivo_map_key_clear(KEY_INFO); break;
-+ default:
-+ return 0;
-+ }
-+ break;
-+ default:
-+ return 0;
-+ }
-+
-+ /* This means we found a matching mapping here, else, look in the
-+ * standard hid mappings in hid-input.c */
-+ return 1;
-+}
-+
-+static const struct hid_device_id tivo_devices[] = {
-+ /* TiVo Slide Bluetooth remote, pairs with a Broadcom dongle */
-+ { HID_USB_DEVICE(USB_VENDOR_ID_TIVO, USB_DEVICE_ID_TIVO_SLIDE) },
-+ { }
-+};
-+MODULE_DEVICE_TABLE(hid, tivo_devices);
-+
-+static struct hid_driver tivo_driver = {
-+ .name = "tivo_slide",
-+ .id_table = tivo_devices,
-+ .input_mapping = tivo_input_mapping,
-+};
-+
-+static int __init tivo_init(void)
-+{
-+ return hid_register_driver(&tivo_driver);
-+}
-+
-+static void __exit tivo_exit(void)
-+{
-+ hid_unregister_driver(&tivo_driver);
-+}
-+
-+module_init(tivo_init);
-+module_exit(tivo_exit);
-+MODULE_LICENSE("GPL");
-+MODULE_AUTHOR("Jarod Wilson <jarod(a)redhat.com>");
-diff --git a/drivers/media/dvb/dvb-usb/dibusb-common.c
b/drivers/media/dvb/dvb-usb/dibusb-common.c
-index 956f7ae..4c2a689 100644
---- a/drivers/media/dvb/dvb-usb/dibusb-common.c
-+++ b/drivers/media/dvb/dvb-usb/dibusb-common.c
-@@ -408,7 +408,7 @@ struct rc_map_table rc_map_dibusb_table[] = {
-
- { 0x8008, KEY_DVD },
- { 0x8009, KEY_AUDIO },
-- { 0x800a, KEY_MEDIA }, /* Pictures */
-+ { 0x800a, KEY_IMAGES }, /* Pictures */
- { 0x800b, KEY_VIDEO },
-
- { 0x800c, KEY_BACK },
-diff --git a/drivers/media/dvb/dvb-usb/m920x.c b/drivers/media/dvb/dvb-usb/m920x.c
-index da9dc91..51bfd42 100644
---- a/drivers/media/dvb/dvb-usb/m920x.c
-+++ b/drivers/media/dvb/dvb-usb/m920x.c
-@@ -632,9 +632,9 @@ static struct rc_map_table rc_map_pinnacle310e_table[] = {
- { 0x16, KEY_POWER },
- { 0x17, KEY_FAVORITES },
- { 0x0f, KEY_TEXT },
-- { 0x48, KEY_MEDIA }, /* preview */
-+ { 0x48, KEY_PROGRAM }, /* preview */
- { 0x1c, KEY_EPG },
-- { 0x04, KEY_LIST }, /* record list */
-+ { 0x04, KEY_LIST }, /* record list */
- { 0x03, KEY_1 },
- { 0x01, KEY_2 },
- { 0x06, KEY_3 },
-@@ -674,14 +674,14 @@ static struct rc_map_table rc_map_pinnacle310e_table[] = {
- { 0x0e, KEY_MUTE },
- /* { 0x49, KEY_LR }, */ /* L/R */
- { 0x07, KEY_SLEEP }, /* Hibernate */
-- { 0x08, KEY_MEDIA }, /* A/V */
-- { 0x0e, KEY_MENU }, /* Recall */
-+ { 0x08, KEY_VIDEO }, /* A/V */
-+ { 0x0e, KEY_MENU }, /* Recall */
- { 0x45, KEY_ZOOMIN },
- { 0x46, KEY_ZOOMOUT },
-- { 0x18, KEY_TV }, /* Red */
-- { 0x53, KEY_VCR }, /* Green */
-- { 0x5e, KEY_SAT }, /* Yellow */
-- { 0x5f, KEY_PLAYER }, /* Blue */
-+ { 0x18, KEY_RED }, /* Red */
-+ { 0x53, KEY_GREEN }, /* Green */
-+ { 0x5e, KEY_YELLOW }, /* Yellow */
-+ { 0x5f, KEY_BLUE }, /* Blue */
- };
-
- /* DVB USB Driver stuff */
-diff --git a/drivers/media/dvb/dvb-usb/nova-t-usb2.c
b/drivers/media/dvb/dvb-usb/nova-t-usb2.c
-index 9d3cd2d..bc350e9 100644
---- a/drivers/media/dvb/dvb-usb/nova-t-usb2.c
-+++ b/drivers/media/dvb/dvb-usb/nova-t-usb2.c
-@@ -47,7 +47,7 @@ static struct rc_map_table rc_map_haupp_table[] = {
- { 0x1e17, KEY_RIGHT },
- { 0x1e18, KEY_VIDEO },
- { 0x1e19, KEY_AUDIO },
-- { 0x1e1a, KEY_MEDIA },
-+ { 0x1e1a, KEY_IMAGES },
- { 0x1e1b, KEY_EPG },
- { 0x1e1c, KEY_TV },
- { 0x1e1e, KEY_NEXT },
-diff --git a/drivers/media/dvb/frontends/drx397xD.c
b/drivers/media/dvb/frontends/drx397xD.c
-index a05007c..235ac72 100644
---- a/drivers/media/dvb/frontends/drx397xD.c
-+++ b/drivers/media/dvb/frontends/drx397xD.c
-@@ -17,7 +17,6 @@
- * along with this program; If not, see <
http://www.gnu.org/licenses/>.
- */
-
--#define DEBUG /* uncomment if you want debugging output */
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/moduleparam.h>
-diff --git a/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c
b/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c
-index cbe2f0d..420bb42 100644
---- a/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c
-+++ b/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c
-@@ -52,7 +52,7 @@
- my TTUSB, so let it undef'd unless you want to implement another
- frontend. never tested.
-
-- DEBUG:
-+ debug:
- define it to > 3 for really hardcore debugging. you probably don't want
- this unless the device doesn't load at all. > 2 for bandwidth statistics.
- */
-@@ -134,20 +134,19 @@ struct ttusb {
- /* ugly workaround ... don't know why it's necessary to read */
- /* all result codes. */
-
--#define DEBUG 0
- static int ttusb_cmd(struct ttusb *ttusb,
- const u8 * data, int len, int needresult)
- {
- int actual_len;
- int err;
--#if DEBUG >= 3
- int i;
-
-- printk(">");
-- for (i = 0; i < len; ++i)
-- printk(" %02x", data[i]);
-- printk("\n");
--#endif
-+ if (debug >= 3) {
-+ printk(KERN_DEBUG ">");
-+ for (i = 0; i < len; ++i)
-+ printk(KERN_CONT " %02x", data[i]);
-+ printk(KERN_CONT "\n");
-+ }
-
- if (mutex_lock_interruptible(&ttusb->semusb) < 0)
- return -EAGAIN;
-@@ -176,13 +175,15 @@ static int ttusb_cmd(struct ttusb *ttusb,
- mutex_unlock(&ttusb->semusb);
- return err;
- }
--#if DEBUG >= 3
-- actual_len = ttusb->last_result[3] + 4;
-- printk("<");
-- for (i = 0; i < actual_len; ++i)
-- printk(" %02x", ttusb->last_result[i]);
-- printk("\n");
--#endif
-+
-+ if (debug >= 3) {
-+ actual_len = ttusb->last_result[3] + 4;
-+ printk(KERN_DEBUG "<");
-+ for (i = 0; i < actual_len; ++i)
-+ printk(KERN_CONT " %02x", ttusb->last_result[i]);
-+ printk(KERN_CONT "\n");
-+ }
-+
- if (!needresult)
- mutex_unlock(&ttusb->semusb);
- return 0;
-@@ -636,16 +637,13 @@ static void ttusb_process_frame(struct ttusb *ttusb, u8 * data, int
len)
- ++ttusb->mux_state;
- else {
- ttusb->mux_state = 0;
--#if DEBUG > 3
-- if (ttusb->insync)
-- printk("%02x ", data[-1]);
--#else
- if (ttusb->insync) {
-- printk("%s: lost sync.\n",
-+ dprintk("%s: %02x\n",
-+ __func__, data[-1]);
-+ printk(KERN_INFO "%s: lost sync.\n",
- __func__);
- ttusb->insync = 0;
- }
--#endif
- }
- break;
- case 3:
-@@ -744,6 +742,9 @@ static void ttusb_process_frame(struct ttusb *ttusb, u8 * data, int
len)
- static void ttusb_iso_irq(struct urb *urb)
- {
- struct ttusb *ttusb = urb->context;
-+ struct usb_iso_packet_descriptor *d;
-+ u8 *data;
-+ int len, i;
-
- if (!ttusb->iso_streaming)
- return;
-@@ -755,21 +756,14 @@ static void ttusb_iso_irq(struct urb *urb)
- #endif
-
- if (!urb->status) {
-- int i;
- for (i = 0; i < urb->number_of_packets; ++i) {
-- struct usb_iso_packet_descriptor *d;
-- u8 *data;
-- int len;
- numpkt++;
- if (time_after_eq(jiffies, lastj + HZ)) {
--#if DEBUG > 2
-- printk
-- ("frames/s: %d (ts: %d, stuff %d, sec: %d, invalid: %d, all: %d)\n",
-- numpkt * HZ / (jiffies - lastj),
-- numts, numstuff, numsec, numinvalid,
-- numts + numstuff + numsec +
-- numinvalid);
--#endif
-+ dprintk("frames/s: %lu (ts: %d, stuff %d, "
-+ "sec: %d, invalid: %d, all: %d)\n",
-+ numpkt * HZ / (jiffies - lastj),
-+ numts, numstuff, numsec, numinvalid,
-+ numts + numstuff + numsec + numinvalid);
- numts = numstuff = numsec = numinvalid = 0;
- lastj = jiffies;
- numpkt = 0;
-diff --git a/drivers/media/rc/keymaps/Makefile b/drivers/media/rc/keymaps/Makefile
-index 85cac7d..8c0cb70 100644
---- a/drivers/media/rc/keymaps/Makefile
-+++ b/drivers/media/rc/keymaps/Makefile
-@@ -2,6 +2,7 @@ obj-$(CONFIG_RC_MAP) += rc-adstech-dvb-t-pci.o \
- rc-alink-dtu-m.o \
- rc-anysee.o \
- rc-apac-viewcomp.o \
-+ rc-apple.o \
- rc-asus-pc39.o \
- rc-ati-tv-wonder-hd-600.o \
- rc-avermedia-a16d.o \
-@@ -77,6 +78,7 @@ obj-$(CONFIG_RC_MAP) += rc-adstech-dvb-t-pci.o \
- rc-terratec-cinergy-xs.o \
- rc-terratec-slim.o \
- rc-tevii-nec.o \
-+ rc-tivo.o \
- rc-total-media-in-hand.o \
- rc-trekstor.o \
- rc-tt-1500.o \
-diff --git a/drivers/media/rc/keymaps/rc-apple.c b/drivers/media/rc/keymaps/rc-apple.c
-new file mode 100644
-index 0000000..9fff474
---- /dev/null
-+++ b/drivers/media/rc/keymaps/rc-apple.c
-@@ -0,0 +1,55 @@
-+/* rc-apple.c - Keytable for Apple remotes
-+ *
-+ * Copyright (c) 2011 by Jarod Wilson <jarod(a)redhat.com>
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ */
-+
-+#include <media/rc-map.h>
-+
-+/*
-+ * The Apple remotes use an NEC-ish protocol, but instead of having a
-+ * command/not_command pair, they use a vendor ID of 0x77e1. Another byte
-+ * is used for a pairing ID (0-255), to make it possible to have a system
-+ * listen for only its specific remote. The last byte is the actual command
-+ * byte. This table will only Just Work(tm) with remotes that have their
-+ * pairing byte set to 0xc7 at the moment (one of my Apple remotes), but
-+ * it can be trivially replaced from userspace with one using a different
-+ * pairing byte value.
-+ */
-+static struct rc_map_table apple[] = {
-+ { 0x77e150c7, KEY_VOLUMEUP },
-+ { 0x77e130c7, KEY_VOLUMEDOWN },
-+ { 0x77e190c7, KEY_REWIND },
-+ { 0x77e160c7, KEY_FASTFORWARD },
-+ { 0x77e1a0c7, KEY_PLAYPAUSE },
-+ { 0x77e1c0c7, KEY_MENU },
-+};
-+
-+static struct rc_map_list apple_map = {
-+ .map = {
-+ .scan = apple,
-+ .size = ARRAY_SIZE(apple),
-+ .rc_type = RC_TYPE_NEC,
-+ .name = RC_MAP_APPLE,
-+ }
-+};
-+
-+static int __init init_rc_map_apple(void)
-+{
-+ return rc_map_register(&apple_map);
-+}
-+
-+static void __exit exit_rc_map_apple(void)
-+{
-+ rc_map_unregister(&apple_map);
-+}
-+
-+module_init(init_rc_map_apple)
-+module_exit(exit_rc_map_apple)
-+
-+MODULE_LICENSE("GPL");
-+MODULE_AUTHOR("Jarod Wilson <jarod(a)redhat.com>");
-diff --git a/drivers/media/rc/keymaps/rc-avermedia-cardbus.c
b/drivers/media/rc/keymaps/rc-avermedia-cardbus.c
-index bdf97b7..22f54d4 100644
---- a/drivers/media/rc/keymaps/rc-avermedia-cardbus.c
-+++ b/drivers/media/rc/keymaps/rc-avermedia-cardbus.c
-@@ -52,7 +52,7 @@ static struct rc_map_table avermedia_cardbus[] = {
- { 0x28, KEY_SELECT }, /* Select */
- { 0x29, KEY_BLUE }, /* Blue/Picture */
- { 0x2a, KEY_BACKSPACE }, /* Back */
-- { 0x2b, KEY_MEDIA }, /* PIP (Picture-in-picture) */
-+ { 0x2b, KEY_VIDEO }, /* PIP (Picture-in-picture) */
- { 0x2c, KEY_DOWN },
- { 0x2e, KEY_DOT },
- { 0x2f, KEY_TV }, /* Live TV */
-diff --git a/drivers/media/rc/keymaps/rc-imon-mce.c
b/drivers/media/rc/keymaps/rc-imon-mce.c
-index 937a819..0ea2aa1 100644
---- a/drivers/media/rc/keymaps/rc-imon-mce.c
-+++ b/drivers/media/rc/keymaps/rc-imon-mce.c
-@@ -111,7 +111,7 @@ static struct rc_map_table imon_mce[] = {
- { 0x800ff44d, KEY_TITLE },
-
- { 0x800ff40c, KEY_POWER },
-- { 0x800ff40d, KEY_LEFTMETA }, /* Windows MCE button */
-+ { 0x800ff40d, KEY_MEDIA }, /* Windows MCE button */
-
- };
-
-diff --git a/drivers/media/rc/keymaps/rc-imon-pad.c
b/drivers/media/rc/keymaps/rc-imon-pad.c
-index 63d42bd..75d3843 100644
---- a/drivers/media/rc/keymaps/rc-imon-pad.c
-+++ b/drivers/media/rc/keymaps/rc-imon-pad.c
-@@ -87,7 +87,7 @@ static struct rc_map_table imon_pad[] = {
-
- { 0x2b8515b7, KEY_VIDEO },
- { 0x299195b7, KEY_AUDIO },
-- { 0x2ba115b7, KEY_CAMERA },
-+ { 0x2ba115b7, KEY_IMAGES },
- { 0x28a515b7, KEY_TV },
- { 0x29a395b7, KEY_DVD },
- { 0x29a295b7, KEY_DVD },
-@@ -97,7 +97,7 @@ static struct rc_map_table imon_pad[] = {
- { 0x2ba395b7, KEY_MENU },
-
- { 0x288515b7, KEY_BOOKMARKS },
-- { 0x2ab715b7, KEY_MEDIA }, /* Thumbnail */
-+ { 0x2ab715b7, KEY_CAMERA }, /* Thumbnail */
- { 0x298595b7, KEY_SUBTITLE },
- { 0x2b8595b7, KEY_LANGUAGE },
-
-@@ -125,7 +125,7 @@ static struct rc_map_table imon_pad[] = {
- { 0x2b8195b7, KEY_CONTEXT_MENU }, /* Left Menu*/
- { 0x02000065, KEY_COMPOSE }, /* RightMenu */
- { 0x28b715b7, KEY_COMPOSE }, /* RightMenu */
-- { 0x2ab195b7, KEY_LEFTMETA }, /* Go or MultiMon */
-+ { 0x2ab195b7, KEY_MEDIA }, /* Go or MultiMon */
- { 0x29b715b7, KEY_DASHBOARD }, /* AppLauncher */
- };
-
-diff --git a/drivers/media/rc/keymaps/rc-kworld-plus-tv-analog.c
b/drivers/media/rc/keymaps/rc-kworld-plus-tv-analog.c
-index 08d1831..7fa17a3 100644
---- a/drivers/media/rc/keymaps/rc-kworld-plus-tv-analog.c
-+++ b/drivers/media/rc/keymaps/rc-kworld-plus-tv-analog.c
-@@ -17,7 +17,7 @@
- */
-
- static struct rc_map_table kworld_plus_tv_analog[] = {
-- { 0x0c, KEY_LEFTMETA }, /* Kworld key */
-+ { 0x0c, KEY_MEDIA }, /* Kworld key */
- { 0x16, KEY_CLOSECD }, /* -> ) */
- { 0x1d, KEY_POWER2 },
-
-diff --git a/drivers/media/rc/keymaps/rc-rc6-mce.c
b/drivers/media/rc/keymaps/rc-rc6-mce.c
-index 8dd519e..01b69bc 100644
---- a/drivers/media/rc/keymaps/rc-rc6-mce.c
-+++ b/drivers/media/rc/keymaps/rc-rc6-mce.c
-@@ -30,7 +30,7 @@ static struct rc_map_table rc6_mce[] = {
- { 0x800f040a, KEY_DELETE },
- { 0x800f040b, KEY_ENTER },
- { 0x800f040c, KEY_POWER }, /* PC Power */
-- { 0x800f040d, KEY_LEFTMETA }, /* Windows MCE button */
-+ { 0x800f040d, KEY_MEDIA }, /* Windows MCE button */
- { 0x800f040e, KEY_MUTE },
- { 0x800f040f, KEY_INFO },
-
-@@ -87,7 +87,7 @@ static struct rc_map_table rc6_mce[] = {
-
- { 0x800f0465, KEY_POWER2 }, /* TV Power */
- { 0x800f046e, KEY_PLAYPAUSE },
-- { 0x800f046f, KEY_MEDIA }, /* Start media application (NEW) */
-+ { 0x800f046f, KEY_PLAYER }, /* Start media application (NEW) */
-
- { 0x800f0480, KEY_BRIGHTNESSDOWN },
- { 0x800f0481, KEY_PLAYPAUSE },
-diff --git a/drivers/media/rc/keymaps/rc-tivo.c b/drivers/media/rc/keymaps/rc-tivo.c
-new file mode 100644
-index 0000000..98ad085
---- /dev/null
-+++ b/drivers/media/rc/keymaps/rc-tivo.c
-@@ -0,0 +1,98 @@
-+/* rc-tivo.c - Keytable for TiVo remotes
-+ *
-+ * Copyright (c) 2011 by Jarod Wilson <jarod(a)redhat.com>
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ */
-+
-+#include <media/rc-map.h>
-+
-+/*
-+ * Initial mapping is for the TiVo remote included in the Nero LiquidTV bundle,
-+ * which also ships with a TiVo-branded IR transceiver, supported by the mceusb
-+ * driver. Note that the remote uses an NEC-ish protocol, but instead of having
-+ * a command/not_command pair, it has a vendor ID of 0xa10c, but some keys, the
-+ * NEC extended checksums do pass, so the table presently has the intended
-+ * values and the checksum-passed versions for those keys.
-+ */
-+static struct rc_map_table tivo[] = {
-+ { 0xa10c900f, KEY_MEDIA }, /* TiVo Button */
-+ { 0xa10c0807, KEY_POWER2 }, /* TV Power */
-+ { 0xa10c8807, KEY_TV }, /* Live TV/Swap */
-+ { 0xa10c2c03, KEY_VIDEO_NEXT }, /* TV Input */
-+ { 0xa10cc807, KEY_INFO },
-+ { 0xa10cfa05, KEY_CYCLEWINDOWS }, /* Window */
-+ { 0x0085305f, KEY_CYCLEWINDOWS },
-+ { 0xa10c6c03, KEY_EPG }, /* Guide */
-+
-+ { 0xa10c2807, KEY_UP },
-+ { 0xa10c6807, KEY_DOWN },
-+ { 0xa10ce807, KEY_LEFT },
-+ { 0xa10ca807, KEY_RIGHT },
-+
-+ { 0xa10c1807, KEY_SCROLLDOWN }, /* Red Thumbs Down */
-+ { 0xa10c9807, KEY_SELECT },
-+ { 0xa10c5807, KEY_SCROLLUP }, /* Green Thumbs Up */
-+
-+ { 0xa10c3807, KEY_VOLUMEUP },
-+ { 0xa10cb807, KEY_VOLUMEDOWN },
-+ { 0xa10cd807, KEY_MUTE },
-+ { 0xa10c040b, KEY_RECORD },
-+ { 0xa10c7807, KEY_CHANNELUP },
-+ { 0xa10cf807, KEY_CHANNELDOWN },
-+ { 0x0085301f, KEY_CHANNELDOWN },
-+
-+ { 0xa10c840b, KEY_PLAY },
-+ { 0xa10cc40b, KEY_PAUSE },
-+ { 0xa10ca40b, KEY_SLOW },
-+ { 0xa10c440b, KEY_REWIND },
-+ { 0xa10c240b, KEY_FASTFORWARD },
-+ { 0xa10c640b, KEY_PREVIOUS },
-+ { 0xa10ce40b, KEY_NEXT }, /* ->| */
-+
-+ { 0xa10c220d, KEY_ZOOM }, /* Aspect */
-+ { 0xa10c120d, KEY_STOP },
-+ { 0xa10c520d, KEY_DVD }, /* DVD Menu */
-+
-+ { 0xa10c140b, KEY_NUMERIC_1 },
-+ { 0xa10c940b, KEY_NUMERIC_2 },
-+ { 0xa10c540b, KEY_NUMERIC_3 },
-+ { 0xa10cd40b, KEY_NUMERIC_4 },
-+ { 0xa10c340b, KEY_NUMERIC_5 },
-+ { 0xa10cb40b, KEY_NUMERIC_6 },
-+ { 0xa10c740b, KEY_NUMERIC_7 },
-+ { 0xa10cf40b, KEY_NUMERIC_8 },
-+ { 0x0085302f, KEY_NUMERIC_8 },
-+ { 0xa10c0c03, KEY_NUMERIC_9 },
-+ { 0xa10c8c03, KEY_NUMERIC_0 },
-+ { 0xa10ccc03, KEY_ENTER },
-+ { 0xa10c4c03, KEY_CLEAR },
-+};
-+
-+static struct rc_map_list tivo_map = {
-+ .map = {
-+ .scan = tivo,
-+ .size = ARRAY_SIZE(tivo),
-+ .rc_type = RC_TYPE_NEC,
-+ .name = RC_MAP_TIVO,
-+ }
-+};
-+
-+static int __init init_rc_map_tivo(void)
-+{
-+ return rc_map_register(&tivo_map);
-+}
-+
-+static void __exit exit_rc_map_tivo(void)
-+{
-+ rc_map_unregister(&tivo_map);
-+}
-+
-+module_init(init_rc_map_tivo)
-+module_exit(exit_rc_map_tivo)
-+
-+MODULE_LICENSE("GPL");
-+MODULE_AUTHOR("Jarod Wilson <jarod(a)redhat.com>");
-diff --git a/drivers/media/rc/mceusb.c b/drivers/media/rc/mceusb.c
-index 044fb7a..47a1c5d 100644
---- a/drivers/media/rc/mceusb.c
-+++ b/drivers/media/rc/mceusb.c
-@@ -149,6 +149,8 @@ enum mceusb_model_type {
- POLARIS_EVK,
- CX_HYBRID_TV,
- MULTIFUNCTION,
-+ TIVO_KIT,
-+ MCE_GEN2_NO_TX,
- };
-
- struct mceusb_model {
-@@ -172,6 +174,10 @@ static const struct mceusb_model mceusb_model[] = {
- [MCE_GEN2] = {
- .mce_gen2 = 1,
- },
-+ [MCE_GEN2_NO_TX] = {
-+ .mce_gen2 = 1,
-+ .no_tx = 1,
-+ },
- [MCE_GEN2_TX_INV] = {
- .mce_gen2 = 1,
- .tx_mask_normal = 1,
-@@ -197,6 +203,10 @@ static const struct mceusb_model mceusb_model[] = {
- .mce_gen2 = 1,
- .ir_intfnum = 2,
- },
-+ [TIVO_KIT] = {
-+ .mce_gen2 = 1,
-+ .rc_map = RC_MAP_TIVO,
-+ },
- };
-
- static struct usb_device_id mceusb_dev_table[] = {
-@@ -230,6 +230,8 @@ static struct usb_device_id mceusb_dev_table[] = {
- { USB_DEVICE(VENDOR_PHILIPS, 0x206c) },
- /* Philips/Spinel plus IR transceiver for ASUS */
- { USB_DEVICE(VENDOR_PHILIPS, 0x2088) },
-+ /* Philips IR transceiver (Dell branded) */
-+ { USB_DEVICE(VENDOR_PHILIPS, 0x2093) },
- /* Realtek MCE IR Receiver and card reader */
- { USB_DEVICE(VENDOR_REALTEK, 0x0161),
- .driver_info = MULTIFUNCTION },
-@@ -279,7 +289,8 @@ static struct usb_device_id mceusb_dev_table[] = {
- /* Formosa21 / eHome Infrared Receiver */
- { USB_DEVICE(VENDOR_FORMOSA, 0xe016) },
- /* Formosa aim / Trust MCE Infrared Receiver */
-- { USB_DEVICE(VENDOR_FORMOSA, 0xe017) },
-+ { USB_DEVICE(VENDOR_FORMOSA, 0xe017),
-+ .driver_info = MCE_GEN2_NO_TX },
- /* Formosa Industrial Computing / Beanbag Emulation Device */
- { USB_DEVICE(VENDOR_FORMOSA, 0xe018) },
- /* Formosa21 / eHome Infrared Receiver */
-@@ -308,7 +319,8 @@ static struct usb_device_id mceusb_dev_table[] = {
- /* Northstar Systems, Inc. eHome Infrared Transceiver */
- { USB_DEVICE(VENDOR_NORTHSTAR, 0xe004) },
- /* TiVo PC IR Receiver */
-- { USB_DEVICE(VENDOR_TIVO, 0x2000) },
-+ { USB_DEVICE(VENDOR_TIVO, 0x2000),
-+ .driver_info = TIVO_KIT },
- /* Conexant Hybrid TV "Shelby" Polaris SDK */
- { USB_DEVICE(VENDOR_CONEXANT, 0x58a1),
- .driver_info = POLARIS_EVK },
-diff --git a/drivers/media/rc/nuvoton-cir.c b/drivers/media/rc/nuvoton-cir.c
-index d4d6449..5d93384 100644
---- a/drivers/media/rc/nuvoton-cir.c
-+++ b/drivers/media/rc/nuvoton-cir.c
-@@ -37,8 +37,6 @@
-
- #include "nuvoton-cir.h"
-
--static char *chip_id = "w836x7hg";
--
- /* write val to config reg */
- static inline void nvt_cr_write(struct nvt_dev *nvt, u8 val, u8 reg)
- {
-@@ -233,6 +231,8 @@ static int nvt_hw_detect(struct nvt_dev *nvt)
- unsigned long flags;
- u8 chip_major, chip_minor;
- int ret = 0;
-+ char chip_id[12];
-+ bool chip_unknown = false;
-
- nvt_efm_enable(nvt);
-
-@@ -246,15 +246,39 @@ static int nvt_hw_detect(struct nvt_dev *nvt)
- }
-
- chip_minor = nvt_cr_read(nvt, CR_CHIP_ID_LO);
-- nvt_dbg("%s: chip id: 0x%02x 0x%02x", chip_id, chip_major, chip_minor);
-
-- if (chip_major != CHIP_ID_HIGH ||
-- (chip_minor != CHIP_ID_LOW && chip_minor != CHIP_ID_LOW2)) {
-- nvt_pr(KERN_ERR, "%s: unsupported chip, id: 0x%02x 0x%02x",
-- chip_id, chip_major, chip_minor);
-- ret = -ENODEV;
-+ /* these are the known working chip revisions... */
-+ switch (chip_major) {
-+ case CHIP_ID_HIGH_667:
-+ strcpy(chip_id, "w83667hg\0");
-+ if (chip_minor != CHIP_ID_LOW_667)
-+ chip_unknown = true;
-+ break;
-+ case CHIP_ID_HIGH_677B:
-+ strcpy(chip_id, "w83677hg\0");
-+ if (chip_minor != CHIP_ID_LOW_677B2 &&
-+ chip_minor != CHIP_ID_LOW_677B3)
-+ chip_unknown = true;
-+ break;
-+ case CHIP_ID_HIGH_677C:
-+ strcpy(chip_id, "w83677hg-c\0");
-+ if (chip_minor != CHIP_ID_LOW_677C)
-+ chip_unknown = true;
-+ break;
-+ default:
-+ strcpy(chip_id, "w836x7hg\0");
-+ chip_unknown = true;
-+ break;
- }
-
-+ /* warn, but still let the driver load, if we don't know this chip */
-+ if (chip_unknown)
-+ nvt_pr(KERN_WARNING, "%s: unknown chip, id: 0x%02x 0x%02x, "
-+ "it may not work...", chip_id, chip_major, chip_minor);
-+ else
-+ nvt_dbg("%s: chip id: 0x%02x 0x%02x",
-+ chip_id, chip_major, chip_minor);
-+
- nvt_efm_disable(nvt);
-
- spin_lock_irqsave(&nvt->nvt_lock, flags);
-@@ -267,13 +291,23 @@ static int nvt_hw_detect(struct nvt_dev *nvt)
-
- static void nvt_cir_ldev_init(struct nvt_dev *nvt)
- {
-- u8 val;
-+ u8 val, psreg, psmask, psval;
-+
-+ if (nvt->chip_major == CHIP_ID_HIGH_667) {
-+ psreg = CR_MULTIFUNC_PIN_SEL;
-+ psmask = MULTIFUNC_PIN_SEL_MASK;
-+ psval = MULTIFUNC_ENABLE_CIR | MULTIFUNC_ENABLE_CIRWB;
-+ } else {
-+ psreg = CR_OUTPUT_PIN_SEL;
-+ psmask = OUTPUT_PIN_SEL_MASK;
-+ psval = OUTPUT_ENABLE_CIR | OUTPUT_ENABLE_CIRWB;
-+ }
-
-- /* output pin selection (Pin95=CIRRX, Pin96=CIRTX1, WB enabled */
-- val = nvt_cr_read(nvt, CR_OUTPUT_PIN_SEL);
-- val &= OUTPUT_PIN_SEL_MASK;
-- val |= (OUTPUT_ENABLE_CIR | OUTPUT_ENABLE_CIRWB);
-- nvt_cr_write(nvt, val, CR_OUTPUT_PIN_SEL);
-+ /* output pin selection: enable CIR, with WB sensor enabled */
-+ val = nvt_cr_read(nvt, psreg);
-+ val &= psmask;
-+ val |= psval;
-+ nvt_cr_write(nvt, val, psreg);
-
- /* Select CIR logical device and enable */
- nvt_select_logical_dev(nvt, LOGICAL_DEV_CIR);
-@@ -674,7 +674,7 @@ static void nvt_process_rx_ir_data(struct nvt_dev *nvt)
- rawir.pulse ? "pulse" : "space",
- rawir.duration);
-
-- ir_raw_event_store(nvt->rdev, &rawir);
-+ ir_raw_event_store_with_filter(nvt->rdev, &rawir);
- }
-
- /*
-@@ -1110,12 +1110,12 @@ static int nvt_probe(struct pnp_dev *pdev, const struct
pnp_device_id *dev_id)
- rdev->input_id.version = nvt->chip_minor;
- rdev->driver_name = NVT_DRIVER_NAME;
- rdev->map_name = RC_MAP_RC6_MCE;
-+ rdev->timeout = US_TO_NS(1000);
-+ /* rx resolution is hardwired to 50us atm, 1, 25, 100 also possible */
-+ rdev->rx_resolution = US_TO_NS(CIR_SAMPLE_PERIOD);
- #if 0
- rdev->min_timeout = XYZ;
- rdev->max_timeout = XYZ;
-- rdev->timeout = XYZ;
-- /* rx resolution is hardwired to 50us atm, 1, 25, 100 also possible */
-- rdev->rx_resolution = XYZ;
- /* tx bits */
- rdev->tx_resolution = XYZ;
- #endif
-diff --git a/drivers/media/rc/nuvoton-cir.h b/drivers/media/rc/nuvoton-cir.h
-index 048135e..379795d 100644
---- a/drivers/media/rc/nuvoton-cir.h
-+++ b/drivers/media/rc/nuvoton-cir.h
-@@ -330,9 +330,13 @@ struct nvt_dev {
- #define EFER_EFM_DISABLE 0xaa
-
- /* Chip IDs found in CR_CHIP_ID_{HI,LO} */
--#define CHIP_ID_HIGH 0xb4
--#define CHIP_ID_LOW 0x72
--#define CHIP_ID_LOW2 0x73
-+#define CHIP_ID_HIGH_667 0xa5
-+#define CHIP_ID_HIGH_677B 0xb4
-+#define CHIP_ID_HIGH_677C 0xc3
-+#define CHIP_ID_LOW_667 0x13
-+#define CHIP_ID_LOW_677B2 0x72
-+#define CHIP_ID_LOW_677B3 0x73
-+#define CHIP_ID_LOW_677C 0x33
-
- /* Config regs we need to care about */
- #define CR_SOFTWARE_RESET 0x02
-@@ -341,6 +345,7 @@ struct nvt_dev {
- #define CR_CHIP_ID_LO 0x21
- #define CR_DEV_POWER_DOWN 0x22 /* bit 2 is CIR power, default power on */
- #define CR_OUTPUT_PIN_SEL 0x27
-+#define CR_MULTIFUNC_PIN_SEL 0x2c
- #define CR_LOGICAL_DEV_EN 0x30 /* valid for all logical devices */
- /* next three regs valid for both the CIR and CIR_WAKE logical devices */
- #define CR_CIR_BASE_ADDR_HI 0x60
-@@ -364,10 +369,16 @@ struct nvt_dev {
- #define CIR_INTR_MOUSE_IRQ_BIT 0x80
- #define PME_INTR_CIR_PASS_BIT 0x08
-
-+/* w83677hg CIR pin config */
- #define OUTPUT_PIN_SEL_MASK 0xbc
- #define OUTPUT_ENABLE_CIR 0x01 /* Pin95=CIRRX, Pin96=CIRTX1 */
- #define OUTPUT_ENABLE_CIRWB 0x40 /* enable wide-band sensor */
-
-+/* w83667hg CIR pin config */
-+#define MULTIFUNC_PIN_SEL_MASK 0x1f
-+#define MULTIFUNC_ENABLE_CIR 0x80 /* Pin75=CIRRX, Pin76=CIRTX1 */
-+#define MULTIFUNC_ENABLE_CIRWB 0x20 /* enable wide-band sensor */
-+
- /* MCE CIR signal length, related on sample period */
-
- /* MCE CIR controller signal length: about 43ms
-diff --git a/drivers/staging/lirc/lirc_sasem.c b/drivers/staging/lirc/lirc_sasem.c
-index 63a438d..7080cde 100644
---- a/drivers/staging/lirc/lirc_sasem.c
-+++ b/drivers/staging/lirc/lirc_sasem.c
-@@ -570,6 +570,7 @@ static void incoming_packet(struct sasem_context *context,
- unsigned char *buf = urb->transfer_buffer;
- long ms;
- struct timeval tv;
-+ int i;
-
- if (len != 8) {
- printk(KERN_WARNING "%s: invalid incoming packet size (%d)\n",
-@@ -577,12 +578,12 @@ static void incoming_packet(struct sasem_context *context,
- return;
- }
-
--#ifdef DEBUG
-- int i;
-- for (i = 0; i < 8; ++i)
-- printk(KERN_INFO "%02x ", buf[i]);
-- printk(KERN_INFO "\n");
--#endif
-+ if (debug) {
-+ printk(KERN_INFO "Incoming data: ");
-+ for (i = 0; i < 8; ++i)
-+ printk(KERN_CONT "%02x ", buf[i]);
-+ printk(KERN_CONT "\n");
-+ }
-
- /*
- * Lirc could deal with the repeat code, but we really need to block it
-diff --git a/include/linux/input.h b/include/linux/input.h
-index e428382..be082e9 100644
---- a/include/linux/input.h
-+++ b/include/linux/input.h
-@@ -553,8 +553,8 @@ struct input_keymap_entry {
- #define KEY_DVD 0x185 /* Media Select DVD */
- #define KEY_AUX 0x186
- #define KEY_MP3 0x187
--#define KEY_AUDIO 0x188
--#define KEY_VIDEO 0x189
-+#define KEY_AUDIO 0x188 /* AL Audio Browser */
-+#define KEY_VIDEO 0x189 /* AL Movie Browser */
- #define KEY_DIRECTORY 0x18a
- #define KEY_LIST 0x18b
- #define KEY_MEMO 0x18c /* Media Select Messages */
-@@ -605,6 +605,7 @@ struct input_keymap_entry {
- #define KEY_MEDIA_REPEAT 0x1b7 /* Consumer - transport control */
- #define KEY_10CHANNELSUP 0x1b8 /* 10 channels up (10+) */
- #define KEY_10CHANNELSDOWN 0x1b9 /* 10 channels down (10-) */
-+#define KEY_IMAGES 0x1ba /* AL Image Browser */
-
- #define KEY_DEL_EOL 0x1c0
- #define KEY_DEL_EOS 0x1c1
-diff --git a/include/media/rc-map.h b/include/media/rc-map.h
-index 9184751..b2bd405 100644
---- a/include/media/rc-map.h
-+++ b/include/media/rc-map.h
-@@ -58,6 +58,7 @@ void rc_map_init(void);
- #define RC_MAP_ALINK_DTU_M "rc-alink-dtu-m"
- #define RC_MAP_ANYSEE "rc-anysee"
- #define RC_MAP_APAC_VIEWCOMP "rc-apac-viewcomp"
-+#define RC_MAP_APPLE "rc-apple"
- #define RC_MAP_ASUS_PC39 "rc-asus-pc39"
- #define RC_MAP_ATI_TV_WONDER_HD_600 "rc-ati-tv-wonder-hd-600"
- #define RC_MAP_AVERMEDIA_A16D "rc-avermedia-a16d"
-@@ -136,6 +137,7 @@ void rc_map_init(void);
- #define RC_MAP_TERRATEC_CINERGY_XS "rc-terratec-cinergy-xs"
- #define RC_MAP_TERRATEC_SLIM "rc-terratec-slim"
- #define RC_MAP_TEVII_NEC "rc-tevii-nec"
-+#define RC_MAP_TIVO "rc-tivo"
- #define RC_MAP_TOTAL_MEDIA_IN_HAND "rc-total-media-in-hand"
- #define RC_MAP_TREKSTOR "rc-trekstor"
- #define RC_MAP_TT_1500 "rc-tt-1500"
-diff --git a/drivers/media/rc/ite-cir.c b/drivers/media/rc/ite-cir.c
-index accaf6c..43908a7 100644
---- a/drivers/media/rc/ite-cir.c
-+++ b/drivers/media/rc/ite-cir.c
-@@ -36,6 +36,7 @@
- #include <linux/io.h>
- #include <linux/interrupt.h>
- #include <linux/sched.h>
-+#include <linux/delay.h>
- #include <linux/slab.h>
- #include <linux/input.h>
- #include <linux/bitops.h>
-
diff --git a/linux-2.6-v4l-dvb-update.patch b/linux-2.6-v4l-dvb-update.patch
index 0984884..e69de29 100644
--- a/linux-2.6-v4l-dvb-update.patch
+++ b/linux-2.6-v4l-dvb-update.patch
@@ -1,7725 +0,0 @@
-v4l/dvb/rc media_tree updates from 2.6.39
-
-commit f9d088784131609419595b51beb701d0f3aa6afc
-Author: Jarod Wilson <jarod(a)redhat.com>
-Date: Tue Mar 22 17:23:15 2011 -0300
-
- [media] rc: interim support for 32-bit NEC-ish scancodes
-
- The Apple and TiVo remotes I've got use an NEC-ish protocol, but rather
- than a command/not_command pair, they have what appear to be vendor ID
- bytes. This change makes the NEC decoder warn if the command/not_command
- checksum fails, but then passes along a full 32-bit scancode for keymap
- lookup. This change should make no difference for existing keymaps,
- since they simply won't have 32-bit scancodes, but allows for a 32-bit
- keymap. At the moment, that'll have to be uploaded by the user, but I've
- got Apple and TiVo remote keymaps forthcoming.
-
- In the long run (2.6.40, hopefully), we should probably just always use
- all 32 bits for all NEC keymaps, but this should get us by for 2.6.39.
-
- (Note that a few of the TiVo keys actuallly *do* pass the command
- checksum, so for now, the keymap for this remote will have to be a mix
- of 24-bit and 32-bit scancodes, but so be it).
-
- Signed-off-by: Jarod Wilson <jarod(a)redhat.com>
- Signed-off-by: Mauro Carvalho Chehab <mchehab(a)redhat.com>
-
-commit 4568844fff1dc46b8adb7364ac3a844aa34d1e38
-Author: Jarod Wilson <jarod(a)redhat.com>
-Date: Fri Mar 4 20:20:47 2011 -0300
-
- [media] mceusb: topseed 0x0011 needs gen3 init for tx to work
-
- Signed-off-by: Jarod Wilson <jarod(a)redhat.com>
- Signed-off-by: Mauro Carvalho Chehab <mchehab(a)redhat.com>
-
-commit 514c3ef0671bdbdb1ae3708c63cce12e6f4b55f0
-Author: Jarod Wilson <jarod(a)redhat.com>
-Date: Fri Mar 4 19:53:05 2011 -0300
-
- [media] lirc_zilog: error out if buffer read bytes != chunk size
-
- Give it a few tries, then exit. Prevents a possible endless loop
- situation.
-
- Signed-off-by: Jarod Wilson <jarod(a)redhat.com>
- Signed-off-by: Mauro Carvalho Chehab <mchehab(a)redhat.com>
-
-commit 7f72453889801675b825083d7ebddc341ccbb331
-Author: Jarod Wilson <jarod(a)redhat.com>
-Date: Fri Mar 4 17:57:24 2011 -0300
-
- [media] lirc: silence some compile warnings
-
- Both lirc_imon and lirc_sasem were causing gcc to complain about the
- possible use of uninitialized variables.
-
- Signed-off-by: Jarod Wilson <jarod(a)redhat.com>
- Signed-off-by: Mauro Carvalho Chehab <mchehab(a)redhat.com>
-
-commit 37bda6318295a3412e191f1a5cb5a5bea2db59a5
-Author: Jarod Wilson <jarod(a)redhat.com>
-Date: Fri Mar 4 17:31:11 2011 -0300
-
- [media] hdpvr: use same polling interval as other OS
-
- The hdpvr's IR part, in short, sucks. As observed with a usb traffic
- sniffer, the Windows software for it uses a polling interval of 405ms.
- Its still not behaving as well as I'd like even with this change, but
- this inches us closer and closer to that point...
-
- Signed-off-by: Jarod Wilson <jarod(a)redhat.com>
- Signed-off-by: Mauro Carvalho Chehab <mchehab(a)redhat.com>
-
-commit 6ba973db97845b0b7322d1a0cd5348d3024d7387
-Author: Jarod Wilson <jarod(a)redhat.com>
-Date: Fri Mar 4 17:30:17 2011 -0300
-
- [media] ir-kbd-i2c: pass device code w/key in hauppauge case
-
- The new hauppauge key tables use both device code button code.
-
- Signed-off-by: Jarod Wilson <jarod(a)redhat.com>
- Signed-off-by: Mauro Carvalho Chehab <mchehab(a)redhat.com>
-
-commit 246286a63b4820c1c039a836025c52ec79d18a2f
-Author: Mauro Carvalho Chehab <mchehab(a)redhat.com>
-Date: Mon Jan 24 22:23:08 2011 -0300
-
- [media] rc/keymaps: Remove the obsolete rc-rc5-tv keymap
-
- This keymap were used for the Hauppauge Black remote controller
- only. It also contains some keycodes not found there. As the
- Hauppauge Black is now part of the hauppauge keymap, just remove
- it.
-
- Also, remove the modprobe hacks to select between the Gray
- and the Black versions of the remote controller as:
- - Both are supported by default by the keymap;
- - If the user just wants one keyboard supported,
- it is just a matter of changing the keymap via
- the userspace tool (ir-keytable), removing
- the keys that he doesn't desire. As ir-keytable
- auto-loads the keys via udev, this is better than
- obscure modprobe parameters.
-
- Signed-off-by: Mauro Carvalho Chehab <mchehab(a)redhat.com>
- Signed-off-by: Jarod Wilson <jarod(a)redhat.com>
-
-commit af2a42cc5eec9659bac301885ac795be81d019c8
-Author: Mauro Carvalho Chehab <mchehab(a)redhat.com>
-Date: Mon Jan 24 12:18:48 2011 -0300
-
- [media] remove the old RC_MAP_HAUPPAUGE_NEW RC map
-
- The rc-hauppauge-new map is a messy thing, as it bundles 3
-
- different remote controllers as if they were just one,
- discarding the address byte. Also, some key maps are wrong.
-
- With the conversion to the new rc-core, it is likely that
- most of the devices won't be working properly, as the i2c
- driver and the raw decoders are now providing 16 bits for
- the remote, instead of just 8.
-
- delete mode 100644 drivers/media/rc/keymaps/rc-hauppauge-new.c
-
- Signed-off-by: Mauro Carvalho Chehab <mchehab(a)redhat.com>
- Signed-off-by: Jarod Wilson <jarod(a)redhat.com>
-
-commit 1ef571252ec29a8b3674deb746bfaa8ad1b034c3
-Author: Mauro Carvalho Chehab <mchehab(a)redhat.com>
-Date: Mon Jan 24 12:18:47 2011 -0300
-
- [media] rc/keymaps: Rename Hauppauge table as rc-hauppauge
-
- There are two "hauppauge-new" keymaps, one with protocol
- unknown, and the other with the protocol marked accordingly.
- However, both tables are miss-named.
-
- Also, the old rc-hauppauge-new is broken, as it mixes
- three different controllers as if they were just one.
-
- This patch solves half of the problem by renaming the
- correct keycode table as just rc-hauppauge. This table
- contains the codes for the four different types of
- remote controllers found on Hauppauge cards, properly
- mapped with their different addresses.
-
- create mode 100644 drivers/media/rc/keymaps/rc-hauppauge.c
- delete mode 100644 drivers/media/rc/keymaps/rc-rc5-hauppauge-new.c
- [Jarod: fix up RC_MAP_HAUPPAUGE defines]
-
- Signed-off-by: Mauro Carvalho Chehab <mchehab(a)redhat.com>
- Signed-off-by: Jarod Wilson <jarod(a)redhat.com>
-
-commit 41abb2ee0ac34ecd8769b2ddd84caf67414ca0f7
-Author: Mauro Carvalho Chehab <mchehab(a)redhat.com>
-Date: Mon Jan 24 12:18:45 2011 -0300
-
- [media] rc-rc5-hauppauge-new: Fix Hauppauge Grey mapping
-
- The keys for the old black were messed with the ones for the
- hauppauge grey. Fix it.
-
- Also, fixes some keycodes and order the keys according with
- the way they appear inside the remote controller.
-
- Signed-off-by: Mauro Carvalho Chehab <mchehab(a)redhat.com>
- Signed-off-by: Jarod Wilson <jarod(a)redhat.com>
-
-commit 80daad9d9ece3bbfd0f7cc13dbefc92e3ebb1f6f
-Author: Mauro Carvalho Chehab <mchehab(a)redhat.com>
-Date: Mon Jan 24 12:18:44 2011 -0300
-
- [media] rc-rc5-hauppauge-new: Add support for the old Black RC
-
- Hans borrowed me an old Black Hauppauge RC. Thanks to that, we
- can fix the RC5 table for Hauppauge.
-
- Thanks-to: Hans Verkuil <hverkuil(a)xs4all.nl>
- Signed-off-by: Mauro Carvalho Chehab <mchehab(a)redhat.com>
- Signed-off-by: Jarod Wilson <jarod(a)redhat.com>
-
-commit 9ba542ee399a091a56711d5bc1f778f39768a26d
-Author: Mauro Carvalho Chehab <mchehab(a)redhat.com>
-Date: Mon Jan 24 12:18:43 2011 -0300
-
- [media] rc-rc5-hauppauge-new: Add the old control to the table
-
- Adds the old grey remote controller to Hauppauge table.
-
- Hans borrowed me an old gray Hauppauge RC. Thanks to that, we
- can fix the RC5 table for Hauppauge.
-
- Thanks-to: Hans Verkuil <hverkuil(a)xs4all.nl>
- Signed-off-by: Mauro Carvalho Chehab <mchehab(a)redhat.com>
- Signed-off-by: Jarod Wilson <jarod(a)redhat.com>
-
-commit 8d198df40f2d6fe2bfb3b8818dce974b40a614e9
-Author: Mauro Carvalho Chehab <mchehab(a)redhat.com>
-Date: Mon Jan 24 12:18:43 2011 -0300
-
- [media] rc-winfast: Fix the keycode tables
-
- One of the remotes has a picture available at:
-
http://lirc.sourceforge.net/remotes/leadtek/Y04G0004.jpg
-
- As there's one variant with a set direction keys plus vol/chann
- keys, and the same table is used for both models, change it to
- represent all keys, avoiding the usage of weird function keys.
-
- Signed-off-by: Mauro Carvalho Chehab <mchehab(a)redhat.com>
- Signed-off-by: Jarod Wilson <jarod(a)redhat.com>
-
-commit 434e6519a292096ee29303d74688ced038606842
-Author: Mauro Carvalho Chehab <mchehab(a)redhat.com>
-Date: Mon Jan 24 12:18:42 2011 -0300
-
- [media] a800: Fix a few wrong IR key assignments
-
- Signed-off-by: Mauro Carvalho Chehab <mchehab(a)redhat.com>
- Signed-off-by: Jarod Wilson <jarod(a)redhat.com>
-
-commit 674ff915ca5d7b40d710eb910afcf7f490b76ab0
-Author: Mauro Carvalho Chehab <mchehab(a)redhat.com>
-Date: Mon Jan 24 12:18:41 2011 -0300
-
- [media] opera1: Use multimedia keys instead of an app-specific mapping
-
- This driver uses an app-specific keymap for one of the tables. This
- is wrong. Instead, use the standard keycodes.
-
- Signed-off-by: Mauro Carvalho Chehab <mchehab(a)redhat.com>
- Signed-off-by: Jarod Wilson <jarod(a)redhat.com>
-
-commit d59b1eedf5d5108cc90b9cfaf17f7845bad4f806
-Author: Mauro Carvalho Chehab <mchehab(a)redhat.com>
-Date: Mon Jan 24 12:18:40 2011 -0300
-
- [media] dw2102: Use multimedia keys instead of an app-specific mapping
-
- This driver uses an app-specific keymap for one of the tables. This
- is wrong. Instead, use the standard keycodes.
-
- Signed-off-by: Mauro Carvalho Chehab <mchehab(a)redhat.com>
- Signed-off-by: Jarod Wilson <jarod(a)redhat.com>
-
-commit 651cef86ff15697ad8a5659ecc9bc43f16ca07ba
-Author: Mauro Carvalho Chehab <mchehab(a)redhat.com>
-Date: Mon Jan 24 12:18:39 2011 -0300
-
- [media] rc/keymaps: Use KEY_LEFTMETA were pertinent
-
- Using xev and testing the "Windows" key on a normal keyboard, it
- is mapped as KEY_LEFTMETA. So, as this is the standard code for
- it, use it, instead of a generic, meaningless KEY_PROG1.
-
- Signed-off-by: Mauro Carvalho Chehab <mchehab(a)redhat.com>
- Signed-off-by: Jarod Wilson <jarod(a)redhat.com>
-
-commit bb8aeecec52791eacc727d8400ced9e1b230ec49
-Author: Mauro Carvalho Chehab <mchehab(a)redhat.com>
-Date: Mon Jan 24 12:18:38 2011 -0300
-
- [media] rc/keymaps: Fix most KEY_PROG[n] keycodes
-
- Those KEY_PROG[n] keys were used on places where the developer
- didn't know for sure what key should be used. On several cases,
- using KEY_RED, KEY_GREEN, KEY_YELLOW would be enough. On others,
- there are specific keys for that already.
-
- Signed-off-by: Mauro Carvalho Chehab <mchehab(a)redhat.com>
- Signed-off-by: Jarod Wilson <jarod(a)redhat.com>
-
-commit 84c122769cca37480fbcd7de5a102f6221874247
-Author: Mauro Carvalho Chehab <mchehab(a)redhat.com>
-Date: Mon Jan 24 12:18:37 2011 -0300
-
- [media] rc/keymaps: Use KEY_VIDEO for Video Source
-
- Each keyboard map were using a different definition for
- the Source/Video Source key.
- Behold Columbus were the only one using KEY_PROPS.
-
- As we want to standardize those keys at X11 and at
- userspace applications, we need to use just one code
- for it.
-
- Signed-off-by: Mauro Carvalho Chehab <mchehab(a)redhat.com>
- Signed-off-by: Jarod Wilson <jarod(a)redhat.com>
-
-commit ea35a76538a45e78cee889d2c462df71a9b34e4c
-Author: Mauro Carvalho Chehab <mchehab(a)redhat.com>
-Date: Mon Jan 24 12:18:36 2011 -0300
-
- [media] rc/keymaps: use KEY_CAMERA for snapshots
-
- On a few places, KEY_MHP were used for snapshots. However, KEY_CAMERA
- is used for it on all the other keyboards that have a snapshot/Picture
- button.
-
- Signed-off-by: Mauro Carvalho Chehab <mchehab(a)redhat.com>
- Signed-off-by: Jarod Wilson <jarod(a)redhat.com>
-
-commit d33d27b1745fc72b042b6431dd29ee484fdabbcc
-Author: Andy Walls <awalls(a)md.metrocast.net>
-Date: Thu Feb 17 21:32:06 2011 -0300
-
- [media] lirc_zilog: Update TODO list based on work completed and revised plans
-
- Update the TODO.lirc_zilog based on what has been completed. Also revised
- the development plan for lirc_zilog to not try and split Tx/Rx for one IR
- transceiver unit between lirc_zilog and ir-kbd-i2c, since that would be a
- ref-counting nightmare.
-
- Signed-off-by: Andy Walls <awalls(a)md.metrocast.net>
- Signed-off-by: Jarod Wilson <jarod(a)redhat.com>
- Signed-off-by: Mauro Carvalho Chehab <mchehab(a)redhat.com>
-
-commit 1a9cb97924e71b33a5d1a59facd58e1a584daa97
-Author: Andy Walls <awalls(a)md.metrocast.net>
-Date: Thu Feb 17 21:14:13 2011 -0300
-
- [media] lirc_zilog: Fix somewhat confusing information messages in ir_probe()
-
- The total sequence of messages emitted by the ir_porbe() calls
- for a transceiver's two i2c_clients was confusing. Clean it up a bit.
-
- Signed-off-by: Andy Walls <awalls(a)md.metrocast.net>
- Signed-off-by: Jarod Wilson <jarod(a)redhat.com>
- Signed-off-by: Mauro Carvalho Chehab <mchehab(a)redhat.com>
-
-commit cf141c455938cb245b6bf489c832d0c2e3833686
-Author: Andy Walls <awalls(a)md.metrocast.net>
-Date: Thu Feb 17 20:50:38 2011 -0300
-
- [media] lirc_zilog: Add locking of the i2c_clients when in use
-
- Lock the i2c_client pointers and prevent i2c_client removal when
- lirc_zilog is perfoming a series of operations that require valid
- i2c_client pointers.
-
- Signed-off-by: Andy Walls <awalls(a)md.metrocast.net>
- Signed-off-by: Jarod Wilson <jarod(a)redhat.com>
- Signed-off-by: Mauro Carvalho Chehab <mchehab(a)redhat.com>
-
-commit 6f4276ac6e98a05833aa7e49e438fec198e537e8
-Author: Andy Walls <awalls(a)md.metrocast.net>
-Date: Mon Feb 7 22:30:55 2011 -0300
-
- [media] lirc_zilog: Add ref counting of struct IR, IR_tx, and IR_rx
-
- This is a major change to add pointer reference counting for
- struct IR, struct IR_tx, and struct IR_rx object instances.
- This ref counting gets lirc_zilog closer to gracefully handling
- bridge drivers and hot-unplugged USB devices disappearing out from
- under lirc_zilog when the /dev/lircN node is still open. (mutexes
- to protect the i2c_client pointers in struct IR_tx and struct IR_rx
- still need to be added.)
-
- This reference counting also helps lirc_zilog clean up properly
- when the i2c_clients disappear.
-
- Signed-off-by: Andy Walls <awalls(a)md.metrocast.net>
- Signed-off-by: Jarod Wilson <jarod(a)redhat.com>
- Signed-off-by: Mauro Carvalho Chehab <mchehab(a)redhat.com>
-
-commit f3bc78dbb5942f1827a97329b1c095903329aa8b
-Author: Andy Walls <awalls(a)md.metrocast.net>
-Date: Thu Jan 27 23:02:20 2011 -0300
-
- [media] lirc_zilog: Move constants from ir_probe() into the lirc_driver template
-
- ir_probe() makes a number of constant assignments into the lirc_driver
- object after copying in a template. Make better use of the template.
-
- Signed-off-by: Andy Walls <awalls(a)md.metrocast.net>
- Signed-off-by: Jarod Wilson <jarod(a)redhat.com>
- Signed-off-by: Mauro Carvalho Chehab <mchehab(a)redhat.com>
-
-commit 6f61cb53e2b8f6c65cf2c6b3e3710233c643e6ce
-Author: Andy Walls <awalls(a)md.metrocast.net>
-Date: Thu Jan 27 22:32:44 2011 -0300
-
- [media] lirc_zilog: Always allocate a Rx lirc_buffer object
-
- Always allocate a lirc_buffer object, instead of just upon setup of
- the Rx i2c_client. If we do not allocate a lirc_buffer object, because
- we are not handling the Rx i2c_client, lirc_dev will allocate its own
- lirc_buffer anyway and not tell us about its location.
-
- Signed-off-by: Andy Walls <awalls(a)md.metrocast.net>
- Signed-off-by: Jarod Wilson <jarod(a)redhat.com>
- Signed-off-by: Mauro Carvalho Chehab <mchehab(a)redhat.com>
-
-commit 8941d66476b33d339408f66898766e0d8ac2cb0a
-Author: Andy Walls <awalls(a)md.metrocast.net>
-Date: Thu Jan 27 02:34:13 2011 -0300
-
- [media] lirc_zilog: Remove unneeded rx->buf_lock
-
- Remove the rx->buf_lock that protected the rx->buf lirc_buffer. The
- underlying operations on the objects within the lirc_buffer are already
- protected by spinlocks, or the objects are constant (e.g. chunk_size).
-
- Signed-off-by: Andy Walls <awalls(a)md.metrocast.net>
- Signed-off-by: Jarod Wilson <jarod(a)redhat.com>
- Signed-off-by: Mauro Carvalho Chehab <mchehab(a)redhat.com>
-
-commit fa2d70732b5699cd3bc9fc0e82c154e1410857e4
-Author: Andy Walls <awalls(a)md.metrocast.net>
-Date: Thu Jan 27 02:10:42 2011 -0300
-
- [media] lirc_zilog: Don't acquire the rx->buf_lock in the poll() function
-
- There is no need to take the rx->buf_lock in the the poll() function
- as all the underling calls made on objects in the rx->buf lirc_buffer object
- are protected by spinlocks.
-
- Corrected a bad error return value in poll(): return POLLERR instead
- of -ENODEV.
-
- Added some comments to poll() for when, in the future, I forget what
- poll() and poll_wait() are supposed to do.
-
- [Jarod: minor debug spew fix]
-
- Signed-off-by: Andy Walls <awalls(a)md.metrocast.net>
- Signed-off-by: Jarod Wilson <jarod(a)redhat.com>
- Signed-off-by: Mauro Carvalho Chehab <mchehab(a)redhat.com>
-
-commit 45a0dd2e9575f72693c94920e8d189ea395d5b5d
-Author: Andy Walls <awalls(a)md.metrocast.net>
-Date: Thu Jan 27 00:04:15 2011 -0300
-
- [media] lirc_zilog: Use kernel standard methods for marking device non-seekable
-
- lirc_zilog had its own llseek stub that returned -ESPIPE. Get rid of
- it and use the kernel's no_llseek() and nonseekable_open() functions
- instead.
-
- Signed-off-by: Andy Walls <awalls(a)md.metrocast.net>
- Signed-off-by: Jarod Wilson <jarod(a)redhat.com>
- Signed-off-by: Mauro Carvalho Chehab <mchehab(a)redhat.com>
-
-commit c4c4362e1e1bd1a39f186b96ba5b0df74470f101
-Author: Andy Walls <awalls(a)md.metrocast.net>
-Date: Wed Jan 26 22:04:24 2011 -0300
-
- [media] lirc_zilog: Convert the instance open count to an atomic_t
-
- The open count is simply used for deciding if the Rx polling thread
- needs to poll the IR chip for userspace. Simplify the manipulation
- of the open count by using an atomic_t and not requiring a lock
- The polling thread errantly didn't try to take the lock anyway.
-
- Signed-off-by: Andy Walls <awalls(a)md.metrocast.net>
- Signed-off-by: Jarod Wilson <jarod(a)redhat.com>
- Signed-off-by: Mauro Carvalho Chehab <mchehab(a)redhat.com>
-
-commit 7f94125db5889c202b95e717ccbe9e35de63c14a
-Author: Andy Walls <awalls(a)md.metrocast.net>
-Date: Wed Jan 26 21:48:32 2011 -0300
-
- [media] lirc_zilog: Convert ir_device instance array to a linked list
-
- Signed-off-by: Andy Walls <awalls(a)md.metrocast.net>
- Signed-off-by: Jarod Wilson <jarod(a)redhat.com>
- Signed-off-by: Mauro Carvalho Chehab <mchehab(a)redhat.com>
-
-commit d2a47dc2e351e6cf33b98f0d3339d6d39fd8ed8b
-Author: Andy Walls <awalls(a)md.metrocast.net>
-Date: Wed Jan 26 21:25:47 2011 -0300
-
- [media] lirc_zilog: Remove broken, ineffective reference counting
-
- The set_use_inc() and set_use_dec() functions tried to lock
- the underlying bridge driver device instance in memory by
- changing the use count on the device's i2c_clients. This
- worked for PCI devices (ivtv, cx18, bttv). It doesn't
- work for hot-pluggable usb devices (pvrusb2 and hdpvr).
- With usb device instances, the driver may get locked into
- memory, but the unplugged hardware is gone.
-
- The set_use_inc() set_use_dec() functions also tried to have
- lirc_zilog change its own module refernce count, which is
- racy and not guaranteed to work. The lirc_dev module does
- actually perform proper module ref count manipulation on the
- lirc_zilog module, so there is need for lirc_zilog to
- attempt a buggy module get on itself anyway.
-
- lirc_zilog also errantly called these functions on itself
- in open() and close(), but lirc_dev did that already too.
-
- So let's just gut the bodies of the set_use_*() functions,
- and remove the extra calls to them from within lirc_zilog.
-
- Proper reference counting of the struct IR, IR_rx, and IR_tx
- objects -- to handle the case when the underlying
- bttv, ivtv, cx18, hdpvr, or pvrusb2 bridge driver module or
- device instance goes away -- will be added in subsequent
- patches.
-
- Signed-off-by: Andy Walls <awalls(a)md.metrocast.net>
- Signed-off-by: Jarod Wilson <jarod(a)redhat.com>
- Signed-off-by: Mauro Carvalho Chehab <mchehab(a)redhat.com>
-
-commit 767dd925f017bd0f0363f827509cebfaf0bb2b57
-Author: Andy Walls <awalls(a)md.metrocast.net>
-Date: Wed Jan 26 21:06:43 2011 -0300
-
- [media] lirc_zilog: Restore checks for existence of the IR_tx object
-
- This reverts commit 8090232a237ab62e22307fc060097da1a283dd66 and
- adds an additional check for ir->tx == NULL.
-
- The user may need us to handle an RX only unit. Apparently
- there are TV capture units in existence with Rx only wiring
- and/or RX only firmware for the on-board Zilog Z8 IR unit.
-
- Signed-off-by: Andy Walls <awalls(a)md.metrocast.net>
- Signed-off-by: Jarod Wilson <jarod(a)redhat.com>
- Signed-off-by: Mauro Carvalho Chehab <mchehab(a)redhat.com>
-
-commit 91f27e09d7bba99341bd8ce035995ae21ff493f7
-Author: Jarod Wilson <jarod(a)redhat.com>
-Date: Wed Mar 2 13:23:52 2011 -0300
-
- [media] hdpvr: i2c master enhancements
-
- Make the hdpvr's i2c master implementation more closely mirror that of
- the pvrusb2 driver. Currently makes no significant difference in IR
- reception behavior with ir-kbd-i2c (i.e., it still sucks).
-
- Signed-off-by: Jarod Wilson <jarod(a)redhat.com>
- Signed-off-by: Mauro Carvalho Chehab <mchehab(a)redhat.com>
-
-commit c1ba04cf3a0626f725795e3a853654928596d522
-Author: Jarod Wilson <jarod(a)redhat.com>
-Date: Tue Feb 1 16:27:05 2011 -0300
-
- [media] imon: add more panel scancode mappings
-
- Signed-off-by: Jarod Wilson <jarod(a)redhat.com>
- Signed-off-by: Mauro Carvalho Chehab <mchehab(a)redhat.com>
-
-commit 9cd4f638d57b01c5d901f73c94b08fad4aa0b295
-Author: Jarod Wilson <jarod(a)redhat.com>
-Date: Mon Jan 24 18:22:12 2011 -0300
-
- [media] docs: fix typo in lirc_device_interface.xml
-
- Reported-by: Daniel Burr <dburr(a)topcon.com>
- Signed-off-by: Jarod Wilson <jarod(a)redhat.com>
- Signed-off-by: Mauro Carvalho Chehab <mchehab(a)redhat.com>
-
-commit 97ad124749a060d8c4f5461111911474db3b555f
-Author: Mauro Carvalho Chehab <mchehab(a)redhat.com>
-Date: Tue Mar 22 17:17:56 2011 -0300
-
- ite-cir: Fix a breakage caused by my cleanup patch
-
- Signed-off-by: Mauro Carvalho Chehab <mchehab(a)redhat.com>
-
-commit a38fc7a384bd679f2550e2a2323ff3e690d4ffd7
-Author: Juan J. Garcia de Soria <skandalfo(a)gmail.com>
-Date: Wed Mar 16 17:14:53 2011 -0300
-
- [media] lirc: remove staging lirc_it87 and lirc_ite8709 drivers
-
- Remove older drivers lirc_it87 and lirc_ite8709 from the LIRC staging area,
- since they're now superceded by ite-cir.
-
- Signed-off-by: Juan J. Garcia de Soria <skandalfo(a)gmail.com>
- Tested-by: Stephan Raue <stephan(a)openelec.tv>
- Signed-off-by: Jarod Wilson <jarod(a)redhat.com>
- Signed-off-by: Mauro Carvalho Chehab <mchehab(a)redhat.com>
-
-commit e1bede3475c792a5c4793ec3cc929efa24aaae64
-Author: Mauro Carvalho Chehab <mchehab(a)redhat.com>
-Date: Tue Mar 22 15:12:40 2011 -0300
-
- [media] ite-cir: Fix some CodingStyle issues
-
- Cc: Juan J. Garcia de Soria <skandalfo(a)gmail.com>
- Cc: Stephan Raue <stephan(a)openelec.tv>
- Cc: Jarod Wilson <jarod(a)redhat.com>
- Signed-off-by: Mauro Carvalho Chehab <mchehab(a)redhat.com>
-
-commit 9e8739744ccc917011a91e489339278d7bb14eac
-Author: Juan J. Garcia de Soria <skandalfo(a)gmail.com>
-Date: Wed Mar 16 17:14:52 2011 -0300
-
- [media] rc: New rc-based ite-cir driver for several ITE CIRs
-
- This is a second version of an rc-core based driver for the ITE Tech IT8712F
- CIR and now for a pair of other variants of the IT8512 CIR too.
-
- This driver should replace the lirc_it87 and lirc_ite8709 currently living in
- the LIRC staging directory.
-
- The driver should support the ITE8704, ITE8713, ITE8708 and ITE8709 (this last
- one yet untested) PNP ID's.
-
- The code doesn'te reuse code from the pre-existing LIRC drivers, but has been
- written from scratch using the nuvoton.cir driver as a skeleton.
-
- This new driver shouldn't exhibit timing problems when running under load (or
- with interrupts disabled for relatively long times). It works OOTB with the
- RC6 MCE remote bundled with the ASUS EEEBox. TX support is implemented, but
- I'm unable to test it since my hardware lacks TX capability.
-
- Signed-off-by: Juan J. Garcia de Soria <skandalfo(a)gmail.com>
- Tested-by: Stephan Raue <stephan(a)openelec.tv>
- Signed-off-by: Jarod Wilson <jarod(a)redhat.com>
- Signed-off-by: Mauro Carvalho Chehab <mchehab(a)redhat.com>
- .../DocBook/v4l/lirc_device_interface.xml | 2 +-
- drivers/media/dvb/dvb-usb/a800.c | 8 +-
- drivers/media/dvb/dvb-usb/digitv.c | 2 +-
- drivers/media/dvb/dvb-usb/dw2102.c | 40 +-
- drivers/media/dvb/dvb-usb/opera1.c | 33 +-
- drivers/media/dvb/siano/sms-cards.c | 2 +-
- drivers/media/dvb/ttpci/budget-ci.c | 15 +-
- drivers/media/rc/Kconfig | 13 +
- drivers/media/rc/Makefile | 1 +
- drivers/media/rc/imon.c | 11 +-
- drivers/media/rc/ir-nec-decoder.c | 10 +-
- drivers/media/rc/ite-cir.c | 1736 ++++++++++++++++++++
- drivers/media/rc/ite-cir.h | 481 ++++++
- drivers/media/rc/keymaps/Makefile | 4 +-
- drivers/media/rc/keymaps/rc-adstech-dvb-t-pci.c | 6 +-
- drivers/media/rc/keymaps/rc-avermedia-dvbt.c | 4 +-
- drivers/media/rc/keymaps/rc-avermedia-m135a.c | 2 +-
- .../media/rc/keymaps/rc-avermedia-m733a-rm-k6.c | 2 +-
- drivers/media/rc/keymaps/rc-avermedia-rm-ks.c | 2 +-
- drivers/media/rc/keymaps/rc-behold-columbus.c | 2 +-
- drivers/media/rc/keymaps/rc-behold.c | 2 +-
- drivers/media/rc/keymaps/rc-budget-ci-old.c | 3 +-
- drivers/media/rc/keymaps/rc-cinergy.c | 2 +-
- drivers/media/rc/keymaps/rc-dntv-live-dvb-t.c | 2 +-
- drivers/media/rc/keymaps/rc-encore-enltv.c | 4 +-
- drivers/media/rc/keymaps/rc-encore-enltv2.c | 2 +-
- drivers/media/rc/keymaps/rc-flydvb.c | 4 +-
- drivers/media/rc/keymaps/rc-hauppauge-new.c | 100 --
- drivers/media/rc/keymaps/rc-hauppauge.c | 241 +++
- drivers/media/rc/keymaps/rc-imon-mce.c | 2 +-
- drivers/media/rc/keymaps/rc-imon-pad.c | 2 +-
- drivers/media/rc/keymaps/rc-kworld-315u.c | 2 +-
- .../media/rc/keymaps/rc-kworld-plus-tv-analog.c | 2 +-
- drivers/media/rc/keymaps/rc-msi-tvanywhere-plus.c | 2 +-
- drivers/media/rc/keymaps/rc-nebula.c | 2 +-
- drivers/media/rc/keymaps/rc-norwood.c | 2 +-
- drivers/media/rc/keymaps/rc-pctv-sedna.c | 2 +-
- drivers/media/rc/keymaps/rc-pixelview-mk12.c | 2 +-
- drivers/media/rc/keymaps/rc-pixelview-new.c | 2 +-
- drivers/media/rc/keymaps/rc-pixelview.c | 2 +-
- drivers/media/rc/keymaps/rc-pv951.c | 4 +-
- drivers/media/rc/keymaps/rc-rc5-hauppauge-new.c | 141 --
- drivers/media/rc/keymaps/rc-rc5-tv.c | 81 -
- drivers/media/rc/keymaps/rc-rc6-mce.c | 2 +-
- .../media/rc/keymaps/rc-real-audio-220-32-keys.c | 2 +-
- drivers/media/rc/keymaps/rc-winfast.c | 22 +-
- drivers/media/rc/mceusb.c | 4 +-
- drivers/media/video/cx18/cx18-i2c.c | 2 +-
- drivers/media/video/cx23885/cx23885-input.c | 2 +-
- drivers/media/video/cx88/cx88-input.c | 4 +-
- drivers/media/video/em28xx/em28xx-cards.c | 10 +-
- drivers/media/video/hdpvr/hdpvr-i2c.c | 72 +-
- drivers/media/video/ir-kbd-i2c.c | 18 +-
- drivers/media/video/ivtv/ivtv-i2c.c | 5 +-
- drivers/media/video/pvrusb2/pvrusb2-i2c-core.c | 4 +-
- drivers/media/video/saa7134/saa7134-input.c | 2 +-
- drivers/staging/lirc/Kconfig | 12 -
- drivers/staging/lirc/Makefile | 2 -
- drivers/staging/lirc/TODO.lirc_zilog | 51 +-
- drivers/staging/lirc/lirc_imon.c | 2 +-
- drivers/staging/lirc/lirc_it87.c | 1027 ------------
- drivers/staging/lirc/lirc_it87.h | 116 --
- drivers/staging/lirc/lirc_ite8709.c | 542 ------
- drivers/staging/lirc/lirc_sasem.c | 2 +-
- drivers/staging/lirc/lirc_zilog.c | 814 ++++++----
- include/media/rc-map.h | 4 +-
- include/media/soc_camera.h | 2 +
- 67 files changed, 3128 insertions(+), 2513 deletions(-)
-
----
-diff --git a/Documentation/DocBook/v4l/lirc_device_interface.xml
b/Documentation/DocBook/v4l/lirc_device_interface.xml
-index 68134c0..0e0453f 100644
---- a/Documentation/DocBook/v4l/lirc_device_interface.xml
-+++ b/Documentation/DocBook/v4l/lirc_device_interface.xml
-@@ -45,7 +45,7 @@ describing an IR signal are read from the chardev.</para>
- <para>The data written to the chardev is a pulse/space sequence of integer
- values. Pulses and spaces are only marked implicitly by their position. The
- data must start and end with a pulse, therefore, the data must always include
--an unevent number of samples. The write function must block until the data has
-+an uneven number of samples. The write function must block until the data has
- been transmitted by the hardware.</para>
- </section>
-
-diff --git a/drivers/media/dvb/dvb-usb/a800.c b/drivers/media/dvb/dvb-usb/a800.c
-index 53b93a4..f8e9bf1 100644
---- a/drivers/media/dvb/dvb-usb/a800.c
-+++ b/drivers/media/dvb/dvb-usb/a800.c
-@@ -38,8 +38,8 @@ static int a800_identify_state(struct usb_device *udev, struct
dvb_usb_device_pr
- }
-
- static struct rc_map_table rc_map_a800_table[] = {
-- { 0x0201, KEY_PROG1 }, /* SOURCE */
-- { 0x0200, KEY_POWER }, /* POWER */
-+ { 0x0201, KEY_MODE }, /* SOURCE */
-+ { 0x0200, KEY_POWER2 }, /* POWER */
- { 0x0205, KEY_1 }, /* 1 */
- { 0x0206, KEY_2 }, /* 2 */
- { 0x0207, KEY_3 }, /* 3 */
-@@ -52,8 +52,8 @@ static struct rc_map_table rc_map_a800_table[] = {
- { 0x0212, KEY_LEFT }, /* L / DISPLAY */
- { 0x0211, KEY_0 }, /* 0 */
- { 0x0213, KEY_RIGHT }, /* R / CH RTN */
-- { 0x0217, KEY_PROG2 }, /* SNAP SHOT */
-- { 0x0210, KEY_PROG3 }, /* 16-CH PREV */
-+ { 0x0217, KEY_CAMERA }, /* SNAP SHOT */
-+ { 0x0210, KEY_LAST }, /* 16-CH PREV */
- { 0x021e, KEY_VOLUMEDOWN }, /* VOL DOWN */
- { 0x020c, KEY_ZOOM }, /* FULL SCREEN */
- { 0x021f, KEY_VOLUMEUP }, /* VOL UP */
-diff --git a/drivers/media/dvb/dvb-usb/digitv.c b/drivers/media/dvb/dvb-usb/digitv.c
-index f2dbce7..f6344cd 100644
---- a/drivers/media/dvb/dvb-usb/digitv.c
-+++ b/drivers/media/dvb/dvb-usb/digitv.c
-@@ -176,7 +176,7 @@ static struct rc_map_table rc_map_digitv_table[] = {
- { 0xaf59, KEY_AUX },
- { 0x5f5a, KEY_DVD },
- { 0x6f5a, KEY_POWER },
-- { 0x9f5a, KEY_MHP }, /* labelled 'Picture' */
-+ { 0x9f5a, KEY_CAMERA }, /* labelled 'Picture' */
- { 0xaf5a, KEY_AUDIO },
- { 0x5f65, KEY_INFO },
- { 0x6f65, KEY_F13 }, /* 16:9 */
-diff --git a/drivers/media/dvb/dvb-usb/dw2102.c b/drivers/media/dvb/dvb-usb/dw2102.c
-index 98cf302..f5b9da1 100644
---- a/drivers/media/dvb/dvb-usb/dw2102.c
-+++ b/drivers/media/dvb/dvb-usb/dw2102.c
-@@ -1224,8 +1224,8 @@ static int dw3101_tuner_attach(struct dvb_usb_adapter *adap)
- }
-
- static struct rc_map_table rc_map_dw210x_table[] = {
-- { 0xf80a, KEY_Q }, /*power*/
-- { 0xf80c, KEY_M }, /*mute*/
-+ { 0xf80a, KEY_POWER2 }, /*power*/
-+ { 0xf80c, KEY_MUTE }, /*mute*/
- { 0xf811, KEY_1 },
- { 0xf812, KEY_2 },
- { 0xf813, KEY_3 },
-@@ -1236,25 +1236,25 @@ static struct rc_map_table rc_map_dw210x_table[] = {
- { 0xf818, KEY_8 },
- { 0xf819, KEY_9 },
- { 0xf810, KEY_0 },
-- { 0xf81c, KEY_PAGEUP }, /*ch+*/
-- { 0xf80f, KEY_PAGEDOWN }, /*ch-*/
-- { 0xf81a, KEY_O }, /*vol+*/
-- { 0xf80e, KEY_Z }, /*vol-*/
-- { 0xf804, KEY_R }, /*rec*/
-- { 0xf809, KEY_D }, /*fav*/
-- { 0xf808, KEY_BACKSPACE }, /*rewind*/
-- { 0xf807, KEY_A }, /*fast*/
-- { 0xf80b, KEY_P }, /*pause*/
-- { 0xf802, KEY_ESC }, /*cancel*/
-- { 0xf803, KEY_G }, /*tab*/
-+ { 0xf81c, KEY_CHANNELUP }, /*ch+*/
-+ { 0xf80f, KEY_CHANNELDOWN }, /*ch-*/
-+ { 0xf81a, KEY_VOLUMEUP }, /*vol+*/
-+ { 0xf80e, KEY_VOLUMEDOWN }, /*vol-*/
-+ { 0xf804, KEY_RECORD }, /*rec*/
-+ { 0xf809, KEY_FAVORITES }, /*fav*/
-+ { 0xf808, KEY_REWIND }, /*rewind*/
-+ { 0xf807, KEY_FASTFORWARD }, /*fast*/
-+ { 0xf80b, KEY_PAUSE }, /*pause*/
-+ { 0xf802, KEY_ESC }, /*cancel*/
-+ { 0xf803, KEY_TAB }, /*tab*/
- { 0xf800, KEY_UP }, /*up*/
-- { 0xf81f, KEY_ENTER }, /*ok*/
-- { 0xf801, KEY_DOWN }, /*down*/
-- { 0xf805, KEY_C }, /*cap*/
-- { 0xf806, KEY_S }, /*stop*/
-- { 0xf840, KEY_F }, /*full*/
-- { 0xf81e, KEY_W }, /*tvmode*/
-- { 0xf81b, KEY_B }, /*recall*/
-+ { 0xf81f, KEY_OK }, /*ok*/
-+ { 0xf801, KEY_DOWN }, /*down*/
-+ { 0xf805, KEY_CAMERA }, /*cap*/
-+ { 0xf806, KEY_STOP }, /*stop*/
-+ { 0xf840, KEY_ZOOM }, /*full*/
-+ { 0xf81e, KEY_TV }, /*tvmode*/
-+ { 0xf81b, KEY_LAST }, /*recall*/
- };
-
- static struct rc_map_table rc_map_tevii_table[] = {
-diff --git a/drivers/media/dvb/dvb-usb/opera1.c b/drivers/media/dvb/dvb-usb/opera1.c
-index 1f1b7d6..7e569f4 100644
---- a/drivers/media/dvb/dvb-usb/opera1.c
-+++ b/drivers/media/dvb/dvb-usb/opera1.c
-@@ -342,23 +342,22 @@ static struct rc_map_table rc_map_opera1_table[] = {
- {0x49b6, KEY_8},
- {0x05fa, KEY_9},
- {0x45ba, KEY_0},
-- {0x09f6, KEY_UP}, /*chanup */
-- {0x1be5, KEY_DOWN}, /*chandown */
-- {0x5da3, KEY_LEFT}, /*voldown */
-- {0x5fa1, KEY_RIGHT}, /*volup */
-- {0x07f8, KEY_SPACE}, /*tab */
-- {0x1fe1, KEY_ENTER}, /*play ok */
-- {0x1be4, KEY_Z}, /*zoom */
-- {0x59a6, KEY_M}, /*mute */
-- {0x5ba5, KEY_F}, /*tv/f */
-- {0x19e7, KEY_R}, /*rec */
-- {0x01fe, KEY_S}, /*Stop */
-- {0x03fd, KEY_P}, /*pause */
-- {0x03fc, KEY_W}, /*<- -> */
-- {0x07f9, KEY_C}, /*capture */
-- {0x47b9, KEY_Q}, /*exit */
-- {0x43bc, KEY_O}, /*power */
--
-+ {0x09f6, KEY_CHANNELUP}, /*chanup */
-+ {0x1be5, KEY_CHANNELDOWN}, /*chandown */
-+ {0x5da3, KEY_VOLUMEDOWN}, /*voldown */
-+ {0x5fa1, KEY_VOLUMEUP}, /*volup */
-+ {0x07f8, KEY_SPACE}, /*tab */
-+ {0x1fe1, KEY_OK}, /*play ok */
-+ {0x1be4, KEY_ZOOM}, /*zoom */
-+ {0x59a6, KEY_MUTE}, /*mute */
-+ {0x5ba5, KEY_RADIO}, /*tv/f */
-+ {0x19e7, KEY_RECORD}, /*rec */
-+ {0x01fe, KEY_STOP}, /*Stop */
-+ {0x03fd, KEY_PAUSE}, /*pause */
-+ {0x03fc, KEY_SCREEN}, /*<- -> */
-+ {0x07f9, KEY_CAMERA}, /*capture */
-+ {0x47b9, KEY_ESC}, /*exit */
-+ {0x43bc, KEY_POWER2}, /*power */
- };
-
- static int opera1_rc_query(struct dvb_usb_device *dev, u32 * event, int *state)
-diff --git a/drivers/media/dvb/siano/sms-cards.c b/drivers/media/dvb/siano/sms-cards.c
-index 25b43e5..af121db 100644
---- a/drivers/media/dvb/siano/sms-cards.c
-+++ b/drivers/media/dvb/siano/sms-cards.c
-@@ -64,7 +64,7 @@ static struct sms_board sms_boards[] = {
- .type = SMS_NOVA_B0,
- .fw[DEVICE_MODE_ISDBT_BDA] = "sms1xxx-hcw-55xxx-isdbt-02.fw",
- .fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-hcw-55xxx-dvbt-02.fw",
-- .rc_codes = RC_MAP_RC5_HAUPPAUGE_NEW,
-+ .rc_codes = RC_MAP_HAUPPAUGE,
- .board_cfg.leds_power = 26,
- .board_cfg.led0 = 27,
- .board_cfg.led1 = 28,
-diff --git a/drivers/media/dvb/ttpci/budget-ci.c b/drivers/media/dvb/ttpci/budget-ci.c
-index b82756d..1d79ada 100644
---- a/drivers/media/dvb/ttpci/budget-ci.c
-+++ b/drivers/media/dvb/ttpci/budget-ci.c
-@@ -26,7 +26,7 @@
- * Or, point your browser to
http://www.gnu.org/copyleft/gpl.html
- *
- *
-- * the project's page is at
http://www.linuxtv.org/
-+ * the project's page is at
http://www.linuxtv.org/
- */
-
- #include <linux/module.h>
-@@ -102,6 +102,7 @@ struct budget_ci_ir {
- int rc5_device;
- u32 ir_key;
- bool have_command;
-+ bool full_rc5; /* Outputs a full RC5 code */
- };
-
- struct budget_ci {
-@@ -154,11 +155,18 @@ static void msp430_ir_interrupt(unsigned long data)
- return;
- budget_ci->ir.have_command = false;
-
-- /* FIXME: We should generate complete scancodes with device info */
- if (budget_ci->ir.rc5_device != IR_DEVICE_ANY &&
- budget_ci->ir.rc5_device != (command & 0x1f))
- return;
-
-+ if (budget_ci->ir.full_rc5) {
-+ rc_keydown(dev,
-+ budget_ci->ir.rc5_device <<8 | budget_ci->ir.ir_key,
-+ (command & 0x20) ? 1 : 0);
-+ return;
-+ }
-+
-+ /* FIXME: We should generate complete scancodes for all devices */
- rc_keydown(dev, budget_ci->ir.ir_key, (command & 0x20) ? 1 : 0);
- }
-
-@@ -206,7 +214,8 @@ static int msp430_ir_init(struct budget_ci *budget_ci)
- case 0x1011:
- case 0x1012:
- /* The hauppauge keymap is a superset of these remotes */
-- dev->map_name = RC_MAP_HAUPPAUGE_NEW;
-+ dev->map_name = RC_MAP_HAUPPAUGE;
-+ budget_ci->ir.full_rc5 = true;
-
- if (rc5_device < 0)
- budget_ci->ir.rc5_device = 0x1f;
-diff --git a/drivers/media/rc/Kconfig b/drivers/media/rc/Kconfig
-index 1143845..7f03142 100644
---- a/drivers/media/rc/Kconfig
-+++ b/drivers/media/rc/Kconfig
-@@ -135,6 +135,19 @@ config IR_MCEUSB
- To compile this driver as a module, choose M here: the
- module will be called mceusb.
-
-+config IR_ITE_CIR
-+ tristate "ITE Tech Inc. IT8712/IT8512 Consumer Infrared Transceiver"
-+ depends on PNP
-+ depends on RC_CORE
-+ ---help---
-+ Say Y here to enable support for integrated infrared receivers
-+ /transceivers made by ITE Tech Inc. These are found in
-+ several ASUS devices, like the ASUS Digimatrix or the ASUS
-+ EEEBox 1501U.
-+
-+ To compile this driver as a module, choose M here: the
-+ module will be called ite-cir.
-+
- config IR_NUVOTON
- tristate "Nuvoton w836x7hg Consumer Infrared Transceiver"
- depends on PNP
-diff --git a/drivers/media/rc/Makefile b/drivers/media/rc/Makefile
-index 67b4f7f..c6cfe70 100644
---- a/drivers/media/rc/Makefile
-+++ b/drivers/media/rc/Makefile
-@@ -14,6 +14,7 @@ obj-$(CONFIG_IR_LIRC_CODEC) += ir-lirc-codec.o
-
- # stand-alone IR receivers/transmitters
- obj-$(CONFIG_IR_IMON) += imon.o
-+obj-$(CONFIG_IR_ITE_CIR) += ite-cir.o
- obj-$(CONFIG_IR_MCEUSB) += mceusb.o
- obj-$(CONFIG_IR_NUVOTON) += nuvoton-cir.o
- obj-$(CONFIG_IR_ENE) += ene_ir.o
-diff --git a/drivers/media/rc/imon.c b/drivers/media/rc/imon.c
-index e7dc6b4..f714e1a 100644
---- a/drivers/media/rc/imon.c
-+++ b/drivers/media/rc/imon.c
-@@ -277,12 +277,21 @@ static const struct {
- u64 hw_code;
- u32 keycode;
- } imon_panel_key_table[] = {
-- { 0x000000000f00ffeell, KEY_PROG1 }, /* Go */
-+ { 0x000000000f00ffeell, KEY_MEDIA }, /* Go */
-+ { 0x000000001200ffeell, KEY_UP },
-+ { 0x000000001300ffeell, KEY_DOWN },
-+ { 0x000000001400ffeell, KEY_LEFT },
-+ { 0x000000001500ffeell, KEY_RIGHT },
-+ { 0x000000001600ffeell, KEY_ENTER },
-+ { 0x000000001700ffeell, KEY_ESC },
- { 0x000000001f00ffeell, KEY_AUDIO },
- { 0x000000002000ffeell, KEY_VIDEO },
- { 0x000000002100ffeell, KEY_CAMERA },
- { 0x000000002700ffeell, KEY_DVD },
- { 0x000000002300ffeell, KEY_TV },
-+ { 0x000000002b00ffeell, KEY_EXIT },
-+ { 0x000000002c00ffeell, KEY_SELECT },
-+ { 0x000000002d00ffeell, KEY_MENU },
- { 0x000000000500ffeell, KEY_PREVIOUS },
- { 0x000000000700ffeell, KEY_REWIND },
- { 0x000000000400ffeell, KEY_STOP },
-diff --git a/drivers/media/rc/ir-nec-decoder.c b/drivers/media/rc/ir-nec-decoder.c
-index 7b58b4a..63ee722 100644
---- a/drivers/media/rc/ir-nec-decoder.c
-+++ b/drivers/media/rc/ir-nec-decoder.c
-@@ -49,6 +49,7 @@ static int ir_nec_decode(struct rc_dev *dev, struct ir_raw_event ev)
- struct nec_dec *data = &dev->raw->nec;
- u32 scancode;
- u8 address, not_address, command, not_command;
-+ bool send_32bits = false;
-
- if (!(dev->raw->enabled_protocols & RC_TYPE_NEC))
- return 0;
-@@ -164,10 +165,15 @@ static int ir_nec_decode(struct rc_dev *dev, struct ir_raw_event
ev)
- if ((command ^ not_command) != 0xff) {
- IR_dprintk(1, "NEC checksum error: received 0x%08x\n",
- data->bits);
-- break;
-+ send_32bits = true;
- }
-
-- if ((address ^ not_address) != 0xff) {
-+ if (send_32bits) {
-+ /* NEC transport, but modified protocol, used by at
-+ * least Apple and TiVo remotes */
-+ scancode = data->bits;
-+ IR_dprintk(1, "NEC (modified) scancode 0x%08x\n", scancode);
-+ } else if ((address ^ not_address) != 0xff) {
- /* Extended NEC */
- scancode = address << 16 |
- not_address << 8 |
-diff --git a/drivers/media/rc/ite-cir.c b/drivers/media/rc/ite-cir.c
-new file mode 100644
-index 0000000..9be6a83
---- /dev/null
-+++ b/drivers/media/rc/ite-cir.c
-@@ -0,0 +1,1736 @@
-+/*
-+ * Driver for ITE Tech Inc. IT8712F/IT8512 CIR
-+ *
-+ * Copyright (C) 2010 Juan Jesús García de Soria <skandalfo(a)gmail.com>
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License as
-+ * published by the Free Software Foundation; either version 2 of the
-+ * License, or (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful, but
-+ * WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ * General Public License for more details.
-+ *
-+ * 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.
-+ *
-+ * Inspired by the original lirc_it87 and lirc_ite8709 drivers, on top of the
-+ * skeleton provided by the nuvoton-cir driver.
-+ *
-+ * The lirc_it87 driver was originally written by Hans-Gunter Lutke Uphues
-+ * <hg_lu(a)web.de> in 2001, with enhancements by Christoph Bartelmus
-+ * <lirc(a)bartelmus.de>, Andrew Calkin <r_tay(a)hotmail.com> and James Edwards
-+ * <jimbo-lirc(a)edwardsclan.net>.
-+ *
-+ * The lirc_ite8709 driver was written by Grégory Lardière
-+ * <spmf2004-lirc(a)yahoo.fr> in 2008.
-+ */
-+
-+#include <linux/kernel.h>
-+#include <linux/module.h>
-+#include <linux/pnp.h>
-+#include <linux/io.h>
-+#include <linux/interrupt.h>
-+#include <linux/sched.h>
-+#include <linux/slab.h>
-+#include <linux/input.h>
-+#include <linux/bitops.h>
-+#include <media/rc-core.h>
-+#include <linux/pci_ids.h>
-+
-+#include "ite-cir.h"
-+
-+/* module parameters */
-+
-+/* debug level */
-+static int debug;
-+module_param(debug, int, S_IRUGO | S_IWUSR);
-+MODULE_PARM_DESC(debug, "Enable debugging output");
-+
-+/* low limit for RX carrier freq, Hz, 0 for no RX demodulation */
-+static int rx_low_carrier_freq;
-+module_param(rx_low_carrier_freq, int, S_IRUGO | S_IWUSR);
-+MODULE_PARM_DESC(rx_low_carrier_freq, "Override low RX carrier frequency, Hz,
"
-+ "0 for no RX demodulation");
-+
-+/* high limit for RX carrier freq, Hz, 0 for no RX demodulation */
-+static int rx_high_carrier_freq;
-+module_param(rx_high_carrier_freq, int, S_IRUGO | S_IWUSR);
-+MODULE_PARM_DESC(rx_high_carrier_freq, "Override high RX carrier frequency, "
-+ "Hz, 0 for no RX demodulation");
-+
-+/* override tx carrier frequency */
-+static int tx_carrier_freq;
-+module_param(tx_carrier_freq, int, S_IRUGO | S_IWUSR);
-+MODULE_PARM_DESC(tx_carrier_freq, "Override TX carrier frequency, Hz");
-+
-+/* override tx duty cycle */
-+static int tx_duty_cycle;
-+module_param(tx_duty_cycle, int, S_IRUGO | S_IWUSR);
-+MODULE_PARM_DESC(tx_duty_cycle, "Override TX duty cycle, 1-100");
-+
-+/* override default sample period */
-+static long sample_period;
-+module_param(sample_period, long, S_IRUGO | S_IWUSR);
-+MODULE_PARM_DESC(sample_period, "Override carrier sample period, us");
-+
-+/* override detected model id */
-+static int model_number = -1;
-+module_param(model_number, int, S_IRUGO | S_IWUSR);
-+MODULE_PARM_DESC(model_number, "Use this model number, don't
autodetect");
-+
-+
-+/* HW-independent code functions */
-+
-+/* check whether carrier frequency is high frequency */
-+static inline bool ite_is_high_carrier_freq(unsigned int freq)
-+{
-+ return freq >= ITE_HCF_MIN_CARRIER_FREQ;
-+}
-+
-+/* get the bits required to program the carrier frequency in CFQ bits,
-+ * unshifted */
-+static u8 ite_get_carrier_freq_bits(unsigned int freq)
-+{
-+ if (ite_is_high_carrier_freq(freq)) {
-+ if (freq < 425000)
-+ return ITE_CFQ_400;
-+
-+ else if (freq < 465000)
-+ return ITE_CFQ_450;
-+
-+ else if (freq < 490000)
-+ return ITE_CFQ_480;
-+
-+ else
-+ return ITE_CFQ_500;
-+ } else {
-+ /* trim to limits */
-+ if (freq < ITE_LCF_MIN_CARRIER_FREQ)
-+ freq = ITE_LCF_MIN_CARRIER_FREQ;
-+ if (freq > ITE_LCF_MAX_CARRIER_FREQ)
-+ freq = ITE_LCF_MAX_CARRIER_FREQ;
-+
-+ /* convert to kHz and subtract the base freq */
-+ freq =
-+ DIV_ROUND_CLOSEST(freq - ITE_LCF_MIN_CARRIER_FREQ,
-+ 1000);
-+
-+ return (u8) freq;
-+ }
-+}
-+
-+/* get the bits required to program the pulse with in TXMPW */
-+static u8 ite_get_pulse_width_bits(unsigned int freq, int duty_cycle)
-+{
-+ unsigned long period_ns, on_ns;
-+
-+ /* sanitize freq into range */
-+ if (freq < ITE_LCF_MIN_CARRIER_FREQ)
-+ freq = ITE_LCF_MIN_CARRIER_FREQ;
-+ if (freq > ITE_HCF_MAX_CARRIER_FREQ)
-+ freq = ITE_HCF_MAX_CARRIER_FREQ;
-+
-+ period_ns = 1000000000UL / freq;
-+ on_ns = period_ns * duty_cycle / 100;
-+
-+ if (ite_is_high_carrier_freq(freq)) {
-+ if (on_ns < 750)
-+ return ITE_TXMPW_A;
-+
-+ else if (on_ns < 850)
-+ return ITE_TXMPW_B;
-+
-+ else if (on_ns < 950)
-+ return ITE_TXMPW_C;
-+
-+ else if (on_ns < 1080)
-+ return ITE_TXMPW_D;
-+
-+ else
-+ return ITE_TXMPW_E;
-+ } else {
-+ if (on_ns < 6500)
-+ return ITE_TXMPW_A;
-+
-+ else if (on_ns < 7850)
-+ return ITE_TXMPW_B;
-+
-+ else if (on_ns < 9650)
-+ return ITE_TXMPW_C;
-+
-+ else if (on_ns < 11950)
-+ return ITE_TXMPW_D;
-+
-+ else
-+ return ITE_TXMPW_E;
-+ }
-+}
-+
-+/* decode raw bytes as received by the hardware, and push them to the ir-core
-+ * layer */
-+static void ite_decode_bytes(struct ite_dev *dev, const u8 * data, int
-+ length)
-+{
-+ u32 sample_period;
-+ unsigned long *ldata;
-+ unsigned int next_one, next_zero, size;
-+ DEFINE_IR_RAW_EVENT(ev);
-+
-+ if (length == 0)
-+ return;
-+
-+ sample_period = dev->params.sample_period;
-+ ldata = (unsigned long *)data;
-+ size = length << 3;
-+ next_one = generic_find_next_le_bit(ldata, size, 0);
-+ if (next_one > 0) {
-+ ev.pulse = true;
-+ ev.duration =
-+ ITE_BITS_TO_NS(next_one, sample_period);
-+ ir_raw_event_store_with_filter(dev->rdev, &ev);
-+ }
-+
-+ while (next_one < size) {
-+ next_zero = generic_find_next_zero_le_bit(ldata, size, next_one + 1);
-+ ev.pulse = false;
-+ ev.duration = ITE_BITS_TO_NS(next_zero - next_one, sample_period);
-+ ir_raw_event_store_with_filter(dev->rdev, &ev);
-+
-+ if (next_zero < size) {
-+ next_one =
-+ generic_find_next_le_bit(ldata,
-+ size,
-+ next_zero + 1);
-+ ev.pulse = true;
-+ ev.duration =
-+ ITE_BITS_TO_NS(next_one - next_zero,
-+ sample_period);
-+ ir_raw_event_store_with_filter
-+ (dev->rdev, &ev);
-+ } else
-+ next_one = size;
-+ }
-+
-+ ir_raw_event_handle(dev->rdev);
-+
-+ ite_dbg_verbose("decoded %d bytes.", length);
-+}
-+
-+/* set all the rx/tx carrier parameters; this must be called with the device
-+ * spinlock held */
-+static void ite_set_carrier_params(struct ite_dev *dev)
-+{
-+ unsigned int freq, low_freq, high_freq;
-+ int allowance;
-+ bool use_demodulator;
-+ bool for_tx = dev->transmitting;
-+
-+ ite_dbg("%s called", __func__);
-+
-+ if (for_tx) {
-+ /* we don't need no stinking calculations */
-+ freq = dev->params.tx_carrier_freq;
-+ allowance = ITE_RXDCR_DEFAULT;
-+ use_demodulator = false;
-+ } else {
-+ low_freq = dev->params.rx_low_carrier_freq;
-+ high_freq = dev->params.rx_high_carrier_freq;
-+
-+ if (low_freq == 0) {
-+ /* don't demodulate */
-+ freq =
-+ ITE_DEFAULT_CARRIER_FREQ;
-+ allowance = ITE_RXDCR_DEFAULT;
-+ use_demodulator = false;
-+ } else {
-+ /* calculate the middle freq */
-+ freq = (low_freq + high_freq) / 2;
-+
-+ /* calculate the allowance */
-+ allowance =
-+ DIV_ROUND_CLOSEST(10000 * (high_freq - low_freq),
-+ ITE_RXDCR_PER_10000_STEP
-+ * (high_freq + low_freq));
-+
-+ if (allowance < 1)
-+ allowance = 1;
-+
-+ if (allowance > ITE_RXDCR_MAX)
-+ allowance = ITE_RXDCR_MAX;
-+ }
-+ }
-+
-+ /* set the carrier parameters in a device-dependent way */
-+ dev->params.set_carrier_params(dev, ite_is_high_carrier_freq(freq),
-+ use_demodulator, ite_get_carrier_freq_bits(freq), allowance,
-+ ite_get_pulse_width_bits(freq, dev->params.tx_duty_cycle));
-+}
-+
-+/* interrupt service routine for incoming and outgoing CIR data */
-+static irqreturn_t ite_cir_isr(int irq, void *data)
-+{
-+ struct ite_dev *dev = data;
-+ unsigned long flags;
-+ irqreturn_t ret = IRQ_RETVAL(IRQ_NONE);
-+ u8 rx_buf[ITE_RX_FIFO_LEN];
-+ int rx_bytes;
-+ int iflags;
-+
-+ ite_dbg_verbose("%s firing", __func__);
-+
-+ /* grab the spinlock */
-+ spin_lock_irqsave(&dev->lock, flags);
-+
-+ /* read the interrupt flags */
-+ iflags = dev->params.get_irq_causes(dev);
-+
-+ /* check for the receive interrupt */
-+ if (iflags & (ITE_IRQ_RX_FIFO | ITE_IRQ_RX_FIFO_OVERRUN)) {
-+ /* read the FIFO bytes */
-+ rx_bytes =
-+ dev->params.get_rx_bytes(dev, rx_buf,
-+ ITE_RX_FIFO_LEN);
-+
-+ if (rx_bytes > 0) {
-+ /* drop the spinlock, since the ir-core layer
-+ * may call us back again through
-+ * ite_s_idle() */
-+ spin_unlock_irqrestore(&dev->
-+ lock,
-+ flags);
-+
-+ /* decode the data we've just received */
-+ ite_decode_bytes(dev, rx_buf,
-+ rx_bytes);
-+
-+ /* reacquire the spinlock */
-+ spin_lock_irqsave(&dev->lock,
-+ flags);
-+
-+ /* mark the interrupt as serviced */
-+ ret = IRQ_RETVAL(IRQ_HANDLED);
-+ }
-+ } else if (iflags & ITE_IRQ_TX_FIFO) {
-+ /* FIFO space available interrupt */
-+ ite_dbg_verbose("got interrupt for TX FIFO");
-+
-+ /* wake any sleeping transmitter */
-+ wake_up_interruptible(&dev->tx_queue);
-+
-+ /* mark the interrupt as serviced */
-+ ret = IRQ_RETVAL(IRQ_HANDLED);
-+ }
-+
-+ /* drop the spinlock */
-+ spin_unlock_irqrestore(&dev->lock, flags);
-+
-+ ite_dbg_verbose("%s done returning %d", __func__, (int)ret);
-+
-+ return ret;
-+}
-+
-+/* set the rx carrier freq range, guess it's in Hz... */
-+static int ite_set_rx_carrier_range(struct rc_dev *rcdev, u32 carrier_low, u32
-+ carrier_high)
-+{
-+ unsigned long flags;
-+ struct ite_dev *dev = rcdev->priv;
-+
-+ spin_lock_irqsave(&dev->lock, flags);
-+ dev->params.rx_low_carrier_freq = carrier_low;
-+ dev->params.rx_high_carrier_freq = carrier_high;
-+ ite_set_carrier_params(dev);
-+ spin_unlock_irqrestore(&dev->lock, flags);
-+
-+ return 0;
-+}
-+
-+/* set the tx carrier freq, guess it's in Hz... */
-+static int ite_set_tx_carrier(struct rc_dev *rcdev, u32 carrier)
-+{
-+ unsigned long flags;
-+ struct ite_dev *dev = rcdev->priv;
-+
-+ spin_lock_irqsave(&dev->lock, flags);
-+ dev->params.tx_carrier_freq = carrier;
-+ ite_set_carrier_params(dev);
-+ spin_unlock_irqrestore(&dev->lock, flags);
-+
-+ return 0;
-+}
-+
-+/* set the tx duty cycle by controlling the pulse width */
-+static int ite_set_tx_duty_cycle(struct rc_dev *rcdev, u32 duty_cycle)
-+{
-+ unsigned long flags;
-+ struct ite_dev *dev = rcdev->priv;
-+
-+ spin_lock_irqsave(&dev->lock, flags);
-+ dev->params.tx_duty_cycle = duty_cycle;
-+ ite_set_carrier_params(dev);
-+ spin_unlock_irqrestore(&dev->lock, flags);
-+
-+ return 0;
-+}
-+
-+/* transmit out IR pulses; what you get here is a batch of alternating
-+ * pulse/space/pulse/space lengths that we should write out completely through
-+ * the FIFO, blocking on a full FIFO */
-+static int ite_tx_ir(struct rc_dev *rcdev, int *txbuf, u32 n)
-+{
-+ unsigned long flags;
-+ struct ite_dev *dev = rcdev->priv;
-+ bool is_pulse = false;
-+ int remaining_us, fifo_avail, fifo_remaining, last_idx = 0;
-+ int max_rle_us, next_rle_us;
-+ int ret = n;
-+ u8 last_sent[ITE_TX_FIFO_LEN];
-+ u8 val;
-+
-+ ite_dbg("%s called", __func__);
-+
-+ /* clear the array just in case */
-+ memset(last_sent, 0, ARRAY_SIZE(last_sent));
-+
-+ /* n comes in bytes; convert to ints */
-+ n /= sizeof(int);
-+
-+ spin_lock_irqsave(&dev->lock, flags);
-+
-+ /* let everybody know we're now transmitting */
-+ dev->transmitting = true;
-+
-+ /* and set the carrier values for transmission */
-+ ite_set_carrier_params(dev);
-+
-+ /* calculate how much time we can send in one byte */
-+ max_rle_us =
-+ (ITE_BAUDRATE_DIVISOR * dev->params.sample_period *
-+ ITE_TX_MAX_RLE) / 1000;
-+
-+ /* disable the receiver */
-+ dev->params.disable_rx(dev);
-+
-+ /* this is where we'll begin filling in the FIFO, until it's full.
-+ * then we'll just activate the interrupt, wait for it to wake us up
-+ * again, disable it, continue filling the FIFO... until everything
-+ * has been pushed out */
-+ fifo_avail =
-+ ITE_TX_FIFO_LEN - dev->params.get_tx_used_slots(dev);
-+
-+ while (n > 0 && dev->in_use) {
-+ /* transmit the next sample */
-+ is_pulse = !is_pulse;
-+ remaining_us = *(txbuf++);
-+ n--;
-+
-+ ite_dbg("%s: %ld",
-+ ((is_pulse) ? "pulse" : "space"),
-+ (long int)
-+ remaining_us);
-+
-+ /* repeat while the pulse is non-zero length */
-+ while (remaining_us > 0 && dev->in_use) {
-+ if (remaining_us > max_rle_us)
-+ next_rle_us = max_rle_us;
-+
-+ else
-+ next_rle_us = remaining_us;
-+
-+ remaining_us -= next_rle_us;
-+
-+ /* check what's the length we have to pump out */
-+ val = (ITE_TX_MAX_RLE * next_rle_us) / max_rle_us;
-+
-+ /* put it into the sent buffer */
-+ last_sent[last_idx++] = val;
-+ last_idx &= (ITE_TX_FIFO_LEN);
-+
-+ /* encode it for 7 bits */
-+ val = (val - 1) & ITE_TX_RLE_MASK;
-+
-+ /* take into account pulse/space prefix */
-+ if (is_pulse)
-+ val |= ITE_TX_PULSE;
-+
-+ else
-+ val |= ITE_TX_SPACE;
-+
-+ /*
-+ * if we get to 0 available, read again, just in case
-+ * some other slot got freed
-+ */
-+ if (fifo_avail <= 0)
-+ fifo_avail = ITE_TX_FIFO_LEN - dev->params.get_tx_used_slots(dev);
-+
-+ /* if it's still full */
-+ if (fifo_avail <= 0) {
-+ /* enable the tx interrupt */
-+ dev->params.
-+ enable_tx_interrupt(dev);
-+
-+ /* drop the spinlock */
-+ spin_unlock_irqrestore(&dev->lock, flags);
-+
-+ /* wait for the FIFO to empty enough */
-+ wait_event_interruptible(dev->tx_queue, (fifo_avail = ITE_TX_FIFO_LEN -
dev->params.get_tx_used_slots(dev)) >= 8);
-+
-+ /* get the spinlock again */
-+ spin_lock_irqsave(&dev->lock, flags);
-+
-+ /* disable the tx interrupt again. */
-+ dev->params.
-+ disable_tx_interrupt(dev);
-+ }
-+
-+ /* now send the byte through the FIFO */
-+ dev->params.put_tx_byte(dev, val);
-+ fifo_avail--;
-+ }
-+ }
-+
-+ /* wait and don't return until the whole FIFO has been sent out;
-+ * otherwise we could configure the RX carrier params instead of the
-+ * TX ones while the transmission is still being performed! */
-+ fifo_remaining = dev->params.get_tx_used_slots(dev);
-+ remaining_us = 0;
-+ while (fifo_remaining > 0) {
-+ fifo_remaining--;
-+ last_idx--;
-+ last_idx &= (ITE_TX_FIFO_LEN - 1);
-+ remaining_us += last_sent[last_idx];
-+ }
-+ remaining_us = (remaining_us * max_rle_us) / (ITE_TX_MAX_RLE);
-+
-+ /* drop the spinlock while we sleep */
-+ spin_unlock_irqrestore(&dev->lock, flags);
-+
-+ /* sleep remaining_us microseconds */
-+ mdelay(DIV_ROUND_UP(remaining_us, 1000));
-+
-+ /* reacquire the spinlock */
-+ spin_lock_irqsave(&dev->lock, flags);
-+
-+ /* now we're not transmitting anymore */
-+ dev->transmitting = false;
-+
-+ /* and set the carrier values for reception */
-+ ite_set_carrier_params(dev);
-+
-+ /* reenable the receiver */
-+ if (dev->in_use)
-+ dev->params.enable_rx(dev);
-+
-+ /* notify transmission end */
-+ wake_up_interruptible(&dev->tx_ended);
-+
-+ spin_unlock_irqrestore(&dev->lock, flags);
-+
-+ return ret;
-+}
-+
-+/* idle the receiver if needed */
-+static void ite_s_idle(struct rc_dev *rcdev, bool enable)
-+{
-+ unsigned long flags;
-+ struct ite_dev *dev = rcdev->priv;
-+
-+ ite_dbg("%s called", __func__);
-+
-+ if (enable) {
-+ spin_lock_irqsave(&dev->lock, flags);
-+ dev->params.idle_rx(dev);
-+ spin_unlock_irqrestore(&dev->lock, flags);
-+ }
-+}
-+
-+
-+/* IT8712F HW-specific functions */
-+
-+/* retrieve a bitmask of the current causes for a pending interrupt; this may
-+ * be composed of ITE_IRQ_TX_FIFO, ITE_IRQ_RX_FIFO and ITE_IRQ_RX_FIFO_OVERRUN
-+ * */
-+static int it87_get_irq_causes(struct ite_dev *dev)
-+{
-+ u8 iflags;
-+ int ret = 0;
-+
-+ ite_dbg("%s called", __func__);
-+
-+ /* read the interrupt flags */
-+ iflags = inb(dev->cir_addr + IT87_IIR) & IT87_II;
-+
-+ switch (iflags) {
-+ case IT87_II_RXDS:
-+ ret = ITE_IRQ_RX_FIFO;
-+ break;
-+ case IT87_II_RXFO:
-+ ret = ITE_IRQ_RX_FIFO_OVERRUN;
-+ break;
-+ case IT87_II_TXLDL:
-+ ret = ITE_IRQ_TX_FIFO;
-+ break;
-+ }
-+
-+ return ret;
-+}
-+
-+/* set the carrier parameters; to be called with the spinlock held */
-+static void it87_set_carrier_params(struct ite_dev *dev, bool high_freq,
-+ bool use_demodulator,
-+ u8 carrier_freq_bits, u8 allowance_bits,
-+ u8 pulse_width_bits)
-+{
-+ u8 val;
-+
-+ ite_dbg("%s called", __func__);
-+
-+ /* program the RCR register */
-+ val = inb(dev->cir_addr + IT87_RCR)
-+ & ~(IT87_HCFS | IT87_RXEND | IT87_RXDCR);
-+
-+ if (high_freq)
-+ val |= IT87_HCFS;
-+
-+ if (use_demodulator)
-+ val |= IT87_RXEND;
-+
-+ val |= allowance_bits;
-+
-+ outb(val, dev->cir_addr + IT87_RCR);
-+
-+ /* program the TCR2 register */
-+ outb((carrier_freq_bits << IT87_CFQ_SHIFT) | pulse_width_bits,
-+ dev->cir_addr + IT87_TCR2);
-+}
-+
-+/* read up to buf_size bytes from the RX FIFO; to be called with the spinlock
-+ * held */
-+static int it87_get_rx_bytes(struct ite_dev *dev, u8 * buf, int buf_size)
-+{
-+ int fifo, read = 0;
-+
-+ ite_dbg("%s called", __func__);
-+
-+ /* read how many bytes are still in the FIFO */
-+ fifo = inb(dev->cir_addr + IT87_RSR) & IT87_RXFBC;
-+
-+ while (fifo > 0 && buf_size > 0) {
-+ *(buf++) = inb(dev->cir_addr + IT87_DR);
-+ fifo--;
-+ read++;
-+ buf_size--;
-+ }
-+
-+ return read;
-+}
-+
-+/* return how many bytes are still in the FIFO; this will be called
-+ * with the device spinlock NOT HELD while waiting for the TX FIFO to get
-+ * empty; let's expect this won't be a problem */
-+static int it87_get_tx_used_slots(struct ite_dev *dev)
-+{
-+ ite_dbg("%s called", __func__);
-+
-+ return inb(dev->cir_addr + IT87_TSR) & IT87_TXFBC;
-+}
-+
-+/* put a byte to the TX fifo; this should be called with the spinlock held */
-+static void it87_put_tx_byte(struct ite_dev *dev, u8 value)
-+{
-+ outb(value, dev->cir_addr + IT87_DR);
-+}
-+
-+/* idle the receiver so that we won't receive samples until another
-+ pulse is detected; this must be called with the device spinlock held */
-+static void it87_idle_rx(struct ite_dev *dev)
-+{
-+ ite_dbg("%s called", __func__);
-+
-+ /* disable streaming by clearing RXACT writing it as 1 */
-+ outb(inb(dev->cir_addr + IT87_RCR) | IT87_RXACT,
-+ dev->cir_addr + IT87_RCR);
-+
-+ /* clear the FIFO */
-+ outb(inb(dev->cir_addr + IT87_TCR1) | IT87_FIFOCLR,
-+ dev->cir_addr + IT87_TCR1);
-+}
-+
-+/* disable the receiver; this must be called with the device spinlock held */
-+static void it87_disable_rx(struct ite_dev *dev)
-+{
-+ ite_dbg("%s called", __func__);
-+
-+ /* disable the receiver interrupts */
-+ outb(inb(dev->cir_addr + IT87_IER) & ~(IT87_RDAIE | IT87_RFOIE),
-+ dev->cir_addr + IT87_IER);
-+
-+ /* disable the receiver */
-+ outb(inb(dev->cir_addr + IT87_RCR) & ~IT87_RXEN,
-+ dev->cir_addr + IT87_RCR);
-+
-+ /* clear the FIFO and RXACT (actually RXACT should have been cleared
-+ * in the previous outb() call) */
-+ it87_idle_rx(dev);
-+}
-+
-+/* enable the receiver; this must be called with the device spinlock held */
-+static void it87_enable_rx(struct ite_dev *dev)
-+{
-+ ite_dbg("%s called", __func__);
-+
-+ /* enable the receiver by setting RXEN */
-+ outb(inb(dev->cir_addr + IT87_RCR) | IT87_RXEN,
-+ dev->cir_addr + IT87_RCR);
-+
-+ /* just prepare it to idle for the next reception */
-+ it87_idle_rx(dev);
-+
-+ /* enable the receiver interrupts and master enable flag */
-+ outb(inb(dev->cir_addr + IT87_IER) | IT87_RDAIE | IT87_RFOIE | IT87_IEC,
-+ dev->cir_addr + IT87_IER);
-+}
-+
-+/* disable the transmitter interrupt; this must be called with the device
-+ * spinlock held */
-+static void it87_disable_tx_interrupt(struct ite_dev *dev)
-+{
-+ ite_dbg("%s called", __func__);
-+
-+ /* disable the transmitter interrupts */
-+ outb(inb(dev->cir_addr + IT87_IER) & ~IT87_TLDLIE,
-+ dev->cir_addr + IT87_IER);
-+}
-+
-+/* enable the transmitter interrupt; this must be called with the device
-+ * spinlock held */
-+static void it87_enable_tx_interrupt(struct ite_dev *dev)
-+{
-+ ite_dbg("%s called", __func__);
-+
-+ /* enable the transmitter interrupts and master enable flag */
-+ outb(inb(dev->cir_addr + IT87_IER) | IT87_TLDLIE | IT87_IEC,
-+ dev->cir_addr + IT87_IER);
-+}
-+
-+/* disable the device; this must be called with the device spinlock held */
-+static void it87_disable(struct ite_dev *dev)
-+{
-+ ite_dbg("%s called", __func__);
-+
-+ /* clear out all interrupt enable flags */
-+ outb(inb(dev->cir_addr + IT87_IER) &
-+ ~(IT87_IEC | IT87_RFOIE | IT87_RDAIE | IT87_TLDLIE),
-+ dev->cir_addr + IT87_IER);
-+
-+ /* disable the receiver */
-+ it87_disable_rx(dev);
-+
-+ /* erase the FIFO */
-+ outb(IT87_FIFOCLR | inb(dev->cir_addr + IT87_TCR1),
-+ dev->cir_addr + IT87_TCR1);
-+}
-+
-+/* initialize the hardware */
-+static void it87_init_hardware(struct ite_dev *dev)
-+{
-+ ite_dbg("%s called", __func__);
-+
-+ /* enable just the baud rate divisor register,
-+ disabling all the interrupts at the same time */
-+ outb((inb(dev->cir_addr + IT87_IER) &
-+ ~(IT87_IEC | IT87_RFOIE | IT87_RDAIE | IT87_TLDLIE)) | IT87_BR,
-+ dev->cir_addr + IT87_IER);
-+
-+ /* write out the baud rate divisor */
-+ outb(ITE_BAUDRATE_DIVISOR & 0xff, dev->cir_addr + IT87_BDLR);
-+ outb((ITE_BAUDRATE_DIVISOR >> 8) & 0xff, dev->cir_addr + IT87_BDHR);
-+
-+ /* disable the baud rate divisor register again */
-+ outb(inb(dev->cir_addr + IT87_IER) & ~IT87_BR,
-+ dev->cir_addr + IT87_IER);
-+
-+ /* program the RCR register defaults */
-+ outb(ITE_RXDCR_DEFAULT, dev->cir_addr + IT87_RCR);
-+
-+ /* program the TCR1 register */
-+ outb(IT87_TXMPM_DEFAULT | IT87_TXENDF | IT87_TXRLE
-+ | IT87_FIFOTL_DEFAULT | IT87_FIFOCLR,
-+ dev->cir_addr + IT87_TCR1);
-+
-+ /* program the carrier parameters */
-+ ite_set_carrier_params(dev);
-+}
-+
-+/* IT8512F on ITE8708 HW-specific functions */
-+
-+/* retrieve a bitmask of the current causes for a pending interrupt; this may
-+ * be composed of ITE_IRQ_TX_FIFO, ITE_IRQ_RX_FIFO and ITE_IRQ_RX_FIFO_OVERRUN
-+ * */
-+static int it8708_get_irq_causes(struct ite_dev *dev)
-+{
-+ u8 iflags;
-+ int ret = 0;
-+
-+ ite_dbg("%s called", __func__);
-+
-+ /* read the interrupt flags */
-+ iflags = inb(dev->cir_addr + IT8708_C0IIR);
-+
-+ if (iflags & IT85_TLDLI)
-+ ret |= ITE_IRQ_TX_FIFO;
-+ if (iflags & IT85_RDAI)
-+ ret |= ITE_IRQ_RX_FIFO;
-+ if (iflags & IT85_RFOI)
-+ ret |= ITE_IRQ_RX_FIFO_OVERRUN;
-+
-+ return ret;
-+}
-+
-+/* set the carrier parameters; to be called with the spinlock held */
-+static void it8708_set_carrier_params(struct ite_dev *dev, bool high_freq,
-+ bool use_demodulator,
-+ u8 carrier_freq_bits, u8 allowance_bits,
-+ u8 pulse_width_bits)
-+{
-+ u8 val;
-+
-+ ite_dbg("%s called", __func__);
-+
-+ /* program the C0CFR register, with HRAE=1 */
-+ outb(inb(dev->cir_addr + IT8708_BANKSEL) | IT8708_HRAE,
-+ dev->cir_addr + IT8708_BANKSEL);
-+
-+ val = (inb(dev->cir_addr + IT8708_C0CFR)
-+ & ~(IT85_HCFS | IT85_CFQ)) | carrier_freq_bits;
-+
-+ if (high_freq)
-+ val |= IT85_HCFS;
-+
-+ outb(val, dev->cir_addr + IT8708_C0CFR);
-+
-+ outb(inb(dev->cir_addr + IT8708_BANKSEL) & ~IT8708_HRAE,
-+ dev->cir_addr + IT8708_BANKSEL);
-+
-+ /* program the C0RCR register */
-+ val = inb(dev->cir_addr + IT8708_C0RCR)
-+ & ~(IT85_RXEND | IT85_RXDCR);
-+
-+ if (use_demodulator)
-+ val |= IT85_RXEND;
-+
-+ val |= allowance_bits;
-+
-+ outb(val, dev->cir_addr + IT8708_C0RCR);
-+
-+ /* program the C0TCR register */
-+ val = inb(dev->cir_addr + IT8708_C0TCR) & ~IT85_TXMPW;
-+ val |= pulse_width_bits;
-+ outb(val, dev->cir_addr + IT8708_C0TCR);
-+}
-+
-+/* read up to buf_size bytes from the RX FIFO; to be called with the spinlock
-+ * held */
-+static int it8708_get_rx_bytes(struct ite_dev *dev, u8 * buf, int buf_size)
-+{
-+ int fifo, read = 0;
-+
-+ ite_dbg("%s called", __func__);
-+
-+ /* read how many bytes are still in the FIFO */
-+ fifo = inb(dev->cir_addr + IT8708_C0RFSR) & IT85_RXFBC;
-+
-+ while (fifo > 0 && buf_size > 0) {
-+ *(buf++) = inb(dev->cir_addr + IT8708_C0DR);
-+ fifo--;
-+ read++;
-+ buf_size--;
-+ }
-+
-+ return read;
-+}
-+
-+/* return how many bytes are still in the FIFO; this will be called
-+ * with the device spinlock NOT HELD while waiting for the TX FIFO to get
-+ * empty; let's expect this won't be a problem */
-+static int it8708_get_tx_used_slots(struct ite_dev *dev)
-+{
-+ ite_dbg("%s called", __func__);
-+
-+ return inb(dev->cir_addr + IT8708_C0TFSR) & IT85_TXFBC;
-+}
-+
-+/* put a byte to the TX fifo; this should be called with the spinlock held */
-+static void it8708_put_tx_byte(struct ite_dev *dev, u8 value)
-+{
-+ outb(value, dev->cir_addr + IT8708_C0DR);
-+}
-+
-+/* idle the receiver so that we won't receive samples until another
-+ pulse is detected; this must be called with the device spinlock held */
-+static void it8708_idle_rx(struct ite_dev *dev)
-+{
-+ ite_dbg("%s called", __func__);
-+
-+ /* disable streaming by clearing RXACT writing it as 1 */
-+ outb(inb(dev->cir_addr + IT8708_C0RCR) | IT85_RXACT,
-+ dev->cir_addr + IT8708_C0RCR);
-+
-+ /* clear the FIFO */
-+ outb(inb(dev->cir_addr + IT8708_C0MSTCR) | IT85_FIFOCLR,
-+ dev->cir_addr + IT8708_C0MSTCR);
-+}
-+
-+/* disable the receiver; this must be called with the device spinlock held */
-+static void it8708_disable_rx(struct ite_dev *dev)
-+{
-+ ite_dbg("%s called", __func__);
-+
-+ /* disable the receiver interrupts */
-+ outb(inb(dev->cir_addr + IT8708_C0IER) &
-+ ~(IT85_RDAIE | IT85_RFOIE),
-+ dev->cir_addr + IT8708_C0IER);
-+
-+ /* disable the receiver */
-+ outb(inb(dev->cir_addr + IT8708_C0RCR) & ~IT85_RXEN,
-+ dev->cir_addr + IT8708_C0RCR);
-+
-+ /* clear the FIFO and RXACT (actually RXACT should have been cleared
-+ * in the previous outb() call) */
-+ it8708_idle_rx(dev);
-+}
-+
-+/* enable the receiver; this must be called with the device spinlock held */
-+static void it8708_enable_rx(struct ite_dev *dev)
-+{
-+ ite_dbg("%s called", __func__);
-+
-+ /* enable the receiver by setting RXEN */
-+ outb(inb(dev->cir_addr + IT8708_C0RCR) | IT85_RXEN,
-+ dev->cir_addr + IT8708_C0RCR);
-+
-+ /* just prepare it to idle for the next reception */
-+ it8708_idle_rx(dev);
-+
-+ /* enable the receiver interrupts and master enable flag */
-+ outb(inb(dev->cir_addr + IT8708_C0IER)
-+ |IT85_RDAIE | IT85_RFOIE | IT85_IEC,
-+ dev->cir_addr + IT8708_C0IER);
-+}
-+
-+/* disable the transmitter interrupt; this must be called with the device
-+ * spinlock held */
-+static void it8708_disable_tx_interrupt(struct ite_dev *dev)
-+{
-+ ite_dbg("%s called", __func__);
-+
-+ /* disable the transmitter interrupts */
-+ outb(inb(dev->cir_addr + IT8708_C0IER) & ~IT85_TLDLIE,
-+ dev->cir_addr + IT8708_C0IER);
-+}
-+
-+/* enable the transmitter interrupt; this must be called with the device
-+ * spinlock held */
-+static void it8708_enable_tx_interrupt(struct ite_dev *dev)
-+{
-+ ite_dbg("%s called", __func__);
-+
-+ /* enable the transmitter interrupts and master enable flag */
-+ outb(inb(dev->cir_addr + IT8708_C0IER)
-+ |IT85_TLDLIE | IT85_IEC,
-+ dev->cir_addr + IT8708_C0IER);
-+}
-+
-+/* disable the device; this must be called with the device spinlock held */
-+static void it8708_disable(struct ite_dev *dev)
-+{
-+ ite_dbg("%s called", __func__);
-+
-+ /* clear out all interrupt enable flags */
-+ outb(inb(dev->cir_addr + IT8708_C0IER) &
-+ ~(IT85_IEC | IT85_RFOIE | IT85_RDAIE | IT85_TLDLIE),
-+ dev->cir_addr + IT8708_C0IER);
-+
-+ /* disable the receiver */
-+ it8708_disable_rx(dev);
-+
-+ /* erase the FIFO */
-+ outb(IT85_FIFOCLR | inb(dev->cir_addr + IT8708_C0MSTCR),
-+ dev->cir_addr + IT8708_C0MSTCR);
-+}
-+
-+/* initialize the hardware */
-+static void it8708_init_hardware(struct ite_dev *dev)
-+{
-+ ite_dbg("%s called", __func__);
-+
-+ /* disable all the interrupts */
-+ outb(inb(dev->cir_addr + IT8708_C0IER) &
-+ ~(IT85_IEC | IT85_RFOIE | IT85_RDAIE | IT85_TLDLIE),
-+ dev->cir_addr + IT8708_C0IER);
-+
-+ /* program the baud rate divisor */
-+ outb(inb(dev->cir_addr + IT8708_BANKSEL) | IT8708_HRAE,
-+ dev->cir_addr + IT8708_BANKSEL);
-+
-+ outb(ITE_BAUDRATE_DIVISOR & 0xff, dev->cir_addr + IT8708_C0BDLR);
-+ outb((ITE_BAUDRATE_DIVISOR >> 8) & 0xff,
-+ dev->cir_addr + IT8708_C0BDHR);
-+
-+ outb(inb(dev->cir_addr + IT8708_BANKSEL) & ~IT8708_HRAE,
-+ dev->cir_addr + IT8708_BANKSEL);
-+
-+ /* program the C0MSTCR register defaults */
-+ outb((inb(dev->cir_addr + IT8708_C0MSTCR) &
-+ ~(IT85_ILSEL | IT85_ILE | IT85_FIFOTL |
-+ IT85_FIFOCLR | IT85_RESET)) |
-+ IT85_FIFOTL_DEFAULT,
-+ dev->cir_addr + IT8708_C0MSTCR);
-+
-+ /* program the C0RCR register defaults */
-+ outb((inb(dev->cir_addr + IT8708_C0RCR) &
-+ ~(IT85_RXEN | IT85_RDWOS | IT85_RXEND |
-+ IT85_RXACT | IT85_RXDCR)) |
-+ ITE_RXDCR_DEFAULT,
-+ dev->cir_addr + IT8708_C0RCR);
-+
-+ /* program the C0TCR register defaults */
-+ outb((inb(dev->cir_addr + IT8708_C0TCR) &
-+ ~(IT85_TXMPM | IT85_TXMPW))
-+ |IT85_TXRLE | IT85_TXENDF |
-+ IT85_TXMPM_DEFAULT | IT85_TXMPW_DEFAULT,
-+ dev->cir_addr + IT8708_C0TCR);
-+
-+ /* program the carrier parameters */
-+ ite_set_carrier_params(dev);
-+}
-+
-+/* IT8512F on ITE8709 HW-specific functions */
-+
-+/* read a byte from the SRAM module */
-+static inline u8 it8709_rm(struct ite_dev *dev, int index)
-+{
-+ outb(index, dev->cir_addr + IT8709_RAM_IDX);
-+ return inb(dev->cir_addr + IT8709_RAM_VAL);
-+}
-+
-+/* write a byte to the SRAM module */
-+static inline void it8709_wm(struct ite_dev *dev, u8 val, int index)
-+{
-+ outb(index, dev->cir_addr + IT8709_RAM_IDX);
-+ outb(val, dev->cir_addr + IT8709_RAM_VAL);
-+}
-+
-+static void it8709_wait(struct ite_dev *dev)
-+{
-+ int i = 0;
-+ /*
-+ * loop until device tells it's ready to continue
-+ * iterations count is usually ~750 but can sometimes achieve 13000
-+ */
-+ for (i = 0; i < 15000; i++) {
-+ udelay(2);
-+ if (it8709_rm(dev, IT8709_MODE) == IT8709_IDLE)
-+ break;
-+ }
-+}
-+
-+/* read the value of a CIR register */
-+static u8 it8709_rr(struct ite_dev *dev, int index)
-+{
-+ /* just wait in case the previous access was a write */
-+ it8709_wait(dev);
-+ it8709_wm(dev, index, IT8709_REG_IDX);
-+ it8709_wm(dev, IT8709_READ, IT8709_MODE);
-+
-+ /* wait for the read data to be available */
-+ it8709_wait(dev);
-+
-+ /* return the read value */
-+ return it8709_rm(dev, IT8709_REG_VAL);
-+}
-+
-+/* write the value of a CIR register */
-+static void it8709_wr(struct ite_dev *dev, u8 val, int index)
-+{
-+ /* we wait before writing, and not afterwards, since this allows us to
-+ * pipeline the host CPU with the microcontroller */
-+ it8709_wait(dev);
-+ it8709_wm(dev, val, IT8709_REG_VAL);
-+ it8709_wm(dev, index, IT8709_REG_IDX);
-+ it8709_wm(dev, IT8709_WRITE, IT8709_MODE);
-+}
-+
-+/* retrieve a bitmask of the current causes for a pending interrupt; this may
-+ * be composed of ITE_IRQ_TX_FIFO, ITE_IRQ_RX_FIFO and ITE_IRQ_RX_FIFO_OVERRUN
-+ * */
-+static int it8709_get_irq_causes(struct ite_dev *dev)
-+{
-+ u8 iflags;
-+ int ret = 0;
-+
-+ ite_dbg("%s called", __func__);
-+
-+ /* read the interrupt flags */
-+ iflags = it8709_rm(dev, IT8709_IIR);
-+
-+ if (iflags & IT85_TLDLI)
-+ ret |= ITE_IRQ_TX_FIFO;
-+ if (iflags & IT85_RDAI)
-+ ret |= ITE_IRQ_RX_FIFO;
-+ if (iflags & IT85_RFOI)
-+ ret |= ITE_IRQ_RX_FIFO_OVERRUN;
-+
-+ return ret;
-+}
-+
-+/* set the carrier parameters; to be called with the spinlock held */
-+static void it8709_set_carrier_params(struct ite_dev *dev, bool high_freq,
-+ bool use_demodulator,
-+ u8 carrier_freq_bits, u8 allowance_bits,
-+ u8 pulse_width_bits)
-+{
-+ u8 val;
-+
-+ ite_dbg("%s called", __func__);
-+
-+ val = (it8709_rr(dev, IT85_C0CFR)
-+ &~(IT85_HCFS | IT85_CFQ)) |
-+ carrier_freq_bits;
-+
-+ if (high_freq)
-+ val |= IT85_HCFS;
-+
-+ it8709_wr(dev, val, IT85_C0CFR);
-+
-+ /* program the C0RCR register */
-+ val = it8709_rr(dev, IT85_C0RCR)
-+ & ~(IT85_RXEND | IT85_RXDCR);
-+
-+ if (use_demodulator)
-+ val |= IT85_RXEND;
-+
-+ val |= allowance_bits;
-+
-+ it8709_wr(dev, val, IT85_C0RCR);
-+
-+ /* program the C0TCR register */
-+ val = it8709_rr(dev, IT85_C0TCR) & ~IT85_TXMPW;
-+ val |= pulse_width_bits;
-+ it8709_wr(dev, val, IT85_C0TCR);
-+}
-+
-+/* read up to buf_size bytes from the RX FIFO; to be called with the spinlock
-+ * held */
-+static int it8709_get_rx_bytes(struct ite_dev *dev, u8 * buf, int buf_size)
-+{
-+ int fifo, read = 0;
-+
-+ ite_dbg("%s called", __func__);
-+
-+ /* read how many bytes are still in the FIFO */
-+ fifo = it8709_rm(dev, IT8709_RFSR) & IT85_RXFBC;
-+
-+ while (fifo > 0 && buf_size > 0) {
-+ *(buf++) = it8709_rm(dev, IT8709_FIFO + read);
-+ fifo--;
-+ read++;
-+ buf_size--;
-+ }
-+
-+ /* 'clear' the FIFO by setting the writing index to 0; this is
-+ * completely bound to be racy, but we can't help it, since it's a
-+ * limitation of the protocol */
-+ it8709_wm(dev, 0, IT8709_RFSR);
-+
-+ return read;
-+}
-+
-+/* return how many bytes are still in the FIFO; this will be called
-+ * with the device spinlock NOT HELD while waiting for the TX FIFO to get
-+ * empty; let's expect this won't be a problem */
-+static int it8709_get_tx_used_slots(struct ite_dev *dev)
-+{
-+ ite_dbg("%s called", __func__);
-+
-+ return it8709_rr(dev, IT85_C0TFSR) & IT85_TXFBC;
-+}
-+
-+/* put a byte to the TX fifo; this should be called with the spinlock held */
-+static void it8709_put_tx_byte(struct ite_dev *dev, u8 value)
-+{
-+ it8709_wr(dev, value, IT85_C0DR);
-+}
-+
-+/* idle the receiver so that we won't receive samples until another
-+ pulse is detected; this must be called with the device spinlock held */
-+static void it8709_idle_rx(struct ite_dev *dev)
-+{
-+ ite_dbg("%s called", __func__);
-+
-+ /* disable streaming by clearing RXACT writing it as 1 */
-+ it8709_wr(dev, it8709_rr(dev, IT85_C0RCR) | IT85_RXACT,
-+ IT85_C0RCR);
-+
-+ /* clear the FIFO */
-+ it8709_wr(dev, it8709_rr(dev, IT85_C0MSTCR) | IT85_FIFOCLR,
-+ IT85_C0MSTCR);
-+}
-+
-+/* disable the receiver; this must be called with the device spinlock held */
-+static void it8709_disable_rx(struct ite_dev *dev)
-+{
-+ ite_dbg("%s called", __func__);
-+
-+ /* disable the receiver interrupts */
-+ it8709_wr(dev, it8709_rr(dev, IT85_C0IER) &
-+ ~(IT85_RDAIE | IT85_RFOIE),
-+ IT85_C0IER);
-+
-+ /* disable the receiver */
-+ it8709_wr(dev, it8709_rr(dev, IT85_C0RCR) & ~IT85_RXEN,
-+ IT85_C0RCR);
-+
-+ /* clear the FIFO and RXACT (actually RXACT should have been cleared
-+ * in the previous it8709_wr(dev, ) call) */
-+ it8709_idle_rx(dev);
-+}
-+
-+/* enable the receiver; this must be called with the device spinlock held */
-+static void it8709_enable_rx(struct ite_dev *dev)
-+{
-+ ite_dbg("%s called", __func__);
-+
-+ /* enable the receiver by setting RXEN */
-+ it8709_wr(dev, it8709_rr(dev, IT85_C0RCR) | IT85_RXEN,
-+ IT85_C0RCR);
-+
-+ /* just prepare it to idle for the next reception */
-+ it8709_idle_rx(dev);
-+
-+ /* enable the receiver interrupts and master enable flag */
-+ it8709_wr(dev, it8709_rr(dev, IT85_C0IER)
-+ |IT85_RDAIE | IT85_RFOIE | IT85_IEC,
-+ IT85_C0IER);
-+}
-+
-+/* disable the transmitter interrupt; this must be called with the device
-+ * spinlock held */
-+static void it8709_disable_tx_interrupt(struct ite_dev *dev)
-+{
-+ ite_dbg("%s called", __func__);
-+
-+ /* disable the transmitter interrupts */
-+ it8709_wr(dev, it8709_rr(dev, IT85_C0IER) & ~IT85_TLDLIE,
-+ IT85_C0IER);
-+}
-+
-+/* enable the transmitter interrupt; this must be called with the device
-+ * spinlock held */
-+static void it8709_enable_tx_interrupt(struct ite_dev *dev)
-+{
-+ ite_dbg("%s called", __func__);
-+
-+ /* enable the transmitter interrupts and master enable flag */
-+ it8709_wr(dev, it8709_rr(dev, IT85_C0IER)
-+ |IT85_TLDLIE | IT85_IEC,
-+ IT85_C0IER);
-+}
-+
-+/* disable the device; this must be called with the device spinlock held */
-+static void it8709_disable(struct ite_dev *dev)
-+{
-+ ite_dbg("%s called", __func__);
-+
-+ /* clear out all interrupt enable flags */
-+ it8709_wr(dev,
-+ it8709_rr(dev,
-+ IT85_C0IER) & ~(IT85_IEC | IT85_RFOIE |
-+ IT85_RDAIE |
-+ IT85_TLDLIE), IT85_C0IER);
-+
-+ /* disable the receiver */
-+ it8709_disable_rx(dev);
-+
-+ /* erase the FIFO */
-+ it8709_wr(dev, IT85_FIFOCLR | it8709_rr(dev, IT85_C0MSTCR),
-+ IT85_C0MSTCR);
-+}
-+
-+/* initialize the hardware */
-+static void it8709_init_hardware(struct ite_dev *dev)
-+{
-+ ite_dbg("%s called", __func__);
-+
-+ /* disable all the interrupts */
-+ it8709_wr(dev,
-+ it8709_rr(dev,
-+ IT85_C0IER) & ~(IT85_IEC | IT85_RFOIE |
-+ IT85_RDAIE |
-+ IT85_TLDLIE), IT85_C0IER);
-+
-+ /* program the baud rate divisor */
-+ it8709_wr(dev, ITE_BAUDRATE_DIVISOR & 0xff, IT85_C0BDLR);
-+ it8709_wr(dev, (ITE_BAUDRATE_DIVISOR >> 8) & 0xff,
-+ IT85_C0BDHR);
-+
-+ /* program the C0MSTCR register defaults */
-+ it8709_wr(dev, (it8709_rr(dev, IT85_C0MSTCR) & ~(IT85_ILSEL |
-+ IT85_ILE
-+ | IT85_FIFOTL
-+ |
-+ IT85_FIFOCLR
-+ |
-+ IT85_RESET))
-+ | IT85_FIFOTL_DEFAULT, IT85_C0MSTCR);
-+
-+ /* program the C0RCR register defaults */
-+ it8709_wr(dev,
-+ (it8709_rr(dev, IT85_C0RCR) &
-+ ~(IT85_RXEN | IT85_RDWOS | IT85_RXEND
-+ | IT85_RXACT | IT85_RXDCR)) |
-+ ITE_RXDCR_DEFAULT, IT85_C0RCR);
-+
-+ /* program the C0TCR register defaults */
-+ it8709_wr(dev, (it8709_rr(dev, IT85_C0TCR)
-+ &~(IT85_TXMPM | IT85_TXMPW))
-+ |IT85_TXRLE | IT85_TXENDF |
-+ IT85_TXMPM_DEFAULT |
-+ IT85_TXMPW_DEFAULT, IT85_C0TCR);
-+
-+ /* program the carrier parameters */
-+ ite_set_carrier_params(dev);
-+}
-+
-+
-+/* generic hardware setup/teardown code */
-+
-+/* activate the device for use */
-+static int ite_open(struct rc_dev *rcdev)
-+{
-+ struct ite_dev *dev = rcdev->priv;
-+ unsigned long flags;
-+
-+ ite_dbg("%s called", __func__);
-+
-+ spin_lock_irqsave(&dev->lock, flags);
-+ dev->in_use = true;
-+
-+ /* enable the receiver */
-+ dev->params.enable_rx(dev);
-+
-+ spin_unlock_irqrestore(&dev->lock, flags);
-+
-+ return 0;
-+}
-+
-+/* deactivate the device for use */
-+static void ite_close(struct rc_dev *rcdev)
-+{
-+ struct ite_dev *dev = rcdev->priv;
-+ unsigned long flags;
-+
-+ ite_dbg("%s called", __func__);
-+
-+ spin_lock_irqsave(&dev->lock, flags);
-+ dev->in_use = false;
-+
-+ /* wait for any transmission to end */
-+ spin_unlock_irqrestore(&dev->lock, flags);
-+ wait_event_interruptible(dev->tx_ended, !dev->transmitting);
-+ spin_lock_irqsave(&dev->lock, flags);
-+
-+ dev->params.disable(dev);
-+
-+ spin_unlock_irqrestore(&dev->lock, flags);
-+}
-+
-+/* supported models and their parameters */
-+static const struct ite_dev_params ite_dev_descs[] = {
-+ { /* 0: ITE8704 */
-+ .model = "ITE8704 CIR transceiver",
-+ .io_region_size = IT87_IOREG_LENGTH,
-+ .hw_tx_capable = true,
-+ .sample_period = (u32) (1000000000ULL / 115200),
-+ .tx_carrier_freq = 38000,
-+ .tx_duty_cycle = 33,
-+ .rx_low_carrier_freq = 0,
-+ .rx_high_carrier_freq = 0,
-+
-+ /* operations */
-+ .get_irq_causes = it87_get_irq_causes,
-+ .enable_rx = it87_enable_rx,
-+ .idle_rx = it87_idle_rx,
-+ .disable_rx = it87_idle_rx,
-+ .get_rx_bytes = it87_get_rx_bytes,
-+ .enable_tx_interrupt = it87_enable_tx_interrupt,
-+ .disable_tx_interrupt = it87_disable_tx_interrupt,
-+ .get_tx_used_slots = it87_get_tx_used_slots,
-+ .put_tx_byte = it87_put_tx_byte,
-+ .disable = it87_disable,
-+ .init_hardware = it87_init_hardware,
-+ .set_carrier_params = it87_set_carrier_params,
-+ },
-+ { /* 1: ITE8713 */
-+ .model = "ITE8713 CIR transceiver",
-+ .io_region_size = IT87_IOREG_LENGTH,
-+ .hw_tx_capable = true,
-+ .sample_period = (u32) (1000000000ULL / 115200),
-+ .tx_carrier_freq = 38000,
-+ .tx_duty_cycle = 33,
-+ .rx_low_carrier_freq = 0,
-+ .rx_high_carrier_freq = 0,
-+
-+ /* operations */
-+ .get_irq_causes = it87_get_irq_causes,
-+ .enable_rx = it87_enable_rx,
-+ .idle_rx = it87_idle_rx,
-+ .disable_rx = it87_idle_rx,
-+ .get_rx_bytes = it87_get_rx_bytes,
-+ .enable_tx_interrupt = it87_enable_tx_interrupt,
-+ .disable_tx_interrupt = it87_disable_tx_interrupt,
-+ .get_tx_used_slots = it87_get_tx_used_slots,
-+ .put_tx_byte = it87_put_tx_byte,
-+ .disable = it87_disable,
-+ .init_hardware = it87_init_hardware,
-+ .set_carrier_params = it87_set_carrier_params,
-+ },
-+ { /* 2: ITE8708 */
-+ .model = "ITE8708 CIR transceiver",
-+ .io_region_size = IT8708_IOREG_LENGTH,
-+ .hw_tx_capable = true,
-+ .sample_period = (u32) (1000000000ULL / 115200),
-+ .tx_carrier_freq = 38000,
-+ .tx_duty_cycle = 33,
-+ .rx_low_carrier_freq = 0,
-+ .rx_high_carrier_freq = 0,
-+
-+ /* operations */
-+ .get_irq_causes = it8708_get_irq_causes,
-+ .enable_rx = it8708_enable_rx,
-+ .idle_rx = it8708_idle_rx,
-+ .disable_rx = it8708_idle_rx,
-+ .get_rx_bytes = it8708_get_rx_bytes,
-+ .enable_tx_interrupt = it8708_enable_tx_interrupt,
-+ .disable_tx_interrupt =
-+ it8708_disable_tx_interrupt,
-+ .get_tx_used_slots = it8708_get_tx_used_slots,
-+ .put_tx_byte = it8708_put_tx_byte,
-+ .disable = it8708_disable,
-+ .init_hardware = it8708_init_hardware,
-+ .set_carrier_params = it8708_set_carrier_params,
-+ },
-+ { /* 3: ITE8709 */
-+ .model = "ITE8709 CIR transceiver",
-+ .io_region_size = IT8709_IOREG_LENGTH,
-+ .hw_tx_capable = true,
-+ .sample_period = (u32) (1000000000ULL / 115200),
-+ .tx_carrier_freq = 38000,
-+ .tx_duty_cycle = 33,
-+ .rx_low_carrier_freq = 0,
-+ .rx_high_carrier_freq = 0,
-+
-+ /* operations */
-+ .get_irq_causes = it8709_get_irq_causes,
-+ .enable_rx = it8709_enable_rx,
-+ .idle_rx = it8709_idle_rx,
-+ .disable_rx = it8709_idle_rx,
-+ .get_rx_bytes = it8709_get_rx_bytes,
-+ .enable_tx_interrupt = it8709_enable_tx_interrupt,
-+ .disable_tx_interrupt =
-+ it8709_disable_tx_interrupt,
-+ .get_tx_used_slots = it8709_get_tx_used_slots,
-+ .put_tx_byte = it8709_put_tx_byte,
-+ .disable = it8709_disable,
-+ .init_hardware = it8709_init_hardware,
-+ .set_carrier_params = it8709_set_carrier_params,
-+ },
-+};
-+
-+static const struct pnp_device_id ite_ids[] = {
-+ {"ITE8704", 0}, /* Default model */
-+ {"ITE8713", 1}, /* CIR found in EEEBox 1501U */
-+ {"ITE8708", 2}, /* Bridged IT8512 */
-+ {"ITE8709", 3}, /* SRAM-Bridged IT8512 */
-+ {"", 0},
-+};
-+
-+/* allocate memory, probe hardware, and initialize everything */
-+static int ite_probe(struct pnp_dev *pdev, const struct pnp_device_id
-+ *dev_id)
-+{
-+ const struct ite_dev_params *dev_desc = NULL;
-+ struct ite_dev *itdev = NULL;
-+ struct rc_dev *rdev = NULL;
-+ int ret = -ENOMEM;
-+ int model_no;
-+
-+ ite_dbg("%s called", __func__);
-+
-+ itdev = kzalloc(sizeof(struct ite_dev), GFP_KERNEL);
-+ if (!itdev)
-+ return ret;
-+
-+ /* input device for IR remote (and tx) */
-+ rdev = rc_allocate_device();
-+ if (!rdev)
-+ goto failure;
-+
-+ ret = -ENODEV;
-+
-+ /* get the model number */
-+ model_no = (int)dev_id->driver_data;
-+ ite_pr(KERN_NOTICE, "Auto-detected model: %s\n",
-+ ite_dev_descs[model_no].model);
-+
-+ if (model_number >= 0 && model_number < ARRAY_SIZE(ite_dev_descs)) {
-+ model_no = model_number;
-+ ite_pr(KERN_NOTICE, "The model has been fixed by a module "
-+ "parameter.");
-+ }
-+
-+ ite_pr(KERN_NOTICE, "Using model: %s\n", ite_dev_descs[model_no].model);
-+
-+ /* get the description for the device */
-+ dev_desc = &ite_dev_descs[model_no];
-+
-+ /* validate pnp resources */
-+ if (!pnp_port_valid(pdev, 0) ||
-+ pnp_port_len(pdev, 0) != dev_desc->io_region_size) {
-+ dev_err(&pdev->dev, "IR PNP Port not valid!\n");
-+ goto failure;
-+ }
-+
-+ if (!pnp_irq_valid(pdev, 0)) {
-+ dev_err(&pdev->dev, "PNP IRQ not valid!\n");
-+ goto failure;
-+ }
-+
-+ /* store resource values */
-+ itdev->cir_addr = pnp_port_start(pdev, 0);
-+ itdev->cir_irq = pnp_irq(pdev, 0);
-+
-+ /* initialize spinlocks */
-+ spin_lock_init(&itdev->lock);
-+
-+ /* initialize raw event */
-+ init_ir_raw_event(&itdev->rawir);
-+
-+ ret = -EBUSY;
-+ /* now claim resources */
-+ if (!request_region(itdev->cir_addr,
-+ dev_desc->io_region_size, ITE_DRIVER_NAME))
-+ goto failure;
-+
-+ if (request_irq(itdev->cir_irq, ite_cir_isr, IRQF_SHARED,
-+ ITE_DRIVER_NAME, (void *)itdev))
-+ goto failure;
-+
-+ /* set driver data into the pnp device */
-+ pnp_set_drvdata(pdev, itdev);
-+ itdev->pdev = pdev;
-+
-+ /* initialize waitqueues for transmission */
-+ init_waitqueue_head(&itdev->tx_queue);
-+ init_waitqueue_head(&itdev->tx_ended);
-+
-+ /* copy model-specific parameters */
-+ itdev->params = *dev_desc;
-+
-+ /* apply any overrides */
-+ if (sample_period > 0)
-+ itdev->params.sample_period = sample_period;
-+
-+ if (tx_carrier_freq > 0)
-+ itdev->params.tx_carrier_freq = tx_carrier_freq;
-+
-+ if (tx_duty_cycle > 0 && tx_duty_cycle <= 100)
-+ itdev->params.tx_duty_cycle = tx_duty_cycle;
-+
-+ if (rx_low_carrier_freq > 0)
-+ itdev->params.rx_low_carrier_freq = rx_low_carrier_freq;
-+
-+ if (rx_high_carrier_freq > 0)
-+ itdev->params.rx_high_carrier_freq = rx_high_carrier_freq;
-+
-+ /* print out parameters */
-+ ite_pr(KERN_NOTICE, "TX-capable: %d\n", (int)
-+ itdev->params.hw_tx_capable);
-+ ite_pr(KERN_NOTICE, "Sample period (ns): %ld\n", (long)
-+ itdev->params.sample_period);
-+ ite_pr(KERN_NOTICE, "TX carrier frequency (Hz): %d\n", (int)
-+ itdev->params.tx_carrier_freq);
-+ ite_pr(KERN_NOTICE, "TX duty cycle (%%): %d\n", (int)
-+ itdev->params.tx_duty_cycle);
-+ ite_pr(KERN_NOTICE, "RX low carrier frequency (Hz): %d\n", (int)
-+ itdev->params.rx_low_carrier_freq);
-+ ite_pr(KERN_NOTICE, "RX high carrier frequency (Hz): %d\n", (int)
-+ itdev->params.rx_high_carrier_freq);
-+
-+ /* set up hardware initial state */
-+ itdev->params.init_hardware(itdev);
-+
-+ /* set up ir-core props */
-+ rdev->priv = itdev;
-+ rdev->driver_type = RC_DRIVER_IR_RAW;
-+ rdev->allowed_protos = RC_TYPE_ALL;
-+ rdev->open = ite_open;
-+ rdev->close = ite_close;
-+ rdev->s_idle = ite_s_idle;
-+ rdev->s_rx_carrier_range = ite_set_rx_carrier_range;
-+ rdev->min_timeout = ITE_MIN_IDLE_TIMEOUT;
-+ rdev->max_timeout = ITE_MAX_IDLE_TIMEOUT;
-+ rdev->timeout = ITE_IDLE_TIMEOUT;
-+ rdev->rx_resolution = ITE_BAUDRATE_DIVISOR *
-+ itdev->params.sample_period;
-+ rdev->tx_resolution = ITE_BAUDRATE_DIVISOR *
-+ itdev->params.sample_period;
-+
-+ /* set up transmitter related values if needed */
-+ if (itdev->params.hw_tx_capable) {
-+ rdev->tx_ir = ite_tx_ir;
-+ rdev->s_tx_carrier = ite_set_tx_carrier;
-+ rdev->s_tx_duty_cycle = ite_set_tx_duty_cycle;
-+ }
-+
-+ rdev->input_name = dev_desc->model;
-+ rdev->input_id.bustype = BUS_HOST;
-+ rdev->input_id.vendor = PCI_VENDOR_ID_ITE;
-+ rdev->input_id.product = 0;
-+ rdev->input_id.version = 0;
-+ rdev->driver_name = ITE_DRIVER_NAME;
-+ rdev->map_name = RC_MAP_RC6_MCE;
-+
-+ ret = rc_register_device(rdev);
-+ if (ret)
-+ goto failure;
-+
-+ itdev->rdev = rdev;
-+ ite_pr(KERN_NOTICE, "driver has been successfully loaded\n");
-+
-+ return 0;
-+
-+failure:
-+ if (itdev->cir_irq)
-+ free_irq(itdev->cir_irq, itdev);
-+
-+ if (itdev->cir_addr)
-+ release_region(itdev->cir_addr, itdev->params.io_region_size);
-+
-+ rc_free_device(rdev);
-+ kfree(itdev);
-+
-+ return ret;
-+}
-+
-+static void __devexit ite_remove(struct pnp_dev *pdev)
-+{
-+ struct ite_dev *dev = pnp_get_drvdata(pdev);
-+ unsigned long flags;
-+
-+ ite_dbg("%s called", __func__);
-+
-+ spin_lock_irqsave(&dev->lock, flags);
-+
-+ /* disable hardware */
-+ dev->params.disable(dev);
-+
-+ spin_unlock_irqrestore(&dev->lock, flags);
-+
-+ /* free resources */
-+ free_irq(dev->cir_irq, dev);
-+ release_region(dev->cir_addr, dev->params.io_region_size);
-+
-+ rc_unregister_device(dev->rdev);
-+
-+ kfree(dev);
-+}
-+
-+static int ite_suspend(struct pnp_dev *pdev, pm_message_t state)
-+{
-+ struct ite_dev *dev = pnp_get_drvdata(pdev);
-+ unsigned long flags;
-+
-+ ite_dbg("%s called", __func__);
-+
-+ spin_lock_irqsave(&dev->lock, flags);
-+
-+ /* disable all interrupts */
-+ dev->params.disable(dev);
-+
-+ spin_unlock_irqrestore(&dev->lock, flags);
-+
-+ return 0;
-+}
-+
-+static int ite_resume(struct pnp_dev *pdev)
-+{
-+ int ret = 0;
-+ struct ite_dev *dev = pnp_get_drvdata(pdev);
-+ unsigned long flags;
-+
-+ ite_dbg("%s called", __func__);
-+
-+ spin_lock_irqsave(&dev->lock, flags);
-+
-+ if (dev->transmitting) {
-+ /* wake up the transmitter */
-+ wake_up_interruptible(&dev->tx_queue);
-+ } else {
-+ /* enable the receiver */
-+ dev->params.enable_rx(dev);
-+ }
-+
-+ spin_unlock_irqrestore(&dev->lock, flags);
-+
-+ return ret;
-+}
-+
-+static void ite_shutdown(struct pnp_dev *pdev)
-+{
-+ struct ite_dev *dev = pnp_get_drvdata(pdev);
-+ unsigned long flags;
-+
-+ ite_dbg("%s called", __func__);
-+
-+ spin_lock_irqsave(&dev->lock, flags);
-+
-+ /* disable all interrupts */
-+ dev->params.disable(dev);
-+
-+ spin_unlock_irqrestore(&dev->lock, flags);
-+}
-+
-+static struct pnp_driver ite_driver = {
-+ .name = ITE_DRIVER_NAME,
-+ .id_table = ite_ids,
-+ .probe = ite_probe,
-+ .remove = __devexit_p(ite_remove),
-+ .suspend = ite_suspend,
-+ .resume = ite_resume,
-+ .shutdown = ite_shutdown,
-+};
-+
-+int ite_init(void)
-+{
-+ return pnp_register_driver(&ite_driver);
-+}
-+
-+void ite_exit(void)
-+{
-+ pnp_unregister_driver(&ite_driver);
-+}
-+
-+MODULE_DEVICE_TABLE(pnp, ite_ids);
-+MODULE_DESCRIPTION("ITE Tech Inc. IT8712F/ITE8512F CIR driver");
-+
-+MODULE_AUTHOR("Juan J. Garcia de Soria <skandalfo(a)gmail.com>");
-+MODULE_LICENSE("GPL");
-+
-+module_init(ite_init);
-+module_exit(ite_exit);
-diff --git a/drivers/media/rc/ite-cir.h b/drivers/media/rc/ite-cir.h
-new file mode 100644
-index 0000000..16a19f5
---- /dev/null
-+++ b/drivers/media/rc/ite-cir.h
-@@ -0,0 +1,481 @@
-+/*
-+ * Driver for ITE Tech Inc. IT8712F/IT8512F CIR
-+ *
-+ * Copyright (C) 2010 Juan Jesús García de Soria <skandalfo(a)gmail.com>
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License as
-+ * published by the Free Software Foundation; either version 2 of the
-+ * License, or (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful, but
-+ * WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ * General Public License for more details.
-+ *
-+ * 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.
-+ */
-+
-+/* platform driver name to register */
-+#define ITE_DRIVER_NAME "ite-cir"
-+
-+/* logging macros */
-+#define ite_pr(level, text, ...) \
-+ printk(level KBUILD_MODNAME ": " text, ## __VA_ARGS__)
-+#define ite_dbg(text, ...) do { \
-+ if (debug) \
-+ printk(KERN_DEBUG \
-+ KBUILD_MODNAME ": " text "\n" , ## __VA_ARGS__); \
-+} while (0)
-+
-+#define ite_dbg_verbose(text, ...) do {\
-+ if (debug > 1) \
-+ printk(KERN_DEBUG \
-+ KBUILD_MODNAME ": " text "\n" , ## __VA_ARGS__); \
-+} while (0)
-+
-+/* FIFO sizes */
-+#define ITE_TX_FIFO_LEN 32
-+#define ITE_RX_FIFO_LEN 32
-+
-+/* interrupt types */
-+#define ITE_IRQ_TX_FIFO 1
-+#define ITE_IRQ_RX_FIFO 2
-+#define ITE_IRQ_RX_FIFO_OVERRUN 4
-+
-+/* forward declaration */
-+struct ite_dev;
-+
-+/* struct for storing the parameters of different recognized devices */
-+struct ite_dev_params {
-+ /* model of the device */
-+ const char *model;
-+
-+ /* size of the I/O region */
-+ int io_region_size;
-+
-+ /* true if the hardware supports transmission */
-+ bool hw_tx_capable;
-+
-+ /* base sampling period, in ns */
-+ u32 sample_period;
-+
-+ /* rx low carrier frequency, in Hz, 0 means no demodulation */
-+ unsigned int rx_low_carrier_freq;
-+
-+ /* tx high carrier frequency, in Hz, 0 means no demodulation */
-+ unsigned int rx_high_carrier_freq;
-+
-+ /* tx carrier frequency, in Hz */
-+ unsigned int tx_carrier_freq;
-+
-+ /* duty cycle, 0-100 */
-+ int tx_duty_cycle;
-+
-+ /* hw-specific operation function pointers; most of these must be
-+ * called while holding the spin lock, except for the TX FIFO length
-+ * one */
-+ /* get pending interrupt causes */
-+ int (*get_irq_causes) (struct ite_dev *dev);
-+
-+ /* enable rx */
-+ void (*enable_rx) (struct ite_dev *dev);
-+
-+ /* make rx enter the idle state; keep listening for a pulse, but stop
-+ * streaming space bytes */
-+ void (*idle_rx) (struct ite_dev *dev);
-+
-+ /* disable rx completely */
-+ void (*disable_rx) (struct ite_dev *dev);
-+
-+ /* read bytes from RX FIFO; return read count */
-+ int (*get_rx_bytes) (struct ite_dev *dev, u8 *buf, int buf_size);
-+
-+ /* enable tx FIFO space available interrupt */
-+ void (*enable_tx_interrupt) (struct ite_dev *dev);
-+
-+ /* disable tx FIFO space available interrupt */
-+ void (*disable_tx_interrupt) (struct ite_dev *dev);
-+
-+ /* get number of full TX FIFO slots */
-+ int (*get_tx_used_slots) (struct ite_dev *dev);
-+
-+ /* put a byte to the TX FIFO */
-+ void (*put_tx_byte) (struct ite_dev *dev, u8 value);
-+
-+ /* disable hardware completely */
-+ void (*disable) (struct ite_dev *dev);
-+
-+ /* initialize the hardware */
-+ void (*init_hardware) (struct ite_dev *dev);
-+
-+ /* set the carrier parameters */
-+ void (*set_carrier_params) (struct ite_dev *dev, bool high_freq,
-+ bool use_demodulator, u8 carrier_freq_bits,
-+ u8 allowance_bits, u8 pulse_width_bits);
-+};
-+
-+/* ITE CIR device structure */
-+struct ite_dev {
-+ struct pnp_dev *pdev;
-+ struct rc_dev *rdev;
-+ struct ir_raw_event rawir;
-+
-+ /* sync data */
-+ spinlock_t lock;
-+ bool in_use, transmitting;
-+
-+ /* transmit support */
-+ int tx_fifo_allowance;
-+ wait_queue_head_t tx_queue, tx_ended;
-+
-+ /* hardware I/O settings */
-+ unsigned long cir_addr;
-+ int cir_irq;
-+
-+ /* overridable copy of model parameters */
-+ struct ite_dev_params params;
-+};
-+
-+/* common values for all kinds of hardware */
-+
-+/* baud rate divisor default */
-+#define ITE_BAUDRATE_DIVISOR 1
-+
-+/* low-speed carrier frequency limits (Hz) */
-+#define ITE_LCF_MIN_CARRIER_FREQ 27000
-+#define ITE_LCF_MAX_CARRIER_FREQ 58000
-+
-+/* high-speed carrier frequency limits (Hz) */
-+#define ITE_HCF_MIN_CARRIER_FREQ 400000
-+#define ITE_HCF_MAX_CARRIER_FREQ 500000
-+
-+/* default carrier freq for when demodulator is off (Hz) */
-+#define ITE_DEFAULT_CARRIER_FREQ 38000
-+
-+/* default idling timeout in ns (0.2 seconds) */
-+#define ITE_IDLE_TIMEOUT 200000000UL
-+
-+/* limit timeout values */
-+#define ITE_MIN_IDLE_TIMEOUT 100000000UL
-+#define ITE_MAX_IDLE_TIMEOUT 1000000000UL
-+
-+/* convert bits to us */
-+#define ITE_BITS_TO_NS(bits, sample_period) \
-+((u32) ((bits) * ITE_BAUDRATE_DIVISOR * sample_period))
-+
-+/*
-+ * n in RDCR produces a tolerance of +/- n * 6.25% around the center
-+ * carrier frequency...
-+ *
-+ * From two limit frequencies, L (low) and H (high), we can get both the
-+ * center frequency F = (L + H) / 2 and the variation from the center
-+ * frequency A = (H - L) / (H + L). We can use this in order to honor the
-+ * s_rx_carrier_range() call in ir-core. We'll suppose that any request
-+ * setting L=0 means we must shut down the demodulator.
-+ */
-+#define ITE_RXDCR_PER_10000_STEP 625
-+
-+/* high speed carrier freq values */
-+#define ITE_CFQ_400 0x03
-+#define ITE_CFQ_450 0x08
-+#define ITE_CFQ_480 0x0b
-+#define ITE_CFQ_500 0x0d
-+
-+/* values for pulse widths */
-+#define ITE_TXMPW_A 0x02
-+#define ITE_TXMPW_B 0x03
-+#define ITE_TXMPW_C 0x04
-+#define ITE_TXMPW_D 0x05
-+#define ITE_TXMPW_E 0x06
-+
-+/* values for demodulator carrier range allowance */
-+#define ITE_RXDCR_DEFAULT 0x01 /* default carrier range */
-+#define ITE_RXDCR_MAX 0x07 /* default carrier range */
-+
-+/* DR TX bits */
-+#define ITE_TX_PULSE 0x00
-+#define ITE_TX_SPACE 0x80
-+#define ITE_TX_MAX_RLE 0x80
-+#define ITE_TX_RLE_MASK 0x7f
-+
-+/*
-+ * IT8712F
-+ *
-+ * hardware data obtained from:
-+ *
-+ * IT8712F
-+ * Environment Control – Low Pin Count Input / Output
-+ * (EC - LPC I/O)
-+ * Preliminary Specification V0. 81
-+ */
-+
-+/* register offsets */
-+#define IT87_DR 0x00 /* data register */
-+#define IT87_IER 0x01 /* interrupt enable register */
-+#define IT87_RCR 0x02 /* receiver control register */
-+#define IT87_TCR1 0x03 /* transmitter control register 1 */
-+#define IT87_TCR2 0x04 /* transmitter control register 2 */
-+#define IT87_TSR 0x05 /* transmitter status register */
-+#define IT87_RSR 0x06 /* receiver status register */
-+#define IT87_BDLR 0x05 /* baud rate divisor low byte register */
-+#define IT87_BDHR 0x06 /* baud rate divisor high byte register */
-+#define IT87_IIR 0x07 /* interrupt identification register */
-+
-+#define IT87_IOREG_LENGTH 0x08 /* length of register file */
-+
-+/* IER bits */
-+#define IT87_TLDLIE 0x01 /* transmitter low data interrupt enable */
-+#define IT87_RDAIE 0x02 /* receiver data available interrupt enable */
-+#define IT87_RFOIE 0x04 /* receiver FIFO overrun interrupt enable */
-+#define IT87_IEC 0x08 /* interrupt enable control */
-+#define IT87_BR 0x10 /* baud rate register enable */
-+#define IT87_RESET 0x20 /* reset */
-+
-+/* RCR bits */
-+#define IT87_RXDCR 0x07 /* receiver demodulation carrier range mask */
-+#define IT87_RXACT 0x08 /* receiver active */
-+#define IT87_RXEND 0x10 /* receiver demodulation enable */
-+#define IT87_RXEN 0x20 /* receiver enable */
-+#define IT87_HCFS 0x40 /* high-speed carrier frequency select */
-+#define IT87_RDWOS 0x80 /* receiver data without sync */
-+
-+/* TCR1 bits */
-+#define IT87_TXMPM 0x03 /* transmitter modulation pulse mode mask */
-+#define IT87_TXMPM_DEFAULT 0x00 /* modulation pulse mode default */
-+#define IT87_TXENDF 0x04 /* transmitter deferral */
-+#define IT87_TXRLE 0x08 /* transmitter run length enable */
-+#define IT87_FIFOTL 0x30 /* FIFO level threshold mask */
-+#define IT87_FIFOTL_DEFAULT 0x20 /* FIFO level threshold default
-+ * 0x00 -> 1, 0x10 -> 7, 0x20 -> 17,
-+ * 0x30 -> 25 */
-+#define IT87_ILE 0x40 /* internal loopback enable */
-+#define IT87_FIFOCLR 0x80 /* FIFO clear bit */
-+
-+/* TCR2 bits */
-+#define IT87_TXMPW 0x07 /* transmitter modulation pulse width mask */
-+#define IT87_TXMPW_DEFAULT 0x04 /* default modulation pulse width */
-+#define IT87_CFQ 0xf8 /* carrier frequency mask */
-+#define IT87_CFQ_SHIFT 3 /* carrier frequency bit shift */
-+
-+/* TSR bits */
-+#define IT87_TXFBC 0x3f /* transmitter FIFO byte count mask */
-+
-+/* RSR bits */
-+#define IT87_RXFBC 0x3f /* receiver FIFO byte count mask */
-+#define IT87_RXFTO 0x80 /* receiver FIFO time-out */
-+
-+/* IIR bits */
-+#define IT87_IP 0x01 /* interrupt pending */
-+#define IT87_II 0x06 /* interrupt identification mask */
-+#define IT87_II_NOINT 0x00 /* no interrupt */
-+#define IT87_II_TXLDL 0x02 /* transmitter low data level */
-+#define IT87_II_RXDS 0x04 /* receiver data stored */
-+#define IT87_II_RXFO 0x06 /* receiver FIFO overrun */
-+
-+/*
-+ * IT8512E/F
-+ *
-+ * Hardware data obtained from:
-+ *
-+ * IT8512E/F
-+ * Embedded Controller
-+ * Preliminary Specification V0.4.1
-+ *
-+ * Note that the CIR registers are not directly available to the host, because
-+ * they only are accessible to the integrated microcontroller. Thus, in order
-+ * use it, some kind of bridging is required. As the bridging may depend on
-+ * the controller firmware in use, we are going to use the PNP ID in order to
-+ * determine the strategy and ports available. See after these generic
-+ * IT8512E/F register definitions for register definitions for those
-+ * strategies.
-+ */
-+
-+/* register offsets */
-+#define IT85_C0DR 0x00 /* data register */
-+#define IT85_C0MSTCR 0x01 /* master control register */
-+#define IT85_C0IER 0x02 /* interrupt enable register */
-+#define IT85_C0IIR 0x03 /* interrupt identification register */
-+#define IT85_C0CFR 0x04 /* carrier frequency register */
-+#define IT85_C0RCR 0x05 /* receiver control register */
-+#define IT85_C0TCR 0x06 /* transmitter control register */
-+#define IT85_C0SCK 0x07 /* slow clock control register */
-+#define IT85_C0BDLR 0x08 /* baud rate divisor low byte register */
-+#define IT85_C0BDHR 0x09 /* baud rate divisor high byte register */
-+#define IT85_C0TFSR 0x0a /* transmitter FIFO status register */
-+#define IT85_C0RFSR 0x0b /* receiver FIFO status register */
-+#define IT85_C0WCL 0x0d /* wakeup code length register */
-+#define IT85_C0WCR 0x0e /* wakeup code read/write register */
-+#define IT85_C0WPS 0x0f /* wakeup power control/status register */
-+
-+#define IT85_IOREG_LENGTH 0x10 /* length of register file */
-+
-+/* C0MSTCR bits */
-+#define IT85_RESET 0x01 /* reset */
-+#define IT85_FIFOCLR 0x02 /* FIFO clear bit */
-+#define IT85_FIFOTL 0x0c /* FIFO level threshold mask */
-+#define IT85_FIFOTL_DEFAULT 0x08 /* FIFO level threshold default
-+ * 0x00 -> 1, 0x04 -> 7, 0x08 -> 17,
-+ * 0x0c -> 25 */
-+#define IT85_ILE 0x10 /* internal loopback enable */
-+#define IT85_ILSEL 0x20 /* internal loopback select */
-+
-+/* C0IER bits */
-+#define IT85_TLDLIE 0x01 /* TX low data level interrupt enable */
-+#define IT85_RDAIE 0x02 /* RX data available interrupt enable */
-+#define IT85_RFOIE 0x04 /* RX FIFO overrun interrupt enable */
-+#define IT85_IEC 0x80 /* interrupt enable function control */
-+
-+/* C0IIR bits */
-+#define IT85_TLDLI 0x01 /* transmitter low data level interrupt */
-+#define IT85_RDAI 0x02 /* receiver data available interrupt */
-+#define IT85_RFOI 0x04 /* receiver FIFO overrun interrupt */
-+#define IT85_NIP 0x80 /* no interrupt pending */
-+
-+/* C0CFR bits */
-+#define IT85_CFQ 0x1f /* carrier frequency mask */
-+#define IT85_HCFS 0x20 /* high speed carrier frequency select */
-+
-+/* C0RCR bits */
-+#define IT85_RXDCR 0x07 /* receiver demodulation carrier range mask */
-+#define IT85_RXACT 0x08 /* receiver active */
-+#define IT85_RXEND 0x10 /* receiver demodulation enable */
-+#define IT85_RDWOS 0x20 /* receiver data without sync */
-+#define IT85_RXEN 0x80 /* receiver enable */
-+
-+/* C0TCR bits */
-+#define IT85_TXMPW 0x07 /* transmitter modulation pulse width mask */
-+#define IT85_TXMPW_DEFAULT 0x04 /* default modulation pulse width */
-+#define IT85_TXMPM 0x18 /* transmitter modulation pulse mode mask */
-+#define IT85_TXMPM_DEFAULT 0x00 /* modulation pulse mode default */
-+#define IT85_TXENDF 0x20 /* transmitter deferral */
-+#define IT85_TXRLE 0x40 /* transmitter run length enable */
-+
-+/* C0SCK bits */
-+#define IT85_SCKS 0x01 /* slow clock select */
-+#define IT85_TXDCKG 0x02 /* TXD clock gating */
-+#define IT85_DLL1P8E 0x04 /* DLL 1.8432M enable */
-+#define IT85_DLLTE 0x08 /* DLL test enable */
-+#define IT85_BRCM 0x70 /* baud rate count mode */
-+#define IT85_DLLOCK 0x80 /* DLL lock */
-+
-+/* C0TFSR bits */
-+#define IT85_TXFBC 0x3f /* transmitter FIFO count mask */
-+
-+/* C0RFSR bits */
-+#define IT85_RXFBC 0x3f /* receiver FIFO count mask */
-+#define IT85_RXFTO 0x80 /* receiver FIFO time-out */
-+
-+/* C0WCL bits */
-+#define IT85_WCL 0x3f /* wakeup code length mask */
-+
-+/* C0WPS bits */
-+#define IT85_CIRPOSIE 0x01 /* power on/off status interrupt enable */
-+#define IT85_CIRPOIS 0x02 /* power on/off interrupt status */
-+#define IT85_CIRPOII 0x04 /* power on/off interrupt identification */
-+#define IT85_RCRST 0x10 /* wakeup code reading counter reset bit */
-+#define IT85_WCRST 0x20 /* wakeup code writing counter reset bit */
-+
-+/*
-+ * ITE8708
-+ *
-+ * Hardware data obtained from hacked driver for IT8512 in this forum post:
-+ *
-+ *
http://ubuntuforums.org/showthread.php?t=1028640
-+ *
-+ * Although there's no official documentation for that driver, analysis would
-+ * suggest that it maps the 16 registers of IT8512 onto two 8-register banks,
-+ * selectable by a single bank-select bit that's mapped onto both banks. The
-+ * IT8512 registers are mapped in a different order, so that the first bank
-+ * maps the ones that are used more often, and two registers that share a
-+ * reserved high-order bit are placed at the same offset in both banks in
-+ * order to reuse the reserved bit as the bank select bit.
-+ */
-+
-+/* register offsets */
-+
-+/* mapped onto both banks */
-+#define IT8708_BANKSEL 0x07 /* bank select register */
-+#define IT8708_HRAE 0x80 /* high registers access enable */
-+
-+/* mapped onto the low bank */
-+#define IT8708_C0DR 0x00 /* data register */
-+#define IT8708_C0MSTCR 0x01 /* master control register */
-+#define IT8708_C0IER 0x02 /* interrupt enable register */
-+#define IT8708_C0IIR 0x03 /* interrupt identification register */
-+#define IT8708_C0RFSR 0x04 /* receiver FIFO status register */
-+#define IT8708_C0RCR 0x05 /* receiver control register */
-+#define IT8708_C0TFSR 0x06 /* transmitter FIFO status register */
-+#define IT8708_C0TCR 0x07 /* transmitter control register */
-+
-+/* mapped onto the high bank */
-+#define IT8708_C0BDLR 0x01 /* baud rate divisor low byte register */
-+#define IT8708_C0BDHR 0x02 /* baud rate divisor high byte register */
-+#define IT8708_C0CFR 0x04 /* carrier frequency register */
-+
-+/* registers whose bank mapping we don't know, since they weren't being used
-+ * in the hacked driver... most probably they belong to the high bank too,
-+ * since they fit in the holes the other registers leave */
-+#define IT8708_C0SCK 0x03 /* slow clock control register */
-+#define IT8708_C0WCL 0x05 /* wakeup code length register */
-+#define IT8708_C0WCR 0x06 /* wakeup code read/write register */
-+#define IT8708_C0WPS 0x07 /* wakeup power control/status register */
-+
-+#define IT8708_IOREG_LENGTH 0x08 /* length of register file */
-+
-+/* two more registers that are defined in the hacked driver, but can't be
-+ * found in the data sheets; no idea what they are or how they are accessed,
-+ * since the hacked driver doesn't seem to use them */
-+#define IT8708_CSCRR 0x00
-+#define IT8708_CGPINTR 0x01
-+
-+/* CSCRR bits */
-+#define IT8708_CSCRR_SCRB 0x3f
-+#define IT8708_CSCRR_PM 0x80
-+
-+/* CGPINTR bits */
-+#define IT8708_CGPINT 0x01
-+
-+/*
-+ * ITE8709
-+ *
-+ * Hardware interfacing data obtained from the original lirc_ite8709 driver.
-+ * Verbatim from its sources:
-+ *
-+ * The ITE8709 device seems to be the combination of IT8512 superIO chip and
-+ * a specific firmware running on the IT8512's embedded micro-controller.
-+ * In addition of the embedded micro-controller, the IT8512 chip contains a
-+ * CIR module and several other modules. A few modules are directly accessible
-+ * by the host CPU, but most of them are only accessible by the
-+ * micro-controller. The CIR module is only accessible by the
-+ * micro-controller.
-+ *
-+ * The battery-backed SRAM module is accessible by the host CPU and the
-+ * micro-controller. So one of the MC's firmware role is to act as a bridge
-+ * between the host CPU and the CIR module. The firmware implements a kind of
-+ * communication protocol using the SRAM module as a shared memory. The IT8512
-+ * specification is publicly available on ITE's web site, but the
-+ * communication protocol is not, so it was reverse-engineered.
-+ */
-+
-+/* register offsets */
-+#define IT8709_RAM_IDX 0x00 /* index into the SRAM module bytes */
-+#define IT8709_RAM_VAL 0x01 /* read/write data to the indexed byte */
-+
-+#define IT8709_IOREG_LENGTH 0x02 /* length of register file */
-+
-+/* register offsets inside the SRAM module */
-+#define IT8709_MODE 0x1a /* request/ack byte */
-+#define IT8709_REG_IDX 0x1b /* index of the CIR register to access */
-+#define IT8709_REG_VAL 0x1c /* value read/to be written */
-+#define IT8709_IIR 0x1e /* interrupt identification register */
-+#define IT8709_RFSR 0x1f /* receiver FIFO status register */
-+#define IT8709_FIFO 0x20 /* start of in RAM RX FIFO copy */
-+
-+/* MODE values */
-+#define IT8709_IDLE 0x00
-+#define IT8709_WRITE 0x01
-+#define IT8709_READ 0x02
-diff --git a/drivers/media/rc/keymaps/Makefile b/drivers/media/rc/keymaps/Makefile
-index cb72121..85cac7d 100644
---- a/drivers/media/rc/keymaps/Makefile
-+++ b/drivers/media/rc/keymaps/Makefile
-@@ -37,7 +37,6 @@ obj-$(CONFIG_RC_MAP) += rc-adstech-dvb-t-pci.o \
- rc-gadmei-rm008z.o \
- rc-genius-tvgo-a11mce.o \
- rc-gotview7135.o \
-- rc-hauppauge-new.o \
- rc-imon-mce.o \
- rc-imon-pad.o \
- rc-iodata-bctv7e.o \
-@@ -68,8 +67,7 @@ obj-$(CONFIG_RC_MAP) += rc-adstech-dvb-t-pci.o \
- rc-proteus-2309.o \
- rc-purpletv.o \
- rc-pv951.o \
-- rc-rc5-hauppauge-new.o \
-- rc-rc5-tv.o \
-+ rc-hauppauge.o \
- rc-rc6-mce.o \
- rc-real-audio-220-32-keys.o \
- rc-streamzap.o \
-diff --git a/drivers/media/rc/keymaps/rc-adstech-dvb-t-pci.c
b/drivers/media/rc/keymaps/rc-adstech-dvb-t-pci.c
-index 136d395..9a8752f 100644
---- a/drivers/media/rc/keymaps/rc-adstech-dvb-t-pci.c
-+++ b/drivers/media/rc/keymaps/rc-adstech-dvb-t-pci.c
-@@ -50,9 +50,9 @@ static struct rc_map_table adstech_dvb_t_pci[] = {
- { 0x13, KEY_TUNER }, /* Live */
- { 0x0a, KEY_A },
- { 0x12, KEY_B },
-- { 0x03, KEY_PROG1 }, /* 1 */
-- { 0x01, KEY_PROG2 }, /* 2 */
-- { 0x00, KEY_PROG3 }, /* 3 */
-+ { 0x03, KEY_RED }, /* 1 */
-+ { 0x01, KEY_GREEN }, /* 2 */
-+ { 0x00, KEY_YELLOW }, /* 3 */
- { 0x06, KEY_DVD },
- { 0x48, KEY_AUX }, /* Photo */
- { 0x40, KEY_VIDEO },
-diff --git a/drivers/media/rc/keymaps/rc-avermedia-dvbt.c
b/drivers/media/rc/keymaps/rc-avermedia-dvbt.c
-index 3ddb41b..c25809d 100644
---- a/drivers/media/rc/keymaps/rc-avermedia-dvbt.c
-+++ b/drivers/media/rc/keymaps/rc-avermedia-dvbt.c
-@@ -26,12 +26,12 @@ static struct rc_map_table avermedia_dvbt[] = {
- { 0x16, KEY_8 }, /* '8' / 'down arrow' */
- { 0x36, KEY_9 }, /* '9' */
-
-- { 0x20, KEY_LIST }, /* 'source' */
-+ { 0x20, KEY_VIDEO }, /* 'source' */
- { 0x10, KEY_TEXT }, /* 'teletext' */
- { 0x00, KEY_POWER }, /* 'power' */
- { 0x04, KEY_AUDIO }, /* 'audio' */
- { 0x06, KEY_ZOOM }, /* 'full screen' */
-- { 0x18, KEY_VIDEO }, /* 'display' */
-+ { 0x18, KEY_SWITCHVIDEOMODE }, /* 'display' */
- { 0x38, KEY_SEARCH }, /* 'loop' */
- { 0x08, KEY_INFO }, /* 'preview' */
- { 0x2a, KEY_REWIND }, /* 'backward <<' */
-diff --git a/drivers/media/rc/keymaps/rc-avermedia-m135a.c
b/drivers/media/rc/keymaps/rc-avermedia-m135a.c
-index 357fea5..3d2cbe4 100644
---- a/drivers/media/rc/keymaps/rc-avermedia-m135a.c
-+++ b/drivers/media/rc/keymaps/rc-avermedia-m135a.c
-@@ -108,7 +108,7 @@ static struct rc_map_table avermedia_m135a[] = {
- { 0x0414, KEY_TEXT },
- { 0x0415, KEY_EPG },
- { 0x041a, KEY_TV2 }, /* PIP */
-- { 0x041b, KEY_MHP }, /* Snapshot */
-+ { 0x041b, KEY_CAMERA }, /* Snapshot */
-
- { 0x0417, KEY_RECORD },
- { 0x0416, KEY_PLAYPAUSE },
-diff --git a/drivers/media/rc/keymaps/rc-avermedia-m733a-rm-k6.c
b/drivers/media/rc/keymaps/rc-avermedia-m733a-rm-k6.c
-index e694e6e..8cd7f28 100644
---- a/drivers/media/rc/keymaps/rc-avermedia-m733a-rm-k6.c
-+++ b/drivers/media/rc/keymaps/rc-avermedia-m733a-rm-k6.c
-@@ -56,7 +56,7 @@ static struct rc_map_table avermedia_m733a_rm_k6[] = {
- { 0x0414, KEY_TEXT },
- { 0x0415, KEY_EPG },
- { 0x041a, KEY_TV2 }, /* PIP */
-- { 0x041b, KEY_MHP }, /* Snapshot */
-+ { 0x041b, KEY_CAMERA }, /* Snapshot */
-
- { 0x0417, KEY_RECORD },
- { 0x0416, KEY_PLAYPAUSE },
-diff --git a/drivers/media/rc/keymaps/rc-avermedia-rm-ks.c
b/drivers/media/rc/keymaps/rc-avermedia-rm-ks.c
-index f4ca1ff..9d68af2 100644
---- a/drivers/media/rc/keymaps/rc-avermedia-rm-ks.c
-+++ b/drivers/media/rc/keymaps/rc-avermedia-rm-ks.c
-@@ -31,7 +31,7 @@ static struct rc_map_table avermedia_rm_ks[] = {
- { 0x0505, KEY_VOLUMEDOWN },
- { 0x0506, KEY_MUTE },
- { 0x0507, KEY_RIGHT },
-- { 0x0508, KEY_PROG1 },
-+ { 0x0508, KEY_RED },
- { 0x0509, KEY_1 },
- { 0x050a, KEY_2 },
- { 0x050b, KEY_3 },
-diff --git a/drivers/media/rc/keymaps/rc-behold-columbus.c
b/drivers/media/rc/keymaps/rc-behold-columbus.c
-index 4b787fa..8bf058f 100644
---- a/drivers/media/rc/keymaps/rc-behold-columbus.c
-+++ b/drivers/media/rc/keymaps/rc-behold-columbus.c
-@@ -28,7 +28,7 @@ static struct rc_map_table behold_columbus[] = {
- * */
-
- { 0x13, KEY_MUTE },
-- { 0x11, KEY_PROPS },
-+ { 0x11, KEY_VIDEO },
- { 0x1C, KEY_TUNER }, /* KEY_TV/KEY_RADIO */
- { 0x12, KEY_POWER },
-
-diff --git a/drivers/media/rc/keymaps/rc-behold.c b/drivers/media/rc/keymaps/rc-behold.c
-index 0ee1f14..c909a23 100644
---- a/drivers/media/rc/keymaps/rc-behold.c
-+++ b/drivers/media/rc/keymaps/rc-behold.c
-@@ -97,7 +97,7 @@ static struct rc_map_table behold[] = {
- { 0x6b861a, KEY_STOP },
- { 0x6b860e, KEY_TEXT },
- { 0x6b861f, KEY_RED }, /*XXX KEY_AUDIO */
-- { 0x6b861e, KEY_YELLOW }, /*XXX KEY_SOURCE */
-+ { 0x6b861e, KEY_VIDEO },
-
- /* 0x1d 0x13 0x19 *
- * SLEEP PREVIEW DVB *
-diff --git a/drivers/media/rc/keymaps/rc-budget-ci-old.c
b/drivers/media/rc/keymaps/rc-budget-ci-old.c
-index 97fc386..2f66e43 100644
---- a/drivers/media/rc/keymaps/rc-budget-ci-old.c
-+++ b/drivers/media/rc/keymaps/rc-budget-ci-old.c
-@@ -12,7 +12,8 @@
-
- #include <media/rc-map.h>
-
--/* From reading the following remotes:
-+/*
-+ * From reading the following remotes:
- * Zenith Universal 7 / TV Mode 807 / VCR Mode 837
- * Hauppauge (from NOVA-CI-s box product)
- * This is a "middle of the road" approach, differences are noted
-diff --git a/drivers/media/rc/keymaps/rc-cinergy.c
b/drivers/media/rc/keymaps/rc-cinergy.c
-index 99520ff..cf3a6bf 100644
---- a/drivers/media/rc/keymaps/rc-cinergy.c
-+++ b/drivers/media/rc/keymaps/rc-cinergy.c
-@@ -25,7 +25,7 @@ static struct rc_map_table cinergy[] = {
- { 0x09, KEY_9 },
-
- { 0x0a, KEY_POWER },
-- { 0x0b, KEY_PROG1 }, /* app */
-+ { 0x0b, KEY_MEDIA }, /* app */
- { 0x0c, KEY_ZOOM }, /* zoom/fullscreen */
- { 0x0d, KEY_CHANNELUP }, /* channel */
- { 0x0e, KEY_CHANNELDOWN }, /* channel- */
-diff --git a/drivers/media/rc/keymaps/rc-dntv-live-dvb-t.c
b/drivers/media/rc/keymaps/rc-dntv-live-dvb-t.c
-index 43912bd..82c0200 100644
---- a/drivers/media/rc/keymaps/rc-dntv-live-dvb-t.c
-+++ b/drivers/media/rc/keymaps/rc-dntv-live-dvb-t.c
-@@ -32,7 +32,7 @@ static struct rc_map_table dntv_live_dvb_t[] = {
- { 0x0c, KEY_SEARCH }, /* scan */
- { 0x0d, KEY_STOP },
- { 0x0e, KEY_PAUSE },
-- { 0x0f, KEY_LIST }, /* source */
-+ { 0x0f, KEY_VIDEO }, /* source */
-
- { 0x10, KEY_MUTE },
- { 0x11, KEY_REWIND }, /* backward << */
-diff --git a/drivers/media/rc/keymaps/rc-encore-enltv.c
b/drivers/media/rc/keymaps/rc-encore-enltv.c
-index afa4e92..e56ac6e 100644
---- a/drivers/media/rc/keymaps/rc-encore-enltv.c
-+++ b/drivers/media/rc/keymaps/rc-encore-enltv.c
-@@ -24,7 +24,7 @@ static struct rc_map_table encore_enltv[] = {
- { 0x1e, KEY_TV },
- { 0x00, KEY_VIDEO },
- { 0x01, KEY_AUDIO }, /* music */
-- { 0x02, KEY_MHP }, /* picture */
-+ { 0x02, KEY_CAMERA }, /* picture */
-
- { 0x1f, KEY_1 },
- { 0x03, KEY_2 },
-@@ -77,7 +77,7 @@ static struct rc_map_table encore_enltv[] = {
- { 0x50, KEY_SLEEP }, /* shutdown */
- { 0x51, KEY_MODE }, /* stereo > main */
- { 0x52, KEY_SELECT }, /* stereo > sap */
-- { 0x53, KEY_PROG1 }, /* teletext */
-+ { 0x53, KEY_TEXT }, /* teletext */
-
-
- { 0x59, KEY_RED }, /* AP1 */
-diff --git a/drivers/media/rc/keymaps/rc-encore-enltv2.c
b/drivers/media/rc/keymaps/rc-encore-enltv2.c
-index 7d5b00e..b6264f1 100644
---- a/drivers/media/rc/keymaps/rc-encore-enltv2.c
-+++ b/drivers/media/rc/keymaps/rc-encore-enltv2.c
-@@ -32,7 +32,7 @@ static struct rc_map_table encore_enltv2[] = {
- { 0x64, KEY_LAST }, /* +100 */
- { 0x4e, KEY_AGAIN }, /* Recall */
-
-- { 0x6c, KEY_SWITCHVIDEOMODE }, /* Video Source */
-+ { 0x6c, KEY_VIDEO }, /* Video Source */
- { 0x5e, KEY_MENU },
- { 0x56, KEY_SCREEN },
- { 0x7a, KEY_SETUP },
-diff --git a/drivers/media/rc/keymaps/rc-flydvb.c b/drivers/media/rc/keymaps/rc-flydvb.c
-index aea2f4a..a8b0f66 100644
---- a/drivers/media/rc/keymaps/rc-flydvb.c
-+++ b/drivers/media/rc/keymaps/rc-flydvb.c
-@@ -37,8 +37,8 @@ static struct rc_map_table flydvb[] = {
- { 0x13, KEY_CHANNELDOWN }, /* CH- */
- { 0x1d, KEY_ENTER }, /* Enter */
-
-- { 0x1a, KEY_MODE }, /* PIP */
-- { 0x18, KEY_TUNER }, /* Source */
-+ { 0x1a, KEY_TV2 }, /* PIP */
-+ { 0x18, KEY_VIDEO }, /* Source */
-
- { 0x1e, KEY_RECORD }, /* Record/Pause */
- { 0x15, KEY_ANGLE }, /* Swap (no label on key) */
-diff --git a/drivers/media/rc/keymaps/rc-hauppauge-new.c
b/drivers/media/rc/keymaps/rc-hauppauge-new.c
-deleted file mode 100644
-index bd11da4..0000000
---- a/drivers/media/rc/keymaps/rc-hauppauge-new.c
-+++ /dev/null
-@@ -1,100 +0,0 @@
--/* hauppauge-new.h - Keytable for hauppauge_new Remote Controller
-- *
-- * keymap imported from ir-keymaps.c
-- *
-- * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab(a)redhat.com>
-- *
-- * This program is free software; you can redistribute it and/or modify
-- * it under the terms of the GNU General Public License as published by
-- * the Free Software Foundation; either version 2 of the License, or
-- * (at your option) any later version.
-- */
--
--#include <media/rc-map.h>
--
--/* Hauppauge: the newer, gray remotes (seems there are multiple
-- * slightly different versions), shipped with cx88+ivtv cards.
-- * almost rc5 coding, but some non-standard keys */
--
--static struct rc_map_table hauppauge_new[] = {
-- /* Keys 0 to 9 */
-- { 0x00, KEY_0 },
-- { 0x01, KEY_1 },
-- { 0x02, KEY_2 },
-- { 0x03, KEY_3 },
-- { 0x04, KEY_4 },
-- { 0x05, KEY_5 },
-- { 0x06, KEY_6 },
-- { 0x07, KEY_7 },
-- { 0x08, KEY_8 },
-- { 0x09, KEY_9 },
--
-- { 0x0a, KEY_TEXT }, /* keypad asterisk as well */
-- { 0x0b, KEY_RED }, /* red button */
-- { 0x0c, KEY_RADIO },
-- { 0x0d, KEY_MENU },
-- { 0x0e, KEY_SUBTITLE }, /* also the # key */
-- { 0x0f, KEY_MUTE },
-- { 0x10, KEY_VOLUMEUP },
-- { 0x11, KEY_VOLUMEDOWN },
-- { 0x12, KEY_PREVIOUS }, /* previous channel */
-- { 0x14, KEY_UP },
-- { 0x15, KEY_DOWN },
-- { 0x16, KEY_LEFT },
-- { 0x17, KEY_RIGHT },
-- { 0x18, KEY_VIDEO }, /* Videos */
-- { 0x19, KEY_AUDIO }, /* Music */
-- /* 0x1a: Pictures - presume this means
-- "Multimedia Home Platform" -
-- no "PICTURES" key in input.h
-- */
-- { 0x1a, KEY_MHP },
--
-- { 0x1b, KEY_EPG }, /* Guide */
-- { 0x1c, KEY_TV },
-- { 0x1e, KEY_NEXTSONG }, /* skip >| */
-- { 0x1f, KEY_EXIT }, /* back/exit */
-- { 0x20, KEY_CHANNELUP }, /* channel / program + */
-- { 0x21, KEY_CHANNELDOWN }, /* channel / program - */
-- { 0x22, KEY_CHANNEL }, /* source (old black remote) */
-- { 0x24, KEY_PREVIOUSSONG }, /* replay |< */
-- { 0x25, KEY_ENTER }, /* OK */
-- { 0x26, KEY_SLEEP }, /* minimize (old black remote) */
-- { 0x29, KEY_BLUE }, /* blue key */
-- { 0x2e, KEY_GREEN }, /* green button */
-- { 0x30, KEY_PAUSE }, /* pause */
-- { 0x32, KEY_REWIND }, /* backward << */
-- { 0x34, KEY_FASTFORWARD }, /* forward >> */
-- { 0x35, KEY_PLAY },
-- { 0x36, KEY_STOP },
-- { 0x37, KEY_RECORD }, /* recording */
-- { 0x38, KEY_YELLOW }, /* yellow key */
-- { 0x3b, KEY_SELECT }, /* top right button */
-- { 0x3c, KEY_ZOOM }, /* full */
-- { 0x3d, KEY_POWER }, /* system power (green button) */
--};
--
--static struct rc_map_list hauppauge_new_map = {
-- .map = {
-- .scan = hauppauge_new,
-- .size = ARRAY_SIZE(hauppauge_new),
-- .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
-- .name = RC_MAP_HAUPPAUGE_NEW,
-- }
--};
--
--static int __init init_rc_map_hauppauge_new(void)
--{
-- return rc_map_register(&hauppauge_new_map);
--}
--
--static void __exit exit_rc_map_hauppauge_new(void)
--{
-- rc_map_unregister(&hauppauge_new_map);
--}
--
--module_init(init_rc_map_hauppauge_new)
--module_exit(exit_rc_map_hauppauge_new)
--
--MODULE_LICENSE("GPL");
--MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab(a)redhat.com>");
-diff --git a/drivers/media/rc/keymaps/rc-hauppauge.c
b/drivers/media/rc/keymaps/rc-hauppauge.c
-new file mode 100644
-index 0000000..cd3db77
---- /dev/null
-+++ b/drivers/media/rc/keymaps/rc-hauppauge.c
-@@ -0,0 +1,241 @@
-+/* rc-hauppauge.c - Keytable for Hauppauge Remote Controllers
-+ *
-+ * keymap imported from ir-keymaps.c
-+ *
-+ * This map currently contains the code for four different RCs:
-+ * - New Hauppauge Gray;
-+ * - Old Hauppauge Gray (with a golden screen for media keys);
-+ * - Hauppauge Black;
-+ * - DSR-0112 remote bundled with Haupauge MiniStick.
-+ *
-+ * Copyright (c) 2010-2011 by Mauro Carvalho Chehab <mchehab(a)redhat.com>
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ */
-+
-+#include <media/rc-map.h>
-+
-+/*
-+ * Hauppauge:the newer, gray remotes (seems there are multiple
-+ * slightly different versions), shipped with cx88+ivtv cards.
-+ *
-+ * This table contains the complete RC5 code, instead of just the data part
-+ */
-+
-+static struct rc_map_table rc5_hauppauge_new[] = {
-+ /*
-+ * Remote Controller Hauppauge Gray found on modern devices
-+ * Keycodes start with address = 0x1e
-+ */
-+
-+ { 0x1e3b, KEY_SELECT }, /* GO / house symbol */
-+ { 0x1e3d, KEY_POWER2 }, /* system power (green button) */
-+
-+ { 0x1e1c, KEY_TV },
-+ { 0x1e18, KEY_VIDEO }, /* Videos */
-+ { 0x1e19, KEY_AUDIO }, /* Music */
-+ { 0x1e1a, KEY_CAMERA }, /* Pictures */
-+
-+ { 0x1e1b, KEY_EPG }, /* Guide */
-+ { 0x1e0c, KEY_RADIO },
-+
-+ { 0x1e14, KEY_UP },
-+ { 0x1e15, KEY_DOWN },
-+ { 0x1e16, KEY_LEFT },
-+ { 0x1e17, KEY_RIGHT },
-+ { 0x1e25, KEY_OK }, /* OK */
-+
-+ { 0x1e1f, KEY_EXIT }, /* back/exit */
-+ { 0x1e0d, KEY_MENU },
-+
-+ { 0x1e10, KEY_VOLUMEUP },
-+ { 0x1e11, KEY_VOLUMEDOWN },
-+
-+ { 0x1e12, KEY_PREVIOUS }, /* previous channel */
-+ { 0x1e0f, KEY_MUTE },
-+
-+ { 0x1e20, KEY_CHANNELUP }, /* channel / program + */
-+ { 0x1e21, KEY_CHANNELDOWN }, /* channel / program - */
-+
-+ { 0x1e37, KEY_RECORD }, /* recording */
-+ { 0x1e36, KEY_STOP },
-+
-+ { 0x1e32, KEY_REWIND }, /* backward << */
-+ { 0x1e35, KEY_PLAY },
-+ { 0x1e34, KEY_FASTFORWARD }, /* forward >> */
-+
-+ { 0x1e24, KEY_PREVIOUSSONG }, /* replay |< */
-+ { 0x1e30, KEY_PAUSE }, /* pause */
-+ { 0x1e1e, KEY_NEXTSONG }, /* skip >| */
-+
-+ { 0x1e01, KEY_1 },
-+ { 0x1e02, KEY_2 },
-+ { 0x1e03, KEY_3 },
-+
-+ { 0x1e04, KEY_4 },
-+ { 0x1e05, KEY_5 },
-+ { 0x1e06, KEY_6 },
-+
-+ { 0x1e07, KEY_7 },
-+ { 0x1e08, KEY_8 },
-+ { 0x1e09, KEY_9 },
-+
-+ { 0x1e0a, KEY_TEXT }, /* keypad asterisk as well */
-+ { 0x1e00, KEY_0 },
-+ { 0x1e0e, KEY_SUBTITLE }, /* also the Pound key (#) */
-+
-+ { 0x1e0b, KEY_RED }, /* red button */
-+ { 0x1e2e, KEY_GREEN }, /* green button */
-+ { 0x1e38, KEY_YELLOW }, /* yellow key */
-+ { 0x1e29, KEY_BLUE }, /* blue key */
-+
-+ /*
-+ * Old Remote Controller Hauppauge Gray with a golden screen
-+ * Keycodes start with address = 0x1f
-+ */
-+ { 0x1f3d, KEY_POWER2 }, /* system power (green button) */
-+ { 0x1f3b, KEY_SELECT }, /* GO */
-+
-+ /* Keys 0 to 9 */
-+ { 0x1f00, KEY_0 },
-+ { 0x1f01, KEY_1 },
-+ { 0x1f02, KEY_2 },
-+ { 0x1f03, KEY_3 },
-+ { 0x1f04, KEY_4 },
-+ { 0x1f05, KEY_5 },
-+ { 0x1f06, KEY_6 },
-+ { 0x1f07, KEY_7 },
-+ { 0x1f08, KEY_8 },
-+ { 0x1f09, KEY_9 },
-+
-+ { 0x1f1f, KEY_EXIT }, /* back/exit */
-+ { 0x1f0d, KEY_MENU },
-+
-+ { 0x1f10, KEY_VOLUMEUP },
-+ { 0x1f11, KEY_VOLUMEDOWN },
-+ { 0x1f20, KEY_CHANNELUP }, /* channel / program + */
-+ { 0x1f21, KEY_CHANNELDOWN }, /* channel / program - */
-+ { 0x1f25, KEY_ENTER }, /* OK */
-+
-+ { 0x1f0b, KEY_RED }, /* red button */
-+ { 0x1f2e, KEY_GREEN }, /* green button */
-+ { 0x1f38, KEY_YELLOW }, /* yellow key */
-+ { 0x1f29, KEY_BLUE }, /* blue key */
-+
-+ { 0x1f0f, KEY_MUTE },
-+ { 0x1f0c, KEY_RADIO }, /* There's no indicator on this key */
-+ { 0x1f3c, KEY_ZOOM }, /* full */
-+
-+ { 0x1f32, KEY_REWIND }, /* backward << */
-+ { 0x1f35, KEY_PLAY },
-+ { 0x1f34, KEY_FASTFORWARD }, /* forward >> */
-+
-+ { 0x1f37, KEY_RECORD }, /* recording */
-+ { 0x1f36, KEY_STOP },
-+ { 0x1f30, KEY_PAUSE }, /* pause */
-+
-+ { 0x1f24, KEY_PREVIOUSSONG }, /* replay |< */
-+ { 0x1f1e, KEY_NEXTSONG }, /* skip >| */
-+
-+ /*
-+ * Keycodes for DSR-0112 remote bundled with Haupauge MiniStick
-+ * Keycodes start with address = 0x1d
-+ */
-+ { 0x1d00, KEY_0 },
-+ { 0x1d01, KEY_1 },
-+ { 0x1d02, KEY_2 },
-+ { 0x1d03, KEY_3 },
-+ { 0x1d04, KEY_4 },
-+ { 0x1d05, KEY_5 },
-+ { 0x1d06, KEY_6 },
-+ { 0x1d07, KEY_7 },
-+ { 0x1d08, KEY_8 },
-+ { 0x1d09, KEY_9 },
-+ { 0x1d0a, KEY_TEXT },
-+ { 0x1d0d, KEY_MENU },
-+ { 0x1d0f, KEY_MUTE },
-+ { 0x1d10, KEY_VOLUMEUP },
-+ { 0x1d11, KEY_VOLUMEDOWN },
-+ { 0x1d12, KEY_PREVIOUS }, /* Prev.Ch .. ??? */
-+ { 0x1d14, KEY_UP },
-+ { 0x1d15, KEY_DOWN },
-+ { 0x1d16, KEY_LEFT },
-+ { 0x1d17, KEY_RIGHT },
-+ { 0x1d1c, KEY_TV },
-+ { 0x1d1e, KEY_NEXT }, /* >| */
-+ { 0x1d1f, KEY_EXIT },
-+ { 0x1d20, KEY_CHANNELUP },
-+ { 0x1d21, KEY_CHANNELDOWN },
-+ { 0x1d24, KEY_LAST }, /* <| */
-+ { 0x1d25, KEY_OK },
-+ { 0x1d30, KEY_PAUSE },
-+ { 0x1d32, KEY_REWIND },
-+ { 0x1d34, KEY_FASTFORWARD },
-+ { 0x1d35, KEY_PLAY },
-+ { 0x1d36, KEY_STOP },
-+ { 0x1d37, KEY_RECORD },
-+ { 0x1d3b, KEY_GOTO },
-+ { 0x1d3d, KEY_POWER },
-+ { 0x1d3f, KEY_HOME },
-+
-+ /*
-+ * Keycodes for the old Black Remote Controller
-+ * This one also uses RC-5 protocol
-+ * Keycodes start with address = 0x00
-+ */
-+ { 0x001f, KEY_TV },
-+ { 0x0020, KEY_CHANNELUP },
-+ { 0x000c, KEY_RADIO },
-+
-+ { 0x0011, KEY_VOLUMEDOWN },
-+ { 0x002e, KEY_ZOOM }, /* full screen */
-+ { 0x0010, KEY_VOLUMEUP },
-+
-+ { 0x000d, KEY_MUTE },
-+ { 0x0021, KEY_CHANNELDOWN },
-+ { 0x0022, KEY_VIDEO }, /* source */
-+
-+ { 0x0001, KEY_1 },
-+ { 0x0002, KEY_2 },
-+ { 0x0003, KEY_3 },
-+
-+ { 0x0004, KEY_4 },
-+ { 0x0005, KEY_5 },
-+ { 0x0006, KEY_6 },
-+
-+ { 0x0007, KEY_7 },
-+ { 0x0008, KEY_8 },
-+ { 0x0009, KEY_9 },
-+
-+ { 0x001e, KEY_RED }, /* Reserved */
-+ { 0x0000, KEY_0 },
-+ { 0x0026, KEY_SLEEP }, /* Minimize */
-+};
-+
-+static struct rc_map_list rc5_hauppauge_new_map = {
-+ .map = {
-+ .scan = rc5_hauppauge_new,
-+ .size = ARRAY_SIZE(rc5_hauppauge_new),
-+ .rc_type = RC_TYPE_RC5,
-+ .name = RC_MAP_HAUPPAUGE,
-+ }
-+};
-+
-+static int __init init_rc_map_rc5_hauppauge_new(void)
-+{
-+ return rc_map_register(&rc5_hauppauge_new_map);
-+}
-+
-+static void __exit exit_rc_map_rc5_hauppauge_new(void)
-+{
-+ rc_map_unregister(&rc5_hauppauge_new_map);
-+}
-+
-+module_init(init_rc_map_rc5_hauppauge_new)
-+module_exit(exit_rc_map_rc5_hauppauge_new)
-+
-+MODULE_LICENSE("GPL");
-+MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab(a)redhat.com>");
-diff --git a/drivers/media/rc/keymaps/rc-imon-mce.c
b/drivers/media/rc/keymaps/rc-imon-mce.c
-index cb67184..937a819 100644
---- a/drivers/media/rc/keymaps/rc-imon-mce.c
-+++ b/drivers/media/rc/keymaps/rc-imon-mce.c
-@@ -111,7 +111,7 @@ static struct rc_map_table imon_mce[] = {
- { 0x800ff44d, KEY_TITLE },
-
- { 0x800ff40c, KEY_POWER },
-- { 0x800ff40d, KEY_PROG1 }, /* Windows MCE button */
-+ { 0x800ff40d, KEY_LEFTMETA }, /* Windows MCE button */
-
- };
-
-diff --git a/drivers/media/rc/keymaps/rc-imon-pad.c
b/drivers/media/rc/keymaps/rc-imon-pad.c
-index eef46b7..63d42bd 100644
---- a/drivers/media/rc/keymaps/rc-imon-pad.c
-+++ b/drivers/media/rc/keymaps/rc-imon-pad.c
-@@ -125,7 +125,7 @@ static struct rc_map_table imon_pad[] = {
- { 0x2b8195b7, KEY_CONTEXT_MENU }, /* Left Menu*/
- { 0x02000065, KEY_COMPOSE }, /* RightMenu */
- { 0x28b715b7, KEY_COMPOSE }, /* RightMenu */
-- { 0x2ab195b7, KEY_PROG1 }, /* Go or MultiMon */
-+ { 0x2ab195b7, KEY_LEFTMETA }, /* Go or MultiMon */
- { 0x29b715b7, KEY_DASHBOARD }, /* AppLauncher */
- };
-
-diff --git a/drivers/media/rc/keymaps/rc-kworld-315u.c
b/drivers/media/rc/keymaps/rc-kworld-315u.c
-index 3ce6ef7..7f33edb 100644
---- a/drivers/media/rc/keymaps/rc-kworld-315u.c
-+++ b/drivers/media/rc/keymaps/rc-kworld-315u.c
-@@ -17,7 +17,7 @@
-
- static struct rc_map_table kworld_315u[] = {
- { 0x6143, KEY_POWER },
-- { 0x6101, KEY_TUNER }, /* source */
-+ { 0x6101, KEY_VIDEO }, /* source */
- { 0x610b, KEY_ZOOM },
- { 0x6103, KEY_POWER2 }, /* shutdown */
-
-diff --git a/drivers/media/rc/keymaps/rc-kworld-plus-tv-analog.c
b/drivers/media/rc/keymaps/rc-kworld-plus-tv-analog.c
-index e45f0b8..08d1831 100644
---- a/drivers/media/rc/keymaps/rc-kworld-plus-tv-analog.c
-+++ b/drivers/media/rc/keymaps/rc-kworld-plus-tv-analog.c
-@@ -17,7 +17,7 @@
- */
-
- static struct rc_map_table kworld_plus_tv_analog[] = {
-- { 0x0c, KEY_PROG1 }, /* Kworld key */
-+ { 0x0c, KEY_LEFTMETA }, /* Kworld key */
- { 0x16, KEY_CLOSECD }, /* -> ) */
- { 0x1d, KEY_POWER2 },
-
-diff --git a/drivers/media/rc/keymaps/rc-msi-tvanywhere-plus.c
b/drivers/media/rc/keymaps/rc-msi-tvanywhere-plus.c
-index fa8fd0a..8e9969d 100644
---- a/drivers/media/rc/keymaps/rc-msi-tvanywhere-plus.c
-+++ b/drivers/media/rc/keymaps/rc-msi-tvanywhere-plus.c
-@@ -62,7 +62,7 @@ static struct rc_map_table msi_tvanywhere_plus[] = {
- { 0x13, KEY_AGAIN }, /* Recall */
-
- { 0x1e, KEY_POWER }, /* Power */
-- { 0x07, KEY_TUNER }, /* Source */
-+ { 0x07, KEY_VIDEO }, /* Source */
- { 0x1c, KEY_SEARCH }, /* Scan */
- { 0x18, KEY_MUTE }, /* Mute */
-
-diff --git a/drivers/media/rc/keymaps/rc-nebula.c b/drivers/media/rc/keymaps/rc-nebula.c
-index 3e6f077..ddae20e 100644
---- a/drivers/media/rc/keymaps/rc-nebula.c
-+++ b/drivers/media/rc/keymaps/rc-nebula.c
-@@ -27,7 +27,7 @@ static struct rc_map_table nebula[] = {
- { 0x0b, KEY_AUX },
- { 0x0c, KEY_DVD },
- { 0x0d, KEY_POWER },
-- { 0x0e, KEY_MHP }, /* labelled 'Picture' */
-+ { 0x0e, KEY_CAMERA }, /* labelled 'Picture' */
- { 0x0f, KEY_AUDIO },
- { 0x10, KEY_INFO },
- { 0x11, KEY_F13 }, /* 16:9 */
-diff --git a/drivers/media/rc/keymaps/rc-norwood.c
b/drivers/media/rc/keymaps/rc-norwood.c
-index 629ee9d..f1c1281 100644
---- a/drivers/media/rc/keymaps/rc-norwood.c
-+++ b/drivers/media/rc/keymaps/rc-norwood.c
-@@ -29,7 +29,7 @@ static struct rc_map_table norwood[] = {
- { 0x28, KEY_8 },
- { 0x29, KEY_9 },
-
-- { 0x78, KEY_TUNER }, /* Video Source */
-+ { 0x78, KEY_VIDEO }, /* Video Source */
- { 0x2c, KEY_EXIT }, /* Open/Close software */
- { 0x2a, KEY_SELECT }, /* 2 Digit Select */
- { 0x69, KEY_AGAIN }, /* Recall */
-diff --git a/drivers/media/rc/keymaps/rc-pctv-sedna.c
b/drivers/media/rc/keymaps/rc-pctv-sedna.c
-index fa5ae59..7cdef6e 100644
---- a/drivers/media/rc/keymaps/rc-pctv-sedna.c
-+++ b/drivers/media/rc/keymaps/rc-pctv-sedna.c
-@@ -36,7 +36,7 @@ static struct rc_map_table pctv_sedna[] = {
- { 0x0e, KEY_STOP },
- { 0x0f, KEY_PREVIOUSSONG },
- { 0x10, KEY_ZOOM },
-- { 0x11, KEY_TUNER }, /* Source */
-+ { 0x11, KEY_VIDEO }, /* Source */
- { 0x12, KEY_POWER },
- { 0x13, KEY_MUTE },
- { 0x15, KEY_CHANNELDOWN },
-diff --git a/drivers/media/rc/keymaps/rc-pixelview-mk12.c
b/drivers/media/rc/keymaps/rc-pixelview-mk12.c
-index 8d9f664..125fc39 100644
---- a/drivers/media/rc/keymaps/rc-pixelview-mk12.c
-+++ b/drivers/media/rc/keymaps/rc-pixelview-mk12.c
-@@ -34,7 +34,7 @@ static struct rc_map_table pixelview_mk12[] = {
- { 0x866b13, KEY_AGAIN }, /* loop */
- { 0x866b10, KEY_DIGITS }, /* +100 */
-
-- { 0x866b00, KEY_MEDIA }, /* source */
-+ { 0x866b00, KEY_VIDEO }, /* source */
- { 0x866b18, KEY_MUTE }, /* mute */
- { 0x866b19, KEY_CAMERA }, /* snapshot */
- { 0x866b1a, KEY_SEARCH }, /* scan */
-diff --git a/drivers/media/rc/keymaps/rc-pixelview-new.c
b/drivers/media/rc/keymaps/rc-pixelview-new.c
-index 777a700..bd78d6a 100644
---- a/drivers/media/rc/keymaps/rc-pixelview-new.c
-+++ b/drivers/media/rc/keymaps/rc-pixelview-new.c
-@@ -33,7 +33,7 @@ static struct rc_map_table pixelview_new[] = {
- { 0x3e, KEY_0 },
-
- { 0x1c, KEY_AGAIN }, /* LOOP */
-- { 0x3f, KEY_MEDIA }, /* Source */
-+ { 0x3f, KEY_VIDEO }, /* Source */
- { 0x1f, KEY_LAST }, /* +100 */
- { 0x1b, KEY_MUTE },
-
-diff --git a/drivers/media/rc/keymaps/rc-pixelview.c
b/drivers/media/rc/keymaps/rc-pixelview.c
-index 0ec5988..06187e7 100644
---- a/drivers/media/rc/keymaps/rc-pixelview.c
-+++ b/drivers/media/rc/keymaps/rc-pixelview.c
-@@ -15,7 +15,7 @@
- static struct rc_map_table pixelview[] = {
-
- { 0x1e, KEY_POWER }, /* power */
-- { 0x07, KEY_MEDIA }, /* source */
-+ { 0x07, KEY_VIDEO }, /* source */
- { 0x1c, KEY_SEARCH }, /* scan */
-
-
-diff --git a/drivers/media/rc/keymaps/rc-pv951.c b/drivers/media/rc/keymaps/rc-pv951.c
-index 83a418d..5e8beee 100644
---- a/drivers/media/rc/keymaps/rc-pv951.c
-+++ b/drivers/media/rc/keymaps/rc-pv951.c
-@@ -46,10 +46,10 @@ static struct rc_map_table pv951[] = {
- { 0x0c, KEY_SEARCH }, /* AUTOSCAN */
-
- /* Not sure what to do with these ones! */
-- { 0x0f, KEY_SELECT }, /* SOURCE */
-+ { 0x0f, KEY_VIDEO }, /* SOURCE */
- { 0x0a, KEY_KPPLUS }, /* +100 */
- { 0x14, KEY_EQUAL }, /* SYNC */
-- { 0x1c, KEY_MEDIA }, /* PC/TV */
-+ { 0x1c, KEY_TV }, /* PC/TV */
- };
-
- static struct rc_map_list pv951_map = {
-diff --git a/drivers/media/rc/keymaps/rc-rc5-hauppauge-new.c
b/drivers/media/rc/keymaps/rc-rc5-hauppauge-new.c
-deleted file mode 100644
-index dfc9b15..0000000
---- a/drivers/media/rc/keymaps/rc-rc5-hauppauge-new.c
-+++ /dev/null
-@@ -1,141 +0,0 @@
--/* rc5-hauppauge-new.h - Keytable for rc5_hauppauge_new Remote Controller
-- *
-- * keymap imported from ir-keymaps.c
-- *
-- * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab(a)redhat.com>
-- *
-- * This program is free software; you can redistribute it and/or modify
-- * it under the terms of the GNU General Public License as published by
-- * the Free Software Foundation; either version 2 of the License, or
-- * (at your option) any later version.
-- */
--
--#include <media/rc-map.h>
--
--/*
-- * Hauppauge:the newer, gray remotes (seems there are multiple
-- * slightly different versions), shipped with cx88+ivtv cards.
-- *
-- * This table contains the complete RC5 code, instead of just the data part
-- */
--
--static struct rc_map_table rc5_hauppauge_new[] = {
-- /* Keys 0 to 9 */
-- { 0x1e00, KEY_0 },
-- { 0x1e01, KEY_1 },
-- { 0x1e02, KEY_2 },
-- { 0x1e03, KEY_3 },
-- { 0x1e04, KEY_4 },
-- { 0x1e05, KEY_5 },
-- { 0x1e06, KEY_6 },
-- { 0x1e07, KEY_7 },
-- { 0x1e08, KEY_8 },
-- { 0x1e09, KEY_9 },
--
-- { 0x1e0a, KEY_TEXT }, /* keypad asterisk as well */
-- { 0x1e0b, KEY_RED }, /* red button */
-- { 0x1e0c, KEY_RADIO },
-- { 0x1e0d, KEY_MENU },
-- { 0x1e0e, KEY_SUBTITLE }, /* also the # key */
-- { 0x1e0f, KEY_MUTE },
-- { 0x1e10, KEY_VOLUMEUP },
-- { 0x1e11, KEY_VOLUMEDOWN },
-- { 0x1e12, KEY_PREVIOUS }, /* previous channel */
-- { 0x1e14, KEY_UP },
-- { 0x1e15, KEY_DOWN },
-- { 0x1e16, KEY_LEFT },
-- { 0x1e17, KEY_RIGHT },
-- { 0x1e18, KEY_VIDEO }, /* Videos */
-- { 0x1e19, KEY_AUDIO }, /* Music */
-- /* 0x1e1a: Pictures - presume this means
-- "Multimedia Home Platform" -
-- no "PICTURES" key in input.h
-- */
-- { 0x1e1a, KEY_MHP },
--
-- { 0x1e1b, KEY_EPG }, /* Guide */
-- { 0x1e1c, KEY_TV },
-- { 0x1e1e, KEY_NEXTSONG }, /* skip >| */
-- { 0x1e1f, KEY_EXIT }, /* back/exit */
-- { 0x1e20, KEY_CHANNELUP }, /* channel / program + */
-- { 0x1e21, KEY_CHANNELDOWN }, /* channel / program - */
-- { 0x1e22, KEY_CHANNEL }, /* source (old black remote) */
-- { 0x1e24, KEY_PREVIOUSSONG }, /* replay |< */
-- { 0x1e25, KEY_ENTER }, /* OK */
-- { 0x1e26, KEY_SLEEP }, /* minimize (old black remote) */
-- { 0x1e29, KEY_BLUE }, /* blue key */
-- { 0x1e2e, KEY_GREEN }, /* green button */
-- { 0x1e30, KEY_PAUSE }, /* pause */
-- { 0x1e32, KEY_REWIND }, /* backward << */
-- { 0x1e34, KEY_FASTFORWARD }, /* forward >> */
-- { 0x1e35, KEY_PLAY },
-- { 0x1e36, KEY_STOP },
-- { 0x1e37, KEY_RECORD }, /* recording */
-- { 0x1e38, KEY_YELLOW }, /* yellow key */
-- { 0x1e3b, KEY_SELECT }, /* top right button */
-- { 0x1e3c, KEY_ZOOM }, /* full */
-- { 0x1e3d, KEY_POWER }, /* system power (green button) */
--
-- /* Keycodes for DSR-0112 remote bundled with Haupauge MiniStick */
-- { 0x1d00, KEY_0 },
-- { 0x1d01, KEY_1 },
-- { 0x1d02, KEY_2 },
-- { 0x1d03, KEY_3 },
-- { 0x1d04, KEY_4 },
-- { 0x1d05, KEY_5 },
-- { 0x1d06, KEY_6 },
-- { 0x1d07, KEY_7 },
-- { 0x1d08, KEY_8 },
-- { 0x1d09, KEY_9 },
-- { 0x1d0a, KEY_TEXT },
-- { 0x1d0d, KEY_MENU },
-- { 0x1d0f, KEY_MUTE },
-- { 0x1d10, KEY_VOLUMEUP },
-- { 0x1d11, KEY_VOLUMEDOWN },
-- { 0x1d12, KEY_PREVIOUS }, /* Prev.Ch .. ??? */
-- { 0x1d14, KEY_UP },
-- { 0x1d15, KEY_DOWN },
-- { 0x1d16, KEY_LEFT },
-- { 0x1d17, KEY_RIGHT },
-- { 0x1d1c, KEY_TV },
-- { 0x1d1e, KEY_NEXT }, /* >| */
-- { 0x1d1f, KEY_EXIT },
-- { 0x1d20, KEY_CHANNELUP },
-- { 0x1d21, KEY_CHANNELDOWN },
-- { 0x1d24, KEY_LAST }, /* <| */
-- { 0x1d25, KEY_OK },
-- { 0x1d30, KEY_PAUSE },
-- { 0x1d32, KEY_REWIND },
-- { 0x1d34, KEY_FASTFORWARD },
-- { 0x1d35, KEY_PLAY },
-- { 0x1d36, KEY_STOP },
-- { 0x1d37, KEY_RECORD },
-- { 0x1d3b, KEY_GOTO },
-- { 0x1d3d, KEY_POWER },
-- { 0x1d3f, KEY_HOME },
--};
--
--static struct rc_map_list rc5_hauppauge_new_map = {
-- .map = {
-- .scan = rc5_hauppauge_new,
-- .size = ARRAY_SIZE(rc5_hauppauge_new),
-- .rc_type = RC_TYPE_RC5,
-- .name = RC_MAP_RC5_HAUPPAUGE_NEW,
-- }
--};
--
--static int __init init_rc_map_rc5_hauppauge_new(void)
--{
-- return rc_map_register(&rc5_hauppauge_new_map);
--}
--
--static void __exit exit_rc_map_rc5_hauppauge_new(void)
--{
-- rc_map_unregister(&rc5_hauppauge_new_map);
--}
--
--module_init(init_rc_map_rc5_hauppauge_new)
--module_exit(exit_rc_map_rc5_hauppauge_new)
--
--MODULE_LICENSE("GPL");
--MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab(a)redhat.com>");
-diff --git a/drivers/media/rc/keymaps/rc-rc5-tv.c b/drivers/media/rc/keymaps/rc-rc5-tv.c
-deleted file mode 100644
-index 4fcef9f..0000000
---- a/drivers/media/rc/keymaps/rc-rc5-tv.c
-+++ /dev/null
-@@ -1,81 +0,0 @@
--/* rc5-tv.h - Keytable for rc5_tv Remote Controller
-- *
-- * keymap imported from ir-keymaps.c
-- *
-- * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab(a)redhat.com>
-- *
-- * This program is free software; you can redistribute it and/or modify
-- * it under the terms of the GNU General Public License as published by
-- * the Free Software Foundation; either version 2 of the License, or
-- * (at your option) any later version.
-- */
--
--#include <media/rc-map.h>
--
--/* generic RC5 keytable */
--/* see
http://users.pandora.be/nenya/electronics/rc5/codes00.htm */
--/* used by old (black) Hauppauge remotes */
--
--static struct rc_map_table rc5_tv[] = {
-- /* Keys 0 to 9 */
-- { 0x00, KEY_0 },
-- { 0x01, KEY_1 },
-- { 0x02, KEY_2 },
-- { 0x03, KEY_3 },
-- { 0x04, KEY_4 },
-- { 0x05, KEY_5 },
-- { 0x06, KEY_6 },
-- { 0x07, KEY_7 },
-- { 0x08, KEY_8 },
-- { 0x09, KEY_9 },
--
-- { 0x0b, KEY_CHANNEL }, /* channel / program (japan: 11) */
-- { 0x0c, KEY_POWER }, /* standby */
-- { 0x0d, KEY_MUTE }, /* mute / demute */
-- { 0x0f, KEY_TV }, /* display */
-- { 0x10, KEY_VOLUMEUP },
-- { 0x11, KEY_VOLUMEDOWN },
-- { 0x12, KEY_BRIGHTNESSUP },
-- { 0x13, KEY_BRIGHTNESSDOWN },
-- { 0x1e, KEY_SEARCH }, /* search + */
-- { 0x20, KEY_CHANNELUP }, /* channel / program + */
-- { 0x21, KEY_CHANNELDOWN }, /* channel / program - */
-- { 0x22, KEY_CHANNEL }, /* alt / channel */
-- { 0x23, KEY_LANGUAGE }, /* 1st / 2nd language */
-- { 0x26, KEY_SLEEP }, /* sleeptimer */
-- { 0x2e, KEY_MENU }, /* 2nd controls (USA: menu) */
-- { 0x30, KEY_PAUSE },
-- { 0x32, KEY_REWIND },
-- { 0x33, KEY_GOTO },
-- { 0x35, KEY_PLAY },
-- { 0x36, KEY_STOP },
-- { 0x37, KEY_RECORD }, /* recording */
-- { 0x3c, KEY_TEXT }, /* teletext submode (Japan: 12) */
-- { 0x3d, KEY_SUSPEND }, /* system standby */
--
--};
--
--static struct rc_map_list rc5_tv_map = {
-- .map = {
-- .scan = rc5_tv,
-- .size = ARRAY_SIZE(rc5_tv),
-- .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
-- .name = RC_MAP_RC5_TV,
-- }
--};
--
--static int __init init_rc_map_rc5_tv(void)
--{
-- return rc_map_register(&rc5_tv_map);
--}
--
--static void __exit exit_rc_map_rc5_tv(void)
--{
-- rc_map_unregister(&rc5_tv_map);
--}
--
--module_init(init_rc_map_rc5_tv)
--module_exit(exit_rc_map_rc5_tv)
--
--MODULE_LICENSE("GPL");
--MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab(a)redhat.com>");
-diff --git a/drivers/media/rc/keymaps/rc-rc6-mce.c
b/drivers/media/rc/keymaps/rc-rc6-mce.c
-index 2f5dc06..8dd519e 100644
---- a/drivers/media/rc/keymaps/rc-rc6-mce.c
-+++ b/drivers/media/rc/keymaps/rc-rc6-mce.c
-@@ -30,7 +30,7 @@ static struct rc_map_table rc6_mce[] = {
- { 0x800f040a, KEY_DELETE },
- { 0x800f040b, KEY_ENTER },
- { 0x800f040c, KEY_POWER }, /* PC Power */
-- { 0x800f040d, KEY_PROG1 }, /* Windows MCE button */
-+ { 0x800f040d, KEY_LEFTMETA }, /* Windows MCE button */
- { 0x800f040e, KEY_MUTE },
- { 0x800f040f, KEY_INFO },
-
-diff --git a/drivers/media/rc/keymaps/rc-real-audio-220-32-keys.c
b/drivers/media/rc/keymaps/rc-real-audio-220-32-keys.c
-index 2d14598..6813d11 100644
---- a/drivers/media/rc/keymaps/rc-real-audio-220-32-keys.c
-+++ b/drivers/media/rc/keymaps/rc-real-audio-220-32-keys.c
-@@ -35,7 +35,7 @@ static struct rc_map_table real_audio_220_32_keys[] = {
- { 0x15, KEY_CHANNELDOWN},
- { 0x16, KEY_ENTER},
-
-- { 0x11, KEY_LIST}, /* Source */
-+ { 0x11, KEY_VIDEO}, /* Source */
- { 0x0d, KEY_AUDIO}, /* stereo */
-
- { 0x0f, KEY_PREVIOUS}, /* Prev */
-diff --git a/drivers/media/rc/keymaps/rc-winfast.c
b/drivers/media/rc/keymaps/rc-winfast.c
-index 2747db4..0062ca2 100644
---- a/drivers/media/rc/keymaps/rc-winfast.c
-+++ b/drivers/media/rc/keymaps/rc-winfast.c
-@@ -27,15 +27,15 @@ static struct rc_map_table winfast[] = {
- { 0x0e, KEY_8 },
- { 0x0f, KEY_9 },
-
-- { 0x00, KEY_POWER },
-+ { 0x00, KEY_POWER2 },
- { 0x1b, KEY_AUDIO }, /* Audio Source */
- { 0x02, KEY_TUNER }, /* TV/FM, not on Y0400052 */
- { 0x1e, KEY_VIDEO }, /* Video Source */
- { 0x16, KEY_INFO }, /* Display information */
-- { 0x04, KEY_VOLUMEUP },
-- { 0x08, KEY_VOLUMEDOWN },
-- { 0x0c, KEY_CHANNELUP },
-- { 0x10, KEY_CHANNELDOWN },
-+ { 0x04, KEY_LEFT },
-+ { 0x08, KEY_RIGHT },
-+ { 0x0c, KEY_UP },
-+ { 0x10, KEY_DOWN },
- { 0x03, KEY_ZOOM }, /* fullscreen */
- { 0x1f, KEY_TEXT }, /* closed caption/teletext */
- { 0x20, KEY_SLEEP },
-@@ -47,7 +47,7 @@ static struct rc_map_table winfast[] = {
- { 0x2e, KEY_BLUE },
- { 0x18, KEY_KPPLUS }, /* fine tune + , not on Y040052 */
- { 0x19, KEY_KPMINUS }, /* fine tune - , not on Y040052 */
-- { 0x2a, KEY_MEDIA }, /* PIP (Picture in picture */
-+ { 0x2a, KEY_TV2 }, /* PIP (Picture in picture */
- { 0x21, KEY_DOT },
- { 0x13, KEY_ENTER },
- { 0x11, KEY_LAST }, /* Recall (last channel */
-@@ -57,7 +57,7 @@ static struct rc_map_table winfast[] = {
- { 0x25, KEY_TIME }, /* Time Shifting */
- { 0x26, KEY_STOP },
- { 0x27, KEY_RECORD },
-- { 0x28, KEY_SAVE }, /* Screenshot */
-+ { 0x28, KEY_CAMERA }, /* Screenshot */
- { 0x2f, KEY_MENU },
- { 0x30, KEY_CANCEL },
- { 0x31, KEY_CHANNEL }, /* Channel Surf */
-@@ -70,10 +70,10 @@ static struct rc_map_table winfast[] = {
- { 0x38, KEY_DVD },
-
- { 0x1a, KEY_MODE}, /* change to MCE mode on Y04G0051 */
-- { 0x3e, KEY_F21 }, /* MCE +VOL, on Y04G0033 */
-- { 0x3a, KEY_F22 }, /* MCE -VOL, on Y04G0033 */
-- { 0x3b, KEY_F23 }, /* MCE +CH, on Y04G0033 */
-- { 0x3f, KEY_F24 } /* MCE -CH, on Y04G0033 */
-+ { 0x3e, KEY_VOLUMEUP }, /* MCE +VOL, on Y04G0033 */
-+ { 0x3a, KEY_VOLUMEDOWN }, /* MCE -VOL, on Y04G0033 */
-+ { 0x3b, KEY_CHANNELUP }, /* MCE +CH, on Y04G0033 */
-+ { 0x3f, KEY_CHANNELDOWN } /* MCE -CH, on Y04G0033 */
- };
-
- static struct rc_map_list winfast_map = {
-diff --git a/drivers/media/rc/mceusb.c b/drivers/media/rc/mceusb.c
-index e4f8eac..044fb7a 100644
---- a/drivers/media/rc/mceusb.c
-+++ b/drivers/media/rc/mceusb.c
-@@ -186,7 +186,7 @@ static const struct mceusb_model mceusb_model[] = {
- * remotes, but we should have something handy,
- * to allow testing it
- */
-- .rc_map = RC_MAP_RC5_HAUPPAUGE_NEW,
-+ .rc_map = RC_MAP_HAUPPAUGE,
- .name = "Conexant Hybrid TV (cx231xx) MCE IR",
- },
- [CX_HYBRID_TV] = {
-@@ -261,7 +261,7 @@ static struct usb_device_id mceusb_dev_table[] = {
- .driver_info = MCE_GEN2_TX_INV },
- /* Topseed eHome Infrared Transceiver */
- { USB_DEVICE(VENDOR_TOPSEED, 0x0011),
-- .driver_info = MCE_GEN2_TX_INV },
-+ .driver_info = MCE_GEN3 },
- /* Ricavision internal Infrared Transceiver */
- { USB_DEVICE(VENDOR_RICAVISION, 0x0010) },
- /* Itron ione Libra Q-11 */
-diff --git a/drivers/media/video/cx18/cx18-i2c.c b/drivers/media/video/cx18/cx18-i2c.c
-index c330fb9..040aaa8 100644
---- a/drivers/media/video/cx18/cx18-i2c.c
-+++ b/drivers/media/video/cx18/cx18-i2c.c
-@@ -96,7 +96,7 @@ static int cx18_i2c_new_ir(struct cx18 *cx, struct i2c_adapter *adap,
u32 hw,
- /* Our default information for ir-kbd-i2c.c to use */
- switch (hw) {
- case CX18_HW_Z8F0811_IR_RX_HAUP:
-- init_data->ir_codes = RC_MAP_HAUPPAUGE_NEW;
-+ init_data->ir_codes = RC_MAP_HAUPPAUGE;
- init_data->internal_get_key_func = IR_KBD_GET_KEY_HAUP_XVR;
- init_data->type = RC_TYPE_RC5;
- init_data->name = cx->card_name;
-diff --git a/drivers/media/video/cx23885/cx23885-input.c
b/drivers/media/video/cx23885/cx23885-input.c
-index 199b996..e97cafd 100644
---- a/drivers/media/video/cx23885/cx23885-input.c
-+++ b/drivers/media/video/cx23885/cx23885-input.c
-@@ -264,7 +264,7 @@ int cx23885_input_init(struct cx23885_dev *dev)
- driver_type = RC_DRIVER_IR_RAW;
- allowed_protos = RC_TYPE_ALL;
- /* The grey Hauppauge RC-5 remote */
-- rc_map = RC_MAP_RC5_HAUPPAUGE_NEW;
-+ rc_map = RC_MAP_HAUPPAUGE;
- break;
- case CX23885_BOARD_TEVII_S470:
- /* Integrated CX23885 IR controller */
-diff --git a/drivers/media/video/cx88/cx88-input.c
b/drivers/media/video/cx88/cx88-input.c
-index fbfbba5..c820e2f 100644
---- a/drivers/media/video/cx88/cx88-input.c
-+++ b/drivers/media/video/cx88/cx88-input.c
-@@ -283,7 +283,7 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci)
- case CX88_BOARD_PCHDTV_HD3000:
- case CX88_BOARD_PCHDTV_HD5500:
- case CX88_BOARD_HAUPPAUGE_IRONLY:
-- ir_codes = RC_MAP_HAUPPAUGE_NEW;
-+ ir_codes = RC_MAP_HAUPPAUGE;
- ir->sampling = 1;
- break;
- case CX88_BOARD_WINFAST_DTV2000H:
-@@ -604,7 +604,7 @@ void cx88_i2c_init_ir(struct cx88_core *core)
- if (*addrp == 0x71) {
- /* Hauppauge XVR */
- core->init_data.name = "cx88 Hauppauge XVR remote";
-- core->init_data.ir_codes = RC_MAP_HAUPPAUGE_NEW;
-+ core->init_data.ir_codes = RC_MAP_HAUPPAUGE;
- core->init_data.type = RC_TYPE_RC5;
- core->init_data.internal_get_key_func = IR_KBD_GET_KEY_HAUP_XVR;
-
-diff --git a/drivers/media/video/em28xx/em28xx-cards.c
b/drivers/media/video/em28xx/em28xx-cards.c
-index 87f77a3..69fcea8 100644
---- a/drivers/media/video/em28xx/em28xx-cards.c
-+++ b/drivers/media/video/em28xx/em28xx-cards.c
-@@ -834,7 +834,7 @@ struct em28xx_board em28xx_boards[] = {
- .mts_firmware = 1,
- .has_dvb = 1,
- .dvb_gpio = hauppauge_wintv_hvr_900_digital,
-- .ir_codes = RC_MAP_HAUPPAUGE_NEW,
-+ .ir_codes = RC_MAP_HAUPPAUGE,
- .decoder = EM28XX_TVP5150,
- .input = { {
- .type = EM28XX_VMUX_TELEVISION,
-@@ -859,7 +859,7 @@ struct em28xx_board em28xx_boards[] = {
- .tuner_type = TUNER_XC2028,
- .tuner_gpio = default_tuner_gpio,
- .mts_firmware = 1,
-- .ir_codes = RC_MAP_HAUPPAUGE_NEW,
-+ .ir_codes = RC_MAP_HAUPPAUGE,
- .decoder = EM28XX_TVP5150,
- .input = { {
- .type = EM28XX_VMUX_TELEVISION,
-@@ -885,7 +885,7 @@ struct em28xx_board em28xx_boards[] = {
- .mts_firmware = 1,
- .has_dvb = 1,
- .dvb_gpio = hauppauge_wintv_hvr_900_digital,
-- .ir_codes = RC_MAP_HAUPPAUGE_NEW,
-+ .ir_codes = RC_MAP_HAUPPAUGE,
- .decoder = EM28XX_TVP5150,
- .input = { {
- .type = EM28XX_VMUX_TELEVISION,
-@@ -911,7 +911,7 @@ struct em28xx_board em28xx_boards[] = {
- .mts_firmware = 1,
- .has_dvb = 1,
- .dvb_gpio = hauppauge_wintv_hvr_900_digital,
-- .ir_codes = RC_MAP_RC5_HAUPPAUGE_NEW,
-+ .ir_codes = RC_MAP_HAUPPAUGE,
- .decoder = EM28XX_TVP5150,
- .input = { {
- .type = EM28XX_VMUX_TELEVISION,
-@@ -2430,7 +2430,7 @@ void em28xx_register_i2c_ir(struct em28xx *dev)
- dev->init_data.name = "i2c IR (EM28XX Pinnacle PCTV)";
- break;
- case EM2820_BOARD_HAUPPAUGE_WINTV_USB_2:
-- dev->init_data.ir_codes = RC_MAP_RC5_HAUPPAUGE_NEW;
-+ dev->init_data.ir_codes = RC_MAP_HAUPPAUGE;
- dev->init_data.get_key = em28xx_get_key_em_haup;
- dev->init_data.name = "i2c IR (EM2840 Hauppauge)";
- break;
-diff --git a/drivers/media/video/hdpvr/hdpvr-i2c.c
b/drivers/media/video/hdpvr/hdpvr-i2c.c
-index e53fa55..2a1ac28 100644
---- a/drivers/media/video/hdpvr/hdpvr-i2c.c
-+++ b/drivers/media/video/hdpvr/hdpvr-i2c.c
-@@ -52,25 +52,36 @@ struct i2c_client *hdpvr_register_ir_rx_i2c(struct hdpvr_device
*dev)
- };
-
- /* Our default information for ir-kbd-i2c.c to use */
-- init_data->ir_codes = RC_MAP_HAUPPAUGE_NEW;
-+ init_data->ir_codes = RC_MAP_HAUPPAUGE;
- init_data->internal_get_key_func = IR_KBD_GET_KEY_HAUP_XVR;
- init_data->type = RC_TYPE_RC5;
- init_data->name = "HD-PVR";
-+ init_data->polling_interval = 405; /* ms, duplicated from Windows */
- hdpvr_ir_rx_i2c_board_info.platform_data = init_data;
-
- return i2c_new_device(&dev->i2c_adapter, &hdpvr_ir_rx_i2c_board_info);
- }
-
- static int hdpvr_i2c_read(struct hdpvr_device *dev, int bus,
-- unsigned char addr, char *data, int len)
-+ unsigned char addr, char *wdata, int wlen,
-+ char *data, int len)
- {
- int ret;
-
-- if (len > sizeof(dev->i2c_buf))
-+ if ((len > sizeof(dev->i2c_buf)) || (wlen > sizeof(dev->i2c_buf)))
- return -EINVAL;
-
-- ret = usb_control_msg(dev->udev,
-- usb_rcvctrlpipe(dev->udev, 0),
-+ if (wlen) {
-+ memcpy(&dev->i2c_buf, wdata, wlen);
-+ ret = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0),
-+ REQTYPE_I2C_WRITE, CTRL_WRITE_REQUEST,
-+ (bus << 8) | addr, 0, &dev->i2c_buf,
-+ wlen, 1000);
-+ if (ret < 0)
-+ return ret;
-+ }
-+
-+ ret = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0),
- REQTYPE_I2C_READ, CTRL_READ_REQUEST,
- (bus << 8) | addr, 0, &dev->i2c_buf, len, 1000);
-
-@@ -92,16 +103,14 @@ static int hdpvr_i2c_write(struct hdpvr_device *dev, int bus,
- return -EINVAL;
-
- memcpy(&dev->i2c_buf, data, len);
-- ret = usb_control_msg(dev->udev,
-- usb_sndctrlpipe(dev->udev, 0),
-+ ret = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0),
- REQTYPE_I2C_WRITE, CTRL_WRITE_REQUEST,
- (bus << 8) | addr, 0, &dev->i2c_buf, len, 1000);
-
- if (ret < 0)
- return ret;
-
-- ret = usb_control_msg(dev->udev,
-- usb_rcvctrlpipe(dev->udev, 0),
-+ ret = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0),
- REQTYPE_I2C_WRITE_STATT, CTRL_READ_REQUEST,
- 0, 0, &dev->i2c_buf, 2, 1000);
-
-@@ -117,24 +126,49 @@ static int hdpvr_transfer(struct i2c_adapter *i2c_adapter, struct
i2c_msg *msgs,
- int num)
- {
- struct hdpvr_device *dev = i2c_get_adapdata(i2c_adapter);
-- int retval = 0, i, addr;
-+ int retval = 0, addr;
-
- if (num <= 0)
- return 0;
-
- mutex_lock(&dev->i2c_mutex);
-
-- for (i = 0; i < num && !retval; i++) {
-- addr = msgs[i].addr << 1;
-+ addr = msgs[0].addr << 1;
-
-- if (msgs[i].flags & I2C_M_RD)
-- retval = hdpvr_i2c_read(dev, 1, addr, msgs[i].buf,
-- msgs[i].len);
-+ if (num == 1) {
-+ if (msgs[0].flags & I2C_M_RD)
-+ retval = hdpvr_i2c_read(dev, 1, addr, NULL, 0,
-+ msgs[0].buf, msgs[0].len);
- else
-- retval = hdpvr_i2c_write(dev, 1, addr, msgs[i].buf,
-- msgs[i].len);
-+ retval = hdpvr_i2c_write(dev, 1, addr, msgs[0].buf,
-+ msgs[0].len);
-+ } else if (num == 2) {
-+ if (msgs[0].addr != msgs[1].addr) {
-+ v4l2_warn(&dev->v4l2_dev, "refusing 2-phase i2c xfer "
-+ "with conflicting target addresses\n");
-+ retval = -EINVAL;
-+ goto out;
-+ }
-+
-+ if ((msgs[0].flags & I2C_M_RD) || !(msgs[1].flags & I2C_M_RD)) {
-+ v4l2_warn(&dev->v4l2_dev, "refusing complex xfer with "
-+ "r0=%d, r1=%d\n", msgs[0].flags & I2C_M_RD,
-+ msgs[1].flags & I2C_M_RD);
-+ retval = -EINVAL;
-+ goto out;
-+ }
-+
-+ /*
-+ * Write followed by atomic read is the only complex xfer that
-+ * we actually support here.
-+ */
-+ retval = hdpvr_i2c_read(dev, 1, addr, msgs[0].buf, msgs[0].len,
-+ msgs[1].buf, msgs[1].len);
-+ } else {
-+ v4l2_warn(&dev->v4l2_dev, "refusing %d-phase i2c xfer\n", num);
- }
-
-+out:
- mutex_unlock(&dev->i2c_mutex);
-
- return retval ? retval : num;
-@@ -158,11 +192,11 @@ static struct i2c_adapter hdpvr_i2c_adapter_template = {
-
- static int hdpvr_activate_ir(struct hdpvr_device *dev)
- {
-- char buffer[8];
-+ char buffer[2];
-
- mutex_lock(&dev->i2c_mutex);
-
-- hdpvr_i2c_read(dev, 0, 0x54, buffer, 1);
-+ hdpvr_i2c_read(dev, 0, 0x54, NULL, 0, buffer, 1);
-
- buffer[0] = 0;
- buffer[1] = 0x8;
-diff --git a/drivers/media/video/ir-kbd-i2c.c b/drivers/media/video/ir-kbd-i2c.c
-index a221ad6..3ab875d 100644
---- a/drivers/media/video/ir-kbd-i2c.c
-+++ b/drivers/media/video/ir-kbd-i2c.c
-@@ -55,10 +55,6 @@
- static int debug;
- module_param(debug, int, 0644); /* debug level (0,1,2) */
-
--static int hauppauge;
--module_param(hauppauge, int, 0644); /* Choose Hauppauge remote */
--MODULE_PARM_DESC(hauppauge, "Specify Hauppauge remote: 0=black, 1=grey (defaults to
0)");
--
-
- #define MODULE_NAME "ir-kbd-i2c"
- #define dprintk(level, fmt, arg...) if (debug >= level) \
-@@ -105,10 +101,6 @@ static int get_key_haup_common(struct IR_i2c *ir, u32 *ir_key, u32
*ir_raw,
- /* invalid key press */
- return 0;
-
-- if (dev!=0x1e && dev!=0x1f)
-- /* not a hauppauge remote */
-- return 0;
--
- if (!range)
- code += 64;
-
-@@ -116,7 +108,7 @@ static int get_key_haup_common(struct IR_i2c *ir, u32 *ir_key, u32
*ir_raw,
- start, range, toggle, dev, code);
-
- /* return key */
-- *ir_key = code;
-+ *ir_key = (dev << 8) | code;
- *ir_raw = ircode;
- return 1;
- }
-@@ -312,11 +304,7 @@ static int ir_probe(struct i2c_client *client, const struct
i2c_device_id *id)
- name = "Hauppauge";
- ir->get_key = get_key_haup;
- rc_type = RC_TYPE_RC5;
-- if (hauppauge == 1) {
-- ir_codes = RC_MAP_HAUPPAUGE_NEW;
-- } else {
-- ir_codes = RC_MAP_RC5_TV;
-- }
-+ ir_codes = RC_MAP_HAUPPAUGE;
- break;
- case 0x30:
- name = "KNC One";
-@@ -340,7 +328,7 @@ static int ir_probe(struct i2c_client *client, const struct
i2c_device_id *id)
- name = "Hauppauge/Zilog Z8";
- ir->get_key = get_key_haup_xvr;
- rc_type = RC_TYPE_RC5;
-- ir_codes = hauppauge ? RC_MAP_HAUPPAUGE_NEW : RC_MAP_RC5_TV;
-+ ir_codes = RC_MAP_HAUPPAUGE;
- break;
- }
-
-diff --git a/drivers/media/video/ivtv/ivtv-i2c.c b/drivers/media/video/ivtv/ivtv-i2c.c
-index 9fb86a0..d47f41a 100644
---- a/drivers/media/video/ivtv/ivtv-i2c.c
-+++ b/drivers/media/video/ivtv/ivtv-i2c.c
-@@ -205,15 +205,14 @@ static int ivtv_i2c_new_ir(struct ivtv *itv, u32 hw, const char
*type, u8 addr)
- break;
- case IVTV_HW_I2C_IR_RX_HAUP_EXT:
- case IVTV_HW_I2C_IR_RX_HAUP_INT:
-- /* Default to old black remote */
-- init_data->ir_codes = RC_MAP_RC5_TV;
-+ init_data->ir_codes = RC_MAP_HAUPPAUGE;
- init_data->internal_get_key_func = IR_KBD_GET_KEY_HAUP;
- init_data->type = RC_TYPE_RC5;
- init_data->name = itv->card_name;
- break;
- case IVTV_HW_Z8F0811_IR_RX_HAUP:
- /* Default to grey remote */
-- init_data->ir_codes = RC_MAP_HAUPPAUGE_NEW;
-+ init_data->ir_codes = RC_MAP_HAUPPAUGE;
- init_data->internal_get_key_func = IR_KBD_GET_KEY_HAUP_XVR;
- init_data->type = RC_TYPE_RC5;
- init_data->name = itv->card_name;
-diff --git a/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c
b/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c
-index 451ecd4..e72d510 100644
---- a/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c
-+++ b/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c
-@@ -578,7 +578,7 @@ static void pvr2_i2c_register_ir(struct pvr2_hdw *hdw)
- switch (hdw->ir_scheme_active) {
- case PVR2_IR_SCHEME_24XXX: /* FX2-controlled IR */
- case PVR2_IR_SCHEME_29XXX: /* Original 29xxx device */
-- init_data->ir_codes = RC_MAP_HAUPPAUGE_NEW;
-+ init_data->ir_codes = RC_MAP_HAUPPAUGE;
- init_data->internal_get_key_func = IR_KBD_GET_KEY_HAUP;
- init_data->type = RC_TYPE_RC5;
- init_data->name = hdw->hdw_desc->description;
-@@ -593,7 +593,7 @@ static void pvr2_i2c_register_ir(struct pvr2_hdw *hdw)
- break;
- case PVR2_IR_SCHEME_ZILOG: /* HVR-1950 style */
- case PVR2_IR_SCHEME_24XXX_MCE: /* 24xxx MCE device */
-- init_data->ir_codes = RC_MAP_HAUPPAUGE_NEW;
-+ init_data->ir_codes = RC_MAP_HAUPPAUGE;
- init_data->internal_get_key_func = IR_KBD_GET_KEY_HAUP_XVR;
- init_data->type = RC_TYPE_RC5;
- init_data->name = hdw->hdw_desc->description;
-diff --git a/drivers/media/video/saa7134/saa7134-input.c
b/drivers/media/video/saa7134/saa7134-input.c
-index 790d667..be1c2a2 100644
---- a/drivers/media/video/saa7134/saa7134-input.c
-+++ b/drivers/media/video/saa7134/saa7134-input.c
-@@ -893,7 +893,7 @@ void saa7134_probe_i2c_ir(struct saa7134_dev *dev)
- case SAA7134_BOARD_HAUPPAUGE_HVR1110:
- dev->init_data.name = "HVR 1110";
- dev->init_data.get_key = get_key_hvr1110;
-- dev->init_data.ir_codes = RC_MAP_HAUPPAUGE_NEW;
-+ dev->init_data.ir_codes = RC_MAP_HAUPPAUGE;
- info.addr = 0x71;
- break;
- case SAA7134_BOARD_BEHOLD_607FM_MK3:
-diff --git a/drivers/staging/lirc/Kconfig b/drivers/staging/lirc/Kconfig
-index cdaff59..526ec0f 100644
---- a/drivers/staging/lirc/Kconfig
-+++ b/drivers/staging/lirc/Kconfig
-@@ -32,18 +32,6 @@ config LIRC_IMON
-
- Current generation iMON devices use the input layer imon driver.
-
--config LIRC_IT87
-- tristate "ITE IT87XX CIR Port Receiver"
-- depends on LIRC && PNP
-- help
-- Driver for the ITE IT87xx IR Receiver
--
--config LIRC_ITE8709
-- tristate "ITE8709 CIR Port Receiver"
-- depends on LIRC && PNP
-- help
-- Driver for the ITE8709 IR Receiver
--
- config LIRC_PARALLEL
- tristate "Homebrew Parallel Port Receiver"
- depends on LIRC && PARPORT
-diff --git a/drivers/staging/lirc/Makefile b/drivers/staging/lirc/Makefile
-index 94af218..d76b0fa 100644
---- a/drivers/staging/lirc/Makefile
-+++ b/drivers/staging/lirc/Makefile
-@@ -6,8 +6,6 @@
- obj-$(CONFIG_LIRC_BT829) += lirc_bt829.o
- obj-$(CONFIG_LIRC_IGORPLUGUSB) += lirc_igorplugusb.o
- obj-$(CONFIG_LIRC_IMON) += lirc_imon.o
--obj-$(CONFIG_LIRC_IT87) += lirc_it87.o
--obj-$(CONFIG_LIRC_ITE8709) += lirc_ite8709.o
- obj-$(CONFIG_LIRC_PARALLEL) += lirc_parallel.o
- obj-$(CONFIG_LIRC_SASEM) += lirc_sasem.o
- obj-$(CONFIG_LIRC_SERIAL) += lirc_serial.o
-diff --git a/drivers/staging/lirc/TODO.lirc_zilog b/drivers/staging/lirc/TODO.lirc_zilog
-index 2d0263f..a97800a 100644
---- a/drivers/staging/lirc/TODO.lirc_zilog
-+++ b/drivers/staging/lirc/TODO.lirc_zilog
-@@ -1,34 +1,33 @@
--1. Both ir-kbd-i2c and lirc_zilog provide support for RX events.
--The 'tx_only' lirc_zilog module parameter will allow ir-kbd-i2c
--and lirc_zilog to coexist in the kernel, if the user requires such a set-up.
--However the IR unit will not work well without coordination between the
--two modules. A shared mutex, for transceiver access locking, needs to be
--supplied by bridge drivers, in struct IR_i2_init_data, to both ir-kbd-i2c
--and lirc_zilog, before they will coexist usefully. This should be fixed
--before moving out of staging.
--
--2. References and locking need careful examination. For cx18 and ivtv PCI
--cards, which are not easily "hot unplugged", the imperfect state of reference
--counting and locking is acceptable if not correct. For USB connected units
--like HD PVR, PVR USB2, HVR-1900, and HVR1950, the likelyhood of an Ooops on
--unplug is probably great. Proper reference counting and locking needs to be
--implemented before this module is moved out of staging.
--
--3. The binding between hdpvr and lirc_zilog is currently disabled,
--due to an OOPS reported a few years ago when both the hdpvr and cx18
--drivers were loaded in his system. More details can be seen at:
--
http://www.mail-archive.com/linux-media@vger.kernel.org/msg09163.html
--More tests need to be done, in order to fix the reported issue.
--
--4. In addition to providing a shared mutex for transceiver access
--locking, bridge drivers, if able, should provide a chip reset() callback
-+1. Both ir-kbd-i2c and lirc_zilog provide support for RX events for
-+the chips supported by lirc_zilog. Before moving lirc_zilog out of staging:
-+
-+a. ir-kbd-i2c needs a module parameter added to allow the user to tell
-+ ir-kbd-i2c to ignore Z8 IR units.
-+
-+b. lirc_zilog should provide Rx key presses to the rc core like ir-kbd-i2c
-+ does.
-+
-+
-+2. lirc_zilog module ref-counting need examination. It has not been
-+verified that cdev and lirc_dev will take the proper module references on
-+lirc_zilog to prevent removal of lirc_zilog when the /dev/lircN device node
-+is open.
-+
-+(The good news is ref-counting of lirc_zilog internal structures appears to be
-+complete. Testing has shown the cx18 module can be unloaded out from under
-+irw + lircd + lirc_dev, with the /dev/lirc0 device node open, with no adverse
-+effects. The cx18 module could then be reloaded and irw properly began
-+receiving button presses again and ir_send worked without error.)
-+
-+
-+3. Bridge drivers, if able, should provide a chip reset() callback
- to lirc_zilog via struct IR_i2c_init_data. cx18 and ivtv already have routines
--to perform Z8 chip resets via GPIO manipulations. This will allow lirc_zilog
-+to perform Z8 chip resets via GPIO manipulations. This would allow lirc_zilog
- to bring the chip back to normal when it hangs, in the same places the
- original lirc_pvr150 driver code does. This is not strictly needed, so it
- is not required to move lirc_zilog out of staging.
-
--5. Both lirc_zilog and ir-kbd-i2c support the Zilog Z8 for IR, as programmed
-+Note: Both lirc_zilog and ir-kbd-i2c support the Zilog Z8 for IR, as programmed
- and installed on Hauppauge products. When working on either module, developers
- must consider at least the following bridge drivers which mention an IR Rx unit
- at address 0x71 (indicative of a Z8):
-diff --git a/drivers/staging/lirc/lirc_imon.c b/drivers/staging/lirc/lirc_imon.c
-index 235cab0..4039eda 100644
---- a/drivers/staging/lirc/lirc_imon.c
-+++ b/drivers/staging/lirc/lirc_imon.c
-@@ -379,7 +379,7 @@ static ssize_t vfd_write(struct file *file, const char *buf,
- struct imon_context *context;
- const unsigned char vfd_packet6[] = {
- 0x01, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF };
-- int *data_buf;
-+ int *data_buf = NULL;
-
- context = file->private_data;
- if (!context) {
-diff --git a/drivers/staging/lirc/lirc_it87.c b/drivers/staging/lirc/lirc_it87.c
-deleted file mode 100644
-index 5938616..0000000
---- a/drivers/staging/lirc/lirc_it87.c
-+++ /dev/null
-@@ -1,1027 +0,0 @@
--/*
-- * LIRC driver for ITE IT8712/IT8705 CIR port
-- *
-- * Copyright (C) 2001 Hans-Gunter Lutke Uphues <hg_lu(a)web.de>
-- *
-- * 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
-- *
-- * ITE IT8705 and IT8712(not tested) and IT8720 CIR-port support for lirc based
-- * via cut and paste from lirc_sir.c (C) 2000 Milan Pikula
-- *
-- * Attention: Sendmode only tested with debugging logs
-- *
-- * 2001/02/27 Christoph Bartelmus <lirc(a)bartelmus.de> :
-- * reimplemented read function
-- * 2005/06/05 Andrew Calkin implemented support for Asus Digimatrix,
-- * based on work of the following member of the Outertrack Digimatrix
-- * Forum: Art103 <r_tay(a)hotmail.com>
-- * 2009/12/24 James Edwards <jimbo-lirc(a)edwardsclan.net> implemeted support
-- * for ITE8704/ITE8718, on my machine, the DSDT reports 8704, but the
-- * chip identifies as 18.
-- */
--
--#include <linux/module.h>
--#include <linux/sched.h>
--#include <linux/errno.h>
--#include <linux/signal.h>
--#include <linux/fs.h>
--#include <linux/interrupt.h>
--#include <linux/ioport.h>
--#include <linux/kernel.h>
--#include <linux/time.h>
--#include <linux/string.h>
--#include <linux/types.h>
--#include <linux/wait.h>
--#include <linux/mm.h>
--#include <linux/delay.h>
--#include <linux/poll.h>
--#include <asm/system.h>
--#include <linux/io.h>
--#include <linux/irq.h>
--#include <linux/fcntl.h>
--
--#include <linux/timer.h>
--#include <linux/pnp.h>
--
--#include <media/lirc.h>
--#include <media/lirc_dev.h>
--
--#include "lirc_it87.h"
--
--#ifdef LIRC_IT87_DIGIMATRIX
--static int digimatrix = 1;
--static int it87_freq = 36; /* kHz */
--static int irq = 9;
--#else
--static int digimatrix;
--static int it87_freq = 38; /* kHz */
--static int irq = IT87_CIR_DEFAULT_IRQ;
--#endif
--
--static unsigned long it87_bits_in_byte_out;
--static unsigned long it87_send_counter;
--static unsigned char it87_RXEN_mask = IT87_CIR_RCR_RXEN;
--
--#define RBUF_LEN 1024
--
--#define LIRC_DRIVER_NAME "lirc_it87"
--
--/* timeout for sequences in jiffies (=5/100s) */
--/* must be longer than TIME_CONST */
--#define IT87_TIMEOUT (HZ*5/100)
--
--/* module parameters */
--static int debug;
--#define dprintk(fmt, args...) \
-- do { \
-- if (debug) \
-- printk(KERN_DEBUG LIRC_DRIVER_NAME ": " \
-- fmt, ## args); \
-- } while (0)
--
--static int io = IT87_CIR_DEFAULT_IOBASE;
--/* receiver demodulator default: off */
--static int it87_enable_demodulator;
--
--static int timer_enabled;
--static DEFINE_SPINLOCK(timer_lock);
--static struct timer_list timerlist;
--/* time of last signal change detected */
--static struct timeval last_tv = {0, 0};
--/* time of last UART data ready interrupt */
--static struct timeval last_intr_tv = {0, 0};
--static int last_value;
--
--static DECLARE_WAIT_QUEUE_HEAD(lirc_read_queue);
--
--static DEFINE_SPINLOCK(hardware_lock);
--static DEFINE_SPINLOCK(dev_lock);
--static bool device_open;
--
--static int rx_buf[RBUF_LEN];
--unsigned int rx_tail, rx_head;
--
--static struct pnp_driver it87_pnp_driver;
--
--/* SECTION: Prototypes */
--
--/* Communication with user-space */
--static int lirc_open(struct inode *inode, struct file *file);
--static int lirc_close(struct inode *inode, struct file *file);
--static unsigned int lirc_poll(struct file *file, poll_table *wait);
--static ssize_t lirc_read(struct file *file, char *buf,
-- size_t count, loff_t *ppos);
--static ssize_t lirc_write(struct file *file, const char *buf,
-- size_t n, loff_t *pos);
--static long lirc_ioctl(struct file *filep, unsigned int cmd, unsigned long arg);
--static void add_read_queue(int flag, unsigned long val);
--static int init_chrdev(void);
--static void drop_chrdev(void);
--/* Hardware */
--static irqreturn_t it87_interrupt(int irq, void *dev_id);
--static void send_space(unsigned long len);
--static void send_pulse(unsigned long len);
--static void init_send(void);
--static void terminate_send(unsigned long len);
--static int init_hardware(void);
--static void drop_hardware(void);
--/* Initialisation */
--static int init_port(void);
--static void drop_port(void);
--
--
--/* SECTION: Communication with user-space */
--
--static int lirc_open(struct inode *inode, struct file *file)
--{
-- spin_lock(&dev_lock);
-- if (device_open) {
-- spin_unlock(&dev_lock);
-- return -EBUSY;
-- }
-- device_open = true;
-- spin_unlock(&dev_lock);
-- return 0;
--}
--
--
--static int lirc_close(struct inode *inode, struct file *file)
--{
-- spin_lock(&dev_lock);
-- device_open = false;
-- spin_unlock(&dev_lock);
-- return 0;
--}
--
--
--static unsigned int lirc_poll(struct file *file, poll_table *wait)
--{
-- poll_wait(file, &lirc_read_queue, wait);
-- if (rx_head != rx_tail)
-- return POLLIN | POLLRDNORM;
-- return 0;
--}
--
--
--static ssize_t lirc_read(struct file *file, char *buf,
-- size_t count, loff_t *ppos)
--{
-- int n = 0;
-- int retval = 0;
--
-- while (n < count) {
-- if (file->f_flags & O_NONBLOCK && rx_head == rx_tail) {
-- retval = -EAGAIN;
-- break;
-- }
-- retval = wait_event_interruptible(lirc_read_queue,
-- rx_head != rx_tail);
-- if (retval)
-- break;
--
-- if (copy_to_user((void *) buf + n, (void *) (rx_buf + rx_head),
-- sizeof(int))) {
-- retval = -EFAULT;
-- break;
-- }
-- rx_head = (rx_head + 1) & (RBUF_LEN - 1);
-- n += sizeof(int);
-- }
-- if (n)
-- return n;
-- return retval;
--}
--
--
--static ssize_t lirc_write(struct file *file, const char *buf,
-- size_t n, loff_t *pos)
--{
-- int i = 0;
-- int *tx_buf;
--
-- if (n % sizeof(int))
-- return -EINVAL;
-- tx_buf = memdup_user(buf, n);
-- if (IS_ERR(tx_buf))
-- return PTR_ERR(tx_buf);
-- n /= sizeof(int);
-- init_send();
-- while (1) {
-- if (i >= n)
-- break;
-- if (tx_buf[i])
-- send_pulse(tx_buf[i]);
-- i++;
-- if (i >= n)
-- break;
-- if (tx_buf[i])
-- send_space(tx_buf[i]);
-- i++;
-- }
-- terminate_send(tx_buf[i - 1]);
-- kfree(tx_buf);
-- return n;
--}
--
--
--static long lirc_ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
--{
-- int retval = 0;
-- __u32 value = 0;
-- unsigned long hw_flags;
--
-- if (cmd == LIRC_GET_FEATURES)
-- value = LIRC_CAN_SEND_PULSE |
-- LIRC_CAN_SET_SEND_CARRIER |
-- LIRC_CAN_REC_MODE2;
-- else if (cmd == LIRC_GET_SEND_MODE)
-- value = LIRC_MODE_PULSE;
-- else if (cmd == LIRC_GET_REC_MODE)
-- value = LIRC_MODE_MODE2;
--
-- switch (cmd) {
-- case LIRC_GET_FEATURES:
-- case LIRC_GET_SEND_MODE:
-- case LIRC_GET_REC_MODE:
-- retval = put_user(value, (__u32 *) arg);
-- break;
--
-- case LIRC_SET_SEND_MODE:
-- case LIRC_SET_REC_MODE:
-- retval = get_user(value, (__u32 *) arg);
-- break;
--
-- case LIRC_SET_SEND_CARRIER:
-- retval = get_user(value, (__u32 *) arg);
-- if (retval)
-- return retval;
-- value /= 1000;
-- if (value > IT87_CIR_FREQ_MAX ||
-- value < IT87_CIR_FREQ_MIN)
-- return -EINVAL;
--
-- it87_freq = value;
--
-- spin_lock_irqsave(&hardware_lock, hw_flags);
-- outb(((inb(io + IT87_CIR_TCR2) & IT87_CIR_TCR2_TXMPW) |
-- (it87_freq - IT87_CIR_FREQ_MIN) << 3),
-- io + IT87_CIR_TCR2);
-- spin_unlock_irqrestore(&hardware_lock, hw_flags);
-- dprintk("demodulation frequency: %d kHz\n", it87_freq);
--
-- break;
--
-- default:
-- retval = -EINVAL;
-- }
--
-- if (retval)
-- return retval;
--
-- if (cmd == LIRC_SET_REC_MODE) {
-- if (value != LIRC_MODE_MODE2)
-- retval = -ENOSYS;
-- } else if (cmd == LIRC_SET_SEND_MODE) {
-- if (value != LIRC_MODE_PULSE)
-- retval = -ENOSYS;
-- }
-- return retval;
--}
--
--static void add_read_queue(int flag, unsigned long val)
--{
-- unsigned int new_rx_tail;
-- int newval;
--
-- dprintk("add flag %d with val %lu\n", flag, val);
--
-- newval = val & PULSE_MASK;
--
-- /*
-- * statistically, pulses are ~TIME_CONST/2 too long. we could
-- * maybe make this more exact, but this is good enough
-- */
-- if (flag) {
-- /* pulse */
-- if (newval > TIME_CONST / 2)
-- newval -= TIME_CONST / 2;
-- else /* should not ever happen */
-- newval = 1;
-- newval |= PULSE_BIT;
-- } else
-- newval += TIME_CONST / 2;
-- new_rx_tail = (rx_tail + 1) & (RBUF_LEN - 1);
-- if (new_rx_tail == rx_head) {
-- dprintk("Buffer overrun.\n");
-- return;
-- }
-- rx_buf[rx_tail] = newval;
-- rx_tail = new_rx_tail;
-- wake_up_interruptible(&lirc_read_queue);
--}
--
--
--static const struct file_operations lirc_fops = {
-- .owner = THIS_MODULE,
-- .read = lirc_read,
-- .write = lirc_write,
-- .poll = lirc_poll,
-- .unlocked_ioctl = lirc_ioctl,
--#ifdef CONFIG_COMPAT
-- .compat_ioctl = lirc_ioctl,
--#endif
-- .open = lirc_open,
-- .release = lirc_close,
-- .llseek = noop_llseek,
--};
--
--static int set_use_inc(void *data)
--{
-- return 0;
--}
--
--static void set_use_dec(void *data)
--{
--}
--
--static struct lirc_driver driver = {
-- .name = LIRC_DRIVER_NAME,
-- .minor = -1,
-- .code_length = 1,
-- .sample_rate = 0,
-- .data = NULL,
-- .add_to_buf = NULL,
-- .set_use_inc = set_use_inc,
-- .set_use_dec = set_use_dec,
-- .fops = &lirc_fops,
-- .dev = NULL,
-- .owner = THIS_MODULE,
--};
--
--
--static int init_chrdev(void)
--{
-- driver.minor = lirc_register_driver(&driver);
--
-- if (driver.minor < 0) {
-- printk(KERN_ERR LIRC_DRIVER_NAME ": init_chrdev() failed.\n");
-- return -EIO;
-- }
-- return 0;
--}
--
--
--static void drop_chrdev(void)
--{
-- lirc_unregister_driver(driver.minor);
--}
--
--
--/* SECTION: Hardware */
--static long delta(struct timeval *tv1, struct timeval *tv2)
--{
-- unsigned long deltv;
--
-- deltv = tv2->tv_sec - tv1->tv_sec;
-- if (deltv > 15)
-- deltv = 0xFFFFFF;
-- else
-- deltv = deltv*1000000 + tv2->tv_usec - tv1->tv_usec;
-- return deltv;
--}
--
--static void it87_timeout(unsigned long data)
--{
-- unsigned long flags;
--
-- /* avoid interference with interrupt */
-- spin_lock_irqsave(&timer_lock, flags);
--
-- if (digimatrix) {
-- /* We have timed out. Disable the RX mechanism. */
--
-- outb((inb(io + IT87_CIR_RCR) & ~IT87_CIR_RCR_RXEN) |
-- IT87_CIR_RCR_RXACT, io + IT87_CIR_RCR);
-- if (it87_RXEN_mask)
-- outb(inb(io + IT87_CIR_RCR) | IT87_CIR_RCR_RXEN,
-- io + IT87_CIR_RCR);
-- dprintk(" TIMEOUT\n");
-- timer_enabled = 0;
--
-- /* fifo clear */
-- outb(inb(io + IT87_CIR_TCR1) | IT87_CIR_TCR1_FIFOCLR,
-- io+IT87_CIR_TCR1);
--
-- } else {
-- /*
-- * if last received signal was a pulse, but receiving stopped
-- * within the 9 bit frame, we need to finish this pulse and
-- * simulate a signal change to from pulse to space. Otherwise
-- * upper layers will receive two sequences next time.
-- */
--
-- if (last_value) {
-- unsigned long pulse_end;
--
-- /* determine 'virtual' pulse end: */
-- pulse_end = delta(&last_tv, &last_intr_tv);
-- dprintk("timeout add %d for %lu usec\n",
-- last_value, pulse_end);
-- add_read_queue(last_value, pulse_end);
-- last_value = 0;
-- last_tv = last_intr_tv;
-- }
-- }
-- spin_unlock_irqrestore(&timer_lock, flags);
--}
--
--static irqreturn_t it87_interrupt(int irq, void *dev_id)
--{
-- unsigned char data;
-- struct timeval curr_tv;
-- static unsigned long deltv;
-- unsigned long deltintrtv;
-- unsigned long flags, hw_flags;
-- int iir, lsr;
-- int fifo = 0;
-- static char lastbit;
-- char bit;
--
-- /* Bit duration in microseconds */
-- const unsigned long bit_duration = 1000000ul /
-- (115200 / IT87_CIR_BAUDRATE_DIVISOR);
--
--
-- iir = inb(io + IT87_CIR_IIR);
--
-- switch (iir & IT87_CIR_IIR_IID) {
-- case 0x4:
-- case 0x6:
-- lsr = inb(io + IT87_CIR_RSR) & (IT87_CIR_RSR_RXFTO |
-- IT87_CIR_RSR_RXFBC);
-- fifo = lsr & IT87_CIR_RSR_RXFBC;
-- dprintk("iir: 0x%x fifo: 0x%x\n", iir, lsr);
--
-- /* avoid interference with timer */
-- spin_lock_irqsave(&timer_lock, flags);
-- spin_lock_irqsave(&hardware_lock, hw_flags);
-- if (digimatrix) {
-- static unsigned long acc_pulse;
-- static unsigned long acc_space;
--
-- do {
-- data = inb(io + IT87_CIR_DR);
-- data = ~data;
-- fifo--;
-- if (data != 0x00) {
-- if (timer_enabled)
-- del_timer(&timerlist);
-- /*
-- * start timer for end of
-- * sequence detection
-- */
-- timerlist.expires = jiffies +
-- IT87_TIMEOUT;
-- add_timer(&timerlist);
-- timer_enabled = 1;
-- }
-- /* Loop through */
-- for (bit = 0; bit < 8; ++bit) {
-- if ((data >> bit) & 1) {
-- ++acc_pulse;
-- if (lastbit == 0) {
-- add_read_queue(0,
-- acc_space *
-- bit_duration);
-- acc_space = 0;
-- }
-- } else {
-- ++acc_space;
-- if (lastbit == 1) {
-- add_read_queue(1,
-- acc_pulse *
-- bit_duration);
-- acc_pulse = 0;
-- }
-- }
-- lastbit = (data >> bit) & 1;
-- }
--
-- } while (fifo != 0);
-- } else { /* Normal Operation */
-- do {
-- del_timer(&timerlist);
-- data = inb(io + IT87_CIR_DR);
--
-- dprintk("data=%02x\n", data);
-- do_gettimeofday(&curr_tv);
-- deltv = delta(&last_tv, &curr_tv);
-- deltintrtv = delta(&last_intr_tv, &curr_tv);
--
-- dprintk("t %lu , d %d\n",
-- deltintrtv, (int)data);
--
-- /*
-- * if nothing came in last 2 cycles,
-- * it was gap
-- */
-- if (deltintrtv > TIME_CONST * 2) {
-- if (last_value) {
-- dprintk("GAP\n");
--
-- /* simulate signal change */
-- add_read_queue(last_value,
-- deltv -
-- deltintrtv);
-- last_value = 0;
-- last_tv.tv_sec =
-- last_intr_tv.tv_sec;
-- last_tv.tv_usec =
-- last_intr_tv.tv_usec;
-- deltv = deltintrtv;
-- }
-- }
-- data = 1;
-- if (data ^ last_value) {
-- /*
-- * deltintrtv > 2*TIME_CONST,
-- * remember ? the other case is
-- * timeout
-- */
-- add_read_queue(last_value,
-- deltv-TIME_CONST);
-- last_value = data;
-- last_tv = curr_tv;
-- if (last_tv.tv_usec >= TIME_CONST)
-- last_tv.tv_usec -= TIME_CONST;
-- else {
-- last_tv.tv_sec--;
-- last_tv.tv_usec += 1000000 -
-- TIME_CONST;
-- }
-- }
-- last_intr_tv = curr_tv;
-- if (data) {
-- /*
-- * start timer for end of
-- * sequence detection
-- */
-- timerlist.expires =
-- jiffies + IT87_TIMEOUT;
-- add_timer(&timerlist);
-- }
-- outb((inb(io + IT87_CIR_RCR) &
-- ~IT87_CIR_RCR_RXEN) |
-- IT87_CIR_RCR_RXACT,
-- io + IT87_CIR_RCR);
-- if (it87_RXEN_mask)
-- outb(inb(io + IT87_CIR_RCR) |
-- IT87_CIR_RCR_RXEN,
-- io + IT87_CIR_RCR);
-- fifo--;
-- } while (fifo != 0);
-- }
-- spin_unlock_irqrestore(&hardware_lock, hw_flags);
-- spin_unlock_irqrestore(&timer_lock, flags);
--
-- return IRQ_RETVAL(IRQ_HANDLED);
--
-- default:
-- /* not our irq */
-- dprintk("unknown IRQ (shouldn't happen) !!\n");
-- return IRQ_RETVAL(IRQ_NONE);
-- }
--}
--
--
--static void send_it87(unsigned long len, unsigned long stime,
-- unsigned char send_byte, unsigned int count_bits)
--{
-- long count = len / stime;
-- long time_left = 0;
-- static unsigned char byte_out;
-- unsigned long hw_flags;
--
-- dprintk("%s: len=%ld, sb=%d\n", __func__, len, send_byte);
--
-- time_left = (long)len - (long)count * (long)stime;
-- count += ((2 * time_left) / stime);
-- while (count) {
-- long i = 0;
-- for (i = 0; i < count_bits; i++) {
-- byte_out = (byte_out << 1) | (send_byte & 1);
-- it87_bits_in_byte_out++;
-- }
-- if (it87_bits_in_byte_out == 8) {
-- dprintk("out=0x%x, tsr_txfbc: 0x%x\n",
-- byte_out,
-- inb(io + IT87_CIR_TSR) &
-- IT87_CIR_TSR_TXFBC);
--
-- while ((inb(io + IT87_CIR_TSR) &
-- IT87_CIR_TSR_TXFBC) >= IT87_CIR_FIFO_SIZE)
-- ;
--
-- spin_lock_irqsave(&hardware_lock, hw_flags);
-- outb(byte_out, io + IT87_CIR_DR);
-- spin_unlock_irqrestore(&hardware_lock, hw_flags);
--
-- it87_bits_in_byte_out = 0;
-- it87_send_counter++;
-- byte_out = 0;
-- }
-- count--;
-- }
--}
--
--
--/*TODO: maybe exchange space and pulse because it8705 only modulates 0-bits */
--
--static void send_space(unsigned long len)
--{
-- send_it87(len, TIME_CONST, IT87_CIR_SPACE, IT87_CIR_BAUDRATE_DIVISOR);
--}
--
--static void send_pulse(unsigned long len)
--{
-- send_it87(len, TIME_CONST, IT87_CIR_PULSE, IT87_CIR_BAUDRATE_DIVISOR);
--}
--
--
--static void init_send()
--{
-- unsigned long flags;
--
-- spin_lock_irqsave(&hardware_lock, flags);
-- /* RXEN=0: receiver disable */
-- it87_RXEN_mask = 0;
-- outb(inb(io + IT87_CIR_RCR) & ~IT87_CIR_RCR_RXEN,
-- io + IT87_CIR_RCR);
-- spin_unlock_irqrestore(&hardware_lock, flags);
-- it87_bits_in_byte_out = 0;
-- it87_send_counter = 0;
--}
--
--
--static void terminate_send(unsigned long len)
--{
-- unsigned long flags;
-- unsigned long last = 0;
--
-- last = it87_send_counter;
-- /* make sure all necessary data has been sent */
-- while (last == it87_send_counter)
-- send_space(len);
-- /* wait until all data sent */
-- while ((inb(io + IT87_CIR_TSR) & IT87_CIR_TSR_TXFBC) != 0)
-- ;
-- /* then re-enable receiver */
-- spin_lock_irqsave(&hardware_lock, flags);
-- it87_RXEN_mask = IT87_CIR_RCR_RXEN;
-- outb(inb(io + IT87_CIR_RCR) | IT87_CIR_RCR_RXEN,
-- io + IT87_CIR_RCR);
-- spin_unlock_irqrestore(&hardware_lock, flags);
--}
--
--
--static int init_hardware(void)
--{
-- unsigned long flags;
-- unsigned char it87_rcr = 0;
--
-- spin_lock_irqsave(&hardware_lock, flags);
-- /* init cir-port */
-- /* enable r/w-access to Baudrate-Register */
-- outb(IT87_CIR_IER_BR, io + IT87_CIR_IER);
-- outb(IT87_CIR_BAUDRATE_DIVISOR % 0x100, io+IT87_CIR_BDLR);
-- outb(IT87_CIR_BAUDRATE_DIVISOR / 0x100, io+IT87_CIR_BDHR);
-- /* Baudrate Register off, define IRQs: Input only */
-- if (digimatrix) {
-- outb(IT87_CIR_IER_IEC | IT87_CIR_IER_RFOIE, io + IT87_CIR_IER);
-- /* RX: HCFS=0, RXDCR = 001b (33,75..38,25 kHz), RXEN=1 */
-- } else {
-- outb(IT87_CIR_IER_IEC | IT87_CIR_IER_RDAIE, io + IT87_CIR_IER);
-- /* RX: HCFS=0, RXDCR = 001b (35,6..40,3 kHz), RXEN=1 */
-- }
-- it87_rcr = (IT87_CIR_RCR_RXEN & it87_RXEN_mask) | 0x1;
-- if (it87_enable_demodulator)
-- it87_rcr |= IT87_CIR_RCR_RXEND;
-- outb(it87_rcr, io + IT87_CIR_RCR);
-- if (digimatrix) {
-- /* Set FIFO depth to 1 byte, and disable TX */
-- outb(inb(io + IT87_CIR_TCR1) | 0x00,
-- io + IT87_CIR_TCR1);
--
-- /*
-- * TX: it87_freq (36kHz), 'reserved' sensitivity
-- * setting (0x00)
-- */
-- outb(((it87_freq - IT87_CIR_FREQ_MIN) << 3) | 0x00,
-- io + IT87_CIR_TCR2);
-- } else {
-- /* TX: 38kHz, 13,3us (pulse-width) */
-- outb(((it87_freq - IT87_CIR_FREQ_MIN) << 3) | 0x06,
-- io + IT87_CIR_TCR2);
-- }
-- spin_unlock_irqrestore(&hardware_lock, flags);
-- return 0;
--}
--
--
--static void drop_hardware(void)
--{
-- unsigned long flags;
--
-- spin_lock_irqsave(&hardware_lock, flags);
-- disable_irq(irq);
-- /* receiver disable */
-- it87_RXEN_mask = 0;
-- outb(0x1, io + IT87_CIR_RCR);
-- /* turn off irqs */
-- outb(0, io + IT87_CIR_IER);
-- /* fifo clear */
-- outb(IT87_CIR_TCR1_FIFOCLR, io+IT87_CIR_TCR1);
-- /* reset */
-- outb(IT87_CIR_IER_RESET, io+IT87_CIR_IER);
-- enable_irq(irq);
-- spin_unlock_irqrestore(&hardware_lock, flags);
--}
--
--
--static unsigned char it87_read(unsigned char port)
--{
-- outb(port, IT87_ADRPORT);
-- return inb(IT87_DATAPORT);
--}
--
--
--static void it87_write(unsigned char port, unsigned char data)
--{
-- outb(port, IT87_ADRPORT);
-- outb(data, IT87_DATAPORT);
--}
--
--
--/* SECTION: Initialisation */
--
--static int init_port(void)
--{
-- unsigned long hw_flags;
-- int retval = 0;
--
-- unsigned char init_bytes[4] = IT87_INIT;
-- unsigned char it87_chipid = 0;
-- unsigned char ldn = 0;
-- unsigned int it87_io = 0;
-- unsigned int it87_irq = 0;
--
-- /* Enter MB PnP Mode */
-- outb(init_bytes[0], IT87_ADRPORT);
-- outb(init_bytes[1], IT87_ADRPORT);
-- outb(init_bytes[2], IT87_ADRPORT);
-- outb(init_bytes[3], IT87_ADRPORT);
--
-- /* 8712 or 8705 ? */
-- it87_chipid = it87_read(IT87_CHIP_ID1);
-- if (it87_chipid != 0x87) {
-- retval = -ENXIO;
-- return retval;
-- }
-- it87_chipid = it87_read(IT87_CHIP_ID2);
-- if ((it87_chipid != 0x05) &&
-- (it87_chipid != 0x12) &&
-- (it87_chipid != 0x18) &&
-- (it87_chipid != 0x20)) {
-- printk(KERN_INFO LIRC_DRIVER_NAME
-- ": no IT8704/05/12/18/20 found (claimed IT87%02x), "
-- "exiting..\n", it87_chipid);
-- retval = -ENXIO;
-- return retval;
-- }
-- printk(KERN_INFO LIRC_DRIVER_NAME
-- ": found IT87%02x.\n",
-- it87_chipid);
--
-- /* get I/O-Port and IRQ */
-- if (it87_chipid == 0x12 || it87_chipid == 0x18)
-- ldn = IT8712_CIR_LDN;
-- else
-- ldn = IT8705_CIR_LDN;
-- it87_write(IT87_LDN, ldn);
--
-- it87_io = it87_read(IT87_CIR_BASE_MSB) * 256 +
-- it87_read(IT87_CIR_BASE_LSB);
-- if (it87_io == 0) {
-- if (io == 0)
-- io = IT87_CIR_DEFAULT_IOBASE;
-- printk(KERN_INFO LIRC_DRIVER_NAME
-- ": set default io 0x%x\n",
-- io);
-- it87_write(IT87_CIR_BASE_MSB, io / 0x100);
-- it87_write(IT87_CIR_BASE_LSB, io % 0x100);
-- } else
-- io = it87_io;
--
-- it87_irq = it87_read(IT87_CIR_IRQ);
-- if (digimatrix || it87_irq == 0) {
-- if (irq == 0)
-- irq = IT87_CIR_DEFAULT_IRQ;
-- printk(KERN_INFO LIRC_DRIVER_NAME
-- ": set default irq 0x%x\n",
-- irq);
-- it87_write(IT87_CIR_IRQ, irq);
-- } else
-- irq = it87_irq;
--
-- spin_lock_irqsave(&hardware_lock, hw_flags);
-- /* reset */
-- outb(IT87_CIR_IER_RESET, io+IT87_CIR_IER);
-- /* fifo clear */
-- outb(IT87_CIR_TCR1_FIFOCLR |
-- /* IT87_CIR_TCR1_ILE | */
-- IT87_CIR_TCR1_TXRLE |
-- IT87_CIR_TCR1_TXENDF, io+IT87_CIR_TCR1);
-- spin_unlock_irqrestore(&hardware_lock, hw_flags);
--
-- /* get I/O port access and IRQ line */
-- if (request_region(io, 8, LIRC_DRIVER_NAME) == NULL) {
-- printk(KERN_ERR LIRC_DRIVER_NAME
-- ": i/o port 0x%.4x already in use.\n", io);
-- /* Leaving MB PnP Mode */
-- it87_write(IT87_CFGCTRL, 0x2);
-- return -EBUSY;
-- }
--
-- /* activate CIR-Device */
-- it87_write(IT87_CIR_ACT, 0x1);
--
-- /* Leaving MB PnP Mode */
-- it87_write(IT87_CFGCTRL, 0x2);
--
-- retval = request_irq(irq, it87_interrupt, 0 /*IRQF_DISABLED*/,
-- LIRC_DRIVER_NAME, NULL);
-- if (retval < 0) {
-- printk(KERN_ERR LIRC_DRIVER_NAME
-- ": IRQ %d already in use.\n",
-- irq);
-- release_region(io, 8);
-- return retval;
-- }
--
-- printk(KERN_INFO LIRC_DRIVER_NAME
-- ": I/O port 0x%.4x, IRQ %d.\n", io, irq);
--
-- init_timer(&timerlist);
-- timerlist.function = it87_timeout;
-- timerlist.data = 0xabadcafe;
--
-- return 0;
--}
--
--
--static void drop_port(void)
--{
--#if 0
-- unsigned char init_bytes[4] = IT87_INIT;
--
-- /* Enter MB PnP Mode */
-- outb(init_bytes[0], IT87_ADRPORT);
-- outb(init_bytes[1], IT87_ADRPORT);
-- outb(init_bytes[2], IT87_ADRPORT);
-- outb(init_bytes[3], IT87_ADRPORT);
--
-- /* deactivate CIR-Device */
-- it87_write(IT87_CIR_ACT, 0x0);
--
-- /* Leaving MB PnP Mode */
-- it87_write(IT87_CFGCTRL, 0x2);
--#endif
--
-- del_timer_sync(&timerlist);
-- free_irq(irq, NULL);
-- release_region(io, 8);
--}
--
--
--static int init_lirc_it87(void)
--{
-- int retval;
--
-- init_waitqueue_head(&lirc_read_queue);
-- retval = init_port();
-- if (retval < 0)
-- return retval;
-- init_hardware();
-- printk(KERN_INFO LIRC_DRIVER_NAME ": Installed.\n");
-- return 0;
--}
--
--static int it87_probe(struct pnp_dev *pnp_dev,
-- const struct pnp_device_id *dev_id)
--{
-- int retval;
--
-- driver.dev = &pnp_dev->dev;
--
-- retval = init_chrdev();
-- if (retval < 0)
-- return retval;
--
-- retval = init_lirc_it87();
-- if (retval)
-- goto init_lirc_it87_failed;
--
-- return 0;
--
--init_lirc_it87_failed:
-- drop_chrdev();
--
-- return retval;
--}
--
--static int __init lirc_it87_init(void)
--{
-- return pnp_register_driver(&it87_pnp_driver);
--}
--
--
--static void __exit lirc_it87_exit(void)
--{
-- drop_hardware();
-- drop_chrdev();
-- drop_port();
-- pnp_unregister_driver(&it87_pnp_driver);
-- printk(KERN_INFO LIRC_DRIVER_NAME ": Uninstalled.\n");
--}
--
--/* SECTION: PNP for ITE8704/13/18 */
--
--static const struct pnp_device_id pnp_dev_table[] = {
-- {"ITE8704", 0},
-- {"ITE8713", 0},
-- {}
--};
--
--MODULE_DEVICE_TABLE(pnp, pnp_dev_table);
--
--static struct pnp_driver it87_pnp_driver = {
-- .name = LIRC_DRIVER_NAME,
-- .id_table = pnp_dev_table,
-- .probe = it87_probe,
--};
--
--module_init(lirc_it87_init);
--module_exit(lirc_it87_exit);
--
--MODULE_DESCRIPTION("LIRC driver for ITE IT8704/05/12/18/20 CIR port");
--MODULE_AUTHOR("Hans-Gunter Lutke Uphues");
--MODULE_LICENSE("GPL");
--
--module_param(io, int, S_IRUGO);
--MODULE_PARM_DESC(io, "I/O base address (default: 0x310)");
--
--module_param(irq, int, S_IRUGO);
--#ifdef LIRC_IT87_DIGIMATRIX
--MODULE_PARM_DESC(irq, "Interrupt (1,3-12) (default: 9)");
--#else
--MODULE_PARM_DESC(irq, "Interrupt (1,3-12) (default: 7)");
--#endif
--
--module_param(it87_enable_demodulator, bool, S_IRUGO);
--MODULE_PARM_DESC(it87_enable_demodulator,
-- "Receiver demodulator enable/disable (1/0), default: 0");
--
--module_param(debug, bool, S_IRUGO | S_IWUSR);
--MODULE_PARM_DESC(debug, "Enable debugging messages");
--
--module_param(digimatrix, bool, S_IRUGO | S_IWUSR);
--#ifdef LIRC_IT87_DIGIMATRIX
--MODULE_PARM_DESC(digimatrix,
-- "Asus Digimatrix it87 compat. enable/disable (1/0), default: 1");
--#else
--MODULE_PARM_DESC(digimatrix,
-- "Asus Digimatrix it87 compat. enable/disable (1/0), default: 0");
--#endif
--
--
--module_param(it87_freq, int, S_IRUGO);
--#ifdef LIRC_IT87_DIGIMATRIX
--MODULE_PARM_DESC(it87_freq,
-- "Carrier demodulator frequency (kHz), (default: 36)");
--#else
--MODULE_PARM_DESC(it87_freq,
-- "Carrier demodulator frequency (kHz), (default: 38)");
--#endif
-diff --git a/drivers/staging/lirc/lirc_it87.h b/drivers/staging/lirc/lirc_it87.h
-deleted file mode 100644
-index cf021c8..0000000
---- a/drivers/staging/lirc/lirc_it87.h
-+++ /dev/null
-@@ -1,116 +0,0 @@
--/* lirc_it87.h */
--/* SECTION: Definitions */
--
--/********************************* ITE IT87xx ************************/
--
--/* based on the following documentation from ITE:
-- a) IT8712F Preliminary CIR Programming Guide V0.1
-- b) IT8705F Simple LPC I/O Preliminary Specification V0.3
-- c) IT8712F EC-LPC I/O Preliminary Specification V0.5
--*/
--
--/* IT8712/05 Ports: */
--#define IT87_ADRPORT 0x2e
--#define IT87_DATAPORT 0x2f
--#define IT87_INIT {0x87, 0x01, 0x55, 0x55}
--
--/* alternate Ports: */
--/*
--#define IT87_ADRPORT 0x4e
--#define IT87_DATAPORT 0x4f
--#define IT87_INIT {0x87, 0x01, 0x55, 0xaa}
-- */
--
--/* IT8712/05 Registers */
--#define IT87_CFGCTRL 0x2
--#define IT87_LDN 0x7
--#define IT87_CHIP_ID1 0x20
--#define IT87_CHIP_ID2 0x21
--#define IT87_CFG_VERSION 0x22
--#define IT87_SWSUSPEND 0x23
--
--#define IT8712_CIR_LDN 0xa
--#define IT8705_CIR_LDN 0x7
--
--/* CIR Configuration Registers: */
--#define IT87_CIR_ACT 0x30
--#define IT87_CIR_BASE_MSB 0x60
--#define IT87_CIR_BASE_LSB 0x61
--#define IT87_CIR_IRQ 0x70
--#define IT87_CIR_CONFIG 0xf0
--
--/* List of IT87_CIR registers: offset to BaseAddr */
--#define IT87_CIR_DR 0
--#define IT87_CIR_IER 1
--#define IT87_CIR_RCR 2
--#define IT87_CIR_TCR1 3
--#define IT87_CIR_TCR2 4
--#define IT87_CIR_TSR 5
--#define IT87_CIR_RSR 6
--#define IT87_CIR_BDLR 5
--#define IT87_CIR_BDHR 6
--#define IT87_CIR_IIR 7
--
--/* Bit Definition */
--/* IER: */
--#define IT87_CIR_IER_TM_EN 0x80
--#define IT87_CIR_IER_RESEVED 0x40
--#define IT87_CIR_IER_RESET 0x20
--#define IT87_CIR_IER_BR 0x10
--#define IT87_CIR_IER_IEC 0x8
--#define IT87_CIR_IER_RFOIE 0x4
--#define IT87_CIR_IER_RDAIE 0x2
--#define IT87_CIR_IER_TLDLIE 0x1
--
--/* RCR: */
--#define IT87_CIR_RCR_RDWOS 0x80
--#define IT87_CIR_RCR_HCFS 0x40
--#define IT87_CIR_RCR_RXEN 0x20
--#define IT87_CIR_RCR_RXEND 0x10
--#define IT87_CIR_RCR_RXACT 0x8
--#define IT87_CIR_RCR_RXDCR 0x7
--
--/* TCR1: */
--#define IT87_CIR_TCR1_FIFOCLR 0x80
--#define IT87_CIR_TCR1_ILE 0x40
--#define IT87_CIR_TCR1_FIFOTL 0x30
--#define IT87_CIR_TCR1_TXRLE 0x8
--#define IT87_CIR_TCR1_TXENDF 0x4
--#define IT87_CIR_TCR1_TXMPM 0x3
--
--/* TCR2: */
--#define IT87_CIR_TCR2_CFQ 0xf8
--#define IT87_CIR_TCR2_TXMPW 0x7
--
--/* TSR: */
--#define IT87_CIR_TSR_RESERVED 0xc0
--#define IT87_CIR_TSR_TXFBC 0x3f
--
--/* RSR: */
--#define IT87_CIR_RSR_RXFTO 0x80
--#define IT87_CIR_RSR_RESERVED 0x40
--#define IT87_CIR_RSR_RXFBC 0x3f
--
--/* IIR: */
--#define IT87_CIR_IIR_RESERVED 0xf8
--#define IT87_CIR_IIR_IID 0x6
--#define IT87_CIR_IIR_IIP 0x1
--
--/* TM: */
--#define IT87_CIR_TM_IL_SEL 0x80
--#define IT87_CIR_TM_RESERVED 0x40
--#define IT87_CIR_TM_TM_REG 0x3f
--
--#define IT87_CIR_FIFO_SIZE 32
--
--/* Baudratedivisor for IT87: power of 2: only 1,2,4 or 8) */
--#define IT87_CIR_BAUDRATE_DIVISOR 0x1
--#define IT87_CIR_DEFAULT_IOBASE 0x310
--#define IT87_CIR_DEFAULT_IRQ 0x7
--#define IT87_CIR_SPACE 0x00
--#define IT87_CIR_PULSE 0xff
--#define IT87_CIR_FREQ_MIN 27
--#define IT87_CIR_FREQ_MAX 58
--#define TIME_CONST (IT87_CIR_BAUDRATE_DIVISOR * 8000000ul / 115200ul)
--
--/********************************* ITE IT87xx ************************/
-diff --git a/drivers/staging/lirc/lirc_ite8709.c b/drivers/staging/lirc/lirc_ite8709.c
-deleted file mode 100644
-index cb20cfd..0000000
---- a/drivers/staging/lirc/lirc_ite8709.c
-+++ /dev/null
-@@ -1,542 +0,0 @@
--/*
-- * LIRC driver for ITE8709 CIR port
-- *
-- * Copyright (C) 2008 Grégory Lardière <spmf2004-lirc(a)yahoo.fr>
-- *
-- * 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/module.h>
--#include <linux/interrupt.h>
--#include <linux/sched.h>
--#include <linux/delay.h>
--#include <linux/pnp.h>
--#include <linux/io.h>
--
--#include <media/lirc.h>
--#include <media/lirc_dev.h>
--
--#define LIRC_DRIVER_NAME "lirc_ite8709"
--
--#define BUF_CHUNK_SIZE sizeof(int)
--#define BUF_SIZE (128*BUF_CHUNK_SIZE)
--
--/*
-- * The ITE8709 device seems to be the combination of IT8512 superIO chip and
-- * a specific firmware running on the IT8512's embedded micro-controller.
-- * In addition of the embedded micro-controller, the IT8512 chip contains a
-- * CIR module and several other modules. A few modules are directly accessible
-- * by the host CPU, but most of them are only accessible by the
-- * micro-controller. The CIR module is only accessible by the micro-controller.
-- * The battery-backed SRAM module is accessible by the host CPU and the
-- * micro-controller. So one of the MC's firmware role is to act as a bridge
-- * between the host CPU and the CIR module. The firmware implements a kind of
-- * communication protocol using the SRAM module as a shared memory. The IT8512
-- * specification is publicly available on ITE's web site, but the communication
-- * protocol is not, so it was reverse-engineered.
-- */
--
--/* ITE8709 Registers addresses and values (reverse-engineered) */
--#define ITE8709_MODE 0x1a
--#define ITE8709_REG_ADR 0x1b
--#define ITE8709_REG_VAL 0x1c
--#define ITE8709_IIR 0x1e /* Interrupt identification register */
--#define ITE8709_RFSR 0x1f /* Receiver FIFO status register */
--#define ITE8709_FIFO_START 0x20
--
--#define ITE8709_MODE_READY 0X00
--#define ITE8709_MODE_WRITE 0X01
--#define ITE8709_MODE_READ 0X02
--#define ITE8709_IIR_RDAI 0x02 /* Receiver data available interrupt */
--#define ITE8709_IIR_RFOI 0x04 /* Receiver FIFO overrun interrupt */
--#define ITE8709_RFSR_MASK 0x3f /* FIFO byte count mask */
--
--/*
-- * IT8512 CIR-module registers addresses and values
-- * (from IT8512 E/F specification v0.4.1)
-- */
--#define IT8512_REG_MSTCR 0x01 /* Master control register */
--#define IT8512_REG_IER 0x02 /* Interrupt enable register */
--#define IT8512_REG_CFR 0x04 /* Carrier frequency register */
--#define IT8512_REG_RCR 0x05 /* Receive control register */
--#define IT8512_REG_BDLR 0x08 /* Baud rate divisor low byte register */
--#define IT8512_REG_BDHR 0x09 /* Baud rate divisor high byte register */
--
--#define IT8512_MSTCR_RESET 0x01 /* Reset registers to default value */
--#define IT8512_MSTCR_FIFOCLR 0x02 /* Clear FIFO */
--#define IT8512_MSTCR_FIFOTL_7 0x04 /* FIFO threshold level : 7 */
--#define IT8512_MSTCR_FIFOTL_25 0x0c /* FIFO threshold level : 25 */
--#define IT8512_IER_RDAIE 0x02 /* Enable data interrupt request */
--#define IT8512_IER_RFOIE 0x04 /* Enable FIFO overrun interrupt req */
--#define IT8512_IER_IEC 0x80 /* Enable interrupt request */
--#define IT8512_CFR_CF_36KHZ 0x09 /* Carrier freq : low speed, 36kHz */
--#define IT8512_RCR_RXDCR_1 0x01 /* Demodulation carrier range : 1 */
--#define IT8512_RCR_RXACT 0x08 /* Receiver active */
--#define IT8512_RCR_RXEN 0x80 /* Receiver enable */
--#define IT8512_BDR_6 6 /* Baud rate divisor : 6 */
--
--/* Actual values used by this driver */
--#define CFG_FIFOTL IT8512_MSTCR_FIFOTL_25
--#define CFG_CR_FREQ IT8512_CFR_CF_36KHZ
--#define CFG_DCR IT8512_RCR_RXDCR_1
--#define CFG_BDR IT8512_BDR_6
--#define CFG_TIMEOUT 100000 /* Rearm interrupt when a space is > 100 ms */
--
--static int debug;
--
--struct ite8709_device {
-- int use_count;
-- int io;
-- int irq;
-- spinlock_t hardware_lock;
-- __u64 acc_pulse;
-- __u64 acc_space;
-- char lastbit;
-- struct timeval last_tv;
-- struct lirc_driver driver;
-- struct tasklet_struct tasklet;
-- char force_rearm;
-- char rearmed;
-- char device_busy;
--};
--
--#define dprintk(fmt, args...) \
-- do { \
-- if (debug) \
-- printk(KERN_DEBUG LIRC_DRIVER_NAME ": " \
-- fmt, ## args); \
-- } while (0)
--
--
--static unsigned char ite8709_read(struct ite8709_device *dev,
-- unsigned char port)
--{
-- outb(port, dev->io);
-- return inb(dev->io+1);
--}
--
--static void ite8709_write(struct ite8709_device *dev, unsigned char port,
-- unsigned char data)
--{
-- outb(port, dev->io);
-- outb(data, dev->io+1);
--}
--
--static void ite8709_wait_device(struct ite8709_device *dev)
--{
-- int i = 0;
-- /*
-- * loop until device tells it's ready to continue
-- * iterations count is usually ~750 but can sometimes achieve 13000
-- */
-- for (i = 0; i < 15000; i++) {
-- udelay(2);
-- if (ite8709_read(dev, ITE8709_MODE) == ITE8709_MODE_READY)
-- break;
-- }
--}
--
--static void ite8709_write_register(struct ite8709_device *dev,
-- unsigned char reg_adr, unsigned char reg_value)
--{
-- ite8709_wait_device(dev);
--
-- ite8709_write(dev, ITE8709_REG_VAL, reg_value);
-- ite8709_write(dev, ITE8709_REG_ADR, reg_adr);
-- ite8709_write(dev, ITE8709_MODE, ITE8709_MODE_WRITE);
--}
--
--static void ite8709_init_hardware(struct ite8709_device *dev)
--{
-- spin_lock_irq(&dev->hardware_lock);
-- dev->device_busy = 1;
-- spin_unlock_irq(&dev->hardware_lock);
--
-- ite8709_write_register(dev, IT8512_REG_BDHR, (CFG_BDR >> 8) & 0xff);
-- ite8709_write_register(dev, IT8512_REG_BDLR, CFG_BDR & 0xff);
-- ite8709_write_register(dev, IT8512_REG_CFR, CFG_CR_FREQ);
-- ite8709_write_register(dev, IT8512_REG_IER,
-- IT8512_IER_IEC | IT8512_IER_RFOIE | IT8512_IER_RDAIE);
-- ite8709_write_register(dev, IT8512_REG_RCR, CFG_DCR);
-- ite8709_write_register(dev, IT8512_REG_MSTCR,
-- CFG_FIFOTL | IT8512_MSTCR_FIFOCLR);
-- ite8709_write_register(dev, IT8512_REG_RCR,
-- IT8512_RCR_RXEN | IT8512_RCR_RXACT | CFG_DCR);
--
-- spin_lock_irq(&dev->hardware_lock);
-- dev->device_busy = 0;
-- spin_unlock_irq(&dev->hardware_lock);
--
-- tasklet_enable(&dev->tasklet);
--}
--
--static void ite8709_drop_hardware(struct ite8709_device *dev)
--{
-- tasklet_disable(&dev->tasklet);
--
-- spin_lock_irq(&dev->hardware_lock);
-- dev->device_busy = 1;
-- spin_unlock_irq(&dev->hardware_lock);
--
-- ite8709_write_register(dev, IT8512_REG_RCR, 0);
-- ite8709_write_register(dev, IT8512_REG_MSTCR,
-- IT8512_MSTCR_RESET | IT8512_MSTCR_FIFOCLR);
--
-- spin_lock_irq(&dev->hardware_lock);
-- dev->device_busy = 0;
-- spin_unlock_irq(&dev->hardware_lock);
--}
--
--static int ite8709_set_use_inc(void *data)
--{
-- struct ite8709_device *dev;
-- dev = data;
-- if (dev->use_count == 0)
-- ite8709_init_hardware(dev);
-- dev->use_count++;
-- return 0;
--}
--
--static void ite8709_set_use_dec(void *data)
--{
-- struct ite8709_device *dev;
-- dev = data;
-- dev->use_count--;
-- if (dev->use_count == 0)
-- ite8709_drop_hardware(dev);
--}
--
--static void ite8709_add_read_queue(struct ite8709_device *dev, int flag,
-- __u64 val)
--{
-- int value;
--
-- dprintk("add a %llu usec %s\n", val, flag ? "pulse" :
"space");
--
-- value = (val > PULSE_MASK) ? PULSE_MASK : val;
-- if (flag)
-- value |= PULSE_BIT;
--
-- if (!lirc_buffer_full(dev->driver.rbuf)) {
-- lirc_buffer_write(dev->driver.rbuf, (void *) &value);
-- wake_up(&dev->driver.rbuf->wait_poll);
-- }
--}
--
--static irqreturn_t ite8709_interrupt(int irq, void *dev_id)
--{
-- unsigned char data;
-- int iir, rfsr, i;
-- int fifo = 0;
-- char bit;
-- struct timeval curr_tv;
--
-- /* Bit duration in microseconds */
-- const unsigned long bit_duration = 1000000ul / (115200 / CFG_BDR);
--
-- struct ite8709_device *dev;
-- dev = dev_id;
--
-- /*
-- * If device is busy, we simply discard data because we are in one of
-- * these two cases : shutting down or rearming the device, so this
-- * doesn't really matter and this avoids waiting too long in IRQ ctx
-- */
-- spin_lock(&dev->hardware_lock);
-- if (dev->device_busy) {
-- spin_unlock(&dev->hardware_lock);
-- return IRQ_RETVAL(IRQ_HANDLED);
-- }
--
-- iir = ite8709_read(dev, ITE8709_IIR);
--
-- switch (iir) {
-- case ITE8709_IIR_RFOI:
-- dprintk("fifo overrun, scheduling forced rearm just in case\n");
-- dev->force_rearm = 1;
-- tasklet_schedule(&dev->tasklet);
-- spin_unlock(&dev->hardware_lock);
-- return IRQ_RETVAL(IRQ_HANDLED);
--
-- case ITE8709_IIR_RDAI:
-- rfsr = ite8709_read(dev, ITE8709_RFSR);
-- fifo = rfsr & ITE8709_RFSR_MASK;
-- if (fifo > 32)
-- fifo = 32;
-- dprintk("iir: 0x%x rfsr: 0x%x fifo: %d\n", iir, rfsr, fifo);
--
-- if (dev->rearmed) {
-- do_gettimeofday(&curr_tv);
-- dev->acc_space += 1000000ull
-- * (curr_tv.tv_sec - dev->last_tv.tv_sec)
-- + (curr_tv.tv_usec - dev->last_tv.tv_usec);
-- dev->rearmed = 0;
-- }
-- for (i = 0; i < fifo; i++) {
-- data = ite8709_read(dev, i+ITE8709_FIFO_START);
-- data = ~data;
-- /* Loop through */
-- for (bit = 0; bit < 8; ++bit) {
-- if ((data >> bit) & 1) {
-- dev->acc_pulse += bit_duration;
-- if (dev->lastbit == 0) {
-- ite8709_add_read_queue(dev, 0,
-- dev->acc_space);
-- dev->acc_space = 0;
-- }
-- } else {
-- dev->acc_space += bit_duration;
-- if (dev->lastbit == 1) {
-- ite8709_add_read_queue(dev, 1,
-- dev->acc_pulse);
-- dev->acc_pulse = 0;
-- }
-- }
-- dev->lastbit = (data >> bit) & 1;
-- }
-- }
-- ite8709_write(dev, ITE8709_RFSR, 0);
--
-- if (dev->acc_space > CFG_TIMEOUT) {
-- dprintk("scheduling rearm IRQ\n");
-- do_gettimeofday(&dev->last_tv);
-- dev->force_rearm = 0;
-- tasklet_schedule(&dev->tasklet);
-- }
--
-- spin_unlock(&dev->hardware_lock);
-- return IRQ_RETVAL(IRQ_HANDLED);
--
-- default:
-- /* not our irq */
-- dprintk("unknown IRQ (shouldn't happen) !!\n");
-- spin_unlock(&dev->hardware_lock);
-- return IRQ_RETVAL(IRQ_NONE);
-- }
--}
--
--static void ite8709_rearm_irq(unsigned long data)
--{
-- struct ite8709_device *dev;
-- unsigned long flags;
-- dev = (struct ite8709_device *) data;
--
-- spin_lock_irqsave(&dev->hardware_lock, flags);
-- dev->device_busy = 1;
-- spin_unlock_irqrestore(&dev->hardware_lock, flags);
--
-- if (dev->force_rearm || dev->acc_space > CFG_TIMEOUT) {
-- dprintk("rearming IRQ\n");
-- ite8709_write_register(dev, IT8512_REG_RCR,
-- IT8512_RCR_RXACT | CFG_DCR);
-- ite8709_write_register(dev, IT8512_REG_MSTCR,
-- CFG_FIFOTL | IT8512_MSTCR_FIFOCLR);
-- ite8709_write_register(dev, IT8512_REG_RCR,
-- IT8512_RCR_RXEN | IT8512_RCR_RXACT | CFG_DCR);
-- if (!dev->force_rearm)
-- dev->rearmed = 1;
-- dev->force_rearm = 0;
-- }
--
-- spin_lock_irqsave(&dev->hardware_lock, flags);
-- dev->device_busy = 0;
-- spin_unlock_irqrestore(&dev->hardware_lock, flags);
--}
--
--static int ite8709_cleanup(struct ite8709_device *dev, int stage, int errno,
-- char *msg)
--{
-- if (msg != NULL)
-- printk(KERN_ERR LIRC_DRIVER_NAME ": %s\n", msg);
--
-- switch (stage) {
-- case 6:
-- if (dev->use_count > 0)
-- ite8709_drop_hardware(dev);
-- case 5:
-- free_irq(dev->irq, dev);
-- case 4:
-- release_region(dev->io, 2);
-- case 3:
-- lirc_unregister_driver(dev->driver.minor);
-- case 2:
-- lirc_buffer_free(dev->driver.rbuf);
-- kfree(dev->driver.rbuf);
-- case 1:
-- kfree(dev);
-- case 0:
-- ;
-- }
--
-- return errno;
--}
--
--static int __devinit ite8709_pnp_probe(struct pnp_dev *dev,
-- const struct pnp_device_id *dev_id)
--{
-- struct lirc_driver *driver;
-- struct ite8709_device *ite8709_dev;
-- int ret;
--
-- /* Check resources validity */
-- if (!pnp_irq_valid(dev, 0))
-- return ite8709_cleanup(NULL, 0, -ENODEV, "invalid IRQ");
-- if (!pnp_port_valid(dev, 2))
-- return ite8709_cleanup(NULL, 0, -ENODEV, "invalid IO port");
--
-- /* Allocate memory for device struct */
-- ite8709_dev = kzalloc(sizeof(struct ite8709_device), GFP_KERNEL);
-- if (ite8709_dev == NULL)
-- return ite8709_cleanup(NULL, 0, -ENOMEM, "kzalloc failed");
-- pnp_set_drvdata(dev, ite8709_dev);
--
-- /* Initialize device struct */
-- ite8709_dev->use_count = 0;
-- ite8709_dev->irq = pnp_irq(dev, 0);
-- ite8709_dev->io = pnp_port_start(dev, 2);
-- ite8709_dev->hardware_lock =
-- __SPIN_LOCK_UNLOCKED(ite8709_dev->hardware_lock);
-- ite8709_dev->acc_pulse = 0;
-- ite8709_dev->acc_space = 0;
-- ite8709_dev->lastbit = 0;
-- do_gettimeofday(&ite8709_dev->last_tv);
-- tasklet_init(&ite8709_dev->tasklet, ite8709_rearm_irq,
-- (long) ite8709_dev);
-- ite8709_dev->force_rearm = 0;
-- ite8709_dev->rearmed = 0;
-- ite8709_dev->device_busy = 0;
--
-- /* Initialize driver struct */
-- driver = &ite8709_dev->driver;
-- strcpy(driver->name, LIRC_DRIVER_NAME);
-- driver->minor = -1;
-- driver->code_length = sizeof(int) * 8;
-- driver->sample_rate = 0;
-- driver->features = LIRC_CAN_REC_MODE2;
-- driver->data = ite8709_dev;
-- driver->add_to_buf = NULL;
-- driver->set_use_inc = ite8709_set_use_inc;
-- driver->set_use_dec = ite8709_set_use_dec;
-- driver->dev = &dev->dev;
-- driver->owner = THIS_MODULE;
--
-- /* Initialize LIRC buffer */
-- driver->rbuf = kmalloc(sizeof(struct lirc_buffer), GFP_KERNEL);
-- if (!driver->rbuf)
-- return ite8709_cleanup(ite8709_dev, 1, -ENOMEM,
-- "can't allocate lirc_buffer");
-- if (lirc_buffer_init(driver->rbuf, BUF_CHUNK_SIZE, BUF_SIZE))
-- return ite8709_cleanup(ite8709_dev, 1, -ENOMEM,
-- "lirc_buffer_init() failed");
--
-- /* Register LIRC driver */
-- ret = lirc_register_driver(driver);
-- if (ret < 0)
-- return ite8709_cleanup(ite8709_dev, 2, ret,
-- "lirc_register_driver() failed");
--
-- /* Reserve I/O port access */
-- if (!request_region(ite8709_dev->io, 2, LIRC_DRIVER_NAME))
-- return ite8709_cleanup(ite8709_dev, 3, -EBUSY,
-- "i/o port already in use");
--
-- /* Reserve IRQ line */
-- ret = request_irq(ite8709_dev->irq, ite8709_interrupt, 0,
-- LIRC_DRIVER_NAME, ite8709_dev);
-- if (ret < 0)
-- return ite8709_cleanup(ite8709_dev, 4, ret,
-- "IRQ already in use");
--
-- /* Initialize hardware */
-- ite8709_drop_hardware(ite8709_dev); /* Shutdown hw until first use */
--
-- printk(KERN_INFO LIRC_DRIVER_NAME ": device found : irq=%d io=0x%x\n",
-- ite8709_dev->irq, ite8709_dev->io);
--
-- return 0;
--}
--
--static void __devexit ite8709_pnp_remove(struct pnp_dev *dev)
--{
-- struct ite8709_device *ite8709_dev;
-- ite8709_dev = pnp_get_drvdata(dev);
--
-- ite8709_cleanup(ite8709_dev, 6, 0, NULL);
--
-- printk(KERN_INFO LIRC_DRIVER_NAME ": device removed\n");
--}
--
--#ifdef CONFIG_PM
--static int ite8709_pnp_suspend(struct pnp_dev *dev, pm_message_t state)
--{
-- struct ite8709_device *ite8709_dev;
-- ite8709_dev = pnp_get_drvdata(dev);
--
-- if (ite8709_dev->use_count > 0)
-- ite8709_drop_hardware(ite8709_dev);
--
-- return 0;
--}
--
--static int ite8709_pnp_resume(struct pnp_dev *dev)
--{
-- struct ite8709_device *ite8709_dev;
-- ite8709_dev = pnp_get_drvdata(dev);
--
-- if (ite8709_dev->use_count > 0)
-- ite8709_init_hardware(ite8709_dev);
--
-- return 0;
--}
--#else
--#define ite8709_pnp_suspend NULL
--#define ite8709_pnp_resume NULL
--#endif
--
--static const struct pnp_device_id pnp_dev_table[] = {
-- {"ITE8709", 0},
-- {}
--};
--
--MODULE_DEVICE_TABLE(pnp, pnp_dev_table);
--
--static struct pnp_driver ite8709_pnp_driver = {
-- .name = LIRC_DRIVER_NAME,
-- .probe = ite8709_pnp_probe,
-- .remove = __devexit_p(ite8709_pnp_remove),
-- .suspend = ite8709_pnp_suspend,
-- .resume = ite8709_pnp_resume,
-- .id_table = pnp_dev_table,
--};
--
--static int __init ite8709_init_module(void)
--{
-- return pnp_register_driver(&ite8709_pnp_driver);
--}
--module_init(ite8709_init_module);
--
--static void __exit ite8709_cleanup_module(void)
--{
-- pnp_unregister_driver(&ite8709_pnp_driver);
--}
--module_exit(ite8709_cleanup_module);
--
--MODULE_DESCRIPTION("LIRC driver for ITE8709 CIR port");
--MODULE_AUTHOR("Grégory Lardière");
--MODULE_LICENSE("GPL");
--
--module_param(debug, bool, S_IRUGO | S_IWUSR);
--MODULE_PARM_DESC(debug, "Enable debugging messages");
-diff --git a/drivers/staging/lirc/lirc_sasem.c b/drivers/staging/lirc/lirc_sasem.c
-index 925eabe..63a438d 100644
---- a/drivers/staging/lirc/lirc_sasem.c
-+++ b/drivers/staging/lirc/lirc_sasem.c
-@@ -364,7 +364,7 @@ static ssize_t vfd_write(struct file *file, const char *buf,
- int i;
- int retval = 0;
- struct sasem_context *context;
-- int *data_buf;
-+ int *data_buf = NULL;
-
- context = (struct sasem_context *) file->private_data;
- if (!context) {
-diff --git a/drivers/staging/lirc/lirc_zilog.c b/drivers/staging/lirc/lirc_zilog.c
-index 0aad0d7..dd6a57c 100644
---- a/drivers/staging/lirc/lirc_zilog.c
-+++ b/drivers/staging/lirc/lirc_zilog.c
-@@ -63,14 +63,16 @@
- #include <media/lirc_dev.h>
- #include <media/lirc.h>
-
-+struct IR;
-+
- struct IR_rx {
-+ struct kref ref;
-+ struct IR *ir;
-+
- /* RX device */
-+ struct mutex client_lock;
- struct i2c_client *c;
-
-- /* RX device buffer & lock */
-- struct lirc_buffer buf;
-- struct mutex buf_lock;
--
- /* RX polling thread data */
- struct task_struct *task;
-
-@@ -80,7 +82,11 @@ struct IR_rx {
- };
-
- struct IR_tx {
-+ struct kref ref;
-+ struct IR *ir;
-+
- /* TX device */
-+ struct mutex client_lock;
- struct i2c_client *c;
-
- /* TX additional actions needed */
-@@ -89,19 +95,34 @@ struct IR_tx {
- };
-
- struct IR {
-+ struct kref ref;
-+ struct list_head list;
-+
-+ /* FIXME spinlock access to l.features */
- struct lirc_driver l;
-+ struct lirc_buffer rbuf;
-
- struct mutex ir_lock;
-- int open;
-+ atomic_t open_count;
-
- struct i2c_adapter *adapter;
-+
-+ spinlock_t rx_ref_lock; /* struct IR_rx kref get()/put() */
- struct IR_rx *rx;
-+
-+ spinlock_t tx_ref_lock; /* struct IR_tx kref get()/put() */
- struct IR_tx *tx;
- };
-
--/* Minor -> data mapping */
--static struct mutex ir_devices_lock;
--static struct IR *ir_devices[MAX_IRCTL_DEVICES];
-+/* IR transceiver instance object list */
-+/*
-+ * This lock is used for the following:
-+ * a. ir_devices_list access, insertions, deletions
-+ * b. struct IR kref get()s and put()s
-+ * c. serialization of ir_probe() for the two i2c_clients for a Z8
-+ */
-+static DEFINE_MUTEX(ir_devices_lock);
-+static LIST_HEAD(ir_devices_list);
-
- /* Block size for IR transmitter */
- #define TX_BLOCK_SIZE 99
-@@ -147,6 +168,157 @@ static int minor = -1; /* minor number */
- ## args); \
- } while (0)
-
-+
-+/* struct IR reference counting */
-+static struct IR *get_ir_device(struct IR *ir, bool ir_devices_lock_held)
-+{
-+ if (ir_devices_lock_held) {
-+ kref_get(&ir->ref);
-+ } else {
-+ mutex_lock(&ir_devices_lock);
-+ kref_get(&ir->ref);
-+ mutex_unlock(&ir_devices_lock);
-+ }
-+ return ir;
-+}
-+
-+static void release_ir_device(struct kref *ref)
-+{
-+ struct IR *ir = container_of(ref, struct IR, ref);
-+
-+ /*
-+ * Things should be in this state by now:
-+ * ir->rx set to NULL and deallocated - happens before ir->rx->ir put()
-+ * ir->rx->task kthread stopped - happens before ir->rx->ir put()
-+ * ir->tx set to NULL and deallocated - happens before ir->tx->ir put()
-+ * ir->open_count == 0 - happens on final close()
-+ * ir_lock, tx_ref_lock, rx_ref_lock, all released
-+ */
-+ if (ir->l.minor >= 0 && ir->l.minor < MAX_IRCTL_DEVICES) {
-+ lirc_unregister_driver(ir->l.minor);
-+ ir->l.minor = MAX_IRCTL_DEVICES;
-+ }
-+ if (ir->rbuf.fifo_initialized)
-+ lirc_buffer_free(&ir->rbuf);
-+ list_del(&ir->list);
-+ kfree(ir);
-+}
-+
-+static int put_ir_device(struct IR *ir, bool ir_devices_lock_held)
-+{
-+ int released;
-+
-+ if (ir_devices_lock_held)
-+ return kref_put(&ir->ref, release_ir_device);
-+
-+ mutex_lock(&ir_devices_lock);
-+ released = kref_put(&ir->ref, release_ir_device);
-+ mutex_unlock(&ir_devices_lock);
-+
-+ return released;
-+}
-+
-+/* struct IR_rx reference counting */
-+static struct IR_rx *get_ir_rx(struct IR *ir)
-+{
-+ struct IR_rx *rx;
-+
-+ spin_lock(&ir->rx_ref_lock);
-+ rx = ir->rx;
-+ if (rx != NULL)
-+ kref_get(&rx->ref);
-+ spin_unlock(&ir->rx_ref_lock);
-+ return rx;
-+}
-+
-+static void destroy_rx_kthread(struct IR_rx *rx, bool ir_devices_lock_held)
-+{
-+ /* end up polling thread */
-+ if (!IS_ERR_OR_NULL(rx->task)) {
-+ kthread_stop(rx->task);
-+ rx->task = NULL;
-+ /* Put the ir ptr that ir_probe() gave to the rx poll thread */
-+ put_ir_device(rx->ir, ir_devices_lock_held);
-+ }
-+}
-+
-+static void release_ir_rx(struct kref *ref)
-+{
-+ struct IR_rx *rx = container_of(ref, struct IR_rx, ref);
-+ struct IR *ir = rx->ir;
-+
-+ /*
-+ * This release function can't do all the work, as we want
-+ * to keep the rx_ref_lock a spinlock, and killing the poll thread
-+ * and releasing the ir reference can cause a sleep. That work is
-+ * performed by put_ir_rx()
-+ */
-+ ir->l.features &= ~LIRC_CAN_REC_LIRCCODE;
-+ /* Don't put_ir_device(rx->ir) here; lock can't be freed yet */
-+ ir->rx = NULL;
-+ /* Don't do the kfree(rx) here; we still need to kill the poll thread */
-+ return;
-+}
-+
-+static int put_ir_rx(struct IR_rx *rx, bool ir_devices_lock_held)
-+{
-+ int released;
-+ struct IR *ir = rx->ir;
-+
-+ spin_lock(&ir->rx_ref_lock);
-+ released = kref_put(&rx->ref, release_ir_rx);
-+ spin_unlock(&ir->rx_ref_lock);
-+ /* Destroy the rx kthread while not holding the spinlock */
-+ if (released) {
-+ destroy_rx_kthread(rx, ir_devices_lock_held);
-+ kfree(rx);
-+ /* Make sure we're not still in a poll_table somewhere */
-+ wake_up_interruptible(&ir->rbuf.wait_poll);
-+ }
-+ /* Do a reference put() for the rx->ir reference, if we released rx */
-+ if (released)
-+ put_ir_device(ir, ir_devices_lock_held);
-+ return released;
-+}
-+
-+/* struct IR_tx reference counting */
-+static struct IR_tx *get_ir_tx(struct IR *ir)
-+{
-+ struct IR_tx *tx;
-+
-+ spin_lock(&ir->tx_ref_lock);
-+ tx = ir->tx;
-+ if (tx != NULL)
-+ kref_get(&tx->ref);
-+ spin_unlock(&ir->tx_ref_lock);
-+ return tx;
-+}
-+
-+static void release_ir_tx(struct kref *ref)
-+{
-+ struct IR_tx *tx = container_of(ref, struct IR_tx, ref);
-+ struct IR *ir = tx->ir;
-+
-+ ir->l.features &= ~LIRC_CAN_SEND_PULSE;
-+ /* Don't put_ir_device(tx->ir) here, so our lock doesn't get freed */
-+ ir->tx = NULL;
-+ kfree(tx);
-+}
-+
-+static int put_ir_tx(struct IR_tx *tx, bool ir_devices_lock_held)
-+{
-+ int released;
-+ struct IR *ir = tx->ir;
-+
-+ spin_lock(&ir->tx_ref_lock);
-+ released = kref_put(&tx->ref, release_ir_tx);
-+ spin_unlock(&ir->tx_ref_lock);
-+ /* Do a reference put() for the tx->ir reference, if we released tx */
-+ if (released)
-+ put_ir_device(ir, ir_devices_lock_held);
-+ return released;
-+}
-+
- static int add_to_buf(struct IR *ir)
- {
- __u16 code;
-@@ -156,23 +328,38 @@ static int add_to_buf(struct IR *ir)
- int ret;
- int failures = 0;
- unsigned char sendbuf[1] = { 0 };
-- struct IR_rx *rx = ir->rx;
-+ struct lirc_buffer *rbuf = ir->l.rbuf;
-+ struct IR_rx *rx;
-+ struct IR_tx *tx;
-
-+ if (lirc_buffer_full(rbuf)) {
-+ dprintk("buffer overflow\n");
-+ return -EOVERFLOW;
-+ }
-+
-+ rx = get_ir_rx(ir);
- if (rx == NULL)
- return -ENXIO;
-
-- if (lirc_buffer_full(&rx->buf)) {
-- dprintk("buffer overflow\n");
-- return -EOVERFLOW;
-+ /* Ensure our rx->c i2c_client remains valid for the duration */
-+ mutex_lock(&rx->client_lock);
-+ if (rx->c == NULL) {
-+ mutex_unlock(&rx->client_lock);
-+ put_ir_rx(rx, false);
-+ return -ENXIO;
- }
-
-+ tx = get_ir_tx(ir);
-+
- /*
- * service the device as long as it is returning
- * data and we have space
- */
- do {
-- if (kthread_should_stop())
-- return -ENODATA;
-+ if (kthread_should_stop()) {
-+ ret = -ENODATA;
-+ break;
-+ }
-
- /*
- * Lock i2c bus for the duration. RX/TX chips interfere so
-@@ -182,7 +369,8 @@ static int add_to_buf(struct IR *ir)
-
- if (kthread_should_stop()) {
- mutex_unlock(&ir->ir_lock);
-- return -ENODATA;
-+ ret = -ENODATA;
-+ break;
- }
-
- /*
-@@ -196,7 +384,7 @@ static int add_to_buf(struct IR *ir)
- mutex_unlock(&ir->ir_lock);
- zilog_error("unable to read from the IR chip "
- "after 3 resets, giving up\n");
-- return ret;
-+ break;
- }
-
- /* Looks like the chip crashed, reset it */
-@@ -206,19 +394,23 @@ static int add_to_buf(struct IR *ir)
- set_current_state(TASK_UNINTERRUPTIBLE);
- if (kthread_should_stop()) {
- mutex_unlock(&ir->ir_lock);
-- return -ENODATA;
-+ ret = -ENODATA;
-+ break;
- }
- schedule_timeout((100 * HZ + 999) / 1000);
-- ir->tx->need_boot = 1;
-+ if (tx != NULL)
-+ tx->need_boot = 1;
-
- ++failures;
- mutex_unlock(&ir->ir_lock);
-+ ret = 0;
- continue;
- }
-
- if (kthread_should_stop()) {
- mutex_unlock(&ir->ir_lock);
-- return -ENODATA;
-+ ret = -ENODATA;
-+ break;
- }
- ret = i2c_master_recv(rx->c, keybuf, sizeof(keybuf));
- mutex_unlock(&ir->ir_lock);
-@@ -234,12 +426,17 @@ static int add_to_buf(struct IR *ir)
-
- /* key pressed ? */
- if (rx->hdpvr_data_fmt) {
-- if (got_data && (keybuf[0] == 0x80))
-- return 0;
-- else if (got_data && (keybuf[0] == 0x00))
-- return -ENODATA;
-- } else if ((rx->b[0] & 0x80) == 0)
-- return got_data ? 0 : -ENODATA;
-+ if (got_data && (keybuf[0] == 0x80)) {
-+ ret = 0;
-+ break;
-+ } else if (got_data && (keybuf[0] == 0x00)) {
-+ ret = -ENODATA;
-+ break;
-+ }
-+ } else if ((rx->b[0] & 0x80) == 0) {
-+ ret = got_data ? 0 : -ENODATA;
-+ break;
-+ }
-
- /* look what we have */
- code = (((__u16)rx->b[0] & 0x7f) << 6) | (rx->b[1] >> 2);
-@@ -248,11 +445,16 @@ static int add_to_buf(struct IR *ir)
- codes[1] = code & 0xff;
-
- /* return it */
-- lirc_buffer_write(&rx->buf, codes);
-+ lirc_buffer_write(rbuf, codes);
- ++got_data;
-- } while (!lirc_buffer_full(&rx->buf));
-+ ret = 0;
-+ } while (!lirc_buffer_full(rbuf));
-
-- return 0;
-+ mutex_unlock(&rx->client_lock);
-+ if (tx != NULL)
-+ put_ir_tx(tx, false);
-+ put_ir_rx(rx, false);
-+ return ret;
- }
-
- /*
-@@ -268,19 +470,19 @@ static int add_to_buf(struct IR *ir)
- static int lirc_thread(void *arg)
- {
- struct IR *ir = arg;
-- struct IR_rx *rx = ir->rx;
-+ struct lirc_buffer *rbuf = ir->l.rbuf;
-
- dprintk("poll thread started\n");
-
- while (!kthread_should_stop()) {
-- set_current_state(TASK_INTERRUPTIBLE);
--
- /* if device not opened, we can sleep half a second */
-- if (!ir->open) {
-+ if (atomic_read(&ir->open_count) == 0) {
- schedule_timeout(HZ/2);
- continue;
- }
-
-+ set_current_state(TASK_INTERRUPTIBLE);
-+
- /*
- * This is ~113*2 + 24 + jitter (2*repeat gap + code length).
- * We use this interval as the chip resets every time you poll
-@@ -295,7 +497,7 @@ static int lirc_thread(void *arg)
- if (kthread_should_stop())
- break;
- if (!add_to_buf(ir))
-- wake_up_interruptible(&rx->buf.wait_poll);
-+ wake_up_interruptible(&rbuf->wait_poll);
- }
-
- dprintk("poll thread ended\n");
-@@ -304,34 +506,12 @@ static int lirc_thread(void *arg)
-
- static int set_use_inc(void *data)
- {
-- struct IR *ir = data;
--
-- if (ir->l.owner == NULL || try_module_get(ir->l.owner) == 0)
-- return -ENODEV;
--
-- /* lock bttv in memory while /dev/lirc is in use */
-- /*
-- * this is completely broken code. lirc_unregister_driver()
-- * must be possible even when the device is open
-- */
-- if (ir->rx != NULL)
-- i2c_use_client(ir->rx->c);
-- if (ir->tx != NULL)
-- i2c_use_client(ir->tx->c);
--
- return 0;
- }
-
- static void set_use_dec(void *data)
- {
-- struct IR *ir = data;
--
-- if (ir->rx)
-- i2c_release_client(ir->rx->c);
-- if (ir->tx)
-- i2c_release_client(ir->tx->c);
-- if (ir->l.owner != NULL)
-- module_put(ir->l.owner);
-+ return;
- }
-
- /* safe read of a uint32 (always network byte order) */
-@@ -585,7 +765,7 @@ static int fw_load(struct IR_tx *tx)
- }
-
- /* Request codeset data file */
-- ret = request_firmware(&fw_entry, "haup-ir-blaster.bin",
&tx->c->dev);
-+ ret = request_firmware(&fw_entry, "haup-ir-blaster.bin",
tx->ir->l.dev);
- if (ret != 0) {
- zilog_error("firmware haup-ir-blaster.bin not available "
- "(%d)\n", ret);
-@@ -711,59 +891,32 @@ out:
- return ret;
- }
-
--/* initialise the IR TX device */
--static int tx_init(struct IR_tx *tx)
--{
-- int ret;
--
-- /* Load 'firmware' */
-- ret = fw_load(tx);
-- if (ret != 0)
-- return ret;
--
-- /* Send boot block */
-- ret = send_boot_data(tx);
-- if (ret != 0)
-- return ret;
-- tx->need_boot = 0;
--
-- /* Looks good */
-- return 0;
--}
--
--/* do nothing stub to make LIRC happy */
--static loff_t lseek(struct file *filep, loff_t offset, int orig)
--{
-- return -ESPIPE;
--}
--
- /* copied from lirc_dev */
- static ssize_t read(struct file *filep, char *outbuf, size_t n, loff_t *ppos)
- {
- struct IR *ir = filep->private_data;
-- struct IR_rx *rx = ir->rx;
-- int ret = 0, written = 0;
-+ struct IR_rx *rx;
-+ struct lirc_buffer *rbuf = ir->l.rbuf;
-+ int ret = 0, written = 0, retries = 0;
-+ unsigned int m;
- DECLARE_WAITQUEUE(wait, current);
-
- dprintk("read called\n");
-- if (rx == NULL)
-- return -ENODEV;
--
-- if (mutex_lock_interruptible(&rx->buf_lock))
-- return -ERESTARTSYS;
--
-- if (n % rx->buf.chunk_size) {
-+ if (n % rbuf->chunk_size) {
- dprintk("read result = -EINVAL\n");
-- mutex_unlock(&rx->buf_lock);
- return -EINVAL;
- }
-
-+ rx = get_ir_rx(ir);
-+ if (rx == NULL)
-+ return -ENXIO;
-+
- /*
- * we add ourselves to the task queue before buffer check
- * to avoid losing scan code (in case when queue is awaken somewhere
- * between while condition checking and scheduling)
- */
-- add_wait_queue(&rx->buf.wait_poll, &wait);
-+ add_wait_queue(&rbuf->wait_poll, &wait);
- set_current_state(TASK_INTERRUPTIBLE);
-
- /*
-@@ -771,7 +924,7 @@ static ssize_t read(struct file *filep, char *outbuf, size_t n,
loff_t *ppos)
- * mode and 'copy_to_user' is happy, wait for data.
- */
- while (written < n && ret == 0) {
-- if (lirc_buffer_empty(&rx->buf)) {
-+ if (lirc_buffer_empty(rbuf)) {
- /*
- * According to the read(2) man page, 'written' can be
- * returned as less than 'n', instead of blocking
-@@ -791,20 +944,27 @@ static ssize_t read(struct file *filep, char *outbuf, size_t n,
loff_t *ppos)
- schedule();
- set_current_state(TASK_INTERRUPTIBLE);
- } else {
-- unsigned char buf[rx->buf.chunk_size];
-- lirc_buffer_read(&rx->buf, buf);
-- ret = copy_to_user((void *)outbuf+written, buf,
-- rx->buf.chunk_size);
-- written += rx->buf.chunk_size;
-+ unsigned char buf[rbuf->chunk_size];
-+ m = lirc_buffer_read(rbuf, buf);
-+ if (m == rbuf->chunk_size) {
-+ ret = copy_to_user((void *)outbuf+written, buf,
-+ rbuf->chunk_size);
-+ written += rbuf->chunk_size;
-+ } else {
-+ retries++;
-+ }
-+ if (retries >= 5) {
-+ zilog_error("Buffer read failed!\n");
-+ ret = -EIO;
-+ }
- }
- }
-
-- remove_wait_queue(&rx->buf.wait_poll, &wait);
-+ remove_wait_queue(&rbuf->wait_poll, &wait);
-+ put_ir_rx(rx, false);
- set_current_state(TASK_RUNNING);
-- mutex_unlock(&rx->buf_lock);
-
-- dprintk("read result = %s (%d)\n",
-- ret ? "-EFAULT" : "OK", ret);
-+ dprintk("read result = %d (%s)\n", ret, ret ? "Error" :
"OK");
-
- return ret ? ret : written;
- }
-@@ -931,17 +1091,27 @@ static ssize_t write(struct file *filep, const char *buf, size_t
n,
- loff_t *ppos)
- {
- struct IR *ir = filep->private_data;
-- struct IR_tx *tx = ir->tx;
-+ struct IR_tx *tx;
- size_t i;
- int failures = 0;
-
-- if (tx == NULL)
-- return -ENODEV;
--
- /* Validate user parameters */
- if (n % sizeof(int))
- return -EINVAL;
-
-+ /* Get a struct IR_tx reference */
-+ tx = get_ir_tx(ir);
-+ if (tx == NULL)
-+ return -ENXIO;
-+
-+ /* Ensure our tx->c i2c_client remains valid for the duration */
-+ mutex_lock(&tx->client_lock);
-+ if (tx->c == NULL) {
-+ mutex_unlock(&tx->client_lock);
-+ put_ir_tx(tx, false);
-+ return -ENXIO;
-+ }
-+
- /* Lock i2c bus for the duration */
- mutex_lock(&ir->ir_lock);
-
-@@ -952,11 +1122,24 @@ static ssize_t write(struct file *filep, const char *buf, size_t
n,
-
- if (copy_from_user(&command, buf + i, sizeof(command))) {
- mutex_unlock(&ir->ir_lock);
-+ mutex_unlock(&tx->client_lock);
-+ put_ir_tx(tx, false);
- return -EFAULT;
- }
-
- /* Send boot data first if required */
- if (tx->need_boot == 1) {
-+ /* Make sure we have the 'firmware' loaded, first */
-+ ret = fw_load(tx);
-+ if (ret != 0) {
-+ mutex_unlock(&ir->ir_lock);
-+ mutex_unlock(&tx->client_lock);
-+ put_ir_tx(tx, false);
-+ if (ret != -ENOMEM)
-+ ret = -EIO;
-+ return ret;
-+ }
-+ /* Prep the chip for transmitting codes */
- ret = send_boot_data(tx);
- if (ret == 0)
- tx->need_boot = 0;
-@@ -968,6 +1151,8 @@ static ssize_t write(struct file *filep, const char *buf, size_t n,
- (unsigned)command & 0xFFFF);
- if (ret == -EPROTO) {
- mutex_unlock(&ir->ir_lock);
-+ mutex_unlock(&tx->client_lock);
-+ put_ir_tx(tx, false);
- return ret;
- }
- }
-@@ -985,6 +1170,8 @@ static ssize_t write(struct file *filep, const char *buf, size_t n,
- zilog_error("unable to send to the IR chip "
- "after 3 resets, giving up\n");
- mutex_unlock(&ir->ir_lock);
-+ mutex_unlock(&tx->client_lock);
-+ put_ir_tx(tx, false);
- return ret;
- }
- set_current_state(TASK_UNINTERRUPTIBLE);
-@@ -998,6 +1185,11 @@ static ssize_t write(struct file *filep, const char *buf, size_t
n,
- /* Release i2c bus */
- mutex_unlock(&ir->ir_lock);
-
-+ mutex_unlock(&tx->client_lock);
-+
-+ /* Give back our struct IR_tx reference */
-+ put_ir_tx(tx, false);
-+
- /* All looks good */
- return n;
- }
-@@ -1006,23 +1198,32 @@ static ssize_t write(struct file *filep, const char *buf, size_t
n,
- static unsigned int poll(struct file *filep, poll_table *wait)
- {
- struct IR *ir = filep->private_data;
-- struct IR_rx *rx = ir->rx;
-+ struct IR_rx *rx;
-+ struct lirc_buffer *rbuf = ir->l.rbuf;
- unsigned int ret;
-
- dprintk("poll called\n");
-- if (rx == NULL)
-- return -ENODEV;
--
-- mutex_lock(&rx->buf_lock);
-
-- poll_wait(filep, &rx->buf.wait_poll, wait);
-+ rx = get_ir_rx(ir);
-+ if (rx == NULL) {
-+ /*
-+ * Revisit this, if our poll function ever reports writeable
-+ * status for Tx
-+ */
-+ dprintk("poll result = POLLERR\n");
-+ return POLLERR;
-+ }
-
-- dprintk("poll result = %s\n",
-- lirc_buffer_empty(&rx->buf) ? "0" : "POLLIN|POLLRDNORM");
-+ /*
-+ * Add our lirc_buffer's wait_queue to the poll_table. A wake up on
-+ * that buffer's wait queue indicates we may have a new poll status.
-+ */
-+ poll_wait(filep, &rbuf->wait_poll, wait);
-
-- ret = lirc_buffer_empty(&rx->buf) ? 0 : (POLLIN|POLLRDNORM);
-+ /* Indicate what ops could happen immediately without blocking */
-+ ret = lirc_buffer_empty(rbuf) ? 0 : (POLLIN|POLLRDNORM);
-
-- mutex_unlock(&rx->buf_lock);
-+ dprintk("poll result = %s\n", ret ? "POLLIN|POLLRDNORM" :
"none");
- return ret;
- }
-
-@@ -1030,11 +1231,9 @@ static long ioctl(struct file *filep, unsigned int cmd, unsigned
long arg)
- {
- struct IR *ir = filep->private_data;
- int result;
-- unsigned long mode, features = 0;
-+ unsigned long mode, features;
-
-- features |= LIRC_CAN_SEND_PULSE;
-- if (ir->rx != NULL)
-- features |= LIRC_CAN_REC_LIRCCODE;
-+ features = ir->l.features;
-
- switch (cmd) {
- case LIRC_GET_LENGTH:
-@@ -1061,9 +1260,15 @@ static long ioctl(struct file *filep, unsigned int cmd, unsigned
long arg)
- result = -EINVAL;
- break;
- case LIRC_GET_SEND_MODE:
-+ if (!(features&LIRC_CAN_SEND_MASK))
-+ return -ENOSYS;
-+
- result = put_user(LIRC_MODE_PULSE, (unsigned long *) arg);
- break;
- case LIRC_SET_SEND_MODE:
-+ if (!(features&LIRC_CAN_SEND_MASK))
-+ return -ENOSYS;
-+
- result = get_user(mode, (unsigned long *) arg);
- if (!result && mode != LIRC_MODE_PULSE)
- return -EINVAL;
-@@ -1074,13 +1279,24 @@ static long ioctl(struct file *filep, unsigned int cmd, unsigned
long arg)
- return result;
- }
-
--/* ir_devices_lock must be held */
--static struct IR *find_ir_device_by_minor(unsigned int minor)
-+static struct IR *get_ir_device_by_minor(unsigned int minor)
- {
-- if (minor >= MAX_IRCTL_DEVICES)
-- return NULL;
-+ struct IR *ir;
-+ struct IR *ret = NULL;
-+
-+ mutex_lock(&ir_devices_lock);
-+
-+ if (!list_empty(&ir_devices_list)) {
-+ list_for_each_entry(ir, &ir_devices_list, list) {
-+ if (ir->l.minor == minor) {
-+ ret = get_ir_device(ir, true);
-+ break;
-+ }
-+ }
-+ }
-
-- return ir_devices[minor];
-+ mutex_unlock(&ir_devices_lock);
-+ return ret;
- }
-
- /*
-@@ -1090,31 +1306,20 @@ static struct IR *find_ir_device_by_minor(unsigned int minor)
- static int open(struct inode *node, struct file *filep)
- {
- struct IR *ir;
-- int ret;
- unsigned int minor = MINOR(node->i_rdev);
-
- /* find our IR struct */
-- mutex_lock(&ir_devices_lock);
-- ir = find_ir_device_by_minor(minor);
-- mutex_unlock(&ir_devices_lock);
-+ ir = get_ir_device_by_minor(minor);
-
- if (ir == NULL)
- return -ENODEV;
-
-- /* increment in use count */
-- mutex_lock(&ir->ir_lock);
-- ++ir->open;
-- ret = set_use_inc(ir);
-- if (ret != 0) {
-- --ir->open;
-- mutex_unlock(&ir->ir_lock);
-- return ret;
-- }
-- mutex_unlock(&ir->ir_lock);
-+ atomic_inc(&ir->open_count);
-
- /* stash our IR struct */
- filep->private_data = ir;
-
-+ nonseekable_open(node, filep);
- return 0;
- }
-
-@@ -1128,22 +1333,12 @@ static int close(struct inode *node, struct file *filep)
- return -ENODEV;
- }
-
-- /* decrement in use count */
-- mutex_lock(&ir->ir_lock);
-- --ir->open;
-- set_use_dec(ir);
-- mutex_unlock(&ir->ir_lock);
-+ atomic_dec(&ir->open_count);
-
-+ put_ir_device(ir, false);
- return 0;
- }
-
--static struct lirc_driver lirc_template = {
-- .name = "lirc_zilog",
-- .set_use_inc = set_use_inc,
-- .set_use_dec = set_use_dec,
-- .owner = THIS_MODULE
--};
--
- static int ir_remove(struct i2c_client *client);
- static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id);
-
-@@ -1170,7 +1365,7 @@ static struct i2c_driver driver = {
-
- static const struct file_operations lirc_fops = {
- .owner = THIS_MODULE,
-- .llseek = lseek,
-+ .llseek = no_llseek,
- .read = read,
- .write = write,
- .poll = poll,
-@@ -1182,97 +1377,64 @@ static const struct file_operations lirc_fops = {
- .release = close
- };
-
--static void destroy_rx_kthread(struct IR_rx *rx)
--{
-- /* end up polling thread */
-- if (rx != NULL && !IS_ERR_OR_NULL(rx->task)) {
-- kthread_stop(rx->task);
-- rx->task = NULL;
-- }
--}
-+static struct lirc_driver lirc_template = {
-+ .name = "lirc_zilog",
-+ .minor = -1,
-+ .code_length = 13,
-+ .buffer_size = BUFLEN / 2,
-+ .sample_rate = 0, /* tell lirc_dev to not start its own kthread */
-+ .chunk_size = 2,
-+ .set_use_inc = set_use_inc,
-+ .set_use_dec = set_use_dec,
-+ .fops = &lirc_fops,
-+ .owner = THIS_MODULE,
-+};
-
--/* ir_devices_lock must be held */
--static int add_ir_device(struct IR *ir)
-+static int ir_remove(struct i2c_client *client)
- {
-- int i;
--
-- for (i = 0; i < MAX_IRCTL_DEVICES; i++)
-- if (ir_devices[i] == NULL) {
-- ir_devices[i] = ir;
-- break;
-+ if (strncmp("ir_tx_z8", client->name, 8) == 0) {
-+ struct IR_tx *tx = i2c_get_clientdata(client);
-+ if (tx != NULL) {
-+ mutex_lock(&tx->client_lock);
-+ tx->c = NULL;
-+ mutex_unlock(&tx->client_lock);
-+ put_ir_tx(tx, false);
- }
--
-- return i == MAX_IRCTL_DEVICES ? -ENOMEM : i;
--}
--
--/* ir_devices_lock must be held */
--static void del_ir_device(struct IR *ir)
--{
-- int i;
--
-- for (i = 0; i < MAX_IRCTL_DEVICES; i++)
-- if (ir_devices[i] == ir) {
-- ir_devices[i] = NULL;
-- break;
-+ } else if (strncmp("ir_rx_z8", client->name, 8) == 0) {
-+ struct IR_rx *rx = i2c_get_clientdata(client);
-+ if (rx != NULL) {
-+ mutex_lock(&rx->client_lock);
-+ rx->c = NULL;
-+ mutex_unlock(&rx->client_lock);
-+ put_ir_rx(rx, false);
- }
--}
--
--static int ir_remove(struct i2c_client *client)
--{
-- struct IR *ir = i2c_get_clientdata(client);
--
-- mutex_lock(&ir_devices_lock);
--
-- if (ir == NULL) {
-- /* We destroyed everything when the first client came through */
-- mutex_unlock(&ir_devices_lock);
-- return 0;
- }
--
-- /* Good-bye LIRC */
-- lirc_unregister_driver(ir->l.minor);
--
-- /* Good-bye Rx */
-- destroy_rx_kthread(ir->rx);
-- if (ir->rx != NULL) {
-- if (ir->rx->buf.fifo_initialized)
-- lirc_buffer_free(&ir->rx->buf);
-- i2c_set_clientdata(ir->rx->c, NULL);
-- kfree(ir->rx);
-- }
--
-- /* Good-bye Tx */
-- i2c_set_clientdata(ir->tx->c, NULL);
-- kfree(ir->tx);
--
-- /* Good-bye IR */
-- del_ir_device(ir);
-- kfree(ir);
--
-- mutex_unlock(&ir_devices_lock);
- return 0;
- }
-
-
- /* ir_devices_lock must be held */
--static struct IR *find_ir_device_by_adapter(struct i2c_adapter *adapter)
-+static struct IR *get_ir_device_by_adapter(struct i2c_adapter *adapter)
- {
-- int i;
-- struct IR *ir = NULL;
-+ struct IR *ir;
-
-- for (i = 0; i < MAX_IRCTL_DEVICES; i++)
-- if (ir_devices[i] != NULL &&
-- ir_devices[i]->adapter == adapter) {
-- ir = ir_devices[i];
-- break;
-+ if (list_empty(&ir_devices_list))
-+ return NULL;
-+
-+ list_for_each_entry(ir, &ir_devices_list, list)
-+ if (ir->adapter == adapter) {
-+ get_ir_device(ir, true);
-+ return ir;
- }
-
-- return ir;
-+ return NULL;
- }
-
- static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id)
- {
- struct IR *ir;
-+ struct IR_tx *tx;
-+ struct IR_rx *rx;
- struct i2c_adapter *adap = client->adapter;
- int ret;
- bool tx_probe = false;
-@@ -1296,133 +1458,170 @@ static int ir_probe(struct i2c_client *client, const struct
i2c_device_id *id)
- mutex_lock(&ir_devices_lock);
-
- /* Use a single struct IR instance for both the Rx and Tx functions */
-- ir = find_ir_device_by_adapter(adap);
-+ ir = get_ir_device_by_adapter(adap);
- if (ir == NULL) {
- ir = kzalloc(sizeof(struct IR), GFP_KERNEL);
- if (ir == NULL) {
- ret = -ENOMEM;
- goto out_no_ir;
- }
-+ kref_init(&ir->ref);
-+
- /* store for use in ir_probe() again, and open() later on */
-- ret = add_ir_device(ir);
-- if (ret)
-- goto out_free_ir;
-+ INIT_LIST_HEAD(&ir->list);
-+ list_add_tail(&ir->list, &ir_devices_list);
-
- ir->adapter = adap;
- mutex_init(&ir->ir_lock);
-+ atomic_set(&ir->open_count, 0);
-+ spin_lock_init(&ir->tx_ref_lock);
-+ spin_lock_init(&ir->rx_ref_lock);
-
- /* set lirc_dev stuff */
- memcpy(&ir->l, &lirc_template, sizeof(struct lirc_driver));
-- ir->l.minor = minor; /* module option */
-- ir->l.code_length = 13;
-- ir->l.rbuf = NULL;
-- ir->l.fops = &lirc_fops;
-- ir->l.data = ir;
-- ir->l.dev = &adap->dev;
-- ir->l.sample_rate = 0;
-+ /*
-+ * FIXME this is a pointer reference to us, but no refcount.
-+ *
-+ * This OK for now, since lirc_dev currently won't touch this
-+ * buffer as we provide our own lirc_fops.
-+ *
-+ * Currently our own lirc_fops rely on this ir->l.rbuf pointer
-+ */
-+ ir->l.rbuf = &ir->rbuf;
-+ ir->l.dev = &adap->dev;
-+ ret = lirc_buffer_init(ir->l.rbuf,
-+ ir->l.chunk_size, ir->l.buffer_size);
-+ if (ret)
-+ goto out_put_ir;
- }
-
- if (tx_probe) {
-+ /* Get the IR_rx instance for later, if already allocated */
-+ rx = get_ir_rx(ir);
-+
- /* Set up a struct IR_tx instance */
-- ir->tx = kzalloc(sizeof(struct IR_tx), GFP_KERNEL);
-- if (ir->tx == NULL) {
-+ tx = kzalloc(sizeof(struct IR_tx), GFP_KERNEL);
-+ if (tx == NULL) {
- ret = -ENOMEM;
-- goto out_free_xx;
-+ goto out_put_xx;
- }
--
-- ir->tx->c = client;
-- ir->tx->need_boot = 1;
-- ir->tx->post_tx_ready_poll =
-+ kref_init(&tx->ref);
-+ ir->tx = tx;
-+
-+ ir->l.features |= LIRC_CAN_SEND_PULSE;
-+ mutex_init(&tx->client_lock);
-+ tx->c = client;
-+ tx->need_boot = 1;
-+ tx->post_tx_ready_poll =
- (id->driver_data & ID_FLAG_HDPVR) ? false : true;
-+
-+ /* An ir ref goes to the struct IR_tx instance */
-+ tx->ir = get_ir_device(ir, true);
-+
-+ /* A tx ref goes to the i2c_client */
-+ i2c_set_clientdata(client, get_ir_tx(ir));
-+
-+ /*
-+ * Load the 'firmware'. We do this before registering with
-+ * lirc_dev, so the first firmware load attempt does not happen
-+ * after a open() or write() call on the device.
-+ *
-+ * Failure here is not deemed catastrophic, so the receiver will
-+ * still be usable. Firmware load will be retried in write(),
-+ * if it is needed.
-+ */
-+ fw_load(tx);
-+
-+ /* Proceed only if the Rx client is also ready or not needed */
-+ if (rx == NULL && !tx_only) {
-+ zilog_info("probe of IR Tx on %s (i2c-%d) done. Waiting"
-+ " on IR Rx.\n", adap->name, adap->nr);
-+ goto out_ok;
-+ }
- } else {
-+ /* Get the IR_tx instance for later, if already allocated */
-+ tx = get_ir_tx(ir);
-+
- /* Set up a struct IR_rx instance */
-- ir->rx = kzalloc(sizeof(struct IR_rx), GFP_KERNEL);
-- if (ir->rx == NULL) {
-+ rx = kzalloc(sizeof(struct IR_rx), GFP_KERNEL);
-+ if (rx == NULL) {
- ret = -ENOMEM;
-- goto out_free_xx;
-+ goto out_put_xx;
- }
-+ kref_init(&rx->ref);
-+ ir->rx = rx;
-
-- ret = lirc_buffer_init(&ir->rx->buf, 2, BUFLEN / 2);
-- if (ret)
-- goto out_free_xx;
--
-- mutex_init(&ir->rx->buf_lock);
-- ir->rx->c = client;
-- ir->rx->hdpvr_data_fmt =
-+ ir->l.features |= LIRC_CAN_REC_LIRCCODE;
-+ mutex_init(&rx->client_lock);
-+ rx->c = client;
-+ rx->hdpvr_data_fmt =
- (id->driver_data & ID_FLAG_HDPVR) ? true : false;
-
-- /* set lirc_dev stuff */
-- ir->l.rbuf = &ir->rx->buf;
-- }
--
-- i2c_set_clientdata(client, ir);
-+ /* An ir ref goes to the struct IR_rx instance */
-+ rx->ir = get_ir_device(ir, true);
-
-- /* Proceed only if we have the required Tx and Rx clients ready to go */
-- if (ir->tx == NULL ||
-- (ir->rx == NULL && !tx_only)) {
-- zilog_info("probe of IR %s on %s (i2c-%d) done. Waiting on "
-- "IR %s.\n", tx_probe ? "Tx" : "Rx", adap->name,
-- adap->nr, tx_probe ? "Rx" : "Tx");
-- goto out_ok;
-- }
-+ /* An rx ref goes to the i2c_client */
-+ i2c_set_clientdata(client, get_ir_rx(ir));
-
-- /* initialise RX device */
-- if (ir->rx != NULL) {
-- /* try to fire up polling thread */
-- ir->rx->task = kthread_run(lirc_thread, ir,
-- "zilog-rx-i2c-%d", adap->nr);
-- if (IS_ERR(ir->rx->task)) {
-- ret = PTR_ERR(ir->rx->task);
-+ /*
-+ * Start the polling thread.
-+ * It will only perform an empty loop around schedule_timeout()
-+ * until we register with lirc_dev and the first user open()
-+ */
-+ /* An ir ref goes to the new rx polling kthread */
-+ rx->task = kthread_run(lirc_thread, get_ir_device(ir, true),
-+ "zilog-rx-i2c-%d", adap->nr);
-+ if (IS_ERR(rx->task)) {
-+ ret = PTR_ERR(rx->task);
- zilog_error("%s: could not start IR Rx polling thread"
- "\n", __func__);
-- goto out_free_xx;
-+ /* Failed kthread, so put back the ir ref */
-+ put_ir_device(ir, true);
-+ /* Failure exit, so put back rx ref from i2c_client */
-+ i2c_set_clientdata(client, NULL);
-+ put_ir_rx(rx, true);
-+ ir->l.features &= ~LIRC_CAN_REC_LIRCCODE;
-+ goto out_put_xx;
-+ }
-+
-+ /* Proceed only if the Tx client is also ready */
-+ if (tx == NULL) {
-+ zilog_info("probe of IR Rx on %s (i2c-%d) done. Waiting"
-+ " on IR Tx.\n", adap->name, adap->nr);
-+ goto out_ok;
- }
- }
-
- /* register with lirc */
-+ ir->l.minor = minor; /* module option: user requested minor number */
- ir->l.minor = lirc_register_driver(&ir->l);
- if (ir->l.minor < 0 || ir->l.minor >= MAX_IRCTL_DEVICES) {
- zilog_error("%s: \"minor\" must be between 0 and %d (%d)!\n",
- __func__, MAX_IRCTL_DEVICES-1, ir->l.minor);
- ret = -EBADRQC;
-- goto out_free_thread;
-+ goto out_put_xx;
- }
-+ zilog_info("IR unit on %s (i2c-%d) registered as lirc%d and ready\n",
-+ adap->name, adap->nr, ir->l.minor);
-
-- /*
-- * if we have the tx device, load the 'firmware'. We do this
-- * after registering with lirc as otherwise hotplug seems to take
-- * 10s to create the lirc device.
-- */
-- ret = tx_init(ir->tx);
-- if (ret != 0)
-- goto out_unregister;
--
-- zilog_info("probe of IR %s on %s (i2c-%d) done. IR unit ready.\n",
-- tx_probe ? "Tx" : "Rx", adap->name, adap->nr);
- out_ok:
-+ if (rx != NULL)
-+ put_ir_rx(rx, true);
-+ if (tx != NULL)
-+ put_ir_tx(tx, true);
-+ put_ir_device(ir, true);
-+ zilog_info("probe of IR %s on %s (i2c-%d) done\n",
-+ tx_probe ? "Tx" : "Rx", adap->name, adap->nr);
- mutex_unlock(&ir_devices_lock);
- return 0;
-
--out_unregister:
-- lirc_unregister_driver(ir->l.minor);
--out_free_thread:
-- destroy_rx_kthread(ir->rx);
--out_free_xx:
-- if (ir->rx != NULL) {
-- if (ir->rx->buf.fifo_initialized)
-- lirc_buffer_free(&ir->rx->buf);
-- if (ir->rx->c != NULL)
-- i2c_set_clientdata(ir->rx->c, NULL);
-- kfree(ir->rx);
-- }
-- if (ir->tx != NULL) {
-- if (ir->tx->c != NULL)
-- i2c_set_clientdata(ir->tx->c, NULL);
-- kfree(ir->tx);
-- }
--out_free_ir:
-- del_ir_device(ir);
-- kfree(ir);
-+out_put_xx:
-+ if (rx != NULL)
-+ put_ir_rx(rx, true);
-+ if (tx != NULL)
-+ put_ir_tx(tx, true);
-+out_put_ir:
-+ put_ir_device(ir, true);
- out_no_ir:
- zilog_error("%s: probing IR %s on %s (i2c-%d) failed with %d\n",
- __func__, tx_probe ? "Tx" : "Rx", adap->name, adap->nr,
-@@ -1438,7 +1637,6 @@ static int __init zilog_init(void)
- zilog_notify("Zilog/Hauppauge IR driver initializing\n");
-
- mutex_init(&tx_data_lock);
-- mutex_init(&ir_devices_lock);
-
- request_module("firmware_class");
-
-diff --git a/include/media/rc-map.h b/include/media/rc-map.h
-index d843afc..9184751 100644
---- a/include/media/rc-map.h
-+++ b/include/media/rc-map.h
-@@ -94,7 +94,7 @@ void rc_map_init(void);
- #define RC_MAP_GADMEI_RM008Z "rc-gadmei-rm008z"
- #define RC_MAP_GENIUS_TVGO_A11MCE "rc-genius-tvgo-a11mce"
- #define RC_MAP_GOTVIEW7135 "rc-gotview7135"
--#define RC_MAP_HAUPPAUGE_NEW "rc-hauppauge-new"
-+#define RC_MAP_HAUPPAUGE_NEW "rc-hauppauge"
- #define RC_MAP_IMON_MCE "rc-imon-mce"
- #define RC_MAP_IMON_PAD "rc-imon-pad"
- #define RC_MAP_IODATA_BCTV7E "rc-iodata-bctv7e"
-@@ -125,7 +125,7 @@ void rc_map_init(void);
- #define RC_MAP_PROTEUS_2309 "rc-proteus-2309"
- #define RC_MAP_PURPLETV "rc-purpletv"
- #define RC_MAP_PV951 "rc-pv951"
--#define RC_MAP_RC5_HAUPPAUGE_NEW "rc-rc5-hauppauge-new"
-+#define RC_MAP_HAUPPAUGE "rc-hauppauge"
- #define RC_MAP_RC5_TV "rc-rc5-tv"
- #define RC_MAP_RC6_MCE "rc-rc6-mce"
- #define RC_MAP_REAL_AUDIO_220_32_KEYS "rc-real-audio-220-32-keys"
-diff --git a/include/media/soc_camera.h b/include/media/soc_camera.h
-index 6e96b26..f80b537 100644
---- a/include/media/soc_camera.h
-+++ b/include/media/soc_camera.h
-@@ -30,6 +30,8 @@ struct soc_camera_device {
- struct device *pdev; /* Platform device */
- s32 user_width;
- s32 user_height;
-+ u32 bytesperline; /* for padding, zero if unused */
-+ u32 sizeimage;
- enum v4l2_colorspace colorspace;
- unsigned char iface; /* Host number */
- unsigned char devnum; /* Device number per host */
diff --git a/sources b/sources
index b519133..c8ff5a0 100644
--- a/sources
+++ b/sources
@@ -1,2 +1 @@
-7d471477bfa67546f902da62227fa976 linux-2.6.38.tar.bz2
-c0f416f6a2e916633f697287cc7cb914 patch-2.6.38.8.bz2
+1aab7a741abe08d42e8eccf20de61e05 linux-2.6.39.tar.bz2