Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+15 −40
Original line number Diff line number Diff line
@@ -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);
+6 −3
Original line number Diff line number Diff line
@@ -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;