Re: [RFC] AM35xx glue code for M-USB driver

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi,

(please sure you also Cc linux-usb@xxxxxxxxxxxxxxx for MUSB patches)

Rolf Peukert <rolf.peukert@xxxxxxx> writes:
> Hi,
>
> we're running a 4.x kernel on a board with an AM3505 CPU and would like
> to use device trees. The AM35xx glue code for the M-USB controller
> didn't support configuration from a DT yet. I now got it working
> somehow, but I'm not sure if I'm doing it the correct way. So this post
> is not meant as a patch submission, but more as a request for comments
> or help.
>
> In the older kernel we were using before (3.2.x), some data structures
> were set up in the respective board file and then passed to the function
> am35x_probe(). For the use with DT, I added the function
> am35x_get_config, which sets up these data structures with default
> values and then tries to read settings from the DT.
> The device .compatible declaration is now "ti,am35x-musb", so it's
> separate from "ti,omap3-musb" (as used in omap2430.c).
>
> Now the two things I'm not so sure about:
>
> a) We needed to set pointers to machine-specific functions like
> am35x_musb_clear_irq etc. These functions are implemented in
> arch/arm/mach-omap2/omap_phy_internal.c, and declared in
> arch/arm/mach-omap2/usb.h.
> As this header file can't be included easily from am35x.c, I moved the
> declarations to include/linux/platform_data/usb-omap.h. I hope that's
> OK, but would be happy about suggestions.

Yeah, those functions should not be defined under arch/arm/mach-omap2,
they need to be moved to drivers/usb/musb/am35x.c. That PHY power stuff
also needs to move to some system controller driver of some sort.

> b) The M-USB port on our board is wired as host only. If a device is
> unplugged, the driver normally goes into some idle state and waits for
> an ID signal change. But on our board that never happens.

did you route ID pin anywhere ? I hope you tied it to ground.

> So I added two checks for MUSB_OTG mode to support our hardware. Then

if your HW is host-only, why are you messing around with OTG ?

> I noticed similar code was removed from this file three years ago
> (commit 032ec49f5351e9cb242b1a1c367d14415043ab95), and I don't know if
> these lines might break something on other hardware.
>
> Best regards,
> Rolf
>
> ---
> Index: linux4/drivers/usb/musb/am35x.c
> ===================================================================
> --- linux4.orig/drivers/usb/musb/am35x.c
> +++ linux4/drivers/usb/musb/am35x.c
> @@ -188,6 +188,10 @@ static void am35x_musb_try_idle(struct m
>  {
>  	static unsigned long last_timer;
>
> +	/* do not try if not in OTG mode */
> +	if (musb->port_mode != MUSB_OTG)
> +		return;

peripheral-only and host-only configurations are valid, you should not
bail out unless OTG.

> @@ -323,8 +327,9 @@ eoi:
>  		musb_writel(reg_base, USB_END_OF_INTR_REG, 0);
>  	}
>
> -	/* Poll for ID change */
> -	if (musb->xceiv->otg->state == OTG_STATE_B_IDLE)
> +	/* Poll for ID change (in OTG mode only) */
> +	if (musb->port_mode == MUSB_OTG &&
> +		musb->xceiv->otg->state == OTG_STATE_B_IDLE)

no, this is wrong too.

> @@ -458,6 +463,70 @@ static const struct platform_device_info
>  	.dma_mask	= DMA_BIT_MASK(32),
>  };
>
> +static struct musb_hdrc_platform_data *
> +am35x_get_config(struct platform_device *pdev)
> +{
> +	struct musb_hdrc_platform_data *pdata;
> +	struct omap_musb_board_data *bdata;
> +	struct musb_hdrc_config *config;
> +	struct device_node *np;
> +	int val, ret;
> +
> +	pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
> +	if (!pdata)
> +		goto err_out;
> +
> +	bdata = devm_kzalloc(&pdev->dev, sizeof(*bdata), GFP_KERNEL);
> +	if (!bdata)
> +		goto err_pdata;
> +
> +	config = devm_kzalloc(&pdev->dev, sizeof(*config), GFP_KERNEL);
> +	if (!config)
> +		goto err_bdata;
> +
> +	/* Set defaults */
> +	config->num_eps = 16;
> +	config->ram_bits = 12;
> +	config->multipoint = true;

all of these are board-specific.

> +
> +	bdata->interface_type = MUSB_INTERFACE_UTMI;
> +	bdata->mode = MUSB_OTG;
> +	bdata->power = 500;
> +	bdata->extvbus = 1;

so are these.

> +	bdata->set_phy_power = am35x_musb_phy_power;
> +	bdata->clear_irq = am35x_musb_clear_irq;
> +	bdata->set_mode = am35x_set_mode;
> +	bdata->reset = am35x_musb_reset;
> +
> +	pdata->mode = MUSB_OTG;
> +	pdata->power = 250;

also mode and power.

> +	pdata->board_data = bdata;
> +	pdata->config = config;
> +
> +	/* Read settings from device tree */
> +	np = pdev->dev.of_node;
> +	if (np) {
> +		of_property_read_u32(np, "mode", (u32 *)&pdata->mode);
> +		of_property_read_u32(np, "interface-type",
> +				(u32 *)&bdata->interface_type);
> +		of_property_read_u32(np, "num-eps", (u32 *)&config->num_eps);
> +		of_property_read_u32(np, "ram-bits", (u32 *)&config->ram_bits);
> +		of_property_read_u32(np, "power", (u32 *)&pdata->power);
> +
> +		ret = of_property_read_u32(np, "multipoint", &val);
> +		if (!ret && val)
> +			config->multipoint = true;
> +	}
> +	return pdata;
> +
> +err_bdata:
> +	kfree(bdata);
> +err_pdata:
> +	kfree(pdata);
> +err_out:
> +	return NULL;
> +}
> +
>  static int am35x_probe(struct platform_device *pdev)
>  {
>  	struct musb_hdrc_platform_data	*pdata = dev_get_platdata(&pdev->dev);
> @@ -475,14 +544,20 @@ static int am35x_probe(struct platform_d
>  		goto err0;
>  	}
>
> -	phy_clk = clk_get(&pdev->dev, "fck");
> +	if (!pdata) {
> +		pdata = am35x_get_config(pdev);
> +		if (!pdata)
> +			goto err1;
> +	}
> +
> +	phy_clk = clk_get(&pdev->dev, "hsotgusb_fck");

why did you change the clock name ? That shouldn't be necessary.

>  	if (IS_ERR(phy_clk)) {
>  		dev_err(&pdev->dev, "failed to get PHY clock\n");
>  		ret = PTR_ERR(phy_clk);
>  		goto err3;
>  	}
>
> -	clk = clk_get(&pdev->dev, "ick");
> +	clk = clk_get(&pdev->dev, "hsotgusb_ick");

nor here.

-- 
balbi

Attachment: signature.asc
Description: PGP signature


[Index of Archives]     [Linux Arm (vger)]     [ARM Kernel]     [ARM MSM]     [Linux Tegra]     [Linux WPAN Networking]     [Linux Wireless Networking]     [Maemo Users]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite Trails]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux