Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  * pci.c - DesignWare HS OTG Controller PCI driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  * Copyright (C) 2004-2013 Synopsys, Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  * Redistribution and use in source and binary forms, with or without
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)  * modification, are permitted provided that the following conditions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9)  * are met:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10)  * 1. Redistributions of source code must retain the above copyright
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11)  *    notice, this list of conditions, and the following disclaimer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12)  *    without modification.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13)  * 2. Redistributions in binary form must reproduce the above copyright
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14)  *    notice, this list of conditions and the following disclaimer in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15)  *    documentation and/or other materials provided with the distribution.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16)  * 3. The names of the above-listed copyright holders may not be used
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17)  *    to endorse or promote products derived from this software without
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18)  *    specific prior written permission.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20)  * ALTERNATIVELY, this software may be distributed under the terms of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21)  * GNU General Public License ("GPL") as published by the Free Software
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22)  * Foundation; either version 2 of the License, or (at your option) any
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23)  * later version.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25)  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26)  * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27)  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28)  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29)  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30)  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31)  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32)  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33)  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34)  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35)  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39)  * Provides the initialization and cleanup entry points for the DWC_otg PCI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40)  * driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) #include <linux/moduleparam.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) #include <linux/spinlock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) #include <linux/pci.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) #include <linux/usb.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) #include <linux/usb/hcd.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) #include <linux/usb/ch11.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) #include <linux/usb/usb_phy_generic.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) #define PCI_PRODUCT_ID_HAPS_HSOTG	0xabc0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) static const char dwc2_driver_name[] = "dwc2-pci";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) struct dwc2_pci_glue {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 	struct platform_device *dwc2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 	struct platform_device *phy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) static int dwc2_pci_quirks(struct pci_dev *pdev, struct platform_device *dwc2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 	if (pdev->vendor == PCI_VENDOR_ID_SYNOPSYS &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 	    pdev->device == PCI_PRODUCT_ID_HAPS_HSOTG) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 		struct property_entry properties[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 			{ },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 		};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 		return platform_device_add_properties(dwc2, properties);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81)  * dwc2_pci_probe() - Provides the cleanup entry points for the DWC_otg PCI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82)  * driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84)  * @pci: The programming view of DWC_otg PCI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) static void dwc2_pci_remove(struct pci_dev *pci)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 	struct dwc2_pci_glue *glue = pci_get_drvdata(pci);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 	platform_device_unregister(glue->dwc2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 	usb_phy_generic_unregister(glue->phy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 	pci_set_drvdata(pci, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) static int dwc2_pci_probe(struct pci_dev *pci,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 			  const struct pci_device_id *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 	struct resource		res[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 	struct platform_device	*dwc2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 	struct platform_device	*phy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 	int			ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 	struct device		*dev = &pci->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 	struct dwc2_pci_glue	*glue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 	ret = pcim_enable_device(pci);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 		dev_err(dev, "failed to enable pci device\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 	pci_set_master(pci);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 	phy = usb_phy_generic_register();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 	if (IS_ERR(phy)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 		dev_err(dev, "error registering generic PHY (%ld)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 			PTR_ERR(phy));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 		return PTR_ERR(phy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 	dwc2 = platform_device_alloc("dwc2", PLATFORM_DEVID_AUTO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 	if (!dwc2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 		dev_err(dev, "couldn't allocate dwc2 device\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 		ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 		goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 	memset(res, 0x00, sizeof(struct resource) * ARRAY_SIZE(res));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 	res[0].start	= pci_resource_start(pci, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 	res[0].end	= pci_resource_end(pci, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 	res[0].name	= "dwc2";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 	res[0].flags	= IORESOURCE_MEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 	res[1].start	= pci->irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 	res[1].name	= "dwc2";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 	res[1].flags	= IORESOURCE_IRQ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 	ret = platform_device_add_resources(dwc2, res, ARRAY_SIZE(res));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 		dev_err(dev, "couldn't add resources to dwc2 device\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 		goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 	dwc2->dev.parent = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 	ret = dwc2_pci_quirks(pci, dwc2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 		goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 	glue = devm_kzalloc(dev, sizeof(*glue), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 	if (!glue) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 		ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 		goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 	ret = platform_device_add(dwc2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 		dev_err(dev, "failed to register dwc2 device\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 		goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 	glue->phy = phy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 	glue->dwc2 = dwc2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 	pci_set_drvdata(pci, glue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 	usb_phy_generic_unregister(phy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 	platform_device_put(dwc2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) static const struct pci_device_id dwc2_pci_ids[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 		PCI_DEVICE(PCI_VENDOR_ID_SYNOPSYS, PCI_PRODUCT_ID_HAPS_HSOTG),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 		PCI_DEVICE(PCI_VENDOR_ID_STMICRO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 			   PCI_DEVICE_ID_STMICRO_USB_OTG),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 	{ /* end: all zeroes */ }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) MODULE_DEVICE_TABLE(pci, dwc2_pci_ids);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) static struct pci_driver dwc2_pci_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 	.name = dwc2_driver_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 	.id_table = dwc2_pci_ids,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 	.probe = dwc2_pci_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 	.remove = dwc2_pci_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) module_pci_driver(dwc2_pci_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) MODULE_DESCRIPTION("DESIGNWARE HS OTG PCI Bus Glue");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) MODULE_AUTHOR("Synopsys, Inc.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) MODULE_LICENSE("Dual BSD/GPL");