[PATCH] MIPS: cavium-octeon: register octeon-hcd platform device

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



The forthcoming octeon-hcd USB driver (currently in staging) needs to be
converted into a proper platform device. Before we can do that we need
to register the device in OCTEON platform setup, so that e.g. EdgeRouter
Lite users continue to have a working USB.

Signed-off-by: Aaro Koskinen <aaro.koskinen@xxxxxx>
---
 arch/mips/cavium-octeon/octeon-platform.c | 58 +++++++++++++++++++++++++++++++
 1 file changed, 58 insertions(+)

diff --git a/arch/mips/cavium-octeon/octeon-platform.c b/arch/mips/cavium-octeon/octeon-platform.c
index 1830874..6d01582 100644
--- a/arch/mips/cavium-octeon/octeon-platform.c
+++ b/arch/mips/cavium-octeon/octeon-platform.c
@@ -166,6 +166,64 @@ out:
 }
 device_initcall(octeon_ohci_device_init);
 
+static int __init octeon_hcd_device_init(void)
+{
+	struct resource usb_res;
+	struct platform_device *pdev;
+
+	if (!(OCTEON_IS_MODEL(OCTEON_CN56XX) ||
+	      OCTEON_IS_MODEL(OCTEON_CN52XX) ||
+	      OCTEON_IS_MODEL(OCTEON_CN50XX) ||
+	      OCTEON_IS_MODEL(OCTEON_CN31XX) ||
+	      OCTEON_IS_MODEL(OCTEON_CN30XX)))
+		return 0;
+
+	if (octeon_is_simulation() || usb_disabled())
+		return 0;
+
+	/*
+	 * Only CN52XX and CN56XX have DWC_OTG USB hardware and the IOB priority
+	 * registers. Under heavy network load USB hardware can be starved by
+	 * the IOB causing a crash. Give it a priority boost if it has been
+	 * waiting more than 400 cycles to avoid this situation.
+	 *
+	 * Testing indicates that a cnt_val of 8192 is not sufficient, but no
+	 * failures are seen with 4096. We choose a value of 400 to give a
+	 * safety factor of 10.
+	 */
+	if (OCTEON_IS_MODEL(OCTEON_CN52XX) || OCTEON_IS_MODEL(OCTEON_CN56XX)) {
+		union cvmx_iob_n2c_l2c_pri_cnt pri_cnt;
+
+		pri_cnt.u64 = 0;
+		pri_cnt.s.cnt_enb = 1;
+		pri_cnt.s.cnt_val = 400;
+		cvmx_write_csr(CVMX_IOB_N2C_L2C_PRI_CNT, pri_cnt.u64);
+	}
+
+	memset(&usb_res, 0, sizeof(usb_res));
+	usb_res.start = OCTEON_IRQ_USB0;
+	usb_res.end   = OCTEON_IRQ_USB0;
+	usb_res.flags = IORESOURCE_IRQ;
+	pdev = platform_device_register_simple("octeon-hcd", 0, &usb_res, 1);
+	if (IS_ERR(pdev))
+		return PTR_ERR(pdev);
+
+	/* For all chips except CN52XX there is only one port. */
+	if (!OCTEON_IS_MODEL(OCTEON_CN52XX))
+		return 0;
+
+	memset(&usb_res, 0, sizeof(usb_res));
+	usb_res.start = OCTEON_IRQ_USB1;
+	usb_res.end   = OCTEON_IRQ_USB1;
+	usb_res.flags = IORESOURCE_IRQ;
+	pdev = platform_device_register_simple("octeon-hcd", 1, &usb_res, 1);
+	if (IS_ERR(pdev))
+		return PTR_ERR(pdev);
+
+	return 0;
+}
+device_initcall(octeon_hcd_device_init);
+
 #endif /* CONFIG_USB */
 
 static struct of_device_id __initdata octeon_ids[] = {
-- 
1.8.4.rc3



[Index of Archives]     [Linux MIPS Home]     [LKML Archive]     [Linux ARM Kernel]     [Linux ARM]     [Linux]     [Git]     [Yosemite News]     [Linux SCSI]     [Linux Hams]

  Powered by Linux