Linux Audio

Check our new training course

Loading...
Note: File does not exist in v4.6.
  1/*
  2 * ci13xxx_pci.c - MIPS USB IP core family device controller
  3 *
  4 * Copyright (C) 2008 Chipidea - MIPS Technologies, Inc. All rights reserved.
  5 *
  6 * Author: David Lopo
  7 *
  8 * This program is free software; you can redistribute it and/or modify
  9 * it under the terms of the GNU General Public License version 2 as
 10 * published by the Free Software Foundation.
 11 */
 12
 13#include <linux/module.h>
 14#include <linux/pci.h>
 15
 16#include "ci13xxx_udc.c"
 17
 18/* driver name */
 19#define UDC_DRIVER_NAME   "ci13xxx_pci"
 20
 21/******************************************************************************
 22 * PCI block
 23 *****************************************************************************/
 24/**
 25 * ci13xxx_pci_irq: interrut handler
 26 * @irq:  irq number
 27 * @pdev: USB Device Controller interrupt source
 28 *
 29 * This function returns IRQ_HANDLED if the IRQ has been handled
 30 * This is an ISR don't trace, use attribute interface instead
 31 */
 32static irqreturn_t ci13xxx_pci_irq(int irq, void *pdev)
 33{
 34	if (irq == 0) {
 35		dev_err(&((struct pci_dev *)pdev)->dev, "Invalid IRQ0 usage!");
 36		return IRQ_HANDLED;
 37	}
 38	return udc_irq();
 39}
 40
 41static struct ci13xxx_udc_driver ci13xxx_pci_udc_driver = {
 42	.name		= UDC_DRIVER_NAME,
 43};
 44
 45/**
 46 * ci13xxx_pci_probe: PCI probe
 47 * @pdev: USB device controller being probed
 48 * @id:   PCI hotplug ID connecting controller to UDC framework
 49 *
 50 * This function returns an error code
 51 * Allocates basic PCI resources for this USB device controller, and then
 52 * invokes the udc_probe() method to start the UDC associated with it
 53 */
 54static int __devinit ci13xxx_pci_probe(struct pci_dev *pdev,
 55				       const struct pci_device_id *id)
 56{
 57	void __iomem *regs = NULL;
 58	int retval = 0;
 59
 60	if (id == NULL)
 61		return -EINVAL;
 62
 63	retval = pci_enable_device(pdev);
 64	if (retval)
 65		goto done;
 66
 67	if (!pdev->irq) {
 68		dev_err(&pdev->dev, "No IRQ, check BIOS/PCI setup!");
 69		retval = -ENODEV;
 70		goto disable_device;
 71	}
 72
 73	retval = pci_request_regions(pdev, UDC_DRIVER_NAME);
 74	if (retval)
 75		goto disable_device;
 76
 77	/* BAR 0 holds all the registers */
 78	regs = pci_iomap(pdev, 0, 0);
 79	if (!regs) {
 80		dev_err(&pdev->dev, "Error mapping memory!");
 81		retval = -EFAULT;
 82		goto release_regions;
 83	}
 84	pci_set_drvdata(pdev, (__force void *)regs);
 85
 86	pci_set_master(pdev);
 87	pci_try_set_mwi(pdev);
 88
 89	retval = udc_probe(&ci13xxx_pci_udc_driver, &pdev->dev, regs);
 90	if (retval)
 91		goto iounmap;
 92
 93	/* our device does not have MSI capability */
 94
 95	retval = request_irq(pdev->irq, ci13xxx_pci_irq, IRQF_SHARED,
 96			     UDC_DRIVER_NAME, pdev);
 97	if (retval)
 98		goto gadget_remove;
 99
100	return 0;
101
102 gadget_remove:
103	udc_remove();
104 iounmap:
105	pci_iounmap(pdev, regs);
106 release_regions:
107	pci_release_regions(pdev);
108 disable_device:
109	pci_disable_device(pdev);
110 done:
111	return retval;
112}
113
114/**
115 * ci13xxx_pci_remove: PCI remove
116 * @pdev: USB Device Controller being removed
117 *
118 * Reverses the effect of ci13xxx_pci_probe(),
119 * first invoking the udc_remove() and then releases
120 * all PCI resources allocated for this USB device controller
121 */
122static void __devexit ci13xxx_pci_remove(struct pci_dev *pdev)
123{
124	free_irq(pdev->irq, pdev);
125	udc_remove();
126	pci_iounmap(pdev, (__force void __iomem *)pci_get_drvdata(pdev));
127	pci_release_regions(pdev);
128	pci_disable_device(pdev);
129}
130
131/**
132 * PCI device table
133 * PCI device structure
134 *
135 * Check "pci.h" for details
136 */
137static DEFINE_PCI_DEVICE_TABLE(ci13xxx_pci_id_table) = {
138	{ PCI_DEVICE(0x153F, 0x1004) },
139	{ PCI_DEVICE(0x153F, 0x1006) },
140	{ 0, 0, 0, 0, 0, 0, 0 /* end: all zeroes */ }
141};
142MODULE_DEVICE_TABLE(pci, ci13xxx_pci_id_table);
143
144static struct pci_driver ci13xxx_pci_driver = {
145	.name         =	UDC_DRIVER_NAME,
146	.id_table     =	ci13xxx_pci_id_table,
147	.probe        =	ci13xxx_pci_probe,
148	.remove       =	__devexit_p(ci13xxx_pci_remove),
149};
150
151/**
152 * ci13xxx_pci_init: module init
153 *
154 * Driver load
155 */
156static int __init ci13xxx_pci_init(void)
157{
158	return pci_register_driver(&ci13xxx_pci_driver);
159}
160module_init(ci13xxx_pci_init);
161
162/**
163 * ci13xxx_pci_exit: module exit
164 *
165 * Driver unload
166 */
167static void __exit ci13xxx_pci_exit(void)
168{
169	pci_unregister_driver(&ci13xxx_pci_driver);
170}
171module_exit(ci13xxx_pci_exit);
172
173MODULE_AUTHOR("MIPS - David Lopo <dlopo@chipidea.mips.com>");
174MODULE_DESCRIPTION("MIPS CI13XXX USB Peripheral Controller");
175MODULE_LICENSE("GPL");
176MODULE_VERSION("June 2008");