Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v3.2-rc5 126 lines 3.0 kB view raw
1/* Copyright (c) 2010, Code Aurora Forum. All rights reserved. 2 * 3 * This program is free software; you can redistribute it and/or modify 4 * it under the terms of the GNU General Public License version 2 and 5 * only version 2 as published by the Free Software Foundation. 6 */ 7 8#include <linux/module.h> 9#include <linux/platform_device.h> 10#include <linux/pm_runtime.h> 11#include <linux/usb/msm_hsusb_hw.h> 12#include <linux/usb/ulpi.h> 13 14#include "ci13xxx_udc.c" 15 16#define MSM_USB_BASE (udc->regs) 17 18static irqreturn_t msm_udc_irq(int irq, void *data) 19{ 20 return udc_irq(); 21} 22 23static void ci13xxx_msm_notify_event(struct ci13xxx *udc, unsigned event) 24{ 25 struct device *dev = udc->gadget.dev.parent; 26 int val; 27 28 switch (event) { 29 case CI13XXX_CONTROLLER_RESET_EVENT: 30 dev_dbg(dev, "CI13XXX_CONTROLLER_RESET_EVENT received\n"); 31 writel(0, USB_AHBBURST); 32 writel(0, USB_AHBMODE); 33 break; 34 case CI13XXX_CONTROLLER_STOPPED_EVENT: 35 dev_dbg(dev, "CI13XXX_CONTROLLER_STOPPED_EVENT received\n"); 36 /* 37 * Put the transceiver in non-driving mode. Otherwise host 38 * may not detect soft-disconnection. 39 */ 40 val = otg_io_read(udc->transceiver, ULPI_FUNC_CTRL); 41 val &= ~ULPI_FUNC_CTRL_OPMODE_MASK; 42 val |= ULPI_FUNC_CTRL_OPMODE_NONDRIVING; 43 otg_io_write(udc->transceiver, val, ULPI_FUNC_CTRL); 44 break; 45 default: 46 dev_dbg(dev, "unknown ci13xxx_udc event\n"); 47 break; 48 } 49} 50 51static struct ci13xxx_udc_driver ci13xxx_msm_udc_driver = { 52 .name = "ci13xxx_msm", 53 .flags = CI13XXX_REGS_SHARED | 54 CI13XXX_REQUIRE_TRANSCEIVER | 55 CI13XXX_PULLUP_ON_VBUS | 56 CI13XXX_DISABLE_STREAMING, 57 58 .notify_event = ci13xxx_msm_notify_event, 59}; 60 61static int ci13xxx_msm_probe(struct platform_device *pdev) 62{ 63 struct resource *res; 64 void __iomem *regs; 65 int irq; 66 int ret; 67 68 dev_dbg(&pdev->dev, "ci13xxx_msm_probe\n"); 69 70 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 71 if (!res) { 72 dev_err(&pdev->dev, "failed to get platform resource mem\n"); 73 return -ENXIO; 74 } 75 76 regs = ioremap(res->start, resource_size(res)); 77 if (!regs) { 78 dev_err(&pdev->dev, "ioremap failed\n"); 79 return -ENOMEM; 80 } 81 82 ret = udc_probe(&ci13xxx_msm_udc_driver, &pdev->dev, regs); 83 if (ret < 0) { 84 dev_err(&pdev->dev, "udc_probe failed\n"); 85 goto iounmap; 86 } 87 88 irq = platform_get_irq(pdev, 0); 89 if (irq < 0) { 90 dev_err(&pdev->dev, "IRQ not found\n"); 91 ret = -ENXIO; 92 goto udc_remove; 93 } 94 95 ret = request_irq(irq, msm_udc_irq, IRQF_SHARED, pdev->name, pdev); 96 if (ret < 0) { 97 dev_err(&pdev->dev, "request_irq failed\n"); 98 goto udc_remove; 99 } 100 101 pm_runtime_no_callbacks(&pdev->dev); 102 pm_runtime_enable(&pdev->dev); 103 104 return 0; 105 106udc_remove: 107 udc_remove(); 108iounmap: 109 iounmap(regs); 110 111 return ret; 112} 113 114static struct platform_driver ci13xxx_msm_driver = { 115 .probe = ci13xxx_msm_probe, 116 .driver = { .name = "msm_hsusb", }, 117}; 118MODULE_ALIAS("platform:msm_hsusb"); 119 120static int __init ci13xxx_msm_init(void) 121{ 122 return platform_driver_register(&ci13xxx_msm_driver); 123} 124module_init(ci13xxx_msm_init); 125 126MODULE_LICENSE("GPL v2");