usb: dwc2: embed storage for reg backup in struct dwc2_hsotg
Register backup function can be called from atomic context. Instead of using atomic memory pool, embed backup storage space in struct dwc2_hsotg. Also add a valid flag in each struct as NULL pointer can't be used as the content validity check any more. Acked-by: John Youn <johnyoun@synopsys.com> Tested-by: Heiko Stuebner <heiko@sntech.de> Tested-by: Doug Anderson <dianders@chromium.org> Signed-off-by: Mian Yousaf Kaukab <yousaf.kaukab@intel.com> Signed-off-by: Felipe Balbi <balbi@ti.com>
This commit is contained in:
parent
b5a468a6aa
commit
cc1e204cb0
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue