drivers/usb/dwc3/dwc3-generic-plat.c

Source file repositories/reference/linux-study-clean/drivers/usb/dwc3/dwc3-generic-plat.c

File Facts

System
Linux kernel
Corpus path
drivers/usb/dwc3/dwc3-generic-plat.c
Extension
.c
Size
6492 bytes
Lines
257
Domain
Driver Families
Bucket
drivers/usb
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

struct dwc3_generic {
	struct device		*dev;
	struct dwc3		dwc;
	struct clk_bulk_data	*clks;
	int			num_clocks;
	struct reset_control	*resets;
};

struct dwc3_generic_config {
	int (*init)(struct dwc3_generic *dwc3g);
	struct dwc3_properties properties;
};

#define to_dwc3_generic(d) container_of((d), struct dwc3_generic, dwc)

static void dwc3_generic_reset_control_assert(void *data)
{
	reset_control_assert(data);
}

static int dwc3_eic7700_init(struct dwc3_generic *dwc3g)
{
	struct device *dev = dwc3g->dev;
	struct regmap *regmap;
	u32 hsp_usb_axi_lp;
	u32 hsp_usb_bus;
	u32 args[2];
	u32 val;

	regmap = syscon_regmap_lookup_by_phandle_args(dev->of_node,
						      "eswin,hsp-sp-csr",
						      ARRAY_SIZE(args), args);
	if (IS_ERR(regmap)) {
		dev_err(dev, "No hsp-sp-csr phandle specified\n");
		return PTR_ERR(regmap);
	}

	hsp_usb_bus       = args[0];
	hsp_usb_axi_lp    = args[1];

	regmap_read(regmap, hsp_usb_bus, &val);
	regmap_write(regmap, hsp_usb_bus, val | EIC7700_HSP_BUS_FILTER_EN |
		     EIC7700_HSP_BUS_CLKEN_GM | EIC7700_HSP_BUS_CLKEN_GS);

	regmap_write(regmap, hsp_usb_axi_lp, EIC7700_HSP_AXI_LP_XM_CSYSREQ |
		     EIC7700_HSP_AXI_LP_XS_CSYSREQ);
	return 0;
}

static int dwc3_spacemit_k1_init(struct dwc3_generic *dwc3g)
{
	struct device *dev = dwc3g->dev;

	if (usb_get_dr_mode(dev) == USB_DR_MODE_HOST) {
		int ret = devm_regulator_get_enable_optional(dev, "vbus");

		if (ret && ret != -ENODEV)
			return dev_err_probe(dev, ret, "failed to enable VBUS\n");
	}

	return 0;
}

static int dwc3_generic_probe(struct platform_device *pdev)
{
	const struct dwc3_generic_config *plat_config;
	struct dwc3_probe_data probe_data = {};
	struct device *dev = &pdev->dev;
	struct dwc3_generic *dwc3g;
	struct resource *res;
	int ret;

	dwc3g = devm_kzalloc(dev, sizeof(*dwc3g), GFP_KERNEL);
	if (!dwc3g)
		return -ENOMEM;

	dwc3g->dev = dev;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!res) {
		dev_err(&pdev->dev, "missing memory resource\n");
		return -ENODEV;
	}

	dwc3g->resets = devm_reset_control_array_get_optional_exclusive(dev);
	if (IS_ERR(dwc3g->resets))
		return dev_err_probe(dev, PTR_ERR(dwc3g->resets), "failed to get resets\n");

	ret = reset_control_assert(dwc3g->resets);
	if (ret)

Annotation

Implementation Notes