Re: MUSB dual-role on AM335x behaving weirdly
Hi, On Thu, Jan 22, 2015 at 11:43:30AM +0100, Maxime Ripard wrote: Hi Yegor, On Thu, Jan 22, 2015 at 08:37:45AM +0100, Yegor Yefremov wrote: On 21.01.2015 19:53, Bin Liu wrote: Hi, On Wed, Jan 21, 2015 at 10:06 AM, Maxime Ripard maxime.rip...@free-electrons.com wrote: Hi Felipe, I'm currently working on a custom AM335x-based board, that has a OTG connector wired to one of the musb controlers, and Linux 3.17 This OTG connector seems to behave in a weird way when it comes to switching from one role to another: - The host mode works with CONFIG_USB_MUSB_DUAL_ROLE set, only if the dr_mode is set to host in the DT, and only if we plug the USB device after the kernel has booted. Otherwise, even though the controller seems to be set up as host in the kernel logs, it doesn't work. When DR-mode is set to otg, DRVVBUS is not high which surely doesn't help, but there might be some other issues. - The gadget mode works with CONFIG_USB_MUSB_DUAL_ROLE, if dr_mode is set to otg and not host (obviously), and only if we plug the USB cable after the kernel has booted. - The gadget mode works with CONFIG_USB_MUSB_GADGET, and with dr_mode set to otg, even if we cold plug the device. - As you might expect from the two first items, the runtime switching from gadget to host when CONFIG_USB_MUSB_DUAL_ROLE is set and dr_mode is set in otg doesn't work either. It looks like it's only waiting for an interrupt to occur to read the ID pin state, without reading its initial value, which would explain why both the host and gadget enumerate only when a device/cable is hotplugged, and that there's some configuration bits that differ whenever dr_mode changes, but I couldn't really see anything standing out in the driver nor the datasheet. Have you already experienced something alike with that driver? I don't use vanilla mainline kernel very often, but I don't have such hotplug issues with TI 3.12/14 kernels [1]. I only use CONFIG_USB_MUSB_DUAL_ROLE though. [1] git://git.ti.com/ti-linux-kernel/ti-linux-kernel.git, branch remote/origin/linux-3.14.y I have the same experience with 3.15. The switching is working when CONFIG_USB_MUSB_DUAL_ROLE is set and dr_mode = otg. But since 3.16 it seems to be broken. Still had no time to bisect this. I just gave 3.15 a quick try, and it looks like it can now detect when the device is acting as a gadget, but the host mode is not working at all. That's a good lead though, I'll dig more into the older versions and see if some are working better than others. This issue may be related to the fact that the musb controller does not have an ID pin interrupt. Last year I sent a RFC for a soft detection in OTG mode. It has a poll loop which toggles the SESSION bit of the controller to detect devices as host and drops back to device otherwise. This is far away from a good solution. http://lists.infradead.org/pipermail/linux-arm-kernel/2013-October/204519.html Best Regards, Markus -- Pengutronix e.K. | | Industrial Linux Solutions | http://www.pengutronix.de/ | Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0| Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917- | signature.asc Description: Digital signature
[PATCH] usb/musb: debugfs, fix copy_from_user argument
The first arugment has to be a pointer to the memory. buf is a char array and already a pointer itself. The current code passes a pointer to a char array to copy_from_user() which is not correct. Signed-off-by: Markus Pargmann m...@pengutronix.de --- drivers/usb/musb/musb_debugfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/musb/musb_debugfs.c b/drivers/usb/musb/musb_debugfs.c index ad3701a97389..bb13e0420140 100644 --- a/drivers/usb/musb/musb_debugfs.c +++ b/drivers/usb/musb/musb_debugfs.c @@ -194,7 +194,7 @@ static ssize_t musb_test_mode_write(struct file *file, memset(buf, 0x00, sizeof(buf)); - if (copy_from_user(buf, ubuf, min_t(size_t, sizeof(buf) - 1, count))) + if (copy_from_user(buf, ubuf, min_t(size_t, sizeof(buf) - 1, count))) return -EFAULT; if (!strncmp(buf, force host, 9)) -- 2.1.4 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] usb/musb: debugfs, fix copy_from_user argument
Hi, On Wed, Jan 14, 2015 at 03:19:42PM +, David Laight wrote: From: Markus Pargmann The first arugment has to be a pointer to the memory. buf is a char array and already a pointer itself. The current code passes a pointer to a char array to copy_from_user() which is not correct. It doesn't matter, while the type of the argument is subtly different the value passed is the same. Thanks, I didn't know about this. So the code is actually correct and the patch is not a fix. I would still prefer to have it consistent with the usage of 'buf' in the code above and below, where 'buf' is directly used. Best regards, Markus -- Pengutronix e.K. | | Industrial Linux Solutions | http://www.pengutronix.de/ | Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0| Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917- | signature.asc Description: Digital signature
Re: [PATCH] usb/musb: debugfs, fix copy_from_user argument
Hi, On Wed, Jan 14, 2015 at 11:08:12AM -0600, Felipe Balbi wrote: On Wed, Jan 14, 2015 at 05:12:55PM +0100, 'Markus Pargmann' wrote: Hi, On Wed, Jan 14, 2015 at 03:19:42PM +, David Laight wrote: From: Markus Pargmann The first arugment has to be a pointer to the memory. buf is a char array and already a pointer itself. The current code passes a pointer to a char array to copy_from_user() which is not correct. It doesn't matter, while the type of the argument is subtly different the value passed is the same. Thanks, I didn't know about this. So the code is actually correct and the patch is not a fix. I would still prefer to have it consistent with the usage of 'buf' in the code above and below, where 'buf' is directly used. I modified it like so: commit 5db92ebc06ad815a4032f28145531a879b73db08 Author: Markus Pargmann m...@pengutronix.de Date: Wed Jan 14 16:08:38 2015 +0100 usb: musb: debugfs: improve copy_from_user() argument While the code is correct and functions well, it's still a bit misleading to add the reference operator in from of the buf argument. This patch simply removes that operator in order to make use of buf slightly better to the eyes. Signed-off-by: Markus Pargmann m...@pengutronix.de Signed-off-by: Felipe Balbi ba...@ti.com Looks good, thank you. Best regards, Markus -- Pengutronix e.K. | | Industrial Linux Solutions | http://www.pengutronix.de/ | Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0| Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917- | signature.asc Description: Digital signature
Re: [RESEND PATCH v3 2/4] usb: musb: Bugfix of_node assignment
Hi Sebastian, This thread was about the of_node assignment for the child device musb-hdrc. Mainline commit: 4fc4b274f9b3 (usb: musb: dsps: do not bind to musb-hdrc) On Mon, Nov 25, 2013 at 05:48:54PM +0100, Sebastian Andrzej Siewior wrote: Is this fixing a bug? Commit 4fc4b2 (usb: musb: dsps: do not bind to musb-hdrc) [0] should fix the problem that is described here. ux500 is affected by the same problem as dsps but it is only visible on dsps because we DEFER probe for few reasons there test the fail path. So by just looking at it should fix the same problem as the change I cited _but_ it would also cover ux500. Currently I can't think of any side effects by assigning of_node if the musb_init_*() did not do it. If we take this in I would suggest to remove the check I added (because it does no longer serve any purpose) and the description (why we do this, what is the problem exactly) is could be taken from my patch since I think it is better described (it safe to assign a node to a driver, it becomes unsafe if after platform_probe _also_ the DT probe is executed which was not to designed to work like this). In the long term I would suggest to move the DT probe over to the musb core code and we wouldn't need the node assignment anymore… [0] http://www.spinics.net/lists/linux-usb/msg94701.html Really old thread but I just noticed that this solution does not work for automatically parsed properties like 'default' pinctrl. I added 'default' pinctrl settings for the musb device node. They are automatically setup by the driver core infrastracture as expected. The problem is that the 'default' pincontrol settings will be applied again for the musb-hdrc because they are extracted from the of_ndoe data. This fails because they are already claimed by the 'musb-dsps' driver. musb-hdrc continues probing, but there is a big error message that it failed: [1.181912] pinctrl-single 44e10800.pinmux: pin 44e10a20.0 already requested by 47401c00.usb; cannot clai m for musb-hdrc.1.auto [1.194053] pinctrl-single 44e10800.pinmux: pin-136 (musb-hdrc.1.auto) status -22 [1.201930] pinctrl-single 44e10800.pinmux: could not request pin 136 (44e10a20.0) from group pinmux_usb1 _pins on device pinctrl-single [1.214790] musb-hdrc musb-hdrc.1.auto: Error applying setting, reverse things back Any ideas how to solve it for mainline? Best regards, Markus -- Pengutronix e.K. | | Industrial Linux Solutions | http://www.pengutronix.de/ | Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0| Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917- | signature.asc Description: Digital signature
[PATCH v2 1/2] usb: ci_hdrc_imx: Return -EINVAL for missing USB PHY
-ENODEV is interpreted by the generic driver probing function as a non-matching driver. This leads to a missing probe failure message. Also a missing USB PHY is more of an invalid configuration of the usb driver because it is necessary. This patch returns -EINVAL if devm_usb_get_phy_by_phandle() returned -ENODEV. Signed-off-by: Markus Pargmann m...@pengutronix.de --- drivers/usb/chipidea/ci_hdrc_imx.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/usb/chipidea/ci_hdrc_imx.c b/drivers/usb/chipidea/ci_hdrc_imx.c index 2e58f8dfd311..65444b02bd68 100644 --- a/drivers/usb/chipidea/ci_hdrc_imx.c +++ b/drivers/usb/chipidea/ci_hdrc_imx.c @@ -133,6 +133,9 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev) data-phy = devm_usb_get_phy_by_phandle(pdev-dev, fsl,usbphy, 0); if (IS_ERR(data-phy)) { ret = PTR_ERR(data-phy); + /* Return -EINVAL if no usbphy is available */ + if (ret == -ENODEV) + ret = -EINVAL; goto err_clk; } -- 2.0.0 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 2/2] usb: ci_hdrc_imx doc: fsl,usbphy is required
fsl,usbphy is no optional property. This patch moves it to the list of required properties. Signed-off-by: Markus Pargmann m...@pengutronix.de --- Documentation/devicetree/bindings/usb/ci-hdrc-imx.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/usb/ci-hdrc-imx.txt b/Documentation/devicetree/bindings/usb/ci-hdrc-imx.txt index a6a32cb7f777..1bae71e9ad47 100644 --- a/Documentation/devicetree/bindings/usb/ci-hdrc-imx.txt +++ b/Documentation/devicetree/bindings/usb/ci-hdrc-imx.txt @@ -4,6 +4,7 @@ Required properties: - compatible: Should be fsl,imx27-usb - reg: Should contain registers location and length - interrupts: Should contain controller interrupt +- fsl,usbphy: phandle of usb phy that connects to the port Recommended properies: - phy_type: the type of the phy connected to the core. Should be one @@ -12,7 +13,6 @@ Recommended properies: - dr_mode: One of host, peripheral or otg. Defaults to otg Optional properties: -- fsl,usbphy: phandler of usb phy that connects to the only one port - fsl,usbmisc: phandler of non-core register device, with one argument that indicate usb controller index - vbus-supply: regulator for vbus -- 2.0.0 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 2/2] usb: ci_hdrc_imx doc: fsl,usbphy is required
Hi, On Tue, Jul 08, 2014 at 08:28:59PM +0400, Sergei Shtylyov wrote: Hello. On 07/08/2014 02:14 PM, Markus Pargmann wrote: fsl,usbphy is no optional property. This patch moves it to the list of required properties. Signed-off-by: Markus Pargmann m...@pengutronix.de --- Documentation/devicetree/bindings/usb/ci-hdrc-imx.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/usb/ci-hdrc-imx.txt b/Documentation/devicetree/bindings/usb/ci-hdrc-imx.txt index a6a32cb7f777..8014d0d050f8 100644 --- a/Documentation/devicetree/bindings/usb/ci-hdrc-imx.txt +++ b/Documentation/devicetree/bindings/usb/ci-hdrc-imx.txt @@ -4,6 +4,7 @@ Required properties: - compatible: Should be fsl,imx27-usb - reg: Should contain registers location and length - interrupts: Should contain controller interrupt +- fsl,usbphy: phandler of usb phy that connects to the only one port s/phandler/phandle/. Can fix, while at it... Yes, right, I will fix it and resend. Thanks, Markus -- Pengutronix e.K. | | Industrial Linux Solutions | http://www.pengutronix.de/ | Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0| Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917- | signature.asc Description: Digital signature
[PATCH 1/2] usb: ci_hdrc_imx: Return -EINVAL for missing USB PHY
-ENODEV is interpreted by the generic driver probing function as a non-matching driver. This leads to a missing probe failure message. Also a missing USB PHY is more of an invalid configuration of the usb driver because it is necessary. This patch returns -EINVAL if devm_usb_get_phy_by_phandle() returned -ENODEV. Signed-off-by: Markus Pargmann m...@pengutronix.de --- drivers/usb/chipidea/ci_hdrc_imx.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/usb/chipidea/ci_hdrc_imx.c b/drivers/usb/chipidea/ci_hdrc_imx.c index 2e58f8dfd311..65444b02bd68 100644 --- a/drivers/usb/chipidea/ci_hdrc_imx.c +++ b/drivers/usb/chipidea/ci_hdrc_imx.c @@ -133,6 +133,9 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev) data-phy = devm_usb_get_phy_by_phandle(pdev-dev, fsl,usbphy, 0); if (IS_ERR(data-phy)) { ret = PTR_ERR(data-phy); + /* Return -EINVAL if no usbphy is available */ + if (ret == -ENODEV) + ret = -EINVAL; goto err_clk; } -- 2.0.0 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 2/2] usb: ci_hdrc_imx doc: fsl,usbphy is required
fsl,usbphy is no optional property. This patch moves it to the list of required properties. Signed-off-by: Markus Pargmann m...@pengutronix.de --- Documentation/devicetree/bindings/usb/ci-hdrc-imx.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/usb/ci-hdrc-imx.txt b/Documentation/devicetree/bindings/usb/ci-hdrc-imx.txt index a6a32cb7f777..8014d0d050f8 100644 --- a/Documentation/devicetree/bindings/usb/ci-hdrc-imx.txt +++ b/Documentation/devicetree/bindings/usb/ci-hdrc-imx.txt @@ -4,6 +4,7 @@ Required properties: - compatible: Should be fsl,imx27-usb - reg: Should contain registers location and length - interrupts: Should contain controller interrupt +- fsl,usbphy: phandler of usb phy that connects to the only one port Recommended properies: - phy_type: the type of the phy connected to the core. Should be one @@ -12,7 +13,6 @@ Recommended properies: - dr_mode: One of host, peripheral or otg. Defaults to otg Optional properties: -- fsl,usbphy: phandler of usb phy that connects to the only one port - fsl,usbmisc: phandler of non-core register device, with one argument that indicate usb controller index - vbus-supply: regulator for vbus -- 2.0.0 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v4 0/2] usb: musb dsps updates
Hi, On Fri, Jan 17, 2014 at 10:22:34AM +0100, Markus Pargmann wrote: Hi, The two remaining patches from the previous series usb: musb bugfixes. In v4 I used the device name for the debugfs root dir and added a commit message to the second patch. Felipe, could you please have a look at this? Thanks, Markus Regards, Markus Markus Pargmann (2): usb: musb: dsps, debugfs files usb: musb: dsps, use devm_kzalloc drivers/usb/musb/musb_dsps.c | 58 +--- 1 file changed, 55 insertions(+), 3 deletions(-) -- 1.8.5.2 -- Pengutronix e.K. | | Industrial Linux Solutions | http://www.pengutronix.de/ | Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0| Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917- | -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v4 2/2] usb: musb: dsps, use devm_kzalloc
Replace kzalloc by devm_kzalloc and remove the kfree() calls. Signed-off-by: Markus Pargmann m...@pengutronix.de --- drivers/usb/musb/musb_dsps.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c index d0a97d6..6cae0c8 100644 --- a/drivers/usb/musb/musb_dsps.c +++ b/drivers/usb/musb/musb_dsps.c @@ -668,7 +668,7 @@ static int dsps_probe(struct platform_device *pdev) wrp = match-data; /* allocate glue */ - glue = kzalloc(sizeof(*glue), GFP_KERNEL); + glue = devm_kzalloc(pdev-dev, sizeof(*glue), GFP_KERNEL); if (!glue) { dev_err(pdev-dev, unable to allocate glue memory\n); return -ENOMEM; @@ -696,7 +696,6 @@ err3: pm_runtime_put(pdev-dev); err2: pm_runtime_disable(pdev-dev); - kfree(glue); return ret; } @@ -709,7 +708,6 @@ static int dsps_remove(struct platform_device *pdev) /* disable usbss clocks */ pm_runtime_put(pdev-dev); pm_runtime_disable(pdev-dev); - kfree(glue); debugfs_remove_recursive(glue-dbgfs_root); -- 1.8.5.2 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v4 0/2] usb: musb dsps updates
Hi, The two remaining patches from the previous series usb: musb bugfixes. In v4 I used the device name for the debugfs root dir and added a commit message to the second patch. Regards, Markus Markus Pargmann (2): usb: musb: dsps, debugfs files usb: musb: dsps, use devm_kzalloc drivers/usb/musb/musb_dsps.c | 58 +--- 1 file changed, 55 insertions(+), 3 deletions(-) -- 1.8.5.2 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v4 1/2] usb: musb: dsps, debugfs files
debugfs files to show the contents of important dsps registers. Signed-off-by: Markus Pargmann m...@pengutronix.de --- drivers/usb/musb/musb_dsps.c | 54 1 file changed, 54 insertions(+) diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c index 593d3c9..d0a97d6 100644 --- a/drivers/usb/musb/musb_dsps.c +++ b/drivers/usb/musb/musb_dsps.c @@ -46,6 +46,8 @@ #include linux/of_irq.h #include linux/usb/of.h +#include linux/debugfs.h + #include musb_core.h static const struct of_device_id musb_dsps_of_match[]; @@ -137,6 +139,26 @@ struct dsps_glue { unsigned long last_timer;/* last timer data for each instance */ struct dsps_context context; + struct debugfs_regset32 regset; + struct dentry *dbgfs_root; +}; + +static const struct debugfs_reg32 dsps_musb_regs[] = { + { revision, 0x00 }, + { control,0x14 }, + { status, 0x18 }, + { eoi,0x24 }, + { intr0_stat, 0x30 }, + { intr1_stat, 0x34 }, + { intr0_set, 0x38 }, + { intr1_set, 0x3c }, + { txmode, 0x70 }, + { rxmode, 0x74 }, + { autoreq,0xd0 }, + { srpfixtime, 0xd4 }, + { tdown, 0xd8 }, + { phy_utmi, 0xe0 }, + { mode, 0xe8 }, }; static void dsps_musb_try_idle(struct musb *musb, unsigned long timeout) @@ -369,6 +391,30 @@ out: return ret; } +static int dsps_musb_dbg_init(struct musb *musb, struct dsps_glue *glue) +{ + struct dentry *root; + struct dentry *file; + char buf[128]; + + sprintf(buf, %s.dsps, dev_name(musb-controller)); + root = debugfs_create_dir(buf, NULL); + if (!root) + return -ENOMEM; + glue-dbgfs_root = root; + + glue-regset.regs = dsps_musb_regs; + glue-regset.nregs = ARRAY_SIZE(dsps_musb_regs); + glue-regset.base = musb-ctrl_base; + + file = debugfs_create_regset32(regdump, S_IRUGO, root, glue-regset); + if (!file) { + debugfs_remove_recursive(root); + return -ENOMEM; + } + return 0; +} + static int dsps_musb_init(struct musb *musb) { struct device *dev = musb-controller; @@ -378,6 +424,7 @@ static int dsps_musb_init(struct musb *musb) void __iomem *reg_base; struct resource *r; u32 rev, val; + int ret; r = platform_get_resource_byname(parent, IORESOURCE_MEM, control); if (!r) @@ -411,6 +458,10 @@ static int dsps_musb_init(struct musb *musb) val = ~(1 wrp-otg_disable); dsps_writel(musb-ctrl_base, wrp-phy_utmi, val); + ret = dsps_musb_dbg_init(musb, glue); + if (ret) + return ret; + return 0; } @@ -659,6 +710,9 @@ static int dsps_remove(struct platform_device *pdev) pm_runtime_put(pdev-dev); pm_runtime_disable(pdev-dev); kfree(glue); + + debugfs_remove_recursive(glue-dbgfs_root); + return 0; } -- 1.8.5.2 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RESEND PATCH v3 3/4] usb: musb: dsps, debugfs files
Hi, On Mon, Nov 25, 2013 at 09:57:39AM -0600, Felipe Balbi wrote: Hi, On Mon, Nov 18, 2013 at 04:54:37PM +0100, Markus Pargmann wrote: @@ -350,6 +373,30 @@ out: return ret; } +static int dsps_musb_dbg_init(struct musb *musb, struct dsps_glue *glue) +{ + struct dentry *root; + struct dentry *file; + char buf[128]; + + sprintf(buf, %s.dsps, dev_name(musb-controller)); why ? just use the glue's device I used this to have a more obvious relationship between musb-core debugfs and musb-dsps debugfs. Otherwise we would have '47401400.usb' for dsps and 'musb-hdrc.0.auto' for musb core. But I can change it if you want. Regards, Markus -- Pengutronix e.K. | | Industrial Linux Solutions | http://www.pengutronix.de/ | Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0| Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917- | -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RESEND PATCH v3 4/4] usb: musb: dsps, use devm_kzalloc
On Mon, Nov 25, 2013 at 09:58:04AM -0600, Felipe Balbi wrote: On Mon, Nov 18, 2013 at 04:54:38PM +0100, Markus Pargmann wrote: Signed-off-by: Markus Pargmann m...@pengutronix.de no commit log == no commit. Sorry, but I'll be very pedantic about it. Okay I will add a commit message. Regards, Markus -- Pengutronix e.K. | | Industrial Linux Solutions | http://www.pengutronix.de/ | Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0| Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917- | -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RESEND PATCH v3 2/4] usb: musb: Bugfix of_node assignment
Hi, On Mon, Nov 25, 2013 at 05:48:54PM +0100, Sebastian Andrzej Siewior wrote: On 11/25/2013 05:14 PM, Felipe Balbi wrote: Hi, On Mon, Nov 18, 2013 at 04:54:36PM +0100, Markus Pargmann wrote: It is not safe to assign the of_node to a device without driver. The device is matched against a list of drivers and the of_node could lead to a DT match with the parent driver. Signed-off-by: Markus Pargmann m...@pengutronix.de --- drivers/usb/musb/musb_core.c | 12 +++- drivers/usb/musb/musb_dsps.c | 1 - 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index 8b7d903..d5ad9db 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -1966,6 +1966,7 @@ static int musb_probe(struct platform_device *pdev) int irq = platform_get_irq_byname(pdev, mc); struct resource *iomem; void __iomem*base; +int ret; iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!iomem || irq = 0) @@ -1975,7 +1976,16 @@ static int musb_probe(struct platform_device *pdev) if (IS_ERR(base)) return PTR_ERR(base); - return musb_init_controller(dev, irq, base); + if (dev-parent) don't we always have a parent? + dev-of_node = dev-parent-of_node; + +ret = musb_init_controller(dev, irq, base); +if (ret) { + dev-of_node = NULL; + return ret; + } + + return 0; } static int musb_remove(struct platform_device *pdev) diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c index 82e1da0..7b36d32 100644 --- a/drivers/usb/musb/musb_dsps.c +++ b/drivers/usb/musb/musb_dsps.c @@ -485,7 +485,6 @@ static int dsps_create_musb_pdev(struct dsps_glue *glue, musb-dev.parent = dev; musb-dev.dma_mask= musb_dmamask; musb-dev.coherent_dma_mask= musb_dmamask; - musb-dev.of_node = of_node_get(dn); Sebastian, does this look correct to you ? Is this fixing a bug? Commit 4fc4b2 (usb: musb: dsps: do not bind to musb-hdrc) [0] should fix the problem that is described here. ux500 is affected by the same problem as dsps but it is only visible on dsps because we DEFER probe for few reasons there test the fail path. Sorry, I didn't check again if this is fixed by some applied patches. I first discovered this bug in september and send this patch in october. It is the same bug. So by just looking at it should fix the same problem as the change I cited _but_ it would also cover ux500. Currently I can't think of any side effects by assigning of_node if the musb_init_*() did not do it. If we take this in I would suggest to remove the check I added (because it does no longer serve any purpose) and the description (why we do this, what is the problem exactly) is could be taken from my patch since I think it is better described (it safe to assign a node to a driver, it becomes unsafe if after platform_probe _also_ the DT probe is executed which was not to designed to work like this). Your patch is already applied, so I could simply drop this one. Regards, Markus In the long term I would suggest to move the DT probe over to the musb core code and we wouldn't need the node assignment anymore… [0] http://www.spinics.net/lists/linux-usb/msg94701.html Sebastian -- Pengutronix e.K. | | Industrial Linux Solutions | http://www.pengutronix.de/ | Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0| Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917- | -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[RESEND PATCH v3 2/4] usb: musb: Bugfix of_node assignment
It is not safe to assign the of_node to a device without driver. The device is matched against a list of drivers and the of_node could lead to a DT match with the parent driver. Signed-off-by: Markus Pargmann m...@pengutronix.de --- drivers/usb/musb/musb_core.c | 12 +++- drivers/usb/musb/musb_dsps.c | 1 - 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index 8b7d903..d5ad9db 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -1966,6 +1966,7 @@ static int musb_probe(struct platform_device *pdev) int irq = platform_get_irq_byname(pdev, mc); struct resource *iomem; void __iomem*base; + int ret; iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!iomem || irq = 0) @@ -1975,7 +1976,16 @@ static int musb_probe(struct platform_device *pdev) if (IS_ERR(base)) return PTR_ERR(base); - return musb_init_controller(dev, irq, base); + if (dev-parent) + dev-of_node = dev-parent-of_node; + + ret = musb_init_controller(dev, irq, base); + if (ret) { + dev-of_node = NULL; + return ret; + } + + return 0; } static int musb_remove(struct platform_device *pdev) diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c index 82e1da0..7b36d32 100644 --- a/drivers/usb/musb/musb_dsps.c +++ b/drivers/usb/musb/musb_dsps.c @@ -485,7 +485,6 @@ static int dsps_create_musb_pdev(struct dsps_glue *glue, musb-dev.parent= dev; musb-dev.dma_mask = musb_dmamask; musb-dev.coherent_dma_mask = musb_dmamask; - musb-dev.of_node = of_node_get(dn); glue-musb = musb; -- 1.8.4.2 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[RESEND PATCH v3 3/4] usb: musb: dsps, debugfs files
debugfs files to show the contents of important dsps registers. Signed-off-by: Markus Pargmann m...@pengutronix.de --- drivers/usb/musb/musb_dsps.c | 55 1 file changed, 55 insertions(+) diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c index 7b36d32..06debf8 100644 --- a/drivers/usb/musb/musb_dsps.c +++ b/drivers/usb/musb/musb_dsps.c @@ -46,6 +46,8 @@ #include linux/of_irq.h #include linux/usb/of.h +#include linux/debugfs.h + #include musb_core.h static const struct of_device_id musb_dsps_of_match[]; @@ -119,6 +121,27 @@ struct dsps_glue { const struct dsps_musb_wrapper *wrp; /* wrapper register offsets */ struct timer_list timer;/* otg_workaround timer */ unsigned long last_timer;/* last timer data for each instance */ + + struct debugfs_regset32 regset; + struct dentry *dbgfs_root; +}; + +static const struct debugfs_reg32 dsps_musb_regs[] = { + { revision, 0x00 }, + { control,0x14 }, + { status, 0x18 }, + { eoi,0x24 }, + { intr0_stat, 0x30 }, + { intr1_stat, 0x34 }, + { intr0_set, 0x38 }, + { intr1_set, 0x3c }, + { txmode, 0x70 }, + { rxmode, 0x74 }, + { autoreq,0xd0 }, + { srpfixtime, 0xd4 }, + { tdown, 0xd8 }, + { phy_utmi, 0xe0 }, + { mode, 0xe8 }, }; static void dsps_musb_try_idle(struct musb *musb, unsigned long timeout) @@ -350,6 +373,30 @@ out: return ret; } +static int dsps_musb_dbg_init(struct musb *musb, struct dsps_glue *glue) +{ + struct dentry *root; + struct dentry *file; + char buf[128]; + + sprintf(buf, %s.dsps, dev_name(musb-controller)); + root = debugfs_create_dir(buf, NULL); + if (!root) + return -ENOMEM; + glue-dbgfs_root = root; + + glue-regset.regs = dsps_musb_regs; + glue-regset.nregs = ARRAY_SIZE(dsps_musb_regs); + glue-regset.base = musb-ctrl_base; + + file = debugfs_create_regset32(regdump, S_IRUGO, root, glue-regset); + if (!file) { + debugfs_remove_recursive(root); + return -ENOMEM; + } + return 0; +} + static int dsps_musb_init(struct musb *musb) { struct device *dev = musb-controller; @@ -359,6 +406,7 @@ static int dsps_musb_init(struct musb *musb) void __iomem *reg_base; struct resource *r; u32 rev, val; + int ret; r = platform_get_resource_byname(parent, IORESOURCE_MEM, control); if (!r) @@ -392,6 +440,10 @@ static int dsps_musb_init(struct musb *musb) val = ~(1 wrp-otg_disable); dsps_writel(musb-ctrl_base, wrp-phy_utmi, val); + ret = dsps_musb_dbg_init(musb, glue); + if (ret) + return ret; + return 0; } @@ -586,6 +638,9 @@ static int dsps_remove(struct platform_device *pdev) pm_runtime_put(pdev-dev); pm_runtime_disable(pdev-dev); kfree(glue); + + debugfs_remove_recursive(glue-dbgfs_root); + return 0; } -- 1.8.4.2 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[RESEND PATCH v3 4/4] usb: musb: dsps, use devm_kzalloc
Signed-off-by: Markus Pargmann m...@pengutronix.de --- drivers/usb/musb/musb_dsps.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c index 06debf8..058d611 100644 --- a/drivers/usb/musb/musb_dsps.c +++ b/drivers/usb/musb/musb_dsps.c @@ -596,7 +596,7 @@ static int dsps_probe(struct platform_device *pdev) wrp = match-data; /* allocate glue */ - glue = kzalloc(sizeof(*glue), GFP_KERNEL); + glue = devm_kzalloc(pdev-dev, sizeof(*glue), GFP_KERNEL); if (!glue) { dev_err(pdev-dev, unable to allocate glue memory\n); return -ENOMEM; @@ -624,7 +624,6 @@ err3: pm_runtime_put(pdev-dev); err2: pm_runtime_disable(pdev-dev); - kfree(glue); return ret; } @@ -637,7 +636,6 @@ static int dsps_remove(struct platform_device *pdev) /* disable usbss clocks */ pm_runtime_put(pdev-dev); pm_runtime_disable(pdev-dev); - kfree(glue); debugfs_remove_recursive(glue-dbgfs_root); -- 1.8.4.2 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[RESEND PATCH v3 1/4] usb: musb: gadget, stay IDLE without gadget driver
If there is no gadget driver musb should stay in B_IDLE state. Signed-off-by: Markus Pargmann m...@pengutronix.de --- drivers/usb/musb/musb_core.c | 3 --- drivers/usb/musb/musb_gadget.c | 14 -- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index 4db987f..8b7d903 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -831,12 +831,9 @@ b_host: case OTG_STATE_B_WAIT_ACON: dev_dbg(musb-controller, HNP: RESET (%s), to b_peripheral\n, usb_otg_state_string(musb-xceiv-state)); - musb-xceiv-state = OTG_STATE_B_PERIPHERAL; musb_g_reset(musb); break; case OTG_STATE_B_IDLE: - musb-xceiv-state = OTG_STATE_B_PERIPHERAL; - /* FALLTHROUGH */ case OTG_STATE_B_PERIPHERAL: musb_g_reset(musb); break; diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c index 9a08679..c352f73 100644 --- a/drivers/usb/musb/musb_gadget.c +++ b/drivers/usb/musb/musb_gadget.c @@ -2110,10 +2110,20 @@ __acquires(musb-lock) * or else after HNP, as A-Device */ if (devctl MUSB_DEVCTL_BDEVICE) { - musb-xceiv-state = OTG_STATE_B_PERIPHERAL; + if (!musb-gadget_driver) { + musb-is_active = 0; + musb-xceiv-state = OTG_STATE_B_IDLE; + } else { + musb-xceiv-state = OTG_STATE_B_PERIPHERAL; + } musb-g.is_a_peripheral = 0; } else { - musb-xceiv-state = OTG_STATE_A_PERIPHERAL; + if (!musb-gadget_driver) { + musb-is_active = 0; + musb-xceiv-state = OTG_STATE_A_IDLE; + } else { + musb-xceiv-state = OTG_STATE_A_PERIPHERAL; + } musb-g.is_a_peripheral = 1; } -- 1.8.4.2 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[RESEND PATCH v3 0/4] usb: musb bugfixes
Hi, I rebased this series onto Felipe's next branch. There are no other changes. The series contains two bugfixes and some debugfs file operations for dsps similar to the musb core regdump debugfs file. Regards, Markus Pargmann Changes in v3: - Using debugfs_reg32 for regdump debug file - Added a patch to replace kzalloc with devm_kzalloc - otg-gadget_driver NULL pointer handling was replaced by a musb_g_reset patch to force IDLE states when no gadget driver is loaded. Markus Pargmann (4): usb: musb: gadget, stay IDLE without gadget driver usb: musb: Bugfix of_node assignment usb: musb: dsps, debugfs files usb: musb: dsps, use devm_kzalloc drivers/usb/musb/musb_core.c | 15 --- drivers/usb/musb/musb_dsps.c | 60 +++--- drivers/usb/musb/musb_gadget.c | 14 -- 3 files changed, 79 insertions(+), 10 deletions(-) -- 1.8.4.2 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v3 0/0] usb: musb bugfixes
Hi Felipe, On Wed, Oct 16, 2013 at 02:51:08PM +0200, Markus Pargmann wrote: Hi, the series contains two bugfixes and some debugfs file operations for dsps similar to the musb core regdump debugfs file. Do you have some time to look at these patches? Thanks, Markus Pargmann -- Pengutronix e.K. | | Industrial Linux Solutions | http://www.pengutronix.de/ | Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0| Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917- | -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 1/4] usb: musb: gadget, stay IDLE without gadget driver
If there is no gadget driver musb should stay in B_IDLE state. Signed-off-by: Markus Pargmann m...@pengutronix.de --- drivers/usb/musb/musb_core.c | 3 --- drivers/usb/musb/musb_gadget.c | 14 -- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index 18e877f..7d40dec 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -831,12 +831,9 @@ b_host: case OTG_STATE_B_WAIT_ACON: dev_dbg(musb-controller, HNP: RESET (%s), to b_peripheral\n, usb_otg_state_string(musb-xceiv-state)); - musb-xceiv-state = OTG_STATE_B_PERIPHERAL; musb_g_reset(musb); break; case OTG_STATE_B_IDLE: - musb-xceiv-state = OTG_STATE_B_PERIPHERAL; - /* FALLTHROUGH */ case OTG_STATE_B_PERIPHERAL: musb_g_reset(musb); break; diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c index b19ed21..fddda5d 100644 --- a/drivers/usb/musb/musb_gadget.c +++ b/drivers/usb/musb/musb_gadget.c @@ -2113,10 +2113,20 @@ __acquires(musb-lock) * or else after HNP, as A-Device */ if (devctl MUSB_DEVCTL_BDEVICE) { - musb-xceiv-state = OTG_STATE_B_PERIPHERAL; + if (!musb-gadget_driver) { + musb-is_active = 0; + musb-xceiv-state = OTG_STATE_B_IDLE; + } else { + musb-xceiv-state = OTG_STATE_B_PERIPHERAL; + } musb-g.is_a_peripheral = 0; } else { - musb-xceiv-state = OTG_STATE_A_PERIPHERAL; + if (!musb-gadget_driver) { + musb-is_active = 0; + musb-xceiv-state = OTG_STATE_A_IDLE; + } else { + musb-xceiv-state = OTG_STATE_A_PERIPHERAL; + } musb-g.is_a_peripheral = 1; } -- 1.8.4.rc3 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 0/0] usb: musb bugfixes
Hi, the series contains two bugfixes and some debugfs file operations for dsps similar to the musb core regdump debugfs file. Regards, Markus Pargmann Changes in v3: - Using debugfs_reg32 for regdump debug file - Added a patch to replace kzalloc with devm_kzalloc - otg-gadget_driver NULL pointer handling was replaced by a musb_g_reset patch to force IDLE states when no gadget driver is loaded. Markus Pargmann (4): usb: musb: gadget, stay IDLE without gadget driver usb: musb: Bugfix of_node assignment usb: musb: dsps, debugfs files usb: musb: dsps, use devm_kzalloc drivers/usb/musb/musb_core.c | 15 --- drivers/usb/musb/musb_dsps.c | 60 +++--- drivers/usb/musb/musb_gadget.c | 14 -- 3 files changed, 79 insertions(+), 10 deletions(-) -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 3/4] usb: musb: dsps, debugfs files
debugfs files to show the contents of important dsps registers. Signed-off-by: Markus Pargmann m...@pengutronix.de --- drivers/usb/musb/musb_dsps.c | 55 1 file changed, 55 insertions(+) diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c index 189e52c..0680f0e 100644 --- a/drivers/usb/musb/musb_dsps.c +++ b/drivers/usb/musb/musb_dsps.c @@ -46,6 +46,8 @@ #include linux/of_irq.h #include linux/usb/of.h +#include linux/debugfs.h + #include musb_core.h static const struct of_device_id musb_dsps_of_match[]; @@ -119,6 +121,27 @@ struct dsps_glue { const struct dsps_musb_wrapper *wrp; /* wrapper register offsets */ struct timer_list timer;/* otg_workaround timer */ unsigned long last_timer;/* last timer data for each instance */ + + struct debugfs_regset32 regset; + struct dentry *dbgfs_root; +}; + +static const struct debugfs_reg32 dsps_musb_regs[] = { + { revision, 0x00 }, + { control,0x14 }, + { status, 0x18 }, + { eoi,0x24 }, + { intr0_stat, 0x30 }, + { intr1_stat, 0x34 }, + { intr0_set, 0x38 }, + { intr1_set, 0x3c }, + { txmode, 0x70 }, + { rxmode, 0x74 }, + { autoreq,0xd0 }, + { srpfixtime, 0xd4 }, + { tdown, 0xd8 }, + { phy_utmi, 0xe0 }, + { mode, 0xe8 }, }; /** @@ -348,6 +371,30 @@ out: return ret; } +static int dsps_musb_dbg_init(struct musb *musb, struct dsps_glue *glue) +{ + struct dentry *root; + struct dentry *file; + char buf[128]; + + sprintf(buf, %s.dsps, dev_name(musb-controller)); + root = debugfs_create_dir(buf, NULL); + if (!root) + return -ENOMEM; + glue-dbgfs_root = root; + + glue-regset.regs = dsps_musb_regs; + glue-regset.nregs = ARRAY_SIZE(dsps_musb_regs); + glue-regset.base = musb-ctrl_base; + + file = debugfs_create_regset32(regdump, S_IRUGO, root, glue-regset); + if (!file) { + debugfs_remove_recursive(root); + return -ENOMEM; + } + return 0; +} + static int dsps_musb_init(struct musb *musb) { struct device *dev = musb-controller; @@ -357,6 +404,7 @@ static int dsps_musb_init(struct musb *musb) void __iomem *reg_base; struct resource *r; u32 rev, val; + int ret; r = platform_get_resource_byname(parent, IORESOURCE_MEM, control); if (!r) @@ -390,6 +438,10 @@ static int dsps_musb_init(struct musb *musb) val = ~(1 wrp-otg_disable); dsps_writel(musb-ctrl_base, wrp-phy_utmi, val); + ret = dsps_musb_dbg_init(musb, glue); + if (ret) + return ret; + return 0; } @@ -587,6 +639,9 @@ static int dsps_remove(struct platform_device *pdev) pm_runtime_put(pdev-dev); pm_runtime_disable(pdev-dev); kfree(glue); + + debugfs_remove_recursive(glue-dbgfs_root); + return 0; } -- 1.8.4.rc3 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 4/4] usb: musb: dsps, use devm_kzalloc
Signed-off-by: Markus Pargmann m...@pengutronix.de --- drivers/usb/musb/musb_dsps.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c index 0680f0e..aae017c 100644 --- a/drivers/usb/musb/musb_dsps.c +++ b/drivers/usb/musb/musb_dsps.c @@ -597,7 +597,7 @@ static int dsps_probe(struct platform_device *pdev) wrp = match-data; /* allocate glue */ - glue = kzalloc(sizeof(*glue), GFP_KERNEL); + glue = devm_kzalloc(pdev-dev, sizeof(*glue), GFP_KERNEL); if (!glue) { dev_err(pdev-dev, unable to allocate glue memory\n); return -ENOMEM; @@ -625,7 +625,6 @@ err3: pm_runtime_put(pdev-dev); err2: pm_runtime_disable(pdev-dev); - kfree(glue); return ret; } @@ -638,7 +637,6 @@ static int dsps_remove(struct platform_device *pdev) /* disable usbss clocks */ pm_runtime_put(pdev-dev); pm_runtime_disable(pdev-dev); - kfree(glue); debugfs_remove_recursive(glue-dbgfs_root); -- 1.8.4.rc3 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 2/4] usb: musb: Bugfix of_node assignment
It is not safe to assign the of_node to a device without driver. The device is matched against a list of drivers and the of_node could lead to a DT match with the parent driver. Signed-off-by: Markus Pargmann m...@pengutronix.de --- drivers/usb/musb/musb_core.c | 12 +++- drivers/usb/musb/musb_dsps.c | 1 - 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index 7d40dec..651cce0 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -1958,6 +1958,7 @@ static int musb_probe(struct platform_device *pdev) int irq = platform_get_irq_byname(pdev, mc); struct resource *iomem; void __iomem*base; + int ret; iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!iomem || irq = 0) @@ -1967,7 +1968,16 @@ static int musb_probe(struct platform_device *pdev) if (IS_ERR(base)) return PTR_ERR(base); - return musb_init_controller(dev, irq, base); + if (dev-parent) + dev-of_node = dev-parent-of_node; + + ret = musb_init_controller(dev, irq, base); + if (ret) { + dev-of_node = NULL; + return ret; + } + + return 0; } static int musb_remove(struct platform_device *pdev) diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c index bd4138d..189e52c 100644 --- a/drivers/usb/musb/musb_dsps.c +++ b/drivers/usb/musb/musb_dsps.c @@ -483,7 +483,6 @@ static int dsps_create_musb_pdev(struct dsps_glue *glue, musb-dev.parent= dev; musb-dev.dma_mask = musb_dmamask; musb-dev.coherent_dma_mask = musb_dmamask; - musb-dev.of_node = of_node_get(dn); glue-musb = musb; -- 1.8.4.rc3 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RFC] usb: musb: dsps, OTG detection
On Mon, Oct 14, 2013 at 03:43:35PM -0500, Bin Liu wrote: On Mon, Oct 14, 2013 at 10:22 AM, Markus Pargmann m...@pengutronix.de wrote: Hi, On Mon, Oct 14, 2013 at 08:54:09AM -0500, Bin Liu wrote: On Mon, Oct 14, 2013 at 8:35 AM, Markus Pargmann m...@pengutronix.de wrote: The USB Controller does not support ID pin change interrupts. So we have to use a polling function to detect changes of A/B device state (otg_timer). This poll function has to check in several states if a other device type might be connected to the USB port. This check is triggered by manually starting/stopping a USB Session. I think this is an arguable approach. Toggling the SESSION in otg_timer() causes voltage pulses on VBUS, which will not pass the USB certification. This is only done when no device is connected, so I am not sure if it is important. Unfortunately we do not see the A/B state changes until That is right, and I don't think it hurts. The only problem is that the USB certification test sees the VBUS pulses and fails. toggling the SESSION. Is there another way to check this? Unfortunately, toggling SESSION in b_idle is the only way I am aware of. I have not seen any products required the dynamic dual role switching yet. It always fixed in either device mode or host mode. OTG is explicitly listed in the devicetree bindings documentation, so I think the driver should be able to detect different roles. Yes, MUSB supports OTG. But I have not seen anyone use OTG yet, and I not sure if it is a good idea to add the OTG support, but fail the usb certification test. For example beaglebone does not overwrite the dr_mode = otg; property of am33xx.dtsi and it is a device where OTG could be useful. You may want to connect beaglebone to a PC or a keyboard while the other usb port has a USB storage device attached. With the current implementation this is only possible if the host or device is connected when the driver is probing. I could limit the SESSION toggling to OTG mode. If someone needs a system that passes the USB certification test, he could simply set the correct dr_mode in the DT and the device would pass the test. Regards, Markus Pargmann Regards, -Bin. Regards, Markus Pargmann Regards, -Bin. So in A mode, we cancel the currently running session which also disables the possibility to detect new devices via interrupt. In B mode, we start a session to check for ID-Pin and possibly connected devices. Whenever a real USB session ends, we have to trigger the otg_timer poll function again. Signed-off-by: Markus Pargmann m...@pengutronix.de --- drivers/usb/musb/musb_dsps.c | 84 1 file changed, 78 insertions(+), 6 deletions(-) diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c index b24b697..0245e8d 100644 --- a/drivers/usb/musb/musb_dsps.c +++ b/drivers/usb/musb/musb_dsps.c @@ -178,6 +178,43 @@ static const struct file_operations musb_regdump_fops = { #endif /* IS_ENABLED(CONFIG_DEBUG_FS) */ +/* + * Compare driver and hardware mode and update driver state if necessary. + * Not all hardware changes actually reach the driver through interrupts. + */ +static void dsps_update_mode(struct musb *musb) +{ + u8 devctl; + + devctl = dsps_readb(musb-mregs, MUSB_DEVCTL); + + switch (musb-xceiv-state) { + case OTG_STATE_A_IDLE: + if (devctl MUSB_DEVCTL_BDEVICE) { + dev_dbg(musb-controller, detected controller state B, software state A\n); + musb-xceiv-state = OTG_STATE_B_IDLE; + } + break; + case OTG_STATE_B_IDLE: + if (!(devctl MUSB_DEVCTL_BDEVICE)) { + dev_dbg(musb-controller, detected controller state A, software state B\n); + musb-xceiv-state = OTG_STATE_A_IDLE; + } + break; + default: + if (!(devctl MUSB_DEVCTL_SESSION)) { + dev_dbg(musb-controller, detected controller out of session (%x), software state %s\n, + devctl, + usb_otg_state_string(musb-xceiv-state)); + if (devctl MUSB_DEVCTL_BDEVICE) + musb-xceiv-state = OTG_STATE_B_IDLE; + else + musb-xceiv-state = OTG_STATE_A_IDLE; + } + break; + } +} + /** * dsps_musb_enable - enable interrupts */ @@ -229,6 +266,8 @@ static void otg_timer(unsigned long _musb) u8 devctl; unsigned long flags; + dsps_update_mode(musb
[PATCH 0/3] usb: musb bugfixes
Hi, the series contains two bugfixes and some debugfs file operations for dsps similar to the musb core regdump debugfs file. Regards, Markus Pargmann Markus Pargmann (3): usb: musb: Handle nullpointer usb: musb: Bugfix of_node assignment usb: musb: dsps, debugfs files drivers/usb/musb/musb_core.c | 15 +++- drivers/usb/musb/musb_dsps.c | 90 +++- 2 files changed, 102 insertions(+), 3 deletions(-) -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 2/3] usb: musb: Bugfix of_node assignment
It is not safe to assign the of_node to a device without driver. The device is matched against a list of drivers and the of_node could lead to a DT match with the parent driver. Signed-off-by: Markus Pargmann m...@pengutronix.de --- drivers/usb/musb/musb_core.c | 12 +++- drivers/usb/musb/musb_dsps.c | 1 - 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index baa4f6a..a26eccd 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -1962,6 +1962,7 @@ static int musb_probe(struct platform_device *pdev) int irq = platform_get_irq_byname(pdev, mc); struct resource *iomem; void __iomem*base; + int ret; iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!iomem || irq = 0) @@ -1971,7 +1972,16 @@ static int musb_probe(struct platform_device *pdev) if (IS_ERR(base)) return PTR_ERR(base); - return musb_init_controller(dev, irq, base); + if (dev-parent) + dev-of_node = dev-parent-of_node; + + ret = musb_init_controller(dev, irq, base); + if (ret) { + dev-of_node = NULL; + return ret; + } + + return 0; } static int musb_remove(struct platform_device *pdev) diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c index bd4138d..189e52c 100644 --- a/drivers/usb/musb/musb_dsps.c +++ b/drivers/usb/musb/musb_dsps.c @@ -483,7 +483,6 @@ static int dsps_create_musb_pdev(struct dsps_glue *glue, musb-dev.parent= dev; musb-dev.dma_mask = musb_dmamask; musb-dev.coherent_dma_mask = musb_dmamask; - musb-dev.of_node = of_node_get(dn); glue-musb = musb; -- 1.8.4.rc3 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 3/3] usb: musb: dsps, debugfs files
debugfs files to show the contents of important dsps registers. Signed-off-by: Markus Pargmann m...@pengutronix.de --- drivers/usb/musb/musb_dsps.c | 89 1 file changed, 89 insertions(+) diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c index 189e52c..b24b697 100644 --- a/drivers/usb/musb/musb_dsps.c +++ b/drivers/usb/musb/musb_dsps.c @@ -46,6 +46,8 @@ #include linux/of_irq.h #include linux/usb/of.h +#include linux/debugfs.h + #include musb_core.h static const struct of_device_id musb_dsps_of_match[]; @@ -121,6 +123,61 @@ struct dsps_glue { unsigned long last_timer;/* last timer data for each instance */ }; +#if IS_ENABLED(CONFIG_DEBUG_FS) + +struct musb_register_map { + char*name; + unsignedoffset; +}; + +static const struct musb_register_map musb_regmap[] = { + { revision, 0x00 }, + { control,0x14 }, + { status, 0x18 }, + { eoi,0x24 }, + { intr0_stat, 0x30 }, + { intr1_stat, 0x34 }, + { intr0_set, 0x38 }, + { intr1_set, 0x3c }, + { txmode, 0x70 }, + { rxmode, 0x74 }, + { autoreq,0xd0 }, + { srpfixtime, 0xd4 }, + { tdown, 0xd8 }, + { phy_utmi, 0xe0 }, + { mode, 0xe8 }, + { }/* Terminating Entry */ +}; + +static int musb_regdump_show(struct seq_file *s, void *unused) +{ + struct musb *musb = s-private; + unsignedi; + + seq_puts(s, MUSB (M)HDRC dsps Register Dump\n); + + for (i = 0; i ARRAY_SIZE(musb_regmap); i++) { + u32 val = musb_readl(musb-ctrl_base, musb_regmap[i].offset); + seq_printf(s, %-12s: %08x\n, musb_regmap[i].name, val); + } + + return 0; +} + +static int musb_regdump_open(struct inode *inode, struct file *file) +{ + return single_open(file, musb_regdump_show, inode-i_private); +} + +static const struct file_operations musb_regdump_fops = { + .open = musb_regdump_open, + .read = seq_read, + .llseek = seq_lseek, + .release= single_release, +}; + +#endif /* IS_ENABLED(CONFIG_DEBUG_FS) */ + /** * dsps_musb_enable - enable interrupts */ @@ -348,6 +405,31 @@ out: return ret; } +#if IS_ENABLED(CONFIG_DEBUG_FS) +static int dsps_musb_dbg_init(struct musb *musb) +{ + struct dentry *root; + struct dentry *file; + char buf[128]; + + sprintf(buf, %s.dsps, dev_name(musb-controller)); + root = debugfs_create_dir(buf, NULL); + if (!root) + return -ENOMEM; + + file = debugfs_create_file(regdump, S_IRUGO, root, musb, + musb_regdump_fops); + if (!file) + return -ENOMEM; + return 0; +} +#else +static int dsps_musb_dbg_init(struct musb *musb) +{ + return 0; +} +#endif + static int dsps_musb_init(struct musb *musb) { struct device *dev = musb-controller; @@ -357,6 +439,7 @@ static int dsps_musb_init(struct musb *musb) void __iomem *reg_base; struct resource *r; u32 rev, val; + int ret; r = platform_get_resource_byname(parent, IORESOURCE_MEM, control); if (!r) @@ -390,6 +473,12 @@ static int dsps_musb_init(struct musb *musb) val = ~(1 wrp-otg_disable); dsps_writel(musb-ctrl_base, wrp-phy_utmi, val); + ret = dsps_musb_dbg_init(musb); + if (ret) + return ret; + + dev_info(dev, %s:%d %s: OK\n, __FILE__, __LINE__, __func__); + return 0; } -- 1.8.4.rc3 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 1/3] usb: musb: Handle nullpointer
When the device is connected to a host without a gadget driver, otg-gadget is NULL. Signed-off-by: Markus Pargmann m...@pengutronix.de --- drivers/usb/musb/musb_core.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index 18e877f..baa4f6a 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -654,7 +654,8 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb, break; case OTG_STATE_B_PERIPHERAL: musb_g_suspend(musb); - musb-is_active = otg-gadget-b_hnp_enable; + musb-is_active = otg-gadget + otg-gadget-b_hnp_enable; if (musb-is_active) { musb-xceiv-state = OTG_STATE_B_WAIT_ACON; dev_dbg(musb-controller, HNP: Setting timer for b_ase0_brst\n); -- 1.8.4.rc3 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[RFC] usb: musb: dsps, OTG detection
The USB Controller does not support ID pin change interrupts. So we have to use a polling function to detect changes of A/B device state (otg_timer). This poll function has to check in several states if a other device type might be connected to the USB port. This check is triggered by manually starting/stopping a USB Session. So in A mode, we cancel the currently running session which also disables the possibility to detect new devices via interrupt. In B mode, we start a session to check for ID-Pin and possibly connected devices. Whenever a real USB session ends, we have to trigger the otg_timer poll function again. Signed-off-by: Markus Pargmann m...@pengutronix.de --- drivers/usb/musb/musb_dsps.c | 84 1 file changed, 78 insertions(+), 6 deletions(-) diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c index b24b697..0245e8d 100644 --- a/drivers/usb/musb/musb_dsps.c +++ b/drivers/usb/musb/musb_dsps.c @@ -178,6 +178,43 @@ static const struct file_operations musb_regdump_fops = { #endif /* IS_ENABLED(CONFIG_DEBUG_FS) */ +/* + * Compare driver and hardware mode and update driver state if necessary. + * Not all hardware changes actually reach the driver through interrupts. + */ +static void dsps_update_mode(struct musb *musb) +{ + u8 devctl; + + devctl = dsps_readb(musb-mregs, MUSB_DEVCTL); + + switch (musb-xceiv-state) { + case OTG_STATE_A_IDLE: + if (devctl MUSB_DEVCTL_BDEVICE) { + dev_dbg(musb-controller, detected controller state B, software state A\n); + musb-xceiv-state = OTG_STATE_B_IDLE; + } + break; + case OTG_STATE_B_IDLE: + if (!(devctl MUSB_DEVCTL_BDEVICE)) { + dev_dbg(musb-controller, detected controller state A, software state B\n); + musb-xceiv-state = OTG_STATE_A_IDLE; + } + break; + default: + if (!(devctl MUSB_DEVCTL_SESSION)) { + dev_dbg(musb-controller, detected controller out of session (%x), software state %s\n, + devctl, + usb_otg_state_string(musb-xceiv-state)); + if (devctl MUSB_DEVCTL_BDEVICE) + musb-xceiv-state = OTG_STATE_B_IDLE; + else + musb-xceiv-state = OTG_STATE_A_IDLE; + } + break; + } +} + /** * dsps_musb_enable - enable interrupts */ @@ -229,6 +266,8 @@ static void otg_timer(unsigned long _musb) u8 devctl; unsigned long flags; + dsps_update_mode(musb); + /* * We poll because DSPS IP's won't expose several OTG-critical * status change events (from the transceiver) otherwise. @@ -239,6 +278,16 @@ static void otg_timer(unsigned long _musb) spin_lock_irqsave(musb-lock, flags); switch (musb-xceiv-state) { + case OTG_STATE_A_IDLE: + case OTG_STATE_A_WAIT_VRISE: + /* +* Poll the devctl register to know when the controller switches +* back to B state. +*/ + musb_writeb(mregs, MUSB_DEVCTL, + devctl (~MUSB_DEVCTL_SESSION)); + mod_timer(glue-timer, jiffies + wrp-poll_seconds * HZ); + break; case OTG_STATE_A_WAIT_BCON: devctl = ~MUSB_DEVCTL_SESSION; dsps_writeb(musb-mregs, MUSB_DEVCTL, devctl); @@ -251,6 +300,8 @@ static void otg_timer(unsigned long _musb) musb-xceiv-state = OTG_STATE_A_IDLE; MUSB_HST_MODE(musb); } + mod_timer(glue-timer, + jiffies + wrp-poll_seconds * HZ); break; case OTG_STATE_A_WAIT_VFALL: musb-xceiv-state = OTG_STATE_A_WAIT_VRISE; @@ -258,12 +309,24 @@ static void otg_timer(unsigned long _musb) MUSB_INTR_VBUSERROR wrp-usb_shift); break; case OTG_STATE_B_IDLE: + /* +* There's no ID-changed IRQ, so we have no good way to tell +* when to switch to the A-Default state machine (by setting +* the DEVCTL.Session bit). +* +* Workaround: whenever we're in B_IDLE, try setting the +* session flag every few seconds. If it works, ID was +* grounded and we're now in the A-Default state machine. +* +* NOTE: setting the session flag is _supposed_ to trigger +* SRP but clearly it doesn't. +*/ + musb_writeb(mregs, MUSB_DEVCTL, devctl | MUSB_DEVCTL_SESSION); devctl = dsps_readb(mregs, MUSB_DEVCTL
[PATCH v2 1/3] usb: musb: Handle nullpointer
When the device is connected to a host without a gadget driver, otg-gadget is NULL. Signed-off-by: Markus Pargmann m...@pengutronix.de --- drivers/usb/musb/musb_core.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index 18e877f..baa4f6a 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -654,7 +654,8 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb, break; case OTG_STATE_B_PERIPHERAL: musb_g_suspend(musb); - musb-is_active = otg-gadget-b_hnp_enable; + musb-is_active = otg-gadget + otg-gadget-b_hnp_enable; if (musb-is_active) { musb-xceiv-state = OTG_STATE_B_WAIT_ACON; dev_dbg(musb-controller, HNP: Setting timer for b_ase0_brst\n); -- 1.8.4.rc3 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 0/3] usb: musb bugfixes
Hi, the series contains two bugfixes and some debugfs file operations for dsps similar to the musb core regdump debugfs file. v2 removes the dev_info() in patch 3 in dsps_musb_init. Regards, Markus Pargmann Markus Pargmann (3): usb: musb: Handle nullpointer usb: musb: Bugfix of_node assignment usb: musb: dsps, debugfs files drivers/usb/musb/musb_core.c | 15 +++- drivers/usb/musb/musb_dsps.c | 88 +++- 2 files changed, 100 insertions(+), 3 deletions(-) -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 2/3] usb: musb: Bugfix of_node assignment
It is not safe to assign the of_node to a device without driver. The device is matched against a list of drivers and the of_node could lead to a DT match with the parent driver. Signed-off-by: Markus Pargmann m...@pengutronix.de --- drivers/usb/musb/musb_core.c | 12 +++- drivers/usb/musb/musb_dsps.c | 1 - 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index baa4f6a..a26eccd 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -1962,6 +1962,7 @@ static int musb_probe(struct platform_device *pdev) int irq = platform_get_irq_byname(pdev, mc); struct resource *iomem; void __iomem*base; + int ret; iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!iomem || irq = 0) @@ -1971,7 +1972,16 @@ static int musb_probe(struct platform_device *pdev) if (IS_ERR(base)) return PTR_ERR(base); - return musb_init_controller(dev, irq, base); + if (dev-parent) + dev-of_node = dev-parent-of_node; + + ret = musb_init_controller(dev, irq, base); + if (ret) { + dev-of_node = NULL; + return ret; + } + + return 0; } static int musb_remove(struct platform_device *pdev) diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c index bd4138d..189e52c 100644 --- a/drivers/usb/musb/musb_dsps.c +++ b/drivers/usb/musb/musb_dsps.c @@ -483,7 +483,6 @@ static int dsps_create_musb_pdev(struct dsps_glue *glue, musb-dev.parent= dev; musb-dev.dma_mask = musb_dmamask; musb-dev.coherent_dma_mask = musb_dmamask; - musb-dev.of_node = of_node_get(dn); glue-musb = musb; -- 1.8.4.rc3 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 3/3] usb: musb: dsps, debugfs files
debugfs files to show the contents of important dsps registers. Signed-off-by: Markus Pargmann m...@pengutronix.de --- drivers/usb/musb/musb_dsps.c | 87 1 file changed, 87 insertions(+) diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c index 189e52c..43b22ab 100644 --- a/drivers/usb/musb/musb_dsps.c +++ b/drivers/usb/musb/musb_dsps.c @@ -46,6 +46,8 @@ #include linux/of_irq.h #include linux/usb/of.h +#include linux/debugfs.h + #include musb_core.h static const struct of_device_id musb_dsps_of_match[]; @@ -121,6 +123,61 @@ struct dsps_glue { unsigned long last_timer;/* last timer data for each instance */ }; +#if IS_ENABLED(CONFIG_DEBUG_FS) + +struct musb_register_map { + char*name; + unsignedoffset; +}; + +static const struct musb_register_map musb_regmap[] = { + { revision, 0x00 }, + { control,0x14 }, + { status, 0x18 }, + { eoi,0x24 }, + { intr0_stat, 0x30 }, + { intr1_stat, 0x34 }, + { intr0_set, 0x38 }, + { intr1_set, 0x3c }, + { txmode, 0x70 }, + { rxmode, 0x74 }, + { autoreq,0xd0 }, + { srpfixtime, 0xd4 }, + { tdown, 0xd8 }, + { phy_utmi, 0xe0 }, + { mode, 0xe8 }, + { }/* Terminating Entry */ +}; + +static int musb_regdump_show(struct seq_file *s, void *unused) +{ + struct musb *musb = s-private; + unsignedi; + + seq_puts(s, MUSB (M)HDRC dsps Register Dump\n); + + for (i = 0; i ARRAY_SIZE(musb_regmap); i++) { + u32 val = musb_readl(musb-ctrl_base, musb_regmap[i].offset); + seq_printf(s, %-12s: %08x\n, musb_regmap[i].name, val); + } + + return 0; +} + +static int musb_regdump_open(struct inode *inode, struct file *file) +{ + return single_open(file, musb_regdump_show, inode-i_private); +} + +static const struct file_operations musb_regdump_fops = { + .open = musb_regdump_open, + .read = seq_read, + .llseek = seq_lseek, + .release= single_release, +}; + +#endif /* IS_ENABLED(CONFIG_DEBUG_FS) */ + /** * dsps_musb_enable - enable interrupts */ @@ -348,6 +405,31 @@ out: return ret; } +#if IS_ENABLED(CONFIG_DEBUG_FS) +static int dsps_musb_dbg_init(struct musb *musb) +{ + struct dentry *root; + struct dentry *file; + char buf[128]; + + sprintf(buf, %s.dsps, dev_name(musb-controller)); + root = debugfs_create_dir(buf, NULL); + if (!root) + return -ENOMEM; + + file = debugfs_create_file(regdump, S_IRUGO, root, musb, + musb_regdump_fops); + if (!file) + return -ENOMEM; + return 0; +} +#else +static int dsps_musb_dbg_init(struct musb *musb) +{ + return 0; +} +#endif + static int dsps_musb_init(struct musb *musb) { struct device *dev = musb-controller; @@ -357,6 +439,7 @@ static int dsps_musb_init(struct musb *musb) void __iomem *reg_base; struct resource *r; u32 rev, val; + int ret; r = platform_get_resource_byname(parent, IORESOURCE_MEM, control); if (!r) @@ -390,6 +473,10 @@ static int dsps_musb_init(struct musb *musb) val = ~(1 wrp-otg_disable); dsps_writel(musb-ctrl_base, wrp-phy_utmi, val); + ret = dsps_musb_dbg_init(musb); + if (ret) + return ret; + return 0; } -- 1.8.4.rc3 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RFC] usb: musb: dsps, OTG detection
Hi, On Mon, Oct 14, 2013 at 08:54:09AM -0500, Bin Liu wrote: On Mon, Oct 14, 2013 at 8:35 AM, Markus Pargmann m...@pengutronix.de wrote: The USB Controller does not support ID pin change interrupts. So we have to use a polling function to detect changes of A/B device state (otg_timer). This poll function has to check in several states if a other device type might be connected to the USB port. This check is triggered by manually starting/stopping a USB Session. I think this is an arguable approach. Toggling the SESSION in otg_timer() causes voltage pulses on VBUS, which will not pass the USB certification. This is only done when no device is connected, so I am not sure if it is important. Unfortunately we do not see the A/B state changes until toggling the SESSION. Is there another way to check this? I have not seen any products required the dynamic dual role switching yet. It always fixed in either device mode or host mode. OTG is explicitly listed in the devicetree bindings documentation, so I think the driver should be able to detect different roles. Regards, Markus Pargmann Regards, -Bin. So in A mode, we cancel the currently running session which also disables the possibility to detect new devices via interrupt. In B mode, we start a session to check for ID-Pin and possibly connected devices. Whenever a real USB session ends, we have to trigger the otg_timer poll function again. Signed-off-by: Markus Pargmann m...@pengutronix.de --- drivers/usb/musb/musb_dsps.c | 84 1 file changed, 78 insertions(+), 6 deletions(-) diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c index b24b697..0245e8d 100644 --- a/drivers/usb/musb/musb_dsps.c +++ b/drivers/usb/musb/musb_dsps.c @@ -178,6 +178,43 @@ static const struct file_operations musb_regdump_fops = { #endif /* IS_ENABLED(CONFIG_DEBUG_FS) */ +/* + * Compare driver and hardware mode and update driver state if necessary. + * Not all hardware changes actually reach the driver through interrupts. + */ +static void dsps_update_mode(struct musb *musb) +{ + u8 devctl; + + devctl = dsps_readb(musb-mregs, MUSB_DEVCTL); + + switch (musb-xceiv-state) { + case OTG_STATE_A_IDLE: + if (devctl MUSB_DEVCTL_BDEVICE) { + dev_dbg(musb-controller, detected controller state B, software state A\n); + musb-xceiv-state = OTG_STATE_B_IDLE; + } + break; + case OTG_STATE_B_IDLE: + if (!(devctl MUSB_DEVCTL_BDEVICE)) { + dev_dbg(musb-controller, detected controller state A, software state B\n); + musb-xceiv-state = OTG_STATE_A_IDLE; + } + break; + default: + if (!(devctl MUSB_DEVCTL_SESSION)) { + dev_dbg(musb-controller, detected controller out of session (%x), software state %s\n, + devctl, + usb_otg_state_string(musb-xceiv-state)); + if (devctl MUSB_DEVCTL_BDEVICE) + musb-xceiv-state = OTG_STATE_B_IDLE; + else + musb-xceiv-state = OTG_STATE_A_IDLE; + } + break; + } +} + /** * dsps_musb_enable - enable interrupts */ @@ -229,6 +266,8 @@ static void otg_timer(unsigned long _musb) u8 devctl; unsigned long flags; + dsps_update_mode(musb); + /* * We poll because DSPS IP's won't expose several OTG-critical * status change events (from the transceiver) otherwise. @@ -239,6 +278,16 @@ static void otg_timer(unsigned long _musb) spin_lock_irqsave(musb-lock, flags); switch (musb-xceiv-state) { + case OTG_STATE_A_IDLE: + case OTG_STATE_A_WAIT_VRISE: + /* +* Poll the devctl register to know when the controller switches +* back to B state. +*/ + musb_writeb(mregs, MUSB_DEVCTL, + devctl (~MUSB_DEVCTL_SESSION)); + mod_timer(glue-timer, jiffies + wrp-poll_seconds * HZ); + break; case OTG_STATE_A_WAIT_BCON: devctl = ~MUSB_DEVCTL_SESSION; dsps_writeb(musb-mregs, MUSB_DEVCTL, devctl); @@ -251,6 +300,8 @@ static void otg_timer(unsigned long _musb) musb-xceiv-state = OTG_STATE_A_IDLE; MUSB_HST_MODE(musb); } + mod_timer(glue-timer, + jiffies + wrp-poll_seconds * HZ); break; case