ERR("Can't respond to getstatus request \n");
goto stall;
}
+ /* Status phase */
+ if (ep0_prime_status(udc, EP_DIR_OUT))
+ ep0stall(udc);
return;
stall:
ep0stall(udc);
* This will be set when OTG support is added */
if (setup->wValue == USB_DEVICE_TEST_MODE)
ptc = setup->wIndex >> 8;
+ else if (setup->wValue == USB_DEVICE_REMOTE_WAKEUP) {
+ if (setup->bRequest == USB_REQ_SET_FEATURE)
+ udc->remote_wakeup = 1;
+ else
+ udc->remote_wakeup = 0;
+ }
else if (gadget_is_otg(&udc->gadget)) {
if (setup->bRequest ==
USB_DEVICE_B_HNP_ENABLE)
#endif /* CONFIG_USB_GADGET_DEBUG_FILES */
+/* sys entries for device control */
+static ssize_t fsl_udc_remote_wakeup_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ return sprintf(buf, "%d\n", udc_controller->remote_wakeup);
+}
+
+static ssize_t fsl_udc_remote_wakeup_store(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ int value;
+ unsigned long flags;
+ struct fsl_udc *udc = udc_controller;
+
+ spin_lock_irqsave(&udc->lock, flags);
+ if (udc_controller->stopped) {
+ pr_warning(KERN_ERR "Controller has already stopped, Quit.\n"
+ "Please make sure usb is online, and controller"
+ " is not stopped.\n");
+ spin_unlock_irqrestore(&udc->lock, flags);
+ return -ESHUTDOWN;
+ }
+
+ if (sscanf(buf, "%d", &value) != 1) {
+ printk(KERN_ERR "Only numeric 0/1 is valid\n");
+ spin_unlock_irqrestore(&udc->lock, flags);
+ return -EINVAL;
+ }
+ if (value == 0 || value == 1)
+ udc_controller->remote_wakeup = value;
+ else {
+ printk(KERN_ERR "Only numeric 0/1 is valid\n");
+ spin_unlock_irqrestore(&udc->lock, flags);
+ return -EINVAL;
+ }
+
+ spin_unlock_irqrestore(&udc->lock, flags);
+
+ return count;
+}
+
+static DEVICE_ATTR(remote_wakeup, S_IRUGO | S_IWUGO, fsl_udc_remote_wakeup_show,
+ fsl_udc_remote_wakeup_store);
+
+static ssize_t fsl_udc_start_remote_wakeup_store(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ int value;
+ unsigned long flags;
+ struct fsl_udc *udc = udc_controller;
+
+ spin_lock_irqsave(&udc->lock, flags);
+ if (udc_controller->stopped) {
+ pr_warning(KERN_ERR "Controller has already stopped, Quit.\n"
+ "Please make sure usb is online, and controller"
+ " is not stopped.\n");
+ spin_unlock_irqrestore(&udc->lock, flags);
+ return -ESHUTDOWN;
+ }
+
+ if (sscanf(buf, "%d", &value) != 1) {
+ printk(KERN_ERR "Only numeric 1 is valid\n");
+ spin_unlock_irqrestore(&udc->lock, flags);
+ return -EINVAL;
+ }
+
+ if (value != 1) {
+ printk(KERN_ERR "Only numeric 1 is valid\n");
+ spin_unlock_irqrestore(&udc->lock, flags);
+ return -EINVAL;
+ }
+
+ if (udc_controller->remote_wakeup == 1) {
+ u32 temp;
+ printk(KERN_INFO "Send Resume signal\n");
+ temp = fsl_readl(&dr_regs->portsc1);
+ temp |= PORTSCX_PORT_FORCE_RESUME;
+ fsl_writel(temp, &dr_regs->portsc1);
+ } else
+ printk(KERN_WARNING "udc remote wakeup has not enabled\n");
+
+ spin_unlock_irqrestore(&udc->lock, flags);
+
+ return count;
+}
+
+static DEVICE_ATTR(start_remote_wakeup, S_IWUGO, NULL,
+ fsl_udc_start_remote_wakeup_store);
+
+static struct attribute *fsl_udc_attrs[] = {
+ &dev_attr_remote_wakeup.attr,
+ &dev_attr_start_remote_wakeup.attr,
+ NULL,
+};
+
+static const struct attribute_group fsl_udc_attr_group = {
+ .attrs = fsl_udc_attrs,
+};
+
+static const struct attribute_group *fsl_udc_attr_groups[] = {
+ &fsl_udc_attr_group,
+ NULL,
+};
/*-------------------------------------------------------------------------*/
/* Release udc structures */
dev_set_name(&udc_controller->gadget.dev, "gadget");
udc_controller->gadget.dev.release = fsl_udc_release;
udc_controller->gadget.dev.parent = &pdev->dev;
+ udc_controller->gadget.dev.groups = fsl_udc_attr_groups;
ret = device_register(&udc_controller->gadget.dev);
if (ret < 0)
goto err3;
dr_clk_gate(false);
create_proc_file();
+
return 0;
err4: