isp1760-if.c revision 61c7a080a5a061c976988fd4b844dfb468dda255
1/*
2 * Glue code for the ISP1760 driver and bus
3 * Currently there is support for
4 * - OpenFirmware
5 * - PCI
6 * - PDEV (generic platform device centralized driver model)
7 *
8 * (c) 2007 Sebastian Siewior <bigeasy@linutronix.de>
9 *
10 */
11
12#include <linux/usb.h>
13#include <linux/io.h>
14#include <linux/platform_device.h>
15#include <linux/usb/isp1760.h>
16
17#include "../core/hcd.h"
18#include "isp1760-hcd.h"
19
20#ifdef CONFIG_PPC_OF
21#include <linux/of.h>
22#include <linux/of_platform.h>
23#endif
24
25#ifdef CONFIG_PCI
26#include <linux/pci.h>
27#endif
28
29#ifdef CONFIG_PPC_OF
30static int of_isp1760_probe(struct of_device *dev,
31		const struct of_device_id *match)
32{
33	struct usb_hcd *hcd;
34	struct device_node *dp = dev->dev.of_node;
35	struct resource *res;
36	struct resource memory;
37	struct of_irq oirq;
38	int virq;
39	u64 res_len;
40	int ret;
41	const unsigned int *prop;
42	unsigned int devflags = 0;
43
44	ret = of_address_to_resource(dp, 0, &memory);
45	if (ret)
46		return -ENXIO;
47
48	res = request_mem_region(memory.start, memory.end - memory.start + 1,
49			dev_name(&dev->dev));
50	if (!res)
51		return -EBUSY;
52
53	res_len = memory.end - memory.start + 1;
54
55	if (of_irq_map_one(dp, 0, &oirq)) {
56		ret = -ENODEV;
57		goto release_reg;
58	}
59
60	virq = irq_create_of_mapping(oirq.controller, oirq.specifier,
61			oirq.size);
62
63	if (of_device_is_compatible(dp, "nxp,usb-isp1761"))
64		devflags |= ISP1760_FLAG_ISP1761;
65
66	/* Some systems wire up only 16 of the 32 data lines */
67	prop = of_get_property(dp, "bus-width", NULL);
68	if (prop && *prop == 16)
69		devflags |= ISP1760_FLAG_BUS_WIDTH_16;
70
71	if (of_get_property(dp, "port1-otg", NULL) != NULL)
72		devflags |= ISP1760_FLAG_OTG_EN;
73
74	if (of_get_property(dp, "analog-oc", NULL) != NULL)
75		devflags |= ISP1760_FLAG_ANALOG_OC;
76
77	if (of_get_property(dp, "dack-polarity", NULL) != NULL)
78		devflags |= ISP1760_FLAG_DACK_POL_HIGH;
79
80	if (of_get_property(dp, "dreq-polarity", NULL) != NULL)
81		devflags |= ISP1760_FLAG_DREQ_POL_HIGH;
82
83	hcd = isp1760_register(memory.start, res_len, virq,
84		IRQF_SHARED | IRQF_DISABLED, &dev->dev, dev_name(&dev->dev),
85		devflags);
86	if (IS_ERR(hcd)) {
87		ret = PTR_ERR(hcd);
88		goto release_reg;
89	}
90
91	dev_set_drvdata(&dev->dev, hcd);
92	return ret;
93
94release_reg:
95	release_mem_region(memory.start, memory.end - memory.start + 1);
96	return ret;
97}
98
99static int of_isp1760_remove(struct of_device *dev)
100{
101	struct usb_hcd *hcd = dev_get_drvdata(&dev->dev);
102
103	dev_set_drvdata(&dev->dev, NULL);
104
105	usb_remove_hcd(hcd);
106	iounmap(hcd->regs);
107	release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
108	usb_put_hcd(hcd);
109	return 0;
110}
111
112static const struct of_device_id of_isp1760_match[] = {
113	{
114		.compatible = "nxp,usb-isp1760",
115	},
116	{
117		.compatible = "nxp,usb-isp1761",
118	},
119	{ },
120};
121MODULE_DEVICE_TABLE(of, of_isp1760_match);
122
123static struct of_platform_driver isp1760_of_driver = {
124	.name           = "nxp-isp1760",
125	.match_table    = of_isp1760_match,
126	.probe          = of_isp1760_probe,
127	.remove         = of_isp1760_remove,
128};
129#endif
130
131#ifdef CONFIG_PCI
132static int __devinit isp1761_pci_probe(struct pci_dev *dev,
133		const struct pci_device_id *id)
134{
135	u8 latency, limit;
136	__u32 reg_data;
137	int retry_count;
138	struct usb_hcd *hcd;
139	unsigned int devflags = 0;
140	int ret_status = 0;
141
142	resource_size_t pci_mem_phy0;
143	resource_size_t memlength;
144
145	u8 __iomem *chip_addr;
146	u8 __iomem *iobase;
147	resource_size_t nxp_pci_io_base;
148	resource_size_t iolength;
149
150	if (usb_disabled())
151		return -ENODEV;
152
153	if (pci_enable_device(dev) < 0)
154		return -ENODEV;
155
156	if (!dev->irq)
157		return -ENODEV;
158
159	/* Grab the PLX PCI mem maped port start address we need  */
160	nxp_pci_io_base = pci_resource_start(dev, 0);
161	iolength = pci_resource_len(dev, 0);
162
163	if (!request_mem_region(nxp_pci_io_base, iolength, "ISP1761 IO MEM")) {
164		printk(KERN_ERR "request region #1\n");
165		return -EBUSY;
166	}
167
168	iobase = ioremap_nocache(nxp_pci_io_base, iolength);
169	if (!iobase) {
170		printk(KERN_ERR "ioremap #1\n");
171		ret_status = -ENOMEM;
172		goto cleanup1;
173	}
174	/* Grab the PLX PCI shared memory of the ISP 1761 we need  */
175	pci_mem_phy0 = pci_resource_start(dev, 3);
176	memlength = pci_resource_len(dev, 3);
177	if (memlength < 0xffff) {
178		printk(KERN_ERR "memory length for this resource is wrong\n");
179		ret_status = -ENOMEM;
180		goto cleanup2;
181	}
182
183	if (!request_mem_region(pci_mem_phy0, memlength, "ISP-PCI")) {
184		printk(KERN_ERR "host controller already in use\n");
185		ret_status = -EBUSY;
186		goto cleanup2;
187	}
188
189	/* map available memory */
190	chip_addr = ioremap_nocache(pci_mem_phy0,memlength);
191	if (!chip_addr) {
192		printk(KERN_ERR "Error ioremap failed\n");
193		ret_status = -ENOMEM;
194		goto cleanup3;
195	}
196
197	/* bad pci latencies can contribute to overruns */
198	pci_read_config_byte(dev, PCI_LATENCY_TIMER, &latency);
199	if (latency) {
200		pci_read_config_byte(dev, PCI_MAX_LAT, &limit);
201		if (limit && limit < latency)
202			pci_write_config_byte(dev, PCI_LATENCY_TIMER, limit);
203	}
204
205	/* Try to check whether we can access Scratch Register of
206	 * Host Controller or not. The initial PCI access is retried until
207	 * local init for the PCI bridge is completed
208	 */
209	retry_count = 20;
210	reg_data = 0;
211	while ((reg_data != 0xFACE) && retry_count) {
212		/*by default host is in 16bit mode, so
213		 * io operations at this stage must be 16 bit
214		 * */
215		writel(0xface, chip_addr + HC_SCRATCH_REG);
216		udelay(100);
217		reg_data = readl(chip_addr + HC_SCRATCH_REG) & 0x0000ffff;
218		retry_count--;
219	}
220
221	iounmap(chip_addr);
222
223	/* Host Controller presence is detected by writing to scratch register
224	 * and reading back and checking the contents are same or not
225	 */
226	if (reg_data != 0xFACE) {
227		dev_err(&dev->dev, "scratch register mismatch %x\n", reg_data);
228		ret_status = -ENOMEM;
229		goto cleanup3;
230	}
231
232	pci_set_master(dev);
233
234	/* configure PLX PCI chip to pass interrupts */
235#define PLX_INT_CSR_REG 0x68
236	reg_data = readl(iobase + PLX_INT_CSR_REG);
237	reg_data |= 0x900;
238	writel(reg_data, iobase + PLX_INT_CSR_REG);
239
240	dev->dev.dma_mask = NULL;
241	hcd = isp1760_register(pci_mem_phy0, memlength, dev->irq,
242		IRQF_SHARED | IRQF_DISABLED, &dev->dev, dev_name(&dev->dev),
243		devflags);
244	if (IS_ERR(hcd)) {
245		ret_status = -ENODEV;
246		goto cleanup3;
247	}
248
249	/* done with PLX IO access */
250	iounmap(iobase);
251	release_mem_region(nxp_pci_io_base, iolength);
252
253	pci_set_drvdata(dev, hcd);
254	return 0;
255
256cleanup3:
257	release_mem_region(pci_mem_phy0, memlength);
258cleanup2:
259	iounmap(iobase);
260cleanup1:
261	release_mem_region(nxp_pci_io_base, iolength);
262	return ret_status;
263}
264
265static void isp1761_pci_remove(struct pci_dev *dev)
266{
267	struct usb_hcd *hcd;
268
269	hcd = pci_get_drvdata(dev);
270
271	usb_remove_hcd(hcd);
272	iounmap(hcd->regs);
273	release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
274	usb_put_hcd(hcd);
275
276	pci_disable_device(dev);
277}
278
279static void isp1761_pci_shutdown(struct pci_dev *dev)
280{
281	printk(KERN_ERR "ips1761_pci_shutdown\n");
282}
283
284static const struct pci_device_id isp1760_plx [] = {
285	{
286		.class          = PCI_CLASS_BRIDGE_OTHER << 8,
287		.class_mask     = ~0,
288		.vendor		= PCI_VENDOR_ID_PLX,
289		.device		= 0x5406,
290		.subvendor	= PCI_VENDOR_ID_PLX,
291		.subdevice	= 0x9054,
292	},
293	{ }
294};
295MODULE_DEVICE_TABLE(pci, isp1760_plx);
296
297static struct pci_driver isp1761_pci_driver = {
298	.name =         "isp1760",
299	.id_table =     isp1760_plx,
300	.probe =        isp1761_pci_probe,
301	.remove =       isp1761_pci_remove,
302	.shutdown =     isp1761_pci_shutdown,
303};
304#endif
305
306static int __devinit isp1760_plat_probe(struct platform_device *pdev)
307{
308	int ret = 0;
309	struct usb_hcd *hcd;
310	struct resource *mem_res;
311	struct resource *irq_res;
312	resource_size_t mem_size;
313	struct isp1760_platform_data *priv = pdev->dev.platform_data;
314	unsigned int devflags = 0;
315	unsigned long irqflags = IRQF_SHARED | IRQF_DISABLED;
316
317	mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
318	if (!mem_res) {
319		pr_warning("isp1760: Memory resource not available\n");
320		ret = -ENODEV;
321		goto out;
322	}
323	mem_size = resource_size(mem_res);
324	if (!request_mem_region(mem_res->start, mem_size, "isp1760")) {
325		pr_warning("isp1760: Cannot reserve the memory resource\n");
326		ret = -EBUSY;
327		goto out;
328	}
329
330	irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
331	if (!irq_res) {
332		pr_warning("isp1760: IRQ resource not available\n");
333		return -ENODEV;
334	}
335	irqflags |= irq_res->flags & IRQF_TRIGGER_MASK;
336
337	if (priv) {
338		if (priv->is_isp1761)
339			devflags |= ISP1760_FLAG_ISP1761;
340		if (priv->bus_width_16)
341			devflags |= ISP1760_FLAG_BUS_WIDTH_16;
342		if (priv->port1_otg)
343			devflags |= ISP1760_FLAG_OTG_EN;
344		if (priv->analog_oc)
345			devflags |= ISP1760_FLAG_ANALOG_OC;
346		if (priv->dack_polarity_high)
347			devflags |= ISP1760_FLAG_DACK_POL_HIGH;
348		if (priv->dreq_polarity_high)
349			devflags |= ISP1760_FLAG_DREQ_POL_HIGH;
350	}
351
352	hcd = isp1760_register(mem_res->start, mem_size, irq_res->start,
353			       irqflags, &pdev->dev, dev_name(&pdev->dev), devflags);
354	if (IS_ERR(hcd)) {
355		pr_warning("isp1760: Failed to register the HCD device\n");
356		ret = -ENODEV;
357		goto cleanup;
358	}
359
360	pr_info("ISP1760 USB device initialised\n");
361	return ret;
362
363cleanup:
364	release_mem_region(mem_res->start, mem_size);
365out:
366	return ret;
367}
368
369static int __devexit isp1760_plat_remove(struct platform_device *pdev)
370{
371	struct resource *mem_res;
372	resource_size_t mem_size;
373
374	mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
375	mem_size = resource_size(mem_res);
376	release_mem_region(mem_res->start, mem_size);
377
378	return 0;
379}
380
381static struct platform_driver isp1760_plat_driver = {
382	.probe	= isp1760_plat_probe,
383	.remove	= __devexit_p(isp1760_plat_remove),
384	.driver	= {
385		.name	= "isp1760",
386	},
387};
388
389static int __init isp1760_init(void)
390{
391	int ret, any_ret = -ENODEV;
392
393	init_kmem_once();
394
395	ret = platform_driver_register(&isp1760_plat_driver);
396	if (!ret)
397		any_ret = 0;
398#ifdef CONFIG_PPC_OF
399	ret = of_register_platform_driver(&isp1760_of_driver);
400	if (!ret)
401		any_ret = 0;
402#endif
403#ifdef CONFIG_PCI
404	ret = pci_register_driver(&isp1761_pci_driver);
405	if (!ret)
406		any_ret = 0;
407#endif
408
409	if (any_ret)
410		deinit_kmem_cache();
411	return any_ret;
412}
413module_init(isp1760_init);
414
415static void __exit isp1760_exit(void)
416{
417	platform_driver_unregister(&isp1760_plat_driver);
418#ifdef CONFIG_PPC_OF
419	of_unregister_platform_driver(&isp1760_of_driver);
420#endif
421#ifdef CONFIG_PCI
422	pci_unregister_driver(&isp1761_pci_driver);
423#endif
424	deinit_kmem_cache();
425}
426module_exit(isp1760_exit);
427