Skip to content
Navigation Menu
Toggle navigation
Sign in
In this repository
All GitHub Enterprise
↵
Jump to
↵
No suggested jump to results
In this repository
All GitHub Enterprise
↵
Jump to
↵
In this organization
All GitHub Enterprise
↵
Jump to
↵
In this repository
All GitHub Enterprise
↵
Jump to
↵
Sign in
Reseting focus
You signed in with another tab or window.
Reload
to refresh your session.
You signed out in another tab or window.
Reload
to refresh your session.
You switched accounts on another tab or window.
Reload
to refresh your session.
Dismiss alert
{{ message }}
mariux64
/
linux
Public
Notifications
You must be signed in to change notification settings
Fork
0
Star
0
Code
Issues
2
Pull requests
0
Actions
Projects
0
Wiki
Security
Insights
Additional navigation options
Code
Issues
Pull requests
Actions
Projects
Wiki
Security
Insights
Files
d4f09e2
Documentation
arch
block
crypto
drivers
accessibility
acpi
amba
ata
atm
auxdisplay
base
bcma
block
bluetooth
bus
cdrom
char
clk
clocksource
connector
cpufreq
cpuidle
crypto
dca
devfreq
dio
dma
edac
eisa
extcon
firewire
firmware
fmc
gpio
gpu
hid
hsi
hv
hwmon
hwspinlock
i2c
ide
idle
iio
infiniband
input
iommu
ipack
irqchip
isdn
leds
lguest
macintosh
mailbox
md
media
memory
memstick
message
mfd
misc
mmc
mtd
net
nfc
ntb
nubus
of
oprofile
parisc
parport
pci
pcmcia
pinctrl
platform
pnp
power
pps
ps3
ptp
pwm
rapidio
regulator
remoteproc
reset
rpmsg
rtc
s390
sbus
scsi
sfi
sh
sn
spi
ssb
staging
target
tc
thermal
tty
uio
usb
atm
c67x00
chipidea
class
core
dwc3
early
gadget
host
whci
Kconfig
Makefile
bcma-hcd.c
ehci-atmel.c
ehci-dbg.c
ehci-fsl.c
ehci-fsl.h
ehci-grlib.c
ehci-hcd.c
ehci-hub.c
ehci-mem.c
ehci-msm.c
ehci-mv.c
ehci-mxc.c
ehci-octeon.c
ehci-omap.c
ehci-orion.c
ehci-pci.c
ehci-platform.c
ehci-pmcmsp.c
ehci-ppc-of.c
ehci-ps3.c
ehci-q.c
ehci-s5p.c
ehci-sched.c
ehci-sead3.c
ehci-sh.c
ehci-spear.c
ehci-sysfs.c
ehci-tegra.c
ehci-tilegx.c
ehci-timer.c
ehci-w90x900.c
ehci-xilinx-of.c
ehci.h
fhci-dbg.c
fhci-hcd.c
fhci-hub.c
fhci-mem.c
fhci-q.c
fhci-sched.c
fhci-tds.c
fhci.h
fotg210-hcd.c
fotg210.h
fsl-mph-dr-of.c
fusbh200-hcd.c
fusbh200.h
hwa-hc.c
imx21-dbg.c
imx21-hcd.c
imx21-hcd.h
isp116x-hcd.c
isp116x.h
isp1362-hcd.c
isp1362.h
isp1760-hcd.c
isp1760-hcd.h
isp1760-if.c
octeon2-common.c
ohci-at91.c
ohci-da8xx.c
ohci-dbg.c
ohci-ep93xx.c
ohci-exynos.c
ohci-hcd.c
ohci-hub.c
ohci-jz4740.c
ohci-mem.c
ohci-nxp.c
ohci-octeon.c
ohci-omap.c
ohci-omap3.c
ohci-pci.c
ohci-platform.c
ohci-ppc-of.c
ohci-ps3.c
ohci-pxa27x.c
ohci-q.c
ohci-s3c2410.c
ohci-sa1111.c
ohci-sm501.c
ohci-spear.c
ohci-tilegx.c
ohci-tmio.c
ohci.h
oxu210hp-hcd.c
oxu210hp.h
pci-quirks.c
pci-quirks.h
r8a66597-hcd.c
r8a66597.h
sl811-hcd.c
sl811.h
sl811_cs.c
ssb-hcd.c
u132-hcd.c
uhci-debug.c
uhci-grlib.c
uhci-hcd.c
uhci-hcd.h
uhci-hub.c
uhci-pci.c
uhci-platform.c
uhci-q.c
xhci-dbg.c
xhci-ext-caps.h
xhci-hub.c
xhci-mem.c
xhci-pci.c
xhci-plat.c
xhci-ring.c
xhci.c
xhci.h
image
misc
mon
musb
phy
renesas_usbhs
serial
storage
wusbcore
Kconfig
Makefile
README
usb-common.c
usb-skeleton.c
uwb
vfio
vhost
video
virt
virtio
vlynq
vme
w1
watchdog
xen
zorro
Kconfig
Makefile
firmware
fs
include
init
ipc
kernel
lib
mm
net
samples
scripts
security
sound
tools
usr
virt
.gitignore
.mailmap
COPYING
CREDITS
Kbuild
Kconfig
MAINTAINERS
Makefile
README
REPORTING-BUGS
Breadcrumbs
linux
/
drivers
/
usb
/
host
/
isp1760-if.c
Blame
Blame
Latest commit
History
History
478 lines (402 loc) · 11 KB
Breadcrumbs
linux
/
drivers
/
usb
/
host
/
isp1760-if.c
Top
File metadata and controls
Code
Blame
478 lines (402 loc) · 11 KB
Raw
/* * Glue code for the ISP1760 driver and bus * Currently there is support for * - OpenFirmware * - PCI * - PDEV (generic platform device centralized driver model) * * (c) 2007 Sebastian Siewior <bigeasy@linutronix.de> * */ #include <linux/usb.h> #include <linux/io.h> #include <linux/module.h> #include <linux/platform_device.h> #include <linux/usb/isp1760.h> #include <linux/usb/hcd.h> #include "isp1760-hcd.h" #if defined(CONFIG_OF) && defined(CONFIG_OF_IRQ) #include <linux/slab.h> #include <linux/of.h> #include <linux/of_platform.h> #include <linux/of_address.h> #include <linux/of_irq.h> #include <linux/of_gpio.h> #endif #ifdef CONFIG_PCI #include <linux/pci.h> #endif #if defined(CONFIG_OF) && defined(CONFIG_OF_IRQ) struct isp1760 { struct usb_hcd *hcd; int rst_gpio; }; static int of_isp1760_probe(struct platform_device *dev) { struct isp1760 *drvdata; struct device_node *dp = dev->dev.of_node; struct resource *res; struct resource memory; int virq; resource_size_t res_len; int ret; unsigned int devflags = 0; enum of_gpio_flags gpio_flags; u32 bus_width = 0; drvdata = kzalloc(sizeof(*drvdata), GFP_KERNEL); if (!drvdata) return -ENOMEM; ret = of_address_to_resource(dp, 0, &memory); if (ret) { ret = -ENXIO; goto free_data; } res_len = resource_size(&memory); res = request_mem_region(memory.start, res_len, dev_name(&dev->dev)); if (!res) { ret = -EBUSY; goto free_data; } virq = irq_of_parse_and_map(dp, 0); if (!virq) { ret = -ENODEV; goto release_reg; } if (of_device_is_compatible(dp, "nxp,usb-isp1761")) devflags |= ISP1760_FLAG_ISP1761; /* Some systems wire up only 16 of the 32 data lines */ of_property_read_u32(dp, "bus-width", &bus_width); if (bus_width == 16) devflags |= ISP1760_FLAG_BUS_WIDTH_16; if (of_get_property(dp, "port1-otg", NULL) != NULL) devflags |= ISP1760_FLAG_OTG_EN; if (of_get_property(dp, "analog-oc", NULL) != NULL) devflags |= ISP1760_FLAG_ANALOG_OC; if (of_get_property(dp, "dack-polarity", NULL) != NULL) devflags |= ISP1760_FLAG_DACK_POL_HIGH; if (of_get_property(dp, "dreq-polarity", NULL) != NULL) devflags |= ISP1760_FLAG_DREQ_POL_HIGH; drvdata->rst_gpio = of_get_gpio_flags(dp, 0, &gpio_flags); if (gpio_is_valid(drvdata->rst_gpio)) { ret = gpio_request(drvdata->rst_gpio, dev_name(&dev->dev)); if (!ret) { if (!(gpio_flags & OF_GPIO_ACTIVE_LOW)) { devflags |= ISP1760_FLAG_RESET_ACTIVE_HIGH; gpio_direction_output(drvdata->rst_gpio, 0); } else { gpio_direction_output(drvdata->rst_gpio, 1); } } else { drvdata->rst_gpio = ret; } } drvdata->hcd = isp1760_register(memory.start, res_len, virq, IRQF_SHARED, drvdata->rst_gpio, &dev->dev, dev_name(&dev->dev), devflags); if (IS_ERR(drvdata->hcd)) { ret = PTR_ERR(drvdata->hcd); goto free_gpio; } platform_set_drvdata(dev, drvdata); return ret; free_gpio: if (gpio_is_valid(drvdata->rst_gpio)) gpio_free(drvdata->rst_gpio); release_reg: release_mem_region(memory.start, res_len); free_data: kfree(drvdata); return ret; } static int of_isp1760_remove(struct platform_device *dev) { struct isp1760 *drvdata = platform_get_drvdata(dev); usb_remove_hcd(drvdata->hcd); iounmap(drvdata->hcd->regs); release_mem_region(drvdata->hcd->rsrc_start, drvdata->hcd->rsrc_len); usb_put_hcd(drvdata->hcd); if (gpio_is_valid(drvdata->rst_gpio)) gpio_free(drvdata->rst_gpio); kfree(drvdata); return 0; } static const struct of_device_id of_isp1760_match[] = { { .compatible = "nxp,usb-isp1760", }, { .compatible = "nxp,usb-isp1761", }, { }, }; MODULE_DEVICE_TABLE(of, of_isp1760_match); static struct platform_driver isp1760_of_driver = { .driver = { .name = "nxp-isp1760", .owner = THIS_MODULE, .of_match_table = of_isp1760_match, }, .probe = of_isp1760_probe, .remove = of_isp1760_remove, }; #endif #ifdef CONFIG_PCI static int isp1761_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) { u8 latency, limit; __u32 reg_data; int retry_count; struct usb_hcd *hcd; unsigned int devflags = 0; int ret_status = 0; resource_size_t pci_mem_phy0; resource_size_t memlength; u8 __iomem *chip_addr; u8 __iomem *iobase; resource_size_t nxp_pci_io_base; resource_size_t iolength; if (usb_disabled()) return -ENODEV; if (pci_enable_device(dev) < 0) return -ENODEV; if (!dev->irq) return -ENODEV; /* Grab the PLX PCI mem maped port start address we need */ nxp_pci_io_base = pci_resource_start(dev, 0); iolength = pci_resource_len(dev, 0); if (!request_mem_region(nxp_pci_io_base, iolength, "ISP1761 IO MEM")) { printk(KERN_ERR "request region #1\n"); return -EBUSY; } iobase = ioremap_nocache(nxp_pci_io_base, iolength); if (!iobase) { printk(KERN_ERR "ioremap #1\n"); ret_status = -ENOMEM; goto cleanup1; } /* Grab the PLX PCI shared memory of the ISP 1761 we need */ pci_mem_phy0 = pci_resource_start(dev, 3); memlength = pci_resource_len(dev, 3); if (memlength < 0xffff) { printk(KERN_ERR "memory length for this resource is wrong\n"); ret_status = -ENOMEM; goto cleanup2; } if (!request_mem_region(pci_mem_phy0, memlength, "ISP-PCI")) { printk(KERN_ERR "host controller already in use\n"); ret_status = -EBUSY; goto cleanup2; } /* map available memory */ chip_addr = ioremap_nocache(pci_mem_phy0,memlength); if (!chip_addr) { printk(KERN_ERR "Error ioremap failed\n"); ret_status = -ENOMEM; goto cleanup3; } /* bad pci latencies can contribute to overruns */ pci_read_config_byte(dev, PCI_LATENCY_TIMER, &latency); if (latency) { pci_read_config_byte(dev, PCI_MAX_LAT, &limit); if (limit && limit < latency) pci_write_config_byte(dev, PCI_LATENCY_TIMER, limit); } /* Try to check whether we can access Scratch Register of * Host Controller or not. The initial PCI access is retried until * local init for the PCI bridge is completed */ retry_count = 20; reg_data = 0; while ((reg_data != 0xFACE) && retry_count) { /*by default host is in 16bit mode, so * io operations at this stage must be 16 bit * */ writel(0xface, chip_addr + HC_SCRATCH_REG); udelay(100); reg_data = readl(chip_addr + HC_SCRATCH_REG) & 0x0000ffff; retry_count--; } iounmap(chip_addr); /* Host Controller presence is detected by writing to scratch register * and reading back and checking the contents are same or not */ if (reg_data != 0xFACE) { dev_err(&dev->dev, "scratch register mismatch %x\n", reg_data); ret_status = -ENOMEM; goto cleanup3; } pci_set_master(dev); /* configure PLX PCI chip to pass interrupts */ #define PLX_INT_CSR_REG 0x68 reg_data = readl(iobase + PLX_INT_CSR_REG); reg_data |= 0x900; writel(reg_data, iobase + PLX_INT_CSR_REG); dev->dev.dma_mask = NULL; hcd = isp1760_register(pci_mem_phy0, memlength, dev->irq, IRQF_SHARED, -ENOENT, &dev->dev, dev_name(&dev->dev), devflags); if (IS_ERR(hcd)) { ret_status = -ENODEV; goto cleanup3; } /* done with PLX IO access */ iounmap(iobase); release_mem_region(nxp_pci_io_base, iolength); pci_set_drvdata(dev, hcd); return 0; cleanup3: release_mem_region(pci_mem_phy0, memlength); cleanup2: iounmap(iobase); cleanup1: release_mem_region(nxp_pci_io_base, iolength); return ret_status; } static void isp1761_pci_remove(struct pci_dev *dev) { struct usb_hcd *hcd; hcd = pci_get_drvdata(dev); usb_remove_hcd(hcd); iounmap(hcd->regs); release_mem_region(hcd->rsrc_start, hcd->rsrc_len); usb_put_hcd(hcd); pci_disable_device(dev); } static void isp1761_pci_shutdown(struct pci_dev *dev) { printk(KERN_ERR "ips1761_pci_shutdown\n"); } static const struct pci_device_id isp1760_plx [] = { { .class = PCI_CLASS_BRIDGE_OTHER << 8, .class_mask = ~0, .vendor = PCI_VENDOR_ID_PLX, .device = 0x5406, .subvendor = PCI_VENDOR_ID_PLX, .subdevice = 0x9054, }, { } }; MODULE_DEVICE_TABLE(pci, isp1760_plx); static struct pci_driver isp1761_pci_driver = { .name = "isp1760", .id_table = isp1760_plx, .probe = isp1761_pci_probe, .remove = isp1761_pci_remove, .shutdown = isp1761_pci_shutdown, }; #endif static int isp1760_plat_probe(struct platform_device *pdev) { int ret = 0; struct usb_hcd *hcd; struct resource *mem_res; struct resource *irq_res; resource_size_t mem_size; struct isp1760_platform_data *priv = dev_get_platdata(&pdev->dev); unsigned int devflags = 0; unsigned long irqflags = IRQF_SHARED; mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!mem_res) { pr_warning("isp1760: Memory resource not available\n"); ret = -ENODEV; goto out; } mem_size = resource_size(mem_res); if (!request_mem_region(mem_res->start, mem_size, "isp1760")) { pr_warning("isp1760: Cannot reserve the memory resource\n"); ret = -EBUSY; goto out; } irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); if (!irq_res) { pr_warning("isp1760: IRQ resource not available\n"); ret = -ENODEV; goto cleanup; } irqflags |= irq_res->flags & IRQF_TRIGGER_MASK; if (priv) { if (priv->is_isp1761) devflags |= ISP1760_FLAG_ISP1761; if (priv->bus_width_16) devflags |= ISP1760_FLAG_BUS_WIDTH_16; if (priv->port1_otg) devflags |= ISP1760_FLAG_OTG_EN; if (priv->analog_oc) devflags |= ISP1760_FLAG_ANALOG_OC; if (priv->dack_polarity_high) devflags |= ISP1760_FLAG_DACK_POL_HIGH; if (priv->dreq_polarity_high) devflags |= ISP1760_FLAG_DREQ_POL_HIGH; } hcd = isp1760_register(mem_res->start, mem_size, irq_res->start, irqflags, -ENOENT, &pdev->dev, dev_name(&pdev->dev), devflags); platform_set_drvdata(pdev, hcd); if (IS_ERR(hcd)) { pr_warning("isp1760: Failed to register the HCD device\n"); ret = -ENODEV; goto cleanup; } pr_info("ISP1760 USB device initialised\n"); return ret; cleanup: release_mem_region(mem_res->start, mem_size); out: return ret; } static int isp1760_plat_remove(struct platform_device *pdev) { struct resource *mem_res; resource_size_t mem_size; struct usb_hcd *hcd = platform_get_drvdata(pdev); usb_remove_hcd(hcd); mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); mem_size = resource_size(mem_res); release_mem_region(mem_res->start, mem_size); usb_put_hcd(hcd); return 0; } static struct platform_driver isp1760_plat_driver = { .probe = isp1760_plat_probe, .remove = isp1760_plat_remove, .driver = { .name = "isp1760", }, }; static int __init isp1760_init(void) { int ret, any_ret = -ENODEV; init_kmem_once(); ret = platform_driver_register(&isp1760_plat_driver); if (!ret) any_ret = 0; #if defined(CONFIG_OF) && defined(CONFIG_OF_IRQ) ret = platform_driver_register(&isp1760_of_driver); if (!ret) any_ret = 0; #endif #ifdef CONFIG_PCI ret = pci_register_driver(&isp1761_pci_driver); if (!ret) any_ret = 0; #endif if (any_ret) deinit_kmem_cache(); return any_ret; } module_init(isp1760_init); static void __exit isp1760_exit(void) { platform_driver_unregister(&isp1760_plat_driver); #if defined(CONFIG_OF) && defined(CONFIG_OF_IRQ) platform_driver_unregister(&isp1760_of_driver); #endif #ifdef CONFIG_PCI pci_unregister_driver(&isp1761_pci_driver); #endif deinit_kmem_cache(); } module_exit(isp1760_exit);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
You can’t perform that action at this time.