Merge branch 'x86-mm-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull x86 mm updates from Ingo Molnar: "The dominant change in this cycle was the continued work to isolate kernel drivers from MTRR legacies: this tree gets rid of all kernel internal driver interfaces to MTRRs (mostly by rewriting it to proper PAT interfaces), the only access left is the /proc/mtrr ABI. This work was done by Luis R Rodriguez. There's also some related PCI interface additions for which I've Cc:-ed Bjorn" * 'x86-mm-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (21 commits) x86/mm/mtrr: Remove kernel internal MTRR interfaces: unexport mtrr_add() and mtrr_del() s390/io: Add pci_iomap_wc() and pci_iomap_wc_range() drivers/dma/iop-adma: Use dma_alloc_writecombine() kernel-style drivers/video/fbdev/vt8623fb: Use arch_phys_wc_add() and pci_iomap_wc() drivers/video/fbdev/s3fb: Use arch_phys_wc_add() and pci_iomap_wc() drivers/video/fbdev/arkfb.c: Use arch_phys_wc_add() and pci_iomap_wc() PCI: Add pci_iomap_wc() variants drivers/video/fbdev/gxt4500: Use pci_ioremap_wc_bar() to map framebuffer drivers/video/fbdev/kyrofb: Use arch_phys_wc_add() and pci_ioremap_wc_bar() drivers/video/fbdev/i740fb: Use arch_phys_wc_add() and pci_ioremap_wc_bar() PCI: Add pci_ioremap_wc_bar() x86/mm: Make kernel/check.c explicitly non-modular x86/mm/pat: Make mm/pageattr[-test].c explicitly non-modular x86/mm/pat: Add comments to cachemode translation tables arch/*/io.h: Add ioremap_uc() to all architectures drivers/video/fbdev/atyfb: Use arch_phys_wc_add() and ioremap_wc() drivers/video/fbdev/atyfb: Replace MTRR UC hole with strong UC drivers/video/fbdev/atyfb: Clarify ioremap() base and length used drivers/video/fbdev/atyfb: Carve out framebuffer length fudging into a helper x86/mm, asm-generic: Add IOMMU ioremap_uc() variant default ...
This commit is contained in:
commit
25525bea46
|
@ -6,10 +6,22 @@ Luis R. Rodriguez <mcgrof@do-not-panic.com> - April 9, 2015
|
||||||
===============================================================================
|
===============================================================================
|
||||||
Phasing out MTRR use
|
Phasing out MTRR use
|
||||||
|
|
||||||
MTRR use is replaced on modern x86 hardware with PAT. Over time the only type
|
MTRR use is replaced on modern x86 hardware with PAT. Direct MTRR use by
|
||||||
of effective MTRR that is expected to be supported will be for write-combining.
|
drivers on Linux is now completely phased out, device drivers should use
|
||||||
As MTRR use is phased out device drivers should use arch_phys_wc_add() to make
|
arch_phys_wc_add() in combination with ioremap_wc() to make MTRR effective on
|
||||||
MTRR effective on non-PAT systems while a no-op on PAT enabled systems.
|
non-PAT systems while a no-op but equally effective on PAT enabled systems.
|
||||||
|
|
||||||
|
Even if Linux does not use MTRRs directly, some x86 platform firmware may still
|
||||||
|
set up MTRRs early before booting the OS. They do this as some platform
|
||||||
|
firmware may still have implemented access to MTRRs which would be controlled
|
||||||
|
and handled by the platform firmware directly. An example of platform use of
|
||||||
|
MTRRs is through the use of SMI handlers, one case could be for fan control,
|
||||||
|
the platform code would need uncachable access to some of its fan control
|
||||||
|
registers. Such platform access does not need any Operating System MTRR code in
|
||||||
|
place other than mtrr_type_lookup() to ensure any OS specific mapping requests
|
||||||
|
are aligned with platform MTRR setup. If MTRRs are only set up by the platform
|
||||||
|
firmware code though and the OS does not make any specific MTRR mapping
|
||||||
|
requests mtrr_type_lookup() should always return MTRR_TYPE_INVALID.
|
||||||
|
|
||||||
For details refer to Documentation/x86/pat.txt.
|
For details refer to Documentation/x86/pat.txt.
|
||||||
|
|
||||||
|
|
|
@ -297,6 +297,7 @@ extern void __iounmap(void __iomem *addr);
|
||||||
|
|
||||||
#define ioremap_wc ioremap_nocache
|
#define ioremap_wc ioremap_nocache
|
||||||
#define ioremap_wt ioremap_nocache
|
#define ioremap_wt ioremap_nocache
|
||||||
|
#define ioremap_uc ioremap_nocache
|
||||||
|
|
||||||
#define cached(addr) P1SEGADDR(addr)
|
#define cached(addr) P1SEGADDR(addr)
|
||||||
#define uncached(addr) P2SEGADDR(addr)
|
#define uncached(addr) P2SEGADDR(addr)
|
||||||
|
|
|
@ -278,6 +278,7 @@ static inline void __iomem *ioremap_fullcache(unsigned long physaddr, unsigned l
|
||||||
}
|
}
|
||||||
|
|
||||||
#define ioremap_wc ioremap_nocache
|
#define ioremap_wc ioremap_nocache
|
||||||
|
#define ioremap_uc ioremap_nocache
|
||||||
|
|
||||||
extern void iounmap(void volatile __iomem *addr);
|
extern void iounmap(void volatile __iomem *addr);
|
||||||
|
|
||||||
|
|
|
@ -69,6 +69,7 @@ extern void iounmap(volatile void __iomem *addr);
|
||||||
#define ioremap_nocache(off,size) ioremap(off,size)
|
#define ioremap_nocache(off,size) ioremap(off,size)
|
||||||
#define ioremap_wc ioremap_nocache
|
#define ioremap_wc ioremap_nocache
|
||||||
#define ioremap_wt ioremap_nocache
|
#define ioremap_wt ioremap_nocache
|
||||||
|
#define ioremap_uc ioremap_nocache
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* IO bus memory addresses are also 1:1 with the physical address
|
* IO bus memory addresses are also 1:1 with the physical address
|
||||||
|
|
|
@ -468,6 +468,7 @@ static inline void __iomem *ioremap_nocache(unsigned long physaddr, unsigned lon
|
||||||
{
|
{
|
||||||
return __ioremap(physaddr, size, IOMAP_NOCACHE_SER);
|
return __ioremap(physaddr, size, IOMAP_NOCACHE_SER);
|
||||||
}
|
}
|
||||||
|
#define ioremap_uc ioremap_nocache
|
||||||
static inline void __iomem *ioremap_wt(unsigned long physaddr,
|
static inline void __iomem *ioremap_wt(unsigned long physaddr,
|
||||||
unsigned long size)
|
unsigned long size)
|
||||||
{
|
{
|
||||||
|
|
|
@ -283,6 +283,7 @@ static inline void __iomem *ioremap_nocache(unsigned long offset, unsigned long
|
||||||
|
|
||||||
#define ioremap_wc ioremap_nocache
|
#define ioremap_wc ioremap_nocache
|
||||||
#define ioremap_wt ioremap_nocache
|
#define ioremap_wt ioremap_nocache
|
||||||
|
#define ioremap_uc ioremap_nocache
|
||||||
|
|
||||||
static inline void iounmap(void __iomem *addr)
|
static inline void iounmap(void __iomem *addr)
|
||||||
{
|
{
|
||||||
|
|
|
@ -721,6 +721,7 @@ extern void __iomem *ioremap_prot(phys_addr_t address, unsigned long size,
|
||||||
unsigned long flags);
|
unsigned long flags);
|
||||||
extern void __iomem *ioremap_wc(phys_addr_t address, unsigned long size);
|
extern void __iomem *ioremap_wc(phys_addr_t address, unsigned long size);
|
||||||
#define ioremap_nocache(addr, size) ioremap((addr), (size))
|
#define ioremap_nocache(addr, size) ioremap((addr), (size))
|
||||||
|
#define ioremap_uc(addr, size) ioremap((addr), (size))
|
||||||
|
|
||||||
extern void iounmap(volatile void __iomem *addr);
|
extern void iounmap(volatile void __iomem *addr);
|
||||||
|
|
||||||
|
|
|
@ -57,6 +57,8 @@ static inline void ioport_unmap(void __iomem *p)
|
||||||
*/
|
*/
|
||||||
#define pci_iomap pci_iomap
|
#define pci_iomap pci_iomap
|
||||||
#define pci_iounmap pci_iounmap
|
#define pci_iounmap pci_iounmap
|
||||||
|
#define pci_iomap_wc pci_iomap
|
||||||
|
#define pci_iomap_wc_range pci_iomap_range
|
||||||
|
|
||||||
#define memcpy_fromio(dst, src, count) zpci_memcpy_fromio(dst, src, count)
|
#define memcpy_fromio(dst, src, count) zpci_memcpy_fromio(dst, src, count)
|
||||||
#define memcpy_toio(dst, src, count) zpci_memcpy_toio(dst, src, count)
|
#define memcpy_toio(dst, src, count) zpci_memcpy_toio(dst, src, count)
|
||||||
|
|
|
@ -368,6 +368,7 @@ static inline int iounmap_fixed(void __iomem *addr) { return -EINVAL; }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define ioremap_nocache ioremap
|
#define ioremap_nocache ioremap
|
||||||
|
#define ioremap_uc ioremap
|
||||||
#define iounmap __iounmap
|
#define iounmap __iounmap
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -55,6 +55,7 @@ extern void iounmap(volatile void __iomem *addr);
|
||||||
#define ioremap_nocache(physaddr, size) ioremap(physaddr, size)
|
#define ioremap_nocache(physaddr, size) ioremap(physaddr, size)
|
||||||
#define ioremap_wc(physaddr, size) ioremap(physaddr, size)
|
#define ioremap_wc(physaddr, size) ioremap(physaddr, size)
|
||||||
#define ioremap_wt(physaddr, size) ioremap(physaddr, size)
|
#define ioremap_wt(physaddr, size) ioremap(physaddr, size)
|
||||||
|
#define ioremap_uc(physaddr, size) ioremap(physaddr, size)
|
||||||
#define ioremap_fullcache(physaddr, size) ioremap(physaddr, size)
|
#define ioremap_fullcache(physaddr, size) ioremap(physaddr, size)
|
||||||
|
|
||||||
#define mmiowb()
|
#define mmiowb()
|
||||||
|
|
|
@ -180,6 +180,8 @@ static inline unsigned int isa_virt_to_bus(volatile void *address)
|
||||||
*/
|
*/
|
||||||
extern void __iomem *ioremap_nocache(resource_size_t offset, unsigned long size);
|
extern void __iomem *ioremap_nocache(resource_size_t offset, unsigned long size);
|
||||||
extern void __iomem *ioremap_uc(resource_size_t offset, unsigned long size);
|
extern void __iomem *ioremap_uc(resource_size_t offset, unsigned long size);
|
||||||
|
#define ioremap_uc ioremap_uc
|
||||||
|
|
||||||
extern void __iomem *ioremap_cache(resource_size_t offset, unsigned long size);
|
extern void __iomem *ioremap_cache(resource_size_t offset, unsigned long size);
|
||||||
extern void __iomem *ioremap_prot(resource_size_t offset, unsigned long size,
|
extern void __iomem *ioremap_prot(resource_size_t offset, unsigned long size,
|
||||||
unsigned long prot_val);
|
unsigned long prot_val);
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#include <linux/module.h>
|
#include <linux/init.h>
|
||||||
#include <linux/sched.h>
|
#include <linux/sched.h>
|
||||||
#include <linux/kthread.h>
|
#include <linux/kthread.h>
|
||||||
#include <linux/workqueue.h>
|
#include <linux/workqueue.h>
|
||||||
|
@ -163,6 +163,5 @@ static int start_periodic_check_for_corruption(void)
|
||||||
schedule_delayed_work(&bios_check_work, 0);
|
schedule_delayed_work(&bios_check_work, 0);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
device_initcall(start_periodic_check_for_corruption);
|
||||||
module_init(start_periodic_check_for_corruption);
|
|
||||||
|
|
||||||
|
|
|
@ -448,7 +448,6 @@ int mtrr_add(unsigned long base, unsigned long size, unsigned int type,
|
||||||
return mtrr_add_page(base >> PAGE_SHIFT, size >> PAGE_SHIFT, type,
|
return mtrr_add_page(base >> PAGE_SHIFT, size >> PAGE_SHIFT, type,
|
||||||
increment);
|
increment);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(mtrr_add);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* mtrr_del_page - delete a memory type region
|
* mtrr_del_page - delete a memory type region
|
||||||
|
@ -537,7 +536,6 @@ int mtrr_del(int reg, unsigned long base, unsigned long size)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
return mtrr_del_page(reg, base >> PAGE_SHIFT, size >> PAGE_SHIFT);
|
return mtrr_del_page(reg, base >> PAGE_SHIFT, size >> PAGE_SHIFT);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(mtrr_del);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* arch_phys_wc_add - add a WC MTRR and handle errors if PAT is unavailable
|
* arch_phys_wc_add - add a WC MTRR and handle errors if PAT is unavailable
|
||||||
|
|
|
@ -30,8 +30,11 @@
|
||||||
/*
|
/*
|
||||||
* Tables translating between page_cache_type_t and pte encoding.
|
* Tables translating between page_cache_type_t and pte encoding.
|
||||||
*
|
*
|
||||||
* Minimal supported modes are defined statically, they are modified
|
* The default values are defined statically as minimal supported mode;
|
||||||
* during bootup if more supported cache modes are available.
|
* WC and WT fall back to UC-. pat_init() updates these values to support
|
||||||
|
* more cache modes, WC and WT, when it is safe to do so. See pat_init()
|
||||||
|
* for the details. Note, __early_ioremap() used during early boot-time
|
||||||
|
* takes pgprot_t (pte encoding) and does not use these tables.
|
||||||
*
|
*
|
||||||
* Index into __cachemode2pte_tbl[] is the cachemode.
|
* Index into __cachemode2pte_tbl[] is the cachemode.
|
||||||
*
|
*
|
||||||
|
|
|
@ -137,6 +137,7 @@ page_table_range_init_count(unsigned long start, unsigned long end)
|
||||||
|
|
||||||
vaddr = start;
|
vaddr = start;
|
||||||
pgd_idx = pgd_index(vaddr);
|
pgd_idx = pgd_index(vaddr);
|
||||||
|
pmd_idx = pmd_index(vaddr);
|
||||||
|
|
||||||
for ( ; (pgd_idx < PTRS_PER_PGD) && (vaddr != end); pgd_idx++) {
|
for ( ; (pgd_idx < PTRS_PER_PGD) && (vaddr != end); pgd_idx++) {
|
||||||
for (; (pmd_idx < PTRS_PER_PMD) && (vaddr != end);
|
for (; (pmd_idx < PTRS_PER_PMD) && (vaddr != end);
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#include <linux/kthread.h>
|
#include <linux/kthread.h>
|
||||||
#include <linux/random.h>
|
#include <linux/random.h>
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
|
#include <linux/init.h>
|
||||||
#include <linux/mm.h>
|
#include <linux/mm.h>
|
||||||
#include <linux/vmalloc.h>
|
#include <linux/vmalloc.h>
|
||||||
|
|
||||||
|
@ -256,5 +257,4 @@ static int start_pageattr_test(void)
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
device_initcall(start_pageattr_test);
|
||||||
module_init(start_pageattr_test);
|
|
||||||
|
|
|
@ -4,7 +4,6 @@
|
||||||
*/
|
*/
|
||||||
#include <linux/highmem.h>
|
#include <linux/highmem.h>
|
||||||
#include <linux/bootmem.h>
|
#include <linux/bootmem.h>
|
||||||
#include <linux/module.h>
|
|
||||||
#include <linux/sched.h>
|
#include <linux/sched.h>
|
||||||
#include <linux/mm.h>
|
#include <linux/mm.h>
|
||||||
#include <linux/interrupt.h>
|
#include <linux/interrupt.h>
|
||||||
|
|
|
@ -1300,10 +1300,11 @@ static int iop_adma_probe(struct platform_device *pdev)
|
||||||
* note: writecombine gives slightly better performance, but
|
* note: writecombine gives slightly better performance, but
|
||||||
* requires that we explicitly flush the writes
|
* requires that we explicitly flush the writes
|
||||||
*/
|
*/
|
||||||
if ((adev->dma_desc_pool_virt = dma_alloc_writecombine(&pdev->dev,
|
adev->dma_desc_pool_virt = dma_alloc_writecombine(&pdev->dev,
|
||||||
plat_data->pool_size,
|
plat_data->pool_size,
|
||||||
&adev->dma_desc_pool,
|
&adev->dma_desc_pool,
|
||||||
GFP_KERNEL)) == NULL) {
|
GFP_KERNEL);
|
||||||
|
if (!adev->dma_desc_pool_virt) {
|
||||||
ret = -ENOMEM;
|
ret = -ENOMEM;
|
||||||
goto err_free_adev;
|
goto err_free_adev;
|
||||||
}
|
}
|
||||||
|
|
|
@ -138,6 +138,20 @@ void __iomem *pci_ioremap_bar(struct pci_dev *pdev, int bar)
|
||||||
return ioremap_nocache(res->start, resource_size(res));
|
return ioremap_nocache(res->start, resource_size(res));
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(pci_ioremap_bar);
|
EXPORT_SYMBOL_GPL(pci_ioremap_bar);
|
||||||
|
|
||||||
|
void __iomem *pci_ioremap_wc_bar(struct pci_dev *pdev, int bar)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Make sure the BAR is actually a memory resource, not an IO resource
|
||||||
|
*/
|
||||||
|
if (!(pci_resource_flags(pdev, bar) & IORESOURCE_MEM)) {
|
||||||
|
WARN_ON(1);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return ioremap_wc(pci_resource_start(pdev, bar),
|
||||||
|
pci_resource_len(pdev, bar));
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(pci_ioremap_wc_bar);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -26,13 +26,9 @@
|
||||||
#include <linux/console.h> /* Why should fb driver call console functions? because console_lock() */
|
#include <linux/console.h> /* Why should fb driver call console functions? because console_lock() */
|
||||||
#include <video/vga.h>
|
#include <video/vga.h>
|
||||||
|
|
||||||
#ifdef CONFIG_MTRR
|
|
||||||
#include <asm/mtrr.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct arkfb_info {
|
struct arkfb_info {
|
||||||
int mclk_freq;
|
int mclk_freq;
|
||||||
int mtrr_reg;
|
int wc_cookie;
|
||||||
|
|
||||||
struct dac_info *dac;
|
struct dac_info *dac;
|
||||||
struct vgastate state;
|
struct vgastate state;
|
||||||
|
@ -102,10 +98,6 @@ static const struct svga_timing_regs ark_timing_regs = {
|
||||||
|
|
||||||
static char *mode_option = "640x480-8@60";
|
static char *mode_option = "640x480-8@60";
|
||||||
|
|
||||||
#ifdef CONFIG_MTRR
|
|
||||||
static int mtrr = 1;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
MODULE_AUTHOR("(c) 2007 Ondrej Zajicek <santiago@crfreenet.org>");
|
MODULE_AUTHOR("(c) 2007 Ondrej Zajicek <santiago@crfreenet.org>");
|
||||||
MODULE_LICENSE("GPL");
|
MODULE_LICENSE("GPL");
|
||||||
MODULE_DESCRIPTION("fbdev driver for ARK 2000PV");
|
MODULE_DESCRIPTION("fbdev driver for ARK 2000PV");
|
||||||
|
@ -115,11 +107,6 @@ MODULE_PARM_DESC(mode_option, "Default video mode ('640x480-8@60', etc)");
|
||||||
module_param_named(mode, mode_option, charp, 0444);
|
module_param_named(mode, mode_option, charp, 0444);
|
||||||
MODULE_PARM_DESC(mode, "Default video mode ('640x480-8@60', etc) (deprecated)");
|
MODULE_PARM_DESC(mode, "Default video mode ('640x480-8@60', etc) (deprecated)");
|
||||||
|
|
||||||
#ifdef CONFIG_MTRR
|
|
||||||
module_param(mtrr, int, 0444);
|
|
||||||
MODULE_PARM_DESC(mtrr, "Enable write-combining with MTRR (1=enable, 0=disable, default=1)");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static int threshold = 4;
|
static int threshold = 4;
|
||||||
|
|
||||||
module_param(threshold, int, 0644);
|
module_param(threshold, int, 0644);
|
||||||
|
@ -1002,7 +989,7 @@ static int ark_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
|
||||||
info->fix.smem_len = pci_resource_len(dev, 0);
|
info->fix.smem_len = pci_resource_len(dev, 0);
|
||||||
|
|
||||||
/* Map physical IO memory address into kernel space */
|
/* Map physical IO memory address into kernel space */
|
||||||
info->screen_base = pci_iomap(dev, 0, 0);
|
info->screen_base = pci_iomap_wc(dev, 0, 0);
|
||||||
if (! info->screen_base) {
|
if (! info->screen_base) {
|
||||||
rc = -ENOMEM;
|
rc = -ENOMEM;
|
||||||
dev_err(info->device, "iomap for framebuffer failed\n");
|
dev_err(info->device, "iomap for framebuffer failed\n");
|
||||||
|
@ -1057,14 +1044,8 @@ static int ark_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
|
||||||
|
|
||||||
/* Record a reference to the driver data */
|
/* Record a reference to the driver data */
|
||||||
pci_set_drvdata(dev, info);
|
pci_set_drvdata(dev, info);
|
||||||
|
par->wc_cookie = arch_phys_wc_add(info->fix.smem_start,
|
||||||
#ifdef CONFIG_MTRR
|
info->fix.smem_len);
|
||||||
if (mtrr) {
|
|
||||||
par->mtrr_reg = -1;
|
|
||||||
par->mtrr_reg = mtrr_add(info->fix.smem_start, info->fix.smem_len, MTRR_TYPE_WRCOMB, 1);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* Error handling */
|
/* Error handling */
|
||||||
|
@ -1092,14 +1073,7 @@ static void ark_pci_remove(struct pci_dev *dev)
|
||||||
|
|
||||||
if (info) {
|
if (info) {
|
||||||
struct arkfb_info *par = info->par;
|
struct arkfb_info *par = info->par;
|
||||||
|
arch_phys_wc_del(par->wc_cookie);
|
||||||
#ifdef CONFIG_MTRR
|
|
||||||
if (par->mtrr_reg >= 0) {
|
|
||||||
mtrr_del(par->mtrr_reg, 0, 0);
|
|
||||||
par->mtrr_reg = -1;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
dac_release(par->dac);
|
dac_release(par->dac);
|
||||||
unregister_framebuffer(info);
|
unregister_framebuffer(info);
|
||||||
fb_dealloc_cmap(&info->cmap);
|
fb_dealloc_cmap(&info->cmap);
|
||||||
|
|
|
@ -182,10 +182,7 @@ struct atyfb_par {
|
||||||
unsigned long irq_flags;
|
unsigned long irq_flags;
|
||||||
unsigned int irq;
|
unsigned int irq;
|
||||||
spinlock_t int_lock;
|
spinlock_t int_lock;
|
||||||
#ifdef CONFIG_MTRR
|
int wc_cookie;
|
||||||
int mtrr_aper;
|
|
||||||
int mtrr_reg;
|
|
||||||
#endif
|
|
||||||
u32 mem_cntl;
|
u32 mem_cntl;
|
||||||
struct crtc saved_crtc;
|
struct crtc saved_crtc;
|
||||||
union aty_pll saved_pll;
|
union aty_pll saved_pll;
|
||||||
|
|
|
@ -98,9 +98,6 @@
|
||||||
#ifdef CONFIG_PMAC_BACKLIGHT
|
#ifdef CONFIG_PMAC_BACKLIGHT
|
||||||
#include <asm/backlight.h>
|
#include <asm/backlight.h>
|
||||||
#endif
|
#endif
|
||||||
#ifdef CONFIG_MTRR
|
|
||||||
#include <asm/mtrr.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Debug flags.
|
* Debug flags.
|
||||||
|
@ -303,9 +300,7 @@ static struct fb_ops atyfb_ops = {
|
||||||
};
|
};
|
||||||
|
|
||||||
static bool noaccel;
|
static bool noaccel;
|
||||||
#ifdef CONFIG_MTRR
|
|
||||||
static bool nomtrr;
|
static bool nomtrr;
|
||||||
#endif
|
|
||||||
static int vram;
|
static int vram;
|
||||||
static int pll;
|
static int pll;
|
||||||
static int mclk;
|
static int mclk;
|
||||||
|
@ -427,6 +422,20 @@ static struct {
|
||||||
#endif /* CONFIG_FB_ATY_CT */
|
#endif /* CONFIG_FB_ATY_CT */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Last page of 8 MB (4 MB on ISA) aperture is MMIO,
|
||||||
|
* unless the auxiliary register aperture is used.
|
||||||
|
*/
|
||||||
|
static void aty_fudge_framebuffer_len(struct fb_info *info)
|
||||||
|
{
|
||||||
|
struct atyfb_par *par = (struct atyfb_par *) info->par;
|
||||||
|
|
||||||
|
if (!par->aux_start &&
|
||||||
|
(info->fix.smem_len == 0x800000 ||
|
||||||
|
(par->bus_type == ISA && info->fix.smem_len == 0x400000)))
|
||||||
|
info->fix.smem_len -= GUI_RESERVE;
|
||||||
|
}
|
||||||
|
|
||||||
static int correct_chipset(struct atyfb_par *par)
|
static int correct_chipset(struct atyfb_par *par)
|
||||||
{
|
{
|
||||||
u8 rev;
|
u8 rev;
|
||||||
|
@ -2603,14 +2612,7 @@ static int aty_init(struct fb_info *info)
|
||||||
if (par->pll_ops->resume_pll)
|
if (par->pll_ops->resume_pll)
|
||||||
par->pll_ops->resume_pll(info, &par->pll);
|
par->pll_ops->resume_pll(info, &par->pll);
|
||||||
|
|
||||||
/*
|
aty_fudge_framebuffer_len(info);
|
||||||
* Last page of 8 MB (4 MB on ISA) aperture is MMIO,
|
|
||||||
* unless the auxiliary register aperture is used.
|
|
||||||
*/
|
|
||||||
if (!par->aux_start &&
|
|
||||||
(info->fix.smem_len == 0x800000 ||
|
|
||||||
(par->bus_type == ISA && info->fix.smem_len == 0x400000)))
|
|
||||||
info->fix.smem_len -= GUI_RESERVE;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Disable register access through the linear aperture
|
* Disable register access through the linear aperture
|
||||||
|
@ -2621,25 +2623,13 @@ static int aty_init(struct fb_info *info)
|
||||||
aty_st_le32(BUS_CNTL, aty_ld_le32(BUS_CNTL, par) |
|
aty_st_le32(BUS_CNTL, aty_ld_le32(BUS_CNTL, par) |
|
||||||
BUS_APER_REG_DIS, par);
|
BUS_APER_REG_DIS, par);
|
||||||
|
|
||||||
#ifdef CONFIG_MTRR
|
if (!nomtrr)
|
||||||
par->mtrr_aper = -1;
|
/*
|
||||||
par->mtrr_reg = -1;
|
* Only the ioremap_wc()'d area will get WC here
|
||||||
if (!nomtrr) {
|
* since ioremap_uc() was used on the entire PCI BAR.
|
||||||
/* Cover the whole resource. */
|
*/
|
||||||
par->mtrr_aper = mtrr_add(par->res_start, par->res_size,
|
par->wc_cookie = arch_phys_wc_add(par->res_start,
|
||||||
MTRR_TYPE_WRCOMB, 1);
|
par->res_size);
|
||||||
if (par->mtrr_aper >= 0 && !par->aux_start) {
|
|
||||||
/* Make a hole for mmio. */
|
|
||||||
par->mtrr_reg = mtrr_add(par->res_start + 0x800000 -
|
|
||||||
GUI_RESERVE, GUI_RESERVE,
|
|
||||||
MTRR_TYPE_UNCACHABLE, 1);
|
|
||||||
if (par->mtrr_reg < 0) {
|
|
||||||
mtrr_del(par->mtrr_aper, 0, 0);
|
|
||||||
par->mtrr_aper = -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
info->fbops = &atyfb_ops;
|
info->fbops = &atyfb_ops;
|
||||||
info->pseudo_palette = par->pseudo_palette;
|
info->pseudo_palette = par->pseudo_palette;
|
||||||
|
@ -2767,17 +2757,8 @@ aty_init_exit:
|
||||||
/* restore video mode */
|
/* restore video mode */
|
||||||
aty_set_crtc(par, &par->saved_crtc);
|
aty_set_crtc(par, &par->saved_crtc);
|
||||||
par->pll_ops->set_pll(info, &par->saved_pll);
|
par->pll_ops->set_pll(info, &par->saved_pll);
|
||||||
|
arch_phys_wc_del(par->wc_cookie);
|
||||||
|
|
||||||
#ifdef CONFIG_MTRR
|
|
||||||
if (par->mtrr_reg >= 0) {
|
|
||||||
mtrr_del(par->mtrr_reg, 0, 0);
|
|
||||||
par->mtrr_reg = -1;
|
|
||||||
}
|
|
||||||
if (par->mtrr_aper >= 0) {
|
|
||||||
mtrr_del(par->mtrr_aper, 0, 0);
|
|
||||||
par->mtrr_aper = -1;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3459,7 +3440,11 @@ static int atyfb_setup_generic(struct pci_dev *pdev, struct fb_info *info,
|
||||||
}
|
}
|
||||||
|
|
||||||
info->fix.mmio_start = raddr;
|
info->fix.mmio_start = raddr;
|
||||||
par->ati_regbase = ioremap(info->fix.mmio_start, 0x1000);
|
/*
|
||||||
|
* By using strong UC we force the MTRR to never have an
|
||||||
|
* effect on the MMIO region on both non-PAT and PAT systems.
|
||||||
|
*/
|
||||||
|
par->ati_regbase = ioremap_uc(info->fix.mmio_start, 0x1000);
|
||||||
if (par->ati_regbase == NULL)
|
if (par->ati_regbase == NULL)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
|
@ -3482,7 +3467,24 @@ static int atyfb_setup_generic(struct pci_dev *pdev, struct fb_info *info,
|
||||||
|
|
||||||
/* Map in frame buffer */
|
/* Map in frame buffer */
|
||||||
info->fix.smem_start = addr;
|
info->fix.smem_start = addr;
|
||||||
info->screen_base = ioremap(addr, 0x800000);
|
|
||||||
|
/*
|
||||||
|
* The framebuffer is not always 8 MiB, that's just the size of the
|
||||||
|
* PCI BAR. We temporarily abuse smem_len here to store the size
|
||||||
|
* of the BAR. aty_init() will later correct it to match the actual
|
||||||
|
* framebuffer size.
|
||||||
|
*
|
||||||
|
* On devices that don't have the auxiliary register aperture, the
|
||||||
|
* registers are housed at the top end of the framebuffer PCI BAR.
|
||||||
|
* aty_fudge_framebuffer_len() is used to reduce smem_len to not
|
||||||
|
* overlap with the registers.
|
||||||
|
*/
|
||||||
|
info->fix.smem_len = 0x800000;
|
||||||
|
|
||||||
|
aty_fudge_framebuffer_len(info);
|
||||||
|
|
||||||
|
info->screen_base = ioremap_wc(info->fix.smem_start,
|
||||||
|
info->fix.smem_len);
|
||||||
if (info->screen_base == NULL) {
|
if (info->screen_base == NULL) {
|
||||||
ret = -ENOMEM;
|
ret = -ENOMEM;
|
||||||
goto atyfb_setup_generic_fail;
|
goto atyfb_setup_generic_fail;
|
||||||
|
@ -3554,6 +3556,7 @@ static int atyfb_pci_probe(struct pci_dev *pdev,
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
par = info->par;
|
par = info->par;
|
||||||
|
par->bus_type = PCI;
|
||||||
info->fix = atyfb_fix;
|
info->fix = atyfb_fix;
|
||||||
info->device = &pdev->dev;
|
info->device = &pdev->dev;
|
||||||
par->pci_id = pdev->device;
|
par->pci_id = pdev->device;
|
||||||
|
@ -3655,7 +3658,8 @@ static int __init atyfb_atari_probe(void)
|
||||||
* Map the video memory (physical address given)
|
* Map the video memory (physical address given)
|
||||||
* to somewhere in the kernel address space.
|
* to somewhere in the kernel address space.
|
||||||
*/
|
*/
|
||||||
info->screen_base = ioremap(phys_vmembase[m64_num], phys_size[m64_num]);
|
info->screen_base = ioremap_wc(phys_vmembase[m64_num],
|
||||||
|
phys_size[m64_num]);
|
||||||
info->fix.smem_start = (unsigned long)info->screen_base; /* Fake! */
|
info->fix.smem_start = (unsigned long)info->screen_base; /* Fake! */
|
||||||
par->ati_regbase = ioremap(phys_guiregbase[m64_num], 0x10000) +
|
par->ati_regbase = ioremap(phys_guiregbase[m64_num], 0x10000) +
|
||||||
0xFC00ul;
|
0xFC00ul;
|
||||||
|
@ -3721,17 +3725,8 @@ static void atyfb_remove(struct fb_info *info)
|
||||||
if (M64_HAS(MOBIL_BUS))
|
if (M64_HAS(MOBIL_BUS))
|
||||||
aty_bl_exit(info->bl_dev);
|
aty_bl_exit(info->bl_dev);
|
||||||
#endif
|
#endif
|
||||||
|
arch_phys_wc_del(par->wc_cookie);
|
||||||
|
|
||||||
#ifdef CONFIG_MTRR
|
|
||||||
if (par->mtrr_reg >= 0) {
|
|
||||||
mtrr_del(par->mtrr_reg, 0, 0);
|
|
||||||
par->mtrr_reg = -1;
|
|
||||||
}
|
|
||||||
if (par->mtrr_aper >= 0) {
|
|
||||||
mtrr_del(par->mtrr_aper, 0, 0);
|
|
||||||
par->mtrr_aper = -1;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#ifndef __sparc__
|
#ifndef __sparc__
|
||||||
if (par->ati_regbase)
|
if (par->ati_regbase)
|
||||||
iounmap(par->ati_regbase);
|
iounmap(par->ati_regbase);
|
||||||
|
@ -3847,10 +3842,8 @@ static int __init atyfb_setup(char *options)
|
||||||
while ((this_opt = strsep(&options, ",")) != NULL) {
|
while ((this_opt = strsep(&options, ",")) != NULL) {
|
||||||
if (!strncmp(this_opt, "noaccel", 7)) {
|
if (!strncmp(this_opt, "noaccel", 7)) {
|
||||||
noaccel = 1;
|
noaccel = 1;
|
||||||
#ifdef CONFIG_MTRR
|
|
||||||
} else if (!strncmp(this_opt, "nomtrr", 6)) {
|
} else if (!strncmp(this_opt, "nomtrr", 6)) {
|
||||||
nomtrr = 1;
|
nomtrr = 1;
|
||||||
#endif
|
|
||||||
} else if (!strncmp(this_opt, "vram:", 5))
|
} else if (!strncmp(this_opt, "vram:", 5))
|
||||||
vram = simple_strtoul(this_opt + 5, NULL, 0);
|
vram = simple_strtoul(this_opt + 5, NULL, 0);
|
||||||
else if (!strncmp(this_opt, "pll:", 4))
|
else if (!strncmp(this_opt, "pll:", 4))
|
||||||
|
@ -4020,7 +4013,5 @@ module_param(comp_sync, int, 0);
|
||||||
MODULE_PARM_DESC(comp_sync, "Set composite sync signal to low (0) or high (1)");
|
MODULE_PARM_DESC(comp_sync, "Set composite sync signal to low (0) or high (1)");
|
||||||
module_param(mode, charp, 0);
|
module_param(mode, charp, 0);
|
||||||
MODULE_PARM_DESC(mode, "Specify resolution as \"<xres>x<yres>[-<bpp>][@<refresh>]\" ");
|
MODULE_PARM_DESC(mode, "Specify resolution as \"<xres>x<yres>[-<bpp>][@<refresh>]\" ");
|
||||||
#ifdef CONFIG_MTRR
|
|
||||||
module_param(nomtrr, bool, 0);
|
module_param(nomtrr, bool, 0);
|
||||||
MODULE_PARM_DESC(nomtrr, "bool: disable use of MTRR registers");
|
MODULE_PARM_DESC(nomtrr, "bool: disable use of MTRR registers");
|
||||||
#endif
|
|
||||||
|
|
|
@ -662,7 +662,7 @@ static int gxt4500_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||||
|
|
||||||
info->fix.smem_start = fb_phys;
|
info->fix.smem_start = fb_phys;
|
||||||
info->fix.smem_len = pci_resource_len(pdev, 1);
|
info->fix.smem_len = pci_resource_len(pdev, 1);
|
||||||
info->screen_base = pci_ioremap_bar(pdev, 1);
|
info->screen_base = pci_ioremap_wc_bar(pdev, 1);
|
||||||
if (!info->screen_base) {
|
if (!info->screen_base) {
|
||||||
dev_err(&pdev->dev, "gxt4500: cannot map framebuffer\n");
|
dev_err(&pdev->dev, "gxt4500: cannot map framebuffer\n");
|
||||||
goto err_unmap_regs;
|
goto err_unmap_regs;
|
||||||
|
|
|
@ -27,24 +27,15 @@
|
||||||
#include <linux/console.h>
|
#include <linux/console.h>
|
||||||
#include <video/vga.h>
|
#include <video/vga.h>
|
||||||
|
|
||||||
#ifdef CONFIG_MTRR
|
|
||||||
#include <asm/mtrr.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "i740_reg.h"
|
#include "i740_reg.h"
|
||||||
|
|
||||||
static char *mode_option;
|
static char *mode_option;
|
||||||
|
|
||||||
#ifdef CONFIG_MTRR
|
|
||||||
static int mtrr = 1;
|
static int mtrr = 1;
|
||||||
#endif
|
|
||||||
|
|
||||||
struct i740fb_par {
|
struct i740fb_par {
|
||||||
unsigned char __iomem *regs;
|
unsigned char __iomem *regs;
|
||||||
bool has_sgram;
|
bool has_sgram;
|
||||||
#ifdef CONFIG_MTRR
|
int wc_cookie;
|
||||||
int mtrr_reg;
|
|
||||||
#endif
|
|
||||||
bool ddc_registered;
|
bool ddc_registered;
|
||||||
struct i2c_adapter ddc_adapter;
|
struct i2c_adapter ddc_adapter;
|
||||||
struct i2c_algo_bit_data ddc_algo;
|
struct i2c_algo_bit_data ddc_algo;
|
||||||
|
@ -1040,7 +1031,7 @@ static int i740fb_probe(struct pci_dev *dev, const struct pci_device_id *ent)
|
||||||
goto err_request_regions;
|
goto err_request_regions;
|
||||||
}
|
}
|
||||||
|
|
||||||
info->screen_base = pci_ioremap_bar(dev, 0);
|
info->screen_base = pci_ioremap_wc_bar(dev, 0);
|
||||||
if (!info->screen_base) {
|
if (!info->screen_base) {
|
||||||
dev_err(info->device, "error remapping base\n");
|
dev_err(info->device, "error remapping base\n");
|
||||||
ret = -ENOMEM;
|
ret = -ENOMEM;
|
||||||
|
@ -1144,13 +1135,9 @@ static int i740fb_probe(struct pci_dev *dev, const struct pci_device_id *ent)
|
||||||
|
|
||||||
fb_info(info, "%s frame buffer device\n", info->fix.id);
|
fb_info(info, "%s frame buffer device\n", info->fix.id);
|
||||||
pci_set_drvdata(dev, info);
|
pci_set_drvdata(dev, info);
|
||||||
#ifdef CONFIG_MTRR
|
if (mtrr)
|
||||||
if (mtrr) {
|
par->wc_cookie = arch_phys_wc_add(info->fix.smem_start,
|
||||||
par->mtrr_reg = -1;
|
info->fix.smem_len);
|
||||||
par->mtrr_reg = mtrr_add(info->fix.smem_start,
|
|
||||||
info->fix.smem_len, MTRR_TYPE_WRCOMB, 1);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
err_reg_framebuffer:
|
err_reg_framebuffer:
|
||||||
|
@ -1177,13 +1164,7 @@ static void i740fb_remove(struct pci_dev *dev)
|
||||||
|
|
||||||
if (info) {
|
if (info) {
|
||||||
struct i740fb_par *par = info->par;
|
struct i740fb_par *par = info->par;
|
||||||
|
arch_phys_wc_del(par->wc_cookie);
|
||||||
#ifdef CONFIG_MTRR
|
|
||||||
if (par->mtrr_reg >= 0) {
|
|
||||||
mtrr_del(par->mtrr_reg, 0, 0);
|
|
||||||
par->mtrr_reg = -1;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
unregister_framebuffer(info);
|
unregister_framebuffer(info);
|
||||||
fb_dealloc_cmap(&info->cmap);
|
fb_dealloc_cmap(&info->cmap);
|
||||||
if (par->ddc_registered)
|
if (par->ddc_registered)
|
||||||
|
@ -1287,10 +1268,8 @@ static int __init i740fb_setup(char *options)
|
||||||
while ((opt = strsep(&options, ",")) != NULL) {
|
while ((opt = strsep(&options, ",")) != NULL) {
|
||||||
if (!*opt)
|
if (!*opt)
|
||||||
continue;
|
continue;
|
||||||
#ifdef CONFIG_MTRR
|
|
||||||
else if (!strncmp(opt, "mtrr:", 5))
|
else if (!strncmp(opt, "mtrr:", 5))
|
||||||
mtrr = simple_strtoul(opt + 5, NULL, 0);
|
mtrr = simple_strtoul(opt + 5, NULL, 0);
|
||||||
#endif
|
|
||||||
else
|
else
|
||||||
mode_option = opt;
|
mode_option = opt;
|
||||||
}
|
}
|
||||||
|
@ -1327,7 +1306,5 @@ MODULE_DESCRIPTION("fbdev driver for Intel740");
|
||||||
module_param(mode_option, charp, 0444);
|
module_param(mode_option, charp, 0444);
|
||||||
MODULE_PARM_DESC(mode_option, "Default video mode ('640x480-8@60', etc)");
|
MODULE_PARM_DESC(mode_option, "Default video mode ('640x480-8@60', etc)");
|
||||||
|
|
||||||
#ifdef CONFIG_MTRR
|
|
||||||
module_param(mtrr, int, 0444);
|
module_param(mtrr, int, 0444);
|
||||||
MODULE_PARM_DESC(mtrr, "Enable write-combining with MTRR (1=enable, 0=disable, default=1)");
|
MODULE_PARM_DESC(mtrr, "Enable write-combining with MTRR (1=enable, 0=disable, default=1)");
|
||||||
#endif
|
|
||||||
|
|
|
@ -22,9 +22,6 @@
|
||||||
#include <linux/pci.h>
|
#include <linux/pci.h>
|
||||||
#include <asm/io.h>
|
#include <asm/io.h>
|
||||||
#include <linux/uaccess.h>
|
#include <linux/uaccess.h>
|
||||||
#ifdef CONFIG_MTRR
|
|
||||||
#include <asm/mtrr.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <video/kyro.h>
|
#include <video/kyro.h>
|
||||||
|
|
||||||
|
@ -84,9 +81,7 @@ static device_info_t deviceInfo;
|
||||||
static char *mode_option = NULL;
|
static char *mode_option = NULL;
|
||||||
static int nopan = 0;
|
static int nopan = 0;
|
||||||
static int nowrap = 1;
|
static int nowrap = 1;
|
||||||
#ifdef CONFIG_MTRR
|
|
||||||
static int nomtrr = 0;
|
static int nomtrr = 0;
|
||||||
#endif
|
|
||||||
|
|
||||||
/* PCI driver prototypes */
|
/* PCI driver prototypes */
|
||||||
static int kyrofb_probe(struct pci_dev *pdev, const struct pci_device_id *ent);
|
static int kyrofb_probe(struct pci_dev *pdev, const struct pci_device_id *ent);
|
||||||
|
@ -570,10 +565,8 @@ static int __init kyrofb_setup(char *options)
|
||||||
nopan = 1;
|
nopan = 1;
|
||||||
} else if (strcmp(this_opt, "nowrap") == 0) {
|
} else if (strcmp(this_opt, "nowrap") == 0) {
|
||||||
nowrap = 1;
|
nowrap = 1;
|
||||||
#ifdef CONFIG_MTRR
|
|
||||||
} else if (strcmp(this_opt, "nomtrr") == 0) {
|
} else if (strcmp(this_opt, "nomtrr") == 0) {
|
||||||
nomtrr = 1;
|
nomtrr = 1;
|
||||||
#endif
|
|
||||||
} else {
|
} else {
|
||||||
mode_option = this_opt;
|
mode_option = this_opt;
|
||||||
}
|
}
|
||||||
|
@ -691,17 +684,16 @@ static int kyrofb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||||
|
|
||||||
currentpar->regbase = deviceInfo.pSTGReg =
|
currentpar->regbase = deviceInfo.pSTGReg =
|
||||||
ioremap_nocache(kyro_fix.mmio_start, kyro_fix.mmio_len);
|
ioremap_nocache(kyro_fix.mmio_start, kyro_fix.mmio_len);
|
||||||
|
if (!currentpar->regbase)
|
||||||
|
goto out_free_fb;
|
||||||
|
|
||||||
info->screen_base = ioremap_nocache(kyro_fix.smem_start,
|
info->screen_base = pci_ioremap_wc_bar(pdev, 0);
|
||||||
kyro_fix.smem_len);
|
if (!info->screen_base)
|
||||||
|
goto out_unmap_regs;
|
||||||
|
|
||||||
#ifdef CONFIG_MTRR
|
|
||||||
if (!nomtrr)
|
if (!nomtrr)
|
||||||
currentpar->mtrr_handle =
|
currentpar->wc_cookie = arch_phys_wc_add(kyro_fix.smem_start,
|
||||||
mtrr_add(kyro_fix.smem_start,
|
kyro_fix.smem_len);
|
||||||
kyro_fix.smem_len,
|
|
||||||
MTRR_TYPE_WRCOMB, 1);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
kyro_fix.ypanstep = nopan ? 0 : 1;
|
kyro_fix.ypanstep = nopan ? 0 : 1;
|
||||||
kyro_fix.ywrapstep = nowrap ? 0 : 1;
|
kyro_fix.ywrapstep = nowrap ? 0 : 1;
|
||||||
|
@ -745,8 +737,10 @@ static int kyrofb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
out_unmap:
|
out_unmap:
|
||||||
iounmap(currentpar->regbase);
|
|
||||||
iounmap(info->screen_base);
|
iounmap(info->screen_base);
|
||||||
|
out_unmap_regs:
|
||||||
|
iounmap(currentpar->regbase);
|
||||||
|
out_free_fb:
|
||||||
framebuffer_release(info);
|
framebuffer_release(info);
|
||||||
|
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
@ -770,12 +764,7 @@ static void kyrofb_remove(struct pci_dev *pdev)
|
||||||
iounmap(info->screen_base);
|
iounmap(info->screen_base);
|
||||||
iounmap(par->regbase);
|
iounmap(par->regbase);
|
||||||
|
|
||||||
#ifdef CONFIG_MTRR
|
arch_phys_wc_del(par->wc_cookie);
|
||||||
if (par->mtrr_handle)
|
|
||||||
mtrr_del(par->mtrr_handle,
|
|
||||||
info->fix.smem_start,
|
|
||||||
info->fix.smem_len);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
unregister_framebuffer(info);
|
unregister_framebuffer(info);
|
||||||
framebuffer_release(info);
|
framebuffer_release(info);
|
||||||
|
|
|
@ -28,13 +28,9 @@
|
||||||
#include <linux/i2c.h>
|
#include <linux/i2c.h>
|
||||||
#include <linux/i2c-algo-bit.h>
|
#include <linux/i2c-algo-bit.h>
|
||||||
|
|
||||||
#ifdef CONFIG_MTRR
|
|
||||||
#include <asm/mtrr.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct s3fb_info {
|
struct s3fb_info {
|
||||||
int chip, rev, mclk_freq;
|
int chip, rev, mclk_freq;
|
||||||
int mtrr_reg;
|
int wc_cookie;
|
||||||
struct vgastate state;
|
struct vgastate state;
|
||||||
struct mutex open_lock;
|
struct mutex open_lock;
|
||||||
unsigned int ref_count;
|
unsigned int ref_count;
|
||||||
|
@ -154,11 +150,7 @@ static const struct svga_timing_regs s3_timing_regs = {
|
||||||
|
|
||||||
|
|
||||||
static char *mode_option;
|
static char *mode_option;
|
||||||
|
|
||||||
#ifdef CONFIG_MTRR
|
|
||||||
static int mtrr = 1;
|
static int mtrr = 1;
|
||||||
#endif
|
|
||||||
|
|
||||||
static int fasttext = 1;
|
static int fasttext = 1;
|
||||||
|
|
||||||
|
|
||||||
|
@ -170,11 +162,8 @@ module_param(mode_option, charp, 0444);
|
||||||
MODULE_PARM_DESC(mode_option, "Default video mode ('640x480-8@60', etc)");
|
MODULE_PARM_DESC(mode_option, "Default video mode ('640x480-8@60', etc)");
|
||||||
module_param_named(mode, mode_option, charp, 0444);
|
module_param_named(mode, mode_option, charp, 0444);
|
||||||
MODULE_PARM_DESC(mode, "Default video mode ('640x480-8@60', etc) (deprecated)");
|
MODULE_PARM_DESC(mode, "Default video mode ('640x480-8@60', etc) (deprecated)");
|
||||||
|
|
||||||
#ifdef CONFIG_MTRR
|
|
||||||
module_param(mtrr, int, 0444);
|
module_param(mtrr, int, 0444);
|
||||||
MODULE_PARM_DESC(mtrr, "Enable write-combining with MTRR (1=enable, 0=disable, default=1)");
|
MODULE_PARM_DESC(mtrr, "Enable write-combining with MTRR (1=enable, 0=disable, default=1)");
|
||||||
#endif
|
|
||||||
|
|
||||||
module_param(fasttext, int, 0644);
|
module_param(fasttext, int, 0644);
|
||||||
MODULE_PARM_DESC(fasttext, "Enable S3 fast text mode (1=enable, 0=disable, default=1)");
|
MODULE_PARM_DESC(fasttext, "Enable S3 fast text mode (1=enable, 0=disable, default=1)");
|
||||||
|
@ -1168,7 +1157,7 @@ static int s3_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
|
||||||
info->fix.smem_len = pci_resource_len(dev, 0);
|
info->fix.smem_len = pci_resource_len(dev, 0);
|
||||||
|
|
||||||
/* Map physical IO memory address into kernel space */
|
/* Map physical IO memory address into kernel space */
|
||||||
info->screen_base = pci_iomap(dev, 0, 0);
|
info->screen_base = pci_iomap_wc(dev, 0, 0);
|
||||||
if (! info->screen_base) {
|
if (! info->screen_base) {
|
||||||
rc = -ENOMEM;
|
rc = -ENOMEM;
|
||||||
dev_err(info->device, "iomap for framebuffer failed\n");
|
dev_err(info->device, "iomap for framebuffer failed\n");
|
||||||
|
@ -1365,12 +1354,9 @@ static int s3_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
|
||||||
/* Record a reference to the driver data */
|
/* Record a reference to the driver data */
|
||||||
pci_set_drvdata(dev, info);
|
pci_set_drvdata(dev, info);
|
||||||
|
|
||||||
#ifdef CONFIG_MTRR
|
if (mtrr)
|
||||||
if (mtrr) {
|
par->wc_cookie = arch_phys_wc_add(info->fix.smem_start,
|
||||||
par->mtrr_reg = -1;
|
info->fix.smem_len);
|
||||||
par->mtrr_reg = mtrr_add(info->fix.smem_start, info->fix.smem_len, MTRR_TYPE_WRCOMB, 1);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
@ -1405,14 +1391,7 @@ static void s3_pci_remove(struct pci_dev *dev)
|
||||||
|
|
||||||
if (info) {
|
if (info) {
|
||||||
par = info->par;
|
par = info->par;
|
||||||
|
arch_phys_wc_del(par->wc_cookie);
|
||||||
#ifdef CONFIG_MTRR
|
|
||||||
if (par->mtrr_reg >= 0) {
|
|
||||||
mtrr_del(par->mtrr_reg, 0, 0);
|
|
||||||
par->mtrr_reg = -1;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
unregister_framebuffer(info);
|
unregister_framebuffer(info);
|
||||||
fb_dealloc_cmap(&info->cmap);
|
fb_dealloc_cmap(&info->cmap);
|
||||||
|
|
||||||
|
@ -1551,10 +1530,8 @@ static int __init s3fb_setup(char *options)
|
||||||
|
|
||||||
if (!*opt)
|
if (!*opt)
|
||||||
continue;
|
continue;
|
||||||
#ifdef CONFIG_MTRR
|
|
||||||
else if (!strncmp(opt, "mtrr:", 5))
|
else if (!strncmp(opt, "mtrr:", 5))
|
||||||
mtrr = simple_strtoul(opt + 5, NULL, 0);
|
mtrr = simple_strtoul(opt + 5, NULL, 0);
|
||||||
#endif
|
|
||||||
else if (!strncmp(opt, "fasttext:", 9))
|
else if (!strncmp(opt, "fasttext:", 9))
|
||||||
fasttext = simple_strtoul(opt + 9, NULL, 0);
|
fasttext = simple_strtoul(opt + 9, NULL, 0);
|
||||||
else
|
else
|
||||||
|
|
|
@ -26,13 +26,9 @@
|
||||||
#include <linux/console.h> /* Why should fb driver call console functions? because console_lock() */
|
#include <linux/console.h> /* Why should fb driver call console functions? because console_lock() */
|
||||||
#include <video/vga.h>
|
#include <video/vga.h>
|
||||||
|
|
||||||
#ifdef CONFIG_MTRR
|
|
||||||
#include <asm/mtrr.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct vt8623fb_info {
|
struct vt8623fb_info {
|
||||||
char __iomem *mmio_base;
|
char __iomem *mmio_base;
|
||||||
int mtrr_reg;
|
int wc_cookie;
|
||||||
struct vgastate state;
|
struct vgastate state;
|
||||||
struct mutex open_lock;
|
struct mutex open_lock;
|
||||||
unsigned int ref_count;
|
unsigned int ref_count;
|
||||||
|
@ -99,10 +95,7 @@ static struct svga_timing_regs vt8623_timing_regs = {
|
||||||
/* Module parameters */
|
/* Module parameters */
|
||||||
|
|
||||||
static char *mode_option = "640x480-8@60";
|
static char *mode_option = "640x480-8@60";
|
||||||
|
|
||||||
#ifdef CONFIG_MTRR
|
|
||||||
static int mtrr = 1;
|
static int mtrr = 1;
|
||||||
#endif
|
|
||||||
|
|
||||||
MODULE_AUTHOR("(c) 2006 Ondrej Zajicek <santiago@crfreenet.org>");
|
MODULE_AUTHOR("(c) 2006 Ondrej Zajicek <santiago@crfreenet.org>");
|
||||||
MODULE_LICENSE("GPL");
|
MODULE_LICENSE("GPL");
|
||||||
|
@ -112,11 +105,8 @@ module_param(mode_option, charp, 0644);
|
||||||
MODULE_PARM_DESC(mode_option, "Default video mode ('640x480-8@60', etc)");
|
MODULE_PARM_DESC(mode_option, "Default video mode ('640x480-8@60', etc)");
|
||||||
module_param_named(mode, mode_option, charp, 0);
|
module_param_named(mode, mode_option, charp, 0);
|
||||||
MODULE_PARM_DESC(mode, "Default video mode e.g. '648x480-8@60' (deprecated)");
|
MODULE_PARM_DESC(mode, "Default video mode e.g. '648x480-8@60' (deprecated)");
|
||||||
|
|
||||||
#ifdef CONFIG_MTRR
|
|
||||||
module_param(mtrr, int, 0444);
|
module_param(mtrr, int, 0444);
|
||||||
MODULE_PARM_DESC(mtrr, "Enable write-combining with MTRR (1=enable, 0=disable, default=1)");
|
MODULE_PARM_DESC(mtrr, "Enable write-combining with MTRR (1=enable, 0=disable, default=1)");
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------- */
|
/* ------------------------------------------------------------------------- */
|
||||||
|
@ -710,7 +700,7 @@ static int vt8623_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
|
||||||
info->fix.mmio_len = pci_resource_len(dev, 1);
|
info->fix.mmio_len = pci_resource_len(dev, 1);
|
||||||
|
|
||||||
/* Map physical IO memory address into kernel space */
|
/* Map physical IO memory address into kernel space */
|
||||||
info->screen_base = pci_iomap(dev, 0, 0);
|
info->screen_base = pci_iomap_wc(dev, 0, 0);
|
||||||
if (! info->screen_base) {
|
if (! info->screen_base) {
|
||||||
rc = -ENOMEM;
|
rc = -ENOMEM;
|
||||||
dev_err(info->device, "iomap for framebuffer failed\n");
|
dev_err(info->device, "iomap for framebuffer failed\n");
|
||||||
|
@ -781,12 +771,9 @@ static int vt8623_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
|
||||||
/* Record a reference to the driver data */
|
/* Record a reference to the driver data */
|
||||||
pci_set_drvdata(dev, info);
|
pci_set_drvdata(dev, info);
|
||||||
|
|
||||||
#ifdef CONFIG_MTRR
|
if (mtrr)
|
||||||
if (mtrr) {
|
par->wc_cookie = arch_phys_wc_add(info->fix.smem_start,
|
||||||
par->mtrr_reg = -1;
|
info->fix.smem_len);
|
||||||
par->mtrr_reg = mtrr_add(info->fix.smem_start, info->fix.smem_len, MTRR_TYPE_WRCOMB, 1);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
@ -816,13 +803,7 @@ static void vt8623_pci_remove(struct pci_dev *dev)
|
||||||
if (info) {
|
if (info) {
|
||||||
struct vt8623fb_info *par = info->par;
|
struct vt8623fb_info *par = info->par;
|
||||||
|
|
||||||
#ifdef CONFIG_MTRR
|
arch_phys_wc_del(par->wc_cookie);
|
||||||
if (par->mtrr_reg >= 0) {
|
|
||||||
mtrr_del(par->mtrr_reg, 0, 0);
|
|
||||||
par->mtrr_reg = -1;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
unregister_framebuffer(info);
|
unregister_framebuffer(info);
|
||||||
fb_dealloc_cmap(&info->cmap);
|
fb_dealloc_cmap(&info->cmap);
|
||||||
|
|
||||||
|
|
|
@ -736,6 +736,35 @@ static inline void *phys_to_virt(unsigned long address)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DOC: ioremap() and ioremap_*() variants
|
||||||
|
*
|
||||||
|
* If you have an IOMMU your architecture is expected to have both ioremap()
|
||||||
|
* and iounmap() implemented otherwise the asm-generic helpers will provide a
|
||||||
|
* direct mapping.
|
||||||
|
*
|
||||||
|
* There are ioremap_*() call variants, if you have no IOMMU we naturally will
|
||||||
|
* default to direct mapping for all of them, you can override these defaults.
|
||||||
|
* If you have an IOMMU you are highly encouraged to provide your own
|
||||||
|
* ioremap variant implementation as there currently is no safe architecture
|
||||||
|
* agnostic default. To avoid possible improper behaviour default asm-generic
|
||||||
|
* ioremap_*() variants all return NULL when an IOMMU is available. If you've
|
||||||
|
* defined your own ioremap_*() variant you must then declare your own
|
||||||
|
* ioremap_*() variant as defined to itself to avoid the default NULL return.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef CONFIG_MMU
|
||||||
|
|
||||||
|
#ifndef ioremap_uc
|
||||||
|
#define ioremap_uc ioremap_uc
|
||||||
|
static inline void __iomem *ioremap_uc(phys_addr_t offset, size_t size)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#else /* !CONFIG_MMU */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Change "struct page" to physical address.
|
* Change "struct page" to physical address.
|
||||||
*
|
*
|
||||||
|
@ -743,7 +772,6 @@ static inline void *phys_to_virt(unsigned long address)
|
||||||
* you'll need to provide your own definitions.
|
* you'll need to provide your own definitions.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef CONFIG_MMU
|
|
||||||
#ifndef ioremap
|
#ifndef ioremap
|
||||||
#define ioremap ioremap
|
#define ioremap ioremap
|
||||||
static inline void __iomem *ioremap(phys_addr_t offset, size_t size)
|
static inline void __iomem *ioremap(phys_addr_t offset, size_t size)
|
||||||
|
|
|
@ -15,9 +15,13 @@ struct pci_dev;
|
||||||
#ifdef CONFIG_PCI
|
#ifdef CONFIG_PCI
|
||||||
/* Create a virtual mapping cookie for a PCI BAR (memory or IO) */
|
/* Create a virtual mapping cookie for a PCI BAR (memory or IO) */
|
||||||
extern void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long max);
|
extern void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long max);
|
||||||
|
extern void __iomem *pci_iomap_wc(struct pci_dev *dev, int bar, unsigned long max);
|
||||||
extern void __iomem *pci_iomap_range(struct pci_dev *dev, int bar,
|
extern void __iomem *pci_iomap_range(struct pci_dev *dev, int bar,
|
||||||
unsigned long offset,
|
unsigned long offset,
|
||||||
unsigned long maxlen);
|
unsigned long maxlen);
|
||||||
|
extern void __iomem *pci_iomap_wc_range(struct pci_dev *dev, int bar,
|
||||||
|
unsigned long offset,
|
||||||
|
unsigned long maxlen);
|
||||||
/* Create a virtual mapping cookie for a port on a given PCI device.
|
/* Create a virtual mapping cookie for a port on a given PCI device.
|
||||||
* Do not call this directly, it exists to make it easier for architectures
|
* Do not call this directly, it exists to make it easier for architectures
|
||||||
* to override */
|
* to override */
|
||||||
|
@ -34,12 +38,22 @@ static inline void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned lon
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void __iomem *pci_iomap_wc(struct pci_dev *dev, int bar, unsigned long max)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
static inline void __iomem *pci_iomap_range(struct pci_dev *dev, int bar,
|
static inline void __iomem *pci_iomap_range(struct pci_dev *dev, int bar,
|
||||||
unsigned long offset,
|
unsigned long offset,
|
||||||
unsigned long maxlen)
|
unsigned long maxlen)
|
||||||
{
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
static inline void __iomem *pci_iomap_wc_range(struct pci_dev *dev, int bar,
|
||||||
|
unsigned long offset,
|
||||||
|
unsigned long maxlen)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* __ASM_GENERIC_IO_H */
|
#endif /* __ASM_GENERIC_IO_H */
|
||||||
|
|
|
@ -1710,6 +1710,7 @@ static inline void pci_mmcfg_late_init(void) { }
|
||||||
int pci_ext_cfg_avail(void);
|
int pci_ext_cfg_avail(void);
|
||||||
|
|
||||||
void __iomem *pci_ioremap_bar(struct pci_dev *pdev, int bar);
|
void __iomem *pci_ioremap_bar(struct pci_dev *pdev, int bar);
|
||||||
|
void __iomem *pci_ioremap_wc_bar(struct pci_dev *pdev, int bar);
|
||||||
|
|
||||||
#ifdef CONFIG_PCI_IOV
|
#ifdef CONFIG_PCI_IOV
|
||||||
int pci_iov_virtfn_bus(struct pci_dev *dev, int id);
|
int pci_iov_virtfn_bus(struct pci_dev *dev, int id);
|
||||||
|
|
|
@ -35,9 +35,7 @@ struct kyrofb_info {
|
||||||
/* Useful to hold depth here for Linux */
|
/* Useful to hold depth here for Linux */
|
||||||
u8 PIXDEPTH;
|
u8 PIXDEPTH;
|
||||||
|
|
||||||
#ifdef CONFIG_MTRR
|
int wc_cookie;
|
||||||
int mtrr_handle;
|
|
||||||
#endif
|
|
||||||
};
|
};
|
||||||
|
|
||||||
extern int kyro_dev_init(void);
|
extern int kyro_dev_init(void);
|
||||||
|
|
|
@ -51,6 +51,51 @@ void __iomem *pci_iomap_range(struct pci_dev *dev,
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(pci_iomap_range);
|
EXPORT_SYMBOL(pci_iomap_range);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* pci_iomap_wc_range - create a virtual WC mapping cookie for a PCI BAR
|
||||||
|
* @dev: PCI device that owns the BAR
|
||||||
|
* @bar: BAR number
|
||||||
|
* @offset: map memory at the given offset in BAR
|
||||||
|
* @maxlen: max length of the memory to map
|
||||||
|
*
|
||||||
|
* Using this function you will get a __iomem address to your device BAR.
|
||||||
|
* You can access it using ioread*() and iowrite*(). These functions hide
|
||||||
|
* the details if this is a MMIO or PIO address space and will just do what
|
||||||
|
* you expect from them in the correct way. When possible write combining
|
||||||
|
* is used.
|
||||||
|
*
|
||||||
|
* @maxlen specifies the maximum length to map. If you want to get access to
|
||||||
|
* the complete BAR from offset to the end, pass %0 here.
|
||||||
|
* */
|
||||||
|
void __iomem *pci_iomap_wc_range(struct pci_dev *dev,
|
||||||
|
int bar,
|
||||||
|
unsigned long offset,
|
||||||
|
unsigned long maxlen)
|
||||||
|
{
|
||||||
|
resource_size_t start = pci_resource_start(dev, bar);
|
||||||
|
resource_size_t len = pci_resource_len(dev, bar);
|
||||||
|
unsigned long flags = pci_resource_flags(dev, bar);
|
||||||
|
|
||||||
|
|
||||||
|
if (flags & IORESOURCE_IO)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (len <= offset || !start)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
len -= offset;
|
||||||
|
start += offset;
|
||||||
|
if (maxlen && len > maxlen)
|
||||||
|
len = maxlen;
|
||||||
|
|
||||||
|
if (flags & IORESOURCE_MEM)
|
||||||
|
return ioremap_wc(start, len);
|
||||||
|
|
||||||
|
/* What? */
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(pci_iomap_wc_range);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* pci_iomap - create a virtual mapping cookie for a PCI BAR
|
* pci_iomap - create a virtual mapping cookie for a PCI BAR
|
||||||
* @dev: PCI device that owns the BAR
|
* @dev: PCI device that owns the BAR
|
||||||
|
@ -70,4 +115,25 @@ void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long maxlen)
|
||||||
return pci_iomap_range(dev, bar, 0, maxlen);
|
return pci_iomap_range(dev, bar, 0, maxlen);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(pci_iomap);
|
EXPORT_SYMBOL(pci_iomap);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* pci_iomap_wc - create a virtual WC mapping cookie for a PCI BAR
|
||||||
|
* @dev: PCI device that owns the BAR
|
||||||
|
* @bar: BAR number
|
||||||
|
* @maxlen: length of the memory to map
|
||||||
|
*
|
||||||
|
* Using this function you will get a __iomem address to your device BAR.
|
||||||
|
* You can access it using ioread*() and iowrite*(). These functions hide
|
||||||
|
* the details if this is a MMIO or PIO address space and will just do what
|
||||||
|
* you expect from them in the correct way. When possible write combining
|
||||||
|
* is used.
|
||||||
|
*
|
||||||
|
* @maxlen specifies the maximum length to map. If you want to get access to
|
||||||
|
* the complete BAR without checking for its length first, pass %0 here.
|
||||||
|
* */
|
||||||
|
void __iomem *pci_iomap_wc(struct pci_dev *dev, int bar, unsigned long maxlen)
|
||||||
|
{
|
||||||
|
return pci_iomap_wc_range(dev, bar, 0, maxlen);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(pci_iomap_wc);
|
||||||
#endif /* CONFIG_PCI */
|
#endif /* CONFIG_PCI */
|
||||||
|
|
Loading…
Reference in New Issue