* [PATCH 01/17] Staging: ipack: get rid of ipack_device->bus_nr.
@ 2012-09-27 10:37 Samuel Iglesias Gonsalvez
2012-09-27 10:37 ` [PATCH 02/17] Staging: ipack: Make ipack_device_register() analogous to device_register() Samuel Iglesias Gonsalvez
` (15 more replies)
0 siblings, 16 replies; 17+ messages in thread
From: Samuel Iglesias Gonsalvez @ 2012-09-27 10:37 UTC (permalink / raw)
To: Greg Kroah-Hartman
Cc: devel, linux-kernel, industrypack-devel, Jens Taprogge,
Samuel Iglesias Gonsalvez
From: Jens Taprogge <jens.taprogge@taprogge.org>
It is replicating information contained in ipack_device->bus->bus_nr.
Signed-off-by: Jens Taprogge <jens.taprogge@taprogge.org>
Signed-off-by: Samuel Iglesias Gonsalvez <siglesias@igalia.com>
---
drivers/staging/ipack/bridges/tpci200.c | 18 +++++++++---------
drivers/staging/ipack/devices/ipoctal.c | 2 +-
drivers/staging/ipack/ipack.c | 5 ++---
drivers/staging/ipack/ipack.h | 2 --
4 files changed, 12 insertions(+), 15 deletions(-)
diff --git a/drivers/staging/ipack/bridges/tpci200.c b/drivers/staging/ipack/bridges/tpci200.c
index bb8aa70..2f48dd5 100644
--- a/drivers/staging/ipack/bridges/tpci200.c
+++ b/drivers/staging/ipack/bridges/tpci200.c
@@ -46,7 +46,7 @@ static struct tpci200_board *check_slot(struct ipack_device *dev)
if (dev->slot >= TPCI200_NB_SLOT) {
dev_info(&dev->dev,
"Slot [%d:%d] doesn't exist! Last tpci200 slot is %d.\n",
- dev->bus_nr, dev->slot, TPCI200_NB_SLOT-1);
+ dev->bus->bus_nr, dev->slot, TPCI200_NB_SLOT-1);
return NULL;
}
@@ -206,7 +206,7 @@ static int tpci200_request_irq(struct ipack_device *dev,
if (tpci200->slots[dev->slot].irq != NULL) {
dev_err(&dev->dev,
- "Slot [%d:%d] IRQ already registered !\n", dev->bus_nr,
+ "Slot [%d:%d] IRQ already registered !\n", dev->bus->bus_nr,
dev->slot);
res = -EINVAL;
goto out_unlock;
@@ -216,7 +216,7 @@ static int tpci200_request_irq(struct ipack_device *dev,
if (slot_irq == NULL) {
dev_err(&dev->dev,
"Slot [%d:%d] unable to allocate memory for IRQ !\n",
- dev->bus_nr, dev->slot);
+ dev->bus->bus_nr, dev->slot);
res = -ENOMEM;
goto out_unlock;
}
@@ -379,7 +379,7 @@ static int tpci200_slot_unmap_space(struct ipack_device *dev, int space)
if (dev->io_space.address == NULL) {
dev_info(&dev->dev,
"Slot [%d:%d] IO space not mapped !\n",
- dev->bus_nr, dev->slot);
+ dev->bus->bus_nr, dev->slot);
goto out_unlock;
}
virt_addr_space = &dev->io_space;
@@ -388,7 +388,7 @@ static int tpci200_slot_unmap_space(struct ipack_device *dev, int space)
if (dev->id_space.address == NULL) {
dev_info(&dev->dev,
"Slot [%d:%d] ID space not mapped !\n",
- dev->bus_nr, dev->slot);
+ dev->bus->bus_nr, dev->slot);
goto out_unlock;
}
virt_addr_space = &dev->id_space;
@@ -397,7 +397,7 @@ static int tpci200_slot_unmap_space(struct ipack_device *dev, int space)
if (dev->int_space.address == NULL) {
dev_info(&dev->dev,
"Slot [%d:%d] INT space not mapped !\n",
- dev->bus_nr, dev->slot);
+ dev->bus->bus_nr, dev->slot);
goto out_unlock;
}
virt_addr_space = &dev->int_space;
@@ -406,7 +406,7 @@ static int tpci200_slot_unmap_space(struct ipack_device *dev, int space)
if (dev->mem_space.address == NULL) {
dev_info(&dev->dev,
"Slot [%d:%d] MEM space not mapped !\n",
- dev->bus_nr, dev->slot);
+ dev->bus->bus_nr, dev->slot);
goto out_unlock;
}
virt_addr_space = &dev->mem_space;
@@ -414,7 +414,7 @@ static int tpci200_slot_unmap_space(struct ipack_device *dev, int space)
default:
dev_err(&dev->dev,
"Slot [%d:%d] space number %d doesn't exist !\n",
- dev->bus_nr, dev->slot, space);
+ dev->bus->bus_nr, dev->slot, space);
mutex_unlock(&tpci200->mutex);
return -EINVAL;
}
@@ -497,7 +497,7 @@ static int tpci200_slot_map_space(struct ipack_device *dev,
if (memory_size > tpci200->slots[dev->slot].mem_phys.size) {
dev_err(&dev->dev,
"Slot [%d:%d] request is 0x%X memory, only 0x%X available !\n",
- dev->bus_nr, dev->slot, memory_size,
+ dev->bus->bus_nr, dev->slot, memory_size,
tpci200->slots[dev->slot].mem_phys.size);
res = -EINVAL;
goto out_unlock;
diff --git a/drivers/staging/ipack/devices/ipoctal.c b/drivers/staging/ipack/devices/ipoctal.c
index 2cdbf28..14a0aed 100644
--- a/drivers/staging/ipack/devices/ipoctal.c
+++ b/drivers/staging/ipack/devices/ipoctal.c
@@ -719,7 +719,7 @@ static int ipoctal_probe(struct ipack_device *dev)
return -ENOMEM;
ipoctal->dev = dev;
- res = ipoctal_inst_slot(ipoctal, dev->bus_nr, dev->slot);
+ res = ipoctal_inst_slot(ipoctal, dev->bus->bus_nr, dev->slot);
if (res)
goto out_uninst;
diff --git a/drivers/staging/ipack/ipack.c b/drivers/staging/ipack/ipack.c
index d1e0651..ca8cb327 100644
--- a/drivers/staging/ipack/ipack.c
+++ b/drivers/staging/ipack/ipack.c
@@ -234,7 +234,7 @@ static int ipack_unregister_bus_member(struct device *dev, void *data)
struct ipack_device *idev = to_ipack_dev(dev);
struct ipack_bus_device *bus = data;
- if (idev->bus_nr == bus->bus_nr)
+ if (idev->bus == bus)
ipack_device_unregister(idev);
return 1;
@@ -440,10 +440,9 @@ struct ipack_device *ipack_device_register(struct ipack_bus_device *bus,
dev->dev.release = ipack_device_release;
dev->dev.parent = bus->parent;
dev->slot = slot;
- dev->bus_nr = bus->bus_nr;
dev->bus = bus;
dev_set_name(&dev->dev,
- "ipack-dev.%u.%u", dev->bus_nr, dev->slot);
+ "ipack-dev.%u.%u", dev->bus->bus_nr, dev->slot);
if (bus->ops->set_clockrate(dev, 8))
dev_warn(&dev->dev, "failed to switch to 8 MHz operation for reading of device ID.\n");
diff --git a/drivers/staging/ipack/ipack.h b/drivers/staging/ipack/ipack.h
index d8e3bb6..33fdea5 100644
--- a/drivers/staging/ipack/ipack.h
+++ b/drivers/staging/ipack/ipack.h
@@ -52,7 +52,6 @@ struct ipack_addr_space {
/**
* struct ipack_device
*
- * @bus_nr: IP bus number where the device is plugged
* @slot: Slot where the device is plugged in the carrier board
* @bus: ipack_bus_device where the device is plugged to.
* @id_space: Virtual address to ID space.
@@ -65,7 +64,6 @@ struct ipack_addr_space {
* by the carrier board throught bus->ops.
*/
struct ipack_device {
- unsigned int bus_nr;
unsigned int slot;
struct ipack_bus_device *bus;
struct ipack_addr_space id_space;
--
1.7.10.4
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH 02/17] Staging: ipack: Make ipack_device_register() analogous to device_register().
2012-09-27 10:37 [PATCH 01/17] Staging: ipack: get rid of ipack_device->bus_nr Samuel Iglesias Gonsalvez
@ 2012-09-27 10:37 ` Samuel Iglesias Gonsalvez
2012-09-27 10:37 ` [PATCH 03/17] Staging: ipack/bridges/tpci200: Don't map memory spaces that are not used later on Samuel Iglesias Gonsalvez
` (14 subsequent siblings)
15 siblings, 0 replies; 17+ messages in thread
From: Samuel Iglesias Gonsalvez @ 2012-09-27 10:37 UTC (permalink / raw)
To: Greg Kroah-Hartman
Cc: devel, linux-kernel, industrypack-devel, Jens Taprogge,
Samuel Iglesias Gonsalvez
From: Jens Taprogge <jens.taprogge@taprogge.org>
ipack_device_register() is no longer creating the struct ipack_device
but only registering it. Instead of releasing memory directly the new
ipack_device->release callback is called.
This is preparational work for later patches.
Signed-off-by: Jens Taprogge <jens.taprogge@taprogge.org>
Signed-off-by: Samuel Iglesias Gonsalvez <siglesias@igalia.com>
---
drivers/staging/ipack/bridges/tpci200.c | 19 ++++++++++++++++++-
drivers/staging/ipack/ipack.c | 30 +++++++++---------------------
drivers/staging/ipack/ipack.h | 15 +++++++++------
3 files changed, 36 insertions(+), 28 deletions(-)
diff --git a/drivers/staging/ipack/bridges/tpci200.c b/drivers/staging/ipack/bridges/tpci200.c
index 2f48dd5..ee66129 100644
--- a/drivers/staging/ipack/bridges/tpci200.c
+++ b/drivers/staging/ipack/bridges/tpci200.c
@@ -640,6 +640,23 @@ static int tpci200_install(struct tpci200_board *tpci200)
return 0;
}
+static void tpci200_release_device(struct ipack_device *dev)
+{
+ kfree(dev);
+}
+
+static int tpci200_create_device(struct tpci200_board *tpci200, int i)
+{
+ struct ipack_device *dev =
+ kzalloc(sizeof(struct ipack_device), GFP_KERNEL);
+ if (!dev)
+ return -ENOMEM;
+ dev->slot = i;
+ dev->bus = tpci200->info->ipack_bus;
+ dev->release = tpci200_release_device;
+ return ipack_device_register(dev);
+}
+
static int tpci200_pci_probe(struct pci_dev *pdev,
const struct pci_device_id *id)
{
@@ -715,7 +732,7 @@ static int tpci200_pci_probe(struct pci_dev *pdev,
dev_set_drvdata(&pdev->dev, tpci200);
for (i = 0; i < TPCI200_NB_SLOT; i++)
- ipack_device_register(tpci200->info->ipack_bus, i);
+ tpci200_create_device(tpci200, i);
return 0;
out_err_bus_register:
diff --git a/drivers/staging/ipack/ipack.c b/drivers/staging/ipack/ipack.c
index ca8cb327..d2ed9f5 100644
--- a/drivers/staging/ipack/ipack.c
+++ b/drivers/staging/ipack/ipack.c
@@ -24,7 +24,7 @@ static void ipack_device_release(struct device *dev)
{
struct ipack_device *device = to_ipack_dev(dev);
kfree(device->id);
- kfree(device);
+ device->release(device);
}
static inline const struct ipack_device_id *
@@ -426,51 +426,39 @@ out:
return ret;
}
-struct ipack_device *ipack_device_register(struct ipack_bus_device *bus,
- int slot)
+int ipack_device_register(struct ipack_device *dev)
{
int ret;
- struct ipack_device *dev;
-
- dev = kzalloc(sizeof(struct ipack_device), GFP_KERNEL);
- if (!dev)
- return NULL;
dev->dev.bus = &ipack_bus_type;
dev->dev.release = ipack_device_release;
- dev->dev.parent = bus->parent;
- dev->slot = slot;
- dev->bus = bus;
+ dev->dev.parent = dev->bus->parent;
dev_set_name(&dev->dev,
"ipack-dev.%u.%u", dev->bus->bus_nr, dev->slot);
- if (bus->ops->set_clockrate(dev, 8))
+ if (dev->bus->ops->set_clockrate(dev, 8))
dev_warn(&dev->dev, "failed to switch to 8 MHz operation for reading of device ID.\n");
- if (bus->ops->reset_timeout(dev))
+ if (dev->bus->ops->reset_timeout(dev))
dev_warn(&dev->dev, "failed to reset potential timeout.");
ret = ipack_device_read_id(dev);
if (ret < 0) {
dev_err(&dev->dev, "error reading device id section.\n");
- kfree(dev);
- return NULL;
+ return ret;
}
/* if the device supports 32 MHz operation, use it. */
if (dev->speed_32mhz) {
- ret = bus->ops->set_clockrate(dev, 32);
+ ret = dev->bus->ops->set_clockrate(dev, 32);
if (ret < 0)
dev_err(&dev->dev, "failed to switch to 32 MHz operation.\n");
}
ret = device_register(&dev->dev);
- if (ret < 0) {
+ if (ret < 0)
kfree(dev->id);
- kfree(dev);
- return NULL;
- }
- return dev;
+ return ret;
}
EXPORT_SYMBOL_GPL(ipack_device_register);
diff --git a/drivers/staging/ipack/ipack.h b/drivers/staging/ipack/ipack.h
index 33fdea5..e2987d5 100644
--- a/drivers/staging/ipack/ipack.h
+++ b/drivers/staging/ipack/ipack.h
@@ -71,6 +71,7 @@ struct ipack_device {
struct ipack_addr_space int_space;
struct ipack_addr_space mem_space;
struct device dev;
+ void (*release) (struct ipack_device *dev);
u8 *id;
size_t id_avail;
u32 id_vendor;
@@ -179,15 +180,17 @@ int ipack_driver_register(struct ipack_driver *edrv, struct module *owner,
void ipack_driver_unregister(struct ipack_driver *edrv);
/**
- * ipack_device_register -- register a new mezzanine device
+ * ipack_device_register -- register an IPack device with the kernel
+ * @dev: the new device to register.
*
- * @bus: ipack bus device it is plugged to.
- * @slot: slot position in the bus device.
+ * Register a new IPack device ("module" in IndustryPack jargon). The call
+ * is done by the carrier driver. The carrier should populate the fields
+ * bus and slot of @dev prior to calling this function. The rest of the
+ * fields will be allocated and populated during registration.
*
- * Register a new ipack device (mezzanine device). The call is done by
- * the carrier device driver.
+ * Return zero on success or error code on failure.
*/
-struct ipack_device *ipack_device_register(struct ipack_bus_device *bus, int slot);
+int ipack_device_register(struct ipack_device *dev);
void ipack_device_unregister(struct ipack_device *dev);
/**
--
1.7.10.4
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH 03/17] Staging: ipack/bridges/tpci200: Don't map memory spaces that are not used later on.
2012-09-27 10:37 [PATCH 01/17] Staging: ipack: get rid of ipack_device->bus_nr Samuel Iglesias Gonsalvez
2012-09-27 10:37 ` [PATCH 02/17] Staging: ipack: Make ipack_device_register() analogous to device_register() Samuel Iglesias Gonsalvez
@ 2012-09-27 10:37 ` Samuel Iglesias Gonsalvez
2012-09-27 10:37 ` [PATCH 04/17] Staging: ipack/bridges/tpci200: change tpci200_slot->*_phys type Samuel Iglesias Gonsalvez
` (13 subsequent siblings)
15 siblings, 0 replies; 17+ messages in thread
From: Samuel Iglesias Gonsalvez @ 2012-09-27 10:37 UTC (permalink / raw)
To: Greg Kroah-Hartman
Cc: devel, linux-kernel, industrypack-devel, Jens Taprogge,
Samuel Iglesias Gonsalvez
From: Jens Taprogge <jens.taprogge@taprogge.org>
Remove the unused pointers to these spaces.
Signed-off-by: Jens Taprogge <jens.taprogge@taprogge.org>
Signed-off-by: Samuel Iglesias Gonsalvez <siglesias@igalia.com>
---
drivers/staging/ipack/bridges/tpci200.c | 10 ----------
drivers/staging/ipack/bridges/tpci200.h | 2 --
2 files changed, 12 deletions(-)
diff --git a/drivers/staging/ipack/bridges/tpci200.c b/drivers/staging/ipack/bridges/tpci200.c
index ee66129..a804290 100644
--- a/drivers/staging/ipack/bridges/tpci200.c
+++ b/drivers/staging/ipack/bridges/tpci200.c
@@ -78,8 +78,6 @@ static void tpci200_unregister(struct tpci200_board *tpci200)
free_irq(tpci200->info->pdev->irq, (void *) tpci200);
pci_iounmap(tpci200->info->pdev, tpci200->info->interface_regs);
- pci_iounmap(tpci200->info->pdev, tpci200->info->ioidint_space);
- pci_iounmap(tpci200->info->pdev, tpci200->info->mem8_space);
pci_iounmap(tpci200->info->pdev, tpci200->info->cfg_regs);
pci_release_region(tpci200->info->pdev, TPCI200_IP_INTERFACE_BAR);
@@ -289,14 +287,6 @@ static int tpci200_register(struct tpci200_board *tpci200)
ioremap_nocache(pci_resource_start(tpci200->info->pdev,
TPCI200_IP_INTERFACE_BAR),
TPCI200_IFACE_SIZE);
- tpci200->info->ioidint_space =
- ioremap_nocache(pci_resource_start(tpci200->info->pdev,
- TPCI200_IO_ID_INT_SPACES_BAR),
- TPCI200_IOIDINT_SIZE);
- tpci200->info->mem8_space =
- ioremap_nocache(pci_resource_start(tpci200->info->pdev,
- TPCI200_MEM8_SPACE_BAR),
- TPCI200_MEM8_SIZE);
/* Initialize lock that protects interface_regs */
spin_lock_init(&tpci200->regs_lock);
diff --git a/drivers/staging/ipack/bridges/tpci200.h b/drivers/staging/ipack/bridges/tpci200.h
index 235d1fe..e4ed0a3 100644
--- a/drivers/staging/ipack/bridges/tpci200.h
+++ b/drivers/staging/ipack/bridges/tpci200.h
@@ -156,8 +156,6 @@ struct tpci200_infos {
struct pci_dev *pdev;
struct pci_device_id *id_table;
struct tpci200_regs __iomem *interface_regs;
- void __iomem *ioidint_space;
- void __iomem *mem8_space;
void __iomem *cfg_regs;
struct ipack_bus_device *ipack_bus;
};
--
1.7.10.4
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH 04/17] Staging: ipack/bridges/tpci200: change tpci200_slot->*_phys type.
2012-09-27 10:37 [PATCH 01/17] Staging: ipack: get rid of ipack_device->bus_nr Samuel Iglesias Gonsalvez
2012-09-27 10:37 ` [PATCH 02/17] Staging: ipack: Make ipack_device_register() analogous to device_register() Samuel Iglesias Gonsalvez
2012-09-27 10:37 ` [PATCH 03/17] Staging: ipack/bridges/tpci200: Don't map memory spaces that are not used later on Samuel Iglesias Gonsalvez
@ 2012-09-27 10:37 ` Samuel Iglesias Gonsalvez
2012-09-27 10:37 ` [PATCH 05/17] Staging: ipack/bridges/tpci200: Store beginning of module memory regions in struct tpci200 Samuel Iglesias Gonsalvez
` (12 subsequent siblings)
15 siblings, 0 replies; 17+ messages in thread
From: Samuel Iglesias Gonsalvez @ 2012-09-27 10:37 UTC (permalink / raw)
To: Greg Kroah-Hartman
Cc: devel, linux-kernel, industrypack-devel, Jens Taprogge,
Samuel Iglesias Gonsalvez
From: Jens Taprogge <jens.taprogge@taprogge.org>
Previously the *_phys fields were of type ipack_addr_space, which use
void pointers to refer to memory addresses. Since the *_phys fields
refer to unmapped memory, this is not correct. Introduce a new struct
ipack_region (which uses phys_addr_t to refer to the start of a region)
and use that as a replacement for struct ipack_addr_space.
struct ipack_region is defined in ipack.h because it is planned to later
expose the physical addressed to the IPack Module drivers.
Signed-off-by: Jens Taprogge <jens.taprogge@taprogge.org>
Signed-off-by: Samuel Iglesias Gonsalvez <siglesias@igalia.com>
---
drivers/staging/ipack/bridges/tpci200.c | 41 ++++++++++++++-----------------
drivers/staging/ipack/bridges/tpci200.h | 10 ++++----
drivers/staging/ipack/ipack.h | 9 ++++++-
3 files changed, 32 insertions(+), 28 deletions(-)
diff --git a/drivers/staging/ipack/bridges/tpci200.c b/drivers/staging/ipack/bridges/tpci200.c
index a804290..47b8a1b 100644
--- a/drivers/staging/ipack/bridges/tpci200.c
+++ b/drivers/staging/ipack/bridges/tpci200.c
@@ -89,13 +89,13 @@ static void tpci200_unregister(struct tpci200_board *tpci200)
pci_dev_put(tpci200->info->pdev);
for (i = 0; i < TPCI200_NB_SLOT; i++) {
- tpci200->slots[i].io_phys.address = NULL;
+ tpci200->slots[i].io_phys.start = 0;
tpci200->slots[i].io_phys.size = 0;
- tpci200->slots[i].id_phys.address = NULL;
+ tpci200->slots[i].id_phys.start = 0;
tpci200->slots[i].id_phys.size = 0;
- tpci200->slots[i].int_phys.address = NULL;
+ tpci200->slots[i].int_phys.start = 0;
tpci200->slots[i].int_phys.size = 0;
- tpci200->slots[i].mem_phys.address = NULL;
+ tpci200->slots[i].mem_phys.start = 0;
tpci200->slots[i].mem_phys.size = 0;
}
}
@@ -241,8 +241,8 @@ static int tpci200_register(struct tpci200_board *tpci200)
{
int i;
int res;
- unsigned long ioidint_base;
- unsigned long mem_base;
+ phys_addr_t ioidint_base;
+ phys_addr_t mem_base;
unsigned short slot_ctrl;
if (pci_enable_device(tpci200->info->pdev) < 0)
@@ -308,23 +308,20 @@ static int tpci200_register(struct tpci200_board *tpci200)
/* Set all slot physical address space */
for (i = 0; i < TPCI200_NB_SLOT; i++) {
- tpci200->slots[i].io_phys.address =
- (void __iomem *)ioidint_base +
+ tpci200->slots[i].io_phys.start = ioidint_base +
TPCI200_IO_SPACE_OFF + TPCI200_IO_SPACE_GAP*i;
tpci200->slots[i].io_phys.size = TPCI200_IO_SPACE_SIZE;
- tpci200->slots[i].id_phys.address =
- (void __iomem *)ioidint_base +
+ tpci200->slots[i].id_phys.start = ioidint_base +
TPCI200_ID_SPACE_OFF + TPCI200_ID_SPACE_GAP*i;
tpci200->slots[i].id_phys.size = TPCI200_ID_SPACE_SIZE;
- tpci200->slots[i].int_phys.address =
- (void __iomem *)ioidint_base +
+ tpci200->slots[i].int_phys.start = ioidint_base +
TPCI200_INT_SPACE_OFF + TPCI200_INT_SPACE_GAP * i;
tpci200->slots[i].int_phys.size = TPCI200_INT_SPACE_SIZE;
- tpci200->slots[i].mem_phys.address =
- (void __iomem *)mem_base + TPCI200_MEM8_GAP*i;
+ tpci200->slots[i].mem_phys.start = mem_base +
+ TPCI200_MEM8_GAP * i;
tpci200->slots[i].mem_phys.size = TPCI200_MEM8_SIZE;
writew(slot_ctrl, &tpci200->info->interface_regs->control[i]);
@@ -419,11 +416,11 @@ out_unlock:
}
static int tpci200_slot_map_space(struct ipack_device *dev,
- unsigned int memory_size, int space)
+ ssize_t memory_size, int space)
{
int res = 0;
- unsigned int size_to_map;
- void __iomem *phys_address;
+ size_t size_to_map;
+ phys_addr_t phys_address;
struct ipack_addr_space *virt_addr_space;
struct tpci200_board *tpci200;
@@ -445,7 +442,7 @@ static int tpci200_slot_map_space(struct ipack_device *dev,
}
virt_addr_space = &dev->io_space;
- phys_address = tpci200->slots[dev->slot].io_phys.address;
+ phys_address = tpci200->slots[dev->slot].io_phys.start;
size_to_map = tpci200->slots[dev->slot].io_phys.size;
break;
case IPACK_ID_SPACE:
@@ -458,7 +455,7 @@ static int tpci200_slot_map_space(struct ipack_device *dev,
}
virt_addr_space = &dev->id_space;
- phys_address = tpci200->slots[dev->slot].id_phys.address;
+ phys_address = tpci200->slots[dev->slot].id_phys.start;
size_to_map = tpci200->slots[dev->slot].id_phys.size;
break;
case IPACK_INT_SPACE:
@@ -471,7 +468,7 @@ static int tpci200_slot_map_space(struct ipack_device *dev,
}
virt_addr_space = &dev->int_space;
- phys_address = tpci200->slots[dev->slot].int_phys.address;
+ phys_address = tpci200->slots[dev->slot].int_phys.start;
size_to_map = tpci200->slots[dev->slot].int_phys.size;
break;
case IPACK_MEM_SPACE:
@@ -486,14 +483,14 @@ static int tpci200_slot_map_space(struct ipack_device *dev,
if (memory_size > tpci200->slots[dev->slot].mem_phys.size) {
dev_err(&dev->dev,
- "Slot [%d:%d] request is 0x%X memory, only 0x%X available !\n",
+ "Slot [%d:%d] request is 0x%zX memory, only 0x%zX available !\n",
dev->bus->bus_nr, dev->slot, memory_size,
tpci200->slots[dev->slot].mem_phys.size);
res = -EINVAL;
goto out_unlock;
}
- phys_address = tpci200->slots[dev->slot].mem_phys.address;
+ phys_address = tpci200->slots[dev->slot].mem_phys.start;
size_to_map = memory_size;
break;
default:
diff --git a/drivers/staging/ipack/bridges/tpci200.h b/drivers/staging/ipack/bridges/tpci200.h
index e4ed0a3..59cb5b7 100644
--- a/drivers/staging/ipack/bridges/tpci200.h
+++ b/drivers/staging/ipack/bridges/tpci200.h
@@ -137,11 +137,11 @@ struct slot_irq {
*
*/
struct tpci200_slot {
- struct slot_irq *irq;
- struct ipack_addr_space io_phys;
- struct ipack_addr_space id_phys;
- struct ipack_addr_space int_phys;
- struct ipack_addr_space mem_phys;
+ struct slot_irq *irq;
+ struct ipack_region io_phys;
+ struct ipack_region id_phys;
+ struct ipack_region int_phys;
+ struct ipack_region mem_phys;
};
/**
diff --git a/drivers/staging/ipack/ipack.h b/drivers/staging/ipack/ipack.h
index e2987d5..9e543a5 100644
--- a/drivers/staging/ipack/ipack.h
+++ b/drivers/staging/ipack/ipack.h
@@ -50,6 +50,13 @@ struct ipack_addr_space {
};
/**
+ */
+struct ipack_region {
+ phys_addr_t start;
+ size_t size;
+};
+
+/**
* struct ipack_device
*
* @slot: Slot where the device is plugged in the carrier board
@@ -124,7 +131,7 @@ struct ipack_driver {
* @reset_timeout: Resets the state returned by get_timeout.
*/
struct ipack_bus_ops {
- int (*map_space) (struct ipack_device *dev, unsigned int memory_size, int space);
+ int (*map_space) (struct ipack_device *dev, ssize_t memory_size, int space);
int (*unmap_space) (struct ipack_device *dev, int space);
int (*request_irq) (struct ipack_device *dev,
irqreturn_t (*handler)(void *), void *arg);
--
1.7.10.4
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH 05/17] Staging: ipack/bridges/tpci200: Store beginning of module memory regions in struct tpci200.
2012-09-27 10:37 [PATCH 01/17] Staging: ipack: get rid of ipack_device->bus_nr Samuel Iglesias Gonsalvez
` (2 preceding siblings ...)
2012-09-27 10:37 ` [PATCH 04/17] Staging: ipack/bridges/tpci200: change tpci200_slot->*_phys type Samuel Iglesias Gonsalvez
@ 2012-09-27 10:37 ` Samuel Iglesias Gonsalvez
2012-09-27 10:37 ` [PATCH 06/17] Staging: ipack/bridges/tpci200: Cleanups Samuel Iglesias Gonsalvez
` (11 subsequent siblings)
15 siblings, 0 replies; 17+ messages in thread
From: Samuel Iglesias Gonsalvez @ 2012-09-27 10:37 UTC (permalink / raw)
To: Greg Kroah-Hartman
Cc: devel, linux-kernel, industrypack-devel, Jens Taprogge,
Samuel Iglesias Gonsalvez
From: Jens Taprogge <jens.taprogge@taprogge.org>
tpci200_register is converted to use this.
A later patch will build on this.
Signed-off-by: Jens Taprogge <jens.taprogge@taprogge.org>
Signed-off-by: Samuel Iglesias Gonsalvez <siglesias@igalia.com>
---
drivers/staging/ipack/bridges/tpci200.c | 26 +++++++++++++++++---------
drivers/staging/ipack/bridges/tpci200.h | 1 +
drivers/staging/ipack/ipack.h | 7 +++++--
3 files changed, 23 insertions(+), 11 deletions(-)
diff --git a/drivers/staging/ipack/bridges/tpci200.c b/drivers/staging/ipack/bridges/tpci200.c
index 47b8a1b..5acaea2 100644
--- a/drivers/staging/ipack/bridges/tpci200.c
+++ b/drivers/staging/ipack/bridges/tpci200.c
@@ -242,7 +242,6 @@ static int tpci200_register(struct tpci200_board *tpci200)
int i;
int res;
phys_addr_t ioidint_base;
- phys_addr_t mem_base;
unsigned short slot_ctrl;
if (pci_enable_device(tpci200->info->pdev) < 0)
@@ -293,7 +292,12 @@ static int tpci200_register(struct tpci200_board *tpci200)
ioidint_base = pci_resource_start(tpci200->info->pdev,
TPCI200_IO_ID_INT_SPACES_BAR);
- mem_base = pci_resource_start(tpci200->info->pdev,
+ tpci200->mod_mem[IPACK_IO_SPACE] = ioidint_base + TPCI200_IO_SPACE_OFF;
+ tpci200->mod_mem[IPACK_ID_SPACE] = ioidint_base + TPCI200_ID_SPACE_OFF;
+ tpci200->mod_mem[IPACK_INT_SPACE] =
+ ioidint_base + TPCI200_INT_SPACE_OFF;
+ tpci200->mod_mem[IPACK_MEM_SPACE] =
+ pci_resource_start(tpci200->info->pdev,
TPCI200_MEM8_SPACE_BAR);
/* Set the default parameters of the slot
@@ -308,19 +312,23 @@ static int tpci200_register(struct tpci200_board *tpci200)
/* Set all slot physical address space */
for (i = 0; i < TPCI200_NB_SLOT; i++) {
- tpci200->slots[i].io_phys.start = ioidint_base +
- TPCI200_IO_SPACE_OFF + TPCI200_IO_SPACE_GAP*i;
+ tpci200->slots[i].io_phys.start =
+ tpci200->mod_mem[IPACK_IO_SPACE] +
+ TPCI200_IO_SPACE_GAP * i;
tpci200->slots[i].io_phys.size = TPCI200_IO_SPACE_SIZE;
- tpci200->slots[i].id_phys.start = ioidint_base +
- TPCI200_ID_SPACE_OFF + TPCI200_ID_SPACE_GAP*i;
+ tpci200->slots[i].id_phys.start =
+ tpci200->mod_mem[IPACK_ID_SPACE] +
+ TPCI200_ID_SPACE_GAP * i;
tpci200->slots[i].id_phys.size = TPCI200_ID_SPACE_SIZE;
- tpci200->slots[i].int_phys.start = ioidint_base +
- TPCI200_INT_SPACE_OFF + TPCI200_INT_SPACE_GAP * i;
+ tpci200->slots[i].int_phys.start =
+ tpci200->mod_mem[IPACK_INT_SPACE] +
+ TPCI200_INT_SPACE_GAP * i;
tpci200->slots[i].int_phys.size = TPCI200_INT_SPACE_SIZE;
- tpci200->slots[i].mem_phys.start = mem_base +
+ tpci200->slots[i].mem_phys.start =
+ tpci200->mod_mem[IPACK_MEM_SPACE] +
TPCI200_MEM8_GAP * i;
tpci200->slots[i].mem_phys.size = TPCI200_MEM8_SIZE;
diff --git a/drivers/staging/ipack/bridges/tpci200.h b/drivers/staging/ipack/bridges/tpci200.h
index 59cb5b7..6b7c700 100644
--- a/drivers/staging/ipack/bridges/tpci200.h
+++ b/drivers/staging/ipack/bridges/tpci200.h
@@ -165,6 +165,7 @@ struct tpci200_board {
spinlock_t regs_lock;
struct tpci200_slot *slots;
struct tpci200_infos *info;
+ phys_addr_t mod_mem[IPACK_SPACE_COUNT];
};
#endif /* _TPCI200_H_ */
diff --git a/drivers/staging/ipack/ipack.h b/drivers/staging/ipack/ipack.h
index 9e543a5..a842eea 100644
--- a/drivers/staging/ipack/ipack.h
+++ b/drivers/staging/ipack/ipack.h
@@ -33,9 +33,12 @@ struct ipack_driver;
enum ipack_space {
IPACK_IO_SPACE = 0,
- IPACK_ID_SPACE = 1,
- IPACK_MEM_SPACE = 2,
+ IPACK_ID_SPACE,
+ IPACK_MEM_SPACE,
IPACK_INT_SPACE,
+ /* Dummy for counting the number of entries. Must remain the last
+ * entry */
+ IPACK_SPACE_COUNT,
};
/**
--
1.7.10.4
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH 06/17] Staging: ipack/bridges/tpci200: Cleanups.
2012-09-27 10:37 [PATCH 01/17] Staging: ipack: get rid of ipack_device->bus_nr Samuel Iglesias Gonsalvez
` (3 preceding siblings ...)
2012-09-27 10:37 ` [PATCH 05/17] Staging: ipack/bridges/tpci200: Store beginning of module memory regions in struct tpci200 Samuel Iglesias Gonsalvez
@ 2012-09-27 10:37 ` Samuel Iglesias Gonsalvez
2012-09-27 10:37 ` [PATCH 07/17] Staging: ipack: Provide physical memory regions to IPack devices Samuel Iglesias Gonsalvez
` (10 subsequent siblings)
15 siblings, 0 replies; 17+ messages in thread
From: Samuel Iglesias Gonsalvez @ 2012-09-27 10:37 UTC (permalink / raw)
To: Greg Kroah-Hartman
Cc: devel, linux-kernel, industrypack-devel, Jens Taprogge,
Samuel Iglesias Gonsalvez
From: Jens Taprogge <jens.taprogge@taprogge.org>
Constant renames:
- Rename TPCI200_*_GAP to TPCI200_*_INTERVAL.
- Rename TPCI200_MEM*_* to TPCI200_MEM*_SPACE_* (to match the other SPACE
constants.
Make tpci200_status_timeout and tpci200_status_error const.
Signed-off-by: Jens Taprogge <jens.taprogge@taprogge.org>
Signed-off-by: Samuel Iglesias Gonsalvez <siglesias@igalia.com>
---
drivers/staging/ipack/bridges/tpci200.c | 24 ++++++++++++------------
drivers/staging/ipack/bridges/tpci200.h | 14 +++++++-------
2 files changed, 19 insertions(+), 19 deletions(-)
diff --git a/drivers/staging/ipack/bridges/tpci200.c b/drivers/staging/ipack/bridges/tpci200.c
index 5acaea2..84e1c27 100644
--- a/drivers/staging/ipack/bridges/tpci200.c
+++ b/drivers/staging/ipack/bridges/tpci200.c
@@ -14,14 +14,14 @@
#include <linux/module.h>
#include "tpci200.h"
-static u16 tpci200_status_timeout[] = {
+static const u16 tpci200_status_timeout[] = {
TPCI200_A_TIMEOUT,
TPCI200_B_TIMEOUT,
TPCI200_C_TIMEOUT,
TPCI200_D_TIMEOUT,
};
-static u16 tpci200_status_error[] = {
+static const u16 tpci200_status_error[] = {
TPCI200_A_ERROR,
TPCI200_B_ERROR,
TPCI200_C_ERROR,
@@ -298,7 +298,7 @@ static int tpci200_register(struct tpci200_board *tpci200)
ioidint_base + TPCI200_INT_SPACE_OFF;
tpci200->mod_mem[IPACK_MEM_SPACE] =
pci_resource_start(tpci200->info->pdev,
- TPCI200_MEM8_SPACE_BAR);
+ TPCI200_MEM8_SPACE_BAR);
/* Set the default parameters of the slot
* INT0 disabled, level sensitive
@@ -313,24 +313,24 @@ static int tpci200_register(struct tpci200_board *tpci200)
/* Set all slot physical address space */
for (i = 0; i < TPCI200_NB_SLOT; i++) {
tpci200->slots[i].io_phys.start =
- tpci200->mod_mem[IPACK_IO_SPACE] +
- TPCI200_IO_SPACE_GAP * i;
+ tpci200->mod_mem[IPACK_IO_SPACE]
+ + TPCI200_IO_SPACE_INTERVAL * i;
tpci200->slots[i].io_phys.size = TPCI200_IO_SPACE_SIZE;
tpci200->slots[i].id_phys.start =
- tpci200->mod_mem[IPACK_ID_SPACE] +
- TPCI200_ID_SPACE_GAP * i;
+ tpci200->mod_mem[IPACK_ID_SPACE]
+ + TPCI200_ID_SPACE_INTERVAL * i;
tpci200->slots[i].id_phys.size = TPCI200_ID_SPACE_SIZE;
tpci200->slots[i].int_phys.start =
- tpci200->mod_mem[IPACK_INT_SPACE] +
- TPCI200_INT_SPACE_GAP * i;
+ tpci200->mod_mem[IPACK_INT_SPACE]
+ + TPCI200_INT_SPACE_INTERVAL * i;
tpci200->slots[i].int_phys.size = TPCI200_INT_SPACE_SIZE;
tpci200->slots[i].mem_phys.start =
- tpci200->mod_mem[IPACK_MEM_SPACE] +
- TPCI200_MEM8_GAP * i;
- tpci200->slots[i].mem_phys.size = TPCI200_MEM8_SIZE;
+ tpci200->mod_mem[IPACK_MEM_SPACE]
+ + TPCI200_MEM8_SPACE_INTERVAL * i;
+ tpci200->slots[i].mem_phys.size = TPCI200_MEM8_SPACE_SIZE;
writew(slot_ctrl, &tpci200->info->interface_regs->control[i]);
}
diff --git a/drivers/staging/ipack/bridges/tpci200.h b/drivers/staging/ipack/bridges/tpci200.h
index 6b7c700..fe8e97e 100644
--- a/drivers/staging/ipack/bridges/tpci200.h
+++ b/drivers/staging/ipack/bridges/tpci200.h
@@ -49,20 +49,20 @@ struct tpci200_regs {
#define TPCI200_IFACE_SIZE 0x100
#define TPCI200_IO_SPACE_OFF 0x0000
-#define TPCI200_IO_SPACE_GAP 0x0100
+#define TPCI200_IO_SPACE_INTERVAL 0x0100
#define TPCI200_IO_SPACE_SIZE 0x0080
#define TPCI200_ID_SPACE_OFF 0x0080
-#define TPCI200_ID_SPACE_GAP 0x0100
+#define TPCI200_ID_SPACE_INTERVAL 0x0100
#define TPCI200_ID_SPACE_SIZE 0x0040
#define TPCI200_INT_SPACE_OFF 0x00C0
-#define TPCI200_INT_SPACE_GAP 0x0100
+#define TPCI200_INT_SPACE_INTERVAL 0x0100
#define TPCI200_INT_SPACE_SIZE 0x0040
#define TPCI200_IOIDINT_SIZE 0x0400
-#define TPCI200_MEM8_GAP 0x00400000
-#define TPCI200_MEM8_SIZE 0x00400000
-#define TPCI200_MEM16_GAP 0x00800000
-#define TPCI200_MEM16_SIZE 0x00800000
+#define TPCI200_MEM8_SPACE_INTERVAL 0x00400000
+#define TPCI200_MEM8_SPACE_SIZE 0x00400000
+#define TPCI200_MEM16_SPACE_INTERVAL 0x00800000
+#define TPCI200_MEM16_SPACE_SIZE 0x00800000
/* control field in tpci200_regs */
#define TPCI200_INT0_EN 0x0040
--
1.7.10.4
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH 07/17] Staging: ipack: Provide physical memory regions to IPack devices.
2012-09-27 10:37 [PATCH 01/17] Staging: ipack: get rid of ipack_device->bus_nr Samuel Iglesias Gonsalvez
` (4 preceding siblings ...)
2012-09-27 10:37 ` [PATCH 06/17] Staging: ipack/bridges/tpci200: Cleanups Samuel Iglesias Gonsalvez
@ 2012-09-27 10:37 ` Samuel Iglesias Gonsalvez
2012-09-27 10:37 ` [PATCH 08/17] staging: ipack/devices/ipoctal: fix ipoctal_inst_slot error path Samuel Iglesias Gonsalvez
` (9 subsequent siblings)
15 siblings, 0 replies; 17+ messages in thread
From: Samuel Iglesias Gonsalvez @ 2012-09-27 10:37 UTC (permalink / raw)
To: Greg Kroah-Hartman
Cc: devel, linux-kernel, industrypack-devel, Jens Taprogge,
Samuel Iglesias Gonsalvez
From: Jens Taprogge <jens.taprogge@taprogge.org>
This will allow us to use the regular ioremop functions.
Signed-off-by: Jens Taprogge <jens.taprogge@taprogge.org>
Signed-off-by: Samuel Iglesias Gonsalvez <siglesias@igalia.com>
---
drivers/staging/ipack/bridges/tpci200.c | 22 ++++++++++++++++++++++
drivers/staging/ipack/ipack.h | 6 ++++--
2 files changed, 26 insertions(+), 2 deletions(-)
diff --git a/drivers/staging/ipack/bridges/tpci200.c b/drivers/staging/ipack/bridges/tpci200.c
index 84e1c27..8428e3b 100644
--- a/drivers/staging/ipack/bridges/tpci200.c
+++ b/drivers/staging/ipack/bridges/tpci200.c
@@ -28,6 +28,20 @@ static const u16 tpci200_status_error[] = {
TPCI200_D_ERROR,
};
+static const size_t tpci200_space_size[IPACK_SPACE_COUNT] = {
+ [IPACK_IO_SPACE] = TPCI200_IO_SPACE_SIZE,
+ [IPACK_ID_SPACE] = TPCI200_ID_SPACE_SIZE,
+ [IPACK_INT_SPACE] = TPCI200_INT_SPACE_SIZE,
+ [IPACK_MEM_SPACE] = TPCI200_MEM8_SPACE_SIZE,
+};
+
+static const size_t tpci200_space_interval[IPACK_SPACE_COUNT] = {
+ [IPACK_IO_SPACE] = TPCI200_IO_SPACE_INTERVAL,
+ [IPACK_ID_SPACE] = TPCI200_ID_SPACE_INTERVAL,
+ [IPACK_INT_SPACE] = TPCI200_INT_SPACE_INTERVAL,
+ [IPACK_MEM_SPACE] = TPCI200_MEM8_SPACE_INTERVAL,
+};
+
static struct tpci200_board *check_slot(struct ipack_device *dev)
{
struct tpci200_board *tpci200;
@@ -642,6 +656,7 @@ static void tpci200_release_device(struct ipack_device *dev)
static int tpci200_create_device(struct tpci200_board *tpci200, int i)
{
+ enum ipack_space space;
struct ipack_device *dev =
kzalloc(sizeof(struct ipack_device), GFP_KERNEL);
if (!dev)
@@ -649,6 +664,13 @@ static int tpci200_create_device(struct tpci200_board *tpci200, int i)
dev->slot = i;
dev->bus = tpci200->info->ipack_bus;
dev->release = tpci200_release_device;
+
+ for (space = 0; space < IPACK_SPACE_COUNT; space++) {
+ dev->region[space].start =
+ tpci200->mod_mem[space]
+ + tpci200_space_interval[space] * i;
+ dev->region[space].size = tpci200_space_size[space];
+ }
return ipack_device_register(dev);
}
diff --git a/drivers/staging/ipack/ipack.h b/drivers/staging/ipack/ipack.h
index a842eea..43d152a 100644
--- a/drivers/staging/ipack/ipack.h
+++ b/drivers/staging/ipack/ipack.h
@@ -82,6 +82,7 @@ struct ipack_device {
struct ipack_addr_space mem_space;
struct device dev;
void (*release) (struct ipack_device *dev);
+ struct ipack_region region[IPACK_SPACE_COUNT];
u8 *id;
size_t id_avail;
u32 id_vendor;
@@ -195,8 +196,9 @@ void ipack_driver_unregister(struct ipack_driver *edrv);
*
* Register a new IPack device ("module" in IndustryPack jargon). The call
* is done by the carrier driver. The carrier should populate the fields
- * bus and slot of @dev prior to calling this function. The rest of the
- * fields will be allocated and populated during registration.
+ * bus and slot as well as the region array of @dev prior to calling this
+ * function. The rest of the fields will be allocated and populated
+ * during registration.
*
* Return zero on success or error code on failure.
*/
--
1.7.10.4
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH 08/17] staging: ipack/devices/ipoctal: fix ipoctal_inst_slot error path.
2012-09-27 10:37 [PATCH 01/17] Staging: ipack: get rid of ipack_device->bus_nr Samuel Iglesias Gonsalvez
` (5 preceding siblings ...)
2012-09-27 10:37 ` [PATCH 07/17] Staging: ipack: Provide physical memory regions to IPack devices Samuel Iglesias Gonsalvez
@ 2012-09-27 10:37 ` Samuel Iglesias Gonsalvez
2012-09-27 10:37 ` [PATCH 09/17] staging: ipack/devices/ipoctal: obtain model from dev->id_device Samuel Iglesias Gonsalvez
` (8 subsequent siblings)
15 siblings, 0 replies; 17+ messages in thread
From: Samuel Iglesias Gonsalvez @ 2012-09-27 10:37 UTC (permalink / raw)
To: Greg Kroah-Hartman
Cc: devel, linux-kernel, industrypack-devel, Jens Taprogge,
Samuel Iglesias Gonsalvez
From: Jens Taprogge <jens.taprogge@taprogge.org>
The ordering was wrong.
Signed-off-by: Jens Taprogge <jens.taprogge@taprogge.org>
Signed-off-by: Samuel Iglesias Gonsalvez <siglesias@igalia.com>
---
drivers/staging/ipack/devices/ipoctal.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/staging/ipack/devices/ipoctal.c b/drivers/staging/ipack/devices/ipoctal.c
index 14a0aed..d9dbb3f 100644
--- a/drivers/staging/ipack/devices/ipoctal.c
+++ b/drivers/staging/ipack/devices/ipoctal.c
@@ -460,13 +460,13 @@ static int ipoctal_inst_slot(struct ipoctal *ipoctal, unsigned int bus_nr,
return 0;
out_unregister_slot_unmap:
- ipoctal->dev->bus->ops->unmap_space(ipoctal->dev, IPACK_ID_SPACE);
+ ipoctal->dev->bus->ops->unmap_space(ipoctal->dev, IPACK_MEM_SPACE);
out_unregister_int_space:
ipoctal->dev->bus->ops->unmap_space(ipoctal->dev, IPACK_INT_SPACE);
out_unregister_io_space:
ipoctal->dev->bus->ops->unmap_space(ipoctal->dev, IPACK_IO_SPACE);
out_unregister_id_space:
- ipoctal->dev->bus->ops->unmap_space(ipoctal->dev, IPACK_MEM_SPACE);
+ ipoctal->dev->bus->ops->unmap_space(ipoctal->dev, IPACK_ID_SPACE);
return res;
}
--
1.7.10.4
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH 09/17] staging: ipack/devices/ipoctal: obtain model from dev->id_device.
2012-09-27 10:37 [PATCH 01/17] Staging: ipack: get rid of ipack_device->bus_nr Samuel Iglesias Gonsalvez
` (6 preceding siblings ...)
2012-09-27 10:37 ` [PATCH 08/17] staging: ipack/devices/ipoctal: fix ipoctal_inst_slot error path Samuel Iglesias Gonsalvez
@ 2012-09-27 10:37 ` Samuel Iglesias Gonsalvez
2012-09-27 10:37 ` [PATCH 10/17] staging: ipack: swich to regular ioremap and friends Samuel Iglesias Gonsalvez
` (7 subsequent siblings)
15 siblings, 0 replies; 17+ messages in thread
From: Samuel Iglesias Gonsalvez @ 2012-09-27 10:37 UTC (permalink / raw)
To: Greg Kroah-Hartman
Cc: devel, linux-kernel, industrypack-devel, Jens Taprogge,
Samuel Iglesias Gonsalvez
From: Jens Taprogge <jens.taprogge@taprogge.org>
By doing so we can remove ipoctal_check_model() and we also no longer need
to map the IPACK_ID_SPACE.
Signed-off-by: Jens Taprogge <jens.taprogge@taprogge.org>
Signed-off-by: Samuel Iglesias Gonsalvez <siglesias@igalia.com>
---
drivers/staging/ipack/devices/ipoctal.c | 46 ++-----------------------------
1 file changed, 2 insertions(+), 44 deletions(-)
diff --git a/drivers/staging/ipack/devices/ipoctal.c b/drivers/staging/ipack/devices/ipoctal.c
index d9dbb3f..35b98e8 100644
--- a/drivers/staging/ipack/devices/ipoctal.c
+++ b/drivers/staging/ipack/devices/ipoctal.c
@@ -258,29 +258,6 @@ static irqreturn_t ipoctal_irq_handler(void *arg)
return IRQ_HANDLED;
}
-static int ipoctal_check_model(struct ipack_device *dev, unsigned char *id)
-{
- unsigned char manufacturerID;
- unsigned char board_id;
-
-
- manufacturerID = ioread8(dev->id_space.address + IPACK_IDPROM_OFFSET_MANUFACTURER_ID);
- if (manufacturerID != IPACK1_VENDOR_ID_SBS)
- return -ENODEV;
- board_id = ioread8(dev->id_space.address + IPACK_IDPROM_OFFSET_MODEL);
- switch (board_id) {
- case IPACK1_DEVICE_ID_SBS_OCTAL_232:
- case IPACK1_DEVICE_ID_SBS_OCTAL_422:
- case IPACK1_DEVICE_ID_SBS_OCTAL_485:
- *id = board_id;
- break;
- default:
- return -ENODEV;
- }
-
- return 0;
-}
-
static const struct tty_port_operations ipoctal_tty_port_ops = {
.dtr_rts = NULL,
.activate = ipoctal_port_activate,
@@ -293,27 +270,11 @@ static int ipoctal_inst_slot(struct ipoctal *ipoctal, unsigned int bus_nr,
int i;
struct tty_driver *tty;
char name[20];
- unsigned char board_id;
struct ipoctal_channel *channel;
union scc2698_channel __iomem *chan_regs;
union scc2698_block __iomem *block_regs;
- res = ipoctal->dev->bus->ops->map_space(ipoctal->dev, 0,
- IPACK_ID_SPACE);
- if (res) {
- dev_err(&ipoctal->dev->dev,
- "Unable to map slot [%d:%d] ID space!\n",
- bus_nr, slot);
- return res;
- }
-
- res = ipoctal_check_model(ipoctal->dev, &board_id);
- if (res) {
- ipoctal->dev->bus->ops->unmap_space(ipoctal->dev,
- IPACK_ID_SPACE);
- goto out_unregister_id_space;
- }
- ipoctal->board_id = board_id;
+ ipoctal->board_id = ipoctal->dev->id_device;
res = ipoctal->dev->bus->ops->map_space(ipoctal->dev, 0,
IPACK_IO_SPACE);
@@ -321,7 +282,7 @@ static int ipoctal_inst_slot(struct ipoctal *ipoctal, unsigned int bus_nr,
dev_err(&ipoctal->dev->dev,
"Unable to map slot [%d:%d] IO space!\n",
bus_nr, slot);
- goto out_unregister_id_space;
+ return res;
}
res = ipoctal->dev->bus->ops->map_space(ipoctal->dev, 0,
@@ -465,8 +426,6 @@ out_unregister_int_space:
ipoctal->dev->bus->ops->unmap_space(ipoctal->dev, IPACK_INT_SPACE);
out_unregister_io_space:
ipoctal->dev->bus->ops->unmap_space(ipoctal->dev, IPACK_IO_SPACE);
-out_unregister_id_space:
- ipoctal->dev->bus->ops->unmap_space(ipoctal->dev, IPACK_ID_SPACE);
return res;
}
@@ -748,7 +707,6 @@ static void __ipoctal_remove(struct ipoctal *ipoctal)
ipoctal->dev->bus->ops->unmap_space(ipoctal->dev, IPACK_MEM_SPACE);
ipoctal->dev->bus->ops->unmap_space(ipoctal->dev, IPACK_INT_SPACE);
ipoctal->dev->bus->ops->unmap_space(ipoctal->dev, IPACK_IO_SPACE);
- ipoctal->dev->bus->ops->unmap_space(ipoctal->dev, IPACK_ID_SPACE);
kfree(ipoctal);
}
--
1.7.10.4
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH 10/17] staging: ipack: swich to regular ioremap and friends.
2012-09-27 10:37 [PATCH 01/17] Staging: ipack: get rid of ipack_device->bus_nr Samuel Iglesias Gonsalvez
` (7 preceding siblings ...)
2012-09-27 10:37 ` [PATCH 09/17] staging: ipack/devices/ipoctal: obtain model from dev->id_device Samuel Iglesias Gonsalvez
@ 2012-09-27 10:37 ` Samuel Iglesias Gonsalvez
2012-09-27 10:37 ` [PATCH 11/17] Staging: ipack: remove memory mapping callbacks Samuel Iglesias Gonsalvez
` (6 subsequent siblings)
15 siblings, 0 replies; 17+ messages in thread
From: Samuel Iglesias Gonsalvez @ 2012-09-27 10:37 UTC (permalink / raw)
To: Greg Kroah-Hartman
Cc: devel, linux-kernel, industrypack-devel, Jens Taprogge,
Samuel Iglesias Gonsalvez
From: Jens Taprogge <jens.taprogge@taprogge.org>
Use the regular ioremap functions and their managed counterparts instead
of the ones provided through IPack callbacks.
Signed-off-by: Jens Taprogge <jens.taprogge@taprogge.org>
Signed-off-by: Samuel Iglesias Gonsalvez <siglesias@igalia.com>
---
drivers/staging/ipack/devices/ipoctal.c | 70 +++++++++++++++----------------
drivers/staging/ipack/ipack.c | 8 ++--
2 files changed, 37 insertions(+), 41 deletions(-)
diff --git a/drivers/staging/ipack/devices/ipoctal.c b/drivers/staging/ipack/devices/ipoctal.c
index 35b98e8..3c8eb64 100644
--- a/drivers/staging/ipack/devices/ipoctal.c
+++ b/drivers/staging/ipack/devices/ipoctal.c
@@ -53,6 +53,8 @@ struct ipoctal {
struct ipoctal_channel channel[NR_CHANNELS];
unsigned char write;
struct tty_driver *tty_drv;
+ u8 __iomem *mem_space;
+ u8 __iomem *int_space;
};
static int ipoctal_port_activate(struct tty_port *port, struct tty_struct *tty)
@@ -252,8 +254,8 @@ static irqreturn_t ipoctal_irq_handler(void *arg)
ipoctal_irq_channel(&ipoctal->channel[i]);
/* Clear the IPack device interrupt */
- readw(ipoctal->dev->int_space.address + ACK_INT_REQ0);
- readw(ipoctal->dev->int_space.address + ACK_INT_REQ1);
+ readw(ipoctal->int_space + ACK_INT_REQ0);
+ readw(ipoctal->int_space + ACK_INT_REQ1);
return IRQ_HANDLED;
}
@@ -266,48 +268,55 @@ static const struct tty_port_operations ipoctal_tty_port_ops = {
static int ipoctal_inst_slot(struct ipoctal *ipoctal, unsigned int bus_nr,
unsigned int slot)
{
- int res = 0;
+ int res;
int i;
struct tty_driver *tty;
char name[20];
struct ipoctal_channel *channel;
+ struct ipack_region *region;
+ void __iomem *addr;
union scc2698_channel __iomem *chan_regs;
union scc2698_block __iomem *block_regs;
ipoctal->board_id = ipoctal->dev->id_device;
- res = ipoctal->dev->bus->ops->map_space(ipoctal->dev, 0,
- IPACK_IO_SPACE);
- if (res) {
+ region = &ipoctal->dev->region[IPACK_IO_SPACE];
+ addr = devm_ioremap_nocache(&ipoctal->dev->dev,
+ region->start, region->size);
+ if (!addr) {
dev_err(&ipoctal->dev->dev,
"Unable to map slot [%d:%d] IO space!\n",
bus_nr, slot);
- return res;
+ return -EADDRNOTAVAIL;
}
+ /* Save the virtual address to access the registers easily */
+ chan_regs =
+ (union scc2698_channel __iomem *) addr;
+ block_regs =
+ (union scc2698_block __iomem *) addr;
- res = ipoctal->dev->bus->ops->map_space(ipoctal->dev, 0,
- IPACK_INT_SPACE);
- if (res) {
+ region = &ipoctal->dev->region[IPACK_INT_SPACE];
+ ipoctal->int_space =
+ devm_ioremap_nocache(&ipoctal->dev->dev,
+ region->start, region->size);
+ if (!ipoctal->int_space) {
dev_err(&ipoctal->dev->dev,
"Unable to map slot [%d:%d] INT space!\n",
bus_nr, slot);
- goto out_unregister_io_space;
+ return -EADDRNOTAVAIL;
}
- res = ipoctal->dev->bus->ops->map_space(ipoctal->dev,
- 0x8000, IPACK_MEM_SPACE);
- if (res) {
+ region = &ipoctal->dev->region[IPACK_MEM_SPACE];
+ ipoctal->mem_space =
+ devm_ioremap_nocache(&ipoctal->dev->dev,
+ region->start, 0x8000);
+ if (!addr) {
dev_err(&ipoctal->dev->dev,
"Unable to map slot [%d:%d] MEM space!\n",
bus_nr, slot);
- goto out_unregister_int_space;
+ return -EADDRNOTAVAIL;
}
- /* Save the virtual address to access the registers easily */
- chan_regs =
- (union scc2698_channel __iomem *) ipoctal->dev->io_space.address;
- block_regs =
- (union scc2698_block __iomem *) ipoctal->dev->io_space.address;
/* Disable RX and TX before touching anything */
for (i = 0; i < NR_CHANNELS ; i++) {
@@ -350,17 +359,15 @@ static int ipoctal_inst_slot(struct ipoctal *ipoctal, unsigned int bus_nr,
ipoctal->dev->bus->ops->request_irq(ipoctal->dev,
ipoctal_irq_handler, ipoctal);
/* Dummy write */
- iowrite8(1, ipoctal->dev->mem_space.address + 1);
+ iowrite8(1, ipoctal->mem_space + 1);
/* Register the TTY device */
/* Each IP-OCTAL channel is a TTY port */
tty = alloc_tty_driver(NR_CHANNELS);
- if (!tty) {
- res = -ENOMEM;
- goto out_unregister_slot_unmap;
- }
+ if (!tty)
+ return -ENOMEM;
/* Fill struct tty_driver with ipoctal data */
tty->owner = THIS_MODULE;
@@ -383,7 +390,7 @@ static int ipoctal_inst_slot(struct ipoctal *ipoctal, unsigned int bus_nr,
if (res) {
dev_err(&ipoctal->dev->dev, "Can't register tty driver.\n");
put_tty_driver(tty);
- goto out_unregister_slot_unmap;
+ return res;
}
/* Save struct tty_driver for use it when uninstalling the device */
@@ -419,14 +426,6 @@ static int ipoctal_inst_slot(struct ipoctal *ipoctal, unsigned int bus_nr,
}
return 0;
-
-out_unregister_slot_unmap:
- ipoctal->dev->bus->ops->unmap_space(ipoctal->dev, IPACK_MEM_SPACE);
-out_unregister_int_space:
- ipoctal->dev->bus->ops->unmap_space(ipoctal->dev, IPACK_INT_SPACE);
-out_unregister_io_space:
- ipoctal->dev->bus->ops->unmap_space(ipoctal->dev, IPACK_IO_SPACE);
- return res;
}
static inline int ipoctal_copy_write_buffer(struct ipoctal_channel *channel,
@@ -704,9 +703,6 @@ static void __ipoctal_remove(struct ipoctal *ipoctal)
tty_unregister_driver(ipoctal->tty_drv);
put_tty_driver(ipoctal->tty_drv);
- ipoctal->dev->bus->ops->unmap_space(ipoctal->dev, IPACK_MEM_SPACE);
- ipoctal->dev->bus->ops->unmap_space(ipoctal->dev, IPACK_INT_SPACE);
- ipoctal->dev->bus->ops->unmap_space(ipoctal->dev, IPACK_IO_SPACE);
kfree(ipoctal);
}
diff --git a/drivers/staging/ipack/ipack.c b/drivers/staging/ipack/ipack.c
index d2ed9f5..5bd462b 100644
--- a/drivers/staging/ipack/ipack.c
+++ b/drivers/staging/ipack/ipack.c
@@ -351,12 +351,12 @@ static int ipack_device_read_id(struct ipack_device *dev)
int i;
int ret = 0;
- ret = dev->bus->ops->map_space(dev, 0, IPACK_ID_SPACE);
- if (ret) {
+ idmem = ioremap(dev->region[IPACK_ID_SPACE].start,
+ dev->region[IPACK_ID_SPACE].size);
+ if (!idmem) {
dev_err(&dev->dev, "error mapping memory\n");
return ret;
}
- idmem = dev->id_space.address;
/* Determine ID PROM Data Format. If we find the ids "IPAC" or "IPAH"
* we are dealing with a IndustryPack format 1 device. If we detect
@@ -421,7 +421,7 @@ static int ipack_device_read_id(struct ipack_device *dev)
}
out:
- dev->bus->ops->unmap_space(dev, IPACK_ID_SPACE);
+ iounmap(idmem);
return ret;
}
--
1.7.10.4
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH 11/17] Staging: ipack: remove memory mapping callbacks.
2012-09-27 10:37 [PATCH 01/17] Staging: ipack: get rid of ipack_device->bus_nr Samuel Iglesias Gonsalvez
` (8 preceding siblings ...)
2012-09-27 10:37 ` [PATCH 10/17] staging: ipack: swich to regular ioremap and friends Samuel Iglesias Gonsalvez
@ 2012-09-27 10:37 ` Samuel Iglesias Gonsalvez
2012-09-27 10:37 ` [PATCH 12/17] staging: ipack: Rename IPACK_MEM_SPACE to IPACK_MEM8_SPACE Samuel Iglesias Gonsalvez
` (5 subsequent siblings)
15 siblings, 0 replies; 17+ messages in thread
From: Samuel Iglesias Gonsalvez @ 2012-09-27 10:37 UTC (permalink / raw)
To: Greg Kroah-Hartman
Cc: devel, linux-kernel, industrypack-devel, Jens Taprogge,
Samuel Iglesias Gonsalvez
From: Jens Taprogge <jens.taprogge@taprogge.org>
Now that we have the infrastructure to use the regular function in place
and all existing users are converted, remove the map and unmap callbacks
from the ipack_bus_device->ops.
Signed-off-by: Jens Taprogge <jens.taprogge@taprogge.org>
Signed-off-by: Samuel Iglesias Gonsalvez <siglesias@igalia.com>
---
drivers/staging/ipack/bridges/tpci200.c | 200 +------------------------------
drivers/staging/ipack/bridges/tpci200.h | 4 -
drivers/staging/ipack/ipack.h | 17 ---
3 files changed, 1 insertion(+), 220 deletions(-)
diff --git a/drivers/staging/ipack/bridges/tpci200.c b/drivers/staging/ipack/bridges/tpci200.c
index 8428e3b..901f657 100644
--- a/drivers/staging/ipack/bridges/tpci200.c
+++ b/drivers/staging/ipack/bridges/tpci200.c
@@ -87,8 +87,6 @@ static void tpci200_set_mask(struct tpci200_board *tpci200,
static void tpci200_unregister(struct tpci200_board *tpci200)
{
- int i;
-
free_irq(tpci200->info->pdev->irq, (void *) tpci200);
pci_iounmap(tpci200->info->pdev, tpci200->info->interface_regs);
@@ -101,17 +99,6 @@ static void tpci200_unregister(struct tpci200_board *tpci200)
pci_disable_device(tpci200->info->pdev);
pci_dev_put(tpci200->info->pdev);
-
- for (i = 0; i < TPCI200_NB_SLOT; i++) {
- tpci200->slots[i].io_phys.start = 0;
- tpci200->slots[i].io_phys.size = 0;
- tpci200->slots[i].id_phys.start = 0;
- tpci200->slots[i].id_phys.size = 0;
- tpci200->slots[i].int_phys.start = 0;
- tpci200->slots[i].int_phys.size = 0;
- tpci200->slots[i].mem_phys.start = 0;
- tpci200->slots[i].mem_phys.size = 0;
- }
}
static void tpci200_enable_irq(struct tpci200_board *tpci200,
@@ -323,31 +310,8 @@ static int tpci200_register(struct tpci200_board *tpci200)
* clock rate 8 MHz
*/
slot_ctrl = 0;
-
- /* Set all slot physical address space */
- for (i = 0; i < TPCI200_NB_SLOT; i++) {
- tpci200->slots[i].io_phys.start =
- tpci200->mod_mem[IPACK_IO_SPACE]
- + TPCI200_IO_SPACE_INTERVAL * i;
- tpci200->slots[i].io_phys.size = TPCI200_IO_SPACE_SIZE;
-
- tpci200->slots[i].id_phys.start =
- tpci200->mod_mem[IPACK_ID_SPACE]
- + TPCI200_ID_SPACE_INTERVAL * i;
- tpci200->slots[i].id_phys.size = TPCI200_ID_SPACE_SIZE;
-
- tpci200->slots[i].int_phys.start =
- tpci200->mod_mem[IPACK_INT_SPACE]
- + TPCI200_INT_SPACE_INTERVAL * i;
- tpci200->slots[i].int_phys.size = TPCI200_INT_SPACE_SIZE;
-
- tpci200->slots[i].mem_phys.start =
- tpci200->mod_mem[IPACK_MEM_SPACE]
- + TPCI200_MEM8_SPACE_INTERVAL * i;
- tpci200->slots[i].mem_phys.size = TPCI200_MEM8_SPACE_SIZE;
-
+ for (i = 0; i < TPCI200_NB_SLOT; i++)
writew(slot_ctrl, &tpci200->info->interface_regs->control[i]);
- }
res = request_irq(tpci200->info->pdev->irq,
tpci200_interrupt, IRQF_SHARED,
@@ -371,166 +335,6 @@ out_disable_pci:
return res;
}
-static int tpci200_slot_unmap_space(struct ipack_device *dev, int space)
-{
- struct ipack_addr_space *virt_addr_space;
- struct tpci200_board *tpci200;
-
- tpci200 = check_slot(dev);
- if (tpci200 == NULL)
- return -EINVAL;
-
- if (mutex_lock_interruptible(&tpci200->mutex))
- return -ERESTARTSYS;
-
- switch (space) {
- case IPACK_IO_SPACE:
- if (dev->io_space.address == NULL) {
- dev_info(&dev->dev,
- "Slot [%d:%d] IO space not mapped !\n",
- dev->bus->bus_nr, dev->slot);
- goto out_unlock;
- }
- virt_addr_space = &dev->io_space;
- break;
- case IPACK_ID_SPACE:
- if (dev->id_space.address == NULL) {
- dev_info(&dev->dev,
- "Slot [%d:%d] ID space not mapped !\n",
- dev->bus->bus_nr, dev->slot);
- goto out_unlock;
- }
- virt_addr_space = &dev->id_space;
- break;
- case IPACK_INT_SPACE:
- if (dev->int_space.address == NULL) {
- dev_info(&dev->dev,
- "Slot [%d:%d] INT space not mapped !\n",
- dev->bus->bus_nr, dev->slot);
- goto out_unlock;
- }
- virt_addr_space = &dev->int_space;
- break;
- case IPACK_MEM_SPACE:
- if (dev->mem_space.address == NULL) {
- dev_info(&dev->dev,
- "Slot [%d:%d] MEM space not mapped !\n",
- dev->bus->bus_nr, dev->slot);
- goto out_unlock;
- }
- virt_addr_space = &dev->mem_space;
- break;
- default:
- dev_err(&dev->dev,
- "Slot [%d:%d] space number %d doesn't exist !\n",
- dev->bus->bus_nr, dev->slot, space);
- mutex_unlock(&tpci200->mutex);
- return -EINVAL;
- }
-
- iounmap(virt_addr_space->address);
-
- virt_addr_space->address = NULL;
- virt_addr_space->size = 0;
-out_unlock:
- mutex_unlock(&tpci200->mutex);
- return 0;
-}
-
-static int tpci200_slot_map_space(struct ipack_device *dev,
- ssize_t memory_size, int space)
-{
- int res = 0;
- size_t size_to_map;
- phys_addr_t phys_address;
- struct ipack_addr_space *virt_addr_space;
- struct tpci200_board *tpci200;
-
- tpci200 = check_slot(dev);
- if (tpci200 == NULL)
- return -EINVAL;
-
- if (mutex_lock_interruptible(&tpci200->mutex))
- return -ERESTARTSYS;
-
- switch (space) {
- case IPACK_IO_SPACE:
- if (dev->io_space.address != NULL) {
- dev_err(&dev->dev,
- "Slot [%d:%d] IO space already mapped !\n",
- tpci200->number, dev->slot);
- res = -EINVAL;
- goto out_unlock;
- }
- virt_addr_space = &dev->io_space;
-
- phys_address = tpci200->slots[dev->slot].io_phys.start;
- size_to_map = tpci200->slots[dev->slot].io_phys.size;
- break;
- case IPACK_ID_SPACE:
- if (dev->id_space.address != NULL) {
- dev_err(&dev->dev,
- "Slot [%d:%d] ID space already mapped !\n",
- tpci200->number, dev->slot);
- res = -EINVAL;
- goto out_unlock;
- }
- virt_addr_space = &dev->id_space;
-
- phys_address = tpci200->slots[dev->slot].id_phys.start;
- size_to_map = tpci200->slots[dev->slot].id_phys.size;
- break;
- case IPACK_INT_SPACE:
- if (dev->int_space.address != NULL) {
- dev_err(&dev->dev,
- "Slot [%d:%d] INT space already mapped !\n",
- tpci200->number, dev->slot);
- res = -EINVAL;
- goto out_unlock;
- }
- virt_addr_space = &dev->int_space;
-
- phys_address = tpci200->slots[dev->slot].int_phys.start;
- size_to_map = tpci200->slots[dev->slot].int_phys.size;
- break;
- case IPACK_MEM_SPACE:
- if (dev->mem_space.address != NULL) {
- dev_err(&dev->dev,
- "Slot [%d:%d] MEM space already mapped !\n",
- tpci200->number, dev->slot);
- res = -EINVAL;
- goto out_unlock;
- }
- virt_addr_space = &dev->mem_space;
-
- if (memory_size > tpci200->slots[dev->slot].mem_phys.size) {
- dev_err(&dev->dev,
- "Slot [%d:%d] request is 0x%zX memory, only 0x%zX available !\n",
- dev->bus->bus_nr, dev->slot, memory_size,
- tpci200->slots[dev->slot].mem_phys.size);
- res = -EINVAL;
- goto out_unlock;
- }
-
- phys_address = tpci200->slots[dev->slot].mem_phys.start;
- size_to_map = memory_size;
- break;
- default:
- dev_err(&dev->dev, "Slot [%d:%d] space %d doesn't exist !\n",
- tpci200->number, dev->slot, space);
- res = -EINVAL;
- goto out_unlock;
- }
-
- virt_addr_space->size = size_to_map;
- virt_addr_space->address =
- ioremap_nocache((unsigned long)phys_address, size_to_map);
-
-out_unlock:
- mutex_unlock(&tpci200->mutex);
- return res;
-}
-
static int tpci200_get_clockrate(struct ipack_device *dev)
{
struct tpci200_board *tpci200 = check_slot(dev);
@@ -618,8 +422,6 @@ static void tpci200_uninstall(struct tpci200_board *tpci200)
}
static const struct ipack_bus_ops tpci200_bus_ops = {
- .map_space = tpci200_slot_map_space,
- .unmap_space = tpci200_slot_unmap_space,
.request_irq = tpci200_request_irq,
.free_irq = tpci200_free_irq,
.get_clockrate = tpci200_get_clockrate,
diff --git a/drivers/staging/ipack/bridges/tpci200.h b/drivers/staging/ipack/bridges/tpci200.h
index fe8e97e..982f319 100644
--- a/drivers/staging/ipack/bridges/tpci200.h
+++ b/drivers/staging/ipack/bridges/tpci200.h
@@ -138,10 +138,6 @@ struct slot_irq {
*/
struct tpci200_slot {
struct slot_irq *irq;
- struct ipack_region io_phys;
- struct ipack_region id_phys;
- struct ipack_region int_phys;
- struct ipack_region mem_phys;
};
/**
diff --git a/drivers/staging/ipack/ipack.h b/drivers/staging/ipack/ipack.h
index 43d152a..af95028 100644
--- a/drivers/staging/ipack/ipack.h
+++ b/drivers/staging/ipack/ipack.h
@@ -42,17 +42,6 @@ enum ipack_space {
};
/**
- * struct ipack_addr_space - Virtual address space mapped for a specified type.
- *
- * @address: virtual address
- * @size: size of the mapped space
- */
-struct ipack_addr_space {
- void __iomem *address;
- unsigned int size;
-};
-
-/**
*/
struct ipack_region {
phys_addr_t start;
@@ -76,10 +65,6 @@ struct ipack_region {
struct ipack_device {
unsigned int slot;
struct ipack_bus_device *bus;
- struct ipack_addr_space id_space;
- struct ipack_addr_space io_space;
- struct ipack_addr_space int_space;
- struct ipack_addr_space mem_space;
struct device dev;
void (*release) (struct ipack_device *dev);
struct ipack_region region[IPACK_SPACE_COUNT];
@@ -135,8 +120,6 @@ struct ipack_driver {
* @reset_timeout: Resets the state returned by get_timeout.
*/
struct ipack_bus_ops {
- int (*map_space) (struct ipack_device *dev, ssize_t memory_size, int space);
- int (*unmap_space) (struct ipack_device *dev, int space);
int (*request_irq) (struct ipack_device *dev,
irqreturn_t (*handler)(void *), void *arg);
int (*free_irq) (struct ipack_device *dev);
--
1.7.10.4
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH 12/17] staging: ipack: Rename IPACK_MEM_SPACE to IPACK_MEM8_SPACE.
2012-09-27 10:37 [PATCH 01/17] Staging: ipack: get rid of ipack_device->bus_nr Samuel Iglesias Gonsalvez
` (9 preceding siblings ...)
2012-09-27 10:37 ` [PATCH 11/17] Staging: ipack: remove memory mapping callbacks Samuel Iglesias Gonsalvez
@ 2012-09-27 10:37 ` Samuel Iglesias Gonsalvez
2012-09-27 10:37 ` [PATCH 13/17] staging: ipack: Add support for IPACK_MEM16_SPACE Samuel Iglesias Gonsalvez
` (4 subsequent siblings)
15 siblings, 0 replies; 17+ messages in thread
From: Samuel Iglesias Gonsalvez @ 2012-09-27 10:37 UTC (permalink / raw)
To: Greg Kroah-Hartman
Cc: devel, linux-kernel, industrypack-devel, Jens Taprogge,
Samuel Iglesias Gonsalvez
From: Jens Taprogge <jens.taprogge@taprogge.org>
There also is a MEM16 space. This will make it clear which one is
which, once support for MEM16 space is added.
Signed-off-by: Jens Taprogge <jens.taprogge@taprogge.org>
Signed-off-by: Samuel Iglesias Gonsalvez <siglesias@igalia.com>
---
drivers/staging/ipack/bridges/tpci200.c | 24 ++++++++++++------------
drivers/staging/ipack/devices/ipoctal.c | 10 +++++-----
drivers/staging/ipack/ipack.h | 2 +-
3 files changed, 18 insertions(+), 18 deletions(-)
diff --git a/drivers/staging/ipack/bridges/tpci200.c b/drivers/staging/ipack/bridges/tpci200.c
index 901f657..7127a3b 100644
--- a/drivers/staging/ipack/bridges/tpci200.c
+++ b/drivers/staging/ipack/bridges/tpci200.c
@@ -29,17 +29,17 @@ static const u16 tpci200_status_error[] = {
};
static const size_t tpci200_space_size[IPACK_SPACE_COUNT] = {
- [IPACK_IO_SPACE] = TPCI200_IO_SPACE_SIZE,
- [IPACK_ID_SPACE] = TPCI200_ID_SPACE_SIZE,
- [IPACK_INT_SPACE] = TPCI200_INT_SPACE_SIZE,
- [IPACK_MEM_SPACE] = TPCI200_MEM8_SPACE_SIZE,
+ [IPACK_IO_SPACE] = TPCI200_IO_SPACE_SIZE,
+ [IPACK_ID_SPACE] = TPCI200_ID_SPACE_SIZE,
+ [IPACK_INT_SPACE] = TPCI200_INT_SPACE_SIZE,
+ [IPACK_MEM8_SPACE] = TPCI200_MEM8_SPACE_SIZE,
};
static const size_t tpci200_space_interval[IPACK_SPACE_COUNT] = {
- [IPACK_IO_SPACE] = TPCI200_IO_SPACE_INTERVAL,
- [IPACK_ID_SPACE] = TPCI200_ID_SPACE_INTERVAL,
- [IPACK_INT_SPACE] = TPCI200_INT_SPACE_INTERVAL,
- [IPACK_MEM_SPACE] = TPCI200_MEM8_SPACE_INTERVAL,
+ [IPACK_IO_SPACE] = TPCI200_IO_SPACE_INTERVAL,
+ [IPACK_ID_SPACE] = TPCI200_ID_SPACE_INTERVAL,
+ [IPACK_INT_SPACE] = TPCI200_INT_SPACE_INTERVAL,
+ [IPACK_MEM8_SPACE] = TPCI200_MEM8_SPACE_INTERVAL,
};
static struct tpci200_board *check_slot(struct ipack_device *dev)
@@ -271,12 +271,12 @@ static int tpci200_register(struct tpci200_board *tpci200)
goto out_release_ip_space;
}
- /* Request MEM space (Bar 4) */
+ /* Request MEM8 space (Bar 5) */
res = pci_request_region(tpci200->info->pdev, TPCI200_MEM8_SPACE_BAR,
- "Carrier MEM space");
+ "Carrier MEM8 space");
if (res) {
dev_err(&tpci200->info->pdev->dev,
- "(bn 0x%X, sn 0x%X) failed to allocate PCI resource for BAR 4!",
+ "(bn 0x%X, sn 0x%X) failed to allocate PCI resource for BAR 5!",
tpci200->info->pdev->bus->number,
tpci200->info->pdev->devfn);
goto out_release_ioid_int_space;
@@ -297,7 +297,7 @@ static int tpci200_register(struct tpci200_board *tpci200)
tpci200->mod_mem[IPACK_ID_SPACE] = ioidint_base + TPCI200_ID_SPACE_OFF;
tpci200->mod_mem[IPACK_INT_SPACE] =
ioidint_base + TPCI200_INT_SPACE_OFF;
- tpci200->mod_mem[IPACK_MEM_SPACE] =
+ tpci200->mod_mem[IPACK_MEM8_SPACE] =
pci_resource_start(tpci200->info->pdev,
TPCI200_MEM8_SPACE_BAR);
diff --git a/drivers/staging/ipack/devices/ipoctal.c b/drivers/staging/ipack/devices/ipoctal.c
index 3c8eb64..fb7155c 100644
--- a/drivers/staging/ipack/devices/ipoctal.c
+++ b/drivers/staging/ipack/devices/ipoctal.c
@@ -53,7 +53,7 @@ struct ipoctal {
struct ipoctal_channel channel[NR_CHANNELS];
unsigned char write;
struct tty_driver *tty_drv;
- u8 __iomem *mem_space;
+ u8 __iomem *mem8_space;
u8 __iomem *int_space;
};
@@ -306,13 +306,13 @@ static int ipoctal_inst_slot(struct ipoctal *ipoctal, unsigned int bus_nr,
return -EADDRNOTAVAIL;
}
- region = &ipoctal->dev->region[IPACK_MEM_SPACE];
- ipoctal->mem_space =
+ region = &ipoctal->dev->region[IPACK_MEM8_SPACE];
+ ipoctal->mem8_space =
devm_ioremap_nocache(&ipoctal->dev->dev,
region->start, 0x8000);
if (!addr) {
dev_err(&ipoctal->dev->dev,
- "Unable to map slot [%d:%d] MEM space!\n",
+ "Unable to map slot [%d:%d] MEM8 space!\n",
bus_nr, slot);
return -EADDRNOTAVAIL;
}
@@ -359,7 +359,7 @@ static int ipoctal_inst_slot(struct ipoctal *ipoctal, unsigned int bus_nr,
ipoctal->dev->bus->ops->request_irq(ipoctal->dev,
ipoctal_irq_handler, ipoctal);
/* Dummy write */
- iowrite8(1, ipoctal->mem_space + 1);
+ iowrite8(1, ipoctal->mem8_space + 1);
/* Register the TTY device */
diff --git a/drivers/staging/ipack/ipack.h b/drivers/staging/ipack/ipack.h
index af95028..e35fe54 100644
--- a/drivers/staging/ipack/ipack.h
+++ b/drivers/staging/ipack/ipack.h
@@ -34,8 +34,8 @@ struct ipack_driver;
enum ipack_space {
IPACK_IO_SPACE = 0,
IPACK_ID_SPACE,
- IPACK_MEM_SPACE,
IPACK_INT_SPACE,
+ IPACK_MEM8_SPACE,
/* Dummy for counting the number of entries. Must remain the last
* entry */
IPACK_SPACE_COUNT,
--
1.7.10.4
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH 13/17] staging: ipack: Add support for IPACK_MEM16_SPACE.
2012-09-27 10:37 [PATCH 01/17] Staging: ipack: get rid of ipack_device->bus_nr Samuel Iglesias Gonsalvez
` (10 preceding siblings ...)
2012-09-27 10:37 ` [PATCH 12/17] staging: ipack: Rename IPACK_MEM_SPACE to IPACK_MEM8_SPACE Samuel Iglesias Gonsalvez
@ 2012-09-27 10:37 ` Samuel Iglesias Gonsalvez
2012-09-27 10:37 ` [PATCH 14/17] Staging: ipack: remove blank line at EOF warning in Kconfig files Samuel Iglesias Gonsalvez
` (3 subsequent siblings)
15 siblings, 0 replies; 17+ messages in thread
From: Samuel Iglesias Gonsalvez @ 2012-09-27 10:37 UTC (permalink / raw)
To: Greg Kroah-Hartman
Cc: devel, linux-kernel, industrypack-devel, Jens Taprogge,
Samuel Iglesias Gonsalvez
From: Jens Taprogge <jens.taprogge@taprogge.org>
Signed-off-by: Jens Taprogge <jens.taprogge@taprogge.org>
Signed-off-by: Samuel Iglesias Gonsalvez <siglesias@igalia.com>
---
drivers/staging/ipack/bridges/tpci200.c | 19 +++++++++++++++++++
drivers/staging/ipack/ipack.h | 1 +
2 files changed, 20 insertions(+)
diff --git a/drivers/staging/ipack/bridges/tpci200.c b/drivers/staging/ipack/bridges/tpci200.c
index 7127a3b..376e794 100644
--- a/drivers/staging/ipack/bridges/tpci200.c
+++ b/drivers/staging/ipack/bridges/tpci200.c
@@ -33,6 +33,7 @@ static const size_t tpci200_space_size[IPACK_SPACE_COUNT] = {
[IPACK_ID_SPACE] = TPCI200_ID_SPACE_SIZE,
[IPACK_INT_SPACE] = TPCI200_INT_SPACE_SIZE,
[IPACK_MEM8_SPACE] = TPCI200_MEM8_SPACE_SIZE,
+ [IPACK_MEM16_SPACE] = TPCI200_MEM16_SPACE_SIZE,
};
static const size_t tpci200_space_interval[IPACK_SPACE_COUNT] = {
@@ -40,6 +41,7 @@ static const size_t tpci200_space_interval[IPACK_SPACE_COUNT] = {
[IPACK_ID_SPACE] = TPCI200_ID_SPACE_INTERVAL,
[IPACK_INT_SPACE] = TPCI200_INT_SPACE_INTERVAL,
[IPACK_MEM8_SPACE] = TPCI200_MEM8_SPACE_INTERVAL,
+ [IPACK_MEM16_SPACE] = TPCI200_MEM16_SPACE_INTERVAL,
};
static struct tpci200_board *check_slot(struct ipack_device *dev)
@@ -94,6 +96,7 @@ static void tpci200_unregister(struct tpci200_board *tpci200)
pci_release_region(tpci200->info->pdev, TPCI200_IP_INTERFACE_BAR);
pci_release_region(tpci200->info->pdev, TPCI200_IO_ID_INT_SPACES_BAR);
+ pci_release_region(tpci200->info->pdev, TPCI200_MEM16_SPACE_BAR);
pci_release_region(tpci200->info->pdev, TPCI200_MEM8_SPACE_BAR);
pci_release_region(tpci200->info->pdev, TPCI200_CFG_MEM_BAR);
@@ -282,6 +285,17 @@ static int tpci200_register(struct tpci200_board *tpci200)
goto out_release_ioid_int_space;
}
+ /* Request MEM16 space (Bar 4) */
+ res = pci_request_region(tpci200->info->pdev, TPCI200_MEM16_SPACE_BAR,
+ "Carrier MEM16 space");
+ if (res) {
+ dev_err(&tpci200->info->pdev->dev,
+ "(bn 0x%X, sn 0x%X) failed to allocate PCI resource for BAR 4!",
+ tpci200->info->pdev->bus->number,
+ tpci200->info->pdev->devfn);
+ goto out_release_mem8_space;
+ }
+
/* Map internal tpci200 driver user space */
tpci200->info->interface_regs =
ioremap_nocache(pci_resource_start(tpci200->info->pdev,
@@ -300,6 +314,9 @@ static int tpci200_register(struct tpci200_board *tpci200)
tpci200->mod_mem[IPACK_MEM8_SPACE] =
pci_resource_start(tpci200->info->pdev,
TPCI200_MEM8_SPACE_BAR);
+ tpci200->mod_mem[IPACK_MEM16_SPACE] =
+ pci_resource_start(tpci200->info->pdev,
+ TPCI200_MEM16_SPACE_BAR);
/* Set the default parameters of the slot
* INT0 disabled, level sensitive
@@ -326,6 +343,8 @@ static int tpci200_register(struct tpci200_board *tpci200)
return 0;
+out_release_mem8_space:
+ pci_release_region(tpci200->info->pdev, TPCI200_MEM8_SPACE_BAR);
out_release_ioid_int_space:
pci_release_region(tpci200->info->pdev, TPCI200_IO_ID_INT_SPACES_BAR);
out_release_ip_space:
diff --git a/drivers/staging/ipack/ipack.h b/drivers/staging/ipack/ipack.h
index e35fe54..689af92 100644
--- a/drivers/staging/ipack/ipack.h
+++ b/drivers/staging/ipack/ipack.h
@@ -36,6 +36,7 @@ enum ipack_space {
IPACK_ID_SPACE,
IPACK_INT_SPACE,
IPACK_MEM8_SPACE,
+ IPACK_MEM16_SPACE,
/* Dummy for counting the number of entries. Must remain the last
* entry */
IPACK_SPACE_COUNT,
--
1.7.10.4
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH 14/17] Staging: ipack: remove blank line at EOF warning in Kconfig files
2012-09-27 10:37 [PATCH 01/17] Staging: ipack: get rid of ipack_device->bus_nr Samuel Iglesias Gonsalvez
` (11 preceding siblings ...)
2012-09-27 10:37 ` [PATCH 13/17] staging: ipack: Add support for IPACK_MEM16_SPACE Samuel Iglesias Gonsalvez
@ 2012-09-27 10:37 ` Samuel Iglesias Gonsalvez
2012-09-27 10:37 ` [PATCH 15/17] staging: ipack: Rename bridges to carriers Samuel Iglesias Gonsalvez
` (2 subsequent siblings)
15 siblings, 0 replies; 17+ messages in thread
From: Samuel Iglesias Gonsalvez @ 2012-09-27 10:37 UTC (permalink / raw)
To: Greg Kroah-Hartman
Cc: devel, linux-kernel, industrypack-devel, Samuel Iglesias Gonsalvez
Signed-off-by: Samuel Iglesias Gonsalvez <siglesias@igalia.com>
---
drivers/staging/ipack/bridges/Kconfig | 1 -
drivers/staging/ipack/devices/Kconfig | 1 -
2 files changed, 2 deletions(-)
diff --git a/drivers/staging/ipack/bridges/Kconfig b/drivers/staging/ipack/bridges/Kconfig
index 97c837e..33fdc24 100644
--- a/drivers/staging/ipack/bridges/Kconfig
+++ b/drivers/staging/ipack/bridges/Kconfig
@@ -5,4 +5,3 @@ config BOARD_TPCI200
help
This driver supports the TEWS TPCI200 device for the IndustryPack bus.
default n
-
diff --git a/drivers/staging/ipack/devices/Kconfig b/drivers/staging/ipack/devices/Kconfig
index 39f7188..0b82fdc 100644
--- a/drivers/staging/ipack/devices/Kconfig
+++ b/drivers/staging/ipack/devices/Kconfig
@@ -4,4 +4,3 @@ config SERIAL_IPOCTAL
help
This driver supports the IPOCTAL serial port device for the IndustryPack bus.
default n
-
--
1.7.10.4
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH 15/17] staging: ipack: Rename bridges to carriers.
2012-09-27 10:37 [PATCH 01/17] Staging: ipack: get rid of ipack_device->bus_nr Samuel Iglesias Gonsalvez
` (12 preceding siblings ...)
2012-09-27 10:37 ` [PATCH 14/17] Staging: ipack: remove blank line at EOF warning in Kconfig files Samuel Iglesias Gonsalvez
@ 2012-09-27 10:37 ` Samuel Iglesias Gonsalvez
2012-09-27 10:37 ` [PATCH 16/17] staging: ipack: Documentation cleanups Samuel Iglesias Gonsalvez
2012-09-27 10:37 ` [PATCH 17/17] Staging: ipack: fix wrong return value Samuel Iglesias Gonsalvez
15 siblings, 0 replies; 17+ messages in thread
From: Samuel Iglesias Gonsalvez @ 2012-09-27 10:37 UTC (permalink / raw)
To: Greg Kroah-Hartman
Cc: devel, linux-kernel, industrypack-devel, Jens Taprogge,
Samuel Iglesias Gonsalvez
From: Jens Taprogge <jens.taprogge@taprogge.org>
This is the name used by the standard.
Signed-off-by: Jens Taprogge <jens.taprogge@taprogge.org>
Signed-off-by: Samuel Iglesias Gonsalvez <siglesias@igalia.com>
---
drivers/staging/ipack/Kconfig | 2 +-
drivers/staging/ipack/Makefile | 2 +-
drivers/staging/ipack/bridges/Kconfig | 7 -
drivers/staging/ipack/bridges/Makefile | 1 -
drivers/staging/ipack/bridges/tpci200.c | 634 ------------------------------
drivers/staging/ipack/bridges/tpci200.h | 167 --------
drivers/staging/ipack/carriers/Kconfig | 7 +
drivers/staging/ipack/carriers/Makefile | 1 +
drivers/staging/ipack/carriers/tpci200.c | 634 ++++++++++++++++++++++++++++++
drivers/staging/ipack/carriers/tpci200.h | 167 ++++++++
10 files changed, 811 insertions(+), 811 deletions(-)
delete mode 100644 drivers/staging/ipack/bridges/Kconfig
delete mode 100644 drivers/staging/ipack/bridges/Makefile
delete mode 100644 drivers/staging/ipack/bridges/tpci200.c
delete mode 100644 drivers/staging/ipack/bridges/tpci200.h
create mode 100644 drivers/staging/ipack/carriers/Kconfig
create mode 100644 drivers/staging/ipack/carriers/Makefile
create mode 100644 drivers/staging/ipack/carriers/tpci200.c
create mode 100644 drivers/staging/ipack/carriers/tpci200.h
diff --git a/drivers/staging/ipack/Kconfig b/drivers/staging/ipack/Kconfig
index 4cf4706..9b4495a 100644
--- a/drivers/staging/ipack/Kconfig
+++ b/drivers/staging/ipack/Kconfig
@@ -14,7 +14,7 @@ menuconfig IPACK_BUS
if IPACK_BUS
-source "drivers/staging/ipack/bridges/Kconfig"
+source "drivers/staging/ipack/carriers/Kconfig"
source "drivers/staging/ipack/devices/Kconfig"
diff --git a/drivers/staging/ipack/Makefile b/drivers/staging/ipack/Makefile
index 85ff223..6f14ade 100644
--- a/drivers/staging/ipack/Makefile
+++ b/drivers/staging/ipack/Makefile
@@ -3,4 +3,4 @@
#
obj-$(CONFIG_IPACK_BUS) += ipack.o
obj-y += devices/
-obj-y += bridges/
+obj-y += carriers/
diff --git a/drivers/staging/ipack/bridges/Kconfig b/drivers/staging/ipack/bridges/Kconfig
deleted file mode 100644
index 33fdc24..0000000
--- a/drivers/staging/ipack/bridges/Kconfig
+++ /dev/null
@@ -1,7 +0,0 @@
-config BOARD_TPCI200
- tristate "TEWS TPCI-200 support for IndustryPack bus"
- depends on IPACK_BUS
- depends on PCI
- help
- This driver supports the TEWS TPCI200 device for the IndustryPack bus.
- default n
diff --git a/drivers/staging/ipack/bridges/Makefile b/drivers/staging/ipack/bridges/Makefile
deleted file mode 100644
index d8b7645..0000000
--- a/drivers/staging/ipack/bridges/Makefile
+++ /dev/null
@@ -1 +0,0 @@
-obj-$(CONFIG_BOARD_TPCI200) += tpci200.o
diff --git a/drivers/staging/ipack/bridges/tpci200.c b/drivers/staging/ipack/bridges/tpci200.c
deleted file mode 100644
index 376e794..0000000
--- a/drivers/staging/ipack/bridges/tpci200.c
+++ /dev/null
@@ -1,634 +0,0 @@
-/**
- * tpci200.c
- *
- * driver for the TEWS TPCI-200 device
- * Copyright (c) 2009 Nicolas Serafini, EIC2 SA
- * Copyright (c) 2010,2011 Samuel Iglesias Gonsalvez <siglesia@cern.ch>, CERN
- * Copyright (c) 2012 Samuel Iglesias Gonsalvez <siglesias@igalia.com>, Igalia
- *
- * 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; version 2 of the License.
- */
-
-#include <linux/module.h>
-#include "tpci200.h"
-
-static const u16 tpci200_status_timeout[] = {
- TPCI200_A_TIMEOUT,
- TPCI200_B_TIMEOUT,
- TPCI200_C_TIMEOUT,
- TPCI200_D_TIMEOUT,
-};
-
-static const u16 tpci200_status_error[] = {
- TPCI200_A_ERROR,
- TPCI200_B_ERROR,
- TPCI200_C_ERROR,
- TPCI200_D_ERROR,
-};
-
-static const size_t tpci200_space_size[IPACK_SPACE_COUNT] = {
- [IPACK_IO_SPACE] = TPCI200_IO_SPACE_SIZE,
- [IPACK_ID_SPACE] = TPCI200_ID_SPACE_SIZE,
- [IPACK_INT_SPACE] = TPCI200_INT_SPACE_SIZE,
- [IPACK_MEM8_SPACE] = TPCI200_MEM8_SPACE_SIZE,
- [IPACK_MEM16_SPACE] = TPCI200_MEM16_SPACE_SIZE,
-};
-
-static const size_t tpci200_space_interval[IPACK_SPACE_COUNT] = {
- [IPACK_IO_SPACE] = TPCI200_IO_SPACE_INTERVAL,
- [IPACK_ID_SPACE] = TPCI200_ID_SPACE_INTERVAL,
- [IPACK_INT_SPACE] = TPCI200_INT_SPACE_INTERVAL,
- [IPACK_MEM8_SPACE] = TPCI200_MEM8_SPACE_INTERVAL,
- [IPACK_MEM16_SPACE] = TPCI200_MEM16_SPACE_INTERVAL,
-};
-
-static struct tpci200_board *check_slot(struct ipack_device *dev)
-{
- struct tpci200_board *tpci200;
-
- if (dev == NULL)
- return NULL;
-
-
- tpci200 = dev_get_drvdata(dev->bus->parent);
-
- if (tpci200 == NULL) {
- dev_info(&dev->dev, "carrier board not found\n");
- return NULL;
- }
-
- if (dev->slot >= TPCI200_NB_SLOT) {
- dev_info(&dev->dev,
- "Slot [%d:%d] doesn't exist! Last tpci200 slot is %d.\n",
- dev->bus->bus_nr, dev->slot, TPCI200_NB_SLOT-1);
- return NULL;
- }
-
- return tpci200;
-}
-
-static void tpci200_clear_mask(struct tpci200_board *tpci200,
- __le16 __iomem *addr, u16 mask)
-{
- unsigned long flags;
- spin_lock_irqsave(&tpci200->regs_lock, flags);
- iowrite16(ioread16(addr) & (~mask), addr);
- spin_unlock_irqrestore(&tpci200->regs_lock, flags);
-}
-
-static void tpci200_set_mask(struct tpci200_board *tpci200,
- __le16 __iomem *addr, u16 mask)
-{
- unsigned long flags;
- spin_lock_irqsave(&tpci200->regs_lock, flags);
- iowrite16(ioread16(addr) | mask, addr);
- spin_unlock_irqrestore(&tpci200->regs_lock, flags);
-}
-
-static void tpci200_unregister(struct tpci200_board *tpci200)
-{
- free_irq(tpci200->info->pdev->irq, (void *) tpci200);
-
- pci_iounmap(tpci200->info->pdev, tpci200->info->interface_regs);
- pci_iounmap(tpci200->info->pdev, tpci200->info->cfg_regs);
-
- pci_release_region(tpci200->info->pdev, TPCI200_IP_INTERFACE_BAR);
- pci_release_region(tpci200->info->pdev, TPCI200_IO_ID_INT_SPACES_BAR);
- pci_release_region(tpci200->info->pdev, TPCI200_MEM16_SPACE_BAR);
- pci_release_region(tpci200->info->pdev, TPCI200_MEM8_SPACE_BAR);
- pci_release_region(tpci200->info->pdev, TPCI200_CFG_MEM_BAR);
-
- pci_disable_device(tpci200->info->pdev);
- pci_dev_put(tpci200->info->pdev);
-}
-
-static void tpci200_enable_irq(struct tpci200_board *tpci200,
- int islot)
-{
- tpci200_set_mask(tpci200,
- &tpci200->info->interface_regs->control[islot],
- TPCI200_INT0_EN | TPCI200_INT1_EN);
-}
-
-static void tpci200_disable_irq(struct tpci200_board *tpci200,
- int islot)
-{
- tpci200_clear_mask(tpci200,
- &tpci200->info->interface_regs->control[islot],
- TPCI200_INT0_EN | TPCI200_INT1_EN);
-}
-
-static irqreturn_t tpci200_slot_irq(struct slot_irq *slot_irq)
-{
- irqreturn_t ret;
-
- if (!slot_irq)
- return -ENODEV;
- ret = slot_irq->handler(slot_irq->arg);
-
- return ret;
-}
-
-static irqreturn_t tpci200_interrupt(int irq, void *dev_id)
-{
- struct tpci200_board *tpci200 = (struct tpci200_board *) dev_id;
- struct slot_irq *slot_irq;
- irqreturn_t ret;
- u16 status_reg;
- int i;
-
- /* Read status register */
- status_reg = ioread16(&tpci200->info->interface_regs->status);
-
- /* Did we cause the interrupt? */
- if (!(status_reg & TPCI200_SLOT_INT_MASK))
- return IRQ_NONE;
-
- /* callback to the IRQ handler for the corresponding slot */
- rcu_read_lock();
- for (i = 0; i < TPCI200_NB_SLOT; i++) {
- if (!(status_reg & ((TPCI200_A_INT0 | TPCI200_A_INT1) << (2 * i))))
- continue;
- slot_irq = rcu_dereference(tpci200->slots[i].irq);
- ret = tpci200_slot_irq(slot_irq);
- if (ret == -ENODEV) {
- dev_info(&tpci200->info->pdev->dev,
- "No registered ISR for slot [%d:%d]!. IRQ will be disabled.\n",
- tpci200->number, i);
- tpci200_disable_irq(tpci200, i);
- }
- }
- rcu_read_unlock();
-
- return IRQ_HANDLED;
-}
-
-static int tpci200_free_irq(struct ipack_device *dev)
-{
- struct slot_irq *slot_irq;
- struct tpci200_board *tpci200;
-
- tpci200 = check_slot(dev);
- if (tpci200 == NULL)
- return -EINVAL;
-
- if (mutex_lock_interruptible(&tpci200->mutex))
- return -ERESTARTSYS;
-
- if (tpci200->slots[dev->slot].irq == NULL) {
- mutex_unlock(&tpci200->mutex);
- return -EINVAL;
- }
-
- tpci200_disable_irq(tpci200, dev->slot);
- slot_irq = tpci200->slots[dev->slot].irq;
- /* uninstall handler */
- RCU_INIT_POINTER(tpci200->slots[dev->slot].irq, NULL);
- synchronize_rcu();
- kfree(slot_irq);
- mutex_unlock(&tpci200->mutex);
- return 0;
-}
-
-static int tpci200_request_irq(struct ipack_device *dev,
- irqreturn_t (*handler)(void *), void *arg)
-{
- int res = 0;
- struct slot_irq *slot_irq;
- struct tpci200_board *tpci200;
-
- tpci200 = check_slot(dev);
- if (tpci200 == NULL)
- return -EINVAL;
-
- if (mutex_lock_interruptible(&tpci200->mutex))
- return -ERESTARTSYS;
-
- if (tpci200->slots[dev->slot].irq != NULL) {
- dev_err(&dev->dev,
- "Slot [%d:%d] IRQ already registered !\n", dev->bus->bus_nr,
- dev->slot);
- res = -EINVAL;
- goto out_unlock;
- }
-
- slot_irq = kzalloc(sizeof(struct slot_irq), GFP_KERNEL);
- if (slot_irq == NULL) {
- dev_err(&dev->dev,
- "Slot [%d:%d] unable to allocate memory for IRQ !\n",
- dev->bus->bus_nr, dev->slot);
- res = -ENOMEM;
- goto out_unlock;
- }
-
- /*
- * WARNING: Setup Interrupt Vector in the IndustryPack device
- * before an IRQ request.
- * Read the User Manual of your IndustryPack device to know
- * where to write the vector in memory.
- */
- slot_irq->handler = handler;
- slot_irq->arg = arg;
- slot_irq->holder = dev;
-
- rcu_assign_pointer(tpci200->slots[dev->slot].irq, slot_irq);
- tpci200_enable_irq(tpci200, dev->slot);
-
-out_unlock:
- mutex_unlock(&tpci200->mutex);
- return res;
-}
-
-static int tpci200_register(struct tpci200_board *tpci200)
-{
- int i;
- int res;
- phys_addr_t ioidint_base;
- unsigned short slot_ctrl;
-
- if (pci_enable_device(tpci200->info->pdev) < 0)
- return -ENODEV;
-
- /* Request IP interface register (Bar 2) */
- res = pci_request_region(tpci200->info->pdev, TPCI200_IP_INTERFACE_BAR,
- "Carrier IP interface registers");
- if (res) {
- dev_err(&tpci200->info->pdev->dev,
- "(bn 0x%X, sn 0x%X) failed to allocate PCI resource for BAR 2 !",
- tpci200->info->pdev->bus->number,
- tpci200->info->pdev->devfn);
- goto out_disable_pci;
- }
-
- /* Request IO ID INT space (Bar 3) */
- res = pci_request_region(tpci200->info->pdev,
- TPCI200_IO_ID_INT_SPACES_BAR,
- "Carrier IO ID INT space");
- if (res) {
- dev_err(&tpci200->info->pdev->dev,
- "(bn 0x%X, sn 0x%X) failed to allocate PCI resource for BAR 3 !",
- tpci200->info->pdev->bus->number,
- tpci200->info->pdev->devfn);
- goto out_release_ip_space;
- }
-
- /* Request MEM8 space (Bar 5) */
- res = pci_request_region(tpci200->info->pdev, TPCI200_MEM8_SPACE_BAR,
- "Carrier MEM8 space");
- if (res) {
- dev_err(&tpci200->info->pdev->dev,
- "(bn 0x%X, sn 0x%X) failed to allocate PCI resource for BAR 5!",
- tpci200->info->pdev->bus->number,
- tpci200->info->pdev->devfn);
- goto out_release_ioid_int_space;
- }
-
- /* Request MEM16 space (Bar 4) */
- res = pci_request_region(tpci200->info->pdev, TPCI200_MEM16_SPACE_BAR,
- "Carrier MEM16 space");
- if (res) {
- dev_err(&tpci200->info->pdev->dev,
- "(bn 0x%X, sn 0x%X) failed to allocate PCI resource for BAR 4!",
- tpci200->info->pdev->bus->number,
- tpci200->info->pdev->devfn);
- goto out_release_mem8_space;
- }
-
- /* Map internal tpci200 driver user space */
- tpci200->info->interface_regs =
- ioremap_nocache(pci_resource_start(tpci200->info->pdev,
- TPCI200_IP_INTERFACE_BAR),
- TPCI200_IFACE_SIZE);
-
- /* Initialize lock that protects interface_regs */
- spin_lock_init(&tpci200->regs_lock);
-
- ioidint_base = pci_resource_start(tpci200->info->pdev,
- TPCI200_IO_ID_INT_SPACES_BAR);
- tpci200->mod_mem[IPACK_IO_SPACE] = ioidint_base + TPCI200_IO_SPACE_OFF;
- tpci200->mod_mem[IPACK_ID_SPACE] = ioidint_base + TPCI200_ID_SPACE_OFF;
- tpci200->mod_mem[IPACK_INT_SPACE] =
- ioidint_base + TPCI200_INT_SPACE_OFF;
- tpci200->mod_mem[IPACK_MEM8_SPACE] =
- pci_resource_start(tpci200->info->pdev,
- TPCI200_MEM8_SPACE_BAR);
- tpci200->mod_mem[IPACK_MEM16_SPACE] =
- pci_resource_start(tpci200->info->pdev,
- TPCI200_MEM16_SPACE_BAR);
-
- /* Set the default parameters of the slot
- * INT0 disabled, level sensitive
- * INT1 disabled, level sensitive
- * error interrupt disabled
- * timeout interrupt disabled
- * recover time disabled
- * clock rate 8 MHz
- */
- slot_ctrl = 0;
- for (i = 0; i < TPCI200_NB_SLOT; i++)
- writew(slot_ctrl, &tpci200->info->interface_regs->control[i]);
-
- res = request_irq(tpci200->info->pdev->irq,
- tpci200_interrupt, IRQF_SHARED,
- KBUILD_MODNAME, (void *) tpci200);
- if (res) {
- dev_err(&tpci200->info->pdev->dev,
- "(bn 0x%X, sn 0x%X) unable to register IRQ !",
- tpci200->info->pdev->bus->number,
- tpci200->info->pdev->devfn);
- goto out_release_ioid_int_space;
- }
-
- return 0;
-
-out_release_mem8_space:
- pci_release_region(tpci200->info->pdev, TPCI200_MEM8_SPACE_BAR);
-out_release_ioid_int_space:
- pci_release_region(tpci200->info->pdev, TPCI200_IO_ID_INT_SPACES_BAR);
-out_release_ip_space:
- pci_release_region(tpci200->info->pdev, TPCI200_IP_INTERFACE_BAR);
-out_disable_pci:
- pci_disable_device(tpci200->info->pdev);
- return res;
-}
-
-static int tpci200_get_clockrate(struct ipack_device *dev)
-{
- struct tpci200_board *tpci200 = check_slot(dev);
- __le16 __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);
- __le16 __iomem *addr;
-
- if (!tpci200)
- return -ENODEV;
-
- addr = &tpci200->info->interface_regs->control[dev->slot];
-
- switch (mherz) {
- case 8:
- tpci200_clear_mask(tpci200, addr, TPCI200_CLK32);
- break;
- case 32:
- tpci200_set_mask(tpci200, addr, TPCI200_CLK32);
- break;
- default:
- return -EINVAL;
- }
- return 0;
-}
-
-static int tpci200_get_error(struct ipack_device *dev)
-{
- struct tpci200_board *tpci200 = check_slot(dev);
- __le16 __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);
- __le16 __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);
- __le16 __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)
-{
- tpci200_unregister(tpci200);
- kfree(tpci200->slots);
-}
-
-static const struct ipack_bus_ops tpci200_bus_ops = {
- .request_irq = tpci200_request_irq,
- .free_irq = tpci200_free_irq,
- .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)
-{
- int res;
-
- tpci200->slots = kzalloc(
- TPCI200_NB_SLOT * sizeof(struct tpci200_slot), GFP_KERNEL);
- if (tpci200->slots == NULL)
- return -ENOMEM;
-
- res = tpci200_register(tpci200);
- if (res) {
- kfree(tpci200->slots);
- tpci200->slots = NULL;
- return res;
- }
-
- mutex_init(&tpci200->mutex);
- return 0;
-}
-
-static void tpci200_release_device(struct ipack_device *dev)
-{
- kfree(dev);
-}
-
-static int tpci200_create_device(struct tpci200_board *tpci200, int i)
-{
- enum ipack_space space;
- struct ipack_device *dev =
- kzalloc(sizeof(struct ipack_device), GFP_KERNEL);
- if (!dev)
- return -ENOMEM;
- dev->slot = i;
- dev->bus = tpci200->info->ipack_bus;
- dev->release = tpci200_release_device;
-
- for (space = 0; space < IPACK_SPACE_COUNT; space++) {
- dev->region[space].start =
- tpci200->mod_mem[space]
- + tpci200_space_interval[space] * i;
- dev->region[space].size = tpci200_space_size[space];
- }
- return ipack_device_register(dev);
-}
-
-static int tpci200_pci_probe(struct pci_dev *pdev,
- const struct pci_device_id *id)
-{
- int ret, i;
- struct tpci200_board *tpci200;
- u32 reg32;
-
- tpci200 = kzalloc(sizeof(struct tpci200_board), GFP_KERNEL);
- if (!tpci200)
- return -ENOMEM;
-
- tpci200->info = kzalloc(sizeof(struct tpci200_infos), GFP_KERNEL);
- if (!tpci200->info) {
- ret = -ENOMEM;
- goto out_err_info;
- }
-
- pci_dev_get(pdev);
-
- /* Obtain a mapping of the carrier's PCI configuration registers */
- ret = pci_request_region(pdev, TPCI200_CFG_MEM_BAR,
- KBUILD_MODNAME " Configuration Memory");
- if (ret) {
- dev_err(&pdev->dev, "Failed to allocate PCI Configuration Memory");
- ret = -EBUSY;
- goto out_err_pci_request;
- }
- tpci200->info->cfg_regs = ioremap_nocache(
- pci_resource_start(pdev, TPCI200_CFG_MEM_BAR),
- pci_resource_len(pdev, TPCI200_CFG_MEM_BAR));
- if (!tpci200->info->cfg_regs) {
- dev_err(&pdev->dev, "Failed to map PCI Configuration Memory");
- ret = -EFAULT;
- goto out_err_ioremap;
- }
-
- /* Disable byte swapping for 16 bit IP module access. This will ensure
- * that the Industrypack big endian byte order is preserved by the
- * carrier. */
- reg32 = ioread32(tpci200->info->cfg_regs + LAS1_DESC);
- reg32 |= 1 << LAS_BIT_BIGENDIAN;
- iowrite32(reg32, tpci200->info->cfg_regs + LAS1_DESC);
-
- reg32 = ioread32(tpci200->info->cfg_regs + LAS2_DESC);
- reg32 |= 1 << LAS_BIT_BIGENDIAN;
- iowrite32(reg32, tpci200->info->cfg_regs + LAS2_DESC);
-
- /* Save struct pci_dev pointer */
- tpci200->info->pdev = pdev;
- tpci200->info->id_table = (struct pci_device_id *)id;
-
- /* register the device and initialize it */
- ret = tpci200_install(tpci200);
- if (ret) {
- dev_err(&pdev->dev, "error during tpci200 install\n");
- ret = -ENODEV;
- goto out_err_install;
- }
-
- /* Register the carrier in the industry pack bus driver */
- tpci200->info->ipack_bus = ipack_bus_register(&pdev->dev,
- TPCI200_NB_SLOT,
- &tpci200_bus_ops);
- if (!tpci200->info->ipack_bus) {
- dev_err(&pdev->dev,
- "error registering the carrier on ipack driver\n");
- ret = -EFAULT;
- goto out_err_bus_register;
- }
-
- /* save the bus number given by ipack to logging purpose */
- tpci200->number = tpci200->info->ipack_bus->bus_nr;
- dev_set_drvdata(&pdev->dev, tpci200);
-
- for (i = 0; i < TPCI200_NB_SLOT; i++)
- tpci200_create_device(tpci200, i);
- return 0;
-
-out_err_bus_register:
- tpci200_uninstall(tpci200);
-out_err_install:
- iounmap(tpci200->info->cfg_regs);
-out_err_ioremap:
- pci_release_region(pdev, TPCI200_CFG_MEM_BAR);
-out_err_pci_request:
- pci_dev_put(pdev);
- kfree(tpci200->info);
-out_err_info:
- kfree(tpci200);
- return ret;
-}
-
-static void __tpci200_pci_remove(struct tpci200_board *tpci200)
-{
- ipack_bus_unregister(tpci200->info->ipack_bus);
- tpci200_uninstall(tpci200);
-
- kfree(tpci200->info);
- kfree(tpci200);
-}
-
-static void __devexit tpci200_pci_remove(struct pci_dev *dev)
-{
- struct tpci200_board *tpci200 = pci_get_drvdata(dev);
-
- __tpci200_pci_remove(tpci200);
-}
-
-static DEFINE_PCI_DEVICE_TABLE(tpci200_idtable) = {
- { TPCI200_VENDOR_ID, TPCI200_DEVICE_ID, TPCI200_SUBVENDOR_ID,
- TPCI200_SUBDEVICE_ID },
- { 0, },
-};
-
-MODULE_DEVICE_TABLE(pci, tpci200_idtable);
-
-static struct pci_driver tpci200_pci_drv = {
- .name = "tpci200",
- .id_table = tpci200_idtable,
- .probe = tpci200_pci_probe,
- .remove = __devexit_p(tpci200_pci_remove),
-};
-
-static int __init tpci200_drvr_init_module(void)
-{
- return pci_register_driver(&tpci200_pci_drv);
-}
-
-static void __exit tpci200_drvr_exit_module(void)
-{
- pci_unregister_driver(&tpci200_pci_drv);
-}
-
-MODULE_DESCRIPTION("TEWS TPCI-200 device driver");
-MODULE_LICENSE("GPL");
-module_init(tpci200_drvr_init_module);
-module_exit(tpci200_drvr_exit_module);
diff --git a/drivers/staging/ipack/bridges/tpci200.h b/drivers/staging/ipack/bridges/tpci200.h
deleted file mode 100644
index 982f319..0000000
--- a/drivers/staging/ipack/bridges/tpci200.h
+++ /dev/null
@@ -1,167 +0,0 @@
-/**
- * tpci200.h
- *
- * driver for the carrier TEWS TPCI-200
- * Copyright (c) 2009 Nicolas Serafini, EIC2 SA
- * Copyright (c) 2010,2011 Samuel Iglesias Gonsalvez <siglesia@cern.ch>, CERN
- * Copyright (c) 2012 Samuel Iglesias Gonsalvez <siglesias@igalia.com>, Igalia
- *
- * 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; version 2 of the License.
- */
-
-#ifndef _TPCI200_H_
-#define _TPCI200_H_
-
-#include <linux/limits.h>
-#include <linux/pci.h>
-#include <linux/spinlock.h>
-#include <linux/swab.h>
-#include <linux/io.h>
-
-#include "../ipack.h"
-
-#define TPCI200_NB_SLOT 0x4
-#define TPCI200_NB_BAR 0x6
-
-#define TPCI200_VENDOR_ID 0x1498
-#define TPCI200_DEVICE_ID 0x30C8
-#define TPCI200_SUBVENDOR_ID 0x1498
-#define TPCI200_SUBDEVICE_ID 0x300A
-
-#define TPCI200_CFG_MEM_BAR 0
-#define TPCI200_IP_INTERFACE_BAR 2
-#define TPCI200_IO_ID_INT_SPACES_BAR 3
-#define TPCI200_MEM16_SPACE_BAR 4
-#define TPCI200_MEM8_SPACE_BAR 5
-
-struct tpci200_regs {
- __le16 revision;
- /* writes to control should occur with the mutex held to protect
- * read-modify-write operations */
- __le16 control[4];
- __le16 reset;
- __le16 status;
- u8 reserved[242];
-} __packed;
-
-#define TPCI200_IFACE_SIZE 0x100
-
-#define TPCI200_IO_SPACE_OFF 0x0000
-#define TPCI200_IO_SPACE_INTERVAL 0x0100
-#define TPCI200_IO_SPACE_SIZE 0x0080
-#define TPCI200_ID_SPACE_OFF 0x0080
-#define TPCI200_ID_SPACE_INTERVAL 0x0100
-#define TPCI200_ID_SPACE_SIZE 0x0040
-#define TPCI200_INT_SPACE_OFF 0x00C0
-#define TPCI200_INT_SPACE_INTERVAL 0x0100
-#define TPCI200_INT_SPACE_SIZE 0x0040
-#define TPCI200_IOIDINT_SIZE 0x0400
-
-#define TPCI200_MEM8_SPACE_INTERVAL 0x00400000
-#define TPCI200_MEM8_SPACE_SIZE 0x00400000
-#define TPCI200_MEM16_SPACE_INTERVAL 0x00800000
-#define TPCI200_MEM16_SPACE_SIZE 0x00800000
-
-/* control field in tpci200_regs */
-#define TPCI200_INT0_EN 0x0040
-#define TPCI200_INT1_EN 0x0080
-#define TPCI200_INT0_EDGE 0x0010
-#define TPCI200_INT1_EDGE 0x0020
-#define TPCI200_ERR_INT_EN 0x0008
-#define TPCI200_TIME_INT_EN 0x0004
-#define TPCI200_RECOVER_EN 0x0002
-#define TPCI200_CLK32 0x0001
-
-/* reset field in tpci200_regs */
-#define TPCI200_A_RESET 0x0001
-#define TPCI200_B_RESET 0x0002
-#define TPCI200_C_RESET 0x0004
-#define TPCI200_D_RESET 0x0008
-
-/* status field in tpci200_regs */
-#define TPCI200_A_TIMEOUT 0x1000
-#define TPCI200_B_TIMEOUT 0x2000
-#define TPCI200_C_TIMEOUT 0x4000
-#define TPCI200_D_TIMEOUT 0x8000
-
-#define TPCI200_A_ERROR 0x0100
-#define TPCI200_B_ERROR 0x0200
-#define TPCI200_C_ERROR 0x0400
-#define TPCI200_D_ERROR 0x0800
-
-#define TPCI200_A_INT0 0x0001
-#define TPCI200_A_INT1 0x0002
-#define TPCI200_B_INT0 0x0004
-#define TPCI200_B_INT1 0x0008
-#define TPCI200_C_INT0 0x0010
-#define TPCI200_C_INT1 0x0020
-#define TPCI200_D_INT0 0x0040
-#define TPCI200_D_INT1 0x0080
-
-#define TPCI200_SLOT_INT_MASK 0x00FF
-
-/* PCI Configuration registers. The PCI bridge is a PLX Technology PCI9030. */
-#define LAS1_DESC 0x2C
-#define LAS2_DESC 0x30
-
-/* Bits in the LAS?_DESC registers */
-#define LAS_BIT_BIGENDIAN 24
-
-#define VME_IOID_SPACE "IOID"
-#define VME_MEM_SPACE "MEM"
-
-/**
- * struct slot_irq - slot IRQ definition.
- * @vector Vector number
- * @handler Handler called when IRQ arrives
- * @arg Handler argument
- *
- */
-struct slot_irq {
- struct ipack_device *holder;
- int vector;
- irqreturn_t (*handler)(void *);
- void *arg;
-};
-
-/**
- * struct tpci200_slot - data specific to the tpci200 slot.
- * @slot_id Slot identification gived to external interface
- * @irq Slot IRQ infos
- * @io_phys IO physical base address register of the slot
- * @id_phys ID physical base address register of the slot
- * @int_phys INT physical base address register of the slot
- * @mem_phys MEM physical base address register of the slot
- *
- */
-struct tpci200_slot {
- struct slot_irq *irq;
-};
-
-/**
- * struct tpci200_infos - informations specific of the TPCI200 tpci200.
- * @pci_dev PCI device
- * @interface_regs Pointer to IP interface space (Bar 2)
- * @ioidint_space Pointer to IP ID, IO and INT space (Bar 3)
- * @mem8_space Pointer to MEM space (Bar 4)
- *
- */
-struct tpci200_infos {
- struct pci_dev *pdev;
- struct pci_device_id *id_table;
- struct tpci200_regs __iomem *interface_regs;
- void __iomem *cfg_regs;
- struct ipack_bus_device *ipack_bus;
-};
-struct tpci200_board {
- unsigned int number;
- struct mutex mutex;
- spinlock_t regs_lock;
- struct tpci200_slot *slots;
- struct tpci200_infos *info;
- phys_addr_t mod_mem[IPACK_SPACE_COUNT];
-};
-
-#endif /* _TPCI200_H_ */
diff --git a/drivers/staging/ipack/carriers/Kconfig b/drivers/staging/ipack/carriers/Kconfig
new file mode 100644
index 0000000..33fdc24
--- /dev/null
+++ b/drivers/staging/ipack/carriers/Kconfig
@@ -0,0 +1,7 @@
+config BOARD_TPCI200
+ tristate "TEWS TPCI-200 support for IndustryPack bus"
+ depends on IPACK_BUS
+ depends on PCI
+ help
+ This driver supports the TEWS TPCI200 device for the IndustryPack bus.
+ default n
diff --git a/drivers/staging/ipack/carriers/Makefile b/drivers/staging/ipack/carriers/Makefile
new file mode 100644
index 0000000..d8b7645
--- /dev/null
+++ b/drivers/staging/ipack/carriers/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_BOARD_TPCI200) += tpci200.o
diff --git a/drivers/staging/ipack/carriers/tpci200.c b/drivers/staging/ipack/carriers/tpci200.c
new file mode 100644
index 0000000..376e794
--- /dev/null
+++ b/drivers/staging/ipack/carriers/tpci200.c
@@ -0,0 +1,634 @@
+/**
+ * tpci200.c
+ *
+ * driver for the TEWS TPCI-200 device
+ * Copyright (c) 2009 Nicolas Serafini, EIC2 SA
+ * Copyright (c) 2010,2011 Samuel Iglesias Gonsalvez <siglesia@cern.ch>, CERN
+ * Copyright (c) 2012 Samuel Iglesias Gonsalvez <siglesias@igalia.com>, Igalia
+ *
+ * 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; version 2 of the License.
+ */
+
+#include <linux/module.h>
+#include "tpci200.h"
+
+static const u16 tpci200_status_timeout[] = {
+ TPCI200_A_TIMEOUT,
+ TPCI200_B_TIMEOUT,
+ TPCI200_C_TIMEOUT,
+ TPCI200_D_TIMEOUT,
+};
+
+static const u16 tpci200_status_error[] = {
+ TPCI200_A_ERROR,
+ TPCI200_B_ERROR,
+ TPCI200_C_ERROR,
+ TPCI200_D_ERROR,
+};
+
+static const size_t tpci200_space_size[IPACK_SPACE_COUNT] = {
+ [IPACK_IO_SPACE] = TPCI200_IO_SPACE_SIZE,
+ [IPACK_ID_SPACE] = TPCI200_ID_SPACE_SIZE,
+ [IPACK_INT_SPACE] = TPCI200_INT_SPACE_SIZE,
+ [IPACK_MEM8_SPACE] = TPCI200_MEM8_SPACE_SIZE,
+ [IPACK_MEM16_SPACE] = TPCI200_MEM16_SPACE_SIZE,
+};
+
+static const size_t tpci200_space_interval[IPACK_SPACE_COUNT] = {
+ [IPACK_IO_SPACE] = TPCI200_IO_SPACE_INTERVAL,
+ [IPACK_ID_SPACE] = TPCI200_ID_SPACE_INTERVAL,
+ [IPACK_INT_SPACE] = TPCI200_INT_SPACE_INTERVAL,
+ [IPACK_MEM8_SPACE] = TPCI200_MEM8_SPACE_INTERVAL,
+ [IPACK_MEM16_SPACE] = TPCI200_MEM16_SPACE_INTERVAL,
+};
+
+static struct tpci200_board *check_slot(struct ipack_device *dev)
+{
+ struct tpci200_board *tpci200;
+
+ if (dev == NULL)
+ return NULL;
+
+
+ tpci200 = dev_get_drvdata(dev->bus->parent);
+
+ if (tpci200 == NULL) {
+ dev_info(&dev->dev, "carrier board not found\n");
+ return NULL;
+ }
+
+ if (dev->slot >= TPCI200_NB_SLOT) {
+ dev_info(&dev->dev,
+ "Slot [%d:%d] doesn't exist! Last tpci200 slot is %d.\n",
+ dev->bus->bus_nr, dev->slot, TPCI200_NB_SLOT-1);
+ return NULL;
+ }
+
+ return tpci200;
+}
+
+static void tpci200_clear_mask(struct tpci200_board *tpci200,
+ __le16 __iomem *addr, u16 mask)
+{
+ unsigned long flags;
+ spin_lock_irqsave(&tpci200->regs_lock, flags);
+ iowrite16(ioread16(addr) & (~mask), addr);
+ spin_unlock_irqrestore(&tpci200->regs_lock, flags);
+}
+
+static void tpci200_set_mask(struct tpci200_board *tpci200,
+ __le16 __iomem *addr, u16 mask)
+{
+ unsigned long flags;
+ spin_lock_irqsave(&tpci200->regs_lock, flags);
+ iowrite16(ioread16(addr) | mask, addr);
+ spin_unlock_irqrestore(&tpci200->regs_lock, flags);
+}
+
+static void tpci200_unregister(struct tpci200_board *tpci200)
+{
+ free_irq(tpci200->info->pdev->irq, (void *) tpci200);
+
+ pci_iounmap(tpci200->info->pdev, tpci200->info->interface_regs);
+ pci_iounmap(tpci200->info->pdev, tpci200->info->cfg_regs);
+
+ pci_release_region(tpci200->info->pdev, TPCI200_IP_INTERFACE_BAR);
+ pci_release_region(tpci200->info->pdev, TPCI200_IO_ID_INT_SPACES_BAR);
+ pci_release_region(tpci200->info->pdev, TPCI200_MEM16_SPACE_BAR);
+ pci_release_region(tpci200->info->pdev, TPCI200_MEM8_SPACE_BAR);
+ pci_release_region(tpci200->info->pdev, TPCI200_CFG_MEM_BAR);
+
+ pci_disable_device(tpci200->info->pdev);
+ pci_dev_put(tpci200->info->pdev);
+}
+
+static void tpci200_enable_irq(struct tpci200_board *tpci200,
+ int islot)
+{
+ tpci200_set_mask(tpci200,
+ &tpci200->info->interface_regs->control[islot],
+ TPCI200_INT0_EN | TPCI200_INT1_EN);
+}
+
+static void tpci200_disable_irq(struct tpci200_board *tpci200,
+ int islot)
+{
+ tpci200_clear_mask(tpci200,
+ &tpci200->info->interface_regs->control[islot],
+ TPCI200_INT0_EN | TPCI200_INT1_EN);
+}
+
+static irqreturn_t tpci200_slot_irq(struct slot_irq *slot_irq)
+{
+ irqreturn_t ret;
+
+ if (!slot_irq)
+ return -ENODEV;
+ ret = slot_irq->handler(slot_irq->arg);
+
+ return ret;
+}
+
+static irqreturn_t tpci200_interrupt(int irq, void *dev_id)
+{
+ struct tpci200_board *tpci200 = (struct tpci200_board *) dev_id;
+ struct slot_irq *slot_irq;
+ irqreturn_t ret;
+ u16 status_reg;
+ int i;
+
+ /* Read status register */
+ status_reg = ioread16(&tpci200->info->interface_regs->status);
+
+ /* Did we cause the interrupt? */
+ if (!(status_reg & TPCI200_SLOT_INT_MASK))
+ return IRQ_NONE;
+
+ /* callback to the IRQ handler for the corresponding slot */
+ rcu_read_lock();
+ for (i = 0; i < TPCI200_NB_SLOT; i++) {
+ if (!(status_reg & ((TPCI200_A_INT0 | TPCI200_A_INT1) << (2 * i))))
+ continue;
+ slot_irq = rcu_dereference(tpci200->slots[i].irq);
+ ret = tpci200_slot_irq(slot_irq);
+ if (ret == -ENODEV) {
+ dev_info(&tpci200->info->pdev->dev,
+ "No registered ISR for slot [%d:%d]!. IRQ will be disabled.\n",
+ tpci200->number, i);
+ tpci200_disable_irq(tpci200, i);
+ }
+ }
+ rcu_read_unlock();
+
+ return IRQ_HANDLED;
+}
+
+static int tpci200_free_irq(struct ipack_device *dev)
+{
+ struct slot_irq *slot_irq;
+ struct tpci200_board *tpci200;
+
+ tpci200 = check_slot(dev);
+ if (tpci200 == NULL)
+ return -EINVAL;
+
+ if (mutex_lock_interruptible(&tpci200->mutex))
+ return -ERESTARTSYS;
+
+ if (tpci200->slots[dev->slot].irq == NULL) {
+ mutex_unlock(&tpci200->mutex);
+ return -EINVAL;
+ }
+
+ tpci200_disable_irq(tpci200, dev->slot);
+ slot_irq = tpci200->slots[dev->slot].irq;
+ /* uninstall handler */
+ RCU_INIT_POINTER(tpci200->slots[dev->slot].irq, NULL);
+ synchronize_rcu();
+ kfree(slot_irq);
+ mutex_unlock(&tpci200->mutex);
+ return 0;
+}
+
+static int tpci200_request_irq(struct ipack_device *dev,
+ irqreturn_t (*handler)(void *), void *arg)
+{
+ int res = 0;
+ struct slot_irq *slot_irq;
+ struct tpci200_board *tpci200;
+
+ tpci200 = check_slot(dev);
+ if (tpci200 == NULL)
+ return -EINVAL;
+
+ if (mutex_lock_interruptible(&tpci200->mutex))
+ return -ERESTARTSYS;
+
+ if (tpci200->slots[dev->slot].irq != NULL) {
+ dev_err(&dev->dev,
+ "Slot [%d:%d] IRQ already registered !\n", dev->bus->bus_nr,
+ dev->slot);
+ res = -EINVAL;
+ goto out_unlock;
+ }
+
+ slot_irq = kzalloc(sizeof(struct slot_irq), GFP_KERNEL);
+ if (slot_irq == NULL) {
+ dev_err(&dev->dev,
+ "Slot [%d:%d] unable to allocate memory for IRQ !\n",
+ dev->bus->bus_nr, dev->slot);
+ res = -ENOMEM;
+ goto out_unlock;
+ }
+
+ /*
+ * WARNING: Setup Interrupt Vector in the IndustryPack device
+ * before an IRQ request.
+ * Read the User Manual of your IndustryPack device to know
+ * where to write the vector in memory.
+ */
+ slot_irq->handler = handler;
+ slot_irq->arg = arg;
+ slot_irq->holder = dev;
+
+ rcu_assign_pointer(tpci200->slots[dev->slot].irq, slot_irq);
+ tpci200_enable_irq(tpci200, dev->slot);
+
+out_unlock:
+ mutex_unlock(&tpci200->mutex);
+ return res;
+}
+
+static int tpci200_register(struct tpci200_board *tpci200)
+{
+ int i;
+ int res;
+ phys_addr_t ioidint_base;
+ unsigned short slot_ctrl;
+
+ if (pci_enable_device(tpci200->info->pdev) < 0)
+ return -ENODEV;
+
+ /* Request IP interface register (Bar 2) */
+ res = pci_request_region(tpci200->info->pdev, TPCI200_IP_INTERFACE_BAR,
+ "Carrier IP interface registers");
+ if (res) {
+ dev_err(&tpci200->info->pdev->dev,
+ "(bn 0x%X, sn 0x%X) failed to allocate PCI resource for BAR 2 !",
+ tpci200->info->pdev->bus->number,
+ tpci200->info->pdev->devfn);
+ goto out_disable_pci;
+ }
+
+ /* Request IO ID INT space (Bar 3) */
+ res = pci_request_region(tpci200->info->pdev,
+ TPCI200_IO_ID_INT_SPACES_BAR,
+ "Carrier IO ID INT space");
+ if (res) {
+ dev_err(&tpci200->info->pdev->dev,
+ "(bn 0x%X, sn 0x%X) failed to allocate PCI resource for BAR 3 !",
+ tpci200->info->pdev->bus->number,
+ tpci200->info->pdev->devfn);
+ goto out_release_ip_space;
+ }
+
+ /* Request MEM8 space (Bar 5) */
+ res = pci_request_region(tpci200->info->pdev, TPCI200_MEM8_SPACE_BAR,
+ "Carrier MEM8 space");
+ if (res) {
+ dev_err(&tpci200->info->pdev->dev,
+ "(bn 0x%X, sn 0x%X) failed to allocate PCI resource for BAR 5!",
+ tpci200->info->pdev->bus->number,
+ tpci200->info->pdev->devfn);
+ goto out_release_ioid_int_space;
+ }
+
+ /* Request MEM16 space (Bar 4) */
+ res = pci_request_region(tpci200->info->pdev, TPCI200_MEM16_SPACE_BAR,
+ "Carrier MEM16 space");
+ if (res) {
+ dev_err(&tpci200->info->pdev->dev,
+ "(bn 0x%X, sn 0x%X) failed to allocate PCI resource for BAR 4!",
+ tpci200->info->pdev->bus->number,
+ tpci200->info->pdev->devfn);
+ goto out_release_mem8_space;
+ }
+
+ /* Map internal tpci200 driver user space */
+ tpci200->info->interface_regs =
+ ioremap_nocache(pci_resource_start(tpci200->info->pdev,
+ TPCI200_IP_INTERFACE_BAR),
+ TPCI200_IFACE_SIZE);
+
+ /* Initialize lock that protects interface_regs */
+ spin_lock_init(&tpci200->regs_lock);
+
+ ioidint_base = pci_resource_start(tpci200->info->pdev,
+ TPCI200_IO_ID_INT_SPACES_BAR);
+ tpci200->mod_mem[IPACK_IO_SPACE] = ioidint_base + TPCI200_IO_SPACE_OFF;
+ tpci200->mod_mem[IPACK_ID_SPACE] = ioidint_base + TPCI200_ID_SPACE_OFF;
+ tpci200->mod_mem[IPACK_INT_SPACE] =
+ ioidint_base + TPCI200_INT_SPACE_OFF;
+ tpci200->mod_mem[IPACK_MEM8_SPACE] =
+ pci_resource_start(tpci200->info->pdev,
+ TPCI200_MEM8_SPACE_BAR);
+ tpci200->mod_mem[IPACK_MEM16_SPACE] =
+ pci_resource_start(tpci200->info->pdev,
+ TPCI200_MEM16_SPACE_BAR);
+
+ /* Set the default parameters of the slot
+ * INT0 disabled, level sensitive
+ * INT1 disabled, level sensitive
+ * error interrupt disabled
+ * timeout interrupt disabled
+ * recover time disabled
+ * clock rate 8 MHz
+ */
+ slot_ctrl = 0;
+ for (i = 0; i < TPCI200_NB_SLOT; i++)
+ writew(slot_ctrl, &tpci200->info->interface_regs->control[i]);
+
+ res = request_irq(tpci200->info->pdev->irq,
+ tpci200_interrupt, IRQF_SHARED,
+ KBUILD_MODNAME, (void *) tpci200);
+ if (res) {
+ dev_err(&tpci200->info->pdev->dev,
+ "(bn 0x%X, sn 0x%X) unable to register IRQ !",
+ tpci200->info->pdev->bus->number,
+ tpci200->info->pdev->devfn);
+ goto out_release_ioid_int_space;
+ }
+
+ return 0;
+
+out_release_mem8_space:
+ pci_release_region(tpci200->info->pdev, TPCI200_MEM8_SPACE_BAR);
+out_release_ioid_int_space:
+ pci_release_region(tpci200->info->pdev, TPCI200_IO_ID_INT_SPACES_BAR);
+out_release_ip_space:
+ pci_release_region(tpci200->info->pdev, TPCI200_IP_INTERFACE_BAR);
+out_disable_pci:
+ pci_disable_device(tpci200->info->pdev);
+ return res;
+}
+
+static int tpci200_get_clockrate(struct ipack_device *dev)
+{
+ struct tpci200_board *tpci200 = check_slot(dev);
+ __le16 __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);
+ __le16 __iomem *addr;
+
+ if (!tpci200)
+ return -ENODEV;
+
+ addr = &tpci200->info->interface_regs->control[dev->slot];
+
+ switch (mherz) {
+ case 8:
+ tpci200_clear_mask(tpci200, addr, TPCI200_CLK32);
+ break;
+ case 32:
+ tpci200_set_mask(tpci200, addr, TPCI200_CLK32);
+ break;
+ default:
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static int tpci200_get_error(struct ipack_device *dev)
+{
+ struct tpci200_board *tpci200 = check_slot(dev);
+ __le16 __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);
+ __le16 __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);
+ __le16 __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)
+{
+ tpci200_unregister(tpci200);
+ kfree(tpci200->slots);
+}
+
+static const struct ipack_bus_ops tpci200_bus_ops = {
+ .request_irq = tpci200_request_irq,
+ .free_irq = tpci200_free_irq,
+ .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)
+{
+ int res;
+
+ tpci200->slots = kzalloc(
+ TPCI200_NB_SLOT * sizeof(struct tpci200_slot), GFP_KERNEL);
+ if (tpci200->slots == NULL)
+ return -ENOMEM;
+
+ res = tpci200_register(tpci200);
+ if (res) {
+ kfree(tpci200->slots);
+ tpci200->slots = NULL;
+ return res;
+ }
+
+ mutex_init(&tpci200->mutex);
+ return 0;
+}
+
+static void tpci200_release_device(struct ipack_device *dev)
+{
+ kfree(dev);
+}
+
+static int tpci200_create_device(struct tpci200_board *tpci200, int i)
+{
+ enum ipack_space space;
+ struct ipack_device *dev =
+ kzalloc(sizeof(struct ipack_device), GFP_KERNEL);
+ if (!dev)
+ return -ENOMEM;
+ dev->slot = i;
+ dev->bus = tpci200->info->ipack_bus;
+ dev->release = tpci200_release_device;
+
+ for (space = 0; space < IPACK_SPACE_COUNT; space++) {
+ dev->region[space].start =
+ tpci200->mod_mem[space]
+ + tpci200_space_interval[space] * i;
+ dev->region[space].size = tpci200_space_size[space];
+ }
+ return ipack_device_register(dev);
+}
+
+static int tpci200_pci_probe(struct pci_dev *pdev,
+ const struct pci_device_id *id)
+{
+ int ret, i;
+ struct tpci200_board *tpci200;
+ u32 reg32;
+
+ tpci200 = kzalloc(sizeof(struct tpci200_board), GFP_KERNEL);
+ if (!tpci200)
+ return -ENOMEM;
+
+ tpci200->info = kzalloc(sizeof(struct tpci200_infos), GFP_KERNEL);
+ if (!tpci200->info) {
+ ret = -ENOMEM;
+ goto out_err_info;
+ }
+
+ pci_dev_get(pdev);
+
+ /* Obtain a mapping of the carrier's PCI configuration registers */
+ ret = pci_request_region(pdev, TPCI200_CFG_MEM_BAR,
+ KBUILD_MODNAME " Configuration Memory");
+ if (ret) {
+ dev_err(&pdev->dev, "Failed to allocate PCI Configuration Memory");
+ ret = -EBUSY;
+ goto out_err_pci_request;
+ }
+ tpci200->info->cfg_regs = ioremap_nocache(
+ pci_resource_start(pdev, TPCI200_CFG_MEM_BAR),
+ pci_resource_len(pdev, TPCI200_CFG_MEM_BAR));
+ if (!tpci200->info->cfg_regs) {
+ dev_err(&pdev->dev, "Failed to map PCI Configuration Memory");
+ ret = -EFAULT;
+ goto out_err_ioremap;
+ }
+
+ /* Disable byte swapping for 16 bit IP module access. This will ensure
+ * that the Industrypack big endian byte order is preserved by the
+ * carrier. */
+ reg32 = ioread32(tpci200->info->cfg_regs + LAS1_DESC);
+ reg32 |= 1 << LAS_BIT_BIGENDIAN;
+ iowrite32(reg32, tpci200->info->cfg_regs + LAS1_DESC);
+
+ reg32 = ioread32(tpci200->info->cfg_regs + LAS2_DESC);
+ reg32 |= 1 << LAS_BIT_BIGENDIAN;
+ iowrite32(reg32, tpci200->info->cfg_regs + LAS2_DESC);
+
+ /* Save struct pci_dev pointer */
+ tpci200->info->pdev = pdev;
+ tpci200->info->id_table = (struct pci_device_id *)id;
+
+ /* register the device and initialize it */
+ ret = tpci200_install(tpci200);
+ if (ret) {
+ dev_err(&pdev->dev, "error during tpci200 install\n");
+ ret = -ENODEV;
+ goto out_err_install;
+ }
+
+ /* Register the carrier in the industry pack bus driver */
+ tpci200->info->ipack_bus = ipack_bus_register(&pdev->dev,
+ TPCI200_NB_SLOT,
+ &tpci200_bus_ops);
+ if (!tpci200->info->ipack_bus) {
+ dev_err(&pdev->dev,
+ "error registering the carrier on ipack driver\n");
+ ret = -EFAULT;
+ goto out_err_bus_register;
+ }
+
+ /* save the bus number given by ipack to logging purpose */
+ tpci200->number = tpci200->info->ipack_bus->bus_nr;
+ dev_set_drvdata(&pdev->dev, tpci200);
+
+ for (i = 0; i < TPCI200_NB_SLOT; i++)
+ tpci200_create_device(tpci200, i);
+ return 0;
+
+out_err_bus_register:
+ tpci200_uninstall(tpci200);
+out_err_install:
+ iounmap(tpci200->info->cfg_regs);
+out_err_ioremap:
+ pci_release_region(pdev, TPCI200_CFG_MEM_BAR);
+out_err_pci_request:
+ pci_dev_put(pdev);
+ kfree(tpci200->info);
+out_err_info:
+ kfree(tpci200);
+ return ret;
+}
+
+static void __tpci200_pci_remove(struct tpci200_board *tpci200)
+{
+ ipack_bus_unregister(tpci200->info->ipack_bus);
+ tpci200_uninstall(tpci200);
+
+ kfree(tpci200->info);
+ kfree(tpci200);
+}
+
+static void __devexit tpci200_pci_remove(struct pci_dev *dev)
+{
+ struct tpci200_board *tpci200 = pci_get_drvdata(dev);
+
+ __tpci200_pci_remove(tpci200);
+}
+
+static DEFINE_PCI_DEVICE_TABLE(tpci200_idtable) = {
+ { TPCI200_VENDOR_ID, TPCI200_DEVICE_ID, TPCI200_SUBVENDOR_ID,
+ TPCI200_SUBDEVICE_ID },
+ { 0, },
+};
+
+MODULE_DEVICE_TABLE(pci, tpci200_idtable);
+
+static struct pci_driver tpci200_pci_drv = {
+ .name = "tpci200",
+ .id_table = tpci200_idtable,
+ .probe = tpci200_pci_probe,
+ .remove = __devexit_p(tpci200_pci_remove),
+};
+
+static int __init tpci200_drvr_init_module(void)
+{
+ return pci_register_driver(&tpci200_pci_drv);
+}
+
+static void __exit tpci200_drvr_exit_module(void)
+{
+ pci_unregister_driver(&tpci200_pci_drv);
+}
+
+MODULE_DESCRIPTION("TEWS TPCI-200 device driver");
+MODULE_LICENSE("GPL");
+module_init(tpci200_drvr_init_module);
+module_exit(tpci200_drvr_exit_module);
diff --git a/drivers/staging/ipack/carriers/tpci200.h b/drivers/staging/ipack/carriers/tpci200.h
new file mode 100644
index 0000000..982f319
--- /dev/null
+++ b/drivers/staging/ipack/carriers/tpci200.h
@@ -0,0 +1,167 @@
+/**
+ * tpci200.h
+ *
+ * driver for the carrier TEWS TPCI-200
+ * Copyright (c) 2009 Nicolas Serafini, EIC2 SA
+ * Copyright (c) 2010,2011 Samuel Iglesias Gonsalvez <siglesia@cern.ch>, CERN
+ * Copyright (c) 2012 Samuel Iglesias Gonsalvez <siglesias@igalia.com>, Igalia
+ *
+ * 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; version 2 of the License.
+ */
+
+#ifndef _TPCI200_H_
+#define _TPCI200_H_
+
+#include <linux/limits.h>
+#include <linux/pci.h>
+#include <linux/spinlock.h>
+#include <linux/swab.h>
+#include <linux/io.h>
+
+#include "../ipack.h"
+
+#define TPCI200_NB_SLOT 0x4
+#define TPCI200_NB_BAR 0x6
+
+#define TPCI200_VENDOR_ID 0x1498
+#define TPCI200_DEVICE_ID 0x30C8
+#define TPCI200_SUBVENDOR_ID 0x1498
+#define TPCI200_SUBDEVICE_ID 0x300A
+
+#define TPCI200_CFG_MEM_BAR 0
+#define TPCI200_IP_INTERFACE_BAR 2
+#define TPCI200_IO_ID_INT_SPACES_BAR 3
+#define TPCI200_MEM16_SPACE_BAR 4
+#define TPCI200_MEM8_SPACE_BAR 5
+
+struct tpci200_regs {
+ __le16 revision;
+ /* writes to control should occur with the mutex held to protect
+ * read-modify-write operations */
+ __le16 control[4];
+ __le16 reset;
+ __le16 status;
+ u8 reserved[242];
+} __packed;
+
+#define TPCI200_IFACE_SIZE 0x100
+
+#define TPCI200_IO_SPACE_OFF 0x0000
+#define TPCI200_IO_SPACE_INTERVAL 0x0100
+#define TPCI200_IO_SPACE_SIZE 0x0080
+#define TPCI200_ID_SPACE_OFF 0x0080
+#define TPCI200_ID_SPACE_INTERVAL 0x0100
+#define TPCI200_ID_SPACE_SIZE 0x0040
+#define TPCI200_INT_SPACE_OFF 0x00C0
+#define TPCI200_INT_SPACE_INTERVAL 0x0100
+#define TPCI200_INT_SPACE_SIZE 0x0040
+#define TPCI200_IOIDINT_SIZE 0x0400
+
+#define TPCI200_MEM8_SPACE_INTERVAL 0x00400000
+#define TPCI200_MEM8_SPACE_SIZE 0x00400000
+#define TPCI200_MEM16_SPACE_INTERVAL 0x00800000
+#define TPCI200_MEM16_SPACE_SIZE 0x00800000
+
+/* control field in tpci200_regs */
+#define TPCI200_INT0_EN 0x0040
+#define TPCI200_INT1_EN 0x0080
+#define TPCI200_INT0_EDGE 0x0010
+#define TPCI200_INT1_EDGE 0x0020
+#define TPCI200_ERR_INT_EN 0x0008
+#define TPCI200_TIME_INT_EN 0x0004
+#define TPCI200_RECOVER_EN 0x0002
+#define TPCI200_CLK32 0x0001
+
+/* reset field in tpci200_regs */
+#define TPCI200_A_RESET 0x0001
+#define TPCI200_B_RESET 0x0002
+#define TPCI200_C_RESET 0x0004
+#define TPCI200_D_RESET 0x0008
+
+/* status field in tpci200_regs */
+#define TPCI200_A_TIMEOUT 0x1000
+#define TPCI200_B_TIMEOUT 0x2000
+#define TPCI200_C_TIMEOUT 0x4000
+#define TPCI200_D_TIMEOUT 0x8000
+
+#define TPCI200_A_ERROR 0x0100
+#define TPCI200_B_ERROR 0x0200
+#define TPCI200_C_ERROR 0x0400
+#define TPCI200_D_ERROR 0x0800
+
+#define TPCI200_A_INT0 0x0001
+#define TPCI200_A_INT1 0x0002
+#define TPCI200_B_INT0 0x0004
+#define TPCI200_B_INT1 0x0008
+#define TPCI200_C_INT0 0x0010
+#define TPCI200_C_INT1 0x0020
+#define TPCI200_D_INT0 0x0040
+#define TPCI200_D_INT1 0x0080
+
+#define TPCI200_SLOT_INT_MASK 0x00FF
+
+/* PCI Configuration registers. The PCI bridge is a PLX Technology PCI9030. */
+#define LAS1_DESC 0x2C
+#define LAS2_DESC 0x30
+
+/* Bits in the LAS?_DESC registers */
+#define LAS_BIT_BIGENDIAN 24
+
+#define VME_IOID_SPACE "IOID"
+#define VME_MEM_SPACE "MEM"
+
+/**
+ * struct slot_irq - slot IRQ definition.
+ * @vector Vector number
+ * @handler Handler called when IRQ arrives
+ * @arg Handler argument
+ *
+ */
+struct slot_irq {
+ struct ipack_device *holder;
+ int vector;
+ irqreturn_t (*handler)(void *);
+ void *arg;
+};
+
+/**
+ * struct tpci200_slot - data specific to the tpci200 slot.
+ * @slot_id Slot identification gived to external interface
+ * @irq Slot IRQ infos
+ * @io_phys IO physical base address register of the slot
+ * @id_phys ID physical base address register of the slot
+ * @int_phys INT physical base address register of the slot
+ * @mem_phys MEM physical base address register of the slot
+ *
+ */
+struct tpci200_slot {
+ struct slot_irq *irq;
+};
+
+/**
+ * struct tpci200_infos - informations specific of the TPCI200 tpci200.
+ * @pci_dev PCI device
+ * @interface_regs Pointer to IP interface space (Bar 2)
+ * @ioidint_space Pointer to IP ID, IO and INT space (Bar 3)
+ * @mem8_space Pointer to MEM space (Bar 4)
+ *
+ */
+struct tpci200_infos {
+ struct pci_dev *pdev;
+ struct pci_device_id *id_table;
+ struct tpci200_regs __iomem *interface_regs;
+ void __iomem *cfg_regs;
+ struct ipack_bus_device *ipack_bus;
+};
+struct tpci200_board {
+ unsigned int number;
+ struct mutex mutex;
+ spinlock_t regs_lock;
+ struct tpci200_slot *slots;
+ struct tpci200_infos *info;
+ phys_addr_t mod_mem[IPACK_SPACE_COUNT];
+};
+
+#endif /* _TPCI200_H_ */
--
1.7.10.4
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH 16/17] staging: ipack: Documentation cleanups.
2012-09-27 10:37 [PATCH 01/17] Staging: ipack: get rid of ipack_device->bus_nr Samuel Iglesias Gonsalvez
` (13 preceding siblings ...)
2012-09-27 10:37 ` [PATCH 15/17] staging: ipack: Rename bridges to carriers Samuel Iglesias Gonsalvez
@ 2012-09-27 10:37 ` Samuel Iglesias Gonsalvez
2012-09-27 10:37 ` [PATCH 17/17] Staging: ipack: fix wrong return value Samuel Iglesias Gonsalvez
15 siblings, 0 replies; 17+ messages in thread
From: Samuel Iglesias Gonsalvez @ 2012-09-27 10:37 UTC (permalink / raw)
To: Greg Kroah-Hartman
Cc: devel, linux-kernel, industrypack-devel, Jens Taprogge,
Samuel Iglesias Gonsalvez
From: Jens Taprogge <jens.taprogge@taprogge.org>
Signed-off-by: Jens Taprogge <jens.taprogge@taprogge.org>
Signed-off-by: Samuel Iglesias Gonsalvez <siglesias@igalia.com>
---
drivers/staging/ipack/Kconfig | 13 ++++++++-----
drivers/staging/ipack/carriers/Kconfig | 4 ++--
drivers/staging/ipack/ipack.h | 15 ++++++++-------
3 files changed, 18 insertions(+), 14 deletions(-)
diff --git a/drivers/staging/ipack/Kconfig b/drivers/staging/ipack/Kconfig
index 9b4495a..5cf43b3 100644
--- a/drivers/staging/ipack/Kconfig
+++ b/drivers/staging/ipack/Kconfig
@@ -6,11 +6,14 @@ menuconfig IPACK_BUS
tristate "IndustryPack bus support"
depends on HAS_IOMEM
---help---
- If you say Y here you get support for the IndustryPack Framework
- for drivers for many types of boards that support this industrial
- bus. The IndustryPack Framework is a virtual bus allowing to
- communicate between carrier and mezzanine cards connected through
- this bus.
+ This option provides support for the IndustryPack framework. There
+ are IndustryPack carrier boards, which interface another bus (such as
+ PCI) to an IndustryPack bus, and IndustryPack modules, that are
+ hosted on these buses. While IndustryPack modules can provide a
+ large variety of functionality, they are most often found in
+ industrial control applications.
+
+ Say N if unsure.
if IPACK_BUS
diff --git a/drivers/staging/ipack/carriers/Kconfig b/drivers/staging/ipack/carriers/Kconfig
index 33fdc24..922ff5c 100644
--- a/drivers/staging/ipack/carriers/Kconfig
+++ b/drivers/staging/ipack/carriers/Kconfig
@@ -1,7 +1,7 @@
config BOARD_TPCI200
- tristate "TEWS TPCI-200 support for IndustryPack bus"
+ tristate "Support for the TEWS TPCI-200 IndustryPack carrier board"
depends on IPACK_BUS
depends on PCI
help
- This driver supports the TEWS TPCI200 device for the IndustryPack bus.
+ This driver adds support for the TEWS TPCI200 IndustryPack carrier board.
default n
diff --git a/drivers/staging/ipack/ipack.h b/drivers/staging/ipack/ipack.h
index 689af92..7ca8789 100644
--- a/drivers/staging/ipack/ipack.h
+++ b/drivers/staging/ipack/ipack.h
@@ -80,10 +80,11 @@ struct ipack_device {
};
/**
- * struct ipack_driver_ops -- callbacks to mezzanine driver for installing/removing one device
+ * struct ipack_driver_ops -- Callbacks to IPack device driver
*
- * @probe: Probe function
- * @remove: tell the driver that the carrier board wants to remove one device
+ * @probe: Probe function
+ * @remove: Prepare imminent removal of the device. Services provided by the
+ * device should be revoked.
*/
struct ipack_driver_ops {
@@ -92,10 +93,10 @@ struct ipack_driver_ops {
};
/**
- * struct ipack_driver -- Specific data to each ipack board driver
+ * struct ipack_driver -- Specific data to each ipack device driver
*
- * @driver: Device driver kernel representation
- * @ops: Mezzanine driver operations specific for the ipack bus.
+ * @driver: Device driver kernel representation
+ * @ops: Callbacks provided by the IPack device driver
*/
struct ipack_driver {
struct device_driver driver;
@@ -165,7 +166,7 @@ struct ipack_bus_device *ipack_bus_register(struct device *parent, int slots,
int ipack_bus_unregister(struct ipack_bus_device *bus);
/**
- * ipack_driver_register -- Register a new driver
+ * ipack_driver_register -- Register a new ipack device driver
*
* Called by a ipack driver to register itself as a driver
* that can manage ipack devices.
--
1.7.10.4
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH 17/17] Staging: ipack: fix wrong return value.
2012-09-27 10:37 [PATCH 01/17] Staging: ipack: get rid of ipack_device->bus_nr Samuel Iglesias Gonsalvez
` (14 preceding siblings ...)
2012-09-27 10:37 ` [PATCH 16/17] staging: ipack: Documentation cleanups Samuel Iglesias Gonsalvez
@ 2012-09-27 10:37 ` Samuel Iglesias Gonsalvez
15 siblings, 0 replies; 17+ messages in thread
From: Samuel Iglesias Gonsalvez @ 2012-09-27 10:37 UTC (permalink / raw)
To: Greg Kroah-Hartman
Cc: devel, linux-kernel, industrypack-devel, Samuel Iglesias Gonsalvez
In case it is not possible to remap the memory, it returns 0 and
the driver thinks that everything went fine.
Signed-off-by: Samuel Iglesias Gonsalvez <siglesias@igalia.com>
---
drivers/staging/ipack/ipack.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/staging/ipack/ipack.c b/drivers/staging/ipack/ipack.c
index 5bd462b..75bfecf 100644
--- a/drivers/staging/ipack/ipack.c
+++ b/drivers/staging/ipack/ipack.c
@@ -355,7 +355,7 @@ static int ipack_device_read_id(struct ipack_device *dev)
dev->region[IPACK_ID_SPACE].size);
if (!idmem) {
dev_err(&dev->dev, "error mapping memory\n");
- return ret;
+ return -ENOMEM;
}
/* Determine ID PROM Data Format. If we find the ids "IPAC" or "IPAH"
--
1.7.10.4
^ permalink raw reply related [flat|nested] 17+ messages in thread
end of thread, other threads:[~2012-09-27 10:42 UTC | newest]
Thread overview: 17+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-09-27 10:37 [PATCH 01/17] Staging: ipack: get rid of ipack_device->bus_nr Samuel Iglesias Gonsalvez
2012-09-27 10:37 ` [PATCH 02/17] Staging: ipack: Make ipack_device_register() analogous to device_register() Samuel Iglesias Gonsalvez
2012-09-27 10:37 ` [PATCH 03/17] Staging: ipack/bridges/tpci200: Don't map memory spaces that are not used later on Samuel Iglesias Gonsalvez
2012-09-27 10:37 ` [PATCH 04/17] Staging: ipack/bridges/tpci200: change tpci200_slot->*_phys type Samuel Iglesias Gonsalvez
2012-09-27 10:37 ` [PATCH 05/17] Staging: ipack/bridges/tpci200: Store beginning of module memory regions in struct tpci200 Samuel Iglesias Gonsalvez
2012-09-27 10:37 ` [PATCH 06/17] Staging: ipack/bridges/tpci200: Cleanups Samuel Iglesias Gonsalvez
2012-09-27 10:37 ` [PATCH 07/17] Staging: ipack: Provide physical memory regions to IPack devices Samuel Iglesias Gonsalvez
2012-09-27 10:37 ` [PATCH 08/17] staging: ipack/devices/ipoctal: fix ipoctal_inst_slot error path Samuel Iglesias Gonsalvez
2012-09-27 10:37 ` [PATCH 09/17] staging: ipack/devices/ipoctal: obtain model from dev->id_device Samuel Iglesias Gonsalvez
2012-09-27 10:37 ` [PATCH 10/17] staging: ipack: swich to regular ioremap and friends Samuel Iglesias Gonsalvez
2012-09-27 10:37 ` [PATCH 11/17] Staging: ipack: remove memory mapping callbacks Samuel Iglesias Gonsalvez
2012-09-27 10:37 ` [PATCH 12/17] staging: ipack: Rename IPACK_MEM_SPACE to IPACK_MEM8_SPACE Samuel Iglesias Gonsalvez
2012-09-27 10:37 ` [PATCH 13/17] staging: ipack: Add support for IPACK_MEM16_SPACE Samuel Iglesias Gonsalvez
2012-09-27 10:37 ` [PATCH 14/17] Staging: ipack: remove blank line at EOF warning in Kconfig files Samuel Iglesias Gonsalvez
2012-09-27 10:37 ` [PATCH 15/17] staging: ipack: Rename bridges to carriers Samuel Iglesias Gonsalvez
2012-09-27 10:37 ` [PATCH 16/17] staging: ipack: Documentation cleanups Samuel Iglesias Gonsalvez
2012-09-27 10:37 ` [PATCH 17/17] Staging: ipack: fix wrong return value Samuel Iglesias Gonsalvez
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).