aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb')
-rw-r--r--drivers/usb/host/isp1760-hcd.c17
-rw-r--r--drivers/usb/host/isp1760-hcd.h2
-rw-r--r--drivers/usb/host/isp1760-if.c68
3 files changed, 72 insertions, 15 deletions
diff --git a/drivers/usb/host/isp1760-hcd.c b/drivers/usb/host/isp1760-hcd.c
index 5b08bd743acc..27dfab80ed8f 100644
--- a/drivers/usb/host/isp1760-hcd.c
+++ b/drivers/usb/host/isp1760-hcd.c
@@ -24,6 +24,7 @@
24#include <linux/timer.h> 24#include <linux/timer.h>
25#include <asm/unaligned.h> 25#include <asm/unaligned.h>
26#include <asm/cacheflush.h> 26#include <asm/cacheflush.h>
27#include <linux/gpio.h>
27 28
28#include "isp1760-hcd.h" 29#include "isp1760-hcd.h"
29 30
@@ -48,6 +49,8 @@ struct isp1760_hcd {
48 unsigned long reset_done; 49 unsigned long reset_done;
49 unsigned long next_statechange; 50 unsigned long next_statechange;
50 unsigned int devflags; 51 unsigned int devflags;
52
53 int rst_gpio;
51}; 54};
52 55
53static inline struct isp1760_hcd *hcd_to_priv(struct usb_hcd *hcd) 56static inline struct isp1760_hcd *hcd_to_priv(struct usb_hcd *hcd)
@@ -433,6 +436,18 @@ static int isp1760_hc_setup(struct usb_hcd *hcd)
433 int result; 436 int result;
434 u32 scratch, hwmode; 437 u32 scratch, hwmode;
435 438
439 /* low-level chip reset */
440 if (gpio_is_valid(priv->rst_gpio)) {
441 unsigned int rst_lvl;
442
443 rst_lvl = (priv->devflags &
444 ISP1760_FLAG_RESET_ACTIVE_HIGH) ? 1 : 0;
445
446 gpio_set_value(priv->rst_gpio, rst_lvl);
447 mdelay(50);
448 gpio_set_value(priv->rst_gpio, !rst_lvl);
449 }
450
436 /* Setup HW Mode Control: This assumes a level active-low interrupt */ 451 /* Setup HW Mode Control: This assumes a level active-low interrupt */
437 hwmode = HW_DATA_BUS_32BIT; 452 hwmode = HW_DATA_BUS_32BIT;
438 453
@@ -2207,6 +2222,7 @@ void deinit_kmem_cache(void)
2207 2222
2208struct usb_hcd *isp1760_register(phys_addr_t res_start, resource_size_t res_len, 2223struct usb_hcd *isp1760_register(phys_addr_t res_start, resource_size_t res_len,
2209 int irq, unsigned long irqflags, 2224 int irq, unsigned long irqflags,
2225 int rst_gpio,
2210 struct device *dev, const char *busname, 2226 struct device *dev, const char *busname,
2211 unsigned int devflags) 2227 unsigned int devflags)
2212{ 2228{
@@ -2226,6 +2242,7 @@ struct usb_hcd *isp1760_register(phys_addr_t res_start, resource_size_t res_len,
2226 2242
2227 priv = hcd_to_priv(hcd); 2243 priv = hcd_to_priv(hcd);
2228 priv->devflags = devflags; 2244 priv->devflags = devflags;
2245 priv->rst_gpio = rst_gpio;
2229 init_memory(priv); 2246 init_memory(priv);
2230 hcd->regs = ioremap(res_start, res_len); 2247 hcd->regs = ioremap(res_start, res_len);
2231 if (!hcd->regs) { 2248 if (!hcd->regs) {
diff --git a/drivers/usb/host/isp1760-hcd.h b/drivers/usb/host/isp1760-hcd.h
index fda0f2d54e3d..33dc79ccaa6b 100644
--- a/drivers/usb/host/isp1760-hcd.h
+++ b/drivers/usb/host/isp1760-hcd.h
@@ -4,6 +4,7 @@
4/* exports for if */ 4/* exports for if */
5struct usb_hcd *isp1760_register(phys_addr_t res_start, resource_size_t res_len, 5struct usb_hcd *isp1760_register(phys_addr_t res_start, resource_size_t res_len,
6 int irq, unsigned long irqflags, 6 int irq, unsigned long irqflags,
7 int rst_gpio,
7 struct device *dev, const char *busname, 8 struct device *dev, const char *busname,
8 unsigned int devflags); 9 unsigned int devflags);
9int init_kmem_once(void); 10int init_kmem_once(void);
@@ -126,6 +127,7 @@ typedef void (packet_enqueue)(struct usb_hcd *hcd, struct isp1760_qh *qh,
126#define ISP1760_FLAG_ISP1761 0x00000040 /* Chip is ISP1761 */ 127#define ISP1760_FLAG_ISP1761 0x00000040 /* Chip is ISP1761 */
127#define ISP1760_FLAG_INTR_POL_HIGH 0x00000080 /* Interrupt polarity active high */ 128#define ISP1760_FLAG_INTR_POL_HIGH 0x00000080 /* Interrupt polarity active high */
128#define ISP1760_FLAG_INTR_EDGE_TRIG 0x00000100 /* Interrupt edge triggered */ 129#define ISP1760_FLAG_INTR_EDGE_TRIG 0x00000100 /* Interrupt edge triggered */
130#define ISP1760_FLAG_RESET_ACTIVE_HIGH 0x80000000 /* RESET GPIO active high */
129 131
130/* chip memory management */ 132/* chip memory management */
131struct memory_chunk { 133struct memory_chunk {
diff --git a/drivers/usb/host/isp1760-if.c b/drivers/usb/host/isp1760-if.c
index 791792db6e12..2c7fc830c9e4 100644
--- a/drivers/usb/host/isp1760-if.c
+++ b/drivers/usb/host/isp1760-if.c
@@ -18,10 +18,12 @@
18#include "isp1760-hcd.h" 18#include "isp1760-hcd.h"
19 19
20#ifdef CONFIG_OF 20#ifdef CONFIG_OF
21#include <linux/slab.h>
21#include <linux/of.h> 22#include <linux/of.h>
22#include <linux/of_platform.h> 23#include <linux/of_platform.h>
23#include <linux/of_address.h> 24#include <linux/of_address.h>
24#include <linux/of_irq.h> 25#include <linux/of_irq.h>
26#include <linux/of_gpio.h>
25#endif 27#endif
26 28
27#ifdef CONFIG_PCI 29#ifdef CONFIG_PCI
@@ -29,9 +31,14 @@
29#endif 31#endif
30 32
31#ifdef CONFIG_OF 33#ifdef CONFIG_OF
34struct isp1760 {
35 struct usb_hcd *hcd;
36 int rst_gpio;
37};
38
32static int of_isp1760_probe(struct platform_device *dev) 39static int of_isp1760_probe(struct platform_device *dev)
33{ 40{
34 struct usb_hcd *hcd; 41 struct isp1760 *drvdata;
35 struct device_node *dp = dev->dev.of_node; 42 struct device_node *dp = dev->dev.of_node;
36 struct resource *res; 43 struct resource *res;
37 struct resource memory; 44 struct resource memory;
@@ -41,6 +48,11 @@ static int of_isp1760_probe(struct platform_device *dev)
41 int ret; 48 int ret;
42 const unsigned int *prop; 49 const unsigned int *prop;
43 unsigned int devflags = 0; 50 unsigned int devflags = 0;
51 enum of_gpio_flags gpio_flags;
52
53 drvdata = kzalloc(sizeof(*drvdata), GFP_KERNEL);
54 if (!drvdata)
55 return -ENOMEM;
44 56
45 ret = of_address_to_resource(dp, 0, &memory); 57 ret = of_address_to_resource(dp, 0, &memory);
46 if (ret) 58 if (ret)
@@ -80,32 +92,57 @@ static int of_isp1760_probe(struct platform_device *dev)
80 if (of_get_property(dp, "dreq-polarity", NULL) != NULL) 92 if (of_get_property(dp, "dreq-polarity", NULL) != NULL)
81 devflags |= ISP1760_FLAG_DREQ_POL_HIGH; 93 devflags |= ISP1760_FLAG_DREQ_POL_HIGH;
82 94
83 hcd = isp1760_register(memory.start, res_len, virq, 95 drvdata->rst_gpio = of_get_gpio_flags(dp, 0, &gpio_flags);
84 IRQF_SHARED, &dev->dev, dev_name(&dev->dev), 96 if (gpio_is_valid(drvdata->rst_gpio)) {
85 devflags); 97 ret = gpio_request(drvdata->rst_gpio, dev_name(&dev->dev));
86 if (IS_ERR(hcd)) { 98 if (!ret) {
87 ret = PTR_ERR(hcd); 99 if (!(gpio_flags & OF_GPIO_ACTIVE_LOW)) {
88 goto release_reg; 100 devflags |= ISP1760_FLAG_RESET_ACTIVE_HIGH;
101 gpio_direction_output(drvdata->rst_gpio, 0);
102 } else {
103 gpio_direction_output(drvdata->rst_gpio, 1);
104 }
105 } else {
106 drvdata->rst_gpio = ret;
107 }
89 } 108 }
90 109
91 dev_set_drvdata(&dev->dev, hcd); 110 drvdata->hcd = isp1760_register(memory.start, res_len, virq,
111 IRQF_SHARED, drvdata->rst_gpio,
112 &dev->dev, dev_name(&dev->dev),
113 devflags);
114 if (IS_ERR(drvdata->hcd)) {
115 ret = PTR_ERR(drvdata->hcd);
116 goto free_gpio;
117 }
118
119 dev_set_drvdata(&dev->dev, drvdata);
92 return ret; 120 return ret;
93 121
122free_gpio:
123 if (gpio_is_valid(drvdata->rst_gpio))
124 gpio_free(drvdata->rst_gpio);
94release_reg: 125release_reg:
95 release_mem_region(memory.start, res_len); 126 release_mem_region(memory.start, res_len);
127 kfree(drvdata);
96 return ret; 128 return ret;
97} 129}
98 130
99static int of_isp1760_remove(struct platform_device *dev) 131static int of_isp1760_remove(struct platform_device *dev)
100{ 132{
101 struct usb_hcd *hcd = dev_get_drvdata(&dev->dev); 133 struct isp1760 *drvdata = dev_get_drvdata(&dev->dev);
102 134
103 dev_set_drvdata(&dev->dev, NULL); 135 dev_set_drvdata(&dev->dev, NULL);
104 136
105 usb_remove_hcd(hcd); 137 usb_remove_hcd(drvdata->hcd);
106 iounmap(hcd->regs); 138 iounmap(drvdata->hcd->regs);
107 release_mem_region(hcd->rsrc_start, hcd->rsrc_len); 139 release_mem_region(drvdata->hcd->rsrc_start, drvdata->hcd->rsrc_len);
108 usb_put_hcd(hcd); 140 usb_put_hcd(drvdata->hcd);
141
142 if (gpio_is_valid(drvdata->rst_gpio))
143 gpio_free(drvdata->rst_gpio);
144
145 kfree(drvdata);
109 return 0; 146 return 0;
110} 147}
111 148
@@ -242,7 +279,7 @@ static int __devinit isp1761_pci_probe(struct pci_dev *dev,
242 279
243 dev->dev.dma_mask = NULL; 280 dev->dev.dma_mask = NULL;
244 hcd = isp1760_register(pci_mem_phy0, memlength, dev->irq, 281 hcd = isp1760_register(pci_mem_phy0, memlength, dev->irq,
245 IRQF_SHARED, &dev->dev, dev_name(&dev->dev), 282 IRQF_SHARED, -ENOENT, &dev->dev, dev_name(&dev->dev),
246 devflags); 283 devflags);
247 if (IS_ERR(hcd)) { 284 if (IS_ERR(hcd)) {
248 ret_status = -ENODEV; 285 ret_status = -ENODEV;
@@ -353,7 +390,8 @@ static int __devinit isp1760_plat_probe(struct platform_device *pdev)
353 } 390 }
354 391
355 hcd = isp1760_register(mem_res->start, mem_size, irq_res->start, 392 hcd = isp1760_register(mem_res->start, mem_size, irq_res->start,
356 irqflags, &pdev->dev, dev_name(&pdev->dev), devflags); 393 irqflags, -ENOENT,
394 &pdev->dev, dev_name(&pdev->dev), devflags);
357 if (IS_ERR(hcd)) { 395 if (IS_ERR(hcd)) {
358 pr_warning("isp1760: Failed to register the HCD device\n"); 396 pr_warning("isp1760: Failed to register the HCD device\n");
359 ret = -ENODEV; 397 ret = -ENODEV;