File Index
Files and directories
Sign in
FILE

gpio.c

File preview with syntax highlighting.

linux-6.19.14/arch/powerpc/platforms/44x/gpio.c C
  1// SPDX-License-Identifier: GPL-2.0-only
  2/*
  3 * PPC4xx gpio driver
  4 *
  5 * Copyright (c) 2008 Harris Corporation
  6 * Copyright (c) 2008 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
  7 * Copyright (c) MontaVista Software, Inc. 2008.
  8 *
  9 * Author: Steve Falco <sfalco@harris.com>
 10 */
 11
 12#include <linux/kernel.h>
 13#include <linux/init.h>
 14#include <linux/spinlock.h>
 15#include <linux/io.h>
 16#include <linux/of.h>
 17#include <linux/gpio/driver.h>
 18#include <linux/types.h>
 19#include <linux/slab.h>
 20#include <linux/platform_device.h>
 21
 22#define GPIO_MASK(gpio)		(0x80000000 >> (gpio))
 23#define GPIO_MASK2(gpio)	(0xc0000000 >> ((gpio) * 2))
 24
 25/* Physical GPIO register layout */
 26struct ppc4xx_gpio {
 27	__be32 or;
 28	__be32 tcr;
 29	__be32 osrl;
 30	__be32 osrh;
 31	__be32 tsrl;
 32	__be32 tsrh;
 33	__be32 odr;
 34	__be32 ir;
 35	__be32 rr1;
 36	__be32 rr2;
 37	__be32 rr3;
 38	__be32 reserved1;
 39	__be32 isr1l;
 40	__be32 isr1h;
 41	__be32 isr2l;
 42	__be32 isr2h;
 43	__be32 isr3l;
 44	__be32 isr3h;
 45};
 46
 47struct ppc4xx_gpio_chip {
 48	struct gpio_chip gc;
 49	void __iomem *regs;
 50	spinlock_t lock;
 51};
 52
 53/*
 54 * GPIO LIB API implementation for GPIOs
 55 *
 56 * There are a maximum of 32 gpios in each gpio controller.
 57 */
 58
 59static int ppc4xx_gpio_get(struct gpio_chip *gc, unsigned int gpio)
 60{
 61	struct ppc4xx_gpio_chip *chip = gpiochip_get_data(gc);
 62	struct ppc4xx_gpio __iomem *regs = chip->regs;
 63
 64	return !!(in_be32(&regs->ir) & GPIO_MASK(gpio));
 65}
 66
 67static inline void
 68__ppc4xx_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val)
 69{
 70	struct ppc4xx_gpio_chip *chip = gpiochip_get_data(gc);
 71	struct ppc4xx_gpio __iomem *regs = chip->regs;
 72
 73	if (val)
 74		setbits32(&regs->or, GPIO_MASK(gpio));
 75	else
 76		clrbits32(&regs->or, GPIO_MASK(gpio));
 77}
 78
 79static int ppc4xx_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val)
 80{
 81	struct ppc4xx_gpio_chip *chip = gpiochip_get_data(gc);
 82	unsigned long flags;
 83
 84	spin_lock_irqsave(&chip->lock, flags);
 85
 86	__ppc4xx_gpio_set(gc, gpio, val);
 87
 88	spin_unlock_irqrestore(&chip->lock, flags);
 89
 90	pr_debug("%s: gpio: %d val: %d\n", __func__, gpio, val);
 91
 92	return 0;
 93}
 94
 95static int ppc4xx_gpio_dir_in(struct gpio_chip *gc, unsigned int gpio)
 96{
 97	struct ppc4xx_gpio_chip *chip = gpiochip_get_data(gc);
 98	struct ppc4xx_gpio __iomem *regs = chip->regs;
 99	unsigned long flags;
100
101	spin_lock_irqsave(&chip->lock, flags);
102
103	/* Disable open-drain function */
104	clrbits32(&regs->odr, GPIO_MASK(gpio));
105
106	/* Float the pin */
107	clrbits32(&regs->tcr, GPIO_MASK(gpio));
108
109	/* Bits 0-15 use TSRL/OSRL, bits 16-31 use TSRH/OSRH */
110	if (gpio < 16) {
111		clrbits32(&regs->osrl, GPIO_MASK2(gpio));
112		clrbits32(&regs->tsrl, GPIO_MASK2(gpio));
113	} else {
114		clrbits32(&regs->osrh, GPIO_MASK2(gpio));
115		clrbits32(&regs->tsrh, GPIO_MASK2(gpio));
116	}
117
118	spin_unlock_irqrestore(&chip->lock, flags);
119
120	return 0;
121}
122
123static int
124ppc4xx_gpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
125{
126	struct ppc4xx_gpio_chip *chip = gpiochip_get_data(gc);
127	struct ppc4xx_gpio __iomem *regs = chip->regs;
128	unsigned long flags;
129
130	spin_lock_irqsave(&chip->lock, flags);
131
132	/* First set initial value */
133	__ppc4xx_gpio_set(gc, gpio, val);
134
135	/* Disable open-drain function */
136	clrbits32(&regs->odr, GPIO_MASK(gpio));
137
138	/* Drive the pin */
139	setbits32(&regs->tcr, GPIO_MASK(gpio));
140
141	/* Bits 0-15 use TSRL, bits 16-31 use TSRH */
142	if (gpio < 16) {
143		clrbits32(&regs->osrl, GPIO_MASK2(gpio));
144		clrbits32(&regs->tsrl, GPIO_MASK2(gpio));
145	} else {
146		clrbits32(&regs->osrh, GPIO_MASK2(gpio));
147		clrbits32(&regs->tsrh, GPIO_MASK2(gpio));
148	}
149
150	spin_unlock_irqrestore(&chip->lock, flags);
151
152	pr_debug("%s: gpio: %d val: %d\n", __func__, gpio, val);
153
154	return 0;
155}
156
157static int ppc4xx_gpio_probe(struct platform_device *ofdev)
158{
159	struct device *dev = &ofdev->dev;
160	struct device_node *np = dev->of_node;
161	struct ppc4xx_gpio_chip *chip;
162	struct gpio_chip *gc;
163
164	chip = devm_kzalloc(dev, sizeof(*chip), GFP_KERNEL);
165	if (!chip)
166		return -ENOMEM;
167
168	spin_lock_init(&chip->lock);
169
170	gc = &chip->gc;
171
172	gc->base = -1;
173	gc->ngpio = 32;
174	gc->direction_input = ppc4xx_gpio_dir_in;
175	gc->direction_output = ppc4xx_gpio_dir_out;
176	gc->get = ppc4xx_gpio_get;
177	gc->set = ppc4xx_gpio_set;
178
179	gc->label = devm_kasprintf(dev, GFP_KERNEL, "%pOF", np);
180	if (!gc->label)
181		return -ENOMEM;
182
183	chip->regs = devm_of_iomap(dev, np, 0, NULL);
184	if (IS_ERR(chip->regs))
185		return PTR_ERR(chip->regs);
186
187	return devm_gpiochip_add_data(dev, gc, chip);
188}
189
190static const struct of_device_id ppc4xx_gpio_match[] = {
191	{
192		.compatible = "ibm,ppc4xx-gpio",
193	},
194	{},
195};
196MODULE_DEVICE_TABLE(of, ppc4xx_gpio_match);
197
198static struct platform_driver ppc4xx_gpio_driver = {
199	.probe		= ppc4xx_gpio_probe,
200	.driver		= {
201		.name	= "ppc4xx-gpio",
202		.of_match_table	= ppc4xx_gpio_match,
203	},
204};
205
206static int __init ppc4xx_gpio_init(void)
207{
208	return platform_driver_register(&ppc4xx_gpio_driver);
209}
210arch_initcall(ppc4xx_gpio_init);
~/ Read-only file preview.