Skip to content

Commit 4726773

Browse files
linuswbroonie
authored andcommitted
spi: ppc4xx: Convert to use GPIO descriptors
This converts the PPC4xx SPI driver to use GPIO descriptors. The driver is already just picking some GPIOs from the device tree so the conversion is pretty straight forward. However this driver is looking form a pure "gpios" property rather than the standard binding "cs-gpios" so we need to add a new exception to the gpiolib OF parser to allow this for this driver's compatibles. Signed-off-by: Linus Walleij <[email protected]> Cc: [email protected] Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Mark Brown <[email protected]>
1 parent ce8e60f commit 4726773

File tree

2 files changed

+17
-99
lines changed

2 files changed

+17
-99
lines changed

drivers/gpio/gpiolib-of.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
/**
2727
* of_gpio_spi_cs_get_count() - special GPIO counting for SPI
2828
* Some elder GPIO controllers need special quirks. Currently we handle
29-
* the Freescale GPIO controller with bindings that doesn't use the
29+
* the Freescale and PPC GPIO controller with bindings that doesn't use the
3030
* established "cs-gpios" for chip selects but instead rely on
3131
* "gpios" for the chip select lines. If we detect this, we redirect
3232
* the counting of "cs-gpios" to count "gpios" transparent to the
@@ -41,7 +41,8 @@ static int of_gpio_spi_cs_get_count(struct device *dev, const char *con_id)
4141
if (!con_id || strcmp(con_id, "cs"))
4242
return 0;
4343
if (!of_device_is_compatible(np, "fsl,spi") &&
44-
!of_device_is_compatible(np, "aeroflexgaisler,spictrl"))
44+
!of_device_is_compatible(np, "aeroflexgaisler,spictrl") &&
45+
!of_device_is_compatible(np, "ibm,ppc4xx-spi"))
4546
return 0;
4647
return of_gpio_named_count(np, "gpios");
4748
}
@@ -405,9 +406,10 @@ static struct gpio_desc *of_find_spi_cs_gpio(struct device *dev,
405406
if (!IS_ENABLED(CONFIG_SPI_MASTER))
406407
return ERR_PTR(-ENOENT);
407408

408-
/* Allow this specifically for Freescale devices */
409+
/* Allow this specifically for Freescale and PPC devices */
409410
if (!of_device_is_compatible(np, "fsl,spi") &&
410-
!of_device_is_compatible(np, "aeroflexgaisler,spictrl"))
411+
!of_device_is_compatible(np, "aeroflexgaisler,spictrl") &&
412+
!of_device_is_compatible(np, "ibm,ppc4xx-spi"))
411413
return ERR_PTR(-ENOENT);
412414
/* Allow only if asking for "cs-gpios" */
413415
if (!con_id || strcmp(con_id, "cs"))

drivers/spi/spi-ppc4xx.c

Lines changed: 11 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,9 @@
2828
#include <linux/of_address.h>
2929
#include <linux/of_irq.h>
3030
#include <linux/of_platform.h>
31-
#include <linux/of_gpio.h>
3231
#include <linux/interrupt.h>
3332
#include <linux/delay.h>
3433

35-
#include <linux/gpio.h>
3634
#include <linux/spi/spi.h>
3735
#include <linux/spi/spi_bitbang.h>
3836

@@ -127,8 +125,6 @@ struct ppc4xx_spi {
127125
const unsigned char *tx;
128126
unsigned char *rx;
129127

130-
int *gpios;
131-
132128
struct spi_ppc4xx_regs __iomem *regs; /* pointer to the registers */
133129
struct spi_master *master;
134130
struct device *dev;
@@ -260,27 +256,6 @@ static int spi_ppc4xx_setup(struct spi_device *spi)
260256
return 0;
261257
}
262258

263-
static void spi_ppc4xx_chipsel(struct spi_device *spi, int value)
264-
{
265-
struct ppc4xx_spi *hw = spi_master_get_devdata(spi->master);
266-
unsigned int cs = spi->chip_select;
267-
unsigned int cspol;
268-
269-
/*
270-
* If there are no chip selects at all, or if this is the special
271-
* case of a non-existent (dummy) chip select, do nothing.
272-
*/
273-
274-
if (!hw->master->num_chipselect || hw->gpios[cs] == -EEXIST)
275-
return;
276-
277-
cspol = spi->mode & SPI_CS_HIGH ? 1 : 0;
278-
if (value == BITBANG_CS_INACTIVE)
279-
cspol = !cspol;
280-
281-
gpio_set_value(hw->gpios[cs], cspol);
282-
}
283-
284259
static irqreturn_t spi_ppc4xx_int(int irq, void *dev_id)
285260
{
286261
struct ppc4xx_spi *hw;
@@ -359,19 +334,6 @@ static void spi_ppc4xx_enable(struct ppc4xx_spi *hw)
359334
dcri_clrset(SDR0, SDR0_PFC1, 0x80000000 >> 14, 0);
360335
}
361336

362-
static void free_gpios(struct ppc4xx_spi *hw)
363-
{
364-
if (hw->master->num_chipselect) {
365-
int i;
366-
for (i = 0; i < hw->master->num_chipselect; i++)
367-
if (gpio_is_valid(hw->gpios[i]))
368-
gpio_free(hw->gpios[i]);
369-
370-
kfree(hw->gpios);
371-
hw->gpios = NULL;
372-
}
373-
}
374-
375337
/*
376338
* platform_device layer stuff...
377339
*/
@@ -385,7 +347,6 @@ static int spi_ppc4xx_of_probe(struct platform_device *op)
385347
struct device *dev = &op->dev;
386348
struct device_node *opbnp;
387349
int ret;
388-
int num_gpios;
389350
const unsigned int *clk;
390351

391352
master = spi_alloc_master(dev, sizeof *hw);
@@ -399,82 +360,40 @@ static int spi_ppc4xx_of_probe(struct platform_device *op)
399360

400361
init_completion(&hw->done);
401362

402-
/*
403-
* A count of zero implies a single SPI device without any chip-select.
404-
* Note that of_gpio_count counts all gpios assigned to this spi master.
405-
* This includes both "null" gpio's and real ones.
406-
*/
407-
num_gpios = of_gpio_count(np);
408-
if (num_gpios > 0) {
409-
int i;
410-
411-
hw->gpios = kcalloc(num_gpios, sizeof(*hw->gpios), GFP_KERNEL);
412-
if (!hw->gpios) {
413-
ret = -ENOMEM;
414-
goto free_master;
415-
}
416-
417-
for (i = 0; i < num_gpios; i++) {
418-
int gpio;
419-
enum of_gpio_flags flags;
420-
421-
gpio = of_get_gpio_flags(np, i, &flags);
422-
hw->gpios[i] = gpio;
423-
424-
if (gpio_is_valid(gpio)) {
425-
/* Real CS - set the initial state. */
426-
ret = gpio_request(gpio, np->name);
427-
if (ret < 0) {
428-
dev_err(dev,
429-
"can't request gpio #%d: %d\n",
430-
i, ret);
431-
goto free_gpios;
432-
}
433-
434-
gpio_direction_output(gpio,
435-
!!(flags & OF_GPIO_ACTIVE_LOW));
436-
} else if (gpio == -EEXIST) {
437-
; /* No CS, but that's OK. */
438-
} else {
439-
dev_err(dev, "invalid gpio #%d: %d\n", i, gpio);
440-
ret = -EINVAL;
441-
goto free_gpios;
442-
}
443-
}
444-
}
445-
446363
/* Setup the state for the bitbang driver */
447364
bbp = &hw->bitbang;
448365
bbp->master = hw->master;
449366
bbp->setup_transfer = spi_ppc4xx_setupxfer;
450-
bbp->chipselect = spi_ppc4xx_chipsel;
451367
bbp->txrx_bufs = spi_ppc4xx_txrx;
452368
bbp->use_dma = 0;
453369
bbp->master->setup = spi_ppc4xx_setup;
454370
bbp->master->cleanup = spi_ppc4xx_cleanup;
455371
bbp->master->bits_per_word_mask = SPI_BPW_MASK(8);
372+
bbp->master->use_gpio_descriptors = true;
373+
/*
374+
* The SPI core will count the number of GPIO descriptors to figure
375+
* out the number of chip selects available on the platform.
376+
*/
377+
bbp->master->num_chipselect = 0;
456378

457379
/* the spi->mode bits understood by this driver: */
458380
bbp->master->mode_bits =
459381
SPI_CPHA | SPI_CPOL | SPI_CS_HIGH | SPI_LSB_FIRST;
460382

461-
/* this many pins in all GPIO controllers */
462-
bbp->master->num_chipselect = num_gpios > 0 ? num_gpios : 0;
463-
464383
/* Get the clock for the OPB */
465384
opbnp = of_find_compatible_node(NULL, NULL, "ibm,opb");
466385
if (opbnp == NULL) {
467386
dev_err(dev, "OPB: cannot find node\n");
468387
ret = -ENODEV;
469-
goto free_gpios;
388+
goto free_master;
470389
}
471390
/* Get the clock (Hz) for the OPB */
472391
clk = of_get_property(opbnp, "clock-frequency", NULL);
473392
if (clk == NULL) {
474393
dev_err(dev, "OPB: no clock-frequency property set\n");
475394
of_node_put(opbnp);
476395
ret = -ENODEV;
477-
goto free_gpios;
396+
goto free_master;
478397
}
479398
hw->opb_freq = *clk;
480399
hw->opb_freq >>= 2;
@@ -483,7 +402,7 @@ static int spi_ppc4xx_of_probe(struct platform_device *op)
483402
ret = of_address_to_resource(np, 0, &resource);
484403
if (ret) {
485404
dev_err(dev, "error while parsing device node resource\n");
486-
goto free_gpios;
405+
goto free_master;
487406
}
488407
hw->mapbase = resource.start;
489408
hw->mapsize = resource_size(&resource);
@@ -492,7 +411,7 @@ static int spi_ppc4xx_of_probe(struct platform_device *op)
492411
if (hw->mapsize < sizeof(struct spi_ppc4xx_regs)) {
493412
dev_err(dev, "too small to map registers\n");
494413
ret = -EINVAL;
495-
goto free_gpios;
414+
goto free_master;
496415
}
497416

498417
/* Request IRQ */
@@ -501,7 +420,7 @@ static int spi_ppc4xx_of_probe(struct platform_device *op)
501420
0, "spi_ppc4xx_of", (void *)hw);
502421
if (ret) {
503422
dev_err(dev, "unable to allocate interrupt\n");
504-
goto free_gpios;
423+
goto free_master;
505424
}
506425

507426
if (!request_mem_region(hw->mapbase, hw->mapsize, DRIVER_NAME)) {
@@ -538,8 +457,6 @@ static int spi_ppc4xx_of_probe(struct platform_device *op)
538457
release_mem_region(hw->mapbase, hw->mapsize);
539458
request_mem_error:
540459
free_irq(hw->irqnum, hw);
541-
free_gpios:
542-
free_gpios(hw);
543460
free_master:
544461
spi_master_put(master);
545462

@@ -556,7 +473,6 @@ static int spi_ppc4xx_of_remove(struct platform_device *op)
556473
release_mem_region(hw->mapbase, hw->mapsize);
557474
free_irq(hw->irqnum, hw);
558475
iounmap(hw->regs);
559-
free_gpios(hw);
560476
spi_master_put(master);
561477
return 0;
562478
}

0 commit comments

Comments
 (0)