Commit cc1e204c authored by Mian Yousaf Kaukab's avatar Mian Yousaf Kaukab Committed by Felipe Balbi

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: default avatarJohn Youn <johnyoun@synopsys.com>
Tested-by: default avatarHeiko Stuebner <heiko@sntech.de>
Tested-by: default avatarDoug Anderson <dianders@chromium.org>
Signed-off-by: default avatarMian Yousaf Kaukab <yousaf.kaukab@intel.com>
Signed-off-by: default avatarFelipe Balbi <balbi@ti.com>
parent b5a468a6
......@@ -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;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment