Linux Audio

Check our new training course

Loading...
Note: File does not exist in v4.6.
  1/*
  2 * Copyright 2008 Cavium Networks
  3 *
  4 * This file is free software; you can redistribute it and/or modify
  5 * it under the terms of the GNU General Public License, Version 2, as
  6 * published by the Free Software Foundation.
  7 */
  8
  9#include <linux/platform_device.h>
 10#include <linux/atomic.h>
 11#include <mach/cns3xxx.h>
 12#include <mach/pm.h>
 13
 14static int __devinit
 15cns3xxx_ohci_start(struct usb_hcd *hcd)
 16{
 17	struct ohci_hcd	*ohci = hcd_to_ohci(hcd);
 18	int ret;
 19
 20	/*
 21	 * EHCI and OHCI share the same clock and power,
 22	 * resetting twice would cause the 1st controller been reset.
 23	 * Therefore only do power up  at the first up device, and
 24	 * power down at the last down device.
 25	 *
 26	 * Set USB AHB INCR length to 16
 27	 */
 28	if (atomic_inc_return(&usb_pwr_ref) == 1) {
 29		cns3xxx_pwr_power_up(1 << PM_PLL_HM_PD_CTRL_REG_OFFSET_PLL_USB);
 30		cns3xxx_pwr_clk_en(1 << PM_CLK_GATE_REG_OFFSET_USB_HOST);
 31		cns3xxx_pwr_soft_rst(1 << PM_SOFT_RST_REG_OFFST_USB_HOST);
 32		__raw_writel((__raw_readl(MISC_CHIP_CONFIG_REG) | (0X2 << 24)),
 33			MISC_CHIP_CONFIG_REG);
 34	}
 35
 36	ret = ohci_init(ohci);
 37	if (ret < 0)
 38		return ret;
 39
 40	ohci->num_ports = 1;
 41
 42	ret = ohci_run(ohci);
 43	if (ret < 0) {
 44		dev_err(hcd->self.controller, "can't start %s\n",
 45			hcd->self.bus_name);
 46		ohci_stop(hcd);
 47		return ret;
 48	}
 49	return 0;
 50}
 51
 52static const struct hc_driver cns3xxx_ohci_hc_driver = {
 53	.description		= hcd_name,
 54	.product_desc		= "CNS3XXX OHCI Host controller",
 55	.hcd_priv_size		= sizeof(struct ohci_hcd),
 56	.irq			= ohci_irq,
 57	.flags			= HCD_USB11 | HCD_MEMORY,
 58	.start			= cns3xxx_ohci_start,
 59	.stop			= ohci_stop,
 60	.shutdown		= ohci_shutdown,
 61	.urb_enqueue		= ohci_urb_enqueue,
 62	.urb_dequeue		= ohci_urb_dequeue,
 63	.endpoint_disable	= ohci_endpoint_disable,
 64	.get_frame_number	= ohci_get_frame,
 65	.hub_status_data	= ohci_hub_status_data,
 66	.hub_control		= ohci_hub_control,
 67#ifdef CONFIG_PM
 68	.bus_suspend		= ohci_bus_suspend,
 69	.bus_resume		= ohci_bus_resume,
 70#endif
 71	.start_port_reset	= ohci_start_port_reset,
 72};
 73
 74static int cns3xxx_ohci_probe(struct platform_device *pdev)
 75{
 76	struct device *dev = &pdev->dev;
 77	struct usb_hcd *hcd;
 78	const struct hc_driver *driver = &cns3xxx_ohci_hc_driver;
 79	struct resource *res;
 80	int irq;
 81	int retval;
 82
 83	if (usb_disabled())
 84		return -ENODEV;
 85
 86	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
 87	if (!res) {
 88		dev_err(dev, "Found HC with no IRQ.\n");
 89		return -ENODEV;
 90	}
 91	irq = res->start;
 92
 93	hcd = usb_create_hcd(driver, dev, dev_name(dev));
 94	if (!hcd)
 95		return -ENOMEM;
 96
 97	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 98	if (!res) {
 99		dev_err(dev, "Found HC with no register addr.\n");
100		retval = -ENODEV;
101		goto err1;
102	}
103	hcd->rsrc_start = res->start;
104	hcd->rsrc_len = resource_size(res);
105
106	if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len,
107			driver->description)) {
108		dev_dbg(dev, "controller already in use\n");
109		retval = -EBUSY;
110		goto err1;
111	}
112
113	hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
114	if (!hcd->regs) {
115		dev_dbg(dev, "error mapping memory\n");
116		retval = -EFAULT;
117		goto err2;
118	}
119
120	ohci_hcd_init(hcd_to_ohci(hcd));
121
122	retval = usb_add_hcd(hcd, irq, IRQF_SHARED);
123	if (retval == 0)
124		return retval;
125
126	iounmap(hcd->regs);
127err2:
128	release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
129err1:
130	usb_put_hcd(hcd);
131	return retval;
132}
133
134static int cns3xxx_ohci_remove(struct platform_device *pdev)
135{
136	struct usb_hcd *hcd = platform_get_drvdata(pdev);
137
138	usb_remove_hcd(hcd);
139	iounmap(hcd->regs);
140	release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
141
142	/*
143	 * EHCI and OHCI share the same clock and power,
144	 * resetting twice would cause the 1st controller been reset.
145	 * Therefore only do power up  at the first up device, and
146	 * power down at the last down device.
147	 */
148	if (atomic_dec_return(&usb_pwr_ref) == 0)
149		cns3xxx_pwr_clk_dis(1 << PM_CLK_GATE_REG_OFFSET_USB_HOST);
150
151	usb_put_hcd(hcd);
152
153	platform_set_drvdata(pdev, NULL);
154
155	return 0;
156}
157
158MODULE_ALIAS("platform:cns3xxx-ohci");
159
160static struct platform_driver ohci_hcd_cns3xxx_driver = {
161	.probe = cns3xxx_ohci_probe,
162	.remove = cns3xxx_ohci_remove,
163	.driver = {
164		.name = "cns3xxx-ohci",
165	},
166};