aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host/isp1760-if.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/host/isp1760-if.c')
-rw-r--r--drivers/usb/host/isp1760-if.c116
1 files changed, 65 insertions, 51 deletions
diff --git a/drivers/usb/host/isp1760-if.c b/drivers/usb/host/isp1760-if.c
index b87ca7cf4b37..4cf7ca428b33 100644
--- a/drivers/usb/host/isp1760-if.c
+++ b/drivers/usb/host/isp1760-if.c
@@ -60,9 +60,6 @@ static int of_isp1760_probe(struct of_device *dev,
60 if (of_device_is_compatible(dp, "nxp,usb-isp1761")) 60 if (of_device_is_compatible(dp, "nxp,usb-isp1761"))
61 devflags |= ISP1760_FLAG_ISP1761; 61 devflags |= ISP1760_FLAG_ISP1761;
62 62
63 if (of_get_property(dp, "port1-disable", NULL) != NULL)
64 devflags |= ISP1760_FLAG_PORT1_DIS;
65
66 /* Some systems wire up only 16 of the 32 data lines */ 63 /* Some systems wire up only 16 of the 32 data lines */
67 prop = of_get_property(dp, "bus-width", NULL); 64 prop = of_get_property(dp, "bus-width", NULL);
68 if (prop && *prop == 16) 65 if (prop && *prop == 16)
@@ -129,23 +126,23 @@ static struct of_platform_driver isp1760_of_driver = {
129#endif 126#endif
130 127
131#ifdef CONFIG_PCI 128#ifdef CONFIG_PCI
132static u32 nxp_pci_io_base;
133static u32 iolength;
134static u32 pci_mem_phy0;
135static u32 length;
136static u8 __iomem *chip_addr;
137static u8 __iomem *iobase;
138
139static int __devinit isp1761_pci_probe(struct pci_dev *dev, 129static int __devinit isp1761_pci_probe(struct pci_dev *dev,
140 const struct pci_device_id *id) 130 const struct pci_device_id *id)
141{ 131{
142 u8 latency, limit; 132 u8 latency, limit;
143 __u32 reg_data; 133 __u32 reg_data;
144 int retry_count; 134 int retry_count;
145 int length;
146 int status = 1;
147 struct usb_hcd *hcd; 135 struct usb_hcd *hcd;
148 unsigned int devflags = 0; 136 unsigned int devflags = 0;
137 int ret_status = 0;
138
139 resource_size_t pci_mem_phy0;
140 resource_size_t memlength;
141
142 u8 __iomem *chip_addr;
143 u8 __iomem *iobase;
144 resource_size_t nxp_pci_io_base;
145 resource_size_t iolength;
149 146
150 if (usb_disabled()) 147 if (usb_disabled())
151 return -ENODEV; 148 return -ENODEV;
@@ -168,26 +165,30 @@ static int __devinit isp1761_pci_probe(struct pci_dev *dev,
168 iobase = ioremap_nocache(nxp_pci_io_base, iolength); 165 iobase = ioremap_nocache(nxp_pci_io_base, iolength);
169 if (!iobase) { 166 if (!iobase) {
170 printk(KERN_ERR "ioremap #1\n"); 167 printk(KERN_ERR "ioremap #1\n");
171 release_mem_region(nxp_pci_io_base, iolength); 168 ret_status = -ENOMEM;
172 return -ENOMEM; 169 goto cleanup1;
173 } 170 }
174 /* Grab the PLX PCI shared memory of the ISP 1761 we need */ 171 /* Grab the PLX PCI shared memory of the ISP 1761 we need */
175 pci_mem_phy0 = pci_resource_start(dev, 3); 172 pci_mem_phy0 = pci_resource_start(dev, 3);
176 length = pci_resource_len(dev, 3); 173 memlength = pci_resource_len(dev, 3);
177 174 if (memlength < 0xffff) {
178 if (length < 0xffff) { 175 printk(KERN_ERR "memory length for this resource is wrong\n");
179 printk(KERN_ERR "memory length for this resource is less than " 176 ret_status = -ENOMEM;
180 "required\n"); 177 goto cleanup2;
181 release_mem_region(nxp_pci_io_base, iolength);
182 iounmap(iobase);
183 return -ENOMEM;
184 } 178 }
185 179
186 if (!request_mem_region(pci_mem_phy0, length, "ISP-PCI")) { 180 if (!request_mem_region(pci_mem_phy0, memlength, "ISP-PCI")) {
187 printk(KERN_ERR "host controller already in use\n"); 181 printk(KERN_ERR "host controller already in use\n");
188 release_mem_region(nxp_pci_io_base, iolength); 182 ret_status = -EBUSY;
189 iounmap(iobase); 183 goto cleanup2;
190 return -EBUSY; 184 }
185
186 /* map available memory */
187 chip_addr = ioremap_nocache(pci_mem_phy0,memlength);
188 if (!chip_addr) {
189 printk(KERN_ERR "Error ioremap failed\n");
190 ret_status = -ENOMEM;
191 goto cleanup3;
191 } 192 }
192 193
193 /* bad pci latencies can contribute to overruns */ 194 /* bad pci latencies can contribute to overruns */
@@ -210,39 +211,54 @@ static int __devinit isp1761_pci_probe(struct pci_dev *dev,
210 * */ 211 * */
211 writel(0xface, chip_addr + HC_SCRATCH_REG); 212 writel(0xface, chip_addr + HC_SCRATCH_REG);
212 udelay(100); 213 udelay(100);
213 reg_data = readl(chip_addr + HC_SCRATCH_REG); 214 reg_data = readl(chip_addr + HC_SCRATCH_REG) & 0x0000ffff;
214 retry_count--; 215 retry_count--;
215 } 216 }
216 217
218 iounmap(chip_addr);
219
217 /* Host Controller presence is detected by writing to scratch register 220 /* Host Controller presence is detected by writing to scratch register
218 * and reading back and checking the contents are same or not 221 * and reading back and checking the contents are same or not
219 */ 222 */
220 if (reg_data != 0xFACE) { 223 if (reg_data != 0xFACE) {
221 dev_err(&dev->dev, "scratch register mismatch %x\n", reg_data); 224 dev_err(&dev->dev, "scratch register mismatch %x\n", reg_data);
222 goto clean; 225 ret_status = -ENOMEM;
226 goto cleanup3;
223 } 227 }
224 228
225 pci_set_master(dev); 229 pci_set_master(dev);
226 230
227 status = readl(iobase + 0x68); 231 /* configure PLX PCI chip to pass interrupts */
228 status |= 0x900; 232#define PLX_INT_CSR_REG 0x68
229 writel(status, iobase + 0x68); 233 reg_data = readl(iobase + PLX_INT_CSR_REG);
234 reg_data |= 0x900;
235 writel(reg_data, iobase + PLX_INT_CSR_REG);
230 236
231 dev->dev.dma_mask = NULL; 237 dev->dev.dma_mask = NULL;
232 hcd = isp1760_register(pci_mem_phy0, length, dev->irq, 238 hcd = isp1760_register(pci_mem_phy0, memlength, dev->irq,
233 IRQF_SHARED | IRQF_DISABLED, &dev->dev, dev_name(&dev->dev), 239 IRQF_SHARED | IRQF_DISABLED, &dev->dev, dev_name(&dev->dev),
234 devflags); 240 devflags);
235 if (!IS_ERR(hcd)) { 241 if (IS_ERR(hcd)) {
236 pci_set_drvdata(dev, hcd); 242 ret_status = -ENODEV;
237 return 0; 243 goto cleanup3;
238 } 244 }
239clean: 245
240 status = -ENODEV; 246 /* done with PLX IO access */
247 iounmap(iobase);
248 release_mem_region(nxp_pci_io_base, iolength);
249
250 pci_set_drvdata(dev, hcd);
251 return 0;
252
253cleanup3:
254 release_mem_region(pci_mem_phy0, memlength);
255cleanup2:
241 iounmap(iobase); 256 iounmap(iobase);
242 release_mem_region(pci_mem_phy0, length); 257cleanup1:
243 release_mem_region(nxp_pci_io_base, iolength); 258 release_mem_region(nxp_pci_io_base, iolength);
244 return status; 259 return ret_status;
245} 260}
261
246static void isp1761_pci_remove(struct pci_dev *dev) 262static void isp1761_pci_remove(struct pci_dev *dev)
247{ 263{
248 struct usb_hcd *hcd; 264 struct usb_hcd *hcd;
@@ -255,12 +271,6 @@ static void isp1761_pci_remove(struct pci_dev *dev)
255 usb_put_hcd(hcd); 271 usb_put_hcd(hcd);
256 272
257 pci_disable_device(dev); 273 pci_disable_device(dev);
258
259 iounmap(iobase);
260 iounmap(chip_addr);
261
262 release_mem_region(nxp_pci_io_base, iolength);
263 release_mem_region(pci_mem_phy0, length);
264} 274}
265 275
266static void isp1761_pci_shutdown(struct pci_dev *dev) 276static void isp1761_pci_shutdown(struct pci_dev *dev)
@@ -268,12 +278,16 @@ static void isp1761_pci_shutdown(struct pci_dev *dev)
268 printk(KERN_ERR "ips1761_pci_shutdown\n"); 278 printk(KERN_ERR "ips1761_pci_shutdown\n");
269} 279}
270 280
271static const struct pci_device_id isp1760_plx [] = { { 281static const struct pci_device_id isp1760_plx [] = {
272 /* handle any USB 2.0 EHCI controller */ 282 {
273 PCI_DEVICE_CLASS(((PCI_CLASS_BRIDGE_OTHER << 8) | (0x06 << 16)), ~0), 283 .class = PCI_CLASS_BRIDGE_OTHER << 8,
274 .driver_data = 0, 284 .class_mask = ~0,
275}, 285 .vendor = PCI_VENDOR_ID_PLX,
276{ /* end: all zeroes */ } 286 .device = 0x5406,
287 .subvendor = PCI_VENDOR_ID_PLX,
288 .subdevice = 0x9054,
289 },
290 { }
277}; 291};
278MODULE_DEVICE_TABLE(pci, isp1760_plx); 292MODULE_DEVICE_TABLE(pci, isp1760_plx);
279 293