Re: [PATCH v2 1/4] mfd: add viperboard driver
On 10/18/2012 09:29 AM, Lars Poeschel wrote: > On Tuesday 16 October 2012 at 12:58:48, Lars-Peter Clausen wrote: >> On 10/16/2012 11:43 AM, Lars Poeschel wrote: >>> On Tuesday 16 October 2012 at 10:40:26, Lars-Peter Clausen wrote: On 10/12/2012 04:34 PM, Lars Poeschel wrote: Btw. I'm wondering why is the extra platform device required? Can't you not just use the usb device as the parent device for the mfd cells? >>> >>> This is what I first did, but this does not work. You can read about my >>> first thoughts why this is not working here: (To sum it up: The device >>> is housed in an usb_device, not a platform_device and This usb_device >>> has no mfd_cell member.) >>> >>> https://lkml.org/lkml/2012/9/28/327 >>> >>> As I got a bit more deeper I also noticed, that mfd_add_devices >>> (obviously) adds the devices "as childs" to the parent device. >>> mfd_remove_devices then removes ALL "child" devices from the parent, not >>> only those added by mfd_add_devices before. This does not work in the >>> case of the usb parent device, because it has other childs that the usb >>> layer added before (some endpoints and stuff). So I had to construct an >>> "empty" (in sense of childs) mock platform_device between the usb and >>> mfd. >> >> Ah, ok that makes sense. I was a bit confused, because there are other mfd >> drivers with for example i2c or spi devices as parents and these work fine, >> but I guess this is because non of them registers any additional child >> devices. I guess it makes sense to create a mfd cell device type and assign >> this type to newly created mfd cells and only unregister a device in >> mfd_remove_devices if it has the correct device type. >> >> E.g. something along the lines of: >> >> >> --- a/drivers/mfd/mfd-core.c >> +++ b/drivers/mfd/mfd-core.c >> @@ -21,6 +21,10 @@ >> #include >> #include >> >> +static struct device_type mfd_device_type = { >> +.name = "mfd-cell", >> +}; >> + >> int mfd_cell_enable(struct platform_device *pdev) >> { >> const struct mfd_cell *cell = mfd_get_cell(pdev); >> @@ -91,6 +95,7 @@ static int mfd_add_device(struct device *parent, int id, >> goto fail_device; >> >> pdev->dev.parent = parent; >> +pdev->dev.type = _device_type; >> >> if (parent->of_node && cell->of_compatible) { >> for_each_child_of_node(parent->of_node, np) { >> @@ -204,10 +209,16 @@ EXPORT_SYMBOL(mfd_add_devices); >> >> static int mfd_remove_devices_fn(struct device *dev, void *c) >> { >> -struct platform_device *pdev = to_platform_device(dev); >> -const struct mfd_cell *cell = mfd_get_cell(pdev); >> +struct platform_device *pdev; >> +const struct mfd_cell *cell; >> atomic_t **usage_count = c; >> >> +if (dev->type != _device_type) >> +return 0; >> + >> +pdev = to_platform_device(dev); >> +cell = mfd_get_cell(pdev); >> + >> /* find the base address of usage_count pointers (for freeing) */ >> if (!*usage_count || (cell->usage_count < *usage_count)) >> *usage_count = cell->usage_count; > > I thought about this and I am not fully happy with it: > If we add the mfd devices to the usb_interface parent they are at the same > level in the device tree as the usb endpoints and stuff. I would consider > this > logically wrong. > Is this something we should take care of ? I wouldn't worry to much about it. If you use the the container platform device the container platform device would be at the same level as the usb endpoints. I did a quick search and it seams that other subsystems also register the child devices directly on the usb interface device. E.g. the media subsystem uses this a lot. - Lars -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH v2 1/4] mfd: add viperboard driver
On Tuesday 16 October 2012 at 12:58:48, Lars-Peter Clausen wrote: > On 10/16/2012 11:43 AM, Lars Poeschel wrote: > > On Tuesday 16 October 2012 at 10:40:26, Lars-Peter Clausen wrote: > >> On 10/12/2012 04:34 PM, Lars Poeschel wrote: > >> Btw. I'm wondering why is the extra platform device required? Can't you > >> not just use the usb device as the parent device for the mfd cells? > > > > This is what I first did, but this does not work. You can read about my > > first thoughts why this is not working here: (To sum it up: The device > > is housed in an usb_device, not a platform_device and This usb_device > > has no mfd_cell member.) > > > > https://lkml.org/lkml/2012/9/28/327 > > > > As I got a bit more deeper I also noticed, that mfd_add_devices > > (obviously) adds the devices "as childs" to the parent device. > > mfd_remove_devices then removes ALL "child" devices from the parent, not > > only those added by mfd_add_devices before. This does not work in the > > case of the usb parent device, because it has other childs that the usb > > layer added before (some endpoints and stuff). So I had to construct an > > "empty" (in sense of childs) mock platform_device between the usb and > > mfd. > > Ah, ok that makes sense. I was a bit confused, because there are other mfd > drivers with for example i2c or spi devices as parents and these work fine, > but I guess this is because non of them registers any additional child > devices. I guess it makes sense to create a mfd cell device type and assign > this type to newly created mfd cells and only unregister a device in > mfd_remove_devices if it has the correct device type. > > E.g. something along the lines of: > > > --- a/drivers/mfd/mfd-core.c > +++ b/drivers/mfd/mfd-core.c > @@ -21,6 +21,10 @@ > #include > #include > > +static struct device_type mfd_device_type = { > + .name = "mfd-cell", > +}; > + > int mfd_cell_enable(struct platform_device *pdev) > { > const struct mfd_cell *cell = mfd_get_cell(pdev); > @@ -91,6 +95,7 @@ static int mfd_add_device(struct device *parent, int id, > goto fail_device; > > pdev->dev.parent = parent; > + pdev->dev.type = _device_type; > > if (parent->of_node && cell->of_compatible) { > for_each_child_of_node(parent->of_node, np) { > @@ -204,10 +209,16 @@ EXPORT_SYMBOL(mfd_add_devices); > > static int mfd_remove_devices_fn(struct device *dev, void *c) > { > - struct platform_device *pdev = to_platform_device(dev); > - const struct mfd_cell *cell = mfd_get_cell(pdev); > + struct platform_device *pdev; > + const struct mfd_cell *cell; > atomic_t **usage_count = c; > > + if (dev->type != _device_type) > + return 0; > + > + pdev = to_platform_device(dev); > + cell = mfd_get_cell(pdev); > + > /* find the base address of usage_count pointers (for freeing) */ > if (!*usage_count || (cell->usage_count < *usage_count)) > *usage_count = cell->usage_count; I thought about this and I am not fully happy with it: If we add the mfd devices to the usb_interface parent they are at the same level in the device tree as the usb endpoints and stuff. I would consider this logically wrong. Is this something we should take care of ? -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH v2 1/4] mfd: add viperboard driver
On Tuesday 16 October 2012 at 12:58:48, Lars-Peter Clausen wrote: On 10/16/2012 11:43 AM, Lars Poeschel wrote: On Tuesday 16 October 2012 at 10:40:26, Lars-Peter Clausen wrote: On 10/12/2012 04:34 PM, Lars Poeschel wrote: Btw. I'm wondering why is the extra platform device required? Can't you not just use the usb device as the parent device for the mfd cells? This is what I first did, but this does not work. You can read about my first thoughts why this is not working here: (To sum it up: The device is housed in an usb_device, not a platform_device and This usb_device has no mfd_cell member.) https://lkml.org/lkml/2012/9/28/327 As I got a bit more deeper I also noticed, that mfd_add_devices (obviously) adds the devices as childs to the parent device. mfd_remove_devices then removes ALL child devices from the parent, not only those added by mfd_add_devices before. This does not work in the case of the usb parent device, because it has other childs that the usb layer added before (some endpoints and stuff). So I had to construct an empty (in sense of childs) mock platform_device between the usb and mfd. Ah, ok that makes sense. I was a bit confused, because there are other mfd drivers with for example i2c or spi devices as parents and these work fine, but I guess this is because non of them registers any additional child devices. I guess it makes sense to create a mfd cell device type and assign this type to newly created mfd cells and only unregister a device in mfd_remove_devices if it has the correct device type. E.g. something along the lines of: --- a/drivers/mfd/mfd-core.c +++ b/drivers/mfd/mfd-core.c @@ -21,6 +21,10 @@ #include linux/irqdomain.h #include linux/of.h +static struct device_type mfd_device_type = { + .name = mfd-cell, +}; + int mfd_cell_enable(struct platform_device *pdev) { const struct mfd_cell *cell = mfd_get_cell(pdev); @@ -91,6 +95,7 @@ static int mfd_add_device(struct device *parent, int id, goto fail_device; pdev-dev.parent = parent; + pdev-dev.type = mfd_device_type; if (parent-of_node cell-of_compatible) { for_each_child_of_node(parent-of_node, np) { @@ -204,10 +209,16 @@ EXPORT_SYMBOL(mfd_add_devices); static int mfd_remove_devices_fn(struct device *dev, void *c) { - struct platform_device *pdev = to_platform_device(dev); - const struct mfd_cell *cell = mfd_get_cell(pdev); + struct platform_device *pdev; + const struct mfd_cell *cell; atomic_t **usage_count = c; + if (dev-type != mfd_device_type) + return 0; + + pdev = to_platform_device(dev); + cell = mfd_get_cell(pdev); + /* find the base address of usage_count pointers (for freeing) */ if (!*usage_count || (cell-usage_count *usage_count)) *usage_count = cell-usage_count; I thought about this and I am not fully happy with it: If we add the mfd devices to the usb_interface parent they are at the same level in the device tree as the usb endpoints and stuff. I would consider this logically wrong. Is this something we should take care of ? -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH v2 1/4] mfd: add viperboard driver
On 10/18/2012 09:29 AM, Lars Poeschel wrote: On Tuesday 16 October 2012 at 12:58:48, Lars-Peter Clausen wrote: On 10/16/2012 11:43 AM, Lars Poeschel wrote: On Tuesday 16 October 2012 at 10:40:26, Lars-Peter Clausen wrote: On 10/12/2012 04:34 PM, Lars Poeschel wrote: Btw. I'm wondering why is the extra platform device required? Can't you not just use the usb device as the parent device for the mfd cells? This is what I first did, but this does not work. You can read about my first thoughts why this is not working here: (To sum it up: The device is housed in an usb_device, not a platform_device and This usb_device has no mfd_cell member.) https://lkml.org/lkml/2012/9/28/327 As I got a bit more deeper I also noticed, that mfd_add_devices (obviously) adds the devices as childs to the parent device. mfd_remove_devices then removes ALL child devices from the parent, not only those added by mfd_add_devices before. This does not work in the case of the usb parent device, because it has other childs that the usb layer added before (some endpoints and stuff). So I had to construct an empty (in sense of childs) mock platform_device between the usb and mfd. Ah, ok that makes sense. I was a bit confused, because there are other mfd drivers with for example i2c or spi devices as parents and these work fine, but I guess this is because non of them registers any additional child devices. I guess it makes sense to create a mfd cell device type and assign this type to newly created mfd cells and only unregister a device in mfd_remove_devices if it has the correct device type. E.g. something along the lines of: --- a/drivers/mfd/mfd-core.c +++ b/drivers/mfd/mfd-core.c @@ -21,6 +21,10 @@ #include linux/irqdomain.h #include linux/of.h +static struct device_type mfd_device_type = { +.name = mfd-cell, +}; + int mfd_cell_enable(struct platform_device *pdev) { const struct mfd_cell *cell = mfd_get_cell(pdev); @@ -91,6 +95,7 @@ static int mfd_add_device(struct device *parent, int id, goto fail_device; pdev-dev.parent = parent; +pdev-dev.type = mfd_device_type; if (parent-of_node cell-of_compatible) { for_each_child_of_node(parent-of_node, np) { @@ -204,10 +209,16 @@ EXPORT_SYMBOL(mfd_add_devices); static int mfd_remove_devices_fn(struct device *dev, void *c) { -struct platform_device *pdev = to_platform_device(dev); -const struct mfd_cell *cell = mfd_get_cell(pdev); +struct platform_device *pdev; +const struct mfd_cell *cell; atomic_t **usage_count = c; +if (dev-type != mfd_device_type) +return 0; + +pdev = to_platform_device(dev); +cell = mfd_get_cell(pdev); + /* find the base address of usage_count pointers (for freeing) */ if (!*usage_count || (cell-usage_count *usage_count)) *usage_count = cell-usage_count; I thought about this and I am not fully happy with it: If we add the mfd devices to the usb_interface parent they are at the same level in the device tree as the usb endpoints and stuff. I would consider this logically wrong. Is this something we should take care of ? I wouldn't worry to much about it. If you use the the container platform device the container platform device would be at the same level as the usb endpoints. I did a quick search and it seams that other subsystems also register the child devices directly on the usb interface device. E.g. the media subsystem uses this a lot. - Lars -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH v2 1/4] mfd: add viperboard driver
On 10/16/2012 11:43 AM, Lars Poeschel wrote: > On Tuesday 16 October 2012 at 10:40:26, Lars-Peter Clausen wrote: >> On 10/12/2012 04:34 PM, Lars Poeschel wrote: >>> [...] >>> +static void vprbrd_dev_release(struct device *dev) >>> +{ >>> + return; >> >> A empty release callback is usually a good indicator that something is >> wrong. The release callback will be called once the last reference to the >> device has been called, so the memory associated with the device should not >> be freed before the release callback has been called, otherwise the memory >> might be accessed after it has been freed... >> >>> +} >>> + >>> +static void vprbrd_free(struct vprbrd *dev) >>> +{ >>> + usb_put_dev(dev->usb_dev); >>> + kfree(dev); >> >> ..., so this kfree should be moved from here to the release callback. > > Thank you for catching that one! > >> Btw. I'm wondering why is the extra platform device required? Can't you not >> just use the usb device as the parent device for the mfd cells? > > This is what I first did, but this does not work. You can read about my first > thoughts why this is not working here: (To sum it up: The device is housed in > an usb_device, not a platform_device and This usb_device has no mfd_cell > member.) > > https://lkml.org/lkml/2012/9/28/327 > > As I got a bit more deeper I also noticed, that mfd_add_devices (obviously) > adds the devices "as childs" to the parent device. mfd_remove_devices then > removes ALL "child" devices from the parent, not only those added by > mfd_add_devices before. This does not work in the case of the usb parent > device, because it has other childs that the usb layer added before (some > endpoints and stuff). So I had to construct an "empty" (in sense of childs) > mock platform_device between the usb and mfd. Ah, ok that makes sense. I was a bit confused, because there are other mfd drivers with for example i2c or spi devices as parents and these work fine, but I guess this is because non of them registers any additional child devices. I guess it makes sense to create a mfd cell device type and assign this type to newly created mfd cells and only unregister a device in mfd_remove_devices if it has the correct device type. E.g. something along the lines of: --- a/drivers/mfd/mfd-core.c +++ b/drivers/mfd/mfd-core.c @@ -21,6 +21,10 @@ #include #include +static struct device_type mfd_device_type = { + .name = "mfd-cell", +}; + int mfd_cell_enable(struct platform_device *pdev) { const struct mfd_cell *cell = mfd_get_cell(pdev); @@ -91,6 +95,7 @@ static int mfd_add_device(struct device *parent, int id, goto fail_device; pdev->dev.parent = parent; + pdev->dev.type = _device_type; if (parent->of_node && cell->of_compatible) { for_each_child_of_node(parent->of_node, np) { @@ -204,10 +209,16 @@ EXPORT_SYMBOL(mfd_add_devices); static int mfd_remove_devices_fn(struct device *dev, void *c) { - struct platform_device *pdev = to_platform_device(dev); - const struct mfd_cell *cell = mfd_get_cell(pdev); + struct platform_device *pdev; + const struct mfd_cell *cell; atomic_t **usage_count = c; + if (dev->type != _device_type) + return 0; + + pdev = to_platform_device(dev); + cell = mfd_get_cell(pdev); + /* find the base address of usage_count pointers (for freeing) */ if (!*usage_count || (cell->usage_count < *usage_count)) *usage_count = cell->usage_count; -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH v2 1/4] mfd: add viperboard driver
On Tuesday 16 October 2012 at 10:40:26, Lars-Peter Clausen wrote: > On 10/12/2012 04:34 PM, Lars Poeschel wrote: > > [...] > > +static void vprbrd_dev_release(struct device *dev) > > +{ > > + return; > > A empty release callback is usually a good indicator that something is > wrong. The release callback will be called once the last reference to the > device has been called, so the memory associated with the device should not > be freed before the release callback has been called, otherwise the memory > might be accessed after it has been freed... > > > +} > > + > > +static void vprbrd_free(struct vprbrd *dev) > > +{ > > + usb_put_dev(dev->usb_dev); > > + kfree(dev); > > ..., so this kfree should be moved from here to the release callback. Thank you for catching that one! > Btw. I'm wondering why is the extra platform device required? Can't you not > just use the usb device as the parent device for the mfd cells? This is what I first did, but this does not work. You can read about my first thoughts why this is not working here: (To sum it up: The device is housed in an usb_device, not a platform_device and This usb_device has no mfd_cell member.) https://lkml.org/lkml/2012/9/28/327 As I got a bit more deeper I also noticed, that mfd_add_devices (obviously) adds the devices "as childs" to the parent device. mfd_remove_devices then removes ALL "child" devices from the parent, not only those added by mfd_add_devices before. This does not work in the case of the usb parent device, because it has other childs that the usb layer added before (some endpoints and stuff). So I had to construct an "empty" (in sense of childs) mock platform_device between the usb and mfd. -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH v2 1/4] mfd: add viperboard driver
On 10/12/2012 04:34 PM, Lars Poeschel wrote: > [...] > +static void vprbrd_dev_release(struct device *dev) > +{ > + return; A empty release callback is usually a good indicator that something is wrong. The release callback will be called once the last reference to the device has been called, so the memory associated with the device should not be freed before the release callback has been called, otherwise the memory might be accessed after it has been freed... > +} > + > +static void vprbrd_free(struct vprbrd *dev) > +{ > + usb_put_dev(dev->usb_dev); > + kfree(dev); ..., so this kfree should be moved from here to the release callback. Btw. I'm wondering why is the extra platform device required? Can't you not just use the usb device as the parent device for the mfd cells? > +} > [...][ -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH v2 1/4] mfd: add viperboard driver
On Monday 15 October 2012 at 19:09:53, Peter Meerwald wrote: > minor nitpicking below > > > From: Lars Poeschel > > > > Add mfd driver for Nano River Technologies viperboard. > > > > Signed-off-by: Lars Poeschel > > --- > > > > drivers/mfd/Kconfig| 14 > > drivers/mfd/Makefile |1 + > > drivers/mfd/viperboard.c | 149 > > include/linux/mfd/viperboard.h > > | 99 ++ 4 files changed, 263 insertions(+) > > create mode 100644 drivers/mfd/viperboard.c > > create mode 100644 include/linux/mfd/viperboard.h > > > > diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig > > index b1a1462..98d9fa3 100644 > > --- a/drivers/mfd/Kconfig > > +++ b/drivers/mfd/Kconfig > > @@ -1003,6 +1003,20 @@ config MFD_PALMAS > > > > If you say yes here you get support for the Palmas > > series of PMIC chips from Texas Instruments. > > > > +config MFD_VIPERBOARD > > +tristate "Support for Nano River Technologies Viperboard" > > probably wrong indentation (space vs. tab)? > > > + select MFD_CORE > > + depends on USB && IIO > > +default n > > +help > > + Say yes here if you want support for Nano River Technologies > > + Viperboard. > > + There are mfd cell drivers available for i2c master, adc and > > + both gpios found on the board. The spi part does not yet > > + have a driver. > > + You need to select the mfd cell drivers seperatly. > > separately > > > + The drivers do not support all features the board exposes. > > + > > > > endmenu > > endif > > > > diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile > > index 79dd22d..6ab6b64 100644 > > --- a/drivers/mfd/Makefile > > +++ b/drivers/mfd/Makefile > > @@ -128,6 +128,7 @@ obj-$(CONFIG_MFD_TPS65090) += tps65090.o > > > > obj-$(CONFIG_MFD_AAT2870_CORE) += aat2870-core.o > > obj-$(CONFIG_MFD_INTEL_MSIC) += intel_msic.o > > obj-$(CONFIG_MFD_PALMAS) += palmas.o > > > > +obj-$(CONFIG_MFD_VIPERBOARD)+= viperboard.o > > > > obj-$(CONFIG_MFD_RC5T583) += rc5t583.o rc5t583-irq.o > > obj-$(CONFIG_MFD_SEC_CORE) += sec-core.o sec-irq.o > > obj-$(CONFIG_MFD_ANATOP) += anatop-mfd.o > > > > diff --git a/drivers/mfd/viperboard.c b/drivers/mfd/viperboard.c > > new file mode 100644 > > index 000..8095ea2 > > --- /dev/null > > +++ b/drivers/mfd/viperboard.c > > @@ -0,0 +1,149 @@ > > +/* > > + * Nano River Technologies viperboard driver > > + * > > + * This is the core driver for the viperboard. There are cell drivers > > + * available for I2C, ADC and both GPIOs. SPI is not yet supported > > full stop (.) missing > > > + * The drivers do not support all features the board exposes. See user > > + * manual of the viperboard. > > + * > > + * (C) 2012 by Lemonage GmbH > > + * Author: Lars Poeschel > > + * All rights reserved. > > + * > > + * This program is free software; you can redistribute it and/or > > modify it + * under the terms of the GNU General Public License as > > published by the + * Free Software Foundation; either version 2 of the > > License, or (at your + * option) any later version. > > + * > > + */ > > + > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > + > > +#include > > +#include > > + > > +#include > > + > > + > > +static const struct usb_device_id vprbrd_table[] = { > > + { USB_DEVICE(0x2058, 0x1005) }, /* Nano River Technologies */ > > + { } /* Terminating entry */ > > +}; > > + > > +MODULE_DEVICE_TABLE(usb, vprbrd_table); > > + > > +static void vprbrd_dev_release(struct device *dev) > > +{ > > + return; > > return not needed > > > +} > > + > > +static void vprbrd_free(struct vprbrd *dev) > > +{ > > + usb_put_dev(dev->usb_dev); > > + kfree(dev); > > +} Thanks for your review. I will change this and after waiting some time for additional comments, I will do a version 3 of the whole patchset. Regards, Lars -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH v2 1/4] mfd: add viperboard driver
On Monday 15 October 2012 at 19:09:53, Peter Meerwald wrote: minor nitpicking below From: Lars Poeschel poesc...@lemonage.de Add mfd driver for Nano River Technologies viperboard. Signed-off-by: Lars Poeschel poesc...@lemonage.de --- drivers/mfd/Kconfig| 14 drivers/mfd/Makefile |1 + drivers/mfd/viperboard.c | 149 include/linux/mfd/viperboard.h | 99 ++ 4 files changed, 263 insertions(+) create mode 100644 drivers/mfd/viperboard.c create mode 100644 include/linux/mfd/viperboard.h diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index b1a1462..98d9fa3 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig @@ -1003,6 +1003,20 @@ config MFD_PALMAS If you say yes here you get support for the Palmas series of PMIC chips from Texas Instruments. +config MFD_VIPERBOARD +tristate Support for Nano River Technologies Viperboard probably wrong indentation (space vs. tab)? + select MFD_CORE + depends on USB IIO +default n +help + Say yes here if you want support for Nano River Technologies + Viperboard. + There are mfd cell drivers available for i2c master, adc and + both gpios found on the board. The spi part does not yet + have a driver. + You need to select the mfd cell drivers seperatly. separately + The drivers do not support all features the board exposes. + endmenu endif diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile index 79dd22d..6ab6b64 100644 --- a/drivers/mfd/Makefile +++ b/drivers/mfd/Makefile @@ -128,6 +128,7 @@ obj-$(CONFIG_MFD_TPS65090) += tps65090.o obj-$(CONFIG_MFD_AAT2870_CORE) += aat2870-core.o obj-$(CONFIG_MFD_INTEL_MSIC) += intel_msic.o obj-$(CONFIG_MFD_PALMAS) += palmas.o +obj-$(CONFIG_MFD_VIPERBOARD)+= viperboard.o obj-$(CONFIG_MFD_RC5T583) += rc5t583.o rc5t583-irq.o obj-$(CONFIG_MFD_SEC_CORE) += sec-core.o sec-irq.o obj-$(CONFIG_MFD_ANATOP) += anatop-mfd.o diff --git a/drivers/mfd/viperboard.c b/drivers/mfd/viperboard.c new file mode 100644 index 000..8095ea2 --- /dev/null +++ b/drivers/mfd/viperboard.c @@ -0,0 +1,149 @@ +/* + * Nano River Technologies viperboard driver + * + * This is the core driver for the viperboard. There are cell drivers + * available for I2C, ADC and both GPIOs. SPI is not yet supported full stop (.) missing + * The drivers do not support all features the board exposes. See user + * manual of the viperboard. + * + * (C) 2012 by Lemonage GmbH + * Author: Lars Poeschel poesc...@lemonage.de + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + */ + +#include linux/kernel.h +#include linux/errno.h +#include linux/module.h +#include linux/slab.h +#include linux/types.h +#include linux/mutex.h + +#include linux/mfd/core.h +#include linux/mfd/viperboard.h + +#include linux/usb.h + + +static const struct usb_device_id vprbrd_table[] = { + { USB_DEVICE(0x2058, 0x1005) }, /* Nano River Technologies */ + { } /* Terminating entry */ +}; + +MODULE_DEVICE_TABLE(usb, vprbrd_table); + +static void vprbrd_dev_release(struct device *dev) +{ + return; return not needed +} + +static void vprbrd_free(struct vprbrd *dev) +{ + usb_put_dev(dev-usb_dev); + kfree(dev); +} Thanks for your review. I will change this and after waiting some time for additional comments, I will do a version 3 of the whole patchset. Regards, Lars -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH v2 1/4] mfd: add viperboard driver
On 10/12/2012 04:34 PM, Lars Poeschel wrote: [...] +static void vprbrd_dev_release(struct device *dev) +{ + return; A empty release callback is usually a good indicator that something is wrong. The release callback will be called once the last reference to the device has been called, so the memory associated with the device should not be freed before the release callback has been called, otherwise the memory might be accessed after it has been freed... +} + +static void vprbrd_free(struct vprbrd *dev) +{ + usb_put_dev(dev-usb_dev); + kfree(dev); ..., so this kfree should be moved from here to the release callback. Btw. I'm wondering why is the extra platform device required? Can't you not just use the usb device as the parent device for the mfd cells? +} [...][ -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH v2 1/4] mfd: add viperboard driver
On Tuesday 16 October 2012 at 10:40:26, Lars-Peter Clausen wrote: On 10/12/2012 04:34 PM, Lars Poeschel wrote: [...] +static void vprbrd_dev_release(struct device *dev) +{ + return; A empty release callback is usually a good indicator that something is wrong. The release callback will be called once the last reference to the device has been called, so the memory associated with the device should not be freed before the release callback has been called, otherwise the memory might be accessed after it has been freed... +} + +static void vprbrd_free(struct vprbrd *dev) +{ + usb_put_dev(dev-usb_dev); + kfree(dev); ..., so this kfree should be moved from here to the release callback. Thank you for catching that one! Btw. I'm wondering why is the extra platform device required? Can't you not just use the usb device as the parent device for the mfd cells? This is what I first did, but this does not work. You can read about my first thoughts why this is not working here: (To sum it up: The device is housed in an usb_device, not a platform_device and This usb_device has no mfd_cell member.) https://lkml.org/lkml/2012/9/28/327 As I got a bit more deeper I also noticed, that mfd_add_devices (obviously) adds the devices as childs to the parent device. mfd_remove_devices then removes ALL child devices from the parent, not only those added by mfd_add_devices before. This does not work in the case of the usb parent device, because it has other childs that the usb layer added before (some endpoints and stuff). So I had to construct an empty (in sense of childs) mock platform_device between the usb and mfd. -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH v2 1/4] mfd: add viperboard driver
On 10/16/2012 11:43 AM, Lars Poeschel wrote: On Tuesday 16 October 2012 at 10:40:26, Lars-Peter Clausen wrote: On 10/12/2012 04:34 PM, Lars Poeschel wrote: [...] +static void vprbrd_dev_release(struct device *dev) +{ + return; A empty release callback is usually a good indicator that something is wrong. The release callback will be called once the last reference to the device has been called, so the memory associated with the device should not be freed before the release callback has been called, otherwise the memory might be accessed after it has been freed... +} + +static void vprbrd_free(struct vprbrd *dev) +{ + usb_put_dev(dev-usb_dev); + kfree(dev); ..., so this kfree should be moved from here to the release callback. Thank you for catching that one! Btw. I'm wondering why is the extra platform device required? Can't you not just use the usb device as the parent device for the mfd cells? This is what I first did, but this does not work. You can read about my first thoughts why this is not working here: (To sum it up: The device is housed in an usb_device, not a platform_device and This usb_device has no mfd_cell member.) https://lkml.org/lkml/2012/9/28/327 As I got a bit more deeper I also noticed, that mfd_add_devices (obviously) adds the devices as childs to the parent device. mfd_remove_devices then removes ALL child devices from the parent, not only those added by mfd_add_devices before. This does not work in the case of the usb parent device, because it has other childs that the usb layer added before (some endpoints and stuff). So I had to construct an empty (in sense of childs) mock platform_device between the usb and mfd. Ah, ok that makes sense. I was a bit confused, because there are other mfd drivers with for example i2c or spi devices as parents and these work fine, but I guess this is because non of them registers any additional child devices. I guess it makes sense to create a mfd cell device type and assign this type to newly created mfd cells and only unregister a device in mfd_remove_devices if it has the correct device type. E.g. something along the lines of: --- a/drivers/mfd/mfd-core.c +++ b/drivers/mfd/mfd-core.c @@ -21,6 +21,10 @@ #include linux/irqdomain.h #include linux/of.h +static struct device_type mfd_device_type = { + .name = mfd-cell, +}; + int mfd_cell_enable(struct platform_device *pdev) { const struct mfd_cell *cell = mfd_get_cell(pdev); @@ -91,6 +95,7 @@ static int mfd_add_device(struct device *parent, int id, goto fail_device; pdev-dev.parent = parent; + pdev-dev.type = mfd_device_type; if (parent-of_node cell-of_compatible) { for_each_child_of_node(parent-of_node, np) { @@ -204,10 +209,16 @@ EXPORT_SYMBOL(mfd_add_devices); static int mfd_remove_devices_fn(struct device *dev, void *c) { - struct platform_device *pdev = to_platform_device(dev); - const struct mfd_cell *cell = mfd_get_cell(pdev); + struct platform_device *pdev; + const struct mfd_cell *cell; atomic_t **usage_count = c; + if (dev-type != mfd_device_type) + return 0; + + pdev = to_platform_device(dev); + cell = mfd_get_cell(pdev); + /* find the base address of usage_count pointers (for freeing) */ if (!*usage_count || (cell-usage_count *usage_count)) *usage_count = cell-usage_count; -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH v2 1/4] mfd: add viperboard driver
minor nitpicking below > From: Lars Poeschel > > Add mfd driver for Nano River Technologies viperboard. > > Signed-off-by: Lars Poeschel > --- > drivers/mfd/Kconfig| 14 > drivers/mfd/Makefile |1 + > drivers/mfd/viperboard.c | 149 > > include/linux/mfd/viperboard.h | 99 ++ > 4 files changed, 263 insertions(+) > create mode 100644 drivers/mfd/viperboard.c > create mode 100644 include/linux/mfd/viperboard.h > > diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig > index b1a1462..98d9fa3 100644 > --- a/drivers/mfd/Kconfig > +++ b/drivers/mfd/Kconfig > @@ -1003,6 +1003,20 @@ config MFD_PALMAS > If you say yes here you get support for the Palmas > series of PMIC chips from Texas Instruments. > > +config MFD_VIPERBOARD > +tristate "Support for Nano River Technologies Viperboard" probably wrong indentation (space vs. tab)? > + select MFD_CORE > + depends on USB && IIO > +default n > +help > + Say yes here if you want support for Nano River Technologies > + Viperboard. > + There are mfd cell drivers available for i2c master, adc and > + both gpios found on the board. The spi part does not yet > + have a driver. > + You need to select the mfd cell drivers seperatly. separately > + The drivers do not support all features the board exposes. > + > endmenu > endif > > diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile > index 79dd22d..6ab6b64 100644 > --- a/drivers/mfd/Makefile > +++ b/drivers/mfd/Makefile > @@ -128,6 +128,7 @@ obj-$(CONFIG_MFD_TPS65090)+= tps65090.o > obj-$(CONFIG_MFD_AAT2870_CORE) += aat2870-core.o > obj-$(CONFIG_MFD_INTEL_MSIC) += intel_msic.o > obj-$(CONFIG_MFD_PALMAS) += palmas.o > +obj-$(CONFIG_MFD_VIPERBOARD)+= viperboard.o > obj-$(CONFIG_MFD_RC5T583)+= rc5t583.o rc5t583-irq.o > obj-$(CONFIG_MFD_SEC_CORE) += sec-core.o sec-irq.o > obj-$(CONFIG_MFD_ANATOP) += anatop-mfd.o > diff --git a/drivers/mfd/viperboard.c b/drivers/mfd/viperboard.c > new file mode 100644 > index 000..8095ea2 > --- /dev/null > +++ b/drivers/mfd/viperboard.c > @@ -0,0 +1,149 @@ > +/* > + * Nano River Technologies viperboard driver > + * > + * This is the core driver for the viperboard. There are cell drivers > + * available for I2C, ADC and both GPIOs. SPI is not yet supported full stop (.) missing > + * The drivers do not support all features the board exposes. See user > + * manual of the viperboard. > + * > + * (C) 2012 by Lemonage GmbH > + * Author: Lars Poeschel > + * All rights reserved. > + * > + * This program is free software; you can redistribute it and/or modify it > + * under the terms of the GNU General Public License as published by the > + * Free Software Foundation; either version 2 of the License, or (at your > + * option) any later version. > + * > + */ > + > +#include > +#include > +#include > +#include > +#include > +#include > + > +#include > +#include > + > +#include > + > + > +static const struct usb_device_id vprbrd_table[] = { > + { USB_DEVICE(0x2058, 0x1005) }, /* Nano River Technologies */ > + { } /* Terminating entry */ > +}; > + > +MODULE_DEVICE_TABLE(usb, vprbrd_table); > + > +static void vprbrd_dev_release(struct device *dev) > +{ > + return; return not needed > +} > + > +static void vprbrd_free(struct vprbrd *dev) > +{ > + usb_put_dev(dev->usb_dev); > + kfree(dev); > +} -- Peter Meerwald +43-664-218 (mobile) -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH v2 1/4] mfd: add viperboard driver
minor nitpicking below From: Lars Poeschel poesc...@lemonage.de Add mfd driver for Nano River Technologies viperboard. Signed-off-by: Lars Poeschel poesc...@lemonage.de --- drivers/mfd/Kconfig| 14 drivers/mfd/Makefile |1 + drivers/mfd/viperboard.c | 149 include/linux/mfd/viperboard.h | 99 ++ 4 files changed, 263 insertions(+) create mode 100644 drivers/mfd/viperboard.c create mode 100644 include/linux/mfd/viperboard.h diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index b1a1462..98d9fa3 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig @@ -1003,6 +1003,20 @@ config MFD_PALMAS If you say yes here you get support for the Palmas series of PMIC chips from Texas Instruments. +config MFD_VIPERBOARD +tristate Support for Nano River Technologies Viperboard probably wrong indentation (space vs. tab)? + select MFD_CORE + depends on USB IIO +default n +help + Say yes here if you want support for Nano River Technologies + Viperboard. + There are mfd cell drivers available for i2c master, adc and + both gpios found on the board. The spi part does not yet + have a driver. + You need to select the mfd cell drivers seperatly. separately + The drivers do not support all features the board exposes. + endmenu endif diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile index 79dd22d..6ab6b64 100644 --- a/drivers/mfd/Makefile +++ b/drivers/mfd/Makefile @@ -128,6 +128,7 @@ obj-$(CONFIG_MFD_TPS65090)+= tps65090.o obj-$(CONFIG_MFD_AAT2870_CORE) += aat2870-core.o obj-$(CONFIG_MFD_INTEL_MSIC) += intel_msic.o obj-$(CONFIG_MFD_PALMAS) += palmas.o +obj-$(CONFIG_MFD_VIPERBOARD)+= viperboard.o obj-$(CONFIG_MFD_RC5T583)+= rc5t583.o rc5t583-irq.o obj-$(CONFIG_MFD_SEC_CORE) += sec-core.o sec-irq.o obj-$(CONFIG_MFD_ANATOP) += anatop-mfd.o diff --git a/drivers/mfd/viperboard.c b/drivers/mfd/viperboard.c new file mode 100644 index 000..8095ea2 --- /dev/null +++ b/drivers/mfd/viperboard.c @@ -0,0 +1,149 @@ +/* + * Nano River Technologies viperboard driver + * + * This is the core driver for the viperboard. There are cell drivers + * available for I2C, ADC and both GPIOs. SPI is not yet supported full stop (.) missing + * The drivers do not support all features the board exposes. See user + * manual of the viperboard. + * + * (C) 2012 by Lemonage GmbH + * Author: Lars Poeschel poesc...@lemonage.de + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + */ + +#include linux/kernel.h +#include linux/errno.h +#include linux/module.h +#include linux/slab.h +#include linux/types.h +#include linux/mutex.h + +#include linux/mfd/core.h +#include linux/mfd/viperboard.h + +#include linux/usb.h + + +static const struct usb_device_id vprbrd_table[] = { + { USB_DEVICE(0x2058, 0x1005) }, /* Nano River Technologies */ + { } /* Terminating entry */ +}; + +MODULE_DEVICE_TABLE(usb, vprbrd_table); + +static void vprbrd_dev_release(struct device *dev) +{ + return; return not needed +} + +static void vprbrd_free(struct vprbrd *dev) +{ + usb_put_dev(dev-usb_dev); + kfree(dev); +} -- Peter Meerwald +43-664-218 (mobile) -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v2 1/4] mfd: add viperboard driver
From: Lars Poeschel Add mfd driver for Nano River Technologies viperboard. Signed-off-by: Lars Poeschel --- drivers/mfd/Kconfig| 14 drivers/mfd/Makefile |1 + drivers/mfd/viperboard.c | 149 include/linux/mfd/viperboard.h | 99 ++ 4 files changed, 263 insertions(+) create mode 100644 drivers/mfd/viperboard.c create mode 100644 include/linux/mfd/viperboard.h diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index b1a1462..98d9fa3 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig @@ -1003,6 +1003,20 @@ config MFD_PALMAS If you say yes here you get support for the Palmas series of PMIC chips from Texas Instruments. +config MFD_VIPERBOARD +tristate "Support for Nano River Technologies Viperboard" + select MFD_CORE + depends on USB && IIO +default n +help + Say yes here if you want support for Nano River Technologies + Viperboard. + There are mfd cell drivers available for i2c master, adc and + both gpios found on the board. The spi part does not yet + have a driver. + You need to select the mfd cell drivers seperatly. + The drivers do not support all features the board exposes. + endmenu endif diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile index 79dd22d..6ab6b64 100644 --- a/drivers/mfd/Makefile +++ b/drivers/mfd/Makefile @@ -128,6 +128,7 @@ obj-$(CONFIG_MFD_TPS65090) += tps65090.o obj-$(CONFIG_MFD_AAT2870_CORE) += aat2870-core.o obj-$(CONFIG_MFD_INTEL_MSIC) += intel_msic.o obj-$(CONFIG_MFD_PALMAS) += palmas.o +obj-$(CONFIG_MFD_VIPERBOARD)+= viperboard.o obj-$(CONFIG_MFD_RC5T583) += rc5t583.o rc5t583-irq.o obj-$(CONFIG_MFD_SEC_CORE) += sec-core.o sec-irq.o obj-$(CONFIG_MFD_ANATOP) += anatop-mfd.o diff --git a/drivers/mfd/viperboard.c b/drivers/mfd/viperboard.c new file mode 100644 index 000..8095ea2 --- /dev/null +++ b/drivers/mfd/viperboard.c @@ -0,0 +1,149 @@ +/* + * Nano River Technologies viperboard driver + * + * This is the core driver for the viperboard. There are cell drivers + * available for I2C, ADC and both GPIOs. SPI is not yet supported + * The drivers do not support all features the board exposes. See user + * manual of the viperboard. + * + * (C) 2012 by Lemonage GmbH + * Author: Lars Poeschel + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + */ + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + + +static const struct usb_device_id vprbrd_table[] = { + { USB_DEVICE(0x2058, 0x1005) }, /* Nano River Technologies */ + { } /* Terminating entry */ +}; + +MODULE_DEVICE_TABLE(usb, vprbrd_table); + +static void vprbrd_dev_release(struct device *dev) +{ + return; +} + +static void vprbrd_free(struct vprbrd *dev) +{ + usb_put_dev(dev->usb_dev); + kfree(dev); +} + +static struct mfd_cell vprbrd_devs[] = { +}; + +static int vprbrd_probe(struct usb_interface *interface, + const struct usb_device_id *id) +{ + struct vprbrd *vb; + + u16 version = 0; + int pipe, ret; + unsigned char buf[1]; + + /* allocate memory for our device state and initialize it */ + vb = kzalloc(sizeof(*vb), GFP_KERNEL); + if (vb == NULL) { + dev_err(>dev, "Out of memory\n"); + return -ENOMEM; + } + + device_initialize(>pdev.dev); + vb->pdev.dev.parent = >dev; + vb->pdev.dev.release = vprbrd_dev_release; + dev_set_name(>pdev.dev, "%s-%s-mfd-holder", + dev_driver_string(>dev), dev_name(>dev)); + ret = device_add(>pdev.dev); + if (ret) { + dev_err(>dev, "Failed to add mfd holder device."); + goto error; + } + + mutex_init(>lock); + + vb->usb_dev = usb_get_dev(interface_to_usbdev(interface)); + + /* save our data pointer in this interface device */ + usb_set_intfdata(interface, vb); + dev_set_drvdata(>pdev.dev, vb); + + /* get version information, major first, minor then */ + pipe = usb_rcvctrlpipe(vb->usb_dev, 0); + ret = usb_control_msg(vb->usb_dev, pipe, 0xea, 0xc0, 0x, + 0x, buf, 1, 100); + if (ret == 1) + version = buf[0]; + + ret = usb_control_msg(vb->usb_dev, pipe, 0xeb, 0xc0, 0x, + 0x, buf, 1, 100); + if (ret == 1) { + version <<= 8; + version = version | buf[0]; + } + + dev_info(>dev, +"version
[PATCH v2 1/4] mfd: add viperboard driver
From: Lars Poeschel poesc...@lemonage.de Add mfd driver for Nano River Technologies viperboard. Signed-off-by: Lars Poeschel poesc...@lemonage.de --- drivers/mfd/Kconfig| 14 drivers/mfd/Makefile |1 + drivers/mfd/viperboard.c | 149 include/linux/mfd/viperboard.h | 99 ++ 4 files changed, 263 insertions(+) create mode 100644 drivers/mfd/viperboard.c create mode 100644 include/linux/mfd/viperboard.h diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index b1a1462..98d9fa3 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig @@ -1003,6 +1003,20 @@ config MFD_PALMAS If you say yes here you get support for the Palmas series of PMIC chips from Texas Instruments. +config MFD_VIPERBOARD +tristate Support for Nano River Technologies Viperboard + select MFD_CORE + depends on USB IIO +default n +help + Say yes here if you want support for Nano River Technologies + Viperboard. + There are mfd cell drivers available for i2c master, adc and + both gpios found on the board. The spi part does not yet + have a driver. + You need to select the mfd cell drivers seperatly. + The drivers do not support all features the board exposes. + endmenu endif diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile index 79dd22d..6ab6b64 100644 --- a/drivers/mfd/Makefile +++ b/drivers/mfd/Makefile @@ -128,6 +128,7 @@ obj-$(CONFIG_MFD_TPS65090) += tps65090.o obj-$(CONFIG_MFD_AAT2870_CORE) += aat2870-core.o obj-$(CONFIG_MFD_INTEL_MSIC) += intel_msic.o obj-$(CONFIG_MFD_PALMAS) += palmas.o +obj-$(CONFIG_MFD_VIPERBOARD)+= viperboard.o obj-$(CONFIG_MFD_RC5T583) += rc5t583.o rc5t583-irq.o obj-$(CONFIG_MFD_SEC_CORE) += sec-core.o sec-irq.o obj-$(CONFIG_MFD_ANATOP) += anatop-mfd.o diff --git a/drivers/mfd/viperboard.c b/drivers/mfd/viperboard.c new file mode 100644 index 000..8095ea2 --- /dev/null +++ b/drivers/mfd/viperboard.c @@ -0,0 +1,149 @@ +/* + * Nano River Technologies viperboard driver + * + * This is the core driver for the viperboard. There are cell drivers + * available for I2C, ADC and both GPIOs. SPI is not yet supported + * The drivers do not support all features the board exposes. See user + * manual of the viperboard. + * + * (C) 2012 by Lemonage GmbH + * Author: Lars Poeschel poesc...@lemonage.de + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + */ + +#include linux/kernel.h +#include linux/errno.h +#include linux/module.h +#include linux/slab.h +#include linux/types.h +#include linux/mutex.h + +#include linux/mfd/core.h +#include linux/mfd/viperboard.h + +#include linux/usb.h + + +static const struct usb_device_id vprbrd_table[] = { + { USB_DEVICE(0x2058, 0x1005) }, /* Nano River Technologies */ + { } /* Terminating entry */ +}; + +MODULE_DEVICE_TABLE(usb, vprbrd_table); + +static void vprbrd_dev_release(struct device *dev) +{ + return; +} + +static void vprbrd_free(struct vprbrd *dev) +{ + usb_put_dev(dev-usb_dev); + kfree(dev); +} + +static struct mfd_cell vprbrd_devs[] = { +}; + +static int vprbrd_probe(struct usb_interface *interface, + const struct usb_device_id *id) +{ + struct vprbrd *vb; + + u16 version = 0; + int pipe, ret; + unsigned char buf[1]; + + /* allocate memory for our device state and initialize it */ + vb = kzalloc(sizeof(*vb), GFP_KERNEL); + if (vb == NULL) { + dev_err(interface-dev, Out of memory\n); + return -ENOMEM; + } + + device_initialize(vb-pdev.dev); + vb-pdev.dev.parent = interface-dev; + vb-pdev.dev.release = vprbrd_dev_release; + dev_set_name(vb-pdev.dev, %s-%s-mfd-holder, + dev_driver_string(interface-dev), dev_name(interface-dev)); + ret = device_add(vb-pdev.dev); + if (ret) { + dev_err(interface-dev, Failed to add mfd holder device.); + goto error; + } + + mutex_init(vb-lock); + + vb-usb_dev = usb_get_dev(interface_to_usbdev(interface)); + + /* save our data pointer in this interface device */ + usb_set_intfdata(interface, vb); + dev_set_drvdata(vb-pdev.dev, vb); + + /* get version information, major first, minor then */ + pipe = usb_rcvctrlpipe(vb-usb_dev, 0); + ret = usb_control_msg(vb-usb_dev, pipe, 0xea, 0xc0, 0x, + 0x, buf, 1, 100); + if (ret == 1) + version = buf[0]; + + ret = usb_control_msg(vb-usb_dev,