mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-11-25 16:30:53 +07:00
gpio: mmio: add DT support for memory-mapped GPIOs
This patch adds support for defining memory-mapped GPIOs which are compatible with the existing gpio-mmio interface. The generic library provides support for many memory-mapped GPIO controllers that are found in various on-board FPGA and ASIC solutions that are used to control board's switches, LEDs, chip-selects, Ethernet/USB PHY power, etc. For setting GPIOs there are three configurations: 1. single input/output register resource (named "dat"), 2. set/clear pair (named "set" and "clr"), 3. single output register resource and single input resource ("set" and dat"). The configuration is detected by which resources are present. For the single output register, this drives a 1 by setting a bit and a zero by clearing a bit. For the set clr pair, this drives a 1 by setting a bit in the set register and clears it by setting a bit in the clear register. For setting the GPIO direction, there are three configurations: a. simple bidirectional GPIOs that requires no configuration. b. an output direction register (named "dirout") where a 1 bit indicates the GPIO is an output. c. an input direction register (named "dirin") where a 1 bit indicates the GPIO is an input. Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com> Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com> Signed-off-by: Christian Lamparter <chunkeey@googlemail.com> Acked-by: Alexandre Courbot <acourbot@nvidia.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
This commit is contained in:
parent
54b729987b
commit
e698613ada
@ -61,6 +61,8 @@ o ` ~~~~\___/~~~~ ` controller in FPGA is ,.`
|
|||||||
#include <linux/bitops.h>
|
#include <linux/bitops.h>
|
||||||
#include <linux/platform_device.h>
|
#include <linux/platform_device.h>
|
||||||
#include <linux/mod_devicetable.h>
|
#include <linux/mod_devicetable.h>
|
||||||
|
#include <linux/of.h>
|
||||||
|
#include <linux/of_device.h>
|
||||||
|
|
||||||
static void bgpio_write8(void __iomem *reg, unsigned long data)
|
static void bgpio_write8(void __iomem *reg, unsigned long data)
|
||||||
{
|
{
|
||||||
@ -569,6 +571,37 @@ static void __iomem *bgpio_map(struct platform_device *pdev,
|
|||||||
return devm_ioremap_resource(&pdev->dev, r);
|
return devm_ioremap_resource(&pdev->dev, r);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_OF
|
||||||
|
static const struct of_device_id bgpio_of_match[] = {
|
||||||
|
{ }
|
||||||
|
};
|
||||||
|
MODULE_DEVICE_TABLE(of, bgpio_of_match);
|
||||||
|
|
||||||
|
static struct bgpio_pdata *bgpio_parse_dt(struct platform_device *pdev,
|
||||||
|
unsigned long *flags)
|
||||||
|
{
|
||||||
|
struct bgpio_pdata *pdata;
|
||||||
|
|
||||||
|
if (!of_match_device(bgpio_of_match, &pdev->dev))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
pdata = devm_kzalloc(&pdev->dev, sizeof(struct bgpio_pdata),
|
||||||
|
GFP_KERNEL);
|
||||||
|
if (!pdata)
|
||||||
|
return ERR_PTR(-ENOMEM);
|
||||||
|
|
||||||
|
pdata->base = -1;
|
||||||
|
|
||||||
|
return pdata;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
static struct bgpio_pdata *bgpio_parse_dt(struct platform_device *pdev,
|
||||||
|
unsigned long *flags)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_OF */
|
||||||
|
|
||||||
static int bgpio_pdev_probe(struct platform_device *pdev)
|
static int bgpio_pdev_probe(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct device *dev = &pdev->dev;
|
struct device *dev = &pdev->dev;
|
||||||
@ -579,10 +612,19 @@ static int bgpio_pdev_probe(struct platform_device *pdev)
|
|||||||
void __iomem *dirout;
|
void __iomem *dirout;
|
||||||
void __iomem *dirin;
|
void __iomem *dirin;
|
||||||
unsigned long sz;
|
unsigned long sz;
|
||||||
unsigned long flags = pdev->id_entry->driver_data;
|
unsigned long flags = 0;
|
||||||
int err;
|
int err;
|
||||||
struct gpio_chip *gc;
|
struct gpio_chip *gc;
|
||||||
struct bgpio_pdata *pdata = dev_get_platdata(dev);
|
struct bgpio_pdata *pdata;
|
||||||
|
|
||||||
|
pdata = bgpio_parse_dt(pdev, &flags);
|
||||||
|
if (IS_ERR(pdata))
|
||||||
|
return PTR_ERR(pdata);
|
||||||
|
|
||||||
|
if (!pdata) {
|
||||||
|
pdata = dev_get_platdata(dev);
|
||||||
|
flags = pdev->id_entry->driver_data;
|
||||||
|
}
|
||||||
|
|
||||||
r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dat");
|
r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dat");
|
||||||
if (!r)
|
if (!r)
|
||||||
@ -646,6 +688,7 @@ MODULE_DEVICE_TABLE(platform, bgpio_id_table);
|
|||||||
static struct platform_driver bgpio_driver = {
|
static struct platform_driver bgpio_driver = {
|
||||||
.driver = {
|
.driver = {
|
||||||
.name = "basic-mmio-gpio",
|
.name = "basic-mmio-gpio",
|
||||||
|
.of_match_table = of_match_ptr(bgpio_of_match),
|
||||||
},
|
},
|
||||||
.id_table = bgpio_id_table,
|
.id_table = bgpio_id_table,
|
||||||
.probe = bgpio_pdev_probe,
|
.probe = bgpio_pdev_probe,
|
||||||
|
Loading…
Reference in New Issue
Block a user