linux/drivers/usb/host/isp1760-if.c
<<
>>
Prefs
   1/*
   2 * Glue code for the ISP1760 driver and bus
   3 * Currently there is support for
   4 * - OpenFirmware
   5 * - PCI
   6 * - PDEV (generic platform device centralized driver model)
   7 *
   8 * (c) 2007 Sebastian Siewior <bigeasy@linutronix.de>
   9 *
  10 */
  11
  12#include <linux/usb.h>
  13#include <linux/io.h>
  14#include <linux/module.h>
  15#include <linux/platform_device.h>
  16#include <linux/usb/isp1760.h>
  17#include <linux/usb/hcd.h>
  18
  19#include "isp1760-hcd.h"
  20
  21#if defined(CONFIG_OF) && defined(CONFIG_OF_IRQ)
  22#include <linux/slab.h>
  23#include <linux/of.h>
  24#include <linux/of_platform.h>
  25#include <linux/of_address.h>
  26#include <linux/of_irq.h>
  27#include <linux/of_gpio.h>
  28#endif
  29
  30#ifdef CONFIG_PCI
  31#include <linux/pci.h>
  32#endif
  33
  34#if defined(CONFIG_OF) && defined(CONFIG_OF_IRQ)
  35struct isp1760 {
  36        struct usb_hcd *hcd;
  37        int rst_gpio;
  38};
  39
  40static int of_isp1760_probe(struct platform_device *dev)
  41{
  42        struct isp1760 *drvdata;
  43        struct device_node *dp = dev->dev.of_node;
  44        struct resource *res;
  45        struct resource memory;
  46        struct of_irq oirq;
  47        int virq;
  48        resource_size_t res_len;
  49        int ret;
  50        unsigned int devflags = 0;
  51        enum of_gpio_flags gpio_flags;
  52        u32 bus_width = 0;
  53
  54        drvdata = kzalloc(sizeof(*drvdata), GFP_KERNEL);
  55        if (!drvdata)
  56                return -ENOMEM;
  57
  58        ret = of_address_to_resource(dp, 0, &memory);
  59        if (ret) {
  60                ret = -ENXIO;
  61                goto free_data;
  62        }
  63
  64        res_len = resource_size(&memory);
  65
  66        res = request_mem_region(memory.start, res_len, dev_name(&dev->dev));
  67        if (!res) {
  68                ret = -EBUSY;
  69                goto free_data;
  70        }
  71
  72        if (of_irq_map_one(dp, 0, &oirq)) {
  73                ret = -ENODEV;
  74                goto release_reg;
  75        }
  76
  77        virq = irq_create_of_mapping(oirq.controller, oirq.specifier,
  78                        oirq.size);
  79
  80        if (of_device_is_compatible(dp, "nxp,usb-isp1761"))
  81                devflags |= ISP1760_FLAG_ISP1761;
  82
  83        /* Some systems wire up only 16 of the 32 data lines */
  84        of_property_read_u32(dp, "bus-width", &bus_width);
  85        if (bus_width == 16)
  86                devflags |= ISP1760_FLAG_BUS_WIDTH_16;
  87
  88        if (of_get_property(dp, "port1-otg", NULL) != NULL)
  89                devflags |= ISP1760_FLAG_OTG_EN;
  90
  91        if (of_get_property(dp, "analog-oc", NULL) != NULL)
  92                devflags |= ISP1760_FLAG_ANALOG_OC;
  93
  94        if (of_get_property(dp, "dack-polarity", NULL) != NULL)
  95                devflags |= ISP1760_FLAG_DACK_POL_HIGH;
  96
  97        if (of_get_property(dp, "dreq-polarity", NULL) != NULL)
  98                devflags |= ISP1760_FLAG_DREQ_POL_HIGH;
  99
 100        drvdata->rst_gpio = of_get_gpio_flags(dp, 0, &gpio_flags);
 101        if (gpio_is_valid(drvdata->rst_gpio)) {
 102                ret = gpio_request(drvdata->rst_gpio, dev_name(&dev->dev));
 103                if (!ret) {
 104                        if (!(gpio_flags & OF_GPIO_ACTIVE_LOW)) {
 105                                devflags |= ISP1760_FLAG_RESET_ACTIVE_HIGH;
 106                                gpio_direction_output(drvdata->rst_gpio, 0);
 107                        } else {
 108                                gpio_direction_output(drvdata->rst_gpio, 1);
 109                        }
 110                } else {
 111                        drvdata->rst_gpio = ret;
 112                }
 113        }
 114
 115        drvdata->hcd = isp1760_register(memory.start, res_len, virq,
 116                                        IRQF_SHARED, drvdata->rst_gpio,
 117                                        &dev->dev, dev_name(&dev->dev),
 118                                        devflags);
 119        if (IS_ERR(drvdata->hcd)) {
 120                ret = PTR_ERR(drvdata->hcd);
 121                goto free_gpio;
 122        }
 123
 124        dev_set_drvdata(&dev->dev, drvdata);
 125        return ret;
 126
 127free_gpio:
 128        if (gpio_is_valid(drvdata->rst_gpio))
 129                gpio_free(drvdata->rst_gpio);
 130release_reg:
 131        release_mem_region(memory.start, res_len);
 132free_data:
 133        kfree(drvdata);
 134        return ret;
 135}
 136
 137static int of_isp1760_remove(struct platform_device *dev)
 138{
 139        struct isp1760 *drvdata = dev_get_drvdata(&dev->dev);
 140
 141        dev_set_drvdata(&dev->dev, NULL);
 142
 143        usb_remove_hcd(drvdata->hcd);
 144        iounmap(drvdata->hcd->regs);
 145        release_mem_region(drvdata->hcd->rsrc_start, drvdata->hcd->rsrc_len);
 146        usb_put_hcd(drvdata->hcd);
 147
 148        if (gpio_is_valid(drvdata->rst_gpio))
 149                gpio_free(drvdata->rst_gpio);
 150
 151        kfree(drvdata);
 152        return 0;
 153}
 154
 155static const struct of_device_id of_isp1760_match[] = {
 156        {
 157                .compatible = "nxp,usb-isp1760",
 158        },
 159        {
 160                .compatible = "nxp,usb-isp1761",
 161        },
 162        { },
 163};
 164MODULE_DEVICE_TABLE(of, of_isp1760_match);
 165
 166static struct platform_driver isp1760_of_driver = {
 167        .driver = {
 168                .name = "nxp-isp1760",
 169                .owner = THIS_MODULE,
 170                .of_match_table = of_isp1760_match,
 171        },
 172        .probe          = of_isp1760_probe,
 173        .remove         = of_isp1760_remove,
 174};
 175#endif
 176
 177#ifdef CONFIG_PCI
 178static int __devinit isp1761_pci_probe(struct pci_dev *dev,
 179                const struct pci_device_id *id)
 180{
 181        u8 latency, limit;
 182        __u32 reg_data;
 183        int retry_count;
 184        struct usb_hcd *hcd;
 185        unsigned int devflags = 0;
 186        int ret_status = 0;
 187
 188        resource_size_t pci_mem_phy0;
 189        resource_size_t memlength;
 190
 191        u8 __iomem *chip_addr;
 192        u8 __iomem *iobase;
 193        resource_size_t nxp_pci_io_base;
 194        resource_size_t iolength;
 195
 196        if (usb_disabled())
 197                return -ENODEV;
 198
 199        if (pci_enable_device(dev) < 0)
 200                return -ENODEV;
 201
 202        if (!dev->irq)
 203                return -ENODEV;
 204
 205        /* Grab the PLX PCI mem maped port start address we need  */
 206        nxp_pci_io_base = pci_resource_start(dev, 0);
 207        iolength = pci_resource_len(dev, 0);
 208
 209        if (!request_mem_region(nxp_pci_io_base, iolength, "ISP1761 IO MEM")) {
 210                printk(KERN_ERR "request region #1\n");
 211                return -EBUSY;
 212        }
 213
 214        iobase = ioremap_nocache(nxp_pci_io_base, iolength);
 215        if (!iobase) {
 216                printk(KERN_ERR "ioremap #1\n");
 217                ret_status = -ENOMEM;
 218                goto cleanup1;
 219        }
 220        /* Grab the PLX PCI shared memory of the ISP 1761 we need  */
 221        pci_mem_phy0 = pci_resource_start(dev, 3);
 222        memlength = pci_resource_len(dev, 3);
 223        if (memlength < 0xffff) {
 224                printk(KERN_ERR "memory length for this resource is wrong\n");
 225                ret_status = -ENOMEM;
 226                goto cleanup2;
 227        }
 228
 229        if (!request_mem_region(pci_mem_phy0, memlength, "ISP-PCI")) {
 230                printk(KERN_ERR "host controller already in use\n");
 231                ret_status = -EBUSY;
 232                goto cleanup2;
 233        }
 234
 235        /* map available memory */
 236        chip_addr = ioremap_nocache(pci_mem_phy0,memlength);
 237        if (!chip_addr) {
 238                printk(KERN_ERR "Error ioremap failed\n");
 239                ret_status = -ENOMEM;
 240                goto cleanup3;
 241        }
 242
 243        /* bad pci latencies can contribute to overruns */
 244        pci_read_config_byte(dev, PCI_LATENCY_TIMER, &latency);
 245        if (latency) {
 246                pci_read_config_byte(dev, PCI_MAX_LAT, &limit);
 247                if (limit && limit < latency)
 248                        pci_write_config_byte(dev, PCI_LATENCY_TIMER, limit);
 249        }
 250
 251        /* Try to check whether we can access Scratch Register of
 252         * Host Controller or not. The initial PCI access is retried until
 253         * local init for the PCI bridge is completed
 254         */
 255        retry_count = 20;
 256        reg_data = 0;
 257        while ((reg_data != 0xFACE) && retry_count) {
 258                /*by default host is in 16bit mode, so
 259                 * io operations at this stage must be 16 bit
 260                 * */
 261                writel(0xface, chip_addr + HC_SCRATCH_REG);
 262                udelay(100);
 263                reg_data = readl(chip_addr + HC_SCRATCH_REG) & 0x0000ffff;
 264                retry_count--;
 265        }
 266
 267        iounmap(chip_addr);
 268
 269        /* Host Controller presence is detected by writing to scratch register
 270         * and reading back and checking the contents are same or not
 271         */
 272        if (reg_data != 0xFACE) {
 273                dev_err(&dev->dev, "scratch register mismatch %x\n", reg_data);
 274                ret_status = -ENOMEM;
 275                goto cleanup3;
 276        }
 277
 278        pci_set_master(dev);
 279
 280        /* configure PLX PCI chip to pass interrupts */
 281#define PLX_INT_CSR_REG 0x68
 282        reg_data = readl(iobase + PLX_INT_CSR_REG);
 283        reg_data |= 0x900;
 284        writel(reg_data, iobase + PLX_INT_CSR_REG);
 285
 286        dev->dev.dma_mask = NULL;
 287        hcd = isp1760_register(pci_mem_phy0, memlength, dev->irq,
 288                IRQF_SHARED, -ENOENT, &dev->dev, dev_name(&dev->dev),
 289                devflags);
 290        if (IS_ERR(hcd)) {
 291                ret_status = -ENODEV;
 292                goto cleanup3;
 293        }
 294
 295        /* done with PLX IO access */
 296        iounmap(iobase);
 297        release_mem_region(nxp_pci_io_base, iolength);
 298
 299        pci_set_drvdata(dev, hcd);
 300        return 0;
 301
 302cleanup3:
 303        release_mem_region(pci_mem_phy0, memlength);
 304cleanup2:
 305        iounmap(iobase);
 306cleanup1:
 307        release_mem_region(nxp_pci_io_base, iolength);
 308        return ret_status;
 309}
 310
 311static void isp1761_pci_remove(struct pci_dev *dev)
 312{
 313        struct usb_hcd *hcd;
 314
 315        hcd = pci_get_drvdata(dev);
 316
 317        usb_remove_hcd(hcd);
 318        iounmap(hcd->regs);
 319        release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
 320        usb_put_hcd(hcd);
 321
 322        pci_disable_device(dev);
 323}
 324
 325static void isp1761_pci_shutdown(struct pci_dev *dev)
 326{
 327        printk(KERN_ERR "ips1761_pci_shutdown\n");
 328}
 329
 330static const struct pci_device_id isp1760_plx [] = {
 331        {
 332                .class          = PCI_CLASS_BRIDGE_OTHER << 8,
 333                .class_mask     = ~0,
 334                .vendor         = PCI_VENDOR_ID_PLX,
 335                .device         = 0x5406,
 336                .subvendor      = PCI_VENDOR_ID_PLX,
 337                .subdevice      = 0x9054,
 338        },
 339        { }
 340};
 341MODULE_DEVICE_TABLE(pci, isp1760_plx);
 342
 343static struct pci_driver isp1761_pci_driver = {
 344        .name =         "isp1760",
 345        .id_table =     isp1760_plx,
 346        .probe =        isp1761_pci_probe,
 347        .remove =       isp1761_pci_remove,
 348        .shutdown =     isp1761_pci_shutdown,
 349};
 350#endif
 351
 352static int __devinit isp1760_plat_probe(struct platform_device *pdev)
 353{
 354        int ret = 0;
 355        struct usb_hcd *hcd;
 356        struct resource *mem_res;
 357        struct resource *irq_res;
 358        resource_size_t mem_size;
 359        struct isp1760_platform_data *priv = pdev->dev.platform_data;
 360        unsigned int devflags = 0;
 361        unsigned long irqflags = IRQF_SHARED;
 362
 363        mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 364        if (!mem_res) {
 365                pr_warning("isp1760: Memory resource not available\n");
 366                ret = -ENODEV;
 367                goto out;
 368        }
 369        mem_size = resource_size(mem_res);
 370        if (!request_mem_region(mem_res->start, mem_size, "isp1760")) {
 371                pr_warning("isp1760: Cannot reserve the memory resource\n");
 372                ret = -EBUSY;
 373                goto out;
 374        }
 375
 376        irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
 377        if (!irq_res) {
 378                pr_warning("isp1760: IRQ resource not available\n");
 379                return -ENODEV;
 380        }
 381        irqflags |= irq_res->flags & IRQF_TRIGGER_MASK;
 382
 383        if (priv) {
 384                if (priv->is_isp1761)
 385                        devflags |= ISP1760_FLAG_ISP1761;
 386                if (priv->bus_width_16)
 387                        devflags |= ISP1760_FLAG_BUS_WIDTH_16;
 388                if (priv->port1_otg)
 389                        devflags |= ISP1760_FLAG_OTG_EN;
 390                if (priv->analog_oc)
 391                        devflags |= ISP1760_FLAG_ANALOG_OC;
 392                if (priv->dack_polarity_high)
 393                        devflags |= ISP1760_FLAG_DACK_POL_HIGH;
 394                if (priv->dreq_polarity_high)
 395                        devflags |= ISP1760_FLAG_DREQ_POL_HIGH;
 396        }
 397
 398        hcd = isp1760_register(mem_res->start, mem_size, irq_res->start,
 399                               irqflags, -ENOENT,
 400                               &pdev->dev, dev_name(&pdev->dev), devflags);
 401
 402        dev_set_drvdata(&pdev->dev, hcd);
 403
 404        if (IS_ERR(hcd)) {
 405                pr_warning("isp1760: Failed to register the HCD device\n");
 406                ret = -ENODEV;
 407                goto cleanup;
 408        }
 409
 410        pr_info("ISP1760 USB device initialised\n");
 411        return ret;
 412
 413cleanup:
 414        release_mem_region(mem_res->start, mem_size);
 415out:
 416        return ret;
 417}
 418
 419static int __devexit isp1760_plat_remove(struct platform_device *pdev)
 420{
 421        struct resource *mem_res;
 422        resource_size_t mem_size;
 423        struct usb_hcd *hcd = dev_get_drvdata(&pdev->dev);
 424
 425        usb_remove_hcd(hcd);
 426
 427        mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 428        mem_size = resource_size(mem_res);
 429        release_mem_region(mem_res->start, mem_size);
 430
 431        usb_put_hcd(hcd);
 432
 433        return 0;
 434}
 435
 436static struct platform_driver isp1760_plat_driver = {
 437        .probe  = isp1760_plat_probe,
 438        .remove = __devexit_p(isp1760_plat_remove),
 439        .driver = {
 440                .name   = "isp1760",
 441        },
 442};
 443
 444static int __init isp1760_init(void)
 445{
 446        int ret, any_ret = -ENODEV;
 447
 448        init_kmem_once();
 449
 450        ret = platform_driver_register(&isp1760_plat_driver);
 451        if (!ret)
 452                any_ret = 0;
 453#if defined(CONFIG_OF) && defined(CONFIG_OF_IRQ)
 454        ret = platform_driver_register(&isp1760_of_driver);
 455        if (!ret)
 456                any_ret = 0;
 457#endif
 458#ifdef CONFIG_PCI
 459        ret = pci_register_driver(&isp1761_pci_driver);
 460        if (!ret)
 461                any_ret = 0;
 462#endif
 463
 464        if (any_ret)
 465                deinit_kmem_cache();
 466        return any_ret;
 467}
 468module_init(isp1760_init);
 469
 470static void __exit isp1760_exit(void)
 471{
 472        platform_driver_unregister(&isp1760_plat_driver);
 473#if defined(CONFIG_OF) && defined(CONFIG_OF_IRQ)
 474        platform_driver_unregister(&isp1760_of_driver);
 475#endif
 476#ifdef CONFIG_PCI
 477        pci_unregister_driver(&isp1761_pci_driver);
 478#endif
 479        deinit_kmem_cache();
 480}
 481module_exit(isp1760_exit);
 482