LinuxPPC-Dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* Re: [PATCH] identify_ppc_sys_by_name_and_id function implementation final
From: Kumar Gala @ 2005-08-10 19:16 UTC (permalink / raw)
  To: Vitaly Bordug; +Cc: linuxppc-embedded list
In-Reply-To: <42FA4108.9090808@ru.mvista.com>

+static int __init find_chip_by_name_and_id(char *name, u32 id)
+{
+    int ret = -1;
+    unsigned int i = 0;
+    unsigned int j = 0;
+    unsigned int dups = 0;
+
+    unsigned int matched[count_sys_specs()];

Is is legit in the kernel to use dynamically sized array?

+
+    while (strcmp(ppc_sys_specs[i].ppc_sys_name, "")) {
+        if (!strcmp(ppc_sys_specs[i].ppc_sys_name, name))
+            matched[j++] = i;
+        i++;
+    }
+    if (j != 0) {
+        for (i = 0; i < j; i++) {
+            if ((ppc_sys_specs[matched[i]].mask & id) ==
+                ppc_sys_specs[matched[i]].value) {
+                ret = matched[i];
+                dups++;
+            }
+        }
+        ret = (dups == 1) ? ret : (-1 * dups);
+    }
+    return ret;
+}

On Aug 10, 2005, at 1:01 PM, Vitaly Bordug wrote:

> Finally correct indentation style.
>
> Signed-off-by: Vitaly Bordug <vbordug@ru.mvista.com>
>
> -- 
> Sincerely,
> Vitaly
>
> <ppc_sys_add.patch>
> <ATT87954.txt>
>

^ permalink raw reply

* Re: pci_enable_device fails on MPC8541
From: Kumar Gala @ 2005-08-10 19:11 UTC (permalink / raw)
  To: Bizhan Gholikhamseh \((bgholikh\)); +Cc: linuxppc-embedded
In-Reply-To: <F795765B112E7344AF36AA911279641584950A@xmb-sjc-212.amer.cisco.com>

No problem.  I'm hunting around the problem, but trying to figure out  
exactly where the bug is.  What's a little odd is that in 2.6.11 we  
should have excluded all the devices that are on the VIA chipset.   
However, in the logs you sent me we see those devices. Part of the  
problem is that your TI DSP has its own P2P bridge on it.  Therefor  
the bus numbers for the devices start changing around a bit.

What is CONFIG_85xx_PCI2 set to in your .config?

Can you send me the output of the following on the 8555 CDS:
cat /proc/ioports
cat /proc/iomem

Also, if you feel daring, grab the latest 2.6.13-rc6 kernel and build  
it for 8555 CDS and see what happens.

Oh, is this card something standard or a custom thing?  The issue of  
having a card with P2P bridge on it has come up more than once.   
However, I'm not sure of any standard PC PCI cards do this (at least  
none of the simple cards we have do).  I'd like to see if we can find  
something that we could start testing with.

thanks

- kumar

On Aug 10, 2005, at 1:03 PM, Bizhan Gholikhamseh \(((bgholikh\))) wrote:

> Kumar,
> Sorry it took a while. I have attached the 8540 PCI boot log and
> /proc/pci. Also I found out the functions you mentioned are not  
> used in
> my environment.
>
> Thanks,
> Bizhan
>
> -----Original Message-----
> From: Kumar Gala [mailto:kumar.gala@freescale.com]
> Sent: Wednesday, August 10, 2005 9:06 AM
> To: Bizhan Gholikhamseh (bgholikh)
> Cc: linuxppc-embedded@ozlabs.org
> Subject: Re: pci_enable_device fails on MPC8541
>
> It would be extremely helpful to get the output from the work MPC8540
> for lspci and cat /proc/pci.
>
> Also, I forget if 2.6.11 has CDS VIA support, but if it does you  
> can try
> disabling it by commenting out the calls to:
> mpc85xx_cds_enable_via() & mpc85xx_cds_fixup_via() in arch/ppc/syslib/
> ppc85xx_setup.c and see what happens.
>
> - k
>
> On Aug 10, 2005, at 10:58 AM, Bizhan Gholikhamseh \\((bgholikh\\))
> wrote:
>
>
>>  <<pci_boot.pdf>> Kumar,
>> We do not support or care about VIA IDE controller. I have enabled  
>> the
>>
>
>
>> DEBUG flag and attached the debug messages during boot. This is for
>> 8541E.
>> Regards,
>> Bizhan
>>
>> -----Original Message-----
>> From: Kumar Gala [mailto:kumar.gala@freescale.com]
>> Sent: Tuesday, August 09, 2005 4:11 PM
>> To: Bizhan Gholikhamseh (bgholikh)
>> Cc: linuxppc-embedded@ozlabs.org
>> Subject: Re: pci_enable_device fails on MPC8541
>>
>> Do you need support for the VIA IDE controller?  I'm not sure if that
>> is causing you issues.
>>
>> Also, can you try enabling DEBUG in arch/ppc/kernel/pci.c and send a
>> boot log.  I'm trying to figure out what is causing the resource
>> conflict.  It appears that the memory resource is reasonable, but
>> there could be possible conflict on the IO resource side.
>>
>> Also, if you can send logs of the same thing from the working 8540  
>> ADS
>>
>
>
>> that would be helpful.
>>
>> - kumar
>>
>> On Aug 9, 2005, at 12:18 PM, Bizhan Gholikhamseh \(((bgholikh\)))
>> wrote:
>>
>>
>>
>>> Hi Kumar,
>>> I am using Linux 2.6.11, u-boot 1.1.2.
>>> I see failure in pci_enable_device with message:
>>> "PCI: Device 0000:02:01.0 not available because of resource
>>> collisions"
>>>
>>> I have attached three files:
>>> lspci_output.txt: out put of the "lspci -v"
>>> proc_pci.txt: output of the "cat /proc/pci"
>>> u-boot.txt: output of the "pci command at u-boot"
>>>
>>> Any help greatly appreciated,
>>> Bizhan
>>> -----Original Message-----
>>> From: Kumar Gala [mailto:kumar.gala@freescale.com]
>>> Sent: Monday, August 08, 2005 1:34 PM
>>> To: Bizhan Gholikhamseh (bgholikh)
>>> Cc: linuxppc-embedded@ozlabs.org
>>> Subject: Re: pci_enable_device fails on MPC8541
>>>
>>> Bizhan,
>>>
>>> A few questions:
>>>
>>> 1. what kernel version are you using on these boards:
>>> 2. can you do an lspci -v on the boards
>>>
>>> - kumar
>>>
>>> On Aug 8, 2005, at 1:12 PM, Bizhan Gholikhamseh \(((bgholikh\)))
>>> wrote:
>>>
>>>
>>>
>>>
>>>> Hi All,
>>>> I am using two evaluation board from freescale, 8540ADS and  
>>>> MPC8541.
>>>> The same PCI driver is being compiled and loaded on both platforms.
>>>> The same PCI driver (developed by me) for DSP board compiled and
>>>> loaded on both platforms.
>>>>
>>>> When I type: "insmod C6415.ko" on 8541 board, I get the following
>>>> error:
>>>> "PCI: Device 0000:02:01.0 not available because of resource
>>>> collisions"
>>>> This messages is because of the execution of the generic PCI Linux
>>>> command:
>>>> "pci_enable_device(pdev)"
>>>> The same API has no problem on 8540ADS.
>>>>
>>>>
>>>>
>>>>
>>>>
>>>>> From UBOOT I can see my device is on bus 3:
>>>>>
>>>>>
>>>>>
>>>>>
>>>> => pci 3
>>>> Scanning PCI devices on bus 3
>>>> BusDev FUN    VendorID    DeviceID    Device Class    Sub-Class
>>>> ------------------------------------------------------------------- 
>>>> -
>>>>
>
>
>>>> -
>>>>
>>>>
>>
>>
>>
>>>> -
>>>> --
>>>> --------------------
>>>> 03.01.00            0x104c    0xa106        .........
>>>>
>>>> Any idea why the insmod fails on one board and not on the other  
>>>> one?
>>>>
>>>> Many thanks in advance,
>>>> Bizhan
>>>>
>>>> <ATT2118305.txt>
>>>>
>>>>
>>>> <lspci_output.txt>
>>>> <proc_pci.txt>
>>>> <u-boot.txt>
>>>>
>>>>
>>>
>>>
>>> <pci_boot.txt>
>>> <pci_boot.pdf>
>>>
>>
>>
>> <pci_boot_8540.txt>
>> <proc_pci_8540.txt>
>

^ permalink raw reply

* RE: pci_enable_device fails on MPC8541
From: Bizhan Gholikhamseh (bgholikh) @ 2005-08-10 18:03 UTC (permalink / raw)
  To: Kumar Gala; +Cc: linuxppc-embedded

[-- Attachment #1: Type: text/plain, Size: 4111 bytes --]

Kumar,
Sorry it took a while. I have attached the 8540 PCI boot log and
/proc/pci. Also I found out the functions you mentioned are not used in
my environment.

Thanks,
Bizhan 

-----Original Message-----
From: Kumar Gala [mailto:kumar.gala@freescale.com] 
Sent: Wednesday, August 10, 2005 9:06 AM
To: Bizhan Gholikhamseh (bgholikh)
Cc: linuxppc-embedded@ozlabs.org
Subject: Re: pci_enable_device fails on MPC8541

It would be extremely helpful to get the output from the work MPC8540
for lspci and cat /proc/pci.

Also, I forget if 2.6.11 has CDS VIA support, but if it does you can try
disabling it by commenting out the calls to:
mpc85xx_cds_enable_via() & mpc85xx_cds_fixup_via() in arch/ppc/syslib/
ppc85xx_setup.c and see what happens.

- k

On Aug 10, 2005, at 10:58 AM, Bizhan Gholikhamseh \\((bgholikh\\))
wrote:

>  <<pci_boot.pdf>> Kumar,
> We do not support or care about VIA IDE controller. I have enabled the

> DEBUG flag and attached the debug messages during boot. This is for 
> 8541E.
> Regards,
> Bizhan
>
> -----Original Message-----
> From: Kumar Gala [mailto:kumar.gala@freescale.com]
> Sent: Tuesday, August 09, 2005 4:11 PM
> To: Bizhan Gholikhamseh (bgholikh)
> Cc: linuxppc-embedded@ozlabs.org
> Subject: Re: pci_enable_device fails on MPC8541
>
> Do you need support for the VIA IDE controller?  I'm not sure if that 
> is causing you issues.
>
> Also, can you try enabling DEBUG in arch/ppc/kernel/pci.c and send a 
> boot log.  I'm trying to figure out what is causing the resource 
> conflict.  It appears that the memory resource is reasonable, but 
> there could be possible conflict on the IO resource side.
>
> Also, if you can send logs of the same thing from the working 8540 ADS

> that would be helpful.
>
> - kumar
>
> On Aug 9, 2005, at 12:18 PM, Bizhan Gholikhamseh \(((bgholikh\)))
> wrote:
>
>
>> Hi Kumar,
>> I am using Linux 2.6.11, u-boot 1.1.2.
>> I see failure in pci_enable_device with message:
>> "PCI: Device 0000:02:01.0 not available because of resource
>> collisions"
>>
>> I have attached three files:
>> lspci_output.txt: out put of the "lspci -v"
>> proc_pci.txt: output of the "cat /proc/pci"
>> u-boot.txt: output of the "pci command at u-boot"
>>
>> Any help greatly appreciated,
>> Bizhan
>> -----Original Message-----
>> From: Kumar Gala [mailto:kumar.gala@freescale.com]
>> Sent: Monday, August 08, 2005 1:34 PM
>> To: Bizhan Gholikhamseh (bgholikh)
>> Cc: linuxppc-embedded@ozlabs.org
>> Subject: Re: pci_enable_device fails on MPC8541
>>
>> Bizhan,
>>
>> A few questions:
>>
>> 1. what kernel version are you using on these boards:
>> 2. can you do an lspci -v on the boards
>>
>> - kumar
>>
>> On Aug 8, 2005, at 1:12 PM, Bizhan Gholikhamseh \(((bgholikh\)))
>> wrote:
>>
>>
>>
>>> Hi All,
>>> I am using two evaluation board from freescale, 8540ADS and MPC8541.
>>> The same PCI driver is being compiled and loaded on both platforms.
>>> The same PCI driver (developed by me) for DSP board compiled and
>>> loaded on both platforms.
>>>
>>> When I type: "insmod C6415.ko" on 8541 board, I get the following
>>> error:
>>> "PCI: Device 0000:02:01.0 not available because of resource
>>> collisions"
>>> This messages is because of the execution of the generic PCI Linux
>>> command:
>>> "pci_enable_device(pdev)"
>>> The same API has no problem on 8540ADS.
>>>
>>>
>>>
>>>
>>>> From UBOOT I can see my device is on bus 3:
>>>>
>>>>
>>>>
>>> => pci 3
>>> Scanning PCI devices on bus 3
>>> BusDev FUN    VendorID    DeviceID    Device Class    Sub-Class
>>> --------------------------------------------------------------------

>>> -
>>>
>
>
>>> -
>>> --
>>> --------------------
>>> 03.01.00            0x104c    0xa106        .........
>>>
>>> Any idea why the insmod fails on one board and not on the other one?
>>>
>>> Many thanks in advance,
>>> Bizhan
>>>
>>> <ATT2118305.txt>
>>>
>>>
>>> <lspci_output.txt>
>>> <proc_pci.txt>
>>> <u-boot.txt>
>>>
>>
>>
>> <pci_boot.txt>
>> <pci_boot.pdf>
>

[-- Attachment #2: pci_boot_8540.txt --]
[-- Type: text/plain, Size: 482 bytes --]

PCI: Probing PCI hardware
PCI: bridge rsrc 0..ffffff (100), parent c0203818
PCI: bridge rsrc 80000000..9fffffff (200), parent c02037fc
PCI: bridge rsrc fff000..ffffff (101), parent c0293038
PCI: bridge rsrc 9f000000..9fffffff (200), parent c0293054
PCI: bridge rsrc 9ef00000..9effffff (1201), parent c0293054
PCI:0000:01:01.0: Resource 0: 9fc00000-9fffffff (f=1208)
PCI:0000:01:01.0: Resource 1: 9f000000-9f7fffff (f=200)
PCI:0000:01:01.0: Resource 2: 00fffff0-00ffffff (f=101)





[-- Attachment #3: proc_pci_8540.txt --]
[-- Type: text/plain, Size: 524 bytes --]


# cat /proc/pci

PCI devices found:
  Bus  0, device  21, function  0:
    PCI bridge: Texas Instruments PCI2050 PCI-to-PCI Bridge (rev 2).
      IRQ 98.
      Master Capable.  Latency=128.
  Bus  1, device   1, function  0:
    Non-VGA unclassified device: Texas Instruments TMS320C6205 Fixed Point DSP (rev 1).      IRQ 99.
      Master Capable.  Latency=128.
      Prefetchable 32 bit memory at 0x9fc00000 [0x9fffffff].
      Non-prefetchable 32 bit memory at 0x9f000000 [0x9f7fffff].
      I/O at 0xfffff0 [0xffffff].


^ permalink raw reply

* [PATCH] identify_ppc_sys_by_name_and_id function implementation final
From: Vitaly Bordug @ 2005-08-10 18:01 UTC (permalink / raw)
  To: linuxppc-embedded list
In-Reply-To: <42FA3D7B.8040200@ru.mvista.com>

[-- Attachment #1: Type: text/plain, Size: 112 bytes --]

Finally correct indentation style.

Signed-off-by: Vitaly Bordug <vbordug@ru.mvista.com>

-- 
Sincerely,
Vitaly

[-- Attachment #2: ppc_sys_add.patch --]
[-- Type: text/x-patch, Size: 2173 bytes --]

diff --git a/arch/ppc/syslib/ppc_sys.c b/arch/ppc/syslib/ppc_sys.c
--- a/arch/ppc/syslib/ppc_sys.c
+++ b/arch/ppc/syslib/ppc_sys.c
@@ -6,6 +6,7 @@
  * Maintainer: Kumar Gala <kumar.gala@freescale.com>
  *
  * Copyright 2005 Freescale Semiconductor Inc.
+ * Copyright 2005 MontaVista, Inc. by Vitaly Bordug <vbordug@ru.mvista.com>
  *
  * This program is free software; you can redistribute  it and/or modify it
  * under  the terms of  the GNU General  Public License as published by the
@@ -33,10 +34,46 @@ void __init identify_ppc_sys_by_id(u32 i
 	return;
 }
 
-void __init identify_ppc_sys_by_name(char *name)
+static int __init count_sys_specs(void)
 {
-	/* TODO */
-	return;
+	int i = 0;
+	while (strcmp(ppc_sys_specs[i].ppc_sys_name, ""))
+		i++;
+	return i;
+}
+
+static int __init find_chip_by_name_and_id(char *name, u32 id)
+{
+	int ret = -1;
+	unsigned int i = 0;
+	unsigned int j = 0;
+	unsigned int dups = 0;
+
+	unsigned int matched[count_sys_specs()];
+
+	while (strcmp(ppc_sys_specs[i].ppc_sys_name, "")) {
+		if (!strcmp(ppc_sys_specs[i].ppc_sys_name, name))
+			matched[j++] = i;
+		i++;
+	}
+	if (j != 0) {
+		for (i = 0; i < j; i++) {
+			if ((ppc_sys_specs[matched[i]].mask & id) ==
+			    ppc_sys_specs[matched[i]].value) {
+				ret = matched[i];
+				dups++;
+			}
+		}
+		ret = (dups == 1) ? ret : (-1 * dups);
+	}
+	return ret;
+}
+
+void __init identify_ppc_sys_by_name_and_id(char *name, u32 id)
+{
+	int i = find_chip_by_name_and_id(name, id);
+	BUG_ON(i < 0);
+	cur_ppc_sys_spec = &ppc_sys_specs[i];
 }
 
 /* Update all memory resources by paddr, call before platform_device_register */
diff --git a/include/asm-ppc/ppc_sys.h b/include/asm-ppc/ppc_sys.h
--- a/include/asm-ppc/ppc_sys.h
+++ b/include/asm-ppc/ppc_sys.h
@@ -51,7 +51,7 @@ extern struct ppc_sys_spec *cur_ppc_sys_
 
 /* determine which specific SOC we are */
 extern void identify_ppc_sys_by_id(u32 id) __init;
-extern void identify_ppc_sys_by_name(char *name) __init;
+extern void identify_ppc_sys_by_name_and_id(char *name, u32 id) __init;
 
 /* describes all devices that may exist in a given family of processors */
 extern struct platform_device ppc_sys_platform_devices[];

^ permalink raw reply

* [PATCH] identify_ppc_sys_by_name_and_id function implementation (braces fixed)
From: Vitaly Bordug @ 2005-08-10 17:46 UTC (permalink / raw)
  To: Kumar Gala; +Cc: linuxppc-embedded list
In-Reply-To: <42FA3636.7010804@ru.mvista.com>

[-- Attachment #1: Type: text/plain, Size: 133 bytes --]

The same as above but with correct kernel bracing style.

Signed-off-by: Vitaly Bordug <vbordug@ru.mvista.com>
-- 
Sincerely,
Vitaly

[-- Attachment #2: ppc_sys_add.patch --]
[-- Type: text/x-patch, Size: 2174 bytes --]

diff --git a/arch/ppc/syslib/ppc_sys.c b/arch/ppc/syslib/ppc_sys.c
--- a/arch/ppc/syslib/ppc_sys.c
+++ b/arch/ppc/syslib/ppc_sys.c
@@ -6,6 +6,7 @@
  * Maintainer: Kumar Gala <kumar.gala@freescale.com>
  *
  * Copyright 2005 Freescale Semiconductor Inc.
+ * Copyright 2005 MontaVista, Inc. by Vitaly Bordug <vbordug@ru.mvista.com>
  *
  * This program is free software; you can redistribute  it and/or modify it
  * under  the terms of  the GNU General  Public License as published by the
@@ -33,10 +34,45 @@ void __init identify_ppc_sys_by_id(u32 i
 	return;
 }
 
-void __init identify_ppc_sys_by_name(char *name)
+static int __init count_sys_specs(void)
 {
-	/* TODO */
-	return;
+	int i = 0;
+	while (strcmp(ppc_sys_specs[i].ppc_sys_name,""))
+		i++;
+	return i;
+}
+
+static int __init find_chip_by_name_and_id(char *name, u32 id)
+{
+	int ret = -1;
+	unsigned int i = 0;
+	unsigned int j = 0;
+	unsigned int dups = 0;
+	
+	unsigned int matched[count_sys_specs()];
+	
+	while (strcmp(ppc_sys_specs[i].ppc_sys_name,"")) {
+		if (!strcmp(ppc_sys_specs[i].ppc_sys_name, name))
+			matched[j++]=i;
+		i++;
+	}
+	if(j != 0) {    	
+		for(i = 0;i < j;i++) {	
+			if ((ppc_sys_specs[matched[i]].mask & id) == ppc_sys_specs[matched[i]].value) {	
+				ret = matched[i];
+				dups++;
+			}
+		}
+		ret = (dups == 1) ? ret : (-1*dups);  
+	}
+	return ret;
+}
+
+void __init identify_ppc_sys_by_name_and_id(char* name, u32 id)
+{
+    int i = find_chip_by_name_and_id(name,id);
+    BUG_ON(i < 0);
+    cur_ppc_sys_spec = &ppc_sys_specs[i];
 }
 
 /* Update all memory resources by paddr, call before platform_device_register */
diff --git a/include/asm-ppc/ppc_sys.h b/include/asm-ppc/ppc_sys.h
--- a/include/asm-ppc/ppc_sys.h
+++ b/include/asm-ppc/ppc_sys.h
@@ -51,7 +51,7 @@ extern struct ppc_sys_spec *cur_ppc_sys_
 
 /* determine which specific SOC we are */
 extern void identify_ppc_sys_by_id(u32 id) __init;
-extern void identify_ppc_sys_by_name(char *name) __init;
+extern void identify_ppc_sys_by_name_and_id(char *name, u32 id) __init;
 
 /* describes all devices that may exist in a given family of processors */
 extern struct platform_device ppc_sys_platform_devices[];

^ permalink raw reply

* [PATCH] Use todc on Mot PReP platforms
From: Matt Porter @ 2005-08-10 16:37 UTC (permalink / raw)
  To: linuxppc-dev

This restores behavior from 2.4 where PReP platforms identified
as Motorola would calibrate the decrementer using the RTC. On
real Motorola PReP hardware this isn't needed. However, in order
to boot a stock 2.6 PReP kernel on qemu (which emulates a Motorola
PReP system) it is necessary to allow it to calibrate the decrementer
using an emulated RTC.  If the decrementer rate is read from
residual data then timing is screwed since a qemu PReP system typically
runs much faster than the original hardware.

If anybody has objections to this as the default, let me know. It
still works (as did 2.4) on a couple of my Mot PReP boxes and doesn't
affect the IBM PReP paths. My goal with this is to be able to run
a stock 2.6 defconfig PReP build on qemu.

-Matt

diff --git a/arch/ppc/platforms/prep_setup.c b/arch/ppc/platforms/prep_setup.c
--- a/arch/ppc/platforms/prep_setup.c
+++ b/arch/ppc/platforms/prep_setup.c
@@ -940,8 +940,7 @@ prep_calibrate_decr(void)
 			tb_to_us = mulhwu_scale_factor(freq/divisor, 1000000);
 			tb_ticks_per_jiffy = freq / HZ / divisor;
 		}
-	}
-	else
+	} else
 		todc_calibrate_decr();
 }
 
@@ -1155,16 +1154,17 @@ prep_init(unsigned long r3, unsigned lon
 
 	ppc_md.time_init      = todc_time_init;
 	if (_prep_type == _PREP_IBM) {
+		ppc_md.calibrate_decr = prep_calibrate_decr;
 		ppc_md.rtc_read_val = todc_mc146818_read_val;
 		ppc_md.rtc_write_val = todc_mc146818_write_val;
 		TODC_INIT(TODC_TYPE_MC146818, RTC_PORT(0), NULL, RTC_PORT(1),
 				8);
 	} else {
+		ppc_md.calibrate_decr = todc_calibrate_decr;
 		TODC_INIT(TODC_TYPE_MK48T59, PREP_NVRAM_AS0, PREP_NVRAM_AS1,
 				PREP_NVRAM_DATA, 8);
 	}
 
-	ppc_md.calibrate_decr = prep_calibrate_decr;
 	ppc_md.set_rtc_time   = todc_set_rtc_time;
 	ppc_md.get_rtc_time   = todc_get_rtc_time;
 

^ permalink raw reply

* [RFC][PATCH] identify_ppc_sys_by_name_and_id function implementation
From: Vitaly Bordug @ 2005-08-10 17:15 UTC (permalink / raw)
  To: Kumar Gala; +Cc: linuxppc-embedded list

[-- Attachment #1: Type: text/plain, Size: 322 bytes --]

Kumar,

This is preliminary version of the identify_ppc_sys_by_name_and_id(...).
Tested with pq2 devices/sys for 8272ADS and fs_enet. This will BUG_ON if 
nothing found or duplicates exist (guess if we call identify_ppc_sys.. 
hit is expected).

Signed-off-by: Vitaly Bordug <vbordug@ru.mvista.com>

-- 
Sincerely,
Vitaly

[-- Attachment #2: ppc_sys_add.patch --]
[-- Type: text/x-patch, Size: 2183 bytes --]

diff --git a/arch/ppc/syslib/ppc_sys.c b/arch/ppc/syslib/ppc_sys.c
--- a/arch/ppc/syslib/ppc_sys.c
+++ b/arch/ppc/syslib/ppc_sys.c
@@ -6,6 +6,7 @@
  * Maintainer: Kumar Gala <kumar.gala@freescale.com>
  *
  * Copyright 2005 Freescale Semiconductor Inc.
+ * Copyright 2005 MontaVista, Inc. by Vitaly Bordug <vbordug@ru.mvista.com>
  *
  * This program is free software; you can redistribute  it and/or modify it
  * under  the terms of  the GNU General  Public License as published by the
@@ -33,10 +34,48 @@ void __init identify_ppc_sys_by_id(u32 i
 	return;
 }
 
-void __init identify_ppc_sys_by_name(char *name)
+static int __init count_sys_specs(void)
 {
-	/* TODO */
-	return;
+	int i = 0;
+	while (strcmp(ppc_sys_specs[i].ppc_sys_name,""))
+		i++;
+	return i;
+}
+
+static int __init find_chip_by_name_and_id(char *name, u32 id)
+{
+	int ret = -1;
+	unsigned int i = 0;
+	unsigned int j = 0;
+	unsigned int dups = 0;
+	
+	unsigned int matched[count_sys_specs()];
+	
+	while (strcmp(ppc_sys_specs[i].ppc_sys_name,"")) {
+		if (!strcmp(ppc_sys_specs[i].ppc_sys_name, name))
+			matched[j++]=i;
+		i++;
+	}
+	if(j != 0)
+	{    	
+		for(i = 0;i < j;i++)
+		{	
+			if ((ppc_sys_specs[matched[i]].mask & id) == ppc_sys_specs[matched[i]].value)
+			{	
+				ret = matched[i];
+				dups++;
+			}
+		}
+		ret = (dups == 1) ? ret : (-1*dups);  
+	}
+	return ret;
+}
+
+void __init identify_ppc_sys_by_name_and_id(char* name, u32 id)
+{
+    int i = find_chip_by_name_and_id(name,id);
+    BUG_ON(i < 0);
+    cur_ppc_sys_spec = &ppc_sys_specs[i];
 }
 
 /* Update all memory resources by paddr, call before platform_device_register */
diff --git a/include/asm-ppc/ppc_sys.h b/include/asm-ppc/ppc_sys.h
--- a/include/asm-ppc/ppc_sys.h
+++ b/include/asm-ppc/ppc_sys.h
@@ -51,7 +51,7 @@ extern struct ppc_sys_spec *cur_ppc_sys_
 
 /* determine which specific SOC we are */
 extern void identify_ppc_sys_by_id(u32 id) __init;
-extern void identify_ppc_sys_by_name(char *name) __init;
+extern void identify_ppc_sys_by_name_and_id(char *name, u32 id) __init;
 
 /* describes all devices that may exist in a given family of processors */
 extern struct platform_device ppc_sys_platform_devices[];

^ permalink raw reply

* Re: RFC: proposed arch/powerpc directory structure
From: Dan Malek @ 2005-08-10 17:01 UTC (permalink / raw)
  To: Becky Bruce; +Cc: linuxppc64-dev, linuxppc-dev
In-Reply-To: <c237b7e878e0c32f421209fa37b7a156@freescale.com>


On Aug 10, 2005, at 12:45 PM, Becky Bruce wrote:

> ....  Listed below are the proposed directories, along with a 
> description of the logical contents, as well as a description of which 
> existing files will be moved into these directories.

I think this is fine, but I'd like to make a suggestion about the file 
names themselves.
Since we have platform directories for a specific processor type or 
core, can we
change the file names a little?  For example, if I'm in the 
platforms/82xx directory,
I don't need to prepend every file with mpc82xx_ or ppc82xx- or 
whatever.  We
know that's what it is, let's try to use the file names to be more 
descriptive of what's
inside of them.  Regardless of the build or management tools we use, I 
still find it
nice to keep a concise file name that is still descriptive, and take 
advantage of
the directory structure names to assist with this.

Thanks.


	-- Dan

^ permalink raw reply

* RFC: proposed arch/powerpc directory structure
From: Becky Bruce @ 2005-08-10 16:45 UTC (permalink / raw)
  To: linuxppc64-dev, linuxppc-dev

All,

In the name of moving the much-anticipated 32/64 ppc merge along, Kumar 
Gala, Jon Loeliger, and myself have worked out an initial proposal for 
the directory structure of the new merged arch/powerpc.  Listed below 
are the proposed directories, along with a description of the logical 
contents, as well as a description of which existing files will be 
moved into these directories.

There was some discussion on the list recently about whether or not it 
might be better to change things around to be laid out more along the 
lines of functionality with, say, all pci-related code in one place.  
We've stuck with a more traditional model in this proposal, although 
the topic is certainly still up for discussion.

This is just a first pass at a structure - we're really looking for 
input from this list on the best way to proceed, and that discussion 
needs to start somewhere.  BTW, this proposal preempts the previous 
64-bit directory structure reorg proposal that I sent to this list a 
couple of months ago.

So here it is:

include/powerpc/

arch/powerpc/
	configs/
		- Kconfig defaults per buildable board.

	boot/
		- Pre-kernel execution shims and pre-passes.
		- Convert firmware reprensentations (bi_recs, OF Dev-Trees,
		 bootx,bd_t) to flat-dev-trees.
		- Includes merged files from arch/ppc*/boot/ trees, plus
		prom_init.c from arch/ppc64/kernel.

	kernel/
		- CPU-centric core code and generic PPC-specific kernel
		- Main entry point supports r5=0, r3 = flat-dev-tree, etc.
		- Includes all cpu core-specific code, kernel initialization code,
		and other generic kernel foo like smp, ptrace, syscalls, etc from
		arch/ppc*/kernel.  Files not belonging to one of these categories
		will be moved to other directories.


	platforms/
		- platform-specific code laid out in the following directories:
		pSeries/
		iSeries/
		pmac/  (both 32 and 64-bit)
		classic32/  (platforms containing 6xx/7xx/74xx/8240/8241/8245)
		classic64/  (Maple?)
		83xx/ (may collapse into classic 32 at some point)
		86xx/ (may collapse into classic 32 at some point)
		pq2/ (may collapse into classic 32 at some point)
		52xx/ (may collapse into classic 32 at some point)
		85xx/
		4xx/
		8xx/
		- Includes all code from arch/ppc/platforms, all code from
		arch/ppc64/kernel that is specific to a given platform (where a
		platform is a whole computer system or board)
	
		NOTE: there would be no .[chS] files directly under platforms -
		all live in subdirs.

	mm/
		- Memory management, slabs, tlbs, etc.
		- Unify LMB and mem_pieces for early boot memory.
		- Includes all code from arch/ppc*/mm

	sysdev/
		- System Device support and Kitchen Sink
		- Includes all code currently in arch/ppc/syslib, irq and pci code
		that currently lives in arch/ppc/kernel, and all code from
		arch/ppc64/kernel that is generic system code, including pci,
		irq, interrupt control, bridges, rtas(?)

	lib/
		- Library code
		- Includes all code from arch/ppc*/lib

	math-emu/
		- Math Emulation for FPU-less ppc32s.
		- this is 32-bit only, so this directory would just move from
		arch/ppc to arch/powerpc

	oprofile/
		- Support for oprofile.
		- Includes all code from arch/ppc*/oprofile

	xmon/
		- Support for xmon.
		- Includes all code from arch/ppc*xmon


Cheers,
-Becky

^ permalink raw reply

* PowerBook5,4 sleep w/2.6.12
From: Owen Stampflee @ 2005-08-10 15:57 UTC (permalink / raw)
  To: linuxppc-dev

Anyone else having troubles with it? I've tried 2.6.12-rc2 and
2.6.12.(3|4). Found several success reports on Google about 2.6.12
sleeping this laptop correctly.

My PowerBook refuses to wake up, the screen stays blank, PCMCIA card
lights don't turn on, but I do hear the CDROM drive motor kick.

Sleep works perfectly using 2.6.10, and 2.6.12 works fine on a
co-worker's PowerBook5,2.

Any input would be greatly appreciated, I seem to remember a tidbit
about an early wakeup console, but I'm guessing that doesnt even work.

Thanks,
Owen

^ permalink raw reply

* Re: pci_enable_device fails on MPC8541
From: Kumar Gala @ 2005-08-10 16:05 UTC (permalink / raw)
  To: Bizhan Gholikhamseh \(bgholikh\); +Cc: linuxppc-embedded
In-Reply-To: <F795765B112E7344AF36AA9112796415849508@xmb-sjc-212.amer.cisco.com>

It would be extremely helpful to get the output from the work MPC8540  
for lspci and cat /proc/pci.

Also, I forget if 2.6.11 has CDS VIA support, but if it does you can  
try disabling it by commenting out the calls to:
mpc85xx_cds_enable_via() & mpc85xx_cds_fixup_via() in arch/ppc/syslib/ 
ppc85xx_setup.c and see what happens.

- k

On Aug 10, 2005, at 10:58 AM, Bizhan Gholikhamseh \\((bgholikh\\))  
wrote:

>  <<pci_boot.pdf>> Kumar,
> We do not support or care about VIA IDE controller. I have enabled the
> DEBUG flag and attached the debug messages during boot. This is for
> 8541E.
> Regards,
> Bizhan
>
> -----Original Message-----
> From: Kumar Gala [mailto:kumar.gala@freescale.com]
> Sent: Tuesday, August 09, 2005 4:11 PM
> To: Bizhan Gholikhamseh (bgholikh)
> Cc: linuxppc-embedded@ozlabs.org
> Subject: Re: pci_enable_device fails on MPC8541
>
> Do you need support for the VIA IDE controller?  I'm not sure if  
> that is
> causing you issues.
>
> Also, can you try enabling DEBUG in arch/ppc/kernel/pci.c and send a
> boot log.  I'm trying to figure out what is causing the resource
> conflict.  It appears that the memory resource is reasonable, but  
> there
> could be possible conflict on the IO resource side.
>
> Also, if you can send logs of the same thing from the working 8540 ADS
> that would be helpful.
>
> - kumar
>
> On Aug 9, 2005, at 12:18 PM, Bizhan Gholikhamseh \(((bgholikh\)))  
> wrote:
>
>
>> Hi Kumar,
>> I am using Linux 2.6.11, u-boot 1.1.2.
>> I see failure in pci_enable_device with message:
>> "PCI: Device 0000:02:01.0 not available because of resource
>> collisions"
>>
>> I have attached three files:
>> lspci_output.txt: out put of the "lspci -v"
>> proc_pci.txt: output of the "cat /proc/pci"
>> u-boot.txt: output of the "pci command at u-boot"
>>
>> Any help greatly appreciated,
>> Bizhan
>> -----Original Message-----
>> From: Kumar Gala [mailto:kumar.gala@freescale.com]
>> Sent: Monday, August 08, 2005 1:34 PM
>> To: Bizhan Gholikhamseh (bgholikh)
>> Cc: linuxppc-embedded@ozlabs.org
>> Subject: Re: pci_enable_device fails on MPC8541
>>
>> Bizhan,
>>
>> A few questions:
>>
>> 1. what kernel version are you using on these boards:
>> 2. can you do an lspci -v on the boards
>>
>> - kumar
>>
>> On Aug 8, 2005, at 1:12 PM, Bizhan Gholikhamseh \(((bgholikh\)))
>> wrote:
>>
>>
>>
>>> Hi All,
>>> I am using two evaluation board from freescale, 8540ADS and MPC8541.
>>> The same PCI driver is being compiled and loaded on both platforms.
>>> The same PCI driver (developed by me) for DSP board compiled and
>>> loaded on both platforms.
>>>
>>> When I type: "insmod C6415.ko" on 8541 board, I get the following
>>> error:
>>> "PCI: Device 0000:02:01.0 not available because of resource
>>> collisions"
>>> This messages is because of the execution of the generic PCI Linux
>>> command:
>>> "pci_enable_device(pdev)"
>>> The same API has no problem on 8540ADS.
>>>
>>>
>>>
>>>
>>>> From UBOOT I can see my device is on bus 3:
>>>>
>>>>
>>>>
>>> => pci 3
>>> Scanning PCI devices on bus 3
>>> BusDev FUN    VendorID    DeviceID    Device Class    Sub-Class
>>> -------------------------------------------------------------------- 
>>> -
>>>
>
>
>>> -
>>> --
>>> --------------------
>>> 03.01.00            0x104c    0xa106        .........
>>>
>>> Any idea why the insmod fails on one board and not on the other one?
>>>
>>> Many thanks in advance,
>>> Bizhan
>>>
>>> <ATT2118305.txt>
>>>
>>>
>>> <lspci_output.txt>
>>> <proc_pci.txt>
>>> <u-boot.txt>
>>>
>>
>>
>> <pci_boot.txt>
>> <pci_boot.pdf>
>

^ permalink raw reply

* RE: pci_enable_device fails on MPC8541
From: Bizhan Gholikhamseh (bgholikh) @ 2005-08-10 15:58 UTC (permalink / raw)
  To: Kumar Gala; +Cc: linuxppc-embedded

[-- Attachment #1: Type: text/plain, Size: 3041 bytes --]

 <<pci_boot.pdf>> Kumar,
We do not support or care about VIA IDE controller. I have enabled the
DEBUG flag and attached the debug messages during boot. This is for
8541E.
Regards,
Bizhan 

-----Original Message-----
From: Kumar Gala [mailto:kumar.gala@freescale.com] 
Sent: Tuesday, August 09, 2005 4:11 PM
To: Bizhan Gholikhamseh (bgholikh)
Cc: linuxppc-embedded@ozlabs.org
Subject: Re: pci_enable_device fails on MPC8541

Do you need support for the VIA IDE controller?  I'm not sure if that is
causing you issues.

Also, can you try enabling DEBUG in arch/ppc/kernel/pci.c and send a
boot log.  I'm trying to figure out what is causing the resource
conflict.  It appears that the memory resource is reasonable, but there
could be possible conflict on the IO resource side.

Also, if you can send logs of the same thing from the working 8540 ADS
that would be helpful.

- kumar

On Aug 9, 2005, at 12:18 PM, Bizhan Gholikhamseh \(((bgholikh\))) wrote:

> Hi Kumar,
> I am using Linux 2.6.11, u-boot 1.1.2.
> I see failure in pci_enable_device with message:
> "PCI: Device 0000:02:01.0 not available because of resource 
> collisions"
>
> I have attached three files:
> lspci_output.txt: out put of the "lspci -v"
> proc_pci.txt: output of the "cat /proc/pci"
> u-boot.txt: output of the "pci command at u-boot"
>
> Any help greatly appreciated,
> Bizhan
> -----Original Message-----
> From: Kumar Gala [mailto:kumar.gala@freescale.com]
> Sent: Monday, August 08, 2005 1:34 PM
> To: Bizhan Gholikhamseh (bgholikh)
> Cc: linuxppc-embedded@ozlabs.org
> Subject: Re: pci_enable_device fails on MPC8541
>
> Bizhan,
>
> A few questions:
>
> 1. what kernel version are you using on these boards:
> 2. can you do an lspci -v on the boards
>
> - kumar
>
> On Aug 8, 2005, at 1:12 PM, Bizhan Gholikhamseh \(((bgholikh\)))
> wrote:
>
>
>> Hi All,
>> I am using two evaluation board from freescale, 8540ADS and MPC8541.
>> The same PCI driver is being compiled and loaded on both platforms.
>> The same PCI driver (developed by me) for DSP board compiled and
>> loaded on both platforms.
>>
>> When I type: "insmod C6415.ko" on 8541 board, I get the following
>> error:
>> "PCI: Device 0000:02:01.0 not available because of resource
>> collisions"
>> This messages is because of the execution of the generic PCI Linux
>> command:
>> "pci_enable_device(pdev)"
>> The same API has no problem on 8540ADS.
>>
>>
>>
>>> From UBOOT I can see my device is on bus 3:
>>>
>>>
>> => pci 3
>> Scanning PCI devices on bus 3
>> BusDev FUN    VendorID    DeviceID    Device Class    Sub-Class
>> ---------------------------------------------------------------------

>> -
>> --
>> --------------------
>> 03.01.00            0x104c    0xa106        .........
>>
>> Any idea why the insmod fails on one board and not on the other one?
>>
>> Many thanks in advance,
>> Bizhan
>>
>> <ATT2118305.txt>
>>
>>
>> <lspci_output.txt>
>> <proc_pci.txt>
>> <u-boot.txt>
>

[-- Attachment #2: pci_boot.txt --]
[-- Type: text/plain, Size: 1457 bytes --]

PCI: Probing PCI hardware
PCI: bridge rsrc 0..ffffff (100), parent c0248588
PCI: reparented 8259 (master) [20..21] under PCI1 host bridge
PCI: reparented 8259 (slave) [a0..a1] under PCI1 host bridge
PCI: reparented 8259 edge control [4d0..4d1] under PCI1 host bridge
PCI: bridge rsrc 80000000..9fffffff (200), parent c024856c
PCI: bridge rsrc 0..ffff (101), parent c02e5038
PCI: reparented 8259 (master) [20..21] under PCI Bus #01
PCI: reparented 8259 (slave) [a0..a1] under PCI Bus #01
PCI: reparented 8259 edge control [4d0..4d1] under PCI Bus #01
PCI: bridge rsrc 9fe00000..9fefffff (200), parent c02e5054
PCI: bridge rsrc 9fd00000..9fdfffff (1201), parent c02e5054
PCI: bridge rsrc 0..ffff (101), parent c02e5038
PCI: reparented PCI Bus #01 [0..ffff] under PCI Bus #02
PCI: bridge rsrc 9fc00000..9fcfffff (200), parent c02e5054
PCI: bridge rsrc 9fb00000..9fbfffff (1201), parent c02e5054
PCI: bridge rsrc 1000000..1ffffff (100), parent c0248588
PCI: bridge rsrc a0000000..bfffffff (200), parent c024856c
PCI:0000:00:11.0: Resource 0: 9ffff000-9fffffff (f=200)
PCI:0000:01:02.1: Resource 4: 0000cc00-0000cc0f (f=101)
PCI:0000:01:02.2: Resource 4: 0000ffe0-0000ffff (f=101)
PCI:0000:01:02.3: Resource 4: 0000ffc0-0000ffdf (f=101)
PCI:0000:01:02.5: Resource 0: 0000fe00-0000feff (f=101)
PCI:0000:01:02.5: Resource 1: 0000fdfc-0000fdff (f=101)
PCI:0000:01:02.5: Resource 2: 0000fdf8-0000fdfb (f=101)
PCI:0000:01:02.6: Resource 0: 0000fc00-0000fcff (f=101)


[-- Attachment #3: pci_boot.pdf --]
[-- Type: application/octet-stream, Size: 8370 bytes --]

^ permalink raw reply

* Re: mpc8248  SEC -- interrupt handler 'is' invoked
From: Kim Phillips @ 2005-08-10 15:37 UTC (permalink / raw)
  To: Vikas Aggarwal; +Cc: linuxppc-embedded
In-Reply-To: <53521.198.22.236.230.1123620724.squirrel@198.22.236.230>

On Tue, 9 Aug 2005 16:52:04 -0400 (EDT)
"Vikas Aggarwal" <va824363@albany.edu> wrote:

> The address returned by kmalloc=0x009ffc5c  is 4 byte aligned.
> Are u advicing that dma_map_single() should return 8 byte aligned ,
> becuase thats what gets written into the Data-Paclet_descriptor later.
> 
I wouldn't worry about alignment as much as the register write trace and checking the System Interface Unit and individual eu status registers.

-- 
Kim

^ permalink raw reply

* Re: mpc5200 linux source
From: Grant Likely @ 2005-08-10 15:07 UTC (permalink / raw)
  To: Joel Isaacson, linuxppc-embedded
In-Reply-To: <42F8C436.7010706@ascender.com>

On 8/9/05, Joel Isaacson <joel@ascender.com> wrote:
> Hi
>=20
> My name is Joel Isaacson. I'm a consultant working on a Linux mpc5200
> embedded card. We are working with the 2.4 Denx linux kernel. I saw from
> a mailing that you are  using the 2.6  kernel with SIP support that you
> added. What is the status of the 2.6 port? The latest kernel doesn't
> seem to have the Ethernet (fec, bestcomm) support.
>=20
Here's a post from Sylvain pointing to his mpc5200 git tree.  The
Ethernet driver has not yet been rolled into mainline because the
BestComm DMA engine does not yet conform to the platform bus.  You
must get the driver from Sylvain's tree if you want to use Ethernet.

http://ozlabs.org/pipermail/linuxppc-embedded/2005-June/018887.html

Do you mean SIP or SPI?  I wrote a simple SPI subsystem for my own use
which is posted to the linuxppc-embedded mailing list.  Unlike most
SPI subsystems out there, it is NOT based on the I2C subsystem.  There
are a number of good SPI subsystem implementations out there that you
can choose from.

BTW, you can subscribe to the linuxppc-embedded mailing list from here:

https://ozlabs.org/mailman/listinfo/linuxppc-embedded

Cheers,
g.

^ permalink raw reply

* Antigen found CorruptedCompressedUuencodeFile virus
From: Antigen_EXCH01 @ 2005-08-10 13:56 UTC (permalink / raw)
  To: linuxppc-embedded

Antigen for Exchange found Body of Message infected with CorruptedCompressedUuencodeFile virus.
The file is currently Removed.  The message, "Linuxppc-embedded Digest, Vol 12, Issue 41", was
sent from linuxppc-embedded-bounces@ozlabs.org and was discovered in SMTP Messages\Inbound
located at Quadrics/First Administrative Group/EXCH01.

^ permalink raw reply

* Re: arch/ppc/kernel/find_name.c??
From: Kumar Gala @ 2005-08-10 14:14 UTC (permalink / raw)
  To: linuxppc-dev list
In-Reply-To: <18167A13-B5E6-44B9-894F-8AC451F2DF4B@freescale.com>

Let me try this again.  Does anyone use this code or will anyone care  
if I kill it?

- kumar

On Aug 8, 2005, at 3:48 PM, Gala Kumar K.-galak wrote:

> anyone know why we have this still around since it doesnt seem to be
> used by any makefile?
>
> - kumar
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev@ozlabs.org
> https://ozlabs.org/mailman/listinfo/linuxppc-dev
>

^ permalink raw reply

* Re: 8xx: i2c-algo-8xx - fixed timeout detection and transmission errors
From: Marcelo Tosatti @ 2005-08-10 13:58 UTC (permalink / raw)
  To: cajus.hahn; +Cc: linuxppc-embedded
In-Reply-To: <OF065A7C05.DE2F464C-ONC1257059.00217532-C1257059.00290301@de.abb.com>

On Wed, Aug 10, 2005 at 09:27:57AM +0200, cajus.hahn@de.abb.com wrote:
>=20
>=20
>=20
>=20
> Hi all,
>=20
> I had some problems on my MPC855M based board when I tried to access th=
e
> i2c bus.
> The cause were some disturbances on the i2c bus. If a slave device or
> another master device hold the SDA or SCL line low, the CPM will get in=
to a
> state, where no more transmissions are made. The  only way I found, to =
get
> the CPM back to work, was a complete re-initialisation. -> force_reinit=
()
> In this case the busy-wait for transmissions with count < 16 will lock =
the
> complete system (CPU load 99.9%)
> I added the define I2C_BUSY_WAIT to switch between faster access or saf=
er
> system.
> I found out that the i2c-algo-8xx.c has a bug in cpm_iic_read() and
> cpm_iic_write(): the timeout detection will not work in the case of cou=
nt <
> 16.
> I also added the define I2C_INTERRUPTIBLE_SLEEP: the old driver reporte=
d
> IO-error (-EIO) if a timeout occured (which was not working, see above)=
 or
> if a signal was pending. This caused some problems if the process recei=
ves
> user-signals. The driver will report IO-error, which is not correct. Wi=
th
> the busy-wait this effect might not be seen, because there will be no
> process scheduling -> no signals might be send.
> My modified file is appended. The defines for  I2C_BUSY_WAIT and
> I2C_INTERRUPTIBLE_SLEEP are active, which let the driver act like the o=
ld
> one.
> Maybe this is helpful for others too and some of the modifications find
> it=B4s way into the official kernel tree.

Cajus,

Can you please prepare a diff with "diff -u" against the old version and =
your
modified version of the driver? That way it becomes easier for everyone t=
o=20
stop the changes you have made.

Thanks in advance.

>=20
> Cajus Hahn
>=20
> /*
>  * i2c-algo-8xx.c i2x driver algorithms for MPC8XX CPM
>  * Copyright (c) 1999 Dan Malek (dmalek@jlc.net).
>  *
>     This program is free software; you can redistribute it and/or modif=
y
>     it under the terms of the GNU General Public License as published b=
y
>     the Free Software Foundation; either version 2 of the License, or
>     (at your option) any later version.
>=20
>     This program is distributed in the hope that it will be useful,
>     but WITHOUT ANY WARRANTY; without even the implied warranty of
>     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
>     GNU General Public License for more details.
>=20
>     You should have received a copy of the GNU General Public License
>     along with this program; if not, write to the Free Software
>     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
>  *
>  * moved into proper i2c interface; separated out platform specific
>  * parts into i2c-rpx.c
>  * Brad Parker (brad@heeltoe.com)
>  *
>  * added define for BUSY_WAIT and INTERRUPTIBLE_SLEEP, added
> I2C_ALGO_8XX_DATE + ..VERSION
>  * fixed bug in cpm_iic_read and cpm_iic_write (timeout never detected =
if
> count < 16)
>  * added force_reinit(): in certain cases (disturbances on the I2C bus)=
 a
> timeout will
>  * occur. After this a complete re-initialisation will be necessary,
> otherwise all
>  * following transmissions will have a timeout.
>  * Cajus Hahn, 09.08.2005
>  */
>=20
> // XXX todo
> // timeout sleep?
>=20
> /* $Id: i2c-algo-8xx.c,v 1.1.1.1 2004/12/10 08:44:35 cajus Exp $ */
>=20
> #include <linux/kernel.h>
> #include <linux/module.h>
> #include <linux/delay.h>
> #include <linux/slab.h>
> #include <linux/version.h>
> #include <linux/init.h>
> #include <asm/uaccess.h>
> #include <linux/ioport.h>
> #include <linux/errno.h>
> #include <linux/sched.h>
>=20
> #include <asm/mpc8xx.h>
> #include <asm/commproc.h>
>=20
> #include <linux/i2c.h>
> #include <linux/i2c-algo-8xx.h>
>=20
> #define I2C_ALGO_8XX_DATE "20050809"
> #define I2C_ALGO_8XX_VERSION "2.6.2"
>=20
> #define CPM_MAX_READ    513
> /* #define I2C_CHIP_ERRATA */ /* Try uncomment this if you have an olde=
r
> CPU(earlier than rev D4) */
> #define I2C_BUSY_WAIT  /* Uncomment this if you want to do a busy wait =
in
> cpm_iic_read and cpm_iic_write */
> #define I2C_INTERRUPTIBLE_SLEEP /* Uncomment this if you want the waiti=
ng
> in cpm_iic_read and
>                                          cpm_iic_write beeing interrupt=
able
> by signals */
>=20
> static wait_queue_head_t iic_wait;
> static ushort r_tbase, r_rbase;
>=20
> int cpm_scan =3D 0;
> int cpm_debug =3D 0;
>=20
> static  void
> cpm_iic_interrupt(void *dev_id, struct pt_regs *regs)
>  {
>       volatile i2c8xx_t *i2c =3D (i2c8xx_t *)dev_id;
>=20
>       if (cpm_debug > 1)
>             printk(KERN_DEBUG "cpm_iic_interrupt(dev_id=3D%p)\n", dev_i=
d);
>=20
> #ifdef I2C_CHIP_ERRATA
>       /* Chip errata, clear enable.
>        * This seems to not be needed on rev D4 or newer CPUs.
>        * Someone with an older CPU needs to verify this.
>        */
>       i2c->i2c_i2mod &=3D ~1;
> #endif
>=20
>       /* Clear interrupt.
>       */
>       i2c->i2c_i2cer =3D 0xff;
>=20
>       /* Get 'me going again.
>       */
> #ifdef I2C_INTERRUPTIBLE_SLEEP
>       wake_up_interruptible(&iic_wait);
> #else
>       wake_up(&iic_wait);
> #endif
> }
>=20
> static void
> cpm_iic_init(struct i2c_algo_8xx_data *cpm_adap)
> {
>       volatile iic_t          *iip =3D cpm_adap->iip;
>       volatile i2c8xx_t *i2c =3D cpm_adap->i2c;
>       unsigned char brg;
>       bd_t *bd =3D (bd_t *)__res;
>=20
>       if (cpm_debug) printk(KERN_DEBUG "cpm_iic_init() - iip=3D%p\n",ii=
p);
>=20
>       /* Initialize the parameter ram.
>        * We need to make sure many things are initialized to zero,
>        * especially in the case of a microcode patch.
>        */
>       iip->iic_rstate =3D 0;
>       iip->iic_rdp =3D 0;
>       iip->iic_rbptr =3D 0;
>       iip->iic_rbc =3D 0;
>       iip->iic_rxtmp =3D 0;
>       iip->iic_tstate =3D 0;
>       iip->iic_tdp =3D 0;
>       iip->iic_tbptr =3D 0;
>       iip->iic_tbc =3D 0;
>       iip->iic_txtmp =3D 0;
>=20
>       /* Set up the IIC parameters in the parameter ram.
>       */
>       iip->iic_tbase =3D r_tbase =3D cpm_adap->dp_addr;
>       iip->iic_rbase =3D r_rbase =3D cpm_adap->dp_addr + sizeof(cbd_t)*=
2;
>=20
>       iip->iic_tfcr =3D SMC_EB;
>       iip->iic_rfcr =3D SMC_EB;
>=20
>       /* Set maximum receive size.
>       */
>       iip->iic_mrblr =3D CPM_MAX_READ;
>=20
>       /* Initialize Tx/Rx parameters.
>       */
>       if (cpm_adap->reloc =3D=3D 0) {
>             volatile cpm8xx_t *cp =3D cpm_adap->cp;
>=20
>             cp->cp_cpcr =3D
>                   mk_cr_cmd(CPM_CR_CH_I2C, CPM_CR_INIT_TRX) | CPM_CR_FL=
G;
>             while (cp->cp_cpcr & CPM_CR_FLG);
>       } else {
>             iip->iic_rbptr =3D iip->iic_rbase;
>             iip->iic_tbptr =3D iip->iic_tbase;
>             iip->iic_rstate   =3D 0;
>             iip->iic_tstate   =3D 0;
>       }
>=20
>       /* Select an arbitrary address.  Just make sure it is unique.
>       */
>       i2c->i2c_i2add =3D 0xfe;
>=20
>       /* Make clock run at 60 KHz.
>       */
>       brg =3D (unsigned char) (bd->bi_intfreq/(32*2*60000) -3);
>       i2c->i2c_i2brg =3D brg;
>=20
>       i2c->i2c_i2mod =3D 0x00;
>       i2c->i2c_i2com =3D 0x01; /* Master mode */
>=20
>       /* Disable interrupts.
>       */
>       i2c->i2c_i2cmr =3D 0;
>       i2c->i2c_i2cer =3D 0xff;
>=20
>       init_waitqueue_head(&iic_wait);
>=20
>       /* Install interrupt handler.
>       */
>       if (cpm_debug) {
>             printk (KERN_DEBUG "%s[%d] Install ISR for IRQ %d\n",
>                   __func__,__LINE__, CPMVEC_I2C);
>       }
>       cpm_install_handler(CPMVEC_I2C, cpm_iic_interrupt, (void *)i2c);
> }
>=20
>=20
> static int
> cpm_iic_shutdown(struct i2c_algo_8xx_data *cpm_adap)
> {
>       volatile i2c8xx_t *i2c =3D cpm_adap->i2c;
>=20
>       /* Shut down IIC.
>       */
>       i2c->i2c_i2mod &=3D ~1;
>       i2c->i2c_i2cmr =3D 0;
>       i2c->i2c_i2cer =3D 0xff;
>=20
>       return(0);
> }
>=20
> static void
> cpm_reset_iic_params(volatile iic_t *iip)
> {
>       iip->iic_tbase =3D r_tbase;
>       iip->iic_rbase =3D r_rbase;
>=20
>       iip->iic_tfcr =3D SMC_EB;
>       iip->iic_rfcr =3D SMC_EB;
>=20
>       iip->iic_mrblr =3D CPM_MAX_READ;
>=20
>       iip->iic_rstate =3D 0;
>       iip->iic_rdp =3D 0;
>       iip->iic_rbptr =3D iip->iic_rbase;
>       iip->iic_rbc =3D 0;
>       iip->iic_rxtmp =3D 0;
>       iip->iic_tstate =3D 0;
>       iip->iic_tdp =3D 0;
>       iip->iic_tbptr =3D iip->iic_tbase;
>       iip->iic_tbc =3D 0;
>       iip->iic_txtmp =3D 0;
> }
>=20
> #define BD_SC_NAK       ((ushort)0x0004) /* NAK - did not respond */
> #define BD_SC_OV        ((ushort)0x0002) /* OV - receive overrun */
> #define CPM_CR_CLOSE_RXBD     ((ushort)0x0007)
>=20
> static void force_close(struct i2c_algo_8xx_data *cpm)
> {
>       volatile i2c8xx_t *i2c =3D cpm->i2c;
>=20
>         if (cpm_debug)
>             printk(KERN_DEBUG "force_close()");
>=20
>       if (cpm->reloc =3D=3D 0) { /* micro code disabled */
>             volatile cpm8xx_t *cp =3D cpm->cp;
>             cp->cp_cpcr =3D
>                   mk_cr_cmd(CPM_CR_CH_I2C, CPM_CR_CLOSE_RXBD) |
>                   CPM_CR_FLG;
>=20
>             while (cp->cp_cpcr & CPM_CR_FLG);
>       }
>=20
>       i2c->i2c_i2cmr =3D 0x00;  /* Disable all interrupts */
>       i2c->i2c_i2cer =3D 0xff;
> }
>=20
> static void force_reinit(struct i2c_algo_8xx_data *cpm)
> {
>       volatile iic_t *iip =3D cpm->iip;
>       volatile i2c8xx_t *i2c =3D cpm->i2c;
>       volatile cpm8xx_t *cp =3D cpm->cp;
>       unsigned char brg;
>       bd_t *bd =3D (bd_t *)__res;
>=20
>       // Disable interrupts.
>       i2c->i2c_i2cmr =3D 0;
>       i2c->i2c_i2cer =3D 0xff;
>         // Clear enable
>       i2c->i2c_i2mod &=3D ~1;
>=20
>       // Initialize the parameter ram.
>       iip->iic_rstate =3D 0;
>       iip->iic_rdp =3D 0;
>       iip->iic_rbptr =3D 0;
>       iip->iic_rbc =3D 0;
>       iip->iic_rxtmp =3D 0;
>       iip->iic_tstate =3D 0;
>       iip->iic_tdp =3D 0;
>       iip->iic_tbptr =3D 0;
>       iip->iic_tbc =3D 0;
>       iip->iic_txtmp =3D 0;
>         iip->iic_tbase =3D r_tbase;
>       iip->iic_rbase =3D r_rbase;
>       iip->iic_tfcr =3D SMC_EB;
>       iip->iic_rfcr =3D SMC_EB;
>       iip->iic_mrblr =3D CPM_MAX_READ;
>=20
>       if (cpm->reloc =3D=3D 0)
>         {
>             cp->cp_cpcr =3D mk_cr_cmd(CPM_CR_CH_I2C, CPM_CR_INIT_TRX) |
> CPM_CR_FLG;
>             while (cp->cp_cpcr & CPM_CR_FLG);
>       }
>         else
>         {
>             iip->iic_rbptr =3D iip->iic_rbase;
>             iip->iic_tbptr =3D iip->iic_tbase;
>             iip->iic_rstate   =3D 0;
>             iip->iic_tstate   =3D 0;
>       }
>=20
>       // Select an arbitrary address.  Just make sure it is unique.
>       i2c->i2c_i2add =3D 0xfe;
>=20
>       // Make clock run at 60 KHz.
>       brg =3D (unsigned char) (bd->bi_intfreq/(32*2*60000) -3);
>       i2c->i2c_i2brg =3D brg;
>=20
>       i2c->i2c_i2mod =3D 0x00;
>       i2c->i2c_i2com =3D 0x01; /* Master mode */
> }
>=20
> /* Read from IIC...
>  * abyte =3D address byte, with r/w flag already set
>  */
> static int
> cpm_iic_read(struct i2c_algo_8xx_data *cpm, u_char abyte, char *buf, in=
t
> count)
> {
>       volatile iic_t *iip =3D cpm->iip;
>       volatile i2c8xx_t *i2c =3D cpm->i2c;
>       volatile cpm8xx_t *cp =3D cpm->cp;
>       volatile cbd_t    *tbdf, *rbdf;
>       u_char *tb;
>       unsigned long flags, tmo, timedout;
>=20
>       if (count >=3D CPM_MAX_READ)
>             return -EINVAL;
>=20
>       /* check for and use a microcode relocation patch */
>       if (cpm->reloc) {
>             cpm_reset_iic_params(iip);
>       }
>=20
>       tbdf =3D (cbd_t *)&cp->cp_dpmem[iip->iic_tbase];
>       rbdf =3D (cbd_t *)&cp->cp_dpmem[iip->iic_rbase];
>=20
>       /* To read, we need an empty buffer of the proper length.
>        * All that is used is the first byte for address, the remainder
>        * is just used for timing (and doesn't really have to exist).
>        */
>       tb =3D cpm->temp;
>       tb =3D (u_char *)(((uint)tb + 15) & ~15);
>       tb[0] =3D abyte;          /* Device address byte w/rw flag */
>=20
>       flush_dcache_range((unsigned long) tb, (unsigned long) (tb+1));
>=20
>       if (cpm_debug) printk(KERN_DEBUG "cpm_iic_read(abyte=3D0x%x)\n",
> abyte);
>=20
>       tbdf->cbd_bufaddr =3D __pa(tb);
>       tbdf->cbd_datlen =3D count + 1;
>       tbdf->cbd_sc =3D
>             BD_SC_READY | BD_SC_LAST |
>             BD_SC_WRAP | BD_IIC_START;
>=20
>       iip->iic_mrblr =3D count + 1; /* prevent excessive read, +1
>                               is needed otherwise will the
>                               RXB interrupt come too early */
>=20
>       /* flush will invalidate too. */
>       flush_dcache_range((unsigned long) buf, (unsigned long) (buf+coun=
t));
>=20
>       rbdf->cbd_datlen =3D 0;
>       rbdf->cbd_bufaddr =3D __pa(buf);
>=20
>       rbdf->cbd_sc =3D BD_SC_EMPTY | BD_SC_WRAP| BD_SC_INTRPT;
>         timedout =3D 0;
> #ifdef I2C_BUSY_WAIT
>       if(count > 16){
> #endif
>             /* Chip bug, set enable here */
>             local_irq_save(flags);
>             i2c->i2c_i2cmr =3D 0x13;  /* Enable some interupts */
>             i2c->i2c_i2cer =3D 0xff;
>             i2c->i2c_i2mod |=3D 1;    /* Enable */
>             i2c->i2c_i2com |=3D 0x80; /* Begin transmission */
>=20
>             /* Wait for IIC transfer */
> #ifdef I2C_INTERRUPTIBLE_SLEEP
>             tmo =3D interruptible_sleep_on_timeout(&iic_wait,1*HZ);
> #else
>             tmo =3D sleep_on_timeout(&iic_wait,1*HZ);
> #endif
>                 if(tmo =3D=3D 0) timedout=3D1;
>             local_irq_restore(flags);
> #ifdef I2C_BUSY_WAIT
>       } else { /* busy wait for small transfers, its faster */
>             i2c->i2c_i2cmr =3D 0x00;  /* Disable I2C interupts */
>             i2c->i2c_i2cer =3D 0xff;
>             i2c->i2c_i2mod |=3D 1;    /* Enable */
>             i2c->i2c_i2com |=3D 0x80; /* Begin transmission */
>             tmo =3D jiffies + 1*HZ;
>             while(!(i2c->i2c_i2cer & 0x11 || (timedout =3D
> time_after(jiffies, tmo)))); /* Busy wait, with a timeout */
>       }
> #endif
>         if(timedout)
>         {
>             printk(KERN_DEBUG "cpm_iic_read: timeout!\n");
>             force_reinit(cpm);
>             return -EIO;
>         }
>=20
> #ifdef I2C_INTERRUPTIBLE_SLEEP
>       if (signal_pending(current))
>         {
>             force_close(cpm);
>           if (cpm_debug)
>                 printk(KERN_DEBUG "cpm_iic_read: signal_pending! \n");
>           return -EINTR;
>         }
> #endif
>=20
> #ifdef I2C_CHIP_ERRATA
>       /* Chip errata, clear enable. This is not needed on rev D4 CPUs.
>        Disabling I2C too early may cause too short stop condition */
>       udelay(4);
>       i2c->i2c_i2mod &=3D ~1;
> #endif
>=20
>       if (cpm_debug) {
>             printk(KERN_DEBUG "tx sc %04x, rx sc %04x\n",
>                    tbdf->cbd_sc, rbdf->cbd_sc);
>       }
>=20
>       if (tbdf->cbd_sc & BD_SC_READY) {
>             printk(KERN_INFO "IIC read; complete but tbuf ready\n");
>             force_close(cpm);
>             printk(KERN_INFO "tx sc %04x, rx sc %04x\n",
>                    tbdf->cbd_sc, rbdf->cbd_sc);
>       }
>=20
>       if (tbdf->cbd_sc & BD_SC_NAK) {
>             if (cpm_debug)
>                   printk(KERN_DEBUG "IIC read; no ack\n");
>             return -EREMOTEIO;
>       }
>=20
>       if (rbdf->cbd_sc & BD_SC_EMPTY) {
>             /* force_close(cpm); */
>             if (cpm_debug){
>                   printk(KERN_DEBUG "IIC read; complete but rbuf empty\=
n");
>                   printk(KERN_DEBUG "tx sc %04x, rx sc %04x\n",
>                          tbdf->cbd_sc, rbdf->cbd_sc);
>             }
>             return -EREMOTEIO;
>       }
>=20
>       if (rbdf->cbd_sc & BD_SC_OV) {
>             if (cpm_debug)
>                   printk(KERN_DEBUG "IIC read; Overrun\n");
>             return -EREMOTEIO;;
>       }
>=20
>       if (cpm_debug) printk(KERN_DEBUG "read %d bytes\n",
> rbdf->cbd_datlen);
>=20
>       if (rbdf->cbd_datlen < count) {
>             if (cpm_debug)
>                   printk(KERN_DEBUG "IIC read; short, wanted %d got %d\=
n",
>                          count, rbdf->cbd_datlen);
>             return 0;
>       }
>=20
>       return count;
> }
>=20
> /* Write to IIC...
>  * addr =3D address byte, with r/w flag already set
>  */
> static int
> cpm_iic_write(struct i2c_algo_8xx_data *cpm, u_char abyte, char *buf,in=
t
> count)
> {
>       volatile iic_t *iip =3D cpm->iip;
>       volatile i2c8xx_t *i2c =3D cpm->i2c;
>       volatile cpm8xx_t *cp =3D cpm->cp;
>       volatile cbd_t    *tbdf;
>       u_char *tb;
>       unsigned long flags, tmo, timedout;
>=20
>       /* check for and use a microcode relocation patch */
>       if (cpm->reloc) {
>             cpm_reset_iic_params(iip);
>       }
>       tb =3D cpm->temp;
>       tb =3D (u_char *)(((uint)tb + 15) & ~15);
>       *tb =3D abyte;            /* Device address byte w/rw flag */
>=20
>       flush_dcache_range((unsigned long) tb, (unsigned long) (tb+1));
>       flush_dcache_range((unsigned long) buf, (unsigned long) (buf+coun=
t));
>=20
>       if (cpm_debug) printk(KERN_DEBUG "cpm_iic_write(abyte=3D0x%x)\n",
> abyte);
>=20
>       /* set up 2 descriptors */
>       tbdf =3D (cbd_t *)&cp->cp_dpmem[iip->iic_tbase];
>=20
>       tbdf[0].cbd_bufaddr =3D __pa(tb);
>       tbdf[0].cbd_datlen =3D 1;
>       tbdf[0].cbd_sc =3D BD_SC_READY | BD_IIC_START;
>=20
>       tbdf[1].cbd_bufaddr =3D __pa(buf);
>       tbdf[1].cbd_datlen =3D count;
>       tbdf[1].cbd_sc =3D BD_SC_READY | BD_SC_INTRPT | BD_SC_LAST |
> BD_SC_WRAP;
>=20
>         timedout =3D 0;
> #ifdef I2C_BUSY_WAIT
>       if(count > 16){
> #endif
>             /* Chip bug, set enable here */
>             local_irq_save(flags);
>             i2c->i2c_i2cmr =3D 0x13;  /* Enable some interupts */
>             i2c->i2c_i2cer =3D 0xff;
>             i2c->i2c_i2mod |=3D 1;    /* Enable */
>             i2c->i2c_i2com |=3D 0x80; /* Begin transmission */
>=20
>             /* Wait for IIC transfer */
> #ifdef I2C_INTERRUPTIBLE_SLEEP
>             tmo =3D interruptible_sleep_on_timeout(&iic_wait,1*HZ);
> #else
>             tmo =3D sleep_on_timeout(&iic_wait,1*HZ);
> #endif
>                 if(tmo =3D=3D 0) timedout=3D1;
>             local_irq_restore(flags);
> #ifdef I2C_BUSY_WAIT
>       } else {  /* busy wait for small transfers, its faster */
>             i2c->i2c_i2cmr =3D 0x00;  /* Disable I2C interupts */
>             i2c->i2c_i2cer =3D 0xff;
>             i2c->i2c_i2mod |=3D 1;    /* Enable */
>             i2c->i2c_i2com |=3D 0x80; /* Begin transmission */
>             tmo =3D jiffies + 1*HZ;
>             while(!(i2c->i2c_i2cer & 0x12 || (timedout =3D
> time_after(jiffies, tmo)))); /* Busy wait, with a timeout */
>       }
> #endif
>         if(timedout)
>         {
>             printk(KERN_DEBUG "cpm_iic_write: timeout!\n");
>             force_reinit(cpm);
>             return -EIO;
>         }
>=20
> #ifdef I2C_INTERRUPTIBLE_SLEEP
>       if (signal_pending(current))
>         {
>             force_close(cpm);
>           if (cpm_debug)
>                 printk(KERN_DEBUG "cpm_iic_write: signal_pending! \n");
>           return -EINTR;
>         }
> #endif
>=20
> #if I2C_CHIP_ERRATA
>       /* Chip errata, clear enable. This is not needed on rev D4 CPUs.
>        Disabling I2C too early may cause too short stop condition */
>       udelay(4);
>       i2c->i2c_i2mod &=3D ~1;
> #endif
>       if (cpm_debug) {
>             printk(KERN_DEBUG "tx0 sc %04x, tx1 sc %04x\n",
>                    tbdf[0].cbd_sc, tbdf[1].cbd_sc);
>       }
>=20
>       if ((tbdf[0].cbd_sc | tbdf[1].cbd_sc) & BD_SC_NAK) {
>             if (cpm_debug)
>                   printk(KERN_DEBUG "IIC write; no ack\n");
>             return 0;
>       }
>=20
>       if ((tbdf[0].cbd_sc | tbdf[1].cbd_sc) & BD_SC_READY) {
>             if (cpm_debug)
>                   printk(KERN_DEBUG "IIC write; complete but tbuf
> ready\n");
>             return 0;
>       }
>=20
>       return count;
> }
>=20
> /* See if an IIC address exists..
>  * addr =3D 7 bit address, unshifted
>  */
> static int
> cpm_iic_tryaddress(struct i2c_algo_8xx_data *cpm, int addr)
> {
>       volatile iic_t *iip =3D cpm->iip;
>       volatile i2c8xx_t *i2c =3D cpm->i2c;
>       volatile cpm8xx_t *cp =3D cpm->cp;
>       volatile cbd_t *tbdf, *rbdf;
>       u_char *tb;
>       unsigned long flags, len, tmo;
>=20
>       if (cpm_debug > 1)
>             printk(KERN_DEBUG "cpm_iic_tryaddress(cpm=3D%p,addr=3D%d)\n=
", cpm,
> addr);
>=20
>       /* check for and use a microcode relocation patch */
>       if (cpm->reloc) {
>             cpm_reset_iic_params(iip);
>       }
>=20
>       if (cpm_debug && addr =3D=3D 0) {
>             printk(KERN_DEBUG "iip %p, dp_addr 0x%x\n", cpm->iip,
> cpm->dp_addr);
>             printk(KERN_DEBUG "iic_tbase %d, r_tbase %d\n", iip->iic_tb=
ase,
> r_tbase);
>       }
>=20
>       tbdf =3D (cbd_t *)&cp->cp_dpmem[iip->iic_tbase];
>       rbdf =3D (cbd_t *)&cp->cp_dpmem[iip->iic_rbase];
>=20
>       tb =3D cpm->temp;
>       tb =3D (u_char *)(((uint)tb + 15) & ~15);
>=20
>       /* do a simple read */
>       tb[0] =3D (addr << 1) | 1;      /* device address (+ read) */
>       len =3D 2;
>=20
>       flush_dcache_range((unsigned long) tb, (unsigned long) (tb+1));
>=20
>       tbdf->cbd_bufaddr =3D __pa(tb);
>       tbdf->cbd_datlen =3D len;
>       tbdf->cbd_sc =3D
>             BD_SC_READY | BD_SC_LAST |
>             BD_SC_WRAP | BD_IIC_START;
>=20
>       rbdf->cbd_datlen =3D 0;
>       rbdf->cbd_bufaddr =3D __pa(tb+2);
>       rbdf->cbd_sc =3D BD_SC_EMPTY | BD_SC_WRAP | BD_SC_INTRPT;
>=20
>       local_irq_save(flags);
>       i2c->i2c_i2cmr =3D 0x13;  /* Enable some interupts */
>       i2c->i2c_i2cer =3D 0xff;
>       i2c->i2c_i2mod |=3D 1;    /* Enable */
>       i2c->i2c_i2com |=3D 0x80; /* Begin transmission */
>=20
>       if (cpm_debug > 1) printk(KERN_DEBUG "about to sleep\n");
>=20
>       /* wait for IIC transfer */
> #ifdef I2C_INTERRUPTIBLE_SLEEP
>       tmo =3D interruptible_sleep_on_timeout(&iic_wait,1*HZ);
> #else
>       tmo =3D sleep_on_timeout(&iic_wait,1*HZ);
> #endif
>       local_irq_restore(flags);
>=20
> #ifdef I2C_CHIP_ERRATA
>       /* Chip errata, clear enable. This is not needed on rev D4 CPUs.
>        Disabling I2C too early may cause too short stop condition */
>       udelay(4);
>       i2c->i2c_i2mod &=3D ~1;
> #endif
>=20
>       if (signal_pending(current) || !tmo){
>             force_close(cpm);
>             if(cpm_debug && !tmo)
>                   printk(KERN_DEBUG "IIC tryaddress: timeout!\n");
>             return -EIO;
>       }
>=20
>       if (cpm_debug > 1) printk(KERN_DEBUG "back from sleep\n");
>=20
>       if (tbdf->cbd_sc & BD_SC_NAK) {
>             if (cpm_debug > 1) printk(KERN_DEBUG "IIC try; no ack\n");
>             return 0;
>       }
>=20
>       if (tbdf->cbd_sc & BD_SC_READY) {
>             printk(KERN_INFO "IIC try; complete but tbuf ready\n");
>       }
>=20
>       return 1;
> }
>=20
> static int cpm_xfer(struct i2c_adapter *i2c_adap,
>                 struct i2c_msg msgs[],
>                 int num)
> {
>       struct i2c_algo_8xx_data *adap =3D i2c_adap->algo_data;
>       struct i2c_msg *pmsg;
>       int i, ret;
>       u_char addr;
>=20
>       for (i =3D 0; i < num; i++) {
>             pmsg =3D &msgs[i];
>=20
>             if (cpm_debug)
>                   printk(KERN_DEBUG "i2c-algo-8xx.o: "
>                          "#%d addr=3D0x%x flags=3D0x%x len=3D%d\n buf=3D=
%lx\n",
>                          i, pmsg->addr, pmsg->flags, pmsg->len, (unsign=
ed
> long)pmsg->buf);
>=20
>             addr =3D pmsg->addr << 1;
>             if (pmsg->flags & I2C_M_RD )
>                   addr |=3D 1;
>             if (pmsg->flags & I2C_M_REV_DIR_ADDR )
>                   addr ^=3D 1;
>=20
>             if (!(pmsg->flags & I2C_M_NOSTART)) {
>             }
>             if (pmsg->flags & I2C_M_RD ) {
>                   /* read bytes into buffer*/
>                   ret =3D cpm_iic_read(adap, addr, pmsg->buf, pmsg->len=
);
>                   if (cpm_debug)
>                         printk(KERN_DEBUG "i2c-algo-8xx.o: read %d
> bytes\n", ret);
>                   if (ret < pmsg->len ) {
>                         return (ret<0)? ret : -EREMOTEIO;
>                   }
>             } else {
>                   /* write bytes from buffer */
>                   ret =3D cpm_iic_write(adap, addr, pmsg->buf, pmsg->le=
n);
>                   if (cpm_debug)
>                         printk(KERN_DEBUG "i2c-algo-8xx.o: wrote %d\n",
> ret);
>                   if (ret < pmsg->len ) {
>                         return (ret<0) ? ret : -EREMOTEIO;
>                   }
>             }
>       }
>       return (num);
> }
>=20
> static int algo_control(struct i2c_adapter *adapter,
>       unsigned int cmd, unsigned long arg)
> {
>       return 0;
> }
>=20
> static u32 cpm_func(struct i2c_adapter *adap)
> {
>       return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_10BIT_ADDR |
>              I2C_FUNC_PROTOCOL_MANGLING;
> }
>=20
> /* -----exported algorithm data: ------------------------------------- =
 */
>=20
> static struct i2c_algorithm cpm_algo =3D {
>       "MPC8xx CPM algorithm",
>       I2C_ALGO_MPC8XX,
>       cpm_xfer,
>       NULL,
>       NULL,                   /* slave_xmit           */
>       NULL,                   /* slave_recv           */
>       algo_control,                 /* ioctl          */
>       cpm_func,               /* functionality  */
> };
>=20
> /*
>  * registering functions to load algorithms at runtime
>  */
> int i2c_8xx_add_bus(struct i2c_adapter *adap)
> {
>       int i;
>       struct i2c_algo_8xx_data *cpm_adap =3D adap->algo_data;
>=20
>       if (cpm_debug)
>             printk(KERN_DEBUG "i2c-algo-8xx.o: hw routines for %s
> registered.\n",
>                    adap->name);
>=20
>       /* register new adapter to i2c module... */
>=20
>       adap->id |=3D cpm_algo.id;
>       adap->algo =3D &cpm_algo;
>=20
> #ifdef MODULE
>       MOD_INC_USE_COUNT;
> #endif
>=20
>       i2c_add_adapter(adap);
>       cpm_iic_init(cpm_adap);
>=20
>       /* scan bus */
>       if (cpm_scan) {
>             printk(KERN_INFO " i2c-algo-8xx.o: scanning bus %s...\n",
>                    adap->name);
>             for (i =3D 0; i < 128; i++) {
>                   if (cpm_iic_tryaddress(cpm_adap, i)) {
>                         printk("(%02x)",i<<1);
>                   }
>             }
>             printk("\n");
>       }
>       return 0;
> }
>=20
> int i2c_8xx_del_bus(struct i2c_adapter *adap)
> {
>       int res;
>       struct i2c_algo_8xx_data *cpm_adap =3D adap->algo_data;
>=20
>       cpm_iic_shutdown(cpm_adap);
>=20
>       if ((res =3D i2c_del_adapter(adap)) < 0)
>             return res;
>=20
>       printk(KERN_INFO "i2c-algo-8xx.o: adapter unregistered:
> %s\n",adap->name);
>=20
> #ifdef MODULE
>       MOD_DEC_USE_COUNT;
> #endif
>       return 0;
> }
>=20
> EXPORT_SYMBOL(i2c_8xx_add_bus);
> EXPORT_SYMBOL(i2c_8xx_del_bus);
>=20
> int __init i2c_algo_8xx_init (void)
> {
>       printk(KERN_INFO "i2c-algo-8xx.o: i2c mpc8xx algorithm module ver=
sion
> %s (%s)\n", I2C_ALGO_8XX_VERSION, I2C_ALGO_8XX_DATE);
>       return 0;
> }
>=20
>=20
> #ifdef MODULE
> MODULE_AUTHOR("Brad Parker <brad@heeltoe.com>");
> MODULE_DESCRIPTION("I2C-Bus MPC8XX algorithm");
> #ifdef MODULE_LICENSE
> MODULE_LICENSE("GPL");
> #endif
>=20
> int init_module(void)
> {
>       return i2c_algo_8xx_init();
> }
>=20
> void cleanup_module(void)
> {
> }
> #endif
>=20
> _______________________________________________
> Linuxppc-embedded mailing list
> Linuxppc-embedded@ozlabs.org
> https://ozlabs.org/mailman/listinfo/linuxppc-embedded

^ permalink raw reply

* Re: Merging ppc32 and ppc64
From: Benjamin Herrenschmidt @ 2005-08-10 10:51 UTC (permalink / raw)
  To: Paul Mackerras; +Cc: linuxppc-dev, linuxppc64-dev
In-Reply-To: <17145.12993.672427.466466@cargo.ozlabs.ibm.com>


> Having the flattened device tree doesn't mean that we will be using
> the device tree less, it means we will be using it _more_.

The reason Segher is freaking out is because he wants to keep OF alive
in the future while the kernel is running.... (at least with SLOF)

I think that would require a different entry point with no flattened
tree, and changing of all the OF accessors to call OF instead of walking
an in-kernel tree. That is far from our current target though.

Ben.

^ permalink raw reply

* Re: Merging ppc32 and ppc64
From: Segher Boessenkool @ 2005-08-10 10:15 UTC (permalink / raw)
  To: Paul Mackerras; +Cc: linuxppc64-dev, Geert Uytterhoeven, Linux/PPC Development
In-Reply-To: <17145.13414.996858.522127@cargo.ozlabs.ibm.com>

> It is already the case (and has always been the case) that you can't
> boot a vmlinux image directly from OF - there is always either or both
> of yaboot or a zImage wrapper in between anyway.

If you fix the ELF headers, you can boot a vmlinux directly
from OF just fine.

I agree getting rid of all that RELOC() stuff is a worthy goal;
I just hope there's a better way to do it...

Anyway, I'm not going to stand in you guys way -- please
just don't make it harder for me without reason, though.


Segher

^ permalink raw reply

* Re: 8xx: i2c-algo-8xx - fixed timeout detection and transmission errors
From: Wolfgang Denk @ 2005-08-10  9:48 UTC (permalink / raw)
  To: Debora Liu; +Cc: Linuxppc-embedded
In-Reply-To: <20050810093254.3E98667EF5@ozlabs.org>

Dear Debora,

in message <20050810093254.3E98667EF5@ozlabs.org> you wrote:
> 
> >I had some problems on my MPC855M based board when I tried to access the
> >i2c bus.
> 
> Try update i2c-algo-8xx.c

I guess this will not solve Cajus' problems. Please take the time and
read his message again and you will see that his problems  will still
be present with your driver version. 

Best regards,

Wolfgang Denk

-- 
Software Engineering:  Embedded and Realtime Systems,  Embedded Linux
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd@denx.de
panic: can't find /

^ permalink raw reply

* Re: 8xx: i2c-algo-8xx - fixed timeout detection and transmission errors
From: Debora Liu @ 2005-08-10  9:37 UTC (permalink / raw)
  To: cajus.hahn@de.abb.com; +Cc: Linuxppc-embedded

Hello, cajus.hahn

In message <2005-08-10 15:27:57 cajus.hahn@de.abb.com> you wrote:

>Hi all,
>
>I had some problems on my MPC855M based board when I tried to access the
>i2c bus.

Try update i2c-algo-8xx.c

= = = = = = = = = = = = = = = = = = = =
				 
        Debora Liu
        deboralh@fel.com.cn
          2005-08-10

begin 600 i2c_algo_8xx-port_to_2_6.patch
M.'AX.B!P;W)T(&DR8RUA;&=O7SAX>"!T;R`R+C8-"@T*0F%S960@;VX@5&]M
M(%)I;FDG<R!A;F0@2F]A:VEM(%1J97)N;'5N9"=S('=O<FL-"@T*4VEG;F5D
M+6]F9BUB>3H@07)I<W1E=2!397)G:6\@4F]Z86YS:VD@1FEL:&\@/&%R:7-`
M8V%T:&5D<F%L;&%B<RYO<F<^#0H-"DEN9&5X.B`R+C8M.'AX+V1R:79E<G,O
M:3)C+V%L9V]S+VDR8RUA;&=O+3AX>"YC#0H]/3T]/3T]/3T]/3T]/3T]/3T]
M/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]
M/3T]#0HM+2T@+V1E=B]N=6QL"3$Y-S`M,#$M,#$@,#`Z,#`Z,#`N,#`P,#`P
M,#`P("LP,#`P#0HK*RL@,BXV+3AX>"]D<FEV97)S+VDR8R]A;&=O<R]I,F,M
M86QG;RTX>'@N8PDR,#`U+3`X+3`X(#`Y.C4U.C,P+C`P,#`P,#`P,"`M,#,P
M,`T*0$`@+3`L,"`K,2PV,3<@0$`-"BLO*@T**R`J(&DR8RUA;&=O+3AX>"YC
M(&DR>"!D<FEV97(@86QG;W)I=&AM<R!F;W(@35!#.%A8($-030T**R`J($-O
M<'ER:6=H="`H8RD@,3DY.2!$86X@36%L96L@*&1M86QE:T!J;&,N;F5T*2X-
M"BL@*@T**R`@("!4:&ES('!R;V=R86T@:7,@9G)E92!S;V9T=V%R93L@>6]U
M(&-A;B!R961I<W1R:6)U=&4@:70@86YD+V]R(&UO9&EF>0T**R`@("!I="!U
M;F1E<B!T:&4@=&5R;7,@;V8@=&AE($=.52!'96YE<F%L(%!U8FQI8R!,:6-E
M;G-E(&%S('!U8FQI<VAE9"!B>0T**R`@("!T:&4@1G)E92!3;V9T=V%R92!&
M;W5N9&%T:6]N.R!E:71H97(@=F5R<VEO;B`R(&]F('1H92!,:6-E;G-E+"!O
M<@T**R`@("`H870@>6]U<B!O<'1I;VXI(&%N>2!L871E<B!V97)S:6]N+@T*
M*PT**R`@("!4:&ES('!R;V=R86T@:7,@9&ES=')I8G5T960@:6X@=&AE(&AO
M<&4@=&AA="!I="!W:6QL(&)E('5S969U;"P-"BL@("`@8G5T(%=)5$A/550@
M04Y9(%=!4E)!3E19.R!W:71H;W5T(&5V96X@=&AE(&EM<&QI960@=V%R<F%N
M='D@;V8-"BL@("`@34520TA!3E1!0DE,2519(&]R($9)5$Y%4U,@1D]2($$@
M4$%25$E#54Q!4B!055)03U-%+B`@4V5E('1H90T**R`@("!'3E4@1V5N97)A
M;"!0=6)L:6,@3&EC96YS92!F;W(@;6]R92!D971A:6QS+@T**PT**R`@("!9
M;W4@<VAO=6QD(&AA=F4@<F5C96EV960@82!C;W!Y(&]F('1H92!'3E4@1V5N
M97)A;"!0=6)L:6,@3&EC96YS90T**R`@("!A;&]N9R!W:71H('1H:7,@<')O
M9W)A;3L@:68@;F]T+"!W<FET92!T;R!T:&4@1G)E92!3;V9T=V%R90T**R`@
M("!&;W5N9&%T:6]N+"!);F,N+"`V-S4@36%S<R!!=F4L($-A;6)R:61G92P@
M34$@,#(Q,SDL(%5302X-"BL@*@T**R`J(&UO=F5D(&EN=&\@<')O<&5R(&DR
M8R!I;G1E<F9A8V4[('-E<&%R871E9"!O=70@<&QA=&9O<FT@<W!E8VEF:6,-
M"BL@*B!P87)T<R!I;G1O(&DR8RUR<'@N8PT**R`J($)R860@4&%R:V5R("AB
M<F%D0&AE96QT;V4N8V]M*0T**R`J+PT**PT**R\O(%A86"!T;V1O#0HK+R\@
M=&EM96]U="!S;&5E<#\-"BL-"BLO*B`D260Z(&DR8RUA;&=O+3AX>"YC+'8@
M,2XW(#(P,#(O,#@O,#,@,C(Z-#@Z,3@@86,Y-#$P($5X<"`D("HO#0HK#0HK
M(VEN8VQU9&4@/&QI;G5X+VME<FYE;"YH/@T**R-I;F-L=61E(#QL:6YU>"]M
M;V1U;&4N:#X-"BLC:6YC;'5D92`\;&EN=7@O9&5L87DN:#X-"BLC:6YC;'5D
M92`\;&EN=7@O<VQA8BYH/@T**R-I;F-L=61E(#QL:6YU>"]V97)S:6]N+F@^
M#0HK(VEN8VQU9&4@/&QI;G5X+VEN:70N:#X-"BLC:6YC;'5D92`\87-M+W5A
M8V-E<W,N:#X-"BLC:6YC;'5D92`\;&EN=7@O:6]P;W)T+F@^#0HK(VEN8VQU
M9&4@/&QI;G5X+V5R<FYO+F@^#0HK(VEN8VQU9&4@/&QI;G5X+W-C:&5D+F@^
M#0HK#0HK(VEN8VQU9&4@/&%S;2]M<&,X>'@N:#X-"BLC:6YC;'5D92`\87-M
M+V-O;6UP<F]C+F@^#0HK#0HK(VEN8VQU9&4@/&QI;G5X+VDR8RYH/@T**R-I
M;F-L=61E(#QL:6YU>"]I,F,M86QG;RTX>'@N:#X-"BL-"BLC9&5F:6YE($-0
M35]-05A?4D5!1`DU,3,-"BLO*B!4<GD@=6YC;VUM96YT('1H:7,@:68@>6]U
M(&AA=F4@86X@;VQD97(@0U!5*&5A<FQI97(@=&AA;B!R978@1#0I("HO#0HK
M+RH@(V1E9FEN92!),D-?0TA)4%]%4E)!5$$@*B\-"BL-"BMS=&%T:6,@8VAA
M<B`J;6]D=6QE7VYA;64@/2`B:3)C7V%L9V]?.'AX(CL-"BLC9&5F:6YE($1%
M0E5'4"AL979E;"P@>"P@>2XN+BD@9&\@>R!<#0HK"0D)"6EF("AC<&U?9&5B
M=6<@/CT@;&5V96PI(%P-"BL)"0D)"7!R:6YT:RA+15).7T1%0E5'("(E<SH@
M(B!X+"!<#0HK"0D)"0D@("`@("`@;6]D=6QE7VYA;64L(",C('DI.R!<#0HK
M"0D)"7T@=VAI;&4H,"D-"BL-"BMS=&%T:6,@=V%I=%]Q=65U95]H96%D7W0@
M:6EC7W=A:70[#0HK<W1A=&EC('5S:&]R="!R7W1B87-E+"!R7W)B87-E.PT*
M*PT**VEN="!C<&U?<V-A;B`](#`[#0HK:6YT(&-P;5]D96)U9R`](#`[#0HK
M#0HK<W1A=&EC("!V;VED#0HK8W!M7VEI8U]I;G1E<G)U<'0H=F]I9"`J9&5V
M7VED+"!S=')U8W0@<'1?<F5G<R`J<F5G<RD-"BM[#0HK"79O;&%T:6QE(&DR
M8SAX>%]T("II,F,@/2`H:3)C.'AX7W0@*BED979?:60[#0HK#0HK"41%0E5'
M4"@R+"`B8W!M7VEI8U]I;G1E<G)U<'0H9&5V7VED/25P*5QN(BP@9&5V7VED
M*3L-"BL-"BLC:69D968@23)#7T-(25!?15)2051!#0HK"2\J($-H:7`@97)R
M871A+"!C;&5A<B!E;F%B;&4N#0HK"2`J(%1H:7,@<V5E;7,@=&\@;F]T(&)E
M(&YE961E9"!O;B!R978@1#0@;W(@;F5W97(@0U!5<RX-"BL)("H@4V]M96]N
M92!W:71H(&%N(&]L9&5R($-052!N965D<R!T;R!V97)I9GD@=&AI<RX-"BL)
M("HO#0HK"6DR8RT^:3)C7VDR;6]D("8]('XQ.PT**R-E;F1I9@T**PT**PDO
M*B!#;&5A<B!I;G1E<G)U<'0N#0HK"2HO#0HK"6DR8RT^:3)C7VDR8V5R(#T@
M,'AF9CL-"BL-"BL)+RH@1V5T("=M92!G;VEN9R!A9V%I;BX-"BL)*B\-"BL)
M=V%K95]U<%]I;G1E<G)U<'1I8FQE*"9I:6-?=V%I="D[#0HK?0T**PT**W-T
M871I8R!V;VED#0HK8W!M7VEI8U]I;FET*'-T<G5C="!I,F-?86QG;U\X>'A?
M9&%T82`J8W!M7V%D87`I#0HK>PT**PEV;VQA=&EL92!I:6-?=`D)*FEI<"`]
M(&-P;5]A9&%P+3YI:7`[#0HK"79O;&%T:6QE(&DR8SAX>%]T"2II,F,@/2!C
M<&U?861A<"T^:3)C.PT**PEU;G-I9VYE9"!C:&%R(&)R9SL-"BL)8F1?="`J
M8F0@/2`H8F1?="`J*5]?<F5S.PT**PT**PE$14)51U`H,2P@(F-P;5]I:6-?
M:6YI="@I("T@:6EP/25P7&XB+"!I:7`I.PT**PT**PDO*B!);FET:6%L:7IE
M('1H92!P87)A;65T97(@<F%M+@T**PD@*B!792!N965D('1O(&UA:V4@<W5R
M92!M86YY('1H:6YG<R!A<F4@:6YI=&EA;&EZ960@=&\@>F5R;RP-"BL)("H@
M97-P96-I86QL>2!I;B!T:&4@8V%S92!O9B!A(&UI8W)O8V]D92!P871C:"X-
M"BL)("HO#0HK"6EI<"T^:6EC7W)S=&%T92`](#`[#0HK"6EI<"T^:6EC7W)D
M<"`](#`[#0HK"6EI<"T^:6EC7W)B<'1R(#T@,#L-"BL):6EP+3YI:6-?<F)C
M(#T@,#L-"BL):6EP+3YI:6-?<GAT;7`@/2`P.PT**PEI:7`M/FEI8U]T<W1A
M=&4@/2`P.PT**PEI:7`M/FEI8U]T9'`@/2`P.PT**PEI:7`M/FEI8U]T8G!T
M<B`](#`[#0HK"6EI<"T^:6EC7W1B8R`](#`[#0HK"6EI<"T^:6EC7W1X=&UP
M(#T@,#L-"BL-"BL)+RH@4V5T('5P('1H92!)24,@<&%R86UE=&5R<R!I;B!T
M:&4@<&%R86UE=&5R(')A;2X-"BL)*B\-"BL):6EP+3YI:6-?=&)A<V4@/2!R
M7W1B87-E(#T@8W!M7V%D87`M/F1P7V%D9'([#0HK"6EI<"T^:6EC7W)B87-E
M(#T@<E]R8F%S92`](&-P;5]A9&%P+3YD<%]A9&1R("L@<VEZ96]F*&-B9%]T
M*2`J(#([#0HK#0HK"6EI<"T^:6EC7W1F8W(@/2!334-?14([#0HK"6EI<"T^
M:6EC7W)F8W(@/2!334-?14([#0HK#0HK"2\J(%-E="!M87AI;75M(')E8V5I
M=F4@<VEZ92X-"BL)*B\-"BL):6EP+3YI:6-?;7)B;'(@/2!#4$U?34%87U)%
M040[#0HK#0HK"2\J($EN:71I86QI>F4@5'@O4G@@<&%R86UE=&5R<RX-"BL)
M*B\-"BL):68@*&-P;5]A9&%P+3YR96QO8R`]/2`P*2![#0HK"0EV;VQA=&EL
M92!C<&TX>'A?="`J8W`@/2!C<&U?861A<"T^8W`[#0HK#0HK"0EC<"T^8W!?
M8W!C<B`]#0HK"0D);6M?8W)?8VUD*$-035]#4E]#2%]),D,L($-035]#4E])
M3DE47U126"D@?"!#4$U?0U)?1DQ'.PT**PD)=VAI;&4@*&-P+3YC<%]C<&-R
M("8@0U!-7T-27T9,1RD[#0HK"7T@96QS92![#0HK"0EI:7`M/FEI8U]R8G!T
M<B`](&EI<"T^:6EC7W)B87-E.PT**PD):6EP+3YI:6-?=&)P='(@/2!I:7`M
M/FEI8U]T8F%S93L-"BL)"6EI<"T^:6EC7W)S=&%T90D](#`[#0HK"0EI:7`M
M/FEI8U]T<W1A=&4)/2`P.PT**PE]#0HK#0HK"2\J(%-E;&5C="!A;B!A<F)I
M=')A<GD@861D<F5S<RX@($IU<W0@;6%K92!S=7)E(&ET(&ES('5N:7%U92X-
M"BL)*B\-"BL):3)C+3YI,F-?:3)A9&0@/2`P>&9E.PT**PT**PDO*B!-86ME
M(&-L;V-K(')U;B!A="`V,"!+2'HN#0HK"2HO#0HK"6)R9R`]("AU;G-I9VYE
M9"!C:&%R*2`H8F0M/F)I7VEN=&9R97$O*#,R*C(J-C`P,#`I("TS*3L-"BL)
M:3)C+3YI,F-?:3)B<F<@/2!B<F<[#0HK#0HK"6DR8RT^:3)C7VDR;6]D(#T@
M,'@P,#L-"BL):3)C+3YI,F-?:3)C;VT@/2`P>#`Q.R`O*B!-87-T97(@;6]D
M92`J+PT**PT**PDO*B!$:7-A8FQE(&EN=&5R<G5P=',N#0HK"2HO#0HK"6DR
M8RT^:3)C7VDR8VUR(#T@,#L-"BL):3)C+3YI,F-?:3)C97(@/2`P>&9F.PT*
M*PT**PEI;FET7W=A:71Q=65U95]H96%D*"9I:6-?=V%I="D[#0HK#0HK"2\J
M($EN<W1A;&P@:6YT97)R=7!T(&AA;F1L97(N#0HK"2HO#0HK"41%0E5'4"@Q
M+"`B26YS=&%L;"!)4U(@9F]R($E242`E9%QN(BP@0U!-5D5#7TDR0RD[#0HK
M"6-P;5]I;G-T86QL7VAA;F1L97(H0U!-5D5#7TDR0RP@8W!M7VEI8U]I;G1E
M<G)U<'0L("AV;VED("HI:3)C*3L-"BM]#0HK#0HK#0HK<W1A=&EC(&EN=`T*
M*V-P;5]I:6-?<VAU=&1O=VXH<W1R=6-T(&DR8U]A;&=O7SAX>%]D871A("IC
M<&U?861A<"D-"BM[#0HK"79O;&%T:6QE(&DR8SAX>%]T("II,F,@/2!C<&U?
M861A<"T^:3)C.PT**PT**PDO*B!3:'5T(&1O=VX@24E#+@T**PDJ+PT**PEI
M,F,M/FDR8U]I,FUO9"`F/2!^,3L-"BL):3)C+3YI,F-?:3)C;7(@/2`P.PT*
M*PEI,F,M/FDR8U]I,F-E<B`](#!X9F8[#0HK#0HK"7)E='5R;B`P.PT**WT-
M"BL-"BMS=&%T:6,@=F]I9`T**V-P;5]R97-E=%]I:6-?<&%R86US*'9O;&%T
M:6QE(&EI8U]T("II:7`I#0HK>PT**PEI:7`M/FEI8U]T8F%S92`](')?=&)A
M<V4[#0HK"6EI<"T^:6EC7W)B87-E(#T@<E]R8F%S93L-"BL-"BL):6EP+3YI
M:6-?=&9C<B`](%--0U]%0CL-"BL):6EP+3YI:6-?<F9C<B`](%--0U]%0CL-
M"BL-"BL):6EP+3YI:6-?;7)B;'(@/2!#4$U?34%87U)%040[#0HK#0HK"6EI
M<"T^:6EC7W)S=&%T92`](#`[#0HK"6EI<"T^:6EC7W)D<"`](#`[#0HK"6EI
M<"T^:6EC7W)B<'1R(#T@:6EP+3YI:6-?<F)A<V4[#0HK"6EI<"T^:6EC7W)B
M8R`](#`[#0HK"6EI<"T^:6EC7W)X=&UP(#T@,#L-"BL):6EP+3YI:6-?='-T
M871E(#T@,#L-"BL):6EP+3YI:6-?=&1P(#T@,#L-"BL):6EP+3YI:6-?=&)P
M='(@/2!I:7`M/FEI8U]T8F%S93L-"BL):6EP+3YI:6-?=&)C(#T@,#L-"BL)
M:6EP+3YI:6-?='AT;7`@/2`P.PT**WT-"BL-"BLC9&5F:6YE($)$7U-#7TY!
M2PD)*"AU<VAO<G0I,'@P,#`T*2`O*B!.04L@+2!D:60@;F]T(')E<W!O;F0@
M*B\-"BLC9&5F:6YE($)$7U-#7T]6"0DH*'5S:&]R="DP>#`P,#(I("\J($]6
M("T@<F5C96EV92!O=F5R<G5N("HO#0HK(V1E9FEN92!#4$U?0U)?0TQ/4T5?
M4EA"1`DH*'5S:&]R="DP>#`P,#<I#0HK#0HK<W1A=&EC('9O:60@9F]R8V5?
M8VQO<V4H<W1R=6-T(&DR8U]A;&=O7SAX>%]D871A("IC<&TI#0HK>PT**PEV
M;VQA=&EL92!I,F,X>'A?="`J:3)C(#T@8W!M+3YI,F,[#0HK"6EF("AC<&TM
M/G)E;&]C(#T](#`I('L@+RH@;6EC<F\@8V]D92!D:7-A8FQE9"`J+PT**PD)
M=F]L871I;&4@8W!M.'AX7W0@*F-P(#T@8W!M+3YC<#L-"BL-"BL)"41%0E5'
M4"@Q+"`B9F]R8V5?8VQO<V4H*5QN(BD[#0HK"0EC<"T^8W!?8W!C<B`]#0HK
M"0D);6M?8W)?8VUD*$-035]#4E]#2%]),D,L($-035]#4E]#3$]315]26$)$
M*2!\#0HK"0D)0U!-7T-27T9,1SL-"BL-"BL)"7=H:6QE("AC<"T^8W!?8W!C
M<B`F($-035]#4E]&3$<I.PT**PE]#0HK"6DR8RT^:3)C7VDR8VUR(#T@,'@P
M,#L)+RH@1&ES86)L92!A;&P@:6YT97)R=7!T<R`J+PT**PEI,F,M/FDR8U]I
M,F-E<B`](#!X9F8[#0HK?0T**PT**PT**R\J(%)E860@9G)O;2!)24,N+BX-
M"BL@*B!A8GET92`](&%D9')E<W,@8GET92P@=VET:"!R+W<@9FQA9R!A;')E
M861Y('-E=`T**R`J+PT**W-T871I8R!I;G0-"BMC<&U?:6EC7W)E860H<W1R
M=6-T(&DR8U]A;&=O7SAX>%]D871A("IC<&TL('5?8VAA<B!A8GET92P@8VAA
M<B`J8G5F+"!I;G0@8V]U;G0I#0HK>PT**PEV;VQA=&EL92!I:6-?="`J:6EP
M(#T@8W!M+3YI:7`[#0HK"79O;&%T:6QE(&DR8SAX>%]T("II,F,@/2!C<&TM
M/FDR8SL-"BL)=F]L871I;&4@8W!M.'AX7W0@*F-P(#T@8W!M+3YC<#L-"BL)
M=F]L871I;&4@8V)D7W0)*G1B9&8L("IR8F1F.PT**PEU7V-H87(@*G1B.PT*
M*PEU;G-I9VYE9"!L;VYG(&9L86=S+"!T;6\[#0HK#0HK"6EF("AC;W5N="`^
M/2!#4$U?34%87U)%040I#0HK"0ER971U<FX@+45)3E9!3#L-"BL-"BL)+RH@
M8VAE8VL@9F]R(&%N9"!U<V4@82!M:6-R;V-O9&4@<F5L;V-A=&EO;B!P871C
M:"`J+PT**PEI9B`H8W!M+3YR96QO8RD-"BL)"6-P;5]R97-E=%]I:6-?<&%R
M86US*&EI<"D[#0HK#0HK"71B9&8@/2`H8V)D7W0@*BDF8W`M/F-P7V1P;65M
M6VEI<"T^:6EC7W1B87-E73L-"BL)<F)D9B`]("AC8F1?="`J*29C<"T^8W!?
M9'!M96U;:6EP+3YI:6-?<F)A<V5=.PT**PT**PDO*B!4;R!R96%D+"!W92!N
M965D(&%N(&5M<'1Y(&)U9F9E<B!O9B!T:&4@<')O<&5R(&QE;F=T:"X-"BL)
M("H@06QL('1H870@:7,@=7-E9"!I<R!T:&4@9FER<W0@8GET92!F;W(@861D
M<F5S<RP@=&AE(')E;6%I;F1E<@T**PD@*B!I<R!J=7-T('5S960@9F]R('1I
M;6EN9R`H86YD(&1O97-N)W0@<F5A;&QY(&AA=F4@=&\@97AI<W0I+@T**PD@
M*B\-"BL)=&(@/2!C<&TM/G1E;7`[#0HK"71B(#T@*'5?8VAA<B`J*2@H*'5I
M;G0I=&(@*R`Q-2D@)B!^,34I.PT**PET8ELP72`](&%B>71E.PD)+RH@1&5V
M:6-E(&%D9')E<W,@8GET92!W+W)W(&9L86<@*B\-"BL-"BL)9FQU<VA?9&-A
M8VAE7W)A;F=E*"AU;G-I9VYE9"!L;VYG*2!T8BP@*'5N<VEG;F5D(&QO;F<I
M("AT8B`K(#$I*3L-"BL-"BL)1$5"54=0*#$L(")C<&U?:6EC7W)E860H86)Y
M=&4],'@E>"E<;B(L(&%B>71E*3L-"BL-"BL)=&)D9BT^8V)D7V)U9F%D9'(@
M/2!?7W!A*'1B*3L-"BL)=&)D9BT^8V)D7V1A=&QE;B`](&-O=6YT("L@,3L-
M"BL)=&)D9BT^8V)D7W-C(#T-"BL)"4)$7U-#7U)%0419('P@0D1?4T-?3$%3
M5"!\#0HK"0E"1%]30U]74D%0('P@0D1?24E#7U-405)4.PT**PT**PEI:7`M
M/FEI8U]M<F)L<B`](&-O=6YT("L@,3L@+RH@<')E=F5N="!E>&-E<W-I=F4@
M<F5A9"P@*S$-"BL)"0D)("`@("`@:7,@;F5E9&5D(&]T:&5R=VES92!W:6QL
M('1H90T**PD)"0D@("`@("!26$(@:6YT97)R=7!T(&-O;64@=&]O(&5A<FQY
M("HO#0HK#0HK"2\J(&9L=7-H('=I;&P@:6YV86QI9&%T92!T;V\N("HO#0HK
M"69L=7-H7V1C86-H95]R86YG92@H=6YS:6=N960@;&]N9RD@8G5F+"`H=6YS
M:6=N960@;&]N9RD@*&)U9BMC;W5N="DI.PT**PT**PER8F1F+3YC8F1?9&%T
M;&5N(#T@,#L-"BL)<F)D9BT^8V)D7V)U9F%D9'(@/2!?7W!A*&)U9BD[#0HK
M#0HK"7)B9&8M/F-B9%]S8R`]($)$7U-#7T5-4%19('P@0D1?4T-?5U)!4'P@
M0D1?4T-?24Y44E!4.PT**PT**PDO*B!#:&EP(&)U9RP@<V5T(&5N86)L92!H
M97)E("HO#0HK"6QO8V%L7VER<5]S879E*&9L86=S*3L-"BL):3)C+3YI,F-?
M:3)C;7(@/2`P>#$S.PDO*B!%;F%B;&4@<V]M92!I;G1E<G5P=',@*B\-"BL)
M:3)C+3YI,F-?:3)C97(@/2`P>&9F.PT**PEI,F,M/FDR8U]I,FUO9"!\/2`Q
M.PDO*B!%;F%B;&4@*B\-"BL)+RH-"BL)("H@0F5G:6X@=')A;G-M:7-S:6]N
M(&%N9"!F;W)C92!M87-T97(N#0HK"2`J(%-O;64@97)R;W)S*$-,*2!C;&5A
M<G,@=&AE($TO4R!B:70-"BL)("HO#0HK"6DR8RT^:3)C7VDR8V]M('P](#!X
M.#`@?"`P>#`Q.PT**PT**PDO*B!786ET(&9O<B!)24,@=')A;G-F97(@*B\-
M"BL)=&UO(#T@:6YT97)R=7!T:6)L95]S;&5E<%]O;E]T:6UE;W5T*"9I:6-?
M=V%I="PQ*DA:*3L-"BL);&]C86Q?:7)Q7W)E<W1O<F4H9FQA9W,I.PT**PT*
M*PEI9B`H<VEG;F%L7W!E;F1I;F<H8W5R<F5N="D@?'P@(71M;RE[#0HK"0EF
M;W)C95]C;&]S92AC<&TI.PT**PD)1$5"54=0*#$L("))24,@<F5A9#H@=&EM
M96]U="%<;B(I.PT**PD)<F5T=7)N("U%24\[#0HK"7T-"BLC:69D968@23)#
M7T-(25!?15)2051!#0HK"2\J($-H:7`@97)R871A+"!C;&5A<B!E;F%B;&4N
M(%1H:7,@:7,@;F]T(&YE961E9"!O;B!R978@1#0@0U!5<RX-"BL)($1I<V%B
M;&EN9R!),D,@=&]O(&5A<FQY(&UA>2!C875S92!T;V\@<VAO<G0@<W1O<"!C
M;VYD:71I;VX@*B\-"BL)=61E;&%Y*#0I.PT**PEI,F,M/FDR8U]I,FUO9"`F
M/2!^,3L-"BLC96YD:68-"BL-"BL)1$5"54=0*#$L(")T>"!S8R`E,#1X+"!R
M>"!S8R`E,#1X7&XB+"!T8F1F+3YC8F1?<V,L(')B9&8M/F-B9%]S8RD[#0HK
M#0HK"6EF("AT8F1F+3YC8F1?<V,@)B!"1%]30U]214%$62D@>PT**PD)<')I
M;G1K*$M%4DY?24Y&3R`B24E#(')E860[(&-O;7!L971E(&)U="!T8G5F(')E
M861Y7&XB*3L-"BL)"69O<F-E7V-L;W-E*&-P;2D[#0HK"0EP<FEN=&LH2T52
M3E])3D9/(")T>"!S8R`E,#1X+"!R>"!S8R`E,#1X7&XB+`T**PD)("`@("`@
M('1B9&8M/F-B9%]S8RP@<F)D9BT^8V)D7W-C*3L-"BL)?0T**PT**PEI9B`H
M=&)D9BT^8V)D7W-C("8@0D1?4T-?3D%+*2![#0HK"0E$14)51U`H,2P@(DE)
M0R!R96%D.R!N;R!A8VM<;B(I.PT**PD)<F5T=7)N("U%4D5-3U1%24\[#0HK
M"7T-"BL-"BL):68@*')B9&8M/F-B9%]S8R`F($)$7U-#7T5-4%19*2![#0HK
M"0DO*B!F;W)C95]C;&]S92AC<&TI.R`J+PT**PD)1$5"54=0*#$L("))24,@
M<F5A9#L@8V]M<&QE=&4@8G5T(')B=68@96UP='E<;B(I.PT**PD)1$5"54=0
M*#$L(")T>"!S8R`E,#1X+"!R>"!S8R`E,#1X7&XB+"!T8F1F+3YC8F1?<V,L
M(')B9&8M/F-B9%]S8RD[#0HK"0ER971U<FX@+45214U/5$5)3SL-"BL)?0T*
M*PT**PEI9B`H<F)D9BT^8V)D7W-C("8@0D1?4T-?3U8I('L-"BL)"41%0E5'
M4"@Q+"`B24E#(')E860[($]V97)R=6Y<;B(I.PT**PD)<F5T=7)N("U%4D5-
M3U1%24\[.PT**PE]#0HK#0HK"41%0E5'4"@Q+"`B<F5A9"`E9"!B>71E<UQN
M(BP@<F)D9BT^8V)D7V1A=&QE;BD[#0HK#0HK"6EF("AR8F1F+3YC8F1?9&%T
M;&5N(#P@8V]U;G0I('L-"BL)"41%0E5'4"@Q+"`B24E#(')E860[('-H;W)T
M+"!W86YT960@)60@9V]T("5D7&XB+"!C;W5N="P-"BL)"2`@("`@("!R8F1F
M+3YC8F1?9&%T;&5N*3L-"BL)"7)E='5R;B`P.PT**PE]#0HK#0HK"7)E='5R
M;B!C;W5N=#L-"BM]#0HK#0HK+RH@5W)I=&4@=&\@24E#+BXN#0HK("H@861D
M<B`](&%D9')E<W,@8GET92P@=VET:"!R+W<@9FQA9R!A;')E861Y('-E=`T*
M*R`J+PT**W-T871I8R!I;G0-"BMC<&U?:6EC7W=R:71E*'-T<G5C="!I,F-?
M86QG;U\X>'A?9&%T82`J8W!M+"!U7V-H87(@86)Y=&4L(&-H87(@*F)U9BQI
M;G0@8V]U;G0I#0HK>PT**PEV;VQA=&EL92!I:6-?="`J:6EP(#T@8W!M+3YI
M:7`[#0HK"79O;&%T:6QE(&DR8SAX>%]T("II,F,@/2!C<&TM/FDR8SL-"BL)
M=F]L871I;&4@8W!M.'AX7W0@*F-P(#T@8W!M+3YC<#L-"BL)=F]L871I;&4@
M8V)D7W0)*G1B9&8[#0HK"75?8VAA<B`J=&([#0HK"75N<VEG;F5D(&QO;F<@
M9FQA9W,L('1M;SL-"BL-"BL)+RH@8VAE8VL@9F]R(&%N9"!U<V4@82!M:6-R
M;V-O9&4@<F5L;V-A=&EO;B!P871C:"`J+PT**PEI9B`H8W!M+3YR96QO8RD-
M"BL)"6-P;5]R97-E=%]I:6-?<&%R86US*&EI<"D[#0HK"71B(#T@8W!M+3YT
M96UP.PT**PET8B`]("AU7V-H87(@*BDH*"AU:6YT*71B("L@,34I("8@?C$U
M*3L-"BL)*G1B(#T@86)Y=&4["0DO*B!$979I8V4@861D<F5S<R!B>71E('<O
M<G<@9FQA9R`J+PT**PT**PEF;'5S:%]D8V%C:&5?<F%N9V4H*'5N<VEG;F5D
M(&QO;F<I('1B+"`H=6YS:6=N960@;&]N9RD@*'1B*S$I*3L-"BL)9FQU<VA?
M9&-A8VAE7W)A;F=E*"AU;G-I9VYE9"!L;VYG*2!B=68L("AU;G-I9VYE9"!L
M;VYG*2`H8G5F*V-O=6YT*2D[#0HK#0HK"41%0E5'4"@Q+"`B8W!M7VEI8U]W
M<FET92AA8GET93TP>"5X*5QN(BP@86)Y=&4I.PT**PT**PDO*B!S970@=7`@
M,B!D97-C<FEP=&]R<R`J+PT**PET8F1F(#T@*&-B9%]T("HI)F-P+3YC<%]D
M<&UE;5MI:7`M/FEI8U]T8F%S95T[#0HK#0HK"71B9&9;,%TN8V)D7V)U9F%D
M9'(@/2!?7W!A*'1B*3L-"BL)=&)D9ELP72YC8F1?9&%T;&5N(#T@,3L-"BL)
M=&)D9ELP72YC8F1?<V,@/2!"1%]30U]214%$62!\($)$7TE)0U]35$%25#L-
M"BL-"BL)=&)D9ELQ72YC8F1?8G5F861D<B`](%]?<&$H8G5F*3L-"BL)=&)D
M9ELQ72YC8F1?9&%T;&5N(#T@8V]U;G0[#0HK"71B9&9;,5TN8V)D7W-C(#T@
M0D1?4T-?4D5!1%D@?"!"1%]30U])3E124%0@?"!"1%]30U],05-4('P@0D1?
M4T-?5U)!4#L-"BL-"BL)+RH@0VAI<"!B=6<L('-E="!E;F%B;&4@:&5R92`J
M+PT**PEL;V-A;%]I<G%?<V%V92AF;&%G<RD[#0HK"6DR8RT^:3)C7VDR8VUR
M(#T@,'@Q,SL)+RH@16YA8FQE('-O;64@:6YT97)U<'1S("HO#0HK"6DR8RT^
M:3)C7VDR8V5R(#T@,'AF9CL-"BL):3)C+3YI,F-?:3)M;V0@?#T@,3L)+RH@
M16YA8FQE("HO#0HK"2\J#0HK"2`J($)E9VEN('1R86YS;6ES<VEO;B!A;F0@
M9F]R8V4@;6%S=&5R+@T**PD@*B!3;VUE(&5R<F]R<RA#3"D@8VQE87)S('1H
M92!-+U,@8FET#0HK"2`J+PT**PEI,F,M/FDR8U]I,F-O;2!\/2`P>#@P('P@
M,'@P,3L-"BL-"BL)+RH@5V%I="!F;W(@24E#('1R86YS9F5R("HO#0HK"71M
M;R`](&EN=&5R<G5P=&EB;&5?<VQE97!?;VY?=&EM96]U="@F:6EC7W=A:70L
M,2I(6BD[#0HK"6QO8V%L7VER<5]R97-T;W)E*&9L86=S*3L-"BL-"BL):68@
M*'-I9VYA;%]P96YD:6YG*&-U<G)E;G0I('Q\("%T;6\I>PT**PD)9F]R8V5?
M8VQO<V4H8W!M*3L-"BL)"6EF("@A=&UO*0T**PD)"41%0E5'4"@Q+"`B24E#
M('=R:71E.B!T:6UE;W5T(5QN(BD[#0HK"0ER971U<FX@+45)3SL-"BL)?0T*
M*PT**R-I9B!),D-?0TA)4%]%4E)!5$$-"BL)+RH@0VAI<"!E<G)A=&$L(&-L
M96%R(&5N86)L92X@5&AI<R!I<R!N;W0@;F5E9&5D(&]N(')E=B!$-"!#4%5S
M+@T**PD@1&ES86)L:6YG($DR0R!T;V\@96%R;'D@;6%Y(&-A=7-E('1O;R!S
M:&]R="!S=&]P(&-O;F1I=&EO;B`J+PT**PEU9&5L87DH-"D[#0HK"6DR8RT^
M:3)C7VDR;6]D("8]('XQ.PT**R-E;F1I9@T**PE$14)51U`H,2P@(G1X,"!S
M8R`E,#1X+"!T>#$@<V,@)3`T>%QN(BP@=&)D9ELP72YC8F1?<V,L#0HK"2`@
M("`@("!T8F1F6S%=+F-B9%]S8RD[#0HK#0HK"6EF("@H=&)D9ELP72YC8F1?
M<V,@?"!T8F1F6S%=+F-B9%]S8RD@)B!"1%]30U].04LI('L-"BL)"41%0E5'
M4"@Q+"`B24E#('=R:71E.R!N;R!A8VM<;B(I.PT**PD)<F5T=7)N(#`[#0HK
M"7T-"BL-"BL):68@*"AT8F1F6S!=+F-B9%]S8R!\('1B9&9;,5TN8V)D7W-C
M*2`F($)$7U-#7U)%0419*2![#0HK"0E$14)51U`H,2P@(DE)0R!W<FET93L@
M8V]M<&QE=&4@8G5T('1B=68@<F5A9'E<;B(I.PT**PD)<F5T=7)N(#`[#0HK
M"7T-"BL-"BL)<F5T=7)N(&-O=6YT.PT**WT-"BL-"BLO*B!3964@:68@86X@
M24E#(&%D9')E<W,@97AI<W1S+BX-"BL@*B!A9&1R(#T@-R!B:70@861D<F5S
M<RP@=6YS:&EF=&5D#0HK("HO#0HK<W1A=&EC(&EN=`T**V-P;5]I:6-?=')Y
M861D<F5S<RAS=')U8W0@:3)C7V%L9V]?.'AX7V1A=&$@*F-P;2P@:6YT(&%D
M9'(I#0HK>PT**PEV;VQA=&EL92!I:6-?="`J:6EP(#T@8W!M+3YI:7`[#0HK
M"79O;&%T:6QE(&DR8SAX>%]T("II,F,@/2!C<&TM/FDR8SL-"BL)=F]L871I
M;&4@8W!M.'AX7W0@*F-P(#T@8W!M+3YC<#L-"BL)=F]L871I;&4@8V)D7W0@
M*G1B9&8L("IR8F1F.PT**PEU7V-H87(@*G1B.PT**PEU;G-I9VYE9"!L;VYG
M(&9L86=S+"!L96XL('1M;SL-"BL-"BL)1$5"54=0*#(L(")C<&U?:6EC7W1R
M>6%D9')E<W,H8W!M/25P+&%D9'(])60I7&XB+"!C<&TL(&%D9'(I.PT**PT*
M*PDO*B!C:&5C:R!F;W(@86YD('5S92!A(&UI8W)O8V]D92!R96QO8V%T:6]N
M('!A=&-H("HO#0HK"6EF("AC<&TM/G)E;&]C*0T**PD)8W!M7W)E<V5T7VEI
M8U]P87)A;7,H:6EP*3L-"BL-"BL):68@*&%D9'(@/3T@,"D@>PT**PD)1$5"
M54=0*#$L(")I:7`@)7`L(&1P7V%D9'(@,'@E>%QN(BP@8W!M+3YI:7`L(&-P
M;2T^9'!?861D<BD[#0HK"0E$14)51U`H,2P@(FEI8U]T8F%S92`E9"P@<E]T
M8F%S92`E9%QN(BP@:6EP+3YI:6-?=&)A<V4L#0HK"0D@("`@("`@<E]T8F%S
M92D[#0HK"7T-"BL-"BL)=&)D9B`]("AC8F1?="`J*29C<"T^8W!?9'!M96U;
M:6EP+3YI:6-?=&)A<V5=.PT**PER8F1F(#T@*&-B9%]T("HI)F-P+3YC<%]D
M<&UE;5MI:7`M/FEI8U]R8F%S95T[#0HK#0HK"71B(#T@8W!M+3YT96UP.PT*
M*PET8B`]("AU7V-H87(@*BDH*"AU:6YT*71B("L@,34I("8@?C$U*3L-"BL-
M"BL)+RH@9&\@82!S:6UP;&4@<F5A9"`J+PT**PET8ELP72`]("AA9&1R(#P\
M(#$I('P@,3L)+RH@9&5V:6-E(&%D9')E<W,@*"L@<F5A9"D@*B\-"BL);&5N
M(#T@,CL-"BL-"BL)9FQU<VA?9&-A8VAE7W)A;F=E*"AU;G-I9VYE9"!L;VYG
M*2!T8BP@*'5N<VEG;F5D(&QO;F<I("AT8BLQ*2D[#0HK#0HK"71B9&8M/F-B
M9%]B=69A9&1R(#T@7U]P82AT8BD[#0HK"71B9&8M/F-B9%]D871L96X@/2!L
M96X[#0HK"71B9&8M/F-B9%]S8R`]#0HK"0E"1%]30U]214%$62!\($)$7U-#
M7TQ!4U0@?`T**PD)0D1?4T-?5U)!4"!\($)$7TE)0U]35$%25#L-"BL-"BL)
M<F)D9BT^8V)D7V1A=&QE;B`](#`[#0HK"7)B9&8M/F-B9%]B=69A9&1R(#T@
M7U]P82AT8BLR*3L-"BL)<F)D9BT^8V)D7W-C(#T@0D1?4T-?14U05%D@?"!"
M1%]30U]74D%0('P@0D1?4T-?24Y44E!4.PT**PT**PDO*B!#:&EP(&)U9RP@
M<V5T(&5N86)L92!H97)E("HO#0HK"6QO8V%L7VER<5]S879E*&9L86=S*3L-
M"BL):3)C+3YI,F-?:3)C;7(@/2`P>#$S.PDO*B!%;F%B;&4@<V]M92!I;G1E
M<G5P=',@*B\-"BL):3)C+3YI,F-?:3)C97(@/2`P>&9F.PT**PEI,F,M/FDR
M8U]I,FUO9"!\/2`Q.PDO*B!%;F%B;&4@*B\-"BL)+RH-"BL)("H@0F5G:6X@
M=')A;G-M:7-S:6]N(&%N9"!F;W)C92!M87-T97(N#0HK"2`J(%-O;64@97)R
M;W)S*$-,*2!C;&5A<G,@=&AE($TO4R!B:70-"BL)("HO#0HK"6DR8RT^:3)C
M7VDR8V]M('P](#!X.#`@?"`P>#`Q.PT**PT**PDO*B!786ET(&9O<B!)24,@
M=')A;G-F97(@*B\-"BL)=&UO(#T@:6YT97)R=7!T:6)L95]S;&5E<%]O;E]T
M:6UE;W5T*"9I:6-?=V%I="PQ*DA:*3L-"BL);&]C86Q?:7)Q7W)E<W1O<F4H
M9FQA9W,I.PT**PT**R-I9F1E9B!),D-?0TA)4%]%4E)!5$$-"BL)+RH@0VAI
M<"!E<G)A=&$L(&-L96%R(&5N86)L92X@5&AI<R!I<R!N;W0@;F5E9&5D(&]N
M(')E=B!$-"!#4%5S+@T**PD@1&ES86)L:6YG($DR0R!T;V\@96%R;'D@;6%Y
M(&-A=7-E('1O;R!S:&]R="!S=&]P(&-O;F1I=&EO;B`J+PT**PEU9&5L87DH
M-"D[#0HK"6DR8RT^:3)C7VDR;6]D("8]('XQ.PT**R-E;F1I9@T**PT**PEI
M9B`H<VEG;F%L7W!E;F1I;F<H8W5R<F5N="D@?'P@(71M;RE[#0HK"0EF;W)C
M95]C;&]S92AC<&TI.PT**PD):68@*"%T;6\I#0HK"0D)1$5"54=0*#$L("))
M24,@=')Y861D<F5S<SH@=&EM96]U="%<;B(I.PT**PD)<F5T=7)N("U%24\[
M#0HK"7T-"BL-"BL)1$5"54=0*#(L(")B86-K(&9R;VT@<VQE97!<;B(I.PT*
M*PT**PEI9B`H=&)D9BT^8V)D7W-C("8@0D1?4T-?3D%+*2![#0HK"0E$14)5
M1U`H,BP@(DE)0R!T<GD[(&YO(&%C:UQN(BD[#0HK"0ER971U<FX@,#L-"BL)
M?0T**PT**PEI9B`H=&)D9BT^8V)D7W-C("8@0D1?4T-?4D5!1%DI#0HK"0EP
M<FEN=&LH2T523E])3D9/("))24,@=')Y.R!C;VUP;&5T92!B=70@=&)U9B!R
M96%D>5QN(BD[#0HK#0HK"7)E='5R;B`Q.PT**WT-"BL-"BMS=&%T:6,@:6YT
M(&-P;5]X9F5R*'-T<G5C="!I,F-?861A<'1E<B`J:3)C7V%D87`L#0HK"0D@
M("`@<W1R=6-T(&DR8U]M<V<@;7-G<UM=+`T**PD)("`@(&EN="!N=6TI#0HK
M>PT**PES=')U8W0@:3)C7V%L9V]?.'AX7V1A=&$@*F%D87`@/2!I,F-?861A
M<"T^86QG;U]D871A.PT**PES=')U8W0@:3)C7VUS9R`J<&US9SL-"BL):6YT
M(&DL(')E=#L-"BL)=5]C:&%R(&%D9'([#0HK#0HK"69O<B`H:2`](#`[(&D@
M/"!N=6T[(&DK*RD@>PT**PD)<&US9R`]("9M<V=S6VE=.PT**PT**PD)1$5"
M54=0*#$L("(C)60@861D<CTP>"5X(&9L86=S/3!X)7@@;&5N/25D7&X@8G5F
M/25P7&XB+`T**PD)("`@("`@(&DL('!M<V<M/F%D9'(L('!M<V<M/F9L86=S
M+"!P;7-G+3YL96XL('!M<V<M/F)U9BD[#0HK#0HK"0EA9&1R(#T@<&US9RT^
M861D<B`\/"`Q.PT**PD):68@*'!M<V<M/F9L86=S("8@23)#7TU?4D0I#0HK
M"0D)861D<B!\/2`Q.PT**PD):68@*'!M<V<M/F9L86=S("8@23)#7TU?4D56
M7T1)4E]!1$12*0T**PD)"6%D9'(@7CT@,3L-"BL-"BL)"6EF("AP;7-G+3YF
M;&%G<R`F($DR0U]-7U)$*2![#0HK"0D)+RH@<F5A9"!B>71E<R!I;G1O(&)U
M9F9E<BHO#0HK"0D)<F5T(#T@8W!M7VEI8U]R96%D*&%D87`L(&%D9'(L('!M
M<V<M/F)U9BP@<&US9RT^;&5N*3L-"BL)"0E$14)51U`H,2P@(G)E860@)60@
M8GET97-<;B(L(')E="D[#0HK"0D):68@*')E="`\('!M<V<M/FQE;BD-"BL)
M"0D)<F5T=7)N("AR970@/"`P*3\@<F5T.BU%4D5-3U1%24\[#0HK"0E](&5L
M<V4@>PT**PD)"2\J('=R:71E(&)Y=&5S(&9R;VT@8G5F9F5R("HO#0HK"0D)
M<F5T(#T@8W!M7VEI8U]W<FET92AA9&%P+"!A9&1R+"!P;7-G+3YB=68L('!M
M<V<M/FQE;BD[#0HK"0D)1$5"54=0*#$L(")W<F]T92`E9%QN(BP@<F5T*3L-
M"BL)"0EI9B`H<F5T(#P@<&US9RT^;&5N*0T**PD)"0ER971U<FX@*')E="`\
M(#`I/R!R970Z+45214U/5$5)3SL-"BL)"7T-"BL)?0T**PER971U<FX@;G5M
M.PT**WT-"BL-"BMS=&%T:6,@=3,R(&-P;5]F=6YC*'-T<G5C="!I,F-?861A
M<'1E<B`J861A<"D-"BM[#0HK"7)E='5R;B!),D-?1E5.0U]334)54U]%355,
M('P@23)#7T953D-?,3!"251?041$4B!\#0HK"2`@("`@("!),D-?1E5.0U]0
M4D]43T-/3%]-04Y'3$E.1SL-"BM]#0HK#0HK<W1A=&EC('-T<G5C="!I,F-?
M86QG;W)I=&AM(&DR8U]A;&=O7SAX>"`]('L-"BL)+FYA;64@/2`B35!#.'AX
M($-032!A;&=O<FET:&TB+`T**PDN:60@/2!),D-?04Q'3U]-4$,X6%@L#0HK
M"2YM87-T97)?>&9E<B`](&-P;5]X9F5R+`T**PDN9G5N8W1I;VYA;&ET>2`]
M(&-P;5]F=6YC+`T**WT[#0HK#0HK+RH-"BL@*B!R96=I<W1E<FEN9R!F=6YC
M=&EO;G,@=&\@;&]A9"!A;&=O<FET:&US(&%T(')U;G1I;64-"BL@*B\-"BMI
M;G0@:3)C7SAX>%]A9&1?8G5S*'-T<G5C="!I,F-?861A<'1E<B`J861A<"D-
M"BM[#0HK"6EN="!I.PT**PES=')U8W0@:3)C7V%L9V]?.'AX7V1A=&$@*F-P
M;5]A9&%P(#T@861A<"T^86QG;U]D871A.PT**PT**PE$14)51U`H,2P@(FAW
M(')O=71I;F5S(&9O<B`E<R!R96=I<W1E<F5D+EQN(BP@861A<"T^;F%M92D[
M#0HK#0HK"2\J(')E9VES=&5R(&YE=R!A9&%P=&5R('1O(&DR8R!M;V1U;&4N
M+BX@*B\-"BL-"BL)861A<"T^:60@?#T@:3)C7V%L9V]?.'AX+FED.PT**PEA
M9&%P+3YA;&=O(#T@)FDR8U]A;&=O7SAX>#L-"BL-"BL):3)C7V%D9%]A9&%P
M=&5R*&%D87`I.PT**PEC<&U?:6EC7VEN:70H8W!M7V%D87`I.PT**PT**PDO
M*B!S8V%N(&)U<R`J+PT**PEI9B`H8W!M7W-C86XI('L-"BL)"7!R:6YT:RA+
M15).7TE.1D\@(B5S.B!S8V%N;FEN9R!B=7,@)7,N+BY<;B(L(&UO9'5L95]N
M86UE+`T**PD)("`@("`@(&%D87`M/FYA;64I.PT**PD)9F]R("AI(#T@,#L@
M:2`\(#$R.#L@:2LK*0T**PD)"6EF("AC<&U?:6EC7W1R>6%D9')E<W,H8W!M
M7V%D87`L(&DI*2![#0HK"0D)"7!R:6YT:R@B*"4P,G@I(BP@:2`\/"`Q*3L-
M"BL)"0E]#0HK"0EP<FEN=&LH(EQN(BD[#0HK"7T-"BL)<F5T=7)N(#`[#0HK
M?0T**PT**VEN="!I,F-?.'AX7V1E;%]B=7,H<W1R=6-T(&DR8U]A9&%P=&5R
M("IA9&%P*0T**WL-"BL):6YT(')E<SL-"BL)<W1R=6-T(&DR8U]A;&=O7SAX
M>%]D871A("IC<&U?861A<"`](&%D87`M/F%L9V]?9&%T83L-"BL-"BL)8W!M
M7VEI8U]S:'5T9&]W;BAC<&U?861A<"D[#0HK#0HK"6EF("@H<F5S(#T@:3)C
M7V1E;%]A9&%P=&5R*&%D87`I*2`\(#`I#0HK"0ER971U<FX@<F5S.PT**PT*
M*PEP<FEN=&LH2T523E])3D9/("(E<SH@861A<'1E<B!U;G)E9VES=&5R960Z
M("5S7&XB+"!M;V1U;&5?;F%M92P-"BL)("`@("`@(&%D87`M/FYA;64I.PT*
M*PT**PER971U<FX@,#L-"BM]#0HK#0HK;6]D=6QE7W!A<F%M*&-P;5]D96)U
M9RP@:6YT+"!37TE254=/('P@4U])5U534BD[#0HK34]$54Q%7U!!4DU?1$53
M0RAC<&U?9&5B=6<L(")3971S('1H92!D96)U9R!L979E;"X@*#`@/2!N;VYE
M+"`Q(#T@;F]R;6%L+"`B#0HK"0D@(CXQ(#T@<&QE;G1Y(BD[#0HK34]$54Q%
M7T%55$A/4B@B0G)A9"!087)K97(@/&)R861`:&5E;'1O92YC;VT^(BD[#0HK
M34]$54Q%7T1%4T-225!424].*")),D,M0G5S($U00SA86"!A;&=O<FET:&TB
M*3L-"BM-3T153$5?3$E#14Y312@B1U!,(BD[#0HK#0HK15A03U)47U-934)/
M3"AI,F-?.'AX7V%D9%]B=7,I.PT**T584$]25%]364U"3TPH:3)C7SAX>%]D
M96Q?8G5S*3L-"BL-"DEN9&5X.B`R+C8M.'AX+V1R:79E<G,O:3)C+V%L9V]S
M+TUA:V5F:6QE#0H]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]
M/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]#0HM+2T@,BXV+3AX
M>"YO<FEG+V1R:79E<G,O:3)C+V%L9V]S+TUA:V5F:6QE"3(P,#4M,#@M,#@@
M,#DZ-3`Z-3<N,#`P,#`P,#`P("TP,S`P#0HK*RL@,BXV+3AX>"]D<FEV97)S
M+VDR8R]A;&=O<R]-86ME9FEL90DR,#`U+3`X+3`X(#`Y.C4P.C4Y+C`P,#`P
M,#`P,"`M,#,P,`T*0$`@+3@L-B`K."PW($!`#0H@;V)J+20H0T].1DE'7TDR
M0U]!3$=/251%*0DK/2!I,F,M86QG;RUI=&4N;PT*(&]B:BTD*$-/3D9)1U])
M,D-?04Q'3U]324)95$4I"2L](&DR8RUA;&=O+7-I8GET92YO#0H@;V)J+20H
M0T].1DE'7TDR0U]!3$=/7U-'22D)*ST@:3)C+6%L9V\M<V=I+F\-"BMO8FHM
M)"A#3TY&24=?23)#7T%,1T\X6%@I"2L](&DR8RUA;&=O+3AX>"YO#0H@#0H@
M:69E<2`H)"A#3TY&24=?23)#7T1%0E5'7T%,1T\I+'DI#0H@15A44D%?0T9,
M04=3("L]("U$1$5"54<-"DEN9&5X.B`R+C8M.'AX+VEN8VQU9&4O;&EN=7@O
M:3)C+6%L9V\M.'AX+F@-"CT]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]
M/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T-"BTM+2`O
M9&5V+VYU;&P),3DW,"TP,2TP,2`P,#HP,#HP,"XP,#`P,#`P,#`@*S`P,#`-
M"BLK*R`R+C8M.'AX+VEN8VQU9&4O;&EN=7@O:3)C+6%L9V\M.'AX+F@),C`P
M-2TP."TP."`P.3HU,#HU.2XP,#`P,#`P,#`@+3`S,#`-"D!`("TP+#`@*S$L
M,C@@0$`-"BLO*B`M+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM
M+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM("HO#0HK
M+RH@:3)C+6%L9V\M.'AX+F@@:3)C(&1R:79E<B!A;&=O<FET:&US(&9O<B!-
M4%@X6%@@0U!-"0D)("`@("`J+PT**R\J("TM+2TM+2TM+2TM+2TM+2TM+2TM
M+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM
M+2TM+2TM+2T@*B\-"BL-"BLO*B`D260D("HO#0HK#0HK(VEF;F1E9B!),D-?
M04Q'3U\X6%A?2`T**R-D969I;F4@23)#7T%,1T]?.%A87T@-"BL-"BLC:6YC
M;'5D92`\;&EN=7@O:3)C+F@^#0HK(VEN8VQU9&4@/&%S;2\X>'A?:6UM87`N
M:#X-"BLC:6YC;'5D92`\87-M+V-O;6UP<F]C+F@^#0HK#0HK<W1R=6-T(&DR
M8U]A;&=O7SAX>%]D871A('L-"BL)=6EN="!D<%]A9&1R.PT**PEI;G0@<F5L
M;V,[#0HK"79O;&%T:6QE(&DR8SAX>%]T("II,F,[#0HK"79O;&%T:6QE(&EI
M8U]T"2II:7`[#0HK"79O;&%T:6QE(&-P;3AX>%]T("IC<#L-"BL-"BL)=5]C
M:&%R"71E;7!;-3$S73L-"BM].PT**PT**VEN="!I,F-?.'AX7V%D9%]B=7,H
M<W1R=6-T(&DR8U]A9&%P=&5R("HI.PT**VEN="!I,F-?.'AX7V1E;%]B=7,H
M<W1R=6-T(&DR8U]A9&%P=&5R("HI.PT**PT**R-E;F1I9B`O*B!),D-?04Q'
13U\X6%A?2"`J+PT**PT*#0I
`
end

^ permalink raw reply

* 8xx: i2c-algo-8xx - fixed timeout detection and transmission errors
From: cajus.hahn @ 2005-08-10  7:27 UTC (permalink / raw)
  To: linuxppc-embedded





Hi all,

I had some problems on my MPC855M based board when I tried to access th=
e
i2c bus.
The cause were some disturbances on the i2c bus. If a slave device or
another master device hold the SDA or SCL line low, the CPM will get in=
to a
state, where no more transmissions are made. The  only way I found, to =
get
the CPM back to work, was a complete re-initialisation. -> force_reinit=
()
In this case the busy-wait for transmissions with count < 16 will lock =
the
complete system (CPU load 99.9%)
I added the define I2C_BUSY_WAIT to switch between faster access or saf=
er
system.
I found out that the i2c-algo-8xx.c has a bug in cpm_iic_read() and
cpm_iic_write(): the timeout detection will not work in the case of cou=
nt <
16.
I also added the define I2C_INTERRUPTIBLE_SLEEP: the old driver reporte=
d
IO-error (-EIO) if a timeout occured (which was not working, see above)=
 or
if a signal was pending. This caused some problems if the process recei=
ves
user-signals. The driver will report IO-error, which is not correct. Wi=
th
the busy-wait this effect might not be seen, because there will be no
process scheduling -> no signals might be send.
My modified file is appended. The defines for  I2C_BUSY_WAIT and
I2C_INTERRUPTIBLE_SLEEP are active, which let the driver act like the o=
ld
one.
Maybe this is helpful for others too and some of the modifications find=

it=B4s way into the official kernel tree.

Cajus Hahn

/*
 * i2c-algo-8xx.c i2x driver algorithms for MPC8XX CPM
 * Copyright (c) 1999 Dan Malek (dmalek@jlc.net).
 *
    This program is free software; you can redistribute it and/or modif=
y
    it under the terms of the GNU General Public License as published b=
y
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 * moved into proper i2c interface; separated out platform specific
 * parts into i2c-rpx.c
 * Brad Parker (brad@heeltoe.com)
 *
 * added define for BUSY_WAIT and INTERRUPTIBLE_SLEEP, added
I2C_ALGO_8XX_DATE + ..VERSION
 * fixed bug in cpm_iic_read and cpm_iic_write (timeout never detected =
if
count < 16)
 * added force_reinit(): in certain cases (disturbances on the I2C bus)=
 a
timeout will
 * occur. After this a complete re-initialisation will be necessary,
otherwise all
 * following transmissions will have a timeout.
 * Cajus Hahn, 09.08.2005
 */

// XXX todo
// timeout sleep?

/* $Id: i2c-algo-8xx.c,v 1.1.1.1 2004/12/10 08:44:35 cajus Exp $ */

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/version.h>
#include <linux/init.h>
#include <asm/uaccess.h>
#include <linux/ioport.h>
#include <linux/errno.h>
#include <linux/sched.h>

#include <asm/mpc8xx.h>
#include <asm/commproc.h>

#include <linux/i2c.h>
#include <linux/i2c-algo-8xx.h>

#define I2C_ALGO_8XX_DATE "20050809"
#define I2C_ALGO_8XX_VERSION "2.6.2"

#define CPM_MAX_READ    513
/* #define I2C_CHIP_ERRATA */ /* Try uncomment this if you have an olde=
r
CPU(earlier than rev D4) */
#define I2C_BUSY_WAIT  /* Uncomment this if you want to do a busy wait =
in
cpm_iic_read and cpm_iic_write */
#define I2C_INTERRUPTIBLE_SLEEP /* Uncomment this if you want the waiti=
ng
in cpm_iic_read and
                                         cpm_iic_write beeing interrupt=
able
by signals */

static wait_queue_head_t iic_wait;
static ushort r_tbase, r_rbase;

int cpm_scan =3D 0;
int cpm_debug =3D 0;

static  void
cpm_iic_interrupt(void *dev_id, struct pt_regs *regs)
 {
      volatile i2c8xx_t *i2c =3D (i2c8xx_t *)dev_id;

      if (cpm_debug > 1)
            printk(KERN_DEBUG "cpm_iic_interrupt(dev_id=3D%p)\n", dev_i=
d);

#ifdef I2C_CHIP_ERRATA
      /* Chip errata, clear enable.
       * This seems to not be needed on rev D4 or newer CPUs.
       * Someone with an older CPU needs to verify this.
       */
      i2c->i2c_i2mod &=3D ~1;
#endif

      /* Clear interrupt.
      */
      i2c->i2c_i2cer =3D 0xff;

      /* Get 'me going again.
      */
#ifdef I2C_INTERRUPTIBLE_SLEEP
      wake_up_interruptible(&iic_wait);
#else
      wake_up(&iic_wait);
#endif
}

static void
cpm_iic_init(struct i2c_algo_8xx_data *cpm_adap)
{
      volatile iic_t          *iip =3D cpm_adap->iip;
      volatile i2c8xx_t *i2c =3D cpm_adap->i2c;
      unsigned char brg;
      bd_t *bd =3D (bd_t *)__res;

      if (cpm_debug) printk(KERN_DEBUG "cpm_iic_init() - iip=3D%p\n",ii=
p);

      /* Initialize the parameter ram.
       * We need to make sure many things are initialized to zero,
       * especially in the case of a microcode patch.
       */
      iip->iic_rstate =3D 0;
      iip->iic_rdp =3D 0;
      iip->iic_rbptr =3D 0;
      iip->iic_rbc =3D 0;
      iip->iic_rxtmp =3D 0;
      iip->iic_tstate =3D 0;
      iip->iic_tdp =3D 0;
      iip->iic_tbptr =3D 0;
      iip->iic_tbc =3D 0;
      iip->iic_txtmp =3D 0;

      /* Set up the IIC parameters in the parameter ram.
      */
      iip->iic_tbase =3D r_tbase =3D cpm_adap->dp_addr;
      iip->iic_rbase =3D r_rbase =3D cpm_adap->dp_addr + sizeof(cbd_t)*=
2;

      iip->iic_tfcr =3D SMC_EB;
      iip->iic_rfcr =3D SMC_EB;

      /* Set maximum receive size.
      */
      iip->iic_mrblr =3D CPM_MAX_READ;

      /* Initialize Tx/Rx parameters.
      */
      if (cpm_adap->reloc =3D=3D 0) {
            volatile cpm8xx_t *cp =3D cpm_adap->cp;

            cp->cp_cpcr =3D
                  mk_cr_cmd(CPM_CR_CH_I2C, CPM_CR_INIT_TRX) | CPM_CR_FL=
G;
            while (cp->cp_cpcr & CPM_CR_FLG);
      } else {
            iip->iic_rbptr =3D iip->iic_rbase;
            iip->iic_tbptr =3D iip->iic_tbase;
            iip->iic_rstate   =3D 0;
            iip->iic_tstate   =3D 0;
      }

      /* Select an arbitrary address.  Just make sure it is unique.
      */
      i2c->i2c_i2add =3D 0xfe;

      /* Make clock run at 60 KHz.
      */
      brg =3D (unsigned char) (bd->bi_intfreq/(32*2*60000) -3);
      i2c->i2c_i2brg =3D brg;

      i2c->i2c_i2mod =3D 0x00;
      i2c->i2c_i2com =3D 0x01; /* Master mode */

      /* Disable interrupts.
      */
      i2c->i2c_i2cmr =3D 0;
      i2c->i2c_i2cer =3D 0xff;

      init_waitqueue_head(&iic_wait);

      /* Install interrupt handler.
      */
      if (cpm_debug) {
            printk (KERN_DEBUG "%s[%d] Install ISR for IRQ %d\n",
                  __func__,__LINE__, CPMVEC_I2C);
      }
      cpm_install_handler(CPMVEC_I2C, cpm_iic_interrupt, (void *)i2c);
}


static int
cpm_iic_shutdown(struct i2c_algo_8xx_data *cpm_adap)
{
      volatile i2c8xx_t *i2c =3D cpm_adap->i2c;

      /* Shut down IIC.
      */
      i2c->i2c_i2mod &=3D ~1;
      i2c->i2c_i2cmr =3D 0;
      i2c->i2c_i2cer =3D 0xff;

      return(0);
}

static void
cpm_reset_iic_params(volatile iic_t *iip)
{
      iip->iic_tbase =3D r_tbase;
      iip->iic_rbase =3D r_rbase;

      iip->iic_tfcr =3D SMC_EB;
      iip->iic_rfcr =3D SMC_EB;

      iip->iic_mrblr =3D CPM_MAX_READ;

      iip->iic_rstate =3D 0;
      iip->iic_rdp =3D 0;
      iip->iic_rbptr =3D iip->iic_rbase;
      iip->iic_rbc =3D 0;
      iip->iic_rxtmp =3D 0;
      iip->iic_tstate =3D 0;
      iip->iic_tdp =3D 0;
      iip->iic_tbptr =3D iip->iic_tbase;
      iip->iic_tbc =3D 0;
      iip->iic_txtmp =3D 0;
}

#define BD_SC_NAK       ((ushort)0x0004) /* NAK - did not respond */
#define BD_SC_OV        ((ushort)0x0002) /* OV - receive overrun */
#define CPM_CR_CLOSE_RXBD     ((ushort)0x0007)

static void force_close(struct i2c_algo_8xx_data *cpm)
{
      volatile i2c8xx_t *i2c =3D cpm->i2c;

        if (cpm_debug)
            printk(KERN_DEBUG "force_close()");

      if (cpm->reloc =3D=3D 0) { /* micro code disabled */
            volatile cpm8xx_t *cp =3D cpm->cp;
            cp->cp_cpcr =3D
                  mk_cr_cmd(CPM_CR_CH_I2C, CPM_CR_CLOSE_RXBD) |
                  CPM_CR_FLG;

            while (cp->cp_cpcr & CPM_CR_FLG);
      }

      i2c->i2c_i2cmr =3D 0x00;  /* Disable all interrupts */
      i2c->i2c_i2cer =3D 0xff;
}

static void force_reinit(struct i2c_algo_8xx_data *cpm)
{
      volatile iic_t *iip =3D cpm->iip;
      volatile i2c8xx_t *i2c =3D cpm->i2c;
      volatile cpm8xx_t *cp =3D cpm->cp;
      unsigned char brg;
      bd_t *bd =3D (bd_t *)__res;

      // Disable interrupts.
      i2c->i2c_i2cmr =3D 0;
      i2c->i2c_i2cer =3D 0xff;
        // Clear enable
      i2c->i2c_i2mod &=3D ~1;

      // Initialize the parameter ram.
      iip->iic_rstate =3D 0;
      iip->iic_rdp =3D 0;
      iip->iic_rbptr =3D 0;
      iip->iic_rbc =3D 0;
      iip->iic_rxtmp =3D 0;
      iip->iic_tstate =3D 0;
      iip->iic_tdp =3D 0;
      iip->iic_tbptr =3D 0;
      iip->iic_tbc =3D 0;
      iip->iic_txtmp =3D 0;
        iip->iic_tbase =3D r_tbase;
      iip->iic_rbase =3D r_rbase;
      iip->iic_tfcr =3D SMC_EB;
      iip->iic_rfcr =3D SMC_EB;
      iip->iic_mrblr =3D CPM_MAX_READ;

      if (cpm->reloc =3D=3D 0)
        {
            cp->cp_cpcr =3D mk_cr_cmd(CPM_CR_CH_I2C, CPM_CR_INIT_TRX) |=

CPM_CR_FLG;
            while (cp->cp_cpcr & CPM_CR_FLG);
      }
        else
        {
            iip->iic_rbptr =3D iip->iic_rbase;
            iip->iic_tbptr =3D iip->iic_tbase;
            iip->iic_rstate   =3D 0;
            iip->iic_tstate   =3D 0;
      }

      // Select an arbitrary address.  Just make sure it is unique.
      i2c->i2c_i2add =3D 0xfe;

      // Make clock run at 60 KHz.
      brg =3D (unsigned char) (bd->bi_intfreq/(32*2*60000) -3);
      i2c->i2c_i2brg =3D brg;

      i2c->i2c_i2mod =3D 0x00;
      i2c->i2c_i2com =3D 0x01; /* Master mode */
}

/* Read from IIC...
 * abyte =3D address byte, with r/w flag already set
 */
static int
cpm_iic_read(struct i2c_algo_8xx_data *cpm, u_char abyte, char *buf, in=
t
count)
{
      volatile iic_t *iip =3D cpm->iip;
      volatile i2c8xx_t *i2c =3D cpm->i2c;
      volatile cpm8xx_t *cp =3D cpm->cp;
      volatile cbd_t    *tbdf, *rbdf;
      u_char *tb;
      unsigned long flags, tmo, timedout;

      if (count >=3D CPM_MAX_READ)
            return -EINVAL;

      /* check for and use a microcode relocation patch */
      if (cpm->reloc) {
            cpm_reset_iic_params(iip);
      }

      tbdf =3D (cbd_t *)&cp->cp_dpmem[iip->iic_tbase];
      rbdf =3D (cbd_t *)&cp->cp_dpmem[iip->iic_rbase];

      /* To read, we need an empty buffer of the proper length.
       * All that is used is the first byte for address, the remainder
       * is just used for timing (and doesn't really have to exist).
       */
      tb =3D cpm->temp;
      tb =3D (u_char *)(((uint)tb + 15) & ~15);
      tb[0] =3D abyte;          /* Device address byte w/rw flag */

      flush_dcache_range((unsigned long) tb, (unsigned long) (tb+1));

      if (cpm_debug) printk(KERN_DEBUG "cpm_iic_read(abyte=3D0x%x)\n",
abyte);

      tbdf->cbd_bufaddr =3D __pa(tb);
      tbdf->cbd_datlen =3D count + 1;
      tbdf->cbd_sc =3D
            BD_SC_READY | BD_SC_LAST |
            BD_SC_WRAP | BD_IIC_START;

      iip->iic_mrblr =3D count + 1; /* prevent excessive read, +1
                              is needed otherwise will the
                              RXB interrupt come too early */

      /* flush will invalidate too. */
      flush_dcache_range((unsigned long) buf, (unsigned long) (buf+coun=
t));

      rbdf->cbd_datlen =3D 0;
      rbdf->cbd_bufaddr =3D __pa(buf);

      rbdf->cbd_sc =3D BD_SC_EMPTY | BD_SC_WRAP| BD_SC_INTRPT;
        timedout =3D 0;
#ifdef I2C_BUSY_WAIT
      if(count > 16){
#endif
            /* Chip bug, set enable here */
            local_irq_save(flags);
            i2c->i2c_i2cmr =3D 0x13;  /* Enable some interupts */
            i2c->i2c_i2cer =3D 0xff;
            i2c->i2c_i2mod |=3D 1;    /* Enable */
            i2c->i2c_i2com |=3D 0x80; /* Begin transmission */

            /* Wait for IIC transfer */
#ifdef I2C_INTERRUPTIBLE_SLEEP
            tmo =3D interruptible_sleep_on_timeout(&iic_wait,1*HZ);
#else
            tmo =3D sleep_on_timeout(&iic_wait,1*HZ);
#endif
                if(tmo =3D=3D 0) timedout=3D1;
            local_irq_restore(flags);
#ifdef I2C_BUSY_WAIT
      } else { /* busy wait for small transfers, its faster */
            i2c->i2c_i2cmr =3D 0x00;  /* Disable I2C interupts */
            i2c->i2c_i2cer =3D 0xff;
            i2c->i2c_i2mod |=3D 1;    /* Enable */
            i2c->i2c_i2com |=3D 0x80; /* Begin transmission */
            tmo =3D jiffies + 1*HZ;
            while(!(i2c->i2c_i2cer & 0x11 || (timedout =3D
time_after(jiffies, tmo)))); /* Busy wait, with a timeout */
      }
#endif
        if(timedout)
        {
            printk(KERN_DEBUG "cpm_iic_read: timeout!\n");
            force_reinit(cpm);
            return -EIO;
        }

#ifdef I2C_INTERRUPTIBLE_SLEEP
      if (signal_pending(current))
        {
            force_close(cpm);
          if (cpm_debug)
                printk(KERN_DEBUG "cpm_iic_read: signal_pending! \n");
          return -EINTR;
        }
#endif

#ifdef I2C_CHIP_ERRATA
      /* Chip errata, clear enable. This is not needed on rev D4 CPUs.
       Disabling I2C too early may cause too short stop condition */
      udelay(4);
      i2c->i2c_i2mod &=3D ~1;
#endif

      if (cpm_debug) {
            printk(KERN_DEBUG "tx sc %04x, rx sc %04x\n",
                   tbdf->cbd_sc, rbdf->cbd_sc);
      }

      if (tbdf->cbd_sc & BD_SC_READY) {
            printk(KERN_INFO "IIC read; complete but tbuf ready\n");
            force_close(cpm);
            printk(KERN_INFO "tx sc %04x, rx sc %04x\n",
                   tbdf->cbd_sc, rbdf->cbd_sc);
      }

      if (tbdf->cbd_sc & BD_SC_NAK) {
            if (cpm_debug)
                  printk(KERN_DEBUG "IIC read; no ack\n");
            return -EREMOTEIO;
      }

      if (rbdf->cbd_sc & BD_SC_EMPTY) {
            /* force_close(cpm); */
            if (cpm_debug){
                  printk(KERN_DEBUG "IIC read; complete but rbuf empty\=
n");
                  printk(KERN_DEBUG "tx sc %04x, rx sc %04x\n",
                         tbdf->cbd_sc, rbdf->cbd_sc);
            }
            return -EREMOTEIO;
      }

      if (rbdf->cbd_sc & BD_SC_OV) {
            if (cpm_debug)
                  printk(KERN_DEBUG "IIC read; Overrun\n");
            return -EREMOTEIO;;
      }

      if (cpm_debug) printk(KERN_DEBUG "read %d bytes\n",
rbdf->cbd_datlen);

      if (rbdf->cbd_datlen < count) {
            if (cpm_debug)
                  printk(KERN_DEBUG "IIC read; short, wanted %d got %d\=
n",
                         count, rbdf->cbd_datlen);
            return 0;
      }

      return count;
}

/* Write to IIC...
 * addr =3D address byte, with r/w flag already set
 */
static int
cpm_iic_write(struct i2c_algo_8xx_data *cpm, u_char abyte, char *buf,in=
t
count)
{
      volatile iic_t *iip =3D cpm->iip;
      volatile i2c8xx_t *i2c =3D cpm->i2c;
      volatile cpm8xx_t *cp =3D cpm->cp;
      volatile cbd_t    *tbdf;
      u_char *tb;
      unsigned long flags, tmo, timedout;

      /* check for and use a microcode relocation patch */
      if (cpm->reloc) {
            cpm_reset_iic_params(iip);
      }
      tb =3D cpm->temp;
      tb =3D (u_char *)(((uint)tb + 15) & ~15);
      *tb =3D abyte;            /* Device address byte w/rw flag */

      flush_dcache_range((unsigned long) tb, (unsigned long) (tb+1));
      flush_dcache_range((unsigned long) buf, (unsigned long) (buf+coun=
t));

      if (cpm_debug) printk(KERN_DEBUG "cpm_iic_write(abyte=3D0x%x)\n",=

abyte);

      /* set up 2 descriptors */
      tbdf =3D (cbd_t *)&cp->cp_dpmem[iip->iic_tbase];

      tbdf[0].cbd_bufaddr =3D __pa(tb);
      tbdf[0].cbd_datlen =3D 1;
      tbdf[0].cbd_sc =3D BD_SC_READY | BD_IIC_START;

      tbdf[1].cbd_bufaddr =3D __pa(buf);
      tbdf[1].cbd_datlen =3D count;
      tbdf[1].cbd_sc =3D BD_SC_READY | BD_SC_INTRPT | BD_SC_LAST |
BD_SC_WRAP;

        timedout =3D 0;
#ifdef I2C_BUSY_WAIT
      if(count > 16){
#endif
            /* Chip bug, set enable here */
            local_irq_save(flags);
            i2c->i2c_i2cmr =3D 0x13;  /* Enable some interupts */
            i2c->i2c_i2cer =3D 0xff;
            i2c->i2c_i2mod |=3D 1;    /* Enable */
            i2c->i2c_i2com |=3D 0x80; /* Begin transmission */

            /* Wait for IIC transfer */
#ifdef I2C_INTERRUPTIBLE_SLEEP
            tmo =3D interruptible_sleep_on_timeout(&iic_wait,1*HZ);
#else
            tmo =3D sleep_on_timeout(&iic_wait,1*HZ);
#endif
                if(tmo =3D=3D 0) timedout=3D1;
            local_irq_restore(flags);
#ifdef I2C_BUSY_WAIT
      } else {  /* busy wait for small transfers, its faster */
            i2c->i2c_i2cmr =3D 0x00;  /* Disable I2C interupts */
            i2c->i2c_i2cer =3D 0xff;
            i2c->i2c_i2mod |=3D 1;    /* Enable */
            i2c->i2c_i2com |=3D 0x80; /* Begin transmission */
            tmo =3D jiffies + 1*HZ;
            while(!(i2c->i2c_i2cer & 0x12 || (timedout =3D
time_after(jiffies, tmo)))); /* Busy wait, with a timeout */
      }
#endif
        if(timedout)
        {
            printk(KERN_DEBUG "cpm_iic_write: timeout!\n");
            force_reinit(cpm);
            return -EIO;
        }

#ifdef I2C_INTERRUPTIBLE_SLEEP
      if (signal_pending(current))
        {
            force_close(cpm);
          if (cpm_debug)
                printk(KERN_DEBUG "cpm_iic_write: signal_pending! \n");=

          return -EINTR;
        }
#endif

#if I2C_CHIP_ERRATA
      /* Chip errata, clear enable. This is not needed on rev D4 CPUs.
       Disabling I2C too early may cause too short stop condition */
      udelay(4);
      i2c->i2c_i2mod &=3D ~1;
#endif
      if (cpm_debug) {
            printk(KERN_DEBUG "tx0 sc %04x, tx1 sc %04x\n",
                   tbdf[0].cbd_sc, tbdf[1].cbd_sc);
      }

      if ((tbdf[0].cbd_sc | tbdf[1].cbd_sc) & BD_SC_NAK) {
            if (cpm_debug)
                  printk(KERN_DEBUG "IIC write; no ack\n");
            return 0;
      }

      if ((tbdf[0].cbd_sc | tbdf[1].cbd_sc) & BD_SC_READY) {
            if (cpm_debug)
                  printk(KERN_DEBUG "IIC write; complete but tbuf
ready\n");
            return 0;
      }

      return count;
}

/* See if an IIC address exists..
 * addr =3D 7 bit address, unshifted
 */
static int
cpm_iic_tryaddress(struct i2c_algo_8xx_data *cpm, int addr)
{
      volatile iic_t *iip =3D cpm->iip;
      volatile i2c8xx_t *i2c =3D cpm->i2c;
      volatile cpm8xx_t *cp =3D cpm->cp;
      volatile cbd_t *tbdf, *rbdf;
      u_char *tb;
      unsigned long flags, len, tmo;

      if (cpm_debug > 1)
            printk(KERN_DEBUG "cpm_iic_tryaddress(cpm=3D%p,addr=3D%d)\n=
", cpm,
addr);

      /* check for and use a microcode relocation patch */
      if (cpm->reloc) {
            cpm_reset_iic_params(iip);
      }

      if (cpm_debug && addr =3D=3D 0) {
            printk(KERN_DEBUG "iip %p, dp_addr 0x%x\n", cpm->iip,
cpm->dp_addr);
            printk(KERN_DEBUG "iic_tbase %d, r_tbase %d\n", iip->iic_tb=
ase,
r_tbase);
      }

      tbdf =3D (cbd_t *)&cp->cp_dpmem[iip->iic_tbase];
      rbdf =3D (cbd_t *)&cp->cp_dpmem[iip->iic_rbase];

      tb =3D cpm->temp;
      tb =3D (u_char *)(((uint)tb + 15) & ~15);

      /* do a simple read */
      tb[0] =3D (addr << 1) | 1;      /* device address (+ read) */
      len =3D 2;

      flush_dcache_range((unsigned long) tb, (unsigned long) (tb+1));

      tbdf->cbd_bufaddr =3D __pa(tb);
      tbdf->cbd_datlen =3D len;
      tbdf->cbd_sc =3D
            BD_SC_READY | BD_SC_LAST |
            BD_SC_WRAP | BD_IIC_START;

      rbdf->cbd_datlen =3D 0;
      rbdf->cbd_bufaddr =3D __pa(tb+2);
      rbdf->cbd_sc =3D BD_SC_EMPTY | BD_SC_WRAP | BD_SC_INTRPT;

      local_irq_save(flags);
      i2c->i2c_i2cmr =3D 0x13;  /* Enable some interupts */
      i2c->i2c_i2cer =3D 0xff;
      i2c->i2c_i2mod |=3D 1;    /* Enable */
      i2c->i2c_i2com |=3D 0x80; /* Begin transmission */

      if (cpm_debug > 1) printk(KERN_DEBUG "about to sleep\n");

      /* wait for IIC transfer */
#ifdef I2C_INTERRUPTIBLE_SLEEP
      tmo =3D interruptible_sleep_on_timeout(&iic_wait,1*HZ);
#else
      tmo =3D sleep_on_timeout(&iic_wait,1*HZ);
#endif
      local_irq_restore(flags);

#ifdef I2C_CHIP_ERRATA
      /* Chip errata, clear enable. This is not needed on rev D4 CPUs.
       Disabling I2C too early may cause too short stop condition */
      udelay(4);
      i2c->i2c_i2mod &=3D ~1;
#endif

      if (signal_pending(current) || !tmo){
            force_close(cpm);
            if(cpm_debug && !tmo)
                  printk(KERN_DEBUG "IIC tryaddress: timeout!\n");
            return -EIO;
      }

      if (cpm_debug > 1) printk(KERN_DEBUG "back from sleep\n");

      if (tbdf->cbd_sc & BD_SC_NAK) {
            if (cpm_debug > 1) printk(KERN_DEBUG "IIC try; no ack\n");
            return 0;
      }

      if (tbdf->cbd_sc & BD_SC_READY) {
            printk(KERN_INFO "IIC try; complete but tbuf ready\n");
      }

      return 1;
}

static int cpm_xfer(struct i2c_adapter *i2c_adap,
                struct i2c_msg msgs[],
                int num)
{
      struct i2c_algo_8xx_data *adap =3D i2c_adap->algo_data;
      struct i2c_msg *pmsg;
      int i, ret;
      u_char addr;

      for (i =3D 0; i < num; i++) {
            pmsg =3D &msgs[i];

            if (cpm_debug)
                  printk(KERN_DEBUG "i2c-algo-8xx.o: "
                         "#%d addr=3D0x%x flags=3D0x%x len=3D%d\n buf=3D=
%lx\n",
                         i, pmsg->addr, pmsg->flags, pmsg->len, (unsign=
ed
long)pmsg->buf);

            addr =3D pmsg->addr << 1;
            if (pmsg->flags & I2C_M_RD )
                  addr |=3D 1;
            if (pmsg->flags & I2C_M_REV_DIR_ADDR )
                  addr ^=3D 1;

            if (!(pmsg->flags & I2C_M_NOSTART)) {
            }
            if (pmsg->flags & I2C_M_RD ) {
                  /* read bytes into buffer*/
                  ret =3D cpm_iic_read(adap, addr, pmsg->buf, pmsg->len=
);
                  if (cpm_debug)
                        printk(KERN_DEBUG "i2c-algo-8xx.o: read %d
bytes\n", ret);
                  if (ret < pmsg->len ) {
                        return (ret<0)? ret : -EREMOTEIO;
                  }
            } else {
                  /* write bytes from buffer */
                  ret =3D cpm_iic_write(adap, addr, pmsg->buf, pmsg->le=
n);
                  if (cpm_debug)
                        printk(KERN_DEBUG "i2c-algo-8xx.o: wrote %d\n",=

ret);
                  if (ret < pmsg->len ) {
                        return (ret<0) ? ret : -EREMOTEIO;
                  }
            }
      }
      return (num);
}

static int algo_control(struct i2c_adapter *adapter,
      unsigned int cmd, unsigned long arg)
{
      return 0;
}

static u32 cpm_func(struct i2c_adapter *adap)
{
      return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_10BIT_ADDR |
             I2C_FUNC_PROTOCOL_MANGLING;
}

/* -----exported algorithm data: ------------------------------------- =
 */

static struct i2c_algorithm cpm_algo =3D {
      "MPC8xx CPM algorithm",
      I2C_ALGO_MPC8XX,
      cpm_xfer,
      NULL,
      NULL,                   /* slave_xmit           */
      NULL,                   /* slave_recv           */
      algo_control,                 /* ioctl          */
      cpm_func,               /* functionality  */
};

/*
 * registering functions to load algorithms at runtime
 */
int i2c_8xx_add_bus(struct i2c_adapter *adap)
{
      int i;
      struct i2c_algo_8xx_data *cpm_adap =3D adap->algo_data;

      if (cpm_debug)
            printk(KERN_DEBUG "i2c-algo-8xx.o: hw routines for %s
registered.\n",
                   adap->name);

      /* register new adapter to i2c module... */

      adap->id |=3D cpm_algo.id;
      adap->algo =3D &cpm_algo;

#ifdef MODULE
      MOD_INC_USE_COUNT;
#endif

      i2c_add_adapter(adap);
      cpm_iic_init(cpm_adap);

      /* scan bus */
      if (cpm_scan) {
            printk(KERN_INFO " i2c-algo-8xx.o: scanning bus %s...\n",
                   adap->name);
            for (i =3D 0; i < 128; i++) {
                  if (cpm_iic_tryaddress(cpm_adap, i)) {
                        printk("(%02x)",i<<1);
                  }
            }
            printk("\n");
      }
      return 0;
}

int i2c_8xx_del_bus(struct i2c_adapter *adap)
{
      int res;
      struct i2c_algo_8xx_data *cpm_adap =3D adap->algo_data;

      cpm_iic_shutdown(cpm_adap);

      if ((res =3D i2c_del_adapter(adap)) < 0)
            return res;

      printk(KERN_INFO "i2c-algo-8xx.o: adapter unregistered:
%s\n",adap->name);

#ifdef MODULE
      MOD_DEC_USE_COUNT;
#endif
      return 0;
}

EXPORT_SYMBOL(i2c_8xx_add_bus);
EXPORT_SYMBOL(i2c_8xx_del_bus);

int __init i2c_algo_8xx_init (void)
{
      printk(KERN_INFO "i2c-algo-8xx.o: i2c mpc8xx algorithm module ver=
sion
%s (%s)\n", I2C_ALGO_8XX_VERSION, I2C_ALGO_8XX_DATE);
      return 0;
}


#ifdef MODULE
MODULE_AUTHOR("Brad Parker <brad@heeltoe.com>");
MODULE_DESCRIPTION("I2C-Bus MPC8XX algorithm");
#ifdef MODULE_LICENSE
MODULE_LICENSE("GPL");
#endif

int init_module(void)
{
      return i2c_algo_8xx_init();
}

void cleanup_module(void)
{
}
#endif=

^ permalink raw reply

* RE: fs_enet on MPC885ADS
From: Schaefer-Hutter, Peter @ 2005-08-10  7:58 UTC (permalink / raw)
  To: Vitaly Bordug; +Cc: linuxppc-embedded

> From: Vitaly Bordug [mailto:vbordug@ru.mvista.com]=20
> Sent: Wednesday, August 10, 2005 9:26 AM

> > Schaefer-Hutter, Peter wrote:
> > Reason i'm asking is that the current cpm_uart driver doesn't work
> > with the SCC3 ethernet driver included in the MPC885 board support
> > (as soon as ethernet is initialized, console output stops).
>=20
> This is very interesting since AFAIR SCC3 eth will not work with SMC2
on=20
> my board, but maybe something is changed.=20

Well, SMC2 ist disabled in the config, the DIP switches are set for
10BaseT... But i must confess that i've not looked very deep into that.

> Anyway, oue fs_enet is pretty close to upstream so it would be nice if

> you will use (and test :)) it.

Sure! I'm your guinea pig :)

Best regards,

  Peter

^ permalink raw reply

* sdram control register
From: Nuguru Susheel @ 2005-08-10 10:55 UTC (permalink / raw)
  To: linuxppc-embedded

Hi all,

 Does anyone know how to enable the bit "mode_en" in SDRAM Control
Register (MBAR + 0x0104) ... I have been struggling for that .. 

Just briefly about this register..

writing is not allowed to this register when mode_en bit = '0',

to unlock it we should write mode_en = '1', trying to do this directly
makes the core restart , i think this should be enabled VIA some command
or s0mething.. any help please ...


Thanks for the reply in Advance ..
        nSr

^ permalink raw reply

* Re: ??: Some version different
From: Wolfgang Denk @ 2005-08-10  7:30 UTC (permalink / raw)
  To: FCG WANG Baohua; +Cc: linuxppc-embedded
In-Reply-To: <A9DE2BAF233E444FA9C5E77A5825A01E86505D@ydmail.sbell.com.cn>

In message <A9DE2BAF233E444FA9C5E77A5825A01E86505D@ydmail.sbell.com.cn> you wrote:
>
>   It is the "r3" register data wrong transfer from ppcboot  to kernel. I
> don't know why. very strange. !!!

I'm sure that PPCBoot passes a valid pointer. If you  don;t  see  the
expected  data,  then  you  should probably go back to square one and
read the FAQ: 
http://www.denx.de/twiki/bin/view/DULG/LinuxHangsAfterUncompressingKernel

>   The CONFIG_HD860 cannot be compiled in kernel. I don't know either.
> There is no error or warring during config and make.

There is a bug (at least one) n your modifications to the Linux kernel.

>    Then "Oops: kernel access of bad area, sig: 11" and stopped.
>  
>   How is the "with no serial options enabled" ? is it need any config
> with "make menuconfig" ?

I don't know your hardware.
I don't know why you are using  obsolete  versions  of  the  software
(like PPCBoot) for any current work.
I don't know which modifications you made to U-Boot to make it  work
on your hardware, or if these modifications are working at all.
I don't know which modifications you made to Linux.

I cannot help you. Hire an expert.

Best regards,

Wolfgang Denk

-- 
Software Engineering:  Embedded and Realtime Systems,  Embedded Linux
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd@denx.de
There is nothing in this world constant but inconstancy.      - Swift

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox