am33x: multiple instances and dma support, v2
Subsystems (5)
Hello,
this series contains support for the two available MUSB instances on AM335x and DMA support. I added dma support at the end since it depends on the rework to support multiple instances.
Patch two "still" extends the phy-nop driver since I have to dump it somewhere. I have no problems to replace it with George Cherian PHY driver which was posted earlier. Infact I will to try to review it and integrate it into my series if it fits.
The whole series is also available at
git://git.breakpoint.cc/bigeasy/linux.git am335x_usb
Sebastian
PATCH 1/16 usb: musb: dsps: init / shutdown the phy
If the init / shutdown function of the phy moves out of dsps into the phy driver, then dsps needs to call the callbacks of the phy driver to ensure that this happens.
--- drivers/usb/musb/musb_dsps.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/usb/musb/musb_dsps.c +3 -0
@@ -428,6 +428,8 @@ static int dsps_musb_init(struct musb *musb) goto err0; } +usb_phy_init (musb->xceiv); +setup_timer (&glue->timer[pdev->id], otg_timer, (unsigned long ) musb);/* Reset the musb */
@@ -463,6 +465,7 @@ static int dsps_musb_exit(struct musb *musb)/* Shutdown the on-chip PHY and its PLL. */ musb_dsps_phy_control (glue, pdev->id,0 ); +usb_phy_shutdown (musb->xceiv);/* NOP driver needs change if supporting dual instance */ usb_put_phy (musb->xceiv);
Signature · 1 line
1.8.3.2
Re: [PATCH 01/16] usb: musb: dsps: init / shutdown the phy
Quoted 5 lines · Sebastian Andrzej Siewior
If the init / shutdown function of the phy moves out of dsps into the phy driver, then dsps needs to call the callbacks of the phy driver to ensure that this happens.
Signed-off-by Sebastian Andrzej Siewior <[email protected]>
cool, eventually we should move these calls to musb_core.c though.
Signature · 1 line
balbi
PATCH 2/16 usb: phy: phy-nop: add support for am335x PHY
In reply to Sebastian Andrzej SiewiorThe am335x PHY code is well hidden in multiple places. The glue layer uses the nop and does up/down in the background. This patch copies the power on / power off part out of dsps so it can be removed later in dsps. At this point I am not sure if it is better to write a new phy driver for am335x or just add the missing pieces to this one.
--- drivers/usb/phy/phy-nop.c | 114 +++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 102 insertions(+), 12 deletions(-)
drivers/usb/phy/phy-nop.c +102 -12
@@ -35,6 +35,7 @@#include <linux/clk.h> #include <linux/regulator/consumer.h> #include <linux/of.h> +#include <linux/of_address.h> struct nop_usb_xceiv {struct usb_phy phy;
@@ -42,6 +43,14 @@ struct nop_usb_xceiv {struct clk *clk;struct regulator *vcc;struct regulator *reset; + +void __iomem *priv_reg; +}; + +struct phy_data { +int (*phy_init)(struct usb_phy *x); +void (*phy_shutdown)(struct usb_phy *x); +int (*reg_init)(struct platform_device *pdev); };static struct platform_device *pd;
@@ -139,10 +148,85 @@ static int nop_set_host(struct usb_otg *otg, struct usb_bus *host)return 0 ; } +static int am335x_reg_init (struct platform_device *pdev) +{ +struct device_node *node = pdev->dev.of_node; +struct nop_usb_xceiv *nop; +struct resource res; +int ret; + + nop =platform_get_drvdata (pdev); + ret =of_address_to_resource (node,0 , &res); +if (ret) +return ret; + + nop->priv_reg =devm_request_and_ioremap (&pdev->dev, &res); +if (!nop->priv_reg) +return -EINVAL ; +return 0 ; +} + +#define AM335X_USB_CTRL 0x00 +#define AM335x_USB_STS 0x04 + +#define USBPHY_CM_PWRDN (1 << 0) +#define USBPHY_OTG_PWRDN (1 << 1) +#define USBPHY_OTGVDET_EN (1 << 19) +#define USBPHY_OTGSESSEND_EN (1 << 20) + +static void am335x_phy_power (struct nop_usb_xceiv *nop,bool on) +{ +u32 val; + + val =readl (nop->priv_reg); +if (on) { + val &= ~(USBPHY_CM_PWRDN |USBPHY_OTG_PWRDN ); + val |=USBPHY_OTGVDET_EN |USBPHY_OTGSESSEND_EN ; + }else { + val |=USBPHY_CM_PWRDN |USBPHY_OTG_PWRDN ; + } + +writel (val, nop->priv_reg); +} + +static int am335x_phy_init (struct usb_phy *phy) +{ +struct nop_usb_xceiv *nop =dev_get_drvdata (phy->dev); +int ret; + + ret =nop_init (phy); +if (ret) +return ret; +am335x_phy_power (nop, true); +return 0 ; +} + +static void am335x_phy_shutdown (struct usb_phy *phy) +{ +struct nop_usb_xceiv *nop =dev_get_drvdata (phy->dev); + +am335x_phy_power (nop, false); +nop_shutdown (phy); +} + +struct phy_data am335x_phy_data = { + .reg_init = am335x_reg_init, + .phy_init = am335x_phy_init, + .phy_shutdown = am335x_phy_shutdown, +}; + +static const struct of_device_id nop_xceiv_dt_ids[] = { + { .compatible ="usb-nop-xceiv" }, + { .compatible ="ti,am335x-usb-phy" , .data = &am335x_phy_data }, + { } +}; +MODULE_DEVICE_TABLE (of, nop_xceiv_dt_ids); +static int nop_usb_xceiv_probe (struct platform_device *pdev) {struct device *dev = &pdev->dev;struct nop_usb_xceiv_platform_data *pdata = pdev->dev.platform_data; +const struct phy_data *phy_data =NULL ;struct nop_usb_xceiv *nop;enum usb_phy_type type =USB_PHY_TYPE_USB2 ;int err;
@@ -154,6 +238,7 @@ static int nop_usb_xceiv_probe(struct platform_device *pdev)if (!nop)return -ENOMEM ; +platform_set_drvdata (pdev, nop); nop->phy.otg =devm_kzalloc (&pdev->dev,sizeof (*nop->phy.otg),GFP_KERNEL );if (!nop->phy.otg)
@@ -161,13 +246,20 @@ static int nop_usb_xceiv_probe(struct platform_device *pdev)if (dev->of_node) {struct device_node *node = dev->of_node; +const struct of_device_id *of_id;if (of_property_read_u32 (node,"clock-frequency" , &clk_rate)) clk_rate =0 ; needs_vcc =of_property_read_bool (node,"vcc-supply" ); needs_reset =of_property_read_bool (node,"reset-supply" ); - + of_id =of_match_node (nop_xceiv_dt_ids, node); +if (of_id) { + phy_data = of_id->data; + err = phy_data->reg_init (pdev); +if (err) +return err; + } }else if (pdata) { type = pdata->type; clk_rate = pdata->clk_rate;
@@ -217,8 +309,15 @@ static int nop_usb_xceiv_probe(struct platform_device *pdev) nop->phy.dev = nop->dev; nop->phy.label ="nop-xceiv" ; nop->phy.set_suspend = nop_set_suspend; - nop->phy.init = nop_init; - nop->phy.shutdown = nop_shutdown; +if (phy_data && phy_data->phy_init) + nop->phy.init = phy_data->phy_init; +else + nop->phy.init = nop_init; + +if (phy_data && phy_data->phy_shutdown) + nop->phy.shutdown = phy_data->phy_shutdown; +else + nop->phy.shutdown = nop_shutdown; nop->phy.state =OTG_STATE_UNDEFINED ; nop->phy.type = type;
@@ -233,8 +332,6 @@ static int nop_usb_xceiv_probe(struct platform_device *pdev) goto err_add; } -platform_set_drvdata (pdev, nop); -ATOMIC_INIT_NOTIFIER_HEAD (&nop->phy.notifier);return 0 ;
@@ -257,13 +354,6 @@ static int nop_usb_xceiv_remove(struct platform_device *pdev)return 0 ; } -static const struct of_device_id nop_xceiv_dt_ids[] = { - { .compatible ="usb-nop-xceiv" }, - { } -}; - -MODULE_DEVICE_TABLE (of, nop_xceiv_dt_ids); -static struct platform_driver nop_usb_xceiv_driver = { .probe = nop_usb_xceiv_probe, .remove = nop_usb_xceiv_remove,
Signature · 1 line
1.8.3.2
Re: [PATCH 02/16] usb: phy: phy-nop: add support for am335x PHY
Quoted 7 lines · Sebastian Andrzej Siewior
The am335x PHY code is well hidden in multiple places. The glue layer uses the nop and does up/down in the background. This patch copies the power on / power off part out of dsps so it can be removed later in dsps. At this point I am not sure if it is better to write a new phy driver for am335x or just add the missing pieces to this one.
Signed-off-by Sebastian Andrzej Siewior <[email protected]>
right, I replied to the wrong series, please add a patch renaming file and functions to phy-generic.c/usb_phy_gen_
or something similar.
Signature · 1 line
balbi
Re: [PATCH 02/16] usb: phy: phy-nop: add support for am335x PHY
Quoted 3 lines · * Felipe Balbi | 2013-07-25 17:33:30 [+0300]:
On Mon, Jul 22, 2013 at 08:09:53PM +0200, Sebastian Andrzej Siewior wrote:
right, I replied to the wrong series, please add a patch renaming file and functions to phy-generic.c/usb_phy_gen_
Sorry, I can't parse that.
You want to rename phy-nop.c to phy-generic.c and add the additional functions in usb_phy_gen.c?
Quoted 1 line
or something similar.
Sebastian
Re: [PATCH 02/16] usb: phy: phy-nop: add support for am335x PHY
Quoted 9 lines · Sebastian Andrzej Siewior
Quoted 3 lines · * Felipe Balbi | 2013-07-25 17:33:30 [+0300]:
On Mon, Jul 22, 2013 at 08:09:53PM +0200, Sebastian Andrzej Siewior wrote:
right, I replied to the wrong series, please add a patch renaming file and functions to phy-generic.c/usb_phy_gen_Sorry, I can't parse that.
You want to renamephy-nop.ctophy-generic.cand add the additional functions inusb_phy_gen.c?
$ git mv drivers/usb/phy/phy-nop.c drivers/usb/phy/phy-generic.c $ sed -i 's/\<nop_/usb_phy_gen_/g' drivers/usb/phy/phy-generic.c
Signature · 1 line
balbi
PATCH 3/16 usb: musb: dsps: remove the hardcoded phy pieces
In reply to Sebastian Andrzej Siewiordsps uses a nop driver which is added in dsps itself and does the PHY on/off calls within dsps. Since those calls are now moved the nop driver itself, we can now request the phy proper phy and remove those calls. Currently only the first musb interface is used so we only add one phy node for now.
--- drivers/usb/musb/musb_dsps.c | 97 +------------------------------------------- 1 file changed, 1 insertion(+), 96 deletions(-)
drivers/usb/musb/musb_dsps.c +1 -96
@@ -123,49 +123,8 @@ struct dsps_glue {const struct dsps_musb_wrapper *wrp;/* wrapper register offsets */ struct timer_list timer[2 ];/* otg_workaround timer */ unsigned long last_timer[2 ];/* last timer data for each instance */ -u32 __iomem *usb_ctrl[2 ]; }; -#define DSPS_AM33XX_CONTROL_MODULE_PHYS_0 0x44e10620 -#define DSPS_AM33XX_CONTROL_MODULE_PHYS_1 0x44e10628 - -static const resource_size_t dsps_control_module_phys[] = { -DSPS_AM33XX_CONTROL_MODULE_PHYS_0 , -DSPS_AM33XX_CONTROL_MODULE_PHYS_1 , -}; - -#define USBPHY_CM_PWRDN (1 << 0) -#define USBPHY_OTG_PWRDN (1 << 1) -#define USBPHY_OTGVDET_EN (1 << 19) -#define USBPHY_OTGSESSEND_EN (1 << 20) - -/** -* musb_dsps_phy_control - phy on/off -* @glue: struct dsps_glue * -* @id: musb instance -* @on: flag for phy to be switched on or off -* -* This is to enable the PHY using usb_ctrl register in system control -* module space. -* -* XXX: This function will be removed once we have a seperate driver for -* control module -*/ -static void musb_dsps_phy_control (struct dsps_glue *glue,u8 id,u8 on) -{ -u32 usbphycfg; - - usbphycfg =readl (glue->usb_ctrl[id]); - -if (on) { - usbphycfg &= ~(USBPHY_CM_PWRDN |USBPHY_OTG_PWRDN ); - usbphycfg |=USBPHY_OTGVDET_EN |USBPHY_OTGSESSEND_EN ; - }else { - usbphycfg |=USBPHY_CM_PWRDN |USBPHY_OTG_PWRDN ; - } - -writel (usbphycfg, glue->usb_ctrl[id]); -}/** * dsps_musb_enable - enable interrupts */
@@ -416,8 +375,7 @@ static int dsps_musb_init(struct musb *musb) musb->mregs += wrp->musb_core_offset;/* NOP driver needs change if supporting dual instance */ -usb_nop_xceiv_register (); - musb->xceiv =usb_get_phy (USB_PHY_TYPE_USB2 ); + musb->xceiv =devm_usb_get_phy_by_phandle (glue->dev,"phys" ,0 );if (IS_ERR_OR_NULL (musb->xceiv))return -EPROBE_DEFER ;
@@ -435,9 +393,6 @@ static int dsps_musb_init(struct musb *musb)/* Reset the musb */ dsps_writel (reg_base, wrp->control, (1 << wrp->reset)); -/* Start the on-chip PHY and its PLL. */ -musb_dsps_phy_control (glue, pdev->id,1 ); - musb->isr = dsps_interrupt;/* reset the otgdisable bit, needed for host mode to work */
@@ -450,8 +405,6 @@ static int dsps_musb_init(struct musb *musb)return 0 ; err0: -usb_put_phy (musb->xceiv); -usb_nop_xceiv_unregister ();return status; }
@@ -463,14 +416,7 @@ static int dsps_musb_exit(struct musb *musb)del_timer_sync (&glue->timer[pdev->id]); -/* Shutdown the on-chip PHY and its PLL. */ -musb_dsps_phy_control (glue, pdev->id,0 );usb_phy_shutdown (musb->xceiv); - -/* NOP driver needs change if supporting dual instance */ -usb_put_phy (musb->xceiv); -usb_nop_xceiv_unregister (); -return 0 ; }
@@ -499,16 +445,6 @@ static int dsps_create_musb_pdev(struct dsps_glue *glue, u8 id)char res_name[11 ];int ret; - resources[0 ].start = dsps_control_module_phys[id]; - resources[0 ].end = resources[0 ].start +SZ_4 -1 ; - resources[0 ].flags =IORESOURCE_MEM ; - - glue->usb_ctrl[id] =devm_ioremap_resource (&pdev->dev, resources); -if (IS_ERR (glue->usb_ctrl[id])) { - ret =PTR_ERR (glue->usb_ctrl[id]); - goto err0; - } -/* first resource is for usbss, so start index from 1 */ res =platform_get_resource (pdev,IORESOURCE_MEM , id +1 );if (!res) {
@@ -692,36 +628,6 @@ static int dsps_remove(struct platform_device *pdev)return 0 ; } -#ifdef CONFIG_PM_SLEEP -static int dsps_suspend (struct device *dev) -{ -struct platform_device *pdev =to_platform_device (dev->parent); -struct dsps_glue *glue =platform_get_drvdata (pdev); -const struct dsps_musb_wrapper *wrp = glue->wrp; -int i; - -for (i =0 ; i < wrp->instances; i++) -musb_dsps_phy_control (glue, i,0 ); - -return 0 ; -} - -static int dsps_resume (struct device *dev) -{ -struct platform_device *pdev =to_platform_device (dev->parent); -struct dsps_glue *glue =platform_get_drvdata (pdev); -const struct dsps_musb_wrapper *wrp = glue->wrp; -int i; - -for (i =0 ; i < wrp->instances; i++) -musb_dsps_phy_control (glue, i,1 ); - -return 0 ; -} -#endif - -static SIMPLE_DEV_PM_OPS(dsps_pm_ops, dsps_suspend, dsps_resume); -static const struct dsps_musb_wrapper ti81xx_driver_data = { .revision =0x00 , .control =0x14 ,
@@ -776,7 +682,6 @@ static struct platform_driver dsps_usbss_driver = { .remove = dsps_remove, .driver = { .name = "musb-dsps", - .pm = &dsps_pm_ops, .of_match_table = of_match_ptr(musb_dsps_of_match), }, .id_table = musb_dsps_id_table,
Signature · 1 line
1.8.3.2
PATCH 4/16 usb: musb: remove ti81xx pieces from musb
In reply to Sebastian Andrzej Siewiorti81xx does not have a baseport mainline i.e. it should not boot. The amount of rework that is required makes it easier to simply remove that platform (i.e. that possible platform device) and add it later once it comes back with DT support.
--- drivers/usb/musb/musb_dsps.c | 14 -------------- 1 file changed, 14 deletions(-)
drivers/usb/musb/musb_dsps.c +0 -14
@@ -46,9 +46,7 @@#include "musb_core.h" -#ifdef CONFIG_OF static const struct of_device_id musb_dsps_of_match[]; -#endif /** * avoid using musb_readx()/musb_writex() as glue layer should not be
@@ -659,23 +657,12 @@ static const struct dsps_musb_wrapper ti81xx_driver_data = { .instances = 1, }; -static const struct platform_device_id musb_dsps_id_table[] = { - { - .name ="musb-ti81xx" , - .driver_data = (kernel_ulong_t) &ti81xx_driver_data, - }, - { },/* Terminating Entry */ -}; -MODULE_DEVICE_TABLE (platform, musb_dsps_id_table); - -#ifdef CONFIG_OF static const struct of_device_id musb_dsps_of_match[] = { { .compatible ="ti,musb-am33xx" , .data = (void *) &ti81xx_driver_data, }, { }, };MODULE_DEVICE_TABLE (of, musb_dsps_of_match); -#endif static struct platform_driver dsps_usbss_driver = { .probe = dsps_probe,
@@ -684,7 +671,6 @@ static struct platform_driver dsps_usbss_driver = { .name = "musb-dsps", .of_match_table = of_match_ptr(musb_dsps_of_match), }, - .id_table = musb_dsps_id_table, };MODULE_DESCRIPTION ("TI DSPS MUSB Glue Layer" );
Signature · 1 line
1.8.3.2
PATCH 5/16 usb: musb: dsps: use proper child nodes
In reply to Sebastian Andrzej SiewiorThis moves the two instances from the big node into two child nodes. The glue layer ontop does almost nothing.
There is one devices containing the (2) phy, (2) usb and later the dma engine. The usb device is the "glue device" which contains the musb device as a child. This is what we do ever since.
The new file musb_am335x is just here to prob the new bus and populate child devices.
There are a lot of changes to the dsps file as a result of the changes:
- musb_core_offset
This is gone. The device tree provides memory ressources information for the device there is no need to "fix" things
- instances
This is gone as well. If we have two instances then we have have two child enabled nodes in the device tree. For instance the SoC in beagle bone has two USB instances but only one has been wired up so there is no need to load and init the second instance since it won't be used.
- dsps_glue is now per glue device
In the past there was one of this structs but with an array of two and each instance accessed its variable depending on the platform device id.
- no unneeded copy of structs
I do not know why struct dsps_musb_wrapper is copied but it is not necessary. The same goes for musb_hdrc_platform_data which allocated on demand and then again by platform_device_add_data(). One copy is enough.
--- arch/arm/boot/dts/am335x-bone.dts | 12 ++ arch/arm/boot/dts/am335x-evm.dts | 20 +++ arch/arm/boot/dts/am335x-evmsk.dts | 12 ++ arch/arm/boot/dts/am33xx.dtsi | 89 +++++++++++-- drivers/usb/musb/Kconfig | 4 + drivers/usb/musb/Makefile | 3 + drivers/usb/musb/musb_am335x.c | 55 ++++++++ drivers/usb/musb/musb_dsps.c | 255 ++++++++++++++----------------------- 8 files changed, 279 insertions(+), 171 deletions(-) create mode 100644 drivers/usb/musb/musb_am335x.c
arch/arm/boot/dts/am335x-bone.dts +12 -0
@@ -120,6 +120,18 @@ status = "okay"; }; + musb: usb@47400000 { + status = "okay"; + + phy@47401300 { + status = "okay"; + }; + + usb@47401000 { + status = "okay"; + }; + }; + i2c0: i2c@44e0b000 { pinctrl-names = "default"; pinctrl-0 = <&i2c0_pins>;
arch/arm/boot/dts/am335x-evm.dts +20 -0
@@ -171,6 +171,26 @@ }; }; + musb: usb@47400000 { + status = "okay"; + + phy@47401300 { + status = "okay"; + }; + + phy@47401b00 { + status = "okay"; + }; + + usb@47401000 { + status = "no"; + }; + + usb@47401800 { + status = "okay"; + }; + }; + i2c1: i2c@4802a000 { pinctrl-names = "default"; pinctrl-0 = <&i2c1_pins>;
arch/arm/boot/dts/am335x-evmsk.dts +12 -0
@@ -207,6 +207,18 @@ }; }; + musb: usb@47400000 { + status = "okay"; + + phy@47401300 { + status = "okay"; + }; + + usb@47401000 { + status = "okay"; + }; + }; + epwmss2: epwmss@48304000 { status = "okay";
arch/arm/boot/dts/am33xx.dtsi +75 -14
102 lines not on this page · raw message
drivers/usb/musb/Kconfig +4 -0
@@ -83,6 +83,7 @@ config USB_MUSB_AM35X config USB_MUSB_DSPS tristate "TI DSPS platforms" + select USB_MUSB_AM335X_CHILD config USB_MUSB_BLACKFIN tristate "Blackfin"
@@ -93,6 +94,9 @@ config USB_MUSB_UX500 endchoice +config USB_MUSB_AM335X_CHILD + tristate + choice prompt 'MUSB DMA mode' default MUSB_PIO_ONLY if ARCH_MULTIPLATFORM
drivers/usb/musb/Makefile +3 -0
@@ -20,6 +20,9 @@ obj-$(CONFIG_USB_MUSB_DA8XX) += da8xx.o obj-$(CONFIG_USB_MUSB_BLACKFIN) += blackfin.o obj-$(CONFIG_USB_MUSB_UX500) += ux500.o + +obj-$(CONFIG_USB_MUSB_AM335X_CHILD) += musb_am335x.o + # the kconfig must guarantee that only one of the # possible I/O schemes will be enabled at a time ... # PIO only, or DMA (several potential schemes).
drivers/usb/musb/musb_am335x.c new file +55 -0
55 lines not on this page · raw message
drivers/usb/musb/musb_dsps.c +98 -157
460 lines not on this page · raw message
Signature · 1 line
1.8.3.2
Re: [PATCH 05/16] usb: musb: dsps: use proper child nodes
Quoted 74 lines · Sebastian Andrzej Siewior
This moves the two instances from the big node into two child nodes. The glue layer ontop does almost nothing.
There is one devices containing the (2) phy, (2) usb and later the dma engine. The usb device is the "glue device" which contains the musb device as a child. This is what we do ever since.
The new filemusb_am335xis just here to prob the new bus and populate child devices.
There are a lot of changes to the dsps file as a result of the changes:
-musb_core_offset
This is gone. The device tree provides memory ressources information for the device there is no need to "fix" things
- instances
This is gone as well. If we have two instances then we have have two child enabled nodes in the device tree. For instance the SoC in beagle bone has two USB instances but only one has been wired up so there is no need to load and init the second instance since it won't be used.
-dsps_glueis now per glue device
In the past there was one of this structs but with an array of two and each instance accessed its variable depending on the platform device id.
- no unneeded copy of structs
I do not know why structdsps_musb_wrapperis copied but it is not necessary. The same goes formusb_hdrc_platform_datawhich allocated on demand and then again byplatform_device_add_data(). One copy is enough.Signed-off-by Sebastian Andrzej Siewior <[email protected]>--- arch/arm/boot/dts/am335x-bone.dts | 12 ++ arch/arm/boot/dts/am335x-evm.dts | 20 +++ arch/arm/boot/dts/am335x-evmsk.dts | 12 ++ arch/arm/boot/dts/am33xx.dtsi | 89 +++++++++++-- drivers/usb/musb/Kconfig | 4 + drivers/usb/musb/Makefile | 3 + drivers/usb/musb/musb_am335x.c | 55 ++++++++ drivers/usb/musb/musb_dsps.c | 255 ++++++++++++++----------------------- 8 files changed, 279 insertions(+), 171 deletions(-)create mode 100644
drivers/usb/musb/musb_am335x.carch/arm/boot/dts/am335x-bone.dts +12
-0@@ -120,6 +120,18 @@ status = "okay"; }; + musb: usb@47400000 { + status = "okay"; + + phy@47401300 { + status = "okay"; + }; + + usb@47401000 { + status = "okay"; + }; + }; + i2c0: i2c@44e0b000 { pinctrl-names = "default"; pinctrl-0 = <&i2c0_pins>;arch/arm/boot/dts/am335x-evm.dts +4
-0@@ -171,6 +171,26 @@ }; }; + musb: usb@47400000 { + status = "okay"; + + phy@47401300 {
arch/arm/boot/dts/am335x-evm.dts line 187
Quoted 10 lines
arch/arm/boot/dts/am335x-evm.dts +10
-0+ status = "okay"; + }; + + phy@47401b00 { + status = "okay"; + }; + + usb@47401000 { + status = "no"; + };
Any reason usb0 is disabled for am33xx evm? Just for testing?
Quoted 721 lines
arch/arm/boot/dts/am335x-evm.dts +6
-0+ + usb@47401800 { + status = "okay"; + }; + }; + i2c1: i2c@4802a000 { pinctrl-names = "default"; pinctrl-0 = <&i2c1_pins>;arch/arm/boot/dts/am335x-evmsk.dts +12
-0@@ -207,6 +207,18 @@ }; }; + musb: usb@47400000 { + status = "okay"; + + phy@47401300 { + status = "okay"; + }; + + usb@47401000 { + status = "okay"; + }; + }; + epwmss2: epwmss@48304000 { status = "okay";arch/arm/boot/dts/am33xx.dtsi +75
-14@@ -26,6 +26,10 @@ serial5 = &uart5; d_can0 = &dcan0; d_can1 = &dcan1; + usb0 = &usb0; + usb1 = &usb1; + phy0 = &usb0_phy; + phy1 = &usb1_phy; }; cpus {@@ -333,21 +337,78 @@ status = "disabled"; }; - usb@47400000 { - compatible = "ti,musb-am33xx"; - reg = <0x47400000 0x1000 /* usbss */ - 0x47401000 0x800 /* musb instance 0 */ - 0x47401800 0x800>; /* musb instance 1 */ - interrupts = <17 /* usbss */ - 18 /* musb instance 0 */ - 19>; /* musb instance 1 */ - multipoint = <1>; - num-eps = <16>; - ram-bits = <12>; - port0-mode = <3>; - port1-mode = <3>; - power = <250>; + usb: usb@47400000 { + compatible = "ti,am33xx-usb"; + reg = <0x47400000 0x1000>; + ranges; + #address-cells = <1>; + #size-cells = <1>; ti,hwmods = "usb_otg_hs"; + status = "disabled"; + + usb0_phy: phy@47401300 { + compatible = "ti,am335x-usb-phy"; + reg = <0x44e10620 0x8 + 0x47401300 0x100>; + reg-names = "reset_mod", "phy"; + status = "disabled"; + }; + + usb0: usb@47401000 { + compatible = "ti,musb-am33xx"; + ranges; + #address-cells = <1>; + #size-cells = <1>; + reg = <0x47401000 0x200>; + reg-names = "control"; + status = "disabled"; + + musb0: usb@47401400 { + compatible = "mg,musbmhdrc"; + reg = <0x47401400 0x400>; + reg-names = "mc"; + interrupts = <18>; + interrupt-names = "mc"; + multipoint = <1>; + num-eps = <16>; + ram-bits = <12>; + port-mode = <3>; + power = <250>; + phys = <&usb0_phy>; + }; + }; + + usb1_phy: phy@47401b00 { + compatible = "ti,am335x-usb-phy"; + reg = <0x44e10628 0x8 + 0x47401b00 0x100>; + reg-names = "reset_mod", "phy"; + status = "disabled"; + }; + + usb1: usb@47401800 { + compatible = "ti,musb-am33xx"; + ranges; + #address-cells = <1>; + #size-cells = <1>; + reg = <0x47401800 0x200>; + reg-names = "control"; + status = "disabled"; + + musb1: usb@47401c00 { + compatible = "mg,musbmhdrc"; + reg = <0x47401c00 0x400>; + reg-names = "mc"; + interrupts = <19>; + interrupt-names = "mc"; + multipoint = <1>; + num-eps = <16>; + ram-bits = <12>; + port-mode = <3>; + power = <250>; + phys = <&usb1_phy>; + }; + }; }; epwmss0: epwmss@48300000 {drivers/usb/musb/Kconfig +4
-0@@ -83,6 +83,7 @@ config USB_MUSB_AM35X config USB_MUSB_DSPS tristate "TI DSPS platforms" + select USB_MUSB_AM335X_CHILD config USB_MUSB_BLACKFIN tristate "Blackfin"@@ -93,6 +94,9 @@ config USB_MUSB_UX500 endchoice +config USB_MUSB_AM335X_CHILD + tristate + choice prompt 'MUSB DMA mode' default MUSB_PIO_ONLY if ARCH_MULTIPLATFORMdrivers/usb/musb/Makefile +3
-0@@ -20,6 +20,9 @@ obj-$(CONFIG_USB_MUSB_DA8XX) += da8xx.o obj-$(CONFIG_USB_MUSB_BLACKFIN) += blackfin.o obj-$(CONFIG_USB_MUSB_UX500) += ux500.o + +obj-$(CONFIG_USB_MUSB_AM335X_CHILD) += musb_am335x.o + # the kconfig must guarantee that only one of the # possible I/O schemes will be enabled at a time ... # PIO only, or DMA (several potential schemes).drivers/usb/musb/musb_am335x.c new file +55
-0@@ -0,0 +1,55 @@ +#include <linux/init.h> +#include <linux/platform_device.h> +#include <linux/pm_runtime.h> +#include <linux/module.h> +#include <linux/of_platform.h> + +static int am335x_child_probe (struct platform_device *pdev) +{ +int ret; + +pm_runtime_enable (&pdev->dev); + + ret =of_platform_populate (pdev->dev.of_node,NULL ,NULL , &pdev->dev); +if (ret) + goto err; + +return 0 ; +err: +pm_runtime_disable (&pdev->dev); +return ret; +} + +static int of_remove_populated_child (struct device *dev,void *d) +{ +struct platform_device *pdev =to_platform_device (dev); + +of_device_unregister (pdev); +return 0 ; +} + +static int am335x_child_remove (struct platform_device *pdev) +{ +device_for_each_child (&pdev->dev,NULL , of_remove_populated_child); +pm_runtime_disable (&pdev->dev); +return 0 ; +} + +static const struct of_device_id am335x_child_of_match[] = { + { .compatible ="ti,am33xx-usb" }, + { }, +}; +MODULE_DEVICE_TABLE (of, am335x_child_of_match); + +static struct platform_driver am335x_child_driver = { + .probe = am335x_child_probe, + .remove = am335x_child_remove, + .driver = { + .name ="am335x-usb-childs" , + .of_match_table =of_match_ptr (am335x_child_of_match), + }, +}; + +module_platform_driver (am335x_child_driver); +MODULE_DESCRIPTION ("AM33xx child devices" ); +MODULE_LICENSE ("GPL v2" );drivers/usb/musb/musb_dsps.c +98
-157@@ -43,6 +43,7 @@#include <linux/of.h> #include <linux/of_device.h> #include <linux/of_address.h> +#include <linux/of_irq.h> #include "musb_core.h" @@ -106,10 +107,7 @@ struct dsps_musb_wrapper {/* bit positions for mode */ unsigned iddig:5;/* miscellaneous stuff */ -u32 musb_core_offset;u8 poll_seconds; -/* number of musb instances */ -u8 instances; };/** @@ -117,10 +115,10 @@ struct dsps_musb_wrapper {*/ struct dsps_glue {struct device *dev; -struct platform_device *musb[2 ];/* child musb pdev */ +struct platform_device *musb;/* child musb pdev */ const struct dsps_musb_wrapper *wrp;/* wrapper register offsets */ -struct timer_list timer[2 ];/* otg_workaround timer */ -unsigned long last_timer[2 ];/* last timer data for each instance */ +struct timer_list timer;/* otg_workaround timer */ +unsigned long last_timer;/* last timer data for each instance */ };/** @@ -170,7 +168,6 @@ static void otg_timer(unsigned long _musb)struct musb *musb = (void *)_musb;void __iomem *mregs = musb->mregs;struct device *dev = musb->controller; -struct platform_device *pdev =to_platform_device (dev);struct dsps_glue *glue =dev_get_drvdata (dev->parent);const struct dsps_musb_wrapper *wrp = glue->wrp;u8 devctl;@@ -207,7 +204,7 @@ static void otg_timer(unsigned long _musb)case OTG_STATE_B_IDLE : devctl =dsps_readb (mregs,MUSB_DEVCTL );if (devctl &MUSB_DEVCTL_BDEVICE ) -mod_timer (&glue->timer[pdev->id], +mod_timer (&glue->timer, jiffies + wrp->poll_seconds *HZ );else musb->xceiv->state =OTG_STATE_A_IDLE ;@@ -221,7 +218,6 @@ static void otg_timer(unsigned long _musb)static void dsps_musb_try_idle (struct musb *musb,unsigned long timeout) {struct device *dev = musb->controller; -struct platform_device *pdev =to_platform_device (dev);struct dsps_glue *glue =dev_get_drvdata (dev->parent);if (timeout ==0 )@@ -232,23 +228,23 @@ static void dsps_musb_try_idle(struct musb *musb, unsigned long timeout) musb->xceiv->state == OTG_STATE_A_WAIT_BCON)) {dev_dbg (musb->controller,"%s active, deleting timer\n" ,usb_otg_state_string (musb->xceiv->state)); -del_timer (&glue->timer[pdev->id]); - glue->last_timer[pdev->id] = jiffies; +del_timer (&glue->timer); + glue->last_timer = jiffies;return ; } -if (time_after (glue->last_timer[pdev->id], timeout) && -timer_pending (&glue->timer[pdev->id])) { +if (time_after (glue->last_timer, timeout) && +timer_pending (&glue->timer)) {dev_dbg (musb->controller,"Longer idle timer already pending, ignoring...\n" );return ; } - glue->last_timer[pdev->id] = timeout; + glue->last_timer = timeout;dev_dbg (musb->controller,"%s inactive, starting idle timer for %u ms\n" ,usb_otg_state_string (musb->xceiv->state),jiffies_to_msecs (timeout - jiffies)); -mod_timer (&glue->timer[pdev->id], timeout); +mod_timer (&glue->timer, timeout); }static irqreturn_t dsps_interrupt (int irq,void *hci)@@ -256,7 +252,6 @@ static irqreturn_t dsps_interrupt(int irq, void *hci)struct musb *musb = hci;void __iomem *reg_base = musb->ctrl_base;struct device *dev = musb->controller; -struct platform_device *pdev =to_platform_device (dev);struct dsps_glue *glue =dev_get_drvdata (dev->parent);const struct dsps_musb_wrapper *wrp = glue->wrp;unsigned long flags;@@ -316,7 +311,7 @@ static irqreturn_t dsps_interrupt(int irq, void *hci)*/ musb->int_usb &= ~MUSB_INTR_VBUSERROR ; musb->xceiv->state =OTG_STATE_A_WAIT_VFALL ; -mod_timer (&glue->timer[pdev->id], +mod_timer (&glue->timer, jiffies + wrp->poll_seconds *HZ );WARNING ("VBUS error workaround (delay coming)\n" ); }else if (drvvbus) {@@ -324,7 +319,7 @@ static irqreturn_t dsps_interrupt(int irq, void *hci)MUSB_HST_MODE (musb); musb->xceiv->otg->default_a =1 ; musb->xceiv->state =OTG_STATE_A_WAIT_VRISE ; -del_timer (&glue->timer[pdev->id]); +del_timer (&glue->timer); }else { musb->is_active =0 ;MUSB_DEV_MODE (musb);@@ -351,8 +346,7 @@ static irqreturn_t dsps_interrupt(int irq, void *hci)/* Poll for ID change */ if (musb->xceiv->state ==OTG_STATE_B_IDLE ) -mod_timer (&glue->timer[pdev->id], - jiffies + wrp->poll_seconds *HZ ); +mod_timer (&glue->timer, jiffies + wrp->poll_seconds *HZ );spin_unlock_irqrestore (&musb->lock, flags);@@ -362,31 +356,34 @@ static irqreturn_t dsps_interrupt(int irq, void *hci)static int dsps_musb_init (struct musb *musb) {struct device *dev = musb->controller; -struct platform_device *pdev =to_platform_device (dev);struct dsps_glue *glue =dev_get_drvdata (dev->parent); +struct platform_device *parent =to_platform_device (dev->parent);const struct dsps_musb_wrapper *wrp = glue->wrp; -void __iomem *reg_base = musb->ctrl_base; +void __iomem *reg_base; +struct resource *r;u32 rev, val; -int status; -/* mentor core register starts at offset of 0x400 from musb base */ - musb->mregs += wrp->musb_core_offset; + r =platform_get_resource_byname (parent,IORESOURCE_MEM ,"control" ); +if (!r) +return -EINVAL ; + + reg_base =devm_ioremap_resource (dev, r); +if (!musb->ctrl_base) +return -EINVAL ; + musb->ctrl_base = reg_base;/* NOP driver needs change if supporting dual instance */ - musb->xceiv =devm_usb_get_phy_by_phandle (glue->dev,"phys" ,0 ); -if (IS_ERR_OR_NULL (musb->xceiv)) -return -EPROBE_DEFER ; + musb->xceiv =devm_usb_get_phy_by_phandle (dev,"phys" ,0 ); +if (IS_ERR (musb->xceiv)) +return PTR_ERR (musb->xceiv);/* Returns zero if e.g. not clocked */ rev =dsps_readl (reg_base, wrp->revision); -if (!rev) { - status = -ENODEV ; - goto err0; - } +if (!rev) +return -ENODEV ;usb_phy_init (musb->xceiv); - -setup_timer (&glue->timer[pdev->id], otg_timer, (unsigned long ) musb); +setup_timer (&glue->timer, otg_timer, (unsigned long ) musb);/* Reset the musb */ dsps_writel (reg_base, wrp->control, (1 << wrp->reset));@@ -402,17 +399,14 @@ static int dsps_musb_init(struct musb *musb)dsps_writel (reg_base, wrp->eoi,0 );return 0 ; -err0: -return status; }static int dsps_musb_exit (struct musb *musb) {struct device *dev = musb->controller; -struct platform_device *pdev =to_platform_device (dev);struct dsps_glue *glue =dev_get_drvdata (dev->parent); -del_timer_sync (&glue->timer[pdev->id]); +del_timer_sync (&glue->timer);usb_phy_shutdown (musb->xceiv);return 0 ;@@ -430,106 +424,98 @@ static struct musb_platform_ops dsps_ops = {static u64 musb_dmamask =DMA_BIT_MASK (32 ); -static int dsps_create_musb_pdev (struct dsps_glue *glue,u8 id) +static int get_int_prop (struct device_node *dn,const char *s) { -struct device *dev = glue->dev; -struct platform_device *pdev =to_platform_device (dev); -struct musb_hdrc_platform_data *pdata = dev->platform_data; -struct device_node *np = pdev->dev.of_node; -struct musb_hdrc_config *config; -struct platform_device *musb; -struct resource *res; +int ret; +u32 val; + + ret =of_property_read_u32 (dn, s, &val); +if (ret) +return 0 ; +return val; +} + +static int dsps_create_musb_pdev (struct dsps_glue *glue, +struct platform_device *parent) +{ +struct musb_hdrc_platform_data pdata;struct resource resources[2 ]; -char res_name[11 ]; +struct device *dev = &parent->dev; +struct musb_hdrc_config *config; +struct platform_device *musb; +struct device_node *dn = parent->dev.of_node; +struct device_node *child_node;int ret; -/* first resource is for usbss, so start index from 1 */ - res =platform_get_resource (pdev,IORESOURCE_MEM , id +1 ); -if (!res) { -dev_err (dev,"failed to get memory for instance %d\n" , id); - ret = -ENODEV ; - goto err0; + child_node =of_get_child_by_name (dn,"usb" ); +if (!child_node) +return -EINVAL ; + +memset (resources,0 ,sizeof (resources)); + ret =of_address_to_resource (child_node,0 , &resources[0 ]); +if (ret) { +dev_err (dev,"failed to get memory.\n" ); +return ret; } - res->parent =NULL ; - resources[0 ] = *res; - -/* first resource is for usbss, so start index from 1 */ - res =platform_get_resource (pdev,IORESOURCE_IRQ , id +1 ); -if (!res) { -dev_err (dev,"failed to get irq for instance %d\n" , id); - ret = -ENODEV ; - goto err0; + + ret =of_irq_to_resource (child_node,0 , &resources[1 ]); +if (ret ==0 ) { +dev_err (dev,"failed to get irq.\n" ); + ret = -EINVAL ; +return ret; } - res->parent =NULL ; - resources[1 ] = *res; - resources[1 ].name ="mc" ;/* allocate the child platform device */ musb =platform_device_alloc ("musb-hdrc" ,PLATFORM_DEVID_AUTO );if (!musb) {dev_err (dev,"failed to allocate musb device\n" ); - ret = -ENOMEM ; - goto err0; +return -ENOMEM ; } musb->dev.parent = dev; musb->dev.dma_mask = &musb_dmamask; musb->dev.coherent_dma_mask = musb_dmamask; + musb->dev.of_node =of_node_get (child_node); - glue->musb[id] = musb; + glue->musb = musb; - ret =platform_device_add_resources (musb, resources,2 ); + ret =platform_device_add_resources (musb, resources, +ARRAY_SIZE (resources));if (ret) {dev_err (dev,"failed to add resources\n" ); - goto err2; + goto err; } -if (np) { - pdata =devm_kzalloc (&pdev->dev,sizeof (*pdata),GFP_KERNEL ); -if (!pdata) { -dev_err (&pdev->dev, -"failed to allocate musb platform data\n" ); - ret = -ENOMEM ; - goto err2; - } - - config =devm_kzalloc (&pdev->dev,sizeof (*config),GFP_KERNEL ); -if (!config) { -dev_err (&pdev->dev, -"failed to allocate musb hdrc config\n" ); - ret = -ENOMEM ; - goto err2; - } - -of_property_read_u32 (np,"num-eps" , (u32 *)&config->num_eps); -of_property_read_u32 (np,"ram-bits" , (u32 *)&config->ram_bits); -snprintf (res_name,sizeof (res_name),"port%d-mode" , id); -of_property_read_u32 (np, res_name, (u32 *)&pdata->mode); -of_property_read_u32 (np,"power" , (u32 *)&pdata->power); - config->multipoint =of_property_read_bool (np,"multipoint" ); - - pdata->config = config; + config =devm_kzalloc (&parent->dev,sizeof (*config),GFP_KERNEL ); +if (!config) { +dev_err (dev,"failed to allocate musb hdrc config\n" ); + ret = -ENOMEM ; + goto err; } + pdata.config = config; + pdata.platform_ops = &dsps_ops; - pdata->platform_ops = &dsps_ops; + config->num_eps =get_int_prop (child_node,"num-eps" ); + config->ram_bits =get_int_prop (child_node,"ram-bits" ); + pdata.mode =get_int_prop (child_node,"port-mode" ); + pdata.power =get_int_prop (child_node,"power" ); + config->multipoint =of_property_read_bool (child_node,"multipoint" ); - ret =platform_device_add_data (musb, pdata,sizeof (*pdata)); + ret =platform_device_add_data (musb, &pdata,sizeof (pdata));if (ret) {dev_err (dev,"failed to add platform_data\n" ); - goto err2; + goto err; } ret =platform_device_add (musb);if (ret) {dev_err (dev,"failed to register musb device\n" ); - goto err2; + goto err; } -return 0 ; -err2: +err:platform_device_put (musb); -err0:return ret; }@@ -538,14 +524,12 @@ static int dsps_probe(struct platform_device *pdev)const struct of_device_id *match;const struct dsps_musb_wrapper *wrp;struct dsps_glue *glue; -struct resource *iomem; -int ret, i; +int ret; match =of_match_node (musb_dsps_of_match, pdev->dev.of_node);if (!match) {dev_err (&pdev->dev,"fail to get matching of_match struct\n" ); - ret = -EINVAL ; - goto err0; +return -EINVAL ; } wrp = match->data;@@ -553,29 +537,13 @@ static int dsps_probe(struct platform_device *pdev) glue =kzalloc (sizeof (*glue),GFP_KERNEL );if (!glue) {dev_err (&pdev->dev,"unable to allocate glue memory\n" ); - ret = -ENOMEM ; - goto err0; - } - -/* get memory resource */ - iomem =platform_get_resource (pdev,IORESOURCE_MEM ,0 ); -if (!iomem) { -dev_err (&pdev->dev,"failed to get usbss mem resourse\n" ); - ret = -ENODEV ; - goto err1; +return -ENOMEM ; } glue->dev = &pdev->dev; + glue->wrp = wrp; - glue->wrp =kmemdup (wrp,sizeof (*wrp),GFP_KERNEL ); -if (!glue->wrp) { -dev_err (&pdev->dev,"failed to duplicate wrapper struct memory\n" ); - ret = -ENOMEM ; - goto err1; - }platform_set_drvdata (pdev, glue); - -/* enable the usbss clocks */ pm_runtime_enable (&pdev->dev); ret =pm_runtime_get_sync (&pdev->dev);@@ -584,17 +552,9 @@ static int dsps_probe(struct platform_device *pdev) goto err2; } -/* create the child platform device for all instances of musb */ -for (i =0 ; i < wrp->instances ; i++) { - ret =dsps_create_musb_pdev (glue, i); -if (ret !=0 ) { -dev_err (&pdev->dev,"failed to create child pdev\n" ); -/* release resources of previously created instances */ -for (i--; i >=0 ; i--) -platform_device_unregister (glue->musb[i]); - goto err3; - } - } + ret =dsps_create_musb_pdev (glue, pdev); +if (ret) + goto err3;return 0 ;@@ -602,26 +562,19 @@ static int dsps_probe(struct platform_device *pdev)pm_runtime_put (&pdev->dev); err2:pm_runtime_disable (&pdev->dev); -kfree (glue->wrp); -err1:kfree (glue); -err0:return ret; } +static int dsps_remove (struct platform_device *pdev) {struct dsps_glue *glue =platform_get_drvdata (pdev); -const struct dsps_musb_wrapper *wrp = glue->wrp; -int i; -/* delete the child platform device */ -for (i =0 ; i < wrp->instances ; i++) -platform_device_unregister (glue->musb[i]); +platform_device_unregister (glue->musb);/* disable usbss clocks */ pm_runtime_put (&pdev->dev);pm_runtime_disable (&pdev->dev); -kfree (glue->wrp);kfree (glue);return 0 ; }@@ -652,9 +605,7 @@ static const struct dsps_musb_wrapper ti81xx_driver_data = { .rxep_shift = 16, .rxep_mask = 0xfffe, .rxep_bitmap = (0xfffe << 16), - .musb_core_offset = 0x400, .poll_seconds = 2, - .instances = 1, };static const struct of_device_id musb_dsps_of_match[] = {@@ -678,14 +629,4 @@ MODULE_AUTHOR("Ravi B <[email protected]>");MODULE_AUTHOR ("Ajay Kumar Gupta <[email protected]>" );MODULE_LICENSE ("GPL v2" ); -static int __init dsps_init (void ) -{ -return platform_driver_register (&dsps_usbss_driver); -} -subsys_initcall (dsps_init); - -static void __exit dsps_exit(void) -{ -platform_driver_unregister (&dsps_usbss_driver); -} -module_exit (dsps_exit); +module_platform_driver (dsps_usbss_driver);
Signature · 1 line
-George
Re: [PATCH 05/16] usb: musb: dsps: use proper child nodes
Quoted 15 lines · George Cherian
Quoted 15 lines
arch/arm/boot/dts/am335x-evm.dts +6
-0@@ -171,6 +171,26 @@ }; }; + musb: usb@47400000 { + status = "okay"; + + phy@47401300 { + status = "okay"; + }; +
Quoted 8 lines
arch/arm/boot/dts/am335x-evm.dts line 187
Quoted 7 lines
arch/arm/boot/dts/am335x-evm.dts +7
-0+ phy@47401b00 { + status = "okay"; + }; + + usb@47401000 { + status = "no"; + };Any reason usb0 is disabled for am33xx evm? Just for testing?
No, that is an error and will be corrected.
Please try to reduce the email in reply to sane size / context. Here the reader notices the file you refer to and your comment. Quoting the whole patch eats up more resources for processing plus the reader might overlook additional comments (he most likely will search for at least one line).
Sebastian
PATCH 6/16 usb: musb: dsps: rename ti81xx_driver_data to am33xx_driver_data
In reply to Sebastian Andrzej SiewiorThis patch renames the type struct from ti81xx_driver_data to am33xx_driver_data since it is not used for ti81xx anymore. The EOI member is also removed since the am33xx SoC does not have such register. The interrupt is acknowledged by writting into the stat register.
--- drivers/usb/musb/musb_dsps.c | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-)
drivers/usb/musb/musb_dsps.c +4 -14
@@ -74,7 +74,6 @@ struct dsps_musb_wrapper {u16 revision;u16 control;u16 status; -u16 eoi;u16 epintr_set;u16 epintr_clear;u16 epintr_status;
@@ -160,7 +159,6 @@ static void dsps_musb_disable(struct musb *musb)dsps_writel (reg_base, wrp->epintr_clear, wrp->txep_bitmap | wrp->rxep_bitmap);dsps_writeb (musb->mregs,MUSB_DEVCTL ,0 ); -dsps_writel (reg_base, wrp->eoi,0 ); }static void otg_timer (unsigned long _musb)
@@ -271,7 +269,7 @@ static irqreturn_t dsps_interrupt(int irq, void *hci)/* Get usb core interrupts */ usbintr =dsps_readl (reg_base, wrp->coreintr_status);if (!usbintr && !epintr) - goto eoi; + goto out; musb->int_usb = (usbintr & wrp->usb_bitmap) >> wrp->usb_shift;if (usbintr)
@@ -339,15 +337,11 @@ static irqreturn_t dsps_interrupt(int irq, void *hci)if (musb->int_tx || musb->int_rx || musb->int_usb) ret |=musb_interrupt (musb); - eoi: -/* EOI needs to be written for the IRQ to be re-asserted. */ -if (ret ==IRQ_HANDLED || epintr || usbintr) -dsps_writel (reg_base, wrp->eoi,1 ); -/* Poll for ID change */ if (musb->xceiv->state ==OTG_STATE_B_IDLE )mod_timer (&glue->timer, jiffies + wrp->poll_seconds *HZ ); +out:spin_unlock_irqrestore (&musb->lock, flags);return ret;
@@ -395,9 +389,6 @@ static int dsps_musb_init(struct musb *musb) val &= ~(1 << wrp->otg_disable);dsps_writel (musb->ctrl_base, wrp->phy_utmi, val); -/* clear level interrupt */ -dsps_writel (reg_base, wrp->eoi,0 ); -return 0 ; }
@@ -579,11 +570,10 @@ static int dsps_remove(struct platform_device *pdev)return 0 ; } -static const struct dsps_musb_wrapper ti81xx_driver_data = { +static const struct dsps_musb_wrapper am33xx_driver_data = { .revision =0x00 , .control =0x14 , .status =0x18 , - .eoi =0x24 , .epintr_set =0x38 , .epintr_clear =0x40 , .epintr_status =0x30 ,
@@ -610,7 +600,7 @@ static const struct dsps_musb_wrapper ti81xx_driver_data = {static const struct of_device_id musb_dsps_of_match[] = { { .compatible ="ti,musb-am33xx" , - .data = (void *) &ti81xx_driver_data, }, + .data = (void *) &am33xx_driver_data, }, { }, };MODULE_DEVICE_TABLE (of, musb_dsps_of_match);
Signature · 1 line
1.8.3.2
Re: [PATCH 06/16] usb: musb: dsps: rename ti81xx_driver_data to am33xx_driver_data
Hi Sebastian,
Quoted 5 lines · Sebastian Andrzej Siewior
This patch renames the type struct from
ti81xx_driver_datatoam33xx_driver_datasince it is not used for ti81xx anymore. The EOI member is also removed since the am33xx SoC does not have such register. The interrupt is acknowledged by writting into the stat register.
AM335X TRM Section 16.6.5 and 16.7.5 describes about EOI registers. Its at offset 0x24. Or is it that the interrupts are acknowledged even without writing to eoi register?
Signature · 1 line
-George
Re: [PATCH 06/16] usb: musb: dsps: rename ti81xx_driver_data to am33xx_driver_data
Quoted 11 lines · George Cherian
Hi Sebastian,
Quoted 5 lines · Sebastian Andrzej Siewior
This patch renames the type struct from
ti81xx_driver_datatoam33xx_driver_datasince it is not used for ti81xx anymore. The EOI member is also removed since the am33xx SoC does not have such register. The interrupt is acknowledged by writting into the stat register.
Quoted 3 lines
AM335X TRM Section 16.6.5 and 16.7.5 describes about EOI registers. Its at offset
0x24. Or is it that the interrupts are acknowledged even without writing to eoi register?
I have here "Literature Number: SPRUH73H October 2011 Revised April 2013" which calls itself "AM335x ARM® CortexTM-A8 Microprocessors (MPUs) Technical Reference Manual".
This document ends with 16.5 that means there is no chapter 16.6 or 16.7. The next one is 17.
16.5.2 and 16.5.3 describes the available registers of USB[01]_CTRL REGISTERS which is where the EOI register is accessed. I see here
20h USB0IRQMSTAT
28h USB0IRQSTATRAW0
so no 0x24 at least in my document.
Sebastian
Re: [PATCH 06/16] usb: musb: dsps: rename ti81xx_driver_data to am33xx_driver_data
Quoted 11 lines · Sebastian Andrzej Siewior
Quoted 10 lines · George Cherian
Hi Sebastian,
Quoted 5 lines · Sebastian Andrzej Siewior
This patch renames the type struct from
ti81xx_driver_datatoam33xx_driver_datasince it is not used for ti81xx anymore. The EOI member is also removed since the am33xx SoC does not have such register. The interrupt is acknowledged by writting into the stat register.
Quoted 6 lines
Quoted 3 lines
AM335X TRM Section 16.6.5 and 16.7.5 describes about EOI registers. Its at offset
0x24. Or is it that the interrupts are acknowledged even without writing to eoi register?I have here "Literature Number: SPRUH73H October 2011 Revised April 2013" which calls itself "AM335x ARM® CortexTM-A8 Microprocessors (MPUs) Technical Reference Manual".
Looks like I have an old TRM with me, which has EOI register at 24h. I need to update my TRM. ;)
Quoted 12 lines
This document ends with 16.5 that means there is no chapter 16.6 or 16.7. The next one is 17.
16.5.2 and 16.5.3 describes the available registers of USB[01]_CTRL REGISTERS which is where the EOI register is accessed. I see here20h USB0IRQMSTAT
28h USB0IRQSTATRAW0so no
0x24at least in my document.Sebastian
Signature · 1 line
-George
A message that is not in the archive (sent off-list or not yet received): CADYTM3avh7GFTDQW01FnojKZkmL0_hi+=K-VVwCw5peJL2hwTA@mail.gmail.com
Re: [PATCH 06/16] usb: musb: dsps: rename ti81xx_driver_data to am33xx_driver_data
(re-send, due to last delivery failure to the mailing list...)
Quoted 22 lines · Bin Liu
Hi Sebastian,
Quoted 5 lines · Sebastian Andrzej Siewior
This patch renames the type struct from
ti81xx_driver_datatoam33xx_driver_datasince it is not used for ti81xx anymore. The EOI member is also removed since the am33xx SoC does not have such register. The interrupt is acknowledged by writting into the stat register.I guess the EOI register is removed from the TRM because AM33xx does not use it, there is no need to write to it to acknowledge. It does not hurt to write to it though since the register still exists, it just does nothing, I guess.
But I am not sure if it is a good idea to remove eoi from the
musb_dspsdriver. If the intension is to merge the support for other SoC, such as AM35xx, AM18xx, then EOI handling might be still needed. I just don't know how those devices use EOI.Regards,
-Bin.
Re: [PATCH 06/16] usb: musb: dsps: rename ti81xx_driver_data to am33xx_driver_data
In reply to a message not in the archiveQuoted 1 line · * Bin Liu | 2013-07-23 13:23:57 [-0500]:
Hi Sebastian,
Hi Liu,
Quoted 8 lines
Quoted 5 lines · Sebastian Andrzej Siewior
This patch renames the type struct from
ti81xx_driver_datatoam33xx_driver_datasince it is not used for ti81xx anymore. The EOI member is also removed since the am33xx SoC does not have such register. The interrupt is acknowledged by writting into the stat register.
Quoted 4 lines
I guess the EOI register is removed from the TRM because AM33xx does not use it, there is no need to write to it to acknowledge. It does not hurt to write to it though since the register still exists, it just does nothing, I guess.
Is it really there or was it never there and it has been added to TRM by accident?
Quoted 4 lines
But I am not sure if it is a good idea to remove eoi from the
musb_dspsdriver. If the intension is to merge the support for other SoC, such as AM35xx, AM18xx, then EOI handling might be still needed. I just don't know how those devices use EOI.
If one of the architectures gets added which need an EOI then the offset can be 0 and the EOI will happen only if it is != 0.
Quoted 3 lines
Regards,
-Bin.
Sebastian
Re: [PATCH 06/16] usb: musb: dsps: rename ti81xx_driver_data to am33xx_driver_data
Sebastian,
Quoted 13 lines · Sebastian Andrzej Siewior
Quoted 1 line · * Bin Liu | 2013-07-23 13:23:57 [-0500]:
Hi Sebastian,
Hi Liu,
Quoted 8 lines
Quoted 5 lines · Sebastian Andrzej Siewior
This patch renames the type struct from
ti81xx_driver_datatoam33xx_driver_datasince it is not used for ti81xx anymore. The EOI member is also removed since the am33xx SoC does not have such register. The interrupt is acknowledged by writting into the stat register.
Quoted 7 lines
Quoted 4 lines
I guess the EOI register is removed from the TRM because AM33xx does not use it, there is no need to write to it to acknowledge. It does not hurt to write to it though since the register still exists, it just does nothing, I guess.
Is it really there or was it never there and it has been added to TRM by accident?
The EOI register IS in the USB subsystem of AM33xx, but the SoC does not use it because it uses level triggering for USB interrupt.
Quoted 8 lines
Quoted 5 lines
But I am not sure if it is a good idea to remove eoi from the
musb_dspsdriver. If the intension is to merge the support for other SoC, such as AM35xx, AM18xx, then EOI handling might be still needed. I just don't know how those devices use EOI.If one of the architectures gets added which need an EOI then the offset can be 0 and the EOI will happen only if it is != 0.
This patch cleaned up the use of EOI. Do you mean EOI handling will be added back with condition EOI offset != 0, when the support of new device which uses EIO is added?
Regards,
-Bin.
Quoted 6 lines
Quoted 4 lines
Regards,
-Bin.Sebastian
Re: [PATCH 06/16] usb: musb: dsps: rename ti81xx_driver_data to am33xx_driver_data
Quoted 1 line · Bin Liu
Sebastian,
Hi Bin,
Quoted 4 lines
Quoted 2 lines
Is it really there or was it never there and it has been added to TRM by accident?
The EOI register IS in the USB subsystem of AM33xx, but the SoC does not use it because it uses level triggering for USB interrupt.
I see.
Quoted 10 lines
Quoted 7 lines
Quoted 4 lines
But I am not sure if it is a good idea to remove eoi from the
musb_dspsdriver. If the intension is to merge the support for other SoC, such as AM35xx, AM18xx, then EOI handling might be still needed. I just don't know how those devices use EOI.If one of the architectures gets added which need an EOI then the offset can be 0 and the EOI will happen only if it is != 0.
This patch cleaned up the use of EOI. Do you mean EOI handling will be added back with condition EOI offset != 0, when the support of new device which uses EIO is added?
That is my intention.
Quoted 2 lines
Regards,
-Bin.
Sebastian
Re: [PATCH 06/16] usb: musb: dsps: rename ti81xx_driver_data to am33xx_driver_data
Sebastian,
Quoted 17 lines · Sebastian Andrzej Siewior
Quoted 1 line · Bin Liu
Sebastian,
Hi Bin,
Quoted 4 lines
Quoted 2 lines
Is it really there or was it never there and it has been added to TRM by accident?
The EOI register IS in the USB subsystem of AM33xx, but the SoC does not use it because it uses level triggering for USB interrupt.
I see.
Quoted 5 lines
Quoted 5 lines
Quoted 4 lines
But I am not sure if it is a good idea to remove eoi from the
musb_dspsdriver. If the intension is to merge the support for other SoC, such as AM35xx, AM18xx, then EOI handling might be still needed. I just don't know how those devices use EOI.
Quoted 7 lines
Quoted 5 lines
Quoted 2 lines
If one of the architectures gets added which need an EOI then the offset can be 0 and the EOI will happen only if it is != 0.
This patch cleaned up the use of EOI. Do you mean EOI handling will be added back with condition EOI offset != 0, when the support of new device which uses EIO is added?
That is my intention.
Then should something like EOI cleanup be added into the commit message for better git log searching experience? I would think the EOI cleanup is more important then variable renaming in this patch. Or even better to separate the changes into two patches.
Quoted 5 lines
Quoted 3 lines
Regards,
-Bin.Sebastian
Regards,
-Bin.
Re: [PATCH 06/16] usb: musb: dsps: rename ti81xx_driver_data to am33xx_driver_data
Hi,
Quoted 27 lines · Bin Liu
Sebastian,
Quoted 23 lines · Sebastian Andrzej Siewior
Quoted 1 line · Bin Liu
Sebastian,
Hi Bin,
Quoted 4 lines
Quoted 2 lines
Is it really there or was it never there and it has been added to TRM by accident?
The EOI register IS in the USB subsystem of AM33xx, but the SoC does not use it because it uses level triggering for USB interrupt.
I see.
Quoted 10 lines
Quoted 7 lines
Quoted 4 lines
But I am not sure if it is a good idea to remove eoi from the
musb_dspsdriver. If the intension is to merge the support for other SoC, such as AM35xx, AM18xx, then EOI handling might be still needed. I just don't know how those devices use EOI.If one of the architectures gets added which need an EOI then the offset can be 0 and the EOI will happen only if it is != 0.
This patch cleaned up the use of EOI. Do you mean EOI handling will be added back with condition EOI offset != 0, when the support of new device which uses EIO is added?
Quoted 5 lines
Quoted 1 line
That is my intention.
Then should something like EOI cleanup be added into the commit message for better git log searching experience? I would think the EOI cleanup is more important then variable renaming in this patch. Or even better to separate the changes into two patches.
perhaps two separate patches would be best, indeed. At least it would make it simpler to track regressions.
Signature · 1 line
balbi
PATCH 1/2 usb: musb: dsps: rename ti81xx_driver_data to am33xx_driver_data
The ti81xx platform is not fully supported right now. This patch renames the date structure to a am33xx prefix which is actually used.
--- drivers/usb/musb/musb_dsps.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/usb/musb/musb_dsps.c +2 -2
@@ -742,7 +742,7 @@ static int dsps_resume(struct device *dev) static SIMPLE_DEV_PM_OPS(dsps_pm_ops, dsps_suspend, dsps_resume); -static const struct dsps_musb_wrapper ti81xx_driver_data = { +static const struct dsps_musb_wrapper am33xx_driver_data = { .revision =0x00 , .control =0x14 , .status =0x18 ,
@@ -774,7 +774,7 @@ static const struct dsps_musb_wrapper ti81xx_driver_data = {static const struct of_device_id musb_dsps_of_match[] = { { .compatible ="ti,musb-am33xx" , - .data = (void *) &ti81xx_driver_data, }, + .data = (void *) &am33xx_driver_data, }, { }, };MODULE_DEVICE_TABLE (of, musb_dsps_of_match);
Signature · 1 line
1.8.3.2
PATCH 2/2 usb: musb: dsps: remove EOI access
The EOI register is not present in the AM335x memory space according to the TRM and thus removed.
Should any platform using the EOI register get merged then it may be used again if the register address is not zero.
--- drivers/usb/musb/musb_dsps.c | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-)
drivers/usb/musb/musb_dsps.c +2 -13
@@ -73,7 +73,6 @@ struct dsps_musb_wrapper {u16 revision;u16 control;u16 status; -u16 eoi;u16 epintr_set;u16 epintr_clear;u16 epintr_status;
@@ -202,7 +201,6 @@ static void dsps_musb_disable(struct musb *musb)dsps_writel (reg_base, wrp->epintr_clear, wrp->txep_bitmap | wrp->rxep_bitmap);dsps_writeb (musb->mregs,MUSB_DEVCTL ,0 ); -dsps_writel (reg_base, wrp->eoi,0 ); }static void otg_timer (unsigned long _musb)
@@ -316,7 +314,7 @@ static irqreturn_t dsps_interrupt(int irq, void *hci)/* Get usb core interrupts */ usbintr =dsps_readl (reg_base, wrp->coreintr_status);if (!usbintr && !epintr) - goto eoi; + goto out; musb->int_usb = (usbintr & wrp->usb_bitmap) >> wrp->usb_shift;if (usbintr)
@@ -384,16 +382,11 @@ static irqreturn_t dsps_interrupt(int irq, void *hci)if (musb->int_tx || musb->int_rx || musb->int_usb) ret |=musb_interrupt (musb); - eoi: -/* EOI needs to be written for the IRQ to be re-asserted. */ -if (ret ==IRQ_HANDLED || epintr || usbintr) -dsps_writel (reg_base, wrp->eoi,1 ); -/* Poll for ID change */ if (musb->xceiv->state ==OTG_STATE_B_IDLE )mod_timer (&glue->timer[pdev->id], jiffies + wrp->poll_seconds *HZ ); - +out:spin_unlock_irqrestore (&musb->lock, flags);return ret;
@@ -447,9 +440,6 @@ static int dsps_musb_init(struct musb *musb) val &= ~(1 << wrp->otg_disable);dsps_writel (musb->ctrl_base, wrp->phy_utmi, val); -/* clear level interrupt */ -dsps_writel (reg_base, wrp->eoi,0 ); -return 0 ; err0:usb_put_phy (musb->xceiv);
@@ -746,7 +736,6 @@ static const struct dsps_musb_wrapper am33xx_driver_data = { .revision = 0x00, .control = 0x14, .status = 0x18, - .eoi = 0x24, .epintr_set = 0x38, .epintr_clear = 0x40, .epintr_status = 0x30,
Signature · 1 line
1.8.3.2
Re: [PATCH 06/16] usb: musb: dsps: rename ti81xx_driver_data to am33xx_driver_data
In reply to Sebastian Andrzej SiewiorHi,
Quoted 17 lines · Sebastian Andrzej Siewior
Quoted 1 line · Bin Liu
Sebastian,
Hi Bin,
Quoted 4 lines
Quoted 2 lines
Is it really there or was it never there and it has been added to TRM by accident?
The EOI register IS in the USB subsystem of AM33xx, but the SoC does not use it because it uses level triggering for USB interrupt.
I see.
Quoted 5 lines
Quoted 5 lines
Quoted 4 lines
But I am not sure if it is a good idea to remove eoi from the
musb_dspsdriver. If the intension is to merge the support for other SoC, such as AM35xx, AM18xx, then EOI handling might be still needed. I just don't know how those devices use EOI.
Quoted 7 lines
Quoted 5 lines
Quoted 2 lines
If one of the architectures gets added which need an EOI then the offset can be 0 and the EOI will happen only if it is != 0.
This patch cleaned up the use of EOI. Do you mean EOI handling will be added back with condition EOI offset != 0, when the support of new device which uses EIO is added?
That is my intention.
right, I agree. If there are no users for the code, just delete it. If, eventually, some platform comes to need it, then we add it *after* the platform's base code is merged.
Signature · 1 line
balbi
PATCH 7/16 usb: musb: replace ifndef with ifdef for CONFIG_MUSB_PIO_ONLY
In reply to Sebastian Andrzej SiewiorThe ifdef reads somehow better than an ifndef
--- drivers/usb/musb/musb_dma.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/usb/musb/musb_dma.h +3 -3
@@ -62,10 +62,10 @@ struct musb_hw_ep;#define DMA_ADDR_INVALID (~(dma_addr_t)0) -#ifndef CONFIG_MUSB_PIO_ONLY -#define is_dma_capable () (1) -#else +#ifdef CONFIG_MUSB_PIO_ONLY #define is_dma_capable () (0) +#else +#define is_dma_capable () (1)#endif #ifdef CONFIG_USB_TI_CPPI_DMA
Signature · 1 line
1.8.3.2
PATCH 8/16 usb: musb: dma: merge ->start/stop into create/destroy
In reply to Sebastian Andrzej SiewiorThe core code creates a controller and immediately after that it calls the ->start() callback. This one might drop an error but nobody cares. The same thing happens in the destroy corner: First ->stop() called followed by destroy callback. So why not merge those two into the same function since there is no difference.
--- drivers/usb/musb/cppi_dma.c | 18 +++++------------- drivers/usb/musb/musb_core.c | 18 ++++-------------- drivers/usb/musb/musb_dma.h | 2 -- drivers/usb/musb/musbhsdma.c | 16 +++------------- drivers/usb/musb/tusb6010_omap.c | 24 ------------------------ drivers/usb/musb/ux500_dma.c | 19 ++++++++----------- 6 files changed, 20 insertions(+), 77 deletions(-)
drivers/usb/musb/cppi_dma.c +5 -13
@@ -150,14 +150,11 @@ static void cppi_pool_free(struct cppi_channel *c) c->last_processed =NULL ; } -static int cppi_controller_start (struct dma_controller *c) +static void cppi_controller_start (struct cppi *controller) { -struct cppi *controller;void __iomem *tibase;int i; - controller = container_of(c, struct cppi, controller); -/* do whatever is necessary to start controller */ for (i =0 ; i <ARRAY_SIZE (controller->tx); i++) { controller->tx[i].transmit = true;
@@ -212,8 +209,6 @@ static int cppi_controller_start(struct dma_controller *c)/* disable RNDIS mode, also host rx RNDIS autorequest */ musb_writel (tibase,DAVINCI_RNDIS_REG ,0 );musb_writel (tibase,DAVINCI_AUTOREQ_REG ,0 ); - -return 0 ; }/*
@@ -222,14 +217,12 @@ static int cppi_controller_start(struct dma_controller *c)* De-Init the DMA controller as necessary. */ -static int cppi_controller_stop (struct dma_controller *c) +static void cppi_controller_stop (struct cppi *controller) { -struct cppi *controller;void __iomem *tibase;int i;struct musb *musb; - controller = container_of(c, struct cppi, controller); musb = controller->musb; tibase = controller->tibase;
@@ -255,8 +248,6 @@ static int cppi_controller_stop(struct dma_controller *c)/*disable tx/rx cppi */ musb_writel (tibase,DAVINCI_TXCPPI_CTRL_REG ,DAVINCI_DMA_CTRL_DISABLE );musb_writel (tibase,DAVINCI_RXCPPI_CTRL_REG ,DAVINCI_DMA_CTRL_DISABLE ); - -return 0 ; }/* While dma channel is allocated, we only want the core irqs active
@@ -1321,8 +1312,6 @@ struct dma_controller *dma_controller_create(struct musb *musb, void __iomem *mr controller->tibase = mregs -DAVINCI_BASE_OFFSET ; controller->musb = musb; - controller->controller.start = cppi_controller_start; - controller->controller.stop = cppi_controller_stop; controller->controller.channel_alloc = cppi_channel_allocate; controller->controller.channel_release = cppi_channel_release; controller->controller.channel_program = cppi_channel_program;
@@ -1351,6 +1340,7 @@ struct dma_controller *dma_controller_create(struct musb *musb, void __iomem *mr controller->irq = irq; } +cppi_controller_start (controller);return &controller->controller; }
@@ -1363,6 +1353,8 @@ void dma_controller_destroy(struct dma_controller *c) cppi = container_of(c, struct cppi, controller); +cppi_controller_stop (cppi); +if (cppi->irq)free_irq (cppi->irq, cppi->musb);
drivers/usb/musb/musb_core.c +4 -14
@@ -1764,12 +1764,8 @@ static void musb_free(struct musb *musb)disable_irq_wake (musb->nIrq);free_irq (musb->nIrq, musb); } -if (is_dma_capable () && musb->dma_controller) { -struct dma_controller *c = musb->dma_controller; - - (void ) c->stop (c); -dma_controller_destroy (c); - } +if (is_dma_capable () && musb->dma_controller) +dma_controller_destroy (musb->dma_controller);musb_host_free (musb); }
@@ -1845,14 +1841,8 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl)pm_runtime_get_sync (musb->controller);#ifndef CONFIG_MUSB_PIO_ONLY -if (use_dma && dev->dma_mask) { -struct dma_controller *c; - - c =dma_controller_create (musb, musb->mregs); - musb->dma_controller = c; -if (c) - (void ) c->start (c); - } +if (use_dma && dev->dma_mask) + musb->dma_controller =dma_controller_create (musb, musb->mregs);#endif /* ideally this would be abstracted in platform setup */ if (!is_dma_capable () || !musb->dma_controller)
drivers/usb/musb/musb_dma.h +0 -2
@@ -159,8 +159,6 @@ dma_channel_status(struct dma_channel *c)* Controllers manage dma channels. */ struct dma_controller { -int (*start)(struct dma_controller *); -int (*stop)(struct dma_controller *);struct dma_channel *(*channel_alloc)(struct dma_controller *,struct musb_hw_ep *,u8 is_tx);void (*channel_release)(struct dma_channel *);
drivers/usb/musb/musbhsdma.c +3 -13
@@ -37,18 +37,10 @@#include "musb_core.h" #include "musbhsdma.h" -static int dma_controller_start (struct dma_controller *c) -{ -/* nothing to do */ -return 0 ; -} -static void dma_channel_release (struct dma_channel *channel); -static int dma_controller_stop (struct dma_controller *c) +static void dma_controller_stop (struct musb_dma_controller *controller) { -struct musb_dma_controller *controller =container_of (c, - struct musb_dma_controller, controller);struct musb *musb = controller->private_data;struct dma_channel *channel;u8 bit;
@@ -67,8 +59,6 @@ static int dma_controller_stop(struct dma_controller *c) } } } - -return 0 ; } static struct dma_channel *dma_channel_allocate(struct dma_controller *c,
@@ -374,6 +364,8 @@ void dma_controller_destroy(struct dma_controller *c)if (!controller)return ; +dma_controller_stop (controller); +if (controller->irq)free_irq (controller->irq, c);
@@ -400,8 +392,6 @@ struct dma_controller *dma_controller_create(struct musb *musb, void __iomem *ba controller->private_data = musb; controller->base = base; - controller->controller.start = dma_controller_start; - controller->controller.stop = dma_controller_stop; controller->controller.channel_alloc = dma_channel_allocate; controller->controller.channel_release = dma_channel_release; controller->controller.channel_program = dma_channel_program;
drivers/usb/musb/tusb6010_omap.c +0 -24
@@ -66,28 +66,6 @@ struct tusb_omap_dma { unsigned multichannel:1; }; -static int tusb_omap_dma_start (struct dma_controller *c) -{ -struct tusb_omap_dma *tusb_dma; - - tusb_dma = container_of(c, struct tusb_omap_dma, controller); - -/* dev_dbg(musb->controller, "ep%i ch: %i\n", chdat->epnum, chdat->ch); */ - -return 0 ; -} - -static int tusb_omap_dma_stop (struct dma_controller *c) -{ -struct tusb_omap_dma *tusb_dma; - - tusb_dma = container_of(c, struct tusb_omap_dma, controller); - -/* dev_dbg(musb->controller, "ep%i ch: %i\n", chdat->epnum, chdat->ch); */ - -return 0 ; -} -/* * Allocate dmareq0 to the current channel unless it's already taken */
@@ -695,8 +673,6 @@ struct dma_controller *dma_controller_create(struct musb *musb, void __iomem *ba tusb_dma->dmareq =-1 ; tusb_dma->sync_dev =-1 ; - tusb_dma->controller.start = tusb_omap_dma_start; - tusb_dma->controller.stop = tusb_omap_dma_stop; tusb_dma->controller.channel_alloc = tusb_omap_dma_allocate; tusb_dma->controller.channel_release = tusb_omap_dma_release; tusb_dma->controller.channel_program = tusb_omap_dma_program;
drivers/usb/musb/ux500_dma.c +8 -11
@@ -254,10 +254,8 @@ static int ux500_dma_channel_abort(struct dma_channel *channel)return 0 ; } -static int ux500_dma_controller_stop (struct dma_controller *c) +static void ux500_dma_controller_stop (struct ux500_dma_controller *controller) { -struct ux500_dma_controller *controller =container_of (c, - struct ux500_dma_controller, controller);struct ux500_dma_channel *ux500_channel;struct dma_channel *channel;u8 ch_num;
@@ -281,14 +279,10 @@ static int ux500_dma_controller_stop(struct dma_controller *c)if (ux500_channel->dma_chan)dma_release_channel (ux500_channel->dma_chan); } - -return 0 ; } -static int ux500_dma_controller_start (struct dma_controller *c) +static int ux500_dma_controller_start (struct ux500_dma_controller *controller) { -struct ux500_dma_controller *controller =container_of (c, - struct ux500_dma_controller, controller);struct ux500_dma_channel *ux500_channel =NULL ;struct musb *musb = controller->private_data;struct device *dev = musb->controller;
@@ -347,7 +341,7 @@ static int ux500_dma_controller_start(struct dma_controller *c) dir, ch_num);/* Release already allocated channels */ -ux500_dma_controller_stop (c); +ux500_dma_controller_stop (controller);return -EBUSY ; }
@@ -369,6 +363,7 @@ void dma_controller_destroy(struct dma_controller *c)struct ux500_dma_controller *controller =container_of (c, struct ux500_dma_controller, controller); +ux500_dma_controller_stop (controller);kfree (controller); }
@@ -378,6 +373,7 @@ struct dma_controller *dma_controller_create(struct musb *musb,struct ux500_dma_controller *controller;struct platform_device *pdev =to_platform_device (musb->controller);struct resource *iomem; +int ret; controller =kzalloc (sizeof (*controller),GFP_KERNEL );if (!controller)
@@ -394,14 +390,15 @@ struct dma_controller *dma_controller_create(struct musb *musb, controller->phy_base = (dma_addr_t ) iomem->start; - controller->controller.start = ux500_dma_controller_start; - controller->controller.stop = ux500_dma_controller_stop; controller->controller.channel_alloc = ux500_dma_channel_allocate; controller->controller.channel_release = ux500_dma_channel_release; controller->controller.channel_program = ux500_dma_channel_program; controller->controller.channel_abort = ux500_dma_channel_abort; controller->controller.is_compatible = ux500_dma_is_compatible; + ret =ux500_dma_controller_start (controller); +if (ret) + goto plat_get_fail;return &controller->controller; plat_get_fail:
Signature · 1 line
1.8.3.2
PATCH 9/16 usb: musb: provide empty dma_controller_create() in PIO mode
In reply to Sebastian Andrzej SiewiorAdd a dma_controller_create() returning NULL so a few ifdefs can dropped.
--- drivers/usb/musb/musb_dma.h | 11 +++++++++++ 1 file changed, 11 insertions(+)
drivers/usb/musb/musb_dma.h +11 -0
@@ -175,9 +175,20 @@ struct dma_controller {/* called after channel_program(), may indicate a fault */ extern void musb_dma_completion (struct musb *musb,u8 epnum,u8 transmit); +#ifdef CONFIG_MUSB_PIO_ONLY +static inline struct dma_controller *dma_controller_create (struct musb *m, +void __iomem *io) +{ +return NULL ; +} + +static inline void dma_controller_destroy (struct dma_controller *d) { } + +#else extern struct dma_controller *dma_controller_create (struct musb *,void __iomem *);extern void dma_controller_destroy (struct dma_controller *); +#endif #endif /* __MUSB_DMA_H__ */
Signature · 1 line
1.8.3.2
PATCH 10/16 usb: musb: remove a few is_dma_capable() in init/exit code
In reply to Sebastian Andrzej SiewiorThis patch removes is_dma_capable() and an ifdef in the init/exit path around init/de-init of the dma_controller. Since we have the empty stubs in the PIO code we can call it without gcc trouble. Earlier we had an ifdef and the is_dma_capable() macro where gcc ignored the if (0) path even that the function was not around :)
--- drivers/usb/musb/musb_core.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-)
drivers/usb/musb/musb_core.c +3 -4
@@ -1764,7 +1764,7 @@ static void musb_free(struct musb *musb)disable_irq_wake (musb->nIrq);free_irq (musb->nIrq, musb); } -if (is_dma_capable () && musb->dma_controller) +if (musb->dma_controller)dma_controller_destroy (musb->dma_controller);musb_host_free (musb);
@@ -1840,12 +1840,11 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl)pm_runtime_get_sync (musb->controller); -#ifndef CONFIG_MUSB_PIO_ONLY if (use_dma && dev->dma_mask) musb->dma_controller =dma_controller_create (musb, musb->mregs); -#endif +/* ideally this would be abstracted in platform setup */ -if (!is_dma_capable () || !musb->dma_controller) +if (!musb->dma_controller) dev->dma_mask =NULL ;/* be sure interrupts are disabled before connecting ISR */
Signature · 1 line
1.8.3.2
PATCH 11/16 usb: musb: core: call dma_controller_destroy() in the err path
In reply to Sebastian Andrzej SiewiorThe cleanup in the error is missing the dma controller. The structure is allocated at runtime and ux500 allocates even a little more than just this struct. So cleanup!
--- drivers/usb/musb/musb_core.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/usb/musb/musb_core.c +2 -0
@@ -1933,6 +1933,8 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl)musb_gadget_cleanup (musb); fail3: +if (musb->dma_controller) +dma_controller_destroy (musb->dma_controller);pm_runtime_put_sync (musb->controller); fail2:
Signature · 1 line
1.8.3.2
PATCH 12/16 usb: musb: unmap reqs in musb_gadget_queue()'s error case
In reply to Sebastian Andrzej SiewiorIf the descriptor is missing the reqeust is never unmapped. This patch changes this and renames the cleanup label to unlock since there is no cleanup done. The cleanup would revert the allocation of ressource (i.e. this dma mapping) but it does not, it simply unlocks and returns.
--- drivers/usb/musb/musb_gadget.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
drivers/usb/musb/musb_gadget.c +3 -2
@@ -1266,7 +1266,8 @@ static int musb_gadget_queue(struct usb_ep *ep, struct usb_request *req,dev_dbg (musb->controller,"req %p queued to %s while ep %s\n" , req, ep->name,"disabled" ); status = -ESHUTDOWN ; - goto cleanup; +unmap_dma_buffer (request, musb); + goto unlock; }/* add request to the list */
@@ -1276,7 +1277,7 @@ static int musb_gadget_queue(struct usb_ep *ep, struct usb_request *req,if (!musb_ep->busy && &request->list == musb_ep->req_list.next)musb_ep_restart (musb, request); -cleanup: +unlock:spin_unlock_irqrestore (&musb->lock, lockflags);return status; }
Signature · 1 line
1.8.3.2
PATCH 13/16 usb: musb: do not change dev's dma_mask
In reply to Sebastian Andrzej SiewiorCommit 8d2421e ("usb: musb: kill global and static for multi instance") removed the global dma_mask copy and replaced by parent's DMA mask. The problem here is that if the parent does not have a dma_mask then musb_remove() goes kaboom.
Instead trying to fix this I was thinking we do we need to erase dma_mask in the first place?
--- drivers/usb/musb/musb_core.c | 7 ------- 1 file changed, 7 deletions(-)
drivers/usb/musb/musb_core.c +0 -7
@@ -1843,10 +1843,6 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl)if (use_dma && dev->dma_mask) musb->dma_controller =dma_controller_create (musb, musb->mregs); -/* ideally this would be abstracted in platform setup */ -if (!musb->dma_controller) - dev->dma_mask =NULL ; -/* be sure interrupts are disabled before connecting ISR */ musb_platform_disable (musb);musb_generic_disable (musb);
@@ -1993,9 +1989,6 @@ static int musb_remove(struct platform_device *pdev)musb_free (musb);device_init_wakeup (dev,0 ); -#ifndef CONFIG_MUSB_PIO_ONLY -dma_set_mask (dev, *dev->parent->dma_mask); -#endif return 0 ; }
Signature · 1 line
1.8.3.2
PATCH 14/16 usb: musb: dsps: add MUSB_DEVCTL_SESSION back after removal
In reply to Sebastian Andrzej SiewiorThis patch adds the MUSB_DEVCTL_SESSION back after it has been removed. If it is missing then the host session is not recognized. This bit is added initially added in musb_start() and removed after the first device disconnect.
--- drivers/usb/musb/musb_dsps.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/usb/musb/musb_dsps.c +3 -0
@@ -186,6 +186,9 @@ static void otg_timer(unsigned long _musb)dsps_writeb (musb->mregs,MUSB_DEVCTL , devctl); devctl =dsps_readb (musb->mregs,MUSB_DEVCTL ); + devctl |=MUSB_DEVCTL_SESSION ; +dsps_writeb (musb->mregs,MUSB_DEVCTL , devctl); +if (devctl &MUSB_DEVCTL_BDEVICE ) { musb->xceiv->state =OTG_STATE_B_IDLE ;MUSB_DEV_MODE (musb);
Signature · 1 line
1.8.3.2
A message that is not in the archive (sent off-list or not yet received): CADYTM3a5xzs+-VCTeKLGiRjo7JOqOJ5H4EWDACpTMovY5_ooRA@mail.gmail.com
Re: [PATCH 14/16] usb: musb: dsps: add MUSB_DEVCTL_SESSION back after removal
Quoted 1 line · Bin Liu
Hi,
Hi,
Quoted 11 lines
On Mon, Jul 22, 2013 at 1:10 PM, Sebastian Andrzej Siewior <[email protected] <mailto:[email protected]>> wrote:
This patch adds the
MUSB_DEVCTL_SESSIONback after it has been removed. If it is missing then the host session is not recognized. This bit is added initially added inmusb_start()and removed after the first device disconnect.AFAIK, after the device is disconnected, the OTG state machine will go back to B_IDLE/A_IDLE state. SESSION is not needed in this case.
Okay.
Quoted 3 lines
In OTG mode, when no device is plugged, the ID pin is floating, you can never hold the host session in this case, even set the SESSION bit. The SESSION bit will be cleared by the controller after 100ms.
In my testing the bit remains set. How is the bit supposed to come back after I connect a host device?
Quoted 3 lines
Regards,
-Bin.
Sebastian
Re: [PATCH 14/16] usb: musb: dsps: add MUSB_DEVCTL_SESSION back after removal
Hi Sebastian,
Quoted 19 lines · Sebastian Andrzej Siewior
Quoted 1 line · Bin Liu
Hi,
Hi,
Quoted 11 lines
On Mon, Jul 22, 2013 at 1:10 PM, Sebastian Andrzej Siewior <[email protected] <mailto:[email protected]>> wrote:
This patch adds the
MUSB_DEVCTL_SESSIONback after it has been removed. If it is missing then the host session is not recognized. This bit is added initially added inmusb_start()and removed after the first device disconnect.AFAIK, after the device is disconnected, the OTG state machine will go back to B_IDLE/A_IDLE state. SESSION is not needed in this case.
Quoted 8 lines
Okay.
Quoted 3 lines
In OTG mode, when no device is plugged, the ID pin is floating, you can never hold the host session in this case, even set the SESSION bit. The SESSION bit will be cleared by the controller after 100ms.
In my testing the bit remains set. How is the bit supposed to come back after I connect a host device?
The bit remains even when no device is plugged and ID ping is float? what platform do you use to test it?
'a host device'? you meant a usb device? By the otg specs, the session will not automatically start. The user/app has to issue the command, either by SRP or HNP, or something else. In TI 3.2 kernel, there is workaround in otg_timer() to _toggle_ the SESSION bit to detect if ID pin is grounded, which means a USB device is connected.
Regards,
-Bin.
Quoted 6 lines
Quoted 4 lines
Regards,
-Bin.Sebastian
Re: [PATCH 14/16] usb: musb: dsps: add MUSB_DEVCTL_SESSION back after removal
Quoted 1 line · * Bin Liu | 2013-07-23 13:55:27 [-0500]:
Hi Sebastian,
Hi Bin,
Quoted 3 lines
Quoted 2 lines
In my testing the bit remains set. How is the bit supposed to come back after I connect a host device?
The bit remains even when no device is plugged and ID ping is float?
After I set it, it remains set yes.
Quoted 1 line
what platform do you use to test it?
AM335x evm
Quoted 5 lines
'a host device'? you meant a usb device? By the otg specs, the session will not automatically start. The user/app has to issue the command, either by SRP or HNP, or something else. In TI 3.2 kernel, there is workaround in
otg_timer()to _toggle_ the SESSION bit to detect if ID pin is grounded, which means a USB device is connected.
I see. Let me check that TI kernel. The same thing happens however if the musb is configured as host (not OTG).
Quoted 2 lines
Regards,
-Bin.
Sebastian
Re: [PATCH 14/16] usb: musb: dsps: add MUSB_DEVCTL_SESSION back after removal
In reply to Bin LiuQuoted 1 line · * Bin Liu | 2013-07-23 13:55:27 [-0500]:
Hi Sebastian,
Hi Bin,
Quoted 3 lines
either by SRP or HNP, or something else. In TI 3.2 kernel, there is workaround in
otg_timer()to _toggle_ the SESSION bit to detect if ID pin is grounded, which means a USB device is connected.
I've been looking at
http://downloads.ti.com/sitara_linux/esd/AM335xSDK/latest/index_FDS.html
and I can't find what you are talking about. My MUSB_DEVCTL doesn't change after I connect a device and the SESSION bit is not set. Also I remain in a_idle state. Do you have maybe a hint for me? :)
Quoted 2 lines
Regards,
-Bin.
Sebastian
Re: [PATCH 14/16] usb: musb: dsps: add MUSB_DEVCTL_SESSION back after removal
Sebastian,
Quoted 9 lines · Sebastian Andrzej Siewior
Quoted 1 line · * Bin Liu | 2013-07-23 13:55:27 [-0500]:
Hi Sebastian,
Hi Bin,
Quoted 3 lines
either by SRP or HNP, or something else. In TI 3.2 kernel, there is workaround in
otg_timer()to _toggle_ the SESSION bit to detect if ID pin is grounded, which means a USB device is connected.
Quoted 6 lines
I've been looking at
http://downloads.ti.com/sitara_linux/esd/AM335xSDK/latest/index_FDS.htmland I can't find what you are talking about. My
MUSB_DEVCTLdoesn't change after I connect a device and the SESSION bit is not set. Also I remain ina_idlestate. Do you have maybe a hint for me? :)
In TI 3.2 kernel, the otg_timer() toggles the SESSION bit in OTG_STATE_B_IDLE state. So whenever the ID pin is grounded by connecting a device, the controller will try go into host mode. But I have no idea why your board is in a_idle not b_idle. The toggle does not handle a_idle.
Do you use the AM335x GP EVM, not the smaller StarterKit EVM, right? the USB0 port on SK EVM is device only.
But anyway, I have not seen any use case which uses micro-AB receptacle and requires such dynamic role switching. So I kind of think it is unnecessary to implement this feature.
And it is not easy to implement it in a right way, because AM335x does not have an interrupt for ID pin grounding, so we can only try to set SESSION bit in otg_timer(), but that causes 2sec VBUS pulsing on the wire, which violates the specs.
Quoted 5 lines
Quoted 3 lines
Regards,
-Bin.Sebastian
Re: [PATCH 14/16] usb: musb: dsps: add MUSB_DEVCTL_SESSION back after removal
Quoted 26 lines · Bin Liu
Sebastian,
Quoted 9 lines · Sebastian Andrzej Siewior
Quoted 1 line · * Bin Liu | 2013-07-23 13:55:27 [-0500]:
Hi Sebastian,
Hi Bin,
Quoted 3 lines
either by SRP or HNP, or something else. In TI 3.2 kernel, there is workaround in
otg_timer()to _toggle_ the SESSION bit to detect if ID pin is grounded, which means a USB device is connected.Quoted 6 lines
I've been looking at
http://downloads.ti.com/sitara_linux/esd/AM335xSDK/latest/index_FDS.htmland I can't find what you are talking about. My
MUSB_DEVCTLdoesn't change after I connect a device and the SESSION bit is not set. Also I remain ina_idlestate. Do you have maybe a hint for me? :)In TI 3.2 kernel, the
otg_timer()toggles the SESSION bit inOTG_STATE_B_IDLEstate. So whenever the ID pin is grounded by connecting a device, the controller will try go into host mode. But I have no idea why your board is ina_idlenotb_idle. The toggle does not handlea_idle.
Quoted 5 lines
Do you use the AM335x GP EVM, not the smaller StarterKit EVM, right? the USB0 port on SK EVM is device only.
But anyway, I have not seen any use case which uses micro-AB receptacle and requires such dynamic role switching. So I kind of
I meant the real customer use cases, not the EVMs ;)
Re: [PATCH 14/16] usb: musb: dsps: add MUSB_DEVCTL_SESSION back after removal
On 07/26/2013 08:17 PM, Bin Liu wrote:
Hi Bin.
Quoted 6 lines
Quoted 6 lines
In TI 3.2 kernel, the
otg_timer()toggles the SESSION bit inOTG_STATE_B_IDLEstate. So whenever the ID pin is grounded by connecting a device, the controller will try go into host mode. But I have no idea why your board is ina_idlenotb_idle. The toggle does not handlea_idle.
Quoted 8 lines
Quoted 5 lines
Do you use the AM335x GP EVM, not the smaller StarterKit EVM, right? the USB0 port on SK EVM is device only.
But anyway, I have not seen any use case which uses micro-AB receptacle and requires such dynamic role switching. So I kind of
I meant the real customer use cases, not the EVMs ;)
I am using the about the second port on am335x evm which is used as host (not OTG mode (3) but HOST (1)). If I start the timer OTG after disconnect I see that it gets back to A mode:
[ 97.570852] musb-hdrc musb-hdrc.1.auto: Poll devctl 19 (a_wait_bcon) [ 99.570306] musb-hdrc musb-hdrc.1.auto: Poll devctl 98 (a_idle) … [ 209.570259] musb-hdrc musb-hdrc.1.auto: Poll devctl 80 (a_idle)
and now the session bit is missing and never gets back so I can not plug any other device. I really have no idea what is missing here…
Sebastian
Re: [PATCH 14/16] usb: musb: dsps: add MUSB_DEVCTL_SESSION back after removal
Sebastian,
Quoted 16 lines · Sebastian Andrzej Siewior
On 07/26/2013 08:17 PM, Bin Liu wrote:
Hi Bin.
Quoted 12 lines
Quoted 11 lines
In TI 3.2 kernel, the
otg_timer()toggles the SESSION bit inOTG_STATE_B_IDLEstate. So whenever the ID pin is grounded by connecting a device, the controller will try go into host mode. But I have no idea why your board is ina_idlenotb_idle. The toggle does not handlea_idle.Do you use the AM335x GP EVM, not the smaller StarterKit EVM, right? the USB0 port on SK EVM is device only.
But anyway, I have not seen any use case which uses micro-AB receptacle and requires such dynamic role switching. So I kind of
Quoted 7 lines
Quoted 2 lines
I meant the real customer use cases, not the EVMs ;)
I am using the about the second port on am335x evm which is used as host (not OTG mode (3) but HOST (1)). If I start the timer OTG after disconnect I see that it gets back to A mode:
[ 97.570852] musb-hdrc musb-hdrc.1.auto: Poll devctl 19 (a_wait_bcon)
I don't think you are testing with the 3.2 kernel you referred from the ti.com link you mentioned above.
3.2 kernel should have no '.auto' at the end of the device name.
If it is 3.8 or later, it seems the driver does something wrong, SESSION bit should not be cleared after the device is unplugged.
Quoted 8 lines
[ 99.570306] musb-hdrc musb-hdrc.1.auto: Poll devctl 98 (a_idle) … [ 209.570259] musb-hdrc musb-hdrc.1.auto: Poll devctl 80 (a_idle)and now the session bit is missing and never gets back so I can not plug any other device. I really have no idea what is missing here…
Sebastian
Re: [PATCH 14/16] usb: musb: dsps: add MUSB_DEVCTL_SESSION back after removal
On 07/26/2013 08:29 PM, Bin Liu wrote:
Hi Bin,
Quoted 7 lines
Quoted 1 line
[ 97.570852] musb-hdrc musb-hdrc.1.auto: Poll devctl 19 (a_wait_bcon)I don't think you are testing with the 3.2 kernel you referred from the ti.com link you mentioned above.
3.2 kernel should have no '.auto' at the end of the device name.If it is 3.8 or later, it seems the driver does something wrong, SESSION bit should not be cleared after the device is unplugged.
The bit is removed in otg_timer() because the phy gets into OTG_STATE_A_WAIT_BCON.
Now, this is current HEAD + my stuff to get second port working. I downloaded v3.2 and browsed as I was looking for the workaround, never tested maybe I should…
On v3.8 from git://git.ti.com/ti-linux-kernel/ti-linux-kernel.git I don't get the second port to work. I see
[ 1.989101] usb usb1: New USB device found, idVendor=1d6b, idProduct=0002 [ 1.996361] usb usb1: New USB device strings: Mfr=3, Product=2, SerialNumber=1 [ 2.004060] usb usb1: Product: MUSB HDRC host driver [ 2.009363] usb usb1: Manufacturer: Linux 3.8.13+ musb-hcd [ 2.015183] usb usb1: SerialNumber: musb-hdrc.0.auto [ 2.033653] hub 1-0:1.0: USB hub found [ 2.037861] hub 1-0:1.0: 1 port detected
and nothing happens once I plug in the device.
Sebastian
Re: [PATCH 14/16] usb: musb: dsps: add MUSB_DEVCTL_SESSION back after removal
Sebastian,
Quoted 19 lines · Sebastian Andrzej Siewior
The bit is removed in
otg_timer()because the phy gets intoOTG_STATE_A_WAIT_BCON.Now, this is current HEAD + my stuff to get second port working. I downloaded v3.2 and browsed as I was looking for the workaround, never tested maybe I should…
On v3.8 from
git://git.ti.com/ti-linux-kernel/ti-linux-kernel.gitI don't get the second port to work. I see[ 1.989101] usb usb1: New USB device found, idVendor=1d6b, idProduct=0002 [ 1.996361] usb usb1: New USB device strings: Mfr=3, Product=2, SerialNumber=1 [ 2.004060] usb usb1: Product: MUSB HDRC host driver [ 2.009363] usb usb1: Manufacturer: Linux 3.8.13+ musb-hcd [ 2.015183] usb usb1: SerialNumber: musb-hdrc.0.auto [ 2.033653] hub 1-0:1.0: USB hub found [ 2.037861] hub 1-0:1.0: 1 port detected
Quoted 1 line
and nothing happens once I plug in the device.
I started thinking when I tried this git.ti.com 3.8 kernel, I might have done 'devmem2 0x47401c60 b 0x81' to manually set the SESSION bit after plugged a device. It was months ago, I don't quite remember what I tested.
My build server is down this afternoon. Once it comes back next week, I will try 3.8 again, to see how I can help on this USB1 host mode issue. its devctl register should stay on 0x19 even nothing is connected.
Quoted 2 lines
Sebastian
Re: [PATCH 14/16] usb: musb: dsps: add MUSB_DEVCTL_SESSION back after removal
Quoted 1 line · Bin Liu
Sebastian,
Hi Bin,
Quoted 4 lines
I started thinking when I tried this git.ti.com 3.8 kernel, I might have done 'devmem2
0x47401c60b0x81' to manually set the SESSION bit after plugged a device. It was months ago, I don't quite remember what I tested.
Ah. You cheated! :)
Quoted 4 lines
My build server is down this afternoon. Once it comes back next week, I will try 3.8 again, to see how I can help on this USB1 host mode issue. its devctl register should stay on
0x19even nothing is connected.
Your help is greatly appreciated. To hear what will happen :)
Sebastian
Re: [PATCH 14/16] usb: musb: dsps: add MUSB_DEVCTL_SESSION back after removal
Sebastian,
Quoted 8 lines · Sebastian Andrzej Siewior
Quoted 4 lines
My build server is down this afternoon. Once it comes back next week, I will try 3.8 again, to see how I can help on this USB1 host mode issue. its devctl register should stay on
0x19even nothing is connected.Your help is greatly appreciated. To hear what will happen :)
Sebastian
I have not tested it yet, but I believe I found why host mode works on TI 3.2 kernel but not on mainline. Please look at Line 786 in 3.2 kernel musb_core.c [1].
773 if ((int_usb & MUSB_INTR_DISCONNECT) && !musb->ignore_disconnect) {
......
785 if (musb->a_wait_bcon != 0 &&
786 is_otg_enabled(musb))
787 musb_platform_try_idle(musb, jiffies
788 +msecs_to_jiffies(musb->a_wait_bcon));
So when the device is unplugged, *_try_idle() is not called in host mode, then the SESSION bit will stay set. But in mainline kernel, *_try_idle() will be called regardless.
Please let me know your thoughts.
Regards,
-Bin.
Re: [PATCH 14/16] usb: musb: dsps: add MUSB_DEVCTL_SESSION back after removal
Quoted 1 line · * Bin Liu | 2013-07-26 22:07:14 [-0500]:
Sebastian,
Hi Bin,
Quoted 12 lines
I have not tested it yet, but I believe I found why host mode works on TI 3.2 kernel but not on mainline. Please look at Line 786 in 3.2 kernel
musb_core.c[1].773 if ((
int_usb&MUSB_INTR_DISCONNECT) && !musb->ignore_disconnect) {
......
785 if (musb->a_wait_bcon!= 0 &&
786is_otg_enabled(musb))
787 musb_platform_try_idle(musb, jiffies
788 +msecs_to_jiffies(musb->a_wait_bcon));
Quoted 5 lines
So when the device is unplugged,
*_try_idle()is not called in host mode, then the SESSION bit will stay set. But in mainline kernel,*_try_idle()will be called regardless.Please let me know your thoughts.
I am not too familiar with what should happen. The is_otg_enabled() part is gone since v3.7-rc1 via:
|commit 032ec49f5351e9cb242b1a1c367d14415043ab95 |Author: Felipe Balbi <[email protected]> |Date: Thu Nov 24 15:46:26 2011 +0200 | | usb: musb: drop useless board_mode usage | | we are compiling the driver always with full OTG | capabilities, so that board_mode trick becomes | useless. | | Signed-off-by: Felipe Balbi <[email protected]>
So you say, am335x-evm is not able to run OTG mode and may only run in host mode and as a consequence it must not call musb_platform_try_idle() because it throws that one bit away and there is no way to bring it back?
However, if I look at the tree you reference, I see in arch/arm/mach-omap2/board-am335xevm.c:
| static struct omap_musb_board_data musb_board_data = {
| .interface_type = MUSB_INTERFACE_ULPI,
| .mode = MUSB_OTG,
| .power = 500,
| .instances = 1,
| };…
| static void __init am335x_evm_init(void)
…
| usb_musb_init(&musb_board_data);
and it creates a "ti81xx-usbss" device.
So it creates a musb device with mode MUSB_OTG no matter what. I agree that without that try_idle part things keep working but it seems, that it is also called in the other tree.
Quoted 3 lines
Regards,
-Bin.
Sebastian
Re: [PATCH 14/16] usb: musb: dsps: add MUSB_DEVCTL_SESSION back after removal
Sebastian,
Quoted 3 lines · Sebastian Andrzej Siewior
So you say, am335x-evm is not able to run OTG mode and may only run in host mode and as a consequence it must not call
musb_platform_try_idle()because it throws that one bit away and there is no way to bring it back?
I did not say AM335xEVM is not able to run OTG mode. The problem is in OTG mode the SESSION bit will be cleared once the device is unplugged, then there is no way the SESSION bit will come back in the current mainline kernel.
The TI 3.2 kernel works around this OTG issue by toggling the SESSION bit in b_idle handling in otg_timer(). The workaround makes most users happy but it causes VBUS voltage pulsing. That is why I said I don't know an ideal solution without a ID pin interrupt support.
Quoted 9 lines
However, if I look at the tree you reference, I see in
arch/arm/mach-omap2/board-am335xevm.c:| static struct omap_musb_board_data musb_board_data = { | .interface_type = MUSB_INTERFACE_ULPI, | .mode = MUSB_OTG, | .power = 500, | .instances = 1, | };
Quoted 8 lines
…
| static void__initam335x_evm_init(void)
…
|usb_musb_init(&musb_board_data);and it creates a "ti81xx-usbss" device.
So it creates a musb device with mode
MUSB_OTGno matter what.
I think you looked at a wrong file, maybe a wrong branch. Please check [1], which defines
2644 * mode[0:3] = USB0PORT's mode 2645 * mode[4:7] = USB1PORT's mode 2646 * AM335X beta EVM has USB0 in OTG mode and USB1 in host mode. 2647 */
2648 .mode = (MUSB_HOST << 4) | MUSB_OTG,
Quoted 3 lines
I agree that without that
try_idlepart things keep working but it seems, that it is also called in the other tree.
Then because AM335xEVM USB1 port does not call *try_idle() in this 3.2 kernel, its SESSION bit is always set.
But I don't have a clear idea how to solve this in the mainline kernel since is_otg_enabled() has been cleaned.
Quoted 5 lines
Quoted 3 lines
Regards,
-Bin.Sebastian
Regards,
-Bin.
Re: [PATCH 14/16] usb: musb: dsps: add MUSB_DEVCTL_SESSION back after removal
Quoted 1 line · Bin Liu
Sebastian,
Hi Bin,
Quoted 4 lines
I did not say AM335xEVM is not able to run OTG mode. The problem is in OTG mode the SESSION bit will be cleared once the device is unplugged, then there is no way the SESSION bit will come back in the current mainline kernel.
Yes, you did.
Quoted 5 lines
The TI 3.2 kernel works around this OTG issue by toggling the SESSION bit in
b_idlehandling inotg_timer(). The workaround makes most users happy but it causes VBUS voltage pulsing. That is why I said I don't know an ideal solution without a ID pin interrupt support.
Now I understand more pieces of the puzzle. And the missing ID pin support is Am335x-evm specific since other am335x board may wire up that pin.
But you say there is no way that the phy or anything else could help to avoid that pulsing.
Quoted 8 lines
I think you looked at a wrong file, maybe a wrong branch. Please check [1], which defines
2644 * mode[0:3] = USB0PORT's mode 2645 * mode[4:7] = USB1PORT's mode 2646 * AM335X beta EVM has USB0 in OTG mode and USB1 in host mode. 2647 */2648 .mode = (
MUSB_HOST<< 4) |MUSB_OTG,
Oh it is a long way. So looked into the wrong branch.
Quoted 9 lines
Quoted 3 lines
I agree that without that
try_idlepart things keep working but it seems, that it is also called in the other tree.Then because AM335xEVM USB1 port does not call
*try_idle()in this 3.2 kernel, its SESSION bit is always set.But I don't have a clear idea how to solve this in the mainline kernel since
is_otg_enabled()has been cleaned.
So now I think this is a board problem. What about switching port 1 from OTG to HOST only and avoiding kicking the timer in dsps_musb_try_idle() in such a case? It seems we only need to do this in OTG mode.
Quoted 2 lines
Regards,
-Bin.
Sebastian
Re: [PATCH 14/16] usb: musb: dsps: add MUSB_DEVCTL_SESSION back after removal
Sebastian,
Quoted 11 lines · Sebastian Andrzej Siewior
Quoted 1 line · Bin Liu
Sebastian,
Hi Bin,
Quoted 4 lines
I did not say AM335xEVM is not able to run OTG mode. The problem is in OTG mode the SESSION bit will be cleared once the device is unplugged, then there is no way the SESSION bit will come back in the current mainline kernel.
Yes, you did.
If I did, that was wrong statement.
Quoted 10 lines
Quoted 6 lines
The TI 3.2 kernel works around this OTG issue by toggling the SESSION bit in
b_idlehandling inotg_timer(). The workaround makes most users happy but it causes VBUS voltage pulsing. That is why I said I don't know an ideal solution without a ID pin interrupt support.Now I understand more pieces of the puzzle. And the missing ID pin support is Am335x-evm specific since other am335x board may wire up that pin.
No, it is not board wiring issue. The AM335x EVM DOES have ID pin wired to the ID pin of the micro-AB receptacle. I said AM335x does not have IP pin INTERRUPT support, by which the kernel does not know when a device is plugged in without setting the SESSION bit.
Quoted 21 lines
But you say there is no way that the phy or anything else could help to avoid that pulsing.
Quoted 8 lines
I think you looked at a wrong file, maybe a wrong branch. Please check [1], which defines
2644 * mode[0:3] = USB0PORT's mode 2645 * mode[4:7] = USB1PORT's mode 2646 * AM335X beta EVM has USB0 in OTG mode and USB1 in host mode. 2647 */2648 .mode = (
MUSB_HOST<< 4) |MUSB_OTG,Oh it is a long way. So looked into the wrong branch.
Quoted 7 lines
Quoted 3 lines
I agree that without that
try_idlepart things keep working but it seems, that it is also called in the other tree.Then because AM335xEVM USB1 port does not call
*try_idle()in this 3.2 kernel, its SESSION bit is always set.
Quoted 7 lines
Quoted 2 lines
But I don't have a clear idea how to solve this in the mainline kernel since
is_otg_enabled()has been cleaned.So now I think this is a board problem. What about switching port 1 from OTG to HOST only and avoiding kicking the timer in
dsps_musb_try_idle()in such a case? It seems we only need to do this in OTG mode.
I have not read the MUSB driver in the mainline kernel yet. If somehow port 1 can could be set to HOST mode then the SESSION bit would stay, then that should solve the issue.
Quoted 5 lines
Quoted 3 lines
Regards,
-Bin.Sebastian
PATCH 1/1 usb: musb: am335x: Do not remove the session bin HOST-only mode
This is what I observe:
On the first connect, the musb starts with DEVCTL.Session set. On disconnect, musb_core calls try_idle. That functions removes the Session bit signalize that the session is over (something that only in OTG is required). A new device, that is plugged, is no longer recognized. I've setup a timer and checked the DEVCTL register and I haven't seen a change in VBus and I saw the B-Device bit set. After setting the IDDIG into A mode and forcing the device to behave like I didn't see a change. Neither VBUS goes to 0b11 nor does a session start request come. The TI-v3.2 kernel they skip to call musb_platform_try_idle() in the OTG_STATE_A_WAIT_BCON state while not in OTG mode.
Since the second port hast a standard A plug the patch changes the port to run in host mode only, force the id-pin to host only and skip the timer which would remove DEVCTL.Session.
--- arch/arm/boot/dts/am335x-evm.dts | 3 +++ drivers/usb/musb/musb_dsps.c | 13 +++++++++++++ 2 files changed, 16 insertions(+)
arch/arm/boot/dts/am335x-evm.dts +3 -0
@@ -192,6 +192,9 @@ usb@47401800 { status = "okay"; + musb1: usb@47401c00 { + port-mode = <1>; + }; }; dma@07402000 {
drivers/usb/musb/musb_dsps.c +13 -0
@@ -65,6 +65,9 @@ static inline void dsps_writeb(void __iomem *addr, unsigned offset, u8 data)static inline void dsps_writel (void __iomem *addr,unsigned offset,u32 data) {__raw_writel (data, addr + offset); } +#define USBMODE_IDDIG_A (0 << 8) +#define USBMODE_ID_MUX_REG (1 << 7) +#define USBMODE_ID_MUX_PHY (0 << 7)/** * DSPS musb wrapper register offset. * FIXME: This should be expanded to have all the wrapper registers from TI DSPS
@@ -230,6 +233,8 @@ static void dsps_musb_try_idle(struct musb *musb, unsigned long timeout) glue->last_timer = jiffies;return ; } +if (musb->port_mode ==MUSB_PORT_MODE_HOST ) +return ;if (time_after (glue->last_timer, timeout) &&timer_pending (&glue->timer)) {
@@ -388,6 +393,14 @@ static int dsps_musb_init(struct musb *musb) val &= ~(1 << wrp->otg_disable);dsps_writel (musb->ctrl_base, wrp->phy_utmi, val); +if (musb->port_mode ==MUSB_PORT_MODE_HOST ) { + val =USBMODE_IDDIG_A ; + val |=USBMODE_ID_MUX_REG ; + }else { + val =USBMODE_ID_MUX_PHY ; + } +dsps_writel (musb->ctrl_base, wrp->mode, val); +return 0 ; }
Signature · 1 line
1.8.3.2
Re: [PATCH] usb: musb: am335x: Do not remove the session bin HOST-only mode
Hello.
Quoted 16 lines · Sebastian Andrzej Siewior
This is what I observe:
On the first connect, the musb starts with DEVCTL.Session set. On disconnect,musb_corecallstry_idle. That functions removes the Session bit signalize that the session is over (something that only in OTG is required). A new device, that is plugged, is no longer recognized. I've setup a timer and checked the DEVCTL register and I haven't seen a change in VBus and I saw the B-Device bit set. After setting the IDDIG into A mode and forcing the device to behave like I didn't see a change. Neither VBUS goes to 0b11 nor does a session start request come. The TI-v3.2 kernel they skip to callmusb_platform_try_idle()in theOTG_STATE_A_WAIT_BCONstate while not in OTG mode.
Since the second port hast a standard A plug the patch changes the port to run in host mode only, force the id-pin to host only and skip the timer which would remove DEVCTL.Session.Signed-off-by Sebastian Andrzej Siewior <[email protected]>
[...]
Quoted 4 lines
drivers/usb/musb/musb_dsps.c +0
-0
[...]
drivers/usb/musb/musb_dsps.c static int dsps_musb_init(struct musb *musb) · line 398
Quoted 7 lines
drivers/usb/musb/musb_dsps.c +3
-0@@ -388,6 +393,14 @@ static int dsps_musb_init(struct musb *musb) val &= ~(1 << wrp->otg_disable);dsps_writel (musb->ctrl_base, wrp->phy_utmi, val); +if (musb->port_mode ==MUSB_PORT_MODE_HOST ) { + val =USBMODE_IDDIG_A ; + val |=USBMODE_ID_MUX_REG ;
Why not do the above in one line and save on {} {}? It will look more
aesthetically pleasing IMHO.
drivers/usb/musb/musb_dsps.c static int dsps_musb_init(struct musb *musb) · line 403
Quoted 5 lines
drivers/usb/musb/musb_dsps.c +5
-0+ }else { + val =USBMODE_ID_MUX_PHY ; + } +dsps_writel (musb->ctrl_base, wrp->mode, val); +
WBR, Sergei
Re: [PATCH] usb: musb: am335x: Do not remove the session bin HOST-only mode
Quoted 1 line · Sergei Shtylyov
Hello.
Hi Sergei,
Quoted 6 lines
drivers/usb/musb/musb_dsps.c static int dsps_musb_init(struct musb *musb) · line 398
Quoted 3 lines
drivers/usb/musb/musb_dsps.c +3
-0+if (musb->port_mode ==MUSB_PORT_MODE_HOST ) { + val =USBMODE_IDDIG_A ; + val |=USBMODE_ID_MUX_REG ;Why not do the above in one line and save on {} {}? It will look more
aesthetically pleasing IMHO.
I'm going to redo this if it is agreed that we want to fix it that way.
Sebastian
Re: [PATCH] usb: musb: am335x: Do not remove the session bin HOST-only mode
Sebastian,
Quoted 5 lines · Sebastian Andrzej Siewior
Quoted 1 line · Sergei Shtylyov
Hello.
Hi Sergei,
Quoted 8 lines
Quoted 6 lines
drivers/usb/musb/musb_dsps.c static int dsps_musb_init(struct musb *musb) · line 398
Quoted 3 lines
drivers/usb/musb/musb_dsps.c +3
-0+if (musb->port_mode ==MUSB_PORT_MODE_HOST ) { + val =USBMODE_IDDIG_A ; + val |=USBMODE_ID_MUX_REG ;Why not do the above in one line and save on {} {}? It will look more
aesthetically pleasing IMHO.I'm going to redo this if it is agreed that we want to fix it that way.
I am going to so some tests today for this. I don't object to use the mode register, but am wondering why we have to play with it for host-only mode. The ID pin is grounded for host-only mode, which should cause the same as setting mode register.
Quoted 2 lines
Sebastian
-Bin.
Re: [PATCH] usb: musb: am335x: Do not remove the session bin HOST-only mode
Quoted 1 line · Bin Liu
Sebastian,
Hi Bin,
Quoted 8 lines
Quoted 4 lines
Quoted 4 lines
drivers/usb/musb/musb_dsps.c static int dsps_musb_init(struct musb *musb) · line 398
Quoted 3 lines
drivers/usb/musb/musb_dsps.c +3
-0+if (musb->port_mode ==MUSB_PORT_MODE_HOST ) { + val =USBMODE_IDDIG_A ; + val |=USBMODE_ID_MUX_REG ;I am going to so some tests today for this. I don't object to use the mode register, but am wondering why we have to play with it for host-only mode. The ID pin is grounded for host-only mode, which should cause the same as setting mode register.
I've been looking at the wiki page and it did not mention the ID pin for the second port. If it is grounded then this piece can be removed and the magic trick is just to skip the try_idle() call.
I haven't found anything saying that it is required to clear the session bin in host mode, only in OTG. And then, I would assume to receive a session interrupt once we have the proper VBUS level which does not happen.
Quoted 1 line
-Bin.
Sebastian
Re: [PATCH] usb: musb: am335x: Do not remove the session bin HOST-only mode
Sebastian,
Quoted 9 lines · Sebastian Andrzej Siewior
Quoted 1 line · Bin Liu
Sebastian,
Hi Bin,
Quoted 4 lines
Quoted 4 lines
Quoted 4 lines
Quoted 3 lines
drivers/usb/musb/musb_dsps.c +3
-0+if (musb->port_mode ==MUSB_PORT_MODE_HOST ) { + val =USBMODE_IDDIG_A ; + val |=USBMODE_ID_MUX_REG ;
Quoted 7 lines
Quoted 4 lines
I am going to so some tests today for this. I don't object to use the mode register, but am wondering why we have to play with it for host-only mode. The ID pin is grounded for host-only mode, which should cause the same as setting mode register.
I've been looking at the wiki page and it did not mention the ID pin for the second port. If it is grounded then this piece can be removed
I thought you have already tried that without setting the mode register the session bit cannot stay set.
I am not sure if anywhere mentioned about the ID pin, but ASAIK all the different boards using am335x have ID pin grounded for host port.
Quoted 1 line
and the magic trick is just to skip the
try_idle()call.
Agreed.
Quoted 3 lines
I haven't found anything saying that it is required to clear the session bin in host mode, only in OTG. And then, I would assume to
Agreed.
Quoted 2 lines
receive a session interrupt once we have the proper VBUS level which does not happen.
The TI 3.2 kernel for am335x sets the session bit in musb_start() for host-only mode. Maybe we can do something similar in here? (I noticed mush_start() has gone in mainline, but have not got a chance to check the details...)
Quoted 4 lines
Quoted 2 lines
-Bin.
Sebastian
Re: [PATCH] usb: musb: am335x: Do not remove the session bin HOST-only mode
Quoted 1 line · Bin Liu
Sebastian,
Hi Bin,
Quoted 4 lines
Quoted 2 lines
I've been looking at the wiki page and it did not mention the ID pin for the second port. If it is grounded then this piece can be removed
I thought you have already tried that without setting the mode register the session bit cannot stay set.
This was a misunderstanding then. Sorry. I understood that the bin has to be unset and then the controller set it once a device there.
Quoted 2 lines
I am not sure if anywhere mentioned about the ID pin, but ASAIK all the different boards using am335x have ID pin grounded for host port.
evm is the only I am aware of. The evm-sk and beagle bone have just one port. Beagle bone black is not mainline.
Quoted 6 lines
Quoted 1 line
and the magic trick is just to skip the
try_idle()call.Agreed.
Quoted 3 lines
I haven't found anything saying that it is required to clear the session bin in host mode, only in OTG. And then, I would assume to
Quoted 8 lines
Agreed.
Quoted 2 lines
receive a session interrupt once we have the proper VBUS level which does not happen.
The TI 3.2 kernel for am335x sets the session bit in
musb_start()for host-only mode. Maybe we can do something similar in here? (I noticedmush_start()has gone in mainline, but have not got a chance to check the details...)
This is the case already. From musb_start()
…
if (musb->port_mode != MUSB_PORT_MODE_HOST &&
(devctl & MUSB_DEVCTL_VBUS) == MUSB_DEVCTL_VBUS) {
musb->is_active = 1;
} else {
devctl |= MUSB_DEVCTL_SESSION;
}…
Quoted 1 line
Quoted 1 line
Quoted 1 line
-Bin.
Sebastian
Re: [PATCH] usb: musb: am335x: Do not remove the session bin HOST-only mode
Sebastian,
Quoted 2 lines · Sebastian Andrzej Siewior
This was a misunderstanding then. Sorry. I understood that the bin has to be unset and then the controller set it once a device there.
You meant ID pin? I think it should be set all the time since the driver initialized for host-only mode, if it is unset, the controller has not way to know if a device is plugged or not.
Quoted 5 lines
Quoted 3 lines
I am not sure if anywhere mentioned about the ID pin, but ASAIK all the different boards using am335x have ID pin grounded for host port.
evm is the only I am aware of. The evm-sk and beagle bone have just one port. Beagle bone black is not mainline.
You meant the dts only supports one port for evm-sk and bone? The boards physically have two ports, usb0 is device only, usb1 is host only.
Quoted 9 lines
This is the case already. From
musb_start()
…if (musb->port_mode != MUSB_PORT_MODE_HOST && (devctl & MUSB_DEVCTL_VBUS) == MUSB_DEVCTL_VBUS) { musb->is_active = 1; } else { devctl |= MUSB_DEVCTL_SESSION; }…
great! then the host port on gp evm should work now, right?
Quoted 4 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
-Bin.
Sebastian
Re: [PATCH] usb: musb: am335x: Do not remove the session bin HOST-only mode
Quoted 1 line · Bin Liu
Sebastian,
Hi Bin,
Quoted 7 lines
Quoted 2 lines · Sebastian Andrzej Siewior
This was a misunderstanding then. Sorry. I understood that the bin has to be unset and then the controller set it once a device there.
You meant ID pin? I think it should be set all the time since the driver initialized for host-only mode, if it is unset, the controller has not way to know if a device is plugged or not.
Okay.
Quoted 7 lines
Quoted 4 lines
Quoted 2 lines
I am not sure if anywhere mentioned about the ID pin, but ASAIK all the different boards using am335x have ID pin grounded for host port.
evm is the only I am aware of. The evm-sk and beagle bone have just one port. Beagle bone black is not mainline.
You meant the dts only supports one port for evm-sk and bone? The boards physically have two ports, usb0 is device only, usb1 is host only.
Where is my memory going? So now I have a beagle bone in front of me and I see a micro USB port a standard A connector. My memory was different.
The micro USB is the UART and standard is most likely the first musb instance. So this should run also in host mode and not in OTG mode. Hmmm. Let me double check this.
Quoted 10 lines
Quoted 9 lines
This is the case already. From
musb_start()
…if (musb->port_mode != MUSB_PORT_MODE_HOST && (devctl & MUSB_DEVCTL_VBUS) == MUSB_DEVCTL_VBUS) { musb->is_active = 1; } else { devctl |= MUSB_DEVCTL_SESSION; }…
great! then the host port on gp evm should work now, right?
With the change where don't can try_idle() in host mode, yes.
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
-Bin.
Sebastian
Re: [PATCH] usb: musb: am335x: Do not remove the session bin HOST-only mode
Sebastian,
Quoted 6 lines · Sebastian Andrzej Siewior
Where is my memory going? So now I have a beagle bone in front of me and I see a micro USB port a standard A connector. My memory was different.
The micro USB is the UART and standard is most likely the first musb instance. So this should run also in host mode and not in OTG mode. Hmmm. Let me double check this.
I don't know how dts instances both in mainline, but I would think if you create two musb instances, and load a gadget driver for this micro USB port, the USB host should enumerate it. The standard port should be the 2nd instance which has its ID pin grounded and work in host-only mode.
This is how they work in TI 3.2 kernel.
Quoted 3 lines
Sebastian
Re: [PATCH] usb: musb: am335x: Do not remove the session bin HOST-only mode
Quoted 1 line · Bin Liu
Sebastian,
Hi Bin,
Quoted 8 lines
Quoted 6 lines · Sebastian Andrzej Siewior
Where is my memory going? So now I have a beagle bone in front of me and I see a micro USB port a standard A connector. My memory was different.
The micro USB is the UART and standard is most likely the first musb instance. So this should run also in host mode and not in OTG mode. Hmmm. Let me double check this.
Quoted 7 lines
I don't know how dts instances both in mainline, but I would think if you create two musb instances, and load a gadget driver for this micro USB port, the USB host should enumerate it. The standard port should be the 2nd instance which has its ID pin grounded and work in host-only mode.
This is how they work in TI 3.2 kernel.
So I tried to boot my beagle bone board to figure out if they use the first or the second port in host mode (but it doesn't boot). The tiny micro USB plug is 100% for UART and not wired up to MUSB.
Any comments on that patch? I would remove the ID pin changes and repost if you don't mind.
Quoted 1 line
Quoted 1 line
Sebastian
Sebastian
Re: [PATCH] usb: musb: am335x: Do not remove the session bin HOST-only mode
Sebastian,
Quoted 3 lines · Sebastian Andrzej Siewior
So I tried to boot my beagle bone board to figure out if they use the first or the second port in host mode (but it doesn't boot). The tiny micro USB plug is 100% for UART and not wired up to MUSB.
I have not run the mainline kernel on beagle bone yet, so I cannot comment how it works, and it does not surprise if something is broken since this is what you are trying to fix ;)
But I just booted my beagle bone with the out-of-box SD card which has Angstrom 3.2.34 kernel. The USB0 port is in device mode with g_mass_storage.ko loaded, and USB1 is in host-only mode.
Quoted 2 lines
Any comments on that patch? I would remove the ID pin changes and repost if you don't mind.
That is okay to me, as long as both USB ports on the GP evm work.
-Bin.
PATCH 15/16 dmaengine: add transfered member to dma_async_tx_descriptor
In reply to Sebastian Andrzej SiewiorIn USB RX path it is possible that the we receive less bytes than requested. Take the following example:
The driver for USB-to-UART submits an URB with 256 bytes in size and the dmaengine driver in turn programs a transfer of 256 bytes. The transfer is programmed and the dma engine waits for the data to arrive. Once data is sent on the UART the dma engine begins to move data. If there was only one data byte in the USB packet received then the DMA engine will only move one byte due to USB restrictions / rules. The real size of the transfer has to be notified to the user / caller so he set this to the caller.
This patch adds the transfered member to the dma_async_tx_descriptor where the caller can obtain the final size.
--- include/linux/dmaengine.h | 3 +++ 1 file changed, 3 insertions(+)
include/linux/dmaengine.h +3 -0
@@ -403,6 +403,8 @@ typedef void (*dma_async_tx_callback)(void *dma_async_param);* @tx_submit: set the prepared descriptor(s) to be executed by the engine * @callback: routine to call after this operation is complete * @callback_param: general parameter to pass to the callback routine +* @transfered: number of bytes that were really transfered in case the channel +* transfered less than requested. * ---async_tx api specific fields--- * @next: at completion submit this descriptor * @parent: pointer to the next level up in the dependency chain
@@ -416,6 +418,7 @@ struct dma_async_tx_descriptor {dma_cookie_t (*tx_submit)(struct dma_async_tx_descriptor *tx);dma_async_tx_callback callback;void *callback_param; +unsigned int transfered;#ifdef CONFIG_ASYNC_TX_ENABLE_CHANNEL_SWITCH struct dma_async_tx_descriptor *next;struct dma_async_tx_descriptor *parent;
Signature · 1 line
1.8.3.2
Re: [PATCH 15/16] dmaengine: add transfered member to dma_async_tx_descriptor
Quoted 34 lines · Sebastian Andrzej Siewior
In USB RX path it is possible that the we receive less bytes than requested. Take the following example:
The driver for USB-to-UART submits an URB with 256 bytes in size and the dmaengine driver in turn programs a transfer of 256 bytes. The transfer is programmed and the dma engine waits for the data to arrive. Once data is sent on the UART the dma engine begins to move data. If there was only one data byte in the USB packet received then the DMA engine will only move one byte due to USB restrictions / rules. The real size of the transfer has to be notified to the user / caller so he set this to the caller.
This patch adds the transfered member to thedma_async_tx_descriptorwhere the caller can obtain the final size.Cc Vinod Koul <[email protected]>Cc Dan Williams <[email protected]>Signed-off-by Sebastian Andrzej Siewior <[email protected]>--- include/linux/dmaengine.h | 3 +++ 1 file changed, 3 insertions(+)include/linux/dmaengine.h +2
-0@@ -403,6 +403,8 @@ typedef void (*dma_async_tx_callback)(void *dma_async_param);* @tx_submit: set the prepared descriptor(s) to be executed by the engine * @callback: routine to call after this operation is complete * @callback_param: general parameter to pass to the callback routine +* @transfered: number of bytes that were really transfered in case the channel +* transfered less than requested. * ---async_tx api specific fields--- * @next: at completion submit this descriptor * @parent: pointer to the next level up in the dependency chain
include/linux/dmaengine.h struct dma_async_tx_descriptor { · line 421
Quoted 4 lines
include/linux/dmaengine.h +1
-0@@ -416,6 +418,7 @@ struct dma_async_tx_descriptor {dma_cookie_t (*tx_submit)(struct dma_async_tx_descriptor *tx);dma_async_tx_callback callback;void *callback_param; +unsigned int transfered;
Correct grammar is "transferred".
WBR, Sergei
Re: [PATCH 15/16] dmaengine: add transfered member to dma_async_tx_descriptor
Quoted 7 lines · Sergei Shtylyov
include/linux/dmaengine.h struct dma_async_tx_descriptor { · line 421
Quoted 5 lines
include/linux/dmaengine.h +1
-0@@ -416,6 +418,7 @@ struct dma_async_tx_descriptor {dma_cookie_t (*tx_submit)(struct dma_async_tx_descriptor *tx);dma_async_tx_callback callback;void *callback_param; +unsigned int transfered;Correct grammar is "transferred".
Thanks, corrected.
Quoted 2 lines
WBR, Sergei
Sebastian
Re: [PATCH 15/16] dmaengine: add transfered member to dma_async_tx_descriptor
In reply to Sebastian Andrzej SiewiorQuoted 4 lines · Sebastian Andrzej Siewior
In USB RX path it is possible that the we receive less bytes than requested. Take the following example:
The driver for USB-to-UART submits an URB with 256 bytes in size and the dmaengine driver in turn programs a transfer of 256 bytes. The transfer
Quoted 8 lines
is programmed and the dma engine waits for the data to arrive. Once data is sent on the UART the dma engine begins to move data. If there was only one data byte in the USB packet received then the DMA engine will only move one byte due to USB restrictions / rules. The real size of the transfer has to be notified to the user / caller so he set this to the caller.
This patch adds the transfered member to thedma_async_tx_descriptorwhere the caller can obtain the final size.
I'm not sure that this will work. Once you've submitted the descriptor it is owned by the dmaengine driver and you are not allowed to dereference it anymore since the dmaengine driver might free the memory at any time. You should only reference the descriptor by the cookie returned by submit().
- Lars
Re: [PATCH 15/16] dmaengine: add transfered member to dma_async_tx_descriptor
Quoted 4 lines · Lars-Peter Clausen
I'm not sure that this will work. Once you've submitted the descriptor it is owned by the dmaengine driver and you are not allowed to dereference it anymore since the dmaengine driver might free the memory at any time. You should only reference the descriptor by the cookie returned by
submit().
I see. But it can't be reused before calling the callback if it is going to call the callback, right?
So if this is a no-no, I'm left with an additional argument to the complete callback?
Quoted 1 line
- Lars
Sebastian
Re: [PATCH 15/16] dmaengine: add transfered member to dma_async_tx_descriptor
Quoted 10 lines · Sebastian Andrzej Siewior
Quoted 4 lines · Lars-Peter Clausen
I'm not sure that this will work. Once you've submitted the descriptor it is owned by the dmaengine driver and you are not allowed to dereference it anymore since the dmaengine driver might free the memory at any time. You should only reference the descriptor by the cookie returned by
submit().I see. But it can't be reused before calling the callback if it is going to call the callback, right?
So if this is a no-no, I'm left with an additional argument to the complete callback?
Hm, maybe using dmaengine_tx_status() and checking the residue field of the state struct. transferred is basically len - residue.
Re: [PATCH 15/16] dmaengine: add transfered member to dma_async_tx_descriptor
Quoted 7 lines · Lars-Peter Clausen
Quoted 4 lines
I see. But it can't be reused before calling the callback if it is going to call the callback, right?
So if this is a no-no, I'm left with an additional argument to the complete callback?Hm, maybe using
dmaengine_tx_status()and checking the residue field of the state struct. transferred is basically len - residue.
This might actually work. So this would reduce the patch to simply update the kernel doc for residue in struct dma_tx_state that it might also be valid for DMA_SUCCESS.
Sebastian
Re: [PATCH 15/16] dmaengine: add transfered member to dma_async_tx_descriptor
In reply to Sebastian Andrzej SiewiorQuoted 34 lines · Sebastian Andrzej Siewior
In USB RX path it is possible that the we receive less bytes than requested. Take the following example:
The driver for USB-to-UART submits an URB with 256 bytes in size and the dmaengine driver in turn programs a transfer of 256 bytes. The transfer is programmed and the dma engine waits for the data to arrive. Once data is sent on the UART the dma engine begins to move data. If there was only one data byte in the USB packet received then the DMA engine will only move one byte due to USB restrictions / rules. The real size of the transfer has to be notified to the user / caller so he set this to the caller.
This patch adds the transfered member to thedma_async_tx_descriptorwhere the caller can obtain the final size.Cc Vinod Koul <[email protected]>Cc Dan Williams <[email protected]>Signed-off-by Sebastian Andrzej Siewior <[email protected]>--- include/linux/dmaengine.h | 3 +++ 1 file changed, 3 insertions(+)include/linux/dmaengine.h +2
-0@@ -403,6 +403,8 @@ typedef void (*dma_async_tx_callback)(void *dma_async_param);* @tx_submit: set the prepared descriptor(s) to be executed by the engine * @callback: routine to call after this operation is complete * @callback_param: general parameter to pass to the callback routine +* @transfered: number of bytes that were really transfered in case the channel +* transfered less than requested. * ---async_tx api specific fields--- * @next: at completion submit this descriptor * @parent: pointer to the next level up in the dependency chain
include/linux/dmaengine.h struct dma_async_tx_descriptor { · line 421
Quoted 4 lines
include/linux/dmaengine.h +1
-0@@ -416,6 +418,7 @@ struct dma_async_tx_descriptor {dma_cookie_t (*tx_submit)(struct dma_async_tx_descriptor *tx);dma_async_tx_callback callback;void *callback_param; +unsigned int transfered;
I think this should be doable with residue as well. You can return DMA_SUCCESS for status and fill in what is NOT transfered indicating that txn completed but lesser number of bytes are valid
~Vinod
Re: [PATCH 15/16] dmaengine: add transfered member to dma_async_tx_descriptor
Quoted 8 lines · Vinod Koul
include/linux/dmaengine.h struct dma_async_tx_descriptor { · line 421
Quoted 5 lines
include/linux/dmaengine.h +1
-0@@ -416,6 +418,7 @@ struct dma_async_tx_descriptor {dma_cookie_t (*tx_submit)(struct dma_async_tx_descriptor *tx);dma_async_tx_callback callback;void *callback_param; +unsigned int transfered;I think this should be doable with residue as well. You can return
DMA_SUCCESSfor status and fill in what is NOT transfered indicating that txn completed but lesser number of bytes are valid
Yes, will do.
Quoted 3 lines
~Vinod
Sebastian
PATCH 16/16 usb/musb dma: add cppi41 dma driver
In reply to Sebastian Andrzej SiewiorThis driver is currently used by musb' cppi41 couter part. I may merge both dma engine user of musb at some point but not just yet. The driver seems to work in RX/TX mode. Canceling of transfer is missing haven't noticed any problems so far.
v1..v2:
- RX path added
- dma mode 0 & 1 is working
- device tree nodes re-created.
--- arch/arm/boot/dts/am335x-evm.dts | 4 + arch/arm/boot/dts/am33xx.dtsi | 61 +++ drivers/dma/Kconfig | 8 + drivers/dma/Makefile | 1 + drivers/dma/cppi41.c | 911 +++++++++++++++++++++++++++++++++++++++ drivers/usb/musb/Kconfig | 4 + drivers/usb/musb/Makefile | 1 + drivers/usb/musb/musb_cppi41.c | 433 +++++++++++++++++++ drivers/usb/musb/musb_dma.h | 2 +- 9 files changed, 1424 insertions(+), 1 deletion(-) create mode 100644 drivers/dma/cppi41.c create mode 100644 drivers/usb/musb/musb_cppi41.c
arch/arm/boot/dts/am335x-evm.dts +4 -0
@@ -189,6 +189,10 @@ usb@47401800 { status = "okay"; }; + + dma@07402000 { + status = "okay"; + }; }; i2c1: i2c@4802a000 {
arch/arm/boot/dts/am33xx.dtsi +61 -0
75 lines not on this page · raw message
drivers/dma/Kconfig +8 -0
@@ -287,6 +287,14 @@ config DMA_OMAP select DMA_ENGINE select DMA_VIRTUAL_CHANNELS +config TI_CPPI41 + tristate "AM33xx CPPI41 DMA support" + depends on ARCH_OMAP + select DMA_ENGINE + help + The Communications Port Programming Interface (CPPI) 4.1 DMA engine + is currently used by the USB driver on AM335x platforms. + config MMP_PDMA bool "MMP PDMA support" depends on (ARCH_MMP || ARCH_PXA)
drivers/dma/Makefile +1 -0
@@ -39,3 +39,4 @@ obj-$(CONFIG_MMP_TDMA) += mmp_tdma.o obj-$(CONFIG_DMA_OMAP) += omap-dma.o obj-$(CONFIG_MMP_PDMA) += mmp_pdma.o obj-$(CONFIG_DMA_JZ4740) += dma-jz4740.o +obj-$(CONFIG_TI_CPPI41) += cppi41.o
drivers/dma/cppi41.c new file +911 -0
911 lines not on this page · raw message
drivers/usb/musb/Kconfig +4 -0
@@ -129,6 +129,10 @@ config USB_TI_CPPI_DMA help Enable DMA transfers when TI CPPI DMA is available. +config USB_TI_CPPI41_DMA + bool 'TI CPPI 4.1 (AM335x)' + depends on ARCH_OMAP + config USB_TUSB_OMAP_DMA bool 'TUSB 6010' depends on USB_MUSB_TUSB6010
drivers/usb/musb/Makefile +1 -0
@@ -32,3 +32,4 @@ musb_hdrc-$(CONFIG_USB_INVENTRA_DMA) += musbhsdma.o musb_hdrc-$(CONFIG_USB_TI_CPPI_DMA) += cppi_dma.o musb_hdrc-$(CONFIG_USB_TUSB_OMAP_DMA) += tusb6010_omap.o musb_hdrc-$(CONFIG_USB_UX500_DMA) += ux500_dma.o +musb_hdrc-$(CONFIG_USB_TI_CPPI41_DMA) += musb_cppi41.o
drivers/usb/musb/musb_cppi41.c new file +433 -0
433 lines not on this page · raw message
drivers/usb/musb/musb_dma.h +1 -1
@@ -68,7 +68,7 @@ struct musb_hw_ep;#define is_dma_capable () (1)#endif -#ifdef CONFIG_USB_TI_CPPI_DMA +#if defined(CONFIG_USB_TI_CPPI_DMA ) || defined(CONFIG_USB_TI_CPPI41_DMA )#define is_cppi_enabled () 1#else #define is_cppi_enabled () 0
Signature · 1 line
1.8.3.2