aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorManjunath Goudar <manjunath.goudar@linaro.org>2013-05-28 09:04:49 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2013-05-30 08:36:03 -0400
commit95e44d44fc29b3d84a74fc5793d8a78ba843c66b (patch)
tree81bacebeee5edc700f21ab0fea573b6d1327eadd /drivers
parentf467ff4c7dd736b4a3c7e715efed763c0b021838 (diff)
USB: OHCI: prepare to make ohci-hcd a library module
This patch prepares ohci-hcd for being split up into a core library and separate platform driver modules. A generic ohci_hc_driver structure is created, containing all the "standard" values, and a new mechanism is added whereby a driver module can specify a set of overrides to those values. In addition the ohci_restart(),ohci_suspend() and ohci_resume() routines need to be EXPORTed for use by the drivers. Added ohci_setip(() and ohci_start() routine for to start the generic controller rather than each having its own idiosyncratic approach. This allow to clean duplicated code in most of SOC driver In V2: -ohci_hcd_init() ohci_run() and ohci_stop() are not made non-static. -Adds the ohci_setup() and ohci_start() routine. In V3: -purpose of ohci_setup() and ohci_start() function description written in the patch description. -ohci_init() are not made non-static but now called beginning of the ohci_restart(). -ohci_run() signature change reverted back. -unrelated changes removed. -duplicate comment line removed. -inline ohci_suspend() and ohci_resume() is not needed so removed from ohci.h file. In V4: -ohci-init() EXPORTed because it is called by all bus glue modules. -ohci-setup() removed from 1/2 added into 2/2 patch. In V5: -Again ohci_setup() is added and EXPORTed because to replace the ohci_init() from all bus glues. -ohci_init() is not made non-static function. In V6: -ohci_init() call is removed from ohci_quirk_nec_worker(), because it is already called in ohci_restart(). In V8: -ohci_hcd_init() is called by ohci_setup() to make generic ohci initialization in all ohci drivers. Signed-off-by: Manjunath Goudar <manjunath.goudar@linaro.org> Acked-by: Alan Stern <stern@rowland.harvard.edu> Cc: Arnd Bergmann <arnd@arndb.de> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/usb/host/ohci-hcd.c105
-rw-r--r--drivers/usb/host/ohci-hub.c1
-rw-r--r--drivers/usb/host/ohci-pci.c7
-rw-r--r--drivers/usb/host/ohci.h17
4 files changed, 113 insertions, 17 deletions
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
index fc627fd54116..20a632d09f93 100644
--- a/drivers/usb/host/ohci-hcd.c
+++ b/drivers/usb/host/ohci-hcd.c
@@ -79,13 +79,7 @@ static const char hcd_name [] = "ohci_hcd";
79#include "pci-quirks.h" 79#include "pci-quirks.h"
80 80
81static void ohci_dump (struct ohci_hcd *ohci, int verbose); 81static void ohci_dump (struct ohci_hcd *ohci, int verbose);
82static int ohci_init (struct ohci_hcd *ohci);
83static void ohci_stop (struct usb_hcd *hcd); 82static void ohci_stop (struct usb_hcd *hcd);
84
85#if defined(CONFIG_PM) || defined(CONFIG_PCI)
86static int ohci_restart (struct ohci_hcd *ohci);
87#endif
88
89#ifdef CONFIG_PCI 83#ifdef CONFIG_PCI
90static void sb800_prefetch(struct ohci_hcd *ohci, int on); 84static void sb800_prefetch(struct ohci_hcd *ohci, int on);
91#else 85#else
@@ -772,6 +766,32 @@ retry:
772 return 0; 766 return 0;
773} 767}
774 768
769/* ohci_setup routine for generic controller initialization */
770
771int ohci_setup(struct usb_hcd *hcd)
772{
773 struct ohci_hcd *ohci = hcd_to_ohci(hcd);
774
775 ohci_hcd_init(ohci);
776
777 return ohci_init(ohci);
778}
779EXPORT_SYMBOL_GPL(ohci_setup);
780
781/* ohci_start routine for generic controller start of all OHCI bus glue */
782static int ohci_start(struct usb_hcd *hcd)
783{
784 struct ohci_hcd *ohci = hcd_to_ohci(hcd);
785 int ret;
786
787 ret = ohci_run(ohci);
788 if (ret < 0) {
789 ohci_err(ohci, "can't start\n");
790 ohci_stop(hcd);
791 }
792 return ret;
793}
794
775/*-------------------------------------------------------------------------*/ 795/*-------------------------------------------------------------------------*/
776 796
777/* an interrupt happens */ 797/* an interrupt happens */
@@ -953,12 +973,13 @@ static void ohci_stop (struct usb_hcd *hcd)
953#if defined(CONFIG_PM) || defined(CONFIG_PCI) 973#if defined(CONFIG_PM) || defined(CONFIG_PCI)
954 974
955/* must not be called from interrupt context */ 975/* must not be called from interrupt context */
956static int ohci_restart (struct ohci_hcd *ohci) 976int ohci_restart(struct ohci_hcd *ohci)
957{ 977{
958 int temp; 978 int temp;
959 int i; 979 int i;
960 struct urb_priv *priv; 980 struct urb_priv *priv;
961 981
982 ohci_init(ohci);
962 spin_lock_irq(&ohci->lock); 983 spin_lock_irq(&ohci->lock);
963 ohci->rh_state = OHCI_RH_HALTED; 984 ohci->rh_state = OHCI_RH_HALTED;
964 985
@@ -1012,12 +1033,13 @@ static int ohci_restart (struct ohci_hcd *ohci)
1012 ohci_dbg(ohci, "restart complete\n"); 1033 ohci_dbg(ohci, "restart complete\n");
1013 return 0; 1034 return 0;
1014} 1035}
1036EXPORT_SYMBOL_GPL(ohci_restart);
1015 1037
1016#endif 1038#endif
1017 1039
1018#ifdef CONFIG_PM 1040#ifdef CONFIG_PM
1019 1041
1020static int __maybe_unused ohci_suspend(struct usb_hcd *hcd, bool do_wakeup) 1042int ohci_suspend(struct usb_hcd *hcd, bool do_wakeup)
1021{ 1043{
1022 struct ohci_hcd *ohci = hcd_to_ohci (hcd); 1044 struct ohci_hcd *ohci = hcd_to_ohci (hcd);
1023 unsigned long flags; 1045 unsigned long flags;
@@ -1035,9 +1057,10 @@ static int __maybe_unused ohci_suspend(struct usb_hcd *hcd, bool do_wakeup)
1035 1057
1036 return 0; 1058 return 0;
1037} 1059}
1060EXPORT_SYMBOL_GPL(ohci_suspend);
1038 1061
1039 1062
1040static int __maybe_unused ohci_resume(struct usb_hcd *hcd, bool hibernated) 1063int ohci_resume(struct usb_hcd *hcd, bool hibernated)
1041{ 1064{
1042 struct ohci_hcd *ohci = hcd_to_ohci(hcd); 1065 struct ohci_hcd *ohci = hcd_to_ohci(hcd);
1043 int port; 1066 int port;
@@ -1085,8 +1108,72 @@ static int __maybe_unused ohci_resume(struct usb_hcd *hcd, bool hibernated)
1085 1108
1086 return 0; 1109 return 0;
1087} 1110}
1111EXPORT_SYMBOL_GPL(ohci_resume);
1112
1113#endif
1114
1115/*-------------------------------------------------------------------------*/
1116
1117/*
1118 * Generic structure: This gets copied for platform drivers so that
1119 * individual entries can be overridden as needed.
1120 */
1088 1121
1122static const struct hc_driver ohci_hc_driver = {
1123 .description = hcd_name,
1124 .product_desc = "OHCI Host Controller",
1125 .hcd_priv_size = sizeof(struct ohci_hcd),
1126
1127 /*
1128 * generic hardware linkage
1129 */
1130 .irq = ohci_irq,
1131 .flags = HCD_MEMORY | HCD_USB11,
1132
1133 /*
1134 * basic lifecycle operations
1135 */
1136 .reset = ohci_setup,
1137 .start = ohci_start,
1138 .stop = ohci_stop,
1139 .shutdown = ohci_shutdown,
1140
1141 /*
1142 * managing i/o requests and associated device resources
1143 */
1144 .urb_enqueue = ohci_urb_enqueue,
1145 .urb_dequeue = ohci_urb_dequeue,
1146 .endpoint_disable = ohci_endpoint_disable,
1147
1148 /*
1149 * scheduling support
1150 */
1151 .get_frame_number = ohci_get_frame,
1152
1153 /*
1154 * root hub support
1155 */
1156 .hub_status_data = ohci_hub_status_data,
1157 .hub_control = ohci_hub_control,
1158#ifdef CONFIG_PM
1159 .bus_suspend = ohci_bus_suspend,
1160 .bus_resume = ohci_bus_resume,
1089#endif 1161#endif
1162 .start_port_reset = ohci_start_port_reset,
1163};
1164
1165void ohci_init_driver(struct hc_driver *drv,
1166 const struct ohci_driver_overrides *over)
1167{
1168 /* Copy the generic table to drv and then apply the overrides */
1169 *drv = ohci_hc_driver;
1170
1171 drv->product_desc = over->product_desc;
1172 drv->hcd_priv_size += over->extra_priv_size;
1173 if (over->reset)
1174 drv->reset = over->reset;
1175}
1176EXPORT_SYMBOL_GPL(ohci_init_driver);
1090 1177
1091/*-------------------------------------------------------------------------*/ 1178/*-------------------------------------------------------------------------*/
1092 1179
diff --git a/drivers/usb/host/ohci-hub.c b/drivers/usb/host/ohci-hub.c
index 60ff4220e8b4..2347ab83f046 100644
--- a/drivers/usb/host/ohci-hub.c
+++ b/drivers/usb/host/ohci-hub.c
@@ -176,7 +176,6 @@ __acquires(ohci->lock)
176 if (status == -EBUSY) { 176 if (status == -EBUSY) {
177 if (!autostopped) { 177 if (!autostopped) {
178 spin_unlock_irq (&ohci->lock); 178 spin_unlock_irq (&ohci->lock);
179 (void) ohci_init (ohci);
180 status = ohci_restart (ohci); 179 status = ohci_restart (ohci);
181 180
182 usb_root_hub_lost_power(hcd->self.root_hub); 181 usb_root_hub_lost_power(hcd->self.root_hub);
diff --git a/drivers/usb/host/ohci-pci.c b/drivers/usb/host/ohci-pci.c
index 951514ef446d..2c27a5fc4bfe 100644
--- a/drivers/usb/host/ohci-pci.c
+++ b/drivers/usb/host/ohci-pci.c
@@ -123,13 +123,6 @@ static void ohci_quirk_nec_worker(struct work_struct *work)
123 struct ohci_hcd *ohci = container_of(work, struct ohci_hcd, nec_work); 123 struct ohci_hcd *ohci = container_of(work, struct ohci_hcd, nec_work);
124 int status; 124 int status;
125 125
126 status = ohci_init(ohci);
127 if (status != 0) {
128 ohci_err(ohci, "Restarting NEC controller failed in %s, %d\n",
129 "ohci_init", status);
130 return;
131 }
132
133 status = ohci_restart(ohci); 126 status = ohci_restart(ohci);
134 if (status != 0) 127 if (status != 0)
135 ohci_err(ohci, "Restarting NEC controller failed in %s, %d\n", 128 ohci_err(ohci, "Restarting NEC controller failed in %s, %d\n",
diff --git a/drivers/usb/host/ohci.h b/drivers/usb/host/ohci.h
index d3299143d9e2..3b5848222463 100644
--- a/drivers/usb/host/ohci.h
+++ b/drivers/usb/host/ohci.h
@@ -718,3 +718,20 @@ static inline u32 roothub_status (struct ohci_hcd *hc)
718 { return ohci_readl (hc, &hc->regs->roothub.status); } 718 { return ohci_readl (hc, &hc->regs->roothub.status); }
719static inline u32 roothub_portstatus (struct ohci_hcd *hc, int i) 719static inline u32 roothub_portstatus (struct ohci_hcd *hc, int i)
720 { return read_roothub (hc, portstatus [i], 0xffe0fce0); } 720 { return read_roothub (hc, portstatus [i], 0xffe0fce0); }
721
722/* Declarations of things exported for use by ohci platform drivers */
723
724struct ohci_driver_overrides {
725 const char *product_desc;
726 size_t extra_priv_size;
727 int (*reset)(struct usb_hcd *hcd);
728};
729
730extern void ohci_init_driver(struct hc_driver *drv,
731 const struct ohci_driver_overrides *over);
732extern int ohci_restart(struct ohci_hcd *ohci);
733extern int ohci_setup(struct usb_hcd *hcd);
734#ifdef CONFIG_PM
735extern int ohci_suspend(struct usb_hcd *hcd, bool do_wakeup);
736extern int ohci_resume(struct usb_hcd *hcd, bool hibernated);
737#endif