musb_core.c 是usb_general.c 调用进musb模块的核心函数,
里面有usb,musb,dma,platform模块等内容。
1. musb_init():
/* make us init after usbcore and i2c (transceivers, regulators, etc)
* and before usb gadget and host-side drivers start to register
*/
fs_initcall(musb_init);
static int __init musb_init(void)
{
#ifdef CONFIG_USB_MUSB_HDRC_HCD
if (usb_disabled())
return 0;
#endif
pr_info("%s: version " MUSB_VERSION ", "
#ifdef CONFIG_MUSB_PIO_ONLY //这些宏由内核配置选项中来
"pio"
#elif defined(CONFIG_USB_TI_CPPI_DMA)
"cppi-dma"
#elif defined(CONFIG_USB_INVENTRA_DMA)
"musb-dma"
#elif defined(CONFIG_USB_TUSB_OMAP_DMA)
"tusb-omap-dma"
#elif defined(CONFIG_USB_CARTESIO_DMA)
"pl080-dma"
#else
"?dma?"
#endif
", "
#ifdef CONFIG_USB_MUSB_OTG
"otg (peripheral+host)"
#elif defined(CONFIG_USB_GADGET_MUSB_HDRC)
"peripheral"
#elif defined(CONFIG_USB_MUSB_HDRC_HCD)
"host"
#endif
", debug=%d\n",
musb_driver_name, musb_debug);
return platform_driver_probe(&musb_driver, musb_probe); //这里调用了platform 平台函数,注册进platform类型队列中。
}
musb_driver:
static struct platform_driver musb_driver = {
.driver = {
.name = (char *)musb_driver_name,
.bus = &platform_bus_type, //platform bus类型
.owner = THIS_MODULE,
.pm = MUSB_DEV_PM_OPS, //PM OPS, suspend+resume
},
.remove = __exit_p(musb_remove),
.shutdown = musb_shutdown,
};
1.1 musb_driver_name 定义:
#define MUSB_DRIVER_NAME "musb_hdrc"
const char musb_driver_name[] = MUSB_DRIVER_NAME;
1.2 MUSB_DEV_PM_OPS 定义:
#define MUSB_DEV_PM_OPS (&musb_dev_pm_ops)
#else
#define MUSB_DEV_PM_OPS NULL
#endif
static const struct dev_pm_ops musb_dev_pm_ops = {
.suspend = musb_suspend,
.resume = musb_resume_noirq,
};
static int musb_suspend(struct device *dev)
static int musb_suspend(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
unsigned long flags;
struct musb *musb = dev_to_musb(&pdev->dev);
if (!musb->clock)
return 0;
spin_lock_irqsave(&musb->lock, flags);
if (is_peripheral_active(musb)) {
/* FIXME force disconnect unless we know USB will wake
* the system up quickly enough to respond ...
*/
} else if (is_host_active(musb)) {
/* we know all the children are suspended; sometimes
* they will even be wakeup-enabled.
*/
}
musb_save_context(musb);
if (musb->set_clock)
musb->set_clock(musb->clock, 0);
else
clk_disable(musb->clock);
spin_unlock_irqrestore(&musb->lock, flags);
return 0;
}
static int musb_resume_noirq(struct device *dev):
static int musb_resume_noirq(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
struct musb *musb = dev_to_musb(&pdev->dev);
#ifdef MUSB_RESTORE_REG
int status;
#endif
if (!musb->clock)
return 0;
if (musb->set_clock)
musb->set_clock(musb->clock, 1);
else
clk_enable(musb->clock);
musb_restore_context(musb);
#ifdef MUSB_RESTORE_REG
status = musb_core_init(musb->is_multipoint
? MUSB_CONTROLLER_MHDRC
: MUSB_CONTROLLER_HDRC, musb);
if (status < 0)
return status;
/* we need to apply the DEV_CTRL SESSION bit to initialize the VBUS.
* This should be generally called through root hub POWERON feature,
* but it is needed also here if autosuspend is disabled.
*/
musb_start(musb);
/* wait for the connect interrupt */
mdelay(200);
#endif
return 0;
}
1.4 static int __exit musb_remove(struct platform_device *pdev)
static int __exit musb_remove(struct platform_device *pdev)
{
struct musb *musb = dev_to_musb(&pdev->dev);
void __iomem *ctrl_base = musb->ctrl_base;
/* this gets called on rmmod.
* - Host mode: host may still be active
* - Peripheral mode: peripheral is deactivated (or never-activated)
* - OTG mode: both roles are deactivated (or never-activated)
*/
musb_shutdown(pdev);
#ifdef CONFIG_USB_MUSB_HDRC_HCD
if (musb->board_mode == MUSB_HOST)
usb_remove_hcd(musb_to_hcd(musb));
#endif
musb_writeb(musb->mregs, MUSB_DEVCTL, 0);
musb_platform_exit(musb);
musb_writeb(musb->mregs, MUSB_DEVCTL, 0);
musb_free(musb);
iounmap(ctrl_base);
device_init_wakeup(&pdev->dev, 0);
#ifndef CONFIG_MUSB_PIO_ONLY
pdev->dev.dma_mask = orig_dma_mask;
#endif
return 0;
}
1.5 static void musb_shutdown(struct platform_device *pdev)
static void musb_shutdown(struct platform_device *pdev)
{
struct musb *musb = dev_to_musb(&pdev->dev);
unsigned long flags;
spin_lock_irqsave(&musb->lock, flags);
musb_platform_disable(musb);
musb_generic_disable(musb);
if (musb->clock)
clk_put(musb->clock);
spin_unlock_irqrestore(&musb->lock, flags);
/* FIXME power down */
}
2. musb_cleanup():
static void __exit musb_cleanup(void)
{
platform_driver_unregister(&musb_driver);
}
module_exit(musb_cleanup);
3. static int __init musb_probe(struct platform_device *pdev)
static int __init musb_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
int irq = platform_get_irq(pdev, 0);
int status;
struct resource *iomem;
void __iomem *base;
iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0); //获取 platform 资源
if (!iomem || irq == 0)
return -ENODEV;
base = ioremap(iomem->start, resource_size(iomem)); //映射内存
if (!base) {
dev_err(dev, "ioremap failed\n");
return -ENOMEM;
}
#ifndef CONFIG_MUSB_PIO_ONLY
/* clobbered by use_dma=n */
orig_dma_mask = dev->dma_mask; //如果内核配置了CONFIG_MUSB_PIO_ONLY,则屏蔽DMA
#endif
status = musb_init_controller(dev, irq, base); //这个才是主要的函数
if (status < 0)
iounmap(base);
return status;
}
4. static int __initmusb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl)
/*
* Perform generic per-controller i