Age | Commit message (Collapse) | Author | Files | Lines |
|
Register ASoC HDMI codec for audio functionality and adds device tree
binding for audio configuration.
With the registered HDMI codec the tda998x node can be used like a
regular codec node in ASoC card configurations. HDMI audio info-frame
and audio stream header is generated by the ASoC HDMI codec. The codec
also applies constraints for available sample-rates based on Edid Like
Data from the display. The device tree binding document has been
updated [1].
Part of this patch has been inspired by Jean Francoise's "drm/i2c: tda998x:
Add support of a DT graph of ports"-patch [2]. There may still be some
identical lines left from the original patch and some of the ideas
have come from there.
[1] Documentation/devicetree/bindings/display/bridge/tda998x.txt
[2] http://mailman.alsa-project.org/pipermail/alsa-devel/2015-July/095255.html
Signed-off-by: Jyri Sarha <[email protected]>
Signed-off-by: Russell King <[email protected]>
|
|
Define struct tda998x_audio_params in include/drm/i2c/tda998x.h and
use it in pdata and for tda998x_configure_audio() parameters. Also
updates tda998x_write_aif() to take struct hdmi_audio_infoframe *
directly as a parameter.
Signed-off-by: Jyri Sarha <[email protected]>
Signed-off-by: Russell King <[email protected]>
|
|
called with private data") into drm-tda998x-devel
This commit is required for the TDA998x ASoC support, so to avoid build
errors, merge this commit into this branch prior to commiting Jiri's
patches.
Signed-off-by: Russell King <[email protected]>
|
|
This reverts commit 237ed86c693d8a8e4db476976aeb30df4deac74b.
Our current implementation of live status check (repeat 9 times
with 10ms delays between each attempt as a workaround for
buggy displays) imposes a rather serious penalty, time wise,
on intel_hdmi_detect(). Since we we already skip live status
checks on platforms before gen 7, and since we seem to have
coped quite well before the live status check was introduced
for newer platforms too, the previous behaviour is probably
preferable, at least unless someone can point to a use-case
that the live status check improves (apart from "Bspec says so".)
Signed-off-by: David Weinehall <[email protected]>
Fixes: 237ed86c693d ("drm/i915: Check live status before reading edid")
Fixes: f8d03ea0053b ("drm/i915: increase the tries for HDMI hotplug live status checking")
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=97139
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=94014
Acked-by: Chris Wilson <[email protected]>
Cc: [email protected] # v4.4+
Signed-off-by: Jani Nikula <[email protected]>
Link: http://patchwork.freedesktop.org/patch/msgid/[email protected]
|
|
i915 sometimes needs to disable planes in the middle of an atomic
commit, and then reenable them later in the same commit. Because of
this, we can't make the assumption that the state of the plane actually
changed. Since the state of the plane hasn't actually changed, neither
have it's watermarks. And if the watermarks hasn't changed then we
haven't populated skl_results with anything, which means we'll end up
zeroing out a plane's watermarks in the middle of the atomic commit
without restoring them later.
Simple reproduction recipe:
- Get a SKL laptop, launch any kind of X session
- Get two extra monitors
- Keep hotplugging both displays (so that the display configuration
jumps from 1 active pipe to 3 active pipes and back)
- Eventually underrun
Changes since v1:
- Fix incorrect use of "it's"
Changes since v2:
- Add reproduction recipe
Signed-off-by: Lyude <[email protected]>
Cc: Maarten Lankhorst <[email protected]>
Fixes: 62e0fb880123 ("drm/i915/skl: Update plane watermarks atomically during plane updates")
Signed-off-by: Lyude <[email protected]>
Testcase: kms_plane
Signed-off-by: Maarten Lankhorst <[email protected]>
Link: http://patchwork.freedesktop.org/patch/msgid/[email protected]
Cc: [email protected]
|
|
This reverts commit 77953bd136d2a70bca2dc93b3ccda07a2b37076f.
This causes a kernel panic when trying to assign a blob to a property,
and has obviously never been tested.
Fixes: 77953bd136d2 ("drm: Unify handling of blob and object properties")
Signed-off-by: Maarten Lankhorst <[email protected]>
Tested-by: Liu Ying <[email protected]>
Acked-by: Daniel Stone <[email protected]>
Signed-off-by: Jani Nikula <[email protected]>
Link: http://patchwork.freedesktop.org/patch/msgid/[email protected]
|
|
The usb_driver suspend and resume function pointers must be populated
to prevent forced unbinding of USB interface driver. See usb/core/driver.c:
unbind_no_pm_drivers_interfaces().
Restore mode and damage the entire frame buffer upon resume.
TEST=suspend and resume with the same UDL device connected
TEST=suspend with UDL, unplug UDL and resume
TEST=suspend with UDL, unplug and connect another UDL device then resume
Signed-off-by: Haixia Shi <[email protected]>
Reviewed-by: Stéphane Marchesin <[email protected]>
[seanpaul fixed checkpatch warnings and gave marcheu his é back]
Signed-off-by: Sean Paul <[email protected]>
Link: http://patchwork.freedesktop.org/patch/msgid/[email protected]
|
|
Use 1UL for unsigned long, or we'll meet a overflow issue with UBSAN.
[ 15.589489] UBSAN: Undefined behaviour in drivers/gpu/drm/drm_hashtab.c:145:35
[ 15.589500] signed integer overflow:
[ 15.589999] -2147483648 - 1 cannot be represented in type 'int'
[ 15.590434] CPU: 2 PID: 294 Comm: plymouthd Not tainted 3.10.0-327.28.3.el7.x86_64 #1
[ 15.590653] Hardware name: VMware, Inc. VMware Virtual Platform/440BX Desktop Reference Platform, BIOS 6.00 01/07/2011
[ 15.591001] 1ffff1000670fe83 000000000d6b385e ffff88003387f3e0 ffffffff81ee3140
[ 15.591028] ffff88003387f3f8 ffffffff81ee31fd ffffffffa032f460 ffff88003387f560
[ 15.591044] ffffffff81ee46e2 0000002d00000009 0000000000000001 0000000041b58ab3
[ 15.591059] Call Trace:
[ 15.591078] [<ffffffff81ee3140>] dump_stack+0x1e/0x20
[ 15.591093] [<ffffffff81ee31fd>] ubsan_epilogue+0x12/0x55
[ 15.591109] [<ffffffff81ee46e2>] handle_overflow+0x1ba/0x215
[ 15.591126] [<ffffffff81ee4528>] ? __ubsan_handle_negate_overflow+0x162/0x162
[ 15.591146] [<ffffffff8103416c>] ? print_context_stack+0x9c/0x160
[ 15.591163] [<ffffffff81031df2>] ? dump_trace+0x252/0x750
[ 15.591181] [<ffffffff81739023>] ? __list_add+0x93/0x160
[ 15.591197] [<ffffffff81ee4798>] __ubsan_handle_sub_overflow+0x2a/0x31
[ 15.591261] [<ffffffffa0282140>] drm_ht_just_insert_please+0x1e0/0x200 [drm]
[ 15.591290] [<ffffffffa0528c7a>] ttm_base_object_init+0x10a/0x270 [ttm]
[ 15.591316] [<ffffffffa052a34c>] ttm_vt_lock+0x28c/0x3a0 [ttm]
[ 15.591343] [<ffffffffa052a0c0>] ? ttm_write_lock+0x180/0x180 [ttm]
[ 15.591362] [<ffffffff81419526>] ? kasan_unpoison_shadow+0x36/0x50
[ 15.591379] [<ffffffff81419526>] ? kasan_unpoison_shadow+0x36/0x50
[ 15.591396] [<ffffffff81419526>] ? kasan_unpoison_shadow+0x36/0x50
[ 15.591413] [<ffffffff81419526>] ? kasan_unpoison_shadow+0x36/0x50
[ 15.591442] [<ffffffffa061cbe1>] vmw_master_set+0x121/0x470 [vmwgfx]
[ 15.591459] [<ffffffff811773a5>] ? __init_waitqueue_head+0x45/0x70
[ 15.591487] [<ffffffffa061cac0>] ? vmw_master_drop+0x310/0x310 [vmwgfx]
[ 15.591535] [<ffffffffa026946a>] drm_open+0x92a/0xc00 [drm]
[ 15.591563] [<ffffffffa0619ff0>] ? vmw_driver_open+0x170/0x170 [vmwgfx]
[ 15.591610] [<ffffffffa0268b40>] ? drm_poll+0xe0/0xe0 [drm]
[ 15.591661] [<ffffffffa02797b4>] drm_stub_open+0x224/0x330 [drm]
[ 15.591711] [<ffffffffa0279590>] ? drm_minor_acquire+0x240/0x240 [drm]
[ 15.591727] [<ffffffff8145fa8a>] chrdev_open+0x1fa/0x3f0
[ 15.591742] [<ffffffff8145f890>] ? cdev_put+0x50/0x50
[ 15.591761] [<ffffffff814f6dc3>] ? __fsnotify_parent+0x53/0x210
[ 15.591778] [<ffffffff8144fde1>] do_dentry_open+0x351/0x670
[ 15.591792] [<ffffffff8145f890>] ? cdev_put+0x50/0x50
[ 15.591807] [<ffffffff814503c2>] vfs_open+0xa2/0x170
[ 15.591824] [<ffffffff8147b5df>] do_last+0xccf/0x2c80
[ 15.591842] [<ffffffff8147a910>] ? filename_create+0x320/0x320
[ 15.591858] [<ffffffff81472549>] ? path_init+0x1b9/0xa90
[ 15.591875] [<ffffffff81472390>] ? mountpoint_last+0x9a0/0x9a0
[ 15.591894] [<ffffffff815f9ccf>] ? selinux_file_alloc_security+0xcf/0x130
[ 15.591911] [<ffffffff8147d777>] path_openat+0x1e7/0xcc0
[ 15.591927] [<ffffffff81031df2>] ? dump_trace+0x252/0x750
[ 15.591943] [<ffffffff8147d590>] ? do_last+0x2c80/0x2c80
[ 15.591959] [<ffffffff81739023>] ? __list_add+0x93/0x160
[ 15.591974] [<ffffffff8104b48d>] ? save_stack_trace+0x7d/0xb0
[ 15.591989] [<ffffffff81480824>] do_filp_open+0xa4/0x160
[ 15.592004] [<ffffffff81480780>] ? user_path_mountpoint_at+0x50/0x50
[ 15.592022] [<ffffffff8149d755>] ? __alloc_fd+0x175/0x300
[ 15.592039] [<ffffffff81453127>] do_sys_open+0x1b7/0x3f0
[ 15.592054] [<ffffffff81452f70>] ? filp_open+0x80/0x80
[ 15.592070] [<ffffffff81453392>] SyS_open+0x32/0x40
[ 15.592088] [<ffffffff81f08989>] system_call_fastpath+0x16/0x1b
Signed-off-by: Xie XiuQi <[email protected]>
[seanpaul tweaked subject to remove "gpu/"]
Signed-off-by: Sean Paul <[email protected]>
Link: http://patchwork.freedesktop.org/patch/msgid/[email protected]
|
|
The legacy setprop ioctl doesn't attempt to set properties
that are not enumerated on the object. The atomic ioctl does,
fix this by validating first.
Signed-off-by: Maarten Lankhorst <[email protected]>
Signed-off-by: Sean Paul <[email protected]>
Link: http://patchwork.freedesktop.org/patch/msgid/1473062773-5045-1-git-send-email-maarten.lankhorst@linux.intel.com
|
|
We don't have safe 64-bit mmio writes as they are really split into
2x32-bit writes. This tearing is dangerous as the hardware *will*
operate on the intermediate value, requiring great care when assigning.
(See, for example, i965_write_fence_reg.) As such we don't currently use
them and strongly advise not to us them. Go one step further and remove
the 64-bit write vfuncs.
v2: Add some more details to the comment about why WRITE64 is absent,
and why you need to think twice before using READ64.
Signed-off-by: Chris Wilson <[email protected]>
Reviewed-by: Joonas Lahtinen <[email protected]>
Link: http://patchwork.freedesktop.org/patch/msgid/[email protected]
|
|
Disable 48bit full PPGTT on vGPU too for now.
Signed-off-by: Zhi Wang <[email protected]>
Signed-off-by: Zhenyu Wang <[email protected]>
Reviewed-by: Joonas Lahtinen <[email protected]>
Acked-by: Chris Wilson <[email protected]>
Cc: [email protected]
Signed-off-by: Jani Nikula <[email protected]>
Link: http://patchwork.freedesktop.org/patch/msgid/[email protected]
|
|
vGPU capability is handled by GVT-g host driver, not needed to
put extra HW check for vGPU detection. And we'll actually support
vGPU from BDW.
Signed-off-by: Ping Gao <[email protected]>
Signed-off-by: Zhenyu Wang <[email protected]>
Reviewed-by: Joonas Lahtinen <[email protected]>
Acked-by: Chris Wilson <[email protected]>
Cc: [email protected]
Signed-off-by: Jani Nikula <[email protected]>
Link: http://patchwork.freedesktop.org/patch/msgid/[email protected]
|
|
If we can't grab the breadcrumb's spinlock, possibly due to a driver
deadlock inside the waiters, ignore them. Like hangcheck, error
capturing must work no matter how the driver/GPU dies.
Signed-off-by: Chris Wilson <[email protected]>
Link: http://patchwork.freedesktop.org/patch/msgid/[email protected]
Reviewed-by: Joonas Lahtinen <[email protected]>
|
|
Some downgraded from DRM_ERROR() to DRM_WARN() or DRM_NOTE(),
a few upgraded from DRM_INFO() to DRM_NOTE() or DRM_WARN(),
and one eliminated completely.
v2: different permutation of levels :)
v3: convert a couple of "this shouldn't happen" messages to WARN()
Signed-off-by: Dave Gordon <[email protected]>
Reviewed-by: Tvrtko Ursulin <[email protected]>
Signed-off-by: Tvrtko Ursulin <[email protected]>
|
|
Where we're going to continue regardless of the problem, rather than
fail, then the message should be a WARNing rather than an ERROR.
Signed-off-by: Dave Gordon <[email protected]>
Reviewed-by: Tvrtko Ursulin <[email protected]>
Signed-off-by: Tvrtko Ursulin <[email protected]>
|
|
We had only DRM_INFO() and DRM_ERROR(), whereas the underlying printk()
provides several other useful intermediate levels such as NOTICE and
WARNING. So this patch fills out the set by providing both regular and
once-only macros for each of the levels INFO, NOTICE, and WARNING, using
a common underlying macro that does all the token-pasting.
DRM_ERROR is unchanged, as it's not just a printk wrapper.
v2:
Fix whitespace, missing ## (Eric Engestrom)
Signed-off-by: Dave Gordon <[email protected]>
Reviewed-by: Eric Engestrom <[email protected]>
Cc: [email protected]
Acked-by: Dave Airlie <[email protected]>
Signed-off-by: Tvrtko Ursulin <[email protected]>
|
|
i915_gem_interrupt_info() only looks at mmio registers, and the waiters
under a spinlock. It doesn't need struct_mutex (but does need the rpm
wakelock for mmio access). Maybe useful using get_if_notidle?
Signed-off-by: Chris Wilson <[email protected]>
Link: http://patchwork.freedesktop.org/patch/msgid/[email protected]
Reviewed-by: Matthew Auld <[email protected]>
|
|
i915_gem_seqno_info() supplies its own spinlocks to access the waiters,
and doesn't need any GGTT or mmio access.
Signed-off-by: Chris Wilson <[email protected]>
Link: http://patchwork.freedesktop.org/patch/msgid/[email protected]
Reviewed-by: Matthew Auld <[email protected]>
|
|
Signed-off-by: Tom St Denis <[email protected]>
Reviewed-by: Alex Deucher <[email protected]>
Reviewed-by: Christian König <[email protected]>
Signed-off-by: Alex Deucher <[email protected]>
|
|
Signed-off-by: Tom St Denis <[email protected]>
Reviewed-by: Alex Deucher <[email protected]>
Reviewed-by: Christian König <[email protected]>
Signed-off-by: Alex Deucher <[email protected]>
|
|
Signed-off-by: Tom St Denis <[email protected]>
Reviewed-by: Alex Deucher <[email protected]>
Reviewed-by: Christian König <[email protected]>
Signed-off-by: Alex Deucher <[email protected]>
|
|
Signed-off-by: Tom St Denis <[email protected]>
Reviewed-by: Alex Deucher <[email protected]>
Reviewed-by: Christian König <[email protected]>
Signed-off-by: Alex Deucher <[email protected]>
|
|
Various whitespace and logical simplifications for gfx6.
Signed-off-by: Tom St Denis <[email protected]>
Reviewed-by: Christian König <[email protected]>
Signed-off-by: Alex Deucher <[email protected]>
|
|
Signed-off-by: Tom St Denis <[email protected]>
Reviewed-by: Christian König <[email protected]>
Signed-off-by: Alex Deucher <[email protected]>
|
|
Add missing lock around SE/SH/INSTANCE selections.
Signed-off-by: Tom St Denis <[email protected]>
Reviewed-by: Christian König <[email protected]>
Signed-off-by: Alex Deucher <[email protected]>
|
|
power state table was set based on vbios and should not be changed.
when client need to change power state, just make a copy and send to
smu.
Signed-off-by: Rex Zhu <[email protected]>
Reviewed-by: Alex Deucher <[email protected]>
Signed-off-by: Alex Deucher <[email protected]>
|
|
delete useless member.
Signed-off-by: Rex Zhu <[email protected]>
Reviewed-by: Alex Deucher <[email protected]>
Signed-off-by: Alex Deucher <[email protected]>
|
|
Signed-off-by: Rex Zhu <[email protected]>
Reviewed-by: Alex Deucher <[email protected]>
Signed-off-by: Alex Deucher <[email protected]>
|
|
Signed-off-by: Rex Zhu <[email protected]>
Reviewed-by: Alex Deucher <[email protected]>
Signed-off-by: Alex Deucher <[email protected]>
|
|
As last resort try to evict BOs from the current working set into other
memory domains. This effectively prevents command submission failures when
VM page tables have been swapped out.
v2: fix typos
Signed-off-by: Christian König <[email protected]>
Reviewed-by: Alex Deucher <[email protected]>
Signed-off-by: Alex Deucher <[email protected]>
|
|
All other errors can't be fixed by using a different memory domain.
Signed-off-by: Christian König <[email protected]>
Reviewed-by: Alex Deucher <[email protected]>
Signed-off-by: Alex Deucher <[email protected]>
|
|
Currently when checking for fused off EUs we may ignore the EU count in
an enabled slice if there is any disabled slice preceding the enabled
one (with a lower slice ID). Perhaps this can't happen in reality, but
there is no reason to have this assumption built-in, the code is clearer
without it.
Reviewed-by: Robert Bragg <[email protected]>
Reviewed-by: Ben Widawsky <[email protected]>
Tested-by: Ben Widawsky <[email protected]>
Signed-off-by: Imre Deak <[email protected]>
Link: http://patchwork.freedesktop.org/patch/msgid/[email protected]
|
|
Reviewed-by: Robert Bragg <[email protected]>
Reviewed-by: Ben Widawsky <[email protected]>
Tested-by: Ben Widawsky <[email protected]>
Signed-off-by: Imre Deak <[email protected]>
Link: http://patchwork.freedesktop.org/patch/msgid/[email protected]
|
|
In an upcoming patch we'll need the actual mask of subslices in addition
to their count, so convert the subslice_per_slice field to a mask.
Also we can easily calculate subslice_total from the other fields, so
instead of storing a cached version of this, add a helper to calculate
it.
v2:
- Use hweight8() on u8 typed vars instead of hweight32(). (Ben)
Reviewed-by: Robert Bragg <[email protected]> (v1)
Reviewed-by: Ben Widawsky <[email protected]> (v1)
Tested-by: Ben Widawsky <[email protected]> (v1)
Signed-off-by: Imre Deak <[email protected]>
|
|
In an upcoming patch we'll need the actual mask of slices in addition to
their count, so replace the count field with a mask.
v2:
- Use hweight8() on u8 typed vars instead of hweight32(). (Ben)
Reviewed-by: Robert Bragg <[email protected]> (v1)
Reviewed-by: Ben Widawsky <[email protected]> (v1)
Tested-by: Ben Widawsky <[email protected]> (v1)
Signed-off-by: Imre Deak <[email protected]>
Link: http://patchwork.freedesktop.org/patch/msgid/[email protected]
|
|
Reviewed-by: Robert Bragg <[email protected]>
Reviewed-by: Ben Widawsky <[email protected]>
Tested-by: Ben Widawsky <[email protected]>
Signed-off-by: Imre Deak <[email protected]>
Link: http://patchwork.freedesktop.org/patch/msgid/[email protected]
|
|
Move all slice/subslice/eu related properties to the sseu_dev_info
struct.
No functional change.
v2:
- s/info/sseu/ based on the new struct name. (Ben)
Reviewed-by: Robert Bragg <[email protected]> (v1)
Reviewed-by: Ben Widawsky <[email protected]> (v1)
Tested-by: Ben Widawsky <[email protected]> (v1)
Signed-off-by: Imre Deak <[email protected]>
|
|
The data in this struct is provided both by getting the
slice/subslice/eu features available on a given platform and the actual
runtime state of these same features which depends on the HW's current
power saving state.
Atm members of this struct are duplicated in sseu_dev_status and
intel_device_info. For clarity and code reuse we can share one struct
for both of the above purposes. This patch only moves the struct to the
header file, the next patch will convert users of intel_device_info to
use this struct too.
Instead of unsigned int u8 is used now, which is big enough and is used
anyway in intel_device_info.
No functional change.
v2:
- s/stat/sseu/ based on the new struct name (Ben)
Reviewed-by: Robert Bragg <[email protected]> (v1)
Reviewed-by: Ben Widawsky <[email protected]> (v1)
Tested-by: Ben Widawsky <[email protected]> (v1)
Signed-off-by: Imre Deak <[email protected]>
Link: http://patchwork.freedesktop.org/patch/msgid/[email protected]
|
|
Normally on shutdown or reboot we don't care about necessarily
making sure the hw is in a good state because the system is about
to be powered down or reset. However, after a shutdown or reboot
in a VM, it's best to tear down the hw properly otherwise there
can be problems with the next VM use.
Reviewed-by: Christian König <[email protected]>
Reviewed-by: Edward O'Callaghan <[email protected]>
Signed-off-by: Alex Deucher <[email protected]>
|
|
Normally on shutdown or reboot we don't care about necessarily
making sure the hw is in a good state because the system is about
to be powered down or reset. However, after a shutdown or reboot
in a VM, it's best to tear down the hw properly otherwise there
can be problems with the next VM use.
Reviewed-by: Christian König <[email protected]>
Reviewed-by: Edward O'Callaghan <[email protected]>
Signed-off-by: Alex Deucher <[email protected]>
|
|
Close was not handled correctly.
Reviewed-by: Michel Dänzer <[email protected]>
Signed-off-by: Alex Deucher <[email protected]>
|
|
Close was not handled correctly.
Reviewed-by: Michel Dänzer <[email protected]>
Signed-off-by: Alex Deucher <[email protected]>
|
|
Need to fix the error paths.
Reviewed-by: Michel Dänzer <[email protected]>
Signed-off-by: Alex Deucher <[email protected]>
|
|
Need to fix the error paths.
Reviewed-by: Michel Dänzer <[email protected]>
Signed-off-by: Alex Deucher <[email protected]>
|
|
Missed this case previously. No need to do anything if the
device is already off. runtime pm will handle it.
Acked-by: Michel Dänzer <[email protected]>
Signed-off-by: Alex Deucher <[email protected]>
|
|
The sbios always powers up the dGPU on resume.
Acked-by: Michel Dänzer <[email protected]>
Signed-off-by: Alex Deucher <[email protected]>
|
|
Missed this case previously. No need to do anything if the
device is already off. runtime pm will handle it.
Acked-by: Michel Dänzer <[email protected]>
Signed-off-by: Alex Deucher <[email protected]>
|
|
The sbios always powers up the dGPU on resume.
Acked-by: Michel Dänzer <[email protected]>
Signed-off-by: Alex Deucher <[email protected]>
|
|
The mqd is only used on CI and newer.
Reviewed-by: Edward O'Callaghan <[email protected]>
Signed-off-by: Alex Deucher <[email protected]>
|
|
Rather than having a separate case for each value where we just return
a hardcoded value = 1, we lump them all together and rely on the awesome
case-fallthrough feature of C.
Fix all feature macros to pass dev_priv instead of dev while at it,
and use INTEL_GEN() instead of INTEL_INFO()->gen.
Signed-off-by: David Weinehall <[email protected]>
Link: http://patchwork.freedesktop.org/patch/msgid/[email protected]
Reviewed-by: Chris Wilson <[email protected]>
Signed-off-by: Chris Wilson <[email protected]>
|