* [RFC][PATCH] first pass at iSeries io rewrite
From: Stephen Rothwell @ 2006-04-07 7:57 UTC (permalink / raw)
To: paulus; +Cc: ppc-dev
We would like to reduce the special casing of things for legacy iSeries
generally. This patch starts the work on iSeries i/o. This changes the
i/o so that iSeries will take a fault if any i/o is attempted and the
appripriate instructions are emulated. To make this easier, some of the
i/o primitives have been modified to use a simple set of load/store
instructions with the target or source fixed to r0.
This also (strangely) shrinks a normal pSeries built kernel text by about
130 bytes (but adds 256 bytes to its data).
Before this change, typical outw() took about 1650 - 2740 cycles and
afterward about 2190 - 9020 cycles. The variablilty is interesting and is
probably not only due to these changes.
This does not yet handle memset_io, memcopy_fromio and memcpy_toio.
Some possibilities:
try to shorten the fault path
doing a fixup on the fist trap
Suggestions? Comments?
--
Cheers,
Stephen Rothwell sfr@canb.auug.org.au
---
arch/powerpc/mm/fault.c | 8 ++
arch/powerpc/platforms/iseries/pci.c | 139 +++++++++++++++++++-----------
include/asm-powerpc/io.h | 81 +++++------------
include/asm-powerpc/iseries/iseries_io.h | 19 ----
include/asm-powerpc/ppc-pci.h | 11 ++
5 files changed, 128 insertions(+), 130 deletions(-)
51ff17bea4b0434067e0d3b2fa58493227619baa
diff --git a/arch/powerpc/mm/fault.c b/arch/powerpc/mm/fault.c
index fdbba42..c0b1986 100644
--- a/arch/powerpc/mm/fault.c
+++ b/arch/powerpc/mm/fault.c
@@ -39,6 +39,8 @@
#include <asm/tlbflush.h>
#include <asm/kdebug.h>
#include <asm/siginfo.h>
+#include <asm/firmware.h>
+#include <asm/ppc-pci.h>
/*
* Check whether the instruction at regs->nip is a store using
@@ -152,8 +154,12 @@ int __kprobes do_page_fault(struct pt_re
}
/* On a kernel SLB miss we can only check for a valid exception entry */
- if (!user_mode(regs) && (address >= TASK_SIZE))
+ if (!user_mode(regs) && (address >= TASK_SIZE)) {
+ if (firmware_has_feature(FW_FEATURE_ISERIES) &&
+ iseries_handle_io_fault(regs, address))
+ return 0;
return SIGSEGV;
+ }
#if !(defined(CONFIG_4xx) || defined(CONFIG_BOOKE))
if (error_code & DSISR_DABRMATCH) {
diff --git a/arch/powerpc/platforms/iseries/pci.c b/arch/powerpc/platforms/iseries/pci.c
index a19833b..3631995 100644
--- a/arch/powerpc/platforms/iseries/pci.c
+++ b/arch/powerpc/platforms/iseries/pci.c
@@ -26,6 +26,7 @@
#include <linux/module.h>
#include <linux/ide.h>
#include <linux/pci.h>
+#include <linux/ptrace.h>
#include <asm/io.h>
#include <asm/irq.h>
@@ -37,6 +38,7 @@
#include <asm/iseries/hv_call_xm.h>
#include <asm/iseries/mf.h>
+#include <asm/iseries/iseries_io.h>
#include <asm/ppc-pci.h>
@@ -465,46 +467,6 @@ static int scan_bridge_slot(HvBusNumber
}
/*
- * I/0 Memory copy MUST use mmio commands on iSeries
- * To do; For performance, include the hv call directly
- */
-void iSeries_memset_io(volatile void __iomem *dest, char c, size_t Count)
-{
- u8 ByteValue = c;
- long NumberOfBytes = Count;
-
- while (NumberOfBytes > 0) {
- iSeries_Write_Byte(ByteValue, dest++);
- -- NumberOfBytes;
- }
-}
-EXPORT_SYMBOL(iSeries_memset_io);
-
-void iSeries_memcpy_toio(volatile void __iomem *dest, void *source, size_t count)
-{
- char *src = source;
- long NumberOfBytes = count;
-
- while (NumberOfBytes > 0) {
- iSeries_Write_Byte(*src++, dest++);
- -- NumberOfBytes;
- }
-}
-EXPORT_SYMBOL(iSeries_memcpy_toio);
-
-void iSeries_memcpy_fromio(void *dest, const volatile void __iomem *src, size_t count)
-{
- char *dst = dest;
- long NumberOfBytes = count;
-
- while (NumberOfBytes > 0) {
- *dst++ = iSeries_Read_Byte(src++);
- -- NumberOfBytes;
- }
-}
-EXPORT_SYMBOL(iSeries_memcpy_fromio);
-
-/*
* Look down the chain to find the matching Device Device
*/
static struct device_node *find_Device_Node(int bus, int devfn)
@@ -685,7 +647,7 @@ static inline struct device_node *xlate_
* iSeries_Read_Word = Read Word (16 bit)
* iSeries_Read_Long = Read Long (32 bit)
*/
-u8 iSeries_Read_Byte(const volatile void __iomem *IoAddress)
+static u8 iSeries_Read_Byte(const volatile void __iomem *IoAddress)
{
u64 BarOffset;
u64 dsa;
@@ -713,9 +675,8 @@ u8 iSeries_Read_Byte(const volatile void
return (u8)ret.value;
}
-EXPORT_SYMBOL(iSeries_Read_Byte);
-u16 iSeries_Read_Word(const volatile void __iomem *IoAddress)
+static u16 iSeries_Read_Word(const volatile void __iomem *IoAddress)
{
u64 BarOffset;
u64 dsa;
@@ -744,9 +705,8 @@ u16 iSeries_Read_Word(const volatile voi
return swab16((u16)ret.value);
}
-EXPORT_SYMBOL(iSeries_Read_Word);
-u32 iSeries_Read_Long(const volatile void __iomem *IoAddress)
+static u32 iSeries_Read_Long(const volatile void __iomem *IoAddress)
{
u64 BarOffset;
u64 dsa;
@@ -775,7 +735,6 @@ u32 iSeries_Read_Long(const volatile voi
return swab32((u32)ret.value);
}
-EXPORT_SYMBOL(iSeries_Read_Long);
/*
* Write MM I/O Instructions for the iSeries
@@ -784,7 +743,7 @@ EXPORT_SYMBOL(iSeries_Read_Long);
* iSeries_Write_Word = Write Word(16 bit)
* iSeries_Write_Long = Write Long(32 bit)
*/
-void iSeries_Write_Byte(u8 data, volatile void __iomem *IoAddress)
+static void iSeries_Write_Byte(u8 data, volatile void __iomem *IoAddress)
{
u64 BarOffset;
u64 dsa;
@@ -810,9 +769,8 @@ void iSeries_Write_Byte(u8 data, volatil
rc = HvCall4(HvCallPciBarStore8, dsa, BarOffset, data, 0);
} while (CheckReturnCode("WWB", DevNode, &retry, rc) != 0);
}
-EXPORT_SYMBOL(iSeries_Write_Byte);
-void iSeries_Write_Word(u16 data, volatile void __iomem *IoAddress)
+static void iSeries_Write_Word(u16 data, volatile void __iomem *IoAddress)
{
u64 BarOffset;
u64 dsa;
@@ -838,9 +796,8 @@ void iSeries_Write_Word(u16 data, volati
rc = HvCall4(HvCallPciBarStore16, dsa, BarOffset, swab16(data), 0);
} while (CheckReturnCode("WWW", DevNode, &retry, rc) != 0);
}
-EXPORT_SYMBOL(iSeries_Write_Word);
-void iSeries_Write_Long(u32 data, volatile void __iomem *IoAddress)
+static void iSeries_Write_Long(u32 data, volatile void __iomem *IoAddress)
{
u64 BarOffset;
u64 dsa;
@@ -866,4 +823,82 @@ void iSeries_Write_Long(u32 data, volati
rc = HvCall4(HvCallPciBarStore32, dsa, BarOffset, swab32(data), 0);
} while (CheckReturnCode("WWL", DevNode, &retry, rc) != 0);
}
-EXPORT_SYMBOL(iSeries_Write_Long);
+
+/*
+ * I/0 Memory copy MUST use mmio commands on iSeries
+ * To do; For performance, include the hv call directly
+ */
+void iSeries_memset_io(volatile void __iomem *dest, char c, size_t Count)
+{
+ u8 ByteValue = c;
+ long NumberOfBytes = Count;
+
+ while (NumberOfBytes > 0) {
+ iSeries_Write_Byte(ByteValue, dest++);
+ -- NumberOfBytes;
+ }
+}
+EXPORT_SYMBOL(iSeries_memset_io);
+
+void iSeries_memcpy_toio(volatile void __iomem *dest, void *source, size_t count)
+{
+ char *src = source;
+ long NumberOfBytes = count;
+
+ while (NumberOfBytes > 0) {
+ iSeries_Write_Byte(*src++, dest++);
+ -- NumberOfBytes;
+ }
+}
+EXPORT_SYMBOL(iSeries_memcpy_toio);
+
+void iSeries_memcpy_fromio(void *dest, const volatile void __iomem *src, size_t count)
+{
+ char *dst = dest;
+ long NumberOfBytes = count;
+
+ while (NumberOfBytes > 0) {
+ *dst++ = iSeries_Read_Byte(src++);
+ -- NumberOfBytes;
+ }
+}
+EXPORT_SYMBOL(iSeries_memcpy_fromio);
+
+int iseries_handle_io_fault(struct pt_regs *regs, unsigned long address)
+{
+ u32 instr;
+
+ /* is the address in out i/o range? */
+ if ((address < BASE_IO_MEMORY) || (address >= max_io_memory))
+ return 0;
+ /* we are only called for kernel mode faults */
+ instr = *(u32 *)regs->nip;
+ /* Is the major opcode 31 and target/source r0? */
+ if ((instr & 0xffe00000) != 0x7C000000)
+ return 0;
+
+ switch ((instr >> 1) & 0x3ff) {
+ case 87:
+ regs->gpr[0] = iSeries_Read_Byte((void __iomem *)address);
+ break;
+ case 215:
+ iSeries_Write_Byte(regs->gpr[0], (void __iomem *)address);
+ break;
+ case 790:
+ regs->gpr[0] = iSeries_Read_Word((void __iomem *)address);
+ break;
+ case 918:
+ iSeries_Write_Word(regs->gpr[0], (void __iomem *)address);
+ break;
+ case 534:
+ regs->gpr[0] = iSeries_Read_Long((void __iomem *)address);
+ break;
+ case 662:
+ iSeries_Write_Long(regs->gpr[0], (void __iomem *)address);
+ break;
+ default:
+ return 0;
+ }
+ regs->nip += 4;
+ return 1;
+}
diff --git a/include/asm-powerpc/io.h b/include/asm-powerpc/io.h
index 68efbea..0725c11 100644
--- a/include/asm-powerpc/io.h
+++ b/include/asm-powerpc/io.h
@@ -16,9 +16,6 @@
#include <linux/compiler.h>
#include <asm/page.h>
#include <asm/byteorder.h>
-#ifdef CONFIG_PPC_ISERIES
-#include <asm/iseries/iseries_io.h>
-#endif
#include <asm/synch.h>
#include <asm/delay.h>
@@ -44,41 +41,6 @@ extern unsigned long io_page_mask;
#define _IO_IS_VALID(port) ((port) >= MAX_ISA_PORT || (1 << (port>>PAGE_SHIFT)) \
& io_page_mask)
-#ifdef CONFIG_PPC_ISERIES
-/* __raw_* accessors aren't supported on iSeries */
-#define __raw_readb(addr) { BUG(); 0; }
-#define __raw_readw(addr) { BUG(); 0; }
-#define __raw_readl(addr) { BUG(); 0; }
-#define __raw_readq(addr) { BUG(); 0; }
-#define __raw_writeb(v, addr) { BUG(); 0; }
-#define __raw_writew(v, addr) { BUG(); 0; }
-#define __raw_writel(v, addr) { BUG(); 0; }
-#define __raw_writeq(v, addr) { BUG(); 0; }
-#define readb(addr) iSeries_Read_Byte(addr)
-#define readw(addr) iSeries_Read_Word(addr)
-#define readl(addr) iSeries_Read_Long(addr)
-#define writeb(data, addr) iSeries_Write_Byte((data),(addr))
-#define writew(data, addr) iSeries_Write_Word((data),(addr))
-#define writel(data, addr) iSeries_Write_Long((data),(addr))
-#define memset_io(a,b,c) iSeries_memset_io((a),(b),(c))
-#define memcpy_fromio(a,b,c) iSeries_memcpy_fromio((a), (b), (c))
-#define memcpy_toio(a,b,c) iSeries_memcpy_toio((a), (b), (c))
-
-#define inb(addr) readb(((void __iomem *)(long)(addr)))
-#define inw(addr) readw(((void __iomem *)(long)(addr)))
-#define inl(addr) readl(((void __iomem *)(long)(addr)))
-#define outb(data,addr) writeb(data,((void __iomem *)(long)(addr)))
-#define outw(data,addr) writew(data,((void __iomem *)(long)(addr)))
-#define outl(data,addr) writel(data,((void __iomem *)(long)(addr)))
-/*
- * The *_ns versions below don't do byte-swapping.
- * Neither do the standard versions now, these are just here
- * for older code.
- */
-#define insw_ns(port, buf, ns) _insw_ns((u16 __iomem *)((port)+pci_io_base), (buf), (ns))
-#define insl_ns(port, buf, nl) _insl_ns((u32 __iomem *)((port)+pci_io_base), (buf), (nl))
-#else
-
static inline unsigned char __raw_readb(const volatile void __iomem *addr)
{
return *(volatile unsigned char __force *)addr;
@@ -144,8 +106,6 @@ static inline void __raw_writeq(unsigned
#define outsw(port, buf, ns) _outsw_ns((u16 __iomem *)((port)+pci_io_base), (buf), (ns))
#define outsl(port, buf, nl) _outsl_ns((u32 __iomem *)((port)+pci_io_base), (buf), (nl))
-#endif
-
#define readb_relaxed(addr) readb(addr)
#define readw_relaxed(addr) readw(addr)
#define readl_relaxed(addr) readl(addr)
@@ -273,25 +233,30 @@ static inline void iosync(void)
* These routines do not perform EEH-related I/O address translation,
* and should not be used directly by device drivers. Use inb/readb
* instead.
+ *
+ * For some of these, we force the target/source register to be
+ * r0 to ease decoding on iSeries.
*/
static inline int in_8(const volatile unsigned char __iomem *addr)
{
- int ret;
+ register unsigned int ret __asm__("r0");
- __asm__ __volatile__("lbz%U1%X1 %0,%1; twi 0,%0,0; isync"
- : "=r" (ret) : "m" (*addr));
+ __asm__ __volatile__("lbzx %0,0,%1; twi 0,%0,0; isync"
+ : "=r" (ret) : "r" (addr));
return ret;
}
-static inline void out_8(volatile unsigned char __iomem *addr, int val)
+static inline void out_8(volatile unsigned char __iomem *addr, int ival)
{
- __asm__ __volatile__("stb%U0%X0 %1,%0; sync"
- : "=m" (*addr) : "r" (val));
+ register unsigned int val __asm__("r0") = ival;
+
+ __asm__ __volatile__("stbx %0,0,%1; sync"
+ : : "r" (val), "r" (addr));
}
static inline int in_le16(const volatile unsigned short __iomem *addr)
{
- int ret;
+ register unsigned int ret __asm__("r0");
__asm__ __volatile__("lhbrx %0,0,%1; twi 0,%0,0; isync"
: "=r" (ret) : "r" (addr), "m" (*addr));
@@ -307,10 +272,12 @@ static inline int in_be16(const volatile
return ret;
}
-static inline void out_le16(volatile unsigned short __iomem *addr, int val)
+static inline void out_le16(volatile unsigned short __iomem *addr, int ival)
{
- __asm__ __volatile__("sthbrx %1,0,%2; sync"
- : "=m" (*addr) : "r" (val), "r" (addr));
+ register unsigned int val __asm__("r0") = ival;
+
+ __asm__ __volatile__("sthbrx %0,0,%1; sync"
+ : : "r" (val), "r" (addr));
}
static inline void out_be16(volatile unsigned short __iomem *addr, int val)
@@ -321,7 +288,7 @@ static inline void out_be16(volatile uns
static inline unsigned in_le32(const volatile unsigned __iomem *addr)
{
- unsigned ret;
+ register unsigned int ret __asm__("r0");
__asm__ __volatile__("lwbrx %0,0,%1; twi 0,%0,0; isync"
: "=r" (ret) : "r" (addr), "m" (*addr));
@@ -337,10 +304,12 @@ static inline unsigned in_be32(const vol
return ret;
}
-static inline void out_le32(volatile unsigned __iomem *addr, int val)
+static inline void out_le32(volatile unsigned __iomem *addr, int ival)
{
- __asm__ __volatile__("stwbrx %1,0,%2; sync" : "=m" (*addr)
- : "r" (val), "r" (addr));
+ register unsigned int val __asm__("r0") = ival;
+
+ __asm__ __volatile__("stwbrx %1,0,%2; sync"
+ : "=m" (*addr) : "r" (val), "r" (addr));
}
static inline void out_be32(volatile unsigned __iomem *addr, int val)
@@ -399,9 +368,7 @@ static inline void out_be64(volatile uns
__asm__ __volatile__("std%U0%X0 %1,%0; sync" : "=m" (*addr) : "r" (val));
}
-#ifndef CONFIG_PPC_ISERIES
#include <asm/eeh.h>
-#endif
/**
* check_signature - find BIOS signatures
@@ -417,7 +384,6 @@ static inline int check_signature(const
const unsigned char *signature, int length)
{
int retval = 0;
-#ifndef CONFIG_PPC_ISERIES
do {
if (readb(io_addr) != *signature)
goto out;
@@ -427,7 +393,6 @@ static inline int check_signature(const
} while (length);
retval = 1;
out:
-#endif
return retval;
}
diff --git a/include/asm-powerpc/iseries/iseries_io.h b/include/asm-powerpc/iseries/iseries_io.h
index 496aa85..5be0a73 100644
--- a/include/asm-powerpc/iseries/iseries_io.h
+++ b/include/asm-powerpc/iseries/iseries_io.h
@@ -1,8 +1,6 @@
#ifndef _ASM_POWERPC_ISERIES_ISERIES_IO_H
#define _ASM_POWERPC_ISERIES_ISERIES_IO_H
-#include <linux/config.h>
-
#ifdef CONFIG_PPC_ISERIES
#include <linux/types.h>
/*
@@ -33,28 +31,11 @@
*/
#ifdef CONFIG_PCI
-extern u8 iSeries_Read_Byte(const volatile void __iomem * IoAddress);
-extern u16 iSeries_Read_Word(const volatile void __iomem * IoAddress);
-extern u32 iSeries_Read_Long(const volatile void __iomem * IoAddress);
-extern void iSeries_Write_Byte(u8 IoData, volatile void __iomem * IoAddress);
-extern void iSeries_Write_Word(u16 IoData, volatile void __iomem * IoAddress);
-extern void iSeries_Write_Long(u32 IoData, volatile void __iomem * IoAddress);
-
extern void iSeries_memset_io(volatile void __iomem *dest, char x, size_t n);
extern void iSeries_memcpy_toio(volatile void __iomem *dest, void *source,
size_t n);
extern void iSeries_memcpy_fromio(void *dest,
const volatile void __iomem *source, size_t n);
-#else
-static inline u8 iSeries_Read_Byte(const volatile void __iomem *IoAddress)
-{
- return 0xff;
-}
-
-static inline void iSeries_Write_Byte(u8 IoData,
- volatile void __iomem *IoAddress)
-{
-}
#endif /* CONFIG_PCI */
#endif /* CONFIG_PPC_ISERIES */
diff --git a/include/asm-powerpc/ppc-pci.h b/include/asm-powerpc/ppc-pci.h
index cf79bc7..db153ab 100644
--- a/include/asm-powerpc/ppc-pci.h
+++ b/include/asm-powerpc/ppc-pci.h
@@ -51,6 +51,17 @@ extern void pSeries_irq_bus_setup(struct
extern unsigned long pci_probe_only;
+/* From platforms/iseries/pci.c */
+#if defined(CONFIG_PPC_ISERIES) && defined(CONFIG_PCI)
+extern int iseries_handle_io_fault(struct pt_regs *regs, unsigned long address);
+#else
+static inline int iseries_handle_io_fault(struct pt_regs *regs,
+ unsigned long address)
+{
+ return 0;
+}
+#endif
+
/* ---- EEH internal-use-only related routines ---- */
#ifdef CONFIG_EEH
--
1.2.4
^ permalink raw reply related
* RTC/I2C on 82xx with Linux 2.6.x
From: Laurent Lagrange @ 2006-04-07 8:16 UTC (permalink / raw)
To: linuxppc-embedded
In-Reply-To: <000001c642bd$1dc28fa0$5201a8c0@GEG2400>
Hello,
I use a Linux 2.6.x on a custom 8270 board with a RTC on the I2C bus
(rtc8564).
I want to use it as the system date :
- Is it possible ?
- Do I need to initialize the "ppc_md" structure in the "platform_init"
function with my own RTC functions ?
- In that case, can I use the kernel I2C layer ?
Thanks all
Laurent
^ permalink raw reply
* [PATCH 1/4] tickless idle cpu - Allow any CPU to update jiffies
From: Srivatsa Vaddagiri @ 2006-04-07 6:30 UTC (permalink / raw)
To: anton, benh, paulus; +Cc: linuxppc-dev, sri_vatsa_v
Currently, only boot CPU calls do_timer to update jiffies. This prevents
idle boot CPU from skipping ticks. Patch below, against 2.6.17-rc1-mm1,
allows jiffies to be updated from any CPU.
Signed-off-by: Srivatsa Vaddagiri <vatsa@in.ibm.com>
---
linux-2.6.17-rc1-root/arch/powerpc/kernel/time.c | 22 ++++++++++------------
1 file changed, 10 insertions(+), 12 deletions(-)
diff -puN arch/powerpc/kernel/time.c~boot_cpu_fix arch/powerpc/kernel/time.c
--- linux-2.6.17-rc1/arch/powerpc/kernel/time.c~boot_cpu_fix 2006-04-07 04:13:53.000000000 +0530
+++ linux-2.6.17-rc1-root/arch/powerpc/kernel/time.c 2006-04-07 04:14:03.000000000 +0530
@@ -685,19 +685,17 @@ void timer_interrupt(struct pt_regs * re
if (!cpu_is_offline(cpu))
account_process_time(regs);
- /*
- * No need to check whether cpu is offline here; boot_cpuid
- * should have been fixed up by now.
- */
- if (cpu != boot_cpuid)
- continue;
-
write_seqlock(&xtime_lock);
- tb_last_jiffy += tb_ticks_per_jiffy;
- tb_last_stamp = per_cpu(last_jiffy, cpu);
- do_timer(regs);
- timer_recalc_offset(tb_last_jiffy);
- timer_check_rtc();
+ if (tb_ticks_since(tb_last_stamp) >= tb_ticks_per_jiffy) {
+ tb_last_jiffy += tb_ticks_per_jiffy;
+ tb_last_stamp += tb_ticks_per_jiffy;
+ /* Handle RTCL overflow on 601 */
+ if (__USE_RTC() && tb_last_stamp >= 1000000000)
+ tb_last_stamp -= 1000000000;
+ do_timer(regs);
+ timer_recalc_offset(tb_last_jiffy);
+ timer_check_rtc();
+ }
write_sequnlock(&xtime_lock);
}
_
--
Regards,
vatsa
^ permalink raw reply
* Re[2]: MPC5200 + LocalPlus Bus + memcpy
From: Andrey Volkov @ 2006-04-07 8:57 UTC (permalink / raw)
To: Sascha Hauer; +Cc: Sylvain Munaut, Paul Mackerras, Linuxppc-embedded
In-Reply-To: <20060407073701.GC10831@localhost.localdomain>
Hello, Sascha.
On Friday, April 7, 2006, Sascha Hauer wrote:
> Hello,
> On Thu, Apr 06, 2006 at 06:21:44PM +0400, Andrey Volkov wrote:
>> Hello, Sascha.
>>
>> On Wednesday, April 5, 2006, Sascha Hauer wrote:
>>
>> > Hi all,
>>
>> > I try to use jffs2 on a flash device connected to the mpc5200
>> > LocalPlus Bus. This bus does not allow misaligned accesses.
>> > The jffs2 code uses memcpy to copy from a word aligned address to an
>> > odd address. The ppc memcpy implementation first copies three bytes to get
>> > the target address word aligned, but then the source address is on an
>> > odd address. The following word accesses on this unaligned address fail
>> > badly.
>> Invalid crc on 'name' field ;)?
> Yes, exactly ;)
:)
>>
>> > I have fixed my problem by modifying the physmap mtd driver, but some
>> > day someone wants to connect SRAM to the LocalPlus Bus and I guess he
>> > will expect memcpy to work.
>> Heh, I'll have same problem. Patch (dirty hack)
>> attached (vs head of vanilla 2.6. tree)
>>
>> > (BTW the arm implementation of memcpy seems to work around this problem)
>> Wrong, memcpy to/from SDRAM _may_ be unaligned, only
>> memcpy_fromio/memcpy_toio _must_ be aligned to even addresses.
> Hm, then a proper fix would be:
> - implement an optimized version of memcpy_fromio/memcpy_toio, this
> could be a version of memcpy which only alignes on the io side
Yes.
> - use memcpy_fromio/memcpy_toio in jffs2 code
They already use it (from jffs2_read/write), only scan.c doesn't
calling this fns.
> Do I see this right?
Yes.
> Is SRAM considered io? I know (Arm-)Boards which do not have SDRAM, they
> run completely from SRAM.
Only LBP demand alignment, SDRAM/DDR and internal SRAM didn't.
--
Regards,
Andrey Volkov
^ permalink raw reply
* Re: RTC/I2C on 82xx with Linux 2.6.x
From: Claus Gindhart @ 2006-04-07 8:57 UTC (permalink / raw)
To: linuxppc-embedded
In-Reply-To: <003401c65a1b$915dac90$5201a8c0@GEG2400>
[-- Attachment #1: Type: text/plain, Size: 1403 bytes --]
Laurent,
attached you find a rtc-driver for 2.6.13.
I ported it from 2.4 myself, because i didnt find any 2.6-port out in the
world.
the ppc_md-structure entries are initialized within the driver itself. This is
propably not 100% consistent with the coding conventions, but it works fro
me.
This i2c-layer can still be used with this driver; i have a LM75 and an EEPROM
on the same bus, which i operate via LM-Sensors and the i2c-dev driver.
--
Mit freundlichen Gruessen / Best regards
Claus Gindhart
SW R&D
Kontron Modular Computers
phone :++49 (0)8341-803-374
mailto:claus.gindhart@kontron-modular.com
http://www.kontron.com
-----BEGIN GEEK CODE BLOCK-----
Version: 3.1
GU d- s++:>++:+ a+ C++$ !U !P L++>$ E-- W+(-) N- o?
K? w !O !M V !PS PE- Y+ PGP+ t 5? X R* tv- b+ DI+++
D-- G e++> h--- !r x+++
------END GEEK CODE BLOCK------
Am Friday 07 April 2006 10:16 schrieb Laurent Lagrange:
Hello,
I use a Linux 2.6.x on a custom 8270 board with a RTC on the I2C bus
(rtc8564).
I want to use it as the system date :
- Is it possible ?
- Do I need to initialize the "ppc_md" structure in the "platform_init"
function with my own RTC functions ?
- In that case, can I use the kernel I2C layer ?
Thanks all
Laurent
_______________________________________________
Linuxppc-embedded mailing list
Linuxppc-embedded@ozlabs.org
https://ozlabs.org/mailman/listinfo/linuxppc-embedded
[-- Attachment #2: rtc8564.c --]
[-- Type: text/x-csrc, Size: 11730 bytes --]
/*
* linux/drivers/i2c/chips/rtc8564.c
*
* Copyright (C) 2002-2004 Stefan Eletzhofer
*
* based on linux/drivers/acron/char/pcf8583.c
* Copyright (C) 2000 Russell King
*
* 2006.03.14 Claus Gindhart <claus.gindhart@kontron-modular.com>
* Added missing support for PowerPC and fix up for RTC update
* in interrupt mode (11 minute mode support)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 asr
* published by the Free Software Foundation.
*
* Driver for system3's EPSON RTC 8564 chip
*/
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/i2c.h>
#include <linux/slab.h>
#include <linux/string.h>
#include <linux/rtc.h> /* get the user-level API */
#include <linux/init.h>
#ifdef CONFIG_PPC
#include <asm/machdep.h>
#endif
#include "rtc8564.h"
/* prints out the time to be set, if activated */
#undef EXT_DEBUG
#ifdef DEBUG
# define _DBG(x, fmt, args...) do{ if (debug>=x) printk("%s: " fmt "\n", __FUNCTION__, ##args); } while(0);
#else
# define _DBG(x, fmt, args...) do { } while(0);
#endif
#define _DBGRTCTM(x, rtctm) if (debug>=x) printk(KERN_DEBUG"%s: secs=%d, mins=%d, hours=%d, mday=%d, " \
"mon=%d, year=%d, wday=%d VL=%d\n", __FUNCTION__, \
(rtctm).secs, (rtctm).mins, (rtctm).hours, (rtctm).mday, \
(rtctm).mon, (rtctm).year, (rtctm).wday, (rtctm).vl);
struct rtc8564_data {
struct i2c_client client;
u16 ctrl;
};
static inline u8 _rtc8564_ctrl1(struct i2c_client *client)
{
struct rtc8564_data *data = i2c_get_clientdata(client);
return data->ctrl & 0xff;
}
static inline u8 _rtc8564_ctrl2(struct i2c_client *client)
{
struct rtc8564_data *data = i2c_get_clientdata(client);
return (data->ctrl & 0xff00) >> 8;
}
#define CTRL1(c) _rtc8564_ctrl1(c)
#define CTRL2(c) _rtc8564_ctrl2(c)
#define BCD_TO_BIN(val) (((val)&15) + ((val)>>4)*10)
#define BIN_TO_BCD(val) ((((val)/10)<<4) + (val)%10)
static int debug;
module_param(debug, int, S_IRUGO | S_IWUSR);
DECLARE_MUTEX(rtc8564_sem);
static struct i2c_driver rtc8564_driver;
struct i2c_client *this_client;
static unsigned short ignore[] = { I2C_CLIENT_END };
static unsigned short normal_addr[] = { 0x51, I2C_CLIENT_END };
static struct i2c_client_address_data addr_data = {
.normal_i2c = normal_addr,
.probe = ignore,
.ignore = ignore,
.force = ignore,
};
static int rtc8564_read_mem(struct i2c_client *client, struct mem *mem);
static int rtc8564_write_mem(struct i2c_client *client, struct mem *mem);
static int rtc8564_recv(struct i2c_client *client,
unsigned char *buf, unsigned char addrs, unsigned char count)
{
int ret = -EIO;
unsigned char addr[1] = { addrs };
struct i2c_msg msgs[2] = {
{client->addr, 0, 1, addr},
{client->addr, I2C_M_RD, count, buf}
};
_DBG(1, "client=%p, addrs=%d, buf=%p, count=%d", client, addrs, buf, count);
if (!buf) {
ret = -EINVAL;
goto done;
}
ret = i2c_transfer(client->adapter, msgs, 2);
if (ret == 2) {
ret = 0;
}
done:
return ret;
}
static int rtc8564_write(struct i2c_client *client, unsigned char adr,
unsigned char *data, unsigned char len)
{
int ret = 0;
unsigned char _data[16];
struct i2c_msg wr;
int i;
if (!data || len > 15) {
ret = -EINVAL;
goto done;
}
_DBG(1, "client=%p, adr=%d, buf=%p, len=%d", client, adr, data, len);
_data[0] = adr;
for (i = 0; i < len; i++) {
_data[i + 1] = data[i];
_DBG(5, "data[%d] = 0x%02x (%d)", i, data[i], data[i]);
}
wr.addr = client->addr;
wr.flags = 0;
wr.len = len + 1;
wr.buf = _data;
ret = i2c_transfer(client->adapter, &wr, 1);
if (ret == 1) {
ret = 0;
}
done:
return ret;
}
static int rtc8564_get_datetime(struct i2c_client *client, struct rtc_tm *dt)
{
int ret = -EIO;
unsigned char buf[15];
_DBG(1, "client=%p, dt=%p", client, dt);
if (!dt)
return -EINVAL;
memset(buf, 0, sizeof(buf));
ret = rtc8564_recv(client, buf, 0, 15);
if (ret)
return ret;
/* century stored in minute alarm reg */
dt->year = BCD_TO_BIN(buf[RTC8564_REG_YEAR]);
dt->year += 100 * BCD_TO_BIN(buf[RTC8564_REG_AL_MIN] & 0x3f);
dt->mday = BCD_TO_BIN(buf[RTC8564_REG_DAY] & 0x3f);
dt->wday = BCD_TO_BIN(buf[RTC8564_REG_WDAY] & 7);
dt->mon = BCD_TO_BIN(buf[RTC8564_REG_MON_CENT] & 0x1f);
dt->secs = BCD_TO_BIN(buf[RTC8564_REG_SEC] & 0x7f);
dt->vl = (buf[RTC8564_REG_SEC] & 0x80) == 0x80;
dt->mins = BCD_TO_BIN(buf[RTC8564_REG_MIN] & 0x7f);
dt->hours = BCD_TO_BIN(buf[RTC8564_REG_HR] & 0x3f);
_DBGRTCTM(2, *dt);
return 0;
}
unsigned long ppc_rtc8564_get_time( void )
{
struct rtc_tm time;
int rc;
/* The only way to tell the user that rtc time is not reliable (?) */
if(!this_client)
return -1 /*RTC_24H | RTC_BATT_BAD */;
down(&rtc8564_sem);
rc = rtc8564_get_datetime(this_client,&time);
up(&rtc8564_sem);
if (rc)
{
return -1 /* RTC_24H | RTC_BATT_BAD */;
}
return mktime(time.year, time.mon, time.mday,
time.hours, time.mins, time.secs);
}
static int
rtc8564_set_datetime(struct i2c_client *client, struct rtc_tm *dt, int datetoo)
{
int ret, len = 5;
unsigned char buf[15];
_DBG(1, "client=%p, dt=%p", client, dt);
#ifdef EXT_DEBUG
printk("rtc8564_set_datetime %d\\%d\\%d %d:%d:%d, wday=%d\n",
dt->year,dt->mon,dt->mday,
dt->hours,dt->mins,dt->secs,dt->wday);
#endif
if (!dt)
return -EINVAL;
_DBGRTCTM(2, *dt);
buf[RTC8564_REG_CTRL1] = CTRL1(client) | RTC8564_CTRL1_STOP;
buf[RTC8564_REG_CTRL2] = CTRL2(client);
buf[RTC8564_REG_SEC] = BIN_TO_BCD(dt->secs);
buf[RTC8564_REG_MIN] = BIN_TO_BCD(dt->mins);
buf[RTC8564_REG_HR] = BIN_TO_BCD(dt->hours);
if (datetoo) {
len += 5;
buf[RTC8564_REG_DAY] = BIN_TO_BCD(dt->mday);
buf[RTC8564_REG_WDAY] = BIN_TO_BCD(dt->wday);
buf[RTC8564_REG_MON_CENT] = BIN_TO_BCD(dt->mon) & 0x1f;
/* century stored in minute alarm reg */
buf[RTC8564_REG_YEAR] = BIN_TO_BCD(dt->year % 100);
buf[RTC8564_REG_AL_MIN] = BIN_TO_BCD(dt->year / 100);
}
ret = rtc8564_write(client, 0, buf, len);
if (ret) {
_DBG(1, "error writing data! %d", ret);
}
buf[RTC8564_REG_CTRL1] = CTRL1(client);
ret = rtc8564_write(client, 0, buf, 1);
if (ret) {
_DBG(1, "error writing data! %d", ret);
}
return ret;
}
int rtc8564_set_time(struct rtc_time *time)
{
int rc;
struct rtc_tm dt;
#ifdef EXT_DEBUG
printk("rtc8564_set_time to %d\\%d\\%d %d:%d:%d\n",
time->tm_year,time->tm_mon,time->tm_mday,
time->tm_hour,time->tm_min,time->tm_sec);
#endif
down(&rtc8564_sem);
dt.secs = time->tm_sec;
dt.mins = time->tm_min;
dt.hours = time->tm_hour;
dt.wday = time->tm_wday;
dt.mday = time->tm_mday;
dt.mon = time->tm_mon;
dt.year = time->tm_year;
rc = rtc8564_set_datetime(this_client,&dt,1);
up(&rtc8564_sem);
return rc;
}
static void deferred_set_rtc(void *thistime)
{
struct rtc_time wtime;
unsigned long nowtime = (unsigned long) thistime;
to_tm(nowtime, &wtime);
rtc8564_set_time(&wtime);
return;
}
int ppc_rtc8564_set_time(unsigned long nowtime)
{
struct rtc_time wtime;
static DECLARE_WORK(set_rtc_work, deferred_set_rtc, NULL);
if (unlikely(in_interrupt())) {
/* because RTC works on interrupts (I2C access)
* we can't set time while we are during interrupt
* processing, so set must be done later.
*/
/* if previous setting is not done - cancel it
*/
cancel_delayed_work(&set_rtc_work);
set_rtc_work.data = (void *)nowtime;
schedule_work(&set_rtc_work);
/* unfortunatelly, we can't wait till work_queue
* will be executed - lets assume it will return 0
*/
return 0;
}
to_tm(nowtime, &wtime);
/* wtime probably needs some fiddling here (year -= 1900 etc.) */
/* Be aware that adjtime uses /dev/port for rtc access: x86 only! */
return rtc8564_set_time(&wtime);
}
static int rtc_8564_probe(struct i2c_adapter *adap, int addr, int kind)
{
int ret;
struct i2c_client *new_client;
struct rtc8564_data *d;
unsigned char data[10];
unsigned char ad[1] = { 0 };
struct i2c_msg ctrl_wr[1] = {
{addr, 0, 2, data}
};
struct i2c_msg ctrl_rd[2] = {
{addr, 0, 1, ad},
{addr, I2C_M_RD, 2, data}
};
d = kmalloc(sizeof(struct rtc8564_data), GFP_KERNEL);
if (!d) {
ret = -ENOMEM;
goto done;
}
memset(d, 0, sizeof(struct rtc8564_data));
new_client = &d->client;
strlcpy(new_client->name, "RTC8564", I2C_NAME_SIZE);
i2c_set_clientdata(new_client, d);
new_client->flags = I2C_CLIENT_ALLOW_USE | I2C_DF_NOTIFY;
new_client->addr = addr;
new_client->adapter = adap;
new_client->driver = &rtc8564_driver;
_DBG(1, "client=%p", new_client);
/* init ctrl1 reg */
data[0] = 0;
data[1] = 0;
ret = i2c_transfer(new_client->adapter, ctrl_wr, 1);
if (ret != 1) {
printk(KERN_ERR "rtc8564: cant init ctrl1\n");
ret = -ENODEV;
goto done;
}
/* read back ctrl1 and ctrl2 */
ret = i2c_transfer(new_client->adapter, ctrl_rd, 2);
if (ret != 2) {
printk(KERN_ERR "rtc8564: cant read ctrl\n");
ret = -ENODEV;
goto done;
}
d->ctrl = data[0] | (data[1] << 8);
_DBG(1, "RTC8564_REG_CTRL1=%02x, RTC8564_REG_CTRL2=%02x",
data[0], data[1]);
ret = i2c_attach_client(new_client);
done:
if (ret) {
kfree(d);
}
this_client = new_client;
#ifdef CONFIG_PPC
/* Hook up the wrapper to machdep for 11-minute mode support */
ppc_md.set_rtc_time = ppc_rtc8564_set_time;
ppc_md.get_rtc_time = ppc_rtc8564_get_time;
#endif
return ret;
}
static int rtc_8564_attach(struct i2c_adapter *adap)
{
return i2c_probe(adap, &addr_data, rtc_8564_probe);
}
static int rtc8564_detach(struct i2c_client *client)
{
i2c_detach_client(client);
kfree(i2c_get_clientdata(client));
return 0;
}
static int rtc8564_get_ctrl(struct i2c_client *client, unsigned int *ctrl)
{
struct rtc8564_data *data = i2c_get_clientdata(client);
if (!ctrl)
return -1;
*ctrl = data->ctrl;
return 0;
}
static int rtc8564_set_ctrl(struct i2c_client *client, unsigned int *ctrl)
{
struct rtc8564_data *data = i2c_get_clientdata(client);
unsigned char buf[2];
if (!ctrl)
return -1;
buf[0] = *ctrl & 0xff;
buf[1] = (*ctrl & 0xff00) >> 8;
data->ctrl = *ctrl;
return rtc8564_write(client, 0, buf, 2);
}
static int rtc8564_read_mem(struct i2c_client *client, struct mem *mem)
{
if (!mem)
return -EINVAL;
return rtc8564_recv(client, mem->data, mem->loc, mem->nr);
}
static int rtc8564_write_mem(struct i2c_client *client, struct mem *mem)
{
if (!mem)
return -EINVAL;
return rtc8564_write(client, mem->loc, mem->data, mem->nr);
}
static int
rtc8564_command(struct i2c_client *client, unsigned int cmd, void *arg)
{
int rc;
_DBG(1, "cmd=%d", cmd);
down(&rtc8564_sem);
switch (cmd) {
case RTC_GETDATETIME:
rc = rtc8564_get_datetime(client, arg);
break;
case RTC_SETTIME:
rc = rtc8564_set_datetime(client, arg, 0);
break;
case RTC_SETDATETIME:
rc = rtc8564_set_datetime(client, arg, 1);
break;
case RTC_GETCTRL:
rc = rtc8564_get_ctrl(client, arg);
break;
case RTC_SETCTRL:
rc = rtc8564_set_ctrl(client, arg);
break;
case MEM_READ:
rc = rtc8564_read_mem(client, arg);
break;
case MEM_WRITE:
rc = rtc8564_write_mem(client, arg);
break;
default:
rc = -EINVAL;
break;
}
up(&rtc8564_sem);
return rc;
}
static struct i2c_driver rtc8564_driver = {
.owner = THIS_MODULE,
.name = "RTC8564",
.id = I2C_DRIVERID_RTC8564,
.flags = I2C_DF_NOTIFY,
.attach_adapter = rtc_8564_attach,
.detach_client = rtc8564_detach,
.command = rtc8564_command
};
static __init int rtc8564_init(void)
{
return i2c_add_driver(&rtc8564_driver);
}
static __exit void rtc8564_exit(void)
{
i2c_del_driver(&rtc8564_driver);
}
MODULE_AUTHOR("Stefan Eletzhofer <Stefan.Eletzhofer@eletztrick.de>");
MODULE_DESCRIPTION("EPSON RTC8564 Driver");
MODULE_LICENSE("GPL");
module_init(rtc8564_init);
module_exit(rtc8564_exit);
[-- Attachment #3: rtc8564.h --]
[-- Type: text/x-chdr, Size: 2356 bytes --]
/*
* linux/drivers/i2c/chips/rtc8564.h
*
* Copyright (C) 2002-2004 Stefan Eletzhofer
*
* based on linux/drivers/acron/char/pcf8583.h
* Copyright (C) 2000 Russell King
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
struct rtc_tm {
unsigned char secs;
unsigned char mins;
unsigned char hours;
unsigned char mday;
unsigned char mon;
unsigned short year; /* xxxx 4 digits :) */
unsigned char wday;
unsigned char vl;
};
struct mem {
unsigned int loc;
unsigned int nr;
unsigned char *data;
};
#define RTC_GETDATETIME 0
#define RTC_SETTIME 1
#define RTC_SETDATETIME 2
#define RTC_GETCTRL 3
#define RTC_SETCTRL 4
#define MEM_READ 5
#define MEM_WRITE 6
#define RTC8564_REG_CTRL1 0x0 /* T 0 S 0 | T 0 0 0 */
#define RTC8564_REG_CTRL2 0x1 /* 0 0 0 TI/TP | AF TF AIE TIE */
#define RTC8564_REG_SEC 0x2 /* VL 4 2 1 | 8 4 2 1 */
#define RTC8564_REG_MIN 0x3 /* x 4 2 1 | 8 4 2 1 */
#define RTC8564_REG_HR 0x4 /* x x 2 1 | 8 4 2 1 */
#define RTC8564_REG_DAY 0x5 /* x x 2 1 | 8 4 2 1 */
#define RTC8564_REG_WDAY 0x6 /* x x x x | x 4 2 1 */
#define RTC8564_REG_MON_CENT 0x7 /* C x x 1 | 8 4 2 1 */
#define RTC8564_REG_YEAR 0x8 /* 8 4 2 1 | 8 4 2 1 */
#define RTC8564_REG_AL_MIN 0x9 /* AE 4 2 1 | 8 4 2 1 */
#define RTC8564_REG_AL_HR 0xa /* AE 4 2 1 | 8 4 2 1 */
#define RTC8564_REG_AL_DAY 0xb /* AE x 2 1 | 8 4 2 1 */
#define RTC8564_REG_AL_WDAY 0xc /* AE x x x | x 4 2 1 */
#define RTC8564_REG_CLKOUT 0xd /* FE x x x | x x FD1 FD0 */
#define RTC8564_REG_TCTL 0xe /* TE x x x | x x FD1 FD0 */
#define RTC8564_REG_TIMER 0xf /* 8 bit binary */
/* Control reg */
#define RTC8564_CTRL1_TEST1 (1<<3)
#define RTC8564_CTRL1_STOP (1<<5)
#define RTC8564_CTRL1_TEST2 (1<<7)
#define RTC8564_CTRL2_TIE (1<<0)
#define RTC8564_CTRL2_AIE (1<<1)
#define RTC8564_CTRL2_TF (1<<2)
#define RTC8564_CTRL2_AF (1<<3)
#define RTC8564_CTRL2_TI_TP (1<<4)
/* CLKOUT frequencies */
#define RTC8564_FD_32768HZ (0x0)
#define RTC8564_FD_1024HZ (0x1)
#define RTC8564_FD_32 (0x2)
#define RTC8564_FD_1HZ (0x3)
/* Timer CTRL */
#define RTC8564_TD_4096HZ (0x0)
#define RTC8564_TD_64HZ (0x1)
#define RTC8564_TD_1HZ (0x2)
#define RTC8564_TD_1_60HZ (0x3)
#define I2C_DRIVERID_RTC8564 0xf000
^ permalink raw reply
* Re: [PATCH] spufs: fix compile
From: Christoph Hellwig @ 2006-04-07 11:54 UTC (permalink / raw)
To: arndb; +Cc: linuxppc-dev
In-Reply-To: <20060406134810.GB8552@lst.de>
On Thu, Apr 06, 2006 at 03:48:10PM +0200, Christoph Hellwig wrote:
> The current tree isn't exctly sure about the arguments to
> alloc_spu_context, let it agree on the no-arguments version.
Please ignore all these patches, I had a messed up tree.
^ permalink raw reply
* Re: [PATCH 2/4] tickless idle cpu: Skip ticks when CPU is idle
From: Kumar Gala @ 2006-04-07 14:16 UTC (permalink / raw)
To: vatsa; +Cc: sri_vatsa_v, paulus, linuxppc-dev
In-Reply-To: <20060407063131.GB22416@in.ibm.com>
On Apr 7, 2006, at 1:31 AM, Srivatsa Vaddagiri wrote:
> This is the core patch which skips ticks when a CPU is idle.
> Should work on pSeries, pmac and maple machines.
>
> The patch is against 2.6.17-rc1-mm1 and has been tested on a 16-way
> (with SMT)
> Power5 box (p570).
>
> Signed-off-by: Srivatsa Vaddagiri <vatsa@in.ibm.com>
>
> ---
>
> linux-2.6.17-rc1-root/arch/powerpc/Kconfig | 6
> linux-2.6.17-rc1-root/arch/powerpc/kernel/idle_power4.S | 3
> linux-2.6.17-rc1-root/arch/powerpc/kernel/irq.c | 3
> linux-2.6.17-rc1-root/arch/powerpc/kernel/time.c |
> 150 ++++++++---
> linux-2.6.17-rc1-root/arch/powerpc/kernel/traps.c | 1
> linux-2.6.17-rc1-root/arch/powerpc/platforms/pseries/setup.c | 6
> linux-2.6.17-rc1-root/include/asm-powerpc/time.h | 8
> 7 files changed, 147 insertions(+), 30 deletions(-)
>
[snip]
> diff -puN arch/powerpc/Kconfig~no_idle_hz arch/powerpc/Kconfig
> --- linux-2.6.17-rc1/arch/powerpc/Kconfig~no_idle_hz 2006-04-07
> 04:14:39.000000000 +0530
> +++ linux-2.6.17-rc1-root/arch/powerpc/Kconfig 2006-04-07
> 04:14:58.000000000 +0530
> @@ -593,6 +593,12 @@ config HOTPLUG_CPU
>
> Say N if you are unsure.
>
> +config NO_IDLE_HZ
> + depends on EXPERIMENTAL && (PPC_PSERIES || PPC_PMAC || PPC_MAPLE)
> + bool "Switch off timer ticks on idle CPUs"
> + help
> + Switches the HZ timer interrupts off when a CPU is idle.
> +
any reason not to provide this for all 6xx class processors?
> config KEXEC
> bool "kexec system call (EXPERIMENTAL)"
> depends on PPC_MULTIPLATFORM && EXPERIMENTAL
^ permalink raw reply
* [PATCH 0/5] cell: recent bug fixes
From: arnd @ 2006-04-07 15:01 UTC (permalink / raw)
To: Paul Mackerras; +Cc: linuxppc-dev, cbe-oss-dev
This set of patches is mostly about making it possible to use
64k pages on the Cell platform, which did not work because
of a number of bugs.
Paulus, please apply to your bugfix tree.
Arnd <><
^ permalink raw reply
* Re: RTC/I2C on 82xx with Linux 2.6.x
From: Mark A. Greer @ 2006-04-07 15:17 UTC (permalink / raw)
To: Claus Gindhart; +Cc: linuxppc-embedded
In-Reply-To: <200604071057.26265.claus.gindhart@kontron-modular.com>
On Fri, Apr 07, 2006 at 10:57:25AM +0200, Claus Gindhart wrote:
> Laurent,
>
> attached you find a rtc-driver for 2.6.13.
> I ported it from 2.4 myself, because i didnt find any 2.6-port out in the
> world.
> the ppc_md-structure entries are initialized within the driver itself. This is
> propably not 100% consistent with the coding conventions, but it works fro
> me.
> This i2c-layer can still be used with this driver; i have a LM75 and an EEPROM
> on the same bus, which i operate via LM-Sensors and the i2c-dev driver.
Note that there is a drivers/rtc directory that new (and old) rtc drivers
should be ported to.
Mark
^ permalink raw reply
* Re: [PATCH 4/5] powerpc: export symbols for page size selection
From: Christoph Hellwig @ 2006-04-07 15:28 UTC (permalink / raw)
To: arnd; +Cc: linuxppc-dev, Paul Mackerras, cbe-oss-dev, Arnd Bergmann
In-Reply-To: <20060407150743.688538000@dyn-9-152-242-103.boeblingen.de.ibm.com>
On Fri, Apr 07, 2006 at 12:00:04AM +0200, arnd@arndb.de wrote:
> We need access to some symbols in powerpc memory management
> from spufs in order to create proper SLB entries.
One more reason to disallow modular spufs..
^ permalink raw reply
* Re: [PATCH 4/5] powerpc: export symbols for page size selection
From: Olof Johansson @ 2006-04-07 15:42 UTC (permalink / raw)
To: Christoph Hellwig
Cc: linuxppc-dev, Paul Mackerras, cbe-oss-dev, Arnd Bergmann
In-Reply-To: <20060407152813.GA382@lst.de>
On Fri, Apr 07, 2006 at 05:28:13PM +0200, Christoph Hellwig wrote:
> On Fri, Apr 07, 2006 at 12:00:04AM +0200, arnd@arndb.de wrote:
> > We need access to some symbols in powerpc memory management
> > from spufs in order to create proper SLB entries.
>
> One more reason to disallow modular spufs..
Yeah, what's the need for that, really? It needs to know so much of
kernel internals that it's getting silly to allow it to be a module.
-Olof
^ permalink raw reply
* Re: [Cbe-oss-dev] [PATCH 4/5] powerpc: export symbols for page size selection
From: Geoff Levand @ 2006-04-07 15:54 UTC (permalink / raw)
To: Olof Johansson; +Cc: Arnd Bergmann, linuxppc-dev, cbe-oss-dev
In-Reply-To: <20060407154247.GJ952@pb15.lixom.net>
Olof Johansson wrote:
> On Fri, Apr 07, 2006 at 05:28:13PM +0200, Christoph Hellwig wrote:
>> On Fri, Apr 07, 2006 at 12:00:04AM +0200, arnd@arndb.de wrote:
>> > We need access to some symbols in powerpc memory management
>> > from spufs in order to create proper SLB entries.
>>
>> One more reason to disallow modular spufs..
>
> Yeah, what's the need for that, really? It needs to know so much of
> kernel internals that it's getting silly to allow it to be a module.
We never used that feature either...
-Geoff
^ permalink raw reply
* Re: [Cbe-oss-dev] [PATCH 4/5] powerpc: export symbols for page size selection
From: Arnd Bergmann @ 2006-04-07 16:03 UTC (permalink / raw)
To: cbe-oss-dev; +Cc: linuxppc-dev
In-Reply-To: <20060407154247.GJ952@pb15.lixom.net>
On Friday 07 April 2006 17:42, Olof Johansson wrote:
> Yeah, what's the need for that, really? It needs to know so much of
> kernel internals that it's getting silly to allow it to be a module.
>
It's still quite handy to have the actual file system as a module,
because
a) the module is rather bloated atm, it's about 200kb including the
embedded spu code that it runs for context switch. I don't want
to burden the generic distros with that
b) It simplifies development a bit to not have to reload the whole
kernel when making changes. Booting with all the HW debugger stuff
enabled takes quite a bit of time, especially when you have to
tunnel the binaries through our internal network ;-).
We currently have two modules, and the base module has most of the
stuff that has dependencies on exported symbols. The binary is
25k on my system (with some debugging options enabled).
How about if I do a patch that always includes the base but not
the actual file system?
Arnd <><
^ permalink raw reply
* Re: [Cbe-oss-dev] [PATCH 4/5] powerpc: export symbols for page size selection
From: Olof Johansson @ 2006-04-07 16:20 UTC (permalink / raw)
To: Arnd Bergmann; +Cc: linuxppc-dev, cbe-oss-dev
In-Reply-To: <200604071803.01836.arnd.bergmann@de.ibm.com>
On Fri, Apr 07, 2006 at 06:03:01PM +0200, Arnd Bergmann wrote:
> On Friday 07 April 2006 17:42, Olof Johansson wrote:
> > Yeah, what's the need for that, really? It needs to know so much of
> > kernel internals that it's getting silly to allow it to be a module.
>
> How about if I do a patch that always includes the base but not
> the actual file system?
Sounds like a decent tradeoff.
-Olof
^ permalink raw reply
* Re: [Cbe-oss-dev] [PATCH 4/5] powerpc: export symbols for page size selection
From: Arnd Bergmann @ 2006-04-07 16:49 UTC (permalink / raw)
To: cbe-oss-dev; +Cc: linuxppc-dev, Mark Nutter
In-Reply-To: <20060407162026.GK952@pb15.lixom.net>
On Friday 07 April 2006 18:20, Olof Johansson wrote:
> On Fri, Apr 07, 2006 at 06:03:01PM +0200, Arnd Bergmann wrote:
> > On Friday 07 April 2006 17:42, Olof Johansson wrote:
> > > Yeah, what's the need for that, really? It needs to know so much of
> > > kernel internals that it's getting silly to allow it to be a module.
> >
> > How about if I do a patch that always includes the base but not
> > the actual file system?
>
> Sounds like a decent tradeoff.
>
Unfortunately, this one doesn't get rid of the need to have the
exports, since the context switch code also needs mmu_psize_defs
and the associated objects. I think I have to come up with
a different change for that, but I don't mind putting the base
stuff into the kernel in the first place.
Mark has some changes to the file layout pending that will
impact this as well. I first need to see how that works out
together.
The patch to make the base non-modular is trivial, so we might
as well apply it now.
Arnd <><
Index: linus-2.6/arch/powerpc/platforms/cell/Makefile
===================================================================
--- linus-2.6.orig/arch/powerpc/platforms/cell/Makefile
+++ linus-2.6/arch/powerpc/platforms/cell/Makefile
@@ -2,15 +2,13 @@ obj-y += interrupt.o iommu.o setup.o s
obj-y += pervasive.o
obj-$(CONFIG_SMP) += smp.o
-obj-$(CONFIG_SPU_FS) += spu-base.o spufs/
-
-spu-base-y += spu_base.o spu_priv1.o
+obj-$(CONFIG_SPU_FS) += spufs/
# needed only when building loadable spufs.ko
spufs-modular-$(CONFIG_SPU_FS) += spu_syscalls.o
obj-y += $(spufs-modular-m)
# always needed in kernel
-spufs-builtin-$(CONFIG_SPU_FS) += spu_callbacks.o
+spufs-builtin-$(CONFIG_SPU_FS) += spu_callbacks.o spu_base.o spu_priv1.o
obj-y += $(spufs-builtin-y) $(spufs-builtin-m)
^ permalink raw reply
* [PATCH] powerpc/pseries: clear PCI failure counter if no new failures.
From: Linas Vepstas @ 2006-04-07 21:18 UTC (permalink / raw)
To: Paul Mackerras; +Cc: linuxppc-dev, linux-pci, linux-kernel
[PATCH] powerpc/pseries: clear PCI failure counter if no new failures.
The current PCI error recovery system keeps track of the number of
PCI card resets, and refuses to bring a card back up if this number
is too large. The goal of doing this was to avoid an infinite loop
of resets if a card is obviously dead. However, if the failures are
rare, but the machine has a high uptime, this mechanism might still
be triggered; this is too harsh.
This patch will avoids this problem by decrementing the fail count
after an hour. Thus, as long as a pci card BSOD's less than 6 times
an hour, it will continue to be reset indefinitely. If it's failure
rate is greater than that, it will be taken off-line permanently.
This patch is larger than it might otherwise be because it
changes indentation by removing a pointless while-loop. The while
loop is not needed, as the handler is invoked once fo each event
(by schedule_work()); the loop is leftover cruft from an earlier
implementation.
Signed-off-by: Linas Vepstas <linas@austin.ibm.com>
----
arch/powerpc/platforms/pseries/eeh_driver.c | 13 +++---
arch/powerpc/platforms/pseries/eeh_event.c | 60 +++++++++++++++-------------
include/asm-powerpc/eeh_event.h | 10 ++--
3 files changed, 45 insertions(+), 38 deletions(-)
Index: linux-2.6.17-rc1/arch/powerpc/platforms/pseries/eeh_driver.c
===================================================================
--- linux-2.6.17-rc1.orig/arch/powerpc/platforms/pseries/eeh_driver.c 2006-04-04 15:28:59.000000000 -0500
+++ linux-2.6.17-rc1/arch/powerpc/platforms/pseries/eeh_driver.c 2006-04-07 16:08:27.000000000 -0500
@@ -23,9 +23,8 @@
*
*/
#include <linux/delay.h>
-#include <linux/irq.h>
#include <linux/interrupt.h>
-#include <linux/notifier.h>
+#include <linux/irq.h>
#include <linux/pci.h>
#include <asm/eeh.h>
#include <asm/eeh_event.h>
@@ -250,7 +249,7 @@ static int eeh_reset_device (struct pci_
*/
#define MAX_WAIT_FOR_RECOVERY 15
-void handle_eeh_events (struct eeh_event *event)
+struct pci_dn * handle_eeh_events (struct eeh_event *event)
{
struct device_node *frozen_dn;
struct pci_dn *frozen_pdn;
@@ -265,7 +264,7 @@ void handle_eeh_events (struct eeh_event
if (!frozen_dn) {
printk(KERN_ERR "EEH: Error: Cannot find partition endpoint for %s\n",
pci_name(event->dev));
- return;
+ return NULL;
}
/* There are two different styles for coming up with the PE.
@@ -280,7 +279,7 @@ void handle_eeh_events (struct eeh_event
if (!frozen_bus) {
printk(KERN_ERR "EEH: Cannot find PCI bus for %s\n",
frozen_dn->full_name);
- return;
+ return NULL;
}
#if 0
@@ -355,7 +354,7 @@ void handle_eeh_events (struct eeh_event
/* Tell all device drivers that they can resume operations */
pci_walk_bus(frozen_bus, eeh_report_resume, NULL);
- return;
+ return frozen_pdn;
excess_failures:
/*
@@ -384,6 +383,8 @@ perm_error:
/* Shut down the device drivers for good. */
pcibios_remove_pci_devices(frozen_bus);
+
+ return NULL;
}
/* ---------- end of file ---------- */
Index: linux-2.6.17-rc1/arch/powerpc/platforms/pseries/eeh_event.c
===================================================================
--- linux-2.6.17-rc1.orig/arch/powerpc/platforms/pseries/eeh_event.c 2006-04-04 15:28:59.000000000 -0500
+++ linux-2.6.17-rc1/arch/powerpc/platforms/pseries/eeh_event.c 2006-04-05 09:56:38.000000000 -0500
@@ -18,6 +18,7 @@
* Copyright (c) 2005 Linas Vepstas <linas@linas.org>
*/
+#include <linux/delay.h>
#include <linux/list.h>
#include <linux/mutex.h>
#include <linux/pci.h>
@@ -56,38 +57,43 @@ static int eeh_event_handler(void * dumm
{
unsigned long flags;
struct eeh_event *event;
+ struct pci_dn *pdn;
daemonize ("eehd");
+ set_current_state(TASK_INTERRUPTIBLE);
- while (1) {
- set_current_state(TASK_INTERRUPTIBLE);
+ spin_lock_irqsave(&eeh_eventlist_lock, flags);
+ event = NULL;
+
+ /* Unqueue the event, get ready to process. */
+ if (!list_empty(&eeh_eventlist)) {
+ event = list_entry(eeh_eventlist.next, struct eeh_event, list);
+ list_del(&event->list);
+ }
+ spin_unlock_irqrestore(&eeh_eventlist_lock, flags);
- spin_lock_irqsave(&eeh_eventlist_lock, flags);
- event = NULL;
+ if (event == NULL)
+ return 0;
- /* Unqueue the event, get ready to process. */
- if (!list_empty(&eeh_eventlist)) {
- event = list_entry(eeh_eventlist.next, struct eeh_event, list);
- list_del(&event->list);
- }
- spin_unlock_irqrestore(&eeh_eventlist_lock, flags);
-
- if (event == NULL)
- break;
-
- /* Serialize processing of EEH events */
- mutex_lock(&eeh_event_mutex);
- eeh_mark_slot(event->dn, EEH_MODE_RECOVERING);
-
- printk(KERN_INFO "EEH: Detected PCI bus error on device %s\n",
- pci_name(event->dev));
-
- handle_eeh_events(event);
-
- eeh_clear_slot(event->dn, EEH_MODE_RECOVERING);
- pci_dev_put(event->dev);
- kfree(event);
- mutex_unlock(&eeh_event_mutex);
+ /* Serialize processing of EEH events */
+ mutex_lock(&eeh_event_mutex);
+ eeh_mark_slot(event->dn, EEH_MODE_RECOVERING);
+
+ printk(KERN_INFO "EEH: Detected PCI bus error on device %s\n",
+ pci_name(event->dev));
+
+ pdn = handle_eeh_events(event);
+
+ eeh_clear_slot(event->dn, EEH_MODE_RECOVERING);
+ pci_dev_put(event->dev);
+ kfree(event);
+ mutex_unlock(&eeh_event_mutex);
+
+ /* If there are no new errors after an hour, clear the counter. */
+ if (pdn && pdn->eeh_freeze_count>0) {
+ msleep_interruptible (3600*1000);
+ if (pdn->eeh_freeze_count>0)
+ pdn->eeh_freeze_count--;
}
return 0;
Index: linux-2.6.17-rc1/include/asm-powerpc/eeh_event.h
===================================================================
--- linux-2.6.17-rc1.orig/include/asm-powerpc/eeh_event.h 2006-03-19 23:53:29.000000000 -0600
+++ linux-2.6.17-rc1/include/asm-powerpc/eeh_event.h 2006-04-04 15:37:22.000000000 -0500
@@ -18,8 +18,8 @@
* Copyright (c) 2005 Linas Vepstas <linas@linas.org>
*/
-#ifndef ASM_PPC64_EEH_EVENT_H
-#define ASM_PPC64_EEH_EVENT_H
+#ifndef ASM_POWERPC_EEH_EVENT_H
+#define ASM_POWERPC_EEH_EVENT_H
#ifdef __KERNEL__
/** EEH event -- structure holding pci controller data that describes
@@ -39,7 +39,7 @@ struct eeh_event {
* @dev pci device
*
* This routine builds a PCI error event which will be delivered
- * to all listeners on the peh_notifier_chain.
+ * to all listeners on the eeh_notifier_chain.
*
* This routine can be called within an interrupt context;
* the actual event will be delivered in a normal context
@@ -51,7 +51,7 @@ int eeh_send_failure_event (struct devic
int time_unavail);
/* Main recovery function */
-void handle_eeh_events (struct eeh_event *);
+struct pci_dn * handle_eeh_events (struct eeh_event *);
#endif /* __KERNEL__ */
-#endif /* ASM_PPC64_EEH_EVENT_H */
+#endif /* ASM_POWERPC_EEH_EVENT_H */
^ permalink raw reply
* Re: question about Linux 2.6 with Xilinx ML-403
From: Grant Likely @ 2006-04-07 22:18 UTC (permalink / raw)
To: yding, linuxppc-embedded list
In-Reply-To: <4436BD2B.9050306@lnxw.com>
On 4/7/06, yding <yding@lnxw.com> wrote:
> HI, Grant,
>
> I found this message :
> http://patchwork.ozlabs.org/linuxppc/patch?id=3D3841 on
> Internet.
> It looks like you created some patch files for supporting Linux 2.6 with
> Xilinx ML-403.
>
> how can download the whole kernel source tree with your patched files (vi=
a
> cvs or bitkeeper) ?
I believe they are now in Linus' mainline git tree. If not, they are
in Paul's powerpc git tree.
BTW, please CC the linuxppc-embedded mailing list when emailing me directly=
.
Cheers,
g.
--
Grant Likely, B.Sc. P.Eng.
Secret Lab Technologies Ltd.
(403) 399-0195
^ permalink raw reply
* Virtex-4 FX12 Mini-Module support
From: Aidan Williams @ 2006-04-07 22:42 UTC (permalink / raw)
To: linuxppc-embedded
In-Reply-To: <4418EA57.6060308@petalogix.com>
[-- Attachment #1: Type: text/plain, Size: 828 bytes --]
Hi All,
I'm using the UQ powerpc uclinux code on the
Memec Virtex-4 FX12 Mini-Module Development Kit.
I have attached a patch with our modifications:
- switch to set cache policy (OFF, WriteThru, WriteBack)
- switch to enable PPC405 CPU_213 errata workaround
- cosmetic update to cputable
- view ccr0 register in /proc/cpu
The patch is against:
http://www.itee.uq.edu.au/~pml/uclinux_powerpc/linuxppc-2.4-20051021.tgz
The specific modules/chips we're using have a silicon bug,
See the euphemistically named "Solution 13:"
http://www.xilinx.com/xlnx/xil_ans_display.jsp?iLanguageID=1&iCountryID=1&getPagePath=20658
The board boots and runs reliably with the caches OFF.
WriteThru and WriteBack caching cause memory corruption and
this is why we implemented the cache policy switch.
regards
aidan
____
:wq!
[-- Attachment #2: virtex-4-fx12-minimodule.txt --]
[-- Type: plain/text, Size: 23729 bytes --]
^ permalink raw reply
* Re: [PATCH 1/4] tickless idle cpu - Allow any CPU to update jiffies
From: Paul Mackerras @ 2006-04-07 23:04 UTC (permalink / raw)
To: vatsa; +Cc: sri_vatsa_v, linuxppc-dev
In-Reply-To: <20060407063044.GA22416@in.ibm.com>
Srivatsa Vaddagiri writes:
> Currently, only boot CPU calls do_timer to update jiffies. This prevents
> idle boot CPU from skipping ticks. Patch below, against 2.6.17-rc1-mm1,
> allows jiffies to be updated from any CPU.
We have to be very careful here. The code that keeps xtime and
gettimeofday in sync relies on xtime being incremented as close as
possible in time to when the timebase passes specific values. Since
we currently stagger the timer interrupts for the cpus throughout a
jiffy, having cpus other than the boot cpus calling do_timer will
break this and introduce inaccuracies. There are also implications
for the stolen time accounting on shared-processor LPAR systems.
I think we need to remove the staggering, thus having all cpus take
their timer interrupt at the same time. That way, any of them can
call do_timer. However we then have to be much more careful about
possible contention, e.g. on xtime_lock. Your patch has every cpu
taking xtime_lock for writing rather than just the boot cpu. I'd like
to see if there is some way to avoid that (while still having just one
cpu call do_timer, of course).
Regards,
Paul.
^ permalink raw reply
* Re: [PATCH] PCI Error Recovery: e100 network device driver
From: Linas Vepstas @ 2006-04-07 23:11 UTC (permalink / raw)
To: Greg KH
Cc: netdev, linux-kernel, jesse.brandeburg, linuxppc-dev,
john.ronciak, jeffrey.t.kirsher, linux-pci, Jeff Garzik
In-Reply-To: <20060406224643.GA6278@kroah.com>
On Thu, Apr 06, 2006 at 03:46:43PM -0700, Greg KH wrote:
> On Thu, Apr 06, 2006 at 05:24:00PM -0500, Linas Vepstas wrote:
> > + if(pci_enable_device(pdev)) {
>
> Add a space after "if" and before "(" please.
I guess I'm immune to learning from experience. :-/
Here's a new improved patch.
--linas
[PATCH] PCI Error Recovery: e100 network device driver
Various PCI bus errors can be signaled by newer PCI controllers. This
patch adds the PCI error recovery callbacks to the intel ethernet e100
device driver. The patch has been tested, and appears to work well.
Signed-off-by: Linas Vepstas <linas@linas.org>
Acked-by: Jesse Brandeburg <jesse.brandeburg@intel.com>
----
drivers/net/e100.c | 75 +++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 75 insertions(+)
Index: linux-2.6.17-rc1/drivers/net/e100.c
===================================================================
--- linux-2.6.17-rc1.orig/drivers/net/e100.c 2006-04-07 16:21:46.000000000 -0500
+++ linux-2.6.17-rc1/drivers/net/e100.c 2006-04-07 18:10:52.411266545 -0500
@@ -2780,6 +2780,80 @@ static void e100_shutdown(struct pci_dev
DPRINTK(PROBE,ERR, "Error enabling wake\n");
}
+/* ------------------ PCI Error Recovery infrastructure -------------- */
+/**
+ * e100_io_error_detected - called when PCI error is detected.
+ * @pdev: Pointer to PCI device
+ * @state: The current pci conneection state
+ */
+static pci_ers_result_t e100_io_error_detected(struct pci_dev *pdev, pci_channel_state_t state)
+{
+ struct net_device *netdev = pci_get_drvdata(pdev);
+
+ /* Similar to calling e100_down(), but avoids adpater I/O. */
+ netdev->stop(netdev);
+
+ /* Detach; put netif into state similar to hotplug unplug. */
+ netif_poll_enable(netdev);
+ netif_device_detach(netdev);
+
+ /* Request a slot reset. */
+ return PCI_ERS_RESULT_NEED_RESET;
+}
+
+/**
+ * e100_io_slot_reset - called after the pci bus has been reset.
+ * @pdev: Pointer to PCI device
+ *
+ * Restart the card from scratch.
+ */
+static pci_ers_result_t e100_io_slot_reset(struct pci_dev *pdev)
+{
+ struct net_device *netdev = pci_get_drvdata(pdev);
+ struct nic *nic = netdev_priv(netdev);
+
+ if (pci_enable_device(pdev)) {
+ printk(KERN_ERR "e100: Cannot re-enable PCI device after reset.\n");
+ return PCI_ERS_RESULT_DISCONNECT;
+ }
+ pci_set_master(pdev);
+
+ /* Only one device per card can do a reset */
+ if (0 != PCI_FUNC(pdev->devfn))
+ return PCI_ERS_RESULT_RECOVERED;
+ e100_hw_reset(nic);
+ e100_phy_init(nic);
+
+ return PCI_ERS_RESULT_RECOVERED;
+}
+
+/**
+ * e100_io_resume - resume normal operations
+ * @pdev: Pointer to PCI device
+ *
+ * Resume normal operations after an error recovery
+ * sequence has been completed.
+ */
+static void e100_io_resume(struct pci_dev *pdev)
+{
+ struct net_device *netdev = pci_get_drvdata(pdev);
+ struct nic *nic = netdev_priv(netdev);
+
+ /* ack any pending wake events, disable PME */
+ pci_enable_wake(pdev, 0, 0);
+
+ netif_device_attach(netdev);
+ if (netif_running(netdev)) {
+ e100_open(netdev);
+ mod_timer(&nic->watchdog, jiffies);
+ }
+}
+
+static struct pci_error_handlers e100_err_handler = {
+ .error_detected = e100_io_error_detected,
+ .slot_reset = e100_io_slot_reset,
+ .resume = e100_io_resume,
+};
static struct pci_driver e100_driver = {
.name = DRV_NAME,
@@ -2791,6 +2865,7 @@ static struct pci_driver e100_driver = {
.resume = e100_resume,
#endif
.shutdown = e100_shutdown,
+ .err_handler = &e100_err_handler,
};
static int __init e100_init_module(void)
^ permalink raw reply
* Re: [PATCH 2/4] tickless idle cpu: Skip ticks when CPU is idle
From: Paul Mackerras @ 2006-04-07 23:40 UTC (permalink / raw)
To: vatsa; +Cc: sri_vatsa_v, linuxppc-dev
In-Reply-To: <20060407063131.GB22416@in.ibm.com>
Srivatsa Vaddagiri writes:
> diff -puN arch/powerpc/kernel/idle_power4.S~no_idle_hz arch/powerpc/kernel/idle_power4.S
> --- linux-2.6.17-rc1/arch/powerpc/kernel/idle_power4.S~no_idle_hz 2006-04-07 04:14:39.000000000 +0530
> +++ linux-2.6.17-rc1-root/arch/powerpc/kernel/idle_power4.S 2006-04-07 04:14:58.000000000 +0530
> @@ -30,6 +30,9 @@ END_FTR_SECTION_IFCLR(CPU_FTR_CAN_NAP)
> cmpwi 0,r4,0
> beqlr
>
> + mflr r4
> + bl .stop_hz_timer
> + mtlr r4
This won't work - r4 is volatile across function calls, that is,
stop_hz_timer() could change r4 and is not required to save and
restore it.
Paul.
^ permalink raw reply
* Re: [PATCH] PCI Error Recovery: e100 network device driver
From: Alexey Dobriyan @ 2006-04-08 0:03 UTC (permalink / raw)
To: Linas Vepstas
Cc: Greg KH, linux-kernel, jesse.brandeburg, linuxppc-dev,
john.ronciak, jeffrey.t.kirsher, netdev, linux-pci, Jeff Garzik
In-Reply-To: <20060407231134.GN25225@austin.ibm.com>
On Fri, Apr 07, 2006 at 06:11:34PM -0500, Linas Vepstas wrote:
> --- linux-2.6.17-rc1.orig/drivers/net/e100.c
> +++ linux-2.6.17-rc1/drivers/net/e100.c
> + * @state: The current pci conneection state
connection
> +static pci_ers_result_t e100_io_error_detected(struct pci_dev *pdev, pci_channel_state_t state)
> +{
> + struct net_device *netdev = pci_get_drvdata(pdev);
> +
> + /* Similar to calling e100_down(), but avoids adpater I/O. */
adapter
> +static pci_ers_result_t e100_io_slot_reset(struct pci_dev *pdev)
> +{
> + struct net_device *netdev = pci_get_drvdata(pdev);
> + struct nic *nic = netdev_priv(netdev);
> +
> + if (pci_enable_device(pdev)) {
> + printk(KERN_ERR "e100: Cannot re-enable PCI device after reset.\n");
> + return PCI_ERS_RESULT_DISCONNECT;
> + }
> + pci_set_master(pdev);
> +
> + /* Only one device per card can do a reset */
> + if (0 != PCI_FUNC(pdev->devfn))
Wrong order.
^ permalink raw reply
* Re: freescale lite 5200 board and kernel 2.6
From: Matthias Fechner @ 2006-04-08 8:21 UTC (permalink / raw)
To: linuxppc-embedded
In-Reply-To: <20060406221056.GA15540@raptus.dandreoli.com>
[-- Attachment #1: Type: text/plain, Size: 381 bytes --]
Hello Domenico,
* Domenico Andreoli <cavokz@gmail.com> [07-04-06 00:10]:
> kernel is built following the instructions on your wiki, i attached
> the config file. please have a look, let me know if any check/test may
> be advised.
sry, but I have now time to try your kernel config, but I attached
mine which is working fine for me.
Maybe this helps you.
Best regards,
Matthias
[-- Attachment #2: config-mpc52xx.bz2 --]
[-- Type: application/octet-stream, Size: 4800 bytes --]
^ permalink raw reply
* Re: [PATCH] PCI Error Recovery: e100 network device driver
From: Francois Romieu @ 2006-04-08 8:12 UTC (permalink / raw)
To: Linas Vepstas
Cc: Greg KH, linux-kernel, jesse.brandeburg, linuxppc-dev,
john.ronciak, jeffrey.t.kirsher, netdev, linux-pci, Jeff Garzik
In-Reply-To: <20060407231134.GN25225@austin.ibm.com>
Linas Vepstas <linas@austin.ibm.com> :
> Index: linux-2.6.17-rc1/drivers/net/e100.c
> ===================================================================
> --- linux-2.6.17-rc1.orig/drivers/net/e100.c 2006-04-07 16:21:46.000000000 -0500
> +++ linux-2.6.17-rc1/drivers/net/e100.c 2006-04-07 18:10:52.411266545 -0500
[...]
> +static pci_ers_result_t e100_io_error_detected(struct pci_dev *pdev, pci_channel_state_t state)
80 cols limit.
[...]
> +static pci_ers_result_t e100_io_slot_reset(struct pci_dev *pdev)
> +{
> + struct net_device *netdev = pci_get_drvdata(pdev);
> + struct nic *nic = netdev_priv(netdev);
> +
> + if (pci_enable_device(pdev)) {
> + printk(KERN_ERR "e100: Cannot re-enable PCI device after reset.\n");
- The driver supports {get/set}_msglevel. Please consider using netif_msg_xxx
(see include/linux/netdevice.h).
- s/e100/DRV_NAME/ (or netdev->name, or pci_name(...) depending on the
context).
[...]
> +static struct pci_error_handlers e100_err_handler = {
> + .error_detected = e100_io_error_detected,
> + .slot_reset = e100_io_slot_reset,
> + .resume = e100_io_resume,
> +};
Nit: I'd rather follow the style in the declaration of e100_driver.
--
Ueimor
^ permalink raw reply
* slram
From: Antonio Di Bacco @ 2006-04-08 19:02 UTC (permalink / raw)
To: linuxppc-embedded
Anyone knows what slram driver is meant for?
Bye,
Antonio.
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox