This patch enables to call platform specific power callback function. Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@xxxxxxxxxxx> --- v2 -> v3 - add power multi functions - call it by macro drivers/usb/host/ohci-platform.c | 36 +++++++++++++++++++++++++++++++++--- include/linux/usb/ohci_pdriver.h | 5 +++++ 2 files changed, 38 insertions(+), 3 deletions(-) diff --git a/drivers/usb/host/ohci-platform.c b/drivers/usb/host/ohci-platform.c index d2893e6..b147680 100644 --- a/drivers/usb/host/ohci-platform.c +++ b/drivers/usb/host/ohci-platform.c @@ -17,6 +17,8 @@ #include <linux/usb/ohci_pdriver.h> #define ohci_pdata_get(pdata, x) ((pdata) ? (pdata)->x : 0) +#define ohci_pdata_call(pdata, x, args...) \ + ((!(pdata) || !((pdata)->x)) ? 0 : (pdata)->x(args)) static int ohci_platform_reset(struct usb_hcd *hcd) { @@ -85,10 +87,11 @@ static int __devinit ohci_platform_probe(struct platform_device *dev) { struct usb_hcd *hcd; struct resource *res_mem; + struct usb_ohci_pdata *pdata = dev->dev.platform_data; int irq; int err = -ENOMEM; - WARN_ON(!dev->dev.platform_data); + WARN_ON(!pdata); if (usb_disabled()) return -ENODEV; @@ -105,10 +108,17 @@ static int __devinit ohci_platform_probe(struct platform_device *dev) return -ENXIO; } + /* power ON if platform supported */ + err = ohci_pdata_call(pdata, power_on, dev); + if (err < 0) + return err; + hcd = usb_create_hcd(&ohci_platform_hc_driver, &dev->dev, dev_name(&dev->dev)); - if (!hcd) - return -ENOMEM; + if (!hcd) { + err = -ENOMEM; + goto err_power; + } hcd->rsrc_start = res_mem->start; hcd->rsrc_len = resource_size(res_mem); @@ -136,12 +146,16 @@ err_release_region: release_mem_region(hcd->rsrc_start, hcd->rsrc_len); err_put_hcd: usb_put_hcd(hcd); +err_power: + ohci_pdata_call(pdata, power_off, dev); + return err; } static int __devexit ohci_platform_remove(struct platform_device *dev) { struct usb_hcd *hcd = platform_get_drvdata(dev); + struct usb_ohci_pdata *pdata = dev->dev.platform_data; usb_remove_hcd(hcd); iounmap(hcd->regs); @@ -149,6 +163,9 @@ static int __devexit ohci_platform_remove(struct platform_device *dev) usb_put_hcd(hcd); platform_set_drvdata(dev, NULL); + /* power OFF if platform supported */ + ohci_pdata_call(pdata, power_off, dev); + return 0; } @@ -156,12 +173,25 @@ static int __devexit ohci_platform_remove(struct platform_device *dev) static int ohci_platform_suspend(struct device *dev) { + struct usb_ohci_pdata *pdata = dev->platform_data; + struct platform_device *pdev = + container_of(dev, struct platform_device, dev); + + /* power suspend if platform supported */ + ohci_pdata_call(pdata, power_suspend, pdev); + return 0; } static int ohci_platform_resume(struct device *dev) { struct usb_hcd *hcd = dev_get_drvdata(dev); + struct usb_ohci_pdata *pdata = dev->platform_data; + struct platform_device *pdev = + container_of(dev, struct platform_device, dev); + + /* power resume if platform supported */ + ohci_pdata_call(pdata, power_resume, pdev); ohci_finish_controller_resume(hcd); return 0; diff --git a/include/linux/usb/ohci_pdriver.h b/include/linux/usb/ohci_pdriver.h index 2808f2a..4562960 100644 --- a/include/linux/usb/ohci_pdriver.h +++ b/include/linux/usb/ohci_pdriver.h @@ -33,6 +33,11 @@ struct usb_ohci_pdata { unsigned big_endian_desc:1; unsigned big_endian_mmio:1; unsigned no_big_frame_no:1; + + int (*power_on)(struct platform_device *pdev); + void (*power_off)(struct platform_device *pdev); + void (*power_suspend)(struct platform_device *pdev); + void (*power_resume)(struct platform_device *pdev); }; #endif /* __USB_CORE_OHCI_PDRIVER_H */ -- 1.7.5.4 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html