linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/2] MIPS/staging: Probe octeon-usb driver via device-tree
@ 2013-12-03 19:46 David Daney
  2013-12-03 19:46 ` [PATCH 1/2] MIPS: OCTEON: Supply OCTEON+ USB nodes in internal device trees David Daney
                   ` (2 more replies)
  0 siblings, 3 replies; 8+ messages in thread
From: David Daney @ 2013-12-03 19:46 UTC (permalink / raw)
  To: linux-mips, ralf, Aaro Koskinen, Greg Kroah-Hartman
  Cc: linux-kernel, David Daney

From: David Daney <david.daney@cavium.com>

Tested against both EdgeRouter LITE (no bootloader supplied device
tree), and ebb5610 (device tree supplied by bootloader).

The patch set is spread across both the MIPS and staging trees, so it
would be great if Ralf could merge at least the MIPS parts, if not
both parts.


David Daney (2):
  MIPS: OCTEON: Supply OCTEON+ USB nodes in internal device trees.
  staging: octeon-usb: Probe via device tree populated platform device.

 .../cavium-octeon/executive/cvmx-helper-board.c    |  27 ++
 arch/mips/cavium-octeon/octeon-platform.c          |  32 +++
 arch/mips/cavium-octeon/octeon_3xxx.dts            |  19 ++
 arch/mips/include/asm/octeon/cvmx-helper-board.h   |   9 +
 drivers/staging/octeon-usb/octeon-hcd.c            | 273 +++++++++------------
 5 files changed, 203 insertions(+), 157 deletions(-)

-- 
1.7.11.7


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH 1/2] MIPS: OCTEON: Supply OCTEON+ USB nodes in internal device trees.
  2013-12-03 19:46 [PATCH 0/2] MIPS/staging: Probe octeon-usb driver via device-tree David Daney
@ 2013-12-03 19:46 ` David Daney
  2013-12-04 21:39   ` Aaro Koskinen
  2013-12-03 19:46 ` [PATCH 2/2] staging: octeon-usb: Probe via device tree populated platform device David Daney
  2013-12-04 23:29 ` [PATCH 0/2] MIPS/staging: Probe octeon-usb driver via device-tree Greg Kroah-Hartman
  2 siblings, 1 reply; 8+ messages in thread
From: David Daney @ 2013-12-03 19:46 UTC (permalink / raw)
  To: linux-mips, ralf, Aaro Koskinen, Greg Kroah-Hartman
  Cc: linux-kernel, David Daney

From: David Daney <david.daney@cavium.com>

This will be needed by the next patch to use said nodes for probing
via the device tree.

Signed-off-by: David Daney <david.daney@cavium.com>
---
 .../cavium-octeon/executive/cvmx-helper-board.c    | 27 ++++++++++++++++++
 arch/mips/cavium-octeon/octeon-platform.c          | 32 ++++++++++++++++++++++
 arch/mips/cavium-octeon/octeon_3xxx.dts            | 19 +++++++++++++
 arch/mips/include/asm/octeon/cvmx-helper-board.h   |  9 ++++++
 4 files changed, 87 insertions(+)

diff --git a/arch/mips/cavium-octeon/executive/cvmx-helper-board.c b/arch/mips/cavium-octeon/executive/cvmx-helper-board.c
index 0a1283c..b764df6 100644
--- a/arch/mips/cavium-octeon/executive/cvmx-helper-board.c
+++ b/arch/mips/cavium-octeon/executive/cvmx-helper-board.c
@@ -722,3 +722,30 @@ int __cvmx_helper_board_hardware_enable(int interface)
 	}
 	return 0;
 }
+
+/**
+ * Get the clock type used for the USB block based on board type.
+ * Used by the USB code for auto configuration of clock type.
+ *
+ * Return USB clock type enumeration
+ */
+enum cvmx_helper_board_usb_clock_types __cvmx_helper_board_usb_get_clock_type(void)
+{
+	switch (cvmx_sysinfo_get()->board_type) {
+	case CVMX_BOARD_TYPE_BBGW_REF:
+	case CVMX_BOARD_TYPE_LANAI2_A:
+	case CVMX_BOARD_TYPE_LANAI2_U:
+	case CVMX_BOARD_TYPE_LANAI2_G:
+	case CVMX_BOARD_TYPE_NIC10E_66:
+	case CVMX_BOARD_TYPE_UBNT_E100:
+		return USB_CLOCK_TYPE_CRYSTAL_12;
+	case CVMX_BOARD_TYPE_NIC10E:
+		return USB_CLOCK_TYPE_REF_12;
+	default:
+		break;
+	}
+	/* Most boards except NIC10e use a 12MHz crystal */
+	if (OCTEON_IS_MODEL(OCTEON_FAM_2))
+		return USB_CLOCK_TYPE_CRYSTAL_12;
+	return USB_CLOCK_TYPE_REF_48;
+}
diff --git a/arch/mips/cavium-octeon/octeon-platform.c b/arch/mips/cavium-octeon/octeon-platform.c
index 1830874..cd4fd6b 100644
--- a/arch/mips/cavium-octeon/octeon-platform.c
+++ b/arch/mips/cavium-octeon/octeon-platform.c
@@ -171,6 +171,7 @@ device_initcall(octeon_ohci_device_init);
 static struct of_device_id __initdata octeon_ids[] = {
 	{ .compatible = "simple-bus", },
 	{ .compatible = "cavium,octeon-6335-uctl", },
+	{ .compatible = "cavium,octeon-5750-usbn", },
 	{ .compatible = "cavium,octeon-3860-bootbus", },
 	{ .compatible = "cavium,mdio-mux", },
 	{ .compatible = "gpio-leds", },
@@ -682,6 +683,37 @@ end_led:
 		}
 	}
 
+	/* DWC2 USB */
+	alias_prop = fdt_getprop(initial_boot_params, aliases,
+				 "usbn", NULL);
+	if (alias_prop) {
+		int usbn = fdt_path_offset(initial_boot_params, alias_prop);
+
+		if (usbn >= 0 && (current_cpu_type() == CPU_CAVIUM_OCTEON2 ||
+				  !octeon_has_feature(OCTEON_FEATURE_USB))) {
+			pr_debug("Deleting usbn\n");
+			fdt_nop_node(initial_boot_params, usbn);
+			fdt_nop_property(initial_boot_params, aliases, "usbn");
+		} else  {
+			__be32 new_f[1];
+			enum cvmx_helper_board_usb_clock_types c;
+			c = __cvmx_helper_board_usb_get_clock_type();
+			switch (c) {
+			case USB_CLOCK_TYPE_REF_48:
+				new_f[0] = cpu_to_be32(48000000);
+				fdt_setprop_inplace(initial_boot_params, usbn,
+						    "refclk-frequency",  new_f, sizeof(new_f));
+				/* Fall through ...*/
+			case USB_CLOCK_TYPE_REF_12:
+				/* Missing "refclk-type" defaults to external. */
+				fdt_nop_property(initial_boot_params, usbn, "refclk-type");
+				break;
+			default:
+				break;
+			}
+		}
+	}
+
 	return 0;
 }
 
diff --git a/arch/mips/cavium-octeon/octeon_3xxx.dts b/arch/mips/cavium-octeon/octeon_3xxx.dts
index 88cb42d..fa33115 100644
--- a/arch/mips/cavium-octeon/octeon_3xxx.dts
+++ b/arch/mips/cavium-octeon/octeon_3xxx.dts
@@ -550,6 +550,24 @@
 				big-endian-regs;
 			};
 		};
+
+		usbn: usbn@1180068000000 {
+			compatible = "cavium,octeon-5750-usbn";
+			reg = <0x11800 0x68000000 0x0 0x1000>;
+			ranges; /* Direct mapping */
+			#address-cells = <2>;
+			#size-cells = <2>;
+			/* 12MHz, 24MHz and 48MHz allowed */
+			refclk-frequency = <12000000>;
+			/* Either "crystal" or "external" */
+			refclk-type = "crystal";
+
+			usbc@16f0010000000 {
+				compatible = "cavium,octeon-5750-usbc";
+				reg = <0x16f00 0x10000000 0x0 0x80000>;
+				interrupts = <0 56>;
+			};
+		};
 	};
 
 	aliases {
@@ -566,6 +584,7 @@
 		flash0 = &flash0;
 		cf0 = &cf0;
 		uctl = &uctl;
+		usbn = &usbn;
 		led0 = &led0;
 	};
  };
diff --git a/arch/mips/include/asm/octeon/cvmx-helper-board.h b/arch/mips/include/asm/octeon/cvmx-helper-board.h
index 41785dd..8933203 100644
--- a/arch/mips/include/asm/octeon/cvmx-helper-board.h
+++ b/arch/mips/include/asm/octeon/cvmx-helper-board.h
@@ -36,6 +36,13 @@
 
 #include <asm/octeon/cvmx-helper.h>
 
+enum cvmx_helper_board_usb_clock_types {
+	USB_CLOCK_TYPE_REF_12,
+	USB_CLOCK_TYPE_REF_24,
+	USB_CLOCK_TYPE_REF_48,
+	USB_CLOCK_TYPE_CRYSTAL_12,
+};
+
 typedef enum {
 	set_phy_link_flags_autoneg = 0x1,
 	set_phy_link_flags_flow_control_dont_touch = 0x0 << 1,
@@ -154,4 +161,6 @@ extern int __cvmx_helper_board_interface_probe(int interface,
  */
 extern int __cvmx_helper_board_hardware_enable(int interface);
 
+enum cvmx_helper_board_usb_clock_types __cvmx_helper_board_usb_get_clock_type(void);
+
 #endif /* __CVMX_HELPER_BOARD_H__ */
-- 
1.7.11.7


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 2/2] staging: octeon-usb: Probe via device tree populated platform device.
  2013-12-03 19:46 [PATCH 0/2] MIPS/staging: Probe octeon-usb driver via device-tree David Daney
  2013-12-03 19:46 ` [PATCH 1/2] MIPS: OCTEON: Supply OCTEON+ USB nodes in internal device trees David Daney
@ 2013-12-03 19:46 ` David Daney
  2013-12-04 21:40   ` Aaro Koskinen
  2013-12-04 23:29 ` [PATCH 0/2] MIPS/staging: Probe octeon-usb driver via device-tree Greg Kroah-Hartman
  2 siblings, 1 reply; 8+ messages in thread
From: David Daney @ 2013-12-03 19:46 UTC (permalink / raw)
  To: linux-mips, ralf, Aaro Koskinen, Greg Kroah-Hartman
  Cc: linux-kernel, David Daney

From: David Daney <david.daney@cavium.com>

Extract clocking parameters from the device tree, and remove now dead
code and types.

Signed-off-by: David Daney <david.daney@cavium.com>
---
 drivers/staging/octeon-usb/octeon-hcd.c | 273 ++++++++++++++------------------
 1 file changed, 116 insertions(+), 157 deletions(-)

diff --git a/drivers/staging/octeon-usb/octeon-hcd.c b/drivers/staging/octeon-usb/octeon-hcd.c
index d118952..c53499a 100644
--- a/drivers/staging/octeon-usb/octeon-hcd.c
+++ b/drivers/staging/octeon-usb/octeon-hcd.c
@@ -275,13 +275,6 @@ enum cvmx_usb_pipe_flags {
  */
 #define MAX_TRANSFER_PACKETS	((1<<10)-1)
 
-enum {
-	USB_CLOCK_TYPE_REF_12,
-	USB_CLOCK_TYPE_REF_24,
-	USB_CLOCK_TYPE_REF_48,
-	USB_CLOCK_TYPE_CRYSTAL_12,
-};
-
 /**
  * Logical transactions may take numerous low level
  * transactions, especially when splits are concerned. This
@@ -471,19 +464,6 @@ struct octeon_hcd {
 /* Returns the IO address to push/pop stuff data from the FIFOs */
 #define USB_FIFO_ADDRESS(channel, usb_index) (CVMX_USBCX_GOTGCTL(usb_index) + ((channel)+1)*0x1000)
 
-static int octeon_usb_get_clock_type(void)
-{
-	switch (cvmx_sysinfo_get()->board_type) {
-	case CVMX_BOARD_TYPE_BBGW_REF:
-	case CVMX_BOARD_TYPE_LANAI2_A:
-	case CVMX_BOARD_TYPE_LANAI2_U:
-	case CVMX_BOARD_TYPE_LANAI2_G:
-	case CVMX_BOARD_TYPE_UBNT_E100:
-		return USB_CLOCK_TYPE_CRYSTAL_12;
-	}
-	return USB_CLOCK_TYPE_REF_48;
-}
-
 /**
  * Read a USB 32bit CSR. It performs the necessary address swizzle
  * for 32bit CSRs and logs the value in a readable format if
@@ -582,37 +562,6 @@ static inline int __cvmx_usb_get_data_pid(struct cvmx_usb_pipe *pipe)
 		return 0; /* Data0 */
 }
 
-
-/**
- * Return the number of USB ports supported by this Octeon
- * chip. If the chip doesn't support USB, or is not supported
- * by this API, a zero will be returned. Most Octeon chips
- * support one usb port, but some support two ports.
- * cvmx_usb_initialize() must be called on independent
- * struct cvmx_usb_state.
- *
- * Returns: Number of port, zero if usb isn't supported
- */
-static int cvmx_usb_get_num_ports(void)
-{
-	int arch_ports = 0;
-
-	if (OCTEON_IS_MODEL(OCTEON_CN56XX))
-		arch_ports = 1;
-	else if (OCTEON_IS_MODEL(OCTEON_CN52XX))
-		arch_ports = 2;
-	else if (OCTEON_IS_MODEL(OCTEON_CN50XX))
-		arch_ports = 1;
-	else if (OCTEON_IS_MODEL(OCTEON_CN31XX))
-		arch_ports = 1;
-	else if (OCTEON_IS_MODEL(OCTEON_CN30XX))
-		arch_ports = 1;
-	else
-		arch_ports = 0;
-
-	return arch_ports;
-}
-
 /**
  * Initialize a USB port for use. This must be called before any
  * other access to the Octeon USB port is made. The port starts
@@ -628,41 +577,16 @@ static int cvmx_usb_get_num_ports(void)
  * Returns: 0 or a negative error code.
  */
 static int cvmx_usb_initialize(struct cvmx_usb_state *usb,
-			       int usb_port_number)
+			       int usb_port_number,
+			       enum cvmx_usb_initialize_flags flags)
 {
 	union cvmx_usbnx_clk_ctl usbn_clk_ctl;
 	union cvmx_usbnx_usbp_ctl_status usbn_usbp_ctl_status;
-	enum cvmx_usb_initialize_flags flags = 0;
 	int i;
 
 	/* At first allow 0-1 for the usb port number */
 	if ((usb_port_number < 0) || (usb_port_number > 1))
 		return -EINVAL;
-	/* For all chips except 52XX there is only one port */
-	if (!OCTEON_IS_MODEL(OCTEON_CN52XX) && (usb_port_number > 0))
-		return -EINVAL;
-	/* Try to determine clock type automatically */
-	if (octeon_usb_get_clock_type() == USB_CLOCK_TYPE_CRYSTAL_12) {
-		/* Only 12 MHZ crystals are supported */
-		flags |= CVMX_USB_INITIALIZE_FLAGS_CLOCK_XO_XI;
-	} else {
-		flags |= CVMX_USB_INITIALIZE_FLAGS_CLOCK_XO_GND;
-
-		switch (octeon_usb_get_clock_type()) {
-		case USB_CLOCK_TYPE_REF_12:
-			flags |= CVMX_USB_INITIALIZE_FLAGS_CLOCK_12MHZ;
-			break;
-		case USB_CLOCK_TYPE_REF_24:
-			flags |= CVMX_USB_INITIALIZE_FLAGS_CLOCK_24MHZ;
-			break;
-		case USB_CLOCK_TYPE_REF_48:
-			flags |= CVMX_USB_INITIALIZE_FLAGS_CLOCK_48MHZ;
-			break;
-		default:
-			return -EINVAL;
-			break;
-		}
-	}
 
 	memset(usb, 0, sizeof(*usb));
 	usb->init_flags = flags;
@@ -3431,7 +3355,6 @@ static int octeon_usb_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
 	return 0;
 }
 
-
 static const struct hc_driver octeon_hc_driver = {
 	.description		= "Octeon USB",
 	.product_desc		= "Octeon Host Controller",
@@ -3448,15 +3371,74 @@ static const struct hc_driver octeon_hc_driver = {
 	.hub_control		= octeon_usb_hub_control,
 };
 
-
-static int octeon_usb_driver_probe(struct device *dev)
+static int octeon_usb_probe(struct platform_device *pdev)
 {
 	int status;
-	int usb_num = to_platform_device(dev)->id;
-	int irq = platform_get_irq(to_platform_device(dev), 0);
+	int initialize_flags;
+	int usb_num;
+	struct resource *res_mem;
+	struct device_node *usbn_node;
+	int irq = platform_get_irq(pdev, 0);
+	struct device *dev = &pdev->dev;
 	struct octeon_hcd *priv;
 	struct usb_hcd *hcd;
 	unsigned long flags;
+	u32 clock_rate = 48000000;
+	bool is_crystal_clock = false;
+	const char *clock_type;
+	int i;
+
+	if (dev->of_node == NULL) {
+		dev_err(dev, "Error: empty of_node\n");
+		return -ENXIO;
+	}
+	usbn_node = dev->of_node->parent;
+
+	i = of_property_read_u32(usbn_node,
+				 "refclk-frequency", &clock_rate);
+	if (i) {
+		dev_err(dev, "No USBN \"refclk-frequency\"\n");
+		return -ENXIO;
+	}
+	switch (clock_rate) {
+	case 12000000:
+		initialize_flags = CVMX_USB_INITIALIZE_FLAGS_CLOCK_12MHZ;
+		break;
+	case 24000000:
+		initialize_flags = CVMX_USB_INITIALIZE_FLAGS_CLOCK_24MHZ;
+		break;
+	case 48000000:
+		initialize_flags = CVMX_USB_INITIALIZE_FLAGS_CLOCK_48MHZ;
+		break;
+	default:
+		dev_err(dev, "Illebal USBN \"refclk-frequency\" %u\n", clock_rate);
+		return -ENXIO;
+
+	}
+
+	i = of_property_read_string(usbn_node,
+				    "refclk-type", &clock_type);
+
+	if (!i && strcmp("crystal", clock_type) == 0)
+		is_crystal_clock = true;
+
+	if (is_crystal_clock)
+		initialize_flags |= CVMX_USB_INITIALIZE_FLAGS_CLOCK_XO_XI;
+	else
+		initialize_flags |= CVMX_USB_INITIALIZE_FLAGS_CLOCK_XO_GND;
+
+	res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (res_mem == NULL) {
+		dev_err(dev, "found no memory resource\n");
+		return -ENXIO;
+	}
+	usb_num = (res_mem->start >> 44) & 1;
+
+	if (irq < 0) {
+		/* Defective device tree, but we know how to fix it. */
+		irq_hw_number_t hwirq = usb_num ? (1 << 6) + 17 : 56;
+		irq = irq_create_mapping(NULL, hwirq);
+	}
 
 	/*
 	 * Set the DMA mask to 64bits so we get buffers already translated for
@@ -3465,6 +3447,26 @@ static int octeon_usb_driver_probe(struct device *dev)
 	dev->coherent_dma_mask = ~0;
 	dev->dma_mask = &dev->coherent_dma_mask;
 
+	/*
+	 * 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);
+	}
+
 	hcd = usb_create_hcd(&octeon_hc_driver, dev, dev_name(dev));
 	if (!hcd) {
 		dev_dbg(dev, "Failed to allocate memory for HCD\n");
@@ -3478,7 +3480,7 @@ static int octeon_usb_driver_probe(struct device *dev)
 	tasklet_init(&priv->dequeue_tasklet, octeon_usb_urb_dequeue_work, (unsigned long)priv);
 	INIT_LIST_HEAD(&priv->dequeue_list);
 
-	status = cvmx_usb_initialize(&priv->usb, usb_num);
+	status = cvmx_usb_initialize(&priv->usb, usb_num, initialize_flags);
 	if (status) {
 		dev_dbg(dev, "USB initialization failed with %d\n", status);
 		kfree(hcd);
@@ -3492,21 +3494,22 @@ static int octeon_usb_driver_probe(struct device *dev)
 	cvmx_usb_poll(&priv->usb);
 	spin_unlock_irqrestore(&priv->lock, flags);
 
-	status = usb_add_hcd(hcd, irq, IRQF_SHARED);
+	status = usb_add_hcd(hcd, irq, 0);
 	if (status) {
 		dev_dbg(dev, "USB add HCD failed with %d\n", status);
 		kfree(hcd);
 		return -1;
 	}
 
-	dev_dbg(dev, "Registered HCD for port %d on irq %d\n", usb_num, irq);
+	dev_info(dev, "Registered HCD for port %d on irq %d\n", usb_num, irq);
 
 	return 0;
 }
 
-static int octeon_usb_driver_remove(struct device *dev)
+static int octeon_usb_remove(struct platform_device *pdev)
 {
 	int status;
+	struct device *dev = &pdev->dev;
 	struct usb_hcd *hcd = dev_get_drvdata(dev);
 	struct octeon_hcd *priv = hcd_to_octeon(hcd);
 	unsigned long flags;
@@ -3524,85 +3527,41 @@ static int octeon_usb_driver_remove(struct device *dev)
 	return 0;
 }
 
-static struct device_driver octeon_usb_driver = {
-	.name	= "OcteonUSB",
-	.bus	= &platform_bus_type,
-	.probe	= octeon_usb_driver_probe,
-	.remove	= octeon_usb_driver_remove,
+static struct of_device_id octeon_usb_match[] = {
+	{
+		.compatible = "cavium,octeon-5750-usbc",
+	},
+	{},
 };
 
+static struct platform_driver octeon_usb_driver = {
+	.driver = {
+		.name       = "OcteonUSB",
+		.owner		= THIS_MODULE,
+		.of_match_table = octeon_usb_match,
+	},
+	.probe      = octeon_usb_probe,
+	.remove     = octeon_usb_remove,
+};
 
-#define MAX_USB_PORTS   10
-static struct platform_device *pdev_glob[MAX_USB_PORTS];
-static int octeon_usb_registered;
-static int __init octeon_usb_module_init(void)
+static int __init octeon_usb_driver_init(void)
 {
-	int num_devices = cvmx_usb_get_num_ports();
-	int device;
-
-	if (usb_disabled() || num_devices == 0)
-		return -ENODEV;
-
-	if (driver_register(&octeon_usb_driver))
-		return -ENOMEM;
-
-	octeon_usb_registered = 1;
-
-	/*
-	 * 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);
-	}
-
-	for (device = 0; device < num_devices; device++) {
-		struct resource irq_resource;
-		struct platform_device *pdev;
-		memset(&irq_resource, 0, sizeof(irq_resource));
-		irq_resource.start = (device == 0) ? OCTEON_IRQ_USB0 : OCTEON_IRQ_USB1;
-		irq_resource.end = irq_resource.start;
-		irq_resource.flags = IORESOURCE_IRQ;
-		pdev = platform_device_register_simple((char *)octeon_usb_driver.  name, device, &irq_resource, 1);
-		if (IS_ERR(pdev)) {
-			driver_unregister(&octeon_usb_driver);
-			octeon_usb_registered = 0;
-			return PTR_ERR(pdev);
-		}
-		if (device < MAX_USB_PORTS)
-			pdev_glob[device] = pdev;
+	if (usb_disabled())
+		return 0;
 
-	}
-	return 0;
+	return platform_driver_register(&octeon_usb_driver);
 }
+module_init(octeon_usb_driver_init);
 
-static void __exit octeon_usb_module_cleanup(void)
+static void __exit octeon_usb_driver_exit(void)
 {
-	int i;
+	if (usb_disabled())
+		return;
 
-	for (i = 0; i < MAX_USB_PORTS; i++)
-		if (pdev_glob[i]) {
-			platform_device_unregister(pdev_glob[i]);
-			pdev_glob[i] = NULL;
-		}
-	if (octeon_usb_registered)
-		driver_unregister(&octeon_usb_driver);
+	platform_driver_unregister(&octeon_usb_driver);
 }
+module_exit(octeon_usb_driver_exit);
 
 MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Cavium Networks <support@caviumnetworks.com>");
-MODULE_DESCRIPTION("Cavium Networks Octeon USB Host driver.");
-module_init(octeon_usb_module_init);
-module_exit(octeon_usb_module_cleanup);
+MODULE_AUTHOR("Cavium, Inc. <support@cavium.com>");
+MODULE_DESCRIPTION("Cavium Inc. OCTEON USB Host driver.");
-- 
1.7.11.7


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH 1/2] MIPS: OCTEON: Supply OCTEON+ USB nodes in internal device trees.
  2013-12-03 19:46 ` [PATCH 1/2] MIPS: OCTEON: Supply OCTEON+ USB nodes in internal device trees David Daney
@ 2013-12-04 21:39   ` Aaro Koskinen
  0 siblings, 0 replies; 8+ messages in thread
From: Aaro Koskinen @ 2013-12-04 21:39 UTC (permalink / raw)
  To: David Daney
  Cc: linux-mips, ralf, Greg Kroah-Hartman, linux-kernel, David Daney

Hi,

On Tue, Dec 03, 2013 at 11:46:51AM -0800, David Daney wrote:
> From: David Daney <david.daney@cavium.com>
> 
> This will be needed by the next patch to use said nodes for probing
> via the device tree.
> 
> Signed-off-by: David Daney <david.daney@cavium.com>

Tested-by: Aaro Koskinen <aaro.koskinen@iki.fi>

A.

> ---
>  .../cavium-octeon/executive/cvmx-helper-board.c    | 27 ++++++++++++++++++
>  arch/mips/cavium-octeon/octeon-platform.c          | 32 ++++++++++++++++++++++
>  arch/mips/cavium-octeon/octeon_3xxx.dts            | 19 +++++++++++++
>  arch/mips/include/asm/octeon/cvmx-helper-board.h   |  9 ++++++
>  4 files changed, 87 insertions(+)
> 
> diff --git a/arch/mips/cavium-octeon/executive/cvmx-helper-board.c b/arch/mips/cavium-octeon/executive/cvmx-helper-board.c
> index 0a1283c..b764df6 100644
> --- a/arch/mips/cavium-octeon/executive/cvmx-helper-board.c
> +++ b/arch/mips/cavium-octeon/executive/cvmx-helper-board.c
> @@ -722,3 +722,30 @@ int __cvmx_helper_board_hardware_enable(int interface)
>  	}
>  	return 0;
>  }
> +
> +/**
> + * Get the clock type used for the USB block based on board type.
> + * Used by the USB code for auto configuration of clock type.
> + *
> + * Return USB clock type enumeration
> + */
> +enum cvmx_helper_board_usb_clock_types __cvmx_helper_board_usb_get_clock_type(void)
> +{
> +	switch (cvmx_sysinfo_get()->board_type) {
> +	case CVMX_BOARD_TYPE_BBGW_REF:
> +	case CVMX_BOARD_TYPE_LANAI2_A:
> +	case CVMX_BOARD_TYPE_LANAI2_U:
> +	case CVMX_BOARD_TYPE_LANAI2_G:
> +	case CVMX_BOARD_TYPE_NIC10E_66:
> +	case CVMX_BOARD_TYPE_UBNT_E100:
> +		return USB_CLOCK_TYPE_CRYSTAL_12;
> +	case CVMX_BOARD_TYPE_NIC10E:
> +		return USB_CLOCK_TYPE_REF_12;
> +	default:
> +		break;
> +	}
> +	/* Most boards except NIC10e use a 12MHz crystal */
> +	if (OCTEON_IS_MODEL(OCTEON_FAM_2))
> +		return USB_CLOCK_TYPE_CRYSTAL_12;
> +	return USB_CLOCK_TYPE_REF_48;
> +}
> diff --git a/arch/mips/cavium-octeon/octeon-platform.c b/arch/mips/cavium-octeon/octeon-platform.c
> index 1830874..cd4fd6b 100644
> --- a/arch/mips/cavium-octeon/octeon-platform.c
> +++ b/arch/mips/cavium-octeon/octeon-platform.c
> @@ -171,6 +171,7 @@ device_initcall(octeon_ohci_device_init);
>  static struct of_device_id __initdata octeon_ids[] = {
>  	{ .compatible = "simple-bus", },
>  	{ .compatible = "cavium,octeon-6335-uctl", },
> +	{ .compatible = "cavium,octeon-5750-usbn", },
>  	{ .compatible = "cavium,octeon-3860-bootbus", },
>  	{ .compatible = "cavium,mdio-mux", },
>  	{ .compatible = "gpio-leds", },
> @@ -682,6 +683,37 @@ end_led:
>  		}
>  	}
>  
> +	/* DWC2 USB */
> +	alias_prop = fdt_getprop(initial_boot_params, aliases,
> +				 "usbn", NULL);
> +	if (alias_prop) {
> +		int usbn = fdt_path_offset(initial_boot_params, alias_prop);
> +
> +		if (usbn >= 0 && (current_cpu_type() == CPU_CAVIUM_OCTEON2 ||
> +				  !octeon_has_feature(OCTEON_FEATURE_USB))) {
> +			pr_debug("Deleting usbn\n");
> +			fdt_nop_node(initial_boot_params, usbn);
> +			fdt_nop_property(initial_boot_params, aliases, "usbn");
> +		} else  {
> +			__be32 new_f[1];
> +			enum cvmx_helper_board_usb_clock_types c;
> +			c = __cvmx_helper_board_usb_get_clock_type();
> +			switch (c) {
> +			case USB_CLOCK_TYPE_REF_48:
> +				new_f[0] = cpu_to_be32(48000000);
> +				fdt_setprop_inplace(initial_boot_params, usbn,
> +						    "refclk-frequency",  new_f, sizeof(new_f));
> +				/* Fall through ...*/
> +			case USB_CLOCK_TYPE_REF_12:
> +				/* Missing "refclk-type" defaults to external. */
> +				fdt_nop_property(initial_boot_params, usbn, "refclk-type");
> +				break;
> +			default:
> +				break;
> +			}
> +		}
> +	}
> +
>  	return 0;
>  }
>  
> diff --git a/arch/mips/cavium-octeon/octeon_3xxx.dts b/arch/mips/cavium-octeon/octeon_3xxx.dts
> index 88cb42d..fa33115 100644
> --- a/arch/mips/cavium-octeon/octeon_3xxx.dts
> +++ b/arch/mips/cavium-octeon/octeon_3xxx.dts
> @@ -550,6 +550,24 @@
>  				big-endian-regs;
>  			};
>  		};
> +
> +		usbn: usbn@1180068000000 {
> +			compatible = "cavium,octeon-5750-usbn";
> +			reg = <0x11800 0x68000000 0x0 0x1000>;
> +			ranges; /* Direct mapping */
> +			#address-cells = <2>;
> +			#size-cells = <2>;
> +			/* 12MHz, 24MHz and 48MHz allowed */
> +			refclk-frequency = <12000000>;
> +			/* Either "crystal" or "external" */
> +			refclk-type = "crystal";
> +
> +			usbc@16f0010000000 {
> +				compatible = "cavium,octeon-5750-usbc";
> +				reg = <0x16f00 0x10000000 0x0 0x80000>;
> +				interrupts = <0 56>;
> +			};
> +		};
>  	};
>  
>  	aliases {
> @@ -566,6 +584,7 @@
>  		flash0 = &flash0;
>  		cf0 = &cf0;
>  		uctl = &uctl;
> +		usbn = &usbn;
>  		led0 = &led0;
>  	};
>   };
> diff --git a/arch/mips/include/asm/octeon/cvmx-helper-board.h b/arch/mips/include/asm/octeon/cvmx-helper-board.h
> index 41785dd..8933203 100644
> --- a/arch/mips/include/asm/octeon/cvmx-helper-board.h
> +++ b/arch/mips/include/asm/octeon/cvmx-helper-board.h
> @@ -36,6 +36,13 @@
>  
>  #include <asm/octeon/cvmx-helper.h>
>  
> +enum cvmx_helper_board_usb_clock_types {
> +	USB_CLOCK_TYPE_REF_12,
> +	USB_CLOCK_TYPE_REF_24,
> +	USB_CLOCK_TYPE_REF_48,
> +	USB_CLOCK_TYPE_CRYSTAL_12,
> +};
> +
>  typedef enum {
>  	set_phy_link_flags_autoneg = 0x1,
>  	set_phy_link_flags_flow_control_dont_touch = 0x0 << 1,
> @@ -154,4 +161,6 @@ extern int __cvmx_helper_board_interface_probe(int interface,
>   */
>  extern int __cvmx_helper_board_hardware_enable(int interface);
>  
> +enum cvmx_helper_board_usb_clock_types __cvmx_helper_board_usb_get_clock_type(void);
> +
>  #endif /* __CVMX_HELPER_BOARD_H__ */
> -- 
> 1.7.11.7
> 
> 

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH 2/2] staging: octeon-usb: Probe via device tree populated platform device.
  2013-12-03 19:46 ` [PATCH 2/2] staging: octeon-usb: Probe via device tree populated platform device David Daney
@ 2013-12-04 21:40   ` Aaro Koskinen
  0 siblings, 0 replies; 8+ messages in thread
From: Aaro Koskinen @ 2013-12-04 21:40 UTC (permalink / raw)
  To: David Daney
  Cc: linux-mips, ralf, Greg Kroah-Hartman, linux-kernel, David Daney

Hi,

On Tue, Dec 03, 2013 at 11:46:52AM -0800, David Daney wrote:
> From: David Daney <david.daney@cavium.com>
> 
> Extract clocking parameters from the device tree, and remove now dead
> code and types.
> 
> Signed-off-by: David Daney <david.daney@cavium.com>

Tested-by: Aaro Koskinen <aaro.koskinen@iki.fi>

Thanks,

A.

> ---
>  drivers/staging/octeon-usb/octeon-hcd.c | 273 ++++++++++++++------------------
>  1 file changed, 116 insertions(+), 157 deletions(-)
> 
> diff --git a/drivers/staging/octeon-usb/octeon-hcd.c b/drivers/staging/octeon-usb/octeon-hcd.c
> index d118952..c53499a 100644
> --- a/drivers/staging/octeon-usb/octeon-hcd.c
> +++ b/drivers/staging/octeon-usb/octeon-hcd.c
> @@ -275,13 +275,6 @@ enum cvmx_usb_pipe_flags {
>   */
>  #define MAX_TRANSFER_PACKETS	((1<<10)-1)
>  
> -enum {
> -	USB_CLOCK_TYPE_REF_12,
> -	USB_CLOCK_TYPE_REF_24,
> -	USB_CLOCK_TYPE_REF_48,
> -	USB_CLOCK_TYPE_CRYSTAL_12,
> -};
> -
>  /**
>   * Logical transactions may take numerous low level
>   * transactions, especially when splits are concerned. This
> @@ -471,19 +464,6 @@ struct octeon_hcd {
>  /* Returns the IO address to push/pop stuff data from the FIFOs */
>  #define USB_FIFO_ADDRESS(channel, usb_index) (CVMX_USBCX_GOTGCTL(usb_index) + ((channel)+1)*0x1000)
>  
> -static int octeon_usb_get_clock_type(void)
> -{
> -	switch (cvmx_sysinfo_get()->board_type) {
> -	case CVMX_BOARD_TYPE_BBGW_REF:
> -	case CVMX_BOARD_TYPE_LANAI2_A:
> -	case CVMX_BOARD_TYPE_LANAI2_U:
> -	case CVMX_BOARD_TYPE_LANAI2_G:
> -	case CVMX_BOARD_TYPE_UBNT_E100:
> -		return USB_CLOCK_TYPE_CRYSTAL_12;
> -	}
> -	return USB_CLOCK_TYPE_REF_48;
> -}
> -
>  /**
>   * Read a USB 32bit CSR. It performs the necessary address swizzle
>   * for 32bit CSRs and logs the value in a readable format if
> @@ -582,37 +562,6 @@ static inline int __cvmx_usb_get_data_pid(struct cvmx_usb_pipe *pipe)
>  		return 0; /* Data0 */
>  }
>  
> -
> -/**
> - * Return the number of USB ports supported by this Octeon
> - * chip. If the chip doesn't support USB, or is not supported
> - * by this API, a zero will be returned. Most Octeon chips
> - * support one usb port, but some support two ports.
> - * cvmx_usb_initialize() must be called on independent
> - * struct cvmx_usb_state.
> - *
> - * Returns: Number of port, zero if usb isn't supported
> - */
> -static int cvmx_usb_get_num_ports(void)
> -{
> -	int arch_ports = 0;
> -
> -	if (OCTEON_IS_MODEL(OCTEON_CN56XX))
> -		arch_ports = 1;
> -	else if (OCTEON_IS_MODEL(OCTEON_CN52XX))
> -		arch_ports = 2;
> -	else if (OCTEON_IS_MODEL(OCTEON_CN50XX))
> -		arch_ports = 1;
> -	else if (OCTEON_IS_MODEL(OCTEON_CN31XX))
> -		arch_ports = 1;
> -	else if (OCTEON_IS_MODEL(OCTEON_CN30XX))
> -		arch_ports = 1;
> -	else
> -		arch_ports = 0;
> -
> -	return arch_ports;
> -}
> -
>  /**
>   * Initialize a USB port for use. This must be called before any
>   * other access to the Octeon USB port is made. The port starts
> @@ -628,41 +577,16 @@ static int cvmx_usb_get_num_ports(void)
>   * Returns: 0 or a negative error code.
>   */
>  static int cvmx_usb_initialize(struct cvmx_usb_state *usb,
> -			       int usb_port_number)
> +			       int usb_port_number,
> +			       enum cvmx_usb_initialize_flags flags)
>  {
>  	union cvmx_usbnx_clk_ctl usbn_clk_ctl;
>  	union cvmx_usbnx_usbp_ctl_status usbn_usbp_ctl_status;
> -	enum cvmx_usb_initialize_flags flags = 0;
>  	int i;
>  
>  	/* At first allow 0-1 for the usb port number */
>  	if ((usb_port_number < 0) || (usb_port_number > 1))
>  		return -EINVAL;
> -	/* For all chips except 52XX there is only one port */
> -	if (!OCTEON_IS_MODEL(OCTEON_CN52XX) && (usb_port_number > 0))
> -		return -EINVAL;
> -	/* Try to determine clock type automatically */
> -	if (octeon_usb_get_clock_type() == USB_CLOCK_TYPE_CRYSTAL_12) {
> -		/* Only 12 MHZ crystals are supported */
> -		flags |= CVMX_USB_INITIALIZE_FLAGS_CLOCK_XO_XI;
> -	} else {
> -		flags |= CVMX_USB_INITIALIZE_FLAGS_CLOCK_XO_GND;
> -
> -		switch (octeon_usb_get_clock_type()) {
> -		case USB_CLOCK_TYPE_REF_12:
> -			flags |= CVMX_USB_INITIALIZE_FLAGS_CLOCK_12MHZ;
> -			break;
> -		case USB_CLOCK_TYPE_REF_24:
> -			flags |= CVMX_USB_INITIALIZE_FLAGS_CLOCK_24MHZ;
> -			break;
> -		case USB_CLOCK_TYPE_REF_48:
> -			flags |= CVMX_USB_INITIALIZE_FLAGS_CLOCK_48MHZ;
> -			break;
> -		default:
> -			return -EINVAL;
> -			break;
> -		}
> -	}
>  
>  	memset(usb, 0, sizeof(*usb));
>  	usb->init_flags = flags;
> @@ -3431,7 +3355,6 @@ static int octeon_usb_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
>  	return 0;
>  }
>  
> -
>  static const struct hc_driver octeon_hc_driver = {
>  	.description		= "Octeon USB",
>  	.product_desc		= "Octeon Host Controller",
> @@ -3448,15 +3371,74 @@ static const struct hc_driver octeon_hc_driver = {
>  	.hub_control		= octeon_usb_hub_control,
>  };
>  
> -
> -static int octeon_usb_driver_probe(struct device *dev)
> +static int octeon_usb_probe(struct platform_device *pdev)
>  {
>  	int status;
> -	int usb_num = to_platform_device(dev)->id;
> -	int irq = platform_get_irq(to_platform_device(dev), 0);
> +	int initialize_flags;
> +	int usb_num;
> +	struct resource *res_mem;
> +	struct device_node *usbn_node;
> +	int irq = platform_get_irq(pdev, 0);
> +	struct device *dev = &pdev->dev;
>  	struct octeon_hcd *priv;
>  	struct usb_hcd *hcd;
>  	unsigned long flags;
> +	u32 clock_rate = 48000000;
> +	bool is_crystal_clock = false;
> +	const char *clock_type;
> +	int i;
> +
> +	if (dev->of_node == NULL) {
> +		dev_err(dev, "Error: empty of_node\n");
> +		return -ENXIO;
> +	}
> +	usbn_node = dev->of_node->parent;
> +
> +	i = of_property_read_u32(usbn_node,
> +				 "refclk-frequency", &clock_rate);
> +	if (i) {
> +		dev_err(dev, "No USBN \"refclk-frequency\"\n");
> +		return -ENXIO;
> +	}
> +	switch (clock_rate) {
> +	case 12000000:
> +		initialize_flags = CVMX_USB_INITIALIZE_FLAGS_CLOCK_12MHZ;
> +		break;
> +	case 24000000:
> +		initialize_flags = CVMX_USB_INITIALIZE_FLAGS_CLOCK_24MHZ;
> +		break;
> +	case 48000000:
> +		initialize_flags = CVMX_USB_INITIALIZE_FLAGS_CLOCK_48MHZ;
> +		break;
> +	default:
> +		dev_err(dev, "Illebal USBN \"refclk-frequency\" %u\n", clock_rate);
> +		return -ENXIO;
> +
> +	}
> +
> +	i = of_property_read_string(usbn_node,
> +				    "refclk-type", &clock_type);
> +
> +	if (!i && strcmp("crystal", clock_type) == 0)
> +		is_crystal_clock = true;
> +
> +	if (is_crystal_clock)
> +		initialize_flags |= CVMX_USB_INITIALIZE_FLAGS_CLOCK_XO_XI;
> +	else
> +		initialize_flags |= CVMX_USB_INITIALIZE_FLAGS_CLOCK_XO_GND;
> +
> +	res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +	if (res_mem == NULL) {
> +		dev_err(dev, "found no memory resource\n");
> +		return -ENXIO;
> +	}
> +	usb_num = (res_mem->start >> 44) & 1;
> +
> +	if (irq < 0) {
> +		/* Defective device tree, but we know how to fix it. */
> +		irq_hw_number_t hwirq = usb_num ? (1 << 6) + 17 : 56;
> +		irq = irq_create_mapping(NULL, hwirq);
> +	}
>  
>  	/*
>  	 * Set the DMA mask to 64bits so we get buffers already translated for
> @@ -3465,6 +3447,26 @@ static int octeon_usb_driver_probe(struct device *dev)
>  	dev->coherent_dma_mask = ~0;
>  	dev->dma_mask = &dev->coherent_dma_mask;
>  
> +	/*
> +	 * 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);
> +	}
> +
>  	hcd = usb_create_hcd(&octeon_hc_driver, dev, dev_name(dev));
>  	if (!hcd) {
>  		dev_dbg(dev, "Failed to allocate memory for HCD\n");
> @@ -3478,7 +3480,7 @@ static int octeon_usb_driver_probe(struct device *dev)
>  	tasklet_init(&priv->dequeue_tasklet, octeon_usb_urb_dequeue_work, (unsigned long)priv);
>  	INIT_LIST_HEAD(&priv->dequeue_list);
>  
> -	status = cvmx_usb_initialize(&priv->usb, usb_num);
> +	status = cvmx_usb_initialize(&priv->usb, usb_num, initialize_flags);
>  	if (status) {
>  		dev_dbg(dev, "USB initialization failed with %d\n", status);
>  		kfree(hcd);
> @@ -3492,21 +3494,22 @@ static int octeon_usb_driver_probe(struct device *dev)
>  	cvmx_usb_poll(&priv->usb);
>  	spin_unlock_irqrestore(&priv->lock, flags);
>  
> -	status = usb_add_hcd(hcd, irq, IRQF_SHARED);
> +	status = usb_add_hcd(hcd, irq, 0);
>  	if (status) {
>  		dev_dbg(dev, "USB add HCD failed with %d\n", status);
>  		kfree(hcd);
>  		return -1;
>  	}
>  
> -	dev_dbg(dev, "Registered HCD for port %d on irq %d\n", usb_num, irq);
> +	dev_info(dev, "Registered HCD for port %d on irq %d\n", usb_num, irq);
>  
>  	return 0;
>  }
>  
> -static int octeon_usb_driver_remove(struct device *dev)
> +static int octeon_usb_remove(struct platform_device *pdev)
>  {
>  	int status;
> +	struct device *dev = &pdev->dev;
>  	struct usb_hcd *hcd = dev_get_drvdata(dev);
>  	struct octeon_hcd *priv = hcd_to_octeon(hcd);
>  	unsigned long flags;
> @@ -3524,85 +3527,41 @@ static int octeon_usb_driver_remove(struct device *dev)
>  	return 0;
>  }
>  
> -static struct device_driver octeon_usb_driver = {
> -	.name	= "OcteonUSB",
> -	.bus	= &platform_bus_type,
> -	.probe	= octeon_usb_driver_probe,
> -	.remove	= octeon_usb_driver_remove,
> +static struct of_device_id octeon_usb_match[] = {
> +	{
> +		.compatible = "cavium,octeon-5750-usbc",
> +	},
> +	{},
>  };
>  
> +static struct platform_driver octeon_usb_driver = {
> +	.driver = {
> +		.name       = "OcteonUSB",
> +		.owner		= THIS_MODULE,
> +		.of_match_table = octeon_usb_match,
> +	},
> +	.probe      = octeon_usb_probe,
> +	.remove     = octeon_usb_remove,
> +};
>  
> -#define MAX_USB_PORTS   10
> -static struct platform_device *pdev_glob[MAX_USB_PORTS];
> -static int octeon_usb_registered;
> -static int __init octeon_usb_module_init(void)
> +static int __init octeon_usb_driver_init(void)
>  {
> -	int num_devices = cvmx_usb_get_num_ports();
> -	int device;
> -
> -	if (usb_disabled() || num_devices == 0)
> -		return -ENODEV;
> -
> -	if (driver_register(&octeon_usb_driver))
> -		return -ENOMEM;
> -
> -	octeon_usb_registered = 1;
> -
> -	/*
> -	 * 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);
> -	}
> -
> -	for (device = 0; device < num_devices; device++) {
> -		struct resource irq_resource;
> -		struct platform_device *pdev;
> -		memset(&irq_resource, 0, sizeof(irq_resource));
> -		irq_resource.start = (device == 0) ? OCTEON_IRQ_USB0 : OCTEON_IRQ_USB1;
> -		irq_resource.end = irq_resource.start;
> -		irq_resource.flags = IORESOURCE_IRQ;
> -		pdev = platform_device_register_simple((char *)octeon_usb_driver.  name, device, &irq_resource, 1);
> -		if (IS_ERR(pdev)) {
> -			driver_unregister(&octeon_usb_driver);
> -			octeon_usb_registered = 0;
> -			return PTR_ERR(pdev);
> -		}
> -		if (device < MAX_USB_PORTS)
> -			pdev_glob[device] = pdev;
> +	if (usb_disabled())
> +		return 0;
>  
> -	}
> -	return 0;
> +	return platform_driver_register(&octeon_usb_driver);
>  }
> +module_init(octeon_usb_driver_init);
>  
> -static void __exit octeon_usb_module_cleanup(void)
> +static void __exit octeon_usb_driver_exit(void)
>  {
> -	int i;
> +	if (usb_disabled())
> +		return;
>  
> -	for (i = 0; i < MAX_USB_PORTS; i++)
> -		if (pdev_glob[i]) {
> -			platform_device_unregister(pdev_glob[i]);
> -			pdev_glob[i] = NULL;
> -		}
> -	if (octeon_usb_registered)
> -		driver_unregister(&octeon_usb_driver);
> +	platform_driver_unregister(&octeon_usb_driver);
>  }
> +module_exit(octeon_usb_driver_exit);
>  
>  MODULE_LICENSE("GPL");
> -MODULE_AUTHOR("Cavium Networks <support@caviumnetworks.com>");
> -MODULE_DESCRIPTION("Cavium Networks Octeon USB Host driver.");
> -module_init(octeon_usb_module_init);
> -module_exit(octeon_usb_module_cleanup);
> +MODULE_AUTHOR("Cavium, Inc. <support@cavium.com>");
> +MODULE_DESCRIPTION("Cavium Inc. OCTEON USB Host driver.");
> -- 
> 1.7.11.7
> 
> 

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH 0/2] MIPS/staging: Probe octeon-usb driver via device-tree
  2013-12-03 19:46 [PATCH 0/2] MIPS/staging: Probe octeon-usb driver via device-tree David Daney
  2013-12-03 19:46 ` [PATCH 1/2] MIPS: OCTEON: Supply OCTEON+ USB nodes in internal device trees David Daney
  2013-12-03 19:46 ` [PATCH 2/2] staging: octeon-usb: Probe via device tree populated platform device David Daney
@ 2013-12-04 23:29 ` Greg Kroah-Hartman
  2014-02-03 18:35   ` Aaro Koskinen
  2 siblings, 1 reply; 8+ messages in thread
From: Greg Kroah-Hartman @ 2013-12-04 23:29 UTC (permalink / raw)
  To: David Daney; +Cc: linux-mips, ralf, Aaro Koskinen, linux-kernel, David Daney

On Tue, Dec 03, 2013 at 11:46:50AM -0800, David Daney wrote:
> From: David Daney <david.daney@cavium.com>
> 
> Tested against both EdgeRouter LITE (no bootloader supplied device
> tree), and ebb5610 (device tree supplied by bootloader).
> 
> The patch set is spread across both the MIPS and staging trees, so it
> would be great if Ralf could merge at least the MIPS parts, if not
> both parts.

That's fine with me:

Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH 0/2] MIPS/staging: Probe octeon-usb driver via device-tree
  2013-12-04 23:29 ` [PATCH 0/2] MIPS/staging: Probe octeon-usb driver via device-tree Greg Kroah-Hartman
@ 2014-02-03 18:35   ` Aaro Koskinen
  2014-02-03 20:08     ` Greg Kroah-Hartman
  0 siblings, 1 reply; 8+ messages in thread
From: Aaro Koskinen @ 2014-02-03 18:35 UTC (permalink / raw)
  To: Greg Kroah-Hartman, devel, David Daney
  Cc: linux-mips, ralf, linux-kernel, David Daney

Hi,

On Wed, Dec 04, 2013 at 03:29:53PM -0800, Greg Kroah-Hartman wrote:
> On Tue, Dec 03, 2013 at 11:46:50AM -0800, David Daney wrote:
> > From: David Daney <david.daney@cavium.com>
> > 
> > Tested against both EdgeRouter LITE (no bootloader supplied device
> > tree), and ebb5610 (device tree supplied by bootloader).
> > 
> > The patch set is spread across both the MIPS and staging trees, so it
> > would be great if Ralf could merge at least the MIPS parts, if not
> > both parts.
> 
> That's fine with me:
> 
> Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

It seems only the MIPS part was merged, and as a result the OCTEON
USB build is now broken in 3.14-rc1.

Would it be possible to merge the missing part through the staging
tree? The original is here: http://patchwork.linux-mips.org/patch/6186/
The below one is rebased for 3.14-rc1 and tested on EdgeRouter Lite.

A.

---8<---

>From 82be878d85647d4f60f4ae185e0e63f9644af28d Mon Sep 17 00:00:00 2001
From: David Daney <david.daney@cavium.com>
Date: Mon, 3 Feb 2014 19:39:01 +0200
Subject: [PATCH] staging: octeon-usb: Probe via device tree populated platform
 device.

Extract clocking parameters from the device tree, and remove now dead
code and types.

Signed-off-by: David Daney <david.daney@cavium.com>
Tested-by: Aaro Koskinen <aaro.koskinen@iki.fi>
Signed-off-by: Aaro Koskinen <aaro.koskinen@iki.fi>
---
 drivers/staging/octeon-usb/octeon-hcd.c | 273 ++++++++++++++------------------
 1 file changed, 116 insertions(+), 157 deletions(-)

diff --git a/drivers/staging/octeon-usb/octeon-hcd.c b/drivers/staging/octeon-usb/octeon-hcd.c
index 47e0a91238a1..5a001d9b4252 100644
--- a/drivers/staging/octeon-usb/octeon-hcd.c
+++ b/drivers/staging/octeon-usb/octeon-hcd.c
@@ -275,13 +275,6 @@ enum cvmx_usb_pipe_flags {
  */
 #define MAX_TRANSFER_PACKETS	((1<<10)-1)
 
-enum {
-	USB_CLOCK_TYPE_REF_12,
-	USB_CLOCK_TYPE_REF_24,
-	USB_CLOCK_TYPE_REF_48,
-	USB_CLOCK_TYPE_CRYSTAL_12,
-};
-
 /**
  * Logical transactions may take numerous low level
  * transactions, especially when splits are concerned. This
@@ -471,19 +464,6 @@ struct octeon_hcd {
 /* Returns the IO address to push/pop stuff data from the FIFOs */
 #define USB_FIFO_ADDRESS(channel, usb_index) (CVMX_USBCX_GOTGCTL(usb_index) + ((channel)+1)*0x1000)
 
-static int octeon_usb_get_clock_type(void)
-{
-	switch (cvmx_sysinfo_get()->board_type) {
-	case CVMX_BOARD_TYPE_BBGW_REF:
-	case CVMX_BOARD_TYPE_LANAI2_A:
-	case CVMX_BOARD_TYPE_LANAI2_U:
-	case CVMX_BOARD_TYPE_LANAI2_G:
-	case CVMX_BOARD_TYPE_UBNT_E100:
-		return USB_CLOCK_TYPE_CRYSTAL_12;
-	}
-	return USB_CLOCK_TYPE_REF_48;
-}
-
 /**
  * Read a USB 32bit CSR. It performs the necessary address swizzle
  * for 32bit CSRs and logs the value in a readable format if
@@ -582,37 +562,6 @@ static inline int __cvmx_usb_get_data_pid(struct cvmx_usb_pipe *pipe)
 		return 0; /* Data0 */
 }
 
-
-/**
- * Return the number of USB ports supported by this Octeon
- * chip. If the chip doesn't support USB, or is not supported
- * by this API, a zero will be returned. Most Octeon chips
- * support one usb port, but some support two ports.
- * cvmx_usb_initialize() must be called on independent
- * struct cvmx_usb_state.
- *
- * Returns: Number of port, zero if usb isn't supported
- */
-static int cvmx_usb_get_num_ports(void)
-{
-	int arch_ports = 0;
-
-	if (OCTEON_IS_MODEL(OCTEON_CN56XX))
-		arch_ports = 1;
-	else if (OCTEON_IS_MODEL(OCTEON_CN52XX))
-		arch_ports = 2;
-	else if (OCTEON_IS_MODEL(OCTEON_CN50XX))
-		arch_ports = 1;
-	else if (OCTEON_IS_MODEL(OCTEON_CN31XX))
-		arch_ports = 1;
-	else if (OCTEON_IS_MODEL(OCTEON_CN30XX))
-		arch_ports = 1;
-	else
-		arch_ports = 0;
-
-	return arch_ports;
-}
-
 /**
  * Initialize a USB port for use. This must be called before any
  * other access to the Octeon USB port is made. The port starts
@@ -628,41 +577,16 @@ static int cvmx_usb_get_num_ports(void)
  * Returns: 0 or a negative error code.
  */
 static int cvmx_usb_initialize(struct cvmx_usb_state *usb,
-			       int usb_port_number)
+			       int usb_port_number,
+			       enum cvmx_usb_initialize_flags flags)
 {
 	union cvmx_usbnx_clk_ctl usbn_clk_ctl;
 	union cvmx_usbnx_usbp_ctl_status usbn_usbp_ctl_status;
-	enum cvmx_usb_initialize_flags flags = 0;
 	int i;
 
 	/* At first allow 0-1 for the usb port number */
 	if ((usb_port_number < 0) || (usb_port_number > 1))
 		return -EINVAL;
-	/* For all chips except 52XX there is only one port */
-	if (!OCTEON_IS_MODEL(OCTEON_CN52XX) && (usb_port_number > 0))
-		return -EINVAL;
-	/* Try to determine clock type automatically */
-	if (octeon_usb_get_clock_type() == USB_CLOCK_TYPE_CRYSTAL_12) {
-		/* Only 12 MHZ crystals are supported */
-		flags |= CVMX_USB_INITIALIZE_FLAGS_CLOCK_XO_XI;
-	} else {
-		flags |= CVMX_USB_INITIALIZE_FLAGS_CLOCK_XO_GND;
-
-		switch (octeon_usb_get_clock_type()) {
-		case USB_CLOCK_TYPE_REF_12:
-			flags |= CVMX_USB_INITIALIZE_FLAGS_CLOCK_12MHZ;
-			break;
-		case USB_CLOCK_TYPE_REF_24:
-			flags |= CVMX_USB_INITIALIZE_FLAGS_CLOCK_24MHZ;
-			break;
-		case USB_CLOCK_TYPE_REF_48:
-			flags |= CVMX_USB_INITIALIZE_FLAGS_CLOCK_48MHZ;
-			break;
-		default:
-			return -EINVAL;
-			break;
-		}
-	}
 
 	memset(usb, 0, sizeof(*usb));
 	usb->init_flags = flags;
@@ -3431,7 +3355,6 @@ static int octeon_usb_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
 	return 0;
 }
 
-
 static const struct hc_driver octeon_hc_driver = {
 	.description		= "Octeon USB",
 	.product_desc		= "Octeon Host Controller",
@@ -3448,15 +3371,74 @@ static const struct hc_driver octeon_hc_driver = {
 	.hub_control		= octeon_usb_hub_control,
 };
 
-
-static int octeon_usb_driver_probe(struct device *dev)
+static int octeon_usb_probe(struct platform_device *pdev)
 {
 	int status;
-	int usb_num = to_platform_device(dev)->id;
-	int irq = platform_get_irq(to_platform_device(dev), 0);
+	int initialize_flags;
+	int usb_num;
+	struct resource *res_mem;
+	struct device_node *usbn_node;
+	int irq = platform_get_irq(pdev, 0);
+	struct device *dev = &pdev->dev;
 	struct octeon_hcd *priv;
 	struct usb_hcd *hcd;
 	unsigned long flags;
+	u32 clock_rate = 48000000;
+	bool is_crystal_clock = false;
+	const char *clock_type;
+	int i;
+
+	if (dev->of_node == NULL) {
+		dev_err(dev, "Error: empty of_node\n");
+		return -ENXIO;
+	}
+	usbn_node = dev->of_node->parent;
+
+	i = of_property_read_u32(usbn_node,
+				 "refclk-frequency", &clock_rate);
+	if (i) {
+		dev_err(dev, "No USBN \"refclk-frequency\"\n");
+		return -ENXIO;
+	}
+	switch (clock_rate) {
+	case 12000000:
+		initialize_flags = CVMX_USB_INITIALIZE_FLAGS_CLOCK_12MHZ;
+		break;
+	case 24000000:
+		initialize_flags = CVMX_USB_INITIALIZE_FLAGS_CLOCK_24MHZ;
+		break;
+	case 48000000:
+		initialize_flags = CVMX_USB_INITIALIZE_FLAGS_CLOCK_48MHZ;
+		break;
+	default:
+		dev_err(dev, "Illebal USBN \"refclk-frequency\" %u\n", clock_rate);
+		return -ENXIO;
+
+	}
+
+	i = of_property_read_string(usbn_node,
+				    "refclk-type", &clock_type);
+
+	if (!i && strcmp("crystal", clock_type) == 0)
+		is_crystal_clock = true;
+
+	if (is_crystal_clock)
+		initialize_flags |= CVMX_USB_INITIALIZE_FLAGS_CLOCK_XO_XI;
+	else
+		initialize_flags |= CVMX_USB_INITIALIZE_FLAGS_CLOCK_XO_GND;
+
+	res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (res_mem == NULL) {
+		dev_err(dev, "found no memory resource\n");
+		return -ENXIO;
+	}
+	usb_num = (res_mem->start >> 44) & 1;
+
+	if (irq < 0) {
+		/* Defective device tree, but we know how to fix it. */
+		irq_hw_number_t hwirq = usb_num ? (1 << 6) + 17 : 56;
+		irq = irq_create_mapping(NULL, hwirq);
+	}
 
 	/*
 	 * Set the DMA mask to 64bits so we get buffers already translated for
@@ -3465,6 +3447,26 @@ static int octeon_usb_driver_probe(struct device *dev)
 	dev->coherent_dma_mask = ~0;
 	dev->dma_mask = &dev->coherent_dma_mask;
 
+	/*
+	 * 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);
+	}
+
 	hcd = usb_create_hcd(&octeon_hc_driver, dev, dev_name(dev));
 	if (!hcd) {
 		dev_dbg(dev, "Failed to allocate memory for HCD\n");
@@ -3478,7 +3480,7 @@ static int octeon_usb_driver_probe(struct device *dev)
 	tasklet_init(&priv->dequeue_tasklet, octeon_usb_urb_dequeue_work, (unsigned long)priv);
 	INIT_LIST_HEAD(&priv->dequeue_list);
 
-	status = cvmx_usb_initialize(&priv->usb, usb_num);
+	status = cvmx_usb_initialize(&priv->usb, usb_num, initialize_flags);
 	if (status) {
 		dev_dbg(dev, "USB initialization failed with %d\n", status);
 		kfree(hcd);
@@ -3492,7 +3494,7 @@ static int octeon_usb_driver_probe(struct device *dev)
 	cvmx_usb_poll(&priv->usb);
 	spin_unlock_irqrestore(&priv->lock, flags);
 
-	status = usb_add_hcd(hcd, irq, IRQF_SHARED);
+	status = usb_add_hcd(hcd, irq, 0);
 	if (status) {
 		dev_dbg(dev, "USB add HCD failed with %d\n", status);
 		kfree(hcd);
@@ -3500,14 +3502,15 @@ static int octeon_usb_driver_probe(struct device *dev)
 	}
 	device_wakeup_enable(hcd->self.controller);
 
-	dev_dbg(dev, "Registered HCD for port %d on irq %d\n", usb_num, irq);
+	dev_info(dev, "Registered HCD for port %d on irq %d\n", usb_num, irq);
 
 	return 0;
 }
 
-static int octeon_usb_driver_remove(struct device *dev)
+static int octeon_usb_remove(struct platform_device *pdev)
 {
 	int status;
+	struct device *dev = &pdev->dev;
 	struct usb_hcd *hcd = dev_get_drvdata(dev);
 	struct octeon_hcd *priv = hcd_to_octeon(hcd);
 	unsigned long flags;
@@ -3525,85 +3528,41 @@ static int octeon_usb_driver_remove(struct device *dev)
 	return 0;
 }
 
-static struct device_driver octeon_usb_driver = {
-	.name	= "OcteonUSB",
-	.bus	= &platform_bus_type,
-	.probe	= octeon_usb_driver_probe,
-	.remove	= octeon_usb_driver_remove,
+static struct of_device_id octeon_usb_match[] = {
+	{
+		.compatible = "cavium,octeon-5750-usbc",
+	},
+	{},
 };
 
+static struct platform_driver octeon_usb_driver = {
+	.driver = {
+		.name       = "OcteonUSB",
+		.owner		= THIS_MODULE,
+		.of_match_table = octeon_usb_match,
+	},
+	.probe      = octeon_usb_probe,
+	.remove     = octeon_usb_remove,
+};
 
-#define MAX_USB_PORTS   10
-static struct platform_device *pdev_glob[MAX_USB_PORTS];
-static int octeon_usb_registered;
-static int __init octeon_usb_module_init(void)
+static int __init octeon_usb_driver_init(void)
 {
-	int num_devices = cvmx_usb_get_num_ports();
-	int device;
-
-	if (usb_disabled() || num_devices == 0)
-		return -ENODEV;
-
-	if (driver_register(&octeon_usb_driver))
-		return -ENOMEM;
-
-	octeon_usb_registered = 1;
-
-	/*
-	 * 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);
-	}
-
-	for (device = 0; device < num_devices; device++) {
-		struct resource irq_resource;
-		struct platform_device *pdev;
-		memset(&irq_resource, 0, sizeof(irq_resource));
-		irq_resource.start = (device == 0) ? OCTEON_IRQ_USB0 : OCTEON_IRQ_USB1;
-		irq_resource.end = irq_resource.start;
-		irq_resource.flags = IORESOURCE_IRQ;
-		pdev = platform_device_register_simple((char *)octeon_usb_driver.  name, device, &irq_resource, 1);
-		if (IS_ERR(pdev)) {
-			driver_unregister(&octeon_usb_driver);
-			octeon_usb_registered = 0;
-			return PTR_ERR(pdev);
-		}
-		if (device < MAX_USB_PORTS)
-			pdev_glob[device] = pdev;
+	if (usb_disabled())
+		return 0;
 
-	}
-	return 0;
+	return platform_driver_register(&octeon_usb_driver);
 }
+module_init(octeon_usb_driver_init);
 
-static void __exit octeon_usb_module_cleanup(void)
+static void __exit octeon_usb_driver_exit(void)
 {
-	int i;
+	if (usb_disabled())
+		return;
 
-	for (i = 0; i < MAX_USB_PORTS; i++)
-		if (pdev_glob[i]) {
-			platform_device_unregister(pdev_glob[i]);
-			pdev_glob[i] = NULL;
-		}
-	if (octeon_usb_registered)
-		driver_unregister(&octeon_usb_driver);
+	platform_driver_unregister(&octeon_usb_driver);
 }
+module_exit(octeon_usb_driver_exit);
 
 MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Cavium Networks <support@caviumnetworks.com>");
-MODULE_DESCRIPTION("Cavium Networks Octeon USB Host driver.");
-module_init(octeon_usb_module_init);
-module_exit(octeon_usb_module_cleanup);
+MODULE_AUTHOR("Cavium, Inc. <support@cavium.com>");
+MODULE_DESCRIPTION("Cavium Inc. OCTEON USB Host driver.");
-- 
1.8.3.3


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH 0/2] MIPS/staging: Probe octeon-usb driver via device-tree
  2014-02-03 18:35   ` Aaro Koskinen
@ 2014-02-03 20:08     ` Greg Kroah-Hartman
  0 siblings, 0 replies; 8+ messages in thread
From: Greg Kroah-Hartman @ 2014-02-03 20:08 UTC (permalink / raw)
  To: Aaro Koskinen
  Cc: devel, David Daney, linux-mips, linux-kernel, ralf, David Daney

On Mon, Feb 03, 2014 at 08:35:06PM +0200, Aaro Koskinen wrote:
> Hi,
> 
> On Wed, Dec 04, 2013 at 03:29:53PM -0800, Greg Kroah-Hartman wrote:
> > On Tue, Dec 03, 2013 at 11:46:50AM -0800, David Daney wrote:
> > > From: David Daney <david.daney@cavium.com>
> > > 
> > > Tested against both EdgeRouter LITE (no bootloader supplied device
> > > tree), and ebb5610 (device tree supplied by bootloader).
> > > 
> > > The patch set is spread across both the MIPS and staging trees, so it
> > > would be great if Ralf could merge at least the MIPS parts, if not
> > > both parts.
> > 
> > That's fine with me:
> > 
> > Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> 
> It seems only the MIPS part was merged, and as a result the OCTEON
> USB build is now broken in 3.14-rc1.
> 
> Would it be possible to merge the missing part through the staging
> tree? The original is here: http://patchwork.linux-mips.org/patch/6186/
> The below one is rebased for 3.14-rc1 and tested on EdgeRouter Lite.

Sure, I can queue it up for 3.14, and will do so in a few days.

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2014-02-03 20:07 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-12-03 19:46 [PATCH 0/2] MIPS/staging: Probe octeon-usb driver via device-tree David Daney
2013-12-03 19:46 ` [PATCH 1/2] MIPS: OCTEON: Supply OCTEON+ USB nodes in internal device trees David Daney
2013-12-04 21:39   ` Aaro Koskinen
2013-12-03 19:46 ` [PATCH 2/2] staging: octeon-usb: Probe via device tree populated platform device David Daney
2013-12-04 21:40   ` Aaro Koskinen
2013-12-04 23:29 ` [PATCH 0/2] MIPS/staging: Probe octeon-usb driver via device-tree Greg Kroah-Hartman
2014-02-03 18:35   ` Aaro Koskinen
2014-02-03 20:08     ` Greg Kroah-Hartman

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).