root/drivers/usb/isp1760/isp1760-if.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. isp1761_pci_init
  2. isp1761_pci_probe
  3. isp1761_pci_remove
  4. isp1761_pci_shutdown
  5. isp1760_plat_probe
  6. isp1760_plat_remove
  7. isp1760_init
  8. isp1760_exit

   1 // SPDX-License-Identifier: GPL-2.0
   2 /*
   3  * Glue code for the ISP1760 driver and bus
   4  * Currently there is support for
   5  * - OpenFirmware
   6  * - PCI
   7  * - PDEV (generic platform device centralized driver model)
   8  *
   9  * (c) 2007 Sebastian Siewior <bigeasy@linutronix.de>
  10  *
  11  */
  12 
  13 #include <linux/usb.h>
  14 #include <linux/io.h>
  15 #include <linux/module.h>
  16 #include <linux/of.h>
  17 #include <linux/platform_device.h>
  18 #include <linux/slab.h>
  19 #include <linux/usb/isp1760.h>
  20 #include <linux/usb/hcd.h>
  21 
  22 #include "isp1760-core.h"
  23 #include "isp1760-regs.h"
  24 
  25 #ifdef CONFIG_USB_PCI
  26 #include <linux/pci.h>
  27 #endif
  28 
  29 #ifdef CONFIG_USB_PCI
  30 static int isp1761_pci_init(struct pci_dev *dev)
  31 {
  32         resource_size_t mem_start;
  33         resource_size_t mem_length;
  34         u8 __iomem *iobase;
  35         u8 latency, limit;
  36         int retry_count;
  37         u32 reg_data;
  38 
  39         /* Grab the PLX PCI shared memory of the ISP 1761 we need  */
  40         mem_start = pci_resource_start(dev, 3);
  41         mem_length = pci_resource_len(dev, 3);
  42         if (mem_length < 0xffff) {
  43                 printk(KERN_ERR "memory length for this resource is wrong\n");
  44                 return -ENOMEM;
  45         }
  46 
  47         if (!request_mem_region(mem_start, mem_length, "ISP-PCI")) {
  48                 printk(KERN_ERR "host controller already in use\n");
  49                 return -EBUSY;
  50         }
  51 
  52         /* map available memory */
  53         iobase = ioremap_nocache(mem_start, mem_length);
  54         if (!iobase) {
  55                 printk(KERN_ERR "Error ioremap failed\n");
  56                 release_mem_region(mem_start, mem_length);
  57                 return -ENOMEM;
  58         }
  59 
  60         /* bad pci latencies can contribute to overruns */
  61         pci_read_config_byte(dev, PCI_LATENCY_TIMER, &latency);
  62         if (latency) {
  63                 pci_read_config_byte(dev, PCI_MAX_LAT, &limit);
  64                 if (limit && limit < latency)
  65                         pci_write_config_byte(dev, PCI_LATENCY_TIMER, limit);
  66         }
  67 
  68         /* Try to check whether we can access Scratch Register of
  69          * Host Controller or not. The initial PCI access is retried until
  70          * local init for the PCI bridge is completed
  71          */
  72         retry_count = 20;
  73         reg_data = 0;
  74         while ((reg_data != 0xFACE) && retry_count) {
  75                 /*by default host is in 16bit mode, so
  76                  * io operations at this stage must be 16 bit
  77                  * */
  78                 writel(0xface, iobase + HC_SCRATCH_REG);
  79                 udelay(100);
  80                 reg_data = readl(iobase + HC_SCRATCH_REG) & 0x0000ffff;
  81                 retry_count--;
  82         }
  83 
  84         iounmap(iobase);
  85         release_mem_region(mem_start, mem_length);
  86 
  87         /* Host Controller presence is detected by writing to scratch register
  88          * and reading back and checking the contents are same or not
  89          */
  90         if (reg_data != 0xFACE) {
  91                 dev_err(&dev->dev, "scratch register mismatch %x\n", reg_data);
  92                 return -ENOMEM;
  93         }
  94 
  95         /* Grab the PLX PCI mem maped port start address we need  */
  96         mem_start = pci_resource_start(dev, 0);
  97         mem_length = pci_resource_len(dev, 0);
  98 
  99         if (!request_mem_region(mem_start, mem_length, "ISP1761 IO MEM")) {
 100                 printk(KERN_ERR "request region #1\n");
 101                 return -EBUSY;
 102         }
 103 
 104         iobase = ioremap_nocache(mem_start, mem_length);
 105         if (!iobase) {
 106                 printk(KERN_ERR "ioremap #1\n");
 107                 release_mem_region(mem_start, mem_length);
 108                 return -ENOMEM;
 109         }
 110 
 111         /* configure PLX PCI chip to pass interrupts */
 112 #define PLX_INT_CSR_REG 0x68
 113         reg_data = readl(iobase + PLX_INT_CSR_REG);
 114         reg_data |= 0x900;
 115         writel(reg_data, iobase + PLX_INT_CSR_REG);
 116 
 117         /* done with PLX IO access */
 118         iounmap(iobase);
 119         release_mem_region(mem_start, mem_length);
 120 
 121         return 0;
 122 }
 123 
 124 static int isp1761_pci_probe(struct pci_dev *dev,
 125                 const struct pci_device_id *id)
 126 {
 127         unsigned int devflags = 0;
 128         int ret;
 129 
 130         if (!dev->irq)
 131                 return -ENODEV;
 132 
 133         if (pci_enable_device(dev) < 0)
 134                 return -ENODEV;
 135 
 136         ret = isp1761_pci_init(dev);
 137         if (ret < 0)
 138                 goto error;
 139 
 140         pci_set_master(dev);
 141 
 142         ret = isp1760_register(&dev->resource[3], dev->irq, 0, &dev->dev,
 143                                devflags);
 144         if (ret < 0)
 145                 goto error;
 146 
 147         return 0;
 148 
 149 error:
 150         pci_disable_device(dev);
 151         return ret;
 152 }
 153 
 154 static void isp1761_pci_remove(struct pci_dev *dev)
 155 {
 156         isp1760_unregister(&dev->dev);
 157 
 158         pci_disable_device(dev);
 159 }
 160 
 161 static void isp1761_pci_shutdown(struct pci_dev *dev)
 162 {
 163         printk(KERN_ERR "ips1761_pci_shutdown\n");
 164 }
 165 
 166 static const struct pci_device_id isp1760_plx[] = {
 167         {
 168                 .class          = PCI_CLASS_BRIDGE_OTHER << 8,
 169                 .class_mask     = ~0,
 170                 .vendor         = PCI_VENDOR_ID_PLX,
 171                 .device         = 0x5406,
 172                 .subvendor      = PCI_VENDOR_ID_PLX,
 173                 .subdevice      = 0x9054,
 174         },
 175         { }
 176 };
 177 MODULE_DEVICE_TABLE(pci, isp1760_plx);
 178 
 179 static struct pci_driver isp1761_pci_driver = {
 180         .name =         "isp1760",
 181         .id_table =     isp1760_plx,
 182         .probe =        isp1761_pci_probe,
 183         .remove =       isp1761_pci_remove,
 184         .shutdown =     isp1761_pci_shutdown,
 185 };
 186 #endif
 187 
 188 static int isp1760_plat_probe(struct platform_device *pdev)
 189 {
 190         unsigned long irqflags;
 191         unsigned int devflags = 0;
 192         struct resource *mem_res;
 193         struct resource *irq_res;
 194         int ret;
 195 
 196         mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 197 
 198         irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
 199         if (!irq_res) {
 200                 pr_warn("isp1760: IRQ resource not available\n");
 201                 return -ENODEV;
 202         }
 203         irqflags = irq_res->flags & IRQF_TRIGGER_MASK;
 204 
 205         if (IS_ENABLED(CONFIG_OF) && pdev->dev.of_node) {
 206                 struct device_node *dp = pdev->dev.of_node;
 207                 u32 bus_width = 0;
 208 
 209                 if (of_device_is_compatible(dp, "nxp,usb-isp1761"))
 210                         devflags |= ISP1760_FLAG_ISP1761;
 211 
 212                 /* Some systems wire up only 16 of the 32 data lines */
 213                 of_property_read_u32(dp, "bus-width", &bus_width);
 214                 if (bus_width == 16)
 215                         devflags |= ISP1760_FLAG_BUS_WIDTH_16;
 216 
 217                 if (of_property_read_bool(dp, "port1-otg"))
 218                         devflags |= ISP1760_FLAG_OTG_EN;
 219 
 220                 if (of_property_read_bool(dp, "analog-oc"))
 221                         devflags |= ISP1760_FLAG_ANALOG_OC;
 222 
 223                 if (of_property_read_bool(dp, "dack-polarity"))
 224                         devflags |= ISP1760_FLAG_DACK_POL_HIGH;
 225 
 226                 if (of_property_read_bool(dp, "dreq-polarity"))
 227                         devflags |= ISP1760_FLAG_DREQ_POL_HIGH;
 228         } else if (dev_get_platdata(&pdev->dev)) {
 229                 struct isp1760_platform_data *pdata =
 230                         dev_get_platdata(&pdev->dev);
 231 
 232                 if (pdata->is_isp1761)
 233                         devflags |= ISP1760_FLAG_ISP1761;
 234                 if (pdata->bus_width_16)
 235                         devflags |= ISP1760_FLAG_BUS_WIDTH_16;
 236                 if (pdata->port1_otg)
 237                         devflags |= ISP1760_FLAG_OTG_EN;
 238                 if (pdata->analog_oc)
 239                         devflags |= ISP1760_FLAG_ANALOG_OC;
 240                 if (pdata->dack_polarity_high)
 241                         devflags |= ISP1760_FLAG_DACK_POL_HIGH;
 242                 if (pdata->dreq_polarity_high)
 243                         devflags |= ISP1760_FLAG_DREQ_POL_HIGH;
 244         }
 245 
 246         ret = isp1760_register(mem_res, irq_res->start, irqflags, &pdev->dev,
 247                                devflags);
 248         if (ret < 0)
 249                 return ret;
 250 
 251         pr_info("ISP1760 USB device initialised\n");
 252         return 0;
 253 }
 254 
 255 static int isp1760_plat_remove(struct platform_device *pdev)
 256 {
 257         isp1760_unregister(&pdev->dev);
 258 
 259         return 0;
 260 }
 261 
 262 #ifdef CONFIG_OF
 263 static const struct of_device_id isp1760_of_match[] = {
 264         { .compatible = "nxp,usb-isp1760", },
 265         { .compatible = "nxp,usb-isp1761", },
 266         { },
 267 };
 268 MODULE_DEVICE_TABLE(of, isp1760_of_match);
 269 #endif
 270 
 271 static struct platform_driver isp1760_plat_driver = {
 272         .probe  = isp1760_plat_probe,
 273         .remove = isp1760_plat_remove,
 274         .driver = {
 275                 .name   = "isp1760",
 276                 .of_match_table = of_match_ptr(isp1760_of_match),
 277         },
 278 };
 279 
 280 static int __init isp1760_init(void)
 281 {
 282         int ret, any_ret = -ENODEV;
 283 
 284         isp1760_init_kmem_once();
 285 
 286         ret = platform_driver_register(&isp1760_plat_driver);
 287         if (!ret)
 288                 any_ret = 0;
 289 #ifdef CONFIG_USB_PCI
 290         ret = pci_register_driver(&isp1761_pci_driver);
 291         if (!ret)
 292                 any_ret = 0;
 293 #endif
 294 
 295         if (any_ret)
 296                 isp1760_deinit_kmem_cache();
 297         return any_ret;
 298 }
 299 module_init(isp1760_init);
 300 
 301 static void __exit isp1760_exit(void)
 302 {
 303         platform_driver_unregister(&isp1760_plat_driver);
 304 #ifdef CONFIG_USB_PCI
 305         pci_unregister_driver(&isp1761_pci_driver);
 306 #endif
 307         isp1760_deinit_kmem_cache();
 308 }
 309 module_exit(isp1760_exit);

/* [<][>][^][v][top][bottom][index][help] */