0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023 #include <linux/device.h>
0024 #include <linux/io.h>
0025 #include <linux/list.h>
0026 #include <linux/slab.h>
0027 #include <linux/module.h>
0028 #include <linux/usb.h>
0029 #include <linux/usb/c67x00.h>
0030
0031 #include "c67x00.h"
0032 #include "c67x00-hcd.h"
0033
0034 static void c67x00_probe_sie(struct c67x00_sie *sie,
0035 struct c67x00_device *dev, int sie_num)
0036 {
0037 spin_lock_init(&sie->lock);
0038 sie->dev = dev;
0039 sie->sie_num = sie_num;
0040 sie->mode = c67x00_sie_config(dev->pdata->sie_config, sie_num);
0041
0042 switch (sie->mode) {
0043 case C67X00_SIE_HOST:
0044 c67x00_hcd_probe(sie);
0045 break;
0046
0047 case C67X00_SIE_UNUSED:
0048 dev_info(sie_dev(sie),
0049 "Not using SIE %d as requested\n", sie->sie_num);
0050 break;
0051
0052 default:
0053 dev_err(sie_dev(sie),
0054 "Unsupported configuration: 0x%x for SIE %d\n",
0055 sie->mode, sie->sie_num);
0056 break;
0057 }
0058 }
0059
0060 static void c67x00_remove_sie(struct c67x00_sie *sie)
0061 {
0062 switch (sie->mode) {
0063 case C67X00_SIE_HOST:
0064 c67x00_hcd_remove(sie);
0065 break;
0066
0067 default:
0068 break;
0069 }
0070 }
0071
0072 static irqreturn_t c67x00_irq(int irq, void *__dev)
0073 {
0074 struct c67x00_device *c67x00 = __dev;
0075 struct c67x00_sie *sie;
0076 u16 msg, int_status;
0077 int i, count = 8;
0078
0079 int_status = c67x00_ll_hpi_status(c67x00);
0080 if (!int_status)
0081 return IRQ_NONE;
0082
0083 while (int_status != 0 && (count-- >= 0)) {
0084 c67x00_ll_irq(c67x00, int_status);
0085 for (i = 0; i < C67X00_SIES; i++) {
0086 sie = &c67x00->sie[i];
0087 msg = 0;
0088 if (int_status & SIEMSG_FLG(i))
0089 msg = c67x00_ll_fetch_siemsg(c67x00, i);
0090 if (sie->irq)
0091 sie->irq(sie, int_status, msg);
0092 }
0093 int_status = c67x00_ll_hpi_status(c67x00);
0094 }
0095
0096 if (int_status)
0097 dev_warn(&c67x00->pdev->dev, "Not all interrupts handled! "
0098 "status = 0x%04x\n", int_status);
0099
0100 return IRQ_HANDLED;
0101 }
0102
0103
0104
0105 static int c67x00_drv_probe(struct platform_device *pdev)
0106 {
0107 struct c67x00_device *c67x00;
0108 struct c67x00_platform_data *pdata;
0109 struct resource *res, *res2;
0110 int ret, i;
0111
0112 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
0113 if (!res)
0114 return -ENODEV;
0115
0116 res2 = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
0117 if (!res2)
0118 return -ENODEV;
0119
0120 pdata = dev_get_platdata(&pdev->dev);
0121 if (!pdata)
0122 return -ENODEV;
0123
0124 c67x00 = kzalloc(sizeof(*c67x00), GFP_KERNEL);
0125 if (!c67x00)
0126 return -ENOMEM;
0127
0128 if (!request_mem_region(res->start, resource_size(res),
0129 pdev->name)) {
0130 dev_err(&pdev->dev, "Memory region busy\n");
0131 ret = -EBUSY;
0132 goto request_mem_failed;
0133 }
0134 c67x00->hpi.base = ioremap(res->start, resource_size(res));
0135 if (!c67x00->hpi.base) {
0136 dev_err(&pdev->dev, "Unable to map HPI registers\n");
0137 ret = -EIO;
0138 goto map_failed;
0139 }
0140
0141 spin_lock_init(&c67x00->hpi.lock);
0142 c67x00->hpi.regstep = pdata->hpi_regstep;
0143 c67x00->pdata = dev_get_platdata(&pdev->dev);
0144 c67x00->pdev = pdev;
0145
0146 c67x00_ll_init(c67x00);
0147 c67x00_ll_hpi_reg_init(c67x00);
0148
0149 ret = request_irq(res2->start, c67x00_irq, 0, pdev->name, c67x00);
0150 if (ret) {
0151 dev_err(&pdev->dev, "Cannot claim IRQ\n");
0152 goto request_irq_failed;
0153 }
0154
0155 ret = c67x00_ll_reset(c67x00);
0156 if (ret) {
0157 dev_err(&pdev->dev, "Device reset failed\n");
0158 goto reset_failed;
0159 }
0160
0161 for (i = 0; i < C67X00_SIES; i++)
0162 c67x00_probe_sie(&c67x00->sie[i], c67x00, i);
0163
0164 platform_set_drvdata(pdev, c67x00);
0165
0166 return 0;
0167
0168 reset_failed:
0169 free_irq(res2->start, c67x00);
0170 request_irq_failed:
0171 iounmap(c67x00->hpi.base);
0172 map_failed:
0173 release_mem_region(res->start, resource_size(res));
0174 request_mem_failed:
0175 kfree(c67x00);
0176
0177 return ret;
0178 }
0179
0180 static int c67x00_drv_remove(struct platform_device *pdev)
0181 {
0182 struct c67x00_device *c67x00 = platform_get_drvdata(pdev);
0183 struct resource *res;
0184 int i;
0185
0186 for (i = 0; i < C67X00_SIES; i++)
0187 c67x00_remove_sie(&c67x00->sie[i]);
0188
0189 c67x00_ll_release(c67x00);
0190
0191 res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
0192 free_irq(res->start, c67x00);
0193
0194 iounmap(c67x00->hpi.base);
0195
0196 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
0197 release_mem_region(res->start, resource_size(res));
0198
0199 kfree(c67x00);
0200
0201 return 0;
0202 }
0203
0204 static struct platform_driver c67x00_driver = {
0205 .probe = c67x00_drv_probe,
0206 .remove = c67x00_drv_remove,
0207 .driver = {
0208 .name = "c67x00",
0209 },
0210 };
0211
0212 module_platform_driver(c67x00_driver);
0213
0214 MODULE_AUTHOR("Peter Korsgaard, Jan Veldeman, Grant Likely");
0215 MODULE_DESCRIPTION("Cypress C67X00 USB Controller Driver");
0216 MODULE_LICENSE("GPL");
0217 MODULE_ALIAS("platform:c67x00");