[PATCH linux dev-4.7 02/14] gpio: aspeed: Reset to mainline
Andrew Jeffery
andrew at aj.id.au
Fri Feb 3 14:57:04 AEDT 2017
Signed-off-by: Andrew Jeffery <andrew at aj.id.au>
---
drivers/gpio/Kconfig | 13 +++--
drivers/gpio/gpio-aspeed.c | 137 ++++++++++++++++++++-------------------------
2 files changed, 69 insertions(+), 81 deletions(-)
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index a9c816f795ac..094d3a12d9f6 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -128,6 +128,13 @@ config GPIO_AMDPT
driver for GPIO functionality on Promontory IOHub
Require ACPI ASL code to enumerate as a platform device.
+config GPIO_ASPEED
+ tristate "Aspeed GPIO support"
+ depends on (ARCH_ASPEED || COMPILE_TEST) && OF_GPIO
+ select GPIOLIB_IRQCHIP
+ help
+ Say Y here to support Aspeed AST2400 and AST2500 GPIO controllers.
+
config GPIO_ATH79
tristate "Atheros AR71XX/AR724X/AR913X GPIO support"
default y if ATH79
@@ -138,12 +145,6 @@ config GPIO_ATH79
Select this option to enable GPIO driver for
Atheros AR71XX/AR724X/AR913X SoC devices.
-config GPIO_ASPEED
- bool "Aspeed GPIO support"
- depends on (ARCH_ASPEED || COMPILE_TEST) && OF
- select GENERIC_IRQ_CHIP
- help
- Say Y here to support Aspeed AST2400 and AST2500 GPIO controllers.
config GPIO_BCM_KONA
bool "Broadcom Kona GPIO"
diff --git a/drivers/gpio/gpio-aspeed.c b/drivers/gpio/gpio-aspeed.c
index e48bd1ea82d1..03a5925a423c 100644
--- a/drivers/gpio/gpio-aspeed.c
+++ b/drivers/gpio/gpio-aspeed.c
@@ -23,8 +23,6 @@ struct aspeed_gpio {
spinlock_t lock;
void __iomem *base;
int irq;
- struct irq_chip irq_chip;
- struct irq_domain *irq_domain;
};
struct aspeed_gpio_bank {
@@ -84,11 +82,6 @@ static const struct aspeed_gpio_bank aspeed_gpio_banks[] = {
#define GPIO_IRQ_TYPE2 0x0c
#define GPIO_IRQ_STATUS 0x10
-static inline struct aspeed_gpio *to_aspeed_gpio(struct gpio_chip *chip)
-{
- return container_of(chip, struct aspeed_gpio, chip);
-}
-
static const struct aspeed_gpio_bank *to_bank(unsigned int offset)
{
unsigned int bank = GPIO_BANK(offset);
@@ -113,23 +106,24 @@ static void __iomem *bank_irq_reg(struct aspeed_gpio *gpio,
static int aspeed_gpio_get(struct gpio_chip *gc, unsigned int offset)
{
- struct aspeed_gpio *gpio = to_aspeed_gpio(gc);
+ struct aspeed_gpio *gpio = gpiochip_get_data(gc);
const struct aspeed_gpio_bank *bank = to_bank(offset);
return !!(ioread32(bank_val_reg(gpio, bank, GPIO_DATA))
& GPIO_BIT(offset));
}
-static void __aspeed_gpio_set(struct gpio_chip *gc, unsigned int offset, int val)
+static void __aspeed_gpio_set(struct gpio_chip *gc, unsigned int offset,
+ int val)
{
- u32 reg;
- void __iomem *addr;
- struct aspeed_gpio *gpio = to_aspeed_gpio(gc);
+ struct aspeed_gpio *gpio = gpiochip_get_data(gc);
const struct aspeed_gpio_bank *bank = to_bank(offset);
+ void __iomem *addr;
+ u32 reg;
addr = bank_val_reg(gpio, bank, GPIO_DATA);
-
reg = ioread32(addr);
+
if (val)
reg |= GPIO_BIT(offset);
else
@@ -141,7 +135,7 @@ static void __aspeed_gpio_set(struct gpio_chip *gc, unsigned int offset, int val
static void aspeed_gpio_set(struct gpio_chip *gc, unsigned int offset,
int val)
{
- struct aspeed_gpio *gpio = to_aspeed_gpio(gc);
+ struct aspeed_gpio *gpio = gpiochip_get_data(gc);
unsigned long flags;
spin_lock_irqsave(&gpio->lock, flags);
@@ -153,7 +147,7 @@ static void aspeed_gpio_set(struct gpio_chip *gc, unsigned int offset,
static int aspeed_gpio_dir_in(struct gpio_chip *gc, unsigned int offset)
{
- struct aspeed_gpio *gpio = to_aspeed_gpio(gc);
+ struct aspeed_gpio *gpio = gpiochip_get_data(gc);
const struct aspeed_gpio_bank *bank = to_bank(offset);
unsigned long flags;
u32 reg;
@@ -171,7 +165,7 @@ static int aspeed_gpio_dir_in(struct gpio_chip *gc, unsigned int offset)
static int aspeed_gpio_dir_out(struct gpio_chip *gc,
unsigned int offset, int val)
{
- struct aspeed_gpio *gpio = to_aspeed_gpio(gc);
+ struct aspeed_gpio *gpio = gpiochip_get_data(gc);
const struct aspeed_gpio_bank *bank = to_bank(offset);
unsigned long flags;
u32 reg;
@@ -188,6 +182,23 @@ static int aspeed_gpio_dir_out(struct gpio_chip *gc,
return 0;
}
+static int aspeed_gpio_get_direction(struct gpio_chip *gc, unsigned int offset)
+{
+ struct aspeed_gpio *gpio = gpiochip_get_data(gc);
+ const struct aspeed_gpio_bank *bank = to_bank(offset);
+ unsigned long flags;
+ u32 val;
+
+ spin_lock_irqsave(&gpio->lock, flags);
+
+ val = ioread32(bank_val_reg(gpio, bank, GPIO_DIR)) & GPIO_BIT(offset);
+
+ spin_unlock_irqrestore(&gpio->lock, flags);
+
+ return !val;
+
+}
+
static inline int irqd_to_aspeed_gpio_data(struct irq_data *d,
struct aspeed_gpio **gpio,
const struct aspeed_gpio_bank **bank,
@@ -224,7 +235,7 @@ static void aspeed_gpio_irq_ack(struct irq_data *d)
spin_unlock_irqrestore(&gpio->lock, flags);
}
-static void __aspeed_gpio_irq_set_mask(struct irq_data *d, bool set)
+static void aspeed_gpio_irq_set_mask(struct irq_data *d, bool set)
{
const struct aspeed_gpio_bank *bank;
struct aspeed_gpio *gpio;
@@ -253,17 +264,20 @@ static void __aspeed_gpio_irq_set_mask(struct irq_data *d, bool set)
static void aspeed_gpio_irq_mask(struct irq_data *d)
{
- __aspeed_gpio_irq_set_mask(d, false);
+ aspeed_gpio_irq_set_mask(d, false);
}
static void aspeed_gpio_irq_unmask(struct irq_data *d)
{
- __aspeed_gpio_irq_set_mask(d, true);
+ aspeed_gpio_irq_set_mask(d, true);
}
static int aspeed_gpio_set_type(struct irq_data *d, unsigned int type)
{
- u32 type0, type1, type2, bit, reg;
+ u32 type0 = 0;
+ u32 type1 = 0;
+ u32 type2 = 0;
+ u32 bit, reg;
const struct aspeed_gpio_bank *bank;
irq_flow_handler_t handler;
struct aspeed_gpio *gpio;
@@ -275,8 +289,6 @@ static int aspeed_gpio_set_type(struct irq_data *d, unsigned int type)
if (rc)
return -EINVAL;
- type0 = type1 = type2 = 0;
-
switch (type & IRQ_TYPE_SENSE_MASK) {
case IRQ_TYPE_EDGE_BOTH:
type2 |= bit;
@@ -321,26 +333,27 @@ static int aspeed_gpio_set_type(struct irq_data *d, unsigned int type)
static void aspeed_gpio_irq_handler(struct irq_desc *desc)
{
- struct aspeed_gpio *gpio = irq_desc_get_handler_data(desc);
- struct irq_chip *chip = irq_desc_get_chip(desc);
+ struct gpio_chip *gc = irq_desc_get_handler_data(desc);
+ struct irq_chip *ic = irq_desc_get_chip(desc);
+ struct aspeed_gpio *data = gpiochip_get_data(gc);
unsigned int i, p, girq;
unsigned long reg;
- chained_irq_enter(chip, desc);
+ chained_irq_enter(ic, desc);
for (i = 0; i < ARRAY_SIZE(aspeed_gpio_banks); i++) {
const struct aspeed_gpio_bank *bank = &aspeed_gpio_banks[i];
- reg = ioread32(bank_irq_reg(gpio, bank, GPIO_IRQ_STATUS));
+ reg = ioread32(bank_irq_reg(data, bank, GPIO_IRQ_STATUS));
for_each_set_bit(p, ®, 32) {
- girq = irq_find_mapping(gpio->irq_domain, i * 32 + p);
+ girq = irq_find_mapping(gc->irqdomain, i * 32 + p);
generic_handle_irq(girq);
}
}
- chained_irq_exit(chip, desc);
+ chained_irq_exit(ic, desc);
}
static struct irq_chip aspeed_gpio_irqchip = {
@@ -351,39 +364,28 @@ static struct irq_chip aspeed_gpio_irqchip = {
.irq_set_type = aspeed_gpio_set_type,
};
-static int aspeed_gpio_to_irq(struct gpio_chip *chip, unsigned int offset)
-{
- struct aspeed_gpio *gpio = to_aspeed_gpio(chip);
-
- return irq_find_mapping(gpio->irq_domain, offset);
-}
-
-static void aspeed_gpio_setup_irqs(struct aspeed_gpio *gpio,
+static int aspeed_gpio_setup_irqs(struct aspeed_gpio *gpio,
struct platform_device *pdev)
{
- int i, irq;
+ int rc;
- /* request our upstream IRQ */
- gpio->irq = platform_get_irq(pdev, 0);
- if (gpio->irq < 0)
- return;
+ rc = platform_get_irq(pdev, 0);
+ if (rc < 0)
+ return rc;
- /* establish our irq domain to provide IRQs for each extended bank */
- gpio->irq_domain = irq_domain_add_linear(pdev->dev.of_node,
- gpio->chip.ngpio, &irq_domain_simple_ops, NULL);
- if (!gpio->irq_domain)
- return;
+ gpio->irq = rc;
- for (i = 0; i < gpio->chip.ngpio; i++) {
- irq = irq_create_mapping(gpio->irq_domain, i);
- irq_set_chip_data(irq, gpio);
- irq_set_chip_and_handler(irq, &aspeed_gpio_irqchip,
- handle_simple_irq);
- irq_set_probe(irq);
+ rc = gpiochip_irqchip_add(&gpio->chip, &aspeed_gpio_irqchip,
+ 0, handle_bad_irq, IRQ_TYPE_NONE);
+ if (rc) {
+ dev_info(&pdev->dev, "Could not add irqchip\n");
+ return rc;
}
- irq_set_chained_handler_and_data(gpio->irq,
- aspeed_gpio_irq_handler, gpio);
+ gpiochip_set_chained_irqchip(&gpio->chip, &aspeed_gpio_irqchip,
+ gpio->irq, aspeed_gpio_irq_handler);
+
+ return 0;
}
static int aspeed_gpio_request(struct gpio_chip *chip, unsigned int offset)
@@ -407,12 +409,9 @@ static int __init aspeed_gpio_probe(struct platform_device *pdev)
return -ENOMEM;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!res)
- return -ENXIO;
-
gpio->base = devm_ioremap_resource(&pdev->dev, res);
- if (!gpio->base)
- return -ENOMEM;
+ if (IS_ERR(gpio->base))
+ return PTR_ERR(gpio->base);
spin_lock_init(&gpio->lock);
@@ -421,31 +420,19 @@ static int __init aspeed_gpio_probe(struct platform_device *pdev)
gpio->chip.parent = &pdev->dev;
gpio->chip.direction_input = aspeed_gpio_dir_in;
gpio->chip.direction_output = aspeed_gpio_dir_out;
+ gpio->chip.get_direction = aspeed_gpio_get_direction;
gpio->chip.request = aspeed_gpio_request;
gpio->chip.free = aspeed_gpio_free;
gpio->chip.get = aspeed_gpio_get;
gpio->chip.set = aspeed_gpio_set;
- gpio->chip.to_irq = aspeed_gpio_to_irq;
gpio->chip.label = dev_name(&pdev->dev);
gpio->chip.base = -1;
- platform_set_drvdata(pdev, gpio);
-
- rc = gpiochip_add(&gpio->chip);
+ rc = devm_gpiochip_add_data(&pdev->dev, &gpio->chip, gpio);
if (rc < 0)
return rc;
- aspeed_gpio_setup_irqs(gpio, pdev);
-
- return 0;
-}
-
-static int aspeed_gpio_remove(struct platform_device *pdev)
-{
- struct aspeed_gpio *gpio = platform_get_drvdata(pdev);
-
- gpiochip_remove(&gpio->chip);
- return 0;
+ return aspeed_gpio_setup_irqs(gpio, pdev);
}
static const struct of_device_id aspeed_gpio_of_table[] = {
@@ -456,7 +443,6 @@ static const struct of_device_id aspeed_gpio_of_table[] = {
MODULE_DEVICE_TABLE(of, aspeed_gpio_of_table);
static struct platform_driver aspeed_gpio_driver = {
- .remove = aspeed_gpio_remove,
.driver = {
.name = KBUILD_MODNAME,
.of_match_table = aspeed_gpio_of_table,
@@ -466,3 +452,4 @@ static struct platform_driver aspeed_gpio_driver = {
module_platform_driver_probe(aspeed_gpio_driver, aspeed_gpio_probe);
MODULE_DESCRIPTION("Aspeed GPIO Driver");
+MODULE_LICENSE("GPL");
--
2.9.3
More information about the openbmc
mailing list