Compare commits

...

260 Commits

Author SHA1 Message Date
Steve Dickson 3a4ec2bd5a Fixed up kernel.spec from the merge.
Signed-off-by: Steve Dickson <steved@redhat.com>
2011-01-28 12:18:57 -05:00
Steve Dickson 3b1a284d7f Merge branch 'f14/user/steved/pnfs-f14' of ssh://pkgs.fedoraproject.org/kernel into f14/user/steved/pnfs-f14 2011-01-28 12:07:19 -05:00
Steve Dickson b170076e1c Reworked the changelog so the date were in the correct order.
Signed-off-by: Steve Dickson <steved@redhat.com>
2011-01-28 12:06:42 -05:00
Steve Dickson 250f7589e4 Updated to the latest pNFS tag: pnfs-all-2.6.35-2010-08-19
Signed-off-by: Steve Dickson <steved@redhat.com>
2011-01-28 12:06:41 -05:00
Steve Dickson 5cde5ec617 Took out the localversion-pnfs file.
Signed-off-by: Steve Dickson <steved@redhat.com>
2011-01-28 12:06:41 -05:00
Steve Dickson c304842dfa Updated to the latest pNFS tag: pnfs-all-2.6.35-2010-08-19
Signed-off-by: Steve Dickson <steved@redhat.com>
2011-01-28 12:06:41 -05:00
Steve Dickson 1c967e02e8 Updated to the latest pNFS tag: pnfs-all-2.6.35-2010-09-14
Signed-off-by: Steve Dickson <steved@redhat.com>
2011-01-28 12:06:08 -05:00
Steve Dickson 2f1b6218c2 - Updated to the latest pNFS tag: pnfs-all-2.6.35-2010-08-24
Signed-off-by: Steve Dickson <steved@redhat.com>
2011-01-28 12:04:51 -05:00
Steve Dickson 0aee182506 Updated to the latest pNFS tag: pnfs-all-2.6.35-2010-08-19
Signed-off-by: Steve Dickson <steved@redhat.com>
2011-01-28 12:03:49 -05:00
Steve Dickson a0798f575a - Updated to the latest pNFS tag: pnfs-all-2.6.35-2010-08-24
Signed-off-by: Steve Dickson <steved@redhat.com>
2011-01-28 12:03:49 -05:00
Steve Dickson 5af4710c35 Took out the localversion-pnfs file.
Signed-off-by: Steve Dickson <steved@redhat.com>
2011-01-28 12:02:17 -05:00
Steve Dickson 7c7185f5b6 Updated to the latest pNFS tag: pnfs-all-2.6.35-2010-08-19
Signed-off-by: Steve Dickson <steved@redhat.com>
2011-01-28 12:02:17 -05:00
Steve Dickson 26ae753414 Updated to the latest pNFS tag: pnfs-all-2.6.35-2010-08-19
Signed-off-by: Steve Dickson <steved@redhat.com>
2011-01-28 12:02:17 -05:00
Steve Dickson d3e09fea2e Updated to the latest pNFS tag: pnfs-all-2.6.35-2010-09-14
Signed-off-by: Steve Dickson <steved@redhat.com>
2011-01-28 12:00:36 -05:00
Steve Dickson 9c73b72b5f - Updated to the latest pNFS tag: pnfs-all-2.6.35-2010-08-24
Signed-off-by: Steve Dickson <steved@redhat.com>
2011-01-28 12:00:36 -05:00
Steve Dickson 3df03d3c34 Updated to the latest pNFS tag: pnfs-all-2.6.35-2010-08-19
Signed-off-by: Steve Dickson <steved@redhat.com>
2011-01-28 11:59:23 -05:00
Steve Dickson cf1662d8fb - Updated to the latest pNFS tag: pnfs-all-2.6.35-2010-08-24
Signed-off-by: Steve Dickson <steved@redhat.com>
2011-01-28 11:56:55 -05:00
Steve Dickson 2baff9db8b Updated to the latest pNFS tag: pnfs-all-2.6.35-2010-08-19
Signed-off-by: Steve Dickson <steved@redhat.com>
2011-01-28 11:55:13 -05:00
Steve Dickson 7931835043 Updated to the latest pNFS tag: pnfs-all-2.6.35-2010-08-19
Signed-off-by: Steve Dickson <steved@redhat.com>
2011-01-28 11:53:18 -05:00
Steve Dickson de8bc7b809 Updated to the latest pNFS tag: pnfs-all-2.6.35-2010-09-14
Signed-off-by: Steve Dickson <steved@redhat.com>
2011-01-28 11:51:27 -05:00
Steve Dickson 5c5064cff6 - Updated to the latest pNFS tag: pnfs-all-2.6.35-2010-08-24
Signed-off-by: Steve Dickson <steved@redhat.com>
2011-01-28 11:50:12 -05:00
Steve Dickson bcef2ab5ff Updated to the latest pNFS tag: pnfs-all-2.6.35-2010-08-19
Signed-off-by: Steve Dickson <steved@redhat.com>
2011-01-28 11:50:11 -05:00
Steve Dickson 04b78851f2 - Updated to the latest pNFS tag: pnfs-all-2.6.35-2010-08-24
Signed-off-by: Steve Dickson <steved@redhat.com>
2011-01-28 11:47:59 -05:00
Steve Dickson d9c1e2fc10 Updated to the latest pNFS tag: pnfs-all-2.6.35-2010-08-19
Signed-off-by: Steve Dickson <steved@redhat.com>
2011-01-28 11:46:37 -05:00
Steve Dickson a17e76f845 Took out the localversion-pnfs file.
Signed-off-by: Steve Dickson <steved@redhat.com>
2011-01-28 11:42:07 -05:00
Steve Dickson bed19a5610 Updated to the latest pNFS tag: pnfs-all-2.6.35-2010-08-19
Signed-off-by: Steve Dickson <steved@redhat.com>
2011-01-28 11:42:07 -05:00
Jarod Wilson e2f91db6ff Fix streamzap remote repeat event reporting
Signed-off-by: Jarod Wilson <jarod@redhat.com>
2011-01-27 13:33:40 -05:00
Jarod Wilson 639fa258dc Restructure v4l/dvb backport patches a bit so I quit forgetting necessary backport changes
Signed-off-by: Jarod Wilson <jarod@redhat.com>
2011-01-25 11:30:39 -05:00
Jarod Wilson 1875248d2a Your seemingly bi-weekly installment of IR updates
Signed-off-by: Jarod Wilson <jarod@redhat.com>
2011-01-24 23:12:41 -05:00
Jarod Wilson ef402ae0aa Fix more IR bugs
Signed-off-by: Jarod Wilson <jarod@redhat.com>
2011-01-19 17:13:38 -05:00
Jarod Wilson c998b6666e this thing is borkified. disable it.
Signed-off-by: Jarod Wilson <jarod@redhat.com>
2011-01-18 16:34:02 -05:00
Jarod Wilson dd3abe2b99 and now, really make it actually build. sigh.
Signed-off-by: Jarod Wilson <jarod@redhat.com>
2011-01-18 16:14:55 -05:00
Jarod Wilson 893aff6339 I suck at this game.
Signed-off-by: Jarod Wilson <jarod@redhat.com>
2011-01-18 15:38:52 -05:00
Kyle McMartin 7aeac617c0 hostap_cs-fix-sleeping-function-called-from-invalid-context.patch 2011-01-18 14:48:55 -05:00
Jarod Wilson 0252aa3de3 backport fallout fixups
Signed-off-by: Jarod Wilson <jarod@redhat.com>
2011-01-18 10:35:58 -05:00
Jarod Wilson 5423b80362 Whoops, forgot to bump version
Signed-off-by: Jarod Wilson <jarod@redhat.com>
2011-01-18 00:38:02 -05:00
Jarod Wilson a49e3abdff Yet another v4l/dvb/rc update
Signed-off-by: Jarod Wilson <jarod@redhat.com>
2011-01-18 00:37:11 -05:00
Chuck Ebbert b11f51521b Fix wrong file allocation size in btrfs (#669511) 2011-01-16 12:34:09 -05:00
Jarod Wilson b97dc7392d mac80211 fix for hard lockup in sta_addba_resp_timer_expired (sgruszka, #667459)
Signed-off-by: Jarod Wilson <jarod@redhat.com>
2011-01-10 17:28:31 -05:00
Jarod Wilson 49ee500dd9 Restore imon mce default proto modparam
Signed-off-by: Jarod Wilson <jarod@redhat.com>
2011-01-10 17:28:30 -05:00
Jarod Wilson f0f13be684 Add missing --with/--without pae build flag support
Signed-off-by: Jarod Wilson <jarod@redhat.com>
2011-01-10 17:28:01 -05:00
Jarod Wilson 4b2adb7be5 Add support for local rebuild config option overrides
Signed-off-by: Jarod Wilson <jarod@redhat.com>
2011-01-10 17:27:59 -05:00
Chuck Ebbert aee782a97f CVE-2010-4668: kernel panic with 0-length IOV 2011-01-10 16:16:28 -05:00
Chuck Ebbert 1f90e5b6f6 remove modules.builtin.bin to prevent RPM verify errors (#650807) 2011-01-10 08:15:17 -05:00
Chuck Ebbert b1f2f04a2b Fix failure to get link with e1000e model 82576DC (#652744) 2011-01-06 08:52:42 -05:00
Jarod Wilson 3ebdcc0e61 Fix some v4l/dvb rebase buglets
- Restore functional audio on PVR-150 video capture cards (#666456)
- Fix another mceusb regression cropping up mostly with rc5 signals (#662071)
- Add back some ir-lirc-codec debug spew

Signed-off-by: Jarod Wilson <jarod@redhat.com>
2011-01-05 23:22:22 -05:00
Jarod Wilson d1877af9bb Fix imon 0xffdc device detection and oops on probe
Signed-off-by: Jarod Wilson <jarod@redhat.com>
2010-12-31 00:39:55 -05:00
Matthew Garrett 70d2ada596 Fix patch collision 2010-12-23 10:46:45 -05:00
Matthew Garrett 73ab1e483b - Backport the ACPI battery notification patch (#656738) 2010-12-23 10:16:11 -05:00
Kyle McMartin c60b83ee86 fix issues with ene_ir driver (#664145) 2010-12-22 22:49:59 -05:00
Kyle McMartin 0cb25895ed move flexcop patch to hopefully avoid future issues 2010-12-21 16:20:15 -05:00
Kyle McMartin bd64b2b5de disable trambling flexcop-fix-xlate_proc_name-warning.patch 2010-12-21 16:18:52 -05:00
Jarod Wilson 1328b3a839 Oops, re-enable building lirc staging bits (bz #664164)
Signed-off-by: Jarod Wilson <jarod@redhat.com>
2010-12-20 15:59:43 -05:00
Kyle McMartin 249677902c revert revert revert revert revert AWOOOGA 2010-12-20 14:36:25 -05:00
Kyle McMartin 646207ff5c Merge branch 'bz664206' into f14
Conflicts:
	kernel.spec
2010-12-20 14:34:00 -05:00
Jarod Wilson 1cd0593638 Restore v4l/dvb/rc rebase, now with additional fixage for bttv and ene_ir
Signed-off-by: Jarod Wilson <jarod@redhat.com>
2010-12-20 14:26:29 -05:00
Jarod Wilson 42434a4dc9 Revert "temporarily revert v4l rebase due to issues reported in previous update"
This reverts commit 3dbb45b665.
2010-12-20 13:15:12 -05:00
Jarod Wilson d3e2823f71 Revert "Revert "v4l/dvb/rc: rebase to latest upstream""
This reverts commit 358f4a55c5.
2010-12-20 13:15:02 -05:00
Kyle McMartin 358f4a55c5 Revert "v4l/dvb/rc: rebase to latest upstream"
This reverts commit 92d37ba1d3.

Conflicts:

	kernel.spec
2010-12-20 12:21:56 -05:00
Kyle McMartin 825b8ce73a changelog 2010-12-20 10:15:05 -05:00
Kyle McMartin f8d75b80e6 backport cs checker fixes for r600 2010-12-20 10:13:41 -05:00
Kyle McMartin 3dbb45b665 temporarily revert v4l rebase due to issues reported in previous update 2010-12-19 15:27:51 -05:00
Kyle McMartin 68b623121d copy nhorman's AF_PACKET vmalloc patch from f13 (#637619) 2010-12-18 11:05:38 -05:00
Kyle McMartin 558463d9fb fs-call-security_d_instantiate-in-d_obtain_alias (#662344) 2010-12-18 10:54:08 -05:00
Jarod Wilson 703515438b A few additional mceusb driver fixups
Signed-off-by: Jarod Wilson <jarod@redhat.com>
2010-12-16 16:24:48 -05:00
Jarod Wilson fbfed34fec damn you, CONFIG_VIDEO_SH_MOBILE_CSI2...
Signed-off-by: Jarod Wilson <jarod@redhat.com>
2010-12-15 17:23:49 -05:00
Jarod Wilson 92d37ba1d3 v4l/dvb/rc: rebase to latest upstream
- Rebase v4l/dvb/rc code to latest upstream, should fix a fair
  number of ir/rc-related issues, including bugzilla #662071
- Drop the spaghetti mess of patches we had for v4l/dvb/rc

Note: new patches can be trivially created using this:

http://git.linuxtv.org/media_build.git
Signed-off-by: Jarod Wilson <jarod@redhat.com>
2010-12-15 17:14:26 -05:00
Chuck Ebbert 8f007394cd Linux 2.6.35.10
Remove merged patches and fix up conflicts:
   drm-polling-fixes.patch
   linux-2.6-v4l-dvb-hdpvr-updates.patch
   kvm-fix-fs-gs-reload-oops-with-invalid-ldt.patch
Drop merged patches:
   linux-2.6-rcu-sched-warning.patch
   pnpacpi-cope-with-invalid-device-ids.patch
   ipc-zero-struct-memory-for-compat-fns.patch
   ipc-shm-fix-information-leak-to-user.patch
   r8169-01-fix-rx-checksum-offload.patch
   r8169-02-_re_init-phy-on-resume.patch
   r8169-03-fix-broken-checksum-for-invalid-sctp_igmp-packets.patch
   hda_realtek-handle-unset-external-amp-bits.patch
2010-12-15 15:12:09 -05:00
Kyle McMartin f045c5648e fix typo pci_clear_aspm -> pcie_clear_aspm 2010-12-10 14:55:52 -05:00
Kyle McMartin f2ed8cf30b PCI: Disable ASPM if BIOS asks us to 2010-12-10 11:13:54 -05:00
Kyle McMartin 5a95077aa5 fix patches
don't do a make prep /after/ changing branches... cough.
2010-12-10 10:32:57 -05:00
Kyle McMartin 54f1e03004 fix some issues mounting btrfs devices with subvolumes (#656465) 2010-12-10 10:17:40 -05:00
Kyle McMartin 9d6e5dc425 fix jbd2 warnings when using quotas (#578674) 2010-12-10 09:47:05 -05:00
Kyle McMartin 4bd3ae5daa orinoco: initialise priv->hw before assigning the interrupt 2010-12-09 18:29:25 -05:00
Kyle McMartin bd61adb09d Copy tpm-fix-stall-on-boot.patch from rawhide tree. (#530393) 2010-12-09 17:06:27 -05:00
Chuck Ebbert 983a2bb5c5 Require newt-devel for building perf, to enable the perf TUI (#661180) 2010-12-09 11:20:43 -05:00
Kyle McMartin bed92c4e50 ameliorate the load average account issues with dynticks (rhbz#650934) 2010-12-08 17:20:15 -05:00
Kyle McMartin 20b0493429 enable cplus_demangle in perf 2010-12-04 12:18:59 -05:00
Kyle McMartin 65c06ec080 enable hpilo on x86_64 2010-12-03 07:03:54 -05:00
Kyle McMartin 76a7ebfb42 kswapd fixes from mmotm 2010-12-02 11:21:28 -05:00
Kyle McMartin d40233bb75 forgot to uncomment... 2010-11-30 15:31:20 -05:00
Kyle McMartin 592f4fb443 cherry picked and updated 2010-11-30 15:20:21 -05:00
Kyle McMartin 48eb5c319b add a patch to log pnp resources (from rawhide) 2010-11-29 20:17:45 -05:00
Kyle McMartin 26ea0f2631 drm/ttm: Fix two race conditions + fix busy codepaths [1df6a2eb] (#615505) 2010-11-29 19:10:59 -05:00
Kyle McMartin ca2a17f441 quiet a build warning the inet_diag fix caused 2010-11-26 15:20:25 -05:00
Kyle McMartin 6abfea1c89 plug various tty/serial stack leaks 2010-11-26 15:01:31 -05:00
kyle 7a80ec3e7d hda/realtek and r8169 fixes 2010-11-26 11:20:50 -05:00
kyle e1c14200b1 copy nodebug/nodebuginfo from master 2010-11-25 12:47:00 -05:00
John W. Linville dd99fe005c rtl8180: improve signal reporting for rtl8185 hardware
rtl8180: improve signal reporting for actual rtl8180 hardware
2010-11-24 10:52:09 -05:00
Kyle McMartin 003654d6ca posix-cpu-timers: workaround to suppress the problems with mt exec (rhbz#656264) 2010-11-23 11:40:33 -05:00
Kyle McMartin c86d4707a6 fix logic error in INET_DIAG bytecode auditing (CVE-2010-3880) 2010-11-23 11:12:31 -05:00
Kyle McMartin de964e3639 zero struct memory in ipc shm (CVE-2010-4072) 2010-11-23 10:58:12 -05:00
Kyle McMartin 55415ebd4a initialize struct memory to zero in ipc compat (CVE-2010-4073) 2010-11-23 10:08:40 -05:00
Kyle McMartin cc7fb594a9 fix i8k inline asm to workaround miscompilation with newer gcc 2010-11-23 09:47:06 -05:00
Jarod Wilson 51157289c8 Update to 2.6.35.9 final, tack on some IR fixes
Signed-off-by: Jarod Wilson <jarod@redhat.com>
2010-11-22 16:13:38 -05:00
Chuck Ebbert 0081a7139c Linux 2.6.35.9-rc1
Comment out upstreamed patches:
kvm-fix-regression-with-cmpxchg8b-on-i386-hosts.patch
2010-11-20 07:09:04 -05:00
Ben Skeggs 466450dbeb nouveau: a couple of bug fixes 2010-11-19 19:04:49 +10:00
Kyle McMartin b2e700d12a bump baserelease to 59 2010-11-15 22:02:29 -05:00
Kyle McMartin 4c76cc7f94 pull in support for MBA3 2010-11-15 22:00:06 -05:00
Dave Airlie d5b83e3877 drm: fix stupid in warning 2010-11-12 14:33:52 +10:00
Dave Airlie 5f72d41789 drm: fix EDID issues 2010-11-11 20:49:55 -05:00
Dave Airlie 171d7cfb89 drm: fix invalid edid issues 2010-11-11 20:49:15 -05:00
Justin M. Forbes adfff05db3 fix regression with cmpxchg8b on i386 hosts (rhbz#650215) 2010-11-11 08:49:27 -06:00
Jarod Wilson 28683a07fb 2.6.35.8, ir-core, lirc and hdpvr updates
* Wed Nov 10 2010 Jarod Wilson <jarod@redhat.com> 2.6.35.8-53
- Linux 2.6.35.8
- Drop patches upstreamed in 2.6.35.8
- More ir-core and lirc updates
- HD-PVR driver updates

Signed-off-by: Jarod Wilson <jarod@redhat.com>
2010-11-10 12:42:45 -05:00
Dave Airlie 5ddd90a5d8 - add i915 polling s/r patch 2010-11-09 14:40:50 +10:00
Dave Airlie a474625d92 - Backport polling fixes + radeon hang fixes from upstream 2010-11-08 20:14:05 -05:00
Dave Airlie 05493c4e57 drm: apply polling + radeon fixes from upstream
remove the old polling stuff
2010-11-08 20:12:47 -05:00
Steve Dickson b1908c3f14 Reworked the changelog so the date were in the correct order.
Signed-off-by: Steve Dickson <steved@redhat.com>
2010-11-08 12:33:13 -05:00
Steve Dickson 4075b4330d Merge branch 'f14/user/steved/pnfs-f14' of ssh://pkgs.fedoraproject.org/kernel into f14/user/steved/pnfs-f14 2010-11-08 06:43:20 -05:00
Steve Dickson 7ae8052041 Updated to the latest pNFS tag: pnfs-all-2.6.35-2010-08-19
Signed-off-by: Steve Dickson <steved@redhat.com>
2010-11-08 06:38:10 -05:00
Steve Dickson 988a85aa6c Took out the localversion-pnfs file.
Signed-off-by: Steve Dickson <steved@redhat.com>
2010-11-08 06:36:49 -05:00
Steve Dickson 5bb2257913 Updated to the latest pNFS tag: pnfs-all-2.6.35-2010-08-19
Signed-off-by: Steve Dickson <steved@redhat.com>
2010-11-08 06:36:19 -05:00
Steve Dickson 5d0f2f53b5 Updated to the latest pNFS tag: pnfs-all-2.6.35-2010-09-14
Signed-off-by: Steve Dickson <steved@redhat.com>
2010-11-08 06:33:48 -05:00
Steve Dickson 9f73d83bc4 - Updated to the latest pNFS tag: pnfs-all-2.6.35-2010-08-24
Signed-off-by: Steve Dickson <steved@redhat.com>
2010-11-08 06:33:12 -05:00
Steve Dickson e83ea7932d Updated to the latest pNFS tag: pnfs-all-2.6.35-2010-08-19
Signed-off-by: Steve Dickson <steved@redhat.com>
2010-11-08 06:31:21 -05:00
Steve Dickson 42b1398bfb - Updated to the latest pNFS tag: pnfs-all-2.6.35-2010-08-24
Signed-off-by: Steve Dickson <steved@redhat.com>
2010-11-08 06:29:15 -05:00
Steve Dickson c14bfbaece Took out the localversion-pnfs file.
Signed-off-by: Steve Dickson <steved@redhat.com>
2010-11-08 06:28:33 -05:00
Steve Dickson a062dba9af Updated to the latest pNFS tag: pnfs-all-2.6.35-2010-08-19
Signed-off-by: Steve Dickson <steved@redhat.com>
2010-11-08 06:27:44 -05:00
Steve Dickson ab7f8fbb16 Took out the localversion-pnfs file.
Signed-off-by: Steve Dickson <steved@redhat.com>
2010-11-08 06:26:55 -05:00
Steve Dickson 29691321a1 Updated to the latest pNFS tag: pnfs-all-2.6.35-2010-08-19
Signed-off-by: Steve Dickson <steved@redhat.com>
2010-11-08 06:26:55 -05:00
Ben Skeggs 383a70142a bump baserelease 2010-11-02 13:37:05 +10:00
Ben Skeggs c7b0072805 nouveau: nv86 workaround + dual-head fix 2010-11-02 13:36:15 +10:00
Ben Skeggs df57a85a75 nouveau: add workaround for nv86 hw bug 2010-11-02 13:09:33 +10:00
Steve Dickson 97df345045 Merge branch 'f14/user/steved/pnfs-f14' of ssh://pkgs.fedoraproject.org/kernel into f14/user/steved/pnfs-f14
Conflicts:
	kernel.spec
2010-11-01 09:17:00 -04:00
Steve Dickson 4cd7bbe2c2 Updated to the latest pNFS tag: pnfs-all-2.6.35-2010-09-14
Signed-off-by: Steve Dickson <steved@redhat.com>
2010-11-01 09:14:32 -04:00
Steve Dickson 4d9d24fa91 - Updated to the latest pNFS tag: pnfs-all-2.6.35-2010-08-24
Signed-off-by: Steve Dickson <steved@redhat.com>
2010-11-01 09:13:26 -04:00
Steve Dickson 518cb858af Updated to the latest pNFS tag: pnfs-all-2.6.35-2010-08-19
Signed-off-by: Steve Dickson <steved@redhat.com>
2010-11-01 09:10:28 -04:00
Steve Dickson e8f419b0f2 - Updated to the latest pNFS tag: pnfs-all-2.6.35-2010-08-24
Signed-off-by: Steve Dickson <steved@redhat.com>
2010-11-01 09:09:25 -04:00
Steve Dickson 00a1e4687b Updated to the latest pNFS tag: pnfs-all-2.6.35-2010-08-19
Signed-off-by: Steve Dickson <steved@redhat.com>
2010-11-01 09:08:47 -04:00
Steve Dickson b26c11d70d Took out the localversion-pnfs file.
Signed-off-by: Steve Dickson <steved@redhat.com>
2010-11-01 08:55:49 -04:00
Steve Dickson fdb21e64be Updated to the latest pNFS tag: pnfs-all-2.6.35-2010-08-19
Signed-off-by: Steve Dickson <steved@redhat.com>
2010-11-01 08:55:49 -04:00
Jarod Wilson 030d3b3b4b Fix brown paper bag hardlock bug in imon driver
Signed-off-by: Jarod Wilson <jarod@redhat.com>
2010-10-23 16:03:57 -04:00
Chuck Ebbert 643d353feb More security fixes
drm-i915-sanity-check-pread-pwrite.patch;
 fix CVE-2010-2962, arbitrary kernel memory write via i915 GEM ioctl
kvm-fix-fs-gs-reload-oops-with-invalid-ldt.patch;
 fix CVE-2010-3698, kvm: invalid selector in fs/gs causes kernel panic
v4l1-fix-32-bit-compat-microcode-loading-translation.patch;
 fixes CVE-2010-2963, v4l: VIDIOCSMICROCODE arbitrary write
2010-10-22 11:02:18 -04:00
Kyle McMartin cbdb312a9e last minute f14 kernel fixes 2010-10-22 10:34:02 -04:00
Kyle McMartin 8311d5168d Revert "ir-core, lirc and hdpvr updates"
This reverts commit 59a83bd584
and 61d7a69fe6.
2010-10-22 10:26:15 -04:00
Jarod Wilson 61d7a69fe6 add pointers to the trees these patches come from
Signed-off-by: Jarod Wilson <jarod@redhat.com>
2010-10-20 11:16:02 -04:00
Jarod Wilson 59a83bd584 ir-core, lirc and hdpvr updates
* Tue Oct 19 2010 Jarod Wilson <jarod@redhat.com> 2.6.35.6-47
- More ir-core and lirc updates
- HD-PVR driver updates

Signed-off-by: Jarod Wilson <jarod@redhat.com>
2010-10-19 17:24:50 -04:00
Kyle McMartin c4e830cb35 build 2.6.35.6-46 2010-10-18 22:44:57 -04:00
Kyle McMartin e38a760c9a dmar: add dev->device print like i had intended... 2010-10-18 22:38:42 -04:00
Kyle McMartin f1b58c7ca8 ricoh e822 sdhci support 2010-10-18 22:24:45 -04:00
Kyle McMartin a1b8c4ed84 bomb out of edp bringout that's going to be fail anyway 2010-10-18 19:28:12 -04:00
Kyle McMartin 6268215f01 fix ima patch 2010-10-18 13:35:50 -04:00
Kyle McMartin 6aca938822 ima: Default it to off
Pass ima=on to enable. Reduce impact of the option
when disabled.
2010-10-18 12:38:23 -04:00
kyle c76455ec66 copy the right patch this time 2010-10-18 11:52:57 -04:00
kyle 915df7f6de Quirk to disable DMAR with Ricoh card reader/firewire 2010-10-18 11:39:49 -04:00
Kyle McMartin 7d350a94ee Two networking fixes (skge, r8169) from sgruska 2010-10-18 10:59:42 -04:00
Kyle McMartin 9ee136bcf7 pnpacpi: cope with invalid device IDs. (rhbz#641468) 2010-10-15 15:04:48 -04:00
Kyle McMartin 97e19f7196 build for f14 2010-10-15 13:34:08 -04:00
Peter Jones 7810142e6c Fix missing dm_put().
There's an error path that fails to call dm_put(), which means bad
things happen.  This patch adds the dm_put() call.
2010-10-15 13:16:48 -04:00
Dave Jones c13cbf3b7d bump build 2010-10-13 17:08:13 -04:00
Kyle McMartin c19187e334 disable xhci by default
see spec %changelog for rationale.
2010-10-13 00:01:19 -04:00
Kyle McMartin a2d889c53a "i build tested it" are famous last words 2010-10-12 14:53:56 -04:00
Kyle McMartin 7140c9dd2d dm-allow-setting-of-uuid-via-rename-if-not-already-set.patch
Fix devicemapper UUID field cannot be assigned after map creation
  (rhbz#641476) thanks pjones@.
2010-10-12 13:40:04 -04:00
Jarod Wilson 167ee12e60 Grab a few more little IR fixes and document commits
Signed-off-by: Jarod Wilson <jarod@redhat.com>
2010-10-11 16:49:13 -04:00
Jarod Wilson 870acad08e drop cruft from patch
Signed-off-by: Jarod Wilson <jarod@redhat.com>
2010-10-11 14:07:36 -04:00
Jarod Wilson 866bf4f059 IR stack update (matches 2.6.37-rc1-to-be code)
- update imon driver to fix issues with key releases and properly
  auto-configure another 0xffdc device (VFD + MCE IR)
- add new nuvoton-cir driver (for integrated IR in ASRock ION 330HT)
- add lirc compat ioctl portability fixups

Signed-off-by: Jarod Wilson <jarod@redhat.com>
2010-10-11 11:37:53 -04:00
Ben Skeggs bd31d54eac fix ttm bug 2010-10-11 16:21:22 +10:00
Kyle McMartin f7f1f5ef4a bump to f14 2010-10-08 11:52:32 -04:00
Dave Jones a09b817bc1 Another day, another rcu_dereference warning. (#640673) 2010-10-06 14:09:52 -04:00
Kyle McMartin 2fe1e8e397 build intel_idle into the kernel 2010-10-04 16:13:30 -04:00
Kyle McMartin eaab8be2d4 enable printk.time by default 2010-10-04 10:37:57 -04:00
Kyle McMartin bc9e072d9b efifb updates from upstream 2010-10-03 17:32:27 -04:00
Ben Skeggs 2e4b75da82 nouveau: more fixes 2010-10-01 15:52:28 +10:00
Dave Jones db140fac23 silence another rcu_reference warning 2010-09-30 16:01:42 -04:00
Steve Dickson d10953c63b Updated to the latest pNFS tag: pnfs-all-2.6.35-2010-09-14
Signed-off-by: Steve Dickson <steved@redhat.com>
2010-09-30 12:15:24 -04:00
Ben Skeggs 7043d42b5a nouveau: fix potential dma race 2010-09-30 13:19:07 +10:00
Dave Jones 452369b936 build fix, again. I suck. 2010-09-29 18:50:05 -04:00
Dave Jones 8f3d6a8c3f build fix 2010-09-29 18:31:36 -04:00
Steve Dickson 853d932874 Merge branch 'f14/user/steved/pnfs-f14' of ssh://pkgs.fedoraproject.org/kernel into f14/user/steved/pnfs-f14
Conflicts:
	kernel.spec
2010-09-29 18:12:31 -04:00
Dave Jones fbce23b0ff bump for build 2010-09-29 18:11:07 -04:00
Steve Dickson e3f262ca54 - Updated to the latest pNFS tag: pnfs-all-2.6.35-2010-08-24
Signed-off-by: Steve Dickson <steved@redhat.com>
2010-09-29 18:08:15 -04:00
Dave Jones bbaea70ee5 Add back an old hack to make an SDV e1000e variant work. 2010-09-29 18:07:59 -04:00
Steve Dickson a4eb340836 Took out the localversion-pnfs file.
Signed-off-by: Steve Dickson <steved@redhat.com>
2010-09-29 18:05:23 -04:00
Steve Dickson 6ac45b1066 Updated to the latest pNFS tag: pnfs-all-2.6.35-2010-08-19
Signed-off-by: Steve Dickson <steved@redhat.com>
2010-09-29 18:05:23 -04:00
Dave Jones 04093b926b Enable IB700 watchdog (used by qemu/kvm). (#637152) 2010-09-29 12:34:17 -04:00
Chuck Ebbert 4141bfc9b1 clean up patches merged in -stable 2010-09-27 13:44:47 -04:00
Kyle McMartin 05f615c82e Linux 2.6.35.6 2010-09-26 22:43:03 -04:00
Chuck Ebbert b999dfdb6a Add xen-fix-typo-in-xen-irq-fix.patch, fixes typo in 2.6.35.5 patch. 2010-09-25 08:38:14 -04:00
Chuck Ebbert b49b116bb0 Add sched-35-increment-cache_nice_tries-only-on-periodic-lb.patch 2010-09-25 08:29:41 -04:00
Chuck Ebbert eda054e8bd Linux 2.6.35.6-rc1
Comment out merged patches:
 aio-check-for-multiplication-overflow-in-do_io_submit.patch
 linux-2.6.35.4-virtio_console-fix-poll.patch
 fix-unprotected-access-to-task-credentials-in-whatid.patch
 dell-wmi-add-support-for-eject-key-studio-1555.patch
 irda-correctly-clean-up-self-ias_obj-on-irda_bind-failure.patch
 keys-fix-bug-in-keyctl_session_to_parent-if-parent-has-no-session-keyring.patch
 keys-fix-rcu-no-lock-warning-in-keyctl_session_to_parent.patch
 sched-00-fix-user-time-incorrectly-accounted-as-system-time-on-32-bit.patch
Revert: "drm/nv50: initialize ramht_refs list for faked 0 channel"
(our DRM update removes ramht_refs entirely.)
2010-09-25 08:18:19 -04:00
Kyle McMartin c2aa9135d2 Bump baserelease 2010-09-23 23:02:02 -04:00
Kyle McMartin 2348a607b7 Serialize mandocs/htmldocs build 2010-09-23 23:01:13 -04:00
Kyle McMartin b13dd03f62 Slay another rcu_dereference_check warning pointed out by rmcgrath 2010-09-23 20:59:39 -04:00
Kyle McMartin 6289a5fca9 Enable -debug flavours and switch default image to release builds
- Bump NR_CPUS on i686 to 64.
2010-09-23 20:39:02 -04:00
Ben Skeggs 31ce2e5e16 nouveau: IGP and DP fixes 2010-09-23 08:54:13 +10:00
Chuck Ebbert b2398b3ef3 Dump stack on failed ATA commands in pata_it821x driver (#632753) 2010-09-22 11:54:31 -04:00
Chuck Ebbert 69a476baa9 Fix possible lockup with new scheduler idle balance code. 2010-09-22 08:40:20 -04:00
Kyle McMartin 027325ab53 Add new btusb ids for MacBookPro from wwoods@ 2010-09-21 11:30:59 -04:00
Chuck Ebbert b218718b2b Scheduler fixes for Bugzilla #635813 and #633037 2010-09-21 09:27:25 -04:00
Chuck Ebbert 7a68cb0b55 Linux 2.6.35.5
Drop merged patches:
01-compat-make-compat_alloc_user_space-incorporate-the-access_ok-check.patch
02-compat-test-rax-for-the-system-call-number-not-eax.patch
03-compat-retruncate-rax-after-ia32-syscall-entry-tracing.patch
direct-io-move-aio_complete-into-end_io.patch
ext4-move-aio-completion-after-unwritten-extent-conversion.patch
xfs-move-aio-completion-after-unwritten-extent-conversion.patch
alsa-seq-oss-fix-double-free-at-error-path-of-snd_seq_oss_open.patch
2010-09-20 21:04:51 -04:00
Dennis Gilmore 42589b1be2 add changelog entry for sparc fixes 2010-09-16 19:29:12 +00:00
Dennis Gilmore 6daeb4142a setup kernel headers to be buit on sparcv9 for 32 bit sparc 2010-09-16 19:26:54 +00:00
Dennis Gilmore c549b813ae disable some modules to get the kerenl building again on sparc 2010-09-16 19:26:53 +00:00
Hans de Goede 7193965656 - Small fix to virtio_console poll fix from upstream review 2010-09-16 10:53:51 +02:00
Dave Jones 291833d307 Fix another RCU lockdep warning (cgroups). 2010-09-15 16:12:01 -04:00
Hans de Goede cb6f3ab735 - virtio_console: Fix poll/select blocking even though there is data to read 2010-09-15 17:33:15 +02:00
Chuck Ebbert db056c27c3 Fix 3 CVEs
/dev/sequencer open failure is not handled correctly (CVE-2010-3080)
NULL deref and panic in irda (CVE-2010-2954)
keyctl_session_to_parent NULL deref system crash (CVE-2010-2960)
2010-09-14 21:31:20 -04:00
Chuck Ebbert 14525abb6d Fix DOS with large argument lists. 2010-09-14 21:05:09 -04:00
Kyle McMartin a1b0ec05b6 security fixes from git head 2010-09-14 20:51:27 -04:00
Chuck Ebbert 9bd241a830 Add support for perl and python scripting to perf (#632942) 2010-09-14 00:35:08 -04:00
Ben Skeggs 4badda4370 nouveau: fix oops in acpi edid support 2010-09-13 09:11:50 +10:00
Jarod Wilson 17a76a95c4 ir-core rebase to current upstream
Signed-off-by: Jarod Wilson <jarod@redhat.com>
2010-09-10 11:57:42 -04:00
Bastien Nocera 9ea075ebba Fix patch application 2010-09-10 16:42:02 +01:00
Bastien Nocera ea6d873cc2 - Update AppleIR patch to work, and support the enter key on
newer remotes
2010-09-10 16:11:56 +01:00
Kyle McMartin 88a50a0b1d Revert 102e2d67
This reverts commit 102e2d6718 which
accidentally snuck into the wrong branch.
2010-09-10 10:33:28 -04:00
Kyle McMartin 102e2d6718 bz620313 2010-09-10 10:28:50 -04:00
Chuck Ebbert 63fcde2459 Disable asynchronous suspend by default. 2010-09-10 10:17:06 -04:00
Ben Skeggs fbc4283e12 nouveau: disable accel on nva3/nva5/nva8 2010-09-10 15:22:18 +10:00
Kyle McMartin 3ceeb77a79 enable GPIO_SYSFS 2010-09-08 20:52:22 -04:00
Kyle McMartin 72b3bf972e linux-2.6-defaults-pci_use_crs 2010-09-08 15:09:01 -04:00
Ben Skeggs 0fe99e9810 nouveau: fix compile error due to upstream differences 2010-09-08 16:49:21 +10:00
Ben Skeggs 215a71b03d nouveau: more updates 2010-09-08 16:23:30 +10:00
Dave Jones 2eba9aa0ec Disable hung task checker, it only ever causes false positives. (#630777) 2010-09-07 12:40:07 -04:00
Jarod Wilson f4da561c3d Enhance HID layer to fully support TiVo Slide remote and dongle
Signed-off-by: Jarod Wilson <jarod@redhat.com>
2010-09-07 12:07:10 -04:00
Kyle McMartin 8b695bdd15 flexcop: fix registering braindead stupid names (#575873) 2010-09-06 16:05:54 -04:00
Kyle McMartin 426c30b2f1 add in f13 patch to fix eject key on dell studio 1555 2010-09-06 15:17:29 -04:00
Kyle McMartin cfdae029cc fix rcu_dereference_check warning 2010-09-06 14:22:48 -04:00
Jarod Wilson 8ccfe4ce6a Restore the rest of the appleir driver patch
Signed-off-by: Jarod Wilson <jarod@redhat.com>
2010-09-06 02:10:02 -04:00
Ben Skeggs 1001ab34f7 nouveau: misc fixes from upstream + NVAF support
This looks far far worse than it is... The reason:
 - NVAF support came after nv50_grctx.c was de-magiced (ie. lots of
   comments explaining what all the hexified numbers are for)
 - nv50_grctx.c de-magic depended on an earlier commit which changed
   all gpu object accessors from 32-bit indices to byte offsets

All in all, it was easier to pull in those big scary-looking (but
harmless) commits than to risk messing up a backport.
2010-09-06 15:55:25 +10:00
Kyle McMartin d3a72eaedc restore appleir driver that got lost from f13 2010-09-03 13:25:36 -04:00
Chuck Ebbert 44c4f071d9 Re-enable I2O, but only for 32-bit x86 (#629676) 2010-09-03 05:23:58 -04:00
Dave Jones 7def7eaed3 Scatter-gather on via-velocity is hopelessly broken.
Just switch it off for now.
2010-09-02 17:23:32 -04:00
Dave Jones 35cc504508 Simplify the VIA Velocity changes. The last round of fixes introduced some bugs. 2010-09-02 13:15:02 -04:00
Dave Jones 705539efb5 One more velocity fix. 2010-09-01 21:45:56 -04:00
Dave Jones c348adbe39 Improved version of the VIA Velocity DMA unmapping fix. 2010-09-01 16:45:48 -04:00
Chuck Ebbert 0c8a5559c3 Don't build UIO platform drivers: they require additional platform code. 2010-09-01 08:00:00 -04:00
Steve Dickson cea8e93168 - Updated to the latest pNFS tag: pnfs-all-2.6.35-2010-08-24
Signed-off-by: Steve Dickson <steved@redhat.com>
2010-08-31 21:17:17 -04:00
Steve Dickson 17fde2a710 Merge branch 'f14/user/steved/pnfs-f14' of ssh://pkgs.fedoraproject.org/kernel into f14/user/steved/pnfs-f14
Conflicts:
	kernel.spec

Signed-off-by: Steve Dickson <steved@redhat.com>
2010-08-31 20:30:47 -04:00
Steve Dickson e4d5325720 Took out the localversion-pnfs file.
Signed-off-by: Steve Dickson <steved@redhat.com>
2010-08-31 20:28:51 -04:00
Steve Dickson bffee47a5b Updated to the latest pNFS tag: pnfs-all-2.6.35-2010-08-19
Signed-off-by: Steve Dickson <steved@redhat.com>
2010-08-31 20:28:51 -04:00
Kyle McMartin 3c5d4de07c add in patch from lmacken to support more mac models with efifb 2010-08-31 17:23:33 -04:00
Dave Jones 90303f9462 bump release 2010-08-31 11:45:25 -04:00
Dave Jones 10931f1112 Fix incorrect DMA size freeing error in via-velocity. 2010-08-31 11:44:00 -04:00
Chuck Ebbert 27e8302707 Drop obsolete ssb patch 2010-08-27 02:11:04 -04:00
Chuck Ebbert 8f132e348c kprobes-x86-fix-kprobes-to-skip-prefixes-correctly.patch (#610941) 2010-08-27 02:07:13 -04:00
Chuck Ebbert b30c150da1 Linux 2.6.35.4 2010-08-27 01:59:01 -04:00
Chuck Ebbert 3e8e94e0cd Linux 2.6.35.4-rc1
Fix up linux-2.6-i386-nx-emulation.patch for 2.6.35.4
2010-08-25 08:17:36 -04:00
Steve Dickson 2380b040ab Took out the localversion-pnfs file.
Signed-off-by: Steve Dickson <steved@redhat.com>
2010-08-24 14:53:51 -04:00
Chuck Ebbert 74e18cdf9e Linux 2.6.35.3
Drop merged patches:
   mm-fix-page-table-unmap-for-stack-guard-page-properly.patch
   mm-fix-up-some-user-visible-effects-of-the-stack-guard-page.patch
2010-08-21 00:29:58 -04:00
Steve Dickson a3dc221272 Updated to the latest pNFS tag: pnfs-all-2.6.35-2010-08-19
Signed-off-by: Steve Dickson <steved@redhat.com>
2010-08-19 21:39:23 -04:00
Dave Jones 4135368fb0 systemd is dependant upon autofs, so build it in instead of modular. 2010-08-18 19:41:03 -04:00
Chuck Ebbert 13dcde2426 fix duplicate patch numbers 2010-08-17 18:27:57 -04:00
Chuck Ebbert bfc8e84a86 Fix fallout from the stack guard page fixes.
(mm-fix-page-table-unmap-for-stack-guard-page-properly.patch,
 mm-fix-up-some-user-visible-effects-of-the-stack-guard-page.patch)
2010-08-17 18:26:23 -04:00
Kyle McMartin e2302e0109 create a /sys/fs/cgroup mountpoint for cgroupfs 2010-08-17 10:58:11 -04:00
Kyle McMartin 4cfceabb6c fix make local, see %changelog for description 2010-08-17 10:32:29 -04:00
Jarod Wilson b9878dcfec Add ir-core streamzap driver, drop lirc_streamzap
Signed-off-by: Jarod Wilson <jarod@redhat.com>
2010-08-16 11:57:58 -04:00
Chuck Ebbert e1151597d5 Linux 2.6.35.2 2010-08-15 04:26:48 -04:00
Chuck Ebbert d6d51a1a42 - Linux 2.6.35.2-rc1
- Comment out patches merged in -stable:
    linux-2.6-tip.git-396e894d289d69bacf5acd983c97cd6e21a14c08.patch
    linux-2.6-ext4-fix-freeze-deadlock.patch
- New config option:
    CONFIG_CRYPTO_MANAGER_TESTS=y
2010-08-13 07:47:42 -04:00
Chuck Ebbert 4ed348073c - Linux 2.6.35.1 2010-08-10 16:35:19 -04:00
Ben Skeggs 71e9b6763f nouveau: bring in misc fixes + fermi kms support 2010-08-10 11:43:52 +10:00
Chuck Ebbert 74b9092d38 Linux 2.6.35.1-rc1 2010-08-07 12:55:01 -04:00
Chuck Ebbert 9a98a7ebe3 Require newer linux-firmware package 2010-08-07 12:36:54 -04:00
Chuck Ebbert 6c58ce89ec Copy fix for bug #617699 from f13. 2010-08-06 15:34:00 -04:00
Chuck Ebbert 85a693ce78 Disable CONFIG_MULTICORE_RAID456 2010-08-05 14:22:55 -04:00
Dave Jones 4326aa56d8 sched: Revert nohz_ratelimit() which causes a lot of extra wakeups burning CPU, and my legs. 2010-08-04 15:06:07 -04:00
Chuck Ebbert 4d5b945030 Port shared source tree updates from f13. 2010-08-02 10:21:13 -04:00
Chuck Ebbert b6805461ca Merge branch 'master' into f14 2010-08-02 08:25:07 -04:00
Chuck Ebbert 557b0fb7c4 Merge branch 'f14/master' of ssh://pkgs.fedoraproject.org/kernel into f14 2010-08-02 08:14:45 -04:00
Dave Jones f8200febc9 Bump baserelease 2010-08-01 23:25:18 -04:00
Dave Jones 37cd8b7c4c .35 is a released kernel, so set it as such. 2010-08-01 20:57:07 -04:00
119 changed files with 352428 additions and 22211 deletions

View File

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

View File

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

View File

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

263
add-macbookair3-ids.patch Normal file
View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

2
config-local Normal file
View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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, &param->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

View File

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

54
drm-edid-invalid.patch Normal file
View File

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

57
drm-i2c-ch7006-fix.patch Normal file
View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

167
drm-nouveau-imac-g4.patch Normal file
View File

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

View File

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

231
drm-nouveau-nv86-bug.patch Normal file
View File

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

View File

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

View File

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

141
drm-nouveau-race-fix.patch Normal file
View File

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

601
drm-polling-fixes.patch Normal file
View File

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

View File

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

View File

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

592
drm-sil164-module.patch Normal file
View File

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

View File

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

View File

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

39
drm-ttm-fix.patch Normal file
View File

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

View File

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

View File

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

124
efifb-add-more-models.patch Normal file
View File

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

View File

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

View File

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

84
fix-i8k-inline-asm.patch Normal file
View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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, &params);
v4l2_subdev_call(dev->sd_ir, ir, rx_g_parameters, &params);
}
+
+ 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)) {

View File

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

View File

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

View File

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

View File

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

View File

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

196
linux-2.6-vzalloc.patch Normal file
View File

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

11
linux-2.6.35-inline.patch Normal file
View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

254
net-AF_PACKET-vmalloc.patch Normal file
View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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