forked from Minki/linux
USB driver fixes for 4.2-rc3
Here's some USB driver fixes for 4.2-rc3. The ususal number of gadget driver fixes are in here, along with some new device ids and a build fix for the mn10300 arch which required some symbols to be renamed in the mos7720 driver. All have been in linux-next for a while with no reported issues. Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> -----BEGIN PGP SIGNATURE----- Version: GnuPG v2 iEYEABECAAYFAlWpRQEACgkQMUfUDdst+ykQTACfbXmLNn/1ycArRysqHGg5llIZ pdIAn2Yi8TCbXr9HvtugUcxQrDIANNcF =WUtC -----END PGP SIGNATURE----- Merge tag 'usb-4.2-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb Pull USB driver fixes from Greg KH: "Here's some USB driver fixes for 4.2-rc3. The ususal number of gadget driver fixes are in here, along with some new device ids and a build fix for the mn10300 arch which required some symbols to be renamed in the mos7720 driver. All have been in linux-next for a while with no reported issues" * tag 'usb-4.2-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb: USB: serial: Destroy serial_minors IDR on module exit usb: gadget: f_midi: fix error recovery path usb: phy: mxs: suspend to RAM causes NULL pointer dereference usb: gadget: udc: fix free_irq() after request_irq() failed usb: gadget: composite: Fix NULL pointer dereference usb: gadget: f_fs: do not set cancel function on synchronous {read,write} usb: f_mass_storage: limit number of reported LUNs usb: dwc3: core: avoid NULL pointer dereference usb: dwc2: embed storage for reg backup in struct dwc2_hsotg usb: dwc2: host: allocate qtd before atomic enqueue usb: dwc2: host: allocate qh before atomic enqueue usb: musb: host: rely on port_mode to call musb_start() USB: cp210x: add ID for Aruba Networks controllers USB: mos7720: rename registers USB: option: add 2020:4000 ID
This commit is contained in:
commit
2b3eb6e337
@ -72,17 +72,7 @@ static int dwc2_backup_host_registers(struct dwc2_hsotg *hsotg)
|
||||
dev_dbg(hsotg->dev, "%s\n", __func__);
|
||||
|
||||
/* Backup Host regs */
|
||||
hr = hsotg->hr_backup;
|
||||
if (!hr) {
|
||||
hr = devm_kzalloc(hsotg->dev, sizeof(*hr), GFP_KERNEL);
|
||||
if (!hr) {
|
||||
dev_err(hsotg->dev, "%s: can't allocate host regs\n",
|
||||
__func__);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
hsotg->hr_backup = hr;
|
||||
}
|
||||
hr = &hsotg->hr_backup;
|
||||
hr->hcfg = readl(hsotg->regs + HCFG);
|
||||
hr->haintmsk = readl(hsotg->regs + HAINTMSK);
|
||||
for (i = 0; i < hsotg->core_params->host_channels; ++i)
|
||||
@ -90,6 +80,7 @@ static int dwc2_backup_host_registers(struct dwc2_hsotg *hsotg)
|
||||
|
||||
hr->hprt0 = readl(hsotg->regs + HPRT0);
|
||||
hr->hfir = readl(hsotg->regs + HFIR);
|
||||
hr->valid = true;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -109,12 +100,13 @@ static int dwc2_restore_host_registers(struct dwc2_hsotg *hsotg)
|
||||
dev_dbg(hsotg->dev, "%s\n", __func__);
|
||||
|
||||
/* Restore host regs */
|
||||
hr = hsotg->hr_backup;
|
||||
if (!hr) {
|
||||
hr = &hsotg->hr_backup;
|
||||
if (!hr->valid) {
|
||||
dev_err(hsotg->dev, "%s: no host registers to restore\n",
|
||||
__func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
hr->valid = false;
|
||||
|
||||
writel(hr->hcfg, hsotg->regs + HCFG);
|
||||
writel(hr->haintmsk, hsotg->regs + HAINTMSK);
|
||||
@ -152,17 +144,7 @@ static int dwc2_backup_device_registers(struct dwc2_hsotg *hsotg)
|
||||
dev_dbg(hsotg->dev, "%s\n", __func__);
|
||||
|
||||
/* Backup dev regs */
|
||||
dr = hsotg->dr_backup;
|
||||
if (!dr) {
|
||||
dr = devm_kzalloc(hsotg->dev, sizeof(*dr), GFP_KERNEL);
|
||||
if (!dr) {
|
||||
dev_err(hsotg->dev, "%s: can't allocate device regs\n",
|
||||
__func__);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
hsotg->dr_backup = dr;
|
||||
}
|
||||
dr = &hsotg->dr_backup;
|
||||
|
||||
dr->dcfg = readl(hsotg->regs + DCFG);
|
||||
dr->dctl = readl(hsotg->regs + DCTL);
|
||||
@ -195,7 +177,7 @@ static int dwc2_backup_device_registers(struct dwc2_hsotg *hsotg)
|
||||
dr->doeptsiz[i] = readl(hsotg->regs + DOEPTSIZ(i));
|
||||
dr->doepdma[i] = readl(hsotg->regs + DOEPDMA(i));
|
||||
}
|
||||
|
||||
dr->valid = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -215,12 +197,13 @@ static int dwc2_restore_device_registers(struct dwc2_hsotg *hsotg)
|
||||
dev_dbg(hsotg->dev, "%s\n", __func__);
|
||||
|
||||
/* Restore dev regs */
|
||||
dr = hsotg->dr_backup;
|
||||
if (!dr) {
|
||||
dr = &hsotg->dr_backup;
|
||||
if (!dr->valid) {
|
||||
dev_err(hsotg->dev, "%s: no device registers to restore\n",
|
||||
__func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
dr->valid = false;
|
||||
|
||||
writel(dr->dcfg, hsotg->regs + DCFG);
|
||||
writel(dr->dctl, hsotg->regs + DCTL);
|
||||
@ -268,17 +251,7 @@ static int dwc2_backup_global_registers(struct dwc2_hsotg *hsotg)
|
||||
int i;
|
||||
|
||||
/* Backup global regs */
|
||||
gr = hsotg->gr_backup;
|
||||
if (!gr) {
|
||||
gr = devm_kzalloc(hsotg->dev, sizeof(*gr), GFP_KERNEL);
|
||||
if (!gr) {
|
||||
dev_err(hsotg->dev, "%s: can't allocate global regs\n",
|
||||
__func__);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
hsotg->gr_backup = gr;
|
||||
}
|
||||
gr = &hsotg->gr_backup;
|
||||
|
||||
gr->gotgctl = readl(hsotg->regs + GOTGCTL);
|
||||
gr->gintmsk = readl(hsotg->regs + GINTMSK);
|
||||
@ -291,6 +264,7 @@ static int dwc2_backup_global_registers(struct dwc2_hsotg *hsotg)
|
||||
for (i = 0; i < MAX_EPS_CHANNELS; i++)
|
||||
gr->dtxfsiz[i] = readl(hsotg->regs + DPTXFSIZN(i));
|
||||
|
||||
gr->valid = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -309,12 +283,13 @@ static int dwc2_restore_global_registers(struct dwc2_hsotg *hsotg)
|
||||
dev_dbg(hsotg->dev, "%s\n", __func__);
|
||||
|
||||
/* Restore global regs */
|
||||
gr = hsotg->gr_backup;
|
||||
if (!gr) {
|
||||
gr = &hsotg->gr_backup;
|
||||
if (!gr->valid) {
|
||||
dev_err(hsotg->dev, "%s: no global registers to restore\n",
|
||||
__func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
gr->valid = false;
|
||||
|
||||
writel(0xffffffff, hsotg->regs + GINTSTS);
|
||||
writel(gr->gotgctl, hsotg->regs + GOTGCTL);
|
||||
|
@ -492,6 +492,7 @@ struct dwc2_gregs_backup {
|
||||
u32 gdfifocfg;
|
||||
u32 dtxfsiz[MAX_EPS_CHANNELS];
|
||||
u32 gpwrdn;
|
||||
bool valid;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -521,6 +522,7 @@ struct dwc2_dregs_backup {
|
||||
u32 doepctl[MAX_EPS_CHANNELS];
|
||||
u32 doeptsiz[MAX_EPS_CHANNELS];
|
||||
u32 doepdma[MAX_EPS_CHANNELS];
|
||||
bool valid;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -538,6 +540,7 @@ struct dwc2_hregs_backup {
|
||||
u32 hcintmsk[MAX_EPS_CHANNELS];
|
||||
u32 hprt0;
|
||||
u32 hfir;
|
||||
bool valid;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -705,9 +708,9 @@ struct dwc2_hsotg {
|
||||
struct work_struct wf_otg;
|
||||
struct timer_list wkp_timer;
|
||||
enum dwc2_lx_state lx_state;
|
||||
struct dwc2_gregs_backup *gr_backup;
|
||||
struct dwc2_dregs_backup *dr_backup;
|
||||
struct dwc2_hregs_backup *hr_backup;
|
||||
struct dwc2_gregs_backup gr_backup;
|
||||
struct dwc2_dregs_backup dr_backup;
|
||||
struct dwc2_hregs_backup hr_backup;
|
||||
|
||||
struct dentry *debug_root;
|
||||
struct debugfs_regset32 *regset;
|
||||
|
@ -359,10 +359,9 @@ void dwc2_hcd_stop(struct dwc2_hsotg *hsotg)
|
||||
|
||||
/* Caller must hold driver lock */
|
||||
static int dwc2_hcd_urb_enqueue(struct dwc2_hsotg *hsotg,
|
||||
struct dwc2_hcd_urb *urb, void **ep_handle,
|
||||
gfp_t mem_flags)
|
||||
struct dwc2_hcd_urb *urb, struct dwc2_qh *qh,
|
||||
struct dwc2_qtd *qtd)
|
||||
{
|
||||
struct dwc2_qtd *qtd;
|
||||
u32 intr_mask;
|
||||
int retval;
|
||||
int dev_speed;
|
||||
@ -386,18 +385,15 @@ static int dwc2_hcd_urb_enqueue(struct dwc2_hsotg *hsotg,
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
qtd = kzalloc(sizeof(*qtd), mem_flags);
|
||||
if (!qtd)
|
||||
return -ENOMEM;
|
||||
return -EINVAL;
|
||||
|
||||
dwc2_hcd_qtd_init(qtd, urb);
|
||||
retval = dwc2_hcd_qtd_add(hsotg, qtd, (struct dwc2_qh **)ep_handle,
|
||||
mem_flags);
|
||||
retval = dwc2_hcd_qtd_add(hsotg, qtd, qh);
|
||||
if (retval) {
|
||||
dev_err(hsotg->dev,
|
||||
"DWC OTG HCD URB Enqueue failed adding QTD. Error status %d\n",
|
||||
retval);
|
||||
kfree(qtd);
|
||||
return retval;
|
||||
}
|
||||
|
||||
@ -2445,6 +2441,9 @@ static int _dwc2_hcd_urb_enqueue(struct usb_hcd *hcd, struct urb *urb,
|
||||
u32 tflags = 0;
|
||||
void *buf;
|
||||
unsigned long flags;
|
||||
struct dwc2_qh *qh;
|
||||
bool qh_allocated = false;
|
||||
struct dwc2_qtd *qtd;
|
||||
|
||||
if (dbg_urb(urb)) {
|
||||
dev_vdbg(hsotg->dev, "DWC OTG HCD URB Enqueue\n");
|
||||
@ -2523,16 +2522,33 @@ static int _dwc2_hcd_urb_enqueue(struct usb_hcd *hcd, struct urb *urb,
|
||||
urb->iso_frame_desc[i].length);
|
||||
|
||||
urb->hcpriv = dwc2_urb;
|
||||
qh = (struct dwc2_qh *) ep->hcpriv;
|
||||
/* Create QH for the endpoint if it doesn't exist */
|
||||
if (!qh) {
|
||||
qh = dwc2_hcd_qh_create(hsotg, dwc2_urb, mem_flags);
|
||||
if (!qh) {
|
||||
retval = -ENOMEM;
|
||||
goto fail0;
|
||||
}
|
||||
ep->hcpriv = qh;
|
||||
qh_allocated = true;
|
||||
}
|
||||
|
||||
qtd = kzalloc(sizeof(*qtd), mem_flags);
|
||||
if (!qtd) {
|
||||
retval = -ENOMEM;
|
||||
goto fail1;
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&hsotg->lock, flags);
|
||||
retval = usb_hcd_link_urb_to_ep(hcd, urb);
|
||||
if (retval)
|
||||
goto fail1;
|
||||
|
||||
retval = dwc2_hcd_urb_enqueue(hsotg, dwc2_urb, &ep->hcpriv, mem_flags);
|
||||
if (retval)
|
||||
goto fail2;
|
||||
|
||||
retval = dwc2_hcd_urb_enqueue(hsotg, dwc2_urb, qh, qtd);
|
||||
if (retval)
|
||||
goto fail3;
|
||||
|
||||
if (alloc_bandwidth) {
|
||||
dwc2_allocate_bus_bandwidth(hcd,
|
||||
dwc2_hcd_get_ep_bandwidth(hsotg, ep),
|
||||
@ -2543,12 +2559,25 @@ static int _dwc2_hcd_urb_enqueue(struct usb_hcd *hcd, struct urb *urb,
|
||||
|
||||
return 0;
|
||||
|
||||
fail2:
|
||||
fail3:
|
||||
dwc2_urb->priv = NULL;
|
||||
usb_hcd_unlink_urb_from_ep(hcd, urb);
|
||||
fail1:
|
||||
fail2:
|
||||
spin_unlock_irqrestore(&hsotg->lock, flags);
|
||||
urb->hcpriv = NULL;
|
||||
kfree(qtd);
|
||||
fail1:
|
||||
if (qh_allocated) {
|
||||
struct dwc2_qtd *qtd2, *qtd2_tmp;
|
||||
|
||||
ep->hcpriv = NULL;
|
||||
dwc2_hcd_qh_unlink(hsotg, qh);
|
||||
/* Free each QTD in the QH's QTD list */
|
||||
list_for_each_entry_safe(qtd2, qtd2_tmp, &qh->qtd_list,
|
||||
qtd_list_entry)
|
||||
dwc2_hcd_qtd_unlink_and_free(hsotg, qtd2, qh);
|
||||
dwc2_hcd_qh_free(hsotg, qh);
|
||||
}
|
||||
fail0:
|
||||
kfree(dwc2_urb);
|
||||
|
||||
|
@ -463,6 +463,9 @@ extern void dwc2_hcd_queue_transactions(struct dwc2_hsotg *hsotg,
|
||||
/* Schedule Queue Functions */
|
||||
/* Implemented in hcd_queue.c */
|
||||
extern void dwc2_hcd_init_usecs(struct dwc2_hsotg *hsotg);
|
||||
extern struct dwc2_qh *dwc2_hcd_qh_create(struct dwc2_hsotg *hsotg,
|
||||
struct dwc2_hcd_urb *urb,
|
||||
gfp_t mem_flags);
|
||||
extern void dwc2_hcd_qh_free(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh);
|
||||
extern int dwc2_hcd_qh_add(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh);
|
||||
extern void dwc2_hcd_qh_unlink(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh);
|
||||
@ -471,7 +474,7 @@ extern void dwc2_hcd_qh_deactivate(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh,
|
||||
|
||||
extern void dwc2_hcd_qtd_init(struct dwc2_qtd *qtd, struct dwc2_hcd_urb *urb);
|
||||
extern int dwc2_hcd_qtd_add(struct dwc2_hsotg *hsotg, struct dwc2_qtd *qtd,
|
||||
struct dwc2_qh **qh, gfp_t mem_flags);
|
||||
struct dwc2_qh *qh);
|
||||
|
||||
/* Unlinks and frees a QTD */
|
||||
static inline void dwc2_hcd_qtd_unlink_and_free(struct dwc2_hsotg *hsotg,
|
||||
|
@ -191,7 +191,7 @@ static void dwc2_qh_init(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh,
|
||||
*
|
||||
* Return: Pointer to the newly allocated QH, or NULL on error
|
||||
*/
|
||||
static struct dwc2_qh *dwc2_hcd_qh_create(struct dwc2_hsotg *hsotg,
|
||||
struct dwc2_qh *dwc2_hcd_qh_create(struct dwc2_hsotg *hsotg,
|
||||
struct dwc2_hcd_urb *urb,
|
||||
gfp_t mem_flags)
|
||||
{
|
||||
@ -767,57 +767,32 @@ void dwc2_hcd_qtd_init(struct dwc2_qtd *qtd, struct dwc2_hcd_urb *urb)
|
||||
*
|
||||
* @hsotg: The DWC HCD structure
|
||||
* @qtd: The QTD to add
|
||||
* @qh: Out parameter to return queue head
|
||||
* @atomic_alloc: Flag to do atomic alloc if needed
|
||||
* @qh: Queue head to add qtd to
|
||||
*
|
||||
* Return: 0 if successful, negative error code otherwise
|
||||
*
|
||||
* Finds the correct QH to place the QTD into. If it does not find a QH, it
|
||||
* will create a new QH. If the QH to which the QTD is added is not currently
|
||||
* scheduled, it is placed into the proper schedule based on its EP type.
|
||||
* If the QH to which the QTD is added is not currently scheduled, it is placed
|
||||
* into the proper schedule based on its EP type.
|
||||
*/
|
||||
int dwc2_hcd_qtd_add(struct dwc2_hsotg *hsotg, struct dwc2_qtd *qtd,
|
||||
struct dwc2_qh **qh, gfp_t mem_flags)
|
||||
struct dwc2_qh *qh)
|
||||
{
|
||||
struct dwc2_hcd_urb *urb = qtd->urb;
|
||||
int allocated = 0;
|
||||
int retval;
|
||||
|
||||
/*
|
||||
* Get the QH which holds the QTD-list to insert to. Create QH if it
|
||||
* doesn't exist.
|
||||
*/
|
||||
if (*qh == NULL) {
|
||||
*qh = dwc2_hcd_qh_create(hsotg, urb, mem_flags);
|
||||
if (*qh == NULL)
|
||||
return -ENOMEM;
|
||||
allocated = 1;
|
||||
if (unlikely(!qh)) {
|
||||
dev_err(hsotg->dev, "%s: Invalid QH\n", __func__);
|
||||
retval = -EINVAL;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
retval = dwc2_hcd_qh_add(hsotg, *qh);
|
||||
retval = dwc2_hcd_qh_add(hsotg, qh);
|
||||
if (retval)
|
||||
goto fail;
|
||||
|
||||
qtd->qh = *qh;
|
||||
list_add_tail(&qtd->qtd_list_entry, &(*qh)->qtd_list);
|
||||
qtd->qh = qh;
|
||||
list_add_tail(&qtd->qtd_list_entry, &qh->qtd_list);
|
||||
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
if (allocated) {
|
||||
struct dwc2_qtd *qtd2, *qtd2_tmp;
|
||||
struct dwc2_qh *qh_tmp = *qh;
|
||||
|
||||
*qh = NULL;
|
||||
dwc2_hcd_qh_unlink(hsotg, qh_tmp);
|
||||
|
||||
/* Free each QTD in the QH's QTD list */
|
||||
list_for_each_entry_safe(qtd2, qtd2_tmp, &qh_tmp->qtd_list,
|
||||
qtd_list_entry)
|
||||
dwc2_hcd_qtd_unlink_and_free(hsotg, qtd2, qh_tmp);
|
||||
|
||||
dwc2_hcd_qh_free(hsotg, qh_tmp);
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
@ -446,10 +446,12 @@ static int dwc3_phy_setup(struct dwc3 *dwc)
|
||||
/* Select the HS PHY interface */
|
||||
switch (DWC3_GHWPARAMS3_HSPHY_IFC(dwc->hwparams.hwparams3)) {
|
||||
case DWC3_GHWPARAMS3_HSPHY_IFC_UTMI_ULPI:
|
||||
if (!strncmp(dwc->hsphy_interface, "utmi", 4)) {
|
||||
if (dwc->hsphy_interface &&
|
||||
!strncmp(dwc->hsphy_interface, "utmi", 4)) {
|
||||
reg &= ~DWC3_GUSB2PHYCFG_ULPI_UTMI;
|
||||
break;
|
||||
} else if (!strncmp(dwc->hsphy_interface, "ulpi", 4)) {
|
||||
} else if (dwc->hsphy_interface &&
|
||||
!strncmp(dwc->hsphy_interface, "ulpi", 4)) {
|
||||
reg |= DWC3_GUSB2PHYCFG_ULPI_UTMI;
|
||||
dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg);
|
||||
} else {
|
||||
|
@ -1758,10 +1758,13 @@ unknown:
|
||||
* take such requests too, if that's ever needed: to work
|
||||
* in config 0, etc.
|
||||
*/
|
||||
list_for_each_entry(f, &cdev->config->functions, list)
|
||||
if (f->req_match && f->req_match(f, ctrl))
|
||||
goto try_fun_setup;
|
||||
f = NULL;
|
||||
if (cdev->config) {
|
||||
list_for_each_entry(f, &cdev->config->functions, list)
|
||||
if (f->req_match && f->req_match(f, ctrl))
|
||||
goto try_fun_setup;
|
||||
f = NULL;
|
||||
}
|
||||
|
||||
switch (ctrl->bRequestType & USB_RECIP_MASK) {
|
||||
case USB_RECIP_INTERFACE:
|
||||
if (!cdev->config || intf >= MAX_CONFIG_INTERFACES)
|
||||
|
@ -924,7 +924,8 @@ static ssize_t ffs_epfile_write_iter(struct kiocb *kiocb, struct iov_iter *from)
|
||||
|
||||
kiocb->private = p;
|
||||
|
||||
kiocb_set_cancel_fn(kiocb, ffs_aio_cancel);
|
||||
if (p->aio)
|
||||
kiocb_set_cancel_fn(kiocb, ffs_aio_cancel);
|
||||
|
||||
res = ffs_epfile_io(kiocb->ki_filp, p);
|
||||
if (res == -EIOCBQUEUED)
|
||||
@ -968,7 +969,8 @@ static ssize_t ffs_epfile_read_iter(struct kiocb *kiocb, struct iov_iter *to)
|
||||
|
||||
kiocb->private = p;
|
||||
|
||||
kiocb_set_cancel_fn(kiocb, ffs_aio_cancel);
|
||||
if (p->aio)
|
||||
kiocb_set_cancel_fn(kiocb, ffs_aio_cancel);
|
||||
|
||||
res = ffs_epfile_io(kiocb->ki_filp, p);
|
||||
if (res == -EIOCBQUEUED)
|
||||
|
@ -2786,7 +2786,7 @@ int fsg_common_set_nluns(struct fsg_common *common, int nluns)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
curlun = kcalloc(nluns, sizeof(*curlun), GFP_KERNEL);
|
||||
curlun = kcalloc(FSG_MAX_LUNS, sizeof(*curlun), GFP_KERNEL);
|
||||
if (unlikely(!curlun))
|
||||
return -ENOMEM;
|
||||
|
||||
@ -2796,8 +2796,6 @@ int fsg_common_set_nluns(struct fsg_common *common, int nluns)
|
||||
common->luns = curlun;
|
||||
common->nluns = nluns;
|
||||
|
||||
pr_info("Number of LUNs=%d\n", common->nluns);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(fsg_common_set_nluns);
|
||||
@ -3563,14 +3561,26 @@ static struct usb_function *fsg_alloc(struct usb_function_instance *fi)
|
||||
struct fsg_opts *opts = fsg_opts_from_func_inst(fi);
|
||||
struct fsg_common *common = opts->common;
|
||||
struct fsg_dev *fsg;
|
||||
unsigned nluns, i;
|
||||
|
||||
fsg = kzalloc(sizeof(*fsg), GFP_KERNEL);
|
||||
if (unlikely(!fsg))
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
mutex_lock(&opts->lock);
|
||||
if (!opts->refcnt) {
|
||||
for (nluns = i = 0; i < FSG_MAX_LUNS; ++i)
|
||||
if (common->luns[i])
|
||||
nluns = i + 1;
|
||||
if (!nluns)
|
||||
pr_warn("No LUNS defined, continuing anyway\n");
|
||||
else
|
||||
common->nluns = nluns;
|
||||
pr_info("Number of LUNs=%u\n", common->nluns);
|
||||
}
|
||||
opts->refcnt++;
|
||||
mutex_unlock(&opts->lock);
|
||||
|
||||
fsg->function.name = FSG_DRIVER_DESC;
|
||||
fsg->function.bind = fsg_bind;
|
||||
fsg->function.unbind = fsg_unbind;
|
||||
|
@ -1145,7 +1145,7 @@ static struct usb_function *f_midi_alloc(struct usb_function_instance *fi)
|
||||
if (opts->id && !midi->id) {
|
||||
status = -ENOMEM;
|
||||
mutex_unlock(&opts->lock);
|
||||
goto kstrdup_fail;
|
||||
goto setup_fail;
|
||||
}
|
||||
midi->in_ports = opts->in_ports;
|
||||
midi->out_ports = opts->out_ports;
|
||||
@ -1164,8 +1164,6 @@ static struct usb_function *f_midi_alloc(struct usb_function_instance *fi)
|
||||
|
||||
return &midi->func;
|
||||
|
||||
kstrdup_fail:
|
||||
f_midi_unregister_card(midi);
|
||||
setup_fail:
|
||||
for (--i; i >= 0; i--)
|
||||
kfree(midi->in_port[i]);
|
||||
|
@ -1171,7 +1171,7 @@ static int fotg210_udc_probe(struct platform_device *pdev)
|
||||
udc_name, fotg210);
|
||||
if (ret < 0) {
|
||||
pr_err("request_irq error (%d)\n", ret);
|
||||
goto err_irq;
|
||||
goto err_req;
|
||||
}
|
||||
|
||||
ret = usb_add_gadget_udc(&pdev->dev, &fotg210->gadget);
|
||||
@ -1183,7 +1183,6 @@ static int fotg210_udc_probe(struct platform_device *pdev)
|
||||
return 0;
|
||||
|
||||
err_add_udc:
|
||||
err_irq:
|
||||
free_irq(ires->start, fotg210);
|
||||
|
||||
err_req:
|
||||
|
@ -275,9 +275,7 @@ static int musb_has_gadget(struct musb *musb)
|
||||
#ifdef CONFIG_USB_MUSB_HOST
|
||||
return 1;
|
||||
#else
|
||||
if (musb->port_mode == MUSB_PORT_MODE_HOST)
|
||||
return 1;
|
||||
return musb->g.dev.driver != NULL;
|
||||
return musb->port_mode == MUSB_PORT_MODE_HOST;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -217,6 +217,9 @@ static bool mxs_phy_get_vbus_status(struct mxs_phy *mxs_phy)
|
||||
{
|
||||
unsigned int vbus_value;
|
||||
|
||||
if (!mxs_phy->regmap_anatop)
|
||||
return false;
|
||||
|
||||
if (mxs_phy->port_id == 0)
|
||||
regmap_read(mxs_phy->regmap_anatop,
|
||||
ANADIG_USB1_VBUS_DET_STAT,
|
||||
|
@ -187,6 +187,7 @@ static const struct usb_device_id id_table[] = {
|
||||
{ USB_DEVICE(0x1FB9, 0x0602) }, /* Lake Shore Model 648 Magnet Power Supply */
|
||||
{ USB_DEVICE(0x1FB9, 0x0700) }, /* Lake Shore Model 737 VSM Controller */
|
||||
{ USB_DEVICE(0x1FB9, 0x0701) }, /* Lake Shore Model 776 Hall Matrix */
|
||||
{ USB_DEVICE(0x2626, 0xEA60) }, /* Aruba Networks 7xxx USB Serial Console */
|
||||
{ USB_DEVICE(0x3195, 0xF190) }, /* Link Instruments MSO-19 */
|
||||
{ USB_DEVICE(0x3195, 0xF280) }, /* Link Instruments MSO-28 */
|
||||
{ USB_DEVICE(0x3195, 0xF281) }, /* Link Instruments MSO-28 */
|
||||
|
@ -121,26 +121,26 @@ static DEFINE_SPINLOCK(release_lock);
|
||||
static const unsigned int dummy; /* for clarity in register access fns */
|
||||
|
||||
enum mos_regs {
|
||||
THR, /* serial port regs */
|
||||
RHR,
|
||||
IER,
|
||||
FCR,
|
||||
ISR,
|
||||
LCR,
|
||||
MCR,
|
||||
LSR,
|
||||
MSR,
|
||||
SPR,
|
||||
DLL,
|
||||
DLM,
|
||||
DPR, /* parallel port regs */
|
||||
DSR,
|
||||
DCR,
|
||||
ECR,
|
||||
SP1_REG, /* device control regs */
|
||||
SP2_REG, /* serial port 2 (7720 only) */
|
||||
PP_REG,
|
||||
SP_CONTROL_REG,
|
||||
MOS7720_THR, /* serial port regs */
|
||||
MOS7720_RHR,
|
||||
MOS7720_IER,
|
||||
MOS7720_FCR,
|
||||
MOS7720_ISR,
|
||||
MOS7720_LCR,
|
||||
MOS7720_MCR,
|
||||
MOS7720_LSR,
|
||||
MOS7720_MSR,
|
||||
MOS7720_SPR,
|
||||
MOS7720_DLL,
|
||||
MOS7720_DLM,
|
||||
MOS7720_DPR, /* parallel port regs */
|
||||
MOS7720_DSR,
|
||||
MOS7720_DCR,
|
||||
MOS7720_ECR,
|
||||
MOS7720_SP1_REG, /* device control regs */
|
||||
MOS7720_SP2_REG, /* serial port 2 (7720 only) */
|
||||
MOS7720_PP_REG,
|
||||
MOS7720_SP_CONTROL_REG,
|
||||
};
|
||||
|
||||
/*
|
||||
@ -150,26 +150,26 @@ enum mos_regs {
|
||||
static inline __u16 get_reg_index(enum mos_regs reg)
|
||||
{
|
||||
static const __u16 mos7715_index_lookup_table[] = {
|
||||
0x00, /* THR */
|
||||
0x00, /* RHR */
|
||||
0x01, /* IER */
|
||||
0x02, /* FCR */
|
||||
0x02, /* ISR */
|
||||
0x03, /* LCR */
|
||||
0x04, /* MCR */
|
||||
0x05, /* LSR */
|
||||
0x06, /* MSR */
|
||||
0x07, /* SPR */
|
||||
0x00, /* DLL */
|
||||
0x01, /* DLM */
|
||||
0x00, /* DPR */
|
||||
0x01, /* DSR */
|
||||
0x02, /* DCR */
|
||||
0x0a, /* ECR */
|
||||
0x01, /* SP1_REG */
|
||||
0x02, /* SP2_REG (7720 only) */
|
||||
0x04, /* PP_REG (7715 only) */
|
||||
0x08, /* SP_CONTROL_REG */
|
||||
0x00, /* MOS7720_THR */
|
||||
0x00, /* MOS7720_RHR */
|
||||
0x01, /* MOS7720_IER */
|
||||
0x02, /* MOS7720_FCR */
|
||||
0x02, /* MOS7720_ISR */
|
||||
0x03, /* MOS7720_LCR */
|
||||
0x04, /* MOS7720_MCR */
|
||||
0x05, /* MOS7720_LSR */
|
||||
0x06, /* MOS7720_MSR */
|
||||
0x07, /* MOS7720_SPR */
|
||||
0x00, /* MOS7720_DLL */
|
||||
0x01, /* MOS7720_DLM */
|
||||
0x00, /* MOS7720_DPR */
|
||||
0x01, /* MOS7720_DSR */
|
||||
0x02, /* MOS7720_DCR */
|
||||
0x0a, /* MOS7720_ECR */
|
||||
0x01, /* MOS7720_SP1_REG */
|
||||
0x02, /* MOS7720_SP2_REG (7720 only) */
|
||||
0x04, /* MOS7720_PP_REG (7715 only) */
|
||||
0x08, /* MOS7720_SP_CONTROL_REG */
|
||||
};
|
||||
return mos7715_index_lookup_table[reg];
|
||||
}
|
||||
@ -181,10 +181,10 @@ static inline __u16 get_reg_index(enum mos_regs reg)
|
||||
static inline __u16 get_reg_value(enum mos_regs reg,
|
||||
unsigned int serial_portnum)
|
||||
{
|
||||
if (reg >= SP1_REG) /* control reg */
|
||||
if (reg >= MOS7720_SP1_REG) /* control reg */
|
||||
return 0x0000;
|
||||
|
||||
else if (reg >= DPR) /* parallel port reg (7715 only) */
|
||||
else if (reg >= MOS7720_DPR) /* parallel port reg (7715 only) */
|
||||
return 0x0100;
|
||||
|
||||
else /* serial port reg */
|
||||
@ -252,7 +252,8 @@ static inline int mos7715_change_mode(struct mos7715_parport *mos_parport,
|
||||
enum mos7715_pp_modes mode)
|
||||
{
|
||||
mos_parport->shadowECR = mode;
|
||||
write_mos_reg(mos_parport->serial, dummy, ECR, mos_parport->shadowECR);
|
||||
write_mos_reg(mos_parport->serial, dummy, MOS7720_ECR,
|
||||
mos_parport->shadowECR);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -486,7 +487,7 @@ static void parport_mos7715_write_data(struct parport *pp, unsigned char d)
|
||||
if (parport_prologue(pp) < 0)
|
||||
return;
|
||||
mos7715_change_mode(mos_parport, SPP);
|
||||
write_mos_reg(mos_parport->serial, dummy, DPR, (__u8)d);
|
||||
write_mos_reg(mos_parport->serial, dummy, MOS7720_DPR, (__u8)d);
|
||||
parport_epilogue(pp);
|
||||
}
|
||||
|
||||
@ -497,7 +498,7 @@ static unsigned char parport_mos7715_read_data(struct parport *pp)
|
||||
|
||||
if (parport_prologue(pp) < 0)
|
||||
return 0;
|
||||
read_mos_reg(mos_parport->serial, dummy, DPR, &d);
|
||||
read_mos_reg(mos_parport->serial, dummy, MOS7720_DPR, &d);
|
||||
parport_epilogue(pp);
|
||||
return d;
|
||||
}
|
||||
@ -510,7 +511,7 @@ static void parport_mos7715_write_control(struct parport *pp, unsigned char d)
|
||||
if (parport_prologue(pp) < 0)
|
||||
return;
|
||||
data = ((__u8)d & 0x0f) | (mos_parport->shadowDCR & 0xf0);
|
||||
write_mos_reg(mos_parport->serial, dummy, DCR, data);
|
||||
write_mos_reg(mos_parport->serial, dummy, MOS7720_DCR, data);
|
||||
mos_parport->shadowDCR = data;
|
||||
parport_epilogue(pp);
|
||||
}
|
||||
@ -543,7 +544,8 @@ static unsigned char parport_mos7715_frob_control(struct parport *pp,
|
||||
if (parport_prologue(pp) < 0)
|
||||
return 0;
|
||||
mos_parport->shadowDCR = (mos_parport->shadowDCR & (~mask)) ^ val;
|
||||
write_mos_reg(mos_parport->serial, dummy, DCR, mos_parport->shadowDCR);
|
||||
write_mos_reg(mos_parport->serial, dummy, MOS7720_DCR,
|
||||
mos_parport->shadowDCR);
|
||||
dcr = mos_parport->shadowDCR & 0x0f;
|
||||
parport_epilogue(pp);
|
||||
return dcr;
|
||||
@ -581,7 +583,8 @@ static void parport_mos7715_data_forward(struct parport *pp)
|
||||
return;
|
||||
mos7715_change_mode(mos_parport, PS2);
|
||||
mos_parport->shadowDCR &= ~0x20;
|
||||
write_mos_reg(mos_parport->serial, dummy, DCR, mos_parport->shadowDCR);
|
||||
write_mos_reg(mos_parport->serial, dummy, MOS7720_DCR,
|
||||
mos_parport->shadowDCR);
|
||||
parport_epilogue(pp);
|
||||
}
|
||||
|
||||
@ -593,7 +596,8 @@ static void parport_mos7715_data_reverse(struct parport *pp)
|
||||
return;
|
||||
mos7715_change_mode(mos_parport, PS2);
|
||||
mos_parport->shadowDCR |= 0x20;
|
||||
write_mos_reg(mos_parport->serial, dummy, DCR, mos_parport->shadowDCR);
|
||||
write_mos_reg(mos_parport->serial, dummy, MOS7720_DCR,
|
||||
mos_parport->shadowDCR);
|
||||
parport_epilogue(pp);
|
||||
}
|
||||
|
||||
@ -633,8 +637,10 @@ static void parport_mos7715_restore_state(struct parport *pp,
|
||||
spin_unlock(&release_lock);
|
||||
return;
|
||||
}
|
||||
write_parport_reg_nonblock(mos_parport, DCR, mos_parport->shadowDCR);
|
||||
write_parport_reg_nonblock(mos_parport, ECR, mos_parport->shadowECR);
|
||||
write_parport_reg_nonblock(mos_parport, MOS7720_DCR,
|
||||
mos_parport->shadowDCR);
|
||||
write_parport_reg_nonblock(mos_parport, MOS7720_ECR,
|
||||
mos_parport->shadowECR);
|
||||
spin_unlock(&release_lock);
|
||||
}
|
||||
|
||||
@ -714,14 +720,16 @@ static int mos7715_parport_init(struct usb_serial *serial)
|
||||
init_completion(&mos_parport->syncmsg_compl);
|
||||
|
||||
/* cycle parallel port reset bit */
|
||||
write_mos_reg(mos_parport->serial, dummy, PP_REG, (__u8)0x80);
|
||||
write_mos_reg(mos_parport->serial, dummy, PP_REG, (__u8)0x00);
|
||||
write_mos_reg(mos_parport->serial, dummy, MOS7720_PP_REG, (__u8)0x80);
|
||||
write_mos_reg(mos_parport->serial, dummy, MOS7720_PP_REG, (__u8)0x00);
|
||||
|
||||
/* initialize device registers */
|
||||
mos_parport->shadowDCR = DCR_INIT_VAL;
|
||||
write_mos_reg(mos_parport->serial, dummy, DCR, mos_parport->shadowDCR);
|
||||
write_mos_reg(mos_parport->serial, dummy, MOS7720_DCR,
|
||||
mos_parport->shadowDCR);
|
||||
mos_parport->shadowECR = ECR_INIT_VAL;
|
||||
write_mos_reg(mos_parport->serial, dummy, ECR, mos_parport->shadowECR);
|
||||
write_mos_reg(mos_parport->serial, dummy, MOS7720_ECR,
|
||||
mos_parport->shadowECR);
|
||||
|
||||
/* register with parport core */
|
||||
mos_parport->pp = parport_register_port(0, PARPORT_IRQ_NONE,
|
||||
@ -1033,45 +1041,49 @@ static int mos7720_open(struct tty_struct *tty, struct usb_serial_port *port)
|
||||
/* Initialize MCS7720 -- Write Init values to corresponding Registers
|
||||
*
|
||||
* Register Index
|
||||
* 0 : THR/RHR
|
||||
* 1 : IER
|
||||
* 2 : FCR
|
||||
* 3 : LCR
|
||||
* 4 : MCR
|
||||
* 5 : LSR
|
||||
* 6 : MSR
|
||||
* 7 : SPR
|
||||
* 0 : MOS7720_THR/MOS7720_RHR
|
||||
* 1 : MOS7720_IER
|
||||
* 2 : MOS7720_FCR
|
||||
* 3 : MOS7720_LCR
|
||||
* 4 : MOS7720_MCR
|
||||
* 5 : MOS7720_LSR
|
||||
* 6 : MOS7720_MSR
|
||||
* 7 : MOS7720_SPR
|
||||
*
|
||||
* 0x08 : SP1/2 Control Reg
|
||||
*/
|
||||
port_number = port->port_number;
|
||||
read_mos_reg(serial, port_number, LSR, &data);
|
||||
read_mos_reg(serial, port_number, MOS7720_LSR, &data);
|
||||
|
||||
dev_dbg(&port->dev, "SS::%p LSR:%x\n", mos7720_port, data);
|
||||
|
||||
write_mos_reg(serial, dummy, SP1_REG, 0x02);
|
||||
write_mos_reg(serial, dummy, SP2_REG, 0x02);
|
||||
write_mos_reg(serial, dummy, MOS7720_SP1_REG, 0x02);
|
||||
write_mos_reg(serial, dummy, MOS7720_SP2_REG, 0x02);
|
||||
|
||||
write_mos_reg(serial, port_number, IER, 0x00);
|
||||
write_mos_reg(serial, port_number, FCR, 0x00);
|
||||
write_mos_reg(serial, port_number, MOS7720_IER, 0x00);
|
||||
write_mos_reg(serial, port_number, MOS7720_FCR, 0x00);
|
||||
|
||||
write_mos_reg(serial, port_number, FCR, 0xcf);
|
||||
write_mos_reg(serial, port_number, MOS7720_FCR, 0xcf);
|
||||
mos7720_port->shadowLCR = 0x03;
|
||||
write_mos_reg(serial, port_number, LCR, mos7720_port->shadowLCR);
|
||||
write_mos_reg(serial, port_number, MOS7720_LCR,
|
||||
mos7720_port->shadowLCR);
|
||||
mos7720_port->shadowMCR = 0x0b;
|
||||
write_mos_reg(serial, port_number, MCR, mos7720_port->shadowMCR);
|
||||
write_mos_reg(serial, port_number, MOS7720_MCR,
|
||||
mos7720_port->shadowMCR);
|
||||
|
||||
write_mos_reg(serial, port_number, SP_CONTROL_REG, 0x00);
|
||||
read_mos_reg(serial, dummy, SP_CONTROL_REG, &data);
|
||||
write_mos_reg(serial, port_number, MOS7720_SP_CONTROL_REG, 0x00);
|
||||
read_mos_reg(serial, dummy, MOS7720_SP_CONTROL_REG, &data);
|
||||
data = data | (port->port_number + 1);
|
||||
write_mos_reg(serial, dummy, SP_CONTROL_REG, data);
|
||||
write_mos_reg(serial, dummy, MOS7720_SP_CONTROL_REG, data);
|
||||
mos7720_port->shadowLCR = 0x83;
|
||||
write_mos_reg(serial, port_number, LCR, mos7720_port->shadowLCR);
|
||||
write_mos_reg(serial, port_number, THR, 0x0c);
|
||||
write_mos_reg(serial, port_number, IER, 0x00);
|
||||
write_mos_reg(serial, port_number, MOS7720_LCR,
|
||||
mos7720_port->shadowLCR);
|
||||
write_mos_reg(serial, port_number, MOS7720_THR, 0x0c);
|
||||
write_mos_reg(serial, port_number, MOS7720_IER, 0x00);
|
||||
mos7720_port->shadowLCR = 0x03;
|
||||
write_mos_reg(serial, port_number, LCR, mos7720_port->shadowLCR);
|
||||
write_mos_reg(serial, port_number, IER, 0x0c);
|
||||
write_mos_reg(serial, port_number, MOS7720_LCR,
|
||||
mos7720_port->shadowLCR);
|
||||
write_mos_reg(serial, port_number, MOS7720_IER, 0x0c);
|
||||
|
||||
response = usb_submit_urb(port->read_urb, GFP_KERNEL);
|
||||
if (response)
|
||||
@ -1144,8 +1156,8 @@ static void mos7720_close(struct usb_serial_port *port)
|
||||
usb_kill_urb(port->write_urb);
|
||||
usb_kill_urb(port->read_urb);
|
||||
|
||||
write_mos_reg(serial, port->port_number, MCR, 0x00);
|
||||
write_mos_reg(serial, port->port_number, IER, 0x00);
|
||||
write_mos_reg(serial, port->port_number, MOS7720_MCR, 0x00);
|
||||
write_mos_reg(serial, port->port_number, MOS7720_IER, 0x00);
|
||||
|
||||
mos7720_port->open = 0;
|
||||
}
|
||||
@ -1169,7 +1181,8 @@ static void mos7720_break(struct tty_struct *tty, int break_state)
|
||||
data = mos7720_port->shadowLCR & ~UART_LCR_SBC;
|
||||
|
||||
mos7720_port->shadowLCR = data;
|
||||
write_mos_reg(serial, port->port_number, LCR, mos7720_port->shadowLCR);
|
||||
write_mos_reg(serial, port->port_number, MOS7720_LCR,
|
||||
mos7720_port->shadowLCR);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1297,7 +1310,7 @@ static void mos7720_throttle(struct tty_struct *tty)
|
||||
/* if we are implementing RTS/CTS, toggle that line */
|
||||
if (tty->termios.c_cflag & CRTSCTS) {
|
||||
mos7720_port->shadowMCR &= ~UART_MCR_RTS;
|
||||
write_mos_reg(port->serial, port->port_number, MCR,
|
||||
write_mos_reg(port->serial, port->port_number, MOS7720_MCR,
|
||||
mos7720_port->shadowMCR);
|
||||
}
|
||||
}
|
||||
@ -1327,7 +1340,7 @@ static void mos7720_unthrottle(struct tty_struct *tty)
|
||||
/* if we are implementing RTS/CTS, toggle that line */
|
||||
if (tty->termios.c_cflag & CRTSCTS) {
|
||||
mos7720_port->shadowMCR |= UART_MCR_RTS;
|
||||
write_mos_reg(port->serial, port->port_number, MCR,
|
||||
write_mos_reg(port->serial, port->port_number, MOS7720_MCR,
|
||||
mos7720_port->shadowMCR);
|
||||
}
|
||||
}
|
||||
@ -1352,35 +1365,39 @@ static int set_higher_rates(struct moschip_port *mos7720_port,
|
||||
dev_dbg(&port->dev, "Sending Setting Commands ..........\n");
|
||||
port_number = port->port_number;
|
||||
|
||||
write_mos_reg(serial, port_number, IER, 0x00);
|
||||
write_mos_reg(serial, port_number, FCR, 0x00);
|
||||
write_mos_reg(serial, port_number, FCR, 0xcf);
|
||||
write_mos_reg(serial, port_number, MOS7720_IER, 0x00);
|
||||
write_mos_reg(serial, port_number, MOS7720_FCR, 0x00);
|
||||
write_mos_reg(serial, port_number, MOS7720_FCR, 0xcf);
|
||||
mos7720_port->shadowMCR = 0x0b;
|
||||
write_mos_reg(serial, port_number, MCR, mos7720_port->shadowMCR);
|
||||
write_mos_reg(serial, dummy, SP_CONTROL_REG, 0x00);
|
||||
write_mos_reg(serial, port_number, MOS7720_MCR,
|
||||
mos7720_port->shadowMCR);
|
||||
write_mos_reg(serial, dummy, MOS7720_SP_CONTROL_REG, 0x00);
|
||||
|
||||
/***********************************************
|
||||
* Set for higher rates *
|
||||
***********************************************/
|
||||
/* writing baud rate verbatum into uart clock field clearly not right */
|
||||
if (port_number == 0)
|
||||
sp_reg = SP1_REG;
|
||||
sp_reg = MOS7720_SP1_REG;
|
||||
else
|
||||
sp_reg = SP2_REG;
|
||||
sp_reg = MOS7720_SP2_REG;
|
||||
write_mos_reg(serial, dummy, sp_reg, baud * 0x10);
|
||||
write_mos_reg(serial, dummy, SP_CONTROL_REG, 0x03);
|
||||
write_mos_reg(serial, dummy, MOS7720_SP_CONTROL_REG, 0x03);
|
||||
mos7720_port->shadowMCR = 0x2b;
|
||||
write_mos_reg(serial, port_number, MCR, mos7720_port->shadowMCR);
|
||||
write_mos_reg(serial, port_number, MOS7720_MCR,
|
||||
mos7720_port->shadowMCR);
|
||||
|
||||
/***********************************************
|
||||
* Set DLL/DLM
|
||||
***********************************************/
|
||||
mos7720_port->shadowLCR = mos7720_port->shadowLCR | UART_LCR_DLAB;
|
||||
write_mos_reg(serial, port_number, LCR, mos7720_port->shadowLCR);
|
||||
write_mos_reg(serial, port_number, DLL, 0x01);
|
||||
write_mos_reg(serial, port_number, DLM, 0x00);
|
||||
write_mos_reg(serial, port_number, MOS7720_LCR,
|
||||
mos7720_port->shadowLCR);
|
||||
write_mos_reg(serial, port_number, MOS7720_DLL, 0x01);
|
||||
write_mos_reg(serial, port_number, MOS7720_DLM, 0x00);
|
||||
mos7720_port->shadowLCR = mos7720_port->shadowLCR & ~UART_LCR_DLAB;
|
||||
write_mos_reg(serial, port_number, LCR, mos7720_port->shadowLCR);
|
||||
write_mos_reg(serial, port_number, MOS7720_LCR,
|
||||
mos7720_port->shadowLCR);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -1488,15 +1505,16 @@ static int send_cmd_write_baud_rate(struct moschip_port *mos7720_port,
|
||||
|
||||
/* Enable access to divisor latch */
|
||||
mos7720_port->shadowLCR = mos7720_port->shadowLCR | UART_LCR_DLAB;
|
||||
write_mos_reg(serial, number, LCR, mos7720_port->shadowLCR);
|
||||
write_mos_reg(serial, number, MOS7720_LCR, mos7720_port->shadowLCR);
|
||||
|
||||
/* Write the divisor */
|
||||
write_mos_reg(serial, number, DLL, (__u8)(divisor & 0xff));
|
||||
write_mos_reg(serial, number, DLM, (__u8)((divisor & 0xff00) >> 8));
|
||||
write_mos_reg(serial, number, MOS7720_DLL, (__u8)(divisor & 0xff));
|
||||
write_mos_reg(serial, number, MOS7720_DLM,
|
||||
(__u8)((divisor & 0xff00) >> 8));
|
||||
|
||||
/* Disable access to divisor latch */
|
||||
mos7720_port->shadowLCR = mos7720_port->shadowLCR & ~UART_LCR_DLAB;
|
||||
write_mos_reg(serial, number, LCR, mos7720_port->shadowLCR);
|
||||
write_mos_reg(serial, number, MOS7720_LCR, mos7720_port->shadowLCR);
|
||||
|
||||
return status;
|
||||
}
|
||||
@ -1600,14 +1618,16 @@ static void change_port_settings(struct tty_struct *tty,
|
||||
|
||||
|
||||
/* Disable Interrupts */
|
||||
write_mos_reg(serial, port_number, IER, 0x00);
|
||||
write_mos_reg(serial, port_number, FCR, 0x00);
|
||||
write_mos_reg(serial, port_number, FCR, 0xcf);
|
||||
write_mos_reg(serial, port_number, MOS7720_IER, 0x00);
|
||||
write_mos_reg(serial, port_number, MOS7720_FCR, 0x00);
|
||||
write_mos_reg(serial, port_number, MOS7720_FCR, 0xcf);
|
||||
|
||||
/* Send the updated LCR value to the mos7720 */
|
||||
write_mos_reg(serial, port_number, LCR, mos7720_port->shadowLCR);
|
||||
write_mos_reg(serial, port_number, MOS7720_LCR,
|
||||
mos7720_port->shadowLCR);
|
||||
mos7720_port->shadowMCR = 0x0b;
|
||||
write_mos_reg(serial, port_number, MCR, mos7720_port->shadowMCR);
|
||||
write_mos_reg(serial, port_number, MOS7720_MCR,
|
||||
mos7720_port->shadowMCR);
|
||||
|
||||
/* set up the MCR register and send it to the mos7720 */
|
||||
mos7720_port->shadowMCR = UART_MCR_OUT2;
|
||||
@ -1619,14 +1639,17 @@ static void change_port_settings(struct tty_struct *tty,
|
||||
/* To set hardware flow control to the specified *
|
||||
* serial port, in SP1/2_CONTROL_REG */
|
||||
if (port_number)
|
||||
write_mos_reg(serial, dummy, SP_CONTROL_REG, 0x01);
|
||||
write_mos_reg(serial, dummy, MOS7720_SP_CONTROL_REG,
|
||||
0x01);
|
||||
else
|
||||
write_mos_reg(serial, dummy, SP_CONTROL_REG, 0x02);
|
||||
write_mos_reg(serial, dummy, MOS7720_SP_CONTROL_REG,
|
||||
0x02);
|
||||
|
||||
} else
|
||||
mos7720_port->shadowMCR &= ~(UART_MCR_XONANY);
|
||||
|
||||
write_mos_reg(serial, port_number, MCR, mos7720_port->shadowMCR);
|
||||
write_mos_reg(serial, port_number, MOS7720_MCR,
|
||||
mos7720_port->shadowMCR);
|
||||
|
||||
/* Determine divisor based on baud rate */
|
||||
baud = tty_get_baud_rate(tty);
|
||||
@ -1639,7 +1662,7 @@ static void change_port_settings(struct tty_struct *tty,
|
||||
if (baud >= 230400) {
|
||||
set_higher_rates(mos7720_port, baud);
|
||||
/* Enable Interrupts */
|
||||
write_mos_reg(serial, port_number, IER, 0x0c);
|
||||
write_mos_reg(serial, port_number, MOS7720_IER, 0x0c);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1650,7 +1673,7 @@ static void change_port_settings(struct tty_struct *tty,
|
||||
if (cflag & CBAUD)
|
||||
tty_encode_baud_rate(tty, baud, baud);
|
||||
/* Enable Interrupts */
|
||||
write_mos_reg(serial, port_number, IER, 0x0c);
|
||||
write_mos_reg(serial, port_number, MOS7720_IER, 0x0c);
|
||||
|
||||
if (port->read_urb->status != -EINPROGRESS) {
|
||||
status = usb_submit_urb(port->read_urb, GFP_KERNEL);
|
||||
@ -1725,7 +1748,7 @@ static int get_lsr_info(struct tty_struct *tty,
|
||||
|
||||
count = mos7720_chars_in_buffer(tty);
|
||||
if (count == 0) {
|
||||
read_mos_reg(port->serial, port_number, LSR, &data);
|
||||
read_mos_reg(port->serial, port_number, MOS7720_LSR, &data);
|
||||
if ((data & (UART_LSR_TEMT | UART_LSR_THRE))
|
||||
== (UART_LSR_TEMT | UART_LSR_THRE)) {
|
||||
dev_dbg(&port->dev, "%s -- Empty\n", __func__);
|
||||
@ -1782,7 +1805,7 @@ static int mos7720_tiocmset(struct tty_struct *tty,
|
||||
mcr &= ~UART_MCR_LOOP;
|
||||
|
||||
mos7720_port->shadowMCR = mcr;
|
||||
write_mos_reg(port->serial, port->port_number, MCR,
|
||||
write_mos_reg(port->serial, port->port_number, MOS7720_MCR,
|
||||
mos7720_port->shadowMCR);
|
||||
|
||||
return 0;
|
||||
@ -1827,7 +1850,7 @@ static int set_modem_info(struct moschip_port *mos7720_port, unsigned int cmd,
|
||||
}
|
||||
|
||||
mos7720_port->shadowMCR = mcr;
|
||||
write_mos_reg(port->serial, port->port_number, MCR,
|
||||
write_mos_reg(port->serial, port->port_number, MOS7720_MCR,
|
||||
mos7720_port->shadowMCR);
|
||||
|
||||
return 0;
|
||||
@ -1942,7 +1965,7 @@ static int mos7720_startup(struct usb_serial *serial)
|
||||
}
|
||||
#endif
|
||||
/* LSR For Port 1 */
|
||||
read_mos_reg(serial, 0, LSR, &data);
|
||||
read_mos_reg(serial, 0, MOS7720_LSR, &data);
|
||||
dev_dbg(&dev->dev, "LSR:%x\n", data);
|
||||
|
||||
return 0;
|
||||
|
@ -1765,6 +1765,7 @@ static const struct usb_device_id option_ids[] = {
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x7d03, 0xff, 0x00, 0x00) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x07d1, 0x3e01, 0xff, 0xff, 0xff) }, /* D-Link DWM-152/C1 */
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x07d1, 0x3e02, 0xff, 0xff, 0xff) }, /* D-Link DWM-156/C1 */
|
||||
{ USB_DEVICE_INTERFACE_CLASS(0x2020, 0x4000, 0xff) }, /* OLICARD300 - MT6225 */
|
||||
{ USB_DEVICE(INOVIA_VENDOR_ID, INOVIA_SEW858) },
|
||||
{ USB_DEVICE(VIATELECOM_VENDOR_ID, VIATELECOM_PRODUCT_CDS7) },
|
||||
{ } /* Terminating entry */
|
||||
|
@ -1306,6 +1306,7 @@ static void __exit usb_serial_exit(void)
|
||||
tty_unregister_driver(usb_serial_tty_driver);
|
||||
put_tty_driver(usb_serial_tty_driver);
|
||||
bus_unregister(&usb_serial_bus_type);
|
||||
idr_destroy(&serial_minors);
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user