* [PATCH v2 01/20] Staging: ipack/bridges/tpci200: Put the TPCI200 control registers into a struct.
2012-09-11 11:34 [PATCH v2 00/20] ipack: added callbacks and some cleanup Samuel Iglesias Gonsálvez
@ 2012-09-11 11:34 ` Samuel Iglesias Gonsálvez
2012-09-11 11:34 ` [PATCH v2 02/20] Staging: ipack: Provide several carrier callbacks Samuel Iglesias Gonsálvez
` (19 subsequent siblings)
20 siblings, 0 replies; 22+ messages in thread
From: Samuel Iglesias Gonsálvez @ 2012-09-11 11:34 UTC (permalink / raw)
To: Greg Kroah-Hartman
Cc: devel, linux-kernel, industrypack-devel, Jens Taprogge,
Samuel Iglesias Gonsálvez
From: Jens Taprogge <jens.taprogge@taprogge.org>
This saves us from a little pointer arithmetic and cleans up the code a bit.
Signed-off-by: Jens Taprogge <jens.taprogge@taprogge.org>
Signed-off-by: Samuel Iglesias Gonsálvez <siglesias@igalia.com>
---
drivers/staging/ipack/bridges/tpci200.c | 28 +++++++---------------------
drivers/staging/ipack/bridges/tpci200.h | 21 +++++++++++++--------
2 files changed, 20 insertions(+), 29 deletions(-)
diff --git a/drivers/staging/ipack/bridges/tpci200.c b/drivers/staging/ipack/bridges/tpci200.c
index 302fc21..c88166d 100644
--- a/drivers/staging/ipack/bridges/tpci200.c
+++ b/drivers/staging/ipack/bridges/tpci200.c
@@ -14,14 +14,6 @@
#include <linux/module.h>
#include "tpci200.h"
-/* TPCI200 controls registers */
-static const int control_reg[] = {
- TPCI200_CONTROL_A_REG,
- TPCI200_CONTROL_B_REG,
- TPCI200_CONTROL_C_REG,
- TPCI200_CONTROL_D_REG
-};
-
static int tpci200_slot_unregister(struct ipack_device *dev);
static struct tpci200_board *check_slot(struct ipack_device *dev)
@@ -85,8 +77,7 @@ static irqreturn_t tpci200_interrupt(int irq, void *dev_id)
irqreturn_t ret = IRQ_NONE;
/* Read status register */
- status_reg = readw(tpci200->info->interface_regs +
- TPCI200_STATUS_REG);
+ status_reg = readw(&tpci200->info->interface_regs->status);
if (status_reg & TPCI200_SLOT_INT_MASK) {
unhandled_ints = status_reg & TPCI200_SLOT_INT_MASK;
@@ -107,7 +98,7 @@ static irqreturn_t tpci200_interrupt(int irq, void *dev_id)
}
}
}
- /* Interrupt not handled are disabled */
+ /* Interrupts not handled are disabled */
if (unhandled_ints) {
for (i = 0; i < TPCI200_NB_SLOT; i++) {
if (unhandled_ints & ((TPCI200_INT0_EN | TPCI200_INT1_EN) << (2*i))) {
@@ -115,13 +106,11 @@ static irqreturn_t tpci200_interrupt(int irq, void *dev_id)
"No registered ISR for slot [%d:%d]!. IRQ will be disabled.\n",
tpci200->number, i);
reg_value = readw(
- tpci200->info->interface_regs +
- control_reg[i]);
+ &tpci200->info->interface_regs->control[i]);
reg_value &=
~(TPCI200_INT0_EN | TPCI200_INT1_EN);
writew(reg_value,
- (tpci200->info->interface_regs +
- control_reg[i]));
+ &tpci200->info->interface_regs->control[i]);
}
}
}
@@ -219,8 +208,7 @@ static int tpci200_register(struct tpci200_board *tpci200)
(void __iomem *)mem_base + TPCI200_MEM8_GAP*i;
tpci200->slots[i].mem_phys.size = TPCI200_MEM8_SIZE;
- writew(slot_ctrl, (tpci200->info->interface_regs +
- control_reg[i]));
+ writew(slot_ctrl, &tpci200->info->interface_regs->control[i]);
}
res = request_irq(tpci200->info->pdev->irq,
@@ -259,8 +247,7 @@ static int __tpci200_request_irq(struct tpci200_board *tpci200,
* clock rate 8 MHz
*/
slot_ctrl = TPCI200_INT0_EN | TPCI200_INT1_EN;
- writew(slot_ctrl, (tpci200->info->interface_regs +
- control_reg[dev->slot]));
+ writew(slot_ctrl, &tpci200->info->interface_regs->control[dev->slot]);
return 0;
}
@@ -279,8 +266,7 @@ static void __tpci200_free_irq(struct tpci200_board *tpci200,
* clock rate 8 MHz
*/
slot_ctrl = 0;
- writew(slot_ctrl, (tpci200->info->interface_regs +
- control_reg[dev->slot]));
+ writew(slot_ctrl, &tpci200->info->interface_regs->control[dev->slot]);
}
static int tpci200_free_irq(struct ipack_device *dev)
diff --git a/drivers/staging/ipack/bridges/tpci200.h b/drivers/staging/ipack/bridges/tpci200.h
index 38acba1..867d696 100644
--- a/drivers/staging/ipack/bridges/tpci200.h
+++ b/drivers/staging/ipack/bridges/tpci200.h
@@ -37,13 +37,15 @@
#define TPCI200_MEM16_SPACE_BAR 4
#define TPCI200_MEM8_SPACE_BAR 5
-#define TPCI200_REVISION_REG 0x00
-#define TPCI200_CONTROL_A_REG 0x02
-#define TPCI200_CONTROL_B_REG 0x04
-#define TPCI200_CONTROL_C_REG 0x06
-#define TPCI200_CONTROL_D_REG 0x08
-#define TPCI200_RESET_REG 0x0A
-#define TPCI200_STATUS_REG 0x0C
+struct tpci200_regs {
+ u16 revision;
+ /* writes to control should occur with the mutex held to protect
+ * read-modify-write operations */
+ u16 control[4];
+ u16 reset;
+ u16 status;
+ u8 reserved[242];
+} __packed;
#define TPCI200_IFACE_SIZE 0x100
@@ -63,6 +65,7 @@
#define TPCI200_MEM16_GAP 0x00800000
#define TPCI200_MEM16_SIZE 0x00800000
+/* control field in tpci200_regs */
#define TPCI200_INT0_EN 0x0040
#define TPCI200_INT1_EN 0x0080
#define TPCI200_INT0_EDGE 0x0010
@@ -72,11 +75,13 @@
#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
@@ -149,7 +154,7 @@ struct tpci200_slot {
struct tpci200_infos {
struct pci_dev *pdev;
struct pci_device_id *id_table;
- void __iomem *interface_regs;
+ struct tpci200_regs __iomem *interface_regs;
void __iomem *ioidint_space;
void __iomem *mem8_space;
void __iomem *cfg_regs;
--
1.7.10.4
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH v2 02/20] Staging: ipack: Provide several carrier callbacks.
2012-09-11 11:34 [PATCH v2 00/20] ipack: added callbacks and some cleanup Samuel Iglesias Gonsálvez
2012-09-11 11:34 ` [PATCH v2 01/20] Staging: ipack/bridges/tpci200: Put the TPCI200 control registers into a struct Samuel Iglesias Gonsálvez
@ 2012-09-11 11:34 ` Samuel Iglesias Gonsálvez
2012-09-11 11:34 ` [PATCH v2 03/20] Staging: ipack/bridges/tpci200: provide new callbacks to tpci200 Samuel Iglesias Gonsálvez
` (18 subsequent siblings)
20 siblings, 0 replies; 22+ messages in thread
From: Samuel Iglesias Gonsálvez @ 2012-09-11 11:34 UTC (permalink / raw)
To: Greg Kroah-Hartman
Cc: devel, linux-kernel, industrypack-devel, Jens Taprogge,
Samuel Iglesias Gonsálvez
From: Jens Taprogge <jens.taprogge@taprogge.org>
We provide callbacks to:
- set/get the clockrate a module is accessed at,
- get the error state of a slot,
- get/reset the timeout state of a slot.
Signed-off-by: Jens Taprogge <jens.taprogge@taprogge.org>
Signed-off-by: Samuel Iglesias Gonsálvez <siglesias@igalia.com>
---
drivers/staging/ipack/ipack.h | 15 +++++++++++++++
1 file changed, 15 insertions(+)
diff --git a/drivers/staging/ipack/ipack.h b/drivers/staging/ipack/ipack.h
index 4d73f75..a133304 100644
--- a/drivers/staging/ipack/ipack.h
+++ b/drivers/staging/ipack/ipack.h
@@ -113,6 +113,15 @@ struct ipack_driver {
* @request_irq: request IRQ
* @free_irq: free IRQ
* @remove_device: tell the bridge module that the device has been removed
+ * @get_clockrate: Returns the clockrate the carrier is currently
+ * communicating with the device at.
+ * @set_clockrate: Sets the clock-rate for carrier / module communication.
+ * Should return -EINVAL if the requested speed is not supported.
+ * @get_error: Returns the error state for the slot the device is attached
+ * to.
+ * @get_timeout: Returns 1 if the communication with the device has
+ * previously timed out.
+ * @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);
@@ -120,6 +129,12 @@ struct ipack_bus_ops {
int (*request_irq) (struct ipack_device *dev, int vector, int (*handler)(void *), void *arg);
int (*free_irq) (struct ipack_device *dev);
int (*remove_device) (struct ipack_device *dev);
+
+ int (*get_clockrate) (struct ipack_device *dev);
+ int (*set_clockrate) (struct ipack_device *dev, int mherz);
+ int (*get_error) (struct ipack_device *dev);
+ int (*get_timeout) (struct ipack_device *dev);
+ int (*reset_timeout) (struct ipack_device *dev);
};
/**
--
1.7.10.4
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH v2 03/20] Staging: ipack/bridges/tpci200: provide new callbacks to tpci200
2012-09-11 11:34 [PATCH v2 00/20] ipack: added callbacks and some cleanup Samuel Iglesias Gonsálvez
2012-09-11 11:34 ` [PATCH v2 01/20] Staging: ipack/bridges/tpci200: Put the TPCI200 control registers into a struct Samuel Iglesias Gonsálvez
2012-09-11 11:34 ` [PATCH v2 02/20] Staging: ipack: Provide several carrier callbacks Samuel Iglesias Gonsálvez
@ 2012-09-11 11:34 ` Samuel Iglesias Gonsálvez
2012-09-11 11:34 ` [PATCH v2 04/20] Staging: ipack: Obtain supported speeds from ID ROM Samuel Iglesias Gonsálvez
` (17 subsequent siblings)
20 siblings, 0 replies; 22+ messages in thread
From: Samuel Iglesias Gonsálvez @ 2012-09-11 11:34 UTC (permalink / raw)
To: Greg Kroah-Hartman
Cc: devel, linux-kernel, industrypack-devel, Jens Taprogge,
Samuel Iglesias Gonsálvez
From: Jens Taprogge <jens.taprogge@taprogge.org>
Provide get_clockrate, set_clockrate, get_error, get_timeout and reset_timeout
callbacks.
Signed-off-by: Jens Taprogge <jens.taprogge@taprogge.org>
Signed-off-by: Samuel Iglesias Gonsálvez <siglesias@igalia.com>
---
drivers/staging/ipack/bridges/tpci200.c | 109 ++++++++++++++++++++++++++++++-
1 file changed, 108 insertions(+), 1 deletion(-)
diff --git a/drivers/staging/ipack/bridges/tpci200.c b/drivers/staging/ipack/bridges/tpci200.c
index c88166d..22e3da1 100644
--- a/drivers/staging/ipack/bridges/tpci200.c
+++ b/drivers/staging/ipack/bridges/tpci200.c
@@ -14,6 +14,20 @@
#include <linux/module.h>
#include "tpci200.h"
+static u16 tpci200_status_timeout[] = {
+ TPCI200_A_TIMEOUT,
+ TPCI200_B_TIMEOUT,
+ TPCI200_C_TIMEOUT,
+ TPCI200_D_TIMEOUT,
+};
+
+static u16 tpci200_status_error[] = {
+ TPCI200_A_ERROR,
+ TPCI200_B_ERROR,
+ TPCI200_C_ERROR,
+ TPCI200_D_ERROR,
+};
+
static int tpci200_slot_unregister(struct ipack_device *dev);
static struct tpci200_board *check_slot(struct ipack_device *dev)
@@ -505,6 +519,94 @@ out_unlock:
return res;
}
+static int tpci200_get_clockrate(struct ipack_device *dev)
+{
+ struct tpci200_board *tpci200 = check_slot(dev);
+ u16 __iomem *addr;
+
+ if (!tpci200)
+ return -ENODEV;
+
+ addr = &tpci200->info->interface_regs->control[dev->slot];
+ return (ioread16(addr) & TPCI200_CLK32) ? 32 : 8;
+}
+
+static int tpci200_set_clockrate(struct ipack_device *dev, int mherz)
+{
+ struct tpci200_board *tpci200 = check_slot(dev);
+ u16 __iomem *addr;
+ u16 reg;
+
+ if (!tpci200)
+ return -ENODEV;
+
+ addr = &tpci200->info->interface_regs->control[dev->slot];
+
+ /* Ensure the control register is not changed by another task after we
+ * have read it. */
+ mutex_lock(&tpci200->mutex);
+ reg = ioread16(addr);
+ switch (mherz) {
+ case 8:
+ reg &= ~(TPCI200_CLK32);
+ break;
+ case 32:
+ reg |= TPCI200_CLK32;
+ break;
+ default:
+ mutex_unlock(&tpci200->mutex);
+ return -EINVAL;
+ }
+ iowrite16(reg, addr);
+ mutex_unlock(&tpci200->mutex);
+ return 0;
+}
+
+static int tpci200_get_error(struct ipack_device *dev)
+{
+ struct tpci200_board *tpci200 = check_slot(dev);
+ u16 __iomem *addr;
+ u16 mask;
+
+ if (!tpci200)
+ return -ENODEV;
+
+ addr = &tpci200->info->interface_regs->status;
+ mask = tpci200_status_error[dev->slot];
+ return (ioread16(addr) & mask) ? 1 : 0;
+}
+
+static int tpci200_get_timeout(struct ipack_device *dev)
+{
+ struct tpci200_board *tpci200 = check_slot(dev);
+ u16 __iomem *addr;
+ u16 mask;
+
+ if (!tpci200)
+ return -ENODEV;
+
+ addr = &tpci200->info->interface_regs->status;
+ mask = tpci200_status_timeout[dev->slot];
+
+ return (ioread16(addr) & mask) ? 1 : 0;
+}
+
+static int tpci200_reset_timeout(struct ipack_device *dev)
+{
+ struct tpci200_board *tpci200 = check_slot(dev);
+ u16 __iomem *addr;
+ u16 mask;
+
+ if (!tpci200)
+ return -ENODEV;
+
+ addr = &tpci200->info->interface_regs->status;
+ mask = tpci200_status_timeout[dev->slot];
+
+ iowrite16(mask, addr);
+ return 0;
+}
+
static void tpci200_uninstall(struct tpci200_board *tpci200)
{
int i;
@@ -522,6 +624,11 @@ static const struct ipack_bus_ops tpci200_bus_ops = {
.request_irq = tpci200_request_irq,
.free_irq = tpci200_free_irq,
.remove_device = tpci200_slot_unregister,
+ .get_clockrate = tpci200_get_clockrate,
+ .set_clockrate = tpci200_set_clockrate,
+ .get_error = tpci200_get_error,
+ .get_timeout = tpci200_get_timeout,
+ .reset_timeout = tpci200_reset_timeout,
};
static int tpci200_install(struct tpci200_board *tpci200)
@@ -549,7 +656,7 @@ static int tpci200_pci_probe(struct pci_dev *pdev,
{
int ret, i;
struct tpci200_board *tpci200;
- __le32 reg32;
+ u32 reg32;
tpci200 = kzalloc(sizeof(struct tpci200_board), GFP_KERNEL);
if (!tpci200)
--
1.7.10.4
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH v2 04/20] Staging: ipack: Obtain supported speeds from ID ROM.
2012-09-11 11:34 [PATCH v2 00/20] ipack: added callbacks and some cleanup Samuel Iglesias Gonsálvez
` (2 preceding siblings ...)
2012-09-11 11:34 ` [PATCH v2 03/20] Staging: ipack/bridges/tpci200: provide new callbacks to tpci200 Samuel Iglesias Gonsálvez
@ 2012-09-11 11:34 ` Samuel Iglesias Gonsálvez
2012-09-11 11:34 ` [PATCH v2 05/20] Staging: ipack: Choose the optimum bus speed by default Samuel Iglesias Gonsálvez
` (16 subsequent siblings)
20 siblings, 0 replies; 22+ messages in thread
From: Samuel Iglesias Gonsálvez @ 2012-09-11 11:34 UTC (permalink / raw)
To: Greg Kroah-Hartman
Cc: devel, linux-kernel, industrypack-devel, Jens Taprogge,
Samuel Iglesias Gonsálvez
From: Jens Taprogge <jens.taprogge@taprogge.org>
Signed-off-by: Jens Taprogge <jens.taprogge@taprogge.org>
Signed-off-by: Samuel Iglesias Gonsálvez <siglesias@igalia.com>
---
drivers/staging/ipack/ipack.c | 6 ++++++
drivers/staging/ipack/ipack.h | 2 ++
2 files changed, 8 insertions(+)
diff --git a/drivers/staging/ipack/ipack.c b/drivers/staging/ipack/ipack.c
index af47772..c36ba9e 100644
--- a/drivers/staging/ipack/ipack.c
+++ b/drivers/staging/ipack/ipack.c
@@ -262,15 +262,21 @@ static void ipack_parse_id1(struct ipack_device *dev)
dev->id_vendor = id[4];
dev->id_device = id[5];
+ dev->speed_8mhz = 1;
+ dev->speed_32mhz = (id[7] == 'H');
}
static void ipack_parse_id2(struct ipack_device *dev)
{
__be16 *id = (__be16 *) dev->id;
+ u16 flags;
dev->id_vendor = ((be16_to_cpu(id[3]) & 0xff) << 16)
+ be16_to_cpu(id[4]);
dev->id_device = be16_to_cpu(id[5]);
+ flags = be16_to_cpu(id[10]);
+ dev->speed_8mhz = !!(flags & 2);
+ dev->speed_32mhz = !!(flags & 4);
}
static int ipack_device_read_id(struct ipack_device *dev)
diff --git a/drivers/staging/ipack/ipack.h b/drivers/staging/ipack/ipack.h
index a133304..89af9e4 100644
--- a/drivers/staging/ipack/ipack.h
+++ b/drivers/staging/ipack/ipack.h
@@ -79,6 +79,8 @@ struct ipack_device {
u32 id_vendor;
u32 id_device;
u8 id_format;
+ unsigned int speed_8mhz:1;
+ unsigned int speed_32mhz:1;
};
/**
--
1.7.10.4
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH v2 05/20] Staging: ipack: Choose the optimum bus speed by default.
2012-09-11 11:34 [PATCH v2 00/20] ipack: added callbacks and some cleanup Samuel Iglesias Gonsálvez
` (3 preceding siblings ...)
2012-09-11 11:34 ` [PATCH v2 04/20] Staging: ipack: Obtain supported speeds from ID ROM Samuel Iglesias Gonsálvez
@ 2012-09-11 11:34 ` Samuel Iglesias Gonsálvez
2012-09-11 11:34 ` [PATCH v2 06/20] Staging: ipack: remove field driver from struct ipack_device Samuel Iglesias Gonsálvez
` (15 subsequent siblings)
20 siblings, 0 replies; 22+ messages in thread
From: Samuel Iglesias Gonsálvez @ 2012-09-11 11:34 UTC (permalink / raw)
To: Greg Kroah-Hartman
Cc: devel, linux-kernel, industrypack-devel, Jens Taprogge,
Samuel Iglesias Gonsálvez
From: Jens Taprogge <jens.taprogge@taprogge.org>
Signed-off-by: Jens Taprogge <jens.taprogge@taprogge.org>
Signed-off-by: Samuel Iglesias Gonsálvez <siglesias@igalia.com>
---
drivers/staging/ipack/ipack.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/drivers/staging/ipack/ipack.c b/drivers/staging/ipack/ipack.c
index c36ba9e..1ad73e5 100644
--- a/drivers/staging/ipack/ipack.c
+++ b/drivers/staging/ipack/ipack.c
@@ -387,6 +387,11 @@ struct ipack_device *ipack_device_register(struct ipack_bus_device *bus,
return NULL;
}
+ /* if the device supports 32 MHz operation, use it. */
+ ret = bus->ops->set_clockrate(dev, dev->speed_32mhz ? 32 : 8);
+ if (ret < 0)
+ dev_err(&dev->dev, "failed to perform set_clock_rate operation.\n");
+
ret = device_register(&dev->dev);
if (ret < 0) {
kfree(dev->id);
--
1.7.10.4
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH v2 06/20] Staging: ipack: remove field driver from struct ipack_device.
2012-09-11 11:34 [PATCH v2 00/20] ipack: added callbacks and some cleanup Samuel Iglesias Gonsálvez
` (4 preceding siblings ...)
2012-09-11 11:34 ` [PATCH v2 05/20] Staging: ipack: Choose the optimum bus speed by default Samuel Iglesias Gonsálvez
@ 2012-09-11 11:34 ` Samuel Iglesias Gonsálvez
2012-09-11 11:35 ` [PATCH v2 07/20] Staging: ipack/bridges/tpci200: remove struct list_head Samuel Iglesias Gonsálvez
` (14 subsequent siblings)
20 siblings, 0 replies; 22+ messages in thread
From: Samuel Iglesias Gonsálvez @ 2012-09-11 11:34 UTC (permalink / raw)
To: Greg Kroah-Hartman
Cc: devel, linux-kernel, industrypack-devel, Jens Taprogge,
Samuel Iglesias Gonsálvez
From: Jens Taprogge <jens.taprogge@taprogge.org>
After a successful match is found the driver field in struct device is
set by the core device code. We can use this field.
Signed-off-by: Jens Taprogge <jens.taprogge@taprogge.org>
Signed-off-by: Samuel Iglesias Gonsálvez <siglesias@igalia.com>
---
drivers/staging/ipack/ipack.c | 17 +++++++----------
drivers/staging/ipack/ipack.h | 2 --
2 files changed, 7 insertions(+), 12 deletions(-)
diff --git a/drivers/staging/ipack/ipack.c b/drivers/staging/ipack/ipack.c
index 1ad73e5..6895426 100644
--- a/drivers/staging/ipack/ipack.c
+++ b/drivers/staging/ipack/ipack.c
@@ -59,32 +59,29 @@ static int ipack_bus_match(struct device *dev, struct device_driver *drv)
const struct ipack_device_id *found_id;
found_id = ipack_match_id(idrv->id_table, idev);
- if (found_id) {
- idev->driver = idrv;
- return 1;
- }
-
- return 0;
+ return found_id ? 1 : 0;
}
static int ipack_bus_probe(struct device *device)
{
struct ipack_device *dev = to_ipack_dev(device);
+ struct ipack_driver *drv = to_ipack_driver(device->driver);
- if (!dev->driver->ops->probe)
+ if (!drv->ops->probe)
return -EINVAL;
- return dev->driver->ops->probe(dev);
+ return drv->ops->probe(dev);
}
static int ipack_bus_remove(struct device *device)
{
struct ipack_device *dev = to_ipack_dev(device);
+ struct ipack_driver *drv = to_ipack_driver(device->driver);
- if (!dev->driver->ops->remove)
+ if (!drv->ops->remove)
return -EINVAL;
- dev->driver->ops->remove(dev);
+ drv->ops->remove(dev);
return 0;
}
diff --git a/drivers/staging/ipack/ipack.h b/drivers/staging/ipack/ipack.h
index 89af9e4..ad4c3bf 100644
--- a/drivers/staging/ipack/ipack.h
+++ b/drivers/staging/ipack/ipack.h
@@ -53,7 +53,6 @@ struct ipack_addr_space {
* @bus_nr: IP bus number where the device is plugged
* @slot: Slot where the device is plugged in the carrier board
* @irq: IRQ vector
- * @driver: Pointer to the ipack_driver that manages the device
* @bus: ipack_bus_device where the device is plugged to.
* @id_space: Virtual address to ID space.
* @io_space: Virtual address to IO space.
@@ -68,7 +67,6 @@ struct ipack_device {
unsigned int bus_nr;
unsigned int slot;
unsigned int irq;
- struct ipack_driver *driver;
struct ipack_bus_device *bus;
struct ipack_addr_space id_space;
struct ipack_addr_space io_space;
--
1.7.10.4
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH v2 07/20] Staging: ipack/bridges/tpci200: remove struct list_head
2012-09-11 11:34 [PATCH v2 00/20] ipack: added callbacks and some cleanup Samuel Iglesias Gonsálvez
` (5 preceding siblings ...)
2012-09-11 11:34 ` [PATCH v2 06/20] Staging: ipack: remove field driver from struct ipack_device Samuel Iglesias Gonsálvez
@ 2012-09-11 11:35 ` Samuel Iglesias Gonsálvez
2012-09-11 11:35 ` [PATCH v2 08/20] Staging: ipack: Switch to 8MHz operation before reading ID Samuel Iglesias Gonsálvez
` (13 subsequent siblings)
20 siblings, 0 replies; 22+ messages in thread
From: Samuel Iglesias Gonsálvez @ 2012-09-11 11:35 UTC (permalink / raw)
To: Greg Kroah-Hartman
Cc: devel, linux-kernel, industrypack-devel, Samuel Iglesias Gonsálvez
As the linked list was removed before, delete the useless struct list_head
Signed-off-by: Samuel Iglesias Gonsálvez <siglesias@igalia.com>
---
drivers/staging/ipack/bridges/tpci200.h | 1 -
1 file changed, 1 deletion(-)
diff --git a/drivers/staging/ipack/bridges/tpci200.h b/drivers/staging/ipack/bridges/tpci200.h
index 867d696..fc90a94 100644
--- a/drivers/staging/ipack/bridges/tpci200.h
+++ b/drivers/staging/ipack/bridges/tpci200.h
@@ -161,7 +161,6 @@ struct tpci200_infos {
struct ipack_bus_device *ipack_bus;
};
struct tpci200_board {
- struct list_head list;
unsigned int number;
struct mutex mutex;
struct tpci200_slot *slots;
--
1.7.10.4
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH v2 08/20] Staging: ipack: Switch to 8MHz operation before reading ID.
2012-09-11 11:34 [PATCH v2 00/20] ipack: added callbacks and some cleanup Samuel Iglesias Gonsálvez
` (6 preceding siblings ...)
2012-09-11 11:35 ` [PATCH v2 07/20] Staging: ipack/bridges/tpci200: remove struct list_head Samuel Iglesias Gonsálvez
@ 2012-09-11 11:35 ` Samuel Iglesias Gonsálvez
2012-09-11 11:35 ` [PATCH v2 09/20] Staging: ipack: reset previous timeouts during device registration Samuel Iglesias Gonsálvez
` (12 subsequent siblings)
20 siblings, 0 replies; 22+ messages in thread
From: Samuel Iglesias Gonsálvez @ 2012-09-11 11:35 UTC (permalink / raw)
To: Greg Kroah-Hartman
Cc: devel, linux-kernel, industrypack-devel, Jens Taprogge,
Samuel Iglesias Gonsálvez
From: Jens Taprogge <jens.taprogge@taprogge.org>
Reading the ID space at 8 MHz is always supported. Most carriers will
boot up in 8MHz mode. Still, play it safe and ensure we are operating at
8Mhz.
Signed-off-by: Jens Taprogge <jens.taprogge@taprogge.org>
Signed-off-by: Samuel Iglesias Gonsálvez <siglesias@igalia.com>
---
drivers/staging/ipack/ipack.c | 11 ++++++++---
1 file changed, 8 insertions(+), 3 deletions(-)
diff --git a/drivers/staging/ipack/ipack.c b/drivers/staging/ipack/ipack.c
index 6895426..e2f819c 100644
--- a/drivers/staging/ipack/ipack.c
+++ b/drivers/staging/ipack/ipack.c
@@ -377,6 +377,9 @@ struct ipack_device *ipack_device_register(struct ipack_bus_device *bus,
dev_set_name(&dev->dev,
"ipack-dev.%u.%u", dev->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");
+
ret = ipack_device_read_id(dev);
if (ret < 0) {
dev_err(&dev->dev, "error reading device id section.\n");
@@ -385,9 +388,11 @@ struct ipack_device *ipack_device_register(struct ipack_bus_device *bus,
}
/* if the device supports 32 MHz operation, use it. */
- ret = bus->ops->set_clockrate(dev, dev->speed_32mhz ? 32 : 8);
- if (ret < 0)
- dev_err(&dev->dev, "failed to perform set_clock_rate operation.\n");
+ if (dev->speed_32mhz) {
+ ret = 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) {
--
1.7.10.4
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH v2 09/20] Staging: ipack: reset previous timeouts during device registration.
2012-09-11 11:34 [PATCH v2 00/20] ipack: added callbacks and some cleanup Samuel Iglesias Gonsálvez
` (7 preceding siblings ...)
2012-09-11 11:35 ` [PATCH v2 08/20] Staging: ipack: Switch to 8MHz operation before reading ID Samuel Iglesias Gonsálvez
@ 2012-09-11 11:35 ` Samuel Iglesias Gonsálvez
2012-09-11 11:35 ` [PATCH v2 10/20] Staging: ipack: check the device ID space CRC Samuel Iglesias Gonsálvez
` (11 subsequent siblings)
20 siblings, 0 replies; 22+ messages in thread
From: Samuel Iglesias Gonsálvez @ 2012-09-11 11:35 UTC (permalink / raw)
To: Greg Kroah-Hartman
Cc: devel, linux-kernel, industrypack-devel, Jens Taprogge,
Samuel Iglesias Gonsálvez
From: Jens Taprogge <jens.taprogge@taprogge.org>
Resetting the previous timeout we avoid to read the timeout status register
and see timeout errors that don't correspond to the present state of the
device.
Signed-off-by: Jens Taprogge <jens.taprogge@taprogge.org>
Signed-off-by: Samuel Iglesias Gonsálvez <siglesias@igalia.com>
---
drivers/staging/ipack/ipack.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/staging/ipack/ipack.c b/drivers/staging/ipack/ipack.c
index e2f819c..08b122d 100644
--- a/drivers/staging/ipack/ipack.c
+++ b/drivers/staging/ipack/ipack.c
@@ -379,6 +379,8 @@ struct ipack_device *ipack_device_register(struct ipack_bus_device *bus,
if (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))
+ dev_warn(&dev->dev, "failed to reset potential timeout.");
ret = ipack_device_read_id(dev);
if (ret < 0) {
--
1.7.10.4
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH v2 10/20] Staging: ipack: check the device ID space CRC.
2012-09-11 11:34 [PATCH v2 00/20] ipack: added callbacks and some cleanup Samuel Iglesias Gonsálvez
` (8 preceding siblings ...)
2012-09-11 11:35 ` [PATCH v2 09/20] Staging: ipack: reset previous timeouts during device registration Samuel Iglesias Gonsálvez
@ 2012-09-11 11:35 ` Samuel Iglesias Gonsálvez
2012-09-11 11:35 ` [PATCH v2 11/20] Staging: ipack/bridges/tpci200: reorder the iounmap and pci_release_region Samuel Iglesias Gonsálvez
` (10 subsequent siblings)
20 siblings, 0 replies; 22+ messages in thread
From: Samuel Iglesias Gonsálvez @ 2012-09-11 11:35 UTC (permalink / raw)
To: Greg Kroah-Hartman
Cc: devel, linux-kernel, industrypack-devel, Jens Taprogge,
Samuel Iglesias Gonsálvez
From: Jens Taprogge <jens.taprogge@taprogge.org>
We check the CRC and store the result of the check in struct ipac_device.
A warning is emitted if the check fails. However we leave it to the
IPack module device to refuse to initialize due to a bad CRC. I have seen
otherwise good modules with bad CRCs.
Signed-off-by: Jens Taprogge <jens.taprogge@taprogge.org>
Signed-off-by: Samuel Iglesias Gonsálvez <siglesias@igalia.com>
---
drivers/staging/ipack/ipack.c | 59 ++++++++++++++++++++++++++++++++++++++++-
drivers/staging/ipack/ipack.h | 1 +
2 files changed, 59 insertions(+), 1 deletion(-)
diff --git a/drivers/staging/ipack/ipack.c b/drivers/staging/ipack/ipack.c
index 08b122d..26dc976 100644
--- a/drivers/staging/ipack/ipack.c
+++ b/drivers/staging/ipack/ipack.c
@@ -253,20 +253,71 @@ void ipack_driver_unregister(struct ipack_driver *edrv)
}
EXPORT_SYMBOL_GPL(ipack_driver_unregister);
+static u16 ipack_crc_byte(u16 crc, u8 c)
+{
+ int i;
+
+ crc ^= c << 8;
+ for (i = 0; i < 8; i++)
+ crc = (crc << 1) ^ ((crc & 0x8000) ? 0x1021 : 0);
+ return crc;
+}
+
+/*
+ * The algorithm in lib/crc-ccitt.c does not seem to apply since it uses the
+ * opposite bit ordering.
+ */
+static u8 ipack_calc_crc1(struct ipack_device *dev)
+{
+ u8 c;
+ u16 crc;
+ unsigned int i;
+
+ crc = 0xffff;
+ for (i = 0; i < dev->id_avail; i++) {
+ c = (i != 11) ? dev->id[i] : 0;
+ crc = ipack_crc_byte(crc, c);
+ }
+ crc = ~crc;
+ return crc & 0xff;
+}
+
+static u16 ipack_calc_crc2(struct ipack_device *dev)
+{
+ u8 c;
+ u16 crc;
+ unsigned int i;
+
+ crc = 0xffff;
+ for (i = 0; i < dev->id_avail; i++) {
+ c = ((i != 0x18) && (i != 0x19)) ? dev->id[i] : 0;
+ crc = ipack_crc_byte(crc, c);
+ }
+ crc = ~crc;
+ return crc;
+}
+
static void ipack_parse_id1(struct ipack_device *dev)
{
u8 *id = dev->id;
+ u8 crc;
dev->id_vendor = id[4];
dev->id_device = id[5];
dev->speed_8mhz = 1;
dev->speed_32mhz = (id[7] == 'H');
+ crc = ipack_calc_crc1(dev);
+ dev->id_crc_correct = (crc == id[11]);
+ if (!dev->id_crc_correct) {
+ dev_warn(&dev->dev, "ID CRC invalid found 0x%x, expected 0x%x.\n",
+ id[11], crc);
+ }
}
static void ipack_parse_id2(struct ipack_device *dev)
{
__be16 *id = (__be16 *) dev->id;
- u16 flags;
+ u16 flags, crc;
dev->id_vendor = ((be16_to_cpu(id[3]) & 0xff) << 16)
+ be16_to_cpu(id[4]);
@@ -274,6 +325,12 @@ static void ipack_parse_id2(struct ipack_device *dev)
flags = be16_to_cpu(id[10]);
dev->speed_8mhz = !!(flags & 2);
dev->speed_32mhz = !!(flags & 4);
+ crc = ipack_calc_crc2(dev);
+ dev->id_crc_correct = (crc == be16_to_cpu(id[12]));
+ if (!dev->id_crc_correct) {
+ dev_warn(&dev->dev, "ID CRC invalid found 0x%x, expected 0x%x.\n",
+ id[11], crc);
+ }
}
static int ipack_device_read_id(struct ipack_device *dev)
diff --git a/drivers/staging/ipack/ipack.h b/drivers/staging/ipack/ipack.h
index ad4c3bf..77d8075 100644
--- a/drivers/staging/ipack/ipack.h
+++ b/drivers/staging/ipack/ipack.h
@@ -77,6 +77,7 @@ struct ipack_device {
u32 id_vendor;
u32 id_device;
u8 id_format;
+ unsigned int id_crc_correct:1;
unsigned int speed_8mhz:1;
unsigned int speed_32mhz:1;
};
--
1.7.10.4
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH v2 11/20] Staging: ipack/bridges/tpci200: reorder the iounmap and pci_release_region
2012-09-11 11:34 [PATCH v2 00/20] ipack: added callbacks and some cleanup Samuel Iglesias Gonsálvez
` (9 preceding siblings ...)
2012-09-11 11:35 ` [PATCH v2 10/20] Staging: ipack: check the device ID space CRC Samuel Iglesias Gonsálvez
@ 2012-09-11 11:35 ` Samuel Iglesias Gonsálvez
2012-09-11 11:35 ` [PATCH v2 12/20] Staging: ipack/bridges/tpci200: increment the reference counter of the pci_dev Samuel Iglesias Gonsálvez
` (9 subsequent siblings)
20 siblings, 0 replies; 22+ messages in thread
From: Samuel Iglesias Gonsálvez @ 2012-09-11 11:35 UTC (permalink / raw)
To: Greg Kroah-Hartman
Cc: devel, linux-kernel, industrypack-devel, Samuel Iglesias Gonsálvez
Move iounmap and pci_release_region to tpci200_unregister(), as it is the place
where the clean-up of the device is done.
Also, renamed iounmap() to pci_iounmap() as the mapped region was requested
from PCI bus.
Signed-off-by: Samuel Iglesias Gonsálvez <siglesias@igalia.com>
---
drivers/staging/ipack/bridges/tpci200.c | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/drivers/staging/ipack/bridges/tpci200.c b/drivers/staging/ipack/bridges/tpci200.c
index 22e3da1..383571c 100644
--- a/drivers/staging/ipack/bridges/tpci200.c
+++ b/drivers/staging/ipack/bridges/tpci200.c
@@ -64,10 +64,12 @@ static void tpci200_unregister(struct tpci200_board *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);
pci_release_region(tpci200->info->pdev, TPCI200_IO_ID_INT_SPACES_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);
@@ -750,9 +752,6 @@ static void __tpci200_pci_remove(struct tpci200_board *tpci200)
tpci200_uninstall(tpci200);
ipack_bus_unregister(tpci200->info->ipack_bus);
- iounmap(tpci200->info->cfg_regs);
- pci_release_region(tpci200->info->pdev, TPCI200_CFG_MEM_BAR);
-
kfree(tpci200->info);
kfree(tpci200);
}
--
1.7.10.4
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH v2 12/20] Staging: ipack/bridges/tpci200: increment the reference counter of the pci_dev
2012-09-11 11:34 [PATCH v2 00/20] ipack: added callbacks and some cleanup Samuel Iglesias Gonsálvez
` (10 preceding siblings ...)
2012-09-11 11:35 ` [PATCH v2 11/20] Staging: ipack/bridges/tpci200: reorder the iounmap and pci_release_region Samuel Iglesias Gonsálvez
@ 2012-09-11 11:35 ` Samuel Iglesias Gonsálvez
2012-09-11 11:35 ` [PATCH v2 13/20] Staging: ipack/bridges/tpci200: fix the uninstall the ipack device Samuel Iglesias Gonsálvez
` (8 subsequent siblings)
20 siblings, 0 replies; 22+ messages in thread
From: Samuel Iglesias Gonsálvez @ 2012-09-11 11:35 UTC (permalink / raw)
To: Greg Kroah-Hartman
Cc: devel, linux-kernel, industrypack-devel, Samuel Iglesias Gonsálvez
As indicated in the documentation of pci_dev_get.
Signed-off-by: Samuel Iglesias Gonsálvez <siglesias@igalia.com>
---
drivers/staging/ipack/bridges/tpci200.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/staging/ipack/bridges/tpci200.c b/drivers/staging/ipack/bridges/tpci200.c
index 383571c..b928140 100644
--- a/drivers/staging/ipack/bridges/tpci200.c
+++ b/drivers/staging/ipack/bridges/tpci200.c
@@ -670,6 +670,8 @@ static int tpci200_pci_probe(struct pci_dev *pdev,
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");
@@ -741,6 +743,7 @@ out_err_install:
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);
--
1.7.10.4
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH v2 13/20] Staging: ipack/bridges/tpci200: fix the uninstall the ipack device
2012-09-11 11:34 [PATCH v2 00/20] ipack: added callbacks and some cleanup Samuel Iglesias Gonsálvez
` (11 preceding siblings ...)
2012-09-11 11:35 ` [PATCH v2 12/20] Staging: ipack/bridges/tpci200: increment the reference counter of the pci_dev Samuel Iglesias Gonsálvez
@ 2012-09-11 11:35 ` Samuel Iglesias Gonsálvez
2012-09-11 11:35 ` [PATCH v2 14/20] Staging: ipack/devices/ipoctal: change exiting procedure Samuel Iglesias Gonsálvez
` (7 subsequent siblings)
20 siblings, 0 replies; 22+ messages in thread
From: Samuel Iglesias Gonsálvez @ 2012-09-11 11:35 UTC (permalink / raw)
To: Greg Kroah-Hartman
Cc: devel, linux-kernel, industrypack-devel, Samuel Iglesias Gonsálvez
Using the call to the ipack_device_unregister() function to avoid the
strange way it was doing, as the device model will take care of calling
the bus's .remove function when a device is being unregistered.
Signed-off-by: Samuel Iglesias Gonsálvez <siglesias@igalia.com>
---
drivers/staging/ipack/bridges/tpci200.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/drivers/staging/ipack/bridges/tpci200.c b/drivers/staging/ipack/bridges/tpci200.c
index b928140..77e6392 100644
--- a/drivers/staging/ipack/bridges/tpci200.c
+++ b/drivers/staging/ipack/bridges/tpci200.c
@@ -385,7 +385,6 @@ static int tpci200_slot_unregister(struct ipack_device *dev)
return -ERESTARTSYS;
tpci200->slots[dev->slot].dev = NULL;
- ipack_device_unregister(dev);
mutex_unlock(&tpci200->mutex);
return 0;
@@ -614,7 +613,7 @@ static void tpci200_uninstall(struct tpci200_board *tpci200)
int i;
for (i = 0; i < TPCI200_NB_SLOT; i++)
- tpci200_slot_unregister(tpci200->slots[i].dev);
+ ipack_device_unregister(tpci200->slots[i].dev);
tpci200_unregister(tpci200);
kfree(tpci200->slots);
--
1.7.10.4
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH v2 14/20] Staging: ipack/devices/ipoctal: change exiting procedure
2012-09-11 11:34 [PATCH v2 00/20] ipack: added callbacks and some cleanup Samuel Iglesias Gonsálvez
` (12 preceding siblings ...)
2012-09-11 11:35 ` [PATCH v2 13/20] Staging: ipack/bridges/tpci200: fix the uninstall the ipack device Samuel Iglesias Gonsálvez
@ 2012-09-11 11:35 ` Samuel Iglesias Gonsálvez
2012-09-11 11:35 ` [PATCH v2 15/20] Staging: ipack/devices/ipoctal: free the IRQ Samuel Iglesias Gonsálvez
` (6 subsequent siblings)
20 siblings, 0 replies; 22+ messages in thread
From: Samuel Iglesias Gonsálvez @ 2012-09-11 11:35 UTC (permalink / raw)
To: Greg Kroah-Hartman
Cc: devel, linux-kernel, industrypack-devel, Samuel Iglesias Gonsálvez
The ipoctal devices can be uninstalled from the ipack_driver_unregister()
call as the device model calles the bus's .remove() function for each device
registered by the driver and it will execute the .remove() function of the
ipoctal driver.
Signed-off-by: Samuel Iglesias Gonsálvez <siglesias@igalia.com>
---
drivers/staging/ipack/devices/ipoctal.c | 5 -----
1 file changed, 5 deletions(-)
diff --git a/drivers/staging/ipack/devices/ipoctal.c b/drivers/staging/ipack/devices/ipoctal.c
index c94a9df..272832f 100644
--- a/drivers/staging/ipack/devices/ipoctal.c
+++ b/drivers/staging/ipack/devices/ipoctal.c
@@ -853,11 +853,6 @@ static int __init ipoctal_init(void)
static void __exit ipoctal_exit(void)
{
- struct ipoctal *p, *next;
-
- list_for_each_entry_safe(p, next, &ipoctal_list, list)
- p->dev->bus->ops->remove_device(p->dev);
-
ipack_driver_unregister(&driver);
}
--
1.7.10.4
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH v2 15/20] Staging: ipack/devices/ipoctal: free the IRQ.
2012-09-11 11:34 [PATCH v2 00/20] ipack: added callbacks and some cleanup Samuel Iglesias Gonsálvez
` (13 preceding siblings ...)
2012-09-11 11:35 ` [PATCH v2 14/20] Staging: ipack/devices/ipoctal: change exiting procedure Samuel Iglesias Gonsálvez
@ 2012-09-11 11:35 ` Samuel Iglesias Gonsálvez
2012-09-11 11:35 ` [PATCH v2 16/20] Staging: ipack: unregister devices when uninstall the carrier device Samuel Iglesias Gonsálvez
` (5 subsequent siblings)
20 siblings, 0 replies; 22+ messages in thread
From: Samuel Iglesias Gonsálvez @ 2012-09-11 11:35 UTC (permalink / raw)
To: Greg Kroah-Hartman
Cc: devel, linux-kernel, industrypack-devel, Samuel Iglesias Gonsálvez
As the IRQ was requested by the driver, it should free it also.
Signed-off-by: Samuel Iglesias Gonsálvez <siglesias@igalia.com>
---
drivers/staging/ipack/devices/ipoctal.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/staging/ipack/devices/ipoctal.c b/drivers/staging/ipack/devices/ipoctal.c
index 272832f..35513d9 100644
--- a/drivers/staging/ipack/devices/ipoctal.c
+++ b/drivers/staging/ipack/devices/ipoctal.c
@@ -803,6 +803,8 @@ static void __ipoctal_remove(struct ipoctal *ipoctal)
{
int i;
+ ipoctal->dev->bus->ops->free_irq(ipoctal->dev);
+
for (i = 0; i < NR_CHANNELS; i++) {
tty_unregister_device(ipoctal->tty_drv, i);
tty_port_free_xmit_buf(&ipoctal->tty_port[i]);
--
1.7.10.4
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH v2 16/20] Staging: ipack: unregister devices when uninstall the carrier device.
2012-09-11 11:34 [PATCH v2 00/20] ipack: added callbacks and some cleanup Samuel Iglesias Gonsálvez
` (14 preceding siblings ...)
2012-09-11 11:35 ` [PATCH v2 15/20] Staging: ipack/devices/ipoctal: free the IRQ Samuel Iglesias Gonsálvez
@ 2012-09-11 11:35 ` Samuel Iglesias Gonsálvez
2012-09-11 11:35 ` [PATCH v2 17/20] Staging: ipack/bridges/tpci200: delete ipack_device_unregister calls when exiting Samuel Iglesias Gonsálvez
` (4 subsequent siblings)
20 siblings, 0 replies; 22+ messages in thread
From: Samuel Iglesias Gonsálvez @ 2012-09-11 11:35 UTC (permalink / raw)
To: Greg Kroah-Hartman
Cc: devel, linux-kernel, industrypack-devel, Samuel Iglesias Gonsálvez
Find the IP modules that are plugged to the carrier and unregister them.
Signed-off-by: Samuel Iglesias Gonsálvez <siglesias@igalia.com>
---
drivers/staging/ipack/ipack.c | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/drivers/staging/ipack/ipack.c b/drivers/staging/ipack/ipack.c
index 26dc976..c83f015 100644
--- a/drivers/staging/ipack/ipack.c
+++ b/drivers/staging/ipack/ipack.c
@@ -229,8 +229,20 @@ struct ipack_bus_device *ipack_bus_register(struct device *parent, int slots,
}
EXPORT_SYMBOL_GPL(ipack_bus_register);
+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)
+ ipack_device_unregister(idev);
+
+ return 1;
+}
+
int ipack_bus_unregister(struct ipack_bus_device *bus)
{
+ bus_for_each_dev(&ipack_bus_type, NULL, bus, ipack_unregister_bus_member);
ida_simple_remove(&ipack_ida, bus->bus_nr);
kfree(bus);
return 0;
--
1.7.10.4
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH v2 17/20] Staging: ipack/bridges/tpci200: delete ipack_device_unregister calls when exiting
2012-09-11 11:34 [PATCH v2 00/20] ipack: added callbacks and some cleanup Samuel Iglesias Gonsálvez
` (15 preceding siblings ...)
2012-09-11 11:35 ` [PATCH v2 16/20] Staging: ipack: unregister devices when uninstall the carrier device Samuel Iglesias Gonsálvez
@ 2012-09-11 11:35 ` Samuel Iglesias Gonsálvez
2012-09-11 11:35 ` [PATCH v2 18/20] Staging: ipack/bridges/tpci200: remove tpci200_slot_unregister Samuel Iglesias Gonsálvez
` (3 subsequent siblings)
20 siblings, 0 replies; 22+ messages in thread
From: Samuel Iglesias Gonsálvez @ 2012-09-11 11:35 UTC (permalink / raw)
To: Greg Kroah-Hartman
Cc: devel, linux-kernel, industrypack-devel, Samuel Iglesias Gonsálvez
As the ipack_bus_unregister() takes care of unregistering the devices plugged
in the carrier, it is not needed to do it in the carrier driver.
Signed-off-by: Samuel Iglesias Gonsálvez <siglesias@igalia.com>
---
drivers/staging/ipack/bridges/tpci200.c | 7 +------
1 file changed, 1 insertion(+), 6 deletions(-)
diff --git a/drivers/staging/ipack/bridges/tpci200.c b/drivers/staging/ipack/bridges/tpci200.c
index 77e6392..8de74c9 100644
--- a/drivers/staging/ipack/bridges/tpci200.c
+++ b/drivers/staging/ipack/bridges/tpci200.c
@@ -610,11 +610,6 @@ static int tpci200_reset_timeout(struct ipack_device *dev)
static void tpci200_uninstall(struct tpci200_board *tpci200)
{
- int i;
-
- for (i = 0; i < TPCI200_NB_SLOT; i++)
- ipack_device_unregister(tpci200->slots[i].dev);
-
tpci200_unregister(tpci200);
kfree(tpci200->slots);
}
@@ -751,8 +746,8 @@ out_err_info:
static void __tpci200_pci_remove(struct tpci200_board *tpci200)
{
- tpci200_uninstall(tpci200);
ipack_bus_unregister(tpci200->info->ipack_bus);
+ tpci200_uninstall(tpci200);
kfree(tpci200->info);
kfree(tpci200);
--
1.7.10.4
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH v2 18/20] Staging: ipack/bridges/tpci200: remove tpci200_slot_unregister
2012-09-11 11:34 [PATCH v2 00/20] ipack: added callbacks and some cleanup Samuel Iglesias Gonsálvez
` (16 preceding siblings ...)
2012-09-11 11:35 ` [PATCH v2 17/20] Staging: ipack/bridges/tpci200: delete ipack_device_unregister calls when exiting Samuel Iglesias Gonsálvez
@ 2012-09-11 11:35 ` Samuel Iglesias Gonsálvez
2012-09-11 11:35 ` [PATCH v2 19/20] Staging: ipack: delete .remove_device() callback Samuel Iglesias Gonsálvez
` (2 subsequent siblings)
20 siblings, 0 replies; 22+ messages in thread
From: Samuel Iglesias Gonsálvez @ 2012-09-11 11:35 UTC (permalink / raw)
To: Greg Kroah-Hartman
Cc: devel, linux-kernel, industrypack-devel, Samuel Iglesias Gonsálvez
It is not needed as the IP module should free its IRQ using
tpci200_free_irq callback.
Signed-off-by: Samuel Iglesias Gonsálvez <siglesias@igalia.com>
---
drivers/staging/ipack/bridges/tpci200.c | 26 +-------------------------
1 file changed, 1 insertion(+), 25 deletions(-)
diff --git a/drivers/staging/ipack/bridges/tpci200.c b/drivers/staging/ipack/bridges/tpci200.c
index 8de74c9..0823cdb 100644
--- a/drivers/staging/ipack/bridges/tpci200.c
+++ b/drivers/staging/ipack/bridges/tpci200.c
@@ -28,8 +28,6 @@ static u16 tpci200_status_error[] = {
TPCI200_D_ERROR,
};
-static int tpci200_slot_unregister(struct ipack_device *dev);
-
static struct tpci200_board *check_slot(struct ipack_device *dev)
{
struct tpci200_board *tpci200;
@@ -368,28 +366,6 @@ out_unlock:
return 0;
}
-static int tpci200_slot_unregister(struct ipack_device *dev)
-{
- struct tpci200_board *tpci200;
-
- if (dev == NULL)
- return -ENODEV;
-
- tpci200 = check_slot(dev);
- if (tpci200 == NULL)
- return -EINVAL;
-
- tpci200_free_irq(dev);
-
- if (mutex_lock_interruptible(&tpci200->mutex))
- return -ERESTARTSYS;
-
- tpci200->slots[dev->slot].dev = NULL;
- mutex_unlock(&tpci200->mutex);
-
- return 0;
-}
-
static int tpci200_slot_map_space(struct ipack_device *dev,
unsigned int memory_size, int space)
{
@@ -619,7 +595,7 @@ static const struct ipack_bus_ops tpci200_bus_ops = {
.unmap_space = tpci200_slot_unmap_space,
.request_irq = tpci200_request_irq,
.free_irq = tpci200_free_irq,
- .remove_device = tpci200_slot_unregister,
+ .remove_device = NULL,
.get_clockrate = tpci200_get_clockrate,
.set_clockrate = tpci200_set_clockrate,
.get_error = tpci200_get_error,
--
1.7.10.4
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH v2 19/20] Staging: ipack: delete .remove_device() callback
2012-09-11 11:34 [PATCH v2 00/20] ipack: added callbacks and some cleanup Samuel Iglesias Gonsálvez
` (17 preceding siblings ...)
2012-09-11 11:35 ` [PATCH v2 18/20] Staging: ipack/bridges/tpci200: remove tpci200_slot_unregister Samuel Iglesias Gonsálvez
@ 2012-09-11 11:35 ` Samuel Iglesias Gonsálvez
2012-09-11 11:35 ` [PATCH v2 20/20] Staging: ipack/bridges/tpci200: Store the irq holder in slot_irq Samuel Iglesias Gonsálvez
2012-09-11 19:18 ` [PATCH v2 00/20] ipack: added callbacks and some cleanup Greg Kroah-Hartman
20 siblings, 0 replies; 22+ messages in thread
From: Samuel Iglesias Gonsálvez @ 2012-09-11 11:35 UTC (permalink / raw)
To: Greg Kroah-Hartman
Cc: devel, linux-kernel, industrypack-devel, Samuel Iglesias Gonsálvez
As the IP module driver takes care of freeing its resources.
Signed-off-by: Samuel Iglesias Gonsálvez <siglesias@igalia.com>
---
drivers/staging/ipack/bridges/tpci200.c | 1 -
drivers/staging/ipack/ipack.h | 3 ---
2 files changed, 4 deletions(-)
diff --git a/drivers/staging/ipack/bridges/tpci200.c b/drivers/staging/ipack/bridges/tpci200.c
index 0823cdb..5aff0d0 100644
--- a/drivers/staging/ipack/bridges/tpci200.c
+++ b/drivers/staging/ipack/bridges/tpci200.c
@@ -595,7 +595,6 @@ static const struct ipack_bus_ops tpci200_bus_ops = {
.unmap_space = tpci200_slot_unmap_space,
.request_irq = tpci200_request_irq,
.free_irq = tpci200_free_irq,
- .remove_device = NULL,
.get_clockrate = tpci200_get_clockrate,
.set_clockrate = tpci200_set_clockrate,
.get_error = tpci200_get_error,
diff --git a/drivers/staging/ipack/ipack.h b/drivers/staging/ipack/ipack.h
index 77d8075..0ea9d84 100644
--- a/drivers/staging/ipack/ipack.h
+++ b/drivers/staging/ipack/ipack.h
@@ -113,7 +113,6 @@ struct ipack_driver {
* @unmap_space: unmap IP address space
* @request_irq: request IRQ
* @free_irq: free IRQ
- * @remove_device: tell the bridge module that the device has been removed
* @get_clockrate: Returns the clockrate the carrier is currently
* communicating with the device at.
* @set_clockrate: Sets the clock-rate for carrier / module communication.
@@ -129,8 +128,6 @@ struct ipack_bus_ops {
int (*unmap_space) (struct ipack_device *dev, int space);
int (*request_irq) (struct ipack_device *dev, int vector, int (*handler)(void *), void *arg);
int (*free_irq) (struct ipack_device *dev);
- int (*remove_device) (struct ipack_device *dev);
-
int (*get_clockrate) (struct ipack_device *dev);
int (*set_clockrate) (struct ipack_device *dev, int mherz);
int (*get_error) (struct ipack_device *dev);
--
1.7.10.4
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH v2 20/20] Staging: ipack/bridges/tpci200: Store the irq holder in slot_irq.
2012-09-11 11:34 [PATCH v2 00/20] ipack: added callbacks and some cleanup Samuel Iglesias Gonsálvez
` (18 preceding siblings ...)
2012-09-11 11:35 ` [PATCH v2 19/20] Staging: ipack: delete .remove_device() callback Samuel Iglesias Gonsálvez
@ 2012-09-11 11:35 ` Samuel Iglesias Gonsálvez
2012-09-11 19:18 ` [PATCH v2 00/20] ipack: added callbacks and some cleanup Greg Kroah-Hartman
20 siblings, 0 replies; 22+ messages in thread
From: Samuel Iglesias Gonsálvez @ 2012-09-11 11:35 UTC (permalink / raw)
To: Greg Kroah-Hartman
Cc: devel, linux-kernel, industrypack-devel, Jens Taprogge,
Samuel Iglesias Gonsálvez
From: Jens Taprogge <jens.taprogge@taprogge.org>
This way we do no longer need to keep a dangling pointer to struct
ipack_device in tpci200_slot after the device has been removed.
Signed-off-by: Jens Taprogge <jens.taprogge@taprogge.org>
Signed-off-by: Samuel Iglesias Gonsálvez <siglesias@igalia.com>
---
drivers/staging/ipack/bridges/tpci200.c | 19 ++++++++++++-------
drivers/staging/ipack/bridges/tpci200.h | 2 +-
2 files changed, 13 insertions(+), 8 deletions(-)
diff --git a/drivers/staging/ipack/bridges/tpci200.c b/drivers/staging/ipack/bridges/tpci200.c
index 5aff0d0..9d886b7 100644
--- a/drivers/staging/ipack/bridges/tpci200.c
+++ b/drivers/staging/ipack/bridges/tpci200.c
@@ -89,6 +89,7 @@ static irqreturn_t tpci200_interrupt(int irq, void *dev_id)
unsigned short status_reg, reg_value;
unsigned short unhandled_ints = 0;
irqreturn_t ret = IRQ_NONE;
+ struct slot_irq *slot_irq;
/* Read status register */
status_reg = readw(&tpci200->info->interface_regs->status);
@@ -97,15 +98,17 @@ static irqreturn_t tpci200_interrupt(int irq, void *dev_id)
unhandled_ints = status_reg & TPCI200_SLOT_INT_MASK;
/* callback to the IRQ handler for the corresponding slot */
for (i = 0; i < TPCI200_NB_SLOT; i++) {
- if ((tpci200->slots[i].irq != NULL) &&
+ slot_irq = tpci200->slots[i].irq;
+
+ if ((slot_irq != NULL) &&
(status_reg & ((TPCI200_A_INT0 | TPCI200_A_INT1) << (2*i)))) {
- ret = tpci200->slots[i].irq->handler(tpci200->slots[i].irq->arg);
+ ret = slot_irq->handler(slot_irq->arg);
/* Dummy reads */
- readw(tpci200->slots[i].dev->io_space.address +
+ readw(slot_irq->holder->io_space.address +
0xC0);
- readw(tpci200->slots[i].dev->io_space.address +
+ readw(slot_irq->holder->io_space.address +
0xC2);
unhandled_ints &= ~(((TPCI200_A_INT0 | TPCI200_A_INT1) << (2*i)));
@@ -115,8 +118,10 @@ static irqreturn_t tpci200_interrupt(int irq, void *dev_id)
/* Interrupts not handled are disabled */
if (unhandled_ints) {
for (i = 0; i < TPCI200_NB_SLOT; i++) {
+ slot_irq = tpci200->slots[i].irq;
+
if (unhandled_ints & ((TPCI200_INT0_EN | TPCI200_INT1_EN) << (2*i))) {
- dev_info(&tpci200->slots[i].dev->dev,
+ dev_info(&slot_irq->holder->dev,
"No registered ISR for slot [%d:%d]!. IRQ will be disabled.\n",
tpci200->number, i);
reg_value = readw(
@@ -487,6 +492,7 @@ static int tpci200_request_irq(struct ipack_device *dev, int vector,
slot_irq->vector = vector;
slot_irq->handler = handler;
slot_irq->arg = arg;
+ slot_irq->holder = dev;
tpci200->slots[dev->slot].irq = slot_irq;
res = __tpci200_request_irq(tpci200, dev);
@@ -701,8 +707,7 @@ static int tpci200_pci_probe(struct pci_dev *pdev,
* The TPCI200 has assigned his own two IRQ by PCI bus driver
*/
for (i = 0; i < TPCI200_NB_SLOT; i++)
- tpci200->slots[i].dev =
- ipack_device_register(tpci200->info->ipack_bus, i, i);
+ ipack_device_register(tpci200->info->ipack_bus, i, i);
return 0;
out_err_bus_register:
diff --git a/drivers/staging/ipack/bridges/tpci200.h b/drivers/staging/ipack/bridges/tpci200.h
index fc90a94..75a5dcc 100644
--- a/drivers/staging/ipack/bridges/tpci200.h
+++ b/drivers/staging/ipack/bridges/tpci200.h
@@ -121,6 +121,7 @@ struct tpci200_regs {
*
*/
struct slot_irq {
+ struct ipack_device *holder;
int vector;
int (*handler)(void *);
void *arg;
@@ -136,7 +137,6 @@ struct slot_irq {
*
*/
struct tpci200_slot {
- struct ipack_device *dev;
struct slot_irq *irq;
struct ipack_addr_space io_phys;
struct ipack_addr_space id_phys;
--
1.7.10.4
^ permalink raw reply related [flat|nested] 22+ messages in thread
* Re: [PATCH v2 00/20] ipack: added callbacks and some cleanup
2012-09-11 11:34 [PATCH v2 00/20] ipack: added callbacks and some cleanup Samuel Iglesias Gonsálvez
` (19 preceding siblings ...)
2012-09-11 11:35 ` [PATCH v2 20/20] Staging: ipack/bridges/tpci200: Store the irq holder in slot_irq Samuel Iglesias Gonsálvez
@ 2012-09-11 19:18 ` Greg Kroah-Hartman
20 siblings, 0 replies; 22+ messages in thread
From: Greg Kroah-Hartman @ 2012-09-11 19:18 UTC (permalink / raw)
To: Samuel Iglesias Gonsálvez; +Cc: devel, linux-kernel, industrypack-devel
On Tue, Sep 11, 2012 at 01:34:53PM +0200, Samuel Iglesias Gonsálvez wrote:
> Hello,
>
> This second version adds Dan Carpenter's suggestions and it has been rebased
> from gregkh's staging-next repository.
>
> Dan, if you want, you can add the Reviewed-by for all the patches again.
>
> Hopefully, this time the MTA will not change the Content-Transfer-Encoding from
> 8bit to base64.
Worked well this time, thanks, all now applied.
greg k-h
^ permalink raw reply [flat|nested] 22+ messages in thread