Commit 4064e47c authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'csky-for-linus-5.0-rc1' of git://github.com/c-sky/csky-linux

Pull arch/csky bug fixes from Guo Ren:
 "Here are some fixup patches for 5.0-rc1:

   - fix compile error with pte_alloc

   - fix handle_irq_perbit break irq flow

   - fix CACHEV1 store instruction fast retire

   - fix module relocation error with 807 & 860

   - add csky kernel features to documentation"

* tag 'csky-for-linus-5.0-rc1' of git://github.com/c-sky/csky-linux:
  irqchip/csky: fixup handle_irq_perbit break irq
  csky: fixup compile error with pte_alloc
  csky: fixup CACHEV1 store instruction fast retire
  csky: fixup relocation error with 807 & 860
  Documentation/features: Add csky kernel features
parents a88cc8da 56752b21
......@@ -11,6 +11,7 @@
| arm: | TODO |
| arm64: | TODO |
| c6x: | TODO |
| csky: | TODO |
| h8300: | TODO |
| hexagon: | TODO |
| ia64: | TODO |
......
......@@ -11,6 +11,7 @@
| arm: | ok |
| arm64: | ok |
| c6x: | TODO |
| csky: | TODO |
| h8300: | TODO |
| hexagon: | TODO |
| ia64: | TODO |
......
......@@ -11,6 +11,7 @@
| arm: | ok |
| arm64: | ok |
| c6x: | TODO |
| csky: | ok |
| h8300: | TODO |
| hexagon: | ok |
| ia64: | ok |
......
......@@ -11,6 +11,7 @@
| arm: | ok |
| arm64: | ok |
| c6x: | TODO |
| csky: | TODO |
| h8300: | TODO |
| hexagon: | TODO |
| ia64: | TODO |
......
......@@ -11,6 +11,7 @@
| arm: | ok |
| arm64: | ok |
| c6x: | ok |
| csky: | ok |
| h8300: | TODO |
| hexagon: | ok |
| ia64: | ok |
......
......@@ -11,6 +11,7 @@
| arm: | TODO |
| arm64: | ok |
| c6x: | TODO |
| csky: | TODO |
| h8300: | TODO |
| hexagon: | TODO |
| ia64: | TODO |
......
......@@ -11,6 +11,7 @@
| arm: | ok |
| arm64: | ok |
| c6x: | TODO |
| csky: | TODO |
| h8300: | TODO |
| hexagon: | TODO |
| ia64: | TODO |
......
......@@ -11,6 +11,7 @@
| arm: | ok |
| arm64: | ok |
| c6x: | TODO |
| csky: | TODO |
| h8300: | ok |
| hexagon: | ok |
| ia64: | TODO |
......
......@@ -11,6 +11,7 @@
| arm: | TODO |
| arm64: | TODO |
| c6x: | TODO |
| csky: | TODO |
| h8300: | TODO |
| hexagon: | TODO |
| ia64: | TODO |
......
......@@ -11,6 +11,7 @@
| arm: | ok |
| arm64: | ok |
| c6x: | TODO |
| csky: | TODO |
| h8300: | TODO |
| hexagon: | TODO |
| ia64: | ok |
......
......@@ -11,6 +11,7 @@
| arm: | ok |
| arm64: | ok |
| c6x: | TODO |
| csky: | TODO |
| h8300: | TODO |
| hexagon: | TODO |
| ia64: | ok |
......
......@@ -11,6 +11,7 @@
| arm: | ok |
| arm64: | TODO |
| c6x: | TODO |
| csky: | TODO |
| h8300: | TODO |
| hexagon: | TODO |
| ia64: | TODO |
......
......@@ -11,6 +11,7 @@
| arm: | ok |
| arm64: | ok |
| c6x: | TODO |
| csky: | TODO |
| h8300: | TODO |
| hexagon: | TODO |
| ia64: | TODO |
......
......@@ -11,6 +11,7 @@
| arm: | ok |
| arm64: | ok |
| c6x: | TODO |
| csky: | TODO |
| h8300: | TODO |
| hexagon: | TODO |
| ia64: | TODO |
......
......@@ -11,6 +11,7 @@
| arm: | TODO |
| arm64: | TODO |
| c6x: | TODO |
| csky: | TODO |
| h8300: | TODO |
| hexagon: | TODO |
| ia64: | TODO |
......
......@@ -11,6 +11,7 @@
| arm: | ok |
| arm64: | ok |
| c6x: | TODO |
| csky: | ok |
| h8300: | TODO |
| hexagon: | TODO |
| ia64: | TODO |
......
......@@ -11,6 +11,7 @@
| arm: | TODO |
| arm64: | ok |
| c6x: | TODO |
| csky: | TODO |
| h8300: | TODO |
| hexagon: | TODO |
| ia64: | TODO |
......
......@@ -11,6 +11,7 @@
| arm: | ok |
| arm64: | ok |
| c6x: | TODO |
| csky: | TODO |
| h8300: | TODO |
| hexagon: | ok |
| ia64: | TODO |
......
......@@ -11,6 +11,7 @@
| arm: | TODO |
| arm64: | ok |
| c6x: | TODO |
| csky: | ok |
| h8300: | TODO |
| hexagon: | TODO |
| ia64: | TODO |
......
......@@ -11,6 +11,7 @@
| arm: | TODO |
| arm64: | TODO |
| c6x: | TODO |
| csky: | TODO |
| h8300: | TODO |
| hexagon: | TODO |
| ia64: | TODO |
......
......@@ -11,6 +11,7 @@
| arm: | ok |
| arm64: | ok |
| c6x: | TODO |
| csky: | TODO |
| h8300: | TODO |
| hexagon: | TODO |
| ia64: | ok |
......
......@@ -11,6 +11,7 @@
| arm: | ok |
| arm64: | ok |
| c6x: | TODO |
| csky: | TODO |
| h8300: | TODO |
| hexagon: | ok |
| ia64: | TODO |
......
......@@ -11,6 +11,7 @@
| arm: | ok |
| arm64: | ok |
| c6x: | TODO |
| csky: | TODO |
| h8300: | TODO |
| hexagon: | TODO |
| ia64: | TODO |
......
......@@ -11,6 +11,7 @@
| arm: | ok |
| arm64: | ok |
| c6x: | TODO |
| csky: | TODO |
| h8300: | TODO |
| hexagon: | TODO |
| ia64: | TODO |
......
......@@ -34,6 +34,7 @@
| arm: | ok |
| arm64: | ok |
| c6x: | TODO |
| csky: | TODO |
| h8300: | TODO |
| hexagon: | TODO |
| ia64: | TODO |
......
......@@ -11,6 +11,7 @@
| arm: | .. |
| arm64: | ok |
| c6x: | .. |
| csky: | .. |
| h8300: | .. |
| hexagon: | .. |
| ia64: | TODO |
......
......@@ -11,6 +11,7 @@
| arm: | ok |
| arm64: | ok |
| c6x: | TODO |
| csky: | TODO |
| h8300: | TODO |
| hexagon: | TODO |
| ia64: | TODO |
......
......@@ -11,6 +11,7 @@
| arm: | ok |
| arm64: | ok |
| c6x: | TODO |
| csky: | TODO |
| h8300: | TODO |
| hexagon: | TODO |
| ia64: | TODO |
......
......@@ -11,6 +11,7 @@
| arm: | ok |
| arm64: | ok |
| c6x: | ok |
| csky: | ok |
| h8300: | ok |
| hexagon: | ok |
| ia64: | TODO |
......
......@@ -11,6 +11,7 @@
| arm: | ok |
| arm64: | ok |
| c6x: | TODO |
| csky: | TODO |
| h8300: | TODO |
| hexagon: | TODO |
| ia64: | TODO |
......
......@@ -11,6 +11,7 @@
| arm: | ok |
| arm64: | ok |
| c6x: | TODO |
| csky: | TODO |
| h8300: | TODO |
| hexagon: | TODO |
| ia64: | .. |
......
......@@ -11,6 +11,7 @@
| arm: | TODO |
| arm64: | ok |
| c6x: | ok |
| csky: | ok |
| h8300: | ok |
| hexagon: | ok |
| ia64: | ok |
......
......@@ -11,6 +11,7 @@
| arm: | ok |
| arm64: | ok |
| c6x: | TODO |
| csky: | TODO |
| h8300: | TODO |
| hexagon: | TODO |
| ia64: | ok |
......
......@@ -11,6 +11,7 @@
| arm: | ok |
| arm64: | ok |
| c6x: | TODO |
| csky: | TODO |
| h8300: | TODO |
| hexagon: | TODO |
| ia64: | TODO |
......
......@@ -11,6 +11,7 @@
| arm: | TODO |
| arm64: | TODO |
| c6x: | TODO |
| csky: | TODO |
| h8300: | TODO |
| hexagon: | TODO |
| ia64: | ok |
......
......@@ -11,6 +11,7 @@
| arm: | ok |
| arm64: | ok |
| c6x: | .. |
| csky: | .. |
| h8300: | .. |
| hexagon: | .. |
| ia64: | TODO |
......
......@@ -11,6 +11,7 @@
| arm: | TODO |
| arm64: | TODO |
| c6x: | .. |
| csky: | TODO |
| h8300: | .. |
| hexagon: | TODO |
| ia64: | TODO |
......
......@@ -11,6 +11,7 @@
| arm: | TODO |
| arm64: | ok |
| c6x: | TODO |
| csky: | TODO |
| h8300: | TODO |
| hexagon: | TODO |
| ia64: | TODO |
......
......@@ -11,6 +11,7 @@
| arm: | TODO |
| arm64: | TODO |
| c6x: | TODO |
| csky: | TODO |
| h8300: | TODO |
| hexagon: | TODO |
| ia64: | TODO |
......
......@@ -11,6 +11,7 @@
| arm: | .. |
| arm64: | ok |
| c6x: | .. |
| csky: | .. |
| h8300: | .. |
| hexagon: | .. |
| ia64: | ok |
......
......@@ -11,6 +11,7 @@
| arm: | ok |
| arm64: | ok |
| c6x: | TODO |
| csky: | TODO |
| h8300: | TODO |
| hexagon: | TODO |
| ia64: | TODO |
......
......@@ -15,6 +15,31 @@ extern void iounmap(void *addr);
extern int remap_area_pages(unsigned long address, phys_addr_t phys_addr,
size_t size, unsigned long flags);
/*
* I/O memory access primitives. Reads are ordered relative to any
* following Normal memory access. Writes are ordered relative to any prior
* Normal memory access.
*
* For CACHEV1 (807, 810), store instruction could fast retire, so we need
* another mb() to prevent st fast retire.
*
* For CACHEV2 (860), store instruction with PAGE_ATTR_NO_BUFFERABLE won't
* fast retire.
*/
#define readb(c) ({ u8 __v = readb_relaxed(c); rmb(); __v; })
#define readw(c) ({ u16 __v = readw_relaxed(c); rmb(); __v; })
#define readl(c) ({ u32 __v = readl_relaxed(c); rmb(); __v; })
#ifdef CONFIG_CPU_HAS_CACHEV2
#define writeb(v,c) ({ wmb(); writeb_relaxed((v),(c)); })
#define writew(v,c) ({ wmb(); writew_relaxed((v),(c)); })
#define writel(v,c) ({ wmb(); writel_relaxed((v),(c)); })
#else
#define writeb(v,c) ({ wmb(); writeb_relaxed((v),(c)); mb(); })
#define writew(v,c) ({ wmb(); writew_relaxed((v),(c)); mb(); })
#define writel(v,c) ({ wmb(); writel_relaxed((v),(c)); mb(); })
#endif
#define ioremap_nocache(phy, sz) ioremap(phy, sz)
#define ioremap_wc ioremap_nocache
#define ioremap_wt ioremap_nocache
......
......@@ -24,41 +24,34 @@ static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd,
extern void pgd_init(unsigned long *p);
static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm,
unsigned long address)
static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm)
{
pte_t *pte;
unsigned long *kaddr, i;
unsigned long i;
pte = (pte_t *) __get_free_pages(GFP_KERNEL | __GFP_RETRY_MAYFAIL,
PTE_ORDER);
kaddr = (unsigned long *)pte;
if (address & 0x80000000)
for (i = 0; i < (PAGE_SIZE/4); i++)
*(kaddr + i) = 0x1;
else
clear_page(kaddr);
pte = (pte_t *) __get_free_page(GFP_KERNEL);
if (!pte)
return NULL;
for (i = 0; i < PAGE_SIZE/sizeof(pte_t); i++)
(pte + i)->pte_low = _PAGE_GLOBAL;
return pte;
}
static inline struct page *pte_alloc_one(struct mm_struct *mm,
unsigned long address)
static inline struct page *pte_alloc_one(struct mm_struct *mm)
{
struct page *pte;
unsigned long *kaddr, i;
pte = alloc_pages(GFP_KERNEL | __GFP_RETRY_MAYFAIL, PTE_ORDER);
if (pte) {
kaddr = kmap_atomic(pte);
if (address & 0x80000000) {
for (i = 0; i < (PAGE_SIZE/4); i++)
*(kaddr + i) = 0x1;
} else
clear_page(kaddr);
kunmap_atomic(kaddr);
pgtable_page_ctor(pte);
pte = alloc_pages(GFP_KERNEL | __GFP_ZERO, 0);
if (!pte)
return NULL;
if (!pgtable_page_ctor(pte)) {
__free_page(pte);
return NULL;
}
return pte;
}
......
......@@ -12,7 +12,7 @@
#include <linux/spinlock.h>
#include <asm/pgtable.h>
#if defined(__CSKYABIV2__)
#ifdef CONFIG_CPU_CK810
#define IS_BSR32(hi16, lo16) (((hi16) & 0xFC00) == 0xE000)
#define IS_JSRI32(hi16, lo16) ((hi16) == 0xEAE0)
......@@ -25,6 +25,26 @@
*(uint16_t *)(addr) = 0xE8Fa; \
*((uint16_t *)(addr) + 1) = 0x0000; \
} while (0)
static void jsri_2_lrw_jsr(uint32_t *location)
{
uint16_t location_tmp = (uint16_t *)location;
if (IS_BSR32(*location_tmp, *(location_tmp + 1)))
return;
if (IS_JSRI32(*location_tmp, *(location_tmp + 1))) {
/* jsri 0x... --> lrw r26, 0x... */
CHANGE_JSRI_TO_LRW(location);
/* lsli r0, r0 --> jsr r26 */
SET_JSR32_R26(location + 1);
}
}
#else
static void inline jsri_2_lrw_jsr(uint32_t *location)
{
return;
}
#endif
int apply_relocate_add(Elf32_Shdr *sechdrs, const char *strtab,
......@@ -35,9 +55,6 @@ int apply_relocate_add(Elf32_Shdr *sechdrs, const char *strtab,
Elf32_Sym *sym;
uint32_t *location;
short *temp;
#if defined(__CSKYABIV2__)
uint16_t *location_tmp;
#endif
for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) {
/* This is where to make the change */
......@@ -59,18 +76,7 @@ int apply_relocate_add(Elf32_Shdr *sechdrs, const char *strtab,
case R_CSKY_PCRELJSR_IMM11BY2:
break;
case R_CSKY_PCRELJSR_IMM26BY2:
#if defined(__CSKYABIV2__)
location_tmp = (uint16_t *)location;
if (IS_BSR32(*location_tmp, *(location_tmp + 1)))
break;
if (IS_JSRI32(*location_tmp, *(location_tmp + 1))) {
/* jsri 0x... --> lrw r26, 0x... */
CHANGE_JSRI_TO_LRW(location);
/* lsli r0, r0 --> jsr r26 */
SET_JSR32_R26(location + 1);
}
#endif
jsri_2_lrw_jsr(location);
break;
case R_CSKY_ADDR_HI16:
temp = ((short *)location) + 1;
......
......@@ -95,7 +95,7 @@ static inline void setup_irq_channel(u32 magic, void __iomem *reg_addr)
/* Setup 64 channel slots */
for (i = 0; i < INTC_IRQS; i += 4)
writel_relaxed(build_channel_val(i, magic), reg_addr + i);
writel(build_channel_val(i, magic), reg_addr + i);
}
static int __init
......@@ -135,16 +135,10 @@ ck_intc_init_comm(struct device_node *node, struct device_node *parent)
static inline bool handle_irq_perbit(struct pt_regs *regs, u32 hwirq,
u32 irq_base)
{
u32 irq;
if (hwirq == 0)
return 0;
while (hwirq) {
irq = __ffs(hwirq);
hwirq &= ~BIT(irq);
handle_domain_irq(root_domain, irq_base + irq, regs);
}
handle_domain_irq(root_domain, irq_base + __fls(hwirq), regs);
return 1;
}
......@@ -154,12 +148,16 @@ static void gx_irq_handler(struct pt_regs *regs)
{
bool ret;
do {
retry:
ret = handle_irq_perbit(regs,
readl_relaxed(reg_base + GX_INTC_PEN31_00), 0);
ret |= handle_irq_perbit(regs,
readl_relaxed(reg_base + GX_INTC_PEN63_32), 32);
} while (ret);
readl(reg_base + GX_INTC_PEN63_32), 32);
if (ret)
goto retry;
ret = handle_irq_perbit(regs,
readl(reg_base + GX_INTC_PEN31_00), 0);
if (ret)
goto retry;
}
static int __init
......@@ -174,14 +172,14 @@ gx_intc_init(struct device_node *node, struct device_node *parent)
/*
* Initial enable reg to disable all interrupts
*/
writel_relaxed(0x0, reg_base + GX_INTC_NEN31_00);
writel_relaxed(0x0, reg_base + GX_INTC_NEN63_32);
writel(0x0, reg_base + GX_INTC_NEN31_00);
writel(0x0, reg_base + GX_INTC_NEN63_32);
/*
* Initial mask reg with all unmasked, because we only use enalbe reg
*/
writel_relaxed(0x0, reg_base + GX_INTC_NMASK31_00);
writel_relaxed(0x0, reg_base + GX_INTC_NMASK63_32);
writel(0x0, reg_base + GX_INTC_NMASK31_00);
writel(0x0, reg_base + GX_INTC_NMASK63_32);
setup_irq_channel(0x03020100, reg_base + GX_INTC_SOURCE);
......@@ -204,20 +202,29 @@ static void ck_irq_handler(struct pt_regs *regs)
void __iomem *reg_pen_lo = reg_base + CK_INTC_PEN31_00;
void __iomem *reg_pen_hi = reg_base + CK_INTC_PEN63_32;
do {
/* handle 0 - 31 irqs */
ret = handle_irq_perbit(regs, readl_relaxed(reg_pen_lo), 0);
ret |= handle_irq_perbit(regs, readl_relaxed(reg_pen_hi), 32);
retry:
/* handle 0 - 63 irqs */
ret = handle_irq_perbit(regs, readl(reg_pen_hi), 32);
if (ret)
goto retry;
ret = handle_irq_perbit(regs, readl(reg_pen_lo), 0);
if (ret)
goto retry;
if (nr_irq == INTC_IRQS)
continue;
return;
/* handle 64 - 127 irqs */
ret |= handle_irq_perbit(regs,
readl_relaxed(reg_pen_lo + CK_INTC_DUAL_BASE), 64);
ret |= handle_irq_perbit(regs,
readl_relaxed(reg_pen_hi + CK_INTC_DUAL_BASE), 96);
} while (ret);
ret = handle_irq_perbit(regs,
readl(reg_pen_hi + CK_INTC_DUAL_BASE), 96);
if (ret)
goto retry;
ret = handle_irq_perbit(regs,
readl(reg_pen_lo + CK_INTC_DUAL_BASE), 64);
if (ret)
goto retry;
}
static int __init
......@@ -230,11 +237,11 @@ ck_intc_init(struct device_node *node, struct device_node *parent)
return ret;
/* Initial enable reg to disable all interrupts */
writel_relaxed(0, reg_base + CK_INTC_NEN31_00);
writel_relaxed(0, reg_base + CK_INTC_NEN63_32);
writel(0, reg_base + CK_INTC_NEN31_00);
writel(0, reg_base + CK_INTC_NEN63_32);
/* Enable irq intc */
writel_relaxed(BIT(31), reg_base + CK_INTC_ICR);
writel(BIT(31), reg_base + CK_INTC_ICR);
ck_set_gc(node, reg_base, CK_INTC_NEN31_00, 0);
ck_set_gc(node, reg_base, CK_INTC_NEN63_32, 32);
......@@ -260,8 +267,8 @@ ck_dual_intc_init(struct device_node *node, struct device_node *parent)
return ret;
/* Initial enable reg to disable all interrupts */
writel_relaxed(0, reg_base + CK_INTC_NEN31_00 + CK_INTC_DUAL_BASE);
writel_relaxed(0, reg_base + CK_INTC_NEN63_32 + CK_INTC_DUAL_BASE);
writel(0, reg_base + CK_INTC_NEN31_00 + CK_INTC_DUAL_BASE);
writel(0, reg_base + CK_INTC_NEN63_32 + CK_INTC_DUAL_BASE);
ck_set_gc(node, reg_base + CK_INTC_DUAL_BASE, CK_INTC_NEN31_00, 64);
ck_set_gc(node, reg_base + CK_INTC_DUAL_BASE, CK_INTC_NEN63_32, 96);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment