Merge tag 'csky-for-linus-5.4-rc1' of git://github.com/c-sky/csky-linux
Pull csky updates from Guo Ren: "This round of csky subsystem just some fixups: - Fix mb() synchronization problem - Fix dma_alloc_coherent with PAGE_SO attribute - Fix cache_op failed when cross memory ZONEs - Optimize arch_sync_dma_for_cpu/device with dma_inv_range - Fix ioremap function losing - Fix arch_get_unmapped_area() implementation - Fix defer cache flush for 610 - Support kernel non-aligned access - Fix 610 vipt cache flush mechanism - Fix add zero_fp fixup perf backtrace panic - Move static keyword to the front of declaration - Fix csky_pmu.max_period assignment - Use generic free_initrd_mem() - entry: Remove unneeded need_resched() loop" * tag 'csky-for-linus-5.4-rc1' of git://github.com/c-sky/csky-linux: csky: Move static keyword to the front of declaration csky: entry: Remove unneeded need_resched() loop csky: Fixup csky_pmu.max_period assignment csky: Fixup add zero_fp fixup perf backtrace panic csky: Use generic free_initrd_mem() csky: Fixup 610 vipt cache flush mechanism csky: Support kernel non-aligned access csky: Fixup defer cache flush for 610 csky: Fixup arch_get_unmapped_area() implementation csky: Fixup ioremap function losing csky: Optimize arch_sync_dma_for_cpu/device with dma_inv_range csky/dma: Fixup cache_op failed when cross memory ZONEs csky: Fixup dma_alloc_coherent with PAGE_SO attribute csky: Fixup mb() synchronization problem
Bu işleme şunda yer alıyor:
@@ -120,7 +120,12 @@ void dma_wbinv_range(unsigned long start, unsigned long end)
|
||||
cache_op_range(start, end, DATA_CACHE|CACHE_CLR|CACHE_INV, 1);
|
||||
}
|
||||
|
||||
void dma_inv_range(unsigned long start, unsigned long end)
|
||||
{
|
||||
cache_op_range(start, end, DATA_CACHE|CACHE_CLR|CACHE_INV, 1);
|
||||
}
|
||||
|
||||
void dma_wb_range(unsigned long start, unsigned long end)
|
||||
{
|
||||
cache_op_range(start, end, DATA_CACHE|CACHE_INV, 1);
|
||||
cache_op_range(start, end, DATA_CACHE|CACHE_CLR|CACHE_INV, 1);
|
||||
}
|
||||
|
@@ -69,11 +69,20 @@ void dma_wbinv_range(unsigned long start, unsigned long end)
|
||||
sync_is();
|
||||
}
|
||||
|
||||
void dma_inv_range(unsigned long start, unsigned long end)
|
||||
{
|
||||
unsigned long i = start & ~(L1_CACHE_BYTES - 1);
|
||||
|
||||
for (; i < end; i += L1_CACHE_BYTES)
|
||||
asm volatile("dcache.iva %0\n"::"r"(i):"memory");
|
||||
sync_is();
|
||||
}
|
||||
|
||||
void dma_wb_range(unsigned long start, unsigned long end)
|
||||
{
|
||||
unsigned long i = start & ~(L1_CACHE_BYTES - 1);
|
||||
|
||||
for (; i < end; i += L1_CACHE_BYTES)
|
||||
asm volatile("dcache.civa %0\n"::"r"(i):"memory");
|
||||
asm volatile("dcache.cva %0\n"::"r"(i):"memory");
|
||||
sync_is();
|
||||
}
|
||||
|
@@ -14,69 +14,50 @@
|
||||
#include <linux/version.h>
|
||||
#include <asm/cache.h>
|
||||
|
||||
void arch_dma_prep_coherent(struct page *page, size_t size)
|
||||
{
|
||||
if (PageHighMem(page)) {
|
||||
unsigned int count = PAGE_ALIGN(size) >> PAGE_SHIFT;
|
||||
|
||||
do {
|
||||
void *ptr = kmap_atomic(page);
|
||||
size_t _size = (size < PAGE_SIZE) ? size : PAGE_SIZE;
|
||||
|
||||
memset(ptr, 0, _size);
|
||||
dma_wbinv_range((unsigned long)ptr,
|
||||
(unsigned long)ptr + _size);
|
||||
|
||||
kunmap_atomic(ptr);
|
||||
|
||||
page++;
|
||||
size -= PAGE_SIZE;
|
||||
count--;
|
||||
} while (count);
|
||||
} else {
|
||||
void *ptr = page_address(page);
|
||||
|
||||
memset(ptr, 0, size);
|
||||
dma_wbinv_range((unsigned long)ptr, (unsigned long)ptr + size);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void cache_op(phys_addr_t paddr, size_t size,
|
||||
void (*fn)(unsigned long start, unsigned long end))
|
||||
{
|
||||
struct page *page = pfn_to_page(paddr >> PAGE_SHIFT);
|
||||
unsigned int offset = paddr & ~PAGE_MASK;
|
||||
size_t left = size;
|
||||
unsigned long start;
|
||||
struct page *page = phys_to_page(paddr);
|
||||
void *start = __va(page_to_phys(page));
|
||||
unsigned long offset = offset_in_page(paddr);
|
||||
size_t left = size;
|
||||
|
||||
do {
|
||||
size_t len = left;
|
||||
|
||||
if (offset + len > PAGE_SIZE)
|
||||
len = PAGE_SIZE - offset;
|
||||
|
||||
if (PageHighMem(page)) {
|
||||
void *addr;
|
||||
start = kmap_atomic(page);
|
||||
|
||||
if (offset + len > PAGE_SIZE) {
|
||||
if (offset >= PAGE_SIZE) {
|
||||
page += offset >> PAGE_SHIFT;
|
||||
offset &= ~PAGE_MASK;
|
||||
}
|
||||
len = PAGE_SIZE - offset;
|
||||
}
|
||||
fn((unsigned long)start + offset,
|
||||
(unsigned long)start + offset + len);
|
||||
|
||||
addr = kmap_atomic(page);
|
||||
start = (unsigned long)(addr + offset);
|
||||
fn(start, start + len);
|
||||
kunmap_atomic(addr);
|
||||
kunmap_atomic(start);
|
||||
} else {
|
||||
start = (unsigned long)phys_to_virt(paddr);
|
||||
fn(start, start + size);
|
||||
fn((unsigned long)start + offset,
|
||||
(unsigned long)start + offset + len);
|
||||
}
|
||||
offset = 0;
|
||||
|
||||
page++;
|
||||
start += PAGE_SIZE;
|
||||
left -= len;
|
||||
} while (left);
|
||||
}
|
||||
|
||||
static void dma_wbinv_set_zero_range(unsigned long start, unsigned long end)
|
||||
{
|
||||
memset((void *)start, 0, end - start);
|
||||
dma_wbinv_range(start, end);
|
||||
}
|
||||
|
||||
void arch_dma_prep_coherent(struct page *page, size_t size)
|
||||
{
|
||||
cache_op(page_to_phys(page), size, dma_wbinv_set_zero_range);
|
||||
}
|
||||
|
||||
void arch_sync_dma_for_device(struct device *dev, phys_addr_t paddr,
|
||||
size_t size, enum dma_data_direction dir)
|
||||
{
|
||||
@@ -98,11 +79,10 @@ void arch_sync_dma_for_cpu(struct device *dev, phys_addr_t paddr,
|
||||
{
|
||||
switch (dir) {
|
||||
case DMA_TO_DEVICE:
|
||||
cache_op(paddr, size, dma_wb_range);
|
||||
break;
|
||||
return;
|
||||
case DMA_FROM_DEVICE:
|
||||
case DMA_BIDIRECTIONAL:
|
||||
cache_op(paddr, size, dma_wbinv_range);
|
||||
cache_op(paddr, size, dma_inv_range);
|
||||
break;
|
||||
default:
|
||||
BUG();
|
||||
|
@@ -60,22 +60,6 @@ void __init mem_init(void)
|
||||
mem_init_print_info(NULL);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_BLK_DEV_INITRD
|
||||
void free_initrd_mem(unsigned long start, unsigned long end)
|
||||
{
|
||||
if (start < end)
|
||||
pr_info("Freeing initrd memory: %ldk freed\n",
|
||||
(end - start) >> 10);
|
||||
|
||||
for (; start < end; start += PAGE_SIZE) {
|
||||
ClearPageReserved(virt_to_page(start));
|
||||
init_page_count(virt_to_page(start));
|
||||
free_page(start);
|
||||
totalram_pages_inc();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
extern char __init_begin[], __init_end[];
|
||||
|
||||
void free_initmem(void)
|
||||
|
@@ -8,12 +8,12 @@
|
||||
|
||||
#include <asm/pgtable.h>
|
||||
|
||||
void __iomem *ioremap(phys_addr_t addr, size_t size)
|
||||
static void __iomem *__ioremap_caller(phys_addr_t addr, size_t size,
|
||||
pgprot_t prot, void *caller)
|
||||
{
|
||||
phys_addr_t last_addr;
|
||||
unsigned long offset, vaddr;
|
||||
struct vm_struct *area;
|
||||
pgprot_t prot;
|
||||
|
||||
last_addr = addr + size - 1;
|
||||
if (!size || last_addr < addr)
|
||||
@@ -23,15 +23,12 @@ void __iomem *ioremap(phys_addr_t addr, size_t size)
|
||||
addr &= PAGE_MASK;
|
||||
size = PAGE_ALIGN(size + offset);
|
||||
|
||||
area = get_vm_area_caller(size, VM_ALLOC, __builtin_return_address(0));
|
||||
area = get_vm_area_caller(size, VM_IOREMAP, caller);
|
||||
if (!area)
|
||||
return NULL;
|
||||
|
||||
vaddr = (unsigned long)area->addr;
|
||||
|
||||
prot = __pgprot(_PAGE_PRESENT | __READABLE | __WRITEABLE |
|
||||
_PAGE_GLOBAL | _CACHE_UNCACHED | _PAGE_SO);
|
||||
|
||||
if (ioremap_page_range(vaddr, vaddr + size, addr, prot)) {
|
||||
free_vm_area(area);
|
||||
return NULL;
|
||||
@@ -39,7 +36,20 @@ void __iomem *ioremap(phys_addr_t addr, size_t size)
|
||||
|
||||
return (void __iomem *)(vaddr + offset);
|
||||
}
|
||||
EXPORT_SYMBOL(ioremap);
|
||||
|
||||
void __iomem *__ioremap(phys_addr_t phys_addr, size_t size, pgprot_t prot)
|
||||
{
|
||||
return __ioremap_caller(phys_addr, size, prot,
|
||||
__builtin_return_address(0));
|
||||
}
|
||||
EXPORT_SYMBOL(__ioremap);
|
||||
|
||||
void __iomem *ioremap_cache(phys_addr_t phys_addr, size_t size)
|
||||
{
|
||||
return __ioremap_caller(phys_addr, size, PAGE_KERNEL,
|
||||
__builtin_return_address(0));
|
||||
}
|
||||
EXPORT_SYMBOL(ioremap_cache);
|
||||
|
||||
void iounmap(void __iomem *addr)
|
||||
{
|
||||
@@ -51,10 +61,9 @@ pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
|
||||
unsigned long size, pgprot_t vma_prot)
|
||||
{
|
||||
if (!pfn_valid(pfn)) {
|
||||
vma_prot.pgprot |= _PAGE_SO;
|
||||
return pgprot_noncached(vma_prot);
|
||||
} else if (file->f_flags & O_SYNC) {
|
||||
return pgprot_noncached(vma_prot);
|
||||
return pgprot_writecombine(vma_prot);
|
||||
}
|
||||
|
||||
return vma_prot;
|
||||
|
Yeni konuda referans
Bir kullanıcı engelle