From 6081e59c482c143869b00052f5726ed98d38c164 Mon Sep 17 00:00:00 2001 From: Tao Huang Date: Wed, 24 May 2023 09:32:51 +0800 Subject: [PATCH 1/6] rk: kbuild: silence resource_tool warning scripts/resource_tool.c:718:9: warning: ISO C90 forbids mixed declarations and code [-Wdeclaration-after-statement] ... Signed-off-by: Tao Huang Change-Id: I393a60474eb557ca0cdd54df9a391171e097f8b0 --- scripts/Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/Makefile b/scripts/Makefile index 96799cc4a57f..b350de8a41ea 100644 --- a/scripts/Makefile +++ b/scripts/Makefile @@ -15,6 +15,7 @@ hostprogs-always-$(CONFIG_RUST) += generate_rust_target generate_rust_target-rust := y +HOSTCFLAGS_resource_tool.o += -Wno-declaration-after-statement HOSTCFLAGS_sorttable.o = -I$(srctree)/tools/include HOSTLDLIBS_sorttable = -lpthread HOSTCFLAGS_asn1_compiler.o = -I$(srctree)/include From 258519868737ec8481a5f6bd202e0a645dffc07f Mon Sep 17 00:00:00 2001 From: Sandy Huang Date: Wed, 24 May 2023 10:07:49 +0800 Subject: [PATCH 2/6] drm/rockchip: dw_hdmi: regulator avdd-0v9 and avdd-1v8 is optional Fixes: daf27963218f ("Merge commit '52f971ee6e023d89d24f9e3cd145d86d707e459c'") Signed-off-by: Sandy Huang Change-Id: Ib4034fac08e43801b1c15c63159ac871150a232f --- drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c index fec8ed36ffa5..b238bdbe58d7 100644 --- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c +++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c @@ -1489,12 +1489,20 @@ static int rockchip_hdmi_parse_dt(struct rockchip_hdmi *hdmi) } hdmi->avdd_0v9 = devm_regulator_get_optional(hdmi->dev, "avdd-0v9"); - if (IS_ERR(hdmi->avdd_0v9)) - return PTR_ERR(hdmi->avdd_0v9); + if (IS_ERR(hdmi->avdd_0v9)) { + if (PTR_ERR(hdmi->avdd_0v9) != -ENODEV) + return dev_err_probe(hdmi->dev, PTR_ERR(hdmi->avdd_0v9), + "failed to get regulator: avdd-0v9\n"); + hdmi->avdd_0v9 = NULL; + } hdmi->avdd_1v8 = devm_regulator_get_optional(hdmi->dev, "avdd-1v8"); - if (IS_ERR(hdmi->avdd_1v8)) - return PTR_ERR(hdmi->avdd_1v8); + if (IS_ERR(hdmi->avdd_1v8)) { + if (PTR_ERR(hdmi->avdd_1v8) != -ENODEV) + return dev_err_probe(hdmi->dev, PTR_ERR(hdmi->avdd_1v8), + "failed to get regulator: avdd-1v8\n"); + hdmi->avdd_1v8 = NULL; + } hdmi->skip_check_420_mode = of_property_read_bool(np, "skip-check-420-mode"); From 640eb99d42cfa513af5c088e71a9cdea15978bc4 Mon Sep 17 00:00:00 2001 From: Frank Wang Date: Wed, 24 May 2023 10:13:22 +0800 Subject: [PATCH 3/6] phy: rockchip: inno-usb2: only disable usb480m clk in error path This fix the usb480m clk disable error when phy power on. Fixes: daf27963218f ("Merge commit '52f971ee6e023d89d24f9e3cd145d86d707e459c'") Signed-off-by: Frank Wang Change-Id: I79f84757cccdca56357794d3bb5bfdc8df6c0a1f --- drivers/phy/rockchip/phy-rockchip-inno-usb2.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c index e2b4ed027a75..66b36f65a5b5 100644 --- a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c +++ b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c @@ -886,8 +886,10 @@ static int rockchip_usb2phy_power_on(struct phy *phy) goto unlock; ret = property_enable(base, &rport->port_cfg->phy_sus, false); - if (ret) - goto disable_clks; + if (ret) { + clk_disable_unprepare(rphy->clk480m); + goto unlock; + } /* * For rk3588, it needs to reset phy when exit from @@ -900,8 +902,10 @@ static int rockchip_usb2phy_power_on(struct phy *phy) if (rport->port_id == USB2PHY_PORT_OTG && of_device_is_compatible(rphy->dev->of_node, "rockchip,rk3588-usb2phy")) { ret = rockchip_usb2phy_reset(rphy); - if (ret) - goto disable_clks; + if (ret) { + clk_disable_unprepare(rphy->clk480m); + goto unlock; + } } /* waiting for the utmi_clk to become stable */ @@ -909,9 +913,6 @@ static int rockchip_usb2phy_power_on(struct phy *phy) rport->suspended = false; -disable_clks: - clk_disable_unprepare(rphy->clk480m); - unlock: mutex_unlock(&rport->mutex); From 79b5303e248ec35abe4451602fafe5e30a5ea2b5 Mon Sep 17 00:00:00 2001 From: Badhri Jagan Sridharan Date: Mon, 15 Dec 2014 16:42:27 -0800 Subject: [PATCH 4/6] ANDROID: usb: gadget: configfs: Add usb_function ptr to fi struct Add a pointer to the usb_function inside the usb_function_instance structure to service functions specific setup requests even before the function gets added to the usb_gadget Bug: 63740241 Bug: 68755607 Bug: 78114713 Bug: 120441124 [badhri: This is a supporting patch for other patches which have replacements pipelined. It can be dropped when those implementations land.] Change-Id: I6f457006f6c5516cc6986ec2acdf5b1ecf259d0c Signed-off-by: Badhri Jagan Sridharan Signed-off-by: Frank Wang (cherry picked from commit 2d89290aec213c015611aadce0c99368f3bea4a4 https://android.googlesource.com/kernel/common) --- include/linux/usb/composite.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/linux/usb/composite.h b/include/linux/usb/composite.h index 43ac3fa760db..814f65799200 100644 --- a/include/linux/usb/composite.h +++ b/include/linux/usb/composite.h @@ -578,6 +578,7 @@ struct usb_function_instance { struct config_group group; struct list_head cfs_list; struct usb_function_driver *fd; + struct usb_function *f; int (*set_inst_name)(struct usb_function_instance *inst, const char *name); void (*free_func_inst)(struct usb_function_instance *inst); From ac360121408cbb1482076a113d059028a3d744e8 Mon Sep 17 00:00:00 2001 From: Badhri Jagan Sridharan Date: Mon, 15 Dec 2014 10:44:47 -0800 Subject: [PATCH 5/6] ANDROID: usb: gadget: configfs: Add Uevent to notify userspace Android userspace UsbDeviceManager relies on the uevents generated by the composition driver to generate user notifications. This CL adds uevents to be generated whenever USB changes its state i.e. connected, disconnected, configured. This CL also intercepts the setup requests from the usb_core anb routes it to the specific usb function if required. Change-Id: I112662728edcc404e3f08fa0c2d9e4f7b17e1b43 Bug: 68755607 Bug: 120441124 [badhri: Migrate to using udc uevents from upstream sysfs.] Signed-off-by: Badhri Jagan Sridharan [AmitP: Folded following android-4.9 commit changes into this patch 9214c899f730 ("ANDROID: usb: gadget: configfs: handle gadget reset request for android")] Signed-off-by: Amit Pundir [astrachan: Folded change 5c899c9fd75d ("ANDROID: usb: gadget: configfs: fix null ptr in android_disconnect") into this patch] Signed-off-by: Alistair Strachan Signed-off-by: Frank Wang (cherry picked from commit 7a160e2b962b3b38dbb3e044ca28232332524c84 https://android.googlesource.com/kernel/common) --- drivers/usb/gadget/Kconfig | 8 ++ drivers/usb/gadget/configfs.c | 252 +++++++++++++++++++++++++++++++++- 2 files changed, 258 insertions(+), 2 deletions(-) diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index 4fa2ddf322b4..605eb1c9cd95 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig @@ -230,6 +230,14 @@ config USB_CONFIGFS appropriate symbolic links. For more information see Documentation/usb/gadget_configfs.rst. +config USB_CONFIGFS_UEVENT + bool "Uevent notification of Gadget state" + depends on USB_CONFIGFS + help + Enable uevent notifications to userspace when the gadget + state changes. The gadget can be in any of the following + three states: "CONNECTED/DISCONNECTED/CONFIGURED" + config USB_CONFIGFS_SERIAL bool "Generic serial bulk in/out" depends on USB_CONFIGFS diff --git a/drivers/usb/gadget/configfs.c b/drivers/usb/gadget/configfs.c index d27faf74ccf2..b51ab8096292 100644 --- a/drivers/usb/gadget/configfs.c +++ b/drivers/usb/gadget/configfs.c @@ -10,6 +10,32 @@ #include "u_f.h" #include "u_os_desc.h" +#ifdef CONFIG_USB_CONFIGFS_UEVENT +#include +#include +#include + +#ifdef CONFIG_USB_CONFIGFS_F_ACC +extern int acc_ctrlrequest_composite(struct usb_composite_dev *cdev, + const struct usb_ctrlrequest *ctrl); +void acc_disconnect(void); +#endif +static struct class *android_class; +static struct device *android_device; +static int index; +static int gadget_index; + +struct device *create_function_device(char *name) +{ + if (android_device && !IS_ERR(android_device)) + return device_create(android_class, android_device, + MKDEV(0, index++), NULL, name); + else + return ERR_PTR(-EINVAL); +} +EXPORT_SYMBOL_GPL(create_function_device); +#endif + int check_user_usb_string(const char *name, struct usb_gadget_strings *stringtab_dev) { @@ -51,6 +77,12 @@ struct gadget_info { char qw_sign[OS_STRING_QW_SIGN_LEN]; spinlock_t spinlock; bool unbind; +#ifdef CONFIG_USB_CONFIGFS_UEVENT + bool connected; + bool sw_connected; + struct work_struct work; + struct device *dev; +#endif }; static inline struct gadget_info *to_gadget_info(struct config_item *item) @@ -273,7 +305,7 @@ static ssize_t gadget_dev_desc_UDC_store(struct config_item *item, mutex_lock(&gi->lock); - if (!strlen(name)) { + if (!strlen(name) || strcmp(name, "none") == 0) { ret = unregister_gadget(gi); if (ret) goto err; @@ -1427,6 +1459,57 @@ err_comp_cleanup: return ret; } +#ifdef CONFIG_USB_CONFIGFS_UEVENT +static void android_work(struct work_struct *data) +{ + struct gadget_info *gi = container_of(data, struct gadget_info, work); + struct usb_composite_dev *cdev = &gi->cdev; + char *disconnected[2] = { "USB_STATE=DISCONNECTED", NULL }; + char *connected[2] = { "USB_STATE=CONNECTED", NULL }; + char *configured[2] = { "USB_STATE=CONFIGURED", NULL }; + /* 0-connected 1-configured 2-disconnected*/ + bool status[3] = { false, false, false }; + unsigned long flags; + bool uevent_sent = false; + + spin_lock_irqsave(&cdev->lock, flags); + if (cdev->config) + status[1] = true; + + if (gi->connected != gi->sw_connected) { + if (gi->connected) + status[0] = true; + else + status[2] = true; + gi->sw_connected = gi->connected; + } + spin_unlock_irqrestore(&cdev->lock, flags); + + if (status[0]) { + kobject_uevent_env(&gi->dev->kobj, KOBJ_CHANGE, connected); + pr_info("%s: sent uevent %s\n", __func__, connected[0]); + uevent_sent = true; + } + + if (status[1]) { + kobject_uevent_env(&gi->dev->kobj, KOBJ_CHANGE, configured); + pr_info("%s: sent uevent %s\n", __func__, configured[0]); + uevent_sent = true; + } + + if (status[2]) { + kobject_uevent_env(&gi->dev->kobj, KOBJ_CHANGE, disconnected); + pr_info("%s: sent uevent %s\n", __func__, disconnected[0]); + uevent_sent = true; + } + + if (!uevent_sent) { + pr_info("%s: did not send uevent (%d %d %p)\n", __func__, + gi->connected, gi->sw_connected, cdev->config); + } +} +#endif + static void configfs_composite_unbind(struct usb_gadget *gadget) { struct usb_composite_dev *cdev; @@ -1454,6 +1537,50 @@ static void configfs_composite_unbind(struct usb_gadget *gadget) spin_unlock_irqrestore(&gi->spinlock, flags); } +#ifdef CONFIG_USB_CONFIGFS_UEVENT +static int android_setup(struct usb_gadget *gadget, + const struct usb_ctrlrequest *c) +{ + struct usb_composite_dev *cdev = get_gadget_data(gadget); + unsigned long flags; + struct gadget_info *gi = container_of(cdev, struct gadget_info, cdev); + int value = -EOPNOTSUPP; + struct usb_function_instance *fi; + + spin_lock_irqsave(&cdev->lock, flags); + if (!gi->connected) { + gi->connected = 1; + schedule_work(&gi->work); + } + spin_unlock_irqrestore(&cdev->lock, flags); + list_for_each_entry(fi, &gi->available_func, cfs_list) { + if (fi != NULL && fi->f != NULL && fi->f->setup != NULL) { + value = fi->f->setup(fi->f, c); + if (value >= 0) + break; + } + } + +#ifdef CONFIG_USB_CONFIGFS_F_ACC + if (value < 0) + value = acc_ctrlrequest_composite(cdev, c); +#endif + + if (value < 0) + value = composite_setup(gadget, c); + + spin_lock_irqsave(&cdev->lock, flags); + if (c->bRequest == USB_REQ_SET_CONFIGURATION && + cdev->config) { + schedule_work(&gi->work); + } + spin_unlock_irqrestore(&cdev->lock, flags); + + return value; +} + +#else // CONFIG_USB_CONFIGFS_UEVENT + static int configfs_composite_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) { @@ -1479,6 +1606,8 @@ static int configfs_composite_setup(struct usb_gadget *gadget, return ret; } +#endif // CONFIG_USB_CONFIGFS_UEVENT + static void configfs_composite_disconnect(struct usb_gadget *gadget) { struct usb_composite_dev *cdev; @@ -1489,6 +1618,14 @@ static void configfs_composite_disconnect(struct usb_gadget *gadget) if (!cdev) return; +#ifdef CONFIG_USB_CONFIGFS_F_ACC + /* + * accessory HID support can be active while the + * accessory function is not actually enabled, + * so we need to inform it when we are disconnected. + */ + acc_disconnect(); +#endif gi = container_of(cdev, struct gadget_info, cdev); spin_lock_irqsave(&gi->spinlock, flags); cdev = get_gadget_data(gadget); @@ -1497,6 +1634,10 @@ static void configfs_composite_disconnect(struct usb_gadget *gadget) return; } +#ifdef CONFIG_USB_CONFIGFS_UEVENT + gi->connected = 0; + schedule_work(&gi->work); +#endif composite_disconnect(gadget); spin_unlock_irqrestore(&gi->spinlock, flags); } @@ -1571,10 +1712,13 @@ static const struct usb_gadget_driver configfs_driver_template = { .bind = configfs_composite_bind, .unbind = configfs_composite_unbind, +#ifdef CONFIG_USB_CONFIGFS_UEVENT + .setup = android_setup, +#else .setup = configfs_composite_setup, +#endif .reset = configfs_composite_reset, .disconnect = configfs_composite_disconnect, - .suspend = configfs_composite_suspend, .resume = configfs_composite_resume, @@ -1585,6 +1729,91 @@ static const struct usb_gadget_driver configfs_driver_template = { .match_existing_only = 1, }; +#ifdef CONFIG_USB_CONFIGFS_UEVENT +static ssize_t state_show(struct device *pdev, struct device_attribute *attr, + char *buf) +{ + struct gadget_info *dev = dev_get_drvdata(pdev); + struct usb_composite_dev *cdev; + char *state = "DISCONNECTED"; + unsigned long flags; + + if (!dev) + goto out; + + cdev = &dev->cdev; + + if (!cdev) + goto out; + + spin_lock_irqsave(&cdev->lock, flags); + if (cdev->config) + state = "CONFIGURED"; + else if (dev->connected) + state = "CONNECTED"; + spin_unlock_irqrestore(&cdev->lock, flags); +out: + return sprintf(buf, "%s\n", state); +} + +static DEVICE_ATTR(state, S_IRUGO, state_show, NULL); + +static struct device_attribute *android_usb_attributes[] = { + &dev_attr_state, + NULL +}; + +static int android_device_create(struct gadget_info *gi) +{ + struct device_attribute **attrs; + struct device_attribute *attr; + + INIT_WORK(&gi->work, android_work); + gi->dev = device_create(android_class, NULL, + MKDEV(0, 0), NULL, "android%d", gadget_index++); + if (IS_ERR(gi->dev)) + return PTR_ERR(gi->dev); + + dev_set_drvdata(gi->dev, gi); + if (!android_device) + android_device = gi->dev; + + attrs = android_usb_attributes; + while ((attr = *attrs++)) { + int err; + + err = device_create_file(gi->dev, attr); + if (err) { + device_destroy(gi->dev->class, + gi->dev->devt); + return err; + } + } + + return 0; +} + +static void android_device_destroy(struct gadget_info *gi) +{ + struct device_attribute **attrs; + struct device_attribute *attr; + + attrs = android_usb_attributes; + while ((attr = *attrs++)) + device_remove_file(gi->dev, attr); + device_destroy(gi->dev->class, gi->dev->devt); +} +#else +static inline int android_device_create(struct gadget_info *gi) +{ + return 0; +} + +static inline void android_device_destroy(struct gadget_info *gi) +{ +} +#endif + static struct config_group *gadgets_make( struct config_group *group, const char *name) @@ -1642,6 +1871,9 @@ static struct config_group *gadgets_make( if (!gi->composite.gadget_driver.function) goto out_free_driver_name; + if (android_device_create(gi) < 0) + goto out_free_driver_name; + return &gi->group; out_free_driver_name: @@ -1653,7 +1885,11 @@ err: static void gadgets_drop(struct config_group *group, struct config_item *item) { + struct gadget_info *gi; + + gi = container_of(to_config_group(item), struct gadget_info, group); config_item_put(item); + android_device_destroy(gi); } static struct configfs_group_operations gadgets_ops = { @@ -1693,6 +1929,13 @@ static int __init gadget_cfs_init(void) config_group_init(&gadget_subsys.su_group); ret = configfs_register_subsystem(&gadget_subsys); + +#ifdef CONFIG_USB_CONFIGFS_UEVENT + android_class = class_create(THIS_MODULE, "android_usb"); + if (IS_ERR(android_class)) + return PTR_ERR(android_class); +#endif + return ret; } module_init(gadget_cfs_init); @@ -1700,5 +1943,10 @@ module_init(gadget_cfs_init); static void __exit gadget_cfs_exit(void) { configfs_unregister_subsystem(&gadget_subsys); +#ifdef CONFIG_USB_CONFIGFS_UEVENT + if (!IS_ERR(android_class)) + class_destroy(android_class); +#endif + } module_exit(gadget_cfs_exit); From 62ba841def983d87eb54878372a252048a85c801 Mon Sep 17 00:00:00 2001 From: Tao Huang Date: Wed, 24 May 2023 16:49:51 +0800 Subject: [PATCH 6/6] usb: gadget: u_audio: Add missing break in g_audio_work Fixes: c740acfa3426 ("usb: gadget: u_audio: add uevent for ppm compensation") Signed-off-by: Tao Huang Change-Id: I375a5cf21344ddd7d85eeaf66473bd2709c077ab --- drivers/usb/gadget/function/u_audio.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/usb/gadget/function/u_audio.c b/drivers/usb/gadget/function/u_audio.c index ee23af609429..727a9f475e55 100644 --- a/drivers/usb/gadget/function/u_audio.c +++ b/drivers/usb/gadget/function/u_audio.c @@ -1284,6 +1284,7 @@ static void g_audio_work(struct work_struct *data) uac_event[0] = "USB_STATE=SET_AUDIO_CLK"; snprintf(str, sizeof(str), "PPM=%d", audio->params.ppm); uac_event[1] = str; + break; default: break; }