From 244b2c5ca8b14627e4a17755e5922221e121c771 Mon Sep 17 00:00:00 2001
From: hc <hc@nodka.com>
Date: Wed, 09 Oct 2024 06:15:07 +0000
Subject: [PATCH] change system file
---
kernel/drivers/pinctrl/nomadik/pinctrl-nomadik.c | 151 ++++++++++++++++++++------------------------------
1 files changed, 61 insertions(+), 90 deletions(-)
diff --git a/kernel/drivers/pinctrl/nomadik/pinctrl-nomadik.c b/kernel/drivers/pinctrl/nomadik/pinctrl-nomadik.c
index f0e7a8c..d80ec0d 100644
--- a/kernel/drivers/pinctrl/nomadik/pinctrl-nomadik.c
+++ b/kernel/drivers/pinctrl/nomadik/pinctrl-nomadik.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0-only
/*
* Generic GPIO driver for logic cells found in the Nomadik SoC
*
@@ -5,10 +6,6 @@
* Copyright (C) 2009 Alessandro Rubini <rubini@unipv.it>
* Rewritten based on work by Prafulla WADASKAR <prafulla.wadaskar@st.com>
* Copyright (C) 2011-2013 Linus Walleij <linus.walleij@linaro.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
*/
#include <linux/kernel.h>
#include <linux/init.h>
@@ -17,7 +14,7 @@
#include <linux/io.h>
#include <linux/clk.h>
#include <linux/err.h>
-#include <linux/gpio.h>
+#include <linux/gpio/driver.h>
#include <linux/spinlock.h>
#include <linux/interrupt.h>
#include <linux/slab.h>
@@ -203,7 +200,7 @@
#define GPIO_BLOCK_SHIFT 5
#define NMK_GPIO_PER_CHIP (1 << GPIO_BLOCK_SHIFT)
-#define NMK_MAX_BANKS DIV_ROUND_UP(ARCH_NR_GPIOS, NMK_GPIO_PER_CHIP)
+#define NMK_MAX_BANKS DIV_ROUND_UP(512, NMK_GPIO_PER_CHIP)
/* Register in the logic block */
#define NMK_GPIO_DAT 0x00
@@ -251,9 +248,6 @@
void __iomem *addr;
struct clk *clk;
unsigned int bank;
- unsigned int parent_irq;
- int latent_parent_irq;
- u32 (*get_latent_status)(unsigned int bank);
void (*set_ioforce)(bool enable);
spinlock_t lock;
bool sleepmode;
@@ -805,12 +799,18 @@
clk_disable(nmk_chip->clk);
}
-static void __nmk_gpio_irq_handler(struct irq_desc *desc, u32 status)
+static void nmk_gpio_irq_handler(struct irq_desc *desc)
{
struct irq_chip *host_chip = irq_desc_get_chip(desc);
struct gpio_chip *chip = irq_desc_get_handler_data(desc);
+ struct nmk_gpio_chip *nmk_chip = gpiochip_get_data(chip);
+ u32 status;
chained_irq_enter(host_chip, desc);
+
+ clk_enable(nmk_chip->clk);
+ status = readl(nmk_chip->addr + NMK_GPIO_IS);
+ clk_disable(nmk_chip->clk);
while (status) {
int bit = __ffs(status);
@@ -822,28 +822,6 @@
chained_irq_exit(host_chip, desc);
}
-static void nmk_gpio_irq_handler(struct irq_desc *desc)
-{
- struct gpio_chip *chip = irq_desc_get_handler_data(desc);
- struct nmk_gpio_chip *nmk_chip = gpiochip_get_data(chip);
- u32 status;
-
- clk_enable(nmk_chip->clk);
- status = readl(nmk_chip->addr + NMK_GPIO_IS);
- clk_disable(nmk_chip->clk);
-
- __nmk_gpio_irq_handler(desc, status);
-}
-
-static void nmk_gpio_latent_irq_handler(struct irq_desc *desc)
-{
- struct gpio_chip *chip = irq_desc_get_handler_data(desc);
- struct nmk_gpio_chip *nmk_chip = gpiochip_get_data(chip);
- u32 status = nmk_chip->get_latent_status(nmk_chip->bank);
-
- __nmk_gpio_irq_handler(desc, status);
-}
-
/* I/O Functions */
static int nmk_gpio_get_dir(struct gpio_chip *chip, unsigned offset)
@@ -853,11 +831,14 @@
clk_enable(nmk_chip->clk);
- dir = !(readl(nmk_chip->addr + NMK_GPIO_DIR) & BIT(offset));
+ dir = readl(nmk_chip->addr + NMK_GPIO_DIR) & BIT(offset);
clk_disable(nmk_chip->clk);
- return dir;
+ if (dir)
+ return GPIO_LINE_DIRECTION_OUT;
+
+ return GPIO_LINE_DIRECTION_IN;
}
static int nmk_gpio_make_input(struct gpio_chip *chip, unsigned offset)
@@ -950,11 +931,6 @@
[NMK_GPIO_ALT_C+3] = "altC3",
[NMK_GPIO_ALT_C+4] = "altC4",
};
- const char *pulls[] = {
- "none ",
- "pull down",
- "pull up ",
- };
clk_enable(nmk_chip->clk);
is_out = !!(readl(nmk_chip->addr + NMK_GPIO_DIR) & BIT(offset));
@@ -965,19 +941,20 @@
mode = nmk_prcm_gpiocr_get_mode(pctldev, gpio);
if (is_out) {
- seq_printf(s, " gpio-%-3d (%-20.20s) out %s %s",
+ seq_printf(s, " gpio-%-3d (%-20.20s) out %s %s",
gpio,
label ?: "(none)",
data_out ? "hi" : "lo",
(mode < 0) ? "unknown" : modes[mode]);
} else {
- int irq = gpio_to_irq(gpio);
+ int irq = chip->to_irq(chip, offset);
struct irq_desc *desc = irq_to_desc(irq);
- int pullidx = 0;
+ const int pullidx = pull ? 1 : 0;
int val;
-
- if (pull)
- pullidx = data_out ? 2 : 1;
+ static const char * const pulls[] = {
+ "none ",
+ "pull enabled",
+ };
seq_printf(s, " gpio-%-3d (%-20.20s) in %s %s",
gpio,
@@ -1051,22 +1028,27 @@
gpio_pdev = of_find_device_by_node(np);
if (!gpio_pdev) {
- pr_err("populate \"%s\": device not found\n", np->name);
+ pr_err("populate \"%pOFn\": device not found\n", np);
return ERR_PTR(-ENODEV);
}
if (of_property_read_u32(np, "gpio-bank", &id)) {
dev_err(&pdev->dev, "populate: gpio-bank property not found\n");
+ platform_device_put(gpio_pdev);
return ERR_PTR(-EINVAL);
}
/* Already populated? */
nmk_chip = nmk_gpio_chips[id];
- if (nmk_chip)
+ if (nmk_chip) {
+ platform_device_put(gpio_pdev);
return nmk_chip;
+ }
nmk_chip = devm_kzalloc(&pdev->dev, sizeof(*nmk_chip), GFP_KERNEL);
- if (!nmk_chip)
+ if (!nmk_chip) {
+ platform_device_put(gpio_pdev);
return ERR_PTR(-ENOMEM);
+ }
nmk_chip->bank = id;
chip = &nmk_chip->chip;
@@ -1077,13 +1059,17 @@
res = platform_get_resource(gpio_pdev, IORESOURCE_MEM, 0);
base = devm_ioremap_resource(&pdev->dev, res);
- if (IS_ERR(base))
+ if (IS_ERR(base)) {
+ platform_device_put(gpio_pdev);
return ERR_CAST(base);
+ }
nmk_chip->addr = base;
clk = clk_get(&gpio_pdev->dev, NULL);
- if (IS_ERR(clk))
+ if (IS_ERR(clk)) {
+ platform_device_put(gpio_pdev);
return (void *) clk;
+ }
clk_prepare(clk);
nmk_chip->clk = clk;
@@ -1097,8 +1083,8 @@
struct device_node *np = dev->dev.of_node;
struct nmk_gpio_chip *nmk_chip;
struct gpio_chip *chip;
+ struct gpio_irq_chip *girq;
struct irq_chip *irqchip;
- int latent_irq;
bool supports_sleepmode;
int irq;
int ret;
@@ -1119,15 +1105,10 @@
if (irq < 0)
return irq;
- /* It's OK for this IRQ not to be present */
- latent_irq = platform_get_irq(dev, 1);
-
/*
* The virt address in nmk_chip->addr is in the nomadik register space,
* so we can simply convert the resource address, without remapping
*/
- nmk_chip->parent_irq = irq;
- nmk_chip->latent_parent_irq = latent_irq;
nmk_chip->sleepmode = supports_sleepmode;
spin_lock_init(&nmk_chip->lock);
@@ -1157,6 +1138,19 @@
chip->base,
chip->base + chip->ngpio - 1);
+ girq = &chip->irq;
+ girq->chip = irqchip;
+ girq->parent_handler = nmk_gpio_irq_handler;
+ girq->num_parents = 1;
+ girq->parents = devm_kcalloc(&dev->dev, 1,
+ sizeof(*girq->parents),
+ GFP_KERNEL);
+ if (!girq->parents)
+ return -ENOMEM;
+ girq->parents[0] = irq;
+ girq->default_type = IRQ_TYPE_NONE;
+ girq->handler = handle_edge_irq;
+
clk_enable(nmk_chip->clk);
nmk_chip->lowemi = readl_relaxed(nmk_chip->addr + NMK_GPIO_LOWEMI);
clk_disable(nmk_chip->clk);
@@ -1168,33 +1162,7 @@
platform_set_drvdata(dev, nmk_chip);
- /*
- * Let the generic code handle this edge IRQ, the the chained
- * handler will perform the actual work of handling the parent
- * interrupt.
- */
- ret = gpiochip_irqchip_add(chip,
- irqchip,
- 0,
- handle_edge_irq,
- IRQ_TYPE_NONE);
- if (ret) {
- dev_err(&dev->dev, "could not add irqchip\n");
- gpiochip_remove(&nmk_chip->chip);
- return -ENODEV;
- }
- /* Then register the chain on the parent IRQ */
- gpiochip_set_chained_irqchip(chip,
- irqchip,
- nmk_chip->parent_irq,
- nmk_gpio_irq_handler);
- if (nmk_chip->latent_parent_irq > 0)
- gpiochip_set_chained_irqchip(chip,
- irqchip,
- nmk_chip->latent_parent_irq,
- nmk_gpio_latent_irq_handler);
-
- dev_info(&dev->dev, "at address %p\n", nmk_chip->addr);
+ dev_info(&dev->dev, "chip registered\n");
return 0;
}
@@ -1371,8 +1339,6 @@
static int nmk_dt_pin_config(int index, int val, unsigned long *config)
{
- int ret = 0;
-
if (nmk_cfg_params[index].choice == NULL)
*config = nmk_cfg_params[index].config;
else {
@@ -1382,7 +1348,7 @@
nmk_cfg_params[index].choice[val];
}
}
- return ret;
+ return 0;
}
static const char *nmk_find_pin_name(struct pinctrl_dev *pctldev, const char *pin_name)
@@ -1455,8 +1421,10 @@
has_config = nmk_pinctrl_dt_get_config(np, &configs);
np_config = of_parse_phandle(np, "ste,config", 0);
- if (np_config)
+ if (np_config) {
has_config |= nmk_pinctrl_dt_get_config(np_config, &configs);
+ of_node_put(np_config);
+ }
if (has_config) {
const char *gpio_name;
const char *pin;
@@ -1502,6 +1470,7 @@
&reserved_maps, num_maps);
if (ret < 0) {
pinctrl_utils_free_map(pctldev, *map, *num_maps);
+ of_node_put(np);
return ret;
}
}
@@ -1904,8 +1873,8 @@
gpio_np = of_parse_phandle(np, "nomadik-gpio-chips", i);
if (gpio_np) {
dev_info(&pdev->dev,
- "populate NMK GPIO %d \"%s\"\n",
- i, gpio_np->name);
+ "populate NMK GPIO %d \"%pOFn\"\n",
+ i, gpio_np);
nmk_chip = nmk_gpio_populate_chip(gpio_np, pdev);
if (IS_ERR(nmk_chip))
dev_err(&pdev->dev,
@@ -1916,8 +1885,10 @@
}
prcm_np = of_parse_phandle(np, "prcm", 0);
- if (prcm_np)
+ if (prcm_np) {
npct->prcm_base = of_iomap(prcm_np, 0);
+ of_node_put(prcm_np);
+ }
if (!npct->prcm_base) {
if (version == PINCTRL_NMK_STN8815) {
dev_info(&pdev->dev,
--
Gitblit v1.6.2