Skip to content

Commit

Permalink
Staging: ipack/bridges/tpci200: provide new callbacks to tpci200
Browse files Browse the repository at this point in the history
Provide get_clockrate, set_clockrate, get_error, get_timeout and reset_timeout
callbacks.

Signed-off-by: Jens Taprogge <jens.taprogge@taprogge.org>
Signed-off-by: Samuel Iglesias Gonsálvez <siglesias@igalia.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
  • Loading branch information
Jens Taprogge authored and Greg Kroah-Hartman committed Sep 11, 2012
1 parent 7b6ab33 commit eb12d88
Showing 1 changed file with 108 additions and 1 deletion.
109 changes: 108 additions & 1 deletion drivers/staging/ipack/bridges/tpci200.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,20 @@
#include <linux/module.h>
#include "tpci200.h"

static u16 tpci200_status_timeout[] = {
TPCI200_A_TIMEOUT,
TPCI200_B_TIMEOUT,
TPCI200_C_TIMEOUT,
TPCI200_D_TIMEOUT,
};

static u16 tpci200_status_error[] = {
TPCI200_A_ERROR,
TPCI200_B_ERROR,
TPCI200_C_ERROR,
TPCI200_D_ERROR,
};

static int tpci200_slot_unregister(struct ipack_device *dev);

static struct tpci200_board *check_slot(struct ipack_device *dev)
Expand Down Expand Up @@ -505,6 +519,94 @@ static int tpci200_request_irq(struct ipack_device *dev, int vector,
return res;
}

static int tpci200_get_clockrate(struct ipack_device *dev)
{
struct tpci200_board *tpci200 = check_slot(dev);
u16 __iomem *addr;

if (!tpci200)
return -ENODEV;

addr = &tpci200->info->interface_regs->control[dev->slot];
return (ioread16(addr) & TPCI200_CLK32) ? 32 : 8;
}

static int tpci200_set_clockrate(struct ipack_device *dev, int mherz)
{
struct tpci200_board *tpci200 = check_slot(dev);
u16 __iomem *addr;
u16 reg;

if (!tpci200)
return -ENODEV;

addr = &tpci200->info->interface_regs->control[dev->slot];

/* Ensure the control register is not changed by another task after we
* have read it. */
mutex_lock(&tpci200->mutex);
reg = ioread16(addr);
switch (mherz) {
case 8:
reg &= ~(TPCI200_CLK32);
break;
case 32:
reg |= TPCI200_CLK32;
break;
default:
mutex_unlock(&tpci200->mutex);
return -EINVAL;
}
iowrite16(reg, addr);
mutex_unlock(&tpci200->mutex);
return 0;
}

static int tpci200_get_error(struct ipack_device *dev)
{
struct tpci200_board *tpci200 = check_slot(dev);
u16 __iomem *addr;
u16 mask;

if (!tpci200)
return -ENODEV;

addr = &tpci200->info->interface_regs->status;
mask = tpci200_status_error[dev->slot];
return (ioread16(addr) & mask) ? 1 : 0;
}

static int tpci200_get_timeout(struct ipack_device *dev)
{
struct tpci200_board *tpci200 = check_slot(dev);
u16 __iomem *addr;
u16 mask;

if (!tpci200)
return -ENODEV;

addr = &tpci200->info->interface_regs->status;
mask = tpci200_status_timeout[dev->slot];

return (ioread16(addr) & mask) ? 1 : 0;
}

static int tpci200_reset_timeout(struct ipack_device *dev)
{
struct tpci200_board *tpci200 = check_slot(dev);
u16 __iomem *addr;
u16 mask;

if (!tpci200)
return -ENODEV;

addr = &tpci200->info->interface_regs->status;
mask = tpci200_status_timeout[dev->slot];

iowrite16(mask, addr);
return 0;
}

static void tpci200_uninstall(struct tpci200_board *tpci200)
{
int i;
Expand All @@ -522,6 +624,11 @@ static const struct ipack_bus_ops tpci200_bus_ops = {
.request_irq = tpci200_request_irq,
.free_irq = tpci200_free_irq,
.remove_device = tpci200_slot_unregister,
.get_clockrate = tpci200_get_clockrate,
.set_clockrate = tpci200_set_clockrate,
.get_error = tpci200_get_error,
.get_timeout = tpci200_get_timeout,
.reset_timeout = tpci200_reset_timeout,
};

static int tpci200_install(struct tpci200_board *tpci200)
Expand Down Expand Up @@ -549,7 +656,7 @@ static int tpci200_pci_probe(struct pci_dev *pdev,
{
int ret, i;
struct tpci200_board *tpci200;
__le32 reg32;
u32 reg32;

tpci200 = kzalloc(sizeof(struct tpci200_board), GFP_KERNEL);
if (!tpci200)
Expand Down

0 comments on commit eb12d88

Please sign in to comment.