diff options
author | Manjunath Goudar <manjunath.goudar@linaro.org> | 2013-05-28 09:04:49 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2013-05-30 08:36:03 -0400 |
commit | 95e44d44fc29b3d84a74fc5793d8a78ba843c66b (patch) | |
tree | 81bacebeee5edc700f21ab0fea573b6d1327eadd /drivers | |
parent | f467ff4c7dd736b4a3c7e715efed763c0b021838 (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.c | 105 | ||||
-rw-r--r-- | drivers/usb/host/ohci-hub.c | 1 | ||||
-rw-r--r-- | drivers/usb/host/ohci-pci.c | 7 | ||||
-rw-r--r-- | drivers/usb/host/ohci.h | 17 |
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 | ||
81 | static void ohci_dump (struct ohci_hcd *ohci, int verbose); | 81 | static void ohci_dump (struct ohci_hcd *ohci, int verbose); |
82 | static int ohci_init (struct ohci_hcd *ohci); | ||
83 | static void ohci_stop (struct usb_hcd *hcd); | 82 | static void ohci_stop (struct usb_hcd *hcd); |
84 | |||
85 | #if defined(CONFIG_PM) || defined(CONFIG_PCI) | ||
86 | static int ohci_restart (struct ohci_hcd *ohci); | ||
87 | #endif | ||
88 | |||
89 | #ifdef CONFIG_PCI | 83 | #ifdef CONFIG_PCI |
90 | static void sb800_prefetch(struct ohci_hcd *ohci, int on); | 84 | static 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 | |||
771 | int 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 | } | ||
779 | EXPORT_SYMBOL_GPL(ohci_setup); | ||
780 | |||
781 | /* ohci_start routine for generic controller start of all OHCI bus glue */ | ||
782 | static 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 */ |
956 | static int ohci_restart (struct ohci_hcd *ohci) | 976 | int 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 | } |
1036 | EXPORT_SYMBOL_GPL(ohci_restart); | ||
1015 | 1037 | ||
1016 | #endif | 1038 | #endif |
1017 | 1039 | ||
1018 | #ifdef CONFIG_PM | 1040 | #ifdef CONFIG_PM |
1019 | 1041 | ||
1020 | static int __maybe_unused ohci_suspend(struct usb_hcd *hcd, bool do_wakeup) | 1042 | int 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 | } |
1060 | EXPORT_SYMBOL_GPL(ohci_suspend); | ||
1038 | 1061 | ||
1039 | 1062 | ||
1040 | static int __maybe_unused ohci_resume(struct usb_hcd *hcd, bool hibernated) | 1063 | int 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 | } |
1111 | EXPORT_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 | ||
1122 | static 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 | |||
1165 | void 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 | } | ||
1176 | EXPORT_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); } |
719 | static inline u32 roothub_portstatus (struct ohci_hcd *hc, int i) | 719 | static 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 | |||
724 | struct ohci_driver_overrides { | ||
725 | const char *product_desc; | ||
726 | size_t extra_priv_size; | ||
727 | int (*reset)(struct usb_hcd *hcd); | ||
728 | }; | ||
729 | |||
730 | extern void ohci_init_driver(struct hc_driver *drv, | ||
731 | const struct ohci_driver_overrides *over); | ||
732 | extern int ohci_restart(struct ohci_hcd *ohci); | ||
733 | extern int ohci_setup(struct usb_hcd *hcd); | ||
734 | #ifdef CONFIG_PM | ||
735 | extern int ohci_suspend(struct usb_hcd *hcd, bool do_wakeup); | ||
736 | extern int ohci_resume(struct usb_hcd *hcd, bool hibernated); | ||
737 | #endif | ||