LinuxPPC-Dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* Re: [RFC PATCH v0.1] net driver: mpc52xx fec
From: Juergen Beisert @ 2007-10-01  8:35 UTC (permalink / raw)
  To: linuxppc-embedded
In-Reply-To: <9e4733910709280838v5deebfdbo62b9097faed9c937@mail.gmail.com>

On Friday 28 September 2007 17:38, Jon Smirl wrote:
> On 9/28/07, Juergen Beisert <jbe@pengutronix.de> wrote:
> > But I can't run it a second time, as the network on target's side doesn=
't
> > respond. Any idea?
>
> Do the stress tests complete on a non-rt kernel?

I tried it again:

1) Target runs 2.6.23-rc8 without rt-preempt:

@host$ nmap 192.168.23.226

Starting Nmap 4.20 ( http://insecure.org ) at 2007-10-01 10:20 CEST
Interesting ports on 192.168.23.226:
Not shown: 1695 closed ports
PORT   STATE SERVICE
22/tcp open  ssh
23/tcp open  telnet

Nmap finished: 1 IP address (1 host up) scanned in 0.581 seconds

Target continues to work. Does not make a difference if the root filesystem=
 is=20
jffs2 or nfs.

2) Same target runs 2.6.23-rc8-rt1

@host$ nmap 192.168.23.226

Starting Nmap 4.20 ( http://insecure.org ) at 2007-10-01 10:15 CEST
Interesting ports on 192.168.23.226:
Not shown: 871 filtered ports, 824 closed ports
PORT   STATE SERVICE
22/tcp open  ssh
23/tcp open  telnet

Nmap finished: 1 IP address (1 host up) scanned in 14.116 seconds

Network on target dies. But can be reactivated by an "ifconfig eth0 down;=20
ifconfig eth0 up". I included some printk statements into the fec.c source =
to=20
see what interrupts are happen.

"r" means fec_rx_interrupt was entered, "t" means fec_tx_interrupt was ente=
red=20
and "p" means fec_interrupt was entered. This is the output of the=20
nmap "attack" above:

rtrtrrr
 at this point: fec_hard_start_xmit, stop queue
rrt
 at this point: fec_tx_interrupt, wake queue
ttrr
 at this point: fec_hard_start_xmit, stop queue
rrt
 at this point: fec_tx_interrupt, wake queue
ttrr
 at this point: fec_hard_start_xmit, stop queue
rrt
 at this point: fec_tx_interrupt, wake queue
ttrr
 at this point: fec_hard_start_xmit, stop queue
rrt
 at this point: fec_tx_interrupt, wake queue
ttrr
 at this point: fec_hard_start_xmit, stop queue
rrt
 at this point: fec_tx_interrupt, wake queue
ttrr
 at this point: fec_hard_start_xmit, stop queue
rrt
 at this point: fec_tx_interrupt, wake queue
ttr
 at this point: fec_hard_start_xmit, stop queue
rrt
 at this point: fec_tx_interrupt, wake queue
 at this point: fec_hard_start_xmit, stop queue
t
 at this point: fec_tx_interrupt, wake queue
tp
<7>net eth0: ievent: 08020000

=2E..at this point the network is dead.

BTW: Without rt-preempt none of the wake/stop queue events and no=20
fec_interrupt occurs. I only see a long list of "r"s and "t"s...

Juergen

=2D-=20
Dipl.-Ing. Juergen Beisert | http://www.pengutronix.de
=A0Pengutronix - Linux Solutions for Science and Industry
=A0   Handelsregister: Amtsgericht Hildesheim, HRA 2686
=A0 =A0 =A0    Vertretung Sued/Muenchen, Germany
   Phone: +49-8766-939 228 |  Fax: +49-5121-206917-9

^ permalink raw reply

* Re: Powerbook shuts down hard when hot, patch found
From: Michel Dänzer @ 2007-10-01  8:00 UTC (permalink / raw)
  To: Michael Buesch; +Cc: linuxppc-dev
In-Reply-To: <200709301216.55123.mb@bu3sch.de>


On Sun, 2007-09-30 at 12:16 +0200, Michael Buesch wrote:
> 
> Ah, forgot to say.
> It does not crash immediately when the register is written. It takes about two seconds
> to crash. And when the machine is colder to begin with, it takes slightly
> longer to trigger. That _might_ support your overheating theory.
> 
> Though, it does not trigger when it's up and running, no matter how hot you drive it.

Maybe the thermal control module prevents it from overheating. Have you
tried unloading it or loading it ASAP on bootup to see if that makes any
difference either way?


-- 
Earthling Michel Dänzer           |          http://tungstengraphics.com
Libre software enthusiast         |          Debian, X and DRI developer

^ permalink raw reply

* Re: Is it safe to use these Linux function (test_bit(), set_bit(), clear_bit()) in character device driver for 2.6.10 ppc kernel.
From: Misbah khan @ 2007-10-01  5:38 UTC (permalink / raw)
  To: linuxppc-embedded
In-Reply-To: <20071001042559.GA32255@lixom.net>




Olof Johansson-2 wrote:
> 
> First, PLEASE stop quoting your own text. Do not append > in front of
> the lines you write yourself in the reply. It makes it impossible to
> tell what parts are new and what are old.
> 
> On Sun, Sep 30, 2007 at 07:54:28AM -0700, Misbah khan wrote:
> 
>> >> FPGA is Indeed mapped non cashed here is the part of the code 
>> >> 
>> >> /* Physical bus memory is mapped */
>> >> 	mmap_reg_ptr=(UINT32 *)ioremap_nocache(PHY_MEM_ADDR,PHY_MEM_SIZE);
>> >> 
>> >> And is it ok if I caste FPGA pointer volatile like this will reduce
>> the
>> >> probability of failure 
> 
> You cannot ever use set_bit/clear_bit to uncacheable memory. Ever. It
> uses load-reserve/store-conditional, and they are not legal to use to
> uncacheable memory.
> 
> Also, regular ioremap() is by default uncacheable, so it's quite adequate
> to use in this case, no need to use the _nocache version.
> 
>> >> do you think   in_be32()  could be the best approach than direct
>> >> dereferencing. And about test_bit() function does it looks fine to you 
> 
> You need to use in_be32() + manipulating the value + out_be32(),
> yes. Depending on the rest of your driver you might need to protect it
> with a spinlock, but that's beyond the scope of this question.
> 
> 
> -Olof
> 
> I am confused that some people tells me to map the memory noncacheble and
> some tells me not. could you tell me which is the best approach and please
> elaborate the reason as well. The part of the code is mentioned above is a
> reference and my concern are as follows:-
> 
> 1. I am mapping 32 KB of memory for which i am using _nocasheble. Is it
> absolutely fine????
> 
> 2. I am directly dereferencing the pointer to the mapped region insted of
> using a wrapper function due to (1) Aready used in the past and have faith
> in it .
>     (2) I had used functions like ioread32() iowrite32() in the past which
> is suggested by rubini in his book on Linux device Driver but the output i
> got was bitswapped .
> 
> 3. test_bit()/clear_bit() are the functions which i am using in my driver
> and in the way i described above , please let me know that is looks fine
> in the Implimention or shall i read the value and mask the bits rather
> than beliving in these functions for eg :-
> 
> dfr_data_ret=*(volatile UINT32 *)((volatile UINT32
> *)mmap_reg_ptr+DATA_STATUS_REG);
> 
> dfr_data_ret&=STATUS_MASK;
> 
> Please reply to clear my doubts.
> 
> Misbah
> 
> 
> 
> _______________________________________________
> Linuxppc-embedded mailing list
> Linuxppc-embedded@ozlabs.org
> https://ozlabs.org/mailman/listinfo/linuxppc-embedded
> 
> 

-- 
View this message in context: http://www.nabble.com/Is-it-safe-to-use-these-Linux-function-%28test_bit%28%29%2Cset_bit%28%29%2Cclear_bit%28%29%29-in-character-device-driver-for-2.6.10-ppc-kernel.-tf4527008.html#a12973587
Sent from the linuxppc-embedded mailing list archive at Nabble.com.

^ permalink raw reply

* Re: [PATCH 1/2] qemu platform, v2
From: David Gibson @ 2007-10-01  5:33 UTC (permalink / raw)
  To: Segher Boessenkool
  Cc: linuxppc-dev, Paul Mackerras, Milton Miller, Rob Landley,
	Christoph Hellwig
In-Reply-To: <4d27912d86d1373ca01d43bd296e237b@kernel.crashing.org>

On Fri, Sep 28, 2007 at 06:53:28PM +0200, Segher Boessenkool wrote:
> >> I'd be following this more closely if compiling a device tree didn't 
> >> currently
> >> require an external utility (dtc or some such) that doesn't come with 
> >> the
> >> Linux kernel.  No other target platform I've built kernels for 
> >> requires such
> >> an environmental dependency.
> >
> > No?  You haven't built kernels for other platforms that have external
> > dependencies such as perl, gcc, make, binutils, etc.? :)
> 
> Two of the supported Linux archs cannot be built with a mainline
> compiler, even!
> 
> And I have to install GNU sed/awk to get builds to work, too.
> 
> OTOH, it would be nice if we didn't need DTC -- it itself doesn't
> build out-of-the-box on all systems, either ;-)
> 
> >>  (This is a problem both for hardwiring the
> >> device tree into the kernel and for building a new boot rom from the 
> >> linux
> >> kernel's ppc boot wrapper that would contain such a device tree to 
> >> feed to
> >> the kernel.)
> >
> > It's only really been a problem for ps3 so far, since the embedded
> > guys don't seem to have any difficulty with installing dtc.  We are
> > looking at what to do for ps3 and prep, and the answer may well
> > involve bundling dtc in the kernel source (it's not too big, around
> > 3400 lines).
> 
> If only a few platforms have this problem, we could instead include
> their .dtb files in the kernel source tree.

Including .dtbs in the kernel tree has a big practical problem:
they're binary, so can't be patch(1)ed, which makes updating them a
complete PITA.

I'm working on merging dtc into the kernel tree instead.

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

^ permalink raw reply

* Re: Is it safe to use these Linux function (test_bit(), set_bit(), clear_bit()) in character device driver for 2.6.10 ppc kernel.
From: Olof Johansson @ 2007-10-01  4:25 UTC (permalink / raw)
  To: Misbah khan; +Cc: linuxppc-embedded
In-Reply-To: <12966462.post@talk.nabble.com>

First, PLEASE stop quoting your own text. Do not append > in front of
the lines you write yourself in the reply. It makes it impossible to
tell what parts are new and what are old.

On Sun, Sep 30, 2007 at 07:54:28AM -0700, Misbah khan wrote:

> >> FPGA is Indeed mapped non cashed here is the part of the code 
> >> 
> >> /* Physical bus memory is mapped */
> >> 	mmap_reg_ptr=(UINT32 *)ioremap_nocache(PHY_MEM_ADDR,PHY_MEM_SIZE);
> >> 
> >> And is it ok if I caste FPGA pointer volatile like this will reduce the
> >> probability of failure 

You cannot ever use set_bit/clear_bit to uncacheable memory. Ever. It
uses load-reserve/store-conditional, and they are not legal to use to
uncacheable memory.

Also, regular ioremap() is by default uncacheable, so it's quite adequate
to use in this case, no need to use the _nocache version.

> >> do you think   in_be32()  could be the best approach than direct
> >> dereferencing. And about test_bit() function does it looks fine to you 

You need to use in_be32() + manipulating the value + out_be32(),
yes. Depending on the rest of your driver you might need to protect it
with a spinlock, but that's beyond the scope of this question.


-Olof

^ permalink raw reply

* Re: [PATCHv2 0/4] Xilinx Virtex support for arch/powerpc
From: Grant Likely @ 2007-10-01  3:44 UTC (permalink / raw)
  To: Josh Boyer; +Cc: linuxppc-dev
In-Reply-To: <1191206775.10089.10.camel@localhost.localdomain>

On 9/30/07, Josh Boyer <jwboyer@linux.vnet.ibm.com> wrote:
> On Sun, 2007-09-30 at 16:20 -0600, Grant Likely wrote:
> > 2nd version of Xilinx Virtex patches.  I've addressed all the comments
> > that I've received so far.  This series is just the arch/powerpc support
> > code.  I'll send the device driver changes in a seperate series for
> > each driver.
>
> Overall looks pretty darn good.  You dropped the patch to add you as the
> Xilinx maintainer.  Oversight?

I just don't have an OK from Paulus yet.

> Also, the support seems fairly generic but I don't see any ml300.dts or
> ml4xx.dts files.  And the Kconfig files don't select WANT_DEVICE_TREE.
> Are those patches coming later, or do these boards really not need a DTS
> file?

Those patches are coming later along with a defconfig patch.

Thanks Josh!
g.

-- 
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.
grant.likely@secretlab.ca
(403) 399-0195

^ permalink raw reply

* Re: [PATCHv2 0/4] Xilinx Virtex support for arch/powerpc
From: Josh Boyer @ 2007-10-01  2:46 UTC (permalink / raw)
  To: Grant Likely; +Cc: linuxppc-dev
In-Reply-To: <20070930221613.583.252.stgit@trillian.cg.shawcable.net>

On Sun, 2007-09-30 at 16:20 -0600, Grant Likely wrote:
> 2nd version of Xilinx Virtex patches.  I've addressed all the comments
> that I've received so far.  This series is just the arch/powerpc support
> code.  I'll send the device driver changes in a seperate series for
> each driver.

Overall looks pretty darn good.  You dropped the patch to add you as the
Xilinx maintainer.  Oversight?

Also, the support seems fairly generic but I don't see any ml300.dts or
ml4xx.dts files.  And the Kconfig files don't select WANT_DEVICE_TREE.
Are those patches coming later, or do these boards really not need a DTS
file?

josh

^ permalink raw reply

* Re: [PATCH 0/3] Bug fixes to Virtex support in arch/ppc
From: Josh Boyer @ 2007-10-01  1:49 UTC (permalink / raw)
  To: Grant Likely; +Cc: linuxppc-dev
In-Reply-To: <20070930214140.31899.55951.stgit@trillian.cg.shawcable.net>

On Sun, 2007-09-30 at 15:46 -0600, Grant Likely wrote:
> Josh,
> 
> Here are some small bug fixes to arch/ppc.  They are all pretty trivial,
> and I think they should go in for 2.6.24.  If there are no problems with
> them, can you please merge them into your tree and ask paulus to pull
> them?

Yep.  These all seem truly bug-fix and sane.  I'll pull them into my
tree tomorrow.

josh

^ permalink raw reply

* Re: [PATCH v2 2/6] Sysace: Use the established platform bus api
From: Grant Likely @ 2007-09-30 23:33 UTC (permalink / raw)
  To: Christoph Hellwig, Grant Likely, linux-kernel, linuxppc-dev,
	paulus, axboe
In-Reply-To: <20070930230557.GA17654@infradead.org>

On 9/30/07, Christoph Hellwig <hch@infradead.org> wrote:
> On Sun, Sep 30, 2007 at 04:57:09PM -0600, Grant Likely wrote:
> > +     if ((rc = platform_driver_register(&ace_platform_driver)) != 0)
> > +             goto err_plat;
>
>         rc = platform_driver_register(&ace_platform_driver);
>         if (rc)
>                  goto err_plat;
>
> please.

Okay, will do.

>
> > +      err_plat:
> > +     unregister_blkdev(ace_major, "xsysace");
> > +      err_blk:
>
> labels should be indented zero or one space, but not more.

scripts/Lindent does this.  Originally, I *didn't* have my labels
indented.  :-)   Does Lindent need to be fixed?

Cheers,
g.

-- 
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.
grant.likely@secretlab.ca
(403) 399-0195

^ permalink raw reply

* Re: [PATCH v2 2/6] Sysace: Use the established platform bus api
From: Christoph Hellwig @ 2007-09-30 23:05 UTC (permalink / raw)
  To: Grant Likely; +Cc: axboe, linuxppc-dev, paulus, linux-kernel
In-Reply-To: <20070930225707.2476.24080.stgit@trillian.cg.shawcable.net>

On Sun, Sep 30, 2007 at 04:57:09PM -0600, Grant Likely wrote:
> +	if ((rc = platform_driver_register(&ace_platform_driver)) != 0)
> +		goto err_plat;

	rc = platform_driver_register(&ace_platform_driver);
	if (rc)
		 goto err_plat;

please.

> +      err_plat:
> +	unregister_blkdev(ace_major, "xsysace");
> +      err_blk:

labels should be indented zero or one space, but not more.

^ permalink raw reply

* [PATCH v2 4/6] Sysace: minor rework and cleanup changes
From: Grant Likely @ 2007-09-30 22:57 UTC (permalink / raw)
  To: linux-kernel, linuxppc-dev, paulus, axboe
In-Reply-To: <20070930225112.2476.49914.stgit@trillian.cg.shawcable.net>

From: Grant Likely <grant.likely@secretlab.ca>

Miscellanious rework to the sysace driver; Not critical, but makes the
subsequent addition of the of_platform bus binding a wee bit cleaner

Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
---

 drivers/block/xsysace.c |   12 +++++++++---
 1 files changed, 9 insertions(+), 3 deletions(-)

diff --git a/drivers/block/xsysace.c b/drivers/block/xsysace.c
index 555939b..10bb4e5 100644
--- a/drivers/block/xsysace.c
+++ b/drivers/block/xsysace.c
@@ -158,6 +158,9 @@ MODULE_LICENSE("GPL");
 #define ACE_FIFO_SIZE (32)
 #define ACE_BUF_PER_SECTOR (ACE_SECTOR_SIZE / ACE_FIFO_SIZE)
 
+#define ACE_BUS_WIDTH_8  0
+#define ACE_BUS_WIDTH_16 1
+
 struct ace_reg_ops;
 
 struct ace_device {
@@ -931,9 +934,11 @@ static int __devinit ace_setup(struct ace_device *ace)
 {
 	u16 version;
 	u16 val;
-
 	int rc;
 
+	dev_dbg(ace->dev, "ace_setup(ace=0x%p)\n", ace);
+	dev_dbg(ace->dev, "physaddr=0x%lx irq=%i\n", ace->physaddr, ace->irq);
+
 	spin_lock_init(&ace->lock);
 	init_completion(&ace->id_completion);
 
@@ -982,7 +987,7 @@ static int __devinit ace_setup(struct ace_device *ace)
 	snprintf(ace->gd->disk_name, 32, "xs%c", ace->id + 'a');
 
 	/* set bus width */
-	if (ace->bus_width == 1) {
+	if (ace->bus_width == ACE_BUS_WIDTH_16) {
 		/* 0x0101 should work regardless of endianess */
 		ace_out_le16(ace, ACE_BUSMODE, 0x0101);
 
@@ -1117,7 +1122,7 @@ static void __devexit ace_free(struct device *dev)
 static int __devinit ace_probe(struct platform_device *dev)
 {
 	unsigned long physaddr = 0;
-	int bus_width = 1; /* FIXME: should not be hard coded */
+	int bus_width = ACE_BUS_WIDTH_16; /* FIXME: should not be hard coded */
 	int id = dev->id;
 	int irq = NO_IRQ;
 	int i;
@@ -1166,6 +1171,7 @@ static int __init ace_init(void)
 		goto err_blk;
 	}
 
+	pr_debug("xsysace: registering platform binding\n");
 	if ((rc = platform_driver_register(&ace_platform_driver)) != 0)
 		goto err_plat;
 

^ permalink raw reply related

* [PATCH v2 6/6] Sysace: Add of_platform_bus binding
From: Grant Likely @ 2007-09-30 22:57 UTC (permalink / raw)
  To: linux-kernel, linuxppc-dev, paulus, axboe
In-Reply-To: <20070930225112.2476.49914.stgit@trillian.cg.shawcable.net>

From: Grant Likely <grant.likely@secretlab.ca>

The of_platform bus binding is needed to make the device driver usable
under arch/powerpc.

Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
---

 drivers/block/xsysace.c |   89 +++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 89 insertions(+), 0 deletions(-)

diff --git a/drivers/block/xsysace.c b/drivers/block/xsysace.c
index 296d567..56c4af3 100644
--- a/drivers/block/xsysace.c
+++ b/drivers/block/xsysace.c
@@ -91,6 +91,10 @@
 #include <linux/blkdev.h>
 #include <linux/hdreg.h>
 #include <linux/platform_device.h>
+#if defined(CONFIG_OF)
+#include <linux/of_device.h>
+#include <linux/of_platform.h>
+#endif
 
 MODULE_AUTHOR("Grant Likely <grant.likely@secretlab.ca>");
 MODULE_DESCRIPTION("Xilinx SystemACE device driver");
@@ -1158,6 +1162,85 @@ static struct platform_driver ace_platform_driver = {
 };
 
 /* ---------------------------------------------------------------------
+ * OF_Platform Bus Support
+ */
+
+#if defined(CONFIG_OF)
+static int __devinit
+ace_of_probe(struct of_device *op, const struct of_device_id *match)
+{
+	struct resource res;
+	unsigned long physaddr;
+	const u32 *id;
+	int irq, bus_width, rc;
+
+	dev_dbg(&op->dev, "ace_of_probe(%p, %p)\n", op, match);
+
+	/* device id */
+	id = of_get_property(op->node, "port-number", NULL);
+
+	/* physaddr */
+	rc = of_address_to_resource(op->node, 0, &res);
+	if (rc) {
+		dev_err(&op->dev, "invalid address\n");
+		return rc;
+	}
+	physaddr = res.start;
+
+	/* irq */
+	irq = irq_of_parse_and_map(op->node, 0);
+
+	/* bus width */
+	bus_width = ACE_BUS_WIDTH_16;
+	if (of_find_property(op->node, "8-bit", NULL))
+		bus_width = ACE_BUS_WIDTH_8;
+
+	/* Call the bus-independant setup code */
+	return ace_alloc(&op->dev, id ? *id : 0, physaddr, irq, bus_width);
+}
+
+static int __devexit ace_of_remove(struct of_device *op)
+{
+	ace_free(&op->dev);
+	return 0;
+}
+
+/* Match table for of_platform binding */
+static struct of_device_id __devinit ace_of_match[] = {
+	{ .compatible = "xilinx,xsysace", },
+	{},
+};
+MODULE_DEVICE_TABLE(of, ace_of_match);
+
+static struct of_platform_driver ace_of_driver = {
+	.owner = THIS_MODULE,
+	.name = "xsysace",
+	.match_table = ace_of_match,
+	.probe = ace_of_probe,
+	.remove = __devexit_p(ace_of_remove),
+	.driver = {
+		.name = "xsysace",
+	},
+};
+
+/* Registration helpers to keep the number of #ifdefs to a minimum */
+static inline int __init ace_of_register(void)
+{
+	pr_debug("xsysace: registering OF binding\n");
+	return of_register_platform_driver(&ace_of_driver);
+}
+
+static inline void __exit ace_of_unregister(void)
+{
+	of_unregister_platform_driver(&ace_of_driver);
+}
+#else /* CONFIG_OF */
+/* CONFIG_OF not enabled; do nothing helpers */
+static inline int __init ace_of_register(void) { return 0; }
+static inline void __exit ace_of_unregister(void) { }
+#endif /* CONFIG_OF */
+
+/* ---------------------------------------------------------------------
  * Module init/exit routines
  */
 static int __init ace_init(void)
@@ -1170,6 +1253,9 @@ static int __init ace_init(void)
 		goto err_blk;
 	}
 
+	if ((rc = ace_of_register()) != 0)
+		goto err_of;
+
 	pr_debug("xsysace: registering platform binding\n");
 	if ((rc = platform_driver_register(&ace_platform_driver)) != 0)
 		goto err_plat;
@@ -1178,6 +1264,8 @@ static int __init ace_init(void)
 	return 0;
 
       err_plat:
+	ace_of_unregister();
+      err_of:
 	unregister_blkdev(ace_major, "xsysace");
       err_blk:
 	printk(KERN_ERR "xsysace: registration failed; err=%i\n", rc);
@@ -1188,6 +1276,7 @@ static void __exit ace_exit(void)
 {
 	pr_debug("Unregistering Xilinx SystemACE driver\n");
 	platform_driver_unregister(&ace_platform_driver);
+	ace_of_unregister();
 	unregister_blkdev(ace_major, "xsysace");
 }
 

^ permalink raw reply related

* [PATCH v2 5/6] Sysace: Move IRQ handler registration to occur after FSM is initialized
From: Grant Likely @ 2007-09-30 22:57 UTC (permalink / raw)
  To: linux-kernel, linuxppc-dev, paulus, axboe
In-Reply-To: <20070930225112.2476.49914.stgit@trillian.cg.shawcable.net>

From: Grant Likely <grant.likely@secretlab.ca>

The FSM needs to be initialized before it is safe to call the ISR

Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
---

 drivers/block/xsysace.c |   21 ++++++++++-----------
 1 files changed, 10 insertions(+), 11 deletions(-)

diff --git a/drivers/block/xsysace.c b/drivers/block/xsysace.c
index 10bb4e5..296d567 100644
--- a/drivers/block/xsysace.c
+++ b/drivers/block/xsysace.c
@@ -949,15 +949,6 @@ static int __devinit ace_setup(struct ace_device *ace)
 	if (!ace->baseaddr)
 		goto err_ioremap;
 
-	if (ace->irq != NO_IRQ) {
-		rc = request_irq(ace->irq, ace_interrupt, 0, "systemace", ace);
-		if (rc) {
-			/* Failure - fall back to polled mode */
-			dev_err(ace->dev, "request_irq failed\n");
-			ace->irq = NO_IRQ;
-		}
-	}
-
 	/*
 	 * Initialize the state machine tasklet and stall timer
 	 */
@@ -1015,6 +1006,16 @@ static int __devinit ace_setup(struct ace_device *ace)
 	val |= ACE_CTRL_DATABUFRDYIRQ | ACE_CTRL_ERRORIRQ;
 	ace_out(ace, ACE_CTRL, val);
 
+	/* Now we can hook up the irq handler */
+	if (ace->irq != NO_IRQ) {
+		rc = request_irq(ace->irq, ace_interrupt, 0, "systemace", ace);
+		if (rc) {
+			/* Failure - fall back to polled mode */
+			dev_err(ace->dev, "request_irq failed\n");
+			ace->irq = NO_IRQ;
+		}
+	}
+
 	/* Print the identification */
 	dev_info(ace->dev, "Xilinx SystemACE revision %i.%i.%i\n",
 		 (version >> 12) & 0xf, (version >> 8) & 0x0f, version & 0xff);
@@ -1035,8 +1036,6 @@ static int __devinit ace_setup(struct ace_device *ace)
 	blk_cleanup_queue(ace->queue);
       err_blk_initq:
 	iounmap(ace->baseaddr);
-	if (ace->irq != NO_IRQ)
-		free_irq(ace->irq, ace);
       err_ioremap:
 	dev_info(ace->dev, "xsysace: error initializing device at 0x%lx\n",
 	       ace->physaddr);

^ permalink raw reply related

* [PATCH v2 0/6] SystemACE: rework and of_platform bus binding patches
From: Grant Likely @ 2007-09-30 22:56 UTC (permalink / raw)
  To: linux-kernel, linuxppc-dev, paulus, axboe

Here is a set of rework patches on the Xilinx SystemACE driver which ends
in the addition of an of_platform bus binding.  The of_platform bus binding
is needed to use the driver from arch/powerpc.  SystemACE is most commonly
used in Xilinx Virtex system (ppc405).

Jens, I'm hoping I can get these changes in for 2.6.24.  Assuming nobody
raises any issues, can you please merge these into your tree?

Thanks,
g.

Grant Likely (6):
 Add Xilinx SystemACE entry to maintainers
 Sysace: Use the established platform bus api
 Sysace: Move structure allocation from bus binding into common code
 Sysace: minor rework and cleanup changes
 Sysace: Move IRQ handler registration to occur after FSM is initialized
 Sysace: Add of_platform_bus binding

 MAINTAINERS             |    7 ++
 drivers/block/xsysace.c |  249 +++++++++++++++++++++++++++++++++++-----------
       2 files changed, 196 insertions(+), 60 deletions(-)

--
Grant Likely, B.Sc. P.Eng.
Secret Lab Technologies Ltd.

^ permalink raw reply

* [PATCH v2 2/6] Sysace: Use the established platform bus api
From: Grant Likely @ 2007-09-30 22:57 UTC (permalink / raw)
  To: linux-kernel, linuxppc-dev, paulus, axboe
In-Reply-To: <20070930225112.2476.49914.stgit@trillian.cg.shawcable.net>

From: Grant Likely <grant.likely@secretlab.ca>

SystemACE uses the platform bus binding, but it doesn't use the
platform bus API.  Move to using the correct API for consistency
sake and future proofing against platform bus changes.

Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
---

 drivers/block/xsysace.c |   48 +++++++++++++++++++++++++++++------------------
 1 files changed, 30 insertions(+), 18 deletions(-)

diff --git a/drivers/block/xsysace.c b/drivers/block/xsysace.c
index 3ede0b6..b104476 100644
--- a/drivers/block/xsysace.c
+++ b/drivers/block/xsysace.c
@@ -1060,13 +1060,12 @@ static void __devexit ace_teardown(struct ace_device *ace)
  * Platform Bus Support
  */
 
-static int __devinit ace_probe(struct device *device)
+static int __devinit ace_probe(struct platform_device *dev)
 {
-	struct platform_device *dev = to_platform_device(device);
 	struct ace_device *ace;
 	int i;
 
-	dev_dbg(device, "ace_probe(%p)\n", device);
+	dev_dbg(&dev->dev, "ace_probe(%p)\n", dev);
 
 	/*
 	 * Allocate the ace device structure
@@ -1075,7 +1074,7 @@ static int __devinit ace_probe(struct device *device)
 	if (!ace)
 		goto err_alloc;
 
-	ace->dev = device;
+	ace->dev = &dev->dev;
 	ace->id = dev->id;
 	ace->irq = NO_IRQ;
 
@@ -1089,7 +1088,7 @@ static int __devinit ace_probe(struct device *device)
 	/* FIXME: Should get bus_width from the platform_device struct */
 	ace->bus_width = 1;
 
-	dev_set_drvdata(&dev->dev, ace);
+	platform_set_drvdata(dev, ace);
 
 	/* Call the bus-independant setup code */
 	if (ace_setup(ace) != 0)
@@ -1098,7 +1097,7 @@ static int __devinit ace_probe(struct device *device)
 	return 0;
 
       err_setup:
-	dev_set_drvdata(&dev->dev, NULL);
+	platform_set_drvdata(dev, NULL);
 	kfree(ace);
       err_alloc:
 	printk(KERN_ERR "xsysace: could not initialize device\n");
@@ -1108,25 +1107,27 @@ static int __devinit ace_probe(struct device *device)
 /*
  * Platform bus remove() method
  */
-static int __devexit ace_remove(struct device *device)
+static int __devexit ace_remove(struct platform_device *dev)
 {
-	struct ace_device *ace = dev_get_drvdata(device);
-
-	dev_dbg(device, "ace_remove(%p)\n", device);
+	struct ace_device *ace =  platform_get_drvdata(dev);
+	dev_dbg(&dev->dev, "ace_remove(%p)\n", dev);
 
 	if (ace) {
 		ace_teardown(ace);
+		platform_set_drvdata(dev, NULL);
 		kfree(ace);
 	}
 
 	return 0;
 }
 
-static struct device_driver ace_driver = {
-	.name = "xsysace",
-	.bus = &platform_bus_type,
+static struct platform_driver ace_platform_driver = {
 	.probe = ace_probe,
 	.remove = __devexit_p(ace_remove),
+	.driver = {
+		.owner = THIS_MODULE,
+		.name = "xsysace",
+	},
 };
 
 /* ---------------------------------------------------------------------
@@ -1134,20 +1135,31 @@ static struct device_driver ace_driver = {
  */
 static int __init ace_init(void)
 {
+	int rc;
+
 	ace_major = register_blkdev(ace_major, "xsysace");
 	if (ace_major <= 0) {
-		printk(KERN_WARNING "xsysace: register_blkdev() failed\n");
-		return ace_major;
+		rc = -ENOMEM;
+		goto err_blk;
 	}
 
-	pr_debug("Registering Xilinx SystemACE driver, major=%i\n", ace_major);
-	return driver_register(&ace_driver);
+	if ((rc = platform_driver_register(&ace_platform_driver)) != 0)
+		goto err_plat;
+
+	pr_info("Xilinx SystemACE device driver, major=%i\n", ace_major);
+	return 0;
+
+      err_plat:
+	unregister_blkdev(ace_major, "xsysace");
+      err_blk:
+	printk(KERN_ERR "xsysace: registration failed; err=%i\n", rc);
+	return rc;
 }
 
 static void __exit ace_exit(void)
 {
 	pr_debug("Unregistering Xilinx SystemACE driver\n");
-	driver_unregister(&ace_driver);
+	platform_driver_unregister(&ace_platform_driver);
 	unregister_blkdev(ace_major, "xsysace");
 }
 

^ permalink raw reply related

* [PATCH v2 3/6] Sysace: Move structure allocation from bus binding into common code
From: Grant Likely @ 2007-09-30 22:57 UTC (permalink / raw)
  To: linux-kernel, linuxppc-dev, paulus, axboe
In-Reply-To: <20070930225112.2476.49914.stgit@trillian.cg.shawcable.net>

From: Grant Likely <grant.likely@secretlab.ca>

Split the determination of device registers/irqs/etc from the actual
allocation and initialization of the device structure.  This cleans
up the code a bit in preparation to add an of_platform bus binding

Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
---

 drivers/block/xsysace.c |   99 +++++++++++++++++++++++++++++------------------
 1 files changed, 61 insertions(+), 38 deletions(-)

diff --git a/drivers/block/xsysace.c b/drivers/block/xsysace.c
index b104476..555939b 100644
--- a/drivers/block/xsysace.c
+++ b/drivers/block/xsysace.c
@@ -1033,7 +1033,7 @@ static int __devinit ace_setup(struct ace_device *ace)
 	if (ace->irq != NO_IRQ)
 		free_irq(ace->irq, ace);
       err_ioremap:
-	printk(KERN_INFO "xsysace: error initializing device at 0x%lx\n",
+	dev_info(ace->dev, "xsysace: error initializing device at 0x%lx\n",
 	       ace->physaddr);
 	return -ENOMEM;
 }
@@ -1056,68 +1056,91 @@ static void __devexit ace_teardown(struct ace_device *ace)
 	iounmap(ace->baseaddr);
 }
 
-/* ---------------------------------------------------------------------
- * Platform Bus Support
- */
-
-static int __devinit ace_probe(struct platform_device *dev)
+static int __devinit
+ace_alloc(struct device *dev, int id, unsigned long physaddr,
+	  int irq, int bus_width)
 {
 	struct ace_device *ace;
-	int i;
+	int rc;
+	dev_dbg(dev, "ace_alloc(%p)\n", dev);
 
-	dev_dbg(&dev->dev, "ace_probe(%p)\n", dev);
+	if (!physaddr) {
+		rc = -ENODEV;
+		goto err_noreg;
+	}
 
-	/*
-	 * Allocate the ace device structure
-	 */
+	/* Allocate and initialize the ace device structure */
 	ace = kzalloc(sizeof(struct ace_device), GFP_KERNEL);
-	if (!ace)
+	if (!ace) {
+		rc = -ENOMEM;
 		goto err_alloc;
-
-	ace->dev = &dev->dev;
-	ace->id = dev->id;
-	ace->irq = NO_IRQ;
-
-	for (i = 0; i < dev->num_resources; i++) {
-		if (dev->resource[i].flags & IORESOURCE_MEM)
-			ace->physaddr = dev->resource[i].start;
-		if (dev->resource[i].flags & IORESOURCE_IRQ)
-			ace->irq = dev->resource[i].start;
 	}
 
-	/* FIXME: Should get bus_width from the platform_device struct */
-	ace->bus_width = 1;
-
-	platform_set_drvdata(dev, ace);
+	ace->dev = dev;
+	ace->id = id;
+	ace->physaddr = physaddr;
+	ace->irq = irq;
+	ace->bus_width = bus_width;
 
-	/* Call the bus-independant setup code */
-	if (ace_setup(ace) != 0)
+	/* Call the setup code */
+	if ((rc = ace_setup(ace)) != 0)
 		goto err_setup;
 
+	dev_set_drvdata(dev, ace);
 	return 0;
 
       err_setup:
-	platform_set_drvdata(dev, NULL);
+	dev_set_drvdata(dev, NULL);
 	kfree(ace);
       err_alloc:
-	printk(KERN_ERR "xsysace: could not initialize device\n");
-	return -ENOMEM;
+      err_noreg:
+	dev_err(dev, "could not initialize device, err=%i\n", rc);
+	return rc;
 }
 
-/*
- * Platform bus remove() method
- */
-static int __devexit ace_remove(struct platform_device *dev)
+static void __devexit ace_free(struct device *dev)
 {
-	struct ace_device *ace =  platform_get_drvdata(dev);
-	dev_dbg(&dev->dev, "ace_remove(%p)\n", dev);
+	struct ace_device *ace = dev_get_drvdata(dev);
+	dev_dbg(dev, "ace_free(%p)\n", dev);
 
 	if (ace) {
 		ace_teardown(ace);
-		platform_set_drvdata(dev, NULL);
+		dev_set_drvdata(dev, NULL);
 		kfree(ace);
 	}
+}
+
+/* ---------------------------------------------------------------------
+ * Platform Bus Support
+ */
+
+static int __devinit ace_probe(struct platform_device *dev)
+{
+	unsigned long physaddr = 0;
+	int bus_width = 1; /* FIXME: should not be hard coded */
+	int id = dev->id;
+	int irq = NO_IRQ;
+	int i;
+
+	dev_dbg(&dev->dev, "ace_probe(%p)\n", dev);
+
+	for (i = 0; i < dev->num_resources; i++) {
+		if (dev->resource[i].flags & IORESOURCE_MEM)
+			physaddr = dev->resource[i].start;
+		if (dev->resource[i].flags & IORESOURCE_IRQ)
+			irq = dev->resource[i].start;
+	}
+
+	/* Call the bus-independant setup code */
+	return ace_alloc(&dev->dev, id, physaddr, irq, bus_width);
+}
 
+/*
+ * Platform bus remove() method
+ */
+static int __devexit ace_remove(struct platform_device *dev)
+{
+	ace_free(&dev->dev);
 	return 0;
 }
 

^ permalink raw reply related

* [PATCH v2 1/6] Add Xilinx SystemACE entry to maintainers
From: Grant Likely @ 2007-09-30 22:57 UTC (permalink / raw)
  To: linux-kernel, linuxppc-dev, paulus, axboe
In-Reply-To: <20070930225112.2476.49914.stgit@trillian.cg.shawcable.net>

From: Grant Likely <grant.likely@secretlab.ca>

I'm the author of the SystemACE driver

Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
---

 MAINTAINERS |    7 +++++++
 1 files changed, 7 insertions(+), 0 deletions(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index 8f80068..cb6323e 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -4179,6 +4179,13 @@ W:	http://oss.sgi.com/projects/xfs
 T:	git git://oss.sgi.com:8090/xfs/xfs-2.6.git
 S:	Supported
 
+XILINX SYSTEMACE DRIVER
+P:	Grant Likely
+M:	grant.likely@secretlab.ca
+W:	http://www.secretlab.ca/
+L:	linux-kernel@vger.kernel.org
+S:	Maintained
+
 XILINX UARTLITE SERIAL DRIVER
 P:	Peter Korsgaard
 M:	jacmet@sunsite.dk

^ permalink raw reply related

* [PATCH 2 6/7] Uartlite: Add of-platform-bus binding
From: Grant Likely @ 2007-09-30 22:42 UTC (permalink / raw)
  To: linuxppc-dev, jwboyer, jacmet
In-Reply-To: <20070930224117.1871.87164.stgit@trillian.cg.shawcable.net>

From: Grant Likely <grant.likely@secretlab.ca>

Add of_platform bus binding so this driver can be used with arch/powerpc

Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
---

 drivers/serial/uartlite.c |  101 +++++++++++++++++++++++++++++++++++++++++----
 1 files changed, 93 insertions(+), 8 deletions(-)

diff --git a/drivers/serial/uartlite.c b/drivers/serial/uartlite.c
index ed13b9f..8752fac 100644
--- a/drivers/serial/uartlite.c
+++ b/drivers/serial/uartlite.c
@@ -1,7 +1,8 @@
 /*
  * uartlite.c: Serial driver for Xilinx uartlite serial controller
  *
- * Peter Korsgaard <jacmet@sunsite.dk>
+ * Copyright (C) 2006 Peter Korsgaard <jacmet@sunsite.dk>
+ * Copyright (C) 2007 Secret Lab Technologies Ltd.
  *
  * This file is licensed under the terms of the GNU General Public License
  * version 2.  This program is licensed "as is" without any warranty of any
@@ -17,6 +18,10 @@
 #include <linux/delay.h>
 #include <linux/interrupt.h>
 #include <asm/io.h>
+#if defined(CONFIG_OF)
+#include <linux/of_device.h>
+#include <linux/of_platform.h>
+#endif
 
 #define ULITE_NAME		"ttyUL"
 #define ULITE_MAJOR		204
@@ -382,8 +387,10 @@ static int __init ulite_console_setup(struct console *co, char *options)
 	port = &ulite_ports[co->index];
 
 	/* not initialized yet? */
-	if (!port->membase)
+	if (!port->membase) {
+		pr_debug("console on ttyUL%i not initialized\n", co->index);
 		return -ENODEV;
+	}
 
 	if (options)
 		uart_parse_options(options, &baud, &parity, &bits, &flow);
@@ -542,6 +549,72 @@ static struct platform_driver ulite_platform_driver = {
 };
 
 /* ---------------------------------------------------------------------
+ * OF bus bindings
+ */
+#if defined(CONFIG_OF)
+static int __devinit
+ulite_of_probe(struct of_device *op, const struct of_device_id *match)
+{
+	struct resource res;
+	const unsigned int *id;
+	int irq, rc;
+
+	dev_dbg(&op->dev, "%s(%p, %p)\n", __FUNCTION__, op, match);
+
+	rc = of_address_to_resource(op->node, 0, &res);
+	if (rc) {
+		dev_err(&op->dev, "invalide address\n");
+		return rc;
+	}
+
+	irq = irq_of_parse_and_map(op->node, 0);
+
+	id = of_get_property(op->node, "port-number", NULL);
+
+	return ulite_assign(&op->dev, id ? *id : -1, res.start, irq);
+}
+
+static int __devexit ulite_of_remove(struct of_device *op)
+{
+	return ulite_release(&op->dev);
+}
+
+/* Match table for of_platform binding */
+static struct of_device_id __devinit ulite_of_match[] = {
+	{ .type = "serial", .compatible = "xilinx,uartlite", },
+	{},
+};
+MODULE_DEVICE_TABLE(of, ulite_of_match);
+
+static struct of_platform_driver ulite_of_driver = {
+	.owner = THIS_MODULE,
+	.name = "uartlite",
+	.match_table = ulite_of_match,
+	.probe = ulite_of_probe,
+	.remove = __devexit_p(ulite_of_remove),
+	.driver = {
+		.name = "uartlite",
+	},
+};
+
+/* Registration helpers to keep the number of #ifdefs to a minimum */
+static inline int __init ulite_of_register(void)
+{
+	pr_debug("uartlite: calling of_register_platform_driver()\n");
+	return of_register_platform_driver(&ulite_of_driver);
+}
+
+static inline void __exit ulite_of_unregister(void)
+{
+	of_unregister_platform_driver(&ulite_of_driver);
+}
+#else /* CONFIG_OF */
+/* CONFIG_OF not enabled; do nothing helpers */
+static inline int __init ulite_of_register(void) { return 0; }
+static inline void __exit ulite_of_unregister(void) { }
+#endif /* CONFIG_OF */
+
+/* ---------------------------------------------------------------------
  * Module setup/teardown
  */
 
@@ -549,20 +622,32 @@ int __init ulite_init(void)
 {
 	int ret;
 
-	ret = uart_register_driver(&ulite_uart_driver);
-	if (ret)
-		return ret;
+	pr_debug("uartlite: calling uart_register_driver()\n");
+	if ((ret = uart_register_driver(&ulite_uart_driver)) != 0)
+		goto err_uart;
 
-	ret = platform_driver_register(&ulite_platform_driver);
-	if (ret)
-		uart_unregister_driver(&ulite_uart_driver);
+	if ((ret = ulite_of_register()) != 0)
+		goto err_of;
 
+	pr_debug("uartlite: calling platform_driver_register()\n");
+	if ((ret = platform_driver_register(&ulite_platform_driver)) != 0)
+		goto err_plat;
+
+	return 0;
+
+err_plat:
+	ulite_of_unregister();
+err_of:
+	uart_unregister_driver(&ulite_uart_driver);
+err_uart:
+	printk(KERN_ERR "registering uartlite driver failed: err=%i", ret);
 	return ret;
 }
 
 void __exit ulite_exit(void)
 {
 	platform_driver_unregister(&ulite_platform_driver);
+	ulite_of_unregister();
 	uart_unregister_driver(&ulite_uart_driver);
 }
 

^ permalink raw reply related

* [PATCH 2 2/7] Uartlite: change name of ports to ulite_ports
From: Grant Likely @ 2007-09-30 22:41 UTC (permalink / raw)
  To: linuxppc-dev, jwboyer, jacmet
In-Reply-To: <20070930224117.1871.87164.stgit@trillian.cg.shawcable.net>

From: Grant Likely <grant.likely@secretlab.ca>

Changed to match naming convention used in the rest of the module

Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
---

 drivers/serial/uartlite.c |   10 +++++-----
 1 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/serial/uartlite.c b/drivers/serial/uartlite.c
index 59b674a..ae05a67 100644
--- a/drivers/serial/uartlite.c
+++ b/drivers/serial/uartlite.c
@@ -46,7 +46,7 @@
 #define ULITE_CONTROL_IE	0x10
 
 
-static struct uart_port ports[ULITE_NR_UARTS];
+static struct uart_port ulite_ports[ULITE_NR_UARTS];
 
 static int ulite_receive(struct uart_port *port, int stat)
 {
@@ -329,7 +329,7 @@ static void ulite_console_putchar(struct uart_port *port, int ch)
 static void ulite_console_write(struct console *co, const char *s,
 				unsigned int count)
 {
-	struct uart_port *port = &ports[co->index];
+	struct uart_port *port = &ulite_ports[co->index];
 	unsigned long flags;
 	unsigned int ier;
 	int locked = 1;
@@ -366,7 +366,7 @@ static int __init ulite_console_setup(struct console *co, char *options)
 	if (co->index < 0 || co->index >= ULITE_NR_UARTS)
 		return -EINVAL;
 
-	port = &ports[co->index];
+	port = &ulite_ports[co->index];
 
 	/* not initialized yet? */
 	if (!port->membase)
@@ -420,7 +420,7 @@ static int __devinit ulite_probe(struct platform_device *pdev)
 	if (pdev->id < 0 || pdev->id >= ULITE_NR_UARTS)
 		return -EINVAL;
 
-	if (ports[pdev->id].membase)
+	if (ulite_ports[pdev->id].membase)
 		return -EBUSY;
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -431,7 +431,7 @@ static int __devinit ulite_probe(struct platform_device *pdev)
 	if (!res2)
 		return -ENODEV;
 
-	port = &ports[pdev->id];
+	port = &ulite_ports[pdev->id];
 
 	port->fifosize	= 16;
 	port->regshift	= 2;

^ permalink raw reply related

* [PATCH 2 7/7] Uartlite: Let the console be initialized earlier
From: Grant Likely @ 2007-09-30 22:42 UTC (permalink / raw)
  To: linuxppc-dev, jwboyer, jacmet
In-Reply-To: <20070930224117.1871.87164.stgit@trillian.cg.shawcable.net>

From: Grant Likely <grant.likely@secretlab.ca>

By configuring it earlier we get console output sooner which is helpful
for debugging when the kernel crashes before the serial drivers are
initialized.

Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
---

 drivers/serial/uartlite.c |   41 ++++++++++++++++++++++++++++++++++++++---
 1 files changed, 38 insertions(+), 3 deletions(-)

diff --git a/drivers/serial/uartlite.c b/drivers/serial/uartlite.c
index 8752fac..a1891d9 100644
--- a/drivers/serial/uartlite.c
+++ b/drivers/serial/uartlite.c
@@ -373,6 +373,31 @@ static void ulite_console_write(struct console *co, const char *s,
 		spin_unlock_irqrestore(&port->lock, flags);
 }
 
+#if defined(CONFIG_OF)
+static inline void __init ulite_console_of_find_device(int id)
+{
+	struct device_node *np;
+	struct resource res;
+	const unsigned int *of_id;
+	int rc;
+
+	for_each_compatible_node(np, NULL, "xilinx,uartlite") {
+		of_id = of_get_property(np, "port-number", NULL);
+		if ((!of_id) || (*of_id != id))
+			continue;
+
+		rc = of_address_to_resource(np, 0, &res);
+		if (rc)
+			continue;
+
+		ulite_ports[id].mapbase = res.start;
+		return;
+	}
+}
+#else /* CONFIG_OF */
+static inline void __init ulite_console_of_find_device(int id) { /* do nothing */ }
+#endif /* CONFIG_OF */
+
 static int __init ulite_console_setup(struct console *co, char *options)
 {
 	struct uart_port *port;
@@ -386,10 +411,20 @@ static int __init ulite_console_setup(struct console *co, char *options)
 
 	port = &ulite_ports[co->index];
 
+	/* Check if it is an OF device */
+	if (!port->mapbase)
+		ulite_console_of_find_device(co->index);
+
+	/* Do we have a device now? */
+	if (!port->mapbase) {
+		pr_debug("console on ttyUL%i not present\n", co->index);
+		return -ENODEV;
+	}
+
 	/* not initialized yet? */
 	if (!port->membase) {
-		pr_debug("console on ttyUL%i not initialized\n", co->index);
-		return -ENODEV;
+		if (ulite_request_port(port))
+			return -ENODEV;
 	}
 
 	if (options)
@@ -461,7 +496,7 @@ static int __devinit ulite_assign(struct device *dev, int id, u32 base, int irq)
 		return -EINVAL;
 	}
 
-	if (ulite_ports[id].mapbase) {
+	if ((ulite_ports[id].mapbase) && (ulite_ports[id].mapbase != base)) {
 		dev_err(dev, "cannot assign to %s%i; it is already in use\n",
 			ULITE_NAME, id);
 		return -EBUSY;

^ permalink raw reply related

* [PATCH 2 5/7] Uartlite: Comment block tidy
From: Grant Likely @ 2007-09-30 22:42 UTC (permalink / raw)
  To: linuxppc-dev, jwboyer, jacmet
In-Reply-To: <20070930224117.1871.87164.stgit@trillian.cg.shawcable.net>

From: Grant Likely <grant.likely@secretlab.ca>

Tidy the comments to split the driver into logical section; the main driver,
the console driver, the platform bus binding, and module initialization
and teardown.

Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
---

 drivers/serial/uartlite.c |   43 ++++++++++++++++++++++++++++++++++++++++---
 1 files changed, 40 insertions(+), 3 deletions(-)

diff --git a/drivers/serial/uartlite.c b/drivers/serial/uartlite.c
index c00a627..ed13b9f 100644
--- a/drivers/serial/uartlite.c
+++ b/drivers/serial/uartlite.c
@@ -23,9 +23,13 @@
 #define ULITE_MINOR		187
 #define ULITE_NR_UARTS		4
 
-/* For register details see datasheet:
-   http://www.xilinx.com/bvdocs/ipcenter/data_sheet/opb_uartlite.pdf
-*/
+/* ---------------------------------------------------------------------
+ * Register definitions
+ *
+ * For register details see datasheet:
+ * http://www.xilinx.com/bvdocs/ipcenter/data_sheet/opb_uartlite.pdf
+ */
+
 #define ULITE_RX		0x00
 #define ULITE_TX		0x04
 #define ULITE_STATUS		0x08
@@ -49,6 +53,10 @@
 
 static struct uart_port ulite_ports[ULITE_NR_UARTS];
 
+/* ---------------------------------------------------------------------
+ * Core UART driver operations
+ */
+
 static int ulite_receive(struct uart_port *port, int stat)
 {
 	struct tty_struct *tty = port->info->tty;
@@ -308,6 +316,10 @@ static struct uart_ops ulite_ops = {
 	.verify_port	= ulite_verify_port
 };
 
+/* ---------------------------------------------------------------------
+ * Console driver operations
+ */
+
 #ifdef CONFIG_SERIAL_UARTLITE_CONSOLE
 static void ulite_console_wait_tx(struct uart_port *port)
 {
@@ -413,6 +425,19 @@ static struct uart_driver ulite_uart_driver = {
 #endif
 };
 
+/* ---------------------------------------------------------------------
+ * Port assignment functions (mapping devices to uart_port structures)
+ */
+
+/** ulite_assign: register a uartlite device with the driver
+ *
+ * @dev: pointer to device structure
+ * @id: requested id number.  Pass -1 for automatic port assignment
+ * @base: base address of uartlite registers
+ * @irq: irq number for uartlite
+ *
+ * Returns: 0 on success, <0 otherwise
+ */
 static int __devinit ulite_assign(struct device *dev, int id, u32 base, int irq)
 {
 	struct uart_port *port;
@@ -465,6 +490,10 @@ static int __devinit ulite_assign(struct device *dev, int id, u32 base, int irq)
 	return 0;
 }
 
+/** ulite_release: register a uartlite device with the driver
+ *
+ * @dev: pointer to device structure
+ */
 static int __devinit ulite_release(struct device *dev)
 {
 	struct uart_port *port = dev_get_drvdata(dev);
@@ -479,6 +508,10 @@ static int __devinit ulite_release(struct device *dev)
 	return rc;
 }
 
+/* ---------------------------------------------------------------------
+ * Platform bus binding
+ */
+
 static int __devinit ulite_probe(struct platform_device *pdev)
 {
 	struct resource *res, *res2;
@@ -508,6 +541,10 @@ static struct platform_driver ulite_platform_driver = {
 		   },
 };
 
+/* ---------------------------------------------------------------------
+ * Module setup/teardown
+ */
+
 int __init ulite_init(void)
 {
 	int ret;

^ permalink raw reply related

* [PATCH 2 4/7] Uartlite: Separate the bus binding from the driver proper
From: Grant Likely @ 2007-09-30 22:41 UTC (permalink / raw)
  To: linuxppc-dev, jwboyer, jacmet
In-Reply-To: <20070930224117.1871.87164.stgit@trillian.cg.shawcable.net>

From: Grant Likely <grant.likely@secretlab.ca>

Separate the bus binding code from the driver structure allocation code in
preparation for adding the of_platform_bus bindings needed by arch/powerpc

Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
---

 drivers/serial/uartlite.c |   99 ++++++++++++++++++++++++++++++---------------
 1 files changed, 65 insertions(+), 34 deletions(-)

diff --git a/drivers/serial/uartlite.c b/drivers/serial/uartlite.c
index 10e0da9..c00a627 100644
--- a/drivers/serial/uartlite.c
+++ b/drivers/serial/uartlite.c
@@ -413,59 +413,90 @@ static struct uart_driver ulite_uart_driver = {
 #endif
 };
 
-static int __devinit ulite_probe(struct platform_device *pdev)
+static int __devinit ulite_assign(struct device *dev, int id, u32 base, int irq)
 {
-	struct resource *res, *res2;
 	struct uart_port *port;
+	int rc;
 
-	if (pdev->id < 0 || pdev->id >= ULITE_NR_UARTS)
+	/* if id = -1; then scan for a free id and use that */
+	if (id < 0) {
+		for (id = 0; id < ULITE_NR_UARTS; id++)
+			if (ulite_ports[id].mapbase == 0)
+				break;
+	}
+	if (id < 0 || id >= ULITE_NR_UARTS) {
+		dev_err(dev, "%s%i too large\n", ULITE_NAME, id);
 		return -EINVAL;
+	}
 
-	if (ulite_ports[pdev->id].membase)
+	if (ulite_ports[id].mapbase) {
+		dev_err(dev, "cannot assign to %s%i; it is already in use\n",
+			ULITE_NAME, id);
 		return -EBUSY;
+	}
 
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	if (!res)
-		return -ENODEV;
+	port = &ulite_ports[id];
 
-	res2 = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
-	if (!res2)
-		return -ENODEV;
+	spin_lock_init(&port->lock);
+	port->fifosize = 16;
+	port->regshift = 2;
+	port->iotype = UPIO_MEM;
+	port->iobase = 1; /* mark port in use */
+	port->mapbase = base;
+	port->membase = NULL;
+	port->ops = &ulite_ops;
+	port->irq = irq;
+	port->flags = UPF_BOOT_AUTOCONF;
+	port->dev = dev;
+	port->type = PORT_UNKNOWN;
+	port->line = id;
+
+	dev_set_drvdata(dev, port);
+
+	/* Register the port */
+	rc = uart_add_one_port(&ulite_uart_driver, port);
+	if (rc) {
+		dev_err(dev, "uart_add_one_port() failed; err=%i\n", rc);
+		port->mapbase = 0;
+		dev_set_drvdata(dev, NULL);
+		return rc;
+	}
 
-	port = &ulite_ports[pdev->id];
+	return 0;
+}
 
-	port->fifosize	= 16;
-	port->regshift	= 2;
-	port->iotype	= UPIO_MEM;
-	port->iobase	= 1; /* mark port in use */
-	port->mapbase	= res->start;
-	port->membase	= NULL;
-	port->ops	= &ulite_ops;
-	port->irq	= res2->start;
-	port->flags	= UPF_BOOT_AUTOCONF;
-	port->dev	= &pdev->dev;
-	port->type	= PORT_UNKNOWN;
-	port->line	= pdev->id;
+static int __devinit ulite_release(struct device *dev)
+{
+	struct uart_port *port = dev_get_drvdata(dev);
+	int rc = 0;
 
-	uart_add_one_port(&ulite_uart_driver, port);
-	platform_set_drvdata(pdev, port);
+	if (port) {
+		rc = uart_remove_one_port(&ulite_uart_driver, port);
+		dev_set_drvdata(dev, NULL);
+		port->mapbase = 0;
+	}
 
-	return 0;
+	return rc;
 }
 
-static int ulite_remove(struct platform_device *pdev)
+static int __devinit ulite_probe(struct platform_device *pdev)
 {
-	struct uart_port *port = platform_get_drvdata(pdev);
+	struct resource *res, *res2;
 
-	platform_set_drvdata(pdev, NULL);
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res)
+		return -ENODEV;
 
-	if (port)
-		uart_remove_one_port(&ulite_uart_driver, port);
+	res2 = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+	if (!res2)
+		return -ENODEV;
 
-	/* mark port as free */
-	port->membase = NULL;
+	return ulite_assign(&pdev->dev, pdev->id, res->start, res2->start);
+}
 
-	return 0;
+static int ulite_remove(struct platform_device *pdev)
+{
+	return ulite_release(&pdev->dev);
 }
 
 static struct platform_driver ulite_platform_driver = {

^ permalink raw reply related

* [PATCH 2 3/7] Uartlite: Add macro for uartlite device name
From: Grant Likely @ 2007-09-30 22:41 UTC (permalink / raw)
  To: linuxppc-dev, jwboyer, jacmet
In-Reply-To: <20070930224117.1871.87164.stgit@trillian.cg.shawcable.net>

From: Grant Likely <grant.likely@secretlab.ca>

Changed to make the following OF_platform bus binding patch a wee bit cleaner

Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
---

 drivers/serial/uartlite.c |    5 +++--
 1 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/serial/uartlite.c b/drivers/serial/uartlite.c
index ae05a67..10e0da9 100644
--- a/drivers/serial/uartlite.c
+++ b/drivers/serial/uartlite.c
@@ -18,6 +18,7 @@
 #include <linux/interrupt.h>
 #include <asm/io.h>
 
+#define ULITE_NAME		"ttyUL"
 #define ULITE_MAJOR		204
 #define ULITE_MINOR		187
 #define ULITE_NR_UARTS		4
@@ -381,7 +382,7 @@ static int __init ulite_console_setup(struct console *co, char *options)
 static struct uart_driver ulite_uart_driver;
 
 static struct console ulite_console = {
-	.name	= "ttyUL",
+	.name	= ULITE_NAME,
 	.write	= ulite_console_write,
 	.device	= uart_console_device,
 	.setup	= ulite_console_setup,
@@ -403,7 +404,7 @@ console_initcall(ulite_console_init);
 static struct uart_driver ulite_uart_driver = {
 	.owner		= THIS_MODULE,
 	.driver_name	= "uartlite",
-	.dev_name	= "ttyUL",
+	.dev_name	= ULITE_NAME,
 	.major		= ULITE_MAJOR,
 	.minor		= ULITE_MINOR,
 	.nr		= ULITE_NR_UARTS,

^ permalink raw reply related

* [PATCH 2 1/7] Uartlite: Fix reg io to access documented register size
From: Grant Likely @ 2007-09-30 22:41 UTC (permalink / raw)
  To: linuxppc-dev, jwboyer, jacmet

From: Grant Likely <grant.likely@secretlab.ca>

The Uartlite data sheet defines the registers as 32 bit wide.  This
patch changes the register access to use 32 bit transfers and eliminates
the magic +3 offset which is currently required to make the device
work.

Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
Acked-by: John Williams <jwilliams@itee.uq.edu.au>
---

 arch/ppc/syslib/virtex_devices.c |    2 +-
 drivers/serial/uartlite.c        |   32 ++++++++++++++++----------------
 2 files changed, 17 insertions(+), 17 deletions(-)

diff --git a/arch/ppc/syslib/virtex_devices.c b/arch/ppc/syslib/virtex_devices.c
index ace4ec0..270ad3a 100644
--- a/arch/ppc/syslib/virtex_devices.c
+++ b/arch/ppc/syslib/virtex_devices.c
@@ -28,7 +28,7 @@
 	.num_resources = 2, \
 	.resource = (struct resource[]) { \
 		{ \
-			.start = XPAR_UARTLITE_##num##_BASEADDR + 3, \
+			.start = XPAR_UARTLITE_##num##_BASEADDR, \
 			.end = XPAR_UARTLITE_##num##_HIGHADDR, \
 			.flags = IORESOURCE_MEM, \
 		}, \
diff --git a/drivers/serial/uartlite.c b/drivers/serial/uartlite.c
index f5051cf..59b674a 100644
--- a/drivers/serial/uartlite.c
+++ b/drivers/serial/uartlite.c
@@ -61,7 +61,7 @@ static int ulite_receive(struct uart_port *port, int stat)
 	/* stats */
 	if (stat & ULITE_STATUS_RXVALID) {
 		port->icount.rx++;
-		ch = readb(port->membase + ULITE_RX);
+		ch = in_be32((void*)port->membase + ULITE_RX);
 
 		if (stat & ULITE_STATUS_PARITY)
 			port->icount.parity++;
@@ -106,7 +106,7 @@ static int ulite_transmit(struct uart_port *port, int stat)
 		return 0;
 
 	if (port->x_char) {
-		writeb(port->x_char, port->membase + ULITE_TX);
+		out_be32((void*)port->membase + ULITE_TX, port->x_char);
 		port->x_char = 0;
 		port->icount.tx++;
 		return 1;
@@ -115,7 +115,7 @@ static int ulite_transmit(struct uart_port *port, int stat)
 	if (uart_circ_empty(xmit) || uart_tx_stopped(port))
 		return 0;
 
-	writeb(xmit->buf[xmit->tail], port->membase + ULITE_TX);
+	out_be32((void*)port->membase + ULITE_TX, xmit->buf[xmit->tail]);
 	xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE-1);
 	port->icount.tx++;
 
@@ -132,7 +132,7 @@ static irqreturn_t ulite_isr(int irq, void *dev_id)
 	int busy;
 
 	do {
-		int stat = readb(port->membase + ULITE_STATUS);
+		int stat = in_be32((void*)port->membase + ULITE_STATUS);
 		busy  = ulite_receive(port, stat);
 		busy |= ulite_transmit(port, stat);
 	} while (busy);
@@ -148,7 +148,7 @@ static unsigned int ulite_tx_empty(struct uart_port *port)
 	unsigned int ret;
 
 	spin_lock_irqsave(&port->lock, flags);
-	ret = readb(port->membase + ULITE_STATUS);
+	ret = in_be32((void*)port->membase + ULITE_STATUS);
 	spin_unlock_irqrestore(&port->lock, flags);
 
 	return ret & ULITE_STATUS_TXEMPTY ? TIOCSER_TEMT : 0;
@@ -171,7 +171,7 @@ static void ulite_stop_tx(struct uart_port *port)
 
 static void ulite_start_tx(struct uart_port *port)
 {
-	ulite_transmit(port, readb(port->membase + ULITE_STATUS));
+	ulite_transmit(port, in_be32((void*)port->membase + ULITE_STATUS));
 }
 
 static void ulite_stop_rx(struct uart_port *port)
@@ -200,17 +200,17 @@ static int ulite_startup(struct uart_port *port)
 	if (ret)
 		return ret;
 
-	writeb(ULITE_CONTROL_RST_RX | ULITE_CONTROL_RST_TX,
-	       port->membase + ULITE_CONTROL);
-	writeb(ULITE_CONTROL_IE, port->membase + ULITE_CONTROL);
+	out_be32((void*)port->membase + ULITE_CONTROL,
+	         ULITE_CONTROL_RST_RX | ULITE_CONTROL_RST_TX);
+	out_be32((void*)port->membase + ULITE_CONTROL, ULITE_CONTROL_IE);
 
 	return 0;
 }
 
 static void ulite_shutdown(struct uart_port *port)
 {
-	writeb(0, port->membase + ULITE_CONTROL);
-	readb(port->membase + ULITE_CONTROL); /* dummy */
+	out_be32((void*)port->membase + ULITE_CONTROL, 0);
+	in_be32((void*)port->membase + ULITE_CONTROL); /* dummy */
 	free_irq(port->irq, port);
 }
 
@@ -314,7 +314,7 @@ static void ulite_console_wait_tx(struct uart_port *port)
 
 	/* wait up to 10ms for the character(s) to be sent */
 	for (i = 0; i < 10000; i++) {
-		if (readb(port->membase + ULITE_STATUS) & ULITE_STATUS_TXEMPTY)
+		if (in_be32((void*)port->membase + ULITE_STATUS) & ULITE_STATUS_TXEMPTY)
 			break;
 		udelay(1);
 	}
@@ -323,7 +323,7 @@ static void ulite_console_wait_tx(struct uart_port *port)
 static void ulite_console_putchar(struct uart_port *port, int ch)
 {
 	ulite_console_wait_tx(port);
-	writeb(ch, port->membase + ULITE_TX);
+	out_be32((void*)port->membase + ULITE_TX, ch);
 }
 
 static void ulite_console_write(struct console *co, const char *s,
@@ -340,8 +340,8 @@ static void ulite_console_write(struct console *co, const char *s,
 		spin_lock_irqsave(&port->lock, flags);
 
 	/* save and disable interrupt */
-	ier = readb(port->membase + ULITE_STATUS) & ULITE_STATUS_IE;
-	writeb(0, port->membase + ULITE_CONTROL);
+	ier = in_be32((void*)port->membase + ULITE_STATUS) & ULITE_STATUS_IE;
+	out_be32((void*)port->membase + ULITE_CONTROL, 0);
 
 	uart_console_write(port, s, count, ulite_console_putchar);
 
@@ -349,7 +349,7 @@ static void ulite_console_write(struct console *co, const char *s,
 
 	/* restore interrupt state */
 	if (ier)
-		writeb(ULITE_CONTROL_IE, port->membase + ULITE_CONTROL);
+		out_be32((void*)port->membase + ULITE_CONTROL, ULITE_CONTROL_IE);
 
 	if (locked)
 		spin_unlock_irqrestore(&port->lock, flags);

^ permalink raw reply related

* [PATCHv2 4/4] Virtex: Add generic Xilinx Virtex board support
From: Grant Likely @ 2007-09-30 22:20 UTC (permalink / raw)
  To: linuxppc-dev, jwboyer
In-Reply-To: <20070930221613.583.252.stgit@trillian.cg.shawcable.net>

From: Grant Likely <grant.likely@secretlab.ca>

Adds support for generic Xilinx Virtex boards.  Any board which specifies
"xilinx,virtex" in the compatible property will make use of this board
support.

Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
---

 arch/powerpc/platforms/40x/Makefile |    1 +
 arch/powerpc/platforms/40x/virtex.c |   50 +++++++++++++++++++++++++++++++++++
 2 files changed, 51 insertions(+), 0 deletions(-)

diff --git a/arch/powerpc/platforms/40x/Makefile b/arch/powerpc/platforms/40x/Makefile
index e6c0bbd..0a3cfe9 100644
--- a/arch/powerpc/platforms/40x/Makefile
+++ b/arch/powerpc/platforms/40x/Makefile
@@ -1 +1,2 @@
 obj-$(CONFIG_WALNUT) += walnut.o
+obj-$(CONFIG_XILINX_VIRTEX_GENERIC_BOARD) += virtex.o
diff --git a/arch/powerpc/platforms/40x/virtex.c b/arch/powerpc/platforms/40x/virtex.c
new file mode 100644
index 0000000..ede982c
--- /dev/null
+++ b/arch/powerpc/platforms/40x/virtex.c
@@ -0,0 +1,50 @@
+/*
+ * Xilinx Virtex (IIpro & 4FX) based board support
+ *
+ * Copyright 2007 Secret Lab Technologies Ltd.
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+#include <linux/init.h>
+#include <asm/machdep.h>
+#include <asm/prom.h>
+#include <asm/time.h>
+#include <asm/xilinx_intc.h>
+#include <asm/of_platform.h>
+
+static int __init virtex_device_probe(void)
+{
+	if (!machine_is(virtex))
+		return 0;
+
+	of_platform_bus_probe(NULL, NULL, NULL);
+
+	return 0;
+}
+device_initcall(virtex_device_probe);
+
+static int __init virtex_probe(void)
+{
+	unsigned long root = of_get_flat_dt_root();
+
+	if (!of_flat_dt_is_compatible(root, "xilinx,virtex"))
+		return 0;
+
+	return 1;
+}
+
+static void __init virtex_setup_arch(void)
+{
+}
+
+define_machine(virtex) {
+	.name			= "Xilinx Virtex",
+	.probe			= virtex_probe,
+	.setup_arch		= virtex_setup_arch,
+	.init_IRQ		= xilinx_intc_init_tree,
+	.get_irq		= xilinx_intc_get_irq,
+	.calibrate_decr		= generic_calibrate_decr,
+};

^ permalink raw reply related


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