public inbox for u-boot@lists.denx.de
 help / color / mirror / Atom feed
From: Pavel Herrmann <morpheus.ibis@gmail.com>
To: u-boot@lists.denx.de
Subject: [U-Boot] [PATCH 06/25] dm: spi: Add a uclass for SPI
Date: Thu, 17 Jul 2014 20:01:29 +0200	[thread overview]
Message-ID: <9701986.dr4ku0Su2V@bloomfield> (raw)
In-Reply-To: <CAPnjgZ0_nhpJOtAuSBkkf3Pea1gczJjkzERXW7dGU03mQDsz1A@mail.gmail.com>

Hi

On Thursday 17 of July 2014 09:26:47 Simon Glass wrote:
> Hi Pavel,
> 
> On 17 July 2014 01:57, Pavel Herrmann <morpheus.ibis@gmail.com> wrote:
> > Hi
> > 
> > On Wednesday 16 of July 2014 23:39:44 Simon Glass wrote:
> >> Hi Pavel,
> >> 
> >> On 15 July 2014 02:26, Pavel Herrmann <morpheus.ibis@gmail.com> wrote:
> >> > Hi
> >> > 
> >> > On Monday 14 of July 2014 18:56:13 Simon Glass wrote:
> >> > > Add a uclass which provides access to SPI buses and includes
> >> > > operations
> >> > > required by SPI.
> >> > > 
> >> > > For a time driver model will need to co-exist with the legacy SPI
> >> > > interface
> >> > > so some parts of the header file are changed depending on which is in
> >> > > use.
> >> > > The exports are adjusted also since some functions are not available
> >> > > with
> >> > > driver model.
> >> > > 
> >> > > Boards must define CONFIG_DM_SPI to use driver model for SPI.
> >> > > 
> >> > > Signed-off-by: Simon Glass <sjg@chromium.org>
> >> > > ---
> >> > > 
> >> > > ...
> >> > > +int spi_xfer(struct spi_slave *slave, unsigned int bitlen,
> >> > > +          const void *dout, void *din, unsigned long flags)
> >> > > +{
> >> > > +     struct udevice *dev = slave->dev;
> >> > > +     struct udevice *bus = dev->parent;
> >> > 
> >> > is this the best interface here?
> >> > I think it would be cleaner if bus drivers had interfaces which follow
> >> > a
> >> > certain template, such as
> >> > bus_ops(struct udevice *bus, struct udevice *child, ...)
> >> 
> >> Thanks for your comments.
> >> 
> >> Well I thought about that long and hard. Clearly in a pure
> >> driver-model work we would pass a udevice, not a spi_slave.
> >> 
> >> > struct spi_slave would be a prime candidate to have in
> >> > child->parentdata
> >> > (which should only be accessed by the parent IIUC)
> >> 
> >> Yes, it is. In other words, 'struct spi_slave' is the child's parent
> >> data. The only reason that spi_xfer() is passed a spi_slave rather
> >> than a udevice is to maintain compatibility with the existing SPI
> >> system. I tried various other approachs, such as '#define spi_slave
> >> udevice' and the like. At some point we can change it, but it is
> >> really painful to have two completely different APIs co-existing in
> >> U-Boot.
> >> 
> >> This way, driver model becomes a fairly soft transition, the amount of
> >> rewriting needed is reduced, and I think it is much more likely that
> >> people will use it. As an example, one of the reasons that the generic
> >> board change has been relatively painless is that people can just
> >> define CONFIG_SYS_GENERIC_BOARD in their board header file, and in
> >> most cases it just works. If we require people to rewrite things it
> >> will take longer, etc. There is already enough rewriting required in
> >> individual drivers to keep people busy. It will be a relatively easy
> >> change to do in the future if we want to.
> > 
> > OK, that reason I understand.
> > 
> > However, what you are doing now is limiting what parentdata a SPI bus
> > controller can use.
> > This means that each bus driver has its parentdata defined by what uclass
> > it belongs to. Are you sure this won't be a limitation? I mean that you
> > could end up with uclasses that have the same calls but a slightly
> > different parentdata.
> No it is defined by the driver of the bus. Since it is possible to
> have (for example) 3 different USB drivers in a system, each can have
> its own idea of what child data it wants. I definitely agree that
> setting the parentdata by the child's uclass, or even the bus's uclass
> would be limiting. In the case of SPI I have elected to use struct
> spi_slave for reasons I explained earlier.

OK, so you would have some bus uclasses that pass typecasted parentdata, 
because it is the same for all bus drivers, and some that pass the childs 
udevice*, because the parentdata type is not known beforehands? what happens 
if suddenly you need to add a bus controller that needs a little more per-
child data than the existing ones?

wouldn't it be better to unify this somehow?

> > Yes, you could have a shared parentdata from the uclass (that makes sense
> > for all controllers, because of the way the bus works), and a
> > controller-specific parentdata as an extension (read "void *private" at
> > the end of the parentdata structure)
> > 
> >> Re passing both the bus and the device, really, what's the point? The
> >> only valid bus to pass to the function is dev->parent. If you pass
> >> anything else it is an error. It is redundant and therefore just
> >> introduces the possibility of error.
> > 
> > Well, yes, sort of.
> > 
> > Consider a bus with transparent bridges, like USB or PCI.
> > 
> > If you were to represent these bridges as udevices, you would end up with
> > something in between the actual devices and the bus controller, that
> > forwards requests with no or minimal change.
> > in case of USB specifically (IIRC), hubs are visible during
> > initialization, but when the device is up it has its own descriptor that
> > is used to
> > in case of PCI, the device address actually contains the bus number, but
> > the device itself doesn't really care about it, and is only used to
> > select which bus the command goes to.
> > 
> > consider the following scenario:
> > ------     ----------     ---------     ---------     ------------
> > 
> > |root| --- |ehci_hcd| --- |usb_hub| --- |usb_hub| --- |usb_device|
> > 
> > ------     ----------     ---------     ---------     ------------
> > 
> > If you were to flatten the bus, the udevice tree would not really
> > correspond to how the bus looks like in reality, and it might give you
> > some hurdles with initialization.
> > 
> > note that in these cases you cannot pass a child udevice to the bus
> > controller as a part of the upcall, since it is not necessarily its
> > child. this is in contradiction to what I wrote previously, simply
> > because I didn't think hard enough to find these counter examples.
> 
> I think you are referring to setting up a bus such that it becomes
> transparent. But even when it is, I'm not sure that driver model needs
> to rearrange its data structures to suit. Why would you flatten the
> bus? If we keep the data structures the same (strict parent-child
> relationships) then we always have a parent for the child, rather than
> trying to be too clever. Still, the child can obtain direct bus access
> through some mechanism delegated by the parent if we like. In that
> case there is even less reason to access the parent udevice IMO.
> 
> I think I'm missing something from your example, so please let me know.

ok, lets try some code examples

lets say a usb_hub is implemented as a USB bus that itself sits in a USB bus.
lets say USB bus uclass has a function usb_bulk_msg()
usb_hub's implementation of such function would look like this:

usb_bulk_msg(udevice *hub, usb_descriptor *child, ...)
{
	return usb_bulk_msg(hub->parent, child, ...);
}

your USB device would then call
usb_bulk_msg(my_dev->parent, my_desc,...)

this would work recursively through all hubs, and the end result you would 
like is to call usb_bulk_msg() of the host bus controller, without changing 
any of the parameters. (except the first, which is used for recursion)

However, if you got rid of the first parameter, you would need a different 
variable to control your recursion, or you would need the device descriptor to 
hold pointer to the udevice of the host controller, which would effectively 
flatten the bus.

this is the case where I believe the best way to implement is to have a shared 
parentdata based on parent uclass (the usb_descriptor in this case), with a 
driver-specific extension, in case the bus driver need something extra over 
what the "standard" is. the shared parentdata would then be used as a device 
descriptor/address/whatever-you-call-that in the bus calls.

One would also need to relax the semantics a bit, so that host bus controller 
can fill the parentdata for a udevice that is not its direct child.

I'm not saying your code is wrong or anything, I just think you should have a 
look at a more complex bus like USB or PCI, and design the "bus uclass 
interface template" in a way that would support such a bus. Otherwise you 
might end up either reworking your simpler busses later, or having 
inconsistent bus uclass interfaces (which we did when we tried this the first 
time).

I understand that API compatibility is an issue, and I agree that it is fine to 
cut some corners at this point, but we need to keep in mind to fix them once 
all the drivers have been converted.

regards
Pavel

  reply	other threads:[~2014-07-17 18:01 UTC|newest]

Thread overview: 51+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-07-15  0:56 [U-Boot] [PATCH 0/25] Introduce driver model support for SPI, SPI flash, cros_ec Simon Glass
2014-07-15  0:56 ` [U-Boot] [PATCH 01/25] sandbox: Convert SPI flash emulation to use sf_params Simon Glass
2014-08-25  9:24   ` Jagan Teki
2014-07-15  0:56 ` [U-Boot] [PATCH 02/25] sandbox: config: Enable all SPI flash chips Simon Glass
2014-08-25  9:24   ` Jagan Teki
2014-07-15  0:56 ` [U-Boot] [PATCH 03/25] sandbox: dts: Add a SPI device and cros_ec device Simon Glass
2014-08-25  9:32   ` Jagan Teki
2014-07-15  0:56 ` [U-Boot] [PATCH 04/25] dm: spi: Move cmd device code into its own function Simon Glass
2014-08-25 18:31   ` Jagan Teki
2014-09-02 19:22     ` Simon Glass
2014-07-15  0:56 ` [U-Boot] [PATCH 05/25] spi: Add brackets and tidy defines in spi.h Simon Glass
2014-08-25  9:34   ` Jagan Teki
2014-07-15  0:56 ` [U-Boot] [PATCH 06/25] dm: spi: Add a uclass for SPI Simon Glass
2014-07-15  8:26   ` Pavel Herrmann
2014-07-17  5:39     ` Simon Glass
2014-07-17  7:57       ` Pavel Herrmann
2014-07-17 15:26         ` Simon Glass
2014-07-17 18:01           ` Pavel Herrmann [this message]
2014-07-17 18:29             ` Pavel Herrmann
2014-07-21  2:17               ` Simon Glass
2014-07-21  2:15             ` Simon Glass
2014-08-11 21:46   ` Daniel Schwierzeck
2014-08-28  8:58   ` Jagan Teki
2014-08-29 23:38     ` Simon Glass
2014-07-15  0:56 ` [U-Boot] [PATCH 07/25] dm: sandbox: Add a SPI emulation uclass Simon Glass
2014-07-15  0:56 ` [U-Boot] [PATCH 08/25] dm: Remove spi_init() from board_r.c when using driver model Simon Glass
2014-07-15  0:56 ` [U-Boot] [PATCH 09/25] dm: Add spi.h header to a few files Simon Glass
2014-07-15  0:56 ` [U-Boot] [PATCH 10/25] dm: spi: Adjust cmd_spi to work with driver model Simon Glass
2014-07-15  0:56 ` [U-Boot] [PATCH 11/25] dm: sandbox: spi: Move to " Simon Glass
2014-07-15  0:56 ` [U-Boot] [PATCH 12/25] dm: spi: Add documentation on how to convert over SPI drivers Simon Glass
2014-08-28 11:32   ` Jagan Teki
2014-09-01  5:06     ` Simon Glass
2014-09-01  6:45       ` Jagan Teki
2014-09-02  0:24         ` Simon Glass
2014-07-15  0:56 ` [U-Boot] [PATCH 13/25] dm: exynos: Convert SPI to driver model Simon Glass
2014-07-15  0:56 ` [U-Boot] [PATCH 14/25] sf: Add an empty entry to the parameter list Simon Glass
2014-07-15  0:56 ` [U-Boot] [PATCH 15/25] sf: Tidy up public and private header files Simon Glass
2014-07-15  0:56 ` [U-Boot] [PATCH 16/25] spi: Use error return value in sf_ops Simon Glass
2014-07-15  0:56 ` [U-Boot] [PATCH 17/25] dm: sf: Add a uclass for SPI flash Simon Glass
2014-07-15  0:56 ` [U-Boot] [PATCH 18/25] dm: Convert spi_flash_probe() and 'sf probe' to use driver model Simon Glass
2014-07-15  0:56 ` [U-Boot] [PATCH 19/25] dm: sf: sandbox: Convert SPI flash driver to " Simon Glass
2014-07-15  0:56 ` [U-Boot] [PATCH 20/25] dm: exynos: config: Use driver model for SPI flash Simon Glass
2014-07-15  0:56 ` [U-Boot] [PATCH 21/25] dm: spi: Add tests Simon Glass
2014-07-15  0:56 ` [U-Boot] [PATCH 22/25] dm: sf: Add tests for SPI flash Simon Glass
2014-07-15  0:56 ` [U-Boot] [PATCH 23/25] dm: cros_ec: Add support for driver model Simon Glass
2014-07-15  0:56 ` [U-Boot] [PATCH 24/25] dm: sandbox: cros_ec: Move sandbox cros_ec to driver module Simon Glass
2014-07-15  0:56 ` [U-Boot] [PATCH 25/25] dm: exynos: cros_ec: Move cros_ec_spi to driver model Simon Glass
2014-08-09 21:29 ` [U-Boot] [PATCH 0/25] Introduce driver model support for SPI, SPI flash, cros_ec Simon Glass
2014-08-10  9:16   ` Jagan Teki
2014-08-11 19:55     ` Simon Glass
2014-09-15  1:03       ` Simon Glass

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=9701986.dr4ku0Su2V@bloomfield \
    --to=morpheus.ibis@gmail.com \
    --cc=u-boot@lists.denx.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox