mirror of
https://github.com/edk2-porting/linux-next.git
synced 2024-12-25 21:54:06 +08:00
gpio: langwell: add Intel Merrifield support
This patch implements a better way to handle multiple SoC's and adds Intel Merrifield support to gpio-langwell. It was based on previous work from Ning Li <ning.li@intel.com> Signed-off-by: David Cohen <david.a.cohen@linux.intel.com> Signed-off-by: Fei Yang <fei.yang@intel.com> Signed-off-by: Ning Li <ning.li@intel.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
This commit is contained in:
parent
70b5341138
commit
d56d6b3d7d
@ -37,6 +37,9 @@
|
|||||||
#include <linux/pm_runtime.h>
|
#include <linux/pm_runtime.h>
|
||||||
#include <linux/irqdomain.h>
|
#include <linux/irqdomain.h>
|
||||||
|
|
||||||
|
#define LNW_IRQ_TYPE_EDGE (1 << 0)
|
||||||
|
#define LNW_IRQ_TYPE_LEVEL (1 << 1)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Langwell chip has 64 pins and thus there are 2 32bit registers to control
|
* Langwell chip has 64 pins and thus there are 2 32bit registers to control
|
||||||
* each feature, while Penwell chip has 96 pins for each block, and need 3 32bit
|
* each feature, while Penwell chip has 96 pins for each block, and need 3 32bit
|
||||||
@ -62,6 +65,16 @@ enum GPIO_REG {
|
|||||||
GAFR, /* alt function */
|
GAFR, /* alt function */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* langwell gpio driver data */
|
||||||
|
struct lnw_gpio_ddata {
|
||||||
|
u16 ngpio; /* number of gpio pins */
|
||||||
|
u32 gplr_offset; /* offset of first GPLR register from base */
|
||||||
|
u32 flis_base; /* base address of FLIS registers */
|
||||||
|
u32 flis_len; /* length of FLIS registers */
|
||||||
|
u32 (*get_flis_offset)(int gpio);
|
||||||
|
u32 chip_irq_type; /* chip interrupt type */
|
||||||
|
};
|
||||||
|
|
||||||
struct lnw_gpio {
|
struct lnw_gpio {
|
||||||
struct gpio_chip chip;
|
struct gpio_chip chip;
|
||||||
void __iomem *reg_base;
|
void __iomem *reg_base;
|
||||||
@ -227,13 +240,71 @@ static struct irq_chip lnw_irqchip = {
|
|||||||
.irq_set_type = lnw_irq_type,
|
.irq_set_type = lnw_irq_type,
|
||||||
};
|
};
|
||||||
|
|
||||||
static DEFINE_PCI_DEVICE_TABLE(lnw_gpio_ids) = { /* pin number */
|
static const struct lnw_gpio_ddata gpio_lincroft = {
|
||||||
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x080f), .driver_data = 64 },
|
.ngpio = 64,
|
||||||
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x081f), .driver_data = 96 },
|
};
|
||||||
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x081a), .driver_data = 96 },
|
|
||||||
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x08eb), .driver_data = 96 },
|
static const struct lnw_gpio_ddata gpio_penwell_aon = {
|
||||||
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x08f7), .driver_data = 96 },
|
.ngpio = 96,
|
||||||
{ 0, }
|
.chip_irq_type = LNW_IRQ_TYPE_EDGE,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct lnw_gpio_ddata gpio_penwell_core = {
|
||||||
|
.ngpio = 96,
|
||||||
|
.chip_irq_type = LNW_IRQ_TYPE_EDGE,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct lnw_gpio_ddata gpio_cloverview_aon = {
|
||||||
|
.ngpio = 96,
|
||||||
|
.chip_irq_type = LNW_IRQ_TYPE_EDGE | LNW_IRQ_TYPE_LEVEL,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct lnw_gpio_ddata gpio_cloverview_core = {
|
||||||
|
.ngpio = 96,
|
||||||
|
.chip_irq_type = LNW_IRQ_TYPE_EDGE,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct lnw_gpio_ddata gpio_tangier = {
|
||||||
|
.ngpio = 192,
|
||||||
|
.gplr_offset = 4,
|
||||||
|
.flis_base = 0xff0c0000,
|
||||||
|
.flis_len = 0x8000,
|
||||||
|
.get_flis_offset = NULL,
|
||||||
|
.chip_irq_type = LNW_IRQ_TYPE_EDGE,
|
||||||
|
};
|
||||||
|
|
||||||
|
static DEFINE_PCI_DEVICE_TABLE(lnw_gpio_ids) = {
|
||||||
|
{
|
||||||
|
/* Lincroft */
|
||||||
|
PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x080f),
|
||||||
|
.driver_data = (kernel_ulong_t)&gpio_lincroft,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
/* Penwell AON */
|
||||||
|
PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x081f),
|
||||||
|
.driver_data = (kernel_ulong_t)&gpio_penwell_aon,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
/* Penwell Core */
|
||||||
|
PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x081a),
|
||||||
|
.driver_data = (kernel_ulong_t)&gpio_penwell_core,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
/* Cloverview Aon */
|
||||||
|
PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x08eb),
|
||||||
|
.driver_data = (kernel_ulong_t)&gpio_cloverview_aon,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
/* Cloverview Core */
|
||||||
|
PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x08f7),
|
||||||
|
.driver_data = (kernel_ulong_t)&gpio_cloverview_core,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
/* Tangier */
|
||||||
|
PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x1199),
|
||||||
|
.driver_data = (kernel_ulong_t)&gpio_tangier,
|
||||||
|
},
|
||||||
|
{ 0 }
|
||||||
};
|
};
|
||||||
MODULE_DEVICE_TABLE(pci, lnw_gpio_ids);
|
MODULE_DEVICE_TABLE(pci, lnw_gpio_ids);
|
||||||
|
|
||||||
@ -316,7 +387,7 @@ static int lnw_gpio_probe(struct pci_dev *pdev,
|
|||||||
u32 gpio_base;
|
u32 gpio_base;
|
||||||
u32 irq_base;
|
u32 irq_base;
|
||||||
int retval;
|
int retval;
|
||||||
int ngpio = id->driver_data;
|
struct lnw_gpio_ddata *ddata = (struct lnw_gpio_ddata *)id->driver_data;
|
||||||
|
|
||||||
retval = pcim_enable_device(pdev);
|
retval = pcim_enable_device(pdev);
|
||||||
if (retval)
|
if (retval)
|
||||||
@ -351,14 +422,14 @@ static int lnw_gpio_probe(struct pci_dev *pdev,
|
|||||||
lnw->chip.set = lnw_gpio_set;
|
lnw->chip.set = lnw_gpio_set;
|
||||||
lnw->chip.to_irq = lnw_gpio_to_irq;
|
lnw->chip.to_irq = lnw_gpio_to_irq;
|
||||||
lnw->chip.base = gpio_base;
|
lnw->chip.base = gpio_base;
|
||||||
lnw->chip.ngpio = ngpio;
|
lnw->chip.ngpio = ddata->ngpio;
|
||||||
lnw->chip.can_sleep = 0;
|
lnw->chip.can_sleep = 0;
|
||||||
lnw->pdev = pdev;
|
lnw->pdev = pdev;
|
||||||
|
|
||||||
spin_lock_init(&lnw->lock);
|
spin_lock_init(&lnw->lock);
|
||||||
|
|
||||||
lnw->domain = irq_domain_add_simple(pdev->dev.of_node, ngpio, irq_base,
|
lnw->domain = irq_domain_add_simple(pdev->dev.of_node, ddata->ngpio,
|
||||||
&lnw_gpio_irq_ops, lnw);
|
irq_base, &lnw_gpio_irq_ops, lnw);
|
||||||
if (!lnw->domain)
|
if (!lnw->domain)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user