[PATCH 1/2 resend] USB: host: Remove hard-coded octeon platform information for ehci/ohci

2014-12-15 Thread Andreas Herrmann
Instead rely on device tree information for ehci and ohci.

This was suggested with
http://www.linux-mips.org/archives/linux-mips/2014-05/msg00307.html

  "The device tree will *always* have correct ehci/ohci clock
  configuration, so use it.  This allows us to remove a big chunk of
  platform configuration code from octeon-platform.c."

More or less I rebased that patch on Alan's work to remove ehci-octeon
and ohci-octeon drivers.

Cc: David Daney 
Cc: Alex Smith 
Cc: Alan Stern 
Signed-off-by: Andreas Herrmann 
Acked-by: Ralf Baechle 
Tested-by: Aaro Koskinen 
---
 arch/mips/cavium-octeon/octeon-platform.c |  148 -
 drivers/usb/host/ehci-platform.c  |1 +
 drivers/usb/host/ohci-platform.c  |1 +
 3 files changed, 64 insertions(+), 86 deletions(-)

diff --git a/arch/mips/cavium-octeon/octeon-platform.c 
b/arch/mips/cavium-octeon/octeon-platform.c
index b67ddf0..eea60b6 100644
--- a/arch/mips/cavium-octeon/octeon-platform.c
+++ b/arch/mips/cavium-octeon/octeon-platform.c
@@ -77,7 +77,7 @@ static DEFINE_MUTEX(octeon2_usb_clocks_mutex);
 
 static int octeon2_usb_clock_start_cnt;
 
-static void octeon2_usb_clocks_start(void)
+static void octeon2_usb_clocks_start(struct device *dev)
 {
u64 div;
union cvmx_uctlx_if_ena if_ena;
@@ -86,6 +86,8 @@ static void octeon2_usb_clocks_start(void)
union cvmx_uctlx_uphy_portx_ctl_status port_ctl_status;
int i;
unsigned long io_clk_64_to_ns;
+   u32 clock_rate = 1200;
+   bool is_crystal_clock = false;
 
 
mutex_lock(&octeon2_usb_clocks_mutex);
@@ -96,6 +98,28 @@ static void octeon2_usb_clocks_start(void)
 
io_clk_64_to_ns = 640ull / octeon_get_io_clock_rate();
 
+   if (dev->of_node) {
+   struct device_node *uctl_node;
+   const char *clock_type;
+
+   uctl_node = of_get_parent(dev->of_node);
+   if (!uctl_node) {
+   dev_err(dev, "No UCTL device node\n");
+   goto exit;
+   }
+   i = of_property_read_u32(uctl_node,
+"refclk-frequency", &clock_rate);
+   if (i) {
+   dev_err(dev, "No UCTL \"refclk-frequency\"\n");
+   goto exit;
+   }
+   i = of_property_read_string(uctl_node,
+   "refclk-type", &clock_type);
+
+   if (!i && strcmp("crystal", clock_type) == 0)
+   is_crystal_clock = true;
+   }
+
/*
 * Step 1: Wait for voltages stable.  That surely happened
 * before starting the kernel.
@@ -126,9 +150,22 @@ static void octeon2_usb_clocks_start(void)
cvmx_write_csr(CVMX_UCTLX_CLK_RST_CTL(0), clk_rst_ctl.u64);
 
/* 3b */
-   /* 12MHz crystal. */
-   clk_rst_ctl.s.p_refclk_sel = 0;
-   clk_rst_ctl.s.p_refclk_div = 0;
+   clk_rst_ctl.s.p_refclk_sel = is_crystal_clock ? 0 : 1;
+   switch (clock_rate) {
+   default:
+   pr_err("Invalid UCTL clock rate of %u, using 1200 
instead\n",
+   clock_rate);
+   /* Fall through */
+   case 1200:
+   clk_rst_ctl.s.p_refclk_div = 0;
+   break;
+   case 2400:
+   clk_rst_ctl.s.p_refclk_div = 1;
+   break;
+   case 4800:
+   clk_rst_ctl.s.p_refclk_div = 2;
+   break;
+   }
cvmx_write_csr(CVMX_UCTLX_CLK_RST_CTL(0), clk_rst_ctl.u64);
 
/* 3c */
@@ -259,7 +296,7 @@ static void octeon2_usb_clocks_stop(void)
 
 static int octeon_ehci_power_on(struct platform_device *pdev)
 {
-   octeon2_usb_clocks_start();
+   octeon2_usb_clocks_start(&pdev->dev);
return 0;
 }
 
@@ -277,11 +314,11 @@ static struct usb_ehci_pdata octeon_ehci_pdata = {
.power_off  = octeon_ehci_power_off,
 };
 
-static void __init octeon_ehci_hw_start(void)
+static void __init octeon_ehci_hw_start(struct device *dev)
 {
union cvmx_uctlx_ehci_ctl ehci_ctl;
 
-   octeon2_usb_clocks_start();
+   octeon2_usb_clocks_start(dev);
 
ehci_ctl.u64 = cvmx_read_csr(CVMX_UCTLX_EHCI_CTL(0));
/* Use 64-bit addressing. */
@@ -299,59 +336,28 @@ static u64 octeon_ehci_dma_mask = DMA_BIT_MASK(64);
 static int __init octeon_ehci_device_init(void)
 {
struct platform_device *pd;
+   struct device_node *ehci_node;
int ret = 0;
 
-   struct resource usb_resources[] = {
-   {
-   .flags  = IORESOURCE_MEM,
-   }, {
-   .flags  = IORESOURCE_IRQ,
-   }
-   };
-
-   /* Only Octeon2 has ehci/ohci */
-   if (!OCTEON_IS_MODEL(OCTEON_CN63XX))
+   ehci_node = of_find_node_by_name(NULL, "ehci");
+   if (!ehci_node)
return 0;
 
-   if (octeon_is_simulation() || usb_disab

Re: [PATCH 1/2 resend] USB: host: Remove hard-coded octeon platform information for ehci/ohci

2014-12-15 Thread Ralf Baechle
On Mon, Dec 15, 2014 at 02:28:41PM +0100, Andreas Herrmann wrote:

> Instead rely on device tree information for ehci and ohci.
> 
> This was suggested with
> http://www.linux-mips.org/archives/linux-mips/2014-05/msg00307.html

Please use the permanent link from that page:

  
http://www.linux-mips.org/cgi-bin/mesg.cgi?a=linux-mips&i=1401358203-60225-4-git-send-email-alex.smith%40imgtec.com

The non-permanent links might change.

  Ralf
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html