* Question on supporting multiple HW versions with a single driver (warning: long post)
@ 2011-02-02 21:57 Bruce_Leonard
2011-02-08 2:16 ` David Gibson
0 siblings, 1 reply; 5+ messages in thread
From: Bruce_Leonard @ 2011-02-02 21:57 UTC (permalink / raw)
To: linuxppc-dev
So this is sort of a follow on question to one I posted a month ago about
trying to get a PCI driver to work with OF (which I think I more or less
understood the answer to). I'm encountering a different sort of problem
that I'd like to solve with OF but I'm not sure I can. Let me lay out a
little background first.
We build embedded systems, so we never really have hot plug events and our
addresses (at least for HW interfaces) are pretty much static for any
given product. In other words for product "A" the NAND controller will
always be at address "X", though on product "B" that same NAND controller
may be at address "Y". Also, the devices in the product are static, i.e.,
we'll always talk to an LXT971 as the PHY.
Currently I'm working on building a driver for an ethernet MAC we're
putting in an FPGA. The MAC is based on the MPC8347 TSEC and the driver
is based on the gianfar driver. (My previous question was how to spoof
the OF gianfar driver into thinking it was a PCI driver because our MAC is
going to be hanging off a PCI bus. Ultimately I decided to just
steal...err...borrow... the guts of the gianfar driver and make it a PCI
driver that only deals with our MAC.)
Right in the middle of writing this driver, my HW guys came to me and said
they wanted to use this same MAC in other products. Great I said. Local
bus they said. Which opens up a whole can of worms and leads to my
question. We've got a MAC in a FPGA with a nice generic interface on the
front of it that can talk to a whole range of different busses, PCI, PCIe,
local bus (of any variety of any processor), etc. But the internals of
the MAC (i.e., the register sets, the buffers, the whole buffer descriptor
mechanism) all looks the same. Seems to me that this is exactly the sort
of situation OF and device trees was developed for.
What I'd like to do, and I'm sure it's possible but I have no idea how, is
to still have this as an OF driver and have the device tree tell the
kernel about the HW interface to use. So on one product (currently all
products use an MCP83xx variant) I would have a child node under a PCI
node to describe it's interrupts, addressing (which could also come from a
PCI probe I expect), compatibility, any attached PHYs etc, and on a second
product do the same thing under a localbus node.
First question that comes to mind is ordering. If I put a child node in
the PCI node of the device tree, what happens when the device tree is
processed? Is it immediately going to try and find and install a driver
for that child node? Since the device tree is processed very early, the
PCI bus isn't going to be set up and available yet. Will trying to
install a PCI driver via OF even be possible at this point? Then I'd
still need a PCI function to claim the device when the PCI bus gets
probed. If the driver is already installed via OF, what does the PCI
function do?
Or am I all backwards. Does having the child node to the PCI node
actually do anything when the early OF code runs? If not would the PCI
probe function be the first indication to the system that the driver needs
to be loaded? In which case I just walk the device tree looking
for...what? How would I match up the PCI ID with something in the device
tree?
Then there's the local bus side of the question? That should truly be an
OF driver and use struct of_platform_driver along with that whole
mechanism. How do I make that compatible with the version of the MAC that
runs on PCI?
Or am I making a whole lot of work for myself and I should just make them
separate drivers? I'm trying to keep the code base as small and coherent
as possible. I don't want to have to maintain multiple copies of a driver
that are essentially identical.
Thanks.
Bruce
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: Question on supporting multiple HW versions with a single driver (warning: long post)
2011-02-02 21:57 Question on supporting multiple HW versions with a single driver (warning: long post) Bruce_Leonard
@ 2011-02-08 2:16 ` David Gibson
2011-02-08 2:37 ` Bruce_Leonard
0 siblings, 1 reply; 5+ messages in thread
From: David Gibson @ 2011-02-08 2:16 UTC (permalink / raw)
To: Bruce_Leonard; +Cc: linuxppc-dev
On Wed, Feb 02, 2011 at 01:57:13PM -0800, Bruce_Leonard@selinc.com wrote:
> So this is sort of a follow on question to one I posted a month ago about
> trying to get a PCI driver to work with OF (which I think I more or less
> understood the answer to). I'm encountering a different sort of problem
> that I'd like to solve with OF but I'm not sure I can. Let me lay out a
> little background first.
>
> We build embedded systems, so we never really have hot plug events and our
> addresses (at least for HW interfaces) are pretty much static for any
> given product. In other words for product "A" the NAND controller will
> always be at address "X", though on product "B" that same NAND controller
> may be at address "Y". Also, the devices in the product are static, i.e.,
> we'll always talk to an LXT971 as the PHY.
>
> Currently I'm working on building a driver for an ethernet MAC we're
> putting in an FPGA. The MAC is based on the MPC8347 TSEC and the driver
> is based on the gianfar driver. (My previous question was how to spoof
> the OF gianfar driver into thinking it was a PCI driver because our MAC is
> going to be hanging off a PCI bus. Ultimately I decided to just
> steal...err...borrow... the guts of the gianfar driver and make it a PCI
> driver that only deals with our MAC.)
>
> Right in the middle of writing this driver, my HW guys came to me and said
> they wanted to use this same MAC in other products. Great I said. Local
> bus they said. Which opens up a whole can of worms and leads to my
> question. We've got a MAC in a FPGA with a nice generic interface on the
> front of it that can talk to a whole range of different busses, PCI, PCIe,
> local bus (of any variety of any processor), etc. But the internals of
> the MAC (i.e., the register sets, the buffers, the whole buffer descriptor
> mechanism) all looks the same. Seems to me that this is exactly the sort
> of situation OF and device trees was developed for.
>
> What I'd like to do, and I'm sure it's possible but I have no idea how, is
> to still have this as an OF driver and have the device tree tell the
> kernel about the HW interface to use. So on one product (currently all
> products use an MCP83xx variant) I would have a child node under a PCI
> node to describe it's interrupts, addressing (which could also come from a
> PCI probe I expect), compatibility, any attached PHYs etc, and on a second
> product do the same thing under a localbus node.
>
> First question that comes to mind is ordering. If I put a child node in
> the PCI node of the device tree, what happens when the device tree is
> processed? Is it immediately going to try and find and install a driver
> for that child node? Since the device tree is processed very early, the
> PCI bus isn't going to be set up and available yet. Will trying to
> install a PCI driver via OF even be possible at this point? Then I'd
> still need a PCI function to claim the device when the PCI bus gets
> probed. If the driver is already installed via OF, what does the PCI
> function do?
>
> Or am I all backwards. Does having the child node to the PCI node
> actually do anything when the early OF code runs? If not would the PCI
> probe function be the first indication to the system that the driver needs
> to be loaded? In which case I just walk the device tree looking
> for...what? How would I match up the PCI ID with something in the device
> tree?
>
> Then there's the local bus side of the question? That should truly be an
> OF driver and use struct of_platform_driver along with that whole
> mechanism. How do I make that compatible with the version of the MAC that
> runs on PCI?
>
> Or am I making a whole lot of work for myself and I should just make them
> separate drivers? I'm trying to keep the code base as small and coherent
> as possible. I don't want to have to maintain multiple copies of a driver
> that are essentially identical.
No, you shouldn't need multiple drivers. However, what you will want
is two sets of bus binding "glue" for the one driver. The driver
proper won't directly advertise a struct driver, but will provide some
sort of explicit init/probe function with enough information to set up
the device on either PCI or localbus.
Then you have a PCI bus binding which advertises to the driver model
as a PCI driver, and when probed does any PCI specific magic then
instantiates the core driver in the right way based on the information
obtained from the PCI system.
A second bus binding advertises as a platform[*] driver and when
probed instantiates the core driver based on the platform device
information.
There are a number of drivers which already have this sort of dual bus
binding.
[*] of_platform_driver is now deprecated - the whole concept was
based on a flawed conceptual model which causes problems in, amongst
others, exactly this case. The new approach is to have a platform
device structure which is created automatically during device tree
scanning. This also makes it easier to have a single driver (and
binding) which will work both on device-tree-based and non
device-tree-based platforms.
--
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 [flat|nested] 5+ messages in thread
* Re: Question on supporting multiple HW versions with a single driver (warning: long post)
2011-02-08 2:16 ` David Gibson
@ 2011-02-08 2:37 ` Bruce_Leonard
2011-02-08 5:13 ` Bill Gatliff
0 siblings, 1 reply; 5+ messages in thread
From: Bruce_Leonard @ 2011-02-08 2:37 UTC (permalink / raw)
To: David Gibson; +Cc: linuxppc-dev
>
> There are a number of drivers which already have this sort of dual bus
> binding.
>
Thanks for the feedback David, I appreciate it. Could you point me to one
of those drivers that has "this sort of dual bus binding" so can see an
example of what I'm trying to do?
Bruce
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: Question on supporting multiple HW versions with a single driver (warning: long post)
2011-02-08 2:37 ` Bruce_Leonard
@ 2011-02-08 5:13 ` Bill Gatliff
2011-02-08 16:59 ` Bruce_Leonard
0 siblings, 1 reply; 5+ messages in thread
From: Bill Gatliff @ 2011-02-08 5:13 UTC (permalink / raw)
To: Bruce_Leonard; +Cc: linuxppc-dev, David Gibson
Guys:
I think the Silicon Motion SM501 driver might provide a useful
example, since the chip comes in both memory-mapped and PCI versions.
Unfortunately the chip is implemented as a multi-function driver
(mfd), so the code is not un-complicated. Still fairly
straightforward and well-written once you learn your way around it,
though.
Basically, it implements a core set of functionality to talk to the
actual chip registers, which is bus-agnostic. Then the bus-specific
drivers use these functions when they actually want to touch the chip
itself. In other words, exactly what David suggested.
b.g.
On Mon, Feb 7, 2011 at 8:37 PM, <Bruce_Leonard@selinc.com> wrote:
>>
>> There are a number of drivers which already have this sort of dual bus
>> binding.
>>
>
> Thanks for the feedback David, I appreciate it. =A0Could you point me to =
one
> of those drivers that has "this sort of dual bus binding" so can see an
> example of what I'm trying to do?
>
> Bruce
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev@lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/linuxppc-dev
>
--=20
Bill Gatliff
bgat@billgatliff.com
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: Question on supporting multiple HW versions with a single driver (warning: long post)
2011-02-08 5:13 ` Bill Gatliff
@ 2011-02-08 16:59 ` Bruce_Leonard
0 siblings, 0 replies; 5+ messages in thread
From: Bruce_Leonard @ 2011-02-08 16:59 UTC (permalink / raw)
To: Bill Gatliff; +Cc: linuxppc-dev, David Gibson
Ah, okay. Taking a look at that it makes sense now. Thanks to both of
you for the help.
Bruce
From:
Bill Gatliff <bgat@billgatliff.com>
To:
Bruce_Leonard@selinc.com
Cc:
David Gibson <david@gibson.dropbear.id.au>, linuxppc-dev@lists.ozlabs.org
Date:
02/07/2011 09:13 PM
Subject:
Re: Question on supporting multiple HW versions with a single driver
(warning: long post)
Guys:
I think the Silicon Motion SM501 driver might provide a useful
example, since the chip comes in both memory-mapped and PCI versions.
Unfortunately the chip is implemented as a multi-function driver
(mfd), so the code is not un-complicated. Still fairly
straightforward and well-written once you learn your way around it,
though.
Basically, it implements a core set of functionality to talk to the
actual chip registers, which is bus-agnostic. Then the bus-specific
drivers use these functions when they actually want to touch the chip
itself. In other words, exactly what David suggested.
b.g.
On Mon, Feb 7, 2011 at 8:37 PM, <Bruce_Leonard@selinc.com> wrote:
>>
>> There are a number of drivers which already have this sort of dual bus
>> binding.
>>
>
> Thanks for the feedback David, I appreciate it. Could you point me to
one
> of those drivers that has "this sort of dual bus binding" so can see an
> example of what I'm trying to do?
>
> Bruce
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev@lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/linuxppc-dev
>
--
Bill Gatliff
bgat@billgatliff.com
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2011-02-08 16:59 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-02-02 21:57 Question on supporting multiple HW versions with a single driver (warning: long post) Bruce_Leonard
2011-02-08 2:16 ` David Gibson
2011-02-08 2:37 ` Bruce_Leonard
2011-02-08 5:13 ` Bill Gatliff
2011-02-08 16:59 ` Bruce_Leonard
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox