Message ID | 1412606587-3323-1-git-send-email-muth@cypress.com |
---|---|
State | Not Applicable, archived |
Headers | show |
On Mon, 06 Oct 2014, Muthu Mani wrote: > Adds support for USB-I2C/GPIO interfaces of Cypress Semiconductor > CYUSBS234 USB-Serial Bridge controller. > > Details about the device can be found at: > http://www.cypress.com/?rID=84126 > > Signed-off-by: Muthu Mani <muth@cypress.com> > Signed-off-by: Rajaram Regupathy <rera@cypress.com> > --- > Changes since v2: > * Used auto mfd id to support multiple devices > * Cleaned up the code > > Changes since v1: > * Identified different serial interface and loaded correct cell driver > * Formed a mfd id to support multiple devices > * Removed unused platform device > > drivers/mfd/Kconfig | 12 +++ > drivers/mfd/Makefile | 1 + > drivers/mfd/cyusbs23x.c | 167 ++++++++++++++++++++++++++++++++++++++++++ > include/linux/mfd/cyusbs23x.h | 62 ++++++++++++++++ > 4 files changed, 242 insertions(+) > create mode 100644 drivers/mfd/cyusbs23x.c > create mode 100644 include/linux/mfd/cyusbs23x.h > > diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig > index de5abf2..a31e9e3 100644 > --- a/drivers/mfd/Kconfig > +++ b/drivers/mfd/Kconfig > @@ -116,6 +116,18 @@ config MFD_ASIC3 > This driver supports the ASIC3 multifunction chip found on many > PDAs (mainly iPAQ and HTC based ones) > > +config MFD_CYUSBS23X > + tristate "Cypress CYUSBS23x USB Serial Bridge controller" White space issue here. > + select MFD_CORE > + depends on USB > + default n > + help > + Say yes here if you want support for Cypress Semiconductor > + CYUSBS23x USB-Serial Bridge controller. > + > + This driver can also be built as a module. If so, the module will be > + called cyusbs23x. > + > config PMIC_DA903X > bool "Dialog Semiconductor DA9030/DA9034 PMIC Support" > depends on I2C=y > diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile > index f001487..fc5bcd1 100644 > --- a/drivers/mfd/Makefile > +++ b/drivers/mfd/Makefile > @@ -151,6 +151,7 @@ si476x-core-y := si476x-cmd.o si476x-prop.o si476x-i2c.o > obj-$(CONFIG_MFD_SI476X_CORE) += si476x-core.o > > obj-$(CONFIG_MFD_CS5535) += cs5535-mfd.o > +obj-$(CONFIG_MFD_CYUSBS23X) += cyusbs23x.o > obj-$(CONFIG_MFD_OMAP_USB_HOST) += omap-usb-host.o omap-usb-tll.o > obj-$(CONFIG_MFD_PM8921_CORE) += pm8921-core.o ssbi.o > obj-$(CONFIG_TPS65911_COMPARATOR) += tps65911-comparator.o > diff --git a/drivers/mfd/cyusbs23x.c b/drivers/mfd/cyusbs23x.c > new file mode 100644 > index 0000000..c70ea40 > --- /dev/null > +++ b/drivers/mfd/cyusbs23x.c > @@ -0,0 +1,167 @@ > +/* > + * Cypress USB-Serial Bridge Controller USB adapter driver > + * > + * Copyright (c) 2014 Cypress Semiconductor Corporation. > + * > + * Author: > + * Muthu Mani <muth@cypress.com> > + * > + * Additional contributors include: > + * Rajaram Regupathy <rera@cypress.com> > + * > + * This program is free software; you can redistribute it and/or modify it > + * under the terms of the GNU General Public License version 2 as published by > + * the Free Software Foundation. > + */ > + > +/* > + * This is core MFD driver for Cypress Semiconductor CYUSBS234 USB-Serial > + * Bridge controller. CYUSBS234 offers a single channel serial interface > + * (I2C/SPI/UART). It can be configured to enable either of I2C, SPI, UART > + * interfaces. The GPIOs are also available to access. > + * Details about the device can be found at: > + * http://www.cypress.com/?rID=84126 > + * > + * Separate cell drivers are available for I2C and GPIO. SPI and UART are not > + * supported yet. All GPIOs are exposed for get operation. However, only > + * unused GPIOs can be set. > + */ > + > +#include <linux/kernel.h> > +#include <linux/errno.h> > +#include <linux/module.h> > +#include <linux/slab.h> > +#include <linux/types.h> > +#include <linux/mutex.h> > + This '\n' is superfluous, please remove it. > +#include <linux/mfd/core.h> > +#include <linux/mfd/cyusbs23x.h> > + > +#include <linux/usb.h> > + > +static const struct usb_device_id cyusbs23x_usb_table[] = { > + { USB_DEVICE(0x04b4, 0x0004) }, /* Cypress Semiconductor */ > + { } /* Terminating entry */ This comment is not required, please remove it. > +}; > + > +MODULE_DEVICE_TABLE(usb, cyusbs23x_usb_table); > + > +static const struct mfd_cell cyusbs23x_i2c_devs[] = { > + { > + .name = "cyusbs23x-i2c", > + }, > + { > + .name = "cyusbs23x-gpio", > + }, > +}; > + > +static int update_ep_details(struct usb_interface *interface, > + struct cyusbs23x *cyusbs) > +{ > + struct usb_host_interface *iface_desc; > + struct usb_endpoint_descriptor *ep; > + int i; > + > + iface_desc = interface->cur_altsetting; > + > + for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) { > + > + ep = &iface_desc->endpoint[i].desc; > + > + if (!cyusbs->bulk_in_ep_num && usb_endpoint_is_bulk_in(ep)) > + cyusbs->bulk_in_ep_num = ep->bEndpointAddress; > + if (!cyusbs->bulk_out_ep_num && usb_endpoint_is_bulk_out(ep)) > + cyusbs->bulk_out_ep_num = ep->bEndpointAddress; > + if (!cyusbs->intr_in_ep_num && usb_endpoint_is_int_in(ep)) > + cyusbs->intr_in_ep_num = ep->bEndpointAddress; > + } All of the USB specific code in this driver will require a USB Ack. > + dev_dbg(&interface->dev, "%s intr_in=%d, bulk_in=%d, bulk_out=%d\n", > + __func__, cyusbs->intr_in_ep_num , > + cyusbs->bulk_in_ep_num, cyusbs->bulk_out_ep_num); > + > + if (!cyusbs->bulk_in_ep_num || !cyusbs->bulk_out_ep_num || > + !cyusbs->intr_in_ep_num) > + return -ENODEV; > + > + return 0; > +} > + > +static int cyusbs23x_probe(struct usb_interface *interface, > + const struct usb_device_id *id) > +{ > + struct cyusbs23x *cyusbs; > + const struct mfd_cell *cyusbs23x_devs; > + int ret, ndevs = 0; > + u8 sub_class; > + > + cyusbs = kzalloc(sizeof(*cyusbs), GFP_KERNEL); Any reason for not using managed resources (devm_*)? > + if (cyusbs == NULL) if (!cyusbs) > + return -ENOMEM; > + > + cyusbs->usb_dev = usb_get_dev(interface_to_usbdev(interface)); Can you do this last? Then you can remove the 'error' error path. > + cyusbs->usb_intf = interface; > + cyusbs->intf_num = interface->cur_altsetting->desc.bInterfaceNumber; If you're already saving 'interface' there is no need to save this also, just extract it from 'cyusbs->usb_intf' when you need it. > + ret = update_ep_details(interface, cyusbs); > + if (ret < 0) { Can ret be > 0? If not, just do 'if (ret)' > + dev_err(&interface->dev, "invalid interface\n"); If you put the error message in update_ep_details() can you print out a more specific error message and remove this line. > + goto error; > + } > + > + usb_set_intfdata(interface, cyusbs); > + > + /* Serial interfaces (I2C, SPI, UART) differ in interface subclass */ > + sub_class = interface->cur_altsetting->desc.bInterfaceSubClass; > + switch (sub_class) { This is a waste of a variable and adds nothing to the code. Just switch() for 'interface->cur_altsetting->desc.bInterfaceSubClass'. > + case CY_USBS_SCB_I2C: > + dev_info(&interface->dev, "I2C interface found\n"); Was it even lost? Would "using I2C interface" be better? > + cyusbs23x_devs = cyusbs23x_i2c_devs; > + ndevs = ARRAY_SIZE(cyusbs23x_i2c_devs); > + break; I assume there will be other interfaces supported at a later date? If not, this switch() is pretty over-the-top. > + default: > + dev_err(&interface->dev, "unsupported subclass\n"); > + ret = -ENODEV; > + goto error; > + } > + > + ret = mfd_add_devices(&interface->dev, PLATFORM_DEVID_AUTO, > + cyusbs23x_devs, ndevs, NULL, 0, NULL); > + if (ret != 0) { if (ret) > + dev_err(&interface->dev, "Failed to add mfd devices to core\n"); "Failed to register devices" > + goto error; > + } > + > + return 0; > + > +error: > + usb_put_dev(cyusbs->usb_dev); > + kfree(cyusbs); > + > + return ret; > +} > + > +static void cyusbs23x_disconnect(struct usb_interface *interface) > +{ > + struct cyusbs23x *cyusbs = usb_get_intfdata(interface); > + > + mfd_remove_devices(&interface->dev); > + usb_put_dev(cyusbs->usb_dev); > + kfree(cyusbs); If you use managed resources, you can remove this line. > + dev_dbg(&interface->dev, "disconnected\n"); Please remove this line. > +} > + > +static struct usb_driver cyusbs23x_usb_driver = { > + .name = "cyusbs23x", > + .probe = cyusbs23x_probe, > + .disconnect = cyusbs23x_disconnect, > + .id_table = cyusbs23x_usb_table, > +}; > + > +module_usb_driver(cyusbs23x_usb_driver); > + > +MODULE_AUTHOR("Rajaram Regupathy <rera@cypress.com>"); > +MODULE_AUTHOR("Muthu Mani <muth@cypress.com>"); > +MODULE_DESCRIPTION("Cypress CYUSBS23x mfd core driver"); s/mfd/MFD/ > +MODULE_LICENSE("GPL v2"); > diff --git a/include/linux/mfd/cyusbs23x.h b/include/linux/mfd/cyusbs23x.h > new file mode 100644 > index 0000000..1580d98 > --- /dev/null > +++ b/include/linux/mfd/cyusbs23x.h > @@ -0,0 +1,62 @@ > +/* > + * Cypress USB-Serial Bridge Controller definitions > + * > + * Copyright (c) 2014 Cypress Semiconductor Corporation. > + * > + * Author: > + * Muthu Mani <muth@cypress.com> > + * > + * Additional contributors include: > + * Rajaram Regupathy <rera@cypress.com> > + * > + * This program is free software; you can redistribute it and/or modify it > + * under the terms of the GNU General Public License version 2 as published by > + * the Free Software Foundation. > + */ > + > +#ifndef __MFD_CYUSBS23X_H__ > +#define __MFD_CYUSBS23X_H__ > + > +#include <linux/types.h> > +#include <linux/usb.h> > + > +/* Structure to hold all device specific stuff */ > +struct cyusbs23x { > + struct usb_device *usb_dev; > + struct usb_interface *usb_intf; > + > + u8 intf_num; > + u8 bulk_in_ep_num; > + u8 bulk_out_ep_num; > + u8 intr_in_ep_num; > +}; > + > +enum cy_usbs_vendor_cmds { > + CY_I2C_GET_CONFIG_CMD = 0xC4, > + CY_I2C_SET_CONFIG_CMD = 0xC5, > + CY_I2C_WRITE_CMD = 0xC6, > + CY_I2C_READ_CMD = 0xC7, > + CY_I2C_GET_STATUS_CMD = 0xC8, > + CY_I2C_RESET_CMD = 0xC9, > + CY_GPIO_GET_CONFIG_CMD = 0xD8, > + CY_GPIO_SET_CONFIG_CMD = 0xD9, > + CY_GPIO_GET_VALUE_CMD = 0xDA, > + CY_GPIO_SET_VALUE_CMD = 0xDB, > +}; > + > +/* Serial interfaces (I2C, SPI, UART) differ in interface subclass */ > +enum cy_scb_modes { > + CY_USBS_SCB_DISABLED = 0, > + CY_USBS_SCB_UART = 1, > + CY_USBS_SCB_SPI = 2, > + CY_USBS_SCB_I2C = 3 No need to number these. > +}; > + > +/* SCB index shift */ > +#define CY_SCB_INDEX_SHIFT 15 > + > +#define CY_USBS_CTRL_XFER_TIMEOUT 2000 > +#define CY_USBS_BULK_XFER_TIMEOUT 5000 > +#define CY_USBS_INTR_XFER_TIMEOUT 5000 > + > +#endif /* __MFD_CYUSBS23X_H__ */
On Thu, Oct 09, 2014 at 08:40:29AM +0100, Lee Jones wrote: > On Mon, 06 Oct 2014, Muthu Mani wrote: > > +static int update_ep_details(struct usb_interface *interface, > > + struct cyusbs23x *cyusbs) > > +{ > > + struct usb_host_interface *iface_desc; > > + struct usb_endpoint_descriptor *ep; > > + int i; > > + > > + iface_desc = interface->cur_altsetting; > > + > > + for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) { > > + > > + ep = &iface_desc->endpoint[i].desc; > > + > > + if (!cyusbs->bulk_in_ep_num && usb_endpoint_is_bulk_in(ep)) > > + cyusbs->bulk_in_ep_num = ep->bEndpointAddress; > > + if (!cyusbs->bulk_out_ep_num && usb_endpoint_is_bulk_out(ep)) > > + cyusbs->bulk_out_ep_num = ep->bEndpointAddress; > > + if (!cyusbs->intr_in_ep_num && usb_endpoint_is_int_in(ep)) > > + cyusbs->intr_in_ep_num = ep->bEndpointAddress; > > + } > > All of the USB specific code in this driver will require a USB Ack. I'll review it once the incomplete gpio-driver issue has been resolved. > > + dev_dbg(&interface->dev, "%s intr_in=%d, bulk_in=%d, bulk_out=%d\n", > > + __func__, cyusbs->intr_in_ep_num , > > + cyusbs->bulk_in_ep_num, cyusbs->bulk_out_ep_num); > > + > > + if (!cyusbs->bulk_in_ep_num || !cyusbs->bulk_out_ep_num || > > + !cyusbs->intr_in_ep_num) > > + return -ENODEV; > > + > > + return 0; > > +} [...] > > diff --git a/include/linux/mfd/cyusbs23x.h b/include/linux/mfd/cyusbs23x.h > > +/* Serial interfaces (I2C, SPI, UART) differ in interface subclass */ > > +enum cy_scb_modes { > > + CY_USBS_SCB_DISABLED = 0, > > + CY_USBS_SCB_UART = 1, > > + CY_USBS_SCB_SPI = 2, > > + CY_USBS_SCB_I2C = 3 > > No need to number these. As it's not an arbitrary enumeration, I think they should be initialised explicitly. They could be defined in the mfd driver though, as they only appear to be needed during probe. Johan -- To unsubscribe from this list: send the line "unsubscribe linux-gpio" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On Thu, 09 Oct 2014, Johan Hovold wrote: > On Thu, Oct 09, 2014 at 08:40:29AM +0100, Lee Jones wrote: > > On Mon, 06 Oct 2014, Muthu Mani wrote: > > > > +static int update_ep_details(struct usb_interface *interface, > > > + struct cyusbs23x *cyusbs) > > > +{ > > > + struct usb_host_interface *iface_desc; > > > + struct usb_endpoint_descriptor *ep; > > > + int i; > > > + > > > + iface_desc = interface->cur_altsetting; > > > + > > > + for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) { > > > + > > > + ep = &iface_desc->endpoint[i].desc; > > > + > > > + if (!cyusbs->bulk_in_ep_num && usb_endpoint_is_bulk_in(ep)) > > > + cyusbs->bulk_in_ep_num = ep->bEndpointAddress; > > > + if (!cyusbs->bulk_out_ep_num && usb_endpoint_is_bulk_out(ep)) > > > + cyusbs->bulk_out_ep_num = ep->bEndpointAddress; > > > + if (!cyusbs->intr_in_ep_num && usb_endpoint_is_int_in(ep)) > > > + cyusbs->intr_in_ep_num = ep->bEndpointAddress; > > > + } > > > > All of the USB specific code in this driver will require a USB Ack. > > I'll review it once the incomplete gpio-driver issue has been resolved. Okay, great. > > > + dev_dbg(&interface->dev, "%s intr_in=%d, bulk_in=%d, bulk_out=%d\n", > > > + __func__, cyusbs->intr_in_ep_num , > > > + cyusbs->bulk_in_ep_num, cyusbs->bulk_out_ep_num); > > > + > > > + if (!cyusbs->bulk_in_ep_num || !cyusbs->bulk_out_ep_num || > > > + !cyusbs->intr_in_ep_num) > > > + return -ENODEV; > > > + > > > + return 0; > > > +} > > [...] > > > > diff --git a/include/linux/mfd/cyusbs23x.h b/include/linux/mfd/cyusbs23x.h > > > > +/* Serial interfaces (I2C, SPI, UART) differ in interface subclass */ > > > +enum cy_scb_modes { > > > + CY_USBS_SCB_DISABLED = 0, > > > + CY_USBS_SCB_UART = 1, > > > + CY_USBS_SCB_SPI = 2, > > > + CY_USBS_SCB_I2C = 3 > > > > No need to number these. > > As it's not an arbitrary enumeration, I think they should be initialised > explicitly. No need. You are protected by the C Standard: 6.7.2.2 Enumeration specifiers "If the first enumerator has no =, the value of its enumeration constant is 0. Each subsequent enumerator with no = defines its enumeration constant as the value of the constant expression obtained by adding 1 to the value of the previous enumeration constant." There's nothing arbitrary about that. > They could be defined in the mfd driver though, as they only > appear to be needed during probe.
On Thu, Oct 09, 2014 at 11:59:50AM +0100, Lee Jones wrote: > On Thu, 09 Oct 2014, Johan Hovold wrote: > > On Thu, Oct 09, 2014 at 08:40:29AM +0100, Lee Jones wrote: > > > On Mon, 06 Oct 2014, Muthu Mani wrote: > > > > diff --git a/include/linux/mfd/cyusbs23x.h b/include/linux/mfd/cyusbs23x.h > > > > > > +/* Serial interfaces (I2C, SPI, UART) differ in interface subclass */ > > > > +enum cy_scb_modes { > > > > + CY_USBS_SCB_DISABLED = 0, > > > > + CY_USBS_SCB_UART = 1, > > > > + CY_USBS_SCB_SPI = 2, > > > > + CY_USBS_SCB_I2C = 3 > > > > > > No need to number these. > > > > As it's not an arbitrary enumeration, I think they should be initialised > > explicitly. > > No need. You are protected by the C Standard: > > 6.7.2.2 Enumeration specifiers > > "If the first enumerator has no =, the value of its enumeration > constant is 0. Each subsequent enumerator with no = defines its > enumeration constant as the value of the constant expression obtained > by adding 1 to the value of the previous enumeration constant." > > There's nothing arbitrary about that. I obviously wasn't suggesting that the definition of an enum (and the values of its constants) in c was arbitrary. My point was that the values of the USB interface subclasses (defined through the enum) are not arbitrary. In this case they just happen to be zero-based and consecutive. You cannot reorder, or remove an unused item, without breaking the driver. By initialising each constant explicitly this would become apparent. Using preprocessor defines could be an alternative if you really do not like initialised enumeration constants. > > They could be defined in the mfd driver though, as they only > > appear to be needed during probe. Johan -- To unsubscribe from this list: send the line "unsubscribe linux-gpio" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
PiAtLS0tLU9yaWdpbmFsIE1lc3NhZ2UtLS0tLQ0KPiBGcm9tOiBMZWUgSm9uZXMgW21haWx0bzps ZWUuam9uZXNAbGluYXJvLm9yZ10NCj4gU2VudDogVGh1cnNkYXksIE9jdG9iZXIgMDksIDIwMTQg MToxMCBQTQ0KPiBUbzogTXV0aHUgTWFuaQ0KPiBDYzogU2FtdWVsIE9ydGl6OyBXb2xmcmFtIFNh bmc7IExpbnVzIFdhbGxlaWo7IEFsZXhhbmRyZSBDb3VyYm90Ow0KPiBncmVna2hAbGludXhmb3Vu ZGF0aW9uLm9yZzsgbGludXgtaTJjQHZnZXIua2VybmVsLm9yZzsgbGludXgtDQo+IGdwaW9Admdl ci5rZXJuZWwub3JnOyBsaW51eC11c2JAdmdlci5rZXJuZWwub3JnOyBsaW51eC0NCj4ga2VybmVs QHZnZXIua2VybmVsLm9yZzsgUmFqYXJhbSBSZWd1cGF0aHk7IEpvaGFuIEhvdm9sZA0KPiBTdWJq ZWN0OiBSZTogW1BBVENIIHYzIDEvM10gbWZkOiBhZGQgc3VwcG9ydCBmb3IgQ3lwcmVzcyBDWVVT QlMyMzQgVVNCDQo+IFNlcmlhbCBCcmlkZ2UgY29udHJvbGxlcg0KPiANCj4gT24gTW9uLCAwNiBP Y3QgMjAxNCwgTXV0aHUgTWFuaSB3cm90ZToNCj4gDQo+ID4gQWRkcyBzdXBwb3J0IGZvciBVU0It STJDL0dQSU8gaW50ZXJmYWNlcyBvZiBDeXByZXNzIFNlbWljb25kdWN0b3INCj4gPiBDWVVTQlMy MzQgVVNCLVNlcmlhbCBCcmlkZ2UgY29udHJvbGxlci4NCj4gPg0KPiA+IERldGFpbHMgYWJvdXQg dGhlIGRldmljZSBjYW4gYmUgZm91bmQgYXQ6DQo+ID4gaHR0cDovL3d3dy5jeXByZXNzLmNvbS8/ cklEPTg0MTI2DQo+ID4NCj4gPiBTaWduZWQtb2ZmLWJ5OiBNdXRodSBNYW5pIDxtdXRoQGN5cHJl c3MuY29tPg0KPiA+IFNpZ25lZC1vZmYtYnk6IFJhamFyYW0gUmVndXBhdGh5IDxyZXJhQGN5cHJl c3MuY29tPg0KPiA+IC0tLQ0KPiA+IENoYW5nZXMgc2luY2UgdjI6DQo+ID4gKiBVc2VkIGF1dG8g bWZkIGlkIHRvIHN1cHBvcnQgbXVsdGlwbGUgZGV2aWNlcw0KPiA+ICogQ2xlYW5lZCB1cCB0aGUg Y29kZQ0KPiA+DQo+ID4gQ2hhbmdlcyBzaW5jZSB2MToNCj4gPiAqIElkZW50aWZpZWQgZGlmZmVy ZW50IHNlcmlhbCBpbnRlcmZhY2UgYW5kIGxvYWRlZCBjb3JyZWN0IGNlbGwgZHJpdmVyDQo+ID4g KiBGb3JtZWQgYSBtZmQgaWQgdG8gc3VwcG9ydCBtdWx0aXBsZSBkZXZpY2VzDQo+ID4gKiBSZW1v dmVkIHVudXNlZCBwbGF0Zm9ybSBkZXZpY2UNCj4gPg0KPiA+ICBkcml2ZXJzL21mZC9LY29uZmln ICAgICAgICAgICB8ICAxMiArKysNCj4gPiAgZHJpdmVycy9tZmQvTWFrZWZpbGUgICAgICAgICAg fCAgIDEgKw0KPiA+ICBkcml2ZXJzL21mZC9jeXVzYnMyM3guYyAgICAgICB8IDE2Nw0KPiArKysr KysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysNCj4gPiAgaW5jbHVkZS9saW51 eC9tZmQvY3l1c2JzMjN4LmggfCAgNjIgKysrKysrKysrKysrKysrKw0KPiA+ICA0IGZpbGVzIGNo YW5nZWQsIDI0MiBpbnNlcnRpb25zKCspDQo+ID4gIGNyZWF0ZSBtb2RlIDEwMDY0NCBkcml2ZXJz L21mZC9jeXVzYnMyM3guYw0KPiA+ICBjcmVhdGUgbW9kZSAxMDA2NDQgaW5jbHVkZS9saW51eC9t ZmQvY3l1c2JzMjN4LmgNCj4gPg0KPiA+IGRpZmYgLS1naXQgYS9kcml2ZXJzL21mZC9LY29uZmln IGIvZHJpdmVycy9tZmQvS2NvbmZpZw0KPiA+IGluZGV4IGRlNWFiZjIuLmEzMWU5ZTMgMTAwNjQ0 DQo+ID4gLS0tIGEvZHJpdmVycy9tZmQvS2NvbmZpZw0KPiA+ICsrKyBiL2RyaXZlcnMvbWZkL0tj b25maWcNCj4gPiBAQCAtMTE2LDYgKzExNiwxOCBAQCBjb25maWcgTUZEX0FTSUMzDQo+ID4gICAg ICAgICBUaGlzIGRyaXZlciBzdXBwb3J0cyB0aGUgQVNJQzMgbXVsdGlmdW5jdGlvbiBjaGlwIGZv dW5kIG9uIG1hbnkNCj4gPiAgICAgICAgIFBEQXMgKG1haW5seSBpUEFRIGFuZCBIVEMgYmFzZWQg b25lcykNCj4gPg0KPiA+ICtjb25maWcgTUZEX0NZVVNCUzIzWA0KPiA+ICsgICAgICAgIHRyaXN0 YXRlICJDeXByZXNzIENZVVNCUzIzeCBVU0IgU2VyaWFsIEJyaWRnZSBjb250cm9sbGVyIg0KPiAN Cj4gV2hpdGUgc3BhY2UgaXNzdWUgaGVyZS4NCg0KVGhhbmtzIGZvciByZXZpZXdpbmchDQpTdXJl LCB3aWxsIGZpeCBvdGhlciBmaWxlcyBhcyB3ZWxsLg0KDQo+IA0KPiA+ICsgICAgIHNlbGVjdCBN RkRfQ09SRQ0KPiA+ICsgICAgIGRlcGVuZHMgb24gVVNCDQo+ID4gKyAgICAgZGVmYXVsdCBuDQo+ ID4gKyAgICAgaGVscA0KPiA+ICsgICAgICAgU2F5IHllcyBoZXJlIGlmIHlvdSB3YW50IHN1cHBv cnQgZm9yIEN5cHJlc3MgU2VtaWNvbmR1Y3Rvcg0KPiA+ICsgICAgICAgQ1lVU0JTMjN4IFVTQi1T ZXJpYWwgQnJpZGdlIGNvbnRyb2xsZXIuDQo+ID4gKw0KPiA+ICsgICAgICAgVGhpcyBkcml2ZXIg Y2FuIGFsc28gYmUgYnVpbHQgYXMgYSBtb2R1bGUuIElmIHNvLCB0aGUgbW9kdWxlIHdpbGwgYmUN Cj4gPiArICAgICAgIGNhbGxlZCBjeXVzYnMyM3guDQo+ID4gKw0KPiA+ICBjb25maWcgUE1JQ19E QTkwM1gNCj4gPiAgICAgICBib29sICJEaWFsb2cgU2VtaWNvbmR1Y3RvciBEQTkwMzAvREE5MDM0 IFBNSUMgU3VwcG9ydCINCj4gPiAgICAgICBkZXBlbmRzIG9uIEkyQz15DQo+ID4gZGlmZiAtLWdp dCBhL2RyaXZlcnMvbWZkL01ha2VmaWxlIGIvZHJpdmVycy9tZmQvTWFrZWZpbGUNCj4gPiBpbmRl eCBmMDAxNDg3Li5mYzViY2QxIDEwMDY0NA0KPiA+IC0tLSBhL2RyaXZlcnMvbWZkL01ha2VmaWxl DQo+ID4gKysrIGIvZHJpdmVycy9tZmQvTWFrZWZpbGUNCj4gPiBAQCAtMTUxLDYgKzE1MSw3IEBA IHNpNDc2eC1jb3JlLXkgOj0gc2k0NzZ4LWNtZC5vIHNpNDc2eC1wcm9wLm8gc2k0NzZ4LQ0KPiBp MmMubw0KPiA+ICBvYmotJChDT05GSUdfTUZEX1NJNDc2WF9DT1JFKSAgICAgICAgKz0gc2k0NzZ4 LWNvcmUubw0KPiA+DQo+ID4gIG9iai0kKENPTkZJR19NRkRfQ1M1NTM1KSAgICAgKz0gY3M1NTM1 LW1mZC5vDQo+ID4gK29iai0kKENPTkZJR19NRkRfQ1lVU0JTMjNYKSAgICAgKz0gY3l1c2JzMjN4 Lm8NCj4gPiAgb2JqLSQoQ09ORklHX01GRF9PTUFQX1VTQl9IT1NUKSAgICAgICs9IG9tYXAtdXNi LWhvc3QubyBvbWFwLQ0KPiB1c2ItdGxsLm8NCj4gPiAgb2JqLSQoQ09ORklHX01GRF9QTTg5MjFf Q09SRSkgICAgICAgICs9IHBtODkyMS1jb3JlLm8gc3NiaS5vDQo+ID4gIG9iai0kKENPTkZJR19U UFM2NTkxMV9DT01QQVJBVE9SKSAgICArPSB0cHM2NTkxMS1jb21wYXJhdG9yLm8NCj4gPiBkaWZm IC0tZ2l0IGEvZHJpdmVycy9tZmQvY3l1c2JzMjN4LmMgYi9kcml2ZXJzL21mZC9jeXVzYnMyM3gu Yw0KPiA+IG5ldyBmaWxlIG1vZGUgMTAwNjQ0DQo+ID4gaW5kZXggMDAwMDAwMC4uYzcwZWE0MA0K PiA+IC0tLSAvZGV2L251bGwNCj4gPiArKysgYi9kcml2ZXJzL21mZC9jeXVzYnMyM3guYw0KPiA+ IEBAIC0wLDAgKzEsMTY3IEBADQo+ID4gKy8qDQo+ID4gKyAqIEN5cHJlc3MgVVNCLVNlcmlhbCBC cmlkZ2UgQ29udHJvbGxlciBVU0IgYWRhcHRlciBkcml2ZXINCj4gPiArICoNCj4gPiArICogQ29w eXJpZ2h0IChjKSAyMDE0IEN5cHJlc3MgU2VtaWNvbmR1Y3RvciBDb3Jwb3JhdGlvbi4NCj4gPiAr ICoNCj4gPiArICogQXV0aG9yOg0KPiA+ICsgKiAgIE11dGh1IE1hbmkgPG11dGhAY3lwcmVzcy5j b20+DQo+ID4gKyAqDQo+ID4gKyAqIEFkZGl0aW9uYWwgY29udHJpYnV0b3JzIGluY2x1ZGU6DQo+ ID4gKyAqICAgUmFqYXJhbSBSZWd1cGF0aHkgPHJlcmFAY3lwcmVzcy5jb20+DQo+ID4gKyAqDQo+ ID4gKyAqIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0 ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0DQo+ID4gKyAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05V IEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIGFzDQo+IHB1Ymxpc2hlZCBieQ0KPiA+ ICsgKiB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLg0KPiA+ICsgKi8NCj4gPiArDQo+ID4g Ky8qDQo+ID4gKyAqIFRoaXMgaXMgY29yZSBNRkQgZHJpdmVyIGZvciBDeXByZXNzIFNlbWljb25k dWN0b3IgQ1lVU0JTMjM0IFVTQi0NCj4gU2VyaWFsDQo+ID4gKyAqIEJyaWRnZSBjb250cm9sbGVy LiBDWVVTQlMyMzQgb2ZmZXJzIGEgc2luZ2xlIGNoYW5uZWwgc2VyaWFsIGludGVyZmFjZQ0KPiA+ ICsgKiAoSTJDL1NQSS9VQVJUKS4gSXQgY2FuIGJlIGNvbmZpZ3VyZWQgdG8gZW5hYmxlIGVpdGhl ciBvZiBJMkMsIFNQSSwgVUFSVA0KPiA+ICsgKiBpbnRlcmZhY2VzLiBUaGUgR1BJT3MgYXJlIGFs c28gYXZhaWxhYmxlIHRvIGFjY2Vzcy4NCj4gPiArICogRGV0YWlscyBhYm91dCB0aGUgZGV2aWNl IGNhbiBiZSBmb3VuZCBhdDoNCj4gPiArICogICAgaHR0cDovL3d3dy5jeXByZXNzLmNvbS8/cklE PTg0MTI2DQo+ID4gKyAqDQo+ID4gKyAqIFNlcGFyYXRlIGNlbGwgZHJpdmVycyBhcmUgYXZhaWxh YmxlIGZvciBJMkMgYW5kIEdQSU8uIFNQSSBhbmQgVUFSVCBhcmUNCj4gbm90DQo+ID4gKyAqIHN1 cHBvcnRlZCB5ZXQuIEFsbCBHUElPcyBhcmUgZXhwb3NlZCBmb3IgZ2V0IG9wZXJhdGlvbi4gSG93 ZXZlciwgb25seQ0KPiA+ICsgKiB1bnVzZWQgR1BJT3MgY2FuIGJlIHNldC4NCj4gPiArICovDQo+ ID4gKw0KPiA+ICsjaW5jbHVkZSA8bGludXgva2VybmVsLmg+DQo+ID4gKyNpbmNsdWRlIDxsaW51 eC9lcnJuby5oPg0KPiA+ICsjaW5jbHVkZSA8bGludXgvbW9kdWxlLmg+DQo+ID4gKyNpbmNsdWRl IDxsaW51eC9zbGFiLmg+DQo+ID4gKyNpbmNsdWRlIDxsaW51eC90eXBlcy5oPg0KPiA+ICsjaW5j bHVkZSA8bGludXgvbXV0ZXguaD4NCj4gPiArDQo+IA0KPiBUaGlzICdcbicgaXMgc3VwZXJmbHVv dXMsIHBsZWFzZSByZW1vdmUgaXQuDQo+IA0KPiA+ICsjaW5jbHVkZSA8bGludXgvbWZkL2NvcmUu aD4NCj4gPiArI2luY2x1ZGUgPGxpbnV4L21mZC9jeXVzYnMyM3guaD4NCj4gPiArDQo+ID4gKyNp bmNsdWRlIDxsaW51eC91c2IuaD4NCj4gPiArDQo+ID4gK3N0YXRpYyBjb25zdCBzdHJ1Y3QgdXNi X2RldmljZV9pZCBjeXVzYnMyM3hfdXNiX3RhYmxlW10gPSB7DQo+ID4gKyAgICAgeyBVU0JfREVW SUNFKDB4MDRiNCwgMHgwMDA0KSB9LCAgIC8qIEN5cHJlc3MgU2VtaWNvbmR1Y3RvciAqLw0KPiA+ ICsgICAgIHsgfSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBUZXJtaW5hdGluZyBl bnRyeSAqLw0KPiANCj4gVGhpcyBjb21tZW50IGlzIG5vdCByZXF1aXJlZCwgcGxlYXNlIHJlbW92 ZSBpdC4NCj4gDQo+ID4gK307DQo+ID4gKw0KPiA+ICtNT0RVTEVfREVWSUNFX1RBQkxFKHVzYiwg Y3l1c2JzMjN4X3VzYl90YWJsZSk7DQo+ID4gKw0KPiA+ICtzdGF0aWMgY29uc3Qgc3RydWN0IG1m ZF9jZWxsIGN5dXNiczIzeF9pMmNfZGV2c1tdID0gew0KPiA+ICsgICAgIHsNCj4gPiArICAgICAg ICAgICAgIC5uYW1lID0gImN5dXNiczIzeC1pMmMiLA0KPiA+ICsgICAgIH0sDQo+ID4gKyAgICAg ew0KPiA+ICsgICAgICAgICAgICAgLm5hbWUgPSAiY3l1c2JzMjN4LWdwaW8iLA0KPiA+ICsgICAg IH0sDQo+ID4gK307DQo+ID4gKw0KPiA+ICtzdGF0aWMgaW50IHVwZGF0ZV9lcF9kZXRhaWxzKHN0 cnVjdCB1c2JfaW50ZXJmYWNlICppbnRlcmZhY2UsDQo+ID4gKyAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgc3RydWN0IGN5dXNiczIzeCAqY3l1c2JzKQ0KPiA+ICt7DQo+ID4gKyAgICAgc3Ry dWN0IHVzYl9ob3N0X2ludGVyZmFjZSAqaWZhY2VfZGVzYzsNCj4gPiArICAgICBzdHJ1Y3QgdXNi X2VuZHBvaW50X2Rlc2NyaXB0b3IgKmVwOw0KPiA+ICsgICAgIGludCBpOw0KPiA+ICsNCj4gPiAr ICAgICBpZmFjZV9kZXNjID0gaW50ZXJmYWNlLT5jdXJfYWx0c2V0dGluZzsNCj4gPiArDQo+ID4g KyAgICAgZm9yIChpID0gMDsgaSA8IGlmYWNlX2Rlc2MtPmRlc2MuYk51bUVuZHBvaW50czsgKytp KSB7DQo+ID4gKw0KPiA+ICsgICAgICAgICAgICAgZXAgPSAmaWZhY2VfZGVzYy0+ZW5kcG9pbnRb aV0uZGVzYzsNCj4gPiArDQo+ID4gKyAgICAgICAgICAgICBpZiAoIWN5dXNicy0+YnVsa19pbl9l cF9udW0gJiYgdXNiX2VuZHBvaW50X2lzX2J1bGtfaW4oZXApKQ0KPiA+ICsgICAgICAgICAgICAg ICAgICAgICBjeXVzYnMtPmJ1bGtfaW5fZXBfbnVtID0gZXAtPmJFbmRwb2ludEFkZHJlc3M7DQo+ ID4gKyAgICAgICAgICAgICBpZiAoIWN5dXNicy0+YnVsa19vdXRfZXBfbnVtICYmDQo+IHVzYl9l bmRwb2ludF9pc19idWxrX291dChlcCkpDQo+ID4gKyAgICAgICAgICAgICAgICAgICAgIGN5dXNi cy0+YnVsa19vdXRfZXBfbnVtID0gZXAtPmJFbmRwb2ludEFkZHJlc3M7DQo+ID4gKyAgICAgICAg ICAgICBpZiAoIWN5dXNicy0+aW50cl9pbl9lcF9udW0gJiYgdXNiX2VuZHBvaW50X2lzX2ludF9p bihlcCkpDQo+ID4gKyAgICAgICAgICAgICAgICAgICAgIGN5dXNicy0+aW50cl9pbl9lcF9udW0g PSBlcC0+YkVuZHBvaW50QWRkcmVzczsNCj4gPiArICAgICB9DQo+IA0KPiBBbGwgb2YgdGhlIFVT QiBzcGVjaWZpYyBjb2RlIGluIHRoaXMgZHJpdmVyIHdpbGwgcmVxdWlyZSBhIFVTQiBBY2suDQo+ IA0KPiA+ICsgICAgIGRldl9kYmcoJmludGVyZmFjZS0+ZGV2LCAiJXMgaW50cl9pbj0lZCwgYnVs a19pbj0lZCwNCj4gYnVsa19vdXQ9JWRcbiIsDQo+ID4gKyAgICAgICAgICAgICBfX2Z1bmNfXywg Y3l1c2JzLT5pbnRyX2luX2VwX251bSAsDQo+ID4gKyAgICAgICAgICAgICBjeXVzYnMtPmJ1bGtf aW5fZXBfbnVtLCBjeXVzYnMtPmJ1bGtfb3V0X2VwX251bSk7DQo+ID4gKw0KPiA+ICsgICAgIGlm ICghY3l1c2JzLT5idWxrX2luX2VwX251bSB8fCAhY3l1c2JzLT5idWxrX291dF9lcF9udW0gfHwN Cj4gPiArICAgICAgICAgICAgICFjeXVzYnMtPmludHJfaW5fZXBfbnVtKQ0KPiA+ICsgICAgICAg ICAgICAgcmV0dXJuIC1FTk9ERVY7DQo+ID4gKw0KPiA+ICsgICAgIHJldHVybiAwOw0KPiA+ICt9 DQo+ID4gKw0KPiA+ICtzdGF0aWMgaW50IGN5dXNiczIzeF9wcm9iZShzdHJ1Y3QgdXNiX2ludGVy ZmFjZSAqaW50ZXJmYWNlLA0KPiA+ICsgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBzdHJ1 Y3QgdXNiX2RldmljZV9pZCAqaWQpDQo+ID4gK3sNCj4gPiArICAgICBzdHJ1Y3QgY3l1c2JzMjN4 ICpjeXVzYnM7DQo+ID4gKyAgICAgY29uc3Qgc3RydWN0IG1mZF9jZWxsICpjeXVzYnMyM3hfZGV2 czsNCj4gPiArICAgICBpbnQgcmV0LCBuZGV2cyA9IDA7DQo+ID4gKyAgICAgdTggc3ViX2NsYXNz Ow0KPiA+ICsNCj4gPiArICAgICBjeXVzYnMgPSBremFsbG9jKHNpemVvZigqY3l1c2JzKSwgR0ZQ X0tFUk5FTCk7DQo+IA0KPiBBbnkgcmVhc29uIGZvciBub3QgdXNpbmcgbWFuYWdlZCByZXNvdXJj ZXMgKGRldm1fKik/DQoNCk9rLCB3aWxsIHVzZSBtYW5hZ2VkIHJlc291cmNlcy4NCg0KPiANCj4g PiArICAgICBpZiAoY3l1c2JzID09IE5VTEwpDQo+IA0KPiBpZiAoIWN5dXNicykNCj4gDQo+ID4g KyAgICAgICAgICAgICByZXR1cm4gLUVOT01FTTsNCj4gPiArDQo+ID4gKyAgICAgY3l1c2JzLT51 c2JfZGV2ID0gdXNiX2dldF9kZXYoaW50ZXJmYWNlX3RvX3VzYmRldihpbnRlcmZhY2UpKTsNCj4g DQo+IENhbiB5b3UgZG8gdGhpcyBsYXN0PyAgVGhlbiB5b3UgY2FuIHJlbW92ZSB0aGUgJ2Vycm9y JyBlcnJvciBwYXRoLg0KDQptZmRfYWRkX2RldmljZXMgd291bGQgdXRsaW1hdGVseSBpbnZva2Ug dGhlIGNlbGwgZHJpdmVycycgcHJvYmUgYmVmb3JlIHJldHVybmluZyBhbmQgY2VsbCBkcml2ZXJz IHVzZSB1c2JfZGV2IGluIHRoZWlyIHByb2JlLg0KU28sIGxlYXZpbmcgaXQgYXMgc3VjaC4NCg0K PiANCj4gPiArICAgICBjeXVzYnMtPnVzYl9pbnRmID0gaW50ZXJmYWNlOw0KPiA+ICsgICAgIGN5 dXNicy0+aW50Zl9udW0gPSBpbnRlcmZhY2UtPmN1cl9hbHRzZXR0aW5nLQ0KPiA+ZGVzYy5iSW50 ZXJmYWNlTnVtYmVyOw0KPiANCj4gSWYgeW91J3JlIGFscmVhZHkgc2F2aW5nICdpbnRlcmZhY2Un IHRoZXJlIGlzIG5vIG5lZWQgdG8gc2F2ZSB0aGlzDQo+IGFsc28sIGp1c3QgZXh0cmFjdCBpdCBm cm9tICdjeXVzYnMtPnVzYl9pbnRmJyB3aGVuIHlvdSBuZWVkIGl0Lg0KPiANCj4gPiArICAgICBy ZXQgPSB1cGRhdGVfZXBfZGV0YWlscyhpbnRlcmZhY2UsIGN5dXNicyk7DQo+ID4gKyAgICAgaWYg KHJldCA8IDApIHsNCj4gDQo+IENhbiByZXQgYmUgPiAwPyAgSWYgbm90LCBqdXN0IGRvICdpZiAo cmV0KScNCj4gDQo+ID4gKyAgICAgICAgICAgICBkZXZfZXJyKCZpbnRlcmZhY2UtPmRldiwgImlu dmFsaWQgaW50ZXJmYWNlXG4iKTsNCj4gDQo+IElmIHlvdSBwdXQgdGhlIGVycm9yIG1lc3NhZ2Ug aW4gdXBkYXRlX2VwX2RldGFpbHMoKSBjYW4geW91IHByaW50IG91dA0KPiBhIG1vcmUgc3BlY2lm aWMgZXJyb3IgbWVzc2FnZSBhbmQgcmVtb3ZlIHRoaXMgbGluZS4NCj4gDQo+ID4gKyAgICAgICAg ICAgICBnb3RvIGVycm9yOw0KPiA+ICsgICAgIH0NCj4gPiArDQo+ID4gKyAgICAgdXNiX3NldF9p bnRmZGF0YShpbnRlcmZhY2UsIGN5dXNicyk7DQo+ID4gKw0KPiA+ICsgICAgIC8qIFNlcmlhbCBp bnRlcmZhY2VzIChJMkMsIFNQSSwgVUFSVCkgZGlmZmVyIGluIGludGVyZmFjZSBzdWJjbGFzcyAq Lw0KPiA+ICsgICAgIHN1Yl9jbGFzcyA9IGludGVyZmFjZS0+Y3VyX2FsdHNldHRpbmctPmRlc2Mu YkludGVyZmFjZVN1YkNsYXNzOw0KPiA+ICsgICAgIHN3aXRjaCAoc3ViX2NsYXNzKSB7DQo+IA0K PiBUaGlzIGlzIGEgd2FzdGUgb2YgYSB2YXJpYWJsZSBhbmQgYWRkcyBub3RoaW5nIHRvIHRoZSBj b2RlLiAgSnVzdA0KPiBzd2l0Y2goKSBmb3IgJ2ludGVyZmFjZS0+Y3VyX2FsdHNldHRpbmctPmRl c2MuYkludGVyZmFjZVN1YkNsYXNzJy4NCj4gDQo+ID4gKyAgICAgY2FzZSBDWV9VU0JTX1NDQl9J MkM6DQo+ID4gKyAgICAgICAgICAgICBkZXZfaW5mbygmaW50ZXJmYWNlLT5kZXYsICJJMkMgaW50 ZXJmYWNlIGZvdW5kXG4iKTsNCj4gDQo+IFdhcyBpdCBldmVuIGxvc3Q/DQo+IA0KPiBXb3VsZCAi dXNpbmcgSTJDIGludGVyZmFjZSIgYmUgYmV0dGVyPw0KPiANCj4gPiArICAgICAgICAgICAgIGN5 dXNiczIzeF9kZXZzID0gY3l1c2JzMjN4X2kyY19kZXZzOw0KPiA+ICsgICAgICAgICAgICAgbmRl dnMgPSBBUlJBWV9TSVpFKGN5dXNiczIzeF9pMmNfZGV2cyk7DQo+ID4gKyAgICAgICAgICAgICBi cmVhazsNCj4gDQo+IEkgYXNzdW1lIHRoZXJlIHdpbGwgYmUgb3RoZXIgaW50ZXJmYWNlcyBzdXBw b3J0ZWQgYXQgYSBsYXRlciBkYXRlPyAgSWYNCj4gbm90LCB0aGlzIHN3aXRjaCgpIGlzIHByZXR0 eSBvdmVyLXRoZS10b3AuDQo+IA0KPiA+ICsgICAgIGRlZmF1bHQ6DQo+ID4gKyAgICAgICAgICAg ICBkZXZfZXJyKCZpbnRlcmZhY2UtPmRldiwgInVuc3VwcG9ydGVkIHN1YmNsYXNzXG4iKTsNCj4g PiArICAgICAgICAgICAgIHJldCA9IC1FTk9ERVY7DQo+ID4gKyAgICAgICAgICAgICBnb3RvIGVy cm9yOw0KPiA+ICsgICAgIH0NCj4gPiArDQo+ID4gKyAgICAgcmV0ID0gbWZkX2FkZF9kZXZpY2Vz KCZpbnRlcmZhY2UtPmRldiwgUExBVEZPUk1fREVWSURfQVVUTywNCj4gPiArICAgICAgICAgICAg ICAgICAgICAgICAgICAgICBjeXVzYnMyM3hfZGV2cywgbmRldnMsIE5VTEwsIDAsIE5VTEwpOw0K PiA+ICsgICAgIGlmIChyZXQgIT0gMCkgew0KPiANCj4gaWYgKHJldCkNCj4gDQo+ID4gKyAgICAg ICAgICAgICBkZXZfZXJyKCZpbnRlcmZhY2UtPmRldiwgIkZhaWxlZCB0byBhZGQgbWZkIGRldmlj ZXMgdG8gY29yZVxuIik7DQo+IA0KPiAiRmFpbGVkIHRvIHJlZ2lzdGVyIGRldmljZXMiDQo+IA0K PiA+ICsgICAgICAgICAgICAgZ290byBlcnJvcjsNCj4gPiArICAgICB9DQo+ID4gKw0KPiA+ICsg ICAgIHJldHVybiAwOw0KPiA+ICsNCj4gPiArZXJyb3I6DQo+ID4gKyAgICAgdXNiX3B1dF9kZXYo Y3l1c2JzLT51c2JfZGV2KTsNCj4gPiArICAgICBrZnJlZShjeXVzYnMpOw0KPiA+ICsNCj4gPiAr ICAgICByZXR1cm4gcmV0Ow0KPiA+ICt9DQo+ID4gKw0KPiA+ICtzdGF0aWMgdm9pZCBjeXVzYnMy M3hfZGlzY29ubmVjdChzdHJ1Y3QgdXNiX2ludGVyZmFjZSAqaW50ZXJmYWNlKQ0KPiA+ICt7DQo+ ID4gKyAgICAgc3RydWN0IGN5dXNiczIzeCAqY3l1c2JzID0gdXNiX2dldF9pbnRmZGF0YShpbnRl cmZhY2UpOw0KPiA+ICsNCj4gPiArICAgICBtZmRfcmVtb3ZlX2RldmljZXMoJmludGVyZmFjZS0+ ZGV2KTsNCj4gPiArICAgICB1c2JfcHV0X2RldihjeXVzYnMtPnVzYl9kZXYpOw0KPiA+ICsgICAg IGtmcmVlKGN5dXNicyk7DQo+IA0KPiBJZiB5b3UgdXNlIG1hbmFnZWQgcmVzb3VyY2VzLCB5b3Ug Y2FuIHJlbW92ZSB0aGlzIGxpbmUuDQo+IA0KPiA+ICsgICAgIGRldl9kYmcoJmludGVyZmFjZS0+ ZGV2LCAiZGlzY29ubmVjdGVkXG4iKTsNCj4gDQo+IFBsZWFzZSByZW1vdmUgdGhpcyBsaW5lLg0K PiANCj4gPiArfQ0KPiA+ICsNCj4gPiArc3RhdGljIHN0cnVjdCB1c2JfZHJpdmVyIGN5dXNiczIz eF91c2JfZHJpdmVyID0gew0KPiA+ICsgICAgIC5uYW1lICAgICAgICAgICA9ICJjeXVzYnMyM3gi LA0KPiA+ICsgICAgIC5wcm9iZSAgICAgICAgICA9IGN5dXNiczIzeF9wcm9iZSwNCj4gPiArICAg ICAuZGlzY29ubmVjdCAgICAgPSBjeXVzYnMyM3hfZGlzY29ubmVjdCwNCj4gPiArICAgICAuaWRf dGFibGUgICAgICAgPSBjeXVzYnMyM3hfdXNiX3RhYmxlLA0KPiA+ICt9Ow0KPiA+ICsNCj4gPiAr bW9kdWxlX3VzYl9kcml2ZXIoY3l1c2JzMjN4X3VzYl9kcml2ZXIpOw0KPiA+ICsNCj4gPiArTU9E VUxFX0FVVEhPUigiUmFqYXJhbSBSZWd1cGF0aHkgPHJlcmFAY3lwcmVzcy5jb20+Iik7DQo+ID4g K01PRFVMRV9BVVRIT1IoIk11dGh1IE1hbmkgPG11dGhAY3lwcmVzcy5jb20+Iik7DQo+ID4gK01P RFVMRV9ERVNDUklQVElPTigiQ3lwcmVzcyBDWVVTQlMyM3ggbWZkIGNvcmUgZHJpdmVyIik7DQo+ IA0KPiBzL21mZC9NRkQvDQoNCklzIHRoZXJlIGEgdHlwbz8NCg0KPiANCj4gPiArTU9EVUxFX0xJ Q0VOU0UoIkdQTCB2MiIpOw0KPiA+IGRpZmYgLS1naXQgYS9pbmNsdWRlL2xpbnV4L21mZC9jeXVz YnMyM3guaA0KPiBiL2luY2x1ZGUvbGludXgvbWZkL2N5dXNiczIzeC5oDQo+ID4gbmV3IGZpbGUg bW9kZSAxMDA2NDQNCj4gPiBpbmRleCAwMDAwMDAwLi4xNTgwZDk4DQo+ID4gLS0tIC9kZXYvbnVs bA0KPiA+ICsrKyBiL2luY2x1ZGUvbGludXgvbWZkL2N5dXNiczIzeC5oDQo+ID4gQEAgLTAsMCAr MSw2MiBAQA0KPiA+ICsvKg0KPiA+ICsgKiBDeXByZXNzIFVTQi1TZXJpYWwgQnJpZGdlIENvbnRy b2xsZXIgZGVmaW5pdGlvbnMNCj4gPiArICoNCj4gPiArICogQ29weXJpZ2h0IChjKSAyMDE0IEN5 cHJlc3MgU2VtaWNvbmR1Y3RvciBDb3Jwb3JhdGlvbi4NCj4gPiArICoNCj4gPiArICogQXV0aG9y Og0KPiA+ICsgKiAgIE11dGh1IE1hbmkgPG11dGhAY3lwcmVzcy5jb20+DQo+ID4gKyAqDQo+ID4g KyAqIEFkZGl0aW9uYWwgY29udHJpYnV0b3JzIGluY2x1ZGU6DQo+ID4gKyAqICAgUmFqYXJhbSBS ZWd1cGF0aHkgPHJlcmFAY3lwcmVzcy5jb20+DQo+ID4gKyAqDQo+ID4gKyAqIFRoaXMgcHJvZ3Jh bSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5 IGl0DQo+ID4gKyAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExp Y2Vuc2UgdmVyc2lvbiAyIGFzDQo+IHB1Ymxpc2hlZCBieQ0KPiA+ICsgKiB0aGUgRnJlZSBTb2Z0 d2FyZSBGb3VuZGF0aW9uLg0KPiA+ICsgKi8NCj4gPiArDQo+ID4gKyNpZm5kZWYgX19NRkRfQ1lV U0JTMjNYX0hfXw0KPiA+ICsjZGVmaW5lIF9fTUZEX0NZVVNCUzIzWF9IX18NCj4gPiArDQo+ID4g KyNpbmNsdWRlIDxsaW51eC90eXBlcy5oPg0KPiA+ICsjaW5jbHVkZSA8bGludXgvdXNiLmg+DQo+ ID4gKw0KPiA+ICsvKiBTdHJ1Y3R1cmUgdG8gaG9sZCBhbGwgZGV2aWNlIHNwZWNpZmljIHN0dWZm ICovDQo+ID4gK3N0cnVjdCBjeXVzYnMyM3ggew0KPiA+ICsgICAgIHN0cnVjdCB1c2JfZGV2aWNl ICp1c2JfZGV2Ow0KPiA+ICsgICAgIHN0cnVjdCB1c2JfaW50ZXJmYWNlICp1c2JfaW50ZjsNCj4g PiArDQo+ID4gKyAgICAgdTggaW50Zl9udW07DQo+ID4gKyAgICAgdTggYnVsa19pbl9lcF9udW07 DQo+ID4gKyAgICAgdTggYnVsa19vdXRfZXBfbnVtOw0KPiA+ICsgICAgIHU4IGludHJfaW5fZXBf bnVtOw0KPiA+ICt9Ow0KPiA+ICsNCj4gPiArZW51bSBjeV91c2JzX3ZlbmRvcl9jbWRzIHsNCj4g PiArICAgICBDWV9JMkNfR0VUX0NPTkZJR19DTUQgID0gMHhDNCwNCj4gPiArICAgICBDWV9JMkNf U0VUX0NPTkZJR19DTUQgID0gMHhDNSwNCj4gPiArICAgICBDWV9JMkNfV1JJVEVfQ01EICAgICAg ID0gMHhDNiwNCj4gPiArICAgICBDWV9JMkNfUkVBRF9DTUQgICAgICAgID0gMHhDNywNCj4gPiAr ICAgICBDWV9JMkNfR0VUX1NUQVRVU19DTUQgID0gMHhDOCwNCj4gPiArICAgICBDWV9JMkNfUkVT RVRfQ01EICAgICAgID0gMHhDOSwNCj4gPiArICAgICBDWV9HUElPX0dFVF9DT05GSUdfQ01EID0g MHhEOCwNCj4gPiArICAgICBDWV9HUElPX1NFVF9DT05GSUdfQ01EID0gMHhEOSwNCj4gPiArICAg ICBDWV9HUElPX0dFVF9WQUxVRV9DTUQgID0gMHhEQSwNCj4gPiArICAgICBDWV9HUElPX1NFVF9W QUxVRV9DTUQgID0gMHhEQiwNCj4gPiArfTsNCj4gPiArDQo+ID4gKy8qIFNlcmlhbCBpbnRlcmZh Y2VzIChJMkMsIFNQSSwgVUFSVCkgZGlmZmVyIGluIGludGVyZmFjZSBzdWJjbGFzcyAqLw0KPiA+ ICtlbnVtIGN5X3NjYl9tb2RlcyB7DQo+ID4gKyAgICAgQ1lfVVNCU19TQ0JfRElTQUJMRUQgPSAw LA0KPiA+ICsgICAgIENZX1VTQlNfU0NCX1VBUlQgPSAxLA0KPiA+ICsgICAgIENZX1VTQlNfU0NC X1NQSSA9IDIsDQo+ID4gKyAgICAgQ1lfVVNCU19TQ0JfSTJDID0gMw0KPiANCj4gTm8gbmVlZCB0 byBudW1iZXIgdGhlc2UuDQo+IA0KPiA+ICt9Ow0KPiA+ICsNCj4gPiArLyogU0NCIGluZGV4IHNo aWZ0ICovDQo+ID4gKyNkZWZpbmUgQ1lfU0NCX0lOREVYX1NISUZUICAgICAgMTUNCj4gPiArDQo+ ID4gKyNkZWZpbmUgQ1lfVVNCU19DVFJMX1hGRVJfVElNRU9VVCAgICAyMDAwDQo+ID4gKyNkZWZp bmUgQ1lfVVNCU19CVUxLX1hGRVJfVElNRU9VVCAgICA1MDAwDQo+ID4gKyNkZWZpbmUgQ1lfVVNC U19JTlRSX1hGRVJfVElNRU9VVCAgICA1MDAwDQo+ID4gKw0KPiA+ICsjZW5kaWYgLyogX19NRkRf Q1lVU0JTMjNYX0hfXyAqLw0KPiANCj4gLS0NCj4gTGVlIEpvbmVzDQo+IExpbmFybyBTVE1pY3Jv ZWxlY3Ryb25pY3MgTGFuZGluZyBUZWFtIExlYWQNCj4gTGluYXJvLm9yZyDilIIgT3BlbiBzb3Vy Y2Ugc29mdHdhcmUgZm9yIEFSTSBTb0NzDQo+IEZvbGxvdyBMaW5hcm86IEZhY2Vib29rIHwgVHdp dHRlciB8IEJsb2cNCj4gVGhpcyBtZXNzYWdlIGFuZCBhbnkgYXR0YWNobWVudHMgbWF5IGNvbnRh aW4gQ3lwcmVzcyAob3IgaXRzIHN1YnNpZGlhcmllcykNCj4gY29uZmlkZW50aWFsIGluZm9ybWF0 aW9uLiBJZiBpdCBoYXMgYmVlbiByZWNlaXZlZCBpbiBlcnJvciwgcGxlYXNlIGFkdmlzZSB0aGUN Cj4gc2VuZGVyIGFuZCBpbW1lZGlhdGVseSBkZWxldGUgdGhpcyBtZXNzYWdlLg0K -- To unsubscribe from this list: send the line "unsubscribe linux-gpio" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
> > -----Original Message----- > > From: Lee Jones [mailto:lee.jones@linaro.org] > > Sent: Thursday, October 09, 2014 1:10 PM > > To: Muthu Mani > > Cc: Samuel Ortiz; Wolfram Sang; Linus Walleij; Alexandre Courbot; > > gregkh@linuxfoundation.org; linux-i2c@vger.kernel.org; linux- > > gpio@vger.kernel.org; linux-usb@vger.kernel.org; linux- > > kernel@vger.kernel.org; Rajaram Regupathy; Johan Hovold > > Subject: Re: [PATCH v3 1/3] mfd: add support for Cypress CYUSBS234 USB > > Serial Bridge controller Why is this in here? > > > + cyusbs->usb_dev = usb_get_dev(interface_to_usbdev(interface)); > > > > Can you do this last? Then you can remove the 'error' error path. > > mfd_add_devices would utlimately invoke the cell drivers' probe before returning and cell drivers use usb_dev in their probe. > So, leaving it as such. Can you move it down to just about mfd_add_devices() then. That way can you at least return directly in the other error paths. [...] > > > +MODULE_AUTHOR("Rajaram Regupathy <rera@cypress.com>"); > > > +MODULE_AUTHOR("Muthu Mani <muth@cypress.com>"); > > > +MODULE_DESCRIPTION("Cypress CYUSBS23x mfd core driver"); > > > > s/mfd/MFD/ > > Is there a typo? Yes mfd should be MFD, as I sed (spelt this way on purpose).
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index de5abf2..a31e9e3 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig @@ -116,6 +116,18 @@ config MFD_ASIC3 This driver supports the ASIC3 multifunction chip found on many PDAs (mainly iPAQ and HTC based ones) +config MFD_CYUSBS23X + tristate "Cypress CYUSBS23x USB Serial Bridge controller" + select MFD_CORE + depends on USB + default n + help + Say yes here if you want support for Cypress Semiconductor + CYUSBS23x USB-Serial Bridge controller. + + This driver can also be built as a module. If so, the module will be + called cyusbs23x. + config PMIC_DA903X bool "Dialog Semiconductor DA9030/DA9034 PMIC Support" depends on I2C=y diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile index f001487..fc5bcd1 100644 --- a/drivers/mfd/Makefile +++ b/drivers/mfd/Makefile @@ -151,6 +151,7 @@ si476x-core-y := si476x-cmd.o si476x-prop.o si476x-i2c.o obj-$(CONFIG_MFD_SI476X_CORE) += si476x-core.o obj-$(CONFIG_MFD_CS5535) += cs5535-mfd.o +obj-$(CONFIG_MFD_CYUSBS23X) += cyusbs23x.o obj-$(CONFIG_MFD_OMAP_USB_HOST) += omap-usb-host.o omap-usb-tll.o obj-$(CONFIG_MFD_PM8921_CORE) += pm8921-core.o ssbi.o obj-$(CONFIG_TPS65911_COMPARATOR) += tps65911-comparator.o diff --git a/drivers/mfd/cyusbs23x.c b/drivers/mfd/cyusbs23x.c new file mode 100644 index 0000000..c70ea40 --- /dev/null +++ b/drivers/mfd/cyusbs23x.c @@ -0,0 +1,167 @@ +/* + * Cypress USB-Serial Bridge Controller USB adapter driver + * + * Copyright (c) 2014 Cypress Semiconductor Corporation. + * + * Author: + * Muthu Mani <muth@cypress.com> + * + * Additional contributors include: + * Rajaram Regupathy <rera@cypress.com> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published by + * the Free Software Foundation. + */ + +/* + * This is core MFD driver for Cypress Semiconductor CYUSBS234 USB-Serial + * Bridge controller. CYUSBS234 offers a single channel serial interface + * (I2C/SPI/UART). It can be configured to enable either of I2C, SPI, UART + * interfaces. The GPIOs are also available to access. + * Details about the device can be found at: + * http://www.cypress.com/?rID=84126 + * + * Separate cell drivers are available for I2C and GPIO. SPI and UART are not + * supported yet. All GPIOs are exposed for get operation. However, only + * unused GPIOs can be set. + */ + +#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/cyusbs23x.h> + +#include <linux/usb.h> + +static const struct usb_device_id cyusbs23x_usb_table[] = { + { USB_DEVICE(0x04b4, 0x0004) }, /* Cypress Semiconductor */ + { } /* Terminating entry */ +}; + +MODULE_DEVICE_TABLE(usb, cyusbs23x_usb_table); + +static const struct mfd_cell cyusbs23x_i2c_devs[] = { + { + .name = "cyusbs23x-i2c", + }, + { + .name = "cyusbs23x-gpio", + }, +}; + +static int update_ep_details(struct usb_interface *interface, + struct cyusbs23x *cyusbs) +{ + struct usb_host_interface *iface_desc; + struct usb_endpoint_descriptor *ep; + int i; + + iface_desc = interface->cur_altsetting; + + for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) { + + ep = &iface_desc->endpoint[i].desc; + + if (!cyusbs->bulk_in_ep_num && usb_endpoint_is_bulk_in(ep)) + cyusbs->bulk_in_ep_num = ep->bEndpointAddress; + if (!cyusbs->bulk_out_ep_num && usb_endpoint_is_bulk_out(ep)) + cyusbs->bulk_out_ep_num = ep->bEndpointAddress; + if (!cyusbs->intr_in_ep_num && usb_endpoint_is_int_in(ep)) + cyusbs->intr_in_ep_num = ep->bEndpointAddress; + } + + dev_dbg(&interface->dev, "%s intr_in=%d, bulk_in=%d, bulk_out=%d\n", + __func__, cyusbs->intr_in_ep_num , + cyusbs->bulk_in_ep_num, cyusbs->bulk_out_ep_num); + + if (!cyusbs->bulk_in_ep_num || !cyusbs->bulk_out_ep_num || + !cyusbs->intr_in_ep_num) + return -ENODEV; + + return 0; +} + +static int cyusbs23x_probe(struct usb_interface *interface, + const struct usb_device_id *id) +{ + struct cyusbs23x *cyusbs; + const struct mfd_cell *cyusbs23x_devs; + int ret, ndevs = 0; + u8 sub_class; + + cyusbs = kzalloc(sizeof(*cyusbs), GFP_KERNEL); + if (cyusbs == NULL) + return -ENOMEM; + + cyusbs->usb_dev = usb_get_dev(interface_to_usbdev(interface)); + cyusbs->usb_intf = interface; + cyusbs->intf_num = interface->cur_altsetting->desc.bInterfaceNumber; + + ret = update_ep_details(interface, cyusbs); + if (ret < 0) { + dev_err(&interface->dev, "invalid interface\n"); + goto error; + } + + usb_set_intfdata(interface, cyusbs); + + /* Serial interfaces (I2C, SPI, UART) differ in interface subclass */ + sub_class = interface->cur_altsetting->desc.bInterfaceSubClass; + switch (sub_class) { + case CY_USBS_SCB_I2C: + dev_info(&interface->dev, "I2C interface found\n"); + cyusbs23x_devs = cyusbs23x_i2c_devs; + ndevs = ARRAY_SIZE(cyusbs23x_i2c_devs); + break; + default: + dev_err(&interface->dev, "unsupported subclass\n"); + ret = -ENODEV; + goto error; + } + + ret = mfd_add_devices(&interface->dev, PLATFORM_DEVID_AUTO, + cyusbs23x_devs, ndevs, NULL, 0, NULL); + if (ret != 0) { + dev_err(&interface->dev, "Failed to add mfd devices to core\n"); + goto error; + } + + return 0; + +error: + usb_put_dev(cyusbs->usb_dev); + kfree(cyusbs); + + return ret; +} + +static void cyusbs23x_disconnect(struct usb_interface *interface) +{ + struct cyusbs23x *cyusbs = usb_get_intfdata(interface); + + mfd_remove_devices(&interface->dev); + usb_put_dev(cyusbs->usb_dev); + kfree(cyusbs); + + dev_dbg(&interface->dev, "disconnected\n"); +} + +static struct usb_driver cyusbs23x_usb_driver = { + .name = "cyusbs23x", + .probe = cyusbs23x_probe, + .disconnect = cyusbs23x_disconnect, + .id_table = cyusbs23x_usb_table, +}; + +module_usb_driver(cyusbs23x_usb_driver); + +MODULE_AUTHOR("Rajaram Regupathy <rera@cypress.com>"); +MODULE_AUTHOR("Muthu Mani <muth@cypress.com>"); +MODULE_DESCRIPTION("Cypress CYUSBS23x mfd core driver"); +MODULE_LICENSE("GPL v2"); diff --git a/include/linux/mfd/cyusbs23x.h b/include/linux/mfd/cyusbs23x.h new file mode 100644 index 0000000..1580d98 --- /dev/null +++ b/include/linux/mfd/cyusbs23x.h @@ -0,0 +1,62 @@ +/* + * Cypress USB-Serial Bridge Controller definitions + * + * Copyright (c) 2014 Cypress Semiconductor Corporation. + * + * Author: + * Muthu Mani <muth@cypress.com> + * + * Additional contributors include: + * Rajaram Regupathy <rera@cypress.com> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published by + * the Free Software Foundation. + */ + +#ifndef __MFD_CYUSBS23X_H__ +#define __MFD_CYUSBS23X_H__ + +#include <linux/types.h> +#include <linux/usb.h> + +/* Structure to hold all device specific stuff */ +struct cyusbs23x { + struct usb_device *usb_dev; + struct usb_interface *usb_intf; + + u8 intf_num; + u8 bulk_in_ep_num; + u8 bulk_out_ep_num; + u8 intr_in_ep_num; +}; + +enum cy_usbs_vendor_cmds { + CY_I2C_GET_CONFIG_CMD = 0xC4, + CY_I2C_SET_CONFIG_CMD = 0xC5, + CY_I2C_WRITE_CMD = 0xC6, + CY_I2C_READ_CMD = 0xC7, + CY_I2C_GET_STATUS_CMD = 0xC8, + CY_I2C_RESET_CMD = 0xC9, + CY_GPIO_GET_CONFIG_CMD = 0xD8, + CY_GPIO_SET_CONFIG_CMD = 0xD9, + CY_GPIO_GET_VALUE_CMD = 0xDA, + CY_GPIO_SET_VALUE_CMD = 0xDB, +}; + +/* Serial interfaces (I2C, SPI, UART) differ in interface subclass */ +enum cy_scb_modes { + CY_USBS_SCB_DISABLED = 0, + CY_USBS_SCB_UART = 1, + CY_USBS_SCB_SPI = 2, + CY_USBS_SCB_I2C = 3 +}; + +/* SCB index shift */ +#define CY_SCB_INDEX_SHIFT 15 + +#define CY_USBS_CTRL_XFER_TIMEOUT 2000 +#define CY_USBS_BULK_XFER_TIMEOUT 5000 +#define CY_USBS_INTR_XFER_TIMEOUT 5000 + +#endif /* __MFD_CYUSBS23X_H__ */