Compare commits
123 Commits
master
...
f14-user-l
Author | SHA1 | Date |
---|---|---|
Lubomir Rintel | 26a6cc5806 | |
Lubomir Rintel | fc131445da | |
Ben Skeggs | 383a70142a | |
Ben Skeggs | c7b0072805 | |
Ben Skeggs | df57a85a75 | |
Jarod Wilson | 030d3b3b4b | |
Chuck Ebbert | 643d353feb | |
Kyle McMartin | cbdb312a9e | |
Kyle McMartin | 8311d5168d | |
Jarod Wilson | 61d7a69fe6 | |
Jarod Wilson | 59a83bd584 | |
Kyle McMartin | c4e830cb35 | |
Kyle McMartin | e38a760c9a | |
Kyle McMartin | f1b58c7ca8 | |
Kyle McMartin | a1b8c4ed84 | |
Kyle McMartin | 6268215f01 | |
Kyle McMartin | 6aca938822 | |
kyle | c76455ec66 | |
kyle | 915df7f6de | |
Kyle McMartin | 7d350a94ee | |
Kyle McMartin | 9ee136bcf7 | |
Kyle McMartin | 97e19f7196 | |
Peter Jones | 7810142e6c | |
Dave Jones | c13cbf3b7d | |
Kyle McMartin | c19187e334 | |
Kyle McMartin | a2d889c53a | |
Kyle McMartin | 7140c9dd2d | |
Jarod Wilson | 167ee12e60 | |
Jarod Wilson | 870acad08e | |
Jarod Wilson | 866bf4f059 | |
Ben Skeggs | bd31d54eac | |
Kyle McMartin | f7f1f5ef4a | |
Dave Jones | a09b817bc1 | |
Kyle McMartin | 2fe1e8e397 | |
Kyle McMartin | eaab8be2d4 | |
Kyle McMartin | bc9e072d9b | |
Ben Skeggs | 2e4b75da82 | |
Dave Jones | db140fac23 | |
Ben Skeggs | 7043d42b5a | |
Dave Jones | 452369b936 | |
Dave Jones | 8f3d6a8c3f | |
Dave Jones | fbce23b0ff | |
Dave Jones | bbaea70ee5 | |
Dave Jones | 04093b926b | |
Chuck Ebbert | 4141bfc9b1 | |
Kyle McMartin | 05f615c82e | |
Chuck Ebbert | b999dfdb6a | |
Chuck Ebbert | b49b116bb0 | |
Chuck Ebbert | eda054e8bd | |
Kyle McMartin | c2aa9135d2 | |
Kyle McMartin | 2348a607b7 | |
Kyle McMartin | b13dd03f62 | |
Kyle McMartin | 6289a5fca9 | |
Ben Skeggs | 31ce2e5e16 | |
Chuck Ebbert | b2398b3ef3 | |
Chuck Ebbert | 69a476baa9 | |
Kyle McMartin | 027325ab53 | |
Chuck Ebbert | b218718b2b | |
Chuck Ebbert | 7a68cb0b55 | |
Dennis Gilmore | 42589b1be2 | |
Dennis Gilmore | 6daeb4142a | |
Dennis Gilmore | c549b813ae | |
Hans de Goede | 7193965656 | |
Dave Jones | 291833d307 | |
Hans de Goede | cb6f3ab735 | |
Chuck Ebbert | db056c27c3 | |
Chuck Ebbert | 14525abb6d | |
Kyle McMartin | a1b0ec05b6 | |
Chuck Ebbert | 9bd241a830 | |
Ben Skeggs | 4badda4370 | |
Jarod Wilson | 17a76a95c4 | |
Bastien Nocera | 9ea075ebba | |
Bastien Nocera | ea6d873cc2 | |
Kyle McMartin | 88a50a0b1d | |
Kyle McMartin | 102e2d6718 | |
Chuck Ebbert | 63fcde2459 | |
Ben Skeggs | fbc4283e12 | |
Kyle McMartin | 3ceeb77a79 | |
Kyle McMartin | 72b3bf972e | |
Ben Skeggs | 0fe99e9810 | |
Ben Skeggs | 215a71b03d | |
Dave Jones | 2eba9aa0ec | |
Jarod Wilson | f4da561c3d | |
Kyle McMartin | 8b695bdd15 | |
Kyle McMartin | 426c30b2f1 | |
Kyle McMartin | cfdae029cc | |
Jarod Wilson | 8ccfe4ce6a | |
Ben Skeggs | 1001ab34f7 | |
Kyle McMartin | d3a72eaedc | |
Chuck Ebbert | 44c4f071d9 | |
Dave Jones | 7def7eaed3 | |
Dave Jones | 35cc504508 | |
Dave Jones | 705539efb5 | |
Dave Jones | c348adbe39 | |
Chuck Ebbert | 0c8a5559c3 | |
Kyle McMartin | 3c5d4de07c | |
Dave Jones | 90303f9462 | |
Dave Jones | 10931f1112 | |
Chuck Ebbert | 27e8302707 | |
Chuck Ebbert | 8f132e348c | |
Chuck Ebbert | b30c150da1 | |
Chuck Ebbert | 3e8e94e0cd | |
Chuck Ebbert | 74e18cdf9e | |
Dave Jones | 4135368fb0 | |
Chuck Ebbert | 13dcde2426 | |
Chuck Ebbert | bfc8e84a86 | |
Kyle McMartin | e2302e0109 | |
Kyle McMartin | 4cfceabb6c | |
Jarod Wilson | b9878dcfec | |
Chuck Ebbert | e1151597d5 | |
Chuck Ebbert | d6d51a1a42 | |
Chuck Ebbert | 4ed348073c | |
Ben Skeggs | 71e9b6763f | |
Chuck Ebbert | 74b9092d38 | |
Chuck Ebbert | 9a98a7ebe3 | |
Chuck Ebbert | 6c58ce89ec | |
Chuck Ebbert | 85a693ce78 | |
Dave Jones | 4326aa56d8 | |
Chuck Ebbert | 4d5b945030 | |
Chuck Ebbert | b6805461ca | |
Chuck Ebbert | 557b0fb7c4 | |
Dave Jones | f8200febc9 | |
Dave Jones | 37cd8b7c4c |
2
Makefile
2
Makefile
|
@ -88,6 +88,7 @@ debug:
|
|||
@perl -pi -e 's/# CONFIG_KDB_KEYBOARD is not set/CONFIG_KDB_KEYBOARD=y/' config-nodebug
|
||||
@perl -pi -e 's/# CONFIG_CPU_NOTIFIER_ERROR_INJECT is not set/CONFIG_CPU_NOTIFIER_ERROR_INJECT=m/' config-nodebug
|
||||
@perl -pi -e 's/# CONFIG_DEBUG_PER_CPU_MAPS is not set/CONFIG_DEBUG_PER_CPU_MAPS=y/' config-nodebug
|
||||
#@perl -pi -e 's/# CONFIG_PCI_DEFAULT_USE_CRS is not set/CONFIG_PCI_DEFAULT_USE_CRS=y/' config-nodebug
|
||||
|
||||
@# just in case we're going from extremedebug -> debug
|
||||
@perl -pi -e 's/CONFIG_DEBUG_PAGEALLOC=y/# CONFIG_DEBUG_PAGEALLOC is not set/' config-nodebug
|
||||
|
@ -156,6 +157,7 @@ release:
|
|||
#@perl -pi -e 's/CONFIG_KGDB_KDB=y/# CONFIG_KGDB_KDB is not set/' config-nodebug
|
||||
#@perl -pi -e 's/CONFIG_KDB_KEYBOARD=y/# CONFIG_KDB_KEYBOARD is not set/' config-nodebug
|
||||
@perl -pi -e 's/CONFIG_DEBUG_PER_CPU_MAPS=y/# CONFIG_DEBUG_PER_CPU_MAPS is not set/' config-nodebug
|
||||
#@perl -pi -e 's/CONFIG_PCI_DEFAULT_USE_CRS=y/# CONFIG_PCI_DEFAULT_USE_CRS is not set/' config-nodebug
|
||||
|
||||
@perl -pi -e 's/CONFIG_DEBUG_PAGEALLOC=y/# CONFIG_DEBUG_PAGEALLOC is not set/' config-debug
|
||||
@perl -pi -e 's/CONFIG_DEBUG_PAGEALLOC=y/# CONFIG_DEBUG_PAGEALLOC is not set/' config-nodebug
|
||||
|
|
|
@ -0,0 +1,702 @@
|
|||
From 46fadae732d825141f45bf2fbd6381451da26ad7 Mon Sep 17 00:00:00 2001
|
||||
From: Bastien Nocera <hadess@hadess.net>
|
||||
Date: Fri, 10 Sep 2010 16:40:46 +0100
|
||||
Subject: [PATCH] Input: add appleir USB driver
|
||||
|
||||
This driver was originally written by James McKenzie, updated by
|
||||
Greg Kroah-Hartman, further updated by myself, with suspend support
|
||||
added.
|
||||
|
||||
More recent versions of the IR receiver are also supported through
|
||||
a patch by Alex Karpenko. The patch also adds support for the 2nd
|
||||
and 5th generation of the controller, and the menu key on newer
|
||||
brushed metal remotes.
|
||||
|
||||
Tested on a MacbookAir1,1
|
||||
|
||||
Signed-off-by: Bastien Nocera <hadess@hadess.net>
|
||||
---
|
||||
Documentation/input/appleir.txt | 46 ++++
|
||||
drivers/hid/hid-apple.c | 4 -
|
||||
drivers/hid/hid-core.c | 7 +-
|
||||
drivers/hid/hid-ids.h | 5 +-
|
||||
drivers/input/misc/Kconfig | 13 +
|
||||
drivers/input/misc/Makefile | 1 +
|
||||
drivers/input/misc/appleir.c | 519 +++++++++++++++++++++++++++++++++++++++
|
||||
7 files changed, 588 insertions(+), 7 deletions(-)
|
||||
create mode 100644 Documentation/input/appleir.txt
|
||||
create mode 100644 drivers/input/misc/appleir.c
|
||||
|
||||
diff --git a/Documentation/input/appleir.txt b/Documentation/input/appleir.txt
|
||||
new file mode 100644
|
||||
index 0000000..db637fb
|
||||
--- /dev/null
|
||||
+++ b/Documentation/input/appleir.txt
|
||||
@@ -0,0 +1,46 @@
|
||||
+Apple IR receiver Driver (appleir)
|
||||
+----------------------------------
|
||||
+ Copyright (C) 2009 Bastien Nocera <hadess@hadess.net>
|
||||
+
|
||||
+The appleir driver is a kernel input driver to handle Apple's IR
|
||||
+receivers (and associated remotes) in the kernel.
|
||||
+
|
||||
+The driver is an input driver which only handles "official" remotes
|
||||
+as built and sold by Apple.
|
||||
+
|
||||
+Authors
|
||||
+-------
|
||||
+
|
||||
+James McKenzie (original driver)
|
||||
+Alex Karpenko (05ac:8242 support)
|
||||
+Greg Kroah-Hartman (cleanups and original submission)
|
||||
+Bastien Nocera (further cleanups, brushed metal "enter"
|
||||
+button support and suspend support)
|
||||
+
|
||||
+Supported hardware
|
||||
+------------------
|
||||
+
|
||||
+- All Apple laptops and desktops from 2005 onwards, except:
|
||||
+ - the unibody Macbook (2009)
|
||||
+ - Mac Pro (all versions)
|
||||
+- Apple TV (all revisions prior to September 2010)
|
||||
+
|
||||
+The remote will only support the 6 (old white) or 7 (brushed metal) buttons
|
||||
+of the remotes as sold by Apple. See the next section if you want to use
|
||||
+other remotes or want to use lirc with the device instead of the kernel driver.
|
||||
+
|
||||
+Using lirc (native) instead of the kernel driver
|
||||
+------------------------------------------------
|
||||
+
|
||||
+First, you will need to disable the kernel driver for the receiver.
|
||||
+
|
||||
+This can be achieved by passing quirks to the usbhid driver.
|
||||
+The quirk line would be:
|
||||
+usbhid.quirks=0x05ac:0x8242:0x40000010
|
||||
+
|
||||
+With 0x05ac being the vendor ID (Apple, you shouldn't need to change this)
|
||||
+With 0x8242 being the product ID (check the output of lsusb for your hardware)
|
||||
+And 0x10 being "HID_QUIRK_HIDDEV_FORCE" and 0x40000000 being "HID_QUIRK_NO_IGNORE"
|
||||
+
|
||||
+This should force the creation of a hiddev device for the receiver, and
|
||||
+make it usable under lirc.
|
||||
diff --git a/drivers/hid/hid-apple.c b/drivers/hid/hid-apple.c
|
||||
index bba05d0..0059d5a 100644
|
||||
--- a/drivers/hid/hid-apple.c
|
||||
+++ b/drivers/hid/hid-apple.c
|
||||
@@ -361,10 +361,6 @@ static void apple_remove(struct hid_device *hdev)
|
||||
}
|
||||
|
||||
static const struct hid_device_id apple_devices[] = {
|
||||
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ATV_IRCONTROL),
|
||||
- .driver_data = APPLE_HIDDEV | APPLE_IGNORE_HIDINPUT },
|
||||
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL4),
|
||||
- .driver_data = APPLE_HIDDEV | APPLE_IGNORE_HIDINPUT },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MIGHTYMOUSE),
|
||||
.driver_data = APPLE_MIGHTYMOUSE | APPLE_INVERT_HWHEEL },
|
||||
|
||||
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
|
||||
index 866e54e..1d5e284 100644
|
||||
--- a/drivers/hid/hid-core.c
|
||||
+++ b/drivers/hid/hid-core.c
|
||||
@@ -1239,8 +1239,6 @@ static const struct hid_device_id hid_blacklist[] = {
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_3M, USB_DEVICE_ID_3M2256) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_WCP32PU) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_X5_005D) },
|
||||
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ATV_IRCONTROL) },
|
||||
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL4) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MIGHTYMOUSE) },
|
||||
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGICMOUSE) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_ANSI) },
|
||||
@@ -1571,6 +1569,11 @@ static const struct hid_device_id hid_ignore_list[] = {
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_24) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_AIRCABLE, USB_DEVICE_ID_AIRCABLE1) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_ALCOR, USB_DEVICE_ID_ALCOR_USBRS232) },
|
||||
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL) },
|
||||
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL2) },
|
||||
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL3) },
|
||||
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL4) },
|
||||
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL5) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_ASUS, USB_DEVICE_ID_ASUS_T91MT)},
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK, USB_DEVICE_ID_ASUSTEK_LCM)},
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK, USB_DEVICE_ID_ASUSTEK_LCM2)},
|
||||
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
|
||||
index 31601ee..9afe3bc 100644
|
||||
--- a/drivers/hid/hid-ids.h
|
||||
+++ b/drivers/hid/hid-ids.h
|
||||
@@ -98,8 +98,11 @@
|
||||
#define USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_JIS 0x023b
|
||||
#define USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY 0x030a
|
||||
#define USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY 0x030b
|
||||
-#define USB_DEVICE_ID_APPLE_ATV_IRCONTROL 0x8241
|
||||
+#define USB_DEVICE_ID_APPLE_IRCONTROL 0x8240
|
||||
+#define USB_DEVICE_ID_APPLE_IRCONTROL2 0x1440
|
||||
+#define USB_DEVICE_ID_APPLE_IRCONTROL3 0x8241
|
||||
#define USB_DEVICE_ID_APPLE_IRCONTROL4 0x8242
|
||||
+#define USB_DEVICE_ID_APPLE_IRCONTROL5 0x8243
|
||||
|
||||
#define USB_VENDOR_ID_ASUS 0x0486
|
||||
#define USB_DEVICE_ID_ASUS_T91MT 0x0185
|
||||
diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig
|
||||
index c44b9ea..76a12b7 100644
|
||||
--- a/drivers/input/misc/Kconfig
|
||||
+++ b/drivers/input/misc/Kconfig
|
||||
@@ -199,6 +199,19 @@ config INPUT_KEYSPAN_REMOTE
|
||||
To compile this driver as a module, choose M here: the module will
|
||||
be called keyspan_remote.
|
||||
|
||||
+config INPUT_APPLEIR
|
||||
+ tristate "Apple infrared receiver (built in)"
|
||||
+ depends on USB_ARCH_HAS_HCD
|
||||
+ select USB
|
||||
+ help
|
||||
+ Say Y here if you want to use a Apple infrared remote control. All
|
||||
+ the Apple computers from 2005 onwards include such a port, except
|
||||
+ the unibody Macbook (2009), and Mac Pros. This receiver is also
|
||||
+ used in the Apple TV set-top box prior to the 2010 model.
|
||||
+
|
||||
+ To compile this driver as a module, choose M here: the module will
|
||||
+ be called appleir.
|
||||
+
|
||||
config INPUT_POWERMATE
|
||||
tristate "Griffin PowerMate and Contour Jog support"
|
||||
depends on USB_ARCH_HAS_HCD
|
||||
diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile
|
||||
index 71fe57d..62a5c60 100644
|
||||
--- a/drivers/input/misc/Makefile
|
||||
+++ b/drivers/input/misc/Makefile
|
||||
@@ -9,6 +9,7 @@ obj-$(CONFIG_INPUT_AD714X) += ad714x.o
|
||||
obj-$(CONFIG_INPUT_AD714X_I2C) += ad714x-i2c.o
|
||||
obj-$(CONFIG_INPUT_AD714X_SPI) += ad714x-spi.o
|
||||
obj-$(CONFIG_INPUT_APANEL) += apanel.o
|
||||
+obj-$(CONFIG_INPUT_APPLEIR) += appleir.o
|
||||
obj-$(CONFIG_INPUT_ATI_REMOTE) += ati_remote.o
|
||||
obj-$(CONFIG_INPUT_ATI_REMOTE2) += ati_remote2.o
|
||||
obj-$(CONFIG_INPUT_ATLAS_BTNS) += atlas_btns.o
|
||||
diff --git a/drivers/input/misc/appleir.c b/drivers/input/misc/appleir.c
|
||||
new file mode 100644
|
||||
index 0000000..3817a3c
|
||||
--- /dev/null
|
||||
+++ b/drivers/input/misc/appleir.c
|
||||
@@ -0,0 +1,519 @@
|
||||
+/*
|
||||
+ * appleir: USB driver for the apple ir device
|
||||
+ *
|
||||
+ * Original driver written by James McKenzie
|
||||
+ * Ported to recent 2.6 kernel versions by Greg Kroah-Hartman <gregkh@suse.de>
|
||||
+ *
|
||||
+ * Copyright (C) 2006 James McKenzie
|
||||
+ * Copyright (C) 2008 Greg Kroah-Hartman <greg@kroah.com>
|
||||
+ * Copyright (C) 2008 Novell Inc.
|
||||
+ *
|
||||
+ * 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, version 2.
|
||||
+ *
|
||||
+ */
|
||||
+
|
||||
+#include <linux/kernel.h>
|
||||
+#include <linux/slab.h>
|
||||
+#include <linux/input.h>
|
||||
+#include <linux/usb/input.h>
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/init.h>
|
||||
+#include <linux/usb.h>
|
||||
+#include <linux/usb/input.h>
|
||||
+#include <asm/unaligned.h>
|
||||
+#include <asm/byteorder.h>
|
||||
+
|
||||
+#define DRIVER_VERSION "v1.2"
|
||||
+#define DRIVER_AUTHOR "James McKenzie"
|
||||
+#define DRIVER_DESC "Apple infrared receiver driver"
|
||||
+#define DRIVER_LICENSE "GPL"
|
||||
+
|
||||
+MODULE_AUTHOR(DRIVER_AUTHOR);
|
||||
+MODULE_DESCRIPTION(DRIVER_DESC);
|
||||
+MODULE_LICENSE(DRIVER_LICENSE);
|
||||
+
|
||||
+#define USB_VENDOR_ID_APPLE 0x05ac
|
||||
+#define USB_DEVICE_ID_APPLE_IRCONTROL 0x8240
|
||||
+#define USB_DEVICE_ID_APPLE_IRCONTROL2 0x1440
|
||||
+#define USB_DEVICE_ID_APPLE_IRCONTROL3 0x8241
|
||||
+#define USB_DEVICE_ID_APPLE_IRCONTROL4 0x8242
|
||||
+#define USB_DEVICE_ID_APPLE_IRCONTROL5 0x8243
|
||||
+
|
||||
+#define URB_SIZE 32
|
||||
+
|
||||
+#define MAX_KEYS 9
|
||||
+#define MAX_KEYS_MASK (MAX_KEYS - 1)
|
||||
+
|
||||
+#define dbginfo(dev, format, arg...) do { if (debug) dev_info(dev , format , ## arg); } while (0)
|
||||
+
|
||||
+static int debug;
|
||||
+module_param(debug, int, 0644);
|
||||
+MODULE_PARM_DESC(debug, "Enable extra debug messages and information");
|
||||
+
|
||||
+/* I have two devices both of which report the following */
|
||||
+/* 25 87 ee 83 0a + */
|
||||
+/* 25 87 ee 83 0c - */
|
||||
+/* 25 87 ee 83 09 << */
|
||||
+/* 25 87 ee 83 06 >> */
|
||||
+/* 25 87 ee 83 05 >" */
|
||||
+/* 25 87 ee 83 03 menu */
|
||||
+/* 26 00 00 00 00 for key repeat*/
|
||||
+
|
||||
+/* Thomas Glanzmann reports the following responses */
|
||||
+/* 25 87 ee ca 0b + */
|
||||
+/* 25 87 ee ca 0d - */
|
||||
+/* 25 87 ee ca 08 << */
|
||||
+/* 25 87 ee ca 07 >> */
|
||||
+/* 25 87 ee ca 04 >" */
|
||||
+/* 25 87 ee ca 02 menu */
|
||||
+/* 26 00 00 00 00 for key repeat*/
|
||||
+/* He also observes the following event sometimes */
|
||||
+/* sent after a key is release, which I interpret */
|
||||
+/* as a flat battery message */
|
||||
+/* 25 87 e0 ca 06 flat battery */
|
||||
+
|
||||
+/* Alexandre Karpenko reports the following responses for Device ID 0x8242 */
|
||||
+/* 25 87 ee 47 0b + */
|
||||
+/* 25 87 ee 47 0d - */
|
||||
+/* 25 87 ee 47 08 << */
|
||||
+/* 25 87 ee 47 07 >> */
|
||||
+/* 25 87 ee 47 04 >" */
|
||||
+/* 25 87 ee 47 02 menu */
|
||||
+/* 26 87 ee 47 ** for key repeat (** is the code of the key being held) */
|
||||
+
|
||||
+/* Bastien Nocera's "new" remote */
|
||||
+/* 25 87 ee 91 5f followed by
|
||||
+ * 25 87 ee 91 05 gives you >"
|
||||
+ *
|
||||
+ * 25 87 ee 91 5c followed by
|
||||
+ * 25 87 ee 91 05 gives you the middle button */
|
||||
+
|
||||
+static const unsigned short appleir_key_table[] = {
|
||||
+ KEY_RESERVED,
|
||||
+ KEY_MENU,
|
||||
+ KEY_PLAYPAUSE,
|
||||
+ KEY_FORWARD,
|
||||
+ KEY_BACK,
|
||||
+ KEY_VOLUMEUP,
|
||||
+ KEY_VOLUMEDOWN,
|
||||
+ KEY_ENTER,
|
||||
+ KEY_RESERVED,
|
||||
+};
|
||||
+
|
||||
+struct appleir {
|
||||
+ struct input_dev *input_dev;
|
||||
+ unsigned short keymap[ARRAY_SIZE(appleir_key_table)];
|
||||
+ u8 *data;
|
||||
+ dma_addr_t dma_buf;
|
||||
+ struct usb_device *usbdev;
|
||||
+ unsigned int flags;
|
||||
+ struct urb *urb;
|
||||
+ struct timer_list key_up_timer;
|
||||
+ int current_key;
|
||||
+ int prev_key_idx;
|
||||
+ char phys[32];
|
||||
+};
|
||||
+
|
||||
+static DEFINE_MUTEX(appleir_mutex);
|
||||
+
|
||||
+enum {
|
||||
+ APPLEIR_OPENED = 0x1,
|
||||
+ APPLEIR_SUSPENDED = 0x2,
|
||||
+};
|
||||
+
|
||||
+static struct usb_device_id appleir_ids[] = {
|
||||
+ { USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL) },
|
||||
+ { USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL2) },
|
||||
+ { USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL3) },
|
||||
+ { USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL4) },
|
||||
+ { USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL5) },
|
||||
+ {}
|
||||
+};
|
||||
+MODULE_DEVICE_TABLE(usb, appleir_ids);
|
||||
+
|
||||
+static void dump_packet(struct appleir *appleir, char *msg, u8 *data, int len)
|
||||
+{
|
||||
+ int i;
|
||||
+
|
||||
+ printk(KERN_ERR "appleir: %s (%d bytes)", msg, len);
|
||||
+
|
||||
+ for (i = 0; i < len; ++i)
|
||||
+ printk(" %02x", data[i]);
|
||||
+ printk(" (should be command %d)\n", (data[4] >> 1) & MAX_KEYS_MASK);
|
||||
+}
|
||||
+
|
||||
+static int get_key(int data)
|
||||
+{
|
||||
+ switch (data) {
|
||||
+ case 0x02:
|
||||
+ case 0x03:
|
||||
+ /* menu */
|
||||
+ return 1;
|
||||
+ case 0x04:
|
||||
+ case 0x05:
|
||||
+ /* >" */
|
||||
+ return 2;
|
||||
+ case 0x06:
|
||||
+ case 0x07:
|
||||
+ /* >> */
|
||||
+ return 3;
|
||||
+ case 0x08:
|
||||
+ case 0x09:
|
||||
+ /* << */
|
||||
+ return 4;
|
||||
+ case 0x0a:
|
||||
+ case 0x0b:
|
||||
+ /* + */
|
||||
+ return 5;
|
||||
+ case 0x0c:
|
||||
+ case 0x0d:
|
||||
+ /* - */
|
||||
+ return 6;
|
||||
+ case 0x5c:
|
||||
+ /* Middle button, on newer remotes,
|
||||
+ * part of a 2 packet-command */
|
||||
+ return -7;
|
||||
+ default:
|
||||
+ return -1;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void key_up(struct appleir *appleir, int key)
|
||||
+{
|
||||
+ dbginfo(&appleir->input_dev->dev, "key %d up\n", key);
|
||||
+ input_report_key(appleir->input_dev, key, 0);
|
||||
+ input_sync(appleir->input_dev);
|
||||
+}
|
||||
+
|
||||
+static void key_down(struct appleir *appleir, int key)
|
||||
+{
|
||||
+ dbginfo(&appleir->input_dev->dev, "key %d down\n", key);
|
||||
+ input_report_key(appleir->input_dev, key, 1);
|
||||
+ input_sync(appleir->input_dev);
|
||||
+}
|
||||
+
|
||||
+static void battery_flat(struct appleir *appleir)
|
||||
+{
|
||||
+ dev_err(&appleir->input_dev->dev, "possible flat battery?\n");
|
||||
+}
|
||||
+
|
||||
+static void key_up_tick(unsigned long data)
|
||||
+{
|
||||
+ struct appleir *appleir = (struct appleir *)data;
|
||||
+
|
||||
+ if (appleir->current_key) {
|
||||
+ key_up(appleir, appleir->current_key);
|
||||
+ appleir->current_key = 0;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void new_data(struct appleir *appleir, u8 *data, int len)
|
||||
+{
|
||||
+ static const u8 keydown[] = { 0x25, 0x87, 0xee };
|
||||
+ static const u8 keyrepeat[] = { 0x26, };
|
||||
+ static const u8 flatbattery[] = { 0x25, 0x87, 0xe0 };
|
||||
+
|
||||
+ if (debug)
|
||||
+ dump_packet(appleir, "received", data, len);
|
||||
+
|
||||
+ if (len != 5)
|
||||
+ return;
|
||||
+
|
||||
+ if (!memcmp(data, keydown, sizeof(keydown))) {
|
||||
+ int index;
|
||||
+
|
||||
+ /* If we already have a key down, take it up before marking
|
||||
+ this one down */
|
||||
+ if (appleir->current_key)
|
||||
+ key_up(appleir, appleir->current_key);
|
||||
+
|
||||
+ /* Handle dual packet commands */
|
||||
+ if (appleir->prev_key_idx > 0)
|
||||
+ index = appleir->prev_key_idx;
|
||||
+ else
|
||||
+ index = get_key(data[4]);
|
||||
+
|
||||
+ if (index > 0) {
|
||||
+ appleir->current_key = appleir->keymap[index];
|
||||
+
|
||||
+ key_down(appleir, appleir->current_key);
|
||||
+ /* Remote doesn't do key up, either pull them up, in the test
|
||||
+ above, or here set a timer which pulls them up after 1/8 s */
|
||||
+ mod_timer(&appleir->key_up_timer, jiffies + HZ / 8);
|
||||
+ appleir->prev_key_idx = 0;
|
||||
+ return;
|
||||
+ } else if (index == -7) {
|
||||
+ /* Remember key for next packet */
|
||||
+ appleir->prev_key_idx = 0 - index;
|
||||
+ return;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ appleir->prev_key_idx = 0;
|
||||
+
|
||||
+ if (!memcmp(data, keyrepeat, sizeof(keyrepeat))) {
|
||||
+ key_down(appleir, appleir->current_key);
|
||||
+ /* Remote doesn't do key up, either pull them up, in the test
|
||||
+ above, or here set a timer which pulls them up after 1/8 s */
|
||||
+ mod_timer(&appleir->key_up_timer, jiffies + HZ / 8);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ if (!memcmp(data, flatbattery, sizeof(flatbattery))) {
|
||||
+ battery_flat(appleir);
|
||||
+ /* Fall through */
|
||||
+ }
|
||||
+
|
||||
+ dump_packet(appleir, "unknown packet", data, len);
|
||||
+}
|
||||
+
|
||||
+static void appleir_urb(struct urb *urb)
|
||||
+{
|
||||
+ struct appleir *appleir = urb->context;
|
||||
+ int status = urb->status;
|
||||
+ int retval;
|
||||
+
|
||||
+ switch (status) {
|
||||
+ case 0:
|
||||
+ new_data(appleir, urb->transfer_buffer, urb->actual_length);
|
||||
+ break;
|
||||
+ case -ECONNRESET:
|
||||
+ case -ENOENT:
|
||||
+ case -ESHUTDOWN:
|
||||
+ /* This urb is terminated, clean up */
|
||||
+ dbginfo(&appleir->input_dev->dev, "%s - urb shutting down with status: %d", __func__,
|
||||
+ urb->status);
|
||||
+ return;
|
||||
+ default:
|
||||
+ dbginfo(&appleir->input_dev->dev, "%s - nonzero urb status received: %d", __func__,
|
||||
+ urb->status);
|
||||
+ }
|
||||
+
|
||||
+ retval = usb_submit_urb(urb, GFP_ATOMIC);
|
||||
+ if (retval)
|
||||
+ err("%s - usb_submit_urb failed with result %d", __func__,
|
||||
+ retval);
|
||||
+}
|
||||
+
|
||||
+static int appleir_open(struct input_dev *dev)
|
||||
+{
|
||||
+ struct appleir *appleir = input_get_drvdata(dev);
|
||||
+ struct usb_interface *intf = usb_ifnum_to_if(appleir->usbdev, 0);
|
||||
+ int r;
|
||||
+
|
||||
+ r = usb_autopm_get_interface(intf);
|
||||
+ if (r) {
|
||||
+ dev_err(&intf->dev,
|
||||
+ "%s(): usb_autopm_get_interface() = %d\n", __func__, r);
|
||||
+ return r;
|
||||
+ }
|
||||
+
|
||||
+ mutex_lock(&appleir_mutex);
|
||||
+
|
||||
+ if (usb_submit_urb(appleir->urb, GFP_ATOMIC)) {
|
||||
+ r = -EIO;
|
||||
+ goto fail;
|
||||
+ }
|
||||
+
|
||||
+ appleir->flags |= APPLEIR_OPENED;
|
||||
+
|
||||
+ mutex_unlock(&appleir_mutex);
|
||||
+
|
||||
+ usb_autopm_put_interface(intf);
|
||||
+
|
||||
+ return 0;
|
||||
+fail:
|
||||
+ mutex_unlock(&appleir_mutex);
|
||||
+ usb_autopm_put_interface(intf);
|
||||
+ return r;
|
||||
+}
|
||||
+
|
||||
+static void appleir_close(struct input_dev *dev)
|
||||
+{
|
||||
+ struct appleir *appleir = input_get_drvdata(dev);
|
||||
+
|
||||
+ mutex_lock(&appleir_mutex);
|
||||
+
|
||||
+ if (!(appleir->flags & APPLEIR_SUSPENDED)) {
|
||||
+ usb_kill_urb(appleir->urb);
|
||||
+ del_timer_sync(&appleir->key_up_timer);
|
||||
+ }
|
||||
+
|
||||
+ appleir->flags &= ~APPLEIR_OPENED;
|
||||
+
|
||||
+ mutex_unlock(&appleir_mutex);
|
||||
+}
|
||||
+
|
||||
+static int appleir_probe(struct usb_interface *intf,
|
||||
+ const struct usb_device_id *id)
|
||||
+{
|
||||
+ struct usb_device *dev = interface_to_usbdev(intf);
|
||||
+ struct usb_endpoint_descriptor *endpoint;
|
||||
+ struct appleir *appleir = NULL;
|
||||
+ struct input_dev *input_dev;
|
||||
+ int retval = -ENOMEM;
|
||||
+ int i;
|
||||
+
|
||||
+ appleir = kzalloc(sizeof(struct appleir), GFP_KERNEL);
|
||||
+ if (!appleir)
|
||||
+ goto allocfail;
|
||||
+
|
||||
+ appleir->data = usb_alloc_coherent(dev, URB_SIZE, GFP_KERNEL,
|
||||
+ &appleir->dma_buf);
|
||||
+ if (!appleir->data)
|
||||
+ goto usbfail;
|
||||
+
|
||||
+ appleir->urb = usb_alloc_urb(0, GFP_KERNEL);
|
||||
+ if (!appleir->urb)
|
||||
+ goto urbfail;
|
||||
+
|
||||
+ appleir->usbdev = dev;
|
||||
+
|
||||
+ input_dev = input_allocate_device();
|
||||
+ if (!input_dev)
|
||||
+ goto inputfail;
|
||||
+
|
||||
+ appleir->input_dev = input_dev;
|
||||
+
|
||||
+ usb_make_path(dev, appleir->phys, sizeof(appleir->phys));
|
||||
+ strlcpy(appleir->phys, "/input0", sizeof(appleir->phys));
|
||||
+
|
||||
+ input_dev->name = "Apple Infrared Remote Controller";
|
||||
+ input_dev->phys = appleir->phys;
|
||||
+ usb_to_input_id(dev, &input_dev->id);
|
||||
+ input_dev->dev.parent = &intf->dev;
|
||||
+ input_dev->keycode = appleir->keymap;
|
||||
+ input_dev->keycodesize = sizeof(unsigned short);
|
||||
+ input_dev->keycodemax = ARRAY_SIZE(appleir->keymap);
|
||||
+
|
||||
+ input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
|
||||
+
|
||||
+ memcpy(appleir->keymap, appleir_key_table, sizeof(appleir->keymap));
|
||||
+ for (i = 0; i < ARRAY_SIZE(appleir_key_table); i++)
|
||||
+ set_bit(appleir->keymap[i], input_dev->keybit);
|
||||
+ clear_bit(KEY_RESERVED, input_dev->keybit);
|
||||
+
|
||||
+ input_set_drvdata(input_dev, appleir);
|
||||
+ input_dev->open = appleir_open;
|
||||
+ input_dev->close = appleir_close;
|
||||
+
|
||||
+ endpoint = &intf->cur_altsetting->endpoint[0].desc;
|
||||
+
|
||||
+ usb_fill_int_urb(appleir->urb, dev,
|
||||
+ usb_rcvintpipe(dev, endpoint->bEndpointAddress),
|
||||
+ appleir->data, 8,
|
||||
+ appleir_urb, appleir, endpoint->bInterval);
|
||||
+
|
||||
+ appleir->urb->transfer_dma = appleir->dma_buf;
|
||||
+ appleir->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
|
||||
+
|
||||
+ setup_timer(&appleir->key_up_timer,
|
||||
+ key_up_tick, (unsigned long) appleir);
|
||||
+
|
||||
+ retval = input_register_device(appleir->input_dev);
|
||||
+ if (retval)
|
||||
+ goto inputfail;
|
||||
+
|
||||
+ usb_set_intfdata(intf, appleir);
|
||||
+
|
||||
+ return 0;
|
||||
+
|
||||
+inputfail:
|
||||
+ input_free_device(appleir->input_dev);
|
||||
+
|
||||
+urbfail:
|
||||
+ usb_free_urb(appleir->urb);
|
||||
+
|
||||
+usbfail:
|
||||
+ usb_free_coherent(dev, URB_SIZE, appleir->data,
|
||||
+ appleir->dma_buf);
|
||||
+
|
||||
+allocfail:
|
||||
+ kfree(appleir);
|
||||
+
|
||||
+ return retval;
|
||||
+}
|
||||
+
|
||||
+static void appleir_disconnect(struct usb_interface *intf)
|
||||
+{
|
||||
+ struct appleir *appleir = usb_get_intfdata(intf);
|
||||
+
|
||||
+ usb_set_intfdata(intf, NULL);
|
||||
+ input_unregister_device(appleir->input_dev);
|
||||
+ usb_free_urb(appleir->urb);
|
||||
+ usb_free_coherent(interface_to_usbdev(intf), URB_SIZE,
|
||||
+ appleir->data, appleir->dma_buf);
|
||||
+ kfree(appleir);
|
||||
+}
|
||||
+
|
||||
+static int appleir_suspend(struct usb_interface *interface,
|
||||
+ pm_message_t message)
|
||||
+{
|
||||
+ struct appleir *appleir = usb_get_intfdata(interface);
|
||||
+
|
||||
+ mutex_lock(&appleir_mutex);
|
||||
+ if (appleir->flags & APPLEIR_OPENED)
|
||||
+ usb_kill_urb(appleir->urb);
|
||||
+
|
||||
+ appleir->flags |= APPLEIR_SUSPENDED;
|
||||
+
|
||||
+ mutex_unlock(&appleir_mutex);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int appleir_resume(struct usb_interface *interface)
|
||||
+{
|
||||
+ struct appleir *appleir;
|
||||
+ int r = 0;
|
||||
+
|
||||
+ appleir = usb_get_intfdata(interface);
|
||||
+
|
||||
+ mutex_lock(&appleir_mutex);
|
||||
+ if (appleir->flags & APPLEIR_OPENED) {
|
||||
+ struct usb_endpoint_descriptor *endpoint;
|
||||
+
|
||||
+ endpoint = &interface->cur_altsetting->endpoint[0].desc;
|
||||
+ usb_fill_int_urb(appleir->urb, appleir->usbdev,
|
||||
+ usb_rcvintpipe(appleir->usbdev, endpoint->bEndpointAddress),
|
||||
+ appleir->data, 8,
|
||||
+ appleir_urb, appleir, endpoint->bInterval);
|
||||
+ appleir->urb->transfer_dma = appleir->dma_buf;
|
||||
+ appleir->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
|
||||
+
|
||||
+ /* And reset the USB device */
|
||||
+ if (usb_submit_urb(appleir->urb, GFP_ATOMIC))
|
||||
+ r = -EIO;
|
||||
+ }
|
||||
+
|
||||
+ appleir->flags &= ~APPLEIR_SUSPENDED;
|
||||
+
|
||||
+ mutex_unlock(&appleir_mutex);
|
||||
+
|
||||
+ return r;
|
||||
+}
|
||||
+
|
||||
+static struct usb_driver appleir_driver = {
|
||||
+ .name = "appleir",
|
||||
+ .probe = appleir_probe,
|
||||
+ .disconnect = appleir_disconnect,
|
||||
+ .suspend = appleir_suspend,
|
||||
+ .resume = appleir_resume,
|
||||
+ .reset_resume = appleir_resume,
|
||||
+ .id_table = appleir_ids,
|
||||
+};
|
||||
+
|
||||
+static int __init appleir_init(void)
|
||||
+{
|
||||
+ return usb_register(&appleir_driver);
|
||||
+}
|
||||
+
|
||||
+static void __exit appleir_exit(void)
|
||||
+{
|
||||
+ usb_deregister(&appleir_driver);
|
||||
+}
|
||||
+
|
||||
+module_init(appleir_init);
|
||||
+module_exit(appleir_exit);
|
||||
--
|
||||
1.7.2.2
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
From kernel-bounces@lists.fedoraproject.org Fri Sep 17 17:09:15 2010
|
||||
From: Will Woods <wwoods@redhat.com>
|
||||
To: Marcel Holtmann <marcel@holtmann.org>
|
||||
Subject: [PATCH 2/2] bluetooth: add support for controller in MacBookPro6,2
|
||||
Date: Fri, 17 Sep 2010 17:09:21 -0400
|
||||
|
||||
Once again the device class is ff(vend.) instead of e0(wlcon).
|
||||
|
||||
output from 'usb-devices':
|
||||
T: Bus=01 Lev=03 Prnt=03 Port=02 Cnt=03 Dev#= 8 Spd=12 MxCh= 0
|
||||
D: Ver= 2.00 Cls=ff(vend.) Sub=01 Prot=01 MxPS=64 #Cfgs= 1
|
||||
P: Vendor=05ac ProdID=8218 Rev=00.22
|
||||
S: Manufacturer=Apple Inc.
|
||||
S: Product=Bluetooth USB Host Controller
|
||||
C: #Ifs= 4 Cfg#= 1 Atr=e0 MxPwr=0mA
|
||||
I: If#= 0 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=01 Prot=01 Driver=(none)
|
||||
I: If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=(none)
|
||||
I: If#= 2 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=ff Driver=(none)
|
||||
I: If#= 3 Alt= 0 #EPs= 0 Cls=fe(app. ) Sub=01 Prot=01 Driver=(none)
|
||||
|
||||
Signed-off-by: Will Woods <wwoods@redhat.com>
|
||||
---
|
||||
drivers/bluetooth/btusb.c | 3 +++
|
||||
1 files changed, 3 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
|
||||
index eac44e4..320e798 100644
|
||||
--- a/drivers/bluetooth/btusb.c
|
||||
+++ b/drivers/bluetooth/btusb.c
|
||||
@@ -65,6 +65,9 @@ static struct usb_device_id btusb_table[] = {
|
||||
/* Apple iMac11,1 */
|
||||
{ USB_DEVICE(0x05ac, 0x8215) },
|
||||
|
||||
+ /* Apple MacBookPro6,2 */
|
||||
+ { USB_DEVICE(0x05ac, 0x8218) },
|
||||
+
|
||||
/* AVM BlueFRITZ! USB v2.0 */
|
||||
{ USB_DEVICE(0x057c, 0x3800) },
|
||||
|
||||
--
|
||||
1.7.2.3
|
|
@ -0,0 +1,42 @@
|
|||
From kernel-bounces@lists.fedoraproject.org Fri Sep 17 17:09:18 2010
|
||||
From: Will Woods <wwoods@redhat.com>
|
||||
To: Marcel Holtmann <marcel@holtmann.org>
|
||||
Subject: [PATCH 1/2] bluetooth: add support for controller in MacBookPro7,1
|
||||
Date: Fri, 17 Sep 2010 17:09:20 -0400
|
||||
|
||||
As with iMac11,1 the device class is ff(vend.) instead of e0(wlcon).
|
||||
|
||||
output from 'usb-devices':
|
||||
T: Bus=04 Lev=02 Prnt=04 Port=00 Cnt=01 Dev#= 5 Spd=12 MxCh= 0
|
||||
D: Ver= 2.00 Cls=ff(vend.) Sub=01 Prot=01 MxPS=64 #Cfgs= 1
|
||||
P: Vendor=05ac ProdID=8213 Rev=01.86
|
||||
S: Manufacturer=Apple Inc.
|
||||
S: Product=Bluetooth USB Host Controller
|
||||
S: SerialNumber=58B0359C28ED
|
||||
C: #Ifs= 4 Cfg#= 1 Atr=e0 MxPwr=0mA
|
||||
I: If#= 0 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=01 Prot=01 Driver=btusb
|
||||
I: If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
|
||||
I: If#= 2 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=ff Driver=(none)
|
||||
I: If#= 3 Alt= 0 #EPs= 0 Cls=fe(app. ) Sub=01 Prot=00 Driver=(none)
|
||||
|
||||
Signed-off-by: Will Woods <wwoods@redhat.com>
|
||||
---
|
||||
drivers/bluetooth/btusb.c | 3 +++
|
||||
1 files changed, 3 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
|
||||
index d22ce3c..eac44e4 100644
|
||||
--- a/drivers/bluetooth/btusb.c
|
||||
+++ b/drivers/bluetooth/btusb.c
|
||||
@@ -59,6 +59,9 @@ static struct usb_device_id btusb_table[] = {
|
||||
/* Generic Bluetooth USB device */
|
||||
{ USB_DEVICE_INFO(0xe0, 0x01, 0x01) },
|
||||
|
||||
+ /* Apple MacBookPro7,1 */
|
||||
+ { USB_DEVICE(0x05ac, 0x8213) },
|
||||
+
|
||||
/* Apple iMac11,1 */
|
||||
{ USB_DEVICE(0x05ac, 0x8215) },
|
||||
|
||||
--
|
||||
1.7.2.3
|
|
@ -87,5 +87,7 @@ CONFIG_PM_ADVANCED_DEBUG=y
|
|||
CONFIG_CEPH_FS_PRETTYDEBUG=y
|
||||
CONFIG_QUOTA_DEBUG=y
|
||||
|
||||
# CONFIG_PCI_DEFAULT_USE_CRS is not set
|
||||
|
||||
CONFIG_KGDB_KDB=y
|
||||
CONFIG_KDB_KEYBOARD=y
|
||||
|
|
|
@ -684,7 +684,7 @@ CONFIG_MD_RAID0=m
|
|||
CONFIG_MD_RAID1=m
|
||||
CONFIG_MD_RAID10=m
|
||||
CONFIG_MD_RAID456=m
|
||||
CONFIG_MULTICORE_RAID456=y
|
||||
# CONFIG_MULTICORE_RAID456 is not set
|
||||
CONFIG_ASYNC_RAID6_TEST=m
|
||||
CONFIG_BLK_DEV_DM=y
|
||||
CONFIG_DM_CRYPT=m
|
||||
|
@ -1423,11 +1423,11 @@ CONFIG_ATMEL=m
|
|||
CONFIG_B43=m
|
||||
CONFIG_B43_PCMCIA=y
|
||||
CONFIG_B43_SDIO=y
|
||||
CONFIG_B43_DEBUG=y
|
||||
# CONFIG_B43_DEBUG is not set
|
||||
CONFIG_B43_PHY_LP=y
|
||||
# CONFIG_B43_FORCE_PIO is not set
|
||||
CONFIG_B43LEGACY=m
|
||||
CONFIG_B43LEGACY_DEBUG=y
|
||||
# CONFIG_B43LEGACY_DEBUG is not set
|
||||
CONFIG_B43LEGACY_DMA=y
|
||||
CONFIG_B43LEGACY_PIO=y
|
||||
CONFIG_B43LEGACY_DMA_AND_PIO_MODE=y
|
||||
|
@ -2193,7 +2193,7 @@ CONFIG_WDTPCI=m
|
|||
# CONFIG_ACQUIRE_WDT is not set
|
||||
# CONFIG_ADVANTECH_WDT is not set
|
||||
# CONFIG_EUROTECH_WDT is not set
|
||||
# CONFIG_IB700_WDT is not set
|
||||
CONFIG_IB700_WDT=m
|
||||
# CONFIG_MIXCOMWD is not set
|
||||
# CONFIG_SCx200_WDT is not set
|
||||
# CONFIG_60XX_WDT is not set
|
||||
|
@ -2308,6 +2308,7 @@ CONFIG_DRM_NOUVEAU=m
|
|||
CONFIG_DRM_NOUVEAU_BACKLIGHT=y
|
||||
CONFIG_DRM_NOUVEAU_DEBUG=y
|
||||
CONFIG_DRM_I2C_CH7006=m
|
||||
CONFIG_DRM_I2C_SIL164=m
|
||||
CONFIG_DRM_VMWGFX=m
|
||||
|
||||
#
|
||||
|
@ -2581,14 +2582,20 @@ CONFIG_VIDEO_PVRUSB2_SYSFS=y
|
|||
# CONFIG_VIDEO_PVRUSB2_DEBUGIFC is not set
|
||||
|
||||
CONFIG_RC_MAP=m
|
||||
CONFIG_IR_CORE=m
|
||||
CONFIG_IR_NEC_DECODER=m
|
||||
CONFIG_IR_RC5_DECODER=m
|
||||
CONFIG_IR_RC6_DECODER=m
|
||||
CONFIG_IR_JVC_DECODER=m
|
||||
CONFIG_IR_SONY_DECODER=m
|
||||
CONFIG_IR_RC5_SZ_DECODER=m
|
||||
CONFIG_IR_LIRC_CODEC=m
|
||||
CONFIG_IR_ENE=m
|
||||
CONFIG_IR_IMON=m
|
||||
CONFIG_IR_MCEUSB=m
|
||||
CONFIG_IR_NUVOTON=m
|
||||
CONFIG_IR_STREAMZAP=m
|
||||
CONFIG_IR_WINBOND_CIR=m
|
||||
|
||||
CONFIG_V4L_MEM2MEM_DRIVERS=y
|
||||
# CONFIG_VIDEO_MEM2MEM_TESTDEV is not set
|
||||
|
@ -3321,7 +3328,8 @@ CONFIG_QUOTACTL=y
|
|||
CONFIG_DNOTIFY=y
|
||||
# Autofsv3 is obsolete.
|
||||
# CONFIG_AUTOFS_FS is not set
|
||||
CONFIG_AUTOFS4_FS=m
|
||||
# systemd is dependant upon AUTOFS, so build it in.
|
||||
CONFIG_AUTOFS4_FS=y
|
||||
CONFIG_EXOFS_FS=m
|
||||
# CONFIG_EXOFS_DEBUG is not set
|
||||
CONFIG_NILFS2_FS=m
|
||||
|
@ -3601,6 +3609,7 @@ CONFIG_CRYPTO_FIPS=y
|
|||
CONFIG_CRYPTO_HW=y
|
||||
CONFIG_CRYPTO_BLKCIPHER=y
|
||||
CONFIG_CRYPTO_MANAGER=m
|
||||
CONFIG_CRYPTO_MANAGER_TESTS=y
|
||||
# CONFIG_CRYPTO_CRYPTD is not set
|
||||
CONFIG_CRYPTO_AES=m
|
||||
CONFIG_CRYPTO_ARC4=m
|
||||
|
@ -3722,7 +3731,7 @@ CONFIG_BLK_CGROUP=y
|
|||
# CONFIG_SYSFS_DEPRECATED_V2 is not set
|
||||
|
||||
CONFIG_RELAY=y
|
||||
# CONFIG_PRINTK_TIME is not set
|
||||
CONFIG_PRINTK_TIME=y
|
||||
|
||||
CONFIG_ENABLE_MUST_CHECK=y
|
||||
# CONFIG_ENABLE_WARN_DEPRECATED is not set
|
||||
|
@ -3742,7 +3751,7 @@ CONFIG_IBMASR=m
|
|||
CONFIG_PM_DEBUG=y
|
||||
CONFIG_PM_TRACE=y
|
||||
# CONFIG_PM_VERBOSE is not set
|
||||
CONFIG_PM_TEST_SUSPEND=y
|
||||
# CONFIG_PM_TEST_SUSPEND is not set
|
||||
CONFIG_PM_RUNTIME=y
|
||||
|
||||
## BEGIN ISA Junk.
|
||||
|
@ -3987,8 +3996,8 @@ CONFIG_AUXDISPLAY=y
|
|||
CONFIG_UIO=m
|
||||
CONFIG_UIO_CIF=m
|
||||
CONFIG_UIO_SMX=m
|
||||
CONFIG_UIO_PDRV=m
|
||||
CONFIG_UIO_PDRV_GENIRQ=m
|
||||
# CONFIG_UIO_PDRV is not set
|
||||
# CONFIG_UIO_PDRV_GENIRQ is not set
|
||||
CONFIG_UIO_AEC=m
|
||||
CONFIG_UIO_SERCOS3=m
|
||||
CONFIG_UIO_PCI_GENERIC=m
|
||||
|
@ -4013,7 +4022,7 @@ CONFIG_LIRC_SERIAL=m
|
|||
CONFIG_LIRC_SERIAL_TRANSMITTER=y
|
||||
CONFIG_LIRC_SASEM=m
|
||||
CONFIG_LIRC_SIR=m
|
||||
CONFIG_LIRC_STREAMZAP=m
|
||||
# CONFIG_LIRC_STREAMZAP is not set
|
||||
CONFIG_LIRC_TTUSBIR=m
|
||||
|
||||
# CONFIG_SAMPLES is not set
|
||||
|
@ -4175,7 +4184,7 @@ CONFIG_USB_ATMEL=m
|
|||
# CONFIG_RCU_CPU_STALL_DETECTOR is not set
|
||||
# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
|
||||
# CONFIG_FUNCTION_GRAPH_TRACER is not set
|
||||
CONFIG_BOOT_TRACER=y
|
||||
# CONFIG_BOOT_TRACER is not set
|
||||
CONFIG_EARLY_PRINTK_DBGP=y
|
||||
|
||||
CONFIG_SECURITYFS=y
|
||||
|
@ -4253,7 +4262,7 @@ CONFIG_DEBUG_NX_TEST=m
|
|||
CONFIG_DEBUG_BOOT_PARAMS=y
|
||||
CONFIG_DETECT_SOFTLOCKUP=y
|
||||
# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
|
||||
CONFIG_DETECT_HUNG_TASK=y
|
||||
# CONFIG_DETECT_HUNG_TASK is not set
|
||||
# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
|
||||
CONFIG_ATOMIC64_SELFTEST=y
|
||||
|
||||
|
@ -4269,7 +4278,7 @@ CONFIG_BLK_DEV_DRBD=m
|
|||
# CONFIG_DEBUG_GPIO is not set
|
||||
# CONFIG_W1_MASTER_GPIO is not set
|
||||
# CONFIG_LEDS_GPIO is not set
|
||||
# CONFIG_GPIO_SYSFS is not set
|
||||
CONFIG_GPIO_SYSFS=y
|
||||
# CONFIG_GPIO_MAX732X is not set
|
||||
# CONFIG_GPIO_PCA953X is not set
|
||||
# CONFIG_GPIO_PCF857X is not set
|
||||
|
|
|
@ -3,3 +3,6 @@ CONFIG_HIGHMEM64G=y
|
|||
|
||||
CONFIG_XEN_DEV_EVTCHN=m
|
||||
CONFIG_XEN_SYS_HYPERVISOR=y
|
||||
|
||||
# I2O only works on non-PAE 32-bit x86
|
||||
# CONFIG_I2O is not set
|
||||
|
|
|
@ -136,7 +136,7 @@ CONFIG_ACPI_SLEEP=y
|
|||
CONFIG_ACPI_THERMAL=y
|
||||
# CONFIG_ACPI_TOSHIBA is not set
|
||||
CONFIG_ACPI_VIDEO=m
|
||||
# CONFIG_ACPI_PROC_EVENT is not set
|
||||
CONFIG_ACPI_PROC_EVENT=y
|
||||
CONFIG_ACPI_HED=m
|
||||
|
||||
CONFIG_PM=y
|
||||
|
|
|
@ -2,90 +2,92 @@ CONFIG_SND_VERBOSE_PRINTK=y
|
|||
CONFIG_SND_DEBUG=y
|
||||
CONFIG_SND_PCM_XRUN_DEBUG=y
|
||||
|
||||
CONFIG_DEBUG_MUTEXES=y
|
||||
CONFIG_DEBUG_RT_MUTEXES=y
|
||||
CONFIG_DEBUG_LOCK_ALLOC=y
|
||||
CONFIG_PROVE_LOCKING=y
|
||||
CONFIG_DEBUG_VM=y
|
||||
CONFIG_DEBUG_SPINLOCK=y
|
||||
CONFIG_PROVE_RCU=y
|
||||
# CONFIG_DEBUG_MUTEXES is not set
|
||||
# CONFIG_DEBUG_RT_MUTEXES is not set
|
||||
# CONFIG_DEBUG_LOCK_ALLOC is not set
|
||||
# CONFIG_PROVE_LOCKING is not set
|
||||
# CONFIG_DEBUG_VM is not set
|
||||
# CONFIG_DEBUG_SPINLOCK is not set
|
||||
# CONFIG_PROVE_RCU is not set
|
||||
# CONFIG_PROVE_RCU_REPEATEDLY is not set
|
||||
CONFIG_DEBUG_PER_CPU_MAPS=y
|
||||
# CONFIG_DEBUG_PER_CPU_MAPS is not set
|
||||
CONFIG_CPUMASK_OFFSTACK=y
|
||||
|
||||
CONFIG_CPU_NOTIFIER_ERROR_INJECT=m
|
||||
# CONFIG_CPU_NOTIFIER_ERROR_INJECT is not set
|
||||
|
||||
CONFIG_FAULT_INJECTION=y
|
||||
CONFIG_FAILSLAB=y
|
||||
CONFIG_FAIL_PAGE_ALLOC=y
|
||||
CONFIG_FAIL_MAKE_REQUEST=y
|
||||
CONFIG_FAULT_INJECTION_DEBUG_FS=y
|
||||
CONFIG_FAULT_INJECTION_STACKTRACE_FILTER=y
|
||||
CONFIG_FAIL_IO_TIMEOUT=y
|
||||
# CONFIG_FAULT_INJECTION is not set
|
||||
# CONFIG_FAILSLAB is not set
|
||||
# CONFIG_FAIL_PAGE_ALLOC is not set
|
||||
# CONFIG_FAIL_MAKE_REQUEST is not set
|
||||
# CONFIG_FAULT_INJECTION_DEBUG_FS is not set
|
||||
# CONFIG_FAULT_INJECTION_STACKTRACE_FILTER is not set
|
||||
# CONFIG_FAIL_IO_TIMEOUT is not set
|
||||
|
||||
CONFIG_SLUB_DEBUG_ON=y
|
||||
# CONFIG_SLUB_DEBUG_ON is not set
|
||||
|
||||
CONFIG_LOCK_STAT=y
|
||||
# CONFIG_LOCK_STAT is not set
|
||||
|
||||
CONFIG_DEBUG_STACK_USAGE=y
|
||||
# CONFIG_DEBUG_STACK_USAGE is not set
|
||||
|
||||
CONFIG_ACPI_DEBUG=y
|
||||
# CONFIG_ACPI_DEBUG is not set
|
||||
# CONFIG_ACPI_DEBUG_FUNC_TRACE is not set
|
||||
|
||||
CONFIG_DEBUG_SG=y
|
||||
# CONFIG_DEBUG_SG is not set
|
||||
|
||||
# CONFIG_DEBUG_PAGEALLOC is not set
|
||||
|
||||
CONFIG_DEBUG_WRITECOUNT=y
|
||||
CONFIG_DEBUG_OBJECTS=y
|
||||
# CONFIG_DEBUG_WRITECOUNT is not set
|
||||
# CONFIG_DEBUG_OBJECTS is not set
|
||||
# CONFIG_DEBUG_OBJECTS_SELFTEST is not set
|
||||
CONFIG_DEBUG_OBJECTS_FREE=y
|
||||
CONFIG_DEBUG_OBJECTS_TIMERS=y
|
||||
# CONFIG_DEBUG_OBJECTS_FREE is not set
|
||||
# CONFIG_DEBUG_OBJECTS_TIMERS is not set
|
||||
CONFIG_DEBUG_OBJECTS_ENABLE_DEFAULT=1
|
||||
|
||||
CONFIG_X86_PTDUMP=y
|
||||
# CONFIG_X86_PTDUMP is not set
|
||||
|
||||
CONFIG_CAN_DEBUG_DEVICES=y
|
||||
# CONFIG_CAN_DEBUG_DEVICES is not set
|
||||
|
||||
CONFIG_MODULE_FORCE_UNLOAD=y
|
||||
# CONFIG_MODULE_FORCE_UNLOAD is not set
|
||||
|
||||
CONFIG_SYSCTL_SYSCALL_CHECK=y
|
||||
# CONFIG_SYSCTL_SYSCALL_CHECK is not set
|
||||
|
||||
CONFIG_DEBUG_NOTIFIERS=y
|
||||
# CONFIG_DEBUG_NOTIFIERS is not set
|
||||
|
||||
CONFIG_DMA_API_DEBUG=y
|
||||
# CONFIG_DMA_API_DEBUG is not set
|
||||
|
||||
CONFIG_MMIOTRACE=y
|
||||
# CONFIG_MMIOTRACE is not set
|
||||
|
||||
CONFIG_DEBUG_CREDENTIALS=y
|
||||
# CONFIG_DEBUG_CREDENTIALS is not set
|
||||
|
||||
# off in both production debug and nodebug builds,
|
||||
# on in rawhide nodebug builds
|
||||
CONFIG_DEBUG_FORCE_WEAK_PER_CPU=y
|
||||
# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
|
||||
|
||||
CONFIG_EXT4_DEBUG=y
|
||||
# CONFIG_EXT4_DEBUG is not set
|
||||
|
||||
CONFIG_DEBUG_PERF_USE_VMALLOC=y
|
||||
# CONFIG_DEBUG_PERF_USE_VMALLOC is not set
|
||||
|
||||
CONFIG_JBD2_DEBUG=y
|
||||
# CONFIG_JBD2_DEBUG is not set
|
||||
|
||||
CONFIG_DEBUG_CFQ_IOSCHED=y
|
||||
# CONFIG_DEBUG_CFQ_IOSCHED is not set
|
||||
|
||||
CONFIG_DRBD_FAULT_INJECTION=y
|
||||
# CONFIG_DRBD_FAULT_INJECTION is not set
|
||||
|
||||
CONFIG_ATH_DEBUG=y
|
||||
CONFIG_IWLWIFI_DEVICE_TRACING=y
|
||||
# CONFIG_ATH_DEBUG is not set
|
||||
# CONFIG_IWLWIFI_DEVICE_TRACING is not set
|
||||
|
||||
CONFIG_DEBUG_OBJECTS_WORK=y
|
||||
CONFIG_DEBUG_STRICT_USER_COPY_CHECKS=y
|
||||
# CONFIG_DEBUG_OBJECTS_WORK is not set
|
||||
# CONFIG_DEBUG_STRICT_USER_COPY_CHECKS is not set
|
||||
|
||||
CONFIG_DMADEVICES_DEBUG=y
|
||||
CONFIG_DMADEVICES_VDEBUG=y
|
||||
# CONFIG_DMADEVICES_DEBUG is not set
|
||||
# CONFIG_DMADEVICES_VDEBUG is not set
|
||||
|
||||
CONFIG_PM_ADVANCED_DEBUG=y
|
||||
|
||||
CONFIG_CEPH_FS_PRETTYDEBUG=y
|
||||
CONFIG_QUOTA_DEBUG=y
|
||||
# CONFIG_CEPH_FS_PRETTYDEBUG is not set
|
||||
# CONFIG_QUOTA_DEBUG is not set
|
||||
|
||||
# CONFIG_PCI_DEFAULT_USE_CRS is not set
|
||||
|
||||
CONFIG_KGDB_KDB=y
|
||||
CONFIG_KDB_KEYBOARD=y
|
||||
|
|
|
@ -200,4 +200,9 @@ CONFIG_SERIAL_GRLIB_GAISLER_APBUART=m
|
|||
CONFIG_GRETH=m
|
||||
CONFIG_FB_XVR1000=y
|
||||
|
||||
CONFIG_CRYPTO_DEV_NIAGARA2=y
|
||||
CONFIG_CRYPTO_DEV_NIAGARA2=m
|
||||
|
||||
# Bellow is changes made to get the kernel building on sparc again, they need to have upstream fixes
|
||||
# CONFIG_DEBUG_STRICT_USER_COPY_CHECKS is not set
|
||||
# CONFIG_ATA_OVER_ETH is not set
|
||||
# CONFIG_INFINIBAND is not set
|
||||
|
|
|
@ -37,7 +37,7 @@ CONFIG_M686=y
|
|||
# CONFIG_MCYRIXIII is not set
|
||||
# CONFIG_MVIAC3_2 is not set
|
||||
CONFIG_SMP=y
|
||||
CONFIG_NR_CPUS=32
|
||||
CONFIG_NR_CPUS=64
|
||||
CONFIG_X86_GENERIC=y
|
||||
# CONFIG_X86_PPRO_FENCE is not set
|
||||
CONFIG_HPET=y
|
||||
|
@ -100,6 +100,16 @@ CONFIG_SECCOMP=y
|
|||
|
||||
CONFIG_CAPI_EICON=y
|
||||
|
||||
# I2O enabled only for 32-bit x86, disabled for PAE kernel
|
||||
CONFIG_I2O=m
|
||||
CONFIG_I2O_BLOCK=m
|
||||
CONFIG_I2O_SCSI=m
|
||||
CONFIG_I2O_PROC=m
|
||||
CONFIG_I2O_CONFIG=y
|
||||
CONFIG_I2O_EXT_ADAPTEC=y
|
||||
CONFIG_I2O_CONFIG_OLD_IOCTL=y
|
||||
CONFIG_I2O_BUS=m
|
||||
|
||||
#
|
||||
# APM (Advanced Power Management) BIOS Support
|
||||
#
|
||||
|
@ -136,7 +146,7 @@ CONFIG_ACPI_THERMAL=y
|
|||
CONFIG_TOPSTAR_LAPTOP=m
|
||||
CONFIG_ACPI_TOSHIBA=m
|
||||
CONFIG_ACPI_VIDEO=m
|
||||
# CONFIG_ACPI_PROC_EVENT is not set
|
||||
CONFIG_ACPI_PROC_EVENT=y
|
||||
CONFIG_PNPACPI=y
|
||||
CONFIG_ACPI_POWER_METER=m
|
||||
CONFIG_ACPI_PROCESSOR_AGGREGATOR=m
|
||||
|
@ -479,6 +489,6 @@ CONFIG_TOSHIBA_BT_RFKILL=m
|
|||
CONFIG_VGA_SWITCHEROO=y
|
||||
CONFIG_LPC_SCH=m
|
||||
|
||||
CONFIG_INTEL_IDLE=m
|
||||
CONFIG_INTEL_IDLE=y
|
||||
|
||||
CONFIG_PCI_CNB20LE_QUIRK=y
|
||||
|
|
|
@ -15,7 +15,7 @@ CONFIG_NUMA=y
|
|||
CONFIG_K8_NUMA=y
|
||||
CONFIG_X86_64_ACPI_NUMA=y
|
||||
# CONFIG_NUMA_EMU is not set
|
||||
CONFIG_NR_CPUS=512
|
||||
CONFIG_NR_CPUS=256
|
||||
CONFIG_X86_POWERNOW_K8=m
|
||||
CONFIG_X86_P4_CLOCKMOD=m
|
||||
CONFIG_IA32_EMULATION=y
|
||||
|
@ -90,7 +90,7 @@ CONFIG_ACPI_THERMAL=y
|
|||
CONFIG_ACPI_TOSHIBA=m
|
||||
CONFIG_ACPI_POWER=y
|
||||
CONFIG_ACPI_VIDEO=m
|
||||
# CONFIG_ACPI_PROC_EVENT is not set
|
||||
CONFIG_ACPI_PROC_EVENT=y
|
||||
CONFIG_ACPI_POWER_METER=m
|
||||
CONFIG_ACPI_PROCESSOR_AGGREGATOR=m
|
||||
CONFIG_ACPI_HED=m
|
||||
|
@ -403,7 +403,7 @@ CONFIG_CRYPTO_GHASH_CLMUL_NI_INTEL=m
|
|||
CONFIG_VGA_SWITCHEROO=y
|
||||
CONFIG_LPC_SCH=m
|
||||
|
||||
CONFIG_INTEL_IDLE=m
|
||||
CONFIG_INTEL_IDLE=y
|
||||
CONFIG_I7300_IDLE=m
|
||||
|
||||
CONFIG_PCI_CNB20LE_QUIRK=y
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
From: Greg KH <gregkh@suse.de>
|
||||
Date: Thu, 5 Aug 2010 20:53:35 +0000 (-0700)
|
||||
Subject: cgroupfs: create /sys/fs/cgroup to mount cgroupfs on
|
||||
X-Git-Tag: v2.6.36-rc1~521^2~7
|
||||
X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=676db4af043014e852f67ba0349dae0071bd11f3
|
||||
|
||||
cgroupfs: create /sys/fs/cgroup to mount cgroupfs on
|
||||
|
||||
We really shouldn't be asking userspace to create new root filesystems.
|
||||
So follow along with all of the other in-kernel filesystems, and provide
|
||||
a mount point in sysfs.
|
||||
|
||||
For cgroupfs, this should be in /sys/fs/cgroup/ This change provides
|
||||
that mount point when the cgroup filesystem is registered in the kernel.
|
||||
|
||||
Acked-by: Paul Menage <menage@google.com>
|
||||
Acked-by: Dhaval Giani <dhaval.giani@gmail.com>
|
||||
Cc: Li Zefan <lizf@cn.fujitsu.com>
|
||||
Cc: Lennart Poettering <lennart@poettering.net>
|
||||
Cc: Kay Sievers <kay.sievers@vrfy.org>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
|
||||
---
|
||||
|
||||
diff --git a/kernel/cgroup.c b/kernel/cgroup.c
|
||||
index a8ce099..d83cab0 100644
|
||||
--- a/kernel/cgroup.c
|
||||
+++ b/kernel/cgroup.c
|
||||
@@ -1623,6 +1623,8 @@ static struct file_system_type cgroup_fs_type = {
|
||||
.kill_sb = cgroup_kill_sb,
|
||||
};
|
||||
|
||||
+static struct kobject *cgroup_kobj;
|
||||
+
|
||||
static inline struct cgroup *__d_cgrp(struct dentry *dentry)
|
||||
{
|
||||
return dentry->d_fsdata;
|
||||
@@ -3894,9 +3896,18 @@ int __init cgroup_init(void)
|
||||
hhead = css_set_hash(init_css_set.subsys);
|
||||
hlist_add_head(&init_css_set.hlist, hhead);
|
||||
BUG_ON(!init_root_id(&rootnode));
|
||||
+
|
||||
+ cgroup_kobj = kobject_create_and_add("cgroup", fs_kobj);
|
||||
+ if (!cgroup_kobj) {
|
||||
+ err = -ENOMEM;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
err = register_filesystem(&cgroup_fs_type);
|
||||
- if (err < 0)
|
||||
+ if (err < 0) {
|
||||
+ kobject_put(cgroup_kobj);
|
||||
goto out;
|
||||
+ }
|
||||
|
||||
proc_create("cgroups", 0, NULL, &proc_cgroupstats_operations);
|
||||
|
|
@ -0,0 +1,78 @@
|
|||
From 799c10559d60f159ab2232203f222f18fa3c4a5f Mon Sep 17 00:00:00 2001
|
||||
From: Linus Torvalds <torvalds@linux-foundation.org>
|
||||
Date: Fri, 15 Oct 2010 11:09:28 -0700
|
||||
Subject: [PATCH] De-pessimize rds_page_copy_user
|
||||
|
||||
Don't try to "optimize" rds_page_copy_user() by using kmap_atomic() and
|
||||
the unsafe atomic user mode accessor functions. It's actually slower
|
||||
than the straightforward code on any reasonable modern CPU.
|
||||
|
||||
Back when the code was written (although probably not by the time it was
|
||||
actually merged, though), 32-bit x86 may have been the dominant
|
||||
architecture. And there kmap_atomic() can be a lot faster than kmap()
|
||||
(unless you have very good locality, in which case the virtual address
|
||||
caching by kmap() can overcome all the downsides).
|
||||
|
||||
But these days, x86-64 may not be more populous, but it's getting there
|
||||
(and if you care about performance, it's definitely already there -
|
||||
you'd have upgraded your CPU's already in the last few years). And on
|
||||
x86-64, the non-kmap_atomic() version is faster, simply because the code
|
||||
is simpler and doesn't have the "re-try page fault" case.
|
||||
|
||||
People with old hardware are not likely to care about RDS anyway, and
|
||||
the optimization for the 32-bit case is simply buggy, since it doesn't
|
||||
verify the user addresses properly.
|
||||
|
||||
Reported-by: Dan Rosenberg <drosenberg@vsecurity.com>
|
||||
Acked-by: Andrew Morton <akpm@linux-foundation.org>
|
||||
Cc: stable@kernel.org
|
||||
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
|
||||
---
|
||||
net/rds/page.c | 27 +++++++--------------------
|
||||
1 files changed, 7 insertions(+), 20 deletions(-)
|
||||
|
||||
diff --git a/net/rds/page.c b/net/rds/page.c
|
||||
index 595a952..1dfbfea 100644
|
||||
--- a/net/rds/page.c
|
||||
+++ b/net/rds/page.c
|
||||
@@ -57,30 +57,17 @@ int rds_page_copy_user(struct page *page, unsigned long offset,
|
||||
unsigned long ret;
|
||||
void *addr;
|
||||
|
||||
- if (to_user)
|
||||
+ addr = kmap(page);
|
||||
+ if (to_user) {
|
||||
rds_stats_add(s_copy_to_user, bytes);
|
||||
- else
|
||||
+ ret = copy_to_user(ptr, addr + offset, bytes);
|
||||
+ } else {
|
||||
rds_stats_add(s_copy_from_user, bytes);
|
||||
-
|
||||
- addr = kmap_atomic(page, KM_USER0);
|
||||
- if (to_user)
|
||||
- ret = __copy_to_user_inatomic(ptr, addr + offset, bytes);
|
||||
- else
|
||||
- ret = __copy_from_user_inatomic(addr + offset, ptr, bytes);
|
||||
- kunmap_atomic(addr, KM_USER0);
|
||||
-
|
||||
- if (ret) {
|
||||
- addr = kmap(page);
|
||||
- if (to_user)
|
||||
- ret = copy_to_user(ptr, addr + offset, bytes);
|
||||
- else
|
||||
- ret = copy_from_user(addr + offset, ptr, bytes);
|
||||
- kunmap(page);
|
||||
- if (ret)
|
||||
- return -EFAULT;
|
||||
+ ret = copy_from_user(addr + offset, ptr, bytes);
|
||||
}
|
||||
+ kunmap(page);
|
||||
|
||||
- return 0;
|
||||
+ return ret ? -EFAULT : 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rds_page_copy_user);
|
||||
|
||||
--
|
||||
1.7.3.2
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c
|
||||
index 11482b6..b05ff9c 100644
|
||||
--- a/drivers/usb/host/xhci-pci.c
|
||||
+++ b/drivers/usb/host/xhci-pci.c
|
||||
@@ -179,9 +179,25 @@ static struct pci_driver xhci_pci_driver = {
|
||||
.shutdown = usb_hcd_pci_shutdown,
|
||||
};
|
||||
|
||||
+
|
||||
+static int enable;
|
||||
+module_param(enable, int, S_IRUGO);
|
||||
+MODULE_PARM_DESC(enable, "Enable XHCI host controller");
|
||||
+
|
||||
int xhci_register_pci(void)
|
||||
{
|
||||
- return pci_register_driver(&xhci_pci_driver);
|
||||
+ /* xhci will prevent suspend/resume if it's loaded.
|
||||
+ * force user to pass xhci.enable=1 to the kernel in order
|
||||
+ * to get usb3.0 support for the time being.
|
||||
+ *
|
||||
+ * ugly yes, but there's few enough users out there using
|
||||
+ * usb3.0, and a lot who just have the hardware breaking
|
||||
+ * their suspend.
|
||||
+ */
|
||||
+ if (enable)
|
||||
+ return pci_register_driver(&xhci_pci_driver);
|
||||
+ else
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
void xhci_unregister_pci(void)
|
|
@ -0,0 +1,205 @@
|
|||
From ce5fa9851090cc5f3de4139bf0f343eb78d1c568 Mon Sep 17 00:00:00 2001
|
||||
From: Peter Jones <pjones@redhat.com>
|
||||
Date: Mon, 11 Oct 2010 15:49:28 -0400
|
||||
Subject: [PATCH] device-mapper: Allow setting of UUID via rename if not already set
|
||||
|
||||
This makes it possible to use DM_DEV_RENAME to add a uuid to a device so
|
||||
long as one has not been previously set either with DM_DEV_CREATE or
|
||||
with DM_DEV_RENAME. This is needed because sometimes in it's necessary
|
||||
to create the device before the uuid is known, and in such cases the
|
||||
uuid must be filled in after the creation.
|
||||
|
||||
Also bump the minor number to 19.
|
||||
|
||||
Signed-off-by: Peter Jones <pjones@redhat.com>
|
||||
---
|
||||
drivers/md/dm-ioctl.c | 95 ++++++++++++++++++++++++++++++++--------------
|
||||
include/linux/dm-ioctl.h | 11 ++++-
|
||||
2 files changed, 74 insertions(+), 32 deletions(-)
|
||||
|
||||
diff --git a/drivers/md/dm-ioctl.c b/drivers/md/dm-ioctl.c
|
||||
index bb6bdc8..d102269 100644
|
||||
--- a/drivers/md/dm-ioctl.c
|
||||
+++ b/drivers/md/dm-ioctl.c
|
||||
@@ -298,15 +298,15 @@ retry:
|
||||
static int dm_hash_rename(uint32_t cookie, uint32_t *flags, const char *old,
|
||||
const char *new)
|
||||
{
|
||||
- char *new_name, *old_name;
|
||||
+ char *new_data, *old_data;
|
||||
struct hash_cell *hc;
|
||||
struct dm_table *table;
|
||||
|
||||
/*
|
||||
* duplicate new.
|
||||
*/
|
||||
- new_name = kstrdup(new, GFP_KERNEL);
|
||||
- if (!new_name)
|
||||
+ new_data = kstrdup(new, GFP_KERNEL);
|
||||
+ if (!new_data)
|
||||
return -ENOMEM;
|
||||
|
||||
down_write(&_hash_lock);
|
||||
@@ -314,13 +314,18 @@ static int dm_hash_rename(uint32_t cookie, uint32_t *flags, const char *old,
|
||||
/*
|
||||
* Is new free ?
|
||||
*/
|
||||
- hc = __get_name_cell(new);
|
||||
+ if (*flags & DM_NEW_UUID_FLAG)
|
||||
+ hc = __get_uuid_cell(new);
|
||||
+ else
|
||||
+ hc = __get_name_cell(new);
|
||||
if (hc) {
|
||||
- DMWARN("asked to rename to an already existing name %s -> %s",
|
||||
+ DMWARN("Unable to change %s on device, %s to one that "
|
||||
+ "already exists: %s",
|
||||
+ (*flags & DM_NEW_UUID_FLAG) ? "uuid" : "name",
|
||||
old, new);
|
||||
dm_put(hc->md);
|
||||
up_write(&_hash_lock);
|
||||
- kfree(new_name);
|
||||
+ kfree(new_data);
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
@@ -329,22 +334,46 @@ static int dm_hash_rename(uint32_t cookie, uint32_t *flags, const char *old,
|
||||
*/
|
||||
hc = __get_name_cell(old);
|
||||
if (!hc) {
|
||||
- DMWARN("asked to rename a non existent device %s -> %s",
|
||||
+ DMWARN("Unable to rename non-existent device, %s to %s",
|
||||
old, new);
|
||||
up_write(&_hash_lock);
|
||||
- kfree(new_name);
|
||||
+ kfree(new_data);
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
- /*
|
||||
- * rename and move the name cell.
|
||||
- */
|
||||
- list_del(&hc->name_list);
|
||||
- old_name = hc->name;
|
||||
- mutex_lock(&dm_hash_cells_mutex);
|
||||
- hc->name = new_name;
|
||||
- mutex_unlock(&dm_hash_cells_mutex);
|
||||
- list_add(&hc->name_list, _name_buckets + hash_str(new_name));
|
||||
+ if (*flags & DM_NEW_UUID_FLAG) {
|
||||
+ /*
|
||||
+ * Does this device already have a uuid?
|
||||
+ */
|
||||
+ if (hc->uuid) {
|
||||
+ DMWARN("Unable to change uuid of device, %s because "
|
||||
+ "uuid is already set to %s",
|
||||
+ old, hc->uuid);
|
||||
+ dm_put(hc->md);
|
||||
+ up_write(&_hash_lock);
|
||||
+ kfree(new_data);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+ /*
|
||||
+ * change uuid and move the uuid cell.
|
||||
+ */
|
||||
+ list_del(&hc->uuid_list);
|
||||
+ old_data = hc->uuid;
|
||||
+ mutex_lock(&dm_hash_cells_mutex);
|
||||
+ hc->uuid = new_data;
|
||||
+ mutex_unlock(&dm_hash_cells_mutex);
|
||||
+ list_add(&hc->uuid_list, _uuid_buckets + hash_str(new_data));
|
||||
+ } else {
|
||||
+ /*
|
||||
+ * rename and move the name cell.
|
||||
+ */
|
||||
+ list_del(&hc->name_list);
|
||||
+ old_data = hc->name;
|
||||
+ mutex_lock(&dm_hash_cells_mutex);
|
||||
+ hc->name = new_data;
|
||||
+ mutex_unlock(&dm_hash_cells_mutex);
|
||||
+ list_add(&hc->name_list, _name_buckets + hash_str(new_data));
|
||||
+ }
|
||||
|
||||
/*
|
||||
* Wake up any dm event waiters.
|
||||
@@ -360,7 +388,7 @@ static int dm_hash_rename(uint32_t cookie, uint32_t *flags, const char *old,
|
||||
|
||||
dm_put(hc->md);
|
||||
up_write(&_hash_lock);
|
||||
- kfree(old_name);
|
||||
+ kfree(old_data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -773,23 +801,32 @@ static int invalid_str(char *str, void *end)
|
||||
static int dev_rename(struct dm_ioctl *param, size_t param_size)
|
||||
{
|
||||
int r;
|
||||
- char *new_name = (char *) param + param->data_start;
|
||||
+ char *new_data = (char *) param + param->data_start;
|
||||
|
||||
- if (new_name < param->data ||
|
||||
- invalid_str(new_name, (void *) param + param_size) ||
|
||||
- strlen(new_name) > DM_NAME_LEN - 1) {
|
||||
- DMWARN("Invalid new logical volume name supplied.");
|
||||
- return -EINVAL;
|
||||
- }
|
||||
+ if (param->flags & DM_NEW_UUID_FLAG) {
|
||||
+ if (new_data < param->data ||
|
||||
+ invalid_str(new_data, (void *) param + param_size) ||
|
||||
+ strlen(new_data) > DM_UUID_LEN - 1) {
|
||||
+ DMWARN("Invalid new device uuid supplied.");
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+ } else {
|
||||
+ if (new_data < param->data ||
|
||||
+ invalid_str(new_data, (void *) param + param_size) ||
|
||||
+ strlen(new_data) > DM_NAME_LEN - 1) {
|
||||
+ DMWARN("Invalid new device name supplied.");
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
|
||||
- r = check_name(new_name);
|
||||
- if (r)
|
||||
- return r;
|
||||
+ r = check_name(new_data);
|
||||
+ if (r)
|
||||
+ return r;
|
||||
+ }
|
||||
|
||||
param->data_size = 0;
|
||||
|
||||
return dm_hash_rename(param->event_nr, ¶m->flags, param->name,
|
||||
- new_name);
|
||||
+ new_data);
|
||||
}
|
||||
|
||||
static int dev_set_geometry(struct dm_ioctl *param, size_t param_size)
|
||||
diff --git a/include/linux/dm-ioctl.h b/include/linux/dm-ioctl.h
|
||||
index 2c445e1..3bbcb3a 100644
|
||||
--- a/include/linux/dm-ioctl.h
|
||||
+++ b/include/linux/dm-ioctl.h
|
||||
@@ -266,9 +266,9 @@ enum {
|
||||
#define DM_DEV_SET_GEOMETRY _IOWR(DM_IOCTL, DM_DEV_SET_GEOMETRY_CMD, struct dm_ioctl)
|
||||
|
||||
#define DM_VERSION_MAJOR 4
|
||||
-#define DM_VERSION_MINOR 17
|
||||
-#define DM_VERSION_PATCHLEVEL 0
|
||||
-#define DM_VERSION_EXTRA "-ioctl (2010-03-05)"
|
||||
+#define DM_VERSION_MINOR 19
|
||||
+#define DM_VERSION_PATCHLEVEL 1
|
||||
+#define DM_VERSION_EXTRA "-ioctl (2010-10-12)"
|
||||
|
||||
/* Status bits */
|
||||
#define DM_READONLY_FLAG (1 << 0) /* In/Out */
|
||||
@@ -321,4 +321,9 @@ enum {
|
||||
*/
|
||||
#define DM_UEVENT_GENERATED_FLAG (1 << 13) /* Out */
|
||||
|
||||
+/*
|
||||
+ * If set, rename operates on uuid, not name.
|
||||
+ */
|
||||
+#define DM_NEW_UUID_FLAG (1 << 14) /* In */
|
||||
+
|
||||
#endif /* _LINUX_DM_IOCTL_H */
|
||||
--
|
||||
1.7.2.3
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
From 8d2f6746f7f82e1aee2dc40a937b5954cfc73414 Mon Sep 17 00:00:00 2001
|
||||
From: Kyle McMartin <kyle@mcmartin.ca>
|
||||
Date: Sun, 17 Oct 2010 15:55:32 -0400
|
||||
Subject: [PATCH] dmar: disable if ricoh multifunction detected
|
||||
|
||||
---
|
||||
drivers/pci/intel-iommu.c | 10 ++++++++++
|
||||
1 files changed, 10 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/drivers/pci/intel-iommu.c b/drivers/pci/intel-iommu.c
|
||||
index 8e499e8..076c5de 100644
|
||||
--- a/drivers/pci/intel-iommu.c
|
||||
+++ b/drivers/pci/intel-iommu.c
|
||||
@@ -3755,6 +3755,18 @@ static void __devinit quirk_iommu_rwbf(struct pci_dev *dev)
|
||||
|
||||
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2a40, quirk_iommu_rwbf);
|
||||
|
||||
+/* https://bugzilla.redhat.com/show_bug.cgi?id=605888 */
|
||||
+static void __devinit quirk_ricoh_multifunction(struct pci_dev *dev)
|
||||
+{
|
||||
+ printk(KERN_INFO "intel_iommu: broken Ricoh device %04X detected, disabling...\n",
|
||||
+ dev->device);
|
||||
+ dmar_disabled = 1;
|
||||
+}
|
||||
+DECLARE_PCI_FIXUP_HEADER(0x1180, 0xe822, quirk_ricoh_multifunction);
|
||||
+DECLARE_PCI_FIXUP_HEADER(0x1180, 0xe230, quirk_ricoh_multifunction);
|
||||
+DECLARE_PCI_FIXUP_HEADER(0x1180, 0xe832, quirk_ricoh_multifunction);
|
||||
+DECLARE_PCI_FIXUP_HEADER(0x1180, 0xe476, quirk_ricoh_multifunction);
|
||||
+
|
||||
/* On Tylersburg chipsets, some BIOSes have been known to enable the
|
||||
ISOCH DMAR unit for the Azalia sound device, but not give it any
|
||||
TLB entries, which causes it to deadlock. Check for that. We do
|
||||
--
|
||||
1.7.3.1
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
From 9fa9e790eb301bade8fe4ea0fd9ecb72617f0928 Mon Sep 17 00:00:00 2001
|
||||
From: Francisco Jerez <currojerez@riseup.net>
|
||||
Date: Thu, 5 Aug 2010 22:57:08 +0200
|
||||
Subject: [PATCH 3/5] drm-i2c-ch7006-fix
|
||||
|
||||
drm/i2c/ch7006: Don't use POWER_LEVEL_FULL_POWER_OFF on early chip versions.
|
||||
|
||||
Signed-off-by: Francisco Jerez <currojerez@riseup.net>
|
||||
---
|
||||
drivers/gpu/drm/i2c/ch7006_drv.c | 1 +
|
||||
drivers/gpu/drm/i2c/ch7006_mode.c | 5 ++++-
|
||||
drivers/gpu/drm/i2c/ch7006_priv.h | 1 +
|
||||
3 files changed, 6 insertions(+), 1 deletions(-)
|
||||
|
||||
diff --git a/drivers/gpu/drm/i2c/ch7006_drv.c b/drivers/gpu/drm/i2c/ch7006_drv.c
|
||||
index 81681a0..8c760c7 100644
|
||||
--- a/drivers/gpu/drm/i2c/ch7006_drv.c
|
||||
+++ b/drivers/gpu/drm/i2c/ch7006_drv.c
|
||||
@@ -454,6 +454,7 @@ static int ch7006_encoder_init(struct i2c_client *client,
|
||||
priv->hmargin = 50;
|
||||
priv->vmargin = 50;
|
||||
priv->last_dpms = -1;
|
||||
+ priv->chip_version = ch7006_read(client, CH7006_VERSION_ID);
|
||||
|
||||
if (ch7006_tv_norm) {
|
||||
for (i = 0; i < NUM_TV_NORMS; i++) {
|
||||
diff --git a/drivers/gpu/drm/i2c/ch7006_mode.c b/drivers/gpu/drm/i2c/ch7006_mode.c
|
||||
index e447dfb..c860f24 100644
|
||||
--- a/drivers/gpu/drm/i2c/ch7006_mode.c
|
||||
+++ b/drivers/gpu/drm/i2c/ch7006_mode.c
|
||||
@@ -316,7 +316,10 @@ void ch7006_setup_power_state(struct drm_encoder *encoder)
|
||||
}
|
||||
|
||||
} else {
|
||||
- *power |= bitfs(CH7006_POWER_LEVEL, FULL_POWER_OFF);
|
||||
+ if (priv->chip_version >= 0x20)
|
||||
+ *power |= bitfs(CH7006_POWER_LEVEL, FULL_POWER_OFF);
|
||||
+ else
|
||||
+ *power |= bitfs(CH7006_POWER_LEVEL, POWER_OFF);
|
||||
}
|
||||
}
|
||||
|
||||
diff --git a/drivers/gpu/drm/i2c/ch7006_priv.h b/drivers/gpu/drm/i2c/ch7006_priv.h
|
||||
index b06d3d9..9487123 100644
|
||||
--- a/drivers/gpu/drm/i2c/ch7006_priv.h
|
||||
+++ b/drivers/gpu/drm/i2c/ch7006_priv.h
|
||||
@@ -95,6 +95,7 @@ struct ch7006_priv {
|
||||
int flicker;
|
||||
int scale;
|
||||
|
||||
+ int chip_version;
|
||||
int last_dpms;
|
||||
};
|
||||
|
||||
--
|
||||
1.7.2
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
https://bugzilla.redhat.com/show_bug.cgi?id=639146
|
||||
|
||||
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
|
||||
index ce8ff0e..3bbd2c4 100644
|
||||
--- a/drivers/gpu/drm/i915/i915_dma.c
|
||||
+++ b/drivers/gpu/drm/i915/i915_dma.c
|
||||
@@ -1353,6 +1353,27 @@ static bool i915_switcheroo_can_switch(struct pci_dev *pdev)
|
||||
return can_switch;
|
||||
}
|
||||
|
||||
+/* check the VBT to see whether the eDP is on DP-D port */
|
||||
+static bool intel_dpd_is_edp(struct drm_device *dev)
|
||||
+{
|
||||
+ struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
+ struct child_device_config *p_child;
|
||||
+ int i;
|
||||
+
|
||||
+ if (!dev_priv->child_dev_num)
|
||||
+ return false;
|
||||
+
|
||||
+ for (i = 0; i < dev_priv->child_dev_num; i++) {
|
||||
+ p_child = dev_priv->child_dev + i;
|
||||
+
|
||||
+ if (p_child->dvo_port == PORT_IDPD &&
|
||||
+ p_child->device_type == DEVICE_TYPE_eDP)
|
||||
+ return true;
|
||||
+ }
|
||||
+
|
||||
+ return false;
|
||||
+}
|
||||
+
|
||||
static int i915_load_modeset_init(struct drm_device *dev,
|
||||
unsigned long prealloc_start,
|
||||
unsigned long prealloc_size,
|
||||
@@ -1409,6 +1430,15 @@ static int i915_load_modeset_init(struct drm_device *dev,
|
||||
if (ret)
|
||||
DRM_INFO("failed to find VBIOS tables\n");
|
||||
|
||||
+ /* XXX: eDP doesn't even work in git HEAD,
|
||||
+ * bail out and pray that text mode still works...
|
||||
+ */
|
||||
+ if (intel_dpd_is_edp(dev)) {
|
||||
+ DRM_ERROR("eDP support is currently non-functional, please boot with \"nomodeset xdriver=vesa\"\n");
|
||||
+ ret = -EINVAL;
|
||||
+ goto cleanup_ringbuffer;
|
||||
+ }
|
||||
+
|
||||
/* if we have > 1 VGA cards, then disable the radeon VGA resources */
|
||||
ret = vga_client_register(dev->pdev, dev, NULL, i915_vga_set_decode);
|
||||
if (ret)
|
|
@ -0,0 +1,89 @@
|
|||
From ce9d419dbecc292cc3e06e8b1d6d123d3fa813a4 Mon Sep 17 00:00:00 2001
|
||||
From: Chris Wilson <chris@chris-wilson.co.uk>
|
||||
Date: Sun, 26 Sep 2010 20:50:05 +0100
|
||||
Subject: drm/i915: Sanity check pread/pwrite
|
||||
|
||||
From: Chris Wilson <chris@chris-wilson.co.uk>
|
||||
|
||||
commit ce9d419dbecc292cc3e06e8b1d6d123d3fa813a4 upstream.
|
||||
|
||||
Move the access control up from the fast paths, which are no longer
|
||||
universally taken first, up into the caller. This then duplicates some
|
||||
sanity checking along the slow paths, but is much simpler.
|
||||
Tracked as CVE-2010-2962.
|
||||
|
||||
Reported-by: Kees Cook <kees@ubuntu.com>
|
||||
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
|
||||
|
||||
---
|
||||
drivers/gpu/drm/i915/i915_gem.c | 28 ++++++++++++++++++++--------
|
||||
1 file changed, 20 insertions(+), 8 deletions(-)
|
||||
|
||||
--- a/drivers/gpu/drm/i915/i915_gem.c
|
||||
+++ b/drivers/gpu/drm/i915/i915_gem.c
|
||||
@@ -465,8 +465,15 @@ i915_gem_pread_ioctl(struct drm_device *
|
||||
*/
|
||||
if (args->offset > obj->size || args->size > obj->size ||
|
||||
args->offset + args->size > obj->size) {
|
||||
- drm_gem_object_unreference_unlocked(obj);
|
||||
- return -EINVAL;
|
||||
+ ret = -EINVAL;
|
||||
+ goto err;
|
||||
+ }
|
||||
+
|
||||
+ if (!access_ok(VERIFY_WRITE,
|
||||
+ (char __user *)(uintptr_t)args->data_ptr,
|
||||
+ args->size)) {
|
||||
+ ret = -EFAULT;
|
||||
+ goto err;
|
||||
}
|
||||
|
||||
if (i915_gem_object_needs_bit17_swizzle(obj)) {
|
||||
@@ -478,8 +485,8 @@ i915_gem_pread_ioctl(struct drm_device *
|
||||
file_priv);
|
||||
}
|
||||
|
||||
+err:
|
||||
drm_gem_object_unreference_unlocked(obj);
|
||||
-
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -568,8 +575,6 @@ i915_gem_gtt_pwrite_fast(struct drm_devi
|
||||
|
||||
user_data = (char __user *) (uintptr_t) args->data_ptr;
|
||||
remain = args->size;
|
||||
- if (!access_ok(VERIFY_READ, user_data, remain))
|
||||
- return -EFAULT;
|
||||
|
||||
|
||||
mutex_lock(&dev->struct_mutex);
|
||||
@@ -928,8 +933,15 @@ i915_gem_pwrite_ioctl(struct drm_device
|
||||
*/
|
||||
if (args->offset > obj->size || args->size > obj->size ||
|
||||
args->offset + args->size > obj->size) {
|
||||
- drm_gem_object_unreference_unlocked(obj);
|
||||
- return -EINVAL;
|
||||
+ ret = -EINVAL;
|
||||
+ goto err;
|
||||
+ }
|
||||
+
|
||||
+ if (!access_ok(VERIFY_READ,
|
||||
+ (char __user *)(uintptr_t)args->data_ptr,
|
||||
+ args->size)) {
|
||||
+ ret = -EFAULT;
|
||||
+ goto err;
|
||||
}
|
||||
|
||||
/* We can only do the GTT pwrite on untiled buffers, as otherwise
|
||||
@@ -963,8 +975,8 @@ i915_gem_pwrite_ioctl(struct drm_device
|
||||
DRM_INFO("pwrite failed %d\n", ret);
|
||||
#endif
|
||||
|
||||
+err:
|
||||
drm_gem_object_unreference_unlocked(obj);
|
||||
-
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
From 8f51b07995c55369bfd27921ef10b76c2b203fe8 Mon Sep 17 00:00:00 2001
|
||||
From: Ben Skeggs <bskeggs@redhat.com>
|
||||
Date: Tue, 17 Aug 2010 14:20:29 +1000
|
||||
Subject: [PATCH] drm-nouveau-nv50-crtc-update-delay
|
||||
|
||||
rhbz#614552
|
||||
|
||||
Adds a short delay before doing framebuffer-only CRTC updates. Fixes
|
||||
an issue that effects some cards (Quadro NVS295/FX580) where two of
|
||||
these updates in quick succession hangs the display engine.
|
||||
|
||||
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
|
||||
---
|
||||
drivers/gpu/drm/nouveau/nv50_crtc.c | 3 +++
|
||||
1 files changed, 3 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/drivers/gpu/drm/nouveau/nv50_crtc.c b/drivers/gpu/drm/nouveau/nv50_crtc.c
|
||||
index 2423c92..5c2aa1e 100644
|
||||
--- a/drivers/gpu/drm/nouveau/nv50_crtc.c
|
||||
+++ b/drivers/gpu/drm/nouveau/nv50_crtc.c
|
||||
@@ -540,6 +540,9 @@ nv50_crtc_do_mode_set_base(struct drm_crtc *crtc, int x, int y,
|
||||
nouveau_bo_unpin(ofb->nvbo);
|
||||
}
|
||||
|
||||
+ if (update)
|
||||
+ mdelay(1);
|
||||
+
|
||||
nv_crtc->fb.offset = fb->nvbo->bo.offset - dev_priv->vm_vram_base;
|
||||
nv_crtc->fb.tile_flags = fb->nvbo->tile_flags;
|
||||
nv_crtc->fb.cpp = drm_fb->bits_per_pixel / 8;
|
||||
--
|
||||
1.7.3.1
|
||||
|
|
@ -0,0 +1,231 @@
|
|||
From e7e3837f6395e44b5b5fb7cdbcccaba5baf76803 Mon Sep 17 00:00:00 2001
|
||||
From: Ben Skeggs <bskeggs@redhat.com>
|
||||
Date: Fri, 22 Oct 2010 10:26:24 +1000
|
||||
Subject: [PATCH] drm-nouveau-nv86-bug
|
||||
|
||||
drm/nv50: implement possible workaround for NV86 PGRAPH TLB flush hang
|
||||
|
||||
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
|
||||
---
|
||||
drivers/gpu/drm/nouveau/nouveau_drv.h | 5 +++
|
||||
drivers/gpu/drm/nouveau/nouveau_mem.c | 14 +++-----
|
||||
drivers/gpu/drm/nouveau/nouveau_sgdma.c | 8 ++--
|
||||
drivers/gpu/drm/nouveau/nouveau_state.c | 10 ++++++
|
||||
drivers/gpu/drm/nouveau/nv50_fifo.c | 5 +++
|
||||
drivers/gpu/drm/nouveau/nv50_graph.c | 52 +++++++++++++++++++++++++++++++
|
||||
drivers/gpu/drm/nouveau/nv50_instmem.c | 1 -
|
||||
7 files changed, 82 insertions(+), 13 deletions(-)
|
||||
|
||||
diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h
|
||||
index be53e92..4273390 100644
|
||||
--- a/drivers/gpu/drm/nouveau/nouveau_drv.h
|
||||
+++ b/drivers/gpu/drm/nouveau/nouveau_drv.h
|
||||
@@ -304,6 +304,7 @@ struct nouveau_fifo_engine {
|
||||
void (*destroy_context)(struct nouveau_channel *);
|
||||
int (*load_context)(struct nouveau_channel *);
|
||||
int (*unload_context)(struct drm_device *);
|
||||
+ void (*tlb_flush)(struct drm_device *dev);
|
||||
};
|
||||
|
||||
struct nouveau_pgraph_object_method {
|
||||
@@ -336,6 +337,7 @@ struct nouveau_pgraph_engine {
|
||||
void (*destroy_context)(struct nouveau_channel *);
|
||||
int (*load_context)(struct nouveau_channel *);
|
||||
int (*unload_context)(struct drm_device *);
|
||||
+ void (*tlb_flush)(struct drm_device *dev);
|
||||
|
||||
void (*set_region_tiling)(struct drm_device *dev, int i, uint32_t addr,
|
||||
uint32_t size, uint32_t pitch);
|
||||
@@ -944,6 +946,7 @@ extern int nv50_fifo_create_context(struct nouveau_channel *);
|
||||
extern void nv50_fifo_destroy_context(struct nouveau_channel *);
|
||||
extern int nv50_fifo_load_context(struct nouveau_channel *);
|
||||
extern int nv50_fifo_unload_context(struct drm_device *);
|
||||
+extern void nv50_fifo_tlb_flush(struct drm_device *dev);
|
||||
|
||||
/* nvc0_fifo.c */
|
||||
extern int nvc0_fifo_init(struct drm_device *);
|
||||
@@ -1021,6 +1024,8 @@ extern int nv50_graph_load_context(struct nouveau_channel *);
|
||||
extern int nv50_graph_unload_context(struct drm_device *);
|
||||
extern void nv50_graph_context_switch(struct drm_device *);
|
||||
extern int nv50_grctx_init(struct nouveau_grctx *);
|
||||
+extern void nv50_graph_tlb_flush(struct drm_device *dev);
|
||||
+extern void nv86_graph_tlb_flush(struct drm_device *dev);
|
||||
|
||||
/* nvc0_graph.c */
|
||||
extern int nvc0_graph_init(struct drm_device *);
|
||||
diff --git a/drivers/gpu/drm/nouveau/nouveau_mem.c b/drivers/gpu/drm/nouveau/nouveau_mem.c
|
||||
index 4f0ae39..514ad9f 100644
|
||||
--- a/drivers/gpu/drm/nouveau/nouveau_mem.c
|
||||
+++ b/drivers/gpu/drm/nouveau/nouveau_mem.c
|
||||
@@ -173,11 +173,10 @@ nv50_mem_vm_bind_linear(struct drm_device *dev, uint64_t virt, uint32_t size,
|
||||
}
|
||||
}
|
||||
}
|
||||
- dev_priv->engine.instmem.flush(dev);
|
||||
|
||||
- nv50_vm_flush(dev, 5);
|
||||
- nv50_vm_flush(dev, 0);
|
||||
- nv50_vm_flush(dev, 4);
|
||||
+ dev_priv->engine.instmem.flush(dev);
|
||||
+ dev_priv->engine.fifo.tlb_flush(dev);
|
||||
+ dev_priv->engine.graph.tlb_flush(dev);
|
||||
nv50_vm_flush(dev, 6);
|
||||
return 0;
|
||||
}
|
||||
@@ -207,11 +206,10 @@ nv50_mem_vm_unbind(struct drm_device *dev, uint64_t virt, uint32_t size)
|
||||
pte++;
|
||||
}
|
||||
}
|
||||
- dev_priv->engine.instmem.flush(dev);
|
||||
|
||||
- nv50_vm_flush(dev, 5);
|
||||
- nv50_vm_flush(dev, 0);
|
||||
- nv50_vm_flush(dev, 4);
|
||||
+ dev_priv->engine.instmem.flush(dev);
|
||||
+ dev_priv->engine.fifo.tlb_flush(dev);
|
||||
+ dev_priv->engine.graph.tlb_flush(dev);
|
||||
nv50_vm_flush(dev, 6);
|
||||
}
|
||||
|
||||
diff --git a/drivers/gpu/drm/nouveau/nouveau_sgdma.c b/drivers/gpu/drm/nouveau/nouveau_sgdma.c
|
||||
index 7f028fe..d55a583 100644
|
||||
--- a/drivers/gpu/drm/nouveau/nouveau_sgdma.c
|
||||
+++ b/drivers/gpu/drm/nouveau/nouveau_sgdma.c
|
||||
@@ -120,8 +120,8 @@ nouveau_sgdma_bind(struct ttm_backend *be, struct ttm_mem_reg *mem)
|
||||
dev_priv->engine.instmem.flush(nvbe->dev);
|
||||
|
||||
if (dev_priv->card_type == NV_50) {
|
||||
- nv50_vm_flush(dev, 5); /* PGRAPH */
|
||||
- nv50_vm_flush(dev, 0); /* PFIFO */
|
||||
+ dev_priv->engine.fifo.tlb_flush(dev);
|
||||
+ dev_priv->engine.graph.tlb_flush(dev);
|
||||
}
|
||||
|
||||
nvbe->bound = true;
|
||||
@@ -162,8 +162,8 @@ nouveau_sgdma_unbind(struct ttm_backend *be)
|
||||
dev_priv->engine.instmem.flush(nvbe->dev);
|
||||
|
||||
if (dev_priv->card_type == NV_50) {
|
||||
- nv50_vm_flush(dev, 5);
|
||||
- nv50_vm_flush(dev, 0);
|
||||
+ dev_priv->engine.fifo.tlb_flush(dev);
|
||||
+ dev_priv->engine.graph.tlb_flush(dev);
|
||||
}
|
||||
|
||||
nvbe->bound = false;
|
||||
diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c
|
||||
index be85960..47c353c 100644
|
||||
--- a/drivers/gpu/drm/nouveau/nouveau_state.c
|
||||
+++ b/drivers/gpu/drm/nouveau/nouveau_state.c
|
||||
@@ -333,6 +333,15 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
|
||||
engine->graph.destroy_context = nv50_graph_destroy_context;
|
||||
engine->graph.load_context = nv50_graph_load_context;
|
||||
engine->graph.unload_context = nv50_graph_unload_context;
|
||||
+ if (dev_priv->chipset != 0x86)
|
||||
+ engine->graph.tlb_flush = nv50_graph_tlb_flush;
|
||||
+ else {
|
||||
+ /* from what i can see nvidia do this on every
|
||||
+ * pre-NVA3 board except NVAC, but, we've only
|
||||
+ * ever seen problems on NV86
|
||||
+ */
|
||||
+ engine->graph.tlb_flush = nv86_graph_tlb_flush;
|
||||
+ }
|
||||
engine->fifo.channels = 128;
|
||||
engine->fifo.init = nv50_fifo_init;
|
||||
engine->fifo.takedown = nv50_fifo_takedown;
|
||||
@@ -344,6 +353,7 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
|
||||
engine->fifo.destroy_context = nv50_fifo_destroy_context;
|
||||
engine->fifo.load_context = nv50_fifo_load_context;
|
||||
engine->fifo.unload_context = nv50_fifo_unload_context;
|
||||
+ engine->fifo.tlb_flush = nv50_fifo_tlb_flush;
|
||||
engine->display.early_init = nv50_display_early_init;
|
||||
engine->display.late_takedown = nv50_display_late_takedown;
|
||||
engine->display.create = nv50_display_create;
|
||||
diff --git a/drivers/gpu/drm/nouveau/nv50_fifo.c b/drivers/gpu/drm/nouveau/nv50_fifo.c
|
||||
index a46a961..1da65bd 100644
|
||||
--- a/drivers/gpu/drm/nouveau/nv50_fifo.c
|
||||
+++ b/drivers/gpu/drm/nouveau/nv50_fifo.c
|
||||
@@ -464,3 +464,8 @@ nv50_fifo_unload_context(struct drm_device *dev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
+void
|
||||
+nv50_fifo_tlb_flush(struct drm_device *dev)
|
||||
+{
|
||||
+ nv50_vm_flush(dev, 5);
|
||||
+}
|
||||
diff --git a/drivers/gpu/drm/nouveau/nv50_graph.c b/drivers/gpu/drm/nouveau/nv50_graph.c
|
||||
index cbf5ae2..8b669d0 100644
|
||||
--- a/drivers/gpu/drm/nouveau/nv50_graph.c
|
||||
+++ b/drivers/gpu/drm/nouveau/nv50_graph.c
|
||||
@@ -402,3 +402,55 @@ struct nouveau_pgraph_object_class nv50_graph_grclass[] = {
|
||||
{ 0x8597, false, NULL }, /* tesla (nva3, nva5, nva8) */
|
||||
{}
|
||||
};
|
||||
+
|
||||
+void
|
||||
+nv50_graph_tlb_flush(struct drm_device *dev)
|
||||
+{
|
||||
+ nv50_vm_flush(dev, 0);
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+nv86_graph_tlb_flush(struct drm_device *dev)
|
||||
+{
|
||||
+ struct drm_nouveau_private *dev_priv = dev->dev_private;
|
||||
+ struct nouveau_timer_engine *ptimer = &dev_priv->engine.timer;
|
||||
+ bool idle, timeout = false;
|
||||
+ unsigned long flags;
|
||||
+ u64 start;
|
||||
+ u32 tmp;
|
||||
+
|
||||
+ spin_lock_irqsave(&dev_priv->context_switch_lock, flags);
|
||||
+ nv_mask(dev, 0x400500, 0x00000001, 0x00000000);
|
||||
+
|
||||
+ start = ptimer->read(dev);
|
||||
+ do {
|
||||
+ idle = true;
|
||||
+
|
||||
+ for (tmp = nv_rd32(dev, 0x400380); tmp && idle; tmp >>= 3) {
|
||||
+ if ((tmp & 7) == 1)
|
||||
+ idle = false;
|
||||
+ }
|
||||
+
|
||||
+ for (tmp = nv_rd32(dev, 0x400384); tmp && idle; tmp >>= 3) {
|
||||
+ if ((tmp & 7) == 1)
|
||||
+ idle = false;
|
||||
+ }
|
||||
+
|
||||
+ for (tmp = nv_rd32(dev, 0x400388); tmp && idle; tmp >>= 3) {
|
||||
+ if ((tmp & 7) == 1)
|
||||
+ idle = false;
|
||||
+ }
|
||||
+ } while (!idle && !(timeout = ptimer->read(dev) - start > 2000000000));
|
||||
+
|
||||
+ if (timeout) {
|
||||
+ NV_ERROR(dev, "PGRAPH TLB flush idle timeout fail: "
|
||||
+ "0x%08x 0x%08x 0x%08x 0x%08x\n",
|
||||
+ nv_rd32(dev, 0x400700), nv_rd32(dev, 0x400380),
|
||||
+ nv_rd32(dev, 0x400384), nv_rd32(dev, 0x400388));
|
||||
+ }
|
||||
+
|
||||
+ nv50_vm_flush(dev, 0);
|
||||
+
|
||||
+ nv_mask(dev, 0x400500, 0x00000001, 0x00000001);
|
||||
+ spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags);
|
||||
+}
|
||||
diff --git a/drivers/gpu/drm/nouveau/nv50_instmem.c b/drivers/gpu/drm/nouveau/nv50_instmem.c
|
||||
index ac3de05..c836ddc 100644
|
||||
--- a/drivers/gpu/drm/nouveau/nv50_instmem.c
|
||||
+++ b/drivers/gpu/drm/nouveau/nv50_instmem.c
|
||||
@@ -402,7 +402,6 @@ nv50_instmem_bind(struct drm_device *dev, struct nouveau_gpuobj *gpuobj)
|
||||
}
|
||||
dev_priv->engine.instmem.flush(dev);
|
||||
|
||||
- nv50_vm_flush(dev, 4);
|
||||
nv50_vm_flush(dev, 6);
|
||||
|
||||
gpuobj->im_bound = 1;
|
||||
--
|
||||
1.7.3.1
|
||||
|
|
@ -0,0 +1,106 @@
|
|||
From 07a51882863d9e45b0715dcffbb66491adf2fb4e Mon Sep 17 00:00:00 2001
|
||||
From: Ben Skeggs <bskeggs@redhat.com>
|
||||
Date: Wed, 30 Jun 2010 13:34:05 +1000
|
||||
Subject: [PATCH] drm/nouveau: disable acceleration on NVA3/NVA5/NVA8 by default
|
||||
|
||||
There's an GPU lockup problem for which the cause is currently unknown
|
||||
on these chipsets.
|
||||
|
||||
Until it's resolved, it's better to leave the user with a working system
|
||||
without acceleration than to have random lockups.
|
||||
|
||||
With this patch, acceleration will be off by default if a known problem
|
||||
chipset is detected, but can be re-enabled with nouveau.noaccel=0 on
|
||||
the kernel commandline.
|
||||
|
||||
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
|
||||
---
|
||||
drivers/gpu/drm/nouveau/nouveau_drv.c | 2 +-
|
||||
drivers/gpu/drm/nouveau/nouveau_drv.h | 1 +
|
||||
drivers/gpu/drm/nouveau/nouveau_state.c | 23 +++++++++++++++++++----
|
||||
3 files changed, 21 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.c b/drivers/gpu/drm/nouveau/nouveau_drv.c
|
||||
index 946748a..9b69328 100644
|
||||
--- a/drivers/gpu/drm/nouveau/nouveau_drv.c
|
||||
+++ b/drivers/gpu/drm/nouveau/nouveau_drv.c
|
||||
@@ -72,7 +72,7 @@ int nouveau_ignorelid = 0;
|
||||
module_param_named(ignorelid, nouveau_ignorelid, int, 0400);
|
||||
|
||||
MODULE_PARM_DESC(noaccel, "Disable all acceleration");
|
||||
-int nouveau_noaccel = 0;
|
||||
+int nouveau_noaccel = -1;
|
||||
module_param_named(noaccel, nouveau_noaccel, int, 0400);
|
||||
|
||||
MODULE_PARM_DESC(nofbaccel, "Disable fbcon acceleration");
|
||||
diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h
|
||||
index 24b3d03..0cf1bee 100644
|
||||
--- a/drivers/gpu/drm/nouveau/nouveau_drv.h
|
||||
+++ b/drivers/gpu/drm/nouveau/nouveau_drv.h
|
||||
@@ -504,6 +504,7 @@ enum nouveau_card_type {
|
||||
|
||||
struct drm_nouveau_private {
|
||||
struct drm_device *dev;
|
||||
+ bool noaccel;
|
||||
|
||||
/* the card type, takes NV_* as values */
|
||||
enum nouveau_card_type card_type;
|
||||
diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c
|
||||
index be85960..896f6ae 100644
|
||||
--- a/drivers/gpu/drm/nouveau/nouveau_state.c
|
||||
+++ b/drivers/gpu/drm/nouveau/nouveau_state.c
|
||||
@@ -563,7 +563,7 @@ nouveau_card_init(struct drm_device *dev)
|
||||
if (ret)
|
||||
goto out_timer;
|
||||
|
||||
- if (nouveau_noaccel)
|
||||
+ if (dev_priv->noaccel)
|
||||
engine->graph.accel_blocked = true;
|
||||
else {
|
||||
/* PGRAPH */
|
||||
@@ -613,10 +613,10 @@ out_irq:
|
||||
out_display:
|
||||
engine->display.destroy(dev);
|
||||
out_fifo:
|
||||
- if (!nouveau_noaccel)
|
||||
+ if (!dev_priv->noaccel)
|
||||
engine->fifo.takedown(dev);
|
||||
out_graph:
|
||||
- if (!nouveau_noaccel)
|
||||
+ if (!dev_priv->noaccel)
|
||||
engine->graph.takedown(dev);
|
||||
out_fb:
|
||||
engine->fb.takedown(dev);
|
||||
@@ -655,7 +655,7 @@ static void nouveau_card_takedown(struct drm_device *dev)
|
||||
dev_priv->channel = NULL;
|
||||
}
|
||||
|
||||
- if (!nouveau_noaccel) {
|
||||
+ if (!dev_priv->noaccel) {
|
||||
engine->fifo.takedown(dev);
|
||||
engine->graph.takedown(dev);
|
||||
}
|
||||
@@ -861,6 +861,21 @@ int nouveau_load(struct drm_device *dev, unsigned long flags)
|
||||
if (ret)
|
||||
goto err_mmio;
|
||||
|
||||
+ if (nouveau_noaccel == -1) {
|
||||
+ switch (dev_priv->chipset) {
|
||||
+ case 0xa3:
|
||||
+ case 0xa5:
|
||||
+ case 0xa8:
|
||||
+ dev_priv->noaccel = true;
|
||||
+ break;
|
||||
+ default:
|
||||
+ dev_priv->noaccel = false;
|
||||
+ break;
|
||||
+ }
|
||||
+ } else {
|
||||
+ dev_priv->noaccel = (nouveau_noaccel != 0);
|
||||
+ }
|
||||
+
|
||||
/* Map PRAMIN BAR, or on older cards, the aperture withing BAR0 */
|
||||
if (dev_priv->card_type >= NV_40) {
|
||||
int ramin_bar = 2;
|
||||
--
|
||||
1.7.2.2
|
|
@ -0,0 +1,141 @@
|
|||
From 4733f633c4bfb0672d5bd88a8d19a03e27a3c1d0 Mon Sep 17 00:00:00 2001
|
||||
From: Ben Skeggs <bskeggs@redhat.com>
|
||||
Date: Fri, 23 Jul 2010 09:06:52 +1000
|
||||
Subject: [PATCH 2/2] drm-nouveau-race-fix
|
||||
|
||||
drm/nouveau: fix race condition when under memory pressure
|
||||
|
||||
rhbz#602663
|
||||
|
||||
When VRAM is running out it's possible that the client's push buffers get
|
||||
evicted to main memory. When they're validated back in, the GPU may
|
||||
be used for the copy back to VRAM, but the existing synchronisation code
|
||||
only deals with inter-channel sync, not sync between PFIFO and PGRAPH on
|
||||
the same channel. This leads to PFIFO fetching from command buffers that
|
||||
haven't quite been copied by PGRAPH yet.
|
||||
|
||||
This patch marks push buffers as so, and forces any GPU-assisted buffer
|
||||
moves to be done on a different channel, which triggers the correct
|
||||
synchronisation to happen before we submit them.
|
||||
|
||||
After discussion with another nouveau developer, it was agreed that while
|
||||
this patch is fine in itself, that we'd prefer to work out a nicer, but
|
||||
likely much more invasive, fix upstream.
|
||||
|
||||
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
|
||||
---
|
||||
drivers/gpu/drm/nouveau/nouveau_bo.c | 15 +++++++++++++
|
||||
drivers/gpu/drm/nouveau/nouveau_drv.h | 1 +
|
||||
drivers/gpu/drm/nouveau/nouveau_gem.c | 36 +++++++++++++++++++++++---------
|
||||
3 files changed, 42 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c
|
||||
index 553a01d..5e62d1b 100644
|
||||
--- a/drivers/gpu/drm/nouveau/nouveau_bo.c
|
||||
+++ b/drivers/gpu/drm/nouveau/nouveau_bo.c
|
||||
@@ -36,6 +36,21 @@
|
||||
#include <linux/log2.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
+int
|
||||
+nouveau_bo_sync_gpu(struct nouveau_bo *nvbo, struct nouveau_channel *chan)
|
||||
+{
|
||||
+ struct nouveau_fence *prev_fence = nvbo->bo.sync_obj;
|
||||
+ int ret;
|
||||
+
|
||||
+ if (!prev_fence || nouveau_fence_channel(prev_fence) == chan)
|
||||
+ return 0;
|
||||
+
|
||||
+ spin_lock(&nvbo->bo.lock);
|
||||
+ ret = ttm_bo_wait(&nvbo->bo, false, false, false);
|
||||
+ spin_unlock(&nvbo->bo.lock);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
static void
|
||||
nouveau_bo_del_ttm(struct ttm_buffer_object *bo)
|
||||
{
|
||||
diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h
|
||||
index 2eb622b..70a16f3 100644
|
||||
--- a/drivers/gpu/drm/nouveau/nouveau_drv.h
|
||||
+++ b/drivers/gpu/drm/nouveau/nouveau_drv.h
|
||||
@@ -1167,6 +1167,7 @@ extern u16 nouveau_bo_rd16(struct nouveau_bo *nvbo, unsigned index);
|
||||
extern void nouveau_bo_wr16(struct nouveau_bo *nvbo, unsigned index, u16 val);
|
||||
extern u32 nouveau_bo_rd32(struct nouveau_bo *nvbo, unsigned index);
|
||||
extern void nouveau_bo_wr32(struct nouveau_bo *nvbo, unsigned index, u32 val);
|
||||
+extern int nouveau_bo_sync_gpu(struct nouveau_bo *, struct nouveau_channel *);
|
||||
|
||||
/* nouveau_fence.c */
|
||||
struct nouveau_fence;
|
||||
diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c b/drivers/gpu/drm/nouveau/nouveau_gem.c
|
||||
index 62ac673..613f878 100644
|
||||
--- a/drivers/gpu/drm/nouveau/nouveau_gem.c
|
||||
+++ b/drivers/gpu/drm/nouveau/nouveau_gem.c
|
||||
@@ -361,16 +361,11 @@ validate_list(struct nouveau_channel *chan, struct list_head *list,
|
||||
|
||||
list_for_each_entry(nvbo, list, entry) {
|
||||
struct drm_nouveau_gem_pushbuf_bo *b = &pbbo[nvbo->pbbo_index];
|
||||
- struct nouveau_fence *prev_fence = nvbo->bo.sync_obj;
|
||||
|
||||
- if (prev_fence && nouveau_fence_channel(prev_fence) != chan) {
|
||||
- spin_lock(&nvbo->bo.lock);
|
||||
- ret = ttm_bo_wait(&nvbo->bo, false, false, false);
|
||||
- spin_unlock(&nvbo->bo.lock);
|
||||
- if (unlikely(ret)) {
|
||||
- NV_ERROR(dev, "fail wait other chan\n");
|
||||
- return ret;
|
||||
- }
|
||||
+ ret = nouveau_bo_sync_gpu(nvbo, chan);
|
||||
+ if (unlikely(ret)) {
|
||||
+ NV_ERROR(dev, "fail pre-validate sync\n");
|
||||
+ return ret;
|
||||
}
|
||||
|
||||
ret = nouveau_gem_set_domain(nvbo->gem, b->read_domains,
|
||||
@@ -381,7 +376,7 @@ validate_list(struct nouveau_channel *chan, struct list_head *list,
|
||||
return ret;
|
||||
}
|
||||
|
||||
- nvbo->channel = chan;
|
||||
+ nvbo->channel = (b->read_domains & (1 << 31)) ? NULL : chan;
|
||||
ret = ttm_bo_validate(&nvbo->bo, &nvbo->placement,
|
||||
false, false, false);
|
||||
nvbo->channel = NULL;
|
||||
@@ -390,6 +385,12 @@ validate_list(struct nouveau_channel *chan, struct list_head *list,
|
||||
return ret;
|
||||
}
|
||||
|
||||
+ ret = nouveau_bo_sync_gpu(nvbo, chan);
|
||||
+ if (unlikely(ret)) {
|
||||
+ NV_ERROR(dev, "fail post-validate sync\n");
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
if (nvbo->bo.offset == b->presumed.offset &&
|
||||
((nvbo->bo.mem.mem_type == TTM_PL_VRAM &&
|
||||
b->presumed.domain & NOUVEAU_GEM_DOMAIN_VRAM) ||
|
||||
@@ -615,6 +616,21 @@ nouveau_gem_ioctl_pushbuf(struct drm_device *dev, void *data,
|
||||
|
||||
mutex_lock(&dev->struct_mutex);
|
||||
|
||||
+ /* Mark push buffers as being used on PFIFO, the validation code
|
||||
+ * will then make sure that if the pushbuf bo moves, that they
|
||||
+ * happen on the kernel channel, which will in turn cause a sync
|
||||
+ * to happen before we try and submit the push buffer.
|
||||
+ */
|
||||
+ for (i = 0; i < req->nr_push; i++) {
|
||||
+ if (push[i].bo_index >= req->nr_buffers) {
|
||||
+ NV_ERROR(dev, "push %d buffer not in list\n", i);
|
||||
+ ret = -EINVAL;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ bo[push[i].bo_index].read_domains |= (1 << 31);
|
||||
+ }
|
||||
+
|
||||
/* Validate buffer list */
|
||||
ret = nouveau_gem_pushbuf_validate(chan, file_priv, bo, req->buffers,
|
||||
req->nr_buffers, &op, &do_reloc);
|
||||
--
|
||||
1.7.2.2
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,592 @@
|
|||
From f1719f0dcd68ca4de42c7b00ef2b37658007dda7 Mon Sep 17 00:00:00 2001
|
||||
From: Francisco Jerez <currojerez@riseup.net>
|
||||
Date: Thu, 22 Jul 2010 17:06:18 +0200
|
||||
Subject: [PATCH 2/5] drm-sil164-module
|
||||
|
||||
drm: Import driver for the sil164 I2C TMDS transmitter.
|
||||
|
||||
sil164 transmitters are used for DVI outputs on Intel/nvidia and ATI setups.
|
||||
|
||||
So far only nouveau can use this driver.
|
||||
|
||||
Signed-off-by: Francisco Jerez <currojerez@riseup.net>
|
||||
Tested-by: Patrice Mandin <patmandin@gmail.com>
|
||||
Signed-off-by: Dave Airlie <airlied@redhat.com>
|
||||
---
|
||||
drivers/gpu/drm/i2c/Makefile | 3 +
|
||||
drivers/gpu/drm/i2c/sil164_drv.c | 462 ++++++++++++++++++++++++++++++++++++++
|
||||
drivers/gpu/drm/nouveau/Kconfig | 9 +
|
||||
include/drm/i2c/sil164.h | 63 +++++
|
||||
4 files changed, 537 insertions(+), 0 deletions(-)
|
||||
create mode 100644 drivers/gpu/drm/i2c/sil164_drv.c
|
||||
create mode 100644 include/drm/i2c/sil164.h
|
||||
|
||||
diff --git a/drivers/gpu/drm/i2c/Makefile b/drivers/gpu/drm/i2c/Makefile
|
||||
index 6d2abaf..9286256 100644
|
||||
--- a/drivers/gpu/drm/i2c/Makefile
|
||||
+++ b/drivers/gpu/drm/i2c/Makefile
|
||||
@@ -2,3 +2,6 @@ ccflags-y := -Iinclude/drm
|
||||
|
||||
ch7006-y := ch7006_drv.o ch7006_mode.o
|
||||
obj-$(CONFIG_DRM_I2C_CH7006) += ch7006.o
|
||||
+
|
||||
+sil164-y := sil164_drv.o
|
||||
+obj-$(CONFIG_DRM_I2C_SIL164) += sil164.o
|
||||
diff --git a/drivers/gpu/drm/i2c/sil164_drv.c b/drivers/gpu/drm/i2c/sil164_drv.c
|
||||
new file mode 100644
|
||||
index 0000000..0b67732
|
||||
--- /dev/null
|
||||
+++ b/drivers/gpu/drm/i2c/sil164_drv.c
|
||||
@@ -0,0 +1,462 @@
|
||||
+/*
|
||||
+ * Copyright (C) 2010 Francisco Jerez.
|
||||
+ * All Rights Reserved.
|
||||
+ *
|
||||
+ * Permission is hereby granted, free of charge, to any person obtaining
|
||||
+ * a copy of this software and associated documentation files (the
|
||||
+ * "Software"), to deal in the Software without restriction, including
|
||||
+ * without limitation the rights to use, copy, modify, merge, publish,
|
||||
+ * distribute, sublicense, and/or sell copies of the Software, and to
|
||||
+ * permit persons to whom the Software is furnished to do so, subject to
|
||||
+ * the following conditions:
|
||||
+ *
|
||||
+ * The above copyright notice and this permission notice (including the
|
||||
+ * next paragraph) shall be included in all copies or substantial
|
||||
+ * portions of the Software.
|
||||
+ *
|
||||
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
+ * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
|
||||
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
+ *
|
||||
+ */
|
||||
+
|
||||
+#include "drmP.h"
|
||||
+#include "drm_crtc_helper.h"
|
||||
+#include "drm_encoder_slave.h"
|
||||
+#include "i2c/sil164.h"
|
||||
+
|
||||
+struct sil164_priv {
|
||||
+ struct sil164_encoder_params config;
|
||||
+ struct i2c_client *duallink_slave;
|
||||
+
|
||||
+ uint8_t saved_state[0x10];
|
||||
+ uint8_t saved_slave_state[0x10];
|
||||
+};
|
||||
+
|
||||
+#define to_sil164_priv(x) \
|
||||
+ ((struct sil164_priv *)to_encoder_slave(x)->slave_priv)
|
||||
+
|
||||
+#define sil164_dbg(client, format, ...) do { \
|
||||
+ if (drm_debug & DRM_UT_KMS) \
|
||||
+ dev_printk(KERN_DEBUG, &client->dev, \
|
||||
+ "%s: " format, __func__, ## __VA_ARGS__); \
|
||||
+ } while (0)
|
||||
+#define sil164_info(client, format, ...) \
|
||||
+ dev_info(&client->dev, format, __VA_ARGS__)
|
||||
+#define sil164_err(client, format, ...) \
|
||||
+ dev_err(&client->dev, format, __VA_ARGS__)
|
||||
+
|
||||
+#define SIL164_I2C_ADDR_MASTER 0x38
|
||||
+#define SIL164_I2C_ADDR_SLAVE 0x39
|
||||
+
|
||||
+/* HW register definitions */
|
||||
+
|
||||
+#define SIL164_VENDOR_LO 0x0
|
||||
+#define SIL164_VENDOR_HI 0x1
|
||||
+#define SIL164_DEVICE_LO 0x2
|
||||
+#define SIL164_DEVICE_HI 0x3
|
||||
+#define SIL164_REVISION 0x4
|
||||
+#define SIL164_FREQ_MIN 0x6
|
||||
+#define SIL164_FREQ_MAX 0x7
|
||||
+#define SIL164_CONTROL0 0x8
|
||||
+# define SIL164_CONTROL0_POWER_ON 0x01
|
||||
+# define SIL164_CONTROL0_EDGE_RISING 0x02
|
||||
+# define SIL164_CONTROL0_INPUT_24BIT 0x04
|
||||
+# define SIL164_CONTROL0_DUAL_EDGE 0x08
|
||||
+# define SIL164_CONTROL0_HSYNC_ON 0x10
|
||||
+# define SIL164_CONTROL0_VSYNC_ON 0x20
|
||||
+#define SIL164_DETECT 0x9
|
||||
+# define SIL164_DETECT_INTR_STAT 0x01
|
||||
+# define SIL164_DETECT_HOTPLUG_STAT 0x02
|
||||
+# define SIL164_DETECT_RECEIVER_STAT 0x04
|
||||
+# define SIL164_DETECT_INTR_MODE_RECEIVER 0x00
|
||||
+# define SIL164_DETECT_INTR_MODE_HOTPLUG 0x08
|
||||
+# define SIL164_DETECT_OUT_MODE_HIGH 0x00
|
||||
+# define SIL164_DETECT_OUT_MODE_INTR 0x10
|
||||
+# define SIL164_DETECT_OUT_MODE_RECEIVER 0x20
|
||||
+# define SIL164_DETECT_OUT_MODE_HOTPLUG 0x30
|
||||
+# define SIL164_DETECT_VSWING_STAT 0x80
|
||||
+#define SIL164_CONTROL1 0xa
|
||||
+# define SIL164_CONTROL1_DESKEW_ENABLE 0x10
|
||||
+# define SIL164_CONTROL1_DESKEW_INCR_SHIFT 5
|
||||
+#define SIL164_GPIO 0xb
|
||||
+#define SIL164_CONTROL2 0xc
|
||||
+# define SIL164_CONTROL2_FILTER_ENABLE 0x01
|
||||
+# define SIL164_CONTROL2_FILTER_SETTING_SHIFT 1
|
||||
+# define SIL164_CONTROL2_DUALLINK_MASTER 0x40
|
||||
+# define SIL164_CONTROL2_SYNC_CONT 0x80
|
||||
+#define SIL164_DUALLINK 0xd
|
||||
+# define SIL164_DUALLINK_ENABLE 0x10
|
||||
+# define SIL164_DUALLINK_SKEW_SHIFT 5
|
||||
+#define SIL164_PLLZONE 0xe
|
||||
+# define SIL164_PLLZONE_STAT 0x08
|
||||
+# define SIL164_PLLZONE_FORCE_ON 0x10
|
||||
+# define SIL164_PLLZONE_FORCE_HIGH 0x20
|
||||
+
|
||||
+/* HW access functions */
|
||||
+
|
||||
+static void
|
||||
+sil164_write(struct i2c_client *client, uint8_t addr, uint8_t val)
|
||||
+{
|
||||
+ uint8_t buf[] = {addr, val};
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = i2c_master_send(client, buf, ARRAY_SIZE(buf));
|
||||
+ if (ret < 0)
|
||||
+ sil164_err(client, "Error %d writing to subaddress 0x%x\n",
|
||||
+ ret, addr);
|
||||
+}
|
||||
+
|
||||
+static uint8_t
|
||||
+sil164_read(struct i2c_client *client, uint8_t addr)
|
||||
+{
|
||||
+ uint8_t val;
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = i2c_master_send(client, &addr, sizeof(addr));
|
||||
+ if (ret < 0)
|
||||
+ goto fail;
|
||||
+
|
||||
+ ret = i2c_master_recv(client, &val, sizeof(val));
|
||||
+ if (ret < 0)
|
||||
+ goto fail;
|
||||
+
|
||||
+ return val;
|
||||
+
|
||||
+fail:
|
||||
+ sil164_err(client, "Error %d reading from subaddress 0x%x\n",
|
||||
+ ret, addr);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+sil164_save_state(struct i2c_client *client, uint8_t *state)
|
||||
+{
|
||||
+ int i;
|
||||
+
|
||||
+ for (i = 0x8; i <= 0xe; i++)
|
||||
+ state[i] = sil164_read(client, i);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+sil164_restore_state(struct i2c_client *client, uint8_t *state)
|
||||
+{
|
||||
+ int i;
|
||||
+
|
||||
+ for (i = 0x8; i <= 0xe; i++)
|
||||
+ sil164_write(client, i, state[i]);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+sil164_set_power_state(struct i2c_client *client, bool on)
|
||||
+{
|
||||
+ uint8_t control0 = sil164_read(client, SIL164_CONTROL0);
|
||||
+
|
||||
+ if (on)
|
||||
+ control0 |= SIL164_CONTROL0_POWER_ON;
|
||||
+ else
|
||||
+ control0 &= ~SIL164_CONTROL0_POWER_ON;
|
||||
+
|
||||
+ sil164_write(client, SIL164_CONTROL0, control0);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+sil164_init_state(struct i2c_client *client,
|
||||
+ struct sil164_encoder_params *config,
|
||||
+ bool duallink)
|
||||
+{
|
||||
+ sil164_write(client, SIL164_CONTROL0,
|
||||
+ SIL164_CONTROL0_HSYNC_ON |
|
||||
+ SIL164_CONTROL0_VSYNC_ON |
|
||||
+ (config->input_edge ? SIL164_CONTROL0_EDGE_RISING : 0) |
|
||||
+ (config->input_width ? SIL164_CONTROL0_INPUT_24BIT : 0) |
|
||||
+ (config->input_dual ? SIL164_CONTROL0_DUAL_EDGE : 0));
|
||||
+
|
||||
+ sil164_write(client, SIL164_DETECT,
|
||||
+ SIL164_DETECT_INTR_STAT |
|
||||
+ SIL164_DETECT_OUT_MODE_RECEIVER);
|
||||
+
|
||||
+ sil164_write(client, SIL164_CONTROL1,
|
||||
+ (config->input_skew ? SIL164_CONTROL1_DESKEW_ENABLE : 0) |
|
||||
+ (((config->input_skew + 4) & 0x7)
|
||||
+ << SIL164_CONTROL1_DESKEW_INCR_SHIFT));
|
||||
+
|
||||
+ sil164_write(client, SIL164_CONTROL2,
|
||||
+ SIL164_CONTROL2_SYNC_CONT |
|
||||
+ (config->pll_filter ? 0 : SIL164_CONTROL2_FILTER_ENABLE) |
|
||||
+ (4 << SIL164_CONTROL2_FILTER_SETTING_SHIFT));
|
||||
+
|
||||
+ sil164_write(client, SIL164_PLLZONE, 0);
|
||||
+
|
||||
+ if (duallink)
|
||||
+ sil164_write(client, SIL164_DUALLINK,
|
||||
+ SIL164_DUALLINK_ENABLE |
|
||||
+ (((config->duallink_skew + 4) & 0x7)
|
||||
+ << SIL164_DUALLINK_SKEW_SHIFT));
|
||||
+ else
|
||||
+ sil164_write(client, SIL164_DUALLINK, 0);
|
||||
+}
|
||||
+
|
||||
+/* DRM encoder functions */
|
||||
+
|
||||
+static void
|
||||
+sil164_encoder_set_config(struct drm_encoder *encoder, void *params)
|
||||
+{
|
||||
+ struct sil164_priv *priv = to_sil164_priv(encoder);
|
||||
+
|
||||
+ priv->config = *(struct sil164_encoder_params *)params;
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+sil164_encoder_dpms(struct drm_encoder *encoder, int mode)
|
||||
+{
|
||||
+ struct sil164_priv *priv = to_sil164_priv(encoder);
|
||||
+ bool on = (mode == DRM_MODE_DPMS_ON);
|
||||
+ bool duallink = (on && encoder->crtc->mode.clock > 165000);
|
||||
+
|
||||
+ sil164_set_power_state(drm_i2c_encoder_get_client(encoder), on);
|
||||
+
|
||||
+ if (priv->duallink_slave)
|
||||
+ sil164_set_power_state(priv->duallink_slave, duallink);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+sil164_encoder_save(struct drm_encoder *encoder)
|
||||
+{
|
||||
+ struct sil164_priv *priv = to_sil164_priv(encoder);
|
||||
+
|
||||
+ sil164_save_state(drm_i2c_encoder_get_client(encoder),
|
||||
+ priv->saved_state);
|
||||
+
|
||||
+ if (priv->duallink_slave)
|
||||
+ sil164_save_state(priv->duallink_slave,
|
||||
+ priv->saved_slave_state);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+sil164_encoder_restore(struct drm_encoder *encoder)
|
||||
+{
|
||||
+ struct sil164_priv *priv = to_sil164_priv(encoder);
|
||||
+
|
||||
+ sil164_restore_state(drm_i2c_encoder_get_client(encoder),
|
||||
+ priv->saved_state);
|
||||
+
|
||||
+ if (priv->duallink_slave)
|
||||
+ sil164_restore_state(priv->duallink_slave,
|
||||
+ priv->saved_slave_state);
|
||||
+}
|
||||
+
|
||||
+static bool
|
||||
+sil164_encoder_mode_fixup(struct drm_encoder *encoder,
|
||||
+ struct drm_display_mode *mode,
|
||||
+ struct drm_display_mode *adjusted_mode)
|
||||
+{
|
||||
+ return true;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+sil164_encoder_mode_valid(struct drm_encoder *encoder,
|
||||
+ struct drm_display_mode *mode)
|
||||
+{
|
||||
+ struct sil164_priv *priv = to_sil164_priv(encoder);
|
||||
+
|
||||
+ if (mode->clock < 32000)
|
||||
+ return MODE_CLOCK_LOW;
|
||||
+
|
||||
+ if (mode->clock > 330000 ||
|
||||
+ (mode->clock > 165000 && !priv->duallink_slave))
|
||||
+ return MODE_CLOCK_HIGH;
|
||||
+
|
||||
+ return MODE_OK;
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+sil164_encoder_mode_set(struct drm_encoder *encoder,
|
||||
+ struct drm_display_mode *mode,
|
||||
+ struct drm_display_mode *adjusted_mode)
|
||||
+{
|
||||
+ struct sil164_priv *priv = to_sil164_priv(encoder);
|
||||
+ bool duallink = adjusted_mode->clock > 165000;
|
||||
+
|
||||
+ sil164_init_state(drm_i2c_encoder_get_client(encoder),
|
||||
+ &priv->config, duallink);
|
||||
+
|
||||
+ if (priv->duallink_slave)
|
||||
+ sil164_init_state(priv->duallink_slave,
|
||||
+ &priv->config, duallink);
|
||||
+
|
||||
+ sil164_encoder_dpms(encoder, DRM_MODE_DPMS_ON);
|
||||
+}
|
||||
+
|
||||
+static enum drm_connector_status
|
||||
+sil164_encoder_detect(struct drm_encoder *encoder,
|
||||
+ struct drm_connector *connector)
|
||||
+{
|
||||
+ struct i2c_client *client = drm_i2c_encoder_get_client(encoder);
|
||||
+
|
||||
+ if (sil164_read(client, SIL164_DETECT) & SIL164_DETECT_HOTPLUG_STAT)
|
||||
+ return connector_status_connected;
|
||||
+ else
|
||||
+ return connector_status_disconnected;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+sil164_encoder_get_modes(struct drm_encoder *encoder,
|
||||
+ struct drm_connector *connector)
|
||||
+{
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+sil164_encoder_create_resources(struct drm_encoder *encoder,
|
||||
+ struct drm_connector *connector)
|
||||
+{
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+sil164_encoder_set_property(struct drm_encoder *encoder,
|
||||
+ struct drm_connector *connector,
|
||||
+ struct drm_property *property,
|
||||
+ uint64_t val)
|
||||
+{
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+sil164_encoder_destroy(struct drm_encoder *encoder)
|
||||
+{
|
||||
+ struct sil164_priv *priv = to_sil164_priv(encoder);
|
||||
+
|
||||
+ if (priv->duallink_slave)
|
||||
+ i2c_unregister_device(priv->duallink_slave);
|
||||
+
|
||||
+ kfree(priv);
|
||||
+ drm_i2c_encoder_destroy(encoder);
|
||||
+}
|
||||
+
|
||||
+static struct drm_encoder_slave_funcs sil164_encoder_funcs = {
|
||||
+ .set_config = sil164_encoder_set_config,
|
||||
+ .destroy = sil164_encoder_destroy,
|
||||
+ .dpms = sil164_encoder_dpms,
|
||||
+ .save = sil164_encoder_save,
|
||||
+ .restore = sil164_encoder_restore,
|
||||
+ .mode_fixup = sil164_encoder_mode_fixup,
|
||||
+ .mode_valid = sil164_encoder_mode_valid,
|
||||
+ .mode_set = sil164_encoder_mode_set,
|
||||
+ .detect = sil164_encoder_detect,
|
||||
+ .get_modes = sil164_encoder_get_modes,
|
||||
+ .create_resources = sil164_encoder_create_resources,
|
||||
+ .set_property = sil164_encoder_set_property,
|
||||
+};
|
||||
+
|
||||
+/* I2C driver functions */
|
||||
+
|
||||
+static int
|
||||
+sil164_probe(struct i2c_client *client, const struct i2c_device_id *id)
|
||||
+{
|
||||
+ int vendor = sil164_read(client, SIL164_VENDOR_HI) << 8 |
|
||||
+ sil164_read(client, SIL164_VENDOR_LO);
|
||||
+ int device = sil164_read(client, SIL164_DEVICE_HI) << 8 |
|
||||
+ sil164_read(client, SIL164_DEVICE_LO);
|
||||
+ int rev = sil164_read(client, SIL164_REVISION);
|
||||
+
|
||||
+ if (vendor != 0x1 || device != 0x6) {
|
||||
+ sil164_dbg(client, "Unknown device %x:%x.%x\n",
|
||||
+ vendor, device, rev);
|
||||
+ return -ENODEV;
|
||||
+ }
|
||||
+
|
||||
+ sil164_info(client, "Detected device %x:%x.%x\n",
|
||||
+ vendor, device, rev);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+sil164_remove(struct i2c_client *client)
|
||||
+{
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static struct i2c_client *
|
||||
+sil164_detect_slave(struct i2c_client *client)
|
||||
+{
|
||||
+ struct i2c_adapter *adap = client->adapter;
|
||||
+ struct i2c_msg msg = {
|
||||
+ .addr = SIL164_I2C_ADDR_SLAVE,
|
||||
+ .len = 0,
|
||||
+ };
|
||||
+ const struct i2c_board_info info = {
|
||||
+ I2C_BOARD_INFO("sil164", SIL164_I2C_ADDR_SLAVE)
|
||||
+ };
|
||||
+
|
||||
+ if (i2c_transfer(adap, &msg, 1) != 1) {
|
||||
+ sil164_dbg(adap, "No dual-link slave found.");
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ return i2c_new_device(adap, &info);
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+sil164_encoder_init(struct i2c_client *client,
|
||||
+ struct drm_device *dev,
|
||||
+ struct drm_encoder_slave *encoder)
|
||||
+{
|
||||
+ struct sil164_priv *priv;
|
||||
+
|
||||
+ priv = kzalloc(sizeof(*priv), GFP_KERNEL);
|
||||
+ if (!priv)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ encoder->slave_priv = priv;
|
||||
+ encoder->slave_funcs = &sil164_encoder_funcs;
|
||||
+
|
||||
+ priv->duallink_slave = sil164_detect_slave(client);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static struct i2c_device_id sil164_ids[] = {
|
||||
+ { "sil164", 0 },
|
||||
+ { }
|
||||
+};
|
||||
+MODULE_DEVICE_TABLE(i2c, sil164_ids);
|
||||
+
|
||||
+static struct drm_i2c_encoder_driver sil164_driver = {
|
||||
+ .i2c_driver = {
|
||||
+ .probe = sil164_probe,
|
||||
+ .remove = sil164_remove,
|
||||
+ .driver = {
|
||||
+ .name = "sil164",
|
||||
+ },
|
||||
+ .id_table = sil164_ids,
|
||||
+ },
|
||||
+ .encoder_init = sil164_encoder_init,
|
||||
+};
|
||||
+
|
||||
+/* Module initialization */
|
||||
+
|
||||
+static int __init
|
||||
+sil164_init(void)
|
||||
+{
|
||||
+ return drm_i2c_encoder_register(THIS_MODULE, &sil164_driver);
|
||||
+}
|
||||
+
|
||||
+static void __exit
|
||||
+sil164_exit(void)
|
||||
+{
|
||||
+ drm_i2c_encoder_unregister(&sil164_driver);
|
||||
+}
|
||||
+
|
||||
+MODULE_AUTHOR("Francisco Jerez <currojerez@riseup.net>");
|
||||
+MODULE_DESCRIPTION("Silicon Image sil164 TMDS transmitter driver");
|
||||
+MODULE_LICENSE("GPL and additional rights");
|
||||
+
|
||||
+module_init(sil164_init);
|
||||
+module_exit(sil164_exit);
|
||||
diff --git a/drivers/gpu/drm/nouveau/Kconfig b/drivers/gpu/drm/nouveau/Kconfig
|
||||
index 1175429..6b8967a 100644
|
||||
--- a/drivers/gpu/drm/nouveau/Kconfig
|
||||
+++ b/drivers/gpu/drm/nouveau/Kconfig
|
||||
@@ -41,4 +41,13 @@ config DRM_I2C_CH7006
|
||||
|
||||
This driver is currently only useful if you're also using
|
||||
the nouveau driver.
|
||||
+
|
||||
+config DRM_I2C_SIL164
|
||||
+ tristate "Silicon Image sil164 TMDS transmitter"
|
||||
+ default m if DRM_NOUVEAU
|
||||
+ help
|
||||
+ Support for sil164 and similar single-link (or dual-link
|
||||
+ when used in pairs) TMDS transmitters, used in some nVidia
|
||||
+ video cards.
|
||||
+
|
||||
endmenu
|
||||
diff --git a/include/drm/i2c/sil164.h b/include/drm/i2c/sil164.h
|
||||
new file mode 100644
|
||||
index 0000000..205e273
|
||||
--- /dev/null
|
||||
+++ b/include/drm/i2c/sil164.h
|
||||
@@ -0,0 +1,63 @@
|
||||
+/*
|
||||
+ * Copyright (C) 2010 Francisco Jerez.
|
||||
+ * All Rights Reserved.
|
||||
+ *
|
||||
+ * Permission is hereby granted, free of charge, to any person obtaining
|
||||
+ * a copy of this software and associated documentation files (the
|
||||
+ * "Software"), to deal in the Software without restriction, including
|
||||
+ * without limitation the rights to use, copy, modify, merge, publish,
|
||||
+ * distribute, sublicense, and/or sell copies of the Software, and to
|
||||
+ * permit persons to whom the Software is furnished to do so, subject to
|
||||
+ * the following conditions:
|
||||
+ *
|
||||
+ * The above copyright notice and this permission notice (including the
|
||||
+ * next paragraph) shall be included in all copies or substantial
|
||||
+ * portions of the Software.
|
||||
+ *
|
||||
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
+ * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
|
||||
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
+ *
|
||||
+ */
|
||||
+
|
||||
+#ifndef __DRM_I2C_SIL164_H__
|
||||
+#define __DRM_I2C_SIL164_H__
|
||||
+
|
||||
+/**
|
||||
+ * struct sil164_encoder_params
|
||||
+ *
|
||||
+ * Describes how the sil164 is connected to the GPU. It should be used
|
||||
+ * as the @params parameter of its @set_config method.
|
||||
+ *
|
||||
+ * See "http://www.siliconimage.com/docs/SiI-DS-0021-E-164.pdf".
|
||||
+ */
|
||||
+struct sil164_encoder_params {
|
||||
+ enum {
|
||||
+ SIL164_INPUT_EDGE_FALLING = 0,
|
||||
+ SIL164_INPUT_EDGE_RISING
|
||||
+ } input_edge;
|
||||
+
|
||||
+ enum {
|
||||
+ SIL164_INPUT_WIDTH_12BIT = 0,
|
||||
+ SIL164_INPUT_WIDTH_24BIT
|
||||
+ } input_width;
|
||||
+
|
||||
+ enum {
|
||||
+ SIL164_INPUT_SINGLE_EDGE = 0,
|
||||
+ SIL164_INPUT_DUAL_EDGE
|
||||
+ } input_dual;
|
||||
+
|
||||
+ enum {
|
||||
+ SIL164_PLL_FILTER_ON = 0,
|
||||
+ SIL164_PLL_FILTER_OFF,
|
||||
+ } pll_filter;
|
||||
+
|
||||
+ int input_skew; /** < Allowed range [-4, 3], use 0 for no de-skew. */
|
||||
+ int duallink_skew; /** < Allowed range [-4, 3]. */
|
||||
+};
|
||||
+
|
||||
+#endif
|
||||
--
|
||||
1.7.2
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
From 74ef65374ae6d0eead4a631aea3aca80d016ff0f Mon Sep 17 00:00:00 2001
|
||||
From: Francisco Jerez <currojerez@riseup.net>
|
||||
Date: Thu, 22 Jul 2010 17:07:38 +0200
|
||||
Subject: [PATCH 1/5] drm-simplify-i2c-config
|
||||
|
||||
drm/kms: Simplify setup of the initial I2C encoder config.
|
||||
|
||||
In most use cases the driver will be using the same static config all
|
||||
the time: interpreting i2c_board_info::platform_data as the default
|
||||
config we can can save the GPU driver a redundant set_config() call.
|
||||
|
||||
Signed-off-by: Francisco Jerez <currojerez@riseup.net>
|
||||
Signed-off-by: Dave Airlie <airlied@redhat.com>
|
||||
---
|
||||
drivers/gpu/drm/drm_encoder_slave.c | 7 +++++++
|
||||
1 files changed, 7 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/drivers/gpu/drm/drm_encoder_slave.c b/drivers/gpu/drm/drm_encoder_slave.c
|
||||
index f018469..d62c064 100644
|
||||
--- a/drivers/gpu/drm/drm_encoder_slave.c
|
||||
+++ b/drivers/gpu/drm/drm_encoder_slave.c
|
||||
@@ -41,6 +41,9 @@
|
||||
* &drm_encoder_slave. The @slave_funcs field will be initialized with
|
||||
* the hooks provided by the slave driver.
|
||||
*
|
||||
+ * If @info->platform_data is non-NULL it will be used as the initial
|
||||
+ * slave config.
|
||||
+ *
|
||||
* Returns 0 on success or a negative errno on failure, in particular,
|
||||
* -ENODEV is returned when no matching driver is found.
|
||||
*/
|
||||
@@ -85,6 +88,10 @@ int drm_i2c_encoder_init(struct drm_device *dev,
|
||||
if (err)
|
||||
goto fail_unregister;
|
||||
|
||||
+ if (info->platform_data)
|
||||
+ encoder->slave_funcs->set_config(&encoder->base,
|
||||
+ info->platform_data);
|
||||
+
|
||||
return 0;
|
||||
|
||||
fail_unregister:
|
||||
--
|
||||
1.7.2
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
From 0fbecd400dd0a82d465b3086f209681e8c54cb0f Mon Sep 17 00:00:00 2001
|
||||
From: Francisco Jerez <currojerez@riseup.net>
|
||||
Date: Tue, 21 Sep 2010 02:15:15 +0200
|
||||
Subject: [PATCH] drm/ttm: Clear the ghost cpu_writers flag on ttm_buffer_object_transfer.
|
||||
|
||||
It makes sense for a BO to move after a process has requested
|
||||
exclusive RW access on it (e.g. because the BO used to be located in
|
||||
unmappable VRAM and we intercepted the CPU access from the fault
|
||||
handler).
|
||||
|
||||
If we let the ghost object inherit cpu_writers from the original
|
||||
object, ttm_bo_release_list() will raise a kernel BUG when the ghost
|
||||
object is destroyed. This can be reproduced with the nouveau driver on
|
||||
nv5x.
|
||||
|
||||
Reported-by: Marcin Slusarz <marcin.slusarz@gmail.com>
|
||||
Reviewed-by: Jerome Glisse <jglisse@redhat.com>
|
||||
Tested-by: Marcin Slusarz <marcin.slusarz@gmail.com>
|
||||
Signed-off-by: Francisco Jerez <currojerez@riseup.net>
|
||||
Signed-off-by: Dave Airlie <airlied@redhat.com>
|
||||
---
|
||||
drivers/gpu/drm/ttm/ttm_bo_util.c | 1 +
|
||||
1 files changed, 1 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/drivers/gpu/drm/ttm/ttm_bo_util.c b/drivers/gpu/drm/ttm/ttm_bo_util.c
|
||||
index 7cffb3e..3451a82 100644
|
||||
--- a/drivers/gpu/drm/ttm/ttm_bo_util.c
|
||||
+++ b/drivers/gpu/drm/ttm/ttm_bo_util.c
|
||||
@@ -351,6 +351,7 @@ static int ttm_buffer_object_transfer(struct ttm_buffer_object *bo,
|
||||
INIT_LIST_HEAD(&fbo->lru);
|
||||
INIT_LIST_HEAD(&fbo->swap);
|
||||
fbo->vm_node = NULL;
|
||||
+ atomic_set(&fbo->cpu_writers, 0);
|
||||
|
||||
fbo->sync_obj = driver->sync_obj_ref(bo->sync_obj);
|
||||
kref_init(&fbo->list_kref);
|
||||
--
|
||||
1.7.3.1
|
||||
|
|
@ -0,0 +1,124 @@
|
|||
commit a5757c2a474a15f87e5baa9a4caacc31cde2bae6
|
||||
Author: Luke Macken <lmacken@redhat.com>
|
||||
Date: Wed Sep 22 13:05:04 2010 -0700
|
||||
|
||||
efifb: support the EFI framebuffer on more Apple hardware
|
||||
|
||||
Enable the EFI framebuffer on 14 more Macs, including the iMac11,1
|
||||
iMac10,1 iMac8,1 Macmini3,1 Macmini4,1 MacBook5,1 MacBook6,1 MacBook7,1
|
||||
MacBookPro2,2 MacBookPro5,2 MacBookPro5,3 MacBookPro6,1 MacBookPro6,2 and
|
||||
MacBookPro7,1
|
||||
|
||||
Information gathered from various user submissions.
|
||||
|
||||
https://bugzilla.redhat.com/show_bug.cgi?id=528232
|
||||
http://ubuntuforums.org/showthread.php?t=1557326
|
||||
|
||||
[akpm@linux-foundation.org: coding-style fixes]
|
||||
Signed-off-by: Luke Macken <lmacken@redhat.com>
|
||||
Signed-off-by: Peter Jones <pjones@redhat.com>
|
||||
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
||||
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
|
||||
|
||||
diff --git a/drivers/video/efifb.c b/drivers/video/efifb.c
|
||||
index c082b61..70477c2 100644
|
||||
--- a/drivers/video/efifb.c
|
||||
+++ b/drivers/video/efifb.c
|
||||
@@ -39,17 +39,31 @@ enum {
|
||||
M_I20, /* 20-Inch iMac */
|
||||
M_I20_SR, /* 20-Inch iMac (Santa Rosa) */
|
||||
M_I24, /* 24-Inch iMac */
|
||||
+ M_I24_8_1, /* 24-Inch iMac, 8,1th gen */
|
||||
+ M_I24_10_1, /* 24-Inch iMac, 10,1th gen */
|
||||
+ M_I27_11_1, /* 27-Inch iMac, 11,1th gen */
|
||||
M_MINI, /* Mac Mini */
|
||||
+ M_MINI_3_1, /* Mac Mini, 3,1th gen */
|
||||
+ M_MINI_4_1, /* Mac Mini, 4,1th gen */
|
||||
M_MB, /* MacBook */
|
||||
M_MB_2, /* MacBook, 2nd rev. */
|
||||
M_MB_3, /* MacBook, 3rd rev. */
|
||||
+ M_MB_5_1, /* MacBook, 5th rev. */
|
||||
+ M_MB_6_1, /* MacBook, 6th rev. */
|
||||
+ M_MB_7_1, /* MacBook, 7th rev. */
|
||||
M_MB_SR, /* MacBook, 2nd gen, (Santa Rosa) */
|
||||
M_MBA, /* MacBook Air */
|
||||
M_MBP, /* MacBook Pro */
|
||||
M_MBP_2, /* MacBook Pro 2nd gen */
|
||||
+ M_MBP_2_2, /* MacBook Pro 2,2nd gen */
|
||||
M_MBP_SR, /* MacBook Pro (Santa Rosa) */
|
||||
M_MBP_4, /* MacBook Pro, 4th gen */
|
||||
M_MBP_5_1, /* MacBook Pro, 5,1th gen */
|
||||
+ M_MBP_5_2, /* MacBook Pro, 5,2th gen */
|
||||
+ M_MBP_5_3, /* MacBook Pro, 5,3rd gen */
|
||||
+ M_MBP_6_1, /* MacBook Pro, 6,1th gen */
|
||||
+ M_MBP_6_2, /* MacBook Pro, 6,2th gen */
|
||||
+ M_MBP_7_1, /* MacBook Pro, 7,1th gen */
|
||||
M_UNKNOWN /* placeholder */
|
||||
};
|
||||
|
||||
@@ -64,14 +78,28 @@ static struct efifb_dmi_info {
|
||||
[M_I20] = { "i20", 0x80010000, 1728 * 4, 1680, 1050 }, /* guess */
|
||||
[M_I20_SR] = { "imac7", 0x40010000, 1728 * 4, 1680, 1050 },
|
||||
[M_I24] = { "i24", 0x80010000, 2048 * 4, 1920, 1200 }, /* guess */
|
||||
+ [M_I24_8_1] = { "imac8", 0xc0060000, 2048 * 4, 1920, 1200 },
|
||||
+ [M_I24_10_1] = { "imac10", 0xc0010000, 2048 * 4, 1920, 1080 },
|
||||
+ [M_I27_11_1] = { "imac11", 0xc0010000, 2560 * 4, 2560, 1440 },
|
||||
[M_MINI]= { "mini", 0x80000000, 2048 * 4, 1024, 768 },
|
||||
+ [M_MINI_3_1] = { "mini31", 0x40010000, 1024 * 4, 1024, 768 },
|
||||
+ [M_MINI_4_1] = { "mini41", 0xc0010000, 2048 * 4, 1920, 1200 },
|
||||
[M_MB] = { "macbook", 0x80000000, 2048 * 4, 1280, 800 },
|
||||
+ [M_MB_5_1] = { "macbook51", 0x80010000, 2048 * 4, 1280, 800 },
|
||||
+ [M_MB_6_1] = { "macbook61", 0x80010000, 2048 * 4, 1280, 800 },
|
||||
+ [M_MB_7_1] = { "macbook71", 0x80010000, 2048 * 4, 1280, 800 },
|
||||
[M_MBA] = { "mba", 0x80000000, 2048 * 4, 1280, 800 },
|
||||
[M_MBP] = { "mbp", 0x80010000, 1472 * 4, 1440, 900 },
|
||||
[M_MBP_2] = { "mbp2", 0, 0, 0, 0 }, /* placeholder */
|
||||
+ [M_MBP_2_2] = { "mbp22", 0x80010000, 1472 * 4, 1440, 900 },
|
||||
[M_MBP_SR] = { "mbp3", 0x80030000, 2048 * 4, 1440, 900 },
|
||||
[M_MBP_4] = { "mbp4", 0xc0060000, 2048 * 4, 1920, 1200 },
|
||||
[M_MBP_5_1] = { "mbp51", 0xc0010000, 2048 * 4, 1440, 900 },
|
||||
+ [M_MBP_5_2] = { "mbp52", 0xc0010000, 2048 * 4, 1920, 1200 },
|
||||
+ [M_MBP_5_3] = { "mbp53", 0xd0010000, 2048 * 4, 1440, 900 },
|
||||
+ [M_MBP_6_1] = { "mbp61", 0x90030000, 2048 * 4, 1920, 1200 },
|
||||
+ [M_MBP_6_2] = { "mbp62", 0x90030000, 2048 * 4, 1680, 1050 },
|
||||
+ [M_MBP_7_1] = { "mbp71", 0xc0010000, 2048 * 4, 1280, 800 },
|
||||
[M_UNKNOWN] = { NULL, 0, 0, 0, 0 }
|
||||
};
|
||||
|
||||
@@ -92,7 +120,12 @@ static const struct dmi_system_id dmi_system_table[] __initconst = {
|
||||
EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "iMac6,1", M_I24),
|
||||
EFIFB_DMI_SYSTEM_ID("Apple Inc.", "iMac6,1", M_I24),
|
||||
EFIFB_DMI_SYSTEM_ID("Apple Inc.", "iMac7,1", M_I20_SR),
|
||||
+ EFIFB_DMI_SYSTEM_ID("Apple Inc.", "iMac8,1", M_I24_8_1),
|
||||
+ EFIFB_DMI_SYSTEM_ID("Apple Inc.", "iMac10,1", M_I24_10_1),
|
||||
+ EFIFB_DMI_SYSTEM_ID("Apple Inc.", "iMac11,1", M_I27_11_1),
|
||||
EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "Macmini1,1", M_MINI),
|
||||
+ EFIFB_DMI_SYSTEM_ID("Apple Inc.", "Macmini3,1", M_MINI_3_1),
|
||||
+ EFIFB_DMI_SYSTEM_ID("Apple Inc.", "Macmini4,1", M_MINI_4_1),
|
||||
EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBook1,1", M_MB),
|
||||
/* At least one of these two will be right; maybe both? */
|
||||
EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBook2,1", M_MB),
|
||||
@@ -101,14 +134,23 @@ static const struct dmi_system_id dmi_system_table[] __initconst = {
|
||||
EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBook3,1", M_MB),
|
||||
EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBook3,1", M_MB),
|
||||
EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBook4,1", M_MB),
|
||||
+ EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBook5,1", M_MB_5_1),
|
||||
+ EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBook6,1", M_MB_6_1),
|
||||
+ EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBook7,1", M_MB_7_1),
|
||||
EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookAir1,1", M_MBA),
|
||||
EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBookPro1,1", M_MBP),
|
||||
EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBookPro2,1", M_MBP_2),
|
||||
+ EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBookPro2,2", M_MBP_2_2),
|
||||
EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro2,1", M_MBP_2),
|
||||
EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBookPro3,1", M_MBP_SR),
|
||||
EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro3,1", M_MBP_SR),
|
||||
EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro4,1", M_MBP_4),
|
||||
EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro5,1", M_MBP_5_1),
|
||||
+ EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro5,2", M_MBP_5_2),
|
||||
+ EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro5,3", M_MBP_5_3),
|
||||
+ EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro6,1", M_MBP_6_1),
|
||||
+ EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro6,2", M_MBP_6_2),
|
||||
+ EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro7,1", M_MBP_7_1),
|
||||
{},
|
||||
};
|
||||
|
|
@ -0,0 +1,135 @@
|
|||
commit 85a00d9bbfb4704fbf368944b1cb9fed8f1598c5
|
||||
Author: Peter Jones <pjones@redhat.com>
|
||||
Date: Wed Sep 22 13:05:04 2010 -0700
|
||||
|
||||
efifb: check that the base address is plausible on pci systems
|
||||
|
||||
Some Apple machines have identical DMI data but different memory
|
||||
configurations for the video. Given that, check that the address in our
|
||||
table is actually within the range of a PCI BAR on a VGA device in the
|
||||
machine.
|
||||
|
||||
This also fixes up the return value from set_system(), which has always
|
||||
been wrong, but never resulted in bad behavior since there's only ever
|
||||
been one matching entry in the dmi table.
|
||||
|
||||
The patch
|
||||
|
||||
1) stops people's machines from crashing when we get their display wrong,
|
||||
which seems to be unfortunately inevitable,
|
||||
|
||||
2) allows us to support identical dmi data with differing video memory
|
||||
configurations
|
||||
|
||||
This also adds me as the efifb maintainer, since I've effectively been
|
||||
acting as such for quite some time.
|
||||
|
||||
Signed-off-by: Peter Jones <pjones@redhat.com>
|
||||
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
||||
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
|
||||
|
||||
diff --git a/MAINTAINERS b/MAINTAINERS
|
||||
index 726433a..4d4881d 100644
|
||||
--- a/MAINTAINERS
|
||||
+++ b/MAINTAINERS
|
||||
@@ -2199,6 +2199,12 @@ W: http://acpi4asus.sf.net
|
||||
S: Maintained
|
||||
F: drivers/platform/x86/eeepc-laptop.c
|
||||
|
||||
+EFIFB FRAMEBUFFER DRIVER
|
||||
+L: linux-fbdev@vger.kernel.org
|
||||
+M: Peter Jones <pjones@redhat.com>
|
||||
+S: Maintained
|
||||
+F: drivers/video/efifb.c
|
||||
+
|
||||
EFS FILESYSTEM
|
||||
W: http://aeschi.ch.eu.org/efs/
|
||||
S: Orphan
|
||||
diff --git a/drivers/video/efifb.c b/drivers/video/efifb.c
|
||||
index 815f84b..c082b61 100644
|
||||
--- a/drivers/video/efifb.c
|
||||
+++ b/drivers/video/efifb.c
|
||||
@@ -13,7 +13,7 @@
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/screen_info.h>
|
||||
#include <linux/dmi.h>
|
||||
-
|
||||
+#include <linux/pci.h>
|
||||
#include <video/vga.h>
|
||||
|
||||
static struct fb_var_screeninfo efifb_defined __devinitdata = {
|
||||
@@ -116,7 +116,7 @@ static int set_system(const struct dmi_system_id *id)
|
||||
{
|
||||
struct efifb_dmi_info *info = id->driver_data;
|
||||
if (info->base == 0)
|
||||
- return -ENODEV;
|
||||
+ return 0;
|
||||
|
||||
printk(KERN_INFO "efifb: dmi detected %s - framebuffer at %p "
|
||||
"(%dx%d, stride %d)\n", id->ident,
|
||||
@@ -124,18 +124,55 @@ static int set_system(const struct dmi_system_id *id)
|
||||
info->stride);
|
||||
|
||||
/* Trust the bootloader over the DMI tables */
|
||||
- if (screen_info.lfb_base == 0)
|
||||
+ if (screen_info.lfb_base == 0) {
|
||||
+#if defined(CONFIG_PCI)
|
||||
+ struct pci_dev *dev = NULL;
|
||||
+ int found_bar = 0;
|
||||
+#endif
|
||||
screen_info.lfb_base = info->base;
|
||||
- if (screen_info.lfb_linelength == 0)
|
||||
- screen_info.lfb_linelength = info->stride;
|
||||
- if (screen_info.lfb_width == 0)
|
||||
- screen_info.lfb_width = info->width;
|
||||
- if (screen_info.lfb_height == 0)
|
||||
- screen_info.lfb_height = info->height;
|
||||
- if (screen_info.orig_video_isVGA == 0)
|
||||
- screen_info.orig_video_isVGA = VIDEO_TYPE_EFI;
|
||||
|
||||
- return 0;
|
||||
+#if defined(CONFIG_PCI)
|
||||
+ /* make sure that the address in the table is actually on a
|
||||
+ * VGA device's PCI BAR */
|
||||
+
|
||||
+ for_each_pci_dev(dev) {
|
||||
+ int i;
|
||||
+ if ((dev->class >> 8) != PCI_CLASS_DISPLAY_VGA)
|
||||
+ continue;
|
||||
+ for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
|
||||
+ resource_size_t start, end;
|
||||
+
|
||||
+ start = pci_resource_start(dev, i);
|
||||
+ if (start == 0)
|
||||
+ break;
|
||||
+ end = pci_resource_end(dev, i);
|
||||
+ if (screen_info.lfb_base >= start &&
|
||||
+ screen_info.lfb_base < end) {
|
||||
+ found_bar = 1;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ if (!found_bar)
|
||||
+ screen_info.lfb_base = 0;
|
||||
+#endif
|
||||
+ }
|
||||
+ if (screen_info.lfb_base) {
|
||||
+ if (screen_info.lfb_linelength == 0)
|
||||
+ screen_info.lfb_linelength = info->stride;
|
||||
+ if (screen_info.lfb_width == 0)
|
||||
+ screen_info.lfb_width = info->width;
|
||||
+ if (screen_info.lfb_height == 0)
|
||||
+ screen_info.lfb_height = info->height;
|
||||
+ if (screen_info.orig_video_isVGA == 0)
|
||||
+ screen_info.orig_video_isVGA = VIDEO_TYPE_EFI;
|
||||
+ } else {
|
||||
+ screen_info.lfb_linelength = 0;
|
||||
+ screen_info.lfb_width = 0;
|
||||
+ screen_info.lfb_height = 0;
|
||||
+ screen_info.orig_video_isVGA = 0;
|
||||
+ return 0;
|
||||
+ }
|
||||
+ return 1;
|
||||
}
|
||||
|
||||
static int efifb_setcolreg(unsigned regno, unsigned red, unsigned green,
|
|
@ -0,0 +1,36 @@
|
|||
From: Roland McGrath <roland@redhat.com>
|
||||
Date: Wed, 8 Sep 2010 02:36:28 +0000 (-0700)
|
||||
Subject: execve: improve interactivity with large arguments
|
||||
X-Git-Tag: v2.6.36-rc4~13
|
||||
X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=7993bc1f4663c0db67bb8f0d98e6678145b387cd
|
||||
|
||||
execve: improve interactivity with large arguments
|
||||
|
||||
This adds a preemption point during the copying of the argument and
|
||||
environment strings for execve, in copy_strings(). There is already
|
||||
a preemption point in the count() loop, so this doesn't add any new
|
||||
points in the abstract sense.
|
||||
|
||||
When the total argument+environment strings are very large, the time
|
||||
spent copying them can be much more than a normal user time slice.
|
||||
So this change improves the interactivity of the rest of the system
|
||||
when one process is doing an execve with very large arguments.
|
||||
|
||||
Signed-off-by: Roland McGrath <roland@redhat.com>
|
||||
Reviewed-by: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>
|
||||
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
|
||||
---
|
||||
|
||||
diff --git a/fs/exec.c b/fs/exec.c
|
||||
index 1b63237..6f2d777 100644
|
||||
--- a/fs/exec.c
|
||||
+++ b/fs/exec.c
|
||||
@@ -419,6 +419,8 @@ static int copy_strings(int argc, const char __user *const __user *argv,
|
||||
while (len > 0) {
|
||||
int offset, bytes_to_copy;
|
||||
|
||||
+ cond_resched();
|
||||
+
|
||||
offset = pos % PAGE_SIZE;
|
||||
if (offset == 0)
|
||||
offset = PAGE_SIZE;
|
|
@ -0,0 +1,51 @@
|
|||
From: Roland McGrath <roland@redhat.com>
|
||||
Date: Wed, 8 Sep 2010 02:37:06 +0000 (-0700)
|
||||
Subject: execve: make responsive to SIGKILL with large arguments
|
||||
X-Git-Tag: v2.6.36-rc4~12
|
||||
X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=9aea5a65aa7a1af9a4236dfaeb0088f1624f9919
|
||||
|
||||
execve: make responsive to SIGKILL with large arguments
|
||||
|
||||
An execve with a very large total of argument/environment strings
|
||||
can take a really long time in the execve system call. It runs
|
||||
uninterruptibly to count and copy all the strings. This change
|
||||
makes it abort the exec quickly if sent a SIGKILL.
|
||||
|
||||
Note that this is the conservative change, to interrupt only for
|
||||
SIGKILL, by using fatal_signal_pending(). It would be perfectly
|
||||
correct semantics to let any signal interrupt the string-copying in
|
||||
execve, i.e. use signal_pending() instead of fatal_signal_pending().
|
||||
We'll save that change for later, since it could have user-visible
|
||||
consequences, such as having a timer set too quickly make it so that
|
||||
an execve can never complete, though it always happened to work before.
|
||||
|
||||
Signed-off-by: Roland McGrath <roland@redhat.com>
|
||||
Reviewed-by: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>
|
||||
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
|
||||
---
|
||||
|
||||
diff --git a/fs/exec.c b/fs/exec.c
|
||||
index 6f2d777..828dd24 100644
|
||||
--- a/fs/exec.c
|
||||
+++ b/fs/exec.c
|
||||
@@ -376,6 +376,9 @@ static int count(const char __user * const __user * argv, int max)
|
||||
argv++;
|
||||
if (i++ >= max)
|
||||
return -E2BIG;
|
||||
+
|
||||
+ if (fatal_signal_pending(current))
|
||||
+ return -ERESTARTNOHAND;
|
||||
cond_resched();
|
||||
}
|
||||
}
|
||||
@@ -419,6 +422,10 @@ static int copy_strings(int argc, const char __user *const __user *argv,
|
||||
while (len > 0) {
|
||||
int offset, bytes_to_copy;
|
||||
|
||||
+ if (fatal_signal_pending(current)) {
|
||||
+ ret = -ERESTARTNOHAND;
|
||||
+ goto out;
|
||||
+ }
|
||||
cond_resched();
|
||||
|
||||
offset = pos % PAGE_SIZE;
|
|
@ -0,0 +1,27 @@
|
|||
diff --git a/kernel/sched.c b/kernel/sched.c
|
||||
index 6d0dbeb..3640c20 100644
|
||||
--- a/kernel/sched.c
|
||||
+++ b/kernel/sched.c
|
||||
@@ -5155,9 +5155,11 @@ void __cpuinit init_idle_bootup_task(struct task_struct *idle)
|
||||
void __cpuinit init_idle(struct task_struct *idle, int cpu)
|
||||
{
|
||||
struct rq *rq = cpu_rq(cpu);
|
||||
+ struct rq *oldrq = task_rq(idle);
|
||||
unsigned long flags;
|
||||
|
||||
- raw_spin_lock_irqsave(&rq->lock, flags);
|
||||
+ local_irq_save(flags);
|
||||
+ double_rq_lock(oldrq, rq);
|
||||
|
||||
__sched_fork(idle);
|
||||
idle->state = TASK_RUNNING;
|
||||
@@ -5170,7 +5172,8 @@ void __cpuinit init_idle(struct task_struct *idle, int cpu)
|
||||
#if defined(CONFIG_SMP) && defined(__ARCH_WANT_UNLOCKED_CTXSW)
|
||||
idle->oncpu = 1;
|
||||
#endif
|
||||
- raw_spin_unlock_irqrestore(&rq->lock, flags);
|
||||
+ double_rq_unlock(oldrq, rq);
|
||||
+ local_irq_restore(flags);
|
||||
|
||||
/* Set the preempt count _outside_ the spinlocks! */
|
||||
#if defined(CONFIG_PREEMPT)
|
|
@ -0,0 +1,30 @@
|
|||
diff --git a/drivers/media/dvb/b2c2/flexcop-pci.c b/drivers/media/dvb/b2c2/flexcop-pci.c
|
||||
index 227c020..7465308 100644
|
||||
--- a/drivers/media/dvb/b2c2/flexcop-pci.c
|
||||
+++ b/drivers/media/dvb/b2c2/flexcop-pci.c
|
||||
@@ -39,6 +39,7 @@ MODULE_PARM_DESC(debug,
|
||||
|
||||
#define DRIVER_VERSION "0.1"
|
||||
#define DRIVER_NAME "Technisat/B2C2 FlexCop II/IIb/III Digital TV PCI Driver"
|
||||
+#define FLEXCOP_MODULE_NAME "b2c2-flexcop"
|
||||
#define DRIVER_AUTHOR "Patrick Boettcher <patrick.boettcher@desy.de>"
|
||||
|
||||
struct flexcop_pci {
|
||||
@@ -299,7 +300,7 @@ static int flexcop_pci_init(struct flexcop_pci *fc_pci)
|
||||
return ret;
|
||||
pci_set_master(fc_pci->pdev);
|
||||
|
||||
- if ((ret = pci_request_regions(fc_pci->pdev, DRIVER_NAME)) != 0)
|
||||
+ if ((ret = pci_request_regions(fc_pci->pdev, FLEXCOP_MODULE_NAME)) != 0)
|
||||
goto err_pci_disable_device;
|
||||
|
||||
fc_pci->io_mem = pci_iomap(fc_pci->pdev, 0, 0x800);
|
||||
@@ -313,7 +314,7 @@ static int flexcop_pci_init(struct flexcop_pci *fc_pci)
|
||||
pci_set_drvdata(fc_pci->pdev, fc_pci);
|
||||
spin_lock_init(&fc_pci->irq_lock);
|
||||
if ((ret = request_irq(fc_pci->pdev->irq, flexcop_pci_isr,
|
||||
- IRQF_SHARED, DRIVER_NAME, fc_pci)) != 0)
|
||||
+ IRQF_SHARED, FLEXCOP_MODULE_NAME, fc_pci)) != 0)
|
||||
goto err_pci_iounmap;
|
||||
|
||||
fc_pci->init_state |= FC_PCI_INIT;
|
|
@ -0,0 +1,163 @@
|
|||
[PATCH] hid: support for bluetooth tivo slide remote and usb dongle
|
||||
|
||||
This patch adds full support for the TiVo Slide Remote, primarily by way
|
||||
of extending the existing generic HID support. Only four keys are not
|
||||
usages within a standard usage page, but they're easily handled by the
|
||||
addition of a HID_UP_TIVOVENDOR usage page. Note that the UP is 0xffff,
|
||||
which matches the mask, but its also a valid vendor-specific UP, according
|
||||
to the spec.
|
||||
|
||||
What's actually connected to the computer is a Broadcom-made usb dongle,
|
||||
which has an embedded hub, bluetooth adapter, mouse and keyboard devices.
|
||||
You pair with the dongle, then the remote sends data that its converted
|
||||
into HID on the keyboard interface (the mouse interface doesn't do anything
|
||||
interesting right now, so far as I can tell).
|
||||
|
||||
lsusb for this device:
|
||||
Bus 004 Device 005: ID 0a5c:2190 Broadcom Corp.
|
||||
Bus 004 Device 004: ID 0a5c:4503 Broadcom Corp.
|
||||
Bus 004 Device 003: ID 150a:1201
|
||||
Bus 004 Device 002: ID 0a5c:4500 Broadcom Corp. BCM2046B1 USB 2.0 Hub (part of BCM2046 Bluetooth)
|
||||
|
||||
Speaking of the keyboard interface, the remote actually does contain a
|
||||
keyboard as well. The top slides away, revealing a reasonably functional
|
||||
qwerty keyboard (not unlike many slide cell phones), thus the product
|
||||
name.
|
||||
|
||||
Now for some caveats... This device seems to report 0xc (consumer usage
|
||||
page) 0x20 ("+10") after most key presses. At the moment, this will simply
|
||||
be ignored, but if a mapping for that usage is added, the remote behaves
|
||||
very badly (we end up w/a repeating/stuck key until another key is pressed).
|
||||
Not quite sure what to do about that one, if that usage does get mapped. I
|
||||
guess a device-specific quirk to just ignore it would work.
|
||||
|
||||
Anyway, the thing is working 100% as expected with this patch right now.
|
||||
|
||||
Three more things to note... This patch fixes an incorrect mapping of 0xc 0x45,
|
||||
which was mapped to KEY_RADIO, which is definitely wrong, but may cause some
|
||||
existing device to now report KEY_RIGHT there. Second, there's also an
|
||||
unrelated fix for a redundant KERN_DEBUG in a dbg_hid call. Third, the
|
||||
additions to HID_UP_GENDESK aren't strictly needed by the remote, but the
|
||||
dongle does try to register those, and they're all technically correct, so
|
||||
I've included them for the benefit of a device that comes along and
|
||||
actually does try to use them.
|
||||
|
||||
Applies cleanly to hid master, tested w/a 2.6.35.4-based Fedora kernel.
|
||||
|
||||
Signed-off-by: Jarod Wilson <jarod@redhat.com>
|
||||
|
||||
---
|
||||
drivers/hid/hid-input.c | 45 ++++++++++++++++++++++++++++++++++++++++-----
|
||||
include/linux/hid.h | 1 +
|
||||
2 files changed, 41 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c
|
||||
index 6c03dcc..bd1479e 100644
|
||||
--- a/drivers/hid/hid-input.c
|
||||
+++ b/drivers/hid/hid-input.c
|
||||
@@ -44,11 +44,11 @@ static const unsigned char hid_keyboard[256] = {
|
||||
72, 73, 82, 83, 86,127,116,117,183,184,185,186,187,188,189,190,
|
||||
191,192,193,194,134,138,130,132,128,129,131,137,133,135,136,113,
|
||||
115,114,unk,unk,unk,121,unk, 89, 93,124, 92, 94, 95,unk,unk,unk,
|
||||
- 122,123, 90, 91, 85,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,
|
||||
+ 122,123, 90, 91, 85,unk,unk,unk,unk,unk,unk,unk,111,unk,unk,unk,
|
||||
unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,
|
||||
unk,unk,unk,unk,unk,unk,179,180,unk,unk,unk,unk,unk,unk,unk,unk,
|
||||
unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,
|
||||
- unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,
|
||||
+ unk,unk,unk,unk,unk,unk,unk,unk,111,unk,unk,unk,unk,unk,unk,unk,
|
||||
29, 42, 56,125, 97, 54,100,126,164,166,165,163,161,115,114,113,
|
||||
150,158,159,128,136,177,178,176,142,152,173,140,unk,unk,unk,unk
|
||||
};
|
||||
@@ -136,7 +136,7 @@ static int hidinput_setkeycode(struct input_dev *dev,
|
||||
|
||||
clear_bit(old_keycode, dev->keybit);
|
||||
set_bit(usage->code, dev->keybit);
|
||||
- dbg_hid(KERN_DEBUG "Assigned keycode %d to HID usage code %x\n", keycode, scancode);
|
||||
+ dbg_hid("Assigned keycode %d to HID usage code %x\n", keycode, scancode);
|
||||
/* Set the keybit for the old keycode if the old keycode is used
|
||||
* by another key */
|
||||
if (hidinput_find_key (hid, 0, old_keycode))
|
||||
@@ -235,6 +235,18 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
|
||||
case 0x1: map_key_clear(KEY_POWER); break;
|
||||
case 0x2: map_key_clear(KEY_SLEEP); break;
|
||||
case 0x3: map_key_clear(KEY_WAKEUP); break;
|
||||
+ case 0x4: map_key_clear(KEY_CONTEXT_MENU); break;
|
||||
+ case 0x5: map_key_clear(KEY_MENU); break;
|
||||
+ case 0x6: map_key_clear(KEY_PROG1); break;
|
||||
+ case 0x7: map_key_clear(KEY_HELP); break;
|
||||
+ case 0x8: map_key_clear(KEY_EXIT); break;
|
||||
+ case 0x9: map_key_clear(KEY_SELECT); break;
|
||||
+ case 0xa: map_key_clear(KEY_RIGHT); break;
|
||||
+ case 0xb: map_key_clear(KEY_LEFT); break;
|
||||
+ case 0xc: map_key_clear(KEY_UP); break;
|
||||
+ case 0xd: map_key_clear(KEY_DOWN); break;
|
||||
+ case 0xe: map_key_clear(KEY_POWER2); break;
|
||||
+ case 0xf: map_key_clear(KEY_RESTART); break;
|
||||
default: goto unknown;
|
||||
}
|
||||
break;
|
||||
@@ -343,12 +355,24 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
|
||||
case HID_UP_CONSUMER: /* USB HUT v1.1, pages 56-62 */
|
||||
switch (usage->hid & HID_USAGE) {
|
||||
case 0x000: goto ignore;
|
||||
+ case 0x030: map_key_clear(KEY_POWER); break;
|
||||
case 0x034: map_key_clear(KEY_SLEEP); break;
|
||||
case 0x036: map_key_clear(BTN_MISC); break;
|
||||
|
||||
case 0x040: map_key_clear(KEY_MENU); break;
|
||||
- case 0x045: map_key_clear(KEY_RADIO); break;
|
||||
-
|
||||
+ case 0x041: map_key_clear(KEY_SELECT); break;
|
||||
+ case 0x042: map_key_clear(KEY_UP); break;
|
||||
+ case 0x043: map_key_clear(KEY_DOWN); break;
|
||||
+ case 0x044: map_key_clear(KEY_LEFT); break;
|
||||
+ case 0x045: map_key_clear(KEY_RIGHT); break;
|
||||
+
|
||||
+ case 0x069: map_key_clear(KEY_RED); break;
|
||||
+ case 0x06a: map_key_clear(KEY_GREEN); break;
|
||||
+ case 0x06b: map_key_clear(KEY_BLUE); break;
|
||||
+ case 0x06c: map_key_clear(KEY_YELLOW); break;
|
||||
+ case 0x06d: map_key_clear(KEY_ZOOM); break;
|
||||
+
|
||||
+ case 0x082: map_key_clear(KEY_VIDEO_NEXT); break;
|
||||
case 0x083: map_key_clear(KEY_LAST); break;
|
||||
case 0x088: map_key_clear(KEY_PC); break;
|
||||
case 0x089: map_key_clear(KEY_TV); break;
|
||||
@@ -390,6 +414,7 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
|
||||
case 0x0e5: map_key_clear(KEY_BASSBOOST); break;
|
||||
case 0x0e9: map_key_clear(KEY_VOLUMEUP); break;
|
||||
case 0x0ea: map_key_clear(KEY_VOLUMEDOWN); break;
|
||||
+ case 0x0f5: map_key_clear(KEY_SLOW); break;
|
||||
|
||||
case 0x182: map_key_clear(KEY_BOOKMARKS); break;
|
||||
case 0x183: map_key_clear(KEY_CONFIG); break;
|
||||
@@ -491,6 +516,16 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
|
||||
}
|
||||
break;
|
||||
|
||||
+ case HID_UP_TIVOVENDOR:
|
||||
+ switch (usage->hid & HID_USAGE) {
|
||||
+ case 0x3d: map_key_clear(KEY_PROG1); break;
|
||||
+ case 0x3e: map_key_clear(KEY_TV); break;
|
||||
+ case 0x41: map_key_clear(KEY_PAGEDOWN); break;
|
||||
+ case 0x42: map_key_clear(KEY_PAGEUP); break;
|
||||
+ default: goto unknown;
|
||||
+ }
|
||||
+ break;
|
||||
+
|
||||
default:
|
||||
unknown:
|
||||
if (field->report_size == 1) {
|
||||
diff --git a/include/linux/hid.h b/include/linux/hid.h
|
||||
index 42a0f1d..083cfb2 100644
|
||||
--- a/include/linux/hid.h
|
||||
+++ b/include/linux/hid.h
|
||||
@@ -200,6 +200,7 @@ struct hid_item {
|
||||
#define HID_UP_MSVENDOR 0xff000000
|
||||
#define HID_UP_CUSTOM 0x00ff0000
|
||||
#define HID_UP_LOGIVENDOR 0xffbc0000
|
||||
+#define HID_UP_TIVOVENDOR 0xffff0000
|
||||
|
||||
#define HID_USAGE 0x0000ffff
|
||||
|
|
@ -0,0 +1,145 @@
|
|||
From 785465d9cffd65b5a69dd2f465d2f7c917713220 Mon Sep 17 00:00:00 2001
|
||||
From: Kyle McMartin <kyle@mcmartin.ca>
|
||||
Date: Mon, 18 Oct 2010 13:30:39 -0400
|
||||
Subject: [PATCH] ima: provide a toggle to disable it entirely
|
||||
|
||||
Signed-off-by: Kyle McMartin <kyle@redhat.com>
|
||||
---
|
||||
security/integrity/ima/ima.h | 1 +
|
||||
security/integrity/ima/ima_iint.c | 9 +++++++++
|
||||
security/integrity/ima/ima_main.c | 24 +++++++++++++++++++++---
|
||||
3 files changed, 31 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h
|
||||
index 3fbcd1d..65c3977 100644
|
||||
--- a/security/integrity/ima/ima.h
|
||||
+++ b/security/integrity/ima/ima.h
|
||||
@@ -37,6 +37,7 @@ enum tpm_pcrs { TPM_PCR0 = 0, TPM_PCR8 = 8 };
|
||||
/* set during initialization */
|
||||
extern int iint_initialized;
|
||||
extern int ima_initialized;
|
||||
+extern int ima_enabled;
|
||||
extern int ima_used_chip;
|
||||
extern char *ima_hash;
|
||||
|
||||
diff --git a/security/integrity/ima/ima_iint.c b/security/integrity/ima/ima_iint.c
|
||||
index afba4ae..3d191ef 100644
|
||||
--- a/security/integrity/ima/ima_iint.c
|
||||
+++ b/security/integrity/ima/ima_iint.c
|
||||
@@ -54,6 +54,9 @@ int ima_inode_alloc(struct inode *inode)
|
||||
struct ima_iint_cache *iint = NULL;
|
||||
int rc = 0;
|
||||
|
||||
+ if (!ima_enabled)
|
||||
+ return 0;
|
||||
+
|
||||
iint = kmem_cache_alloc(iint_cache, GFP_NOFS);
|
||||
if (!iint)
|
||||
return -ENOMEM;
|
||||
@@ -116,6 +119,9 @@ void ima_inode_free(struct inode *inode)
|
||||
{
|
||||
struct ima_iint_cache *iint;
|
||||
|
||||
+ if (!ima_enabled)
|
||||
+ return;
|
||||
+
|
||||
spin_lock(&ima_iint_lock);
|
||||
iint = radix_tree_delete(&ima_iint_store, (unsigned long)inode);
|
||||
spin_unlock(&ima_iint_lock);
|
||||
@@ -139,6 +145,9 @@ static void init_once(void *foo)
|
||||
|
||||
static int __init ima_iintcache_init(void)
|
||||
{
|
||||
+ if (!ima_enabled)
|
||||
+ return 0;
|
||||
+
|
||||
iint_cache =
|
||||
kmem_cache_create("iint_cache", sizeof(struct ima_iint_cache), 0,
|
||||
SLAB_PANIC, init_once);
|
||||
diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c
|
||||
index e662b89..6e91905 100644
|
||||
--- a/security/integrity/ima/ima_main.c
|
||||
+++ b/security/integrity/ima/ima_main.c
|
||||
@@ -26,6 +26,7 @@
|
||||
#include "ima.h"
|
||||
|
||||
int ima_initialized;
|
||||
+int ima_enabled;
|
||||
|
||||
char *ima_hash = "sha1";
|
||||
static int __init hash_setup(char *str)
|
||||
@@ -36,6 +37,14 @@ static int __init hash_setup(char *str)
|
||||
}
|
||||
__setup("ima_hash=", hash_setup);
|
||||
|
||||
+static int __init ima_enable(char *str)
|
||||
+{
|
||||
+ if (strncmp(str, "on", 2) == 0)
|
||||
+ ima_enabled = 1;
|
||||
+ return 1;
|
||||
+}
|
||||
+__setup("ima=", ima_enable);
|
||||
+
|
||||
struct ima_imbalance {
|
||||
struct hlist_node node;
|
||||
unsigned long fsmagic;
|
||||
@@ -148,7 +157,7 @@ void ima_counts_get(struct file *file)
|
||||
struct ima_iint_cache *iint;
|
||||
int rc;
|
||||
|
||||
- if (!iint_initialized || !S_ISREG(inode->i_mode))
|
||||
+ if (!ima_enabled || !iint_initialized || !S_ISREG(inode->i_mode))
|
||||
return;
|
||||
iint = ima_iint_find_get(inode);
|
||||
if (!iint)
|
||||
@@ -215,7 +224,7 @@ void ima_file_free(struct file *file)
|
||||
struct inode *inode = file->f_dentry->d_inode;
|
||||
struct ima_iint_cache *iint;
|
||||
|
||||
- if (!iint_initialized || !S_ISREG(inode->i_mode))
|
||||
+ if (!ima_enabled || !iint_initialized || !S_ISREG(inode->i_mode))
|
||||
return;
|
||||
iint = ima_iint_find_get(inode);
|
||||
if (!iint)
|
||||
@@ -269,7 +278,7 @@ int ima_file_mmap(struct file *file, unsigned long prot)
|
||||
{
|
||||
int rc;
|
||||
|
||||
- if (!file)
|
||||
+ if (!ima_enabled || !file)
|
||||
return 0;
|
||||
if (prot & PROT_EXEC)
|
||||
rc = process_measurement(file, file->f_dentry->d_name.name,
|
||||
@@ -294,6 +303,9 @@ int ima_bprm_check(struct linux_binprm *bprm)
|
||||
{
|
||||
int rc;
|
||||
|
||||
+ if (!ima_enabled)
|
||||
+ return 0;
|
||||
+
|
||||
rc = process_measurement(bprm->file, bprm->filename,
|
||||
MAY_EXEC, BPRM_CHECK);
|
||||
return 0;
|
||||
@@ -313,6 +325,9 @@ int ima_file_check(struct file *file, int mask)
|
||||
{
|
||||
int rc;
|
||||
|
||||
+ if (!ima_enabled)
|
||||
+ return 0;
|
||||
+
|
||||
rc = process_measurement(file, file->f_dentry->d_name.name,
|
||||
mask & (MAY_READ | MAY_WRITE | MAY_EXEC),
|
||||
FILE_CHECK);
|
||||
@@ -324,6 +339,9 @@ static int __init init_ima(void)
|
||||
{
|
||||
int error;
|
||||
|
||||
+ if (!ima_enabled)
|
||||
+ return 0;
|
||||
+
|
||||
error = ima_init();
|
||||
ima_initialized = 1;
|
||||
return error;
|
||||
--
|
||||
1.7.3.1
|
||||
|
609
kernel.spec
609
kernel.spec
|
@ -6,7 +6,7 @@ Summary: The Linux kernel
|
|||
# For a stable, released kernel, released_kernel should be 1. For rawhide
|
||||
# and/or a kernel built from an rc or git snapshot, released_kernel should
|
||||
# be 0.
|
||||
%global released_kernel 0
|
||||
%global released_kernel 1
|
||||
|
||||
# Save original buildid for later if it's defined
|
||||
%if 0%{?buildid:1}
|
||||
|
@ -23,6 +23,7 @@ Summary: The Linux kernel
|
|||
#
|
||||
# (Uncomment the '#' and both spaces below to set the buildid.)
|
||||
#
|
||||
%define buildid .lr645937
|
||||
# % define buildid .local
|
||||
###################################################################
|
||||
|
||||
|
@ -48,7 +49,7 @@ Summary: The Linux kernel
|
|||
# reset this by hand to 1 (or to 0 and then use rpmdev-bumpspec).
|
||||
# scripts/rebase.sh should be made to do that for you, actually.
|
||||
#
|
||||
%global baserelease 0
|
||||
%global baserelease 50
|
||||
%global fedora_build %{baserelease}
|
||||
|
||||
# base_sublevel is the kernel version we're starting with and patching
|
||||
|
@ -60,7 +61,7 @@ Summary: The Linux kernel
|
|||
%if 0%{?released_kernel}
|
||||
|
||||
# Do we have a -stable update to apply?
|
||||
%define stable_update 0
|
||||
%define stable_update 6
|
||||
# Is it a -stable RC?
|
||||
%define stable_rc 0
|
||||
# Set rpm version accordingly
|
||||
|
@ -125,7 +126,7 @@ Summary: The Linux kernel
|
|||
%define doc_build_fail true
|
||||
%endif
|
||||
|
||||
%define rawhide_skip_docs 1
|
||||
%define rawhide_skip_docs 0
|
||||
%if 0%{?rawhide_skip_docs}
|
||||
%define with_doc 0
|
||||
%define doc_build_fail true
|
||||
|
@ -146,7 +147,7 @@ Summary: The Linux kernel
|
|||
# Set debugbuildsenabled to 1 for production (build separate debug kernels)
|
||||
# and 0 for rawhide (all kernels are debug kernels).
|
||||
# See also 'make debug' and 'make release'.
|
||||
%define debugbuildsenabled 0
|
||||
%define debugbuildsenabled 1
|
||||
|
||||
# Want to build a vanilla kernel build without any non-upstream patches?
|
||||
# (well, almost none, we need nonintconfig for build purposes). Default to 0 (off).
|
||||
|
@ -326,6 +327,10 @@ Summary: The Linux kernel
|
|||
%define kernel_image arch/s390/boot/image
|
||||
%endif
|
||||
|
||||
%ifarch sparcv9
|
||||
%define hdrarch sparc
|
||||
%endif
|
||||
|
||||
%ifarch sparc64
|
||||
%define asmarch sparc
|
||||
%define all_arch_configs kernel-%{version}-sparc64*.config
|
||||
|
@ -387,7 +392,7 @@ Summary: The Linux kernel
|
|||
# Which is a BadThing(tm).
|
||||
|
||||
# We only build kernel-headers on the following...
|
||||
%define nobuildarches i386 s390 sparc %{arm}
|
||||
%define nobuildarches i386 s390 sparc sparcv9 %{arm}
|
||||
|
||||
%ifarch %nobuildarches
|
||||
%define with_up 0
|
||||
|
@ -451,7 +456,7 @@ Requires(pre): %{initrd_prereq}\
|
|||
%if %{with_firmware}\
|
||||
Requires(pre): kernel-firmware >= %{rpmversion}-%{pkg_release}\
|
||||
%else\
|
||||
Requires(pre): linux-firmware\
|
||||
Requires(pre): linux-firmware >= 20100806-2\
|
||||
%endif\
|
||||
Requires(post): /sbin/new-kernel-pkg\
|
||||
Requires(preun): /sbin/new-kernel-pkg\
|
||||
|
@ -475,7 +480,7 @@ Version: %{rpmversion}
|
|||
Release: %{pkg_release}
|
||||
# DO NOT CHANGE THE 'ExclusiveArch' LINE TO TEMPORARILY EXCLUDE AN ARCHITECTURE BUILD.
|
||||
# SET %%nobuildarches (ABOVE) INSTEAD
|
||||
ExclusiveArch: noarch %{all_x86} x86_64 ppc ppc64 ia64 sparc sparc64 s390 s390x alpha alphaev56 %{arm}
|
||||
ExclusiveArch: noarch %{all_x86} x86_64 ppc ppc64 ia64 sparc sparcv9 sparc64 s390 s390x alpha alphaev56 %{arm}
|
||||
ExclusiveOS: Linux
|
||||
|
||||
%kernel_reqprovconf
|
||||
|
@ -495,8 +500,9 @@ BuildRequires: xmlto, asciidoc
|
|||
%if %{with_sparse}
|
||||
BuildRequires: sparse >= 0.4.1
|
||||
%endif
|
||||
# python-devel and perl(ExtUtils::Embed) are required for perf scripting
|
||||
%if %{with_perf}
|
||||
BuildRequires: elfutils-devel zlib-devel binutils-devel
|
||||
BuildRequires: elfutils-devel zlib-devel binutils-devel python-devel perl(ExtUtils::Embed)
|
||||
%endif
|
||||
BuildConflicts: rhbuildsys(DiskFree) < 500Mb
|
||||
|
||||
|
@ -612,7 +618,13 @@ Patch202: linux-2.6-debug-taint-vm.patch
|
|||
Patch203: linux-2.6-debug-vm-would-have-oomkilled.patch
|
||||
Patch204: linux-2.6-debug-always-inline-kzalloc.patch
|
||||
|
||||
Patch300: create-sys-fs-cgroup-to-mount-cgroupfs-on.patch
|
||||
|
||||
Patch360: disable-xhci-by-default.patch
|
||||
|
||||
Patch380: linux-2.6-defaults-pci_no_msi.patch
|
||||
Patch381: linux-2.6-defaults-pci_use_crs.patch
|
||||
Patch382: linux-2.6-defaults-no-pm-async.patch
|
||||
Patch383: linux-2.6-defaults-aspm.patch
|
||||
Patch384: pci-acpi-disable-aspm-if-no-osc.patch
|
||||
Patch385: pci-aspm-dont-enable-too-early.patch
|
||||
|
@ -637,6 +649,8 @@ Patch580: linux-2.6-sparc-selinux-mprotect-checks.patch
|
|||
|
||||
Patch610: hda_intel-prealloc-4mb-dmabuffer.patch
|
||||
|
||||
Patch700: linux-2.6-e1000-ich9-montevina.patch
|
||||
|
||||
Patch800: linux-2.6-crash-driver.patch
|
||||
|
||||
# crypto/
|
||||
|
@ -647,14 +661,25 @@ Patch1555: fix_xen_guest_on_old_EC2.patch
|
|||
# DRM
|
||||
Patch1801: drm-revert-drm-fbdev-rework-output-polling-to-be-back-in-core.patch
|
||||
Patch1802: revert-drm-kms-toggle-poll-around-switcheroo.patch
|
||||
# drm fixes nouveau depends on
|
||||
Patch1805: drm-simplify-i2c-config.patch
|
||||
Patch1806: drm-sil164-module.patch
|
||||
Patch1807: drm-i2c-ch7006-fix.patch
|
||||
Patch1808: drm-ttm-fix.patch
|
||||
# nouveau + drm fixes
|
||||
Patch1810: drm-nouveau-updates.patch
|
||||
Patch1811: drm-nouveau-race-fix.patch
|
||||
Patch1812: drm-nouveau-nva3-noaccel.patch
|
||||
Patch1813: drm-nouveau-nv86-bug.patch
|
||||
Patch1814: drm-nouveau-nv50-crtc-update-delay.patch
|
||||
Patch1819: drm-intel-big-hammer.patch
|
||||
# intel drm is all merged upstream
|
||||
Patch1824: drm-intel-next.patch
|
||||
# make sure the lvds comes back on lid open
|
||||
Patch1825: drm-intel-make-lvds-work.patch
|
||||
Patch1900: linux-2.6-intel-iommu-igfx.patch
|
||||
Patch2000: efifb-add-more-models.patch
|
||||
Patch2001: efifb-check-that-the-base-addr-is-plausible-on-pci-systems.patch
|
||||
|
||||
# linux1394 git patches
|
||||
Patch2200: linux-2.6-firewire-git-update.patch
|
||||
|
@ -674,18 +699,23 @@ Patch2910: linux-2.6-v4l-dvb-add-lgdt3304-support.patch
|
|||
Patch2911: linux-2.6-v4l-dvb-add-kworld-a340-support.patch
|
||||
Patch2912: linux-2.6-v4l-dvb-ir-core-update.patch
|
||||
Patch2913: linux-2.6-v4l-dvb-ir-core-memleak-fixes.patch
|
||||
Patch2914: linux-2.6-v4l-dvb-ir-core-streamzap.patch
|
||||
|
||||
Patch2915: lirc-staging-2.6.36.patch
|
||||
#Patch2916: lirc-staging-2.6.36-fixes.patch
|
||||
Patch2917: hdpvr-ir-enable.patch
|
||||
Patch2918: linux-2.6-v4l-dvb-ir-core-update-2.patch
|
||||
Patch2919: linux-2.6-v4l-dvb-ir-core-update-3.patch
|
||||
Patch2920: linux-2.6-lirc-ioctl-compat-fixups.patch
|
||||
Patch2923: linux-2.6-v4l-dvb-ir-core-fix-imon.patch
|
||||
|
||||
# fs fixes
|
||||
Patch3000: linux-2.6-ext4-fix-freeze-deadlock.patch
|
||||
Patch2950: linux-2.6-via-velocity-dma-fix.patch
|
||||
|
||||
Patch3000: linux-2.6-rcu-sched-warning.patch
|
||||
Patch3010: linux-2.6-rcu-netpoll.patch
|
||||
|
||||
# NFSv4
|
||||
|
||||
# VIA Nano / VX8xx updates
|
||||
|
||||
# patches headed upstream
|
||||
|
||||
Patch12016: disable-i8042-check-on-apple-mac.patch
|
||||
|
@ -694,10 +724,61 @@ Patch12017: prevent-runtime-conntrack-changes.patch
|
|||
|
||||
Patch12018: neuter_intel_microcode_load.patch
|
||||
|
||||
Patch12030: ssb_check_for_sprom.patch
|
||||
Patch12019: add-appleir-usb-driver.patch
|
||||
|
||||
Patch12020: hid-support-tivo-slide-remote.patch
|
||||
|
||||
Patch12040: only-use-alpha2-regulatory-information-from-country-IE.patch
|
||||
|
||||
Patch12080: kprobes-x86-fix-kprobes-to-skip-prefixes-correctly.patch
|
||||
|
||||
# rhbz #622149
|
||||
Patch12085: fix-rcu_deref_check-warning.patch
|
||||
Patch12086: linux-2.6-cgroups-rcu.patch
|
||||
|
||||
Patch12517: flexcop-fix-xlate_proc_name-warning.patch
|
||||
|
||||
# mitigate DOS attack with large argument lists
|
||||
Patch12520: execve-improve-interactivity-with-large-arguments.patch
|
||||
Patch12521: execve-make-responsive-to-sigkill-with-large-arguments.patch
|
||||
Patch12522: setup_arg_pages-diagnose-excessive-argument-size.patch
|
||||
|
||||
Patch12565: sched-05-avoid-side-effect-of-tickless-idle-on-update_cpu_load.patch
|
||||
Patch12570: sched-10-change-nohz-idle-load-balancing-logic-to-push-model.patch
|
||||
Patch12575: sched-15-update-rq-clock-for-nohz-balanced-cpus.patch
|
||||
Patch12580: sched-20-fix-rq-clock-synchronization-when-migrating-tasks.patch
|
||||
Patch12585: sched-25-move-sched_avg_update-to-update_cpu_load.patch
|
||||
Patch12590: sched-30-sched-fix-nohz-balance-kick.patch
|
||||
Patch12595: sched-35-increment-cache_nice_tries-only-on-periodic-lb.patch
|
||||
|
||||
Patch13600: btusb-macbookpro-6-2.patch
|
||||
Patch13601: btusb-macbookpro-7-1.patch
|
||||
|
||||
Patch13603: pnpacpi-cope-with-invalid-device-ids.patch
|
||||
|
||||
Patch13610: libata-it821x-dump-stack-on-cache-flush.patch
|
||||
Patch13620: xen-fix-typo-in-xen-irq-fix.patch
|
||||
|
||||
Patch13630: dm-allow-setting-of-uuid-via-rename-if-not-already-set.patch
|
||||
|
||||
Patch13635: r8169-fix-dma-allocations.patch
|
||||
Patch13636: skge-quirk-to-4gb-dma.patch
|
||||
|
||||
Patch13637: dmar-disable-when-ricoh-multifunction.patch
|
||||
|
||||
Patch13638: ima-allow-it-to-be-completely-disabled-and-default-off.patch
|
||||
|
||||
Patch13640: sdhci-8-bit-data-transfer-width-support.patch
|
||||
Patch13641: mmc-make-sdhci-work-with-ricoh-mmc-controller.patch
|
||||
Patch13642: mmc-add-ricoh-e822-pci-id.patch
|
||||
|
||||
Patch13645: tpm-autodetect-itpm-devices.patch
|
||||
Patch13646: depessimize-rds_copy_page_user.patch
|
||||
|
||||
Patch13650: drm-i915-sanity-check-pread-pwrite.patch
|
||||
Patch13651: kvm-fix-fs-gs-reload-oops-with-invalid-ldt.patch
|
||||
Patch13652: v4l1-fix-32-bit-compat-microcode-loading-translation.patch
|
||||
|
||||
%endif
|
||||
|
||||
BuildRoot: %{_tmppath}/kernel-%{KVERREL}-root
|
||||
|
@ -969,16 +1050,23 @@ ApplyOptionalPatch()
|
|||
%endif
|
||||
%endif
|
||||
|
||||
# We can share hardlinked source trees by putting a list of
|
||||
# directory names of the CVS checkouts that we want to share
|
||||
# with in .shared-srctree. (Full pathnames are required.)
|
||||
[ -f .shared-srctree ] && sharedirs=$(cat .shared-srctree)
|
||||
# %{vanillaversion} : the full version name, e.g. 2.6.35-rc6-git3
|
||||
# %{kversion} : the base version, e.g. 2.6.34
|
||||
|
||||
if [ ! -d kernel-%{kversion}/vanilla-%{vanillaversion} ]; then
|
||||
# Use kernel-%{kversion}%{?dist} as the top-level directory name
|
||||
# so we can prep different trees within a single git directory.
|
||||
|
||||
if [ -d kernel-%{kversion}/vanilla-%{kversion} ]; then
|
||||
# Build a list of the other top-level kernel tree directories.
|
||||
# This will be used to hardlink identical vanilla subdirs.
|
||||
sharedirs=$(find "$PWD" -maxdepth 1 -type d -name 'kernel-2.6.*' \
|
||||
| grep -x -v "$PWD"/kernel-%{kversion}%{?dist}) ||:
|
||||
|
||||
cd kernel-%{kversion}
|
||||
if [ ! -d kernel-%{kversion}%{?dist}/vanilla-%{vanillaversion} ]; then
|
||||
|
||||
if [ -d kernel-%{kversion}%{?dist}/vanilla-%{kversion} ]; then
|
||||
|
||||
# The base vanilla version already exists.
|
||||
cd kernel-%{kversion}%{?dist}
|
||||
|
||||
# Any vanilla-* directories other than the base one are stale.
|
||||
for dir in vanilla-*; do
|
||||
|
@ -987,18 +1075,18 @@ if [ ! -d kernel-%{kversion}/vanilla-%{vanillaversion} ]; then
|
|||
|
||||
else
|
||||
|
||||
# Ok, first time we do a make prep.
|
||||
rm -f pax_global_header
|
||||
# Look for an identical base vanilla dir that can be hardlinked.
|
||||
for sharedir in $sharedirs ; do
|
||||
if [[ ! -z $sharedir && -d $sharedir/kernel-%{kversion}/vanilla-%{kversion} ]] ; then
|
||||
if [[ ! -z $sharedir && -d $sharedir/vanilla-%{kversion} ]] ; then
|
||||
break
|
||||
fi
|
||||
done
|
||||
if [[ ! -z $sharedir && -d $sharedir/kernel-%{kversion}/vanilla-%{kversion} ]] ; then
|
||||
%setup -q -n kernel-%{kversion} -c -T
|
||||
cp -rl $sharedir/kernel-%{kversion}/vanilla-%{kversion} .
|
||||
if [[ ! -z $sharedir && -d $sharedir/vanilla-%{kversion} ]] ; then
|
||||
%setup -q -n kernel-%{kversion}%{?dist} -c -T
|
||||
cp -rl $sharedir/vanilla-%{kversion} .
|
||||
else
|
||||
%setup -q -n kernel-%{kversion} -c
|
||||
%setup -q -n kernel-%{kversion}%{?dist} -c
|
||||
mv linux-%{kversion} vanilla-%{kversion}
|
||||
fi
|
||||
|
||||
|
@ -1007,16 +1095,17 @@ if [ ! -d kernel-%{kversion}/vanilla-%{vanillaversion} ]; then
|
|||
%if "%{kversion}" != "%{vanillaversion}"
|
||||
|
||||
for sharedir in $sharedirs ; do
|
||||
if [[ ! -z $sharedir && -d $sharedir/kernel-%{kversion}/vanilla-%{vanillaversion} ]] ; then
|
||||
if [[ ! -z $sharedir && -d $sharedir/vanilla-%{vanillaversion} ]] ; then
|
||||
break
|
||||
fi
|
||||
done
|
||||
if [[ ! -z $sharedir && -d $sharedir/kernel-%{kversion}/vanilla-%{vanillaversion} ]] ; then
|
||||
if [[ ! -z $sharedir && -d $sharedir/vanilla-%{vanillaversion} ]] ; then
|
||||
|
||||
cp -rl $sharedir/kernel-%{kversion}/vanilla-%{vanillaversion} .
|
||||
cp -rl $sharedir/vanilla-%{vanillaversion} .
|
||||
|
||||
else
|
||||
|
||||
# Need to apply patches to the base vanilla version.
|
||||
cp -rl vanilla-%{kversion} vanilla-%{vanillaversion}
|
||||
cd vanilla-%{vanillaversion}
|
||||
|
||||
|
@ -1041,10 +1130,13 @@ if [ ! -d kernel-%{kversion}/vanilla-%{vanillaversion} ]; then
|
|||
%endif
|
||||
|
||||
else
|
||||
# We already have a vanilla dir.
|
||||
cd kernel-%{kversion}
|
||||
|
||||
# We already have all vanilla dirs, just change to the top-level directory.
|
||||
cd kernel-%{kversion}%{?dist}
|
||||
|
||||
fi
|
||||
|
||||
# Now build the fedora kernel tree.
|
||||
if [ -d linux-%{kversion}.%{_target_cpu} ]; then
|
||||
# Just in case we ctrl-c'd a prep already
|
||||
rm -rf deleteme.%{_target_cpu}
|
||||
|
@ -1139,7 +1231,6 @@ ApplyPatch linux-2.6-32bit-mmap-exec-randomization.patch
|
|||
#
|
||||
|
||||
# ext4
|
||||
ApplyPatch linux-2.6-ext4-fix-freeze-deadlock.patch
|
||||
|
||||
# xfs
|
||||
|
||||
|
@ -1151,6 +1242,7 @@ ApplyPatch linux-2.6-ext4-fix-freeze-deadlock.patch
|
|||
# NFSv4
|
||||
|
||||
# USB
|
||||
ApplyPatch disable-xhci-by-default.patch
|
||||
|
||||
# WMI
|
||||
|
||||
|
@ -1159,6 +1251,7 @@ ApplyPatch linux-2.6-defaults-acpi-video.patch
|
|||
ApplyPatch linux-2.6-acpi-video-dos.patch
|
||||
ApplyPatch acpi-ec-add-delay-before-write.patch
|
||||
ApplyPatch linux-2.6-acpi-debug-infinite-loop.patch
|
||||
ApplyPatch linux-2.6-defaults-no-pm-async.patch
|
||||
|
||||
# Various low-impact patches to aid debugging.
|
||||
ApplyPatch linux-2.6-debug-sizeof-structs.patch
|
||||
|
@ -1172,6 +1265,7 @@ ApplyPatch linux-2.6-debug-always-inline-kzalloc.patch
|
|||
#
|
||||
# make default state of PCI MSI a config option
|
||||
ApplyPatch linux-2.6-defaults-pci_no_msi.patch
|
||||
ApplyPatch linux-2.6-defaults-pci_use_crs.patch
|
||||
# enable ASPM by default on hardware we expect to work
|
||||
ApplyPatch linux-2.6-defaults-aspm.patch
|
||||
# disable aspm if acpi doesn't provide an _OSC method
|
||||
|
@ -1217,11 +1311,15 @@ ApplyPatch linux-2.6-silence-fbcon-logo.patch
|
|||
#ApplyPatch linux-2.6-sparc-selinux-mprotect-checks.patch
|
||||
|
||||
# Changes to upstream defaults.
|
||||
ApplyPatch create-sys-fs-cgroup-to-mount-cgroupfs-on.patch
|
||||
|
||||
|
||||
# /dev/crash driver.
|
||||
ApplyPatch linux-2.6-crash-driver.patch
|
||||
|
||||
# Hack e1000e to work on Montevina SDV
|
||||
ApplyPatch linux-2.6-e1000-ich9-montevina.patch
|
||||
|
||||
# crypto/
|
||||
|
||||
# Assorted Virt Fixes
|
||||
|
@ -1230,13 +1328,25 @@ ApplyPatch fix_xen_guest_on_old_EC2.patch
|
|||
#ApplyPatch drm-revert-drm-fbdev-rework-output-polling-to-be-back-in-core.patch
|
||||
#ApplyPatch revert-drm-kms-toggle-poll-around-switcheroo.patch
|
||||
|
||||
ApplyPatch drm-simplify-i2c-config.patch
|
||||
ApplyPatch drm-sil164-module.patch
|
||||
ApplyPatch drm-i2c-ch7006-fix.patch
|
||||
ApplyPatch drm-ttm-fix.patch
|
||||
# Nouveau DRM + drm fixes
|
||||
ApplyPatch drm-nouveau-updates.patch
|
||||
ApplyPatch drm-nouveau-race-fix.patch
|
||||
ApplyPatch drm-nouveau-nva3-noaccel.patch
|
||||
ApplyPatch drm-nouveau-nv86-bug.patch
|
||||
ApplyPatch drm-nouveau-nv50-crtc-update-delay.patch
|
||||
|
||||
ApplyPatch drm-intel-big-hammer.patch
|
||||
ApplyOptionalPatch drm-intel-next.patch
|
||||
ApplyPatch drm-intel-make-lvds-work.patch
|
||||
ApplyPatch linux-2.6-intel-iommu-igfx.patch
|
||||
|
||||
ApplyPatch efifb-add-more-models.patch
|
||||
ApplyPatch efifb-check-that-the-base-addr-is-plausible-on-pci-systems.patch
|
||||
|
||||
# linux1394 git patches
|
||||
#ApplyPatch linux-2.6-firewire-git-update.patch
|
||||
#ApplyOptionalPatch linux-2.6-firewire-git-pending.patch
|
||||
|
@ -1253,6 +1363,7 @@ ApplyPatch linux-2.6-v4l-dvb-uvcvideo-update.patch
|
|||
|
||||
ApplyPatch linux-2.6-v4l-dvb-ir-core-update.patch
|
||||
ApplyPatch linux-2.6-v4l-dvb-ir-core-memleak-fixes.patch
|
||||
ApplyPatch linux-2.6-v4l-dvb-ir-core-streamzap.patch
|
||||
ApplyPatch linux-2.6-v4l-dvb-add-lgdt3304-support.patch
|
||||
ApplyPatch linux-2.6-v4l-dvb-add-kworld-a340-support.patch
|
||||
|
||||
|
@ -1261,17 +1372,93 @@ ApplyPatch lirc-staging-2.6.36.patch
|
|||
#ApplyOptionalPatch lirc-staging-2.6.36-fixes.patch
|
||||
# enable IR receiver on Hauppauge HD PVR (v4l-dvb merge pending)
|
||||
ApplyPatch hdpvr-ir-enable.patch
|
||||
ApplyPatch linux-2.6-v4l-dvb-ir-core-update-2.patch
|
||||
ApplyPatch linux-2.6-v4l-dvb-ir-core-update-3.patch
|
||||
ApplyPatch linux-2.6-lirc-ioctl-compat-fixups.patch
|
||||
ApplyPatch linux-2.6-v4l-dvb-ir-core-fix-imon.patch
|
||||
|
||||
# Fix DMA bug on via-velocity
|
||||
ApplyPatch linux-2.6-via-velocity-dma-fix.patch
|
||||
|
||||
# silence another rcu_reference warning
|
||||
ApplyPatch linux-2.6-rcu-sched-warning.patch
|
||||
ApplyPatch linux-2.6-rcu-netpoll.patch
|
||||
|
||||
# Patches headed upstream
|
||||
ApplyPatch disable-i8042-check-on-apple-mac.patch
|
||||
|
||||
ApplyPatch add-appleir-usb-driver.patch
|
||||
|
||||
ApplyPatch hid-support-tivo-slide-remote.patch
|
||||
|
||||
ApplyPatch neuter_intel_microcode_load.patch
|
||||
|
||||
# rhbz#533746
|
||||
#ApplyPatch ssb_check_for_sprom.patch
|
||||
|
||||
ApplyPatch only-use-alpha2-regulatory-information-from-country-IE.patch
|
||||
|
||||
# bz 610941
|
||||
ApplyPatch kprobes-x86-fix-kprobes-to-skip-prefixes-correctly.patch
|
||||
|
||||
# bz 622149
|
||||
ApplyPatch fix-rcu_deref_check-warning.patch
|
||||
ApplyPatch linux-2.6-cgroups-rcu.patch
|
||||
|
||||
# bz #575873
|
||||
ApplyPatch flexcop-fix-xlate_proc_name-warning.patch
|
||||
|
||||
# mitigate DOS attack with large argument lists
|
||||
ApplyPatch execve-improve-interactivity-with-large-arguments.patch
|
||||
ApplyPatch execve-make-responsive-to-sigkill-with-large-arguments.patch
|
||||
ApplyPatch setup_arg_pages-diagnose-excessive-argument-size.patch
|
||||
|
||||
# Scheduler fixes (#635813 and #633037)
|
||||
ApplyPatch sched-05-avoid-side-effect-of-tickless-idle-on-update_cpu_load.patch
|
||||
ApplyPatch sched-10-change-nohz-idle-load-balancing-logic-to-push-model.patch
|
||||
ApplyPatch sched-15-update-rq-clock-for-nohz-balanced-cpus.patch
|
||||
ApplyPatch sched-20-fix-rq-clock-synchronization-when-migrating-tasks.patch
|
||||
ApplyPatch sched-25-move-sched_avg_update-to-update_cpu_load.patch
|
||||
ApplyPatch sched-30-sched-fix-nohz-balance-kick.patch
|
||||
ApplyPatch sched-35-increment-cache_nice_tries-only-on-periodic-lb.patch
|
||||
|
||||
ApplyPatch btusb-macbookpro-7-1.patch
|
||||
ApplyPatch btusb-macbookpro-6-2.patch
|
||||
|
||||
# temporary patch, dump stack on failed it821x commands
|
||||
ApplyPatch libata-it821x-dump-stack-on-cache-flush.patch
|
||||
|
||||
# temporary fix for typo in Xen -stable patch
|
||||
ApplyPatch xen-fix-typo-in-xen-irq-fix.patch
|
||||
|
||||
# rhbz#641468
|
||||
ApplyPatch pnpacpi-cope-with-invalid-device-ids.patch
|
||||
|
||||
# rhbz#641476
|
||||
ApplyPatch dm-allow-setting-of-uuid-via-rename-if-not-already-set.patch
|
||||
|
||||
# rhbz#629158
|
||||
ApplyPatch r8169-fix-dma-allocations.patch
|
||||
# rhbz#447489
|
||||
ApplyPatch skge-quirk-to-4gb-dma.patch
|
||||
|
||||
# rhbz#605888
|
||||
ApplyPatch dmar-disable-when-ricoh-multifunction.patch
|
||||
|
||||
ApplyPatch ima-allow-it-to-be-completely-disabled-and-default-off.patch
|
||||
|
||||
# rhbz#596475
|
||||
ApplyPatch sdhci-8-bit-data-transfer-width-support.patch
|
||||
ApplyPatch mmc-make-sdhci-work-with-ricoh-mmc-controller.patch
|
||||
ApplyPatch mmc-add-ricoh-e822-pci-id.patch
|
||||
|
||||
ApplyPatch depessimize-rds_copy_page_user.patch
|
||||
ApplyPatch tpm-autodetect-itpm-devices.patch
|
||||
|
||||
# CVE-2010-2962
|
||||
ApplyPatch drm-i915-sanity-check-pread-pwrite.patch
|
||||
# CVE-2010-3698
|
||||
ApplyPatch kvm-fix-fs-gs-reload-oops-with-invalid-ldt.patch
|
||||
# CVE-2010-2963
|
||||
ApplyPatch v4l1-fix-32-bit-compat-microcode-loading-translation.patch
|
||||
|
||||
# END OF PATCH APPLICATIONS
|
||||
|
||||
%endif
|
||||
|
@ -1296,6 +1483,8 @@ done
|
|||
rm -f kernel-%{version}-*debug.config
|
||||
%endif
|
||||
|
||||
touch .scmversion
|
||||
|
||||
# now run oldconfig over all the config files
|
||||
for i in *.config
|
||||
do
|
||||
|
@ -1571,7 +1760,7 @@ BuildKernel %make_target %kernel_image smp
|
|||
|
||||
%if %{with_doc}
|
||||
# Make the HTML and man pages.
|
||||
make %{?_smp_mflags} htmldocs mandocs || %{doc_build_fail}
|
||||
make htmldocs mandocs || %{doc_build_fail}
|
||||
|
||||
# sometimes non-world-readable files sneak into the kernel source tree
|
||||
chmod -R a=rX Documentation
|
||||
|
@ -1855,17 +2044,343 @@ fi
|
|||
# plz don't put in a version string unless you're going to tag
|
||||
# and build.
|
||||
|
||||
# ___________________________________________________________
|
||||
# / This branch is for Fedora 14. You probably want to commit \
|
||||
# \ to the F-13 branch instead, or in addition to this one. /
|
||||
# -----------------------------------------------------------
|
||||
# \ ^__^
|
||||
# \ (@@)\_______
|
||||
# (__)\ )\/\
|
||||
# ||----w |
|
||||
# || ||
|
||||
|
||||
%changelog
|
||||
* Tue Nov 02 2010 Ben Skeggs <bskeggs@redhat.com> 2.6.35.6-50
|
||||
- nouveau: add potential workaround for NV86 hardware quirk
|
||||
- fix issue that occurs in certain dual-head configurations (rhbz#641524)
|
||||
|
||||
* Sat Oct 23 2010 Jarod Wilson <jarod@redhat.com> 2.6.35.6-49
|
||||
- Fix brown paper bag bug in imon driver
|
||||
|
||||
* Fri Oct 22 2010 Chuck Ebbert <cebbert@redhat.com> 2.6.35.6-48
|
||||
- drm-i915-sanity-check-pread-pwrite.patch;
|
||||
fix CVE-2010-2962, arbitrary kernel memory write via i915 GEM ioctl
|
||||
- kvm-fix-fs-gs-reload-oops-with-invalid-ldt.patch;
|
||||
fix CVE-2010-3698, kvm: invalid selector in fs/gs causes kernel panic
|
||||
- v4l1-fix-32-bit-compat-microcode-loading-translation.patch;
|
||||
fixes CVE-2010-2963, v4l: VIDIOCSMICROCODE arbitrary write
|
||||
|
||||
* Fri Oct 22 2010 Kyle McMartin <kyle@redhat.com> 2.6.35.6-47
|
||||
- tpm-autodetect-itpm-devices.patch: Auto-fix TPM issues on various
|
||||
laptops which prevented suspend/resume.
|
||||
- depessimize-rds_copy_page_user.patch: Fix CVE-2010-3904, local
|
||||
privilege escalation via RDS protocol.
|
||||
|
||||
* Mon Oct 18 2010 Kyle McMartin <kyle@redhat.com> 2.6.35.6-46
|
||||
- Add Ricoh e822 support. (rhbz#596475) Thanks to sgruszka@ for
|
||||
sending the patches in.
|
||||
|
||||
* Mon Oct 18 2010 Kyle McMartin <kyle@redhat.com> 2.6.35.6-45
|
||||
- Print a useful message when disabling IOMMU when a Ricoh cardreader
|
||||
is probed.
|
||||
- Disable eDP pipe bringup on i915 since it won't work anyway, and changes
|
||||
away from text-mode, resulting in nothing but a backlight on a lot of
|
||||
laptops. (rhbz#639146)
|
||||
|
||||
* Mon Oct 18 2010 Kyle McMartin <kyle@redhat.com>
|
||||
- ima: Default it to off, pass ima=on to enable. Reduce impact of the option
|
||||
when disabled.
|
||||
|
||||
* Mon Oct 18 2010 Kyle McMartin <kyle@redhat.com>
|
||||
- Quirk to disable DMAR with Ricoh card reader/firewire. (rhbz#605888)
|
||||
|
||||
* Mon Oct 18 2010 Kyle McMartin <kyle@redhat.com>
|
||||
- Two networking fixes (skge, r8169) from sgruszka@. (rhbz#447489,629158)
|
||||
|
||||
* Fri Oct 15 2010 Kyle McMartin <kyle@redhat.com>
|
||||
- pnpacpi: cope with invalid device IDs. (rhbz#641468)
|
||||
|
||||
* Fri Oct 15 2010 Peter Jones <pjones@redhat.com> 2.6.35.6-44
|
||||
- Add a missing dm_put in previous device mapper patch.
|
||||
|
||||
* Wed Oct 13 2010 Dave Jones <davej@redhat.com> 2.6.35.6-43
|
||||
- bump build.
|
||||
|
||||
* Wed Oct 13 2010 Kyle McMartin <kyle@redhat.com>
|
||||
- Disable XHCI registration by default. Passing xhci.enable=1 to the
|
||||
kernel will enable it, as will
|
||||
echo "options xhci-hcd enable=1" >/etc/modprobe.d/xhci.conf
|
||||
This is necessary, because it is beginning to turn up on more and
|
||||
more boards, and prevents suspend if the device is probed (since it
|
||||
does not implement suspend handlers.)
|
||||
Simply removing the module alias would work (and require you to
|
||||
manually load the driver, like for floppy) however, there's a chance
|
||||
people would like to install onto usb3 drives, so let's provide them
|
||||
with an easy means to enable it (the grub cmdline.)
|
||||
|
||||
* Tue Oct 12 2010 Kyle McMartin <kyle@redhat.com> 2.6.35.6-42
|
||||
- Fix devicemapper UUID field cannot be assigned after map creation
|
||||
(rhbz#641476) thanks pjones@.
|
||||
|
||||
* Mon Oct 11 2010 Jarod Wilson <jarod@redhat.com> 2.6.35.6-40
|
||||
- update imon driver to fix issues with key releases and properly
|
||||
auto-configure another 0xffdc device (VFD + MCE IR)
|
||||
- add new nuvoton-cir driver (for integrated IR in ASRock ION 330HT)
|
||||
- add lirc compat ioctl portability fixups
|
||||
|
||||
* Mon Oct 11 2010 Ben Skeggs <bskeggs@redhat.com>
|
||||
- fix ttm bug that can cause nouveau to crash
|
||||
|
||||
* Fri Oct 08 2010 Kyle McMartin <kyle@redhat.com> 2.6.35.6-39
|
||||
- Push to F-14.
|
||||
|
||||
* Wed Oct 06 2010 Dave Jones <davej@redhat.com>
|
||||
- Another day, another rcu_dereference warning. (#640673)
|
||||
|
||||
* Mon Oct 04 2010 Kyle McMartin <kyle@redhat.com>
|
||||
- Build intel_idle into the kernel, so they get loaded by default. In
|
||||
later kernels, it is no longer modular, so it isn't an issue. Noticed
|
||||
by mjg59.
|
||||
|
||||
* Mon Oct 04 2010 Kyle McMartin <kyle@redhat.com>
|
||||
- Make printk.time=1 the default, use printk.time=0 to turn it off.
|
||||
Results in much more useful traces for us, which is a big win.
|
||||
|
||||
* Sun Oct 03 2010 Kyle McMartin <kyle@redhat.com> 2.6.35.6-38
|
||||
- Add more mac models supported by efifb. (#528232)
|
||||
- Sanity check base address in efifb on pci systems.
|
||||
|
||||
* Fri Oct 01 2010 Ben Skeggs <bskeggs@redhat.com> 2.6.35.6-37
|
||||
- nouveau: DP fixes, nv50+ corruption fix, display fixes
|
||||
- drm-nouveau-ibdma-race.patch: removed, in updates now
|
||||
|
||||
* Thu Sep 30 2010 Dave Jones <davej@redhat.com>
|
||||
- silence another rcu_reference warning
|
||||
|
||||
* Thu Sep 30 2010 Ben Skeggs <bskeggs@redhat.com> 2.6.35.6-36
|
||||
- nouveau: fix theoretical race condition which may be the cause of some
|
||||
random hangs people reported.
|
||||
|
||||
* Wed Sep 29 2010 Dave Jones <davej@redhat.com> 2.6.35.6-35
|
||||
- Add back an old hack to make an SDV e1000e variant work.
|
||||
|
||||
* Wed Sep 29 2010 Dave Jones <davej@redhat.com>
|
||||
- Enable IB700 watchdog (used by qemu/kvm). (#637152)
|
||||
|
||||
* Mon Sep 27 2010 Kyle McMartin <kyle@redhat.com> 2.6.35.6-34
|
||||
- Linux 2.6.35.6
|
||||
- bdi-fix-warnings-in-__mark_inode_dirty-for-dev-zero-and-friends.patch was
|
||||
dropped, should fix the inode_to_bdi WARN_ON triggering for a bunch of
|
||||
people.
|
||||
|
||||
* Sat Sep 25 2010 Chuck Ebbert <kyle@redhat.com> 2.6.35.6-33.rc1
|
||||
- Linux 2.6.35.6-rc1
|
||||
- Comment out merged patches:
|
||||
aio-check-for-multiplication-overflow-in-do_io_submit.patch
|
||||
linux-2.6.35.4-virtio_console-fix-poll.patch
|
||||
fix-unprotected-access-to-task-credentials-in-whatid.patch
|
||||
dell-wmi-add-support-for-eject-key-studio-1555.patch
|
||||
irda-correctly-clean-up-self-ias_obj-on-irda_bind-failure.patch
|
||||
keys-fix-bug-in-keyctl_session_to_parent-if-parent-has-no-session-keyring.patch
|
||||
keys-fix-rcu-no-lock-warning-in-keyctl_session_to_parent.patch
|
||||
sched-00-fix-user-time-incorrectly-accounted-as-system-time-on-32-bit.patch
|
||||
- Revert: "drm/nv50: initialize ramht_refs list for faked 0 channel"
|
||||
(our DRM update removes ramht_refs entirely.)
|
||||
- Add sched-35-increment-cache_nice_tries-only-on-periodic-lb.patch, another
|
||||
fix for excessive scheduler load balancing.
|
||||
- Add xen-fix-typo-in-xen-irq-fix.patch, fixes typo in 2.6.35.5 patch.
|
||||
|
||||
* Thu Sep 23 2010 Kyle McMartin <kyle@redhat.com> 2.6.35.5-32
|
||||
- Serialize mandocs/htmldocs build, since otherwise it will constantly
|
||||
fail on the koji builders.
|
||||
|
||||
* Thu Sep 23 2010 Kyle McMartin <kyle@redhat.com> 2.6.35.5-31
|
||||
- Slay another rcu_dereference_check warning pointed out by
|
||||
rmcgrath@.
|
||||
|
||||
* Thu Sep 23 2010 Kyle McMartin <kyle@redhat.com>
|
||||
- Enable -debug flavours and switch default image to release builds.
|
||||
- Bump NR_CPUS on i686 to 64.
|
||||
|
||||
* Thu Sep 23 2010 Ben Skeggs <bskeggs@redhat.com> 2.6.35.5-30
|
||||
- nouveau: fix IGP chipsets (rhbz#636326), and some DP boards
|
||||
- drm-nouveau-acpi-edid-fix.patch: drop, merged into updates
|
||||
|
||||
* Wed Sep 22 2010 Chuck Ebbert <cebbert@redhat.com>
|
||||
- Fix possible lockup with new scheduler idle balance code.
|
||||
- Dump stack on failed ATA commands in pata_it821x driver (#632753)
|
||||
|
||||
* Tue Sep 21 2010 Kyle McMartin <kyle@redhat.com>
|
||||
- Add new btusb ids for MacBookPro from wwoods@.
|
||||
|
||||
* Tue Sep 21 2010 Chuck Ebbert <cebbert@redhat.com> 2.6.35.5-29
|
||||
- Scheduler fixes for Bugzilla #635813 and #633037
|
||||
|
||||
* Mon Sep 20 2010 Chuck Ebbert <cebbert@redhat.com>
|
||||
- Linux 2.6.35.5
|
||||
- Drop merged patches:
|
||||
01-compat-make-compat_alloc_user_space-incorporate-the-access_ok-check.patch
|
||||
02-compat-test-rax-for-the-system-call-number-not-eax.patch
|
||||
03-compat-retruncate-rax-after-ia32-syscall-entry-tracing.patch
|
||||
direct-io-move-aio_complete-into-end_io.patch
|
||||
ext4-move-aio-completion-after-unwritten-extent-conversion.patch
|
||||
xfs-move-aio-completion-after-unwritten-extent-conversion.patch
|
||||
alsa-seq-oss-fix-double-free-at-error-path-of-snd_seq_oss_open.patch
|
||||
|
||||
* Thu Sep 16 2010 Dennis Gilmore <dennis@ausil.us>
|
||||
- build sparc headers on sparcv9
|
||||
- disable some modules to enable the kernel to build on sparc
|
||||
|
||||
* Thu Sep 16 2010 Hans de Goede <hdegoede@redhat.com>
|
||||
- Small fix to virtio_console poll fix from upstream review
|
||||
|
||||
* Wed Sep 15 2010 Dave Jones <davej@redhat.com>
|
||||
- Fix another RCU lockdep warning (cgroups).
|
||||
|
||||
* Wed Sep 15 2010 Hans de Goede <hdegoede@redhat.com>
|
||||
- virtio_console: Fix poll/select blocking even though there is data to read
|
||||
|
||||
* Tue Sep 14 2010 Chuck Ebbert <cebbert@redhat.com> 2.6.35.4-28
|
||||
- Fix 3 CVEs:
|
||||
/dev/sequencer open failure is not handled correctly (CVE-2010-3080)
|
||||
NULL deref and panic in irda (CVE-2010-2954)
|
||||
keyctl_session_to_parent NULL deref system crash (CVE-2010-2960)
|
||||
|
||||
* Tue Sep 14 2010 Chuck Ebbert <cebbert@redhat.com>
|
||||
- Fix DOS with large argument lists.
|
||||
|
||||
* Tue Sep 14 2010 Kyle McMartin <kyle@redhat.com>
|
||||
- x86_64: plug compat syscalls holes. (CVE-2010-3081, CVE-2010-3301)
|
||||
upgrading is highly recommended.
|
||||
- aio: check for multiplication overflow in do_io_submit. (CVE-2010-3067)
|
||||
|
||||
* Mon Sep 13 2010 Chuck Ebbert <cebbert@redhat.com>
|
||||
- Add support for perl and python scripting to perf (#632942)
|
||||
|
||||
* Mon Sep 13 2010 Ben Skeggs <bskeggs@redhat.com> 2.6.35.4-27
|
||||
- nouveau: fix oops in acpi edid support
|
||||
|
||||
* Fri Sep 10 2010 Jarod Wilson <jarod@redhat.com> 2.6.35.4-26
|
||||
- ir-core rebase to current upstream
|
||||
|
||||
* Fri Sep 10 2010 Bastien Nocera <bnocera@redhat.com> - 2.6.35.4-25
|
||||
- Update AppleIR patch to work, and support the enter key on
|
||||
newer remotes
|
||||
|
||||
* Fri Sep 10 2010 Chuck Ebbert <cebbert@redhat.com>
|
||||
- Disable asynchronous suspend by default.
|
||||
|
||||
* Fri Sep 10 2010 Ben Skeggs <bskeggs@redhat.com> - 2.6.35.4-23
|
||||
- nouveau: disable acceleration on nva3/nva5/nva8
|
||||
|
||||
* Wed Sep 08 2010 Kyle McMartin <kyle@redhat.com>
|
||||
- Enable GPIO_SYSFS. (#631958)
|
||||
|
||||
* Wed Sep 08 2010 Kyle McMartin <kyle@redhat.com>
|
||||
- Make pci=use_crs a config option.
|
||||
|
||||
* Wed Sep 08 2010 Ben Skeggs <bskeggs@redhat.com> 2.6.35.4-23
|
||||
- nouveau: handle certain GPU errors better, AGP + misc fixes
|
||||
|
||||
* Tue Sep 07 2010 Dave Jones <davej@redhat.com> 2.6.35.4-22
|
||||
- Disable hung task checker, it only ever causes false positives. (#630777)
|
||||
|
||||
* Tue Sep 07 2010 Jarod Wilson <jarod@redhat.com> 2.6.35.4-21
|
||||
- Enhance HID layer to fully support TiVo Slide remote and dongle
|
||||
|
||||
* Mon Sep 06 2010 Kyle McMartin <kyle@redhat.com>
|
||||
- Suck in patch from F-13 to add support for the eject key on the
|
||||
Dell Studio 1555. (#513530)
|
||||
- flexcop: fix registering braindead stupid names (#575873)
|
||||
|
||||
* Mon Sep 06 2010 Kyle McMartin <kyle@redhat.com>
|
||||
- Patch from paulmck to fix rcu_dereference_check warning
|
||||
(http://lkml.org/lkml/2010/8/16/258)
|
||||
|
||||
* Mon Sep 06 2010 Jarod Wilson <jarod@redhat.com> 2.6.35.4-20
|
||||
- Restore the rest of the appleir driver patch
|
||||
|
||||
* Mon Sep 06 2010 Ben Skeggs <bskeggs@redhat.com> 2.6.35.4-19
|
||||
- nouveau: misc fixes from upstream + NVAF support
|
||||
|
||||
* Fri Sep 03 2010 Kyle McMartin <kyle@redhat.com>
|
||||
- Restore appleir driver that got lost in the 2.6.35 rebase.
|
||||
|
||||
* Thu Sep 02 2010 Dave Jones <davej@redhat.com> 2.6.35.4-18
|
||||
- Scatter-gather on via-velocity is hopelessly broken.
|
||||
Just switch it off for now.
|
||||
|
||||
* Thu Sep 02 2010 Dave Jones <davej@redhat.com> 2.6.35.4-17
|
||||
- Simplify the VIA Velocity changes. The last round of
|
||||
fixes introduced some bugs.
|
||||
|
||||
* Wed Sep 01 2010 Dave Jones <davej@redhat.com> 2.6.35.4-16
|
||||
- Another VIA Velocity fix. This time in ifdown path.
|
||||
|
||||
* Wed Sep 01 2010 Dave Jones <davej@redhat.com> 2.6.35.4-15
|
||||
- Improved version of the VIA Velocity DMA fix.
|
||||
|
||||
* Tue Aug 31 2010 Kyle McMartin <kyle@redhat.com> 2.6.35.4-14
|
||||
- efifb-add-more-models.patch: Add patch from Luke Macken to
|
||||
support more Mac models (rhbz#528232)
|
||||
|
||||
* Tue Aug 31 2010 Dave Jones <davej@redhat.com> 2.6.35.4-13
|
||||
- Fix incorrect DMA size freeing error in via-velocity.
|
||||
|
||||
* Fri Aug 27 2010 Chuck Ebbert <cebbert@redhat.com> 2.6.35.4-12
|
||||
- Linux 2.6.35.4
|
||||
- kprobes-x86-fix-kprobes-to-skip-prefixes-correctly.patch (#610941)
|
||||
|
||||
* Wed Aug 25 2010 Chuck Ebbert <cebbert@redhat.com> 2.6.35.4-11.rc1
|
||||
- Linux 2.6.35.4-rc1
|
||||
- Fix up linux-2.6-i386-nx-emulation.patch for 2.6.35.4
|
||||
|
||||
* Sat Aug 21 2010 Chuck Ebbert <cebbert@redhat.com> 2.6.35.3-10
|
||||
- Linux 2.6.35.3
|
||||
- Drop merged patches:
|
||||
mm-fix-page-table-unmap-for-stack-guard-page-properly.patch
|
||||
mm-fix-up-some-user-visible-effects-of-the-stack-guard-page.patch
|
||||
|
||||
* Wed Aug 18 2010 Dave Jones <davej@redhat.com>
|
||||
- systemd is dependant upon autofs, so build it in instead of modular.
|
||||
|
||||
* Tue Aug 17 2010 Chuck Ebbert <cebbert@redhat.com> 2.6.35.2-9
|
||||
- Fix fallout from the stack guard page fixes.
|
||||
(mm-fix-page-table-unmap-for-stack-guard-page-properly.patch,
|
||||
mm-fix-up-some-user-visible-effects-of-the-stack-guard-page.patch)
|
||||
|
||||
* Tue Aug 17 2010 Kyle McMartin <kyle@redhat.com>
|
||||
- Move cgroup fs to /sys/fs/cgroup instead of /cgroup in accordance with
|
||||
upstream change post 2.6.35.
|
||||
|
||||
* Tue Aug 17 2010 Kyle McMartin <kyle@redhat.com>
|
||||
- Touch .scmversion in the kernel top level to prevent scripts/setlocalversion
|
||||
from recursing into our fedpkg git tree and trying to decide whether the
|
||||
kernel git is modified (obviously not, since it's a tarball.) Fixes make
|
||||
local.
|
||||
|
||||
* Mon Aug 16 2010 Jarod Wilson <jarod@redhat.com>
|
||||
- Add ir-core streamzap driver, nuke lirc_streamzap
|
||||
|
||||
* Sun Aug 15 2010 Chuck Ebbert <cebbert@redhat.com> 2.6.35.2-8
|
||||
- Linux 2.6.35.2
|
||||
|
||||
* Fri Aug 13 2010 Chuck Ebbert <cebbert@redhat.com> 2.6.35.2-7.rc1
|
||||
- Linux 2.6.35.2-rc1
|
||||
- Comment out patches merged in -stable:
|
||||
linux-2.6-tip.git-396e894d289d69bacf5acd983c97cd6e21a14c08.patch
|
||||
linux-2.6-ext4-fix-freeze-deadlock.patch
|
||||
- New config option:
|
||||
CONFIG_CRYPTO_MANAGER_TESTS=y
|
||||
|
||||
* Tue Aug 10 2010 Chuck Ebbert <cebbert@redhat.com> 2.6.35.1-6
|
||||
- Linux 2.6.35.1
|
||||
|
||||
* Tue Aug 10 2010 Ben Skeggs <bskeggs@redhat.com> 2.6.35.1-5.rc1
|
||||
- nouveau: bring in patches up to what will be in 2.6.36
|
||||
|
||||
* Sat Aug 07 2010 Chuck Ebbert <cebbert@redhat.com> 2.6.35.1-4.rc1
|
||||
- Linux 2.6.35.1-rc1
|
||||
|
||||
* Fri Aug 06 2010 Chuck Ebbert <cebbert@redhat.com> 2.6.35-3
|
||||
- Copy fix for bug #617699 ("ext4 and xfs wrong data returned on read
|
||||
after write if file size was changed with ftruncate") from F-13
|
||||
- Disable CONFIG_MULTICORE_RAID456
|
||||
|
||||
* Wed Aug 04 2010 Dave Jones <davej@redhat.com>
|
||||
- sched: Revert nohz_ratelimit() which causes a lot of
|
||||
extra wakeups burning CPU, and my legs.
|
||||
|
||||
* Sun Aug 01 2010 Dave Jones <davej@redhat.com>
|
||||
- Linux 2.6.35
|
||||
|
||||
|
|
|
@ -0,0 +1,98 @@
|
|||
From: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
|
||||
Date: Tue, 29 Jun 2010 05:53:50 +0000 (+0900)
|
||||
Subject: kprobes/x86: Fix kprobes to skip prefixes correctly
|
||||
X-Git-Tag: v2.6.36-rc1~41^2~53
|
||||
X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=567a9fd86735ccdc897768ed2dacdd5e83a13509
|
||||
|
||||
kprobes/x86: Fix kprobes to skip prefixes correctly
|
||||
|
||||
Fix resume_execution() and is_IF_modifier() to skip x86
|
||||
instruction prefixes correctly by using x86 instruction
|
||||
attribute.
|
||||
|
||||
Without this fix, resume_execution() can't handle instructions
|
||||
which have non-REX prefixes (REX prefixes are skipped). This
|
||||
will cause unexpected kernel panic by hitting bad address when a
|
||||
kprobe hits on two-byte ret (e.g. "repz ret" generated for
|
||||
Athlon/K8 optimization), because it just checks "repz" and can't
|
||||
recognize the "ret" instruction.
|
||||
|
||||
These prefixes can be found easily with x86 instruction
|
||||
attribute. This patch introduces skip_prefixes() and uses it in
|
||||
resume_execution() and is_IF_modifier() to skip prefixes.
|
||||
|
||||
Signed-off-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
|
||||
Cc: Ananth N Mavinakayanahalli <ananth@in.ibm.com>
|
||||
LKML-Reference: <4C298A6E.8070609@hitachi.com>
|
||||
Signed-off-by: Ingo Molnar <mingo@elte.hu>
|
||||
---
|
||||
|
||||
diff --git a/arch/x86/kernel/kprobes.c b/arch/x86/kernel/kprobes.c
|
||||
index 345a4b1..175f85c 100644
|
||||
--- a/arch/x86/kernel/kprobes.c
|
||||
+++ b/arch/x86/kernel/kprobes.c
|
||||
@@ -126,16 +126,22 @@ static void __kprobes synthesize_reljump(void *from, void *to)
|
||||
}
|
||||
|
||||
/*
|
||||
- * Check for the REX prefix which can only exist on X86_64
|
||||
- * X86_32 always returns 0
|
||||
+ * Skip the prefixes of the instruction.
|
||||
*/
|
||||
-static int __kprobes is_REX_prefix(kprobe_opcode_t *insn)
|
||||
+static kprobe_opcode_t *__kprobes skip_prefixes(kprobe_opcode_t *insn)
|
||||
{
|
||||
+ insn_attr_t attr;
|
||||
+
|
||||
+ attr = inat_get_opcode_attribute((insn_byte_t)*insn);
|
||||
+ while (inat_is_legacy_prefix(attr)) {
|
||||
+ insn++;
|
||||
+ attr = inat_get_opcode_attribute((insn_byte_t)*insn);
|
||||
+ }
|
||||
#ifdef CONFIG_X86_64
|
||||
- if ((*insn & 0xf0) == 0x40)
|
||||
- return 1;
|
||||
+ if (inat_is_rex_prefix(attr))
|
||||
+ insn++;
|
||||
#endif
|
||||
- return 0;
|
||||
+ return insn;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -272,6 +278,9 @@ static int __kprobes can_probe(unsigned long paddr)
|
||||
*/
|
||||
static int __kprobes is_IF_modifier(kprobe_opcode_t *insn)
|
||||
{
|
||||
+ /* Skip prefixes */
|
||||
+ insn = skip_prefixes(insn);
|
||||
+
|
||||
switch (*insn) {
|
||||
case 0xfa: /* cli */
|
||||
case 0xfb: /* sti */
|
||||
@@ -280,13 +289,6 @@ static int __kprobes is_IF_modifier(kprobe_opcode_t *insn)
|
||||
return 1;
|
||||
}
|
||||
|
||||
- /*
|
||||
- * on X86_64, 0x40-0x4f are REX prefixes so we need to look
|
||||
- * at the next byte instead.. but of course not recurse infinitely
|
||||
- */
|
||||
- if (is_REX_prefix(insn))
|
||||
- return is_IF_modifier(++insn);
|
||||
-
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -803,9 +805,8 @@ static void __kprobes resume_execution(struct kprobe *p,
|
||||
unsigned long orig_ip = (unsigned long)p->addr;
|
||||
kprobe_opcode_t *insn = p->ainsn.insn;
|
||||
|
||||
- /*skip the REX prefix*/
|
||||
- if (is_REX_prefix(insn))
|
||||
- insn++;
|
||||
+ /* Skip prefixes */
|
||||
+ insn = skip_prefixes(insn);
|
||||
|
||||
regs->flags &= ~X86_EFLAGS_TF;
|
||||
switch (*insn) {
|
|
@ -0,0 +1,164 @@
|
|||
From: Avi Kivity <avi@redhat.com>
|
||||
Date: Tue, 19 Oct 2010 14:46:55 +0000 (+0200)
|
||||
Subject: KVM: Fix fs/gs reload oops with invalid ldt
|
||||
X-Git-Tag: v2.6.36~4^2
|
||||
X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=9581d442b9058d3699b4be568b6e5eae38a41493
|
||||
|
||||
KVM: Fix fs/gs reload oops with invalid ldt
|
||||
|
||||
kvm reloads the host's fs and gs blindly, however the underlying segment
|
||||
descriptors may be invalid due to the user modifying the ldt after loading
|
||||
them.
|
||||
|
||||
Fix by using the safe accessors (loadsegment() and load_gs_index()) instead
|
||||
of home grown unsafe versions.
|
||||
|
||||
This is CVE-2010-3698.
|
||||
|
||||
KVM-Stable-Tag.
|
||||
Signed-off-by: Avi Kivity <avi@redhat.com>
|
||||
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
|
||||
---
|
||||
|
||||
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
|
||||
index 502e53f..c52e2eb 100644
|
||||
--- a/arch/x86/include/asm/kvm_host.h
|
||||
+++ b/arch/x86/include/asm/kvm_host.h
|
||||
@@ -652,20 +652,6 @@ static inline struct kvm_mmu_page *page_header(hpa_t shadow_page)
|
||||
return (struct kvm_mmu_page *)page_private(page);
|
||||
}
|
||||
|
||||
-static inline u16 kvm_read_fs(void)
|
||||
-{
|
||||
- u16 seg;
|
||||
- asm("mov %%fs, %0" : "=g"(seg));
|
||||
- return seg;
|
||||
-}
|
||||
-
|
||||
-static inline u16 kvm_read_gs(void)
|
||||
-{
|
||||
- u16 seg;
|
||||
- asm("mov %%gs, %0" : "=g"(seg));
|
||||
- return seg;
|
||||
-}
|
||||
-
|
||||
static inline u16 kvm_read_ldt(void)
|
||||
{
|
||||
u16 ldt;
|
||||
@@ -673,16 +659,6 @@ static inline u16 kvm_read_ldt(void)
|
||||
return ldt;
|
||||
}
|
||||
|
||||
-static inline void kvm_load_fs(u16 sel)
|
||||
-{
|
||||
- asm("mov %0, %%fs" : : "rm"(sel));
|
||||
-}
|
||||
-
|
||||
-static inline void kvm_load_gs(u16 sel)
|
||||
-{
|
||||
- asm("mov %0, %%gs" : : "rm"(sel));
|
||||
-}
|
||||
-
|
||||
static inline void kvm_load_ldt(u16 sel)
|
||||
{
|
||||
asm("lldt %0" : : "rm"(sel));
|
||||
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
|
||||
index 81ed28c..8a3f9f6 100644
|
||||
--- a/arch/x86/kvm/svm.c
|
||||
+++ b/arch/x86/kvm/svm.c
|
||||
@@ -3163,8 +3163,8 @@ static void svm_vcpu_run(struct kvm_vcpu *vcpu)
|
||||
sync_lapic_to_cr8(vcpu);
|
||||
|
||||
save_host_msrs(vcpu);
|
||||
- fs_selector = kvm_read_fs();
|
||||
- gs_selector = kvm_read_gs();
|
||||
+ savesegment(fs, fs_selector);
|
||||
+ savesegment(gs, gs_selector);
|
||||
ldt_selector = kvm_read_ldt();
|
||||
svm->vmcb->save.cr2 = vcpu->arch.cr2;
|
||||
/* required for live migration with NPT */
|
||||
@@ -3251,10 +3251,15 @@ static void svm_vcpu_run(struct kvm_vcpu *vcpu)
|
||||
vcpu->arch.regs[VCPU_REGS_RSP] = svm->vmcb->save.rsp;
|
||||
vcpu->arch.regs[VCPU_REGS_RIP] = svm->vmcb->save.rip;
|
||||
|
||||
- kvm_load_fs(fs_selector);
|
||||
- kvm_load_gs(gs_selector);
|
||||
- kvm_load_ldt(ldt_selector);
|
||||
load_host_msrs(vcpu);
|
||||
+ loadsegment(fs, fs_selector);
|
||||
+#ifdef CONFIG_X86_64
|
||||
+ load_gs_index(gs_selector);
|
||||
+ wrmsrl(MSR_KERNEL_GS_BASE, current->thread.gs);
|
||||
+#else
|
||||
+ loadsegment(gs, gs_selector);
|
||||
+#endif
|
||||
+ kvm_load_ldt(ldt_selector);
|
||||
|
||||
reload_tss(vcpu);
|
||||
|
||||
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
|
||||
index 49b25ee..7bddfab 100644
|
||||
--- a/arch/x86/kvm/vmx.c
|
||||
+++ b/arch/x86/kvm/vmx.c
|
||||
@@ -803,7 +803,7 @@ static void vmx_save_host_state(struct kvm_vcpu *vcpu)
|
||||
*/
|
||||
vmx->host_state.ldt_sel = kvm_read_ldt();
|
||||
vmx->host_state.gs_ldt_reload_needed = vmx->host_state.ldt_sel;
|
||||
- vmx->host_state.fs_sel = kvm_read_fs();
|
||||
+ savesegment(fs, vmx->host_state.fs_sel);
|
||||
if (!(vmx->host_state.fs_sel & 7)) {
|
||||
vmcs_write16(HOST_FS_SELECTOR, vmx->host_state.fs_sel);
|
||||
vmx->host_state.fs_reload_needed = 0;
|
||||
@@ -811,7 +811,7 @@ static void vmx_save_host_state(struct kvm_vcpu *vcpu)
|
||||
vmcs_write16(HOST_FS_SELECTOR, 0);
|
||||
vmx->host_state.fs_reload_needed = 1;
|
||||
}
|
||||
- vmx->host_state.gs_sel = kvm_read_gs();
|
||||
+ savesegment(gs, vmx->host_state.gs_sel);
|
||||
if (!(vmx->host_state.gs_sel & 7))
|
||||
vmcs_write16(HOST_GS_SELECTOR, vmx->host_state.gs_sel);
|
||||
else {
|
||||
@@ -841,27 +841,21 @@ static void vmx_save_host_state(struct kvm_vcpu *vcpu)
|
||||
|
||||
static void __vmx_load_host_state(struct vcpu_vmx *vmx)
|
||||
{
|
||||
- unsigned long flags;
|
||||
-
|
||||
if (!vmx->host_state.loaded)
|
||||
return;
|
||||
|
||||
++vmx->vcpu.stat.host_state_reload;
|
||||
vmx->host_state.loaded = 0;
|
||||
if (vmx->host_state.fs_reload_needed)
|
||||
- kvm_load_fs(vmx->host_state.fs_sel);
|
||||
+ loadsegment(fs, vmx->host_state.fs_sel);
|
||||
if (vmx->host_state.gs_ldt_reload_needed) {
|
||||
kvm_load_ldt(vmx->host_state.ldt_sel);
|
||||
- /*
|
||||
- * If we have to reload gs, we must take care to
|
||||
- * preserve our gs base.
|
||||
- */
|
||||
- local_irq_save(flags);
|
||||
- kvm_load_gs(vmx->host_state.gs_sel);
|
||||
#ifdef CONFIG_X86_64
|
||||
- wrmsrl(MSR_GS_BASE, vmcs_readl(HOST_GS_BASE));
|
||||
+ load_gs_index(vmx->host_state.gs_sel);
|
||||
+ wrmsrl(MSR_KERNEL_GS_BASE, current->thread.gs);
|
||||
+#else
|
||||
+ loadsegment(gs, vmx->host_state.gs_sel);
|
||||
#endif
|
||||
- local_irq_restore(flags);
|
||||
}
|
||||
reload_tss();
|
||||
#ifdef CONFIG_X86_64
|
||||
@@ -2589,8 +2583,8 @@ static int vmx_vcpu_setup(struct vcpu_vmx *vmx)
|
||||
vmcs_write16(HOST_CS_SELECTOR, __KERNEL_CS); /* 22.2.4 */
|
||||
vmcs_write16(HOST_DS_SELECTOR, __KERNEL_DS); /* 22.2.4 */
|
||||
vmcs_write16(HOST_ES_SELECTOR, __KERNEL_DS); /* 22.2.4 */
|
||||
- vmcs_write16(HOST_FS_SELECTOR, kvm_read_fs()); /* 22.2.4 */
|
||||
- vmcs_write16(HOST_GS_SELECTOR, kvm_read_gs()); /* 22.2.4 */
|
||||
+ vmcs_write16(HOST_FS_SELECTOR, 0); /* 22.2.4 */
|
||||
+ vmcs_write16(HOST_GS_SELECTOR, 0); /* 22.2.4 */
|
||||
vmcs_write16(HOST_SS_SELECTOR, __KERNEL_DS); /* 22.2.4 */
|
||||
#ifdef CONFIG_X86_64
|
||||
rdmsrl(MSR_FS_BASE, a);
|
|
@ -0,0 +1,30 @@
|
|||
Dump stack once on unsupported commands to see who is submitting them.
|
||||
(#632753)
|
||||
|
||||
--- linux-2.6.34.noarch.orig/drivers/ata/pata_it821x.c
|
||||
+++ linux-2.6.34.noarch/drivers/ata/pata_it821x.c
|
||||
@@ -399,6 +399,16 @@ static void it821x_passthru_dev_select(s
|
||||
ata_sff_dev_select(ap, device);
|
||||
}
|
||||
|
||||
+static void it821x_dump_stack_once(void)
|
||||
+{
|
||||
+ static int dumped = 0;
|
||||
+
|
||||
+ if (!dumped) {
|
||||
+ dump_stack();
|
||||
+ dumped = 1;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
/**
|
||||
* it821x_smart_qc_issue - wrap qc issue prot
|
||||
* @qc: command
|
||||
@@ -433,6 +443,7 @@ static unsigned int it821x_smart_qc_issu
|
||||
return ata_sff_qc_issue(qc);
|
||||
}
|
||||
printk(KERN_DEBUG "it821x: can't process command 0x%02X\n", qc->tf.command);
|
||||
+ it821x_dump_stack_once();
|
||||
return AC_ERR_DEV;
|
||||
}
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
Message-ID: <4C805293.1020305@cn.fujitsu.com>
|
||||
Date: Fri, 03 Sep 2010 09:42:43 +0800
|
||||
From: Li Zefan <lizf@cn.fujitsu.com>
|
||||
To: David Miller <davem@davemloft.net>
|
||||
CC: Herbert Xu <herbert@gondor.hengli.com.au>, Dave Jones <davej@redhat.com>,
|
||||
netdev <netdev@vger.kernel.org>, LKML <linux-kernel@vger.kernel.org>,
|
||||
Peter Zijlstra <peterz@infradead.org>, Paul Menage <menage@google.com>
|
||||
Subject: [PATCH v2] cls_cgroup: Fix rcu lockdep warning
|
||||
|
||||
Dave reported an rcu lockdep warning on 2.6.35.4 kernel
|
||||
|
||||
task->cgroups and task->cgroups->subsys[i] are protected by RCU.
|
||||
So we avoid accessing invalid pointers here. This might happen,
|
||||
for example, when you are deref-ing those pointers while someone
|
||||
move @task from one cgroup to another.
|
||||
|
||||
Reported-by: Dave Jones <davej@redhat.com>
|
||||
Signed-off-by: Li Zefan <lizf@cn.fujitsu.com>
|
||||
---
|
||||
include/net/cls_cgroup.h | 10 ++++++++--
|
||||
1 files changed, 8 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/include/net/cls_cgroup.h b/include/net/cls_cgroup.h
|
||||
index dd1fdb8..a4dc5b0 100644
|
||||
--- a/include/net/cls_cgroup.h
|
||||
+++ b/include/net/cls_cgroup.h
|
||||
@@ -27,11 +27,17 @@ struct cgroup_cls_state
|
||||
#ifdef CONFIG_NET_CLS_CGROUP
|
||||
static inline u32 task_cls_classid(struct task_struct *p)
|
||||
{
|
||||
+ int classid;
|
||||
+
|
||||
if (in_interrupt())
|
||||
return 0;
|
||||
|
||||
- return container_of(task_subsys_state(p, net_cls_subsys_id),
|
||||
- struct cgroup_cls_state, css)->classid;
|
||||
+ rcu_read_lock();
|
||||
+ classid = container_of(task_subsys_state(p, net_cls_subsys_id),
|
||||
+ struct cgroup_cls_state, css)->classid;
|
||||
+ rcu_read_unlock();
|
||||
+
|
||||
+ return classid;
|
||||
}
|
||||
#else
|
||||
extern int net_cls_subsys_id;
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
--- linux-2.6.34.noarch.orig/kernel/power/main.c
|
||||
+++ linux-2.6.34.noarch/kernel/power/main.c
|
||||
@@ -45,7 +45,7 @@ int pm_notifier_call_chain(unsigned long
|
||||
}
|
||||
|
||||
/* If set, devices may be suspended and resumed asynchronously. */
|
||||
-int pm_async_enabled = 1;
|
||||
+int pm_async_enabled;
|
||||
|
||||
static ssize_t pm_async_show(struct kobject *kobj, struct kobj_attribute *attr,
|
||||
char *buf)
|
|
@ -0,0 +1,29 @@
|
|||
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
|
||||
index cea0cd9..c326065 100644
|
||||
--- a/arch/x86/Kconfig
|
||||
+++ b/arch/x86/Kconfig
|
||||
@@ -2142,3 +2142,8 @@ source "crypto/Kconfig"
|
||||
source "arch/x86/kvm/Kconfig"
|
||||
|
||||
source "lib/Kconfig"
|
||||
+
|
||||
+config PCI_DEFAULT_USE_CRS
|
||||
+ def_bool y
|
||||
+ prompt "Use PCI Host Bridge Windows from ACPI by default?"
|
||||
+ depends on ACPI
|
||||
diff --git a/arch/x86/pci/acpi.c b/arch/x86/pci/acpi.c
|
||||
index 15466c0..3099406 100644
|
||||
--- a/arch/x86/pci/acpi.c
|
||||
+++ b/arch/x86/pci/acpi.c
|
||||
@@ -16,7 +16,11 @@ struct pci_root_info {
|
||||
int busnum;
|
||||
};
|
||||
|
||||
+#ifdef CONFIG_PCI_DEFAULT_USE_CRS
|
||||
static bool pci_use_crs = true;
|
||||
+#else
|
||||
+static bool pci_use_crs = false;
|
||||
+#endif
|
||||
|
||||
static int __init set_use_crs(const struct dmi_system_id *id)
|
||||
{
|
|
@ -0,0 +1,30 @@
|
|||
This only showed up in one SDV (Montevina).
|
||||
The PCIE slots don't seem to like network cards, so this is the only hope
|
||||
to get networking working. It's never going upstream, but it's low impact
|
||||
enough to carry just to keep those SDVs working.
|
||||
|
||||
--- linux-2.6.35.noarch/drivers/net/e1000e/ich8lan.c~ 2010-09-29 17:53:13.000000000 -0400
|
||||
+++ linux-2.6.35.noarch/drivers/net/e1000e/ich8lan.c 2010-09-29 17:54:00.000000000 -0400
|
||||
@@ -424,6 +424,12 @@ static s32 e1000_init_phy_params_ich8lan
|
||||
|
||||
/* Verify phy id */
|
||||
switch (phy->id) {
|
||||
+ case 0:
|
||||
+ if (hw->adapter->pdev->device == 0x10be)
|
||||
+ e_dbg("got 0 phy id, trying anyway");
|
||||
+ /* Fall through to IGP03E1000 case below */
|
||||
+ else
|
||||
+ return -E1000_ERR_PHY;
|
||||
case IGP03E1000_E_PHY_ID:
|
||||
phy->type = e1000_phy_igp_3;
|
||||
phy->autoneg_mask = AUTONEG_ADVERTISE_SPEED_DEFAULT;
|
||||
--- linux-2.6.35.noarch/drivers/net/e1000e/netdev.c~ 2010-09-29 17:54:07.000000000 -0400
|
||||
+++ linux-2.6.35.noarch/drivers/net/e1000e/netdev.c 2010-09-29 17:54:29.000000000 -0400
|
||||
@@ -5994,6 +5994,7 @@ static DEFINE_PCI_DEVICE_TABLE(e1000_pci
|
||||
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IGP_M), board_ich9lan },
|
||||
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IGP_M_AMT), board_ich9lan },
|
||||
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IGP_M_V), board_ich9lan },
|
||||
+ { PCI_VDEVICE(INTEL, 0x10be), board_ich9lan },
|
||||
|
||||
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH10_R_BM_LM), board_ich9lan },
|
||||
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH10_R_BM_LF), board_ich9lan },
|
|
@ -1,46 +0,0 @@
|
|||
[PATCH] ext4: fix freeze deadlock under IO
|
||||
|
||||
Commit 6b0310fbf087ad6 caused a regression resulting in deadlocks
|
||||
when freezing a filesystem which had active IO; the vfs_check_frozen
|
||||
level (SB_FREEZE_WRITE) did not let the freeze-related IO syncing
|
||||
through. Duh.
|
||||
|
||||
Changing the test to FREEZE_TRANS should let the normal freeze
|
||||
syncing get through the fs, but still block any transactions from
|
||||
starting once the fs is completely frozen.
|
||||
|
||||
I tested this by running fsstress in the background while periodically
|
||||
snapshotting the fs and running fsck on the result. I ran into
|
||||
occasional deadlocks, but different ones. I think this is a
|
||||
fine fix for the problem at hand, and the other deadlocky things
|
||||
will need more investigation.
|
||||
|
||||
Reported-by: Phillip Susi <psusi@cfl.rr.com>
|
||||
Signed-off-by: Eric Sandeen <sandeen@redhat.com>
|
||||
---
|
||||
|
||||
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
|
||||
index 4e8983a..a45ced9 100644
|
||||
--- a/fs/ext4/super.c
|
||||
+++ b/fs/ext4/super.c
|
||||
@@ -241,7 +241,7 @@ handle_t *ext4_journal_start_sb(struct super_block *sb, int nblocks)
|
||||
if (sb->s_flags & MS_RDONLY)
|
||||
return ERR_PTR(-EROFS);
|
||||
|
||||
- vfs_check_frozen(sb, SB_FREEZE_WRITE);
|
||||
+ vfs_check_frozen(sb, SB_FREEZE_TRANS);
|
||||
/* Special case here: if the journal has aborted behind our
|
||||
* backs (eg. EIO in the commit thread), then we still need to
|
||||
* take the FS itself readonly cleanly. */
|
||||
@@ -3491,7 +3491,7 @@ int ext4_force_commit(struct super_block *sb)
|
||||
|
||||
journal = EXT4_SB(sb)->s_journal;
|
||||
if (journal) {
|
||||
- vfs_check_frozen(sb, SB_FREEZE_WRITE);
|
||||
+ vfs_check_frozen(sb, SB_FREEZE_TRANS);
|
||||
ret = ext4_journal_force_commit(journal);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
@ -538,15 +538,16 @@
|
|||
static void unmap_region(struct mm_struct *mm,
|
||||
struct vm_area_struct *vma, struct vm_area_struct *prev,
|
||||
unsigned long start, unsigned long end);
|
||||
@@ -388,6 +401,8 @@
|
||||
__vma_link_list(struct mm_struct *mm, struct vm_area_struct *vma,
|
||||
struct vm_area_struct *prev, struct rb_node *rb_parent)
|
||||
@@ -388,6 +401,9 @@
|
||||
{
|
||||
struct vm_area_struct *next;
|
||||
|
||||
+ if (vma->vm_flags & VM_EXEC)
|
||||
+ arch_add_exec_range(mm, vma->vm_end);
|
||||
+
|
||||
vma->vm_prev = prev;
|
||||
if (prev) {
|
||||
vma->vm_next = prev->vm_next;
|
||||
prev->vm_next = vma;
|
||||
next = prev->vm_next;
|
||||
@@ -489,6 +504,8 @@
|
||||
rb_erase(&vma->vm_rb, &mm->mm_rb);
|
||||
if (mm->mmap_cache == vma)
|
||||
|
|
|
@ -0,0 +1,625 @@
|
|||
This patch rolls up the following commits pending merge in the v4l-dvb tree:
|
||||
|
||||
commit 7ce3b9f7bdb40837e15af89bb9d623c207ac9586
|
||||
Author: Jarod Wilson <jarod@redhat.com>
|
||||
Date: Sat Oct 9 14:17:03 2010 -0400
|
||||
|
||||
lirc_dev: fixup error messages w/missing newlines
|
||||
|
||||
Signed-off-by: Jarod Wilson <jarod@redhat.com>
|
||||
|
||||
commit d1af871dadaf58580490431a335ea122a9b00d92
|
||||
Author: Jarod Wilson <jarod@redhat.com>
|
||||
Date: Sat Oct 9 14:07:06 2010 -0400
|
||||
|
||||
lirc: wire up .compat_ioctl to main ioctl handler
|
||||
|
||||
As pointed out (and tested) by Joris van Rantwijk, we do actually need
|
||||
to wire up .compat_ioctl for 32-bit lirc userspace to work with 64-bit
|
||||
lirc kernelspace. Do it. And add a check to make sure we get a valid
|
||||
irctl in the ioctl handler.
|
||||
|
||||
Signed-off-by: Jarod Wilson <jarod@redhat.com>
|
||||
|
||||
commit 8dea589f4dc51b0363555a53fee128965a0548d4
|
||||
Author: Jarod Wilson <jarod@redhat.com>
|
||||
Date: Fri Oct 8 16:24:21 2010 -0400
|
||||
|
||||
IR/lirc: further ioctl portability fixups
|
||||
|
||||
From: Joris van Rantwijk <jorispubl@xs4all.nl>
|
||||
|
||||
----8<----
|
||||
I tested lirc_serial and found that it works fine.
|
||||
Except the LIRC ioctls do not work in my 64-bit-kernel/32-bit-user
|
||||
setup. I added compat_ioctl entries in the drivers to fix this.
|
||||
|
||||
While doing so, I noticed inconsistencies in the argument type of
|
||||
the LIRC ioctls. All ioctls are declared in lirc.h as having argument
|
||||
type __u32, however there are a few places where the driver calls
|
||||
get_user/put_user with an unsigned long argument.
|
||||
|
||||
The patch below changes lirc_dev and lirc_serial to use __u32 for all
|
||||
ioctl arguments, and adds compat_ioctl entries.
|
||||
It should probably also be done in the other low-level drivers,
|
||||
but I don't have hardware to test those.
|
||||
----8<----
|
||||
|
||||
I've dropped the .compat_ioctl addition from Joris' original patch,
|
||||
as I swear the non-compat definition should now work for both 32-bit
|
||||
and 64-bit userspace. Technically, I think we still need/want a
|
||||
Signed-off-by: from Joris here. Joris? (And sorry for the lengthy delay
|
||||
in getting a reply to you).
|
||||
|
||||
Signed-off-by: Jarod Wilson <jarod@redhat.com>
|
||||
|
||||
---
|
||||
drivers/media/IR/ir-lirc-codec.c | 13 +++++++----
|
||||
drivers/media/IR/lirc_dev.c | 36 ++++++++++++++++++++----------
|
||||
drivers/staging/lirc/lirc_igorplugusb.c | 2 +-
|
||||
drivers/staging/lirc/lirc_it87.c | 20 +++++++++-------
|
||||
drivers/staging/lirc/lirc_ite8709.c | 6 ++--
|
||||
drivers/staging/lirc/lirc_parallel.c | 35 ++++++++++++++++-------------
|
||||
drivers/staging/lirc/lirc_serial.c | 24 +++++++++++---------
|
||||
drivers/staging/lirc/lirc_sir.c | 24 +++++++++++---------
|
||||
drivers/staging/lirc/lirc_zilog.c | 3 ++
|
||||
include/media/lirc_dev.h | 6 ++--
|
||||
10 files changed, 98 insertions(+), 71 deletions(-)
|
||||
|
||||
diff --git a/drivers/media/IR/ir-lirc-codec.c b/drivers/media/IR/ir-lirc-codec.c
|
||||
index e63f757..20ac9a4 100644
|
||||
--- a/drivers/media/IR/ir-lirc-codec.c
|
||||
+++ b/drivers/media/IR/ir-lirc-codec.c
|
||||
@@ -102,7 +102,7 @@ static long ir_lirc_ioctl(struct file *filep, unsigned int cmd,
|
||||
struct ir_input_dev *ir_dev;
|
||||
int ret = 0;
|
||||
void *drv_data;
|
||||
- unsigned long val = 0;
|
||||
+ __u32 val = 0;
|
||||
|
||||
lirc = lirc_get_pdata(filep);
|
||||
if (!lirc)
|
||||
@@ -115,7 +115,7 @@ static long ir_lirc_ioctl(struct file *filep, unsigned int cmd,
|
||||
drv_data = ir_dev->props->priv;
|
||||
|
||||
if (_IOC_DIR(cmd) & _IOC_WRITE) {
|
||||
- ret = get_user(val, (unsigned long *)arg);
|
||||
+ ret = get_user(val, (__u32 *)arg);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
@@ -135,14 +135,14 @@ static long ir_lirc_ioctl(struct file *filep, unsigned int cmd,
|
||||
/* TX settings */
|
||||
case LIRC_SET_TRANSMITTER_MASK:
|
||||
if (ir_dev->props->s_tx_mask)
|
||||
- ret = ir_dev->props->s_tx_mask(drv_data, (u32)val);
|
||||
+ ret = ir_dev->props->s_tx_mask(drv_data, val);
|
||||
else
|
||||
return -EINVAL;
|
||||
break;
|
||||
|
||||
case LIRC_SET_SEND_CARRIER:
|
||||
if (ir_dev->props->s_tx_carrier)
|
||||
- ir_dev->props->s_tx_carrier(drv_data, (u32)val);
|
||||
+ ir_dev->props->s_tx_carrier(drv_data, val);
|
||||
else
|
||||
return -EINVAL;
|
||||
break;
|
||||
@@ -212,7 +212,7 @@ static long ir_lirc_ioctl(struct file *filep, unsigned int cmd,
|
||||
}
|
||||
|
||||
if (_IOC_DIR(cmd) & _IOC_READ)
|
||||
- ret = put_user(val, (unsigned long *)arg);
|
||||
+ ret = put_user(val, (__u32 *)arg);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -231,6 +231,9 @@ static struct file_operations lirc_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.write = ir_lirc_transmit_ir,
|
||||
.unlocked_ioctl = ir_lirc_ioctl,
|
||||
+#ifdef CONFIG_COMPAT
|
||||
+ .compat_ioctl = ir_lirc_ioctl,
|
||||
+#endif
|
||||
.read = lirc_dev_fop_read,
|
||||
.poll = lirc_dev_fop_poll,
|
||||
.open = lirc_dev_fop_open,
|
||||
diff --git a/drivers/media/IR/lirc_dev.c b/drivers/media/IR/lirc_dev.c
|
||||
index 899891b..930e4a7 100644
|
||||
--- a/drivers/media/IR/lirc_dev.c
|
||||
+++ b/drivers/media/IR/lirc_dev.c
|
||||
@@ -161,6 +161,9 @@ static struct file_operations fops = {
|
||||
.write = lirc_dev_fop_write,
|
||||
.poll = lirc_dev_fop_poll,
|
||||
.unlocked_ioctl = lirc_dev_fop_ioctl,
|
||||
+#ifdef CONFIG_COMPAT
|
||||
+ .compat_ioctl = lirc_dev_fop_ioctl,
|
||||
+#endif
|
||||
.open = lirc_dev_fop_open,
|
||||
.release = lirc_dev_fop_close,
|
||||
};
|
||||
@@ -359,19 +362,23 @@ int lirc_unregister_driver(int minor)
|
||||
struct irctl *ir;
|
||||
|
||||
if (minor < 0 || minor >= MAX_IRCTL_DEVICES) {
|
||||
- printk(KERN_ERR "lirc_dev: lirc_unregister_driver: "
|
||||
- "\"minor (%d)\" must be between 0 and %d!\n",
|
||||
- minor, MAX_IRCTL_DEVICES-1);
|
||||
+ printk(KERN_ERR "lirc_dev: %s: minor (%d) must be between "
|
||||
+ "0 and %d!\n", __func__, minor, MAX_IRCTL_DEVICES-1);
|
||||
return -EBADRQC;
|
||||
}
|
||||
|
||||
ir = irctls[minor];
|
||||
+ if (!ir) {
|
||||
+ printk(KERN_ERR "lirc_dev: %s: failed to get irctl struct "
|
||||
+ "for minor %d!\n", __func__, minor);
|
||||
+ return -ENOENT;
|
||||
+ }
|
||||
|
||||
mutex_lock(&lirc_dev_lock);
|
||||
|
||||
if (ir->d.minor != minor) {
|
||||
- printk(KERN_ERR "lirc_dev: lirc_unregister_driver: "
|
||||
- "minor (%d) device not registered!", minor);
|
||||
+ printk(KERN_ERR "lirc_dev: %s: minor (%d) device not "
|
||||
+ "registered!\n", __func__, minor);
|
||||
mutex_unlock(&lirc_dev_lock);
|
||||
return -ENOENT;
|
||||
}
|
||||
@@ -519,10 +526,15 @@ EXPORT_SYMBOL(lirc_dev_fop_poll);
|
||||
|
||||
long lirc_dev_fop_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
- unsigned long mode;
|
||||
+ __u32 mode;
|
||||
int result = 0;
|
||||
struct irctl *ir = file->private_data;
|
||||
|
||||
+ if (!ir) {
|
||||
+ printk(KERN_ERR "lirc_dev: %s: no irctl found!\n", __func__);
|
||||
+ return -ENODEV;
|
||||
+ }
|
||||
+
|
||||
dev_dbg(ir->d.dev, LOGHEAD "ioctl called (0x%x)\n",
|
||||
ir->d.name, ir->d.minor, cmd);
|
||||
|
||||
@@ -536,7 +548,7 @@ long lirc_dev_fop_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
|
||||
|
||||
switch (cmd) {
|
||||
case LIRC_GET_FEATURES:
|
||||
- result = put_user(ir->d.features, (unsigned long *)arg);
|
||||
+ result = put_user(ir->d.features, (__u32 *)arg);
|
||||
break;
|
||||
case LIRC_GET_REC_MODE:
|
||||
if (!(ir->d.features & LIRC_CAN_REC_MASK)) {
|
||||
@@ -546,7 +558,7 @@ long lirc_dev_fop_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
|
||||
|
||||
result = put_user(LIRC_REC2MODE
|
||||
(ir->d.features & LIRC_CAN_REC_MASK),
|
||||
- (unsigned long *)arg);
|
||||
+ (__u32 *)arg);
|
||||
break;
|
||||
case LIRC_SET_REC_MODE:
|
||||
if (!(ir->d.features & LIRC_CAN_REC_MASK)) {
|
||||
@@ -554,7 +566,7 @@ long lirc_dev_fop_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
|
||||
break;
|
||||
}
|
||||
|
||||
- result = get_user(mode, (unsigned long *)arg);
|
||||
+ result = get_user(mode, (__u32 *)arg);
|
||||
if (!result && !(LIRC_MODE2REC(mode) & ir->d.features))
|
||||
result = -EINVAL;
|
||||
/*
|
||||
@@ -563,7 +575,7 @@ long lirc_dev_fop_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
|
||||
*/
|
||||
break;
|
||||
case LIRC_GET_LENGTH:
|
||||
- result = put_user(ir->d.code_length, (unsigned long *)arg);
|
||||
+ result = put_user(ir->d.code_length, (__u32 *)arg);
|
||||
break;
|
||||
case LIRC_GET_MIN_TIMEOUT:
|
||||
if (!(ir->d.features & LIRC_CAN_SET_REC_TIMEOUT) ||
|
||||
@@ -572,7 +584,7 @@ long lirc_dev_fop_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
|
||||
break;
|
||||
}
|
||||
|
||||
- result = put_user(ir->d.min_timeout, (unsigned long *)arg);
|
||||
+ result = put_user(ir->d.min_timeout, (__u32 *)arg);
|
||||
break;
|
||||
case LIRC_GET_MAX_TIMEOUT:
|
||||
if (!(ir->d.features & LIRC_CAN_SET_REC_TIMEOUT) ||
|
||||
@@ -581,7 +593,7 @@ long lirc_dev_fop_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
|
||||
break;
|
||||
}
|
||||
|
||||
- result = put_user(ir->d.max_timeout, (unsigned long *)arg);
|
||||
+ result = put_user(ir->d.max_timeout, (__u32 *)arg);
|
||||
break;
|
||||
default:
|
||||
result = -EINVAL;
|
||||
diff --git a/drivers/staging/lirc/lirc_igorplugusb.c b/drivers/staging/lirc/lirc_igorplugusb.c
|
||||
index bce600e..e680d88 100644
|
||||
--- a/drivers/staging/lirc/lirc_igorplugusb.c
|
||||
+++ b/drivers/staging/lirc/lirc_igorplugusb.c
|
||||
@@ -390,7 +390,7 @@ static int usb_remote_probe(struct usb_interface *intf,
|
||||
devnum = dev->devnum;
|
||||
maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe));
|
||||
|
||||
- dprintk(DRIVER_NAME "[%d]: bytes_in_key=%lu maxp=%d\n",
|
||||
+ dprintk(DRIVER_NAME "[%d]: bytes_in_key=%zu maxp=%d\n",
|
||||
devnum, CODE_LENGTH, maxp);
|
||||
|
||||
|
||||
diff --git a/drivers/staging/lirc/lirc_it87.c b/drivers/staging/lirc/lirc_it87.c
|
||||
index ec11c0e..bd5006c 100644
|
||||
--- a/drivers/staging/lirc/lirc_it87.c
|
||||
+++ b/drivers/staging/lirc/lirc_it87.c
|
||||
@@ -239,8 +239,7 @@ static ssize_t lirc_write(struct file *file, const char *buf,
|
||||
static long lirc_ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
int retval = 0;
|
||||
- unsigned long value = 0;
|
||||
- unsigned int ivalue;
|
||||
+ __u32 value = 0;
|
||||
unsigned long hw_flags;
|
||||
|
||||
if (cmd == LIRC_GET_FEATURES)
|
||||
@@ -256,24 +255,24 @@ static long lirc_ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
|
||||
case LIRC_GET_FEATURES:
|
||||
case LIRC_GET_SEND_MODE:
|
||||
case LIRC_GET_REC_MODE:
|
||||
- retval = put_user(value, (unsigned long *) arg);
|
||||
+ retval = put_user(value, (__u32 *) arg);
|
||||
break;
|
||||
|
||||
case LIRC_SET_SEND_MODE:
|
||||
case LIRC_SET_REC_MODE:
|
||||
- retval = get_user(value, (unsigned long *) arg);
|
||||
+ retval = get_user(value, (__u32 *) arg);
|
||||
break;
|
||||
|
||||
case LIRC_SET_SEND_CARRIER:
|
||||
- retval = get_user(ivalue, (unsigned int *) arg);
|
||||
+ retval = get_user(value, (__u32 *) arg);
|
||||
if (retval)
|
||||
return retval;
|
||||
- ivalue /= 1000;
|
||||
- if (ivalue > IT87_CIR_FREQ_MAX ||
|
||||
- ivalue < IT87_CIR_FREQ_MIN)
|
||||
+ value /= 1000;
|
||||
+ if (value > IT87_CIR_FREQ_MAX ||
|
||||
+ value < IT87_CIR_FREQ_MIN)
|
||||
return -EINVAL;
|
||||
|
||||
- it87_freq = ivalue;
|
||||
+ it87_freq = value;
|
||||
|
||||
spin_lock_irqsave(&hardware_lock, hw_flags);
|
||||
outb(((inb(io + IT87_CIR_TCR2) & IT87_CIR_TCR2_TXMPW) |
|
||||
@@ -340,6 +339,9 @@ static const struct file_operations lirc_fops = {
|
||||
.write = lirc_write,
|
||||
.poll = lirc_poll,
|
||||
.unlocked_ioctl = lirc_ioctl,
|
||||
+#ifdef CONFIG_COMPAT
|
||||
+ .compat_ioctl = lirc_ioctl,
|
||||
+#endif
|
||||
.open = lirc_open,
|
||||
.release = lirc_close,
|
||||
};
|
||||
diff --git a/drivers/staging/lirc/lirc_ite8709.c b/drivers/staging/lirc/lirc_ite8709.c
|
||||
index 9352f45..cb20cfd 100644
|
||||
--- a/drivers/staging/lirc/lirc_ite8709.c
|
||||
+++ b/drivers/staging/lirc/lirc_ite8709.c
|
||||
@@ -102,8 +102,8 @@ struct ite8709_device {
|
||||
int io;
|
||||
int irq;
|
||||
spinlock_t hardware_lock;
|
||||
- unsigned long long acc_pulse;
|
||||
- unsigned long long acc_space;
|
||||
+ __u64 acc_pulse;
|
||||
+ __u64 acc_space;
|
||||
char lastbit;
|
||||
struct timeval last_tv;
|
||||
struct lirc_driver driver;
|
||||
@@ -220,7 +220,7 @@ static void ite8709_set_use_dec(void *data)
|
||||
}
|
||||
|
||||
static void ite8709_add_read_queue(struct ite8709_device *dev, int flag,
|
||||
- unsigned long long val)
|
||||
+ __u64 val)
|
||||
{
|
||||
int value;
|
||||
|
||||
diff --git a/drivers/staging/lirc/lirc_parallel.c b/drivers/staging/lirc/lirc_parallel.c
|
||||
index 6da4a8c..b8cce87 100644
|
||||
--- a/drivers/staging/lirc/lirc_parallel.c
|
||||
+++ b/drivers/staging/lirc/lirc_parallel.c
|
||||
@@ -301,9 +301,9 @@ static void irq_handler(void *blah)
|
||||
|
||||
if (signal != 0) {
|
||||
/* ajust value to usecs */
|
||||
- unsigned long long helper;
|
||||
+ __u64 helper;
|
||||
|
||||
- helper = ((unsigned long long) signal)*1000000;
|
||||
+ helper = ((__u64) signal)*1000000;
|
||||
do_div(helper, timer);
|
||||
signal = (long) helper;
|
||||
|
||||
@@ -404,9 +404,9 @@ static ssize_t lirc_write(struct file *filep, const char *buf, size_t n,
|
||||
|
||||
/* adjust values from usecs */
|
||||
for (i = 0; i < count; i++) {
|
||||
- unsigned long long helper;
|
||||
+ __u64 helper;
|
||||
|
||||
- helper = ((unsigned long long) wbuf[i])*timer;
|
||||
+ helper = ((__u64) wbuf[i])*timer;
|
||||
do_div(helper, 1000000);
|
||||
wbuf[i] = (int) helper;
|
||||
}
|
||||
@@ -464,48 +464,48 @@ static unsigned int lirc_poll(struct file *file, poll_table *wait)
|
||||
static long lirc_ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
int result;
|
||||
- unsigned long features = LIRC_CAN_SET_TRANSMITTER_MASK |
|
||||
- LIRC_CAN_SEND_PULSE | LIRC_CAN_REC_MODE2;
|
||||
- unsigned long mode;
|
||||
- unsigned int ivalue;
|
||||
+ __u32 features = LIRC_CAN_SET_TRANSMITTER_MASK |
|
||||
+ LIRC_CAN_SEND_PULSE | LIRC_CAN_REC_MODE2;
|
||||
+ __u32 mode;
|
||||
+ __u32 value;
|
||||
|
||||
switch (cmd) {
|
||||
case LIRC_GET_FEATURES:
|
||||
- result = put_user(features, (unsigned long *) arg);
|
||||
+ result = put_user(features, (__u32 *) arg);
|
||||
if (result)
|
||||
return result;
|
||||
break;
|
||||
case LIRC_GET_SEND_MODE:
|
||||
- result = put_user(LIRC_MODE_PULSE, (unsigned long *) arg);
|
||||
+ result = put_user(LIRC_MODE_PULSE, (__u32 *) arg);
|
||||
if (result)
|
||||
return result;
|
||||
break;
|
||||
case LIRC_GET_REC_MODE:
|
||||
- result = put_user(LIRC_MODE_MODE2, (unsigned long *) arg);
|
||||
+ result = put_user(LIRC_MODE_MODE2, (__u32 *) arg);
|
||||
if (result)
|
||||
return result;
|
||||
break;
|
||||
case LIRC_SET_SEND_MODE:
|
||||
- result = get_user(mode, (unsigned long *) arg);
|
||||
+ result = get_user(mode, (__u32 *) arg);
|
||||
if (result)
|
||||
return result;
|
||||
if (mode != LIRC_MODE_PULSE)
|
||||
return -EINVAL;
|
||||
break;
|
||||
case LIRC_SET_REC_MODE:
|
||||
- result = get_user(mode, (unsigned long *) arg);
|
||||
+ result = get_user(mode, (__u32 *) arg);
|
||||
if (result)
|
||||
return result;
|
||||
if (mode != LIRC_MODE_MODE2)
|
||||
return -ENOSYS;
|
||||
break;
|
||||
case LIRC_SET_TRANSMITTER_MASK:
|
||||
- result = get_user(ivalue, (unsigned int *) arg);
|
||||
+ result = get_user(value, (__u32 *) arg);
|
||||
if (result)
|
||||
return result;
|
||||
- if ((ivalue & LIRC_PARALLEL_TRANSMITTER_MASK) != ivalue)
|
||||
+ if ((value & LIRC_PARALLEL_TRANSMITTER_MASK) != value)
|
||||
return LIRC_PARALLEL_MAX_TRANSMITTERS;
|
||||
- tx_mask = ivalue;
|
||||
+ tx_mask = value;
|
||||
break;
|
||||
default:
|
||||
return -ENOIOCTLCMD;
|
||||
@@ -546,6 +546,9 @@ static const struct file_operations lirc_fops = {
|
||||
.write = lirc_write,
|
||||
.poll = lirc_poll,
|
||||
.unlocked_ioctl = lirc_ioctl,
|
||||
+#ifdef CONFIG_COMPAT
|
||||
+ .compat_ioctl = lirc_ioctl,
|
||||
+#endif
|
||||
.open = lirc_open,
|
||||
.release = lirc_close
|
||||
};
|
||||
diff --git a/drivers/staging/lirc/lirc_serial.c b/drivers/staging/lirc/lirc_serial.c
|
||||
index 9456f8e..05a9bf3 100644
|
||||
--- a/drivers/staging/lirc/lirc_serial.c
|
||||
+++ b/drivers/staging/lirc/lirc_serial.c
|
||||
@@ -372,7 +372,7 @@ static unsigned long conv_us_to_clocks;
|
||||
static int init_timing_params(unsigned int new_duty_cycle,
|
||||
unsigned int new_freq)
|
||||
{
|
||||
- unsigned long long loops_per_sec, work;
|
||||
+ __u64 loops_per_sec, work;
|
||||
|
||||
duty_cycle = new_duty_cycle;
|
||||
freq = new_freq;
|
||||
@@ -987,8 +987,7 @@ static ssize_t lirc_write(struct file *file, const char *buf,
|
||||
static long lirc_ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
int result;
|
||||
- unsigned long value;
|
||||
- unsigned int ivalue;
|
||||
+ __u32 value;
|
||||
|
||||
switch (cmd) {
|
||||
case LIRC_GET_SEND_MODE:
|
||||
@@ -997,7 +996,7 @@ static long lirc_ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
|
||||
|
||||
result = put_user(LIRC_SEND2MODE
|
||||
(hardware[type].features&LIRC_CAN_SEND_MASK),
|
||||
- (unsigned long *) arg);
|
||||
+ (__u32 *) arg);
|
||||
if (result)
|
||||
return result;
|
||||
break;
|
||||
@@ -1006,7 +1005,7 @@ static long lirc_ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
|
||||
if (!(hardware[type].features&LIRC_CAN_SEND_MASK))
|
||||
return -ENOIOCTLCMD;
|
||||
|
||||
- result = get_user(value, (unsigned long *) arg);
|
||||
+ result = get_user(value, (__u32 *) arg);
|
||||
if (result)
|
||||
return result;
|
||||
/* only LIRC_MODE_PULSE supported */
|
||||
@@ -1023,12 +1022,12 @@ static long lirc_ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
|
||||
if (!(hardware[type].features&LIRC_CAN_SET_SEND_DUTY_CYCLE))
|
||||
return -ENOIOCTLCMD;
|
||||
|
||||
- result = get_user(ivalue, (unsigned int *) arg);
|
||||
+ result = get_user(value, (__u32 *) arg);
|
||||
if (result)
|
||||
return result;
|
||||
- if (ivalue <= 0 || ivalue > 100)
|
||||
+ if (value <= 0 || value > 100)
|
||||
return -EINVAL;
|
||||
- return init_timing_params(ivalue, freq);
|
||||
+ return init_timing_params(value, freq);
|
||||
break;
|
||||
|
||||
case LIRC_SET_SEND_CARRIER:
|
||||
@@ -1036,12 +1035,12 @@ static long lirc_ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
|
||||
if (!(hardware[type].features&LIRC_CAN_SET_SEND_CARRIER))
|
||||
return -ENOIOCTLCMD;
|
||||
|
||||
- result = get_user(ivalue, (unsigned int *) arg);
|
||||
+ result = get_user(value, (__u32 *) arg);
|
||||
if (result)
|
||||
return result;
|
||||
- if (ivalue > 500000 || ivalue < 20000)
|
||||
+ if (value > 500000 || value < 20000)
|
||||
return -EINVAL;
|
||||
- return init_timing_params(duty_cycle, ivalue);
|
||||
+ return init_timing_params(duty_cycle, value);
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -1054,6 +1053,9 @@ static const struct file_operations lirc_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.write = lirc_write,
|
||||
.unlocked_ioctl = lirc_ioctl,
|
||||
+#ifdef CONFIG_COMPAT
|
||||
+ .compat_ioctl = lirc_ioctl,
|
||||
+#endif
|
||||
.read = lirc_dev_fop_read,
|
||||
.poll = lirc_dev_fop_poll,
|
||||
.open = lirc_dev_fop_open,
|
||||
diff --git a/drivers/staging/lirc/lirc_sir.c b/drivers/staging/lirc/lirc_sir.c
|
||||
index eb08fa7..c4cb3aa 100644
|
||||
--- a/drivers/staging/lirc/lirc_sir.c
|
||||
+++ b/drivers/staging/lirc/lirc_sir.c
|
||||
@@ -336,9 +336,8 @@ static ssize_t lirc_write(struct file *file, const char *buf, size_t n,
|
||||
static long lirc_ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
int retval = 0;
|
||||
- unsigned long value = 0;
|
||||
+ __u32 value = 0;
|
||||
#ifdef LIRC_ON_SA1100
|
||||
- unsigned int ivalue;
|
||||
|
||||
if (cmd == LIRC_GET_FEATURES)
|
||||
value = LIRC_CAN_SEND_PULSE |
|
||||
@@ -362,22 +361,22 @@ static long lirc_ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
|
||||
case LIRC_GET_FEATURES:
|
||||
case LIRC_GET_SEND_MODE:
|
||||
case LIRC_GET_REC_MODE:
|
||||
- retval = put_user(value, (unsigned long *) arg);
|
||||
+ retval = put_user(value, (__u32 *) arg);
|
||||
break;
|
||||
|
||||
case LIRC_SET_SEND_MODE:
|
||||
case LIRC_SET_REC_MODE:
|
||||
- retval = get_user(value, (unsigned long *) arg);
|
||||
+ retval = get_user(value, (__u32 *) arg);
|
||||
break;
|
||||
#ifdef LIRC_ON_SA1100
|
||||
case LIRC_SET_SEND_DUTY_CYCLE:
|
||||
- retval = get_user(ivalue, (unsigned int *) arg);
|
||||
+ retval = get_user(value, (__u32 *) arg);
|
||||
if (retval)
|
||||
return retval;
|
||||
- if (ivalue <= 0 || ivalue > 100)
|
||||
+ if (value <= 0 || value > 100)
|
||||
return -EINVAL;
|
||||
- /* (ivalue/100)*(1000000/freq) */
|
||||
- duty_cycle = ivalue;
|
||||
+ /* (value/100)*(1000000/freq) */
|
||||
+ duty_cycle = value;
|
||||
pulse_width = (unsigned long) duty_cycle*10000/freq;
|
||||
space_width = (unsigned long) 1000000L/freq-pulse_width;
|
||||
if (pulse_width >= LIRC_ON_SA1100_TRANSMITTER_LATENCY)
|
||||
@@ -386,12 +385,12 @@ static long lirc_ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
|
||||
space_width -= LIRC_ON_SA1100_TRANSMITTER_LATENCY;
|
||||
break;
|
||||
case LIRC_SET_SEND_CARRIER:
|
||||
- retval = get_user(ivalue, (unsigned int *) arg);
|
||||
+ retval = get_user(value, (__u32 *) arg);
|
||||
if (retval)
|
||||
return retval;
|
||||
- if (ivalue > 500000 || ivalue < 20000)
|
||||
+ if (value > 500000 || value < 20000)
|
||||
return -EINVAL;
|
||||
- freq = ivalue;
|
||||
+ freq = value;
|
||||
pulse_width = (unsigned long) duty_cycle*10000/freq;
|
||||
space_width = (unsigned long) 1000000L/freq-pulse_width;
|
||||
if (pulse_width >= LIRC_ON_SA1100_TRANSMITTER_LATENCY)
|
||||
@@ -457,6 +456,9 @@ static const struct file_operations lirc_fops = {
|
||||
.write = lirc_write,
|
||||
.poll = lirc_poll,
|
||||
.unlocked_ioctl = lirc_ioctl,
|
||||
+#ifdef CONFIG_COMPAT
|
||||
+ .compat_ioctl = lirc_ioctl,
|
||||
+#endif
|
||||
.open = lirc_dev_fop_open,
|
||||
.release = lirc_dev_fop_close,
|
||||
};
|
||||
diff --git a/drivers/staging/lirc/lirc_zilog.c b/drivers/staging/lirc/lirc_zilog.c
|
||||
index 100caab..d920644 100644
|
||||
--- a/drivers/staging/lirc/lirc_zilog.c
|
||||
+++ b/drivers/staging/lirc/lirc_zilog.c
|
||||
@@ -1139,6 +1139,9 @@ static const struct file_operations lirc_fops = {
|
||||
.write = write,
|
||||
.poll = poll,
|
||||
.unlocked_ioctl = ioctl,
|
||||
+#ifdef CONFIG_COMPAT
|
||||
+ .compat_ioctl = ioctl,
|
||||
+#endif
|
||||
.open = open,
|
||||
.release = close
|
||||
};
|
||||
diff --git a/include/media/lirc_dev.h b/include/media/lirc_dev.h
|
||||
index b1f6066..54780a5 100644
|
||||
--- a/include/media/lirc_dev.h
|
||||
+++ b/include/media/lirc_dev.h
|
||||
@@ -125,10 +125,10 @@ static inline unsigned int lirc_buffer_write(struct lirc_buffer *buf,
|
||||
struct lirc_driver {
|
||||
char name[40];
|
||||
int minor;
|
||||
- unsigned long code_length;
|
||||
+ __u32 code_length;
|
||||
unsigned int buffer_size; /* in chunks holding one code each */
|
||||
int sample_rate;
|
||||
- unsigned long features;
|
||||
+ __u32 features;
|
||||
|
||||
unsigned int chunk_size;
|
||||
|
||||
@@ -139,7 +139,7 @@ struct lirc_driver {
|
||||
struct lirc_buffer *rbuf;
|
||||
int (*set_use_inc) (void *data);
|
||||
void (*set_use_dec) (void *data);
|
||||
- struct file_operations *fops;
|
||||
+ const struct file_operations *fops;
|
||||
struct device *dev;
|
||||
struct module *owner;
|
||||
};
|
|
@ -0,0 +1,16 @@
|
|||
|
||||
diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h
|
||||
index 9fbc54a..435c502 100644
|
||||
--- a/include/linux/rcupdate.h
|
||||
+++ b/include/linux/rcupdate.h
|
||||
@@ -454,7 +454,7 @@ static inline notrace void rcu_read_unlock_sched_notrace(void)
|
||||
* Makes rcu_dereference_check() do the dirty work.
|
||||
*/
|
||||
#define rcu_dereference_bh(p) \
|
||||
- rcu_dereference_check(p, rcu_read_lock_bh_held())
|
||||
+ rcu_dereference_check(p, rcu_read_lock_bh_held() || irqs_disabled())
|
||||
|
||||
/**
|
||||
* rcu_dereference_sched - fetch RCU-protected pointer, checking for RCU-sched
|
||||
|
||||
|
|
@ -0,0 +1,215 @@
|
|||
From davej Thu Sep 16 11:55:58 2010
|
||||
Return-Path: linux-kernel-owner@vger.kernel.org
|
||||
X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on gelk
|
||||
X-Spam-Level:
|
||||
X-Spam-Status: No, score=-4.2 required=5.0 tests=BAYES_00,RCVD_IN_DNSWL_MED,
|
||||
T_RP_MATCHES_RCVD,UNPARSEABLE_RELAY autolearn=ham version=3.3.1
|
||||
Received: from mail.corp.redhat.com [10.5.5.52]
|
||||
by gelk with IMAP (fetchmail-6.3.17)
|
||||
for <davej@localhost> (single-drop); Thu, 16 Sep 2010 11:55:58 -0400 (EDT)
|
||||
Received: from zmta02.collab.prod.int.phx2.redhat.com (LHLO
|
||||
zmta02.collab.prod.int.phx2.redhat.com) (10.5.5.32) by
|
||||
mail04.corp.redhat.com with LMTP; Thu, 16 Sep 2010 11:51:27 -0400 (EDT)
|
||||
Received: from localhost (localhost.localdomain [127.0.0.1])
|
||||
by zmta02.collab.prod.int.phx2.redhat.com (Postfix) with ESMTP id 4889C9FC56;
|
||||
Thu, 16 Sep 2010 11:51:27 -0400 (EDT)
|
||||
Received: from zmta02.collab.prod.int.phx2.redhat.com ([127.0.0.1])
|
||||
by localhost (zmta02.collab.prod.int.phx2.redhat.com [127.0.0.1]) (amavisd-new, port 10024)
|
||||
with ESMTP id 94mQrmwfCpY4; Thu, 16 Sep 2010 11:51:27 -0400 (EDT)
|
||||
Received: from int-mx03.intmail.prod.int.phx2.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.16])
|
||||
by zmta02.collab.prod.int.phx2.redhat.com (Postfix) with ESMTP id 0DBDB9FC4B;
|
||||
Thu, 16 Sep 2010 11:51:27 -0400 (EDT)
|
||||
Received: from mx1.redhat.com (ext-mx05.extmail.prod.ext.phx2.redhat.com [10.5.110.9])
|
||||
by int-mx03.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id o8GFpQnO003857;
|
||||
Thu, 16 Sep 2010 11:51:26 -0400
|
||||
Received: from vger.kernel.org (vger.kernel.org [209.132.180.67])
|
||||
by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id o8GFFCFE031066;
|
||||
Thu, 16 Sep 2010 11:51:17 -0400
|
||||
Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand
|
||||
id S1755493Ab0IPPvH (ORCPT <rfc822;jasowang@redhat.com> + 41 others);
|
||||
Thu, 16 Sep 2010 11:51:07 -0400
|
||||
Received: from casper.infradead.org ([85.118.1.10]:41834 "EHLO
|
||||
casper.infradead.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org
|
||||
with ESMTP id S1754921Ab0IPPvC convert rfc822-to-8bit (ORCPT
|
||||
<rfc822;linux-kernel@vger.kernel.org>);
|
||||
Thu, 16 Sep 2010 11:51:02 -0400
|
||||
Received: from f199130.upc-f.chello.nl ([80.56.199.130] helo=laptop)
|
||||
by casper.infradead.org with esmtpsa (Exim 4.72 #1 (Red Hat Linux))
|
||||
id 1OwGjI-0003VE-Ux; Thu, 16 Sep 2010 15:50:33 +0000
|
||||
Received: by laptop (Postfix, from userid 1000)
|
||||
id 6DCDB100AEB1D; Thu, 16 Sep 2010 17:50:32 +0200 (CEST)
|
||||
Subject: Re: 2.6.35-stable/ppc64/p7: suspicious rcu_dereference_check()
|
||||
usage detected during 2.6.35-stable boot
|
||||
From: Peter Zijlstra <peterz@infradead.org>
|
||||
To: paulmck@linux.vnet.ibm.com
|
||||
Cc: Subrata Modak <subrata@linux.vnet.ibm.com>,
|
||||
linux-kernel <linux-kernel@vger.kernel.org>,
|
||||
Li Zefan <lizf@cn.fujitsu.com>, Linuxppc-dev <Linuxppc-dev@ozlabs.org>,
|
||||
sachinp <sachinp@linux.vnet.ibm.com>,
|
||||
DIVYA PRAKASH <dipraksh@linux.vnet.ibm.com>,
|
||||
"Valdis.Kletnieks" <Valdis.Kletnieks@vt.edu>
|
||||
In-Reply-To: <20100809161200.GC3026@linux.vnet.ibm.com>
|
||||
References: <1280739132.15317.9.camel@subratamodak.linux.ibm.com>
|
||||
<20100809161200.GC3026@linux.vnet.ibm.com>
|
||||
Content-Type: text/plain; charset="UTF-8"
|
||||
Content-Transfer-Encoding: 8BIT
|
||||
Date: Thu, 16 Sep 2010 17:50:31 +0200
|
||||
Message-ID: <1284652231.2275.569.camel@laptop>
|
||||
Mime-Version: 1.0
|
||||
Sender: linux-kernel-owner@vger.kernel.org
|
||||
Precedence: bulk
|
||||
List-ID: <linux-kernel.vger.kernel.org>
|
||||
X-Mailing-List: linux-kernel@vger.kernel.org
|
||||
X-RedHat-Spam-Score: -2.31 (RCVD_IN_DNSWL_MED,T_RP_MATCHES_RCVD)
|
||||
X-Scanned-By: MIMEDefang 2.67 on 10.5.11.16
|
||||
X-Scanned-By: MIMEDefang 2.67 on 10.5.110.9
|
||||
Status: RO
|
||||
Content-Length: 6752
|
||||
Lines: 145
|
||||
|
||||
On Mon, 2010-08-09 at 09:12 -0700, Paul E. McKenney wrote:
|
||||
|
||||
> > [ 0.051203] CPU0: AMD QEMU Virtual CPU version 0.12.4 stepping 03
|
||||
> > [ 0.052999] lockdep: fixing up alternatives.
|
||||
> > [ 0.054105]
|
||||
> > [ 0.054106] ===================================================
|
||||
> > [ 0.054999] [ INFO: suspicious rcu_dereference_check() usage. ]
|
||||
> > [ 0.054999] ---------------------------------------------------
|
||||
> > [ 0.054999] kernel/sched.c:616 invoked rcu_dereference_check() without protection!
|
||||
> > [ 0.054999]
|
||||
> > [ 0.054999] other info that might help us debug this:
|
||||
> > [ 0.054999]
|
||||
> > [ 0.054999]
|
||||
> > [ 0.054999] rcu_scheduler_active = 1, debug_locks = 1
|
||||
> > [ 0.054999] 3 locks held by swapper/1:
|
||||
> > [ 0.054999] #0: (cpu_add_remove_lock){+.+.+.}, at: [<ffffffff814be933>] cpu_up+0x42/0x6a
|
||||
> > [ 0.054999] #1: (cpu_hotplug.lock){+.+.+.}, at: [<ffffffff810400d8>] cpu_hotplug_begin+0x2a/0x51
|
||||
> > [ 0.054999] #2: (&rq->lock){-.-...}, at: [<ffffffff814be2f7>] init_idle+0x2f/0x113
|
||||
> > [ 0.054999]
|
||||
> > [ 0.054999] stack backtrace:
|
||||
> > [ 0.054999] Pid: 1, comm: swapper Not tainted 2.6.35 #1
|
||||
> > [ 0.054999] Call Trace:
|
||||
> > [ 0.054999] [<ffffffff81068054>] lockdep_rcu_dereference+0x9b/0xa3
|
||||
> > [ 0.054999] [<ffffffff810325c3>] task_group+0x7b/0x8a
|
||||
> > [ 0.054999] [<ffffffff810325e5>] set_task_rq+0x13/0x40
|
||||
> > [ 0.054999] [<ffffffff814be39a>] init_idle+0xd2/0x113
|
||||
> > [ 0.054999] [<ffffffff814be78a>] fork_idle+0xb8/0xc7
|
||||
> > [ 0.054999] [<ffffffff81068717>] ? mark_held_locks+0x4d/0x6b
|
||||
> > [ 0.054999] [<ffffffff814bcebd>] do_fork_idle+0x17/0x2b
|
||||
> > [ 0.054999] [<ffffffff814bc89b>] native_cpu_up+0x1c1/0x724
|
||||
> > [ 0.054999] [<ffffffff814bcea6>] ? do_fork_idle+0x0/0x2b
|
||||
> > [ 0.054999] [<ffffffff814be876>] _cpu_up+0xac/0x127
|
||||
> > [ 0.054999] [<ffffffff814be946>] cpu_up+0x55/0x6a
|
||||
> > [ 0.054999] [<ffffffff81ab562a>] kernel_init+0xe1/0x1ff
|
||||
> > [ 0.054999] [<ffffffff81003854>] kernel_thread_helper+0x4/0x10
|
||||
> > [ 0.054999] [<ffffffff814c353c>] ? restore_args+0x0/0x30
|
||||
> > [ 0.054999] [<ffffffff81ab5549>] ? kernel_init+0x0/0x1ff
|
||||
> > [ 0.054999] [<ffffffff81003850>] ? kernel_thread_helper+0x0/0x10
|
||||
> > [ 0.056074] Booting Node 0, Processors #1lockdep: fixing up alternatives.
|
||||
> > [ 0.130045] #2lockdep: fixing up alternatives.
|
||||
> > [ 0.203089] #3 Ok.
|
||||
> > [ 0.275286] Brought up 4 CPUs
|
||||
> > [ 0.276005] Total of 4 processors activated (16017.17 BogoMIPS).
|
||||
>
|
||||
> This does look like a new one, thank you for reporting it!
|
||||
>
|
||||
> Here is my analysis, which should at least provide some humor value to
|
||||
> those who understand the code better than I do. ;-)
|
||||
>
|
||||
> So the corresponding rcu_dereference_check() is in
|
||||
> task_subsys_state_check(), and is fetching the cpu_cgroup_subsys_id
|
||||
> element of the newly created task's task->cgroups->subsys[] array.
|
||||
> The "git grep" command finds only three uses of cpu_cgroup_subsys_id,
|
||||
> but no definition.
|
||||
>
|
||||
> Now, fork_idle() invokes copy_process(), which invokes cgroup_fork(),
|
||||
> which sets the child process's ->cgroups pointer to that of the parent,
|
||||
> also invoking get_css_set(), which increments the corresponding reference
|
||||
> count, doing both operations under task_lock() protection (->alloc_lock).
|
||||
> Because fork_idle() does not specify any of CLONE_NEWNS, CLONE_NEWUTS,
|
||||
> CLONE_NEWIPC, CLONE_NEWPID, or CLONE_NEWNET, copy_namespaces() should
|
||||
> not create a new namespace, and so there should be no ns_cgroup_clone().
|
||||
> We should thus retain the parent's ->cgroups pointer. And copy_process()
|
||||
> installs the new task in the various lists, so that the task is externally
|
||||
> accessible upon return.
|
||||
>
|
||||
> After a non-error return from copy_process(), fork_init() invokes
|
||||
> init_idle_pid(), which does not appear to affect the task's cgroup
|
||||
> state. Next fork_init() invokes init_idle(), which in turn invokes
|
||||
> __set_task_cpu(), which invokes set_task_rq(), which calls task_group()
|
||||
> several times, which calls task_subsys_state_check(), which calls the
|
||||
> rcu_dereference_check() that complained above.
|
||||
>
|
||||
> However, the result returns by rcu_dereference_check() is stored into
|
||||
> the task structure:
|
||||
>
|
||||
> p->se.cfs_rq = task_group(p)->cfs_rq[cpu];
|
||||
> p->se.parent = task_group(p)->se[cpu];
|
||||
>
|
||||
> This means that the corresponding structure must have been tied down with
|
||||
> a reference count or some such. If such a reference has been taken, then
|
||||
> this complaint is a false positive, and could be suppressed by putting
|
||||
> rcu_read_lock() and rcu_read_unlock() around the call to init_idle()
|
||||
> from fork_idle(). However, although, reference to the enclosing ->cgroups
|
||||
> struct css_set is held, it is not clear to me that this reference applies
|
||||
> to the structures pointed to by the ->subsys[] array, especially given
|
||||
> that the cgroup_subsys_state structures referenced by this array have
|
||||
> their own reference count, which does not appear to me to be acquired
|
||||
> by this code path.
|
||||
>
|
||||
> Or are the cgroup_subsys_state structures referenced by idle tasks
|
||||
> never freed or some such?
|
||||
|
||||
I would hope so!, the idle tasks should be part of the root cgroup,
|
||||
which is not removable.
|
||||
|
||||
The problem is that while we do in-fact hold rq->lock, the newly spawned
|
||||
idle thread's cpu is not yet set to the correct cpu so the lockdep check
|
||||
in task_group():
|
||||
|
||||
lockdep_is_held(&task_rq(p)->lock)
|
||||
|
||||
will fail.
|
||||
|
||||
But of a chicken and egg problem. Setting the cpu needs to have the cpu
|
||||
set ;-)
|
||||
|
||||
Ingo, why do we have rq->lock there at all? The CPU isn't up and running
|
||||
yet, nothing should be touching it.
|
||||
|
||||
Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
|
||||
---
|
||||
kernel/sched.c | 12 ++++++++++++
|
||||
1 files changed, 12 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/kernel/sched.c b/kernel/sched.c
|
||||
index bd8b487..6241049 100644
|
||||
--- a/kernel/sched.c
|
||||
+++ b/kernel/sched.c
|
||||
@@ -5332,7 +5332,19 @@ void __cpuinit init_idle(struct task_struct *idle, int cpu)
|
||||
idle->se.exec_start = sched_clock();
|
||||
|
||||
cpumask_copy(&idle->cpus_allowed, cpumask_of(cpu));
|
||||
+ /*
|
||||
+ * We're having a chicken and egg problem, even though we are
|
||||
+ * holding rq->lock, the cpu isn't yet set to this cpu so the
|
||||
+ * lockdep check in task_group() will fail.
|
||||
+ *
|
||||
+ * Similar case to sched_fork(). / Alternatively we could
|
||||
+ * use task_rq_lock() here and obtain the other rq->lock.
|
||||
+ *
|
||||
+ * Silence PROVE_RCU
|
||||
+ */
|
||||
+ rcu_read_lock();
|
||||
__set_task_cpu(idle, cpu);
|
||||
+ rcu_read_unlock();
|
||||
|
||||
rq->curr = rq->idle = idle;
|
||||
#if defined(CONFIG_SMP) && defined(__ARCH_WANT_UNLOCKED_CTXSW)
|
||||
|
||||
--
|
||||
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
|
||||
the body of a message to majordomo@vger.kernel.org
|
||||
More majordomo info at http://vger.kernel.org/majordomo-info.html
|
||||
Please read the FAQ at http://www.tux.org/lkml/
|
||||
|
|
@ -1 +1,33 @@
|
|||
nil
|
||||
From 615661f3948a066fd22a36fe8ea0c528b75ee373 Mon Sep 17 00:00:00 2001
|
||||
From: Marcin Slusarz <marcin.slusarz@gmail.com>
|
||||
Date: Sun, 22 Aug 2010 20:54:08 +0200
|
||||
Subject: drm/nv50: initialize ramht_refs list for faked 0 channel
|
||||
|
||||
From: Marcin Slusarz <marcin.slusarz@gmail.com>
|
||||
|
||||
commit 615661f3948a066fd22a36fe8ea0c528b75ee373 upstream.
|
||||
|
||||
We need it for PFIFO_INTR_CACHE_ERROR interrupt handling,
|
||||
because nouveau_fifo_swmthd looks for matching gpuobj in
|
||||
ramht_refs list.
|
||||
It fixes kernel panic in nouveau_gpuobj_ref_find.
|
||||
|
||||
Signed-off-by: Marcin Slusarz <marcin.slusarz@gmail.com>
|
||||
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
|
||||
|
||||
---
|
||||
drivers/gpu/drm/nouveau/nv50_instmem.c | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
--- a/drivers/gpu/drm/nouveau/nv50_instmem.c
|
||||
+++ b/drivers/gpu/drm/nouveau/nv50_instmem.c
|
||||
@@ -141,6 +141,8 @@ nv50_instmem_init(struct drm_device *dev
|
||||
chan->file_priv = (struct drm_file *)-2;
|
||||
dev_priv->fifos[0] = dev_priv->fifos[127] = chan;
|
||||
|
||||
+ INIT_LIST_HEAD(&chan->ramht_refs);
|
||||
+
|
||||
/* Channel's PRAMIN object + heap */
|
||||
ret = nouveau_gpuobj_new_fake(dev, 0, c_offset, c_size, 0,
|
||||
NULL, &chan->ramin);
|
||||
|
|
|
@ -0,0 +1,76 @@
|
|||
From: Jarod Wilson <jarod@redhat.com>
|
||||
Date: Sat, 23 Oct 2010 19:42:20 +0000 (-0300)
|
||||
Subject: [media] imon: fix my egregious brown paper bag w/rdev/idev split
|
||||
X-Git-Url: http://git.linuxtv.org/media_tree.git?a=commitdiff_plain;h=428cc7633dedbab05aab80b805d8585572dc6dbf
|
||||
|
||||
[media] imon: fix my egregious brown paper bag w/rdev/idev split
|
||||
|
||||
Somehow, I managed to screw things up when reworking the rdev/idev split
|
||||
patch from David, and started trying to get ir_input_dev from idev
|
||||
instead of rdev, thus resulting in button presses hanging the system.
|
||||
This fixes it.
|
||||
|
||||
Signed-off-by: Jarod Wilson <jarod@redhat.com>
|
||||
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
|
||||
---
|
||||
|
||||
diff --git a/drivers/media/IR/imon.c b/drivers/media/IR/imon.c
|
||||
index 0391c3b..bcb2826 100644
|
||||
--- a/drivers/media/IR/imon.c
|
||||
+++ b/drivers/media/IR/imon.c
|
||||
@@ -1477,7 +1477,7 @@ static void imon_incoming_packet(struct imon_context *ictx,
|
||||
bool norelease = false;
|
||||
int i;
|
||||
u64 scancode;
|
||||
- struct input_dev *idev = NULL;
|
||||
+ struct input_dev *rdev = NULL;
|
||||
struct ir_input_dev *irdev = NULL;
|
||||
int press_type = 0;
|
||||
int msec;
|
||||
@@ -1485,8 +1485,8 @@ static void imon_incoming_packet(struct imon_context *ictx,
|
||||
static struct timeval prev_time = { 0, 0 };
|
||||
u8 ktype;
|
||||
|
||||
- idev = ictx->idev;
|
||||
- irdev = input_get_drvdata(idev);
|
||||
+ rdev = ictx->rdev;
|
||||
+ irdev = input_get_drvdata(rdev);
|
||||
|
||||
/* filter out junk data on the older 0xffdc imon devices */
|
||||
if ((buf[0] == 0xff) && (buf[1] == 0xff) && (buf[2] == 0xff))
|
||||
@@ -1570,8 +1570,7 @@ static void imon_incoming_packet(struct imon_context *ictx,
|
||||
if (press_type == 0)
|
||||
ir_keyup(irdev);
|
||||
else {
|
||||
- ir_keydown(ictx->rdev, ictx->rc_scancode,
|
||||
- ictx->rc_toggle);
|
||||
+ ir_keydown(rdev, ictx->rc_scancode, ictx->rc_toggle);
|
||||
spin_lock_irqsave(&ictx->kc_lock, flags);
|
||||
ictx->last_keycode = ictx->kc;
|
||||
spin_unlock_irqrestore(&ictx->kc_lock, flags);
|
||||
@@ -1587,7 +1586,7 @@ static void imon_incoming_packet(struct imon_context *ictx,
|
||||
do_gettimeofday(&t);
|
||||
msec = tv2int(&t, &prev_time);
|
||||
prev_time = t;
|
||||
- if (msec < idev->rep[REP_DELAY]) {
|
||||
+ if (msec < ictx->idev->rep[REP_DELAY]) {
|
||||
spin_unlock_irqrestore(&ictx->kc_lock, flags);
|
||||
return;
|
||||
}
|
||||
@@ -1596,12 +1595,12 @@ static void imon_incoming_packet(struct imon_context *ictx,
|
||||
|
||||
spin_unlock_irqrestore(&ictx->kc_lock, flags);
|
||||
|
||||
- input_report_key(idev, kc, press_type);
|
||||
- input_sync(idev);
|
||||
+ input_report_key(ictx->idev, kc, press_type);
|
||||
+ input_sync(ictx->idev);
|
||||
|
||||
/* panel keys don't generate a release */
|
||||
- input_report_key(idev, kc, 0);
|
||||
- input_sync(idev);
|
||||
+ input_report_key(ictx->idev, kc, 0);
|
||||
+ input_sync(ictx->idev);
|
||||
|
||||
ictx->last_keycode = kc;
|
||||
|
|
@ -0,0 +1,944 @@
|
|||
diff -Naurp linux-2.6.35.x86_64.orig/drivers/media/IR/ir-core-priv.h linux-2.6.35.x86_64/drivers/media/IR/ir-core-priv.h
|
||||
--- linux-2.6.35.x86_64.orig/drivers/media/IR/ir-core-priv.h 2010-08-15 17:50:34.572382442 -0400
|
||||
+++ linux-2.6.35.x86_64/drivers/media/IR/ir-core-priv.h 2010-08-16 00:11:42.756124321 -0400
|
||||
@@ -73,6 +73,12 @@ struct ir_raw_event_ctrl {
|
||||
bool first;
|
||||
bool toggle;
|
||||
} jvc;
|
||||
+ struct rc5_sz_dec {
|
||||
+ int state;
|
||||
+ u32 bits;
|
||||
+ unsigned count;
|
||||
+ unsigned wanted_bits;
|
||||
+ } rc5_sz;
|
||||
struct lirc_codec {
|
||||
struct ir_input_dev *ir_dev;
|
||||
struct lirc_driver *drv;
|
||||
diff -Naurp linux-2.6.35.x86_64.orig/drivers/media/IR/ir-rc5-sz-decoder.c linux-2.6.35.x86_64/drivers/media/IR/ir-rc5-sz-decoder.c
|
||||
--- linux-2.6.35.x86_64.orig/drivers/media/IR/ir-rc5-sz-decoder.c 1969-12-31 19:00:00.000000000 -0500
|
||||
+++ linux-2.6.35.x86_64/drivers/media/IR/ir-rc5-sz-decoder.c 2010-08-16 00:07:19.962608685 -0400
|
||||
@@ -0,0 +1,153 @@
|
||||
+/* ir-rc5-sz-decoder.c - handle RC5 Streamzap IR Pulse/Space protocol
|
||||
+ *
|
||||
+ * Copyright (C) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
|
||||
+ * Copyright (C) 2010 by Jarod Wilson <jarod@redhat.com>
|
||||
+ *
|
||||
+ * This program is free software; you can redistribute it and/or modify
|
||||
+ * it under the terms of the GNU General Public License as published by
|
||||
+ * the Free Software Foundation version 2 of the License.
|
||||
+ *
|
||||
+ * 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.
|
||||
+ */
|
||||
+
|
||||
+/*
|
||||
+ * This code handles the 15 bit RC5-ish protocol used by the Streamzap
|
||||
+ * PC Remote.
|
||||
+ * It considers a carrier of 36 kHz, with a total of 15 bits, where
|
||||
+ * the first two bits are start bits, and a third one is a filing bit
|
||||
+ */
|
||||
+
|
||||
+#include "ir-core-priv.h"
|
||||
+
|
||||
+#define RC5_SZ_NBITS 15
|
||||
+#define RC5_UNIT 888888 /* ns */
|
||||
+#define RC5_BIT_START (1 * RC5_UNIT)
|
||||
+#define RC5_BIT_END (1 * RC5_UNIT)
|
||||
+
|
||||
+enum rc5_sz_state {
|
||||
+ STATE_INACTIVE,
|
||||
+ STATE_BIT_START,
|
||||
+ STATE_BIT_END,
|
||||
+ STATE_FINISHED,
|
||||
+};
|
||||
+
|
||||
+/**
|
||||
+ * ir_rc5_sz_decode() - Decode one RC-5 Streamzap pulse or space
|
||||
+ * @input_dev: the struct input_dev descriptor of the device
|
||||
+ * @ev: the struct ir_raw_event descriptor of the pulse/space
|
||||
+ *
|
||||
+ * This function returns -EINVAL if the pulse violates the state machine
|
||||
+ */
|
||||
+static int ir_rc5_sz_decode(struct input_dev *input_dev, struct ir_raw_event ev)
|
||||
+{
|
||||
+ struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
|
||||
+ struct rc5_sz_dec *data = &ir_dev->raw->rc5_sz;
|
||||
+ u8 toggle, command, system;
|
||||
+ u32 scancode;
|
||||
+
|
||||
+ if (!(ir_dev->raw->enabled_protocols & IR_TYPE_RC5_SZ))
|
||||
+ return 0;
|
||||
+
|
||||
+ if (IS_RESET(ev)) {
|
||||
+ data->state = STATE_INACTIVE;
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ if (!geq_margin(ev.duration, RC5_UNIT, RC5_UNIT / 2))
|
||||
+ goto out;
|
||||
+
|
||||
+again:
|
||||
+ IR_dprintk(2, "RC5-sz decode started at state %i (%uus %s)\n",
|
||||
+ data->state, TO_US(ev.duration), TO_STR(ev.pulse));
|
||||
+
|
||||
+ if (!geq_margin(ev.duration, RC5_UNIT, RC5_UNIT / 2))
|
||||
+ return 0;
|
||||
+
|
||||
+ switch (data->state) {
|
||||
+
|
||||
+ case STATE_INACTIVE:
|
||||
+ if (!ev.pulse)
|
||||
+ break;
|
||||
+
|
||||
+ data->state = STATE_BIT_START;
|
||||
+ data->count = 1;
|
||||
+ data->wanted_bits = RC5_SZ_NBITS;
|
||||
+ decrease_duration(&ev, RC5_BIT_START);
|
||||
+ goto again;
|
||||
+
|
||||
+ case STATE_BIT_START:
|
||||
+ if (!eq_margin(ev.duration, RC5_BIT_START, RC5_UNIT / 2))
|
||||
+ break;
|
||||
+
|
||||
+ data->bits <<= 1;
|
||||
+ if (!ev.pulse)
|
||||
+ data->bits |= 1;
|
||||
+ data->count++;
|
||||
+ data->state = STATE_BIT_END;
|
||||
+ return 0;
|
||||
+
|
||||
+ case STATE_BIT_END:
|
||||
+ if (!is_transition(&ev, &ir_dev->raw->prev_ev))
|
||||
+ break;
|
||||
+
|
||||
+ if (data->count == data->wanted_bits)
|
||||
+ data->state = STATE_FINISHED;
|
||||
+ else
|
||||
+ data->state = STATE_BIT_START;
|
||||
+
|
||||
+ decrease_duration(&ev, RC5_BIT_END);
|
||||
+ goto again;
|
||||
+
|
||||
+ case STATE_FINISHED:
|
||||
+ if (ev.pulse)
|
||||
+ break;
|
||||
+
|
||||
+ /* RC5-sz */
|
||||
+ command = (data->bits & 0x0003F) >> 0;
|
||||
+ system = (data->bits & 0x02FC0) >> 6;
|
||||
+ toggle = (data->bits & 0x01000) ? 1 : 0;
|
||||
+ scancode = system << 6 | command;
|
||||
+
|
||||
+ IR_dprintk(1, "RC5-sz scancode 0x%04x (toggle: %u)\n",
|
||||
+ scancode, toggle);
|
||||
+
|
||||
+ ir_keydown(input_dev, scancode, toggle);
|
||||
+ data->state = STATE_INACTIVE;
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+out:
|
||||
+ IR_dprintk(1, "RC5-sz decode failed at state %i (%uus %s)\n",
|
||||
+ data->state, TO_US(ev.duration), TO_STR(ev.pulse));
|
||||
+ data->state = STATE_INACTIVE;
|
||||
+ return -EINVAL;
|
||||
+}
|
||||
+
|
||||
+static struct ir_raw_handler rc5_sz_handler = {
|
||||
+ .protocols = IR_TYPE_RC5_SZ,
|
||||
+ .decode = ir_rc5_sz_decode,
|
||||
+};
|
||||
+
|
||||
+static int __init ir_rc5_sz_decode_init(void)
|
||||
+{
|
||||
+ ir_raw_handler_register(&rc5_sz_handler);
|
||||
+
|
||||
+ printk(KERN_INFO "IR RC5 (streamzap) protocol handler initialized\n");
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void __exit ir_rc5_sz_decode_exit(void)
|
||||
+{
|
||||
+ ir_raw_handler_unregister(&rc5_sz_handler);
|
||||
+}
|
||||
+
|
||||
+module_init(ir_rc5_sz_decode_init);
|
||||
+module_exit(ir_rc5_sz_decode_exit);
|
||||
+
|
||||
+MODULE_LICENSE("GPL");
|
||||
+MODULE_AUTHOR("Jarod Wilson <jarod@redhat.com>");
|
||||
+MODULE_AUTHOR("Red Hat Inc. (http://www.redhat.com)");
|
||||
+MODULE_DESCRIPTION("RC5 (streamzap) IR protocol decoder");
|
||||
diff -Naurp linux-2.6.35.x86_64.orig/drivers/media/IR/ir-sysfs.c linux-2.6.35.x86_64/drivers/media/IR/ir-sysfs.c
|
||||
--- linux-2.6.35.x86_64.orig/drivers/media/IR/ir-sysfs.c 2010-08-15 17:50:34.574380413 -0400
|
||||
+++ linux-2.6.35.x86_64/drivers/media/IR/ir-sysfs.c 2010-08-16 00:23:24.893168856 -0400
|
||||
@@ -93,6 +93,11 @@ static ssize_t show_protocols(struct dev
|
||||
else if (allowed & IR_TYPE_SONY)
|
||||
tmp += sprintf(tmp, "sony ");
|
||||
|
||||
+ if (allowed & enabled & IR_TYPE_RC5_SZ)
|
||||
+ tmp += sprintf(tmp, "[rc5sz] ");
|
||||
+ else if (allowed & IR_TYPE_RC5_SZ)
|
||||
+ tmp += sprintf(tmp, "rc5sz ");
|
||||
+
|
||||
if (allowed & enabled & IR_TYPE_LIRC)
|
||||
tmp += sprintf(tmp, "[lirc] ");
|
||||
else if (allowed & IR_TYPE_LIRC)
|
||||
@@ -165,6 +170,9 @@ static ssize_t store_protocols(struct de
|
||||
} else if (!strncasecmp(tmp, "sony", 4)) {
|
||||
tmp += 4;
|
||||
mask = IR_TYPE_SONY;
|
||||
+ } else if (!strncasecmp(tmp, "rc5sz", 5)) {
|
||||
+ tmp += 5;
|
||||
+ mask = IR_TYPE_RC5_SZ;
|
||||
} else if (!strncasecmp(tmp, "lirc", 4)) {
|
||||
tmp += 4;
|
||||
mask = IR_TYPE_LIRC;
|
||||
diff -Naurp linux-2.6.35.x86_64.orig/drivers/media/IR/Kconfig linux-2.6.35.x86_64/drivers/media/IR/Kconfig
|
||||
--- linux-2.6.35.x86_64.orig/drivers/media/IR/Kconfig 2010-08-15 17:50:34.571382513 -0400
|
||||
+++ linux-2.6.35.x86_64/drivers/media/IR/Kconfig 2010-08-16 00:10:09.292873588 -0400
|
||||
@@ -69,6 +69,16 @@ config IR_SONY_DECODER
|
||||
Enable this option if you have an infrared remote control which
|
||||
uses the Sony protocol, and you need software decoding support.
|
||||
|
||||
+config IR_RC5_SZ_DECODER
|
||||
+ tristate "Enable IR raw decoder for the RC-5 (streamzap) protocol"
|
||||
+ depends on IR_CORE
|
||||
+ select BITREVERSE
|
||||
+ default y
|
||||
+
|
||||
+ ---help---
|
||||
+ Enable this option if you have IR with RC-5 (streamzap) protocol,
|
||||
+ and if the IR is decoded in software.
|
||||
+
|
||||
config IR_LIRC_CODEC
|
||||
tristate "Enable IR to LIRC bridge"
|
||||
depends on IR_CORE
|
||||
@@ -102,3 +112,15 @@ config IR_MCEUSB
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called mceusb.
|
||||
+
|
||||
+config IR_STREAMZAP
|
||||
+ tristate "Streamzap PC Remote IR Receiver"
|
||||
+ depends on USB_ARCH_HAS_HCD
|
||||
+ depends on IR_CORE
|
||||
+ select USB
|
||||
+ ---help---
|
||||
+ Say Y here if you want to use a Streamzap PC Remote
|
||||
+ Infrared Receiver.
|
||||
+
|
||||
+ To compile this driver as a module, choose M here: the
|
||||
+ module will be called streamzap.
|
||||
diff -Naurp linux-2.6.35.x86_64.orig/drivers/media/IR/keymaps/Makefile linux-2.6.35.x86_64/drivers/media/IR/keymaps/Makefile
|
||||
--- linux-2.6.35.x86_64.orig/drivers/media/IR/keymaps/Makefile 2010-08-15 17:50:34.575383346 -0400
|
||||
+++ linux-2.6.35.x86_64/drivers/media/IR/keymaps/Makefile 2010-08-16 00:05:47.400370419 -0400
|
||||
@@ -60,6 +60,7 @@ obj-$(CONFIG_RC_MAP) += rc-adstech-dvb-t
|
||||
rc-rc5-tv.o \
|
||||
rc-rc6-mce.o \
|
||||
rc-real-audio-220-32-keys.o \
|
||||
+ rc-streamzap.o \
|
||||
rc-tbs-nec.o \
|
||||
rc-terratec-cinergy-xs.o \
|
||||
rc-tevii-nec.o \
|
||||
diff -Naurp linux-2.6.35.x86_64.orig/drivers/media/IR/keymaps/rc-streamzap.c linux-2.6.35.x86_64/drivers/media/IR/keymaps/rc-streamzap.c
|
||||
--- linux-2.6.35.x86_64.orig/drivers/media/IR/keymaps/rc-streamzap.c 1969-12-31 19:00:00.000000000 -0500
|
||||
+++ linux-2.6.35.x86_64/drivers/media/IR/keymaps/rc-streamzap.c 2010-08-16 00:05:47.402370467 -0400
|
||||
@@ -0,0 +1,82 @@
|
||||
+/* rc-streamzap.c - Keytable for Streamzap PC Remote, for use
|
||||
+ * with the Streamzap PC Remote IR Receiver.
|
||||
+ *
|
||||
+ * Copyright (c) 2010 by Jarod Wilson <jarod@redhat.com>
|
||||
+ *
|
||||
+ * This program is free software; you can redistribute it and/or modify
|
||||
+ * it under the terms of the GNU General Public License as published by
|
||||
+ * the Free Software Foundation; either version 2 of the License, or
|
||||
+ * (at your option) any later version.
|
||||
+ */
|
||||
+
|
||||
+#include <media/rc-map.h>
|
||||
+
|
||||
+static struct ir_scancode streamzap[] = {
|
||||
+/*
|
||||
+ * The Streamzap remote is almost, but not quite, RC-5, as it has an extra
|
||||
+ * bit in it, which throws the in-kernel RC-5 decoder for a loop. Currently,
|
||||
+ * an additional RC-5-sz decoder is being deployed to support it, but it
|
||||
+ * may be possible to merge it back with the standard RC-5 decoder.
|
||||
+ */
|
||||
+ { 0x28c0, KEY_NUMERIC_0 },
|
||||
+ { 0x28c1, KEY_NUMERIC_1 },
|
||||
+ { 0x28c2, KEY_NUMERIC_2 },
|
||||
+ { 0x28c3, KEY_NUMERIC_3 },
|
||||
+ { 0x28c4, KEY_NUMERIC_4 },
|
||||
+ { 0x28c5, KEY_NUMERIC_5 },
|
||||
+ { 0x28c6, KEY_NUMERIC_6 },
|
||||
+ { 0x28c7, KEY_NUMERIC_7 },
|
||||
+ { 0x28c8, KEY_NUMERIC_8 },
|
||||
+ { 0x28c9, KEY_NUMERIC_9 },
|
||||
+ { 0x28ca, KEY_POWER },
|
||||
+ { 0x28cb, KEY_MUTE },
|
||||
+ { 0x28cc, KEY_CHANNELUP },
|
||||
+ { 0x28cd, KEY_VOLUMEUP },
|
||||
+ { 0x28ce, KEY_CHANNELDOWN },
|
||||
+ { 0x28cf, KEY_VOLUMEDOWN },
|
||||
+ { 0x28d0, KEY_UP },
|
||||
+ { 0x28d1, KEY_LEFT },
|
||||
+ { 0x28d2, KEY_OK },
|
||||
+ { 0x28d3, KEY_RIGHT },
|
||||
+ { 0x28d4, KEY_DOWN },
|
||||
+ { 0x28d5, KEY_MENU },
|
||||
+ { 0x28d6, KEY_EXIT },
|
||||
+ { 0x28d7, KEY_PLAY },
|
||||
+ { 0x28d8, KEY_PAUSE },
|
||||
+ { 0x28d9, KEY_STOP },
|
||||
+ { 0x28da, KEY_BACK },
|
||||
+ { 0x28db, KEY_FORWARD },
|
||||
+ { 0x28dc, KEY_RECORD },
|
||||
+ { 0x28dd, KEY_REWIND },
|
||||
+ { 0x28de, KEY_FASTFORWARD },
|
||||
+ { 0x28e0, KEY_RED },
|
||||
+ { 0x28e1, KEY_GREEN },
|
||||
+ { 0x28e2, KEY_YELLOW },
|
||||
+ { 0x28e3, KEY_BLUE },
|
||||
+
|
||||
+};
|
||||
+
|
||||
+static struct rc_keymap streamzap_map = {
|
||||
+ .map = {
|
||||
+ .scan = streamzap,
|
||||
+ .size = ARRAY_SIZE(streamzap),
|
||||
+ .ir_type = IR_TYPE_RC5,
|
||||
+ .name = RC_MAP_STREAMZAP,
|
||||
+ }
|
||||
+};
|
||||
+
|
||||
+static int __init init_rc_map_streamzap(void)
|
||||
+{
|
||||
+ return ir_register_map(&streamzap_map);
|
||||
+}
|
||||
+
|
||||
+static void __exit exit_rc_map_streamzap(void)
|
||||
+{
|
||||
+ ir_unregister_map(&streamzap_map);
|
||||
+}
|
||||
+
|
||||
+module_init(init_rc_map_streamzap)
|
||||
+module_exit(exit_rc_map_streamzap)
|
||||
+
|
||||
+MODULE_LICENSE("GPL");
|
||||
+MODULE_AUTHOR("Jarod Wilson <jarod@redhat.com>");
|
||||
diff -Naurp linux-2.6.35.x86_64.orig/drivers/media/IR/Makefile linux-2.6.35.x86_64/drivers/media/IR/Makefile
|
||||
--- linux-2.6.35.x86_64.orig/drivers/media/IR/Makefile 2010-08-15 17:50:34.571382513 -0400
|
||||
+++ linux-2.6.35.x86_64/drivers/media/IR/Makefile 2010-08-16 00:10:29.478144601 -0400
|
||||
@@ -11,8 +11,10 @@ obj-$(CONFIG_IR_RC5_DECODER) += ir-rc5-d
|
||||
obj-$(CONFIG_IR_RC6_DECODER) += ir-rc6-decoder.o
|
||||
obj-$(CONFIG_IR_JVC_DECODER) += ir-jvc-decoder.o
|
||||
obj-$(CONFIG_IR_SONY_DECODER) += ir-sony-decoder.o
|
||||
+obj-$(CONFIG_IR_RC5_SZ_DECODER) += ir-rc5-sz-decoder.o
|
||||
obj-$(CONFIG_IR_LIRC_CODEC) += ir-lirc-codec.o
|
||||
|
||||
# stand-alone IR receivers/transmitters
|
||||
obj-$(CONFIG_IR_IMON) += imon.o
|
||||
obj-$(CONFIG_IR_MCEUSB) += mceusb.o
|
||||
+obj-$(CONFIG_IR_STREAMZAP) += streamzap.o
|
||||
diff -Naurp linux-2.6.35.x86_64.orig/drivers/media/IR/streamzap.c linux-2.6.35.x86_64/drivers/media/IR/streamzap.c
|
||||
--- linux-2.6.35.x86_64.orig/drivers/media/IR/streamzap.c 1969-12-31 19:00:00.000000000 -0500
|
||||
+++ linux-2.6.35.x86_64/drivers/media/IR/streamzap.c 2010-08-16 00:12:43.223932881 -0400
|
||||
@@ -0,0 +1,569 @@
|
||||
+/*
|
||||
+ * Streamzap Remote Control driver
|
||||
+ *
|
||||
+ * Copyright (c) 2005 Christoph Bartelmus <lirc@bartelmus.de>
|
||||
+ * Copyright (c) 2010 Jarod Wilson <jarod@wilsonet.com>
|
||||
+ *
|
||||
+ * This driver was based on the work of Greg Wickham and Adrian
|
||||
+ * Dewhurst. It was substantially rewritten to support correct signal
|
||||
+ * gaps and now maintains a delay buffer, which is used to present
|
||||
+ * consistent timing behaviour to user space applications. Without the
|
||||
+ * delay buffer an ugly hack would be required in lircd, which can
|
||||
+ * cause sluggish signal decoding in certain situations.
|
||||
+ *
|
||||
+ * Ported to in-kernel ir-core interface by Jarod Wilson
|
||||
+ *
|
||||
+ * This driver is based on the USB skeleton driver packaged with the
|
||||
+ * kernel; copyright (C) 2001-2003 Greg Kroah-Hartman (greg@kroah.com)
|
||||
+ *
|
||||
+ * This program is free software; you can redistribute it and/or modify
|
||||
+ * it under the terms of the GNU General Public License as published by
|
||||
+ * the Free Software Foundation; either version 2 of the License, or
|
||||
+ * (at your option) any later version.
|
||||
+ *
|
||||
+ * This program is distributed in the hope that it will be useful,
|
||||
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
+ * GNU General Public License for more details.
|
||||
+ *
|
||||
+ * You should have received a copy of the GNU General Public License
|
||||
+ * along with this program; if not, write to the Free Software
|
||||
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
+ */
|
||||
+
|
||||
+#include <linux/device.h>
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/slab.h>
|
||||
+#include <linux/usb.h>
|
||||
+#include <linux/input.h>
|
||||
+#include <media/ir-core.h>
|
||||
+
|
||||
+#define DRIVER_VERSION "1.61"
|
||||
+#define DRIVER_NAME "streamzap"
|
||||
+#define DRIVER_DESC "Streamzap Remote Control driver"
|
||||
+
|
||||
+#ifdef CONFIG_USB_DEBUG
|
||||
+static int debug = 1;
|
||||
+#else
|
||||
+static int debug;
|
||||
+#endif
|
||||
+
|
||||
+#define USB_STREAMZAP_VENDOR_ID 0x0e9c
|
||||
+#define USB_STREAMZAP_PRODUCT_ID 0x0000
|
||||
+
|
||||
+/* table of devices that work with this driver */
|
||||
+static struct usb_device_id streamzap_table[] = {
|
||||
+ /* Streamzap Remote Control */
|
||||
+ { USB_DEVICE(USB_STREAMZAP_VENDOR_ID, USB_STREAMZAP_PRODUCT_ID) },
|
||||
+ /* Terminating entry */
|
||||
+ { }
|
||||
+};
|
||||
+
|
||||
+MODULE_DEVICE_TABLE(usb, streamzap_table);
|
||||
+
|
||||
+#define STREAMZAP_PULSE_MASK 0xf0
|
||||
+#define STREAMZAP_SPACE_MASK 0x0f
|
||||
+#define STREAMZAP_TIMEOUT 0xff
|
||||
+#define STREAMZAP_RESOLUTION 256
|
||||
+
|
||||
+/* number of samples buffered */
|
||||
+#define SZ_BUF_LEN 128
|
||||
+
|
||||
+/* from ir-rc5-sz-decoder.c */
|
||||
+#ifdef CONFIG_IR_RC5_SZ_DECODER_MODULE
|
||||
+#define load_rc5_sz_decode() request_module("ir-rc5-sz-decoder")
|
||||
+#else
|
||||
+#define load_rc5_sz_decode() 0
|
||||
+#endif
|
||||
+
|
||||
+enum StreamzapDecoderState {
|
||||
+ PulseSpace,
|
||||
+ FullPulse,
|
||||
+ FullSpace,
|
||||
+ IgnorePulse
|
||||
+};
|
||||
+
|
||||
+/* structure to hold our device specific stuff */
|
||||
+struct streamzap_ir {
|
||||
+
|
||||
+ /* ir-core */
|
||||
+ struct ir_dev_props *props;
|
||||
+
|
||||
+ /* core device info */
|
||||
+ struct device *dev;
|
||||
+ struct input_dev *idev;
|
||||
+
|
||||
+ /* usb */
|
||||
+ struct usb_device *usbdev;
|
||||
+ struct usb_interface *interface;
|
||||
+ struct usb_endpoint_descriptor *endpoint;
|
||||
+ struct urb *urb_in;
|
||||
+
|
||||
+ /* buffer & dma */
|
||||
+ unsigned char *buf_in;
|
||||
+ dma_addr_t dma_in;
|
||||
+ unsigned int buf_in_len;
|
||||
+
|
||||
+ /* track what state we're in */
|
||||
+ enum StreamzapDecoderState decoder_state;
|
||||
+ /* tracks whether we are currently receiving some signal */
|
||||
+ bool idle;
|
||||
+ /* sum of signal lengths received since signal start */
|
||||
+ unsigned long sum;
|
||||
+ /* start time of signal; necessary for gap tracking */
|
||||
+ struct timeval signal_last;
|
||||
+ struct timeval signal_start;
|
||||
+ bool timeout_enabled;
|
||||
+
|
||||
+ char name[128];
|
||||
+ char phys[64];
|
||||
+};
|
||||
+
|
||||
+
|
||||
+/* local function prototypes */
|
||||
+static int streamzap_probe(struct usb_interface *interface,
|
||||
+ const struct usb_device_id *id);
|
||||
+static void streamzap_disconnect(struct usb_interface *interface);
|
||||
+static void streamzap_callback(struct urb *urb);
|
||||
+static int streamzap_suspend(struct usb_interface *intf, pm_message_t message);
|
||||
+static int streamzap_resume(struct usb_interface *intf);
|
||||
+
|
||||
+/* usb specific object needed to register this driver with the usb subsystem */
|
||||
+static struct usb_driver streamzap_driver = {
|
||||
+ .name = DRIVER_NAME,
|
||||
+ .probe = streamzap_probe,
|
||||
+ .disconnect = streamzap_disconnect,
|
||||
+ .suspend = streamzap_suspend,
|
||||
+ .resume = streamzap_resume,
|
||||
+ .id_table = streamzap_table,
|
||||
+};
|
||||
+
|
||||
+static void sz_push(struct streamzap_ir *sz, struct ir_raw_event rawir)
|
||||
+{
|
||||
+ ir_raw_event_store(sz->idev, &rawir);
|
||||
+}
|
||||
+
|
||||
+static void sz_push_full_pulse(struct streamzap_ir *sz,
|
||||
+ unsigned char value)
|
||||
+{
|
||||
+ struct ir_raw_event rawir;
|
||||
+
|
||||
+ if (sz->idle) {
|
||||
+ long deltv;
|
||||
+
|
||||
+ sz->signal_last = sz->signal_start;
|
||||
+ do_gettimeofday(&sz->signal_start);
|
||||
+
|
||||
+ deltv = sz->signal_start.tv_sec - sz->signal_last.tv_sec;
|
||||
+ rawir.pulse = false;
|
||||
+ if (deltv > 15) {
|
||||
+ /* really long time */
|
||||
+ rawir.duration = IR_MAX_DURATION;
|
||||
+ } else {
|
||||
+ rawir.duration = (int)(deltv * 1000000 +
|
||||
+ sz->signal_start.tv_usec -
|
||||
+ sz->signal_last.tv_usec);
|
||||
+ rawir.duration -= sz->sum;
|
||||
+ rawir.duration *= 1000;
|
||||
+ rawir.duration &= IR_MAX_DURATION;
|
||||
+ }
|
||||
+ dev_dbg(sz->dev, "ls %u\n", rawir.duration);
|
||||
+ sz_push(sz, rawir);
|
||||
+
|
||||
+ sz->idle = false;
|
||||
+ sz->sum = 0;
|
||||
+ }
|
||||
+
|
||||
+ rawir.pulse = true;
|
||||
+ rawir.duration = ((int) value) * STREAMZAP_RESOLUTION;
|
||||
+ rawir.duration += STREAMZAP_RESOLUTION / 2;
|
||||
+ sz->sum += rawir.duration;
|
||||
+ rawir.duration *= 1000;
|
||||
+ rawir.duration &= IR_MAX_DURATION;
|
||||
+ dev_dbg(sz->dev, "p %u\n", rawir.duration);
|
||||
+ sz_push(sz, rawir);
|
||||
+}
|
||||
+
|
||||
+static void sz_push_half_pulse(struct streamzap_ir *sz,
|
||||
+ unsigned char value)
|
||||
+{
|
||||
+ sz_push_full_pulse(sz, (value & STREAMZAP_PULSE_MASK) >> 4);
|
||||
+}
|
||||
+
|
||||
+static void sz_push_full_space(struct streamzap_ir *sz,
|
||||
+ unsigned char value)
|
||||
+{
|
||||
+ struct ir_raw_event rawir;
|
||||
+
|
||||
+ rawir.pulse = false;
|
||||
+ rawir.duration = ((int) value) * STREAMZAP_RESOLUTION;
|
||||
+ rawir.duration += STREAMZAP_RESOLUTION / 2;
|
||||
+ sz->sum += rawir.duration;
|
||||
+ rawir.duration *= 1000;
|
||||
+ dev_dbg(sz->dev, "s %u\n", rawir.duration);
|
||||
+ sz_push(sz, rawir);
|
||||
+}
|
||||
+
|
||||
+static void sz_push_half_space(struct streamzap_ir *sz,
|
||||
+ unsigned long value)
|
||||
+{
|
||||
+ sz_push_full_space(sz, value & STREAMZAP_SPACE_MASK);
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * streamzap_callback - usb IRQ handler callback
|
||||
+ *
|
||||
+ * This procedure is invoked on reception of data from
|
||||
+ * the usb remote.
|
||||
+ */
|
||||
+static void streamzap_callback(struct urb *urb)
|
||||
+{
|
||||
+ struct streamzap_ir *sz;
|
||||
+ unsigned int i;
|
||||
+ int len;
|
||||
+ static int timeout = (((STREAMZAP_TIMEOUT * STREAMZAP_RESOLUTION) &
|
||||
+ IR_MAX_DURATION) | 0x03000000);
|
||||
+
|
||||
+ if (!urb)
|
||||
+ return;
|
||||
+
|
||||
+ sz = urb->context;
|
||||
+ len = urb->actual_length;
|
||||
+
|
||||
+ switch (urb->status) {
|
||||
+ case -ECONNRESET:
|
||||
+ case -ENOENT:
|
||||
+ case -ESHUTDOWN:
|
||||
+ /*
|
||||
+ * this urb is terminated, clean up.
|
||||
+ * sz might already be invalid at this point
|
||||
+ */
|
||||
+ dev_err(sz->dev, "urb terminated, status: %d\n", urb->status);
|
||||
+ return;
|
||||
+ default:
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ dev_info(sz->dev, "%s: received urb, len %d\n", __func__, len);
|
||||
+ for (i = 0; i < len; i++) {
|
||||
+ dev_info(sz->dev, "sz idx %d: %x\n",
|
||||
+ i, (unsigned char)sz->buf_in[i]);
|
||||
+ switch (sz->decoder_state) {
|
||||
+ case PulseSpace:
|
||||
+ if ((sz->buf_in[i] & STREAMZAP_PULSE_MASK) ==
|
||||
+ STREAMZAP_PULSE_MASK) {
|
||||
+ sz->decoder_state = FullPulse;
|
||||
+ continue;
|
||||
+ } else if ((sz->buf_in[i] & STREAMZAP_SPACE_MASK)
|
||||
+ == STREAMZAP_SPACE_MASK) {
|
||||
+ sz_push_half_pulse(sz, sz->buf_in[i]);
|
||||
+ sz->decoder_state = FullSpace;
|
||||
+ continue;
|
||||
+ } else {
|
||||
+ sz_push_half_pulse(sz, sz->buf_in[i]);
|
||||
+ sz_push_half_space(sz, sz->buf_in[i]);
|
||||
+ }
|
||||
+ break;
|
||||
+ case FullPulse:
|
||||
+ sz_push_full_pulse(sz, sz->buf_in[i]);
|
||||
+ sz->decoder_state = IgnorePulse;
|
||||
+ break;
|
||||
+ case FullSpace:
|
||||
+ if (sz->buf_in[i] == STREAMZAP_TIMEOUT) {
|
||||
+ struct ir_raw_event rawir;
|
||||
+
|
||||
+ rawir.pulse = false;
|
||||
+ rawir.duration = timeout * 1000;
|
||||
+ sz->idle = true;
|
||||
+ if (sz->timeout_enabled)
|
||||
+ sz_push(sz, rawir);
|
||||
+ ir_raw_event_handle(sz->idev);
|
||||
+ } else {
|
||||
+ sz_push_full_space(sz, sz->buf_in[i]);
|
||||
+ }
|
||||
+ sz->decoder_state = PulseSpace;
|
||||
+ break;
|
||||
+ case IgnorePulse:
|
||||
+ if ((sz->buf_in[i] & STREAMZAP_SPACE_MASK) ==
|
||||
+ STREAMZAP_SPACE_MASK) {
|
||||
+ sz->decoder_state = FullSpace;
|
||||
+ continue;
|
||||
+ }
|
||||
+ sz_push_half_space(sz, sz->buf_in[i]);
|
||||
+ sz->decoder_state = PulseSpace;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ usb_submit_urb(urb, GFP_ATOMIC);
|
||||
+
|
||||
+ return;
|
||||
+}
|
||||
+
|
||||
+static struct input_dev *streamzap_init_input_dev(struct streamzap_ir *sz)
|
||||
+{
|
||||
+ struct input_dev *idev;
|
||||
+ struct ir_dev_props *props;
|
||||
+ struct device *dev = sz->dev;
|
||||
+ int ret;
|
||||
+
|
||||
+ idev = input_allocate_device();
|
||||
+ if (!idev) {
|
||||
+ dev_err(dev, "remote input dev allocation failed\n");
|
||||
+ goto idev_alloc_failed;
|
||||
+ }
|
||||
+
|
||||
+ props = kzalloc(sizeof(struct ir_dev_props), GFP_KERNEL);
|
||||
+ if (!props) {
|
||||
+ dev_err(dev, "remote ir dev props allocation failed\n");
|
||||
+ goto props_alloc_failed;
|
||||
+ }
|
||||
+
|
||||
+ snprintf(sz->name, sizeof(sz->name), "Streamzap PC Remote Infrared "
|
||||
+ "Receiver (%04x:%04x)",
|
||||
+ le16_to_cpu(sz->usbdev->descriptor.idVendor),
|
||||
+ le16_to_cpu(sz->usbdev->descriptor.idProduct));
|
||||
+
|
||||
+ idev->name = sz->name;
|
||||
+ usb_make_path(sz->usbdev, sz->phys, sizeof(sz->phys));
|
||||
+ strlcat(sz->phys, "/input0", sizeof(sz->phys));
|
||||
+ idev->phys = sz->phys;
|
||||
+
|
||||
+ props->priv = sz;
|
||||
+ props->driver_type = RC_DRIVER_IR_RAW;
|
||||
+ props->allowed_protos = IR_TYPE_ALL;
|
||||
+
|
||||
+ sz->props = props;
|
||||
+
|
||||
+ ret = ir_input_register(idev, RC_MAP_STREAMZAP, props, DRIVER_NAME);
|
||||
+ if (ret < 0) {
|
||||
+ dev_err(dev, "remote input device register failed\n");
|
||||
+ goto irdev_failed;
|
||||
+ }
|
||||
+
|
||||
+ return idev;
|
||||
+
|
||||
+irdev_failed:
|
||||
+ kfree(props);
|
||||
+props_alloc_failed:
|
||||
+ input_free_device(idev);
|
||||
+idev_alloc_failed:
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * streamzap_probe
|
||||
+ *
|
||||
+ * Called by usb-core to associated with a candidate device
|
||||
+ * On any failure the return value is the ERROR
|
||||
+ * On success return 0
|
||||
+ */
|
||||
+static int __devinit streamzap_probe(struct usb_interface *intf,
|
||||
+ const struct usb_device_id *id)
|
||||
+{
|
||||
+ struct usb_device *usbdev = interface_to_usbdev(intf);
|
||||
+ struct usb_host_interface *iface_host;
|
||||
+ struct streamzap_ir *sz = NULL;
|
||||
+ char buf[63], name[128] = "";
|
||||
+ int retval = -ENOMEM;
|
||||
+ int pipe, maxp;
|
||||
+
|
||||
+ /* Allocate space for device driver specific data */
|
||||
+ sz = kzalloc(sizeof(struct streamzap_ir), GFP_KERNEL);
|
||||
+ if (!sz)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ sz->usbdev = usbdev;
|
||||
+ sz->interface = intf;
|
||||
+
|
||||
+ /* Check to ensure endpoint information matches requirements */
|
||||
+ iface_host = intf->cur_altsetting;
|
||||
+
|
||||
+ if (iface_host->desc.bNumEndpoints != 1) {
|
||||
+ dev_err(&intf->dev, "%s: Unexpected desc.bNumEndpoints (%d)\n",
|
||||
+ __func__, iface_host->desc.bNumEndpoints);
|
||||
+ retval = -ENODEV;
|
||||
+ goto free_sz;
|
||||
+ }
|
||||
+
|
||||
+ sz->endpoint = &(iface_host->endpoint[0].desc);
|
||||
+ if ((sz->endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK)
|
||||
+ != USB_DIR_IN) {
|
||||
+ dev_err(&intf->dev, "%s: endpoint doesn't match input device "
|
||||
+ "02%02x\n", __func__, sz->endpoint->bEndpointAddress);
|
||||
+ retval = -ENODEV;
|
||||
+ goto free_sz;
|
||||
+ }
|
||||
+
|
||||
+ if ((sz->endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
|
||||
+ != USB_ENDPOINT_XFER_INT) {
|
||||
+ dev_err(&intf->dev, "%s: endpoint attributes don't match xfer "
|
||||
+ "02%02x\n", __func__, sz->endpoint->bmAttributes);
|
||||
+ retval = -ENODEV;
|
||||
+ goto free_sz;
|
||||
+ }
|
||||
+
|
||||
+ pipe = usb_rcvintpipe(usbdev, sz->endpoint->bEndpointAddress);
|
||||
+ maxp = usb_maxpacket(usbdev, pipe, usb_pipeout(pipe));
|
||||
+
|
||||
+ if (maxp == 0) {
|
||||
+ dev_err(&intf->dev, "%s: endpoint Max Packet Size is 0!?!\n",
|
||||
+ __func__);
|
||||
+ retval = -ENODEV;
|
||||
+ goto free_sz;
|
||||
+ }
|
||||
+
|
||||
+ /* Allocate the USB buffer and IRQ URB */
|
||||
+ sz->buf_in = usb_alloc_coherent(usbdev, maxp, GFP_ATOMIC, &sz->dma_in);
|
||||
+ if (!sz->buf_in)
|
||||
+ goto free_sz;
|
||||
+
|
||||
+ sz->urb_in = usb_alloc_urb(0, GFP_KERNEL);
|
||||
+ if (!sz->urb_in)
|
||||
+ goto free_buf_in;
|
||||
+
|
||||
+ sz->dev = &intf->dev;
|
||||
+ sz->buf_in_len = maxp;
|
||||
+
|
||||
+ if (usbdev->descriptor.iManufacturer
|
||||
+ && usb_string(usbdev, usbdev->descriptor.iManufacturer,
|
||||
+ buf, sizeof(buf)) > 0)
|
||||
+ strlcpy(name, buf, sizeof(name));
|
||||
+
|
||||
+ if (usbdev->descriptor.iProduct
|
||||
+ && usb_string(usbdev, usbdev->descriptor.iProduct,
|
||||
+ buf, sizeof(buf)) > 0)
|
||||
+ snprintf(name + strlen(name), sizeof(name) - strlen(name),
|
||||
+ " %s", buf);
|
||||
+
|
||||
+ sz->idev = streamzap_init_input_dev(sz);
|
||||
+ if (!sz->idev)
|
||||
+ goto input_dev_fail;
|
||||
+
|
||||
+ sz->idle = true;
|
||||
+ sz->decoder_state = PulseSpace;
|
||||
+ /* FIXME: don't yet have a way to set this */
|
||||
+ sz->timeout_enabled = true;
|
||||
+ #if 0
|
||||
+ /* not yet supported, depends on patches from maxim */
|
||||
+ /* see also: LIRC_GET_REC_RESOLUTION and LIRC_SET_REC_TIMEOUT */
|
||||
+ sz->min_timeout = STREAMZAP_TIMEOUT * STREAMZAP_RESOLUTION * 1000;
|
||||
+ sz->max_timeout = STREAMZAP_TIMEOUT * STREAMZAP_RESOLUTION * 1000;
|
||||
+ #endif
|
||||
+
|
||||
+ do_gettimeofday(&sz->signal_start);
|
||||
+
|
||||
+ /* Complete final initialisations */
|
||||
+ usb_fill_int_urb(sz->urb_in, usbdev, pipe, sz->buf_in,
|
||||
+ maxp, (usb_complete_t)streamzap_callback,
|
||||
+ sz, sz->endpoint->bInterval);
|
||||
+ sz->urb_in->transfer_dma = sz->dma_in;
|
||||
+ sz->urb_in->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
|
||||
+
|
||||
+ usb_set_intfdata(intf, sz);
|
||||
+
|
||||
+ if (usb_submit_urb(sz->urb_in, GFP_ATOMIC))
|
||||
+ dev_err(sz->dev, "urb submit failed\n");
|
||||
+
|
||||
+ dev_info(sz->dev, "Registered %s on usb%d:%d\n", name,
|
||||
+ usbdev->bus->busnum, usbdev->devnum);
|
||||
+
|
||||
+ /* Load the streamzap not-quite-rc5 decoder too */
|
||||
+ load_rc5_sz_decode();
|
||||
+
|
||||
+ return 0;
|
||||
+
|
||||
+input_dev_fail:
|
||||
+ usb_free_urb(sz->urb_in);
|
||||
+free_buf_in:
|
||||
+ usb_free_coherent(usbdev, maxp, sz->buf_in, sz->dma_in);
|
||||
+free_sz:
|
||||
+ kfree(sz);
|
||||
+
|
||||
+ return retval;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * streamzap_disconnect
|
||||
+ *
|
||||
+ * Called by the usb core when the device is removed from the system.
|
||||
+ *
|
||||
+ * This routine guarantees that the driver will not submit any more urbs
|
||||
+ * by clearing dev->usbdev. It is also supposed to terminate any currently
|
||||
+ * active urbs. Unfortunately, usb_bulk_msg(), used in streamzap_read(),
|
||||
+ * does not provide any way to do this.
|
||||
+ */
|
||||
+static void streamzap_disconnect(struct usb_interface *interface)
|
||||
+{
|
||||
+ struct streamzap_ir *sz = usb_get_intfdata(interface);
|
||||
+ struct usb_device *usbdev = interface_to_usbdev(interface);
|
||||
+
|
||||
+ usb_set_intfdata(interface, NULL);
|
||||
+
|
||||
+ if (!sz)
|
||||
+ return;
|
||||
+
|
||||
+ sz->usbdev = NULL;
|
||||
+ ir_input_unregister(sz->idev);
|
||||
+ usb_kill_urb(sz->urb_in);
|
||||
+ usb_free_urb(sz->urb_in);
|
||||
+ usb_free_coherent(usbdev, sz->buf_in_len, sz->buf_in, sz->dma_in);
|
||||
+
|
||||
+ kfree(sz);
|
||||
+}
|
||||
+
|
||||
+static int streamzap_suspend(struct usb_interface *intf, pm_message_t message)
|
||||
+{
|
||||
+ struct streamzap_ir *sz = usb_get_intfdata(intf);
|
||||
+
|
||||
+ usb_kill_urb(sz->urb_in);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int streamzap_resume(struct usb_interface *intf)
|
||||
+{
|
||||
+ struct streamzap_ir *sz = usb_get_intfdata(intf);
|
||||
+
|
||||
+ if (usb_submit_urb(sz->urb_in, GFP_ATOMIC)) {
|
||||
+ dev_err(sz->dev, "Error sumbiting urb\n");
|
||||
+ return -EIO;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * streamzap_init
|
||||
+ */
|
||||
+static int __init streamzap_init(void)
|
||||
+{
|
||||
+ int ret;
|
||||
+
|
||||
+ /* register this driver with the USB subsystem */
|
||||
+ ret = usb_register(&streamzap_driver);
|
||||
+ if (ret < 0)
|
||||
+ printk(KERN_ERR DRIVER_NAME ": usb register failed, "
|
||||
+ "result = %d\n", ret);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * streamzap_exit
|
||||
+ */
|
||||
+static void __exit streamzap_exit(void)
|
||||
+{
|
||||
+ usb_deregister(&streamzap_driver);
|
||||
+}
|
||||
+
|
||||
+
|
||||
+module_init(streamzap_init);
|
||||
+module_exit(streamzap_exit);
|
||||
+
|
||||
+MODULE_AUTHOR("Jarod Wilson <jarod@wilsonet.com>");
|
||||
+MODULE_DESCRIPTION(DRIVER_DESC);
|
||||
+MODULE_LICENSE("GPL");
|
||||
+
|
||||
+module_param(debug, bool, S_IRUGO | S_IWUSR);
|
||||
+MODULE_PARM_DESC(debug, "Enable debugging messages");
|
||||
diff -Naurp linux-2.6.35.x86_64.orig/include/media/rc-map.h linux-2.6.35.x86_64/include/media/rc-map.h
|
||||
--- linux-2.6.35.x86_64.orig/include/media/rc-map.h 2010-08-15 17:50:34.584382568 -0400
|
||||
+++ linux-2.6.35.x86_64/include/media/rc-map.h 2010-08-16 00:18:02.455993732 -0400
|
||||
@@ -17,12 +17,13 @@
|
||||
#define IR_TYPE_RC6 (1 << 2) /* Philips RC6 protocol */
|
||||
#define IR_TYPE_JVC (1 << 3) /* JVC protocol */
|
||||
#define IR_TYPE_SONY (1 << 4) /* Sony12/15/20 protocol */
|
||||
+#define IR_TYPE_RC5_SZ (1 << 5) /* RC5 variant used by Streamzap */
|
||||
#define IR_TYPE_LIRC (1 << 30) /* Pass raw IR to lirc userspace */
|
||||
#define IR_TYPE_OTHER (1u << 31)
|
||||
|
||||
#define IR_TYPE_ALL (IR_TYPE_RC5 | IR_TYPE_NEC | IR_TYPE_RC6 | \
|
||||
IR_TYPE_JVC | IR_TYPE_SONY | IR_TYPE_LIRC | \
|
||||
- IR_TYPE_OTHER)
|
||||
+ IR_TYPE_RC5_SZ | IR_TYPE_OTHER)
|
||||
|
||||
struct ir_scancode {
|
||||
u32 scancode;
|
||||
@@ -115,6 +116,7 @@ void rc_map_init(void);
|
||||
#define RC_MAP_RC5_TV "rc-rc5-tv"
|
||||
#define RC_MAP_RC6_MCE "rc-rc6-mce"
|
||||
#define RC_MAP_REAL_AUDIO_220_32_KEYS "rc-real-audio-220-32-keys"
|
||||
+#define RC_MAP_STREAMZAP "rc-streamzap"
|
||||
#define RC_MAP_TBS_NEC "rc-tbs-nec"
|
||||
#define RC_MAP_TERRATEC_CINERGY_XS "rc-terratec-cinergy-xs"
|
||||
#define RC_MAP_TEVII_NEC "rc-tevii-nec"
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,28 @@
|
|||
Date: Wed, 01 Sep 2010 13:37:33 -0700 (PDT)
|
||||
Message-Id: <20100901.133733.223467599.davem@davemloft.net>
|
||||
To: davej@redhat.com
|
||||
Cc: simon.kagstrom@netinsight.net, netdev@vger.kernel.org
|
||||
Subject: Re: via-velocity dma-debug warnings again. (2.6.35.2)
|
||||
From: David Miller <davem@davemloft.net>
|
||||
In-Reply-To: <20100901.133547.236248297.davem@davemloft.net>
|
||||
References: <20100901200555.GA30689@redhat.com>
|
||||
<20100901.133414.24593005.davem@davemloft.net>
|
||||
<20100901.133547.236248297.davem@davemloft.net>
|
||||
|
||||
|
||||
Ok, this is becomming hopeless. Let's just try turning off SG support
|
||||
for now, the length calculations are correct in those cases.
|
||||
|
||||
diff --git a/drivers/net/via-velocity.c b/drivers/net/via-velocity.c
|
||||
index fd69095..f534123 100644
|
||||
--- a/drivers/net/via-velocity.c
|
||||
+++ b/drivers/net/via-velocity.c
|
||||
@@ -2824,7 +2824,7 @@ static int __devinit velocity_found1(struct pci_dev *pdev, const struct pci_devi
|
||||
netif_napi_add(dev, &vptr->napi, velocity_poll, VELOCITY_NAPI_WEIGHT);
|
||||
|
||||
dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_FILTER |
|
||||
- NETIF_F_HW_VLAN_RX | NETIF_F_IP_CSUM | NETIF_F_SG;
|
||||
+ NETIF_F_HW_VLAN_RX | NETIF_F_IP_CSUM;
|
||||
|
||||
ret = register_netdev(dev);
|
||||
if (ret < 0)
|
|
@ -1,7 +1,7 @@
|
|||
drivers/staging/Kconfig | 2 +
|
||||
drivers/staging/Makefile | 1 +
|
||||
drivers/staging/lirc/Kconfig | 111 +++
|
||||
drivers/staging/lirc/Makefile | 19 +
|
||||
drivers/staging/lirc/Kconfig | 106 +++
|
||||
drivers/staging/lirc/Makefile | 18 +
|
||||
drivers/staging/lirc/TODO | 8 +
|
||||
drivers/staging/lirc/TODO.lirc_i2c | 3 +
|
||||
drivers/staging/lirc/lirc_bt829.c | 383 +++++++++
|
||||
|
@ -18,10 +18,9 @@
|
|||
drivers/staging/lirc/lirc_sasem.c | 933 +++++++++++++++++++++
|
||||
drivers/staging/lirc/lirc_serial.c | 1313 +++++++++++++++++++++++++++++
|
||||
drivers/staging/lirc/lirc_sir.c | 1282 ++++++++++++++++++++++++++++
|
||||
drivers/staging/lirc/lirc_streamzap.c | 821 ++++++++++++++++++
|
||||
drivers/staging/lirc/lirc_ttusbir.c | 396 +++++++++
|
||||
drivers/staging/lirc/lirc_zilog.c | 1387 +++++++++++++++++++++++++++++++
|
||||
23 files changed, 12034 insertions(+), 0 deletions(-)
|
||||
22 files changed, 11206 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig
|
||||
index 984a754..9296517 100644
|
||||
|
@ -52,7 +51,7 @@ new file mode 100644
|
|||
index 0000000..ab30a09
|
||||
--- /dev/null
|
||||
+++ b/drivers/staging/lirc/Kconfig
|
||||
@@ -0,0 +1,111 @@
|
||||
@@ -0,0 +1,105 @@
|
||||
+#
|
||||
+# LIRC driver(s) configuration
|
||||
+#
|
||||
|
@ -145,12 +144,6 @@ index 0000000..ab30a09
|
|||
+ help
|
||||
+ Driver for the SIR IrDA port
|
||||
+
|
||||
+config LIRC_STREAMZAP
|
||||
+ tristate "Streamzap PC Receiver"
|
||||
+ depends on LIRC_STAGING && USB
|
||||
+ help
|
||||
+ Driver for the Streamzap PC Receiver
|
||||
+
|
||||
+config LIRC_TTUSBIR
|
||||
+ tristate "Technotrend USB IR Receiver"
|
||||
+ depends on LIRC_STAGING && USB
|
||||
|
@ -169,7 +162,7 @@ new file mode 100644
|
|||
index 0000000..a019182
|
||||
--- /dev/null
|
||||
+++ b/drivers/staging/lirc/Makefile
|
||||
@@ -0,0 +1,19 @@
|
||||
@@ -0,0 +1,18 @@
|
||||
+# Makefile for the lirc drivers.
|
||||
+#
|
||||
+
|
||||
|
@ -186,7 +179,6 @@ index 0000000..a019182
|
|||
+obj-$(CONFIG_LIRC_SASEM) += lirc_sasem.o
|
||||
+obj-$(CONFIG_LIRC_SERIAL) += lirc_serial.o
|
||||
+obj-$(CONFIG_LIRC_SIR) += lirc_sir.o
|
||||
+obj-$(CONFIG_LIRC_STREAMZAP) += lirc_streamzap.o
|
||||
+obj-$(CONFIG_LIRC_TTUSBIR) += lirc_ttusbir.o
|
||||
+obj-$(CONFIG_LIRC_ZILOG) += lirc_zilog.o
|
||||
diff --git a/drivers/staging/lirc/TODO b/drivers/staging/lirc/TODO
|
||||
|
@ -9582,833 +9574,6 @@ index 0000000..eb08fa7
|
|||
+
|
||||
+module_param(debug, bool, S_IRUGO | S_IWUSR);
|
||||
+MODULE_PARM_DESC(debug, "Enable debugging messages");
|
||||
diff --git a/drivers/staging/lirc/lirc_streamzap.c b/drivers/staging/lirc/lirc_streamzap.c
|
||||
new file mode 100644
|
||||
index 0000000..be09c10
|
||||
--- /dev/null
|
||||
+++ b/drivers/staging/lirc/lirc_streamzap.c
|
||||
@@ -0,0 +1,821 @@
|
||||
+/*
|
||||
+ * Streamzap Remote Control driver
|
||||
+ *
|
||||
+ * Copyright (c) 2005 Christoph Bartelmus <lirc@bartelmus.de>
|
||||
+ *
|
||||
+ * This driver was based on the work of Greg Wickham and Adrian
|
||||
+ * Dewhurst. It was substantially rewritten to support correct signal
|
||||
+ * gaps and now maintains a delay buffer, which is used to present
|
||||
+ * consistent timing behaviour to user space applications. Without the
|
||||
+ * delay buffer an ugly hack would be required in lircd, which can
|
||||
+ * cause sluggish signal decoding in certain situations.
|
||||
+ *
|
||||
+ * This driver is based on the USB skeleton driver packaged with the
|
||||
+ * kernel; copyright (C) 2001-2003 Greg Kroah-Hartman (greg@kroah.com)
|
||||
+ *
|
||||
+ * This program is free software; you can redistribute it and/or modify
|
||||
+ * it under the terms of the GNU General Public License as published by
|
||||
+ * the Free Software Foundation; either version 2 of the License, or
|
||||
+ * (at your option) any later version.
|
||||
+ *
|
||||
+ * This program is distributed in the hope that it will be useful,
|
||||
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
+ * GNU General Public License for more details.
|
||||
+ *
|
||||
+ * You should have received a copy of the GNU General Public License
|
||||
+ * along with this program; if not, write to the Free Software
|
||||
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
+ */
|
||||
+
|
||||
+#include <linux/kernel.h>
|
||||
+#include <linux/errno.h>
|
||||
+#include <linux/init.h>
|
||||
+#include <linux/slab.h>
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/smp_lock.h>
|
||||
+#include <linux/completion.h>
|
||||
+#include <linux/uaccess.h>
|
||||
+#include <linux/usb.h>
|
||||
+
|
||||
+#include <media/lirc.h>
|
||||
+#include <media/lirc_dev.h>
|
||||
+
|
||||
+#define DRIVER_VERSION "1.28"
|
||||
+#define DRIVER_NAME "lirc_streamzap"
|
||||
+#define DRIVER_DESC "Streamzap Remote Control driver"
|
||||
+
|
||||
+static int debug;
|
||||
+
|
||||
+#define USB_STREAMZAP_VENDOR_ID 0x0e9c
|
||||
+#define USB_STREAMZAP_PRODUCT_ID 0x0000
|
||||
+
|
||||
+/* Use our own dbg macro */
|
||||
+#define dprintk(fmt, args...) \
|
||||
+ do { \
|
||||
+ if (debug) \
|
||||
+ printk(KERN_DEBUG DRIVER_NAME "[%d]: " \
|
||||
+ fmt "\n", ## args); \
|
||||
+ } while (0)
|
||||
+
|
||||
+/* table of devices that work with this driver */
|
||||
+static struct usb_device_id streamzap_table[] = {
|
||||
+ /* Streamzap Remote Control */
|
||||
+ { USB_DEVICE(USB_STREAMZAP_VENDOR_ID, USB_STREAMZAP_PRODUCT_ID) },
|
||||
+ /* Terminating entry */
|
||||
+ { }
|
||||
+};
|
||||
+
|
||||
+MODULE_DEVICE_TABLE(usb, streamzap_table);
|
||||
+
|
||||
+#define STREAMZAP_PULSE_MASK 0xf0
|
||||
+#define STREAMZAP_SPACE_MASK 0x0f
|
||||
+#define STREAMZAP_TIMEOUT 0xff
|
||||
+#define STREAMZAP_RESOLUTION 256
|
||||
+
|
||||
+/* number of samples buffered */
|
||||
+#define STREAMZAP_BUF_LEN 128
|
||||
+
|
||||
+enum StreamzapDecoderState {
|
||||
+ PulseSpace,
|
||||
+ FullPulse,
|
||||
+ FullSpace,
|
||||
+ IgnorePulse
|
||||
+};
|
||||
+
|
||||
+/* Structure to hold all of our device specific stuff
|
||||
+ *
|
||||
+ * some remarks regarding locking:
|
||||
+ * theoretically this struct can be accessed from three threads:
|
||||
+ *
|
||||
+ * - from lirc_dev through set_use_inc/set_use_dec
|
||||
+ *
|
||||
+ * - from the USB layer throuh probe/disconnect/irq
|
||||
+ *
|
||||
+ * Careful placement of lirc_register_driver/lirc_unregister_driver
|
||||
+ * calls will prevent conflicts. lirc_dev makes sure that
|
||||
+ * set_use_inc/set_use_dec are not being executed and will not be
|
||||
+ * called after lirc_unregister_driver returns.
|
||||
+ *
|
||||
+ * - by the timer callback
|
||||
+ *
|
||||
+ * The timer is only running when the device is connected and the
|
||||
+ * LIRC device is open. Making sure the timer is deleted by
|
||||
+ * set_use_dec will make conflicts impossible.
|
||||
+ */
|
||||
+struct usb_streamzap {
|
||||
+
|
||||
+ /* usb */
|
||||
+ /* save off the usb device pointer */
|
||||
+ struct usb_device *udev;
|
||||
+ /* the interface for this device */
|
||||
+ struct usb_interface *interface;
|
||||
+
|
||||
+ /* buffer & dma */
|
||||
+ unsigned char *buf_in;
|
||||
+ dma_addr_t dma_in;
|
||||
+ unsigned int buf_in_len;
|
||||
+
|
||||
+ struct usb_endpoint_descriptor *endpoint;
|
||||
+
|
||||
+ /* IRQ */
|
||||
+ struct urb *urb_in;
|
||||
+
|
||||
+ /* lirc */
|
||||
+ struct lirc_driver *driver;
|
||||
+ struct lirc_buffer *delay_buf;
|
||||
+
|
||||
+ /* timer used to support delay buffering */
|
||||
+ struct timer_list delay_timer;
|
||||
+ int timer_running;
|
||||
+ spinlock_t timer_lock;
|
||||
+
|
||||
+ /* tracks whether we are currently receiving some signal */
|
||||
+ int idle;
|
||||
+ /* sum of signal lengths received since signal start */
|
||||
+ unsigned long sum;
|
||||
+ /* start time of signal; necessary for gap tracking */
|
||||
+ struct timeval signal_last;
|
||||
+ struct timeval signal_start;
|
||||
+ enum StreamzapDecoderState decoder_state;
|
||||
+ struct timer_list flush_timer;
|
||||
+ int flush;
|
||||
+ int in_use;
|
||||
+ int timeout_enabled;
|
||||
+};
|
||||
+
|
||||
+
|
||||
+/* local function prototypes */
|
||||
+static int streamzap_probe(struct usb_interface *interface,
|
||||
+ const struct usb_device_id *id);
|
||||
+static void streamzap_disconnect(struct usb_interface *interface);
|
||||
+static void usb_streamzap_irq(struct urb *urb);
|
||||
+static int streamzap_use_inc(void *data);
|
||||
+static void streamzap_use_dec(void *data);
|
||||
+static long streamzap_ioctl(struct file *filep, unsigned int cmd,
|
||||
+ unsigned long arg);
|
||||
+static int streamzap_suspend(struct usb_interface *intf, pm_message_t message);
|
||||
+static int streamzap_resume(struct usb_interface *intf);
|
||||
+
|
||||
+/* usb specific object needed to register this driver with the usb subsystem */
|
||||
+
|
||||
+static struct usb_driver streamzap_driver = {
|
||||
+ .name = DRIVER_NAME,
|
||||
+ .probe = streamzap_probe,
|
||||
+ .disconnect = streamzap_disconnect,
|
||||
+ .suspend = streamzap_suspend,
|
||||
+ .resume = streamzap_resume,
|
||||
+ .id_table = streamzap_table,
|
||||
+};
|
||||
+
|
||||
+static void stop_timer(struct usb_streamzap *sz)
|
||||
+{
|
||||
+ unsigned long flags;
|
||||
+
|
||||
+ spin_lock_irqsave(&sz->timer_lock, flags);
|
||||
+ if (sz->timer_running) {
|
||||
+ sz->timer_running = 0;
|
||||
+ spin_unlock_irqrestore(&sz->timer_lock, flags);
|
||||
+ del_timer_sync(&sz->delay_timer);
|
||||
+ } else {
|
||||
+ spin_unlock_irqrestore(&sz->timer_lock, flags);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void flush_timeout(unsigned long arg)
|
||||
+{
|
||||
+ struct usb_streamzap *sz = (struct usb_streamzap *) arg;
|
||||
+
|
||||
+ /* finally start accepting data */
|
||||
+ sz->flush = 0;
|
||||
+}
|
||||
+static void delay_timeout(unsigned long arg)
|
||||
+{
|
||||
+ unsigned long flags;
|
||||
+ /* deliver data every 10 ms */
|
||||
+ static unsigned long timer_inc =
|
||||
+ (10000/(1000000/HZ)) == 0 ? 1 : (10000/(1000000/HZ));
|
||||
+ struct usb_streamzap *sz = (struct usb_streamzap *) arg;
|
||||
+ int data;
|
||||
+
|
||||
+ spin_lock_irqsave(&sz->timer_lock, flags);
|
||||
+
|
||||
+ if (!lirc_buffer_empty(sz->delay_buf) &&
|
||||
+ !lirc_buffer_full(sz->driver->rbuf)) {
|
||||
+ lirc_buffer_read(sz->delay_buf, (unsigned char *) &data);
|
||||
+ lirc_buffer_write(sz->driver->rbuf, (unsigned char *) &data);
|
||||
+ }
|
||||
+ if (!lirc_buffer_empty(sz->delay_buf)) {
|
||||
+ while (lirc_buffer_available(sz->delay_buf) <
|
||||
+ STREAMZAP_BUF_LEN / 2 &&
|
||||
+ !lirc_buffer_full(sz->driver->rbuf)) {
|
||||
+ lirc_buffer_read(sz->delay_buf,
|
||||
+ (unsigned char *) &data);
|
||||
+ lirc_buffer_write(sz->driver->rbuf,
|
||||
+ (unsigned char *) &data);
|
||||
+ }
|
||||
+ if (sz->timer_running) {
|
||||
+ sz->delay_timer.expires = jiffies + timer_inc;
|
||||
+ add_timer(&sz->delay_timer);
|
||||
+ }
|
||||
+ } else {
|
||||
+ sz->timer_running = 0;
|
||||
+ }
|
||||
+
|
||||
+ if (!lirc_buffer_empty(sz->driver->rbuf))
|
||||
+ wake_up(&sz->driver->rbuf->wait_poll);
|
||||
+
|
||||
+ spin_unlock_irqrestore(&sz->timer_lock, flags);
|
||||
+}
|
||||
+
|
||||
+static void flush_delay_buffer(struct usb_streamzap *sz)
|
||||
+{
|
||||
+ int data;
|
||||
+ int empty = 1;
|
||||
+
|
||||
+ while (!lirc_buffer_empty(sz->delay_buf)) {
|
||||
+ empty = 0;
|
||||
+ lirc_buffer_read(sz->delay_buf, (unsigned char *) &data);
|
||||
+ if (!lirc_buffer_full(sz->driver->rbuf)) {
|
||||
+ lirc_buffer_write(sz->driver->rbuf,
|
||||
+ (unsigned char *) &data);
|
||||
+ } else {
|
||||
+ dprintk("buffer overflow", sz->driver->minor);
|
||||
+ }
|
||||
+ }
|
||||
+ if (!empty)
|
||||
+ wake_up(&sz->driver->rbuf->wait_poll);
|
||||
+}
|
||||
+
|
||||
+static void push(struct usb_streamzap *sz, unsigned char *data)
|
||||
+{
|
||||
+ unsigned long flags;
|
||||
+
|
||||
+ spin_lock_irqsave(&sz->timer_lock, flags);
|
||||
+ if (lirc_buffer_full(sz->delay_buf)) {
|
||||
+ int read_data;
|
||||
+
|
||||
+ lirc_buffer_read(sz->delay_buf,
|
||||
+ (unsigned char *) &read_data);
|
||||
+ if (!lirc_buffer_full(sz->driver->rbuf)) {
|
||||
+ lirc_buffer_write(sz->driver->rbuf,
|
||||
+ (unsigned char *) &read_data);
|
||||
+ } else {
|
||||
+ dprintk("buffer overflow", sz->driver->minor);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ lirc_buffer_write(sz->delay_buf, data);
|
||||
+
|
||||
+ if (!sz->timer_running) {
|
||||
+ sz->delay_timer.expires = jiffies + HZ/10;
|
||||
+ add_timer(&sz->delay_timer);
|
||||
+ sz->timer_running = 1;
|
||||
+ }
|
||||
+
|
||||
+ spin_unlock_irqrestore(&sz->timer_lock, flags);
|
||||
+}
|
||||
+
|
||||
+static void push_full_pulse(struct usb_streamzap *sz,
|
||||
+ unsigned char value)
|
||||
+{
|
||||
+ int pulse;
|
||||
+
|
||||
+ if (sz->idle) {
|
||||
+ long deltv;
|
||||
+ int tmp;
|
||||
+
|
||||
+ sz->signal_last = sz->signal_start;
|
||||
+ do_gettimeofday(&sz->signal_start);
|
||||
+
|
||||
+ deltv = sz->signal_start.tv_sec-sz->signal_last.tv_sec;
|
||||
+ if (deltv > 15) {
|
||||
+ /* really long time */
|
||||
+ tmp = LIRC_SPACE(LIRC_VALUE_MASK);
|
||||
+ } else {
|
||||
+ tmp = (int) (deltv*1000000+
|
||||
+ sz->signal_start.tv_usec -
|
||||
+ sz->signal_last.tv_usec);
|
||||
+ tmp -= sz->sum;
|
||||
+ tmp = LIRC_SPACE(tmp);
|
||||
+ }
|
||||
+ dprintk("ls %u", sz->driver->minor, tmp);
|
||||
+ push(sz, (char *)&tmp);
|
||||
+
|
||||
+ sz->idle = 0;
|
||||
+ sz->sum = 0;
|
||||
+ }
|
||||
+
|
||||
+ pulse = ((int) value) * STREAMZAP_RESOLUTION;
|
||||
+ pulse += STREAMZAP_RESOLUTION / 2;
|
||||
+ sz->sum += pulse;
|
||||
+ pulse = LIRC_PULSE(pulse);
|
||||
+
|
||||
+ dprintk("p %u", sz->driver->minor, pulse & PULSE_MASK);
|
||||
+ push(sz, (char *)&pulse);
|
||||
+}
|
||||
+
|
||||
+static void push_half_pulse(struct usb_streamzap *sz,
|
||||
+ unsigned char value)
|
||||
+{
|
||||
+ push_full_pulse(sz, (value & STREAMZAP_PULSE_MASK)>>4);
|
||||
+}
|
||||
+
|
||||
+static void push_full_space(struct usb_streamzap *sz,
|
||||
+ unsigned char value)
|
||||
+{
|
||||
+ int space;
|
||||
+
|
||||
+ space = ((int) value)*STREAMZAP_RESOLUTION;
|
||||
+ space += STREAMZAP_RESOLUTION/2;
|
||||
+ sz->sum += space;
|
||||
+ space = LIRC_SPACE(space);
|
||||
+ dprintk("s %u", sz->driver->minor, space);
|
||||
+ push(sz, (char *)&space);
|
||||
+}
|
||||
+
|
||||
+static void push_half_space(struct usb_streamzap *sz,
|
||||
+ unsigned char value)
|
||||
+{
|
||||
+ push_full_space(sz, value & STREAMZAP_SPACE_MASK);
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * usb_streamzap_irq - IRQ handler
|
||||
+ *
|
||||
+ * This procedure is invoked on reception of data from
|
||||
+ * the usb remote.
|
||||
+ */
|
||||
+static void usb_streamzap_irq(struct urb *urb)
|
||||
+{
|
||||
+ struct usb_streamzap *sz;
|
||||
+ int len;
|
||||
+ unsigned int i = 0;
|
||||
+
|
||||
+ if (!urb)
|
||||
+ return;
|
||||
+
|
||||
+ sz = urb->context;
|
||||
+ len = urb->actual_length;
|
||||
+
|
||||
+ switch (urb->status) {
|
||||
+ case -ECONNRESET:
|
||||
+ case -ENOENT:
|
||||
+ case -ESHUTDOWN:
|
||||
+ /*
|
||||
+ * this urb is terminated, clean up.
|
||||
+ * sz might already be invalid at this point
|
||||
+ */
|
||||
+ dprintk("urb status: %d", -1, urb->status);
|
||||
+ return;
|
||||
+ default:
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ dprintk("received %d", sz->driver->minor, urb->actual_length);
|
||||
+ if (!sz->flush) {
|
||||
+ for (i = 0; i < urb->actual_length; i++) {
|
||||
+ dprintk("%d: %x", sz->driver->minor,
|
||||
+ i, (unsigned char) sz->buf_in[i]);
|
||||
+ switch (sz->decoder_state) {
|
||||
+ case PulseSpace:
|
||||
+ if ((sz->buf_in[i]&STREAMZAP_PULSE_MASK) ==
|
||||
+ STREAMZAP_PULSE_MASK) {
|
||||
+ sz->decoder_state = FullPulse;
|
||||
+ continue;
|
||||
+ } else if ((sz->buf_in[i]&STREAMZAP_SPACE_MASK)
|
||||
+ == STREAMZAP_SPACE_MASK) {
|
||||
+ push_half_pulse(sz, sz->buf_in[i]);
|
||||
+ sz->decoder_state = FullSpace;
|
||||
+ continue;
|
||||
+ } else {
|
||||
+ push_half_pulse(sz, sz->buf_in[i]);
|
||||
+ push_half_space(sz, sz->buf_in[i]);
|
||||
+ }
|
||||
+ break;
|
||||
+ case FullPulse:
|
||||
+ push_full_pulse(sz, sz->buf_in[i]);
|
||||
+ sz->decoder_state = IgnorePulse;
|
||||
+ break;
|
||||
+ case FullSpace:
|
||||
+ if (sz->buf_in[i] == STREAMZAP_TIMEOUT) {
|
||||
+ sz->idle = 1;
|
||||
+ stop_timer(sz);
|
||||
+ if (sz->timeout_enabled) {
|
||||
+ int timeout =
|
||||
+ LIRC_TIMEOUT
|
||||
+ (STREAMZAP_TIMEOUT *
|
||||
+ STREAMZAP_RESOLUTION);
|
||||
+ push(sz, (char *)&timeout);
|
||||
+ }
|
||||
+ flush_delay_buffer(sz);
|
||||
+ } else
|
||||
+ push_full_space(sz, sz->buf_in[i]);
|
||||
+ sz->decoder_state = PulseSpace;
|
||||
+ break;
|
||||
+ case IgnorePulse:
|
||||
+ if ((sz->buf_in[i]&STREAMZAP_SPACE_MASK) ==
|
||||
+ STREAMZAP_SPACE_MASK) {
|
||||
+ sz->decoder_state = FullSpace;
|
||||
+ continue;
|
||||
+ }
|
||||
+ push_half_space(sz, sz->buf_in[i]);
|
||||
+ sz->decoder_state = PulseSpace;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ usb_submit_urb(urb, GFP_ATOMIC);
|
||||
+
|
||||
+ return;
|
||||
+}
|
||||
+
|
||||
+static const struct file_operations streamzap_fops = {
|
||||
+ .owner = THIS_MODULE,
|
||||
+ .unlocked_ioctl = streamzap_ioctl,
|
||||
+ .read = lirc_dev_fop_read,
|
||||
+ .write = lirc_dev_fop_write,
|
||||
+ .poll = lirc_dev_fop_poll,
|
||||
+ .open = lirc_dev_fop_open,
|
||||
+ .release = lirc_dev_fop_close,
|
||||
+};
|
||||
+
|
||||
+
|
||||
+/**
|
||||
+ * streamzap_probe
|
||||
+ *
|
||||
+ * Called by usb-core to associated with a candidate device
|
||||
+ * On any failure the return value is the ERROR
|
||||
+ * On success return 0
|
||||
+ */
|
||||
+static int streamzap_probe(struct usb_interface *interface,
|
||||
+ const struct usb_device_id *id)
|
||||
+{
|
||||
+ struct usb_device *udev = interface_to_usbdev(interface);
|
||||
+ struct usb_host_interface *iface_host;
|
||||
+ struct usb_streamzap *sz;
|
||||
+ struct lirc_driver *driver;
|
||||
+ struct lirc_buffer *lirc_buf;
|
||||
+ struct lirc_buffer *delay_buf;
|
||||
+ char buf[63], name[128] = "";
|
||||
+ int retval = -ENOMEM;
|
||||
+ int minor = 0;
|
||||
+
|
||||
+ /* Allocate space for device driver specific data */
|
||||
+ sz = kzalloc(sizeof(struct usb_streamzap), GFP_KERNEL);
|
||||
+ if (sz == NULL)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ sz->udev = udev;
|
||||
+ sz->interface = interface;
|
||||
+
|
||||
+ /* Check to ensure endpoint information matches requirements */
|
||||
+ iface_host = interface->cur_altsetting;
|
||||
+
|
||||
+ if (iface_host->desc.bNumEndpoints != 1) {
|
||||
+ err("%s: Unexpected desc.bNumEndpoints (%d)", __func__,
|
||||
+ iface_host->desc.bNumEndpoints);
|
||||
+ retval = -ENODEV;
|
||||
+ goto free_sz;
|
||||
+ }
|
||||
+
|
||||
+ sz->endpoint = &(iface_host->endpoint[0].desc);
|
||||
+ if ((sz->endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK)
|
||||
+ != USB_DIR_IN) {
|
||||
+ err("%s: endpoint doesn't match input device 02%02x",
|
||||
+ __func__, sz->endpoint->bEndpointAddress);
|
||||
+ retval = -ENODEV;
|
||||
+ goto free_sz;
|
||||
+ }
|
||||
+
|
||||
+ if ((sz->endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
|
||||
+ != USB_ENDPOINT_XFER_INT) {
|
||||
+ err("%s: endpoint attributes don't match xfer 02%02x",
|
||||
+ __func__, sz->endpoint->bmAttributes);
|
||||
+ retval = -ENODEV;
|
||||
+ goto free_sz;
|
||||
+ }
|
||||
+
|
||||
+ if (sz->endpoint->wMaxPacketSize == 0) {
|
||||
+ err("%s: endpoint message size==0? ", __func__);
|
||||
+ retval = -ENODEV;
|
||||
+ goto free_sz;
|
||||
+ }
|
||||
+
|
||||
+ /* Allocate the USB buffer and IRQ URB */
|
||||
+
|
||||
+ sz->buf_in_len = sz->endpoint->wMaxPacketSize;
|
||||
+ sz->buf_in = usb_alloc_coherent(sz->udev, sz->buf_in_len,
|
||||
+ GFP_ATOMIC, &sz->dma_in);
|
||||
+ if (sz->buf_in == NULL)
|
||||
+ goto free_sz;
|
||||
+
|
||||
+ sz->urb_in = usb_alloc_urb(0, GFP_KERNEL);
|
||||
+ if (sz->urb_in == NULL)
|
||||
+ goto free_sz;
|
||||
+
|
||||
+ /* Connect this device to the LIRC sub-system */
|
||||
+ driver = kzalloc(sizeof(struct lirc_driver), GFP_KERNEL);
|
||||
+ if (!driver)
|
||||
+ goto free_sz;
|
||||
+
|
||||
+ lirc_buf = kmalloc(sizeof(struct lirc_buffer), GFP_KERNEL);
|
||||
+ if (!lirc_buf)
|
||||
+ goto free_driver;
|
||||
+ if (lirc_buffer_init(lirc_buf, sizeof(int), STREAMZAP_BUF_LEN))
|
||||
+ goto kfree_lirc_buf;
|
||||
+
|
||||
+ delay_buf = kmalloc(sizeof(struct lirc_buffer), GFP_KERNEL);
|
||||
+ if (!delay_buf)
|
||||
+ goto free_lirc_buf;
|
||||
+ if (lirc_buffer_init(delay_buf, sizeof(int), STREAMZAP_BUF_LEN))
|
||||
+ goto kfree_delay_buf;
|
||||
+
|
||||
+ sz->driver = driver;
|
||||
+ strcpy(sz->driver->name, DRIVER_NAME);
|
||||
+ sz->driver->minor = -1;
|
||||
+ sz->driver->sample_rate = 0;
|
||||
+ sz->driver->code_length = sizeof(int) * 8;
|
||||
+ sz->driver->features = LIRC_CAN_REC_MODE2 |
|
||||
+ LIRC_CAN_GET_REC_RESOLUTION |
|
||||
+ LIRC_CAN_SET_REC_TIMEOUT;
|
||||
+ sz->driver->data = sz;
|
||||
+ sz->driver->min_timeout = STREAMZAP_TIMEOUT * STREAMZAP_RESOLUTION;
|
||||
+ sz->driver->max_timeout = STREAMZAP_TIMEOUT * STREAMZAP_RESOLUTION;
|
||||
+ sz->driver->rbuf = lirc_buf;
|
||||
+ sz->delay_buf = delay_buf;
|
||||
+ sz->driver->set_use_inc = &streamzap_use_inc;
|
||||
+ sz->driver->set_use_dec = &streamzap_use_dec;
|
||||
+ sz->driver->fops = &streamzap_fops;
|
||||
+ sz->driver->dev = &interface->dev;
|
||||
+ sz->driver->owner = THIS_MODULE;
|
||||
+
|
||||
+ sz->idle = 1;
|
||||
+ sz->decoder_state = PulseSpace;
|
||||
+ init_timer(&sz->delay_timer);
|
||||
+ sz->delay_timer.function = delay_timeout;
|
||||
+ sz->delay_timer.data = (unsigned long) sz;
|
||||
+ sz->timer_running = 0;
|
||||
+ spin_lock_init(&sz->timer_lock);
|
||||
+
|
||||
+ init_timer(&sz->flush_timer);
|
||||
+ sz->flush_timer.function = flush_timeout;
|
||||
+ sz->flush_timer.data = (unsigned long) sz;
|
||||
+ /* Complete final initialisations */
|
||||
+
|
||||
+ usb_fill_int_urb(sz->urb_in, udev,
|
||||
+ usb_rcvintpipe(udev, sz->endpoint->bEndpointAddress),
|
||||
+ sz->buf_in, sz->buf_in_len, usb_streamzap_irq, sz,
|
||||
+ sz->endpoint->bInterval);
|
||||
+ sz->urb_in->transfer_dma = sz->dma_in;
|
||||
+ sz->urb_in->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
|
||||
+
|
||||
+ if (udev->descriptor.iManufacturer
|
||||
+ && usb_string(udev, udev->descriptor.iManufacturer,
|
||||
+ buf, sizeof(buf)) > 0)
|
||||
+ strlcpy(name, buf, sizeof(name));
|
||||
+
|
||||
+ if (udev->descriptor.iProduct
|
||||
+ && usb_string(udev, udev->descriptor.iProduct,
|
||||
+ buf, sizeof(buf)) > 0)
|
||||
+ snprintf(name + strlen(name), sizeof(name) - strlen(name),
|
||||
+ " %s", buf);
|
||||
+
|
||||
+ minor = lirc_register_driver(driver);
|
||||
+
|
||||
+ if (minor < 0)
|
||||
+ goto free_delay_buf;
|
||||
+
|
||||
+ sz->driver->minor = minor;
|
||||
+
|
||||
+ usb_set_intfdata(interface, sz);
|
||||
+
|
||||
+ printk(KERN_INFO DRIVER_NAME "[%d]: %s on usb%d:%d attached\n",
|
||||
+ sz->driver->minor, name,
|
||||
+ udev->bus->busnum, sz->udev->devnum);
|
||||
+
|
||||
+ return 0;
|
||||
+
|
||||
+free_delay_buf:
|
||||
+ lirc_buffer_free(sz->delay_buf);
|
||||
+kfree_delay_buf:
|
||||
+ kfree(delay_buf);
|
||||
+free_lirc_buf:
|
||||
+ lirc_buffer_free(sz->driver->rbuf);
|
||||
+kfree_lirc_buf:
|
||||
+ kfree(lirc_buf);
|
||||
+free_driver:
|
||||
+ kfree(driver);
|
||||
+free_sz:
|
||||
+ if (retval == -ENOMEM)
|
||||
+ err("Out of memory");
|
||||
+
|
||||
+ if (sz) {
|
||||
+ usb_free_urb(sz->urb_in);
|
||||
+ usb_free_coherent(udev, sz->buf_in_len, sz->buf_in, sz->dma_in);
|
||||
+ kfree(sz);
|
||||
+ }
|
||||
+
|
||||
+ return retval;
|
||||
+}
|
||||
+
|
||||
+static int streamzap_use_inc(void *data)
|
||||
+{
|
||||
+ struct usb_streamzap *sz = data;
|
||||
+
|
||||
+ if (!sz) {
|
||||
+ dprintk("%s called with no context", -1, __func__);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+ dprintk("set use inc", sz->driver->minor);
|
||||
+
|
||||
+ lirc_buffer_clear(sz->driver->rbuf);
|
||||
+ lirc_buffer_clear(sz->delay_buf);
|
||||
+
|
||||
+ sz->flush_timer.expires = jiffies + HZ;
|
||||
+ sz->flush = 1;
|
||||
+ add_timer(&sz->flush_timer);
|
||||
+
|
||||
+ sz->urb_in->dev = sz->udev;
|
||||
+ if (usb_submit_urb(sz->urb_in, GFP_ATOMIC)) {
|
||||
+ dprintk("open result = -EIO error submitting urb",
|
||||
+ sz->driver->minor);
|
||||
+ return -EIO;
|
||||
+ }
|
||||
+ sz->in_use++;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void streamzap_use_dec(void *data)
|
||||
+{
|
||||
+ struct usb_streamzap *sz = data;
|
||||
+
|
||||
+ if (!sz) {
|
||||
+ dprintk("%s called with no context", -1, __func__);
|
||||
+ return;
|
||||
+ }
|
||||
+ dprintk("set use dec", sz->driver->minor);
|
||||
+
|
||||
+ if (sz->flush) {
|
||||
+ sz->flush = 0;
|
||||
+ del_timer_sync(&sz->flush_timer);
|
||||
+ }
|
||||
+
|
||||
+ usb_kill_urb(sz->urb_in);
|
||||
+
|
||||
+ stop_timer(sz);
|
||||
+
|
||||
+ sz->in_use--;
|
||||
+}
|
||||
+
|
||||
+static long streamzap_ioctl(struct file *filep, unsigned int cmd,
|
||||
+ unsigned long arg)
|
||||
+{
|
||||
+ int result = 0;
|
||||
+ int val;
|
||||
+ struct usb_streamzap *sz = lirc_get_pdata(filep);
|
||||
+
|
||||
+ switch (cmd) {
|
||||
+ case LIRC_GET_REC_RESOLUTION:
|
||||
+ result = put_user(STREAMZAP_RESOLUTION, (unsigned int *) arg);
|
||||
+ break;
|
||||
+ case LIRC_SET_REC_TIMEOUT:
|
||||
+ result = get_user(val, (int *)arg);
|
||||
+ if (result == 0) {
|
||||
+ if (val == STREAMZAP_TIMEOUT * STREAMZAP_RESOLUTION)
|
||||
+ sz->timeout_enabled = 1;
|
||||
+ else if (val == 0)
|
||||
+ sz->timeout_enabled = 0;
|
||||
+ else
|
||||
+ result = -EINVAL;
|
||||
+ }
|
||||
+ break;
|
||||
+ default:
|
||||
+ return lirc_dev_fop_ioctl(filep, cmd, arg);
|
||||
+ }
|
||||
+ return result;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * streamzap_disconnect
|
||||
+ *
|
||||
+ * Called by the usb core when the device is removed from the system.
|
||||
+ *
|
||||
+ * This routine guarantees that the driver will not submit any more urbs
|
||||
+ * by clearing dev->udev. It is also supposed to terminate any currently
|
||||
+ * active urbs. Unfortunately, usb_bulk_msg(), used in streamzap_read(),
|
||||
+ * does not provide any way to do this.
|
||||
+ */
|
||||
+static void streamzap_disconnect(struct usb_interface *interface)
|
||||
+{
|
||||
+ struct usb_streamzap *sz;
|
||||
+ int errnum;
|
||||
+ int minor;
|
||||
+
|
||||
+ sz = usb_get_intfdata(interface);
|
||||
+
|
||||
+ /* unregister from the LIRC sub-system */
|
||||
+
|
||||
+ errnum = lirc_unregister_driver(sz->driver->minor);
|
||||
+ if (errnum != 0)
|
||||
+ dprintk("error in lirc_unregister: (returned %d)",
|
||||
+ sz->driver->minor, errnum);
|
||||
+
|
||||
+ lirc_buffer_free(sz->delay_buf);
|
||||
+ lirc_buffer_free(sz->driver->rbuf);
|
||||
+
|
||||
+ /* unregister from the USB sub-system */
|
||||
+
|
||||
+ usb_free_urb(sz->urb_in);
|
||||
+
|
||||
+ usb_free_coherent(sz->udev, sz->buf_in_len, sz->buf_in, sz->dma_in);
|
||||
+
|
||||
+ minor = sz->driver->minor;
|
||||
+ kfree(sz->driver->rbuf);
|
||||
+ kfree(sz->driver);
|
||||
+ kfree(sz->delay_buf);
|
||||
+ kfree(sz);
|
||||
+
|
||||
+ printk(KERN_INFO DRIVER_NAME "[%d]: disconnected\n", minor);
|
||||
+}
|
||||
+
|
||||
+static int streamzap_suspend(struct usb_interface *intf, pm_message_t message)
|
||||
+{
|
||||
+ struct usb_streamzap *sz = usb_get_intfdata(intf);
|
||||
+
|
||||
+ printk(KERN_INFO DRIVER_NAME "[%d]: suspend\n", sz->driver->minor);
|
||||
+ if (sz->in_use) {
|
||||
+ if (sz->flush) {
|
||||
+ sz->flush = 0;
|
||||
+ del_timer_sync(&sz->flush_timer);
|
||||
+ }
|
||||
+
|
||||
+ stop_timer(sz);
|
||||
+
|
||||
+ usb_kill_urb(sz->urb_in);
|
||||
+ }
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int streamzap_resume(struct usb_interface *intf)
|
||||
+{
|
||||
+ struct usb_streamzap *sz = usb_get_intfdata(intf);
|
||||
+
|
||||
+ lirc_buffer_clear(sz->driver->rbuf);
|
||||
+ lirc_buffer_clear(sz->delay_buf);
|
||||
+
|
||||
+ if (sz->in_use) {
|
||||
+ sz->flush_timer.expires = jiffies + HZ;
|
||||
+ sz->flush = 1;
|
||||
+ add_timer(&sz->flush_timer);
|
||||
+
|
||||
+ sz->urb_in->dev = sz->udev;
|
||||
+ if (usb_submit_urb(sz->urb_in, GFP_ATOMIC)) {
|
||||
+ dprintk("open result = -EIO error submitting urb",
|
||||
+ sz->driver->minor);
|
||||
+ return -EIO;
|
||||
+ }
|
||||
+ }
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * usb_streamzap_init
|
||||
+ */
|
||||
+static int __init usb_streamzap_init(void)
|
||||
+{
|
||||
+ int result;
|
||||
+
|
||||
+ /* register this driver with the USB subsystem */
|
||||
+ result = usb_register(&streamzap_driver);
|
||||
+
|
||||
+ if (result) {
|
||||
+ err("usb_register failed. Error number %d",
|
||||
+ result);
|
||||
+ return result;
|
||||
+ }
|
||||
+
|
||||
+ printk(KERN_INFO DRIVER_NAME " " DRIVER_VERSION " registered\n");
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * usb_streamzap_exit
|
||||
+ */
|
||||
+static void __exit usb_streamzap_exit(void)
|
||||
+{
|
||||
+ usb_deregister(&streamzap_driver);
|
||||
+}
|
||||
+
|
||||
+
|
||||
+module_init(usb_streamzap_init);
|
||||
+module_exit(usb_streamzap_exit);
|
||||
+
|
||||
+MODULE_AUTHOR("Christoph Bartelmus, Greg Wickham, Adrian Dewhurst");
|
||||
+MODULE_DESCRIPTION(DRIVER_DESC);
|
||||
+MODULE_LICENSE("GPL");
|
||||
+
|
||||
+module_param(debug, bool, S_IRUGO | S_IWUSR);
|
||||
+MODULE_PARM_DESC(debug, "Enable debugging messages");
|
||||
diff --git a/drivers/staging/lirc/lirc_ttusbir.c b/drivers/staging/lirc/lirc_ttusbir.c
|
||||
new file mode 100644
|
||||
index 0000000..e345ab9
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
From kernel-bounces@lists.fedoraproject.org Thu Sep 9 09:24:46 2010
|
||||
From: Stanislaw Gruszka <sgruszka@redhat.com>
|
||||
Subject: [PATCH 3/3] mmc: add ricoh e822 pci id
|
||||
Date: Thu, 9 Sep 2010 15:24:12 +0200
|
||||
|
||||
From: Pablo Castillo <CyberCastle@gmail.com>
|
||||
|
||||
Upstream 568133ebda39f7507759a744fa9cf4d5097bad2f commit.
|
||||
|
||||
Signed-off-by: Pablo Castillo <CyberCastle@gmail.com>
|
||||
Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
|
||||
Tested-by: Gregg Lebovitz <gregg@lebovitz.net>
|
||||
Cc: Maxim Levitsky <maximlevitsky@gmail.com>
|
||||
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
||||
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
|
||||
---
|
||||
drivers/mmc/host/sdhci-pci.c | 8 ++++++++
|
||||
1 files changed, 8 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/drivers/mmc/host/sdhci-pci.c b/drivers/mmc/host/sdhci-pci.c
|
||||
index e021431..e8aa99d 100644
|
||||
--- a/drivers/mmc/host/sdhci-pci.c
|
||||
+++ b/drivers/mmc/host/sdhci-pci.c
|
||||
@@ -415,6 +415,14 @@ static const struct pci_device_id pci_ids[] __devinitdata = {
|
||||
},
|
||||
|
||||
{
|
||||
+ .vendor = PCI_VENDOR_ID_RICOH,
|
||||
+ .device = 0xe822,
|
||||
+ .subvendor = PCI_ANY_ID,
|
||||
+ .subdevice = PCI_ANY_ID,
|
||||
+ .driver_data = (kernel_ulong_t)&sdhci_ricoh_mmc,
|
||||
+ },
|
||||
+
|
||||
+ {
|
||||
.vendor = PCI_VENDOR_ID_ENE,
|
||||
.device = PCI_DEVICE_ID_ENE_CB712_SD,
|
||||
.subvendor = PCI_ANY_ID,
|
||||
--
|
||||
1.7.1
|
||||
|
||||
_______________________________________________
|
||||
kernel mailing list
|
||||
kernel@lists.fedoraproject.org
|
||||
https://admin.fedoraproject.org/mailman/listinfo/kernel
|
||||
|
|
@ -0,0 +1,150 @@
|
|||
From kernel-bounces@lists.fedoraproject.org Thu Sep 9 09:24:33 2010
|
||||
From: Stanislaw Gruszka <sgruszka@redhat.com>
|
||||
Subject: [PATCH 2/3] mmc: make sdhci work with ricoh mmc controller
|
||||
Date: Thu, 9 Sep 2010 15:24:11 +0200
|
||||
|
||||
From: Maxim Levitsky <maximlevitsky@gmail.com>
|
||||
|
||||
Upstream ccc92c23240cdf952ef7cc39ba563910dcbc9cbe commit.
|
||||
|
||||
The current way of disabling it is not well tested by vendor and has all
|
||||
kinds of bugs that show up on resume from ram/disk. A very good example
|
||||
is a dead SDHCI controller.
|
||||
|
||||
Old way of disabling is still supported by continuing to use
|
||||
CONFIG_MMC_RICOH_MMC.
|
||||
|
||||
Based on 'http://list.drzeus.cx/pipermail/sdhci-devel/2007-December/002085.html'
|
||||
Therefore most of the credit for this goes to Andrew de Quincey
|
||||
|
||||
Signed-off-by: Maxim Levitsky <maximlevitsky@gmail.com>
|
||||
Cc: Andrew de Quincey <adq_dvb@lidskialf.net>
|
||||
Acked-by: Philip Langdale <philipl@overt.org>
|
||||
Cc: "Rafael J. Wysocki" <rjw@sisk.pl>
|
||||
Cc: <linux-mmc@vger.kernel.org>
|
||||
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
||||
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
|
||||
---
|
||||
drivers/mmc/host/sdhci-pci.c | 41 +++++++++++++++++++++++++++++++++++++++++
|
||||
drivers/mmc/host/sdhci.c | 3 ++-
|
||||
drivers/mmc/host/sdhci.h | 4 ++++
|
||||
3 files changed, 47 insertions(+), 1 deletions(-)
|
||||
|
||||
diff --git a/drivers/mmc/host/sdhci-pci.c b/drivers/mmc/host/sdhci-pci.c
|
||||
index 65483fd..e021431 100644
|
||||
--- a/drivers/mmc/host/sdhci-pci.c
|
||||
+++ b/drivers/mmc/host/sdhci-pci.c
|
||||
@@ -17,6 +17,7 @@
|
||||
#include <linux/pci.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/slab.h>
|
||||
+#include <linux/device.h>
|
||||
|
||||
#include <linux/mmc/host.h>
|
||||
|
||||
@@ -84,7 +85,30 @@ static int ricoh_probe(struct sdhci_pci_chip *chip)
|
||||
if (chip->pdev->subsystem_vendor == PCI_VENDOR_ID_SAMSUNG ||
|
||||
chip->pdev->subsystem_vendor == PCI_VENDOR_ID_SONY)
|
||||
chip->quirks |= SDHCI_QUIRK_NO_CARD_NO_RESET;
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int ricoh_mmc_probe_slot(struct sdhci_pci_slot *slot)
|
||||
+{
|
||||
+ slot->host->caps =
|
||||
+ ((0x21 << SDHCI_TIMEOUT_CLK_SHIFT)
|
||||
+ & SDHCI_TIMEOUT_CLK_MASK) |
|
||||
+
|
||||
+ ((0x21 << SDHCI_CLOCK_BASE_SHIFT)
|
||||
+ & SDHCI_CLOCK_BASE_MASK) |
|
||||
|
||||
+ SDHCI_TIMEOUT_CLK_UNIT |
|
||||
+ SDHCI_CAN_VDD_330 |
|
||||
+ SDHCI_CAN_DO_SDMA;
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int ricoh_mmc_resume(struct sdhci_pci_chip *chip)
|
||||
+{
|
||||
+ /* Apply a delay to allow controller to settle */
|
||||
+ /* Otherwise it becomes confused if card state changed
|
||||
+ during suspend */
|
||||
+ msleep(500);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -95,6 +119,15 @@ static const struct sdhci_pci_fixes sdhci_ricoh = {
|
||||
SDHCI_QUIRK_CLOCK_BEFORE_RESET,
|
||||
};
|
||||
|
||||
+static const struct sdhci_pci_fixes sdhci_ricoh_mmc = {
|
||||
+ .probe_slot = ricoh_mmc_probe_slot,
|
||||
+ .resume = ricoh_mmc_resume,
|
||||
+ .quirks = SDHCI_QUIRK_32BIT_DMA_ADDR |
|
||||
+ SDHCI_QUIRK_CLOCK_BEFORE_RESET |
|
||||
+ SDHCI_QUIRK_NO_CARD_NO_RESET |
|
||||
+ SDHCI_QUIRK_MISSING_CAPS
|
||||
+};
|
||||
+
|
||||
static const struct sdhci_pci_fixes sdhci_ene_712 = {
|
||||
.quirks = SDHCI_QUIRK_SINGLE_POWER_WRITE |
|
||||
SDHCI_QUIRK_BROKEN_DMA,
|
||||
@@ -374,6 +407,14 @@ static const struct pci_device_id pci_ids[] __devinitdata = {
|
||||
},
|
||||
|
||||
{
|
||||
+ .vendor = PCI_VENDOR_ID_RICOH,
|
||||
+ .device = 0x843,
|
||||
+ .subvendor = PCI_ANY_ID,
|
||||
+ .subdevice = PCI_ANY_ID,
|
||||
+ .driver_data = (kernel_ulong_t)&sdhci_ricoh_mmc,
|
||||
+ },
|
||||
+
|
||||
+ {
|
||||
.vendor = PCI_VENDOR_ID_ENE,
|
||||
.device = PCI_DEVICE_ID_ENE_CB712_SD,
|
||||
.subvendor = PCI_ANY_ID,
|
||||
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
|
||||
index 955cad9..8e1dda3 100644
|
||||
--- a/drivers/mmc/host/sdhci.c
|
||||
+++ b/drivers/mmc/host/sdhci.c
|
||||
@@ -1692,7 +1692,8 @@ int sdhci_add_host(struct sdhci_host *host)
|
||||
host->version);
|
||||
}
|
||||
|
||||
- caps = sdhci_readl(host, SDHCI_CAPABILITIES);
|
||||
+ caps = (host->quirks & SDHCI_QUIRK_MISSING_CAPS) ? host->caps :
|
||||
+ sdhci_readl(host, SDHCI_CAPABILITIES);
|
||||
|
||||
if (host->quirks & SDHCI_QUIRK_FORCE_DMA)
|
||||
host->flags |= SDHCI_USE_SDMA;
|
||||
diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
|
||||
index eb5efe0..030de49 100644
|
||||
--- a/drivers/mmc/host/sdhci.h
|
||||
+++ b/drivers/mmc/host/sdhci.h
|
||||
@@ -241,6 +241,8 @@ struct sdhci_host {
|
||||
#define SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN (1<<25)
|
||||
/* Controller cannot support End Attribute in NOP ADMA descriptor */
|
||||
#define SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC (1<<26)
|
||||
+/* Controller is missing device caps. Use caps provided by host */
|
||||
+#define SDHCI_QUIRK_MISSING_CAPS (1<<27)
|
||||
|
||||
int irq; /* Device IRQ */
|
||||
void __iomem * ioaddr; /* Mapped address */
|
||||
@@ -293,6 +295,8 @@ struct sdhci_host {
|
||||
|
||||
struct timer_list timer; /* Timer for timeouts */
|
||||
|
||||
+ unsigned int caps; /* Alternative capabilities */
|
||||
+
|
||||
unsigned long private[0] ____cacheline_aligned;
|
||||
};
|
||||
|
||||
--
|
||||
1.7.1
|
||||
|
||||
_______________________________________________
|
||||
kernel mailing list
|
||||
kernel@lists.fedoraproject.org
|
||||
https://admin.fedoraproject.org/mailman/listinfo/kernel
|
||||
|
|
@ -0,0 +1,85 @@
|
|||
commit 420a0f66378c84b00b0e603e4d38210102dbe367
|
||||
Author: Dmitry Torokhov <dmitry.torokhov@gmail.com>
|
||||
Date: Sat Sep 18 10:11:09 2010 -0700
|
||||
|
||||
PNPACPI: cope with invalid device IDs
|
||||
|
||||
If primary ID (HID) is invalid try locating first valid ID on compatible
|
||||
ID list before giving up.
|
||||
|
||||
This helps, for example, to recognize i8042 AUX port on Sony Vaio VPCZ1
|
||||
which uses SNYSYN0003 as HID. Without the patch users are forced to
|
||||
boot with i8042.nopnp to make use of their touchpads.
|
||||
|
||||
Tested-by: Jan-Hendrik Zab <jan@jhz.name>
|
||||
Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
|
||||
Signed-off-by: Len Brown <len.brown@intel.com>
|
||||
|
||||
diff --git a/drivers/pnp/pnpacpi/core.c b/drivers/pnp/pnpacpi/core.c
|
||||
index dc4e32e..0d943ee 100644
|
||||
--- a/drivers/pnp/pnpacpi/core.c
|
||||
+++ b/drivers/pnp/pnpacpi/core.c
|
||||
@@ -28,7 +28,7 @@
|
||||
#include "../base.h"
|
||||
#include "pnpacpi.h"
|
||||
|
||||
-static int num = 0;
|
||||
+static int num;
|
||||
|
||||
/* We need only to blacklist devices that have already an acpi driver that
|
||||
* can't use pnp layer. We don't need to blacklist device that are directly
|
||||
@@ -180,11 +180,24 @@ struct pnp_protocol pnpacpi_protocol = {
|
||||
};
|
||||
EXPORT_SYMBOL(pnpacpi_protocol);
|
||||
|
||||
+static char *pnpacpi_get_id(struct acpi_device *device)
|
||||
+{
|
||||
+ struct acpi_hardware_id *id;
|
||||
+
|
||||
+ list_for_each_entry(id, &device->pnp.ids, list) {
|
||||
+ if (ispnpidacpi(id->id))
|
||||
+ return id->id;
|
||||
+ }
|
||||
+
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
static int __init pnpacpi_add_device(struct acpi_device *device)
|
||||
{
|
||||
acpi_handle temp = NULL;
|
||||
acpi_status status;
|
||||
struct pnp_dev *dev;
|
||||
+ char *pnpid;
|
||||
struct acpi_hardware_id *id;
|
||||
|
||||
/*
|
||||
@@ -192,11 +205,17 @@ static int __init pnpacpi_add_device(struct acpi_device *device)
|
||||
* driver should not be loaded.
|
||||
*/
|
||||
status = acpi_get_handle(device->handle, "_CRS", &temp);
|
||||
- if (ACPI_FAILURE(status) || !ispnpidacpi(acpi_device_hid(device)) ||
|
||||
- is_exclusive_device(device) || (!device->status.present))
|
||||
+ if (ACPI_FAILURE(status))
|
||||
+ return 0;
|
||||
+
|
||||
+ pnpid = pnpacpi_get_id(device);
|
||||
+ if (!pnpid)
|
||||
+ return 0;
|
||||
+
|
||||
+ if (is_exclusive_device(device) || !device->status.present)
|
||||
return 0;
|
||||
|
||||
- dev = pnp_alloc_dev(&pnpacpi_protocol, num, acpi_device_hid(device));
|
||||
+ dev = pnp_alloc_dev(&pnpacpi_protocol, num, pnpid);
|
||||
if (!dev)
|
||||
return -ENOMEM;
|
||||
|
||||
@@ -227,7 +246,7 @@ static int __init pnpacpi_add_device(struct acpi_device *device)
|
||||
pnpacpi_parse_resource_option_data(dev);
|
||||
|
||||
list_for_each_entry(id, &device->pnp.ids, list) {
|
||||
- if (!strcmp(id->id, acpi_device_hid(device)))
|
||||
+ if (!strcmp(id->id, pnpid))
|
||||
continue;
|
||||
if (!ispnpidacpi(id->id))
|
||||
continue;
|
|
@ -0,0 +1,120 @@
|
|||
From sgruszka@redhat.com Mon Oct 18 05:10:00 2010
|
||||
Return-Path: sgruszka@redhat.com
|
||||
Received: from zmta01.collab.prod.int.phx2.redhat.com (LHLO
|
||||
zmta01.collab.prod.int.phx2.redhat.com) (10.5.5.31) by
|
||||
mail03.corp.redhat.com with LMTP; Mon, 18 Oct 2010 05:10:00 -0400 (EDT)
|
||||
Received: from localhost (localhost.localdomain [127.0.0.1])
|
||||
by zmta01.collab.prod.int.phx2.redhat.com (Postfix) with ESMTP id 5E48E928A4;
|
||||
Mon, 18 Oct 2010 05:10:00 -0400 (EDT)
|
||||
Received: from zmta01.collab.prod.int.phx2.redhat.com ([127.0.0.1])
|
||||
by localhost (zmta01.collab.prod.int.phx2.redhat.com [127.0.0.1]) (amavisd-new, port 10024)
|
||||
with ESMTP id q3QJQ+TOP+bt; Mon, 18 Oct 2010 05:10:00 -0400 (EDT)
|
||||
Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23])
|
||||
by zmta01.collab.prod.int.phx2.redhat.com (Postfix) with ESMTP id 423CC91A7C;
|
||||
Mon, 18 Oct 2010 05:10:00 -0400 (EDT)
|
||||
Received: from localhost (dhcp-1-246.brq.redhat.com [10.34.1.246])
|
||||
by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id o9I99x6b006228;
|
||||
Mon, 18 Oct 2010 05:09:59 -0400
|
||||
From: Stanislaw Gruszka <sgruszka@redhat.com>
|
||||
To: stable@kernel.org
|
||||
Cc: Kyle McMartin <kmcmartin@redhat.com>,
|
||||
Stanislaw Gruszka <sgruszka@redhat.com>,
|
||||
"David S. Miller" <davem@davemloft.net>
|
||||
Subject: [PATCH -stable 2.6.34+] r8169: allocate with GFP_KERNEL flag when able to sleep
|
||||
Date: Mon, 18 Oct 2010 11:12:22 +0200
|
||||
Message-Id: <1287393142-2566-1-git-send-email-sgruszka@redhat.com>
|
||||
X-Scanned-By: MIMEDefang 2.68 on 10.5.11.23
|
||||
|
||||
Upstream aeb19f6052b5e5c8a24aa444fbff73b84341beac commit.
|
||||
|
||||
We have fedora bug report where driver fail to initialize after
|
||||
suspend/resume because of memory allocation errors:
|
||||
https://bugzilla.redhat.com/show_bug.cgi?id=629158
|
||||
|
||||
To fix use GFP_KERNEL allocation where possible.
|
||||
|
||||
Patch should fix any allocation errors with calltrace like that:
|
||||
|
||||
NetworkManager: page allocation failure. order:3, mode:0x4020
|
||||
Pid: 1427, comm: NetworkManager Not tainted 2.6.31.12-rhapsody.fc12-121 #1
|
||||
Call Trace:
|
||||
[<ffffffff810c876f>] __alloc_pages_nodemask+0x57a/0x5bb
|
||||
[<ffffffff810f415d>] alloc_pages_node+0x48/0x4a
|
||||
[<ffffffff810f4189>] kmalloc_large_node+0x2a/0x67
|
||||
[<ffffffff810f5f1c>] __kmalloc_node_track_caller+0x31/0x11b
|
||||
[<ffffffff8136f4fe>] ? __netdev_alloc_skb+0x34/0x50
|
||||
[<ffffffff8136e8b8>] __alloc_skb+0x80/0x170
|
||||
[<ffffffff8136f4fe>] __netdev_alloc_skb+0x34/0x50
|
||||
[<ffffffffa011c5e0>] rtl8169_rx_fill+0xa8/0x154 [r8169]
|
||||
[<ffffffffa011e5c5>] rtl8169_init_ring+0x71/0x9f [r8169]
|
||||
[<ffffffffa011edbe>] rtl8169_open+0x7f/0x199 [r8169]
|
||||
|
||||
Tested-by: Neal Becker <ndbecker2@gmail.com>
|
||||
Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
|
||||
Acked-by: Eric Dumazet <eric.dumazet@gmail.com>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
drivers/net/r8169.c | 12 ++++++------
|
||||
1 files changed, 6 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
|
||||
index a0da4a1..a68ec8f 100644
|
||||
--- a/drivers/net/r8169.c
|
||||
+++ b/drivers/net/r8169.c
|
||||
@@ -4000,7 +4000,7 @@ static inline void rtl8169_map_to_asic(struct RxDesc *desc, dma_addr_t mapping,
|
||||
static struct sk_buff *rtl8169_alloc_rx_skb(struct pci_dev *pdev,
|
||||
struct net_device *dev,
|
||||
struct RxDesc *desc, int rx_buf_sz,
|
||||
- unsigned int align)
|
||||
+ unsigned int align, gfp_t gfp)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
dma_addr_t mapping;
|
||||
@@ -4008,7 +4008,7 @@ static struct sk_buff *rtl8169_alloc_rx_skb(struct pci_dev *pdev,
|
||||
|
||||
pad = align ? align : NET_IP_ALIGN;
|
||||
|
||||
- skb = netdev_alloc_skb(dev, rx_buf_sz + pad);
|
||||
+ skb = __netdev_alloc_skb(dev, rx_buf_sz + pad, gfp);
|
||||
if (!skb)
|
||||
goto err_out;
|
||||
|
||||
@@ -4039,7 +4039,7 @@ static void rtl8169_rx_clear(struct rtl8169_private *tp)
|
||||
}
|
||||
|
||||
static u32 rtl8169_rx_fill(struct rtl8169_private *tp, struct net_device *dev,
|
||||
- u32 start, u32 end)
|
||||
+ u32 start, u32 end, gfp_t gfp)
|
||||
{
|
||||
u32 cur;
|
||||
|
||||
@@ -4054,7 +4054,7 @@ static u32 rtl8169_rx_fill(struct rtl8169_private *tp, struct net_device *dev,
|
||||
|
||||
skb = rtl8169_alloc_rx_skb(tp->pci_dev, dev,
|
||||
tp->RxDescArray + i,
|
||||
- tp->rx_buf_sz, tp->align);
|
||||
+ tp->rx_buf_sz, tp->align, gfp);
|
||||
if (!skb)
|
||||
break;
|
||||
|
||||
@@ -4082,7 +4082,7 @@ static int rtl8169_init_ring(struct net_device *dev)
|
||||
memset(tp->tx_skb, 0x0, NUM_TX_DESC * sizeof(struct ring_info));
|
||||
memset(tp->Rx_skbuff, 0x0, NUM_RX_DESC * sizeof(struct sk_buff *));
|
||||
|
||||
- if (rtl8169_rx_fill(tp, dev, 0, NUM_RX_DESC) != NUM_RX_DESC)
|
||||
+ if (rtl8169_rx_fill(tp, dev, 0, NUM_RX_DESC, GFP_KERNEL) != NUM_RX_DESC)
|
||||
goto err_out;
|
||||
|
||||
rtl8169_mark_as_last_descriptor(tp->RxDescArray + NUM_RX_DESC - 1);
|
||||
@@ -4583,7 +4583,7 @@ static int rtl8169_rx_interrupt(struct net_device *dev,
|
||||
count = cur_rx - tp->cur_rx;
|
||||
tp->cur_rx = cur_rx;
|
||||
|
||||
- delta = rtl8169_rx_fill(tp, dev, tp->dirty_rx, tp->cur_rx);
|
||||
+ delta = rtl8169_rx_fill(tp, dev, tp->dirty_rx, tp->cur_rx, GFP_ATOMIC);
|
||||
if (!delta && count)
|
||||
netif_info(tp, intr, dev, "no Rx buffer allocated\n");
|
||||
tp->dirty_rx += delta;
|
||||
--
|
||||
1.7.1
|
||||
|
|
@ -0,0 +1,276 @@
|
|||
From: Venkatesh Pallipadi <venki@google.com>
|
||||
Date: Tue, 18 May 2010 01:14:43 +0000 (-0700)
|
||||
Subject: sched: Avoid side-effect of tickless idle on update_cpu_load
|
||||
X-Git-Tag: v2.6.36-rc1~531^2~22
|
||||
X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=fdf3e95d3916f18bf8703fb065499fdbc4dfe34c
|
||||
|
||||
sched: Avoid side-effect of tickless idle on update_cpu_load
|
||||
|
||||
tickless idle has a negative side effect on update_cpu_load(), which
|
||||
in turn can affect load balancing behavior.
|
||||
|
||||
update_cpu_load() is supposed to be called every tick, to keep track
|
||||
of various load indicies. With tickless idle, there are no scheduler
|
||||
ticks called on the idle CPUs. Idle CPUs may still do load balancing
|
||||
(with idle_load_balance CPU) using the stale cpu_load. It will also
|
||||
cause problems when all CPUs go idle for a while and become active
|
||||
again. In this case loads would not degrade as expected.
|
||||
|
||||
This is how rq->nr_load_updates change looks like under different
|
||||
conditions:
|
||||
|
||||
<cpu_num> <nr_load_updates change>
|
||||
All CPUS idle for 10 seconds (HZ=1000)
|
||||
0 1621
|
||||
10 496
|
||||
11 139
|
||||
12 875
|
||||
13 1672
|
||||
14 12
|
||||
15 21
|
||||
1 1472
|
||||
2 2426
|
||||
3 1161
|
||||
4 2108
|
||||
5 1525
|
||||
6 701
|
||||
7 249
|
||||
8 766
|
||||
9 1967
|
||||
|
||||
One CPU busy rest idle for 10 seconds
|
||||
0 10003
|
||||
10 601
|
||||
11 95
|
||||
12 966
|
||||
13 1597
|
||||
14 114
|
||||
15 98
|
||||
1 3457
|
||||
2 93
|
||||
3 6679
|
||||
4 1425
|
||||
5 1479
|
||||
6 595
|
||||
7 193
|
||||
8 633
|
||||
9 1687
|
||||
|
||||
All CPUs busy for 10 seconds
|
||||
0 10026
|
||||
10 10026
|
||||
11 10026
|
||||
12 10026
|
||||
13 10025
|
||||
14 10025
|
||||
15 10025
|
||||
1 10026
|
||||
2 10026
|
||||
3 10026
|
||||
4 10026
|
||||
5 10026
|
||||
6 10026
|
||||
7 10026
|
||||
8 10026
|
||||
9 10026
|
||||
|
||||
That is update_cpu_load works properly only when all CPUs are busy.
|
||||
If all are idle, all the CPUs get way lower updates. And when few
|
||||
CPUs are busy and rest are idle, only busy and ilb CPU does proper
|
||||
updates and rest of the idle CPUs will do lower updates.
|
||||
|
||||
The patch keeps track of when a last update was done and fixes up
|
||||
the load avg based on current time.
|
||||
|
||||
On one of my test system SPECjbb with warehouse 1..numcpus, patch
|
||||
improves throughput numbers by ~1% (average of 6 runs). On another
|
||||
test system (with different domain hierarchy) there is no noticable
|
||||
change in perf.
|
||||
|
||||
Signed-off-by: Venkatesh Pallipadi <venki@google.com>
|
||||
Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
|
||||
Cc: Thomas Gleixner <tglx@linutronix.de>
|
||||
LKML-Reference: <AANLkTilLtDWQsAUrIxJ6s04WTgmw9GuOODc5AOrYsaR5@mail.gmail.com>
|
||||
Signed-off-by: Ingo Molnar <mingo@elte.hu>
|
||||
---
|
||||
|
||||
diff --git a/kernel/sched.c b/kernel/sched.c
|
||||
index f37a961..a757f6b 100644
|
||||
--- a/kernel/sched.c
|
||||
+++ b/kernel/sched.c
|
||||
@@ -457,6 +457,7 @@ struct rq {
|
||||
unsigned long nr_running;
|
||||
#define CPU_LOAD_IDX_MAX 5
|
||||
unsigned long cpu_load[CPU_LOAD_IDX_MAX];
|
||||
+ unsigned long last_load_update_tick;
|
||||
#ifdef CONFIG_NO_HZ
|
||||
u64 nohz_stamp;
|
||||
unsigned char in_nohz_recently;
|
||||
@@ -1803,6 +1804,7 @@ static void cfs_rq_set_shares(struct cfs_rq *cfs_rq, unsigned long shares)
|
||||
static void calc_load_account_idle(struct rq *this_rq);
|
||||
static void update_sysctl(void);
|
||||
static int get_update_sysctl_factor(void);
|
||||
+static void update_cpu_load(struct rq *this_rq);
|
||||
|
||||
static inline void __set_task_cpu(struct task_struct *p, unsigned int cpu)
|
||||
{
|
||||
@@ -3050,23 +3052,102 @@ static void calc_load_account_active(struct rq *this_rq)
|
||||
}
|
||||
|
||||
/*
|
||||
+ * The exact cpuload at various idx values, calculated at every tick would be
|
||||
+ * load = (2^idx - 1) / 2^idx * load + 1 / 2^idx * cur_load
|
||||
+ *
|
||||
+ * If a cpu misses updates for n-1 ticks (as it was idle) and update gets called
|
||||
+ * on nth tick when cpu may be busy, then we have:
|
||||
+ * load = ((2^idx - 1) / 2^idx)^(n-1) * load
|
||||
+ * load = (2^idx - 1) / 2^idx) * load + 1 / 2^idx * cur_load
|
||||
+ *
|
||||
+ * decay_load_missed() below does efficient calculation of
|
||||
+ * load = ((2^idx - 1) / 2^idx)^(n-1) * load
|
||||
+ * avoiding 0..n-1 loop doing load = ((2^idx - 1) / 2^idx) * load
|
||||
+ *
|
||||
+ * The calculation is approximated on a 128 point scale.
|
||||
+ * degrade_zero_ticks is the number of ticks after which load at any
|
||||
+ * particular idx is approximated to be zero.
|
||||
+ * degrade_factor is a precomputed table, a row for each load idx.
|
||||
+ * Each column corresponds to degradation factor for a power of two ticks,
|
||||
+ * based on 128 point scale.
|
||||
+ * Example:
|
||||
+ * row 2, col 3 (=12) says that the degradation at load idx 2 after
|
||||
+ * 8 ticks is 12/128 (which is an approximation of exact factor 3^8/4^8).
|
||||
+ *
|
||||
+ * With this power of 2 load factors, we can degrade the load n times
|
||||
+ * by looking at 1 bits in n and doing as many mult/shift instead of
|
||||
+ * n mult/shifts needed by the exact degradation.
|
||||
+ */
|
||||
+#define DEGRADE_SHIFT 7
|
||||
+static const unsigned char
|
||||
+ degrade_zero_ticks[CPU_LOAD_IDX_MAX] = {0, 8, 32, 64, 128};
|
||||
+static const unsigned char
|
||||
+ degrade_factor[CPU_LOAD_IDX_MAX][DEGRADE_SHIFT + 1] = {
|
||||
+ {0, 0, 0, 0, 0, 0, 0, 0},
|
||||
+ {64, 32, 8, 0, 0, 0, 0, 0},
|
||||
+ {96, 72, 40, 12, 1, 0, 0},
|
||||
+ {112, 98, 75, 43, 15, 1, 0},
|
||||
+ {120, 112, 98, 76, 45, 16, 2} };
|
||||
+
|
||||
+/*
|
||||
+ * Update cpu_load for any missed ticks, due to tickless idle. The backlog
|
||||
+ * would be when CPU is idle and so we just decay the old load without
|
||||
+ * adding any new load.
|
||||
+ */
|
||||
+static unsigned long
|
||||
+decay_load_missed(unsigned long load, unsigned long missed_updates, int idx)
|
||||
+{
|
||||
+ int j = 0;
|
||||
+
|
||||
+ if (!missed_updates)
|
||||
+ return load;
|
||||
+
|
||||
+ if (missed_updates >= degrade_zero_ticks[idx])
|
||||
+ return 0;
|
||||
+
|
||||
+ if (idx == 1)
|
||||
+ return load >> missed_updates;
|
||||
+
|
||||
+ while (missed_updates) {
|
||||
+ if (missed_updates % 2)
|
||||
+ load = (load * degrade_factor[idx][j]) >> DEGRADE_SHIFT;
|
||||
+
|
||||
+ missed_updates >>= 1;
|
||||
+ j++;
|
||||
+ }
|
||||
+ return load;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
* Update rq->cpu_load[] statistics. This function is usually called every
|
||||
- * scheduler tick (TICK_NSEC).
|
||||
+ * scheduler tick (TICK_NSEC). With tickless idle this will not be called
|
||||
+ * every tick. We fix it up based on jiffies.
|
||||
*/
|
||||
static void update_cpu_load(struct rq *this_rq)
|
||||
{
|
||||
unsigned long this_load = this_rq->load.weight;
|
||||
+ unsigned long curr_jiffies = jiffies;
|
||||
+ unsigned long pending_updates;
|
||||
int i, scale;
|
||||
|
||||
this_rq->nr_load_updates++;
|
||||
|
||||
+ /* Avoid repeated calls on same jiffy, when moving in and out of idle */
|
||||
+ if (curr_jiffies == this_rq->last_load_update_tick)
|
||||
+ return;
|
||||
+
|
||||
+ pending_updates = curr_jiffies - this_rq->last_load_update_tick;
|
||||
+ this_rq->last_load_update_tick = curr_jiffies;
|
||||
+
|
||||
/* Update our load: */
|
||||
- for (i = 0, scale = 1; i < CPU_LOAD_IDX_MAX; i++, scale += scale) {
|
||||
+ this_rq->cpu_load[0] = this_load; /* Fasttrack for idx 0 */
|
||||
+ for (i = 1, scale = 2; i < CPU_LOAD_IDX_MAX; i++, scale += scale) {
|
||||
unsigned long old_load, new_load;
|
||||
|
||||
/* scale is effectively 1 << i now, and >> i divides by scale */
|
||||
|
||||
old_load = this_rq->cpu_load[i];
|
||||
+ old_load = decay_load_missed(old_load, pending_updates - 1, i);
|
||||
new_load = this_load;
|
||||
/*
|
||||
* Round up the averaging division if load is increasing. This
|
||||
@@ -3074,9 +3155,15 @@ static void update_cpu_load(struct rq *this_rq)
|
||||
* example.
|
||||
*/
|
||||
if (new_load > old_load)
|
||||
- new_load += scale-1;
|
||||
- this_rq->cpu_load[i] = (old_load*(scale-1) + new_load) >> i;
|
||||
+ new_load += scale - 1;
|
||||
+
|
||||
+ this_rq->cpu_load[i] = (old_load * (scale - 1) + new_load) >> i;
|
||||
}
|
||||
+}
|
||||
+
|
||||
+static void update_cpu_load_active(struct rq *this_rq)
|
||||
+{
|
||||
+ update_cpu_load(this_rq);
|
||||
|
||||
calc_load_account_active(this_rq);
|
||||
}
|
||||
@@ -3464,7 +3551,7 @@ void scheduler_tick(void)
|
||||
|
||||
raw_spin_lock(&rq->lock);
|
||||
update_rq_clock(rq);
|
||||
- update_cpu_load(rq);
|
||||
+ update_cpu_load_active(rq);
|
||||
curr->sched_class->task_tick(rq, curr, 0);
|
||||
raw_spin_unlock(&rq->lock);
|
||||
|
||||
@@ -7688,6 +7775,9 @@ void __init sched_init(void)
|
||||
|
||||
for (j = 0; j < CPU_LOAD_IDX_MAX; j++)
|
||||
rq->cpu_load[j] = 0;
|
||||
+
|
||||
+ rq->last_load_update_tick = jiffies;
|
||||
+
|
||||
#ifdef CONFIG_SMP
|
||||
rq->sd = NULL;
|
||||
rq->rd = NULL;
|
||||
diff --git a/kernel/sched_fair.c b/kernel/sched_fair.c
|
||||
index eed35ed..22b8b4f 100644
|
||||
--- a/kernel/sched_fair.c
|
||||
+++ b/kernel/sched_fair.c
|
||||
@@ -3420,9 +3420,12 @@ static void run_rebalance_domains(struct softirq_action *h)
|
||||
if (need_resched())
|
||||
break;
|
||||
|
||||
+ rq = cpu_rq(balance_cpu);
|
||||
+ raw_spin_lock_irq(&rq->lock);
|
||||
+ update_cpu_load(rq);
|
||||
+ raw_spin_unlock_irq(&rq->lock);
|
||||
rebalance_domains(balance_cpu, CPU_IDLE);
|
||||
|
||||
- rq = cpu_rq(balance_cpu);
|
||||
if (time_after(this_rq->next_balance, rq->next_balance))
|
||||
this_rq->next_balance = rq->next_balance;
|
||||
}
|
|
@ -0,0 +1,651 @@
|
|||
From: Venkatesh Pallipadi <venki@google.com>
|
||||
Date: Sat, 22 May 2010 00:09:41 +0000 (-0700)
|
||||
Subject: sched: Change nohz idle load balancing logic to push model
|
||||
X-Git-Tag: v2.6.36-rc1~531^2~21
|
||||
X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=83cd4fe27ad8446619b2e030b171b858501de87d
|
||||
|
||||
sched: Change nohz idle load balancing logic to push model
|
||||
|
||||
In the new push model, all idle CPUs indeed go into nohz mode. There is
|
||||
still the concept of idle load balancer (performing the load balancing
|
||||
on behalf of all the idle cpu's in the system). Busy CPU kicks the nohz
|
||||
balancer when any of the nohz CPUs need idle load balancing.
|
||||
The kickee CPU does the idle load balancing on behalf of all idle CPUs
|
||||
instead of the normal idle balance.
|
||||
|
||||
This addresses the below two problems with the current nohz ilb logic:
|
||||
* the idle load balancer continued to have periodic ticks during idle and
|
||||
wokeup frequently, even though it did not have any rebalancing to do on
|
||||
behalf of any of the idle CPUs.
|
||||
* On x86 and CPUs that have APIC timer stoppage on idle CPUs, this
|
||||
periodic wakeup can result in a periodic additional interrupt on a CPU
|
||||
doing the timer broadcast.
|
||||
|
||||
Also currently we are migrating the unpinned timers from an idle to the cpu
|
||||
doing idle load balancing (when all the cpus in the system are idle,
|
||||
there is no idle load balancing cpu and timers get added to the same idle cpu
|
||||
where the request was made. So the existing optimization works only on semi idle
|
||||
system).
|
||||
|
||||
And In semi idle system, we no longer have periodic ticks on the idle load
|
||||
balancer CPU. Using that cpu will add more delays to the timers than intended
|
||||
(as that cpu's timer base may not be uptodate wrt jiffies etc). This was
|
||||
causing mysterious slowdowns during boot etc.
|
||||
|
||||
For now, in the semi idle case, use the nearest busy cpu for migrating timers
|
||||
from an idle cpu. This is good for power-savings anyway.
|
||||
|
||||
Signed-off-by: Venkatesh Pallipadi <venki@google.com>
|
||||
Signed-off-by: Suresh Siddha <suresh.b.siddha@intel.com>
|
||||
Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
|
||||
Cc: Thomas Gleixner <tglx@linutronix.de>
|
||||
LKML-Reference: <1274486981.2840.46.camel@sbs-t61.sc.intel.com>
|
||||
Signed-off-by: Ingo Molnar <mingo@elte.hu>
|
||||
---
|
||||
|
||||
[ backported for 2.6.35 ]
|
||||
|
||||
diff --git a/include/linux/sched.h b/include/linux/sched.h
|
||||
index c2d4316..a3e5b1c 100644
|
||||
--- a/include/linux/sched.h
|
||||
+++ b/include/linux/sched.h
|
||||
@@ -271,13 +271,10 @@ extern int runqueue_is_locked(int cpu);
|
||||
|
||||
extern cpumask_var_t nohz_cpu_mask;
|
||||
#if defined(CONFIG_SMP) && defined(CONFIG_NO_HZ)
|
||||
-extern int select_nohz_load_balancer(int cpu);
|
||||
-extern int get_nohz_load_balancer(void);
|
||||
+extern void select_nohz_load_balancer(int stop_tick);
|
||||
+extern int get_nohz_timer_target(void);
|
||||
#else
|
||||
-static inline int select_nohz_load_balancer(int cpu)
|
||||
-{
|
||||
- return 0;
|
||||
-}
|
||||
+static inline void select_nohz_load_balancer(int stop_tick) { }
|
||||
#endif
|
||||
|
||||
/*
|
||||
diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c
|
||||
index 5c69e99..e934339 100644
|
||||
--- a/kernel/hrtimer.c
|
||||
+++ b/kernel/hrtimer.c
|
||||
@@ -144,12 +144,8 @@ struct hrtimer_clock_base *lock_hrtimer_base(const struct hrtimer *timer,
|
||||
static int hrtimer_get_target(int this_cpu, int pinned)
|
||||
{
|
||||
#ifdef CONFIG_NO_HZ
|
||||
- if (!pinned && get_sysctl_timer_migration() && idle_cpu(this_cpu)) {
|
||||
- int preferred_cpu = get_nohz_load_balancer();
|
||||
-
|
||||
- if (preferred_cpu >= 0)
|
||||
- return preferred_cpu;
|
||||
- }
|
||||
+ if (!pinned && get_sysctl_timer_migration() && idle_cpu(this_cpu))
|
||||
+ return get_nohz_timer_target();
|
||||
#endif
|
||||
return this_cpu;
|
||||
}
|
||||
diff --git a/kernel/sched.c b/kernel/sched.c
|
||||
index a757f6b..132950b 100644
|
||||
--- a/kernel/sched.c
|
||||
+++ b/kernel/sched.c
|
||||
@@ -460,7 +460,7 @@ struct rq {
|
||||
unsigned long last_load_update_tick;
|
||||
#ifdef CONFIG_NO_HZ
|
||||
u64 nohz_stamp;
|
||||
- unsigned char in_nohz_recently;
|
||||
+ unsigned char nohz_balance_kick;
|
||||
#endif
|
||||
unsigned int skip_clock_update;
|
||||
|
||||
@@ -1195,6 +1195,27 @@ static void resched_cpu(int cpu)
|
||||
|
||||
#ifdef CONFIG_NO_HZ
|
||||
/*
|
||||
+ * In the semi idle case, use the nearest busy cpu for migrating timers
|
||||
+ * from an idle cpu. This is good for power-savings.
|
||||
+ *
|
||||
+ * We don't do similar optimization for completely idle system, as
|
||||
+ * selecting an idle cpu will add more delays to the timers than intended
|
||||
+ * (as that cpu's timer base may not be uptodate wrt jiffies etc).
|
||||
+ */
|
||||
+int get_nohz_timer_target(void)
|
||||
+{
|
||||
+ int cpu = smp_processor_id();
|
||||
+ int i;
|
||||
+ struct sched_domain *sd;
|
||||
+
|
||||
+ for_each_domain(cpu, sd) {
|
||||
+ for_each_cpu(i, sched_domain_span(sd))
|
||||
+ if (!idle_cpu(i))
|
||||
+ return i;
|
||||
+ }
|
||||
+ return cpu;
|
||||
+}
|
||||
+/*
|
||||
* When add_timer_on() enqueues a timer into the timer wheel of an
|
||||
* idle CPU then this timer might expire before the next timer event
|
||||
* which is scheduled to wake up that CPU. In case of a completely
|
||||
@@ -7791,6 +7812,10 @@ void __init sched_init(void)
|
||||
rq->idle_stamp = 0;
|
||||
rq->avg_idle = 2*sysctl_sched_migration_cost;
|
||||
rq_attach_root(rq, &def_root_domain);
|
||||
+#ifdef CONFIG_NO_HZ
|
||||
+ rq->nohz_balance_kick = 0;
|
||||
+ init_sched_softirq_csd(&per_cpu(remote_sched_softirq_cb, i));
|
||||
+#endif
|
||||
#endif
|
||||
init_rq_hrtick(rq);
|
||||
atomic_set(&rq->nr_iowait, 0);
|
||||
@@ -7835,8 +7860,11 @@ void __init sched_init(void)
|
||||
zalloc_cpumask_var(&nohz_cpu_mask, GFP_NOWAIT);
|
||||
#ifdef CONFIG_SMP
|
||||
#ifdef CONFIG_NO_HZ
|
||||
- zalloc_cpumask_var(&nohz.cpu_mask, GFP_NOWAIT);
|
||||
- alloc_cpumask_var(&nohz.ilb_grp_nohz_mask, GFP_NOWAIT);
|
||||
+ zalloc_cpumask_var(&nohz.idle_cpus_mask, GFP_NOWAIT);
|
||||
+ alloc_cpumask_var(&nohz.grp_idle_mask, GFP_NOWAIT);
|
||||
+ atomic_set(&nohz.load_balancer, nr_cpu_ids);
|
||||
+ atomic_set(&nohz.first_pick_cpu, nr_cpu_ids);
|
||||
+ atomic_set(&nohz.second_pick_cpu, nr_cpu_ids);
|
||||
#endif
|
||||
/* May be allocated at isolcpus cmdline parse time */
|
||||
if (cpu_isolated_map == NULL)
|
||||
diff --git a/kernel/sched_fair.c b/kernel/sched_fair.c
|
||||
index 22b8b4f..6ee2e0a 100644
|
||||
--- a/kernel/sched_fair.c
|
||||
+++ b/kernel/sched_fair.c
|
||||
@@ -3091,13 +3091,40 @@ out_unlock:
|
||||
}
|
||||
|
||||
#ifdef CONFIG_NO_HZ
|
||||
+
|
||||
+static DEFINE_PER_CPU(struct call_single_data, remote_sched_softirq_cb);
|
||||
+
|
||||
+static void trigger_sched_softirq(void *data)
|
||||
+{
|
||||
+ raise_softirq_irqoff(SCHED_SOFTIRQ);
|
||||
+}
|
||||
+
|
||||
+static inline void init_sched_softirq_csd(struct call_single_data *csd)
|
||||
+{
|
||||
+ csd->func = trigger_sched_softirq;
|
||||
+ csd->info = NULL;
|
||||
+ csd->flags = 0;
|
||||
+ csd->priv = 0;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * idle load balancing details
|
||||
+ * - One of the idle CPUs nominates itself as idle load_balancer, while
|
||||
+ * entering idle.
|
||||
+ * - This idle load balancer CPU will also go into tickless mode when
|
||||
+ * it is idle, just like all other idle CPUs
|
||||
+ * - When one of the busy CPUs notice that there may be an idle rebalancing
|
||||
+ * needed, they will kick the idle load balancer, which then does idle
|
||||
+ * load balancing for all the idle CPUs.
|
||||
+ */
|
||||
static struct {
|
||||
atomic_t load_balancer;
|
||||
- cpumask_var_t cpu_mask;
|
||||
- cpumask_var_t ilb_grp_nohz_mask;
|
||||
-} nohz ____cacheline_aligned = {
|
||||
- .load_balancer = ATOMIC_INIT(-1),
|
||||
-};
|
||||
+ atomic_t first_pick_cpu;
|
||||
+ atomic_t second_pick_cpu;
|
||||
+ cpumask_var_t idle_cpus_mask;
|
||||
+ cpumask_var_t grp_idle_mask;
|
||||
+ unsigned long next_balance; /* in jiffy units */
|
||||
+} nohz ____cacheline_aligned;
|
||||
|
||||
int get_nohz_load_balancer(void)
|
||||
{
|
||||
@@ -3151,17 +3178,17 @@ static inline struct sched_domain *lowest_flag_domain(int cpu, int flag)
|
||||
*/
|
||||
static inline int is_semi_idle_group(struct sched_group *ilb_group)
|
||||
{
|
||||
- cpumask_and(nohz.ilb_grp_nohz_mask, nohz.cpu_mask,
|
||||
+ cpumask_and(nohz.grp_idle_mask, nohz.idle_cpus_mask,
|
||||
sched_group_cpus(ilb_group));
|
||||
|
||||
/*
|
||||
* A sched_group is semi-idle when it has atleast one busy cpu
|
||||
* and atleast one idle cpu.
|
||||
*/
|
||||
- if (cpumask_empty(nohz.ilb_grp_nohz_mask))
|
||||
+ if (cpumask_empty(nohz.grp_idle_mask))
|
||||
return 0;
|
||||
|
||||
- if (cpumask_equal(nohz.ilb_grp_nohz_mask, sched_group_cpus(ilb_group)))
|
||||
+ if (cpumask_equal(nohz.grp_idle_mask, sched_group_cpus(ilb_group)))
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
@@ -3194,7 +3221,7 @@ static int find_new_ilb(int cpu)
|
||||
* Optimize for the case when we have no idle CPUs or only one
|
||||
* idle CPU. Don't walk the sched_domain hierarchy in such cases
|
||||
*/
|
||||
- if (cpumask_weight(nohz.cpu_mask) < 2)
|
||||
+ if (cpumask_weight(nohz.idle_cpus_mask) < 2)
|
||||
goto out_done;
|
||||
|
||||
for_each_flag_domain(cpu, sd, SD_POWERSAVINGS_BALANCE) {
|
||||
@@ -3202,7 +3229,7 @@ static int find_new_ilb(int cpu)
|
||||
|
||||
do {
|
||||
if (is_semi_idle_group(ilb_group))
|
||||
- return cpumask_first(nohz.ilb_grp_nohz_mask);
|
||||
+ return cpumask_first(nohz.grp_idle_mask);
|
||||
|
||||
ilb_group = ilb_group->next;
|
||||
|
||||
@@ -3210,98 +3237,116 @@ static int find_new_ilb(int cpu)
|
||||
}
|
||||
|
||||
out_done:
|
||||
- return cpumask_first(nohz.cpu_mask);
|
||||
+ return nr_cpu_ids;
|
||||
}
|
||||
#else /* (CONFIG_SCHED_MC || CONFIG_SCHED_SMT) */
|
||||
static inline int find_new_ilb(int call_cpu)
|
||||
{
|
||||
- return cpumask_first(nohz.cpu_mask);
|
||||
+ return nr_cpu_ids;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
+ * Kick a CPU to do the nohz balancing, if it is time for it. We pick the
|
||||
+ * nohz_load_balancer CPU (if there is one) otherwise fallback to any idle
|
||||
+ * CPU (if there is one).
|
||||
+ */
|
||||
+static void nohz_balancer_kick(int cpu)
|
||||
+{
|
||||
+ int ilb_cpu;
|
||||
+
|
||||
+ nohz.next_balance++;
|
||||
+
|
||||
+ ilb_cpu = get_nohz_load_balancer();
|
||||
+
|
||||
+ if (ilb_cpu >= nr_cpu_ids) {
|
||||
+ ilb_cpu = cpumask_first(nohz.idle_cpus_mask);
|
||||
+ if (ilb_cpu >= nr_cpu_ids)
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ if (!cpu_rq(ilb_cpu)->nohz_balance_kick) {
|
||||
+ struct call_single_data *cp;
|
||||
+
|
||||
+ cpu_rq(ilb_cpu)->nohz_balance_kick = 1;
|
||||
+ cp = &per_cpu(remote_sched_softirq_cb, cpu);
|
||||
+ __smp_call_function_single(ilb_cpu, cp, 0);
|
||||
+ }
|
||||
+ return;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
* This routine will try to nominate the ilb (idle load balancing)
|
||||
* owner among the cpus whose ticks are stopped. ilb owner will do the idle
|
||||
- * load balancing on behalf of all those cpus. If all the cpus in the system
|
||||
- * go into this tickless mode, then there will be no ilb owner (as there is
|
||||
- * no need for one) and all the cpus will sleep till the next wakeup event
|
||||
- * arrives...
|
||||
- *
|
||||
- * For the ilb owner, tick is not stopped. And this tick will be used
|
||||
- * for idle load balancing. ilb owner will still be part of
|
||||
- * nohz.cpu_mask..
|
||||
+ * load balancing on behalf of all those cpus.
|
||||
*
|
||||
- * While stopping the tick, this cpu will become the ilb owner if there
|
||||
- * is no other owner. And will be the owner till that cpu becomes busy
|
||||
- * or if all cpus in the system stop their ticks at which point
|
||||
- * there is no need for ilb owner.
|
||||
+ * When the ilb owner becomes busy, we will not have new ilb owner until some
|
||||
+ * idle CPU wakes up and goes back to idle or some busy CPU tries to kick
|
||||
+ * idle load balancing by kicking one of the idle CPUs.
|
||||
*
|
||||
- * When the ilb owner becomes busy, it nominates another owner, during the
|
||||
- * next busy scheduler_tick()
|
||||
+ * Ticks are stopped for the ilb owner as well, with busy CPU kicking this
|
||||
+ * ilb owner CPU in future (when there is a need for idle load balancing on
|
||||
+ * behalf of all idle CPUs).
|
||||
*/
|
||||
-int select_nohz_load_balancer(int stop_tick)
|
||||
+void select_nohz_load_balancer(int stop_tick)
|
||||
{
|
||||
int cpu = smp_processor_id();
|
||||
|
||||
if (stop_tick) {
|
||||
- cpu_rq(cpu)->in_nohz_recently = 1;
|
||||
-
|
||||
if (!cpu_active(cpu)) {
|
||||
if (atomic_read(&nohz.load_balancer) != cpu)
|
||||
- return 0;
|
||||
+ return;
|
||||
|
||||
/*
|
||||
* If we are going offline and still the leader,
|
||||
* give up!
|
||||
*/
|
||||
- if (atomic_cmpxchg(&nohz.load_balancer, cpu, -1) != cpu)
|
||||
+ if (atomic_cmpxchg(&nohz.load_balancer, cpu,
|
||||
+ nr_cpu_ids) != cpu)
|
||||
BUG();
|
||||
|
||||
- return 0;
|
||||
+ return;
|
||||
}
|
||||
|
||||
- cpumask_set_cpu(cpu, nohz.cpu_mask);
|
||||
+ cpumask_set_cpu(cpu, nohz.idle_cpus_mask);
|
||||
|
||||
- /* time for ilb owner also to sleep */
|
||||
- if (cpumask_weight(nohz.cpu_mask) == num_active_cpus()) {
|
||||
- if (atomic_read(&nohz.load_balancer) == cpu)
|
||||
- atomic_set(&nohz.load_balancer, -1);
|
||||
- return 0;
|
||||
- }
|
||||
+ if (atomic_read(&nohz.first_pick_cpu) == cpu)
|
||||
+ atomic_cmpxchg(&nohz.first_pick_cpu, cpu, nr_cpu_ids);
|
||||
+ if (atomic_read(&nohz.second_pick_cpu) == cpu)
|
||||
+ atomic_cmpxchg(&nohz.second_pick_cpu, cpu, nr_cpu_ids);
|
||||
|
||||
- if (atomic_read(&nohz.load_balancer) == -1) {
|
||||
- /* make me the ilb owner */
|
||||
- if (atomic_cmpxchg(&nohz.load_balancer, -1, cpu) == -1)
|
||||
- return 1;
|
||||
- } else if (atomic_read(&nohz.load_balancer) == cpu) {
|
||||
+ if (atomic_read(&nohz.load_balancer) >= nr_cpu_ids) {
|
||||
int new_ilb;
|
||||
|
||||
- if (!(sched_smt_power_savings ||
|
||||
- sched_mc_power_savings))
|
||||
- return 1;
|
||||
+ /* make me the ilb owner */
|
||||
+ if (atomic_cmpxchg(&nohz.load_balancer, nr_cpu_ids,
|
||||
+ cpu) != nr_cpu_ids)
|
||||
+ return;
|
||||
+
|
||||
/*
|
||||
* Check to see if there is a more power-efficient
|
||||
* ilb.
|
||||
*/
|
||||
new_ilb = find_new_ilb(cpu);
|
||||
if (new_ilb < nr_cpu_ids && new_ilb != cpu) {
|
||||
- atomic_set(&nohz.load_balancer, -1);
|
||||
+ atomic_set(&nohz.load_balancer, nr_cpu_ids);
|
||||
resched_cpu(new_ilb);
|
||||
- return 0;
|
||||
+ return;
|
||||
}
|
||||
- return 1;
|
||||
+ return;
|
||||
}
|
||||
} else {
|
||||
- if (!cpumask_test_cpu(cpu, nohz.cpu_mask))
|
||||
- return 0;
|
||||
+ if (!cpumask_test_cpu(cpu, nohz.idle_cpus_mask))
|
||||
+ return;
|
||||
|
||||
- cpumask_clear_cpu(cpu, nohz.cpu_mask);
|
||||
+ cpumask_clear_cpu(cpu, nohz.idle_cpus_mask);
|
||||
|
||||
if (atomic_read(&nohz.load_balancer) == cpu)
|
||||
- if (atomic_cmpxchg(&nohz.load_balancer, cpu, -1) != cpu)
|
||||
+ if (atomic_cmpxchg(&nohz.load_balancer, cpu,
|
||||
+ nr_cpu_ids) != cpu)
|
||||
BUG();
|
||||
}
|
||||
- return 0;
|
||||
+ return;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -3383,11 +3428,101 @@ out:
|
||||
rq->next_balance = next_balance;
|
||||
}
|
||||
|
||||
+#ifdef CONFIG_NO_HZ
|
||||
/*
|
||||
- * run_rebalance_domains is triggered when needed from the scheduler tick.
|
||||
- * In CONFIG_NO_HZ case, the idle load balance owner will do the
|
||||
+ * In CONFIG_NO_HZ case, the idle balance kickee will do the
|
||||
* rebalancing for all the cpus for whom scheduler ticks are stopped.
|
||||
*/
|
||||
+static void nohz_idle_balance(int this_cpu, enum cpu_idle_type idle)
|
||||
+{
|
||||
+ struct rq *this_rq = cpu_rq(this_cpu);
|
||||
+ struct rq *rq;
|
||||
+ int balance_cpu;
|
||||
+
|
||||
+ if (idle != CPU_IDLE || !this_rq->nohz_balance_kick)
|
||||
+ return;
|
||||
+
|
||||
+ for_each_cpu(balance_cpu, nohz.idle_cpus_mask) {
|
||||
+ if (balance_cpu == this_cpu)
|
||||
+ continue;
|
||||
+
|
||||
+ /*
|
||||
+ * If this cpu gets work to do, stop the load balancing
|
||||
+ * work being done for other cpus. Next load
|
||||
+ * balancing owner will pick it up.
|
||||
+ */
|
||||
+ if (need_resched()) {
|
||||
+ this_rq->nohz_balance_kick = 0;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ raw_spin_lock_irq(&this_rq->lock);
|
||||
+ update_cpu_load(this_rq);
|
||||
+ raw_spin_unlock_irq(&this_rq->lock);
|
||||
+
|
||||
+ rebalance_domains(balance_cpu, CPU_IDLE);
|
||||
+
|
||||
+ rq = cpu_rq(balance_cpu);
|
||||
+ if (time_after(this_rq->next_balance, rq->next_balance))
|
||||
+ this_rq->next_balance = rq->next_balance;
|
||||
+ }
|
||||
+ nohz.next_balance = this_rq->next_balance;
|
||||
+ this_rq->nohz_balance_kick = 0;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * Current heuristic for kicking the idle load balancer
|
||||
+ * - first_pick_cpu is the one of the busy CPUs. It will kick
|
||||
+ * idle load balancer when it has more than one process active. This
|
||||
+ * eliminates the need for idle load balancing altogether when we have
|
||||
+ * only one running process in the system (common case).
|
||||
+ * - If there are more than one busy CPU, idle load balancer may have
|
||||
+ * to run for active_load_balance to happen (i.e., two busy CPUs are
|
||||
+ * SMT or core siblings and can run better if they move to different
|
||||
+ * physical CPUs). So, second_pick_cpu is the second of the busy CPUs
|
||||
+ * which will kick idle load balancer as soon as it has any load.
|
||||
+ */
|
||||
+static inline int nohz_kick_needed(struct rq *rq, int cpu)
|
||||
+{
|
||||
+ unsigned long now = jiffies;
|
||||
+ int ret;
|
||||
+ int first_pick_cpu, second_pick_cpu;
|
||||
+
|
||||
+ if (time_before(now, nohz.next_balance))
|
||||
+ return 0;
|
||||
+
|
||||
+ if (!rq->nr_running)
|
||||
+ return 0;
|
||||
+
|
||||
+ first_pick_cpu = atomic_read(&nohz.first_pick_cpu);
|
||||
+ second_pick_cpu = atomic_read(&nohz.second_pick_cpu);
|
||||
+
|
||||
+ if (first_pick_cpu < nr_cpu_ids && first_pick_cpu != cpu &&
|
||||
+ second_pick_cpu < nr_cpu_ids && second_pick_cpu != cpu)
|
||||
+ return 0;
|
||||
+
|
||||
+ ret = atomic_cmpxchg(&nohz.first_pick_cpu, nr_cpu_ids, cpu);
|
||||
+ if (ret == nr_cpu_ids || ret == cpu) {
|
||||
+ atomic_cmpxchg(&nohz.second_pick_cpu, cpu, nr_cpu_ids);
|
||||
+ if (rq->nr_running > 1)
|
||||
+ return 1;
|
||||
+ } else {
|
||||
+ ret = atomic_cmpxchg(&nohz.second_pick_cpu, nr_cpu_ids, cpu);
|
||||
+ if (ret == nr_cpu_ids || ret == cpu) {
|
||||
+ if (rq->nr_running)
|
||||
+ return 1;
|
||||
+ }
|
||||
+ }
|
||||
+ return 0;
|
||||
+}
|
||||
+#else
|
||||
+static void nohz_idle_balance(int this_cpu, enum cpu_idle_type idle) { }
|
||||
+#endif
|
||||
+
|
||||
+/*
|
||||
+ * run_rebalance_domains is triggered when needed from the scheduler tick.
|
||||
+ * Also triggered for nohz idle balancing (with nohz_balancing_kick set).
|
||||
+ */
|
||||
static void run_rebalance_domains(struct softirq_action *h)
|
||||
{
|
||||
int this_cpu = smp_processor_id();
|
||||
@@ -3397,40 +3532,12 @@ static void run_rebalance_domains(struct softirq_action *h)
|
||||
|
||||
rebalance_domains(this_cpu, idle);
|
||||
|
||||
-#ifdef CONFIG_NO_HZ
|
||||
/*
|
||||
- * If this cpu is the owner for idle load balancing, then do the
|
||||
+ * If this cpu has a pending nohz_balance_kick, then do the
|
||||
* balancing on behalf of the other idle cpus whose ticks are
|
||||
* stopped.
|
||||
*/
|
||||
- if (this_rq->idle_at_tick &&
|
||||
- atomic_read(&nohz.load_balancer) == this_cpu) {
|
||||
- struct rq *rq;
|
||||
- int balance_cpu;
|
||||
-
|
||||
- for_each_cpu(balance_cpu, nohz.cpu_mask) {
|
||||
- if (balance_cpu == this_cpu)
|
||||
- continue;
|
||||
-
|
||||
- /*
|
||||
- * If this cpu gets work to do, stop the load balancing
|
||||
- * work being done for other cpus. Next load
|
||||
- * balancing owner will pick it up.
|
||||
- */
|
||||
- if (need_resched())
|
||||
- break;
|
||||
-
|
||||
- rq = cpu_rq(balance_cpu);
|
||||
- raw_spin_lock_irq(&rq->lock);
|
||||
- update_cpu_load(rq);
|
||||
- raw_spin_unlock_irq(&rq->lock);
|
||||
- rebalance_domains(balance_cpu, CPU_IDLE);
|
||||
-
|
||||
- if (time_after(this_rq->next_balance, rq->next_balance))
|
||||
- this_rq->next_balance = rq->next_balance;
|
||||
- }
|
||||
- }
|
||||
-#endif
|
||||
+ nohz_idle_balance(this_cpu, idle);
|
||||
}
|
||||
|
||||
static inline int on_null_domain(int cpu)
|
||||
@@ -3440,57 +3547,17 @@ static inline int on_null_domain(int cpu)
|
||||
|
||||
/*
|
||||
* Trigger the SCHED_SOFTIRQ if it is time to do periodic load balancing.
|
||||
- *
|
||||
- * In case of CONFIG_NO_HZ, this is the place where we nominate a new
|
||||
- * idle load balancing owner or decide to stop the periodic load balancing,
|
||||
- * if the whole system is idle.
|
||||
*/
|
||||
static inline void trigger_load_balance(struct rq *rq, int cpu)
|
||||
{
|
||||
-#ifdef CONFIG_NO_HZ
|
||||
- /*
|
||||
- * If we were in the nohz mode recently and busy at the current
|
||||
- * scheduler tick, then check if we need to nominate new idle
|
||||
- * load balancer.
|
||||
- */
|
||||
- if (rq->in_nohz_recently && !rq->idle_at_tick) {
|
||||
- rq->in_nohz_recently = 0;
|
||||
-
|
||||
- if (atomic_read(&nohz.load_balancer) == cpu) {
|
||||
- cpumask_clear_cpu(cpu, nohz.cpu_mask);
|
||||
- atomic_set(&nohz.load_balancer, -1);
|
||||
- }
|
||||
-
|
||||
- if (atomic_read(&nohz.load_balancer) == -1) {
|
||||
- int ilb = find_new_ilb(cpu);
|
||||
-
|
||||
- if (ilb < nr_cpu_ids)
|
||||
- resched_cpu(ilb);
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- /*
|
||||
- * If this cpu is idle and doing idle load balancing for all the
|
||||
- * cpus with ticks stopped, is it time for that to stop?
|
||||
- */
|
||||
- if (rq->idle_at_tick && atomic_read(&nohz.load_balancer) == cpu &&
|
||||
- cpumask_weight(nohz.cpu_mask) == num_online_cpus()) {
|
||||
- resched_cpu(cpu);
|
||||
- return;
|
||||
- }
|
||||
-
|
||||
- /*
|
||||
- * If this cpu is idle and the idle load balancing is done by
|
||||
- * someone else, then no need raise the SCHED_SOFTIRQ
|
||||
- */
|
||||
- if (rq->idle_at_tick && atomic_read(&nohz.load_balancer) != cpu &&
|
||||
- cpumask_test_cpu(cpu, nohz.cpu_mask))
|
||||
- return;
|
||||
-#endif
|
||||
/* Don't need to rebalance while attached to NULL domain */
|
||||
if (time_after_eq(jiffies, rq->next_balance) &&
|
||||
likely(!on_null_domain(cpu)))
|
||||
raise_softirq(SCHED_SOFTIRQ);
|
||||
+#ifdef CONFIG_NO_HZ
|
||||
+ else if (nohz_kick_needed(rq, cpu) && likely(!on_null_domain(cpu)))
|
||||
+ nohz_balancer_kick(cpu);
|
||||
+#endif
|
||||
}
|
||||
|
||||
static void rq_online_fair(struct rq *rq)
|
||||
diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c
|
||||
index 1d7b9bc..5f171f0 100644
|
||||
--- a/kernel/time/tick-sched.c
|
||||
+++ b/kernel/time/tick-sched.c
|
||||
@@ -408,13 +408,7 @@ void tick_nohz_stop_sched_tick(int inidle)
|
||||
* the scheduler tick in nohz_restart_sched_tick.
|
||||
*/
|
||||
if (!ts->tick_stopped) {
|
||||
- if (select_nohz_load_balancer(1)) {
|
||||
- /*
|
||||
- * sched tick not stopped!
|
||||
- */
|
||||
- cpumask_clear_cpu(cpu, nohz_cpu_mask);
|
||||
- goto out;
|
||||
- }
|
||||
+ select_nohz_load_balancer(1);
|
||||
|
||||
ts->idle_tick = hrtimer_get_expires(&ts->sched_timer);
|
||||
ts->tick_stopped = 1;
|
||||
diff --git a/kernel/timer.c b/kernel/timer.c
|
||||
index ee305c8..48d6aec 100644
|
||||
--- a/kernel/timer.c
|
||||
+++ b/kernel/timer.c
|
||||
@@ -679,12 +679,8 @@ __mod_timer(struct timer_list *timer, unsigned long expires,
|
||||
cpu = smp_processor_id();
|
||||
|
||||
#if defined(CONFIG_NO_HZ) && defined(CONFIG_SMP)
|
||||
- if (!pinned && get_sysctl_timer_migration() && idle_cpu(cpu)) {
|
||||
- int preferred_cpu = get_nohz_load_balancer();
|
||||
-
|
||||
- if (preferred_cpu >= 0)
|
||||
- cpu = preferred_cpu;
|
||||
- }
|
||||
+ if (!pinned && get_sysctl_timer_migration() && idle_cpu(cpu))
|
||||
+ cpu = get_nohz_timer_target();
|
||||
#endif
|
||||
new_base = per_cpu(tvec_bases, cpu);
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
From: Suresh Siddha <suresh.b.siddha@intel.com>
|
||||
Date: Fri, 9 Jul 2010 13:19:54 +0000 (+0200)
|
||||
Subject: sched: Update rq->clock for nohz balanced cpus
|
||||
X-Git-Tag: v2.6.36-rc1~531^2~5
|
||||
X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=5343bdb8fd076f16edc9d113a9e35e2a1d1f4966
|
||||
|
||||
sched: Update rq->clock for nohz balanced cpus
|
||||
|
||||
Suresh spotted that we don't update the rq->clock in the nohz
|
||||
load-balancer path.
|
||||
|
||||
Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
|
||||
LKML-Reference: <1278626014.2834.74.camel@sbs-t61.sc.intel.com>
|
||||
Signed-off-by: Ingo Molnar <mingo@elte.hu>
|
||||
---
|
||||
|
||||
diff --git a/kernel/sched_fair.c b/kernel/sched_fair.c
|
||||
index b4da534..e44a591 100644
|
||||
--- a/kernel/sched_fair.c
|
||||
+++ b/kernel/sched_fair.c
|
||||
@@ -3596,6 +3596,7 @@ static void nohz_idle_balance(int this_cpu, enum cpu_idle_type idle)
|
||||
}
|
||||
|
||||
raw_spin_lock_irq(&this_rq->lock);
|
||||
+ update_rq_clock(this_rq);
|
||||
update_cpu_load(this_rq);
|
||||
raw_spin_unlock_irq(&this_rq->lock);
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
From: Peter Zijlstra <peterz@infradead.org>
|
||||
Date: Thu, 19 Aug 2010 11:31:43 +0000 (+0200)
|
||||
Subject: sched: Fix rq->clock synchronization when migrating tasks
|
||||
X-Git-Tag: v2.6.36-rc3~25^2~1
|
||||
X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=861d034ee814917a83bd5de4b26e3b8336ddeeb8
|
||||
|
||||
sched: Fix rq->clock synchronization when migrating tasks
|
||||
|
||||
sched_fork() -- we do task placement in ->task_fork_fair() ensure we
|
||||
update_rq_clock() so we work with current time. We leave the vruntime
|
||||
in relative state, so the time delay until wake_up_new_task() doesn't
|
||||
matter.
|
||||
|
||||
wake_up_new_task() -- Since task_fork_fair() left p->vruntime in
|
||||
relative state we can safely migrate, the activate_task() on the
|
||||
remote rq will call update_rq_clock() and causes the clock to be
|
||||
synced (enough).
|
||||
|
||||
Tested-by: Jack Daniel <wanders.thirst@gmail.com>
|
||||
Tested-by: Philby John <pjohn@mvista.com>
|
||||
Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
|
||||
LKML-Reference: <1281002322.1923.1708.camel@laptop>
|
||||
Signed-off-by: Ingo Molnar <mingo@elte.hu>
|
||||
---
|
||||
|
||||
diff --git a/kernel/sched_fair.c b/kernel/sched_fair.c
|
||||
index 806d1b2..ab661eb 100644
|
||||
--- a/kernel/sched_fair.c
|
||||
+++ b/kernel/sched_fair.c
|
||||
@@ -3752,6 +3752,8 @@ static void task_fork_fair(struct task_struct *p)
|
||||
|
||||
raw_spin_lock_irqsave(&rq->lock, flags);
|
||||
|
||||
+ update_rq_clock(rq);
|
||||
+
|
||||
if (unlikely(task_cpu(p) != this_cpu))
|
||||
__set_task_cpu(p, this_cpu);
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
From: Suresh Siddha <suresh.b.siddha@intel.com>
|
||||
Date: Mon, 23 Aug 2010 20:42:51 +0000 (-0700)
|
||||
Subject: sched: Move sched_avg_update() to update_cpu_load()
|
||||
X-Git-Tag: v2.6.36-rc4~8^2~1
|
||||
X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=da2b71edd8a7db44fe1746261410a981f3e03632
|
||||
|
||||
sched: Move sched_avg_update() to update_cpu_load()
|
||||
|
||||
Currently sched_avg_update() (which updates rt_avg stats in the rq)
|
||||
is getting called from scale_rt_power() (in the load balance context)
|
||||
which doesn't take rq->lock.
|
||||
|
||||
Fix it by moving the sched_avg_update() to more appropriate
|
||||
update_cpu_load() where the CFS load gets updated as well.
|
||||
|
||||
Signed-off-by: Suresh Siddha <suresh.b.siddha@intel.com>
|
||||
Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
|
||||
LKML-Reference: <1282596171.2694.3.camel@sbsiddha-MOBL3>
|
||||
Signed-off-by: Ingo Molnar <mingo@elte.hu>
|
||||
---
|
||||
|
||||
diff --git a/kernel/sched.c b/kernel/sched.c
|
||||
index 09b574e..ed09d4f 100644
|
||||
--- a/kernel/sched.c
|
||||
+++ b/kernel/sched.c
|
||||
@@ -1294,6 +1294,10 @@ static void resched_task(struct task_struct *p)
|
||||
static void sched_rt_avg_update(struct rq *rq, u64 rt_delta)
|
||||
{
|
||||
}
|
||||
+
|
||||
+static void sched_avg_update(struct rq *rq)
|
||||
+{
|
||||
+}
|
||||
#endif /* CONFIG_SMP */
|
||||
|
||||
#if BITS_PER_LONG == 32
|
||||
@@ -3182,6 +3186,8 @@ static void update_cpu_load(struct rq *this_rq)
|
||||
|
||||
this_rq->cpu_load[i] = (old_load * (scale - 1) + new_load) >> i;
|
||||
}
|
||||
+
|
||||
+ sched_avg_update(this_rq);
|
||||
}
|
||||
|
||||
static void update_cpu_load_active(struct rq *this_rq)
|
||||
diff --git a/kernel/sched_fair.c b/kernel/sched_fair.c
|
||||
index ab661eb..f53ec75 100644
|
||||
--- a/kernel/sched_fair.c
|
||||
+++ b/kernel/sched_fair.c
|
||||
@@ -2268,8 +2268,6 @@ unsigned long scale_rt_power(int cpu)
|
||||
struct rq *rq = cpu_rq(cpu);
|
||||
u64 total, available;
|
||||
|
||||
- sched_avg_update(rq);
|
||||
-
|
||||
total = sched_avg_period() + (rq->clock - rq->age_stamp);
|
||||
available = total - rq->rt_avg;
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
From: Suresh Siddha <suresh.b.siddha@intel.com>
|
||||
Date: Mon, 13 Sep 2010 18:02:21 +0000 (-0700)
|
||||
Subject: sched: Fix nohz balance kick
|
||||
X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=f6c3f1686e7ec1dd8725a9a3dcb857dfd0c7a5bf
|
||||
|
||||
sched: Fix nohz balance kick
|
||||
|
||||
There's a situation where the nohz balancer will try to wake itself:
|
||||
|
||||
cpu-x is idle which is also ilb_cpu
|
||||
got a scheduler tick during idle
|
||||
and the nohz_kick_needed() in trigger_load_balance() checks for
|
||||
rq_x->nr_running which might not be zero (because of someone waking a
|
||||
task on this rq etc) and this leads to the situation of the cpu-x
|
||||
sending a kick to itself.
|
||||
|
||||
And this can cause a lockup.
|
||||
|
||||
Avoid this by not marking ourself eligible for kicking.
|
||||
|
||||
Signed-off-by: Suresh Siddha <suresh.b.siddha@intel.com>
|
||||
Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
|
||||
LKML-Reference: <1284400941.2684.19.camel@sbsiddha-MOBL3.sc.intel.com>
|
||||
Signed-off-by: Ingo Molnar <mingo@elte.hu>
|
||||
---
|
||||
|
||||
diff --git a/kernel/sched_fair.c b/kernel/sched_fair.c
|
||||
index a171138..db3f674 100644
|
||||
--- a/kernel/sched_fair.c
|
||||
+++ b/kernel/sched_fair.c
|
||||
@@ -3630,7 +3630,7 @@ static inline int nohz_kick_needed(struct rq *rq, int cpu)
|
||||
if (time_before(now, nohz.next_balance))
|
||||
return 0;
|
||||
|
||||
- if (!rq->nr_running)
|
||||
+ if (rq->idle_at_tick)
|
||||
return 0;
|
||||
|
||||
first_pick_cpu = atomic_read(&nohz.first_pick_cpu);
|
|
@ -0,0 +1,93 @@
|
|||
From: Venkatesh Pallipadi <venki@google.com>
|
||||
Date: Sat, 11 Sep 2010 01:19:17 +0000 (-0700)
|
||||
Subject: sched: Increment cache_nice_tries only on periodic lb
|
||||
X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Fmingo%2Flinux-2.6-x86.git;a=commitdiff_plain;h=58b26c4c025778c09c7a1438ff185080e11b7d0a
|
||||
|
||||
sched: Increment cache_nice_tries only on periodic lb
|
||||
|
||||
scheduler uses cache_nice_tries as an indicator to do cache_hot and
|
||||
active load balance, when normal load balance fails. Currently,
|
||||
this value is changed on any failed load balance attempt. That ends
|
||||
up being not so nice to workloads that enter/exit idle often, as
|
||||
they do more frequent new_idle balance and that pretty soon results
|
||||
in cache hot tasks being pulled in.
|
||||
|
||||
Making the cache_nice_tries ignore failed new_idle balance seems to
|
||||
make better sense. With that only the failed load balance in
|
||||
periodic load balance gets accounted and the rate of accumulation
|
||||
of cache_nice_tries will not depend on idle entry/exit (short
|
||||
running sleep-wakeup kind of tasks). This reduces movement of
|
||||
cache_hot tasks.
|
||||
|
||||
schedstat diff (after-before) excerpt from a workload that has
|
||||
frequent and short wakeup-idle pattern (:2 in cpu col below refers
|
||||
to NEWIDLE idx) This snapshot was across ~400 seconds.
|
||||
|
||||
Without this change:
|
||||
domainstats: domain0
|
||||
cpu cnt bln fld imb gain hgain nobusyq nobusyg
|
||||
0:2 306487 219575 73167 110069413 44583 19070 1172 218403
|
||||
1:2 292139 194853 81421 120893383 50745 21902 1259 193594
|
||||
2:2 283166 174607 91359 129699642 54931 23688 1287 173320
|
||||
3:2 273998 161788 93991 132757146 57122 24351 1366 160422
|
||||
4:2 289851 215692 62190 83398383 36377 13680 851 214841
|
||||
5:2 316312 222146 77605 117582154 49948 20281 988 221158
|
||||
6:2 297172 195596 83623 122133390 52801 21301 929 194667
|
||||
7:2 283391 178078 86378 126622761 55122 22239 928 177150
|
||||
8:2 297655 210359 72995 110246694 45798 19777 1125 209234
|
||||
9:2 297357 202011 79363 119753474 50953 22088 1089 200922
|
||||
10:2 278797 178703 83180 122514385 52969 22726 1128 177575
|
||||
11:2 272661 167669 86978 127342327 55857 24342 1195 166474
|
||||
12:2 293039 204031 73211 110282059 47285 19651 948 203083
|
||||
13:2 289502 196762 76803 114712942 49339 20547 1016 195746
|
||||
14:2 264446 169609 78292 115715605 50459 21017 982 168627
|
||||
15:2 260968 163660 80142 116811793 51483 21281 1064 162596
|
||||
|
||||
With this change:
|
||||
domainstats: domain0
|
||||
cpu cnt bln fld imb gain hgain nobusyq nobusyg
|
||||
0:2 272347 187380 77455 105420270 24975 1 953 186427
|
||||
1:2 267276 172360 86234 116242264 28087 6 1028 171332
|
||||
2:2 259769 156777 93281 123243134 30555 1 1043 155734
|
||||
3:2 250870 143129 97627 127370868 32026 6 1188 141941
|
||||
4:2 248422 177116 64096 78261112 22202 2 757 176359
|
||||
5:2 275595 180683 84950 116075022 29400 6 778 179905
|
||||
6:2 262418 162609 88944 119256898 31056 4 817 161792
|
||||
7:2 252204 147946 92646 122388300 32879 4 824 147122
|
||||
8:2 262335 172239 81631 110477214 26599 4 864 171375
|
||||
9:2 261563 164775 88016 117203621 28331 3 849 163926
|
||||
10:2 243389 140949 93379 121353071 29585 2 909 140040
|
||||
11:2 242795 134651 98310 124768957 30895 2 1016 133635
|
||||
12:2 255234 166622 79843 104696912 26483 4 746 165876
|
||||
13:2 244944 151595 83855 109808099 27787 3 801 150794
|
||||
14:2 241301 140982 89935 116954383 30403 6 845 140137
|
||||
15:2 232271 128564 92821 119185207 31207 4 1416 127148
|
||||
|
||||
Signed-off-by: Venkatesh Pallipadi <venki@google.com>
|
||||
Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
|
||||
LKML-Reference: <1284167957-3675-1-git-send-email-venki@google.com>
|
||||
Signed-off-by: Ingo Molnar <mingo@elte.hu>
|
||||
---
|
||||
|
||||
[ 2.6.35.x backport ]
|
||||
|
||||
diff --git a/kernel/sched_fair.c b/kernel/sched_fair.c
|
||||
index a171138..aa16cf1 100644
|
||||
--- a/kernel/sched_fair.c
|
||||
+++ b/kernel/sched_fair.c
|
||||
@@ -3031,7 +3031,14 @@ redo:
|
||||
|
||||
if (!ld_moved) {
|
||||
schedstat_inc(sd, lb_failed[idle]);
|
||||
- sd->nr_balance_failed++;
|
||||
+ /*
|
||||
+ * Increment the failure counter only on periodic balance.
|
||||
+ * We do not want newidle balance, which can be very
|
||||
+ * frequent, pollute the failure counter causing
|
||||
+ * excessive cache_hot migrations and active balances.
|
||||
+ */
|
||||
+ if (idle != CPU_NEWLY_IDLE)
|
||||
+ sd->nr_balance_failed++;
|
||||
|
||||
if (need_active_balance(sd, sd_idle, idle)) {
|
||||
raw_spin_lock_irqsave(&busiest->lock, flags);
|
|
@ -0,0 +1,57 @@
|
|||
From kernel-bounces@lists.fedoraproject.org Thu Sep 9 09:23:49 2010
|
||||
From: Stanislaw Gruszka <sgruszka@redhat.com>
|
||||
Subject: [PATCH 1/3] sdhci: 8-bit data transfer width support
|
||||
Date: Thu, 9 Sep 2010 15:24:10 +0200
|
||||
|
||||
From: Kyungmin Park <kyungmin.park@samsung.com>
|
||||
|
||||
Upstream ae6d6c92212e94b12ab9365c23fb73acc2c3c2e7 commit.
|
||||
|
||||
Some host controllers such as s5pc110 support the WIDE8 feature.
|
||||
|
||||
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
|
||||
Cc: Grant Likely <grant.likely@secretlab.ca>
|
||||
Cc: <linux-mmc@vger.kernel.org>
|
||||
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
||||
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
|
||||
---
|
||||
drivers/mmc/host/sdhci.c | 5 +++++
|
||||
drivers/mmc/host/sdhci.h | 1 +
|
||||
2 files changed, 6 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
|
||||
index c6d1bd8..955cad9 100644
|
||||
--- a/drivers/mmc/host/sdhci.c
|
||||
+++ b/drivers/mmc/host/sdhci.c
|
||||
@@ -1159,6 +1159,11 @@ static void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
|
||||
|
||||
ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL);
|
||||
|
||||
+ if (ios->bus_width == MMC_BUS_WIDTH_8)
|
||||
+ ctrl |= SDHCI_CTRL_8BITBUS;
|
||||
+ else
|
||||
+ ctrl &= ~SDHCI_CTRL_8BITBUS;
|
||||
+
|
||||
if (ios->bus_width == MMC_BUS_WIDTH_4)
|
||||
ctrl |= SDHCI_CTRL_4BITBUS;
|
||||
else
|
||||
diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
|
||||
index c846813..eb5efe0 100644
|
||||
--- a/drivers/mmc/host/sdhci.h
|
||||
+++ b/drivers/mmc/host/sdhci.h
|
||||
@@ -72,6 +72,7 @@
|
||||
#define SDHCI_CTRL_ADMA1 0x08
|
||||
#define SDHCI_CTRL_ADMA32 0x10
|
||||
#define SDHCI_CTRL_ADMA64 0x18
|
||||
+#define SDHCI_CTRL_8BITBUS 0x20
|
||||
|
||||
#define SDHCI_POWER_CONTROL 0x29
|
||||
#define SDHCI_POWER_ON 0x01
|
||||
--
|
||||
1.7.1
|
||||
|
||||
_______________________________________________
|
||||
kernel mailing list
|
||||
kernel@lists.fedoraproject.org
|
||||
https://admin.fedoraproject.org/mailman/listinfo/kernel
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
From: Roland McGrath <roland@redhat.com>
|
||||
Date: Wed, 8 Sep 2010 02:35:49 +0000 (-0700)
|
||||
Subject: setup_arg_pages: diagnose excessive argument size
|
||||
X-Git-Tag: v2.6.36-rc4~14
|
||||
X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=1b528181b2ffa14721fb28ad1bd539fe1732c583
|
||||
|
||||
setup_arg_pages: diagnose excessive argument size
|
||||
|
||||
The CONFIG_STACK_GROWSDOWN variant of setup_arg_pages() does not
|
||||
check the size of the argument/environment area on the stack.
|
||||
When it is unworkably large, shift_arg_pages() hits its BUG_ON.
|
||||
This is exploitable with a very large RLIMIT_STACK limit, to
|
||||
create a crash pretty easily.
|
||||
|
||||
Check that the initial stack is not too large to make it possible
|
||||
to map in any executable. We're not checking that the actual
|
||||
executable (or intepreter, for binfmt_elf) will fit. So those
|
||||
mappings might clobber part of the initial stack mapping. But
|
||||
that is just userland lossage that userland made happen, not a
|
||||
kernel problem.
|
||||
|
||||
Signed-off-by: Roland McGrath <roland@redhat.com>
|
||||
Reviewed-by: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>
|
||||
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
|
||||
---
|
||||
|
||||
diff --git a/fs/exec.c b/fs/exec.c
|
||||
index 2d94552..1b63237 100644
|
||||
--- a/fs/exec.c
|
||||
+++ b/fs/exec.c
|
||||
@@ -594,6 +594,11 @@ int setup_arg_pages(struct linux_binprm *bprm,
|
||||
#else
|
||||
stack_top = arch_align_stack(stack_top);
|
||||
stack_top = PAGE_ALIGN(stack_top);
|
||||
+
|
||||
+ if (unlikely(stack_top < mmap_min_addr) ||
|
||||
+ unlikely(vma->vm_end - vma->vm_start >= stack_top - mmap_min_addr))
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
stack_shift = vma->vm_end - stack_top;
|
||||
|
||||
bprm->p -= stack_shift;
|
|
@ -0,0 +1,98 @@
|
|||
From sgruszka@redhat.com Mon Oct 18 05:19:21 2010
|
||||
Return-Path: sgruszka@redhat.com
|
||||
Received: from zmta02.collab.prod.int.phx2.redhat.com (LHLO
|
||||
zmta02.collab.prod.int.phx2.redhat.com) (10.5.5.32) by
|
||||
mail03.corp.redhat.com with LMTP; Mon, 18 Oct 2010 05:19:21 -0400 (EDT)
|
||||
Received: from localhost (localhost.localdomain [127.0.0.1])
|
||||
by zmta02.collab.prod.int.phx2.redhat.com (Postfix) with ESMTP id A11F69E559;
|
||||
Mon, 18 Oct 2010 05:19:21 -0400 (EDT)
|
||||
Received: from zmta02.collab.prod.int.phx2.redhat.com ([127.0.0.1])
|
||||
by localhost (zmta02.collab.prod.int.phx2.redhat.com [127.0.0.1]) (amavisd-new, port 10024)
|
||||
with ESMTP id IhyIgD7E4aj3; Mon, 18 Oct 2010 05:19:21 -0400 (EDT)
|
||||
Received: from int-mx08.intmail.prod.int.phx2.redhat.com (int-mx08.intmail.prod.int.phx2.redhat.com [10.5.11.21])
|
||||
by zmta02.collab.prod.int.phx2.redhat.com (Postfix) with ESMTP id 9007B9E55E;
|
||||
Mon, 18 Oct 2010 05:19:21 -0400 (EDT)
|
||||
Received: from localhost (dhcp-1-246.brq.redhat.com [10.34.1.246])
|
||||
by int-mx08.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id o9I9JKsF025385;
|
||||
Mon, 18 Oct 2010 05:19:21 -0400
|
||||
From: Stanislaw Gruszka <sgruszka@redhat.com>
|
||||
To: stable@kernel.org
|
||||
Cc: Kyle McMartin <kmcmartin@redhat.com>,
|
||||
Stanislaw Gruszka <sgruszka@redhat.com>,
|
||||
"David S. Miller" <davem@davemloft.net>
|
||||
Subject: [PATCH -stable 2.6.34+] skge: add quirk to limit DMA
|
||||
Date: Mon, 18 Oct 2010 11:21:54 +0200
|
||||
Message-Id: <1287393714-3720-1-git-send-email-sgruszka@redhat.com>
|
||||
X-Scanned-By: MIMEDefang 2.67 on 10.5.11.21
|
||||
|
||||
Upstream 392bd0cb000d4aac9e88e4f50823db85e7220688 commit.
|
||||
|
||||
Skge devices installed on some Gigabyte motherboards are not able to
|
||||
perform 64 dma correctly due to board PCI implementation, so limit
|
||||
DMA to 32bit if such boards are detected.
|
||||
|
||||
Bug was reported here:
|
||||
https://bugzilla.redhat.com/show_bug.cgi?id=447489
|
||||
|
||||
Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
|
||||
Tested-by: Luya Tshimbalanga <luya@fedoraproject.org>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
drivers/net/skge.c | 18 +++++++++++++++++-
|
||||
1 files changed, 17 insertions(+), 1 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/skge.c b/drivers/net/skge.c
|
||||
index 40e5c46..465ae7e 100644
|
||||
--- a/drivers/net/skge.c
|
||||
+++ b/drivers/net/skge.c
|
||||
@@ -43,6 +43,7 @@
|
||||
#include <linux/seq_file.h>
|
||||
#include <linux/mii.h>
|
||||
#include <linux/slab.h>
|
||||
+#include <linux/dmi.h>
|
||||
#include <asm/irq.h>
|
||||
|
||||
#include "skge.h"
|
||||
@@ -3868,6 +3869,8 @@ static void __devinit skge_show_addr(struct net_device *dev)
|
||||
netif_info(skge, probe, skge->netdev, "addr %pM\n", dev->dev_addr);
|
||||
}
|
||||
|
||||
+static int only_32bit_dma;
|
||||
+
|
||||
static int __devinit skge_probe(struct pci_dev *pdev,
|
||||
const struct pci_device_id *ent)
|
||||
{
|
||||
@@ -3889,7 +3892,7 @@ static int __devinit skge_probe(struct pci_dev *pdev,
|
||||
|
||||
pci_set_master(pdev);
|
||||
|
||||
- if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) {
|
||||
+ if (!only_32bit_dma && !pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) {
|
||||
using_dac = 1;
|
||||
err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64));
|
||||
} else if (!(err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)))) {
|
||||
@@ -4147,8 +4150,21 @@ static struct pci_driver skge_driver = {
|
||||
.shutdown = skge_shutdown,
|
||||
};
|
||||
|
||||
+static struct dmi_system_id skge_32bit_dma_boards[] = {
|
||||
+ {
|
||||
+ .ident = "Gigabyte nForce boards",
|
||||
+ .matches = {
|
||||
+ DMI_MATCH(DMI_BOARD_VENDOR, "Gigabyte Technology Co"),
|
||||
+ DMI_MATCH(DMI_BOARD_NAME, "nForce"),
|
||||
+ },
|
||||
+ },
|
||||
+ {}
|
||||
+};
|
||||
+
|
||||
static int __init skge_init_module(void)
|
||||
{
|
||||
+ if (dmi_check_system(skge_32bit_dma_boards))
|
||||
+ only_32bit_dma = 1;
|
||||
skge_debug_init();
|
||||
return pci_register_driver(&skge_driver);
|
||||
}
|
||||
--
|
||||
1.7.1
|
||||
|
1
sources
1
sources
|
@ -1 +1,2 @@
|
|||
091abeb4684ce03d1d936851618687b6 linux-2.6.35.tar.bz2
|
||||
0dbd6ebf242a1428d4161bc32b1306fa patch-2.6.35.6.bz2
|
||||
|
|
|
@ -1,155 +0,0 @@
|
|||
From 4d9d1ff88f920e9fcdde155c0a1366b7e0462d14 Mon Sep 17 00:00:00 2001
|
||||
From: John W. Linville <linville@tuxdriver.com>
|
||||
Date: Fri, 19 Mar 2010 14:58:01 -0400
|
||||
Subject: [PATCH v4] ssb: do not read SPROM if it does not exist
|
||||
|
||||
Attempting to read registers that don't exist on the SSB bus can cause
|
||||
hangs on some boxes. At least some b43 devices are 'in the wild' that
|
||||
don't have SPROMs at all. When the SSB bus support loads, it attempts
|
||||
to read these (non-existant) SPROMs and causes hard hangs on the box --
|
||||
no console output, etc.
|
||||
|
||||
This patch adds some intelligence to determine whether or not the SPROM
|
||||
is present before attempting to read it. This avoids those hard hangs
|
||||
on those devices with no SPROM attached to their SSB bus. The
|
||||
SSB-attached devices (e.g. b43, et al.) won't work, but at least the box
|
||||
will survive to test further patches. :-)
|
||||
|
||||
Signed-off-by: John W. Linville <linville@tuxdriver.com>
|
||||
Cc: Larry Finger <Larry.Finger@lwfinger.net>
|
||||
Cc: Michael Buesch <mb@bu3sch.de>
|
||||
Cc: stable@kernel.org
|
||||
---
|
||||
drivers/ssb/driver_chipcommon.c | 3 +++
|
||||
drivers/ssb/pci.c | 3 +++
|
||||
drivers/ssb/sprom.c | 26 ++++++++++++++++++++++++++
|
||||
include/linux/ssb/ssb.h | 3 +++
|
||||
include/linux/ssb/ssb_driver_chipcommon.h | 15 +++++++++++++++
|
||||
5 files changed, 50 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/drivers/ssb/driver_chipcommon.c b/drivers/ssb/driver_chipcommon.c
|
||||
index 9681536..6cf288d 100644
|
||||
--- a/drivers/ssb/driver_chipcommon.c
|
||||
+++ b/drivers/ssb/driver_chipcommon.c
|
||||
@@ -233,6 +233,9 @@ void ssb_chipcommon_init(struct ssb_chipcommon *cc)
|
||||
{
|
||||
if (!cc->dev)
|
||||
return; /* We don't have a ChipCommon */
|
||||
+ if (cc->dev->id.revision >= 11) {
|
||||
+ cc->status = chipco_read32(cc, SSB_CHIPCO_CHIPSTAT);
|
||||
+ }
|
||||
ssb_pmu_init(cc);
|
||||
chipco_powercontrol_init(cc);
|
||||
ssb_chipco_set_clockmode(cc, SSB_CLKMODE_FAST);
|
||||
diff --git a/drivers/ssb/pci.c b/drivers/ssb/pci.c
|
||||
index a8dbb06..89d7ab1 100644
|
||||
--- a/drivers/ssb/pci.c
|
||||
+++ b/drivers/ssb/pci.c
|
||||
@@ -621,6 +621,9 @@ static int ssb_pci_sprom_get(struct ssb_bus *bus,
|
||||
int err = -ENOMEM;
|
||||
u16 *buf;
|
||||
|
||||
+ if (!ssb_is_sprom_available(bus))
|
||||
+ return -ENODEV;
|
||||
+
|
||||
buf = kcalloc(SSB_SPROMSIZE_WORDS_R123, sizeof(u16), GFP_KERNEL);
|
||||
if (!buf)
|
||||
goto out;
|
||||
diff --git a/drivers/ssb/sprom.c b/drivers/ssb/sprom.c
|
||||
index f2f920f..c690f58 100644
|
||||
--- a/drivers/ssb/sprom.c
|
||||
+++ b/drivers/ssb/sprom.c
|
||||
@@ -176,3 +176,29 @@ const struct ssb_sprom *ssb_get_fallback_sprom(void)
|
||||
{
|
||||
return fallback_sprom;
|
||||
}
|
||||
+
|
||||
+bool ssb_is_sprom_available(struct ssb_bus *bus)
|
||||
+{
|
||||
+ /* some older devices don't have chipcommon, but they have sprom */
|
||||
+ if (!bus->chipco.dev)
|
||||
+ return true;
|
||||
+
|
||||
+ /* status register only exists on chipcomon rev >= 11 */
|
||||
+ if (bus->chipco.dev->id.revision < 11)
|
||||
+ return true;
|
||||
+
|
||||
+ switch (bus->chip_id) {
|
||||
+ case 0x4312:
|
||||
+ return SSB_CHIPCO_CHST_4312_SPROM_PRESENT(bus->chipco.status);
|
||||
+ case 0x4322:
|
||||
+ return SSB_CHIPCO_CHST_4322_SPROM_PRESENT(bus->chipco.status);
|
||||
+ case 0x4325:
|
||||
+ return SSB_CHIPCO_CHST_4325_SPROM_PRESENT(bus->chipco.status);
|
||||
+ default:
|
||||
+ break;
|
||||
+ }
|
||||
+ if (bus->chipco.dev->id.revision >= 31)
|
||||
+ return bus->chipco.capabilities & SSB_CHIPCO_CAP_SPROM;
|
||||
+
|
||||
+ return true;
|
||||
+}
|
||||
diff --git a/include/linux/ssb/ssb.h b/include/linux/ssb/ssb.h
|
||||
index 24f9885..3b4da23 100644
|
||||
--- a/include/linux/ssb/ssb.h
|
||||
+++ b/include/linux/ssb/ssb.h
|
||||
@@ -394,6 +394,9 @@ extern int ssb_bus_sdiobus_register(struct ssb_bus *bus,
|
||||
|
||||
extern void ssb_bus_unregister(struct ssb_bus *bus);
|
||||
|
||||
+/* Does the device have an SPROM? */
|
||||
+extern bool ssb_is_sprom_available(struct ssb_bus *bus);
|
||||
+
|
||||
/* Set a fallback SPROM.
|
||||
* See kdoc at the function definition for complete documentation. */
|
||||
extern int ssb_arch_set_fallback_sprom(const struct ssb_sprom *sprom);
|
||||
diff --git a/include/linux/ssb/ssb_driver_chipcommon.h b/include/linux/ssb/ssb_driver_chipcommon.h
|
||||
index 4e27acf..2cdf249 100644
|
||||
--- a/include/linux/ssb/ssb_driver_chipcommon.h
|
||||
+++ b/include/linux/ssb/ssb_driver_chipcommon.h
|
||||
@@ -53,6 +53,7 @@
|
||||
#define SSB_CHIPCO_CAP_64BIT 0x08000000 /* 64-bit Backplane */
|
||||
#define SSB_CHIPCO_CAP_PMU 0x10000000 /* PMU available (rev >= 20) */
|
||||
#define SSB_CHIPCO_CAP_ECI 0x20000000 /* ECI available (rev >= 20) */
|
||||
+#define SSB_CHIPCO_CAP_SPROM 0x40000000 /* SPROM present */
|
||||
#define SSB_CHIPCO_CORECTL 0x0008
|
||||
#define SSB_CHIPCO_CORECTL_UARTCLK0 0x00000001 /* Drive UART with internal clock */
|
||||
#define SSB_CHIPCO_CORECTL_SE 0x00000002 /* sync clk out enable (corerev >= 3) */
|
||||
@@ -385,6 +386,7 @@
|
||||
|
||||
|
||||
/** Chip specific Chip-Status register contents. */
|
||||
+#define SSB_CHIPCO_CHST_4322_SPROM_EXISTS 0x00000040 /* SPROM present */
|
||||
#define SSB_CHIPCO_CHST_4325_SPROM_OTP_SEL 0x00000003
|
||||
#define SSB_CHIPCO_CHST_4325_DEFCIS_SEL 0 /* OTP is powered up, use def. CIS, no SPROM */
|
||||
#define SSB_CHIPCO_CHST_4325_SPROM_SEL 1 /* OTP is powered up, SPROM is present */
|
||||
@@ -398,6 +400,18 @@
|
||||
#define SSB_CHIPCO_CHST_4325_RCAL_VALUE_SHIFT 4
|
||||
#define SSB_CHIPCO_CHST_4325_PMUTOP_2B 0x00000200 /* 1 for 2b, 0 for to 2a */
|
||||
|
||||
+/** Macros to determine SPROM presence based on Chip-Status register. */
|
||||
+#define SSB_CHIPCO_CHST_4312_SPROM_PRESENT(status) \
|
||||
+ ((status & SSB_CHIPCO_CHST_4325_SPROM_OTP_SEL) != \
|
||||
+ SSB_CHIPCO_CHST_4325_OTP_SEL)
|
||||
+#define SSB_CHIPCO_CHST_4322_SPROM_PRESENT(status) \
|
||||
+ (status & SSB_CHIPCO_CHST_4322_SPROM_EXISTS)
|
||||
+#define SSB_CHIPCO_CHST_4325_SPROM_PRESENT(status) \
|
||||
+ (((status & SSB_CHIPCO_CHST_4325_SPROM_OTP_SEL) != \
|
||||
+ SSB_CHIPCO_CHST_4325_DEFCIS_SEL) && \
|
||||
+ ((status & SSB_CHIPCO_CHST_4325_SPROM_OTP_SEL) != \
|
||||
+ SSB_CHIPCO_CHST_4325_OTP_SEL))
|
||||
+
|
||||
|
||||
|
||||
/** Clockcontrol masks and values **/
|
||||
@@ -564,6 +578,7 @@ struct ssb_chipcommon_pmu {
|
||||
struct ssb_chipcommon {
|
||||
struct ssb_device *dev;
|
||||
u32 capabilities;
|
||||
+ u32 status;
|
||||
/* Fast Powerup Delay constant */
|
||||
u16 fast_pwrup_delay;
|
||||
struct ssb_chipcommon_pmu pmu;
|
||||
--
|
||||
1.7.0.1
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
commit 8cf5102c84dba60b2ea29b7e89f1a65100e20bb9
|
||||
Author: Matthew Garrett <mjg@redhat.com>
|
||||
Date: Thu Oct 21 17:31:56 2010 -0400
|
||||
|
||||
tpm: Autodetect itpm devices
|
||||
|
||||
Some Lenovos have TPMs that require a quirk to function correctly. This can
|
||||
be autodetected by checking whether the device has a _HID of INTC0102. This
|
||||
is an invalid PNPid, and as such is discarded by the pnp layer - however
|
||||
it's still present in the ACPI code, so we can pull it out that way. This
|
||||
means that the quirk won't be automatically applied on non-ACPI systems,
|
||||
but without ACPI we don't have any way to identify the chip anyway so I
|
||||
don't think that's a great concern.
|
||||
|
||||
Signed-off-by: Matthew Garrett <mjg@redhat.com>
|
||||
|
||||
diff --git a/drivers/char/tpm/tpm_tis.c b/drivers/char/tpm/tpm_tis.c
|
||||
index 1030f84..c17a305 100644
|
||||
--- a/drivers/char/tpm/tpm_tis.c
|
||||
+++ b/drivers/char/tpm/tpm_tis.c
|
||||
@@ -25,6 +25,7 @@
|
||||
#include <linux/slab.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/wait.h>
|
||||
+#include <linux/acpi.h>
|
||||
#include "tpm.h"
|
||||
|
||||
#define TPM_HEADER_SIZE 10
|
||||
@@ -78,6 +79,26 @@ enum tis_defaults {
|
||||
static LIST_HEAD(tis_chips);
|
||||
static DEFINE_SPINLOCK(tis_lock);
|
||||
|
||||
+#ifdef CONFIG_ACPI
|
||||
+static int is_itpm(struct pnp_dev *dev)
|
||||
+{
|
||||
+ struct acpi_device *acpi = pnp_acpi_device(dev);
|
||||
+ struct acpi_hardware_id *id;
|
||||
+
|
||||
+ list_for_each_entry(id, &acpi->pnp.ids, list) {
|
||||
+ if (!strcmp("INTC0102", id->id))
|
||||
+ return 1;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+#else
|
||||
+static int is_itpm(struct pnp_dev *dev)
|
||||
+{
|
||||
+ return 0;
|
||||
+}
|
||||
+#endif
|
||||
+
|
||||
static int check_locality(struct tpm_chip *chip, int l)
|
||||
{
|
||||
if ((ioread8(chip->vendor.iobase + TPM_ACCESS(l)) &
|
||||
@@ -472,6 +493,9 @@ static int tpm_tis_init(struct device *dev, resource_size_t start,
|
||||
"1.2 TPM (device-id 0x%X, rev-id %d)\n",
|
||||
vendor >> 16, ioread8(chip->vendor.iobase + TPM_RID(0)));
|
||||
|
||||
+ if (is_itpm(to_pnp_dev(dev)))
|
||||
+ itpm = 1;
|
||||
+
|
||||
if (itpm)
|
||||
dev_info(dev, "Intel iTPM workaround enabled\n");
|
||||
|
|
@ -0,0 +1,88 @@
|
|||
From 3e645d6b485446c54c6745c5e2cf5c528fe4deec Mon Sep 17 00:00:00 2001
|
||||
From: Linus Torvalds <torvalds@linux-foundation.org>
|
||||
Date: Fri, 15 Oct 2010 11:12:38 -0700
|
||||
Subject: v4l1: fix 32-bit compat microcode loading translation
|
||||
|
||||
From: Linus Torvalds <torvalds@linux-foundation.org>
|
||||
|
||||
commit 3e645d6b485446c54c6745c5e2cf5c528fe4deec upstream.
|
||||
|
||||
The compat code for the VIDIOCSMICROCODE ioctl is totally buggered.
|
||||
It's only used by the VIDEO_STRADIS driver, and that one is scheduled to
|
||||
staging and eventually removed unless somebody steps up to maintain it
|
||||
(at which point it should use request_firmware() rather than some magic
|
||||
ioctl). So we'll get rid of it eventually.
|
||||
|
||||
But in the meantime, the compatibility ioctl code is broken, and this
|
||||
tries to get it to at least limp along (even if Mauro suggested just
|
||||
deleting it entirely, which may be the right thing to do - I don't think
|
||||
the compatibility translation code has ever worked unless you were very
|
||||
lucky).
|
||||
|
||||
Reported-by: Kees Cook <kees.cook@canonical.com>
|
||||
Cc: Mauro Carvalho Chehab <mchehab@infradead.org>
|
||||
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
|
||||
|
||||
---
|
||||
drivers/media/video/v4l2-compat-ioctl32.c | 32 +++++++++++++++++++-----------
|
||||
1 file changed, 21 insertions(+), 11 deletions(-)
|
||||
|
||||
--- a/drivers/media/video/v4l2-compat-ioctl32.c
|
||||
+++ b/drivers/media/video/v4l2-compat-ioctl32.c
|
||||
@@ -193,17 +193,24 @@ static int put_video_window32(struct vid
|
||||
struct video_code32 {
|
||||
char loadwhat[16]; /* name or tag of file being passed */
|
||||
compat_int_t datasize;
|
||||
- unsigned char *data;
|
||||
+ compat_uptr_t data;
|
||||
};
|
||||
|
||||
-static int get_microcode32(struct video_code *kp, struct video_code32 __user *up)
|
||||
+static struct video_code __user *get_microcode32(struct video_code32 *kp)
|
||||
{
|
||||
- if (!access_ok(VERIFY_READ, up, sizeof(struct video_code32)) ||
|
||||
- copy_from_user(kp->loadwhat, up->loadwhat, sizeof(up->loadwhat)) ||
|
||||
- get_user(kp->datasize, &up->datasize) ||
|
||||
- copy_from_user(kp->data, up->data, up->datasize))
|
||||
- return -EFAULT;
|
||||
- return 0;
|
||||
+ struct video_code __user *up;
|
||||
+
|
||||
+ up = compat_alloc_user_space(sizeof(*up));
|
||||
+
|
||||
+ /*
|
||||
+ * NOTE! We don't actually care if these fail. If the
|
||||
+ * user address is invalid, the native ioctl will do
|
||||
+ * the error handling for us
|
||||
+ */
|
||||
+ (void) copy_to_user(up->loadwhat, kp->loadwhat, sizeof(up->loadwhat));
|
||||
+ (void) put_user(kp->datasize, &up->datasize);
|
||||
+ (void) put_user(compat_ptr(kp->data), &up->data);
|
||||
+ return up;
|
||||
}
|
||||
|
||||
#define VIDIOCGTUNER32 _IOWR('v', 4, struct video_tuner32)
|
||||
@@ -744,7 +751,7 @@ static long do_video_ioctl(struct file *
|
||||
struct video_tuner vt;
|
||||
struct video_buffer vb;
|
||||
struct video_window vw;
|
||||
- struct video_code vc;
|
||||
+ struct video_code32 vc;
|
||||
struct video_audio va;
|
||||
#endif
|
||||
struct v4l2_format v2f;
|
||||
@@ -823,8 +830,11 @@ static long do_video_ioctl(struct file *
|
||||
break;
|
||||
|
||||
case VIDIOCSMICROCODE:
|
||||
- err = get_microcode32(&karg.vc, up);
|
||||
- compatible_arg = 0;
|
||||
+ /* Copy the 32-bit "video_code32" to kernel space */
|
||||
+ if (copy_from_user(&karg.vc, up, sizeof(karg.vc)))
|
||||
+ return -EFAULT;
|
||||
+ /* Convert the 32-bit version to a 64-bit version in user space */
|
||||
+ up = get_microcode32(&karg.vc);
|
||||
break;
|
||||
|
||||
case VIDIOCSFREQ:
|
|
@ -0,0 +1,13 @@
|
|||
Fix typo in Xen patch from 2.6.35.5
|
||||
|
||||
--- linux-2.6.35.noarch.orig/drivers/xen/events.c
|
||||
+++ linux-2.6.35.noarch/drivers/xen/events.c
|
||||
@@ -935,7 +935,7 @@ static struct irq_chip xen_dynamic_chip
|
||||
.retrigger = retrigger_dynirq,
|
||||
};
|
||||
|
||||
-static struct irq_chip en_percpu_chip __read_mostly = {
|
||||
+static struct irq_chip xen_percpu_chip __read_mostly = {
|
||||
.name = "xen-percpu",
|
||||
|
||||
.disable = disable_dynirq,
|
Loading…
Reference in New Issue