|
@@ -14,8 +14,8 @@
|
|
|
|
|
|
#include <linux/clk.h>
|
|
|
#include <linux/dma-mapping.h>
|
|
|
+#include <linux/gpio/consumer.h>
|
|
|
#include <linux/of_platform.h>
|
|
|
-#include <linux/of_gpio.h>
|
|
|
#include <linux/platform_device.h>
|
|
|
#include <linux/platform_data/atmel.h>
|
|
|
#include <linux/io.h>
|
|
@@ -39,8 +39,8 @@
|
|
|
|
|
|
#define AT91_MAX_USBH_PORTS 3
|
|
|
struct at91_usbh_data {
|
|
|
- int vbus_pin[AT91_MAX_USBH_PORTS]; /* port power-control pin */
|
|
|
- int overcurrent_pin[AT91_MAX_USBH_PORTS];
|
|
|
+ struct gpio_desc *vbus_pin[AT91_MAX_USBH_PORTS];
|
|
|
+ struct gpio_desc *overcurrent_pin[AT91_MAX_USBH_PORTS];
|
|
|
u8 ports; /* number of ports on root hub */
|
|
|
u8 overcurrent_supported;
|
|
|
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))
|
|
|
return;
|
|
|
|
|
|
- if (!gpio_is_valid(pdata->vbus_pin[port]))
|
|
|
- return;
|
|
|
-
|
|
|
- gpio_set_value(pdata->vbus_pin[port],
|
|
|
- pdata->vbus_pin_active_low[port] ^ enable);
|
|
|
+ gpiod_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)
|
|
@@ -274,11 +271,8 @@ static int ohci_at91_usb_get_power(struct at91_usbh_data *pdata, int port)
|
|
|
if (!valid_port(port))
|
|
|
return -EINVAL;
|
|
|
|
|
|
- if (!gpio_is_valid(pdata->vbus_pin[port]))
|
|
|
- return -EINVAL;
|
|
|
-
|
|
|
- return gpio_get_value(pdata->vbus_pin[port]) ^
|
|
|
- pdata->vbus_pin_active_low[port];
|
|
|
+ return gpiod_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 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
|
|
|
* out the corresponding port */
|
|
|
at91_for_each_port(port) {
|
|
|
- if (gpio_is_valid(pdata->overcurrent_pin[port]) &&
|
|
|
- gpio_to_irq(pdata->overcurrent_pin[port]) == irq) {
|
|
|
- gpio = pdata->overcurrent_pin[port];
|
|
|
+ if (gpiod_to_irq(pdata->overcurrent_pin[port]) == irq)
|
|
|
break;
|
|
|
- }
|
|
|
}
|
|
|
|
|
|
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;
|
|
|
}
|
|
|
|
|
|
- val = gpio_get_value(gpio);
|
|
|
+ val = gpiod_get_value(pdata->overcurrent_pin[port]);
|
|
|
|
|
|
/* When notified of an over-current situation, disable power
|
|
|
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 at91_usbh_data *pdata;
|
|
|
int i;
|
|
|
- int gpio;
|
|
|
int ret;
|
|
|
- enum of_gpio_flags flags;
|
|
|
+ int err;
|
|
|
u32 ports;
|
|
|
|
|
|
/* 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;
|
|
|
|
|
|
at91_for_each_port(i) {
|
|
|
- /*
|
|
|
- * do not configure PIO if not in relation with
|
|
|
- * real USB port on board
|
|
|
- */
|
|
|
- if (i >= pdata->ports) {
|
|
|
- pdata->vbus_pin[i] = -EINVAL;
|
|
|
- pdata->overcurrent_pin[i] = -EINVAL;
|
|
|
+ pdata->vbus_pin[i] = devm_gpiod_get_optional(&pdev->dev,
|
|
|
+ "atmel,vbus-gpio",
|
|
|
+ GPIOD_IN);
|
|
|
+ if (IS_ERR(pdata->vbus_pin[i])) {
|
|
|
+ err = PTR_ERR(pdata->vbus_pin[i]);
|
|
|
+ dev_err(&pdev->dev, "unable to claim gpio \"vbus\": %d\n", err);
|
|
|
continue;
|
|
|
}
|
|
|
|
|
|
- gpio = of_get_named_gpio_flags(np, "atmel,vbus-gpio", 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;
|
|
|
- }
|
|
|
+ pdata->vbus_pin_active_low[i] = gpiod_get_value(pdata->vbus_pin[i]);
|
|
|
|
|
|
ohci_at91_usb_set_power(pdata, i, 1);
|
|
|
}
|
|
@@ -580,37 +548,21 @@ static int ohci_hcd_at91_drv_probe(struct platform_device *pdev)
|
|
|
break;
|
|
|
|
|
|
pdata->overcurrent_pin[i] =
|
|
|
- of_get_named_gpio_flags(np, "atmel,oc-gpio", i, &flags);
|
|
|
-
|
|
|
- if (!gpio_is_valid(pdata->overcurrent_pin[i]))
|
|
|
- continue;
|
|
|
- gpio = pdata->overcurrent_pin[i];
|
|
|
-
|
|
|
- ret = gpio_request(gpio, "ohci_overcurrent");
|
|
|
- if (ret) {
|
|
|
- dev_err(&pdev->dev,
|
|
|
- "can't request overcurrent gpio %d\n",
|
|
|
- gpio);
|
|
|
+ devm_gpiod_get_optional(&pdev->dev,
|
|
|
+ "atmel,oc-gpio", GPIOD_IN);
|
|
|
+ if (IS_ERR(pdata->overcurrent_pin[i])) {
|
|
|
+ err = PTR_ERR(pdata->overcurrent_pin[i]);
|
|
|
+ dev_err(&pdev->dev, "unable to claim gpio \"overcurrent\": %d\n", err);
|
|
|
continue;
|
|
|
}
|
|
|
|
|
|
- ret = gpio_direction_input(gpio);
|
|
|
- if (ret) {
|
|
|
- dev_err(&pdev->dev,
|
|
|
- "can't configure overcurrent gpio %d as input\n",
|
|
|
- gpio);
|
|
|
- gpio_free(gpio);
|
|
|
- continue;
|
|
|
- }
|
|
|
-
|
|
|
- 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");
|
|
|
- }
|
|
|
+ ret = devm_request_irq(&pdev->dev,
|
|
|
+ gpiod_to_irq(pdata->overcurrent_pin[i]),
|
|
|
+ ohci_hcd_at91_overcurrent_irq,
|
|
|
+ IRQF_SHARED,
|
|
|
+ "ohci_overcurrent", pdev);
|
|
|
+ if (ret)
|
|
|
+ dev_info(&pdev->dev, "failed to request gpio \"overcurrent\" IRQ\n");
|
|
|
}
|
|
|
|
|
|
device_init_wakeup(&pdev->dev, 1);
|
|
@@ -623,19 +575,8 @@ static int ohci_hcd_at91_drv_remove(struct platform_device *pdev)
|
|
|
int i;
|
|
|
|
|
|
if (pdata) {
|
|
|
- at91_for_each_port(i) {
|
|
|
- if (!gpio_is_valid(pdata->vbus_pin[i]))
|
|
|
- continue;
|
|
|
+ at91_for_each_port(i)
|
|
|
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);
|