mirror of
https://github.com/LibreELEC/LibreELEC.tv.git
synced 2025-07-24 11:16:51 +00:00
remove project 'Cuboxi' for OpenELEC-4.2
Signed-off-by: Stephan Raue <stephan@openelec.tv>
This commit is contained in:
parent
91c6fab179
commit
876ca6a481
@ -1,3 +0,0 @@
|
||||
zImage=/KERNEL
|
||||
bootfile=/KERNEL
|
||||
mmcargs=setenv bootargs 'boot=/dev/mmcblk0p1 disk=/dev/mmcblk0p2 quiet video=mxcfb0:dev=hdmi,1920x1080M@60,if=RGB24,bpp=32 dmfc=3'
|
File diff suppressed because it is too large
Load Diff
@ -1,355 +0,0 @@
|
||||
# Name of the Distro to build (full name, without special characters)
|
||||
DISTRONAME="OpenELEC_Helix"
|
||||
|
||||
# short project description
|
||||
DESCRIPTION="OpenELEC is a fast and userfriendly XBMC Mediacenter distribution."
|
||||
|
||||
# Welcome Message for e.g. SSH Server (up to 5 Lines)
|
||||
GREETING0="##############################################"
|
||||
GREETING1="# OpenELEC - The living room PC for everyone #"
|
||||
GREETING2="# ...... visit http://www.openelec.tv ...... #"
|
||||
GREETING3="##############################################"
|
||||
GREETING4=""
|
||||
|
||||
# Root password to integrate in the target system
|
||||
ROOT_PASSWORD="openelec"
|
||||
|
||||
# The TARGET_CPU variable controls which processor should be targeted for
|
||||
# generated code.
|
||||
case $TARGET_ARCH in
|
||||
i386)
|
||||
# (AMD CPUs) k8 k8-sse3 opteron opteron-sse3 athlon64 athlon64-sse3
|
||||
# athlon-fx athlon-mp athlon-xp athlon-4
|
||||
# athlon-tbird athlon k6-3 k6-2 k6 geode
|
||||
# (Intel CPUs) atom core2 nocona prescott pentium4[m] pentium3[m]
|
||||
# pentium-m pentium2 pentiumpro pentium-mmx pentium
|
||||
# i686 i586 i486 i386
|
||||
# (VIA CPUs) c3 c3-2
|
||||
#
|
||||
TARGET_CPU="atom"
|
||||
;;
|
||||
|
||||
x86_64)
|
||||
# (AMD CPUs) k8 k8-sse3 opteron opteron-sse3 athlon64 athlon64-sse3
|
||||
# athlon-fx amdfam10 barcelona
|
||||
# (Intel CPUs) atom core2 nocona
|
||||
#
|
||||
TARGET_CPU="atom"
|
||||
;;
|
||||
|
||||
arm)
|
||||
# TARGET_CPU:
|
||||
# arm2 arm250 arm3 arm6 arm60 arm600 arm610 arm620 arm7 arm7m arm7d
|
||||
# arm7dm arm7di arm7dmi arm70 arm700 arm700i arm710 arm710c
|
||||
# arm7100 arm720 arm7500 arm7500fe arm7tdmi arm7tdmi-s arm710t
|
||||
# arm720t arm740t strongarm strongarm110 strongarm1100
|
||||
# strongarm1110 arm8 arm810 arm9 arm9e arm920 arm920t arm922t
|
||||
# arm946e-s arm966e-s arm968e-s arm926ej-s arm940t arm9tdmi
|
||||
# arm10tdmi arm1020t arm1026ej-s arm10e arm1020e arm1022e
|
||||
# arm1136j-s arm1136jf-s mpcore mpcorenovfp arm1156t2-s
|
||||
# arm1176jz-s arm1176jzf-s cortex-a8 cortex-a9 cortex-r4
|
||||
# cortex-r4f cortex-m3 cortex-m1 xscale iwmmxt iwmmxt2 ep9312.
|
||||
#
|
||||
TARGET_CPU="cortex-a9"
|
||||
|
||||
# TARGET_FLOAT:
|
||||
# Specifies which floating-point ABI to use. Permissible values are:
|
||||
# soft softfp hard
|
||||
TARGET_FLOAT="hard"
|
||||
|
||||
# TARGET_FPU:
|
||||
# This specifies what floating point hardware (or hardware emulation) is
|
||||
# available on the target. Permissible names are:
|
||||
# fpa fpe2 fpe3 maverick vfp vfpv3 vfpv3-fp16 vfpv3-d16 vfpv3-d16-fp16
|
||||
# vfpv3xd vfpv3xd-fp16 neon neon-fp16 vfpv4 vfpv4-d16 fpv4-sp-d16
|
||||
# neon-vfpv4.
|
||||
TARGET_FPU="neon"
|
||||
;;
|
||||
esac
|
||||
|
||||
# Build optimizations (size/normal)
|
||||
OPTIMIZATIONS="size"
|
||||
|
||||
# Project CFLAGS
|
||||
PROJECT_CFLAGS=""
|
||||
|
||||
# LTO (Link Time Optimization) support
|
||||
LTO_SUPPORT="yes"
|
||||
|
||||
# GOLD (Google Linker) support
|
||||
GOLD_SUPPORT="yes"
|
||||
|
||||
# Bootloader to use (syslinux / u-boot / atv-bootloader / bcm2835-bootloader)
|
||||
BOOTLOADER="u-boot"
|
||||
|
||||
# u-boot version to use (default)
|
||||
UBOOT_VERSION="imx6-cuboxi"
|
||||
|
||||
# Configuration for u-boot
|
||||
UBOOT_CONFIG="mx6_cubox-i_config"
|
||||
|
||||
# Target Configfile for u-boot
|
||||
UBOOT_CONFIGFILE=""
|
||||
|
||||
# Kernel target for u-boot (default 'uImage' if BOOTLOADER=u-boot) (uImage / zImage)
|
||||
KERNEL_UBOOT_TARGET="zImage"
|
||||
|
||||
# Kernel extra targets to build
|
||||
KERNEL_UBOOT_EXTRA_TARGET="imx6q-cubox-i.dtb imx6dl-cubox-i.dtb imx6dl-hummingboard.dtb"
|
||||
|
||||
# Additional kernel make parameters (for example to specify the u-boot loadaddress)
|
||||
KERNEL_MAKE_EXTRACMD=""
|
||||
|
||||
# GCC to use. values can be:
|
||||
# default: default mainline gcc
|
||||
GCC_VERSION="4.7"
|
||||
|
||||
# Kernel to use. values can be:
|
||||
# default: default mainline kernel
|
||||
LINUX="imx6"
|
||||
|
||||
# use linux-next (latest rc) instead latest released version
|
||||
LINUX_NEXT="no"
|
||||
|
||||
# SquashFS compression method (gzip / lzo / xz)
|
||||
SQUASHFS_COMPRESSION="gzip"
|
||||
|
||||
# Mediacenter to use (xbmc / no)
|
||||
MEDIACENTER="xbmc-master"
|
||||
|
||||
# Skins to install (Confluence)
|
||||
# Space separated list is supported,
|
||||
# e.g. SKINS="Confluence"
|
||||
SKINS="Confluence"
|
||||
|
||||
# Default Skin (Confluence)
|
||||
SKIN_DEFAULT="Confluence"
|
||||
|
||||
# install extra subtitle Fonts for XBMC (yes / no)
|
||||
XBMC_EXTRA_FONTS="yes"
|
||||
|
||||
# build and install 'RSXS' Screensaver (yes / no)
|
||||
XBMC_SCR_RSXS="no"
|
||||
|
||||
# build and install 'ProjectM' Visualization (yes / no)
|
||||
XBMC_VIS_PROJECTM="no"
|
||||
|
||||
# build and install 'GOOM' Visualization (yes / no)
|
||||
XBMC_VIS_GOOM="no"
|
||||
|
||||
# build and install 'Waveform' Visualization (yes / no)
|
||||
XBMC_VIS_WAVEFORM="yes"
|
||||
|
||||
# build and install 'Spectrum' Visualization (yes / no)
|
||||
XBMC_VIS_SPECTRUM="yes"
|
||||
|
||||
# build and install 'FishBMC' Visualization (yes / no)
|
||||
# does not work on RPi
|
||||
XBMC_VIS_FISHBMC="no"
|
||||
|
||||
# build and install ALSA Audio support (yes / no)
|
||||
ALSA_SUPPORT="yes"
|
||||
|
||||
# build and install PulseAudio support (yes / no)
|
||||
PULSEAUDIO_SUPPORT="no"
|
||||
|
||||
# build and install espeak support (yes / no)
|
||||
ESPEAK_SUPPORT="yes"
|
||||
|
||||
# build and install with non-free support
|
||||
# (RAR compression support in XBMC) (yes / no)
|
||||
NONFREE_SUPPORT="yes"
|
||||
|
||||
# build and install with DVDCSS support
|
||||
# (DVD decryption support in XBMC) (yes / no)
|
||||
DVDCSS_SUPPORT="yes"
|
||||
|
||||
# build and install with LAME cdrip encoder support
|
||||
ENCODER_LAME="yes"
|
||||
|
||||
# build and install with BluRay support (yes / no)
|
||||
BLURAY_SUPPORT="yes"
|
||||
|
||||
# additional drivers to install:
|
||||
# for a list of additinoal drivers see packages/linux-drivers
|
||||
# Space separated list is supported,
|
||||
# e.g. ADDITIONAL_DRIVERS="DRIVER1 DRIVER2"
|
||||
ADDITIONAL_DRIVERS="RTL8192CU RTL8192DU RTL8188EU dvbhdhomerun"
|
||||
|
||||
# build and install bluetooth support (yes / no)
|
||||
BLUETOOTH_SUPPORT="yes"
|
||||
|
||||
# build and install with XBMC webfrontend (yes / no)
|
||||
WEBSERVER="yes"
|
||||
|
||||
# build and install Avahi (Zeroconf) daemon (yes / no)
|
||||
AVAHI_DAEMON="yes"
|
||||
|
||||
# build with UPnP support (yes / no)
|
||||
UPNP_SUPPORT="yes"
|
||||
|
||||
# build with MySQL support (yes / no)
|
||||
MYSQL_SUPPORT="yes"
|
||||
|
||||
# build xbmc with sshlib support (yes / no)
|
||||
SSHLIB_SUPPORT="yes"
|
||||
|
||||
# build xbmc with optical drive support (yes / no)
|
||||
OPTICAL_DRIVE_SUPPORT="yes"
|
||||
|
||||
# build with AirPlay support (stream videos from iDevices to XBMC) (yes / no)
|
||||
AIRPLAY_SUPPORT="yes"
|
||||
|
||||
# build with AirTunes support (stream music from iDevices to XBMC) (yes / no)
|
||||
AIRTUNES_SUPPORT="yes"
|
||||
|
||||
# build with libnfs support (mounting nfs shares with XBMC) (yes / no)
|
||||
NFS_SUPPORT="yes"
|
||||
|
||||
# build with afpfs-ng support (mounting AFP shares with XBMC) (yes / no)
|
||||
AFP_SUPPORT="yes"
|
||||
|
||||
# build and install Samba Client support (yes / no)
|
||||
SAMBA_SUPPORT="yes"
|
||||
|
||||
# build and install Samba Server (yes / no)
|
||||
SAMBA_SERVER="yes"
|
||||
|
||||
# build and install SFTP Server (yes / no)
|
||||
SFTP_SERVER="yes"
|
||||
|
||||
# build and install PPP support (yes / no)
|
||||
PPTP_SUPPORT="yes"
|
||||
|
||||
# build and install OpenVPN support (yes / no)
|
||||
OPENVPN_SUPPORT="yes"
|
||||
|
||||
# build and install diskmounter support (udevil)
|
||||
# this service provide auto mounting support for external drives in the
|
||||
# mediacenter also automount internally drives at boottime via udev (yes / no)
|
||||
UDEVIL="yes"
|
||||
|
||||
# build and install exFAT fuse support (yes / no)
|
||||
EXFAT="yes"
|
||||
|
||||
# build and install NTFS-3G fuse support (yes / no)
|
||||
NTFS3G="yes"
|
||||
|
||||
# build and install hfs filesystem utilities (yes / no)
|
||||
HFSTOOLS="yes"
|
||||
|
||||
# OpenGL(X) implementation to use (no / Mesa)
|
||||
OPENGL="no"
|
||||
|
||||
# OpenGL-ES implementation to use (no / bcm2835-driver / gpu-viv-bin-mx6q)
|
||||
OPENGLES="gpu-viv-bin-mx6q"
|
||||
|
||||
# Windowmanager to use (ratpoison / fluxbox / none)
|
||||
WINDOWMANAGER="none"
|
||||
|
||||
# include uvesafb support (yes / no)
|
||||
UVESAFB_SUPPORT="no"
|
||||
|
||||
# Displayserver to use (x11 / no)
|
||||
DISPLAYSERVER="no"
|
||||
|
||||
# Xorg Graphic drivers to use (all / i915,i965,r200,r300,r600,nvidia,nouveau)
|
||||
# Space separated list is supported,
|
||||
# e.g. GRAPHIC_DRIVERS="i915 i965 r300 r600 radeonsi nvidia nouveau"
|
||||
GRAPHIC_DRIVERS=""
|
||||
|
||||
# XBMC Player implementation to use (default / bcm2835-driver)
|
||||
XBMCPLAYER_DRIVER="libfslvpuwrap"
|
||||
|
||||
# Use VDPAU video acceleration (needs nVidia driver and a supported card)
|
||||
VDPAU="no"
|
||||
|
||||
# Use VAAPI video acceleration (needs intel i965 driver and a supported card)
|
||||
VAAPI="no"
|
||||
|
||||
# Use Broadcom CrystalHD Decoder Card for video acceleration
|
||||
# (needs Kernelsupport for Broadcom Decoder Card and a supported card)
|
||||
CRYSTALHD="no"
|
||||
|
||||
# build and install remote support (yes / no)
|
||||
REMOTE_SUPPORT="yes"
|
||||
|
||||
# build and install ATV IR remote support (yes / no)
|
||||
ATVCLIENT_SUPPORT="no"
|
||||
|
||||
# build and install IRServer IR/LCD support (yes / no)
|
||||
IRSERVER_SUPPORT="no"
|
||||
|
||||
# build and install Joystick support (yes / no)
|
||||
JOYSTICK_SUPPORT="yes"
|
||||
|
||||
# build and install CEC adapter support (yes / no)
|
||||
CEC_SUPPORT="yes"
|
||||
|
||||
# build and install iSCSI support - iscsistart (yes / no)
|
||||
ISCSI_SUPPORT="yes"
|
||||
|
||||
# LCD driver to Use - Possible drivers are ( Comma seperated:
|
||||
# bayrad,CFontz,CFontz633,CFontzPacket,curses,CwLnx,dm140,
|
||||
# ea65,EyeboxOne,g15,glcdlib,glk,hd44780,i2500vfd,
|
||||
# icp_a106,imon,imonlcd,IOWarrior,irman,irtrans,
|
||||
# joy,lb216,lcdm001,lcterm,lirc,lis,MD8800,mdm166a,
|
||||
# ms6931,mtc_s16209x,MtxOrb,mx5000,NoritakeVFD,
|
||||
# picolcd,pyramid,sed1330,sed1520,serialPOS,
|
||||
# serialVFD,shuttleVFD,sli,stv5730,SureElec,svga,vlsys_m428
|
||||
# 'all' compiles all drivers;
|
||||
# 'all,!xxx,!yyy' de-selects previously selected drivers
|
||||
# "none" for disable LCD support
|
||||
LCD_DRIVER="irtrans,imon,imonlcd,mdm166a,MtxOrb,lis,dm140,hd44780,CFontz,SureElec,vlsys_m428"
|
||||
|
||||
# Modules to install in initramfs for early boot
|
||||
INITRAMFS_MODULES=""
|
||||
|
||||
# additional Firmware to use (dvb-firmware, misc-firmware, wlan-firmware)
|
||||
# Space separated list is supported,
|
||||
# e.g. FIRMWARE="dvb-firmware misc-firmware wlan-firmware"
|
||||
FIRMWARE="misc-firmware wlan-firmware dvb-firmware"
|
||||
|
||||
# build with lm_sensors hardware monitoring support (yes / no)
|
||||
SENSOR_SUPPORT="yes"
|
||||
|
||||
# build with swap support (yes / no)
|
||||
SWAP_SUPPORT="no"
|
||||
|
||||
# swap support enabled per default (yes / no)
|
||||
SWAP_ENABLED_DEFAULT="no"
|
||||
|
||||
# swapfile size if SWAP_SUPPORT=yes in MB
|
||||
SWAPFILESIZE="128"
|
||||
|
||||
# build with installer (yes / no)
|
||||
INSTALLER_SUPPORT="no"
|
||||
|
||||
# Testpackages for development (yes / no)
|
||||
TESTING="no"
|
||||
|
||||
# OEM packages for OEM's (yes / no)
|
||||
OEM_SUPPORT="no"
|
||||
|
||||
# build and install nano text editor (yes / no)
|
||||
NANO_EDITOR="yes"
|
||||
|
||||
# cron support (yes / no)
|
||||
CRON_SUPPORT="yes"
|
||||
|
||||
# Perf support in development builds (yes / no)
|
||||
PERF_SUPPORT="yes"
|
||||
|
||||
# Coreboot support (yes / no)
|
||||
COREBOOT="no"
|
||||
|
||||
# Distribution Specific source location
|
||||
DISTRO_MIRROR="http://sources.openelec.tv/mirror"
|
||||
DISTRO_SRC="http://sources.openelec.tv/$OPENELEC_VERSION"
|
||||
|
||||
# Addon Server Url
|
||||
ADDON_SERVER_URL="http://addons.openelec.tv"
|
||||
|
||||
# set the addon dirs
|
||||
ADDON_PATH="$ADDON_VERSION/$PROJECT/$TARGET_ARCH"
|
||||
ADDON_URL="$ADDON_SERVER_URL/$ADDON_PATH"
|
@ -1,817 +0,0 @@
|
||||
From 4cf83161dbedfa2d3487841a1bfec4e38fa6939b Mon Sep 17 00:00:00 2001
|
||||
From: wolfgar <stephan.rafin@laposte.net>
|
||||
Date: Thu, 13 Mar 2014 16:03:58 +0100
|
||||
Subject: [PATCH] Add iMX6 support Requires specific kernel driver. Check
|
||||
http://stephan-rafin.net/blog/2013/09/30/i-mx6-cec/
|
||||
|
||||
---
|
||||
configure.ac | 19 ++
|
||||
include/cectypes.h | 14 +-
|
||||
src/lib/CECTypeUtils.h | 2 +
|
||||
src/lib/Makefile.am | 5 +
|
||||
src/lib/adapter/AdapterFactory.cpp | 29 ++-
|
||||
src/lib/adapter/IMX/AdapterMessageQueue.h | 134 ++++++++++
|
||||
src/lib/adapter/IMX/IMXCECAdapterCommunication.cpp | 279 +++++++++++++++++++++
|
||||
src/lib/adapter/IMX/IMXCECAdapterCommunication.h | 114 +++++++++
|
||||
src/lib/adapter/IMX/IMXCECAdapterDetection.cpp | 42 ++++
|
||||
src/lib/adapter/IMX/IMXCECAdapterDetection.h | 36 +++
|
||||
10 files changed, 671 insertions(+), 3 deletions(-)
|
||||
create mode 100644 src/lib/adapter/IMX/AdapterMessageQueue.h
|
||||
create mode 100644 src/lib/adapter/IMX/IMXCECAdapterCommunication.cpp
|
||||
create mode 100644 src/lib/adapter/IMX/IMXCECAdapterCommunication.h
|
||||
create mode 100644 src/lib/adapter/IMX/IMXCECAdapterDetection.cpp
|
||||
create mode 100644 src/lib/adapter/IMX/IMXCECAdapterDetection.h
|
||||
|
||||
diff --git a/configure.ac b/configure.ac
|
||||
index 510d851..923d7e5 100644
|
||||
--- a/configure.ac
|
||||
+++ b/configure.ac
|
||||
@@ -93,6 +93,14 @@ if test "x$use_rpi" != "xno"; then
|
||||
esac
|
||||
fi
|
||||
|
||||
+## i.MX6 support
|
||||
+AC_ARG_ENABLE([imx6],
|
||||
+ [AS_HELP_STRING([--enable-imx6],
|
||||
+ [enable support for freescale i.MX6 (default is no)])],
|
||||
+ [use_imx6=$enableval],
|
||||
+ [use_imx6=no])
|
||||
+
|
||||
+
|
||||
## add the top dir and include to the include path, so we can include config.h and cec.h
|
||||
CPPFLAGS="$CPPFLAGS -I\$(abs_top_srcdir)/src -I\$(abs_top_srcdir)/include"
|
||||
|
||||
@@ -270,6 +278,17 @@ else
|
||||
features="$features\n TDA995x support :\t\t\tno"
|
||||
fi
|
||||
|
||||
+## mark i.MX6 support as available
|
||||
+if test "x$use_imx6" != "xno"; then
|
||||
+ AC_DEFINE([HAVE_IMX_API],[1],[Define to 1 to include i.MX6 support])
|
||||
+ AM_CONDITIONAL(USE_IMX_API, true)
|
||||
+ features="$features\n i.MX6 support :\t\t\tyes"
|
||||
+ LIB_INFO="$LIB_INFO 'i.MX6'"
|
||||
+else
|
||||
+ AM_CONDITIONAL(USE_IMX_API, false)
|
||||
+ features="$features\n i.MX6 support :\t\t\tno"
|
||||
+fi
|
||||
+
|
||||
## check if our build system is complete
|
||||
AC_CHECK_HEADER(algorithm,,AC_MSG_ERROR($msg_required_header_missing))
|
||||
AC_CHECK_HEADER(ctype.h,,AC_MSG_ERROR($msg_required_header_missing))
|
||||
diff --git a/include/cectypes.h b/include/cectypes.h
|
||||
index 9f86253..7fabf00 100644
|
||||
--- a/include/cectypes.h
|
||||
+++ b/include/cectypes.h
|
||||
@@ -295,6 +295,17 @@ namespace CEC {
|
||||
#define CEC_TDA995x_VIRTUAL_COM "CuBox"
|
||||
|
||||
/*!
|
||||
+ * the path to use for the i.MX CEC wire
|
||||
+ */
|
||||
+#define CEC_IMX_PATH "/dev/mxc_hdmi_cec"
|
||||
+
|
||||
+/*!
|
||||
+ * the name of the virtual COM port to use for the i.MX CEC wire
|
||||
+ */
|
||||
+#define CEC_IMX_VIRTUAL_COM "i.MX"
|
||||
+
|
||||
+
|
||||
+/*!
|
||||
* Mimimum client version
|
||||
*/
|
||||
#define CEC_MIN_LIB_VERSION 2
|
||||
@@ -858,7 +869,8 @@ typedef enum cec_adapter_type
|
||||
ADAPTERTYPE_P8_EXTERNAL = 0x1,
|
||||
ADAPTERTYPE_P8_DAUGHTERBOARD = 0x2,
|
||||
ADAPTERTYPE_RPI = 0x100,
|
||||
- ADAPTERTYPE_TDA995x = 0x200
|
||||
+ ADAPTERTYPE_TDA995x = 0x200,
|
||||
+ ADAPTERTYPE_IMX = 0x300,
|
||||
} cec_adapter_type;
|
||||
|
||||
typedef struct cec_menu_language
|
||||
diff --git a/src/lib/CECTypeUtils.h b/src/lib/CECTypeUtils.h
|
||||
index dc4e5f1..1cf7ef1 100644
|
||||
--- a/src/lib/CECTypeUtils.h
|
||||
+++ b/src/lib/CECTypeUtils.h
|
||||
@@ -858,6 +858,8 @@ namespace CEC
|
||||
return "Raspberry Pi";
|
||||
case ADAPTERTYPE_TDA995x:
|
||||
return "TDA995x";
|
||||
+ case ADAPTERTYPE_IMX:
|
||||
+ return "i.MX";
|
||||
default:
|
||||
return "unknown";
|
||||
}
|
||||
diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am
|
||||
index 9117d8e..6788303 100644
|
||||
--- a/src/lib/Makefile.am
|
||||
+++ b/src/lib/Makefile.am
|
||||
@@ -59,5 +59,10 @@ libcec_la_SOURCES += adapter/TDA995x/TDA995xCECAdapterDetection.cpp \
|
||||
adapter/TDA995x/TDA995xCECAdapterCommunication.cpp
|
||||
endif
|
||||
|
||||
+## i.MX6 support
|
||||
+if USE_IMX_API
|
||||
+libcec_la_SOURCES += adapter/IMX/IMXCECAdapterDetection.cpp \
|
||||
+ adapter/IMX/IMXCECAdapterCommunication.cpp
|
||||
+endif
|
||||
|
||||
libcec_la_LDFLAGS = @LIBS_LIBCEC@ -version-info @VERSION@
|
||||
diff --git a/src/lib/adapter/AdapterFactory.cpp b/src/lib/adapter/AdapterFactory.cpp
|
||||
index 42cdd0b..576589f 100644
|
||||
--- a/src/lib/adapter/AdapterFactory.cpp
|
||||
+++ b/src/lib/adapter/AdapterFactory.cpp
|
||||
@@ -52,6 +52,11 @@
|
||||
#include "TDA995x/TDA995xCECAdapterCommunication.h"
|
||||
#endif
|
||||
|
||||
+#if defined(HAVE_IMX_API)
|
||||
+#include "IMX/IMXCECAdapterDetection.h"
|
||||
+#include "IMX/IMXCECAdapterCommunication.h"
|
||||
+#endif
|
||||
+
|
||||
using namespace std;
|
||||
using namespace CEC;
|
||||
|
||||
@@ -109,7 +114,22 @@ int8_t CAdapterFactory::DetectAdapters(cec_adapter_descriptor *deviceList, uint8
|
||||
}
|
||||
#endif
|
||||
|
||||
-#if !defined(HAVE_RPI_API) && !defined(HAVE_P8_USB) && !defined(HAVE_TDA995X_API)
|
||||
+
|
||||
+#if defined(HAVE_IMX_API)
|
||||
+ if (iAdaptersFound < iBufSize && CIMXCECAdapterDetection::FindAdapter() &&
|
||||
+ (!strDevicePath || !strcmp(strDevicePath, CEC_IMX_VIRTUAL_COM)))
|
||||
+ {
|
||||
+ snprintf(deviceList[iAdaptersFound].strComPath, sizeof(deviceList[iAdaptersFound].strComPath), CEC_IMX_PATH);
|
||||
+ snprintf(deviceList[iAdaptersFound].strComName, sizeof(deviceList[iAdaptersFound].strComName), CEC_IMX_VIRTUAL_COM);
|
||||
+ deviceList[iAdaptersFound].iVendorId = IMX_ADAPTER_VID;
|
||||
+ deviceList[iAdaptersFound].iProductId = IMX_ADAPTER_PID;
|
||||
+ deviceList[iAdaptersFound].adapterType = ADAPTERTYPE_IMX;
|
||||
+ iAdaptersFound++;
|
||||
+ }
|
||||
+#endif
|
||||
+
|
||||
+
|
||||
+#if !defined(HAVE_RPI_API) && !defined(HAVE_P8_USB) && !defined(HAVE_TDA995X_API) && !defined(HAVE_IMX_API)
|
||||
#error "libCEC doesn't have support for any type of adapter. please check your build system or configuration"
|
||||
#endif
|
||||
|
||||
@@ -128,11 +148,16 @@ IAdapterCommunication *CAdapterFactory::GetInstance(const char *strPort, uint16_
|
||||
return new CRPiCECAdapterCommunication(m_lib->m_cec);
|
||||
#endif
|
||||
|
||||
+#if defined(HAVE_IMX_API)
|
||||
+ if (!strcmp(strPort, CEC_IMX_VIRTUAL_COM))
|
||||
+ return new CIMXCECAdapterCommunication(m_lib->m_cec);
|
||||
+#endif
|
||||
+
|
||||
#if defined(HAVE_P8_USB)
|
||||
return new CUSBCECAdapterCommunication(m_lib->m_cec, strPort, iBaudRate);
|
||||
#endif
|
||||
|
||||
-#if !defined(HAVE_RPI_API) && !defined(HAVE_P8_USB) && !defined(HAVE_TDA995X_API)
|
||||
+#if !defined(HAVE_RPI_API) && !defined(HAVE_P8_USB) && !defined(HAVE_TDA995X_API) && !defined(HAVE_IMX_API)
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
diff --git a/src/lib/adapter/IMX/AdapterMessageQueue.h b/src/lib/adapter/IMX/AdapterMessageQueue.h
|
||||
new file mode 100644
|
||||
index 0000000..c8bcf71
|
||||
--- /dev/null
|
||||
+++ b/src/lib/adapter/IMX/AdapterMessageQueue.h
|
||||
@@ -0,0 +1,134 @@
|
||||
+#pragma once
|
||||
+/*
|
||||
+ * This file is part of the libCEC(R) library.
|
||||
+ *
|
||||
+ * libCEC(R) is Copyright (C) 2011-2013 Pulse-Eight Limited. All rights reserved.
|
||||
+ * libCEC(R) is an original work, containing original code.
|
||||
+ *
|
||||
+ * libCEC(R) is a trademark of Pulse-Eight Limited.
|
||||
+ *
|
||||
+ * This program is dual-licensed; 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.
|
||||
+ *
|
||||
+ *
|
||||
+ * Alternatively, you can license this library under a commercial license,
|
||||
+ * please contact Pulse-Eight Licensing for more information.
|
||||
+ *
|
||||
+ * For more information contact:
|
||||
+ * Pulse-Eight Licensing <license@pulse-eight.com>
|
||||
+ * http://www.pulse-eight.com/
|
||||
+ * http://www.pulse-eight.net/
|
||||
+ */
|
||||
+
|
||||
+#include "lib/platform/threads/mutex.h"
|
||||
+
|
||||
+namespace CEC
|
||||
+{
|
||||
+ using namespace PLATFORM;
|
||||
+
|
||||
+ class CAdapterMessageQueueEntry
|
||||
+ {
|
||||
+ public:
|
||||
+ CAdapterMessageQueueEntry(const cec_command &command)
|
||||
+ : m_bWaiting(true), m_retval((uint32_t)-1), m_bSucceeded(false)
|
||||
+ {
|
||||
+ m_hash = hashValue(
|
||||
+ uint32_t(command.opcode_set ? command.opcode : CEC_OPCODE_NONE),
|
||||
+ command.initiator, command.destination);
|
||||
+ }
|
||||
+
|
||||
+ virtual ~CAdapterMessageQueueEntry(void) {}
|
||||
+
|
||||
+ /*!
|
||||
+ * @brief Query result from worker thread
|
||||
+ */
|
||||
+ uint32_t Result() const
|
||||
+ {
|
||||
+ return m_retval;
|
||||
+ }
|
||||
+
|
||||
+ /*!
|
||||
+ * @brief Signal waiting threads
|
||||
+ */
|
||||
+ void Broadcast(void)
|
||||
+ {
|
||||
+ CLockObject lock(m_mutex);
|
||||
+ m_condition.Broadcast();
|
||||
+ }
|
||||
+
|
||||
+ /*!
|
||||
+ * @brief Signal waiting thread(s) when message matches this entry
|
||||
+ */
|
||||
+ bool CheckMatch(uint32_t opcode, cec_logical_address initiator,
|
||||
+ cec_logical_address destination, uint32_t response)
|
||||
+ {
|
||||
+ uint32_t hash = hashValue(opcode, initiator, destination);
|
||||
+
|
||||
+ if (hash == m_hash)
|
||||
+ {
|
||||
+ CLockObject lock(m_mutex);
|
||||
+
|
||||
+ m_retval = response;
|
||||
+ m_bSucceeded = true;
|
||||
+ m_condition.Signal();
|
||||
+ return true;
|
||||
+ }
|
||||
+
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ /*!
|
||||
+ * @brief Wait for a response to this command.
|
||||
+ * @param iTimeout The timeout to use while waiting.
|
||||
+ * @return True when a response was received before the timeout passed, false otherwise.
|
||||
+ */
|
||||
+ bool Wait(uint32_t iTimeout)
|
||||
+ {
|
||||
+ CLockObject lock(m_mutex);
|
||||
+
|
||||
+ bool bReturn = m_bSucceeded ? true : m_condition.Wait(m_mutex, m_bSucceeded, iTimeout);
|
||||
+ m_bWaiting = false;
|
||||
+ return bReturn;
|
||||
+ }
|
||||
+
|
||||
+ /*!
|
||||
+ * @return True while a thread is waiting for a signal or isn't waiting yet, false otherwise.
|
||||
+ */
|
||||
+ bool IsWaiting(void)
|
||||
+ {
|
||||
+ CLockObject lock(m_mutex);
|
||||
+ return m_bWaiting;
|
||||
+ }
|
||||
+
|
||||
+ /*!
|
||||
+ * @return Hash value for given cec_command
|
||||
+ */
|
||||
+ static uint32_t hashValue(uint32_t opcode,
|
||||
+ cec_logical_address initiator,
|
||||
+ cec_logical_address destination)
|
||||
+ {
|
||||
+ return 1 | ((uint32_t)initiator << 8) |
|
||||
+ ((uint32_t)destination << 16) | ((uint32_t)opcode << 16);
|
||||
+ }
|
||||
+
|
||||
+ private:
|
||||
+ bool m_bWaiting; /**< true while a thread is waiting or when it hasn't started waiting yet */
|
||||
+ PLATFORM::CCondition<bool> m_condition; /**< the condition to wait on */
|
||||
+ PLATFORM::CMutex m_mutex; /**< mutex for changes to this class */
|
||||
+ uint32_t m_hash;
|
||||
+ uint32_t m_retval;
|
||||
+ bool m_bSucceeded;
|
||||
+ };
|
||||
+
|
||||
+};
|
||||
diff --git a/src/lib/adapter/IMX/IMXCECAdapterCommunication.cpp b/src/lib/adapter/IMX/IMXCECAdapterCommunication.cpp
|
||||
new file mode 100644
|
||||
index 0000000..54e5662
|
||||
--- /dev/null
|
||||
+++ b/src/lib/adapter/IMX/IMXCECAdapterCommunication.cpp
|
||||
@@ -0,0 +1,279 @@
|
||||
+/*
|
||||
+ * This file is part of the libCEC(R) library.
|
||||
+ *
|
||||
+ * libCEC(R) is Copyright (C) 2011-2013 Pulse-Eight Limited. All rights reserved.
|
||||
+ * libCEC(R) is an original work, containing original code.
|
||||
+ *
|
||||
+ * libCEC(R) is a trademark of Pulse-Eight Limited.
|
||||
+ *
|
||||
+ * IMX adpater port is Copyright (C) 2013 by Stephan Rafin
|
||||
+ *
|
||||
+ * You can redistribute this file 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 "env.h"
|
||||
+
|
||||
+#if defined(HAVE_IMX_API)
|
||||
+#include "IMXCECAdapterCommunication.h"
|
||||
+
|
||||
+#include "lib/CECTypeUtils.h"
|
||||
+#include "lib/LibCEC.h"
|
||||
+#include "lib/platform/sockets/cdevsocket.h"
|
||||
+#include "lib/platform/util/StdString.h"
|
||||
+#include "lib/platform/util/buffer.h"
|
||||
+
|
||||
+/*
|
||||
+ * Ioctl definitions from kernel header
|
||||
+ */
|
||||
+#define HDMICEC_IOC_MAGIC 'H'
|
||||
+#define HDMICEC_IOC_SETLOGICALADDRESS _IOW(HDMICEC_IOC_MAGIC, 1, unsigned char)
|
||||
+#define HDMICEC_IOC_STARTDEVICE _IO(HDMICEC_IOC_MAGIC, 2)
|
||||
+#define HDMICEC_IOC_STOPDEVICE _IO(HDMICEC_IOC_MAGIC, 3)
|
||||
+#define HDMICEC_IOC_GETPHYADDRESS _IOR(HDMICEC_IOC_MAGIC, 4, unsigned char[4])
|
||||
+
|
||||
+#define MAX_CEC_MESSAGE_LEN 17
|
||||
+
|
||||
+#define MESSAGE_TYPE_RECEIVE_SUCCESS 1
|
||||
+#define MESSAGE_TYPE_NOACK 2
|
||||
+#define MESSAGE_TYPE_DISCONNECTED 3
|
||||
+#define MESSAGE_TYPE_CONNECTED 4
|
||||
+#define MESSAGE_TYPE_SEND_SUCCESS 5
|
||||
+
|
||||
+typedef struct hdmi_cec_event{
|
||||
+ int event_type;
|
||||
+ int msg_len;
|
||||
+ unsigned char msg[MAX_CEC_MESSAGE_LEN];
|
||||
+}hdmi_cec_event;
|
||||
+
|
||||
+
|
||||
+using namespace std;
|
||||
+using namespace CEC;
|
||||
+using namespace PLATFORM;
|
||||
+
|
||||
+#include "AdapterMessageQueue.h"
|
||||
+
|
||||
+#define LIB_CEC m_callback->GetLib()
|
||||
+
|
||||
+// these are defined in nxp private header file
|
||||
+#define CEC_MSG_SUCCESS 0x00 /*Message transmisson Succeed*/
|
||||
+#define CEC_CSP_OFF_STATE 0x80 /*CSP in Off State*/
|
||||
+#define CEC_BAD_REQ_SERVICE 0x81 /*Bad .req service*/
|
||||
+#define CEC_MSG_FAIL_UNABLE_TO_ACCESS 0x82 /*Message transmisson failed: Unable to access CEC line*/
|
||||
+#define CEC_MSG_FAIL_ARBITRATION_ERROR 0x83 /*Message transmisson failed: Arbitration error*/
|
||||
+#define CEC_MSG_FAIL_BIT_TIMMING_ERROR 0x84 /*Message transmisson failed: Bit timming error*/
|
||||
+#define CEC_MSG_FAIL_DEST_NOT_ACK 0x85 /*Message transmisson failed: Destination Address not aknowledged*/
|
||||
+#define CEC_MSG_FAIL_DATA_NOT_ACK 0x86 /*Message transmisson failed: Databyte not acknowledged*/
|
||||
+
|
||||
+
|
||||
+CIMXCECAdapterCommunication::CIMXCECAdapterCommunication(IAdapterCommunicationCallback *callback) :
|
||||
+ IAdapterCommunication(callback)/*,
|
||||
+ m_bLogicalAddressChanged(false)*/
|
||||
+{
|
||||
+ CLockObject lock(m_mutex);
|
||||
+
|
||||
+ m_iNextMessage = 0;
|
||||
+ //m_logicalAddresses.Clear();
|
||||
+ m_logicalAddress = CECDEVICE_UNKNOWN;
|
||||
+ m_dev = new CCDevSocket(CEC_IMX_PATH);
|
||||
+}
|
||||
+
|
||||
+CIMXCECAdapterCommunication::~CIMXCECAdapterCommunication(void)
|
||||
+{
|
||||
+ Close();
|
||||
+
|
||||
+ CLockObject lock(m_mutex);
|
||||
+ delete m_dev;
|
||||
+ m_dev = 0;
|
||||
+}
|
||||
+
|
||||
+bool CIMXCECAdapterCommunication::IsOpen(void)
|
||||
+{
|
||||
+ return IsInitialised() && m_dev->IsOpen();
|
||||
+}
|
||||
+
|
||||
+bool CIMXCECAdapterCommunication::Open(uint32_t iTimeoutMs, bool UNUSED(bSkipChecks), bool bStartListening)
|
||||
+{
|
||||
+ if (m_dev->Open(iTimeoutMs))
|
||||
+ {
|
||||
+ if (!bStartListening || CreateThread()) {
|
||||
+ if (m_dev->Ioctl(HDMICEC_IOC_STARTDEVICE, NULL) != 0) {
|
||||
+ LIB_CEC->AddLog(CEC_LOG_ERROR, "%s: Unable to start device\n", __func__);
|
||||
+ }
|
||||
+ return true;
|
||||
+ }
|
||||
+ m_dev->Close();
|
||||
+ }
|
||||
+
|
||||
+ return false;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+void CIMXCECAdapterCommunication::Close(void)
|
||||
+{
|
||||
+ StopThread(0);
|
||||
+ if (m_dev->Ioctl(HDMICEC_IOC_STOPDEVICE, NULL) != 0) {
|
||||
+ LIB_CEC->AddLog(CEC_LOG_ERROR, "%s: Unable to stop device\n", __func__);
|
||||
+ }
|
||||
+ m_dev->Close();
|
||||
+}
|
||||
+
|
||||
+
|
||||
+std::string CIMXCECAdapterCommunication::GetError(void) const
|
||||
+{
|
||||
+ std::string strError(m_strError);
|
||||
+ return strError;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+cec_adapter_message_state CIMXCECAdapterCommunication::Write(
|
||||
+ const cec_command &data, bool &UNUSED(bRetry), uint8_t UNUSED(iLineTimeout), bool UNUSED(bIsReply))
|
||||
+{
|
||||
+ //cec_frame frame;
|
||||
+ unsigned char message[MAX_CEC_MESSAGE_LEN];
|
||||
+ int msg_len = 1;
|
||||
+ cec_adapter_message_state rc = ADAPTER_MESSAGE_STATE_ERROR;
|
||||
+
|
||||
+ if ((size_t)data.parameters.size + data.opcode_set + 1 > sizeof(message))
|
||||
+ {
|
||||
+ LIB_CEC->AddLog(CEC_LOG_ERROR, "%s: data size too large !", __func__);
|
||||
+ return ADAPTER_MESSAGE_STATE_ERROR;
|
||||
+ }
|
||||
+
|
||||
+ message[0] = (data.initiator << 4) | (data.destination & 0x0f);
|
||||
+ if (data.opcode_set)
|
||||
+ {
|
||||
+ message[1] = data.opcode;
|
||||
+ msg_len++;
|
||||
+ memcpy(&message[2], data.parameters.data, data.parameters.size);
|
||||
+ msg_len+=data.parameters.size;
|
||||
+ }
|
||||
+
|
||||
+ if (m_dev->Write(message, msg_len) == msg_len)
|
||||
+ {
|
||||
+ rc = ADAPTER_MESSAGE_STATE_SENT_ACKED;
|
||||
+ }
|
||||
+ else
|
||||
+ LIB_CEC->AddLog(CEC_LOG_ERROR, "%s: sent command error !", __func__);
|
||||
+
|
||||
+ return rc;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+uint16_t CIMXCECAdapterCommunication::GetFirmwareVersion(void)
|
||||
+{
|
||||
+ /* FIXME add ioctl ? */
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+cec_vendor_id CIMXCECAdapterCommunication::GetVendorId(void)
|
||||
+{
|
||||
+ return CEC_VENDOR_UNKNOWN;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+uint16_t CIMXCECAdapterCommunication::GetPhysicalAddress(void)
|
||||
+{
|
||||
+ uint32_t info;
|
||||
+
|
||||
+ if (m_dev->Ioctl(HDMICEC_IOC_GETPHYADDRESS, &info) != 0)
|
||||
+ {
|
||||
+ LIB_CEC->AddLog(CEC_LOG_ERROR, "%s: HDMICEC_IOC_GETPHYADDRESS failed !", __func__);
|
||||
+ return CEC_INVALID_PHYSICAL_ADDRESS;
|
||||
+ }
|
||||
+
|
||||
+ return info;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+cec_logical_addresses CIMXCECAdapterCommunication::GetLogicalAddresses(void)
|
||||
+{
|
||||
+ cec_logical_addresses addresses;
|
||||
+ addresses.Clear();
|
||||
+
|
||||
+ CLockObject lock(m_mutex);
|
||||
+ if ( m_logicalAddress != CECDEVICE_UNKNOWN)
|
||||
+ addresses.Set(m_logicalAddress);
|
||||
+
|
||||
+ return addresses;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+bool CIMXCECAdapterCommunication::SetLogicalAddresses(const cec_logical_addresses &addresses)
|
||||
+{
|
||||
+ int log_addr = addresses.primary;
|
||||
+
|
||||
+ CLockObject lock(m_mutex);
|
||||
+ if (m_logicalAddress == log_addr)
|
||||
+ return true;
|
||||
+
|
||||
+ if (m_dev->Ioctl(HDMICEC_IOC_SETLOGICALADDRESS, (void *)log_addr) != 0)
|
||||
+ {
|
||||
+ LIB_CEC->AddLog(CEC_LOG_ERROR, "%s: HDMICEC_IOC_SETLOGICALADDRESS failed !", __func__);
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ m_logicalAddress = (cec_logical_address)log_addr;
|
||||
+ return true;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+void *CIMXCECAdapterCommunication::Process(void)
|
||||
+{
|
||||
+ bool bHandled;
|
||||
+ hdmi_cec_event event;
|
||||
+ int ret;
|
||||
+
|
||||
+ uint32_t opcode, status;
|
||||
+ cec_logical_address initiator, destination;
|
||||
+
|
||||
+ while (!IsStopped())
|
||||
+ {
|
||||
+ ret = m_dev->Read((char *)&event, sizeof(event), 5000);
|
||||
+ if (ret > 0)
|
||||
+ {
|
||||
+
|
||||
+ initiator = cec_logical_address(event.msg[0] >> 4);
|
||||
+ destination = cec_logical_address(event.msg[0] & 0x0f);
|
||||
+
|
||||
+ //LIB_CEC->AddLog(CEC_LOG_DEBUG, "%s: Read data : type : %d initiator %d dest %d", __func__, event.event_type, initiator, destination);
|
||||
+ if (event.event_type == MESSAGE_TYPE_RECEIVE_SUCCESS)
|
||||
+ /* Message received */
|
||||
+ {
|
||||
+ cec_command cmd;
|
||||
+
|
||||
+ cec_command::Format(
|
||||
+ cmd, initiator, destination,
|
||||
+ ( event.msg_len > 1 ) ? cec_opcode(event.msg[1]) : CEC_OPCODE_NONE);
|
||||
+
|
||||
+ for( uint8_t i = 2; i < event.msg_len; i++ )
|
||||
+ cmd.parameters.PushBack(event.msg[i]);
|
||||
+
|
||||
+ if (!IsStopped())
|
||||
+ m_callback->OnCommandReceived(cmd);
|
||||
+ }
|
||||
+ /* We are not interested in other events */
|
||||
+ } /*else {
|
||||
+ LIB_CEC->AddLog(CEC_LOG_DEBUG, "%s: Read returned %d", __func__, ret);
|
||||
+ }*/
|
||||
+
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+#endif // HAVE_IMX_API
|
||||
diff --git a/src/lib/adapter/IMX/IMXCECAdapterCommunication.h b/src/lib/adapter/IMX/IMXCECAdapterCommunication.h
|
||||
new file mode 100644
|
||||
index 0000000..910dd39
|
||||
--- /dev/null
|
||||
+++ b/src/lib/adapter/IMX/IMXCECAdapterCommunication.h
|
||||
@@ -0,0 +1,114 @@
|
||||
+#pragma once
|
||||
+/*
|
||||
+ * This file is part of the libCEC(R) library.
|
||||
+ *
|
||||
+ * libCEC(R) is Copyright (C) 2011-2013 Pulse-Eight Limited. All rights reserved.
|
||||
+ * libCEC(R) is an original work, containing original code.
|
||||
+ *
|
||||
+ * libCEC(R) is a trademark of Pulse-Eight Limited.
|
||||
+ *
|
||||
+ * IMX adpater port is Copyright (C) 2013 by Stephan Rafin
|
||||
+ *
|
||||
+ * You can redistribute this file 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.
|
||||
+ *
|
||||
+ *
|
||||
+ */
|
||||
+
|
||||
+#if defined(HAVE_IMX_API)
|
||||
+
|
||||
+#include "lib/platform/threads/mutex.h"
|
||||
+#include "lib/platform/threads/threads.h"
|
||||
+#include "lib/platform/sockets/socket.h"
|
||||
+#include "lib/adapter/AdapterCommunication.h"
|
||||
+#include <map>
|
||||
+
|
||||
+#define IMX_ADAPTER_VID 0x0471 /*FIXME TBD*/
|
||||
+#define IMX_ADAPTER_PID 0x1001
|
||||
+
|
||||
+
|
||||
+
|
||||
+namespace PLATFORM
|
||||
+{
|
||||
+ class CCDevSocket;
|
||||
+};
|
||||
+
|
||||
+
|
||||
+namespace CEC
|
||||
+{
|
||||
+ class CAdapterMessageQueueEntry;
|
||||
+
|
||||
+ class CIMXCECAdapterCommunication : public IAdapterCommunication, public PLATFORM::CThread
|
||||
+ {
|
||||
+ public:
|
||||
+ /*!
|
||||
+ * @brief Create a new USB-CEC communication handler.
|
||||
+ * @param callback The callback to use for incoming CEC commands.
|
||||
+ */
|
||||
+ CIMXCECAdapterCommunication(IAdapterCommunicationCallback *callback);
|
||||
+ virtual ~CIMXCECAdapterCommunication(void);
|
||||
+
|
||||
+ /** @name IAdapterCommunication implementation */
|
||||
+ ///{
|
||||
+ bool Open(uint32_t iTimeoutMs = CEC_DEFAULT_CONNECT_TIMEOUT, bool bSkipChecks = false, bool bStartListening = true);
|
||||
+ void Close(void);
|
||||
+ bool IsOpen(void);
|
||||
+ std::string GetError(void) const;
|
||||
+ cec_adapter_message_state Write(const cec_command &data, bool &bRetry, uint8_t iLineTimeout, bool bIsReply);
|
||||
+
|
||||
+ bool SetLineTimeout(uint8_t UNUSED(iTimeout)) { return true; }
|
||||
+ bool StartBootloader(void) { return false; }
|
||||
+ bool SetLogicalAddresses(const cec_logical_addresses &addresses);
|
||||
+ cec_logical_addresses GetLogicalAddresses(void);
|
||||
+ bool PingAdapter(void) { return IsInitialised(); }
|
||||
+ uint16_t GetFirmwareVersion(void);
|
||||
+ uint32_t GetFirmwareBuildDate(void) { return 0; }
|
||||
+ bool IsRunningLatestFirmware(void) { return true; }
|
||||
+ bool PersistConfiguration(const libcec_configuration & UNUSED(configuration)) { return false; }
|
||||
+ bool GetConfiguration(libcec_configuration & UNUSED(configuration)) { return false; }
|
||||
+ std::string GetPortName(void) { return std::string("IMX"); }
|
||||
+ uint16_t GetPhysicalAddress(void);
|
||||
+ bool SetControlledMode(bool UNUSED(controlled)) { return true; }
|
||||
+ cec_vendor_id GetVendorId(void);
|
||||
+ bool SupportsSourceLogicalAddress(const cec_logical_address address) { return address > CECDEVICE_TV && address <= CECDEVICE_BROADCAST; }
|
||||
+ cec_adapter_type GetAdapterType(void) { return ADAPTERTYPE_IMX; }
|
||||
+ uint16_t GetAdapterVendorId(void) const { return IMX_ADAPTER_VID; }
|
||||
+ uint16_t GetAdapterProductId(void) const { return IMX_ADAPTER_PID; }
|
||||
+ void SetActiveSource(bool UNUSED(bSetTo), bool UNUSED(bClientUnregistered)) {}
|
||||
+ ///}
|
||||
+
|
||||
+ /** @name PLATFORM::CThread implementation */
|
||||
+ ///{
|
||||
+ void *Process(void);
|
||||
+ ///}
|
||||
+
|
||||
+ private:
|
||||
+ bool IsInitialised(void) const { return m_dev != 0; };
|
||||
+
|
||||
+ std::string m_strError; /**< current error message */
|
||||
+
|
||||
+ //cec_logical_addresses m_logicalAddresses;
|
||||
+ cec_logical_address m_logicalAddress;
|
||||
+
|
||||
+ PLATFORM::CMutex m_mutex;
|
||||
+ PLATFORM::CCDevSocket *m_dev; /**< the device connection */
|
||||
+
|
||||
+ PLATFORM::CMutex m_messageMutex;
|
||||
+ uint32_t m_iNextMessage;
|
||||
+ std::map<uint32_t, CAdapterMessageQueueEntry *> m_messages;
|
||||
+ };
|
||||
+
|
||||
+};
|
||||
+
|
||||
+#endif
|
||||
diff --git a/src/lib/adapter/IMX/IMXCECAdapterDetection.cpp b/src/lib/adapter/IMX/IMXCECAdapterDetection.cpp
|
||||
new file mode 100644
|
||||
index 0000000..6c93c45
|
||||
--- /dev/null
|
||||
+++ b/src/lib/adapter/IMX/IMXCECAdapterDetection.cpp
|
||||
@@ -0,0 +1,42 @@
|
||||
+/*
|
||||
+ * This file is part of the libCEC(R) library.
|
||||
+ *
|
||||
+ * libCEC(R) is Copyright (C) 2011-2013 Pulse-Eight Limited. All rights reserved.
|
||||
+ * libCEC(R) is an original work, containing original code.
|
||||
+ *
|
||||
+ * libCEC(R) is a trademark of Pulse-Eight Limited.
|
||||
+ *
|
||||
+ * IMX adpater port is Copyright (C) 2013 by Stephan Rafin
|
||||
+ *
|
||||
+ * You can redistribute this file 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 "env.h"
|
||||
+#include <stdio.h>
|
||||
+
|
||||
+#if defined(HAVE_IMX_API)
|
||||
+#include "IMXCECAdapterDetection.h"
|
||||
+
|
||||
+
|
||||
+using namespace CEC;
|
||||
+
|
||||
+bool CIMXCECAdapterDetection::FindAdapter(void)
|
||||
+{
|
||||
+ return access(CEC_IMX_PATH, 0) == 0;
|
||||
+}
|
||||
+
|
||||
+#endif
|
||||
diff --git a/src/lib/adapter/IMX/IMXCECAdapterDetection.h b/src/lib/adapter/IMX/IMXCECAdapterDetection.h
|
||||
new file mode 100644
|
||||
index 0000000..d54891d
|
||||
--- /dev/null
|
||||
+++ b/src/lib/adapter/IMX/IMXCECAdapterDetection.h
|
||||
@@ -0,0 +1,36 @@
|
||||
+#pragma once
|
||||
+/*
|
||||
+ * This file is part of the libCEC(R) library.
|
||||
+ *
|
||||
+ * libCEC(R) is Copyright (C) 2011-2013 Pulse-Eight Limited. All rights reserved.
|
||||
+ * libCEC(R) is an original work, containing original code.
|
||||
+ *
|
||||
+ * libCEC(R) is a trademark of Pulse-Eight Limited.
|
||||
+ *
|
||||
+ * IMX adpater port is Copyright (C) 2013 by Stephan Rafin
|
||||
+ *
|
||||
+ * You can redistribute this file 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.
|
||||
+ *
|
||||
+ *
|
||||
+ */
|
||||
+
|
||||
+namespace CEC
|
||||
+{
|
||||
+ class CIMXCECAdapterDetection
|
||||
+ {
|
||||
+ public:
|
||||
+ static bool FindAdapter(void);
|
||||
+ };
|
||||
+}
|
||||
--
|
||||
1.9.1
|
||||
|
@ -1,214 +0,0 @@
|
||||
From d821a5f9b03a436950570ee9d7741452248f72e8 Mon Sep 17 00:00:00 2001
|
||||
From: wolfgar <stephan.rafin@laposte.net>
|
||||
Date: Wed, 23 Apr 2014 03:16:04 +0200
|
||||
Subject: [PATCH 1/2] Fix physical address retrieval and notify new address
|
||||
after unplug/plug
|
||||
|
||||
---
|
||||
src/lib/adapter/IMX/IMXCECAdapterCommunication.cpp | 13 ++++++++++++-
|
||||
1 file changed, 12 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/lib/adapter/IMX/IMXCECAdapterCommunication.cpp b/src/lib/adapter/IMX/IMXCECAdapterCommunication.cpp
|
||||
index 54e5662..a226a70 100644
|
||||
--- a/src/lib/adapter/IMX/IMXCECAdapterCommunication.cpp
|
||||
+++ b/src/lib/adapter/IMX/IMXCECAdapterCommunication.cpp
|
||||
@@ -189,14 +189,18 @@ cec_vendor_id CIMXCECAdapterCommunication::GetVendorId(void)
|
||||
uint16_t CIMXCECAdapterCommunication::GetPhysicalAddress(void)
|
||||
{
|
||||
uint32_t info;
|
||||
+ uint16_t phy_addr;
|
||||
|
||||
if (m_dev->Ioctl(HDMICEC_IOC_GETPHYADDRESS, &info) != 0)
|
||||
{
|
||||
LIB_CEC->AddLog(CEC_LOG_ERROR, "%s: HDMICEC_IOC_GETPHYADDRESS failed !", __func__);
|
||||
return CEC_INVALID_PHYSICAL_ADDRESS;
|
||||
}
|
||||
+ /* Rebuild 16 bit raw value from fsl 32 bits value */
|
||||
+ phy_addr = ((info & 0x0f) << 12) | (info & 0x0f00) |
|
||||
+ ((info & 0x0f0000) >> 12) | ((info & 0x0f000000) >> 24);
|
||||
|
||||
- return info;
|
||||
+ return phy_addr;
|
||||
}
|
||||
|
||||
|
||||
@@ -266,6 +270,13 @@ void *CIMXCECAdapterCommunication::Process(void)
|
||||
if (!IsStopped())
|
||||
m_callback->OnCommandReceived(cmd);
|
||||
}
|
||||
+
|
||||
+ if (event.event_type == MESSAGE_TYPE_CONNECTED)
|
||||
+ /* HDMI has just been reconnected - Notify phy address*/
|
||||
+ {
|
||||
+ uint16_t iNewAddress = GetPhysicalAddress();
|
||||
+ m_callback->HandlePhysicalAddressChanged(iNewAddress);
|
||||
+ }
|
||||
/* We are not interested in other events */
|
||||
} /*else {
|
||||
LIB_CEC->AddLog(CEC_LOG_DEBUG, "%s: Read returned %d", __func__, ret);
|
||||
--
|
||||
1.7.9.5
|
||||
|
||||
|
||||
From 42c3c07a79b8155635851c2eed9558b221b89047 Mon Sep 17 00:00:00 2001
|
||||
From: wolfgar <stephan.rafin@laposte.net>
|
||||
Date: Sat, 26 Apr 2014 01:48:06 +0200
|
||||
Subject: [PATCH 2/2] Grab enhancements from mk01 commit
|
||||
https://github.com/mk01/libcec/commit/40ac7550fe22a9fed665eec0aec1882498f838d6#diff-f2ea3f151edca2fc91b2f3cea1159c9bR336
|
||||
|
||||
---
|
||||
src/lib/adapter/IMX/IMXCECAdapterCommunication.cpp | 58 ++++++++++++++++----
|
||||
src/lib/adapter/IMX/IMXCECAdapterCommunication.h | 9 ++-
|
||||
2 files changed, 55 insertions(+), 12 deletions(-)
|
||||
|
||||
diff --git a/src/lib/adapter/IMX/IMXCECAdapterCommunication.cpp b/src/lib/adapter/IMX/IMXCECAdapterCommunication.cpp
|
||||
index a226a70..1f70989 100644
|
||||
--- a/src/lib/adapter/IMX/IMXCECAdapterCommunication.cpp
|
||||
+++ b/src/lib/adapter/IMX/IMXCECAdapterCommunication.cpp
|
||||
@@ -88,6 +88,8 @@ CIMXCECAdapterCommunication::CIMXCECAdapterCommunication(IAdapterCommunicationCa
|
||||
m_iNextMessage = 0;
|
||||
//m_logicalAddresses.Clear();
|
||||
m_logicalAddress = CECDEVICE_UNKNOWN;
|
||||
+ m_bLogicalAddressRegistered = false;
|
||||
+ m_bInitialised = false;
|
||||
m_dev = new CCDevSocket(CEC_IMX_PATH);
|
||||
}
|
||||
|
||||
@@ -110,10 +112,11 @@ bool CIMXCECAdapterCommunication::Open(uint32_t iTimeoutMs, bool UNUSED(bSkipChe
|
||||
if (m_dev->Open(iTimeoutMs))
|
||||
{
|
||||
if (!bStartListening || CreateThread()) {
|
||||
- if (m_dev->Ioctl(HDMICEC_IOC_STARTDEVICE, NULL) != 0) {
|
||||
- LIB_CEC->AddLog(CEC_LOG_ERROR, "%s: Unable to start device\n", __func__);
|
||||
+ if (m_dev->Ioctl(HDMICEC_IOC_STARTDEVICE, NULL) == 0) {
|
||||
+ m_bInitialised = true;
|
||||
+ return true;
|
||||
}
|
||||
- return true;
|
||||
+ LIB_CEC->AddLog(CEC_LOG_ERROR, "%s: Unable to start device\n", __func__);
|
||||
}
|
||||
m_dev->Close();
|
||||
}
|
||||
@@ -125,10 +128,16 @@ bool CIMXCECAdapterCommunication::Open(uint32_t iTimeoutMs, bool UNUSED(bSkipChe
|
||||
void CIMXCECAdapterCommunication::Close(void)
|
||||
{
|
||||
StopThread(0);
|
||||
+
|
||||
+ CLockObject lock(m_mutex);
|
||||
+ if (!m_bInitialised) {
|
||||
+ return;
|
||||
+ }
|
||||
if (m_dev->Ioctl(HDMICEC_IOC_STOPDEVICE, NULL) != 0) {
|
||||
LIB_CEC->AddLog(CEC_LOG_ERROR, "%s: Unable to stop device\n", __func__);
|
||||
}
|
||||
m_dev->Close();
|
||||
+ m_bInitialised = false;
|
||||
}
|
||||
|
||||
|
||||
@@ -210,31 +219,60 @@ cec_logical_addresses CIMXCECAdapterCommunication::GetLogicalAddresses(void)
|
||||
addresses.Clear();
|
||||
|
||||
CLockObject lock(m_mutex);
|
||||
- if ( m_logicalAddress != CECDEVICE_UNKNOWN)
|
||||
+ if ((m_logicalAddress & (CECDEVICE_UNKNOWN | CECDEVICE_UNREGISTERED)) == 0)
|
||||
addresses.Set(m_logicalAddress);
|
||||
|
||||
return addresses;
|
||||
}
|
||||
|
||||
+void CIMXCECAdapterCommunication::HandleLogicalAddressLost(cec_logical_address UNUSED(oldAddress))
|
||||
+{
|
||||
+ UnregisterLogicalAddress();
|
||||
+}
|
||||
|
||||
-bool CIMXCECAdapterCommunication::SetLogicalAddresses(const cec_logical_addresses &addresses)
|
||||
+bool CIMXCECAdapterCommunication::UnregisterLogicalAddress(void)
|
||||
{
|
||||
- int log_addr = addresses.primary;
|
||||
+ CLockObject lock(m_mutex);
|
||||
+ if (!m_bLogicalAddressRegistered)
|
||||
+ return true;
|
||||
+
|
||||
+ if (m_dev->Ioctl(HDMICEC_IOC_SETLOGICALADDRESS, (void *)CECDEVICE_BROADCAST) != 0)
|
||||
+ {
|
||||
+ LIB_CEC->AddLog(CEC_LOG_ERROR, "%s: HDMICEC_IOC_SETLOGICALADDRESS failed !", __func__);
|
||||
+ return false;
|
||||
+ }
|
||||
|
||||
+ m_logicalAddress = CECDEVICE_UNKNOWN;
|
||||
+ m_bLogicalAddressRegistered = false;
|
||||
+ return true;
|
||||
+}
|
||||
+
|
||||
+bool CIMXCECAdapterCommunication::RegisterLogicalAddress(const cec_logical_address address)
|
||||
+{
|
||||
CLockObject lock(m_mutex);
|
||||
- if (m_logicalAddress == log_addr)
|
||||
- return true;
|
||||
|
||||
- if (m_dev->Ioctl(HDMICEC_IOC_SETLOGICALADDRESS, (void *)log_addr) != 0)
|
||||
+ if (m_logicalAddress == address && m_bLogicalAddressRegistered)
|
||||
+ {
|
||||
+ return true;
|
||||
+ }
|
||||
+
|
||||
+ if (m_dev->Ioctl(HDMICEC_IOC_SETLOGICALADDRESS, (void *)address) != 0)
|
||||
{
|
||||
LIB_CEC->AddLog(CEC_LOG_ERROR, "%s: HDMICEC_IOC_SETLOGICALADDRESS failed !", __func__);
|
||||
return false;
|
||||
}
|
||||
|
||||
- m_logicalAddress = (cec_logical_address)log_addr;
|
||||
+ m_logicalAddress = address;
|
||||
+ m_bLogicalAddressRegistered = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
+bool CIMXCECAdapterCommunication::SetLogicalAddresses(const cec_logical_addresses &addresses)
|
||||
+{
|
||||
+ int log_addr = addresses.primary;
|
||||
+
|
||||
+ return RegisterLogicalAddress((cec_logical_address)log_addr);
|
||||
+}
|
||||
|
||||
void *CIMXCECAdapterCommunication::Process(void)
|
||||
{
|
||||
diff --git a/src/lib/adapter/IMX/IMXCECAdapterCommunication.h b/src/lib/adapter/IMX/IMXCECAdapterCommunication.h
|
||||
index 910dd39..ce5c4cb 100644
|
||||
--- a/src/lib/adapter/IMX/IMXCECAdapterCommunication.h
|
||||
+++ b/src/lib/adapter/IMX/IMXCECAdapterCommunication.h
|
||||
@@ -85,7 +85,9 @@ namespace CEC
|
||||
cec_adapter_type GetAdapterType(void) { return ADAPTERTYPE_IMX; }
|
||||
uint16_t GetAdapterVendorId(void) const { return IMX_ADAPTER_VID; }
|
||||
uint16_t GetAdapterProductId(void) const { return IMX_ADAPTER_PID; }
|
||||
+ void HandleLogicalAddressLost(cec_logical_address UNUSED(oldAddress));
|
||||
void SetActiveSource(bool UNUSED(bSetTo), bool UNUSED(bClientUnregistered)) {}
|
||||
+ bool RegisterLogicalAddress(const cec_logical_address address);
|
||||
///}
|
||||
|
||||
/** @name PLATFORM::CThread implementation */
|
||||
@@ -94,7 +96,8 @@ namespace CEC
|
||||
///}
|
||||
|
||||
private:
|
||||
- bool IsInitialised(void) const { return m_dev != 0; };
|
||||
+ bool IsInitialised(void) const { return m_bInitialised; };
|
||||
+ bool UnregisterLogicalAddress(void);
|
||||
|
||||
std::string m_strError; /**< current error message */
|
||||
|
||||
@@ -103,7 +106,9 @@ namespace CEC
|
||||
|
||||
PLATFORM::CMutex m_mutex;
|
||||
PLATFORM::CCDevSocket *m_dev; /**< the device connection */
|
||||
-
|
||||
+ bool m_bLogicalAddressRegistered;
|
||||
+ bool m_bInitialised;
|
||||
+
|
||||
PLATFORM::CMutex m_messageMutex;
|
||||
uint32_t m_iNextMessage;
|
||||
std::map<uint32_t, CAdapterMessageQueueEntry *> m_messages;
|
||||
--
|
||||
1.7.9.5
|
||||
|
@ -1,800 +0,0 @@
|
||||
diff --git a/Makefile b/Makefile
|
||||
index 18016a55dbd3..56b93edbbe4e 100644
|
||||
--- a/Makefile
|
||||
+++ b/Makefile
|
||||
@@ -1,6 +1,6 @@
|
||||
VERSION = 3
|
||||
PATCHLEVEL = 10
|
||||
-SUBLEVEL = 30
|
||||
+SUBLEVEL = 31
|
||||
EXTRAVERSION =
|
||||
NAME = TOSSUG Baby Fish
|
||||
|
||||
diff --git a/arch/arm64/include/asm/cacheflush.h b/arch/arm64/include/asm/cacheflush.h
|
||||
index 3300cbd18a89..0c13554965b8 100644
|
||||
--- a/arch/arm64/include/asm/cacheflush.h
|
||||
+++ b/arch/arm64/include/asm/cacheflush.h
|
||||
@@ -116,6 +116,7 @@ extern void flush_dcache_page(struct page *);
|
||||
static inline void __flush_icache_all(void)
|
||||
{
|
||||
asm("ic ialluis");
|
||||
+ dsb();
|
||||
}
|
||||
|
||||
#define flush_dcache_mmap_lock(mapping) \
|
||||
diff --git a/arch/arm64/kernel/vdso.c b/arch/arm64/kernel/vdso.c
|
||||
index 6a389dc1bd49..0ea7a22bcdf2 100644
|
||||
--- a/arch/arm64/kernel/vdso.c
|
||||
+++ b/arch/arm64/kernel/vdso.c
|
||||
@@ -235,6 +235,8 @@ void update_vsyscall(struct timekeeper *tk)
|
||||
vdso_data->use_syscall = use_syscall;
|
||||
vdso_data->xtime_coarse_sec = xtime_coarse.tv_sec;
|
||||
vdso_data->xtime_coarse_nsec = xtime_coarse.tv_nsec;
|
||||
+ vdso_data->wtm_clock_sec = tk->wall_to_monotonic.tv_sec;
|
||||
+ vdso_data->wtm_clock_nsec = tk->wall_to_monotonic.tv_nsec;
|
||||
|
||||
if (!use_syscall) {
|
||||
vdso_data->cs_cycle_last = tk->clock->cycle_last;
|
||||
@@ -242,8 +244,6 @@ void update_vsyscall(struct timekeeper *tk)
|
||||
vdso_data->xtime_clock_nsec = tk->xtime_nsec;
|
||||
vdso_data->cs_mult = tk->mult;
|
||||
vdso_data->cs_shift = tk->shift;
|
||||
- vdso_data->wtm_clock_sec = tk->wall_to_monotonic.tv_sec;
|
||||
- vdso_data->wtm_clock_nsec = tk->wall_to_monotonic.tv_nsec;
|
||||
}
|
||||
|
||||
smp_wmb();
|
||||
diff --git a/arch/arm64/kernel/vdso/Makefile b/arch/arm64/kernel/vdso/Makefile
|
||||
index d8064af42e62..6d20b7d162d8 100644
|
||||
--- a/arch/arm64/kernel/vdso/Makefile
|
||||
+++ b/arch/arm64/kernel/vdso/Makefile
|
||||
@@ -48,7 +48,7 @@ $(obj-vdso): %.o: %.S
|
||||
|
||||
# Actual build commands
|
||||
quiet_cmd_vdsold = VDSOL $@
|
||||
- cmd_vdsold = $(CC) $(c_flags) -Wl,-T $^ -o $@
|
||||
+ cmd_vdsold = $(CC) $(c_flags) -Wl,-n -Wl,-T $^ -o $@
|
||||
quiet_cmd_vdsoas = VDSOA $@
|
||||
cmd_vdsoas = $(CC) $(a_flags) -c -o $@ $<
|
||||
|
||||
diff --git a/arch/arm64/kernel/vdso/gettimeofday.S b/arch/arm64/kernel/vdso/gettimeofday.S
|
||||
index f0a6d10b5211..fe652ffd34c2 100644
|
||||
--- a/arch/arm64/kernel/vdso/gettimeofday.S
|
||||
+++ b/arch/arm64/kernel/vdso/gettimeofday.S
|
||||
@@ -103,6 +103,8 @@ ENTRY(__kernel_clock_gettime)
|
||||
bl __do_get_tspec
|
||||
seqcnt_check w9, 1b
|
||||
|
||||
+ mov x30, x2
|
||||
+
|
||||
cmp w0, #CLOCK_MONOTONIC
|
||||
b.ne 6f
|
||||
|
||||
@@ -118,6 +120,9 @@ ENTRY(__kernel_clock_gettime)
|
||||
ccmp w0, #CLOCK_MONOTONIC_COARSE, #0x4, ne
|
||||
b.ne 8f
|
||||
|
||||
+ /* xtime_coarse_nsec is already right-shifted */
|
||||
+ mov x12, #0
|
||||
+
|
||||
/* Get coarse timespec. */
|
||||
adr vdso_data, _vdso_data
|
||||
3: seqcnt_acquire
|
||||
@@ -156,7 +161,7 @@ ENTRY(__kernel_clock_gettime)
|
||||
lsr x11, x11, x12
|
||||
stp x10, x11, [x1, #TSPEC_TV_SEC]
|
||||
mov x0, xzr
|
||||
- ret x2
|
||||
+ ret
|
||||
7:
|
||||
mov x30, x2
|
||||
8: /* Syscall fallback. */
|
||||
diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
|
||||
index 80a369eab637..ba7477efad5c 100644
|
||||
--- a/arch/arm64/mm/mmu.c
|
||||
+++ b/arch/arm64/mm/mmu.c
|
||||
@@ -203,10 +203,18 @@ static void __init alloc_init_pmd(pud_t *pud, unsigned long addr,
|
||||
do {
|
||||
next = pmd_addr_end(addr, end);
|
||||
/* try section mapping first */
|
||||
- if (((addr | next | phys) & ~SECTION_MASK) == 0)
|
||||
+ if (((addr | next | phys) & ~SECTION_MASK) == 0) {
|
||||
+ pmd_t old_pmd =*pmd;
|
||||
set_pmd(pmd, __pmd(phys | prot_sect_kernel));
|
||||
- else
|
||||
+ /*
|
||||
+ * Check for previous table entries created during
|
||||
+ * boot (__create_page_tables) and flush them.
|
||||
+ */
|
||||
+ if (!pmd_none(old_pmd))
|
||||
+ flush_tlb_all();
|
||||
+ } else {
|
||||
alloc_init_pte(pmd, addr, next, __phys_to_pfn(phys));
|
||||
+ }
|
||||
phys += next - addr;
|
||||
} while (pmd++, addr = next, addr != end);
|
||||
}
|
||||
diff --git a/arch/s390/crypto/aes_s390.c b/arch/s390/crypto/aes_s390.c
|
||||
index 94e20dd2729f..2a245b55bb71 100644
|
||||
--- a/arch/s390/crypto/aes_s390.c
|
||||
+++ b/arch/s390/crypto/aes_s390.c
|
||||
@@ -25,6 +25,7 @@
|
||||
#include <linux/err.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
+#include <linux/spinlock.h>
|
||||
#include "crypt_s390.h"
|
||||
|
||||
#define AES_KEYLEN_128 1
|
||||
@@ -32,6 +33,7 @@
|
||||
#define AES_KEYLEN_256 4
|
||||
|
||||
static u8 *ctrblk;
|
||||
+static DEFINE_SPINLOCK(ctrblk_lock);
|
||||
static char keylen_flag;
|
||||
|
||||
struct s390_aes_ctx {
|
||||
@@ -756,43 +758,67 @@ static int ctr_aes_set_key(struct crypto_tfm *tfm, const u8 *in_key,
|
||||
return aes_set_key(tfm, in_key, key_len);
|
||||
}
|
||||
|
||||
+static unsigned int __ctrblk_init(u8 *ctrptr, unsigned int nbytes)
|
||||
+{
|
||||
+ unsigned int i, n;
|
||||
+
|
||||
+ /* only use complete blocks, max. PAGE_SIZE */
|
||||
+ n = (nbytes > PAGE_SIZE) ? PAGE_SIZE : nbytes & ~(AES_BLOCK_SIZE - 1);
|
||||
+ for (i = AES_BLOCK_SIZE; i < n; i += AES_BLOCK_SIZE) {
|
||||
+ memcpy(ctrptr + i, ctrptr + i - AES_BLOCK_SIZE,
|
||||
+ AES_BLOCK_SIZE);
|
||||
+ crypto_inc(ctrptr + i, AES_BLOCK_SIZE);
|
||||
+ }
|
||||
+ return n;
|
||||
+}
|
||||
+
|
||||
static int ctr_aes_crypt(struct blkcipher_desc *desc, long func,
|
||||
struct s390_aes_ctx *sctx, struct blkcipher_walk *walk)
|
||||
{
|
||||
int ret = blkcipher_walk_virt_block(desc, walk, AES_BLOCK_SIZE);
|
||||
- unsigned int i, n, nbytes;
|
||||
- u8 buf[AES_BLOCK_SIZE];
|
||||
- u8 *out, *in;
|
||||
+ unsigned int n, nbytes;
|
||||
+ u8 buf[AES_BLOCK_SIZE], ctrbuf[AES_BLOCK_SIZE];
|
||||
+ u8 *out, *in, *ctrptr = ctrbuf;
|
||||
|
||||
if (!walk->nbytes)
|
||||
return ret;
|
||||
|
||||
- memcpy(ctrblk, walk->iv, AES_BLOCK_SIZE);
|
||||
+ if (spin_trylock(&ctrblk_lock))
|
||||
+ ctrptr = ctrblk;
|
||||
+
|
||||
+ memcpy(ctrptr, walk->iv, AES_BLOCK_SIZE);
|
||||
while ((nbytes = walk->nbytes) >= AES_BLOCK_SIZE) {
|
||||
out = walk->dst.virt.addr;
|
||||
in = walk->src.virt.addr;
|
||||
while (nbytes >= AES_BLOCK_SIZE) {
|
||||
- /* only use complete blocks, max. PAGE_SIZE */
|
||||
- n = (nbytes > PAGE_SIZE) ? PAGE_SIZE :
|
||||
- nbytes & ~(AES_BLOCK_SIZE - 1);
|
||||
- for (i = AES_BLOCK_SIZE; i < n; i += AES_BLOCK_SIZE) {
|
||||
- memcpy(ctrblk + i, ctrblk + i - AES_BLOCK_SIZE,
|
||||
- AES_BLOCK_SIZE);
|
||||
- crypto_inc(ctrblk + i, AES_BLOCK_SIZE);
|
||||
- }
|
||||
- ret = crypt_s390_kmctr(func, sctx->key, out, in, n, ctrblk);
|
||||
- if (ret < 0 || ret != n)
|
||||
+ if (ctrptr == ctrblk)
|
||||
+ n = __ctrblk_init(ctrptr, nbytes);
|
||||
+ else
|
||||
+ n = AES_BLOCK_SIZE;
|
||||
+ ret = crypt_s390_kmctr(func, sctx->key, out, in,
|
||||
+ n, ctrptr);
|
||||
+ if (ret < 0 || ret != n) {
|
||||
+ if (ctrptr == ctrblk)
|
||||
+ spin_unlock(&ctrblk_lock);
|
||||
return -EIO;
|
||||
+ }
|
||||
if (n > AES_BLOCK_SIZE)
|
||||
- memcpy(ctrblk, ctrblk + n - AES_BLOCK_SIZE,
|
||||
+ memcpy(ctrptr, ctrptr + n - AES_BLOCK_SIZE,
|
||||
AES_BLOCK_SIZE);
|
||||
- crypto_inc(ctrblk, AES_BLOCK_SIZE);
|
||||
+ crypto_inc(ctrptr, AES_BLOCK_SIZE);
|
||||
out += n;
|
||||
in += n;
|
||||
nbytes -= n;
|
||||
}
|
||||
ret = blkcipher_walk_done(desc, walk, nbytes);
|
||||
}
|
||||
+ if (ctrptr == ctrblk) {
|
||||
+ if (nbytes)
|
||||
+ memcpy(ctrbuf, ctrptr, AES_BLOCK_SIZE);
|
||||
+ else
|
||||
+ memcpy(walk->iv, ctrptr, AES_BLOCK_SIZE);
|
||||
+ spin_unlock(&ctrblk_lock);
|
||||
+ }
|
||||
/*
|
||||
* final block may be < AES_BLOCK_SIZE, copy only nbytes
|
||||
*/
|
||||
@@ -800,14 +826,15 @@ static int ctr_aes_crypt(struct blkcipher_desc *desc, long func,
|
||||
out = walk->dst.virt.addr;
|
||||
in = walk->src.virt.addr;
|
||||
ret = crypt_s390_kmctr(func, sctx->key, buf, in,
|
||||
- AES_BLOCK_SIZE, ctrblk);
|
||||
+ AES_BLOCK_SIZE, ctrbuf);
|
||||
if (ret < 0 || ret != AES_BLOCK_SIZE)
|
||||
return -EIO;
|
||||
memcpy(out, buf, nbytes);
|
||||
- crypto_inc(ctrblk, AES_BLOCK_SIZE);
|
||||
+ crypto_inc(ctrbuf, AES_BLOCK_SIZE);
|
||||
ret = blkcipher_walk_done(desc, walk, 0);
|
||||
+ memcpy(walk->iv, ctrbuf, AES_BLOCK_SIZE);
|
||||
}
|
||||
- memcpy(walk->iv, ctrblk, AES_BLOCK_SIZE);
|
||||
+
|
||||
return ret;
|
||||
}
|
||||
|
||||
diff --git a/arch/s390/crypto/des_s390.c b/arch/s390/crypto/des_s390.c
|
||||
index bcca01c9989d..2d96e68febb2 100644
|
||||
--- a/arch/s390/crypto/des_s390.c
|
||||
+++ b/arch/s390/crypto/des_s390.c
|
||||
@@ -25,6 +25,7 @@
|
||||
#define DES3_KEY_SIZE (3 * DES_KEY_SIZE)
|
||||
|
||||
static u8 *ctrblk;
|
||||
+static DEFINE_SPINLOCK(ctrblk_lock);
|
||||
|
||||
struct s390_des_ctx {
|
||||
u8 iv[DES_BLOCK_SIZE];
|
||||
@@ -105,29 +106,35 @@ static int ecb_desall_crypt(struct blkcipher_desc *desc, long func,
|
||||
}
|
||||
|
||||
static int cbc_desall_crypt(struct blkcipher_desc *desc, long func,
|
||||
- u8 *iv, struct blkcipher_walk *walk)
|
||||
+ struct blkcipher_walk *walk)
|
||||
{
|
||||
+ struct s390_des_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
|
||||
int ret = blkcipher_walk_virt(desc, walk);
|
||||
unsigned int nbytes = walk->nbytes;
|
||||
+ struct {
|
||||
+ u8 iv[DES_BLOCK_SIZE];
|
||||
+ u8 key[DES3_KEY_SIZE];
|
||||
+ } param;
|
||||
|
||||
if (!nbytes)
|
||||
goto out;
|
||||
|
||||
- memcpy(iv, walk->iv, DES_BLOCK_SIZE);
|
||||
+ memcpy(param.iv, walk->iv, DES_BLOCK_SIZE);
|
||||
+ memcpy(param.key, ctx->key, DES3_KEY_SIZE);
|
||||
do {
|
||||
/* only use complete blocks */
|
||||
unsigned int n = nbytes & ~(DES_BLOCK_SIZE - 1);
|
||||
u8 *out = walk->dst.virt.addr;
|
||||
u8 *in = walk->src.virt.addr;
|
||||
|
||||
- ret = crypt_s390_kmc(func, iv, out, in, n);
|
||||
+ ret = crypt_s390_kmc(func, ¶m, out, in, n);
|
||||
if (ret < 0 || ret != n)
|
||||
return -EIO;
|
||||
|
||||
nbytes &= DES_BLOCK_SIZE - 1;
|
||||
ret = blkcipher_walk_done(desc, walk, nbytes);
|
||||
} while ((nbytes = walk->nbytes));
|
||||
- memcpy(walk->iv, iv, DES_BLOCK_SIZE);
|
||||
+ memcpy(walk->iv, param.iv, DES_BLOCK_SIZE);
|
||||
|
||||
out:
|
||||
return ret;
|
||||
@@ -179,22 +186,20 @@ static int cbc_des_encrypt(struct blkcipher_desc *desc,
|
||||
struct scatterlist *dst, struct scatterlist *src,
|
||||
unsigned int nbytes)
|
||||
{
|
||||
- struct s390_des_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
|
||||
struct blkcipher_walk walk;
|
||||
|
||||
blkcipher_walk_init(&walk, dst, src, nbytes);
|
||||
- return cbc_desall_crypt(desc, KMC_DEA_ENCRYPT, ctx->iv, &walk);
|
||||
+ return cbc_desall_crypt(desc, KMC_DEA_ENCRYPT, &walk);
|
||||
}
|
||||
|
||||
static int cbc_des_decrypt(struct blkcipher_desc *desc,
|
||||
struct scatterlist *dst, struct scatterlist *src,
|
||||
unsigned int nbytes)
|
||||
{
|
||||
- struct s390_des_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
|
||||
struct blkcipher_walk walk;
|
||||
|
||||
blkcipher_walk_init(&walk, dst, src, nbytes);
|
||||
- return cbc_desall_crypt(desc, KMC_DEA_DECRYPT, ctx->iv, &walk);
|
||||
+ return cbc_desall_crypt(desc, KMC_DEA_DECRYPT, &walk);
|
||||
}
|
||||
|
||||
static struct crypto_alg cbc_des_alg = {
|
||||
@@ -327,22 +332,20 @@ static int cbc_des3_encrypt(struct blkcipher_desc *desc,
|
||||
struct scatterlist *dst, struct scatterlist *src,
|
||||
unsigned int nbytes)
|
||||
{
|
||||
- struct s390_des_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
|
||||
struct blkcipher_walk walk;
|
||||
|
||||
blkcipher_walk_init(&walk, dst, src, nbytes);
|
||||
- return cbc_desall_crypt(desc, KMC_TDEA_192_ENCRYPT, ctx->iv, &walk);
|
||||
+ return cbc_desall_crypt(desc, KMC_TDEA_192_ENCRYPT, &walk);
|
||||
}
|
||||
|
||||
static int cbc_des3_decrypt(struct blkcipher_desc *desc,
|
||||
struct scatterlist *dst, struct scatterlist *src,
|
||||
unsigned int nbytes)
|
||||
{
|
||||
- struct s390_des_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
|
||||
struct blkcipher_walk walk;
|
||||
|
||||
blkcipher_walk_init(&walk, dst, src, nbytes);
|
||||
- return cbc_desall_crypt(desc, KMC_TDEA_192_DECRYPT, ctx->iv, &walk);
|
||||
+ return cbc_desall_crypt(desc, KMC_TDEA_192_DECRYPT, &walk);
|
||||
}
|
||||
|
||||
static struct crypto_alg cbc_des3_alg = {
|
||||
@@ -366,54 +369,80 @@ static struct crypto_alg cbc_des3_alg = {
|
||||
}
|
||||
};
|
||||
|
||||
+static unsigned int __ctrblk_init(u8 *ctrptr, unsigned int nbytes)
|
||||
+{
|
||||
+ unsigned int i, n;
|
||||
+
|
||||
+ /* align to block size, max. PAGE_SIZE */
|
||||
+ n = (nbytes > PAGE_SIZE) ? PAGE_SIZE : nbytes & ~(DES_BLOCK_SIZE - 1);
|
||||
+ for (i = DES_BLOCK_SIZE; i < n; i += DES_BLOCK_SIZE) {
|
||||
+ memcpy(ctrptr + i, ctrptr + i - DES_BLOCK_SIZE, DES_BLOCK_SIZE);
|
||||
+ crypto_inc(ctrptr + i, DES_BLOCK_SIZE);
|
||||
+ }
|
||||
+ return n;
|
||||
+}
|
||||
+
|
||||
static int ctr_desall_crypt(struct blkcipher_desc *desc, long func,
|
||||
- struct s390_des_ctx *ctx, struct blkcipher_walk *walk)
|
||||
+ struct s390_des_ctx *ctx,
|
||||
+ struct blkcipher_walk *walk)
|
||||
{
|
||||
int ret = blkcipher_walk_virt_block(desc, walk, DES_BLOCK_SIZE);
|
||||
- unsigned int i, n, nbytes;
|
||||
- u8 buf[DES_BLOCK_SIZE];
|
||||
- u8 *out, *in;
|
||||
+ unsigned int n, nbytes;
|
||||
+ u8 buf[DES_BLOCK_SIZE], ctrbuf[DES_BLOCK_SIZE];
|
||||
+ u8 *out, *in, *ctrptr = ctrbuf;
|
||||
+
|
||||
+ if (!walk->nbytes)
|
||||
+ return ret;
|
||||
|
||||
- memcpy(ctrblk, walk->iv, DES_BLOCK_SIZE);
|
||||
+ if (spin_trylock(&ctrblk_lock))
|
||||
+ ctrptr = ctrblk;
|
||||
+
|
||||
+ memcpy(ctrptr, walk->iv, DES_BLOCK_SIZE);
|
||||
while ((nbytes = walk->nbytes) >= DES_BLOCK_SIZE) {
|
||||
out = walk->dst.virt.addr;
|
||||
in = walk->src.virt.addr;
|
||||
while (nbytes >= DES_BLOCK_SIZE) {
|
||||
- /* align to block size, max. PAGE_SIZE */
|
||||
- n = (nbytes > PAGE_SIZE) ? PAGE_SIZE :
|
||||
- nbytes & ~(DES_BLOCK_SIZE - 1);
|
||||
- for (i = DES_BLOCK_SIZE; i < n; i += DES_BLOCK_SIZE) {
|
||||
- memcpy(ctrblk + i, ctrblk + i - DES_BLOCK_SIZE,
|
||||
- DES_BLOCK_SIZE);
|
||||
- crypto_inc(ctrblk + i, DES_BLOCK_SIZE);
|
||||
- }
|
||||
- ret = crypt_s390_kmctr(func, ctx->key, out, in, n, ctrblk);
|
||||
- if (ret < 0 || ret != n)
|
||||
+ if (ctrptr == ctrblk)
|
||||
+ n = __ctrblk_init(ctrptr, nbytes);
|
||||
+ else
|
||||
+ n = DES_BLOCK_SIZE;
|
||||
+ ret = crypt_s390_kmctr(func, ctx->key, out, in,
|
||||
+ n, ctrptr);
|
||||
+ if (ret < 0 || ret != n) {
|
||||
+ if (ctrptr == ctrblk)
|
||||
+ spin_unlock(&ctrblk_lock);
|
||||
return -EIO;
|
||||
+ }
|
||||
if (n > DES_BLOCK_SIZE)
|
||||
- memcpy(ctrblk, ctrblk + n - DES_BLOCK_SIZE,
|
||||
+ memcpy(ctrptr, ctrptr + n - DES_BLOCK_SIZE,
|
||||
DES_BLOCK_SIZE);
|
||||
- crypto_inc(ctrblk, DES_BLOCK_SIZE);
|
||||
+ crypto_inc(ctrptr, DES_BLOCK_SIZE);
|
||||
out += n;
|
||||
in += n;
|
||||
nbytes -= n;
|
||||
}
|
||||
ret = blkcipher_walk_done(desc, walk, nbytes);
|
||||
}
|
||||
-
|
||||
+ if (ctrptr == ctrblk) {
|
||||
+ if (nbytes)
|
||||
+ memcpy(ctrbuf, ctrptr, DES_BLOCK_SIZE);
|
||||
+ else
|
||||
+ memcpy(walk->iv, ctrptr, DES_BLOCK_SIZE);
|
||||
+ spin_unlock(&ctrblk_lock);
|
||||
+ }
|
||||
/* final block may be < DES_BLOCK_SIZE, copy only nbytes */
|
||||
if (nbytes) {
|
||||
out = walk->dst.virt.addr;
|
||||
in = walk->src.virt.addr;
|
||||
ret = crypt_s390_kmctr(func, ctx->key, buf, in,
|
||||
- DES_BLOCK_SIZE, ctrblk);
|
||||
+ DES_BLOCK_SIZE, ctrbuf);
|
||||
if (ret < 0 || ret != DES_BLOCK_SIZE)
|
||||
return -EIO;
|
||||
memcpy(out, buf, nbytes);
|
||||
- crypto_inc(ctrblk, DES_BLOCK_SIZE);
|
||||
+ crypto_inc(ctrbuf, DES_BLOCK_SIZE);
|
||||
ret = blkcipher_walk_done(desc, walk, 0);
|
||||
+ memcpy(walk->iv, ctrbuf, DES_BLOCK_SIZE);
|
||||
}
|
||||
- memcpy(walk->iv, ctrblk, DES_BLOCK_SIZE);
|
||||
return ret;
|
||||
}
|
||||
|
||||
diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c
|
||||
index 32d37d9a7787..f187806dfc18 100644
|
||||
--- a/arch/x86/kernel/cpu/intel.c
|
||||
+++ b/arch/x86/kernel/cpu/intel.c
|
||||
@@ -628,7 +628,7 @@ static void __cpuinit intel_tlb_flushall_shift_set(struct cpuinfo_x86 *c)
|
||||
tlb_flushall_shift = 5;
|
||||
break;
|
||||
case 0x63a: /* Ivybridge */
|
||||
- tlb_flushall_shift = 1;
|
||||
+ tlb_flushall_shift = 2;
|
||||
break;
|
||||
default:
|
||||
tlb_flushall_shift = 6;
|
||||
diff --git a/drivers/infiniband/hw/qib/qib_user_sdma.c b/drivers/infiniband/hw/qib/qib_user_sdma.c
|
||||
index 82442085cbe6..573b4601d5b9 100644
|
||||
--- a/drivers/infiniband/hw/qib/qib_user_sdma.c
|
||||
+++ b/drivers/infiniband/hw/qib/qib_user_sdma.c
|
||||
@@ -284,8 +284,7 @@ static int qib_user_sdma_pin_pages(const struct qib_devdata *dd,
|
||||
int j;
|
||||
int ret;
|
||||
|
||||
- ret = get_user_pages(current, current->mm, addr,
|
||||
- npages, 0, 1, pages, NULL);
|
||||
+ ret = get_user_pages_fast(addr, npages, 0, pages);
|
||||
|
||||
if (ret != npages) {
|
||||
int i;
|
||||
@@ -830,10 +829,7 @@ int qib_user_sdma_writev(struct qib_ctxtdata *rcd,
|
||||
while (dim) {
|
||||
const int mxp = 8;
|
||||
|
||||
- down_write(¤t->mm->mmap_sem);
|
||||
ret = qib_user_sdma_queue_pkts(dd, pq, &list, iov, dim, mxp);
|
||||
- up_write(¤t->mm->mmap_sem);
|
||||
-
|
||||
if (ret <= 0)
|
||||
goto done_unlock;
|
||||
else {
|
||||
diff --git a/drivers/irqchip/irq-armada-370-xp.c b/drivers/irqchip/irq-armada-370-xp.c
|
||||
index bb328a366122..a51ee009ed83 100644
|
||||
--- a/drivers/irqchip/irq-armada-370-xp.c
|
||||
+++ b/drivers/irqchip/irq-armada-370-xp.c
|
||||
@@ -229,7 +229,7 @@ armada_370_xp_handle_irq(struct pt_regs *regs)
|
||||
ARMADA_370_XP_IN_DRBEL_CAUSE_OFFS)
|
||||
& IPI_DOORBELL_MASK;
|
||||
|
||||
- writel(~IPI_DOORBELL_MASK, per_cpu_int_base +
|
||||
+ writel(~ipimask, per_cpu_int_base +
|
||||
ARMADA_370_XP_IN_DRBEL_CAUSE_OFFS);
|
||||
|
||||
/* Handle all pending doorbells */
|
||||
diff --git a/drivers/media/usb/dvb-usb-v2/af9035.c b/drivers/media/usb/dvb-usb-v2/af9035.c
|
||||
index 46f05ad529f9..2e93ba5598c4 100644
|
||||
--- a/drivers/media/usb/dvb-usb-v2/af9035.c
|
||||
+++ b/drivers/media/usb/dvb-usb-v2/af9035.c
|
||||
@@ -1517,6 +1517,8 @@ static const struct usb_device_id af9035_id_table[] = {
|
||||
&af9035_props, "TerraTec Cinergy T Stick Dual RC (rev. 2)", NULL) },
|
||||
{ DVB_USB_DEVICE(USB_VID_LEADTEK, 0x6a05,
|
||||
&af9035_props, "Leadtek WinFast DTV Dongle Dual", NULL) },
|
||||
+ { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xf900,
|
||||
+ &af9035_props, "Hauppauge WinTV-MiniStick 2", NULL) },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(usb, af9035_id_table);
|
||||
diff --git a/drivers/media/usb/dvb-usb-v2/mxl111sf-tuner.h b/drivers/media/usb/dvb-usb-v2/mxl111sf-tuner.h
|
||||
index 90f583e5d6a6..a8f65d88c9e7 100644
|
||||
--- a/drivers/media/usb/dvb-usb-v2/mxl111sf-tuner.h
|
||||
+++ b/drivers/media/usb/dvb-usb-v2/mxl111sf-tuner.h
|
||||
@@ -68,7 +68,7 @@ struct dvb_frontend *mxl111sf_tuner_attach(struct dvb_frontend *fe,
|
||||
#else
|
||||
static inline
|
||||
struct dvb_frontend *mxl111sf_tuner_attach(struct dvb_frontend *fe,
|
||||
- struct mxl111sf_state *mxl_state
|
||||
+ struct mxl111sf_state *mxl_state,
|
||||
struct mxl111sf_tuner_config *cfg)
|
||||
{
|
||||
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
|
||||
diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c
|
||||
index 5327f35d9b5c..bb7ee9cb00b1 100644
|
||||
--- a/drivers/pinctrl/core.c
|
||||
+++ b/drivers/pinctrl/core.c
|
||||
@@ -807,7 +807,9 @@ static struct pinctrl *create_pinctrl(struct device *dev)
|
||||
kref_init(&p->users);
|
||||
|
||||
/* Add the pinctrl handle to the global list */
|
||||
+ mutex_lock(&pinctrl_list_mutex);
|
||||
list_add_tail(&p->node, &pinctrl_list);
|
||||
+ mutex_unlock(&pinctrl_list_mutex);
|
||||
|
||||
return p;
|
||||
}
|
||||
diff --git a/drivers/pinctrl/vt8500/pinctrl-wmt.c b/drivers/pinctrl/vt8500/pinctrl-wmt.c
|
||||
index 70d986e04afb..8b54b5da00c0 100644
|
||||
--- a/drivers/pinctrl/vt8500/pinctrl-wmt.c
|
||||
+++ b/drivers/pinctrl/vt8500/pinctrl-wmt.c
|
||||
@@ -276,7 +276,20 @@ static int wmt_pctl_dt_node_to_map_pull(struct wmt_pinctrl_data *data,
|
||||
if (!configs)
|
||||
return -ENOMEM;
|
||||
|
||||
- configs[0] = pull;
|
||||
+ switch (pull) {
|
||||
+ case 0:
|
||||
+ configs[0] = PIN_CONFIG_BIAS_DISABLE;
|
||||
+ break;
|
||||
+ case 1:
|
||||
+ configs[0] = PIN_CONFIG_BIAS_PULL_DOWN;
|
||||
+ break;
|
||||
+ case 2:
|
||||
+ configs[0] = PIN_CONFIG_BIAS_PULL_UP;
|
||||
+ break;
|
||||
+ default:
|
||||
+ configs[0] = PIN_CONFIG_BIAS_DISABLE;
|
||||
+ dev_err(data->dev, "invalid pull state %d - disabling\n", pull);
|
||||
+ }
|
||||
|
||||
map->type = PIN_MAP_TYPE_CONFIGS_PIN;
|
||||
map->data.configs.group_or_pin = data->groups[group];
|
||||
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
|
||||
index 0bcee78cde16..25e6a8e1014e 100644
|
||||
--- a/fs/btrfs/inode.c
|
||||
+++ b/fs/btrfs/inode.c
|
||||
@@ -2655,7 +2655,7 @@ static int btrfs_finish_ordered_io(struct btrfs_ordered_extent *ordered_extent)
|
||||
EXTENT_DEFRAG, 1, cached_state);
|
||||
if (ret) {
|
||||
u64 last_snapshot = btrfs_root_last_snapshot(&root->root_item);
|
||||
- if (last_snapshot >= BTRFS_I(inode)->generation)
|
||||
+ if (0 && last_snapshot >= BTRFS_I(inode)->generation)
|
||||
/* the inode is shared */
|
||||
new = record_old_file_extents(inode, ordered_extent);
|
||||
|
||||
diff --git a/fs/buffer.c b/fs/buffer.c
|
||||
index d2a4d1bb2d57..75964d734444 100644
|
||||
--- a/fs/buffer.c
|
||||
+++ b/fs/buffer.c
|
||||
@@ -620,14 +620,16 @@ EXPORT_SYMBOL(mark_buffer_dirty_inode);
|
||||
static void __set_page_dirty(struct page *page,
|
||||
struct address_space *mapping, int warn)
|
||||
{
|
||||
- spin_lock_irq(&mapping->tree_lock);
|
||||
+ unsigned long flags;
|
||||
+
|
||||
+ spin_lock_irqsave(&mapping->tree_lock, flags);
|
||||
if (page->mapping) { /* Race with truncate? */
|
||||
WARN_ON_ONCE(warn && !PageUptodate(page));
|
||||
account_page_dirtied(page, mapping);
|
||||
radix_tree_tag_set(&mapping->page_tree,
|
||||
page_index(page), PAGECACHE_TAG_DIRTY);
|
||||
}
|
||||
- spin_unlock_irq(&mapping->tree_lock);
|
||||
+ spin_unlock_irqrestore(&mapping->tree_lock, flags);
|
||||
__mark_inode_dirty(mapping->host, I_DIRTY_PAGES);
|
||||
}
|
||||
|
||||
diff --git a/lib/Makefile b/lib/Makefile
|
||||
index c55a037a354e..9efe480b975e 100644
|
||||
--- a/lib/Makefile
|
||||
+++ b/lib/Makefile
|
||||
@@ -45,6 +45,7 @@ lib-$(CONFIG_RWSEM_GENERIC_SPINLOCK) += rwsem-spinlock.o
|
||||
lib-$(CONFIG_RWSEM_XCHGADD_ALGORITHM) += rwsem.o
|
||||
lib-$(CONFIG_PERCPU_RWSEM) += percpu-rwsem.o
|
||||
|
||||
+GCOV_PROFILE_hweight.o := n
|
||||
CFLAGS_hweight.o = $(subst $(quote),,$(CONFIG_ARCH_HWEIGHT_CFLAGS))
|
||||
obj-$(CONFIG_GENERIC_HWEIGHT) += hweight.o
|
||||
|
||||
diff --git a/mm/hugetlb.c b/mm/hugetlb.c
|
||||
index 40ad2c6e0ca9..aa3b9a63394b 100644
|
||||
--- a/mm/hugetlb.c
|
||||
+++ b/mm/hugetlb.c
|
||||
@@ -21,6 +21,7 @@
|
||||
#include <linux/rmap.h>
|
||||
#include <linux/swap.h>
|
||||
#include <linux/swapops.h>
|
||||
+#include <linux/page-isolation.h>
|
||||
|
||||
#include <asm/page.h>
|
||||
#include <asm/pgtable.h>
|
||||
@@ -517,9 +518,15 @@ static struct page *dequeue_huge_page_node(struct hstate *h, int nid)
|
||||
{
|
||||
struct page *page;
|
||||
|
||||
- if (list_empty(&h->hugepage_freelists[nid]))
|
||||
+ list_for_each_entry(page, &h->hugepage_freelists[nid], lru)
|
||||
+ if (!is_migrate_isolate_page(page))
|
||||
+ break;
|
||||
+ /*
|
||||
+ * if 'non-isolated free hugepage' not found on the list,
|
||||
+ * the allocation fails.
|
||||
+ */
|
||||
+ if (&h->hugepage_freelists[nid] == &page->lru)
|
||||
return NULL;
|
||||
- page = list_entry(h->hugepage_freelists[nid].next, struct page, lru);
|
||||
list_move(&page->lru, &h->hugepage_activelist);
|
||||
set_page_refcounted(page);
|
||||
h->free_huge_pages--;
|
||||
diff --git a/mm/memory-failure.c b/mm/memory-failure.c
|
||||
index 3b4120e38d48..f2a591d87d00 100644
|
||||
--- a/mm/memory-failure.c
|
||||
+++ b/mm/memory-failure.c
|
||||
@@ -1421,7 +1421,8 @@ static int __get_any_page(struct page *p, unsigned long pfn, int flags)
|
||||
|
||||
/*
|
||||
* Isolate the page, so that it doesn't get reallocated if it
|
||||
- * was free.
|
||||
+ * was free. This flag should be kept set until the source page
|
||||
+ * is freed and PG_hwpoison on it is set.
|
||||
*/
|
||||
set_migratetype_isolate(p, true);
|
||||
/*
|
||||
@@ -1444,7 +1445,6 @@ static int __get_any_page(struct page *p, unsigned long pfn, int flags)
|
||||
/* Not a free page */
|
||||
ret = 1;
|
||||
}
|
||||
- unset_migratetype_isolate(p, MIGRATE_MOVABLE);
|
||||
unlock_memory_hotplug();
|
||||
return ret;
|
||||
}
|
||||
@@ -1511,7 +1511,6 @@ static int soft_offline_huge_page(struct page *page, int flags)
|
||||
atomic_long_inc(&num_poisoned_pages);
|
||||
}
|
||||
}
|
||||
- /* keep elevated page count for bad page */
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -1576,7 +1575,7 @@ int soft_offline_page(struct page *page, int flags)
|
||||
atomic_long_inc(&num_poisoned_pages);
|
||||
}
|
||||
}
|
||||
- /* keep elevated page count for bad page */
|
||||
+ unset_migratetype_isolate(page, MIGRATE_MOVABLE);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -1642,7 +1641,22 @@ static int __soft_offline_page(struct page *page, int flags)
|
||||
if (ret > 0)
|
||||
ret = -EIO;
|
||||
} else {
|
||||
+ /*
|
||||
+ * After page migration succeeds, the source page can
|
||||
+ * be trapped in pagevec and actual freeing is delayed.
|
||||
+ * Freeing code works differently based on PG_hwpoison,
|
||||
+ * so there's a race. We need to make sure that the
|
||||
+ * source page should be freed back to buddy before
|
||||
+ * setting PG_hwpoison.
|
||||
+ */
|
||||
+ if (!is_free_buddy_page(page))
|
||||
+ lru_add_drain_all();
|
||||
+ if (!is_free_buddy_page(page))
|
||||
+ drain_all_pages();
|
||||
SetPageHWPoison(page);
|
||||
+ if (!is_free_buddy_page(page))
|
||||
+ pr_info("soft offline: %#lx: page leaked\n",
|
||||
+ pfn);
|
||||
atomic_long_inc(&num_poisoned_pages);
|
||||
}
|
||||
} else {
|
||||
diff --git a/mm/page-writeback.c b/mm/page-writeback.c
|
||||
index 5a06d4cb9a3d..73cbc5dc150b 100644
|
||||
--- a/mm/page-writeback.c
|
||||
+++ b/mm/page-writeback.c
|
||||
@@ -2026,11 +2026,12 @@ int __set_page_dirty_nobuffers(struct page *page)
|
||||
if (!TestSetPageDirty(page)) {
|
||||
struct address_space *mapping = page_mapping(page);
|
||||
struct address_space *mapping2;
|
||||
+ unsigned long flags;
|
||||
|
||||
if (!mapping)
|
||||
return 1;
|
||||
|
||||
- spin_lock_irq(&mapping->tree_lock);
|
||||
+ spin_lock_irqsave(&mapping->tree_lock, flags);
|
||||
mapping2 = page_mapping(page);
|
||||
if (mapping2) { /* Race with truncate? */
|
||||
BUG_ON(mapping2 != mapping);
|
||||
@@ -2039,7 +2040,7 @@ int __set_page_dirty_nobuffers(struct page *page)
|
||||
radix_tree_tag_set(&mapping->page_tree,
|
||||
page_index(page), PAGECACHE_TAG_DIRTY);
|
||||
}
|
||||
- spin_unlock_irq(&mapping->tree_lock);
|
||||
+ spin_unlock_irqrestore(&mapping->tree_lock, flags);
|
||||
if (mapping->host) {
|
||||
/* !PageAnon && !swapper_space */
|
||||
__mark_inode_dirty(mapping->host, I_DIRTY_PAGES);
|
||||
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
|
||||
index b4feecc3fe01..18caa16de27b 100644
|
||||
--- a/security/selinux/ss/services.c
|
||||
+++ b/security/selinux/ss/services.c
|
||||
@@ -1231,6 +1231,10 @@ static int security_context_to_sid_core(const char *scontext, u32 scontext_len,
|
||||
struct context context;
|
||||
int rc = 0;
|
||||
|
||||
+ /* An empty security context is never valid. */
|
||||
+ if (!scontext_len)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
if (!ss_initialized) {
|
||||
int i;
|
||||
|
||||
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c
|
||||
index a7b07f72c9dd..5a6527668c07 100644
|
||||
--- a/sound/pci/hda/patch_analog.c
|
||||
+++ b/sound/pci/hda/patch_analog.c
|
||||
@@ -1680,6 +1680,7 @@ static int ad1983_parse_auto_config(struct hda_codec *codec)
|
||||
return err;
|
||||
spec = codec->spec;
|
||||
|
||||
+ spec->gen.mixer_nid = 0x0e;
|
||||
spec->gen.beep_nid = 0x10;
|
||||
set_beep_amp(spec, 0x10, 0, HDA_OUTPUT);
|
||||
err = ad198x_parse_auto_config(codec);
|
||||
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
|
||||
index 4b06e0a64392..87a03aca1b2e 100644
|
||||
--- a/sound/pci/hda/patch_realtek.c
|
||||
+++ b/sound/pci/hda/patch_realtek.c
|
||||
@@ -1765,6 +1765,7 @@ enum {
|
||||
ALC889_FIXUP_IMAC91_VREF,
|
||||
ALC889_FIXUP_MBA11_VREF,
|
||||
ALC889_FIXUP_MBA21_VREF,
|
||||
+ ALC889_FIXUP_MP11_VREF,
|
||||
ALC882_FIXUP_INV_DMIC,
|
||||
ALC882_FIXUP_NO_PRIMARY_HP,
|
||||
ALC887_FIXUP_ASUS_BASS,
|
||||
@@ -2119,6 +2120,12 @@ static const struct hda_fixup alc882_fixups[] = {
|
||||
.chained = true,
|
||||
.chain_id = ALC889_FIXUP_MBP_VREF,
|
||||
},
|
||||
+ [ALC889_FIXUP_MP11_VREF] = {
|
||||
+ .type = HDA_FIXUP_FUNC,
|
||||
+ .v.func = alc889_fixup_mba11_vref,
|
||||
+ .chained = true,
|
||||
+ .chain_id = ALC885_FIXUP_MACPRO_GPIO,
|
||||
+ },
|
||||
[ALC882_FIXUP_INV_DMIC] = {
|
||||
.type = HDA_FIXUP_FUNC,
|
||||
.v.func = alc_fixup_inv_dmic_0x12,
|
||||
@@ -2176,7 +2183,7 @@ static const struct snd_pci_quirk alc882_fixup_tbl[] = {
|
||||
SND_PCI_QUIRK(0x106b, 0x00a0, "MacBookPro 3,1", ALC889_FIXUP_MBP_VREF),
|
||||
SND_PCI_QUIRK(0x106b, 0x00a1, "Macbook", ALC889_FIXUP_MBP_VREF),
|
||||
SND_PCI_QUIRK(0x106b, 0x00a4, "MacbookPro 4,1", ALC889_FIXUP_MBP_VREF),
|
||||
- SND_PCI_QUIRK(0x106b, 0x0c00, "Mac Pro", ALC885_FIXUP_MACPRO_GPIO),
|
||||
+ SND_PCI_QUIRK(0x106b, 0x0c00, "Mac Pro", ALC889_FIXUP_MP11_VREF),
|
||||
SND_PCI_QUIRK(0x106b, 0x1000, "iMac 24", ALC885_FIXUP_MACPRO_GPIO),
|
||||
SND_PCI_QUIRK(0x106b, 0x2800, "AppleTV", ALC885_FIXUP_MACPRO_GPIO),
|
||||
SND_PCI_QUIRK(0x106b, 0x2c00, "MacbookPro rev3", ALC889_FIXUP_MBP_VREF),
|
||||
diff --git a/sound/usb/Kconfig b/sound/usb/Kconfig
|
||||
index 225dfd737265..ba2664200d14 100644
|
||||
--- a/sound/usb/Kconfig
|
||||
+++ b/sound/usb/Kconfig
|
||||
@@ -14,6 +14,7 @@ config SND_USB_AUDIO
|
||||
select SND_HWDEP
|
||||
select SND_RAWMIDI
|
||||
select SND_PCM
|
||||
+ select BITREVERSE
|
||||
help
|
||||
Say Y here to include support for USB audio and USB MIDI
|
||||
devices.
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,996 +0,0 @@
|
||||
diff --git a/Makefile b/Makefile
|
||||
index 571a1bf14868..06b31fce1ff5 100644
|
||||
--- a/Makefile
|
||||
+++ b/Makefile
|
||||
@@ -1,6 +1,6 @@
|
||||
VERSION = 3
|
||||
PATCHLEVEL = 10
|
||||
-SUBLEVEL = 34
|
||||
+SUBLEVEL = 35
|
||||
EXTRAVERSION =
|
||||
NAME = TOSSUG Baby Fish
|
||||
|
||||
diff --git a/arch/arm/include/asm/outercache.h b/arch/arm/include/asm/outercache.h
|
||||
index 12f71a190422..f94784f0e3a6 100644
|
||||
--- a/arch/arm/include/asm/outercache.h
|
||||
+++ b/arch/arm/include/asm/outercache.h
|
||||
@@ -37,10 +37,10 @@ struct outer_cache_fns {
|
||||
void (*resume)(void);
|
||||
};
|
||||
|
||||
-#ifdef CONFIG_OUTER_CACHE
|
||||
-
|
||||
extern struct outer_cache_fns outer_cache;
|
||||
|
||||
+#ifdef CONFIG_OUTER_CACHE
|
||||
+
|
||||
static inline void outer_inv_range(phys_addr_t start, phys_addr_t end)
|
||||
{
|
||||
if (outer_cache.inv_range)
|
||||
diff --git a/arch/arm/mach-highbank/highbank.c b/arch/arm/mach-highbank/highbank.c
|
||||
index 5ed19e88874b..35d1029d7c9d 100644
|
||||
--- a/arch/arm/mach-highbank/highbank.c
|
||||
+++ b/arch/arm/mach-highbank/highbank.c
|
||||
@@ -65,14 +65,12 @@ void highbank_set_cpu_jump(int cpu, void *jump_addr)
|
||||
HB_JUMP_TABLE_PHYS(cpu) + 15);
|
||||
}
|
||||
|
||||
-#ifdef CONFIG_CACHE_L2X0
|
||||
static void highbank_l2x0_disable(void)
|
||||
{
|
||||
outer_flush_all();
|
||||
/* Disable PL310 L2 Cache controller */
|
||||
highbank_smc1(0x102, 0x0);
|
||||
}
|
||||
-#endif
|
||||
|
||||
static void __init highbank_init_irq(void)
|
||||
{
|
||||
@@ -81,12 +79,13 @@ static void __init highbank_init_irq(void)
|
||||
if (of_find_compatible_node(NULL, NULL, "arm,cortex-a9"))
|
||||
highbank_scu_map_io();
|
||||
|
||||
-#ifdef CONFIG_CACHE_L2X0
|
||||
/* Enable PL310 L2 Cache controller */
|
||||
- highbank_smc1(0x102, 0x1);
|
||||
- l2x0_of_init(0, ~0UL);
|
||||
- outer_cache.disable = highbank_l2x0_disable;
|
||||
-#endif
|
||||
+ if (IS_ENABLED(CONFIG_CACHE_L2X0) &&
|
||||
+ of_find_compatible_node(NULL, NULL, "arm,pl310-cache")) {
|
||||
+ highbank_smc1(0x102, 0x1);
|
||||
+ l2x0_of_init(0, ~0UL);
|
||||
+ outer_cache.disable = highbank_l2x0_disable;
|
||||
+ }
|
||||
}
|
||||
|
||||
static void __init highbank_timer_init(void)
|
||||
diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c
|
||||
index 004cc87b781c..711c649f80b7 100644
|
||||
--- a/arch/x86/kvm/mmu.c
|
||||
+++ b/arch/x86/kvm/mmu.c
|
||||
@@ -2585,6 +2585,9 @@ static int __direct_map(struct kvm_vcpu *vcpu, gpa_t v, int write,
|
||||
int emulate = 0;
|
||||
gfn_t pseudo_gfn;
|
||||
|
||||
+ if (!VALID_PAGE(vcpu->arch.mmu.root_hpa))
|
||||
+ return 0;
|
||||
+
|
||||
for_each_shadow_entry(vcpu, (u64)gfn << PAGE_SHIFT, iterator) {
|
||||
if (iterator.level == level) {
|
||||
mmu_set_spte(vcpu, iterator.sptep, ACC_ALL,
|
||||
@@ -2748,6 +2751,9 @@ static bool fast_page_fault(struct kvm_vcpu *vcpu, gva_t gva, int level,
|
||||
bool ret = false;
|
||||
u64 spte = 0ull;
|
||||
|
||||
+ if (!VALID_PAGE(vcpu->arch.mmu.root_hpa))
|
||||
+ return false;
|
||||
+
|
||||
if (!page_fault_can_be_fast(vcpu, error_code))
|
||||
return false;
|
||||
|
||||
@@ -3139,6 +3145,9 @@ static u64 walk_shadow_page_get_mmio_spte(struct kvm_vcpu *vcpu, u64 addr)
|
||||
struct kvm_shadow_walk_iterator iterator;
|
||||
u64 spte = 0ull;
|
||||
|
||||
+ if (!VALID_PAGE(vcpu->arch.mmu.root_hpa))
|
||||
+ return spte;
|
||||
+
|
||||
walk_shadow_page_lockless_begin(vcpu);
|
||||
for_each_shadow_entry_lockless(vcpu, addr, iterator, spte)
|
||||
if (!is_shadow_present_pte(spte))
|
||||
@@ -4329,6 +4338,9 @@ int kvm_mmu_get_spte_hierarchy(struct kvm_vcpu *vcpu, u64 addr, u64 sptes[4])
|
||||
u64 spte;
|
||||
int nr_sptes = 0;
|
||||
|
||||
+ if (!VALID_PAGE(vcpu->arch.mmu.root_hpa))
|
||||
+ return nr_sptes;
|
||||
+
|
||||
walk_shadow_page_lockless_begin(vcpu);
|
||||
for_each_shadow_entry_lockless(vcpu, addr, iterator, spte) {
|
||||
sptes[iterator.level-1] = spte;
|
||||
diff --git a/arch/x86/kvm/paging_tmpl.h b/arch/x86/kvm/paging_tmpl.h
|
||||
index da20860b457a..7e6090e13237 100644
|
||||
--- a/arch/x86/kvm/paging_tmpl.h
|
||||
+++ b/arch/x86/kvm/paging_tmpl.h
|
||||
@@ -423,6 +423,9 @@ static int FNAME(fetch)(struct kvm_vcpu *vcpu, gva_t addr,
|
||||
if (FNAME(gpte_changed)(vcpu, gw, top_level))
|
||||
goto out_gpte_changed;
|
||||
|
||||
+ if (!VALID_PAGE(vcpu->arch.mmu.root_hpa))
|
||||
+ goto out_gpte_changed;
|
||||
+
|
||||
for (shadow_walk_init(&it, vcpu, addr);
|
||||
shadow_walk_okay(&it) && it.level > gw->level;
|
||||
shadow_walk_next(&it)) {
|
||||
@@ -671,6 +674,11 @@ static void FNAME(invlpg)(struct kvm_vcpu *vcpu, gva_t gva)
|
||||
*/
|
||||
mmu_topup_memory_caches(vcpu);
|
||||
|
||||
+ if (!VALID_PAGE(vcpu->arch.mmu.root_hpa)) {
|
||||
+ WARN_ON(1);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
spin_lock(&vcpu->kvm->mmu_lock);
|
||||
for_each_shadow_entry(vcpu, gva, iterator) {
|
||||
level = iterator.level;
|
||||
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
|
||||
index 5402c94ab768..7cdafb6dc705 100644
|
||||
--- a/arch/x86/kvm/vmx.c
|
||||
+++ b/arch/x86/kvm/vmx.c
|
||||
@@ -7133,8 +7133,8 @@ static void vmx_free_vcpu(struct kvm_vcpu *vcpu)
|
||||
struct vcpu_vmx *vmx = to_vmx(vcpu);
|
||||
|
||||
free_vpid(vmx);
|
||||
- free_nested(vmx);
|
||||
free_loaded_vmcs(vmx->loaded_vmcs);
|
||||
+ free_nested(vmx);
|
||||
kfree(vmx->guest_msrs);
|
||||
kvm_vcpu_uninit(vcpu);
|
||||
kmem_cache_free(kvm_vcpu_cache, vmx);
|
||||
diff --git a/arch/x86/net/bpf_jit.S b/arch/x86/net/bpf_jit.S
|
||||
index 877b9a1b2152..01495755701b 100644
|
||||
--- a/arch/x86/net/bpf_jit.S
|
||||
+++ b/arch/x86/net/bpf_jit.S
|
||||
@@ -140,7 +140,7 @@ bpf_slow_path_byte_msh:
|
||||
push %r9; \
|
||||
push SKBDATA; \
|
||||
/* rsi already has offset */ \
|
||||
- mov $SIZE,%ecx; /* size */ \
|
||||
+ mov $SIZE,%edx; /* size */ \
|
||||
call bpf_internal_load_pointer_neg_helper; \
|
||||
test %rax,%rax; \
|
||||
pop SKBDATA; \
|
||||
diff --git a/drivers/input/mouse/elantech.c b/drivers/input/mouse/elantech.c
|
||||
index 1e8e42fb03a4..1fb1a7b5a754 100644
|
||||
--- a/drivers/input/mouse/elantech.c
|
||||
+++ b/drivers/input/mouse/elantech.c
|
||||
@@ -486,6 +486,7 @@ static void elantech_input_sync_v4(struct psmouse *psmouse)
|
||||
unsigned char *packet = psmouse->packet;
|
||||
|
||||
input_report_key(dev, BTN_LEFT, packet[0] & 0x01);
|
||||
+ input_report_key(dev, BTN_RIGHT, packet[0] & 0x02);
|
||||
input_mt_report_pointer_emulation(dev, true);
|
||||
input_sync(dev);
|
||||
}
|
||||
@@ -954,6 +955,44 @@ static int elantech_get_resolution_v4(struct psmouse *psmouse,
|
||||
}
|
||||
|
||||
/*
|
||||
+ * Advertise INPUT_PROP_BUTTONPAD for clickpads. The testing of bit 12 in
|
||||
+ * fw_version for this is based on the following fw_version & caps table:
|
||||
+ *
|
||||
+ * Laptop-model: fw_version: caps: buttons:
|
||||
+ * Acer S3 0x461f00 10, 13, 0e clickpad
|
||||
+ * Acer S7-392 0x581f01 50, 17, 0d clickpad
|
||||
+ * Acer V5-131 0x461f02 01, 16, 0c clickpad
|
||||
+ * Acer V5-551 0x461f00 ? clickpad
|
||||
+ * Asus K53SV 0x450f01 78, 15, 0c 2 hw buttons
|
||||
+ * Asus G46VW 0x460f02 00, 18, 0c 2 hw buttons
|
||||
+ * Asus G750JX 0x360f00 00, 16, 0c 2 hw buttons
|
||||
+ * Asus UX31 0x361f00 20, 15, 0e clickpad
|
||||
+ * Asus UX32VD 0x361f02 00, 15, 0e clickpad
|
||||
+ * Avatar AVIU-145A2 0x361f00 ? clickpad
|
||||
+ * Gigabyte U2442 0x450f01 58, 17, 0c 2 hw buttons
|
||||
+ * Lenovo L430 0x350f02 b9, 15, 0c 2 hw buttons (*)
|
||||
+ * Samsung NF210 0x150b00 78, 14, 0a 2 hw buttons
|
||||
+ * Samsung NP770Z5E 0x575f01 10, 15, 0f clickpad
|
||||
+ * Samsung NP700Z5B 0x361f06 21, 15, 0f clickpad
|
||||
+ * Samsung NP900X3E-A02 0x575f03 ? clickpad
|
||||
+ * Samsung NP-QX410 0x851b00 19, 14, 0c clickpad
|
||||
+ * Samsung RC512 0x450f00 08, 15, 0c 2 hw buttons
|
||||
+ * Samsung RF710 0x450f00 ? 2 hw buttons
|
||||
+ * System76 Pangolin 0x250f01 ? 2 hw buttons
|
||||
+ * (*) + 3 trackpoint buttons
|
||||
+ */
|
||||
+static void elantech_set_buttonpad_prop(struct psmouse *psmouse)
|
||||
+{
|
||||
+ struct input_dev *dev = psmouse->dev;
|
||||
+ struct elantech_data *etd = psmouse->private;
|
||||
+
|
||||
+ if (etd->fw_version & 0x001000) {
|
||||
+ __set_bit(INPUT_PROP_BUTTONPAD, dev->propbit);
|
||||
+ __clear_bit(BTN_RIGHT, dev->keybit);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
* Set the appropriate event bits for the input subsystem
|
||||
*/
|
||||
static int elantech_set_input_params(struct psmouse *psmouse)
|
||||
@@ -996,6 +1035,8 @@ static int elantech_set_input_params(struct psmouse *psmouse)
|
||||
__set_bit(INPUT_PROP_SEMI_MT, dev->propbit);
|
||||
/* fall through */
|
||||
case 3:
|
||||
+ if (etd->hw_version == 3)
|
||||
+ elantech_set_buttonpad_prop(psmouse);
|
||||
input_set_abs_params(dev, ABS_X, x_min, x_max, 0, 0);
|
||||
input_set_abs_params(dev, ABS_Y, y_min, y_max, 0, 0);
|
||||
if (etd->reports_pressure) {
|
||||
@@ -1017,9 +1058,7 @@ static int elantech_set_input_params(struct psmouse *psmouse)
|
||||
*/
|
||||
psmouse_warn(psmouse, "couldn't query resolution data.\n");
|
||||
}
|
||||
- /* v4 is clickpad, with only one button. */
|
||||
- __set_bit(INPUT_PROP_BUTTONPAD, dev->propbit);
|
||||
- __clear_bit(BTN_RIGHT, dev->keybit);
|
||||
+ elantech_set_buttonpad_prop(psmouse);
|
||||
__set_bit(BTN_TOOL_QUADTAP, dev->keybit);
|
||||
/* For X to recognize me as touchpad. */
|
||||
input_set_abs_params(dev, ABS_X, x_min, x_max, 0, 0);
|
||||
diff --git a/drivers/input/tablet/wacom_sys.c b/drivers/input/tablet/wacom_sys.c
|
||||
index aaf23aeae2ea..3d838c0b495d 100644
|
||||
--- a/drivers/input/tablet/wacom_sys.c
|
||||
+++ b/drivers/input/tablet/wacom_sys.c
|
||||
@@ -339,7 +339,7 @@ static int wacom_parse_hid(struct usb_interface *intf,
|
||||
struct usb_device *dev = interface_to_usbdev(intf);
|
||||
char limit = 0;
|
||||
/* result has to be defined as int for some devices */
|
||||
- int result = 0;
|
||||
+ int result = 0, touch_max = 0;
|
||||
int i = 0, usage = WCM_UNDEFINED, finger = 0, pen = 0;
|
||||
unsigned char *report;
|
||||
|
||||
@@ -386,7 +386,8 @@ static int wacom_parse_hid(struct usb_interface *intf,
|
||||
if (usage == WCM_DESKTOP) {
|
||||
if (finger) {
|
||||
features->device_type = BTN_TOOL_FINGER;
|
||||
-
|
||||
+ /* touch device at least supports one touch point */
|
||||
+ touch_max = 1;
|
||||
switch (features->type) {
|
||||
case TABLETPC2FG:
|
||||
features->pktlen = WACOM_PKGLEN_TPC2FG;
|
||||
@@ -539,6 +540,8 @@ static int wacom_parse_hid(struct usb_interface *intf,
|
||||
}
|
||||
|
||||
out:
|
||||
+ if (!features->touch_max && touch_max)
|
||||
+ features->touch_max = touch_max;
|
||||
result = 0;
|
||||
kfree(report);
|
||||
return result;
|
||||
diff --git a/drivers/media/pci/cx18/cx18-driver.c b/drivers/media/pci/cx18/cx18-driver.c
|
||||
index 13c9718a5ace..16e89f026bca 100644
|
||||
--- a/drivers/media/pci/cx18/cx18-driver.c
|
||||
+++ b/drivers/media/pci/cx18/cx18-driver.c
|
||||
@@ -327,13 +327,16 @@ void cx18_read_eeprom(struct cx18 *cx, struct tveeprom *tv)
|
||||
struct i2c_client *c;
|
||||
u8 eedata[256];
|
||||
|
||||
+ memset(tv, 0, sizeof(*tv));
|
||||
+
|
||||
c = kzalloc(sizeof(*c), GFP_KERNEL);
|
||||
+ if (!c)
|
||||
+ return;
|
||||
|
||||
strlcpy(c->name, "cx18 tveeprom tmp", sizeof(c->name));
|
||||
c->adapter = &cx->i2c_adap[0];
|
||||
c->addr = 0xa0 >> 1;
|
||||
|
||||
- memset(tv, 0, sizeof(*tv));
|
||||
if (tveeprom_read(c, eedata, sizeof(eedata)))
|
||||
goto ret;
|
||||
|
||||
diff --git a/drivers/media/usb/dvb-usb/cxusb.c b/drivers/media/usb/dvb-usb/cxusb.c
|
||||
index 20e345d9fe8f..a1c641e18362 100644
|
||||
--- a/drivers/media/usb/dvb-usb/cxusb.c
|
||||
+++ b/drivers/media/usb/dvb-usb/cxusb.c
|
||||
@@ -149,6 +149,7 @@ static int cxusb_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
|
||||
int num)
|
||||
{
|
||||
struct dvb_usb_device *d = i2c_get_adapdata(adap);
|
||||
+ int ret;
|
||||
int i;
|
||||
|
||||
if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
|
||||
@@ -173,7 +174,8 @@ static int cxusb_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
|
||||
if (1 + msg[i].len > sizeof(ibuf)) {
|
||||
warn("i2c rd: len=%d is too big!\n",
|
||||
msg[i].len);
|
||||
- return -EOPNOTSUPP;
|
||||
+ ret = -EOPNOTSUPP;
|
||||
+ goto unlock;
|
||||
}
|
||||
obuf[0] = 0;
|
||||
obuf[1] = msg[i].len;
|
||||
@@ -193,12 +195,14 @@ static int cxusb_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
|
||||
if (3 + msg[i].len > sizeof(obuf)) {
|
||||
warn("i2c wr: len=%d is too big!\n",
|
||||
msg[i].len);
|
||||
- return -EOPNOTSUPP;
|
||||
+ ret = -EOPNOTSUPP;
|
||||
+ goto unlock;
|
||||
}
|
||||
if (1 + msg[i + 1].len > sizeof(ibuf)) {
|
||||
warn("i2c rd: len=%d is too big!\n",
|
||||
msg[i + 1].len);
|
||||
- return -EOPNOTSUPP;
|
||||
+ ret = -EOPNOTSUPP;
|
||||
+ goto unlock;
|
||||
}
|
||||
obuf[0] = msg[i].len;
|
||||
obuf[1] = msg[i+1].len;
|
||||
@@ -223,7 +227,8 @@ static int cxusb_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
|
||||
if (2 + msg[i].len > sizeof(obuf)) {
|
||||
warn("i2c wr: len=%d is too big!\n",
|
||||
msg[i].len);
|
||||
- return -EOPNOTSUPP;
|
||||
+ ret = -EOPNOTSUPP;
|
||||
+ goto unlock;
|
||||
}
|
||||
obuf[0] = msg[i].addr;
|
||||
obuf[1] = msg[i].len;
|
||||
@@ -237,8 +242,14 @@ static int cxusb_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
|
||||
}
|
||||
}
|
||||
|
||||
+ if (i == num)
|
||||
+ ret = num;
|
||||
+ else
|
||||
+ ret = -EREMOTEIO;
|
||||
+
|
||||
+unlock:
|
||||
mutex_unlock(&d->i2c_mutex);
|
||||
- return i == num ? num : -EREMOTEIO;
|
||||
+ return ret;
|
||||
}
|
||||
|
||||
static u32 cxusb_i2c_func(struct i2c_adapter *adapter)
|
||||
diff --git a/drivers/media/usb/dvb-usb/dw2102.c b/drivers/media/usb/dvb-usb/dw2102.c
|
||||
index 71b22f5a05ce..4170a45d17e0 100644
|
||||
--- a/drivers/media/usb/dvb-usb/dw2102.c
|
||||
+++ b/drivers/media/usb/dvb-usb/dw2102.c
|
||||
@@ -301,6 +301,7 @@ static int dw2102_serit_i2c_transfer(struct i2c_adapter *adap,
|
||||
static int dw2102_earda_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], int num)
|
||||
{
|
||||
struct dvb_usb_device *d = i2c_get_adapdata(adap);
|
||||
+ int ret;
|
||||
|
||||
if (!d)
|
||||
return -ENODEV;
|
||||
@@ -316,7 +317,8 @@ static int dw2102_earda_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg ms
|
||||
if (2 + msg[1].len > sizeof(ibuf)) {
|
||||
warn("i2c rd: len=%d is too big!\n",
|
||||
msg[1].len);
|
||||
- return -EOPNOTSUPP;
|
||||
+ ret = -EOPNOTSUPP;
|
||||
+ goto unlock;
|
||||
}
|
||||
|
||||
obuf[0] = msg[0].addr << 1;
|
||||
@@ -340,7 +342,8 @@ static int dw2102_earda_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg ms
|
||||
if (2 + msg[0].len > sizeof(obuf)) {
|
||||
warn("i2c wr: len=%d is too big!\n",
|
||||
msg[1].len);
|
||||
- return -EOPNOTSUPP;
|
||||
+ ret = -EOPNOTSUPP;
|
||||
+ goto unlock;
|
||||
}
|
||||
|
||||
obuf[0] = msg[0].addr << 1;
|
||||
@@ -357,7 +360,8 @@ static int dw2102_earda_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg ms
|
||||
if (2 + msg[0].len > sizeof(obuf)) {
|
||||
warn("i2c wr: len=%d is too big!\n",
|
||||
msg[1].len);
|
||||
- return -EOPNOTSUPP;
|
||||
+ ret = -EOPNOTSUPP;
|
||||
+ goto unlock;
|
||||
}
|
||||
|
||||
obuf[0] = msg[0].addr << 1;
|
||||
@@ -386,15 +390,17 @@ static int dw2102_earda_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg ms
|
||||
|
||||
break;
|
||||
}
|
||||
+ ret = num;
|
||||
|
||||
+unlock:
|
||||
mutex_unlock(&d->i2c_mutex);
|
||||
- return num;
|
||||
+ return ret;
|
||||
}
|
||||
|
||||
static int dw2104_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], int num)
|
||||
{
|
||||
struct dvb_usb_device *d = i2c_get_adapdata(adap);
|
||||
- int len, i, j;
|
||||
+ int len, i, j, ret;
|
||||
|
||||
if (!d)
|
||||
return -ENODEV;
|
||||
@@ -430,7 +436,8 @@ static int dw2104_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], i
|
||||
if (2 + msg[j].len > sizeof(ibuf)) {
|
||||
warn("i2c rd: len=%d is too big!\n",
|
||||
msg[j].len);
|
||||
- return -EOPNOTSUPP;
|
||||
+ ret = -EOPNOTSUPP;
|
||||
+ goto unlock;
|
||||
}
|
||||
|
||||
dw210x_op_rw(d->udev, 0xc3,
|
||||
@@ -466,7 +473,8 @@ static int dw2104_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], i
|
||||
if (2 + msg[j].len > sizeof(obuf)) {
|
||||
warn("i2c wr: len=%d is too big!\n",
|
||||
msg[j].len);
|
||||
- return -EOPNOTSUPP;
|
||||
+ ret = -EOPNOTSUPP;
|
||||
+ goto unlock;
|
||||
}
|
||||
|
||||
obuf[0] = msg[j].addr << 1;
|
||||
@@ -481,15 +489,18 @@ static int dw2104_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], i
|
||||
}
|
||||
|
||||
}
|
||||
+ ret = num;
|
||||
|
||||
+unlock:
|
||||
mutex_unlock(&d->i2c_mutex);
|
||||
- return num;
|
||||
+ return ret;
|
||||
}
|
||||
|
||||
static int dw3101_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
|
||||
int num)
|
||||
{
|
||||
struct dvb_usb_device *d = i2c_get_adapdata(adap);
|
||||
+ int ret;
|
||||
int i;
|
||||
|
||||
if (!d)
|
||||
@@ -506,7 +517,8 @@ static int dw3101_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
|
||||
if (2 + msg[1].len > sizeof(ibuf)) {
|
||||
warn("i2c rd: len=%d is too big!\n",
|
||||
msg[1].len);
|
||||
- return -EOPNOTSUPP;
|
||||
+ ret = -EOPNOTSUPP;
|
||||
+ goto unlock;
|
||||
}
|
||||
obuf[0] = msg[0].addr << 1;
|
||||
obuf[1] = msg[0].len;
|
||||
@@ -530,7 +542,8 @@ static int dw3101_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
|
||||
if (2 + msg[0].len > sizeof(obuf)) {
|
||||
warn("i2c wr: len=%d is too big!\n",
|
||||
msg[0].len);
|
||||
- return -EOPNOTSUPP;
|
||||
+ ret = -EOPNOTSUPP;
|
||||
+ goto unlock;
|
||||
}
|
||||
obuf[0] = msg[0].addr << 1;
|
||||
obuf[1] = msg[0].len;
|
||||
@@ -556,9 +569,11 @@ static int dw3101_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
|
||||
msg[i].flags == 0 ? ">>>" : "<<<");
|
||||
debug_dump(msg[i].buf, msg[i].len, deb_xfer);
|
||||
}
|
||||
+ ret = num;
|
||||
|
||||
+unlock:
|
||||
mutex_unlock(&d->i2c_mutex);
|
||||
- return num;
|
||||
+ return ret;
|
||||
}
|
||||
|
||||
static int s6x0_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
|
||||
@@ -566,7 +581,7 @@ static int s6x0_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
|
||||
{
|
||||
struct dvb_usb_device *d = i2c_get_adapdata(adap);
|
||||
struct usb_device *udev;
|
||||
- int len, i, j;
|
||||
+ int len, i, j, ret;
|
||||
|
||||
if (!d)
|
||||
return -ENODEV;
|
||||
@@ -618,7 +633,8 @@ static int s6x0_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
|
||||
if (msg[j].len > sizeof(ibuf)) {
|
||||
warn("i2c rd: len=%d is too big!\n",
|
||||
msg[j].len);
|
||||
- return -EOPNOTSUPP;
|
||||
+ ret = -EOPNOTSUPP;
|
||||
+ goto unlock;
|
||||
}
|
||||
|
||||
dw210x_op_rw(d->udev, 0x91, 0, 0,
|
||||
@@ -652,7 +668,8 @@ static int s6x0_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
|
||||
if (2 + msg[j].len > sizeof(obuf)) {
|
||||
warn("i2c wr: len=%d is too big!\n",
|
||||
msg[j].len);
|
||||
- return -EOPNOTSUPP;
|
||||
+ ret = -EOPNOTSUPP;
|
||||
+ goto unlock;
|
||||
}
|
||||
|
||||
obuf[0] = msg[j + 1].len;
|
||||
@@ -671,7 +688,8 @@ static int s6x0_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
|
||||
if (2 + msg[j].len > sizeof(obuf)) {
|
||||
warn("i2c wr: len=%d is too big!\n",
|
||||
msg[j].len);
|
||||
- return -EOPNOTSUPP;
|
||||
+ ret = -EOPNOTSUPP;
|
||||
+ goto unlock;
|
||||
}
|
||||
obuf[0] = msg[j].len + 1;
|
||||
obuf[1] = (msg[j].addr << 1);
|
||||
@@ -685,9 +703,11 @@ static int s6x0_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
|
||||
}
|
||||
}
|
||||
}
|
||||
+ ret = num;
|
||||
|
||||
+unlock:
|
||||
mutex_unlock(&d->i2c_mutex);
|
||||
- return num;
|
||||
+ return ret;
|
||||
}
|
||||
|
||||
static int su3000_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
|
||||
diff --git a/drivers/net/ethernet/intel/e100.c b/drivers/net/ethernet/intel/e100.c
|
||||
index d2bea3f07c73..69d3f59f8728 100644
|
||||
--- a/drivers/net/ethernet/intel/e100.c
|
||||
+++ b/drivers/net/ethernet/intel/e100.c
|
||||
@@ -3039,7 +3039,7 @@ static void __e100_shutdown(struct pci_dev *pdev, bool *enable_wake)
|
||||
*enable_wake = false;
|
||||
}
|
||||
|
||||
- pci_disable_device(pdev);
|
||||
+ pci_clear_master(pdev);
|
||||
}
|
||||
|
||||
static int __e100_power_off(struct pci_dev *pdev, bool wake)
|
||||
diff --git a/drivers/net/wireless/p54/txrx.c b/drivers/net/wireless/p54/txrx.c
|
||||
index f95de0d16216..1de59b0f8fa8 100644
|
||||
--- a/drivers/net/wireless/p54/txrx.c
|
||||
+++ b/drivers/net/wireless/p54/txrx.c
|
||||
@@ -587,7 +587,7 @@ static void p54_rx_stats(struct p54_common *priv, struct sk_buff *skb)
|
||||
chan = priv->curchan;
|
||||
if (chan) {
|
||||
struct survey_info *survey = &priv->survey[chan->hw_value];
|
||||
- survey->noise = clamp_t(s8, priv->noise, -128, 127);
|
||||
+ survey->noise = clamp(priv->noise, -128, 127);
|
||||
survey->channel_time = priv->survey_raw.active;
|
||||
survey->channel_time_tx = priv->survey_raw.tx;
|
||||
survey->channel_time_busy = priv->survey_raw.tx +
|
||||
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
|
||||
index c59cc6ed7adb..a86d12326137 100644
|
||||
--- a/drivers/regulator/core.c
|
||||
+++ b/drivers/regulator/core.c
|
||||
@@ -1712,8 +1712,6 @@ static int _regulator_do_disable(struct regulator_dev *rdev)
|
||||
|
||||
trace_regulator_disable_complete(rdev_get_name(rdev));
|
||||
|
||||
- _notifier_call_chain(rdev, REGULATOR_EVENT_DISABLE,
|
||||
- NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1737,6 +1735,8 @@ static int _regulator_disable(struct regulator_dev *rdev)
|
||||
rdev_err(rdev, "failed to disable\n");
|
||||
return ret;
|
||||
}
|
||||
+ _notifier_call_chain(rdev, REGULATOR_EVENT_DISABLE,
|
||||
+ NULL);
|
||||
}
|
||||
|
||||
rdev->use_count = 0;
|
||||
@@ -1789,20 +1789,16 @@ static int _regulator_force_disable(struct regulator_dev *rdev)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
- /* force disable */
|
||||
- if (rdev->desc->ops->disable) {
|
||||
- /* ah well, who wants to live forever... */
|
||||
- ret = rdev->desc->ops->disable(rdev);
|
||||
- if (ret < 0) {
|
||||
- rdev_err(rdev, "failed to force disable\n");
|
||||
- return ret;
|
||||
- }
|
||||
- /* notify other consumers that power has been forced off */
|
||||
- _notifier_call_chain(rdev, REGULATOR_EVENT_FORCE_DISABLE |
|
||||
- REGULATOR_EVENT_DISABLE, NULL);
|
||||
+ ret = _regulator_do_disable(rdev);
|
||||
+ if (ret < 0) {
|
||||
+ rdev_err(rdev, "failed to force disable\n");
|
||||
+ return ret;
|
||||
}
|
||||
|
||||
- return ret;
|
||||
+ _notifier_call_chain(rdev, REGULATOR_EVENT_FORCE_DISABLE |
|
||||
+ REGULATOR_EVENT_DISABLE, NULL);
|
||||
+
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -3788,8 +3784,6 @@ int regulator_suspend_finish(void)
|
||||
|
||||
mutex_lock(®ulator_list_mutex);
|
||||
list_for_each_entry(rdev, ®ulator_list, list) {
|
||||
- struct regulator_ops *ops = rdev->desc->ops;
|
||||
-
|
||||
mutex_lock(&rdev->mutex);
|
||||
if (rdev->use_count > 0 || rdev->constraints->always_on) {
|
||||
error = _regulator_do_enable(rdev);
|
||||
@@ -3798,12 +3792,10 @@ int regulator_suspend_finish(void)
|
||||
} else {
|
||||
if (!has_full_constraints)
|
||||
goto unlock;
|
||||
- if (!ops->disable)
|
||||
- goto unlock;
|
||||
if (!_regulator_is_enabled(rdev))
|
||||
goto unlock;
|
||||
|
||||
- error = ops->disable(rdev);
|
||||
+ error = _regulator_do_disable(rdev);
|
||||
if (error)
|
||||
ret = error;
|
||||
}
|
||||
@@ -3993,7 +3985,7 @@ static int __init regulator_init_complete(void)
|
||||
ops = rdev->desc->ops;
|
||||
c = rdev->constraints;
|
||||
|
||||
- if (!ops->disable || (c && c->always_on))
|
||||
+ if (c && c->always_on)
|
||||
continue;
|
||||
|
||||
mutex_lock(&rdev->mutex);
|
||||
@@ -4014,7 +4006,7 @@ static int __init regulator_init_complete(void)
|
||||
/* We log since this may kill the system if it
|
||||
* goes wrong. */
|
||||
rdev_info(rdev, "disabling\n");
|
||||
- ret = ops->disable(rdev);
|
||||
+ ret = _regulator_do_disable(rdev);
|
||||
if (ret != 0) {
|
||||
rdev_err(rdev, "couldn't disable: %d\n", ret);
|
||||
}
|
||||
diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c
|
||||
index 159e3c6d92b9..3581416a24d8 100644
|
||||
--- a/drivers/usb/host/xhci-pci.c
|
||||
+++ b/drivers/usb/host/xhci-pci.c
|
||||
@@ -113,6 +113,11 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci)
|
||||
xhci_dbg(xhci, "QUIRK: Resetting on resume\n");
|
||||
xhci->quirks |= XHCI_TRUST_TX_LENGTH;
|
||||
}
|
||||
+ if (pdev->vendor == PCI_VENDOR_ID_RENESAS &&
|
||||
+ pdev->device == 0x0015 &&
|
||||
+ pdev->subsystem_vendor == PCI_VENDOR_ID_SAMSUNG &&
|
||||
+ pdev->subsystem_device == 0xc0cd)
|
||||
+ xhci->quirks |= XHCI_RESET_ON_RESUME;
|
||||
if (pdev->vendor == PCI_VENDOR_ID_VIA)
|
||||
xhci->quirks |= XHCI_RESET_ON_RESUME;
|
||||
}
|
||||
diff --git a/include/linux/ceph/osd_client.h b/include/linux/ceph/osd_client.h
|
||||
index 8f47625a0661..4fb6a8938957 100644
|
||||
--- a/include/linux/ceph/osd_client.h
|
||||
+++ b/include/linux/ceph/osd_client.h
|
||||
@@ -138,6 +138,7 @@ struct ceph_osd_request {
|
||||
__le64 *r_request_pool;
|
||||
void *r_request_pgid;
|
||||
__le32 *r_request_attempts;
|
||||
+ bool r_paused;
|
||||
struct ceph_eversion *r_request_reassert_version;
|
||||
|
||||
int r_result;
|
||||
diff --git a/include/linux/ftrace_event.h b/include/linux/ftrace_event.h
|
||||
index 120d57a1c3a5..b5e36017acd7 100644
|
||||
--- a/include/linux/ftrace_event.h
|
||||
+++ b/include/linux/ftrace_event.h
|
||||
@@ -325,10 +325,6 @@ enum {
|
||||
FILTER_TRACE_FN,
|
||||
};
|
||||
|
||||
-#define EVENT_STORAGE_SIZE 128
|
||||
-extern struct mutex event_storage_mutex;
|
||||
-extern char event_storage[EVENT_STORAGE_SIZE];
|
||||
-
|
||||
extern int trace_event_raw_init(struct ftrace_event_call *call);
|
||||
extern int trace_define_field(struct ftrace_event_call *call, const char *type,
|
||||
const char *name, int offset, int size,
|
||||
diff --git a/include/trace/ftrace.h b/include/trace/ftrace.h
|
||||
index 66dba42128d7..dbb47418df81 100644
|
||||
--- a/include/trace/ftrace.h
|
||||
+++ b/include/trace/ftrace.h
|
||||
@@ -299,15 +299,12 @@ static struct trace_event_functions ftrace_event_type_funcs_##call = { \
|
||||
#undef __array
|
||||
#define __array(type, item, len) \
|
||||
do { \
|
||||
- mutex_lock(&event_storage_mutex); \
|
||||
+ char *type_str = #type"["__stringify(len)"]"; \
|
||||
BUILD_BUG_ON(len > MAX_FILTER_STR_VAL); \
|
||||
- snprintf(event_storage, sizeof(event_storage), \
|
||||
- "%s[%d]", #type, len); \
|
||||
- ret = trace_define_field(event_call, event_storage, #item, \
|
||||
+ ret = trace_define_field(event_call, type_str, #item, \
|
||||
offsetof(typeof(field), item), \
|
||||
sizeof(field.item), \
|
||||
is_signed_type(type), FILTER_OTHER); \
|
||||
- mutex_unlock(&event_storage_mutex); \
|
||||
if (ret) \
|
||||
return ret; \
|
||||
} while (0);
|
||||
diff --git a/kernel/sched/auto_group.c b/kernel/sched/auto_group.c
|
||||
index 64de5f8b0c9e..4a073539c58e 100644
|
||||
--- a/kernel/sched/auto_group.c
|
||||
+++ b/kernel/sched/auto_group.c
|
||||
@@ -77,8 +77,6 @@ static inline struct autogroup *autogroup_create(void)
|
||||
if (IS_ERR(tg))
|
||||
goto out_free;
|
||||
|
||||
- sched_online_group(tg, &root_task_group);
|
||||
-
|
||||
kref_init(&ag->kref);
|
||||
init_rwsem(&ag->lock);
|
||||
ag->id = atomic_inc_return(&autogroup_seq_nr);
|
||||
@@ -98,6 +96,7 @@ static inline struct autogroup *autogroup_create(void)
|
||||
#endif
|
||||
tg->autogroup = ag;
|
||||
|
||||
+ sched_online_group(tg, &root_task_group);
|
||||
return ag;
|
||||
|
||||
out_free:
|
||||
diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c
|
||||
index 2f4b185bfc23..001b349af939 100644
|
||||
--- a/kernel/trace/trace_events.c
|
||||
+++ b/kernel/trace/trace_events.c
|
||||
@@ -27,12 +27,6 @@
|
||||
|
||||
DEFINE_MUTEX(event_mutex);
|
||||
|
||||
-DEFINE_MUTEX(event_storage_mutex);
|
||||
-EXPORT_SYMBOL_GPL(event_storage_mutex);
|
||||
-
|
||||
-char event_storage[EVENT_STORAGE_SIZE];
|
||||
-EXPORT_SYMBOL_GPL(event_storage);
|
||||
-
|
||||
LIST_HEAD(ftrace_events);
|
||||
static LIST_HEAD(ftrace_common_fields);
|
||||
|
||||
diff --git a/kernel/trace/trace_export.c b/kernel/trace/trace_export.c
|
||||
index d21a74670088..d7d0b50b1b70 100644
|
||||
--- a/kernel/trace/trace_export.c
|
||||
+++ b/kernel/trace/trace_export.c
|
||||
@@ -95,15 +95,12 @@ static void __always_unused ____ftrace_check_##name(void) \
|
||||
#undef __array
|
||||
#define __array(type, item, len) \
|
||||
do { \
|
||||
+ char *type_str = #type"["__stringify(len)"]"; \
|
||||
BUILD_BUG_ON(len > MAX_FILTER_STR_VAL); \
|
||||
- mutex_lock(&event_storage_mutex); \
|
||||
- snprintf(event_storage, sizeof(event_storage), \
|
||||
- "%s[%d]", #type, len); \
|
||||
- ret = trace_define_field(event_call, event_storage, #item, \
|
||||
+ ret = trace_define_field(event_call, type_str, #item, \
|
||||
offsetof(typeof(field), item), \
|
||||
sizeof(field.item), \
|
||||
is_signed_type(type), filter_type); \
|
||||
- mutex_unlock(&event_storage_mutex); \
|
||||
if (ret) \
|
||||
return ret; \
|
||||
} while (0);
|
||||
diff --git a/net/ceph/osd_client.c b/net/ceph/osd_client.c
|
||||
index bc0016e3e5ac..3663a305daf7 100644
|
||||
--- a/net/ceph/osd_client.c
|
||||
+++ b/net/ceph/osd_client.c
|
||||
@@ -1225,6 +1225,22 @@ void ceph_osdc_set_request_linger(struct ceph_osd_client *osdc,
|
||||
EXPORT_SYMBOL(ceph_osdc_set_request_linger);
|
||||
|
||||
/*
|
||||
+ * Returns whether a request should be blocked from being sent
|
||||
+ * based on the current osdmap and osd_client settings.
|
||||
+ *
|
||||
+ * Caller should hold map_sem for read.
|
||||
+ */
|
||||
+static bool __req_should_be_paused(struct ceph_osd_client *osdc,
|
||||
+ struct ceph_osd_request *req)
|
||||
+{
|
||||
+ bool pauserd = ceph_osdmap_flag(osdc->osdmap, CEPH_OSDMAP_PAUSERD);
|
||||
+ bool pausewr = ceph_osdmap_flag(osdc->osdmap, CEPH_OSDMAP_PAUSEWR) ||
|
||||
+ ceph_osdmap_flag(osdc->osdmap, CEPH_OSDMAP_FULL);
|
||||
+ return (req->r_flags & CEPH_OSD_FLAG_READ && pauserd) ||
|
||||
+ (req->r_flags & CEPH_OSD_FLAG_WRITE && pausewr);
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
* Pick an osd (the first 'up' osd in the pg), allocate the osd struct
|
||||
* (as needed), and set the request r_osd appropriately. If there is
|
||||
* no up osd, set r_osd to NULL. Move the request to the appropriate list
|
||||
@@ -1241,6 +1257,7 @@ static int __map_request(struct ceph_osd_client *osdc,
|
||||
int acting[CEPH_PG_MAX_SIZE];
|
||||
int o = -1, num = 0;
|
||||
int err;
|
||||
+ bool was_paused;
|
||||
|
||||
dout("map_request %p tid %lld\n", req, req->r_tid);
|
||||
err = ceph_calc_ceph_pg(&pgid, req->r_oid, osdc->osdmap,
|
||||
@@ -1257,12 +1274,18 @@ static int __map_request(struct ceph_osd_client *osdc,
|
||||
num = err;
|
||||
}
|
||||
|
||||
+ was_paused = req->r_paused;
|
||||
+ req->r_paused = __req_should_be_paused(osdc, req);
|
||||
+ if (was_paused && !req->r_paused)
|
||||
+ force_resend = 1;
|
||||
+
|
||||
if ((!force_resend &&
|
||||
req->r_osd && req->r_osd->o_osd == o &&
|
||||
req->r_sent >= req->r_osd->o_incarnation &&
|
||||
req->r_num_pg_osds == num &&
|
||||
memcmp(req->r_pg_osds, acting, sizeof(acting[0])*num) == 0) ||
|
||||
- (req->r_osd == NULL && o == -1))
|
||||
+ (req->r_osd == NULL && o == -1) ||
|
||||
+ req->r_paused)
|
||||
return 0; /* no change */
|
||||
|
||||
dout("map_request tid %llu pgid %lld.%x osd%d (was osd%d)\n",
|
||||
@@ -1606,14 +1629,17 @@ static void reset_changed_osds(struct ceph_osd_client *osdc)
|
||||
*
|
||||
* Caller should hold map_sem for read.
|
||||
*/
|
||||
-static void kick_requests(struct ceph_osd_client *osdc, int force_resend)
|
||||
+static void kick_requests(struct ceph_osd_client *osdc, bool force_resend,
|
||||
+ bool force_resend_writes)
|
||||
{
|
||||
struct ceph_osd_request *req, *nreq;
|
||||
struct rb_node *p;
|
||||
int needmap = 0;
|
||||
int err;
|
||||
+ bool force_resend_req;
|
||||
|
||||
- dout("kick_requests %s\n", force_resend ? " (force resend)" : "");
|
||||
+ dout("kick_requests %s %s\n", force_resend ? " (force resend)" : "",
|
||||
+ force_resend_writes ? " (force resend writes)" : "");
|
||||
mutex_lock(&osdc->request_mutex);
|
||||
for (p = rb_first(&osdc->requests); p; ) {
|
||||
req = rb_entry(p, struct ceph_osd_request, r_node);
|
||||
@@ -1638,7 +1664,10 @@ static void kick_requests(struct ceph_osd_client *osdc, int force_resend)
|
||||
continue;
|
||||
}
|
||||
|
||||
- err = __map_request(osdc, req, force_resend);
|
||||
+ force_resend_req = force_resend ||
|
||||
+ (force_resend_writes &&
|
||||
+ req->r_flags & CEPH_OSD_FLAG_WRITE);
|
||||
+ err = __map_request(osdc, req, force_resend_req);
|
||||
if (err < 0)
|
||||
continue; /* error */
|
||||
if (req->r_osd == NULL) {
|
||||
@@ -1658,7 +1687,8 @@ static void kick_requests(struct ceph_osd_client *osdc, int force_resend)
|
||||
r_linger_item) {
|
||||
dout("linger req=%p req->r_osd=%p\n", req, req->r_osd);
|
||||
|
||||
- err = __map_request(osdc, req, force_resend);
|
||||
+ err = __map_request(osdc, req,
|
||||
+ force_resend || force_resend_writes);
|
||||
dout("__map_request returned %d\n", err);
|
||||
if (err == 0)
|
||||
continue; /* no change and no osd was specified */
|
||||
@@ -1700,6 +1730,7 @@ void ceph_osdc_handle_map(struct ceph_osd_client *osdc, struct ceph_msg *msg)
|
||||
struct ceph_osdmap *newmap = NULL, *oldmap;
|
||||
int err;
|
||||
struct ceph_fsid fsid;
|
||||
+ bool was_full;
|
||||
|
||||
dout("handle_map have %u\n", osdc->osdmap ? osdc->osdmap->epoch : 0);
|
||||
p = msg->front.iov_base;
|
||||
@@ -1713,6 +1744,8 @@ void ceph_osdc_handle_map(struct ceph_osd_client *osdc, struct ceph_msg *msg)
|
||||
|
||||
down_write(&osdc->map_sem);
|
||||
|
||||
+ was_full = ceph_osdmap_flag(osdc->osdmap, CEPH_OSDMAP_FULL);
|
||||
+
|
||||
/* incremental maps */
|
||||
ceph_decode_32_safe(&p, end, nr_maps, bad);
|
||||
dout(" %d inc maps\n", nr_maps);
|
||||
@@ -1737,7 +1770,10 @@ void ceph_osdc_handle_map(struct ceph_osd_client *osdc, struct ceph_msg *msg)
|
||||
ceph_osdmap_destroy(osdc->osdmap);
|
||||
osdc->osdmap = newmap;
|
||||
}
|
||||
- kick_requests(osdc, 0);
|
||||
+ was_full = was_full ||
|
||||
+ ceph_osdmap_flag(osdc->osdmap,
|
||||
+ CEPH_OSDMAP_FULL);
|
||||
+ kick_requests(osdc, 0, was_full);
|
||||
} else {
|
||||
dout("ignoring incremental map %u len %d\n",
|
||||
epoch, maplen);
|
||||
@@ -1780,7 +1816,10 @@ void ceph_osdc_handle_map(struct ceph_osd_client *osdc, struct ceph_msg *msg)
|
||||
skipped_map = 1;
|
||||
ceph_osdmap_destroy(oldmap);
|
||||
}
|
||||
- kick_requests(osdc, skipped_map);
|
||||
+ was_full = was_full ||
|
||||
+ ceph_osdmap_flag(osdc->osdmap,
|
||||
+ CEPH_OSDMAP_FULL);
|
||||
+ kick_requests(osdc, skipped_map, was_full);
|
||||
}
|
||||
p += maplen;
|
||||
nr_maps--;
|
||||
@@ -1797,7 +1836,9 @@ done:
|
||||
* we find out when we are no longer full and stop returning
|
||||
* ENOSPC.
|
||||
*/
|
||||
- if (ceph_osdmap_flag(osdc->osdmap, CEPH_OSDMAP_FULL))
|
||||
+ if (ceph_osdmap_flag(osdc->osdmap, CEPH_OSDMAP_FULL) ||
|
||||
+ ceph_osdmap_flag(osdc->osdmap, CEPH_OSDMAP_PAUSERD) ||
|
||||
+ ceph_osdmap_flag(osdc->osdmap, CEPH_OSDMAP_PAUSEWR))
|
||||
ceph_monc_request_next_osdmap(&osdc->client->monc);
|
||||
|
||||
mutex_lock(&osdc->request_mutex);
|
||||
diff --git a/scripts/package/builddeb b/scripts/package/builddeb
|
||||
index acb86507828a..3001ec5ae07d 100644
|
||||
--- a/scripts/package/builddeb
|
||||
+++ b/scripts/package/builddeb
|
||||
@@ -62,7 +62,7 @@ create_package() {
|
||||
fi
|
||||
|
||||
# Create the package
|
||||
- dpkg-gencontrol -isp $forcearch -p$pname -P"$pdir"
|
||||
+ dpkg-gencontrol -isp $forcearch -Vkernel:debarch="${debarch:-$(dpkg --print-architecture)}" -p$pname -P"$pdir"
|
||||
dpkg --build "$pdir" ..
|
||||
}
|
||||
|
||||
@@ -252,15 +252,14 @@ mkdir -p "$destdir"
|
||||
(cd $objtree; tar -c -f - -T "$objtree/debian/hdrobjfiles") | (cd $destdir; tar -xf -)
|
||||
ln -sf "/usr/src/linux-headers-$version" "$kernel_headers_dir/lib/modules/$version/build"
|
||||
rm -f "$objtree/debian/hdrsrcfiles" "$objtree/debian/hdrobjfiles"
|
||||
-arch=$(dpkg --print-architecture)
|
||||
|
||||
cat <<EOF >> debian/control
|
||||
|
||||
Package: $kernel_headers_packagename
|
||||
Provides: linux-headers, linux-headers-2.6
|
||||
-Architecture: $arch
|
||||
-Description: Linux kernel headers for $KERNELRELEASE on $arch
|
||||
- This package provides kernel header files for $KERNELRELEASE on $arch
|
||||
+Architecture: any
|
||||
+Description: Linux kernel headers for $KERNELRELEASE on \${kernel:debarch}
|
||||
+ This package provides kernel header files for $KERNELRELEASE on \${kernel:debarch}
|
||||
.
|
||||
This is useful for people who need to build external modules
|
||||
EOF
|
||||
diff --git a/sound/core/compress_offload.c b/sound/core/compress_offload.c
|
||||
index 19799931c51d..3fdf998ad057 100644
|
||||
--- a/sound/core/compress_offload.c
|
||||
+++ b/sound/core/compress_offload.c
|
||||
@@ -133,7 +133,7 @@ static int snd_compr_open(struct inode *inode, struct file *f)
|
||||
kfree(data);
|
||||
}
|
||||
snd_card_unref(compr->card);
|
||||
- return 0;
|
||||
+ return ret;
|
||||
}
|
||||
|
||||
static int snd_compr_free(struct inode *inode, struct file *f)
|
||||
diff --git a/sound/soc/codecs/max98090.c b/sound/soc/codecs/max98090.c
|
||||
index 819c90fe021f..4fdcc1cefc25 100644
|
||||
--- a/sound/soc/codecs/max98090.c
|
||||
+++ b/sound/soc/codecs/max98090.c
|
||||
@@ -336,6 +336,7 @@ static bool max98090_readable_register(struct device *dev, unsigned int reg)
|
||||
case M98090_REG_RECORD_TDM_SLOT:
|
||||
case M98090_REG_SAMPLE_RATE:
|
||||
case M98090_REG_DMIC34_BIQUAD_BASE ... M98090_REG_DMIC34_BIQUAD_BASE + 0x0E:
|
||||
+ case M98090_REG_REVISION_ID:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
@ -1,604 +0,0 @@
|
||||
diff --git a/Makefile b/Makefile
|
||||
index 06b31fce1ff5..b5f4ef30f6e6 100644
|
||||
--- a/Makefile
|
||||
+++ b/Makefile
|
||||
@@ -1,6 +1,6 @@
|
||||
VERSION = 3
|
||||
PATCHLEVEL = 10
|
||||
-SUBLEVEL = 35
|
||||
+SUBLEVEL = 36
|
||||
EXTRAVERSION =
|
||||
NAME = TOSSUG Baby Fish
|
||||
|
||||
diff --git a/arch/x86/include/asm/topology.h b/arch/x86/include/asm/topology.h
|
||||
index 095b21507b6a..60bd2748a7c9 100644
|
||||
--- a/arch/x86/include/asm/topology.h
|
||||
+++ b/arch/x86/include/asm/topology.h
|
||||
@@ -119,9 +119,10 @@ static inline void setup_node_to_cpumask_map(void) { }
|
||||
|
||||
extern const struct cpumask *cpu_coregroup_mask(int cpu);
|
||||
|
||||
-#ifdef ENABLE_TOPO_DEFINES
|
||||
#define topology_physical_package_id(cpu) (cpu_data(cpu).phys_proc_id)
|
||||
#define topology_core_id(cpu) (cpu_data(cpu).cpu_core_id)
|
||||
+
|
||||
+#ifdef ENABLE_TOPO_DEFINES
|
||||
#define topology_core_cpumask(cpu) (per_cpu(cpu_core_map, cpu))
|
||||
#define topology_thread_cpumask(cpu) (per_cpu(cpu_sibling_map, cpu))
|
||||
|
||||
diff --git a/drivers/block/aoe/aoecmd.c b/drivers/block/aoe/aoecmd.c
|
||||
index fc803ecbbce4..31262732db23 100644
|
||||
--- a/drivers/block/aoe/aoecmd.c
|
||||
+++ b/drivers/block/aoe/aoecmd.c
|
||||
@@ -899,7 +899,7 @@ bio_pageinc(struct bio *bio)
|
||||
* but this has never been seen here.
|
||||
*/
|
||||
if (unlikely(PageCompound(page)))
|
||||
- if (compound_trans_head(page) != page) {
|
||||
+ if (compound_head(page) != page) {
|
||||
pr_crit("page tail used for block I/O\n");
|
||||
BUG();
|
||||
}
|
||||
diff --git a/drivers/input/mouse/cypress_ps2.c b/drivers/input/mouse/cypress_ps2.c
|
||||
index 888a81a7ea3d..0aaea7ad6cee 100644
|
||||
--- a/drivers/input/mouse/cypress_ps2.c
|
||||
+++ b/drivers/input/mouse/cypress_ps2.c
|
||||
@@ -410,7 +410,6 @@ static int cypress_set_input_params(struct input_dev *input,
|
||||
__clear_bit(REL_X, input->relbit);
|
||||
__clear_bit(REL_Y, input->relbit);
|
||||
|
||||
- __set_bit(INPUT_PROP_BUTTONPAD, input->propbit);
|
||||
__set_bit(EV_KEY, input->evbit);
|
||||
__set_bit(BTN_LEFT, input->keybit);
|
||||
__set_bit(BTN_RIGHT, input->keybit);
|
||||
diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c
|
||||
index b2420ae19e14..c69c81608f43 100644
|
||||
--- a/drivers/input/mouse/synaptics.c
|
||||
+++ b/drivers/input/mouse/synaptics.c
|
||||
@@ -265,11 +265,22 @@ static int synaptics_identify(struct psmouse *psmouse)
|
||||
* Read touchpad resolution and maximum reported coordinates
|
||||
* Resolution is left zero if touchpad does not support the query
|
||||
*/
|
||||
+
|
||||
+static const int *quirk_min_max;
|
||||
+
|
||||
static int synaptics_resolution(struct psmouse *psmouse)
|
||||
{
|
||||
struct synaptics_data *priv = psmouse->private;
|
||||
unsigned char resp[3];
|
||||
|
||||
+ if (quirk_min_max) {
|
||||
+ priv->x_min = quirk_min_max[0];
|
||||
+ priv->x_max = quirk_min_max[1];
|
||||
+ priv->y_min = quirk_min_max[2];
|
||||
+ priv->y_max = quirk_min_max[3];
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
if (SYN_ID_MAJOR(priv->identity) < 4)
|
||||
return 0;
|
||||
|
||||
@@ -1485,10 +1496,54 @@ static const struct dmi_system_id __initconst olpc_dmi_table[] = {
|
||||
{ }
|
||||
};
|
||||
|
||||
+static const struct dmi_system_id min_max_dmi_table[] __initconst = {
|
||||
+#if defined(CONFIG_DMI)
|
||||
+ {
|
||||
+ /* Lenovo ThinkPad Helix */
|
||||
+ .matches = {
|
||||
+ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
|
||||
+ DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad Helix"),
|
||||
+ },
|
||||
+ .driver_data = (int []){1024, 5052, 2258, 4832},
|
||||
+ },
|
||||
+ {
|
||||
+ /* Lenovo ThinkPad X240 */
|
||||
+ .matches = {
|
||||
+ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
|
||||
+ DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad X240"),
|
||||
+ },
|
||||
+ .driver_data = (int []){1232, 5710, 1156, 4696},
|
||||
+ },
|
||||
+ {
|
||||
+ /* Lenovo ThinkPad T440s */
|
||||
+ .matches = {
|
||||
+ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
|
||||
+ DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad T440"),
|
||||
+ },
|
||||
+ .driver_data = (int []){1024, 5112, 2024, 4832},
|
||||
+ },
|
||||
+ {
|
||||
+ /* Lenovo ThinkPad T540p */
|
||||
+ .matches = {
|
||||
+ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
|
||||
+ DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad T540"),
|
||||
+ },
|
||||
+ .driver_data = (int []){1024, 5056, 2058, 4832},
|
||||
+ },
|
||||
+#endif
|
||||
+ { }
|
||||
+};
|
||||
+
|
||||
void __init synaptics_module_init(void)
|
||||
{
|
||||
+ const struct dmi_system_id *min_max_dmi;
|
||||
+
|
||||
impaired_toshiba_kbc = dmi_check_system(toshiba_dmi_table);
|
||||
broken_olpc_ec = dmi_check_system(olpc_dmi_table);
|
||||
+
|
||||
+ min_max_dmi = dmi_first_match(min_max_dmi_table);
|
||||
+ if (min_max_dmi)
|
||||
+ quirk_min_max = min_max_dmi->driver_data;
|
||||
}
|
||||
|
||||
static int __synaptics_init(struct psmouse *psmouse, bool absolute_mode)
|
||||
diff --git a/drivers/input/mousedev.c b/drivers/input/mousedev.c
|
||||
index 4c842c320c2e..b604564dec5c 100644
|
||||
--- a/drivers/input/mousedev.c
|
||||
+++ b/drivers/input/mousedev.c
|
||||
@@ -67,7 +67,6 @@ struct mousedev {
|
||||
struct device dev;
|
||||
struct cdev cdev;
|
||||
bool exist;
|
||||
- bool is_mixdev;
|
||||
|
||||
struct list_head mixdev_node;
|
||||
bool opened_by_mixdev;
|
||||
@@ -77,6 +76,9 @@ struct mousedev {
|
||||
int old_x[4], old_y[4];
|
||||
int frac_dx, frac_dy;
|
||||
unsigned long touch;
|
||||
+
|
||||
+ int (*open_device)(struct mousedev *mousedev);
|
||||
+ void (*close_device)(struct mousedev *mousedev);
|
||||
};
|
||||
|
||||
enum mousedev_emul {
|
||||
@@ -116,9 +118,6 @@ static unsigned char mousedev_imex_seq[] = { 0xf3, 200, 0xf3, 200, 0xf3, 80 };
|
||||
static struct mousedev *mousedev_mix;
|
||||
static LIST_HEAD(mousedev_mix_list);
|
||||
|
||||
-static void mixdev_open_devices(void);
|
||||
-static void mixdev_close_devices(void);
|
||||
-
|
||||
#define fx(i) (mousedev->old_x[(mousedev->pkt_count - (i)) & 03])
|
||||
#define fy(i) (mousedev->old_y[(mousedev->pkt_count - (i)) & 03])
|
||||
|
||||
@@ -428,9 +427,7 @@ static int mousedev_open_device(struct mousedev *mousedev)
|
||||
if (retval)
|
||||
return retval;
|
||||
|
||||
- if (mousedev->is_mixdev)
|
||||
- mixdev_open_devices();
|
||||
- else if (!mousedev->exist)
|
||||
+ if (!mousedev->exist)
|
||||
retval = -ENODEV;
|
||||
else if (!mousedev->open++) {
|
||||
retval = input_open_device(&mousedev->handle);
|
||||
@@ -446,9 +443,7 @@ static void mousedev_close_device(struct mousedev *mousedev)
|
||||
{
|
||||
mutex_lock(&mousedev->mutex);
|
||||
|
||||
- if (mousedev->is_mixdev)
|
||||
- mixdev_close_devices();
|
||||
- else if (mousedev->exist && !--mousedev->open)
|
||||
+ if (mousedev->exist && !--mousedev->open)
|
||||
input_close_device(&mousedev->handle);
|
||||
|
||||
mutex_unlock(&mousedev->mutex);
|
||||
@@ -459,21 +454,29 @@ static void mousedev_close_device(struct mousedev *mousedev)
|
||||
* stream. Note that this function is called with mousedev_mix->mutex
|
||||
* held.
|
||||
*/
|
||||
-static void mixdev_open_devices(void)
|
||||
+static int mixdev_open_devices(struct mousedev *mixdev)
|
||||
{
|
||||
- struct mousedev *mousedev;
|
||||
+ int error;
|
||||
+
|
||||
+ error = mutex_lock_interruptible(&mixdev->mutex);
|
||||
+ if (error)
|
||||
+ return error;
|
||||
|
||||
- if (mousedev_mix->open++)
|
||||
- return;
|
||||
+ if (!mixdev->open++) {
|
||||
+ struct mousedev *mousedev;
|
||||
|
||||
- list_for_each_entry(mousedev, &mousedev_mix_list, mixdev_node) {
|
||||
- if (!mousedev->opened_by_mixdev) {
|
||||
- if (mousedev_open_device(mousedev))
|
||||
- continue;
|
||||
+ list_for_each_entry(mousedev, &mousedev_mix_list, mixdev_node) {
|
||||
+ if (!mousedev->opened_by_mixdev) {
|
||||
+ if (mousedev_open_device(mousedev))
|
||||
+ continue;
|
||||
|
||||
- mousedev->opened_by_mixdev = true;
|
||||
+ mousedev->opened_by_mixdev = true;
|
||||
+ }
|
||||
}
|
||||
}
|
||||
+
|
||||
+ mutex_unlock(&mixdev->mutex);
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -481,19 +484,22 @@ static void mixdev_open_devices(void)
|
||||
* device. Note that this function is called with mousedev_mix->mutex
|
||||
* held.
|
||||
*/
|
||||
-static void mixdev_close_devices(void)
|
||||
+static void mixdev_close_devices(struct mousedev *mixdev)
|
||||
{
|
||||
- struct mousedev *mousedev;
|
||||
+ mutex_lock(&mixdev->mutex);
|
||||
|
||||
- if (--mousedev_mix->open)
|
||||
- return;
|
||||
+ if (!--mixdev->open) {
|
||||
+ struct mousedev *mousedev;
|
||||
|
||||
- list_for_each_entry(mousedev, &mousedev_mix_list, mixdev_node) {
|
||||
- if (mousedev->opened_by_mixdev) {
|
||||
- mousedev->opened_by_mixdev = false;
|
||||
- mousedev_close_device(mousedev);
|
||||
+ list_for_each_entry(mousedev, &mousedev_mix_list, mixdev_node) {
|
||||
+ if (mousedev->opened_by_mixdev) {
|
||||
+ mousedev->opened_by_mixdev = false;
|
||||
+ mousedev_close_device(mousedev);
|
||||
+ }
|
||||
}
|
||||
}
|
||||
+
|
||||
+ mutex_unlock(&mixdev->mutex);
|
||||
}
|
||||
|
||||
|
||||
@@ -522,7 +528,7 @@ static int mousedev_release(struct inode *inode, struct file *file)
|
||||
mousedev_detach_client(mousedev, client);
|
||||
kfree(client);
|
||||
|
||||
- mousedev_close_device(mousedev);
|
||||
+ mousedev->close_device(mousedev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -550,7 +556,7 @@ static int mousedev_open(struct inode *inode, struct file *file)
|
||||
client->mousedev = mousedev;
|
||||
mousedev_attach_client(mousedev, client);
|
||||
|
||||
- error = mousedev_open_device(mousedev);
|
||||
+ error = mousedev->open_device(mousedev);
|
||||
if (error)
|
||||
goto err_free_client;
|
||||
|
||||
@@ -861,16 +867,21 @@ static struct mousedev *mousedev_create(struct input_dev *dev,
|
||||
|
||||
if (mixdev) {
|
||||
dev_set_name(&mousedev->dev, "mice");
|
||||
+
|
||||
+ mousedev->open_device = mixdev_open_devices;
|
||||
+ mousedev->close_device = mixdev_close_devices;
|
||||
} else {
|
||||
int dev_no = minor;
|
||||
/* Normalize device number if it falls into legacy range */
|
||||
if (dev_no < MOUSEDEV_MINOR_BASE + MOUSEDEV_MINORS)
|
||||
dev_no -= MOUSEDEV_MINOR_BASE;
|
||||
dev_set_name(&mousedev->dev, "mouse%d", dev_no);
|
||||
+
|
||||
+ mousedev->open_device = mousedev_open_device;
|
||||
+ mousedev->close_device = mousedev_close_device;
|
||||
}
|
||||
|
||||
mousedev->exist = true;
|
||||
- mousedev->is_mixdev = mixdev;
|
||||
mousedev->handle.dev = input_get_device(dev);
|
||||
mousedev->handle.name = dev_name(&mousedev->dev);
|
||||
mousedev->handle.handler = handler;
|
||||
@@ -919,7 +930,7 @@ static void mousedev_destroy(struct mousedev *mousedev)
|
||||
device_del(&mousedev->dev);
|
||||
mousedev_cleanup(mousedev);
|
||||
input_free_minor(MINOR(mousedev->dev.devt));
|
||||
- if (!mousedev->is_mixdev)
|
||||
+ if (mousedev != mousedev_mix)
|
||||
input_unregister_handle(&mousedev->handle);
|
||||
put_device(&mousedev->dev);
|
||||
}
|
||||
diff --git a/drivers/net/ethernet/marvell/mvneta.c b/drivers/net/ethernet/marvell/mvneta.c
|
||||
index 254f255204f9..a602aeeb3acb 100644
|
||||
--- a/drivers/net/ethernet/marvell/mvneta.c
|
||||
+++ b/drivers/net/ethernet/marvell/mvneta.c
|
||||
@@ -119,7 +119,7 @@
|
||||
#define MVNETA_GMAC_MAX_RX_SIZE_MASK 0x7ffc
|
||||
#define MVNETA_GMAC0_PORT_ENABLE BIT(0)
|
||||
#define MVNETA_GMAC_CTRL_2 0x2c08
|
||||
-#define MVNETA_GMAC2_PSC_ENABLE BIT(3)
|
||||
+#define MVNETA_GMAC2_PCS_ENABLE BIT(3)
|
||||
#define MVNETA_GMAC2_PORT_RGMII BIT(4)
|
||||
#define MVNETA_GMAC2_PORT_RESET BIT(6)
|
||||
#define MVNETA_GMAC_STATUS 0x2c10
|
||||
@@ -655,7 +655,7 @@ static void mvneta_port_sgmii_config(struct mvneta_port *pp)
|
||||
u32 val;
|
||||
|
||||
val = mvreg_read(pp, MVNETA_GMAC_CTRL_2);
|
||||
- val |= MVNETA_GMAC2_PSC_ENABLE;
|
||||
+ val |= MVNETA_GMAC2_PCS_ENABLE;
|
||||
mvreg_write(pp, MVNETA_GMAC_CTRL_2, val);
|
||||
}
|
||||
|
||||
diff --git a/drivers/vfio/vfio_iommu_type1.c b/drivers/vfio/vfio_iommu_type1.c
|
||||
index 6f3fbc48a6c7..22080eb6aff6 100644
|
||||
--- a/drivers/vfio/vfio_iommu_type1.c
|
||||
+++ b/drivers/vfio/vfio_iommu_type1.c
|
||||
@@ -138,12 +138,12 @@ static bool is_invalid_reserved_pfn(unsigned long pfn)
|
||||
if (pfn_valid(pfn)) {
|
||||
bool reserved;
|
||||
struct page *tail = pfn_to_page(pfn);
|
||||
- struct page *head = compound_trans_head(tail);
|
||||
+ struct page *head = compound_head(tail);
|
||||
reserved = !!(PageReserved(head));
|
||||
if (head != tail) {
|
||||
/*
|
||||
* "head" is not a dangling pointer
|
||||
- * (compound_trans_head takes care of that)
|
||||
+ * (compound_head takes care of that)
|
||||
* but the hugepage may have been split
|
||||
* from under us (and we may not hold a
|
||||
* reference count on the head page so it can
|
||||
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
|
||||
index 21dff8f236f6..f9e11df768d5 100644
|
||||
--- a/fs/ext4/inode.c
|
||||
+++ b/fs/ext4/inode.c
|
||||
@@ -38,6 +38,7 @@
|
||||
#include <linux/slab.h>
|
||||
#include <linux/ratelimit.h>
|
||||
#include <linux/aio.h>
|
||||
+#include <linux/bitops.h>
|
||||
|
||||
#include "ext4_jbd2.h"
|
||||
#include "xattr.h"
|
||||
@@ -4044,18 +4045,20 @@ int ext4_get_inode_loc(struct inode *inode, struct ext4_iloc *iloc)
|
||||
void ext4_set_inode_flags(struct inode *inode)
|
||||
{
|
||||
unsigned int flags = EXT4_I(inode)->i_flags;
|
||||
+ unsigned int new_fl = 0;
|
||||
|
||||
- inode->i_flags &= ~(S_SYNC|S_APPEND|S_IMMUTABLE|S_NOATIME|S_DIRSYNC);
|
||||
if (flags & EXT4_SYNC_FL)
|
||||
- inode->i_flags |= S_SYNC;
|
||||
+ new_fl |= S_SYNC;
|
||||
if (flags & EXT4_APPEND_FL)
|
||||
- inode->i_flags |= S_APPEND;
|
||||
+ new_fl |= S_APPEND;
|
||||
if (flags & EXT4_IMMUTABLE_FL)
|
||||
- inode->i_flags |= S_IMMUTABLE;
|
||||
+ new_fl |= S_IMMUTABLE;
|
||||
if (flags & EXT4_NOATIME_FL)
|
||||
- inode->i_flags |= S_NOATIME;
|
||||
+ new_fl |= S_NOATIME;
|
||||
if (flags & EXT4_DIRSYNC_FL)
|
||||
- inode->i_flags |= S_DIRSYNC;
|
||||
+ new_fl |= S_DIRSYNC;
|
||||
+ set_mask_bits(&inode->i_flags,
|
||||
+ S_SYNC|S_APPEND|S_IMMUTABLE|S_NOATIME|S_DIRSYNC, new_fl);
|
||||
}
|
||||
|
||||
/* Propagate flags from i_flags to EXT4_I(inode)->i_flags */
|
||||
diff --git a/fs/proc/page.c b/fs/proc/page.c
|
||||
index b8730d9ebaee..2a8cc94bb641 100644
|
||||
--- a/fs/proc/page.c
|
||||
+++ b/fs/proc/page.c
|
||||
@@ -121,7 +121,7 @@ u64 stable_page_flags(struct page *page)
|
||||
* just checks PG_head/PG_tail, so we need to check PageLRU to make
|
||||
* sure a given page is a thp, not a non-huge compound page.
|
||||
*/
|
||||
- else if (PageTransCompound(page) && PageLRU(compound_trans_head(page)))
|
||||
+ else if (PageTransCompound(page) && PageLRU(compound_head(page)))
|
||||
u |= 1 << KPF_THP;
|
||||
|
||||
/*
|
||||
diff --git a/include/linux/bitops.h b/include/linux/bitops.h
|
||||
index a3b6b82108b9..c1dde8e00d25 100644
|
||||
--- a/include/linux/bitops.h
|
||||
+++ b/include/linux/bitops.h
|
||||
@@ -185,6 +185,21 @@ static inline unsigned long __ffs64(u64 word)
|
||||
|
||||
#ifdef __KERNEL__
|
||||
|
||||
+#ifndef set_mask_bits
|
||||
+#define set_mask_bits(ptr, _mask, _bits) \
|
||||
+({ \
|
||||
+ const typeof(*ptr) mask = (_mask), bits = (_bits); \
|
||||
+ typeof(*ptr) old, new; \
|
||||
+ \
|
||||
+ do { \
|
||||
+ old = ACCESS_ONCE(*ptr); \
|
||||
+ new = (old & ~mask) | bits; \
|
||||
+ } while (cmpxchg(ptr, old, new) != old); \
|
||||
+ \
|
||||
+ new; \
|
||||
+})
|
||||
+#endif
|
||||
+
|
||||
#ifndef find_last_bit
|
||||
/**
|
||||
* find_last_bit - find the last set bit in a memory region
|
||||
diff --git a/include/linux/huge_mm.h b/include/linux/huge_mm.h
|
||||
index 528454c2caa9..a193bb3e4138 100644
|
||||
--- a/include/linux/huge_mm.h
|
||||
+++ b/include/linux/huge_mm.h
|
||||
@@ -159,23 +159,6 @@ static inline int hpage_nr_pages(struct page *page)
|
||||
return HPAGE_PMD_NR;
|
||||
return 1;
|
||||
}
|
||||
-static inline struct page *compound_trans_head(struct page *page)
|
||||
-{
|
||||
- if (PageTail(page)) {
|
||||
- struct page *head;
|
||||
- head = page->first_page;
|
||||
- smp_rmb();
|
||||
- /*
|
||||
- * head may be a dangling pointer.
|
||||
- * __split_huge_page_refcount clears PageTail before
|
||||
- * overwriting first_page, so if PageTail is still
|
||||
- * there it means the head pointer isn't dangling.
|
||||
- */
|
||||
- if (PageTail(page))
|
||||
- return head;
|
||||
- }
|
||||
- return page;
|
||||
-}
|
||||
|
||||
extern int do_huge_pmd_numa_page(struct mm_struct *mm, struct vm_area_struct *vma,
|
||||
unsigned long addr, pmd_t pmd, pmd_t *pmdp);
|
||||
@@ -205,7 +188,6 @@ static inline int split_huge_page(struct page *page)
|
||||
do { } while (0)
|
||||
#define split_huge_page_pmd_mm(__mm, __address, __pmd) \
|
||||
do { } while (0)
|
||||
-#define compound_trans_head(page) compound_head(page)
|
||||
static inline int hugepage_madvise(struct vm_area_struct *vma,
|
||||
unsigned long *vm_flags, int advice)
|
||||
{
|
||||
diff --git a/include/linux/mm.h b/include/linux/mm.h
|
||||
index 3bf21c3502d0..a9a48309f045 100644
|
||||
--- a/include/linux/mm.h
|
||||
+++ b/include/linux/mm.h
|
||||
@@ -361,8 +361,18 @@ static inline void compound_unlock_irqrestore(struct page *page,
|
||||
|
||||
static inline struct page *compound_head(struct page *page)
|
||||
{
|
||||
- if (unlikely(PageTail(page)))
|
||||
- return page->first_page;
|
||||
+ if (unlikely(PageTail(page))) {
|
||||
+ struct page *head = page->first_page;
|
||||
+
|
||||
+ /*
|
||||
+ * page->first_page may be a dangling pointer to an old
|
||||
+ * compound page, so recheck that it is still a tail
|
||||
+ * page before returning.
|
||||
+ */
|
||||
+ smp_rmb();
|
||||
+ if (likely(PageTail(page)))
|
||||
+ return head;
|
||||
+ }
|
||||
return page;
|
||||
}
|
||||
|
||||
diff --git a/mm/ksm.c b/mm/ksm.c
|
||||
index b6afe0c440d8..784d1e4bc385 100644
|
||||
--- a/mm/ksm.c
|
||||
+++ b/mm/ksm.c
|
||||
@@ -444,7 +444,7 @@ static void break_cow(struct rmap_item *rmap_item)
|
||||
static struct page *page_trans_compound_anon(struct page *page)
|
||||
{
|
||||
if (PageTransCompound(page)) {
|
||||
- struct page *head = compound_trans_head(page);
|
||||
+ struct page *head = compound_head(page);
|
||||
/*
|
||||
* head may actually be splitted and freed from under
|
||||
* us but it's ok here.
|
||||
diff --git a/mm/memory-failure.c b/mm/memory-failure.c
|
||||
index e386beefc994..59c62fa75c5a 100644
|
||||
--- a/mm/memory-failure.c
|
||||
+++ b/mm/memory-failure.c
|
||||
@@ -1544,7 +1544,7 @@ int soft_offline_page(struct page *page, int flags)
|
||||
{
|
||||
int ret;
|
||||
unsigned long pfn = page_to_pfn(page);
|
||||
- struct page *hpage = compound_trans_head(page);
|
||||
+ struct page *hpage = compound_head(page);
|
||||
|
||||
if (PageHWPoison(page)) {
|
||||
pr_info("soft offline: %#lx page already poisoned\n", pfn);
|
||||
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
|
||||
index 2ee0fd313f03..0ab02fb8e9b1 100644
|
||||
--- a/mm/page_alloc.c
|
||||
+++ b/mm/page_alloc.c
|
||||
@@ -360,9 +360,11 @@ void prep_compound_page(struct page *page, unsigned long order)
|
||||
__SetPageHead(page);
|
||||
for (i = 1; i < nr_pages; i++) {
|
||||
struct page *p = page + i;
|
||||
- __SetPageTail(p);
|
||||
set_page_count(p, 0);
|
||||
p->first_page = page;
|
||||
+ /* Make sure p->first_page is always valid for PageTail() */
|
||||
+ smp_wmb();
|
||||
+ __SetPageTail(p);
|
||||
}
|
||||
}
|
||||
|
||||
diff --git a/mm/swap.c b/mm/swap.c
|
||||
index ea58dbde788e..4e35f3ff0427 100644
|
||||
--- a/mm/swap.c
|
||||
+++ b/mm/swap.c
|
||||
@@ -81,7 +81,7 @@ static void put_compound_page(struct page *page)
|
||||
{
|
||||
if (unlikely(PageTail(page))) {
|
||||
/* __split_huge_page_refcount can run under us */
|
||||
- struct page *page_head = compound_trans_head(page);
|
||||
+ struct page *page_head = compound_head(page);
|
||||
|
||||
if (likely(page != page_head &&
|
||||
get_page_unless_zero(page_head))) {
|
||||
@@ -219,7 +219,7 @@ bool __get_page_tail(struct page *page)
|
||||
*/
|
||||
unsigned long flags;
|
||||
bool got = false;
|
||||
- struct page *page_head = compound_trans_head(page);
|
||||
+ struct page *page_head = compound_head(page);
|
||||
|
||||
if (likely(page != page_head && get_page_unless_zero(page_head))) {
|
||||
/* Ref to put_compound_page() comment. */
|
||||
diff --git a/net/netfilter/nf_conntrack_proto_dccp.c b/net/netfilter/nf_conntrack_proto_dccp.c
|
||||
index a99b6c3427b0..59359bec328a 100644
|
||||
--- a/net/netfilter/nf_conntrack_proto_dccp.c
|
||||
+++ b/net/netfilter/nf_conntrack_proto_dccp.c
|
||||
@@ -428,7 +428,7 @@ static bool dccp_new(struct nf_conn *ct, const struct sk_buff *skb,
|
||||
const char *msg;
|
||||
u_int8_t state;
|
||||
|
||||
- dh = skb_header_pointer(skb, dataoff, sizeof(_dh), &dh);
|
||||
+ dh = skb_header_pointer(skb, dataoff, sizeof(_dh), &_dh);
|
||||
BUG_ON(dh == NULL);
|
||||
|
||||
state = dccp_state_table[CT_DCCP_ROLE_CLIENT][dh->dccph_type][CT_DCCP_NONE];
|
||||
@@ -486,7 +486,7 @@ static int dccp_packet(struct nf_conn *ct, const struct sk_buff *skb,
|
||||
u_int8_t type, old_state, new_state;
|
||||
enum ct_dccp_roles role;
|
||||
|
||||
- dh = skb_header_pointer(skb, dataoff, sizeof(_dh), &dh);
|
||||
+ dh = skb_header_pointer(skb, dataoff, sizeof(_dh), &_dh);
|
||||
BUG_ON(dh == NULL);
|
||||
type = dh->dccph_type;
|
||||
|
||||
@@ -577,7 +577,7 @@ static int dccp_error(struct net *net, struct nf_conn *tmpl,
|
||||
unsigned int cscov;
|
||||
const char *msg;
|
||||
|
||||
- dh = skb_header_pointer(skb, dataoff, sizeof(_dh), &dh);
|
||||
+ dh = skb_header_pointer(skb, dataoff, sizeof(_dh), &_dh);
|
||||
if (dh == NULL) {
|
||||
msg = "nf_ct_dccp: short packet ";
|
||||
goto out_invalid;
|
||||
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
|
||||
index eb99458f5b68..8cf1cd2fadaa 100644
|
||||
--- a/virt/kvm/kvm_main.c
|
||||
+++ b/virt/kvm/kvm_main.c
|
||||
@@ -105,12 +105,12 @@ bool kvm_is_mmio_pfn(pfn_t pfn)
|
||||
if (pfn_valid(pfn)) {
|
||||
int reserved;
|
||||
struct page *tail = pfn_to_page(pfn);
|
||||
- struct page *head = compound_trans_head(tail);
|
||||
+ struct page *head = compound_head(tail);
|
||||
reserved = PageReserved(head);
|
||||
if (head != tail) {
|
||||
/*
|
||||
* "head" is not a dangling pointer
|
||||
- * (compound_trans_head takes care of that)
|
||||
+ * (compound_head takes care of that)
|
||||
* but the hugepage may have been splitted
|
||||
* from under us (and we may not hold a
|
||||
* reference count on the head page so it can
|
File diff suppressed because it is too large
Load Diff
@ -1,719 +0,0 @@
|
||||
diff --git a/Makefile b/Makefile
|
||||
index bd9fb5b72fc0..bd51b50a567b 100644
|
||||
--- a/Makefile
|
||||
+++ b/Makefile
|
||||
@@ -1,6 +1,6 @@
|
||||
VERSION = 3
|
||||
PATCHLEVEL = 10
|
||||
-SUBLEVEL = 37
|
||||
+SUBLEVEL = 38
|
||||
EXTRAVERSION =
|
||||
NAME = TOSSUG Baby Fish
|
||||
|
||||
diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig
|
||||
index 9ac9f1666339..2668b3142fa2 100644
|
||||
--- a/arch/sparc/Kconfig
|
||||
+++ b/arch/sparc/Kconfig
|
||||
@@ -25,7 +25,7 @@ config SPARC
|
||||
select RTC_DRV_M48T59
|
||||
select HAVE_DMA_ATTRS
|
||||
select HAVE_DMA_API_DEBUG
|
||||
- select HAVE_ARCH_JUMP_LABEL
|
||||
+ select HAVE_ARCH_JUMP_LABEL if SPARC64
|
||||
select HAVE_GENERIC_HARDIRQS
|
||||
select GENERIC_IRQ_SHOW
|
||||
select ARCH_WANT_IPC_PARSE_VERSION
|
||||
diff --git a/arch/sparc/include/asm/uaccess_64.h b/arch/sparc/include/asm/uaccess_64.h
|
||||
index e562d3caee57..ad7e178337f1 100644
|
||||
--- a/arch/sparc/include/asm/uaccess_64.h
|
||||
+++ b/arch/sparc/include/asm/uaccess_64.h
|
||||
@@ -262,8 +262,8 @@ extern unsigned long __must_check __clear_user(void __user *, unsigned long);
|
||||
extern __must_check long strlen_user(const char __user *str);
|
||||
extern __must_check long strnlen_user(const char __user *str, long n);
|
||||
|
||||
-#define __copy_to_user_inatomic ___copy_to_user
|
||||
-#define __copy_from_user_inatomic ___copy_from_user
|
||||
+#define __copy_to_user_inatomic __copy_to_user
|
||||
+#define __copy_from_user_inatomic __copy_from_user
|
||||
|
||||
struct pt_regs;
|
||||
extern unsigned long compute_effective_address(struct pt_regs *,
|
||||
diff --git a/arch/sparc/kernel/pci.c b/arch/sparc/kernel/pci.c
|
||||
index baf4366e2d6a..906cbf0f8608 100644
|
||||
--- a/arch/sparc/kernel/pci.c
|
||||
+++ b/arch/sparc/kernel/pci.c
|
||||
@@ -399,8 +399,8 @@ static void apb_fake_ranges(struct pci_dev *dev,
|
||||
apb_calc_first_last(map, &first, &last);
|
||||
res = bus->resource[1];
|
||||
res->flags = IORESOURCE_MEM;
|
||||
- region.start = (first << 21);
|
||||
- region.end = (last << 21) + ((1 << 21) - 1);
|
||||
+ region.start = (first << 29);
|
||||
+ region.end = (last << 29) + ((1 << 29) - 1);
|
||||
pcibios_bus_to_resource(dev, res, ®ion);
|
||||
}
|
||||
|
||||
diff --git a/arch/sparc/kernel/process_64.c b/arch/sparc/kernel/process_64.c
|
||||
index baebab215492..b9cc9763faf4 100644
|
||||
--- a/arch/sparc/kernel/process_64.c
|
||||
+++ b/arch/sparc/kernel/process_64.c
|
||||
@@ -57,9 +57,12 @@ void arch_cpu_idle(void)
|
||||
{
|
||||
if (tlb_type != hypervisor) {
|
||||
touch_nmi_watchdog();
|
||||
+ local_irq_enable();
|
||||
} else {
|
||||
unsigned long pstate;
|
||||
|
||||
+ local_irq_enable();
|
||||
+
|
||||
/* The sun4v sleeping code requires that we have PSTATE.IE cleared over
|
||||
* the cpu sleep hypervisor call.
|
||||
*/
|
||||
@@ -81,7 +84,6 @@ void arch_cpu_idle(void)
|
||||
: "=&r" (pstate)
|
||||
: "i" (PSTATE_IE));
|
||||
}
|
||||
- local_irq_enable();
|
||||
}
|
||||
|
||||
#ifdef CONFIG_HOTPLUG_CPU
|
||||
diff --git a/arch/sparc/kernel/syscalls.S b/arch/sparc/kernel/syscalls.S
|
||||
index 73ec8a798d95..c79c687fbe1e 100644
|
||||
--- a/arch/sparc/kernel/syscalls.S
|
||||
+++ b/arch/sparc/kernel/syscalls.S
|
||||
@@ -189,7 +189,8 @@ linux_sparc_syscall32:
|
||||
mov %i0, %l5 ! IEU1
|
||||
5: call %l7 ! CTI Group brk forced
|
||||
srl %i5, 0, %o5 ! IEU1
|
||||
- ba,a,pt %xcc, 3f
|
||||
+ ba,pt %xcc, 3f
|
||||
+ sra %o0, 0, %o0
|
||||
|
||||
/* Linux native system calls enter here... */
|
||||
.align 32
|
||||
@@ -217,7 +218,6 @@ linux_sparc_syscall:
|
||||
3: stx %o0, [%sp + PTREGS_OFF + PT_V9_I0]
|
||||
ret_sys_call:
|
||||
ldx [%sp + PTREGS_OFF + PT_V9_TSTATE], %g3
|
||||
- sra %o0, 0, %o0
|
||||
mov %ulo(TSTATE_XCARRY | TSTATE_ICARRY), %g2
|
||||
sllx %g2, 32, %g2
|
||||
|
||||
diff --git a/arch/x86/kernel/early-quirks.c b/arch/x86/kernel/early-quirks.c
|
||||
index 63bdb29b2549..4f7c82cdd0f5 100644
|
||||
--- a/arch/x86/kernel/early-quirks.c
|
||||
+++ b/arch/x86/kernel/early-quirks.c
|
||||
@@ -202,18 +202,15 @@ static void __init intel_remapping_check(int num, int slot, int func)
|
||||
revision = read_pci_config_byte(num, slot, func, PCI_REVISION_ID);
|
||||
|
||||
/*
|
||||
- * Revision 13 of all triggering devices id in this quirk have
|
||||
- * a problem draining interrupts when irq remapping is enabled,
|
||||
- * and should be flagged as broken. Additionally revisions 0x12
|
||||
- * and 0x22 of device id 0x3405 has this problem.
|
||||
+ * Revision <= 13 of all triggering devices id in this quirk
|
||||
+ * have a problem draining interrupts when irq remapping is
|
||||
+ * enabled, and should be flagged as broken. Additionally
|
||||
+ * revision 0x22 of device id 0x3405 has this problem.
|
||||
*/
|
||||
- if (revision == 0x13)
|
||||
+ if (revision <= 0x13)
|
||||
set_irq_remapping_broken();
|
||||
- else if ((device == 0x3405) &&
|
||||
- ((revision == 0x12) ||
|
||||
- (revision == 0x22)))
|
||||
+ else if (device == 0x3405 && revision == 0x22)
|
||||
set_irq_remapping_broken();
|
||||
-
|
||||
}
|
||||
|
||||
#define QFLAG_APPLY_ONCE 0x1
|
||||
diff --git a/drivers/char/ipmi/ipmi_bt_sm.c b/drivers/char/ipmi/ipmi_bt_sm.c
|
||||
index a22a7a502740..8156cafad11a 100644
|
||||
--- a/drivers/char/ipmi/ipmi_bt_sm.c
|
||||
+++ b/drivers/char/ipmi/ipmi_bt_sm.c
|
||||
@@ -352,7 +352,7 @@ static inline void write_all_bytes(struct si_sm_data *bt)
|
||||
|
||||
static inline int read_all_bytes(struct si_sm_data *bt)
|
||||
{
|
||||
- unsigned char i;
|
||||
+ unsigned int i;
|
||||
|
||||
/*
|
||||
* length is "framing info", minimum = 4: NetFn, Seq, Cmd, cCode.
|
||||
diff --git a/drivers/staging/comedi/drivers/8255_pci.c b/drivers/staging/comedi/drivers/8255_pci.c
|
||||
index 05bcf0dffb8c..e54031c558e8 100644
|
||||
--- a/drivers/staging/comedi/drivers/8255_pci.c
|
||||
+++ b/drivers/staging/comedi/drivers/8255_pci.c
|
||||
@@ -59,6 +59,7 @@ Configuration Options: not applicable, uses PCI auto config
|
||||
#include "../comedidev.h"
|
||||
|
||||
#include "8255.h"
|
||||
+#include "mite.h"
|
||||
|
||||
enum pci_8255_boardid {
|
||||
BOARD_ADLINK_PCI7224,
|
||||
@@ -82,6 +83,7 @@ struct pci_8255_boardinfo {
|
||||
const char *name;
|
||||
int dio_badr;
|
||||
int n_8255;
|
||||
+ unsigned int has_mite:1;
|
||||
};
|
||||
|
||||
static const struct pci_8255_boardinfo pci_8255_boards[] = {
|
||||
@@ -129,36 +131,43 @@ static const struct pci_8255_boardinfo pci_8255_boards[] = {
|
||||
.name = "ni_pci-dio-96",
|
||||
.dio_badr = 1,
|
||||
.n_8255 = 4,
|
||||
+ .has_mite = 1,
|
||||
},
|
||||
[BOARD_NI_PCIDIO96B] = {
|
||||
.name = "ni_pci-dio-96b",
|
||||
.dio_badr = 1,
|
||||
.n_8255 = 4,
|
||||
+ .has_mite = 1,
|
||||
},
|
||||
[BOARD_NI_PXI6508] = {
|
||||
.name = "ni_pxi-6508",
|
||||
.dio_badr = 1,
|
||||
.n_8255 = 4,
|
||||
+ .has_mite = 1,
|
||||
},
|
||||
[BOARD_NI_PCI6503] = {
|
||||
.name = "ni_pci-6503",
|
||||
.dio_badr = 1,
|
||||
.n_8255 = 1,
|
||||
+ .has_mite = 1,
|
||||
},
|
||||
[BOARD_NI_PCI6503B] = {
|
||||
.name = "ni_pci-6503b",
|
||||
.dio_badr = 1,
|
||||
.n_8255 = 1,
|
||||
+ .has_mite = 1,
|
||||
},
|
||||
[BOARD_NI_PCI6503X] = {
|
||||
.name = "ni_pci-6503x",
|
||||
.dio_badr = 1,
|
||||
.n_8255 = 1,
|
||||
+ .has_mite = 1,
|
||||
},
|
||||
[BOARD_NI_PXI_6503] = {
|
||||
.name = "ni_pxi-6503",
|
||||
.dio_badr = 1,
|
||||
.n_8255 = 1,
|
||||
+ .has_mite = 1,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -166,6 +175,25 @@ struct pci_8255_private {
|
||||
void __iomem *mmio_base;
|
||||
};
|
||||
|
||||
+static int pci_8255_mite_init(struct pci_dev *pcidev)
|
||||
+{
|
||||
+ void __iomem *mite_base;
|
||||
+ u32 main_phys_addr;
|
||||
+
|
||||
+ /* ioremap the MITE registers (BAR 0) temporarily */
|
||||
+ mite_base = pci_ioremap_bar(pcidev, 0);
|
||||
+ if (!mite_base)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ /* set data window to main registers (BAR 1) */
|
||||
+ main_phys_addr = pci_resource_start(pcidev, 1);
|
||||
+ writel(main_phys_addr | WENAB, mite_base + MITE_IODWBSR);
|
||||
+
|
||||
+ /* finished with MITE registers */
|
||||
+ iounmap(mite_base);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static int pci_8255_mmio(int dir, int port, int data, unsigned long iobase)
|
||||
{
|
||||
void __iomem *mmio_base = (void __iomem *)iobase;
|
||||
@@ -205,6 +233,12 @@ static int pci_8255_auto_attach(struct comedi_device *dev,
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
+ if (board->has_mite) {
|
||||
+ ret = pci_8255_mite_init(pcidev);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
is_mmio = (pci_resource_flags(pcidev, board->dio_badr) &
|
||||
IORESOURCE_MEM) != 0;
|
||||
if (is_mmio) {
|
||||
diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c
|
||||
index 59d26ef538d8..3723c0ebb316 100644
|
||||
--- a/drivers/tty/tty_io.c
|
||||
+++ b/drivers/tty/tty_io.c
|
||||
@@ -1267,12 +1267,13 @@ static void pty_line_name(struct tty_driver *driver, int index, char *p)
|
||||
*
|
||||
* Locking: None
|
||||
*/
|
||||
-static void tty_line_name(struct tty_driver *driver, int index, char *p)
|
||||
+static ssize_t tty_line_name(struct tty_driver *driver, int index, char *p)
|
||||
{
|
||||
if (driver->flags & TTY_DRIVER_UNNUMBERED_NODE)
|
||||
- strcpy(p, driver->name);
|
||||
+ return sprintf(p, "%s", driver->name);
|
||||
else
|
||||
- sprintf(p, "%s%d", driver->name, index + driver->name_base);
|
||||
+ return sprintf(p, "%s%d", driver->name,
|
||||
+ index + driver->name_base);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -3538,9 +3539,19 @@ static ssize_t show_cons_active(struct device *dev,
|
||||
if (i >= ARRAY_SIZE(cs))
|
||||
break;
|
||||
}
|
||||
- while (i--)
|
||||
- count += sprintf(buf + count, "%s%d%c",
|
||||
- cs[i]->name, cs[i]->index, i ? ' ':'\n');
|
||||
+ while (i--) {
|
||||
+ int index = cs[i]->index;
|
||||
+ struct tty_driver *drv = cs[i]->device(cs[i], &index);
|
||||
+
|
||||
+ /* don't resolve tty0 as some programs depend on it */
|
||||
+ if (drv && (cs[i]->index > 0 || drv->major != TTY_MAJOR))
|
||||
+ count += tty_line_name(drv, index, buf + count);
|
||||
+ else
|
||||
+ count += sprintf(buf + count, "%s%d",
|
||||
+ cs[i]->name, cs[i]->index);
|
||||
+
|
||||
+ count += sprintf(buf + count, "%c", i ? ' ':'\n');
|
||||
+ }
|
||||
console_unlock();
|
||||
|
||||
return count;
|
||||
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
|
||||
index b8b60b660c8f..4354b9127713 100644
|
||||
--- a/fs/btrfs/disk-io.c
|
||||
+++ b/fs/btrfs/disk-io.c
|
||||
@@ -3161,6 +3161,8 @@ static int barrier_all_devices(struct btrfs_fs_info *info)
|
||||
/* send down all the barriers */
|
||||
head = &info->fs_devices->devices;
|
||||
list_for_each_entry_rcu(dev, head, dev_list) {
|
||||
+ if (dev->missing)
|
||||
+ continue;
|
||||
if (!dev->bdev) {
|
||||
errors_send++;
|
||||
continue;
|
||||
@@ -3175,6 +3177,8 @@ static int barrier_all_devices(struct btrfs_fs_info *info)
|
||||
|
||||
/* wait for all the barriers */
|
||||
list_for_each_entry_rcu(dev, head, dev_list) {
|
||||
+ if (dev->missing)
|
||||
+ continue;
|
||||
if (!dev->bdev) {
|
||||
errors_wait++;
|
||||
continue;
|
||||
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
|
||||
index a2b625e279db..84d817b842a8 100644
|
||||
--- a/fs/ext4/extents.c
|
||||
+++ b/fs/ext4/extents.c
|
||||
@@ -2511,6 +2511,27 @@ ext4_ext_rm_leaf(handle_t *handle, struct inode *inode,
|
||||
ex_ee_block = le32_to_cpu(ex->ee_block);
|
||||
ex_ee_len = ext4_ext_get_actual_len(ex);
|
||||
|
||||
+ /*
|
||||
+ * If we're starting with an extent other than the last one in the
|
||||
+ * node, we need to see if it shares a cluster with the extent to
|
||||
+ * the right (towards the end of the file). If its leftmost cluster
|
||||
+ * is this extent's rightmost cluster and it is not cluster aligned,
|
||||
+ * we'll mark it as a partial that is not to be deallocated.
|
||||
+ */
|
||||
+
|
||||
+ if (ex != EXT_LAST_EXTENT(eh)) {
|
||||
+ ext4_fsblk_t current_pblk, right_pblk;
|
||||
+ long long current_cluster, right_cluster;
|
||||
+
|
||||
+ current_pblk = ext4_ext_pblock(ex) + ex_ee_len - 1;
|
||||
+ current_cluster = (long long)EXT4_B2C(sbi, current_pblk);
|
||||
+ right_pblk = ext4_ext_pblock(ex + 1);
|
||||
+ right_cluster = (long long)EXT4_B2C(sbi, right_pblk);
|
||||
+ if (current_cluster == right_cluster &&
|
||||
+ EXT4_PBLK_COFF(sbi, right_pblk))
|
||||
+ *partial_cluster = -right_cluster;
|
||||
+ }
|
||||
+
|
||||
trace_ext4_ext_rm_leaf(inode, start, ex, *partial_cluster);
|
||||
|
||||
while (ex >= EXT_FIRST_EXTENT(eh) &&
|
||||
@@ -4032,7 +4053,7 @@ int ext4_ext_map_blocks(handle_t *handle, struct inode *inode,
|
||||
struct ext4_extent newex, *ex, *ex2;
|
||||
struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
|
||||
ext4_fsblk_t newblock = 0;
|
||||
- int free_on_err = 0, err = 0, depth;
|
||||
+ int free_on_err = 0, err = 0, depth, ret;
|
||||
unsigned int allocated = 0, offset = 0;
|
||||
unsigned int allocated_clusters = 0;
|
||||
struct ext4_allocation_request ar;
|
||||
@@ -4093,9 +4114,13 @@ int ext4_ext_map_blocks(handle_t *handle, struct inode *inode,
|
||||
if (!ext4_ext_is_uninitialized(ex))
|
||||
goto out;
|
||||
|
||||
- allocated = ext4_ext_handle_uninitialized_extents(
|
||||
+ ret = ext4_ext_handle_uninitialized_extents(
|
||||
handle, inode, map, path, flags,
|
||||
allocated, newblock);
|
||||
+ if (ret < 0)
|
||||
+ err = ret;
|
||||
+ else
|
||||
+ allocated = ret;
|
||||
goto out3;
|
||||
}
|
||||
}
|
||||
diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c
|
||||
index e3ab1e4dc442..387213ac2608 100644
|
||||
--- a/fs/fs-writeback.c
|
||||
+++ b/fs/fs-writeback.c
|
||||
@@ -87,16 +87,29 @@ static inline struct inode *wb_inode(struct list_head *head)
|
||||
#define CREATE_TRACE_POINTS
|
||||
#include <trace/events/writeback.h>
|
||||
|
||||
+static void bdi_wakeup_thread(struct backing_dev_info *bdi)
|
||||
+{
|
||||
+ spin_lock_bh(&bdi->wb_lock);
|
||||
+ if (test_bit(BDI_registered, &bdi->state))
|
||||
+ mod_delayed_work(bdi_wq, &bdi->wb.dwork, 0);
|
||||
+ spin_unlock_bh(&bdi->wb_lock);
|
||||
+}
|
||||
+
|
||||
static void bdi_queue_work(struct backing_dev_info *bdi,
|
||||
struct wb_writeback_work *work)
|
||||
{
|
||||
trace_writeback_queue(bdi, work);
|
||||
|
||||
spin_lock_bh(&bdi->wb_lock);
|
||||
+ if (!test_bit(BDI_registered, &bdi->state)) {
|
||||
+ if (work->done)
|
||||
+ complete(work->done);
|
||||
+ goto out_unlock;
|
||||
+ }
|
||||
list_add_tail(&work->list, &bdi->work_list);
|
||||
- spin_unlock_bh(&bdi->wb_lock);
|
||||
-
|
||||
mod_delayed_work(bdi_wq, &bdi->wb.dwork, 0);
|
||||
+out_unlock:
|
||||
+ spin_unlock_bh(&bdi->wb_lock);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -112,7 +125,7 @@ __bdi_start_writeback(struct backing_dev_info *bdi, long nr_pages,
|
||||
work = kzalloc(sizeof(*work), GFP_ATOMIC);
|
||||
if (!work) {
|
||||
trace_writeback_nowork(bdi);
|
||||
- mod_delayed_work(bdi_wq, &bdi->wb.dwork, 0);
|
||||
+ bdi_wakeup_thread(bdi);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -159,7 +172,7 @@ void bdi_start_background_writeback(struct backing_dev_info *bdi)
|
||||
* writeback as soon as there is no other work to do.
|
||||
*/
|
||||
trace_writeback_wake_background(bdi);
|
||||
- mod_delayed_work(bdi_wq, &bdi->wb.dwork, 0);
|
||||
+ bdi_wakeup_thread(bdi);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1016,7 +1029,7 @@ void bdi_writeback_workfn(struct work_struct *work)
|
||||
current->flags |= PF_SWAPWRITE;
|
||||
|
||||
if (likely(!current_is_workqueue_rescuer() ||
|
||||
- list_empty(&bdi->bdi_list))) {
|
||||
+ !test_bit(BDI_registered, &bdi->state))) {
|
||||
/*
|
||||
* The normal path. Keep writing back @bdi until its
|
||||
* work_list is empty. Note that this path is also taken
|
||||
@@ -1038,10 +1051,10 @@ void bdi_writeback_workfn(struct work_struct *work)
|
||||
trace_writeback_pages_written(pages_written);
|
||||
}
|
||||
|
||||
- if (!list_empty(&bdi->work_list) ||
|
||||
- (wb_has_dirty_io(wb) && dirty_writeback_interval))
|
||||
- queue_delayed_work(bdi_wq, &wb->dwork,
|
||||
- msecs_to_jiffies(dirty_writeback_interval * 10));
|
||||
+ if (!list_empty(&bdi->work_list))
|
||||
+ mod_delayed_work(bdi_wq, &wb->dwork, 0);
|
||||
+ else if (wb_has_dirty_io(wb) && dirty_writeback_interval)
|
||||
+ bdi_wakeup_thread_delayed(bdi);
|
||||
|
||||
current->flags &= ~PF_SWAPWRITE;
|
||||
}
|
||||
diff --git a/fs/jffs2/compr_rtime.c b/fs/jffs2/compr_rtime.c
|
||||
index 16a5047903a6..406d9cc84ba8 100644
|
||||
--- a/fs/jffs2/compr_rtime.c
|
||||
+++ b/fs/jffs2/compr_rtime.c
|
||||
@@ -33,7 +33,7 @@ static int jffs2_rtime_compress(unsigned char *data_in,
|
||||
unsigned char *cpage_out,
|
||||
uint32_t *sourcelen, uint32_t *dstlen)
|
||||
{
|
||||
- short positions[256];
|
||||
+ unsigned short positions[256];
|
||||
int outpos = 0;
|
||||
int pos=0;
|
||||
|
||||
@@ -74,7 +74,7 @@ static int jffs2_rtime_decompress(unsigned char *data_in,
|
||||
unsigned char *cpage_out,
|
||||
uint32_t srclen, uint32_t destlen)
|
||||
{
|
||||
- short positions[256];
|
||||
+ unsigned short positions[256];
|
||||
int outpos = 0;
|
||||
int pos=0;
|
||||
|
||||
diff --git a/fs/jffs2/nodelist.h b/fs/jffs2/nodelist.h
|
||||
index e4619b00f7c5..fa35ff79ab35 100644
|
||||
--- a/fs/jffs2/nodelist.h
|
||||
+++ b/fs/jffs2/nodelist.h
|
||||
@@ -231,7 +231,7 @@ struct jffs2_tmp_dnode_info
|
||||
uint32_t version;
|
||||
uint32_t data_crc;
|
||||
uint32_t partial_crc;
|
||||
- uint16_t csize;
|
||||
+ uint32_t csize;
|
||||
uint16_t overlapped;
|
||||
};
|
||||
|
||||
diff --git a/fs/jffs2/nodemgmt.c b/fs/jffs2/nodemgmt.c
|
||||
index 03310721712f..b6bd4affd9ad 100644
|
||||
--- a/fs/jffs2/nodemgmt.c
|
||||
+++ b/fs/jffs2/nodemgmt.c
|
||||
@@ -179,6 +179,7 @@ int jffs2_reserve_space(struct jffs2_sb_info *c, uint32_t minsize,
|
||||
spin_unlock(&c->erase_completion_lock);
|
||||
|
||||
schedule();
|
||||
+ remove_wait_queue(&c->erase_wait, &wait);
|
||||
} else
|
||||
spin_unlock(&c->erase_completion_lock);
|
||||
} else if (ret)
|
||||
@@ -211,20 +212,25 @@ out:
|
||||
int jffs2_reserve_space_gc(struct jffs2_sb_info *c, uint32_t minsize,
|
||||
uint32_t *len, uint32_t sumsize)
|
||||
{
|
||||
- int ret = -EAGAIN;
|
||||
+ int ret;
|
||||
minsize = PAD(minsize);
|
||||
|
||||
jffs2_dbg(1, "%s(): Requested 0x%x bytes\n", __func__, minsize);
|
||||
|
||||
- spin_lock(&c->erase_completion_lock);
|
||||
- while(ret == -EAGAIN) {
|
||||
+ while (true) {
|
||||
+ spin_lock(&c->erase_completion_lock);
|
||||
ret = jffs2_do_reserve_space(c, minsize, len, sumsize);
|
||||
if (ret) {
|
||||
jffs2_dbg(1, "%s(): looping, ret is %d\n",
|
||||
__func__, ret);
|
||||
}
|
||||
+ spin_unlock(&c->erase_completion_lock);
|
||||
+
|
||||
+ if (ret == -EAGAIN)
|
||||
+ cond_resched();
|
||||
+ else
|
||||
+ break;
|
||||
}
|
||||
- spin_unlock(&c->erase_completion_lock);
|
||||
if (!ret)
|
||||
ret = jffs2_prealloc_raw_node_refs(c, c->nextblock, 1);
|
||||
|
||||
diff --git a/include/linux/backing-dev.h b/include/linux/backing-dev.h
|
||||
index c3881553f7d1..4cfdbf28fc6a 100644
|
||||
--- a/include/linux/backing-dev.h
|
||||
+++ b/include/linux/backing-dev.h
|
||||
@@ -95,7 +95,7 @@ struct backing_dev_info {
|
||||
unsigned int max_ratio, max_prop_frac;
|
||||
|
||||
struct bdi_writeback wb; /* default writeback info for this bdi */
|
||||
- spinlock_t wb_lock; /* protects work_list */
|
||||
+ spinlock_t wb_lock; /* protects work_list & wb.dwork scheduling */
|
||||
|
||||
struct list_head work_list;
|
||||
|
||||
diff --git a/kernel/exit.c b/kernel/exit.c
|
||||
index 7bb73f9d09db..6682b2ea5b11 100644
|
||||
--- a/kernel/exit.c
|
||||
+++ b/kernel/exit.c
|
||||
@@ -570,9 +570,6 @@ static void reparent_leader(struct task_struct *father, struct task_struct *p,
|
||||
struct list_head *dead)
|
||||
{
|
||||
list_move_tail(&p->sibling, &p->real_parent->children);
|
||||
-
|
||||
- if (p->exit_state == EXIT_DEAD)
|
||||
- return;
|
||||
/*
|
||||
* If this is a threaded reparent there is no need to
|
||||
* notify anyone anything has happened.
|
||||
@@ -580,9 +577,19 @@ static void reparent_leader(struct task_struct *father, struct task_struct *p,
|
||||
if (same_thread_group(p->real_parent, father))
|
||||
return;
|
||||
|
||||
- /* We don't want people slaying init. */
|
||||
+ /*
|
||||
+ * We don't want people slaying init.
|
||||
+ *
|
||||
+ * Note: we do this even if it is EXIT_DEAD, wait_task_zombie()
|
||||
+ * can change ->exit_state to EXIT_ZOMBIE. If this is the final
|
||||
+ * state, do_notify_parent() was already called and ->exit_signal
|
||||
+ * doesn't matter.
|
||||
+ */
|
||||
p->exit_signal = SIGCHLD;
|
||||
|
||||
+ if (p->exit_state == EXIT_DEAD)
|
||||
+ return;
|
||||
+
|
||||
/* If it has exited notify the new parent about this child's death. */
|
||||
if (!p->ptrace &&
|
||||
p->exit_state == EXIT_ZOMBIE && thread_group_empty(p)) {
|
||||
@@ -794,6 +801,8 @@ void do_exit(long code)
|
||||
exit_shm(tsk);
|
||||
exit_files(tsk);
|
||||
exit_fs(tsk);
|
||||
+ if (group_dead)
|
||||
+ disassociate_ctty(1);
|
||||
exit_task_namespaces(tsk);
|
||||
exit_task_work(tsk);
|
||||
check_stack_usage();
|
||||
@@ -809,13 +818,9 @@ void do_exit(long code)
|
||||
|
||||
cgroup_exit(tsk, 1);
|
||||
|
||||
- if (group_dead)
|
||||
- disassociate_ctty(1);
|
||||
-
|
||||
module_put(task_thread_info(tsk)->exec_domain->module);
|
||||
|
||||
proc_exit_connector(tsk);
|
||||
-
|
||||
/*
|
||||
* FIXME: do that only when needed, using sched_exit tracepoint
|
||||
*/
|
||||
diff --git a/kernel/pid_namespace.c b/kernel/pid_namespace.c
|
||||
index 6917e8edb48e..e32703d5e0ab 100644
|
||||
--- a/kernel/pid_namespace.c
|
||||
+++ b/kernel/pid_namespace.c
|
||||
@@ -312,7 +312,9 @@ static void *pidns_get(struct task_struct *task)
|
||||
struct pid_namespace *ns;
|
||||
|
||||
rcu_read_lock();
|
||||
- ns = get_pid_ns(task_active_pid_ns(task));
|
||||
+ ns = task_active_pid_ns(task);
|
||||
+ if (ns)
|
||||
+ get_pid_ns(ns);
|
||||
rcu_read_unlock();
|
||||
|
||||
return ns;
|
||||
diff --git a/kernel/user_namespace.c b/kernel/user_namespace.c
|
||||
index 9064b919a406..9bea1d7dd21f 100644
|
||||
--- a/kernel/user_namespace.c
|
||||
+++ b/kernel/user_namespace.c
|
||||
@@ -148,7 +148,7 @@ static u32 map_id_range_down(struct uid_gid_map *map, u32 id, u32 count)
|
||||
|
||||
/* Find the matching extent */
|
||||
extents = map->nr_extents;
|
||||
- smp_read_barrier_depends();
|
||||
+ smp_rmb();
|
||||
for (idx = 0; idx < extents; idx++) {
|
||||
first = map->extent[idx].first;
|
||||
last = first + map->extent[idx].count - 1;
|
||||
@@ -172,7 +172,7 @@ static u32 map_id_down(struct uid_gid_map *map, u32 id)
|
||||
|
||||
/* Find the matching extent */
|
||||
extents = map->nr_extents;
|
||||
- smp_read_barrier_depends();
|
||||
+ smp_rmb();
|
||||
for (idx = 0; idx < extents; idx++) {
|
||||
first = map->extent[idx].first;
|
||||
last = first + map->extent[idx].count - 1;
|
||||
@@ -195,7 +195,7 @@ static u32 map_id_up(struct uid_gid_map *map, u32 id)
|
||||
|
||||
/* Find the matching extent */
|
||||
extents = map->nr_extents;
|
||||
- smp_read_barrier_depends();
|
||||
+ smp_rmb();
|
||||
for (idx = 0; idx < extents; idx++) {
|
||||
first = map->extent[idx].lower_first;
|
||||
last = first + map->extent[idx].count - 1;
|
||||
@@ -611,9 +611,8 @@ static ssize_t map_write(struct file *file, const char __user *buf,
|
||||
* were written before the count of the extents.
|
||||
*
|
||||
* To achieve this smp_wmb() is used on guarantee the write
|
||||
- * order and smp_read_barrier_depends() is guaranteed that we
|
||||
- * don't have crazy architectures returning stale data.
|
||||
- *
|
||||
+ * order and smp_rmb() is guaranteed that we don't have crazy
|
||||
+ * architectures returning stale data.
|
||||
*/
|
||||
mutex_lock(&id_map_mutex);
|
||||
|
||||
diff --git a/mm/backing-dev.c b/mm/backing-dev.c
|
||||
index 502517492258..eea1a9dfac38 100644
|
||||
--- a/mm/backing-dev.c
|
||||
+++ b/mm/backing-dev.c
|
||||
@@ -287,13 +287,19 @@ int bdi_has_dirty_io(struct backing_dev_info *bdi)
|
||||
* Note, we wouldn't bother setting up the timer, but this function is on the
|
||||
* fast-path (used by '__mark_inode_dirty()'), so we save few context switches
|
||||
* by delaying the wake-up.
|
||||
+ *
|
||||
+ * We have to be careful not to postpone flush work if it is scheduled for
|
||||
+ * earlier. Thus we use queue_delayed_work().
|
||||
*/
|
||||
void bdi_wakeup_thread_delayed(struct backing_dev_info *bdi)
|
||||
{
|
||||
unsigned long timeout;
|
||||
|
||||
timeout = msecs_to_jiffies(dirty_writeback_interval * 10);
|
||||
- mod_delayed_work(bdi_wq, &bdi->wb.dwork, timeout);
|
||||
+ spin_lock_bh(&bdi->wb_lock);
|
||||
+ if (test_bit(BDI_registered, &bdi->state))
|
||||
+ queue_delayed_work(bdi_wq, &bdi->wb.dwork, timeout);
|
||||
+ spin_unlock_bh(&bdi->wb_lock);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -306,9 +312,6 @@ static void bdi_remove_from_list(struct backing_dev_info *bdi)
|
||||
spin_unlock_bh(&bdi_lock);
|
||||
|
||||
synchronize_rcu_expedited();
|
||||
-
|
||||
- /* bdi_list is now unused, clear it to mark @bdi dying */
|
||||
- INIT_LIST_HEAD(&bdi->bdi_list);
|
||||
}
|
||||
|
||||
int bdi_register(struct backing_dev_info *bdi, struct device *parent,
|
||||
@@ -359,6 +362,11 @@ static void bdi_wb_shutdown(struct backing_dev_info *bdi)
|
||||
*/
|
||||
bdi_remove_from_list(bdi);
|
||||
|
||||
+ /* Make sure nobody queues further work */
|
||||
+ spin_lock_bh(&bdi->wb_lock);
|
||||
+ clear_bit(BDI_registered, &bdi->state);
|
||||
+ spin_unlock_bh(&bdi->wb_lock);
|
||||
+
|
||||
/*
|
||||
* Drain work list and shutdown the delayed_work. At this point,
|
||||
* @bdi->bdi_list is empty telling bdi_Writeback_workfn() that @bdi
|
||||
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
|
||||
index dcaa6dbbab2c..cfca44f8d048 100644
|
||||
--- a/net/bluetooth/hci_event.c
|
||||
+++ b/net/bluetooth/hci_event.c
|
||||
@@ -3619,7 +3619,13 @@ static void hci_le_ltk_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
|
||||
|
||||
hci_send_cmd(hdev, HCI_OP_LE_LTK_REPLY, sizeof(cp), &cp);
|
||||
|
||||
- if (ltk->type & HCI_SMP_STK) {
|
||||
+ /* Ref. Bluetooth Core SPEC pages 1975 and 2004. STK is a
|
||||
+ * temporary key used to encrypt a connection following
|
||||
+ * pairing. It is used during the Encrypted Session Setup to
|
||||
+ * distribute the keys. Later, security can be re-established
|
||||
+ * using a distributed LTK.
|
||||
+ */
|
||||
+ if (ltk->type == HCI_SMP_STK_SLAVE) {
|
||||
list_del(<k->list);
|
||||
kfree(ltk);
|
||||
}
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,21 +0,0 @@
|
||||
diff --git a/init/main.c b/init/main.c
|
||||
index 9484f4b..db55edd 100644
|
||||
--- a/init/main.c
|
||||
+++ b/init/main.c
|
||||
@@ -880,8 +880,14 @@ static noinline void __init kernel_init_freeable(void)
|
||||
do_basic_setup();
|
||||
|
||||
/* Open the /dev/console on the rootfs, this should never fail */
|
||||
- if (sys_open((const char __user *) "/dev/console", O_RDWR, 0) < 0)
|
||||
- pr_err("Warning: unable to open an initial console.\n");
|
||||
+ char *console = "/dev_console";
|
||||
+
|
||||
+ if (sys_open((const char __user *) "/dev/console", O_RDWR, 0) < 0) {
|
||||
+ sys_mknod(console, S_IFCHR|0600, (TTYAUX_MAJOR<<8)|1);
|
||||
+ if (sys_open(console, O_RDWR, 0) < 0)
|
||||
+ printk(KERN_WARNING "Warning: unable to open an initial console.\n");
|
||||
+ sys_unlink(console);
|
||||
+ }
|
||||
|
||||
(void) sys_dup(0);
|
||||
(void) sys_dup(0);
|
@ -1,18 +0,0 @@
|
||||
diff --git a/tools/perf/Makefile b/tools/perf/Makefile
|
||||
index b0f164b..ecb1af6 100644
|
||||
--- a/tools/perf/Makefile
|
||||
+++ b/tools/perf/Makefile
|
||||
@@ -687,12 +687,10 @@ ifndef NO_LIBAUDIT
|
||||
endif
|
||||
|
||||
ifndef NO_SLANG
|
||||
- FLAGS_SLANG=$(ALL_CFLAGS) $(ALL_LDFLAGS) $(EXTLIBS) -I/usr/include/slang -lslang
|
||||
+ FLAGS_SLANG=$(ALL_CFLAGS) $(ALL_LDFLAGS) $(EXTLIBS) -lslang
|
||||
ifneq ($(call try-cc,$(SOURCE_SLANG),$(FLAGS_SLANG),libslang),y)
|
||||
msg := $(warning slang not found, disables TUI support. Please install slang-devel or libslang-dev);
|
||||
else
|
||||
- # Fedora has /usr/include/slang/slang.h, but ubuntu /usr/include/slang.h
|
||||
- BASIC_CFLAGS += -I/usr/include/slang
|
||||
BASIC_CFLAGS += -DSLANG_SUPPORT
|
||||
EXTLIBS += -lslang
|
||||
LIB_OBJS += $(OUTPUT)ui/browser.o
|
File diff suppressed because it is too large
Load Diff
@ -1,161 +0,0 @@
|
||||
diff -Naur linux-3.9/drivers/hid/hid-core.c linux-3.9.patch/drivers/hid/hid-core.c
|
||||
--- linux-3.9/drivers/hid/hid-core.c 2013-04-29 02:36:01.000000000 +0200
|
||||
+++ linux-3.9.patch/drivers/hid/hid-core.c 2013-04-29 17:08:40.528324010 +0200
|
||||
@@ -1681,6 +1681,9 @@
|
||||
{ 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_PETALYNX, USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE) },
|
||||
+ { HID_USB_DEVICE(USB_VENDOR_ID_PHILIPS, USB_DEVICE_ID_PHILIPS_SPINEL_PLUS_1) },
|
||||
+ { HID_USB_DEVICE(USB_VENDOR_ID_PHILIPS, USB_DEVICE_ID_PHILIPS_SPINEL_PLUS_2) },
|
||||
+ { HID_USB_DEVICE(USB_VENDOR_ID_PHILIPS, USB_DEVICE_ID_PHILIPS_SPINEL_PLUS_3) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_PRIMAX, USB_DEVICE_ID_PRIMAX_KEYBOARD) },
|
||||
#if IS_ENABLED(CONFIG_HID_ROCCAT)
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_KONE) },
|
||||
diff -Naur linux-3.9/drivers/hid/hid-ids.h linux-3.9.patch/drivers/hid/hid-ids.h
|
||||
--- linux-3.9/drivers/hid/hid-ids.h 2013-04-29 02:36:01.000000000 +0200
|
||||
+++ linux-3.9.patch/drivers/hid/hid-ids.h 2013-04-29 17:08:40.537323981 +0200
|
||||
@@ -663,6 +663,9 @@
|
||||
|
||||
#define USB_VENDOR_ID_PHILIPS 0x0471
|
||||
#define USB_DEVICE_ID_PHILIPS_IEEE802154_DONGLE 0x0617
|
||||
+#define USB_DEVICE_ID_PHILIPS_SPINEL_PLUS_1 0x206c
|
||||
+#define USB_DEVICE_ID_PHILIPS_SPINEL_PLUS_2 0x20cc
|
||||
+#define USB_DEVICE_ID_PHILIPS_SPINEL_PLUS_3 0x0613
|
||||
|
||||
#define USB_VENDOR_ID_PI_ENGINEERING 0x05f3
|
||||
#define USB_DEVICE_ID_PI_ENGINEERING_VEC_USB_FOOTPEDAL 0xff
|
||||
diff -Naur linux-3.9/drivers/hid/hid-spinelplus.c linux-3.9.patch/drivers/hid/hid-spinelplus.c
|
||||
--- linux-3.9/drivers/hid/hid-spinelplus.c 1970-01-01 01:00:00.000000000 +0100
|
||||
+++ linux-3.9.patch/drivers/hid/hid-spinelplus.c 2013-04-29 17:08:40.537323981 +0200
|
||||
@@ -0,0 +1,104 @@
|
||||
+/*
|
||||
+ * HID driver for "PHILIPS MCE USB IR Receiver- Spinel plus" remotes
|
||||
+ *
|
||||
+ * Copyright (c) 2010 Panagiotis Skintzos
|
||||
+ *
|
||||
+ * Renamed to Spinel, cleanup and modified to also support
|
||||
+ * Spinel Plus 0471:20CC by Stephan Raue 2012.
|
||||
+ */
|
||||
+
|
||||
+/*
|
||||
+ * 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/input.h>
|
||||
+#include <linux/hid.h>
|
||||
+#include <linux/module.h>
|
||||
+
|
||||
+#include "hid-ids.h"
|
||||
+
|
||||
+#define spinelplus_map_key(c) set_bit(EV_REP, hi->input->evbit); \
|
||||
+ hid_map_usage_clear(hi, usage, bit, max, EV_KEY, (c))
|
||||
+
|
||||
+static int spinelplus_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) {
|
||||
+ case 0xffbc000d: spinelplus_map_key(KEY_MEDIA); break;
|
||||
+ case 0xffbc0024: spinelplus_map_key(KEY_MEDIA); break;
|
||||
+ case 0xffbc0027: spinelplus_map_key(KEY_ZOOM); break;
|
||||
+ case 0xffbc0033: spinelplus_map_key(KEY_HOME); break;
|
||||
+ case 0xffbc0035: spinelplus_map_key(KEY_CAMERA); break;
|
||||
+ case 0xffbc0036: spinelplus_map_key(KEY_EPG); break;
|
||||
+ case 0xffbc0037: spinelplus_map_key(KEY_DVD); break;
|
||||
+ case 0xffbc0038: spinelplus_map_key(KEY_HOME); break;
|
||||
+ case 0xffbc0039: spinelplus_map_key(KEY_MP3); break;
|
||||
+ case 0xffbc003a: spinelplus_map_key(KEY_VIDEO); break;
|
||||
+ case 0xffbc005a: spinelplus_map_key(KEY_TEXT); break;
|
||||
+ case 0xffbc005b: spinelplus_map_key(KEY_RED); break;
|
||||
+ case 0xffbc005c: spinelplus_map_key(KEY_GREEN); break;
|
||||
+ case 0xffbc005d: spinelplus_map_key(KEY_YELLOW); break;
|
||||
+ case 0xffbc005e: spinelplus_map_key(KEY_BLUE); break;
|
||||
+ default:
|
||||
+ return 0;
|
||||
+ }
|
||||
+ return 1;
|
||||
+}
|
||||
+
|
||||
+static int spinelplus_probe(struct hid_device *hdev,
|
||||
+ const struct hid_device_id *id)
|
||||
+{
|
||||
+ int ret;
|
||||
+ /* Connect only to hid input (not hiddev & hidraw)*/
|
||||
+ unsigned int cmask = HID_CONNECT_HIDINPUT;
|
||||
+
|
||||
+ ret = hid_parse(hdev);
|
||||
+ if (ret) {
|
||||
+ dev_err(&hdev->dev, "parse failed\n");
|
||||
+ goto err_free;
|
||||
+ }
|
||||
+
|
||||
+ ret = hid_hw_start(hdev, cmask);
|
||||
+ if (ret) {
|
||||
+ dev_err(&hdev->dev, "hw start failed\n");
|
||||
+ goto err_free;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+err_free:
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static const struct hid_device_id spinelplus_devices[] = {
|
||||
+ { HID_USB_DEVICE(USB_VENDOR_ID_PHILIPS,USB_DEVICE_ID_PHILIPS_SPINEL_PLUS_1) },
|
||||
+ { HID_USB_DEVICE(USB_VENDOR_ID_PHILIPS,USB_DEVICE_ID_PHILIPS_SPINEL_PLUS_2) },
|
||||
+ { HID_USB_DEVICE(USB_VENDOR_ID_PHILIPS,USB_DEVICE_ID_PHILIPS_SPINEL_PLUS_3) },
|
||||
+ { }
|
||||
+};
|
||||
+MODULE_DEVICE_TABLE(hid, spinelplus_devices);
|
||||
+
|
||||
+static struct hid_driver spinelplus_driver = {
|
||||
+ .name = "SpinelPlus",
|
||||
+ .id_table = spinelplus_devices,
|
||||
+ .input_mapping = spinelplus_input_mapping,
|
||||
+ .probe = spinelplus_probe,
|
||||
+};
|
||||
+
|
||||
+static int __init spinelplus_init(void)
|
||||
+{
|
||||
+ return hid_register_driver(&spinelplus_driver);
|
||||
+}
|
||||
+
|
||||
+static void __exit spinelplus_exit(void)
|
||||
+{
|
||||
+ hid_unregister_driver(&spinelplus_driver);
|
||||
+}
|
||||
+
|
||||
+module_init(spinelplus_init);
|
||||
+module_exit(spinelplus_exit);
|
||||
+MODULE_LICENSE("GPL");
|
||||
diff -Naur linux-3.9/drivers/hid/Kconfig linux-3.9.patch/drivers/hid/Kconfig
|
||||
--- linux-3.9/drivers/hid/Kconfig 2013-04-29 02:36:01.000000000 +0200
|
||||
+++ linux-3.9.patch/drivers/hid/Kconfig 2013-04-29 17:08:40.538323977 +0200
|
||||
@@ -602,6 +602,12 @@
|
||||
---help---
|
||||
Support for Steelseries SRW-S1 steering wheel
|
||||
|
||||
+config HID_SPINELPLUS
|
||||
+ tristate "Spinel Plus remote control"
|
||||
+ depends on USB_HID
|
||||
+ ---help---
|
||||
+ Say Y here if you have a Spinel Plus (0471:206c/20cc/0613) remote
|
||||
+
|
||||
config HID_SUNPLUS
|
||||
tristate "Sunplus wireless desktop"
|
||||
depends on USB_HID
|
||||
diff -Naur linux-3.9/drivers/hid/Makefile linux-3.9.patch/drivers/hid/Makefile
|
||||
--- linux-3.9/drivers/hid/Makefile 2013-04-29 02:36:01.000000000 +0200
|
||||
+++ linux-3.9.patch/drivers/hid/Makefile 2013-04-29 17:09:26.744173841 +0200
|
||||
@@ -101,6 +101,7 @@
|
||||
obj-$(CONFIG_HID_SMARTJOYPLUS) += hid-sjoy.o
|
||||
obj-$(CONFIG_HID_SONY) += hid-sony.o
|
||||
obj-$(CONFIG_HID_SPEEDLINK) += hid-speedlink.o
|
||||
+obj-$(CONFIG_HID_SPINELPLUS) += hid-spinelplus.o
|
||||
obj-$(CONFIG_HID_STEELSERIES) += hid-steelseries.o
|
||||
obj-$(CONFIG_HID_SUNPLUS) += hid-sunplus.o
|
||||
obj-$(CONFIG_HID_GREENASIA) += hid-gaff.o
|
@ -1,11 +0,0 @@
|
||||
--- linux-3.2.2.orig/drivers/media/rc/mceusb.c 2012-01-30 23:37:12.374473509 +0100
|
||||
+++ linux-3.2.2/drivers/media/rc/mceusb.c 2012-01-30 23:40:57.989652931 +0100
|
||||
@@ -350,6 +350,8 @@
|
||||
{ USB_DEVICE(VENDOR_FORMOSA, 0xe015) },
|
||||
/* Formosa21 / eHome Infrared Receiver */
|
||||
{ USB_DEVICE(VENDOR_FORMOSA, 0xe016) },
|
||||
+ /* Formosa21 / eHome Infrared Receiver */
|
||||
+ { USB_DEVICE(VENDOR_FORMOSA, 0xe042) },
|
||||
/* Formosa aim / Trust MCE Infrared Receiver */
|
||||
{ USB_DEVICE(VENDOR_FORMOSA, 0xe017),
|
||||
.driver_info = MCE_GEN2_NO_TX },
|
@ -1,20 +0,0 @@
|
||||
diff -Naur linux-3.6.7/drivers/media/rc/mceusb.c linux-3.6.7.patch/drivers/media/rc/mceusb.c
|
||||
--- linux-3.6.7/drivers/media/rc/mceusb.c 2012-11-29 04:45:51.142129739 +0100
|
||||
+++ linux-3.6.7.patch/drivers/media/rc/mceusb.c 2012-11-29 04:51:30.982828558 +0100
|
||||
@@ -200,6 +200,7 @@
|
||||
#define VENDOR_TIVO 0x105a
|
||||
#define VENDOR_CONEXANT 0x0572
|
||||
#define VENDOR_TWISTEDMELON 0x2596
|
||||
+#define VENDOR_ADAPTEC 0x03f3
|
||||
|
||||
enum mceusb_model_type {
|
||||
MCE_GEN2 = 0, /* Most boards */
|
||||
@@ -400,6 +401,8 @@
|
||||
{ USB_DEVICE(VENDOR_TWISTEDMELON, 0x8016) },
|
||||
/* Twisted Melon Inc. - Manta Transceiver */
|
||||
{ USB_DEVICE(VENDOR_TWISTEDMELON, 0x8042) },
|
||||
+ /* Adaptec / HP eHome Receiver */
|
||||
+ { USB_DEVICE(VENDOR_ADAPTEC, 0x0094) },
|
||||
/* Terminating entry */
|
||||
{ }
|
||||
};
|
@ -1,22 +0,0 @@
|
||||
--- linux/drivers/media/rc/ir-rc6-decoder.c 2012-11-25 22:08:13.148418669 -0800
|
||||
+++ linux.patch/drivers/media/rc/ir-rc6-decoder.c 2012-11-25 22:07:48.864417975 -0800
|
||||
@@ -39,7 +39,6 @@
|
||||
#define RC6_STARTBIT_MASK 0x08 /* for the header bits */
|
||||
#define RC6_6A_MCE_TOGGLE_MASK 0x8000 /* for the body bits */
|
||||
#define RC6_6A_LCC_MASK 0xffff0000 /* RC6-6A-32 long customer code mask */
|
||||
-#define RC6_6A_MCE_CC 0x800f0000 /* MCE customer code */
|
||||
#ifndef CHAR_BIT
|
||||
#define CHAR_BIT 8 /* Normally in <limits.h> */
|
||||
#endif
|
||||
@@ -242,9 +241,8 @@ again:
|
||||
}
|
||||
|
||||
scancode = data->body;
|
||||
- if (data->count == RC6_6A_32_NBITS &&
|
||||
- (scancode & RC6_6A_LCC_MASK) == RC6_6A_MCE_CC) {
|
||||
- /* MCE RC */
|
||||
+ if (data->count == RC6_6A_32_NBITS) {
|
||||
+ /* MCE compatible RC */
|
||||
toggle = (scancode & RC6_6A_MCE_TOGGLE_MASK) ? 1 : 0;
|
||||
scancode &= ~RC6_6A_MCE_TOGGLE_MASK;
|
||||
} else {
|
@ -1,13 +0,0 @@
|
||||
diff -Naur linux-3.9.4/drivers/media/rc/mceusb.c linux-3.9.4.patch/drivers/media/rc/mceusb.c
|
||||
--- linux-3.9.4/drivers/media/rc/mceusb.c 2013-05-24 20:45:59.000000000 +0200
|
||||
+++ linux-3.9.4.patch/drivers/media/rc/mceusb.c 2013-05-27 12:28:12.811230633 +0200
|
||||
@@ -309,6 +309,9 @@
|
||||
/* SMK/I-O Data GV-MC7/RCKIT Receiver */
|
||||
{ USB_DEVICE(VENDOR_SMK, 0x0353),
|
||||
.driver_info = MCE_GEN2_NO_TX },
|
||||
+ /* SMK Manufacturing, Inc. Receiver */
|
||||
+ { USB_DEVICE(VENDOR_SMK, 0x0357),
|
||||
+ .driver_info = MCE_GEN2_NO_TX },
|
||||
/* Tatung eHome Infrared Transceiver */
|
||||
{ USB_DEVICE(VENDOR_TATUNG, 0x9150) },
|
||||
/* Shuttle eHome Infrared Transceiver */
|
@ -1,867 +0,0 @@
|
||||
diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig
|
||||
index 427b759..22d320e 100644
|
||||
--- a/drivers/hid/Kconfig
|
||||
+++ b/drivers/hid/Kconfig
|
||||
@@ -561,15 +561,6 @@ config HID_PRIMAX
|
||||
Support for Primax devices that are not fully compliant with the
|
||||
HID standard.
|
||||
|
||||
-config HID_PS3REMOTE
|
||||
- tristate "Sony PS3 BD Remote Control"
|
||||
- depends on HID
|
||||
- ---help---
|
||||
- Support for the Sony PS3 Blue-ray Disk Remote Control and Logitech
|
||||
- Harmony Adapter for PS3, which connect over Bluetooth.
|
||||
-
|
||||
- Support for the 6-axis controllers is provided by HID_SONY.
|
||||
-
|
||||
config HID_ROCCAT
|
||||
tristate "Roccat device support"
|
||||
depends on USB_HID
|
||||
@@ -594,12 +585,17 @@ config HID_SAMSUNG
|
||||
Support for Samsung InfraRed remote control or keyboards.
|
||||
|
||||
config HID_SONY
|
||||
- tristate "Sony PS3 controller"
|
||||
+ tristate "Sony PS2/3 accessories"
|
||||
depends on USB_HID
|
||||
+ depends on NEW_LEDS
|
||||
+ depends on LEDS_CLASS
|
||||
---help---
|
||||
- Support for Sony PS3 6-axis controllers.
|
||||
-
|
||||
- Support for the Sony PS3 BD Remote is provided by HID_PS3REMOTE.
|
||||
+ Support for
|
||||
+
|
||||
+ * Sony PS3 6-axis controllers
|
||||
+ * Buzz controllers
|
||||
+ * Sony PS3 Blue-ray Disk Remote Control (Bluetooth)
|
||||
+ * Logitech Harmony adapter for Sony Playstation 3 (Bluetooth)
|
||||
|
||||
config HID_SPEEDLINK
|
||||
tristate "Speedlink VAD Cezanne mouse support"
|
||||
diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile
|
||||
index b545124..419b7ca 100644
|
||||
--- a/drivers/hid/Makefile
|
||||
+++ b/drivers/hid/Makefile
|
||||
@@ -92,7 +92,6 @@ hid-picolcd-y += hid-picolcd_debugfs.o
|
||||
endif
|
||||
|
||||
obj-$(CONFIG_HID_PRIMAX) += hid-primax.o
|
||||
-obj-$(CONFIG_HID_PS3REMOTE) += hid-ps3remote.o
|
||||
obj-$(CONFIG_HID_ROCCAT) += hid-roccat.o hid-roccat-common.o \
|
||||
hid-roccat-arvo.o hid-roccat-isku.o hid-roccat-kone.o \
|
||||
hid-roccat-koneplus.o hid-roccat-konepure.o hid-roccat-kovaplus.o \
|
||||
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
|
||||
index b885a28..37e35c0 100644
|
||||
--- a/drivers/hid/hid-core.c
|
||||
+++ b/drivers/hid/hid-core.c
|
||||
@@ -1683,6 +1683,8 @@ static const struct hid_device_id hid_have_special_driver[] = {
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_IR_REMOTE) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_WIRELESS_KBD_MOUSE) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_SKYCABLE, USB_DEVICE_ID_SKYCABLE_WIRELESS_PRESENTER) },
|
||||
+ { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_BUZZ_CONTROLLER) },
|
||||
+ { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_WIRELESS_BUZZ_CONTROLLER) },
|
||||
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_BDREMOTE) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_NAVIGATION_CONTROLLER) },
|
||||
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
|
||||
index 56b224e..c11cca1 100644
|
||||
--- a/drivers/hid/hid-ids.h
|
||||
+++ b/drivers/hid/hid-ids.h
|
||||
@@ -737,6 +737,8 @@
|
||||
#define USB_DEVICE_ID_SONY_PS3_BDREMOTE 0x0306
|
||||
#define USB_DEVICE_ID_SONY_PS3_CONTROLLER 0x0268
|
||||
#define USB_DEVICE_ID_SONY_NAVIGATION_CONTROLLER 0x042f
|
||||
+#define USB_DEVICE_ID_SONY_BUZZ_CONTROLLER 0x0002
|
||||
+#define USB_DEVICE_ID_SONY_WIRELESS_BUZZ_CONTROLLER 0x1000
|
||||
|
||||
#define USB_VENDOR_ID_SOUNDGRAPH 0x15c2
|
||||
#define USB_DEVICE_ID_SOUNDGRAPH_IMON_FIRST 0x0034
|
||||
diff --git a/drivers/hid/hid-ps3remote.c b/drivers/hid/hid-ps3remote.c
|
||||
deleted file mode 100644
|
||||
index f1239d3..0000000
|
||||
--- a/drivers/hid/hid-ps3remote.c
|
||||
+++ /dev/null
|
||||
@@ -1,204 +0,0 @@
|
||||
-/*
|
||||
- * HID driver for Sony PS3 BD Remote Control
|
||||
- *
|
||||
- * Copyright (c) 2012 David Dillow <dave@thedillows.org>
|
||||
- * Based on a blend of the bluez fakehid user-space code by Marcel Holtmann
|
||||
- * and other kernel HID drivers.
|
||||
- */
|
||||
-
|
||||
-/*
|
||||
- * 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.
|
||||
- */
|
||||
-
|
||||
-/* NOTE: in order for the Sony PS3 BD Remote Control to be found by
|
||||
- * a Bluetooth host, the key combination Start+Enter has to be kept pressed
|
||||
- * for about 7 seconds with the Bluetooth Host Controller in discovering mode.
|
||||
- *
|
||||
- * There will be no PIN request from the device.
|
||||
- */
|
||||
-
|
||||
-#include <linux/device.h>
|
||||
-#include <linux/hid.h>
|
||||
-#include <linux/module.h>
|
||||
-
|
||||
-#include "hid-ids.h"
|
||||
-
|
||||
-static __u8 ps3remote_rdesc[] = {
|
||||
- 0x05, 0x01, /* GUsagePage Generic Desktop */
|
||||
- 0x09, 0x05, /* LUsage 0x05 [Game Pad] */
|
||||
- 0xA1, 0x01, /* MCollection Application (mouse, keyboard) */
|
||||
-
|
||||
- /* Use collection 1 for joypad buttons */
|
||||
- 0xA1, 0x02, /* MCollection Logical (interrelated data) */
|
||||
-
|
||||
- /* Ignore the 1st byte, maybe it is used for a controller
|
||||
- * number but it's not needed for correct operation */
|
||||
- 0x75, 0x08, /* GReportSize 0x08 [8] */
|
||||
- 0x95, 0x01, /* GReportCount 0x01 [1] */
|
||||
- 0x81, 0x01, /* MInput 0x01 (Const[0] Arr[1] Abs[2]) */
|
||||
-
|
||||
- /* Bytes from 2nd to 4th are a bitmap for joypad buttons, for these
|
||||
- * buttons multiple keypresses are allowed */
|
||||
- 0x05, 0x09, /* GUsagePage Button */
|
||||
- 0x19, 0x01, /* LUsageMinimum 0x01 [Button 1 (primary/trigger)] */
|
||||
- 0x29, 0x18, /* LUsageMaximum 0x18 [Button 24] */
|
||||
- 0x14, /* GLogicalMinimum [0] */
|
||||
- 0x25, 0x01, /* GLogicalMaximum 0x01 [1] */
|
||||
- 0x75, 0x01, /* GReportSize 0x01 [1] */
|
||||
- 0x95, 0x18, /* GReportCount 0x18 [24] */
|
||||
- 0x81, 0x02, /* MInput 0x02 (Data[0] Var[1] Abs[2]) */
|
||||
-
|
||||
- 0xC0, /* MEndCollection */
|
||||
-
|
||||
- /* Use collection 2 for remote control buttons */
|
||||
- 0xA1, 0x02, /* MCollection Logical (interrelated data) */
|
||||
-
|
||||
- /* 5th byte is used for remote control buttons */
|
||||
- 0x05, 0x09, /* GUsagePage Button */
|
||||
- 0x18, /* LUsageMinimum [No button pressed] */
|
||||
- 0x29, 0xFE, /* LUsageMaximum 0xFE [Button 254] */
|
||||
- 0x14, /* GLogicalMinimum [0] */
|
||||
- 0x26, 0xFE, 0x00, /* GLogicalMaximum 0x00FE [254] */
|
||||
- 0x75, 0x08, /* GReportSize 0x08 [8] */
|
||||
- 0x95, 0x01, /* GReportCount 0x01 [1] */
|
||||
- 0x80, /* MInput */
|
||||
-
|
||||
- /* Ignore bytes from 6th to 11th, 6th to 10th are always constant at
|
||||
- * 0xff and 11th is for press indication */
|
||||
- 0x75, 0x08, /* GReportSize 0x08 [8] */
|
||||
- 0x95, 0x06, /* GReportCount 0x06 [6] */
|
||||
- 0x81, 0x01, /* MInput 0x01 (Const[0] Arr[1] Abs[2]) */
|
||||
-
|
||||
- /* 12th byte is for battery strength */
|
||||
- 0x05, 0x06, /* GUsagePage Generic Device Controls */
|
||||
- 0x09, 0x20, /* LUsage 0x20 [Battery Strength] */
|
||||
- 0x14, /* GLogicalMinimum [0] */
|
||||
- 0x25, 0x05, /* GLogicalMaximum 0x05 [5] */
|
||||
- 0x75, 0x08, /* GReportSize 0x08 [8] */
|
||||
- 0x95, 0x01, /* GReportCount 0x01 [1] */
|
||||
- 0x81, 0x02, /* MInput 0x02 (Data[0] Var[1] Abs[2]) */
|
||||
-
|
||||
- 0xC0, /* MEndCollection */
|
||||
-
|
||||
- 0xC0 /* MEndCollection [Game Pad] */
|
||||
-};
|
||||
-
|
||||
-static const unsigned int ps3remote_keymap_joypad_buttons[] = {
|
||||
- [0x01] = KEY_SELECT,
|
||||
- [0x02] = BTN_THUMBL, /* L3 */
|
||||
- [0x03] = BTN_THUMBR, /* R3 */
|
||||
- [0x04] = BTN_START,
|
||||
- [0x05] = KEY_UP,
|
||||
- [0x06] = KEY_RIGHT,
|
||||
- [0x07] = KEY_DOWN,
|
||||
- [0x08] = KEY_LEFT,
|
||||
- [0x09] = BTN_TL2, /* L2 */
|
||||
- [0x0a] = BTN_TR2, /* R2 */
|
||||
- [0x0b] = BTN_TL, /* L1 */
|
||||
- [0x0c] = BTN_TR, /* R1 */
|
||||
- [0x0d] = KEY_OPTION, /* options/triangle */
|
||||
- [0x0e] = KEY_BACK, /* back/circle */
|
||||
- [0x0f] = BTN_0, /* cross */
|
||||
- [0x10] = KEY_SCREEN, /* view/square */
|
||||
- [0x11] = KEY_HOMEPAGE, /* PS button */
|
||||
- [0x14] = KEY_ENTER,
|
||||
-};
|
||||
-static const unsigned int ps3remote_keymap_remote_buttons[] = {
|
||||
- [0x00] = KEY_1,
|
||||
- [0x01] = KEY_2,
|
||||
- [0x02] = KEY_3,
|
||||
- [0x03] = KEY_4,
|
||||
- [0x04] = KEY_5,
|
||||
- [0x05] = KEY_6,
|
||||
- [0x06] = KEY_7,
|
||||
- [0x07] = KEY_8,
|
||||
- [0x08] = KEY_9,
|
||||
- [0x09] = KEY_0,
|
||||
- [0x0e] = KEY_ESC, /* return */
|
||||
- [0x0f] = KEY_CLEAR,
|
||||
- [0x16] = KEY_EJECTCD,
|
||||
- [0x1a] = KEY_MENU, /* top menu */
|
||||
- [0x28] = KEY_TIME,
|
||||
- [0x30] = KEY_PREVIOUS,
|
||||
- [0x31] = KEY_NEXT,
|
||||
- [0x32] = KEY_PLAY,
|
||||
- [0x33] = KEY_REWIND, /* scan back */
|
||||
- [0x34] = KEY_FORWARD, /* scan forward */
|
||||
- [0x38] = KEY_STOP,
|
||||
- [0x39] = KEY_PAUSE,
|
||||
- [0x40] = KEY_CONTEXT_MENU, /* pop up/menu */
|
||||
- [0x60] = KEY_FRAMEBACK, /* slow/step back */
|
||||
- [0x61] = KEY_FRAMEFORWARD, /* slow/step forward */
|
||||
- [0x63] = KEY_SUBTITLE,
|
||||
- [0x64] = KEY_AUDIO,
|
||||
- [0x65] = KEY_ANGLE,
|
||||
- [0x70] = KEY_INFO, /* display */
|
||||
- [0x80] = KEY_BLUE,
|
||||
- [0x81] = KEY_RED,
|
||||
- [0x82] = KEY_GREEN,
|
||||
- [0x83] = KEY_YELLOW,
|
||||
-};
|
||||
-
|
||||
-static __u8 *ps3remote_fixup(struct hid_device *hdev, __u8 *rdesc,
|
||||
- unsigned int *rsize)
|
||||
-{
|
||||
- *rsize = sizeof(ps3remote_rdesc);
|
||||
- return ps3remote_rdesc;
|
||||
-}
|
||||
-
|
||||
-static int ps3remote_mapping(struct hid_device *hdev, struct hid_input *hi,
|
||||
- struct hid_field *field, struct hid_usage *usage,
|
||||
- unsigned long **bit, int *max)
|
||||
-{
|
||||
- unsigned int key = usage->hid & HID_USAGE;
|
||||
-
|
||||
- if ((usage->hid & HID_USAGE_PAGE) != HID_UP_BUTTON)
|
||||
- return -1;
|
||||
-
|
||||
- switch (usage->collection_index) {
|
||||
- case 1:
|
||||
- if (key >= ARRAY_SIZE(ps3remote_keymap_joypad_buttons))
|
||||
- return -1;
|
||||
-
|
||||
- key = ps3remote_keymap_joypad_buttons[key];
|
||||
- if (!key)
|
||||
- return -1;
|
||||
- break;
|
||||
- case 2:
|
||||
- if (key >= ARRAY_SIZE(ps3remote_keymap_remote_buttons))
|
||||
- return -1;
|
||||
-
|
||||
- key = ps3remote_keymap_remote_buttons[key];
|
||||
- if (!key)
|
||||
- return -1;
|
||||
- break;
|
||||
- default:
|
||||
- return -1;
|
||||
- }
|
||||
-
|
||||
- hid_map_usage_clear(hi, usage, bit, max, EV_KEY, key);
|
||||
- return 1;
|
||||
-}
|
||||
-
|
||||
-static const struct hid_device_id ps3remote_devices[] = {
|
||||
- /* PS3 BD Remote Control */
|
||||
- { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_BDREMOTE) },
|
||||
- /* Logitech Harmony Adapter for PS3 */
|
||||
- { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_PS3) },
|
||||
- { }
|
||||
-};
|
||||
-MODULE_DEVICE_TABLE(hid, ps3remote_devices);
|
||||
-
|
||||
-static struct hid_driver ps3remote_driver = {
|
||||
- .name = "ps3_remote",
|
||||
- .id_table = ps3remote_devices,
|
||||
- .report_fixup = ps3remote_fixup,
|
||||
- .input_mapping = ps3remote_mapping,
|
||||
-};
|
||||
-module_hid_driver(ps3remote_driver);
|
||||
-
|
||||
-MODULE_LICENSE("GPL");
|
||||
-MODULE_AUTHOR("David Dillow <dave@thedillows.org>, Antonio Ospite <ospite@studenti.unina.it>");
|
||||
diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c
|
||||
index 312098e..83f9629 100644
|
||||
--- a/drivers/hid/hid-sony.c
|
||||
+++ b/drivers/hid/hid-sony.c
|
||||
@@ -1,11 +1,13 @@
|
||||
/*
|
||||
- * HID driver for some sony "special" devices
|
||||
+ * HID driver for Sony / PS2 / PS3 BD devices.
|
||||
*
|
||||
* Copyright (c) 1999 Andreas Gal
|
||||
* Copyright (c) 2000-2005 Vojtech Pavlik <vojtech@suse.cz>
|
||||
* Copyright (c) 2005 Michael Haboustak <mike-@cinci.rr.com> for Concept2, Inc
|
||||
* Copyright (c) 2008 Jiri Slaby
|
||||
- * Copyright (c) 2006-2008 Jiri Kosina
|
||||
+ * Copyright (c) 2012 David Dillow <dave@thedillows.org>
|
||||
+ * Copyright (c) 2006-2013 Jiri Kosina
|
||||
+ * Copyright (c) 2013 Colin Leitner <colin.leitner@gmail.com>
|
||||
*/
|
||||
|
||||
/*
|
||||
@@ -15,17 +17,28 @@
|
||||
* any later version.
|
||||
*/
|
||||
|
||||
+/* NOTE: in order for the Sony PS3 BD Remote Control to be found by
|
||||
+ * a Bluetooth host, the key combination Start+Enter has to be kept pressed
|
||||
+ * for about 7 seconds with the Bluetooth Host Controller in discovering mode.
|
||||
+ *
|
||||
+ * There will be no PIN request from the device.
|
||||
+ */
|
||||
+
|
||||
#include <linux/device.h>
|
||||
#include <linux/hid.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/usb.h>
|
||||
+#include "usbhid/usbhid.h"
|
||||
+#include <linux/leds.h>
|
||||
|
||||
#include "hid-ids.h"
|
||||
|
||||
#define VAIO_RDESC_CONSTANT (1 << 0)
|
||||
#define SIXAXIS_CONTROLLER_USB (1 << 1)
|
||||
#define SIXAXIS_CONTROLLER_BT (1 << 2)
|
||||
+#define BUZZ_CONTROLLER (1 << 3)
|
||||
+#define PS3REMOTE (1 << 4)
|
||||
|
||||
static const u8 sixaxis_rdesc_fixup[] = {
|
||||
0x95, 0x13, 0x09, 0x01, 0x81, 0x02, 0x95, 0x0C,
|
||||
@@ -55,10 +68,214 @@ static const u8 sixaxis_rdesc_fixup2[] = {
|
||||
0xb1, 0x02, 0xc0, 0xc0,
|
||||
};
|
||||
|
||||
+static __u8 ps3remote_rdesc[] = {
|
||||
+ 0x05, 0x01, /* GUsagePage Generic Desktop */
|
||||
+ 0x09, 0x05, /* LUsage 0x05 [Game Pad] */
|
||||
+ 0xA1, 0x01, /* MCollection Application (mouse, keyboard) */
|
||||
+
|
||||
+ /* Use collection 1 for joypad buttons */
|
||||
+ 0xA1, 0x02, /* MCollection Logical (interrelated data) */
|
||||
+
|
||||
+ /* Ignore the 1st byte, maybe it is used for a controller
|
||||
+ * number but it's not needed for correct operation */
|
||||
+ 0x75, 0x08, /* GReportSize 0x08 [8] */
|
||||
+ 0x95, 0x01, /* GReportCount 0x01 [1] */
|
||||
+ 0x81, 0x01, /* MInput 0x01 (Const[0] Arr[1] Abs[2]) */
|
||||
+
|
||||
+ /* Bytes from 2nd to 4th are a bitmap for joypad buttons, for these
|
||||
+ * buttons multiple keypresses are allowed */
|
||||
+ 0x05, 0x09, /* GUsagePage Button */
|
||||
+ 0x19, 0x01, /* LUsageMinimum 0x01 [Button 1 (primary/trigger)] */
|
||||
+ 0x29, 0x18, /* LUsageMaximum 0x18 [Button 24] */
|
||||
+ 0x14, /* GLogicalMinimum [0] */
|
||||
+ 0x25, 0x01, /* GLogicalMaximum 0x01 [1] */
|
||||
+ 0x75, 0x01, /* GReportSize 0x01 [1] */
|
||||
+ 0x95, 0x18, /* GReportCount 0x18 [24] */
|
||||
+ 0x81, 0x02, /* MInput 0x02 (Data[0] Var[1] Abs[2]) */
|
||||
+
|
||||
+ 0xC0, /* MEndCollection */
|
||||
+
|
||||
+ /* Use collection 2 for remote control buttons */
|
||||
+ 0xA1, 0x02, /* MCollection Logical (interrelated data) */
|
||||
+
|
||||
+ /* 5th byte is used for remote control buttons */
|
||||
+ 0x05, 0x09, /* GUsagePage Button */
|
||||
+ 0x18, /* LUsageMinimum [No button pressed] */
|
||||
+ 0x29, 0xFE, /* LUsageMaximum 0xFE [Button 254] */
|
||||
+ 0x14, /* GLogicalMinimum [0] */
|
||||
+ 0x26, 0xFE, 0x00, /* GLogicalMaximum 0x00FE [254] */
|
||||
+ 0x75, 0x08, /* GReportSize 0x08 [8] */
|
||||
+ 0x95, 0x01, /* GReportCount 0x01 [1] */
|
||||
+ 0x80, /* MInput */
|
||||
+
|
||||
+ /* Ignore bytes from 6th to 11th, 6th to 10th are always constant at
|
||||
+ * 0xff and 11th is for press indication */
|
||||
+ 0x75, 0x08, /* GReportSize 0x08 [8] */
|
||||
+ 0x95, 0x06, /* GReportCount 0x06 [6] */
|
||||
+ 0x81, 0x01, /* MInput 0x01 (Const[0] Arr[1] Abs[2]) */
|
||||
+
|
||||
+ /* 12th byte is for battery strength */
|
||||
+ 0x05, 0x06, /* GUsagePage Generic Device Controls */
|
||||
+ 0x09, 0x20, /* LUsage 0x20 [Battery Strength] */
|
||||
+ 0x14, /* GLogicalMinimum [0] */
|
||||
+ 0x25, 0x05, /* GLogicalMaximum 0x05 [5] */
|
||||
+ 0x75, 0x08, /* GReportSize 0x08 [8] */
|
||||
+ 0x95, 0x01, /* GReportCount 0x01 [1] */
|
||||
+ 0x81, 0x02, /* MInput 0x02 (Data[0] Var[1] Abs[2]) */
|
||||
+
|
||||
+ 0xC0, /* MEndCollection */
|
||||
+
|
||||
+ 0xC0 /* MEndCollection [Game Pad] */
|
||||
+};
|
||||
+
|
||||
+static const unsigned int ps3remote_keymap_joypad_buttons[] = {
|
||||
+ [0x01] = KEY_SELECT,
|
||||
+ [0x02] = BTN_THUMBL, /* L3 */
|
||||
+ [0x03] = BTN_THUMBR, /* R3 */
|
||||
+ [0x04] = BTN_START,
|
||||
+ [0x05] = KEY_UP,
|
||||
+ [0x06] = KEY_RIGHT,
|
||||
+ [0x07] = KEY_DOWN,
|
||||
+ [0x08] = KEY_LEFT,
|
||||
+ [0x09] = BTN_TL2, /* L2 */
|
||||
+ [0x0a] = BTN_TR2, /* R2 */
|
||||
+ [0x0b] = BTN_TL, /* L1 */
|
||||
+ [0x0c] = BTN_TR, /* R1 */
|
||||
+ [0x0d] = KEY_OPTION, /* options/triangle */
|
||||
+ [0x0e] = KEY_BACK, /* back/circle */
|
||||
+ [0x0f] = BTN_0, /* cross */
|
||||
+ [0x10] = KEY_SCREEN, /* view/square */
|
||||
+ [0x11] = KEY_HOMEPAGE, /* PS button */
|
||||
+ [0x14] = KEY_ENTER,
|
||||
+};
|
||||
+static const unsigned int ps3remote_keymap_remote_buttons[] = {
|
||||
+ [0x00] = KEY_1,
|
||||
+ [0x01] = KEY_2,
|
||||
+ [0x02] = KEY_3,
|
||||
+ [0x03] = KEY_4,
|
||||
+ [0x04] = KEY_5,
|
||||
+ [0x05] = KEY_6,
|
||||
+ [0x06] = KEY_7,
|
||||
+ [0x07] = KEY_8,
|
||||
+ [0x08] = KEY_9,
|
||||
+ [0x09] = KEY_0,
|
||||
+ [0x0e] = KEY_ESC, /* return */
|
||||
+ [0x0f] = KEY_CLEAR,
|
||||
+ [0x16] = KEY_EJECTCD,
|
||||
+ [0x1a] = KEY_MENU, /* top menu */
|
||||
+ [0x28] = KEY_TIME,
|
||||
+ [0x30] = KEY_PREVIOUS,
|
||||
+ [0x31] = KEY_NEXT,
|
||||
+ [0x32] = KEY_PLAY,
|
||||
+ [0x33] = KEY_REWIND, /* scan back */
|
||||
+ [0x34] = KEY_FORWARD, /* scan forward */
|
||||
+ [0x38] = KEY_STOP,
|
||||
+ [0x39] = KEY_PAUSE,
|
||||
+ [0x40] = KEY_CONTEXT_MENU, /* pop up/menu */
|
||||
+ [0x60] = KEY_FRAMEBACK, /* slow/step back */
|
||||
+ [0x61] = KEY_FRAMEFORWARD, /* slow/step forward */
|
||||
+ [0x63] = KEY_SUBTITLE,
|
||||
+ [0x64] = KEY_AUDIO,
|
||||
+ [0x65] = KEY_ANGLE,
|
||||
+ [0x70] = KEY_INFO, /* display */
|
||||
+ [0x80] = KEY_BLUE,
|
||||
+ [0x81] = KEY_RED,
|
||||
+ [0x82] = KEY_GREEN,
|
||||
+ [0x83] = KEY_YELLOW,
|
||||
+};
|
||||
+
|
||||
+static const unsigned int buzz_keymap[] = {
|
||||
+ /* The controller has 4 remote buzzers, each with one LED and 5
|
||||
+ * buttons.
|
||||
+ *
|
||||
+ * We use the mapping chosen by the controller, which is:
|
||||
+ *
|
||||
+ * Key Offset
|
||||
+ * -------------------
|
||||
+ * Buzz 1
|
||||
+ * Blue 5
|
||||
+ * Orange 4
|
||||
+ * Green 3
|
||||
+ * Yellow 2
|
||||
+ *
|
||||
+ * So, for example, the orange button on the third buzzer is mapped to
|
||||
+ * BTN_TRIGGER_HAPPY14
|
||||
+ */
|
||||
+ [ 1] = BTN_TRIGGER_HAPPY1,
|
||||
+ [ 2] = BTN_TRIGGER_HAPPY2,
|
||||
+ [ 3] = BTN_TRIGGER_HAPPY3,
|
||||
+ [ 4] = BTN_TRIGGER_HAPPY4,
|
||||
+ [ 5] = BTN_TRIGGER_HAPPY5,
|
||||
+ [ 6] = BTN_TRIGGER_HAPPY6,
|
||||
+ [ 7] = BTN_TRIGGER_HAPPY7,
|
||||
+ [ 8] = BTN_TRIGGER_HAPPY8,
|
||||
+ [ 9] = BTN_TRIGGER_HAPPY9,
|
||||
+ [10] = BTN_TRIGGER_HAPPY10,
|
||||
+ [11] = BTN_TRIGGER_HAPPY11,
|
||||
+ [12] = BTN_TRIGGER_HAPPY12,
|
||||
+ [13] = BTN_TRIGGER_HAPPY13,
|
||||
+ [14] = BTN_TRIGGER_HAPPY14,
|
||||
+ [15] = BTN_TRIGGER_HAPPY15,
|
||||
+ [16] = BTN_TRIGGER_HAPPY16,
|
||||
+ [17] = BTN_TRIGGER_HAPPY17,
|
||||
+ [18] = BTN_TRIGGER_HAPPY18,
|
||||
+ [19] = BTN_TRIGGER_HAPPY19,
|
||||
+ [20] = BTN_TRIGGER_HAPPY20,
|
||||
+};
|
||||
+
|
||||
struct sony_sc {
|
||||
unsigned long quirks;
|
||||
+
|
||||
+ void *extra;
|
||||
};
|
||||
|
||||
+struct buzz_extra {
|
||||
+ int led_state;
|
||||
+ struct led_classdev *leds[4];
|
||||
+};
|
||||
+
|
||||
+static __u8 *ps3remote_fixup(struct hid_device *hdev, __u8 *rdesc,
|
||||
+ unsigned int *rsize)
|
||||
+{
|
||||
+ *rsize = sizeof(ps3remote_rdesc);
|
||||
+ return ps3remote_rdesc;
|
||||
+}
|
||||
+
|
||||
+static int ps3remote_mapping(struct hid_device *hdev, struct hid_input *hi,
|
||||
+ struct hid_field *field, struct hid_usage *usage,
|
||||
+ unsigned long **bit, int *max)
|
||||
+{
|
||||
+ unsigned int key = usage->hid & HID_USAGE;
|
||||
+
|
||||
+ if ((usage->hid & HID_USAGE_PAGE) != HID_UP_BUTTON)
|
||||
+ return -1;
|
||||
+
|
||||
+ switch (usage->collection_index) {
|
||||
+ case 1:
|
||||
+ if (key >= ARRAY_SIZE(ps3remote_keymap_joypad_buttons))
|
||||
+ return -1;
|
||||
+
|
||||
+ key = ps3remote_keymap_joypad_buttons[key];
|
||||
+ if (!key)
|
||||
+ return -1;
|
||||
+ break;
|
||||
+ case 2:
|
||||
+ if (key >= ARRAY_SIZE(ps3remote_keymap_remote_buttons))
|
||||
+ return -1;
|
||||
+
|
||||
+ key = ps3remote_keymap_remote_buttons[key];
|
||||
+ if (!key)
|
||||
+ return -1;
|
||||
+ break;
|
||||
+ default:
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ hid_map_usage_clear(hi, usage, bit, max, EV_KEY, key);
|
||||
+ return 1;
|
||||
+}
|
||||
+
|
||||
+
|
||||
/* Sony Vaio VGX has wrongly mouse pointer declared as constant */
|
||||
static __u8 *sony_report_fixup(struct hid_device *hdev, __u8 *rdesc,
|
||||
unsigned int *rsize)
|
||||
@@ -95,6 +312,10 @@ static __u8 *sony_report_fixup(struct hid_device *hdev, __u8 *rdesc,
|
||||
*rsize = sizeof(sixaxis_rdesc_fixup2);
|
||||
memcpy(rdesc, &sixaxis_rdesc_fixup2, *rsize);
|
||||
}
|
||||
+
|
||||
+ if (sc->quirks & PS3REMOTE)
|
||||
+ return ps3remote_fixup(hdev, rdesc, rsize);
|
||||
+
|
||||
return rdesc;
|
||||
}
|
||||
|
||||
@@ -117,6 +338,41 @@ static int sony_raw_event(struct hid_device *hdev, struct hid_report *report,
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static int sony_mapping(struct hid_device *hdev, struct hid_input *hi,
|
||||
+ struct hid_field *field, struct hid_usage *usage,
|
||||
+ unsigned long **bit, int *max)
|
||||
+{
|
||||
+ struct sony_sc *sc = hid_get_drvdata(hdev);
|
||||
+
|
||||
+ if (sc->quirks & BUZZ_CONTROLLER) {
|
||||
+ unsigned int key = usage->hid & HID_USAGE;
|
||||
+
|
||||
+ if ((usage->hid & HID_USAGE_PAGE) != HID_UP_BUTTON)
|
||||
+ return -1;
|
||||
+
|
||||
+ switch (usage->collection_index) {
|
||||
+ case 1:
|
||||
+ if (key >= ARRAY_SIZE(buzz_keymap))
|
||||
+ return -1;
|
||||
+
|
||||
+ key = buzz_keymap[key];
|
||||
+ if (!key)
|
||||
+ return -1;
|
||||
+ break;
|
||||
+ default:
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ hid_map_usage_clear(hi, usage, bit, max, EV_KEY, key);
|
||||
+ return 1;
|
||||
+ }
|
||||
+
|
||||
+ if (sc->quirks & PS3REMOTE)
|
||||
+ return ps3remote_mapping(hdev, hi, field, usage, bit, max);
|
||||
+
|
||||
+ return -1;
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* The Sony Sixaxis does not handle HID Output Reports on the Interrupt EP
|
||||
* like it should according to usbhid/hid-core.c::usbhid_output_raw_report()
|
||||
@@ -192,11 +448,181 @@ static int sixaxis_set_operational_bt(struct hid_device *hdev)
|
||||
return hdev->hid_output_raw_report(hdev, buf, sizeof(buf), HID_FEATURE_REPORT);
|
||||
}
|
||||
|
||||
+static void buzz_set_leds(struct hid_device *hdev, int leds)
|
||||
+{
|
||||
+ struct list_head *report_list =
|
||||
+ &hdev->report_enum[HID_OUTPUT_REPORT].report_list;
|
||||
+ struct hid_report *report = list_entry(report_list->next,
|
||||
+ struct hid_report, list);
|
||||
+ __s32 *value = report->field[0]->value;
|
||||
+
|
||||
+ value[0] = 0x00;
|
||||
+ value[1] = (leds & 1) ? 0xff : 0x00;
|
||||
+ value[2] = (leds & 2) ? 0xff : 0x00;
|
||||
+ value[3] = (leds & 4) ? 0xff : 0x00;
|
||||
+ value[4] = (leds & 8) ? 0xff : 0x00;
|
||||
+ value[5] = 0x00;
|
||||
+ value[6] = 0x00;
|
||||
+ hid_hw_request(hdev, report, HID_REQ_SET_REPORT);
|
||||
+}
|
||||
+
|
||||
+static void buzz_led_set_brightness(struct led_classdev *led,
|
||||
+ enum led_brightness value)
|
||||
+{
|
||||
+ struct device *dev = led->dev->parent;
|
||||
+ struct hid_device *hdev = container_of(dev, struct hid_device, dev);
|
||||
+ struct sony_sc *drv_data;
|
||||
+ struct buzz_extra *buzz;
|
||||
+
|
||||
+ int n;
|
||||
+
|
||||
+ drv_data = hid_get_drvdata(hdev);
|
||||
+ if (!drv_data || !drv_data->extra) {
|
||||
+ hid_err(hdev, "No device data\n");
|
||||
+ return;
|
||||
+ }
|
||||
+ buzz = drv_data->extra;
|
||||
+
|
||||
+ for (n = 0; n < 4; n++) {
|
||||
+ if (led == buzz->leds[n]) {
|
||||
+ int on = !! (buzz->led_state & (1 << n));
|
||||
+ if (value == LED_OFF && on) {
|
||||
+ buzz->led_state &= ~(1 << n);
|
||||
+ buzz_set_leds(hdev, buzz->led_state);
|
||||
+ } else if (value != LED_OFF && !on) {
|
||||
+ buzz->led_state |= (1 << n);
|
||||
+ buzz_set_leds(hdev, buzz->led_state);
|
||||
+ }
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static enum led_brightness buzz_led_get_brightness(struct led_classdev *led)
|
||||
+{
|
||||
+ struct device *dev = led->dev->parent;
|
||||
+ struct hid_device *hdev = container_of(dev, struct hid_device, dev);
|
||||
+ struct sony_sc *drv_data;
|
||||
+ struct buzz_extra *buzz;
|
||||
+
|
||||
+ int n;
|
||||
+ int on = 0;
|
||||
+
|
||||
+ drv_data = hid_get_drvdata(hdev);
|
||||
+ if (!drv_data || !drv_data->extra) {
|
||||
+ hid_err(hdev, "No device data\n");
|
||||
+ return LED_OFF;
|
||||
+ }
|
||||
+ buzz = drv_data->extra;
|
||||
+
|
||||
+ for (n = 0; n < 4; n++) {
|
||||
+ if (led == buzz->leds[n]) {
|
||||
+ on = !! (buzz->led_state & (1 << n));
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return on ? LED_FULL : LED_OFF;
|
||||
+}
|
||||
+
|
||||
+static int buzz_init(struct hid_device *hdev)
|
||||
+{
|
||||
+ struct sony_sc *drv_data;
|
||||
+ struct buzz_extra *buzz;
|
||||
+ int n, ret = 0;
|
||||
+ struct led_classdev *led;
|
||||
+ size_t name_sz;
|
||||
+ char *name;
|
||||
+
|
||||
+ drv_data = hid_get_drvdata(hdev);
|
||||
+ BUG_ON(!(drv_data->quirks & BUZZ_CONTROLLER));
|
||||
+
|
||||
+ buzz = kzalloc(sizeof(*buzz), GFP_KERNEL);
|
||||
+ if (!buzz) {
|
||||
+ hid_err(hdev, "Insufficient memory, cannot allocate driver data\n");
|
||||
+ return -ENOMEM;
|
||||
+ }
|
||||
+ drv_data->extra = buzz;
|
||||
+
|
||||
+ /* Clear LEDs as we have no way of reading their initial state. This is
|
||||
+ * only relevant if the driver is loaded after somebody actively set the
|
||||
+ * LEDs to on */
|
||||
+ buzz_set_leds(hdev, 0x00);
|
||||
+
|
||||
+ name_sz = strlen(dev_name(&hdev->dev)) + strlen("::buzz#") + 1;
|
||||
+
|
||||
+ for (n = 0; n < 4; n++) {
|
||||
+ led = kzalloc(sizeof(struct led_classdev) + name_sz, GFP_KERNEL);
|
||||
+ if (!led) {
|
||||
+ hid_err(hdev, "Couldn't allocate memory for LED %d\n", n);
|
||||
+ goto error_leds;
|
||||
+ }
|
||||
+
|
||||
+ name = (void *)(&led[1]);
|
||||
+ snprintf(name, name_sz, "%s::buzz%d", dev_name(&hdev->dev), n + 1);
|
||||
+ led->name = name;
|
||||
+ led->brightness = 0;
|
||||
+ led->max_brightness = 1;
|
||||
+ led->brightness_get = buzz_led_get_brightness;
|
||||
+ led->brightness_set = buzz_led_set_brightness;
|
||||
+
|
||||
+ if (led_classdev_register(&hdev->dev, led)) {
|
||||
+ hid_err(hdev, "Failed to register LED %d\n", n);
|
||||
+ kfree(led);
|
||||
+ goto error_leds;
|
||||
+ }
|
||||
+
|
||||
+ buzz->leds[n] = led;
|
||||
+ }
|
||||
+
|
||||
+ return ret;
|
||||
+
|
||||
+error_leds:
|
||||
+ for (n = 0; n < 4; n++) {
|
||||
+ led = buzz->leds[n];
|
||||
+ buzz->leds[n] = NULL;
|
||||
+ if (!led)
|
||||
+ continue;
|
||||
+ led_classdev_unregister(led);
|
||||
+ kfree(led);
|
||||
+ }
|
||||
+
|
||||
+ kfree(drv_data->extra);
|
||||
+ drv_data->extra = NULL;
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static void buzz_remove(struct hid_device *hdev)
|
||||
+{
|
||||
+ struct sony_sc *drv_data;
|
||||
+ struct buzz_extra *buzz;
|
||||
+ struct led_classdev *led;
|
||||
+ int n;
|
||||
+
|
||||
+ drv_data = hid_get_drvdata(hdev);
|
||||
+ BUG_ON(!(drv_data->quirks & BUZZ_CONTROLLER));
|
||||
+
|
||||
+ buzz = drv_data->extra;
|
||||
+
|
||||
+ for (n = 0; n < 4; n++) {
|
||||
+ led = buzz->leds[n];
|
||||
+ buzz->leds[n] = NULL;
|
||||
+ if (!led)
|
||||
+ continue;
|
||||
+ led_classdev_unregister(led);
|
||||
+ kfree(led);
|
||||
+ }
|
||||
+
|
||||
+ kfree(drv_data->extra);
|
||||
+ drv_data->extra = NULL;
|
||||
+}
|
||||
+
|
||||
static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id)
|
||||
{
|
||||
int ret;
|
||||
unsigned long quirks = id->driver_data;
|
||||
struct sony_sc *sc;
|
||||
+ unsigned int connect_mask = HID_CONNECT_DEFAULT;
|
||||
|
||||
sc = kzalloc(sizeof(*sc), GFP_KERNEL);
|
||||
if (sc == NULL) {
|
||||
@@ -213,8 +639,14 @@ static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id)
|
||||
goto err_free;
|
||||
}
|
||||
|
||||
- ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT |
|
||||
- HID_CONNECT_HIDDEV_FORCE);
|
||||
+ if (sc->quirks & VAIO_RDESC_CONSTANT)
|
||||
+ connect_mask |= HID_CONNECT_HIDDEV_FORCE;
|
||||
+ else if (sc->quirks & SIXAXIS_CONTROLLER_USB)
|
||||
+ connect_mask |= HID_CONNECT_HIDDEV_FORCE;
|
||||
+ else if (sc->quirks & SIXAXIS_CONTROLLER_BT)
|
||||
+ connect_mask |= HID_CONNECT_HIDDEV_FORCE;
|
||||
+
|
||||
+ ret = hid_hw_start(hdev, connect_mask);
|
||||
if (ret) {
|
||||
hid_err(hdev, "hw start failed\n");
|
||||
goto err_free;
|
||||
@@ -226,6 +658,8 @@ static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id)
|
||||
}
|
||||
else if (sc->quirks & SIXAXIS_CONTROLLER_BT)
|
||||
ret = sixaxis_set_operational_bt(hdev);
|
||||
+ else if (sc->quirks & BUZZ_CONTROLLER)
|
||||
+ ret = buzz_init(hdev);
|
||||
else
|
||||
ret = 0;
|
||||
|
||||
@@ -242,8 +676,13 @@ err_free:
|
||||
|
||||
static void sony_remove(struct hid_device *hdev)
|
||||
{
|
||||
+ struct sony_sc *sc = hid_get_drvdata(hdev);
|
||||
+
|
||||
+ if (sc->quirks & BUZZ_CONTROLLER)
|
||||
+ buzz_remove(hdev);
|
||||
+
|
||||
hid_hw_stop(hdev);
|
||||
- kfree(hid_get_drvdata(hdev));
|
||||
+ kfree(sc);
|
||||
}
|
||||
|
||||
static const struct hid_device_id sony_devices[] = {
|
||||
@@ -257,17 +696,30 @@ static const struct hid_device_id sony_devices[] = {
|
||||
.driver_data = VAIO_RDESC_CONSTANT },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGP_MOUSE),
|
||||
.driver_data = VAIO_RDESC_CONSTANT },
|
||||
+ /* Wired Buzz Controller. Reported as Sony Hub from its USB ID and as
|
||||
+ * Logitech joystick from the device descriptor. */
|
||||
+ { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_BUZZ_CONTROLLER),
|
||||
+ .driver_data = BUZZ_CONTROLLER },
|
||||
+ { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_WIRELESS_BUZZ_CONTROLLER),
|
||||
+ .driver_data = BUZZ_CONTROLLER },
|
||||
+ /* PS3 BD Remote Control */
|
||||
+ { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_BDREMOTE),
|
||||
+ .driver_data = PS3REMOTE },
|
||||
+ /* Logitech Harmony Adapter for PS3 */
|
||||
+ { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_PS3),
|
||||
+ .driver_data = PS3REMOTE },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(hid, sony_devices);
|
||||
|
||||
static struct hid_driver sony_driver = {
|
||||
- .name = "sony",
|
||||
- .id_table = sony_devices,
|
||||
- .probe = sony_probe,
|
||||
- .remove = sony_remove,
|
||||
- .report_fixup = sony_report_fixup,
|
||||
- .raw_event = sony_raw_event
|
||||
+ .name = "sony",
|
||||
+ .id_table = sony_devices,
|
||||
+ .input_mapping = sony_mapping,
|
||||
+ .probe = sony_probe,
|
||||
+ .remove = sony_remove,
|
||||
+ .report_fixup = sony_report_fixup,
|
||||
+ .raw_event = sony_raw_event
|
||||
};
|
||||
module_hid_driver(sony_driver);
|
||||
|
@ -1,61 +0,0 @@
|
||||
Betreff: [RFC] hid/sony: add autorepeat for PS3 remotes
|
||||
Von: David Dillow <dave@thedillows.org>
|
||||
Datum: 28.06.2013 04:28
|
||||
An: linux-input@vger.kernel.org
|
||||
Kopie (CC): Stephan Raue <stephan@openelec.tv>
|
||||
|
||||
Some applications using the PS3 remote would like to have autorepeat
|
||||
from the device. Use the input subsystem's software emulation to provide
|
||||
this capability, and enable those that don't need it to turn it off.
|
||||
---
|
||||
I'm not sure this is the correct approach, or if it is even appropriate
|
||||
for a remote to do autorepeat. However, the media/rc subsystem does do
|
||||
it by default, and it's been requested by users, so there is at least
|
||||
some demand.
|
||||
|
||||
This compiled against the hid-sony driver with the PS3 remote changes
|
||||
merged, but I have done no testing of it. If the approach seems
|
||||
reasonable, I'll try to test it when the MythTV is idle.
|
||||
|
||||
drivers/hid/hid-sony.c | 20 ++++++++++++++++++++
|
||||
1 file changed, 20 insertions(+)
|
||||
diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c
|
||||
index ecbc749..0bbcd07 100644
|
||||
--- a/drivers/hid/hid-sony.c
|
||||
+++ b/drivers/hid/hid-sony.c
|
||||
@@ -274,6 +274,24 @@ static int ps3remote_mapping(struct hid_device *hdev, struct hid_input *hi,
|
||||
return 1;
|
||||
}
|
||||
|
||||
+static int ps3remote_setup_repeat(struct hid_device *hdev)
|
||||
+{
|
||||
+ struct hid_input *hidinput = list_first_entry(&hdev->inputs,
|
||||
+ struct hid_input, list);
|
||||
+ struct input_dev *input = hidinput->input;
|
||||
+
|
||||
+ /*
|
||||
+ * Set up autorepeat defaults per the remote control subsystem;
|
||||
+ * this must be done after hid_hw_start(), as having these non-zero
|
||||
+ * at the time of input_register_device() tells the input system that
|
||||
+ * the hardware does the autorepeat, and the PS3 remote does not.
|
||||
+ */
|
||||
+ set_bit(EV_REP, input->evbit);
|
||||
+ input->rep[REP_DELAY] = 500;
|
||||
+ input->rep[REP_PERIOD] = 125;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
|
||||
/* Sony Vaio VGX has wrongly mouse pointer declared as constant */
|
||||
static __u8 *sony_report_fixup(struct hid_device *hdev, __u8 *rdesc,
|
||||
@@ -659,6 +677,8 @@ static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id)
|
||||
ret = sixaxis_set_operational_bt(hdev);
|
||||
else if (sc->quirks & BUZZ_CONTROLLER)
|
||||
ret = buzz_init(hdev);
|
||||
+ else if (sc->quirks & PS3REMOTE)
|
||||
+ ret = ps3remote_setup_repeat(hdev);
|
||||
else
|
||||
ret = 0;
|
||||
|
||||
|
||||
|
@ -1,47 +0,0 @@
|
||||
commit 5a601d61d36236a667cc7d170b300d18dd6240c6
|
||||
Author: Juan J. Sierralta <sierralta@gmail.com>
|
||||
Date: Sun Jul 28 09:26:04 2013 +0300
|
||||
|
||||
Add support for SMK-Link PS3 remote
|
||||
|
||||
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
|
||||
index 396d24d..9eb7129 100644
|
||||
--- a/drivers/hid/hid-core.c
|
||||
+++ b/drivers/hid/hid-core.c
|
||||
@@ -1686,6 +1686,7 @@ static const struct hid_device_id hid_have_special_driver[] = {
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_IR_REMOTE) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_WIRELESS_KBD_MOUSE) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_SKYCABLE, USB_DEVICE_ID_SKYCABLE_WIRELESS_PRESENTER) },
|
||||
+ { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SMK, USB_DEVICE_ID_SONY_PS3_BDREMOTE) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_BUZZ_CONTROLLER) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_WIRELESS_BUZZ_CONTROLLER) },
|
||||
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_BDREMOTE) },
|
||||
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
|
||||
index dd0511e..2801df1 100644
|
||||
--- a/drivers/hid/hid-ids.h
|
||||
+++ b/drivers/hid/hid-ids.h
|
||||
@@ -734,6 +734,7 @@
|
||||
#define USB_VENDOR_ID_SKYCABLE 0x1223
|
||||
#define USB_DEVICE_ID_SKYCABLE_WIRELESS_PRESENTER 0x3F07
|
||||
|
||||
+#define USB_VENDOR_ID_SMK 0x0609
|
||||
#define USB_VENDOR_ID_SONY 0x054c
|
||||
#define USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE 0x024b
|
||||
#define USB_DEVICE_ID_SONY_VAIO_VGP_MOUSE 0x0374
|
||||
diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c
|
||||
index 8f425e2..614f057 100644
|
||||
--- a/drivers/hid/hid-sony.c
|
||||
+++ b/drivers/hid/hid-sony.c
|
||||
@@ -728,8 +728,12 @@ static const struct hid_device_id sony_devices[] = {
|
||||
/* Logitech Harmony Adapter for PS3 */
|
||||
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_PS3),
|
||||
.driver_data = PS3REMOTE },
|
||||
+ /* SMK-Link Universal Remote Control VP3700 */
|
||||
+ { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SMK, USB_DEVICE_ID_SONY_PS3_BDREMOTE),
|
||||
+ .driver_data = PS3REMOTE },
|
||||
{ }
|
||||
};
|
||||
+
|
||||
MODULE_DEVICE_TABLE(hid, sony_devices);
|
||||
|
||||
static struct hid_driver sony_driver = {
|
@ -1,11 +0,0 @@
|
||||
diff -Naur linux-3.8.4/drivers/input/joystick/xpad.c linux-3.8.4.patch/drivers/input/joystick/xpad.c
|
||||
--- linux-3.8.4/drivers/input/joystick/xpad.c 2013-03-20 21:11:19.000000000 +0100
|
||||
+++ linux-3.8.4.patch/drivers/input/joystick/xpad.c 2013-03-26 20:24:29.273978355 +0100
|
||||
@@ -174,7 +174,6 @@
|
||||
{ 0x1bad, 0xf901, "Gamestop Xbox 360 Controller", 0, XTYPE_XBOX360 },
|
||||
{ 0x1bad, 0xf903, "Tron Xbox 360 controller", 0, XTYPE_XBOX360 },
|
||||
{ 0x24c6, 0x5300, "PowerA MINI PROEX Controller", 0, XTYPE_XBOX360 },
|
||||
- { 0xffff, 0xffff, "Chinese-made Xbox Controller", 0, XTYPE_XBOX },
|
||||
{ 0x0000, 0x0000, "Generic X-Box pad", 0, XTYPE_UNKNOWN }
|
||||
};
|
||||
|
@ -1,14 +0,0 @@
|
||||
diff --git a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c
|
||||
index 2cc8ec7..985fa11 100644
|
||||
--- a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c
|
||||
+++ b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c
|
||||
@@ -1408,6 +1408,9 @@ static const struct usb_device_id rtl28xxu_id_table[] = {
|
||||
&rtl2832u_props, "Compro VideoMate U620F", NULL) },
|
||||
{ DVB_USB_DEVICE(USB_VID_KWORLD_2, 0xd394,
|
||||
&rtl2832u_props, "MaxMedia HU394-T", NULL) },
|
||||
+ { DVB_USB_DEVICE(USB_VID_GTEK, 0xa803,
|
||||
+ &rtl2832u_props, "Realtek RTL2832U reference design", NULL) },
|
||||
+
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(usb, rtl28xxu_id_table);
|
@ -1,12 +0,0 @@
|
||||
diff -Naur linux-3.7.2/drivers/media/dvb-frontends/stb0899_drv.c linux-3.7.2.patch/drivers/media/dvb-frontends/stb0899_drv.c
|
||||
--- linux-3.7.2/drivers/media/dvb-frontends/stb0899_drv.c 2013-01-11 18:19:28.000000000 +0100
|
||||
+++ linux-3.7.2.patch/drivers/media/dvb-frontends/stb0899_drv.c 2013-01-16 10:25:43.479645317 +0100
|
||||
@@ -1581,7 +1581,7 @@
|
||||
.frequency_max = 2150000,
|
||||
.frequency_stepsize = 0,
|
||||
.frequency_tolerance = 0,
|
||||
- .symbol_rate_min = 5000000,
|
||||
+ .symbol_rate_min = 1000000,
|
||||
.symbol_rate_max = 45000000,
|
||||
|
||||
.caps = FE_CAN_INVERSION_AUTO |
|
File diff suppressed because it is too large
Load Diff
@ -1,138 +0,0 @@
|
||||
diff -Naur linux-3.7.2/drivers/media/dvb-frontends/stb0899_algo.c linux-3.7.2.patch/drivers/media/dvb-frontends/stb0899_algo.c
|
||||
--- linux-3.7.2/drivers/media/dvb-frontends/stb0899_algo.c 2013-01-11 18:19:28.000000000 +0100
|
||||
+++ linux-3.7.2.patch/drivers/media/dvb-frontends/stb0899_algo.c 2013-01-16 10:28:33.633409961 +0100
|
||||
@@ -206,7 +206,6 @@
|
||||
static enum stb0899_status stb0899_search_tmg(struct stb0899_state *state)
|
||||
{
|
||||
struct stb0899_internal *internal = &state->internal;
|
||||
- struct stb0899_params *params = &state->params;
|
||||
|
||||
short int derot_step, derot_freq = 0, derot_limit, next_loop = 3;
|
||||
int index = 0;
|
||||
@@ -216,10 +215,9 @@
|
||||
|
||||
/* timing loop computation & symbol rate optimisation */
|
||||
derot_limit = (internal->sub_range / 2L) / internal->mclk;
|
||||
- derot_step = (params->srate / 2L) / internal->mclk;
|
||||
+ derot_step = internal->derot_step * 4; /* dertot_step = decreasing delta */
|
||||
|
||||
while ((stb0899_check_tmg(state) != TIMINGOK) && next_loop) {
|
||||
- index++;
|
||||
derot_freq += index * internal->direction * derot_step; /* next derot zig zag position */
|
||||
|
||||
if (abs(derot_freq) > derot_limit)
|
||||
@@ -230,6 +228,7 @@
|
||||
STB0899_SETFIELD_VAL(CFRL, cfr[1], LSB(state->config->inversion * derot_freq));
|
||||
stb0899_write_regs(state, STB0899_CFRM, cfr, 2); /* derotator frequency */
|
||||
}
|
||||
+ index++;
|
||||
internal->direction = -internal->direction; /* Change zigzag direction */
|
||||
}
|
||||
|
||||
@@ -278,14 +277,18 @@
|
||||
{
|
||||
struct stb0899_internal *internal = &state->internal;
|
||||
|
||||
- short int derot_freq = 0, last_derot_freq = 0, derot_limit, next_loop = 3;
|
||||
+ short int derot_freq = 0, last_derot_freq = 0, derot_limit, derot_step, next_loop = 3;
|
||||
int index = 0;
|
||||
+ int base_freq;
|
||||
u8 cfr[2];
|
||||
u8 reg;
|
||||
|
||||
internal->status = NOCARRIER;
|
||||
derot_limit = (internal->sub_range / 2L) / internal->mclk;
|
||||
derot_freq = internal->derot_freq;
|
||||
+ derot_step = internal->derot_step * 2;
|
||||
+ last_derot_freq = internal->derot_freq;
|
||||
+ base_freq = internal->derot_freq;
|
||||
|
||||
reg = stb0899_read_reg(state, STB0899_CFD);
|
||||
STB0899_SETFIELD_VAL(CFD_ON, reg, 1);
|
||||
@@ -294,11 +297,10 @@
|
||||
do {
|
||||
dprintk(state->verbose, FE_DEBUG, 1, "Derot Freq=%d, mclk=%d", derot_freq, internal->mclk);
|
||||
if (stb0899_check_carrier(state) == NOCARRIER) {
|
||||
- index++;
|
||||
last_derot_freq = derot_freq;
|
||||
- derot_freq += index * internal->direction * internal->derot_step; /* next zig zag derotator position */
|
||||
+ derot_freq += index * internal->direction * derot_step; /* next zig zag derotator position */
|
||||
|
||||
- if(abs(derot_freq) > derot_limit)
|
||||
+ if (derot_freq > base_freq + derot_limit || derot_freq < base_freq - derot_limit)
|
||||
next_loop--;
|
||||
|
||||
if (next_loop) {
|
||||
@@ -310,9 +312,10 @@
|
||||
STB0899_SETFIELD_VAL(CFRL, cfr[1], LSB(state->config->inversion * derot_freq));
|
||||
stb0899_write_regs(state, STB0899_CFRM, cfr, 2); /* derotator frequency */
|
||||
}
|
||||
+ index++;
|
||||
+ internal->direction = -internal->direction; /* Change zigzag direction */
|
||||
}
|
||||
|
||||
- internal->direction = -internal->direction; /* Change zigzag direction */
|
||||
} while ((internal->status != CARRIEROK) && next_loop);
|
||||
|
||||
if (internal->status == CARRIEROK) {
|
||||
@@ -338,6 +341,7 @@
|
||||
int lock = 0, index = 0, dataTime = 500, loop;
|
||||
u8 reg;
|
||||
|
||||
+ msleep(1);
|
||||
internal->status = NODATA;
|
||||
|
||||
/* RESET FEC */
|
||||
@@ -348,6 +352,7 @@
|
||||
reg = stb0899_read_reg(state, STB0899_TSTRES);
|
||||
STB0899_SETFIELD_VAL(FRESACS, reg, 0);
|
||||
stb0899_write_reg(state, STB0899_TSTRES, reg);
|
||||
+ msleep(1);
|
||||
|
||||
if (params->srate <= 2000000)
|
||||
dataTime = 2000;
|
||||
@@ -363,6 +368,7 @@
|
||||
|
||||
stb0899_write_reg(state, STB0899_DSTATUS2, 0x00); /* force search loop */
|
||||
while (1) {
|
||||
+ msleep(1); // Alex: added 1 mSec
|
||||
/* WARNING! VIT LOCKED has to be tested before VIT_END_LOOOP */
|
||||
reg = stb0899_read_reg(state, STB0899_VSTATUS);
|
||||
lock = STB0899_GETFIELD(VSTATUS_LOCKEDVIT, reg);
|
||||
@@ -390,20 +396,21 @@
|
||||
short int derot_freq, derot_step, derot_limit, next_loop = 3;
|
||||
u8 cfr[2];
|
||||
u8 reg;
|
||||
- int index = 1;
|
||||
+ int index = 0;
|
||||
+ int base_freq;
|
||||
|
||||
struct stb0899_internal *internal = &state->internal;
|
||||
- struct stb0899_params *params = &state->params;
|
||||
|
||||
- derot_step = (params->srate / 4L) / internal->mclk;
|
||||
+ derot_step = internal->derot_step;
|
||||
derot_limit = (internal->sub_range / 2L) / internal->mclk;
|
||||
derot_freq = internal->derot_freq;
|
||||
+ base_freq = internal->derot_freq;
|
||||
|
||||
do {
|
||||
if ((internal->status != CARRIEROK) || (stb0899_check_data(state) != DATAOK)) {
|
||||
|
||||
derot_freq += index * internal->direction * derot_step; /* next zig zag derotator position */
|
||||
- if (abs(derot_freq) > derot_limit)
|
||||
+ if (derot_freq > base_freq + derot_limit || derot_freq < base_freq - derot_limit)
|
||||
next_loop--;
|
||||
|
||||
if (next_loop) {
|
||||
@@ -417,9 +424,9 @@
|
||||
stb0899_write_regs(state, STB0899_CFRM, cfr, 2); /* derotator frequency */
|
||||
|
||||
stb0899_check_carrier(state);
|
||||
- index++;
|
||||
}
|
||||
}
|
||||
+ index++;
|
||||
internal->direction = -internal->direction; /* change zig zag direction */
|
||||
} while ((internal->status != DATAOK) && next_loop);
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,62 +0,0 @@
|
||||
diff -Naur linux-3.7.2/drivers/media/dvb-frontends/stb0899_drv.c linux-3.7.2.patch/drivers/media/dvb-frontends/stb0899_drv.c
|
||||
--- linux-3.7.2/drivers/media/dvb-frontends/stb0899_drv.c 2013-01-11 18:19:28.000000000 +0100
|
||||
+++ linux-3.7.2.patch/drivers/media/dvb-frontends/stb0899_drv.c 2013-01-16 10:33:10.323380937 +0100
|
||||
@@ -971,6 +971,16 @@
|
||||
|
||||
*strength = stb0899_table_lookup(stb0899_dvbsrf_tab, ARRAY_SIZE(stb0899_dvbsrf_tab) - 1, val);
|
||||
*strength += 750;
|
||||
+
|
||||
+ const int MIN_STRENGTH_DVBS = 0;
|
||||
+ const int MAX_STRENGTH_DVBS = 680;
|
||||
+ if (*strength < MIN_STRENGTH_DVBS)
|
||||
+ *strength = 0;
|
||||
+ else if(*strength > MAX_STRENGTH_DVBS)
|
||||
+ *strength = 0xFFFF;
|
||||
+ else
|
||||
+ *strength = (*strength - MIN_STRENGTH_DVBS) * 0xFFFF / (MAX_STRENGTH_DVBS - MIN_STRENGTH_DVBS);
|
||||
+
|
||||
dprintk(state->verbose, FE_DEBUG, 1, "AGCIQVALUE = 0x%02x, C = %d * 0.1 dBm",
|
||||
val & 0xff, *strength);
|
||||
}
|
||||
@@ -983,6 +993,7 @@
|
||||
|
||||
*strength = stb0899_table_lookup(stb0899_dvbs2rf_tab, ARRAY_SIZE(stb0899_dvbs2rf_tab) - 1, val);
|
||||
*strength += 950;
|
||||
+ *strength = *strength << 4;
|
||||
dprintk(state->verbose, FE_DEBUG, 1, "IF_AGC_GAIN = 0x%04x, C = %d * 0.1 dBm",
|
||||
val & 0x3fff, *strength);
|
||||
}
|
||||
@@ -1016,6 +1027,16 @@
|
||||
val = MAKEWORD16(buf[0], buf[1]);
|
||||
|
||||
*snr = stb0899_table_lookup(stb0899_cn_tab, ARRAY_SIZE(stb0899_cn_tab) - 1, val);
|
||||
+
|
||||
+ const int MIN_SNR_DVBS = 0;
|
||||
+ const int MAX_SNR_DVBS = 200;
|
||||
+ if (*snr < MIN_SNR_DVBS)
|
||||
+ *snr = 0;
|
||||
+ else if(*snr > MAX_SNR_DVBS)
|
||||
+ *snr = 0xFFFF;
|
||||
+ else
|
||||
+ *snr = (*snr - MIN_SNR_DVBS) * 0xFFFF / (MAX_SNR_DVBS - MIN_SNR_DVBS);
|
||||
+
|
||||
dprintk(state->verbose, FE_DEBUG, 1, "NIR = 0x%02x%02x = %u, C/N = %d * 0.1 dBm\n",
|
||||
buf[0], buf[1], val, *snr);
|
||||
}
|
||||
@@ -1040,6 +1061,16 @@
|
||||
val = (quantn - estn) / 10;
|
||||
}
|
||||
*snr = val;
|
||||
+
|
||||
+ const int MIN_SNR_DVBS2 = 10;
|
||||
+ const int MAX_SNR_DVBS2 = 70;
|
||||
+ if (*snr < MIN_SNR_DVBS2)
|
||||
+ *snr = 0;
|
||||
+ else if(*snr > MAX_SNR_DVBS2)
|
||||
+ *snr = 0xFFFF;
|
||||
+ else
|
||||
+ *snr = (*snr - MIN_SNR_DVBS2) * 0xFFFF / (MAX_SNR_DVBS2 - MIN_SNR_DVBS2);
|
||||
+
|
||||
dprintk(state->verbose, FE_DEBUG, 1, "Es/N0 quant = %d (%d) estimate = %u (%d), C/N = %d * 0.1 dBm",
|
||||
quant, quantn, est, estn, val);
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
diff -Naur linux-3.7.9/drivers/media/usb/dvb-usb/pctv452e.c linux-3.7.9.patch/drivers/media/usb/dvb-usb/pctv452e.c
|
||||
--- linux-3.7.9/drivers/media/usb/dvb-usb/pctv452e.c 2013-01-11 18:19:28.000000000 +0100
|
||||
+++ linux-3.7.9.patch/drivers/media/usb/dvb-usb/pctv452e.c 2013-01-16 10:35:01.131342123 +0100
|
||||
@@ -995,11 +995,11 @@
|
||||
/* parameter for the MPEG2-data transfer */
|
||||
.stream = {
|
||||
.type = USB_ISOC,
|
||||
- .count = 7,
|
||||
+ .count = 4,
|
||||
.endpoint = 0x02,
|
||||
.u = {
|
||||
.isoc = {
|
||||
- .framesperurb = 4,
|
||||
+ .framesperurb = 64,
|
||||
.framesize = 940,
|
||||
.interval = 1
|
||||
}
|
@ -1,21 +0,0 @@
|
||||
--- a/drivers/net/wireless/brcm80211/brcmfmac/usb.c 2013-07-21 16:06:37.443909481 +0200
|
||||
+++ b/drivers/net/wireless/brcm80211/brcmfmac/usb.c 2013-07-21 16:11:10.696335476 +0200
|
||||
@@ -1470,15 +1470,18 @@
|
||||
}
|
||||
|
||||
#define BRCMF_USB_VENDOR_ID_BROADCOM 0x0a5c
|
||||
+#define BRCMF_USB_VENDOR_ID_LINKSYS 0x13b1
|
||||
#define BRCMF_USB_DEVICE_ID_43143 0xbd1e
|
||||
#define BRCMF_USB_DEVICE_ID_43236 0xbd17
|
||||
#define BRCMF_USB_DEVICE_ID_43242 0xbd1f
|
||||
+#define BRCMF_USB_DEVICE_ID_AE2500 0x003a
|
||||
#define BRCMF_USB_DEVICE_ID_BCMFW 0x0bdc
|
||||
|
||||
static struct usb_device_id brcmf_usb_devid_table[] = {
|
||||
{ USB_DEVICE(BRCMF_USB_VENDOR_ID_BROADCOM, BRCMF_USB_DEVICE_ID_43143) },
|
||||
{ USB_DEVICE(BRCMF_USB_VENDOR_ID_BROADCOM, BRCMF_USB_DEVICE_ID_43236) },
|
||||
{ USB_DEVICE(BRCMF_USB_VENDOR_ID_BROADCOM, BRCMF_USB_DEVICE_ID_43242) },
|
||||
+ { USB_DEVICE(BRCMF_USB_VENDOR_ID_LINKSYS, BRCMF_USB_DEVICE_ID_AE2500) },
|
||||
/* special entry for device with firmware loaded and running */
|
||||
{ USB_DEVICE(BRCMF_USB_VENDOR_ID_BROADCOM, BRCMF_USB_DEVICE_ID_BCMFW) },
|
||||
{ }
|
@ -1,72 +0,0 @@
|
||||
commit 073af93346306a0e079c161e3ed8dd263fef0b20
|
||||
Author: Stefan Saraev <stefan@saraev.ca>
|
||||
Date: Sat Jul 13 19:31:03 2013 +0300
|
||||
|
||||
Support for cheap Ralink 3070 WiFi plug
|
||||
|
||||
source: http://www.geekamole.com/2013/rt2800usb-fix-for-ralinkmediatek-3070-gentoo-linux/
|
||||
|
||||
diff --git a/drivers/net/wireless/rt2x00/rt2800.h b/drivers/net/wireless/rt2x00/rt2800.h
|
||||
index a7630d5..9504d45 100644
|
||||
--- a/drivers/net/wireless/rt2x00/rt2800.h
|
||||
+++ b/drivers/net/wireless/rt2x00/rt2800.h
|
||||
@@ -69,6 +69,7 @@
|
||||
#define RF3320 0x000b
|
||||
#define RF3322 0x000c
|
||||
#define RF3053 0x000d
|
||||
+#define RF3070 0x3070
|
||||
#define RF5592 0x000f
|
||||
#define RF3290 0x3290
|
||||
#define RF5360 0x5360
|
||||
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
|
||||
index 72f32e5..3e18df4 100644
|
||||
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
|
||||
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
|
||||
@@ -2599,6 +2599,7 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev,
|
||||
break;
|
||||
case RF5360:
|
||||
case RF5370:
|
||||
+ case RF3070:
|
||||
case RF5372:
|
||||
case RF5390:
|
||||
case RF5392:
|
||||
@@ -2615,6 +2616,7 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev,
|
||||
rt2x00_rf(rt2x00dev, RF3322) ||
|
||||
rt2x00_rf(rt2x00dev, RF5360) ||
|
||||
rt2x00_rf(rt2x00dev, RF5370) ||
|
||||
+ rt2x00_rf(rt2x00dev, RF3070) ||
|
||||
rt2x00_rf(rt2x00dev, RF5372) ||
|
||||
rt2x00_rf(rt2x00dev, RF5390) ||
|
||||
rt2x00_rf(rt2x00dev, RF5392)) {
|
||||
@@ -3199,6 +3201,7 @@ void rt2800_vco_calibration(struct rt2x00_dev *rt2x00dev)
|
||||
case RF3290:
|
||||
case RF5360:
|
||||
case RF5370:
|
||||
+ case RF3070:
|
||||
case RF5372:
|
||||
case RF5390:
|
||||
case RF5392:
|
||||
@@ -5515,6 +5518,7 @@ static int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev)
|
||||
case RF3322:
|
||||
case RF5360:
|
||||
case RF5370:
|
||||
+ case RF3070:
|
||||
case RF5372:
|
||||
case RF5390:
|
||||
case RF5392:
|
||||
@@ -5969,6 +5973,7 @@ static int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
|
||||
rt2x00_rf(rt2x00dev, RF3322) ||
|
||||
rt2x00_rf(rt2x00dev, RF5360) ||
|
||||
rt2x00_rf(rt2x00dev, RF5370) ||
|
||||
+ rt2x00_rf(rt2x00dev, RF3070) ||
|
||||
rt2x00_rf(rt2x00dev, RF5372) ||
|
||||
rt2x00_rf(rt2x00dev, RF5390) ||
|
||||
rt2x00_rf(rt2x00dev, RF5392)) {
|
||||
@@ -6071,6 +6076,7 @@ static int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
|
||||
case RF3290:
|
||||
case RF5360:
|
||||
case RF5370:
|
||||
+ case RF3070:
|
||||
case RF5372:
|
||||
case RF5390:
|
||||
case RF5392:
|
@ -1,28 +0,0 @@
|
||||
From 62330f8f9b6105bfe201f52b7ed86ea6ce3d5901 Mon Sep 17 00:00:00 2001
|
||||
From: popcornmix <popcornmix@gmail.com>
|
||||
Date: Sun, 8 Sep 2013 10:33:51 +0100
|
||||
Subject: [PATCH] Add Ubiquiti WifiStation USB id to ath9k wifi driver
|
||||
|
||||
---
|
||||
drivers/net/wireless/ath/ath9k/hif_usb.c | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c
|
||||
index 75a6376..8cb8d8d 100644
|
||||
--- a/drivers/net/wireless/ath/ath9k/hif_usb.c
|
||||
+++ b/drivers/net/wireless/ath/ath9k/hif_usb.c
|
||||
@@ -37,9 +37,11 @@
|
||||
{ USB_DEVICE(0x13D3, 0x3350) }, /* Azurewave */
|
||||
{ USB_DEVICE(0x04CA, 0x4605) }, /* Liteon */
|
||||
{ USB_DEVICE(0x040D, 0x3801) }, /* VIA */
|
||||
+ { USB_DEVICE(0x0cf3, 0xb002) }, /* Ubiquiti WifiStation */
|
||||
{ USB_DEVICE(0x0cf3, 0xb003) }, /* Ubiquiti WifiStation Ext */
|
||||
{ USB_DEVICE(0x0cf3, 0xb002) }, /* Ubiquiti WifiStation */
|
||||
{ USB_DEVICE(0x057c, 0x8403) }, /* AVM FRITZ!WLAN 11N v2 USB */
|
||||
+ { USB_DEVICE(0x057c, 0x8403) }, /* AVM FRITZ!WLAN 11N v2 USB */
|
||||
|
||||
{ USB_DEVICE(0x0cf3, 0x7015),
|
||||
.driver_info = AR9287_USB }, /* Atheros */
|
||||
--
|
||||
1.8.4
|
||||
|
@ -1,10 +0,0 @@
|
||||
--- a/drivers/net/wireless/rt2x00/rt2800usb.c 2013-10-08 15:14:44.844047190 +0200
|
||||
+++ b/drivers/net/wireless/rt2x00/rt2800usb.c 2013-10-08 15:15:00.279904575 +0200
|
||||
@@ -976,6 +976,7 @@
|
||||
{ USB_DEVICE(0x0411, 0x015d) },
|
||||
{ USB_DEVICE(0x0411, 0x016f) },
|
||||
{ USB_DEVICE(0x0411, 0x01a2) },
|
||||
+ { USB_DEVICE(0x0411, 0x01a8) },
|
||||
{ USB_DEVICE(0x0411, 0x01ee) },
|
||||
/* Corega */
|
||||
{ USB_DEVICE(0x07aa, 0x002f) },
|
@ -1,11 +0,0 @@
|
||||
diff -Naur linux-3.10.16/drivers/staging/rtl8712/usb_intf.c linux-3.10.16.patch/drivers/staging/rtl8712/usb_intf.c
|
||||
--- linux-3.10.16/drivers/staging/rtl8712/usb_intf.c 2013-10-14 01:08:56.000000000 +0200
|
||||
+++ linux-3.10.16.patch/drivers/staging/rtl8712/usb_intf.c 2013-10-16 13:27:44.032951265 +0200
|
||||
@@ -92,6 +92,7 @@
|
||||
{USB_DEVICE(0x0DF6, 0x005B)},
|
||||
{USB_DEVICE(0x0DF6, 0x005D)},
|
||||
{USB_DEVICE(0x0DF6, 0x0063)},
|
||||
+ {USB_DEVICE(0x0DF6, 0x006C)},
|
||||
/* Sweex */
|
||||
{USB_DEVICE(0x177F, 0x0154)},
|
||||
/* Thinkware */
|
File diff suppressed because it is too large
Load Diff
@ -1,49 +0,0 @@
|
||||
From 9098cb577d0f4b2dd71f37988515686008b7c733 Mon Sep 17 00:00:00 2001
|
||||
From: Stefan Saraev <stefan@saraev.ca>
|
||||
Date: Tue, 24 Sep 2013 13:42:50 +0300
|
||||
Subject: [PATCH] mac80211: ignore (E)CSA in probe response frames
|
||||
|
||||
BP: https://git.kernel.org/cgit/linux/kernel/git/stable/linux-stable.git/commit/net/mac80211/mlme.c?id=d70b7616d9080ec9f868fbd31db5fd4341435d61
|
||||
|
||||
thanks @bedouin67
|
||||
---
|
||||
net/mac80211/mlme.c | 11 +++--------
|
||||
1 file changed, 3 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
|
||||
index 5b4328d..1c5a8e6 100644
|
||||
--- a/net/mac80211/mlme.c
|
||||
+++ b/net/mac80211/mlme.c
|
||||
@@ -2885,19 +2885,11 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
|
||||
if (bss)
|
||||
ieee80211_rx_bss_put(local, bss);
|
||||
|
||||
- if (!sdata->u.mgd.associated ||
|
||||
- !ether_addr_equal(mgmt->bssid, sdata->u.mgd.associated->bssid))
|
||||
- return;
|
||||
-
|
||||
if (need_ps) {
|
||||
mutex_lock(&local->iflist_mtx);
|
||||
ieee80211_recalc_ps(local, -1);
|
||||
mutex_unlock(&local->iflist_mtx);
|
||||
}
|
||||
-
|
||||
- ieee80211_sta_process_chanswitch(sdata, rx_status->mactime,
|
||||
- elems, true);
|
||||
-
|
||||
}
|
||||
|
||||
|
||||
@@ -3182,6 +3174,9 @@ ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
|
||||
|
||||
ieee80211_rx_bss_info(sdata, mgmt, len, rx_status, &elems);
|
||||
|
||||
+ ieee80211_sta_process_chanswitch(sdata, rx_status->mactime,
|
||||
+ &elems, true);
|
||||
+
|
||||
if (ieee80211_sta_wmm_params(local, sdata, elems.wmm_param,
|
||||
elems.wmm_param_len))
|
||||
changed |= BSS_CHANGED_QOS;
|
||||
--
|
||||
1.8.3.2
|
||||
|
@ -1,59 +0,0 @@
|
||||
diff -Naur a/arch/arm/boot/dts/imx6dl-hummingboard.dts b/arch/arm/boot/dts/imx6dl-hummingboard.dts
|
||||
--- a/arch/arm/boot/dts/imx6dl-hummingboard.dts 2014-03-22 18:54:01.000000000 +0100
|
||||
+++ b/arch/arm/boot/dts/imx6dl-hummingboard.dts 2014-03-22 19:27:28.561585329 +0100
|
||||
@@ -58,13 +58,13 @@
|
||||
regulator-max-microvolt = <5000000>;
|
||||
};
|
||||
};
|
||||
-
|
||||
+/*
|
||||
codec: spdif-transmitter {
|
||||
compatible = "linux,spdif-dit";
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_hummingboard_spdif>;
|
||||
};
|
||||
-
|
||||
+*/
|
||||
imx-drm {
|
||||
compatible = "fsl,imx-drm";
|
||||
crtcs = <&ipu1 0>, <&ipu1 1>;
|
||||
@@ -74,9 +74,10 @@
|
||||
sound-spdif {
|
||||
compatible = "fsl,imx-audio-spdif";
|
||||
model = "imx-spdif";
|
||||
- /* IMX6 doesn't implement this yet */
|
||||
spdif-controller = <&spdif>;
|
||||
spdif-out;
|
||||
+ pinctrl-names = "default";
|
||||
+ pinctrl-0 = <&pinctrl_hummingboard_spdif>;
|
||||
};
|
||||
|
||||
sound-hdmi {
|
||||
diff -Naur a/arch/arm/boot/dts/imx6qdl-cubox-i.dtsi b/arch/arm/boot/dts/imx6qdl-cubox-i.dtsi
|
||||
--- a/arch/arm/boot/dts/imx6qdl-cubox-i.dtsi 2014-03-22 18:54:01.000000000 +0100
|
||||
+++ b/arch/arm/boot/dts/imx6qdl-cubox-i.dtsi 2014-03-22 18:28:38.000000000 +0100
|
||||
@@ -63,13 +63,13 @@
|
||||
regulator-max-microvolt = <5000000>;
|
||||
};
|
||||
};
|
||||
-
|
||||
+/*
|
||||
codec: spdif-transmitter {
|
||||
compatible = "linux,spdif-dit";
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_cubox_i_spdif>;
|
||||
};
|
||||
-
|
||||
+*/
|
||||
imx-drm {
|
||||
compatible = "fsl,imx-drm";
|
||||
crtcs = <&ipu1 0>, <&ipu1 1>;
|
||||
@@ -81,6 +81,8 @@
|
||||
model = "imx-spdif";
|
||||
spdif-controller = <&spdif>;
|
||||
spdif-out;
|
||||
+ pinctrl-names = "default";
|
||||
+ pinctrl-0 = <&pinctrl_cubox_i_spdif>;
|
||||
};
|
||||
|
||||
sound-hdmi {
|
@ -1,11 +0,0 @@
|
||||
--- a/arch/arm/boot/dts/imx6qdl-cubox-i.dtsi 2014-03-20 19:08:39.169319209 +0100
|
||||
+++ b/arch/arm/boot/dts/imx6qdl-cubox-i.dtsi 2014-03-20 19:08:39.185319208 +0100
|
||||
@@ -144,7 +144,7 @@
|
||||
};
|
||||
|
||||
&hdmi_core {
|
||||
- ipu_id = <1>;
|
||||
+ ipu_id = <0>;
|
||||
disp_id = <0>;
|
||||
status = "okay";
|
||||
};
|
@ -1,49 +0,0 @@
|
||||
--- a/arch/arm/boot/dts/imx6dl-hummingboard.dts 2014-02-28 09:35:11.000000000 +0100
|
||||
+++ b/arch/arm/boot/dts/imx6dl-hummingboard.dts 2014-03-17 07:01:02.258818227 +0100
|
||||
@@ -127,8 +127,6 @@
|
||||
};
|
||||
|
||||
&hdmi {
|
||||
- pinctrl-names = "default";
|
||||
- pinctrl-0 = <&pinctrl_hummingboard_hdmi>;
|
||||
ddc = <&i2c2>;
|
||||
status = "okay";
|
||||
crtcs = <&ipu1 0>;
|
||||
@@ -138,14 +136,8 @@
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
-&hdmi_cec {
|
||||
- pinctrl-names = "default";
|
||||
- pinctrl-0 = <&pinctrl_hummingboard_hdmi>;
|
||||
- status = "okay";
|
||||
-};
|
||||
-
|
||||
&hdmi_core {
|
||||
- ipu_id = <1>;
|
||||
+ ipu_id = <0>;
|
||||
disp_id = <0>;
|
||||
status = "okay";
|
||||
};
|
||||
@@ -178,7 +170,7 @@
|
||||
clock-frequency = <100000>;
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_i2c2_2>;
|
||||
- status = "okay";
|
||||
+ status = "disable";
|
||||
};
|
||||
|
||||
&iomuxc {
|
||||
@@ -196,12 +188,6 @@
|
||||
>;
|
||||
};
|
||||
|
||||
- pinctrl_hummingboard_hdmi: hummingboard-hdmi {
|
||||
- fsl,pins = <
|
||||
- MX6QDL_PAD_KEY_ROW2__HDMI_TX_CEC_LINE 0x1f8b0
|
||||
- >;
|
||||
- };
|
||||
-
|
||||
pinctrl_hummingboard_spdif: hummingboard-spdif {
|
||||
fsl,pins = <MX6QDL_PAD_GPIO_17__SPDIF_OUT 0x1b0b0>;
|
||||
};
|
@ -1,22 +0,0 @@
|
||||
diff -Naur linux-cuboxi-592b2d9/arch/arm/boot/dts/imx6dl-hummingboard.dts linux-cuboxi-592b2d9.patch/arch/arm/boot/dts/imx6dl-hummingboard.dts
|
||||
--- linux-cuboxi-592b2d9/arch/arm/boot/dts/imx6dl-hummingboard.dts 2014-04-13 01:48:52.000000000 +0200
|
||||
+++ linux-cuboxi-592b2d9.patch/arch/arm/boot/dts/imx6dl-hummingboard.dts 2014-04-21 19:18:25.799869731 +0200
|
||||
@@ -23,6 +23,7 @@
|
||||
gpios = <&gpio1 2 1>;
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_hummingboard_gpio1_2>;
|
||||
+ linux,rc-map-name = "rc-rc6-mce";
|
||||
};
|
||||
|
||||
regulators {
|
||||
diff -Naur linux-cuboxi-592b2d9/arch/arm/boot/dts/imx6qdl-cubox-i.dtsi linux-cuboxi-592b2d9.patch/arch/arm/boot/dts/imx6qdl-cubox-i.dtsi
|
||||
--- linux-cuboxi-592b2d9/arch/arm/boot/dts/imx6qdl-cubox-i.dtsi 2014-04-13 01:48:52.000000000 +0200
|
||||
+++ linux-cuboxi-592b2d9.patch/arch/arm/boot/dts/imx6qdl-cubox-i.dtsi 2014-04-21 19:18:00.475889579 +0200
|
||||
@@ -14,6 +14,7 @@
|
||||
gpios = <&gpio3 9 1>;
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_cubox_i_ir>;
|
||||
+ linux,rc-map-name = "rc-rc6-mce";
|
||||
};
|
||||
|
||||
pwmleds {
|
@ -1,731 +0,0 @@
|
||||
From 74fc2e85c080b0ddc2a4b2565eda97c55300303d Mon Sep 17 00:00:00 2001
|
||||
From: wolfgar <stephan.rafin@laposte.net>
|
||||
Date: Sat, 26 Apr 2014 16:50:32 +0200
|
||||
Subject: [PATCH] Merge all CEC driver changes to 3.10 This commit pushes all
|
||||
changes I did in the 3.0.35 kernel to improve/fix its behavior with libcec
|
||||
port for imx6
|
||||
|
||||
It also fixes CEC clock handling in case of FB mode change event
|
||||
and of HDMI cable disconnection
|
||||
---
|
||||
drivers/mxc/hdmi-cec/mxc_hdmi-cec.c | 327 +++++++++++++++---------------------
|
||||
drivers/video/mxc/mxc_hdmi.c | 14 +-
|
||||
2 files changed, 147 insertions(+), 194 deletions(-)
|
||||
|
||||
diff --git a/drivers/mxc/hdmi-cec/mxc_hdmi-cec.c b/drivers/mxc/hdmi-cec/mxc_hdmi-cec.c
|
||||
index d0113ee..3a8aff4 100644
|
||||
--- a/drivers/mxc/hdmi-cec/mxc_hdmi-cec.c
|
||||
+++ b/drivers/mxc/hdmi-cec/mxc_hdmi-cec.c
|
||||
@@ -55,6 +55,8 @@
|
||||
#define MESSAGE_TYPE_CONNECTED 4
|
||||
#define MESSAGE_TYPE_SEND_SUCCESS 5
|
||||
|
||||
+#define CEC_TX_INPROGRESS -1
|
||||
+#define CEC_TX_AVAIL 0
|
||||
|
||||
struct hdmi_cec_priv {
|
||||
int receive_error;
|
||||
@@ -63,7 +65,9 @@ struct hdmi_cec_priv {
|
||||
bool cec_state;
|
||||
u8 last_msg[MAX_MESSAGE_LEN];
|
||||
u8 msg_len;
|
||||
- u8 latest_cec_stat;
|
||||
+ int tx_answer;
|
||||
+ u16 latest_cec_stat;
|
||||
+ u8 link_status;
|
||||
spinlock_t irq_lock;
|
||||
struct delayed_work hdmi_cec_work;
|
||||
struct mutex lock;
|
||||
@@ -76,6 +80,7 @@ struct hdmi_cec_event {
|
||||
struct list_head list;
|
||||
};
|
||||
|
||||
+
|
||||
static LIST_HEAD(head);
|
||||
|
||||
static int hdmi_cec_major;
|
||||
@@ -84,11 +89,14 @@ static struct hdmi_cec_priv hdmi_cec_data;
|
||||
static u8 open_count;
|
||||
|
||||
static wait_queue_head_t hdmi_cec_queue;
|
||||
+static wait_queue_head_t tx_cec_queue;
|
||||
+
|
||||
static irqreturn_t mxc_hdmi_cec_isr(int irq, void *data)
|
||||
{
|
||||
struct hdmi_cec_priv *hdmi_cec = data;
|
||||
- u8 cec_stat = 0;
|
||||
+ u16 cec_stat = 0;
|
||||
unsigned long flags;
|
||||
+ u8 phy_stat0;
|
||||
|
||||
spin_lock_irqsave(&hdmi_cec->irq_lock, flags);
|
||||
|
||||
@@ -96,16 +104,24 @@ static irqreturn_t mxc_hdmi_cec_isr(int irq, void *data)
|
||||
|
||||
cec_stat = hdmi_readb(HDMI_IH_CEC_STAT0);
|
||||
hdmi_writeb(cec_stat, HDMI_IH_CEC_STAT0);
|
||||
-
|
||||
+ phy_stat0 = hdmi_readb(HDMI_PHY_STAT0) & 0x02;
|
||||
+ if (hdmi_cec->link_status ^ phy_stat0) {
|
||||
+ /* HPD value changed */
|
||||
+ hdmi_cec->link_status = phy_stat0;
|
||||
+ if (hdmi_cec->link_status)
|
||||
+ cec_stat |= 0x80; /* Connected */
|
||||
+ else
|
||||
+ cec_stat |= 0x100; /* Disconnected */
|
||||
+ }
|
||||
if ((cec_stat & (HDMI_IH_CEC_STAT0_ERROR_INIT | \
|
||||
HDMI_IH_CEC_STAT0_NACK | HDMI_IH_CEC_STAT0_EOM | \
|
||||
- HDMI_IH_CEC_STAT0_DONE)) == 0) {
|
||||
+ HDMI_IH_CEC_STAT0_DONE | 0x180)) == 0) {
|
||||
spin_unlock_irqrestore(&hdmi_cec->irq_lock, flags);
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
-
|
||||
pr_debug("HDMI CEC interrupt received\n");
|
||||
- hdmi_cec->latest_cec_stat = cec_stat;
|
||||
+ /* FIXME : there is a race with latest_cec_stat */
|
||||
+ hdmi_cec->latest_cec_stat = cec_stat ;
|
||||
|
||||
schedule_delayed_work(&(hdmi_cec->hdmi_cec_work), msecs_to_jiffies(20));
|
||||
|
||||
@@ -118,115 +134,70 @@ void mxc_hdmi_cec_handle(u16 cec_stat)
|
||||
{
|
||||
u8 val = 0, i = 0;
|
||||
struct hdmi_cec_event *event = NULL;
|
||||
-
|
||||
- /* The current transmission is successful (for initiator only). */
|
||||
+ /*The current transmission is successful (for initiator only).*/
|
||||
if (!open_count)
|
||||
return;
|
||||
|
||||
if (cec_stat & HDMI_IH_CEC_STAT0_DONE) {
|
||||
-
|
||||
- event = vmalloc(sizeof(struct hdmi_cec_event));
|
||||
- if (NULL == event) {
|
||||
- pr_err("%s: Not enough memory!\n", __func__);
|
||||
- return;
|
||||
- }
|
||||
-
|
||||
- memset(event, 0, sizeof(struct hdmi_cec_event));
|
||||
- event->event_type = MESSAGE_TYPE_SEND_SUCCESS;
|
||||
-
|
||||
- mutex_lock(&hdmi_cec_data.lock);
|
||||
- list_add_tail(&event->list, &head);
|
||||
- mutex_unlock(&hdmi_cec_data.lock);
|
||||
-
|
||||
- wake_up(&hdmi_cec_queue);
|
||||
+ hdmi_cec_data.tx_answer = cec_stat;
|
||||
+ wake_up(&tx_cec_queue);
|
||||
}
|
||||
-
|
||||
- /* EOM is detected so that the received data is ready
|
||||
- * in the receiver data buffer
|
||||
- */
|
||||
+ /*EOM is detected so that the received data is ready in the receiver data buffer*/
|
||||
if (cec_stat & HDMI_IH_CEC_STAT0_EOM) {
|
||||
-
|
||||
hdmi_writeb(0x02, HDMI_IH_CEC_STAT0);
|
||||
-
|
||||
event = vmalloc(sizeof(struct hdmi_cec_event));
|
||||
if (NULL == event) {
|
||||
pr_err("%s: Not enough memory!\n", __func__);
|
||||
return;
|
||||
}
|
||||
memset(event, 0, sizeof(struct hdmi_cec_event));
|
||||
-
|
||||
event->msg_len = hdmi_readb(HDMI_CEC_RX_CNT);
|
||||
if (!event->msg_len) {
|
||||
pr_err("%s: Invalid CEC message length!\n", __func__);
|
||||
return;
|
||||
}
|
||||
event->event_type = MESSAGE_TYPE_RECEIVE_SUCCESS;
|
||||
-
|
||||
for (i = 0; i < event->msg_len; i++)
|
||||
event->msg[i] = hdmi_readb(HDMI_CEC_RX_DATA0+i);
|
||||
hdmi_writeb(0x0, HDMI_CEC_LOCK);
|
||||
-
|
||||
mutex_lock(&hdmi_cec_data.lock);
|
||||
list_add_tail(&event->list, &head);
|
||||
mutex_unlock(&hdmi_cec_data.lock);
|
||||
-
|
||||
wake_up(&hdmi_cec_queue);
|
||||
}
|
||||
-
|
||||
- /* An error is detected on cec line (for initiator only). */
|
||||
+ /*An error is detected on cec line (for initiator only). */
|
||||
if (cec_stat & HDMI_IH_CEC_STAT0_ERROR_INIT) {
|
||||
-
|
||||
mutex_lock(&hdmi_cec_data.lock);
|
||||
hdmi_cec_data.send_error++;
|
||||
- if (hdmi_cec_data.send_error > 5) {
|
||||
- pr_err("%s:Re-transmission is attempted more than 5 times!\n",
|
||||
- __func__);
|
||||
+ if (hdmi_cec_data.send_error > 2) {
|
||||
+ pr_err("%s:Re-transmission is attempted more than 2 times!\n", __func__);
|
||||
hdmi_cec_data.send_error = 0;
|
||||
mutex_unlock(&hdmi_cec_data.lock);
|
||||
+ hdmi_cec_data.tx_answer = cec_stat;
|
||||
+ wake_up(&tx_cec_queue);
|
||||
return;
|
||||
}
|
||||
-
|
||||
- for (i = 0; i < hdmi_cec_data.msg_len; i++) {
|
||||
- hdmi_writeb(hdmi_cec_data.last_msg[i],
|
||||
- HDMI_CEC_TX_DATA0 + i);
|
||||
- }
|
||||
+ for (i = 0; i < hdmi_cec_data.msg_len; i++)
|
||||
+ hdmi_writeb(hdmi_cec_data.last_msg[i], HDMI_CEC_TX_DATA0+i);
|
||||
hdmi_writeb(hdmi_cec_data.msg_len, HDMI_CEC_TX_CNT);
|
||||
-
|
||||
val = hdmi_readb(HDMI_CEC_CTRL);
|
||||
val |= 0x01;
|
||||
hdmi_writeb(val, HDMI_CEC_CTRL);
|
||||
mutex_unlock(&hdmi_cec_data.lock);
|
||||
}
|
||||
-
|
||||
- /* A frame is not acknowledged in a directly addressed message.
|
||||
- * Or a frame is negatively acknowledged in
|
||||
- * a broadcast message (for initiator only).
|
||||
- */
|
||||
+ /*A frame is not acknowledged in a directly addressed message. Or a frame is negatively acknowledged in
|
||||
+ a broadcast message (for initiator only).*/
|
||||
if (cec_stat & HDMI_IH_CEC_STAT0_NACK) {
|
||||
- event = vmalloc(sizeof(struct hdmi_cec_event));
|
||||
- if (NULL == event) {
|
||||
- pr_err("%s: Not enough memory\n", __func__);
|
||||
- return;
|
||||
- }
|
||||
- memset(event, 0, sizeof(struct hdmi_cec_event));
|
||||
- event->event_type = MESSAGE_TYPE_NOACK;
|
||||
-
|
||||
- mutex_lock(&hdmi_cec_data.lock);
|
||||
- list_add_tail(&event->list, &head);
|
||||
- mutex_unlock(&hdmi_cec_data.lock);
|
||||
-
|
||||
- wake_up(&hdmi_cec_queue);
|
||||
+ hdmi_cec_data.tx_answer = cec_stat;
|
||||
+ wake_up(&tx_cec_queue);
|
||||
}
|
||||
-
|
||||
- /* An error is notified by a follower.
|
||||
- * Abnormal logic data bit error (for follower).
|
||||
- */
|
||||
+ /*An error is notified by a follower. Abnormal logic data bit error (for follower).*/
|
||||
if (cec_stat & HDMI_IH_CEC_STAT0_ERROR_FOLL) {
|
||||
hdmi_cec_data.receive_error++;
|
||||
}
|
||||
-
|
||||
- /* HDMI cable connected */
|
||||
+ /*HDMI cable connected*/
|
||||
if (cec_stat & 0x80) {
|
||||
+ pr_info("HDMI link connected\n");
|
||||
event = vmalloc(sizeof(struct hdmi_cec_event));
|
||||
if (NULL == event) {
|
||||
pr_err("%s: Not enough memory\n", __func__);
|
||||
@@ -234,16 +205,14 @@ void mxc_hdmi_cec_handle(u16 cec_stat)
|
||||
}
|
||||
memset(event, 0, sizeof(struct hdmi_cec_event));
|
||||
event->event_type = MESSAGE_TYPE_CONNECTED;
|
||||
-
|
||||
mutex_lock(&hdmi_cec_data.lock);
|
||||
list_add_tail(&event->list, &head);
|
||||
mutex_unlock(&hdmi_cec_data.lock);
|
||||
-
|
||||
wake_up(&hdmi_cec_queue);
|
||||
}
|
||||
-
|
||||
- /* HDMI cable disconnected */
|
||||
+ /*HDMI cable disconnected*/
|
||||
if (cec_stat & 0x100) {
|
||||
+ pr_info("HDMI link disconnected\n");
|
||||
event = vmalloc(sizeof(struct hdmi_cec_event));
|
||||
if (NULL == event) {
|
||||
pr_err("%s: Not enough memory!\n", __func__);
|
||||
@@ -251,30 +220,24 @@ void mxc_hdmi_cec_handle(u16 cec_stat)
|
||||
}
|
||||
memset(event, 0, sizeof(struct hdmi_cec_event));
|
||||
event->event_type = MESSAGE_TYPE_DISCONNECTED;
|
||||
-
|
||||
mutex_lock(&hdmi_cec_data.lock);
|
||||
list_add_tail(&event->list, &head);
|
||||
mutex_unlock(&hdmi_cec_data.lock);
|
||||
-
|
||||
wake_up(&hdmi_cec_queue);
|
||||
}
|
||||
-
|
||||
return;
|
||||
}
|
||||
EXPORT_SYMBOL(mxc_hdmi_cec_handle);
|
||||
-
|
||||
static void mxc_hdmi_cec_worker(struct work_struct *work)
|
||||
{
|
||||
u8 val;
|
||||
-
|
||||
mxc_hdmi_cec_handle(hdmi_cec_data.latest_cec_stat);
|
||||
- val = HDMI_IH_CEC_STAT0_WAKEUP | HDMI_IH_CEC_STAT0_ERROR_FOLL |
|
||||
- HDMI_IH_CEC_STAT0_ARB_LOST;
|
||||
+ val = HDMI_IH_CEC_STAT0_WAKEUP | HDMI_IH_CEC_STAT0_ERROR_FOLL | HDMI_IH_CEC_STAT0_ARB_LOST;
|
||||
hdmi_writeb(val, HDMI_IH_MUTE_CEC_STAT0);
|
||||
}
|
||||
|
||||
/*!
|
||||
- * @brief open function for vpu file operation
|
||||
+ * @brief open function for cec file operation
|
||||
*
|
||||
* @return 0 on success or negative error code on error
|
||||
*/
|
||||
@@ -285,13 +248,11 @@ static int hdmi_cec_open(struct inode *inode, struct file *filp)
|
||||
mutex_unlock(&hdmi_cec_data.lock);
|
||||
return -EBUSY;
|
||||
}
|
||||
-
|
||||
open_count = 1;
|
||||
filp->private_data = (void *)(&hdmi_cec_data);
|
||||
hdmi_cec_data.Logical_address = 15;
|
||||
hdmi_cec_data.cec_state = false;
|
||||
mutex_unlock(&hdmi_cec_data.lock);
|
||||
-
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -299,36 +260,40 @@ static ssize_t hdmi_cec_read(struct file *file, char __user *buf, size_t count,
|
||||
loff_t *ppos)
|
||||
{
|
||||
struct hdmi_cec_event *event = NULL;
|
||||
-
|
||||
pr_debug("function : %s\n", __func__);
|
||||
+
|
||||
if (!open_count)
|
||||
return -ENODEV;
|
||||
-
|
||||
mutex_lock(&hdmi_cec_data.lock);
|
||||
if (false == hdmi_cec_data.cec_state) {
|
||||
mutex_unlock(&hdmi_cec_data.lock);
|
||||
return -EACCES;
|
||||
}
|
||||
- mutex_unlock(&hdmi_cec_data.lock);
|
||||
|
||||
- /* delete from list */
|
||||
- mutex_lock(&hdmi_cec_data.lock);
|
||||
if (list_empty(&head)) {
|
||||
- mutex_unlock(&hdmi_cec_data.lock);
|
||||
- return -EACCES;
|
||||
+ if (file->f_flags & O_NONBLOCK) {
|
||||
+ mutex_unlock(&hdmi_cec_data.lock);
|
||||
+ return -EAGAIN;
|
||||
+ } else {
|
||||
+ do {
|
||||
+ mutex_unlock(&hdmi_cec_data.lock);
|
||||
+ if (wait_event_interruptible(hdmi_cec_queue, (!list_empty(&head))))
|
||||
+ return -ERESTARTSYS;
|
||||
+ mutex_lock(&hdmi_cec_data.lock);
|
||||
+ } while (list_empty(&head));
|
||||
+ }
|
||||
}
|
||||
+
|
||||
event = list_first_entry(&head, struct hdmi_cec_event, list);
|
||||
list_del(&event->list);
|
||||
mutex_unlock(&hdmi_cec_data.lock);
|
||||
-
|
||||
if (copy_to_user(buf, event,
|
||||
- sizeof(struct hdmi_cec_event) - sizeof(struct list_head))) {
|
||||
+ sizeof(struct hdmi_cec_event) - sizeof(struct list_head))) {
|
||||
vfree(event);
|
||||
return -EFAULT;
|
||||
}
|
||||
vfree(event);
|
||||
-
|
||||
- return sizeof(struct hdmi_cec_event);
|
||||
+ return (sizeof(struct hdmi_cec_event) - sizeof(struct list_head));
|
||||
}
|
||||
|
||||
static ssize_t hdmi_cec_write(struct file *file, const char __user *buf,
|
||||
@@ -339,58 +304,77 @@ static ssize_t hdmi_cec_write(struct file *file, const char __user *buf,
|
||||
u8 msg_len = 0, val = 0;
|
||||
|
||||
pr_debug("function : %s\n", __func__);
|
||||
+
|
||||
if (!open_count)
|
||||
return -ENODEV;
|
||||
-
|
||||
mutex_lock(&hdmi_cec_data.lock);
|
||||
if (false == hdmi_cec_data.cec_state) {
|
||||
mutex_unlock(&hdmi_cec_data.lock);
|
||||
return -EACCES;
|
||||
}
|
||||
+ /* Ensure that there is only one writer who is the only listener of tx_cec_queue */
|
||||
+ if (hdmi_cec_data.tx_answer != CEC_TX_AVAIL) {
|
||||
+ mutex_unlock(&hdmi_cec_data.lock);
|
||||
+ return -EBUSY;
|
||||
+ }
|
||||
mutex_unlock(&hdmi_cec_data.lock);
|
||||
-
|
||||
if (count > MAX_MESSAGE_LEN)
|
||||
return -EINVAL;
|
||||
-
|
||||
- mutex_lock(&hdmi_cec_data.lock);
|
||||
- hdmi_cec_data.send_error = 0;
|
||||
memset(&msg, 0, MAX_MESSAGE_LEN);
|
||||
ret = copy_from_user(&msg, buf, count);
|
||||
- if (ret) {
|
||||
- ret = -EACCES;
|
||||
- goto end;
|
||||
- }
|
||||
-
|
||||
+ if (ret)
|
||||
+ return -EACCES;
|
||||
+ mutex_lock(&hdmi_cec_data.lock);
|
||||
+ hdmi_cec_data.send_error = 0;
|
||||
+ hdmi_cec_data.tx_answer = CEC_TX_INPROGRESS;
|
||||
msg_len = count;
|
||||
hdmi_writeb(msg_len, HDMI_CEC_TX_CNT);
|
||||
- for (i = 0; i < msg_len; i++) {
|
||||
+ for (i = 0; i < msg_len; i++)
|
||||
hdmi_writeb(msg[i], HDMI_CEC_TX_DATA0+i);
|
||||
- }
|
||||
-
|
||||
val = hdmi_readb(HDMI_CEC_CTRL);
|
||||
val |= 0x01;
|
||||
hdmi_writeb(val, HDMI_CEC_CTRL);
|
||||
memcpy(hdmi_cec_data.last_msg, msg, msg_len);
|
||||
hdmi_cec_data.msg_len = msg_len;
|
||||
+ mutex_unlock(&hdmi_cec_data.lock);
|
||||
|
||||
- i = 0;
|
||||
- val = hdmi_readb(HDMI_CEC_CTRL);
|
||||
- while ((val & 0x01) == 0x1) {
|
||||
- msleep(50);
|
||||
- i++;
|
||||
- if (i > 3) {
|
||||
- ret = -EIO;
|
||||
- goto end;
|
||||
- }
|
||||
- val = hdmi_readb(HDMI_CEC_CTRL);
|
||||
+ ret = wait_event_interruptible_timeout(tx_cec_queue, hdmi_cec_data.tx_answer != CEC_TX_INPROGRESS, HZ);
|
||||
+
|
||||
+ if (ret < 0) {
|
||||
+ ret = -ERESTARTSYS;
|
||||
+ goto tx_out;
|
||||
}
|
||||
|
||||
-end:
|
||||
- mutex_unlock(&hdmi_cec_data.lock);
|
||||
+ if (hdmi_cec_data.tx_answer & HDMI_IH_CEC_STAT0_DONE)
|
||||
+ /* msg correctly sent */
|
||||
+ ret = msg_len;
|
||||
+ else
|
||||
+ ret = -EIO;
|
||||
|
||||
+ tx_out:
|
||||
+ hdmi_cec_data.tx_answer = CEC_TX_AVAIL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
+
|
||||
+static void hdmi_stop_device(void)
|
||||
+{
|
||||
+ u8 val;
|
||||
+
|
||||
+ hdmi_writeb(0x10, HDMI_CEC_CTRL);
|
||||
+ val = HDMI_IH_CEC_STAT0_WAKEUP | HDMI_IH_CEC_STAT0_ERROR_FOLL | HDMI_IH_CEC_STAT0_ERROR_INIT | HDMI_IH_CEC_STAT0_ARB_LOST | \
|
||||
+ HDMI_IH_CEC_STAT0_NACK | HDMI_IH_CEC_STAT0_EOM | HDMI_IH_CEC_STAT0_DONE;
|
||||
+ hdmi_writeb(val, HDMI_CEC_MASK);
|
||||
+ hdmi_writeb(val, HDMI_IH_MUTE_CEC_STAT0);
|
||||
+ hdmi_writeb(0x0, HDMI_CEC_POLARITY);
|
||||
+ val = hdmi_readb(HDMI_MC_CLKDIS);
|
||||
+ val |= HDMI_MC_CLKDIS_CECCLK_DISABLE;
|
||||
+ hdmi_writeb(val, HDMI_MC_CLKDIS);
|
||||
+ mutex_lock(&hdmi_cec_data.lock);
|
||||
+ hdmi_cec_data.cec_state = false;
|
||||
+ mutex_unlock(&hdmi_cec_data.lock);
|
||||
+}
|
||||
+
|
||||
/*!
|
||||
* @brief IO ctrl function for vpu file operation
|
||||
* @param cmd IO ctrl command
|
||||
@@ -402,93 +386,59 @@ static long hdmi_cec_ioctl(struct file *filp, u_int cmd,
|
||||
int ret = 0, status = 0;
|
||||
u8 val = 0, msg = 0;
|
||||
struct mxc_edid_cfg hdmi_edid_cfg;
|
||||
-
|
||||
pr_debug("function : %s\n", __func__);
|
||||
if (!open_count)
|
||||
return -ENODEV;
|
||||
-
|
||||
switch (cmd) {
|
||||
case HDMICEC_IOC_SETLOGICALADDRESS:
|
||||
mutex_lock(&hdmi_cec_data.lock);
|
||||
if (false == hdmi_cec_data.cec_state) {
|
||||
mutex_unlock(&hdmi_cec_data.lock);
|
||||
+ pr_err("Trying to set logical address while not started\n");
|
||||
return -EACCES;
|
||||
}
|
||||
-
|
||||
hdmi_cec_data.Logical_address = (u8)arg;
|
||||
-
|
||||
if (hdmi_cec_data.Logical_address <= 7) {
|
||||
val = 1 << hdmi_cec_data.Logical_address;
|
||||
hdmi_writeb(val, HDMI_CEC_ADDR_L);
|
||||
hdmi_writeb(0, HDMI_CEC_ADDR_H);
|
||||
- } else if (hdmi_cec_data.Logical_address > 7 &&
|
||||
- hdmi_cec_data.Logical_address <= 15) {
|
||||
+ } else if (hdmi_cec_data.Logical_address > 7 && hdmi_cec_data.Logical_address <= 15) {
|
||||
val = 1 << (hdmi_cec_data.Logical_address - 8);
|
||||
hdmi_writeb(val, HDMI_CEC_ADDR_H);
|
||||
hdmi_writeb(0, HDMI_CEC_ADDR_L);
|
||||
- } else {
|
||||
+ } else
|
||||
ret = -EINVAL;
|
||||
- }
|
||||
-
|
||||
- /* Send Polling message with same source
|
||||
- * and destination address
|
||||
- */
|
||||
+ /*Send Polling message with same source and destination address*/
|
||||
if (0 == ret && 15 != hdmi_cec_data.Logical_address) {
|
||||
- msg = (hdmi_cec_data.Logical_address << 4) |
|
||||
- hdmi_cec_data.Logical_address;
|
||||
+ msg = (hdmi_cec_data.Logical_address << 4)|hdmi_cec_data.Logical_address;
|
||||
hdmi_writeb(1, HDMI_CEC_TX_CNT);
|
||||
hdmi_writeb(msg, HDMI_CEC_TX_DATA0);
|
||||
-
|
||||
val = hdmi_readb(HDMI_CEC_CTRL);
|
||||
val |= 0x01;
|
||||
hdmi_writeb(val, HDMI_CEC_CTRL);
|
||||
}
|
||||
-
|
||||
mutex_unlock(&hdmi_cec_data.lock);
|
||||
break;
|
||||
-
|
||||
case HDMICEC_IOC_STARTDEVICE:
|
||||
val = hdmi_readb(HDMI_MC_CLKDIS);
|
||||
val &= ~HDMI_MC_CLKDIS_CECCLK_DISABLE;
|
||||
hdmi_writeb(val, HDMI_MC_CLKDIS);
|
||||
-
|
||||
hdmi_writeb(0x02, HDMI_CEC_CTRL);
|
||||
-
|
||||
- val = HDMI_IH_CEC_STAT0_ERROR_INIT | HDMI_IH_CEC_STAT0_NACK |
|
||||
- HDMI_IH_CEC_STAT0_EOM | HDMI_IH_CEC_STAT0_DONE;
|
||||
+ /* Force read unlock */
|
||||
+ hdmi_writeb(0x0, HDMI_CEC_LOCK);
|
||||
+ val = HDMI_IH_CEC_STAT0_ERROR_INIT | HDMI_IH_CEC_STAT0_NACK | HDMI_IH_CEC_STAT0_EOM | HDMI_IH_CEC_STAT0_DONE;
|
||||
hdmi_writeb(val, HDMI_CEC_POLARITY);
|
||||
-
|
||||
- val = HDMI_IH_CEC_STAT0_WAKEUP | HDMI_IH_CEC_STAT0_ERROR_FOLL |
|
||||
- HDMI_IH_CEC_STAT0_ARB_LOST;
|
||||
+ val = HDMI_IH_CEC_STAT0_WAKEUP | HDMI_IH_CEC_STAT0_ERROR_FOLL | HDMI_IH_CEC_STAT0_ARB_LOST;
|
||||
hdmi_writeb(val, HDMI_CEC_MASK);
|
||||
hdmi_writeb(val, HDMI_IH_MUTE_CEC_STAT0);
|
||||
-
|
||||
+ hdmi_cec_data.link_status = hdmi_readb(HDMI_PHY_STAT0) & 0x02;
|
||||
mutex_lock(&hdmi_cec_data.lock);
|
||||
hdmi_cec_data.cec_state = true;
|
||||
mutex_unlock(&hdmi_cec_data.lock);
|
||||
break;
|
||||
-
|
||||
case HDMICEC_IOC_STOPDEVICE:
|
||||
- hdmi_writeb(0x10, HDMI_CEC_CTRL);
|
||||
-
|
||||
- val = HDMI_IH_CEC_STAT0_WAKEUP | HDMI_IH_CEC_STAT0_ERROR_FOLL |
|
||||
- HDMI_IH_CEC_STAT0_ERROR_INIT | HDMI_IH_CEC_STAT0_ARB_LOST |
|
||||
- HDMI_IH_CEC_STAT0_NACK | HDMI_IH_CEC_STAT0_EOM |
|
||||
- HDMI_IH_CEC_STAT0_DONE;
|
||||
- hdmi_writeb(val, HDMI_CEC_MASK);
|
||||
- hdmi_writeb(val, HDMI_IH_MUTE_CEC_STAT0);
|
||||
-
|
||||
- hdmi_writeb(0x0, HDMI_CEC_POLARITY);
|
||||
-
|
||||
- val = hdmi_readb(HDMI_MC_CLKDIS);
|
||||
- val |= HDMI_MC_CLKDIS_CECCLK_DISABLE;
|
||||
- hdmi_writeb(val, HDMI_MC_CLKDIS);
|
||||
-
|
||||
- mutex_lock(&hdmi_cec_data.lock);
|
||||
- hdmi_cec_data.cec_state = false;
|
||||
- mutex_unlock(&hdmi_cec_data.lock);
|
||||
+ hdmi_stop_device();
|
||||
break;
|
||||
-
|
||||
case HDMICEC_IOC_GETPHYADDRESS:
|
||||
hdmi_get_edid_cfg(&hdmi_edid_cfg);
|
||||
status = copy_to_user((void __user *)arg,
|
||||
@@ -497,29 +447,25 @@ static long hdmi_cec_ioctl(struct file *filp, u_int cmd,
|
||||
if (status)
|
||||
ret = -EFAULT;
|
||||
break;
|
||||
-
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
}
|
||||
-
|
||||
- return ret;
|
||||
+ return ret;
|
||||
}
|
||||
|
||||
/*!
|
||||
-* @brief Release function for vpu file operation
|
||||
-* @return 0 on success or negative error code on error
|
||||
-*/
|
||||
+ * @brief Release function for vpu file operation
|
||||
+ * @return 0 on success or negative error code on error
|
||||
+ */
|
||||
static int hdmi_cec_release(struct inode *inode, struct file *filp)
|
||||
{
|
||||
mutex_lock(&hdmi_cec_data.lock);
|
||||
-
|
||||
if (open_count) {
|
||||
open_count = 0;
|
||||
hdmi_cec_data.cec_state = false;
|
||||
hdmi_cec_data.Logical_address = 15;
|
||||
}
|
||||
-
|
||||
mutex_unlock(&hdmi_cec_data.lock);
|
||||
|
||||
return 0;
|
||||
@@ -531,20 +477,18 @@ static unsigned int hdmi_cec_poll(struct file *file, poll_table *wait)
|
||||
|
||||
pr_debug("function : %s\n", __func__);
|
||||
|
||||
- if (!open_count)
|
||||
- return -ENODEV;
|
||||
-
|
||||
- if (false == hdmi_cec_data.cec_state)
|
||||
- return -EACCES;
|
||||
-
|
||||
poll_wait(file, &hdmi_cec_queue, wait);
|
||||
|
||||
+ /* Always writable */
|
||||
+ mask = (POLLOUT | POLLWRNORM);
|
||||
+ mutex_lock(&hdmi_cec_data.lock);
|
||||
if (!list_empty(&head))
|
||||
- mask |= (POLLIN | POLLRDNORM);
|
||||
-
|
||||
+ mask |= (POLLIN | POLLRDNORM);
|
||||
+ mutex_unlock(&hdmi_cec_data.lock);
|
||||
return mask;
|
||||
}
|
||||
|
||||
+
|
||||
const struct file_operations hdmi_cec_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.read = hdmi_cec_read,
|
||||
@@ -563,20 +507,18 @@ static int hdmi_cec_dev_probe(struct platform_device *pdev)
|
||||
struct pinctrl *pinctrl;
|
||||
int irq = platform_get_irq(pdev, 0);
|
||||
|
||||
- hdmi_cec_major = register_chrdev(hdmi_cec_major,
|
||||
- "mxc_hdmi_cec", &hdmi_cec_fops);
|
||||
+ hdmi_cec_major = register_chrdev(hdmi_cec_major, "mxc_hdmi_cec", &hdmi_cec_fops);
|
||||
if (hdmi_cec_major < 0) {
|
||||
dev_err(&pdev->dev, "hdmi_cec: unable to get a major for HDMI CEC\n");
|
||||
err = -EBUSY;
|
||||
goto out;
|
||||
}
|
||||
-
|
||||
+
|
||||
res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
|
||||
if (unlikely(res == NULL)) {
|
||||
dev_err(&pdev->dev, "hdmi_cec:No HDMI irq line provided\n");
|
||||
goto err_out_chrdev;
|
||||
}
|
||||
-
|
||||
spin_lock_init(&hdmi_cec_data.irq_lock);
|
||||
|
||||
err = devm_request_irq(&pdev->dev, irq, mxc_hdmi_cec_isr, IRQF_SHARED,
|
||||
@@ -592,8 +534,8 @@ static int hdmi_cec_dev_probe(struct platform_device *pdev)
|
||||
goto err_out_chrdev;
|
||||
}
|
||||
|
||||
- temp_class = device_create(hdmi_cec_class, NULL,
|
||||
- MKDEV(hdmi_cec_major, 0), NULL, "mxc_hdmi_cec");
|
||||
+ temp_class = device_create(hdmi_cec_class, NULL, MKDEV(hdmi_cec_major, 0),
|
||||
+ NULL, "mxc_hdmi_cec");
|
||||
if (IS_ERR(temp_class)) {
|
||||
err = PTR_ERR(temp_class);
|
||||
goto err_out_class;
|
||||
@@ -606,15 +548,14 @@ static int hdmi_cec_dev_probe(struct platform_device *pdev)
|
||||
}
|
||||
|
||||
init_waitqueue_head(&hdmi_cec_queue);
|
||||
+ init_waitqueue_head(&tx_cec_queue);
|
||||
|
||||
INIT_LIST_HEAD(&head);
|
||||
|
||||
mutex_init(&hdmi_cec_data.lock);
|
||||
-
|
||||
hdmi_cec_data.Logical_address = 15;
|
||||
-
|
||||
+ hdmi_cec_data.tx_answer = CEC_TX_AVAIL;
|
||||
platform_set_drvdata(pdev, &hdmi_cec_data);
|
||||
-
|
||||
INIT_DELAYED_WORK(&hdmi_cec_data.hdmi_cec_work, mxc_hdmi_cec_worker);
|
||||
|
||||
dev_info(&pdev->dev, "HDMI CEC initialized\n");
|
||||
@@ -631,12 +572,14 @@ static int hdmi_cec_dev_probe(struct platform_device *pdev)
|
||||
|
||||
static int hdmi_cec_dev_remove(struct platform_device *pdev)
|
||||
{
|
||||
+ if (hdmi_cec_data.cec_state)
|
||||
+ hdmi_stop_device();
|
||||
if (hdmi_cec_major > 0) {
|
||||
device_destroy(hdmi_cec_class, MKDEV(hdmi_cec_major, 0));
|
||||
class_destroy(hdmi_cec_class);
|
||||
unregister_chrdev(hdmi_cec_major, "mxc_hdmi_cec");
|
||||
hdmi_cec_major = 0;
|
||||
- }
|
||||
+}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -650,9 +593,9 @@ static struct platform_driver mxc_hdmi_cec_driver = {
|
||||
.probe = hdmi_cec_dev_probe,
|
||||
.remove = hdmi_cec_dev_remove,
|
||||
.driver = {
|
||||
- .name = "mxc_hdmi_cec",
|
||||
+ .name = "mxc_hdmi_cec",
|
||||
.of_match_table = imx_hdmi_cec_match,
|
||||
- },
|
||||
+ },
|
||||
};
|
||||
|
||||
module_platform_driver(mxc_hdmi_cec_driver);
|
||||
diff --git a/drivers/video/mxc/mxc_hdmi.c b/drivers/video/mxc/mxc_hdmi.c
|
||||
index 20c6d70..88d62ce 100644
|
||||
--- a/drivers/video/mxc/mxc_hdmi.c
|
||||
+++ b/drivers/video/mxc/mxc_hdmi.c
|
||||
@@ -1708,8 +1708,12 @@ static void mxc_hdmi_enable_video_path(struct mxc_hdmi *hdmi)
|
||||
hdmi_writeb(0x16, HDMI_FC_CH1PREAM);
|
||||
hdmi_writeb(0x21, HDMI_FC_CH2PREAM);
|
||||
|
||||
+ /* Save CEC clock */
|
||||
+ clkdis = hdmi_readb(HDMI_MC_CLKDIS) & HDMI_MC_CLKDIS_CECCLK_DISABLE;
|
||||
+ clkdis |= ~HDMI_MC_CLKDIS_CECCLK_DISABLE;
|
||||
+
|
||||
/* Enable pixel clock and tmds data path */
|
||||
- clkdis = 0x7F;
|
||||
+ clkdis = 0x7F & clkdis;
|
||||
clkdis &= ~HDMI_MC_CLKDIS_PIXELCLK_DISABLE;
|
||||
hdmi_writeb(clkdis, HDMI_MC_CLKDIS);
|
||||
|
||||
@@ -1990,10 +1994,16 @@ static void mxc_hdmi_power_off(struct mxc_dispdrv_handle *disp)
|
||||
|
||||
static void mxc_hdmi_cable_disconnected(struct mxc_hdmi *hdmi)
|
||||
{
|
||||
+ u8 clkdis;
|
||||
+
|
||||
dev_dbg(&hdmi->pdev->dev, "%s\n", __func__);
|
||||
|
||||
+ /* Save CEC clock */
|
||||
+ clkdis = hdmi_readb(HDMI_MC_CLKDIS) & HDMI_MC_CLKDIS_CECCLK_DISABLE;
|
||||
+ clkdis |= ~HDMI_MC_CLKDIS_CECCLK_DISABLE;
|
||||
+
|
||||
/* Disable All HDMI clock */
|
||||
- hdmi_writeb(0xff, HDMI_MC_CLKDIS);
|
||||
+ hdmi_writeb(0xff & clkdis, HDMI_MC_CLKDIS);
|
||||
|
||||
mxc_hdmi_phy_disable(hdmi);
|
||||
|
||||
--
|
||||
1.9.1
|
||||
|
@ -1,76 +0,0 @@
|
||||
From 76796e32b20dd8f34aadad8fd91672017d143812 Mon Sep 17 00:00:00 2001
|
||||
From: wolfgar <stephan.rafin@laposte.net>
|
||||
Date: Tue, 29 Apr 2014 01:35:01 +0200
|
||||
Subject: [PATCH] Fix a bug that could result in CEC interrupts to be
|
||||
improperly muted in case the CEC_STAT register was 0, the worker was not
|
||||
invoked and as a consequence the interrupts were not unmuted Also try to play
|
||||
better with the interrupt sharing with hmdi_video
|
||||
|
||||
---
|
||||
drivers/mxc/hdmi-cec/mxc_hdmi-cec.c | 21 +++++++++++----------
|
||||
1 file changed, 11 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/drivers/mxc/hdmi-cec/mxc_hdmi-cec.c b/drivers/mxc/hdmi-cec/mxc_hdmi-cec.c
|
||||
index 3a8aff4..85e259c 100644
|
||||
--- a/drivers/mxc/hdmi-cec/mxc_hdmi-cec.c
|
||||
+++ b/drivers/mxc/hdmi-cec/mxc_hdmi-cec.c
|
||||
@@ -97,6 +97,7 @@ static irqreturn_t mxc_hdmi_cec_isr(int irq, void *data)
|
||||
u16 cec_stat = 0;
|
||||
unsigned long flags;
|
||||
u8 phy_stat0;
|
||||
+ irqreturn_t ret = IRQ_HANDLED;
|
||||
|
||||
spin_lock_irqsave(&hdmi_cec->irq_lock, flags);
|
||||
|
||||
@@ -105,6 +106,13 @@ static irqreturn_t mxc_hdmi_cec_isr(int irq, void *data)
|
||||
cec_stat = hdmi_readb(HDMI_IH_CEC_STAT0);
|
||||
hdmi_writeb(cec_stat, HDMI_IH_CEC_STAT0);
|
||||
phy_stat0 = hdmi_readb(HDMI_PHY_STAT0) & 0x02;
|
||||
+
|
||||
+ if ((cec_stat & (HDMI_IH_CEC_STAT0_ERROR_INIT | \
|
||||
+ HDMI_IH_CEC_STAT0_NACK | HDMI_IH_CEC_STAT0_EOM | \
|
||||
+ HDMI_IH_CEC_STAT0_DONE)) == 0) {
|
||||
+ ret = IRQ_NONE;
|
||||
+ cec_stat = 0;
|
||||
+ }
|
||||
if (hdmi_cec->link_status ^ phy_stat0) {
|
||||
/* HPD value changed */
|
||||
hdmi_cec->link_status = phy_stat0;
|
||||
@@ -113,21 +121,14 @@ static irqreturn_t mxc_hdmi_cec_isr(int irq, void *data)
|
||||
else
|
||||
cec_stat |= 0x100; /* Disconnected */
|
||||
}
|
||||
- if ((cec_stat & (HDMI_IH_CEC_STAT0_ERROR_INIT | \
|
||||
- HDMI_IH_CEC_STAT0_NACK | HDMI_IH_CEC_STAT0_EOM | \
|
||||
- HDMI_IH_CEC_STAT0_DONE | 0x180)) == 0) {
|
||||
- spin_unlock_irqrestore(&hdmi_cec->irq_lock, flags);
|
||||
- return IRQ_HANDLED;
|
||||
- }
|
||||
pr_debug("HDMI CEC interrupt received\n");
|
||||
- /* FIXME : there is a race with latest_cec_stat */
|
||||
hdmi_cec->latest_cec_stat = cec_stat ;
|
||||
|
||||
schedule_delayed_work(&(hdmi_cec->hdmi_cec_work), msecs_to_jiffies(20));
|
||||
|
||||
spin_unlock_irqrestore(&hdmi_cec->irq_lock, flags);
|
||||
|
||||
- return IRQ_HANDLED;
|
||||
+ return ret;
|
||||
}
|
||||
|
||||
void mxc_hdmi_cec_handle(u16 cec_stat)
|
||||
@@ -479,9 +480,9 @@ static unsigned int hdmi_cec_poll(struct file *file, poll_table *wait)
|
||||
|
||||
poll_wait(file, &hdmi_cec_queue, wait);
|
||||
|
||||
- /* Always writable */
|
||||
- mask = (POLLOUT | POLLWRNORM);
|
||||
mutex_lock(&hdmi_cec_data.lock);
|
||||
+ if (hdmi_cec_data.tx_answer == CEC_TX_AVAIL)
|
||||
+ mask = (POLLOUT | POLLWRNORM);
|
||||
if (!list_empty(&head))
|
||||
mask |= (POLLIN | POLLRDNORM);
|
||||
mutex_unlock(&hdmi_cec_data.lock);
|
||||
--
|
||||
1.9.1
|
||||
|
@ -1,58 +0,0 @@
|
||||
--- u-boot-imx6-cuboxi-3fd848b/include/configs/mx6_cubox-i.h.orig 2014-03-02 20:44:06.000000000 +0100
|
||||
+++ u-boot-imx6-cuboxi-3fd848b/include/configs/mx6_cubox-i.h 2014-03-05 08:11:31.533508170 +0100
|
||||
@@ -150,6 +150,7 @@
|
||||
#define CONFIG_SYS_CONSOLE_IS_IN_ENV
|
||||
|
||||
#define CONFIG_EXTRA_ENV_SETTINGS \
|
||||
+ "zImage=zImage\0" \
|
||||
"script=boot.scr\0" \
|
||||
"bootfile=auto\0" \
|
||||
"bootenv=uEnv.txt\0" \
|
||||
@@ -207,25 +208,25 @@
|
||||
"importbootenv=echo Importing environment from mmc${mmcdev} ...; " \
|
||||
"env import -t ${loadaddr} ${filesize};\0" \
|
||||
"autobootfdt=echo Booting ${boot_file}; " \
|
||||
- "if test ${boot_file} = zImage; then " \
|
||||
+ "if test ${boot_file} = ${zImage}; then " \
|
||||
"bootz ${loadaddr} - ${fdt_addr}; " \
|
||||
"else " \
|
||||
"bootm ${loadaddr} - ${fdt_addr}; " \
|
||||
"fi;\0 " \
|
||||
"autoboot=echo Booting ${boot_file}; " \
|
||||
- "if test ${boot_file} = zImage; then " \
|
||||
+ "if test ${boot_file} = ${zImage}; then " \
|
||||
"bootz; " \
|
||||
"else " \
|
||||
"bootm; " \
|
||||
"fi;\0 " \
|
||||
"bootit=setenv boot_file ${bootfile}; " \
|
||||
- "if test ${boot_file} = zImage; then " \
|
||||
+ "if test ${boot_file} = ${zImage}; then " \
|
||||
"if test ${boot_fdt} = yes || test ${boot_fdt} = try; then " \
|
||||
"if run loadfdt; then " \
|
||||
"run autobootfdt; " \
|
||||
"else " \
|
||||
"if test ${boot_fdt} = try; then " \
|
||||
- "echo WARN: Cannot load the DTB and boot file is type zImage;" \
|
||||
+ "echo WARN: Cannot load the DTB and boot file is type ${zImage};" \
|
||||
"echo if you have not appended a dtb to the file it may;" \
|
||||
"echo hang after displaying Starting kernel...;" \
|
||||
"echo ;" \
|
||||
@@ -255,7 +256,7 @@
|
||||
"setenv get_cmd tftp; " \
|
||||
"fi; " \
|
||||
"if test ${bootfile} = auto; then " \
|
||||
- "setenv bootfile zImage; " \
|
||||
+ "setenv bootfile ${zImage}; " \
|
||||
"if ${get_cmd} ${bootfile}; then " \
|
||||
"run bootit; " \
|
||||
"else " \
|
||||
@@ -278,7 +279,7 @@
|
||||
"fi; " \
|
||||
"if test ${bootfile} = auto; then " \
|
||||
"setenv origbootfile auto; " \
|
||||
- "setenv bootfile zImage; " \
|
||||
+ "setenv bootfile ${zImage}; " \
|
||||
"if run loadbootfile; then " \
|
||||
"run mmcboot; " \
|
||||
"else " \
|
File diff suppressed because it is too large
Load Diff
@ -1,28 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<advancedsettings>
|
||||
<showexitbutton>false</showexitbutton>
|
||||
|
||||
<!---
|
||||
<gui>
|
||||
<nofliptimeout>-1</nofliptimeout>
|
||||
<algorithmdirtyregions>1</algorithmdirtyregions>
|
||||
</gui>
|
||||
--->
|
||||
|
||||
<video>
|
||||
<busydialogdelayms>750</busydialogdelayms>
|
||||
</video>
|
||||
|
||||
<audio>
|
||||
<streamsilence>false</streamsilence>
|
||||
</audio>
|
||||
|
||||
<samba>
|
||||
<clienttimeout>30</clienttimeout>
|
||||
</samba>
|
||||
|
||||
<network>
|
||||
<readbufferfactor>4.0</readbufferfactor>
|
||||
</network>
|
||||
|
||||
</advancedsettings>
|
Loading…
x
Reference in New Issue
Block a user