Message ID | 20110406152322.GA2757@sortiz-mobl (mailing list archive) |
---|---|
State | Superseded, archived |
Headers |
Return-path: <mchehab@pedra> Envelope-to: mchehab@pedra Delivery-date: Wed, 06 Apr 2011 12:24:41 -0300 Received: from mchehab by pedra with local (Exim 4.72) (envelope-from <mchehab@pedra>) id 1Q7Ub2-0005DP-PR for mchehab@pedra; Wed, 06 Apr 2011 12:24:41 -0300 Received: from casper.infradead.org [85.118.1.10] by pedra with IMAP (fetchmail-6.3.17) for <mchehab@localhost> (single-drop); Wed, 06 Apr 2011 12:24:40 -0300 (BRT) Received: from vger.kernel.org ([209.132.180.67]) by casper.infradead.org with esmtp (Exim 4.72 #1 (Red Hat Linux)) id 1Q7UaC-00011l-GP; Wed, 06 Apr 2011 15:23:48 +0000 Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1756465Ab1DFPXa (ORCPT <rfc822; kmpark@infradead.org> + 1 other); Wed, 6 Apr 2011 11:23:30 -0400 Received: from mga01.intel.com ([192.55.52.88]:53033 "EHLO mga01.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1756376Ab1DFPX2 (ORCPT <rfc822;linux-media@vger.kernel.org>); Wed, 6 Apr 2011 11:23:28 -0400 Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by fmsmga101.fm.intel.com with ESMTP; 06 Apr 2011 08:23:28 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="4.63,310,1299484800"; d="scan'208";a="675973080" Received: from unknown (HELO sortiz-mobl) ([10.255.16.172]) by fmsmga002.fm.intel.com with ESMTP; 06 Apr 2011 08:23:24 -0700 Date: Wed, 6 Apr 2011 17:23:23 +0200 From: Samuel Ortiz <sameo@linux.intel.com> To: Grant Likely <grant.likely@secretlab.ca> Cc: Andres Salomon <dilinger@queued.net>, linux-kernel@vger.kernel.org, Mark Brown <broonie@opensource.wolfsonmicro.com>, khali@linux-fr.org, ben-linux@fluff.org, Peter Korsgaard <jacmet@sunsite.dk>, Mauro Carvalho Chehab <mchehab@infradead.org>, David Brownell <dbrownell@users.sourceforge.net>, linux-i2c@vger.kernel.org, linux-media@vger.kernel.org, netdev@vger.kernel.org, spi-devel-general@lists.sourceforge.net, Mocean Laboratories <info@mocean-labs.com>, Greg Kroah-Hartman <gregkh@suse.de> Subject: Re: [PATCH 07/19] timberdale: mfd_cell is now implicitly available to drivers Message-ID: <20110406152322.GA2757@sortiz-mobl> References: <20110202195417.228e2656@queued.net> <20110202200812.3d8d6cba@queued.net> <20110331230522.GI437@ponder.secretlab.ca> <20110401112030.GA3447@sortiz-mobl> <20110401104756.2f5c6f7a@debxo> <BANLkTi=bCd_+f=EG-O=U5VH_ZNjFhxkziQ@mail.gmail.com> <20110401235239.GE29397@sortiz-mobl> <BANLkTi=bq=OGzXFp7qiBr7x_BnGOWf=DRQ@mail.gmail.com> <20110404100314.GC2751@sortiz-mobl> <20110405030428.GB29522@ponder.secretlab.ca> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20110405030428.GB29522@ponder.secretlab.ca> User-Agent: Mutt/1.5.20 (2009-06-14) Precedence: bulk List-ID: <linux-media.vger.kernel.org> X-Mailing-List: linux-media@vger.kernel.org Sender: <mchehab@pedra> |
Commit Message
Samuel Ortiz
April 6, 2011, 3:23 p.m. UTC
On Mon, Apr 04, 2011 at 09:04:29PM -0600, Grant Likely wrote: > > The second step would be to get rid of mfd_get_data() and have all subdrivers > > going back to the regular platform_data way. They would no longer be dependant > > on the MFD code except for those who really need it. In that case they could > > just call mfd_get_cell() and get full access to their MFD cell. > > The revert to platform_data needs to happen ASAP though. If this > second step isn't ready really quickly, then the current patches > should be reverted to give some breathing room for creating the > replacement patches. However, it's not such a rush if the below > patch really does eliminate all of the nastiness of the original > series. (I haven't looked and a rolled up diff of the first series and > this change, so I don't know for sure). I am done reverting these changes, with a final patch getting rid of mfd_get_data. See git://git.kernel.org/pub/scm/linux/kernel/git/sameo/mfd-2.6.git for-linus I still need to give it a second review before pushing it to lkml for comments. It's 20 patches long, so I'm not entirely sure Linus would take that at that point. Pushing patch #1 would be enough for fixing the issues introduced by the original patchset, so I'm leaning toward pushing it and leaving the 19 other patches for the next merge window. > In principle I agree with this patch. Some comments below. Thanks for the comments. I think I addressed all of them in patch #1: --- drivers/base/platform.c | 1 + drivers/mfd/mfd-core.c | 15 +++++++++++++-- include/linux/device.h | 3 +++ include/linux/mfd/core.h | 7 +++++-- 4 files changed, 22 insertions(+), 4 deletions(-)
Comments
On Wed, Apr 06, 2011 at 05:23:23PM +0200, Samuel Ortiz wrote: > --- a/include/linux/device.h > +++ b/include/linux/device.h > @@ -33,6 +33,7 @@ struct class; > struct subsys_private; > struct bus_type; > struct device_node; > +struct mfd_cell; > > struct bus_attribute { > struct attribute attr; > @@ -444,6 +445,8 @@ struct device { > struct device_node *of_node; /* associated device tree node */ > const struct of_device_id *of_match; /* matching of_device_id from driver */ > > + struct mfd_cell *mfd_cell; /* MFD cell pointer */ > + What is a "MFD cell pointer" and why is it needed in struct device? thanks, greg k-h -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Hi Greg, On Wed, Apr 06, 2011 at 08:58:05AM -0700, Greg KH wrote: > On Wed, Apr 06, 2011 at 05:23:23PM +0200, Samuel Ortiz wrote: > > --- a/include/linux/device.h > > +++ b/include/linux/device.h > > @@ -33,6 +33,7 @@ struct class; > > struct subsys_private; > > struct bus_type; > > struct device_node; > > +struct mfd_cell; > > > > struct bus_attribute { > > struct attribute attr; > > @@ -444,6 +445,8 @@ struct device { > > struct device_node *of_node; /* associated device tree node */ > > const struct of_device_id *of_match; /* matching of_device_id from driver */ > > > > + struct mfd_cell *mfd_cell; /* MFD cell pointer */ > > + > > What is a "MFD cell pointer" and why is it needed in struct device? An MFD cell is an MFD instantiated device. MFD (Multi Function Device) drivers instantiate platform devices. Those devices drivers sometimes need a platform data pointer, sometimes an MFD specific pointer, and sometimes both. Also, some of those drivers have been implemented as MFD sub drivers, while others know nothing about MFD and just expect a plain platform_data pointer. We've been faced with the problem of being able to pass both MFD related data and a platform_data pointer to some of those drivers. Squeezing the MFD bits in the sub driver platform_data pointer doesn't work for drivers that know nothing about MFDs. It also adds an additional dependency on the MFD API to all MFD sub drivers. That prevents any of those drivers to eventually be used as plain platform device drivers. So, adding an MFD cell pointer to the device structure allows us to cleanly pass both pieces of information, while keeping all the MFD sub drivers independant from the MFD core if they want/can. Cheers, Samuel.
On Wed, 2011-04-06 at 19:05 +0200, Samuel Ortiz wrote: > Hi Greg, > > On Wed, Apr 06, 2011 at 08:58:05AM -0700, Greg KH wrote: > > On Wed, Apr 06, 2011 at 05:23:23PM +0200, Samuel Ortiz wrote: > > > --- a/include/linux/device.h > > > +++ b/include/linux/device.h > > > @@ -33,6 +33,7 @@ struct class; > > > struct subsys_private; > > > struct bus_type; > > > struct device_node; > > > +struct mfd_cell; > > > > > > struct bus_attribute { > > > struct attribute attr; > > > @@ -444,6 +445,8 @@ struct device { > > > struct device_node *of_node; /* associated device tree node */ > > > const struct of_device_id *of_match; /* matching of_device_id from driver */ > > > > > > + struct mfd_cell *mfd_cell; /* MFD cell pointer */ > > > + > > > > What is a "MFD cell pointer" and why is it needed in struct device? > An MFD cell is an MFD instantiated device. > MFD (Multi Function Device) drivers instantiate platform devices. Those > devices drivers sometimes need a platform data pointer, sometimes an MFD > specific pointer, and sometimes both. Also, some of those drivers have been > implemented as MFD sub drivers, while others know nothing about MFD and just > expect a plain platform_data pointer. > > We've been faced with the problem of being able to pass both MFD related data > and a platform_data pointer to some of those drivers. Squeezing the MFD bits > in the sub driver platform_data pointer doesn't work for drivers that know > nothing about MFDs. It also adds an additional dependency on the MFD API to > all MFD sub drivers. That prevents any of those drivers to eventually be used > as plain platform device drivers. > So, adding an MFD cell pointer to the device structure allows us to cleanly > pass both pieces of information, while keeping all the MFD sub drivers > independant from the MFD core if they want/can. Why isn't an MFD the parent of its component devices? Ben.
Hi Ben, On Wed, Apr 06, 2011 at 06:16:49PM +0100, Ben Hutchings wrote: > > So, adding an MFD cell pointer to the device structure allows us to cleanly > > pass both pieces of information, while keeping all the MFD sub drivers > > independant from the MFD core if they want/can. > > Why isn't an MFD the parent of its component devices? It actually is. How would that help here ? Cheers, Samuel.
On Wed, Apr 06, 2011 at 07:05:38PM +0200, Samuel Ortiz wrote: > Hi Greg, > > On Wed, Apr 06, 2011 at 08:58:05AM -0700, Greg KH wrote: > > On Wed, Apr 06, 2011 at 05:23:23PM +0200, Samuel Ortiz wrote: > > > --- a/include/linux/device.h > > > +++ b/include/linux/device.h > > > @@ -33,6 +33,7 @@ struct class; > > > struct subsys_private; > > > struct bus_type; > > > struct device_node; > > > +struct mfd_cell; > > > > > > struct bus_attribute { > > > struct attribute attr; > > > @@ -444,6 +445,8 @@ struct device { > > > struct device_node *of_node; /* associated device tree node */ > > > const struct of_device_id *of_match; /* matching of_device_id from driver */ > > > > > > + struct mfd_cell *mfd_cell; /* MFD cell pointer */ > > > + > > > > What is a "MFD cell pointer" and why is it needed in struct device? > An MFD cell is an MFD instantiated device. > MFD (Multi Function Device) drivers instantiate platform devices. Those > devices drivers sometimes need a platform data pointer, sometimes an MFD > specific pointer, and sometimes both. Also, some of those drivers have been > implemented as MFD sub drivers, while others know nothing about MFD and just > expect a plain platform_data pointer. That sounds like a bug in those drivers, why not fix them to properly pass in the correct pointer? > We've been faced with the problem of being able to pass both MFD related data > and a platform_data pointer to some of those drivers. Squeezing the MFD bits > in the sub driver platform_data pointer doesn't work for drivers that know > nothing about MFDs. It also adds an additional dependency on the MFD API to > all MFD sub drivers. That prevents any of those drivers to eventually be used > as plain platform device drivers. Then they shouldn't be "plain" platform drivers, that should only be reserved for drivers that are the "lowest" type. Just make them MFD devices and go from there. > So, adding an MFD cell pointer to the device structure allows us to cleanly > pass both pieces of information, while keeping all the MFD sub drivers > independant from the MFD core if they want/can. They shouldn't be "independant", make them "dependant" and go from there. thanks, greg k-h -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On Wed, 2011-04-06 at 19:51 +0200, Samuel Ortiz wrote: > Hi Ben, > > On Wed, Apr 06, 2011 at 06:16:49PM +0100, Ben Hutchings wrote: > > > So, adding an MFD cell pointer to the device structure allows us to cleanly > > > pass both pieces of information, while keeping all the MFD sub drivers > > > independant from the MFD core if they want/can. > > > > Why isn't an MFD the parent of its component devices? > It actually is. How would that help here ? I was thinking you could encode the component address in the platform_device name (just as the bus address is the name of a normal bus device). That plus the parent device pointer would be sufficient information to look up the mfd_cell. Ben.
On Wed, 6 Apr 2011 10:56:47 -0700 Greg KH <gregkh@suse.de> wrote: > On Wed, Apr 06, 2011 at 07:05:38PM +0200, Samuel Ortiz wrote: > > Hi Greg, > > > > On Wed, Apr 06, 2011 at 08:58:05AM -0700, Greg KH wrote: > > > On Wed, Apr 06, 2011 at 05:23:23PM +0200, Samuel Ortiz wrote: > > > > --- a/include/linux/device.h > > > > +++ b/include/linux/device.h > > > > @@ -33,6 +33,7 @@ struct class; > > > > struct subsys_private; > > > > struct bus_type; > > > > struct device_node; > > > > +struct mfd_cell; > > > > > > > > struct bus_attribute { > > > > struct attribute attr; > > > > @@ -444,6 +445,8 @@ struct device { > > > > struct device_node *of_node; /* associated > > > > device tree node */ const struct of_device_id *of_match; /* > > > > matching of_device_id from driver */ > > > > + struct mfd_cell *mfd_cell; /* MFD cell pointer > > > > */ + > > > > > > What is a "MFD cell pointer" and why is it needed in struct > > > device? > > An MFD cell is an MFD instantiated device. > > MFD (Multi Function Device) drivers instantiate platform devices. > > Those devices drivers sometimes need a platform data pointer, > > sometimes an MFD specific pointer, and sometimes both. Also, some > > of those drivers have been implemented as MFD sub drivers, while > > others know nothing about MFD and just expect a plain platform_data > > pointer. > > That sounds like a bug in those drivers, why not fix them to properly > pass in the correct pointer? I'm still trying to understand if this is a theoretical problem, or if Grant has actually experienced a regression. His mention of bisecting made it sound like the latter was the case, but I've yet to hear of specifically what drivers this was breaking. Samuel described some potential driver breakage, but nothing concrete. I do agree that this needs a better solution, given the theoretical breakage. > > > We've been faced with the problem of being able to pass both MFD > > related data and a platform_data pointer to some of those drivers. > > Squeezing the MFD bits in the sub driver platform_data pointer > > doesn't work for drivers that know nothing about MFDs. It also adds > > an additional dependency on the MFD API to all MFD sub drivers. > > That prevents any of those drivers to eventually be used as plain > > platform device drivers. > > Then they shouldn't be "plain" platform drivers, that should only be > reserved for drivers that are the "lowest" type. Just make them MFD > devices and go from there. The problem is of mixing "plain" platform devices and MFD devices. It's reasonable to assume that different hardware may be using one method or the other to create devices; in order to maintain compatibility with the driver, one either needs to use a plain platform device. Alternatively, if an MFD-specific device class is created, then MFD devices would start showing up in weird places. > > > So, adding an MFD cell pointer to the device structure allows us to > > cleanly pass both pieces of information, while keeping all the MFD > > sub drivers independant from the MFD core if they want/can. > > They shouldn't be "independant", make them "dependant" and go from > there. > > thanks, > > greg k-h -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On Wed, Apr 06, 2011 at 11:25:57AM -0700, Andres Salomon wrote: > > > We've been faced with the problem of being able to pass both MFD > > > related data and a platform_data pointer to some of those drivers. > > > Squeezing the MFD bits in the sub driver platform_data pointer > > > doesn't work for drivers that know nothing about MFDs. It also adds > > > an additional dependency on the MFD API to all MFD sub drivers. > > > That prevents any of those drivers to eventually be used as plain > > > platform device drivers. > > > > Then they shouldn't be "plain" platform drivers, that should only be > > reserved for drivers that are the "lowest" type. Just make them MFD > > devices and go from there. > > > The problem is of mixing "plain" platform devices and MFD devices. Then don't do that. > It's reasonable to assume that different hardware may be using > one method or the other to create devices; in order to maintain > compatibility with the driver, one either needs to use a plain platform > device. Alternatively, if an MFD-specific device class is created, > then MFD devices would start showing up in weird places. Then fix it. Lots of other drivers handle different "bus types" just fine (look at the EHCI USB driver for an example.) Don't polute the driver core just because you don't want to fix up the individual driver issues that are quite obvious. thanks, greg k-h -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On Wed, Apr 06, 2011 at 10:56:47AM -0700, Greg KH wrote: > On Wed, Apr 06, 2011 at 07:05:38PM +0200, Samuel Ortiz wrote: > > Hi Greg, > > > > On Wed, Apr 06, 2011 at 08:58:05AM -0700, Greg KH wrote: > > > On Wed, Apr 06, 2011 at 05:23:23PM +0200, Samuel Ortiz wrote: > > > > --- a/include/linux/device.h > > > > +++ b/include/linux/device.h > > > > @@ -33,6 +33,7 @@ struct class; > > > > struct subsys_private; > > > > struct bus_type; > > > > struct device_node; > > > > +struct mfd_cell; > > > > > > > > struct bus_attribute { > > > > struct attribute attr; > > > > @@ -444,6 +445,8 @@ struct device { > > > > struct device_node *of_node; /* associated device tree node */ > > > > const struct of_device_id *of_match; /* matching of_device_id from driver */ > > > > > > > > + struct mfd_cell *mfd_cell; /* MFD cell pointer */ > > > > + > > > > > > What is a "MFD cell pointer" and why is it needed in struct device? > > An MFD cell is an MFD instantiated device. > > MFD (Multi Function Device) drivers instantiate platform devices. Those > > devices drivers sometimes need a platform data pointer, sometimes an MFD > > specific pointer, and sometimes both. Also, some of those drivers have been > > implemented as MFD sub drivers, while others know nothing about MFD and just > > expect a plain platform_data pointer. > > That sounds like a bug in those drivers, why not fix them to properly > pass in the correct pointer? Because they're drivers for generic IPs, not MFD ones. By forcing them to use MFD specific structure and APIs, we make it more difficult for platform code to instantiate them. The timberdale MFD for example is built with a Xilinx SPI controller, and a Micrel ks8842 ethernet switch IP. Forcing those devices into being MFD devices would mean any platform willing to instantiate them would have to use the MFD APIs. That sounds a bit artificial to me. Although there is currently no drivers instantiated by both an MFD driver and some platform code, Grant complaint about the Xilinx SPI driver moving from a platform driver to an MFD one makes sense to me. > > So, adding an MFD cell pointer to the device structure allows us to cleanly > > pass both pieces of information, while keeping all the MFD sub drivers > > independant from the MFD core if they want/can. > > They shouldn't be "independant", Excuse my poor spelling. > make them "dependant" and go from there. That's what the code currently does. Cheers, Samuel.
Hi, On Wed, Apr 06, 2011 at 08:47:34PM +0200, Samuel Ortiz wrote: > > > > What is a "MFD cell pointer" and why is it needed in struct device? > > > An MFD cell is an MFD instantiated device. > > > MFD (Multi Function Device) drivers instantiate platform devices. Those > > > devices drivers sometimes need a platform data pointer, sometimes an MFD > > > specific pointer, and sometimes both. Also, some of those drivers have been > > > implemented as MFD sub drivers, while others know nothing about MFD and just > > > expect a plain platform_data pointer. > > > > That sounds like a bug in those drivers, why not fix them to properly > > pass in the correct pointer? > Because they're drivers for generic IPs, not MFD ones. By forcing them to use > MFD specific structure and APIs, we make it more difficult for platform code > to instantiate them. I agree. What I do on those cases is to have a simple platform_device for the core IP driver and use platform_device_id tables to do runtime checks of the small differences. If one platform X doesn't use a platform_bus, it uses e.g. PCI, then you make a PCI "bridge" which allocates a platform_device with the correct name and adds that to the driver model. See [1] (for the core driver) and [2] (for a PCI bridge driver) for an example of what I'm talking about. > The timberdale MFD for example is built with a Xilinx SPI controller, and a > Micrel ks8842 ethernet switch IP. Forcing those devices into being MFD devices > would mean any platform willing to instantiate them would have to use the MFD > APIs. That sounds a bit artificial to me. do they share any address space ? If they do, then you'd need something to synchronize, right ? If they don't, then you just add two separate devices, they don't have to be MFD. > Although there is currently no drivers instantiated by both an MFD driver > and some platform code, Grant complaint about the Xilinx SPI driver moving > from a platform driver to an MFD one makes sense to me. I don't think so. That's not really an MFD device is it ? It's just two different IPs instantianted on the same ASIC/FPGA, right ? Unless they share the register space, IMHO, there's no need to make them MFD. [1] http://gitorious.org/usb/usb/blobs/dwc3/drivers/usb/dwc3/core.c [2] http://gitorious.org/usb/usb/blobs/dwc3/drivers/usb/dwc3/dwc3-haps.c
On Wed, Apr 06, 2011 at 09:59:02PM +0300, Felipe Balbi wrote: > Hi, > > On Wed, Apr 06, 2011 at 08:47:34PM +0200, Samuel Ortiz wrote: > > > > > What is a "MFD cell pointer" and why is it needed in struct device? > > > > An MFD cell is an MFD instantiated device. > > > > MFD (Multi Function Device) drivers instantiate platform devices. Those > > > > devices drivers sometimes need a platform data pointer, sometimes an MFD > > > > specific pointer, and sometimes both. Also, some of those drivers have been > > > > implemented as MFD sub drivers, while others know nothing about MFD and just > > > > expect a plain platform_data pointer. > > > > > > That sounds like a bug in those drivers, why not fix them to properly > > > pass in the correct pointer? > > Because they're drivers for generic IPs, not MFD ones. By forcing them to use > > MFD specific structure and APIs, we make it more difficult for platform code > > to instantiate them. > > I agree. What I do on those cases is to have a simple platform_device > for the core IP driver and use platform_device_id tables to do runtime > checks of the small differences. If one platform X doesn't use a > platform_bus, it uses e.g. PCI, then you make a PCI "bridge" which > allocates a platform_device with the correct name and adds that to the > driver model. > > See [1] (for the core driver) and [2] (for a PCI bridge driver) for an > example of what I'm talking about. Yes, thanks for providing a real example, this is the best way to handle this. thanks, greg k-h -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On Wed, Apr 06, 2011 at 11:38:54AM -0700, Greg KH wrote: > On Wed, Apr 06, 2011 at 11:25:57AM -0700, Andres Salomon wrote: > > > > We've been faced with the problem of being able to pass both MFD > > > > related data and a platform_data pointer to some of those drivers. > > > > Squeezing the MFD bits in the sub driver platform_data pointer > > > > doesn't work for drivers that know nothing about MFDs. It also adds > > > > an additional dependency on the MFD API to all MFD sub drivers. > > > > That prevents any of those drivers to eventually be used as plain > > > > platform device drivers. > > > > > > Then they shouldn't be "plain" platform drivers, that should only be > > > reserved for drivers that are the "lowest" type. Just make them MFD > > > devices and go from there. > > > > > > The problem is of mixing "plain" platform devices and MFD devices. > > Then don't do that. From my perspective, MFD devices are little more than a bag of platform_devices, with the MFD layer provides infrastructure for managing it. It isn't that there are 'plain' platform device and 'mfd' devices. There are only platform_devices, but some of the drivers use additional data stored in a struct mfd. Personally, I'm not thrilled with the approach of using struct mfd, or more specifically making it available to drivers, but on the ugly scale it isn't very high. However, the changes on how struct mfd is passed that were merged in 2.6.39 were actively dangerous and are going to be reverted. Yet a method is still needed to pass the struct mfd in a safe way. I don't have a problem with adding the mfd pointer to struct platform_device, even if it should just be a stop gap to something better. Independently, I have been experimenting with typesafe methods for attaching data to devices which may very well be the long term approach, but for the short term I see no problem with adding the mfd pointer, particularly because it is by far safer than any of the other immediately available options. g. -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Hi, On Wed, Apr 06, 2011 at 03:09:00PM -0700, Greg KH wrote: > On Wed, Apr 06, 2011 at 09:59:02PM +0300, Felipe Balbi wrote: > > Hi, > > > > On Wed, Apr 06, 2011 at 08:47:34PM +0200, Samuel Ortiz wrote: > > > > > > What is a "MFD cell pointer" and why is it needed in struct device? > > > > > An MFD cell is an MFD instantiated device. > > > > > MFD (Multi Function Device) drivers instantiate platform devices. Those > > > > > devices drivers sometimes need a platform data pointer, sometimes an MFD > > > > > specific pointer, and sometimes both. Also, some of those drivers have been > > > > > implemented as MFD sub drivers, while others know nothing about MFD and just > > > > > expect a plain platform_data pointer. > > > > > > > > That sounds like a bug in those drivers, why not fix them to properly > > > > pass in the correct pointer? > > > Because they're drivers for generic IPs, not MFD ones. By forcing them to use > > > MFD specific structure and APIs, we make it more difficult for platform code > > > to instantiate them. > > > > I agree. What I do on those cases is to have a simple platform_device > > for the core IP driver and use platform_device_id tables to do runtime > > checks of the small differences. If one platform X doesn't use a > > platform_bus, it uses e.g. PCI, then you make a PCI "bridge" which > > allocates a platform_device with the correct name and adds that to the > > driver model. > > > > See [1] (for the core driver) and [2] (for a PCI bridge driver) for an > > example of what I'm talking about. > > Yes, thanks for providing a real example, this is the best way to handle > this. no problem. ps: that's the driver for the USB3 controller which will come on OMAP5. Driver being validate on a pre-silicon platform right now :-D In a few weeks I'll send the driver for integration.
diff --git a/drivers/base/platform.c b/drivers/base/platform.c index f051cff..bde6b97 100644 --- a/drivers/base/platform.c +++ b/drivers/base/platform.c @@ -149,6 +149,7 @@ static void platform_device_release(struct device *dev) of_device_node_put(&pa->pdev.dev); kfree(pa->pdev.dev.platform_data); + kfree(pa->pdev.dev.mfd_cell); kfree(pa->pdev.resource); kfree(pa); } diff --git a/drivers/mfd/mfd-core.c b/drivers/mfd/mfd-core.c index d01574d..99b0d6d 100644 --- a/drivers/mfd/mfd-core.c +++ b/drivers/mfd/mfd-core.c @@ -18,6 +18,18 @@ #include <linux/pm_runtime.h> #include <linux/slab.h> +static int mfd_platform_add_cell(struct platform_device *pdev, const struct mfd_cell *cell) +{ + if (!cell) + return 0; + + pdev->dev.mfd_cell = kmemdup(cell, sizeof(*cell), GFP_KERNEL); + if (!pdev->dev.mfd_cell) + return -ENOMEM; + + return 0; +} + int mfd_cell_enable(struct platform_device *pdev) { const struct mfd_cell *cell = mfd_get_cell(pdev); @@ -75,7 +87,7 @@ static int mfd_add_device(struct device *parent, int id, pdev->dev.parent = parent; - ret = platform_device_add_data(pdev, cell, sizeof(*cell)); + ret = mfd_platform_add_cell(pdev, cell); if (ret) goto fail_res; @@ -123,7 +135,6 @@ static int mfd_add_device(struct device *parent, int id, return 0; -/* platform_device_del(pdev); */ fail_res: kfree(res); fail_device: diff --git a/include/linux/device.h b/include/linux/device.h index ab8dfc0..cf353cf 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -33,6 +33,7 @@ struct class; struct subsys_private; struct bus_type; struct device_node; +struct mfd_cell; struct bus_attribute { struct attribute attr; @@ -444,6 +445,8 @@ struct device { struct device_node *of_node; /* associated device tree node */ const struct of_device_id *of_match; /* matching of_device_id from driver */ + struct mfd_cell *mfd_cell; /* MFD cell pointer */ + dev_t devt; /* dev_t, creates the sysfs "dev" */ spinlock_t devres_lock; diff --git a/include/linux/mfd/core.h b/include/linux/mfd/core.h index ad1b19a..28f81cf 100644 --- a/include/linux/mfd/core.h +++ b/include/linux/mfd/core.h @@ -86,7 +86,7 @@ extern int mfd_clone_cell(const char *cell, const char **clones, */ static inline const struct mfd_cell *mfd_get_cell(struct platform_device *pdev) { - return pdev->dev.platform_data; + return pdev->dev.mfd_cell; } /* @@ -95,7 +95,10 @@ static inline const struct mfd_cell *mfd_get_cell(struct platform_device *pdev) */ static inline void *mfd_get_data(struct platform_device *pdev) { - return mfd_get_cell(pdev)->mfd_data; + if (pdev->dev.mfd_cell) + return mfd_get_cell(pdev)->mfd_data; + else + return pdev->dev.platform_data; } extern int mfd_add_devices(struct device *parent, int id,