cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

dwc3-haps.c (3589B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 * dwc3-haps.c - Synopsys HAPS PCI Specific glue layer
      4 *
      5 * Copyright (C) 2018 Synopsys, Inc.
      6 *
      7 * Authors: Thinh Nguyen <thinhn@synopsys.com>,
      8 *          John Youn <johnyoun@synopsys.com>
      9 */
     10
     11#include <linux/kernel.h>
     12#include <linux/module.h>
     13#include <linux/slab.h>
     14#include <linux/pci.h>
     15#include <linux/platform_device.h>
     16#include <linux/property.h>
     17
     18/**
     19 * struct dwc3_haps - Driver private structure
     20 * @dwc3: child dwc3 platform_device
     21 * @pci: our link to PCI bus
     22 */
     23struct dwc3_haps {
     24	struct platform_device *dwc3;
     25	struct pci_dev *pci;
     26};
     27
     28static const struct property_entry initial_properties[] = {
     29	PROPERTY_ENTRY_BOOL("snps,usb3_lpm_capable"),
     30	PROPERTY_ENTRY_BOOL("snps,has-lpm-erratum"),
     31	PROPERTY_ENTRY_BOOL("snps,dis_enblslpm_quirk"),
     32	PROPERTY_ENTRY_BOOL("linux,sysdev_is_parent"),
     33	{ },
     34};
     35
     36static const struct software_node dwc3_haps_swnode = {
     37	.properties = initial_properties,
     38};
     39
     40static int dwc3_haps_probe(struct pci_dev *pci,
     41			   const struct pci_device_id *id)
     42{
     43	struct dwc3_haps	*dwc;
     44	struct device		*dev = &pci->dev;
     45	struct resource		res[2];
     46	int			ret;
     47
     48	ret = pcim_enable_device(pci);
     49	if (ret) {
     50		dev_err(dev, "failed to enable pci device\n");
     51		return -ENODEV;
     52	}
     53
     54	pci_set_master(pci);
     55
     56	dwc = devm_kzalloc(dev, sizeof(*dwc), GFP_KERNEL);
     57	if (!dwc)
     58		return -ENOMEM;
     59
     60	dwc->dwc3 = platform_device_alloc("dwc3", PLATFORM_DEVID_AUTO);
     61	if (!dwc->dwc3)
     62		return -ENOMEM;
     63
     64	memset(res, 0x00, sizeof(struct resource) * ARRAY_SIZE(res));
     65
     66	res[0].start	= pci_resource_start(pci, 0);
     67	res[0].end	= pci_resource_end(pci, 0);
     68	res[0].name	= "dwc_usb3";
     69	res[0].flags	= IORESOURCE_MEM;
     70
     71	res[1].start	= pci->irq;
     72	res[1].name	= "dwc_usb3";
     73	res[1].flags	= IORESOURCE_IRQ;
     74
     75	ret = platform_device_add_resources(dwc->dwc3, res, ARRAY_SIZE(res));
     76	if (ret) {
     77		dev_err(dev, "couldn't add resources to dwc3 device\n");
     78		goto err;
     79	}
     80
     81	dwc->pci = pci;
     82	dwc->dwc3->dev.parent = dev;
     83
     84	ret = device_add_software_node(&dwc->dwc3->dev, &dwc3_haps_swnode);
     85	if (ret)
     86		goto err;
     87
     88	ret = platform_device_add(dwc->dwc3);
     89	if (ret) {
     90		dev_err(dev, "failed to register dwc3 device\n");
     91		goto err;
     92	}
     93
     94	pci_set_drvdata(pci, dwc);
     95
     96	return 0;
     97err:
     98	device_remove_software_node(&dwc->dwc3->dev);
     99	platform_device_put(dwc->dwc3);
    100	return ret;
    101}
    102
    103static void dwc3_haps_remove(struct pci_dev *pci)
    104{
    105	struct dwc3_haps *dwc = pci_get_drvdata(pci);
    106
    107	device_remove_software_node(&dwc->dwc3->dev);
    108	platform_device_unregister(dwc->dwc3);
    109}
    110
    111static const struct pci_device_id dwc3_haps_id_table[] = {
    112	{
    113		PCI_DEVICE(PCI_VENDOR_ID_SYNOPSYS,
    114			   PCI_DEVICE_ID_SYNOPSYS_HAPSUSB3),
    115		/*
    116		 * i.MX6QP and i.MX7D platform use a PCIe controller with the
    117		 * same VID and PID as this USB controller. The system may
    118		 * incorrectly match this driver to that PCIe controller. To
    119		 * workaround this, specifically use class type USB to prevent
    120		 * incorrect driver matching.
    121		 */
    122		.class = (PCI_CLASS_SERIAL_USB << 8),
    123		.class_mask = 0xffff00,
    124	},
    125	{
    126		PCI_DEVICE(PCI_VENDOR_ID_SYNOPSYS,
    127			   PCI_DEVICE_ID_SYNOPSYS_HAPSUSB3_AXI),
    128	},
    129	{
    130		PCI_DEVICE(PCI_VENDOR_ID_SYNOPSYS,
    131			   PCI_DEVICE_ID_SYNOPSYS_HAPSUSB31),
    132	},
    133	{  }	/* Terminating Entry */
    134};
    135MODULE_DEVICE_TABLE(pci, dwc3_haps_id_table);
    136
    137static struct pci_driver dwc3_haps_driver = {
    138	.name		= "dwc3-haps",
    139	.id_table	= dwc3_haps_id_table,
    140	.probe		= dwc3_haps_probe,
    141	.remove		= dwc3_haps_remove,
    142};
    143
    144MODULE_AUTHOR("Thinh Nguyen <thinhn@synopsys.com>");
    145MODULE_LICENSE("GPL v2");
    146MODULE_DESCRIPTION("Synopsys HAPS PCI Glue Layer");
    147
    148module_pci_driver(dwc3_haps_driver);