mirror of https://gitee.com/openkylin/linux.git
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:
parent
629dd21988
commit
054d4b7b57
|
@ -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);
|
||||||
|
|
Loading…
Reference in New Issue