Re: [RFC][PATCH 0/4 v4] usb: host: ehci-platform: add platform specific .power callback
Hi Alan, Felipe, Greg These are v4 of ehci/ohci-platform patches Kuninori Morimoto (4): usb: host: ehci-platform: BUG_ON() to WARN_ON() on probe usb: host: ohci-platform: BUG_ON() to WARN_ON() on probe usb: host: ehci-platform: add platform specific power callback usb: host: ohci-platform: add platform specific power callback drivers/usb/host/ehci-platform.c | 46 ++--- drivers/usb/host/ohci-platform.c | 42 -- include/linux/usb/ehci_pdriver.h |8 ++ include/linux/usb/ohci_pdriver.h |8 ++ 4 files changed, 97 insertions(+), 7 deletions(-) -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RFC][PATCH 0/4 v3] usb: host: ehci-platform: add platform specific .power callback
Hi Alan, Felipe, Greg These are v3 of ehci/ohci-platform patches Kuninori Morimoto (4): usb: host: ehci-platform: BUG_ON() to WARN_ON() on probe usb: host: ohci-platform: BUG_ON() to WARN_ON() on probe usb: host: ehci-platform: add platform specific power callback usb: host: ohci-platform: add platform specific power callback drivers/usb/host/ehci-platform.c | 56 ++--- drivers/usb/host/ohci-platform.c | 44 + include/linux/usb/ehci_pdriver.h |5 +++ include/linux/usb/ohci_pdriver.h |5 +++ 4 files changed, 93 insertions(+), 17 deletions(-) -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[RFC][PATCH 2/4 v3] usb: host: ohci-platform: BUG_ON() to WARN_ON() on probe
We should avoid using BUG_ON() in drivers. This patch switch to use WARN_ON() from BUG_ON(), and avoid NULL pointer access by new macro. Signed-off-by: Kuninori Morimoto kuninori.morimoto...@renesas.com --- v2 - v3 - BUG_ON - WARN_ON drivers/usb/host/ohci-platform.c | 10 ++ 1 files changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/usb/host/ohci-platform.c b/drivers/usb/host/ohci-platform.c index 670c705..d2893e6 100644 --- a/drivers/usb/host/ohci-platform.c +++ b/drivers/usb/host/ohci-platform.c @@ -16,6 +16,8 @@ #include linux/platform_device.h #include linux/usb/ohci_pdriver.h +#define ohci_pdata_get(pdata, x) ((pdata) ? (pdata)-x : 0) + static int ohci_platform_reset(struct usb_hcd *hcd) { struct platform_device *pdev = to_platform_device(hcd-self.controller); @@ -23,11 +25,11 @@ static int ohci_platform_reset(struct usb_hcd *hcd) struct ohci_hcd *ohci = hcd_to_ohci(hcd); int err; - if (pdata-big_endian_desc) + if (ohci_pdata_get(pdata, big_endian_desc)) ohci-flags |= OHCI_QUIRK_BE_DESC; - if (pdata-big_endian_mmio) + if (ohci_pdata_get(pdata, big_endian_mmio)) ohci-flags |= OHCI_QUIRK_BE_MMIO; - if (pdata-no_big_frame_no) + if (ohci_pdata_get(pdata, no_big_frame_no)) ohci-flags |= OHCI_QUIRK_FRAME_NO; ohci_hcd_init(ohci); @@ -86,7 +88,7 @@ static int __devinit ohci_platform_probe(struct platform_device *dev) int irq; int err = -ENOMEM; - BUG_ON(!dev-dev.platform_data); + WARN_ON(!dev-dev.platform_data); if (usb_disabled()) return -ENODEV; -- 1.7.5.4 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[RFC][PATCH 3/4 v3] 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...@renesas.com --- v2 - v3 - add power multi functions - call it by macro drivers/usb/host/ehci-platform.c | 40 ++--- include/linux/usb/ehci_pdriver.h |5 2 files changed, 41 insertions(+), 4 deletions(-) diff --git a/drivers/usb/host/ehci-platform.c b/drivers/usb/host/ehci-platform.c index db27dfe..bcdb9e4 100644 --- a/drivers/usb/host/ehci-platform.c +++ b/drivers/usb/host/ehci-platform.c @@ -22,6 +22,8 @@ #include linux/usb/ehci_pdriver.h #define ehci_pdata_get(pdata, x) ((pdata) ? (pdata)-x : 0) +#define ehci_pdata_call(pdata, x, args...) \ + ((!(pdata) || !((pdata)-x)) ? 0 : (pdata)-x(args)) static int ehci_platform_reset(struct usb_hcd *hcd) { @@ -84,10 +86,11 @@ static int __devinit ehci_platform_probe(struct platform_device *dev) { struct usb_hcd *hcd; struct resource *res_mem; + struct usb_ehci_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; @@ -103,10 +106,17 @@ static int __devinit ehci_platform_probe(struct platform_device *dev) return -ENXIO; } + /* power ON if platform supported */ + err = ehci_pdata_call(pdata, power_on, dev); + if (err 0) + return err; + hcd = usb_create_hcd(ehci_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); @@ -134,12 +144,16 @@ err_release_region: release_mem_region(hcd-rsrc_start, hcd-rsrc_len); err_put_hcd: usb_put_hcd(hcd); +err_power: + ehci_pdata_call(pdata, power_off, dev); + return err; } static int __devexit ehci_platform_remove(struct platform_device *dev) { struct usb_hcd *hcd = platform_get_drvdata(dev); + struct usb_ehci_pdata *pdata = dev-dev.platform_data; usb_remove_hcd(hcd); iounmap(hcd-regs); @@ -147,6 +161,9 @@ static int __devexit ehci_platform_remove(struct platform_device *dev) usb_put_hcd(hcd); platform_set_drvdata(dev, NULL); + /* power OFF if platform supported */ + ehci_pdata_call(pdata, power_off, dev); + return 0; } @@ -155,14 +172,29 @@ static int __devexit ehci_platform_remove(struct platform_device *dev) static int ehci_platform_suspend(struct device *dev) { struct usb_hcd *hcd = dev_get_drvdata(dev); + struct usb_ehci_pdata *pdata = dev-platform_data; + struct platform_device *pdev = + container_of(dev, struct platform_device, dev); bool do_wakeup = device_may_wakeup(dev); + int ret; - return ehci_suspend(hcd, do_wakeup); + ret = ehci_suspend(hcd, do_wakeup); + + /* power suspend if platform supported */ + ehci_pdata_call(pdata, power_suspend, pdev); + + return ret; } static int ehci_platform_resume(struct device *dev) { struct usb_hcd *hcd = dev_get_drvdata(dev); + struct usb_ehci_pdata *pdata = dev-platform_data; + struct platform_device *pdev = + container_of(dev, struct platform_device, dev); + + /* power resume if platform supported */ + ehci_pdata_call(pdata, power_resume, pdev); ehci_resume(hcd, false); return 0; diff --git a/include/linux/usb/ehci_pdriver.h b/include/linux/usb/ehci_pdriver.h index 1894f42..23a2f38 100644 --- a/include/linux/usb/ehci_pdriver.h +++ b/include/linux/usb/ehci_pdriver.h @@ -41,6 +41,11 @@ struct usb_ehci_pdata { unsignedbig_endian_mmio:1; unsignedport_power_on:1; unsignedport_power_off: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_EHCI_PDRIVER_H */ -- 1.7.5.4 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[RFC][PATCH 4/4 v3] usb: host: ohci-platform: add platform specific power callback
This patch enables to call platform specific power callback function. Signed-off-by: Kuninori Morimoto kuninori.morimoto...@renesas.com --- 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 { unsignedbig_endian_desc:1; unsignedbig_endian_mmio:1; unsignedno_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 majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[RFC][PATCH 1/2 v2] 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...@renesas.com --- drivers/usb/host/ehci-platform.c | 33 + include/linux/usb/ehci_pdriver.h |2 ++ 2 files changed, 31 insertions(+), 4 deletions(-) diff --git a/drivers/usb/host/ehci-platform.c b/drivers/usb/host/ehci-platform.c index 4b1d896..679aa16 100644 --- a/drivers/usb/host/ehci-platform.c +++ b/drivers/usb/host/ehci-platform.c @@ -82,10 +82,11 @@ static int __devinit ehci_platform_probe(struct platform_device *dev) { struct usb_hcd *hcd; struct resource *res_mem; + struct usb_ehci_pdata *pdata = dev-dev.platform_data; int irq; int err = -ENOMEM; - BUG_ON(!dev-dev.platform_data); + BUG_ON(!pdata); if (usb_disabled()) return -ENODEV; @@ -101,10 +102,15 @@ static int __devinit ehci_platform_probe(struct platform_device *dev) return -ENXIO; } + if (pdata-power) /* power enable */ + pdata-power(dev-dev, 0, 1); + hcd = usb_create_hcd(ehci_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); @@ -132,12 +138,17 @@ err_release_region: release_mem_region(hcd-rsrc_start, hcd-rsrc_len); err_put_hcd: usb_put_hcd(hcd); +err_power: + if (pdata-power) /* power disable */ + pdata-power(dev-dev, 0, 0); + return err; } static int __devexit ehci_platform_remove(struct platform_device *dev) { struct usb_hcd *hcd = platform_get_drvdata(dev); + struct usb_ehci_pdata *pdata = dev-dev.platform_data; usb_remove_hcd(hcd); iounmap(hcd-regs); @@ -145,6 +156,9 @@ static int __devexit ehci_platform_remove(struct platform_device *dev) usb_put_hcd(hcd); platform_set_drvdata(dev, NULL); + if (pdata-power) /* power disable */ + pdata-power(dev-dev, 0, 0); + return 0; } @@ -153,14 +167,25 @@ static int __devexit ehci_platform_remove(struct platform_device *dev) static int ehci_platform_suspend(struct device *dev) { struct usb_hcd *hcd = dev_get_drvdata(dev); + struct usb_ehci_pdata *pdata = dev-platform_data; bool do_wakeup = device_may_wakeup(dev); + int ret; - return ehci_suspend(hcd, do_wakeup); + ret = ehci_suspend(hcd, do_wakeup); + + if (pdata-power) /* power disable */ + pdata-power(dev, 1, 0); + + return ret; } static int ehci_platform_resume(struct device *dev) { struct usb_hcd *hcd = dev_get_drvdata(dev); + struct usb_ehci_pdata *pdata = dev-platform_data; + + if (pdata-power) /* power enable */ + pdata-power(dev, 1, 1); ehci_resume(hcd, false); return 0; diff --git a/include/linux/usb/ehci_pdriver.h b/include/linux/usb/ehci_pdriver.h index 1894f42..9164000 100644 --- a/include/linux/usb/ehci_pdriver.h +++ b/include/linux/usb/ehci_pdriver.h @@ -41,6 +41,8 @@ struct usb_ehci_pdata { unsignedbig_endian_mmio:1; unsignedport_power_on:1; unsignedport_power_off:1; + + void (*power)(struct device *dev, int in_pm, int enable); }; #endif /* __USB_CORE_EHCI_PDRIVER_H */ -- 1.7.5.4 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[RFC][PATCH 2/2 v2] usb: host: ohci-platform: add platform specific .power callback
This patch enables to call platform specific power callback function. Signed-off-by: Kuninori Morimoto kuninori.morimoto...@renesas.com --- drivers/usb/host/ohci-platform.c | 29 ++--- include/linux/usb/ohci_pdriver.h |2 ++ 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/drivers/usb/host/ohci-platform.c b/drivers/usb/host/ohci-platform.c index 670c705..03da469 100644 --- a/drivers/usb/host/ohci-platform.c +++ b/drivers/usb/host/ohci-platform.c @@ -83,10 +83,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; - BUG_ON(!dev-dev.platform_data); + BUG_ON(!pdata); if (usb_disabled()) return -ENODEV; @@ -103,10 +104,15 @@ static int __devinit ohci_platform_probe(struct platform_device *dev) return -ENXIO; } + if (pdata-power) /* power enable */ + pdata-power(dev-dev, 0, 1); + 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); @@ -134,12 +140,17 @@ err_release_region: release_mem_region(hcd-rsrc_start, hcd-rsrc_len); err_put_hcd: usb_put_hcd(hcd); +err_power: + if (pdata-power) /* power disable */ + pdata-power(dev-dev, 0, 0); + 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); @@ -147,6 +158,9 @@ static int __devexit ohci_platform_remove(struct platform_device *dev) usb_put_hcd(hcd); platform_set_drvdata(dev, NULL); + if (pdata-power) /* power disable */ + pdata-power(dev-dev, 0, 0); + return 0; } @@ -154,12 +168,21 @@ 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; + + if (pdata-power) /* power disable */ + pdata-power(dev, 1, 0); + 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; + + if (pdata-power) /* power enable */ + pdata-power(dev, 1, 1); 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..6cf973a 100644 --- a/include/linux/usb/ohci_pdriver.h +++ b/include/linux/usb/ohci_pdriver.h @@ -33,6 +33,8 @@ struct usb_ohci_pdata { unsignedbig_endian_desc:1; unsignedbig_endian_mmio:1; unsignedno_big_frame_no:1; + + void (*power)(struct device *dev, int in_pm, int enable); }; #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 majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] usb: host: ehci-platform: add pm_runtime_xx()
Hi Alan, Rafael, Magnus Thank you for your reply The problem is that the ehci-platform driver currently doesn't know anything about clocks or power sources. We need to add that information in a generic fashion, somehow. Until that's done, you can't really use ehci-platform as your driver. So for example, if ehci-platform _did_ know about clocks and power sources, then before calling usb_add_hcd() you would do: ehci_platform_enable_clocks_and_power(dev); pm_runtime_set_active(dev-dev); pm_runtime_enable(dev-dev); But you definitely cannot call pm_runtime_get_aync() or anything similar, because the EHCI core resume routine assumes the controller's clocks are already running and its power supply is at full power. Can you figure out a good way to add clock and power information to the usb_ehci_pdata structure? Something that will work with a large variety of SoC EHCI controllers? It is possible to power-on on platform setup level if Rafael and Magnus don't care this style. Then, I don't need this patch on ehci/ohci driver. 1) power-on on platform setup timing 2) use ehci/ohci driver the other is that add .power callback on usb_ehci_pdata, and control all power on this. -- probe -- if (pdata-power) pdata-power(xxx, 1) usb_add_hcd() -- remove -- usb_remove_hcd() if (pdata-power) pdata-power(xxx, 0) Best regards --- Kuninori Morimoto -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html