Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Manjunath Goudar and committed by
Greg Kroah-Hartman
95e44d44 f467ff4c

+113 -17
+96 -9
drivers/usb/host/ohci-hcd.c
··· 79 79 #include "pci-quirks.h" 80 80 81 81 static void ohci_dump (struct ohci_hcd *ohci, int verbose); 82 - static int ohci_init (struct ohci_hcd *ohci); 83 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 83 #ifdef CONFIG_PCI 90 84 static void sb800_prefetch(struct ohci_hcd *ohci, int on); 91 85 #else ··· 766 772 return 0; 767 773 } 768 774 775 + /* ohci_setup routine for generic controller initialization */ 776 + 777 + int ohci_setup(struct usb_hcd *hcd) 778 + { 779 + struct ohci_hcd *ohci = hcd_to_ohci(hcd); 780 + 781 + ohci_hcd_init(ohci); 782 + 783 + return ohci_init(ohci); 784 + } 785 + EXPORT_SYMBOL_GPL(ohci_setup); 786 + 787 + /* ohci_start routine for generic controller start of all OHCI bus glue */ 788 + static int ohci_start(struct usb_hcd *hcd) 789 + { 790 + struct ohci_hcd *ohci = hcd_to_ohci(hcd); 791 + int ret; 792 + 793 + ret = ohci_run(ohci); 794 + if (ret < 0) { 795 + ohci_err(ohci, "can't start\n"); 796 + ohci_stop(hcd); 797 + } 798 + return ret; 799 + } 800 + 769 801 /*-------------------------------------------------------------------------*/ 770 802 771 803 /* an interrupt happens */ ··· 973 953 #if defined(CONFIG_PM) || defined(CONFIG_PCI) 974 954 975 955 /* must not be called from interrupt context */ 976 - static int ohci_restart (struct ohci_hcd *ohci) 956 + int ohci_restart(struct ohci_hcd *ohci) 977 957 { 978 958 int temp; 979 959 int i; 980 960 struct urb_priv *priv; 981 961 962 + ohci_init(ohci); 982 963 spin_lock_irq(&ohci->lock); 983 964 ohci->rh_state = OHCI_RH_HALTED; 984 965 ··· 1033 1012 ohci_dbg(ohci, "restart complete\n"); 1034 1013 return 0; 1035 1014 } 1015 + EXPORT_SYMBOL_GPL(ohci_restart); 1036 1016 1037 1017 #endif 1038 1018 1039 1019 #ifdef CONFIG_PM 1040 1020 1041 - static int __maybe_unused ohci_suspend(struct usb_hcd *hcd, bool do_wakeup) 1021 + int ohci_suspend(struct usb_hcd *hcd, bool do_wakeup) 1042 1022 { 1043 1023 struct ohci_hcd *ohci = hcd_to_ohci (hcd); 1044 1024 unsigned long flags; ··· 1057 1035 1058 1036 return 0; 1059 1037 } 1038 + EXPORT_SYMBOL_GPL(ohci_suspend); 1060 1039 1061 1040 1062 - static int __maybe_unused ohci_resume(struct usb_hcd *hcd, bool hibernated) 1041 + int ohci_resume(struct usb_hcd *hcd, bool hibernated) 1063 1042 { 1064 1043 struct ohci_hcd *ohci = hcd_to_ohci(hcd); 1065 1044 int port; ··· 1108 1085 1109 1086 return 0; 1110 1087 } 1088 + EXPORT_SYMBOL_GPL(ohci_resume); 1111 1089 1112 1090 #endif 1091 + 1092 + /*-------------------------------------------------------------------------*/ 1093 + 1094 + /* 1095 + * Generic structure: This gets copied for platform drivers so that 1096 + * individual entries can be overridden as needed. 1097 + */ 1098 + 1099 + static const struct hc_driver ohci_hc_driver = { 1100 + .description = hcd_name, 1101 + .product_desc = "OHCI Host Controller", 1102 + .hcd_priv_size = sizeof(struct ohci_hcd), 1103 + 1104 + /* 1105 + * generic hardware linkage 1106 + */ 1107 + .irq = ohci_irq, 1108 + .flags = HCD_MEMORY | HCD_USB11, 1109 + 1110 + /* 1111 + * basic lifecycle operations 1112 + */ 1113 + .reset = ohci_setup, 1114 + .start = ohci_start, 1115 + .stop = ohci_stop, 1116 + .shutdown = ohci_shutdown, 1117 + 1118 + /* 1119 + * managing i/o requests and associated device resources 1120 + */ 1121 + .urb_enqueue = ohci_urb_enqueue, 1122 + .urb_dequeue = ohci_urb_dequeue, 1123 + .endpoint_disable = ohci_endpoint_disable, 1124 + 1125 + /* 1126 + * scheduling support 1127 + */ 1128 + .get_frame_number = ohci_get_frame, 1129 + 1130 + /* 1131 + * root hub support 1132 + */ 1133 + .hub_status_data = ohci_hub_status_data, 1134 + .hub_control = ohci_hub_control, 1135 + #ifdef CONFIG_PM 1136 + .bus_suspend = ohci_bus_suspend, 1137 + .bus_resume = ohci_bus_resume, 1138 + #endif 1139 + .start_port_reset = ohci_start_port_reset, 1140 + }; 1141 + 1142 + void ohci_init_driver(struct hc_driver *drv, 1143 + const struct ohci_driver_overrides *over) 1144 + { 1145 + /* Copy the generic table to drv and then apply the overrides */ 1146 + *drv = ohci_hc_driver; 1147 + 1148 + drv->product_desc = over->product_desc; 1149 + drv->hcd_priv_size += over->extra_priv_size; 1150 + if (over->reset) 1151 + drv->reset = over->reset; 1152 + } 1153 + EXPORT_SYMBOL_GPL(ohci_init_driver); 1113 1154 1114 1155 /*-------------------------------------------------------------------------*/ 1115 1156
-1
drivers/usb/host/ohci-hub.c
··· 176 176 if (status == -EBUSY) { 177 177 if (!autostopped) { 178 178 spin_unlock_irq (&ohci->lock); 179 - (void) ohci_init (ohci); 180 179 status = ohci_restart (ohci); 181 180 182 181 usb_root_hub_lost_power(hcd->self.root_hub);
-7
drivers/usb/host/ohci-pci.c
··· 123 123 struct ohci_hcd *ohci = container_of(work, struct ohci_hcd, nec_work); 124 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 126 status = ohci_restart(ohci); 134 127 if (status != 0) 135 128 ohci_err(ohci, "Restarting NEC controller failed in %s, %d\n",
+17
drivers/usb/host/ohci.h
··· 718 718 { return ohci_readl (hc, &hc->regs->roothub.status); } 719 719 static inline u32 roothub_portstatus (struct ohci_hcd *hc, int i) 720 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