aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKuninori Morimoto <kuninori.morimoto.gx@renesas.com>2012-08-06 21:08:39 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-08-10 15:05:32 -0400
commit04216bedafb1b3992a6c2b7f1518281d2ba5fc7b (patch)
treea7219c5971f999f8d7a4b2e2a8a7b5790cb82426
parentb6dd245c4594482d46507a0bfd100439be367952 (diff)
usb: host: ehci-platform: add platform specific power callback
This patch enables to call platform specific power callback function. Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> Acked-by: Alan Stern <stern@rowland.harvard.edu> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/usb/host/ehci-platform.c40
-rw-r--r--include/linux/usb/ehci_pdriver.h8
2 files changed, 45 insertions, 3 deletions
diff --git a/drivers/usb/host/ehci-platform.c b/drivers/usb/host/ehci-platform.c
index a2aaef618aea..91acdde8d21f 100644
--- a/drivers/usb/host/ehci-platform.c
+++ b/drivers/usb/host/ehci-platform.c
@@ -105,10 +105,18 @@ static int __devinit ehci_platform_probe(struct platform_device *dev)
105 return -ENXIO; 105 return -ENXIO;
106 } 106 }
107 107
108 if (pdata->power_on) {
109 err = pdata->power_on(dev);
110 if (err < 0)
111 return err;
112 }
113
108 hcd = usb_create_hcd(&ehci_platform_hc_driver, &dev->dev, 114 hcd = usb_create_hcd(&ehci_platform_hc_driver, &dev->dev,
109 dev_name(&dev->dev)); 115 dev_name(&dev->dev));
110 if (!hcd) 116 if (!hcd) {
111 return -ENOMEM; 117 err = -ENOMEM;
118 goto err_power;
119 }
112 120
113 hcd->rsrc_start = res_mem->start; 121 hcd->rsrc_start = res_mem->start;
114 hcd->rsrc_len = resource_size(res_mem); 122 hcd->rsrc_len = resource_size(res_mem);
@@ -136,12 +144,17 @@ err_release_region:
136 release_mem_region(hcd->rsrc_start, hcd->rsrc_len); 144 release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
137err_put_hcd: 145err_put_hcd:
138 usb_put_hcd(hcd); 146 usb_put_hcd(hcd);
147err_power:
148 if (pdata->power_off)
149 pdata->power_off(dev);
150
139 return err; 151 return err;
140} 152}
141 153
142static int __devexit ehci_platform_remove(struct platform_device *dev) 154static int __devexit ehci_platform_remove(struct platform_device *dev)
143{ 155{
144 struct usb_hcd *hcd = platform_get_drvdata(dev); 156 struct usb_hcd *hcd = platform_get_drvdata(dev);
157 struct usb_ehci_pdata *pdata = dev->dev.platform_data;
145 158
146 usb_remove_hcd(hcd); 159 usb_remove_hcd(hcd);
147 iounmap(hcd->regs); 160 iounmap(hcd->regs);
@@ -149,6 +162,9 @@ static int __devexit ehci_platform_remove(struct platform_device *dev)
149 usb_put_hcd(hcd); 162 usb_put_hcd(hcd);
150 platform_set_drvdata(dev, NULL); 163 platform_set_drvdata(dev, NULL);
151 164
165 if (pdata->power_off)
166 pdata->power_off(dev);
167
152 return 0; 168 return 0;
153} 169}
154 170
@@ -157,14 +173,32 @@ static int __devexit ehci_platform_remove(struct platform_device *dev)
157static int ehci_platform_suspend(struct device *dev) 173static int ehci_platform_suspend(struct device *dev)
158{ 174{
159 struct usb_hcd *hcd = dev_get_drvdata(dev); 175 struct usb_hcd *hcd = dev_get_drvdata(dev);
176 struct usb_ehci_pdata *pdata = dev->platform_data;
177 struct platform_device *pdev =
178 container_of(dev, struct platform_device, dev);
160 bool do_wakeup = device_may_wakeup(dev); 179 bool do_wakeup = device_may_wakeup(dev);
180 int ret;
181
182 ret = ehci_suspend(hcd, do_wakeup);
161 183
162 return ehci_suspend(hcd, do_wakeup); 184 if (pdata->power_suspend)
185 pdata->power_suspend(pdev);
186
187 return ret;
163} 188}
164 189
165static int ehci_platform_resume(struct device *dev) 190static int ehci_platform_resume(struct device *dev)
166{ 191{
167 struct usb_hcd *hcd = dev_get_drvdata(dev); 192 struct usb_hcd *hcd = dev_get_drvdata(dev);
193 struct usb_ehci_pdata *pdata = dev->platform_data;
194 struct platform_device *pdev =
195 container_of(dev, struct platform_device, dev);
196
197 if (pdata->power_on) {
198 int err = pdata->power_on(pdev);
199 if (err < 0)
200 return err;
201 }
168 202
169 ehci_resume(hcd, false); 203 ehci_resume(hcd, false);
170 return 0; 204 return 0;
diff --git a/include/linux/usb/ehci_pdriver.h b/include/linux/usb/ehci_pdriver.h
index 1894f42fe3f7..c9d09f8b7ff2 100644
--- a/include/linux/usb/ehci_pdriver.h
+++ b/include/linux/usb/ehci_pdriver.h
@@ -41,6 +41,14 @@ struct usb_ehci_pdata {
41 unsigned big_endian_mmio:1; 41 unsigned big_endian_mmio:1;
42 unsigned port_power_on:1; 42 unsigned port_power_on:1;
43 unsigned port_power_off:1; 43 unsigned port_power_off:1;
44
45 /* Turn on all power and clocks */
46 int (*power_on)(struct platform_device *pdev);
47 /* Turn off all power and clocks */
48 void (*power_off)(struct platform_device *pdev);
49 /* Turn on only VBUS suspend power and hotplug detection,
50 * turn off everything else */
51 void (*power_suspend)(struct platform_device *pdev);
44}; 52};
45 53
46#endif /* __USB_CORE_EHCI_PDRIVER_H */ 54#endif /* __USB_CORE_EHCI_PDRIVER_H */