summaryrefslogtreecommitdiffstats
path: root/drivers/pinctrl
diff options
context:
space:
mode:
authorThéo Lebrun <theo.lebrun@bootlin.com>2024-02-28 12:28:04 +0100
committerLinus Walleij <linus.walleij@linaro.org>2024-02-29 10:22:33 +0100
commit966942ae493650210b9514f3d4bfc95f78ef0129 (patch)
tree49165f05e6c0deb06377766942d72824b4aafdc6 /drivers/pinctrl
parent53cf6b72e074864b94ade97dcb6f30b5ac1a82dc (diff)
downloadlinux-966942ae493650210b9514f3d4bfc95f78ef0129.tar.gz
linux-966942ae493650210b9514f3d4bfc95f78ef0129.tar.bz2
linux-966942ae493650210b9514f3d4bfc95f78ef0129.zip
gpio: nomadik: extract GPIO platform driver from drivers/pinctrl/nomadik/
Previously, drivers/pinctrl/nomadik/pinctrl-nomadik.c registered two platform drivers: pinctrl & GPIO. Move the GPIO aspect to the drivers/gpio/ folder, as would be expected. Both drivers are intertwined for a reason; pinctrl requires access to GPIO registers for pinmuxing, pull-disable, disabling interrupts while setting the muxing and wakeup control. Information sharing is done through a shared array containing GPIO chips and a few helper functions. That shared array is not touched from gpio-nomadik when CONFIG_PINCTRL_NOMADIK is not defined. Make no change to the code that moved into gpio-nomadik; there should be no behavior change following. A few functions are shared and header comments are added. Checkpatch warnings are addressed. NUM_BANKS is renamed to NMK_MAX_BANKS. It is supported to compile gpio-nomadik without pinctrl-nomadik. The opposite is not true. Signed-off-by: Théo Lebrun <theo.lebrun@bootlin.com> Link: https://lore.kernel.org/r/20240228-mbly-gpio-v2-6-3ba757474006@bootlin.com Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Diffstat (limited to 'drivers/pinctrl')
-rw-r--r--drivers/pinctrl/nomadik/Kconfig5
-rw-r--r--drivers/pinctrl/nomadik/pinctrl-nomadik-db8500.c3
-rw-r--r--drivers/pinctrl/nomadik/pinctrl-nomadik-stn8815.c3
-rw-r--r--drivers/pinctrl/nomadik/pinctrl-nomadik.c722
-rw-r--r--drivers/pinctrl/nomadik/pinctrl-nomadik.h180
5 files changed, 21 insertions, 892 deletions
diff --git a/drivers/pinctrl/nomadik/Kconfig b/drivers/pinctrl/nomadik/Kconfig
index 0fea167c283f..f47f0755a835 100644
--- a/drivers/pinctrl/nomadik/Kconfig
+++ b/drivers/pinctrl/nomadik/Kconfig
@@ -22,11 +22,10 @@ if (ARCH_U8500 || ARCH_NOMADIK)
config PINCTRL_NOMADIK
bool "Nomadik pin controller driver"
- depends on OF && GPIOLIB
+ depends on OF
select PINMUX
select PINCONF
- select OF_GPIO
- select GPIOLIB_IRQCHIP
+ select GPIO_NOMADIK
config PINCTRL_STN8815
bool "STN8815 pin controller driver"
diff --git a/drivers/pinctrl/nomadik/pinctrl-nomadik-db8500.c b/drivers/pinctrl/nomadik/pinctrl-nomadik-db8500.c
index 490e0959e8be..0b4a3dd9d8c7 100644
--- a/drivers/pinctrl/nomadik/pinctrl-nomadik-db8500.c
+++ b/drivers/pinctrl/nomadik/pinctrl-nomadik-db8500.c
@@ -3,8 +3,9 @@
#include <linux/types.h>
#include <linux/pinctrl/pinctrl.h>
+#include <linux/gpio/driver.h>
-#include "pinctrl-nomadik.h"
+#include <linux/gpio/gpio-nomadik.h>
/* All the pins that can be used for GPIO and some other functions */
#define _GPIO(offset) (offset)
diff --git a/drivers/pinctrl/nomadik/pinctrl-nomadik-stn8815.c b/drivers/pinctrl/nomadik/pinctrl-nomadik-stn8815.c
index 1552222ac68e..c5a52fcaba30 100644
--- a/drivers/pinctrl/nomadik/pinctrl-nomadik-stn8815.c
+++ b/drivers/pinctrl/nomadik/pinctrl-nomadik-stn8815.c
@@ -3,8 +3,9 @@
#include <linux/types.h>
#include <linux/pinctrl/pinctrl.h>
+#include <linux/gpio/driver.h>
-#include "pinctrl-nomadik.h"
+#include <linux/gpio/gpio-nomadik.h>
/* All the pins that can be used for GPIO and some other functions */
#define _GPIO(offset) (offset)
diff --git a/drivers/pinctrl/nomadik/pinctrl-nomadik.c b/drivers/pinctrl/nomadik/pinctrl-nomadik.c
index 4f7c4af4f93c..16d836157f74 100644
--- a/drivers/pinctrl/nomadik/pinctrl-nomadik.c
+++ b/drivers/pinctrl/nomadik/pinctrl-nomadik.c
@@ -1,6 +1,8 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
- * Generic GPIO driver for logic cells found in the Nomadik SoC
+ * Pinmux & pinconf driver for the IP block found in the Nomadik SoC. This
+ * depends on gpio-nomadik and some handling is intertwined; see nmk_gpio_chips
+ * which is used by this driver to access the GPIO banks array.
*
* Copyright (C) 2008,2009 STMicroelectronics
* Copyright (C) 2009 Alessandro Rubini <rubini@unipv.it>
@@ -25,6 +27,7 @@
#include <linux/seq_file.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
+#include <linux/types.h>
/* Since we request GPIOs from ourself */
#include <linux/pinctrl/consumer.h>
@@ -36,15 +39,7 @@
#include "../core.h"
#include "../pinctrl-utils.h"
-#include "pinctrl-nomadik.h"
-
-/*
- * The GPIO module in the Nomadik family of Systems-on-Chip is an
- * AMBA device, managing 32 pins and alternate functions. The logic block
- * is currently used in the Nomadik and ux500.
- *
- * Symbols in this file are called "nmk_gpio" for "nomadik gpio"
- */
+#include <linux/gpio/gpio-nomadik.h>
/*
* pin configurations are represented by 32-bit integers:
@@ -200,75 +195,6 @@ typedef unsigned long pin_cfg_t;
(PIN_CFG_DEFAULT |\
(PIN_NUM(num) | PIN_##alt | PIN_OUTPUT_##val))
-/*
- * "nmk_gpio" and "NMK_GPIO" stand for "Nomadik GPIO", leaving
- * the "gpio" namespace for generic and cross-machine functions
- */
-
-#define GPIO_BLOCK_SHIFT 5
-#define NMK_GPIO_PER_CHIP (1 << GPIO_BLOCK_SHIFT)
-#define NMK_MAX_BANKS DIV_ROUND_UP(512, NMK_GPIO_PER_CHIP)
-
-/* Register in the logic block */
-#define NMK_GPIO_DAT 0x00
-#define NMK_GPIO_DATS 0x04
-#define NMK_GPIO_DATC 0x08
-#define NMK_GPIO_PDIS 0x0c
-#define NMK_GPIO_DIR 0x10
-#define NMK_GPIO_DIRS 0x14
-#define NMK_GPIO_DIRC 0x18
-#define NMK_GPIO_SLPC 0x1c
-#define NMK_GPIO_AFSLA 0x20
-#define NMK_GPIO_AFSLB 0x24
-#define NMK_GPIO_LOWEMI 0x28
-
-#define NMK_GPIO_RIMSC 0x40
-#define NMK_GPIO_FIMSC 0x44
-#define NMK_GPIO_IS 0x48
-#define NMK_GPIO_IC 0x4c
-#define NMK_GPIO_RWIMSC 0x50
-#define NMK_GPIO_FWIMSC 0x54
-#define NMK_GPIO_WKS 0x58
-/* These appear in DB8540 and later ASICs */
-#define NMK_GPIO_EDGELEVEL 0x5C
-#define NMK_GPIO_LEVEL 0x60
-
-
-/* Pull up/down values */
-enum nmk_gpio_pull {
- NMK_GPIO_PULL_NONE,
- NMK_GPIO_PULL_UP,
- NMK_GPIO_PULL_DOWN,
-};
-
-/* Sleep mode */
-enum nmk_gpio_slpm {
- NMK_GPIO_SLPM_INPUT,
- NMK_GPIO_SLPM_WAKEUP_ENABLE = NMK_GPIO_SLPM_INPUT,
- NMK_GPIO_SLPM_NOCHANGE,
- NMK_GPIO_SLPM_WAKEUP_DISABLE = NMK_GPIO_SLPM_NOCHANGE,
-};
-
-struct nmk_gpio_chip {
- struct gpio_chip chip;
- void __iomem *addr;
- struct clk *clk;
- unsigned int bank;
- void (*set_ioforce)(bool enable);
- spinlock_t lock;
- bool sleepmode;
- /* Keep track of configured edges */
- u32 edge_rising;
- u32 edge_falling;
- u32 real_wake;
- u32 rwimsc;
- u32 fwimsc;
- u32 rimsc;
- u32 fimsc;
- u32 pull_up;
- u32 lowemi;
-};
-
/**
* struct nmk_pinctrl - state container for the Nomadik pin controller
* @dev: containing device pointer
@@ -283,11 +209,10 @@ struct nmk_pinctrl {
void __iomem *prcm_base;
};
-static struct nmk_gpio_chip *nmk_gpio_chips[NMK_MAX_BANKS];
+/* See nmk_gpio_populate_chip() that fills this array. */
+struct nmk_gpio_chip *nmk_gpio_chips[NMK_MAX_BANKS];
-static DEFINE_SPINLOCK(nmk_gpio_slpm_lock);
-
-#define NUM_BANKS ARRAY_SIZE(nmk_gpio_chips)
+DEFINE_SPINLOCK(nmk_gpio_slpm_lock);
static void __nmk_gpio_set_mode(struct nmk_gpio_chip *nmk_chip,
unsigned offset, int gpio_mode)
@@ -304,19 +229,6 @@ static void __nmk_gpio_set_mode(struct nmk_gpio_chip *nmk_chip,
writel(bfunc, nmk_chip->addr + NMK_GPIO_AFSLB);
}
-static void __nmk_gpio_set_slpm(struct nmk_gpio_chip *nmk_chip,
- unsigned offset, enum nmk_gpio_slpm mode)
-{
- u32 slpm;
-
- slpm = readl(nmk_chip->addr + NMK_GPIO_SLPC);
- if (mode == NMK_GPIO_SLPM_NOCHANGE)
- slpm |= BIT(offset);
- else
- slpm &= ~BIT(offset);
- writel(slpm, nmk_chip->addr + NMK_GPIO_SLPC);
-}
-
static void __nmk_gpio_set_pull(struct nmk_gpio_chip *nmk_chip,
unsigned offset, enum nmk_gpio_pull pull)
{
@@ -364,22 +276,6 @@ static void __nmk_gpio_make_input(struct nmk_gpio_chip *nmk_chip,
writel(BIT(offset), nmk_chip->addr + NMK_GPIO_DIRC);
}
-static void __nmk_gpio_set_output(struct nmk_gpio_chip *nmk_chip,
- unsigned offset, int val)
-{
- if (val)
- writel(BIT(offset), nmk_chip->addr + NMK_GPIO_DATS);
- else
- writel(BIT(offset), nmk_chip->addr + NMK_GPIO_DATC);
-}
-
-static void __nmk_gpio_make_output(struct nmk_gpio_chip *nmk_chip,
- unsigned offset, int val)
-{
- writel(BIT(offset), nmk_chip->addr + NMK_GPIO_DIRS);
- __nmk_gpio_set_output(nmk_chip, offset, val);
-}
-
static void __nmk_gpio_set_mode_safe(struct nmk_gpio_chip *nmk_chip,
unsigned offset, int gpio_mode,
bool glitch)
@@ -548,7 +444,7 @@ static void nmk_gpio_glitch_slpm_init(unsigned int *slpm)
{
int i;
- for (i = 0; i < NUM_BANKS; i++) {
+ for (i = 0; i < NMK_MAX_BANKS; i++) {
struct nmk_gpio_chip *chip = nmk_gpio_chips[i];
unsigned int temp = slpm[i];
@@ -566,7 +462,7 @@ static void nmk_gpio_glitch_slpm_restore(unsigned int *slpm)
{
int i;
- for (i = 0; i < NUM_BANKS; i++) {
+ for (i = 0; i < NMK_MAX_BANKS; i++) {
struct nmk_gpio_chip *chip = nmk_gpio_chips[i];
if (!chip)
@@ -578,7 +474,8 @@ static void nmk_gpio_glitch_slpm_restore(unsigned int *slpm)
}
}
-static int __maybe_unused nmk_prcm_gpiocr_get_mode(struct pinctrl_dev *pctldev, int gpio)
+/* Only called by gpio-nomadik but requires knowledge of struct nmk_pinctrl. */
+int __maybe_unused nmk_prcm_gpiocr_get_mode(struct pinctrl_dev *pctldev, int gpio)
{
int i;
u16 reg;
@@ -610,576 +507,6 @@ static int __maybe_unused nmk_prcm_gpiocr_get_mode(struct pinctrl_dev *pctldev,
return NMK_GPIO_ALT_C;
}
-/* IRQ functions */
-
-static void nmk_gpio_irq_ack(struct irq_data *d)
-{
- struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
- struct nmk_gpio_chip *nmk_chip = gpiochip_get_data(gc);
-
- clk_enable(nmk_chip->clk);
- writel(BIT(d->hwirq), nmk_chip->addr + NMK_GPIO_IC);
- clk_disable(nmk_chip->clk);
-}
-
-enum nmk_gpio_irq_type {
- NORMAL,
- WAKE,
-};
-
-static void __nmk_gpio_irq_modify(struct nmk_gpio_chip *nmk_chip,
- int offset, enum nmk_gpio_irq_type which,
- bool enable)
-{
- u32 *rimscval;
- u32 *fimscval;
- u32 rimscreg;
- u32 fimscreg;
-
- if (which == NORMAL) {
- rimscreg = NMK_GPIO_RIMSC;
- fimscreg = NMK_GPIO_FIMSC;
- rimscval = &nmk_chip->rimsc;
- fimscval = &nmk_chip->fimsc;
- } else {
- rimscreg = NMK_GPIO_RWIMSC;
- fimscreg = NMK_GPIO_FWIMSC;
- rimscval = &nmk_chip->rwimsc;
- fimscval = &nmk_chip->fwimsc;
- }
-
- /* we must individually set/clear the two edges */
- if (nmk_chip->edge_rising & BIT(offset)) {
- if (enable)
- *rimscval |= BIT(offset);
- else
- *rimscval &= ~BIT(offset);
- writel(*rimscval, nmk_chip->addr + rimscreg);
- }
- if (nmk_chip->edge_falling & BIT(offset)) {
- if (enable)
- *fimscval |= BIT(offset);
- else
- *fimscval &= ~BIT(offset);
- writel(*fimscval, nmk_chip->addr + fimscreg);
- }
-}
-
-static void __nmk_gpio_set_wake(struct nmk_gpio_chip *nmk_chip,
- int offset, bool on)
-{
- /*
- * Ensure WAKEUP_ENABLE is on. No need to disable it if wakeup is
- * disabled, since setting SLPM to 1 increases power consumption, and
- * wakeup is anyhow controlled by the RIMSC and FIMSC registers.
- */
- if (nmk_chip->sleepmode && on) {
- __nmk_gpio_set_slpm(nmk_chip, offset,
- NMK_GPIO_SLPM_WAKEUP_ENABLE);
- }
-
- __nmk_gpio_irq_modify(nmk_chip, offset, WAKE, on);
-}
-
-static void nmk_gpio_irq_maskunmask(struct nmk_gpio_chip *nmk_chip,
- struct irq_data *d, bool enable)
-{
- unsigned long flags;
-
- clk_enable(nmk_chip->clk);
- spin_lock_irqsave(&nmk_gpio_slpm_lock, flags);
- spin_lock(&nmk_chip->lock);
-
- __nmk_gpio_irq_modify(nmk_chip, d->hwirq, NORMAL, enable);
-
- if (!(nmk_chip->real_wake & BIT(d->hwirq)))
- __nmk_gpio_set_wake(nmk_chip, d->hwirq, enable);
-
- spin_unlock(&nmk_chip->lock);
- spin_unlock_irqrestore(&nmk_gpio_slpm_lock, flags);
- clk_disable(nmk_chip->clk);
-}
-
-static void nmk_gpio_irq_mask(struct irq_data *d)
-{
- struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
- struct nmk_gpio_chip *nmk_chip = gpiochip_get_data(gc);
-
- nmk_gpio_irq_maskunmask(nmk_chip, d, false);
- gpiochip_disable_irq(gc, irqd_to_hwirq(d));
-}
-
-static void nmk_gpio_irq_unmask(struct irq_data *d)
-{
- struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
- struct nmk_gpio_chip *nmk_chip = gpiochip_get_data(gc);
-
- gpiochip_enable_irq(gc, irqd_to_hwirq(d));
- nmk_gpio_irq_maskunmask(nmk_chip, d, true);
-}
-
-static int nmk_gpio_irq_set_wake(struct irq_data *d, unsigned int on)
-{
- struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
- struct nmk_gpio_chip *nmk_chip = gpiochip_get_data(gc);
- unsigned long flags;
-
- clk_enable(nmk_chip->clk);
- spin_lock_irqsave(&nmk_gpio_slpm_lock, flags);
- spin_lock(&nmk_chip->lock);
-
- if (irqd_irq_disabled(d))
- __nmk_gpio_set_wake(nmk_chip, d->hwirq, on);
-
- if (on)
- nmk_chip->real_wake |= BIT(d->hwirq);
- else
- nmk_chip->real_wake &= ~BIT(d->hwirq);
-
- spin_unlock(&nmk_chip->lock);
- spin_unlock_irqrestore(&nmk_gpio_slpm_lock, flags);
- clk_disable(nmk_chip->clk);
-
- return 0;
-}
-
-static int nmk_gpio_irq_set_type(struct irq_data *d, unsigned int type)
-{
- struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
- struct nmk_gpio_chip *nmk_chip = gpiochip_get_data(gc);
- bool enabled = !irqd_irq_disabled(d);
- bool wake = irqd_is_wakeup_set(d);
- unsigned long flags;
-
- if (type & IRQ_TYPE_LEVEL_HIGH)
- return -EINVAL;
- if (type & IRQ_TYPE_LEVEL_LOW)
- return -EINVAL;
-
- clk_enable(nmk_chip->clk);
- spin_lock_irqsave(&nmk_chip->lock, flags);
-
- if (enabled)
- __nmk_gpio_irq_modify(nmk_chip, d->hwirq, NORMAL, false);
-
- if (enabled || wake)
- __nmk_gpio_irq_modify(nmk_chip, d->hwirq, WAKE, false);
-
- nmk_chip->edge_rising &= ~BIT(d->hwirq);
- if (type & IRQ_TYPE_EDGE_RISING)
- nmk_chip->edge_rising |= BIT(d->hwirq);
-
- nmk_chip->edge_falling &= ~BIT(d->hwirq);
- if (type & IRQ_TYPE_EDGE_FALLING)
- nmk_chip->edge_falling |= BIT(d->hwirq);
-
- if (enabled)
- __nmk_gpio_irq_modify(nmk_chip, d->hwirq, NORMAL, true);
-
- if (enabled || wake)
- __nmk_gpio_irq_modify(nmk_chip, d->hwirq, WAKE, true);
-
- spin_unlock_irqrestore(&nmk_chip->lock, flags);
- clk_disable(nmk_chip->clk);
-
- return 0;
-}
-
-static unsigned int nmk_gpio_irq_startup(struct irq_data *d)
-{
- struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
- struct nmk_gpio_chip *nmk_chip = gpiochip_get_data(gc);
-
- clk_enable(nmk_chip->clk);
- nmk_gpio_irq_unmask(d);
- return 0;
-}
-
-static void nmk_gpio_irq_shutdown(struct irq_data *d)
-{
- struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
- struct nmk_gpio_chip *nmk_chip = gpiochip_get_data(gc);
-
- nmk_gpio_irq_mask(d);
- clk_disable(nmk_chip->clk);
-}
-
-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);
-
- generic_handle_domain_irq(chip->irq.domain, bit);
- status &= ~BIT(bit);
- }
-
- chained_irq_exit(host_chip, desc);
-}
-
-/* I/O Functions */
-
-static int nmk_gpio_get_dir(struct gpio_chip *chip, unsigned offset)
-{
- struct nmk_gpio_chip *nmk_chip = gpiochip_get_data(chip);
- int dir;
-
- clk_enable(nmk_chip->clk);
-
- dir = readl(nmk_chip->addr + NMK_GPIO_DIR) & BIT(offset);
-
- clk_disable(nmk_chip->clk);
-
- if (dir)
- return GPIO_LINE_DIRECTION_OUT;
-
- return GPIO_LINE_DIRECTION_IN;
-}
-
-static int nmk_gpio_make_input(struct gpio_chip *chip, unsigned offset)
-{
- struct nmk_gpio_chip *nmk_chip = gpiochip_get_data(chip);
-
- clk_enable(nmk_chip->clk);
-
- writel(BIT(offset), nmk_chip->addr + NMK_GPIO_DIRC);
-
- clk_disable(nmk_chip->clk);
-
- return 0;
-}
-
-static int nmk_gpio_get_input(struct gpio_chip *chip, unsigned offset)
-{
- struct nmk_gpio_chip *nmk_chip = gpiochip_get_data(chip);
- int value;
-
- clk_enable(nmk_chip->clk);
-
- value = !!(readl(nmk_chip->addr + NMK_GPIO_DAT) & BIT(offset));
-
- clk_disable(nmk_chip->clk);
-
- return value;
-}
-
-static void nmk_gpio_set_output(struct gpio_chip *chip, unsigned offset,
- int val)
-{
- struct nmk_gpio_chip *nmk_chip = gpiochip_get_data(chip);
-
- clk_enable(nmk_chip->clk);
-
- __nmk_gpio_set_output(nmk_chip, offset, val);
-
- clk_disable(nmk_chip->clk);
-}
-
-static int nmk_gpio_make_output(struct gpio_chip *chip, unsigned offset,
- int val)
-{
- struct nmk_gpio_chip *nmk_chip = gpiochip_get_data(chip);
-
- clk_enable(nmk_chip->clk);
-
- __nmk_gpio_make_output(nmk_chip, offset, val);
-
- clk_disable(nmk_chip->clk);
-
- return 0;
-}
-
-#ifdef CONFIG_DEBUG_FS
-static int nmk_gpio_get_mode(struct nmk_gpio_chip *nmk_chip, int offset)
-{
- u32 afunc, bfunc;
-
- clk_enable(nmk_chip->clk);
-
- afunc = readl(nmk_chip->addr + NMK_GPIO_AFSLA) & BIT(offset);
- bfunc = readl(nmk_chip->addr + NMK_GPIO_AFSLB) & BIT(offset);
-
- clk_disable(nmk_chip->clk);
-
- return (afunc ? NMK_GPIO_ALT_A : 0) | (bfunc ? NMK_GPIO_ALT_B : 0);
-}
-
-static void nmk_gpio_dbg_show_one(struct seq_file *s,
- struct pinctrl_dev *pctldev, struct gpio_chip *chip,
- unsigned offset, unsigned gpio)
-{
- struct nmk_gpio_chip *nmk_chip = gpiochip_get_data(chip);
- int mode;
- bool is_out;
- bool data_out;
- bool pull;
- const char *modes[] = {
- [NMK_GPIO_ALT_GPIO] = "gpio",
- [NMK_GPIO_ALT_A] = "altA",
- [NMK_GPIO_ALT_B] = "altB",
- [NMK_GPIO_ALT_C] = "altC",
- [NMK_GPIO_ALT_C+1] = "altC1",
- [NMK_GPIO_ALT_C+2] = "altC2",
- [NMK_GPIO_ALT_C+3] = "altC3",
- [NMK_GPIO_ALT_C+4] = "altC4",
- };
-
- char *label = gpiochip_dup_line_label(chip, offset);
- if (IS_ERR(label))
- return;
-
- clk_enable(nmk_chip->clk);
- is_out = !!(readl(nmk_chip->addr + NMK_GPIO_DIR) & BIT(offset));
- pull = !(readl(nmk_chip->addr + NMK_GPIO_PDIS) & BIT(offset));
- data_out = !!(readl(nmk_chip->addr + NMK_GPIO_DAT) & BIT(offset));
- mode = nmk_gpio_get_mode(nmk_chip, offset);
- if ((mode == NMK_GPIO_ALT_C) && pctldev)
- mode = nmk_prcm_gpiocr_get_mode(pctldev, gpio);
-
- if (is_out) {
- 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 = chip->to_irq(chip, offset);
- const int pullidx = pull ? 1 : 0;
- int val;
- static const char * const pulls[] = {
- "none ",
- "pull enabled",
- };
-
- seq_printf(s, " gpio-%-3d (%-20.20s) in %s %s",
- gpio,
- label ?: "(none)",
- pulls[pullidx],
- (mode < 0) ? "unknown" : modes[mode]);
-
- val = nmk_gpio_get_input(chip, offset);
- seq_printf(s, " VAL %d", val);
-
- /*
- * This races with request_irq(), set_irq_type(),
- * and set_irq_wake() ... but those are "rare".
- */
- if (irq > 0 && irq_has_action(irq)) {
- char *trigger;
- bool wake;
-
- if (nmk_chip->edge_rising & BIT(offset))
- trigger = "edge-rising";
- else if (nmk_chip->edge_falling & BIT(offset))
- trigger = "edge-falling";
- else
- trigger = "edge-undefined";
-
- wake = !!(nmk_chip->real_wake & BIT(offset));
-
- seq_printf(s, " irq-%d %s%s",
- irq, trigger, wake ? " wakeup" : "");
- }
- }
- clk_disable(nmk_chip->clk);
-}
-
-static void nmk_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
-{
- unsigned i;
- unsigned gpio = chip->base;
-
- for (i = 0; i < chip->ngpio; i++, gpio++) {
- nmk_gpio_dbg_show_one(s, NULL, chip, i, gpio);
- seq_printf(s, "\n");
- }
-}
-
-#else
-static inline void nmk_gpio_dbg_show_one(struct seq_file *s,
- struct pinctrl_dev *pctldev,
- struct gpio_chip *chip,
- unsigned offset, unsigned gpio)
-{
-}
-#define nmk_gpio_dbg_show NULL
-#endif
-
-/*
- * We will allocate memory for the state container using devm* allocators
- * binding to the first device reaching this point, it doesn't matter if
- * it is the pin controller or GPIO driver. However we need to use the right
- * platform device when looking up resources so pay attention to pdev.
- */
-static struct nmk_gpio_chip *nmk_gpio_populate_chip(struct device_node *np,
- struct platform_device *pdev)
-{
- struct nmk_gpio_chip *nmk_chip;
- struct platform_device *gpio_pdev;
- struct gpio_chip *chip;
- struct resource *res;
- struct clk *clk;
- void __iomem *base;
- u32 id;
-
- gpio_pdev = of_find_device_by_node(np);
- if (!gpio_pdev) {
- 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) {
- platform_device_put(gpio_pdev);
- return nmk_chip;
- }
-
- nmk_chip = devm_kzalloc(&pdev->dev, sizeof(*nmk_chip), GFP_KERNEL);
- if (!nmk_chip) {
- platform_device_put(gpio_pdev);
- return ERR_PTR(-ENOMEM);
- }
-
- nmk_chip->bank = id;
- chip = &nmk_chip->chip;
- chip->base = id * NMK_GPIO_PER_CHIP;
- chip->ngpio = NMK_GPIO_PER_CHIP;
- chip->label = dev_name(&gpio_pdev->dev);
- chip->parent = &gpio_pdev->dev;
-
- res = platform_get_resource(gpio_pdev, IORESOURCE_MEM, 0);
- base = devm_ioremap_resource(&pdev->dev, res);
- 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)) {
- platform_device_put(gpio_pdev);
- return (void *) clk;
- }
- clk_prepare(clk);
- nmk_chip->clk = clk;
-
- BUG_ON(nmk_chip->bank >= ARRAY_SIZE(nmk_gpio_chips));
- nmk_gpio_chips[id] = nmk_chip;
- return nmk_chip;
-}
-
-static void nmk_gpio_irq_print_chip(struct irq_data *d, struct seq_file *p)
-{
- struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
- struct nmk_gpio_chip *nmk_chip = gpiochip_get_data(gc);
-
- seq_printf(p, "nmk%u-%u-%u", nmk_chip->bank,
- gc->base, gc->base + gc->ngpio - 1);
-}
-
-static const struct irq_chip nmk_irq_chip = {
- .irq_ack = nmk_gpio_irq_ack,
- .irq_mask = nmk_gpio_irq_mask,
- .irq_unmask = nmk_gpio_irq_unmask,
- .irq_set_type = nmk_gpio_irq_set_type,
- .irq_set_wake = nmk_gpio_irq_set_wake,
- .irq_startup = nmk_gpio_irq_startup,
- .irq_shutdown = nmk_gpio_irq_shutdown,
- .irq_print_chip = nmk_gpio_irq_print_chip,
- .flags = IRQCHIP_MASK_ON_SUSPEND | IRQCHIP_IMMUTABLE,
- GPIOCHIP_IRQ_RESOURCE_HELPERS,
-};
-
-static int nmk_gpio_probe(struct platform_device *dev)
-{
- struct device_node *np = dev->dev.of_node;
- struct nmk_gpio_chip *nmk_chip;
- struct gpio_chip *chip;
- struct gpio_irq_chip *girq;
- bool supports_sleepmode;
- int irq;
- int ret;
-
- nmk_chip = nmk_gpio_populate_chip(np, dev);
- if (IS_ERR(nmk_chip)) {
- dev_err(&dev->dev, "could not populate nmk chip struct\n");
- return PTR_ERR(nmk_chip);
- }
-
- supports_sleepmode =
- of_property_read_bool(np, "st,supports-sleepmode");
-
- /* Correct platform device ID */
- dev->id = nmk_chip->bank;
-
- irq = platform_get_irq(dev, 0);
- if (irq < 0)
- return irq;
-
- /*
- * 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->sleepmode = supports_sleepmode;
- spin_lock_init(&nmk_chip->lock);
-
- chip = &nmk_chip->chip;
- chip->parent = &dev->dev;
- chip->request = gpiochip_generic_request;
- chip->free = gpiochip_generic_free;
- chip->get_direction = nmk_gpio_get_dir;
- chip->direction_input = nmk_gpio_make_input;
- chip->get = nmk_gpio_get_input;
- chip->direction_output = nmk_gpio_make_output;
- chip->set = nmk_gpio_set_output;
- chip->dbg_show = nmk_gpio_dbg_show;
- chip->can_sleep = false;
- chip->owner = THIS_MODULE;
-
- girq = &chip->irq;
- gpio_irq_chip_set_chip(girq, &nmk_irq_chip);
- 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);
-
- ret = gpiochip_add_data(chip, nmk_chip);
- if (ret)
- return ret;
-
- platform_set_drvdata(dev, nmk_chip);
-
- dev_info(&dev->dev, "chip registered\n");
-
- return 0;
-}
-
static int nmk_get_groups_cnt(struct pinctrl_dev *pctldev)
{
struct nmk_pinctrl *npct = pinctrl_dev_get_drvdata(pctldev);
@@ -1197,12 +524,12 @@ static const char *nmk_get_group_name(struct pinctrl_dev *pctldev,
static int nmk_get_group_pins(struct pinctrl_dev *pctldev, unsigned selector,
const unsigned **pins,
- unsigned *npins)
+ unsigned int *num_pins)
{
struct nmk_pinctrl *npct = pinctrl_dev_get_drvdata(pctldev);
*pins = npct->soc->groups[selector].grp.pins;
- *npins = npct->soc->groups[selector].grp.npins;
+ *num_pins = npct->soc->groups[selector].grp.npins;
return 0;
}
@@ -1533,7 +860,7 @@ static int nmk_pmx_set(struct pinctrl_dev *pctldev, unsigned function,
{
struct nmk_pinctrl *npct = pinctrl_dev_get_drvdata(pctldev);
const struct nmk_pingroup *g;
- static unsigned int slpm[NUM_BANKS];
+ static unsigned int slpm[NMK_MAX_BANKS];
unsigned long flags = 0;
bool glitch;
int ret = -EINVAL;
@@ -1921,19 +1248,6 @@ static int nmk_pinctrl_probe(struct platform_device *pdev)
return 0;
}
-static const struct of_device_id nmk_gpio_match[] = {
- { .compatible = "st,nomadik-gpio", },
- {}
-};
-
-static struct platform_driver nmk_gpio_driver = {
- .driver = {
- .name = "gpio",
- .of_match_table = nmk_gpio_match,
- },
- .probe = nmk_gpio_probe,
-};
-
static SIMPLE_DEV_PM_OPS(nmk_pinctrl_pm_ops,
nmk_pinctrl_suspend,
nmk_pinctrl_resume);
@@ -1947,12 +1261,6 @@ static struct platform_driver nmk_pinctrl_driver = {
.probe = nmk_pinctrl_probe,
};
-static int __init nmk_gpio_init(void)
-{
- return platform_driver_register(&nmk_gpio_driver);
-}
-subsys_initcall(nmk_gpio_init);
-
static int __init nmk_pinctrl_init(void)
{
return platform_driver_register(&nmk_pinctrl_driver);
diff --git a/drivers/pinctrl/nomadik/pinctrl-nomadik.h b/drivers/pinctrl/nomadik/pinctrl-nomadik.h
deleted file mode 100644
index 1ef2559bc571..000000000000
--- a/drivers/pinctrl/nomadik/pinctrl-nomadik.h
+++ /dev/null
@@ -1,180 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef PINCTRL_PINCTRL_NOMADIK_H
-#define PINCTRL_PINCTRL_NOMADIK_H
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-
-#include <linux/pinctrl/pinctrl.h>
-
-/* Package definitions */
-#define PINCTRL_NMK_STN8815 0
-#define PINCTRL_NMK_DB8500 1
-
-/* Alternate functions: function C is set in hw by setting both A and B */
-#define NMK_GPIO_ALT_GPIO 0
-#define NMK_GPIO_ALT_A 1
-#define NMK_GPIO_ALT_B 2
-#define NMK_GPIO_ALT_C (NMK_GPIO_ALT_A | NMK_GPIO_ALT_B)
-
-#define NMK_GPIO_ALT_CX_SHIFT 2
-#define NMK_GPIO_ALT_C1 ((1<<NMK_GPIO_ALT_CX_SHIFT) | NMK_GPIO_ALT_C)
-#define NMK_GPIO_ALT_C2 ((2<<NMK_GPIO_ALT_CX_SHIFT) | NMK_GPIO_ALT_C)
-#define NMK_GPIO_ALT_C3 ((3<<NMK_GPIO_ALT_CX_SHIFT) | NMK_GPIO_ALT_C)
-#define NMK_GPIO_ALT_C4 ((4<<NMK_GPIO_ALT_CX_SHIFT) | NMK_GPIO_ALT_C)
-
-#define PRCM_GPIOCR_ALTCX(pin_num,\
- altc1_used, altc1_ri, altc1_cb,\
- altc2_used, altc2_ri, altc2_cb,\
- altc3_used, altc3_ri, altc3_cb,\
- altc4_used, altc4_ri, altc4_cb)\
-{\
- .pin = pin_num,\
- .altcx[PRCM_IDX_GPIOCR_ALTC1] = {\
- .used = altc1_used,\
- .reg_index = altc1_ri,\
- .control_bit = altc1_cb\
- },\
- .altcx[PRCM_IDX_GPIOCR_ALTC2] = {\
- .used = altc2_used,\
- .reg_index = altc2_ri,\
- .control_bit = altc2_cb\
- },\
- .altcx[PRCM_IDX_GPIOCR_ALTC3] = {\
- .used = altc3_used,\
- .reg_index = altc3_ri,\
- .control_bit = altc3_cb\
- },\
- .altcx[PRCM_IDX_GPIOCR_ALTC4] = {\
- .used = altc4_used,\
- .reg_index = altc4_ri,\
- .control_bit = altc4_cb\
- },\
-}
-
-/**
- * enum prcm_gpiocr_reg_index
- * Used to reference an PRCM GPIOCR register address.
- */
-enum prcm_gpiocr_reg_index {
- PRCM_IDX_GPIOCR1,
- PRCM_IDX_GPIOCR2,
- PRCM_IDX_GPIOCR3
-};
-/**
- * enum prcm_gpiocr_altcx_index
- * Used to reference an Other alternate-C function.
- */
-enum prcm_gpiocr_altcx_index {
- PRCM_IDX_GPIOCR_ALTC1,
- PRCM_IDX_GPIOCR_ALTC2,
- PRCM_IDX_GPIOCR_ALTC3,
- PRCM_IDX_GPIOCR_ALTC4,
- PRCM_IDX_GPIOCR_ALTC_MAX,
-};
-
-/**
- * struct prcm_gpio_altcx - Other alternate-C function
- * @used: other alternate-C function availability
- * @reg_index: PRCM GPIOCR register index used to control the function
- * @control_bit: PRCM GPIOCR bit used to control the function
- */
-struct prcm_gpiocr_altcx {
- bool used:1;
- u8 reg_index:2;
- u8 control_bit:5;
-} __packed;
-
-/**
- * struct prcm_gpio_altcx_pin_desc - Other alternate-C pin
- * @pin: The pin number
- * @altcx: array of other alternate-C[1-4] functions
- */
-struct prcm_gpiocr_altcx_pin_desc {
- unsigned short pin;
- struct prcm_gpiocr_altcx altcx[PRCM_IDX_GPIOCR_ALTC_MAX];
-};
-
-/**
- * struct nmk_function - Nomadik pinctrl mux function
- * @name: The name of the function, exported to pinctrl core.
- * @groups: An array of pin groups that may select this function.
- * @ngroups: The number of entries in @groups.
- */
-struct nmk_function {
- const char *name;
- const char * const *groups;
- unsigned ngroups;
-};
-
-/**
- * struct nmk_pingroup - describes a Nomadik pin group
- * @grp: Generic data of the pin group (name and pins)
- * @altsetting: the altsetting to apply to all pins in this group to
- * configure them to be used by a function
- */
-struct nmk_pingroup {
- struct pingroup grp;
- int altsetting;
-};
-
-#define NMK_PIN_GROUP(a, b) \
- { \
- .grp = PINCTRL_PINGROUP(#a, a##_pins, ARRAY_SIZE(a##_pins)), \
- .altsetting = b, \
- }
-
-/**
- * struct nmk_pinctrl_soc_data - Nomadik pin controller per-SoC configuration
- * @pins: An array describing all pins the pin controller affects.
- * All pins which are also GPIOs must be listed first within the
- * array, and be numbered identically to the GPIO controller's
- * numbering.
- * @npins: The number of entries in @pins.
- * @functions: The functions supported on this SoC.
- * @nfunction: The number of entries in @functions.
- * @groups: An array describing all pin groups the pin SoC supports.
- * @ngroups: The number of entries in @groups.
- * @altcx_pins: The pins that support Other alternate-C function on this SoC
- * @npins_altcx: The number of Other alternate-C pins
- * @prcm_gpiocr_registers: The array of PRCM GPIOCR registers on this SoC
- */
-struct nmk_pinctrl_soc_data {
- const struct pinctrl_pin_desc *pins;
- unsigned npins;
- const struct nmk_function *functions;
- unsigned nfunctions;
- const struct nmk_pingroup *groups;
- unsigned ngroups;
- const struct prcm_gpiocr_altcx_pin_desc *altcx_pins;
- unsigned npins_altcx;
- const u16 *prcm_gpiocr_registers;
-};
-
-#ifdef CONFIG_PINCTRL_STN8815
-
-void nmk_pinctrl_stn8815_init(const struct nmk_pinctrl_soc_data **soc);
-
-#else
-
-static inline void
-nmk_pinctrl_stn8815_init(const struct nmk_pinctrl_soc_data **soc)
-{
-}
-
-#endif
-
-#ifdef CONFIG_PINCTRL_DB8500
-
-void nmk_pinctrl_db8500_init(const struct nmk_pinctrl_soc_data **soc);
-
-#else
-
-static inline void
-nmk_pinctrl_db8500_init(const struct nmk_pinctrl_soc_data **soc)
-{
-}
-
-#endif
-
-#endif /* PINCTRL_PINCTRL_NOMADIK_H */