x86/mm/pat, drivers/media/ivtv: Use arch_phys_wc_add() and require PAT disabled
We are burrying direct access to MTRR code support on x86 in order to take advantage of PAT. In the future, we also want to make the default behavior of ioremap_nocache() to use strong UC, at which point the use of mtrr_add() on those systems would make write-combining void. In order to help both enable us to later make strong UC default and in order to phase out direct MTRR access code, port the driver over to the arch_phys_wc_add() API and annotate that the device driver requires systems to boot with PAT disabled, with the 'nopat' kernel parameter. This is a workable compromise given that the hardware is really rare these days, and perhaps only some lost souls stuck with obsolete hardware are expected to be using this feature of the device driver. Signed-off-by: Luis R. Rodriguez <mcgrof@suse.com> Signed-off-by: Borislav Petkov <bp@suse.de> Acked-by: Andy Walls <awalls@md.metrocast.net> Acked-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com> Cc: Andrew Morton <akpm@linux-foundation.org> Cc: Andy Lutomirski <luto@amacapital.net> Cc: Antonino Daplas <adaplas@gmail.com> Cc: Arnd Bergmann <arnd@arndb.de> Cc: Borislav Petkov <bp@alien8.de> Cc: Brian Gerst <brgerst@gmail.com> Cc: Daniel Vetter <daniel.vetter@ffwll.ch> Cc: Dave Airlie <airlied@redhat.com> Cc: Dave Hansen <dave.hansen@linux.intel.com> Cc: Denys Vlasenko <dvlasenk@redhat.com> Cc: Doug Ledford <dledford@redhat.com> Cc: H. Peter Anvin <hpa@zytor.com> Cc: Jean-Christophe Plagniol-Villard <plagnioj@jcrosoft.com> Cc: Juergen Gross <jgross@suse.com> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Michael S. Tsirkin <mst@redhat.com> Cc: Oleg Nesterov <oleg@redhat.com> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Roger Pau Monné <roger.pau@citrix.com> Cc: Stefan Bader <stefan.bader@canonical.com> Cc: Suresh Siddha <sbsiddha@gmail.com> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: Ville Syrjälä <syrjala@sci.fi> Cc: bhelgaas@google.com Cc: konrad.wilk@oracle.com Cc: linux-media@vger.kernel.org Cc: tomi.valkeinen@ti.com Cc: toshi.kani@hp.com Link: http://lkml.kernel.org/r/1434053994-2196-2-git-send-email-mcgrof@do-not-panic.com Signed-off-by: Ingo Molnar <mingo@kernel.org>
This commit is contained in:
Родитель
957561ec0f
Коммит
1bf1735b47
|
@ -57,5 +57,8 @@ config VIDEO_FB_IVTV
|
|||
This is used in the Hauppauge PVR-350 card. There is a driver
|
||||
homepage at <http://www.ivtvdriver.org>.
|
||||
|
||||
In order to use this module, you will need to boot with PAT disabled
|
||||
on x86 systems, using the nopat kernel parameter.
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called ivtvfb.
|
||||
|
|
|
@ -44,8 +44,8 @@
|
|||
#include <linux/ivtvfb.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#ifdef CONFIG_MTRR
|
||||
#include <asm/mtrr.h>
|
||||
#ifdef CONFIG_X86_64
|
||||
#include <asm/pat.h>
|
||||
#endif
|
||||
|
||||
#include "ivtv-driver.h"
|
||||
|
@ -155,12 +155,11 @@ struct osd_info {
|
|||
/* Buffer size */
|
||||
u32 video_buffer_size;
|
||||
|
||||
#ifdef CONFIG_MTRR
|
||||
/* video_base rounded down as required by hardware MTRRs */
|
||||
unsigned long fb_start_aligned_physaddr;
|
||||
/* video_base rounded up as required by hardware MTRRs */
|
||||
unsigned long fb_end_aligned_physaddr;
|
||||
#endif
|
||||
int wc_cookie;
|
||||
|
||||
/* Store the buffer offset */
|
||||
int set_osd_coords_x;
|
||||
|
@ -1099,6 +1098,8 @@ static int ivtvfb_init_vidmode(struct ivtv *itv)
|
|||
static int ivtvfb_init_io(struct ivtv *itv)
|
||||
{
|
||||
struct osd_info *oi = itv->osd_info;
|
||||
/* Find the largest power of two that maps the whole buffer */
|
||||
int size_shift = 31;
|
||||
|
||||
mutex_lock(&itv->serialize_lock);
|
||||
if (ivtv_init_on_first_open(itv)) {
|
||||
|
@ -1132,29 +1133,16 @@ static int ivtvfb_init_io(struct ivtv *itv)
|
|||
oi->video_pbase, oi->video_vbase,
|
||||
oi->video_buffer_size / 1024);
|
||||
|
||||
#ifdef CONFIG_MTRR
|
||||
{
|
||||
/* Find the largest power of two that maps the whole buffer */
|
||||
int size_shift = 31;
|
||||
|
||||
while (!(oi->video_buffer_size & (1 << size_shift))) {
|
||||
size_shift--;
|
||||
}
|
||||
size_shift++;
|
||||
oi->fb_start_aligned_physaddr = oi->video_pbase & ~((1 << size_shift) - 1);
|
||||
oi->fb_end_aligned_physaddr = oi->video_pbase + oi->video_buffer_size;
|
||||
oi->fb_end_aligned_physaddr += (1 << size_shift) - 1;
|
||||
oi->fb_end_aligned_physaddr &= ~((1 << size_shift) - 1);
|
||||
if (mtrr_add(oi->fb_start_aligned_physaddr,
|
||||
oi->fb_end_aligned_physaddr - oi->fb_start_aligned_physaddr,
|
||||
MTRR_TYPE_WRCOMB, 1) < 0) {
|
||||
IVTVFB_INFO("disabled mttr\n");
|
||||
oi->fb_start_aligned_physaddr = 0;
|
||||
oi->fb_end_aligned_physaddr = 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
while (!(oi->video_buffer_size & (1 << size_shift)))
|
||||
size_shift--;
|
||||
size_shift++;
|
||||
oi->fb_start_aligned_physaddr = oi->video_pbase & ~((1 << size_shift) - 1);
|
||||
oi->fb_end_aligned_physaddr = oi->video_pbase + oi->video_buffer_size;
|
||||
oi->fb_end_aligned_physaddr += (1 << size_shift) - 1;
|
||||
oi->fb_end_aligned_physaddr &= ~((1 << size_shift) - 1);
|
||||
oi->wc_cookie = arch_phys_wc_add(oi->fb_start_aligned_physaddr,
|
||||
oi->fb_end_aligned_physaddr -
|
||||
oi->fb_start_aligned_physaddr);
|
||||
/* Blank the entire osd. */
|
||||
memset_io(oi->video_vbase, 0, oi->video_buffer_size);
|
||||
|
||||
|
@ -1172,14 +1160,7 @@ static void ivtvfb_release_buffers (struct ivtv *itv)
|
|||
|
||||
/* Release pseudo palette */
|
||||
kfree(oi->ivtvfb_info.pseudo_palette);
|
||||
|
||||
#ifdef CONFIG_MTRR
|
||||
if (oi->fb_end_aligned_physaddr) {
|
||||
mtrr_del(-1, oi->fb_start_aligned_physaddr,
|
||||
oi->fb_end_aligned_physaddr - oi->fb_start_aligned_physaddr);
|
||||
}
|
||||
#endif
|
||||
|
||||
arch_phys_wc_del(oi->wc_cookie);
|
||||
kfree(oi);
|
||||
itv->osd_info = NULL;
|
||||
}
|
||||
|
@ -1284,6 +1265,13 @@ static int __init ivtvfb_init(void)
|
|||
int registered = 0;
|
||||
int err;
|
||||
|
||||
#ifdef CONFIG_X86_64
|
||||
if (WARN(pat_enabled(),
|
||||
"ivtvfb needs PAT disabled, boot with nopat kernel parameter\n")) {
|
||||
return -ENODEV;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (ivtvfb_card_id < -1 || ivtvfb_card_id >= IVTV_MAX_CARDS) {
|
||||
printk(KERN_ERR "ivtvfb: ivtvfb_card_id parameter is out of range (valid range: -1 - %d)\n",
|
||||
IVTV_MAX_CARDS - 1);
|
||||
|
|
Загрузка…
Ссылка в новой задаче