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(®s->cpdata);43 qe_gc->saved_regs.cpdata = qe_gc->cpdata;44 qe_gc->saved_regs.cpdir1 = ioread32be(®s->cpdir1);45 qe_gc->saved_regs.cpdir2 = ioread32be(®s->cpdir2);46 qe_gc->saved_regs.cppar1 = ioread32be(®s->cppar1);47 qe_gc->saved_regs.cppar2 = ioread32be(®s->cppar2);48 qe_gc->saved_regs.cpodr = ioread32be(®s->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(®s->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, ®s->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, ®s->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(®s->cpdir2, mask2,250 sregs->cpdir2 & mask2);251 qe_clrsetbits_be32(®s->cppar2, mask2,252 sregs->cppar2 & mask2);253 } else {254 qe_clrsetbits_be32(®s->cpdir1, mask2,255 sregs->cpdir1 & mask2);256 qe_clrsetbits_be32(®s->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, ®s->cpdata);266 qe_clrsetbits_be32(®s->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