* 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 #include <linux/gpio.h>
+#include <linux/gpio/machine.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
 
 #include "common.h"
 
+/* Name of the GPIO chip used by the OMAP for GPIOs 0..15 */
+#define OMAP_GPIO_LABEL                "gpio-0-15"
+
 /* At OMAP5912 OSK the Ethernet is directly connected to CS1 */
 #define OMAP_OSK_ETHR_START            0x04800300
 
 
 static struct i2c_board_info __initdata osk_i2c_board_info[] = {
        {
+               /* This device will get the name "i2c-tps65010" */
                I2C_BOARD_INFO("tps65010", 0x48),
+               .dev_name = "tps65010",
                .platform_data  = &tps_board,
 
        },
        irq_set_irq_type(gpio_to_irq(62), IRQ_TYPE_EDGE_FALLING);
 }
 
+static struct gpiod_lookup_table osk_usb_gpio_table = {
+       .dev_id = "ohci",
+       .table = {
+               /* Power GPIO on the I2C-attached TPS65010 */
+               GPIO_LOOKUP("i2c-tps65010", 1, "power", GPIO_ACTIVE_HIGH),
+               GPIO_LOOKUP(OMAP_GPIO_LABEL, 9, "overcurrent",
+                           GPIO_ACTIVE_HIGH),
+       },
+};
+
 static struct omap_usb_config osk_usb_config __initdata = {
        /* has usb host connector (A) ... for development it can also
         * be used, with a NONSTANDARD gender-bending cable/dongle, as
        l |= (3 << 1);
        omap_writel(l, USB_TRANSCEIVER_CTRL);
 
+       gpiod_add_lookup_table(&osk_usb_gpio_table);
        omap1_usb_init(&osk_usb_config);
 
        /* irq for tps65010 chip */
 
 #include <linux/clk.h>
 #include <linux/dma-mapping.h>
 #include <linux/err.h>
-#include <linux/gpio.h>
+#include <linux/gpio/consumer.h>
 #include <linux/io.h>
 #include <linux/jiffies.h>
 #include <linux/kernel.h>
 
 #define DRIVER_DESC "OHCI OMAP driver"
 
-#ifdef CONFIG_TPS65010
-#include <linux/mfd/tps65010.h>
-#else
-
-#define LOW    0
-#define HIGH   1
-
-#define GPIO1  1
-
-static inline int tps65010_set_gpio_out_value(unsigned gpio, unsigned value)
-{
-       return 0;
-}
-
-#endif
-
 struct ohci_omap_priv {
        struct clk *usb_host_ck;
        struct clk *usb_dc_ck;
+       struct gpio_desc *power;
+       struct gpio_desc *overcurrent;
 };
 
 static const char hcd_name[] = "ohci-omap";
  * Board specific gang-switched transceiver power on/off.
  * NOTE:  OSK supplies power from DC, not battery.
  */
-static int omap_ohci_transceiver_power(int on)
+static int omap_ohci_transceiver_power(struct ohci_omap_priv *priv, int on)
 {
        if (on) {
                if (machine_is_omap_innovator() && cpu_is_omap1510())
                        __raw_writeb(__raw_readb(INNOVATOR_FPGA_CAM_USB_CONTROL)
                                | ((1 << 5/*usb1*/) | (1 << 3/*usb2*/)),
                               INNOVATOR_FPGA_CAM_USB_CONTROL);
-               else if (machine_is_omap_osk())
-                       tps65010_set_gpio_out_value(GPIO1, LOW);
+               else if (priv->power)
+                       gpiod_set_value(priv->power, 0);
        } else {
                if (machine_is_omap_innovator() && cpu_is_omap1510())
                        __raw_writeb(__raw_readb(INNOVATOR_FPGA_CAM_USB_CONTROL)
                                & ~((1 << 5/*usb1*/) | (1 << 3/*usb2*/)),
                               INNOVATOR_FPGA_CAM_USB_CONTROL);
-               else if (machine_is_omap_osk())
-                       tps65010_set_gpio_out_value(GPIO1, HIGH);
+               else if (priv->power)
+                       gpiod_set_value(priv->power, 1);
        }
 
        return 0;
 
                        /* gpio9 for overcurrent detction */
                        omap_cfg_reg(W8_1610_GPIO9);
-                       gpio_request(9, "OHCI overcurrent");
-                       gpio_direction_input(9);
 
                        /* for paranoia's sake:  disable USB.PUEN */
                        omap_cfg_reg(W4_USB_HIGHZ);
        }
 
        /* FIXME hub_wq hub requests should manage power switching */
-       omap_ohci_transceiver_power(1);
+       omap_ohci_transceiver_power(priv, 1);
 
        /* board init will have already handled HMC and mux setup.
         * any external transceiver should already be initialized
        hcd->rsrc_len = pdev->resource[0].end - pdev->resource[0].start + 1;
        priv = hcd_to_ohci_omap_priv(hcd);
 
+       /* Obtain two optional GPIO lines */
+       priv->power = devm_gpiod_get_optional(&pdev->dev, "power", GPIOD_ASIS);
+       if (IS_ERR(priv->power)) {
+               retval = PTR_ERR(priv->power);
+               goto err_put_hcd;
+       }
+       if (priv->power)
+               gpiod_set_consumer_name(priv->power, "OHCI power");
+
+       /*
+        * This "overcurrent" GPIO line isn't really used in the code,
+        * but has a designated hardware function.
+        * TODO: implement proper overcurrent handling.
+        */
+       priv->overcurrent = devm_gpiod_get_optional(&pdev->dev, "overcurrent",
+                                                   GPIOD_IN);
+       if (IS_ERR(priv->overcurrent)) {
+               retval = PTR_ERR(priv->overcurrent);
+               goto err_put_hcd;
+       }
+       if (priv->overcurrent)
+               gpiod_set_consumer_name(priv->overcurrent, "OHCI overcurrent");
+
        priv->usb_host_ck = clk_get(&pdev->dev, "usb_hhc_ck");
        if (IS_ERR(priv->usb_host_ck)) {
                retval = PTR_ERR(priv->usb_host_ck);
                (void) otg_set_host(hcd->usb_phy->otg, 0);
                usb_put_phy(hcd->usb_phy);
        }
-       if (machine_is_omap_osk())
-               gpio_free(9);
        iounmap(hcd->regs);
        release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
        clk_put(priv->usb_dc_ck);