usb: ohci-at91: Use descriptor-based gpio APIs

Use the descriptor-based interface to manipulate GPIOs, instead of
the legacy integer-based interface.

Signed-off-by: Wenyou Yang <wenyou.yang@atmel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
Wenyou Yang 2016-09-29 17:59:02 +08:00 committed by Greg Kroah-Hartman
parent 629dd21988
commit 054d4b7b57
1 changed files with 31 additions and 90 deletions

View File

@ -14,8 +14,8 @@
#include <linux/clk.h> #include <linux/clk.h>
#include <linux/dma-mapping.h> #include <linux/dma-mapping.h>
#include <linux/gpio/consumer.h>
#include <linux/of_platform.h> #include <linux/of_platform.h>
#include <linux/of_gpio.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/platform_data/atmel.h> #include <linux/platform_data/atmel.h>
#include <linux/io.h> #include <linux/io.h>
@ -39,8 +39,8 @@
#define AT91_MAX_USBH_PORTS 3 #define AT91_MAX_USBH_PORTS 3
struct at91_usbh_data { struct at91_usbh_data {
int vbus_pin[AT91_MAX_USBH_PORTS]; /* port power-control pin */ struct gpio_desc *vbus_pin[AT91_MAX_USBH_PORTS];
int overcurrent_pin[AT91_MAX_USBH_PORTS]; struct gpio_desc *overcurrent_pin[AT91_MAX_USBH_PORTS];
u8 ports; /* number of ports on root hub */ u8 ports; /* number of ports on root hub */
u8 overcurrent_supported; u8 overcurrent_supported;
u8 vbus_pin_active_low[AT91_MAX_USBH_PORTS]; u8 vbus_pin_active_low[AT91_MAX_USBH_PORTS];
@ -262,11 +262,8 @@ static void ohci_at91_usb_set_power(struct at91_usbh_data *pdata, int port, int
if (!valid_port(port)) if (!valid_port(port))
return; return;
if (!gpio_is_valid(pdata->vbus_pin[port])) gpiod_set_value(pdata->vbus_pin[port],
return; pdata->vbus_pin_active_low[port] ^ enable);
gpio_set_value(pdata->vbus_pin[port],
pdata->vbus_pin_active_low[port] ^ enable);
} }
static int ohci_at91_usb_get_power(struct at91_usbh_data *pdata, int port) static int ohci_at91_usb_get_power(struct at91_usbh_data *pdata, int port)
@ -274,11 +271,8 @@ static int ohci_at91_usb_get_power(struct at91_usbh_data *pdata, int port)
if (!valid_port(port)) if (!valid_port(port))
return -EINVAL; return -EINVAL;
if (!gpio_is_valid(pdata->vbus_pin[port])) return gpiod_get_value(pdata->vbus_pin[port]) ^
return -EINVAL; pdata->vbus_pin_active_low[port];
return gpio_get_value(pdata->vbus_pin[port]) ^
pdata->vbus_pin_active_low[port];
} }
/* /*
@ -468,16 +462,13 @@ static irqreturn_t ohci_hcd_at91_overcurrent_irq(int irq, void *data)
{ {
struct platform_device *pdev = data; struct platform_device *pdev = data;
struct at91_usbh_data *pdata = dev_get_platdata(&pdev->dev); struct at91_usbh_data *pdata = dev_get_platdata(&pdev->dev);
int val, gpio, port; int val, port;
/* From the GPIO notifying the over-current situation, find /* From the GPIO notifying the over-current situation, find
* out the corresponding port */ * out the corresponding port */
at91_for_each_port(port) { at91_for_each_port(port) {
if (gpio_is_valid(pdata->overcurrent_pin[port]) && if (gpiod_to_irq(pdata->overcurrent_pin[port]) == irq)
gpio_to_irq(pdata->overcurrent_pin[port]) == irq) {
gpio = pdata->overcurrent_pin[port];
break; break;
}
} }
if (port == AT91_MAX_USBH_PORTS) { if (port == AT91_MAX_USBH_PORTS) {
@ -485,7 +476,7 @@ static irqreturn_t ohci_hcd_at91_overcurrent_irq(int irq, void *data)
return IRQ_HANDLED; return IRQ_HANDLED;
} }
val = gpio_get_value(gpio); val = gpiod_get_value(pdata->overcurrent_pin[port]);
/* When notified of an over-current situation, disable power /* When notified of an over-current situation, disable power
on the corresponding port, and mark this port in on the corresponding port, and mark this port in
@ -516,9 +507,8 @@ static int ohci_hcd_at91_drv_probe(struct platform_device *pdev)
struct device_node *np = pdev->dev.of_node; struct device_node *np = pdev->dev.of_node;
struct at91_usbh_data *pdata; struct at91_usbh_data *pdata;
int i; int i;
int gpio;
int ret; int ret;
enum of_gpio_flags flags; int err;
u32 ports; u32 ports;
/* Right now device-tree probed devices don't get dma_mask set. /* Right now device-tree probed devices don't get dma_mask set.
@ -539,38 +529,16 @@ static int ohci_hcd_at91_drv_probe(struct platform_device *pdev)
pdata->ports = ports; pdata->ports = ports;
at91_for_each_port(i) { at91_for_each_port(i) {
/* pdata->vbus_pin[i] = devm_gpiod_get_optional(&pdev->dev,
* do not configure PIO if not in relation with "atmel,vbus-gpio",
* real USB port on board GPIOD_IN);
*/ if (IS_ERR(pdata->vbus_pin[i])) {
if (i >= pdata->ports) { err = PTR_ERR(pdata->vbus_pin[i]);
pdata->vbus_pin[i] = -EINVAL; dev_err(&pdev->dev, "unable to claim gpio \"vbus\": %d\n", err);
pdata->overcurrent_pin[i] = -EINVAL;
continue; continue;
} }
gpio = of_get_named_gpio_flags(np, "atmel,vbus-gpio", i, pdata->vbus_pin_active_low[i] = gpiod_get_value(pdata->vbus_pin[i]);
&flags);
pdata->vbus_pin[i] = gpio;
if (!gpio_is_valid(gpio))
continue;
pdata->vbus_pin_active_low[i] = flags & OF_GPIO_ACTIVE_LOW;
ret = gpio_request(gpio, "ohci_vbus");
if (ret) {
dev_err(&pdev->dev,
"can't request vbus gpio %d\n", gpio);
continue;
}
ret = gpio_direction_output(gpio,
!pdata->vbus_pin_active_low[i]);
if (ret) {
dev_err(&pdev->dev,
"can't put vbus gpio %d as output %d\n",
gpio, !pdata->vbus_pin_active_low[i]);
gpio_free(gpio);
continue;
}
ohci_at91_usb_set_power(pdata, i, 1); ohci_at91_usb_set_power(pdata, i, 1);
} }
@ -580,37 +548,21 @@ static int ohci_hcd_at91_drv_probe(struct platform_device *pdev)
break; break;
pdata->overcurrent_pin[i] = pdata->overcurrent_pin[i] =
of_get_named_gpio_flags(np, "atmel,oc-gpio", i, &flags); devm_gpiod_get_optional(&pdev->dev,
"atmel,oc-gpio", GPIOD_IN);
if (!gpio_is_valid(pdata->overcurrent_pin[i])) if (IS_ERR(pdata->overcurrent_pin[i])) {
continue; err = PTR_ERR(pdata->overcurrent_pin[i]);
gpio = pdata->overcurrent_pin[i]; dev_err(&pdev->dev, "unable to claim gpio \"overcurrent\": %d\n", err);
ret = gpio_request(gpio, "ohci_overcurrent");
if (ret) {
dev_err(&pdev->dev,
"can't request overcurrent gpio %d\n",
gpio);
continue; continue;
} }
ret = gpio_direction_input(gpio); ret = devm_request_irq(&pdev->dev,
if (ret) { gpiod_to_irq(pdata->overcurrent_pin[i]),
dev_err(&pdev->dev, ohci_hcd_at91_overcurrent_irq,
"can't configure overcurrent gpio %d as input\n", IRQF_SHARED,
gpio); "ohci_overcurrent", pdev);
gpio_free(gpio); if (ret)
continue; dev_info(&pdev->dev, "failed to request gpio \"overcurrent\" IRQ\n");
}
ret = request_irq(gpio_to_irq(gpio),
ohci_hcd_at91_overcurrent_irq,
IRQF_SHARED, "ohci_overcurrent", pdev);
if (ret) {
gpio_free(gpio);
dev_err(&pdev->dev,
"can't get gpio IRQ for overcurrent\n");
}
} }
device_init_wakeup(&pdev->dev, 1); device_init_wakeup(&pdev->dev, 1);
@ -623,19 +575,8 @@ static int ohci_hcd_at91_drv_remove(struct platform_device *pdev)
int i; int i;
if (pdata) { if (pdata) {
at91_for_each_port(i) { at91_for_each_port(i)
if (!gpio_is_valid(pdata->vbus_pin[i]))
continue;
ohci_at91_usb_set_power(pdata, i, 0); ohci_at91_usb_set_power(pdata, i, 0);
gpio_free(pdata->vbus_pin[i]);
}
at91_for_each_port(i) {
if (!gpio_is_valid(pdata->overcurrent_pin[i]))
continue;
free_irq(gpio_to_irq(pdata->overcurrent_pin[i]), pdev);
gpio_free(pdata->overcurrent_pin[i]);
}
} }
device_init_wakeup(&pdev->dev, 0); device_init_wakeup(&pdev->dev, 0);