Compare commits
260 Commits
master
...
f14-user-s
Author | SHA1 | Date |
---|---|---|
Steve Dickson | 3a4ec2bd5a | |
Steve Dickson | 3b1a284d7f | |
Steve Dickson | b170076e1c | |
Steve Dickson | 250f7589e4 | |
Steve Dickson | 5cde5ec617 | |
Steve Dickson | c304842dfa | |
Steve Dickson | 1c967e02e8 | |
Steve Dickson | 2f1b6218c2 | |
Steve Dickson | 0aee182506 | |
Steve Dickson | a0798f575a | |
Steve Dickson | 5af4710c35 | |
Steve Dickson | 7c7185f5b6 | |
Steve Dickson | 26ae753414 | |
Steve Dickson | d3e09fea2e | |
Steve Dickson | 9c73b72b5f | |
Steve Dickson | 3df03d3c34 | |
Steve Dickson | cf1662d8fb | |
Steve Dickson | 2baff9db8b | |
Steve Dickson | 7931835043 | |
Steve Dickson | de8bc7b809 | |
Steve Dickson | 5c5064cff6 | |
Steve Dickson | bcef2ab5ff | |
Steve Dickson | 04b78851f2 | |
Steve Dickson | d9c1e2fc10 | |
Steve Dickson | a17e76f845 | |
Steve Dickson | bed19a5610 | |
Jarod Wilson | e2f91db6ff | |
Jarod Wilson | 639fa258dc | |
Jarod Wilson | 1875248d2a | |
Jarod Wilson | ef402ae0aa | |
Jarod Wilson | c998b6666e | |
Jarod Wilson | dd3abe2b99 | |
Jarod Wilson | 893aff6339 | |
Kyle McMartin | 7aeac617c0 | |
Jarod Wilson | 0252aa3de3 | |
Jarod Wilson | 5423b80362 | |
Jarod Wilson | a49e3abdff | |
Chuck Ebbert | b11f51521b | |
Jarod Wilson | b97dc7392d | |
Jarod Wilson | 49ee500dd9 | |
Jarod Wilson | f0f13be684 | |
Jarod Wilson | 4b2adb7be5 | |
Chuck Ebbert | aee782a97f | |
Chuck Ebbert | 1f90e5b6f6 | |
Chuck Ebbert | b1f2f04a2b | |
Jarod Wilson | 3ebdcc0e61 | |
Jarod Wilson | d1877af9bb | |
Matthew Garrett | 70d2ada596 | |
Matthew Garrett | 73ab1e483b | |
Kyle McMartin | c60b83ee86 | |
Kyle McMartin | 0cb25895ed | |
Kyle McMartin | bd64b2b5de | |
Jarod Wilson | 1328b3a839 | |
Kyle McMartin | 249677902c | |
Kyle McMartin | 646207ff5c | |
Jarod Wilson | 1cd0593638 | |
Jarod Wilson | 42434a4dc9 | |
Jarod Wilson | d3e2823f71 | |
Kyle McMartin | 358f4a55c5 | |
Kyle McMartin | 825b8ce73a | |
Kyle McMartin | f8d75b80e6 | |
Kyle McMartin | 3dbb45b665 | |
Kyle McMartin | 68b623121d | |
Kyle McMartin | 558463d9fb | |
Jarod Wilson | 703515438b | |
Jarod Wilson | fbfed34fec | |
Jarod Wilson | 92d37ba1d3 | |
Chuck Ebbert | 8f007394cd | |
Kyle McMartin | f045c5648e | |
Kyle McMartin | f2ed8cf30b | |
Kyle McMartin | 5a95077aa5 | |
Kyle McMartin | 54f1e03004 | |
Kyle McMartin | 9d6e5dc425 | |
Kyle McMartin | 4bd3ae5daa | |
Kyle McMartin | bd61adb09d | |
Chuck Ebbert | 983a2bb5c5 | |
Kyle McMartin | bed92c4e50 | |
Kyle McMartin | 20b0493429 | |
Kyle McMartin | 65c06ec080 | |
Kyle McMartin | 76a7ebfb42 | |
Kyle McMartin | d40233bb75 | |
Kyle McMartin | 592f4fb443 | |
Kyle McMartin | 48eb5c319b | |
Kyle McMartin | 26ea0f2631 | |
Kyle McMartin | ca2a17f441 | |
Kyle McMartin | 6abfea1c89 | |
kyle | 7a80ec3e7d | |
kyle | e1c14200b1 | |
John W. Linville | dd99fe005c | |
Kyle McMartin | 003654d6ca | |
Kyle McMartin | c86d4707a6 | |
Kyle McMartin | de964e3639 | |
Kyle McMartin | 55415ebd4a | |
Kyle McMartin | cc7fb594a9 | |
Jarod Wilson | 51157289c8 | |
Chuck Ebbert | 0081a7139c | |
Ben Skeggs | 466450dbeb | |
Kyle McMartin | b2e700d12a | |
Kyle McMartin | 4c76cc7f94 | |
Dave Airlie | d5b83e3877 | |
Dave Airlie | 5f72d41789 | |
Dave Airlie | 171d7cfb89 | |
Justin M. Forbes | adfff05db3 | |
Jarod Wilson | 28683a07fb | |
Dave Airlie | 5ddd90a5d8 | |
Dave Airlie | a474625d92 | |
Dave Airlie | 05493c4e57 | |
Steve Dickson | b1908c3f14 | |
Steve Dickson | 4075b4330d | |
Steve Dickson | 7ae8052041 | |
Steve Dickson | 988a85aa6c | |
Steve Dickson | 5bb2257913 | |
Steve Dickson | 5d0f2f53b5 | |
Steve Dickson | 9f73d83bc4 | |
Steve Dickson | e83ea7932d | |
Steve Dickson | 42b1398bfb | |
Steve Dickson | c14bfbaece | |
Steve Dickson | a062dba9af | |
Steve Dickson | ab7f8fbb16 | |
Steve Dickson | 29691321a1 | |
Ben Skeggs | 383a70142a | |
Ben Skeggs | c7b0072805 | |
Ben Skeggs | df57a85a75 | |
Steve Dickson | 97df345045 | |
Steve Dickson | 4cd7bbe2c2 | |
Steve Dickson | 4d9d24fa91 | |
Steve Dickson | 518cb858af | |
Steve Dickson | e8f419b0f2 | |
Steve Dickson | 00a1e4687b | |
Steve Dickson | b26c11d70d | |
Steve Dickson | fdb21e64be | |
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 | |
Steve Dickson | d10953c63b | |
Ben Skeggs | 7043d42b5a | |
Dave Jones | 452369b936 | |
Dave Jones | 8f3d6a8c3f | |
Steve Dickson | 853d932874 | |
Dave Jones | fbce23b0ff | |
Steve Dickson | e3f262ca54 | |
Dave Jones | bbaea70ee5 | |
Steve Dickson | a4eb340836 | |
Steve Dickson | 6ac45b1066 | |
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 | |
Steve Dickson | cea8e93168 | |
Steve Dickson | 17fde2a710 | |
Steve Dickson | e4d5325720 | |
Steve Dickson | bffee47a5b | |
Kyle McMartin | 3c5d4de07c | |
Dave Jones | 90303f9462 | |
Dave Jones | 10931f1112 | |
Chuck Ebbert | 27e8302707 | |
Chuck Ebbert | 8f132e348c | |
Chuck Ebbert | b30c150da1 | |
Chuck Ebbert | 3e8e94e0cd | |
Steve Dickson | 2380b040ab | |
Chuck Ebbert | 74e18cdf9e | |
Steve Dickson | a3dc221272 | |
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 |
6
Makefile
6
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
|
||||
|
@ -97,6 +98,10 @@ debug:
|
|||
@perl -pi -e 's/^%define debugbuildsenabled 1/%define debugbuildsenabled 0/' kernel.spec
|
||||
@perl -pi -e 's/^%define rawhide_skip_docs 0/%define rawhide_skip_docs 1/' kernel.spec
|
||||
|
||||
nodebuginfo:
|
||||
@perl -pi -e 's/^%define with_debuginfo %\{\?_without_debuginfo: 0\} %\{\?\!_without_debuginfo: 1\}/%define with_debuginfo %\{\?_without_debuginfo: 0\} %\{\?\!_without_debuginfo: 0\}/' kernel.spec
|
||||
nodebug: release
|
||||
@perl -pi -e 's/^%define debugbuildsenabled 1/%define debugbuildsenabled 0/' kernel.spec
|
||||
release:
|
||||
@perl -pi -e 's/CONFIG_SLUB_DEBUG_ON=y/# CONFIG_SLUB_DEBUG_ON is not set/' config-nodebug
|
||||
@perl -pi -e 's/CONFIG_LOCK_STAT=y/# CONFIG_LOCK_STAT is not set/' config-nodebug
|
||||
|
@ -156,6 +161,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,68 @@
|
|||
--- linux-2.6.35.x86_64/drivers/acpi/battery.c.orig 2010-12-23 10:42:09.291854595 -0500
|
||||
+++ linux-2.6.35.x86_64/drivers/acpi/battery.c 2010-12-23 10:44:30.996045838 -0500
|
||||
@@ -596,9 +596,10 @@
|
||||
}
|
||||
}
|
||||
|
||||
-static int acpi_battery_update(struct acpi_battery *battery)
|
||||
+static int acpi_battery_update(struct acpi_battery *battery, bool get_info)
|
||||
{
|
||||
int result, old_present = acpi_battery_present(battery);
|
||||
+ int old_power_unit = battery->power_unit;
|
||||
result = acpi_battery_get_status(battery);
|
||||
if (result)
|
||||
return result;
|
||||
@@ -621,6 +622,16 @@
|
||||
if (!battery->bat.dev)
|
||||
sysfs_add_battery(battery);
|
||||
#endif
|
||||
+ if (get_info) {
|
||||
+ acpi_battery_get_info(battery);
|
||||
+#ifdef CONFIG_ACPI_SYSFS_POWER
|
||||
+ if (old_power_unit != battery->power_unit) {
|
||||
+ /* The battery has changed its reporting units */
|
||||
+ sysfs_remove_battery(battery);
|
||||
+ sysfs_add_battery(battery);
|
||||
+ }
|
||||
+#endif
|
||||
+ }
|
||||
result = acpi_battery_get_state(battery);
|
||||
acpi_battery_quirks2(battery);
|
||||
return result;
|
||||
@@ -798,7 +809,7 @@
|
||||
static int acpi_battery_read(int fid, struct seq_file *seq)
|
||||
{
|
||||
struct acpi_battery *battery = seq->private;
|
||||
- int result = acpi_battery_update(battery);
|
||||
+ int result = acpi_battery_update(battery, false);
|
||||
return acpi_print_funcs[fid](seq, result);
|
||||
}
|
||||
|
||||
@@ -913,7 +924,8 @@
|
||||
#ifdef CONFIG_ACPI_SYSFS_POWER
|
||||
old = battery->bat.dev;
|
||||
#endif
|
||||
- acpi_battery_update(battery);
|
||||
+ acpi_battery_update(battery, (event == ACPI_BATTERY_NOTIFY_INFO ? true
|
||||
+ : false));
|
||||
acpi_bus_generate_proc_event(device, event,
|
||||
acpi_battery_present(battery));
|
||||
acpi_bus_generate_netlink_event(device->pnp.device_class,
|
||||
@@ -944,7 +956,7 @@
|
||||
if (ACPI_SUCCESS(acpi_get_handle(battery->device->handle,
|
||||
"_BIX", &handle)))
|
||||
set_bit(ACPI_BATTERY_XINFO_PRESENT, &battery->flags);
|
||||
- acpi_battery_update(battery);
|
||||
+ acpi_battery_update(battery, false);
|
||||
#ifdef CONFIG_ACPI_PROCFS_POWER
|
||||
result = acpi_battery_add_fs(device);
|
||||
#endif
|
||||
@@ -987,7 +999,7 @@
|
||||
return -EINVAL;
|
||||
battery = acpi_driver_data(device);
|
||||
battery->update_time = 0;
|
||||
- acpi_battery_update(battery);
|
||||
+ acpi_battery_update(battery, true);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -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,263 @@
|
|||
diff -uNrp kernel-2.6.35.fc14.orig/drivers/bluetooth/btusb.c kernel-2.6.35.fc14.new/drivers/bluetooth/btusb.c
|
||||
--- kernel-2.6.35.fc14.orig/drivers/bluetooth/btusb.c 2010-11-12 12:35:49.390791080 +0100
|
||||
+++ kernel-2.6.35.fc14.new/drivers/bluetooth/btusb.c 2010-11-12 12:48:22.090611963 +0100
|
||||
@@ -68,6 +68,9 @@ static struct usb_device_id btusb_table[
|
||||
/* Apple MacBookPro6,2 */
|
||||
{ USB_DEVICE(0x05ac, 0x8218) },
|
||||
|
||||
+ /* Apple MacBookAir3,1, MacBookAir3,2 */
|
||||
+ { USB_DEVICE(0x05ac, 0x821b) },
|
||||
+
|
||||
/* AVM BlueFRITZ! USB v2.0 */
|
||||
{ USB_DEVICE(0x057c, 0x3800) },
|
||||
|
||||
diff -uNrp kernel-2.6.35.fc14.orig/drivers/hid/hid-apple.c kernel-2.6.35.fc14.new/drivers/hid/hid-apple.c
|
||||
--- kernel-2.6.35.fc14.orig/drivers/hid/hid-apple.c 2010-11-12 12:35:49.153805968 +0100
|
||||
+++ kernel-2.6.35.fc14.new/drivers/hid/hid-apple.c 2010-11-12 12:48:35.689816431 +0100
|
||||
@@ -59,6 +59,27 @@ struct apple_key_translation {
|
||||
u8 flags;
|
||||
};
|
||||
|
||||
+static const struct apple_key_translation macbookair_fn_keys[] = {
|
||||
+ { KEY_BACKSPACE, KEY_DELETE },
|
||||
+ { KEY_ENTER, KEY_INSERT },
|
||||
+ { KEY_F1, KEY_BRIGHTNESSDOWN, APPLE_FLAG_FKEY },
|
||||
+ { KEY_F2, KEY_BRIGHTNESSUP, APPLE_FLAG_FKEY },
|
||||
+ { KEY_F3, KEY_SCALE, APPLE_FLAG_FKEY },
|
||||
+ { KEY_F4, KEY_DASHBOARD, APPLE_FLAG_FKEY },
|
||||
+ { KEY_F6, KEY_PREVIOUSSONG, APPLE_FLAG_FKEY },
|
||||
+ { KEY_F7, KEY_PLAYPAUSE, APPLE_FLAG_FKEY },
|
||||
+ { KEY_F8, KEY_NEXTSONG, APPLE_FLAG_FKEY },
|
||||
+ { KEY_F9, KEY_MUTE, APPLE_FLAG_FKEY },
|
||||
+ { KEY_F10, KEY_VOLUMEDOWN, APPLE_FLAG_FKEY },
|
||||
+ { KEY_F11, KEY_VOLUMEUP, APPLE_FLAG_FKEY },
|
||||
+ { KEY_F12, KEY_EJECTCD, APPLE_FLAG_FKEY },
|
||||
+ { KEY_UP, KEY_PAGEUP },
|
||||
+ { KEY_DOWN, KEY_PAGEDOWN },
|
||||
+ { KEY_LEFT, KEY_HOME },
|
||||
+ { KEY_RIGHT, KEY_END },
|
||||
+ { }
|
||||
+};
|
||||
+
|
||||
static const struct apple_key_translation apple_fn_keys[] = {
|
||||
{ KEY_BACKSPACE, KEY_DELETE },
|
||||
{ KEY_ENTER, KEY_INSERT },
|
||||
@@ -157,10 +178,14 @@ static int hidinput_apple_event(struct h
|
||||
if (fnmode) {
|
||||
int do_translate;
|
||||
|
||||
- trans = apple_find_translation((hid->product < 0x21d ||
|
||||
+ if(hid->product >= 0x023f && hid->product <= 0x0244 ) {
|
||||
+ trans = apple_find_translation(macbookair_fn_keys, usage->code);
|
||||
+ } else {
|
||||
+ trans = apple_find_translation((hid->product < 0x21d ||
|
||||
hid->product >= 0x300) ?
|
||||
powerbook_fn_keys : apple_fn_keys,
|
||||
usage->code);
|
||||
+ }
|
||||
if (trans) {
|
||||
if (test_bit(usage->code, asc->pressed_fn))
|
||||
do_translate = 1;
|
||||
@@ -435,6 +460,18 @@ static const struct hid_device_id apple_
|
||||
.driver_data = APPLE_HAS_FN | APPLE_ISO_KEYBOARD },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_JIS),
|
||||
.driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS },
|
||||
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4_ANSI),
|
||||
+ .driver_data = APPLE_HAS_FN },
|
||||
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4_ISO),
|
||||
+ .driver_data = APPLE_HAS_FN | APPLE_ISO_KEYBOARD },
|
||||
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4_JIS),
|
||||
+ .driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS },
|
||||
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4A_ANSI),
|
||||
+ .driver_data = APPLE_HAS_FN },
|
||||
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4A_ISO),
|
||||
+ .driver_data = APPLE_HAS_FN | APPLE_ISO_KEYBOARD },
|
||||
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4A_JIS),
|
||||
+ .driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS },
|
||||
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI),
|
||||
.driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN },
|
||||
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO),
|
||||
diff -uNrp kernel-2.6.35.fc14.orig/drivers/hid/hid-core.c kernel-2.6.35.fc14.new/drivers/hid/hid-core.c
|
||||
--- kernel-2.6.35.fc14.orig/drivers/hid/hid-core.c 2010-11-12 12:35:49.153805968 +0100
|
||||
+++ kernel-2.6.35.fc14.new/drivers/hid/hid-core.c 2010-11-12 12:48:35.690816373 +0100
|
||||
@@ -1273,6 +1273,12 @@ static const struct hid_device_id hid_bl
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_ANSI) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_ISO) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_JIS) },
|
||||
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4_ANSI) },
|
||||
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4_ISO) },
|
||||
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4_JIS) },
|
||||
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4A_ANSI) },
|
||||
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4A_ISO) },
|
||||
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4A_JIS) },
|
||||
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI) },
|
||||
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO) },
|
||||
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_JIS) },
|
||||
@@ -1738,6 +1744,12 @@ static const struct hid_device_id hid_mo
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_ANSI) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_ISO) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_JIS) },
|
||||
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4_ANSI) },
|
||||
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4_ISO) },
|
||||
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4_JIS) },
|
||||
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4A_ANSI) },
|
||||
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4A_ISO) },
|
||||
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4A_JIS) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY) },
|
||||
{ }
|
||||
diff -uNrp kernel-2.6.35.fc14.orig/drivers/hid/hid-ids.h kernel-2.6.35.fc14.new/drivers/hid/hid-ids.h
|
||||
--- kernel-2.6.35.fc14.orig/drivers/hid/hid-ids.h 2010-11-12 12:35:49.153805968 +0100
|
||||
+++ kernel-2.6.35.fc14.new/drivers/hid/hid-ids.h 2010-11-12 12:48:35.691816314 +0100
|
||||
@@ -93,6 +93,12 @@
|
||||
#define USB_DEVICE_ID_APPLE_WELLSPRING3_ANSI 0x0236
|
||||
#define USB_DEVICE_ID_APPLE_WELLSPRING3_ISO 0x0237
|
||||
#define USB_DEVICE_ID_APPLE_WELLSPRING3_JIS 0x0238
|
||||
+#define USB_DEVICE_ID_APPLE_WELLSPRING4_ANSI 0x023f
|
||||
+#define USB_DEVICE_ID_APPLE_WELLSPRING4_ISO 0x0240
|
||||
+#define USB_DEVICE_ID_APPLE_WELLSPRING4_JIS 0x0241
|
||||
+#define USB_DEVICE_ID_APPLE_WELLSPRING4A_ANSI 0x0242
|
||||
+#define USB_DEVICE_ID_APPLE_WELLSPRING4A_ISO 0x0243
|
||||
+#define USB_DEVICE_ID_APPLE_WELLSPRING4A_JIS 0x0244
|
||||
#define USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI 0x0239
|
||||
#define USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO 0x023a
|
||||
#define USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_JIS 0x023b
|
||||
diff -uNrp kernel-2.6.35.fc14.orig/drivers/hwmon/applesmc.c kernel-2.6.35.fc14.new/drivers/hwmon/applesmc.c
|
||||
--- kernel-2.6.35.fc14.orig/drivers/hwmon/applesmc.c 2010-11-12 12:35:49.618776754 +0100
|
||||
+++ kernel-2.6.35.fc14.new/drivers/hwmon/applesmc.c 2010-11-13 12:25:05.810472278 +0100
|
||||
@@ -162,6 +162,10 @@ static const char *temperature_sensors_s
|
||||
/* Set 22: MacBook Pro 7,1 */
|
||||
{ "TB0T", "TB1T", "TB2T", "TC0D", "TC0P", "TN0D", "TN0P", "TN0S",
|
||||
"TN1D", "TN1F", "TN1G", "TN1S", "Th1H", "Ts0P", "Ts0S", NULL },
|
||||
+/* Set 23: MacBook Air 3,1 */
|
||||
+ { "TB0T", "TB1T", "TB2T", "TC0D", "TC0E", "TC0P", "TC1E", "TCZ3",
|
||||
+ "TCZ4", "TCZ5", "TG0E", "TG1E", "TG2E", "TGZ3", "TGZ4", "TGZ5",
|
||||
+ "TH0F", "TH0O", "TM0P" },
|
||||
};
|
||||
|
||||
/* List of keys used to read/write fan speeds */
|
||||
@@ -1524,11 +1528,21 @@ static __initdata struct dmi_match_data
|
||||
{ .accelerometer = 1, .light = 1, .temperature_set = 21 },
|
||||
/* MacBook Pro 7,1: accelerometer, backlight and temperature set 22 */
|
||||
{ .accelerometer = 1, .light = 1, .temperature_set = 22 },
|
||||
+/* MacBook Air 3,1: accelerometer, backlight and temperature set 15 */
|
||||
+ { .accelerometer = 0, .light = 0, .temperature_set = 23 },
|
||||
};
|
||||
|
||||
/* Note that DMI_MATCH(...,"MacBook") will match "MacBookPro1,1".
|
||||
* So we need to put "Apple MacBook Pro" before "Apple MacBook". */
|
||||
static __initdata struct dmi_system_id applesmc_whitelist[] = {
|
||||
+ { applesmc_dmi_match, "Apple MacBook Air 3", {
|
||||
+ DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
|
||||
+ DMI_MATCH(DMI_PRODUCT_NAME, "MacBookAir3,2") },
|
||||
+ &applesmc_dmi_data[23]},
|
||||
+ { applesmc_dmi_match, "Apple MacBook Air 3", {
|
||||
+ DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
|
||||
+ DMI_MATCH(DMI_PRODUCT_NAME, "MacBookAir3,1") },
|
||||
+ &applesmc_dmi_data[23]},
|
||||
{ applesmc_dmi_match, "Apple MacBook Air 2", {
|
||||
DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "MacBookAir2") },
|
||||
diff -uNrp kernel-2.6.35.fc14.orig/drivers/input/mouse/bcm5974.c kernel-2.6.35.fc14.new/drivers/input/mouse/bcm5974.c
|
||||
--- kernel-2.6.35.fc14.orig/drivers/input/mouse/bcm5974.c 2010-11-12 12:35:50.004752503 +0100
|
||||
+++ kernel-2.6.35.fc14.new/drivers/input/mouse/bcm5974.c 2010-11-12 12:48:13.140136374 +0100
|
||||
@@ -55,6 +55,14 @@
|
||||
#define USB_DEVICE_ID_APPLE_WELLSPRING3_ANSI 0x0236
|
||||
#define USB_DEVICE_ID_APPLE_WELLSPRING3_ISO 0x0237
|
||||
#define USB_DEVICE_ID_APPLE_WELLSPRING3_JIS 0x0238
|
||||
+/* MacbookAir3,2 (unibody), aka wellspring5 */
|
||||
+#define USB_DEVICE_ID_APPLE_WELLSPRING4_ANSI 0x023f
|
||||
+#define USB_DEVICE_ID_APPLE_WELLSPRING4_ISO 0x0240
|
||||
+#define USB_DEVICE_ID_APPLE_WELLSPRING4_JIS 0x0241
|
||||
+/* MacbookAir3,1 (unibody), aka wellspring4 */
|
||||
+#define USB_DEVICE_ID_APPLE_WELLSPRING4A_ANSI 0x0242
|
||||
+#define USB_DEVICE_ID_APPLE_WELLSPRING4A_ISO 0x0243
|
||||
+#define USB_DEVICE_ID_APPLE_WELLSPRING4A_JIS 0x0244
|
||||
|
||||
#define BCM5974_DEVICE(prod) { \
|
||||
.match_flags = (USB_DEVICE_ID_MATCH_DEVICE | \
|
||||
@@ -80,6 +88,14 @@ static const struct usb_device_id bcm597
|
||||
BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING3_ANSI),
|
||||
BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING3_ISO),
|
||||
BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING3_JIS),
|
||||
+ /* MacbookAir3,2 */
|
||||
+ BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING4_ANSI),
|
||||
+ BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING4_ISO),
|
||||
+ BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING4_JIS),
|
||||
+ /* MacbookAir3,1 */
|
||||
+ BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING4A_ANSI),
|
||||
+ BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING4A_ISO),
|
||||
+ BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING4A_JIS),
|
||||
/* Terminating entry */
|
||||
{}
|
||||
};
|
||||
@@ -234,6 +250,30 @@ static const struct bcm5974_config bcm59
|
||||
{ DIM_X, DIM_X / SN_COORD, -4460, 5166 },
|
||||
{ DIM_Y, DIM_Y / SN_COORD, -75, 6700 }
|
||||
},
|
||||
+ {
|
||||
+ USB_DEVICE_ID_APPLE_WELLSPRING4_ANSI,
|
||||
+ USB_DEVICE_ID_APPLE_WELLSPRING4_ISO,
|
||||
+ USB_DEVICE_ID_APPLE_WELLSPRING4_JIS,
|
||||
+ HAS_INTEGRATED_BUTTON,
|
||||
+ 0x84, sizeof(struct bt_data),
|
||||
+ 0x81, TYPE2, FINGER_TYPE2, FINGER_TYPE2 + SIZEOF_ALL_FINGERS,
|
||||
+ { DIM_PRESSURE, DIM_PRESSURE / SN_PRESSURE, 0, 300 },
|
||||
+ { DIM_WIDTH, DIM_WIDTH / SN_WIDTH, 0, 2048 },
|
||||
+ { DIM_X, DIM_X / SN_COORD, -4460, 5166 },
|
||||
+ { DIM_Y, DIM_Y / SN_COORD, -75, 6700 }
|
||||
+ },
|
||||
+ {
|
||||
+ USB_DEVICE_ID_APPLE_WELLSPRING4A_ANSI,
|
||||
+ USB_DEVICE_ID_APPLE_WELLSPRING4A_ISO,
|
||||
+ USB_DEVICE_ID_APPLE_WELLSPRING4A_JIS,
|
||||
+ HAS_INTEGRATED_BUTTON,
|
||||
+ 0x84, sizeof(struct bt_data),
|
||||
+ 0x81, TYPE2, FINGER_TYPE2, FINGER_TYPE2 + SIZEOF_ALL_FINGERS,
|
||||
+ { DIM_PRESSURE, DIM_PRESSURE / SN_PRESSURE, 0, 300 },
|
||||
+ { DIM_WIDTH, DIM_WIDTH / SN_WIDTH, 0, 2048 },
|
||||
+ { DIM_X, DIM_X / SN_COORD, -4460, 5166 },
|
||||
+ { DIM_Y, DIM_Y / SN_COORD, -75, 6700 }
|
||||
+ },
|
||||
{}
|
||||
};
|
||||
|
||||
diff -uNrp kernel-2.6.35.fc14.orig/drivers/video/backlight/mbp_nvidia_bl.c kernel-2.6.35.fc14.new/drivers/video/backlight/mbp_nvidia_bl.c
|
||||
--- kernel-2.6.35.fc14.orig/drivers/video/backlight/mbp_nvidia_bl.c 2010-11-12 12:35:49.159805591 +0100
|
||||
+++ kernel-2.6.35.fc14.new/drivers/video/backlight/mbp_nvidia_bl.c 2010-11-12 12:48:47.412131884 +0100
|
||||
@@ -335,6 +335,24 @@ static const struct dmi_system_id __init
|
||||
},
|
||||
.driver_data = (void *)&nvidia_chipset_data,
|
||||
},
|
||||
+ {
|
||||
+ .callback = mbp_dmi_match,
|
||||
+ .ident = "MacBookAir 3,1",
|
||||
+ .matches = {
|
||||
+ DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
|
||||
+ DMI_MATCH(DMI_PRODUCT_NAME, "MacBookAir3,1"),
|
||||
+ },
|
||||
+ .driver_data = (void *)&nvidia_chipset_data,
|
||||
+ },
|
||||
+ {
|
||||
+ .callback = mbp_dmi_match,
|
||||
+ .ident = "MacBookAir 3,2",
|
||||
+ .matches = {
|
||||
+ DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
|
||||
+ DMI_MATCH(DMI_PRODUCT_NAME, "MacBookAir3,2"),
|
||||
+ },
|
||||
+ .driver_data = (void *)&nvidia_chipset_data,
|
||||
+ },
|
||||
{ }
|
||||
};
|
||||
|
||||
diff -uNrp kernel-2.6.35.fc14.orig/sound/pci/hda/patch_cirrus.c kernel-2.6.35.fc14.new/sound/pci/hda/patch_cirrus.c
|
||||
--- kernel-2.6.35.fc14.orig/sound/pci/hda/patch_cirrus.c 2010-11-12 12:35:49.005815268 +0100
|
||||
+++ kernel-2.6.35.fc14.new/sound/pci/hda/patch_cirrus.c 2010-11-12 12:48:40.379542432 +0100
|
||||
@@ -1139,6 +1139,7 @@ static const char *cs420x_models[CS420X_
|
||||
static struct snd_pci_quirk cs420x_cfg_tbl[] = {
|
||||
SND_PCI_QUIRK(0x10de, 0xcb79, "MacBookPro 5,5", CS420X_MBP55),
|
||||
SND_PCI_QUIRK(0x8086, 0x7270, "IMac 27 Inch", CS420X_IMAC27),
|
||||
+ SND_PCI_QUIRK(0x10de, 0x0d94, "MacBookAir 3,1(2)", CS420X_MBP55),
|
||||
{} /* terminator */
|
||||
};
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
From: Xiaotian Feng <dfeng@redhat.com>
|
||||
Date: Mon, 29 Nov 2010 09:03:55 +0000 (+0100)
|
||||
Subject: block: check for proper length of iov entries earlier in blk_rq_map_user_iov()
|
||||
X-Git-Tag: v2.6.37-rc7~10^2~5
|
||||
X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=54787556
|
||||
|
||||
block: check for proper length of iov entries earlier in blk_rq_map_user_iov()
|
||||
|
||||
commit 9284bcf checks for proper length of iov entries in
|
||||
blk_rq_map_user_iov(). But if the map is unaligned, kernel
|
||||
will break out the loop without checking for the proper length.
|
||||
So we need to check the proper length before the unalign check.
|
||||
|
||||
Signed-off-by: Xiaotian Feng <dfeng@redhat.com>
|
||||
Cc: stable@kernel.org
|
||||
Signed-off-by: Jens Axboe <jaxboe@fusionio.com>
|
||||
---
|
||||
|
||||
diff --git a/block/blk-map.c b/block/blk-map.c
|
||||
index 5d5dbe4..e663ac2 100644
|
||||
--- a/block/blk-map.c
|
||||
+++ b/block/blk-map.c
|
||||
@@ -201,12 +201,13 @@ int blk_rq_map_user_iov(struct request_queue *q, struct request *rq,
|
||||
for (i = 0; i < iov_count; i++) {
|
||||
unsigned long uaddr = (unsigned long)iov[i].iov_base;
|
||||
|
||||
+ if (!iov[i].iov_len)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
if (uaddr & queue_dma_alignment(q)) {
|
||||
unaligned = 1;
|
||||
break;
|
||||
}
|
||||
- if (!iov[i].iov_len)
|
||||
- return -EINVAL;
|
||||
}
|
||||
|
||||
if (unaligned || (q->dma_pad_mask & len) || map_data)
|
|
@ -0,0 +1,65 @@
|
|||
From 8f172904b45a6b530eaa345b23956682629bddee Mon Sep 17 00:00:00 2001
|
||||
From: Josef Bacik <josef@redhat.com>
|
||||
Date: Fri, 22 Oct 2010 15:26:53 -0400
|
||||
Subject: Btrfs: fix error handling in btrfs_get_sb
|
||||
|
||||
If we failed to find the root subvol id, or the subvol=<name>, we would
|
||||
deactivate the locked super and close the devices. The problem is at this point
|
||||
we have gotten the SB all setup, which includes setting super_operations, so
|
||||
when we'd deactiveate the super, we'd do a close_ctree() which closes the
|
||||
devices, so we'd end up closing the devices twice. So if you do something like
|
||||
this
|
||||
|
||||
mount /dev/sda1 /mnt/test1
|
||||
mount /dev/sda1 /mnt/test2 -o subvol=xxx
|
||||
umount /mnt/test1
|
||||
|
||||
it would blow up (if subvol xxx doesn't exist). This patch fixes that problem.
|
||||
Thanks,
|
||||
|
||||
Signed-off-by: Josef Bacik <josef@redhat.com>
|
||||
---
|
||||
fs/btrfs/super.c | 7 +++----
|
||||
1 files changed, 3 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c
|
||||
index f2393b3..c246f25 100644
|
||||
--- a/fs/btrfs/super.c
|
||||
+++ b/fs/btrfs/super.c
|
||||
@@ -629,7 +629,7 @@ static int btrfs_get_sb(struct file_system_type *fs_type, int flags,
|
||||
if (IS_ERR(root)) {
|
||||
error = PTR_ERR(root);
|
||||
deactivate_locked_super(s);
|
||||
- goto error;
|
||||
+ goto error_free_subvol_name;
|
||||
}
|
||||
/* if they gave us a subvolume name bind mount into that */
|
||||
if (strcmp(subvol_name, ".")) {
|
||||
@@ -643,14 +643,14 @@ static int btrfs_get_sb(struct file_system_type *fs_type, int flags,
|
||||
deactivate_locked_super(s);
|
||||
error = PTR_ERR(new_root);
|
||||
dput(root);
|
||||
- goto error_close_devices;
|
||||
+ goto error_free_subvol_name;
|
||||
}
|
||||
if (!new_root->d_inode) {
|
||||
dput(root);
|
||||
dput(new_root);
|
||||
deactivate_locked_super(s);
|
||||
error = -ENXIO;
|
||||
- goto error_close_devices;
|
||||
+ goto error_free_subvol_name;
|
||||
}
|
||||
dput(root);
|
||||
root = new_root;
|
||||
@@ -668,7 +668,6 @@ error_close_devices:
|
||||
btrfs_close_devices(fs_devices);
|
||||
error_free_subvol_name:
|
||||
kfree(subvol_name);
|
||||
-error:
|
||||
return error;
|
||||
}
|
||||
|
||||
--
|
||||
1.7.3.3
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
From 3d07b06c5d62e98b46ef21980e5c2a904990149f Mon Sep 17 00:00:00 2001
|
||||
From: Kyle McMartin <kyle@mcmartin.ca>
|
||||
Date: Fri, 10 Dec 2010 10:32:29 -0500
|
||||
Subject: [PATCH] Btrfs - fix race between btrfs_get_sb() and umount
|
||||
|
||||
When mounting a btrfs file system btrfs_test_super() may attempt to
|
||||
use sb->s_fs_info, the btrfs root, of a super block that is going away
|
||||
and that has had the btrfs root set to NULL in its ->put_super(). But
|
||||
if the super block is going away it cannot be an existing super block
|
||||
so we can return false in this case.
|
||||
|
||||
Signed-off-by: Ian Kent <raven@themaw.net>
|
||||
Signed-off-by: Chris Mason <chris.mason@oracle.com>
|
||||
|
||||
Conflicts:
|
||||
|
||||
fs/btrfs/super.c
|
||||
---
|
||||
fs/btrfs/super.c | 6 ++++++
|
||||
1 files changed, 6 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c
|
||||
index 89e299f..f4a4dd3 100644
|
||||
--- a/fs/btrfs/super.c
|
||||
+++ b/fs/btrfs/super.c
|
||||
@@ -551,6 +551,12 @@ static int btrfs_test_super(struct super_block *s, void *data)
|
||||
struct btrfs_root *test_root = data;
|
||||
struct btrfs_root *root = btrfs_sb(s);
|
||||
|
||||
+ /*
|
||||
+ * If this super block is going away, return false as it
|
||||
+ * can't match as an existing super block.
|
||||
+ */
|
||||
+ if (!atomic_read(&s->s_active))
|
||||
+ return 0;
|
||||
return root->fs_info->fs_devices == test_root->fs_info->fs_devices;
|
||||
}
|
||||
|
||||
--
|
||||
1.7.3.3
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
From: Josef Bacik <josef@redhat.com>
|
||||
Date: Mon, 22 Nov 2010 18:50:32 +0000 (+0000)
|
||||
Subject: Btrfs: fix typo in fallocate to make it honor actual size
|
||||
X-Git-Tag: v2.6.37-rc4~6^2~7
|
||||
X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=55a61d1d06a3dc443d0db8aaa613365dcb83b98a
|
||||
|
||||
Btrfs: fix typo in fallocate to make it honor actual size
|
||||
|
||||
[ Trivial backport to 2.6.35/2.6.36 ]
|
||||
|
||||
There is a typo in __btrfs_prealloc_file_range() where we set the i_size to
|
||||
actual_len/cur_offset, and then just set it to cur_offset again, and do the same
|
||||
with btrfs_ordered_update_i_size(). This fixes it back to keeping i_size in a
|
||||
local variable and then updating i_size properly. Tested this with
|
||||
|
||||
xfs_io -F -f -c "falloc 0 1" -c "pwrite 0 1" foo
|
||||
|
||||
stat'ing foo gives us a size of 1 instead of 4096 like it was. Thanks,
|
||||
|
||||
Signed-off-by: Josef Bacik <josef@redhat.com>
|
||||
Signed-off-by: Chris Mason <chris.mason@oracle.com>
|
||||
---
|
||||
|
||||
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
|
||||
index 37cc177..0058fb3 100644
|
||||
--- a/fs/btrfs/inode.c
|
||||
+++ b/fs/btrfs/inode.c
|
||||
@@ -7002,6 +7002,7 @@ static int __btrfs_prealloc_file_range(struct inode *inode, int mode,
|
||||
struct btrfs_root *root = BTRFS_I(inode)->root;
|
||||
struct btrfs_key ins;
|
||||
u64 cur_offset = start;
|
||||
+ u64 i_size;
|
||||
int ret = 0;
|
||||
|
||||
while (num_bytes > 0) {
|
||||
@@ -7043,11 +7044,11 @@ static int __btrfs_prealloc_file_range(struct inode *inode, int mode,
|
||||
(actual_len > inode->i_size) &&
|
||||
(cur_offset > inode->i_size)) {
|
||||
if (cur_offset > actual_len)
|
||||
- i_size_write(inode, actual_len);
|
||||
+ i_size = actual_len;
|
||||
else
|
||||
- i_size_write(inode, cur_offset);
|
||||
- i_size_write(inode, cur_offset);
|
||||
- btrfs_ordered_update_i_size(inode, cur_offset, NULL);
|
||||
+ i_size = cur_offset;
|
||||
+ i_size_write(inode, i_size);
|
||||
+ btrfs_ordered_update_i_size(inode, i_size, NULL);
|
||||
}
|
||||
|
||||
ret = btrfs_update_inode(trans, root, inode);
|
|
@ -0,0 +1,117 @@
|
|||
From 2049a8887f699650cd66c3da220e84d5c140c546 Mon Sep 17 00:00:00 2001
|
||||
From: Kyle McMartin <kyle@mcmartin.ca>
|
||||
Date: Fri, 10 Dec 2010 10:09:15 -0500
|
||||
Subject: [PATCH] Btrfs: setup blank root and fs_info for mount time
|
||||
|
||||
There is a problem with how we use sget, it searches through the list of supers
|
||||
attached to the fs_type looking for a super with the same fs_devices as what
|
||||
we're trying to mount. This depends on sb->s_fs_info being filled, but we don't
|
||||
fill that in until we get to btrfs_fill_super, so we could hit supers on the
|
||||
fs_type super list that have a null s_fs_info. In order to fix that we need to
|
||||
go ahead and setup a blank root with a blank fs_info to hold fs_devices, that
|
||||
way our test will work out right and then we can set s_fs_info in
|
||||
btrfs_set_super, and then open_ctree will simply use our pre-allocated root and
|
||||
fs_info when setting everything up. Thanks,
|
||||
|
||||
Signed-off-by: Josef Bacik <josef@redhat.com>
|
||||
Signed-off-by: Chris Mason <chris.mason@oracle.com>
|
||||
|
||||
Conflicts:
|
||||
|
||||
fs/btrfs/super.c
|
||||
---
|
||||
fs/btrfs/disk-io.c | 6 ++----
|
||||
fs/btrfs/super.c | 34 +++++++++++++++++++++++++++++++---
|
||||
2 files changed, 33 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
|
||||
index 34f7c37..b6c3dad 100644
|
||||
--- a/fs/btrfs/disk-io.c
|
||||
+++ b/fs/btrfs/disk-io.c
|
||||
@@ -1539,10 +1539,8 @@ struct btrfs_root *open_ctree(struct super_block *sb,
|
||||
GFP_NOFS);
|
||||
struct btrfs_root *csum_root = kzalloc(sizeof(struct btrfs_root),
|
||||
GFP_NOFS);
|
||||
- struct btrfs_root *tree_root = kzalloc(sizeof(struct btrfs_root),
|
||||
- GFP_NOFS);
|
||||
- struct btrfs_fs_info *fs_info = kzalloc(sizeof(*fs_info),
|
||||
- GFP_NOFS);
|
||||
+ struct btrfs_root *tree_root = btrfs_sb(sb);
|
||||
+ struct btrfs_fs_info *fs_info = tree_root->fs_info;
|
||||
struct btrfs_root *chunk_root = kzalloc(sizeof(struct btrfs_root),
|
||||
GFP_NOFS);
|
||||
struct btrfs_root *dev_root = kzalloc(sizeof(struct btrfs_root),
|
||||
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c
|
||||
index f2393b3..89e299f 100644
|
||||
--- a/fs/btrfs/super.c
|
||||
+++ b/fs/btrfs/super.c
|
||||
@@ -548,12 +548,20 @@ static int btrfs_show_options(struct seq_file *seq, struct vfsmount *vfs)
|
||||
|
||||
static int btrfs_test_super(struct super_block *s, void *data)
|
||||
{
|
||||
- struct btrfs_fs_devices *test_fs_devices = data;
|
||||
+ struct btrfs_root *test_root = data;
|
||||
struct btrfs_root *root = btrfs_sb(s);
|
||||
|
||||
- return root->fs_info->fs_devices == test_fs_devices;
|
||||
+ return root->fs_info->fs_devices == test_root->fs_info->fs_devices;
|
||||
}
|
||||
|
||||
+static int btrfs_set_super(struct super_block *s, void *data)
|
||||
+{
|
||||
+ s->s_fs_info = data;
|
||||
+
|
||||
+ return set_anon_super(s, data);
|
||||
+}
|
||||
+
|
||||
+
|
||||
/*
|
||||
* Find a superblock for the given device / mount point.
|
||||
*
|
||||
@@ -567,6 +575,8 @@ static int btrfs_get_sb(struct file_system_type *fs_type, int flags,
|
||||
struct super_block *s;
|
||||
struct dentry *root;
|
||||
struct btrfs_fs_devices *fs_devices = NULL;
|
||||
+ struct btrfs_root *tree_root = NULL;
|
||||
+ struct btrfs_fs_info *fs_info = NULL;
|
||||
fmode_t mode = FMODE_READ;
|
||||
char *subvol_name = NULL;
|
||||
u64 subvol_objectid = 0;
|
||||
@@ -595,8 +605,24 @@ static int btrfs_get_sb(struct file_system_type *fs_type, int flags,
|
||||
goto error_close_devices;
|
||||
}
|
||||
|
||||
+ /*
|
||||
+ * Setup a dummy root and fs_info for test/set super. This is because
|
||||
+ * we don't actually fill this stuff out until open_ctree, but we need
|
||||
+ * it for searching for existing supers, so this lets us do that and
|
||||
+ * then open_ctree will properly initialize everything later.
|
||||
+ */
|
||||
+ fs_info = kzalloc(sizeof(struct btrfs_fs_info), GFP_NOFS);
|
||||
+ tree_root = kzalloc(sizeof(struct btrfs_root), GFP_NOFS);
|
||||
+ if (!fs_info || !tree_root) {
|
||||
+ error = -ENOMEM;
|
||||
+ goto error_close_devices;
|
||||
+ }
|
||||
+ fs_info->tree_root = tree_root;
|
||||
+ fs_info->fs_devices = fs_devices;
|
||||
+ tree_root->fs_info = fs_info;
|
||||
+
|
||||
bdev = fs_devices->latest_bdev;
|
||||
- s = sget(fs_type, btrfs_test_super, set_anon_super, fs_devices);
|
||||
+ s = sget(fs_type, btrfs_test_super, btrfs_set_super, tree_root);
|
||||
if (IS_ERR(s))
|
||||
goto error_s;
|
||||
|
||||
@@ -666,6 +692,8 @@ error_s:
|
||||
error = PTR_ERR(s);
|
||||
error_close_devices:
|
||||
btrfs_close_devices(fs_devices);
|
||||
+ kfree(fs_info);
|
||||
+ kfree(tree_root);
|
||||
error_free_subvol_name:
|
||||
kfree(subvol_name);
|
||||
error:
|
||||
--
|
||||
1.7.3.3
|
||||
|
|
@ -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
|
||||
|
||||
#
|
||||
|
@ -2366,6 +2367,7 @@ CONFIG_VIDEO_EM28XX_DVB=m
|
|||
CONFIG_VIDEO_CX231XX=m
|
||||
CONFIG_VIDEO_CX231XX_ALSA=m
|
||||
CONFIG_VIDEO_CX231XX_DVB=m
|
||||
CONFIG_VIDEO_CX231XX_RC=y
|
||||
CONFIG_VIDEO_HEXIUM_ORION=m
|
||||
CONFIG_VIDEO_HEXIUM_GEMINI=m
|
||||
CONFIG_VIDEO_IVTV=m
|
||||
|
@ -2380,6 +2382,7 @@ CONFIG_VIDEO_SAA6588=m
|
|||
CONFIG_VIDEO_SAA7134=m
|
||||
CONFIG_VIDEO_SAA7134_ALSA=m
|
||||
CONFIG_VIDEO_SAA7134_DVB=m
|
||||
CONFIG_VIDEO_SAA7134_RC=y
|
||||
CONFIG_VIDEO_STRADIS=m
|
||||
CONFIG_VIDEO_USBVISION=m
|
||||
CONFIG_VIDEO_W9966=m
|
||||
|
@ -2394,6 +2397,11 @@ CONFIG_VIDEO_ZORAN_ZR36060=m
|
|||
CONFIG_VIDEO_FB_IVTV=m
|
||||
CONFIG_VIDEO_SAA7164=m
|
||||
CONFIG_VIDEO_TLG2300=m
|
||||
# CONFIG_VIDEO_TIMBERDALE is not set
|
||||
CONFIG_VIDEO_SR030PC30=m
|
||||
# Doesn't build on 2.6.35
|
||||
# CONFIG_VIDEO_VIA_CAMERA is not set
|
||||
# CONFIG_VIDEO_NOON010PC30 is not set
|
||||
|
||||
CONFIG_USB_VIDEO_CLASS=m
|
||||
CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y
|
||||
|
@ -2409,6 +2417,7 @@ CONFIG_MEDIA_ATTACH=y
|
|||
CONFIG_MEDIA_TUNER_CUSTOMISE=y
|
||||
CONFIG_MEDIA_TUNER_SIMPLE=m
|
||||
CONFIG_MEDIA_TUNER_TDA8290=m
|
||||
CONFIG_MEDIA_TUNER_TDA18218=m
|
||||
CONFIG_MEDIA_TUNER_TEA5761=m
|
||||
CONFIG_MEDIA_TUNER_TEA5767=m
|
||||
CONFIG_MEDIA_TUNER_MT20XX=m
|
||||
|
@ -2491,6 +2500,10 @@ CONFIG_DVB_ATBM8830=m
|
|||
CONFIG_DVB_TDA665x=m
|
||||
CONFIG_DVB_STV0299=m
|
||||
CONFIG_DVB_MB86A16=m
|
||||
CONFIG_DVB_USB_LME2510=m
|
||||
CONFIG_DVB_S5H1432=m
|
||||
CONFIG_DVB_MB86A20S=m
|
||||
CONFIG_DVB_IX2505V=m
|
||||
|
||||
#
|
||||
# Supported Frontend Modules
|
||||
|
@ -2517,6 +2530,7 @@ CONFIG_DVB_LGS8GL5=m
|
|||
CONFIG_DVB_DUMMY_FE=m
|
||||
CONFIG_DVB_FIREDTV=m
|
||||
CONFIG_DVB_NGENE=m
|
||||
# CONFIG_DVB_CXD2099 is not set
|
||||
|
||||
#
|
||||
# Supported SAA7146 based PCI Adapters
|
||||
|
@ -2571,6 +2585,8 @@ CONFIG_DVB_PT1=m
|
|||
CONFIG_MANTIS_CORE=m
|
||||
CONFIG_DVB_MANTIS=m
|
||||
CONFIG_DVB_HOPPER=m
|
||||
CONFIG_DVB_USB_TECHNISAT_USB2=m
|
||||
CONFIG_DVB_DIB9000=m
|
||||
|
||||
CONFIG_VIDEO_SAA7146=m
|
||||
CONFIG_VIDEO_SAA7146_VV=m
|
||||
|
@ -2581,14 +2597,21 @@ CONFIG_VIDEO_PVRUSB2_SYSFS=y
|
|||
# CONFIG_VIDEO_PVRUSB2_DEBUGIFC is not set
|
||||
|
||||
CONFIG_RC_MAP=m
|
||||
CONFIG_RC_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_RC_LOOPBACK=m
|
||||
|
||||
CONFIG_V4L_MEM2MEM_DRIVERS=y
|
||||
# CONFIG_VIDEO_MEM2MEM_TESTDEV is not set
|
||||
|
@ -3031,6 +3054,8 @@ CONFIG_USB_GL860=m
|
|||
CONFIG_USB_GSPCA_JEILINJ=m
|
||||
CONFIG_USB_GSPCA_SPCA1528=m
|
||||
CONFIG_USB_GSPCA_SQ930X=m
|
||||
CONFIG_USB_GSPCA_KONICA=m
|
||||
CONFIG_USB_GSPCA_XIRLINK_CIT=m
|
||||
|
||||
CONFIG_USB_IBMCAM=m
|
||||
CONFIG_USB_KONICAWC=m
|
||||
|
@ -3038,6 +3063,7 @@ CONFIG_USB_KONICAWC=m
|
|||
CONFIG_USB_S2255=m
|
||||
CONFIG_USB_SE401=m
|
||||
# CONFIG_VIDEO_SH_MOBILE_CEU is not set
|
||||
# CONFIG_VIDEO_SH_MOBILE_CSI2 is not set
|
||||
# CONFIG_USB_STV680 is not set
|
||||
# CONFIG_USB_SN9C102 is not set
|
||||
CONFIG_USB_ZR364XX=m
|
||||
|
@ -3052,6 +3078,9 @@ CONFIG_SOC_CAMERA_OV772X=m
|
|||
CONFIG_SOC_CAMERA_MT9T112=m
|
||||
CONFIG_SOC_CAMERA_RJ54N1=m
|
||||
CONFIG_SOC_CAMERA_OV9640=m
|
||||
CONFIG_SOC_CAMERA_IMX074=m
|
||||
CONFIG_SOC_CAMERA_OV6650=m
|
||||
CONFIG_SOC_CAMERA_OV2640=m
|
||||
|
||||
#
|
||||
# USB Network adaptors
|
||||
|
@ -3321,7 +3350,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
|
||||
|
@ -3420,6 +3450,18 @@ CONFIG_NFSD_V3=y
|
|||
CONFIG_NFSD_V3_ACL=y
|
||||
CONFIG_NFSD_V4=y
|
||||
CONFIG_NFS_FSCACHE=y
|
||||
# Enable pNFS
|
||||
CONFIG_PNFS=y
|
||||
CONFIG_PNFSD=y
|
||||
CONFIG_PNFSD_LOCAL_EXPORT=y
|
||||
CONFIG_SPNFS=y
|
||||
CONFIG_SPNFS_LAYOUTSEGMENTS=y
|
||||
CONFIG_SPNFS_BLOCK=y
|
||||
CONFIG_PNFS_OBJLAYOUT=m
|
||||
CONFIG_PNFS_BLOCK=m
|
||||
CONFIG_PNFS_PANLAYOUT=m
|
||||
CONFIG_PNFS_FILE_LAYOUT=m
|
||||
#
|
||||
CONFIG_LOCKD=m
|
||||
CONFIG_LOCKD_V4=y
|
||||
CONFIG_EXPORTFS=m
|
||||
|
@ -3601,6 +3643,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 +3765,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 +3785,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.
|
||||
|
@ -3851,6 +3894,7 @@ CONFIG_RADIO_ADAPTERS=y
|
|||
# CONFIG_RADIO_TYPHOON is not set
|
||||
# CONFIG_RADIO_ZOLTRIX is not set
|
||||
# CONFIG_RADIO_SAA7706H is not set
|
||||
# CONFIG_RADIO_WL1273 is not set
|
||||
|
||||
# CONFIG_SND_OPL4_LIB is not set
|
||||
# CONFIG_SND_AD1816A is not set
|
||||
|
@ -3987,8 +4031,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 +4057,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 +4219,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 +4297,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 +4313,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
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
# This file is intentionally left empty in the stock kernel. Its a nicety
|
||||
# added for those wanting to do custom rebuilds with altered config opts.
|
|
@ -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
|
||||
#
|
||||
|
@ -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
|
||||
|
@ -403,7 +403,9 @@ 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
|
||||
|
||||
CONFIG_HP_ILO=m
|
||||
|
|
|
@ -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,54 @@
|
|||
diff -up linux-2.6.35.x86_64/drivers/gpu/drm/drm_edid.c.da linux-2.6.35.x86_64/drivers/gpu/drm/drm_edid.c
|
||||
--- linux-2.6.35.x86_64/drivers/gpu/drm/drm_edid.c.da 2010-08-01 18:11:14.000000000 -0400
|
||||
+++ linux-2.6.35.x86_64/drivers/gpu/drm/drm_edid.c 2010-11-11 20:46:10.000000000 -0500
|
||||
@@ -229,7 +229,7 @@ drm_do_probe_ddc_edid(struct i2c_adapter
|
||||
.addr = DDC_ADDR,
|
||||
.flags = I2C_M_RD,
|
||||
.len = len,
|
||||
- .buf = buf + start,
|
||||
+ .buf = buf,
|
||||
}
|
||||
};
|
||||
|
||||
@@ -242,7 +242,7 @@ drm_do_probe_ddc_edid(struct i2c_adapter
|
||||
static u8 *
|
||||
drm_do_get_edid(struct drm_connector *connector, struct i2c_adapter *adapter)
|
||||
{
|
||||
- int i, j = 0;
|
||||
+ int i, j = 0, valid_extensions = 0;
|
||||
u8 *block, *new;
|
||||
|
||||
if ((block = kmalloc(EDID_LENGTH, GFP_KERNEL)) == NULL)
|
||||
@@ -269,14 +269,28 @@ drm_do_get_edid(struct drm_connector *co
|
||||
|
||||
for (j = 1; j <= block[0x7e]; j++) {
|
||||
for (i = 0; i < 4; i++) {
|
||||
- if (drm_do_probe_ddc_edid(adapter, block, j,
|
||||
- EDID_LENGTH))
|
||||
+ if (drm_do_probe_ddc_edid(adapter,
|
||||
+ block + (valid_extensions + 1) * EDID_LENGTH,
|
||||
+ j, EDID_LENGTH))
|
||||
goto out;
|
||||
- if (drm_edid_block_valid(block + j * EDID_LENGTH))
|
||||
+ if (drm_edid_block_valid(block + (valid_extensions + 1) * EDID_LENGTH)) {
|
||||
+ valid_extensions++;
|
||||
break;
|
||||
+ }
|
||||
}
|
||||
if (i == 4)
|
||||
- goto carp;
|
||||
+ printk(KERN_WARNING
|
||||
+ "%s: Ignoring invalid EDID block %d.\n",
|
||||
+ drm_get_connector_name(connector), j);
|
||||
+ }
|
||||
+
|
||||
+ if (valid_extensions != block[0x7e]) {
|
||||
+ block[EDID_LENGTH-1] += block[0x7e] - valid_extensions;
|
||||
+ block[0x7e] = valid_extensions;
|
||||
+ new = krealloc(block, (valid_extensions + 1) * EDID_LENGTH, GFP_KERNEL);
|
||||
+ if (!new)
|
||||
+ goto out;
|
||||
+ block = new;
|
||||
}
|
||||
|
||||
return block;
|
|
@ -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,70 @@
|
|||
From ab7959dd389be36c0bc63e3e883b7891d2c1bfc4 Mon Sep 17 00:00:00 2001
|
||||
From: Chris Wilson <chris@chris-wilson.co.uk>
|
||||
Date: Wed, 8 Sep 2010 09:45:11 +0100
|
||||
Subject: [PATCH] drm/i915: Disable output polling across suspend & resume
|
||||
|
||||
Suspending (especially hibernating) may take a finite amount of time,
|
||||
during which a hotplug event may trigger and we will attempt to handle
|
||||
it with inconsistent state. Disable hotplug polling around suspend and
|
||||
resume.
|
||||
|
||||
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=30070
|
||||
Reported-by: Rui Tiago Matos <tiagomatos@gmail.com>
|
||||
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
|
||||
---
|
||||
drivers/gpu/drm/i915/i915_dma.c | 2 --
|
||||
drivers/gpu/drm/i915/i915_drv.c | 11 ++++++++++-
|
||||
2 files changed, 10 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
|
||||
index ce8ff0e..c569617 100644
|
||||
--- a/drivers/gpu/drm/i915/i915_dma.c
|
||||
+++ b/drivers/gpu/drm/i915/i915_dma.c
|
||||
@@ -1334,10 +1334,8 @@ static void i915_switcheroo_set_state(struct pci_dev *pdev, enum vga_switcheroo_
|
||||
/* i915 resume handler doesn't set to D0 */
|
||||
pci_set_power_state(dev->pdev, PCI_D0);
|
||||
i915_resume(dev);
|
||||
- drm_kms_helper_poll_enable(dev);
|
||||
} else {
|
||||
printk(KERN_ERR "i915: switched off\n");
|
||||
- drm_kms_helper_poll_disable(dev);
|
||||
i915_suspend(dev, pmm);
|
||||
}
|
||||
}
|
||||
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
|
||||
index 194e0c4..3ad3ebe 100644
|
||||
--- a/drivers/gpu/drm/i915/i915_drv.c
|
||||
+++ b/drivers/gpu/drm/i915/i915_drv.c
|
||||
@@ -263,6 +263,8 @@ int i915_suspend(struct drm_device *dev, pm_message_t state)
|
||||
if (state.event == PM_EVENT_PRETHAW)
|
||||
return 0;
|
||||
|
||||
+ drm_kms_helper_poll_disable(dev);
|
||||
+
|
||||
error = i915_drm_freeze(dev);
|
||||
if (error)
|
||||
return error;
|
||||
@@ -306,12 +308,19 @@ static int i915_drm_thaw(struct drm_device *dev)
|
||||
|
||||
int i915_resume(struct drm_device *dev)
|
||||
{
|
||||
+ int ret;
|
||||
+
|
||||
if (pci_enable_device(dev->pdev))
|
||||
return -EIO;
|
||||
|
||||
pci_set_master(dev->pdev);
|
||||
|
||||
- return i915_drm_thaw(dev);
|
||||
+ ret = i915_drm_thaw(dev);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ drm_kms_helper_poll_enable(dev);
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
--
|
||||
1.7.2.3
|
||||
|
|
@ -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,21 @@
|
|||
diff -up linux-2.6.35.x86_64/drivers/gpu/drm/nouveau/nouveau_connector.c.da linux-2.6.35.x86_64/drivers/gpu/drm/nouveau/nouveau_connector.c
|
||||
--- linux-2.6.35.x86_64/drivers/gpu/drm/nouveau/nouveau_connector.c.da 2010-11-08 19:55:42.000000000 -0500
|
||||
+++ linux-2.6.35.x86_64/drivers/gpu/drm/nouveau/nouveau_connector.c 2010-11-08 19:55:49.000000000 -0500
|
||||
@@ -298,7 +298,7 @@ detect_analog:
|
||||
}
|
||||
|
||||
static enum drm_connector_status
|
||||
-nouveau_connector_detect_lvds(struct drm_connector *connector)
|
||||
+nouveau_connector_detect_lvds(struct drm_connector *connector, bool force)
|
||||
{
|
||||
struct drm_device *dev = connector->dev;
|
||||
struct drm_nouveau_private *dev_priv = dev->dev_private;
|
||||
@@ -319,7 +319,7 @@ nouveau_connector_detect_lvds(struct drm
|
||||
|
||||
/* Try retrieving EDID via DDC */
|
||||
if (!dev_priv->vbios.fp_no_ddc) {
|
||||
- status = nouveau_connector_detect(connector);
|
||||
+ status = nouveau_connector_detect(connector, force);
|
||||
if (status == connector_status_connected)
|
||||
goto out;
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
From d0301ece9e093c484f880893dc86d97848360892 Mon Sep 17 00:00:00 2001
|
||||
From: Ben Skeggs <bskeggs@redhat.com>
|
||||
Date: Fri, 19 Nov 2010 18:50:57 +1000
|
||||
Subject: [PATCH 2/2] drm-nouveau-evo-hang
|
||||
|
||||
On some GF8+ boards, the display engine will stop processing its push
|
||||
buffer if a wrap-around occurs at a certain point. The exact cause
|
||||
is not known.
|
||||
|
||||
This patch by David Dillow (rhbz#537065) is a safe enough work-around
|
||||
until it can be solved properly.
|
||||
|
||||
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
|
||||
---
|
||||
drivers/gpu/drm/nouveau/nv50_display.c | 1 +
|
||||
1 files changed, 1 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c
|
||||
index 11d366a..4e5402c 100644
|
||||
--- a/drivers/gpu/drm/nouveau/nv50_display.c
|
||||
+++ b/drivers/gpu/drm/nouveau/nv50_display.c
|
||||
@@ -364,6 +364,7 @@ nv50_display_init(struct drm_device *dev)
|
||||
nv_wr32(dev, 0x610300, nv_rd32(dev, 0x610300) & ~1);
|
||||
|
||||
evo->dma.max = (4096/4) - 2;
|
||||
+ evo->dma.max &= ~7;
|
||||
evo->dma.put = 0;
|
||||
evo->dma.cur = evo->dma.put;
|
||||
evo->dma.free = evo->dma.max - evo->dma.cur;
|
||||
--
|
||||
1.7.3.2
|
||||
|
|
@ -0,0 +1,167 @@
|
|||
From b4166db6d1f951a460e5e7f52bb4b4d96f27f55a Mon Sep 17 00:00:00 2001
|
||||
From: Francisco Jerez <currojerez@riseup.net>
|
||||
Date: Fri, 19 Nov 2010 18:08:47 +1000
|
||||
Subject: [PATCH 1/2] drm-nouveau-imac-g4
|
||||
|
||||
drm/nouveau: fabricate DCB encoder table for iMac G4
|
||||
|
||||
In typical Apple fashion there's no standard information about what
|
||||
encoders are present on this machine, this patch adds a quirk to
|
||||
provide it.
|
||||
|
||||
Signed-off-by: Francisco Jerez <currojerez@riseup.net>
|
||||
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
|
||||
---
|
||||
drivers/gpu/drm/nouveau/nouveau_bios.c | 102 ++++++++++++--------------------
|
||||
1 files changed, 38 insertions(+), 64 deletions(-)
|
||||
|
||||
diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.c b/drivers/gpu/drm/nouveau/nouveau_bios.c
|
||||
index 72905c9..8c287f8 100644
|
||||
--- a/drivers/gpu/drm/nouveau/nouveau_bios.c
|
||||
+++ b/drivers/gpu/drm/nouveau/nouveau_bios.c
|
||||
@@ -5985,52 +5985,17 @@ static struct dcb_entry *new_dcb_entry(struct dcb_table *dcb)
|
||||
return entry;
|
||||
}
|
||||
|
||||
-static void fabricate_vga_output(struct dcb_table *dcb, int i2c, int heads)
|
||||
+static void fabricate_dcb_output(struct dcb_table *dcb, int type, int i2c,
|
||||
+ int heads, int or)
|
||||
{
|
||||
struct dcb_entry *entry = new_dcb_entry(dcb);
|
||||
|
||||
- entry->type = 0;
|
||||
+ entry->type = type;
|
||||
entry->i2c_index = i2c;
|
||||
entry->heads = heads;
|
||||
- entry->location = DCB_LOC_ON_CHIP;
|
||||
- entry->or = 1;
|
||||
-}
|
||||
-
|
||||
-static void fabricate_dvi_i_output(struct dcb_table *dcb, bool twoHeads)
|
||||
-{
|
||||
- struct dcb_entry *entry = new_dcb_entry(dcb);
|
||||
-
|
||||
- entry->type = 2;
|
||||
- entry->i2c_index = LEGACY_I2C_PANEL;
|
||||
- entry->heads = twoHeads ? 3 : 1;
|
||||
- entry->location = !DCB_LOC_ON_CHIP; /* ie OFF CHIP */
|
||||
- entry->or = 1; /* means |0x10 gets set on CRE_LCD__INDEX */
|
||||
- entry->duallink_possible = false; /* SiI164 and co. are single link */
|
||||
-
|
||||
-#if 0
|
||||
- /*
|
||||
- * For dvi-a either crtc probably works, but my card appears to only
|
||||
- * support dvi-d. "nvidia" still attempts to program it for dvi-a,
|
||||
- * doing the full fp output setup (program 0x6808.. fp dimension regs,
|
||||
- * setting 0x680848 to 0x10000111 to enable, maybe setting 0x680880);
|
||||
- * the monitor picks up the mode res ok and lights up, but no pixel
|
||||
- * data appears, so the board manufacturer probably connected up the
|
||||
- * sync lines, but missed the video traces / components
|
||||
- *
|
||||
- * with this introduction, dvi-a left as an exercise for the reader.
|
||||
- */
|
||||
- fabricate_vga_output(dcb, LEGACY_I2C_PANEL, entry->heads);
|
||||
-#endif
|
||||
-}
|
||||
-
|
||||
-static void fabricate_tv_output(struct dcb_table *dcb, bool twoHeads)
|
||||
-{
|
||||
- struct dcb_entry *entry = new_dcb_entry(dcb);
|
||||
-
|
||||
- entry->type = 1;
|
||||
- entry->i2c_index = LEGACY_I2C_TV;
|
||||
- entry->heads = twoHeads ? 3 : 1;
|
||||
- entry->location = !DCB_LOC_ON_CHIP; /* ie OFF CHIP */
|
||||
+ if (type != OUTPUT_ANALOG)
|
||||
+ entry->location = !DCB_LOC_ON_CHIP; /* ie OFF CHIP */
|
||||
+ entry->or = or;
|
||||
}
|
||||
|
||||
static bool
|
||||
@@ -6297,8 +6262,36 @@ apply_dcb_encoder_quirks(struct drm_device *dev, int idx, u32 *conn, u32 *conf)
|
||||
return true;
|
||||
}
|
||||
|
||||
+static void
|
||||
+fabricate_dcb_encoder_table(struct drm_device *dev, struct nvbios *bios)
|
||||
+{
|
||||
+ struct dcb_table *dcb = &bios->dcb;
|
||||
+ int all_heads = (nv_two_heads(dev) ? 3 : 1);
|
||||
+
|
||||
+#ifdef __powerpc__
|
||||
+ /* Apple iMac G4 NV17 */
|
||||
+ if (of_machine_is_compatible("PowerMac4,5")) {
|
||||
+ fabricate_dcb_output(dcb, OUTPUT_TMDS, 0, all_heads, 1);
|
||||
+ fabricate_dcb_output(dcb, OUTPUT_ANALOG, 1, all_heads, 2);
|
||||
+ return;
|
||||
+ }
|
||||
+#endif
|
||||
+
|
||||
+ /* Make up some sane defaults */
|
||||
+ fabricate_dcb_output(dcb, OUTPUT_ANALOG, LEGACY_I2C_CRT, 1, 1);
|
||||
+
|
||||
+ if (nv04_tv_identify(dev, bios->legacy.i2c_indices.tv) >= 0)
|
||||
+ fabricate_dcb_output(dcb, OUTPUT_TV, LEGACY_I2C_TV,
|
||||
+ all_heads, 0);
|
||||
+
|
||||
+ else if (bios->tmds.output0_script_ptr ||
|
||||
+ bios->tmds.output1_script_ptr)
|
||||
+ fabricate_dcb_output(dcb, OUTPUT_TMDS, LEGACY_I2C_PANEL,
|
||||
+ all_heads, 1);
|
||||
+}
|
||||
+
|
||||
static int
|
||||
-parse_dcb_table(struct drm_device *dev, struct nvbios *bios, bool twoHeads)
|
||||
+parse_dcb_table(struct drm_device *dev, struct nvbios *bios)
|
||||
{
|
||||
struct drm_nouveau_private *dev_priv = dev->dev_private;
|
||||
struct dcb_table *dcb = &bios->dcb;
|
||||
@@ -6318,12 +6311,7 @@ parse_dcb_table(struct drm_device *dev, struct nvbios *bios, bool twoHeads)
|
||||
|
||||
/* this situation likely means a really old card, pre DCB */
|
||||
if (dcbptr == 0x0) {
|
||||
- NV_INFO(dev, "Assuming a CRT output exists\n");
|
||||
- fabricate_vga_output(dcb, LEGACY_I2C_CRT, 1);
|
||||
-
|
||||
- if (nv04_tv_identify(dev, bios->legacy.i2c_indices.tv) >= 0)
|
||||
- fabricate_tv_output(dcb, twoHeads);
|
||||
-
|
||||
+ fabricate_dcb_encoder_table(dev, bios);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -6383,21 +6371,7 @@ parse_dcb_table(struct drm_device *dev, struct nvbios *bios, bool twoHeads)
|
||||
*/
|
||||
NV_TRACEWARN(dev, "No useful information in BIOS output table; "
|
||||
"adding all possible outputs\n");
|
||||
- fabricate_vga_output(dcb, LEGACY_I2C_CRT, 1);
|
||||
-
|
||||
- /*
|
||||
- * Attempt to detect TV before DVI because the test
|
||||
- * for the former is more accurate and it rules the
|
||||
- * latter out.
|
||||
- */
|
||||
- if (nv04_tv_identify(dev,
|
||||
- bios->legacy.i2c_indices.tv) >= 0)
|
||||
- fabricate_tv_output(dcb, twoHeads);
|
||||
-
|
||||
- else if (bios->tmds.output0_script_ptr ||
|
||||
- bios->tmds.output1_script_ptr)
|
||||
- fabricate_dvi_i_output(dcb, twoHeads);
|
||||
-
|
||||
+ fabricate_dcb_encoder_table(dev, bios);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -6787,7 +6761,7 @@ nouveau_bios_init(struct drm_device *dev)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
- ret = parse_dcb_table(dev, bios, nv_two_heads(dev));
|
||||
+ ret = parse_dcb_table(dev, bios);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
--
|
||||
1.7.3.2
|
||||
|
|
@ -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,25 @@
|
|||
From 7abba51e3fc9e3fdd43c63eeb1a680a2e258a833 Mon Sep 17 00:00:00 2001
|
||||
From: Ben Skeggs <bskeggs@redhat.com>
|
||||
Date: Fri, 19 Nov 2010 18:59:15 +1000
|
||||
Subject: [PATCH] drm-nouveau-nvaf-grclass
|
||||
|
||||
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
|
||||
---
|
||||
drivers/gpu/drm/nouveau/nv50_graph.c | 1 +
|
||||
1 files changed, 1 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/drivers/gpu/drm/nouveau/nv50_graph.c b/drivers/gpu/drm/nouveau/nv50_graph.c
|
||||
index 8b669d0..235be5f 100644
|
||||
--- a/drivers/gpu/drm/nouveau/nv50_graph.c
|
||||
+++ b/drivers/gpu/drm/nouveau/nv50_graph.c
|
||||
@@ -400,6 +400,7 @@ struct nouveau_pgraph_object_class nv50_graph_grclass[] = {
|
||||
{ 0x8297, false, NULL }, /* tesla (nv8x/nv9x) */
|
||||
{ 0x8397, false, NULL }, /* tesla (nva0, nvaa, nvac) */
|
||||
{ 0x8597, false, NULL }, /* tesla (nva3, nva5, nva8) */
|
||||
+ { 0x8697, false, NULL }, /* tesla (nvaf) */
|
||||
{}
|
||||
};
|
||||
|
||||
--
|
||||
1.7.3.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,601 @@
|
|||
commit 879d56da9b89b52de2109cadf1369967522428e8
|
||||
Author: Dave Airlie <airlied@redhat.com>
|
||||
Date: Tue Oct 26 12:55:52 2010 +1000
|
||||
|
||||
drm/radeon/kms: don't poll dac load detect.
|
||||
|
||||
This is slightly destructive, cpu intensive and can cause lockups.
|
||||
|
||||
Signed-off-by: Dave Airlie <airlied@redhat.com>
|
||||
|
||||
commit 2563a90cdda1fe490947dc032ce17bf1118afc39
|
||||
Author: Dave Airlie <airlied@redhat.com>
|
||||
Date: Tue Nov 9 10:26:00 2010 +1000
|
||||
|
||||
drm: Use a nondestructive mode for output detect when polling (v2)
|
||||
|
||||
v2: Julien Cristau pointed out that @nondestructive results in
|
||||
double-negatives and confusion when trying to interpret the parameter,
|
||||
so use @force instead. Much easier to type as well. ;-)
|
||||
|
||||
And fix the miscompilation of vmgfx reported by Sedat Dilek.
|
||||
|
||||
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
|
||||
Cc: stable@kernel.org
|
||||
Signed-off-by: Dave Airlie <airlied@redhat.com>
|
||||
|
||||
Conflicts:
|
||||
|
||||
drivers/gpu/drm/i915/intel_tv.c
|
||||
drivers/gpu/drm/nouveau/nouveau_connector.c
|
||||
|
||||
commit deb557bbbcaa7fa8281d51490c73b51f579bc84d
|
||||
Author: Dave Airlie <airlied@redhat.com>
|
||||
Date: Tue Nov 9 10:24:06 2010 +1000
|
||||
|
||||
drm: Use a nondestructive mode for output detect when polling
|
||||
|
||||
Destructive load-detection is very expensive and due to failings
|
||||
elsewhere can trigger system wide stalls of up to 600ms. A simple
|
||||
first step to correcting this is not to invoke such an expensive
|
||||
and destructive load-detection operation automatically.
|
||||
|
||||
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=29536
|
||||
Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=16265
|
||||
Reported-by: Bruno Prémont <bonbons@linux-vserver.org>
|
||||
Tested-by: Sitsofe Wheeler <sitsofe@yahoo.com>
|
||||
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
|
||||
Cc: stable@kernel.org
|
||||
Signed-off-by: Dave Airlie <airlied@redhat.com>
|
||||
|
||||
Conflicts:
|
||||
|
||||
drivers/gpu/drm/i915/intel_tv.c
|
||||
drivers/gpu/drm/nouveau/nouveau_connector.c
|
||||
|
||||
commit 8d5d3cd3612618a3c2214048788f0b2cc463ce0f
|
||||
Author: Chris Wilson <chris@chris-wilson.co.uk>
|
||||
Date: Mon Sep 6 23:53:47 2010 +0100
|
||||
|
||||
drm: Fix regression in disable polling e58f637
|
||||
|
||||
I broke out my trusty i845 and found a new boot failure, which upon
|
||||
inspection turned out to be a recursion within:
|
||||
|
||||
drm_helper_probe_single_connector_modes() -> drm_helper_hpd_irq_event()
|
||||
-> intel_crt_detect() -> drm_helper_probe_single_connector_modes()
|
||||
|
||||
Calling drm_kms_helper_poll_enable() instead performs the desired
|
||||
re-initialisation of the polling should the user have toggled the
|
||||
parameter, without the recursive side-effect.
|
||||
|
||||
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
|
||||
Cc: Dave Airlie <airlied@redhat.com>
|
||||
Signed-off-by: Dave Airlie <airlied@redhat.com>
|
||||
|
||||
commit ec0becade1eae9b0f40b12ea4fcc3ea36e993ba3
|
||||
Author: Dave Airlie <airlied@redhat.com>
|
||||
Date: Tue Nov 9 09:48:34 2010 +1000
|
||||
|
||||
drm/kms: Add a module parameter to disable polling
|
||||
|
||||
Polling for a VGA device on an old system can be quite expensive,
|
||||
causing latencies on the order of 600ms. As we hold the mode mutex for
|
||||
this time and also need the same mutex to move the cursor, we trigger a
|
||||
user-visible stall.
|
||||
|
||||
The real solution would involve improving the granulatity of the
|
||||
locking and so perhaps performing some of the probing not under the lock
|
||||
or some other updates can be done under different locks. Also reducing the
|
||||
cost of probing for a non-existent monitor would be worthwhile. However,
|
||||
exposing a parameter to disable polling is a simple workaround in the
|
||||
meantime.
|
||||
|
||||
In order to accommodate users turning polling on and off at runtime, the
|
||||
polling is potentially re-enabled on every probe. This is coupled to
|
||||
the user calling xrandr, which seems to be a vaild time to reset the
|
||||
polling timeout since the information on the connection has just been
|
||||
updated. (The presumption being that all connections are probed in a
|
||||
single xrandr pass, which is currently valid.)
|
||||
|
||||
References:
|
||||
|
||||
Bug 29536 - 2.6.35 causes ~600ms latency every 10s
|
||||
https://bugs.freedesktop.org/show_bug.cgi?id=29536
|
||||
|
||||
Bug 16265 - Why is kslowd accumulating so much CPU time?
|
||||
https://bugzilla.kernel.org/show_bug.cgi?id=16265
|
||||
|
||||
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
|
||||
Reported-and-tested-by: Bruno Prémont <bonbons@linux-vserver.org>
|
||||
Signed-off-by: Dave Airlie <airlied@redhat.com>
|
||||
|
||||
Conflicts:
|
||||
|
||||
drivers/gpu/drm/drm_crtc_helper.c
|
||||
|
||||
commit 77e90256db2f7e6424717f7cc984b22d2832243f
|
||||
Author: Dan Carpenter <error27@gmail.com>
|
||||
Date: Thu Aug 19 11:46:29 2010 +0200
|
||||
|
||||
drm: move dereference below check
|
||||
|
||||
"fb_helper_conn" is dereferenced before the check for NULL. It's never
|
||||
actually NULL here, so this is mostly to keep the static checkers happy.
|
||||
|
||||
Signed-off-by: Dan Carpenter <error27@gmail.com>
|
||||
Signed-off-by: Dave Airlie <airlied@redhat.com>
|
||||
|
||||
commit 86e25290d9df7a84d185dfc037851d72d270a6c0
|
||||
Author: Alex Deucher <alexdeucher@gmail.com>
|
||||
Date: Tue Jul 20 03:24:11 2010 -0400
|
||||
|
||||
drm/radeon/kms: make sure HPD is set to NONE on analog-only connectors
|
||||
|
||||
HPD is digital only.
|
||||
|
||||
Signed-off-by: Alex Deucher <alexdeucher@gmail.com>
|
||||
Signed-off-by: Dave Airlie <airlied@redhat.com>
|
||||
|
||||
diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c
|
||||
index 25d70d6..d537039 100644
|
||||
--- a/drivers/gpu/drm/drm_crtc_helper.c
|
||||
+++ b/drivers/gpu/drm/drm_crtc_helper.c
|
||||
@@ -34,6 +34,9 @@
|
||||
#include "drm_crtc_helper.h"
|
||||
#include "drm_fb_helper.h"
|
||||
|
||||
+static bool drm_kms_helper_poll = true;
|
||||
+module_param_named(poll, drm_kms_helper_poll, bool, 0600);
|
||||
+
|
||||
static void drm_mode_validate_flag(struct drm_connector *connector,
|
||||
int flags)
|
||||
{
|
||||
@@ -98,8 +101,10 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector,
|
||||
connector->status = connector_status_disconnected;
|
||||
if (connector->funcs->force)
|
||||
connector->funcs->force(connector);
|
||||
- } else
|
||||
- connector->status = connector->funcs->detect(connector);
|
||||
+ } else {
|
||||
+ connector->status = connector->funcs->detect(connector, true);
|
||||
+ drm_kms_helper_poll_enable(dev);
|
||||
+ }
|
||||
|
||||
if (connector->status == connector_status_disconnected) {
|
||||
DRM_DEBUG_KMS("%s is disconnected\n",
|
||||
@@ -820,6 +825,9 @@ static void output_poll_execute(struct slow_work *work)
|
||||
bool repoll = false, changed = false;
|
||||
int ret;
|
||||
|
||||
+ if (!drm_kms_helper_poll)
|
||||
+ return;
|
||||
+
|
||||
mutex_lock(&dev->mode_config.mutex);
|
||||
list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
|
||||
|
||||
@@ -839,7 +847,7 @@ static void output_poll_execute(struct slow_work *work)
|
||||
!(connector->polled & DRM_CONNECTOR_POLL_HPD))
|
||||
continue;
|
||||
|
||||
- status = connector->funcs->detect(connector);
|
||||
+ status = connector->funcs->detect(connector, false);
|
||||
if (old_status != status)
|
||||
changed = true;
|
||||
}
|
||||
@@ -874,6 +882,9 @@ void drm_kms_helper_poll_enable(struct drm_device *dev)
|
||||
struct drm_connector *connector;
|
||||
int ret;
|
||||
|
||||
+ if (!dev->mode_config.poll_enabled || !drm_kms_helper_poll)
|
||||
+ return;
|
||||
+
|
||||
list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
|
||||
if (connector->polled)
|
||||
poll = true;
|
||||
@@ -909,9 +920,12 @@ void drm_helper_hpd_irq_event(struct drm_device *dev)
|
||||
{
|
||||
if (!dev->mode_config.poll_enabled)
|
||||
return;
|
||||
+
|
||||
delayed_slow_work_cancel(&dev->mode_config.output_poll_slow_work);
|
||||
/* schedule a slow work asap */
|
||||
- delayed_slow_work_enqueue(&dev->mode_config.output_poll_slow_work, 0);
|
||||
+ if (drm_kms_helper_poll)
|
||||
+ delayed_slow_work_enqueue(&dev->mode_config.output_poll_slow_work, 0);
|
||||
+
|
||||
}
|
||||
EXPORT_SYMBOL(drm_helper_hpd_irq_event);
|
||||
|
||||
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c
|
||||
index 7196620..cef8d8d 100644
|
||||
--- a/drivers/gpu/drm/drm_fb_helper.c
|
||||
+++ b/drivers/gpu/drm/drm_fb_helper.c
|
||||
@@ -94,10 +94,11 @@ static bool drm_fb_helper_connector_parse_command_line(struct drm_fb_helper_conn
|
||||
int i;
|
||||
enum drm_connector_force force = DRM_FORCE_UNSPECIFIED;
|
||||
struct drm_fb_helper_cmdline_mode *cmdline_mode;
|
||||
- struct drm_connector *connector = fb_helper_conn->connector;
|
||||
+ struct drm_connector *connector;
|
||||
|
||||
if (!fb_helper_conn)
|
||||
return false;
|
||||
+ connector = fb_helper_conn->connector;
|
||||
|
||||
cmdline_mode = &fb_helper_conn->cmdline_mode;
|
||||
if (!mode_option)
|
||||
diff --git a/drivers/gpu/drm/drm_sysfs.c b/drivers/gpu/drm/drm_sysfs.c
|
||||
index 101d381..9500af1 100644
|
||||
--- a/drivers/gpu/drm/drm_sysfs.c
|
||||
+++ b/drivers/gpu/drm/drm_sysfs.c
|
||||
@@ -159,7 +159,7 @@ static ssize_t status_show(struct device *device,
|
||||
struct drm_connector *connector = to_drm_connector(device);
|
||||
enum drm_connector_status status;
|
||||
|
||||
- status = connector->funcs->detect(connector);
|
||||
+ status = connector->funcs->detect(connector, true);
|
||||
return snprintf(buf, PAGE_SIZE, "%s\n",
|
||||
drm_get_connector_status_name(status));
|
||||
}
|
||||
diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c
|
||||
index ee0732b..3886b47 100644
|
||||
--- a/drivers/gpu/drm/i915/intel_crt.c
|
||||
+++ b/drivers/gpu/drm/i915/intel_crt.c
|
||||
@@ -402,7 +402,8 @@ intel_crt_load_detect(struct drm_crtc *crtc, struct intel_encoder *intel_encoder
|
||||
return status;
|
||||
}
|
||||
|
||||
-static enum drm_connector_status intel_crt_detect(struct drm_connector *connector)
|
||||
+static enum drm_connector_status
|
||||
+intel_crt_detect(struct drm_connector *connector, bool force)
|
||||
{
|
||||
struct drm_device *dev = connector->dev;
|
||||
struct drm_encoder *encoder = intel_attached_encoder(connector);
|
||||
@@ -421,6 +422,9 @@ static enum drm_connector_status intel_crt_detect(struct drm_connector *connecto
|
||||
if (intel_crt_detect_ddc(encoder))
|
||||
return connector_status_connected;
|
||||
|
||||
+ if (!force)
|
||||
+ return connector->status;
|
||||
+
|
||||
/* for pre-945g platforms use load detect */
|
||||
if (encoder->crtc && encoder->crtc->enabled) {
|
||||
status = intel_crt_load_detect(encoder->crtc, intel_encoder);
|
||||
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
|
||||
index d9de8f1..b58249d 100644
|
||||
--- a/drivers/gpu/drm/i915/intel_dp.c
|
||||
+++ b/drivers/gpu/drm/i915/intel_dp.c
|
||||
@@ -1287,7 +1287,7 @@ ironlake_dp_detect(struct drm_connector *connector)
|
||||
* \return false if DP port is disconnected.
|
||||
*/
|
||||
static enum drm_connector_status
|
||||
-intel_dp_detect(struct drm_connector *connector)
|
||||
+intel_dp_detect(struct drm_connector *connector, bool force)
|
||||
{
|
||||
struct drm_encoder *encoder = intel_attached_encoder(connector);
|
||||
struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
|
||||
diff --git a/drivers/gpu/drm/i915/intel_dvo.c b/drivers/gpu/drm/i915/intel_dvo.c
|
||||
index 227feca..48a1889 100644
|
||||
--- a/drivers/gpu/drm/i915/intel_dvo.c
|
||||
+++ b/drivers/gpu/drm/i915/intel_dvo.c
|
||||
@@ -211,7 +211,8 @@ static void intel_dvo_mode_set(struct drm_encoder *encoder,
|
||||
*
|
||||
* Unimplemented.
|
||||
*/
|
||||
-static enum drm_connector_status intel_dvo_detect(struct drm_connector *connector)
|
||||
+static enum drm_connector_status
|
||||
+intel_dvo_detect(struct drm_connector *connector, bool force)
|
||||
{
|
||||
struct drm_encoder *encoder = intel_attached_encoder(connector);
|
||||
struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
|
||||
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
|
||||
index 83bd764..d1decfc 100644
|
||||
--- a/drivers/gpu/drm/i915/intel_hdmi.c
|
||||
+++ b/drivers/gpu/drm/i915/intel_hdmi.c
|
||||
@@ -134,7 +134,7 @@ static bool intel_hdmi_mode_fixup(struct drm_encoder *encoder,
|
||||
}
|
||||
|
||||
static enum drm_connector_status
|
||||
-intel_hdmi_detect(struct drm_connector *connector)
|
||||
+intel_hdmi_detect(struct drm_connector *connector, bool force)
|
||||
{
|
||||
struct drm_encoder *encoder = intel_attached_encoder(connector);
|
||||
struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
|
||||
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c
|
||||
index 7d42ff1..9ad3425 100644
|
||||
--- a/drivers/gpu/drm/i915/intel_lvds.c
|
||||
+++ b/drivers/gpu/drm/i915/intel_lvds.c
|
||||
@@ -546,7 +546,8 @@ static void intel_lvds_mode_set(struct drm_encoder *encoder,
|
||||
* connected and closed means disconnected. We also send hotplug events as
|
||||
* needed, using lid status notification from the input layer.
|
||||
*/
|
||||
-static enum drm_connector_status intel_lvds_detect(struct drm_connector *connector)
|
||||
+static enum drm_connector_status
|
||||
+intel_lvds_detect(struct drm_connector *connector, bool force)
|
||||
{
|
||||
struct drm_device *dev = connector->dev;
|
||||
enum drm_connector_status status = connector_status_connected;
|
||||
@@ -641,7 +642,9 @@ static int intel_lid_notify(struct notifier_block *nb, unsigned long val,
|
||||
* the LID nofication event.
|
||||
*/
|
||||
if (connector)
|
||||
- connector->status = connector->funcs->detect(connector);
|
||||
+ connector->status = connector->funcs->detect(connector,
|
||||
+ false);
|
||||
+
|
||||
/* Don't force modeset on machines where it causes a GPU lockup */
|
||||
if (dmi_check_system(intel_no_modeset_on_lid))
|
||||
return NOTIFY_OK;
|
||||
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c
|
||||
index 76993ac..76c9b3d 100644
|
||||
--- a/drivers/gpu/drm/i915/intel_sdvo.c
|
||||
+++ b/drivers/gpu/drm/i915/intel_sdvo.c
|
||||
@@ -1496,7 +1496,7 @@ intel_analog_is_connected(struct drm_device *dev)
|
||||
if (!analog_connector)
|
||||
return false;
|
||||
|
||||
- if (analog_connector->funcs->detect(analog_connector) ==
|
||||
+ if (analog_connector->funcs->detect(analog_connector, false) ==
|
||||
connector_status_disconnected)
|
||||
return false;
|
||||
|
||||
@@ -1567,7 +1567,8 @@ intel_sdvo_hdmi_sink_detect(struct drm_connector *connector)
|
||||
return status;
|
||||
}
|
||||
|
||||
-static enum drm_connector_status intel_sdvo_detect(struct drm_connector *connector)
|
||||
+static enum drm_connector_status
|
||||
+intel_sdvo_detect(struct drm_connector *connector, bool force)
|
||||
{
|
||||
uint16_t response;
|
||||
u8 status;
|
||||
diff --git a/drivers/gpu/drm/i915/intel_tv.c b/drivers/gpu/drm/i915/intel_tv.c
|
||||
index 6d553c2..ad40f1b 100644
|
||||
--- a/drivers/gpu/drm/i915/intel_tv.c
|
||||
+++ b/drivers/gpu/drm/i915/intel_tv.c
|
||||
@@ -1336,7 +1336,7 @@ static void intel_tv_find_better_format(struct drm_connector *connector)
|
||||
* we have a pipe programmed in order to probe the TV.
|
||||
*/
|
||||
static enum drm_connector_status
|
||||
-intel_tv_detect(struct drm_connector *connector)
|
||||
+intel_tv_detect(struct drm_connector *connector, bool force)
|
||||
{
|
||||
struct drm_crtc *crtc;
|
||||
struct drm_display_mode mode;
|
||||
@@ -1351,7 +1351,7 @@ intel_tv_detect(struct drm_connector *connector)
|
||||
|
||||
if (encoder->crtc && encoder->crtc->enabled) {
|
||||
type = intel_tv_detect_type(encoder->crtc, intel_encoder);
|
||||
- } else {
|
||||
+ } else if (force) {
|
||||
crtc = intel_get_load_detect_pipe(intel_encoder, connector,
|
||||
&mode, &dpms_mode);
|
||||
if (crtc) {
|
||||
@@ -1359,8 +1359,9 @@ intel_tv_detect(struct drm_connector *connector)
|
||||
intel_release_load_detect_pipe(intel_encoder, connector,
|
||||
dpms_mode);
|
||||
} else
|
||||
- type = -1;
|
||||
- }
|
||||
+ return connector_status_unknown;
|
||||
+ } else
|
||||
+ return connector->status;
|
||||
|
||||
tv_priv->type = type;
|
||||
|
||||
diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c b/drivers/gpu/drm/nouveau/nouveau_connector.c
|
||||
index 149ed22..1085376 100644
|
||||
--- a/drivers/gpu/drm/nouveau/nouveau_connector.c
|
||||
+++ b/drivers/gpu/drm/nouveau/nouveau_connector.c
|
||||
@@ -228,7 +228,7 @@ nouveau_connector_set_encoder(struct drm_connector *connector,
|
||||
}
|
||||
|
||||
static enum drm_connector_status
|
||||
-nouveau_connector_detect(struct drm_connector *connector)
|
||||
+nouveau_connector_detect(struct drm_connector *connector, bool force)
|
||||
{
|
||||
struct drm_device *dev = connector->dev;
|
||||
struct nouveau_connector *nv_connector = nouveau_connector(connector);
|
||||
diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c
|
||||
index adccbc2..1680600 100644
|
||||
--- a/drivers/gpu/drm/radeon/radeon_connectors.c
|
||||
+++ b/drivers/gpu/drm/radeon/radeon_connectors.c
|
||||
@@ -467,7 +467,8 @@ static int radeon_lvds_mode_valid(struct drm_connector *connector,
|
||||
return MODE_OK;
|
||||
}
|
||||
|
||||
-static enum drm_connector_status radeon_lvds_detect(struct drm_connector *connector)
|
||||
+static enum drm_connector_status
|
||||
+radeon_lvds_detect(struct drm_connector *connector, bool force)
|
||||
{
|
||||
struct radeon_connector *radeon_connector = to_radeon_connector(connector);
|
||||
struct drm_encoder *encoder = radeon_best_single_encoder(connector);
|
||||
@@ -582,7 +583,8 @@ static int radeon_vga_mode_valid(struct drm_connector *connector,
|
||||
return MODE_OK;
|
||||
}
|
||||
|
||||
-static enum drm_connector_status radeon_vga_detect(struct drm_connector *connector)
|
||||
+static enum drm_connector_status
|
||||
+radeon_vga_detect(struct drm_connector *connector, bool force)
|
||||
{
|
||||
struct radeon_connector *radeon_connector = to_radeon_connector(connector);
|
||||
struct drm_encoder *encoder;
|
||||
@@ -621,6 +623,11 @@ static enum drm_connector_status radeon_vga_detect(struct drm_connector *connect
|
||||
ret = connector_status_connected;
|
||||
}
|
||||
} else {
|
||||
+
|
||||
+ /* if we aren't forcing don't do destructive polling */
|
||||
+ if (!force)
|
||||
+ return connector->status;
|
||||
+
|
||||
if (radeon_connector->dac_load_detect && encoder) {
|
||||
encoder_funcs = encoder->helper_private;
|
||||
ret = encoder_funcs->detect(encoder, connector);
|
||||
@@ -679,7 +686,8 @@ static int radeon_tv_mode_valid(struct drm_connector *connector,
|
||||
return MODE_OK;
|
||||
}
|
||||
|
||||
-static enum drm_connector_status radeon_tv_detect(struct drm_connector *connector)
|
||||
+static enum drm_connector_status
|
||||
+radeon_tv_detect(struct drm_connector *connector, bool force)
|
||||
{
|
||||
struct drm_encoder *encoder;
|
||||
struct drm_encoder_helper_funcs *encoder_funcs;
|
||||
@@ -736,7 +744,8 @@ static int radeon_dvi_get_modes(struct drm_connector *connector)
|
||||
* we have to check if this analog encoder is shared with anyone else (TV)
|
||||
* if its shared we have to set the other connector to disconnected.
|
||||
*/
|
||||
-static enum drm_connector_status radeon_dvi_detect(struct drm_connector *connector)
|
||||
+static enum drm_connector_status
|
||||
+radeon_dvi_detect(struct drm_connector *connector, bool force)
|
||||
{
|
||||
struct radeon_connector *radeon_connector = to_radeon_connector(connector);
|
||||
struct drm_encoder *encoder = NULL;
|
||||
@@ -806,6 +815,11 @@ static enum drm_connector_status radeon_dvi_detect(struct drm_connector *connect
|
||||
if ((ret == connector_status_connected) && (radeon_connector->use_digital == true))
|
||||
goto out;
|
||||
|
||||
+ if (!force) {
|
||||
+ ret = connector->status;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
/* find analog encoder */
|
||||
if (radeon_connector->dac_load_detect) {
|
||||
for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
|
||||
@@ -962,7 +976,8 @@ static int radeon_dp_get_modes(struct drm_connector *connector)
|
||||
return ret;
|
||||
}
|
||||
|
||||
-static enum drm_connector_status radeon_dp_detect(struct drm_connector *connector)
|
||||
+static enum drm_connector_status
|
||||
+radeon_dp_detect(struct drm_connector *connector, bool force)
|
||||
{
|
||||
struct radeon_connector *radeon_connector = to_radeon_connector(connector);
|
||||
enum drm_connector_status ret = connector_status_disconnected;
|
||||
@@ -1082,6 +1097,8 @@ radeon_add_atom_connector(struct drm_device *dev,
|
||||
drm_connector_attach_property(&radeon_connector->base,
|
||||
rdev->mode_info.load_detect_property,
|
||||
1);
|
||||
+ /* no HPD on analog connectors */
|
||||
+ radeon_connector->hpd.hpd = RADEON_HPD_NONE;
|
||||
connector->polled = DRM_CONNECTOR_POLL_CONNECT;
|
||||
connector->interlace_allowed = true;
|
||||
connector->doublescan_allowed = true;
|
||||
@@ -1096,6 +1113,8 @@ radeon_add_atom_connector(struct drm_device *dev,
|
||||
drm_connector_attach_property(&radeon_connector->base,
|
||||
rdev->mode_info.load_detect_property,
|
||||
1);
|
||||
+ /* no HPD on analog connectors */
|
||||
+ radeon_connector->hpd.hpd = RADEON_HPD_NONE;
|
||||
connector->interlace_allowed = true;
|
||||
connector->doublescan_allowed = true;
|
||||
break;
|
||||
@@ -1186,6 +1205,8 @@ radeon_add_atom_connector(struct drm_device *dev,
|
||||
drm_connector_attach_property(&radeon_connector->base,
|
||||
rdev->mode_info.tv_std_property,
|
||||
radeon_atombios_get_tv_info(rdev));
|
||||
+ /* no HPD on analog connectors */
|
||||
+ radeon_connector->hpd.hpd = RADEON_HPD_NONE;
|
||||
}
|
||||
connector->interlace_allowed = false;
|
||||
connector->doublescan_allowed = false;
|
||||
@@ -1209,7 +1230,7 @@ radeon_add_atom_connector(struct drm_device *dev,
|
||||
break;
|
||||
}
|
||||
|
||||
- if (hpd->hpd == RADEON_HPD_NONE) {
|
||||
+ if (radeon_connector->hpd.hpd == RADEON_HPD_NONE) {
|
||||
if (i2c_bus->valid)
|
||||
connector->polled = DRM_CONNECTOR_POLL_CONNECT;
|
||||
} else
|
||||
@@ -1276,6 +1297,8 @@ radeon_add_legacy_connector(struct drm_device *dev,
|
||||
drm_connector_attach_property(&radeon_connector->base,
|
||||
rdev->mode_info.load_detect_property,
|
||||
1);
|
||||
+ /* no HPD on analog connectors */
|
||||
+ radeon_connector->hpd.hpd = RADEON_HPD_NONE;
|
||||
connector->polled = DRM_CONNECTOR_POLL_CONNECT;
|
||||
connector->interlace_allowed = true;
|
||||
connector->doublescan_allowed = true;
|
||||
@@ -1290,6 +1313,8 @@ radeon_add_legacy_connector(struct drm_device *dev,
|
||||
drm_connector_attach_property(&radeon_connector->base,
|
||||
rdev->mode_info.load_detect_property,
|
||||
1);
|
||||
+ /* no HPD on analog connectors */
|
||||
+ radeon_connector->hpd.hpd = RADEON_HPD_NONE;
|
||||
connector->interlace_allowed = true;
|
||||
connector->doublescan_allowed = true;
|
||||
break;
|
||||
@@ -1328,6 +1353,8 @@ radeon_add_legacy_connector(struct drm_device *dev,
|
||||
drm_connector_attach_property(&radeon_connector->base,
|
||||
rdev->mode_info.tv_std_property,
|
||||
radeon_combios_get_tv_info(rdev));
|
||||
+ /* no HPD on analog connectors */
|
||||
+ radeon_connector->hpd.hpd = RADEON_HPD_NONE;
|
||||
}
|
||||
connector->interlace_allowed = false;
|
||||
connector->doublescan_allowed = false;
|
||||
@@ -1345,7 +1372,7 @@ radeon_add_legacy_connector(struct drm_device *dev,
|
||||
break;
|
||||
}
|
||||
|
||||
- if (hpd->hpd == RADEON_HPD_NONE) {
|
||||
+ if (radeon_connector->hpd.hpd == RADEON_HPD_NONE) {
|
||||
if (i2c_bus->valid)
|
||||
connector->polled = DRM_CONNECTOR_POLL_CONNECT;
|
||||
} else
|
||||
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c
|
||||
index cfaf690..5b638cb 100644
|
||||
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c
|
||||
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c
|
||||
@@ -335,7 +335,8 @@ static void vmw_ldu_connector_restore(struct drm_connector *connector)
|
||||
}
|
||||
|
||||
static enum drm_connector_status
|
||||
- vmw_ldu_connector_detect(struct drm_connector *connector)
|
||||
+ vmw_ldu_connector_detect(struct drm_connector *connector,
|
||||
+ bool force)
|
||||
{
|
||||
if (vmw_connector_to_ldu(connector)->pref_active)
|
||||
return connector_status_connected;
|
||||
@@ -516,7 +517,7 @@ static int vmw_ldu_init(struct vmw_private *dev_priv, unsigned unit)
|
||||
|
||||
drm_connector_init(dev, connector, &vmw_legacy_connector_funcs,
|
||||
DRM_MODE_CONNECTOR_LVDS);
|
||||
- connector->status = vmw_ldu_connector_detect(connector);
|
||||
+ connector->status = vmw_ldu_connector_detect(connector, true);
|
||||
|
||||
drm_encoder_init(dev, encoder, &vmw_legacy_encoder_funcs,
|
||||
DRM_MODE_ENCODER_LVDS);
|
||||
@@ -610,7 +611,7 @@ int vmw_kms_ldu_update_layout(struct vmw_private *dev_priv, unsigned num,
|
||||
ldu->pref_height = 600;
|
||||
ldu->pref_active = false;
|
||||
}
|
||||
- con->status = vmw_ldu_connector_detect(con);
|
||||
+ con->status = vmw_ldu_connector_detect(con, true);
|
||||
}
|
||||
|
||||
mutex_unlock(&dev->mode_config.mutex);
|
||||
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
|
||||
index 93a1a31..afbb578 100644
|
||||
--- a/include/drm/drm_crtc.h
|
||||
+++ b/include/drm/drm_crtc.h
|
||||
@@ -420,7 +420,15 @@ struct drm_connector_funcs {
|
||||
void (*dpms)(struct drm_connector *connector, int mode);
|
||||
void (*save)(struct drm_connector *connector);
|
||||
void (*restore)(struct drm_connector *connector);
|
||||
- enum drm_connector_status (*detect)(struct drm_connector *connector);
|
||||
+
|
||||
+ /* Check to see if anything is attached to the connector.
|
||||
+ * @force is set to false whilst polling, true when checking the
|
||||
+ * connector due to user request. @force can be used by the driver
|
||||
+ * to avoid expensive, destructive operations during automated
|
||||
+ * probing.
|
||||
+ */
|
||||
+ enum drm_connector_status (*detect)(struct drm_connector *connector,
|
||||
+ bool force);
|
||||
int (*fill_modes)(struct drm_connector *connector, uint32_t max_width, uint32_t max_height);
|
||||
int (*set_property)(struct drm_connector *connector, struct drm_property *property,
|
||||
uint64_t val);
|
|
@ -0,0 +1,854 @@
|
|||
commit 4adf332cc24ee2d46064aaafd8216169d29566d5
|
||||
Author: Alex Deucher <alexdeucher@gmail.com>
|
||||
Date: Sun Nov 14 20:24:35 2010 -0500
|
||||
|
||||
drm/radeon/kms: fix and unify tiled buffer alignment checking for r6xx/7xx
|
||||
|
||||
Tiled buffers have the same alignment requirements regardless of
|
||||
whether the surface is for db, cb, or textures. Previously, the
|
||||
calculations where inconsistent for each buffer type.
|
||||
|
||||
- Unify the alignment calculations in a common function
|
||||
- Standardize the alignment units (pixels for pitch/height/depth,
|
||||
bytes for base)
|
||||
- properly check the buffer base alignments
|
||||
|
||||
Signed-off-by: Alex Deucher <alexdeucher@gmail.com>
|
||||
Signed-off-by: Dave Airlie <airlied@redhat.com>
|
||||
|
||||
commit c37cb9e61dce7437f63280d9347a9ffdf4ec34e7
|
||||
Author: Alex Deucher <alexdeucher@gmail.com>
|
||||
Date: Wed Oct 27 01:44:35 2010 -0400
|
||||
|
||||
drm/radeon/kms: fix tiled db height calculation on 6xx/7xx
|
||||
|
||||
Calculate height based on the slice bitfield rather than the size.
|
||||
Same as Dave's CB fix.
|
||||
|
||||
Signed-off-by: Alex Deucher <alexdeucher@gmail.com>
|
||||
Signed-off-by: Dave Airlie <airlied@redhat.com>
|
||||
|
||||
commit b80c8fdc2fadd8182b958e91a10f2fa287f993e4
|
||||
Author: Alex Deucher <alexdeucher@gmail.com>
|
||||
Date: Tue Oct 26 20:22:42 2010 -0400
|
||||
|
||||
drm/radeon/kms: fix r6xx/7xx 1D tiling CS checker v2
|
||||
|
||||
broken by:
|
||||
drm/radeon/r600: fix tiling issues in CS checker.
|
||||
|
||||
v2: only apply it to 1D tiling case.
|
||||
|
||||
Signed-off-by: Alex Deucher <alexdeucher@gmail.com>
|
||||
Signed-off-by: Dave Airlie <airlied@redhat.com>
|
||||
|
||||
commit 4336ac5c0a4e5dfbb51631ad680d6a5d0b295cd3
|
||||
Author: Alex Deucher <alexdeucher@gmail.com>
|
||||
Date: Mon Oct 18 23:45:39 2010 -0400
|
||||
|
||||
drm/radeon/kms: fix 2D tile height alignment in the r600 CS checker
|
||||
|
||||
macro tile heights are aligned to num channels, not num banks.
|
||||
|
||||
Noticed by Dave Airlie.
|
||||
|
||||
Signed-off-by: Alex Deucher <alexdeucher@gmail.com>
|
||||
Cc: stable@kernel.org
|
||||
Signed-off-by: Dave Airlie <airlied@redhat.com>
|
||||
|
||||
commit 5c76976a1419a633f9f33c6547bae00348b855d2
|
||||
Author: Dave Airlie <airlied@redhat.com>
|
||||
Date: Thu Oct 21 13:55:40 2010 +1000
|
||||
|
||||
drm/radeon/r600: fix tiling issues in CS checker.
|
||||
|
||||
The CS checker had some incorrect alignment requirements for 2D surfaces,
|
||||
this made rendering to mipmap levels that were 2D broken.
|
||||
|
||||
Also the CB height was being worked out from the BO size, this doesn't work
|
||||
at all when rendering mipmap levels, instead we work out what height userspace
|
||||
wanted from slice max and use that to check it fits inside the BO, however
|
||||
the DDX send the wrong slice max for an unaligned buffer so we have to workaround
|
||||
for that even though its a userspace bug.
|
||||
|
||||
Reviewed-by: Alex Deucher <alexdeucher@gmail.com>
|
||||
Signed-off-by: Dave Airlie <airlied@redhat.com>
|
||||
|
||||
commit fa479e9df4558af6f091c45be37f713e64b836a1
|
||||
Author: Alex Deucher <alexdeucher@gmail.com>
|
||||
Date: Tue Sep 14 10:10:47 2010 -0400
|
||||
|
||||
drm/radeon/kms: only warn on mipmap size checks in r600 cs checker (v2)
|
||||
|
||||
The texture base address registers are in units of 256 bytes.
|
||||
The original CS checker treated these offsets as bytes, so the
|
||||
original check was wrong. I fixed the units in a patch during
|
||||
the 2.6.36 cycle, but this ended up breaking some existing
|
||||
userspace (probably due to a bug in either userspace texture allocation
|
||||
or the drm texture mipmap checker). So for now, until we come
|
||||
up with a better fix, just warn if the mipmap size it too large.
|
||||
This will keep existing userspace working and it should be just
|
||||
as safe as before when we were checking the wrong units. These
|
||||
are GPU MC addresses, so if they fall outside of the VRAM or
|
||||
GART apertures, they end up at the GPU default page, so this should
|
||||
be safe from a security perspective.
|
||||
|
||||
v2: Just disable the warning. It just spams the log and there's
|
||||
nothing the user can do about it.
|
||||
|
||||
Signed-off-by: Alex Deucher <alexdeucher@gmail.com>
|
||||
Cc: Jerome Glisse <glisse@freedesktop.org>
|
||||
Signed-off-by: Dave Airlie <airlied@redhat.com>
|
||||
|
||||
commit 6e8df81d43d5c95fe37db7f0ef55332de1a4b698
|
||||
Author: Dave Airlie <airlied@redhat.com>
|
||||
Date: Thu Aug 12 09:40:05 2010 +1000
|
||||
|
||||
drm/radeon: drop old and broken mesa warning
|
||||
|
||||
This never really got fixed in mesa, and the kernel deals with the problem
|
||||
just fine, so don't got reporting things that confuse people.
|
||||
|
||||
Signed-off-by: Dave Airlie <airlied@redhat.com>
|
||||
|
||||
commit 23f012fb9a0633f2f8901440e314d6276255b1c0
|
||||
Author: Alex Deucher <alexdeucher@gmail.com>
|
||||
Date: Wed Aug 11 11:54:25 2010 -0400
|
||||
|
||||
drm/radeon/kms: another r6xx/r7xx CS checker fix
|
||||
|
||||
add default case for buffer formats
|
||||
|
||||
Signed-off-by: Alex Deucher <alexdeucher@gmail.com>
|
||||
Cc: Andre Maasikas <amaasikas@gmail.com>
|
||||
Signed-off-by: Dave Airlie <airlied@redhat.com>
|
||||
|
||||
commit 2c7e76decda2d437f0ca064fef1a2d5d8892288e
|
||||
Author: Alex Deucher <alexdeucher@gmail.com>
|
||||
Date: Fri Aug 6 02:54:05 2010 -0400
|
||||
|
||||
drm/radeon/kms: r600 CS parser fixes
|
||||
|
||||
- buffer offsets in the base regs are 256b aligned so
|
||||
shift properly when comparing, fixed by Andre Maasikas
|
||||
- mipmap size was calculated wrong when nlevel=0
|
||||
- texture bo offsets were used after the bo base address was added
|
||||
- vertex resource size register is size - 1, not size
|
||||
|
||||
Signed-off-by: Alex Deucher <alexdeucher@gmail.com>
|
||||
Cc: Andre Maasikas <amaasikas@gmail.com>
|
||||
Signed-off-by: Dave Airlie <airlied@redhat.com>
|
||||
|
||||
commit 85d1363c9f15b5d4303b635142cee0ba9d1473fc
|
||||
Author: Alex Deucher <alexdeucher@gmail.com>
|
||||
Date: Fri Jun 4 18:41:42 2010 -0400
|
||||
|
||||
drm/radeon/kms: fix CS alignment checking for tiling (v2)
|
||||
|
||||
Covers depth, cb, and textures. Hopefully I got this right.
|
||||
|
||||
v2: - fix bugs:
|
||||
https://bugs.freedesktop.org/show_bug.cgi?id=28327
|
||||
https://bugs.freedesktop.org/show_bug.cgi?id=28381
|
||||
- use ALIGNED(), IS_ALIGNED() macros
|
||||
|
||||
Signed-off-by: Alex Deucher <alexdeucher@gmail.com>
|
||||
Signed-off-by: Dave Airlie <airlied@redhat.com>
|
||||
|
||||
commit b956b6e7c7fb207daf32520c0a72c8c06ef1d5f5
|
||||
Author: Alex Deucher <alexdeucher@gmail.com>
|
||||
Date: Thu May 20 12:43:52 2010 -0400
|
||||
|
||||
drm/radeon/kms: add tiling support to the cs checker for r6xx/r7xx
|
||||
|
||||
Check for relocs for DB_DEPTH_INFO, CB_COLOR*_INFO, and texture
|
||||
resources.
|
||||
|
||||
Signed-off-by: Alex Deucher <alexdeucher@gmail.com>
|
||||
Signed-off-by: Dave Airlie <airlied@redhat.com>
|
||||
|
||||
drivers/gpu/drm/radeon/r600_cs.c | 391 ++++++++++++++++++++++++++++++--------
|
||||
drivers/gpu/drm/radeon/r600d.h | 12 ++
|
||||
2 files changed, 324 insertions(+), 79 deletions(-)
|
||||
|
||||
diff --git a/drivers/gpu/drm/radeon/r600_cs.c b/drivers/gpu/drm/radeon/r600_cs.c
|
||||
index 144c32d..0f90fc3 100644
|
||||
--- a/drivers/gpu/drm/radeon/r600_cs.c
|
||||
+++ b/drivers/gpu/drm/radeon/r600_cs.c
|
||||
@@ -25,6 +25,7 @@
|
||||
* Alex Deucher
|
||||
* Jerome Glisse
|
||||
*/
|
||||
+#include <linux/kernel.h>
|
||||
#include "drmP.h"
|
||||
#include "radeon.h"
|
||||
#include "r600d.h"
|
||||
@@ -49,6 +50,7 @@ struct r600_cs_track {
|
||||
u32 nsamples;
|
||||
u32 cb_color_base_last[8];
|
||||
struct radeon_bo *cb_color_bo[8];
|
||||
+ u64 cb_color_bo_mc[8];
|
||||
u32 cb_color_bo_offset[8];
|
||||
struct radeon_bo *cb_color_frag_bo[8];
|
||||
struct radeon_bo *cb_color_tile_bo[8];
|
||||
@@ -66,6 +68,7 @@ struct r600_cs_track {
|
||||
u32 db_depth_size;
|
||||
u32 db_offset;
|
||||
struct radeon_bo *db_bo;
|
||||
+ u64 db_bo_mc;
|
||||
};
|
||||
|
||||
static inline int r600_bpe_from_format(u32 *bpe, u32 format)
|
||||
@@ -132,12 +135,75 @@ static inline int r600_bpe_from_format(u32 *bpe, u32 format)
|
||||
case V_038004_FMT_GB_GR:
|
||||
case V_038004_FMT_BG_RG:
|
||||
case V_038004_COLOR_INVALID:
|
||||
+ default:
|
||||
*bpe = 16;
|
||||
return -EINVAL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
+struct array_mode_checker {
|
||||
+ int array_mode;
|
||||
+ u32 group_size;
|
||||
+ u32 nbanks;
|
||||
+ u32 npipes;
|
||||
+ u32 nsamples;
|
||||
+ u32 bpe;
|
||||
+};
|
||||
+
|
||||
+/* returns alignment in pixels for pitch/height/depth and bytes for base */
|
||||
+static inline int r600_get_array_mode_alignment(struct array_mode_checker *values,
|
||||
+ u32 *pitch_align,
|
||||
+ u32 *height_align,
|
||||
+ u32 *depth_align,
|
||||
+ u64 *base_align)
|
||||
+{
|
||||
+ u32 tile_width = 8;
|
||||
+ u32 tile_height = 8;
|
||||
+ u32 macro_tile_width = values->nbanks;
|
||||
+ u32 macro_tile_height = values->npipes;
|
||||
+ u32 tile_bytes = tile_width * tile_height * values->bpe * values->nsamples;
|
||||
+ u32 macro_tile_bytes = macro_tile_width * macro_tile_height * tile_bytes;
|
||||
+
|
||||
+ switch (values->array_mode) {
|
||||
+ case ARRAY_LINEAR_GENERAL:
|
||||
+ /* technically tile_width/_height for pitch/height */
|
||||
+ *pitch_align = 1; /* tile_width */
|
||||
+ *height_align = 1; /* tile_height */
|
||||
+ *depth_align = 1;
|
||||
+ *base_align = 1;
|
||||
+ break;
|
||||
+ case ARRAY_LINEAR_ALIGNED:
|
||||
+ *pitch_align = max((u32)64, (u32)(values->group_size / values->bpe));
|
||||
+ *height_align = tile_height;
|
||||
+ *depth_align = 1;
|
||||
+ *base_align = values->group_size;
|
||||
+ break;
|
||||
+ case ARRAY_1D_TILED_THIN1:
|
||||
+ *pitch_align = max((u32)tile_width,
|
||||
+ (u32)(values->group_size /
|
||||
+ (tile_height * values->bpe * values->nsamples)));
|
||||
+ *height_align = tile_height;
|
||||
+ *depth_align = 1;
|
||||
+ *base_align = values->group_size;
|
||||
+ break;
|
||||
+ case ARRAY_2D_TILED_THIN1:
|
||||
+ *pitch_align = max((u32)macro_tile_width,
|
||||
+ (u32)(((values->group_size / tile_height) /
|
||||
+ (values->bpe * values->nsamples)) *
|
||||
+ values->nbanks)) * tile_width;
|
||||
+ *height_align = macro_tile_height * tile_height;
|
||||
+ *depth_align = 1;
|
||||
+ *base_align = max(macro_tile_bytes,
|
||||
+ (*pitch_align) * values->bpe * (*height_align) * values->nsamples);
|
||||
+ break;
|
||||
+ default:
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static void r600_cs_track_init(struct r600_cs_track *track)
|
||||
{
|
||||
int i;
|
||||
@@ -151,10 +217,12 @@ static void r600_cs_track_init(struct r600_cs_track *track)
|
||||
track->cb_color_info[i] = 0;
|
||||
track->cb_color_bo[i] = NULL;
|
||||
track->cb_color_bo_offset[i] = 0xFFFFFFFF;
|
||||
+ track->cb_color_bo_mc[i] = 0xFFFFFFFF;
|
||||
}
|
||||
track->cb_target_mask = 0xFFFFFFFF;
|
||||
track->cb_shader_mask = 0xFFFFFFFF;
|
||||
track->db_bo = NULL;
|
||||
+ track->db_bo_mc = 0xFFFFFFFF;
|
||||
/* assume the biggest format and that htile is enabled */
|
||||
track->db_depth_info = 7 | (1 << 25);
|
||||
track->db_depth_view = 0xFFFFC000;
|
||||
@@ -166,70 +234,58 @@ static void r600_cs_track_init(struct r600_cs_track *track)
|
||||
static inline int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i)
|
||||
{
|
||||
struct r600_cs_track *track = p->track;
|
||||
- u32 bpe = 0, pitch, slice_tile_max, size, tmp, height;
|
||||
+ u32 bpe = 0, slice_tile_max, size, tmp;
|
||||
+ u32 height, height_align, pitch, pitch_align, depth_align;
|
||||
+ u64 base_offset, base_align;
|
||||
+ struct array_mode_checker array_check;
|
||||
volatile u32 *ib = p->ib->ptr;
|
||||
+ unsigned array_mode;
|
||||
|
||||
if (G_0280A0_TILE_MODE(track->cb_color_info[i])) {
|
||||
dev_warn(p->dev, "FMASK or CMASK buffer are not supported by this kernel\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
- size = radeon_bo_size(track->cb_color_bo[i]);
|
||||
+ size = radeon_bo_size(track->cb_color_bo[i]) - track->cb_color_bo_offset[i];
|
||||
if (r600_bpe_from_format(&bpe, G_0280A0_FORMAT(track->cb_color_info[i]))) {
|
||||
dev_warn(p->dev, "%s:%d cb invalid format %d for %d (0x%08X)\n",
|
||||
__func__, __LINE__, G_0280A0_FORMAT(track->cb_color_info[i]),
|
||||
i, track->cb_color_info[i]);
|
||||
return -EINVAL;
|
||||
}
|
||||
- pitch = (G_028060_PITCH_TILE_MAX(track->cb_color_size[i]) + 1) << 3;
|
||||
+ /* pitch in pixels */
|
||||
+ pitch = (G_028060_PITCH_TILE_MAX(track->cb_color_size[i]) + 1) * 8;
|
||||
slice_tile_max = G_028060_SLICE_TILE_MAX(track->cb_color_size[i]) + 1;
|
||||
- if (!pitch) {
|
||||
- dev_warn(p->dev, "%s:%d cb pitch (%d) for %d invalid (0x%08X)\n",
|
||||
- __func__, __LINE__, pitch, i, track->cb_color_size[i]);
|
||||
- return -EINVAL;
|
||||
- }
|
||||
- height = size / (pitch * bpe);
|
||||
+ slice_tile_max *= 64;
|
||||
+ height = slice_tile_max / pitch;
|
||||
if (height > 8192)
|
||||
height = 8192;
|
||||
- switch (G_0280A0_ARRAY_MODE(track->cb_color_info[i])) {
|
||||
+ array_mode = G_0280A0_ARRAY_MODE(track->cb_color_info[i]);
|
||||
+
|
||||
+ base_offset = track->cb_color_bo_mc[i] + track->cb_color_bo_offset[i];
|
||||
+ array_check.array_mode = array_mode;
|
||||
+ array_check.group_size = track->group_size;
|
||||
+ array_check.nbanks = track->nbanks;
|
||||
+ array_check.npipes = track->npipes;
|
||||
+ array_check.nsamples = track->nsamples;
|
||||
+ array_check.bpe = bpe;
|
||||
+ if (r600_get_array_mode_alignment(&array_check,
|
||||
+ &pitch_align, &height_align, &depth_align, &base_align)) {
|
||||
+ dev_warn(p->dev, "%s invalid tiling %d for %d (0x%08X)\n", __func__,
|
||||
+ G_0280A0_ARRAY_MODE(track->cb_color_info[i]), i,
|
||||
+ track->cb_color_info[i]);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+ switch (array_mode) {
|
||||
case V_0280A0_ARRAY_LINEAR_GENERAL:
|
||||
+ break;
|
||||
case V_0280A0_ARRAY_LINEAR_ALIGNED:
|
||||
- if (pitch & 0x3f) {
|
||||
- dev_warn(p->dev, "%s:%d cb pitch (%d x %d = %d) invalid\n",
|
||||
- __func__, __LINE__, pitch, bpe, pitch * bpe);
|
||||
- return -EINVAL;
|
||||
- }
|
||||
- if ((pitch * bpe) & (track->group_size - 1)) {
|
||||
- dev_warn(p->dev, "%s:%d cb pitch (%d) invalid\n",
|
||||
- __func__, __LINE__, pitch);
|
||||
- return -EINVAL;
|
||||
- }
|
||||
break;
|
||||
case V_0280A0_ARRAY_1D_TILED_THIN1:
|
||||
- if ((pitch * 8 * bpe * track->nsamples) & (track->group_size - 1)) {
|
||||
- dev_warn(p->dev, "%s:%d cb pitch (%d) invalid\n",
|
||||
- __func__, __LINE__, pitch);
|
||||
- return -EINVAL;
|
||||
- }
|
||||
- height &= ~0x7;
|
||||
- if (!height)
|
||||
- height = 8;
|
||||
+ /* avoid breaking userspace */
|
||||
+ if (height > 7)
|
||||
+ height &= ~0x7;
|
||||
break;
|
||||
case V_0280A0_ARRAY_2D_TILED_THIN1:
|
||||
- if (pitch & ((8 * track->nbanks) - 1)) {
|
||||
- dev_warn(p->dev, "%s:%d cb pitch (%d) invalid\n",
|
||||
- __func__, __LINE__, pitch);
|
||||
- return -EINVAL;
|
||||
- }
|
||||
- tmp = pitch * 8 * bpe * track->nsamples;
|
||||
- tmp = tmp / track->nbanks;
|
||||
- if (tmp & (track->group_size - 1)) {
|
||||
- dev_warn(p->dev, "%s:%d cb pitch (%d) invalid\n",
|
||||
- __func__, __LINE__, pitch);
|
||||
- return -EINVAL;
|
||||
- }
|
||||
- height &= ~((16 * track->npipes) - 1);
|
||||
- if (!height)
|
||||
- height = 16 * track->npipes;
|
||||
break;
|
||||
default:
|
||||
dev_warn(p->dev, "%s invalid tiling %d for %d (0x%08X)\n", __func__,
|
||||
@@ -237,17 +293,43 @@ static inline int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i)
|
||||
track->cb_color_info[i]);
|
||||
return -EINVAL;
|
||||
}
|
||||
+
|
||||
+ if (!IS_ALIGNED(pitch, pitch_align)) {
|
||||
+ dev_warn(p->dev, "%s:%d cb pitch (%d) invalid\n",
|
||||
+ __func__, __LINE__, pitch);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+ if (!IS_ALIGNED(height, height_align)) {
|
||||
+ dev_warn(p->dev, "%s:%d cb height (%d) invalid\n",
|
||||
+ __func__, __LINE__, height);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+ if (!IS_ALIGNED(base_offset, base_align)) {
|
||||
+ dev_warn(p->dev, "%s offset[%d] 0x%llx not aligned\n", __func__, i, base_offset);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
/* check offset */
|
||||
- tmp = height * pitch;
|
||||
+ tmp = height * pitch * bpe;
|
||||
if ((tmp + track->cb_color_bo_offset[i]) > radeon_bo_size(track->cb_color_bo[i])) {
|
||||
- dev_warn(p->dev, "%s offset[%d] %d to big\n", __func__, i, track->cb_color_bo_offset[i]);
|
||||
- return -EINVAL;
|
||||
+ if (array_mode == V_0280A0_ARRAY_LINEAR_GENERAL) {
|
||||
+ /* the initial DDX does bad things with the CB size occasionally */
|
||||
+ /* it rounds up height too far for slice tile max but the BO is smaller */
|
||||
+ tmp = (height - 7) * 8 * bpe;
|
||||
+ if ((tmp + track->cb_color_bo_offset[i]) > radeon_bo_size(track->cb_color_bo[i])) {
|
||||
+ dev_warn(p->dev, "%s offset[%d] %d %d %lu too big\n", __func__, i, track->cb_color_bo_offset[i], tmp, radeon_bo_size(track->cb_color_bo[i]));
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+ } else {
|
||||
+ dev_warn(p->dev, "%s offset[%d] %d %d %lu too big\n", __func__, i, track->cb_color_bo_offset[i], tmp, radeon_bo_size(track->cb_color_bo[i]));
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
}
|
||||
/* limit max tile */
|
||||
tmp = (height * pitch) >> 6;
|
||||
if (tmp < slice_tile_max)
|
||||
slice_tile_max = tmp;
|
||||
- tmp = S_028060_PITCH_TILE_MAX((pitch >> 3) - 1) |
|
||||
+ tmp = S_028060_PITCH_TILE_MAX((pitch / 8) - 1) |
|
||||
S_028060_SLICE_TILE_MAX(slice_tile_max - 1);
|
||||
ib[track->cb_color_size_idx[i]] = tmp;
|
||||
return 0;
|
||||
@@ -289,7 +371,12 @@ static int r600_cs_track_check(struct radeon_cs_parser *p)
|
||||
/* Check depth buffer */
|
||||
if (G_028800_STENCIL_ENABLE(track->db_depth_control) ||
|
||||
G_028800_Z_ENABLE(track->db_depth_control)) {
|
||||
- u32 nviews, bpe, ntiles;
|
||||
+ u32 nviews, bpe, ntiles, size, slice_tile_max;
|
||||
+ u32 height, height_align, pitch, pitch_align, depth_align;
|
||||
+ u64 base_offset, base_align;
|
||||
+ struct array_mode_checker array_check;
|
||||
+ int array_mode;
|
||||
+
|
||||
if (track->db_bo == NULL) {
|
||||
dev_warn(p->dev, "z/stencil with no depth buffer\n");
|
||||
return -EINVAL;
|
||||
@@ -321,7 +408,6 @@ static int r600_cs_track_check(struct radeon_cs_parser *p)
|
||||
dev_warn(p->dev, "z/stencil buffer size not set\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
- printk_once(KERN_WARNING "You have old & broken userspace please consider updating mesa\n");
|
||||
tmp = radeon_bo_size(track->db_bo) - track->db_offset;
|
||||
tmp = (tmp / bpe) >> 6;
|
||||
if (!tmp) {
|
||||
@@ -332,11 +418,63 @@ static int r600_cs_track_check(struct radeon_cs_parser *p)
|
||||
}
|
||||
ib[track->db_depth_size_idx] = S_028000_SLICE_TILE_MAX(tmp - 1) | (track->db_depth_size & 0x3FF);
|
||||
} else {
|
||||
+ size = radeon_bo_size(track->db_bo);
|
||||
+ /* pitch in pixels */
|
||||
+ pitch = (G_028000_PITCH_TILE_MAX(track->db_depth_size) + 1) * 8;
|
||||
+ slice_tile_max = G_028000_SLICE_TILE_MAX(track->db_depth_size) + 1;
|
||||
+ slice_tile_max *= 64;
|
||||
+ height = slice_tile_max / pitch;
|
||||
+ if (height > 8192)
|
||||
+ height = 8192;
|
||||
+ base_offset = track->db_bo_mc + track->db_offset;
|
||||
+ array_mode = G_028010_ARRAY_MODE(track->db_depth_info);
|
||||
+ array_check.array_mode = array_mode;
|
||||
+ array_check.group_size = track->group_size;
|
||||
+ array_check.nbanks = track->nbanks;
|
||||
+ array_check.npipes = track->npipes;
|
||||
+ array_check.nsamples = track->nsamples;
|
||||
+ array_check.bpe = bpe;
|
||||
+ if (r600_get_array_mode_alignment(&array_check,
|
||||
+ &pitch_align, &height_align, &depth_align, &base_align)) {
|
||||
+ dev_warn(p->dev, "%s invalid tiling %d (0x%08X)\n", __func__,
|
||||
+ G_028010_ARRAY_MODE(track->db_depth_info),
|
||||
+ track->db_depth_info);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+ switch (array_mode) {
|
||||
+ case V_028010_ARRAY_1D_TILED_THIN1:
|
||||
+ /* don't break userspace */
|
||||
+ height &= ~0x7;
|
||||
+ break;
|
||||
+ case V_028010_ARRAY_2D_TILED_THIN1:
|
||||
+ break;
|
||||
+ default:
|
||||
+ dev_warn(p->dev, "%s invalid tiling %d (0x%08X)\n", __func__,
|
||||
+ G_028010_ARRAY_MODE(track->db_depth_info),
|
||||
+ track->db_depth_info);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ if (!IS_ALIGNED(pitch, pitch_align)) {
|
||||
+ dev_warn(p->dev, "%s:%d db pitch (%d) invalid\n",
|
||||
+ __func__, __LINE__, pitch);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+ if (!IS_ALIGNED(height, height_align)) {
|
||||
+ dev_warn(p->dev, "%s:%d db height (%d) invalid\n",
|
||||
+ __func__, __LINE__, height);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+ if (!IS_ALIGNED(base_offset, base_align)) {
|
||||
+ dev_warn(p->dev, "%s offset[%d] 0x%llx not aligned\n", __func__, i, base_offset);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
ntiles = G_028000_SLICE_TILE_MAX(track->db_depth_size) + 1;
|
||||
nviews = G_028004_SLICE_MAX(track->db_depth_view) + 1;
|
||||
tmp = ntiles * bpe * 64 * nviews;
|
||||
if ((tmp + track->db_offset) > radeon_bo_size(track->db_bo)) {
|
||||
- dev_warn(p->dev, "z/stencil buffer too small (0x%08X %d %d %d -> %d have %ld)\n",
|
||||
+ dev_warn(p->dev, "z/stencil buffer too small (0x%08X %d %d %d -> %u have %lu)\n",
|
||||
track->db_depth_size, ntiles, nviews, bpe, tmp + track->db_offset,
|
||||
radeon_bo_size(track->db_bo));
|
||||
return -EINVAL;
|
||||
@@ -724,7 +862,25 @@ static inline int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx
|
||||
track->db_depth_control = radeon_get_ib_value(p, idx);
|
||||
break;
|
||||
case R_028010_DB_DEPTH_INFO:
|
||||
- track->db_depth_info = radeon_get_ib_value(p, idx);
|
||||
+ if (r600_cs_packet_next_is_pkt3_nop(p)) {
|
||||
+ r = r600_cs_packet_next_reloc(p, &reloc);
|
||||
+ if (r) {
|
||||
+ dev_warn(p->dev, "bad SET_CONTEXT_REG "
|
||||
+ "0x%04X\n", reg);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+ track->db_depth_info = radeon_get_ib_value(p, idx);
|
||||
+ ib[idx] &= C_028010_ARRAY_MODE;
|
||||
+ track->db_depth_info &= C_028010_ARRAY_MODE;
|
||||
+ if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) {
|
||||
+ ib[idx] |= S_028010_ARRAY_MODE(V_028010_ARRAY_2D_TILED_THIN1);
|
||||
+ track->db_depth_info |= S_028010_ARRAY_MODE(V_028010_ARRAY_2D_TILED_THIN1);
|
||||
+ } else {
|
||||
+ ib[idx] |= S_028010_ARRAY_MODE(V_028010_ARRAY_1D_TILED_THIN1);
|
||||
+ track->db_depth_info |= S_028010_ARRAY_MODE(V_028010_ARRAY_1D_TILED_THIN1);
|
||||
+ }
|
||||
+ } else
|
||||
+ track->db_depth_info = radeon_get_ib_value(p, idx);
|
||||
break;
|
||||
case R_028004_DB_DEPTH_VIEW:
|
||||
track->db_depth_view = radeon_get_ib_value(p, idx);
|
||||
@@ -757,8 +913,25 @@ static inline int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx
|
||||
case R_0280B4_CB_COLOR5_INFO:
|
||||
case R_0280B8_CB_COLOR6_INFO:
|
||||
case R_0280BC_CB_COLOR7_INFO:
|
||||
- tmp = (reg - R_0280A0_CB_COLOR0_INFO) / 4;
|
||||
- track->cb_color_info[tmp] = radeon_get_ib_value(p, idx);
|
||||
+ if (r600_cs_packet_next_is_pkt3_nop(p)) {
|
||||
+ r = r600_cs_packet_next_reloc(p, &reloc);
|
||||
+ if (r) {
|
||||
+ dev_err(p->dev, "bad SET_CONTEXT_REG 0x%04X\n", reg);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+ tmp = (reg - R_0280A0_CB_COLOR0_INFO) / 4;
|
||||
+ track->cb_color_info[tmp] = radeon_get_ib_value(p, idx);
|
||||
+ if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) {
|
||||
+ ib[idx] |= S_0280A0_ARRAY_MODE(V_0280A0_ARRAY_2D_TILED_THIN1);
|
||||
+ track->cb_color_info[tmp] |= S_0280A0_ARRAY_MODE(V_0280A0_ARRAY_2D_TILED_THIN1);
|
||||
+ } else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) {
|
||||
+ ib[idx] |= S_0280A0_ARRAY_MODE(V_0280A0_ARRAY_1D_TILED_THIN1);
|
||||
+ track->cb_color_info[tmp] |= S_0280A0_ARRAY_MODE(V_0280A0_ARRAY_1D_TILED_THIN1);
|
||||
+ }
|
||||
+ } else {
|
||||
+ tmp = (reg - R_0280A0_CB_COLOR0_INFO) / 4;
|
||||
+ track->cb_color_info[tmp] = radeon_get_ib_value(p, idx);
|
||||
+ }
|
||||
break;
|
||||
case R_028060_CB_COLOR0_SIZE:
|
||||
case R_028064_CB_COLOR1_SIZE:
|
||||
@@ -796,8 +969,6 @@ static inline int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx
|
||||
return -EINVAL;
|
||||
}
|
||||
ib[idx] = track->cb_color_base_last[tmp];
|
||||
- printk_once(KERN_WARNING "You have old & broken userspace "
|
||||
- "please consider updating mesa & xf86-video-ati\n");
|
||||
track->cb_color_frag_bo[tmp] = track->cb_color_bo[tmp];
|
||||
} else {
|
||||
r = r600_cs_packet_next_reloc(p, &reloc);
|
||||
@@ -824,8 +995,6 @@ static inline int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx
|
||||
return -EINVAL;
|
||||
}
|
||||
ib[idx] = track->cb_color_base_last[tmp];
|
||||
- printk_once(KERN_WARNING "You have old & broken userspace "
|
||||
- "please consider updating mesa & xf86-video-ati\n");
|
||||
track->cb_color_tile_bo[tmp] = track->cb_color_bo[tmp];
|
||||
} else {
|
||||
r = r600_cs_packet_next_reloc(p, &reloc);
|
||||
@@ -852,10 +1021,11 @@ static inline int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx
|
||||
return -EINVAL;
|
||||
}
|
||||
tmp = (reg - CB_COLOR0_BASE) / 4;
|
||||
- track->cb_color_bo_offset[tmp] = radeon_get_ib_value(p, idx);
|
||||
+ track->cb_color_bo_offset[tmp] = radeon_get_ib_value(p, idx) << 8;
|
||||
ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
|
||||
track->cb_color_base_last[tmp] = ib[idx];
|
||||
track->cb_color_bo[tmp] = reloc->robj;
|
||||
+ track->cb_color_bo_mc[tmp] = reloc->lobj.gpu_offset;
|
||||
break;
|
||||
case DB_DEPTH_BASE:
|
||||
r = r600_cs_packet_next_reloc(p, &reloc);
|
||||
@@ -864,9 +1034,10 @@ static inline int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx
|
||||
"0x%04X\n", reg);
|
||||
return -EINVAL;
|
||||
}
|
||||
- track->db_offset = radeon_get_ib_value(p, idx);
|
||||
+ track->db_offset = radeon_get_ib_value(p, idx) << 8;
|
||||
ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
|
||||
track->db_bo = reloc->robj;
|
||||
+ track->db_bo_mc = reloc->lobj.gpu_offset;
|
||||
break;
|
||||
case DB_HTILE_DATA_BASE:
|
||||
case SQ_PGM_START_FS:
|
||||
@@ -946,8 +1117,9 @@ static inline unsigned minify(unsigned size, unsigned levels)
|
||||
}
|
||||
|
||||
static void r600_texture_size(unsigned nfaces, unsigned blevel, unsigned nlevels,
|
||||
- unsigned w0, unsigned h0, unsigned d0, unsigned bpe,
|
||||
- unsigned *l0_size, unsigned *mipmap_size)
|
||||
+ unsigned w0, unsigned h0, unsigned d0, unsigned bpe,
|
||||
+ unsigned pitch_align,
|
||||
+ unsigned *l0_size, unsigned *mipmap_size)
|
||||
{
|
||||
unsigned offset, i, level, face;
|
||||
unsigned width, height, depth, rowstride, size;
|
||||
@@ -960,18 +1132,18 @@ static void r600_texture_size(unsigned nfaces, unsigned blevel, unsigned nlevels
|
||||
height = minify(h0, i);
|
||||
depth = minify(d0, i);
|
||||
for(face = 0; face < nfaces; face++) {
|
||||
- rowstride = ((width * bpe) + 255) & ~255;
|
||||
+ rowstride = ALIGN((width * bpe), pitch_align);
|
||||
size = height * rowstride * depth;
|
||||
offset += size;
|
||||
offset = (offset + 0x1f) & ~0x1f;
|
||||
}
|
||||
}
|
||||
- *l0_size = (((w0 * bpe) + 255) & ~255) * h0 * d0;
|
||||
+ *l0_size = ALIGN((w0 * bpe), pitch_align) * h0 * d0;
|
||||
*mipmap_size = offset;
|
||||
- if (!blevel)
|
||||
- *mipmap_size -= *l0_size;
|
||||
if (!nlevels)
|
||||
*mipmap_size = *l0_size;
|
||||
+ if (!blevel)
|
||||
+ *mipmap_size -= *l0_size;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -985,16 +1157,32 @@ static void r600_texture_size(unsigned nfaces, unsigned blevel, unsigned nlevels
|
||||
* the texture and mipmap bo object are big enough to cover this resource.
|
||||
*/
|
||||
static inline int r600_check_texture_resource(struct radeon_cs_parser *p, u32 idx,
|
||||
- struct radeon_bo *texture,
|
||||
- struct radeon_bo *mipmap)
|
||||
+ struct radeon_bo *texture,
|
||||
+ struct radeon_bo *mipmap,
|
||||
+ u64 base_offset,
|
||||
+ u64 mip_offset,
|
||||
+ u32 tiling_flags)
|
||||
{
|
||||
+ struct r600_cs_track *track = p->track;
|
||||
u32 nfaces, nlevels, blevel, w0, h0, d0, bpe = 0;
|
||||
u32 word0, word1, l0_size, mipmap_size;
|
||||
+ u32 height_align, pitch, pitch_align, depth_align;
|
||||
+ u64 base_align;
|
||||
+ struct array_mode_checker array_check;
|
||||
|
||||
/* on legacy kernel we don't perform advanced check */
|
||||
if (p->rdev == NULL)
|
||||
return 0;
|
||||
+
|
||||
+ /* convert to bytes */
|
||||
+ base_offset <<= 8;
|
||||
+ mip_offset <<= 8;
|
||||
+
|
||||
word0 = radeon_get_ib_value(p, idx + 0);
|
||||
+ if (tiling_flags & RADEON_TILING_MACRO)
|
||||
+ word0 |= S_038000_TILE_MODE(V_038000_ARRAY_2D_TILED_THIN1);
|
||||
+ else if (tiling_flags & RADEON_TILING_MICRO)
|
||||
+ word0 |= S_038000_TILE_MODE(V_038000_ARRAY_1D_TILED_THIN1);
|
||||
word1 = radeon_get_ib_value(p, idx + 1);
|
||||
w0 = G_038000_TEX_WIDTH(word0) + 1;
|
||||
h0 = G_038004_TEX_HEIGHT(word1) + 1;
|
||||
@@ -1021,24 +1209,59 @@ static inline int r600_check_texture_resource(struct radeon_cs_parser *p, u32 i
|
||||
__func__, __LINE__, G_038004_DATA_FORMAT(word1));
|
||||
return -EINVAL;
|
||||
}
|
||||
+
|
||||
+ /* pitch in texels */
|
||||
+ pitch = (G_038000_PITCH(word0) + 1) * 8;
|
||||
+ array_check.array_mode = G_038000_TILE_MODE(word0);
|
||||
+ array_check.group_size = track->group_size;
|
||||
+ array_check.nbanks = track->nbanks;
|
||||
+ array_check.npipes = track->npipes;
|
||||
+ array_check.nsamples = 1;
|
||||
+ array_check.bpe = bpe;
|
||||
+ if (r600_get_array_mode_alignment(&array_check,
|
||||
+ &pitch_align, &height_align, &depth_align, &base_align)) {
|
||||
+ dev_warn(p->dev, "%s:%d tex array mode (%d) invalid\n",
|
||||
+ __func__, __LINE__, G_038000_TILE_MODE(word0));
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ /* XXX check height as well... */
|
||||
+
|
||||
+ if (!IS_ALIGNED(pitch, pitch_align)) {
|
||||
+ dev_warn(p->dev, "%s:%d tex pitch (%d) invalid\n",
|
||||
+ __func__, __LINE__, pitch);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+ if (!IS_ALIGNED(base_offset, base_align)) {
|
||||
+ dev_warn(p->dev, "%s:%d tex base offset (0x%llx) invalid\n",
|
||||
+ __func__, __LINE__, base_offset);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+ if (!IS_ALIGNED(mip_offset, base_align)) {
|
||||
+ dev_warn(p->dev, "%s:%d tex mip offset (0x%llx) invalid\n",
|
||||
+ __func__, __LINE__, mip_offset);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
word0 = radeon_get_ib_value(p, idx + 4);
|
||||
word1 = radeon_get_ib_value(p, idx + 5);
|
||||
blevel = G_038010_BASE_LEVEL(word0);
|
||||
nlevels = G_038014_LAST_LEVEL(word1);
|
||||
- r600_texture_size(nfaces, blevel, nlevels, w0, h0, d0, bpe, &l0_size, &mipmap_size);
|
||||
+ r600_texture_size(nfaces, blevel, nlevels, w0, h0, d0, bpe,
|
||||
+ (pitch_align * bpe),
|
||||
+ &l0_size, &mipmap_size);
|
||||
/* using get ib will give us the offset into the texture bo */
|
||||
- word0 = radeon_get_ib_value(p, idx + 2);
|
||||
+ word0 = radeon_get_ib_value(p, idx + 2) << 8;
|
||||
if ((l0_size + word0) > radeon_bo_size(texture)) {
|
||||
dev_warn(p->dev, "texture bo too small (%d %d %d %d -> %d have %ld)\n",
|
||||
w0, h0, bpe, word0, l0_size, radeon_bo_size(texture));
|
||||
return -EINVAL;
|
||||
}
|
||||
/* using get ib will give us the offset into the mipmap bo */
|
||||
- word0 = radeon_get_ib_value(p, idx + 3);
|
||||
+ word0 = radeon_get_ib_value(p, idx + 3) << 8;
|
||||
if ((mipmap_size + word0) > radeon_bo_size(mipmap)) {
|
||||
- dev_warn(p->dev, "mipmap bo too small (%d %d %d %d %d %d -> %d have %ld)\n",
|
||||
- w0, h0, bpe, blevel, nlevels, word0, mipmap_size, radeon_bo_size(texture));
|
||||
- return -EINVAL;
|
||||
+ /*dev_warn(p->dev, "mipmap bo too small (%d %d %d %d %d %d -> %d have %ld)\n",
|
||||
+ w0, h0, bpe, blevel, nlevels, word0, mipmap_size, radeon_bo_size(texture));*/
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -1228,7 +1451,7 @@ static int r600_packet3_check(struct radeon_cs_parser *p,
|
||||
}
|
||||
for (i = 0; i < (pkt->count / 7); i++) {
|
||||
struct radeon_bo *texture, *mipmap;
|
||||
- u32 size, offset;
|
||||
+ u32 size, offset, base_offset, mip_offset;
|
||||
|
||||
switch (G__SQ_VTX_CONSTANT_TYPE(radeon_get_ib_value(p, idx+(i*7)+6+1))) {
|
||||
case SQ_TEX_VTX_VALID_TEXTURE:
|
||||
@@ -1238,7 +1461,11 @@ static int r600_packet3_check(struct radeon_cs_parser *p,
|
||||
DRM_ERROR("bad SET_RESOURCE\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
- ib[idx+1+(i*7)+2] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
|
||||
+ base_offset = (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
|
||||
+ if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO)
|
||||
+ ib[idx+1+(i*7)+0] |= S_038000_TILE_MODE(V_038000_ARRAY_2D_TILED_THIN1);
|
||||
+ else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO)
|
||||
+ ib[idx+1+(i*7)+0] |= S_038000_TILE_MODE(V_038000_ARRAY_1D_TILED_THIN1);
|
||||
texture = reloc->robj;
|
||||
/* tex mip base */
|
||||
r = r600_cs_packet_next_reloc(p, &reloc);
|
||||
@@ -1246,12 +1473,17 @@ static int r600_packet3_check(struct radeon_cs_parser *p,
|
||||
DRM_ERROR("bad SET_RESOURCE\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
- ib[idx+1+(i*7)+3] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
|
||||
+ mip_offset = (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
|
||||
mipmap = reloc->robj;
|
||||
r = r600_check_texture_resource(p, idx+(i*7)+1,
|
||||
- texture, mipmap);
|
||||
+ texture, mipmap,
|
||||
+ base_offset + radeon_get_ib_value(p, idx+1+(i*7)+2),
|
||||
+ mip_offset + radeon_get_ib_value(p, idx+1+(i*7)+3),
|
||||
+ reloc->lobj.tiling_flags);
|
||||
if (r)
|
||||
return r;
|
||||
+ ib[idx+1+(i*7)+2] += base_offset;
|
||||
+ ib[idx+1+(i*7)+3] += mip_offset;
|
||||
break;
|
||||
case SQ_TEX_VTX_VALID_BUFFER:
|
||||
/* vtx base */
|
||||
@@ -1261,10 +1493,11 @@ static int r600_packet3_check(struct radeon_cs_parser *p,
|
||||
return -EINVAL;
|
||||
}
|
||||
offset = radeon_get_ib_value(p, idx+1+(i*7)+0);
|
||||
- size = radeon_get_ib_value(p, idx+1+(i*7)+1);
|
||||
+ size = radeon_get_ib_value(p, idx+1+(i*7)+1) + 1;
|
||||
if (p->rdev && (size + offset) > radeon_bo_size(reloc->robj)) {
|
||||
/* force size to size of the buffer */
|
||||
- dev_warn(p->dev, "vbo resource seems too big for the bo\n");
|
||||
+ dev_warn(p->dev, "vbo resource seems too big (%d) for the bo (%ld)\n",
|
||||
+ size + offset, radeon_bo_size(reloc->robj));
|
||||
ib[idx+1+(i*7)+1] = radeon_bo_size(reloc->robj);
|
||||
}
|
||||
ib[idx+1+(i*7)+0] += (u32)((reloc->lobj.gpu_offset) & 0xffffffff);
|
||||
diff --git a/drivers/gpu/drm/radeon/r600d.h b/drivers/gpu/drm/radeon/r600d.h
|
||||
index 84bc28e..9577945 100644
|
||||
--- a/drivers/gpu/drm/radeon/r600d.h
|
||||
+++ b/drivers/gpu/drm/radeon/r600d.h
|
||||
@@ -51,6 +51,12 @@
|
||||
#define PTE_READABLE (1 << 5)
|
||||
#define PTE_WRITEABLE (1 << 6)
|
||||
|
||||
+/* tiling bits */
|
||||
+#define ARRAY_LINEAR_GENERAL 0x00000000
|
||||
+#define ARRAY_LINEAR_ALIGNED 0x00000001
|
||||
+#define ARRAY_1D_TILED_THIN1 0x00000002
|
||||
+#define ARRAY_2D_TILED_THIN1 0x00000004
|
||||
+
|
||||
/* Registers */
|
||||
#define ARB_POP 0x2418
|
||||
#define ENABLE_TC128 (1 << 30)
|
||||
@@ -1155,6 +1161,10 @@
|
||||
#define S_038000_TILE_MODE(x) (((x) & 0xF) << 3)
|
||||
#define G_038000_TILE_MODE(x) (((x) >> 3) & 0xF)
|
||||
#define C_038000_TILE_MODE 0xFFFFFF87
|
||||
+#define V_038000_ARRAY_LINEAR_GENERAL 0x00000000
|
||||
+#define V_038000_ARRAY_LINEAR_ALIGNED 0x00000001
|
||||
+#define V_038000_ARRAY_1D_TILED_THIN1 0x00000002
|
||||
+#define V_038000_ARRAY_2D_TILED_THIN1 0x00000004
|
||||
#define S_038000_TILE_TYPE(x) (((x) & 0x1) << 7)
|
||||
#define G_038000_TILE_TYPE(x) (((x) >> 7) & 0x1)
|
||||
#define C_038000_TILE_TYPE 0xFFFFFF7F
|
||||
@@ -1358,6 +1368,8 @@
|
||||
#define S_028010_ARRAY_MODE(x) (((x) & 0xF) << 15)
|
||||
#define G_028010_ARRAY_MODE(x) (((x) >> 15) & 0xF)
|
||||
#define C_028010_ARRAY_MODE 0xFFF87FFF
|
||||
+#define V_028010_ARRAY_1D_TILED_THIN1 0x00000002
|
||||
+#define V_028010_ARRAY_2D_TILED_THIN1 0x00000004
|
||||
#define S_028010_TILE_SURFACE_ENABLE(x) (((x) & 0x1) << 25)
|
||||
#define G_028010_TILE_SURFACE_ENABLE(x) (((x) >> 25) & 0x1)
|
||||
#define C_028010_TILE_SURFACE_ENABLE 0xFDFFFFFF
|
|
@ -1,958 +0,0 @@
|
|||
From 5b904034b0ab5195d971b139d0c0b67ab21b063c Mon Sep 17 00:00:00 2001
|
||||
From: Kyle McMartin <kyle@dreadnought.i.jkkm.org>
|
||||
Date: Mon, 21 Jun 2010 20:33:16 +0100
|
||||
Subject: Revert "drm/fbdev: rework output polling to be back in the core. (v4)"
|
||||
|
||||
This reverts commit eb1f8e4f3be898df808e2dfc131099f5831d491d.
|
||||
|
||||
Conflicts:
|
||||
|
||||
drivers/gpu/drm/drm_crtc_helper.c
|
||||
drivers/gpu/drm/i915/i915_dma.c
|
||||
drivers/gpu/drm/i915/intel_fb.c
|
||||
drivers/gpu/drm/nouveau/nouveau_fbcon.c
|
||||
drivers/gpu/drm/radeon/radeon_fb.c
|
||||
include/drm/drm_crtc_helper.h
|
||||
---
|
||||
drivers/gpu/drm/Kconfig | 2 +-
|
||||
drivers/gpu/drm/drm_crtc_helper.c | 111 ------------------------
|
||||
drivers/gpu/drm/drm_fb_helper.c | 123 +++++++++++++++++++++++----
|
||||
drivers/gpu/drm/i915/i915_dma.c | 1 -
|
||||
drivers/gpu/drm/i915/i915_irq.c | 3 +-
|
||||
drivers/gpu/drm/i915/intel_crt.c | 5 -
|
||||
drivers/gpu/drm/i915/intel_display.c | 2 -
|
||||
drivers/gpu/drm/i915/intel_dp.c | 2 -
|
||||
drivers/gpu/drm/i915/intel_drv.h | 2 +-
|
||||
drivers/gpu/drm/i915/intel_fb.c | 14 ++--
|
||||
drivers/gpu/drm/i915/intel_hdmi.c | 1 -
|
||||
drivers/gpu/drm/i915/intel_sdvo.c | 2 -
|
||||
drivers/gpu/drm/nouveau/nouveau_connector.c | 12 ---
|
||||
drivers/gpu/drm/nouveau/nouveau_display.c | 1 -
|
||||
drivers/gpu/drm/nouveau/nouveau_fbcon.c | 13 ++-
|
||||
drivers/gpu/drm/nouveau/nouveau_fbcon.h | 2 +-
|
||||
drivers/gpu/drm/nouveau/nouveau_state.c | 5 +-
|
||||
drivers/gpu/drm/nouveau/nv50_display.c | 2 +-
|
||||
drivers/gpu/drm/radeon/radeon_connectors.c | 13 ---
|
||||
drivers/gpu/drm/radeon/radeon_display.c | 10 --
|
||||
drivers/gpu/drm/radeon/radeon_fb.c | 15 +++-
|
||||
drivers/gpu/drm/radeon/radeon_irq_kms.c | 5 +-
|
||||
drivers/gpu/drm/radeon/radeon_mode.h | 3 +-
|
||||
include/drm/drm_crtc.h | 17 ----
|
||||
include/drm/drm_crtc_helper.h | 6 --
|
||||
include/drm/drm_fb_helper.h | 13 +++-
|
||||
26 files changed, 155 insertions(+), 230 deletions(-)
|
||||
|
||||
diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
|
||||
index c2711c6..a51a1e4 100644
|
||||
--- a/drivers/gpu/drm/Kconfig
|
||||
+++ b/drivers/gpu/drm/Kconfig
|
||||
@@ -9,7 +9,6 @@ menuconfig DRM
|
||||
depends on (AGP || AGP=n) && PCI && !EMULATED_CMPXCHG && MMU
|
||||
select I2C
|
||||
select I2C_ALGOBIT
|
||||
- select SLOW_WORK
|
||||
help
|
||||
Kernel-level support for the Direct Rendering Infrastructure (DRI)
|
||||
introduced in XFree86 4.0. If you say Y here, you need to select
|
||||
@@ -24,6 +23,7 @@ config DRM_KMS_HELPER
|
||||
depends on DRM
|
||||
select FB
|
||||
select FRAMEBUFFER_CONSOLE if !EMBEDDED
|
||||
+ select SLOW_WORK
|
||||
help
|
||||
FB and CRTC helpers for KMS drivers.
|
||||
|
||||
diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c
|
||||
index 9b2a541..b142ac2 100644
|
||||
--- a/drivers/gpu/drm/drm_crtc_helper.c
|
||||
+++ b/drivers/gpu/drm/drm_crtc_helper.c
|
||||
@@ -807,114 +807,3 @@ int drm_helper_resume_force_mode(struct drm_device *dev)
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(drm_helper_resume_force_mode);
|
||||
-
|
||||
-static struct slow_work_ops output_poll_ops;
|
||||
-
|
||||
-#define DRM_OUTPUT_POLL_PERIOD (10*HZ)
|
||||
-static void output_poll_execute(struct slow_work *work)
|
||||
-{
|
||||
- struct delayed_slow_work *delayed_work = container_of(work, struct delayed_slow_work, work);
|
||||
- struct drm_device *dev = container_of(delayed_work, struct drm_device, mode_config.output_poll_slow_work);
|
||||
- struct drm_connector *connector;
|
||||
- enum drm_connector_status old_status, status;
|
||||
- bool repoll = false, changed = false;
|
||||
- int ret;
|
||||
-
|
||||
- mutex_lock(&dev->mode_config.mutex);
|
||||
- list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
|
||||
-
|
||||
- /* if this is HPD or polled don't check it -
|
||||
- TV out for instance */
|
||||
- if (!connector->polled)
|
||||
- continue;
|
||||
-
|
||||
- else if (connector->polled & (DRM_CONNECTOR_POLL_CONNECT | DRM_CONNECTOR_POLL_DISCONNECT))
|
||||
- repoll = true;
|
||||
-
|
||||
- old_status = connector->status;
|
||||
- /* if we are connected and don't want to poll for disconnect
|
||||
- skip it */
|
||||
- if (old_status == connector_status_connected &&
|
||||
- !(connector->polled & DRM_CONNECTOR_POLL_DISCONNECT) &&
|
||||
- !(connector->polled & DRM_CONNECTOR_POLL_HPD))
|
||||
- continue;
|
||||
-
|
||||
- status = connector->funcs->detect(connector);
|
||||
- if (old_status != status)
|
||||
- changed = true;
|
||||
- }
|
||||
-
|
||||
- mutex_unlock(&dev->mode_config.mutex);
|
||||
-
|
||||
- if (changed) {
|
||||
- /* send a uevent + call fbdev */
|
||||
- drm_sysfs_hotplug_event(dev);
|
||||
- if (dev->mode_config.funcs->output_poll_changed)
|
||||
- dev->mode_config.funcs->output_poll_changed(dev);
|
||||
- }
|
||||
-
|
||||
- if (repoll) {
|
||||
- ret = delayed_slow_work_enqueue(delayed_work, DRM_OUTPUT_POLL_PERIOD);
|
||||
- if (ret)
|
||||
- DRM_ERROR("delayed enqueue failed %d\n", ret);
|
||||
- }
|
||||
-}
|
||||
-
|
||||
-void drm_kms_helper_poll_disable(struct drm_device *dev)
|
||||
-{
|
||||
- if (!dev->mode_config.poll_enabled)
|
||||
- return;
|
||||
- delayed_slow_work_cancel(&dev->mode_config.output_poll_slow_work);
|
||||
-}
|
||||
-EXPORT_SYMBOL(drm_kms_helper_poll_disable);
|
||||
-
|
||||
-void drm_kms_helper_poll_enable(struct drm_device *dev)
|
||||
-{
|
||||
- bool poll = false;
|
||||
- struct drm_connector *connector;
|
||||
- int ret;
|
||||
-
|
||||
- list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
|
||||
- if (connector->polled)
|
||||
- poll = true;
|
||||
- }
|
||||
-
|
||||
- if (poll) {
|
||||
- ret = delayed_slow_work_enqueue(&dev->mode_config.output_poll_slow_work, DRM_OUTPUT_POLL_PERIOD);
|
||||
- if (ret)
|
||||
- DRM_ERROR("delayed enqueue failed %d\n", ret);
|
||||
- }
|
||||
-}
|
||||
-EXPORT_SYMBOL(drm_kms_helper_poll_enable);
|
||||
-
|
||||
-void drm_kms_helper_poll_init(struct drm_device *dev)
|
||||
-{
|
||||
- slow_work_register_user(THIS_MODULE);
|
||||
- delayed_slow_work_init(&dev->mode_config.output_poll_slow_work,
|
||||
- &output_poll_ops);
|
||||
- dev->mode_config.poll_enabled = true;
|
||||
-
|
||||
- drm_kms_helper_poll_enable(dev);
|
||||
-}
|
||||
-EXPORT_SYMBOL(drm_kms_helper_poll_init);
|
||||
-
|
||||
-void drm_kms_helper_poll_fini(struct drm_device *dev)
|
||||
-{
|
||||
- drm_kms_helper_poll_disable(dev);
|
||||
- slow_work_unregister_user(THIS_MODULE);
|
||||
-}
|
||||
-EXPORT_SYMBOL(drm_kms_helper_poll_fini);
|
||||
-
|
||||
-void drm_helper_hpd_irq_event(struct drm_device *dev)
|
||||
-{
|
||||
- if (!dev->mode_config.poll_enabled)
|
||||
- return;
|
||||
- delayed_slow_work_cancel(&dev->mode_config.output_poll_slow_work);
|
||||
- /* schedule a slow work asap */
|
||||
- delayed_slow_work_enqueue(&dev->mode_config.output_poll_slow_work, 0);
|
||||
-}
|
||||
-EXPORT_SYMBOL(drm_helper_hpd_irq_event);
|
||||
-
|
||||
-static struct slow_work_ops output_poll_ops = {
|
||||
- .execute = output_poll_execute,
|
||||
-};
|
||||
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c
|
||||
index 08c4c92..dcc6601 100644
|
||||
--- a/drivers/gpu/drm/drm_fb_helper.c
|
||||
+++ b/drivers/gpu/drm/drm_fb_helper.c
|
||||
@@ -42,6 +42,8 @@ MODULE_LICENSE("GPL and additional rights");
|
||||
|
||||
static LIST_HEAD(kernel_fb_helper_list);
|
||||
|
||||
+static struct slow_work_ops output_status_change_ops;
|
||||
+
|
||||
/* simple single crtc case helper function */
|
||||
int drm_fb_helper_single_add_all_connectors(struct drm_fb_helper *fb_helper)
|
||||
{
|
||||
@@ -423,13 +425,19 @@ static void drm_fb_helper_crtc_free(struct drm_fb_helper *helper)
|
||||
|
||||
int drm_fb_helper_init(struct drm_device *dev,
|
||||
struct drm_fb_helper *fb_helper,
|
||||
- int crtc_count, int max_conn_count)
|
||||
+ int crtc_count, int max_conn_count,
|
||||
+ bool polled)
|
||||
{
|
||||
struct drm_crtc *crtc;
|
||||
int ret = 0;
|
||||
int i;
|
||||
|
||||
fb_helper->dev = dev;
|
||||
+ fb_helper->poll_enabled = polled;
|
||||
+
|
||||
+ slow_work_register_user(THIS_MODULE);
|
||||
+ delayed_slow_work_init(&fb_helper->output_status_change_slow_work,
|
||||
+ &output_status_change_ops);
|
||||
|
||||
INIT_LIST_HEAD(&fb_helper->kernel_fb_list);
|
||||
|
||||
@@ -486,6 +494,8 @@ void drm_fb_helper_fini(struct drm_fb_helper *fb_helper)
|
||||
|
||||
drm_fb_helper_crtc_free(fb_helper);
|
||||
|
||||
+ delayed_slow_work_cancel(&fb_helper->output_status_change_slow_work);
|
||||
+ slow_work_unregister_user(THIS_MODULE);
|
||||
}
|
||||
EXPORT_SYMBOL(drm_fb_helper_fini);
|
||||
|
||||
@@ -703,7 +713,7 @@ int drm_fb_helper_set_par(struct fb_info *info)
|
||||
|
||||
if (fb_helper->delayed_hotplug) {
|
||||
fb_helper->delayed_hotplug = false;
|
||||
- drm_fb_helper_hotplug_event(fb_helper);
|
||||
+ delayed_slow_work_enqueue(&fb_helper->output_status_change_slow_work, 0);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -816,7 +826,7 @@ int drm_fb_helper_single_fb_probe(struct drm_fb_helper *fb_helper,
|
||||
if (crtc_count == 0 || sizes.fb_width == -1 || sizes.fb_height == -1) {
|
||||
/* hmm everyone went away - assume VGA cable just fell out
|
||||
and will come back later. */
|
||||
- DRM_INFO("Cannot find any crtc or sizes - going 1024x768\n");
|
||||
+ DRM_ERROR("Cannot find any crtc or sizes - going 1024x768\n");
|
||||
sizes.fb_width = sizes.surface_width = 1024;
|
||||
sizes.fb_height = sizes.surface_height = 768;
|
||||
}
|
||||
@@ -1362,7 +1372,12 @@ bool drm_fb_helper_initial_config(struct drm_fb_helper *fb_helper, int bpp_sel)
|
||||
* we shouldn't end up with no modes here.
|
||||
*/
|
||||
if (count == 0) {
|
||||
- printk(KERN_INFO "No connectors reported connected with modes\n");
|
||||
+ if (fb_helper->poll_enabled) {
|
||||
+ delayed_slow_work_enqueue(&fb_helper->output_status_change_slow_work,
|
||||
+ 5*HZ);
|
||||
+ printk(KERN_INFO "No connectors reported connected with modes - started polling\n");
|
||||
+ } else
|
||||
+ printk(KERN_INFO "No connectors reported connected with modes\n");
|
||||
}
|
||||
drm_setup_crtcs(fb_helper);
|
||||
|
||||
@@ -1370,16 +1385,71 @@ bool drm_fb_helper_initial_config(struct drm_fb_helper *fb_helper, int bpp_sel)
|
||||
}
|
||||
EXPORT_SYMBOL(drm_fb_helper_initial_config);
|
||||
|
||||
-bool drm_fb_helper_hotplug_event(struct drm_fb_helper *fb_helper)
|
||||
+/* we got a hotplug irq - need to update fbcon */
|
||||
+void drm_helper_fb_hpd_irq_event(struct drm_fb_helper *fb_helper)
|
||||
+{
|
||||
+ /* if we don't have the fbdev registered yet do nothing */
|
||||
+ if (!fb_helper->fbdev)
|
||||
+ return;
|
||||
+
|
||||
+ /* schedule a slow work asap */
|
||||
+ delayed_slow_work_enqueue(&fb_helper->output_status_change_slow_work, 0);
|
||||
+}
|
||||
+EXPORT_SYMBOL(drm_helper_fb_hpd_irq_event);
|
||||
+
|
||||
+bool drm_helper_fb_hotplug_event(struct drm_fb_helper *fb_helper, bool polled)
|
||||
{
|
||||
int count = 0;
|
||||
+ int ret;
|
||||
u32 max_width, max_height, bpp_sel;
|
||||
- bool bound = false, crtcs_bound = false;
|
||||
- struct drm_crtc *crtc;
|
||||
|
||||
if (!fb_helper->fb)
|
||||
return false;
|
||||
+ DRM_DEBUG_KMS("\n");
|
||||
+
|
||||
+ max_width = fb_helper->fb->width;
|
||||
+ max_height = fb_helper->fb->height;
|
||||
+ bpp_sel = fb_helper->fb->bits_per_pixel;
|
||||
+
|
||||
+ count = drm_fb_helper_probe_connector_modes(fb_helper, max_width,
|
||||
+ max_height);
|
||||
+ if (fb_helper->poll_enabled && !polled) {
|
||||
+ if (count) {
|
||||
+ delayed_slow_work_cancel(&fb_helper->output_status_change_slow_work);
|
||||
+ } else {
|
||||
+ ret = delayed_slow_work_enqueue(&fb_helper->output_status_change_slow_work, 5*HZ);
|
||||
+ }
|
||||
+ }
|
||||
+ drm_setup_crtcs(fb_helper);
|
||||
+
|
||||
+ return drm_fb_helper_single_fb_probe(fb_helper, bpp_sel);
|
||||
+}
|
||||
+EXPORT_SYMBOL(drm_helper_fb_hotplug_event);
|
||||
+
|
||||
+/*
|
||||
+ * delayed work queue execution function
|
||||
+ * - check if fbdev is actually in use on the gpu
|
||||
+ * - if not set delayed flag and repoll if necessary
|
||||
+ * - check for connector status change
|
||||
+ * - repoll if 0 modes found
|
||||
+ *- call driver output status changed notifier
|
||||
+ */
|
||||
+static void output_status_change_execute(struct slow_work *work)
|
||||
+{
|
||||
+ struct delayed_slow_work *delayed_work = container_of(work, struct delayed_slow_work, work);
|
||||
+ struct drm_fb_helper *fb_helper = container_of(delayed_work, struct drm_fb_helper, output_status_change_slow_work);
|
||||
+ struct drm_connector *connector;
|
||||
+ enum drm_connector_status old_status, status;
|
||||
+ bool repoll, changed = false;
|
||||
+ int ret;
|
||||
+ int i;
|
||||
+ bool bound = false, crtcs_bound = false;
|
||||
+ struct drm_crtc *crtc;
|
||||
|
||||
+ repoll = fb_helper->poll_enabled;
|
||||
+
|
||||
+ /* first of all check the fbcon framebuffer is actually bound to any crtc */
|
||||
+ /* take into account that no crtc at all maybe bound */
|
||||
list_for_each_entry(crtc, &fb_helper->dev->mode_config.crtc_list, head) {
|
||||
if (crtc->fb)
|
||||
crtcs_bound = true;
|
||||
@@ -1387,21 +1457,38 @@ bool drm_fb_helper_hotplug_event(struct drm_fb_helper *fb_helper)
|
||||
bound = true;
|
||||
}
|
||||
|
||||
- if (!bound && crtcs_bound) {
|
||||
+ if (bound == false && crtcs_bound) {
|
||||
fb_helper->delayed_hotplug = true;
|
||||
- return false;
|
||||
+ goto requeue;
|
||||
}
|
||||
- DRM_DEBUG_KMS("\n");
|
||||
|
||||
- max_width = fb_helper->fb->width;
|
||||
- max_height = fb_helper->fb->height;
|
||||
- bpp_sel = fb_helper->fb->bits_per_pixel;
|
||||
+ for (i = 0; i < fb_helper->connector_count; i++) {
|
||||
+ connector = fb_helper->connector_info[i]->connector;
|
||||
+ old_status = connector->status;
|
||||
+ status = connector->funcs->detect(connector);
|
||||
+ if (old_status != status) {
|
||||
+ changed = true;
|
||||
+ }
|
||||
+ if (status == connector_status_connected && repoll) {
|
||||
+ DRM_DEBUG("%s is connected - stop polling\n", drm_get_connector_name(connector));
|
||||
+ repoll = false;
|
||||
+ }
|
||||
+ }
|
||||
|
||||
- count = drm_fb_helper_probe_connector_modes(fb_helper, max_width,
|
||||
- max_height);
|
||||
- drm_setup_crtcs(fb_helper);
|
||||
+ if (changed) {
|
||||
+ if (fb_helper->funcs->fb_output_status_changed)
|
||||
+ fb_helper->funcs->fb_output_status_changed(fb_helper);
|
||||
+ }
|
||||
|
||||
- return drm_fb_helper_single_fb_probe(fb_helper, bpp_sel);
|
||||
+requeue:
|
||||
+ if (repoll) {
|
||||
+ ret = delayed_slow_work_enqueue(delayed_work, 5*HZ);
|
||||
+ if (ret)
|
||||
+ DRM_ERROR("delayed enqueue failed %d\n", ret);
|
||||
+ }
|
||||
}
|
||||
-EXPORT_SYMBOL(drm_fb_helper_hotplug_event);
|
||||
+
|
||||
+static struct slow_work_ops output_status_change_ops = {
|
||||
+ .execute = output_status_change_execute,
|
||||
+};
|
||||
|
||||
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
|
||||
index 59a2bf8..76ace2d 100644
|
||||
--- a/drivers/gpu/drm/i915/i915_dma.c
|
||||
+++ b/drivers/gpu/drm/i915/i915_dma.c
|
||||
@@ -1430,7 +1430,6 @@ static int i915_load_modeset_init(struct drm_device *dev,
|
||||
if (ret)
|
||||
goto cleanup_irq;
|
||||
|
||||
- drm_kms_helper_poll_init(dev);
|
||||
return 0;
|
||||
|
||||
cleanup_irq:
|
||||
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
|
||||
index 2479be0..6350bd3 100644
|
||||
--- a/drivers/gpu/drm/i915/i915_irq.c
|
||||
+++ b/drivers/gpu/drm/i915/i915_irq.c
|
||||
@@ -271,7 +271,8 @@ static void i915_hotplug_work_func(struct work_struct *work)
|
||||
}
|
||||
}
|
||||
/* Just fire off a uevent and let userspace tell us what to do */
|
||||
- drm_helper_hpd_irq_event(dev);
|
||||
+ intelfb_hotplug(dev, false);
|
||||
+ drm_sysfs_hotplug_event(dev);
|
||||
}
|
||||
|
||||
static void i915_handle_rps_change(struct drm_device *dev)
|
||||
diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c
|
||||
index 22ff384..125eded 100644
|
||||
--- a/drivers/gpu/drm/i915/intel_crt.c
|
||||
+++ b/drivers/gpu/drm/i915/intel_crt.c
|
||||
@@ -584,10 +584,5 @@ void intel_crt_init(struct drm_device *dev)
|
||||
|
||||
drm_sysfs_connector_add(connector);
|
||||
|
||||
- if (I915_HAS_HOTPLUG(dev))
|
||||
- connector->polled = DRM_CONNECTOR_POLL_HPD;
|
||||
- else
|
||||
- connector->polled = DRM_CONNECTOR_POLL_CONNECT;
|
||||
-
|
||||
dev_priv->hotplug_supported_mask |= CRT_HOTPLUG_INT_STATUS;
|
||||
}
|
||||
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
|
||||
index d753257..70537cf 100644
|
||||
--- a/drivers/gpu/drm/i915/intel_display.c
|
||||
+++ b/drivers/gpu/drm/i915/intel_display.c
|
||||
@@ -5036,7 +5036,6 @@ intel_user_framebuffer_create(struct drm_device *dev,
|
||||
|
||||
static const struct drm_mode_config_funcs intel_mode_funcs = {
|
||||
.fb_create = intel_user_framebuffer_create,
|
||||
- .output_poll_changed = intel_fb_output_poll_changed,
|
||||
};
|
||||
|
||||
static struct drm_gem_object *
|
||||
@@ -5538,7 +5537,6 @@ void intel_modeset_cleanup(struct drm_device *dev)
|
||||
|
||||
mutex_lock(&dev->struct_mutex);
|
||||
|
||||
- drm_kms_helper_poll_fini(dev);
|
||||
intel_fbdev_fini(dev);
|
||||
|
||||
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
|
||||
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
|
||||
index 49b54f0..1815df5 100644
|
||||
--- a/drivers/gpu/drm/i915/intel_dp.c
|
||||
+++ b/drivers/gpu/drm/i915/intel_dp.c
|
||||
@@ -1393,8 +1393,6 @@ intel_dp_init(struct drm_device *dev, int output_reg)
|
||||
DRM_MODE_CONNECTOR_DisplayPort);
|
||||
drm_connector_helper_add(connector, &intel_dp_connector_helper_funcs);
|
||||
|
||||
- connector->polled = DRM_CONNECTOR_POLL_HPD;
|
||||
-
|
||||
if (output_reg == DP_A)
|
||||
intel_encoder->type = INTEL_OUTPUT_EDP;
|
||||
else
|
||||
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
|
||||
index df931f7..3230e8d 100644
|
||||
--- a/drivers/gpu/drm/i915/intel_drv.h
|
||||
+++ b/drivers/gpu/drm/i915/intel_drv.h
|
||||
@@ -235,5 +235,5 @@ extern int intel_overlay_put_image(struct drm_device *dev, void *data,
|
||||
extern int intel_overlay_attrs(struct drm_device *dev, void *data,
|
||||
struct drm_file *file_priv);
|
||||
|
||||
-extern void intel_fb_output_poll_changed(struct drm_device *dev);
|
||||
+void intelfb_hotplug(struct drm_device *dev, bool polled);
|
||||
#endif /* __INTEL_DRV_H__ */
|
||||
diff --git a/drivers/gpu/drm/i915/intel_fb.c b/drivers/gpu/drm/i915/intel_fb.c
|
||||
index c3c5052..79098b3 100644
|
||||
--- a/drivers/gpu/drm/i915/intel_fb.c
|
||||
+++ b/drivers/gpu/drm/i915/intel_fb.c
|
||||
@@ -211,6 +211,12 @@ static int intel_fb_find_or_create_single(struct drm_fb_helper *helper,
|
||||
return new_fb;
|
||||
}
|
||||
|
||||
+void intelfb_hotplug(struct drm_device *dev, bool polled)
|
||||
+{
|
||||
+ drm_i915_private_t *dev_priv = dev->dev_private;
|
||||
+ drm_helper_fb_hpd_irq_event(&dev_priv->fbdev->helper);
|
||||
+}
|
||||
+
|
||||
static struct drm_fb_helper_funcs intel_fb_helper_funcs = {
|
||||
.gamma_set = intel_crtc_fb_gamma_set,
|
||||
.gamma_get = intel_crtc_fb_gamma_get,
|
||||
@@ -256,7 +262,7 @@ int intel_fbdev_init(struct drm_device *dev)
|
||||
|
||||
ret = drm_fb_helper_init(dev, &ifbdev->helper,
|
||||
dev_priv->num_pipe,
|
||||
- INTELFB_CONN_LIMIT);
|
||||
+ INTELFB_CONN_LIMIT, false);
|
||||
if (ret) {
|
||||
kfree(ifbdev);
|
||||
return ret;
|
||||
@@ -278,9 +284,3 @@ void intel_fbdev_fini(struct drm_device *dev)
|
||||
dev_priv->fbdev = NULL;
|
||||
}
|
||||
MODULE_LICENSE("GPL and additional rights");
|
||||
-
|
||||
-void intel_fb_output_poll_changed(struct drm_device *dev)
|
||||
-{
|
||||
- drm_i915_private_t *dev_priv = dev->dev_private;
|
||||
- drm_fb_helper_hotplug_event(&dev_priv->fbdev->helper);
|
||||
-}
|
||||
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
|
||||
index 83bd764..acaca07 100644
|
||||
--- a/drivers/gpu/drm/i915/intel_hdmi.c
|
||||
+++ b/drivers/gpu/drm/i915/intel_hdmi.c
|
||||
@@ -240,7 +240,6 @@ void intel_hdmi_init(struct drm_device *dev, int sdvox_reg)
|
||||
|
||||
intel_encoder->type = INTEL_OUTPUT_HDMI;
|
||||
|
||||
- connector->polled = DRM_CONNECTOR_POLL_HPD;
|
||||
connector->interlace_allowed = 0;
|
||||
connector->doublescan_allowed = 0;
|
||||
intel_encoder->crtc_mask = (1 << 0) | (1 << 1);
|
||||
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c
|
||||
index 76993ac..1c716b5 100644
|
||||
--- a/drivers/gpu/drm/i915/intel_sdvo.c
|
||||
+++ b/drivers/gpu/drm/i915/intel_sdvo.c
|
||||
@@ -2218,7 +2218,6 @@ intel_sdvo_dvi_init(struct intel_encoder *intel_encoder, int device)
|
||||
}
|
||||
|
||||
connector = &intel_connector->base;
|
||||
- connector->polled = DRM_CONNECTOR_POLL_CONNECT | DRM_CONNECTOR_POLL_DISCONNECT;
|
||||
encoder->encoder_type = DRM_MODE_ENCODER_TMDS;
|
||||
connector->connector_type = DRM_MODE_CONNECTOR_DVID;
|
||||
|
||||
@@ -2285,7 +2284,6 @@ intel_sdvo_analog_init(struct intel_encoder *intel_encoder, int device)
|
||||
return false;
|
||||
|
||||
connector = &intel_connector->base;
|
||||
- connector->polled = DRM_CONNECTOR_POLL_CONNECT;
|
||||
encoder->encoder_type = DRM_MODE_ENCODER_DAC;
|
||||
connector->connector_type = DRM_MODE_CONNECTOR_VGA;
|
||||
sdvo_connector = intel_connector->dev_priv;
|
||||
diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c b/drivers/gpu/drm/nouveau/nouveau_connector.c
|
||||
index 149ed22..9a61f3c 100644
|
||||
--- a/drivers/gpu/drm/nouveau/nouveau_connector.c
|
||||
+++ b/drivers/gpu/drm/nouveau/nouveau_connector.c
|
||||
@@ -846,7 +846,6 @@ nouveau_connector_create(struct drm_device *dev,
|
||||
|
||||
switch (dcb->type) {
|
||||
case DCB_CONNECTOR_VGA:
|
||||
- connector->polled = DRM_CONNECTOR_POLL_CONNECT;
|
||||
if (dev_priv->card_type >= NV_50) {
|
||||
drm_connector_attach_property(connector,
|
||||
dev->mode_config.scaling_mode_property,
|
||||
@@ -858,17 +857,6 @@ nouveau_connector_create(struct drm_device *dev,
|
||||
case DCB_CONNECTOR_TV_3:
|
||||
nv_connector->scaling_mode = DRM_MODE_SCALE_NONE;
|
||||
break;
|
||||
- case DCB_CONNECTOR_DP:
|
||||
- case DCB_CONNECTOR_eDP:
|
||||
- case DCB_CONNECTOR_HDMI_0:
|
||||
- case DCB_CONNECTOR_HDMI_1:
|
||||
- case DCB_CONNECTOR_DVI_I:
|
||||
- case DCB_CONNECTOR_DVI_D:
|
||||
- if (dev_priv->card_type >= NV_50)
|
||||
- connector->polled = DRM_CONNECTOR_POLL_HPD;
|
||||
- else
|
||||
- connector->polled = DRM_CONNECTOR_POLL_CONNECT;
|
||||
- /* fall-through */
|
||||
default:
|
||||
nv_connector->scaling_mode = DRM_MODE_SCALE_FULLSCREEN;
|
||||
|
||||
diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c
|
||||
index 74e6b4e..9d7928f 100644
|
||||
--- a/drivers/gpu/drm/nouveau/nouveau_display.c
|
||||
+++ b/drivers/gpu/drm/nouveau/nouveau_display.c
|
||||
@@ -101,6 +101,5 @@ nouveau_user_framebuffer_create(struct drm_device *dev,
|
||||
|
||||
const struct drm_mode_config_funcs nouveau_mode_config_funcs = {
|
||||
.fb_create = nouveau_user_framebuffer_create,
|
||||
- .output_poll_changed = nouveau_fbcon_output_poll_changed,
|
||||
};
|
||||
|
||||
diff --git a/drivers/gpu/drm/nouveau/nouveau_fbcon.c b/drivers/gpu/drm/nouveau/nouveau_fbcon.c
|
||||
index c9a4a0d..0a59f96 100644
|
||||
--- a/drivers/gpu/drm/nouveau/nouveau_fbcon.c
|
||||
+++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.c
|
||||
@@ -326,11 +326,15 @@ nouveau_fbcon_find_or_create_single(struct drm_fb_helper *helper,
|
||||
return new_fb;
|
||||
}
|
||||
|
||||
-void
|
||||
-nouveau_fbcon_output_poll_changed(struct drm_device *dev)
|
||||
+void nouveau_fbcon_hotplug(struct drm_device *dev)
|
||||
{
|
||||
struct drm_nouveau_private *dev_priv = dev->dev_private;
|
||||
- drm_fb_helper_hotplug_event(&dev_priv->nfbdev->helper);
|
||||
+ drm_helper_fb_hpd_irq_event(&dev_priv->nfbdev->helper);
|
||||
+}
|
||||
+
|
||||
+static void nouveau_fbcon_output_status_changed(struct drm_fb_helper *fb_helper)
|
||||
+{
|
||||
+ drm_helper_fb_hotplug_event(fb_helper, true);
|
||||
}
|
||||
|
||||
int
|
||||
@@ -370,6 +374,7 @@ static struct drm_fb_helper_funcs nouveau_fbcon_helper_funcs = {
|
||||
.gamma_set = nouveau_fbcon_gamma_set,
|
||||
.gamma_get = nouveau_fbcon_gamma_get,
|
||||
.fb_probe = nouveau_fbcon_find_or_create_single,
|
||||
+ .fb_output_status_changed = nouveau_fbcon_output_status_changed,
|
||||
};
|
||||
|
||||
|
||||
@@ -387,7 +392,7 @@ int nouveau_fbcon_init(struct drm_device *dev)
|
||||
dev_priv->nfbdev = nfbdev;
|
||||
nfbdev->helper.funcs = &nouveau_fbcon_helper_funcs;
|
||||
|
||||
- ret = drm_fb_helper_init(dev, &nfbdev->helper, 2, 4);
|
||||
+ ret = drm_fb_helper_init(dev, &nfbdev->helper, 2, 4, true);
|
||||
if (ret) {
|
||||
kfree(nfbdev);
|
||||
return ret;
|
||||
diff --git a/drivers/gpu/drm/nouveau/nouveau_fbcon.h b/drivers/gpu/drm/nouveau/nouveau_fbcon.h
|
||||
index e7e1268..bf8e00d 100644
|
||||
--- a/drivers/gpu/drm/nouveau/nouveau_fbcon.h
|
||||
+++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.h
|
||||
@@ -58,6 +58,6 @@ void nouveau_fbcon_zfill_all(struct drm_device *dev);
|
||||
void nouveau_fbcon_save_disable_accel(struct drm_device *dev);
|
||||
void nouveau_fbcon_restore_accel(struct drm_device *dev);
|
||||
|
||||
-void nouveau_fbcon_output_poll_changed(struct drm_device *dev);
|
||||
+void nouveau_fbcon_hotplug(struct drm_device *dev);
|
||||
#endif /* __NV50_FBCON_H__ */
|
||||
|
||||
diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c
|
||||
index b02a231..4dcb976 100644
|
||||
--- a/drivers/gpu/drm/nouveau/nouveau_state.c
|
||||
+++ b/drivers/gpu/drm/nouveau/nouveau_state.c
|
||||
@@ -519,10 +519,8 @@ nouveau_card_init(struct drm_device *dev)
|
||||
|
||||
dev_priv->init_state = NOUVEAU_CARD_INIT_DONE;
|
||||
|
||||
- if (drm_core_check_feature(dev, DRIVER_MODESET)) {
|
||||
+ if (drm_core_check_feature(dev, DRIVER_MODESET))
|
||||
nouveau_fbcon_init(dev);
|
||||
- drm_kms_helper_poll_init(dev);
|
||||
- }
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -844,7 +842,6 @@ int nouveau_unload(struct drm_device *dev)
|
||||
struct drm_nouveau_private *dev_priv = dev->dev_private;
|
||||
|
||||
if (drm_core_check_feature(dev, DRIVER_MODESET)) {
|
||||
- drm_kms_helper_poll_fini(dev);
|
||||
nouveau_fbcon_fini(dev);
|
||||
if (dev_priv->card_type >= NV_50)
|
||||
nv50_display_destroy(dev);
|
||||
diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c
|
||||
index 580a5d1..e6a44af 100644
|
||||
--- a/drivers/gpu/drm/nouveau/nv50_display.c
|
||||
+++ b/drivers/gpu/drm/nouveau/nv50_display.c
|
||||
@@ -980,7 +980,7 @@ nv50_display_irq_hotplug_bh(struct work_struct *work)
|
||||
if (dev_priv->chipset >= 0x90)
|
||||
nv_wr32(dev, 0xe074, nv_rd32(dev, 0xe074));
|
||||
|
||||
- drm_helper_hpd_irq_event(dev);
|
||||
+ nouveau_fbcon_hotplug(dev);
|
||||
}
|
||||
|
||||
void
|
||||
diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c
|
||||
index 0c7ccc6..40a24c9 100644
|
||||
--- a/drivers/gpu/drm/radeon/radeon_connectors.c
|
||||
+++ b/drivers/gpu/drm/radeon/radeon_connectors.c
|
||||
@@ -1085,7 +1085,6 @@ radeon_add_atom_connector(struct drm_device *dev,
|
||||
drm_connector_attach_property(&radeon_connector->base,
|
||||
rdev->mode_info.load_detect_property,
|
||||
1);
|
||||
- connector->polled = DRM_CONNECTOR_POLL_CONNECT;
|
||||
break;
|
||||
case DRM_MODE_CONNECTOR_DVIA:
|
||||
drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type);
|
||||
@@ -1212,12 +1211,6 @@ radeon_add_atom_connector(struct drm_device *dev,
|
||||
break;
|
||||
}
|
||||
|
||||
- if (hpd->hpd == RADEON_HPD_NONE) {
|
||||
- if (i2c_bus->valid)
|
||||
- connector->polled = DRM_CONNECTOR_POLL_CONNECT;
|
||||
- } else
|
||||
- connector->polled = DRM_CONNECTOR_POLL_HPD;
|
||||
-
|
||||
connector->display_info.subpixel_order = subpixel_order;
|
||||
drm_sysfs_connector_add(connector);
|
||||
return;
|
||||
@@ -1279,7 +1272,6 @@ radeon_add_legacy_connector(struct drm_device *dev,
|
||||
drm_connector_attach_property(&radeon_connector->base,
|
||||
rdev->mode_info.load_detect_property,
|
||||
1);
|
||||
- connector->polled = DRM_CONNECTOR_POLL_CONNECT;
|
||||
break;
|
||||
case DRM_MODE_CONNECTOR_DVIA:
|
||||
drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type);
|
||||
@@ -1348,11 +1340,6 @@ radeon_add_legacy_connector(struct drm_device *dev,
|
||||
break;
|
||||
}
|
||||
|
||||
- if (hpd->hpd == RADEON_HPD_NONE) {
|
||||
- if (i2c_bus->valid)
|
||||
- connector->polled = DRM_CONNECTOR_POLL_CONNECT;
|
||||
- } else
|
||||
- connector->polled = DRM_CONNECTOR_POLL_HPD;
|
||||
connector->display_info.subpixel_order = subpixel_order;
|
||||
drm_sysfs_connector_add(connector);
|
||||
return;
|
||||
diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c
|
||||
index c73444a..ed756be 100644
|
||||
--- a/drivers/gpu/drm/radeon/radeon_display.c
|
||||
+++ b/drivers/gpu/drm/radeon/radeon_display.c
|
||||
@@ -887,15 +887,8 @@ radeon_user_framebuffer_create(struct drm_device *dev,
|
||||
return &radeon_fb->base;
|
||||
}
|
||||
|
||||
-static void radeon_output_poll_changed(struct drm_device *dev)
|
||||
-{
|
||||
- struct radeon_device *rdev = dev->dev_private;
|
||||
- radeon_fb_output_poll_changed(rdev);
|
||||
-}
|
||||
-
|
||||
static const struct drm_mode_config_funcs radeon_mode_funcs = {
|
||||
.fb_create = radeon_user_framebuffer_create,
|
||||
- .output_poll_changed = radeon_output_poll_changed
|
||||
};
|
||||
|
||||
struct drm_prop_enum_list {
|
||||
@@ -1044,8 +1037,6 @@ int radeon_modeset_init(struct radeon_device *rdev)
|
||||
radeon_pm_init(rdev);
|
||||
|
||||
radeon_fbdev_init(rdev);
|
||||
- drm_kms_helper_poll_init(rdev->ddev);
|
||||
-
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1058,7 +1049,6 @@ void radeon_modeset_fini(struct radeon_device *rdev)
|
||||
radeon_pm_fini(rdev);
|
||||
|
||||
if (rdev->mode_info.mode_config_initialized) {
|
||||
- drm_kms_helper_poll_fini(rdev->ddev);
|
||||
radeon_hpd_fini(rdev);
|
||||
drm_mode_config_cleanup(rdev->ddev);
|
||||
rdev->mode_info.mode_config_initialized = false;
|
||||
diff --git a/drivers/gpu/drm/radeon/radeon_fb.c b/drivers/gpu/drm/radeon/radeon_fb.c
|
||||
index dc1634b..7dc38f6 100644
|
||||
--- a/drivers/gpu/drm/radeon/radeon_fb.c
|
||||
+++ b/drivers/gpu/drm/radeon/radeon_fb.c
|
||||
@@ -316,9 +316,16 @@ int radeon_parse_options(char *options)
|
||||
return 0;
|
||||
}
|
||||
|
||||
-void radeon_fb_output_poll_changed(struct radeon_device *rdev)
|
||||
+void radeonfb_hotplug(struct drm_device *dev, bool polled)
|
||||
{
|
||||
- drm_fb_helper_hotplug_event(&rdev->mode_info.rfbdev->helper);
|
||||
+ struct radeon_device *rdev = dev->dev_private;
|
||||
+
|
||||
+ drm_helper_fb_hpd_irq_event(&rdev->mode_info.rfbdev->helper);
|
||||
+}
|
||||
+
|
||||
+static void radeon_fb_output_status_changed(struct drm_fb_helper *fb_helper)
|
||||
+{
|
||||
+ drm_helper_fb_hotplug_event(fb_helper, true);
|
||||
}
|
||||
|
||||
static int radeon_fbdev_destroy(struct drm_device *dev, struct radeon_fbdev *rfbdev)
|
||||
@@ -357,6 +364,7 @@ static struct drm_fb_helper_funcs radeon_fb_helper_funcs = {
|
||||
.gamma_set = radeon_crtc_fb_gamma_set,
|
||||
.gamma_get = radeon_crtc_fb_gamma_get,
|
||||
.fb_probe = radeon_fb_find_or_create_single,
|
||||
+ .fb_output_status_changed = radeon_fb_output_status_changed,
|
||||
};
|
||||
|
||||
int radeon_fbdev_init(struct radeon_device *rdev)
|
||||
@@ -379,7 +387,7 @@ int radeon_fbdev_init(struct radeon_device *rdev)
|
||||
|
||||
ret = drm_fb_helper_init(rdev->ddev, &rfbdev->helper,
|
||||
rdev->num_crtc,
|
||||
- RADEONFB_CONN_LIMIT);
|
||||
+ RADEONFB_CONN_LIMIT, true);
|
||||
if (ret) {
|
||||
kfree(rfbdev);
|
||||
return ret;
|
||||
@@ -388,6 +396,7 @@ int radeon_fbdev_init(struct radeon_device *rdev)
|
||||
drm_fb_helper_single_add_all_connectors(&rfbdev->helper);
|
||||
drm_fb_helper_initial_config(&rfbdev->helper, bpp_sel);
|
||||
return 0;
|
||||
+
|
||||
}
|
||||
|
||||
void radeon_fbdev_fini(struct radeon_device *rdev)
|
||||
diff --git a/drivers/gpu/drm/radeon/radeon_irq_kms.c b/drivers/gpu/drm/radeon/radeon_irq_kms.c
|
||||
index 059bfa4..b0178de 100644
|
||||
--- a/drivers/gpu/drm/radeon/radeon_irq_kms.c
|
||||
+++ b/drivers/gpu/drm/radeon/radeon_irq_kms.c
|
||||
@@ -26,7 +26,6 @@
|
||||
* Jerome Glisse
|
||||
*/
|
||||
#include "drmP.h"
|
||||
-#include "drm_crtc_helper.h"
|
||||
#include "radeon_drm.h"
|
||||
#include "radeon_reg.h"
|
||||
#include "radeon.h"
|
||||
@@ -56,7 +55,9 @@ static void radeon_hotplug_work_func(struct work_struct *work)
|
||||
radeon_connector_hotplug(connector);
|
||||
}
|
||||
/* Just fire off a uevent and let userspace tell us what to do */
|
||||
- drm_helper_hpd_irq_event(dev);
|
||||
+ radeonfb_hotplug(dev, false);
|
||||
+
|
||||
+ drm_sysfs_hotplug_event(dev);
|
||||
}
|
||||
|
||||
void radeon_driver_irq_preinstall_kms(struct drm_device *dev)
|
||||
diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h
|
||||
index 67358ba..fdd1611 100644
|
||||
--- a/drivers/gpu/drm/radeon/radeon_mode.h
|
||||
+++ b/drivers/gpu/drm/radeon/radeon_mode.h
|
||||
@@ -588,6 +588,5 @@ void radeon_fbdev_fini(struct radeon_device *rdev);
|
||||
void radeon_fbdev_set_suspend(struct radeon_device *rdev, int state);
|
||||
int radeon_fbdev_total_size(struct radeon_device *rdev);
|
||||
bool radeon_fbdev_robj_is_fb(struct radeon_device *rdev, struct radeon_bo *robj);
|
||||
-
|
||||
-void radeon_fb_output_poll_changed(struct radeon_device *rdev);
|
||||
+void radeonfb_hotplug(struct drm_device *dev, bool polled);
|
||||
#endif
|
||||
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
|
||||
index 93a1a31..a7148d2 100644
|
||||
--- a/include/drm/drm_crtc.h
|
||||
+++ b/include/drm/drm_crtc.h
|
||||
@@ -31,7 +31,6 @@
|
||||
#include <linux/idr.h>
|
||||
|
||||
#include <linux/fb.h>
|
||||
-#include <linux/slow-work.h>
|
||||
|
||||
struct drm_device;
|
||||
struct drm_mode_set;
|
||||
@@ -461,15 +460,6 @@ enum drm_connector_force {
|
||||
DRM_FORCE_ON_DIGITAL, /* for DVI-I use digital connector */
|
||||
};
|
||||
|
||||
-/* should we poll this connector for connects and disconnects */
|
||||
-/* hot plug detectable */
|
||||
-#define DRM_CONNECTOR_POLL_HPD (1 << 0)
|
||||
-/* poll for connections */
|
||||
-#define DRM_CONNECTOR_POLL_CONNECT (1 << 1)
|
||||
-/* can cleanly poll for disconnections without flickering the screen */
|
||||
-/* DACs should rarely do this without a lot of testing */
|
||||
-#define DRM_CONNECTOR_POLL_DISCONNECT (1 << 2)
|
||||
-
|
||||
/**
|
||||
* drm_connector - central DRM connector control structure
|
||||
* @crtc: CRTC this connector is currently connected to, NULL if none
|
||||
@@ -514,8 +504,6 @@ struct drm_connector {
|
||||
u32 property_ids[DRM_CONNECTOR_MAX_PROPERTY];
|
||||
uint64_t property_values[DRM_CONNECTOR_MAX_PROPERTY];
|
||||
|
||||
- uint8_t polled; /* DRM_CONNECTOR_POLL_* */
|
||||
-
|
||||
/* requested DPMS state */
|
||||
int dpms;
|
||||
|
||||
@@ -555,7 +543,6 @@ struct drm_mode_set {
|
||||
*/
|
||||
struct drm_mode_config_funcs {
|
||||
struct drm_framebuffer *(*fb_create)(struct drm_device *dev, struct drm_file *file_priv, struct drm_mode_fb_cmd *mode_cmd);
|
||||
- void (*output_poll_changed)(struct drm_device *dev);
|
||||
};
|
||||
|
||||
struct drm_mode_group {
|
||||
@@ -593,10 +580,6 @@ struct drm_mode_config {
|
||||
struct drm_mode_config_funcs *funcs;
|
||||
resource_size_t fb_base;
|
||||
|
||||
- /* output poll support */
|
||||
- bool poll_enabled;
|
||||
- struct delayed_slow_work output_poll_slow_work;
|
||||
-
|
||||
/* pointers to standard properties */
|
||||
struct list_head property_blob_list;
|
||||
struct drm_property *edid_property;
|
||||
diff --git a/include/drm/drm_crtc_helper.h b/include/drm/drm_crtc_helper.h
|
||||
index 1121f77..b1fa0f8 100644
|
||||
--- a/include/drm/drm_crtc_helper.h
|
||||
+++ b/include/drm/drm_crtc_helper.h
|
||||
@@ -127,10 +127,4 @@ static inline void drm_connector_helper_add(struct drm_connector *connector,
|
||||
}
|
||||
|
||||
extern int drm_helper_resume_force_mode(struct drm_device *dev);
|
||||
-extern void drm_kms_helper_poll_init(struct drm_device *dev);
|
||||
-extern void drm_kms_helper_poll_fini(struct drm_device *dev);
|
||||
-extern void drm_helper_hpd_irq_event(struct drm_device *dev);
|
||||
-
|
||||
-extern void drm_kms_helper_poll_disable(struct drm_device *dev);
|
||||
-extern void drm_kms_helper_poll_enable(struct drm_device *dev);
|
||||
#endif
|
||||
diff --git a/include/drm/drm_fb_helper.h b/include/drm/drm_fb_helper.h
|
||||
index f0a6afc..9b55a94 100644
|
||||
--- a/include/drm/drm_fb_helper.h
|
||||
+++ b/include/drm/drm_fb_helper.h
|
||||
@@ -30,6 +30,8 @@
|
||||
#ifndef DRM_FB_HELPER_H
|
||||
#define DRM_FB_HELPER_H
|
||||
|
||||
+#include <linux/slow-work.h>
|
||||
+
|
||||
struct drm_fb_helper;
|
||||
|
||||
struct drm_fb_helper_crtc {
|
||||
@@ -69,6 +71,9 @@ struct drm_fb_helper_funcs {
|
||||
|
||||
int (*fb_probe)(struct drm_fb_helper *helper,
|
||||
struct drm_fb_helper_surface_size *sizes);
|
||||
+
|
||||
+ void (*fb_output_status_changed)(struct drm_fb_helper *helper);
|
||||
+
|
||||
};
|
||||
|
||||
struct drm_fb_helper_connector {
|
||||
@@ -90,6 +95,8 @@ struct drm_fb_helper {
|
||||
u32 pseudo_palette[17];
|
||||
struct list_head kernel_fb_list;
|
||||
|
||||
+ struct delayed_slow_work output_status_change_slow_work;
|
||||
+ bool poll_enabled;
|
||||
/* we got a hotplug but fbdev wasn't running the console
|
||||
delay until next set_par */
|
||||
bool delayed_hotplug;
|
||||
@@ -100,7 +107,7 @@ int drm_fb_helper_single_fb_probe(struct drm_fb_helper *helper,
|
||||
|
||||
int drm_fb_helper_init(struct drm_device *dev,
|
||||
struct drm_fb_helper *helper, int crtc_count,
|
||||
- int max_conn);
|
||||
+ int max_conn, bool polled);
|
||||
void drm_fb_helper_fini(struct drm_fb_helper *helper);
|
||||
int drm_fb_helper_blank(int blank, struct fb_info *info);
|
||||
int drm_fb_helper_pan_display(struct fb_var_screeninfo *var,
|
||||
@@ -123,8 +130,10 @@ void drm_fb_helper_fill_fix(struct fb_info *info, uint32_t pitch,
|
||||
|
||||
int drm_fb_helper_setcmap(struct fb_cmap *cmap, struct fb_info *info);
|
||||
|
||||
-bool drm_fb_helper_hotplug_event(struct drm_fb_helper *fb_helper);
|
||||
+bool drm_helper_fb_hotplug_event(struct drm_fb_helper *fb_helper,
|
||||
+ bool polled);
|
||||
bool drm_fb_helper_initial_config(struct drm_fb_helper *fb_helper, int bpp_sel);
|
||||
int drm_fb_helper_single_add_all_connectors(struct drm_fb_helper *fb_helper);
|
||||
|
||||
+void drm_helper_fb_hpd_irq_event(struct drm_fb_helper *fb_helper);
|
||||
#endif
|
||||
--
|
||||
1.7.0.1
|
||||
|
|
@ -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,171 @@
|
|||
From 08ae078a33245bc01dcf895bd886f30103cc6178 Mon Sep 17 00:00:00 2001
|
||||
From: Thomas Hellstrom <thellstrom@vmware.com>
|
||||
Date: Thu, 30 Sep 2010 12:36:45 +0200
|
||||
Subject: drm/ttm: Fix two race conditions + fix busy codepaths
|
||||
|
||||
This fixes a race pointed out by Dave Airlie where we don't take a buffer
|
||||
object about to be destroyed off the LRU lists properly. It also fixes a rare
|
||||
case where a buffer object could be destroyed in the middle of an
|
||||
accelerated eviction.
|
||||
|
||||
The patch also adds a utility function that can be used to prematurely
|
||||
release GPU memory space usage of an object waiting to be destroyed.
|
||||
For example during eviction or swapout.
|
||||
|
||||
The above mentioned commit didn't queue the buffer on the delayed destroy
|
||||
list under some rare circumstances. It also didn't completely honor the
|
||||
remove_all parameter.
|
||||
|
||||
Fixes:
|
||||
https://bugzilla.redhat.com/show_bug.cgi?id=615505
|
||||
http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=591061
|
||||
|
||||
Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com>
|
||||
Signed-off-by: Dave Airlie <airlied@redhat.com>
|
||||
---
|
||||
drivers/gpu/drm/ttm/ttm_bo.c | 84 +++++++++++++++++++++++++++++++++++------
|
||||
include/drm/ttm/ttm_bo_api.h | 4 +-
|
||||
2 files changed, 74 insertions(+), 14 deletions(-)
|
||||
|
||||
diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c
|
||||
index 555ebb1..77f22ba 100644
|
||||
--- a/drivers/gpu/drm/ttm/ttm_bo.c
|
||||
+++ b/drivers/gpu/drm/ttm/ttm_bo.c
|
||||
@@ -442,6 +442,43 @@ out_err:
|
||||
}
|
||||
|
||||
/**
|
||||
+ * Call bo::reserved and with the lru lock held.
|
||||
+ * Will release GPU memory type usage on destruction.
|
||||
+ * This is the place to put in driver specific hooks.
|
||||
+ * Will release the bo::reserved lock and the
|
||||
+ * lru lock on exit.
|
||||
+ */
|
||||
+
|
||||
+static void ttm_bo_cleanup_memtype_use(struct ttm_buffer_object *bo)
|
||||
+{
|
||||
+ struct ttm_bo_global *glob = bo->glob;
|
||||
+
|
||||
+ if (bo->ttm) {
|
||||
+
|
||||
+ /**
|
||||
+ * Release the lru_lock, since we don't want to have
|
||||
+ * an atomic requirement on ttm_tt[unbind|destroy].
|
||||
+ */
|
||||
+
|
||||
+ spin_unlock(&glob->lru_lock);
|
||||
+ ttm_tt_unbind(bo->ttm);
|
||||
+ ttm_tt_destroy(bo->ttm);
|
||||
+ bo->ttm = NULL;
|
||||
+ spin_lock(&glob->lru_lock);
|
||||
+ }
|
||||
+
|
||||
+ if (bo->mem.mm_node) {
|
||||
+ drm_mm_put_block(bo->mem.mm_node);
|
||||
+ bo->mem.mm_node = NULL;
|
||||
+ }
|
||||
+
|
||||
+ atomic_set(&bo->reserved, 0);
|
||||
+ wake_up_all(&bo->event_queue);
|
||||
+ spin_unlock(&glob->lru_lock);
|
||||
+}
|
||||
+
|
||||
+
|
||||
+/**
|
||||
* If bo idle, remove from delayed- and lru lists, and unref.
|
||||
* If not idle, and already on delayed list, do nothing.
|
||||
* If not idle, and not on delayed list, put on delayed list,
|
||||
@@ -456,6 +493,7 @@ static int ttm_bo_cleanup_refs(struct ttm_buffer_object *bo, bool remove_all)
|
||||
int ret;
|
||||
|
||||
spin_lock(&bo->lock);
|
||||
+retry:
|
||||
(void) ttm_bo_wait(bo, false, false, !remove_all);
|
||||
|
||||
if (!bo->sync_obj) {
|
||||
@@ -464,32 +502,52 @@ static int ttm_bo_cleanup_refs(struct ttm_buffer_object *bo, bool remove_all)
|
||||
spin_unlock(&bo->lock);
|
||||
|
||||
spin_lock(&glob->lru_lock);
|
||||
- put_count = ttm_bo_del_from_lru(bo);
|
||||
+ ret = ttm_bo_reserve_locked(bo, false, !remove_all, false, 0);
|
||||
+
|
||||
+ /**
|
||||
+ * Someone else has the object reserved. Bail and retry.
|
||||
+ */
|
||||
|
||||
- ret = ttm_bo_reserve_locked(bo, false, false, false, 0);
|
||||
- BUG_ON(ret);
|
||||
- if (bo->ttm)
|
||||
- ttm_tt_unbind(bo->ttm);
|
||||
+ if (unlikely(ret == -EBUSY)) {
|
||||
+ spin_unlock(&glob->lru_lock);
|
||||
+ spin_lock(&bo->lock);
|
||||
+ goto requeue;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * We can re-check for sync object without taking
|
||||
+ * the bo::lock since setting the sync object requires
|
||||
+ * also bo::reserved. A busy object at this point may
|
||||
+ * be caused by another thread starting an accelerated
|
||||
+ * eviction.
|
||||
+ */
|
||||
+
|
||||
+ if (unlikely(bo->sync_obj)) {
|
||||
+ atomic_set(&bo->reserved, 0);
|
||||
+ wake_up_all(&bo->event_queue);
|
||||
+ spin_unlock(&glob->lru_lock);
|
||||
+ spin_lock(&bo->lock);
|
||||
+ if (remove_all)
|
||||
+ goto retry;
|
||||
+ else
|
||||
+ goto requeue;
|
||||
+ }
|
||||
+
|
||||
+ put_count = ttm_bo_del_from_lru(bo);
|
||||
|
||||
if (!list_empty(&bo->ddestroy)) {
|
||||
list_del_init(&bo->ddestroy);
|
||||
++put_count;
|
||||
}
|
||||
- if (bo->mem.mm_node) {
|
||||
- bo->mem.mm_node->private = NULL;
|
||||
- drm_mm_put_block(bo->mem.mm_node);
|
||||
- bo->mem.mm_node = NULL;
|
||||
- }
|
||||
- spin_unlock(&glob->lru_lock);
|
||||
|
||||
- atomic_set(&bo->reserved, 0);
|
||||
+ ttm_bo_cleanup_memtype_use(bo);
|
||||
|
||||
while (put_count--)
|
||||
kref_put(&bo->list_kref, ttm_bo_ref_bug);
|
||||
|
||||
return 0;
|
||||
}
|
||||
-
|
||||
+requeue:
|
||||
spin_lock(&glob->lru_lock);
|
||||
if (list_empty(&bo->ddestroy)) {
|
||||
void *sync_obj = bo->sync_obj;
|
||||
diff --git a/include/drm/ttm/ttm_bo_api.h b/include/drm/ttm/ttm_bo_api.h
|
||||
index 267a86c..2040e6c 100644
|
||||
--- a/include/drm/ttm/ttm_bo_api.h
|
||||
+++ b/include/drm/ttm/ttm_bo_api.h
|
||||
@@ -246,9 +246,11 @@ struct ttm_buffer_object {
|
||||
|
||||
atomic_t reserved;
|
||||
|
||||
-
|
||||
/**
|
||||
* Members protected by the bo::lock
|
||||
+ * In addition, setting sync_obj to anything else
|
||||
+ * than NULL requires bo::reserved to be held. This allows for
|
||||
+ * checking NULL while reserved but not holding bo::lock.
|
||||
*/
|
||||
|
||||
void *sync_obj_arg;
|
||||
--
|
||||
1.7.3.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,55 @@
|
|||
From: Bruce Allan <bruce.w.allan@intel.com>
|
||||
Date: Wed, 22 Sep 2010 17:15:54 +0000 (+0000)
|
||||
Subject: e1000e: 82566DC fails to get link
|
||||
X-Git-Tag: v2.6.36-rc6~6^2~23
|
||||
X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=5f3eed6fe0e36e4b56c8dd9160241a868ee0de2a
|
||||
|
||||
e1000e: 82566DC fails to get link
|
||||
|
||||
Two recent patches to cleanup the reset[1] and initial PHY configuration[2]
|
||||
code paths for ICH/PCH devices inadvertently left out a 10msec delay and
|
||||
device ID check respectively which are necessary for the 82566DC (device id
|
||||
0x104b) to be configured properly, otherwise it will not get link.
|
||||
|
||||
[1] commit e98cac447cc1cc418dff1d610a5c79c4f2bdec7f
|
||||
[2] commit 3f0c16e84438d657d29446f85fe375794a93f159
|
||||
|
||||
CC: stable@kernel.org
|
||||
Signed-off-by: Bruce Allan <bruce.w.allan@intel.com>
|
||||
Tested-by: Jeff Pieper <jeffrey.e.pieper@intel.com>
|
||||
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
|
||||
diff --git a/drivers/net/e1000e/ich8lan.c b/drivers/net/e1000e/ich8lan.c
|
||||
index fc8c3ce..6f9cb0d 100644
|
||||
--- a/drivers/net/e1000e/ich8lan.c
|
||||
+++ b/drivers/net/e1000e/ich8lan.c
|
||||
@@ -932,7 +932,6 @@ out:
|
||||
**/
|
||||
static s32 e1000_sw_lcd_config_ich8lan(struct e1000_hw *hw)
|
||||
{
|
||||
- struct e1000_adapter *adapter = hw->adapter;
|
||||
struct e1000_phy_info *phy = &hw->phy;
|
||||
u32 i, data, cnf_size, cnf_base_addr, sw_cfg_mask;
|
||||
s32 ret_val = 0;
|
||||
@@ -950,7 +949,8 @@ static s32 e1000_sw_lcd_config_ich8lan(struct e1000_hw *hw)
|
||||
if (phy->type != e1000_phy_igp_3)
|
||||
return ret_val;
|
||||
|
||||
- if (adapter->pdev->device == E1000_DEV_ID_ICH8_IGP_AMT) {
|
||||
+ if ((hw->adapter->pdev->device == E1000_DEV_ID_ICH8_IGP_AMT) ||
|
||||
+ (hw->adapter->pdev->device == E1000_DEV_ID_ICH8_IGP_C)) {
|
||||
sw_cfg_mask = E1000_FEXTNVM_SW_CONFIG;
|
||||
break;
|
||||
}
|
||||
@@ -1626,6 +1626,9 @@ static s32 e1000_post_phy_reset_ich8lan(struct e1000_hw *hw)
|
||||
if (e1000_check_reset_block(hw))
|
||||
goto out;
|
||||
|
||||
+ /* Allow time for h/w to get to quiescent state after reset */
|
||||
+ msleep(10);
|
||||
+
|
||||
/* Perform any necessary post-reset workarounds */
|
||||
switch (hw->mac.type) {
|
||||
case e1000_pchlan:
|
|
@ -0,0 +1,68 @@
|
|||
From: Bruce Allan <bruce.w.allan@intel.com>
|
||||
Date: Wed, 16 Jun 2010 13:26:17 +0000 (+0000)
|
||||
Subject: e1000e: cleanup e1000_sw_lcd_config_ich8lan()
|
||||
X-Git-Tag: v2.6.36-rc1~571^2~529
|
||||
X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=3f0c16e84438d657d29446f85fe375794a93f159
|
||||
|
||||
e1000e: cleanup e1000_sw_lcd_config_ich8lan()
|
||||
|
||||
Do not acquire and release the PHY unnecessarily for parts that return
|
||||
from this workaround without actually accessing the PHY registers.
|
||||
|
||||
Signed-off-by: Bruce Allan <bruce.w.allan@intel.com>
|
||||
Tested-by: Jeff Pieper <jeffrey.e.pieper@intel.com>
|
||||
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
|
||||
diff --git a/drivers/net/e1000e/ich8lan.c b/drivers/net/e1000e/ich8lan.c
|
||||
index b2507d9..5d8fad3 100644
|
||||
--- a/drivers/net/e1000e/ich8lan.c
|
||||
+++ b/drivers/net/e1000e/ich8lan.c
|
||||
@@ -820,14 +820,6 @@ static s32 e1000_sw_lcd_config_ich8lan(struct e1000_hw *hw)
|
||||
s32 ret_val = 0;
|
||||
u16 word_addr, reg_data, reg_addr, phy_page = 0;
|
||||
|
||||
- if (!(hw->mac.type == e1000_ich8lan && phy->type == e1000_phy_igp_3) &&
|
||||
- !(hw->mac.type == e1000_pchlan))
|
||||
- return ret_val;
|
||||
-
|
||||
- ret_val = hw->phy.ops.acquire(hw);
|
||||
- if (ret_val)
|
||||
- return ret_val;
|
||||
-
|
||||
/*
|
||||
* Initialize the PHY from the NVM on ICH platforms. This
|
||||
* is needed due to an issue where the NVM configuration is
|
||||
@@ -835,12 +827,26 @@ static s32 e1000_sw_lcd_config_ich8lan(struct e1000_hw *hw)
|
||||
* Therefore, after each PHY reset, we will load the
|
||||
* configuration data out of the NVM manually.
|
||||
*/
|
||||
- if ((adapter->pdev->device == E1000_DEV_ID_ICH8_IGP_M_AMT) ||
|
||||
- (adapter->pdev->device == E1000_DEV_ID_ICH8_IGP_M) ||
|
||||
- (hw->mac.type == e1000_pchlan))
|
||||
+ switch (hw->mac.type) {
|
||||
+ case e1000_ich8lan:
|
||||
+ if (phy->type != e1000_phy_igp_3)
|
||||
+ return ret_val;
|
||||
+
|
||||
+ if (adapter->pdev->device == E1000_DEV_ID_ICH8_IGP_AMT) {
|
||||
+ sw_cfg_mask = E1000_FEXTNVM_SW_CONFIG;
|
||||
+ break;
|
||||
+ }
|
||||
+ /* Fall-thru */
|
||||
+ case e1000_pchlan:
|
||||
sw_cfg_mask = E1000_FEXTNVM_SW_CONFIG_ICH8M;
|
||||
- else
|
||||
- sw_cfg_mask = E1000_FEXTNVM_SW_CONFIG;
|
||||
+ break;
|
||||
+ default:
|
||||
+ return ret_val;
|
||||
+ }
|
||||
+
|
||||
+ ret_val = hw->phy.ops.acquire(hw);
|
||||
+ if (ret_val)
|
||||
+ return ret_val;
|
||||
|
||||
data = er32(FEXTNVM);
|
||||
if (!(data & sw_cfg_mask))
|
|
@ -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,63 @@
|
|||
From be31c919e6ff27f1a08bc3e0725c51935313b002 Mon Sep 17 00:00:00 2001
|
||||
From: Jan Kara <jack@suse.cz>
|
||||
Date: Tue, 27 Jul 2010 11:56:07 -0400
|
||||
Subject: ext4: Always journal quota file modifications
|
||||
|
||||
When journaled quota options are not specified, we do writes
|
||||
to quota files just in data=ordered mode. This actually causes
|
||||
warnings from JBD2 about dirty journaled buffer because ext4_getblk
|
||||
unconditionally treats a block allocated by it as metadata. Since
|
||||
quota actually is filesystem metadata, the easiest way to get rid
|
||||
of the warning is to always treat quota writes as metadata...
|
||||
|
||||
Signed-off-by: Jan Kara <jack@suse.cz>
|
||||
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
|
||||
---
|
||||
fs/ext4/super.c | 19 +++++--------------
|
||||
1 files changed, 5 insertions(+), 14 deletions(-)
|
||||
|
||||
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
|
||||
index a45ced9..f12daa7 100644
|
||||
--- a/fs/ext4/super.c
|
||||
+++ b/fs/ext4/super.c
|
||||
@@ -4030,7 +4030,6 @@ static ssize_t ext4_quota_write(struct super_block *sb, int type,
|
||||
ext4_lblk_t blk = off >> EXT4_BLOCK_SIZE_BITS(sb);
|
||||
int err = 0;
|
||||
int offset = off & (sb->s_blocksize - 1);
|
||||
- int journal_quota = EXT4_SB(sb)->s_qf_names[type] != NULL;
|
||||
struct buffer_head *bh;
|
||||
handle_t *handle = journal_current_handle();
|
||||
|
||||
@@ -4055,24 +4054,16 @@ static ssize_t ext4_quota_write(struct super_block *sb, int type,
|
||||
bh = ext4_bread(handle, inode, blk, 1, &err);
|
||||
if (!bh)
|
||||
goto out;
|
||||
- if (journal_quota) {
|
||||
- err = ext4_journal_get_write_access(handle, bh);
|
||||
- if (err) {
|
||||
- brelse(bh);
|
||||
- goto out;
|
||||
- }
|
||||
+ err = ext4_journal_get_write_access(handle, bh);
|
||||
+ if (err) {
|
||||
+ brelse(bh);
|
||||
+ goto out;
|
||||
}
|
||||
lock_buffer(bh);
|
||||
memcpy(bh->b_data+offset, data, len);
|
||||
flush_dcache_page(bh->b_page);
|
||||
unlock_buffer(bh);
|
||||
- if (journal_quota)
|
||||
- err = ext4_handle_dirty_metadata(handle, NULL, bh);
|
||||
- else {
|
||||
- /* Always do at least ordered writes for quotas */
|
||||
- err = ext4_jbd2_file_inode(handle, inode);
|
||||
- mark_buffer_dirty(bh);
|
||||
- }
|
||||
+ err = ext4_handle_dirty_metadata(handle, NULL, bh);
|
||||
brelse(bh);
|
||||
out:
|
||||
if (err) {
|
||||
--
|
||||
1.7.3.3
|
||||
|
|
@ -0,0 +1,84 @@
|
|||
commit 22d3243de86bc92d874abb7c5b185d5c47aba323
|
||||
Author: Jim Bos <jim876@xs4all.nl>
|
||||
Date: Mon Nov 15 21:22:37 2010 +0100
|
||||
|
||||
Fix gcc 4.5.1 miscompiling drivers/char/i8k.c (again)
|
||||
|
||||
The fix in commit 6b4e81db2552 ("i8k: Tell gcc that *regs gets
|
||||
clobbered") to work around the gcc miscompiling i8k.c to add "+m
|
||||
(*regs)" caused register pressure problems and a build failure.
|
||||
|
||||
Changing the 'asm' statement to 'asm volatile' instead should prevent
|
||||
that and works around the gcc bug as well, so we can remove the "+m".
|
||||
|
||||
[ Background on the gcc bug: a memory clobber fails to mark the function
|
||||
the asm resides in as non-pure (aka "__attribute__((const))"), so if
|
||||
the function does nothing else that triggers the non-pure logic, gcc
|
||||
will think that that function has no side effects at all. As a result,
|
||||
callers will be mis-compiled.
|
||||
|
||||
Adding the "+m" made gcc see that it's not a pure function, and so
|
||||
does "asm volatile". The problem was never really the need to mark
|
||||
"*regs" as changed, since the memory clobber did that part - the
|
||||
problem was just a bug in the gcc "pure" function analysis - Linus ]
|
||||
|
||||
Signed-off-by: Jim Bos <jim876@xs4all.nl>
|
||||
Acked-by: Jakub Jelinek <jakub@redhat.com>
|
||||
Cc: Andi Kleen <andi@firstfloor.org>
|
||||
Cc: Andreas Schwab <schwab@linux-m68k.org>
|
||||
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
|
||||
|
||||
commit 6b4e81db2552bad04100e7d5ddeed7e848f53b48
|
||||
Author: Jim Bos <jim876@xs4all.nl>
|
||||
Date: Sat Nov 13 12:13:53 2010 +0100
|
||||
|
||||
i8k: Tell gcc that *regs gets clobbered
|
||||
|
||||
More recent GCC caused the i8k driver to stop working, on Slackware
|
||||
compiler was upgraded from gcc-4.4.4 to gcc-4.5.1 after which it didn't
|
||||
work anymore, meaning the driver didn't load or gave total nonsensical
|
||||
output.
|
||||
|
||||
As it turned out the asm(..) statement forgot to mention it modifies the
|
||||
*regs variable.
|
||||
|
||||
Credits to Andi Kleen and Andreas Schwab for providing the fix.
|
||||
|
||||
Signed-off-by: Jim Bos <jim876@xs4all.nl>
|
||||
Cc: Andi Kleen <andi@firstfloor.org>
|
||||
Cc: Andreas Schwab <schwab@linux-m68k.org>
|
||||
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
|
||||
|
||||
---
|
||||
diff --git a/drivers/char/i8k.c b/drivers/char/i8k.c
|
||||
index 3bc0eef..d72433f 100644
|
||||
--- a/drivers/char/i8k.c
|
||||
+++ b/drivers/char/i8k.c
|
||||
@@ -120,7 +120,7 @@ static int i8k_smm(struct smm_regs *regs)
|
||||
int eax = regs->eax;
|
||||
|
||||
#if defined(CONFIG_X86_64)
|
||||
- asm("pushq %%rax\n\t"
|
||||
+ asm volatile("pushq %%rax\n\t"
|
||||
"movl 0(%%rax),%%edx\n\t"
|
||||
"pushq %%rdx\n\t"
|
||||
"movl 4(%%rax),%%ebx\n\t"
|
||||
@@ -146,7 +146,7 @@ static int i8k_smm(struct smm_regs *regs)
|
||||
: "a"(regs)
|
||||
: "%ebx", "%ecx", "%edx", "%esi", "%edi", "memory");
|
||||
#else
|
||||
- asm("pushl %%eax\n\t"
|
||||
+ asm volatile("pushl %%eax\n\t"
|
||||
"movl 0(%%eax),%%edx\n\t"
|
||||
"push %%edx\n\t"
|
||||
"movl 4(%%eax),%%ebx\n\t"
|
||||
@@ -167,7 +167,8 @@ static int i8k_smm(struct smm_regs *regs)
|
||||
"movl %%edx,0(%%eax)\n\t"
|
||||
"lahf\n\t"
|
||||
"shrl $8,%%eax\n\t"
|
||||
- "andl $1,%%eax\n":"=a"(rc)
|
||||
+ "andl $1,%%eax\n"
|
||||
+ :"=a"(rc)
|
||||
: "a"(regs)
|
||||
: "%ebx", "%ecx", "%edx", "%esi", "%edi", "memory");
|
||||
#endif
|
|
@ -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,65 @@
|
|||
From linux-fsdevel-owner@vger.kernel.org Thu Nov 18 21:03:11 2010
|
||||
From: Josef Bacik <josef@redhat.com>
|
||||
To: linux-fsdevel@vger.kernel.org, eparis@redhat.com,
|
||||
linux-kernel@vger.kernel.org, sds@tycho.nsa.gov,
|
||||
selinux@tycho.nsa.gov, bfields@fieldses.org
|
||||
Subject: [PATCH] fs: call security_d_instantiate in d_obtain_alias V2
|
||||
Date: Thu, 18 Nov 2010 20:52:55 -0500
|
||||
Message-Id: <1290131575-2489-1-git-send-email-josef@redhat.com>
|
||||
X-Mailing-List: linux-fsdevel@vger.kernel.org
|
||||
|
||||
While trying to track down some NFS problems with BTRFS, I kept noticing I was
|
||||
getting -EACCESS for no apparent reason. Eric Paris and printk() helped me
|
||||
figure out that it was SELinux that was giving me grief, with the following
|
||||
denial
|
||||
|
||||
type=AVC msg=audit(1290013638.413:95): avc: denied { 0x800000 } for pid=1772
|
||||
comm="nfsd" name="" dev=sda1 ino=256 scontext=system_u:system_r:kernel_t:s0
|
||||
tcontext=system_u:object_r:unlabeled_t:s0 tclass=file
|
||||
|
||||
Turns out this is because in d_obtain_alias if we can't find an alias we create
|
||||
one and do all the normal instantiation stuff, but we don't do the
|
||||
security_d_instantiate.
|
||||
|
||||
Usually we are protected from getting a hashed dentry that hasn't yet run
|
||||
security_d_instantiate() by the parent's i_mutex, but obviously this isn't an
|
||||
option there, so in order to deal with the case that a second thread comes in
|
||||
and finds our new dentry before we get to run security_d_instantiate(), we go
|
||||
ahead and call it if we find a dentry already. Eric assures me that this is ok
|
||||
as the code checks to see if the dentry has been initialized already so calling
|
||||
security_d_instantiate() against the same dentry multiple times is ok. With
|
||||
this patch I'm no longer getting errant -EACCESS values.
|
||||
|
||||
Signed-off-by: Josef Bacik <josef@redhat.com>
|
||||
---
|
||||
V1->V2:
|
||||
-added second security_d_instantiate() call
|
||||
|
||||
fs/dcache.c | 3 +++
|
||||
1 files changed, 3 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/fs/dcache.c b/fs/dcache.c
|
||||
index 23702a9..119d489 100644
|
||||
--- a/fs/dcache.c
|
||||
+++ b/fs/dcache.c
|
||||
@@ -1201,9 +1201,12 @@ struct dentry *d_obtain_alias(struct inode *inode)
|
||||
spin_unlock(&tmp->d_lock);
|
||||
|
||||
spin_unlock(&dcache_lock);
|
||||
+ security_d_instantiate(tmp, inode);
|
||||
return tmp;
|
||||
|
||||
out_iput:
|
||||
+ if (res && !IS_ERR(res))
|
||||
+ security_d_instantiate(res, inode);
|
||||
iput(inode);
|
||||
return res;
|
||||
}
|
||||
--
|
||||
1.6.6.1
|
||||
|
||||
--
|
||||
To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in
|
||||
the body of a message to majordomo@vger.kernel.org
|
||||
More majordomo info at http://vger.kernel.org/majordomo-info.html
|
||||
|
|
@ -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,76 @@
|
|||
From sgruszka@redhat.com Mon Jan 17 08:03:52 2011
|
||||
From: Stanislaw Gruszka <sgruszka@redhat.com>
|
||||
To: stable@kernel.org, kernel@lists.fedoraproject.org
|
||||
Subject: [PATCH 2.6.35.y] hostap_cs: fix sleeping function called from invalid context
|
||||
Date: Mon, 17 Jan 2011 14:03:36 +0100
|
||||
Message-Id: <1295269416-4870-1-git-send-email-sgruszka@redhat.com>
|
||||
|
||||
commit 4e5518ca53be29c1ec3c00089c97bef36bfed515 upstream.
|
||||
|
||||
pcmcia_request_irq() and pcmcia_enable_device() are intended
|
||||
to be called from process context (first function allocate memory
|
||||
with GFP_KERNEL, second take a mutex). We can not take spin lock
|
||||
and call them.
|
||||
|
||||
It's safe to move spin lock after pcmcia_enable_device() as we
|
||||
still hold off IRQ until dev->base_addr is 0 and driver will
|
||||
not proceed with interrupts when is not ready.
|
||||
|
||||
Patch resolves:
|
||||
https://bugzilla.redhat.com/show_bug.cgi?id=643758
|
||||
|
||||
Reported-and-tested-by: rbugz@biobind.com
|
||||
Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
|
||||
---
|
||||
drivers/net/wireless/hostap/hostap_cs.c | 15 ++++++---------
|
||||
1 files changed, 6 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/wireless/hostap/hostap_cs.c b/drivers/net/wireless/hostap/hostap_cs.c
|
||||
index 29b31a6..4ebf63d 100644
|
||||
--- a/drivers/net/wireless/hostap/hostap_cs.c
|
||||
+++ b/drivers/net/wireless/hostap/hostap_cs.c
|
||||
@@ -627,14 +627,13 @@ static int prism2_config(struct pcmcia_device *link)
|
||||
hw_priv->link = link;
|
||||
|
||||
/*
|
||||
- * Make sure the IRQ handler cannot proceed until at least
|
||||
- * dev->base_addr is initialized.
|
||||
+ * We enable IRQ here, but IRQ handler will not proceed
|
||||
+ * until dev->base_addr is set below. This protect us from
|
||||
+ * receive interrupts when driver is not initialized.
|
||||
*/
|
||||
- spin_lock_irqsave(&local->irq_init_lock, flags);
|
||||
-
|
||||
ret = pcmcia_request_irq(link, prism2_interrupt);
|
||||
if (ret)
|
||||
- goto failed_unlock;
|
||||
+ goto failed;
|
||||
|
||||
/*
|
||||
* This actually configures the PCMCIA socket -- setting up
|
||||
@@ -643,11 +642,11 @@ static int prism2_config(struct pcmcia_device *link)
|
||||
*/
|
||||
ret = pcmcia_request_configuration(link, &link->conf);
|
||||
if (ret)
|
||||
- goto failed_unlock;
|
||||
+ goto failed;
|
||||
|
||||
+ spin_lock_irqsave(&local->irq_init_lock, flags);
|
||||
dev->irq = link->irq;
|
||||
dev->base_addr = link->io.BasePort1;
|
||||
-
|
||||
spin_unlock_irqrestore(&local->irq_init_lock, flags);
|
||||
|
||||
/* Finally, report what we've done */
|
||||
@@ -676,8 +675,6 @@ static int prism2_config(struct pcmcia_device *link)
|
||||
|
||||
return ret;
|
||||
|
||||
- failed_unlock:
|
||||
- spin_unlock_irqrestore(&local->irq_init_lock, flags);
|
||||
failed:
|
||||
kfree(hw_priv);
|
||||
prism2_release((u_long)link);
|
||||
--
|
||||
1.7.1
|
||||
|
|
@ -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
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
From: Jarod Wilson <jarod@redhat.com>
|
||||
Date: Sat, 23 Oct 2010 14:54:06 -0400
|
||||
Subject: [PATCH] imon: add back modparam for default protocol
|
||||
|
||||
The latest imon devices support both imon and mce remotes, but we
|
||||
default to using the imon native protocol. Upstream, ir-keytable
|
||||
can be used to change protocol and upload the mce keytable, but it
|
||||
isn't functional with the input layer interfaces in 2.6.35. As a
|
||||
work-around for now, add back a modparam so people can have the
|
||||
driver load the mce keytable by default.
|
||||
|
||||
Note, this patch won't be going upstream. Upstream, we're moving
|
||||
towards all keytables being in userspace, uploaded at driver init
|
||||
time by ir-keytable (triggered by udev events).
|
||||
|
||||
Signed-off-by: Jarod Wilson <jarod@redhat.com>
|
||||
---
|
||||
drivers/media/rc/imon.c | 14 ++++++++++++++
|
||||
1 files changed, 14 insertions(+), 0 deletions(-)
|
||||
|
||||
Index: linux-2.6.35.x86_64/drivers/media/rc/imon.c
|
||||
===================================================================
|
||||
--- linux-2.6.35.x86_64.orig/drivers/media/rc/imon.c
|
||||
+++ linux-2.6.35.x86_64/drivers/media/rc/imon.c
|
||||
@@ -328,6 +328,17 @@ MODULE_PARM_DESC(pad_stabilize, "Apply s
|
||||
"presses in arrow key mode. 0=disable, 1=enable (default).");
|
||||
|
||||
/*
|
||||
+ * The latest imon devices support both imon and mce remotes, but we default
|
||||
+ * to using the imon native protocol. Rather than require people to have and
|
||||
+ * run ir-keytable to switch every module load, they can add mce=1 to their
|
||||
+ * modparams to default to mce/rc6 instead.
|
||||
+ */
|
||||
+static bool mce;
|
||||
+module_param(mce, bool, S_IRUGO);
|
||||
+MODULE_PARM_DESC(mce, "Configure for mce/rc6 protocol instead of imon native, "
|
||||
+ "if supported: 0=no, 1=yes (default: no)");
|
||||
+
|
||||
+/*
|
||||
* In certain use cases, mouse mode isn't really helpful, and could actually
|
||||
* cause confusion, so allow disabling it when the IR device is open.
|
||||
*/
|
||||
@@ -1851,6 +1862,9 @@ static struct rc_dev *imon_init_rdev(str
|
||||
|
||||
imon_set_display_type(ictx);
|
||||
|
||||
+ if (mce && ((rdev->allowed_protos & RC_TYPE_RC6) == RC_TYPE_RC6))
|
||||
+ ictx->rc_type = RC_TYPE_RC6;
|
||||
+
|
||||
if (ictx->rc_type == RC_TYPE_RC6)
|
||||
rdev->map_name = RC_MAP_IMON_MCE;
|
||||
else
|
|
@ -0,0 +1,105 @@
|
|||
From 56e0d4414e5eeacd9eaf68ce93dcb80f9c62bfb4 Mon Sep 17 00:00:00 2001
|
||||
From: Nelson Elhage <nelhage@ksplice.com>
|
||||
Date: Wed, 3 Nov 2010 16:35:41 +0000
|
||||
Subject: inet_diag: Make sure we actually run the same bytecode we audited.
|
||||
|
||||
We were using nlmsg_find_attr() to look up the bytecode by attribute when
|
||||
auditing, but then just using the first attribute when actually running
|
||||
bytecode. So, if we received a message with two attribute elements, where only
|
||||
the second had type INET_DIAG_REQ_BYTECODE, we would validate and run different
|
||||
bytecode strings.
|
||||
|
||||
Fix this by consistently using nlmsg_find_attr everywhere.
|
||||
|
||||
Signed-off-by: Nelson Elhage <nelhage@ksplice.com>
|
||||
Signed-off-by: Thomas Graf <tgraf@infradead.org>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
net/ipv4/inet_diag.c | 27 ++++++++++++++++-----------
|
||||
1 files changed, 16 insertions(+), 11 deletions(-)
|
||||
|
||||
diff --git a/net/ipv4/inet_diag.c b/net/ipv4/inet_diag.c
|
||||
index e5fa2dd..7403b9b 100644
|
||||
--- a/net/ipv4/inet_diag.c
|
||||
+++ b/net/ipv4/inet_diag.c
|
||||
@@ -490,9 +490,11 @@ static int inet_csk_diag_dump(struct sock *sk,
|
||||
{
|
||||
struct inet_diag_req *r = NLMSG_DATA(cb->nlh);
|
||||
|
||||
- if (cb->nlh->nlmsg_len > 4 + NLMSG_SPACE(sizeof(*r))) {
|
||||
+ if (nlmsg_attrlen(cb->nlh, sizeof(*r))) {
|
||||
struct inet_diag_entry entry;
|
||||
- struct rtattr *bc = (struct rtattr *)(r + 1);
|
||||
+ const struct nlattr *bc = nlmsg_find_attr(cb->nlh,
|
||||
+ sizeof(*r),
|
||||
+ INET_DIAG_REQ_BYTECODE);
|
||||
struct inet_sock *inet = inet_sk(sk);
|
||||
|
||||
entry.family = sk->sk_family;
|
||||
@@ -512,7 +514,7 @@ static int inet_csk_diag_dump(struct sock *sk,
|
||||
entry.dport = ntohs(inet->inet_dport);
|
||||
entry.userlocks = sk->sk_userlocks;
|
||||
|
||||
- if (!inet_diag_bc_run(RTA_DATA(bc), RTA_PAYLOAD(bc), &entry))
|
||||
+ if (!inet_diag_bc_run(nla_data(bc), nla_len(bc), &entry))
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -527,9 +529,11 @@ static int inet_twsk_diag_dump(struct inet_timewait_sock *tw,
|
||||
{
|
||||
struct inet_diag_req *r = NLMSG_DATA(cb->nlh);
|
||||
|
||||
- if (cb->nlh->nlmsg_len > 4 + NLMSG_SPACE(sizeof(*r))) {
|
||||
+ if (nlmsg_attrlen(cb->nlh, sizeof(*r))) {
|
||||
struct inet_diag_entry entry;
|
||||
- struct rtattr *bc = (struct rtattr *)(r + 1);
|
||||
+ const struct nlattr *bc = nlmsg_find_attr(cb->nlh,
|
||||
+ sizeof(*r),
|
||||
+ INET_DIAG_REQ_BYTECODE);
|
||||
|
||||
entry.family = tw->tw_family;
|
||||
#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
|
||||
@@ -548,7 +552,7 @@ static int inet_twsk_diag_dump(struct inet_timewait_sock *tw,
|
||||
entry.dport = ntohs(tw->tw_dport);
|
||||
entry.userlocks = 0;
|
||||
|
||||
- if (!inet_diag_bc_run(RTA_DATA(bc), RTA_PAYLOAD(bc), &entry))
|
||||
+ if (!inet_diag_bc_run(nla_data(bc), nla_len(bc), &entry))
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -618,7 +622,7 @@ static int inet_diag_dump_reqs(struct sk_buff *skb, struct sock *sk,
|
||||
struct inet_diag_req *r = NLMSG_DATA(cb->nlh);
|
||||
struct inet_connection_sock *icsk = inet_csk(sk);
|
||||
struct listen_sock *lopt;
|
||||
- struct rtattr *bc = NULL;
|
||||
+ const struct nlattr *bc = NULL;
|
||||
struct inet_sock *inet = inet_sk(sk);
|
||||
int j, s_j;
|
||||
int reqnum, s_reqnum;
|
||||
@@ -638,8 +642,9 @@ static int inet_diag_dump_reqs(struct sk_buff *skb, struct sock *sk,
|
||||
if (!lopt || !lopt->qlen)
|
||||
goto out;
|
||||
|
||||
- if (cb->nlh->nlmsg_len > 4 + NLMSG_SPACE(sizeof(*r))) {
|
||||
- bc = (struct rtattr *)(r + 1);
|
||||
+ if (nlmsg_attrlen(cb->nlh, sizeof(*r))) {
|
||||
+ bc = nlmsg_find_attr(cb->nlh, sizeof(*r),
|
||||
+ INET_DIAG_REQ_BYTECODE);
|
||||
entry.sport = inet->inet_num;
|
||||
entry.userlocks = sk->sk_userlocks;
|
||||
}
|
||||
@@ -672,8 +677,8 @@ static int inet_diag_dump_reqs(struct sk_buff *skb, struct sock *sk,
|
||||
&ireq->rmt_addr;
|
||||
entry.dport = ntohs(ireq->rmt_port);
|
||||
|
||||
- if (!inet_diag_bc_run(RTA_DATA(bc),
|
||||
- RTA_PAYLOAD(bc), &entry))
|
||||
+ if (!inet_diag_bc_run(nla_data(bc),
|
||||
+ nla_len(bc), &entry))
|
||||
continue;
|
||||
}
|
||||
|
||||
--
|
||||
1.7.3.2
|
||||
|
1014
kernel.spec
1014
kernel.spec
File diff suppressed because it is too large
Load Diff
|
@ -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,161 @@
|
|||
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_ldt(ldt_selector);
|
||||
- kvm_load_fs(fs_selector);
|
||||
- kvm_load_gs(gs_selector);
|
||||
load_host_msrs(vcpu);
|
||||
+ kvm_load_ldt(ldt_selector);
|
||||
+ 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
|
||||
|
||||
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,25 +841,19 @@ 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.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);
|
||||
}
|
||||
if (vmx->host_state.fs_reload_needed)
|
||||
loadsegment(fs, vmx->host_state.fs_sel);
|
||||
@@ -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,13 @@
|
|||
diff -up linux-2.6.32.x86_64/fs/nfs/objlayout/pnfs_osd_xdr.h.orig linux-2.6.32.x86_64/fs/nfs/objlayout/pnfs_osd_xdr.h
|
||||
diff -up linux-2.6.32.x86_64/include/net/inet_connection_sock.h.orig linux-2.6.32.x86_64/include/net/inet_connection_sock.h
|
||||
--- linux-2.6.32.x86_64/include/net/inet_connection_sock.h.orig 2009-12-02 22:51:21.000000000 -0500
|
||||
+++ linux-2.6.32.x86_64/include/net/inet_connection_sock.h 2010-04-21 14:26:24.475659551 -0400
|
||||
@@ -23,7 +23,7 @@
|
||||
#include <net/inet_sock.h>
|
||||
#include <net/request_sock.h>
|
||||
|
||||
-#define INET_CSK_DEBUG 1
|
||||
+//#define INET_CSK_DEBUG 1
|
||||
|
||||
/* Cancel timers, when they are not required. */
|
||||
#undef INET_CSK_CLEAR_TIMERS
|
|
@ -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
|
||||
|
||||
|
|
@ -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);
|
||||
|
|
|
@ -1,165 +0,0 @@
|
|||
commit 611225f5e7f9d11c4b119fac224f1bd6903b0150
|
||||
Author: Jarod Wilson <jarod@redhat.com>
|
||||
Date: Sun Mar 7 17:55:43 2010 -0300
|
||||
|
||||
V4L/DVB: dvb: add support for kworld 340u and ub435-q to em28xx-dvb
|
||||
|
||||
This adds support for the KWorld PlusTV 340U and KWorld UB345-Q ATSC
|
||||
sticks, which are really the same device. The sticks have an eMPIA
|
||||
em2870 usb bridge chipset, an LG Electronics LGDT3304 ATSC/QAM
|
||||
demodulator and an NXP TDA18271HD tuner -- early versions of the 340U
|
||||
have a a TDA18271HD/C1, later models and the UB435-Q have a C2.
|
||||
|
||||
The stick has been tested succesfully with both VSB_8 and QAM_256 signals.
|
||||
Its using lgdt3304 support added to the lgdt3305 driver by a prior patch,
|
||||
rather than the current lgdt3304 driver, as its severely lacking in
|
||||
functionality by comparison (see said patch for details).
|
||||
|
||||
Signed-off-by: Jarod Wilson <jarod@redhat.com>
|
||||
Signed-off-by: Michael Krufky <mkrufky@kernellabs.com>
|
||||
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
|
||||
|
||||
diff --git a/Documentation/video4linux/CARDLIST.em28xx b/Documentation/video4linux/CARDLIST.em28xx
|
||||
index 3a623aa..5c56875 100644
|
||||
--- a/Documentation/video4linux/CARDLIST.em28xx
|
||||
+++ b/Documentation/video4linux/CARDLIST.em28xx
|
||||
@@ -72,3 +72,4 @@
|
||||
73 -> Reddo DVB-C USB TV Box (em2870)
|
||||
74 -> Actionmaster/LinXcel/Digitus VC211A (em2800)
|
||||
75 -> Dikom DK300 (em2882)
|
||||
+ 76 -> KWorld PlusTV 340U or UB435-Q (ATSC) (em2870) [1b80:a340]
|
||||
diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c
|
||||
index 3a4fd85..ffbe544 100644
|
||||
--- a/drivers/media/video/em28xx/em28xx-cards.c
|
||||
+++ b/drivers/media/video/em28xx/em28xx-cards.c
|
||||
@@ -158,6 +158,22 @@ static struct em28xx_reg_seq evga_indtube_digital[] = {
|
||||
{ -1, -1, -1, -1},
|
||||
};
|
||||
|
||||
+/*
|
||||
+ * KWorld PlusTV 340U and UB435-Q (ATSC) GPIOs map:
|
||||
+ * EM_GPIO_0 - currently unknown
|
||||
+ * EM_GPIO_1 - LED disable/enable (1 = off, 0 = on)
|
||||
+ * EM_GPIO_2 - currently unknown
|
||||
+ * EM_GPIO_3 - currently unknown
|
||||
+ * EM_GPIO_4 - TDA18271HD/C1 tuner (1 = active, 0 = in reset)
|
||||
+ * EM_GPIO_5 - LGDT3304 ATSC/QAM demod (1 = active, 0 = in reset)
|
||||
+ * EM_GPIO_6 - currently unknown
|
||||
+ * EM_GPIO_7 - currently unknown
|
||||
+ */
|
||||
+static struct em28xx_reg_seq kworld_a340_digital[] = {
|
||||
+ {EM28XX_R08_GPIO, 0x6d, ~EM_GPIO_4, 10},
|
||||
+ { -1, -1, -1, -1},
|
||||
+};
|
||||
+
|
||||
/* Pinnacle Hybrid Pro eb1a:2881 */
|
||||
static struct em28xx_reg_seq pinnacle_hybrid_pro_analog[] = {
|
||||
{EM28XX_R08_GPIO, 0xfd, ~EM_GPIO_4, 10},
|
||||
@@ -1667,6 +1683,16 @@ struct em28xx_board em28xx_boards[] = {
|
||||
.tuner_gpio = reddo_dvb_c_usb_box,
|
||||
.has_dvb = 1,
|
||||
},
|
||||
+ /* 1b80:a340 - Empia EM2870, NXP TDA18271HD and LG DT3304, sold
|
||||
+ * initially as the KWorld PlusTV 340U, then as the UB435-Q.
|
||||
+ * Early variants have a TDA18271HD/C1, later ones a TDA18271HD/C2 */
|
||||
+ [EM2870_BOARD_KWORLD_A340] = {
|
||||
+ .name = "KWorld PlusTV 340U or UB435-Q (ATSC)",
|
||||
+ .tuner_type = TUNER_ABSENT, /* Digital-only TDA18271HD */
|
||||
+ .has_dvb = 1,
|
||||
+ .dvb_gpio = kworld_a340_digital,
|
||||
+ .tuner_gpio = default_tuner_gpio,
|
||||
+ },
|
||||
};
|
||||
const unsigned int em28xx_bcount = ARRAY_SIZE(em28xx_boards);
|
||||
|
||||
@@ -1788,6 +1814,8 @@ struct usb_device_id em28xx_id_table[] = {
|
||||
.driver_info = EM2820_BOARD_IODATA_GVMVP_SZ },
|
||||
{ USB_DEVICE(0xeb1a, 0x50a6),
|
||||
.driver_info = EM2860_BOARD_GADMEI_UTV330 },
|
||||
+ { USB_DEVICE(0x1b80, 0xa340),
|
||||
+ .driver_info = EM2870_BOARD_KWORLD_A340 },
|
||||
{ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(usb, em28xx_id_table);
|
||||
diff --git a/drivers/media/video/em28xx/em28xx-dvb.c b/drivers/media/video/em28xx/em28xx-dvb.c
|
||||
index cf1d8c3..3ac8d30 100644
|
||||
--- a/drivers/media/video/em28xx/em28xx-dvb.c
|
||||
+++ b/drivers/media/video/em28xx/em28xx-dvb.c
|
||||
@@ -30,11 +30,13 @@
|
||||
#include "tuner-simple.h"
|
||||
|
||||
#include "lgdt330x.h"
|
||||
+#include "lgdt3305.h"
|
||||
#include "zl10353.h"
|
||||
#include "s5h1409.h"
|
||||
#include "mt352.h"
|
||||
#include "mt352_priv.h" /* FIXME */
|
||||
#include "tda1002x.h"
|
||||
+#include "tda18271.h"
|
||||
|
||||
MODULE_DESCRIPTION("driver for em28xx based DVB cards");
|
||||
MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@infradead.org>");
|
||||
@@ -231,6 +233,18 @@ static struct lgdt330x_config em2880_lgdt3303_dev = {
|
||||
.demod_chip = LGDT3303,
|
||||
};
|
||||
|
||||
+static struct lgdt3305_config em2870_lgdt3304_dev = {
|
||||
+ .i2c_addr = 0x0e,
|
||||
+ .demod_chip = LGDT3304,
|
||||
+ .spectral_inversion = 1,
|
||||
+ .deny_i2c_rptr = 1,
|
||||
+ .mpeg_mode = LGDT3305_MPEG_PARALLEL,
|
||||
+ .tpclk_edge = LGDT3305_TPCLK_FALLING_EDGE,
|
||||
+ .tpvalid_polarity = LGDT3305_TP_VALID_HIGH,
|
||||
+ .vsb_if_khz = 3250,
|
||||
+ .qam_if_khz = 4000,
|
||||
+};
|
||||
+
|
||||
static struct zl10353_config em28xx_zl10353_with_xc3028 = {
|
||||
.demod_address = (0x1e >> 1),
|
||||
.no_tuner = 1,
|
||||
@@ -247,6 +261,17 @@ static struct s5h1409_config em28xx_s5h1409_with_xc3028 = {
|
||||
.mpeg_timing = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK
|
||||
};
|
||||
|
||||
+static struct tda18271_std_map kworld_a340_std_map = {
|
||||
+ .atsc_6 = { .if_freq = 3250, .agc_mode = 3, .std = 0,
|
||||
+ .if_lvl = 1, .rfagc_top = 0x37, },
|
||||
+ .qam_6 = { .if_freq = 4000, .agc_mode = 3, .std = 1,
|
||||
+ .if_lvl = 1, .rfagc_top = 0x37, },
|
||||
+};
|
||||
+
|
||||
+static struct tda18271_config kworld_a340_config = {
|
||||
+ .std_map = &kworld_a340_std_map,
|
||||
+};
|
||||
+
|
||||
static struct zl10353_config em28xx_zl10353_xc3028_no_i2c_gate = {
|
||||
.demod_address = (0x1e >> 1),
|
||||
.no_tuner = 1,
|
||||
@@ -572,6 +597,14 @@ static int dvb_init(struct em28xx *dev)
|
||||
}
|
||||
}
|
||||
break;
|
||||
+ case EM2870_BOARD_KWORLD_A340:
|
||||
+ dvb->frontend = dvb_attach(lgdt3305_attach,
|
||||
+ &em2870_lgdt3304_dev,
|
||||
+ &dev->i2c_adap);
|
||||
+ if (dvb->frontend != NULL)
|
||||
+ dvb_attach(tda18271_attach, dvb->frontend, 0x60,
|
||||
+ &dev->i2c_adap, &kworld_a340_config);
|
||||
+ break;
|
||||
default:
|
||||
em28xx_errdev("/2: The frontend of your DVB/ATSC card"
|
||||
" isn't supported yet\n");
|
||||
diff --git a/drivers/media/video/em28xx/em28xx.h b/drivers/media/video/em28xx/em28xx.h
|
||||
index 6216786..1c61a6b 100644
|
||||
--- a/drivers/media/video/em28xx/em28xx.h
|
||||
+++ b/drivers/media/video/em28xx/em28xx.h
|
||||
@@ -114,6 +114,7 @@
|
||||
#define EM2870_BOARD_REDDO_DVB_C_USB_BOX 73
|
||||
#define EM2800_BOARD_VC211A 74
|
||||
#define EM2882_BOARD_DIKOM_DK300 75
|
||||
+#define EM2870_BOARD_KWORLD_A340 76
|
||||
|
||||
/* Limits minimum and default number of buffers */
|
||||
#define EM28XX_MIN_BUF 4
|
|
@ -1,350 +0,0 @@
|
|||
From b71e18093e2e7f240797875c50c49552722f8825 Mon Sep 17 00:00:00 2001
|
||||
From: Jarod Wilson <jarod@redhat.com>
|
||||
Date: Mon, 15 Feb 2010 17:13:25 -0500
|
||||
Subject: [PATCH 1/2] dvb: add lgdt3304 support to lgdt3305 driver
|
||||
|
||||
There's a currently-unused lgdt3304 demod driver, which leaves a lot to
|
||||
be desired as far as functionality. The 3304 is unsurprisingly quite
|
||||
similar to the 3305, and empirical testing yeilds far better results
|
||||
and more complete functionality by merging 3304 support into the 3305
|
||||
driver. (For example, the current lgdt3304 driver lacks support for
|
||||
signal strength, snr, ucblocks, etc., which we get w/the lgdt3305).
|
||||
|
||||
For the moment, not dropping the lgdt3304 driver, and its still up to
|
||||
a given device's config setup to choose which demod driver to use, but
|
||||
I'd suggest dropping the 3304 driver entirely.
|
||||
|
||||
As a follow-up to this patch, I've got another patch that adds support
|
||||
for the KWorld PlusTV 340U (ATSC) em2870-based tuner stick, driving
|
||||
its lgdt3304 demod via this lgdt3305 driver, which is what I used to
|
||||
successfully test this patch with both VSB_8 and QAM_256 signals.
|
||||
|
||||
A few pieces are still a touch crude, but I think its a solid start,
|
||||
as well as much cleaner and more feature-complete than the existing
|
||||
lgdt3304 driver.
|
||||
|
||||
Signed-off-by: Jarod Wilson <jarod@redhat.com>
|
||||
---
|
||||
drivers/media/dvb/frontends/lgdt3305.c | 206 ++++++++++++++++++++++++++++++--
|
||||
drivers/media/dvb/frontends/lgdt3305.h | 6 +
|
||||
2 files changed, 203 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/drivers/media/dvb/frontends/lgdt3305.c b/drivers/media/dvb/frontends/lgdt3305.c
|
||||
index fde8c59..40695e6 100644
|
||||
--- a/drivers/media/dvb/frontends/lgdt3305.c
|
||||
+++ b/drivers/media/dvb/frontends/lgdt3305.c
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
- * Support for LGDT3305 - VSB/QAM
|
||||
+ * Support for LG Electronics LGDT3304 and LGDT3305 - VSB/QAM
|
||||
*
|
||||
* Copyright (C) 2008, 2009 Michael Krufky <mkrufky@linuxtv.org>
|
||||
*
|
||||
@@ -357,7 +357,10 @@ static int lgdt3305_rfagc_loop(struct lgdt3305_state *state,
|
||||
case QAM_256:
|
||||
agcdelay = 0x046b;
|
||||
rfbw = 0x8889;
|
||||
- ifbw = 0x8888;
|
||||
+ if (state->cfg->demod_chip == LGDT3305)
|
||||
+ ifbw = 0x8888;
|
||||
+ else
|
||||
+ ifbw = 0x6666;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
@@ -409,8 +412,18 @@ static int lgdt3305_agc_setup(struct lgdt3305_state *state,
|
||||
lg_dbg("lockdten = %d, acqen = %d\n", lockdten, acqen);
|
||||
|
||||
/* control agc function */
|
||||
- lgdt3305_write_reg(state, LGDT3305_AGC_CTRL_4, 0xe1 | lockdten << 1);
|
||||
- lgdt3305_set_reg_bit(state, LGDT3305_AGC_CTRL_1, 2, acqen);
|
||||
+ switch (state->cfg->demod_chip) {
|
||||
+ case LGDT3304:
|
||||
+ lgdt3305_write_reg(state, 0x0314, 0xe1 | lockdten << 1);
|
||||
+ lgdt3305_set_reg_bit(state, 0x030e, 2, acqen);
|
||||
+ break;
|
||||
+ case LGDT3305:
|
||||
+ lgdt3305_write_reg(state, LGDT3305_AGC_CTRL_4, 0xe1 | lockdten << 1);
|
||||
+ lgdt3305_set_reg_bit(state, LGDT3305_AGC_CTRL_1, 2, acqen);
|
||||
+ break;
|
||||
+ default:
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
|
||||
return lgdt3305_rfagc_loop(state, param);
|
||||
}
|
||||
@@ -543,6 +556,11 @@ static int lgdt3305_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
|
||||
enable ? 0 : 1);
|
||||
}
|
||||
|
||||
+static int lgdt3304_sleep(struct dvb_frontend *fe)
|
||||
+{
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static int lgdt3305_sleep(struct dvb_frontend *fe)
|
||||
{
|
||||
struct lgdt3305_state *state = fe->demodulator_priv;
|
||||
@@ -571,6 +589,55 @@ static int lgdt3305_sleep(struct dvb_frontend *fe)
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static int lgdt3304_init(struct dvb_frontend *fe)
|
||||
+{
|
||||
+ struct lgdt3305_state *state = fe->demodulator_priv;
|
||||
+ int ret;
|
||||
+
|
||||
+ static struct lgdt3305_reg lgdt3304_init_data[] = {
|
||||
+ { .reg = LGDT3305_GEN_CTRL_1, .val = 0x03, },
|
||||
+ { .reg = 0x000d, .val = 0x02, },
|
||||
+ { .reg = 0x000e, .val = 0x02, },
|
||||
+ { .reg = LGDT3305_DGTL_AGC_REF_1, .val = 0x32, },
|
||||
+ { .reg = LGDT3305_DGTL_AGC_REF_2, .val = 0xc4, },
|
||||
+ { .reg = LGDT3305_CR_CTR_FREQ_1, .val = 0x00, },
|
||||
+ { .reg = LGDT3305_CR_CTR_FREQ_2, .val = 0x00, },
|
||||
+ { .reg = LGDT3305_CR_CTR_FREQ_3, .val = 0x00, },
|
||||
+ { .reg = LGDT3305_CR_CTR_FREQ_4, .val = 0x00, },
|
||||
+ { .reg = LGDT3305_CR_CTRL_7, .val = 0xf9, },
|
||||
+ { .reg = 0x0112, .val = 0x17, },
|
||||
+ { .reg = 0x0113, .val = 0x15, },
|
||||
+ { .reg = 0x0114, .val = 0x18, },
|
||||
+ { .reg = 0x0115, .val = 0xff, },
|
||||
+ { .reg = 0x0116, .val = 0x3c, },
|
||||
+ { .reg = 0x0214, .val = 0x67, },
|
||||
+ { .reg = 0x0424, .val = 0x8d, },
|
||||
+ { .reg = 0x0427, .val = 0x12, },
|
||||
+ { .reg = 0x0428, .val = 0x4f, },
|
||||
+ { .reg = LGDT3305_IFBW_1, .val = 0x80, },
|
||||
+ { .reg = LGDT3305_IFBW_2, .val = 0x00, },
|
||||
+ { .reg = 0x030a, .val = 0x08, },
|
||||
+ { .reg = 0x030b, .val = 0x9b, },
|
||||
+ { .reg = 0x030d, .val = 0x00, },
|
||||
+ { .reg = 0x030e, .val = 0x1c, },
|
||||
+ { .reg = 0x0314, .val = 0xe1, },
|
||||
+ { .reg = 0x000d, .val = 0x82, },
|
||||
+ { .reg = LGDT3305_TP_CTRL_1, .val = 0x5b, },
|
||||
+ { .reg = LGDT3305_TP_CTRL_1, .val = 0x5b, },
|
||||
+ };
|
||||
+
|
||||
+ lg_dbg("\n");
|
||||
+
|
||||
+ ret = lgdt3305_write_regs(state, lgdt3304_init_data,
|
||||
+ ARRAY_SIZE(lgdt3304_init_data));
|
||||
+ if (lg_fail(ret))
|
||||
+ goto fail;
|
||||
+
|
||||
+ ret = lgdt3305_soft_reset(state);
|
||||
+fail:
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
static int lgdt3305_init(struct dvb_frontend *fe)
|
||||
{
|
||||
struct lgdt3305_state *state = fe->demodulator_priv;
|
||||
@@ -639,6 +706,88 @@ fail:
|
||||
return ret;
|
||||
}
|
||||
|
||||
+static int lgdt3304_set_parameters(struct dvb_frontend *fe,
|
||||
+ struct dvb_frontend_parameters *param)
|
||||
+{
|
||||
+ struct lgdt3305_state *state = fe->demodulator_priv;
|
||||
+ int ret;
|
||||
+
|
||||
+ lg_dbg("(%d, %d)\n", param->frequency, param->u.vsb.modulation);
|
||||
+
|
||||
+ if (fe->ops.tuner_ops.set_params) {
|
||||
+ ret = fe->ops.tuner_ops.set_params(fe, param);
|
||||
+ if (fe->ops.i2c_gate_ctrl)
|
||||
+ fe->ops.i2c_gate_ctrl(fe, 0);
|
||||
+ if (lg_fail(ret))
|
||||
+ goto fail;
|
||||
+ state->current_frequency = param->frequency;
|
||||
+ }
|
||||
+
|
||||
+ ret = lgdt3305_set_modulation(state, param);
|
||||
+ if (lg_fail(ret))
|
||||
+ goto fail;
|
||||
+
|
||||
+ ret = lgdt3305_passband_digital_agc(state, param);
|
||||
+ if (lg_fail(ret))
|
||||
+ goto fail;
|
||||
+
|
||||
+ ret = lgdt3305_agc_setup(state, param);
|
||||
+ if (lg_fail(ret))
|
||||
+ goto fail;
|
||||
+
|
||||
+ /* reg 0x030d is 3304-only... seen in vsb and qam usbsnoops... */
|
||||
+ switch (param->u.vsb.modulation) {
|
||||
+ case VSB_8:
|
||||
+ lgdt3305_write_reg(state, 0x030d, 0x00);
|
||||
+#if 1
|
||||
+ lgdt3305_write_reg(state, LGDT3305_CR_CTR_FREQ_1, 0x4f);
|
||||
+ lgdt3305_write_reg(state, LGDT3305_CR_CTR_FREQ_2, 0x0c);
|
||||
+ lgdt3305_write_reg(state, LGDT3305_CR_CTR_FREQ_3, 0xac);
|
||||
+ lgdt3305_write_reg(state, LGDT3305_CR_CTR_FREQ_4, 0xba);
|
||||
+#endif
|
||||
+ break;
|
||||
+ case QAM_64:
|
||||
+ case QAM_256:
|
||||
+ lgdt3305_write_reg(state, 0x030d, 0x14);
|
||||
+#if 1
|
||||
+ ret = lgdt3305_set_if(state, param);
|
||||
+ if (lg_fail(ret))
|
||||
+ goto fail;
|
||||
+#endif
|
||||
+ break;
|
||||
+ default:
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+#if 0
|
||||
+ /* the set_if vsb formula doesn't work for the 3304, we end up sending
|
||||
+ * 0x40851e07 instead of 0x4f0cacba (which works back to 94050, rather
|
||||
+ * than 3250, in the case of the kworld 340u) */
|
||||
+ ret = lgdt3305_set_if(state, param);
|
||||
+ if (lg_fail(ret))
|
||||
+ goto fail;
|
||||
+#endif
|
||||
+
|
||||
+ ret = lgdt3305_spectral_inversion(state, param,
|
||||
+ state->cfg->spectral_inversion
|
||||
+ ? 1 : 0);
|
||||
+ if (lg_fail(ret))
|
||||
+ goto fail;
|
||||
+
|
||||
+ state->current_modulation = param->u.vsb.modulation;
|
||||
+
|
||||
+ ret = lgdt3305_mpeg_mode(state, state->cfg->mpeg_mode);
|
||||
+ if (lg_fail(ret))
|
||||
+ goto fail;
|
||||
+
|
||||
+ /* lgdt3305_mpeg_mode_polarity calls lgdt3305_soft_reset */
|
||||
+ ret = lgdt3305_mpeg_mode_polarity(state,
|
||||
+ state->cfg->tpclk_edge,
|
||||
+ state->cfg->tpvalid_polarity);
|
||||
+fail:
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
static int lgdt3305_set_parameters(struct dvb_frontend *fe,
|
||||
struct dvb_frontend_parameters *param)
|
||||
{
|
||||
@@ -847,6 +996,10 @@ static int lgdt3305_read_status(struct dvb_frontend *fe, fe_status_t *status)
|
||||
switch (state->current_modulation) {
|
||||
case QAM_256:
|
||||
case QAM_64:
|
||||
+#if 0 /* needed w/3304 to set FE_HAS_SIGNAL */
|
||||
+ if (cr_lock)
|
||||
+ *status |= FE_HAS_SIGNAL;
|
||||
+#endif
|
||||
ret = lgdt3305_read_fec_lock_status(state, &fec_lock);
|
||||
if (lg_fail(ret))
|
||||
goto fail;
|
||||
@@ -992,6 +1145,7 @@ static void lgdt3305_release(struct dvb_frontend *fe)
|
||||
kfree(state);
|
||||
}
|
||||
|
||||
+static struct dvb_frontend_ops lgdt3304_ops;
|
||||
static struct dvb_frontend_ops lgdt3305_ops;
|
||||
|
||||
struct dvb_frontend *lgdt3305_attach(const struct lgdt3305_config *config,
|
||||
@@ -1012,11 +1166,21 @@ struct dvb_frontend *lgdt3305_attach(const struct lgdt3305_config *config,
|
||||
state->cfg = config;
|
||||
state->i2c_adap = i2c_adap;
|
||||
|
||||
- memcpy(&state->frontend.ops, &lgdt3305_ops,
|
||||
- sizeof(struct dvb_frontend_ops));
|
||||
+ switch (config->demod_chip) {
|
||||
+ case LGDT3304:
|
||||
+ memcpy(&state->frontend.ops, &lgdt3304_ops,
|
||||
+ sizeof(struct dvb_frontend_ops));
|
||||
+ break;
|
||||
+ case LGDT3305:
|
||||
+ memcpy(&state->frontend.ops, &lgdt3305_ops,
|
||||
+ sizeof(struct dvb_frontend_ops));
|
||||
+ break;
|
||||
+ default:
|
||||
+ goto fail;
|
||||
+ }
|
||||
state->frontend.demodulator_priv = state;
|
||||
|
||||
- /* verify that we're talking to a lg dt3305 */
|
||||
+ /* verify that we're talking to a lg dt3304/5 */
|
||||
ret = lgdt3305_read_reg(state, LGDT3305_GEN_CTRL_2, &val);
|
||||
if ((lg_fail(ret)) | (val == 0))
|
||||
goto fail;
|
||||
@@ -1035,12 +1199,36 @@ struct dvb_frontend *lgdt3305_attach(const struct lgdt3305_config *config,
|
||||
|
||||
return &state->frontend;
|
||||
fail:
|
||||
- lg_warn("unable to detect LGDT3305 hardware\n");
|
||||
+ lg_warn("unable to detect %s hardware\n",
|
||||
+ config->demod_chip ? "LGDT3304" : "LGDT3305");
|
||||
kfree(state);
|
||||
return NULL;
|
||||
}
|
||||
EXPORT_SYMBOL(lgdt3305_attach);
|
||||
|
||||
+static struct dvb_frontend_ops lgdt3304_ops = {
|
||||
+ .info = {
|
||||
+ .name = "LG Electronics LGDT3304 VSB/QAM Frontend",
|
||||
+ .type = FE_ATSC,
|
||||
+ .frequency_min = 54000000,
|
||||
+ .frequency_max = 858000000,
|
||||
+ .frequency_stepsize = 62500,
|
||||
+ .caps = FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB
|
||||
+ },
|
||||
+ .i2c_gate_ctrl = lgdt3305_i2c_gate_ctrl,
|
||||
+ .init = lgdt3304_init,
|
||||
+ .sleep = lgdt3304_sleep,
|
||||
+ .set_frontend = lgdt3304_set_parameters,
|
||||
+ .get_frontend = lgdt3305_get_frontend,
|
||||
+ .get_tune_settings = lgdt3305_get_tune_settings,
|
||||
+ .read_status = lgdt3305_read_status,
|
||||
+ .read_ber = lgdt3305_read_ber,
|
||||
+ .read_signal_strength = lgdt3305_read_signal_strength,
|
||||
+ .read_snr = lgdt3305_read_snr,
|
||||
+ .read_ucblocks = lgdt3305_read_ucblocks,
|
||||
+ .release = lgdt3305_release,
|
||||
+};
|
||||
+
|
||||
static struct dvb_frontend_ops lgdt3305_ops = {
|
||||
.info = {
|
||||
.name = "LG Electronics LGDT3305 VSB/QAM Frontend",
|
||||
@@ -1064,7 +1252,7 @@ static struct dvb_frontend_ops lgdt3305_ops = {
|
||||
.release = lgdt3305_release,
|
||||
};
|
||||
|
||||
-MODULE_DESCRIPTION("LG Electronics LGDT3305 ATSC/QAM-B Demodulator Driver");
|
||||
+MODULE_DESCRIPTION("LG Electronics LGDT3304/5 ATSC/QAM-B Demodulator Driver");
|
||||
MODULE_AUTHOR("Michael Krufky <mkrufky@linuxtv.org>");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_VERSION("0.1");
|
||||
diff --git a/drivers/media/dvb/frontends/lgdt3305.h b/drivers/media/dvb/frontends/lgdt3305.h
|
||||
index 9cb11c9..a7f30c2 100644
|
||||
--- a/drivers/media/dvb/frontends/lgdt3305.h
|
||||
+++ b/drivers/media/dvb/frontends/lgdt3305.h
|
||||
@@ -41,6 +41,11 @@ enum lgdt3305_tp_valid_polarity {
|
||||
LGDT3305_TP_VALID_HIGH = 1,
|
||||
};
|
||||
|
||||
+enum lgdt_demod_chip_type {
|
||||
+ LGDT3305 = 0,
|
||||
+ LGDT3304 = 1,
|
||||
+};
|
||||
+
|
||||
struct lgdt3305_config {
|
||||
u8 i2c_addr;
|
||||
|
||||
@@ -65,6 +70,7 @@ struct lgdt3305_config {
|
||||
enum lgdt3305_mpeg_mode mpeg_mode;
|
||||
enum lgdt3305_tp_clock_edge tpclk_edge;
|
||||
enum lgdt3305_tp_valid_polarity tpvalid_polarity;
|
||||
+ enum lgdt_demod_chip_type demod_chip;
|
||||
};
|
||||
|
||||
#if defined(CONFIG_DVB_LGDT3305) || (defined(CONFIG_DVB_LGDT3305_MODULE) && \
|
||||
--
|
||||
1.6.6
|
||||
|
|
@ -0,0 +1,306 @@
|
|||
diff -Naurp linux-2.6.35/drivers/media/dvb/dvb-core/dvb_net.c linux-2.6.35.media/drivers/media/dvb/dvb-core/dvb_net.c
|
||||
--- linux-2.6.35/drivers/media/dvb/dvb-core/dvb_net.c 2011-01-25 10:10:44.000000000 -0500
|
||||
+++ linux-2.6.35.media/drivers/media/dvb/dvb-core/dvb_net.c 2011-01-25 10:14:06.000000000 -0500
|
||||
@@ -1329,8 +1329,7 @@ static int dvb_net_remove_if(struct dvb_
|
||||
return -EBUSY;
|
||||
|
||||
dvb_net_stop(net);
|
||||
- flush_work_sync(&priv->set_multicast_list_wq);
|
||||
- flush_work_sync(&priv->restart_net_feed_wq);
|
||||
+ flush_scheduled_work();
|
||||
printk("dvb_net: removed network interface %s\n", net->name);
|
||||
unregister_netdev(net);
|
||||
dvbnet->state[num]=0;
|
||||
diff -Naurp linux-2.6.35/drivers/media/dvb/dvb-usb/dvb-usb-remote.c linux-2.6.35.media/drivers/media/dvb/dvb-usb/dvb-usb-remote.c
|
||||
--- linux-2.6.35/drivers/media/dvb/dvb-usb/dvb-usb-remote.c 2011-01-25 10:10:44.000000000 -0500
|
||||
+++ linux-2.6.35.media/drivers/media/dvb/dvb-usb/dvb-usb-remote.c 2011-01-25 10:14:06.000000000 -0500
|
||||
@@ -314,6 +314,7 @@ int dvb_usb_remote_exit(struct dvb_usb_d
|
||||
{
|
||||
if (d->state & DVB_USB_STATE_REMOTE) {
|
||||
cancel_delayed_work_sync(&d->rc_query_work);
|
||||
+ flush_scheduled_work();
|
||||
if (d->props.rc.mode == DVB_RC_LEGACY)
|
||||
input_unregister_device(d->input_dev);
|
||||
else
|
||||
diff -Naurp linux-2.6.35/drivers/media/dvb/mantis/mantis_evm.c linux-2.6.35.media/drivers/media/dvb/mantis/mantis_evm.c
|
||||
--- linux-2.6.35/drivers/media/dvb/mantis/mantis_evm.c 2011-01-25 10:10:44.000000000 -0500
|
||||
+++ linux-2.6.35.media/drivers/media/dvb/mantis/mantis_evm.c 2011-01-25 10:14:06.000000000 -0500
|
||||
@@ -111,7 +111,7 @@ void mantis_evmgr_exit(struct mantis_ca
|
||||
struct mantis_pci *mantis = ca->ca_priv;
|
||||
|
||||
dprintk(MANTIS_DEBUG, 1, "Mantis Host I/F Event manager exiting");
|
||||
- flush_work_sync(&ca->hif_evm_work);
|
||||
+ flush_scheduled_work();
|
||||
mantis_hif_exit(ca);
|
||||
mantis_pcmcia_exit(ca);
|
||||
}
|
||||
diff -Naurp linux-2.6.35/drivers/media/dvb/mantis/mantis_uart.c linux-2.6.35.media/drivers/media/dvb/mantis/mantis_uart.c
|
||||
--- linux-2.6.35/drivers/media/dvb/mantis/mantis_uart.c 2011-01-25 10:10:44.000000000 -0500
|
||||
+++ linux-2.6.35.media/drivers/media/dvb/mantis/mantis_uart.c 2011-01-25 10:14:06.000000000 -0500
|
||||
@@ -182,6 +182,5 @@ void mantis_uart_exit(struct mantis_pci
|
||||
{
|
||||
/* disable interrupt */
|
||||
mmwrite(mmread(MANTIS_UART_CTL) & 0xffef, MANTIS_UART_CTL);
|
||||
- flush_work_sync(&mantis->uart_work);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(mantis_uart_exit);
|
||||
diff -Naurp linux-2.6.35/drivers/media/rc/keymaps/rc-tbs-nec.c linux-2.6.35.media/drivers/media/rc/keymaps/rc-tbs-nec.c
|
||||
--- linux-2.6.35/drivers/media/rc/keymaps/rc-tbs-nec.c 2011-01-25 10:10:44.000000000 -0500
|
||||
+++ linux-2.6.35.media/drivers/media/rc/keymaps/rc-tbs-nec.c 2011-01-25 11:10:04.000000000 -0500
|
||||
@@ -12,6 +12,9 @@
|
||||
|
||||
#include <media/rc-map.h>
|
||||
|
||||
+#define KEY_10CHANNELSUP 0x1b8
|
||||
+#define KEY_10CHANNELSDOWN 0x1b9
|
||||
+
|
||||
static struct rc_map_table tbs_nec[] = {
|
||||
{ 0x84, KEY_POWER2}, /* power */
|
||||
{ 0x94, KEY_MUTE}, /* mute */
|
||||
diff -Naurp linux-2.6.35/drivers/media/video/bt8xx/bttv-driver.c linux-2.6.35.media/drivers/media/video/bt8xx/bttv-driver.c
|
||||
--- linux-2.6.35/drivers/media/video/bt8xx/bttv-driver.c 2011-01-25 10:10:44.000000000 -0500
|
||||
+++ linux-2.6.35.media/drivers/media/video/bt8xx/bttv-driver.c 2011-01-25 10:32:49.000000000 -0500
|
||||
@@ -189,14 +189,8 @@ static void request_modules(struct bttv
|
||||
INIT_WORK(&dev->request_module_wk, request_module_async);
|
||||
schedule_work(&dev->request_module_wk);
|
||||
}
|
||||
-
|
||||
-static void flush_request_modules(struct bttv *dev)
|
||||
-{
|
||||
- flush_work_sync(&dev->request_module_wk);
|
||||
-}
|
||||
#else
|
||||
#define request_modules(dev)
|
||||
-#define flush_request_modules(dev)
|
||||
#endif /* CONFIG_MODULES */
|
||||
|
||||
|
||||
@@ -4435,9 +4429,6 @@ static void __devexit bttv_remove(struct
|
||||
if (bttv_verbose)
|
||||
printk("bttv%d: unloading\n",btv->c.nr);
|
||||
|
||||
- if (bttv_tvcards[btv->c.type].has_dvb)
|
||||
- flush_request_modules(btv);
|
||||
-
|
||||
/* shutdown everything (DMA+IRQs) */
|
||||
btand(~15, BT848_GPIO_DMA_CTL);
|
||||
btwrite(0, BT848_INT_MASK);
|
||||
diff -Naurp linux-2.6.35/drivers/media/video/cx18/cx18-driver.c linux-2.6.35.media/drivers/media/video/cx18/cx18-driver.c
|
||||
--- linux-2.6.35/drivers/media/video/cx18/cx18-driver.c 2011-01-25 10:10:44.000000000 -0500
|
||||
+++ linux-2.6.35.media/drivers/media/video/cx18/cx18-driver.c 2011-01-25 10:32:49.000000000 -0500
|
||||
@@ -268,14 +268,8 @@ static void request_modules(struct cx18
|
||||
INIT_WORK(&dev->request_module_wk, request_module_async);
|
||||
schedule_work(&dev->request_module_wk);
|
||||
}
|
||||
-
|
||||
-static void flush_request_modules(struct cx18 *dev)
|
||||
-{
|
||||
- flush_work_sync(&dev->request_module_wk);
|
||||
-}
|
||||
#else
|
||||
#define request_modules(dev)
|
||||
-#define flush_request_modules(dev)
|
||||
#endif /* CONFIG_MODULES */
|
||||
|
||||
/* Generic utility functions */
|
||||
@@ -1245,8 +1239,6 @@ static void cx18_remove(struct pci_dev *
|
||||
|
||||
CX18_DEBUG_INFO("Removing Card\n");
|
||||
|
||||
- flush_request_modules(cx);
|
||||
-
|
||||
/* Stop all captures */
|
||||
CX18_DEBUG_INFO("Stopping all streams\n");
|
||||
if (atomic_read(&cx->tot_capturing) > 0)
|
||||
diff -Naurp linux-2.6.35/drivers/media/video/cx231xx/cx231xx-cards.c linux-2.6.35.media/drivers/media/video/cx231xx/cx231xx-cards.c
|
||||
--- linux-2.6.35/drivers/media/video/cx231xx/cx231xx-cards.c 2011-01-25 10:10:44.000000000 -0500
|
||||
+++ linux-2.6.35.media/drivers/media/video/cx231xx/cx231xx-cards.c 2011-01-25 10:32:49.000000000 -0500
|
||||
@@ -813,14 +813,8 @@ static void request_modules(struct cx231
|
||||
INIT_WORK(&dev->request_module_wk, request_module_async);
|
||||
schedule_work(&dev->request_module_wk);
|
||||
}
|
||||
-
|
||||
-static void flush_request_modules(struct cx231xx *dev)
|
||||
-{
|
||||
- flush_work_sync(&dev->request_module_wk);
|
||||
-}
|
||||
#else
|
||||
#define request_modules(dev)
|
||||
-#define flush_request_modules(dev)
|
||||
#endif /* CONFIG_MODULES */
|
||||
|
||||
/*
|
||||
@@ -1153,8 +1147,6 @@ static void cx231xx_usb_disconnect(struc
|
||||
if (!dev->udev)
|
||||
return;
|
||||
|
||||
- flush_request_modules(dev);
|
||||
-
|
||||
/* delete v4l2 device */
|
||||
v4l2_device_unregister(&dev->v4l2_dev);
|
||||
|
||||
diff -Naurp linux-2.6.35/drivers/media/video/cx23885/cx23885-input.c linux-2.6.35.media/drivers/media/video/cx23885/cx23885-input.c
|
||||
--- linux-2.6.35/drivers/media/video/cx23885/cx23885-input.c 2011-01-25 10:10:44.000000000 -0500
|
||||
+++ linux-2.6.35.media/drivers/media/video/cx23885/cx23885-input.c 2011-01-25 10:14:06.000000000 -0500
|
||||
@@ -229,6 +229,8 @@ static void cx23885_input_ir_stop(struct
|
||||
v4l2_subdev_call(dev->sd_ir, ir, rx_s_parameters, ¶ms);
|
||||
v4l2_subdev_call(dev->sd_ir, ir, rx_g_parameters, ¶ms);
|
||||
}
|
||||
+
|
||||
+ flush_scheduled_work();
|
||||
}
|
||||
|
||||
static void cx23885_input_ir_close(struct rc_dev *rc)
|
||||
diff -Naurp linux-2.6.35/drivers/media/video/cx88/cx88-mpeg.c linux-2.6.35.media/drivers/media/video/cx88/cx88-mpeg.c
|
||||
--- linux-2.6.35/drivers/media/video/cx88/cx88-mpeg.c 2011-01-25 10:10:44.000000000 -0500
|
||||
+++ linux-2.6.35.media/drivers/media/video/cx88/cx88-mpeg.c 2011-01-25 10:32:49.000000000 -0500
|
||||
@@ -66,14 +66,8 @@ static void request_modules(struct cx880
|
||||
INIT_WORK(&dev->request_module_wk, request_module_async);
|
||||
schedule_work(&dev->request_module_wk);
|
||||
}
|
||||
-
|
||||
-static void flush_request_modules(struct cx8802_dev *dev)
|
||||
-{
|
||||
- flush_work_sync(&dev->request_module_wk);
|
||||
-}
|
||||
#else
|
||||
#define request_modules(dev)
|
||||
-#define flush_request_modules(dev)
|
||||
#endif /* CONFIG_MODULES */
|
||||
|
||||
|
||||
@@ -825,8 +819,6 @@ static void __devexit cx8802_remove(stru
|
||||
|
||||
dprintk( 1, "%s\n", __func__);
|
||||
|
||||
- flush_request_modules(dev);
|
||||
-
|
||||
if (!list_empty(&dev->drvlist)) {
|
||||
struct cx8802_driver *drv, *tmp;
|
||||
int err;
|
||||
diff -Naurp linux-2.6.35/drivers/media/video/em28xx/em28xx-cards.c linux-2.6.35.media/drivers/media/video/em28xx/em28xx-cards.c
|
||||
--- linux-2.6.35/drivers/media/video/em28xx/em28xx-cards.c 2011-01-25 10:10:44.000000000 -0500
|
||||
+++ linux-2.6.35.media/drivers/media/video/em28xx/em28xx-cards.c 2011-01-25 10:32:49.000000000 -0500
|
||||
@@ -2693,14 +2693,8 @@ static void request_modules(struct em28x
|
||||
INIT_WORK(&dev->request_module_wk, request_module_async);
|
||||
schedule_work(&dev->request_module_wk);
|
||||
}
|
||||
-
|
||||
-static void flush_request_modules(struct em28xx *dev)
|
||||
-{
|
||||
- flush_work_sync(&dev->request_module_wk);
|
||||
-}
|
||||
#else
|
||||
#define request_modules(dev)
|
||||
-#define flush_request_modules(dev)
|
||||
#endif /* CONFIG_MODULES */
|
||||
|
||||
/*
|
||||
@@ -3127,8 +3121,6 @@ static void em28xx_usb_disconnect(struct
|
||||
|
||||
em28xx_info("disconnecting %s\n", dev->vdev->name);
|
||||
|
||||
- flush_request_modules(dev);
|
||||
-
|
||||
/* wait until all current v4l2 io is finished then deallocate
|
||||
resources */
|
||||
mutex_lock(&dev->lock);
|
||||
diff -Naurp linux-2.6.35/drivers/media/video/omap24xxcam.c linux-2.6.35.media/drivers/media/video/omap24xxcam.c
|
||||
--- linux-2.6.35/drivers/media/video/omap24xxcam.c 2011-01-25 10:10:44.000000000 -0500
|
||||
+++ linux-2.6.35.media/drivers/media/video/omap24xxcam.c 2011-01-25 10:14:06.000000000 -0500
|
||||
@@ -1198,7 +1198,7 @@ static int vidioc_streamoff(struct file
|
||||
|
||||
atomic_inc(&cam->reset_disable);
|
||||
|
||||
- flush_work_sync(&cam->sensor_reset_work);
|
||||
+ flush_scheduled_work();
|
||||
|
||||
rval = videobuf_streamoff(q);
|
||||
if (!rval) {
|
||||
@@ -1512,7 +1512,7 @@ static int omap24xxcam_release(struct fi
|
||||
|
||||
atomic_inc(&cam->reset_disable);
|
||||
|
||||
- flush_work_sync(&cam->sensor_reset_work);
|
||||
+ flush_scheduled_work();
|
||||
|
||||
/* stop streaming capture */
|
||||
videobuf_streamoff(&fh->vbq);
|
||||
@@ -1536,7 +1536,7 @@ static int omap24xxcam_release(struct fi
|
||||
* not be scheduled anymore since streaming is already
|
||||
* disabled.)
|
||||
*/
|
||||
- flush_work_sync(&cam->sensor_reset_work);
|
||||
+ flush_scheduled_work();
|
||||
|
||||
mutex_lock(&cam->mutex);
|
||||
if (atomic_dec_return(&cam->users) == 0) {
|
||||
diff -Naurp linux-2.6.35/drivers/media/video/saa7134/saa7134-core.c linux-2.6.35.media/drivers/media/video/saa7134/saa7134-core.c
|
||||
--- linux-2.6.35/drivers/media/video/saa7134/saa7134-core.c 2011-01-25 10:10:44.000000000 -0500
|
||||
+++ linux-2.6.35.media/drivers/media/video/saa7134/saa7134-core.c 2011-01-25 10:32:49.000000000 -0500
|
||||
@@ -166,14 +166,8 @@ static void request_submodules(struct sa
|
||||
schedule_work(&dev->request_module_wk);
|
||||
}
|
||||
|
||||
-static void flush_request_submodules(struct saa7134_dev *dev)
|
||||
-{
|
||||
- flush_work_sync(&dev->request_module_wk);
|
||||
-}
|
||||
-
|
||||
#else
|
||||
#define request_submodules(dev)
|
||||
-#define flush_request_submodules(dev)
|
||||
#endif /* CONFIG_MODULES */
|
||||
|
||||
/* ------------------------------------------------------------------ */
|
||||
@@ -1027,6 +1021,8 @@ static int __devinit saa7134_initdev(str
|
||||
}
|
||||
}
|
||||
|
||||
+ request_submodules(dev);
|
||||
+
|
||||
v4l2_prio_init(&dev->prio);
|
||||
|
||||
mutex_lock(&saa7134_devlist_lock);
|
||||
@@ -1081,7 +1077,6 @@ static int __devinit saa7134_initdev(str
|
||||
if (saa7134_dmasound_init && !dev->dmasound.priv_data)
|
||||
saa7134_dmasound_init(dev);
|
||||
|
||||
- request_submodules(dev);
|
||||
return 0;
|
||||
|
||||
fail4:
|
||||
@@ -1107,8 +1102,6 @@ static void __devexit saa7134_finidev(st
|
||||
struct saa7134_dev *dev = container_of(v4l2_dev, struct saa7134_dev, v4l2_dev);
|
||||
struct saa7134_mpeg_ops *mops;
|
||||
|
||||
- flush_request_submodules(dev);
|
||||
-
|
||||
/* Release DMA sound modules if present */
|
||||
if (saa7134_dmasound_exit && dev->dmasound.priv_data) {
|
||||
saa7134_dmasound_exit(dev);
|
||||
diff -Naurp linux-2.6.35/drivers/media/video/saa7134/saa7134-empress.c linux-2.6.35.media/drivers/media/video/saa7134/saa7134-empress.c
|
||||
--- linux-2.6.35/drivers/media/video/saa7134/saa7134-empress.c 2011-01-25 10:10:44.000000000 -0500
|
||||
+++ linux-2.6.35.media/drivers/media/video/saa7134/saa7134-empress.c 2011-01-25 10:14:06.000000000 -0500
|
||||
@@ -553,7 +553,7 @@ static int empress_fini(struct saa7134_d
|
||||
|
||||
if (NULL == dev->empress_dev)
|
||||
return 0;
|
||||
- flush_work_sync(&dev->empress_workqueue);
|
||||
+ flush_scheduled_work();
|
||||
video_unregister_device(dev->empress_dev);
|
||||
dev->empress_dev = NULL;
|
||||
return 0;
|
||||
diff -Naurp linux-2.6.35/drivers/media/video/tlg2300/pd-main.c linux-2.6.35.media/drivers/media/video/tlg2300/pd-main.c
|
||||
--- linux-2.6.35/drivers/media/video/tlg2300/pd-main.c 2011-01-25 10:10:44.000000000 -0500
|
||||
+++ linux-2.6.35.media/drivers/media/video/tlg2300/pd-main.c 2011-01-25 11:08:48.000000000 -0500
|
||||
@@ -452,8 +452,7 @@ static int poseidon_probe(struct usb_int
|
||||
|
||||
device_init_wakeup(&udev->dev, 1);
|
||||
#ifdef CONFIG_PM
|
||||
- pm_runtime_set_autosuspend_delay(&pd->udev->dev,
|
||||
- 1000 * PM_SUSPEND_DELAY);
|
||||
+ pd->udev->autosuspend_delay = HZ * PM_SUSPEND_DELAY;
|
||||
usb_enable_autosuspend(pd->udev);
|
||||
|
||||
if (in_hibernation(pd)) {
|
|
@ -0,0 +1,21 @@
|
|||
Index: linux-2.6.35.x86_64/drivers/staging/Kconfig
|
||||
===================================================================
|
||||
--- linux-2.6.35.x86_64.orig/drivers/staging/Kconfig
|
||||
+++ linux-2.6.35.x86_64/drivers/staging/Kconfig
|
||||
@@ -147,5 +147,7 @@ source "drivers/staging/mrst-touchscreen
|
||||
|
||||
source "drivers/staging/msm/Kconfig"
|
||||
|
||||
+source "drivers/staging/lirc/Kconfig"
|
||||
+
|
||||
endif # !STAGING_EXCLUDE_BUILD
|
||||
endif # STAGING
|
||||
Index: linux-2.6.35.x86_64/drivers/staging/Makefile
|
||||
===================================================================
|
||||
--- linux-2.6.35.x86_64.orig/drivers/staging/Makefile
|
||||
+++ linux-2.6.35.x86_64/drivers/staging/Makefile
|
||||
@@ -54,3 +54,4 @@ obj-$(CONFIG_ADIS16255) += adis16255/
|
||||
obj-$(CONFIG_FB_XGI) += xgifb/
|
||||
obj-$(CONFIG_TOUCHSCREEN_MRSTOUCH) += mrst-touchscreen/
|
||||
obj-$(CONFIG_MSM_STAGING) += msm/
|
||||
+obj-$(CONFIG_LIRC_STAGING) += lirc/
|
|
@ -0,0 +1,437 @@
|
|||
All IR fixups take from:
|
||||
|
||||
http://git.kernel.org/?p=linux/kernel/git/jarod/linux-2.6-ir.git;a=shortlog;h=refs/heads/staging
|
||||
|
||||
Should be in v4l/dvb/rc soon...
|
||||
|
||||
|
||||
commit db7e4498b17d9b52c8fddf828bad54454ab130ec
|
||||
Author: Jarod Wilson <jarod@redhat.com>
|
||||
Date: Thu Jan 27 13:08:35 2011 -0500
|
||||
|
||||
rc/streamzap: fix reporting response times
|
||||
|
||||
The streamzap driver has relatively low sampling resolution, and any
|
||||
delays in reporting events seem to cause some minor problems for the
|
||||
likes of irw when using the lirc bridge driver, resulting in a single
|
||||
keypress registering as multiple independent ones, rather than as a
|
||||
single press with repeats. If we call ir_raw_event_handle() more
|
||||
frequently and reset the rawir kfifo at end-of-signal, the behavior
|
||||
improves quite a bit.
|
||||
|
||||
Signed-off-by: Jarod Wilson <jarod@redhat.com>
|
||||
|
||||
commit 583602a0c6cab187b2f3b4c90509bbe2b85f5d51
|
||||
Author: Jarod Wilson <jarod@redhat.com>
|
||||
Date: Mon Jan 24 22:06:32 2011 -0500
|
||||
|
||||
mceusb: really fix remaining keybounce issues
|
||||
|
||||
Make sure rawir struct is zeroed out before populating it for each
|
||||
ir_raw_event_store_with_filter() call, and when we see a trailing 0x80
|
||||
packet (end-of-data), issue an ir_raw_event_reset() call.
|
||||
|
||||
Signed-off-by: Jarod Wilson <jarod@redhat.com>
|
||||
|
||||
commit 8b07e7fe2fa1c763a8f08a179917fdf1a43b479d
|
||||
Author: Jarod Wilson <jarod@redhat.com>
|
||||
Date: Thu Jan 20 16:31:18 2011 -0500
|
||||
|
||||
ir-kbd-i2c: improve remote behavior with z8 behind usb
|
||||
|
||||
Add the same "are you ready?" i2c_master_send() poll command to
|
||||
get_key_haup_xvr found in lirc_zilog, which is apparently seen in
|
||||
the Windows driver for the PVR-150 w/a z8. This stabilizes what is
|
||||
received from both the HD-PVR and HVR-1950, even with their polling
|
||||
intervals at the default of 100, thus the removal of the custom
|
||||
260ms polling_interval in pvrusb2-i2c-core.c.
|
||||
|
||||
Acked-by: Andy Walls <awalls@md.metrocast.net>
|
||||
Acked-by: Mike Isely <isely@isely.net>
|
||||
Signed-off-by: Jarod Wilson <jarod@redhat.com>
|
||||
|
||||
commit aedf7d79cdeaf97d3efc7d667eeb94689bbc6e7d
|
||||
Author: Jarod Wilson <jarod@redhat.com>
|
||||
Date: Wed Jan 19 16:49:19 2011 -0500
|
||||
|
||||
lirc_zilog: z8 on usb doesn't like back-to-back i2c_master_send
|
||||
|
||||
Both the HD-PVR and HVR-1950, driven by the hdpvr and pvrusb2 drivers
|
||||
respectively, have a zilog z8 chip exposed via i2c. These are both
|
||||
usb-connected devices, and on both of them, back-to-back i2c_master_send
|
||||
calls that work fine with a z8 on a pci card fail with a -EIO, as the
|
||||
chip isn't yet ready from the prior command. To cope with that, add a
|
||||
delay and retry loop where necessary.
|
||||
|
||||
Acked-by: Andy Walls <awalls@md.metrocast.net>
|
||||
Signed-off-by: Jarod Wilson <jarod@redhat.com>
|
||||
|
||||
t 2b197149441796e694721db984db9e5ca4656856
|
||||
Author: Jarod Wilson <jarod@redhat.com>
|
||||
Date: Wed Jan 19 16:10:14 2011 -0500
|
||||
|
||||
hdpvr: fix up i2c device registration
|
||||
|
||||
We have to actually call i2c_new_device() once for each of the rx and tx
|
||||
addresses. Also improve error-handling and device remove i2c cleanup.
|
||||
|
||||
Reviewed-by: Andy Walls <awalls@md.metrocast.net>
|
||||
Signed-off-by: Jarod Wilson <jarod@redhat.com>
|
||||
|
||||
commit f2a6849f005fc0da0528ada0c3c79c7572db2898
|
||||
Author: Jarod Wilson <jarod@redhat.com>
|
||||
Date: Tue Jan 18 00:33:08 2011 -0500
|
||||
|
||||
rc/ir-lirc-codec: add back debug spew
|
||||
|
||||
Some occasionally useful debug spew disappeared as part of a feature
|
||||
update a while back, and I'm finding myself in need of it again to help
|
||||
diagnose some issues.
|
||||
|
||||
Signed-off-by: Jarod Wilson <jarod@redhat.com>
|
||||
|
||||
commit 20285f04106a578f6202ba043e0044df614aee05
|
||||
Author: Jarod Wilson <jarod@redhat.com>
|
||||
Date: Tue Jan 18 00:27:45 2011 -0500
|
||||
|
||||
rc/mce: add mappings for missing keys
|
||||
|
||||
Per http://mediacenterguides.com/book/export/html/31 and investigation
|
||||
by Erin, we were missing these last three mappings to complete the mce
|
||||
key table. Lets remedy that.
|
||||
|
||||
Reported-by: Erin Simonds <fisslefink@gmail.com>
|
||||
Signed-off-by: Jarod Wilson <jarod@redhat.com>
|
||||
|
||||
|
||||
|
||||
diff --git a/drivers/media/rc/ir-lirc-codec.c b/drivers/media/rc/ir-lirc-codec.c
|
||||
index f011c5d..1c5cc65 100644
|
||||
--- a/drivers/media/rc/ir-lirc-codec.c
|
||||
+++ b/drivers/media/rc/ir-lirc-codec.c
|
||||
@@ -1,4 +1,4 @@
|
||||
-/* ir-lirc-codec.c - ir-core to classic lirc interface bridge
|
||||
+/* ir-lirc-codec.c - rc-core to classic lirc interface bridge
|
||||
*
|
||||
* Copyright (C) 2010 by Jarod Wilson <jarod@redhat.com>
|
||||
*
|
||||
@@ -47,6 +47,7 @@ static int ir_lirc_decode(struct rc_dev *dev, struct ir_raw_event ev)
|
||||
/* Carrier reports */
|
||||
if (ev.carrier_report) {
|
||||
sample = LIRC_FREQUENCY(ev.carrier);
|
||||
+ IR_dprintk(2, "carrier report (freq: %d)\n", sample);
|
||||
|
||||
/* Packet end */
|
||||
} else if (ev.timeout) {
|
||||
@@ -62,6 +63,7 @@ static int ir_lirc_decode(struct rc_dev *dev, struct ir_raw_event ev)
|
||||
return 0;
|
||||
|
||||
sample = LIRC_TIMEOUT(ev.duration / 1000);
|
||||
+ IR_dprintk(2, "timeout report (duration: %d)\n", sample);
|
||||
|
||||
/* Normal sample */
|
||||
} else {
|
||||
@@ -85,6 +87,8 @@ static int ir_lirc_decode(struct rc_dev *dev, struct ir_raw_event ev)
|
||||
|
||||
sample = ev.pulse ? LIRC_PULSE(ev.duration / 1000) :
|
||||
LIRC_SPACE(ev.duration / 1000);
|
||||
+ IR_dprintk(2, "delivering %uus %s to lirc_dev\n",
|
||||
+ TO_US(ev.duration), TO_STR(ev.pulse));
|
||||
}
|
||||
|
||||
lirc_buffer_write(dev->raw->lirc.drv->rbuf,
|
||||
diff --git a/drivers/media/rc/keymaps/rc-rc6-mce.c b/drivers/media/rc/keymaps/rc-rc6-mce.c
|
||||
index 3bf3337..2f5dc06 100644
|
||||
--- a/drivers/media/rc/keymaps/rc-rc6-mce.c
|
||||
+++ b/drivers/media/rc/keymaps/rc-rc6-mce.c
|
||||
@@ -3,6 +3,9 @@
|
||||
*
|
||||
* Copyright (c) 2010 by Jarod Wilson <jarod@redhat.com>
|
||||
*
|
||||
+ * See http://mediacenterguides.com/book/export/html/31 for details on
|
||||
+ * key mappings.
|
||||
+ *
|
||||
* 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
|
||||
@@ -60,6 +63,9 @@ static struct rc_map_table rc6_mce[] = {
|
||||
{ 0x800f0426, KEY_EPG }, /* Guide */
|
||||
{ 0x800f0427, KEY_ZOOM }, /* Aspect */
|
||||
|
||||
+ { 0x800f0432, KEY_MODE }, /* Visualization */
|
||||
+ { 0x800f0433, KEY_PRESENTATION }, /* Slide Show */
|
||||
+ { 0x800f0434, KEY_EJECTCD },
|
||||
{ 0x800f043a, KEY_BRIGHTNESSUP },
|
||||
|
||||
{ 0x800f0446, KEY_TV },
|
||||
diff --git a/drivers/media/rc/mceusb.c b/drivers/media/rc/mceusb.c
|
||||
index 079353e..cf763fb 100644
|
||||
--- a/drivers/media/rc/mceusb.c
|
||||
+++ b/drivers/media/rc/mceusb.c
|
||||
@@ -855,6 +855,7 @@ static void mceusb_process_ir_data(struct mceusb_dev *ir, int buf_len)
|
||||
break;
|
||||
case PARSE_IRDATA:
|
||||
ir->rem--;
|
||||
+ init_ir_raw_event(&rawir);
|
||||
rawir.pulse = ((ir->buf_in[i] & MCE_PULSE_BIT) != 0);
|
||||
rawir.duration = (ir->buf_in[i] & MCE_PULSE_MASK)
|
||||
* MS_TO_US(MCE_TIME_UNIT);
|
||||
@@ -883,6 +884,8 @@ static void mceusb_process_ir_data(struct mceusb_dev *ir, int buf_len)
|
||||
i, ir->rem + 1, false);
|
||||
if (ir->rem)
|
||||
ir->parser_state = PARSE_IRDATA;
|
||||
+ else
|
||||
+ ir_raw_event_reset(ir->rc);
|
||||
break;
|
||||
}
|
||||
|
||||
diff --git a/drivers/media/video/hdpvr/hdpvr-core.c b/drivers/media/video/hdpvr/hdpvr-core.c
|
||||
index a6572e5..a27d93b 100644
|
||||
--- a/drivers/media/video/hdpvr/hdpvr-core.c
|
||||
+++ b/drivers/media/video/hdpvr/hdpvr-core.c
|
||||
@@ -283,6 +283,7 @@ static int hdpvr_probe(struct usb_interface *interface,
|
||||
struct hdpvr_device *dev;
|
||||
struct usb_host_interface *iface_desc;
|
||||
struct usb_endpoint_descriptor *endpoint;
|
||||
+ struct i2c_client *client;
|
||||
size_t buffer_size;
|
||||
int i;
|
||||
int retval = -ENOMEM;
|
||||
@@ -381,13 +382,21 @@ static int hdpvr_probe(struct usb_interface *interface,
|
||||
#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
|
||||
retval = hdpvr_register_i2c_adapter(dev);
|
||||
if (retval < 0) {
|
||||
- v4l2_err(&dev->v4l2_dev, "registering i2c adapter failed\n");
|
||||
+ v4l2_err(&dev->v4l2_dev, "i2c adapter register failed\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
- retval = hdpvr_register_i2c_ir(dev);
|
||||
- if (retval < 0)
|
||||
- v4l2_err(&dev->v4l2_dev, "registering i2c IR devices failed\n");
|
||||
+ client = hdpvr_register_ir_rx_i2c(dev);
|
||||
+ if (!client) {
|
||||
+ v4l2_err(&dev->v4l2_dev, "i2c IR RX device register failed\n");
|
||||
+ goto reg_fail;
|
||||
+ }
|
||||
+
|
||||
+ client = hdpvr_register_ir_tx_i2c(dev);
|
||||
+ if (!client) {
|
||||
+ v4l2_err(&dev->v4l2_dev, "i2c IR TX device register failed\n");
|
||||
+ goto reg_fail;
|
||||
+ }
|
||||
#endif
|
||||
|
||||
/* let the user know what node this device is now attached to */
|
||||
@@ -395,6 +404,10 @@ static int hdpvr_probe(struct usb_interface *interface,
|
||||
video_device_node_name(dev->video_dev));
|
||||
return 0;
|
||||
|
||||
+reg_fail:
|
||||
+#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
|
||||
+ i2c_del_adapter(&dev->i2c_adapter);
|
||||
+#endif
|
||||
error:
|
||||
if (dev) {
|
||||
/* Destroy single thread */
|
||||
@@ -424,6 +437,9 @@ static void hdpvr_disconnect(struct usb_interface *interface)
|
||||
mutex_lock(&dev->io_mutex);
|
||||
hdpvr_cancel_queue(dev);
|
||||
mutex_unlock(&dev->io_mutex);
|
||||
+#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
|
||||
+ i2c_del_adapter(&dev->i2c_adapter);
|
||||
+#endif
|
||||
video_unregister_device(dev->video_dev);
|
||||
atomic_dec(&dev_nr);
|
||||
}
|
||||
diff --git a/drivers/media/video/hdpvr/hdpvr-i2c.c b/drivers/media/video/hdpvr/hdpvr-i2c.c
|
||||
index 89b71fa..e53fa55 100644
|
||||
--- a/drivers/media/video/hdpvr/hdpvr-i2c.c
|
||||
+++ b/drivers/media/video/hdpvr/hdpvr-i2c.c
|
||||
@@ -31,26 +31,34 @@
|
||||
#define Z8F0811_IR_RX_I2C_ADDR 0x71
|
||||
|
||||
|
||||
-static struct i2c_board_info hdpvr_i2c_board_info = {
|
||||
- I2C_BOARD_INFO("ir_tx_z8f0811_hdpvr", Z8F0811_IR_TX_I2C_ADDR),
|
||||
- I2C_BOARD_INFO("ir_rx_z8f0811_hdpvr", Z8F0811_IR_RX_I2C_ADDR),
|
||||
-};
|
||||
+struct i2c_client *hdpvr_register_ir_tx_i2c(struct hdpvr_device *dev)
|
||||
+{
|
||||
+ struct IR_i2c_init_data *init_data = &dev->ir_i2c_init_data;
|
||||
+ struct i2c_board_info hdpvr_ir_tx_i2c_board_info = {
|
||||
+ I2C_BOARD_INFO("ir_tx_z8f0811_hdpvr", Z8F0811_IR_TX_I2C_ADDR),
|
||||
+ };
|
||||
+
|
||||
+ init_data->name = "HD-PVR";
|
||||
+ hdpvr_ir_tx_i2c_board_info.platform_data = init_data;
|
||||
|
||||
-int hdpvr_register_i2c_ir(struct hdpvr_device *dev)
|
||||
+ return i2c_new_device(&dev->i2c_adapter, &hdpvr_ir_tx_i2c_board_info);
|
||||
+}
|
||||
+
|
||||
+struct i2c_client *hdpvr_register_ir_rx_i2c(struct hdpvr_device *dev)
|
||||
{
|
||||
- struct i2c_client *c;
|
||||
struct IR_i2c_init_data *init_data = &dev->ir_i2c_init_data;
|
||||
+ struct i2c_board_info hdpvr_ir_rx_i2c_board_info = {
|
||||
+ I2C_BOARD_INFO("ir_rx_z8f0811_hdpvr", Z8F0811_IR_RX_I2C_ADDR),
|
||||
+ };
|
||||
|
||||
/* Our default information for ir-kbd-i2c.c to use */
|
||||
init_data->ir_codes = RC_MAP_HAUPPAUGE_NEW;
|
||||
init_data->internal_get_key_func = IR_KBD_GET_KEY_HAUP_XVR;
|
||||
init_data->type = RC_TYPE_RC5;
|
||||
- init_data->name = "HD PVR";
|
||||
- hdpvr_i2c_board_info.platform_data = init_data;
|
||||
-
|
||||
- c = i2c_new_device(&dev->i2c_adapter, &hdpvr_i2c_board_info);
|
||||
+ init_data->name = "HD-PVR";
|
||||
+ hdpvr_ir_rx_i2c_board_info.platform_data = init_data;
|
||||
|
||||
- return (c == NULL) ? -ENODEV : 0;
|
||||
+ return i2c_new_device(&dev->i2c_adapter, &hdpvr_ir_rx_i2c_board_info);
|
||||
}
|
||||
|
||||
static int hdpvr_i2c_read(struct hdpvr_device *dev, int bus,
|
||||
diff --git a/drivers/media/video/hdpvr/hdpvr.h b/drivers/media/video/hdpvr/hdpvr.h
|
||||
index ee74e3b..072f23c 100644
|
||||
--- a/drivers/media/video/hdpvr/hdpvr.h
|
||||
+++ b/drivers/media/video/hdpvr/hdpvr.h
|
||||
@@ -313,7 +313,8 @@ int hdpvr_cancel_queue(struct hdpvr_device *dev);
|
||||
/* i2c adapter registration */
|
||||
int hdpvr_register_i2c_adapter(struct hdpvr_device *dev);
|
||||
|
||||
-int hdpvr_register_i2c_ir(struct hdpvr_device *dev);
|
||||
+struct i2c_client *hdpvr_register_ir_rx_i2c(struct hdpvr_device *dev);
|
||||
+struct i2c_client *hdpvr_register_ir_tx_i2c(struct hdpvr_device *dev);
|
||||
|
||||
/*========================================================================*/
|
||||
/* buffer management */
|
||||
diff --git a/drivers/media/video/ir-kbd-i2c.c b/drivers/media/video/ir-kbd-i2c.c
|
||||
index d2b20ad..a221ad6 100644
|
||||
--- a/drivers/media/video/ir-kbd-i2c.c
|
||||
+++ b/drivers/media/video/ir-kbd-i2c.c
|
||||
@@ -128,6 +128,19 @@ static int get_key_haup(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
|
||||
|
||||
static int get_key_haup_xvr(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
|
||||
{
|
||||
+ int ret;
|
||||
+ unsigned char buf[1] = { 0 };
|
||||
+
|
||||
+ /*
|
||||
+ * This is the same apparent "are you ready?" poll command observed
|
||||
+ * watching Windows driver traffic and implemented in lirc_zilog. With
|
||||
+ * this added, we get far saner remote behavior with z8 chips on usb
|
||||
+ * connected devices, even with the default polling interval of 100ms.
|
||||
+ */
|
||||
+ ret = i2c_master_send(ir->c, buf, 1);
|
||||
+ if (ret != 1)
|
||||
+ return (ret < 0) ? ret : -EINVAL;
|
||||
+
|
||||
return get_key_haup_common (ir, ir_key, ir_raw, 6, 3);
|
||||
}
|
||||
|
||||
diff --git a/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c b/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c
|
||||
index ccc8849..451ecd4 100644
|
||||
--- a/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c
|
||||
+++ b/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c
|
||||
@@ -597,7 +597,6 @@ static void pvr2_i2c_register_ir(struct pvr2_hdw *hdw)
|
||||
init_data->internal_get_key_func = IR_KBD_GET_KEY_HAUP_XVR;
|
||||
init_data->type = RC_TYPE_RC5;
|
||||
init_data->name = hdw->hdw_desc->description;
|
||||
- init_data->polling_interval = 260; /* ms From lirc_zilog */
|
||||
/* IR Receiver */
|
||||
info.addr = 0x71;
|
||||
info.platform_data = init_data;
|
||||
diff --git a/drivers/staging/lirc/lirc_zilog.c b/drivers/staging/lirc/lirc_zilog.c
|
||||
index 3fe5f41..0aad0d7 100644
|
||||
--- a/drivers/staging/lirc/lirc_zilog.c
|
||||
+++ b/drivers/staging/lirc/lirc_zilog.c
|
||||
@@ -495,7 +495,7 @@ static int send_data_block(struct IR_tx *tx, unsigned char *data_block)
|
||||
/* send boot data to the IR TX device */
|
||||
static int send_boot_data(struct IR_tx *tx)
|
||||
{
|
||||
- int ret;
|
||||
+ int ret, i;
|
||||
unsigned char buf[4];
|
||||
|
||||
/* send the boot block */
|
||||
@@ -503,7 +503,7 @@ static int send_boot_data(struct IR_tx *tx)
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
- /* kick it off? */
|
||||
+ /* Hit the go button to activate the new boot data */
|
||||
buf[0] = 0x00;
|
||||
buf[1] = 0x20;
|
||||
ret = i2c_master_send(tx->c, buf, 2);
|
||||
@@ -511,7 +511,19 @@ static int send_boot_data(struct IR_tx *tx)
|
||||
zilog_error("i2c_master_send failed with %d\n", ret);
|
||||
return ret < 0 ? ret : -EFAULT;
|
||||
}
|
||||
- ret = i2c_master_send(tx->c, buf, 1);
|
||||
+
|
||||
+ /*
|
||||
+ * Wait for zilog to settle after hitting go post boot block upload.
|
||||
+ * Without this delay, the HD-PVR and HVR-1950 both return an -EIO
|
||||
+ * upon attempting to get firmware revision, and tx probe thus fails.
|
||||
+ */
|
||||
+ for (i = 0; i < 10; i++) {
|
||||
+ ret = i2c_master_send(tx->c, buf, 1);
|
||||
+ if (ret == 1)
|
||||
+ break;
|
||||
+ udelay(100);
|
||||
+ }
|
||||
+
|
||||
if (ret != 1) {
|
||||
zilog_error("i2c_master_send failed with %d\n", ret);
|
||||
return ret < 0 ? ret : -EFAULT;
|
||||
@@ -523,8 +535,8 @@ static int send_boot_data(struct IR_tx *tx)
|
||||
zilog_error("i2c_master_recv failed with %d\n", ret);
|
||||
return 0;
|
||||
}
|
||||
- if (buf[0] != 0x80) {
|
||||
- zilog_error("unexpected IR TX response: %02x\n", buf[0]);
|
||||
+ if ((buf[0] != 0x80) && (buf[0] != 0xa0)) {
|
||||
+ zilog_error("unexpected IR TX init response: %02x\n", buf[0]);
|
||||
return 0;
|
||||
}
|
||||
zilog_notify("Zilog/Hauppauge IR blaster firmware version "
|
||||
@@ -827,7 +839,15 @@ static int send_code(struct IR_tx *tx, unsigned int code, unsigned int key)
|
||||
zilog_error("i2c_master_send failed with %d\n", ret);
|
||||
return ret < 0 ? ret : -EFAULT;
|
||||
}
|
||||
- ret = i2c_master_send(tx->c, buf, 1);
|
||||
+
|
||||
+ /* Give the z8 a moment to process data block */
|
||||
+ for (i = 0; i < 10; i++) {
|
||||
+ ret = i2c_master_send(tx->c, buf, 1);
|
||||
+ if (ret == 1)
|
||||
+ break;
|
||||
+ udelay(100);
|
||||
+ }
|
||||
+
|
||||
if (ret != 1) {
|
||||
zilog_error("i2c_master_send failed with %d\n", ret);
|
||||
return ret < 0 ? ret : -EFAULT;
|
||||
diff --git a/drivers/media/rc/streamzap.c b/drivers/media/rc/streamzap.c
|
||||
index d9b6b48..e435d94 100644
|
||||
--- a/drivers/media/rc/streamzap.c
|
||||
+++ b/drivers/media/rc/streamzap.c
|
||||
@@ -273,6 +273,7 @@ static void streamzap_callback(struct urb *urb)
|
||||
if (sz->timeout_enabled)
|
||||
sz_push(sz, rawir);
|
||||
ir_raw_event_handle(sz->rdev);
|
||||
+ ir_raw_event_reset(sz->rdev);
|
||||
} else {
|
||||
sz_push_full_space(sz, sz->buf_in[i]);
|
||||
}
|
||||
@@ -290,6 +291,7 @@ static void streamzap_callback(struct urb *urb)
|
||||
}
|
||||
}
|
||||
|
||||
+ ir_raw_event_handle(sz->rdev);
|
||||
usb_submit_urb(urb, GFP_ATOMIC);
|
||||
|
||||
return;
|
|
@ -1,142 +0,0 @@
|
|||
drivers/media/IR/imon.c | 20 +-------------------
|
||||
drivers/media/IR/mceusb.c | 15 +--------------
|
||||
2 files changed, 2 insertions(+), 33 deletions(-)
|
||||
|
||||
diff --git a/drivers/media/IR/imon.c b/drivers/media/IR/imon.c
|
||||
index 65c125e..c185422 100644
|
||||
--- a/drivers/media/IR/imon.c
|
||||
+++ b/drivers/media/IR/imon.c
|
||||
@@ -87,7 +87,6 @@ static ssize_t lcd_write(struct file *file, const char *buf,
|
||||
struct imon_context {
|
||||
struct device *dev;
|
||||
struct ir_dev_props *props;
|
||||
- struct ir_input_dev *ir;
|
||||
/* Newer devices have two interfaces */
|
||||
struct usb_device *usbdev_intf0;
|
||||
struct usb_device *usbdev_intf1;
|
||||
@@ -1656,7 +1655,6 @@ static struct input_dev *imon_init_idev(struct imon_context *ictx)
|
||||
{
|
||||
struct input_dev *idev;
|
||||
struct ir_dev_props *props;
|
||||
- struct ir_input_dev *ir;
|
||||
int ret, i;
|
||||
|
||||
idev = input_allocate_device();
|
||||
@@ -1671,12 +1669,6 @@ static struct input_dev *imon_init_idev(struct imon_context *ictx)
|
||||
goto props_alloc_failed;
|
||||
}
|
||||
|
||||
- ir = kzalloc(sizeof(struct ir_input_dev), GFP_KERNEL);
|
||||
- if (!ir) {
|
||||
- dev_err(ictx->dev, "remote ir input dev allocation failed\n");
|
||||
- goto ir_dev_alloc_failed;
|
||||
- }
|
||||
-
|
||||
snprintf(ictx->name_idev, sizeof(ictx->name_idev),
|
||||
"iMON Remote (%04x:%04x)", ictx->vendor, ictx->product);
|
||||
idev->name = ictx->name_idev;
|
||||
@@ -1706,14 +1698,9 @@ static struct input_dev *imon_init_idev(struct imon_context *ictx)
|
||||
props->change_protocol = imon_ir_change_protocol;
|
||||
ictx->props = props;
|
||||
|
||||
- ictx->ir = ir;
|
||||
- memcpy(&ir->dev, ictx->dev, sizeof(struct device));
|
||||
-
|
||||
usb_to_input_id(ictx->usbdev_intf0, &idev->id);
|
||||
idev->dev.parent = ictx->dev;
|
||||
|
||||
- input_set_drvdata(idev, ir);
|
||||
-
|
||||
ret = ir_input_register(idev, RC_MAP_IMON_PAD, props, MOD_NAME);
|
||||
if (ret < 0) {
|
||||
dev_err(ictx->dev, "remote input dev register failed\n");
|
||||
@@ -1723,8 +1710,6 @@ static struct input_dev *imon_init_idev(struct imon_context *ictx)
|
||||
return idev;
|
||||
|
||||
idev_register_failed:
|
||||
- kfree(ir);
|
||||
-ir_dev_alloc_failed:
|
||||
kfree(props);
|
||||
props_alloc_failed:
|
||||
input_free_device(idev);
|
||||
@@ -1944,7 +1929,6 @@ static struct imon_context *imon_init_intf0(struct usb_interface *intf)
|
||||
|
||||
urb_submit_failed:
|
||||
ir_input_unregister(ictx->idev);
|
||||
- input_free_device(ictx->idev);
|
||||
idev_setup_failed:
|
||||
find_endpoint_failed:
|
||||
mutex_unlock(&ictx->lock);
|
||||
@@ -2014,10 +1998,8 @@ static struct imon_context *imon_init_intf1(struct usb_interface *intf,
|
||||
return ictx;
|
||||
|
||||
urb_submit_failed:
|
||||
- if (ictx->touch) {
|
||||
+ if (ictx->touch)
|
||||
input_unregister_device(ictx->touch);
|
||||
- input_free_device(ictx->touch);
|
||||
- }
|
||||
touch_setup_failed:
|
||||
find_endpoint_failed:
|
||||
mutex_unlock(&ictx->lock);
|
||||
diff --git a/drivers/media/IR/mceusb.c b/drivers/media/IR/mceusb.c
|
||||
index 78bf7f7..65b0738 100644
|
||||
--- a/drivers/media/IR/mceusb.c
|
||||
+++ b/drivers/media/IR/mceusb.c
|
||||
@@ -228,7 +228,6 @@ static struct usb_device_id std_tx_mask_list[] = {
|
||||
/* data structure for each usb transceiver */
|
||||
struct mceusb_dev {
|
||||
/* ir-core bits */
|
||||
- struct ir_input_dev *irdev;
|
||||
struct ir_dev_props *props;
|
||||
struct ir_raw_event rawir;
|
||||
|
||||
@@ -739,7 +738,7 @@ static void mceusb_dev_recv(struct urb *urb, struct pt_regs *regs)
|
||||
|
||||
if (ir->send_flags == RECV_FLAG_IN_PROGRESS) {
|
||||
ir->send_flags = SEND_FLAG_COMPLETE;
|
||||
- dev_dbg(&ir->irdev->dev, "setup answer received %d bytes\n",
|
||||
+ dev_dbg(ir->dev, "setup answer received %d bytes\n",
|
||||
buf_len);
|
||||
}
|
||||
|
||||
@@ -861,7 +860,6 @@ static struct input_dev *mceusb_init_input_dev(struct mceusb_dev *ir)
|
||||
{
|
||||
struct input_dev *idev;
|
||||
struct ir_dev_props *props;
|
||||
- struct ir_input_dev *irdev;
|
||||
struct device *dev = ir->dev;
|
||||
int ret = -ENODEV;
|
||||
|
||||
@@ -878,12 +876,6 @@ static struct input_dev *mceusb_init_input_dev(struct mceusb_dev *ir)
|
||||
goto props_alloc_failed;
|
||||
}
|
||||
|
||||
- irdev = kzalloc(sizeof(struct ir_input_dev), GFP_KERNEL);
|
||||
- if (!irdev) {
|
||||
- dev_err(dev, "remote ir input dev allocation failed\n");
|
||||
- goto ir_dev_alloc_failed;
|
||||
- }
|
||||
-
|
||||
snprintf(ir->name, sizeof(ir->name), "Media Center Ed. eHome "
|
||||
"Infrared Remote Transceiver (%04x:%04x)",
|
||||
le16_to_cpu(ir->usbdev->descriptor.idVendor),
|
||||
@@ -902,9 +894,6 @@ static struct input_dev *mceusb_init_input_dev(struct mceusb_dev *ir)
|
||||
props->tx_ir = mceusb_tx_ir;
|
||||
|
||||
ir->props = props;
|
||||
- ir->irdev = irdev;
|
||||
-
|
||||
- input_set_drvdata(idev, irdev);
|
||||
|
||||
ret = ir_input_register(idev, RC_MAP_RC6_MCE, props, DRIVER_NAME);
|
||||
if (ret < 0) {
|
||||
@@ -915,8 +904,6 @@ static struct input_dev *mceusb_init_input_dev(struct mceusb_dev *ir)
|
||||
return idev;
|
||||
|
||||
irdev_failed:
|
||||
- kfree(irdev);
|
||||
-ir_dev_alloc_failed:
|
||||
kfree(props);
|
||||
props_alloc_failed:
|
||||
input_free_device(idev);
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -1,362 +0,0 @@
|
|||
From: Martin Rubli <martin_rubli@logitech.com>
|
||||
Date: Wed, 19 May 2010 22:51:56 +0000 (+0200)
|
||||
Subject: uvcvideo: Add support for absolute pan/tilt controls
|
||||
X-Git-Url: http://git.linuxtv.org/pinchartl/uvcvideo.git?a=commitdiff_plain;h=d3c2f664ec76aff14c3841c99e84cd78d7227f79
|
||||
|
||||
uvcvideo: Add support for absolute pan/tilt controls
|
||||
|
||||
Signed-off-by: Martin Rubli <martin_rubli@logitech.com>
|
||||
---
|
||||
|
||||
diff --git a/drivers/media/video/uvc/uvc_ctrl.c b/drivers/media/video/uvc/uvc_ctrl.c
|
||||
index aa0720a..5ec2f4a 100644
|
||||
--- a/drivers/media/video/uvc/uvc_ctrl.c
|
||||
+++ b/drivers/media/video/uvc/uvc_ctrl.c
|
||||
@@ -606,6 +606,26 @@ static struct uvc_control_mapping uvc_ctrl_mappings[] = {
|
||||
.set = uvc_ctrl_set_zoom,
|
||||
},
|
||||
{
|
||||
+ .id = V4L2_CID_PAN_ABSOLUTE,
|
||||
+ .name = "Pan (Absolute)",
|
||||
+ .entity = UVC_GUID_UVC_CAMERA,
|
||||
+ .selector = UVC_CT_PANTILT_ABSOLUTE_CONTROL,
|
||||
+ .size = 32,
|
||||
+ .offset = 0,
|
||||
+ .v4l2_type = V4L2_CTRL_TYPE_INTEGER,
|
||||
+ .data_type = UVC_CTRL_DATA_TYPE_UNSIGNED,
|
||||
+ },
|
||||
+ {
|
||||
+ .id = V4L2_CID_TILT_ABSOLUTE,
|
||||
+ .name = "Tilt (Absolute)",
|
||||
+ .entity = UVC_GUID_UVC_CAMERA,
|
||||
+ .selector = UVC_CT_PANTILT_ABSOLUTE_CONTROL,
|
||||
+ .size = 32,
|
||||
+ .offset = 32,
|
||||
+ .v4l2_type = V4L2_CTRL_TYPE_INTEGER,
|
||||
+ .data_type = UVC_CTRL_DATA_TYPE_UNSIGNED,
|
||||
+ },
|
||||
+ {
|
||||
.id = V4L2_CID_PRIVACY,
|
||||
.name = "Privacy",
|
||||
.entity = UVC_GUID_UVC_CAMERA,
|
||||
From: Hans de Goede <hdegoede@redhat.com>
|
||||
Date: Wed, 19 May 2010 23:15:00 +0000 (+0200)
|
||||
Subject: uvcvideo: Make button controls work properly
|
||||
X-Git-Url: http://git.linuxtv.org/pinchartl/uvcvideo.git?a=commitdiff_plain;h=2bd47ad4894bfaf1a97660b821cbc46439a614d6
|
||||
|
||||
uvcvideo: Make button controls work properly
|
||||
|
||||
According to the v4l2 spec, writing any value to a button control should
|
||||
result in the action belonging to the button control being triggered.
|
||||
UVC cams however want to see a 1 written, this patch fixes this by
|
||||
overriding whatever value user space passed in with -1 (0xffffffff) when
|
||||
the control is a button control.
|
||||
|
||||
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
|
||||
---
|
||||
|
||||
diff --git a/drivers/media/video/uvc/uvc_ctrl.c b/drivers/media/video/uvc/uvc_ctrl.c
|
||||
index 5ec2f4a..8bb825d 100644
|
||||
--- a/drivers/media/video/uvc/uvc_ctrl.c
|
||||
+++ b/drivers/media/video/uvc/uvc_ctrl.c
|
||||
@@ -698,6 +698,14 @@ static void uvc_set_le_value(struct uvc_control_mapping *mapping,
|
||||
int offset = mapping->offset;
|
||||
__u8 mask;
|
||||
|
||||
+ /* According to the v4l2 spec, writing any value to a button control
|
||||
+ * should result in the action belonging to the button control being
|
||||
+ * triggered. UVC devices however want to see a 1 written -> override
|
||||
+ * value.
|
||||
+ */
|
||||
+ if (mapping->v4l2_type == V4L2_CTRL_TYPE_BUTTON)
|
||||
+ value = -1;
|
||||
+
|
||||
data += offset / 8;
|
||||
offset &= 7;
|
||||
|
||||
From: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
|
||||
Date: Thu, 18 Feb 2010 19:38:52 +0000 (+0100)
|
||||
Subject: uvcvideo: Support menu controls in the control mapping API
|
||||
X-Git-Url: http://git.linuxtv.org/pinchartl/uvcvideo.git?a=commitdiff_plain;h=4930f2662e47d33e5baedac620da401a225bc3a8
|
||||
|
||||
uvcvideo: Support menu controls in the control mapping API
|
||||
|
||||
The UVCIOC_CTRL_MAP ioctl doesn't support menu entries for menu
|
||||
controls. As the uvc_xu_control_mapping structure has no reserved
|
||||
fields, this can't be fixed while keeping ABI compatibility.
|
||||
|
||||
Modify the UVCIOC_CTRL_MAP ioctl to add menu entries support, and define
|
||||
UVCIOC_CTRL_MAP_OLD that supports the old ABI without any ability to add
|
||||
menu controls.
|
||||
|
||||
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
|
||||
---
|
||||
|
||||
diff --git a/drivers/media/video/uvc/uvc_ctrl.c b/drivers/media/video/uvc/uvc_ctrl.c
|
||||
index 8bb825d..c88d72e 100644
|
||||
--- a/drivers/media/video/uvc/uvc_ctrl.c
|
||||
+++ b/drivers/media/video/uvc/uvc_ctrl.c
|
||||
@@ -1606,6 +1606,28 @@ void uvc_ctrl_cleanup_device(struct uvc_device *dev)
|
||||
}
|
||||
}
|
||||
|
||||
+void uvc_ctrl_cleanup(void)
|
||||
+{
|
||||
+ struct uvc_control_info *info;
|
||||
+ struct uvc_control_info *ni;
|
||||
+ struct uvc_control_mapping *mapping;
|
||||
+ struct uvc_control_mapping *nm;
|
||||
+
|
||||
+ list_for_each_entry_safe(info, ni, &uvc_driver.controls, list) {
|
||||
+ if (!(info->flags & UVC_CONTROL_EXTENSION))
|
||||
+ continue;
|
||||
+
|
||||
+ list_for_each_entry_safe(mapping, nm, &info->mappings, list) {
|
||||
+ list_del(&mapping->list);
|
||||
+ kfree(mapping->menu_info);
|
||||
+ kfree(mapping);
|
||||
+ }
|
||||
+
|
||||
+ list_del(&info->list);
|
||||
+ kfree(info);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
void uvc_ctrl_init(void)
|
||||
{
|
||||
struct uvc_control_info *ctrl = uvc_ctrls;
|
||||
diff --git a/drivers/media/video/uvc/uvc_driver.c b/drivers/media/video/uvc/uvc_driver.c
|
||||
index 838b56f..34818c1 100644
|
||||
--- a/drivers/media/video/uvc/uvc_driver.c
|
||||
+++ b/drivers/media/video/uvc/uvc_driver.c
|
||||
@@ -2261,6 +2261,7 @@ static int __init uvc_init(void)
|
||||
static void __exit uvc_cleanup(void)
|
||||
{
|
||||
usb_deregister(&uvc_driver.driver);
|
||||
+ uvc_ctrl_cleanup();
|
||||
}
|
||||
|
||||
module_init(uvc_init);
|
||||
diff --git a/drivers/media/video/uvc/uvc_v4l2.c b/drivers/media/video/uvc/uvc_v4l2.c
|
||||
index 7c9ab29..485a899 100644
|
||||
--- a/drivers/media/video/uvc/uvc_v4l2.c
|
||||
+++ b/drivers/media/video/uvc/uvc_v4l2.c
|
||||
@@ -29,6 +29,71 @@
|
||||
#include "uvcvideo.h"
|
||||
|
||||
/* ------------------------------------------------------------------------
|
||||
+ * UVC ioctls
|
||||
+ */
|
||||
+static int uvc_ioctl_ctrl_map(struct uvc_xu_control_mapping *xmap, int old)
|
||||
+{
|
||||
+ struct uvc_control_mapping *map;
|
||||
+ unsigned int size;
|
||||
+ int ret;
|
||||
+
|
||||
+ map = kzalloc(sizeof *map, GFP_KERNEL);
|
||||
+ if (map == NULL)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ map->id = xmap->id;
|
||||
+ memcpy(map->name, xmap->name, sizeof map->name);
|
||||
+ memcpy(map->entity, xmap->entity, sizeof map->entity);
|
||||
+ map->selector = xmap->selector;
|
||||
+ map->size = xmap->size;
|
||||
+ map->offset = xmap->offset;
|
||||
+ map->v4l2_type = xmap->v4l2_type;
|
||||
+ map->data_type = xmap->data_type;
|
||||
+
|
||||
+ switch (xmap->v4l2_type) {
|
||||
+ case V4L2_CTRL_TYPE_INTEGER:
|
||||
+ case V4L2_CTRL_TYPE_BOOLEAN:
|
||||
+ case V4L2_CTRL_TYPE_BUTTON:
|
||||
+ break;
|
||||
+
|
||||
+ case V4L2_CTRL_TYPE_MENU:
|
||||
+ if (old) {
|
||||
+ ret = -EINVAL;
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ size = xmap->menu_count * sizeof(*map->menu_info);
|
||||
+ map->menu_info = kmalloc(size, GFP_KERNEL);
|
||||
+ if (map->menu_info == NULL) {
|
||||
+ ret = -ENOMEM;
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ if (copy_from_user(map->menu_info, xmap->menu_info, size)) {
|
||||
+ ret = -EFAULT;
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ map->menu_count = xmap->menu_count;
|
||||
+ break;
|
||||
+
|
||||
+ default:
|
||||
+ ret = -EINVAL;
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ ret = uvc_ctrl_add_mapping(map);
|
||||
+
|
||||
+done:
|
||||
+ if (ret < 0) {
|
||||
+ kfree(map->menu_info);
|
||||
+ kfree(map);
|
||||
+ }
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+/* ------------------------------------------------------------------------
|
||||
* V4L2 interface
|
||||
*/
|
||||
|
||||
@@ -974,7 +1039,8 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
|
||||
info->flags = xinfo->flags;
|
||||
|
||||
info->flags |= UVC_CONTROL_GET_MIN | UVC_CONTROL_GET_MAX |
|
||||
- UVC_CONTROL_GET_RES | UVC_CONTROL_GET_DEF;
|
||||
+ UVC_CONTROL_GET_RES | UVC_CONTROL_GET_DEF |
|
||||
+ UVC_CONTROL_EXTENSION;
|
||||
|
||||
ret = uvc_ctrl_add_info(info);
|
||||
if (ret < 0)
|
||||
@@ -982,32 +1048,12 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
|
||||
break;
|
||||
}
|
||||
|
||||
+ case UVCIOC_CTRL_MAP_OLD:
|
||||
case UVCIOC_CTRL_MAP:
|
||||
- {
|
||||
- struct uvc_xu_control_mapping *xmap = arg;
|
||||
- struct uvc_control_mapping *map;
|
||||
-
|
||||
if (!capable(CAP_SYS_ADMIN))
|
||||
return -EPERM;
|
||||
|
||||
- map = kzalloc(sizeof *map, GFP_KERNEL);
|
||||
- if (map == NULL)
|
||||
- return -ENOMEM;
|
||||
-
|
||||
- map->id = xmap->id;
|
||||
- memcpy(map->name, xmap->name, sizeof map->name);
|
||||
- memcpy(map->entity, xmap->entity, sizeof map->entity);
|
||||
- map->selector = xmap->selector;
|
||||
- map->size = xmap->size;
|
||||
- map->offset = xmap->offset;
|
||||
- map->v4l2_type = xmap->v4l2_type;
|
||||
- map->data_type = xmap->data_type;
|
||||
-
|
||||
- ret = uvc_ctrl_add_mapping(map);
|
||||
- if (ret < 0)
|
||||
- kfree(map);
|
||||
- break;
|
||||
- }
|
||||
+ return uvc_ioctl_ctrl_map(arg, cmd == UVCIOC_CTRL_MAP_OLD);
|
||||
|
||||
case UVCIOC_CTRL_GET:
|
||||
return uvc_xu_ctrl_query(chain, arg, 0);
|
||||
diff --git a/drivers/media/video/uvc/uvcvideo.h b/drivers/media/video/uvc/uvcvideo.h
|
||||
index d1f8840..14f77e4 100644
|
||||
--- a/drivers/media/video/uvc/uvcvideo.h
|
||||
+++ b/drivers/media/video/uvc/uvcvideo.h
|
||||
@@ -27,6 +27,8 @@
|
||||
#define UVC_CONTROL_RESTORE (1 << 6)
|
||||
/* Control can be updated by the camera. */
|
||||
#define UVC_CONTROL_AUTO_UPDATE (1 << 7)
|
||||
+/* Control is an extension unit control. */
|
||||
+#define UVC_CONTROL_EXTENSION (1 << 8)
|
||||
|
||||
#define UVC_CONTROL_GET_RANGE (UVC_CONTROL_GET_CUR | UVC_CONTROL_GET_MIN | \
|
||||
UVC_CONTROL_GET_MAX | UVC_CONTROL_GET_RES | \
|
||||
@@ -40,6 +42,15 @@ struct uvc_xu_control_info {
|
||||
__u32 flags;
|
||||
};
|
||||
|
||||
+struct uvc_menu_info {
|
||||
+ __u32 value;
|
||||
+ __u8 name[32];
|
||||
+};
|
||||
+
|
||||
+struct uvc_xu_control_mapping_old {
|
||||
+ __u8 reserved[64];
|
||||
+};
|
||||
+
|
||||
struct uvc_xu_control_mapping {
|
||||
__u32 id;
|
||||
__u8 name[32];
|
||||
@@ -50,6 +61,11 @@ struct uvc_xu_control_mapping {
|
||||
__u8 offset;
|
||||
enum v4l2_ctrl_type v4l2_type;
|
||||
__u32 data_type;
|
||||
+
|
||||
+ struct uvc_menu_info __user *menu_info;
|
||||
+ __u32 menu_count;
|
||||
+
|
||||
+ __u32 reserved[4];
|
||||
};
|
||||
|
||||
struct uvc_xu_control {
|
||||
@@ -60,6 +76,7 @@ struct uvc_xu_control {
|
||||
};
|
||||
|
||||
#define UVCIOC_CTRL_ADD _IOW('U', 1, struct uvc_xu_control_info)
|
||||
+#define UVCIOC_CTRL_MAP_OLD _IOWR('U', 2, struct uvc_xu_control_mapping_old)
|
||||
#define UVCIOC_CTRL_MAP _IOWR('U', 2, struct uvc_xu_control_mapping)
|
||||
#define UVCIOC_CTRL_GET _IOWR('U', 3, struct uvc_xu_control)
|
||||
#define UVCIOC_CTRL_SET _IOW('U', 4, struct uvc_xu_control)
|
||||
@@ -198,11 +215,6 @@ struct uvc_streaming_control {
|
||||
__u8 bMaxVersion;
|
||||
};
|
||||
|
||||
-struct uvc_menu_info {
|
||||
- __u32 value;
|
||||
- __u8 name[32];
|
||||
-};
|
||||
-
|
||||
struct uvc_control_info {
|
||||
struct list_head list;
|
||||
struct list_head mappings;
|
||||
@@ -625,6 +637,7 @@ extern int uvc_ctrl_init_device(struct uvc_device *dev);
|
||||
extern void uvc_ctrl_cleanup_device(struct uvc_device *dev);
|
||||
extern int uvc_ctrl_resume_device(struct uvc_device *dev);
|
||||
extern void uvc_ctrl_init(void);
|
||||
+extern void uvc_ctrl_cleanup(void);
|
||||
|
||||
extern int uvc_ctrl_begin(struct uvc_video_chain *chain);
|
||||
extern int __uvc_ctrl_commit(struct uvc_video_chain *chain, int rollback);
|
||||
From: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
|
||||
Date: Fri, 25 Jun 2010 07:58:43 +0000 (+0200)
|
||||
Subject: uvcvideo: Add support for Manta MM-353 Plako
|
||||
X-Git-Url: http://git.linuxtv.org/pinchartl/uvcvideo.git?a=commitdiff_plain;h=352e661e1f347390a86cf34bc5e41adbdd1caa41
|
||||
|
||||
uvcvideo: Add support for Manta MM-353 Plako
|
||||
|
||||
The camera requires the PROBE_MINMAX quirk. Add a corresponding entry
|
||||
in the device IDs list
|
||||
|
||||
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
|
||||
---
|
||||
|
||||
diff --git a/drivers/media/video/uvc/uvc_driver.c b/drivers/media/video/uvc/uvc_driver.c
|
||||
index 34818c1..1a89384 100644
|
||||
--- a/drivers/media/video/uvc/uvc_driver.c
|
||||
+++ b/drivers/media/video/uvc/uvc_driver.c
|
||||
@@ -2174,6 +2174,15 @@ static struct usb_device_id uvc_ids[] = {
|
||||
.bInterfaceSubClass = 1,
|
||||
.bInterfaceProtocol = 0,
|
||||
.driver_info = UVC_QUIRK_PROBE_EXTRAFIELDS },
|
||||
+ /* Manta MM-353 Plako */
|
||||
+ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
|
||||
+ | USB_DEVICE_ID_MATCH_INT_INFO,
|
||||
+ .idVendor = 0x18ec,
|
||||
+ .idProduct = 0x3188,
|
||||
+ .bInterfaceClass = USB_CLASS_VIDEO,
|
||||
+ .bInterfaceSubClass = 1,
|
||||
+ .bInterfaceProtocol = 0,
|
||||
+ .driver_info = UVC_QUIRK_PROBE_MINMAX },
|
||||
/* FSC WebCam V30S */
|
||||
{ .match_flags = USB_DEVICE_ID_MATCH_DEVICE
|
||||
| USB_DEVICE_ID_MATCH_INT_INFO,
|
|
@ -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)
|
|
@ -0,0 +1,196 @@
|
|||
mm: add vzalloc() and vzalloc_node() helpers
|
||||
|
||||
Drop-in helper function backport from upstream.
|
||||
|
||||
Upstream commits:
|
||||
commit e1ca7788dec6773b1a2bce51b7141948f2b8bccf
|
||||
Author: Dave Young <hidave.darkstar@gmail.com>
|
||||
Date: Tue Oct 26 14:22:06 2010 -0700
|
||||
|
||||
mm: add vzalloc() and vzalloc_node() helpers
|
||||
|
||||
Add vzalloc() and vzalloc_node() to encapsulate the
|
||||
vmalloc-then-memset-zero operation.
|
||||
|
||||
Use __GFP_ZERO to zero fill the allocated memory.
|
||||
|
||||
Signed-off-by: Dave Young <hidave.darkstar@gmail.com>
|
||||
Cc: Christoph Lameter <cl@linux-foundation.org>
|
||||
Acked-by: Greg Ungerer <gerg@snapgear.com>
|
||||
Cc: David Howells <dhowells@redhat.com>
|
||||
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
||||
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
|
||||
|
||||
commit 9a14f653dfe349c0916e6a78c413effa2fa3f001
|
||||
Author: Paul Mundt <lethal@linux-sh.org>
|
||||
Date: Fri Dec 24 11:50:34 2010 +0900
|
||||
|
||||
nommu: Fix up vmalloc_node() symbol export regression.
|
||||
|
||||
Commit e1ca778 ("mm: add vzalloc() and vzalloc_node() helpers") ended up
|
||||
accidentally deleting the vmalloc_node() symbol export, resulting in:
|
||||
|
||||
"vmalloc_node" [net/core/pktgen.ko] undefined!
|
||||
"vmalloc_node" [net/netfilter/x_tables.ko] undefined!
|
||||
|
||||
regressions.
|
||||
|
||||
Signed-off-by: Paul Mundt <lethal@linux-sh.org>
|
||||
|
||||
Signed-off-by: Jarod Wilson <jarod@redhat.com>
|
||||
|
||||
diff --git a/include/linux/vmalloc.h b/include/linux/vmalloc.h
|
||||
index d9a787a..5e03b00 100644
|
||||
--- a/include/linux/vmalloc.h
|
||||
+++ b/include/linux/vmalloc.h
|
||||
@@ -51,8 +51,10 @@ static inline void vmalloc_init(void)
|
||||
#endif
|
||||
|
||||
extern void *vmalloc(unsigned long size);
|
||||
+extern void *vzalloc(unsigned long size);
|
||||
extern void *vmalloc_user(unsigned long size);
|
||||
extern void *vmalloc_node(unsigned long size, int node);
|
||||
+extern void *vzalloc_node(unsigned long size, int node);
|
||||
extern void *vmalloc_exec(unsigned long size);
|
||||
extern void *vmalloc_32(unsigned long size);
|
||||
extern void *vmalloc_32_user(unsigned long size);
|
||||
diff --git a/mm/nommu.c b/mm/nommu.c
|
||||
index b30fde0..bdb4d22 100644
|
||||
--- a/mm/nommu.c
|
||||
+++ b/mm/nommu.c
|
||||
@@ -298,12 +298,60 @@ void *vmalloc(unsigned long size)
|
||||
}
|
||||
EXPORT_SYMBOL(vmalloc);
|
||||
|
||||
+/*
|
||||
+ * vzalloc - allocate virtually continguos memory with zero fill
|
||||
+ *
|
||||
+ * @size: allocation size
|
||||
+ *
|
||||
+ * Allocate enough pages to cover @size from the page level
|
||||
+ * allocator and map them into continguos kernel virtual space.
|
||||
+ * The memory allocated is set to zero.
|
||||
+ *
|
||||
+ * For tight control over page level allocator and protection flags
|
||||
+ * use __vmalloc() instead.
|
||||
+ */
|
||||
+void *vzalloc(unsigned long size)
|
||||
+{
|
||||
+ return __vmalloc(size, GFP_KERNEL | __GFP_HIGHMEM | __GFP_ZERO,
|
||||
+ PAGE_KERNEL);
|
||||
+}
|
||||
+EXPORT_SYMBOL(vzalloc);
|
||||
+
|
||||
+/**
|
||||
+ * vmalloc_node - allocate memory on a specific node
|
||||
+ * @size: allocation size
|
||||
+ * @node: numa node
|
||||
+ *
|
||||
+ * Allocate enough pages to cover @size from the page level
|
||||
+ * allocator and map them into contiguous kernel virtual space.
|
||||
+ *
|
||||
+ * For tight control over page level allocator and protection flags
|
||||
+ * use __vmalloc() instead.
|
||||
+ */
|
||||
void *vmalloc_node(unsigned long size, int node)
|
||||
{
|
||||
return vmalloc(size);
|
||||
}
|
||||
EXPORT_SYMBOL(vmalloc_node);
|
||||
|
||||
+/**
|
||||
+ * vzalloc_node - allocate memory on a specific node with zero fill
|
||||
+ * @size: allocation size
|
||||
+ * @node: numa node
|
||||
+ *
|
||||
+ * Allocate enough pages to cover @size from the page level
|
||||
+ * allocator and map them into contiguous kernel virtual space.
|
||||
+ * The memory allocated is set to zero.
|
||||
+ *
|
||||
+ * For tight control over page level allocator and protection flags
|
||||
+ * use __vmalloc() instead.
|
||||
+ */
|
||||
+void *vzalloc_node(unsigned long size, int node)
|
||||
+{
|
||||
+ return vzalloc(size);
|
||||
+}
|
||||
+EXPORT_SYMBOL(vzalloc_node);
|
||||
+
|
||||
#ifndef PAGE_KERNEL_EXEC
|
||||
# define PAGE_KERNEL_EXEC PAGE_KERNEL
|
||||
#endif
|
||||
diff --git a/mm/vmalloc.c b/mm/vmalloc.c
|
||||
index 12568fa..2e2e7a3 100644
|
||||
--- a/mm/vmalloc.c
|
||||
+++ b/mm/vmalloc.c
|
||||
@@ -1583,6 +1583,13 @@ void *__vmalloc(unsigned long size, gfp_t gfp_mask, pgprot_t prot)
|
||||
}
|
||||
EXPORT_SYMBOL(__vmalloc);
|
||||
|
||||
+static inline void *__vmalloc_node_flags(unsigned long size,
|
||||
+ int node, gfp_t flags)
|
||||
+{
|
||||
+ return __vmalloc_node(size, 1, flags, PAGE_KERNEL,
|
||||
+ node, __builtin_return_address(0));
|
||||
+}
|
||||
+
|
||||
/**
|
||||
* vmalloc - allocate virtually contiguous memory
|
||||
* @size: allocation size
|
||||
@@ -1594,12 +1601,28 @@ EXPORT_SYMBOL(__vmalloc);
|
||||
*/
|
||||
void *vmalloc(unsigned long size)
|
||||
{
|
||||
- return __vmalloc_node(size, 1, GFP_KERNEL | __GFP_HIGHMEM, PAGE_KERNEL,
|
||||
- -1, __builtin_return_address(0));
|
||||
+ return __vmalloc_node_flags(size, -1, GFP_KERNEL | __GFP_HIGHMEM);
|
||||
}
|
||||
EXPORT_SYMBOL(vmalloc);
|
||||
|
||||
/**
|
||||
+ * vzalloc - allocate virtually contiguous memory with zero fill
|
||||
+ * @size: allocation size
|
||||
+ * Allocate enough pages to cover @size from the page level
|
||||
+ * allocator and map them into contiguous kernel virtual space.
|
||||
+ * The memory allocated is set to zero.
|
||||
+ *
|
||||
+ * For tight control over page level allocator and protection flags
|
||||
+ * use __vmalloc() instead.
|
||||
+ */
|
||||
+void *vzalloc(unsigned long size)
|
||||
+{
|
||||
+ return __vmalloc_node_flags(size, -1,
|
||||
+ GFP_KERNEL | __GFP_HIGHMEM | __GFP_ZERO);
|
||||
+}
|
||||
+EXPORT_SYMBOL(vzalloc);
|
||||
+
|
||||
+/**
|
||||
* vmalloc_user - allocate zeroed virtually contiguous memory for userspace
|
||||
* @size: allocation size
|
||||
*
|
||||
@@ -1640,6 +1663,25 @@ void *vmalloc_node(unsigned long size, int node)
|
||||
}
|
||||
EXPORT_SYMBOL(vmalloc_node);
|
||||
|
||||
+/**
|
||||
+ * vzalloc_node - allocate memory on a specific node with zero fill
|
||||
+ * @size: allocation size
|
||||
+ * @node: numa node
|
||||
+ *
|
||||
+ * Allocate enough pages to cover @size from the page level
|
||||
+ * allocator and map them into contiguous kernel virtual space.
|
||||
+ * The memory allocated is set to zero.
|
||||
+ *
|
||||
+ * For tight control over page level allocator and protection flags
|
||||
+ * use __vmalloc_node() instead.
|
||||
+ */
|
||||
+void *vzalloc_node(unsigned long size, int node)
|
||||
+{
|
||||
+ return __vmalloc_node_flags(size, node,
|
||||
+ GFP_KERNEL | __GFP_HIGHMEM | __GFP_ZERO);
|
||||
+}
|
||||
+EXPORT_SYMBOL(vzalloc_node);
|
||||
+
|
||||
#ifndef PAGE_KERNEL_EXEC
|
||||
# define PAGE_KERNEL_EXEC PAGE_KERNEL
|
||||
#endif
|
|
@ -0,0 +1,11 @@
|
|||
diff -up linux-2.6.34.noarch/arch/x86/Makefile.orig linux-2.6.34.noarch/arch/x86/Makefile
|
||||
--- linux-2.6.34.noarch/arch/x86/Makefile.orig 2010-07-01 13:33:21.859627499 -0400
|
||||
+++ linux-2.6.34.noarch/arch/x86/Makefile 2010-07-01 13:36:26.751576450 -0400
|
||||
@@ -81,6 +81,7 @@ ifdef CONFIG_CC_STACKPROTECTOR
|
||||
$(warning stack protector enabled but no compiler support)
|
||||
endif
|
||||
endif
|
||||
+KBUILD_CFLAGS += -fno-inline-functions-called-once
|
||||
|
||||
# Don't unroll struct assignments with kmemcheck enabled
|
||||
ifeq ($(CONFIG_KMEMCHECK),y)
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,35 @@
|
|||
Problem is 2.6.35 specific, bug was introduced in backport
|
||||
of upstream 44271488b91c9eecf249e075a1805dd887e222d2 commit.
|
||||
|
||||
We can not call del_timer_sync(addba_resp_timer) from
|
||||
___ieee80211_stop_tx_ba_session(), as this function can be called from
|
||||
that timer callback. To fix, simply use not synchronous del_timer().
|
||||
|
||||
Resolve https://bugzilla.redhat.com/show_bug.cgi?id=667459
|
||||
|
||||
Reported-and-tested-by: Mathieu Chouquet-Stringer <mathieu-acct@csetco.com>
|
||||
Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
|
||||
---
|
||||
net/mac80211/agg-tx.c | 2 +-
|
||||
1 files changed, 1 insertions(+), 1 deletions(-)
|
||||
|
||||
diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c
|
||||
index f935490..72ab63d 100644
|
||||
--- a/net/mac80211/agg-tx.c
|
||||
+++ b/net/mac80211/agg-tx.c
|
||||
@@ -138,7 +138,7 @@ int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid,
|
||||
sta->sta.addr, tid);
|
||||
#endif /* CONFIG_MAC80211_HT_DEBUG */
|
||||
|
||||
- del_timer_sync(&tid_tx->addba_resp_timer);
|
||||
+ del_timer(&tid_tx->addba_resp_timer);
|
||||
|
||||
state = &sta->ampdu_mlme.tid_state_tx[tid];
|
||||
|
||||
--
|
||||
1.7.3.4
|
||||
|
||||
_______________________________________________
|
||||
kernel mailing list
|
||||
kernel@lists.fedoraproject.org
|
||||
https://admin.fedoraproject.org/mailman/listinfo/kernel
|
|
@ -0,0 +1,390 @@
|
|||
From 9ced9810f0450a7f05eccb40dce4f9e4616c0fb6 Mon Sep 17 00:00:00 2001
|
||||
From: Mel Gorman <mel@csn.ul.ie>
|
||||
Date: Wed, 24 Nov 2010 22:18:23 -0500
|
||||
Subject: [PATCH 1/2] mm: page allocator: Adjust the per-cpu counter threshold when memory is low
|
||||
|
||||
Commit aa45484 ("calculate a better estimate of NR_FREE_PAGES when memory
|
||||
is low") noted that watermarks were based on the vmstat NR_FREE_PAGES. To
|
||||
avoid synchronization overhead, these counters are maintained on a per-cpu
|
||||
basis and drained both periodically and when a threshold is above a
|
||||
threshold. On large CPU systems, the difference between the estimate and
|
||||
real value of NR_FREE_PAGES can be very high. The system can get into a
|
||||
case where pages are allocated far below the min watermark potentially
|
||||
causing livelock issues. The commit solved the problem by taking a better
|
||||
reading of NR_FREE_PAGES when memory was low.
|
||||
|
||||
Unfortately, as reported by Shaohua Li this accurate reading can consume a
|
||||
large amount of CPU time on systems with many sockets due to cache line
|
||||
bouncing. This patch takes a different approach. For large machines
|
||||
where counter drift might be unsafe and while kswapd is awake, the per-cpu
|
||||
thresholds for the target pgdat are reduced to limit the level of drift to
|
||||
what should be a safe level. This incurs a performance penalty in heavy
|
||||
memory pressure by a factor that depends on the workload and the machine
|
||||
but the machine should function correctly without accidentally exhausting
|
||||
all memory on a node. There is an additional cost when kswapd wakes and
|
||||
sleeps but the event is not expected to be frequent - in Shaohua's test
|
||||
case, there was one recorded sleep and wake event at least.
|
||||
|
||||
To ensure that kswapd wakes up, a safe version of zone_watermark_ok() is
|
||||
introduced that takes a more accurate reading of NR_FREE_PAGES when called
|
||||
from wakeup_kswapd, when deciding whether it is really safe to go back to
|
||||
sleep in sleeping_prematurely() and when deciding if a zone is really
|
||||
balanced or not in balance_pgdat(). We are still using an expensive
|
||||
function but limiting how often it is called.
|
||||
|
||||
When the test case is reproduced, the time spent in the watermark
|
||||
functions is reduced. The following report is on the percentage of time
|
||||
spent cumulatively spent in the functions zone_nr_free_pages(),
|
||||
zone_watermark_ok(), __zone_watermark_ok(), zone_watermark_ok_safe(),
|
||||
zone_page_state_snapshot(), zone_page_state().
|
||||
|
||||
vanilla 11.6615%
|
||||
disable-threshold 0.2584%
|
||||
|
||||
Reported-by: Shaohua Li <shaohua.li@intel.com>
|
||||
Signed-off-by: Mel Gorman <mel@csn.ul.ie>
|
||||
Reviewed-by: Christoph Lameter <cl@linux.com>
|
||||
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
||||
---
|
||||
include/linux/mmzone.h | 10 ++-----
|
||||
include/linux/vmstat.h | 5 +++
|
||||
mm/mmzone.c | 21 ---------------
|
||||
mm/page_alloc.c | 35 +++++++++++++++++++-----
|
||||
mm/vmscan.c | 26 ++++++++++--------
|
||||
mm/vmstat.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++-
|
||||
6 files changed, 117 insertions(+), 48 deletions(-)
|
||||
|
||||
diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h
|
||||
index 8b2db3d..1e3d0b4 100644
|
||||
--- a/include/linux/mmzone.h
|
||||
+++ b/include/linux/mmzone.h
|
||||
@@ -463,12 +463,6 @@ static inline int zone_is_oom_locked(const struct zone *zone)
|
||||
return test_bit(ZONE_OOM_LOCKED, &zone->flags);
|
||||
}
|
||||
|
||||
-#ifdef CONFIG_SMP
|
||||
-unsigned long zone_nr_free_pages(struct zone *zone);
|
||||
-#else
|
||||
-#define zone_nr_free_pages(zone) zone_page_state(zone, NR_FREE_PAGES)
|
||||
-#endif /* CONFIG_SMP */
|
||||
-
|
||||
/*
|
||||
* The "priority" of VM scanning is how much of the queues we will scan in one
|
||||
* go. A value of 12 for DEF_PRIORITY implies that we will scan 1/4096th of the
|
||||
@@ -668,7 +662,9 @@ void get_zone_counts(unsigned long *active, unsigned long *inactive,
|
||||
unsigned long *free);
|
||||
void build_all_zonelists(void *data);
|
||||
void wakeup_kswapd(struct zone *zone, int order);
|
||||
-int zone_watermark_ok(struct zone *z, int order, unsigned long mark,
|
||||
+bool zone_watermark_ok(struct zone *z, int order, unsigned long mark,
|
||||
+ int classzone_idx, int alloc_flags);
|
||||
+bool zone_watermark_ok_safe(struct zone *z, int order, unsigned long mark,
|
||||
int classzone_idx, int alloc_flags);
|
||||
enum memmap_context {
|
||||
MEMMAP_EARLY,
|
||||
diff --git a/include/linux/vmstat.h b/include/linux/vmstat.h
|
||||
index eaaea37..e4cc21c 100644
|
||||
--- a/include/linux/vmstat.h
|
||||
+++ b/include/linux/vmstat.h
|
||||
@@ -254,6 +254,8 @@ extern void dec_zone_state(struct zone *, enum zone_stat_item);
|
||||
extern void __dec_zone_state(struct zone *, enum zone_stat_item);
|
||||
|
||||
void refresh_cpu_vm_stats(int);
|
||||
+void reduce_pgdat_percpu_threshold(pg_data_t *pgdat);
|
||||
+void restore_pgdat_percpu_threshold(pg_data_t *pgdat);
|
||||
#else /* CONFIG_SMP */
|
||||
|
||||
/*
|
||||
@@ -298,6 +300,9 @@ static inline void __dec_zone_page_state(struct page *page,
|
||||
#define dec_zone_page_state __dec_zone_page_state
|
||||
#define mod_zone_page_state __mod_zone_page_state
|
||||
|
||||
+static inline void reduce_pgdat_percpu_threshold(pg_data_t *pgdat) { }
|
||||
+static inline void restore_pgdat_percpu_threshold(pg_data_t *pgdat) { }
|
||||
+
|
||||
static inline void refresh_cpu_vm_stats(int cpu) { }
|
||||
#endif
|
||||
|
||||
diff --git a/mm/mmzone.c b/mm/mmzone.c
|
||||
index e35bfb8..f5b7d17 100644
|
||||
--- a/mm/mmzone.c
|
||||
+++ b/mm/mmzone.c
|
||||
@@ -87,24 +87,3 @@ int memmap_valid_within(unsigned long pfn,
|
||||
return 1;
|
||||
}
|
||||
#endif /* CONFIG_ARCH_HAS_HOLES_MEMORYMODEL */
|
||||
-
|
||||
-#ifdef CONFIG_SMP
|
||||
-/* Called when a more accurate view of NR_FREE_PAGES is needed */
|
||||
-unsigned long zone_nr_free_pages(struct zone *zone)
|
||||
-{
|
||||
- unsigned long nr_free_pages = zone_page_state(zone, NR_FREE_PAGES);
|
||||
-
|
||||
- /*
|
||||
- * While kswapd is awake, it is considered the zone is under some
|
||||
- * memory pressure. Under pressure, there is a risk that
|
||||
- * per-cpu-counter-drift will allow the min watermark to be breached
|
||||
- * potentially causing a live-lock. While kswapd is awake and
|
||||
- * free pages are low, get a better estimate for free pages
|
||||
- */
|
||||
- if (nr_free_pages < zone->percpu_drift_mark &&
|
||||
- !waitqueue_active(&zone->zone_pgdat->kswapd_wait))
|
||||
- return zone_page_state_snapshot(zone, NR_FREE_PAGES);
|
||||
-
|
||||
- return nr_free_pages;
|
||||
-}
|
||||
-#endif /* CONFIG_SMP */
|
||||
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
|
||||
index f7cc624..cf5d4c0 100644
|
||||
--- a/mm/page_alloc.c
|
||||
+++ b/mm/page_alloc.c
|
||||
@@ -1454,24 +1454,24 @@ static inline int should_fail_alloc_page(gfp_t gfp_mask, unsigned int order)
|
||||
#endif /* CONFIG_FAIL_PAGE_ALLOC */
|
||||
|
||||
/*
|
||||
- * Return 1 if free pages are above 'mark'. This takes into account the order
|
||||
+ * Return true if free pages are above 'mark'. This takes into account the order
|
||||
* of the allocation.
|
||||
*/
|
||||
-int zone_watermark_ok(struct zone *z, int order, unsigned long mark,
|
||||
- int classzone_idx, int alloc_flags)
|
||||
+static bool __zone_watermark_ok(struct zone *z, int order, unsigned long mark,
|
||||
+ int classzone_idx, int alloc_flags, long free_pages)
|
||||
{
|
||||
/* free_pages my go negative - that's OK */
|
||||
long min = mark;
|
||||
- long free_pages = zone_nr_free_pages(z) - (1 << order) + 1;
|
||||
int o;
|
||||
|
||||
+ free_pages -= (1 << order) + 1;
|
||||
if (alloc_flags & ALLOC_HIGH)
|
||||
min -= min / 2;
|
||||
if (alloc_flags & ALLOC_HARDER)
|
||||
min -= min / 4;
|
||||
|
||||
if (free_pages <= min + z->lowmem_reserve[classzone_idx])
|
||||
- return 0;
|
||||
+ return false;
|
||||
for (o = 0; o < order; o++) {
|
||||
/* At the next order, this order's pages become unavailable */
|
||||
free_pages -= z->free_area[o].nr_free << o;
|
||||
@@ -1480,9 +1480,28 @@ int zone_watermark_ok(struct zone *z, int order, unsigned long mark,
|
||||
min >>= 1;
|
||||
|
||||
if (free_pages <= min)
|
||||
- return 0;
|
||||
+ return false;
|
||||
}
|
||||
- return 1;
|
||||
+ return true;
|
||||
+}
|
||||
+
|
||||
+bool zone_watermark_ok(struct zone *z, int order, unsigned long mark,
|
||||
+ int classzone_idx, int alloc_flags)
|
||||
+{
|
||||
+ return __zone_watermark_ok(z, order, mark, classzone_idx, alloc_flags,
|
||||
+ zone_page_state(z, NR_FREE_PAGES));
|
||||
+}
|
||||
+
|
||||
+bool zone_watermark_ok_safe(struct zone *z, int order, unsigned long mark,
|
||||
+ int classzone_idx, int alloc_flags)
|
||||
+{
|
||||
+ long free_pages = zone_page_state(z, NR_FREE_PAGES);
|
||||
+
|
||||
+ if (z->percpu_drift_mark && free_pages < z->percpu_drift_mark)
|
||||
+ free_pages = zone_page_state_snapshot(z, NR_FREE_PAGES);
|
||||
+
|
||||
+ return __zone_watermark_ok(z, order, mark, classzone_idx, alloc_flags,
|
||||
+ free_pages);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_NUMA
|
||||
@@ -2425,7 +2444,7 @@ void show_free_areas(void)
|
||||
" all_unreclaimable? %s"
|
||||
"\n",
|
||||
zone->name,
|
||||
- K(zone_nr_free_pages(zone)),
|
||||
+ K(zone_page_state(zone, NR_FREE_PAGES)),
|
||||
K(min_wmark_pages(zone)),
|
||||
K(low_wmark_pages(zone)),
|
||||
K(high_wmark_pages(zone)),
|
||||
diff --git a/mm/vmscan.c b/mm/vmscan.c
|
||||
index 9753626..18f4038 100644
|
||||
--- a/mm/vmscan.c
|
||||
+++ b/mm/vmscan.c
|
||||
@@ -2007,7 +2007,7 @@ static int sleeping_prematurely(pg_data_t *pgdat, int order, long remaining)
|
||||
if (zone->all_unreclaimable)
|
||||
continue;
|
||||
|
||||
- if (!zone_watermark_ok(zone, order, high_wmark_pages(zone),
|
||||
+ if (!zone_watermark_ok_safe(zone, order, high_wmark_pages(zone),
|
||||
0, 0))
|
||||
return 1;
|
||||
}
|
||||
@@ -2104,7 +2104,7 @@ loop_again:
|
||||
shrink_active_list(SWAP_CLUSTER_MAX, zone,
|
||||
&sc, priority, 0);
|
||||
|
||||
- if (!zone_watermark_ok(zone, order,
|
||||
+ if (!zone_watermark_ok_safe(zone, order,
|
||||
high_wmark_pages(zone), 0, 0)) {
|
||||
end_zone = i;
|
||||
break;
|
||||
@@ -2155,7 +2155,7 @@ loop_again:
|
||||
* We put equal pressure on every zone, unless one
|
||||
* zone has way too many pages free already.
|
||||
*/
|
||||
- if (!zone_watermark_ok(zone, order,
|
||||
+ if (!zone_watermark_ok_safe(zone, order,
|
||||
8*high_wmark_pages(zone), end_zone, 0))
|
||||
shrink_zone(priority, zone, &sc);
|
||||
reclaim_state->reclaimed_slab = 0;
|
||||
@@ -2176,7 +2176,7 @@ loop_again:
|
||||
total_scanned > sc.nr_reclaimed + sc.nr_reclaimed / 2)
|
||||
sc.may_writepage = 1;
|
||||
|
||||
- if (!zone_watermark_ok(zone, order,
|
||||
+ if (!zone_watermark_ok_safe(zone, order,
|
||||
high_wmark_pages(zone), end_zone, 0)) {
|
||||
all_zones_ok = 0;
|
||||
/*
|
||||
@@ -2184,7 +2184,7 @@ loop_again:
|
||||
* means that we have a GFP_ATOMIC allocation
|
||||
* failure risk. Hurry up!
|
||||
*/
|
||||
- if (!zone_watermark_ok(zone, order,
|
||||
+ if (!zone_watermark_ok_safe(zone, order,
|
||||
min_wmark_pages(zone), end_zone, 0))
|
||||
has_under_min_watermark_zone = 1;
|
||||
}
|
||||
@@ -2326,9 +2326,11 @@ static int kswapd(void *p)
|
||||
* premature sleep. If not, then go fully
|
||||
* to sleep until explicitly woken up
|
||||
*/
|
||||
- if (!sleeping_prematurely(pgdat, order, remaining))
|
||||
+ if (!sleeping_prematurely(pgdat, order, remaining)) {
|
||||
+ restore_pgdat_percpu_threshold(pgdat);
|
||||
schedule();
|
||||
- else {
|
||||
+ reduce_pgdat_percpu_threshold(pgdat);
|
||||
+ } else {
|
||||
if (remaining)
|
||||
count_vm_event(KSWAPD_LOW_WMARK_HIT_QUICKLY);
|
||||
else
|
||||
@@ -2364,15 +2366,16 @@ void wakeup_kswapd(struct zone *zone, int order)
|
||||
if (!populated_zone(zone))
|
||||
return;
|
||||
|
||||
- pgdat = zone->zone_pgdat;
|
||||
- if (zone_watermark_ok(zone, order, low_wmark_pages(zone), 0, 0))
|
||||
+ if (!cpuset_zone_allowed_hardwall(zone, GFP_KERNEL))
|
||||
return;
|
||||
+ pgdat = zone->zone_pgdat;
|
||||
if (pgdat->kswapd_max_order < order)
|
||||
pgdat->kswapd_max_order = order;
|
||||
- if (!cpuset_zone_allowed_hardwall(zone, GFP_KERNEL))
|
||||
- return;
|
||||
if (!waitqueue_active(&pgdat->kswapd_wait))
|
||||
return;
|
||||
+ if (zone_watermark_ok_safe(zone, order, low_wmark_pages(zone), 0, 0))
|
||||
+ return;
|
||||
+
|
||||
wake_up_interruptible(&pgdat->kswapd_wait);
|
||||
}
|
||||
|
||||
diff --git a/mm/vmstat.c b/mm/vmstat.c
|
||||
index 26d5716..41dc8cd 100644
|
||||
--- a/mm/vmstat.c
|
||||
+++ b/mm/vmstat.c
|
||||
@@ -81,6 +81,30 @@ EXPORT_SYMBOL(vm_stat);
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
|
||||
+static int calculate_pressure_threshold(struct zone *zone)
|
||||
+{
|
||||
+ int threshold;
|
||||
+ int watermark_distance;
|
||||
+
|
||||
+ /*
|
||||
+ * As vmstats are not up to date, there is drift between the estimated
|
||||
+ * and real values. For high thresholds and a high number of CPUs, it
|
||||
+ * is possible for the min watermark to be breached while the estimated
|
||||
+ * value looks fine. The pressure threshold is a reduced value such
|
||||
+ * that even the maximum amount of drift will not accidentally breach
|
||||
+ * the min watermark
|
||||
+ */
|
||||
+ watermark_distance = low_wmark_pages(zone) - min_wmark_pages(zone);
|
||||
+ threshold = max(1, (int)(watermark_distance / num_online_cpus()));
|
||||
+
|
||||
+ /*
|
||||
+ * Maximum threshold is 125
|
||||
+ */
|
||||
+ threshold = min(125, threshold);
|
||||
+
|
||||
+ return threshold;
|
||||
+}
|
||||
+
|
||||
static int calculate_threshold(struct zone *zone)
|
||||
{
|
||||
int threshold;
|
||||
@@ -159,6 +183,48 @@ static void refresh_zone_stat_thresholds(void)
|
||||
}
|
||||
}
|
||||
|
||||
+void reduce_pgdat_percpu_threshold(pg_data_t *pgdat)
|
||||
+{
|
||||
+ struct zone *zone;
|
||||
+ int cpu;
|
||||
+ int threshold;
|
||||
+ int i;
|
||||
+
|
||||
+ get_online_cpus();
|
||||
+ for (i = 0; i < pgdat->nr_zones; i++) {
|
||||
+ zone = &pgdat->node_zones[i];
|
||||
+ if (!zone->percpu_drift_mark)
|
||||
+ continue;
|
||||
+
|
||||
+ threshold = calculate_pressure_threshold(zone);
|
||||
+ for_each_online_cpu(cpu)
|
||||
+ per_cpu_ptr(zone->pageset, cpu)->stat_threshold
|
||||
+ = threshold;
|
||||
+ }
|
||||
+ put_online_cpus();
|
||||
+}
|
||||
+
|
||||
+void restore_pgdat_percpu_threshold(pg_data_t *pgdat)
|
||||
+{
|
||||
+ struct zone *zone;
|
||||
+ int cpu;
|
||||
+ int threshold;
|
||||
+ int i;
|
||||
+
|
||||
+ get_online_cpus();
|
||||
+ for (i = 0; i < pgdat->nr_zones; i++) {
|
||||
+ zone = &pgdat->node_zones[i];
|
||||
+ if (!zone->percpu_drift_mark)
|
||||
+ continue;
|
||||
+
|
||||
+ threshold = calculate_threshold(zone);
|
||||
+ for_each_online_cpu(cpu)
|
||||
+ per_cpu_ptr(zone->pageset, cpu)->stat_threshold
|
||||
+ = threshold;
|
||||
+ }
|
||||
+ put_online_cpus();
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* For use when we know that interrupts are disabled.
|
||||
*/
|
||||
@@ -826,7 +892,7 @@ static void zoneinfo_show_print(struct seq_file *m, pg_data_t *pgdat,
|
||||
"\n scanned %lu"
|
||||
"\n spanned %lu"
|
||||
"\n present %lu",
|
||||
- zone_nr_free_pages(zone),
|
||||
+ zone_page_state(zone, NR_FREE_PAGES),
|
||||
min_wmark_pages(zone),
|
||||
low_wmark_pages(zone),
|
||||
high_wmark_pages(zone),
|
||||
--
|
||||
1.7.3.2
|
||||
|
|
@ -0,0 +1,165 @@
|
|||
From 235d4a7af803e65d8fabdf9cd6d1445c11e2fd45 Mon Sep 17 00:00:00 2001
|
||||
From: Mel Gorman <mel@csn.ul.ie>
|
||||
Date: Wed, 24 Nov 2010 22:24:24 -0500
|
||||
Subject: [PATCH 2/2] mm: vmstat: Use a single setter function and callback for adjusting percpu thresholds
|
||||
|
||||
reduce_pgdat_percpu_threshold() and restore_pgdat_percpu_threshold() exist
|
||||
to adjust the per-cpu vmstat thresholds while kswapd is awake to avoid
|
||||
errors due to counter drift. The functions duplicate some code so this
|
||||
patch replaces them with a single set_pgdat_percpu_threshold() that takes
|
||||
a callback function to calculate the desired threshold as a parameter.
|
||||
|
||||
Signed-off-by: Mel Gorman <mel@csn.ul.ie>
|
||||
Reviewed-by: Christoph Lameter <cl@linux.com>
|
||||
Reviewed-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
|
||||
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
||||
[the various mmotm patches updating this were rolled up. --kyle]
|
||||
---
|
||||
include/linux/vmstat.h | 10 ++++++----
|
||||
mm/vmscan.c | 18 ++++++++++++++++--
|
||||
mm/vmstat.c | 36 +++++++-----------------------------
|
||||
3 files changed, 29 insertions(+), 35 deletions(-)
|
||||
|
||||
diff --git a/include/linux/vmstat.h b/include/linux/vmstat.h
|
||||
index e4cc21c..833e676 100644
|
||||
--- a/include/linux/vmstat.h
|
||||
+++ b/include/linux/vmstat.h
|
||||
@@ -254,8 +254,11 @@ extern void dec_zone_state(struct zone *, enum zone_stat_item);
|
||||
extern void __dec_zone_state(struct zone *, enum zone_stat_item);
|
||||
|
||||
void refresh_cpu_vm_stats(int);
|
||||
-void reduce_pgdat_percpu_threshold(pg_data_t *pgdat);
|
||||
-void restore_pgdat_percpu_threshold(pg_data_t *pgdat);
|
||||
+
|
||||
+int calculate_pressure_threshold(struct zone *zone);
|
||||
+int calculate_normal_threshold(struct zone *zone);
|
||||
+void set_pgdat_percpu_threshold(pg_data_t *pgdat,
|
||||
+ int (*calculate_pressure)(struct zone *));
|
||||
#else /* CONFIG_SMP */
|
||||
|
||||
/*
|
||||
@@ -300,8 +303,7 @@ static inline void __dec_zone_page_state(struct page *page,
|
||||
#define dec_zone_page_state __dec_zone_page_state
|
||||
#define mod_zone_page_state __mod_zone_page_state
|
||||
|
||||
-static inline void reduce_pgdat_percpu_threshold(pg_data_t *pgdat) { }
|
||||
-static inline void restore_pgdat_percpu_threshold(pg_data_t *pgdat) { }
|
||||
+#define set_pgdat_percpu_threshold(pgdat, callback) { }
|
||||
|
||||
static inline void refresh_cpu_vm_stats(int cpu) { }
|
||||
#endif
|
||||
diff --git a/mm/vmscan.c b/mm/vmscan.c
|
||||
index 18f4038..e8df269 100644
|
||||
--- a/mm/vmscan.c
|
||||
+++ b/mm/vmscan.c
|
||||
@@ -2327,9 +2327,23 @@ static int kswapd(void *p)
|
||||
* to sleep until explicitly woken up
|
||||
*/
|
||||
if (!sleeping_prematurely(pgdat, order, remaining)) {
|
||||
- restore_pgdat_percpu_threshold(pgdat);
|
||||
+ /*
|
||||
+ * vmstat counters are not perfectly
|
||||
+ * accurate and the estimated value
|
||||
+ * for counters such as NR_FREE_PAGES
|
||||
+ * can deviate from the true value by
|
||||
+ * nr_online_cpus * threshold. To
|
||||
+ * avoid the zone watermarks being
|
||||
+ * breached while under pressure, we
|
||||
+ * reduce the per-cpu vmstat threshold
|
||||
+ * while kswapd is awake and restore
|
||||
+ * them before going back to sleep.
|
||||
+ */
|
||||
+ set_pgdat_percpu_threshold(pgdat,
|
||||
+ calculate_normal_threshold);
|
||||
schedule();
|
||||
- reduce_pgdat_percpu_threshold(pgdat);
|
||||
+ set_pgdat_percpu_threshold(pgdat,
|
||||
+ calculate_pressure_threshold);
|
||||
} else {
|
||||
if (remaining)
|
||||
count_vm_event(KSWAPD_LOW_WMARK_HIT_QUICKLY);
|
||||
diff --git a/mm/vmstat.c b/mm/vmstat.c
|
||||
index 41dc8cd..5b44b82 100644
|
||||
--- a/mm/vmstat.c
|
||||
+++ b/mm/vmstat.c
|
||||
@@ -81,7 +81,7 @@ EXPORT_SYMBOL(vm_stat);
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
|
||||
-static int calculate_pressure_threshold(struct zone *zone)
|
||||
+int calculate_pressure_threshold(struct zone *zone)
|
||||
{
|
||||
int threshold;
|
||||
int watermark_distance;
|
||||
@@ -105,7 +105,7 @@ static int calculate_pressure_threshold(struct zone *zone)
|
||||
return threshold;
|
||||
}
|
||||
|
||||
-static int calculate_threshold(struct zone *zone)
|
||||
+int calculate_normal_threshold(struct zone *zone)
|
||||
{
|
||||
int threshold;
|
||||
int mem; /* memory in 128 MB units */
|
||||
@@ -164,7 +164,7 @@ static void refresh_zone_stat_thresholds(void)
|
||||
for_each_populated_zone(zone) {
|
||||
unsigned long max_drift, tolerate_drift;
|
||||
|
||||
- threshold = calculate_threshold(zone);
|
||||
+ threshold = calculate_normal_threshold(zone);
|
||||
|
||||
for_each_online_cpu(cpu)
|
||||
per_cpu_ptr(zone->pageset, cpu)->stat_threshold
|
||||
@@ -183,46 +183,24 @@ static void refresh_zone_stat_thresholds(void)
|
||||
}
|
||||
}
|
||||
|
||||
-void reduce_pgdat_percpu_threshold(pg_data_t *pgdat)
|
||||
+void set_pgdat_percpu_threshold(pg_data_t *pgdat,
|
||||
+ int (*calculate_pressure)(struct zone *))
|
||||
{
|
||||
struct zone *zone;
|
||||
int cpu;
|
||||
int threshold;
|
||||
int i;
|
||||
|
||||
- get_online_cpus();
|
||||
- for (i = 0; i < pgdat->nr_zones; i++) {
|
||||
- zone = &pgdat->node_zones[i];
|
||||
- if (!zone->percpu_drift_mark)
|
||||
- continue;
|
||||
-
|
||||
- threshold = calculate_pressure_threshold(zone);
|
||||
- for_each_online_cpu(cpu)
|
||||
- per_cpu_ptr(zone->pageset, cpu)->stat_threshold
|
||||
- = threshold;
|
||||
- }
|
||||
- put_online_cpus();
|
||||
-}
|
||||
-
|
||||
-void restore_pgdat_percpu_threshold(pg_data_t *pgdat)
|
||||
-{
|
||||
- struct zone *zone;
|
||||
- int cpu;
|
||||
- int threshold;
|
||||
- int i;
|
||||
-
|
||||
- get_online_cpus();
|
||||
for (i = 0; i < pgdat->nr_zones; i++) {
|
||||
zone = &pgdat->node_zones[i];
|
||||
if (!zone->percpu_drift_mark)
|
||||
continue;
|
||||
|
||||
- threshold = calculate_threshold(zone);
|
||||
- for_each_online_cpu(cpu)
|
||||
+ threshold = (*calculate_pressure)(zone);
|
||||
+ for_each_possible_cpu(cpu)
|
||||
per_cpu_ptr(zone->pageset, cpu)->stat_threshold
|
||||
= threshold;
|
||||
}
|
||||
- put_online_cpus();
|
||||
}
|
||||
|
||||
/*
|
||||
--
|
||||
1.7.3.2
|
||||
|
|
@ -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,254 @@
|
|||
Author: Neil Horman <nhorman@tuxdriver.com>
|
||||
Date: Fri Dec 17 13:35:36 2010 -0500
|
||||
|
||||
Enhance AF_PACKET to support using non-contiguous memory when allocating ring
|
||||
buffer space. This is a combined backport of the following commits from
|
||||
net-next-2.6:
|
||||
0e3125c755445664f00ad036e4fc2cd32fd52877
|
||||
bbce5a59e4e0e6e1dbc85492caaf310ff6611309
|
||||
0af55bb58f8fa7865004ac48d16affe125ac1b7f
|
||||
920b8d913bd3d963d5c88bca160a272b71e0c95a
|
||||
|
||||
diff -up linux-2.6.34.x86_64/net/packet/af_packet.c.orig linux-2.6.34.x86_64/net/packet/af_packet.c
|
||||
--- linux-2.6.34.x86_64/net/packet/af_packet.c.orig 2010-12-17 12:16:58.000000000 -0500
|
||||
+++ linux-2.6.34.x86_64/net/packet/af_packet.c 2010-12-17 12:30:14.000000000 -0500
|
||||
@@ -61,6 +61,7 @@
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/kmod.h>
|
||||
#include <linux/slab.h>
|
||||
+#include <linux/vmalloc.h>
|
||||
#include <net/net_namespace.h>
|
||||
#include <net/ip.h>
|
||||
#include <net/protocol.h>
|
||||
@@ -161,8 +162,14 @@ struct packet_mreq_max {
|
||||
static int packet_set_ring(struct sock *sk, struct tpacket_req *req,
|
||||
int closing, int tx_ring);
|
||||
|
||||
+#define PGV_FROM_VMALLOC 1
|
||||
+struct pgv {
|
||||
+ char *buffer;
|
||||
+ unsigned char flags;
|
||||
+};
|
||||
+
|
||||
struct packet_ring_buffer {
|
||||
- char **pg_vec;
|
||||
+ struct pgv *pg_vec;
|
||||
unsigned int head;
|
||||
unsigned int frames_per_block;
|
||||
unsigned int frame_size;
|
||||
@@ -214,6 +221,13 @@ struct packet_skb_cb {
|
||||
|
||||
#define PACKET_SKB_CB(__skb) ((struct packet_skb_cb *)((__skb)->cb))
|
||||
|
||||
+static inline struct page *pgv_to_page(void *addr)
|
||||
+{
|
||||
+ if (is_vmalloc_addr(addr))
|
||||
+ return vmalloc_to_page(addr);
|
||||
+ return virt_to_page(addr);
|
||||
+}
|
||||
+
|
||||
static void __packet_set_status(struct packet_sock *po, void *frame, int status)
|
||||
{
|
||||
union {
|
||||
@@ -226,11 +240,11 @@ static void __packet_set_status(struct p
|
||||
switch (po->tp_version) {
|
||||
case TPACKET_V1:
|
||||
h.h1->tp_status = status;
|
||||
- flush_dcache_page(virt_to_page(&h.h1->tp_status));
|
||||
+ flush_dcache_page(pgv_to_page(&h.h1->tp_status));
|
||||
break;
|
||||
case TPACKET_V2:
|
||||
h.h2->tp_status = status;
|
||||
- flush_dcache_page(virt_to_page(&h.h2->tp_status));
|
||||
+ flush_dcache_page(pgv_to_page(&h.h2->tp_status));
|
||||
break;
|
||||
default:
|
||||
pr_err("TPACKET version not supported\n");
|
||||
@@ -253,10 +267,10 @@ static int __packet_get_status(struct pa
|
||||
h.raw = frame;
|
||||
switch (po->tp_version) {
|
||||
case TPACKET_V1:
|
||||
- flush_dcache_page(virt_to_page(&h.h1->tp_status));
|
||||
+ flush_dcache_page(pgv_to_page(&h.h1->tp_status));
|
||||
return h.h1->tp_status;
|
||||
case TPACKET_V2:
|
||||
- flush_dcache_page(virt_to_page(&h.h2->tp_status));
|
||||
+ flush_dcache_page(pgv_to_page(&h.h2->tp_status));
|
||||
return h.h2->tp_status;
|
||||
default:
|
||||
pr_err("TPACKET version not supported\n");
|
||||
@@ -280,7 +294,8 @@ static void *packet_lookup_frame(struct
|
||||
pg_vec_pos = position / rb->frames_per_block;
|
||||
frame_offset = position % rb->frames_per_block;
|
||||
|
||||
- h.raw = rb->pg_vec[pg_vec_pos] + (frame_offset * rb->frame_size);
|
||||
+ h.raw = rb->pg_vec[pg_vec_pos].buffer +
|
||||
+ (frame_offset * rb->frame_size);
|
||||
|
||||
if (status != __packet_get_status(po, h.raw))
|
||||
return NULL;
|
||||
@@ -771,15 +786,11 @@ static int tpacket_rcv(struct sk_buff *s
|
||||
__packet_set_status(po, h.raw, status);
|
||||
smp_mb();
|
||||
{
|
||||
- struct page *p_start, *p_end;
|
||||
- u8 *h_end = h.raw + macoff + snaplen - 1;
|
||||
+ u8 *start, *end;
|
||||
|
||||
- p_start = virt_to_page(h.raw);
|
||||
- p_end = virt_to_page(h_end);
|
||||
- while (p_start <= p_end) {
|
||||
- flush_dcache_page(p_start);
|
||||
- p_start++;
|
||||
- }
|
||||
+ end = (u8 *)PAGE_ALIGN((unsigned long)h.raw + macoff + snaplen);
|
||||
+ for (start = h.raw; start < end; start += PAGE_SIZE)
|
||||
+ flush_dcache_page(pgv_to_page(start));
|
||||
}
|
||||
|
||||
sk->sk_data_ready(sk, 0);
|
||||
@@ -886,7 +897,6 @@ static int tpacket_fill_skb(struct packe
|
||||
}
|
||||
|
||||
err = -EFAULT;
|
||||
- page = virt_to_page(data);
|
||||
offset = offset_in_page(data);
|
||||
len_max = PAGE_SIZE - offset;
|
||||
len = ((to_write > len_max) ? len_max : to_write);
|
||||
@@ -905,11 +915,11 @@ static int tpacket_fill_skb(struct packe
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
+ page = pgv_to_page(data);
|
||||
+ data += len;
|
||||
flush_dcache_page(page);
|
||||
get_page(page);
|
||||
- skb_fill_page_desc(skb,
|
||||
- nr_frags,
|
||||
- page++, offset, len);
|
||||
+ skb_fill_page_desc(skb, nr_frags, page, offset, len);
|
||||
to_write -= len;
|
||||
offset = 0;
|
||||
len_max = PAGE_SIZE;
|
||||
@@ -2230,37 +2240,76 @@ static const struct vm_operations_struct
|
||||
.close = packet_mm_close,
|
||||
};
|
||||
|
||||
-static void free_pg_vec(char **pg_vec, unsigned int order, unsigned int len)
|
||||
+static void free_pg_vec(struct pgv *pg_vec, unsigned int order,
|
||||
+ unsigned int len)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
- if (likely(pg_vec[i]))
|
||||
- free_pages((unsigned long) pg_vec[i], order);
|
||||
+ if (likely(pg_vec[i].buffer)) {
|
||||
+ if (pg_vec[i].flags & PGV_FROM_VMALLOC)
|
||||
+ vfree(pg_vec[i].buffer);
|
||||
+ else
|
||||
+ free_pages((unsigned long)pg_vec[i].buffer,
|
||||
+ order);
|
||||
+ pg_vec[i].buffer = NULL;
|
||||
+ }
|
||||
}
|
||||
kfree(pg_vec);
|
||||
}
|
||||
|
||||
-static inline char *alloc_one_pg_vec_page(unsigned long order)
|
||||
+static inline char *alloc_one_pg_vec_page(unsigned long order,
|
||||
+ unsigned char *flags)
|
||||
{
|
||||
- gfp_t gfp_flags = GFP_KERNEL | __GFP_COMP | __GFP_ZERO | __GFP_NOWARN;
|
||||
+ char *buffer = NULL;
|
||||
+ gfp_t gfp_flags = GFP_KERNEL | __GFP_COMP |
|
||||
+ __GFP_ZERO | __GFP_NOWARN | __GFP_NORETRY;
|
||||
+
|
||||
+ buffer = (char *) __get_free_pages(gfp_flags, order);
|
||||
|
||||
- return (char *) __get_free_pages(gfp_flags, order);
|
||||
+ if (buffer)
|
||||
+ return buffer;
|
||||
+
|
||||
+ /*
|
||||
+ * __get_free_pages failed, fall back to vmalloc
|
||||
+ */
|
||||
+ *flags |= PGV_FROM_VMALLOC;
|
||||
+ buffer = vmalloc((1 << order) * PAGE_SIZE);
|
||||
+
|
||||
+ if (buffer) {
|
||||
+ memset(buffer, 0, (1 << order) * PAGE_SIZE);
|
||||
+ return buffer;
|
||||
+ }
|
||||
+
|
||||
+ /*
|
||||
+ * vmalloc failed, lets dig into swap here
|
||||
+ */
|
||||
+ *flags = 0;
|
||||
+ gfp_flags &= ~__GFP_NORETRY;
|
||||
+ buffer = (char *)__get_free_pages(gfp_flags, order);
|
||||
+ if (buffer)
|
||||
+ return buffer;
|
||||
+
|
||||
+ /*
|
||||
+ * complete and utter failure
|
||||
+ */
|
||||
+ return NULL;
|
||||
}
|
||||
|
||||
-static char **alloc_pg_vec(struct tpacket_req *req, int order)
|
||||
+static struct pgv *alloc_pg_vec(struct tpacket_req *req, int order)
|
||||
{
|
||||
unsigned int block_nr = req->tp_block_nr;
|
||||
- char **pg_vec;
|
||||
+ struct pgv *pg_vec;
|
||||
int i;
|
||||
|
||||
- pg_vec = kzalloc(block_nr * sizeof(char *), GFP_KERNEL);
|
||||
+ pg_vec = kcalloc(block_nr, sizeof(struct pgv), GFP_KERNEL);
|
||||
if (unlikely(!pg_vec))
|
||||
goto out;
|
||||
|
||||
for (i = 0; i < block_nr; i++) {
|
||||
- pg_vec[i] = alloc_one_pg_vec_page(order);
|
||||
- if (unlikely(!pg_vec[i]))
|
||||
+ pg_vec[i].buffer = alloc_one_pg_vec_page(order,
|
||||
+ &pg_vec[i].flags);
|
||||
+ if (unlikely(!pg_vec[i].buffer))
|
||||
goto out_free_pgvec;
|
||||
}
|
||||
|
||||
@@ -2276,7 +2325,7 @@ out_free_pgvec:
|
||||
static int packet_set_ring(struct sock *sk, struct tpacket_req *req,
|
||||
int closing, int tx_ring)
|
||||
{
|
||||
- char **pg_vec = NULL;
|
||||
+ struct pgv *pg_vec = NULL;
|
||||
struct packet_sock *po = pkt_sk(sk);
|
||||
int was_running, order = 0;
|
||||
struct packet_ring_buffer *rb;
|
||||
@@ -2438,15 +2487,22 @@ static int packet_mmap(struct file *file
|
||||
continue;
|
||||
|
||||
for (i = 0; i < rb->pg_vec_len; i++) {
|
||||
- struct page *page = virt_to_page(rb->pg_vec[i]);
|
||||
+ struct page *page;
|
||||
+ void *kaddr = rb->pg_vec[i].buffer;
|
||||
int pg_num;
|
||||
|
||||
for (pg_num = 0; pg_num < rb->pg_vec_pages;
|
||||
- pg_num++, page++) {
|
||||
+ pg_num++) {
|
||||
+ if (rb->pg_vec[i].flags & PGV_FROM_VMALLOC)
|
||||
+ page = vmalloc_to_page(kaddr);
|
||||
+ else
|
||||
+ page = virt_to_page(kaddr);
|
||||
+
|
||||
err = vm_insert_page(vma, start, page);
|
||||
if (unlikely(err))
|
||||
goto out;
|
||||
start += PAGE_SIZE;
|
||||
+ kaddr += PAGE_SIZE;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
From 38f1f0db010ac5b981ae06f1fe2fd64095ebb171 Mon Sep 17 00:00:00 2001
|
||||
From: Nelson Elhage <nelhage@ksplice.com>
|
||||
Date: Wed, 3 Nov 2010 16:35:40 +0000
|
||||
Subject: [PATCH] netlink: Make nlmsg_find_attr take a const nlmsghdr*.
|
||||
|
||||
This will let us use it on a nlmsghdr stored inside a netlink_callback.
|
||||
|
||||
Signed-off-by: Nelson Elhage <nelhage@ksplice.com>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
include/net/netlink.h | 2 +-
|
||||
1 files changed, 1 insertions(+), 1 deletions(-)
|
||||
|
||||
diff --git a/include/net/netlink.h b/include/net/netlink.h
|
||||
index a63b219..c344646 100644
|
||||
--- a/include/net/netlink.h
|
||||
+++ b/include/net/netlink.h
|
||||
@@ -384,7 +384,7 @@ static inline int nlmsg_parse(const struct nlmsghdr *nlh, int hdrlen,
|
||||
*
|
||||
* Returns the first attribute which matches the specified type.
|
||||
*/
|
||||
-static inline struct nlattr *nlmsg_find_attr(struct nlmsghdr *nlh,
|
||||
+static inline struct nlattr *nlmsg_find_attr(const struct nlmsghdr *nlh,
|
||||
int hdrlen, int attrtype)
|
||||
{
|
||||
return nla_find(nlmsg_attrdata(nlh, hdrlen),
|
||||
--
|
||||
1.7.3.2
|
||||
|
|
@ -0,0 +1,86 @@
|
|||
From 1b3df4f489345b0fd6e83645ad5d464aee55f7de Mon Sep 17 00:00:00 2001
|
||||
From: David Kilroy <kilroyd@googlemail.com>
|
||||
Date: Sat, 4 Dec 2010 18:36:30 +0000
|
||||
Subject: [PATCH] orinoco: initialise priv->hw before assigning the interrupt
|
||||
|
||||
The interrupt handler takes a lock - but since commit bcad6e80f3f this
|
||||
lock goes through an indirection specified in the hermes_t structure.
|
||||
We must therefore initialise the structure before setting up the
|
||||
interrupt handler.
|
||||
|
||||
<https://bugzilla.kernel.org/show_bug.cgi?id=23932>
|
||||
|
||||
Fix both orinoco_cs and spectrum_cs
|
||||
|
||||
Bisected by: Matt Domsch <Matt_Domsch@dell.com>
|
||||
Tested by: Matt Domsch <Matt_Domsch@dell.com>
|
||||
Signed-off by: David Kilroy <kilroyd@googlemail.com>
|
||||
---
|
||||
drivers/net/wireless/orinoco/orinoco_cs.c | 12 ++++++------
|
||||
drivers/net/wireless/orinoco/spectrum_cs.c | 12 ++++++------
|
||||
2 files changed, 12 insertions(+), 12 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/wireless/orinoco/orinoco_cs.c b/drivers/net/wireless/orinoco/orinoco_cs.c
|
||||
index b16d5db..66c7bcc 100644
|
||||
--- a/drivers/net/wireless/orinoco/orinoco_cs.c
|
||||
+++ b/drivers/net/wireless/orinoco/orinoco_cs.c
|
||||
@@ -251,19 +251,19 @@ orinoco_cs_config(struct pcmcia_device *link)
|
||||
goto failed;
|
||||
}
|
||||
|
||||
- ret = pcmcia_request_irq(link, orinoco_interrupt);
|
||||
- if (ret)
|
||||
+ mem = ioport_map(link->io.BasePort1, link->io.NumPorts1);
|
||||
+ if (!mem)
|
||||
goto failed;
|
||||
|
||||
/* We initialize the hermes structure before completing PCMCIA
|
||||
* configuration just in case the interrupt handler gets
|
||||
* called. */
|
||||
- mem = ioport_map(link->io.BasePort1, link->io.NumPorts1);
|
||||
- if (!mem)
|
||||
- goto failed;
|
||||
-
|
||||
hermes_struct_init(hw, mem, HERMES_16BIT_REGSPACING);
|
||||
|
||||
+ ret = pcmcia_request_irq(link, orinoco_interrupt);
|
||||
+ if (ret)
|
||||
+ goto failed;
|
||||
+
|
||||
/*
|
||||
* This actually configures the PCMCIA socket -- setting up
|
||||
* the I/O windows and the interrupt mapping, and putting the
|
||||
diff --git a/drivers/net/wireless/orinoco/spectrum_cs.c b/drivers/net/wireless/orinoco/spectrum_cs.c
|
||||
index b51a9ad..0148763 100644
|
||||
--- a/drivers/net/wireless/orinoco/spectrum_cs.c
|
||||
+++ b/drivers/net/wireless/orinoco/spectrum_cs.c
|
||||
@@ -325,20 +325,20 @@ spectrum_cs_config(struct pcmcia_device *link)
|
||||
goto failed;
|
||||
}
|
||||
|
||||
- ret = pcmcia_request_irq(link, orinoco_interrupt);
|
||||
- if (ret)
|
||||
+ mem = ioport_map(link->io.BasePort1, link->io.NumPorts1);
|
||||
+ if (!mem)
|
||||
goto failed;
|
||||
|
||||
/* We initialize the hermes structure before completing PCMCIA
|
||||
* configuration just in case the interrupt handler gets
|
||||
* called. */
|
||||
- mem = ioport_map(link->io.BasePort1, link->io.NumPorts1);
|
||||
- if (!mem)
|
||||
- goto failed;
|
||||
-
|
||||
hermes_struct_init(hw, mem, HERMES_16BIT_REGSPACING);
|
||||
hw->eeprom_pda = true;
|
||||
|
||||
+ ret = pcmcia_request_irq(link, orinoco_interrupt);
|
||||
+ if (ret)
|
||||
+ goto failed;
|
||||
+
|
||||
/*
|
||||
* This actually configures the PCMCIA socket -- setting up
|
||||
* the I/O windows and the interrupt mapping, and putting the
|
||||
--
|
||||
1.7.2.2
|
||||
|
|
@ -0,0 +1,144 @@
|
|||
From linux-kernel-owner@vger.kernel.org Mon Dec 6 14:01:17 2010
|
||||
From: Matthew Garrett <mjg@redhat.com>
|
||||
To: linux-pci@vger.kernel.org
|
||||
Cc: linux-kernel@vger.kernel.org, jbarnes@virtuousgeek.org,
|
||||
Matthew Garrett <mjg@redhat.com>
|
||||
Subject: [PATCH v2] PCI: Disable ASPM if BIOS asks us to
|
||||
Date: Mon, 6 Dec 2010 14:00:56 -0500
|
||||
Message-Id: <1291662056-6055-1-git-send-email-mjg@redhat.com>
|
||||
|
||||
We currently refuse to touch the ASPM registers if the BIOS tells us that
|
||||
ASPM isn't supported. This can cause problems if the BIOS has (for any
|
||||
reason) enabled ASPM on some devices anyway. Change the code such that we
|
||||
explicitly clear ASPM if the FADT indicates that ASPM isn't supported,
|
||||
and make sure we tidy up appropriately on device removal in order to deal
|
||||
with the hotplug case. If ASPM is disabled because the BIOS doesn't hand
|
||||
over control then we won't touch the registers.
|
||||
|
||||
Signed-off-by: Matthew Garrett <mjg@redhat.com>
|
||||
---
|
||||
|
||||
Implement Rafael's suggestion to use two separate functions, and also
|
||||
ensure that we clear the clkpm bit as well as the ASPM bits.
|
||||
|
||||
drivers/pci/pci-acpi.c | 1 +
|
||||
drivers/pci/pcie/aspm.c | 21 +++++++++++++++++----
|
||||
include/linux/pci-aspm.h | 5 ++++-
|
||||
3 files changed, 22 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c
|
||||
index 24e19c5..d7ea699 100644
|
||||
--- a/drivers/pci/pci-acpi.c
|
||||
+++ b/drivers/pci/pci-acpi.c
|
||||
@@ -399,6 +399,7 @@ static int __init acpi_pci_init(void)
|
||||
|
||||
if (acpi_gbl_FADT.boot_flags & ACPI_FADT_NO_ASPM) {
|
||||
printk(KERN_INFO"ACPI FADT declares the system doesn't support PCIe ASPM, so disable it\n");
|
||||
+ pcie_clear_aspm();
|
||||
pcie_no_aspm();
|
||||
}
|
||||
|
||||
diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c
|
||||
index 7122281..8112415 100644
|
||||
--- a/drivers/pci/pcie/aspm.c
|
||||
+++ b/drivers/pci/pcie/aspm.c
|
||||
@@ -68,7 +68,7 @@ struct pcie_link_state {
|
||||
struct aspm_latency acceptable[8];
|
||||
};
|
||||
|
||||
-static int aspm_disabled, aspm_force;
|
||||
+static int aspm_disabled, aspm_force, aspm_clear_state;
|
||||
static DEFINE_MUTEX(aspm_lock);
|
||||
static LIST_HEAD(link_list);
|
||||
|
||||
@@ -139,7 +139,7 @@ static void pcie_set_clkpm(struct pcie_link_state *link, int enable)
|
||||
{
|
||||
/* Don't enable Clock PM if the link is not Clock PM capable */
|
||||
if (!link->clkpm_capable && enable)
|
||||
- return;
|
||||
+ enable = 0;
|
||||
/* Need nothing if the specified equals to current state */
|
||||
if (link->clkpm_enabled == enable)
|
||||
return;
|
||||
@@ -498,6 +498,10 @@ static int pcie_aspm_sanity_check(struct pci_dev *pdev)
|
||||
struct pci_dev *child;
|
||||
int pos;
|
||||
u32 reg32;
|
||||
+
|
||||
+ if (aspm_clear_state)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
/*
|
||||
* Some functions in a slot might not all be PCIe functions,
|
||||
* very strange. Disable ASPM for the whole slot
|
||||
@@ -563,12 +567,15 @@ void pcie_aspm_init_link_state(struct pci_dev *pdev)
|
||||
struct pcie_link_state *link;
|
||||
int blacklist = !!pcie_aspm_sanity_check(pdev);
|
||||
|
||||
- if (aspm_disabled || !pci_is_pcie(pdev) || pdev->link_state)
|
||||
+ if (!pci_is_pcie(pdev) || pdev->link_state)
|
||||
return;
|
||||
if (pdev->pcie_type != PCI_EXP_TYPE_ROOT_PORT &&
|
||||
pdev->pcie_type != PCI_EXP_TYPE_DOWNSTREAM)
|
||||
return;
|
||||
|
||||
+ if (aspm_disabled && !aspm_clear_state)
|
||||
+ return;
|
||||
+
|
||||
/* VIA has a strange chipset, root port is under a bridge */
|
||||
if (pdev->pcie_type == PCI_EXP_TYPE_ROOT_PORT &&
|
||||
pdev->bus->self)
|
||||
@@ -641,7 +648,7 @@ void pcie_aspm_exit_link_state(struct pci_dev *pdev)
|
||||
struct pci_dev *parent = pdev->bus->self;
|
||||
struct pcie_link_state *link, *root, *parent_link;
|
||||
|
||||
- if (aspm_disabled || !pci_is_pcie(pdev) ||
|
||||
+ if ((aspm_disabled && !aspm_clear_state) || !pci_is_pcie(pdev) ||
|
||||
!parent || !parent->link_state)
|
||||
return;
|
||||
if ((parent->pcie_type != PCI_EXP_TYPE_ROOT_PORT) &&
|
||||
@@ -899,6 +906,12 @@ static int __init pcie_aspm_disable(char *str)
|
||||
|
||||
__setup("pcie_aspm=", pcie_aspm_disable);
|
||||
|
||||
+void pcie_clear_aspm(void)
|
||||
+{
|
||||
+ if (!aspm_force)
|
||||
+ aspm_clear_state = 1;
|
||||
+}
|
||||
+
|
||||
void pcie_no_aspm(void)
|
||||
{
|
||||
if (!aspm_force)
|
||||
diff --git a/include/linux/pci-aspm.h b/include/linux/pci-aspm.h
|
||||
index 91ba0b3..ce68105 100644
|
||||
--- a/include/linux/pci-aspm.h
|
||||
+++ b/include/linux/pci-aspm.h
|
||||
@@ -27,6 +27,7 @@ extern void pcie_aspm_init_link_state(struct pci_dev *pdev);
|
||||
extern void pcie_aspm_exit_link_state(struct pci_dev *pdev);
|
||||
extern void pcie_aspm_pm_state_change(struct pci_dev *pdev);
|
||||
extern void pci_disable_link_state(struct pci_dev *pdev, int state);
|
||||
+extern void pcie_clear_aspm(void);
|
||||
extern void pcie_no_aspm(void);
|
||||
#else
|
||||
static inline void pcie_aspm_init_link_state(struct pci_dev *pdev)
|
||||
@@ -41,7 +42,9 @@ static inline void pcie_aspm_pm_state_change(struct pci_dev *pdev)
|
||||
static inline void pci_disable_link_state(struct pci_dev *pdev, int state)
|
||||
{
|
||||
}
|
||||
-
|
||||
+static inline void pcie_clear_aspm(void)
|
||||
+{
|
||||
+}
|
||||
static inline void pcie_no_aspm(void)
|
||||
{
|
||||
}
|
||||
--
|
||||
1.7.3.2
|
||||
|
||||
--
|
||||
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/
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,84 @@
|
|||
From 8ba192510be47fc327c59449a4b5d347e9669329 Mon Sep 17 00:00:00 2001
|
||||
From: Bjorn Helgaas <bjorn.helgaas@hp.com>
|
||||
Date: Wed, 29 Sep 2010 12:24:23 -0600
|
||||
Subject: PNP: log PNP resources, as we do for PCI
|
||||
|
||||
ACPI devices are often involved in address space conflicts with PCI devices,
|
||||
so I think it's worth logging the resources they use. Otherwise we have to
|
||||
depend on lspnp or groping around in sysfs to find them.
|
||||
|
||||
Signed-off-by: Bjorn Helgaas <bjorn.helgaas@hp.com>
|
||||
Signed-off-by: Len Brown <len.brown@intel.com>
|
||||
---
|
||||
drivers/pnp/core.c | 5 +++--
|
||||
drivers/pnp/resource.c | 10 +++++-----
|
||||
2 files changed, 8 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/drivers/pnp/core.c b/drivers/pnp/core.c
|
||||
index 5dba909..e457f99 100644
|
||||
--- a/drivers/pnp/core.c
|
||||
+++ b/drivers/pnp/core.c
|
||||
@@ -191,8 +191,9 @@ int pnp_add_device(struct pnp_dev *dev)
|
||||
for (id = dev->id; id; id = id->next)
|
||||
len += scnprintf(buf + len, sizeof(buf) - len, " %s", id->id);
|
||||
|
||||
- pnp_dbg(&dev->dev, "%s device, IDs%s (%s)\n",
|
||||
- dev->protocol->name, buf, dev->active ? "active" : "disabled");
|
||||
+ dev_printk(KERN_DEBUG, &dev->dev, "%s device, IDs%s (%s)\n",
|
||||
+ dev->protocol->name, buf,
|
||||
+ dev->active ? "active" : "disabled");
|
||||
return 0;
|
||||
}
|
||||
|
||||
diff --git a/drivers/pnp/resource.c b/drivers/pnp/resource.c
|
||||
index e3446ab..a925e6b 100644
|
||||
--- a/drivers/pnp/resource.c
|
||||
+++ b/drivers/pnp/resource.c
|
||||
@@ -523,7 +523,7 @@ struct pnp_resource *pnp_add_irq_resource(struct pnp_dev *dev, int irq,
|
||||
res->start = irq;
|
||||
res->end = irq;
|
||||
|
||||
- pnp_dbg(&dev->dev, " add %pr\n", res);
|
||||
+ dev_printk(KERN_DEBUG, &dev->dev, "%pR\n", res);
|
||||
return pnp_res;
|
||||
}
|
||||
|
||||
@@ -544,7 +544,7 @@ struct pnp_resource *pnp_add_dma_resource(struct pnp_dev *dev, int dma,
|
||||
res->start = dma;
|
||||
res->end = dma;
|
||||
|
||||
- pnp_dbg(&dev->dev, " add %pr\n", res);
|
||||
+ dev_printk(KERN_DEBUG, &dev->dev, "%pR\n", res);
|
||||
return pnp_res;
|
||||
}
|
||||
|
||||
@@ -568,7 +568,7 @@ struct pnp_resource *pnp_add_io_resource(struct pnp_dev *dev,
|
||||
res->start = start;
|
||||
res->end = end;
|
||||
|
||||
- pnp_dbg(&dev->dev, " add %pr\n", res);
|
||||
+ dev_printk(KERN_DEBUG, &dev->dev, "%pR\n", res);
|
||||
return pnp_res;
|
||||
}
|
||||
|
||||
@@ -592,7 +592,7 @@ struct pnp_resource *pnp_add_mem_resource(struct pnp_dev *dev,
|
||||
res->start = start;
|
||||
res->end = end;
|
||||
|
||||
- pnp_dbg(&dev->dev, " add %pr\n", res);
|
||||
+ dev_printk(KERN_DEBUG, &dev->dev, "%pR\n", res);
|
||||
return pnp_res;
|
||||
}
|
||||
|
||||
@@ -616,7 +616,7 @@ struct pnp_resource *pnp_add_bus_resource(struct pnp_dev *dev,
|
||||
res->start = start;
|
||||
res->end = end;
|
||||
|
||||
- pnp_dbg(&dev->dev, " add %pr\n", res);
|
||||
+ dev_printk(KERN_DEBUG, &dev->dev, "%pR\n", res);
|
||||
return pnp_res;
|
||||
}
|
||||
|
||||
--
|
||||
1.7.3.2
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
From 2876b1571839c25ce5e7485ead8417506d720c73 Mon Sep 17 00:00:00 2001
|
||||
From: Oleg Nesterov <oleg@redhat.com>
|
||||
Date: Fri, 5 Nov 2010 16:53:42 +0100
|
||||
Subject: posix-cpu-timers: workaround to suppress the problems with mt exec
|
||||
|
||||
posix-cpu-timers.c correctly assumes that the dying process does
|
||||
posix_cpu_timers_exit_group() and removes all !CPUCLOCK_PERTHREAD
|
||||
timers from signal->cpu_timers list.
|
||||
|
||||
But, it also assumes that timer->it.cpu.task is always the group
|
||||
leader, and thus the dead ->task means the dead thread group.
|
||||
|
||||
This is obviously not true after de_thread() changes the leader.
|
||||
After that almost every posix_cpu_timer_ method has problems.
|
||||
|
||||
It is not simple to fix this bug correctly. First of all, I think
|
||||
that timer->it.cpu should use struct pid instead of task_struct.
|
||||
Also, the locking should be reworked completely. In particular,
|
||||
tasklist_lock should not be used at all. This all needs a lot of
|
||||
nontrivial and hard-to-test changes.
|
||||
|
||||
Change __exit_signal() to do posix_cpu_timers_exit_group() when
|
||||
the old leader dies during exec. This is not the fix, just the
|
||||
temporary hack to hide the problem for 2.6.37 and stable. IOW,
|
||||
this is obviously wrong but this is what we currently have anyway:
|
||||
cpu timers do not work after mt exec.
|
||||
|
||||
In theory this change adds another race. The exiting leader can
|
||||
detach the timers which were attached to the new leader. However,
|
||||
the window between de_thread() and release_task() is small, we
|
||||
can pretend that sys_timer_create() was called before de_thread().
|
||||
|
||||
Signed-off-by: Oleg Nesterov <oleg@redhat.com>
|
||||
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
|
||||
---
|
||||
kernel/exit.c | 8 ++++++++
|
||||
1 files changed, 8 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/kernel/exit.c b/kernel/exit.c
|
||||
index ac90425..85daf1d 100644
|
||||
--- a/kernel/exit.c
|
||||
+++ b/kernel/exit.c
|
||||
@@ -95,6 +95,14 @@ static void __exit_signal(struct task_struct *tsk)
|
||||
sig->tty = NULL;
|
||||
} else {
|
||||
/*
|
||||
+ * This can only happen if the caller is de_thread().
|
||||
+ * FIXME: this is the temporary hack, we should teach
|
||||
+ * posix-cpu-timers to handle this case correctly.
|
||||
+ */
|
||||
+ if (unlikely(has_group_leader_pid(tsk)))
|
||||
+ posix_cpu_timers_exit_group(tsk);
|
||||
+
|
||||
+ /*
|
||||
* If there is any task waiting for the group exit
|
||||
* then notify it:
|
||||
*/
|
||||
--
|
||||
1.7.3.2
|
||||
|
|
@ -1,65 +0,0 @@
|
|||
From 69b711c0c5e3d9cb3a5b9f741fb4cdc96b5739cb Mon Sep 17 00:00:00 2001
|
||||
From: Kyle McMartin <kyle@dreadnought.i.jkkm.org>
|
||||
Subject: Revert "drm/kms: disable/enable poll around switcheroo on/off"
|
||||
|
||||
This reverts commit fbf81762e385d3d45acad057b654d56972acf58c, mostly.
|
||||
---
|
||||
drivers/gpu/drm/i915/i915_dma.c | 4 +---
|
||||
drivers/gpu/drm/nouveau/nouveau_state.c | 3 ---
|
||||
drivers/gpu/drm/radeon/radeon_device.c | 2 --
|
||||
|
||||
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
|
||||
index 59a2bf8..2df3286 100644
|
||||
--- a/drivers/gpu/drm/i915/i915_dma.c
|
||||
+++ b/drivers/gpu/drm/i915/i915_dma.c
|
||||
@@ -1320,14 +1320,12 @@ static void i915_switcheroo_set_state(struct pci_dev *pdev, enum vga_switcheroo_
|
||||
struct drm_device *dev = pci_get_drvdata(pdev);
|
||||
pm_message_t pmm = { .event = PM_EVENT_SUSPEND };
|
||||
if (state == VGA_SWITCHEROO_ON) {
|
||||
- printk(KERN_INFO "i915: switched on\n");
|
||||
+ printk(KERN_INFO "i915: switched off\n");
|
||||
/* i915 resume handler doesn't set to D0 */
|
||||
pci_set_power_state(dev->pdev, PCI_D0);
|
||||
i915_resume(dev);
|
||||
- drm_kms_helper_poll_enable(dev);
|
||||
} else {
|
||||
printk(KERN_ERR "i915: switched off\n");
|
||||
- drm_kms_helper_poll_disable(dev);
|
||||
i915_suspend(dev, pmm);
|
||||
}
|
||||
}
|
||||
diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c
|
||||
index b02a231..0c28266 100644
|
||||
--- a/drivers/gpu/drm/nouveau/nouveau_state.c
|
||||
+++ b/drivers/gpu/drm/nouveau/nouveau_state.c
|
||||
@@ -376,15 +376,12 @@ out_err:
|
||||
static void nouveau_switcheroo_set_state(struct pci_dev *pdev,
|
||||
enum vga_switcheroo_state state)
|
||||
{
|
||||
- struct drm_device *dev = pci_get_drvdata(pdev);
|
||||
pm_message_t pmm = { .event = PM_EVENT_SUSPEND };
|
||||
if (state == VGA_SWITCHEROO_ON) {
|
||||
printk(KERN_ERR "VGA switcheroo: switched nouveau on\n");
|
||||
nouveau_pci_resume(pdev);
|
||||
- drm_kms_helper_poll_enable(dev);
|
||||
} else {
|
||||
printk(KERN_ERR "VGA switcheroo: switched nouveau off\n");
|
||||
- drm_kms_helper_poll_disable(dev);
|
||||
nouveau_pci_suspend(pdev, pmm);
|
||||
}
|
||||
}
|
||||
diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c
|
||||
index f10faed..225a9f2 100644
|
||||
--- a/drivers/gpu/drm/radeon/radeon_device.c
|
||||
+++ b/drivers/gpu/drm/radeon/radeon_device.c
|
||||
@@ -546,10 +546,8 @@ static void radeon_switcheroo_set_state(struct pci_dev *pdev, enum vga_switchero
|
||||
/* don't suspend or resume card normally */
|
||||
rdev->powered_down = false;
|
||||
radeon_resume_kms(dev);
|
||||
- drm_kms_helper_poll_enable(dev);
|
||||
} else {
|
||||
printk(KERN_INFO "radeon: switched off\n");
|
||||
- drm_kms_helper_poll_disable(dev);
|
||||
radeon_suspend_kms(dev, pmm);
|
||||
/* don't suspend or resume card normally */
|
||||
rdev->powered_down = true;
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue