diff options
-rw-r--r-- | drivers/usb/host/ohci-platform.c | 36 | ||||
-rw-r--r-- | include/linux/usb/ohci_pdriver.h | 8 |
2 files changed, 42 insertions, 2 deletions
diff --git a/drivers/usb/host/ohci-platform.c b/drivers/usb/host/ohci-platform.c index 4c886f938f6..10d85b9d9e9 100644 --- a/drivers/usb/host/ohci-platform.c +++ b/drivers/usb/host/ohci-platform.c | |||
@@ -107,10 +107,18 @@ static int __devinit ohci_platform_probe(struct platform_device *dev) | |||
107 | return -ENXIO; | 107 | return -ENXIO; |
108 | } | 108 | } |
109 | 109 | ||
110 | if (pdata->power_on) { | ||
111 | err = pdata->power_on(dev); | ||
112 | if (err < 0) | ||
113 | return err; | ||
114 | } | ||
115 | |||
110 | hcd = usb_create_hcd(&ohci_platform_hc_driver, &dev->dev, | 116 | hcd = usb_create_hcd(&ohci_platform_hc_driver, &dev->dev, |
111 | dev_name(&dev->dev)); | 117 | dev_name(&dev->dev)); |
112 | if (!hcd) | 118 | if (!hcd) { |
113 | return -ENOMEM; | 119 | err = -ENOMEM; |
120 | goto err_power; | ||
121 | } | ||
114 | 122 | ||
115 | hcd->rsrc_start = res_mem->start; | 123 | hcd->rsrc_start = res_mem->start; |
116 | hcd->rsrc_len = resource_size(res_mem); | 124 | hcd->rsrc_len = resource_size(res_mem); |
@@ -138,12 +146,17 @@ err_release_region: | |||
138 | release_mem_region(hcd->rsrc_start, hcd->rsrc_len); | 146 | release_mem_region(hcd->rsrc_start, hcd->rsrc_len); |
139 | err_put_hcd: | 147 | err_put_hcd: |
140 | usb_put_hcd(hcd); | 148 | usb_put_hcd(hcd); |
149 | err_power: | ||
150 | if (pdata->power_off) | ||
151 | pdata->power_off(dev); | ||
152 | |||
141 | return err; | 153 | return err; |
142 | } | 154 | } |
143 | 155 | ||
144 | static int __devexit ohci_platform_remove(struct platform_device *dev) | 156 | static int __devexit ohci_platform_remove(struct platform_device *dev) |
145 | { | 157 | { |
146 | struct usb_hcd *hcd = platform_get_drvdata(dev); | 158 | struct usb_hcd *hcd = platform_get_drvdata(dev); |
159 | struct usb_ohci_pdata *pdata = dev->dev.platform_data; | ||
147 | 160 | ||
148 | usb_remove_hcd(hcd); | 161 | usb_remove_hcd(hcd); |
149 | iounmap(hcd->regs); | 162 | iounmap(hcd->regs); |
@@ -151,6 +164,9 @@ static int __devexit ohci_platform_remove(struct platform_device *dev) | |||
151 | usb_put_hcd(hcd); | 164 | usb_put_hcd(hcd); |
152 | platform_set_drvdata(dev, NULL); | 165 | platform_set_drvdata(dev, NULL); |
153 | 166 | ||
167 | if (pdata->power_off) | ||
168 | pdata->power_off(dev); | ||
169 | |||
154 | return 0; | 170 | return 0; |
155 | } | 171 | } |
156 | 172 | ||
@@ -158,12 +174,28 @@ static int __devexit ohci_platform_remove(struct platform_device *dev) | |||
158 | 174 | ||
159 | static int ohci_platform_suspend(struct device *dev) | 175 | static int ohci_platform_suspend(struct device *dev) |
160 | { | 176 | { |
177 | struct usb_ohci_pdata *pdata = dev->platform_data; | ||
178 | struct platform_device *pdev = | ||
179 | container_of(dev, struct platform_device, dev); | ||
180 | |||
181 | if (pdata->power_suspend) | ||
182 | pdata->power_suspend(pdev); | ||
183 | |||
161 | return 0; | 184 | return 0; |
162 | } | 185 | } |
163 | 186 | ||
164 | static int ohci_platform_resume(struct device *dev) | 187 | static int ohci_platform_resume(struct device *dev) |
165 | { | 188 | { |
166 | struct usb_hcd *hcd = dev_get_drvdata(dev); | 189 | struct usb_hcd *hcd = dev_get_drvdata(dev); |
190 | struct usb_ohci_pdata *pdata = dev->platform_data; | ||
191 | struct platform_device *pdev = | ||
192 | container_of(dev, struct platform_device, dev); | ||
193 | |||
194 | if (pdata->power_on) { | ||
195 | int err = pdata->power_on(pdev); | ||
196 | if (err < 0) | ||
197 | return err; | ||
198 | } | ||
167 | 199 | ||
168 | ohci_finish_controller_resume(hcd); | 200 | ohci_finish_controller_resume(hcd); |
169 | return 0; | 201 | return 0; |
diff --git a/include/linux/usb/ohci_pdriver.h b/include/linux/usb/ohci_pdriver.h index 2808f2a9cce..74e7755168b 100644 --- a/include/linux/usb/ohci_pdriver.h +++ b/include/linux/usb/ohci_pdriver.h | |||
@@ -33,6 +33,14 @@ struct usb_ohci_pdata { | |||
33 | unsigned big_endian_desc:1; | 33 | unsigned big_endian_desc:1; |
34 | unsigned big_endian_mmio:1; | 34 | unsigned big_endian_mmio:1; |
35 | unsigned no_big_frame_no:1; | 35 | unsigned no_big_frame_no:1; |
36 | |||
37 | /* Turn on all power and clocks */ | ||
38 | int (*power_on)(struct platform_device *pdev); | ||
39 | /* Turn off all power and clocks */ | ||
40 | void (*power_off)(struct platform_device *pdev); | ||
41 | /* Turn on only VBUS suspend power and hotplug detection, | ||
42 | * turn off everything else */ | ||
43 | void (*power_suspend)(struct platform_device *pdev); | ||
36 | }; | 44 | }; |
37 | 45 | ||
38 | #endif /* __USB_CORE_OHCI_PDRIVER_H */ | 46 | #endif /* __USB_CORE_OHCI_PDRIVER_H */ |