[2/5] Cleanup management of kmem_caches for pagetables
Currently we have a fair bit of rather fiddly code to manage the various kmem_caches used to store page tables of various levels. We generally have two caches holding some combination of PGD, PUD and PMD tables, plus several more for the special hugepage pagetables. This patch cleans this all up by taking a different approach. Rather than the caches being designated as for PUDs or for hugeptes for 16M pages, the caches are simply allocated to be a specific size. Thus sharing of caches between different types/levels of pagetables happens naturally. The pagetable size, where needed, is passed around encoded in the same way as {PGD,PUD,PMD}_INDEX_SIZE; that is n where the pagetable contains 2^n pointers. Signed-off-by: David Gibson d...@au1.ibm.com --- arch/powerpc/include/asm/pgalloc-64.h| 43 - arch/powerpc/include/asm/pgalloc.h | 25 +++-- arch/powerpc/include/asm/pgtable-ppc64.h |1 arch/powerpc/mm/hugetlbpage.c| 45 --- arch/powerpc/mm/init_64.c| 42 ++-- arch/powerpc/mm/pgtable.c| 25 +++-- 6 files changed, 73 insertions(+), 108 deletions(-) Index: working-2.6/arch/powerpc/mm/init_64.c === --- working-2.6.orig/arch/powerpc/mm/init_64.c 2009-09-04 14:35:30.0 +1000 +++ working-2.6/arch/powerpc/mm/init_64.c 2009-09-04 14:38:20.0 +1000 @@ -148,30 +148,30 @@ static void pmd_ctor(void *addr) memset(addr, 0, PMD_TABLE_SIZE); } -static const unsigned int pgtable_cache_size[2] = { - PGD_TABLE_SIZE, PMD_TABLE_SIZE -}; -static const char *pgtable_cache_name[ARRAY_SIZE(pgtable_cache_size)] = { -#ifdef CONFIG_PPC_64K_PAGES - pgd_cache, pmd_cache, -#else - pgd_cache, pud_pmd_cache, -#endif /* CONFIG_PPC_64K_PAGES */ -}; - -#ifdef CONFIG_HUGETLB_PAGE -/* Hugepages need an extra cache per hugepagesize, initialized in - * hugetlbpage.c. We can't put into the tables above, because HPAGE_SHIFT - * is not compile time constant. */ -struct kmem_cache *pgtable_cache[ARRAY_SIZE(pgtable_cache_size)+MMU_PAGE_COUNT]; -#else -struct kmem_cache *pgtable_cache[ARRAY_SIZE(pgtable_cache_size)]; -#endif +struct kmem_cache *pgtable_cache[PGF_SHIFT_MASK]; + +void pgtable_cache_add(unsigned shift, void (*ctor)(void *)) +{ + char *name; + unsigned long table_size = sizeof(void *) shift; + struct kmem_cache *new; + + BUG_ON((shift 1) || (shift PGF_SHIFT_MASK)); + if (PGT_CACHE(shift)) + return; /* Already have a cache of this size */ + name = kasprintf(GFP_KERNEL, pgtable-2^%d, shift); + new = kmem_cache_create(name, table_size, table_size, 0, ctor); + PGT_CACHE(shift) = new; +} + void pgtable_cache_init(void) { - pgtable_cache[0] = kmem_cache_create(pgtable_cache_name[0], PGD_TABLE_SIZE, PGD_TABLE_SIZE, SLAB_PANIC, pgd_ctor); - pgtable_cache[1] = kmem_cache_create(pgtable_cache_name[1], PMD_TABLE_SIZE, PMD_TABLE_SIZE, SLAB_PANIC, pmd_ctor); + pgtable_cache_add(PGD_INDEX_SIZE, pgd_ctor); + pgtable_cache_add(PMD_INDEX_SIZE, pmd_ctor); + if (!PGT_CACHE(PGD_INDEX_SIZE) || !PGT_CACHE(PMD_INDEX_SIZE)) + panic(Couldn't allocate pgtable caches); + BUG_ON(!PGT_CACHE(PUD_INDEX_SIZE)); } #ifdef CONFIG_SPARSEMEM_VMEMMAP Index: working-2.6/arch/powerpc/include/asm/pgalloc-64.h === --- working-2.6.orig/arch/powerpc/include/asm/pgalloc-64.h 2009-09-04 14:35:30.0 +1000 +++ working-2.6/arch/powerpc/include/asm/pgalloc-64.h 2009-09-04 14:38:20.0 +1000 @@ -16,22 +16,17 @@ static inline void subpage_prot_free(pgd #endif extern struct kmem_cache *pgtable_cache[]; - -#define PGD_CACHE_NUM 0 -#define PUD_CACHE_NUM 1 -#define PMD_CACHE_NUM 1 -#define HUGEPTE_CACHE_NUM 2 -#define PTE_NONCACHE_NUM 7 /* from GFP rather than kmem_cache */ +#define PGT_CACHE(shift) (pgtable_cache[(shift)-1]) static inline pgd_t *pgd_alloc(struct mm_struct *mm) { - return kmem_cache_alloc(pgtable_cache[PGD_CACHE_NUM], GFP_KERNEL); + return kmem_cache_alloc(PGT_CACHE(PGD_INDEX_SIZE), GFP_KERNEL); } static inline void pgd_free(struct mm_struct *mm, pgd_t *pgd) { subpage_prot_free(pgd); - kmem_cache_free(pgtable_cache[PGD_CACHE_NUM], pgd); + kmem_cache_free(PGT_CACHE(PGD_INDEX_SIZE), pgd); } #ifndef CONFIG_PPC_64K_PAGES @@ -40,13 +35,13 @@ static inline void pgd_free(struct mm_st static inline pud_t *pud_alloc_one(struct mm_struct *mm, unsigned long addr) { - return kmem_cache_alloc(pgtable_cache[PUD_CACHE_NUM], + return kmem_cache_alloc(PGT_CACHE(PUD_INDEX_SIZE), GFP_KERNEL|__GFP_REPEAT); } static inline void pud_free(struct mm_struct *mm,
[4/5] Cleanup initialization of hugepages on powerpc
This patch simplifies the logic used to initialize hugepages on powerpc. The somewhat oddly named set_huge_psize() is renamed to add_huge_page_size() and now does all necessary verification of whether it's given a valid hugepage sizes (instead of just some) and instantiates the generic hstate structure (but no more). hugetlbpage_init() now steps through the available pagesizes, checks if they're valid for hugepages by calling add_huge_page_size() and initializes the kmem_caches for the hugepage pagetables. This means we can now eliminate the mmu_huge_psizes array, since we no longer need to pass the sizing information for the pagetable caches from set_huge_psize() into hugetlbpage_init() Signed-off-by: David Gibson d...@au1.ibm.com --- arch/powerpc/mm/hugetlbpage.c | 106 +++--- 1 file changed, 49 insertions(+), 57 deletions(-) Index: working-2.6/arch/powerpc/mm/hugetlbpage.c === --- working-2.6.orig/arch/powerpc/mm/hugetlbpage.c 2009-09-09 15:15:12.0 +1000 +++ working-2.6/arch/powerpc/mm/hugetlbpage.c 2009-09-09 15:22:49.0 +1000 @@ -37,11 +37,6 @@ static unsigned long gpage_freearray[MAX_NUMBER_GPAGES]; static unsigned nr_gpages; -/* Array of valid huge page sizes - non-zero value(hugepte_shift) is - * stored for the huge page sizes that are valid. - */ -static unsigned int mmu_huge_psizes[MMU_PAGE_COUNT] = { }; /* initialize all to 0 */ - /* Flag to mark huge PD pointers. This means pmd_bad() and pud_bad() * will choke on pointers to hugepte tables, which is handy for * catching screwups early. */ @@ -502,8 +497,6 @@ unsigned long hugetlb_get_unmapped_area( struct hstate *hstate = hstate_file(file); int mmu_psize = shift_to_mmu_psize(huge_page_shift(hstate)); - if (!mmu_huge_psizes[mmu_psize]) - return -EINVAL; return slice_get_unmapped_area(addr, len, flags, mmu_psize, 1, 0); } @@ -666,47 +659,46 @@ repeat: return err; } -static void __init set_huge_psize(int psize) +static int __init add_huge_page_size(unsigned long long size) { - unsigned pdshift; + int shift = __ffs(size); + int mmu_psize; /* Check that it is a page size supported by the hardware and -* that it fits within pagetable limits. */ - if (mmu_psize_defs[psize].shift - mmu_psize_defs[psize].shift SID_SHIFT_1T - (mmu_psize_defs[psize].shift MIN_HUGEPTE_SHIFT || -mmu_psize_defs[psize].shift == PAGE_SHIFT_64K || -mmu_psize_defs[psize].shift == PAGE_SHIFT_16G)) { - /* Return if huge page size has already been setup or is the -* same as the base page size. */ - if (mmu_huge_psizes[psize] || - mmu_psize_defs[psize].shift == PAGE_SHIFT) - return; - hugetlb_add_hstate(mmu_psize_defs[psize].shift - PAGE_SHIFT); +* that it fits within pagetable and slice limits. */ + if (!is_power_of_2(size) + || (shift SLICE_HIGH_SHIFT) || (shift = PAGE_SHIFT)) + return -EINVAL; - if (mmu_psize_defs[psize].shift PMD_SHIFT) - pdshift = PMD_SHIFT; - else if (mmu_psize_defs[psize].shift PUD_SHIFT) - pdshift = PUD_SHIFT; - else - pdshift = PGDIR_SHIFT; - mmu_huge_psizes[psize] = pdshift - mmu_psize_defs[psize].shift; - } + if ((mmu_psize = shift_to_mmu_psize(shift)) 0) + return -EINVAL; + +#ifndef CONFIG_SPU_FS_64K_LS + /* Disable support for 64K huge pages when 64K SPU local store +* support is enabled as the current implementation conflicts. +*/ + if (size == PAGE_SIZE_64K) + return -EINVAL; +#endif /* CONFIG_SPU_FS_64K_LS */ + + BUG_ON(mmu_psize_defs[mmu_psize].shift != shift); + + /* Return if huge page size has already been setup */ + if (size_to_hstate(size)) + return 0; + + hugetlb_add_hstate(shift - PAGE_SHIFT); + + return 0; } static int __init hugepage_setup_sz(char *str) { unsigned long long size; - int mmu_psize; - int shift; size = memparse(str, str); - shift = __ffs(size); - mmu_psize = shift_to_mmu_psize(shift); - if (mmu_psize = 0 mmu_psize_defs[mmu_psize].shift) - set_huge_psize(mmu_psize); - else + if (add_huge_page_size(size) != 0) printk(KERN_WARNING Invalid huge page size specified(%llu)\n, size); return 1; @@ -720,31 +712,31 @@ static int __init hugetlbpage_init(void) if (!cpu_has_feature(CPU_FTR_16M_PAGE)) return -ENODEV; - /* Add supported huge page sizes. Need to change HUGE_MAX_HSTATE -* and adjust PTE_NONCACHE_NUM if the
[3/5] Allow more flexible layouts for hugepage pagetables
Currently each available hugepage size uses a slightly different pagetable layout: that is, the bottem level table of pointers to hugepages is a different size, and may branch off from the normal page tables at a different level. Every hugepage aware path that needs to walk the pagetables must therefore look up the hugepage size from the slice info first, and work out the correct way to walk the pagetables accordingly. Future hardware is likely to add more possible hugepage sizes, more layout options and more mess. This patch, therefore reworks the handling of hugepage pagetables to reduce this complexity. In the new scheme, instead of having to consult the slice mask, pagetable walking code can check a flag in the PGD/PUD/PMD entries to see where to branch off to hugepage pagetables, and the entry also contains the information (eseentially hugepage shift) necessary to then interpret that table without recourse to the slice mask. This scheme can be extended neatly to handle multiple levels of self-describing special hugepage pagetables, although for now we assume only one level exists. This approach means that only the pagetable allocation path needs to know how the pagetables should be set out. All other (hugepage) pagetable walking paths can just interpret the structure as they go. There already was a flag bit in PGD/PUD/PMD entries for hugepage directory pointers, but it was only used for debug. We alter that flag bit to instead be a 0 in the MSB to indicate a hugepage pagetable pointer (normally it would be 1 since the pointer lies in the linear mapping). This means that asm pagetable walking can test for (and punt on) hugepage pointers with the same test that checks for unpopulated page directory entries (beq becomes bge), since hugepage pointers will always be positive, and normal pointers always negative. While we're at it, we get rid of the confusing (and grep defeating) #defining of hugepte_shift to be the same thing as mmu_huge_psizes. Signed-off-by: David Gibson d...@au1.ibm.com --- arch/powerpc/include/asm/hugetlb.h | 12 arch/powerpc/include/asm/mmu-hash64.h| 14 arch/powerpc/include/asm/pgtable-ppc64.h | 13 arch/powerpc/kernel/perf_callchain.c | 20 - arch/powerpc/mm/gup.c| 149 + arch/powerpc/mm/hash_utils_64.c | 17 - arch/powerpc/mm/hugetlbpage.c| 473 ++- arch/powerpc/mm/init_64.c| 11 8 files changed, 304 insertions(+), 405 deletions(-) Index: working-2.6/arch/powerpc/mm/hugetlbpage.c === --- working-2.6.orig/arch/powerpc/mm/hugetlbpage.c 2009-09-08 11:44:17.0 +1000 +++ working-2.6/arch/powerpc/mm/hugetlbpage.c 2009-09-08 17:13:33.0 +1000 @@ -40,25 +40,11 @@ static unsigned nr_gpages; /* Array of valid huge page sizes - non-zero value(hugepte_shift) is * stored for the huge page sizes that are valid. */ -unsigned int mmu_huge_psizes[MMU_PAGE_COUNT] = { }; /* initialize all to 0 */ - -#define hugepte_shift mmu_huge_psizes -#define HUGEPTE_INDEX_SIZE(psize) (mmu_huge_psizes[(psize)]) -#define PTRS_PER_HUGEPTE(psize)(1 mmu_huge_psizes[psize]) - -#define HUGEPD_SHIFT(psize)(mmu_psize_to_shift(psize) \ -+ HUGEPTE_INDEX_SIZE(psize)) -#define HUGEPD_SIZE(psize) (1UL HUGEPD_SHIFT(psize)) -#define HUGEPD_MASK(psize) (~(HUGEPD_SIZE(psize)-1)) +static unsigned int mmu_huge_psizes[MMU_PAGE_COUNT] = { }; /* initialize all to 0 */ /* Flag to mark huge PD pointers. This means pmd_bad() and pud_bad() * will choke on pointers to hugepte tables, which is handy for * catching screwups early. */ -#define HUGEPD_OK 0x1 - -typedef struct { unsigned long pd; } hugepd_t; - -#define hugepd_none(hpd) ((hpd).pd == 0) static inline int shift_to_mmu_psize(unsigned int shift) { @@ -82,71 +68,126 @@ static inline unsigned int mmu_psize_to_ BUG(); } +#define hugepd_none(hpd) ((hpd).pd == 0) + static inline pte_t *hugepd_page(hugepd_t hpd) { - BUG_ON(!(hpd.pd HUGEPD_OK)); - return (pte_t *)(hpd.pd ~HUGEPD_OK); + BUG_ON(!hugepd_ok(hpd)); + return (pte_t *)((hpd.pd ~HUGEPD_SHIFT_MASK) | 0xc000); } -static inline pte_t *hugepte_offset(hugepd_t *hpdp, unsigned long addr, - struct hstate *hstate) +static inline unsigned int hugepd_shift(hugepd_t hpd) { - unsigned int shift = huge_page_shift(hstate); - int psize = shift_to_mmu_psize(shift); - unsigned long idx = ((addr shift) (PTRS_PER_HUGEPTE(psize)-1)); + return hpd.pd HUGEPD_SHIFT_MASK; +} + +static inline pte_t *hugepte_offset(hugepd_t *hpdp, unsigned long addr, unsigned pdshift) +{ + unsigned long idx = (addr ((1UL pdshift) - 1)) hugepd_shift(*hpdp); pte_t *dir =
[5/5] Split hash MMU specific hugepage code into a new file
This patch separates the parts of hugetlbpage.c which are inherently specific to the hash MMU into a new hugelbpage-hash64.c file. Signed-off-by: David Gibson d...@au1.ibm.com --- arch/powerpc/include/asm/hugetlb.h |3 arch/powerpc/mm/Makefile |5 - arch/powerpc/mm/hugetlbpage-hash64.c | 167 ++ arch/powerpc/mm/hugetlbpage.c| 168 --- 4 files changed, 176 insertions(+), 167 deletions(-) Index: working-2.6/arch/powerpc/mm/Makefile === --- working-2.6.orig/arch/powerpc/mm/Makefile 2009-08-14 16:07:54.0 +1000 +++ working-2.6/arch/powerpc/mm/Makefile2009-09-09 15:24:33.0 +1000 @@ -28,7 +28,10 @@ obj-$(CONFIG_44x)+= 44x_mmu.o obj-$(CONFIG_FSL_BOOKE)+= fsl_booke_mmu.o obj-$(CONFIG_NEED_MULTIPLE_NODES) += numa.o obj-$(CONFIG_PPC_MM_SLICES)+= slice.o -obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o +ifeq ($(CONFIG_HUGETLB_PAGE),y) +obj-y += hugetlbpage.o +obj-$(CONFIG_PPC_STD_MMU_64) += hugetlbpage-hash64.o +endif obj-$(CONFIG_PPC_SUBPAGE_PROT) += subpage-prot.o obj-$(CONFIG_NOT_COHERENT_CACHE) += dma-noncoherent.o obj-$(CONFIG_HIGHMEM) += highmem.o Index: working-2.6/arch/powerpc/mm/hugetlbpage-hash64.c === --- /dev/null 1970-01-01 00:00:00.0 + +++ working-2.6/arch/powerpc/mm/hugetlbpage-hash64.c2009-09-09 15:25:35.0 +1000 @@ -0,0 +1,167 @@ +/* + * PPC64 Huge TLB Page Support for hash based MMUs (POWER4 and later) + * + * Copyright (C) 2003 David Gibson, IBM Corporation. + * + * Based on the IA-32 version: + * Copyright (C) 2002, Rohit Seth rohit.s...@intel.com + */ + +#include linux/mm.h +#include linux/hugetlb.h +#include asm/pgtable.h +#include asm/pgalloc.h +#include asm/cacheflush.h +#include asm/machdep.h + +/* + * Called by asm hashtable.S for doing lazy icache flush + */ +static unsigned int hash_huge_page_do_lazy_icache(unsigned long rflags, + pte_t pte, int trap, unsigned long sz) +{ + struct page *page; + int i; + + if (!pfn_valid(pte_pfn(pte))) + return rflags; + + page = pte_page(pte); + + /* page is dirty */ + if (!test_bit(PG_arch_1, page-flags) !PageReserved(page)) { + if (trap == 0x400) { + for (i = 0; i (sz / PAGE_SIZE); i++) + __flush_dcache_icache(page_address(page+i)); + set_bit(PG_arch_1, page-flags); + } else { + rflags |= HPTE_R_N; + } + } + return rflags; +} + +int __hash_page_huge(unsigned long ea, unsigned long access, unsigned long vsid, +pte_t *ptep, unsigned long trap, int local, int ssize, +unsigned int shift, unsigned int mmu_psize) +{ + unsigned long old_pte, new_pte; + unsigned long va, rflags, pa, sz; + long slot; + int err = 1; + + BUG_ON(shift != mmu_psize_defs[mmu_psize].shift); + + /* Search the Linux page table for a match with va */ + va = hpt_va(ea, vsid, ssize); + + /* +* Check the user's access rights to the page. If access should be +* prevented then send the problem up to do_page_fault. +*/ + if (unlikely(access ~pte_val(*ptep))) + goto out; + /* +* At this point, we have a pte (old_pte) which can be used to build +* or update an HPTE. There are 2 cases: +* +* 1. There is a valid (present) pte with no associated HPTE (this is +* the most common case) +* 2. There is a valid (present) pte with an associated HPTE. The +* current values of the pp bits in the HPTE prevent access +* because we are doing software DIRTY bit management and the +* page is currently not DIRTY. +*/ + + + do { + old_pte = pte_val(*ptep); + if (old_pte _PAGE_BUSY) + goto out; + new_pte = old_pte | _PAGE_BUSY | _PAGE_ACCESSED; + } while(old_pte != __cmpxchg_u64((unsigned long *)ptep, +old_pte, new_pte)); + + rflags = 0x2 | (!(new_pte _PAGE_RW)); + /* _PAGE_EXEC - HW_NO_EXEC since it's inverted */ + rflags |= ((new_pte _PAGE_EXEC) ? 0 : HPTE_R_N); + sz = ((1UL) shift); + if (!cpu_has_feature(CPU_FTR_COHERENT_ICACHE)) + /* No CPU has hugepages but lacks no execute, so we +* don't need to worry about that case */ + rflags = hash_huge_page_do_lazy_icache(rflags, __pte(old_pte), + trap, sz); + + /* Check if pte already has an hpte
Re: [FTRACE] Enabling function_graph causes OOPS
Steven Rostedt wrote: I'm going through old email, and I found this. Do you still see this error. I don't recall seeing it myself. I can still recreate this with 31-rc9. When i enable tracing with function_graph i notice the following oops. This happens only once. Later if i try to enable/disable tracing i don't get this oops message. This behavior is observed only with function_graph. Other tracers work fine. Oops: Kernel access of bad area, sig: 11 [#1] SMP NR_CPUS=1024 NUMA pSeries Modules linked in: ipv6 fuse loop dm_mod sr_mod ehea ibmveth sg cdrom sd_mod crc_t10dif ibmvscsic scsi_transport_srp scsi_tgt scsi_mod NIP: c0008f30 LR: c0008f04 CTR: 800f6d68 REGS: c0003e98f560 TRAP: 0300 Not tainted (2.6.31-rc9) MSR: 80009032 EE,ME,IR,DR CR: 24000422 XER: 0020 DAR: 0008, DSISR: 4000 TASK = c0003e953b20[2483] 'irqbalance' THREAD: c0003e98c000 CPU: 1 GPR00: c0008f04 c0003e98f7e0 d117ed38 GPR04: 6600 10bf GPR08: 80010021bb40 00ff 80010021bb60 GPR12: 0002 c1032800 effdff68 GPR16: 0fffa39fd6a0 0fffa39e6c38 c0003ebe9c38 f000 GPR20: c0002a6cf980 c0003e98fdf8 c0003e98fba8 0fffa174 GPR24: f000 80010300 ffe0 0009 GPR28: c0003db4 0002 d117da78 c0003e98f850 NIP [c0008f30] .mod_return_to_handler+0x2c/0x64 LR [c0008f04] .mod_return_to_handler+0x0/0x64 Call Trace: [c0003e98f7e0] [c0002a6cf980] 0xc0002a6cf980 (unreliable) [c0003e98f850] [c0008f04] .mod_return_to_handler+0x0/0x64 [c0003e98f900] [c0008f04] .mod_return_to_handler+0x0/0x64 [c0003e98f9a0] [c0008f04] .mod_return_to_handler+0x0/0x64 [c0003e98fa30] [c0008ed0] .return_to_handler+0x0/0x34 (.bad_page_fault+0xc8/0xe8) [c0003e98fb30] [c0008ed0] .return_to_handler+0x0/0x34 (handle_page_fault+0x3c/0x5c) [c0003e98fc20] [c0008ed0] .return_to_handler+0x0/0x34 (.ehea_h_query_ehea_port+0x74/0x9c [ehea]) [c0003e98fcd0] [c0008ed0] .return_to_handler+0x0/0x34 (.ehea_get_stats+0xa0/0x1d0 [ehea]) [c0003e98fd80] [c0008ed0] .return_to_handler+0x0/0x34 (.dev_get_stats+0x50/0xec) [c0003e98fe30] [c0008ed0] .return_to_handler+0x0/0x34 (.dev_seq_show+0x5c/0x140) Instruction dump: 4e800020 f881ffe0 f861ffe8 f841fff0 fbe1fff8 7c3f0b78 f821ff91 3c80 6084 788407c6 6484 6084 e8440008 48126375 6000 7c6803a6 ---[ end trace bb43efc994aed790 ]--- function_graph traces are recorded and can be retrieved using /sys/kernel/debug/tracing/trace. 1) 3.936 us|} 1) |.release_console_sem() { 1) 0.594 us| ._spin_lock_irqsave(); 1) 0.560 us| ._call_console_drivers(); 1) 0.580 us| ._call_console_drivers(); 1) 0.582 us| ._spin_lock_irqsave(); 1) | .up() { 1) 0.592 us|._spin_lock_irqsave(); 1) 0.556 us|._spin_unlock_irqrestore(); 1) 2.842 us| } 1) 0.588 us| ._spin_unlock_irqrestore(); 1) 9.750 us|} 1) + 75.274 us | } 1) | .die() { 1) |.oops_enter() { Thanks -Sachin -- - Sachin Sant IBM Linux Technology Center India Systems and Technology Labs Bangalore, India - ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: Question about e300 core decrementer interrupt
On Tue, 2009-09-08 at 13:48 +0800, Li Tao-B22598 wrote: Dear all, I have a problem in MPC5121 sleep mode. As you know MPC5121 use e300c4 core. When I make the e300c4 core into sleep mode, it will return to full power mode when the“decrementer interrupt” occurred. But in the e300 core reference manual said that the “decrementer interrupt”have no effect when e300 core in sleep mode, because the time base and decrementer are disabled while the core is in sleep mode. Can anybody explain about this procedure ? Please talk to people internal to freescale. There is errata on this that is known for a long time(more than a year now) that for some reason is never entered into the errata document. I'm a bit irritated that it's not as the solution can mean hardware changes an thus it's potentially expensive. ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH] powerpc: Fix bug where perf_counters breaks oprofile
Currently there is a bug where if you use oprofile on a pSeries machine, then use perf_counters, then use oprofile again, oprofile will not work correctly; it will lose the PMU configuration the next time the hypervisor does a partition context switch, and thereafter won't count anything. Maynard Johnson identified the sequence causing the problem: - oprofile setup calls ppc_enable_pmcs(), which calls pseries_lpar_enable_pmcs, which tells the hypervisor that we want to use the PMU, and sets the PMU in use flag in the lppaca. This flag tells the hypervisor whether it needs to save and restore the PMU config. - The perf_counter code sets and clears the PMU in use flag directly as it context-switches the PMU between tasks, and leaves it clear when it finishes. - oprofile setup, called for a new oprofile run, calls ppc_enable_pmcs, which does nothing because it has already been called. In particular it doesn't set the PMU in use flag. This fixes the problem by arranging for ppc_enable_pmcs to always set the PMU in use flag. It makes the perf_counter code call ppc_enable_pmcs also rather than calling the lower-level function directly, and removes the setting of the PMU in use flag from pseries_lpar_enable_pmcs, since that is now done in its caller. This also removes the declaration of pasemi_enable_pmcs because it isn't defined anywhere. Reported-by: Maynard Johnson mpj...@us.ibm.com Signed-off-by: Paul Mackerras pau...@samba.org --- arch/powerpc/include/asm/pmc.h | 16 ++-- arch/powerpc/kernel/perf_counter.c | 13 +++-- arch/powerpc/kernel/sysfs.c|3 +++ arch/powerpc/platforms/pseries/setup.c |4 4 files changed, 20 insertions(+), 16 deletions(-) diff --git a/arch/powerpc/include/asm/pmc.h b/arch/powerpc/include/asm/pmc.h index d6a616a..ccc68b5 100644 --- a/arch/powerpc/include/asm/pmc.h +++ b/arch/powerpc/include/asm/pmc.h @@ -27,10 +27,22 @@ extern perf_irq_t perf_irq; int reserve_pmc_hardware(perf_irq_t new_perf_irq); void release_pmc_hardware(void); +void ppc_enable_pmcs(void); #ifdef CONFIG_PPC64 -void power4_enable_pmcs(void); -void pasemi_enable_pmcs(void); +#include asm/lppaca.h + +static inline void ppc_set_pmu_inuse(int inuse) +{ + get_lppaca()-pmcregs_in_use = inuse; +} + +extern void power4_enable_pmcs(void); + +#else /* CONFIG_PPC64 */ + +static inline void ppc_set_pmu_inuse(int inuse) { } + #endif #endif /* __KERNEL__ */ diff --git a/arch/powerpc/kernel/perf_counter.c b/arch/powerpc/kernel/perf_counter.c index 70e1f57..ccd6b21 100644 --- a/arch/powerpc/kernel/perf_counter.c +++ b/arch/powerpc/kernel/perf_counter.c @@ -62,7 +62,6 @@ static inline unsigned long perf_ip_adjust(struct pt_regs *regs) { return 0; } -static inline void perf_set_pmu_inuse(int inuse) { } static inline void perf_get_data_addr(struct pt_regs *regs, u64 *addrp) { } static inline u32 perf_get_misc_flags(struct pt_regs *regs) { @@ -93,11 +92,6 @@ static inline unsigned long perf_ip_adjust(struct pt_regs *regs) return 0; } -static inline void perf_set_pmu_inuse(int inuse) -{ - get_lppaca()-pmcregs_in_use = inuse; -} - /* * The user wants a data address recorded. * If we're not doing instruction sampling, give them the SDAR @@ -531,8 +525,7 @@ void hw_perf_disable(void) * Check if we ever enabled the PMU on this cpu. */ if (!cpuhw-pmcs_enabled) { - if (ppc_md.enable_pmcs) - ppc_md.enable_pmcs(); + ppc_enable_pmcs(); cpuhw-pmcs_enabled = 1; } @@ -594,7 +587,7 @@ void hw_perf_enable(void) mtspr(SPRN_MMCRA, cpuhw-mmcr[2] ~MMCRA_SAMPLE_ENABLE); mtspr(SPRN_MMCR1, cpuhw-mmcr[1]); if (cpuhw-n_counters == 0) - perf_set_pmu_inuse(0); + ppc_set_pmu_inuse(0); goto out_enable; } @@ -627,7 +620,7 @@ void hw_perf_enable(void) * bit set and set the hardware counters to their initial values. * Then unfreeze the counters. */ - perf_set_pmu_inuse(1); + ppc_set_pmu_inuse(1); mtspr(SPRN_MMCRA, cpuhw-mmcr[2] ~MMCRA_SAMPLE_ENABLE); mtspr(SPRN_MMCR1, cpuhw-mmcr[1]); mtspr(SPRN_MMCR0, (cpuhw-mmcr[0] ~(MMCR0_PMC1CE | MMCR0_PMCjCE)) diff --git a/arch/powerpc/kernel/sysfs.c b/arch/powerpc/kernel/sysfs.c index f41aec8..956ab33 100644 --- a/arch/powerpc/kernel/sysfs.c +++ b/arch/powerpc/kernel/sysfs.c @@ -17,6 +17,7 @@ #include asm/prom.h #include asm/machdep.h #include asm/smp.h +#include asm/pmc.h #include cacheinfo.h @@ -123,6 +124,8 @@ static DEFINE_PER_CPU(char, pmcs_enabled); void ppc_enable_pmcs(void) { + ppc_set_pmu_inuse(1); + /* Only need to enable them once */ if (__get_cpu_var(pmcs_enabled)) return; diff --git
RE: Queries regarding I2C and GPIO driver for Freescale MPC5121e in Linux2.6.24 of BSP: MPC512xADS_20090603-ltib.iso
Hi Chen Hongjun-R66092, Thanks for your response. Actually for the GPIO driver I am having some success and it is in progress. But regarding the I2C chip(client) driver I am running witout any progress. Actually I followed the existing driver $(LINUX)\drivers\rtc\rtc-m41t80.c (for the RTC M41T62 existing on the ADS5121Rev4.1 board). I made a legacy style driver with attach_adapter and detach_client functions defined. For testing purpose I geve the chip address as 0x68(address of M41T62 existing on the board). But when I tried ot insert my driver I get the error message as: [r...@freescale chips]# insmod dis_fpc.ko [ 177.808848] i2c 0-0068: uevent [ 498.528032] In dis_fpc_init [ 498.531851] i2c-core: driver [dis_fpc] registered [ 498.532446] In dis_fpc_attach_adapter [ 498.536827] i2c-adapter i2c-0: found normal entry for adapter 0, addr 0x55 [ 498.537730] i2c-adapter i2c-0: master_xfer[0] W, addr=0x55, len=0 [ 498.538533] Doing write 0 bytes to 0x55 - 1 of 1 messages [ 498.539770] I2C: No RXAK [ 498.540970] In dis_fpc_attach_adapter [ 498.554500] i2c-adapter i2c-1: found normal entry for adapter 1, addr 0x55 [ 498.555166] i2c-adapter i2c-1: master_xfer[0] W, addr=0x55, len=0 [ 498.555872] Doing write 0 bytes to 0x55 - 1 of 1 messages [ 498.556785] I2C: MAL [ 498.557476] In dis_fpc_attach_adapter [ 498.565733] i2c-adapter i2c-2: found normal entry for adapter 2, addr 0x55 [ 498.566377] i2c-adapter i2c-2: master_xfer[0] W, addr=0x55, len=0 [ 498.567082] Doing write 0 bytes to 0x55 - 1 of 1 messages [ 498.568240] I2C: No RXAK So can you tell me what other places do I need to change the configurations( like i2c_platform_data definition, linking the chip to the specific I2C module(0/1/2) with the adapter, configuring the speed of I2C communication etc). I would like to get any suggestion on making the I2C chip driver inpowerpc platform. Thanks Regards, Uma From: Chen Hongjun-R66092 [mailto:hong-jun.c...@freescale.com] Sent: Wednesday, September 09, 2009 5:39 AM To: Uma Kanta Patro; linuxppc-dev@lists.ozlabs.org Subject: RE: Queries regarding I2C and GPIO driver for Freescale MPC5121e in Linux2.6.24 of BSP: MPC512xADS_20090603-ltib.iso One I2C driver has been included in 0603 bsp, you can refer to it. It has no specific driver for GPIO, but you can find some initializing code for GPIO in arch/powerpc/platforms/512x/mpc5125_ads.c. and mpc512x_pm_test.c. _ From: linuxppc-dev-bounces+hong-jun.chen=freescale@lists.ozlabs.org [mailto:linuxppc-dev-bounces+hong-jun.chen=freescale@lists.ozlabs.org] On Behalf Of Uma Kanta Patro Sent: Tuesday, September 08, 2009 6:56 PM To: linuxppc-dev@lists.ozlabs.org Subject: Queries regarding I2C and GPIO driver for Freescale MPC5121e in Linux2.6.24 of BSP: MPC512xADS_20090603-ltib.iso Hi all, I am a newbie to the powerpc linux kernel, but I have worked on some drivers in arm architecture. I am finding powerpc architecture to be fully different than that. I am working on Freescale MPC5121e with the BSP MPC512xADS_20090603-ltib.iso running in it on the ADS512101 Rev4.1 development kit. Can anyone help me in finding some documentation for understanding and working on the powerpc kernel. Any links to the powerpc forums will also be appreciable. - Currently I am going to develop an I2C client driver for one slave microcontroller of our project. I have some knowledge in the I2C client driver making(legacy style and new style). I made a basic I2C client driver to probe for the chip address and for testing I gave it the chip address 0x68(I2C chip address of the M4T162 RTC, present on the board). But while inserting my driver I am getting failure message for the detection of my chip. So I would like to know what other formalities am I lagging in my I2C chip driver. - Also I am in a need for the GPIO driver for my controller ot get interrupt on ht estate change. When I searched in the kernel code I could not find any procedure to do that, also I could not find out the procedure to access either any GPIO pin macros or any register to remap with ioremap(). So please guide me in finding the proper way to do the GPIO accessing and interrupt registration. Will the ioremap() work on powerpc arch? If yes where can I find the memory mapping(register definitions) to use for my GPIO driver making. Thanks for patience in reading my queries. Any help is appreciable. Thanks Regards, Uma ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
pq2 pro: kgdb access to MURAM?
Just wondering how I can get kgdb to show me the contents of MURAM on the QE? -- Michael Barkowski 905-482-4577 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH] powerpc: Fix bug where perf_counters breaks oprofile
Paul Mackerras wrote: Currently there is a bug where if you use oprofile on a pSeries machine, then use perf_counters, then use oprofile again, oprofile will not work correctly; it will lose the PMU configuration the next time the hypervisor does a partition context switch, and thereafter won't count anything. Maynard Johnson identified the sequence causing the problem: - oprofile setup calls ppc_enable_pmcs(), which calls pseries_lpar_enable_pmcs, which tells the hypervisor that we want to use the PMU, and sets the PMU in use flag in the lppaca. This flag tells the hypervisor whether it needs to save and restore the PMU config. - The perf_counter code sets and clears the PMU in use flag directly as it context-switches the PMU between tasks, and leaves it clear when it finishes. - oprofile setup, called for a new oprofile run, calls ppc_enable_pmcs, which does nothing because it has already been called. In particular it doesn't set the PMU in use flag. This fixes the problem by arranging for ppc_enable_pmcs to always set the PMU in use flag. It makes the perf_counter code call ppc_enable_pmcs also rather than calling the lower-level function directly, and removes the setting of the PMU in use flag from pseries_lpar_enable_pmcs, since that is now done in its caller. This also removes the declaration of pasemi_enable_pmcs because it isn't defined anywhere. Thanks, Paul. I tested the patch, and oprofile and perf now play nicely together. -Maynard Reported-by: Maynard Johnson mpj...@us.ibm.com Signed-off-by: Paul Mackerras pau...@samba.org --- arch/powerpc/include/asm/pmc.h | 16 ++-- arch/powerpc/kernel/perf_counter.c | 13 +++-- arch/powerpc/kernel/sysfs.c|3 +++ arch/powerpc/platforms/pseries/setup.c |4 4 files changed, 20 insertions(+), 16 deletions(-) diff --git a/arch/powerpc/include/asm/pmc.h b/arch/powerpc/include/asm/pmc.h index d6a616a..ccc68b5 100644 --- a/arch/powerpc/include/asm/pmc.h +++ b/arch/powerpc/include/asm/pmc.h @@ -27,10 +27,22 @@ extern perf_irq_t perf_irq; int reserve_pmc_hardware(perf_irq_t new_perf_irq); void release_pmc_hardware(void); +void ppc_enable_pmcs(void); #ifdef CONFIG_PPC64 -void power4_enable_pmcs(void); -void pasemi_enable_pmcs(void); +#include asm/lppaca.h + +static inline void ppc_set_pmu_inuse(int inuse) +{ + get_lppaca()-pmcregs_in_use = inuse; +} + +extern void power4_enable_pmcs(void); + +#else /* CONFIG_PPC64 */ + +static inline void ppc_set_pmu_inuse(int inuse) { } + #endif #endif /* __KERNEL__ */ diff --git a/arch/powerpc/kernel/perf_counter.c b/arch/powerpc/kernel/perf_counter.c index 70e1f57..ccd6b21 100644 --- a/arch/powerpc/kernel/perf_counter.c +++ b/arch/powerpc/kernel/perf_counter.c @@ -62,7 +62,6 @@ static inline unsigned long perf_ip_adjust(struct pt_regs *regs) { return 0; } -static inline void perf_set_pmu_inuse(int inuse) { } static inline void perf_get_data_addr(struct pt_regs *regs, u64 *addrp) { } static inline u32 perf_get_misc_flags(struct pt_regs *regs) { @@ -93,11 +92,6 @@ static inline unsigned long perf_ip_adjust(struct pt_regs *regs) return 0; } -static inline void perf_set_pmu_inuse(int inuse) -{ - get_lppaca()-pmcregs_in_use = inuse; -} - /* * The user wants a data address recorded. * If we're not doing instruction sampling, give them the SDAR @@ -531,8 +525,7 @@ void hw_perf_disable(void) * Check if we ever enabled the PMU on this cpu. */ if (!cpuhw-pmcs_enabled) { - if (ppc_md.enable_pmcs) - ppc_md.enable_pmcs(); + ppc_enable_pmcs(); cpuhw-pmcs_enabled = 1; } @@ -594,7 +587,7 @@ void hw_perf_enable(void) mtspr(SPRN_MMCRA, cpuhw-mmcr[2] ~MMCRA_SAMPLE_ENABLE); mtspr(SPRN_MMCR1, cpuhw-mmcr[1]); if (cpuhw-n_counters == 0) - perf_set_pmu_inuse(0); + ppc_set_pmu_inuse(0); goto out_enable; } @@ -627,7 +620,7 @@ void hw_perf_enable(void) * bit set and set the hardware counters to their initial values. * Then unfreeze the counters. */ - perf_set_pmu_inuse(1); + ppc_set_pmu_inuse(1); mtspr(SPRN_MMCRA, cpuhw-mmcr[2] ~MMCRA_SAMPLE_ENABLE); mtspr(SPRN_MMCR1, cpuhw-mmcr[1]); mtspr(SPRN_MMCR0, (cpuhw-mmcr[0] ~(MMCR0_PMC1CE | MMCR0_PMCjCE)) diff --git a/arch/powerpc/kernel/sysfs.c b/arch/powerpc/kernel/sysfs.c index f41aec8..956ab33 100644 --- a/arch/powerpc/kernel/sysfs.c +++ b/arch/powerpc/kernel/sysfs.c @@ -17,6 +17,7 @@ #include asm/prom.h #include asm/machdep.h #include asm/smp.h +#include asm/pmc.h #include cacheinfo.h @@ -123,6 +124,8 @@ static DEFINE_PER_CPU(char, pmcs_enabled);
Re: AW: PowerPC PCI DMA issues (prefetch/coherency?)
Hi, Why manage cache lines manually, if appropriate code is a part of __dma_sync / dma_sync_single_for_device of DMA API ? (implies CONFIG_NOT_COHERENT_CACHE enabled, as default for Sequoia Board) Prodyut Hazarika wrote: Hi Adam, Yes, I am using the 440EPx (same as the sequoia board). Our ideDriver is DMA'ing blocks of 192-byte data over the PCI bus (using the Sil0680A PCI-IDE bridge). Most of the DMA's (depending on timing) end up being partially corrupted when we try to parse the data in the virtual page. We have confirmed the data is good before the PCI-IDE bridge. We are creating two 8K pages and map them to physical DMA memory using single-entry scatter/gather structs. When a DMA block is corrupted, we see a random portion of it (always a multiple of 16byte cache lines) is overwritten with old data from the last time the buffer was used. This looks like a cache coherency problem. Can you ensure that the TLB entries corresponding to the DMA region has the CacheInhibit bit set. You will need a BDI connected to your system. Also, you will need to invalidate and flush the lines appropriately, since in 440 cores, L1Cache coherency is managed entirely by software. Please look at drivers/net/ibm_newemac/mal.c and core.c for example on how to do it. Thanks Prodyut On Thu, 2009-09-03 at 13:27 -0700, Prodyut Hazarika wrote: Hi Adam, Are you sure there is L2 cache on the 440? It depends on the SoC you are using. SoC like 460EX (Canyonlands board) have L2Cache. It seems you are using a Sequoia board, which has a 440EPx SoC. 440EPx has a 440 cpu core, but no L2Cache. Could you please tell me which SoC you are using? You can also refer to the appropriate dts file to see if there is L2C. For example, in canyonlands.dts (460EX based board), we have the L2C entry. L2C0: l2c { ... } I am seeing this problem with our custom IDE driver which is based on pretty old code. Our driver uses pci_alloc_consistent() to allocate the physical DMA memory and alloc_pages() to allocate a virtual page. It then uses pci_map_sg() to map to a scatter/gather buffer. Perhaps I should convert these to the DMA API calls as you suggest. Could you give more details on the consistency problem? It is a good idea to change to the new DMA APIs, but pci_alloc_consistent() should work too Thanks Prodyut On Thu, 2009-09-03 at 19:57 +1000, Benjamin Herrenschmidt wrote: On Thu, 2009-09-03 at 09:05 +0100, Chris Pringle wrote: Hi Adam, If you have a look in include/asm-ppc/pgtable.h for the following section: #ifdef CONFIG_44x #define _PAGE_BASE(_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_GUARDED) #else #define _PAGE_BASE(_PAGE_PRESENT | _PAGE_ACCESSED) #endif Try adding _PAGE_COHERENT to the appropriate line above and see if that fixes your issue - this causes the 'M' bit to be set on the page which sure enforce cache coherency. If it doesn't, you'll need to check the 'M' bit isn't being masked out in head_44x.S (it was originally masked out on arch/powerpc, but was fixed in later kernels when the cache coherency issues with non-SMP systems were resolved). I have some doubts about the usefulness of doing that for 4xx. AFAIK, the 440 core just ignores M. The problem lies probably elsewhere. Maybe the L2 cache coherency isn't enabled or not working ? The L1 cache on 440 is simply not coherent, so drivers have to make sure they use the appropriate DMA APIs which will do cache flushing when needed. Adam, what driver is causing you that sort of problems ? Cheers, Ben. ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Bug in of_mpc8xxx_spi chipselect
Just want to document this bug, since I don't have time to make a patch: In of_mpc8xxx_spi_get_chipselects(): pinfo-alow_flags[i] = flags OF_GPIO_ACTIVE_LOW; ret = gpio_direction_output(pinfo-gpios[i], pinfo-alow_flags[i]); The initial value of the chip should be disabled. If SPI_CS_HIGH, value of 0 means disabled - ok, but... If not SPI_CS_HIGH for a given device (which is the case for most devices), that device will be enabled until it is disabled at the end of the first transaction to that device. If there are transactions to other devices on the same bus in the meantime, this device may be confused and fail the first transaction. Maybe the chip select should be disabled until the device entry is initialized with full knowledge of its configuration. Not sure of the right solution. -- Michael Barkowski 905-482-4577 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: AW: PowerPC PCI DMA issues (prefetch/coherency?)
Hi Tom, possible solution could be to use tasklet to perform DMA-related job (as in most cases DMA transfer is interrupt driven - makes sense). Tom Burns wrote: Hi, With the default config for the Sequoia board on 2.6.24, calling pci_dma_sync_sg_for_cpu() results in executing invalidate_dcache_range() in arch/ppc/kernel/misc.S from __dma_sync(). This OOPses on PPC440 since it tries to call directly the assembly instruction dcbi, which can only be executed in supervisor mode. We tried that before resorting to manual cache line management with usermode-safe assembly calls. Regards, Tom Burns International Datacasting Corporation Mikhail Zolotaryov wrote: Hi, Why manage cache lines manually, if appropriate code is a part of __dma_sync / dma_sync_single_for_device of DMA API ? (implies CONFIG_NOT_COHERENT_CACHE enabled, as default for Sequoia Board) Prodyut Hazarika wrote: Hi Adam, Yes, I am using the 440EPx (same as the sequoia board). Our ideDriver is DMA'ing blocks of 192-byte data over the PCI bus (using the Sil0680A PCI-IDE bridge). Most of the DMA's (depending on timing) end up being partially corrupted when we try to parse the data in the virtual page. We have confirmed the data is good before the PCI-IDE bridge. We are creating two 8K pages and map them to physical DMA memory using single-entry scatter/gather structs. When a DMA block is corrupted, we see a random portion of it (always a multiple of 16byte cache lines) is overwritten with old data from the last time the buffer was used. This looks like a cache coherency problem. Can you ensure that the TLB entries corresponding to the DMA region has the CacheInhibit bit set. You will need a BDI connected to your system. Also, you will need to invalidate and flush the lines appropriately, since in 440 cores, L1Cache coherency is managed entirely by software. Please look at drivers/net/ibm_newemac/mal.c and core.c for example on how to do it. Thanks Prodyut On Thu, 2009-09-03 at 13:27 -0700, Prodyut Hazarika wrote: Hi Adam, Are you sure there is L2 cache on the 440? It depends on the SoC you are using. SoC like 460EX (Canyonlands board) have L2Cache. It seems you are using a Sequoia board, which has a 440EPx SoC. 440EPx has a 440 cpu core, but no L2Cache. Could you please tell me which SoC you are using? You can also refer to the appropriate dts file to see if there is L2C. For example, in canyonlands.dts (460EX based board), we have the L2C entry. L2C0: l2c { ... } I am seeing this problem with our custom IDE driver which is based on pretty old code. Our driver uses pci_alloc_consistent() to allocate the physical DMA memory and alloc_pages() to allocate a virtual page. It then uses pci_map_sg() to map to a scatter/gather buffer. Perhaps I should convert these to the DMA API calls as you suggest. Could you give more details on the consistency problem? It is a good idea to change to the new DMA APIs, but pci_alloc_consistent() should work too Thanks Prodyut On Thu, 2009-09-03 at 19:57 +1000, Benjamin Herrenschmidt wrote: On Thu, 2009-09-03 at 09:05 +0100, Chris Pringle wrote: Hi Adam, If you have a look in include/asm-ppc/pgtable.h for the following section: #ifdef CONFIG_44x #define _PAGE_BASE(_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_GUARDED) #else #define _PAGE_BASE(_PAGE_PRESENT | _PAGE_ACCESSED) #endif Try adding _PAGE_COHERENT to the appropriate line above and see if that fixes your issue - this causes the 'M' bit to be set on the page which sure enforce cache coherency. If it doesn't, you'll need to check the 'M' bit isn't being masked out in head_44x.S (it was originally masked out on arch/powerpc, but was fixed in later kernels when the cache coherency issues with non-SMP systems were resolved). I have some doubts about the usefulness of doing that for 4xx. AFAIK, the 440 core just ignores M. The problem lies probably elsewhere. Maybe the L2 cache coherency isn't enabled or not working ? The L1 cache on 440 is simply not coherent, so drivers have to make sure they use the appropriate DMA APIs which will do cache flushing when needed. Adam, what driver is causing you that sort of problems ? Cheers, Ben. ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: AW: PowerPC PCI DMA issues (prefetch/coherency?)
Hi, With the default config for the Sequoia board on 2.6.24, calling pci_dma_sync_sg_for_cpu() results in executing invalidate_dcache_range() in arch/ppc/kernel/misc.S from __dma_sync(). This OOPses on PPC440 since it tries to call directly the assembly instruction dcbi, which can only be executed in supervisor mode. We tried that before resorting to manual cache line management with usermode-safe assembly calls. Regards, Tom Burns International Datacasting Corporation Mikhail Zolotaryov wrote: Hi, Why manage cache lines manually, if appropriate code is a part of __dma_sync / dma_sync_single_for_device of DMA API ? (implies CONFIG_NOT_COHERENT_CACHE enabled, as default for Sequoia Board) Prodyut Hazarika wrote: Hi Adam, Yes, I am using the 440EPx (same as the sequoia board). Our ideDriver is DMA'ing blocks of 192-byte data over the PCI bus (using the Sil0680A PCI-IDE bridge). Most of the DMA's (depending on timing) end up being partially corrupted when we try to parse the data in the virtual page. We have confirmed the data is good before the PCI-IDE bridge. We are creating two 8K pages and map them to physical DMA memory using single-entry scatter/gather structs. When a DMA block is corrupted, we see a random portion of it (always a multiple of 16byte cache lines) is overwritten with old data from the last time the buffer was used. This looks like a cache coherency problem. Can you ensure that the TLB entries corresponding to the DMA region has the CacheInhibit bit set. You will need a BDI connected to your system. Also, you will need to invalidate and flush the lines appropriately, since in 440 cores, L1Cache coherency is managed entirely by software. Please look at drivers/net/ibm_newemac/mal.c and core.c for example on how to do it. Thanks Prodyut On Thu, 2009-09-03 at 13:27 -0700, Prodyut Hazarika wrote: Hi Adam, Are you sure there is L2 cache on the 440? It depends on the SoC you are using. SoC like 460EX (Canyonlands board) have L2Cache. It seems you are using a Sequoia board, which has a 440EPx SoC. 440EPx has a 440 cpu core, but no L2Cache. Could you please tell me which SoC you are using? You can also refer to the appropriate dts file to see if there is L2C. For example, in canyonlands.dts (460EX based board), we have the L2C entry. L2C0: l2c { ... } I am seeing this problem with our custom IDE driver which is based on pretty old code. Our driver uses pci_alloc_consistent() to allocate the physical DMA memory and alloc_pages() to allocate a virtual page. It then uses pci_map_sg() to map to a scatter/gather buffer. Perhaps I should convert these to the DMA API calls as you suggest. Could you give more details on the consistency problem? It is a good idea to change to the new DMA APIs, but pci_alloc_consistent() should work too Thanks Prodyut On Thu, 2009-09-03 at 19:57 +1000, Benjamin Herrenschmidt wrote: On Thu, 2009-09-03 at 09:05 +0100, Chris Pringle wrote: Hi Adam, If you have a look in include/asm-ppc/pgtable.h for the following section: #ifdef CONFIG_44x #define _PAGE_BASE(_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_GUARDED) #else #define _PAGE_BASE(_PAGE_PRESENT | _PAGE_ACCESSED) #endif Try adding _PAGE_COHERENT to the appropriate line above and see if that fixes your issue - this causes the 'M' bit to be set on the page which sure enforce cache coherency. If it doesn't, you'll need to check the 'M' bit isn't being masked out in head_44x.S (it was originally masked out on arch/powerpc, but was fixed in later kernels when the cache coherency issues with non-SMP systems were resolved). I have some doubts about the usefulness of doing that for 4xx. AFAIK, the 440 core just ignores M. The problem lies probably elsewhere. Maybe the L2 cache coherency isn't enabled or not working ? The L1 cache on 440 is simply not coherent, so drivers have to make sure they use the appropriate DMA APIs which will do cache flushing when needed. Adam, what driver is causing you that sort of problems ? Cheers, Ben. ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: AW: PowerPC PCI DMA issues (prefetch/coherency?)
Hi Mikhail, Sorry, this DMA code is in a tasklet. Are you suggesting the processor is in supervisor mode at that time? Calling pci_dma_sync_sg_for_cpu() from the tasklet context is what generates the OOPS. The entire oops is as follows, if it's relevant: Oops: kernel access of bad area, sig: 11 [#1] NIP: c0003ab0 LR: c0010c30 CTR: 0241 REGS: df117bd0 TRAP: 0300 Tainted: P (2.6.24.2) MSR: 00029000 EE,ME CR: 44224042 XER: 2000 DEAR: 3fd39000, ESR: 0080 TASK = de5db7d0[157] 'cat' THREAD: df116000 GPR00: e11e5854 df117c80 de5db7d0 3fd39000 0241 001f 0002 0079a169 GPR08: 0001 c031 c0010c84 24224042 101c0dac c031 10177000 GPR16: deb14200 df116000 e12062d0 e11f6104 de0f16c0 e11f c031 e11f59cc GPR24: e11f62d0 e11f e11f 0002 defee014 3fd39008 87d39009 NIP [c0003ab0] invalidate_dcache_range+0x1c/0x30 LR [c0010c30] __dma_sync+0x58/0xac Call Trace: [df117c80] [000a] 0xa (unreliable) [df117c90] [e11e5854] DoTasklet+0x67c/0xc90 [ideDriverDuo_cyph] [df117ce0] [c001ee24] tasklet_action+0x60/0xcc [df117cf0] [c001ef04] __do_softirq+0x74/0xe0 [df117d10] [c00067a8] do_softirq+0x54/0x58 [df117d20] [c001edb4] irq_exit+0x48/0x58 [df117d30] [c00069d0] do_IRQ+0x6c/0xc0 [df117d40] [c00020e0] ret_from_except+0x0/0x18 [df117e00] [c00501e0] unmap_vmas+0x2c4/0x560 [df117e90] [c0053ebc] exit_mmap+0x64/0xec [df117ec0] [c00171ac] mmput+0x50/0xd4 [df117ed0] [c001aef8] exit_mm+0x80/0xe0 [df117ef0] [c001c818] do_exit+0x134/0x6f8 [df117f30] [c001ce14] do_group_exit+0x38/0x74 [df117f40] [c0001a80] ret_from_syscall+0x0/0x3c Instruction dump: 7c0018ac 38630020 4200fff8 7c0004ac 4e800020 38a0001f 7c632878 7c832050 7c842a14 5484d97f 4d820020 7c8903a6 7c001bac 38630020 4200fff8 7c0004ac Kernel panic - not syncing: Aiee, killing interrupt handler! Rebooting in 180 seconds.. Cheers, Tom Mikhail Zolotaryov wrote: Hi Tom, possible solution could be to use tasklet to perform DMA-related job (as in most cases DMA transfer is interrupt driven - makes sense). Tom Burns wrote: Hi, With the default config for the Sequoia board on 2.6.24, calling pci_dma_sync_sg_for_cpu() results in executing invalidate_dcache_range() in arch/ppc/kernel/misc.S from __dma_sync(). This OOPses on PPC440 since it tries to call directly the assembly instruction dcbi, which can only be executed in supervisor mode. We tried that before resorting to manual cache line management with usermode-safe assembly calls. Regards, Tom Burns International Datacasting Corporation Mikhail Zolotaryov wrote: Hi, Why manage cache lines manually, if appropriate code is a part of __dma_sync / dma_sync_single_for_device of DMA API ? (implies CONFIG_NOT_COHERENT_CACHE enabled, as default for Sequoia Board) Prodyut Hazarika wrote: Hi Adam, Yes, I am using the 440EPx (same as the sequoia board). Our ideDriver is DMA'ing blocks of 192-byte data over the PCI bus (using the Sil0680A PCI-IDE bridge). Most of the DMA's (depending on timing) end up being partially corrupted when we try to parse the data in the virtual page. We have confirmed the data is good before the PCI-IDE bridge. We are creating two 8K pages and map them to physical DMA memory using single-entry scatter/gather structs. When a DMA block is corrupted, we see a random portion of it (always a multiple of 16byte cache lines) is overwritten with old data from the last time the buffer was used. This looks like a cache coherency problem. Can you ensure that the TLB entries corresponding to the DMA region has the CacheInhibit bit set. You will need a BDI connected to your system. Also, you will need to invalidate and flush the lines appropriately, since in 440 cores, L1Cache coherency is managed entirely by software. Please look at drivers/net/ibm_newemac/mal.c and core.c for example on how to do it. Thanks Prodyut On Thu, 2009-09-03 at 13:27 -0700, Prodyut Hazarika wrote: Hi Adam, Are you sure there is L2 cache on the 440? It depends on the SoC you are using. SoC like 460EX (Canyonlands board) have L2Cache. It seems you are using a Sequoia board, which has a 440EPx SoC. 440EPx has a 440 cpu core, but no L2Cache. Could you please tell me which SoC you are using? You can also refer to the appropriate dts file to see if there is L2C. For example, in canyonlands.dts (460EX based board), we have the L2C entry. L2C0: l2c { ... } I am seeing this problem with our custom IDE driver which is based on pretty old code. Our driver uses pci_alloc_consistent() to allocate the physical DMA memory and alloc_pages() to allocate a virtual page. It then uses pci_map_sg() to map to a scatter/gather buffer. Perhaps I should convert these to the DMA API calls as you suggest. Could you give more details on the consistency problem? It is a good idea to change to the new DMA APIs, but pci_alloc_consistent()
[PATCH] 82xx: kmalloc failure ignored in ep8248e_mdio_probe()
Prevent NULL dereference if kmalloc() fails. Also clean up if of_mdiobus_register() returns an error. Signed-off-by: Roel Kluin roel.kl...@gmail.com --- Found with sed: http://kernelnewbies.org/roelkluin Please review. diff --git a/arch/powerpc/platforms/82xx/ep8248e.c b/arch/powerpc/platforms/82xx/ep8248e.c index 51fcae4..f9aee18 100644 --- a/arch/powerpc/platforms/82xx/ep8248e.c +++ b/arch/powerpc/platforms/82xx/ep8248e.c @@ -132,12 +132,25 @@ static int __devinit ep8248e_mdio_probe(struct of_device *ofdev, return -ENOMEM; bus-irq = kmalloc(sizeof(int) * PHY_MAX_ADDR, GFP_KERNEL); + if (bus-irq == NULL) { + ret = -ENOMEM; + goto err_free_bus; + } bus-name = ep8248e-mdio-bitbang; bus-parent = ofdev-dev; snprintf(bus-id, MII_BUS_ID_SIZE, %x, res.start); - return of_mdiobus_register(bus, ofdev-node); + ret = of_mdiobus_register(bus, ofdev-node); + if (ret) + goto err_free_irq; + + return 0; +err_free_irq: + kfree(bus-irq); +err_free_bus: + free_mdio_bitbang(bus); + return ret; } static int ep8248e_mdio_remove(struct of_device *ofdev) ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH] powerpc: kmalloc failure ignored in vio_build_iommu_table()
Prevent NULL dereference if kmalloc() fails. Signed-off-by: Roel Kluin roel.kl...@gmail.com --- Found with sed: http://kernelnewbies.org/roelkluin diff --git a/arch/powerpc/kernel/vio.c b/arch/powerpc/kernel/vio.c index 819e59f..1f5266f 100644 --- a/arch/powerpc/kernel/vio.c +++ b/arch/powerpc/kernel/vio.c @@ -1054,6 +1054,8 @@ static struct iommu_table *vio_build_iommu_table(struct vio_dev *dev) return NULL; tbl = kmalloc(sizeof(*tbl), GFP_KERNEL); + if (tbl == NULL) + return NULL; of_parse_dma_window(dev-dev.archdata.of_node, dma_window, tbl-it_index, offset, size); ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: some questions [gpio]
(Added devicetree and linuxppc-dev to cc: list) On Wed, Sep 9, 2009 at 5:50 AM, Vitaly Bordugv...@kernel.crashing.org wrote: Hi Grant, Remember I was asking some time ago about multiple gpio chips per device node to enable sint gpio on 52xx? I need an advice again: adding multiple chips is OK but it stores address of the of_gpio_chip or smth like that in device_node-data. And that is used in routine that grabs all data from gpios. Hereby to implement multiple chips, I'd need to store in device_node -data ponter to the array of gpio_chips, and to store actual amount of those chips somewhere, + study of_get_gpio_flags() to traverse several gpio_chips. That way, gpio_cells would be 3. Seems a little overkill... Hmmm. Refactoring the existing binding in non-backwards compatible ways is not okay. gpio_cells cannot be changed from 2 to 3 without breaking existing users. Maybe it would be better to split away gpio_sint stuff? I don't like it much since it kind of is one block of registers. However, a binding change must be made regardless because the current binding has no method of describing the sint pins (or the output-only pins for that matter). That leaves 2 options that I see: 1) Add a new node for the sint register range in the GPIO standard registers block. 2) add some kind of offset to the 1st cell in the gpio property. (ie. 0-0x20 for simple GPIOs, 0x200-0x207 for interrupt gpios, and 0x100-0x107 for output only gpios) I'll ignore which approach is easier to implement currently in Linux and try to focus on what the best binding would be. Option 2 looks pretty ugly and non-intuitive to me. The only advantage there is it keeps things described as a single block in the mpc5200 user manual all in one node. However, I think the clarity of option 1 wins out, especially considering that there isn't currently any code that tries to describe the sint pins in the device tree, so it has a smaller likelyhood of causing breakage. ... so it would seem that my opinion on this matter is now the exact opposite from the last time I talked to you now that I've actually looked at the binding. :-) g. -- Grant Likely, B.Sc., P.Eng. Secret Lab Technologies Ltd. ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH] * mpc8313erdb.dts: Fixed eTSEC interrupt assignment.
On Fri, Sep 04, 2009 at 12:31:25PM +0200, Roland Lezuo wrote: The following patch is needed to correctly assign the IRQs for the gianfar driver on the MPC8313ERDB-revc boards. ERR and TX are swapped as well as the interrupt lines for the two devices. And it will incorrectly assign them on older revisions of the chip. We really should have a u-boot fixup based on SVR. -Scott ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: MPC85xx External/Internal Interrupts
On Sun, Sep 06, 2009 at 01:06:41PM +0200, Sebastian Andrzej Siewior wrote: irq_of_parse_and_map() creates a mapping between the hardware irq number as specified in the device tree and the linux number (virq) which is used within the linux api in request_irq() for instance. irq_of_parse_and_map() is essential to create a mapping between those two. The interrupt controller on the MPC8555 (mpic) specifies the first few interrupt numbers as external sources followed by internal sources. Now, during the init sequenze of the mpic every interrupt source (internal and external) becomes its uniqe vector number which identifies the source by a number. This number is the hardware interrupt number i.e. that thing in the device tree. The init sequence is a for loop which starts at 0 for the first interrupt source which happens to be external interrupt 0, 1 for external interrupt 1 and so on. At the time it reaches the first internal interrupt source the vector number is 16. That's why you always have an offset of 16 between every internal interupt source number in the MPC855ERM document and those weired numbers in the device tree :) This seems to be a common point of confusion -- we should probably put something in the dts bindings that explains it. Am I correct in assuming that this particular internal/external split is Freescale-specific and not a general OpenPIC thing? -Scott ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: Question about e300 core decrementer interrupt
On Wed, Sep 09, 2009 at 01:16:07PM +0200, Kenneth Johansson wrote: On Tue, 2009-09-08 at 13:48 +0800, Li Tao-B22598 wrote: Dear all, I have a problem in MPC5121 sleep mode. As you know MPC5121 use e300c4 core. When I make the e300c4 core into sleep mode, it will return to full power mode when the“decrementer interrupt” occurred. But in the e300 core reference manual said that the “decrementer interrupt”have no effect when e300 core in sleep mode, because the time base and decrementer are disabled while the core is in sleep mode. Can anybody explain about this procedure ? I'm not specifically familiar with MPC5121, but I'll answer from the perspective of MPC83xx which has a similar core: The decrementer stops ticking when the core goes to sleep. However, if a decrementer was already pending (but masked with MSR[EE]) before you enter sleep mode, it will cause a wakeup. To avoid this, the decrementer is set to a very large value prior to and after disabling interrupts. See generic_suspend_disable_irqs() in arch/powerpc/kernel/time.c. Is this not happening for you? Which kernel version are you using, and what mechanism are you using to go to sleep? I'm a bit irritated that it's not as the solution can mean hardware changes an thus it's potentially expensive. What sort of hardware changes? -Scott ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH] 82xx: kmalloc failure ignored in ep8248e_mdio_probe()
On Wed, Sep 09, 2009 at 04:49:57PM +0200, Roel Kluin wrote: Prevent NULL dereference if kmalloc() fails. Also clean up if of_mdiobus_register() returns an error. Signed-off-by: Roel Kluin roel.kl...@gmail.com Acked-by: Scott Wood scottw...@freescale.com -Scott ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [FTRACE] Enabling function_graph causes OOPS
On Wed, 2009-09-09 at 11:57 +0530, Sachin Sant wrote: Steven Rostedt wrote: I'm going through old email, and I found this. Do you still see this error. I don't recall seeing it myself. I can still recreate this with 31-rc9. When i enable tracing with function_graph i notice the following oops. This happens only once. Later if i try to enable/disable tracing i don't get this oops message. This behavior is observed only with function_graph. Other tracers work fine. Oops: Kernel access of bad area, sig: 11 [#1] SMP NR_CPUS=1024 NUMA pSeries Modules linked in: ipv6 fuse loop dm_mod sr_mod ehea ibmveth sg cdrom sd_mod crc_t10dif ibmvscsic scsi_transport_srp scsi_tgt scsi_mod NIP: c0008f30 LR: c0008f04 CTR: 800f6d68 REGS: c0003e98f560 TRAP: 0300 Not tainted (2.6.31-rc9) MSR: 80009032 EE,ME,IR,DR CR: 24000422 XER: 0020 DAR: 0008, DSISR: 4000 TASK = c0003e953b20[2483] 'irqbalance' THREAD: c0003e98c000 CPU: 1 GPR00: c0008f04 c0003e98f7e0 d117ed38 GPR04: 6600 10bf GPR08: 80010021bb40 00ff 80010021bb60 GPR12: 0002 c1032800 effdff68 GPR16: 0fffa39fd6a0 0fffa39e6c38 c0003ebe9c38 f000 GPR20: c0002a6cf980 c0003e98fdf8 c0003e98fba8 0fffa174 GPR24: f000 80010300 ffe0 0009 GPR28: c0003db4 0002 d117da78 c0003e98f850 NIP [c0008f30] .mod_return_to_handler+0x2c/0x64 LR [c0008f04] .mod_return_to_handler+0x0/0x64 Call Trace: [c0003e98f7e0] [c0002a6cf980] 0xc0002a6cf980 (unreliable) [c0003e98f850] [c0008f04] .mod_return_to_handler+0x0/0x64 [c0003e98f900] [c0008f04] .mod_return_to_handler+0x0/0x64 [c0003e98f9a0] [c0008f04] .mod_return_to_handler+0x0/0x64 Ah, seems the bug happens to be in the module handling. Does the call back always have .mod_return_to_handler? This doesn't surprise me any. The module code is a bit harry, and function graph does some crazy crap with it. -- Steve [c0003e98fa30] [c0008ed0] .return_to_handler+0x0/0x34 (.bad_page_fault+0xc8/0xe8) [c0003e98fb30] [c0008ed0] .return_to_handler+0x0/0x34 (handle_page_fault+0x3c/0x5c) [c0003e98fc20] [c0008ed0] .return_to_handler+0x0/0x34 (.ehea_h_query_ehea_port+0x74/0x9c [ehea]) [c0003e98fcd0] [c0008ed0] .return_to_handler+0x0/0x34 (.ehea_get_stats+0xa0/0x1d0 [ehea]) [c0003e98fd80] [c0008ed0] .return_to_handler+0x0/0x34 (.dev_get_stats+0x50/0xec) [c0003e98fe30] [c0008ed0] .return_to_handler+0x0/0x34 (.dev_seq_show+0x5c/0x140) Instruction dump: 4e800020 f881ffe0 f861ffe8 f841fff0 fbe1fff8 7c3f0b78 f821ff91 3c80 6084 788407c6 6484 6084 e8440008 48126375 6000 7c6803a6 ---[ end trace bb43efc994aed790 ]--- function_graph traces are recorded and can be retrieved using /sys/kernel/debug/tracing/trace. 1) 3.936 us|} 1) |.release_console_sem() { 1) 0.594 us| ._spin_lock_irqsave(); 1) 0.560 us| ._call_console_drivers(); 1) 0.580 us| ._call_console_drivers(); 1) 0.582 us| ._spin_lock_irqsave(); 1) | .up() { 1) 0.592 us|._spin_lock_irqsave(); 1) 0.556 us|._spin_unlock_irqrestore(); 1) 2.842 us| } 1) 0.588 us| ._spin_unlock_irqrestore(); 1) 9.750 us|} 1) + 75.274 us | } 1) | .die() { 1) |.oops_enter() { Thanks -Sachin ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH] * mpc8313erdb.dts: Fixed eTSEC interrupt assignment.
On Sep 9, 2009, at 1:22 PM, Scott Wood wrote: On Fri, Sep 04, 2009 at 12:31:25PM +0200, Roland Lezuo wrote: The following patch is needed to correctly assign the IRQs for the gianfar driver on the MPC8313ERDB-revc boards. ERR and TX are swapped as well as the interrupt lines for the two devices. And it will incorrectly assign them on older revisions of the chip. We really should have a u-boot fixup based on SVR. I felt like Kim did this. - k ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH] * mpc8313erdb.dts: Fixed eTSEC interrupt assignment.
On Wed, 9 Sep 2009 15:28:01 -0500 Kumar Gala ga...@kernel.crashing.org wrote: On Sep 9, 2009, at 1:22 PM, Scott Wood wrote: On Fri, Sep 04, 2009 at 12:31:25PM +0200, Roland Lezuo wrote: The following patch is needed to correctly assign the IRQs for the gianfar driver on the MPC8313ERDB-revc boards. ERR and TX are swapped as well as the interrupt lines for the two devices. And it will incorrectly assign them on older revisions of the chip. We really should have a u-boot fixup based on SVR. definitely. I felt like Kim did this. I never got my hands on a Rev. C board. What's the SVR on it? I think this is also valid for Rev. B boards, and I don't have one of those either. Kim ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH] * mpc8313erdb.dts: Fixed eTSEC interrupt assignment.
Quoting Scott Wood scottw...@freescale.com: On Fri, Sep 04, 2009 at 12:31:25PM +0200, Roland Lezuo wrote: The following patch is needed to correctly assign the IRQs for the gianfar driver on the MPC8313ERDB-revc boards. ERR and TX are swapped as well as the interrupt lines for the two devices. And it will incorrectly assign them on older revisions of the chip. We really should have a u-boot fixup based on SVR. -Scott ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev I have both versions of the boards and I use two versions of the .dts file. Actually, four, two to support the old style uboot .dts that comes with Freescale's BSP and 2 that support the newer uboot. ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Removing deprecated drivers from drivers/i2c/chips
Hi, continuing the quest to clean up and ultimately remove the drivers/i2c/chips directory, this patch series removes three drivers for GPIO-expanders which are obsoleted and marked as deprecated for more than a year. The newer (and better) drivers can be found in drivers/gpio. As it is ensured that the newer drivers cover the same i2c_device_ids, all platform_devices will still match. Some defconfig updates may be necessary though, but according to [1] this is left to the arch|platform-maintainers (also as most defconfigs are quite outdated). For that reason, I put the relevant arch-mailing-lists to Cc. Comments are welcome. Regards, Wolfram [1] http://lkml.org/lkml/2009/5/7/34 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 1/4] gpio/pcf857x: copy i2c_device_id from old pcf8574-driver
The deprecated pcf8574 driver is going to be removed. Make sure this replacement-driver inherits all i2c_device_ids for a smooth transition. Signed-off-by: Wolfram Sang w.s...@pengutronix.de Cc: David Brownell dbrown...@users.sourceforge.net Cc: Jean Delvare kh...@linux-fr.org --- drivers/gpio/pcf857x.c |1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/drivers/gpio/pcf857x.c b/drivers/gpio/pcf857x.c index 9525724..3f1ec1e 100644 --- a/drivers/gpio/pcf857x.c +++ b/drivers/gpio/pcf857x.c @@ -28,6 +28,7 @@ static const struct i2c_device_id pcf857x_id[] = { { pcf8574, 8 }, + { pcf8574a, 8 }, { pca8574, 8 }, { pca9670, 8 }, { pca9672, 8 }, -- 1.6.3.3 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 2/4] i2c/chips: Remove deprecated pcf8575-driver
The pcf8575-driver in drivers/i2c/chips which just exports its register to sysfs is superseeded by drivers/gpio/pcf857x.c which properly uses the gpiolib. As this driver has been deprecated for more than a year, finally remove it. Signed-off-by: Wolfram Sang w.s...@pengutronix.de Cc: Bart Van Assche bart.vanass...@gmail.com Cc: Jean Delvare kh...@linux-fr.org --- Documentation/i2c/chips/pcf8575 | 69 -- drivers/i2c/chips/Kconfig | 18 drivers/i2c/chips/Makefile |1 - drivers/i2c/chips/pcf8575.c | 198 --- 4 files changed, 0 insertions(+), 286 deletions(-) delete mode 100644 Documentation/i2c/chips/pcf8575 delete mode 100644 drivers/i2c/chips/pcf8575.c diff --git a/Documentation/i2c/chips/pcf8575 b/Documentation/i2c/chips/pcf8575 deleted file mode 100644 index 40b268e..000 --- a/Documentation/i2c/chips/pcf8575 +++ /dev/null @@ -1,69 +0,0 @@ -About the PCF8575 chip and the pcf8575 kernel driver - - -The PCF8575 chip is produced by the following manufacturers: - - * Philips NXP - http://www.nxp.com/#/pip/cb=[type=product,path=50807/41735/41850,final=PCF8575_3]|pip=[pip=PCF8575_3][0] - - * Texas Instruments -http://focus.ti.com/docs/prod/folders/print/pcf8575.html - - -Some vendors sell small PCB's with the PCF8575 mounted on it. You can connect -such a board to a Linux host via e.g. an USB to I2C interface. Examples of -PCB boards with a PCF8575: - - * SFE Breakout Board for PCF8575 I2C Expander by RobotShop - http://www.robotshop.ca/home/products/robot-parts/electronics/adapters-converters/sfe-pcf8575-i2c-expander-board.html - - * Breakout Board for PCF8575 I2C Expander by Spark Fun Electronics -http://www.sparkfun.com/commerce/product_info.php?products_id=8130 - - -Description -The PCF8575 chip is a 16-bit I/O expander for the I2C bus. Up to eight of -these chips can be connected to the same I2C bus. You can find this -chip on some custom designed hardware, but you won't find it on PC -motherboards. - -The PCF8575 chip consists of a 16-bit quasi-bidirectional port and an I2C-bus -interface. Each of the sixteen I/O's can be independently used as an input or -an output. To set up an I/O pin as an input, you have to write a 1 to the -corresponding output. - -For more information please see the datasheet. - - -Detection -- - -There is no method known to detect whether a chip on a given I2C address is -a PCF8575 or whether it is any other I2C device, so you have to pass the I2C -bus and address of the installed PCF8575 devices explicitly to the driver at -load time via the force=... parameter. - -/sys interface --- - -For each address on which a PCF8575 chip was found or forced the following -files will be created under /sys: -* /sys/bus/i2c/devices/bus-address/read -* /sys/bus/i2c/devices/bus-address/write -where bus is the I2C bus number (0, 1, ...) and address is the four-digit -hexadecimal representation of the 7-bit I2C address of the PCF8575 -(0020 .. 0027). - -The read file is read-only. Reading it will trigger an I2C read and will hence -report the current input state for the pins configured as inputs, and the -current output value for the pins configured as outputs. - -The write file is read-write. Writing a value to it will configure all pins -as output for which the corresponding bit is zero. Reading the write file will -return the value last written, or -EAGAIN if no value has yet been written to -the write file. - -On module initialization the configuration of the chip is not changed -- the -chip is left in the state it was already configured in through either power-up -or through previous I2C write actions. diff --git a/drivers/i2c/chips/Kconfig b/drivers/i2c/chips/Kconfig index 02d746c..1b5455e 100644 --- a/drivers/i2c/chips/Kconfig +++ b/drivers/i2c/chips/Kconfig @@ -33,24 +33,6 @@ config SENSORS_PCF8574 These devices are hard to detect and rarely found on mainstream hardware. If unsure, say N. -config PCF8575 - tristate Philips PCF8575 (DEPRECATED) - default n - depends on GPIO_PCF857X = n - help - If you say yes here you get support for Philips PCF8575 chip. - This chip is a 16-bit I/O expander for the I2C bus. Several other - chip manufacturers sell equivalent chips, e.g. Texas Instruments. - - This driver can also be built as a module. If so, the module - will be called pcf8575. - - This driver is deprecated and will be dropped soon. Use - drivers/gpio/pcf857x.c instead. - - This device is hard to detect and is rarely found on mainstream - hardware. If unsure, say N. - config SENSORS_PCA9539 tristate Philips PCA9539 16-bit I/O port (DEPRECATED) depends on EXPERIMENTAL GPIO_PCA953X = n diff --git a/drivers/i2c/chips/Makefile b/drivers/i2c/chips/Makefile index
[PATCH 3/4] i2c/chips: Remove deprecated pca9539-driver
The pca9539-driver in drivers/i2c/chips which just exports its registers to sysfs is superseeded by drivers/gpio/pca953x.c which properly uses the gpiolib. As this driver has been deprecated for more than a year, finally remove it. Signed-off-by: Wolfram Sang w.s...@pengutronix.de Cc: Ben Gardner gardner@gmail.com Cc: Jean Delvare kh...@linux-fr.org --- Documentation/i2c/chips/pca9539 | 58 --- drivers/i2c/chips/Kconfig | 13 drivers/i2c/chips/Makefile |1 - drivers/i2c/chips/pca9539.c | 152 --- 4 files changed, 0 insertions(+), 224 deletions(-) delete mode 100644 Documentation/i2c/chips/pca9539 delete mode 100644 drivers/i2c/chips/pca9539.c diff --git a/Documentation/i2c/chips/pca9539 b/Documentation/i2c/chips/pca9539 deleted file mode 100644 index 6aff890..000 --- a/Documentation/i2c/chips/pca9539 +++ /dev/null @@ -1,58 +0,0 @@ -Kernel driver pca9539 -= - -NOTE: this driver is deprecated and will be dropped soon, use -drivers/gpio/pca9539.c instead. - -Supported chips: - * Philips PCA9539 -Prefix: 'pca9539' -Addresses scanned: none -Datasheet: -http://www.semiconductors.philips.com/acrobat/datasheets/PCA9539_2.pdf - -Author: Ben Gardner bgard...@wabtec.com - - -Description - -The Philips PCA9539 is a 16 bit low power I/O device. -All 16 lines can be individually configured as an input or output. -The input sense can also be inverted. -The 16 lines are split between two bytes. - - -Detection -- - -The PCA9539 is difficult to detect and not commonly found in PC machines, -so you have to pass the I2C bus and address of the installed PCA9539 -devices explicitly to the driver at load time via the force=... parameter. - - -Sysfs entries -- - -Each is a byte that maps to the 8 I/O bits. -A '0' suffix is for bits 0-7, while '1' is for bits 8-15. - -input[01] - read the current value -output[01]- sets the output value -direction[01] - direction of each bit: 1=input, 0=output -invert[01]- toggle the input bit sense - -input reads the actual state of the line and is always available. -The direction defaults to input for all channels. - - -General Remarks - -Note that each output, direction, and invert entry controls 8 lines. -You should use the read, modify, write sequence. -For example. to set output bit 0 of 1. - val=$(cat output0) - val=$(( $val | 1 )) - echo $val output0 - diff --git a/drivers/i2c/chips/Kconfig b/drivers/i2c/chips/Kconfig index 1b5455e..8cd1a7f 100644 --- a/drivers/i2c/chips/Kconfig +++ b/drivers/i2c/chips/Kconfig @@ -33,19 +33,6 @@ config SENSORS_PCF8574 These devices are hard to detect and rarely found on mainstream hardware. If unsure, say N. -config SENSORS_PCA9539 - tristate Philips PCA9539 16-bit I/O port (DEPRECATED) - depends on EXPERIMENTAL GPIO_PCA953X = n - help - If you say yes here you get support for the Philips PCA9539 - 16-bit I/O port. - - This driver can also be built as a module. If so, the module - will be called pca9539. - - This driver is deprecated and will be dropped soon. Use - drivers/gpio/pca953x.c instead. - config SENSORS_TSL2550 tristate Taos TSL2550 ambient light sensor depends on EXPERIMENTAL diff --git a/drivers/i2c/chips/Makefile b/drivers/i2c/chips/Makefile index fceb377..8cd778d 100644 --- a/drivers/i2c/chips/Makefile +++ b/drivers/i2c/chips/Makefile @@ -11,7 +11,6 @@ # obj-$(CONFIG_DS1682) += ds1682.o -obj-$(CONFIG_SENSORS_PCA9539) += pca9539.o obj-$(CONFIG_SENSORS_PCF8574) += pcf8574.o obj-$(CONFIG_SENSORS_TSL2550) += tsl2550.o diff --git a/drivers/i2c/chips/pca9539.c b/drivers/i2c/chips/pca9539.c deleted file mode 100644 index 270de4e..000 --- a/drivers/i2c/chips/pca9539.c +++ /dev/null @@ -1,152 +0,0 @@ -/* -pca9539.c - 16-bit I/O port with interrupt and reset - -Copyright (C) 2005 Ben Gardner bgard...@wabtec.com - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; version 2 of the License. -*/ - -#include linux/module.h -#include linux/init.h -#include linux/slab.h -#include linux/i2c.h -#include linux/hwmon-sysfs.h - -/* Addresses to scan: none, device is not autodetected */ -static const unsigned short normal_i2c[] = { I2C_CLIENT_END }; - -/* Insmod parameters */ -I2C_CLIENT_INSMOD_1(pca9539); - -enum pca9539_cmd -{ - PCA9539_INPUT_0 = 0, - PCA9539_INPUT_1 = 1, - PCA9539_OUTPUT_0= 2, - PCA9539_OUTPUT_1= 3, - PCA9539_INVERT_0= 4, - PCA9539_INVERT_1= 5, - PCA9539_DIRECTION_0 = 6, - PCA9539_DIRECTION_1 = 7, -}; - -/* following are the sysfs callback functions */ -static ssize_t
[PATCH 4/4] i2c/chips: Remove deprecated pcf8574-driver
The pcf8574-driver in drivers/i2c/chips which just exports its register to sysfs is superseeded by drivers/gpio/pcf857x.c which properly uses the gpiolib. As this driver has been deprecated for more than a year, finally remove it. Signed-off-by: Wolfram Sang w.s...@pengutronix.de Cc: Aurelien Jarno aurel...@aurel32.net Cc: Jean Delvare kh...@linux-fr.org --- Documentation/i2c/chips/pcf8574 | 65 drivers/i2c/chips/Kconfig | 17 --- drivers/i2c/chips/Makefile |1 - drivers/i2c/chips/pcf8574.c | 215 --- 4 files changed, 0 insertions(+), 298 deletions(-) delete mode 100644 Documentation/i2c/chips/pcf8574 delete mode 100644 drivers/i2c/chips/pcf8574.c diff --git a/Documentation/i2c/chips/pcf8574 b/Documentation/i2c/chips/pcf8574 deleted file mode 100644 index 235815c..000 --- a/Documentation/i2c/chips/pcf8574 +++ /dev/null @@ -1,65 +0,0 @@ -Kernel driver pcf8574 -= - -Supported chips: - * Philips PCF8574 -Prefix: 'pcf8574' -Addresses scanned: none -Datasheet: Publicly available at the Philips Semiconductors website - http://www.semiconductors.philips.com/pip/PCF8574P.html - - * Philips PCF8574A -Prefix: 'pcf8574a' -Addresses scanned: none -Datasheet: Publicly available at the Philips Semiconductors website - http://www.semiconductors.philips.com/pip/PCF8574P.html - -Authors: -Frodo Looijaard fro...@dds.nl, -Philip Edelbrock p...@netroedge.com, -Dan Eaton dan.ea...@rocketlogix.com, -Aurelien Jarno aurel...@aurel32.net, -Jean Delvare kh...@linux-fr.org, - - -Description -The PCF8574(A) is an 8-bit I/O expander for the I2C bus produced by Philips -Semiconductors. It is designed to provide a byte I2C interface to up to 16 -separate devices (8 x PCF8574 and 8 x PCF8574A). - -This device consists of a quasi-bidirectional port. Each of the eight I/Os -can be independently used as an input or output. To setup an I/O as an -input, you have to write a 1 to the corresponding output. - -For more informations see the datasheet. - - -Accessing PCF8574(A) via /sys interface -- - -The PCF8574(A) is plainly impossible to detect ! Stupid chip. -So, you have to pass the I2C bus and address of the installed PCF857A -and PCF8574A devices explicitly to the driver at load time via the -force=... parameter. - -On detection (i.e. insmod, modprobe et al.), directories are being -created for each detected PCF8574(A): - -/sys/bus/i2c/devices/0-1/ -where 0 is the bus the chip was detected on (e. g. i2c-0) -and 1 the chip address ([20..27] or [38..3f]): - -(example: /sys/bus/i2c/devices/1-0020/) - -Inside these directories, there are two files each: -read and write (and one file with chip name). - -The read file is read-only. Reading gives you the current I/O input -if the corresponding output is set as 1, otherwise the current output -value, that is to say 0. - -The write file is read/write. Writing a value outputs it on the I/O -port. Reading returns the last written value. As it is not possible -to read this value from the chip, you need to write at least once to -this file before you can read back from it. diff --git a/drivers/i2c/chips/Kconfig b/drivers/i2c/chips/Kconfig index 8cd1a7f..f9618f4 100644 --- a/drivers/i2c/chips/Kconfig +++ b/drivers/i2c/chips/Kconfig @@ -16,23 +16,6 @@ config DS1682 This driver can also be built as a module. If so, the module will be called ds1682. -config SENSORS_PCF8574 - tristate Philips PCF8574 and PCF8574A (DEPRECATED) - depends on EXPERIMENTAL GPIO_PCF857X = n - default n - help - If you say yes here you get support for Philips PCF8574 and - PCF8574A chips. These chips are 8-bit I/O expanders for the I2C bus. - - This driver can also be built as a module. If so, the module - will be called pcf8574. - - This driver is deprecated and will be dropped soon. Use - drivers/gpio/pcf857x.c instead. - - These devices are hard to detect and rarely found on mainstream - hardware. If unsure, say N. - config SENSORS_TSL2550 tristate Taos TSL2550 ambient light sensor depends on EXPERIMENTAL diff --git a/drivers/i2c/chips/Makefile b/drivers/i2c/chips/Makefile index 8cd778d..749cf36 100644 --- a/drivers/i2c/chips/Makefile +++ b/drivers/i2c/chips/Makefile @@ -11,7 +11,6 @@ # obj-$(CONFIG_DS1682) += ds1682.o -obj-$(CONFIG_SENSORS_PCF8574) += pcf8574.o obj-$(CONFIG_SENSORS_TSL2550) += tsl2550.o ifeq ($(CONFIG_I2C_DEBUG_CHIP),y) diff --git a/drivers/i2c/chips/pcf8574.c b/drivers/i2c/chips/pcf8574.c deleted file mode 100644 index 6ec3098..000 --- a/drivers/i2c/chips/pcf8574.c +++ /dev/null @@ -1,215 +0,0 @@ -/* -Copyright (c) 2000 Frodo Looijaard fro...@dds.nl, -Philip Edelbrock
powerpc/ps3: Workaround for flash memory I/O error
A workaround for flash memory I/O errors when the PS3 internal hard disk has not been formatted for OtherOS use. This error condition mainly effects 'Live CD' users who have not formatted the PS3's internal hard disk for OtherOS. Fixes errors similar to these when using the ps3-flash-util or ps3-boot-game-os programs: ps3flash read failed 0x205 os_area_header_read: read error: os_area_header: Input/output error main:627: os_area_read_hp error. ERROR: can't change boot flag Signed-off-by: Geoff Levand geoffrey.lev...@am.sony.com --- drivers/ps3/ps3stor_lib.c | 65 +++--- 1 file changed, 62 insertions(+), 3 deletions(-) --- a/drivers/ps3/ps3stor_lib.c +++ b/drivers/ps3/ps3stor_lib.c @@ -23,6 +23,65 @@ #include asm/lv1call.h #include asm/ps3stor.h +/* + * A workaround for flash memory I/O errors when the internal hard disk + * has not been formatted for OtherOS use. Delay disk close until flash + * memory is closed. + */ + +static struct ps3_flash_workaround { + int flash_open; + int disk_open; + struct ps3_system_bus_device *disk_sbd; +} ps3_flash_workaround; + +static int ps3stor_open_hv_device(struct ps3_system_bus_device *sbd) +{ + int error = ps3_open_hv_device(sbd); + + if (error) + return error; + + if (sbd-match_id == PS3_MATCH_ID_STOR_FLASH) + ps3_flash_workaround.flash_open = 1; + + if (sbd-match_id == PS3_MATCH_ID_STOR_DISK) + ps3_flash_workaround.disk_open = 1; + + return 0; +} + +static int ps3stor_close_hv_device(struct ps3_system_bus_device *sbd) +{ + int error; + + if (sbd-match_id == PS3_MATCH_ID_STOR_DISK +ps3_flash_workaround.disk_open +ps3_flash_workaround.flash_open) { + ps3_flash_workaround.disk_sbd = sbd; + return 0; + } + + error = ps3_close_hv_device(sbd); + + if (error) + return error; + + if (sbd-match_id == PS3_MATCH_ID_STOR_DISK) + ps3_flash_workaround.disk_open = 0; + + if (sbd-match_id == PS3_MATCH_ID_STOR_FLASH) { + ps3_flash_workaround.flash_open = 0; + + if (ps3_flash_workaround.disk_sbd) { + ps3_close_hv_device(ps3_flash_workaround.disk_sbd); + ps3_flash_workaround.disk_open = 0; + ps3_flash_workaround.disk_sbd = NULL; + } + } + + return 0; +} static int ps3stor_probe_access(struct ps3_storage_device *dev) { @@ -90,7 +149,7 @@ int ps3stor_setup(struct ps3_storage_dev int error, res, alignment; enum ps3_dma_page_size page_size; - error = ps3_open_hv_device(dev-sbd); + error = ps3stor_open_hv_device(dev-sbd); if (error) { dev_err(dev-sbd.core, %s:%u: ps3_open_hv_device failed %d\n, __func__, @@ -166,7 +225,7 @@ fail_free_irq: fail_sb_event_receive_port_destroy: ps3_sb_event_receive_port_destroy(dev-sbd, dev-irq); fail_close_device: - ps3_close_hv_device(dev-sbd); + ps3stor_close_hv_device(dev-sbd); fail: return error; } @@ -193,7 +252,7 @@ void ps3stor_teardown(struct ps3_storage %s:%u: destroy event receive port failed %d\n, __func__, __LINE__, error); - error = ps3_close_hv_device(dev-sbd); + error = ps3stor_close_hv_device(dev-sbd); if (error) dev_err(dev-sbd.core, %s:%u: ps3_close_hv_device failed %d\n, __func__, ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [Uclinux-dist-devel] Removing deprecated drivers from drivers/i2c/chips
On Wed, Sep 9, 2009 at 17:22, Wolfram Sang wrote: continuing the quest to clean up and ultimately remove the drivers/i2c/chips directory, this patch series removes three drivers for GPIO-expanders which are obsoleted and marked as deprecated for more than a year. The newer (and better) drivers can be found in drivers/gpio. As it is ensured that the newer drivers cover the same i2c_device_ids, all platform_devices will still match. Some defconfig updates may be necessary though, but according to [1] this is left to the arch|platform-maintainers (also as most defconfigs are quite outdated). For that reason, I put the relevant arch-mailing-lists to Cc. Comments are welcome. the Blackfin defconfigs refer to an input driver for the PCF8574, not the I2C client driver -mike ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH 3/4] i2c/chips: Remove deprecated pca9539-driver
On Wed, Sep 9, 2009 at 4:22 PM, Wolfram Sangw.s...@pengutronix.de wrote: The pca9539-driver in drivers/i2c/chips which just exports its registers to sysfs is superseeded by drivers/gpio/pca953x.c which properly uses the gpiolib. As this driver has been deprecated for more than a year, finally remove it. Signed-off-by: Wolfram Sang w.s...@pengutronix.de Cc: Ben Gardner gardner@gmail.com Cc: Jean Delvare kh...@linux-fr.org Acked-by: Ben Gardner gardner@gmail.com Thanks for taking care of this. Ben ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
RE: Queries regarding I2C and GPIO driver for Freescale MPC5121e in Linux2.6.24 of BSP: MPC512xADS_20090603-ltib.iso
From the following error message, I2C controller can't receive ACK from I2C client, so please make sure that the pins of I2C have been initialized properly, or you can measure the tx signal and rx signal on the right pins. B.R, Hongjun From: Uma Kanta Patro [mailto:upa...@implantaire.com] Sent: Wednesday, September 09, 2009 9:13 PM To: Chen Hongjun-R66092; linuxppc-dev@lists.ozlabs.org Subject: RE: Queries regarding I2C and GPIO driver for Freescale MPC5121e in Linux2.6.24 of BSP: MPC512xADS_20090603-ltib.iso Hi Chen Hongjun-R66092, Thanks for your response. Actually for the GPIO driver I am having some success and it is in progress. But regarding the I2C chip(client) driver I am running witout any progress. Actually I followed the existing driver $(LINUX)\drivers\rtc\rtc-m41t80.c (for the RTC M41T62 existing on the ADS5121Rev4.1 board). I made a legacy style driver with attach_adapter and detach_client functions defined. For testing purpose I geve the chip address as 0x68(address of M41T62 existing on the board). But when I tried ot insert my driver I get the error message as: [r...@freescale chips]# insmod dis_fpc.ko [ 177.808848] i2c 0-0068: uevent [ 498.528032] In dis_fpc_init [ 498.531851] i2c-core: driver [dis_fpc] registered [ 498.532446] In dis_fpc_attach_adapter [ 498.536827] i2c-adapter i2c-0: found normal entry for adapter 0, addr 0x55 [ 498.537730] i2c-adapter i2c-0: master_xfer[0] W, addr=0x55, len=0 [ 498.538533] Doing write 0 bytes to 0x55 - 1 of 1 messages [ 498.539770] I2C: No RXAK [ 498.540970] In dis_fpc_attach_adapter [ 498.554500] i2c-adapter i2c-1: found normal entry for adapter 1, addr 0x55 [ 498.555166] i2c-adapter i2c-1: master_xfer[0] W, addr=0x55, len=0 [ 498.555872] Doing write 0 bytes to 0x55 - 1 of 1 messages [ 498.556785] I2C: MAL [ 498.557476] In dis_fpc_attach_adapter [ 498.565733] i2c-adapter i2c-2: found normal entry for adapter 2, addr 0x55 [ 498.566377] i2c-adapter i2c-2: master_xfer[0] W, addr=0x55, len=0 [ 498.567082] Doing write 0 bytes to 0x55 - 1 of 1 messages [ 498.568240] I2C: No RXAK So can you tell me what other places do I need to change the configurations( like i2c_platform_data definition, linking the chip to the specific I2C module(0/1/2) with the adapter, configuring the speed of I2C communication etc). I would like to get any suggestion on making the I2C chip driver inpowerpc platform. Thanks Regards, Uma From: Chen Hongjun-R66092 [mailto:hong-jun.c...@freescale.com] Sent: Wednesday, September 09, 2009 5:39 AM To: Uma Kanta Patro; linuxppc-dev@lists.ozlabs.org Subject: RE: Queries regarding I2C and GPIO driver for Freescale MPC5121e in Linux2.6.24 of BSP: MPC512xADS_20090603-ltib.iso One I2C driver has been included in 0603 bsp, you can refer to it. It has no specific driver for GPIO, but you can find some initializing code for GPIO in arch/powerpc/platforms/512x/mpc5125_ads.c. and mpc512x_pm_test.c. From: linuxppc-dev-bounces+hong-jun.chen=freescale@lists.ozlabs.org [mailto:linuxppc-dev-bounces+hong-jun.chen=freescale@lists.ozlabs.or g] On Behalf Of Uma Kanta Patro Sent: Tuesday, September 08, 2009 6:56 PM To: linuxppc-dev@lists.ozlabs.org Subject: Queries regarding I2C and GPIO driver for Freescale MPC5121e in Linux2.6.24 of BSP: MPC512xADS_20090603-ltib.iso Hi all, I am a newbie to the powerpc linux kernel, but I have worked on some drivers in arm architecture. I am finding powerpc architecture to be fully different than that. I am working on Freescale MPC5121e with the BSP MPC512xADS_20090603-ltib.iso running in it on the ADS512101 Rev4.1 development kit. Can anyone help me in finding some documentation for understanding and working on the powerpc kernel. Any links to the powerpc forums will also be appreciable. - Currently I am going to develop an I2C client driver for one slave microcontroller of our project. I have some knowledge in the I2C client driver making(legacy style and new style). I made a basic I2C client driver to probe for the chip address and for testing I gave it the chip address 0x68(I2C chip address of the M4T162 RTC, present on the board). But while inserting my driver I am
[PATCH 1/3] phy/marvell: Make non-aneg speed/duplex forcing work for 88E1111 PHYs
According to specs, when auto-negotiation is disabled, Marvell PHYs need a software reset after changing speed/duplex forcing bits. Otherwise, the modified bits have no effect. Signed-off-by: Anton Vorontsov avoront...@ru.mvista.com --- drivers/net/phy/marvell.c | 21 - 1 files changed, 20 insertions(+), 1 deletions(-) diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c index dd6f54d..6f69b9b 100644 --- a/drivers/net/phy/marvell.c +++ b/drivers/net/phy/marvell.c @@ -155,8 +155,27 @@ static int marvell_config_aneg(struct phy_device *phydev) return err; err = genphy_config_aneg(phydev); + if (err 0) + return err; - return err; + if (phydev-autoneg != AUTONEG_ENABLE) { + int bmcr; + + /* +* A write to speed/duplex bits (that is performed by +* genphy_config_aneg() call above) must be followed by +* a software reset. Otherwise, the write has no effect. +*/ + bmcr = phy_read(phydev, MII_BMCR); + if (bmcr 0) + return bmcr; + + err = phy_write(phydev, MII_BMCR, bmcr | BMCR_RESET); + if (err 0) + return err; + } + + return 0; } static int m88e1121_config_aneg(struct phy_device *phydev) -- 1.6.3.3 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 2/3] ucc_geth: Rearrange some code to avoid forward declarations
We'll need ugeth_disable() and ugeth_enable() calls earlier in the file, so rearrange some code to avoid forward declarations. The patch doesn't contain any functional changes. Signed-off-by: Anton Vorontsov avoront...@ru.mvista.com --- drivers/net/ucc_geth.c | 300 1 files changed, 149 insertions(+), 151 deletions(-) diff --git a/drivers/net/ucc_geth.c b/drivers/net/ucc_geth.c index 33ed69e..2a2c973 100644 --- a/drivers/net/ucc_geth.c +++ b/drivers/net/ucc_geth.c @@ -1411,6 +1411,155 @@ static int adjust_enet_interface(struct ucc_geth_private *ugeth) return 0; } +static int ugeth_graceful_stop_tx(struct ucc_geth_private *ugeth) +{ + struct ucc_fast_private *uccf; + u32 cecr_subblock; + u32 temp; + int i = 10; + + uccf = ugeth-uccf; + + /* Mask GRACEFUL STOP TX interrupt bit and clear it */ + clrbits32(uccf-p_uccm, UCC_GETH_UCCE_GRA); + out_be32(uccf-p_ucce, UCC_GETH_UCCE_GRA); /* clear by writing 1 */ + + /* Issue host command */ + cecr_subblock = + ucc_fast_get_qe_cr_subblock(ugeth-ug_info-uf_info.ucc_num); + qe_issue_cmd(QE_GRACEFUL_STOP_TX, cecr_subblock, +QE_CR_PROTOCOL_ETHERNET, 0); + + /* Wait for command to complete */ + do { + msleep(10); + temp = in_be32(uccf-p_ucce); + } while (!(temp UCC_GETH_UCCE_GRA) --i); + + uccf-stopped_tx = 1; + + return 0; +} + +static int ugeth_graceful_stop_rx(struct ucc_geth_private *ugeth) +{ + struct ucc_fast_private *uccf; + u32 cecr_subblock; + u8 temp; + int i = 10; + + uccf = ugeth-uccf; + + /* Clear acknowledge bit */ + temp = in_8(ugeth-p_rx_glbl_pram-rxgstpack); + temp = ~GRACEFUL_STOP_ACKNOWLEDGE_RX; + out_8(ugeth-p_rx_glbl_pram-rxgstpack, temp); + + /* Keep issuing command and checking acknowledge bit until + it is asserted, according to spec */ + do { + /* Issue host command */ + cecr_subblock = + ucc_fast_get_qe_cr_subblock(ugeth-ug_info-uf_info. + ucc_num); + qe_issue_cmd(QE_GRACEFUL_STOP_RX, cecr_subblock, +QE_CR_PROTOCOL_ETHERNET, 0); + msleep(10); + temp = in_8(ugeth-p_rx_glbl_pram-rxgstpack); + } while (!(temp GRACEFUL_STOP_ACKNOWLEDGE_RX) --i); + + uccf-stopped_rx = 1; + + return 0; +} + +static int ugeth_restart_tx(struct ucc_geth_private *ugeth) +{ + struct ucc_fast_private *uccf; + u32 cecr_subblock; + + uccf = ugeth-uccf; + + cecr_subblock = + ucc_fast_get_qe_cr_subblock(ugeth-ug_info-uf_info.ucc_num); + qe_issue_cmd(QE_RESTART_TX, cecr_subblock, QE_CR_PROTOCOL_ETHERNET, 0); + uccf-stopped_tx = 0; + + return 0; +} + +static int ugeth_restart_rx(struct ucc_geth_private *ugeth) +{ + struct ucc_fast_private *uccf; + u32 cecr_subblock; + + uccf = ugeth-uccf; + + cecr_subblock = + ucc_fast_get_qe_cr_subblock(ugeth-ug_info-uf_info.ucc_num); + qe_issue_cmd(QE_RESTART_RX, cecr_subblock, QE_CR_PROTOCOL_ETHERNET, +0); + uccf-stopped_rx = 0; + + return 0; +} + +static int ugeth_enable(struct ucc_geth_private *ugeth, enum comm_dir mode) +{ + struct ucc_fast_private *uccf; + int enabled_tx, enabled_rx; + + uccf = ugeth-uccf; + + /* check if the UCC number is in range. */ + if (ugeth-ug_info-uf_info.ucc_num = UCC_MAX_NUM) { + if (netif_msg_probe(ugeth)) + ugeth_err(%s: ucc_num out of range., __func__); + return -EINVAL; + } + + enabled_tx = uccf-enabled_tx; + enabled_rx = uccf-enabled_rx; + + /* Get Tx and Rx going again, in case this channel was actively + disabled. */ + if ((mode COMM_DIR_TX) (!enabled_tx) uccf-stopped_tx) + ugeth_restart_tx(ugeth); + if ((mode COMM_DIR_RX) (!enabled_rx) uccf-stopped_rx) + ugeth_restart_rx(ugeth); + + ucc_fast_enable(uccf, mode);/* OK to do even if not disabled */ + + return 0; + +} + +static int ugeth_disable(struct ucc_geth_private *ugeth, enum comm_dir mode) +{ + struct ucc_fast_private *uccf; + + uccf = ugeth-uccf; + + /* check if the UCC number is in range. */ + if (ugeth-ug_info-uf_info.ucc_num = UCC_MAX_NUM) { + if (netif_msg_probe(ugeth)) + ugeth_err(%s: ucc_num out of range., __func__); + return -EINVAL; + } + + /* Stop any transmissions */ + if ((mode COMM_DIR_TX) uccf-enabled_tx !uccf-stopped_tx) + ugeth_graceful_stop_tx(ugeth); + + /* Stop any receptions */ + if ((mode COMM_DIR_RX) uccf-enabled_rx !uccf-stopped_rx) +
[PATCH 3/3] ucc_geth: Fix hangs after switching from full to half duplex
MPC8360 QE UCC ethernet controllers hang when changing link duplex under a load (a bit of NFS activity is enough). PHY: m...@e0102120:00 - Link is Up - 1000/Full sh-3.00# ethtool -s eth0 speed 100 duplex half autoneg off PHY: m...@e0102120:00 - Link is Down PHY: m...@e0102120:00 - Link is Up - 100/Half NETDEV WATCHDOG: eth0 (ucc_geth): transmit queue 0 timed out [ cut here ] Badness at c01fcbd0 [verbose debug info unavailable] NIP: c01fcbd0 LR: c01fcbd0 CTR: c0194e44 ... The cure is to disable the controller before changing speed/duplex and enable it afterwards. Signed-off-by: Anton Vorontsov avoront...@ru.mvista.com --- drivers/net/ucc_geth.c |4 1 files changed, 4 insertions(+), 0 deletions(-) diff --git a/drivers/net/ucc_geth.c b/drivers/net/ucc_geth.c index 2a2c973..9ad9015 100644 --- a/drivers/net/ucc_geth.c +++ b/drivers/net/ucc_geth.c @@ -1631,9 +1631,13 @@ static void adjust_link(struct net_device *dev) ugeth-oldspeed = phydev-speed; } + ugeth_disable(ugeth, COMM_DIR_RX_AND_TX); + out_be32(ug_regs-maccfg2, tempval); out_be32(uf_regs-upsmr, upsmr); + ugeth_enable(ugeth, COMM_DIR_RX_AND_TX); + if (!ugeth-oldlink) { new_state = 1; ugeth-oldlink = 1; -- 1.6.3.3 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [FTRACE] Enabling function_graph causes OOPS
Steven Rostedt wrote: Ah, seems the bug happens to be in the module handling. Does the call back always have .mod_return_to_handler? Yes. Every time it ends up in .mod_return_to_handler Thanks -Sachin This doesn't surprise me any. The module code is a bit harry, and function graph does some crazy crap with it. -- Steve -- - Sachin Sant IBM Linux Technology Center India Systems and Technology Labs Bangalore, India - ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev