Re: [Patch v2 1/2] 5200/mpc: improve i2c bus error recovery
This patch improves the recovery of the MPC's I2C bus from errors like bus hangs resulting in timeouts: 1. make the bus timeout configurable, as it depends on the bus clock and the attached slave chip(s); default is still 1 second; 2. detect any of the cases indicated by the CF, BB and RXAK MSR flags if a timeout occurs, and add a missing (required) MAL reset; 3. use a more reliable method to fixup the bus if a hang has been detected. The sequence is sent 9 times which seems to be necessary if a slave misses more than one clock cycle. For 400 kHz bus speed, the fixup is also ~70us (81us vs. 150us) faster. Tested on a custom Lite5200b derived board, with a Dallas RTC, AD sensors and NXP IO expander chips attached to the i2c. Changes vs. v1: - use improved bus fixup sequence for all chips (not only the 5200) - calculate real clock from defaults if no clock is given in the device tree - better description (I hope) of the changes. I didn't split the changes in this file into three parts as recommended by Grant, as they actually belong together (i.e. they address one single problem, just in three places of one single source file). Signed-off-by: Albrecht Dreß albrecht.dr...@arcor.de --- Note about the reset sequence: I verified the waveforms for 18.4kHz, 85.9kHz and 375kHz (drop me a note if you want to see scope screen shots). Not verified on other mpc chips yet. @Ira: thanks in advance for giving it a try on your box! Does this reset sequence also send a START condition for every clock? The ideal I2C reset sequence should look like this: for(j = 0; j 9; j++) { if(I2C_READ) send_start(); I2C_SCL(0); I2C_DELAY; I2C_TRISTATE; I2C_SDA(1); I2C_DELAY; I2C_SCL(1); I2C_DELAY; I2C_DELAY; } send_stop(); static void send_start(void) { I2C_DELAY; I2C_TRISTATE; I2C_SDA(1); I2C_DELAY; I2C_SCL(1); I2C_DELAY; I2C_SDA(0); I2C_ACTIVE; I2C_DELAY; } static void send_stop(void) { I2C_SCL(0); I2C_DELAY; I2C_SDA(0); I2C_ACTIVE; I2C_DELAY; I2C_SCL(1); I2C_DELAY; I2C_TRISTATE; I2C_SDA(1); I2C_DELAY; } Jocke ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH 1/5] powerpc/head fsl: fix the case where we are not in the first page
* Kumar Gala | 2010-02-17 21:07:49 [-0600]: On Jan 15, 2010, at 10:41 AM, Sebastian Andrzej Siewior wrote: From: Sebastian Andrzej Siewior bige...@linutronix.de During boot we change the mapping a few times until we have a defined mapping. During this procedure a small 4KiB mapping is created and after that one a 64MiB. Currently the offset of the 4KiB page in that we run is zero because the complete startup up code is in first page which starts at RPN zero. If the code is recycled and moved to another location then its execution will fail because the start address in the 64 MiB mapping is computed wrongly. It does not consider the offset to the page from the begin of the memory. This patch fixes this. Usually (system boot) r25 is zero so this does not change anything unless the code is recycled. Signed-off-by: Sebastian Andrzej Siewior bige...@linutronix.de --- arch/powerpc/kernel/head_fsl_booke.S |1 + 1 files changed, 1 insertions(+), 0 deletions(-) I don't get this. Why would would we not run at KERNELBASE? We don't. The ld script makes sure that the entry code is at the begin of our vmlinux and is linked against offset 0. This makes sure it starts at RPN 0. If it would be linked against 4096 _or_ we would have other code in front of us (atleast 4KiB) then the rfi down there would fail because the code assumes that it was started at 0. Right now this is basically a nop because the kernel always starts at 0. This is only required because I grab the same code in kexec / default_machine_kexec() and run it in a random page which is not RPN 0. - k diff --git a/arch/powerpc/kernel/head_fsl_booke.S b/arch/powerpc/kernel/head_fsl_booke.S index 7f4bd7f..799ddbe 100644 --- a/arch/powerpc/kernel/head_fsl_booke.S +++ b/arch/powerpc/kernel/head_fsl_booke.S @@ -275,6 +275,7 @@ skpinv: addir6,r6,1 /* Increment */ 1: mflrr9 rlwimi r6,r9,0,20,31 addir6,r6,(2f - 1b) +add r6, r6, r25 mtspr SPRN_SRR0,r6 mtspr SPRN_SRR1,r7 rfi /* start execution out of TLB1[0] entry */ Sebastian ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH 2/5] powerpc/head fsl: move the temp 4KiB mapping to TLB0
* Kumar Gala | 2010-02-17 21:09:08 [-0600]: On Jan 15, 2010, at 10:41 AM, Sebastian Andrzej Siewior wrote: From: Sebastian Andrzej Siewior bige...@linutronix.de Right now the setup code takes ESEL of the current mapping and puts the temporary into ESEL (old_ESEL 1 ) + 1 which is either one or two. This is actually not required since all slots in TLB0 are invalid by now and can be used. This patch moved the temp mapping to TLB0, ESEL[0]. The invalidation of TLB0 does not care about IPPROT so that part can go as well. The benefit is that now the setup code may set every slot of TLB1 while before that it was not allowed to touch ESEL one or two depending on the old_ESEL. Signed-off-by: Sebastian Andrzej Siewior bige...@linutronix.de --- arch/powerpc/kernel/head_fsl_booke.S | 20 +--- 1 files changed, 5 insertions(+), 15 deletions(-) this is problematic, we can't assume that TLB0 is safe. It possible some other software is running on a second core and does a broadcast tlbivax which will wipe what's in TLB0. Ah right SMP. So if CPU0 would wait until CPU1-X are up and kick them one by one could make it work but is not that pretty. So let me think of something. I will probably just skip the current mapping while making new ones for kexec. - k Sebastian ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [Patch v2 1/2] 5200/mpc: improve i2c bus error recovery
Hi Joakim: Does this reset sequence also send a START condition for every clock? Please see the attached scan from a scope output, showing the first two out of the 9 sequences at 375 kHz (that's what the 5200's divider makes from 400 kHz requested). Resolution is 2us/div and 1V/div for both signals. The waveform itself for each of the 9 sequences is exactly the same we had before with the old solution, just the timing is faster and adjusted to the ii2c clock, i.e. the /relative/ waveforms look identical for slower clocks. Any insight if this is *really* correct would be great, as I'm not an i2c expert. I can only say it reliably fixes the bus hangs I saw! Thanks, Albrecht. Immer auf dem Laufenden! Sport, Auto, Reise, Politik und Promis. Von uns für Sie: der neue Arcor.de-Newsletter! Jetzt anmelden und einfach alles wissen: http://www.arcor.de/rd/footer.newsletterattachment: i2c-fixup.png___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH] perf_event: e500 support
On Wed, Feb 17, 2010 at 09:33:06PM -0600, Kumar Gala wrote: Other than splitting the patch did you have any other changes you wanted to see before we'd get an Ack. I'd like to see this go in for .34. I thought it was a bit ugly having two different definitions of struct power_pmu in perf_event.h with ifdefs. Either give the two structs different names or put them in different files. That plus the splitting out of the perf_callchain patch were my two main concerns. Paul. ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[patch 00/15] powerpc: raw_spinlock conversions
Ben, the following patch series is from preempt-rt. It converts the locks which need to be real spinlocks in -rt to raw_spinlocks. There is no behaviourial change for !RT kernels because spinlocks and raw_spinlocks are the same on !RT. So for mainline this is a pure annotation while having it in mainline takes the burden of keeping up with the code changes from the RT patch set. Please consider to merge into .34. Thanks, tglx ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[patch 03/15] powerpc: Convert die.lock to raw_spinlock
die.lock needs to be a real spinlock in RT. Convert it to raw_spinlock. Signed-off-by: Thomas Gleixner t...@linutronix.de --- arch/powerpc/kernel/traps.c |8 1 file changed, 4 insertions(+), 4 deletions(-) Index: linux-2.6-tip/arch/powerpc/kernel/traps.c === --- linux-2.6-tip.orig/arch/powerpc/kernel/traps.c +++ linux-2.6-tip/arch/powerpc/kernel/traps.c @@ -102,11 +102,11 @@ static inline void pmac_backlight_unblan int die(const char *str, struct pt_regs *regs, long err) { static struct { - spinlock_t lock; + raw_spinlock_t lock; u32 lock_owner; int lock_owner_depth; } die = { - .lock = __SPIN_LOCK_UNLOCKED(die.lock), + .lock = __RAW_SPIN_LOCK_UNLOCKED(die.lock), .lock_owner = -1, .lock_owner_depth = 0 }; @@ -120,7 +120,7 @@ int die(const char *str, struct pt_regs if (die.lock_owner != raw_smp_processor_id()) { console_verbose(); - spin_lock_irqsave(die.lock, flags); + raw_spin_lock_irqsave(die.lock, flags); die.lock_owner = smp_processor_id(); die.lock_owner_depth = 0; bust_spinlocks(1); @@ -155,7 +155,7 @@ int die(const char *str, struct pt_regs bust_spinlocks(0); die.lock_owner = -1; add_taint(TAINT_DIE); - spin_unlock_irqrestore(die.lock, flags); + raw_spin_unlock_irqrestore(die.lock, flags); if (kexec_should_crash(current) || kexec_sr_activated(smp_processor_id())) ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[patch 02/15] powerpc: Convert pmc_owner_lock to raw_spinlock
pmc_owner_lock needs to be a real spinlock in RT. Convert it to raw_spinlock. Signed-off-by: Thomas Gleixner t...@linutronix.de --- arch/powerpc/kernel/pmc.c | 10 +- 1 file changed, 5 insertions(+), 5 deletions(-) Index: linux-2.6-tip/arch/powerpc/kernel/pmc.c === --- linux-2.6-tip.orig/arch/powerpc/kernel/pmc.c +++ linux-2.6-tip/arch/powerpc/kernel/pmc.c @@ -37,7 +37,7 @@ static void dummy_perf(struct pt_regs *r } -static DEFINE_SPINLOCK(pmc_owner_lock); +static DEFINE_RAW_SPINLOCK(pmc_owner_lock); static void *pmc_owner_caller; /* mostly for debugging */ perf_irq_t perf_irq = dummy_perf; @@ -45,7 +45,7 @@ int reserve_pmc_hardware(perf_irq_t new_ { int err = 0; - spin_lock(pmc_owner_lock); + raw_spin_lock(pmc_owner_lock); if (pmc_owner_caller) { printk(KERN_WARNING reserve_pmc_hardware: @@ -59,21 +59,21 @@ int reserve_pmc_hardware(perf_irq_t new_ perf_irq = new_perf_irq ? new_perf_irq : dummy_perf; out: - spin_unlock(pmc_owner_lock); + raw_spin_unlock(pmc_owner_lock); return err; } EXPORT_SYMBOL_GPL(reserve_pmc_hardware); void release_pmc_hardware(void) { - spin_lock(pmc_owner_lock); + raw_spin_lock(pmc_owner_lock); WARN_ON(! pmc_owner_caller); pmc_owner_caller = NULL; perf_irq = dummy_perf; - spin_unlock(pmc_owner_lock); + raw_spin_unlock(pmc_owner_lock); } EXPORT_SYMBOL_GPL(release_pmc_hardware); ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[patch 10/15] powerpc: Convert nv_lock to raw_spinlock
nv_lock needs to be a real spinlock in RT. Convert it to raw_spinlock. Signed-off-by: Thomas Gleixner t...@linutronix.de --- arch/powerpc/platforms/powermac/nvram.c | 14 +++--- 1 file changed, 7 insertions(+), 7 deletions(-) Index: linux-2.6-tip/arch/powerpc/platforms/powermac/nvram.c === --- linux-2.6-tip.orig/arch/powerpc/platforms/powermac/nvram.c +++ linux-2.6-tip/arch/powerpc/platforms/powermac/nvram.c @@ -80,7 +80,7 @@ static int is_core_99; static int core99_bank = 0; static int nvram_partitions[3]; // XXX Turn that into a sem -static DEFINE_SPINLOCK(nv_lock); +static DEFINE_RAW_SPINLOCK(nv_lock); static int (*core99_write_bank)(int bank, u8* datas); static int (*core99_erase_bank)(int bank); @@ -165,10 +165,10 @@ static unsigned char indirect_nvram_read unsigned char val; unsigned long flags; - spin_lock_irqsave(nv_lock, flags); + raw_spin_lock_irqsave(nv_lock, flags); out_8(nvram_addr, addr 5); val = in_8(nvram_data[(addr 0x1f) 4]); - spin_unlock_irqrestore(nv_lock, flags); + raw_spin_unlock_irqrestore(nv_lock, flags); return val; } @@ -177,10 +177,10 @@ static void indirect_nvram_write_byte(in { unsigned long flags; - spin_lock_irqsave(nv_lock, flags); + raw_spin_lock_irqsave(nv_lock, flags); out_8(nvram_addr, addr 5); out_8(nvram_data[(addr 0x1f) 4], val); - spin_unlock_irqrestore(nv_lock, flags); + raw_spin_unlock_irqrestore(nv_lock, flags); } @@ -481,7 +481,7 @@ static void core99_nvram_sync(void) if (!is_core_99 || !nvram_data || !nvram_image) return; - spin_lock_irqsave(nv_lock, flags); + raw_spin_lock_irqsave(nv_lock, flags); if (!memcmp(nvram_image, (u8*)nvram_data + core99_bank*NVRAM_SIZE, NVRAM_SIZE)) goto bail; @@ -503,7 +503,7 @@ static void core99_nvram_sync(void) if (core99_write_bank(core99_bank, nvram_image)) printk(nvram: Error writing bank %d\n, core99_bank); bail: - spin_unlock_irqrestore(nv_lock, flags); + raw_spin_unlock_irqrestore(nv_lock, flags); #ifdef DEBUG mdelay(2000); ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[patch 05/15] powerpc: Convert context_lock to raw_spinlock
context_lock needs to be a real spinlock in RT. Convert it to raw_spinlock. Signed-off-by: Thomas Gleixner t...@linutronix.de --- arch/powerpc/mm/mmu_context_nohash.c | 14 +++--- 1 file changed, 7 insertions(+), 7 deletions(-) Index: linux-2.6-tip/arch/powerpc/mm/mmu_context_nohash.c === --- linux-2.6-tip.orig/arch/powerpc/mm/mmu_context_nohash.c +++ linux-2.6-tip/arch/powerpc/mm/mmu_context_nohash.c @@ -56,7 +56,7 @@ static unsigned int next_context, nr_fre static unsigned long *context_map; static unsigned long *stale_map[NR_CPUS]; static struct mm_struct **context_mm; -static DEFINE_SPINLOCK(context_lock); +static DEFINE_RAW_SPINLOCK(context_lock); #define CTX_MAP_SIZE \ (sizeof(unsigned long) * (last_context / BITS_PER_LONG + 1)) @@ -121,9 +121,9 @@ static unsigned int steal_context_smp(un /* This will happen if you have more CPUs than available contexts, * all we can do here is wait a bit and try again */ - spin_unlock(context_lock); + raw_spin_unlock(context_lock); cpu_relax(); - spin_lock(context_lock); + raw_spin_lock(context_lock); /* This will cause the caller to try again */ return MMU_NO_CONTEXT; @@ -194,7 +194,7 @@ void switch_mmu_context(struct mm_struct unsigned long *map; /* No lockless fast path .. yet */ - spin_lock(context_lock); + raw_spin_lock(context_lock); pr_hard([%d] activating context for mm @%p, active=%d, id=%d, cpu, next, next-context.active, next-context.id); @@ -278,7 +278,7 @@ void switch_mmu_context(struct mm_struct /* Flick the MMU and release lock */ pr_hardcont( - %d\n, id); set_context(id, next-pgd); - spin_unlock(context_lock); + raw_spin_unlock(context_lock); } /* @@ -307,7 +307,7 @@ void destroy_context(struct mm_struct *m WARN_ON(mm-context.active != 0); - spin_lock_irqsave(context_lock, flags); + raw_spin_lock_irqsave(context_lock, flags); id = mm-context.id; if (id != MMU_NO_CONTEXT) { __clear_bit(id, context_map); @@ -318,7 +318,7 @@ void destroy_context(struct mm_struct *m context_mm[id] = NULL; nr_free_contexts++; } - spin_unlock_irqrestore(context_lock, flags); + raw_spin_unlock_irqrestore(context_lock, flags); } #ifdef CONFIG_SMP ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[patch 04/15] powerpc: Convert native_tlbie_lock to raw_spinlock
native_tlbie_lock needs to be a real spinlock in RT. Convert it to raw_spinlock. Signed-off-by: Thomas Gleixner t...@linutronix.de --- arch/powerpc/mm/hash_native_64.c | 14 +++--- 1 file changed, 7 insertions(+), 7 deletions(-) Index: linux-2.6-tip/arch/powerpc/mm/hash_native_64.c === --- linux-2.6-tip.orig/arch/powerpc/mm/hash_native_64.c +++ linux-2.6-tip/arch/powerpc/mm/hash_native_64.c @@ -37,7 +37,7 @@ #define HPTE_LOCK_BIT 3 -static DEFINE_SPINLOCK(native_tlbie_lock); +static DEFINE_RAW_SPINLOCK(native_tlbie_lock); static inline void __tlbie(unsigned long va, int psize, int ssize) { @@ -104,7 +104,7 @@ static inline void tlbie(unsigned long v if (use_local) use_local = mmu_psize_defs[psize].tlbiel; if (lock_tlbie !use_local) - spin_lock(native_tlbie_lock); + raw_spin_lock(native_tlbie_lock); asm volatile(ptesync: : :memory); if (use_local) { __tlbiel(va, psize, ssize); @@ -114,7 +114,7 @@ static inline void tlbie(unsigned long v asm volatile(eieio; tlbsync; ptesync: : :memory); } if (lock_tlbie !use_local) - spin_unlock(native_tlbie_lock); + raw_spin_unlock(native_tlbie_lock); } static inline void native_lock_hpte(struct hash_pte *hptep) @@ -434,7 +434,7 @@ static void native_hpte_clear(void) /* we take the tlbie lock and hold it. Some hardware will * deadlock if we try to tlbie from two processors at once. */ - spin_lock(native_tlbie_lock); + raw_spin_lock(native_tlbie_lock); slots = pteg_count * HPTES_PER_GROUP; @@ -458,7 +458,7 @@ static void native_hpte_clear(void) } asm volatile(eieio; tlbsync; ptesync:::memory); - spin_unlock(native_tlbie_lock); + raw_spin_unlock(native_tlbie_lock); local_irq_restore(flags); } @@ -521,7 +521,7 @@ static void native_flush_hash_range(unsi int lock_tlbie = !cpu_has_feature(CPU_FTR_LOCKLESS_TLBIE); if (lock_tlbie) - spin_lock(native_tlbie_lock); + raw_spin_lock(native_tlbie_lock); asm volatile(ptesync:::memory); for (i = 0; i number; i++) { @@ -536,7 +536,7 @@ static void native_flush_hash_range(unsi asm volatile(eieio; tlbsync; ptesync:::memory); if (lock_tlbie) - spin_unlock(native_tlbie_lock); + raw_spin_unlock(native_tlbie_lock); } local_irq_restore(flags); ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[patch 08/15] powerpc: Convert beatic_irq_mask_lock to raw_spinlock
beatic_irq_mask_lock needs to be a real spinlock in RT. Convert it to raw_spinlock. Signed-off-by: Thomas Gleixner t...@linutronix.de --- arch/powerpc/platforms/cell/beat_interrupt.c | 18 +- 1 file changed, 9 insertions(+), 9 deletions(-) Index: linux-2.6-tip/arch/powerpc/platforms/cell/beat_interrupt.c === --- linux-2.6-tip.orig/arch/powerpc/platforms/cell/beat_interrupt.c +++ linux-2.6-tip/arch/powerpc/platforms/cell/beat_interrupt.c @@ -30,7 +30,7 @@ #include beat_wrapper.h #defineMAX_IRQSNR_IRQS -static DEFINE_SPINLOCK(beatic_irq_mask_lock); +static DEFINE_RAW_SPINLOCK(beatic_irq_mask_lock); static uint64_tbeatic_irq_mask_enable[(MAX_IRQS+255)/64]; static uint64_tbeatic_irq_mask_ack[(MAX_IRQS+255)/64]; @@ -65,30 +65,30 @@ static void beatic_mask_irq(unsigned int { unsigned long flags; - spin_lock_irqsave(beatic_irq_mask_lock, flags); + raw_spin_lock_irqsave(beatic_irq_mask_lock, flags); beatic_irq_mask_enable[irq_plug/64] = ~(1UL (63 - (irq_plug%64))); beatic_update_irq_mask(irq_plug); - spin_unlock_irqrestore(beatic_irq_mask_lock, flags); + raw_spin_unlock_irqrestore(beatic_irq_mask_lock, flags); } static void beatic_unmask_irq(unsigned int irq_plug) { unsigned long flags; - spin_lock_irqsave(beatic_irq_mask_lock, flags); + raw_spin_lock_irqsave(beatic_irq_mask_lock, flags); beatic_irq_mask_enable[irq_plug/64] |= 1UL (63 - (irq_plug%64)); beatic_update_irq_mask(irq_plug); - spin_unlock_irqrestore(beatic_irq_mask_lock, flags); + raw_spin_unlock_irqrestore(beatic_irq_mask_lock, flags); } static void beatic_ack_irq(unsigned int irq_plug) { unsigned long flags; - spin_lock_irqsave(beatic_irq_mask_lock, flags); + raw_spin_lock_irqsave(beatic_irq_mask_lock, flags); beatic_irq_mask_ack[irq_plug/64] = ~(1UL (63 - (irq_plug%64))); beatic_update_irq_mask(irq_plug); - spin_unlock_irqrestore(beatic_irq_mask_lock, flags); + raw_spin_unlock_irqrestore(beatic_irq_mask_lock, flags); } static void beatic_end_irq(unsigned int irq_plug) @@ -103,10 +103,10 @@ static void beatic_end_irq(unsigned int printk(KERN_ERR IRQ over-downcounted, plug %d\n, irq_plug); } - spin_lock_irqsave(beatic_irq_mask_lock, flags); + raw_spin_lock_irqsave(beatic_irq_mask_lock, flags); beatic_irq_mask_ack[irq_plug/64] |= 1UL (63 - (irq_plug%64)); beatic_update_irq_mask(irq_plug); - spin_unlock_irqrestore(beatic_irq_mask_lock, flags); + raw_spin_unlock_irqrestore(beatic_irq_mask_lock, flags); } static struct irq_chip beatic_pic = { ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[patch 12/15] powerpc: Convert confirm_error_lock to raw_spinlock
confirm_error_lock needs to be a real spinlock in RT. Convert it to raw_spinlock. Signed-off-by: Thomas Gleixner t...@linutronix.de --- arch/powerpc/platforms/pseries/eeh.c | 14 +++--- 1 file changed, 7 insertions(+), 7 deletions(-) Index: linux-2.6-tip/arch/powerpc/platforms/pseries/eeh.c === --- linux-2.6-tip.orig/arch/powerpc/platforms/pseries/eeh.c +++ linux-2.6-tip/arch/powerpc/platforms/pseries/eeh.c @@ -100,7 +100,7 @@ int eeh_subsystem_enabled; EXPORT_SYMBOL(eeh_subsystem_enabled); /* Lock to avoid races due to multiple reports of an error */ -static DEFINE_SPINLOCK(confirm_error_lock); +static DEFINE_RAW_SPINLOCK(confirm_error_lock); /* Buffer for reporting slot-error-detail rtas calls. Its here * in BSS, and not dynamically alloced, so that it ends up in @@ -436,7 +436,7 @@ static void __eeh_clear_slot(struct devi void eeh_clear_slot (struct device_node *dn, int mode_flag) { unsigned long flags; - spin_lock_irqsave(confirm_error_lock, flags); + raw_spin_lock_irqsave(confirm_error_lock, flags); dn = find_device_pe (dn); @@ -447,7 +447,7 @@ void eeh_clear_slot (struct device_node PCI_DN(dn)-eeh_mode = ~mode_flag; PCI_DN(dn)-eeh_check_count = 0; __eeh_clear_slot(dn, mode_flag); - spin_unlock_irqrestore(confirm_error_lock, flags); + raw_spin_unlock_irqrestore(confirm_error_lock, flags); } /** @@ -506,7 +506,7 @@ int eeh_dn_check_failure(struct device_n * in one slot might report errors simultaneously, and we * only want one error recovery routine running. */ - spin_lock_irqsave(confirm_error_lock, flags); + raw_spin_lock_irqsave(confirm_error_lock, flags); rc = 1; if (pdn-eeh_mode EEH_MODE_ISOLATED) { pdn-eeh_check_count ++; @@ -575,7 +575,7 @@ int eeh_dn_check_failure(struct device_n * with other functions on this device, and functions under * bridges. */ eeh_mark_slot (dn, EEH_MODE_ISOLATED); - spin_unlock_irqrestore(confirm_error_lock, flags); + raw_spin_unlock_irqrestore(confirm_error_lock, flags); eeh_send_failure_event (dn, dev); @@ -586,7 +586,7 @@ int eeh_dn_check_failure(struct device_n return 1; dn_unlock: - spin_unlock_irqrestore(confirm_error_lock, flags); + raw_spin_unlock_irqrestore(confirm_error_lock, flags); return rc; } @@ -1064,7 +1064,7 @@ void __init eeh_init(void) struct device_node *phb, *np; struct eeh_early_enable_info info; - spin_lock_init(confirm_error_lock); + raw_spin_lock_init(confirm_error_lock); spin_lock_init(slot_errbuf_lock); np = of_find_node_by_path(/rtas); ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[patch 14/15] powerpc: Convert ipic_lock to raw_spinlock
ipic_lock needs to be a real spinlock in RT. Convert it to raw_spinlock. Signed-off-by: Thomas Gleixner t...@linutronix.de --- arch/powerpc/sysdev/ipic.c | 18 +- 1 file changed, 9 insertions(+), 9 deletions(-) Index: linux-2.6-tip/arch/powerpc/sysdev/ipic.c === --- linux-2.6-tip.orig/arch/powerpc/sysdev/ipic.c +++ linux-2.6-tip/arch/powerpc/sysdev/ipic.c @@ -32,7 +32,7 @@ static struct ipic * primary_ipic; static struct irq_chip ipic_level_irq_chip, ipic_edge_irq_chip; -static DEFINE_SPINLOCK(ipic_lock); +static DEFINE_RAW_SPINLOCK(ipic_lock); static struct ipic_info ipic_info[] = { [1] = { @@ -530,13 +530,13 @@ static void ipic_unmask_irq(unsigned int unsigned long flags; u32 temp; - spin_lock_irqsave(ipic_lock, flags); + raw_spin_lock_irqsave(ipic_lock, flags); temp = ipic_read(ipic-regs, ipic_info[src].mask); temp |= (1 (31 - ipic_info[src].bit)); ipic_write(ipic-regs, ipic_info[src].mask, temp); - spin_unlock_irqrestore(ipic_lock, flags); + raw_spin_unlock_irqrestore(ipic_lock, flags); } static void ipic_mask_irq(unsigned int virq) @@ -546,7 +546,7 @@ static void ipic_mask_irq(unsigned int v unsigned long flags; u32 temp; - spin_lock_irqsave(ipic_lock, flags); + raw_spin_lock_irqsave(ipic_lock, flags); temp = ipic_read(ipic-regs, ipic_info[src].mask); temp = ~(1 (31 - ipic_info[src].bit)); @@ -556,7 +556,7 @@ static void ipic_mask_irq(unsigned int v * for nearly all cases. */ mb(); - spin_unlock_irqrestore(ipic_lock, flags); + raw_spin_unlock_irqrestore(ipic_lock, flags); } static void ipic_ack_irq(unsigned int virq) @@ -566,7 +566,7 @@ static void ipic_ack_irq(unsigned int vi unsigned long flags; u32 temp; - spin_lock_irqsave(ipic_lock, flags); + raw_spin_lock_irqsave(ipic_lock, flags); temp = 1 (31 - ipic_info[src].bit); ipic_write(ipic-regs, ipic_info[src].ack, temp); @@ -575,7 +575,7 @@ static void ipic_ack_irq(unsigned int vi * for nearly all cases. */ mb(); - spin_unlock_irqrestore(ipic_lock, flags); + raw_spin_unlock_irqrestore(ipic_lock, flags); } static void ipic_mask_irq_and_ack(unsigned int virq) @@ -585,7 +585,7 @@ static void ipic_mask_irq_and_ack(unsign unsigned long flags; u32 temp; - spin_lock_irqsave(ipic_lock, flags); + raw_spin_lock_irqsave(ipic_lock, flags); temp = ipic_read(ipic-regs, ipic_info[src].mask); temp = ~(1 (31 - ipic_info[src].bit)); @@ -598,7 +598,7 @@ static void ipic_mask_irq_and_ack(unsign * for nearly all cases. */ mb(); - spin_unlock_irqrestore(ipic_lock, flags); + raw_spin_unlock_irqrestore(ipic_lock, flags); } static int ipic_set_irq_type(unsigned int virq, unsigned int flow_type) ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[patch 13/15] powerpc: Convert i8259_lock to raw_spinlock
i8259_lock needs to be a real spinlock in RT. Convert it to raw_spinlock. Signed-off-by: Thomas Gleixner t...@linutronix.de --- arch/powerpc/sysdev/i8259.c | 22 +++--- 1 file changed, 11 insertions(+), 11 deletions(-) Index: linux-2.6-tip/arch/powerpc/sysdev/i8259.c === --- linux-2.6-tip.orig/arch/powerpc/sysdev/i8259.c +++ linux-2.6-tip/arch/powerpc/sysdev/i8259.c @@ -23,7 +23,7 @@ static unsigned char cached_8259[2] = { #define cached_A1 (cached_8259[0]) #define cached_21 (cached_8259[1]) -static DEFINE_SPINLOCK(i8259_lock); +static DEFINE_RAW_SPINLOCK(i8259_lock); static struct irq_host *i8259_host; @@ -42,7 +42,7 @@ unsigned int i8259_irq(void) if (pci_intack) irq = readb(pci_intack); else { - spin_lock(i8259_lock); + raw_spin_lock(i8259_lock); lock = 1; /* Perform an interrupt acknowledge cycle on controller 1. */ @@ -74,7 +74,7 @@ unsigned int i8259_irq(void) irq = NO_IRQ; if (lock) - spin_unlock(i8259_lock); + raw_spin_unlock(i8259_lock); return irq; } @@ -82,7 +82,7 @@ static void i8259_mask_and_ack_irq(unsig { unsigned long flags; - spin_lock_irqsave(i8259_lock, flags); + raw_spin_lock_irqsave(i8259_lock, flags); if (irq_nr 7) { cached_A1 |= 1 (irq_nr-8); inb(0xA1); /* DUMMY */ @@ -95,7 +95,7 @@ static void i8259_mask_and_ack_irq(unsig outb(cached_21, 0x21); outb(0x20, 0x20); /* Non-specific EOI */ } - spin_unlock_irqrestore(i8259_lock, flags); + raw_spin_unlock_irqrestore(i8259_lock, flags); } static void i8259_set_irq_mask(int irq_nr) @@ -110,13 +110,13 @@ static void i8259_mask_irq(unsigned int pr_debug(i8259_mask_irq(%d)\n, irq_nr); - spin_lock_irqsave(i8259_lock, flags); + raw_spin_lock_irqsave(i8259_lock, flags); if (irq_nr 8) cached_21 |= 1 irq_nr; else cached_A1 |= 1 (irq_nr-8); i8259_set_irq_mask(irq_nr); - spin_unlock_irqrestore(i8259_lock, flags); + raw_spin_unlock_irqrestore(i8259_lock, flags); } static void i8259_unmask_irq(unsigned int irq_nr) @@ -125,13 +125,13 @@ static void i8259_unmask_irq(unsigned in pr_debug(i8259_unmask_irq(%d)\n, irq_nr); - spin_lock_irqsave(i8259_lock, flags); + raw_spin_lock_irqsave(i8259_lock, flags); if (irq_nr 8) cached_21 = ~(1 irq_nr); else cached_A1 = ~(1 (irq_nr-8)); i8259_set_irq_mask(irq_nr); - spin_unlock_irqrestore(i8259_lock, flags); + raw_spin_unlock_irqrestore(i8259_lock, flags); } static struct irq_chip i8259_pic = { @@ -241,7 +241,7 @@ void i8259_init(struct device_node *node unsigned long flags; /* initialize the controller */ - spin_lock_irqsave(i8259_lock, flags); + raw_spin_lock_irqsave(i8259_lock, flags); /* Mask all first */ outb(0xff, 0xA1); @@ -273,7 +273,7 @@ void i8259_init(struct device_node *node outb(cached_A1, 0xA1); outb(cached_21, 0x21); - spin_unlock_irqrestore(i8259_lock, flags); + raw_spin_unlock_irqrestore(i8259_lock, flags); /* create a legacy host */ i8259_host = irq_alloc_host(node, IRQ_HOST_MAP_LEGACY, ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[patch 07/15] powerpc: Convert beat_htab_lock to raw_spinlock
beat_htab_lock needs to be a real spinlock in RT. Convert it to raw_spinlock. Signed-off-by: Thomas Gleixner t...@linutronix.de --- arch/powerpc/platforms/cell/beat_htab.c | 24 1 file changed, 12 insertions(+), 12 deletions(-) Index: linux-2.6-tip/arch/powerpc/platforms/cell/beat_htab.c === --- linux-2.6-tip.orig/arch/powerpc/platforms/cell/beat_htab.c +++ linux-2.6-tip/arch/powerpc/platforms/cell/beat_htab.c @@ -40,7 +40,7 @@ #define DBG_LOW(fmt...) do { } while (0) #endif -static DEFINE_SPINLOCK(beat_htab_lock); +static DEFINE_RAW_SPINLOCK(beat_htab_lock); static inline unsigned int beat_read_mask(unsigned hpte_group) { @@ -114,18 +114,18 @@ static long beat_lpar_hpte_insert(unsign if (rflags _PAGE_NO_CACHE) hpte_r = ~_PAGE_COHERENT; - spin_lock(beat_htab_lock); + raw_spin_lock(beat_htab_lock); lpar_rc = beat_read_mask(hpte_group); if (lpar_rc == 0) { if (!(vflags HPTE_V_BOLTED)) DBG_LOW( full\n); - spin_unlock(beat_htab_lock); + raw_spin_unlock(beat_htab_lock); return -1; } lpar_rc = beat_insert_htab_entry(0, hpte_group, lpar_rc 48, hpte_v, hpte_r, slot); - spin_unlock(beat_htab_lock); + raw_spin_unlock(beat_htab_lock); /* * Since we try and ioremap PHBs we don't own, the pte insert @@ -198,17 +198,17 @@ static long beat_lpar_hpte_updatepp(unsi avpnv=%016lx, slot=%016lx, psize: %d, newpp %016lx ... , want_v HPTE_V_AVPN, slot, psize, newpp); - spin_lock(beat_htab_lock); + raw_spin_lock(beat_htab_lock); dummy0 = beat_lpar_hpte_getword0(slot); if ((dummy0 ~0x7FUL) != (want_v ~0x7FUL)) { DBG_LOW(not found !\n); - spin_unlock(beat_htab_lock); + raw_spin_unlock(beat_htab_lock); return -1; } lpar_rc = beat_write_htab_entry(0, slot, 0, newpp, 0, 7, dummy0, dummy1); - spin_unlock(beat_htab_lock); + raw_spin_unlock(beat_htab_lock); if (lpar_rc != 0 || dummy0 == 0) { DBG_LOW(not found !\n); return -1; @@ -262,13 +262,13 @@ static void beat_lpar_hpte_updateboltedp vsid = get_kernel_vsid(ea, MMU_SEGSIZE_256M); va = (vsid 28) | (ea 0x0fff); - spin_lock(beat_htab_lock); + raw_spin_lock(beat_htab_lock); slot = beat_lpar_hpte_find(va, psize); BUG_ON(slot == -1); lpar_rc = beat_write_htab_entry(0, slot, 0, newpp, 0, 7, dummy0, dummy1); - spin_unlock(beat_htab_lock); + raw_spin_unlock(beat_htab_lock); BUG_ON(lpar_rc != 0); } @@ -285,18 +285,18 @@ static void beat_lpar_hpte_invalidate(un slot, va, psize, local); want_v = hpte_encode_v(va, psize, MMU_SEGSIZE_256M); - spin_lock_irqsave(beat_htab_lock, flags); + raw_spin_lock_irqsave(beat_htab_lock, flags); dummy1 = beat_lpar_hpte_getword0(slot); if ((dummy1 ~0x7FUL) != (want_v ~0x7FUL)) { DBG_LOW(not found !\n); - spin_unlock_irqrestore(beat_htab_lock, flags); + raw_spin_unlock_irqrestore(beat_htab_lock, flags); return; } lpar_rc = beat_write_htab_entry(0, slot, 0, 0, HPTE_V_VALID, 0, dummy1, dummy2); - spin_unlock_irqrestore(beat_htab_lock, flags); + raw_spin_unlock_irqrestore(beat_htab_lock, flags); BUG_ON(lpar_rc != 0); } ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[patch 01/15] powerpc: Convert big_irq_lock to raw_spinlock
big_irq_lock needs to be a real spinlock in RT. Convert it to raw_spinlock. Signed-off-by: Thomas Gleixner t...@linutronix.de --- arch/powerpc/kernel/irq.c | 22 +++--- 1 file changed, 11 insertions(+), 11 deletions(-) Index: linux-2.6-tip/arch/powerpc/kernel/irq.c === --- linux-2.6-tip.orig/arch/powerpc/kernel/irq.c +++ linux-2.6-tip/arch/powerpc/kernel/irq.c @@ -474,7 +474,7 @@ void do_softirq(void) */ static LIST_HEAD(irq_hosts); -static DEFINE_SPINLOCK(irq_big_lock); +static DEFINE_RAW_SPINLOCK(irq_big_lock); static unsigned int revmap_trees_allocated; static DEFINE_MUTEX(revmap_trees_mutex); struct irq_map_entry irq_map[NR_IRQS]; @@ -520,14 +520,14 @@ struct irq_host *irq_alloc_host(struct d if (host-ops-match == NULL) host-ops-match = default_irq_host_match; - spin_lock_irqsave(irq_big_lock, flags); + raw_spin_lock_irqsave(irq_big_lock, flags); /* If it's a legacy controller, check for duplicates and * mark it as allocated (we use irq 0 host pointer for that */ if (revmap_type == IRQ_HOST_MAP_LEGACY) { if (irq_map[0].host != NULL) { - spin_unlock_irqrestore(irq_big_lock, flags); + raw_spin_unlock_irqrestore(irq_big_lock, flags); /* If we are early boot, we can't free the structure, * too bad... * this will be fixed once slab is made available early @@ -541,7 +541,7 @@ struct irq_host *irq_alloc_host(struct d } list_add(host-link, irq_hosts); - spin_unlock_irqrestore(irq_big_lock, flags); + raw_spin_unlock_irqrestore(irq_big_lock, flags); /* Additional setups per revmap type */ switch(revmap_type) { @@ -592,13 +592,13 @@ struct irq_host *irq_find_host(struct de * the absence of a device node. This isn't a problem so far * yet though... */ - spin_lock_irqsave(irq_big_lock, flags); + raw_spin_lock_irqsave(irq_big_lock, flags); list_for_each_entry(h, irq_hosts, link) if (h-ops-match(h, node)) { found = h; break; } - spin_unlock_irqrestore(irq_big_lock, flags); + raw_spin_unlock_irqrestore(irq_big_lock, flags); return found; } EXPORT_SYMBOL_GPL(irq_find_host); @@ -967,7 +967,7 @@ unsigned int irq_alloc_virt(struct irq_h if (count == 0 || count (irq_virq_count - NUM_ISA_INTERRUPTS)) return NO_IRQ; - spin_lock_irqsave(irq_big_lock, flags); + raw_spin_lock_irqsave(irq_big_lock, flags); /* Use hint for 1 interrupt if any */ if (count == 1 hint = NUM_ISA_INTERRUPTS @@ -991,7 +991,7 @@ unsigned int irq_alloc_virt(struct irq_h } } if (found == NO_IRQ) { - spin_unlock_irqrestore(irq_big_lock, flags); + raw_spin_unlock_irqrestore(irq_big_lock, flags); return NO_IRQ; } hint_found: @@ -1000,7 +1000,7 @@ unsigned int irq_alloc_virt(struct irq_h smp_wmb(); irq_map[i].host = host; } - spin_unlock_irqrestore(irq_big_lock, flags); + raw_spin_unlock_irqrestore(irq_big_lock, flags); return found; } @@ -1012,7 +1012,7 @@ void irq_free_virt(unsigned int virq, un WARN_ON (virq NUM_ISA_INTERRUPTS); WARN_ON (count == 0 || (virq + count) irq_virq_count); - spin_lock_irqsave(irq_big_lock, flags); + raw_spin_lock_irqsave(irq_big_lock, flags); for (i = virq; i (virq + count); i++) { struct irq_host *host; @@ -1025,7 +1025,7 @@ void irq_free_virt(unsigned int virq, un smp_wmb(); irq_map[i].host = NULL; } - spin_unlock_irqrestore(irq_big_lock, flags); + raw_spin_unlock_irqrestore(irq_big_lock, flags); } int arch_early_irq_init(void) ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[patch 09/15] powerpc: Convert feature_lock to raw_spinlock
feature_lock needs to be a real spinlock in RT. Convert it to raw_spinlock. Signed-off-by: Thomas Gleixner t...@linutronix.de --- arch/powerpc/include/asm/pmac_feature.h |2 +- arch/powerpc/platforms/powermac/feature.c|6 +++--- arch/powerpc/platforms/powermac/pfunc_base.c | 24 3 files changed, 16 insertions(+), 16 deletions(-) Index: linux-2.6-tip/arch/powerpc/include/asm/pmac_feature.h === --- linux-2.6-tip.orig/arch/powerpc/include/asm/pmac_feature.h +++ linux-2.6-tip/arch/powerpc/include/asm/pmac_feature.h @@ -378,7 +378,7 @@ extern struct macio_chip* macio_find(str * Those are exported by pmac feature for internal use by arch code * only like the platform function callbacks, do not use directly in drivers */ -extern spinlock_t feature_lock; +extern raw_spinlock_t feature_lock; extern struct device_node *uninorth_node; extern u32 __iomem *uninorth_base; Index: linux-2.6-tip/arch/powerpc/platforms/powermac/feature.c === --- linux-2.6-tip.orig/arch/powerpc/platforms/powermac/feature.c +++ linux-2.6-tip/arch/powerpc/platforms/powermac/feature.c @@ -59,10 +59,10 @@ extern struct device_node *k2_skiplist[2 * We use a single global lock to protect accesses. Each driver has * to take care of its own locking */ -DEFINE_SPINLOCK(feature_lock); +DEFINE_RAW_SPINLOCK(feature_lock); -#define LOCK(flags)spin_lock_irqsave(feature_lock, flags); -#define UNLOCK(flags) spin_unlock_irqrestore(feature_lock, flags); +#define LOCK(flags)raw_spin_lock_irqsave(feature_lock, flags); +#define UNLOCK(flags) raw_spin_unlock_irqrestore(feature_lock, flags); /* Index: linux-2.6-tip/arch/powerpc/platforms/powermac/pfunc_base.c === --- linux-2.6-tip.orig/arch/powerpc/platforms/powermac/pfunc_base.c +++ linux-2.6-tip/arch/powerpc/platforms/powermac/pfunc_base.c @@ -50,13 +50,13 @@ static int macio_do_gpio_write(PMF_STD_A value = ~value; /* Toggle the GPIO */ - spin_lock_irqsave(feature_lock, flags); + raw_spin_lock_irqsave(feature_lock, flags); tmp = readb(addr); tmp = (tmp ~mask) | (value mask); DBG(Do write 0x%02x to GPIO %s (%p)\n, tmp, func-node-full_name, addr); writeb(tmp, addr); - spin_unlock_irqrestore(feature_lock, flags); + raw_spin_unlock_irqrestore(feature_lock, flags); return 0; } @@ -145,9 +145,9 @@ static int macio_do_write_reg32(PMF_STD_ struct macio_chip *macio = func-driver_data; unsigned long flags; - spin_lock_irqsave(feature_lock, flags); + raw_spin_lock_irqsave(feature_lock, flags); MACIO_OUT32(offset, (MACIO_IN32(offset) ~mask) | (value mask)); - spin_unlock_irqrestore(feature_lock, flags); + raw_spin_unlock_irqrestore(feature_lock, flags); return 0; } @@ -168,9 +168,9 @@ static int macio_do_write_reg8(PMF_STD_A struct macio_chip *macio = func-driver_data; unsigned long flags; - spin_lock_irqsave(feature_lock, flags); + raw_spin_lock_irqsave(feature_lock, flags); MACIO_OUT8(offset, (MACIO_IN8(offset) ~mask) | (value mask)); - spin_unlock_irqrestore(feature_lock, flags); + raw_spin_unlock_irqrestore(feature_lock, flags); return 0; } @@ -223,12 +223,12 @@ static int macio_do_write_reg32_slm(PMF_ if (args == NULL || args-count == 0) return -EINVAL; - spin_lock_irqsave(feature_lock, flags); + raw_spin_lock_irqsave(feature_lock, flags); tmp = MACIO_IN32(offset); val = args-u[0].v shift; tmp = (tmp ~mask) | (val mask); MACIO_OUT32(offset, tmp); - spin_unlock_irqrestore(feature_lock, flags); + raw_spin_unlock_irqrestore(feature_lock, flags); return 0; } @@ -243,12 +243,12 @@ static int macio_do_write_reg8_slm(PMF_S if (args == NULL || args-count == 0) return -EINVAL; - spin_lock_irqsave(feature_lock, flags); + raw_spin_lock_irqsave(feature_lock, flags); tmp = MACIO_IN8(offset); val = args-u[0].v shift; tmp = (tmp ~mask) | (val mask); MACIO_OUT8(offset, tmp); - spin_unlock_irqrestore(feature_lock, flags); + raw_spin_unlock_irqrestore(feature_lock, flags); return 0; } @@ -278,12 +278,12 @@ static int unin_do_write_reg32(PMF_STD_A { unsigned long flags; - spin_lock_irqsave(feature_lock, flags); + raw_spin_lock_irqsave(feature_lock, flags); /* This is fairly bogus in darwin, but it should work for our needs * implemeted that way: */ UN_OUT(offset, (UN_IN(offset) ~mask) | (value mask)); - spin_unlock_irqrestore(feature_lock, flags); +
[patch 11/15] powerpc: Convert pmac_pic_lock to raw_spinlock
pmac_pic_lock needs to be a real spinlock in RT. Convert it to raw_spinlock. Signed-off-by: Thomas Gleixner t...@linutronix.de --- arch/powerpc/platforms/powermac/pic.c | 38 +- 1 file changed, 19 insertions(+), 19 deletions(-) Index: linux-2.6-tip/arch/powerpc/platforms/powermac/pic.c === --- linux-2.6-tip.orig/arch/powerpc/platforms/powermac/pic.c +++ linux-2.6-tip/arch/powerpc/platforms/powermac/pic.c @@ -57,7 +57,7 @@ static int max_irqs; static int max_real_irqs; static u32 level_mask[4]; -static DEFINE_SPINLOCK(pmac_pic_lock); +static DEFINE_RAW_SPINLOCK(pmac_pic_lock); #define NR_MASK_WORDS ((NR_IRQS + 31) / 32) static unsigned long ppc_lost_interrupts[NR_MASK_WORDS]; @@ -85,7 +85,7 @@ static void pmac_mask_and_ack_irq(unsign int i = src 5; unsigned long flags; - spin_lock_irqsave(pmac_pic_lock, flags); + raw_spin_lock_irqsave(pmac_pic_lock, flags); __clear_bit(src, ppc_cached_irq_mask); if (__test_and_clear_bit(src, ppc_lost_interrupts)) atomic_dec(ppc_n_lost_interrupts); @@ -97,7 +97,7 @@ static void pmac_mask_and_ack_irq(unsign mb(); } while((in_le32(pmac_irq_hw[i]-enable) bit) != (ppc_cached_irq_mask[i] bit)); - spin_unlock_irqrestore(pmac_pic_lock, flags); + raw_spin_unlock_irqrestore(pmac_pic_lock, flags); } static void pmac_ack_irq(unsigned int virq) @@ -107,12 +107,12 @@ static void pmac_ack_irq(unsigned int vi int i = src 5; unsigned long flags; - spin_lock_irqsave(pmac_pic_lock, flags); + raw_spin_lock_irqsave(pmac_pic_lock, flags); if (__test_and_clear_bit(src, ppc_lost_interrupts)) atomic_dec(ppc_n_lost_interrupts); out_le32(pmac_irq_hw[i]-ack, bit); (void)in_le32(pmac_irq_hw[i]-ack); - spin_unlock_irqrestore(pmac_pic_lock, flags); + raw_spin_unlock_irqrestore(pmac_pic_lock, flags); } static void __pmac_set_irq_mask(unsigned int irq_nr, int nokicklost) @@ -152,12 +152,12 @@ static unsigned int pmac_startup_irq(uns unsigned long bit = 1UL (src 0x1f); int i = src 5; - spin_lock_irqsave(pmac_pic_lock, flags); + raw_spin_lock_irqsave(pmac_pic_lock, flags); if ((irq_to_desc(virq)-status IRQ_LEVEL) == 0) out_le32(pmac_irq_hw[i]-ack, bit); __set_bit(src, ppc_cached_irq_mask); __pmac_set_irq_mask(src, 0); - spin_unlock_irqrestore(pmac_pic_lock, flags); + raw_spin_unlock_irqrestore(pmac_pic_lock, flags); return 0; } @@ -167,10 +167,10 @@ static void pmac_mask_irq(unsigned int v unsigned long flags; unsigned int src = irq_map[virq].hwirq; - spin_lock_irqsave(pmac_pic_lock, flags); + raw_spin_lock_irqsave(pmac_pic_lock, flags); __clear_bit(src, ppc_cached_irq_mask); __pmac_set_irq_mask(src, 1); - spin_unlock_irqrestore(pmac_pic_lock, flags); + raw_spin_unlock_irqrestore(pmac_pic_lock, flags); } static void pmac_unmask_irq(unsigned int virq) @@ -178,19 +178,19 @@ static void pmac_unmask_irq(unsigned int unsigned long flags; unsigned int src = irq_map[virq].hwirq; - spin_lock_irqsave(pmac_pic_lock, flags); + raw_spin_lock_irqsave(pmac_pic_lock, flags); __set_bit(src, ppc_cached_irq_mask); __pmac_set_irq_mask(src, 0); - spin_unlock_irqrestore(pmac_pic_lock, flags); + raw_spin_unlock_irqrestore(pmac_pic_lock, flags); } static int pmac_retrigger(unsigned int virq) { unsigned long flags; - spin_lock_irqsave(pmac_pic_lock, flags); + raw_spin_lock_irqsave(pmac_pic_lock, flags); __pmac_retrigger(irq_map[virq].hwirq); - spin_unlock_irqrestore(pmac_pic_lock, flags); + raw_spin_unlock_irqrestore(pmac_pic_lock, flags); return 1; } @@ -210,7 +210,7 @@ static irqreturn_t gatwick_action(int cp int irq, bits; int rc = IRQ_NONE; - spin_lock_irqsave(pmac_pic_lock, flags); + raw_spin_lock_irqsave(pmac_pic_lock, flags); for (irq = max_irqs; (irq -= 32) = max_real_irqs; ) { int i = irq 5; bits = in_le32(pmac_irq_hw[i]-event) | ppc_lost_interrupts[i]; @@ -220,12 +220,12 @@ static irqreturn_t gatwick_action(int cp if (bits == 0) continue; irq += __ilog2(bits); - spin_unlock_irqrestore(pmac_pic_lock, flags); + raw_spin_unlock_irqrestore(pmac_pic_lock, flags); generic_handle_irq(irq); - spin_lock_irqsave(pmac_pic_lock, flags); + raw_spin_lock_irqsave(pmac_pic_lock, flags); rc = IRQ_HANDLED; } - spin_unlock_irqrestore(pmac_pic_lock, flags); + raw_spin_unlock_irqrestore(pmac_pic_lock, flags);
[patch 15/15] powerpc: Convert mpic locks to raw_spinlock
mpic_lock, irq_rover_lock and fixup_lock need to be real spinlocks in RT. Convert them to raw_spinlock. Signed-off-by: Thomas Gleixner t...@linutronix.de --- arch/powerpc/include/asm/mpic.h |2 +- arch/powerpc/sysdev/mpic.c | 38 +++--- 2 files changed, 20 insertions(+), 20 deletions(-) Index: linux-2.6-tip/arch/powerpc/include/asm/mpic.h === --- linux-2.6-tip.orig/arch/powerpc/include/asm/mpic.h +++ linux-2.6-tip/arch/powerpc/include/asm/mpic.h @@ -289,7 +289,7 @@ struct mpic #ifdef CONFIG_MPIC_U3_HT_IRQS /* The fixup table */ struct mpic_irq_fixup *fixups; - spinlock_t fixup_lock; + raw_spinlock_t fixup_lock; #endif /* Register access method */ Index: linux-2.6-tip/arch/powerpc/sysdev/mpic.c === --- linux-2.6-tip.orig/arch/powerpc/sysdev/mpic.c +++ linux-2.6-tip/arch/powerpc/sysdev/mpic.c @@ -46,7 +46,7 @@ static struct mpic *mpics; static struct mpic *mpic_primary; -static DEFINE_SPINLOCK(mpic_lock); +static DEFINE_RAW_SPINLOCK(mpic_lock); #ifdef CONFIG_PPC32/* XXX for now */ #ifdef CONFIG_IRQ_ALL_CPUS @@ -347,10 +347,10 @@ static inline void mpic_ht_end_irq(struc unsigned int mask = 1U (fixup-index 0x1f); writel(mask, fixup-applebase + soff); } else { - spin_lock(mpic-fixup_lock); + raw_spin_lock(mpic-fixup_lock); writeb(0x11 + 2 * fixup-index, fixup-base + 2); writel(fixup-data, fixup-base + 4); - spin_unlock(mpic-fixup_lock); + raw_spin_unlock(mpic-fixup_lock); } } @@ -366,7 +366,7 @@ static void mpic_startup_ht_interrupt(st DBG(startup_ht_interrupt(0x%x, 0x%x) index: %d\n, source, irqflags, fixup-index); - spin_lock_irqsave(mpic-fixup_lock, flags); + raw_spin_lock_irqsave(mpic-fixup_lock, flags); /* Enable and configure */ writeb(0x10 + 2 * fixup-index, fixup-base + 2); tmp = readl(fixup-base + 4); @@ -374,7 +374,7 @@ static void mpic_startup_ht_interrupt(st if (irqflags IRQ_LEVEL) tmp |= 0x22; writel(tmp, fixup-base + 4); - spin_unlock_irqrestore(mpic-fixup_lock, flags); + raw_spin_unlock_irqrestore(mpic-fixup_lock, flags); #ifdef CONFIG_PM /* use the lowest bit inverted to the actual HW, @@ -396,12 +396,12 @@ static void mpic_shutdown_ht_interrupt(s DBG(shutdown_ht_interrupt(0x%x, 0x%x)\n, source, irqflags); /* Disable */ - spin_lock_irqsave(mpic-fixup_lock, flags); + raw_spin_lock_irqsave(mpic-fixup_lock, flags); writeb(0x10 + 2 * fixup-index, fixup-base + 2); tmp = readl(fixup-base + 4); tmp |= 1; writel(tmp, fixup-base + 4); - spin_unlock_irqrestore(mpic-fixup_lock, flags); + raw_spin_unlock_irqrestore(mpic-fixup_lock, flags); #ifdef CONFIG_PM /* use the lowest bit inverted to the actual HW, @@ -515,7 +515,7 @@ static void __init mpic_scan_ht_pics(str BUG_ON(mpic-fixups == NULL); /* Init spinlock */ - spin_lock_init(mpic-fixup_lock); + raw_spin_lock_init(mpic-fixup_lock); /* Map U3 config space. We assume all IO-APICs are on the primary bus * so we only need to map 64kB. @@ -573,12 +573,12 @@ static int irq_choose_cpu(const cpumask_ if (cpumask_equal(mask, cpu_all_mask)) { static int irq_rover; - static DEFINE_SPINLOCK(irq_rover_lock); + static DEFINE_RAW_SPINLOCK(irq_rover_lock); unsigned long flags; /* Round-robin distribution... */ do_round_robin: - spin_lock_irqsave(irq_rover_lock, flags); + raw_spin_lock_irqsave(irq_rover_lock, flags); while (!cpu_online(irq_rover)) { if (++irq_rover = NR_CPUS) @@ -590,7 +590,7 @@ static int irq_choose_cpu(const cpumask_ irq_rover = 0; } while (!cpu_online(irq_rover)); - spin_unlock_irqrestore(irq_rover_lock, flags); + raw_spin_unlock_irqrestore(irq_rover_lock, flags); } else { cpuid = cpumask_first_and(mask, cpu_online_mask); if (cpuid = nr_cpu_ids) @@ -1368,14 +1368,14 @@ void __init mpic_set_serial_int(struct m unsigned long flags; u32 v; - spin_lock_irqsave(mpic_lock, flags); + raw_spin_lock_irqsave(mpic_lock, flags); v = mpic_read(mpic-gregs, MPIC_GREG_GLOBAL_CONF_1); if (enable) v |= MPIC_GREG_GLOBAL_CONF_1_SIE; else v = ~MPIC_GREG_GLOBAL_CONF_1_SIE; mpic_write(mpic-gregs, MPIC_GREG_GLOBAL_CONF_1, v); - spin_unlock_irqrestore(mpic_lock, flags); +
Re: [Patch v2 1/2] 5200/mpc: improve i2c bus error recovery
Albrecht Dreß albrecht.dr...@arcor.de wrote on 2010/02/18 10:09:23: Hi Joakim: Does this reset sequence also send a START condition for every clock? Please see the attached scan from a scope output, showing the first two out of the 9 sequences at 375 kHz (that's what the 5200's divider makes from 400 kHz requested). Resolution is 2us/div and 1V/div for both signals. The waveform itself for each of the 9 sequences is exactly the same we had before with the old solution, just the timing is faster and adjusted to the ii2c clock, i.e. the /relative/ waveforms look identical for slower clocks. Any insight if this is *really* correct would be great, as I'm not an i2c expert. I can only say it reliably fixes the bus hangs I saw! Looks like you do a STOP then START each time SCL is high so yes you do a START each SCL and a STOP too. Don't think the STOP will hurt though. Timing is OK for FAST-MODE(400kHz), cannot say for STANDARD-MODE though need a 100Khz scope img for that. The times to look for are: tHD;STA, tSU;STA, tSU;STO and tBUF at least that is what I have identified. Jocke ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Reading command line args from assmebly
Hi All, I have written one sample assmebly and c code which reads command line args and displays . find the source files as attachments. expected output is , $ ./a.out Inside __linker_init argc = 1 Inside __linker_init argv[0] = ./a.out Segmentation fault [Seg fault Never mind] if i statically link startx86.S linker.c on x86 AND statrt_ppc.S linker.c on PS3,i'll get SEGV fault on both system. But on PS3, inside '_start' function if i verify the contents of 'r1[stack pointer]' and '(Char *) *(r1 + 4)' in GDB i get '1' and '~/a.out' respectively .But once 'r1' moved to r3[holds the 1st arg of the function] passed as argument to __linker_init ,inside the function '*elfdata' points '1' but (char *) *(elfdata + 1) points to some junk string. some thing like this |c\033x|i\003�N\200\004 \224!��|\b\002�\220\001. find the GDB log file of PS3. if i link them without statically,i'll get the correct output on x86 .i.e $ ./a.out Inside __linker_init argc = 1 Inside __linker_init argv[0] = ./a.out Segmentation fault [Seg fault Never mind] but on ps3 i get this, $ ./a.out Inside __linker_init argc = 0 Inside __linker_init argv[0] = |c|i�N� �! Segmentation fault Why am i getting strange characters instead of './a.out' and y 'argc' having 'zero' ? Why is this two different outputs for static linking and dynamic linking ? -Anand This GDB was configured as powerpc-linux-gnu... (gdb) b _start Breakpoint 1 at 0x10e4: file start.S, line 35. (gdb) r Starting program: /home/dayananda/junks/power/a.out Breakpoint 1, _start () at start.S:37 37 bl __linker_init Current language: auto; currently asm (gdb) s __linker_init (elfdata=0x0) at linker.c:5 5{ Current language: auto; currently c (gdb) i r r0 0x0 0 r1 0xff9a1820 4288288800 r2 0x0 0 r3 0xff9a1820 4288288800 r4 0x0 0 r5 0x0 0 r6 0x0 0 r7 0x0 0 r8 0x0 0 r9 0x0 0 r100x0 0 r110x0 0 r120x0 0 r130x0 0 r140x0 0 r150x0 0 r160x0 0 r170x0 0 r180x0 0 r190x0 0 r200x0 0 r210x0 0 r220x0 0 r230x0 0 r240x0 0 r250x0 0 r260x0 0 r270x0 0 r280x0 0 r290x0 0 r300x0 0 r310x0 0 pc 0x10f4 268435700 msr0x4010c032 1074839602 cr 0x0 0 lr 0x10e8 268435688 ctr0x0 0 xer0x0 0 (gdb) p *(0xff9a1820) $1 = 1 (gdb) p *(0xff9a1820+4) $2 = -6678169 (gdb) p (char *)*(0xff9a1820+4) $3 = 0xff9a1967 /home/dayananda/junks/power/a.out (gdb) s 7 int argc = (int) *elfdata; (gdb) s 8 char **argv = (char**) (elfdata + 1); (gdb) p elfdata $4 = (unsigned int **) 0xff9a1820 (gdb) p *elfdata $5 = (unsigned int *) 0x1 (gdb) p *(elfdata + 1) $6 = (unsigned int *) 0x10e8 (gdb) p (char *)*(elfdata + 1) $7 = 0x10e8 |c\033x|i\003�N\200\004 \224!��|\b\002�\220\001 linker.c Description: Binary data start_ppc.S Description: Binary data start_x86.S Description: Binary data ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [patch 00/15] powerpc: raw_spinlock conversions
On Thu, 18 Feb 2010, Thomas Gleixner wrote: the following patch series is from preempt-rt. It converts the locks which need to be real spinlocks in -rt to raw_spinlocks. None of the patch descriptions mention why the locks need to be real spinlocks in -rt. So can you please elaborate? With kind regards, Geert Uytterhoeven Software Architect Techsoft Centre Technology and Software Centre Europe The Corporate Village · Da Vincilaan 7-D1 · B-1935 Zaventem · Belgium Phone:+32 (0)2 700 8453 Fax: +32 (0)2 700 8622 E-mail: geert.uytterhoe...@sonycom.com Internet: http://www.sony-europe.com/ A division of Sony Europe (Belgium) N.V. VAT BE 0413.825.160 · RPR Brussels Fortis · BIC GEBABEBB · IBAN BE41293037680010 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: State of PREEMPT_RT in PPC arch
I'm soliciting comments from the community. Thanks in advance for sharing your thoughts. Mainline your driver and you are free from such problems :) -- Pengutronix e.K. | Wolfram Sang| Industrial Linux Solutions | http://www.pengutronix.de/ | signature.asc Description: Digital signature ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCHv4 2/2] powerpc: implement arch_scale_smt_power for Power7
On Thu, 2010-02-18 at 09:20 +1100, Michael Neuling wrote: Suppose for a moment we have 2 threads (hot-unplugged thread 1 and 3, we can construct an equivalent but more complex example for 4 threads), and we have 4 tasks, 3 SCHED_OTHER of equal nice level and 1 SCHED_FIFO, the SCHED_FIFO task will consume exactly 50% walltime of whatever cpu it ends up on. In that situation, provided that each cpu's cpu_power is of equal measure, scale_rt_power() ensures that we run 2 SCHED_OTHER tasks on the cpu that doesn't run the RT task, and 1 SCHED_OTHER task next to the RT task, so that each task consumes 50%, which is all fair and proper. However, if you do the above, thread 0 will have +75% = 1.75 and thread 2 will have -75% = 0.25, then if the RT task will land on thread 0, we'll be having: 0.875 vs 0.25, or on thread 3, 1.75 vs 0.125. In either case thread 0 will receive too many (if not all) SCHED_OTHER tasks. That is, unless these threads 2 and 3 really are _that_ weak, at which point one wonders why IBM bothered with the silicon ;-) Peter, 2 3 aren't weaker than 0 1 but The core has dynamic SMT mode switching which is controlled by the hypervisor (IBM's PHYP). There are 3 SMT modes: SMT1 uses thread 0 SMT2 uses threads 0 1 SMT4 uses threads 0, 1, 2 3 When in any particular SMT mode, all threads have the same performance as each other (ie. at any moment in time, all threads perform the same). The SMT mode switching works such that when linux has threads 2 3 idle and 0 1 active, it will cede (H_CEDE hypercall) threads 2 and 3 in the idle loop and the hypervisor will automatically switch to SMT2 for that core (independent of other cores). The opposite is not true, so if threads 0 1 are idle and 2 3 are active, we will stay in SMT4 mode. Similarly if thread 0 is active and threads 1, 2 3 are idle, we'll go into SMT1 mode. If we can get the core into a lower SMT mode (SMT1 is best), the threads will perform better (since they share less core resources). Hence when we have idle threads, we want them to be the higher ones. Just out of curiosity, is this a hardware constraint or a hypervisor constraint? So to answer your question, threads 2 and 3 aren't weaker than the other threads when in SMT4 mode. It's that if we idle threads 2 3, threads 0 1 will speed up since we'll move to SMT2 mode. I'm pretty vague on linux scheduler details, so I'm a bit at sea as to how to solve this. Can you suggest any mechanisms we currently have in the kernel to reflect these properties, or do you think we need to develop something new? If so, any pointers as to where we should look? Well there currently isn't one, and I've been telling people to create a new SD_flag to reflect this and influence the f_b_g() behaviour. Something like the below perhaps, totally untested and without comments so that you'll have to reverse engineer and validate my thinking. There's one fundamental assumption, and one weakness in the implementation. --- include/linux/sched.h |2 +- kernel/sched_fair.c | 61 +--- 2 files changed, 58 insertions(+), 5 deletions(-) diff --git a/include/linux/sched.h b/include/linux/sched.h index 0eef87b..42fa5c6 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -849,7 +849,7 @@ enum cpu_idle_type { #define SD_POWERSAVINGS_BALANCE0x0100 /* Balance for power savings */ #define SD_SHARE_PKG_RESOURCES 0x0200 /* Domain members share cpu pkg resources */ #define SD_SERIALIZE 0x0400 /* Only a single load balancing instance */ - +#define SD_ASYM_PACKING0x0800 #define SD_PREFER_SIBLING 0x1000 /* Prefer to place tasks in a sibling domain */ enum powersavings_balance_level { diff --git a/kernel/sched_fair.c b/kernel/sched_fair.c index ff7692c..7e42bfe 100644 --- a/kernel/sched_fair.c +++ b/kernel/sched_fair.c @@ -2086,6 +2086,7 @@ struct sd_lb_stats { struct sched_group *this; /* Local group in this sd */ unsigned long total_load; /* Total load of all groups in sd */ unsigned long total_pwr; /* Total power of all groups in sd */ + unsigned long total_nr_running; unsigned long avg_load;/* Average load across all groups in sd */ /** Statistics of this group */ @@ -2414,10 +2415,10 @@ static inline void update_sg_lb_stats(struct sched_domain *sd, int *balance, struct sg_lb_stats *sgs) { unsigned long load, max_cpu_load, min_cpu_load; - int i; unsigned int balance_cpu = -1, first_idle_cpu = 0; unsigned long sum_avg_load_per_task; unsigned long avg_load_per_task; + int i; if (local_group) balance_cpu = group_first_cpu(group); @@ -2493,6 +2494,28 @@ static inline void update_sg_lb_stats(struct sched_domain *sd,
Re: [PATCHv4 2/2] powerpc: implement arch_scale_smt_power for Power7
On Thu, 2010-02-18 at 14:17 +0100, Peter Zijlstra wrote: There's one fundamental assumption, and one weakness in the implementation. Aside from bugs and the like.. ;-) ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [Patch v2 1/2] 5200/mpc: improve i2c bus error recovery
@@ -93,20 +94,23 @@ static irqreturn_t mpc_i2c_isr(int irq, /* Sometimes 9th clock pulse isn't generated, and slave doesn't release * the bus, because it wants to send ACK. * Following sequence of enabling/disabling and sending start/stop generates - * the pulse, so it's all OK. + * the 9 pulses, so it's all OK. */ static void mpc_i2c_fixup(struct mpc_i2c *i2c) { - writeccr(i2c, 0); - udelay(30); - writeccr(i2c, CCR_MEN); - udelay(30); - writeccr(i2c, CCR_MSTA | CCR_MTX); - udelay(30); - writeccr(i2c, CCR_MSTA | CCR_MTX | CCR_MEN); - udelay(30); - writeccr(i2c, CCR_MEN); - udelay(30); + int k; + u32 delay_val = 100 / i2c-real_clk + 1; + + if (delay_val 2) + delay_val = 2; + + for (k = 9; k; k--) { + writeccr(i2c, 0); + writeccr(i2c, CCR_MSTA | CCR_MTX | CCR_MEN); + udelay(delay_val); + writeccr(i2c, CCR_MEN); + udelay(delay_val 1); + } } I am curious, didn't old method work with by just wrapping a for(k=9; k; k--) around it? How did the wave form look? Jocke ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH] powerpc/qe: Convert qe_ic_lock to raw_spinlock
Interrupt controllers' hooks are executed in the atomic context, so they are not permitted to sleep (with RT kernels non-raw spinlocks are sleepable). So, qe_ic_lock has to be a real (non-sleepable) spinlock. Signed-off-by: Anton Vorontsov avoront...@ru.mvista.com --- On Thu, Feb 18, 2010 at 12:22:18PM -, Thomas Gleixner wrote: Ben, the following patch series is from preempt-rt. It converts the locks which need to be real spinlocks in -rt to raw_spinlocks. There is no behaviourial change for !RT kernels because spinlocks and raw_spinlocks are the same on !RT. So for mainline this is a pure annotation while having it in mainline takes the burden of keeping up with the code changes from the RT patch set. Please consider to merge into .34. If nothing has changed in -rt, then qe_ic should be in the same boat. arch/powerpc/sysdev/qe_lib/qe_ic.c | 10 +- 1 files changed, 5 insertions(+), 5 deletions(-) diff --git a/arch/powerpc/sysdev/qe_lib/qe_ic.c b/arch/powerpc/sysdev/qe_lib/qe_ic.c index 2acc928..9c90a34 100644 --- a/arch/powerpc/sysdev/qe_lib/qe_ic.c +++ b/arch/powerpc/sysdev/qe_lib/qe_ic.c @@ -33,7 +33,7 @@ #include qe_ic.h -static DEFINE_SPINLOCK(qe_ic_lock); +static DEFINE_RAW_SPINLOCK(qe_ic_lock); static struct qe_ic_info qe_ic_info[] = { [1] = { @@ -201,13 +201,13 @@ static void qe_ic_unmask_irq(unsigned int virq) unsigned long flags; u32 temp; - spin_lock_irqsave(qe_ic_lock, flags); + raw_spin_lock_irqsave(qe_ic_lock, flags); temp = qe_ic_read(qe_ic-regs, qe_ic_info[src].mask_reg); qe_ic_write(qe_ic-regs, qe_ic_info[src].mask_reg, temp | qe_ic_info[src].mask); - spin_unlock_irqrestore(qe_ic_lock, flags); + raw_spin_unlock_irqrestore(qe_ic_lock, flags); } static void qe_ic_mask_irq(unsigned int virq) @@ -217,7 +217,7 @@ static void qe_ic_mask_irq(unsigned int virq) unsigned long flags; u32 temp; - spin_lock_irqsave(qe_ic_lock, flags); + raw_spin_lock_irqsave(qe_ic_lock, flags); temp = qe_ic_read(qe_ic-regs, qe_ic_info[src].mask_reg); qe_ic_write(qe_ic-regs, qe_ic_info[src].mask_reg, @@ -233,7 +233,7 @@ static void qe_ic_mask_irq(unsigned int virq) */ mb(); - spin_unlock_irqrestore(qe_ic_lock, flags); + raw_spin_unlock_irqrestore(qe_ic_lock, flags); } static struct irq_chip qe_ic_irq_chip = { -- 1.6.5.7 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH] powerpc/85xx: Convert socrates_fpga_pic_lock to raw_spinlock
Interrupt controllers' hooks are executed in the atomic context, so they are not permitted to sleep (with RT kernels non-raw spinlocks are sleepable). So, socrates_fpga_pic_lock has to be a real (non-sleepable) spinlock. Signed-off-by: Anton Vorontsov avoront...@ru.mvista.com --- On Thu, Feb 18, 2010 at 12:22:18PM -, Thomas Gleixner wrote: Ben, the following patch series is from preempt-rt. It converts the locks which need to be real spinlocks in -rt to raw_spinlocks. There is no behaviourial change for !RT kernels because spinlocks and raw_spinlocks are the same on !RT. So for mainline this is a pure annotation while having it in mainline takes the burden of keeping up with the code changes from the RT patch set. Please consider to merge into .34. Oh, and I guess the same for the socrates fpga pic... arch/powerpc/platforms/85xx/socrates_fpga_pic.c | 34 +++--- 1 files changed, 17 insertions(+), 17 deletions(-) diff --git a/arch/powerpc/platforms/85xx/socrates_fpga_pic.c b/arch/powerpc/platforms/85xx/socrates_fpga_pic.c index e5da5f6..678560a 100644 --- a/arch/powerpc/platforms/85xx/socrates_fpga_pic.c +++ b/arch/powerpc/platforms/85xx/socrates_fpga_pic.c @@ -50,7 +50,7 @@ static struct socrates_fpga_irq_info fpga_irqs[SOCRATES_FPGA_NUM_IRQS] = { #define socrates_fpga_irq_to_hw(virq)((unsigned int)irq_map[virq].hwirq) -static DEFINE_SPINLOCK(socrates_fpga_pic_lock); +static DEFINE_RAW_SPINLOCK(socrates_fpga_pic_lock); static void __iomem *socrates_fpga_pic_iobase; static struct irq_host *socrates_fpga_pic_irq_host; @@ -80,9 +80,9 @@ static inline unsigned int socrates_fpga_pic_get_irq(unsigned int irq) if (i == 3) return NO_IRQ; - spin_lock_irqsave(socrates_fpga_pic_lock, flags); + raw_spin_lock_irqsave(socrates_fpga_pic_lock, flags); cause = socrates_fpga_pic_read(FPGA_PIC_IRQMASK(i)); - spin_unlock_irqrestore(socrates_fpga_pic_lock, flags); + raw_spin_unlock_irqrestore(socrates_fpga_pic_lock, flags); for (i = SOCRATES_FPGA_NUM_IRQS - 1; i = 0; i--) { if (cause (i + 16)) break; @@ -116,12 +116,12 @@ static void socrates_fpga_pic_ack(unsigned int virq) hwirq = socrates_fpga_irq_to_hw(virq); irq_line = fpga_irqs[hwirq].irq_line; - spin_lock_irqsave(socrates_fpga_pic_lock, flags); + raw_spin_lock_irqsave(socrates_fpga_pic_lock, flags); mask = socrates_fpga_pic_read(FPGA_PIC_IRQMASK(irq_line)) SOCRATES_FPGA_IRQ_MASK; mask |= (1 (hwirq + 16)); socrates_fpga_pic_write(FPGA_PIC_IRQMASK(irq_line), mask); - spin_unlock_irqrestore(socrates_fpga_pic_lock, flags); + raw_spin_unlock_irqrestore(socrates_fpga_pic_lock, flags); } static void socrates_fpga_pic_mask(unsigned int virq) @@ -134,12 +134,12 @@ static void socrates_fpga_pic_mask(unsigned int virq) hwirq = socrates_fpga_irq_to_hw(virq); irq_line = fpga_irqs[hwirq].irq_line; - spin_lock_irqsave(socrates_fpga_pic_lock, flags); + raw_spin_lock_irqsave(socrates_fpga_pic_lock, flags); mask = socrates_fpga_pic_read(FPGA_PIC_IRQMASK(irq_line)) SOCRATES_FPGA_IRQ_MASK; mask = ~(1 hwirq); socrates_fpga_pic_write(FPGA_PIC_IRQMASK(irq_line), mask); - spin_unlock_irqrestore(socrates_fpga_pic_lock, flags); + raw_spin_unlock_irqrestore(socrates_fpga_pic_lock, flags); } static void socrates_fpga_pic_mask_ack(unsigned int virq) @@ -152,13 +152,13 @@ static void socrates_fpga_pic_mask_ack(unsigned int virq) hwirq = socrates_fpga_irq_to_hw(virq); irq_line = fpga_irqs[hwirq].irq_line; - spin_lock_irqsave(socrates_fpga_pic_lock, flags); + raw_spin_lock_irqsave(socrates_fpga_pic_lock, flags); mask = socrates_fpga_pic_read(FPGA_PIC_IRQMASK(irq_line)) SOCRATES_FPGA_IRQ_MASK; mask = ~(1 hwirq); mask |= (1 (hwirq + 16)); socrates_fpga_pic_write(FPGA_PIC_IRQMASK(irq_line), mask); - spin_unlock_irqrestore(socrates_fpga_pic_lock, flags); + raw_spin_unlock_irqrestore(socrates_fpga_pic_lock, flags); } static void socrates_fpga_pic_unmask(unsigned int virq) @@ -171,12 +171,12 @@ static void socrates_fpga_pic_unmask(unsigned int virq) hwirq = socrates_fpga_irq_to_hw(virq); irq_line = fpga_irqs[hwirq].irq_line; - spin_lock_irqsave(socrates_fpga_pic_lock, flags); + raw_spin_lock_irqsave(socrates_fpga_pic_lock, flags); mask = socrates_fpga_pic_read(FPGA_PIC_IRQMASK(irq_line)) SOCRATES_FPGA_IRQ_MASK; mask |= (1 hwirq); socrates_fpga_pic_write(FPGA_PIC_IRQMASK(irq_line), mask); - spin_unlock_irqrestore(socrates_fpga_pic_lock, flags); + raw_spin_unlock_irqrestore(socrates_fpga_pic_lock, flags); } static void socrates_fpga_pic_eoi(unsigned int virq) @@ -189,12 +189,12 @@ static void
[PATCH] powerpc/86xx: Convert gef_pic_lock to raw_spinlock
Interrupt controllers' hooks are executed in the atomic context, so they are not permitted to sleep (with RT kernels non-raw spinlocks are sleepable). So, gef_pic_lock has to be a real (non-sleepable) spinlock. Signed-off-by: Anton Vorontsov avoront...@ru.mvista.com --- arch/powerpc/platforms/86xx/gef_pic.c | 14 +++--- 1 files changed, 7 insertions(+), 7 deletions(-) diff --git a/arch/powerpc/platforms/86xx/gef_pic.c b/arch/powerpc/platforms/86xx/gef_pic.c index 0110a87..7ad9c0d 100644 --- a/arch/powerpc/platforms/86xx/gef_pic.c +++ b/arch/powerpc/platforms/86xx/gef_pic.c @@ -49,7 +49,7 @@ #define gef_irq_to_hw(virq)((unsigned int)irq_map[virq].hwirq) -static DEFINE_SPINLOCK(gef_pic_lock); +static DEFINE_RAW_SPINLOCK(gef_pic_lock); static void __iomem *gef_pic_irq_reg_base; static struct irq_host *gef_pic_irq_host; @@ -118,11 +118,11 @@ static void gef_pic_mask(unsigned int virq) hwirq = gef_irq_to_hw(virq); - spin_lock_irqsave(gef_pic_lock, flags); + raw_spin_lock_irqsave(gef_pic_lock, flags); mask = in_be32(gef_pic_irq_reg_base + GEF_PIC_INTR_MASK(0)); mask = ~(1 hwirq); out_be32(gef_pic_irq_reg_base + GEF_PIC_INTR_MASK(0), mask); - spin_unlock_irqrestore(gef_pic_lock, flags); + raw_spin_unlock_irqrestore(gef_pic_lock, flags); } static void gef_pic_mask_ack(unsigned int virq) @@ -141,11 +141,11 @@ static void gef_pic_unmask(unsigned int virq) hwirq = gef_irq_to_hw(virq); - spin_lock_irqsave(gef_pic_lock, flags); + raw_spin_lock_irqsave(gef_pic_lock, flags); mask = in_be32(gef_pic_irq_reg_base + GEF_PIC_INTR_MASK(0)); mask |= (1 hwirq); out_be32(gef_pic_irq_reg_base + GEF_PIC_INTR_MASK(0), mask); - spin_unlock_irqrestore(gef_pic_lock, flags); + raw_spin_unlock_irqrestore(gef_pic_lock, flags); } static struct irq_chip gef_pic_chip = { @@ -199,7 +199,7 @@ void __init gef_pic_init(struct device_node *np) /* Map the devices registers into memory */ gef_pic_irq_reg_base = of_iomap(np, 0); - spin_lock_irqsave(gef_pic_lock, flags); + raw_spin_lock_irqsave(gef_pic_lock, flags); /* Initialise everything as masked. */ out_be32(gef_pic_irq_reg_base + GEF_PIC_CPU0_INTR_MASK, 0); @@ -208,7 +208,7 @@ void __init gef_pic_init(struct device_node *np) out_be32(gef_pic_irq_reg_base + GEF_PIC_CPU0_MCP_MASK, 0); out_be32(gef_pic_irq_reg_base + GEF_PIC_CPU1_MCP_MASK, 0); - spin_unlock_irqrestore(gef_pic_lock, flags); + raw_spin_unlock_irqrestore(gef_pic_lock, flags); /* Map controller */ gef_pic_cascade_irq = irq_of_parse_and_map(np, 0); -- 1.6.5.7 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH] powerpc/82xx: Convert pci_pic_lock to raw_spinlock
Interrupt controllers' hooks are executed in the atomic context, so they are not permitted to sleep (with RT kernels non-raw spinlocks are sleepable). So, pci_pic_lock has to be a real (non-sleepable) spinlock. Signed-off-by: Anton Vorontsov avoront...@ru.mvista.com --- arch/powerpc/platforms/82xx/pq2ads-pci-pic.c | 10 +- 1 files changed, 5 insertions(+), 5 deletions(-) diff --git a/arch/powerpc/platforms/82xx/pq2ads-pci-pic.c b/arch/powerpc/platforms/82xx/pq2ads-pci-pic.c index 9d962d7..d4a09f8 100644 --- a/arch/powerpc/platforms/82xx/pq2ads-pci-pic.c +++ b/arch/powerpc/platforms/82xx/pq2ads-pci-pic.c @@ -24,7 +24,7 @@ #include pq2.h -static DEFINE_SPINLOCK(pci_pic_lock); +static DEFINE_RAW_SPINLOCK(pci_pic_lock); struct pq2ads_pci_pic { struct device_node *node; @@ -45,12 +45,12 @@ static void pq2ads_pci_mask_irq(unsigned int virq) if (irq != -1) { unsigned long flags; - spin_lock_irqsave(pci_pic_lock, flags); + raw_spin_lock_irqsave(pci_pic_lock, flags); setbits32(priv-regs-mask, 1 irq); mb(); - spin_unlock_irqrestore(pci_pic_lock, flags); + raw_spin_unlock_irqrestore(pci_pic_lock, flags); } } @@ -62,9 +62,9 @@ static void pq2ads_pci_unmask_irq(unsigned int virq) if (irq != -1) { unsigned long flags; - spin_lock_irqsave(pci_pic_lock, flags); + raw_spin_lock_irqsave(pci_pic_lock, flags); clrbits32(priv-regs-mask, 1 irq); - spin_unlock_irqrestore(pci_pic_lock, flags); + raw_spin_unlock_irqrestore(pci_pic_lock, flags); } } -- 1.6.5.7 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [Patch v2 1/2] 5200/mpc: improve i2c bus error recovery
Hi Joakim: [snip] static void mpc_i2c_fixup(struct mpc_i2c *i2c) { - writeccr(i2c, 0); - udelay(30); - writeccr(i2c, CCR_MEN); - udelay(30); - writeccr(i2c, CCR_MSTA | CCR_MTX); - udelay(30); - writeccr(i2c, CCR_MSTA | CCR_MTX | CCR_MEN); - udelay(30); - writeccr(i2c, CCR_MEN); - udelay(30); + int k; + u32 delay_val = 100 / i2c-real_clk + 1; + + if (delay_val 2) + delay_val = 2; + + for (k = 9; k; k--) { + writeccr(i2c, 0); + writeccr(i2c, CCR_MSTA | CCR_MTX | CCR_MEN); + udelay(delay_val); + writeccr(i2c, CCR_MEN); + udelay(delay_val 1); + } } I am curious, didn't old method work with by just wrapping a for(k=9; k; k--) around it? How did the wave form look? Sure does that work! The waveform was somewhat streched, mainly due to the delays between some of the writeccr() calls which don't change the sda/scl lines. Unfortunately I didn't take shots from the scope. However, for *one* cycle, the old code needed (only counting the udelay's) 150 us. For 9 cycles, it's 1.35 ms, which isn't really nice ;-). At 375 kHz real clock rate, delay_val is 3, i.e. each cycle consumes 9 us, or 81 us for the whole fixup procedure. If the clock is slower, the gain is of course a lot smaller, and at 20.5 kHz each cycle again needs 150 us... My feeling is that the delays used in the old code are just some values which work for sure, to if you like, my change is basically optimisation... BTW, related to your earlier question, I checked the timings recorded with the scope at 100 and at 20 kHz against the nxp's I2C bus specification and user manual, rev. 03 - everything seems to be fine. Thanks, Albrecht. Immer auf dem Laufenden! Sport, Auto, Reise, Politik und Promis. Von uns für Sie: der neue Arcor.de-Newsletter! Jetzt anmelden und einfach alles wissen: http://www.arcor.de/rd/footer.newsletter ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [patch 00/15] powerpc: raw_spinlock conversions
On Thu, 18 Feb 2010, Geert Uytterhoeven wrote: On Thu, 18 Feb 2010, Thomas Gleixner wrote: the following patch series is from preempt-rt. It converts the locks which need to be real spinlocks in -rt to raw_spinlocks. None of the patch descriptions mention why the locks need to be real spinlocks in -rt. So can you please elaborate? Sorry, forgot that there are people who do not share that particular flavour of crazy. The locks are protecting low level hardware access (mostly interrupt hardware, tlb control, et.c) and need to be taken in hard interrupt context, exception handlers or irq disabled regions. Therefor they can not be converted to sleeping spinlocks like we do for the the bulk of the spinlocks in the kernel. We annotate those locks by converting them to raw_spinlocks. In mainline there is no difference between spinlock and raw_spinlock; spinlock is simply using the raw_spinlock implementation. In RT we keep raw_spinlocks as real spinlocks and convert spinlocks to the sleeping variant. Hope that helps. tglx ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: resurrecting the mvme5100 ppc platform
On Mon, Feb 08, 2010 at 12:21:16PM +0100, Gabriel Paubert wrote: On Thu, Feb 04, 2010 at 01:39:35PM +, Paride Legovini wrote: Hello, I'm just started working on some mvme5100 boards, and so I discovered that support for these cards has been dropped with linux-2.6.27 due to lack of interest. Here is the relevent post on linuxppc-embedded: http://www.mail-archive.com/linuxppc-embed...@ozlabs.org/msg30049.html Well, I'd really like to see support for the mvme5100 to be reintegrated in the kernel. I'm willing to help on this, but at the moment I don't know how much work is to be done, as I don't know how the switch from ppc to powerpc changed things. A lot, these are PreP platforms. I'm using several MVME24xx/26xx/27xx here (some have been running continously over a decade). They have a lot of similarities with MVME5100 if I remember correctly. I don't have time right now (especially if I am alone) to write support for them, but I am interested in running a more recent kernel, provided it's not too bloated (some machines only have 16MB of RAM). This is quite discouraging, I think I'll just keep using linux-2.6.26.8, the last kernel supporting the mvme5100 (afaik). I'd like to work on a patch for newer kernels, but I have to finish a project in a reasonable time, so unfortunately I can't start studying these kernel internals now. Anyway, if you'll feel like working on it tell me, I'll be happy to help. Paride ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH v3 09/11] powerpc/mpc5121: shared DIU framebuffer support
On Tue, 2010-02-16 at 11:06 -0700, Grant Likely wrote: [...] diff --git a/drivers/video/fsl-diu-fb.c b/drivers/video/fsl-diu-fb.c index 72d68b3..29c7f31 100644 --- a/drivers/video/fsl-diu-fb.c +++ b/drivers/video/fsl-diu-fb.c @@ -34,7 +34,7 @@ #include linux/of_platform.h #include sysdev/fsl_soc.h -#include fsl-diu-fb.h +#include linux/fsl-diu-fb.h /* * These parameters give default parameters @@ -178,6 +178,21 @@ static struct fb_videomode __devinitdata fsl_diu_mode_db[] = { .sync = FB_SYNC_COMP_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, .vmode = FB_VMODE_NONINTERLACED }, + { + .name = 800x480-60, + .refresh= 60, + .xres = 800, + .yres = 480, + .pixclock = 31250, + .left_margin= 86, + .right_margin = 42, + .upper_margin = 33, + .lower_margin = 10, + .hsync_len = 128, + .vsync_len = 2, + .sync = FB_SYNC_COMP_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, + .vmode = FB_VMODE_NONINTERLACED + }, }; This hunk bothers me. It looks like the type of data that belongs either in some common shared .c file, or encoded into the device tree. It seems to be data about the display panel, instead of data about the framebuffer driver. I know that the driver already uses this pattern, but before I merge this patch and further rely on that pattern, I think it is worth discussing. Kumar, York, thoughts? g. It is a hardware related configuration. It is only used during booting before other configuration comes available. I am OK to move it to anywhere as long as it doesn't get confused or lost. York ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCHv4 2/2] powerpc: implement arch_scale_smt_power for Power7
Sorry for the slow reply, was on vacation. Mikey seems to have answered pretty well though. That is, unless these threads 2 and 3 really are _that_ weak, at which point one wonders why IBM bothered with the silicon ;-) Peter, 2 3 aren't weaker than 0 1 but The core has dynamic SMT mode switching which is controlled by the hypervisor (IBM's PHYP). There are 3 SMT modes: SMT1 uses thread 0 SMT2 uses threads 0 1 SMT4 uses threads 0, 1, 2 3 When in any particular SMT mode, all threads have the same performance as each other (ie. at any moment in time, all threads perform the same). The SMT mode switching works such that when linux has threads 2 3 idle and 0 1 active, it will cede (H_CEDE hypercall) threads 2 and 3 in the idle loop and the hypervisor will automatically switch to SMT2 for that core (independent of other cores). The opposite is not true, so if threads 0 1 are idle and 2 3 are active, we will stay in SMT4 mode. Similarly if thread 0 is active and threads 1, 2 3 are idle, we'll go into SMT1 mode. If we can get the core into a lower SMT mode (SMT1 is best), the threads will perform better (since they share less core resources). Hence when we have idle threads, we want them to be the higher ones. Just out of curiosity, is this a hardware constraint or a hypervisor constraint? hardware So to answer your question, threads 2 and 3 aren't weaker than the other threads when in SMT4 mode. It's that if we idle threads 2 3, threads 0 1 will speed up since we'll move to SMT2 mode. I'm pretty vague on linux scheduler details, so I'm a bit at sea as to how to solve this. Can you suggest any mechanisms we currently have in the kernel to reflect these properties, or do you think we need to develop something new? If so, any pointers as to where we should look? Since the threads speed up we'd need to change their weights at runtime regardless of placement. It just seems to make sense to let the changed weights affect placement naturally at the same time. Well there currently isn't one, and I've been telling people to create a new SD_flag to reflect this and influence the f_b_g() behaviour. Something like the below perhaps, totally untested and without comments so that you'll have to reverse engineer and validate my thinking. There's one fundamental assumption, and one weakness in the implementation. I'm going to guess the weakness is that it doesn't adjust the cpu power so tasks running in SMT1 mode actually get more than they account for? What's the assumption? ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH] powerpc/82xx: Convert pci_pic_lock to raw_spinlock
On Thu, 18 Feb 2010, Anton Vorontsov wrote: Interrupt controllers' hooks are executed in the atomic context, so they are not permitted to sleep (with RT kernels non-raw spinlocks are sleepable). So, pci_pic_lock has to be a real (non-sleepable) spinlock. Signed-off-by: Anton Vorontsov avoront...@ru.mvista.com Acked-by: Thomas Gleixner t...@linutronix.de ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCHv4 2/2] powerpc: implement arch_scale_smt_power for Power7
On Thu, 2010-02-18 at 10:28 -0600, Joel Schopp wrote: There's one fundamental assumption, and one weakness in the implementation. I'm going to guess the weakness is that it doesn't adjust the cpu power so tasks running in SMT1 mode actually get more than they account for? No, but you're right, if these SMTx modes are running at different frequencies then yes that needs to happen as well. The weakness is failing to do the right thing in the presence of a 'strategically' placed RT task. Suppose: Sibling0, Sibling1, Sibling2, Sibling3 idle OTHER OTHER FIFO it might not manage to migrate a task to 0 because it ends up selecting 3 as busiest. It doesn't at all influence RT placement, but it does look at nr_running (which does include RT tasks) What's the assumption? That cpu_of(Sibling n) cpu_of(Sibling n+1) ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [Patch v2 1/2] 5200/mpc: improve i2c bus error recovery
Albrecht Dreß albrecht.dr...@arcor.de wrote on 2010/02/18 16:04:16: Hi Joakim: [snip] static void mpc_i2c_fixup(struct mpc_i2c *i2c) { - writeccr(i2c, 0); - udelay(30); - writeccr(i2c, CCR_MEN); - udelay(30); - writeccr(i2c, CCR_MSTA | CCR_MTX); - udelay(30); - writeccr(i2c, CCR_MSTA | CCR_MTX | CCR_MEN); - udelay(30); - writeccr(i2c, CCR_MEN); - udelay(30); + int k; + u32 delay_val = 100 / i2c-real_clk + 1; + + if (delay_val 2) + delay_val = 2; + + for (k = 9; k; k--) { + writeccr(i2c, 0); + writeccr(i2c, CCR_MSTA | CCR_MTX | CCR_MEN); + udelay(delay_val); + writeccr(i2c, CCR_MEN); + udelay(delay_val 1); + } } I am curious, didn't old method work with by just wrapping a for(k=9; k; k--) around it? How did the wave form look? Sure does that work! The waveform was somewhat streched, mainly due to the delays between some of the writeccr() calls which don't change the sda/scl lines. Unfortunately I didn't take shots from the scope. Yeah, the long delays has to go. So the wave form was the same but more stretched in time? I ask because I don't understand the writeccr(i2c, CCR_MSTA | CCR_MTX); is supposed to do. However, for *one* cycle, the old code needed (only counting the udelay's) 150 us. For 9 cycles, it's 1.35 ms, which isn't really nice ;-). At 375 kHz real clock rate, delay_val is 3, i.e. each cycle consumes 9 us, or 81 us for the whole fixup procedure. If the clock is slower, the gain is of course a lot smaller, and at 20.5 kHz each cycle again needs 150 us... My feeling is that the delays used in the old code are just some values which work for sure, to if you like, my change is basically optimisation... The old code only works when the device is stuck at the last bit. To cope with any bit (worst case is the first bit) you need 9 cycles, 8 bits + ack = 9 Just toggling the clock 9 cycles should unlock any slave stuck in a read operation. To unlock slaves stuck in a write operation you also need to generate a START in every cycle too. As far as I can tell your patch does all of the above so Signed-off-by: Joakim Tjernlund joakim.tjernl...@transmode.se BTW, related to your earlier question, I checked the timings recorded with the scope at 100 and at 20 kHz against the nxp's I2C bus specification and user manual, rev. 03 - everything seems to be fine. Good, thanks. Jocke ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [Patch v2 1/2] 5200/mpc: improve i2c bus error recovery
On Thu, Feb 18, 2010 at 10:14 AM, Joakim Tjernlund joakim.tjernl...@transmode.se wrote: Albrecht Dreß albrecht.dr...@arcor.de wrote on 2010/02/18 16:04:16: As far as I can tell your patch does all of the above so Signed-off-by: Joakim Tjernlund joakim.tjernl...@transmode.se Thanks Joakim. On a point of process; Signed-off-by means that you've actually handled the patch and forwarded it on, either by reposting or putting it in a git tree for someone to pull. The Signed-off-by trail collects a history of all the people who have touched a patch during its development and merging. Reviewers can use Acked-by: or Reviewed-by: to indicate their consent. Ben can add your annotation when he merges the patch into his i2c tree. Cheers, g. ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [Patch v2 1/2] 5200/mpc: improve i2c bus error recovery
glik...@secretlab.ca wrote on 2010/02/18 18:41:40: On Thu, Feb 18, 2010 at 10:14 AM, Joakim Tjernlund joakim.tjernl...@transmode.se wrote: Albrecht Dreß albrecht.dr...@arcor.de wrote on 2010/02/18 16:04:16: As far as I can tell your patch does all of the above so Signed-off-by: Joakim Tjernlund joakim.tjernl...@transmode.se Thanks Joakim. On a point of process; Signed-off-by means that you've actually handled the patch and forwarded it on, either by reposting or putting it in a git tree for someone to pull. The Signed-off-by trail collects a history of all the people who have touched a patch during its development and merging. Reviewers can use Acked-by: or Reviewed-by: to indicate their consent. Ben can add your annotation when he merges the patch into his i2c tree. I see, then please change that to Acked-by: Joakim Tjernlund joakim.tjernl...@transmode.se Thanks, Jocke ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [Patch v2 1/2] 5200/mpc: improve i2c bus error recovery
Hi Joakim: Am 18.02.10 18:14 schrieb(en) Joakim Tjernlund: [snip] static void mpc_i2c_fixup(struct mpc_i2c *i2c) { - writeccr(i2c, 0); - udelay(30); - writeccr(i2c, CCR_MEN); - udelay(30); - writeccr(i2c, CCR_MSTA | CCR_MTX); - udelay(30); - writeccr(i2c, CCR_MSTA | CCR_MTX | CCR_MEN); - udelay(30); - writeccr(i2c, CCR_MEN); - udelay(30); + int k; + u32 delay_val = 100 / i2c-real_clk + 1; + + if (delay_val 2) + delay_val = 2; + + for (k = 9; k; k--) { + writeccr(i2c, 0); + writeccr(i2c, CCR_MSTA | CCR_MTX | CCR_MEN); + udelay(delay_val); + writeccr(i2c, CCR_MEN); + udelay(delay_val 1); + } } I am curious, didn't old method work with by just wrapping a for(k=9; k; k--) around it? How did the wave form look? Sure does that work! The waveform was somewhat streched, mainly due to the delays between some of the writeccr() calls which don't change the sda/scl lines. Unfortunately I didn't take shots from the scope. Yeah, the long delays has to go. So the wave form was the same but more stretched in time? I ask because I don't understand the writeccr(i2c, CCR_MSTA | CCR_MTX); is supposed to do. Afaict, this is really a no-op. The '5200 user's manual says about MEN snip * 0 module is reset and disabled. This is the Power-ON reset. When low the interface is held in reset, but registers can still be accessed. * 1 I2C module is enabled. Bit must be set before other CR bits have any effect. /snip The change in the MSTA is needed -with the proper delays- as to generate the START and STOP conditions. Unfortunately, the data sheet is not very clear (or my English too bad), but reading it *after* seeing the signals on the scope, I can at least guess what they mean :-/ Thus, the old code will probably produce SDA and SCL held high for ~90us, then a SDA/SCL low for ~30us (plus/minus the delays the hw adds internally according to the clock setting), and then a ~30us SDA/SCL high. It is not possible to get the necessary delays from the data sheet, but as I said I empirically verified some cases to be safe. The old code only works when the device is stuck at the last bit. To cope with any bit (worst case is the first bit) you need 9 cycles, 8 bits + ack = 9 Just toggling the clock 9 cycles should unlock any slave stuck in a read operation. To unlock slaves stuck in a write operation you also need to generate a START in every cycle too. Yes, of course... this was the initial motivation of the patch, as I *have* a slave which sometimes needs more than one cycle! As far as I can tell your patch does all of the above so Signed-off-by: Joakim Tjernlund joakim.tjernl...@transmode.se Thanks a lot again for your time, and your helpful comments! Best, Albrecht. pgpmK1BnBMsNC.pgp Description: PGP signature ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [patch 06/15] powerpc: Convert tlbivax_lock to raw_spinlock
On Feb 18, 2010, at 6:22 AM, Thomas Gleixner wrote: tlbivax_lock needs to be a real spinlock in RT. Convert it to raw_spinlock. Signed-off-by: Thomas Gleixner t...@linutronix.de --- arch/powerpc/mm/tlb_nohash.c |6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) Acked-by: Kumar Gala ga...@kernel.crashing.org - k ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH] powerpc/85xx: Convert socrates_fpga_pic_lock to raw_spinlock
On Feb 18, 2010, at 7:45 AM, Anton Vorontsov wrote: Interrupt controllers' hooks are executed in the atomic context, so they are not permitted to sleep (with RT kernels non-raw spinlocks are sleepable). So, socrates_fpga_pic_lock has to be a real (non-sleepable) spinlock. Signed-off-by: Anton Vorontsov avoront...@ru.mvista.com --- On Thu, Feb 18, 2010 at 12:22:18PM -, Thomas Gleixner wrote: Ben, the following patch series is from preempt-rt. It converts the locks which need to be real spinlocks in -rt to raw_spinlocks. There is no behaviourial change for !RT kernels because spinlocks and raw_spinlocks are the same on !RT. So for mainline this is a pure annotation while having it in mainline takes the burden of keeping up with the code changes from the RT patch set. Please consider to merge into .34. Oh, and I guess the same for the socrates fpga pic... arch/powerpc/platforms/85xx/socrates_fpga_pic.c | 34 +++--- 1 files changed, 17 insertions(+), 17 deletions(-) applied to next - k ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH] powerpc/82xx: Convert pci_pic_lock to raw_spinlock
On Feb 18, 2010, at 7:57 AM, Anton Vorontsov wrote: Interrupt controllers' hooks are executed in the atomic context, so they are not permitted to sleep (with RT kernels non-raw spinlocks are sleepable). So, pci_pic_lock has to be a real (non-sleepable) spinlock. Signed-off-by: Anton Vorontsov avoront...@ru.mvista.com --- arch/powerpc/platforms/82xx/pq2ads-pci-pic.c | 10 +- 1 files changed, 5 insertions(+), 5 deletions(-) applied to next - k ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH] powerpc/qe: Convert qe_ic_lock to raw_spinlock
On Feb 18, 2010, at 7:43 AM, Anton Vorontsov wrote: Interrupt controllers' hooks are executed in the atomic context, so they are not permitted to sleep (with RT kernels non-raw spinlocks are sleepable). So, qe_ic_lock has to be a real (non-sleepable) spinlock. Signed-off-by: Anton Vorontsov avoront...@ru.mvista.com --- applied to next - k ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH] powerpc/86xx: Convert gef_pic_lock to raw_spinlock
On Feb 18, 2010, at 7:57 AM, Anton Vorontsov wrote: Interrupt controllers' hooks are executed in the atomic context, so they are not permitted to sleep (with RT kernels non-raw spinlocks are sleepable). So, gef_pic_lock has to be a real (non-sleepable) spinlock. Signed-off-by: Anton Vorontsov avoront...@ru.mvista.com --- arch/powerpc/platforms/86xx/gef_pic.c | 14 +++--- 1 files changed, 7 insertions(+), 7 deletions(-) applied to next - k ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH] powerpc: Call ibm,os-term if the ibm,extended-os-term is present
We have had issues in the past with ibm,os-term initiating shutdown of a partition. This is confusing to the user, especially if panic_timeout is non zero. The temporary fix was to avoid calling ibm,os-term if a panic_timeout was set and since we set it on every boot we basically never call ibm,os-term. An extended version of ibm,os-term has since been implemented which gives us the behaviour we want: When the platform supports extended ibm,os-term behavior, the return to the RTAS will always occur unless there is a kernel assisted dump active as initiated by an ibm,configure-kernel-dump call. This patch checks for the ibm,extended-os-term property and calls ibm,os-term if it exists. Signed-off-by: Anton Blanchard an...@samba.org --- Index: linux-cpumask/arch/powerpc/kernel/rtas.c === --- linux-cpumask.orig/arch/powerpc/kernel/rtas.c 2010-02-18 20:31:17.283568754 +1100 +++ linux-cpumask/arch/powerpc/kernel/rtas.c2010-02-19 09:07:05.735254857 +1100 @@ -690,10 +690,14 @@ void rtas_os_term(char *str) { int status; - if (panic_timeout) - return; - - if (RTAS_UNKNOWN_SERVICE == rtas_token(ibm,os-term)) + /* +* Firmware with the ibm,extended-os-term property is guaranteed +* to always return from an ibm,os-term call. Earlier versions without +* this property may terminate the partition which we want to avoid +* since it interferes with panic_timeout. +*/ + if (RTAS_UNKNOWN_SERVICE == rtas_token(ibm,os-term) || + RTAS_UNKNOWN_SERVICE == rtas_token(ibm,extended-os-term)) return; snprintf(rtas_os_term_buf, 2048, OS panic: %s, str); @@ -704,8 +708,7 @@ void rtas_os_term(char *str) } while (rtas_busy_delay(status)); if (status != 0) - printk(KERN_EMERG ibm,os-term call failed %d\n, - status); + printk(KERN_EMERG ibm,os-term call failed %d\n, status); } static int ibm_suspend_me_token = RTAS_UNKNOWN_SERVICE; ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[-next Feb 18] PowerPC boot failure (Unknowd ADD relocation :26)
Yesterday's next failed to boot on various powerpc boxes with following error : NET: Registered protocol family 15 registered taskstats version 1 Freeing unused kernel memory: 640k freed doing fast boot scsi_mod: Unknown ADD relocation: 26 WARNING: Error inserting scsi_mod (/lib/modules/2.6.33-rc8-autotest-next-20100218/kernel/drivers/scsi/scsi_mod.ko): Invalid module format scsi_tgt: Unknown symbol scsi_release_buffers scsi_tgt: Unknown symbol scsi_host_put scsi_tgt: Unknown symbol __scsi_put_command scsi_tgt: Unknown symbol scsi_host_lookup scsi_tgt: Unknown symbol __scsi_get_command scsi_tgt: Unknown symbol scsi_init_io scsi_tgt: Unknown symbol __scsi_alloc_queue and many more such modules related errors. I have attached the boot log here. Next Feb 17th was OK. Haven't yet tried the git bisect. Will try that out today. Thanks -Sachin -- - Sachin Sant IBM Linux Technology Center India Systems and Technology Labs Bangalore, India - Using 00825420 bytes for initrd buffer Please wait, loading kernel... Allocated 00f0 bytes for kernel @ 00d0 Elf64 kernel loaded... Loading ramdisk... ramdisk loaded 00825420 @ 034d OF stdout device is: /vdevice/v...@3000 Preparing to boot Linux version 2.6.33-rc8-autotest-next-20100218 (r...@llm62) (gcc version 4.3.2 [gcc-4_3-branch revision 141291] (SUSE Linux) ) #1 SMP Thu Feb 18 17:49:40 IST 2010 Max number of cores passed to firmware: 0x0200 Calling ibm,client-architecture-support... done command line: root=/dev/sda5 IDENT=1266496633 memory layout at init: memory_limit : (16 MB aligned) alloc_bottom : 03d0 alloc_top: 0800 alloc_top_hi : 0800 rmo_top : 0800 ram_top : 0800 instantiating rtas at 0x074e... done boot cpu hw idx starting cpu hw idx 0002... done copying OF device tree... Building dt strings... Building dt structure... Device tree strings 0x03d1 - 0x03d115fa Device tree struct 0x03d2 - 0x03d4 Calling quiesce... returning from prom_init Using pSeries machine description Using 1TB segments Found initrd at 0xc34d:0xc3cf5420 bootconsole [udbg0] enabled Partition configured for 4 cpus. CPU maps initialized for 2 threads per core Starting Linux PPC64 #1 SMP Thu Feb 18 17:49:40 IST 2010 - ppc64_pft_size= 0x1a physicalMemorySize= 0x1 htab_hash_mask= 0x7 - Initializing cgroup subsys cpuset Initializing cgroup subsys cpu Linux version 2.6.33-rc8-autotest-next-20100218 (r...@llm62) (gcc version 4.3.2 [gcc-4_3-branch revision 141291] (SUSE Linux) ) #1 SMP Thu Feb 18 17:49:40 IST 2010 [boot]0012 Setup Arch EEH: No capable adapters found PPC64 nvram contains 15360 bytes Zone PFN ranges: DMA 0x - 0x0001 Normal 0x0001 - 0x0001 Movable zone start PFN for each node early_node_map[1] active PFN ranges 1: 0x - 0x0001 Could not find start_pfn for node 0 [boot]0015 Setup Done PERCPU: Embedded 2 pages/cpu @c0f0 s89768 r0 d41304 u262144 pcpu-alloc: s89768 r0 d41304 u262144 alloc=1*1048576 pcpu-alloc: [0] 0 1 2 3 Built 2 zonelists in Node order, mobility grouping on. Total pages: 65480 Policy zone: DMA Kernel command line: root=/dev/sda5 IDENT=1266496633 PID hash table entries: 4096 (order: -1, 32768 bytes) freeing bootmem node 1 Memory: 4142272k/4194304k available (9280k kernel code, 52032k reserved, 2624k data, 2287k bss, 640k init) Hierarchical RCU implementation. RCU-based detection of stalled CPUs is enabled. NR_IRQS:512 nr_irqs:512 [boot]0020 XICS Init [boot]0021 XICS Done clocksource: timebase mult[7d] shift[22] registered Console: colour dummy device 80x25 console [hvc0] enabled, bootconsole disabled console [hvc0] enabled, bootconsole disabled allocated 2621440 bytes of page_cgroup please try 'cgroup_disable=memory' option if you don't want memory cgroups Security Framework initialized SELinux: Disabled at boot. Dentry cache hash table entries: 524288 (order: 6, 4194304 bytes) Inode-cache hash table entries: 262144 (order: 5, 2097152 bytes) Mount-cache hash table entries: 4096 Initializing cgroup subsys ns Initializing cgroup subsys cpuacct Initializing cgroup subsys memory Initializing cgroup subsys devices Initializing cgroup subsys freezer Initializing cgroup subsys blkio Processor 1 found. Processor 2 found. Processor 3 found. Brought up 4 CPUs devtmpfs: initialized NET: Registered protocol family 16 IBM eBus Device Driver POWER6 performance monitor hardware support registered PCI: Probing PCI hardware bio: create slab bio-0 at 0 vgaarb: loaded usbcore: registered new interface driver usbfs usbcore: registered new interface driver hub
Re: State of PREEMPT_RT in PPC arch
On Thu, Feb 18, 2010 at 5:15 AM, Wolfram Sang w.s...@pengutronix.de wrote: I'm soliciting comments from the community. Thanks in advance for sharing your thoughts. Mainline your driver and you are free from such problems :) Shouldn't it be the opposite way? That is, get drivers working first then mainline them? I even don't have a working driver with RT patch. Thanks for the response though. At least it shows that such emails are not completely ignored. I feel the linuxppc-dev mailing list is full of development patches and discussions about them, kinda dedicated to active developers. Is there a place that users or not-so-active developers can post technical questions and get some relatively quick answers or comments? I think there used to be such a mailing list but I couldn't remember it. -Ryan. ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCHv4 2/2] powerpc: implement arch_scale_smt_power for Power7
On Thu, 2010-02-18 at 09:20 +1100, Michael Neuling wrote: Suppose for a moment we have 2 threads (hot-unplugged thread 1 and 3, we can construct an equivalent but more complex example for 4 threads), and we have 4 tasks, 3 SCHED_OTHER of equal nice level and 1 SCHED_FIFO, the SCHED_FIFO task will consume exactly 50% walltime of whatever cpu it ends up on. In that situation, provided that each cpu's cpu_power is of equal measure, scale_rt_power() ensures that we run 2 SCHED_OTHER tasks on the cpu that doesn't run the RT task, and 1 SCHED_OTHER task next to the RT task, so that each task consumes 50%, which is all fair and proper. However, if you do the above, thread 0 will have +75% = 1.75 and thread 2 will have -75% = 0.25, then if the RT task will land on thread 0, we'll be having: 0.875 vs 0.25, or on thread 3, 1.75 vs 0.125. In either case thread 0 will receive too many (if not all) SCHED_OTHER tasks. That is, unless these threads 2 and 3 really are _that_ weak, at which point one wonders why IBM bothered with the silicon ;-) Peter, 2 3 aren't weaker than 0 1 but The core has dynamic SMT mode switching which is controlled by the hypervisor (IBM's PHYP). There are 3 SMT modes: SMT1 uses thread 0 SMT2 uses threads 0 1 SMT4 uses threads 0, 1, 2 3 When in any particular SMT mode, all threads have the same performance as each other (ie. at any moment in time, all threads perform the same). The SMT mode switching works such that when linux has threads 2 3 idle and 0 1 active, it will cede (H_CEDE hypercall) threads 2 and 3 in the idle loop and the hypervisor will automatically switch to SMT2 for that core (independent of other cores). The opposite is not true, so if threads 0 1 are idle and 2 3 are active, we will stay in SMT4 mode. Similarly if thread 0 is active and threads 1, 2 3 are idle, we'll go into SMT1 mode. If we can get the core into a lower SMT mode (SMT1 is best), the threads will perform better (since they share less core resources). Hence when we have idle threads, we want them to be the higher ones. Just out of curiosity, is this a hardware constraint or a hypervisor constraint? So to answer your question, threads 2 and 3 aren't weaker than the other threads when in SMT4 mode. It's that if we idle threads 2 3, threads 0 1 will speed up since we'll move to SMT2 mode. I'm pretty vague on linux scheduler details, so I'm a bit at sea as to how to solve this. Can you suggest any mechanisms we currently have in the kernel to reflect these properties, or do you think we need to develop something new? If so, any pointers as to where we should look? Well there currently isn't one, and I've been telling people to create a new SD_flag to reflect this and influence the f_b_g() behaviour. Something like the below perhaps, totally untested and without comments so that you'll have to reverse engineer and validate my thinking. There's one fundamental assumption, and one weakness in the implementation. Thanks for the help. I'm still trying to get up to speed with how this works but while trying to cleanup and compile your patch, I had some simple questions below... --- include/linux/sched.h |2 +- kernel/sched_fair.c | 61 +-- - 2 files changed, 58 insertions(+), 5 deletions(-) diff --git a/include/linux/sched.h b/include/linux/sched.h index 0eef87b..42fa5c6 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -849,7 +849,7 @@ enum cpu_idle_type { #define SD_POWERSAVINGS_BALANCE 0x0100 /* Balance for power savings */ #define SD_SHARE_PKG_RESOURCES 0x0200 /* Domain members share cpu pkg resources */ #define SD_SERIALIZE 0x0400 /* Only a single load balancing instanc e */ - +#define SD_ASYM_PACKING 0x0800 Would we eventually add this to SD_SIBLING_INIT in a arch specific hook, or is this ok to add it generically? #define SD_PREFER_SIBLING0x1000 /* Prefer to place tasks in a sibling d omain */ enum powersavings_balance_level { diff --git a/kernel/sched_fair.c b/kernel/sched_fair.c index ff7692c..7e42bfe 100644 --- a/kernel/sched_fair.c +++ b/kernel/sched_fair.c @@ -2086,6 +2086,7 @@ struct sd_lb_stats { struct sched_group *this; /* Local group in this sd */ unsigned long total_load; /* Total load of all groups in sd */ unsigned long total_pwr; /* Total power of all groups in sd */ + unsigned long total_nr_running; unsigned long avg_load;/* Average load across all groups in sd */ /** Statistics of this group */ @@ -2414,10 +2415,10 @@ static inline void update_sg_lb_stats(struct sched_do main *sd, int *balance, struct sg_lb_stats *sgs) { unsigned long load, max_cpu_load, min_cpu_load; - int i;