Merge branch 'for-next/gadget' of git://git.kernel.org/pub/scm/linux/kernel/git/balbi/usb into usb-next

* 'for-next/gadget' of git://git.kernel.org/pub/scm/linux/kernel/git/balbi/usb: (50 commits)
  usb: renesas_usbhs: show error reason on usbhsh_urb_enqueu()
  usb: renesas_usbhs: add force packet remove method
  usb: renesas_usbhs: care usb_hcd_giveback_urb() status
  usb: renesas_usbhs: add usbhsh_is_running()
  usb: renesas_usbhs: disable attch irq after device attached
  usb: renesas_usbhs: care pipe sequence
  usb: renesas_usbhs: add usbhs_pipe_attach() method
  usb: renesas_usbhs: add usbhsh_endpoint_detach_all() for error case
  usb: renesas_usbhs: modify device attach method
  usb: renesas_usbhs: pop packet when urb dequeued
  usb: renesas_usbhs: add lost error value when enqueue
  usb: gadget: mv_udc: replace some debug info
  usb: gadget: mv_udc: refine suspend/resume function
  usb: gadget: mv_udc: refine the clock relative code
  usb: gadget: mv_udc: disable ISR when stopped
  usb: gadget: mv_udc: add otg relative code
  usb: gadget: Use kcalloc instead of kzalloc to allocate array
  usb: renesas_usbhs: remove the_controller_link
  usb: renesas_usbhs: add test-mode support
  usb: renesas_usbhs: call usbhsg_queue_pop() when pipe disable.
  ...
This commit is contained in:
Greg Kroah-Hartman 2011-12-13 09:37:40 -08:00
commit 121a8cdd79
49 changed files with 1139 additions and 600 deletions

View File

@ -535,6 +535,20 @@ Why: In 3.0, we can now autodetect internal 3G device and already have
information log when acer-wmi initial.
Who: Lee, Chun-Yi <jlee@novell.com>
---------------------------
What: /sys/devices/platform/_UDC_/udc/_UDC_/is_dualspeed file and
is_dualspeed line in /sys/devices/platform/ci13xxx_*/udc/device file.
When: 3.8
Why: The is_dualspeed file is superseded by maximum_speed in the same
directory and is_dualspeed line in device file is superseded by
max_speed line in the same file.
The maximum_speed/max_speed specifies maximum speed supported by UDC.
To check if dualspeeed is supported, check if the value is >= 3.
Various possible speeds are defined in <linux/usb/ch9.h>.
Who: Michal Nazarewicz <mina86@mina86.com>
----------------------------
What: The XFS nodelaylog mount option

View File

@ -2087,7 +2087,7 @@ int __devinit dwc3_gadget_init(struct dwc3 *dwc)
dev_set_name(&dwc->gadget.dev, "gadget");
dwc->gadget.ops = &dwc3_gadget_ops;
dwc->gadget.is_dualspeed = true;
dwc->gadget.max_speed = USB_SPEED_SUPER;
dwc->gadget.speed = USB_SPEED_UNKNOWN;
dwc->gadget.dev.parent = dwc->dev;

View File

@ -235,7 +235,6 @@ config USB_R8A66597
config USB_RENESAS_USBHS_UDC
tristate 'Renesas USBHS controller'
depends on SUPERH || ARCH_SHMOBILE
depends on USB_RENESAS_USBHS
select USB_GADGET_DUALSPEED
help

View File

@ -1959,7 +1959,7 @@ static int amd5536_start(struct usb_gadget_driver *driver,
u32 tmp;
if (!driver || !bind || !driver->setup
|| driver->speed < USB_SPEED_HIGH)
|| driver->max_speed < USB_SPEED_HIGH)
return -EINVAL;
if (!dev)
return -ENODEV;
@ -3349,7 +3349,7 @@ static int udc_probe(struct udc *dev)
dev_set_name(&dev->gadget.dev, "gadget");
dev->gadget.dev.release = gadget_release;
dev->gadget.name = name;
dev->gadget.is_dualspeed = 1;
dev->gadget.max_speed = USB_SPEED_HIGH;
/* init registers, interrupts, ... */
startup_registers(dev);

View File

@ -1633,7 +1633,7 @@ static int at91_start(struct usb_gadget_driver *driver,
unsigned long flags;
if (!driver
|| driver->speed < USB_SPEED_FULL
|| driver->max_speed < USB_SPEED_FULL
|| !bind
|| !driver->setup) {
DBG("bad parameter.\n");

View File

@ -1038,7 +1038,7 @@ static struct usba_udc the_udc = {
.gadget = {
.ops = &usba_udc_ops,
.ep_list = LIST_HEAD_INIT(the_udc.gadget.ep_list),
.is_dualspeed = 1,
.max_speed = USB_SPEED_HIGH,
.name = "atmel_usba_udc",
.dev = {
.init_name = "gadget",

View File

@ -182,6 +182,16 @@ static inline int hw_ep_bit(int num, int dir)
return num + (dir ? 16 : 0);
}
static int ep_to_bit(int n)
{
int fill = 16 - hw_ep_max / 2;
if (n >= hw_ep_max / 2)
n += fill;
return n;
}
/**
* hw_aread: reads from register bitfield
* @addr: address relative to bus map
@ -440,12 +450,13 @@ static int hw_ep_get_halt(int num, int dir)
/**
* hw_test_and_clear_setup_status: test & clear setup status (execute without
* interruption)
* @n: bit number (endpoint)
* @n: endpoint number
*
* This function returns setup status
*/
static int hw_test_and_clear_setup_status(int n)
{
n = ep_to_bit(n);
return hw_ctest_and_clear(CAP_ENDPTSETUPSTAT, BIT(n));
}
@ -641,12 +652,13 @@ static int hw_register_write(u16 addr, u32 data)
/**
* hw_test_and_clear_complete: test & clear complete status (execute without
* interruption)
* @n: bit number (endpoint)
* @n: endpoint number
*
* This function returns complete status
*/
static int hw_test_and_clear_complete(int n)
{
n = ep_to_bit(n);
return hw_ctest_and_clear(CAP_ENDPTCOMPLETE, BIT(n));
}
@ -754,8 +766,11 @@ static ssize_t show_device(struct device *dev, struct device_attribute *attr,
n += scnprintf(buf + n, PAGE_SIZE - n, "speed = %d\n",
gadget->speed);
n += scnprintf(buf + n, PAGE_SIZE - n, "max_speed = %d\n",
gadget->max_speed);
/* TODO: Scheduled for removal in 3.8. */
n += scnprintf(buf + n, PAGE_SIZE - n, "is_dualspeed = %d\n",
gadget->is_dualspeed);
gadget_is_dualspeed(gadget));
n += scnprintf(buf + n, PAGE_SIZE - n, "is_otg = %d\n",
gadget->is_otg);
n += scnprintf(buf + n, PAGE_SIZE - n, "is_a_peripheral = %d\n",
@ -798,7 +813,7 @@ static ssize_t show_driver(struct device *dev, struct device_attribute *attr,
n += scnprintf(buf + n, PAGE_SIZE - n, "function = %s\n",
(driver->function ? driver->function : ""));
n += scnprintf(buf + n, PAGE_SIZE - n, "max speed = %d\n",
driver->speed);
driver->max_speed);
return n;
}
@ -2563,9 +2578,7 @@ static int ci13xxx_start(struct usb_gadget_driver *driver,
if (driver == NULL ||
bind == NULL ||
driver->setup == NULL ||
driver->disconnect == NULL ||
driver->suspend == NULL ||
driver->resume == NULL)
driver->disconnect == NULL)
return -EINVAL;
else if (udc == NULL)
return -ENODEV;
@ -2693,8 +2706,6 @@ static int ci13xxx_stop(struct usb_gadget_driver *driver)
driver->unbind == NULL ||
driver->setup == NULL ||
driver->disconnect == NULL ||
driver->suspend == NULL ||
driver->resume == NULL ||
driver != udc->driver)
return -EINVAL;
@ -2793,7 +2804,7 @@ static irqreturn_t udc_irq(void)
isr_statistics.pci++;
udc->gadget.speed = hw_port_is_high_speed() ?
USB_SPEED_HIGH : USB_SPEED_FULL;
if (udc->suspended) {
if (udc->suspended && udc->driver->resume) {
spin_unlock(udc->lock);
udc->driver->resume(&udc->gadget);
spin_lock(udc->lock);
@ -2807,7 +2818,8 @@ static irqreturn_t udc_irq(void)
isr_tr_complete_handler(udc);
}
if (USBi_SLI & intr) {
if (udc->gadget.speed != USB_SPEED_UNKNOWN) {
if (udc->gadget.speed != USB_SPEED_UNKNOWN &&
udc->driver->suspend) {
udc->suspended = 1;
spin_unlock(udc->lock);
udc->driver->suspend(&udc->gadget);
@ -2871,7 +2883,7 @@ static int udc_probe(struct ci13xxx_udc_driver *driver, struct device *dev,
udc->gadget.ops = &usb_gadget_ops;
udc->gadget.speed = USB_SPEED_UNKNOWN;
udc->gadget.is_dualspeed = 1;
udc->gadget.max_speed = USB_SPEED_HIGH;
udc->gadget.is_otg = 0;
udc->gadget.name = driver->name;

View File

@ -127,7 +127,7 @@ struct ci13xxx {
struct ci13xxx_ep ci13xxx_ep[ENDPT_MAX]; /* extended endpts */
u32 ep0_dir; /* ep0 direction */
#define ep0out ci13xxx_ep[0]
#define ep0in ci13xxx_ep[16]
#define ep0in ci13xxx_ep[hw_ep_max / 2]
u8 remote_wakeup; /* Is remote wakeup feature
enabled by the host? */
u8 suspended; /* suspended by the host */

View File

@ -1535,9 +1535,9 @@ composite_resume(struct usb_gadget *gadget)
static struct usb_gadget_driver composite_driver = {
#ifdef CONFIG_USB_GADGET_SUPERSPEED
.speed = USB_SPEED_SUPER,
.max_speed = USB_SPEED_SUPER,
#else
.speed = USB_SPEED_HIGH,
.max_speed = USB_SPEED_HIGH,
#endif
.unbind = composite_unbind,
@ -1584,8 +1584,8 @@ int usb_composite_probe(struct usb_composite_driver *driver,
driver->iProduct = driver->name;
composite_driver.function = (char *) driver->name;
composite_driver.driver.name = driver->name;
composite_driver.speed = min((u8)composite_driver.speed,
(u8)driver->max_speed);
composite_driver.max_speed =
min_t(u8, composite_driver.max_speed, driver->max_speed);
composite = driver;
composite_gadget_bind = bind;

View File

@ -404,7 +404,7 @@ fail:
static struct usb_gadget_driver dbgp_driver = {
.function = "dbgp",
.speed = USB_SPEED_HIGH,
.max_speed = USB_SPEED_HIGH,
.unbind = dbgp_unbind,
.setup = dbgp_setup,
.disconnect = dbgp_disconnect,

View File

@ -823,19 +823,18 @@ static int dummy_pullup (struct usb_gadget *_gadget, int value)
if (value && dum->driver) {
if (mod_data.is_super_speed)
dum->gadget.speed = dum->driver->speed;
dum->gadget.speed = dum->driver->max_speed;
else if (mod_data.is_high_speed)
dum->gadget.speed = min_t(u8, USB_SPEED_HIGH,
dum->driver->speed);
dum->driver->max_speed);
else
dum->gadget.speed = USB_SPEED_FULL;
dummy_udc_udpate_ep0(dum);
if (dum->gadget.speed < dum->driver->speed)
if (dum->gadget.speed < dum->driver->max_speed)
dev_dbg(udc_dev(dum), "This device can perform faster"
" if you connect it to a %s port...\n",
(dum->driver->speed == USB_SPEED_SUPER ?
"SuperSpeed" : "HighSpeed"));
" if you connect it to a %s port...\n",
usb_speed_string(dum->driver->max_speed));
}
dum_hcd = gadget_to_dummy_hcd(_gadget);
@ -898,7 +897,7 @@ static int dummy_udc_start(struct usb_gadget *g,
struct dummy_hcd *dum_hcd = gadget_to_dummy_hcd(g);
struct dummy *dum = dum_hcd->dum;
if (driver->speed == USB_SPEED_UNKNOWN)
if (driver->max_speed == USB_SPEED_UNKNOWN)
return -EINVAL;
/*
@ -977,7 +976,7 @@ static int dummy_udc_probe (struct platform_device *pdev)
dum->gadget.name = gadget_name;
dum->gadget.ops = &dummy_ops;
dum->gadget.is_dualspeed = 1;
dum->gadget.max_speed = USB_SPEED_SUPER;
dev_set_name(&dum->gadget.dev, "gadget");
dum->gadget.dev.parent = &pdev->dev;

View File

@ -152,7 +152,7 @@ ep_matches (
switch (type) {
case USB_ENDPOINT_XFER_INT:
/* INT: limit 64 bytes full speed, 1024 high/super speed */
if (!gadget->is_dualspeed && max > 64)
if (!gadget_is_dualspeed(gadget) && max > 64)
return 0;
/* FALLTHROUGH */
@ -160,12 +160,12 @@ ep_matches (
/* ISO: limit 1023 bytes full speed, 1024 high/super speed */
if (ep->maxpacket < max)
return 0;
if (!gadget->is_dualspeed && max > 1023)
if (!gadget_is_dualspeed(gadget) && max > 1023)
return 0;
/* BOTH: "high bandwidth" works only at high speed */
if ((desc->wMaxPacketSize & cpu_to_le16(3<<11))) {
if (!gadget->is_dualspeed)
if (!gadget_is_dualspeed(gadget))
return 0;
/* configure your hardware with enough buffering!! */
}

View File

@ -1408,7 +1408,7 @@ static int ffs_epfiles_create(struct ffs_data *ffs)
ENTER();
count = ffs->eps_count;
epfiles = kzalloc(count * sizeof *epfiles, GFP_KERNEL);
epfiles = kcalloc(count, sizeof(*epfiles), GFP_KERNEL);
if (!epfiles)
return -ENOMEM;

View File

@ -1873,17 +1873,14 @@ static int check_command(struct fsg_common *common, int cmnd_size,
common->lun, lun);
/* Check the LUN */
if (common->lun < common->nluns) {
curlun = &common->luns[common->lun];
common->curlun = curlun;
curlun = common->curlun;
if (curlun) {
if (common->cmnd[0] != REQUEST_SENSE) {
curlun->sense_data = SS_NO_SENSE;
curlun->sense_data_info = 0;
curlun->info_valid = 0;
}
} else {
common->curlun = NULL;
curlun = NULL;
common->bad_lun_okay = 0;
/*
@ -1929,6 +1926,17 @@ static int check_command(struct fsg_common *common, int cmnd_size,
return 0;
}
/* wrapper of check_command for data size in blocks handling */
static int check_command_size_in_blocks(struct fsg_common *common,
int cmnd_size, enum data_direction data_dir,
unsigned int mask, int needs_medium, const char *name)
{
if (common->curlun)
common->data_size_from_cmnd <<= common->curlun->blkbits;
return check_command(common, cmnd_size, data_dir,
mask, needs_medium, name);
}
static int do_scsi_command(struct fsg_common *common)
{
struct fsg_buffhd *bh;
@ -2011,9 +2019,9 @@ static int do_scsi_command(struct fsg_common *common)
case READ_6:
i = common->cmnd[4];
common->data_size_from_cmnd = (i == 0 ? 256 : i) <<
common->curlun->blkbits;
reply = check_command(common, 6, DATA_DIR_TO_HOST,
common->data_size_from_cmnd = (i == 0) ? 256 : i;
reply = check_command_size_in_blocks(common, 6,
DATA_DIR_TO_HOST,
(7<<1) | (1<<4), 1,
"READ(6)");
if (reply == 0)
@ -2022,9 +2030,9 @@ static int do_scsi_command(struct fsg_common *common)
case READ_10:
common->data_size_from_cmnd =
get_unaligned_be16(&common->cmnd[7]) <<
common->curlun->blkbits;
reply = check_command(common, 10, DATA_DIR_TO_HOST,
get_unaligned_be16(&common->cmnd[7]);
reply = check_command_size_in_blocks(common, 10,
DATA_DIR_TO_HOST,
(1<<1) | (0xf<<2) | (3<<7), 1,
"READ(10)");
if (reply == 0)
@ -2033,9 +2041,9 @@ static int do_scsi_command(struct fsg_common *common)
case READ_12:
common->data_size_from_cmnd =
get_unaligned_be32(&common->cmnd[6]) <<
common->curlun->blkbits;
reply = check_command(common, 12, DATA_DIR_TO_HOST,
get_unaligned_be32(&common->cmnd[6]);
reply = check_command_size_in_blocks(common, 12,
DATA_DIR_TO_HOST,
(1<<1) | (0xf<<2) | (0xf<<6), 1,
"READ(12)");
if (reply == 0)
@ -2134,9 +2142,9 @@ static int do_scsi_command(struct fsg_common *common)
case WRITE_6:
i = common->cmnd[4];
common->data_size_from_cmnd = (i == 0 ? 256 : i) <<
common->curlun->blkbits;
reply = check_command(common, 6, DATA_DIR_FROM_HOST,
common->data_size_from_cmnd = (i == 0) ? 256 : i;
reply = check_command_size_in_blocks(common, 6,
DATA_DIR_FROM_HOST,
(7<<1) | (1<<4), 1,
"WRITE(6)");
if (reply == 0)
@ -2145,9 +2153,9 @@ static int do_scsi_command(struct fsg_common *common)
case WRITE_10:
common->data_size_from_cmnd =
get_unaligned_be16(&common->cmnd[7]) <<
common->curlun->blkbits;
reply = check_command(common, 10, DATA_DIR_FROM_HOST,
get_unaligned_be16(&common->cmnd[7]);
reply = check_command_size_in_blocks(common, 10,
DATA_DIR_FROM_HOST,
(1<<1) | (0xf<<2) | (3<<7), 1,
"WRITE(10)");
if (reply == 0)
@ -2156,9 +2164,9 @@ static int do_scsi_command(struct fsg_common *common)
case WRITE_12:
common->data_size_from_cmnd =
get_unaligned_be32(&common->cmnd[6]) <<
common->curlun->blkbits;
reply = check_command(common, 12, DATA_DIR_FROM_HOST,
get_unaligned_be32(&common->cmnd[6]);
reply = check_command_size_in_blocks(common, 12,
DATA_DIR_FROM_HOST,
(1<<1) | (0xf<<2) | (0xf<<6), 1,
"WRITE(12)");
if (reply == 0)
@ -2273,6 +2281,10 @@ static int received_cbw(struct fsg_dev *fsg, struct fsg_buffhd *bh)
if (common->data_size == 0)
common->data_dir = DATA_DIR_NONE;
common->lun = cbw->Lun;
if (common->lun >= 0 && common->lun < common->nluns)
common->curlun = &common->luns[common->lun];
else
common->curlun = NULL;
common->tag = cbw->Tag;
return 0;
}
@ -2763,7 +2775,7 @@ static struct fsg_common *fsg_common_init(struct fsg_common *common,
* Create the LUNs, open their backing files, and register the
* LUN devices in sysfs.
*/
curlun = kzalloc(nluns * sizeof *curlun, GFP_KERNEL);
curlun = kcalloc(nluns, sizeof(*curlun), GFP_KERNEL);
if (unlikely(!curlun)) {
rc = -ENOMEM;
goto error_release;

View File

@ -2297,19 +2297,17 @@ static int check_command(struct fsg_dev *fsg, int cmnd_size,
DBG(fsg, "using LUN %d from CBW, "
"not LUN %d from CDB\n",
fsg->lun, lun);
} else
fsg->lun = lun; // Use LUN from the command
}
/* Check the LUN */
if (fsg->lun < fsg->nluns) {
fsg->curlun = curlun = &fsg->luns[fsg->lun];
curlun = fsg->curlun;
if (curlun) {
if (fsg->cmnd[0] != REQUEST_SENSE) {
curlun->sense_data = SS_NO_SENSE;
curlun->sense_data_info = 0;
curlun->info_valid = 0;
}
} else {
fsg->curlun = curlun = NULL;
fsg->bad_lun_okay = 0;
/* INQUIRY and REQUEST SENSE commands are explicitly allowed
@ -2351,6 +2349,16 @@ static int check_command(struct fsg_dev *fsg, int cmnd_size,
return 0;
}
/* wrapper of check_command for data size in blocks handling */
static int check_command_size_in_blocks(struct fsg_dev *fsg, int cmnd_size,
enum data_direction data_dir, unsigned int mask,
int needs_medium, const char *name)
{
if (fsg->curlun)
fsg->data_size_from_cmnd <<= fsg->curlun->blkbits;
return check_command(fsg, cmnd_size, data_dir,
mask, needs_medium, name);
}
static int do_scsi_command(struct fsg_dev *fsg)
{
@ -2425,26 +2433,27 @@ static int do_scsi_command(struct fsg_dev *fsg)
case READ_6:
i = fsg->cmnd[4];
fsg->data_size_from_cmnd = (i == 0 ? 256 : i) << fsg->curlun->blkbits;
if ((reply = check_command(fsg, 6, DATA_DIR_TO_HOST,
fsg->data_size_from_cmnd = (i == 0) ? 256 : i;
if ((reply = check_command_size_in_blocks(fsg, 6,
DATA_DIR_TO_HOST,
(7<<1) | (1<<4), 1,
"READ(6)")) == 0)
reply = do_read(fsg);
break;
case READ_10:
fsg->data_size_from_cmnd =
get_unaligned_be16(&fsg->cmnd[7]) << fsg->curlun->blkbits;
if ((reply = check_command(fsg, 10, DATA_DIR_TO_HOST,
fsg->data_size_from_cmnd = get_unaligned_be16(&fsg->cmnd[7]);
if ((reply = check_command_size_in_blocks(fsg, 10,
DATA_DIR_TO_HOST,
(1<<1) | (0xf<<2) | (3<<7), 1,
"READ(10)")) == 0)
reply = do_read(fsg);
break;
case READ_12:
fsg->data_size_from_cmnd =
get_unaligned_be32(&fsg->cmnd[6]) << fsg->curlun->blkbits;
if ((reply = check_command(fsg, 12, DATA_DIR_TO_HOST,
fsg->data_size_from_cmnd = get_unaligned_be32(&fsg->cmnd[6]);
if ((reply = check_command_size_in_blocks(fsg, 12,
DATA_DIR_TO_HOST,
(1<<1) | (0xf<<2) | (0xf<<6), 1,
"READ(12)")) == 0)
reply = do_read(fsg);
@ -2529,26 +2538,27 @@ static int do_scsi_command(struct fsg_dev *fsg)
case WRITE_6:
i = fsg->cmnd[4];
fsg->data_size_from_cmnd = (i == 0 ? 256 : i) << fsg->curlun->blkbits;
if ((reply = check_command(fsg, 6, DATA_DIR_FROM_HOST,
fsg->data_size_from_cmnd = (i == 0) ? 256 : i;
if ((reply = check_command_size_in_blocks(fsg, 6,
DATA_DIR_FROM_HOST,
(7<<1) | (1<<4), 1,
"WRITE(6)")) == 0)
reply = do_write(fsg);
break;
case WRITE_10:
fsg->data_size_from_cmnd =
get_unaligned_be16(&fsg->cmnd[7]) << fsg->curlun->blkbits;
if ((reply = check_command(fsg, 10, DATA_DIR_FROM_HOST,
fsg->data_size_from_cmnd = get_unaligned_be16(&fsg->cmnd[7]);
if ((reply = check_command_size_in_blocks(fsg, 10,
DATA_DIR_FROM_HOST,
(1<<1) | (0xf<<2) | (3<<7), 1,
"WRITE(10)")) == 0)
reply = do_write(fsg);
break;
case WRITE_12:
fsg->data_size_from_cmnd =
get_unaligned_be32(&fsg->cmnd[6]) << fsg->curlun->blkbits;
if ((reply = check_command(fsg, 12, DATA_DIR_FROM_HOST,
fsg->data_size_from_cmnd = get_unaligned_be32(&fsg->cmnd[6]);
if ((reply = check_command_size_in_blocks(fsg, 12,
DATA_DIR_FROM_HOST,
(1<<1) | (0xf<<2) | (0xf<<6), 1,
"WRITE(12)")) == 0)
reply = do_write(fsg);
@ -2715,7 +2725,17 @@ static int get_next_command(struct fsg_dev *fsg)
memcpy(fsg->cmnd, fsg->cbbuf_cmnd, fsg->cmnd_size);
fsg->cbbuf_cmnd_size = 0;
spin_unlock_irq(&fsg->lock);
/* Use LUN from the command */
fsg->lun = fsg->cmnd[1] >> 5;
}
/* Update current lun */
if (fsg->lun >= 0 && fsg->lun < fsg->nluns)
fsg->curlun = &fsg->luns[fsg->lun];
else
fsg->curlun = NULL;
return rc;
}
@ -3584,7 +3604,7 @@ static void fsg_resume(struct usb_gadget *gadget)
/*-------------------------------------------------------------------------*/
static struct usb_gadget_driver fsg_driver = {
.speed = USB_SPEED_SUPER,
.max_speed = USB_SPEED_SUPER,
.function = (char *) fsg_string_product,
.unbind = fsg_unbind,
.disconnect = fsg_disconnect,

View File

@ -2336,7 +2336,7 @@ static int fsl_qe_start(struct usb_gadget_driver *driver,
if (!udc_controller)
return -ENODEV;
if (!driver || driver->speed < USB_SPEED_FULL
if (!driver || driver->max_speed < USB_SPEED_FULL
|| !bind || !driver->disconnect || !driver->setup)
return -EINVAL;
@ -2350,7 +2350,7 @@ static int fsl_qe_start(struct usb_gadget_driver *driver,
/* hook up the driver */
udc_controller->driver = driver;
udc_controller->gadget.dev.driver = &driver->driver;
udc_controller->gadget.speed = (enum usb_device_speed)(driver->speed);
udc_controller->gadget.speed = driver->max_speed;
spin_unlock_irqrestore(&udc_controller->lock, flags);
retval = bind(&udc_controller->gadget);

View File

@ -1934,7 +1934,7 @@ static int fsl_start(struct usb_gadget_driver *driver,
if (!udc_controller)
return -ENODEV;
if (!driver || driver->speed < USB_SPEED_FULL
if (!driver || driver->max_speed < USB_SPEED_FULL
|| !bind || !driver->disconnect || !driver->setup)
return -EINVAL;
@ -2525,7 +2525,7 @@ static int __init fsl_udc_probe(struct platform_device *pdev)
/* Setup gadget structure */
udc_controller->gadget.ops = &fsl_gadget_ops;
udc_controller->gadget.is_dualspeed = 1;
udc_controller->gadget.max_speed = USB_SPEED_HIGH;
udc_controller->gadget.ep0 = &udc_controller->eps[0].ep;
INIT_LIST_HEAD(&udc_controller->gadget.ep_list);
udc_controller->gadget.speed = USB_SPEED_UNKNOWN;

View File

@ -1317,7 +1317,7 @@ static int fusb300_udc_start(struct usb_gadget_driver *driver,
int retval;
if (!driver
|| driver->speed < USB_SPEED_FULL
|| driver->max_speed < USB_SPEED_FULL
|| !bind
|| !driver->setup)
return -EINVAL;
@ -1463,7 +1463,7 @@ static int __init fusb300_probe(struct platform_device *pdev)
dev_set_name(&fusb300->gadget.dev, "gadget");
fusb300->gadget.is_dualspeed = 1;
fusb300->gadget.max_speed = USB_SPEED_HIGH;
fusb300->gadget.dev.parent = &pdev->dev;
fusb300->gadget.dev.dma_mask = pdev->dev.dma_mask;
fusb300->gadget.dev.release = pdev->dev.release;

View File

@ -1357,7 +1357,7 @@ static int goku_start(struct usb_gadget_driver *driver,
int retval;
if (!driver
|| driver->speed < USB_SPEED_FULL
|| driver->max_speed < USB_SPEED_FULL
|| !bind
|| !driver->disconnect
|| !driver->setup)
@ -1796,6 +1796,7 @@ static int goku_probe(struct pci_dev *pdev, const struct pci_device_id *id)
spin_lock_init(&dev->lock);
dev->pdev = pdev;
dev->gadget.ops = &goku_ops;
dev->gadget.max_speed = USB_SPEED_FULL;
/* the "gadget" abstracts/virtualizes the controller */
dev_set_name(&dev->gadget.dev, "gadget");

View File

@ -1336,7 +1336,7 @@ static int imx_udc_start(struct usb_gadget_driver *driver,
int retval;
if (!driver
|| driver->speed < USB_SPEED_FULL
|| driver->max_speed < USB_SPEED_FULL
|| !bind
|| !driver->disconnect
|| !driver->setup)

View File

@ -1766,9 +1766,9 @@ gadgetfs_suspend (struct usb_gadget *gadget)
static struct usb_gadget_driver gadgetfs_driver = {
#ifdef CONFIG_USB_GADGET_DUALSPEED
.speed = USB_SPEED_HIGH,
.max_speed = USB_SPEED_HIGH,
#else
.speed = USB_SPEED_FULL,
.max_speed = USB_SPEED_FULL,
#endif
.function = (char *) driver_desc,
.unbind = gadgetfs_unbind,
@ -1792,7 +1792,7 @@ static int gadgetfs_probe (struct usb_gadget *gadget)
}
static struct usb_gadget_driver probe_driver = {
.speed = USB_SPEED_HIGH,
.max_speed = USB_SPEED_HIGH,
.unbind = gadgetfs_nop,
.setup = (void *)gadgetfs_nop,
.disconnect = gadgetfs_nop,

View File

@ -3267,7 +3267,7 @@ static int langwell_udc_probe(struct pci_dev *pdev,
dev->gadget.ep0 = &dev->ep[0].ep; /* gadget ep0 */
INIT_LIST_HEAD(&dev->gadget.ep_list); /* ep_list */
dev->gadget.speed = USB_SPEED_UNKNOWN; /* speed */
dev->gadget.is_dualspeed = 1; /* support dual speed */
dev->gadget.max_speed = USB_SPEED_HIGH; /* support dual speed */
#ifdef OTG_TRANSCEIVER
dev->gadget.is_otg = 1; /* support otg mode */
#endif

View File

@ -1472,7 +1472,7 @@ static int m66592_start(struct usb_gadget_driver *driver,
int retval;
if (!driver
|| driver->speed < USB_SPEED_HIGH
|| driver->max_speed < USB_SPEED_HIGH
|| !bind
|| !driver->setup)
return -EINVAL;
@ -1653,7 +1653,7 @@ static int __init m66592_probe(struct platform_device *pdev)
m66592->gadget.ops = &m66592_gadget_ops;
device_initialize(&m66592->gadget.dev);
dev_set_name(&m66592->gadget.dev, "gadget");
m66592->gadget.is_dualspeed = 1;
m66592->gadget.max_speed = USB_SPEED_HIGH;
m66592->gadget.dev.parent = &pdev->dev;
m66592->gadget.dev.dma_mask = pdev->dev.dma_mask;
m66592->gadget.dev.release = pdev->dev.release;

View File

@ -211,11 +211,14 @@ struct mv_udc {
softconnected:1,
force_fs:1,
clock_gating:1,
active:1;
active:1,
stopped:1; /* stop bit is setted */
struct work_struct vbus_work;
struct workqueue_struct *qwork;
struct otg_transceiver *transceiver;
struct mv_usb_platform_data *pdata;
/* some SOC has mutiple clock sources for USB*/

View File

@ -1056,6 +1056,8 @@ static void udc_stop(struct mv_udc *udc)
USBINTR_PORT_CHANGE_DETECT_EN | USBINTR_RESET_EN);
writel(tmp, &udc->op_regs->usbintr);
udc->stopped = 1;
/* Reset the Run the bit in the command register to stop VUSB */
tmp = readl(&udc->op_regs->usbcmd);
tmp &= ~USBCMD_RUN_STOP;
@ -1072,6 +1074,8 @@ static void udc_start(struct mv_udc *udc)
/* Enable interrupts */
writel(usbintr, &udc->op_regs->usbintr);
udc->stopped = 0;
/* Set the Run bit in the command register */
writel(USBCMD_RUN_STOP, &udc->op_regs->usbcmd);
}
@ -1134,11 +1138,11 @@ static int udc_reset(struct mv_udc *udc)
return 0;
}
static int mv_udc_enable(struct mv_udc *udc)
static int mv_udc_enable_internal(struct mv_udc *udc)
{
int retval;
if (udc->clock_gating == 0 || udc->active)
if (udc->active)
return 0;
dev_dbg(&udc->dev->dev, "enable udc\n");
@ -1157,9 +1161,17 @@ static int mv_udc_enable(struct mv_udc *udc)
return 0;
}
static void mv_udc_disable(struct mv_udc *udc)
static int mv_udc_enable(struct mv_udc *udc)
{
if (udc->clock_gating && udc->active) {
if (udc->clock_gating)
return mv_udc_enable_internal(udc);
return 0;
}
static void mv_udc_disable_internal(struct mv_udc *udc)
{
if (udc->active) {
dev_dbg(&udc->dev->dev, "disable udc\n");
if (udc->pdata->phy_deinit)
udc->pdata->phy_deinit(udc->phy_regs);
@ -1168,6 +1180,12 @@ static void mv_udc_disable(struct mv_udc *udc)
}
}
static void mv_udc_disable(struct mv_udc *udc)
{
if (udc->clock_gating)
mv_udc_disable_internal(udc);
}
static int mv_udc_get_frame(struct usb_gadget *gadget)
{
struct mv_udc *udc;
@ -1212,10 +1230,11 @@ static int mv_udc_vbus_session(struct usb_gadget *gadget, int is_active)
udc = container_of(gadget, struct mv_udc, gadget);
spin_lock_irqsave(&udc->lock, flags);
udc->vbus_active = (is_active != 0);
dev_dbg(&udc->dev->dev, "%s: softconnect %d, vbus_active %d\n",
__func__, udc->softconnect, udc->vbus_active);
udc->vbus_active = (is_active != 0);
if (udc->driver && udc->softconnect && udc->vbus_active) {
retval = mv_udc_enable(udc);
if (retval == 0) {
@ -1244,10 +1263,11 @@ static int mv_udc_pullup(struct usb_gadget *gadget, int is_on)
udc = container_of(gadget, struct mv_udc, gadget);
spin_lock_irqsave(&udc->lock, flags);
udc->softconnect = (is_on != 0);
dev_dbg(&udc->dev->dev, "%s: softconnect %d, vbus_active %d\n",
__func__, udc->softconnect, udc->vbus_active);
udc->softconnect = (is_on != 0);
if (udc->driver && udc->softconnect && udc->vbus_active) {
retval = mv_udc_enable(udc);
if (retval == 0) {
@ -1407,6 +1427,20 @@ static int mv_udc_start(struct usb_gadget_driver *driver,
return retval;
}
if (udc->transceiver) {
retval = otg_set_peripheral(udc->transceiver, &udc->gadget);
if (retval) {
dev_err(&udc->dev->dev,
"unable to register peripheral to otg\n");
if (driver->unbind) {
driver->unbind(&udc->gadget);
udc->gadget.dev.driver = NULL;
udc->driver = NULL;
}
return retval;
}
}
/* pullup is always on */
mv_udc_pullup(&udc->gadget, 1);
@ -2026,6 +2060,10 @@ static irqreturn_t mv_udc_irq(int irq, void *dev)
struct mv_udc *udc = (struct mv_udc *)dev;
u32 status, intr;
/* Disable ISR when stopped bit is set */
if (udc->stopped)
return IRQ_NONE;
spin_lock(&udc->lock);
status = readl(&udc->op_regs->usbsts);
@ -2109,7 +2147,12 @@ static int __devexit mv_udc_remove(struct platform_device *dev)
destroy_workqueue(udc->qwork);
}
if (udc->pdata && udc->pdata->vbus && udc->clock_gating)
/*
* If we have transceiver inited,
* then vbus irq will not be requested in udc driver.
*/
if (udc->pdata && udc->pdata->vbus
&& udc->clock_gating && udc->transceiver == NULL)
free_irq(udc->pdata->vbus->irq, &dev->dev);
/* free memory allocated in probe */
@ -2182,6 +2225,11 @@ static int __devinit mv_udc_probe(struct platform_device *dev)
udc->dev = dev;
#ifdef CONFIG_USB_OTG_UTILS
if (pdata->mode == MV_USB_MODE_OTG)
udc->transceiver = otg_get_transceiver();
#endif
udc->clknum = pdata->clknum;
for (clk_i = 0; clk_i < udc->clknum; clk_i++) {
udc->clk[clk_i] = clk_get(&dev->dev, pdata->clkname[clk_i]);
@ -2221,14 +2269,9 @@ static int __devinit mv_udc_probe(struct platform_device *dev)
}
/* we will acces controller register, so enable the clk */
udc_clock_enable(udc);
if (pdata->phy_init) {
retval = pdata->phy_init(udc->phy_regs);
if (retval) {
dev_err(&dev->dev, "phy init error %d\n", retval);
goto err_iounmap_phyreg;
}
}
retval = mv_udc_enable_internal(udc);
if (retval)
goto err_iounmap_phyreg;
udc->op_regs = (struct mv_op_regs __iomem *)((u32)udc->cap_regs
+ (readl(&udc->cap_regs->caplength_hciversion)
@ -2312,7 +2355,7 @@ static int __devinit mv_udc_probe(struct platform_device *dev)
udc->gadget.ep0 = &udc->eps[0].ep; /* gadget ep0 */
INIT_LIST_HEAD(&udc->gadget.ep_list); /* ep_list */
udc->gadget.speed = USB_SPEED_UNKNOWN; /* speed */
udc->gadget.is_dualspeed = 1; /* support dual speed */
udc->gadget.max_speed = USB_SPEED_HIGH; /* support dual speed */
/* the "gadget" abstracts/virtualizes the controller */
dev_set_name(&udc->gadget.dev, "gadget");
@ -2328,7 +2371,9 @@ static int __devinit mv_udc_probe(struct platform_device *dev)
eps_init(udc);
/* VBUS detect: we can disable/enable clock on demand.*/
if (pdata->vbus) {
if (udc->transceiver)
udc->clock_gating = 1;
else if (pdata->vbus) {
udc->clock_gating = 1;
retval = request_threaded_irq(pdata->vbus->irq, NULL,
mv_udc_vbus_irq, IRQF_ONESHOT, "vbus", udc);
@ -2354,11 +2399,9 @@ static int __devinit mv_udc_probe(struct platform_device *dev)
* If not, it means that VBUS detection is not supported, we
* have to enable vbus active all the time to let controller work.
*/
if (udc->clock_gating) {
if (udc->pdata->phy_deinit)
udc->pdata->phy_deinit(udc->phy_regs);
udc_clock_disable(udc);
} else
if (udc->clock_gating)
mv_udc_disable_internal(udc);
else
udc->vbus_active = 1;
retval = usb_add_gadget_udc(&dev->dev, &udc->gadget);
@ -2371,7 +2414,8 @@ static int __devinit mv_udc_probe(struct platform_device *dev)
return 0;
err_unregister:
if (udc->pdata && udc->pdata->vbus && udc->clock_gating)
if (udc->pdata && udc->pdata->vbus
&& udc->clock_gating && udc->transceiver == NULL)
free_irq(pdata->vbus->irq, &dev->dev);
device_unregister(&udc->gadget.dev);
err_free_irq:
@ -2387,9 +2431,7 @@ err_free_dma:
dma_free_coherent(&dev->dev, udc->ep_dqh_size,
udc->ep_dqh, udc->ep_dqh_dma);
err_disable_clock:
if (udc->pdata->phy_deinit)
udc->pdata->phy_deinit(udc->phy_regs);
udc_clock_disable(udc);
mv_udc_disable_internal(udc);
err_iounmap_phyreg:
iounmap((void *)udc->phy_regs);
err_iounmap_capreg:
@ -2407,7 +2449,30 @@ static int mv_udc_suspend(struct device *_dev)
{
struct mv_udc *udc = the_controller;
udc_stop(udc);
/* if OTG is enabled, the following will be done in OTG driver*/
if (udc->transceiver)
return 0;
if (udc->pdata->vbus && udc->pdata->vbus->poll)
if (udc->pdata->vbus->poll() == VBUS_HIGH) {
dev_info(&udc->dev->dev, "USB cable is connected!\n");
return -EAGAIN;
}
/*
* only cable is unplugged, udc can suspend.
* So do not care about clock_gating == 1.
*/
if (!udc->clock_gating) {
udc_stop(udc);
spin_lock_irq(&udc->lock);
/* stop all usb activities */
stop_activity(udc, udc->driver);
spin_unlock_irq(&udc->lock);
mv_udc_disable_internal(udc);
}
return 0;
}
@ -2417,20 +2482,22 @@ static int mv_udc_resume(struct device *_dev)
struct mv_udc *udc = the_controller;
int retval;
if (udc->pdata->phy_init) {
retval = udc->pdata->phy_init(udc->phy_regs);
if (retval) {
dev_err(&udc->dev->dev,
"init phy error %d when resume back\n",
retval);
/* if OTG is enabled, the following will be done in OTG driver*/
if (udc->transceiver)
return 0;
if (!udc->clock_gating) {
retval = mv_udc_enable_internal(udc);
if (retval)
return retval;
if (udc->driver && udc->softconnect) {
udc_reset(udc);
ep0_reset(udc);
udc_start(udc);
}
}
udc_reset(udc);
ep0_reset(udc);
udc_start(udc);
return 0;
}

View File

@ -1459,7 +1459,7 @@ static int net2272_start(struct usb_gadget *_gadget,
unsigned i;
if (!driver || !driver->unbind || !driver->setup ||
driver->speed != USB_SPEED_HIGH)
driver->max_speed != USB_SPEED_HIGH)
return -EINVAL;
dev = container_of(_gadget, struct net2272, gadget);
@ -2235,7 +2235,7 @@ net2272_probe_init(struct device *dev, unsigned int irq)
ret->irq = irq;
ret->dev = dev;
ret->gadget.ops = &net2272_ops;
ret->gadget.is_dualspeed = 1;
ret->gadget.max_speed = USB_SPEED_HIGH;
/* the "gadget" abstracts/virtualizes the controller */
dev_set_name(&ret->gadget.dev, "gadget");

View File

@ -1881,7 +1881,7 @@ static int net2280_start(struct usb_gadget *_gadget,
* (dev->usb->xcvrdiag & FORCE_FULL_SPEED_MODE)
* "must not be used in normal operation"
*/
if (!driver || driver->speed < USB_SPEED_HIGH
if (!driver || driver->max_speed < USB_SPEED_HIGH
|| !driver->setup)
return -EINVAL;
@ -2698,7 +2698,7 @@ static int net2280_probe (struct pci_dev *pdev, const struct pci_device_id *id)
spin_lock_init (&dev->lock);
dev->pdev = pdev;
dev->gadget.ops = &net2280_ops;
dev->gadget.is_dualspeed = 1;
dev->gadget.max_speed = USB_SPEED_HIGH;
/* the "gadget" abstracts/virtualizes the controller */
dev_set_name(&dev->gadget.dev, "gadget");

View File

@ -2110,7 +2110,7 @@ static int omap_udc_start(struct usb_gadget_driver *driver,
return -ENODEV;
if (!driver
// FIXME if otg, check: driver->is_otg
|| driver->speed < USB_SPEED_FULL
|| driver->max_speed < USB_SPEED_FULL
|| !bind || !driver->setup)
return -EINVAL;
@ -2676,6 +2676,7 @@ omap_udc_setup(struct platform_device *odev, struct otg_transceiver *xceiv)
INIT_LIST_HEAD(&udc->gadget.ep_list);
INIT_LIST_HEAD(&udc->iso);
udc->gadget.speed = USB_SPEED_UNKNOWN;
udc->gadget.max_speed = USB_SPEED_FULL;
udc->gadget.name = driver_name;
device_initialize(&udc->gadget.dev);

View File

@ -2693,7 +2693,7 @@ static int pch_udc_start(struct usb_gadget_driver *driver,
struct pch_udc_dev *dev = pch_udc;
int retval;
if (!driver || (driver->speed == USB_SPEED_UNKNOWN) || !bind ||
if (!driver || (driver->max_speed == USB_SPEED_UNKNOWN) || !bind ||
!driver->setup || !driver->unbind || !driver->disconnect) {
dev_err(&dev->pdev->dev,
"%s: invalid driver parameter\n", __func__);
@ -2941,7 +2941,7 @@ static int pch_udc_probe(struct pci_dev *pdev,
dev->gadget.dev.dma_mask = pdev->dev.dma_mask;
dev->gadget.dev.release = gadget_release;
dev->gadget.name = KBUILD_MODNAME;
dev->gadget.is_dualspeed = 1;
dev->gadget.max_speed = USB_SPEED_HIGH;
retval = device_register(&dev->gadget.dev);
if (retval)

View File

@ -1141,7 +1141,7 @@ printer_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl)
break;
#ifdef CONFIG_USB_GADGET_DUALSPEED
case USB_DT_DEVICE_QUALIFIER:
if (!gadget->is_dualspeed)
if (!gadget_is_dualspeed(gadget))
break;
/*
* assumes ep0 uses the same value for both
@ -1155,7 +1155,7 @@ printer_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl)
break;
case USB_DT_OTHER_SPEED_CONFIG:
if (!gadget->is_dualspeed)
if (!gadget_is_dualspeed(gadget))
break;
/* FALLTHROUGH */
#endif /* CONFIG_USB_GADGET_DUALSPEED */
@ -1535,7 +1535,7 @@ fail:
/*-------------------------------------------------------------------------*/
static struct usb_gadget_driver printer_driver = {
.speed = DEVSPEED,
.max_speed = DEVSPEED,
.function = (char *) driver_desc,
.unbind = printer_unbind,

View File

@ -1264,7 +1264,7 @@ static int pxa25x_start(struct usb_gadget_driver *driver,
int retval;
if (!driver
|| driver->speed < USB_SPEED_FULL
|| driver->max_speed < USB_SPEED_FULL
|| !bind
|| !driver->disconnect
|| !driver->setup)

View File

@ -1807,7 +1807,7 @@ static int pxa27x_udc_start(struct usb_gadget_driver *driver,
struct pxa_udc *udc = the_controller;
int retval;
if (!driver || driver->speed < USB_SPEED_FULL || !bind
if (!driver || driver->max_speed < USB_SPEED_FULL || !bind
|| !driver->disconnect || !driver->setup)
return -EINVAL;
if (!udc)

View File

@ -1746,7 +1746,7 @@ static int r8a66597_start(struct usb_gadget *gadget,
struct r8a66597 *r8a66597 = gadget_to_r8a66597(gadget);
if (!driver
|| driver->speed < USB_SPEED_HIGH
|| driver->max_speed < USB_SPEED_HIGH
|| !driver->setup)
return -EINVAL;
if (!r8a66597)
@ -1911,7 +1911,7 @@ static int __init r8a66597_probe(struct platform_device *pdev)
r8a66597->gadget.ops = &r8a66597_gadget_ops;
dev_set_name(&r8a66597->gadget.dev, "gadget");
r8a66597->gadget.is_dualspeed = 1;
r8a66597->gadget.max_speed = USB_SPEED_HIGH;
r8a66597->gadget.dev.parent = &pdev->dev;
r8a66597->gadget.dev.dma_mask = pdev->dev.dma_mask;
r8a66597->gadget.dev.release = pdev->dev.release;

View File

@ -2586,7 +2586,7 @@ static int s3c_hsotg_start(struct usb_gadget_driver *driver,
return -EINVAL;
}
if (driver->speed < USB_SPEED_FULL)
if (driver->max_speed < USB_SPEED_FULL)
dev_err(hsotg->dev, "%s: bad speed\n", __func__);
if (!bind || !driver->setup) {
@ -3362,7 +3362,7 @@ static int __devinit s3c_hsotg_probe(struct platform_device *pdev)
dev_set_name(&hsotg->gadget.dev, "gadget");
hsotg->gadget.is_dualspeed = 1;
hsotg->gadget.max_speed = USB_SPEED_HIGH;
hsotg->gadget.ops = &s3c_hsotg_gadget_ops;
hsotg->gadget.name = dev_name(dev);

View File

@ -1142,7 +1142,7 @@ static int s3c_hsudc_start(struct usb_gadget_driver *driver,
int ret;
if (!driver
|| driver->speed < USB_SPEED_FULL
|| driver->max_speed < USB_SPEED_FULL
|| !bind
|| !driver->unbind || !driver->disconnect || !driver->setup)
return -EINVAL;
@ -1310,7 +1310,7 @@ static int s3c_hsudc_probe(struct platform_device *pdev)
device_initialize(&hsudc->gadget.dev);
dev_set_name(&hsudc->gadget.dev, "gadget");
hsudc->gadget.is_dualspeed = 1;
hsudc->gadget.max_speed = USB_SPEED_HIGH;
hsudc->gadget.ops = &s3c_hsudc_gadget_ops;
hsudc->gadget.name = dev_name(dev);
hsudc->gadget.dev.parent = dev;

View File

@ -1683,9 +1683,9 @@ static int s3c2410_udc_start(struct usb_gadget_driver *driver,
if (udc->driver)
return -EBUSY;
if (!bind || !driver->setup || driver->speed < USB_SPEED_FULL) {
if (!bind || !driver->setup || driver->max_speed < USB_SPEED_FULL) {
printk(KERN_ERR "Invalid driver: bind %p setup %p speed %d\n",
bind, driver->setup, driver->speed);
bind, driver->setup, driver->max_speed);
return -EINVAL;
}
#if defined(MODULE)

View File

@ -371,14 +371,28 @@ static ssize_t usb_udc_softconn_store(struct device *dev,
}
static DEVICE_ATTR(soft_connect, S_IWUSR, NULL, usb_udc_softconn_store);
static ssize_t usb_udc_speed_show(struct device *dev,
#define USB_UDC_SPEED_ATTR(name, param) \
ssize_t usb_udc_##param##_show(struct device *dev, \
struct device_attribute *attr, char *buf) \
{ \
struct usb_udc *udc = container_of(dev, struct usb_udc, dev); \
return snprintf(buf, PAGE_SIZE, "%s\n", \
usb_speed_string(udc->gadget->param)); \
} \
static DEVICE_ATTR(name, S_IRUSR, usb_udc_##param##_show, NULL)
static USB_UDC_SPEED_ATTR(current_speed, speed);
static USB_UDC_SPEED_ATTR(maximum_speed, max_speed);
/* TODO: Scheduled for removal in 3.8. */
static ssize_t usb_udc_is_dualspeed_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct usb_udc *udc = container_of(dev, struct usb_udc, dev);
return snprintf(buf, PAGE_SIZE, "%s\n",
usb_speed_string(udc->gadget->speed));
return snprintf(buf, PAGE_SIZE, "%d\n",
gadget_is_dualspeed(udc->gadget));
}
static DEVICE_ATTR(speed, S_IRUGO, usb_udc_speed_show, NULL);
static DEVICE_ATTR(is_dualspeed, S_IRUSR, usb_udc_is_dualspeed_show, NULL);
#define USB_UDC_ATTR(name) \
ssize_t usb_udc_##name##_show(struct device *dev, \
@ -391,7 +405,6 @@ ssize_t usb_udc_##name##_show(struct device *dev, \
} \
static DEVICE_ATTR(name, S_IRUGO, usb_udc_##name##_show, NULL)
static USB_UDC_ATTR(is_dualspeed);
static USB_UDC_ATTR(is_otg);
static USB_UDC_ATTR(is_a_peripheral);
static USB_UDC_ATTR(b_hnp_enable);
@ -401,7 +414,8 @@ static USB_UDC_ATTR(a_alt_hnp_support);
static struct attribute *usb_udc_attrs[] = {
&dev_attr_srp.attr,
&dev_attr_soft_connect.attr,
&dev_attr_speed.attr,
&dev_attr_current_speed.attr,
&dev_attr_maximum_speed.attr,
&dev_attr_is_dualspeed.attr,
&dev_attr_is_otg.attr,

View File

@ -1842,7 +1842,7 @@ int __init musb_gadget_setup(struct musb *musb)
*/
musb->g.ops = &musb_gadget_operations;
musb->g.is_dualspeed = 1;
musb->g.max_speed = USB_SPEED_HIGH;
musb->g.speed = USB_SPEED_UNKNOWN;
/* this "gadget" abstracts/virtualizes the controller */
@ -1901,7 +1901,7 @@ static int musb_gadget_start(struct usb_gadget *g,
unsigned long flags;
int retval = -EINVAL;
if (driver->speed < USB_SPEED_HIGH)
if (driver->max_speed < USB_SPEED_HIGH)
goto err0;
pm_runtime_get_sync(musb->controller);

View File

@ -95,25 +95,15 @@ struct usbhs_priv *usbhs_pdev_to_priv(struct platform_device *pdev)
/*
* syscfg functions
*/
void usbhs_sys_clock_ctrl(struct usbhs_priv *priv, int enable)
static void usbhs_sys_clock_ctrl(struct usbhs_priv *priv, int enable)
{
usbhs_bset(priv, SYSCFG, SCKE, enable ? SCKE : 0);
}
void usbhs_sys_hispeed_ctrl(struct usbhs_priv *priv, int enable)
{
usbhs_bset(priv, SYSCFG, HSE, enable ? HSE : 0);
}
void usbhs_sys_usb_ctrl(struct usbhs_priv *priv, int enable)
{
usbhs_bset(priv, SYSCFG, USBE, enable ? USBE : 0);
}
void usbhs_sys_host_ctrl(struct usbhs_priv *priv, int enable)
{
u16 mask = DCFM | DRPD | DPRPU;
u16 val = DCFM | DRPD;
u16 mask = DCFM | DRPD | DPRPU | HSE | USBE;
u16 val = DCFM | DRPD | HSE | USBE;
int has_otg = usbhs_get_dparam(priv, has_otg);
if (has_otg)
@ -130,8 +120,8 @@ void usbhs_sys_host_ctrl(struct usbhs_priv *priv, int enable)
void usbhs_sys_function_ctrl(struct usbhs_priv *priv, int enable)
{
u16 mask = DCFM | DRPD | DPRPU;
u16 val = DPRPU;
u16 mask = DCFM | DRPD | DPRPU | HSE | USBE;
u16 val = DPRPU | HSE | USBE;
/*
* if enable
@ -142,6 +132,11 @@ void usbhs_sys_function_ctrl(struct usbhs_priv *priv, int enable)
usbhs_bset(priv, SYSCFG, mask, enable ? val : 0);
}
void usbhs_sys_set_test_mode(struct usbhs_priv *priv, u16 mode)
{
usbhs_write(priv, TESTMODE, mode);
}
/*
* frame functions
*/
@ -229,7 +224,7 @@ static void usbhsc_bus_init(struct usbhs_priv *priv)
/*
* device configuration
*/
int usbhs_set_device_speed(struct usbhs_priv *priv, int devnum,
int usbhs_set_device_config(struct usbhs_priv *priv, int devnum,
u16 upphub, u16 hubport, u16 speed)
{
struct device *dev = usbhs_priv_to_dev(priv);
@ -301,18 +296,25 @@ static u32 usbhsc_default_pipe_type[] = {
*/
static void usbhsc_power_ctrl(struct usbhs_priv *priv, int enable)
{
struct platform_device *pdev = usbhs_priv_to_pdev(priv);
struct device *dev = usbhs_priv_to_dev(priv);
if (enable) {
/* enable PM */
pm_runtime_get_sync(dev);
/* enable platform power */
usbhs_platform_call(priv, power_ctrl, pdev, priv->base, enable);
/* USB on */
usbhs_sys_clock_ctrl(priv, enable);
} else {
/* USB off */
usbhs_sys_clock_ctrl(priv, enable);
/* disable platform power */
usbhs_platform_call(priv, power_ctrl, pdev, priv->base, enable);
/* disable PM */
pm_runtime_put_sync(dev);
}
@ -388,7 +390,7 @@ static void usbhsc_notify_hotplug(struct work_struct *work)
usbhsc_hotplug(priv);
}
int usbhsc_drvcllbck_notify_hotplug(struct platform_device *pdev)
static int usbhsc_drvcllbck_notify_hotplug(struct platform_device *pdev)
{
struct usbhs_priv *priv = usbhs_pdev_to_priv(pdev);
int delay = usbhs_get_dparam(priv, detection_delay);
@ -398,7 +400,8 @@ int usbhsc_drvcllbck_notify_hotplug(struct platform_device *pdev)
* To make sure safety context,
* use workqueue for usbhs_notify_hotplug
*/
schedule_delayed_work(&priv->notify_hotplug_work, delay);
schedule_delayed_work(&priv->notify_hotplug_work,
msecs_to_jiffies(delay));
return 0;
}

View File

@ -33,6 +33,7 @@ struct usbhs_priv;
#define SYSCFG 0x0000
#define BUSWAIT 0x0002
#define DVSTCTR 0x0008
#define TESTMODE 0x000C
#define CFIFO 0x0014
#define CFIFOSEL 0x0020
#define CFIFOCTR 0x0022
@ -275,19 +276,15 @@ u16 usbhs_read(struct usbhs_priv *priv, u32 reg);
void usbhs_write(struct usbhs_priv *priv, u32 reg, u16 data);
void usbhs_bset(struct usbhs_priv *priv, u32 reg, u16 mask, u16 data);
int usbhsc_drvcllbck_notify_hotplug(struct platform_device *pdev);
#define usbhs_lock(p, f) spin_lock_irqsave(usbhs_priv_to_lock(p), f)
#define usbhs_unlock(p, f) spin_unlock_irqrestore(usbhs_priv_to_lock(p), f)
/*
* sysconfig
*/
void usbhs_sys_clock_ctrl(struct usbhs_priv *priv, int enable);
void usbhs_sys_hispeed_ctrl(struct usbhs_priv *priv, int enable);
void usbhs_sys_usb_ctrl(struct usbhs_priv *priv, int enable);
void usbhs_sys_host_ctrl(struct usbhs_priv *priv, int enable);
void usbhs_sys_function_ctrl(struct usbhs_priv *priv, int enable);
void usbhs_sys_set_test_mode(struct usbhs_priv *priv, u16 mode);
/*
* usb request
@ -311,7 +308,7 @@ int usbhs_frame_get_num(struct usbhs_priv *priv);
/*
* device config
*/
int usbhs_set_device_speed(struct usbhs_priv *priv, int devnum, u16 upphub,
int usbhs_set_device_config(struct usbhs_priv *priv, int devnum, u16 upphub,
u16 hubport, u16 speed);
/*

View File

@ -56,7 +56,7 @@ static struct usbhs_pkt_handle usbhsf_null_handler = {
void usbhs_pkt_push(struct usbhs_pipe *pipe, struct usbhs_pkt *pkt,
void (*done)(struct usbhs_priv *priv,
struct usbhs_pkt *pkt),
void *buf, int len, int zero)
void *buf, int len, int zero, int sequence)
{
struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);
struct device *dev = usbhs_priv_to_dev(priv);
@ -90,6 +90,7 @@ void usbhs_pkt_push(struct usbhs_pipe *pipe, struct usbhs_pkt *pkt,
pkt->zero = zero;
pkt->actual = 0;
pkt->done = done;
pkt->sequence = sequence;
usbhs_unlock(priv, flags);
/******************** spin unlock ******************/
@ -481,6 +482,9 @@ static int usbhsf_pio_try_push(struct usbhs_pkt *pkt, int *is_done)
int i, ret, len;
int is_short;
usbhs_pipe_data_sequence(pipe, pkt->sequence);
pkt->sequence = -1; /* -1 sequence will be ignored */
ret = usbhsf_fifo_select(pipe, fifo, 1);
if (ret < 0)
return 0;
@ -584,6 +588,8 @@ static int usbhsf_prepare_pop(struct usbhs_pkt *pkt, int *is_done)
/*
* pipe enable to prepare packet receive
*/
usbhs_pipe_data_sequence(pipe, pkt->sequence);
pkt->sequence = -1; /* -1 sequence will be ignored */
usbhs_pipe_enable(pipe);
usbhsf_rx_irq_ctrl(pipe, 1);
@ -641,6 +647,7 @@ static int usbhsf_pio_try_pop(struct usbhs_pkt *pkt, int *is_done)
* "Operation" - "FIFO Buffer Memory" - "FIFO Port Function"
*/
if (0 == rcv_len) {
pkt->zero = 1;
usbhsf_fifo_clear(pipe, fifo);
goto usbhs_fifo_read_end;
}

View File

@ -59,6 +59,7 @@ struct usbhs_pkt {
int trans;
int actual;
int zero;
int sequence;
};
struct usbhs_pkt_handle {
@ -95,7 +96,7 @@ void usbhs_pkt_init(struct usbhs_pkt *pkt);
void usbhs_pkt_push(struct usbhs_pipe *pipe, struct usbhs_pkt *pkt,
void (*done)(struct usbhs_priv *priv,
struct usbhs_pkt *pkt),
void *buf, int len, int zero);
void *buf, int len, int zero, int sequence);
struct usbhs_pkt *usbhs_pkt_pop(struct usbhs_pipe *pipe, struct usbhs_pkt *pkt);
void usbhs_pkt_start(struct usbhs_pipe *pipe);

View File

@ -50,7 +50,9 @@ static int usbhsm_autonomy_irq_vbus(struct usbhs_priv *priv,
{
struct platform_device *pdev = usbhs_priv_to_pdev(priv);
return usbhsc_drvcllbck_notify_hotplug(pdev);
renesas_usbhs_call_notify_hotplug(pdev);
return 0;
}
void usbhs_mod_autonomy_mode(struct usbhs_priv *priv)

View File

@ -14,6 +14,7 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#include <linux/delay.h>
#include <linux/dma-mapping.h>
#include <linux/io.h>
#include <linux/module.h>
@ -44,7 +45,6 @@ struct usbhsg_uep {
struct usbhsg_gpriv {
struct usb_gadget gadget;
struct usbhs_mod mod;
struct list_head link;
struct usbhsg_uep *uep;
int uep_size;
@ -114,16 +114,6 @@ struct usbhsg_recip_handle {
#define usbhsg_status_clr(gp, b) (gp->status &= ~b)
#define usbhsg_status_has(gp, b) (gp->status & b)
/* controller */
LIST_HEAD(the_controller_link);
#define usbhsg_for_each_controller(gpriv)\
list_for_each_entry(gpriv, &the_controller_link, link)
#define usbhsg_controller_register(gpriv)\
list_add_tail(&(gpriv)->link, &the_controller_link)
#define usbhsg_controller_unregister(gpriv)\
list_del_init(&(gpriv)->link)
/*
* queue push/pop
*/
@ -164,7 +154,7 @@ static void usbhsg_queue_push(struct usbhsg_uep *uep,
req->actual = 0;
req->status = -EINPROGRESS;
usbhs_pkt_push(pipe, pkt, usbhsg_queue_done,
req->buf, req->length, req->zero);
req->buf, req->length, req->zero, -1);
usbhs_pkt_start(pipe);
dev_dbg(dev, "pipe %d : queue push (%d)\n",
@ -271,6 +261,8 @@ static int usbhsg_recip_handler_std_clear_endpoint(struct usbhs_priv *priv,
usbhsg_recip_handler_std_control_done(priv, uep, ctrl);
usbhs_pkt_start(pipe);
return 0;
}
@ -281,6 +273,145 @@ struct usbhsg_recip_handle req_clear_feature = {
.endpoint = usbhsg_recip_handler_std_clear_endpoint,
};
/*
* USB_TYPE_STANDARD / set feature functions
*/
static int usbhsg_recip_handler_std_set_device(struct usbhs_priv *priv,
struct usbhsg_uep *uep,
struct usb_ctrlrequest *ctrl)
{
switch (le16_to_cpu(ctrl->wValue)) {
case USB_DEVICE_TEST_MODE:
usbhsg_recip_handler_std_control_done(priv, uep, ctrl);
udelay(100);
usbhs_sys_set_test_mode(priv, le16_to_cpu(ctrl->wIndex >> 8));
break;
default:
usbhsg_recip_handler_std_control_done(priv, uep, ctrl);
break;
}
return 0;
}
static int usbhsg_recip_handler_std_set_endpoint(struct usbhs_priv *priv,
struct usbhsg_uep *uep,
struct usb_ctrlrequest *ctrl)
{
struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(uep);
usbhs_pipe_stall(pipe);
usbhsg_recip_handler_std_control_done(priv, uep, ctrl);
return 0;
}
struct usbhsg_recip_handle req_set_feature = {
.name = "set feature",
.device = usbhsg_recip_handler_std_set_device,
.interface = usbhsg_recip_handler_std_control_done,
.endpoint = usbhsg_recip_handler_std_set_endpoint,
};
/*
* USB_TYPE_STANDARD / get status functions
*/
static void __usbhsg_recip_send_complete(struct usb_ep *ep,
struct usb_request *req)
{
struct usbhsg_request *ureq = usbhsg_req_to_ureq(req);
/* free allocated recip-buffer/usb_request */
kfree(ureq->pkt.buf);
usb_ep_free_request(ep, req);
}
static void __usbhsg_recip_send_status(struct usbhsg_gpriv *gpriv,
unsigned short status)
{
struct usbhsg_uep *dcp = usbhsg_gpriv_to_dcp(gpriv);
struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(dcp);
struct device *dev = usbhsg_gpriv_to_dev(gpriv);
struct usb_request *req;
unsigned short *buf;
/* alloc new usb_request for recip */
req = usb_ep_alloc_request(&dcp->ep, GFP_ATOMIC);
if (!req) {
dev_err(dev, "recip request allocation fail\n");
return;
}
/* alloc recip data buffer */
buf = kmalloc(sizeof(*buf), GFP_ATOMIC);
if (!buf) {
usb_ep_free_request(&dcp->ep, req);
dev_err(dev, "recip data allocation fail\n");
return;
}
/* recip data is status */
*buf = cpu_to_le16(status);
/* allocated usb_request/buffer will be freed */
req->complete = __usbhsg_recip_send_complete;
req->buf = buf;
req->length = sizeof(*buf);
req->zero = 0;
/* push packet */
pipe->handler = &usbhs_fifo_pio_push_handler;
usbhsg_queue_push(dcp, usbhsg_req_to_ureq(req));
}
static int usbhsg_recip_handler_std_get_device(struct usbhs_priv *priv,
struct usbhsg_uep *uep,
struct usb_ctrlrequest *ctrl)
{
struct usbhsg_gpriv *gpriv = usbhsg_uep_to_gpriv(uep);
unsigned short status = 1 << USB_DEVICE_SELF_POWERED;
__usbhsg_recip_send_status(gpriv, status);
return 0;
}
static int usbhsg_recip_handler_std_get_interface(struct usbhs_priv *priv,
struct usbhsg_uep *uep,
struct usb_ctrlrequest *ctrl)
{
struct usbhsg_gpriv *gpriv = usbhsg_uep_to_gpriv(uep);
unsigned short status = 0;
__usbhsg_recip_send_status(gpriv, status);
return 0;
}
static int usbhsg_recip_handler_std_get_endpoint(struct usbhs_priv *priv,
struct usbhsg_uep *uep,
struct usb_ctrlrequest *ctrl)
{
struct usbhsg_gpriv *gpriv = usbhsg_uep_to_gpriv(uep);
struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(uep);
unsigned short status = 0;
if (usbhs_pipe_is_stall(pipe))
status = 1 << USB_ENDPOINT_HALT;
__usbhsg_recip_send_status(gpriv, status);
return 0;
}
struct usbhsg_recip_handle req_get_status = {
.name = "get status",
.device = usbhsg_recip_handler_std_get_device,
.interface = usbhsg_recip_handler_std_get_interface,
.endpoint = usbhsg_recip_handler_std_get_endpoint,
};
/*
* USB_TYPE handler
*/
@ -303,8 +434,7 @@ static int usbhsg_recip_run_handle(struct usbhs_priv *priv,
pipe = usbhsg_uep_to_pipe(uep);
if (!pipe) {
dev_err(dev, "wrong recip request\n");
ret = -EINVAL;
goto usbhsg_recip_run_handle_end;
return -EINVAL;
}
switch (recip) {
@ -327,20 +457,10 @@ static int usbhsg_recip_run_handle(struct usbhs_priv *priv,
}
if (func) {
unsigned long flags;
dev_dbg(dev, "%s (pipe %d :%s)\n", handler->name, nth, msg);
/******************** spin lock ********************/
usbhs_lock(priv, flags);
ret = func(priv, uep, ctrl);
usbhs_unlock(priv, flags);
/******************** spin unlock ******************/
}
usbhsg_recip_run_handle_end:
usbhs_pkt_start(pipe);
return ret;
}
@ -412,6 +532,12 @@ static int usbhsg_irq_ctrl_stage(struct usbhs_priv *priv,
case USB_REQ_CLEAR_FEATURE:
recip_handler = &req_clear_feature;
break;
case USB_REQ_SET_FEATURE:
recip_handler = &req_set_feature;
break;
case USB_REQ_GET_STATUS:
recip_handler = &req_get_status;
break;
}
}
@ -439,14 +565,16 @@ static int usbhsg_pipe_disable(struct usbhsg_uep *uep)
struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(uep);
struct usbhs_pkt *pkt;
usbhs_pipe_disable(pipe);
while (1) {
pkt = usbhs_pkt_pop(pipe, NULL);
if (!pkt)
break;
usbhsg_queue_pop(uep, usbhsg_pkt_to_ureq(pkt), -ECONNRESET);
}
usbhs_pipe_disable(pipe);
return 0;
}
@ -681,9 +809,7 @@ static int usbhsg_try_start(struct usbhs_priv *priv, u32 status)
* - function
* - usb module
*/
usbhs_sys_hispeed_ctrl(priv, 1);
usbhs_sys_function_ctrl(priv, 1);
usbhs_sys_usb_ctrl(priv, 1);
/*
* enable irq callback
@ -731,9 +857,8 @@ static int usbhsg_try_stop(struct usbhs_priv *priv, u32 status)
gpriv->gadget.speed = USB_SPEED_UNKNOWN;
/* disable sys */
usbhs_sys_hispeed_ctrl(priv, 0);
usbhs_sys_set_test_mode(priv, 0);
usbhs_sys_function_ctrl(priv, 0);
usbhs_sys_usb_ctrl(priv, 0);
usbhsg_pipe_disable(dcp);
@ -755,7 +880,7 @@ static int usbhsg_gadget_start(struct usb_gadget *gadget,
if (!driver ||
!driver->setup ||
driver->speed < USB_SPEED_FULL)
driver->max_speed < USB_SPEED_FULL)
return -EINVAL;
/* first hook up the driver ... */
@ -866,7 +991,7 @@ int usbhs_mod_gadget_probe(struct usbhs_priv *priv)
gpriv->gadget.dev.parent = dev;
gpriv->gadget.name = "renesas_usbhs_udc";
gpriv->gadget.ops = &usbhsg_gadget_ops;
gpriv->gadget.is_dualspeed = 1;
gpriv->gadget.max_speed = USB_SPEED_HIGH;
ret = device_register(&gpriv->gadget.dev);
if (ret < 0)
goto err_add_udc;
@ -896,8 +1021,6 @@ int usbhs_mod_gadget_probe(struct usbhs_priv *priv)
}
}
usbhsg_controller_register(gpriv);
ret = usb_add_gadget_udc(dev, &gpriv->gadget);
if (ret)
goto err_register;
@ -926,8 +1049,6 @@ void usbhs_mod_gadget_remove(struct usbhs_priv *priv)
device_unregister(&gpriv->gadget.dev);
usbhsg_controller_unregister(gpriv);
kfree(gpriv->uep);
kfree(gpriv);
}

File diff suppressed because it is too large Load Diff

View File

@ -257,6 +257,13 @@ void usbhs_pipe_stall(struct usbhs_pipe *pipe)
}
}
int usbhs_pipe_is_stall(struct usbhs_pipe *pipe)
{
u16 pid = usbhsp_pipectrl_get(pipe) & PID_MASK;
return (int)(pid == PID_STALL10 || pid == PID_STALL11);
}
/*
* pipe setup
*/
@ -471,10 +478,27 @@ int usbhs_pipe_is_dir_host(struct usbhs_pipe *pipe)
return usbhsp_flags_has(pipe, IS_DIR_HOST);
}
void usbhs_pipe_data_sequence(struct usbhs_pipe *pipe, int data)
void usbhs_pipe_data_sequence(struct usbhs_pipe *pipe, int sequence)
{
u16 mask = (SQCLR | SQSET);
u16 val = (data) ? SQSET : SQCLR;
u16 val;
/*
* sequence
* 0 : data0
* 1 : data1
* -1 : no change
*/
switch (sequence) {
case 0:
val = SQCLR;
break;
case 1:
val = SQSET;
break;
default:
return;
}
usbhsp_pipectrl_set(pipe, mask, val);
}

View File

@ -87,6 +87,7 @@ int usbhs_pipe_is_accessible(struct usbhs_pipe *pipe);
void usbhs_pipe_enable(struct usbhs_pipe *pipe);
void usbhs_pipe_disable(struct usbhs_pipe *pipe);
void usbhs_pipe_stall(struct usbhs_pipe *pipe);
int usbhs_pipe_is_stall(struct usbhs_pipe *pipe);
void usbhs_pipe_select_fifo(struct usbhs_pipe *pipe, struct usbhs_fifo *fifo);
void usbhs_pipe_config_update(struct usbhs_pipe *pipe, u16 devsel,
u16 epnum, u16 maxp);

View File

@ -477,8 +477,8 @@ struct usb_gadget_ops {
* driver setup() requests
* @ep_list: List of other endpoints supported by the device.
* @speed: Speed of current connection to USB host.
* @is_dualspeed: True if the controller supports both high and full speed
* operation. If it does, the gadget driver must also support both.
* @max_speed: Maximal speed the UDC can handle. UDC must support this
* and all slower speeds.
* @is_otg: True if the USB device port uses a Mini-AB jack, so that the
* gadget driver must provide a USB OTG descriptor.
* @is_a_peripheral: False unless is_otg, the "A" end of a USB cable
@ -518,7 +518,7 @@ struct usb_gadget {
struct usb_ep *ep0;
struct list_head ep_list; /* of usb_ep */
enum usb_device_speed speed;
unsigned is_dualspeed:1;
enum usb_device_speed max_speed;
unsigned is_otg:1;
unsigned is_a_peripheral:1;
unsigned b_hnp_enable:1;
@ -549,7 +549,7 @@ static inline struct usb_gadget *dev_to_usb_gadget(struct device *dev)
static inline int gadget_is_dualspeed(struct usb_gadget *g)
{
#ifdef CONFIG_USB_GADGET_DUALSPEED
/* runtime test would check "g->is_dualspeed" ... that might be
/* runtime test would check "g->max_speed" ... that might be
* useful to work around hardware bugs, but is mostly pointless
*/
return 1;
@ -567,7 +567,7 @@ static inline int gadget_is_superspeed(struct usb_gadget *g)
{
#ifdef CONFIG_USB_GADGET_SUPERSPEED
/*
* runtime test would check "g->is_superspeed" ... that might be
* runtime test would check "g->max_speed" ... that might be
* useful to work around hardware bugs, but is mostly pointless
*/
return 1;
@ -760,7 +760,7 @@ static inline int usb_gadget_disconnect(struct usb_gadget *gadget)
/**
* struct usb_gadget_driver - driver for usb 'slave' devices
* @function: String describing the gadget's function
* @speed: Highest speed the driver handles.
* @max_speed: Highest speed the driver handles.
* @setup: Invoked for ep0 control requests that aren't handled by
* the hardware level driver. Most calls must be handled by
* the gadget driver, including descriptor and configuration
@ -824,7 +824,7 @@ static inline int usb_gadget_disconnect(struct usb_gadget *gadget)
*/
struct usb_gadget_driver {
char *function;
enum usb_device_speed speed;
enum usb_device_speed max_speed;
void (*unbind)(struct usb_gadget *);
int (*setup)(struct usb_gadget *,
const struct usb_ctrlrequest *);

View File

@ -64,6 +64,14 @@ struct renesas_usbhs_platform_callback {
*/
void (*hardware_exit)(struct platform_device *pdev);
/*
* option:
*
* for board specific clock control
*/
void (*power_ctrl)(struct platform_device *pdev,
void __iomem *base, int enable);
/*
* option:
*
@ -118,7 +126,7 @@ struct renesas_usbhs_driver_param {
*
* delay time from notify_hotplug callback
*/
int detection_delay;
int detection_delay; /* msec */
/*
* option: