Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 74c2e936 authored by Daniel Mack's avatar Daniel Mack Committed by Felipe Balbi
Browse files

usb: musb: factor out hcd initalization



The musb struct is currently allocated along with the hcd, which makes
it difficult to build a driver that only acts as gadget device.

Fix this by allocating musb directly, and keep the hcd around as
a pointer in the musb struct.

struct hc_driver musb_hc_driver can now also be static to musb_host.c,
and the macro musb_to_hcd() is just a pointer dereferencer for now, and
will be eliminated later.

Signed-off-by: default avatarDaniel Mack <zonque@gmail.com>
Acked-by: default avatarPeter Korsgaard <jacmet@sunsite.dk>
Signed-off-by: default avatarFelipe Balbi <balbi@ti.com>
parent 69ae2a70
Loading
Loading
Loading
Loading
+19 −21
Original line number Diff line number Diff line
@@ -403,6 +403,7 @@ void musb_hnp_stop(struct musb *musb)
		break;
	case OTG_STATE_B_HOST:
		dev_dbg(musb->controller, "HNP: Disabling HR\n");
		if (hcd)
			hcd->self.is_b_host = 0;
		musb->xceiv->state = OTG_STATE_B_PERIPHERAL;
		MUSB_DEV_MODE(musb);
@@ -725,7 +726,8 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb,
			dev_dbg(musb->controller, "HNP: CONNECT, now b_host\n");
b_host:
			musb->xceiv->state = OTG_STATE_B_HOST;
			hcd->self.is_b_host = 1;
			if (musb->hcd)
				musb->hcd->self.is_b_host = 1;
			del_timer(&musb->otg_timer);
			break;
		default:
@@ -766,7 +768,8 @@ b_host:
			 * in hnp_stop() is currently not used...
			 */
			musb_root_disconnect(musb);
			musb_to_hcd(musb)->self.is_b_host = 0;
			if (musb->hcd)
				musb->hcd->self.is_b_host = 0;
			musb->xceiv->state = OTG_STATE_B_PERIPHERAL;
			MUSB_DEV_MODE(musb);
			musb_g_disconnect(musb);
@@ -1706,24 +1709,18 @@ static struct musb *allocate_instance(struct device *dev,
	struct musb		*musb;
	struct musb_hw_ep	*ep;
	int			epnum;
	struct usb_hcd	*hcd;
	int			ret;

	hcd = usb_create_hcd(&musb_hc_driver, dev, dev_name(dev));
	if (!hcd)
	musb = devm_kzalloc(dev, sizeof(*musb), GFP_KERNEL);
	if (!musb)
		return NULL;
	/* usbcore sets dev->driver_data to hcd, and sometimes uses that... */

	musb = hcd_to_musb(hcd);
	INIT_LIST_HEAD(&musb->control);
	INIT_LIST_HEAD(&musb->in_bulk);
	INIT_LIST_HEAD(&musb->out_bulk);

	hcd->uses_new_polling = 1;
	hcd->has_tt = 1;

	musb->vbuserr_retry = VBUSERR_RETRY_COUNT;
	musb->a_wait_bcon = OTG_TIME_A_WAIT_BCON;
	dev_set_drvdata(dev, musb);
	musb->mregs = mbase;
	musb->ctrl_base = mbase;
	musb->nIrq = -ENODEV;
@@ -1738,7 +1735,16 @@ static struct musb *allocate_instance(struct device *dev,

	musb->controller = dev;

	ret = musb_host_alloc(musb);
	if (ret < 0)
		goto err_free;

	dev_set_drvdata(dev, musb);

	return musb;

err_free:
	return NULL;
}

static void musb_free(struct musb *musb)
@@ -1764,7 +1770,7 @@ static void musb_free(struct musb *musb)
		dma_controller_destroy(c);
	}

	usb_put_hcd(musb_to_hcd(musb));
	musb_host_free(musb);
}

/*
@@ -1781,7 +1787,6 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl)
	int			status;
	struct musb		*musb;
	struct musb_hdrc_platform_data *plat = dev->platform_data;
	struct usb_hcd		*hcd;

	/* The driver might handle more features than the board; OK.
	 * Fail when the board needs a feature that's not enabled.
@@ -1882,13 +1887,6 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl)
		musb->irq_wake = 0;
	}

	/* host side needs more setup */
	hcd = musb_to_hcd(musb);
	otg_set_host(musb->xceiv->otg, &hcd->self);
	hcd->self.otg_port = 1;
	musb->xceiv->otg->host = &hcd->self;
	hcd->power_budget = 2 * (plat->power ? : 250);

	/* program PHY to use external vBus if required */
	if (plat->extvbus) {
		u8 busctl = musb_read_ulpi_buscontrol(musb->mregs);
+1 −0
Original line number Diff line number Diff line
@@ -401,6 +401,7 @@ struct musb {
	enum musb_g_ep0_state	ep0_state;
	struct usb_gadget	g;			/* the gadget */
	struct usb_gadget_driver *gadget_driver;	/* its driver */
	struct usb_hcd		*hcd;			/* the usb hcd */

	/*
	 * FIXME: Remove this flag.
+39 −7
Original line number Diff line number Diff line
@@ -95,6 +95,11 @@
 * of transfers between endpoints, or anything clever.
 */

struct musb *hcd_to_musb(struct usb_hcd *hcd)
{
	return *(struct musb **) hcd->hcd_priv;
}


static void musb_ep_program(struct musb *musb, u8 epnum,
			struct urb *urb, int is_out,
@@ -2464,7 +2469,6 @@ static int musb_bus_resume(struct usb_hcd *hcd)
	return 0;
}


#ifndef CONFIG_MUSB_PIO_ONLY

#define MUSB_USB_DMA_ALIGN 4
@@ -2576,10 +2580,10 @@ static void musb_unmap_urb_for_dma(struct usb_hcd *hcd, struct urb *urb)
}
#endif /* !CONFIG_MUSB_PIO_ONLY */

const struct hc_driver musb_hc_driver = {
static const struct hc_driver musb_hc_driver = {
	.description		= "musb-hcd",
	.product_desc		= "MUSB HDRC host driver",
	.hcd_priv_size		= sizeof(struct musb),
	.hcd_priv_size		= sizeof(struct musb *),
	.flags			= HCD_USB2 | HCD_MEMORY,

	/* not using irq handler or reset hooks from usbcore, since
@@ -2608,16 +2612,44 @@ const struct hc_driver musb_hc_driver = {
	/* .hub_irq_enable	= NULL, */
};

int musb_host_alloc(struct musb *musb)
{
	struct device	*dev = musb->controller;

	/* usbcore sets dev->driver_data to hcd, and sometimes uses that... */
	musb->hcd = usb_create_hcd(&musb_hc_driver, dev, dev_name(dev));
	if (!musb->hcd)
		return -EINVAL;

	*musb->hcd->hcd_priv = (unsigned long) musb;
	musb->hcd->self.uses_pio_for_control = 1;
	musb->hcd->uses_new_polling = 1;
	musb->hcd->has_tt = 1;

	return 0;
}

void musb_host_cleanup(struct musb *musb)
{
	usb_remove_hcd(musb->hcd);
	musb->hcd = NULL;
}

void musb_host_free(struct musb *musb)
{
	usb_put_hcd(musb->hcd);
}

void musb_host_resume_root_hub(struct musb *musb)
{
	usb_hcd_resume_root_hub(musb_to_hcd(musb));
	usb_hcd_resume_root_hub(musb->hcd);
}

void musb_host_poke_root_hub(struct musb *musb)
{
	MUSB_HST_MODE(musb);
	if (musb_to_hcd(musb)->status_urb)
		usb_hcd_poll_rh_status(musb_to_hcd(musb));
	if (musb->hcd->status_urb)
		usb_hcd_poll_rh_status(musb->hcd);
	else
		usb_hcd_resume_root_hub(musb_to_hcd(musb));
		usb_hcd_resume_root_hub(musb->hcd);
}
+8 −11
Original line number Diff line number Diff line
@@ -37,15 +37,9 @@

#include <linux/scatterlist.h>

static inline struct usb_hcd *musb_to_hcd(struct musb *musb)
{
	return container_of((void *) musb, struct usb_hcd, hcd_priv);
}
#define musb_to_hcd(MUSB) ((MUSB)->hcd)

static inline struct musb *hcd_to_musb(struct usb_hcd *hcd)
{
	return (struct musb *) (hcd->hcd_priv);
}
extern struct musb *hcd_to_musb(struct usb_hcd *);

/* stored in "usb_host_endpoint.hcpriv" for scheduled endpoints */
struct musb_qh {
@@ -85,10 +79,15 @@ static inline struct musb_qh *first_qh(struct list_head *q)
}

extern irqreturn_t musb_h_ep0_irq(struct musb *);
extern int musb_host_alloc(struct musb *);
extern void musb_host_tx(struct musb *, u8);
extern void musb_host_rx(struct musb *, u8);
extern void musb_root_disconnect(struct musb *musb);
extern void musb_host_free(struct musb *);
extern void musb_host_cleanup(struct musb *);
extern void musb_host_tx(struct musb *, u8);
extern void musb_host_rx(struct musb *, u8);
extern void musb_root_disconnect(struct musb *musb);

extern void musb_host_resume_root_hub(struct musb *musb);
extern void musb_host_poke_root_hub(struct musb *musb);

@@ -99,8 +98,6 @@ extern int musb_hub_control(struct usb_hcd *hcd,
			u16 typeReq, u16 wValue, u16 wIndex,
			char *buf, u16 wLength);

extern const struct hc_driver musb_hc_driver;

static inline struct urb *next_urb(struct musb_qh *qh)
{
	struct list_head	*queue;