summaryrefslogtreecommitdiffstats
path: root/arch/mips/pnx8550/common/platform.c
blob: 0a8faeaa7b70e4c3c9e893dde55e377c31e85f9a (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
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
/*
 * Platform device support for NXP PNX8550 SoCs
 *
 * Copyright 2005, Embedded Alley Solutions, Inc
 *
 * Based on arch/mips/au1000/common/platform.c
 * Platform device support for Au1x00 SoCs.
 *
 * Copyright 2004, Matt Porter <mporter@kernel.crashing.org>
 *
 * This file is licensed under the terms of the GNU General Public
 * License version 2.  This program is licensed "as is" without any
 * warranty of any kind, whether express or implied.
 */
#include <linux/device.h>
#include <linux/dma-mapping.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/resource.h>
#include <linux/serial.h>
#include <linux/serial_pnx8xxx.h>
#include <linux/platform_device.h>
#include <linux/usb/ohci_pdriver.h>

#include <int.h>
#include <usb.h>
#include <uart.h>

static struct resource pnx8550_usb_ohci_resources[] = {
	[0] = {
		.start		= PNX8550_USB_OHCI_OP_BASE,
		.end		= PNX8550_USB_OHCI_OP_BASE +
				  PNX8550_USB_OHCI_OP_LEN,
		.flags		= IORESOURCE_MEM,
	},
	[1] = {
		.start		= PNX8550_INT_USB,
		.end		= PNX8550_INT_USB,
		.flags		= IORESOURCE_IRQ,
	},
};

static struct resource pnx8550_uart_resources[] = {
	[0] = {
		.start		= PNX8550_UART_PORT0,
		.end		= PNX8550_UART_PORT0 + 0xfff,
		.flags		= IORESOURCE_MEM,
	},
	[1] = {
		.start		= PNX8550_UART_INT(0),
		.end		= PNX8550_UART_INT(0),
		.flags		= IORESOURCE_IRQ,
	},
	[2] = {
		.start		= PNX8550_UART_PORT1,
		.end		= PNX8550_UART_PORT1 + 0xfff,
		.flags		= IORESOURCE_MEM,
	},
	[3] = {
		.start		= PNX8550_UART_INT(1),
		.end		= PNX8550_UART_INT(1),
		.flags		= IORESOURCE_IRQ,
	},
};

struct pnx8xxx_port pnx8xxx_ports[] = {
	[0] = {
		.port   = {
			.type		= PORT_PNX8XXX,
			.iotype		= UPIO_MEM,
			.membase	= (void __iomem *)PNX8550_UART_PORT0,
			.mapbase	= PNX8550_UART_PORT0,
			.irq		= PNX8550_UART_INT(0),
			.uartclk	= 3692300,
			.fifosize	= 16,
			.flags		= UPF_BOOT_AUTOCONF,
			.line		= 0,
		},
	},
	[1] = {
		.port   = {
			.type		= PORT_PNX8XXX,
			.iotype		= UPIO_MEM,
			.membase	= (void __iomem *)PNX8550_UART_PORT1,
			.mapbase	= PNX8550_UART_PORT1,
			.irq		= PNX8550_UART_INT(1),
			.uartclk	= 3692300,
			.fifosize	= 16,
			.flags		= UPF_BOOT_AUTOCONF,
			.line		= 1,
		},
	},
};

/* The dmamask must be set for OHCI to work */
static u64 ohci_dmamask = DMA_BIT_MASK(32);

static u64 uart_dmamask = DMA_BIT_MASK(32);

static int pnx8550_usb_ohci_power_on(struct platform_device *pdev)
{
	/*
	 * Set register CLK48CTL to enable and 48MHz
	 */
	outl(0x00000003, PCI_BASE | 0x0004770c);

	/*
	 * Set register CLK12CTL to enable and 48MHz
	 */
	outl(0x00000003, PCI_BASE | 0x00047710);

	udelay(100);

	return 0;
}

static void pnx8550_usb_ohci_power_off(struct platform_device *pdev)
{
	udelay(10);
}

static struct usb_ohci_pdata pnx8550_usb_ohci_pdata = {
	.power_on	= pnx8550_usb_ohci_power_on,
	.power_off	= pnx8550_usb_ohci_power_off,
};

static struct platform_device pnx8550_usb_ohci_device = {
	.name		= "ohci-platform",
	.id		= -1,
	.dev = {
		.dma_mask		= &ohci_dmamask,
		.coherent_dma_mask	= DMA_BIT_MASK(32),
		.platform_data		= &pnx8550_usb_ohci_pdata,
	},
	.num_resources	= ARRAY_SIZE(pnx8550_usb_ohci_resources),
	.resource	= pnx8550_usb_ohci_resources,
};

static struct platform_device pnx8550_uart_device = {
	.name		= "pnx8xxx-uart",
	.id		= -1,
	.dev = {
		.dma_mask		= &uart_dmamask,
		.coherent_dma_mask	= DMA_BIT_MASK(32),
		.platform_data = pnx8xxx_ports,
	},
	.num_resources	= ARRAY_SIZE(pnx8550_uart_resources),
	.resource	= pnx8550_uart_resources,
};

static struct platform_device *pnx8550_platform_devices[] __initdata = {
	&pnx8550_usb_ohci_device,
	&pnx8550_uart_device,
};

static int __init pnx8550_platform_init(void)
{
	return platform_add_devices(pnx8550_platform_devices,
			            ARRAY_SIZE(pnx8550_platform_devices));
}

arch_initcall(pnx8550_platform_init);