summaryrefslogtreecommitdiffstats
path: root/drivers/staging/vme/devices/vme_pio2_core.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2017-11-13 20:53:28 -0800
committerLinus Torvalds <torvalds@linux-foundation.org>2017-11-13 20:53:28 -0800
commit449fcf3ab0baf3dde9952385e6789f2ca10c3980 (patch)
tree180f10c2cdd63836e47725cddc8850ca7144091a /drivers/staging/vme/devices/vme_pio2_core.c
parent3c073991eb417b6f785ddc6afbbdc369eb84aa6a (diff)
parentc14dd9d5f8beda9d8c621683b4e7d6cb5cd3cda7 (diff)
downloadlinux-449fcf3ab0baf3dde9952385e6789f2ca10c3980.tar.bz2
Merge tag 'staging-4.15-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging
Pull staging and IIO updates from Greg KH: "Here is the "big" staging and IIO driver update for 4.15-rc1. Lots and lots of little changes, almost all minor code cleanups as the Outreachy application process happened during this development cycle. Also happened was a lot of IIO driver activity, and the typec USB code moving out of staging to drivers/usb (same commits are in the USB tree on a persistent branch to not cause merge issues.) Overall, it's a wash, I think we added a few hundred more lines than removed, but really only a few thousand were modified at all. All of these have been in linux-next for a while. There might be a merge issue with Al's vfs tree in the pi433 driver (take his changes, they are always better), and the media tree with some of the odd atomisp cleanups (take the media tree's version)" * tag 'staging-4.15-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging: (507 commits) staging: lustre: add SPDX identifiers to all lustre files staging: greybus: Remove redundant license text staging: greybus: add SPDX identifiers to all greybus driver files staging: ccree: simplify ioread/iowrite staging: ccree: simplify registers access staging: ccree: simplify error handling logic staging: ccree: remove dead code staging: ccree: handle limiting of DMA masks staging: ccree: copy IV to DMAable memory staging: fbtft: remove redundant initialization of buf staging: sm750fb: Fix parameter mistake in poke32 staging: wilc1000: Fix bssid buffer offset in Txq staging: fbtft: fb_ssd1331: fix mirrored display staging: android: Fix checkpatch.pl error staging: greybus: loopback: convert loopback to use generic async operations staging: greybus: operation: add private data with get/set accessors staging: greybus: loopback: Fix iteration count on async path staging: greybus: loopback: Hold per-connection mutex across operations staging: greybus/loopback: use ktime_get() for time intervals staging: fsl-dpaa2/eth: Extra headroom in RX buffers ...
Diffstat (limited to 'drivers/staging/vme/devices/vme_pio2_core.c')
-rw-r--r--drivers/staging/vme/devices/vme_pio2_core.c493
1 files changed, 0 insertions, 493 deletions
diff --git a/drivers/staging/vme/devices/vme_pio2_core.c b/drivers/staging/vme/devices/vme_pio2_core.c
deleted file mode 100644
index 367535b4b77f..000000000000
--- a/drivers/staging/vme/devices/vme_pio2_core.c
+++ /dev/null
@@ -1,493 +0,0 @@
-/*
- * GE PIO2 6U VME I/O Driver
- *
- * Author: Martyn Welch <martyn.welch@ge.com>
- * Copyright 2009 GE Intelligent Platforms Embedded Systems, Inc.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/device.h>
-#include <linux/ctype.h>
-#include <linux/gpio.h>
-#include <linux/slab.h>
-#include <linux/vme.h>
-
-#include "vme_pio2.h"
-
-static const char driver_name[] = "pio2";
-
-static int bus[PIO2_CARDS_MAX];
-static int bus_num;
-static long base[PIO2_CARDS_MAX];
-static int base_num;
-static int vector[PIO2_CARDS_MAX];
-static int vector_num;
-static int level[PIO2_CARDS_MAX];
-static int level_num;
-static char *variant[PIO2_CARDS_MAX];
-static int variant_num;
-
-static bool loopback;
-
-static int pio2_match(struct vme_dev *);
-static int pio2_probe(struct vme_dev *);
-static int pio2_remove(struct vme_dev *);
-
-static int pio2_get_led(struct pio2_card *card)
-{
- /* Can't read hardware, state saved in structure */
- return card->led;
-}
-
-static int pio2_set_led(struct pio2_card *card, int state)
-{
- u8 reg;
- int retval;
-
- reg = card->irq_level;
-
- /* Register state inverse of led state */
- if (!state)
- reg |= PIO2_LED;
-
- if (loopback)
- reg |= PIO2_LOOP;
-
- retval = vme_master_write(card->window, &reg, 1, PIO2_REGS_CTRL);
- if (retval < 0)
- return retval;
-
- card->led = state ? 1 : 0;
-
- return 0;
-}
-
-static void pio2_int(int level, int vector, void *ptr)
-{
- int vec, i, channel, retval;
- u8 reg;
- struct pio2_card *card = ptr;
-
- vec = vector & ~PIO2_VME_VECTOR_MASK;
-
- switch (vec) {
- case 0:
- dev_warn(&card->vdev->dev, "Spurious Interrupt\n");
- break;
- case 1:
- case 2:
- case 3:
- case 4:
- /* Channels 0 to 7 */
- retval = vme_master_read(card->window, &reg, 1,
- PIO2_REGS_INT_STAT[vec - 1]);
- if (retval < 0) {
- dev_err(&card->vdev->dev,
- "Unable to read IRQ status register\n");
- return;
- }
- for (i = 0; i < 8; i++) {
- channel = ((vec - 1) * 8) + i;
- if (reg & PIO2_CHANNEL_BIT[channel])
- dev_info(&card->vdev->dev,
- "Interrupt on I/O channel %d\n",
- channel);
- }
- break;
- case 5:
- case 6:
- case 7:
- case 8:
- case 9:
- case 10:
- /* Counters are dealt with by their own handler */
- dev_err(&card->vdev->dev,
- "Counter interrupt\n");
- break;
- }
-}
-
-/*
- * We return whether this has been successful - this is used in the probe to
- * ensure we have a valid card.
- */
-static int pio2_reset_card(struct pio2_card *card)
-{
- int retval = 0;
- u8 data = 0;
-
- /* Clear main register*/
- retval = vme_master_write(card->window, &data, 1, PIO2_REGS_CTRL);
- if (retval < 0)
- return retval;
-
- /* Clear VME vector */
- retval = vme_master_write(card->window, &data, 1, PIO2_REGS_VME_VECTOR);
- if (retval < 0)
- return retval;
-
- /* Reset GPIO */
- retval = pio2_gpio_reset(card);
- if (retval < 0)
- return retval;
-
- /* Reset counters */
- retval = pio2_cntr_reset(card);
- if (retval < 0)
- return retval;
-
- return 0;
-}
-
-static struct vme_driver pio2_driver = {
- .name = driver_name,
- .match = pio2_match,
- .probe = pio2_probe,
- .remove = pio2_remove,
-};
-
-static int __init pio2_init(void)
-{
- if (bus_num == 0) {
- pr_err("No cards, skipping registration\n");
- return -ENODEV;
- }
-
- if (bus_num > PIO2_CARDS_MAX) {
- pr_err("Driver only able to handle %d PIO2 Cards\n",
- PIO2_CARDS_MAX);
- bus_num = PIO2_CARDS_MAX;
- }
-
- /* Register the PIO2 driver */
- return vme_register_driver(&pio2_driver, bus_num);
-}
-
-static int pio2_match(struct vme_dev *vdev)
-{
- if (vdev->num >= bus_num) {
- dev_err(&vdev->dev,
- "The enumeration of the VMEbus to which the board is connected must be specified\n");
- return 0;
- }
-
- if (vdev->num >= base_num) {
- dev_err(&vdev->dev,
- "The VME address for the cards registers must be specified\n");
- return 0;
- }
-
- if (vdev->num >= vector_num) {
- dev_err(&vdev->dev,
- "The IRQ vector used by the card must be specified\n");
- return 0;
- }
-
- if (vdev->num >= level_num) {
- dev_err(&vdev->dev,
- "The IRQ level used by the card must be specified\n");
- return 0;
- }
-
- if (vdev->num >= variant_num) {
- dev_err(&vdev->dev, "The variant of the card must be specified\n");
- return 0;
- }
-
- return 1;
-}
-
-static int pio2_probe(struct vme_dev *vdev)
-{
- struct pio2_card *card;
- int retval;
- int i;
- u8 reg;
- int vec;
-
- card = devm_kzalloc(&vdev->dev, sizeof(*card), GFP_KERNEL);
- if (!card)
- return -ENOMEM;
-
- card->id = vdev->num;
- card->bus = bus[card->id];
- card->base = base[card->id];
- card->irq_vector = vector[card->id];
- card->irq_level = level[card->id] & PIO2_VME_INT_MASK;
- strncpy(card->variant, variant[card->id], PIO2_VARIANT_LENGTH);
- card->vdev = vdev;
-
- for (i = 0; i < PIO2_VARIANT_LENGTH; i++) {
- if (!isdigit(card->variant[i])) {
- dev_err(&card->vdev->dev, "Variant invalid\n");
- return -EINVAL;
- }
- }
-
- /*
- * Bottom 4 bits of VME interrupt vector used to determine source,
- * provided vector should only use upper 4 bits.
- */
- if (card->irq_vector & ~PIO2_VME_VECTOR_MASK) {
- dev_err(&card->vdev->dev,
- "Invalid VME IRQ Vector, vector must not use lower 4 bits\n");
- return -EINVAL;
- }
-
- /*
- * There is no way to determine the build variant or whether each bank
- * is input, output or both at run time. The inputs are also inverted
- * if configured as both.
- *
- * We pass in the board variant and use that to determine the
- * configuration of the banks.
- */
- for (i = 1; i < PIO2_VARIANT_LENGTH; i++) {
- switch (card->variant[i]) {
- case '0':
- card->bank[i - 1].config = NOFIT;
- break;
- case '1':
- case '2':
- case '3':
- case '4':
- card->bank[i - 1].config = INPUT;
- break;
- case '5':
- card->bank[i - 1].config = OUTPUT;
- break;
- case '6':
- case '7':
- case '8':
- case '9':
- card->bank[i - 1].config = BOTH;
- break;
- }
- }
-
- /* Get a master window and position over regs */
- card->window = vme_master_request(vdev, VME_A24, VME_SCT, VME_D16);
- if (!card->window) {
- dev_err(&card->vdev->dev,
- "Unable to assign VME master resource\n");
- return -EIO;
- }
-
- retval = vme_master_set(card->window, 1, card->base, 0x10000, VME_A24,
- VME_SCT | VME_USER | VME_DATA, VME_D16);
- if (retval) {
- dev_err(&card->vdev->dev,
- "Unable to configure VME master resource\n");
- goto err_set;
- }
-
- /*
- * There is also no obvious register which we can probe to determine
- * whether the provided base is valid. If we can read the "ID Register"
- * offset and the reset function doesn't error, assume we have a valid
- * location.
- */
- retval = vme_master_read(card->window, &reg, 1, PIO2_REGS_ID);
- if (retval < 0) {
- dev_err(&card->vdev->dev, "Unable to read from device\n");
- goto err_read;
- }
-
- dev_dbg(&card->vdev->dev, "ID Register:%x\n", reg);
-
- /*
- * Ensure all the I/O is cleared. We can't read back the states, so
- * this is the only method we have to ensure that the I/O is in a known
- * state.
- */
- retval = pio2_reset_card(card);
- if (retval) {
- dev_err(&card->vdev->dev,
- "Failed to reset card, is location valid?\n");
- retval = -ENODEV;
- goto err_reset;
- }
-
- /* Configure VME Interrupts */
- reg = card->irq_level;
- if (pio2_get_led(card))
- reg |= PIO2_LED;
- if (loopback)
- reg |= PIO2_LOOP;
- retval = vme_master_write(card->window, &reg, 1, PIO2_REGS_CTRL);
- if (retval < 0)
- return retval;
-
- /* Set VME vector */
- retval = vme_master_write(card->window, &card->irq_vector, 1,
- PIO2_REGS_VME_VECTOR);
- if (retval < 0)
- return retval;
-
- /* Attach spurious interrupt handler. */
- vec = card->irq_vector | PIO2_VME_VECTOR_SPUR;
-
- retval = vme_irq_request(vdev, card->irq_level, vec,
- &pio2_int, card);
- if (retval < 0) {
- dev_err(&card->vdev->dev,
- "Unable to attach VME interrupt vector0x%x, level 0x%x\n",
- vec, card->irq_level);
- goto err_irq;
- }
-
- /* Attach GPIO interrupt handlers. */
- for (i = 0; i < 4; i++) {
- vec = card->irq_vector | PIO2_VECTOR_BANK[i];
-
- retval = vme_irq_request(vdev, card->irq_level, vec,
- &pio2_int, card);
- if (retval < 0) {
- dev_err(&card->vdev->dev,
- "Unable to attach VME interrupt vector0x%x, level 0x%x\n",
- vec, card->irq_level);
- goto err_gpio_irq;
- }
- }
-
- /* Attach counter interrupt handlers. */
- for (i = 0; i < 6; i++) {
- vec = card->irq_vector | PIO2_VECTOR_CNTR[i];
-
- retval = vme_irq_request(vdev, card->irq_level, vec,
- &pio2_int, card);
- if (retval < 0) {
- dev_err(&card->vdev->dev,
- "Unable to attach VME interrupt vector0x%x, level 0x%x\n",
- vec, card->irq_level);
- goto err_cntr_irq;
- }
- }
-
- /* Register IO */
- retval = pio2_gpio_init(card);
- if (retval < 0) {
- dev_err(&card->vdev->dev,
- "Unable to register with GPIO framework\n");
- goto err_gpio;
- }
-
- /* Set LED - This also sets interrupt level */
- retval = pio2_set_led(card, 0);
- if (retval < 0) {
- dev_err(&card->vdev->dev, "Unable to set LED\n");
- goto err_led;
- }
-
- dev_set_drvdata(&card->vdev->dev, card);
-
- dev_info(&card->vdev->dev,
- "PIO2 (variant %s) configured at 0x%lx\n", card->variant,
- card->base);
-
- return 0;
-
-err_led:
- pio2_gpio_exit(card);
-err_gpio:
- i = 6;
-err_cntr_irq:
- while (i > 0) {
- i--;
- vec = card->irq_vector | PIO2_VECTOR_CNTR[i];
- vme_irq_free(vdev, card->irq_level, vec);
- }
-
- i = 4;
-err_gpio_irq:
- while (i > 0) {
- i--;
- vec = card->irq_vector | PIO2_VECTOR_BANK[i];
- vme_irq_free(vdev, card->irq_level, vec);
- }
-
- vec = (card->irq_vector & PIO2_VME_VECTOR_MASK) | PIO2_VME_VECTOR_SPUR;
- vme_irq_free(vdev, card->irq_level, vec);
-err_irq:
- pio2_reset_card(card);
-err_reset:
-err_read:
- vme_master_set(card->window, 0, 0, 0, VME_A16, 0, VME_D16);
-err_set:
- vme_master_free(card->window);
- return retval;
-}
-
-static int pio2_remove(struct vme_dev *vdev)
-{
- int vec;
- int i;
-
- struct pio2_card *card = dev_get_drvdata(&vdev->dev);
-
- pio2_gpio_exit(card);
-
- for (i = 0; i < 6; i++) {
- vec = card->irq_vector | PIO2_VECTOR_CNTR[i];
- vme_irq_free(vdev, card->irq_level, vec);
- }
-
- for (i = 0; i < 4; i++) {
- vec = card->irq_vector | PIO2_VECTOR_BANK[i];
- vme_irq_free(vdev, card->irq_level, vec);
- }
-
- vec = (card->irq_vector & PIO2_VME_VECTOR_MASK) | PIO2_VME_VECTOR_SPUR;
- vme_irq_free(vdev, card->irq_level, vec);
-
- pio2_reset_card(card);
-
- vme_master_set(card->window, 0, 0, 0, VME_A16, 0, VME_D16);
-
- vme_master_free(card->window);
-
- return 0;
-}
-
-static void __exit pio2_exit(void)
-{
- vme_unregister_driver(&pio2_driver);
-}
-
-/* These are required for each board */
-MODULE_PARM_DESC(bus, "Enumeration of VMEbus to which the board is connected");
-module_param_hw_array(bus, int, other, &bus_num, 0444);
-
-MODULE_PARM_DESC(base, "Base VME address for PIO2 Registers");
-module_param_hw_array(base, long, other, &base_num, 0444);
-
-MODULE_PARM_DESC(vector, "VME IRQ Vector (Lower 4 bits masked)");
-module_param_hw_array(vector, int, other, &vector_num, 0444);
-
-MODULE_PARM_DESC(level, "VME IRQ Level");
-module_param_hw_array(level, int, other, &level_num, 0444);
-
-MODULE_PARM_DESC(variant, "Last 4 characters of PIO2 board variant");
-module_param_array(variant, charp, &variant_num, 0444);
-
-/* This is for debugging */
-MODULE_PARM_DESC(loopback, "Enable loopback mode on all cards");
-module_param(loopback, bool, 0444);
-
-MODULE_DESCRIPTION("GE PIO2 6U VME I/O Driver");
-MODULE_AUTHOR("Martyn Welch <martyn.welch@ge.com");
-MODULE_LICENSE("GPL");
-
-module_init(pio2_init);
-module_exit(pio2_exit);
-