Skip to content

Commit

Permalink
x86/mm/pat, drivers/media/ivtv: Use arch_phys_wc_add() and require PA…
Browse files Browse the repository at this point in the history
…T 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 <[email protected]>
Signed-off-by: Borislav Petkov <[email protected]>
Acked-by: Andy Walls <[email protected]>
Acked-by: Mauro Carvalho Chehab <[email protected]>
Cc: Andrew Morton <[email protected]>
Cc: Andy Lutomirski <[email protected]>
Cc: Antonino Daplas <[email protected]>
Cc: Arnd Bergmann <[email protected]>
Cc: Borislav Petkov <[email protected]>
Cc: Brian Gerst <[email protected]>
Cc: Daniel Vetter <[email protected]>
Cc: Dave Airlie <[email protected]>
Cc: Dave Hansen <[email protected]>
Cc: Denys Vlasenko <[email protected]>
Cc: Doug Ledford <[email protected]>
Cc: H. Peter Anvin <[email protected]>
Cc: Jean-Christophe Plagniol-Villard <[email protected]>
Cc: Juergen Gross <[email protected]>
Cc: Linus Torvalds <[email protected]>
Cc: Michael S. Tsirkin <[email protected]>
Cc: Oleg Nesterov <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Cc: Roger Pau Monné <[email protected]>
Cc: Stefan Bader <[email protected]>
Cc: Suresh Siddha <[email protected]>
Cc: Thomas Gleixner <[email protected]>
Cc: Ville Syrjälä <[email protected]>
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Ingo Molnar <[email protected]>
  • Loading branch information
mcgrof authored and Ingo Molnar committed Jun 18, 2015
1 parent 957561e commit 1bf1735
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 35 deletions.
3 changes: 3 additions & 0 deletions drivers/media/pci/ivtv/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -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.
58 changes: 23 additions & 35 deletions drivers/media/pci/ivtv/ivtvfb.c
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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)) {
Expand Down Expand Up @@ -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);

Expand All @@ -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;
}
Expand Down Expand Up @@ -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);
Expand Down

0 comments on commit 1bf1735

Please sign in to comment.