Subject: Re: PPCboot and latest kernel

2009-07-27 Thread Mike Ditto
vijay sharma wrote:
> Linux/PowerPC load:
> Finalizing device tree... flat tree at 0x2f65300 <== Beyond this point no
> output is available.

I have found that on my MPC8272 system running 2.6.28 & cuImage, the
/chosen/linux,stdout-path node is respected by the boot wrapper, but the
main kernel always uses the first serial port mentioned in the device
tree as the console.  If you have multiple serial ports in your .dts,
try re-ordering them.

-=] Mike [=-
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


Re: How to bring up fs_enet on 2.6.27?

2009-02-25 Thread Mike Ditto
Daniel Ng wrote:
>> Now, I'm seeing these boot messages:
>>
>> f0010d40:00 not found
>> eth0: Could not attach to PHY

Daniel,

These messages are typical of having the wrong GPIO pins in the mdio
node or the wrong MDIO address (reg property) in the ethernet-phy node.

>> Currently, our PHY
>> attributes eg. 'auto-negotiate' are not changeable, so we aren't
>> actually using MDC+MDIO even the MDC+MDIO lines exist.

The driver definitely tries to talk to the PHY using the GPIO pins
and address specified and if it doesn't respond, it won't attach.

>> Also, the PHY
>> interrupt line is not wired up. Hence the PHY0 interrupts field is <0
>> 8> (or should it be removed altogether?).

The mdio driver works without interrupts.  I have no interrupt-parent
or interrupts properties on my ethernet-phy node.

-=] Mike [=-

___
Linuxppc-dev mailing list
Linuxppc-dev@ozlabs.org
https://ozlabs.org/mailman/listinfo/linuxppc-dev


Re: Calling wait_event_interruptible_timeout() in I2C wait functions

2009-02-04 Thread Mike Ditto
Timur Tabi wrote:
> However, it appears that this is not common behavior for I2C driver.  In
> fact, only these six drivers ever call wait_event_interruptible_timeout():
> 
> i2c-cpm.c

I don't know about the others, but in i2c-cpm.c the use of interruptible
wait seems incorrect.  Maybe it could be made correct, but as is, it
does not correctly clean up the hardware state or return a useful
value when interrupted by a signal.  It's not clear what to do, anyway -
it's hard to know which messages of the interrupted transaction have
actually taken effect in the hardware.  I think it's better to use
uninterruptible wait here and just live with the delayed signal
handling (one second delay in the unlikely worst case for i2c-cpm).

In general, I think it's best to consider I2C I/O to be uninterruptible,
like disk I/O.  The only reason to make it interruptible is to make
sure you don't end up with an unkillable process due to an I/O error,
and that is adequately handled by a timeout (and re-initialization of
the I2C interface in that case).

-=] Mike [=-
___
Linuxppc-dev mailing list
Linuxppc-dev@ozlabs.org
https://ozlabs.org/mailman/listinfo/linuxppc-dev


Re: How to bring up fs_enet on 2.6.27?

2009-01-28 Thread Mike Ditto
Daniel Ng  wrote:
> Should the device just be available as 'eth2', so that I can do
> 'ifconfig eth2 192.168.1.33'?

It will be eth0 if you have no other network devices.

> // FCC2-
> reg = <0x11320 0x20 0x8500 0x100 0x113b0 0x1>;
> fsl,cpm-command = <0x12000300>;

That's not the right fsl,cpm-command for FCC2.  You want 0x16200300.

Also, for my similar board, I had to add (for immap at F000):
virtual-reg = <0xF0011320
   0xF0008500
   0xF00113B0>;

But I can't explain why the driver isn't attaching for you.  Did you
try it built-in instead of as a module?

-=] Mike [=-
___
Linuxppc-dev mailing list
Linuxppc-dev@ozlabs.org
https://ozlabs.org/mailman/listinfo/linuxppc-dev


Re: Erratic MPC8248 CPM2 I2C behaviour

2008-12-02 Thread Mike Ditto
Jocke,

> The I2C_CHIP_ERRATA is mine and refers to mpc8xx, mpc860 in my case. The
> driver was adapted by me some years ago in 2.4 and now someone has
> ported it to 2.6 it seems.

Thanks for the background info.  Any idea which particular errata it
was meant to fix?  I took a quick look at MPC860 errata document and it
seems that CPM5 and CPM6 both suggest this workaround.

I don't think any of the 8xx CPM errata are present on 82xx, but it
would be good to enable the same or similar workaround on CPM2 for
82xx erratum CPM98, probably even when I2C_CHIP_ERRATA is not defined.

-=] Mike [=-
___
Linuxppc-dev mailing list
Linuxppc-dev@ozlabs.org
https://ozlabs.org/mailman/listinfo/linuxppc-dev


Re: Erratic MPC8248 CPM2 I2C behaviour

2008-12-02 Thread Mike Ditto
Hi, Laurent,

> While the problem seems to be similar to CPM98, I don't understand how it 
> could happen on the first character of the first I2C transfer.

I agree, that is hard to explain given that i2c-cpm keeps the controller
shut off until the very moment of the first transfer.  Can you check that
the bus is really idle (SCL is high) when the timeout happens?  If one of
the slave devices is in a bad state and pulling SCL low, I think the
behavior you see is expected (CPM will wait forever for the bus to be
idle).  The same is probably true if a GPIO pin is mis-configured.

> As explained in my previous mail to Joakim, I spent some more time last 
> Friday 
> investigating the problem, and it seems the baud rate generator configuration 
> plays an important role. The default configuration (60kHz nominal => 
> 65.104kHz 
> using a 25MHz brg clock and a /32 predivider) leads to timeouts, while I 
> haven't been able to reproduce the problem with the i2c-mpc8260.c 
> configuration (100kHz nominal => 104.167kHz using a 25MHz brg clock and a /8 
> predivider).

It would be interesting to try each driver with the other's clock settings.

-=] Mike [=-
___
Linuxppc-dev mailing list
Linuxppc-dev@ozlabs.org
https://ozlabs.org/mailman/listinfo/linuxppc-dev


Re: Erratic MPC8248 CPM2 I2C behaviour

2008-12-01 Thread Mike Ditto
(replying to myself again)

I wrote:
> But the key difference is that we see a persistent failure, while the
> erratum only mentions a problem with "the next transaction".

I think the timeout recovery code is not adequate for these CPM errors,
and that is why a transient error becomes a persistent one.  The
function cpm_i2c_force_close in i2c-cpm.c sends a CPM_CR_CLOSE_RX_BD
command, which will abort any receive transaction in progress, but if
it's the transmit phase that got the CPM hung up, there is no code to
abort that (and there does not exist a CP command to do so, as far as
I can tell).

So the I2C disable/enable seems to be an appropriate fix for the
persistent failure part of the problem.  Again, this doesn't explain
how it gets hung up the first time.

-=] Mike [=-
___
Linuxppc-dev mailing list
Linuxppc-dev@ozlabs.org
https://ozlabs.org/mailman/listinfo/linuxppc-dev


Re: Erratic MPC8248 CPM2 I2C behaviour

2008-12-01 Thread Mike Ditto
I wrote:
> Our production equipment is using Linux 2.6 with the out-of-tree
> i2c-algo-8260.c by Dan Malek and Brad Parker.

Oops, I meant to say Linux 2.4.20 (MontaVista).

-=] Mike [=-
___
Linuxppc-dev mailing list
Linuxppc-dev@ozlabs.org
https://ozlabs.org/mailman/listinfo/linuxppc-dev


Re: Erratic MPC8248 CPM2 I2C behaviour

2008-12-01 Thread Mike Ditto
Laurent Pinchart <[EMAIL PROTECTED]> wrote:
> Transmission timeout after one second. The first TX buffer descriptor status 
> hasn't been modified by the CPM. The CPM state dump shows that processing of 
...

This sounds very similar to a problem I have seen on MPC8247 and
MPC8248.

It could be a variation of the CPM bug documented by Freescale as
erratum CPM98.  But the key difference is that we see a persistent
failure, while the erratum only mentions a problem with "the next
transaction".  What we see is that once the I2C engine gets confused
by some anomaly on the SCL signal, it stops processing buffer
descriptors entirely until it is turned off and back on.  You can
observe this bug by momentarily grounding the SCL line (it's an
open-collector bus) with a jumper while you attempt an I/O.

Our production equipment is using Linux 2.6 with the out-of-tree
i2c-algo-8260.c by Dan Malek and Brad Parker.  I modified this
driver to shut off the I2C controller and turn it back on when it
hits this problem, and now it can recover from this condition.

However, this does not explain how the controller gets into the
frozen state in the first place.  We see it very rarely in production
units and have not been able to identify the cause.  If it is
similar to erratum CPM98 then it could be noise on the SCL signal or
perhaps an I2C device that doesn't conform to the protocol perfectly.
Also beware, if you are using some kind of multiplexer, that you don't
direct the multiplexer to switch to a different bus (segment) while a
transaction is in progress.

In testing with the current (2.6.27) i2c-cpm.c driver, I found that
it is sufficient to #define I2C_CHIP_ERRATA to allow it to recover
from the CPM I2C freeze.  However, I don't know if I like this
approach because it turns off the I2C engine after every transfer,
even successful ones, and I don't know if this will affect reliability
or performance.  And I don't know if this will actually prevent the
freeze from happening, although I presume that it would protect the
I2C engine from getting confused by a glitch that happens while no
transfer is in progress.

I am not aware of any documentation for what exactly the I2C_CHIP_ERRATA
conditional code in i2c-cpm.c is meant to work around.  The comment
mentions "earlier than rev D4" but I'm not aware of any such rev for
8260 or 8272 chip families, and if it is related to erratum CPM98,
Freescale seems to say that this erratum is in all revs of these chips
and has no plan to fix it, so it seems that the workaround should be
enabled by default.

-=] Mike [=-
___
Linuxppc-dev mailing list
Linuxppc-dev@ozlabs.org
https://ozlabs.org/mailman/listinfo/linuxppc-dev


[PATCH] i2c-cpm: Add flexibility for I2C clock frequency and filter.

2008-11-05 Thread Mike Ditto
This patch adds the ability to enable the digital filter in the device
tree (with the "clock-filter" boolean property) and automates the
predivider selection according to the clock-frequency and clock-filter
properties.  This allows use of a wider range of I2C bus frequencies.

Signed-off-by:  Mike Ditto <[EMAIL PROTECTED]>
---
This patch is against 2.6.27.

To use the full range of I2C clock frequencies supported by the
Freescale CPM I2C controller, it is necessary to choose an appropriate
predivider value.  The choice is affected by whether the SCL signal
digital filter is enabled.

The existing code computes the final divider (i2brg) but always uses
a predivider of 32.  This can set illegal values in i2brg - for example
on a machine with 25 MHz BRG_CLK, when selecting I2C clock-frequency
97656 Hz, the code was loading i2brg with the value 1, which does not
work (the CPM requires a minimum value of 3 when the digital filter is
not enabled).  Additionally, the calculation did not work when the
filter is enabled (and the driver did not provide a way to enable it).

Index: linux/drivers/i2c/busses/i2c-cpm.c
===
diff -u -p -r1.1.1.1 i2c-cpm.c
--- linux/drivers/i2c/busses/i2c-cpm.c  11 Oct 2008 02:53:07 -  1.1.1.1
+++ linux/drivers/i2c/busses/i2c-cpm.c  6 Nov 2008 01:45:15 -
@@ -87,6 +87,11 @@ struct i2c_ram {
 #define I2CER_TXB  0x02
 #define I2CER_RXB  0x01
 #define I2MOD_EN   0x01
+#define I2MOD_PDIV_32  0x00/* BRGCLK/32 */
+#define I2MOD_PDIV_16  0x02/* BRGCLK/16 */
+#define I2MOD_PDIV_8   0x04/* BRGCLK/8 */
+#define I2MOD_PDIV_4   0x06/* BRGCLK/4 */
+#define I2MOD_FLT  0x08

 /* I2C Registers */
 struct i2c_reg {
@@ -111,7 +116,6 @@ struct cpm_i2c {
int version; /* CPM1=1, CPM2=2 */
int irq;
int cp_command;
-   int freq;
struct i2c_reg __iomem *i2c_reg;
struct i2c_ram __iomem *i2c_ram;
u16 i2c_addr;
@@ -365,6 +369,7 @@ static int cpm_i2c_xfer(struct i2c_adapt
pmsg = &msgs[tptr];
if (pmsg->flags & I2C_M_RD)
ret = wait_event_interruptible_timeout(cpm->i2c_wait,
+   (in_be16(&tbdf[tptr].cbd_sc) & BD_SC_NAK) ||
!(in_be16(&rbdf[rptr].cbd_sc) & BD_SC_EMPTY),
1 * HZ);
else
@@ -434,7 +439,8 @@ static int __devinit cpm_i2c_setup(struc
void __iomem *i2c_base;
cbd_t __iomem *tbdf;
cbd_t __iomem *rbdf;
-   unsigned char brg;
+   uint freq, maxfreq, prediv;
+   unsigned char mod, brg;

dev_dbg(&cpm->ofdev->dev, "cpm_i2c_setup()\n");

@@ -508,9 +514,15 @@ static int __devinit cpm_i2c_setup(struc

data = of_get_property(ofdev->node, "clock-frequency", &len);
if (data && len == 4)
-   cpm->freq = *data;
+   freq = *data;
else
-   cpm->freq = 6; /* use 60kHz i2c clock by default */
+   freq = 6;   /* use 60kHz I2C clock by default */
+
+   data = of_get_property(ofdev->node, "clock-filter", &len);
+   if (data && len == 0)
+   mod = I2MOD_FLT;
+   else
+   mod = 0;

/*
 * Allocate space for CPM_MAXBD transmit and receive buffer
@@ -552,8 +564,8 @@ static int __devinit cpm_i2c_setup(struc

cpm_reset_i2c_params(cpm);

-   dev_dbg(&cpm->ofdev->dev, "i2c_ram 0x%p, i2c_addr 0x%04x, freq %d\n",
-   cpm->i2c_ram, cpm->i2c_addr, cpm->freq);
+   dev_dbg(&cpm->ofdev->dev, "i2c_ram 0x%p, i2c_addr 0x%04x, freq %u\n",
+   cpm->i2c_ram, cpm->i2c_addr, freq);
dev_dbg(&cpm->ofdev->dev, "tbase 0x%04x, rbase 0x%04x\n",
(u8 __iomem *)cpm->tbase - DPRAM_BASE,
(u8 __iomem *)cpm->rbase - DPRAM_BASE);
@@ -566,14 +578,48 @@ static int __devinit cpm_i2c_setup(struc
out_8(&cpm->i2c_reg->i2add, 0x7f << 1);

/*
-* PDIV is set to 00 in i2mod, so brgclk/32 is used as input to the
-* i2c baud rate generator. This is divided by 2 x (DIV + 3) to get
-* the actual i2c bus frequency.
+* Compute the clock predivider and final divider to generate something
+* close to the desired I2C clock frequency.  Use the largest predivider
+* possible.  i2brg must be >= 6 when using I2MOD_FLT, otherwise >= 3.
+* So compute the highest frequency that will work with I2MOD_PDIV_32;
+* if that isn't high enough, see if we can use I2MOD_PDIV_16, etc.
+* Then choose a final divider that will generate at least the desired
+* clock frequency.  Note the "at least" -- this round

Re: [PATCH] i2c-cpm: Add flexibility for I2C clock frequency and filter.

2008-11-05 Thread Mike Ditto
[including extra context because some of the thread went to the
 wrong I2C list]

David Gibson wrote:
> On Wed, Nov 05, 2008 at 04:35:03PM -0800, Mike Ditto wrote:
>> David Gibson wrote:
>> > What does worry me, however, is the description says it's about
>> > whether the driver "should" enable the filter.  Generally the device
>> > tree doesn't attempt to say what users "should" do with the hardware,
>> > just what the characteristics of the hardware are.
>> >
>> > What's the underlying difference here that affects the driver's choice
>> > to enable the filter or not?
>> 
>> I think it's a hardware/environment design parameter - e.g. if the I2C
>> bus has hot-pluggable devices, long PCB traces, or a hierarchy of
>> multiplexed bus segments, these can result in a noisy SCL signal that
>> needs to be filtered.  It's also a recommended mitigation for errata
>> in certain CPU revs.
> 
> Ah, ok.  Well the CPU revision thing could be selected based on the
> CPU revision, but the other conditions are a property of the board
> wiring.  Obviously it's hard to precisely characterize what it says
> about the hardware, which is usually best avoided for devtree
> properties, but I can see why this is more-or-less unavoidable in this
> case.
> 
> Ok.  This property name and meaning looks ok to me.  I would suggest a
> note in the binding roughly explaining what leads to the property
> being set (basically what you just told me in the paragraph above).

Will do.  I'll send a revised patch shortly.

Thanks,
-=] Mike [=-
___
Linuxppc-dev mailing list
Linuxppc-dev@ozlabs.org
https://ozlabs.org/mailman/listinfo/linuxppc-dev


Re: [PATCH] i2c-cpm: Add flexibility for I2C clock frequency and filter.

2008-11-05 Thread Mike Ditto
David Gibson wrote:
> What does worry me, however, is the description says it's about
> whether the driver "should" enable the filter.  Generally the device
> tree doesn't attempt to say what users "should" do with the hardware,
> just what the characteristics of the hardware are.
>
> What's the underlying difference here that affects the driver's choice
> to enable the filter or not?

I think it's a hardware/environment design parameter - e.g. if the I2C
bus has hot-pluggable devices, long PCB traces, or a hierarchy of
multiplexed bus segments, these can result in a noisy SCL signal that
needs to be filtered.  It's also a recommended mitigation for errata
in certain CPU revs.

-=] Mike [=-
___
Linuxppc-dev mailing list
Linuxppc-dev@ozlabs.org
https://ozlabs.org/mailman/listinfo/linuxppc-dev


Re: [PATCH] i2c-cpm: Detect and report NAK right away instead of timing out.

2008-11-02 Thread Mike Ditto

Ben Dooks wrote:

When reading from a device that is not present or declines to respond
to, e.g., a non-existent register address, CPM immediately reports a
NAK condition in the TxBD, but the driver kept waiting until a timeout,
which takes 1 second and causes an ugly console error message.


hmm, that block of text could probably go into the patch description.


It's certainly fine with me if you want to include it.  I was just
trying, perhaps inappropriately, to separate the "bug report" from the
"description of the change".

-=] Mike [=-
--
To unsubscribe from this list: send the line "unsubscribe linux-i2c" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] i2c-cpm: Detect and report NAK right away instead of timing out.

2008-10-31 Thread Mike Ditto
Make the driver report an ENXIO error immediately upon NAK instead of
waiting for another interrupt and getting a timeout.

Signed-off-by: Mike Ditto <[EMAIL PROTECTED]>
---
When reading from a device that is not present or declines to respond
to, e.g., a non-existent register address, CPM immediately reports a
NAK condition in the TxBD, but the driver kept waiting until a timeout,
which takes 1 second and causes an ugly console error message.

Index: linux/drivers/i2c/busses/i2c-cpm.c
===
retrieving revision 1.3
diff -u -p -r1.3 i2c-cpm.c
--- linux/drivers/i2c/busses/i2c-cpm.c  31 Oct 2008 06:36:08 -  1.3
+++ linux/drivers/i2c/busses/i2c-cpm.c  1 Nov 2008 00:12:45 -
@@ -369,6 +369,7 @@ static int cpm_i2c_xfer(struct i2c_adapt
pmsg = &msgs[tptr];
if (pmsg->flags & I2C_M_RD)
ret = wait_event_interruptible_timeout(cpm->i2c_wait,
+   (in_be16(&tbdf[tptr].cbd_sc) & BD_SC_NAK) ||
!(in_be16(&rbdf[rptr].cbd_sc) & BD_SC_EMPTY),
1 * HZ);
else
___
Linuxppc-dev mailing list
Linuxppc-dev@ozlabs.org
https://ozlabs.org/mailman/listinfo/linuxppc-dev


Re: [PATCH] i2c-cpm: Add flexibility for I2C clock frequency and filter.

2008-10-31 Thread Mike Ditto
[redirecting again to the new i2c mailing list]

Jochen Friedrich wrote:
> What needs to be done though is to document this change in
> Documentation/powerpc/dts-bindings/fsl/cpm_qe/cpm/i2c.txt.

How about the below?

I'll wait for David to comment on the property name and for any suggestions
on the documentation below, then I'll submit a new patch.

-=] Mike [=-

--- linux/Documentation/powerpc/dts-bindings/fsl/cpm_qe/cpm/i2c.txt 11 Oct 
2008 02:49:31 -  1.1.1.1
+++ linux/Documentation/powerpc/dts-bindings/fsl/cpm_qe/cpm/i2c.txt 31 Oct 
2008 21:15:06 -
@@ -10,8 +10,12 @@
 - #address-cells : Should be one. The cell is the i2c device address with
   the r/w bit set to zero.
 - #size-cells : Should be zero.
-- clock-frequency : Can be used to set the i2c clock frequency. If
-  unspecified, a default frequency of 60kHz is being used.
+- clock-frequency : Can be used to set the desired i2c clock frequency (in Hz).
+  If unspecified, a default of 60 kHz is being used.  The actual frequency may
+  be somewhat higher than this value, depending on how the BRG_CLK and dividers
+  work out.
+- clock-filter : boolean; if defined, indicates that this controller
+  should enable the SCL digital filter.
 The following two properties are deprecated. They are only used by legacy
 i2c drivers to find the bus to probe:
 - linux,i2c-index : Can be used to hard code an i2c bus number. By default,
___
Linuxppc-dev mailing list
Linuxppc-dev@ozlabs.org
https://ozlabs.org/mailman/listinfo/linuxppc-dev


Re: [PATCH] i2c-cpm: Add flexibility for I2C clock frequency and filter.

2008-10-31 Thread Mike Ditto
Jochen Friedrich wrote:
> What needs to be done though is to document this change in
> Documentation/powerpc/dts-bindings/fsl/cpm_qe/cpm/i2c.txt.

How about the below?

I'll wait for David to comment on the property name and for any suggestions
on the documentation below, then I'll submit a new patch.


--- linux/Documentation/powerpc/dts-bindings/fsl/cpm_qe/cpm/i2c.txt 11 Oct 
2008 02:49:31 -  1.1.1.1
+++ linux/Documentation/powerpc/dts-bindings/fsl/cpm_qe/cpm/i2c.txt 31 Oct 
2008 21:15:06 -
@@ -10,8 +10,12 @@
 - #address-cells : Should be one. The cell is the i2c device address with
   the r/w bit set to zero.
 - #size-cells : Should be zero.
-- clock-frequency : Can be used to set the i2c clock frequency. If
-  unspecified, a default frequency of 60kHz is being used.
+- clock-frequency : Can be used to set the desired i2c clock frequency (in Hz).
+  If unspecified, a default of 60 kHz is being used.  The actual frequency may
+  be somewhat higher than this value, depending on how the BRG_CLK and dividers
+  work out.
+- clock-filter : boolean; if defined, indicates that this controller
+  should enable the SCL digital filter.
 The following two properties are deprecated. They are only used by legacy
 i2c drivers to find the bus to probe:
 - linux,i2c-index : Can be used to hard code an i2c bus number. By default,
___
Linuxppc-dev mailing list
Linuxppc-dev@ozlabs.org
https://ozlabs.org/mailman/listinfo/linuxppc-dev


[PATCH] i2c-cpm: Add flexibility for I2C clock frequency and filter.

2008-10-30 Thread Mike Ditto
This patch adds the ability to enable the digital filter in the device
tree (with the "clock-filter" boolean property) and automates the
predivider selection according to the clock-frequency and clock-filter
properties.

Signed-off-by:  Mike Ditto <[EMAIL PROTECTED]>
---
Resending to moved i2c mailing list.
This patch is against 2.6.27.

To use the full range of I2C clock frequencies supported by the
Freescale CPM I2C controller, it is necessary to choose an appropriate
predivider value.  The choice is affected by whether the SCL signal
digital filter is enabled.

The existing code computes the final divider (i2brg) but always uses
a predivider of 32.  This can set illegal values in i2brg - for example
on a machine with 25 MHz BRG_CLK, when selecting I2C clock-frequency
97656 Hz, the code was loading i2brg with the value 1, which does not
work (the CPM requires a minimum value of 3 when the digital filter is
not enabled).  Additionally, the calculation did not work when the
filter is enabled (and the driver did not provide a way to enable it).

And by the way, thanks to Jochen Friedrich for integrating this driver
on the very day that I went looking for it.  :-)

Index: linux/drivers/i2c/busses/i2c-cpm.c
===
RCS file: /n/home2/mditto/ws/myrepo/kernel/linux/drivers/i2c/busses/i2c-cpm.c,v
retrieving revision 1.1.1.1
diff -u -p -r1.1.1.1 i2c-cpm.c
--- linux/drivers/i2c/busses/i2c-cpm.c  11 Oct 2008 02:53:07 -  1.1.1.1
+++ linux/drivers/i2c/busses/i2c-cpm.c  31 Oct 2008 04:05:41 -
@@ -87,6 +87,11 @@ struct i2c_ram {
 #define I2CER_TXB  0x02
 #define I2CER_RXB  0x01
 #define I2MOD_EN   0x01
+#define I2MOD_PDIV_32  0x00/* BRGCLK/32 */
+#define I2MOD_PDIV_16  0x02/* BRGCLK/16 */
+#define I2MOD_PDIV_8   0x04/* BRGCLK/8 */
+#define I2MOD_PDIV_4   0x06/* BRGCLK/4 */
+#define I2MOD_FLT  0x08

 /* I2C Registers */
 struct i2c_reg {
@@ -111,7 +116,6 @@ struct cpm_i2c {
int version; /* CPM1=1, CPM2=2 */
int irq;
int cp_command;
-   int freq;
struct i2c_reg __iomem *i2c_reg;
struct i2c_ram __iomem *i2c_ram;
u16 i2c_addr;
@@ -434,7 +438,8 @@ static int __devinit cpm_i2c_setup(struc
void __iomem *i2c_base;
cbd_t __iomem *tbdf;
cbd_t __iomem *rbdf;
-   unsigned char brg;
+   uint freq, maxfreq, prediv;
+   unsigned char mod, brg;

dev_dbg(&cpm->ofdev->dev, "cpm_i2c_setup()\n");

@@ -508,9 +513,15 @@ static int __devinit cpm_i2c_setup(struc

data = of_get_property(ofdev->node, "clock-frequency", &len);
if (data && len == 4)
-   cpm->freq = *data;
+   freq = *data;
else
-   cpm->freq = 6; /* use 60kHz i2c clock by default */
+   freq = 6;   /* use 60kHz I2C clock by default */
+
+   data = of_get_property(ofdev->node, "clock-filter", &len);
+   if (data && len == 0)
+   mod = I2MOD_FLT;
+   else
+   mod = 0;

/*
 * Allocate space for CPM_MAXBD transmit and receive buffer
@@ -552,8 +563,8 @@ static int __devinit cpm_i2c_setup(struc

cpm_reset_i2c_params(cpm);

-   dev_dbg(&cpm->ofdev->dev, "i2c_ram 0x%p, i2c_addr 0x%04x, freq %d\n",
-   cpm->i2c_ram, cpm->i2c_addr, cpm->freq);
+   dev_dbg(&cpm->ofdev->dev, "i2c_ram 0x%p, i2c_addr 0x%04x, freq %u\n",
+   cpm->i2c_ram, cpm->i2c_addr, freq);
dev_dbg(&cpm->ofdev->dev, "tbase 0x%04x, rbase 0x%04x\n",
(u8 __iomem *)cpm->tbase - DPRAM_BASE,
(u8 __iomem *)cpm->rbase - DPRAM_BASE);
@@ -566,20 +577,53 @@ static int __devinit cpm_i2c_setup(struc
out_8(&cpm->i2c_reg->i2add, 0x7f << 1);

/*
-* PDIV is set to 00 in i2mod, so brgclk/32 is used as input to the
-* i2c baud rate generator. This is divided by 2 x (DIV + 3) to get
-* the actual i2c bus frequency.
+* Compute the clock predivider and final divider to generate something
+* close to the desired I2C clock frequency.  Use the largest predivider
+* possible.  i2brg must be >= 6 when using I2MOD_FLT, otherwise >= 3.
+* So compute the highest frequency that will work with I2MOD_PDIV_32;
+* if that isn't high enough, see if we can use I2MOD_PDIV_16, etc.
+* Then choose a final divider that will generate at least the desired
+* clock frequency.  Note the "at least" -- this rounds upward, not
+* toward the nearest available frequency.
+*
+* I2C frequency for a given predivider and i2brg value is:
+*   i2cfreq = brgfreq / prediv / 2 / (i2brg + 3 + 2 * flt)
+* i2brg value for a given 

[PATCH] i2c-cpm: Add flexibility for I2C clock frequency and filter.

2008-10-30 Thread Mike Ditto
This patch adds the ability to enable the digital filter in the device
tree (with the "clock-filter" boolean property) and automates the
predivider selection according to the clock-frequency and clock-filter
properties.

Signed-off-by:  Mike Ditto <[EMAIL PROTECTED]>
---
This patch is against 2.6.27.

To use the full range of I2C clock frequencies supported by the
Freescale CPM I2C controller, it is necessary to choose an appropriate
predivider value.  The choice is affected by whether the SCL signal
digital filter is enabled.

The existing code computes the final divider (i2brg) but always uses
a predivider of 32.  This can set illegal values in i2brg - for example
on a machine with 25 MHz BRG_CLK, when selecting I2C clock-frequency
97656 Hz, the code was loading i2brg with the value 1, which does not
work (the CPM requires a minimum value of 3 when the digital filter is
not enabled).  Additionally, the calculation did not work when the
filter is enabled (and the driver did not provide a way to enable it).

And by the way, thanks to Jochen Friedrich for integrating this driver
on the very day that I went looking for it.  :-)

Index: linux/drivers/i2c/busses/i2c-cpm.c
===
RCS file: /n/home2/mditto/ws/myrepo/kernel/linux/drivers/i2c/busses/i2c-cpm.c,v
retrieving revision 1.1.1.1
diff -u -p -r1.1.1.1 i2c-cpm.c
--- linux/drivers/i2c/busses/i2c-cpm.c  11 Oct 2008 02:53:07 -  1.1.1.1
+++ linux/drivers/i2c/busses/i2c-cpm.c  31 Oct 2008 04:05:41 -
@@ -87,6 +87,11 @@ struct i2c_ram {
 #define I2CER_TXB  0x02
 #define I2CER_RXB  0x01
 #define I2MOD_EN   0x01
+#define I2MOD_PDIV_32  0x00/* BRGCLK/32 */
+#define I2MOD_PDIV_16  0x02/* BRGCLK/16 */
+#define I2MOD_PDIV_8   0x04/* BRGCLK/8 */
+#define I2MOD_PDIV_4   0x06/* BRGCLK/4 */
+#define I2MOD_FLT  0x08

 /* I2C Registers */
 struct i2c_reg {
@@ -111,7 +116,6 @@ struct cpm_i2c {
int version; /* CPM1=1, CPM2=2 */
int irq;
int cp_command;
-   int freq;
struct i2c_reg __iomem *i2c_reg;
struct i2c_ram __iomem *i2c_ram;
u16 i2c_addr;
@@ -434,7 +438,8 @@ static int __devinit cpm_i2c_setup(struc
void __iomem *i2c_base;
cbd_t __iomem *tbdf;
cbd_t __iomem *rbdf;
-   unsigned char brg;
+   uint freq, maxfreq, prediv;
+   unsigned char mod, brg;

dev_dbg(&cpm->ofdev->dev, "cpm_i2c_setup()\n");

@@ -508,9 +513,15 @@ static int __devinit cpm_i2c_setup(struc

data = of_get_property(ofdev->node, "clock-frequency", &len);
if (data && len == 4)
-   cpm->freq = *data;
+   freq = *data;
else
-   cpm->freq = 6; /* use 60kHz i2c clock by default */
+   freq = 6;   /* use 60kHz I2C clock by default */
+
+   data = of_get_property(ofdev->node, "clock-filter", &len);
+   if (data && len == 0)
+   mod = I2MOD_FLT;
+   else
+   mod = 0;

/*
 * Allocate space for CPM_MAXBD transmit and receive buffer
@@ -552,8 +563,8 @@ static int __devinit cpm_i2c_setup(struc

cpm_reset_i2c_params(cpm);

-   dev_dbg(&cpm->ofdev->dev, "i2c_ram 0x%p, i2c_addr 0x%04x, freq %d\n",
-   cpm->i2c_ram, cpm->i2c_addr, cpm->freq);
+   dev_dbg(&cpm->ofdev->dev, "i2c_ram 0x%p, i2c_addr 0x%04x, freq %u\n",
+   cpm->i2c_ram, cpm->i2c_addr, freq);
dev_dbg(&cpm->ofdev->dev, "tbase 0x%04x, rbase 0x%04x\n",
(u8 __iomem *)cpm->tbase - DPRAM_BASE,
(u8 __iomem *)cpm->rbase - DPRAM_BASE);
@@ -566,20 +577,53 @@ static int __devinit cpm_i2c_setup(struc
out_8(&cpm->i2c_reg->i2add, 0x7f << 1);

/*
-* PDIV is set to 00 in i2mod, so brgclk/32 is used as input to the
-* i2c baud rate generator. This is divided by 2 x (DIV + 3) to get
-* the actual i2c bus frequency.
+* Compute the clock predivider and final divider to generate something
+* close to the desired I2C clock frequency.  Use the largest predivider
+* possible.  i2brg must be >= 6 when using I2MOD_FLT, otherwise >= 3.
+* So compute the highest frequency that will work with I2MOD_PDIV_32;
+* if that isn't high enough, see if we can use I2MOD_PDIV_16, etc.
+* Then choose a final divider that will generate at least the desired
+* clock frequency.  Note the "at least" -- this rounds upward, not
+* toward the nearest available frequency.
+*
+* I2C frequency for a given predivider and i2brg value is:
+*   i2cfreq = brgfreq / prediv / 2 / (i2brg + 3 + 2 * flt)
+* i2brg value for a given predivider and I2C frequency is:
+*  

Re: [PATCH v2] powerpc/fs_enet: Add missing irq free in error path.

2008-10-27 Thread Mike Ditto
If something goes wrong attaching to phy driver, we weren't freeing
the IRQ.

Signed-off-by: Mike Ditto <[EMAIL PROTECTED]>
---
Reposting to CC netdev list.  (Thanks, Kumar)

diff -r -upN 2.6.28-rc1/drivers/net/fs_enet/fs_enet-main.c 
NEW/drivers/net/fs_enet/fs_enet-main.c
--- 2.6.28-rc1/drivers/net/fs_enet/fs_enet-main.c   2008-10-24 
17:54:31.0 -0700
+++ NEW/drivers/net/fs_enet/fs_enet-main.c  2008-10-24 17:57:03.0 
-0700
@@ -795,6 +795,7 @@ static int fs_enet_open(struct net_devic

err = fs_init_phy(dev);
if (err) {
+   free_irq(fep->interrupt, dev);
if (fep->fpi->use_napi)
napi_disable(&fep->napi);
return err;
___
Linuxppc-dev mailing list
Linuxppc-dev@ozlabs.org
https://ozlabs.org/mailman/listinfo/linuxppc-dev


[PATCH v2] powerpc: Add missing irq free in fs_enet error path.

2008-10-24 Thread Mike Ditto
If something goes wrong attaching to phy driver, we weren't freeing the IRQ.

Signed-off-by: Mike Ditto <[EMAIL PROTECTED]>
---
I just noticed this file has already been touched in -rc1 so here is the
patch again, adjusted accordingly.

diff -r -upN 2.6.28-rc1/drivers/net/fs_enet/fs_enet-main.c 
NEW/drivers/net/fs_enet/fs_enet-main.c
--- 2.6.28-rc1/drivers/net/fs_enet/fs_enet-main.c   2008-10-24 
17:54:31.0 -0700
+++ NEW/drivers/net/fs_enet/fs_enet-main.c  2008-10-24 17:57:03.0 
-0700
@@ -795,6 +795,7 @@ static int fs_enet_open(struct net_devic

err = fs_init_phy(dev);
if (err) {
+   free_irq(fep->interrupt, dev);
if (fep->fpi->use_napi)
napi_disable(&fep->napi);
return err;

___
Linuxppc-dev mailing list
Linuxppc-dev@ozlabs.org
https://ozlabs.org/mailman/listinfo/linuxppc-dev


[PATCH] powerpc: Add missing irq free in fs_enet error path.

2008-10-24 Thread Mike Ditto
If something goes wrong attaching to phy driver, we weren't freeing the IRQ.

Signed-off-by: Mike Ditto <[EMAIL PROTECTED]>
---

cvs diff -r linux-2_6_27 -upN linux/drivers/net/fs_enet/fs_enet-main.c
Index: linux/drivers/net/fs_enet/fs_enet-main.c
===
retrieving revision 1.1.1.1
diff -u -p -r1.1.1.1 fs_enet-main.c
--- linux/drivers/net/fs_enet/fs_enet-main.c11 Oct 2008 02:53:59 - 
1.1.1.1
+++ linux/drivers/net/fs_enet/fs_enet-main.c24 Oct 2008 22:19:47 -
@@ -811,6 +811,7 @@ static int fs_enet_open(struct net_devic

err = fs_init_phy(dev);
if (err) {
+   fs_free_irq(dev, fep->interrupt);
if (fep->fpi->use_napi)
napi_disable(&fep->napi);
return err;

___
Linuxppc-dev mailing list
Linuxppc-dev@ozlabs.org
https://ozlabs.org/mailman/listinfo/linuxppc-dev


Re: [PATCH] powerpc: Add del_node function to allow early boot code to prune inapplicable devices.

2008-10-21 Thread Mike Ditto
Benjamin Herrenschmidt wrote:
> I've fixed it up manually so no need to re-submit, but you'll know next
> time :-)

Thanks!
-=] Mike [=-
___
Linuxppc-dev mailing list
Linuxppc-dev@ozlabs.org
https://ozlabs.org/mailman/listinfo/linuxppc-dev


[PATCH] powerpc: Add del_node function to allow early boot code to prune inapplicable devices.

2008-10-21 Thread Mike Ditto
Reposting in proper format...

Some platforms have variants that can share most of a flat device tree but need
a few devices selectively pruned at boot time.  This adds del_node() to ops.h
to allow access to the existing fdt_del_node().

Signed-off-by: Mike Ditto <[EMAIL PROTECTED]>
---

Index: arch/powerpc/boot/ops.h
===
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 ops.h
--- arch/powerpc/boot/ops.h 11 Oct 2008 02:51:35 -  1.1.1.1
+++ arch/powerpc/boot/ops.h 18 Oct 2008 02:06:45 -
@@ -40,6 +40,7 @@
const int buflen);
int (*setprop)(const void *phandle, const char *name,
const void *buf, const int buflen);
+   int (*del_node)(const void *phandle);
void *(*get_parent)(const void *phandle);
/* The node must not already exist. */
void *(*create_node)(const void *parent, const char *name);
@@ -124,6 +125,11 @@
return dt_ops.setprop(devp, name, buf, strlen(buf) + 1);

return -1;
+}
+
+static inline int del_node(const void *devp)
+{
+   return dt_ops.del_node ? dt_ops.del_node(devp) : -1;
 }

 static inline void *get_parent(const char *devp)
Index: arch/powerpc/boot/libfdt-wrapper.c
===
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 libfdt-wrapper.c
--- arch/powerpc/boot/libfdt-wrapper.c  11 Oct 2008 02:51:35 -  1.1.1.1
+++ arch/powerpc/boot/libfdt-wrapper.c  17 Oct 2008 22:08:44 -
@@ -105,6 +105,11 @@
return check_err(rc);
 }

+static int fdt_wrapper_del_node(const void *devp)
+{
+   return fdt_del_node(fdt, devp_offset(devp));
+}
+
 static void *fdt_wrapper_get_parent(const void *devp)
 {
return offset_devp(fdt_parent_offset(fdt, devp_offset(devp)));
@@ -173,6 +178,7 @@
dt_ops.create_node = fdt_wrapper_create_node;
dt_ops.find_node_by_prop_value = fdt_wrapper_find_node_by_prop_value;
dt_ops.find_node_by_compatible = fdt_wrapper_find_node_by_compatible;
+   dt_ops.del_node = fdt_wrapper_del_node;
dt_ops.get_path = fdt_wrapper_get_path;
dt_ops.finalize = fdt_wrapper_finalize;

___
Linuxppc-dev mailing list
Linuxppc-dev@ozlabs.org
https://ozlabs.org/mailman/listinfo/linuxppc-dev


Re: device tree variations

2008-10-17 Thread Mike Ditto
David Gibson wrote:
> Deleting the irrelevant parts or picking a device tree to pass to
> fdt_init() are both reasonable solutions.  libfdt which is included in
> the bootwrapper has functions for removing unwanted nodes: either
> fdt_nop_node() or fdt_del_node() will suffice.  There isn't currently
> a dt_ops hook to call though to those functions though.  You could
> either add one, or (knowing that your platform always has a flat dt)
> bypass the dt_ops hooks and call libfdt directly.

Thanks.  The fdt_del_node approach works pretty nicely.  I added a
dt_ops hook since fdt is static in libfdt-wrapper.c.

At first I tried fdt_nop_node, fearing that find_node_by_prop_value()
and fdt_del_node() would interact badly when deleting in mid-traversal,
but it turns out that fdt_nop_node() upsets find_node_by_prop_value()
anyway.  Plus, the kernel prints harmless but strange messages when
there are NOPs in the tree.  So I use fdt_del_node() and rescan from
the top each time I delete a node and it works fine.

/* Find all product-dependent nodes and delete inapplicable ones. */
dev = NULL;
while ((dev = find_node_by_prop_value(dev,
  "product-dependent",
  "", 0)) != NULL) {
u32 mask;
int len;

len = getprop(dev, "productmask", &mask, sizeof mask);
if (len == sizeof mask) {
if ((mask & (1 << product_id)) == 0) {
del_node(dev);
/* Have to restart from the beginning. */
dev = NULL;
}
}
}

I had to fix the memcmp bug I mentioned in an earlier posting to allow
searching for a boolean (empty) property.

If anyone cares, below is a trivial patch to expose the del_node()
operation via dt_ops.

Thanks again,
-=] Mike [=-


Index: arch/powerpc/boot/ops.h
===
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 ops.h
--- arch/powerpc/boot/ops.h 11 Oct 2008 02:51:35 -  1.1.1.1
+++ arch/powerpc/boot/ops.h 18 Oct 2008 02:06:45 -
@@ -40,6 +40,7 @@
const int buflen);
int (*setprop)(const void *phandle, const char *name,
const void *buf, const int buflen);
+   int (*del_node)(const void *phandle);
void *(*get_parent)(const void *phandle);
/* The node must not already exist. */
void *(*create_node)(const void *parent, const char *name);
@@ -124,6 +125,11 @@
return dt_ops.setprop(devp, name, buf, strlen(buf) + 1);

return -1;
+}
+
+static inline int del_node(const void *devp)
+{
+   return dt_ops.del_node ? dt_ops.del_node(devp) : -1;
 }

 static inline void *get_parent(const char *devp)
Index: arch/powerpc/boot/libfdt-wrapper.c
===
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 libfdt-wrapper.c
--- arch/powerpc/boot/libfdt-wrapper.c  11 Oct 2008 02:51:35 -  1.1.1.1
+++ arch/powerpc/boot/libfdt-wrapper.c  17 Oct 2008 22:08:44 -
@@ -105,6 +105,11 @@
return check_err(rc);
 }

+static int fdt_wrapper_del_node(const void *devp)
+{
+   return fdt_del_node(fdt, devp_offset(devp));
+}
+
 static void *fdt_wrapper_get_parent(const void *devp)
 {
return offset_devp(fdt_parent_offset(fdt, devp_offset(devp)));
@@ -173,6 +178,7 @@
dt_ops.create_node = fdt_wrapper_create_node;
dt_ops.find_node_by_prop_value = fdt_wrapper_find_node_by_prop_value;
dt_ops.find_node_by_compatible = fdt_wrapper_find_node_by_compatible;
+   dt_ops.del_node = fdt_wrapper_del_node;
dt_ops.get_path = fdt_wrapper_get_path;
dt_ops.finalize = fdt_wrapper_finalize;

___
Linuxppc-dev mailing list
Linuxppc-dev@ozlabs.org
https://ozlabs.org/mailman/listinfo/linuxppc-dev


Bug in boot code memcmp with zero length

2008-10-17 Thread Mike Ditto
I noticed, when trying to use, e.g.,
node = find_node_by_prop_value(prev, "booleanprop", "", 0))
to search for all nodes with a certain boolean property, that memcmp()
returns garbage when comparing zero bytes.  It should return zero.

Index: arch/powerpc/boot/string.S
===
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 string.S
--- arch/powerpc/boot/string.S  11 Oct 2008 02:51:35 -  1.1.1.1
+++ arch/powerpc/boot/string.S  17 Oct 2008 19:11:18 -
@@ -235,7 +235,7 @@
.globl  memcmp
 memcmp:
cmpwi   0,r5,0
-   blelr
+   ble 2f
mtctr   r5
addir6,r3,-1
addir4,r4,-1
@@ -243,6 +243,8 @@
lbzur0,1(r4)
subf.   r3,r0,r3
bdnzt   2,1b
+   blr
+2: li  r3,0
blr


___
Linuxppc-dev mailing list
Linuxppc-dev@ozlabs.org
https://ozlabs.org/mailman/listinfo/linuxppc-dev


device tree variations

2008-10-16 Thread Mike Ditto
I'm building a kernel that can run on a handful of hardware
configurations, all using OF-unaware U-Boot.  I know how to make a
static device tree (dts file) that works on one of these hardware
variations, and how to add nodes and modify properties in the platform
init code.  But I don't see a nice way to deal with nodes that should be
present on only some hardware configurations.

I could have the dts file contain only the common elements, and add all
the variable elements in the startup code.  But that means the bulk of
the device tree will be expressed as relatively ugly C source instead of
the much more readable and maintainable dts notation.  I would much
rather have the dts file contain the union of all platforms and have the
platform init code delete the nodes that are not applicable, but I don't
see an API to do those deletions.

I suppose I could instead compile N different dts files and have the
platform init code pick the appropriate dtb blob to pass to fdt_init().

Any suggestions for the best way to do this?

-=] Mike [=-
___
Linuxppc-dev mailing list
Linuxppc-dev@ozlabs.org
https://ozlabs.org/mailman/listinfo/linuxppc-dev