mirror of
https://github.com/torvalds/linux.git
synced 2026-06-07 22:14:04 +02:00
usb: gadget: pch_udc: Provide a GPIO line used on Intel Minnowboard (v1)
[ Upstream commit049d3db625] Intel Minnowboard (v1) uses SCH GPIO line SUS7 (i.e. 12) for VBUS sense. Provide a DMI based quirk to have it's being used. Fixes:e20849a8c8("usb: gadget: pch_udc: Convert to use GPIO descriptors") Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> Link: https://lore.kernel.org/r/20210323153626.54908-7-andriy.shevchenko@linux.intel.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
parent
9f6e0fdb15
commit
22ae303805
|
|
@ -7,12 +7,14 @@
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <linux/pci.h>
|
#include <linux/pci.h>
|
||||||
#include <linux/delay.h>
|
#include <linux/delay.h>
|
||||||
|
#include <linux/dmi.h>
|
||||||
#include <linux/errno.h>
|
#include <linux/errno.h>
|
||||||
|
#include <linux/gpio/consumer.h>
|
||||||
|
#include <linux/gpio/machine.h>
|
||||||
#include <linux/list.h>
|
#include <linux/list.h>
|
||||||
#include <linux/interrupt.h>
|
#include <linux/interrupt.h>
|
||||||
#include <linux/usb/ch9.h>
|
#include <linux/usb/ch9.h>
|
||||||
#include <linux/usb/gadget.h>
|
#include <linux/usb/gadget.h>
|
||||||
#include <linux/gpio/consumer.h>
|
|
||||||
#include <linux/irq.h>
|
#include <linux/irq.h>
|
||||||
|
|
||||||
#define PCH_VBUS_PERIOD 3000 /* VBUS polling period (msec) */
|
#define PCH_VBUS_PERIOD 3000 /* VBUS polling period (msec) */
|
||||||
|
|
@ -1359,6 +1361,43 @@ static irqreturn_t pch_vbus_gpio_irq(int irq, void *data)
|
||||||
return IRQ_HANDLED;
|
return IRQ_HANDLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct gpiod_lookup_table minnowboard_udc_gpios = {
|
||||||
|
.dev_id = "0000:02:02.4",
|
||||||
|
.table = {
|
||||||
|
GPIO_LOOKUP("sch_gpio.33158", 12, NULL, GPIO_ACTIVE_HIGH),
|
||||||
|
{}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct dmi_system_id pch_udc_gpio_dmi_table[] = {
|
||||||
|
{
|
||||||
|
.ident = "MinnowBoard",
|
||||||
|
.matches = {
|
||||||
|
DMI_MATCH(DMI_BOARD_NAME, "MinnowBoard"),
|
||||||
|
},
|
||||||
|
.driver_data = &minnowboard_udc_gpios,
|
||||||
|
},
|
||||||
|
{ }
|
||||||
|
};
|
||||||
|
|
||||||
|
static void pch_vbus_gpio_remove_table(void *table)
|
||||||
|
{
|
||||||
|
gpiod_remove_lookup_table(table);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int pch_vbus_gpio_add_table(struct pch_udc_dev *dev)
|
||||||
|
{
|
||||||
|
struct device *d = &dev->pdev->dev;
|
||||||
|
const struct dmi_system_id *dmi;
|
||||||
|
|
||||||
|
dmi = dmi_first_match(pch_udc_gpio_dmi_table);
|
||||||
|
if (!dmi)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
gpiod_add_lookup_table(dmi->driver_data);
|
||||||
|
return devm_add_action_or_reset(d, pch_vbus_gpio_remove_table, dmi->driver_data);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* pch_vbus_gpio_init() - This API initializes GPIO port detecting VBUS.
|
* pch_vbus_gpio_init() - This API initializes GPIO port detecting VBUS.
|
||||||
* @dev: Reference to the driver structure
|
* @dev: Reference to the driver structure
|
||||||
|
|
@ -1377,8 +1416,12 @@ static int pch_vbus_gpio_init(struct pch_udc_dev *dev)
|
||||||
dev->vbus_gpio.port = NULL;
|
dev->vbus_gpio.port = NULL;
|
||||||
dev->vbus_gpio.intr = 0;
|
dev->vbus_gpio.intr = 0;
|
||||||
|
|
||||||
|
err = pch_vbus_gpio_add_table(dev);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
/* Retrieve the GPIO line from the USB gadget device */
|
/* Retrieve the GPIO line from the USB gadget device */
|
||||||
gpiod = devm_gpiod_get(d, NULL, GPIOD_IN);
|
gpiod = devm_gpiod_get_optional(d, NULL, GPIOD_IN);
|
||||||
if (IS_ERR(gpiod))
|
if (IS_ERR(gpiod))
|
||||||
return PTR_ERR(gpiod);
|
return PTR_ERR(gpiod);
|
||||||
gpiod_set_consumer_name(gpiod, "pch_vbus");
|
gpiod_set_consumer_name(gpiod, "pch_vbus");
|
||||||
|
|
@ -2888,14 +2931,20 @@ static void pch_udc_pcd_reinit(struct pch_udc_dev *dev)
|
||||||
* @dev: Reference to the driver structure
|
* @dev: Reference to the driver structure
|
||||||
*
|
*
|
||||||
* Return codes:
|
* Return codes:
|
||||||
* 0: Success
|
* 0: Success
|
||||||
|
* -%ERRNO: All kind of errors when retrieving VBUS GPIO
|
||||||
*/
|
*/
|
||||||
static int pch_udc_pcd_init(struct pch_udc_dev *dev)
|
static int pch_udc_pcd_init(struct pch_udc_dev *dev)
|
||||||
{
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
pch_udc_init(dev);
|
pch_udc_init(dev);
|
||||||
pch_udc_pcd_reinit(dev);
|
pch_udc_pcd_reinit(dev);
|
||||||
pch_vbus_gpio_init(dev);
|
|
||||||
return 0;
|
ret = pch_vbus_gpio_init(dev);
|
||||||
|
if (ret)
|
||||||
|
pch_udc_exit(dev);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -3097,16 +3146,10 @@ static int pch_udc_probe(struct pci_dev *pdev,
|
||||||
|
|
||||||
dev->base_addr = pcim_iomap_table(pdev)[bar];
|
dev->base_addr = pcim_iomap_table(pdev)[bar];
|
||||||
|
|
||||||
/*
|
|
||||||
* FIXME: add a GPIO descriptor table to pdev.dev using
|
|
||||||
* gpiod_add_descriptor_table() from <linux/gpio/machine.h> based on
|
|
||||||
* the PCI subsystem ID. The system-dependent GPIO is necessary for
|
|
||||||
* VBUS operation.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* initialize the hardware */
|
/* initialize the hardware */
|
||||||
if (pch_udc_pcd_init(dev))
|
retval = pch_udc_pcd_init(dev);
|
||||||
return -ENODEV;
|
if (retval)
|
||||||
|
return retval;
|
||||||
|
|
||||||
pci_enable_msi(pdev);
|
pci_enable_msi(pdev);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user