summaryrefslogtreecommitdiff
path: root/target/linux/brcm63xx/patches-3.8/105-MIPS-BCM63XX-add-support-for-the-on-chip-OHCI-contro.patch
blob: 732fe94cfd893fd1fc6c7197e89682dd0f03be54 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
From 30d22baef255c99a12c4858ce4ab0d45f0d8c9ae Mon Sep 17 00:00:00 2001
From: Florian Fainelli <florian@openwrt.org>
Date: Mon, 28 Jan 2013 20:06:24 +0100
Subject: [PATCH 06/11] MIPS: BCM63XX: add support for the on-chip OHCI
 controller

Broadcom BCM63XX SoCs include an on-chip OHCI controller which can be
driven by the ohci-platform generic driver by using specific power
on/off/suspend callback to manage clocks and hardware specific
configuration.

Signed-off-by: Maxime Bizon <mbizon@freebox.fr>
Signed-off-by: Florian Fainelli <florian@openwrt.org>
---
 arch/mips/bcm63xx/Makefile                         |    2 +-
 arch/mips/bcm63xx/dev-usb-ohci.c                   |   94 ++++++++++++++++++++
 .../asm/mach-bcm63xx/bcm63xx_dev_usb_ohci.h        |    6 ++
 3 files changed, 101 insertions(+), 1 deletion(-)
 create mode 100644 arch/mips/bcm63xx/dev-usb-ohci.c
 create mode 100644 arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_usb_ohci.h

--- a/arch/mips/bcm63xx/Makefile
+++ b/arch/mips/bcm63xx/Makefile
@@ -1,7 +1,7 @@
 obj-y		+= clk.o cpu.o cs.o gpio.o irq.o nvram.o prom.o reset.o \
 		   setup.o timer.o dev-dsp.o dev-enet.o dev-flash.o \
 		   dev-pcmcia.o dev-rng.o dev-spi.o dev-uart.o dev-wdt.o \
-		   dev-usb-usbd.o usb-common.o
+		   dev-usb-ohci.o dev-usb-usbd.o usb-common.o
 obj-$(CONFIG_EARLY_PRINTK)	+= early_printk.o
 
 obj-y		+= boards/
--- /dev/null
+++ b/arch/mips/bcm63xx/dev-usb-ohci.c
@@ -0,0 +1,94 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr>
+ * Copyright (C) 2013 Florian Fainelli <florian@openwrt.org>
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/usb/ohci_pdriver.h>
+#include <linux/dma-mapping.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+
+#include <bcm63xx_cpu.h>
+#include <bcm63xx_regs.h>
+#include <bcm63xx_io.h>
+#include <bcm63xx_usb_priv.h>
+#include <bcm63xx_dev_usb_ohci.h>
+
+static struct resource ohci_resources[] = {
+	{
+		.start		= -1, /* filled at runtime */
+		.end		= -1, /* filled at runtime */
+		.flags		= IORESOURCE_MEM,
+	},
+	{
+		.start		= -1, /* filled at runtime */
+		.flags		= IORESOURCE_IRQ,
+	},
+};
+
+static u64 ohci_dmamask = DMA_BIT_MASK(32);
+
+static struct clk *usb_host_clock;
+
+static int bcm63xx_ohci_power_on(struct platform_device *pdev)
+{
+	usb_host_clock = clk_get(&pdev->dev, "usbh");
+	if (IS_ERR_OR_NULL(usb_host_clock))
+		return -ENODEV;
+
+	clk_prepare_enable(usb_host_clock);
+
+	bcm63xx_usb_priv_ohci_cfg_set();
+
+	return 0;
+}
+
+static void bcm63xx_ohci_power_off(struct platform_device *pdev)
+{
+	if (!IS_ERR_OR_NULL(usb_host_clock)) {
+		clk_disable_unprepare(usb_host_clock);
+		clk_put(usb_host_clock);
+	}
+}
+
+static struct usb_ohci_pdata bcm63xx_ohci_pdata = {
+	.big_endian_desc	= 1,
+	.big_endian_mmio	= 1,
+	.no_big_frame_no	= 1,
+	.num_ports		= 1,
+	.power_on		= bcm63xx_ohci_power_on,
+	.power_off		= bcm63xx_ohci_power_off,
+	.power_suspend		= bcm63xx_ohci_power_off,
+};
+
+static struct platform_device bcm63xx_ohci_device = {
+	.name		= "ohci-platform",
+	.id		= -1,
+	.num_resources	= ARRAY_SIZE(ohci_resources),
+	.resource	= ohci_resources,
+	.dev		= {
+		.platform_data		= &bcm63xx_ohci_pdata,
+		.dma_mask		= &ohci_dmamask,
+		.coherent_dma_mask	= DMA_BIT_MASK(32),
+	},
+};
+
+int __init bcm63xx_ohci_register(void)
+{
+	if (BCMCPU_IS_6345() || BCMCPU_IS_6338())
+		return -ENODEV;
+
+	ohci_resources[0].start = bcm63xx_regset_address(RSET_OHCI0);
+	ohci_resources[0].end = ohci_resources[0].start;
+	ohci_resources[0].end += RSET_OHCI_SIZE - 1;
+	ohci_resources[1].start = bcm63xx_get_irq_number(IRQ_OHCI0);
+
+	return platform_device_register(&bcm63xx_ohci_device);
+}
--- /dev/null
+++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_usb_ohci.h
@@ -0,0 +1,6 @@
+#ifndef BCM63XX_DEV_USB_OHCI_H_
+#define BCM63XX_DEV_USB_OHCI_H_
+
+int bcm63xx_ohci_register(void);
+
+#endif /* BCM63XX_DEV_USB_OHCI_H_ */