LinuxPPC-Dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* Re: Please pull pasemi.git for-2.6.25 branch
From: Olof Johansson @ 2007-12-04  0:07 UTC (permalink / raw)
  To: paulus; +Cc: linuxppc-dev
In-Reply-To: <20071203050446.GC24492@lixom.net>

On Sun, Dec 02, 2007 at 11:04:47PM -0600, Olof Johansson wrote:
> Paul,
> 
> Please do:
> 
> git pull \
> git://git.kernel.org/pub/scm/linux/kernel/git/olof/pasemi.git for-2.6.25
> 
> For the following patches queued up for 2.6.25. All but one are PA
> Semi-specific (the i2c boardinfo consolidation that's a pre-req for the
> platform-specific one).

Sorry for the churn here, I hope you haven't pulled yet.

Based on today's i2c patches from Jon Smirl, it makes more sense for me
to hold off on my i2c changes and make them on top of his work once that
has been merged.

I've backed out and rebased the patch set, new shortlog and diffstat:

 arch/powerpc/platforms/pasemi/Kconfig     |    2 
 arch/powerpc/platforms/pasemi/cpufreq.c   |   19 +++++-
 arch/powerpc/platforms/pasemi/gpio_mdio.c |   94 ++++++++++++++++++------------
 arch/powerpc/platforms/pasemi/pasemi.h    |    6 +
 arch/powerpc/platforms/pasemi/powersave.S |   11 +++
 arch/powerpc/platforms/pasemi/setup.c     |   16 ++++-
 drivers/char/hw_random/Kconfig            |    2 
 drivers/char/hw_random/pasemi-rng.c       |    7 --
 drivers/edac/pasemi_edac.c                |    4 -
 9 files changed, 111 insertions(+), 50 deletions(-)

Olof Johansson (5):
      [POWERPC] pasemi: clean up mdio_gpio a bit
      [POWERPC] pasemi: Broaden specific references to 1682M
      [POWERPC] pasemi: Don't enter powersaving states from elevated astates
      [POWERPC] pasemi: Move cpus to hold loop before restart
      [POWERPC] pasemi: Fix module information for gpio-mdio


-Olof

^ permalink raw reply

* Re: [PATCH 0/4] Series to add device tree naming to i2c
From: Olof Johansson @ 2007-12-04  0:04 UTC (permalink / raw)
  To: Jon Smirl; +Cc: linuxppc-dev, paulus, i2c
In-Reply-To: <9e4733910712031552j36efd4b2u933f0f4e9832a003@mail.gmail.com>

On Mon, Dec 03, 2007 at 06:52:06PM -0500, Jon Smirl wrote:
> On 12/3/07, Olof Johansson <olof@lixom.net> wrote:
> > On Mon, Dec 03, 2007 at 04:20:32PM -0500, Jon Smirl wrote:
> > > The following series implements standard linux module aliasing for i2c modules
> > > It then converts the mpc i2c driver from being a platform driver to an open
> > > firmware one. I2C device names are picked up from the device tree. Module
> > > aliasing is used to translate from device tree names into to linux kernel
> > > names. Several i2c drivers are updated to use the new aliasing.
> >
> > May I ask why you want to modify the i2c layer instead of keeping the
> > OF->i2c driver mapping in PPC code? It seems simpler to keep it in the
> > PPC-specific code, since otherwise you might end up with confused i2c
> > driver writers that make up their own OF names without knowing for sure
> > that's what will be used. No?
> 
> Audio codecs have the same problem. That table is could end up with
> hundreds of entries. The right place to store the mappings is in the
> device driver for the device.
> 
> A side effect of moving the mappings into the device drivers is that
> the correct i2c drivers can be automatically loaded by the kernel.
> This lets you make distro CDs with all of the i2c drivers on disk and
> the device tree will cause insmod of the correct ones.

Ok, good enough reasons. I'll back out my i2c commits and wait for yours
to settle, then add the pasemi stuff in the same way.

(Whitespace comments still apply).


-Olof

^ permalink raw reply

* Re: [PATCH 0/4] Series to add device tree naming to i2c
From: Scott Wood @ 2007-12-03 23:51 UTC (permalink / raw)
  To: Olof Johansson; +Cc: linuxppc-dev, i2c
In-Reply-To: <20071203233752.GA7041@lixom.net>

Olof Johansson wrote:
> On Mon, Dec 03, 2007 at 04:20:32PM -0500, Jon Smirl wrote:
>> The following series implements standard linux module aliasing for i2c modules
>> It then converts the mpc i2c driver from being a platform driver to an open
>> firmware one. I2C device names are picked up from the device tree. Module
>> aliasing is used to translate from device tree names into to linux kernel
>> names. Several i2c drivers are updated to use the new aliasing. 
> 
> May I ask why you want to modify the i2c layer instead of keeping the
> OF->i2c driver mapping in PPC code?

Because it doesn't belong there -- at the least, it should be in 
drivers/of.  But putting it in the driver is better, IMHO.

> It seems simpler to keep it in the
> PPC-specific code, since otherwise you might end up with confused i2c
> driver writers that make up their own OF names without knowing for sure
> that's what will be used. No?

How is this different from drivers that have of_platform bindings?

That said, there should probably be some sort of tag to indicate the 
namespace being matched against (OF, Linux, etc), to avoid matching an 
OF device with a non-OF name (or vice versa).

> I recently posted (and asked Paulus to pull) a patch where I consolidate
> the fsl_soc mapping code so I can also use that on pasemi, and modified
> the pasemi platform code to setup the board_info from the device tree
> accordingly.

Having just one bit i2c glue code for arch/powerpc is certainly an 
improvement over the current situation, but it's not really powerpc 
specific.  Just because other architectures don't use it now doesn't 
mean they won't in the future -- and I don't like the "we'll move it 
when they do" argument because I want to make it easy for other 
architectures to decide to use it. :-)

-Scott

^ permalink raw reply

* Re: [PATCH 0/4] Series to add device tree naming to i2c
From: Jon Smirl @ 2007-12-03 23:52 UTC (permalink / raw)
  To: Olof Johansson; +Cc: linuxppc-dev, i2c
In-Reply-To: <20071203233752.GA7041@lixom.net>

On 12/3/07, Olof Johansson <olof@lixom.net> wrote:
> On Mon, Dec 03, 2007 at 04:20:32PM -0500, Jon Smirl wrote:
> > The following series implements standard linux module aliasing for i2c modules
> > It then converts the mpc i2c driver from being a platform driver to an open
> > firmware one. I2C device names are picked up from the device tree. Module
> > aliasing is used to translate from device tree names into to linux kernel
> > names. Several i2c drivers are updated to use the new aliasing.
>
> May I ask why you want to modify the i2c layer instead of keeping the
> OF->i2c driver mapping in PPC code? It seems simpler to keep it in the
> PPC-specific code, since otherwise you might end up with confused i2c
> driver writers that make up their own OF names without knowing for sure
> that's what will be used. No?

Audio codecs have the same problem. That table is could end up with
hundreds of entries. The right place to store the mappings is in the
device driver for the device.

A side effect of moving the mappings into the device drivers is that
the correct i2c drivers can be automatically loaded by the kernel.
This lets you make distro CDs with all of the i2c drivers on disk and
the device tree will cause insmod of the correct ones.

I'm working on a parallel patch for Alsa SOC but it isn't ready yet.

>
> I recently posted (and asked Paulus to pull) a patch where I consolidate
> the fsl_soc mapping code so I can also use that on pasemi, and modified
> the pasemi platform code to setup the board_info from the device tree
> accordingly.
>
> Finally, whitespace is broken in several of your patches.
>
>
> -Olof
>


-- 
Jon Smirl
jonsmirl@gmail.com

^ permalink raw reply

* Re: [PATCH 0/4] Series to add device tree naming to i2c
From: Olof Johansson @ 2007-12-03 23:37 UTC (permalink / raw)
  To: Jon Smirl; +Cc: linuxppc-dev, i2c
In-Reply-To: <20071203212032.23543.3453.stgit@terra.home>

On Mon, Dec 03, 2007 at 04:20:32PM -0500, Jon Smirl wrote:
> The following series implements standard linux module aliasing for i2c modules
> It then converts the mpc i2c driver from being a platform driver to an open
> firmware one. I2C device names are picked up from the device tree. Module
> aliasing is used to translate from device tree names into to linux kernel
> names. Several i2c drivers are updated to use the new aliasing. 

May I ask why you want to modify the i2c layer instead of keeping the
OF->i2c driver mapping in PPC code? It seems simpler to keep it in the
PPC-specific code, since otherwise you might end up with confused i2c
driver writers that make up their own OF names without knowing for sure
that's what will be used. No?

I recently posted (and asked Paulus to pull) a patch where I consolidate
the fsl_soc mapping code so I can also use that on pasemi, and modified
the pasemi platform code to setup the board_info from the device tree
accordingly.

Finally, whitespace is broken in several of your patches.


-Olof

^ permalink raw reply

* Re: Problem compiling sequoia using DENX kernel. Xenomai-patch required?
From: Wolfgang Denk @ 2007-12-03 23:08 UTC (permalink / raw)
  To: niklaus.giger; +Cc: linuxppc-embedded
In-Reply-To: <200712022141.36467.niklaus.giger@member.fsf.org>

In message <200712022141.36467.niklaus.giger@member.fsf.org> you wrote:
> 
> I tried with (tags DENX-v2.6.23.9, DENX-v.2.6.23, master) to build a kernel 
> for the sequoia board.
> I am using ELDK 4.1. I did a 
> git checkout -b copy-master master
> make ARCH=powerpc CROSS_COMPILE=ppc_4xx- CFLAGS=-g sequoia_defconfig 
> make ARCH=powerpc CROSS_COMPILE=ppc_4xx- CFLAGS=-g zImage 

The ARCH=powerpc is the "interesting" part here.

> First I stumbled about problem compiling arch/powerpc/platforms/44x/ppc4xx*.c
> file with errors like
> arch/powerpc/platforms/44x/ppc4xx-pci.c: In function 'ppc4xx_setup_pci':
> arch/powerpc/platforms/44x/ppc4xx-pci.c:62: sorry, unimplemented: inlining 
> failed in call to 'pci_cfg_out': function body not available
> arch/powerpc/platforms/44x/ppc4xx-pci.c:98: sorry, unimplemented: called from 
> here

There are many moving targets in the ARCH=powerpc hemisphere for 4xx
systems...

> I thought that denx compiled images for the sequoia using 2.6.23. 

Yes, we do. But stable support is only available  with  the  arch/ppc
tree yet.

> Do they only work after having applied the Xenomai patch? Because if I apply 

No.

> the Xenomai patch, the kernel compiles cleanly. In this case  I think it 

That's just lucky coincidence...

> would be nice to get somewhere a hint (or did I missed it somewhere) that 
> this is a requirement. I lost quite a few hours as I wanted to first compile 
> a "normal" kernel and afterwars apply the xenomai patch.

I'm afraid "normal" here still means arch/ppc  -  hopefully  for  not
long any more. Note: a matching Xenomai patch for arch/ppc will be in
Xenomai 2.4 when it comes out in a few days.

Best regards,

Wolfgang Denk

-- 
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd@denx.de
Good manners are the settled  medium  of  social,  as  specie  is  of
commercial, life; returns are equally expected for both.
           - Lord Chesterfield _Letters to his Son_, 25 December 1753

^ permalink raw reply

* Re: [PATCH 09/28] blk_end_request: changing ps3disk (take 3)
From: Kiyoshi Ueda @ 2007-12-03 22:55 UTC (permalink / raw)
  To: Geert.Uytterhoeven
  Cc: k-ueda, linux-scsi, linuxppc-dev, jens.axboe, linux-kernel,
	linux-ide, dm-devel, bharrosh, j-nomura
In-Reply-To: <Pine.LNX.4.64.0712021032490.29349@anakin>

Hi Geert,

On Sun, 2 Dec 2007 10:34:56 +0100 (CET), Geert Uytterhoeven <Geert.Uytterhoeven@sonycom.com> wrote:
> On Fri, 30 Nov 2007, Kiyoshi Ueda wrote:
> > This patch converts ps3disk to use blk_end_request().
>                                      ^^^^^^^^^^^^^^^
> Patch subject and description are inconsistent with actual change.
> 
> > Signed-off-by: Kiyoshi Ueda <k-ueda@ct.jp.nec.com>
> > Signed-off-by: Jun'ichi Nomura <j-nomura@ce.jp.nec.com>
> > ---
> >  drivers/block/ps3disk.c |    6 +-----
> >  1 files changed, 1 insertion(+), 5 deletions(-)
> > 
> > Index: 2.6.24-rc3-mm2/drivers/block/ps3disk.c
> > ===================================================================
> > --- 2.6.24-rc3-mm2.orig/drivers/block/ps3disk.c
> > +++ 2.6.24-rc3-mm2/drivers/block/ps3disk.c
> > @@ -280,11 +280,7 @@ static irqreturn_t ps3disk_interrupt(int
> >  	}
> >  
> >  	spin_lock(&priv->lock);
> > -	if (!end_that_request_first(req, uptodate, num_sectors)) {
> > -		add_disk_randomness(req->rq_disk);
> > -		blkdev_dequeue_request(req);
> > -		end_that_request_last(req, uptodate);
> > -	}
> > +	__blk_end_request(req, uptodate, num_sectors << 9);
>       ^^^^^^^^^^^^^^^^^

Thank you for the comment.
The description meant the blk_end_request family, not actual function,
blk_end_request().  But as you pointed out, it is misleading.
I'll change the description of all related patches.

Thanks,
Kiyoshi Ueda

^ permalink raw reply

* Re: SMP on linux with Microblaze?
From: John Williams @ 2007-12-03 21:18 UTC (permalink / raw)
  To: khollan; +Cc: linuxppc-embedded
In-Reply-To: <14137760.post@talk.nabble.com>

Hi,

khollan wrote:

>Now that Full Linux can run on Microblaze with the addition of the MMU, are
>there plans to enable Symmetric Multi-Processing of two or more Microblaze
>cores running Linux?
>  
>
This isn't really the right list for direct microblaze discussion, but
since you asked..  The challenge with SMP is not an MMU, but cache
coherency.  This is why native SMP on dual PPC on V4/V5 is also a
non-starter.  It is possible to build software driven snoop/invalidate
mechanisms that might allow a crippled SMP on MicroBlaze, but I think
the performance would be pretty nasty. 

The Blackfin Linux team have done some interesting things towards SMP on
non cache-coherent dual CPUs.  Basically they do a local cache
invalidation upon acquiring any kernel lock, on the theory that if you
are accessing a shared data structure you will grab a lock first.  Thus,
the cache flush will make sure you get the "true" value, not some stale
locally cached result.  But, it's still pretty inefficient, and cannot
do things like processor affinity and process migration.  Google the
bfin lists for details and patches.

Regards,

John

^ permalink raw reply

* Re: [PATCH] Generic RTC class support for ppc_md.[gs]et_rtc_time
From: David Woodhouse @ 2007-12-03 22:44 UTC (permalink / raw)
  To: benh; +Cc: linuxppc-dev
In-Reply-To: <1196721397.13230.236.camel@pasglop>

On Tue, 2007-12-04 at 09:36 +1100, Benjamin Herrenschmidt wrote:
> Worst one is time_init :-) Way too early to do any i2c babbling. Then
> there used to be something with the NTP writeback, dunno if it's
> changed.

Setting the system time seems to be done in the new RTC class by a
late_initcall() in drivers/rtc/hctosys.c. In fact, it could even be done
in userspace.

NTP uses update_persistent_clock() and doesn't seem to have been
'solved' yet for the new RTC class. I don't think there's any particular
reason for it to do i2c stuff in that context though.

-- 
dwmw2

^ permalink raw reply

* Re: [PATCH] Generic RTC class support for ppc_md.[gs]et_rtc_time
From: Benjamin Herrenschmidt @ 2007-12-03 22:36 UTC (permalink / raw)
  To: David Woodhouse; +Cc: linuxppc-dev
In-Reply-To: <1196715974.13978.176.camel@pmac.infradead.org>


On Mon, 2007-12-03 at 21:06 +0000, David Woodhouse wrote:
> On Tue, 2007-12-04 at 07:45 +1100, Benjamin Herrenschmidt wrote:
> > On Mon, 2007-12-03 at 17:04 +0000, David Woodhouse wrote:
> > > It would be good to migrate the platform code to register RTC devices
> > > directly, but for now this will make them functional enough for most
> > > purposes...
> > 
> > Wouldn't it be best to do the other way around at some stage ?
> 
> Yes, definitely. We can migrate them one at a time to the RTC class.
> 
> > We need to solve the problem of ppc_md. stuff being called by the core
> > in atomic contexts first though.
> 
> Where from?

Worst one is time_init :-) Way too early to do any i2c babbling. Then
there used to be something with the NTP writeback, dunno if it's
changed.

Ben.

^ permalink raw reply

* [PATCH 4/4] Convert pfc8563 i2c driver from old style to new style
From: Jon Smirl @ 2007-12-03 21:20 UTC (permalink / raw)
  To: i2c, linuxppc-dev
In-Reply-To: <20071203212032.23543.3453.stgit@terra.home>

Convert pfc8563 i2c driver from old style to new style. The
driver is also modified to support device tree names via the
i2c mod alias mechanism.
---

 drivers/rtc/rtc-pcf8563.c |  114 +++++++++++++--------------------------------
 1 files changed, 32 insertions(+), 82 deletions(-)


diff --git a/drivers/rtc/rtc-pcf8563.c b/drivers/rtc/rtc-pcf8563.c
index 0242d80..20b1acf 100644
--- a/drivers/rtc/rtc-pcf8563.c
+++ b/drivers/rtc/rtc-pcf8563.c
@@ -25,10 +25,6 @@
  * located at 0x51 will pass the validation routine due to
  * the way the registers are implemented.
  */
-static unsigned short normal_i2c[] = { I2C_CLIENT_END };
-
-/* Module parameters */
-I2C_CLIENT_INSMOD;
 
 #define PCF8563_REG_ST1		0x00 /* status */
 #define PCF8563_REG_ST2		0x01
@@ -72,9 +68,6 @@ struct pcf8563 {
 	int c_polarity;	/* 0: MO_C=1 means 19xx, otherwise MO_C=1 means 20xx */
 };
 
-static int pcf8563_probe(struct i2c_adapter *adapter, int address, int kind);
-static int pcf8563_detach(struct i2c_client *client);
-
 /*
  * In the routines that deal directly with the pcf8563 hardware, we use
  * rtc_time -- month 0-11, hour 0-23, yr = calendar year-epoch.
@@ -257,98 +250,55 @@ static const struct rtc_class_ops pcf8563_rtc_ops = {
 	.set_time	= pcf8563_rtc_set_time,
 };
 
-static int pcf8563_attach(struct i2c_adapter *adapter)
+static int pcf8563_remove(struct i2c_client *client)
 {
-	return i2c_probe(adapter, &addr_data, pcf8563_probe);
+	struct rtc_device *rtc = i2c_get_clientdata(client);
+
+	if (rtc)
+		rtc_device_unregister(rtc);
+	
+	return 0;
 }
 
+static struct i2c_device_id pcf8563_id[] = {
+	{"rtc-pcf8563", 0},
+	{"pcf8563", 0},
+	{"philips,pcf8563", 0},
+	{"rtc8564", 0},
+	{"epson,rtc8564", 0},
+	{},
+};
+MODULE_DEVICE_TABLE(i2c, pcf8563_id);
+
+static int pcf8563_probe(struct i2c_client *client, const struct i2c_device_id *id);
+
 static struct i2c_driver pcf8563_driver = {
 	.driver		= {
-		.name	= "pcf8563",
+		.name	= "rtc-pcf8563",
 	},
 	.id		= I2C_DRIVERID_PCF8563,
-	.attach_adapter = &pcf8563_attach,
-	.detach_client	= &pcf8563_detach,
+	.probe = &pcf8563_probe,
+	.remove = &pcf8563_remove,
+	.id_table	= pcf8563_id,
 };
 
-static int pcf8563_probe(struct i2c_adapter *adapter, int address, int kind)
+static int pcf8563_probe(struct i2c_client *client, const struct i2c_device_id *id)
 {
-	struct pcf8563 *pcf8563;
-	struct i2c_client *client;
+	int result;
 	struct rtc_device *rtc;
-
-	int err = 0;
-
-	dev_dbg(&adapter->dev, "%s\n", __FUNCTION__);
-
-	if (!i2c_check_functionality(adapter, I2C_FUNC_I2C)) {
-		err = -ENODEV;
-		goto exit;
-	}
-
-	if (!(pcf8563 = kzalloc(sizeof(struct pcf8563), GFP_KERNEL))) {
-		err = -ENOMEM;
-		goto exit;
-	}
-
-	client = &pcf8563->client;
-	client->addr = address;
-	client->driver = &pcf8563_driver;
-	client->adapter	= adapter;
-
-	strlcpy(client->name, pcf8563_driver.driver.name, I2C_NAME_SIZE);
-
-	/* Verify the chip is really an PCF8563 */
-	if (kind < 0) {
-		if (pcf8563_validate_client(client) < 0) {
-			err = -ENODEV;
-			goto exit_kfree;
-		}
-	}
-
-	/* Inform the i2c layer */
-	if ((err = i2c_attach_client(client)))
-		goto exit_kfree;
-
-	dev_info(&client->dev, "chip found, driver version " DRV_VERSION "\n");
-
+	
+	result = pcf8563_validate_client(client);
+	if (result)
+		return result;
+	
 	rtc = rtc_device_register(pcf8563_driver.driver.name, &client->dev,
 				&pcf8563_rtc_ops, THIS_MODULE);
-
-	if (IS_ERR(rtc)) {
-		err = PTR_ERR(rtc);
-		goto exit_detach;
-	}
+	if (IS_ERR(rtc))
+		return PTR_ERR(rtc);
 
 	i2c_set_clientdata(client, rtc);
 
 	return 0;
-
-exit_detach:
-	i2c_detach_client(client);
-
-exit_kfree:
-	kfree(pcf8563);
-
-exit:
-	return err;
-}
-
-static int pcf8563_detach(struct i2c_client *client)
-{
-	struct pcf8563 *pcf8563 = container_of(client, struct pcf8563, client);
-	int err;
-	struct rtc_device *rtc = i2c_get_clientdata(client);
-
-	if (rtc)
-		rtc_device_unregister(rtc);
-
-	if ((err = i2c_detach_client(client)))
-		return err;
-
-	kfree(pcf8563);
-
-	return 0;
 }
 
 static int __init pcf8563_init(void)

^ permalink raw reply related

* [PATCH 1/4] Implement module aliasing for i2c to translate from device tree names
From: Jon Smirl @ 2007-12-03 21:20 UTC (permalink / raw)
  To: i2c, linuxppc-dev
In-Reply-To: <20071203212032.23543.3453.stgit@terra.home>

This patch allows new style i2c chip drivers to have alias names using
the official kernel aliasing system and MODULE_DEVICE_TABLE(). I've
tested it on PowerPC and x86. This change is required for PowerPC
device tree support.
---

 drivers/i2c/i2c-core.c          |   34 +++++++++++++++++++++++++++-------
 include/linux/i2c.h             |    5 ++---
 include/linux/mod_devicetable.h |    9 +++++++++
 3 files changed, 38 insertions(+), 10 deletions(-)


diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
index b5e13e4..76f48be 100644
--- a/drivers/i2c/i2c-core.c
+++ b/drivers/i2c/i2c-core.c
@@ -47,10 +47,26 @@ static DEFINE_IDR(i2c_adapter_idr);
 
 /* ------------------------------------------------------------------------- */
 
-static int i2c_device_match(struct device *dev, struct device_driver *drv)
+static const struct i2c_device_id * i2c_device_match(const struct i2c_device_id *id, struct i2c_client *client)
+{
+	/* new style drivers use the same kind of driver matching policy
+	 * as platform devices or SPI:  compare device and driver IDs.
+	 */
+	if (id) {
+    	while (id->name[0]) {
+        	if (strcmp(client->driver_name, id->name) == 0)
+            	return id;
+            id++;
+        }
+    }
+    return NULL;
+}
+
+static int i2c_bus_match(struct device *dev, struct device_driver *drv)
 {
 	struct i2c_client	*client = to_i2c_client(dev);
 	struct i2c_driver	*driver = to_i2c_driver(drv);
+	const struct i2c_device_id *found_id;
 
 	/* make legacy i2c drivers bypass driver model probing entirely;
 	 * such drivers scan each i2c adapter/bus themselves.
@@ -58,10 +74,11 @@ static int i2c_device_match(struct device *dev, struct device_driver *drv)
 	if (!is_newstyle_driver(driver))
 		return 0;
 
-	/* new style drivers use the same kind of driver matching policy
-	 * as platform devices or SPI:  compare device and driver IDs.
-	 */
-	return strcmp(client->driver_name, drv->name) == 0;
+    found_id = i2c_device_match(driver->id_table, client);
+    if (found_id)
+            return 1;
+
+    return 0;
 }
 
 #ifdef	CONFIG_HOTPLUG
@@ -89,12 +106,15 @@ static int i2c_device_probe(struct device *dev)
 {
 	struct i2c_client	*client = to_i2c_client(dev);
 	struct i2c_driver	*driver = to_i2c_driver(dev->driver);
+	const struct i2c_device_id *id;
 
 	if (!driver->probe)
 		return -ENODEV;
 	client->driver = driver;
 	dev_dbg(dev, "probe\n");
-	return driver->probe(client);
+	
+    id = i2c_device_match(driver->id_table, client);
+	return driver->probe(client, id);
 }
 
 static int i2c_device_remove(struct device *dev)
@@ -189,7 +209,7 @@ static struct device_attribute i2c_dev_attrs[] = {
 static struct bus_type i2c_bus_type = {
 	.name		= "i2c",
 	.dev_attrs	= i2c_dev_attrs,
-	.match		= i2c_device_match,
+	.match		= i2c_bus_match,
 	.uevent		= i2c_device_uevent,
 	.probe		= i2c_device_probe,
 	.remove		= i2c_device_remove,
diff --git a/include/linux/i2c.h b/include/linux/i2c.h
index a100c9f..56d2dca 100644
--- a/include/linux/i2c.h
+++ b/include/linux/i2c.h
@@ -126,7 +126,7 @@ struct i2c_driver {
 	 * With the driver model, device enumeration is NEVER done by drivers;
 	 * it's done by infrastructure.  (NEW STYLE DRIVERS ONLY)
 	 */
-	int (*probe)(struct i2c_client *);
+	int (*probe)(struct i2c_client *, const struct i2c_device_id *id);
 	int (*remove)(struct i2c_client *);
 
 	/* driver model interfaces that don't relate to enumeration  */
@@ -141,11 +141,10 @@ struct i2c_driver {
 
 	struct device_driver driver;
 	struct list_head list;
+	struct i2c_device_id *id_table; 
 };
 #define to_i2c_driver(d) container_of(d, struct i2c_driver, driver)
 
-#define I2C_NAME_SIZE	20
-
 /**
  * struct i2c_client - represent an I2C slave device
  * @flags: I2C_CLIENT_TEN indicates the device uses a ten bit chip address;
diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h
index e9fddb4..688fad6 100644
--- a/include/linux/mod_devicetable.h
+++ b/include/linux/mod_devicetable.h
@@ -367,4 +367,13 @@ struct virtio_device_id {
 };
 #define VIRTIO_DEV_ANY_ID	0xffffffff
 
+/* i2c */
+
+#define I2C_NAME_SIZE	40
+struct i2c_device_id {
+	char name[I2C_NAME_SIZE];
+	kernel_ulong_t driver_data;	/* Data private to the driver */
+};
+
+
 #endif /* LINUX_MOD_DEVICETABLE_H */

^ permalink raw reply related

* [PATCH 0/4] Series to add device tree naming to i2c
From: Jon Smirl @ 2007-12-03 21:20 UTC (permalink / raw)
  To: i2c, linuxppc-dev

The following series implements standard linux module aliasing for i2c modules
It then converts the mpc i2c driver from being a platform driver to an open
firmware one. I2C device names are picked up from the device tree. Module
aliasing is used to translate from device tree names into to linux kernel
names. Several i2c drivers are updated to use the new aliasing. 

--
Jon Smirl
jonsmirl@gmail.com 

^ permalink raw reply

* [PATCH 2/4] Modify several rtc drivers to use the alias names list property of i2c
From: Jon Smirl @ 2007-12-03 21:20 UTC (permalink / raw)
  To: i2c, linuxppc-dev
In-Reply-To: <20071203212032.23543.3453.stgit@terra.home>

This patch modifies the ds1307, ds1374, and rs5c372 i2c drivers to support
device tree names using the new i2c mod alias support
---

 arch/powerpc/sysdev/fsl_soc.c |   46 ++++++-----------------------------------
 drivers/rtc/rtc-ds1307.c      |   38 ++++++++++++++++++----------------
 drivers/rtc/rtc-ds1374.c      |   11 +++++++++-
 drivers/rtc/rtc-rs5c372.c     |   31 +++++++++++++++-------------
 4 files changed, 54 insertions(+), 72 deletions(-)


diff --git a/arch/powerpc/sysdev/fsl_soc.c b/arch/powerpc/sysdev/fsl_soc.c
index 3ace747..e4c766e 100644
--- a/arch/powerpc/sysdev/fsl_soc.c
+++ b/arch/powerpc/sysdev/fsl_soc.c
@@ -320,48 +320,12 @@ arch_initcall(gfar_of_init);
 
 #ifdef CONFIG_I2C_BOARDINFO
 #include <linux/i2c.h>
-struct i2c_driver_device {
-	char	*of_device;
-	char	*i2c_driver;
-	char	*i2c_type;
-};
-
-static struct i2c_driver_device i2c_devices[] __initdata = {
-	{"ricoh,rs5c372a", "rtc-rs5c372", "rs5c372a",},
-	{"ricoh,rs5c372b", "rtc-rs5c372", "rs5c372b",},
-	{"ricoh,rv5c386",  "rtc-rs5c372", "rv5c386",},
-	{"ricoh,rv5c387a", "rtc-rs5c372", "rv5c387a",},
-	{"dallas,ds1307",  "rtc-ds1307",  "ds1307",},
-	{"dallas,ds1337",  "rtc-ds1307",  "ds1337",},
-	{"dallas,ds1338",  "rtc-ds1307",  "ds1338",},
-	{"dallas,ds1339",  "rtc-ds1307",  "ds1339",},
-	{"dallas,ds1340",  "rtc-ds1307",  "ds1340",},
-	{"stm,m41t00",     "rtc-ds1307",  "m41t00"},
-	{"dallas,ds1374",  "rtc-ds1374",  "rtc-ds1374",},
-};
-
-static int __init of_find_i2c_driver(struct device_node *node,
-				     struct i2c_board_info *info)
-{
-	int i;
-
-	for (i = 0; i < ARRAY_SIZE(i2c_devices); i++) {
-		if (!of_device_is_compatible(node, i2c_devices[i].of_device))
-			continue;
-		if (strlcpy(info->driver_name, i2c_devices[i].i2c_driver,
-			    KOBJ_NAME_LEN) >= KOBJ_NAME_LEN ||
-		    strlcpy(info->type, i2c_devices[i].i2c_type,
-			    I2C_NAME_SIZE) >= I2C_NAME_SIZE)
-			return -ENOMEM;
-		return 0;
-	}
-	return -ENODEV;
-}
 
 static void __init of_register_i2c_devices(struct device_node *adap_node,
 					   int bus_num)
 {
 	struct device_node *node = NULL;
+	const char *compatible;
 
 	while ((node = of_get_next_child(adap_node, node))) {
 		struct i2c_board_info info = {};
@@ -378,9 +342,13 @@ static void __init of_register_i2c_devices(struct device_node *adap_node,
 		if (info.irq == NO_IRQ)
 			info.irq = -1;
 
-		if (of_find_i2c_driver(node, &info) < 0)
+		compatible = of_get_property(node, "compatible", &len);
+		if (!compatible) {
+			printk(KERN_WARNING "i2c-mpc.c: invalid entry, missing compatible attribute\n");
 			continue;
-
+		}
+		strncpy(info.driver_name, compatible, sizeof(info.driver_name));
+		
 		info.addr = *addr;
 
 		i2c_register_board_info(bus_num, &info, 1);
diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c
index bc1c7fe..a4dec4b 100644
--- a/drivers/rtc/rtc-ds1307.c
+++ b/drivers/rtc/rtc-ds1307.c
@@ -99,45 +99,46 @@ struct ds1307 {
 };
 
 struct chip_desc {
-	char			name[9];
 	unsigned		nvram56:1;
 	unsigned		alarm:1;
 	enum ds_type		type;
 };
 
 static const struct chip_desc chips[] = { {
-	.name		= "ds1307",
 	.type		= ds_1307,
 	.nvram56	= 1,
 }, {
-	.name		= "ds1337",
 	.type		= ds_1337,
 	.alarm		= 1,
 }, {
-	.name		= "ds1338",
 	.type		= ds_1338,
 	.nvram56	= 1,
 }, {
-	.name		= "ds1339",
 	.type		= ds_1339,
 	.alarm		= 1,
 }, {
-	.name		= "ds1340",
 	.type		= ds_1340,
 }, {
-	.name		= "m41t00",
 	.type		= m41t00,
 }, };
 
-static inline const struct chip_desc *find_chip(const char *s)
-{
-	unsigned i;
-
-	for (i = 0; i < ARRAY_SIZE(chips); i++)
-		if (strnicmp(s, chips[i].name, sizeof chips[i].name) == 0)
-			return &chips[i];
-	return NULL;
-}
+static struct i2c_device_id ds1307_id[] = {
+	{"rtc-ds1307", ds_1307},
+	{"ds1307", ds_1307},
+	{"ds1337", ds_1337},
+	{"ds1338", ds_1338},
+	{"ds1339", ds_1339},
+	{"ds1340", ds_1340},
+	{"m41t00", m41t00},
+	{"dallas,ds1307", ds_1307},
+	{"dallas,ds1337", ds_1337},
+	{"dallas,ds1338", ds_1338},
+	{"dallas,ds1339", ds_1339},
+	{"dallas,ds1340", ds_1340},
+	{"stm,m41t00", m41t00},
+	{},
+};
+MODULE_DEVICE_TABLE(i2c, ds1307_id);
 
 static int ds1307_get_time(struct device *dev, struct rtc_time *t)
 {
@@ -326,7 +327,7 @@ static struct bin_attribute nvram = {
 
 static struct i2c_driver ds1307_driver;
 
-static int __devinit ds1307_probe(struct i2c_client *client)
+static int __devinit ds1307_probe(struct i2c_client *client, const struct i2c_device_id *id)
 {
 	struct ds1307		*ds1307;
 	int			err = -ENODEV;
@@ -334,7 +335,7 @@ static int __devinit ds1307_probe(struct i2c_client *client)
 	const struct chip_desc	*chip;
 	struct i2c_adapter	*adapter = to_i2c_adapter(client->dev.parent);
 
-	chip = find_chip(client->name);
+	chip = &chips[id->driver_data];
 	if (!chip) {
 		dev_err(&client->dev, "unknown chip type '%s'\n",
 				client->name);
@@ -537,6 +538,7 @@ static struct i2c_driver ds1307_driver = {
 	},
 	.probe		= ds1307_probe,
 	.remove		= __devexit_p(ds1307_remove),
+	.id_table	= ds1307_id,
 };
 
 static int __init ds1307_init(void)
diff --git a/drivers/rtc/rtc-ds1374.c b/drivers/rtc/rtc-ds1374.c
index 45bda18..2b852f3 100644
--- a/drivers/rtc/rtc-ds1374.c
+++ b/drivers/rtc/rtc-ds1374.c
@@ -41,6 +41,14 @@
 #define DS1374_REG_SR_AF	0x01 /* Alarm Flag */
 #define DS1374_REG_TCR		0x09 /* Trickle Charge */
 
+static struct i2c_device_id ds1374_id[] = {
+	{"rtc-ds1374", 0},
+	{"ds1374", 0},
+	{"dallas,ds1374", 0},
+	{},
+};
+MODULE_DEVICE_TABLE(i2c, ds1374_id);
+
 struct ds1374 {
 	struct i2c_client *client;
 	struct rtc_device *rtc;
@@ -355,7 +363,7 @@ static const struct rtc_class_ops ds1374_rtc_ops = {
 	.ioctl = ds1374_ioctl,
 };
 
-static int ds1374_probe(struct i2c_client *client)
+static int ds1374_probe(struct i2c_client *client, const struct i2c_device_id *id)
 {
 	struct ds1374 *ds1374;
 	int ret;
@@ -429,6 +437,7 @@ static struct i2c_driver ds1374_driver = {
 	},
 	.probe = ds1374_probe,
 	.remove = __devexit_p(ds1374_remove),
+	.id_table = ds1374_id,
 };
 
 static int __init ds1374_init(void)
diff --git a/drivers/rtc/rtc-rs5c372.c b/drivers/rtc/rtc-rs5c372.c
index 6b67b50..de0d458 100644
--- a/drivers/rtc/rtc-rs5c372.c
+++ b/drivers/rtc/rtc-rs5c372.c
@@ -62,13 +62,26 @@
 
 
 enum rtc_type {
-	rtc_undef = 0,
 	rtc_rs5c372a,
 	rtc_rs5c372b,
 	rtc_rv5c386,
 	rtc_rv5c387a,
 };
 
+static struct i2c_device_id rs5c372_id[] = {
+	{"rtc-rs5c372", rtc_rs5c372a},
+	{"rs5c372a", rtc_rs5c372a},
+	{"rs5c372b", rtc_rs5c372b},
+	{"rv5c386", rtc_rv5c386},
+	{"rv5c387a", rtc_rv5c387a},
+	{"ricoh,rs5c372a", rtc_rs5c372a},
+	{"ricoh,rs5c372b", rtc_rs5c372b},
+	{"ricoh,rv5c386", rtc_rv5c386},
+	{"ricoh,rv5c387a", rtc_rv5c387a},
+	{},
+};
+MODULE_DEVICE_TABLE(i2c, rs5c372_id);
+
 /* REVISIT:  this assumes that:
  *  - we're in the 21st century, so it's safe to ignore the century
  *    bit for rv5c38[67] (REG_MONTH bit 7);
@@ -494,7 +507,7 @@ static void rs5c_sysfs_unregister(struct device *dev)
 
 static struct i2c_driver rs5c372_driver;
 
-static int rs5c372_probe(struct i2c_client *client)
+static int rs5c372_probe(struct i2c_client *client, const struct i2c_device_id *id)
 {
 	int err = 0;
 	struct rs5c372 *rs5c372;
@@ -522,18 +535,7 @@ static int rs5c372_probe(struct i2c_client *client)
 	if (err < 0)
 		goto exit_kfree;
 
-	if (strcmp(client->name, "rs5c372a") == 0)
-		rs5c372->type = rtc_rs5c372a;
-	else if (strcmp(client->name, "rs5c372b") == 0)
-		rs5c372->type = rtc_rs5c372b;
-	else if (strcmp(client->name, "rv5c386") == 0)
-		rs5c372->type = rtc_rv5c386;
-	else if (strcmp(client->name, "rv5c387a") == 0)
-		rs5c372->type = rtc_rv5c387a;
-	else {
-		rs5c372->type = rtc_rs5c372b;
-		dev_warn(&client->dev, "assuming rs5c372b\n");
-	}
+	rs5c372->type = id->driver_data;
 
 	/* clock may be set for am/pm or 24 hr time */
 	switch (rs5c372->type) {
@@ -651,6 +653,7 @@ static struct i2c_driver rs5c372_driver = {
 	},
 	.probe		= rs5c372_probe,
 	.remove		= rs5c372_remove,
+	.id_table	= rs5c372_id,
 };
 
 static __init int rs5c372_init(void)

^ permalink raw reply related

* [PATCH 3/4] Convert PowerPC MPC i2c to of_platform_driver from platform_driver
From: Jon Smirl @ 2007-12-03 21:20 UTC (permalink / raw)
  To: i2c, linuxppc-dev
In-Reply-To: <20071203212032.23543.3453.stgit@terra.home>

Convert MPC i2c driver from being a platform_driver to an open firmware version. Error returns were improved. Routine names were changed from fsl_ to mpc_ to make them match the file name.
---

 arch/powerpc/sysdev/fsl_soc.c |   96 ---------------------
 drivers/i2c/busses/i2c-mpc.c  |  185 +++++++++++++++++++++++++++--------------
 2 files changed, 123 insertions(+), 158 deletions(-)


diff --git a/arch/powerpc/sysdev/fsl_soc.c b/arch/powerpc/sysdev/fsl_soc.c
index e4c766e..d6ef264 100644
--- a/arch/powerpc/sysdev/fsl_soc.c
+++ b/arch/powerpc/sysdev/fsl_soc.c
@@ -318,102 +318,6 @@ err:
 
 arch_initcall(gfar_of_init);
 
-#ifdef CONFIG_I2C_BOARDINFO
-#include <linux/i2c.h>
-
-static void __init of_register_i2c_devices(struct device_node *adap_node,
-					   int bus_num)
-{
-	struct device_node *node = NULL;
-	const char *compatible;
-
-	while ((node = of_get_next_child(adap_node, node))) {
-		struct i2c_board_info info = {};
-		const u32 *addr;
-		int len;
-
-		addr = of_get_property(node, "reg", &len);
-		if (!addr || len < sizeof(int) || *addr > (1 << 10) - 1) {
-			printk(KERN_WARNING "fsl_soc.c: invalid i2c device entry\n");
-			continue;
-		}
-
-		info.irq = irq_of_parse_and_map(node, 0);
-		if (info.irq == NO_IRQ)
-			info.irq = -1;
-
-		compatible = of_get_property(node, "compatible", &len);
-		if (!compatible) {
-			printk(KERN_WARNING "i2c-mpc.c: invalid entry, missing compatible attribute\n");
-			continue;
-		}
-		strncpy(info.driver_name, compatible, sizeof(info.driver_name));
-		
-		info.addr = *addr;
-
-		i2c_register_board_info(bus_num, &info, 1);
-	}
-}
-
-static int __init fsl_i2c_of_init(void)
-{
-	struct device_node *np;
-	unsigned int i;
-	struct platform_device *i2c_dev;
-	int ret;
-
-	for (np = NULL, i = 0;
-	     (np = of_find_compatible_node(np, "i2c", "fsl-i2c")) != NULL;
-	     i++) {
-		struct resource r[2];
-		struct fsl_i2c_platform_data i2c_data;
-		const unsigned char *flags = NULL;
-
-		memset(&r, 0, sizeof(r));
-		memset(&i2c_data, 0, sizeof(i2c_data));
-
-		ret = of_address_to_resource(np, 0, &r[0]);
-		if (ret)
-			goto err;
-
-		of_irq_to_resource(np, 0, &r[1]);
-
-		i2c_dev = platform_device_register_simple("fsl-i2c", i, r, 2);
-		if (IS_ERR(i2c_dev)) {
-			ret = PTR_ERR(i2c_dev);
-			goto err;
-		}
-
-		i2c_data.device_flags = 0;
-		flags = of_get_property(np, "dfsrr", NULL);
-		if (flags)
-			i2c_data.device_flags |= FSL_I2C_DEV_SEPARATE_DFSRR;
-
-		flags = of_get_property(np, "fsl5200-clocking", NULL);
-		if (flags)
-			i2c_data.device_flags |= FSL_I2C_DEV_CLOCK_5200;
-
-		ret =
-		    platform_device_add_data(i2c_dev, &i2c_data,
-					     sizeof(struct
-						    fsl_i2c_platform_data));
-		if (ret)
-			goto unreg;
-
-		of_register_i2c_devices(np, i);
-	}
-
-	return 0;
-
-unreg:
-	platform_device_unregister(i2c_dev);
-err:
-	return ret;
-}
-
-arch_initcall(fsl_i2c_of_init);
-#endif
-
 #ifdef CONFIG_PPC_83xx
 static int __init mpc83xx_wdt_init(void)
 {
diff --git a/drivers/i2c/busses/i2c-mpc.c b/drivers/i2c/busses/i2c-mpc.c
index d8de4ac..bb6284e 100644
--- a/drivers/i2c/busses/i2c-mpc.c
+++ b/drivers/i2c/busses/i2c-mpc.c
@@ -17,7 +17,7 @@
 #include <linux/module.h>
 #include <linux/sched.h>
 #include <linux/init.h>
-#include <linux/platform_device.h>
+#include <linux/of_platform.h>
 
 #include <asm/io.h>
 #include <linux/fsl_devices.h>
@@ -25,13 +25,13 @@
 #include <linux/interrupt.h>
 #include <linux/delay.h>
 
-#define MPC_I2C_ADDR  0x00
+#define DRV_NAME "mpc-i2c"
+
 #define MPC_I2C_FDR 	0x04
 #define MPC_I2C_CR	0x08
 #define MPC_I2C_SR	0x0c
 #define MPC_I2C_DR	0x10
 #define MPC_I2C_DFSRR 0x14
-#define MPC_I2C_REGION 0x20
 
 #define CCR_MEN  0x80
 #define CCR_MIEN 0x40
@@ -180,7 +180,7 @@ static void mpc_i2c_stop(struct mpc_i2c *i2c)
 static int mpc_write(struct mpc_i2c *i2c, int target,
 		     const u8 * data, int length, int restart)
 {
-	int i;
+	int i, result;
 	unsigned timeout = i2c->adap.timeout;
 	u32 flags = restart ? CCR_RSTA : 0;
 
@@ -192,15 +192,15 @@ static int mpc_write(struct mpc_i2c *i2c, int target,
 	/* Write target byte */
 	writeb((target << 1), i2c->base + MPC_I2C_DR);
 
-	if (i2c_wait(i2c, timeout, 1) < 0)
-		return -1;
+	if ((result = i2c_wait(i2c, timeout, 1)) < 0)
+		return result;
 
 	for (i = 0; i < length; i++) {
 		/* Write data byte */
 		writeb(data[i], i2c->base + MPC_I2C_DR);
 
-		if (i2c_wait(i2c, timeout, 1) < 0)
-			return -1;
+		if ((result = i2c_wait(i2c, timeout, 1)) < 0)
+			return result;
 	}
 
 	return 0;
@@ -210,7 +210,7 @@ static int mpc_read(struct mpc_i2c *i2c, int target,
 		    u8 * data, int length, int restart)
 {
 	unsigned timeout = i2c->adap.timeout;
-	int i;
+	int i, result;
 	u32 flags = restart ? CCR_RSTA : 0;
 
 	/* Start with MEN */
@@ -221,8 +221,8 @@ static int mpc_read(struct mpc_i2c *i2c, int target,
 	/* Write target address byte - this time with the read flag set */
 	writeb((target << 1) | 1, i2c->base + MPC_I2C_DR);
 
-	if (i2c_wait(i2c, timeout, 1) < 0)
-		return -1;
+	if ((result = i2c_wait(i2c, timeout, 1)) < 0)
+		return result;
 
 	if (length) {
 		if (length == 1)
@@ -234,8 +234,8 @@ static int mpc_read(struct mpc_i2c *i2c, int target,
 	}
 
 	for (i = 0; i < length; i++) {
-		if (i2c_wait(i2c, timeout, 0) < 0)
-			return -1;
+		if ((result = i2c_wait(i2c, timeout, 0)) < 0)
+			return result;
 
 		/* Generate txack on next to last byte */
 		if (i == length - 2)
@@ -312,105 +312,166 @@ static struct i2c_adapter mpc_ops = {
 	.retries = 1
 };
 
-static int fsl_i2c_probe(struct platform_device *pdev)
+struct i2c_driver_device {
+	char	*of_device;
+	char	*i2c_driver;
+	char	*i2c_type;
+};
+
+static void of_register_i2c_devices(struct i2c_adapter *adap, struct device_node *adap_node)
+{
+	struct device_node *node = NULL;
+
+	while ((node = of_get_next_child(adap_node, node))) {
+		struct i2c_board_info info;
+		const u32 *addr;
+		const char *compatible;
+		int len;
+
+		addr = of_get_property(node, "reg", &len);
+		if (!addr || len < sizeof(int) || *addr > (1 << 10) - 1) {
+			printk(KERN_ERR "i2c-mpc.c: invalid entry, missing reg attribute\n");
+			continue;
+		}
+
+		info.irq = irq_of_parse_and_map(node, 0);
+		if (info.irq == NO_IRQ)
+			info.irq = -1;
+
+		compatible = of_get_property(node, "compatible", &len);
+		if (!compatible) {
+			printk(KERN_ERR "i2c-mpc.c: invalid entry, missing compatible attribute\n");
+			continue;
+		}
+		strncpy(info.driver_name, compatible, sizeof(info.driver_name));
+		info.type[0] = '\0';
+
+		info.platform_data = NULL;
+		info.addr = *addr;
+		
+		if (!i2c_new_device(adap, &info)) {
+			printk(KERN_ERR "i2c-mpc.c: Failed to load driver for %s\n", info.driver_name);
+			continue;
+		}
+	}
+}
+
+static int mpc_i2c_probe(struct of_device *op, const struct of_device_id *match)
 {
 	int result = 0;
 	struct mpc_i2c *i2c;
-	struct fsl_i2c_platform_data *pdata;
-	struct resource *r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-
-	pdata = (struct fsl_i2c_platform_data *) pdev->dev.platform_data;
 
-	if (!(i2c = kzalloc(sizeof(*i2c), GFP_KERNEL))) {
+	if (!(i2c = kzalloc(sizeof(*i2c), GFP_KERNEL)))
 		return -ENOMEM;
-	}
 
-	i2c->irq = platform_get_irq(pdev, 0);
-	if (i2c->irq < 0) {
-		result = -ENXIO;
-		goto fail_get_irq;
-	}
-	i2c->flags = pdata->device_flags;
-	init_waitqueue_head(&i2c->queue);
+	if (of_get_property(op->node, "dfsrr", NULL))
+		i2c->flags |= FSL_I2C_DEV_SEPARATE_DFSRR;
 
-	i2c->base = ioremap((phys_addr_t)r->start, MPC_I2C_REGION);
+	if (of_device_is_compatible(op->node, "mpc5200-i2c"))
+		i2c->flags |= FSL_I2C_DEV_CLOCK_5200;
 
+	init_waitqueue_head(&i2c->queue);
+
+	i2c->base = of_iomap(op->node, 0);
 	if (!i2c->base) {
 		printk(KERN_ERR "i2c-mpc - failed to map controller\n");
 		result = -ENOMEM;
 		goto fail_map;
 	}
 
-	if (i2c->irq != 0)
-		if ((result = request_irq(i2c->irq, mpc_i2c_isr,
-					  IRQF_SHARED, "i2c-mpc", i2c)) < 0) {
-			printk(KERN_ERR
-			       "i2c-mpc - failed to attach interrupt\n");
-			goto fail_irq;
-		}
+	i2c->irq = irq_of_parse_and_map(op->node, 0);
+	if (i2c->irq == NO_IRQ) {
+		result = -ENXIO;
+		goto fail_irq;
+	}
+	
+	if ((result = request_irq(i2c->irq, mpc_i2c_isr,
+				  	IRQF_SHARED, "i2c-mpc", i2c)) < 0) {
+		printk(KERN_ERR "i2c-mpc - failed to attach interrupt\n");
+		goto fail_request;
+	}
 
 	mpc_i2c_setclock(i2c);
-	platform_set_drvdata(pdev, i2c);
+	
+	dev_set_drvdata(&op->dev, i2c);
 
 	i2c->adap = mpc_ops;
-	i2c->adap.nr = pdev->id;
 	i2c_set_adapdata(&i2c->adap, i2c);
-	i2c->adap.dev.parent = &pdev->dev;
-	if ((result = i2c_add_numbered_adapter(&i2c->adap)) < 0) {
+	i2c->adap.dev.parent = &op->dev;
+	if ((result = i2c_add_adapter(&i2c->adap)) < 0) {
 		printk(KERN_ERR "i2c-mpc - failed to add adapter\n");
 		goto fail_add;
 	}
+	
+	of_register_i2c_devices(&i2c->adap, op->node);
 
 	return result;
 
-      fail_add:
-	if (i2c->irq != 0)
-		free_irq(i2c->irq, i2c);
-      fail_irq:
+fail_add:
+	free_irq(i2c->irq, i2c);
+fail_request:
+	irq_dispose_mapping(i2c->irq);
+fail_irq:
 	iounmap(i2c->base);
-      fail_map:
-      fail_get_irq:
+fail_map:
 	kfree(i2c);
 	return result;
 };
 
-static int fsl_i2c_remove(struct platform_device *pdev)
+static int mpc_i2c_remove(struct of_device *op)
 {
-	struct mpc_i2c *i2c = platform_get_drvdata(pdev);
+	struct mpc_i2c *i2c = dev_get_drvdata(&op->dev);
 
 	i2c_del_adapter(&i2c->adap);
-	platform_set_drvdata(pdev, NULL);
+	dev_set_drvdata(&op->dev, NULL);
 
-	if (i2c->irq != 0)
+	if (i2c->irq != NO_IRQ)
 		free_irq(i2c->irq, i2c);
-
+	
+	irq_dispose_mapping(i2c->irq);
 	iounmap(i2c->base);
 	kfree(i2c);
 	return 0;
 };
 
+static struct of_device_id mpc_i2c_of_match[] = {
+	{
+		.compatible	= "fsl-i2c",
+	},
+};
+MODULE_DEVICE_TABLE(of, mpc_i2c_of_match);
+
+
 /* Structure for a device driver */
-static struct platform_driver fsl_i2c_driver = {
-	.probe = fsl_i2c_probe,
-	.remove = fsl_i2c_remove,
-	.driver	= {
-		.owner = THIS_MODULE,
-		.name = "fsl-i2c",
+static struct of_platform_driver mpc_i2c_driver = {
+	.match_table	= mpc_i2c_of_match,
+	.probe		= mpc_i2c_probe,
+	.remove		= __devexit_p(mpc_i2c_remove),
+	.driver		= {
+		.owner	= THIS_MODULE,
+		.name	= DRV_NAME,
 	},
 };
 
-static int __init fsl_i2c_init(void)
+static int __init mpc_i2c_init(void)
 {
-	return platform_driver_register(&fsl_i2c_driver);
+	int rv;
+
+	rv = of_register_platform_driver(&mpc_i2c_driver);
+	if (rv) {
+		printk(KERN_ERR DRV_NAME " of_register_platform_driver failed (%i)\n", rv);
+		return rv;
+	}
+	return 0;
 }
 
-static void __exit fsl_i2c_exit(void)
+static void __exit mpc_i2c_exit(void)
 {
-	platform_driver_unregister(&fsl_i2c_driver);
+	of_unregister_platform_driver(&mpc_i2c_driver);
 }
 
-module_init(fsl_i2c_init);
-module_exit(fsl_i2c_exit);
+module_init(mpc_i2c_init);
+module_exit(mpc_i2c_exit);
 
 MODULE_AUTHOR("Adrian Cox <adrian@humboldt.co.uk>");
 MODULE_DESCRIPTION

^ permalink raw reply related

* Re: [PATCH 2/2] powerpc: make 64K huge pages more reliable
From: Chris Snook @ 2007-12-03 21:51 UTC (permalink / raw)
  To: kniht, linuxppc-dev, Linux Memory Management List
In-Reply-To: <20071203020648.GF26919@localhost.localdomain>

David Gibson wrote:
> On Tue, Nov 27, 2007 at 11:03:16PM -0600, Jon Tollefson wrote:
>> This patch adds reliability to the 64K huge page option by making use of 
>> the PMD for 64K huge pages when base pages are 4k.  So instead of a 12 
>> bit pte it would be 7 bit pmd and a 5 bit pte. The pgd and pud offsets 
>> would continue as 9 bits and 7 bits respectively.  This will allow the 
>> pgtable to fit in one base page.  This patch would have to be applied 
>> after part 1.
> 
> Hrm.. shouldn't we just ban 64K hugepages on a 64K base page size
> setup?  There's not a whole lot of point to it, after all...
> 

Actually, it sounds to me like an ideal way to benchmark the efficiency of the 
hugepage implementation and VM effects, without the TLB performance obscuring 
the results.

I agree that it's not something people will want to do very often, but the same 
can be said about quite a lot of strange things that we allow just because 
there's no fundamental reason why they cannot be.

	-- Chris

^ permalink raw reply

* [PATCH 1/2] qe: add function qe_clock_source()
From: Timur Tabi @ 2007-12-03 21:17 UTC (permalink / raw)
  To: netdev, linuxppc-dev, galak; +Cc: Timur Tabi
In-Reply-To: <11967166791607-git-send-email-timur@freescale.com>

Add function qe_clock_source() which takes a string containing the name of a
QE clock source (as is typically found in device trees) and returns the
matching enum qe_clock value.

Update booting-without-of.txt to indicate that the UCC properties rx-clock
and tx-clock are deprecated and replaced with rx-clock-name and tx-clock-name,
which use strings instead of numbers to indicate QE clock sources.

Signed-off-by: Timur Tabi <timur@freescale.com>
---

This patch applies to Kumar's for-2.6.25 branch.  You may need to apply
my other pending patch, "qe: add ability to upload QE firmware", first.

 Documentation/powerpc/booting-without-of.txt |   13 ++++++++++
 arch/powerpc/sysdev/qe_lib/qe.c              |   32 ++++++++++++++++++++++++++
 include/asm-powerpc/qe.h                     |    1 +
 3 files changed, 46 insertions(+), 0 deletions(-)

diff --git a/Documentation/powerpc/booting-without-of.txt b/Documentation/powerpc/booting-without-of.txt
index e9a3cb1..c4342d3 100644
--- a/Documentation/powerpc/booting-without-of.txt
+++ b/Documentation/powerpc/booting-without-of.txt
@@ -1626,6 +1626,19 @@ platforms are moved over to use the flattened-device-tree model.
    - interrupt-parent : the phandle for the interrupt controller that
      services interrupts for this device.
    - pio-handle : The phandle for the Parallel I/O port configuration.
+   - rx-clock-name: the UCC receive clock source
+     "none": clock source is disabled
+     "brg1" through "brg16": clock source is BRG1-BRG16, respectively
+     "clk1" through "clk24": clock source is CLK1-CLK24, respectively
+   - tx-clock-name: the UCC transmit clock source
+     "none": clock source is disabled
+     "brg1" through "brg16": clock source is BRG1-BRG16, respectively
+     "clk1" through "clk24": clock source is CLK1-CLK24, respectively
+   The following two properties are deprecated.  rx-clock has been replaced
+   with rx-clock-name, and tx-clock has been replaced with tx-clock-name.
+   Drivers that currently use the deprecated properties should continue to
+   do so, in order to support older device trees, but they should be updated
+   to check for the new properties first.
    - rx-clock : represents the UCC receive clock source.
      0x00 : clock source is disabled;
      0x1~0x10 : clock source is BRG1~BRG16 respectively;
diff --git a/arch/powerpc/sysdev/qe_lib/qe.c b/arch/powerpc/sysdev/qe_lib/qe.c
index 865277b..5df8530 100644
--- a/arch/powerpc/sysdev/qe_lib/qe.c
+++ b/arch/powerpc/sysdev/qe_lib/qe.c
@@ -204,6 +204,38 @@ int qe_setbrg(enum qe_clock brg, unsigned int rate, unsigned int multiplier)
 }
 EXPORT_SYMBOL(qe_setbrg);
 
+/* Convert a string to a QE clock source enum
+ *
+ * This function takes a string, typically from a property in the device
+ * tree, and returns the corresponding "enum qe_clock" value.
+*/
+enum qe_clock qe_clock_source(const char *source)
+{
+	unsigned int i;
+
+	if (strcasecmp(source, "none") == 0)
+		return QE_CLK_NONE;
+
+	if (strncasecmp(source, "brg", 3) == 0) {
+		i = simple_strtoul(source + 3, NULL, 10);
+		if ((i >= 1) && (i <= 16))
+			return (QE_BRG1 - 1) + i;
+		else
+			return QE_CLK_DUMMY;
+	}
+
+	if (strncasecmp(source, "clk", 3) == 0) {
+		i = simple_strtoul(source + 3, NULL, 10);
+		if ((i >= 1) && (i <= 24))
+			return (QE_CLK1 - 1) + i;
+		else
+			return QE_CLK_DUMMY;
+	}
+
+	return QE_CLK_DUMMY;
+}
+EXPORT_SYMBOL(qe_clock_source);
+
 /* Initialize SNUMs (thread serial numbers) according to
  * QE Module Control chapter, SNUM table
  */
diff --git a/include/asm-powerpc/qe.h b/include/asm-powerpc/qe.h
index 35c7b8d..430dc77 100644
--- a/include/asm-powerpc/qe.h
+++ b/include/asm-powerpc/qe.h
@@ -84,6 +84,7 @@ extern int par_io_data_set(u8 port, u8 pin, u8 val);
 
 /* QE internal API */
 int qe_issue_cmd(u32 cmd, u32 device, u8 mcn_protocol, u32 cmd_input);
+enum qe_clock qe_clock_source(const char *source);
 int qe_setbrg(enum qe_clock brg, unsigned int rate, unsigned int multiplier);
 int qe_get_snum(void);
 void qe_put_snum(u8 snum);
-- 
1.5.2.4

^ permalink raw reply related

* Re: OT: Re: solved: Re: [rtc-linux] Re: DS1337 RTC on I2C broken.
From: Scott Wood @ 2007-12-03 20:46 UTC (permalink / raw)
  To: Clemens Koller; +Cc: Alessandro Zummo, rtc-linux, linuxppc-embedded
In-Reply-To: <47545A81.90804@anagramm.de>

On Mon, Dec 03, 2007 at 08:35:29PM +0100, Clemens Koller wrote:
> Hello, Scott!
>
> Scott Wood schrieb:
> >> Here, the next idea which comes to my mind:
> >> Maybe we should think about a kernel-config -> dts compiler for
> >> the future where the enabled drivers generate their default dts
> >> entries automagically?
> >
> > Sorry, there's just not enough information in .config for that.
>
> If there is really the need to put more information (which I don't
> see in the case of the RTCs)

It's not uncommon for RTCs to have an alarm IRQ.  It's not uncommon for
multiple not-quite-compatible RTC chips to be driven by the same driver,
which needs to know what it's dealing with.

> to .config, it might be an idea to extend the current structure for this
> use instead of duplicating and maintaining a second repository.

.config is not nearly as flexible in describing hardware as the device tree
is.  Sorry, but even apart from the multiplatform issue, it's the wrong tool
for the job.

> And regarding the DS1337 (or the PCF8563 and similar RTCs):
> It's address (0x68) is immutable fixed by the manufacturer
> of that device. So, why do we include it in the DT, when we
> already told the kernel what driver we want to use?

You did not tell the kernel what driver you wanted to use; you told the
driver which address the chip will be on.  There are other chips that also
use address 0x68, such as DS1374, which is completely incompatible with
DS1337 and uses a different driver.

> Even if I have an eeprom which can have varying addresses,
> I can simply tell the driver/the kernel .config what address
> it should use...

That's precisely what we do, via the device tree.  It is not practical to do
it with kconfig.  Again putting aside multiplatform kernels for the moment,
what would you do in kconfig to describe the addresses of multiple chips
without having a fixed-size list of possibilities?  How would you tell the
kernel, using kconfig, that there's a "foo" chip at address 0x68 on i2c bus
0, and a "bar" chip at address 0x68 on i2c bus 1?

-Scott

^ permalink raw reply

* Re: [PATCH 2/2] powerpc: make 64K huge pages more reliable
From: Jon Tollefson @ 2007-12-03 21:33 UTC (permalink / raw)
  To: David Gibson; +Cc: linuxppc-dev, Linux Memory Management List
In-Reply-To: <20071203020648.GF26919@localhost.localdomain>

David Gibson wrote:
> On Tue, Nov 27, 2007 at 11:03:16PM -0600, Jon Tollefson wrote:
>   
>> This patch adds reliability to the 64K huge page option by making use of 
>> the PMD for 64K huge pages when base pages are 4k.  So instead of a 12 
>> bit pte it would be 7 bit pmd and a 5 bit pte. The pgd and pud offsets 
>> would continue as 9 bits and 7 bits respectively.  This will allow the 
>> pgtable to fit in one base page.  This patch would have to be applied 
>> after part 1.
>>     
>
> Hrm.. shouldn't we just ban 64K hugepages on a 64K base page size
> setup?  There's not a whole lot of point to it, after all...
>   

Banning the base and huge page size from being the same size feels like
an artificial barrier.  It is probably not the most massively useful
combination, but it shouldn't hurt performance. 

Jon

^ permalink raw reply

* [PATCH 0/2] QE clock source improvements
From: Timur Tabi @ 2007-12-03 21:17 UTC (permalink / raw)
  To: netdev, linuxppc-dev, galak


This patch set adds a new property to make specifying QE clock sources
easier, adds a function to help parse the property, and updates the ucc_geth
driver to take advantage of all this.

Patch #1 is an arch/powerpc patch meant for Kumar's for-2.6.25 branch.
Patch #2 is a netdev patch, so it's either for Jeff G and/or Kumar.

^ permalink raw reply

* [PATCH 2/2] ucc_geth: use rx-clock-name and tx-clock-name device tree properties
From: Timur Tabi @ 2007-12-03 21:17 UTC (permalink / raw)
  To: netdev, linuxppc-dev, galak; +Cc: Timur Tabi
In-Reply-To: <1196716680381-git-send-email-timur@freescale.com>

Updates the ucc_geth device driver to check the new rx-clock-name and
tx-clock-name properties first.  If present, it uses the new function
qe_clock_source() to obtain the clock source.  Otherwise, it checks the
deprecated rx-clock and tx-clock properties.

Update the device trees for 832x, 836x, and 8568 to contain the new property
names only.

Signed-off-by: Timur Tabi <timur@freescale.com>
---

This patch applies to Kumar's for-2.6.25 branch.  ucc_geth will compile but not
run if my other patch, "qe: add function qe_clock_source" has not also been
applied.

 arch/powerpc/boot/dts/mpc832x_mds.dts |    8 ++--
 arch/powerpc/boot/dts/mpc832x_rdb.dts |    8 ++--
 arch/powerpc/boot/dts/mpc836x_mds.dts |    8 ++--
 arch/powerpc/boot/dts/mpc8568mds.dts  |    8 ++--
 drivers/net/ucc_geth.c                |   55 ++++++++++++++++++++++++++++++--
 5 files changed, 67 insertions(+), 20 deletions(-)

diff --git a/arch/powerpc/boot/dts/mpc832x_mds.dts b/arch/powerpc/boot/dts/mpc832x_mds.dts
index c64f303..fe54489 100644
--- a/arch/powerpc/boot/dts/mpc832x_mds.dts
+++ b/arch/powerpc/boot/dts/mpc832x_mds.dts
@@ -223,8 +223,8 @@
 			 */
 			mac-address = [ 00 00 00 00 00 00 ];
 			local-mac-address = [ 00 00 00 00 00 00 ];
-			rx-clock = <19>;
-			tx-clock = <1a>;
+			rx-clock-name = "clk9";
+			tx-clock-name = "clk10";
 			phy-handle = < &phy3 >;
 			pio-handle = < &pio3 >;
 		};
@@ -244,8 +244,8 @@
 			 */
 			mac-address = [ 00 00 00 00 00 00 ];
 			local-mac-address = [ 00 00 00 00 00 00 ];
-			rx-clock = <17>;
-			tx-clock = <18>;
+			rx-clock-name = "clk7";
+			tx-clock-name = "clk8";
 			phy-handle = < &phy4 >;
 			pio-handle = < &pio4 >;
 		};
diff --git a/arch/powerpc/boot/dts/mpc832x_rdb.dts b/arch/powerpc/boot/dts/mpc832x_rdb.dts
index 388c8a7..e68a08b 100644
--- a/arch/powerpc/boot/dts/mpc832x_rdb.dts
+++ b/arch/powerpc/boot/dts/mpc832x_rdb.dts
@@ -202,8 +202,8 @@
 			 */
 			mac-address = [ 00 00 00 00 00 00 ];
 			local-mac-address = [ 00 00 00 00 00 00 ];
-			rx-clock = <20>;
-			tx-clock = <13>;
+			rx-clock-name = "clk16";
+			tx-clock-name = "clk3";
 			phy-handle = <&phy00>;
 			pio-handle = <&ucc2pio>;
 		};
@@ -223,8 +223,8 @@
 			 */
 			mac-address = [ 00 00 00 00 00 00 ];
 			local-mac-address = [ 00 00 00 00 00 00 ];
-			rx-clock = <19>;
-			tx-clock = <1a>;
+			rx-clock-name = "clk9";
+			tx-clock-name = "clk10";
 			phy-handle = <&phy04>;
 			pio-handle = <&ucc3pio>;
 		};
diff --git a/arch/powerpc/boot/dts/mpc836x_mds.dts b/arch/powerpc/boot/dts/mpc836x_mds.dts
index 0b2d2b5..bfd48d0 100644
--- a/arch/powerpc/boot/dts/mpc836x_mds.dts
+++ b/arch/powerpc/boot/dts/mpc836x_mds.dts
@@ -254,8 +254,8 @@
 			 */
 			mac-address = [ 00 00 00 00 00 00 ];
 			local-mac-address = [ 00 00 00 00 00 00 ];
-			rx-clock = <0>;
-			tx-clock = <19>;
+			rx-clock-name = "none";
+			tx-clock-name = "clk9";
 			phy-handle = < &phy0 >;
 			phy-connection-type = "rgmii-id";
 			pio-handle = < &pio1 >;
@@ -276,8 +276,8 @@
 			 */
 			mac-address = [ 00 00 00 00 00 00 ];
 			local-mac-address = [ 00 00 00 00 00 00 ];
-			rx-clock = <0>;
-			tx-clock = <14>;
+			rx-clock-name = "none";
+			tx-clock-name = "clk4";
 			phy-handle = < &phy1 >;
 			phy-connection-type = "rgmii-id";
 			pio-handle = < &pio2 >;
diff --git a/arch/powerpc/boot/dts/mpc8568mds.dts b/arch/powerpc/boot/dts/mpc8568mds.dts
index 5439437..cf45aab 100644
--- a/arch/powerpc/boot/dts/mpc8568mds.dts
+++ b/arch/powerpc/boot/dts/mpc8568mds.dts
@@ -333,8 +333,8 @@
 			 */
 			mac-address = [ 00 00 00 00 00 00 ];
 			local-mac-address = [ 00 00 00 00 00 00 ];
-			rx-clock = <0>;
-			tx-clock = <20>;
+			rx-clock-name = "none";
+			tx-clock-name = "clk16";
 			pio-handle = <&pio1>;
 			phy-handle = <&phy0>;
 			phy-connection-type = "rgmii-id";
@@ -355,8 +355,8 @@
 			 */
 			mac-address = [ 00 00 00 00 00 00 ];
 			local-mac-address = [ 00 00 00 00 00 00 ];
-			rx-clock = <0>;
-			tx-clock = <20>;
+			rx-clock-name = "none";
+			tx-clock-name = "clk16";
 			pio-handle = <&pio2>;
 			phy-handle = <&phy1>;
 			phy-connection-type = "rgmii-id";
diff --git a/drivers/net/ucc_geth.c b/drivers/net/ucc_geth.c
index a3ff270..a93342e 100644
--- a/drivers/net/ucc_geth.c
+++ b/drivers/net/ucc_geth.c
@@ -3814,6 +3814,7 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma
 	int err, ucc_num, max_speed = 0;
 	const phandle *ph;
 	const unsigned int *prop;
+	const char *sprop;
 	const void *mac_addr;
 	phy_interface_t phy_interface;
 	static const int enet_to_speed[] = {
@@ -3846,10 +3847,56 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma
 
 	ug_info->uf_info.ucc_num = ucc_num;
 
-	prop = of_get_property(np, "rx-clock", NULL);
-	ug_info->uf_info.rx_clock = *prop;
-	prop = of_get_property(np, "tx-clock", NULL);
-	ug_info->uf_info.tx_clock = *prop;
+	sprop = of_get_property(np, "rx-clock-name", NULL);
+	if (sprop) {
+		ug_info->uf_info.rx_clock = qe_clock_source(sprop);
+		if ((ug_info->uf_info.rx_clock < QE_CLK_NONE) ||
+		    (ug_info->uf_info.rx_clock > QE_CLK24)) {
+			printk(KERN_ERR
+				"ucc_geth: invalid rx-clock-name property\n");
+			return -EINVAL;
+		}
+	} else {
+		prop = of_get_property(np, "rx-clock", NULL);
+		if (!prop) {
+			/* If both rx-clock-name and rx-clock are missing,
+			   we want to tell people to use rx-clock-name. */
+			printk(KERN_ERR
+				"ucc_geth: missing rx-clock-name property\n");
+			return -EINVAL;
+		}
+		if ((*prop < QE_CLK_NONE) || (*prop > QE_CLK24)) {
+			printk(KERN_ERR
+				"ucc_geth: invalid rx-clock propperty\n");
+			return -EINVAL;
+		}
+		ug_info->uf_info.rx_clock = *prop;
+	}
+
+	sprop = of_get_property(np, "tx-clock-name", NULL);
+	if (sprop) {
+		ug_info->uf_info.tx_clock = qe_clock_source(sprop);
+		if ((ug_info->uf_info.tx_clock < QE_CLK_NONE) ||
+		    (ug_info->uf_info.tx_clock > QE_CLK24)) {
+			printk(KERN_ERR
+				"ucc_geth: invalid tx-clock-name property\n");
+			return -EINVAL;
+		}
+	} else {
+		prop = of_get_property(np, "rx-clock", NULL);
+		if (!prop) {
+			printk(KERN_ERR
+				"ucc_geth: mising tx-clock-name property\n");
+			return -EINVAL;
+		}
+		if ((*prop < QE_CLK_NONE) || (*prop > QE_CLK24)) {
+			printk(KERN_ERR
+				"ucc_geth: invalid tx-clock property\n");
+			return -EINVAL;
+		}
+		ug_info->uf_info.tx_clock = *prop;
+	}
+
 	err = of_address_to_resource(np, 0, &res);
 	if (err)
 		return -EINVAL;
-- 
1.5.2.4

^ permalink raw reply related

* Re: [BUG] 2.6.24-rc3-git2 softlockup detected
From: Andrew Morton @ 2007-12-03 21:11 UTC (permalink / raw)
  To: Kamalesh Babulal
  Cc: rjw, linux-scsi, willy, linux-kernel, kyle, linuxppc-dev, balbir
In-Reply-To: <474FBB86.5000004@linux.vnet.ibm.com>

On Fri, 30 Nov 2007 12:58:06 +0530
Kamalesh Babulal <kamalesh@linux.vnet.ibm.com> wrote:

> Andrew Morton wrote:
> > On Thu, 29 Nov 2007 23:00:47 -0800 Andrew Morton <akpm@linux-foundation.org> wrote:
> > 
> >> On Fri, 30 Nov 2007 01:39:29 -0500 Kyle McMartin <kyle@mcmartin.ca> wrote:
> >>
> >>> On Thu, Nov 29, 2007 at 12:35:33AM -0800, Andrew Morton wrote:
> >>>> ten million is close enough to infinity for me to assume that we broke the
> >>>> driver and that's never going to terminate.
> >>>>
> >>> how about this? doesn't break things on my pa8800:
> >>>
> >>> diff --git a/drivers/scsi/sym53c8xx_2/sym_hipd.c b/drivers/scsi/sym53c8xx_2/sym_hipd.c
> >>> index 463f119..ef01cb1 100644
> >>> --- a/drivers/scsi/sym53c8xx_2/sym_hipd.c
> >>> +++ b/drivers/scsi/sym53c8xx_2/sym_hipd.c
> >>> @@ -1037,10 +1037,13 @@ restart_test:
> >>>  	/*
> >>>  	 *  Wait 'til done (with timeout)
> >>>  	 */
> >>> -	for (i=0; i<SYM_SNOOP_TIMEOUT; i++)
> >>> +	do {	
> >>>  		if (INB(np, nc_istat) & (INTF|SIP|DIP))
> >>>  			break;
> >>> -	if (i>=SYM_SNOOP_TIMEOUT) {
> >>> +		msleep(10);
> >>> +	} while (i++ < SYM_SNOOP_TIMEOUT);
> >>> +
> >>> +	if (i >= SYM_SNOOP_TIMEOUT) {
> >>>  		printf ("CACHE TEST FAILED: timeout.\n");
> >>>  		return (0x20);
> >>>  	}
> >>> diff --git a/drivers/scsi/sym53c8xx_2/sym_hipd.h b/drivers/scsi/sym53c8xx_2/sym_hipd.h
> >>> index ad07880..85c483b 100644
> >>> --- a/drivers/scsi/sym53c8xx_2/sym_hipd.h
> >>> +++ b/drivers/scsi/sym53c8xx_2/sym_hipd.h
> >>> @@ -339,7 +339,7 @@
> >>>  /*
> >>>   *  Misc.
> >>>   */
> >>> -#define SYM_SNOOP_TIMEOUT (10000000)
> >>> +#define SYM_SNOOP_TIMEOUT (1000)
> >>>  #define BUS_8_BIT	0
> >>>  #define BUS_16_BIT	1
> >>>  
> >> That might be the fix, but do we know what we're actually fixing?  afaik
> >> 2.6.24-rc3 doesn't get this timeout, 2.6.24-rc3-mm2 does get it and we
> >> don't know why?
> >>
> > 
> > <looks at Subject:>
> > 
> > <Checks that Rafael was cc'ed>
> > 
> > So 2.6.24-rc3 was OK and 2.6.24-rc3-git2 is not?
> 
> Yes, the 2.6.24-rc3 was Ok and this is seen from 2.6.24-rc3-git2/3/4.
> 

There are effectively no drivers/scsi/ changes after 2.6.24-rc3 and we
don't (I believe) have a clue what caused this regression.

Can you please do a bisection search on this?

Thanks.

^ permalink raw reply

* Re: [PATCH] Generic RTC class support for ppc_md.[gs]et_rtc_time
From: David Woodhouse @ 2007-12-03 21:06 UTC (permalink / raw)
  To: benh; +Cc: linuxppc-dev
In-Reply-To: <1196714722.13230.224.camel@pasglop>

On Tue, 2007-12-04 at 07:45 +1100, Benjamin Herrenschmidt wrote:
> On Mon, 2007-12-03 at 17:04 +0000, David Woodhouse wrote:
> > It would be good to migrate the platform code to register RTC devices
> > directly, but for now this will make them functional enough for most
> > purposes...
> 
> Wouldn't it be best to do the other way around at some stage ?

Yes, definitely. We can migrate them one at a time to the RTC class.

> We need to solve the problem of ppc_md. stuff being called by the core
> in atomic contexts first though.

Where from?

-- 
dwmw2

^ permalink raw reply

* [PATCH] Make QSpan PCI work
From: John Tyner @ 2007-12-03 21:05 UTC (permalink / raw)
  To: linuxppc-dev

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

The following patch makes the QSpan PCI code compile and work on my 
hardware. The patch is against 2.4, but I'm hoping it will still be viewed 
as useful since the code currently does not even compile (2.6 is the 
same). I had to make a change to move the PCI setup later in the 
m8xx_setup code as well because the kernel would crash during the 
pcibios_alloc_controller because the bootmem stuff had not come up yet.

Please CC me on any responses since I'm not subscribed.

Thanks,
John

[-- Attachment #2: qspan.patch --]
[-- Type: text/plain, Size: 24255 bytes --]

diff -ruNa linux-2.4.35.4.orig/arch/ppc/kernel/m8xx_setup.c linux-2.4.35.4/arch/ppc/kernel/m8xx_setup.c
--- linux-2.4.35.4.orig/arch/ppc/kernel/m8xx_setup.c	2007-11-17 09:23:15.000000000 -0800
+++ linux-2.4.35.4/arch/ppc/kernel/m8xx_setup.c	2007-11-29 14:38:41.000000000 -0800
@@ -65,6 +65,10 @@
 {
 	int	cpm_page;
 
+#ifdef CONFIG_PCI
+	m8xx_setup_pci_ptrs();
+#endif
+
 	cpm_page = (int) alloc_bootmem_pages(PAGE_SIZE);
 
 	/* Reset the Communication Processor Module.
@@ -364,10 +368,6 @@
 	if ( r3 )
 		memcpy( (void *)__res,(void *)(r3+KERNELBASE), sizeof(bd_t) );
 
-#ifdef CONFIG_PCI
-	m8xx_setup_pci_ptrs();
-#endif
-
 #ifdef CONFIG_BLK_DEV_INITRD
 	/* take care of initrd if we have one */
 	if ( r4 )
diff -ruNa linux-2.4.35.4.orig/arch/ppc/kernel/qspan_pci.c linux-2.4.35.4/arch/ppc/kernel/qspan_pci.c
--- linux-2.4.35.4.orig/arch/ppc/kernel/qspan_pci.c	2007-11-17 09:23:15.000000000 -0800
+++ linux-2.4.35.4/arch/ppc/kernel/qspan_pci.c	2007-12-03 11:22:44.000000000 -0800
@@ -28,6 +28,7 @@
 #include <asm/machdep.h>
 #include <asm/pci-bridge.h>
 
+#include "qspan_pci.h"
 
 /*
  * This blows......
@@ -83,7 +84,7 @@
 		"	.align 2\n"			\
 		"	.long 1b,3b\n"			\
 		".text"					\
-		: "=r"(x) : "r"(addr) : " %0")
+		: "+r"(x) : "r"(addr) )
 
 #define QS_CONFIG_ADDR	((volatile uint *)(PCI_CSR_ADDR + 0x500))
 #define QS_CONFIG_DATA	((volatile uint *)(PCI_CSR_ADDR + 0x504))
@@ -94,8 +95,8 @@
 #define mk_config_type1(bus, dev, offset) \
 	mk_config_addr(bus, dev, offset) | 1;
 
-int qspan_pcibios_read_config_byte(unsigned char bus, unsigned char dev_fn,
-				  unsigned char offset, unsigned char *val)
+static int qspan_pcibios_read_config_byte(struct pci_dev * const dev,
+                                          int offset, u8 * const val)
 {
 	uint	temp;
 	u_char	*cp;
@@ -103,7 +104,7 @@
 	unsigned long flags;
 #endif
 
-	if ((bus > 7) || (dev_fn > 127)) {
+	if ((dev->bus->number > 7) || (dev->devfn > 127)) {
 		*val = 0xff;
 		return PCIBIOS_DEVICE_NOT_FOUND;
 	}
@@ -115,10 +116,10 @@
 	eieio();
 #endif
 
-	if (bus == 0)
-		*QS_CONFIG_ADDR = mk_config_addr(bus, dev_fn, offset);
+	if (dev->bus->number == 0)
+		*QS_CONFIG_ADDR = mk_config_addr(dev->bus->number, dev->devfn, offset);
 	else
-		*QS_CONFIG_ADDR = mk_config_type1(bus, dev_fn, offset);
+		*QS_CONFIG_ADDR = mk_config_type1(dev->bus->number, dev->devfn, offset);
 	__get_qspan_pci_config(temp, QS_CONFIG_DATA, "lwz");
 
 #ifdef CONFIG_RPXCLASSIC
@@ -133,8 +134,8 @@
 	return PCIBIOS_SUCCESSFUL;
 }
 
-int qspan_pcibios_read_config_word(unsigned char bus, unsigned char dev_fn,
-				  unsigned char offset, unsigned short *val)
+static int qspan_pcibios_read_config_word(struct pci_dev * const dev,
+                                          int offset, u16 * const val)
 {
 	uint	temp;
 	ushort	*sp;
@@ -142,7 +143,7 @@
 	unsigned long flags;
 #endif
 
-	if ((bus > 7) || (dev_fn > 127)) {
+	if ((dev->bus->number > 7) || (dev->devfn > 127)) {
 		*val = 0xffff;
 		return PCIBIOS_DEVICE_NOT_FOUND;
 	}
@@ -154,10 +155,10 @@
 	eieio();
 #endif
 
-	if (bus == 0)
-		*QS_CONFIG_ADDR = mk_config_addr(bus, dev_fn, offset);
+	if (dev->bus->number == 0)
+		*QS_CONFIG_ADDR = mk_config_addr(dev->bus->number, dev->devfn, offset);
 	else
-		*QS_CONFIG_ADDR = mk_config_type1(bus, dev_fn, offset);
+		*QS_CONFIG_ADDR = mk_config_type1(dev->bus->number, dev->devfn, offset);
 	__get_qspan_pci_config(temp, QS_CONFIG_DATA, "lwz");
 	offset ^= 0x02;
 
@@ -172,14 +173,14 @@
 	return PCIBIOS_SUCCESSFUL;
 }
 
-int qspan_pcibios_read_config_dword(unsigned char bus, unsigned char dev_fn,
-				   unsigned char offset, unsigned int *val)
+static int qspan_pcibios_read_config_dword(struct pci_dev * const dev,
+                                           const int offset, u32 * const val)
 {
 #ifdef CONFIG_RPXCLASSIC
 	unsigned long flags;
 #endif
 
-	if ((bus > 7) || (dev_fn > 127)) {
+	if ((dev->bus->number > 7) || (dev->devfn > 127)) {
 		*val = 0xffffffff;
 		return PCIBIOS_DEVICE_NOT_FOUND;
 	}
@@ -191,10 +192,10 @@
 	eieio();
 #endif
 
-	if (bus == 0)
-		*QS_CONFIG_ADDR = mk_config_addr(bus, dev_fn, offset);
+	if (dev->bus->number == 0)
+		*QS_CONFIG_ADDR = mk_config_addr(dev->bus->number, dev->devfn, offset);
 	else
-		*QS_CONFIG_ADDR = mk_config_type1(bus, dev_fn, offset);
+		*QS_CONFIG_ADDR = mk_config_type1(dev->bus->number, dev->devfn, offset);
 	__get_qspan_pci_config(*val, QS_CONFIG_DATA, "lwz");
 
 #ifdef CONFIG_RPXCLASSIC
@@ -206,8 +207,8 @@
 	return PCIBIOS_SUCCESSFUL;
 }
 
-int qspan_pcibios_write_config_byte(unsigned char bus, unsigned char dev_fn,
-				   unsigned char offset, unsigned char val)
+static int qspan_pcibios_write_config_byte(struct pci_dev * const dev,
+                                           int offset, const u8 val)
 {
 	uint	temp;
 	u_char	*cp;
@@ -215,10 +216,10 @@
 	unsigned long flags;
 #endif
 
-	if ((bus > 7) || (dev_fn > 127))
+	if ((dev->bus->number > 7) || (dev->devfn > 127))
 		return PCIBIOS_DEVICE_NOT_FOUND;
 
-	qspan_pcibios_read_config_dword(bus, dev_fn, offset, &temp);
+	qspan_pcibios_read_config_dword(dev, offset, &temp);
 
 	offset ^= 0x03;
 	cp = ((u_char *)&temp) + (offset & 0x03);
@@ -231,10 +232,10 @@
 	eieio();
 #endif
 
-	if (bus == 0)
-		*QS_CONFIG_ADDR = mk_config_addr(bus, dev_fn, offset);
+	if (dev->bus->number == 0)
+		*QS_CONFIG_ADDR = mk_config_addr(dev->bus->number, dev->devfn, offset);
 	else
-		*QS_CONFIG_ADDR = mk_config_type1(bus, dev_fn, offset);
+		*QS_CONFIG_ADDR = mk_config_type1(dev->bus->number, dev->devfn, offset);
 	*QS_CONFIG_DATA = temp;
 
 #ifdef CONFIG_RPXCLASSIC
@@ -246,8 +247,8 @@
 	return PCIBIOS_SUCCESSFUL;
 }
 
-int qspan_pcibios_write_config_word(unsigned char bus, unsigned char dev_fn,
-				   unsigned char offset, unsigned short val)
+static int qspan_pcibios_write_config_word(struct pci_dev * const dev,
+                                           int offset, const u16 val)
 {
 	uint	temp;
 	ushort	*sp;
@@ -255,10 +256,10 @@
 	unsigned long flags;
 #endif
 
-	if ((bus > 7) || (dev_fn > 127))
+	if ((dev->bus->number > 7) || (dev->devfn > 127))
 		return PCIBIOS_DEVICE_NOT_FOUND;
 
-	qspan_pcibios_read_config_dword(bus, dev_fn, offset, &temp);
+	qspan_pcibios_read_config_dword(dev, offset, &temp);
 
 	offset ^= 0x02;
 	sp = ((ushort *)&temp) + ((offset >> 1) & 1);
@@ -271,10 +272,10 @@
 	eieio();
 #endif
 
-	if (bus == 0)
-		*QS_CONFIG_ADDR = mk_config_addr(bus, dev_fn, offset);
+	if (dev->bus->number == 0)
+		*QS_CONFIG_ADDR = mk_config_addr(dev->bus->number, dev->devfn, offset);
 	else
-		*QS_CONFIG_ADDR = mk_config_type1(bus, dev_fn, offset);
+		*QS_CONFIG_ADDR = mk_config_type1(dev->bus->number, dev->devfn, offset);
 	*QS_CONFIG_DATA = temp;
 
 #ifdef CONFIG_RPXCLASSIC
@@ -286,14 +287,14 @@
 	return PCIBIOS_SUCCESSFUL;
 }
 
-int qspan_pcibios_write_config_dword(unsigned char bus, unsigned char dev_fn,
-				    unsigned char offset, unsigned int val)
+static int qspan_pcibios_write_config_dword(struct pci_dev * const dev,
+                                            const int offset, const u32 val)
 {
 #ifdef CONFIG_RPXCLASSIC
 	unsigned long flags;
 #endif
 
-	if ((bus > 7) || (dev_fn > 127))
+	if ((dev->bus->number > 7) || (dev->devfn > 127))
 		return PCIBIOS_DEVICE_NOT_FOUND;
 
 #ifdef CONFIG_RPXCLASSIC
@@ -303,10 +304,10 @@
 	eieio();
 #endif
 
-	if (bus == 0)
-		*QS_CONFIG_ADDR = mk_config_addr(bus, dev_fn, offset);
+	if (dev->bus->number == 0)
+		*QS_CONFIG_ADDR = mk_config_addr(dev->bus->number, dev->devfn, offset);
 	else
-		*QS_CONFIG_ADDR = mk_config_type1(bus, dev_fn, offset);
+		*QS_CONFIG_ADDR = mk_config_type1(dev->bus->number, dev->devfn, offset);
 	*(unsigned int *)QS_CONFIG_DATA = val;
 
 #ifdef CONFIG_RPXCLASSIC
@@ -318,62 +319,140 @@
 	return PCIBIOS_SUCCESSFUL;
 }
 
-int qspan_pcibios_find_device(unsigned short vendor, unsigned short dev_id,
-			     unsigned short index, unsigned char *bus_ptr,
-			     unsigned char *dev_fn_ptr)
+static void qspan_init( void )
 {
-    int num, devfn;
-    unsigned int x, vendev;
+        qspan_t * const qs = (qspan_t *)PCI_CSR_ADDR;
 
-    if (vendor == 0xffff)
-	return PCIBIOS_BAD_VENDOR_ID;
-    vendev = (dev_id << 16) + vendor;
-    num = 0;
-    for (devfn = 0;  devfn < 32;  devfn++) {
-	qspan_pcibios_read_config_dword(0, devfn<<3, PCI_VENDOR_ID, &x);
-	if (x == vendev) {
-	    if (index == num) {
-		*bus_ptr = 0;
-		*dev_fn_ptr = devfn<<3;
-		return PCIBIOS_SUCCESSFUL;
-	    }
-	    ++num;
-	}
-    }
-    return PCIBIOS_DEVICE_NOT_FOUND;
+        /*
+         * clear all PCI error status
+         * disable SERR, and PERR
+         * disable I/O-space, memory-space, and bus mastering
+         */
+        qs->pci_cs      = QSPCI_CS_D_PE | QSPCI_CS_S_SERR | QSPCI_CS_R_MA |
+                QSPCI_CS_R_TA | QSPCI_CS_S_TA | QSPCI_CS_DEVSEL( 1 ) |
+                QSPCI_CS_MD_PED;
+
+        /* Disable i20 mode */
+        qs->i20_cs     |= QSI20_CS_I20_EN;
+
+        /* disable all slave and target images */
+        qs->pbti0_ctl   = 0;
+        qs->pbti1_ctl   = 0;
+        qs->qbsi0_at    = 0;
+        qs->qbsi1_at    = 0;
+
+        /*
+         * set latency timer to 8 clocks
+         * disable cache line
+         */
+        qs->pci_misc0   = 0;
+
+        /*
+         * allow PCI access to the 4KByte register file in PCI memory space
+         * (put at bottom, the PCI autoconfigure routine places PCI-memory
+         * devices found from the top of PCI memory space down)
+         */
+        qs->pci_bsm     = 0;
+
+        /* disable the PCI configuration expansion ROM */
+        qs->pci_bsrom   = 0;
+
+        /*
+         * set interrupt line to zero (this is a S/W register, its value
+         * is a don't care for the F/W)
+         */
+        qs->pci_misc1   = 0;
+
+        /* Enable PCI access to CPU DRAM at address 0 (64M) */
+        qs->pbti0_add   = 0x00000000;
+        qs->pbti0_ctl   = QSPBTI_CTL_EN | QSPBTI_CTL_BS( 10 ) | QSPBTI_CTL_PWEN;
+
+        /*
+         * enable error logging
+         */
+        qs->pb_errcs    = QSPB_ERRCS_EN;
+
+        /*
+         * clear all IDMA error status
+         * initialize to PowerQUICC mode
+         */
+        qs->idma_cs     = QSIDMA_CS_IRST | QSIDMA_CS_DONE | QSIDMA_CS_IPE |
+                QSIDMA_CS_IQE | QSIDMA_CS_IMODE;
+
+        /*
+         * disable all interrupts
+         * clear all interrupt status
+         * map all interrupts to the QBus
+         */
+        qs->int_ctl     = 0;
+        qs->int_stat    = ~0;
+        qs->int_dir     = 0;
+
+        /*
+         * BG* input is synchronous to QCLK
+         * BG* input is synchronous to QCLK (acknowledge)
+         * QBus is big-endian
+         */
+        qs->misc_ctl    = QSMISC_CTL_S_BG | QSMISC_CTL_S_BB |
+                QSMISC_CTL_MSTSLV( 3 );
+        qs->misc_ctl2  &= ~QSMISC_CTL2_QINT_PME;
+
+        /* setup slave image #0, 64KB window to PCI MEM space */
+        qs->qbsi0_ctl   = 0;
+        qs->qbsi0_at    = QSQBSI_AT_TA( PCI_ISA_MEM_ADDR >> 16 ) |
+                QSQBSI_AT_BS( 0 ) | QSQBSI_AT_EN;
+
+        /*
+         * clear all QBus error status
+         * enable QBus error log
+         */
+        qs->qb_errcs    = QSQB_ERRCS_EN | QSQB_ERRCS_ES;
+
+        /* Matrix only enable Memory-space and bus-mastering */
+        qs->pci_cs     |= QSPCI_CS_BM | QSPCI_CS_MS;
 }
 
-int qspan_pcibios_find_class(unsigned int class_code, unsigned short index,
-			    unsigned char *bus_ptr, unsigned char *dev_fn_ptr)
+static struct pci_ops qspan_pci_ops =
 {
-    int devnr, x, num;
-
-    num = 0;
-    for (devnr = 0;  devnr < 32;  devnr++) {
-	qspan_pcibios_read_config_dword(0, devnr<<3, PCI_CLASS_REVISION, &x);
-	if ((x>>8) == class_code) {
-	    if (index == num) {
-		*bus_ptr = 0;
-		*dev_fn_ptr = devnr<<3;
-		return PCIBIOS_SUCCESSFUL;
-	    }
-	    ++num;
-	}
-    }
-    return PCIBIOS_DEVICE_NOT_FOUND;
-}
+	.read_byte      = qspan_pcibios_read_config_byte,
+	.read_word      = qspan_pcibios_read_config_word,
+	.read_dword     = qspan_pcibios_read_config_dword,
+	.write_byte     = qspan_pcibios_write_config_byte,
+	.write_word     = qspan_pcibios_write_config_word,
+	.write_dword    = qspan_pcibios_write_config_dword,
+};
 
-void __init
-m8xx_pcibios_fixup(void))
+void __init m8xx_pcibios_fixup(void)
 {
-   /* Lots to do here, all board and configuration specific. */
+        /* Lots to do here, all board and configuration specific. */
 }
 
-void __init
-m8xx_setup_pci_ptrs(void))
+void __init m8xx_setup_pci_ptrs(void)
 {
-	set_config_access_method(qspan);
+        struct pci_controller * hose;
+
+        qspan_init();
 
 	ppc_md.pcibios_fixup = m8xx_pcibios_fixup;
-}
 
+        hose = pcibios_alloc_controller();
+        if ( !hose ) {
+                return;
+        }
+
+        hose->ops = &qspan_pci_ops;
+
+        hose->io_space.name     = "PCI I/O";
+        hose->io_space.start    = PCI_ISA_IO_ADDR;
+        hose->io_space.end      = PCI_ISA_IO_ADDR + PCI_ISA_IO_SIZE - 1;
+        hose->io_space.flags    = IORESOURCE_IO;
+
+        hose->io_resource       = hose->io_space;
+
+        hose->mem_space.name    = "PCI Memory";
+        hose->mem_space.start   = PCI_ISA_MEM_ADDR;
+        hose->mem_space.end     = PCI_ISA_MEM_ADDR + PCI_ISA_MEM_SIZE - 1;
+        hose->mem_space.flags   = IORESOURCE_MEM;
+
+        hose->mem_resources[0]  = hose->mem_space;
+}
diff -ruNa linux-2.4.35.4.orig/arch/ppc/kernel/qspan_pci.h linux-2.4.35.4/arch/ppc/kernel/qspan_pci.h
--- linux-2.4.35.4.orig/arch/ppc/kernel/qspan_pci.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.35.4/arch/ppc/kernel/qspan_pci.h	2007-12-03 11:06:29.000000000 -0800
@@ -0,0 +1,195 @@
+#ifndef _PPC_KERNEL_QSPAN_PCI_H
+#define _PPC_KERNEL_QSPAN_PCI_H
+
+typedef struct qspan {
+        u32 pci_id;             /* 0x000 - PCI configuration space ID register */
+        u32 pci_cs;             /* 0x004 - PCI configuration space control and status register */
+        u32 pci_class;  /* 0x008 - PCI configuration class register */
+        u32 pci_misc0;  /* 0x00C - PCI configuration miscellaneous 0 register */
+        u32 pci_bsm;    /* 0x010 - PCI configuration base address for memory register */
+        u32 pci_bsio;   /* 0x014 - PCI configuration base address for I/O register */
+        u32 pci_u0[0x005];      /* 0x018 - PCI unimplemented */
+        u32 pci_sid;    /* 0x02C - PCI configuration subsystem ID register */
+        u32 pci_bsrom;  /* 0x030 - PCI configuration expansion ROM base address register */
+        u32 pci_r0[0x002];      /* 0x034 - PCI reserved */
+        u32 pci_misc1;  /* 0x03C - PCI configuration miscellaneous 1 register */
+        u32 pci_u1[0x030];      /* 0x040 - PCI unimplemented */
+        u32 pbti0_ctl;  /* 0x100 - PCI bus target image 0 control register */
+        u32 pbti0_add;  /* 0x104 - PCI bus target image 0 address register */
+        u32 qspan_r0[0x002];/* 0x108 - QSpan reserved */
+        u32 pbti1_ctl;  /* 0x110 - PCI bus target image 1 control register */
+        u32 pbti1_add;  /* 0x114 - PCI bus target image 1 address register */
+        u32 qspan_r1[0x009];/* 0x118 - QSpan reserved */
+        u32 pbrom_ctl;  /* 0x13C - PCI bus expansion ROM control register */
+        u32 pb_errcs;   /* 0x140 - PCI bus error control and status register */
+        u32 pb_aerr;    /* 0x144 - PCI bus address error log register */
+        u32 pb_derr;    /* 0x148 - PCI bus data error log register */
+        u32 qspan_r2[0x02D];/* 0x14C - QSpan reserved */
+        u32 i20_cs;     /* 0x200 - IDMA control and status register */
+        u32 qspan_r2a[0x07F];/* 0x204 - QSpan reserved */
+        u32 idma_cs;    /* 0x400 - IDMA control and status register */
+        u32 idma_add;   /* 0x404 - IDMA address register */
+        u32 idma_cnt;   /* 0x408 - IDMA transfer count register */
+        u32 qspan_r3[0x03D];/* 0x40C - QSpan reserved */
+        u32 con_add;    /* 0x500 - configuration address register */
+        u32 con_data;   /* 0x504 - configuration data register */
+        u32 qspan_r4[0x03E];/* 0x508 - QSpan reserved */
+        u32 int_stat;   /* 0x600 - interrupt status register */
+        u32 int_ctl;    /* 0x604 - interrupt control register */
+        u32 int_dir;    /* 0x608 - interrupt direction control register */
+        u32 qspan_r5[0x07D];/* 0x60C - QSpan reserved */
+        u32 misc_ctl;   /* 0x800 - miscellaneous control and status register */
+        u32 eepprom_cs;     /* 0x804 - reserved */
+        u32 misc_ctl2;     /* 0x808 - misc ctl 2 */
+        u32 qspan_r6[0x1BD];/* 0x80c - QSpan reserved */
+        u32 qbsi0_ctl;  /* 0xF00 - QBus slave image 0 control register */
+        u32 qbsi0_at;   /* 0xF04 - QBus slave image 0 address translation register */
+        u32 qspan_r7[0x002];/* 0xF08 - QSpan reserved */
+        u32 qbsi1_ctl;  /* 0xF10 - QBus slave image 1 control register */
+        u32 qbsi1_at;   /* 0xF14 - QBus slave image 1 address translation register */
+        u32 qspan_r8[0x01A];/* 0xF18 - QSpan reserved */
+        u32 qb_errcs;   /* 0xF80 - QBus error log control and status register */
+        u32 qb_aerr;    /* 0xF84 - QBus address error log register */
+        u32 qb_derr;    /* 0xF88 - QBus data error log register */
+        u32 qspan_r9[0x01D];/* 0xF8C - QSpan reserved */
+} qspan_t;
+
+#define QSPCI_CS_D_PE                   ( 1 << 31 )
+#define QSPCI_CS_S_SERR                 ( 1 << 30 )
+#define QSPCI_CS_R_MA                   ( 1 << 29 )
+#define QSPCI_CS_R_TA                   ( 1 << 28 )
+#define QSPCI_CS_S_TA                   ( 1 << 27 )
+#define QSPCI_CS_DEVSEL( x )            ( ( ( x ) & 0x3 ) << 25 )
+#define QSPCI_CS_MD_PED                 ( 1 << 24 )
+#define QSPCI_CS_TFBBC                  ( 1 << 23 )
+#define QSPCI_CS_DEV66                  ( 1 << 21 )
+#define QSPCI_CS_CAP_L                  ( 1 << 20 )
+#define QSPCI_CS_MFFBC                  ( 1 << 9 )
+#define QSPCI_CS_SERR_EN                ( 1 << 8 )
+#define QSPCI_CS_WAIT                   ( 1 << 7 )
+#define QSPCI_CS_PERESP                 ( 1 << 6 )
+#define QSPCI_CS_VGAPS                  ( 1 << 5 )
+#define QSPCI_CS_MWI_EN                 ( 1 << 4 )
+#define QSPCI_CS_SC                     ( 1 << 3 )
+#define QSPCI_CS_BM                     ( 1 << 2 )
+#define QSPCI_CS_MS                     ( 1 << 1 )
+#define QSPCI_CS_IOS                    ( 1 << 0 )
+
+#define QSPBTI_CTL_EN                   ( 1 << 31 )
+#define QSPBTI_CTL_BS( x )              ( ( ( x ) & 0xf ) << 24 )
+#define QSPBTI_CTL_PREN                 ( 1 << 23 )
+#define QSPBTI_CTL_BRSTWREN             ( 1 << 22 )
+#define QSPBTI_CTL_INVEND               ( 1 << 19 )
+#define QSPBTI_CTL_TC( x )              ( ( ( x ) & 0xf ) << 12 )
+#define QSPBTI_CTL_DSIZE( x )           ( ( ( x ) & 0x3 ) << 10 )
+#define QSPBTI_CTL_PWEN                 ( 1 << 7 )
+#define QSPBTI_CTL_PAS                  ( 1 << 6 )
+
+#define QSPB_ERRCS_EN                   ( 1 << 31 )
+#define QSPB_ERRCS_ES                   ( 1 << 24 )
+#define QSPB_ERRCS_UNL_QSC              ( 1 << 23 )
+#define QSPB_ERRCS_CMDERR( x )          ( ( ( x ) & 0xf ) << 4 )
+#define QSPB_ERRCS_BE_ERR( x )          ( ( ( x ) & 0xf ) << 0 )
+
+#define QSI20_CS_QIBA( x )              ( ( ( x ) & 0xfff ) << 16 )
+#define QSI20_CS_IF_E                   ( 1 << 15 )
+#define QSI20_CS_IP_E                   ( 1 << 14 )
+#define QSI20_CS_OF_E                   ( 1 << 13 )
+#define QSI20_CS_OP_E                   ( 1 << 12 )
+#define QSI20_CS_IF_F                   ( 1 << 11 )
+#define QSI20_CS_IP_F                   ( 1 << 10 )
+#define QSI20_CS_OF_F                   ( 1 << 9 )
+#define QSI20_CS_OP_F                   ( 1 << 8 )
+#define QSI20_CS_FIFO_SIZE( x )         ( ( ( x ) & 0x7 ) << 4 )
+#define QSI20_CS_RR_BP                  ( 1 << 1 )
+#define QSI20_CS_I20_EN                 ( 1 << 0 )
+
+#define QSIDMA_CS_GO                    ( 1 << 31 )
+#define QSIDMA_CS_IRST_REQ              ( 1 << 30 )
+#define QSIDMA_CS_ACT                   ( 1 << 23 )
+#define QSIDMA_CS_IRST                  ( 1 << 22 )
+#define QSIDMA_CS_DONE                  ( 1 << 21 )
+#define QSIDMA_CS_IPE                   ( 1 << 20 )
+#define QSIDMA_CS_IQE                   ( 1 << 19 )
+#define QSIDMA_CS_CMD                   ( 1 << 18 )
+#define QSIDMA_CS_IWM( x )              ( ( ( x ) & 0xf ) << 12 )
+#define QSIDMA_CS_TC( x )               ( ( ( x ) & 0xf ) << 8 )
+#define QSIDMA_CS_TC_EN                 ( 1 << 7 )
+#define QSIDMA_CS_CHAIN                 ( 1 << 6 )
+#define QSIDMA_CS_DMA                   ( 1 << 5 )
+#define QSIDMA_CS_DIR                   ( 1 << 4 )
+#define QSIDMA_CS_IMODE                 ( 1 << 3 )
+#define QSIDMA_CS_QTERM                 ( 1 << 2 )
+#define QSIDMA_CS_STERM                 ( 1 << 1 )
+#define QSIDMA_CS_PORT16                ( 1 << 0 )
+
+#define QSINT_PEL_IS                    ( 1 << 31 )
+#define QSINT_QEL_IS                    ( 1 << 30 )
+#define QSINT_MDPED_IS                  ( 1 << 29 )
+#define QSINT_PCSR_IS                   ( 1 << 28 )
+#define QSINT_IQE_IS                    ( 1 << 27 )
+#define QSINT_IPE_IS                    ( 1 << 26 )
+#define QSINT_IRST_IS                   ( 1 << 25 )
+#define QSINT_DONE_IS                   ( 1 << 24 )
+#define QSINT_INT_IS                    ( 1 << 23 )
+#define QSINT_PERR_IS                   ( 1 << 22 )
+#define QSINT_SERR_IS                   ( 1 << 21 )
+#define QSINT_QINT_IS                   ( 1 << 20 )
+#define QSINT_MB3_IS                    ( 1 << 19 )
+#define QSINT_MB2_IS                    ( 1 << 18 )
+#define QSINT_MB1_IS                    ( 1 << 17 )
+#define QSINT_MB0_IS                    ( 1 << 16 )
+#define QSINT_QDPE_S                    ( 1 << 15 )
+#define QSINT_PSC_IS                    ( 1 << 14 )
+#define QSINT_OPNE_S                    ( 1 << 13 )
+#define QSINT_IPN_IS                    ( 1 << 12 )
+#define QSINT_IFE_S                     ( 1 << 11 )
+#define QSINT_OFE_S                     ( 1 << 10 )
+#define QSINT_IPF_S                     ( 1 << 9 )
+#define QSINT_OFF_S                     ( 1 << 8 )
+#define QSINT_SI3_IS                    ( 1 << 3 )
+#define QSINT_SI2_IS                    ( 1 << 2 )
+#define QSINT_SI1_IS                    ( 1 << 1 )
+#define QSINT_SI0_IS                    ( 1 << 0 )
+
+#define QSMISC_CTL_SW_RST               ( 1 << 31 )
+#define QSMISC_CTL_S_BG                 ( 1 << 19 )
+#define QSMISC_CTL_S_BB                 ( 1 << 18 )
+#define QSMISC_CTL_QB_BOC               ( 1 << 16 )
+#define QSMISC_CTL_QB_MA_BE_D           ( 1 << 12 )
+#define QSMISC_CTL_QFIFO_BLK8           ( 1 << 9 )
+#define QSMISC_CTL_QFIFO_MODE           ( 1 << 8 )
+#define QSMISC_CTL_PRCNT( x )           ( ( ( x ) & 0x3f ) << 2 )
+#define QSMISC_CTL_MSTSLV( x )          ( ( ( x ) & 0x3 ) << 0 )
+
+#define QSMISC_CTL2_PCI_DIS             ( 1 << 31 )
+#define QSMISC_CTL2_PTP_IB              ( 1 << 23 )
+#define QSMISC_CTL2_KEEP_BB             ( 1 << 22 )
+#define QSMISC_CTL2_MAX_RTRY( x )       ( ( ( x ) & 0x3 ) << 20 )
+#define QSMISC_CTL2_PTC_PD              ( 1 << 19 )
+#define QSMISC_CTL2_TA_BE_EN            ( 1 << 18 )
+#define QSMISC_CTL2_BURST_4             ( 1 << 17 )
+#define QSMISC_CTL2_PR_SING             ( 1 << 16 )
+#define QSMISC_CTL2_PRCNT2( x )         ( ( ( x ) & 0x3f ) << 10 )
+#define QSMISC_CTL2_REG_AC              ( 1 << 9 )
+#define QSMISC_CTL2_QSC_PW              ( 1 << 8 )
+#define QSMISC_CTL2_QBUS_PAR            ( 1 << 4 )
+#define QSMISC_CTL2_EEPROM_ACC          ( 1 << 3 )
+#define QSMISC_CTL2_NOTO                ( 1 << 2 )
+#define QSMISC_CTL2_PSC_QRST            ( 1 << 1 )
+#define QSMISC_CTL2_QINT_PME            ( 1 << 0 )
+
+#define QSQBSI_CTL_PWEN                 ( 1 << 31 )
+#define QSQBSI_CTL_PAS                  ( 1 << 24 )
+#define QSQBSI_CTL_PREN                 ( 1 << 23 )
+
+#define QSQBSI_AT_TA( x )               ( ( ( x ) & 0xffff ) << 16 )
+#define QSQBSI_AT_BS( x )               ( ( ( x ) & 0xf ) << 4 )
+#define QSQBSI_AT_EN                    ( 1 << 0 )
+
+#define QSQB_ERRCS_EN                   ( 1 << 31 )
+#define QSQB_ERRCS_ES                   ( 1 << 24 )
+#define QSQB_ERRCS_TC_ERR( x )          ( ( ( x ) & 0xf ) << 4 )
+#define QSQB_ERRCS_SIZ_ERR( x )         ( ( ( x ) & 0x3 ) << 0 )
+
+#endif

^ permalink raw reply

* Re: [PATCH] Add IPIC MSI interrupt support
From: Benjamin Herrenschmidt @ 2007-12-03 21:03 UTC (permalink / raw)
  To: Li Li; +Cc: linuxppc-dev, Gala Kumar, Li Tony
In-Reply-To: <1196672870.14353.21.camel@Guyver>


On Mon, 2007-12-03 at 17:07 +0800, Li Li wrote:
> 
> In IPIC, the 8 MSI interrupts is handled as level intrrupt.
> I just provide a versatile in case it is changed.

Level ? Are you sure ? MSIs are by definition edge interrupts... Or do
you have some weird logic that asserts a level input until you go ack
something ? Sounds weird...

Ben.

^ 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