brintos

brintos / linux-shallow public Read only

0
0
Text · 8.4 KiB · 3ef24ba Raw
336 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 * QUICC Engine GPIOs4 *5 * Copyright (c) MontaVista Software, Inc. 2008.6 *7 * Author: Anton Vorontsov <avorontsov@ru.mvista.com>8 */9 10#include <linux/kernel.h>11#include <linux/init.h>12#include <linux/spinlock.h>13#include <linux/err.h>14#include <linux/io.h>15#include <linux/of.h>16#include <linux/gpio/legacy-of-mm-gpiochip.h>17#include <linux/gpio/consumer.h>18#include <linux/gpio/driver.h>19#include <linux/slab.h>20#include <linux/export.h>21#include <linux/property.h>22 23#include <soc/fsl/qe/qe.h>24 25struct qe_gpio_chip {26	struct of_mm_gpio_chip mm_gc;27	spinlock_t lock;28 29	/* shadowed data register to clear/set bits safely */30	u32 cpdata;31 32	/* saved_regs used to restore dedicated functions */33	struct qe_pio_regs saved_regs;34};35 36static void qe_gpio_save_regs(struct of_mm_gpio_chip *mm_gc)37{38	struct qe_gpio_chip *qe_gc =39		container_of(mm_gc, struct qe_gpio_chip, mm_gc);40	struct qe_pio_regs __iomem *regs = mm_gc->regs;41 42	qe_gc->cpdata = ioread32be(&regs->cpdata);43	qe_gc->saved_regs.cpdata = qe_gc->cpdata;44	qe_gc->saved_regs.cpdir1 = ioread32be(&regs->cpdir1);45	qe_gc->saved_regs.cpdir2 = ioread32be(&regs->cpdir2);46	qe_gc->saved_regs.cppar1 = ioread32be(&regs->cppar1);47	qe_gc->saved_regs.cppar2 = ioread32be(&regs->cppar2);48	qe_gc->saved_regs.cpodr = ioread32be(&regs->cpodr);49}50 51static int qe_gpio_get(struct gpio_chip *gc, unsigned int gpio)52{53	struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);54	struct qe_pio_regs __iomem *regs = mm_gc->regs;55	u32 pin_mask = 1 << (QE_PIO_PINS - 1 - gpio);56 57	return !!(ioread32be(&regs->cpdata) & pin_mask);58}59 60static void qe_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val)61{62	struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);63	struct qe_gpio_chip *qe_gc = gpiochip_get_data(gc);64	struct qe_pio_regs __iomem *regs = mm_gc->regs;65	unsigned long flags;66	u32 pin_mask = 1 << (QE_PIO_PINS - 1 - gpio);67 68	spin_lock_irqsave(&qe_gc->lock, flags);69 70	if (val)71		qe_gc->cpdata |= pin_mask;72	else73		qe_gc->cpdata &= ~pin_mask;74 75	iowrite32be(qe_gc->cpdata, &regs->cpdata);76 77	spin_unlock_irqrestore(&qe_gc->lock, flags);78}79 80static void qe_gpio_set_multiple(struct gpio_chip *gc,81				 unsigned long *mask, unsigned long *bits)82{83	struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);84	struct qe_gpio_chip *qe_gc = gpiochip_get_data(gc);85	struct qe_pio_regs __iomem *regs = mm_gc->regs;86	unsigned long flags;87	int i;88 89	spin_lock_irqsave(&qe_gc->lock, flags);90 91	for (i = 0; i < gc->ngpio; i++) {92		if (*mask == 0)93			break;94		if (__test_and_clear_bit(i, mask)) {95			if (test_bit(i, bits))96				qe_gc->cpdata |= (1U << (QE_PIO_PINS - 1 - i));97			else98				qe_gc->cpdata &= ~(1U << (QE_PIO_PINS - 1 - i));99		}100	}101 102	iowrite32be(qe_gc->cpdata, &regs->cpdata);103 104	spin_unlock_irqrestore(&qe_gc->lock, flags);105}106 107static int qe_gpio_dir_in(struct gpio_chip *gc, unsigned int gpio)108{109	struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);110	struct qe_gpio_chip *qe_gc = gpiochip_get_data(gc);111	unsigned long flags;112 113	spin_lock_irqsave(&qe_gc->lock, flags);114 115	__par_io_config_pin(mm_gc->regs, gpio, QE_PIO_DIR_IN, 0, 0, 0);116 117	spin_unlock_irqrestore(&qe_gc->lock, flags);118 119	return 0;120}121 122static int qe_gpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)123{124	struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);125	struct qe_gpio_chip *qe_gc = gpiochip_get_data(gc);126	unsigned long flags;127 128	qe_gpio_set(gc, gpio, val);129 130	spin_lock_irqsave(&qe_gc->lock, flags);131 132	__par_io_config_pin(mm_gc->regs, gpio, QE_PIO_DIR_OUT, 0, 0, 0);133 134	spin_unlock_irqrestore(&qe_gc->lock, flags);135 136	return 0;137}138 139struct qe_pin {140	/*141	 * The qe_gpio_chip name is unfortunate, we should change that to142	 * something like qe_pio_controller. Someday.143	 */144	struct qe_gpio_chip *controller;145	int num;146};147 148/**149 * qe_pin_request - Request a QE pin150 * @dev:	device to get the pin from151 * @index:	index of the pin in the device tree152 * Context:	non-atomic153 *154 * This function return qe_pin so that you could use it with the rest of155 * the QE Pin Multiplexing API.156 */157struct qe_pin *qe_pin_request(struct device *dev, int index)158{159	struct qe_pin *qe_pin;160	struct gpio_chip *gc;161	struct gpio_desc *gpiod;162	int gpio_num;163	int err;164 165	qe_pin = kzalloc(sizeof(*qe_pin), GFP_KERNEL);166	if (!qe_pin) {167		dev_dbg(dev, "%s: can't allocate memory\n", __func__);168		return ERR_PTR(-ENOMEM);169	}170 171	/*172	 * Request gpio as nonexclusive as it was likely reserved by the173	 * caller, and we are not planning on controlling it, we only need174	 * the descriptor to the to the gpio chip structure.175	 */176	gpiod = gpiod_get_index(dev, NULL, index,177			        GPIOD_ASIS | GPIOD_FLAGS_BIT_NONEXCLUSIVE);178	err = PTR_ERR_OR_ZERO(gpiod);179	if (err)180		goto err0;181 182	gc = gpiod_to_chip(gpiod);183	gpio_num = desc_to_gpio(gpiod);184	/* We no longer need this descriptor */185	gpiod_put(gpiod);186 187	if (WARN_ON(!gc)) {188		err = -ENODEV;189		goto err0;190	}191 192	qe_pin->controller = gpiochip_get_data(gc);193	/*194	 * FIXME: this gets the local offset on the gpio_chip so that the driver195	 * can manipulate pin control settings through its custom API. The real196	 * solution is to create a real pin control driver for this.197	 */198	qe_pin->num = gpio_num - gc->base;199 200	if (!fwnode_device_is_compatible(gc->fwnode, "fsl,mpc8323-qe-pario-bank")) {201		dev_dbg(dev, "%s: tried to get a non-qe pin\n", __func__);202		err = -EINVAL;203		goto err0;204	}205	return qe_pin;206err0:207	kfree(qe_pin);208	dev_dbg(dev, "%s failed with status %d\n", __func__, err);209	return ERR_PTR(err);210}211EXPORT_SYMBOL(qe_pin_request);212 213/**214 * qe_pin_free - Free a pin215 * @qe_pin:	pointer to the qe_pin structure216 * Context:	any217 *218 * This function frees the qe_pin structure and makes a pin available219 * for further qe_pin_request() calls.220 */221void qe_pin_free(struct qe_pin *qe_pin)222{223	kfree(qe_pin);224}225EXPORT_SYMBOL(qe_pin_free);226 227/**228 * qe_pin_set_dedicated - Revert a pin to a dedicated peripheral function mode229 * @qe_pin:	pointer to the qe_pin structure230 * Context:	any231 *232 * This function resets a pin to a dedicated peripheral function that233 * has been set up by the firmware.234 */235void qe_pin_set_dedicated(struct qe_pin *qe_pin)236{237	struct qe_gpio_chip *qe_gc = qe_pin->controller;238	struct qe_pio_regs __iomem *regs = qe_gc->mm_gc.regs;239	struct qe_pio_regs *sregs = &qe_gc->saved_regs;240	int pin = qe_pin->num;241	u32 mask1 = 1 << (QE_PIO_PINS - (pin + 1));242	u32 mask2 = 0x3 << (QE_PIO_PINS - (pin % (QE_PIO_PINS / 2) + 1) * 2);243	bool second_reg = pin > (QE_PIO_PINS / 2) - 1;244	unsigned long flags;245 246	spin_lock_irqsave(&qe_gc->lock, flags);247 248	if (second_reg) {249		qe_clrsetbits_be32(&regs->cpdir2, mask2,250				   sregs->cpdir2 & mask2);251		qe_clrsetbits_be32(&regs->cppar2, mask2,252				   sregs->cppar2 & mask2);253	} else {254		qe_clrsetbits_be32(&regs->cpdir1, mask2,255				   sregs->cpdir1 & mask2);256		qe_clrsetbits_be32(&regs->cppar1, mask2,257				   sregs->cppar1 & mask2);258	}259 260	if (sregs->cpdata & mask1)261		qe_gc->cpdata |= mask1;262	else263		qe_gc->cpdata &= ~mask1;264 265	iowrite32be(qe_gc->cpdata, &regs->cpdata);266	qe_clrsetbits_be32(&regs->cpodr, mask1, sregs->cpodr & mask1);267 268	spin_unlock_irqrestore(&qe_gc->lock, flags);269}270EXPORT_SYMBOL(qe_pin_set_dedicated);271 272/**273 * qe_pin_set_gpio - Set a pin to the GPIO mode274 * @qe_pin:	pointer to the qe_pin structure275 * Context:	any276 *277 * This function sets a pin to the GPIO mode.278 */279void qe_pin_set_gpio(struct qe_pin *qe_pin)280{281	struct qe_gpio_chip *qe_gc = qe_pin->controller;282	struct qe_pio_regs __iomem *regs = qe_gc->mm_gc.regs;283	unsigned long flags;284 285	spin_lock_irqsave(&qe_gc->lock, flags);286 287	/* Let's make it input by default, GPIO API is able to change that. */288	__par_io_config_pin(regs, qe_pin->num, QE_PIO_DIR_IN, 0, 0, 0);289 290	spin_unlock_irqrestore(&qe_gc->lock, flags);291}292EXPORT_SYMBOL(qe_pin_set_gpio);293 294static int __init qe_add_gpiochips(void)295{296	struct device_node *np;297 298	for_each_compatible_node(np, NULL, "fsl,mpc8323-qe-pario-bank") {299		int ret;300		struct qe_gpio_chip *qe_gc;301		struct of_mm_gpio_chip *mm_gc;302		struct gpio_chip *gc;303 304		qe_gc = kzalloc(sizeof(*qe_gc), GFP_KERNEL);305		if (!qe_gc) {306			ret = -ENOMEM;307			goto err;308		}309 310		spin_lock_init(&qe_gc->lock);311 312		mm_gc = &qe_gc->mm_gc;313		gc = &mm_gc->gc;314 315		mm_gc->save_regs = qe_gpio_save_regs;316		gc->ngpio = QE_PIO_PINS;317		gc->direction_input = qe_gpio_dir_in;318		gc->direction_output = qe_gpio_dir_out;319		gc->get = qe_gpio_get;320		gc->set = qe_gpio_set;321		gc->set_multiple = qe_gpio_set_multiple;322 323		ret = of_mm_gpiochip_add_data(np, mm_gc, qe_gc);324		if (ret)325			goto err;326		continue;327err:328		pr_err("%pOF: registration failed with status %d\n",329		       np, ret);330		kfree(qe_gc);331		/* try others anyway */332	}333	return 0;334}335arch_initcall(qe_add_gpiochips);336