On Sat, 21 Jan 2012, Hauke Mehrtens wrote:
> This adds a generic driver for platform devices. It works like the PCI
> driver and is based on it. This is for devices which do not have an own
> bus but their EHCI controller works like a PCI controller. It will be
> used for the Broadcom bcma and ssb USB EHCI controller.
Before adding a generic platform driver for EHCI, you should give some
to thought to how it might be generalized. There are a lot of EHCI
platform drivers, all differing in various major or minor respects.
It should be possible to replace a lot of them with the generic driver,
but first it will need some way to cope with a few minor quirks.
Please consider this, and think about which of the existing drivers
could be replaced.
> --- /dev/null
> +++ b/drivers/usb/host/ehci-platform.c
> @@ -0,0 +1,211 @@
> +/*
> + * Generic platform ehci driver
> + *
> + * Copyright 2007 Steven Brown <sbrown@cortland.com>
> + * Copyright 2010-2011 Hauke Mehrtens <hauke@hauke-m.de>
> + *
> + * Derived from the ohci-ssb driver
> + * Copyright 2007 Michael Buesch <m@bues.ch>
> + *
> + * Derived from the EHCI-PCI driver
> + * Copyright (c) 2000-2004 by David Brownell
> + *
> + * Derived from the ohci-pci driver
> + * Copyright 1999 Roman Weissgaerber
> + * Copyright 2000-2002 David Brownell
> + * Copyright 1999 Linus Torvalds
> + * Copyright 1999 Gregory P. Smith
> + *
> + * Licensed under the GNU/GPL. See COPYING for details.
> + */
> +#include <linux/platform_device.h>
> +
> +static int ehci_platform_reset(struct usb_hcd *hcd)
> +{
> + struct ehci_hcd *ehci = hcd_to_ehci(hcd);
> + int retval;
> +
> + ehci->caps = hcd->regs;
> + ehci->regs = hcd->regs +
> + HC_LENGTH(ehci, ehci_readl(ehci, &ehci->caps->hc_capbase));
> +
> + dbg_hcs_params(ehci, "reset");
> + dbg_hcc_params(ehci, "reset");
> +
> + /* cache this readonly data; minimize chip reads */
> + ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params);
> +
> + retval = ehci_halt(ehci);
> + if (retval)
> + return retval;
> +
> + /* data structure init */
> + retval = ehci_init(hcd);
> + if (retval)
> + return retval;
> +
> + ehci_reset(ehci);
> +
> + ehci_port_power(ehci, 1);
> +
> + return retval;
> +}
Most of this routine should be replaced with a call to ehci_setup.
Alan Stern
|