remove project 'Cuboxi' for OpenELEC-4.2

Signed-off-by: Stephan Raue <stephan@openelec.tv>
This commit is contained in:
Stephan Raue 2014-06-12 20:37:54 +02:00
parent 91c6fab179
commit 876ca6a481
50 changed files with 0 additions and 61607 deletions

View File

@ -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

View File

@ -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"

View File

@ -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

View File

@ -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

View File

@ -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, &param, 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(&current->mm->mmap_sem);
ret = qib_user_sdma_queue_pkts(dd, pq, &list, iov, dim, mxp);
- up_write(&current->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

View File

@ -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(&regulator_list_mutex);
list_for_each_entry(rdev, &regulator_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;

View File

@ -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

View File

@ -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, &region);
}
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(&ltk->list);
kfree(ltk);
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -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);

View File

@ -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

View File

@ -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

View File

@ -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 },

View File

@ -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 */
{ }
};

View File

@ -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 {

View File

@ -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 */

View File

@ -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);

View File

@ -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;

View File

@ -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 = {

View File

@ -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 }
};

View File

@ -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);

View File

@ -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

View File

@ -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

View File

@ -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);
}

View File

@ -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
}

View File

@ -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) },
{ }

View File

@ -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:

View File

@ -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

View File

@ -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) },

View File

@ -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 */

View File

@ -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

View File

@ -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 {

View File

@ -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";
};

View File

@ -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>;
};

View File

@ -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 {

View File

@ -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

View File

@ -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

View File

@ -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 " \

View File

@ -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>