linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 00/16] ipack: autoload IP module drivers
@ 2012-09-04 15:01 Samuel Iglesias Gonsálvez
  2012-09-04 15:01 ` [PATCH 01/16] Staging: ipack/bridges/tpci200: Reorganize tpci200_probe in preparation for functional changes Samuel Iglesias Gonsálvez
                   ` (15 more replies)
  0 siblings, 16 replies; 17+ messages in thread
From: Samuel Iglesias Gonsálvez @ 2012-09-04 15:01 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: devel, linux-kernel, industrypack-devel, Samuel Iglesias Gonsálvez

Hello,

This bunch of patches adds support to autoload IP module drivers when they are
detected by the ipack bus driver.

Also, it changes the endianness of the carrier device to Big Endian as it is
defined in the Industry Pack standard. Due to that, the source code is
simplified too.

There are more patches (~40) waiting to be sent but I prefer to send them in
batches for proper review. If you think it will be a better idea to send them
all together, please tell me.

Thanks to Jens Taprogge for his work on this area.

Best regards,

Sam

Jens Taprogge (15):
  Staging: ipack/bridges/tpci200: Reorganize tpci200_probe in
    preparation for functional changes.
  Staging: ipack/bridges/tpci200: Use the TPCI200 in big endian mode.
  Staging: ipack/devices/ipoctal: Convert ipoctal to directly use
    ioread/write functions.
  Staging: ipack/bridges/tpci200: Remove the read/write functions from
    ipack_bus_ops.
  Staging: ipack/devices/ipoctal: ipoctal cleanups.
  Staging: ipack/devices/ipoctal: Tidy up ipoctal some more.
  Staging: ipack: implement ipack device table.
  Staging: ipack: Read the ID space during device registration.
  Staging: ipack: Parse vendor and device id.
  Staging: ipack: Move device ids from ipoctal.c to ipack_ids.h.
  Staging: ipack: Make ipack_driver_ops const.
  Staging: ipack/devices/ipoctal: Expose DEVICE_TABLE for ipoctal.
  Staging: ipack: Implement device matching on the bus level.
  Staging: ipack: Expose modalias through sysfs.
  Staging: ipack: Provide ID Prom through sysfs.

Samuel Iglesias Gonsálvez (1):
  Staging: ipack: remove read/write operations from ipack_bus_ops

 drivers/staging/ipack/bridges/tpci200.c |  280 ++++++-------------------------
 drivers/staging/ipack/bridges/tpci200.h |    9 +
 drivers/staging/ipack/devices/ipoctal.c |  188 +++++++++------------
 drivers/staging/ipack/devices/scc2698.h |  114 ++++++-------
 drivers/staging/ipack/ipack.c           |  271 ++++++++++++++++++++++++++++--
 drivers/staging/ipack/ipack.h           |   49 ++++--
 drivers/staging/ipack/ipack_ids.h       |   32 ++++
 include/linux/mod_devicetable.h         |    7 +
 scripts/mod/file2alias.c                |   15 ++
 9 files changed, 543 insertions(+), 422 deletions(-)
 create mode 100644 drivers/staging/ipack/ipack_ids.h

-- 
1.7.10.4


^ permalink raw reply	[flat|nested] 17+ messages in thread

* [PATCH 01/16] Staging: ipack/bridges/tpci200: Reorganize tpci200_probe in preparation for functional changes.
  2012-09-04 15:01 [PATCH 00/16] ipack: autoload IP module drivers Samuel Iglesias Gonsálvez
@ 2012-09-04 15:01 ` Samuel Iglesias Gonsálvez
  2012-09-04 15:01 ` [PATCH 02/16] Staging: ipack/bridges/tpci200: Use the TPCI200 in big endian mode Samuel Iglesias Gonsálvez
                   ` (14 subsequent siblings)
  15 siblings, 0 replies; 17+ messages in thread
From: Samuel Iglesias Gonsálvez @ 2012-09-04 15:01 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>

These changes make it easier to add more initialization steps later on.

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 |   25 +++++++++++++++----------
 1 file changed, 15 insertions(+), 10 deletions(-)

diff --git a/drivers/staging/ipack/bridges/tpci200.c b/drivers/staging/ipack/bridges/tpci200.c
index 5831af8..eda02e7 100644
--- a/drivers/staging/ipack/bridges/tpci200.c
+++ b/drivers/staging/ipack/bridges/tpci200.c
@@ -790,8 +790,8 @@ static int tpci200_pciprobe(struct pci_dev *pdev,
 
 	tpci200->info = kzalloc(sizeof(struct tpci200_infos), GFP_KERNEL);
 	if (!tpci200->info) {
-		kfree(tpci200);
-		return -ENOMEM;
+		ret = -ENOMEM;
+		goto out_err_info;
 	}
 
 	/* Save struct pci_dev pointer */
@@ -801,10 +801,9 @@ static int tpci200_pciprobe(struct pci_dev *pdev,
 	/* register the device and initialize it */
 	ret = tpci200_install(tpci200);
 	if (ret) {
-		dev_err(&pdev->dev, "Error during tpci200 install !\n");
-		kfree(tpci200->info);
-		kfree(tpci200);
-		return -ENODEV;
+		dev_err(&pdev->dev, "error during tpci200 install\n");
+		ret = -ENODEV;
+		goto out_err_install;
 	}
 
 	/* Register the carrier in the industry pack bus driver */
@@ -814,10 +813,8 @@ static int tpci200_pciprobe(struct pci_dev *pdev,
 	if (!tpci200->info->ipack_bus) {
 		dev_err(&pdev->dev,
 			"error registering the carrier on ipack driver\n");
-		tpci200_uninstall(tpci200);
-		kfree(tpci200->info);
-		kfree(tpci200);
-		return -EFAULT;
+		ret = -EFAULT;
+		goto out_err_bus_register;
 	}
 
 	/* save the bus number given by ipack to logging purpose */
@@ -831,6 +828,14 @@ static int tpci200_pciprobe(struct pci_dev *pdev,
 	for (i = 0; i < TPCI200_NB_SLOT; i++)
 		tpci200->slots[i].dev =
 			ipack_device_register(tpci200->info->ipack_bus, i, i);
+	return 0;
+
+out_err_bus_register:
+	tpci200_uninstall(tpci200);
+out_err_install:
+	kfree(tpci200->info);
+out_err_info:
+	kfree(tpci200);
 	return ret;
 }
 
-- 
1.7.10.4


^ permalink raw reply	[flat|nested] 17+ messages in thread

* [PATCH 02/16] Staging: ipack/bridges/tpci200: Use the TPCI200 in big endian mode.
  2012-09-04 15:01 [PATCH 00/16] ipack: autoload IP module drivers Samuel Iglesias Gonsálvez
  2012-09-04 15:01 ` [PATCH 01/16] Staging: ipack/bridges/tpci200: Reorganize tpci200_probe in preparation for functional changes Samuel Iglesias Gonsálvez
@ 2012-09-04 15:01 ` Samuel Iglesias Gonsálvez
  2012-09-04 15:01 ` [PATCH 03/16] Staging: ipack/devices/ipoctal: Convert ipoctal to directly use ioread/write functions Samuel Iglesias Gonsálvez
                   ` (13 subsequent siblings)
  15 siblings, 0 replies; 17+ messages in thread
From: Samuel Iglesias Gonsálvez @ 2012-09-04 15:01 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>

During initialization we configure the TPCI200 so it does not swap data
lanes on IndustryPack module access.  The read and write functions are
changed accordingly.

We are taking this approach in the hope that all IP Carriers are able to
present the Module memory layout unchanged.  We can thus directly access
the memory and registers of IP Modules without having to rely on the
read and write wrappers currently exposed in ipack_bus_opts.  A later
patch will convert the existing driver and remove the wrappers.

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 |   49 +++++++++++++++++++++++++++----
 drivers/staging/ipack/bridges/tpci200.h |    9 ++++++
 drivers/staging/ipack/devices/ipoctal.c |    2 +-
 3 files changed, 53 insertions(+), 7 deletions(-)

diff --git a/drivers/staging/ipack/bridges/tpci200.c b/drivers/staging/ipack/bridges/tpci200.c
index eda02e7..f2501c9 100644
--- a/drivers/staging/ipack/bridges/tpci200.c
+++ b/drivers/staging/ipack/bridges/tpci200.c
@@ -54,39 +54,39 @@ static struct tpci200_board *check_slot(struct ipack_device *dev)
 static inline unsigned char __tpci200_read8(void __iomem *address,
 					    unsigned long offset)
 {
-	return ioread8(address + (offset^1));
+	return ioread8(address + offset);
 }
 
 static inline unsigned short __tpci200_read16(void __iomem *address,
 					      unsigned long offset)
 {
-	return ioread16(address + offset);
+	return ioread16be(address + offset);
 }
 
 static inline unsigned int __tpci200_read32(void __iomem *address,
 					    unsigned long offset)
 {
-	return swahw32(ioread32(address + offset));
+	return ioread32be(address + offset);
 }
 
 static inline void __tpci200_write8(unsigned char value,
 				    void __iomem *address, unsigned long offset)
 {
-	iowrite8(value, address+(offset^1));
+	iowrite8(value, address + offset);
 }
 
 static inline void __tpci200_write16(unsigned short value,
 				     void __iomem *address,
 				     unsigned long offset)
 {
-	iowrite16(value, address+offset);
+	iowrite16be(value, address + offset);
 }
 
 static inline void __tpci200_write32(unsigned int value,
 				     void __iomem *address,
 				     unsigned long offset)
 {
-	iowrite32(swahw32(value), address+offset);
+	iowrite32be(value, address + offset);
 }
 
 static struct ipack_addr_space *get_slot_address_space(struct ipack_device *dev,
@@ -783,6 +783,7 @@ static int tpci200_pciprobe(struct pci_dev *pdev,
 {
 	int ret, i;
 	struct tpci200_board *tpci200;
+	__le32 reg32;
 
 	tpci200 = kzalloc(sizeof(struct tpci200_board), GFP_KERNEL);
 	if (!tpci200)
@@ -794,6 +795,34 @@ static int tpci200_pciprobe(struct pci_dev *pdev,
 		goto out_err_info;
 	}
 
+	/* 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;
@@ -833,6 +862,10 @@ static int tpci200_pciprobe(struct pci_dev *pdev,
 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:
 	kfree(tpci200->info);
 out_err_info:
 	kfree(tpci200);
@@ -843,6 +876,10 @@ 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);
 }
diff --git a/drivers/staging/ipack/bridges/tpci200.h b/drivers/staging/ipack/bridges/tpci200.h
index d04510a..38acba1 100644
--- a/drivers/staging/ipack/bridges/tpci200.h
+++ b/drivers/staging/ipack/bridges/tpci200.h
@@ -31,6 +31,7 @@
 #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
@@ -97,6 +98,13 @@
 
 #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"
 
@@ -144,6 +152,7 @@ struct tpci200_infos {
 	void __iomem			*interface_regs;
 	void __iomem			*ioidint_space;
 	void __iomem			*mem8_space;
+	void __iomem			*cfg_regs;
 	struct ipack_bus_device		*ipack_bus;
 };
 struct tpci200_board {
diff --git a/drivers/staging/ipack/devices/ipoctal.c b/drivers/staging/ipack/devices/ipoctal.c
index fd0e301..963ed20 100644
--- a/drivers/staging/ipack/devices/ipoctal.c
+++ b/drivers/staging/ipack/devices/ipoctal.c
@@ -449,7 +449,7 @@ static int ipoctal_inst_slot(struct ipoctal *ipoctal, unsigned int bus_nr,
 	 */
 	ipoctal->dev->bus->ops->request_irq(ipoctal->dev, vector,
 				       ipoctal_irq_handler, ipoctal);
-	ipoctal->dev->bus->ops->write8(ipoctal->dev, IPACK_MEM_SPACE, 0,
+	ipoctal->dev->bus->ops->write8(ipoctal->dev, IPACK_MEM_SPACE, 1,
 				       vector);
 
 	/* Register the TTY device */
-- 
1.7.10.4


^ permalink raw reply	[flat|nested] 17+ messages in thread

* [PATCH 03/16] Staging: ipack/devices/ipoctal: Convert ipoctal to directly use ioread/write functions.
  2012-09-04 15:01 [PATCH 00/16] ipack: autoload IP module drivers Samuel Iglesias Gonsálvez
  2012-09-04 15:01 ` [PATCH 01/16] Staging: ipack/bridges/tpci200: Reorganize tpci200_probe in preparation for functional changes Samuel Iglesias Gonsálvez
  2012-09-04 15:01 ` [PATCH 02/16] Staging: ipack/bridges/tpci200: Use the TPCI200 in big endian mode Samuel Iglesias Gonsálvez
@ 2012-09-04 15:01 ` Samuel Iglesias Gonsálvez
  2012-09-04 15:01 ` [PATCH 04/16] Staging: ipack/bridges/tpci200: Remove the read/write functions from ipack_bus_ops Samuel Iglesias Gonsálvez
                   ` (12 subsequent siblings)
  15 siblings, 0 replies; 17+ messages in thread
From: Samuel Iglesias Gonsálvez @ 2012-09-04 15:01 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>

Before it was using the functions in ipack_bus_ops.

Signed-off-by: Jens Taprogge <jens.taprogge@taprogge.org>
Signed-off-by: Samuel Iglesias Gonsálvez <siglesias@igalia.com>
---
 drivers/staging/ipack/devices/ipoctal.c |   29 ++++++++---------------------
 1 file changed, 8 insertions(+), 21 deletions(-)

diff --git a/drivers/staging/ipack/devices/ipoctal.c b/drivers/staging/ipack/devices/ipoctal.c
index 963ed20..085b6c0 100644
--- a/drivers/staging/ipack/devices/ipoctal.c
+++ b/drivers/staging/ipack/devices/ipoctal.c
@@ -20,6 +20,7 @@
 #include <linux/tty_flip.h>
 #include <linux/slab.h>
 #include <linux/atomic.h>
+#include <linux/io.h>
 #include "../ipack.h"
 #include "ipoctal.h"
 #include "scc2698.h"
@@ -61,16 +62,12 @@ static inline void ipoctal_write_io_reg(struct ipoctal *ipoctal,
 					unsigned char *dest,
 					unsigned char value)
 {
-	unsigned long offset;
-
-	offset = ((void __iomem *) dest) - ipoctal->dev->io_space.address;
-	ipoctal->dev->bus->ops->write8(ipoctal->dev, IPACK_IO_SPACE, offset,
-				       value);
+	iowrite8(value, dest);
 }
 
 static inline void ipoctal_write_cr_cmd(struct ipoctal *ipoctal,
-					unsigned char *dest,
-					unsigned char value)
+					u8 __iomem *dest,
+					u8 value)
 {
 	ipoctal_write_io_reg(ipoctal, dest, value);
 }
@@ -78,13 +75,7 @@ static inline void ipoctal_write_cr_cmd(struct ipoctal *ipoctal,
 static inline unsigned char ipoctal_read_io_reg(struct ipoctal *ipoctal,
 						unsigned char *src)
 {
-	unsigned long offset;
-	unsigned char value;
-
-	offset = ((void __iomem *) src) - ipoctal->dev->io_space.address;
-	ipoctal->dev->bus->ops->read8(ipoctal->dev, IPACK_IO_SPACE, offset,
-				      &value);
-	return value;
+	return ioread8(src);
 }
 
 static struct ipoctal *ipoctal_find_board(struct tty_struct *tty)
@@ -331,14 +322,11 @@ static int ipoctal_check_model(struct ipack_device *dev, unsigned char *id)
 	unsigned char manufacturerID;
 	unsigned char board_id;
 
-	dev->bus->ops->read8(dev, IPACK_ID_SPACE,
-			IPACK_IDPROM_OFFSET_MANUFACTURER_ID, &manufacturerID);
+	manufacturerID = ioread8(dev->id_space.address + IPACK_IDPROM_OFFSET_MANUFACTURER_ID);
 	if (manufacturerID != IP_OCTAL_MANUFACTURER_ID)
 		return -ENODEV;
 
-	dev->bus->ops->read8(dev, IPACK_ID_SPACE,
-			IPACK_IDPROM_OFFSET_MODEL, (unsigned char *)&board_id);
-
+	board_id = ioread8(dev->id_space.address + IPACK_IDPROM_OFFSET_MODEL);
 	switch (board_id) {
 	case IP_OCTAL_232_ID:
 	case IP_OCTAL_422_ID:
@@ -449,8 +437,7 @@ static int ipoctal_inst_slot(struct ipoctal *ipoctal, unsigned int bus_nr,
 	 */
 	ipoctal->dev->bus->ops->request_irq(ipoctal->dev, vector,
 				       ipoctal_irq_handler, ipoctal);
-	ipoctal->dev->bus->ops->write8(ipoctal->dev, IPACK_MEM_SPACE, 1,
-				       vector);
+	iowrite8(vector, ipoctal->dev->mem_space.address + 1);
 
 	/* Register the TTY device */
 
-- 
1.7.10.4


^ permalink raw reply	[flat|nested] 17+ messages in thread

* [PATCH 04/16] Staging: ipack/bridges/tpci200: Remove the read/write functions from ipack_bus_ops.
  2012-09-04 15:01 [PATCH 00/16] ipack: autoload IP module drivers Samuel Iglesias Gonsálvez
                   ` (2 preceding siblings ...)
  2012-09-04 15:01 ` [PATCH 03/16] Staging: ipack/devices/ipoctal: Convert ipoctal to directly use ioread/write functions Samuel Iglesias Gonsálvez
@ 2012-09-04 15:01 ` Samuel Iglesias Gonsálvez
  2012-09-04 15:01 ` [PATCH 05/16] Staging: ipack: remove read/write operations " Samuel Iglesias Gonsálvez
                   ` (11 subsequent siblings)
  15 siblings, 0 replies; 17+ messages in thread
From: Samuel Iglesias Gonsálvez @ 2012-09-04 15:01 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>

They are not used any longer.

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 |  218 -------------------------------
 1 file changed, 218 deletions(-)

diff --git a/drivers/staging/ipack/bridges/tpci200.c b/drivers/staging/ipack/bridges/tpci200.c
index f2501c9..b81a8c9 100644
--- a/drivers/staging/ipack/bridges/tpci200.c
+++ b/drivers/staging/ipack/bridges/tpci200.c
@@ -51,218 +51,6 @@ static struct tpci200_board *check_slot(struct ipack_device *dev)
 	return tpci200;
 }
 
-static inline unsigned char __tpci200_read8(void __iomem *address,
-					    unsigned long offset)
-{
-	return ioread8(address + offset);
-}
-
-static inline unsigned short __tpci200_read16(void __iomem *address,
-					      unsigned long offset)
-{
-	return ioread16be(address + offset);
-}
-
-static inline unsigned int __tpci200_read32(void __iomem *address,
-					    unsigned long offset)
-{
-	return ioread32be(address + offset);
-}
-
-static inline void __tpci200_write8(unsigned char value,
-				    void __iomem *address, unsigned long offset)
-{
-	iowrite8(value, address + offset);
-}
-
-static inline void __tpci200_write16(unsigned short value,
-				     void __iomem *address,
-				     unsigned long offset)
-{
-	iowrite16be(value, address + offset);
-}
-
-static inline void __tpci200_write32(unsigned int value,
-				     void __iomem *address,
-				     unsigned long offset)
-{
-	iowrite32be(value, address + offset);
-}
-
-static struct ipack_addr_space *get_slot_address_space(struct ipack_device *dev,
-						       int space)
-{
-	struct ipack_addr_space *addr;
-
-	switch (space) {
-	case IPACK_IO_SPACE:
-		addr = &dev->io_space;
-		break;
-	case IPACK_ID_SPACE:
-		addr = &dev->id_space;
-		break;
-	case IPACK_MEM_SPACE:
-		addr = &dev->mem_space;
-		break;
-	default:
-		dev_err(&dev->dev,
-			"Slot [%d:%d] space number %d doesn't exist !\n",
-			dev->bus_nr, dev->slot, space);
-		return NULL;
-		break;
-	}
-
-	if ((addr->size == 0) || (addr->address == NULL)) {
-		dev_err(&dev->dev, "Error, slot space not mapped !\n");
-		return NULL;
-	}
-
-	return addr;
-}
-
-static int tpci200_read8(struct ipack_device *dev, int space,
-			 unsigned long offset, unsigned char *value)
-{
-	struct ipack_addr_space *addr;
-	struct tpci200_board *tpci200;
-
-	tpci200 = check_slot(dev);
-	if (tpci200 == NULL)
-		return -EINVAL;
-
-	addr = get_slot_address_space(dev, space);
-	if (addr == NULL)
-		return -EINVAL;
-
-	if (offset >= addr->size) {
-		dev_err(&dev->dev, "Error, slot space offset error !\n");
-		return -EFAULT;
-	}
-
-	*value = __tpci200_read8(addr->address, offset);
-
-	return 0;
-}
-
-static int tpci200_read16(struct ipack_device *dev, int space,
-			  unsigned long offset, unsigned short *value)
-{
-	struct ipack_addr_space *addr;
-	struct tpci200_board *tpci200;
-
-	tpci200 = check_slot(dev);
-	if (tpci200 == NULL)
-		return -EINVAL;
-
-	addr = get_slot_address_space(dev, space);
-	if (addr == NULL)
-		return -EINVAL;
-
-	if ((offset+2) >= addr->size) {
-		dev_err(&dev->dev, "Error, slot space offset error !\n");
-		return -EFAULT;
-	}
-	*value = __tpci200_read16(addr->address, offset);
-
-	return 0;
-}
-
-static int tpci200_read32(struct ipack_device *dev, int space,
-			  unsigned long offset, unsigned int *value)
-{
-	struct ipack_addr_space *addr;
-	struct tpci200_board *tpci200;
-
-	tpci200 = check_slot(dev);
-	if (tpci200 == NULL)
-		return -EINVAL;
-
-	addr = get_slot_address_space(dev, space);
-	if (addr == NULL)
-		return -EINVAL;
-
-	if ((offset+4) >= addr->size) {
-		dev_err(&dev->dev, "Error, slot space offset error !\n");
-		return -EFAULT;
-	}
-
-	*value = __tpci200_read32(addr->address, offset);
-
-	return 0;
-}
-
-static int tpci200_write8(struct ipack_device *dev, int space,
-			  unsigned long offset, unsigned char value)
-{
-	struct ipack_addr_space *addr;
-	struct tpci200_board *tpci200;
-
-	tpci200 = check_slot(dev);
-	if (tpci200 == NULL)
-		return -EINVAL;
-
-	addr = get_slot_address_space(dev, space);
-	if (addr == NULL)
-		return -EINVAL;
-
-	if (offset >= addr->size) {
-		dev_err(&dev->dev, "Error, slot space offset error !\n");
-		return -EFAULT;
-	}
-
-	__tpci200_write8(value, addr->address, offset);
-
-	return 0;
-}
-
-static int tpci200_write16(struct ipack_device *dev, int space,
-			   unsigned long offset, unsigned short value)
-{
-	struct ipack_addr_space *addr;
-	struct tpci200_board *tpci200;
-
-	tpci200 = check_slot(dev);
-	if (tpci200 == NULL)
-		return -EINVAL;
-
-	addr = get_slot_address_space(dev, space);
-	if (addr == NULL)
-		return -EINVAL;
-
-	if ((offset+2) >= addr->size) {
-		dev_err(&dev->dev, "Error, slot space offset error !\n");
-		return -EFAULT;
-	}
-
-	__tpci200_write16(value, addr->address, offset);
-
-	return 0;
-}
-
-static int tpci200_write32(struct ipack_device *dev, int space,
-			   unsigned long offset, unsigned int value)
-{
-	struct ipack_addr_space *addr;
-	struct tpci200_board *tpci200;
-
-	tpci200 = check_slot(dev);
-	if (tpci200 == NULL)
-		return -EINVAL;
-
-	addr = get_slot_address_space(dev, space);
-	if (addr == NULL)
-		return -EINVAL;
-
-	if ((offset+4) >= addr->size) {
-		dev_err(&dev->dev, "Error, slot space offset error !\n");
-		return -EFAULT;
-	}
-
-	__tpci200_write32(value, addr->address, offset);
-
-	return 0;
-}
-
 static void tpci200_unregister(struct tpci200_board *tpci200)
 {
 	int i;
@@ -749,12 +537,6 @@ static struct ipack_bus_ops tpci200_bus_ops = {
 	.unmap_space = tpci200_slot_unmap_space,
 	.request_irq = tpci200_request_irq,
 	.free_irq = tpci200_free_irq,
-	.read8 = tpci200_read8,
-	.read16 = tpci200_read16,
-	.read32 = tpci200_read32,
-	.write8 = tpci200_write8,
-	.write16 = tpci200_write16,
-	.write32 = tpci200_write32,
 	.remove_device = tpci200_slot_unregister,
 };
 
-- 
1.7.10.4


^ permalink raw reply	[flat|nested] 17+ messages in thread

* [PATCH 05/16] Staging: ipack: remove read/write operations from ipack_bus_ops
  2012-09-04 15:01 [PATCH 00/16] ipack: autoload IP module drivers Samuel Iglesias Gonsálvez
                   ` (3 preceding siblings ...)
  2012-09-04 15:01 ` [PATCH 04/16] Staging: ipack/bridges/tpci200: Remove the read/write functions from ipack_bus_ops Samuel Iglesias Gonsálvez
@ 2012-09-04 15:01 ` Samuel Iglesias Gonsálvez
  2012-09-04 15:01 ` [PATCH 06/16] Staging: ipack/devices/ipoctal: ipoctal cleanups Samuel Iglesias Gonsálvez
                   ` (10 subsequent siblings)
  15 siblings, 0 replies; 17+ messages in thread
From: Samuel Iglesias Gonsálvez @ 2012-09-04 15:01 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: devel, linux-kernel, industrypack-devel,
	Samuel Iglesias Gonsálvez, Jens Taprogge

They are not used any longer.

Signed-off-by: Jens Taprogge <jens.taprogge@taprogge.org>
Signed-off-by: Samuel Iglesias Gonsálvez <siglesias@igalia.com>
---
 drivers/staging/ipack/ipack.h |   12 ------------
 1 file changed, 12 deletions(-)

diff --git a/drivers/staging/ipack/ipack.h b/drivers/staging/ipack/ipack.h
index 8bc001e..e3609b1 100644
--- a/drivers/staging/ipack/ipack.h
+++ b/drivers/staging/ipack/ipack.h
@@ -105,12 +105,6 @@ struct ipack_driver {
  *	@unmap_space: unmap IP address space
  *	@request_irq: request IRQ
  *	@free_irq: free IRQ
- *	@read8: read unsigned char
- *	@read16: read unsigned short
- *	@read32: read unsigned int
- *	@write8: read unsigned char
- *	@write16: read unsigned short
- *	@write32: read unsigned int
  *	@remove_device: tell the bridge module that the device has been removed
  */
 struct ipack_bus_ops {
@@ -118,12 +112,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 (*read8) (struct ipack_device *dev, int space, unsigned long offset, unsigned char *value);
-	int (*read16) (struct ipack_device *dev, int space, unsigned long offset, unsigned short *value);
-	int (*read32) (struct ipack_device *dev, int space, unsigned long offset, unsigned int *value);
-	int (*write8) (struct ipack_device *dev, int space, unsigned long offset, unsigned char value);
-	int (*write16) (struct ipack_device *dev, int space, unsigned long offset, unsigned short value);
-	int (*write32) (struct ipack_device *dev, int space, unsigned long offset, unsigned int value);
 	int (*remove_device) (struct ipack_device *dev);
 };
 
-- 
1.7.10.4


^ permalink raw reply	[flat|nested] 17+ messages in thread

* [PATCH 06/16] Staging: ipack/devices/ipoctal: ipoctal cleanups.
  2012-09-04 15:01 [PATCH 00/16] ipack: autoload IP module drivers Samuel Iglesias Gonsálvez
                   ` (4 preceding siblings ...)
  2012-09-04 15:01 ` [PATCH 05/16] Staging: ipack: remove read/write operations " Samuel Iglesias Gonsálvez
@ 2012-09-04 15:01 ` Samuel Iglesias Gonsálvez
  2012-09-04 15:01 ` [PATCH 07/16] Staging: ipack/devices/ipoctal: Tidy up ipoctal some more Samuel Iglesias Gonsálvez
                   ` (9 subsequent siblings)
  15 siblings, 0 replies; 17+ messages in thread
From: Samuel Iglesias Gonsálvez @ 2012-09-04 15:01 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>

Define memory address space, fix sparse warnings and mark the structs
reflecting hardware memory layout "packed" to be on the safe side.

Signed-off-by: Jens Taprogge <jens.taprogge@taprogge.org>
Signed-off-by: Samuel Iglesias Gonsálvez <siglesias@igalia.com>
---
 drivers/staging/ipack/devices/ipoctal.c |   14 ++---
 drivers/staging/ipack/devices/scc2698.h |   96 +++++++++++++++----------------
 2 files changed, 55 insertions(+), 55 deletions(-)

diff --git a/drivers/staging/ipack/devices/ipoctal.c b/drivers/staging/ipack/devices/ipoctal.c
index 085b6c0..76f8427 100644
--- a/drivers/staging/ipack/devices/ipoctal.c
+++ b/drivers/staging/ipack/devices/ipoctal.c
@@ -40,8 +40,8 @@ struct ipoctal {
 	struct list_head		list;
 	struct ipack_device		*dev;
 	unsigned int			board_id;
-	struct scc2698_channel		*chan_regs;
-	struct scc2698_block		*block_regs;
+	struct scc2698_channel __iomem	*chan_regs;
+	struct scc2698_block __iomem	*block_regs;
 	struct ipoctal_stats		chan_stats[NR_CHANNELS];
 	unsigned int			nb_bytes[NR_CHANNELS];
 	unsigned int			count_wr[NR_CHANNELS];
@@ -59,8 +59,8 @@ struct ipoctal {
 static LIST_HEAD(ipoctal_list);
 
 static inline void ipoctal_write_io_reg(struct ipoctal *ipoctal,
-					unsigned char *dest,
-					unsigned char value)
+					u8 __iomem *dest,
+					u8 value)
 {
 	iowrite8(value, dest);
 }
@@ -73,7 +73,7 @@ static inline void ipoctal_write_cr_cmd(struct ipoctal *ipoctal,
 }
 
 static inline unsigned char ipoctal_read_io_reg(struct ipoctal *ipoctal,
-						unsigned char *src)
+						u8 __iomem *src)
 {
 	return ioread8(src);
 }
@@ -391,9 +391,9 @@ static int ipoctal_inst_slot(struct ipoctal *ipoctal, unsigned int bus_nr,
 
 	/* Save the virtual address to access the registers easily */
 	ipoctal->chan_regs =
-		(struct scc2698_channel *) ipoctal->dev->io_space.address;
+		(struct scc2698_channel __iomem *) ipoctal->dev->io_space.address;
 	ipoctal->block_regs =
-		(struct scc2698_block *) ipoctal->dev->io_space.address;
+		(struct scc2698_block __iomem *) ipoctal->dev->io_space.address;
 
 	/* Disable RX and TX before touching anything */
 	for (i = 0; i < NR_CHANNELS ; i++) {
diff --git a/drivers/staging/ipack/devices/scc2698.h b/drivers/staging/ipack/devices/scc2698.h
index 47f6269..fcab427 100644
--- a/drivers/staging/ipack/devices/scc2698.h
+++ b/drivers/staging/ipack/devices/scc2698.h
@@ -23,21 +23,21 @@
 struct scc2698_channel {
 	union {
 		struct {
-			unsigned char d0, mr;  /* Mode register 1/2*/
-			unsigned char d1, sr;  /* Status register */
-			unsigned char d2, r1;  /* reserved */
-			unsigned char d3, rhr; /* Receive holding register (R) */
-			unsigned char junk[8]; /* other crap for block control */
-		} r; /* Read access */
+			u8 d0, mr;  /* Mode register 1/2*/
+			u8 d1, sr;  /* Status register */
+			u8 d2, r1;  /* reserved */
+			u8 d3, rhr; /* Receive holding register (R) */
+			u8 junk[8]; /* other crap for block control */
+		} __packed r; /* Read access */
 		struct {
-			unsigned char d0, mr;  /* Mode register 1/2 */
-			unsigned char d1, csr; /* Clock select register */
-			unsigned char d2, cr;  /* Command register */
-			unsigned char d3, thr; /* Transmit holding register */
-			unsigned char junk[8]; /* other crap for block control */
-		} w; /* Write access */
+			u8 d0, mr;  /* Mode register 1/2 */
+			u8 d1, csr; /* Clock select register */
+			u8 d2, cr;  /* Command register */
+			u8 d3, thr; /* Transmit holding register */
+			u8 junk[8]; /* other crap for block control */
+		} __packed w; /* Write access */
 	} u;
-};
+} __packed;
 
 /*
  * struct scc2698_block - Block access to scc2698 IO
@@ -50,43 +50,43 @@ struct scc2698_channel {
 struct scc2698_block {
 	union {
 		struct {
-			unsigned char d0, mra;  /* Mode register 1/2 (a) */
-			unsigned char d1, sra;  /* Status register (a) */
-			unsigned char d2, r1;   /* reserved */
-			unsigned char d3, rhra; /* Receive holding register (a) */
-			unsigned char d4, ipcr; /* Input port change register of block */
-			unsigned char d5, isr;  /* Interrupt status register of block */
-			unsigned char d6, ctur; /* Counter timer upper register of block */
-			unsigned char d7, ctlr; /* Counter timer lower register of block */
-			unsigned char d8, mrb;  /* Mode register 1/2 (b) */
-			unsigned char d9, srb;  /* Status register (b) */
-			unsigned char da, r2;   /* reserved */
-			unsigned char db, rhrb; /* Receive holding register (b) */
-			unsigned char dc, r3;   /* reserved */
-			unsigned char dd, ip;   /* Input port register of block */
-			unsigned char de, ctg;  /* Start counter timer of block */
-			unsigned char df, cts;  /* Stop counter timer of block */
-		} r; /* Read access */
+			u8 d0, mra;  /* Mode register 1/2 (a) */
+			u8 d1, sra;  /* Status register (a) */
+			u8 d2, r1;   /* reserved */
+			u8 d3, rhra; /* Receive holding register (a) */
+			u8 d4, ipcr; /* Input port change register of block */
+			u8 d5, isr;  /* Interrupt status register of block */
+			u8 d6, ctur; /* Counter timer upper register of block */
+			u8 d7, ctlr; /* Counter timer lower register of block */
+			u8 d8, mrb;  /* Mode register 1/2 (b) */
+			u8 d9, srb;  /* Status register (b) */
+			u8 da, r2;   /* reserved */
+			u8 db, rhrb; /* Receive holding register (b) */
+			u8 dc, r3;   /* reserved */
+			u8 dd, ip;   /* Input port register of block */
+			u8 de, ctg;  /* Start counter timer of block */
+			u8 df, cts;  /* Stop counter timer of block */
+		} __packed r; /* Read access */
 		struct {
-			unsigned char d0, mra;  /* Mode register 1/2 (a) */
-			unsigned char d1, csra; /* Clock select register (a) */
-			unsigned char d2, cra;  /* Command register (a) */
-			unsigned char d3, thra; /* Transmit holding register (a) */
-			unsigned char d4, acr;  /* Auxiliary control register of block */
-			unsigned char d5, imr;  /* Interrupt mask register of block  */
-			unsigned char d6, ctu;  /* Counter timer upper register of block */
-			unsigned char d7, ctl;  /* Counter timer lower register of block */
-			unsigned char d8, mrb;  /* Mode register 1/2 (b) */
-			unsigned char d9, csrb; /* Clock select register (a) */
-			unsigned char da, crb;  /* Command register (b) */
-			unsigned char db, thrb; /* Transmit holding register (b) */
-			unsigned char dc, r1;   /* reserved */
-			unsigned char dd, opcr; /* Output port configuration register of block */
-			unsigned char de, r2;   /* reserved */
-			unsigned char df, r3;   /* reserved */
-		} w; /* Write access */
+			u8 d0, mra;  /* Mode register 1/2 (a) */
+			u8 d1, csra; /* Clock select register (a) */
+			u8 d2, cra;  /* Command register (a) */
+			u8 d3, thra; /* Transmit holding register (a) */
+			u8 d4, acr;  /* Auxiliary control register of block */
+			u8 d5, imr;  /* Interrupt mask register of block  */
+			u8 d6, ctu;  /* Counter timer upper register of block */
+			u8 d7, ctl;  /* Counter timer lower register of block */
+			u8 d8, mrb;  /* Mode register 1/2 (b) */
+			u8 d9, csrb; /* Clock select register (a) */
+			u8 da, crb;  /* Command register (b) */
+			u8 db, thrb; /* Transmit holding register (b) */
+			u8 dc, r1;   /* reserved */
+			u8 dd, opcr; /* Output port configuration register of block */
+			u8 de, r2;   /* reserved */
+			u8 df, r3;   /* reserved */
+		} __packed w; /* Write access */
 	} u;
-} ;
+} __packed;
 
 #define MR1_CHRL_5_BITS             (0x0 << 0)
 #define MR1_CHRL_6_BITS             (0x1 << 0)
-- 
1.7.10.4


^ permalink raw reply	[flat|nested] 17+ messages in thread

* [PATCH 07/16] Staging: ipack/devices/ipoctal: Tidy up ipoctal some more.
  2012-09-04 15:01 [PATCH 00/16] ipack: autoload IP module drivers Samuel Iglesias Gonsálvez
                   ` (5 preceding siblings ...)
  2012-09-04 15:01 ` [PATCH 06/16] Staging: ipack/devices/ipoctal: ipoctal cleanups Samuel Iglesias Gonsálvez
@ 2012-09-04 15:01 ` Samuel Iglesias Gonsálvez
  2012-09-04 15:01 ` [PATCH 08/16] Staging: ipack: implement ipack device table Samuel Iglesias Gonsálvez
                   ` (8 subsequent siblings)
  15 siblings, 0 replies; 17+ messages in thread
From: Samuel Iglesias Gonsálvez @ 2012-09-04 15:01 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>

No need to have a struct when it has only one field.

Signed-off-by: Jens Taprogge <jens.taprogge@taprogge.org>
Signed-off-by: Samuel Iglesias Gonsálvez <siglesias@igalia.com>
---
 drivers/staging/ipack/devices/ipoctal.c |   82 +++++++++++-----------
 drivers/staging/ipack/devices/scc2698.h |  116 +++++++++++++++----------------
 2 files changed, 97 insertions(+), 101 deletions(-)

diff --git a/drivers/staging/ipack/devices/ipoctal.c b/drivers/staging/ipack/devices/ipoctal.c
index 76f8427..c1d0c00 100644
--- a/drivers/staging/ipack/devices/ipoctal.c
+++ b/drivers/staging/ipack/devices/ipoctal.c
@@ -40,8 +40,8 @@ struct ipoctal {
 	struct list_head		list;
 	struct ipack_device		*dev;
 	unsigned int			board_id;
-	struct scc2698_channel __iomem	*chan_regs;
-	struct scc2698_block __iomem	*block_regs;
+	union scc2698_channel __iomem	*chan_regs;
+	union scc2698_block __iomem	*block_regs;
 	struct ipoctal_stats		chan_stats[NR_CHANNELS];
 	unsigned int			nb_bytes[NR_CHANNELS];
 	unsigned int			count_wr[NR_CHANNELS];
@@ -103,7 +103,7 @@ static int ipoctal_port_activate(struct tty_port *port, struct tty_struct *tty)
 		return -ENODEV;
 	}
 
-	ipoctal_write_io_reg(ipoctal, &ipoctal->chan_regs[channel].u.w.cr,
+	ipoctal_write_io_reg(ipoctal, &ipoctal->chan_regs[channel].w.cr,
 			     CR_ENABLE_RX);
 	return 0;
 }
@@ -216,9 +216,9 @@ static int ipoctal_irq_handler(void *arg)
 		 */
 		block = channel / 2;
 		isr = ipoctal_read_io_reg(ipoctal,
-					  &ipoctal->block_regs[block].u.r.isr);
+					  &ipoctal->block_regs[block].r.isr);
 		sr = ipoctal_read_io_reg(ipoctal,
-					 &ipoctal->chan_regs[channel].u.r.sr);
+					 &ipoctal->chan_regs[channel].r.sr);
 
 		if ((channel % 2) == 1) {
 			isr_tx_rdy = isr & ISR_TxRDY_B;
@@ -235,13 +235,13 @@ static int ipoctal_irq_handler(void *arg)
 		    (sr & SR_TX_EMPTY) &&
 		    (ipoctal->nb_bytes[channel] == 0)) {
 			ipoctal_write_io_reg(ipoctal,
-					     &ipoctal->chan_regs[channel].u.w.cr,
+					     &ipoctal->chan_regs[channel].w.cr,
 					     CR_DISABLE_TX);
 			ipoctal_write_cr_cmd(ipoctal,
-					     &ipoctal->chan_regs[channel].u.w.cr,
+					     &ipoctal->chan_regs[channel].w.cr,
 					     CR_CMD_NEGATE_RTSN);
 			ipoctal_write_io_reg(ipoctal,
-					     &ipoctal->chan_regs[channel].u.w.cr,
+					     &ipoctal->chan_regs[channel].w.cr,
 					     CR_ENABLE_RX);
 			ipoctal->write = 1;
 			wake_up_interruptible(&ipoctal->queue[channel]);
@@ -250,13 +250,13 @@ static int ipoctal_irq_handler(void *arg)
 		/* RX data */
 		if (isr_rx_rdy && (sr & SR_RX_READY)) {
 			value = ipoctal_read_io_reg(ipoctal,
-						    &ipoctal->chan_regs[channel].u.r.rhr);
+						    &ipoctal->chan_regs[channel].r.rhr);
 			flag = TTY_NORMAL;
 
 			/* Error: count statistics */
 			if (sr & SR_ERROR) {
 				ipoctal_write_cr_cmd(ipoctal,
-						     &ipoctal->chan_regs[channel].u.w.cr,
+						     &ipoctal->chan_regs[channel].w.cr,
 						     CR_CMD_RESET_ERR_STATUS);
 
 				if (sr & SR_OVERRUN_ERROR) {
@@ -293,7 +293,7 @@ static int ipoctal_irq_handler(void *arg)
 
 			value = ipoctal->tty_port[channel].xmit_buf[*pointer_write];
 			ipoctal_write_io_reg(ipoctal,
-					     &ipoctal->chan_regs[channel].u.w.thr,
+					     &ipoctal->chan_regs[channel].w.thr,
 					     value);
 			ipoctal->chan_stats[channel].tx++;
 			ipoctal->count_wr[channel]++;
@@ -391,40 +391,40 @@ static int ipoctal_inst_slot(struct ipoctal *ipoctal, unsigned int bus_nr,
 
 	/* Save the virtual address to access the registers easily */
 	ipoctal->chan_regs =
-		(struct scc2698_channel __iomem *) ipoctal->dev->io_space.address;
+		(union scc2698_channel __iomem *) ipoctal->dev->io_space.address;
 	ipoctal->block_regs =
-		(struct scc2698_block __iomem *) ipoctal->dev->io_space.address;
+		(union scc2698_block __iomem *) ipoctal->dev->io_space.address;
 
 	/* Disable RX and TX before touching anything */
 	for (i = 0; i < NR_CHANNELS ; i++) {
-		ipoctal_write_io_reg(ipoctal, &ipoctal->chan_regs[i].u.w.cr,
+		ipoctal_write_io_reg(ipoctal, &ipoctal->chan_regs[i].w.cr,
 				     CR_DISABLE_RX | CR_DISABLE_TX);
-		ipoctal_write_cr_cmd(ipoctal, &ipoctal->chan_regs[i].u.w.cr,
+		ipoctal_write_cr_cmd(ipoctal, &ipoctal->chan_regs[i].w.cr,
 				     CR_CMD_RESET_RX);
-		ipoctal_write_cr_cmd(ipoctal, &ipoctal->chan_regs[i].u.w.cr,
+		ipoctal_write_cr_cmd(ipoctal, &ipoctal->chan_regs[i].w.cr,
 				     CR_CMD_RESET_TX);
 		ipoctal_write_io_reg(ipoctal,
-				     &ipoctal->chan_regs[i].u.w.mr,
+				     &ipoctal->chan_regs[i].w.mr,
 				     MR1_CHRL_8_BITS | MR1_ERROR_CHAR |
 				     MR1_RxINT_RxRDY); /* mr1 */
 		ipoctal_write_io_reg(ipoctal,
-				     &ipoctal->chan_regs[i].u.w.mr,
+				     &ipoctal->chan_regs[i].w.mr,
 				     0); /* mr2 */
 		ipoctal_write_io_reg(ipoctal,
-				     &ipoctal->chan_regs[i].u.w.csr,
+				     &ipoctal->chan_regs[i].w.csr,
 				     TX_CLK_9600  | RX_CLK_9600);
 	}
 
 	for (i = 0; i < IP_OCTAL_NB_BLOCKS; i++) {
 		ipoctal_write_io_reg(ipoctal,
-				     &ipoctal->block_regs[i].u.w.acr,
+				     &ipoctal->block_regs[i].w.acr,
 				     ACR_BRG_SET2);
 		ipoctal_write_io_reg(ipoctal,
-				     &ipoctal->block_regs[i].u.w.opcr,
+				     &ipoctal->block_regs[i].w.opcr,
 				     OPCR_MPP_OUTPUT | OPCR_MPOa_RTSN |
 				     OPCR_MPOb_RTSN);
 		ipoctal_write_io_reg(ipoctal,
-				     &ipoctal->block_regs[i].u.w.imr,
+				     &ipoctal->block_regs[i].w.imr,
 				     IMR_TxRDY_A | IMR_RxRDY_FFULL_A |
 				     IMR_DELTA_BREAK_A | IMR_TxRDY_B |
 				     IMR_RxRDY_FFULL_B | IMR_DELTA_BREAK_B);
@@ -495,7 +495,7 @@ static int ipoctal_inst_slot(struct ipoctal *ipoctal, unsigned int bus_nr,
 		 * Enable again the RX. TX will be enabled when
 		 * there is something to send
 		 */
-		ipoctal_write_io_reg(ipoctal, &ipoctal->chan_regs[i].u.w.cr,
+		ipoctal_write_io_reg(ipoctal, &ipoctal->chan_regs[i].w.cr,
 				     CR_ENABLE_RX);
 	}
 
@@ -545,10 +545,10 @@ static int ipoctal_write(struct ipoctal *ipoctal, unsigned int channel,
 	/* As the IP-OCTAL 485 only supports half duplex, do it manually */
 	if (ipoctal->board_id == IP_OCTAL_485_ID) {
 		ipoctal_write_io_reg(ipoctal,
-				     &ipoctal->chan_regs[channel].u.w.cr,
+				     &ipoctal->chan_regs[channel].w.cr,
 				     CR_DISABLE_RX);
 		ipoctal_write_cr_cmd(ipoctal,
-				     &ipoctal->chan_regs[channel].u.w.cr,
+				     &ipoctal->chan_regs[channel].w.cr,
 				     CR_CMD_ASSERT_RTSN);
 	}
 
@@ -557,11 +557,11 @@ static int ipoctal_write(struct ipoctal *ipoctal, unsigned int channel,
 	 * operations
 	 */
 	ipoctal_write_io_reg(ipoctal,
-			     &ipoctal->chan_regs[channel].u.w.cr,
+			     &ipoctal->chan_regs[channel].w.cr,
 			     CR_ENABLE_TX);
 	wait_event_interruptible(ipoctal->queue[channel], ipoctal->write);
 	ipoctal_write_io_reg(ipoctal,
-			     &ipoctal->chan_regs[channel].u.w.cr,
+			     &ipoctal->chan_regs[channel].w.cr,
 			     CR_DISABLE_TX);
 
 	ipoctal->write = 0;
@@ -607,15 +607,15 @@ static void ipoctal_set_termios(struct tty_struct *tty,
 	cflag = tty->termios->c_cflag;
 
 	/* Disable and reset everything before change the setup */
-	ipoctal_write_io_reg(ipoctal, &ipoctal->chan_regs[channel].u.w.cr,
+	ipoctal_write_io_reg(ipoctal, &ipoctal->chan_regs[channel].w.cr,
 			     CR_DISABLE_RX | CR_DISABLE_TX);
-	ipoctal_write_cr_cmd(ipoctal, &ipoctal->chan_regs[channel].u.w.cr,
+	ipoctal_write_cr_cmd(ipoctal, &ipoctal->chan_regs[channel].w.cr,
 			     CR_CMD_RESET_RX);
-	ipoctal_write_cr_cmd(ipoctal, &ipoctal->chan_regs[channel].u.w.cr,
+	ipoctal_write_cr_cmd(ipoctal, &ipoctal->chan_regs[channel].w.cr,
 			     CR_CMD_RESET_TX);
-	ipoctal_write_cr_cmd(ipoctal, &ipoctal->chan_regs[channel].u.w.cr,
+	ipoctal_write_cr_cmd(ipoctal, &ipoctal->chan_regs[channel].w.cr,
 			     CR_CMD_RESET_ERR_STATUS);
-	ipoctal_write_cr_cmd(ipoctal, &ipoctal->chan_regs[channel].u.w.cr,
+	ipoctal_write_cr_cmd(ipoctal, &ipoctal->chan_regs[channel].w.cr,
 			     CR_CMD_RESET_MR);
 
 	/* Set Bits per chars */
@@ -729,12 +729,12 @@ static void ipoctal_set_termios(struct tty_struct *tty,
 	mr1 |= MR1_RxINT_RxRDY;
 
 	/* Write the control registers */
-	ipoctal_write_io_reg(ipoctal, &ipoctal->chan_regs[channel].u.w.mr, mr1);
-	ipoctal_write_io_reg(ipoctal, &ipoctal->chan_regs[channel].u.w.mr, mr2);
-	ipoctal_write_io_reg(ipoctal, &ipoctal->chan_regs[channel].u.w.csr, csr);
+	ipoctal_write_io_reg(ipoctal, &ipoctal->chan_regs[channel].w.mr, mr1);
+	ipoctal_write_io_reg(ipoctal, &ipoctal->chan_regs[channel].w.mr, mr2);
+	ipoctal_write_io_reg(ipoctal, &ipoctal->chan_regs[channel].w.csr, csr);
 
 	/* Enable again the RX */
-	ipoctal_write_io_reg(ipoctal, &ipoctal->chan_regs[channel].u.w.cr,
+	ipoctal_write_io_reg(ipoctal, &ipoctal->chan_regs[channel].w.cr,
 			     CR_ENABLE_RX);
 }
 
@@ -755,15 +755,15 @@ static void ipoctal_hangup(struct tty_struct *tty)
 
 	tty_port_hangup(&ipoctal->tty_port[channel]);
 
-	ipoctal_write_io_reg(ipoctal, &ipoctal->chan_regs[channel].u.w.cr,
+	ipoctal_write_io_reg(ipoctal, &ipoctal->chan_regs[channel].w.cr,
 			     CR_DISABLE_RX | CR_DISABLE_TX);
-	ipoctal_write_cr_cmd(ipoctal, &ipoctal->chan_regs[channel].u.w.cr,
+	ipoctal_write_cr_cmd(ipoctal, &ipoctal->chan_regs[channel].w.cr,
 			     CR_CMD_RESET_RX);
-	ipoctal_write_cr_cmd(ipoctal, &ipoctal->chan_regs[channel].u.w.cr,
+	ipoctal_write_cr_cmd(ipoctal, &ipoctal->chan_regs[channel].w.cr,
 			     CR_CMD_RESET_TX);
-	ipoctal_write_cr_cmd(ipoctal, &ipoctal->chan_regs[channel].u.w.cr,
+	ipoctal_write_cr_cmd(ipoctal, &ipoctal->chan_regs[channel].w.cr,
 			     CR_CMD_RESET_ERR_STATUS);
-	ipoctal_write_cr_cmd(ipoctal, &ipoctal->chan_regs[channel].u.w.cr,
+	ipoctal_write_cr_cmd(ipoctal, &ipoctal->chan_regs[channel].w.cr,
 			     CR_CMD_RESET_MR);
 
 	clear_bit(ASYNCB_INITIALIZED, &ipoctal->tty_port[channel].flags);
diff --git a/drivers/staging/ipack/devices/scc2698.h b/drivers/staging/ipack/devices/scc2698.h
index fcab427..223838a 100644
--- a/drivers/staging/ipack/devices/scc2698.h
+++ b/drivers/staging/ipack/devices/scc2698.h
@@ -15,78 +15,74 @@
 #define SCC2698_H_
 
 /*
- * struct scc2698_channel - Channel access to scc2698 IO
+ * union scc2698_channel - Channel access to scc2698 IO
  *
  * dn value are only spacer.
  *
  */
-struct scc2698_channel {
-	union {
-		struct {
-			u8 d0, mr;  /* Mode register 1/2*/
-			u8 d1, sr;  /* Status register */
-			u8 d2, r1;  /* reserved */
-			u8 d3, rhr; /* Receive holding register (R) */
-			u8 junk[8]; /* other crap for block control */
-		} __packed r; /* Read access */
-		struct {
-			u8 d0, mr;  /* Mode register 1/2 */
-			u8 d1, csr; /* Clock select register */
-			u8 d2, cr;  /* Command register */
-			u8 d3, thr; /* Transmit holding register */
-			u8 junk[8]; /* other crap for block control */
-		} __packed w; /* Write access */
-	} u;
-} __packed;
+union scc2698_channel {
+	struct {
+		u8 d0, mr;  /* Mode register 1/2*/
+		u8 d1, sr;  /* Status register */
+		u8 d2, r1;  /* reserved */
+		u8 d3, rhr; /* Receive holding register (R) */
+		u8 junk[8]; /* other crap for block control */
+	} __packed r; /* Read access */
+	struct {
+		u8 d0, mr;  /* Mode register 1/2 */
+		u8 d1, csr; /* Clock select register */
+		u8 d2, cr;  /* Command register */
+		u8 d3, thr; /* Transmit holding register */
+		u8 junk[8]; /* other crap for block control */
+	} __packed w; /* Write access */
+};
 
 /*
- * struct scc2698_block - Block access to scc2698 IO
+ * union scc2698_block - Block access to scc2698 IO
  *
  * The scc2698 contain 4 block.
  * Each block containt two channel a and b.
  * dn value are only spacer.
  *
  */
-struct scc2698_block {
-	union {
-		struct {
-			u8 d0, mra;  /* Mode register 1/2 (a) */
-			u8 d1, sra;  /* Status register (a) */
-			u8 d2, r1;   /* reserved */
-			u8 d3, rhra; /* Receive holding register (a) */
-			u8 d4, ipcr; /* Input port change register of block */
-			u8 d5, isr;  /* Interrupt status register of block */
-			u8 d6, ctur; /* Counter timer upper register of block */
-			u8 d7, ctlr; /* Counter timer lower register of block */
-			u8 d8, mrb;  /* Mode register 1/2 (b) */
-			u8 d9, srb;  /* Status register (b) */
-			u8 da, r2;   /* reserved */
-			u8 db, rhrb; /* Receive holding register (b) */
-			u8 dc, r3;   /* reserved */
-			u8 dd, ip;   /* Input port register of block */
-			u8 de, ctg;  /* Start counter timer of block */
-			u8 df, cts;  /* Stop counter timer of block */
-		} __packed r; /* Read access */
-		struct {
-			u8 d0, mra;  /* Mode register 1/2 (a) */
-			u8 d1, csra; /* Clock select register (a) */
-			u8 d2, cra;  /* Command register (a) */
-			u8 d3, thra; /* Transmit holding register (a) */
-			u8 d4, acr;  /* Auxiliary control register of block */
-			u8 d5, imr;  /* Interrupt mask register of block  */
-			u8 d6, ctu;  /* Counter timer upper register of block */
-			u8 d7, ctl;  /* Counter timer lower register of block */
-			u8 d8, mrb;  /* Mode register 1/2 (b) */
-			u8 d9, csrb; /* Clock select register (a) */
-			u8 da, crb;  /* Command register (b) */
-			u8 db, thrb; /* Transmit holding register (b) */
-			u8 dc, r1;   /* reserved */
-			u8 dd, opcr; /* Output port configuration register of block */
-			u8 de, r2;   /* reserved */
-			u8 df, r3;   /* reserved */
-		} __packed w; /* Write access */
-	} u;
-} __packed;
+union scc2698_block {
+	struct {
+		u8 d0, mra;  /* Mode register 1/2 (a) */
+		u8 d1, sra;  /* Status register (a) */
+		u8 d2, r1;   /* reserved */
+		u8 d3, rhra; /* Receive holding register (a) */
+		u8 d4, ipcr; /* Input port change register of block */
+		u8 d5, isr;  /* Interrupt status register of block */
+		u8 d6, ctur; /* Counter timer upper register of block */
+		u8 d7, ctlr; /* Counter timer lower register of block */
+		u8 d8, mrb;  /* Mode register 1/2 (b) */
+		u8 d9, srb;  /* Status register (b) */
+		u8 da, r2;   /* reserved */
+		u8 db, rhrb; /* Receive holding register (b) */
+		u8 dc, r3;   /* reserved */
+		u8 dd, ip;   /* Input port register of block */
+		u8 de, ctg;  /* Start counter timer of block */
+		u8 df, cts;  /* Stop counter timer of block */
+	} __packed r; /* Read access */
+	struct {
+		u8 d0, mra;  /* Mode register 1/2 (a) */
+		u8 d1, csra; /* Clock select register (a) */
+		u8 d2, cra;  /* Command register (a) */
+		u8 d3, thra; /* Transmit holding register (a) */
+		u8 d4, acr;  /* Auxiliary control register of block */
+		u8 d5, imr;  /* Interrupt mask register of block  */
+		u8 d6, ctu;  /* Counter timer upper register of block */
+		u8 d7, ctl;  /* Counter timer lower register of block */
+		u8 d8, mrb;  /* Mode register 1/2 (b) */
+		u8 d9, csrb; /* Clock select register (a) */
+		u8 da, crb;  /* Command register (b) */
+		u8 db, thrb; /* Transmit holding register (b) */
+		u8 dc, r1;   /* reserved */
+		u8 dd, opcr; /* Output port configuration register of block */
+		u8 de, r2;   /* reserved */
+		u8 df, r3;   /* reserved */
+	} __packed w; /* Write access */
+};
 
 #define MR1_CHRL_5_BITS             (0x0 << 0)
 #define MR1_CHRL_6_BITS             (0x1 << 0)
-- 
1.7.10.4


^ permalink raw reply	[flat|nested] 17+ messages in thread

* [PATCH 08/16] Staging: ipack: implement ipack device table.
  2012-09-04 15:01 [PATCH 00/16] ipack: autoload IP module drivers Samuel Iglesias Gonsálvez
                   ` (6 preceding siblings ...)
  2012-09-04 15:01 ` [PATCH 07/16] Staging: ipack/devices/ipoctal: Tidy up ipoctal some more Samuel Iglesias Gonsálvez
@ 2012-09-04 15:01 ` Samuel Iglesias Gonsálvez
  2012-09-04 15:01 ` [PATCH 09/16] Staging: ipack: Read the ID space during device registration Samuel Iglesias Gonsálvez
                   ` (7 subsequent siblings)
  15 siblings, 0 replies; 17+ messages in thread
From: Samuel Iglesias Gonsálvez @ 2012-09-04 15:01 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>

The modaliases look like ipack:fXvNdM, where X is the format version (8
bit) and N and M are the vendor and device ID represented as 32 bit
hexadecimal numbers each. Using 32 bits allows us to define IPACK_ANY_ID
as (~0) without interfering with the valid ids.

The resulting modalias string for ipoctal.ko looks like this (once
ipoctal provides a device table):
alias:          ipack:f01v000000F0d00000048*
alias:          ipack:f01v000000F0d0000002A*
alias:          ipack:f01v000000F0d00000022*
(output from modinfo)

Signed-off-by: Jens Taprogge <jens.taprogge@taprogge.org>
Signed-off-by: Samuel Iglesias Gonsálvez <siglesias@igalia.com>
---
 drivers/staging/ipack/ipack.h     |   26 ++++++++++++++++++++++++++
 drivers/staging/ipack/ipack_ids.h |   27 +++++++++++++++++++++++++++
 include/linux/mod_devicetable.h   |    7 +++++++
 scripts/mod/file2alias.c          |   15 +++++++++++++++
 4 files changed, 75 insertions(+)
 create mode 100644 drivers/staging/ipack/ipack_ids.h

diff --git a/drivers/staging/ipack/ipack.h b/drivers/staging/ipack/ipack.h
index e3609b1..703142d 100644
--- a/drivers/staging/ipack/ipack.h
+++ b/drivers/staging/ipack/ipack.h
@@ -9,6 +9,7 @@
  * Software Foundation; version 2 of the License.
  */
 
+#include <linux/mod_devicetable.h>
 #include <linux/device.h>
 
 #define IPACK_IDPROM_OFFSET_I			0x01
@@ -95,6 +96,7 @@ struct ipack_driver_ops {
  */
 struct ipack_driver {
 	struct device_driver driver;
+	const struct ipack_device_id *id_table;
 	struct ipack_driver_ops *ops;
 };
 
@@ -169,3 +171,27 @@ void ipack_driver_unregister(struct ipack_driver *edrv);
  */
 struct ipack_device *ipack_device_register(struct ipack_bus_device *bus, int slot, int irqv);
 void ipack_device_unregister(struct ipack_device *dev);
+
+/**
+ * DEFINE_IPACK_DEVICE_TABLE - macro used to describe a IndustryPack table
+ * @_table: device table name
+ *
+ * This macro is used to create a struct ipack_device_id array (a device table)
+ * in a generic manner.
+ */
+#define DEFINE_IPACK_DEVICE_TABLE(_table) \
+	const struct ipack_device_id _table[] __devinitconst
+
+/**
+ * IPACK_DEVICE - macro used to describe a specific IndustryPack device
+ * @_format: the format version (currently either 1 or 2, 8 bit value)
+ * @vend:    the 8 or 24 bit IndustryPack Vendor ID
+ * @dev:     the 8 or 16  bit IndustryPack Device ID
+ *
+ * This macro is used to create a struct ipack_device_id that matches a specific
+ * device.
+ */
+#define IPACK_DEVICE(_format, vend, dev) \
+	 .format = (_format), \
+	 .vendor = (vend), \
+	 .device = (dev)
diff --git a/drivers/staging/ipack/ipack_ids.h b/drivers/staging/ipack/ipack_ids.h
new file mode 100644
index 0000000..ba85ec5
--- /dev/null
+++ b/drivers/staging/ipack/ipack_ids.h
@@ -0,0 +1,27 @@
+/*
+ * IndustryPack Fromat, Vendor and Device IDs.
+ */
+
+/* ID section format versions */
+#define IPACK_ID_VERSION_INVALID	0x00
+#define IPACK_ID_VERSION_1		0x01
+#define IPACK_ID_VERSION_2		0x02
+
+/* Vendors and devices. Sort key: vendor first, device next. */
+#define IPACK1_VENDOR_ID_RESERVED1	0x00
+#define IPACK1_VENDOR_ID_RESERVED2	0xFF
+#define IPACK1_VENDOR_ID_UNREGISTRED01	0x01
+#define IPACK1_VENDOR_ID_UNREGISTRED02	0x02
+#define IPACK1_VENDOR_ID_UNREGISTRED03	0x03
+#define IPACK1_VENDOR_ID_UNREGISTRED04	0x04
+#define IPACK1_VENDOR_ID_UNREGISTRED05	0x05
+#define IPACK1_VENDOR_ID_UNREGISTRED06	0x06
+#define IPACK1_VENDOR_ID_UNREGISTRED07	0x07
+#define IPACK1_VENDOR_ID_UNREGISTRED08	0x08
+#define IPACK1_VENDOR_ID_UNREGISTRED09	0x09
+#define IPACK1_VENDOR_ID_UNREGISTRED10	0x0A
+#define IPACK1_VENDOR_ID_UNREGISTRED11	0x0B
+#define IPACK1_VENDOR_ID_UNREGISTRED12	0x0C
+#define IPACK1_VENDOR_ID_UNREGISTRED13	0x0D
+#define IPACK1_VENDOR_ID_UNREGISTRED14	0x0E
+#define IPACK1_VENDOR_ID_UNREGISTRED15	0x0F
diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h
index 6955045..999c4c2 100644
--- a/include/linux/mod_devicetable.h
+++ b/include/linux/mod_devicetable.h
@@ -600,4 +600,11 @@ struct x86_cpu_id {
 #define X86_MODEL_ANY  0
 #define X86_FEATURE_ANY 0	/* Same as FPU, you can't test for that */
 
+#define IPACK_ANY_ID (~0)
+struct ipack_device_id {
+	__u8  format;			/* Format version or IPACK_ANY_ID */
+	__u32 vendor;			/* Vendor ID or IPACK_ANY_ID */
+	__u32 device;			/* Device ID or IPACK_ANY_ID */
+};
+
 #endif /* LINUX_MOD_DEVICETABLE_H */
diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c
index 7ed6864..3c22bda 100644
--- a/scripts/mod/file2alias.c
+++ b/scripts/mod/file2alias.c
@@ -966,6 +966,21 @@ static int do_isapnp_entry(const char *filename,
 }
 ADD_TO_DEVTABLE("isapnp", struct isapnp_device_id, do_isapnp_entry);
 
+/* Looks like: "ipack:fNvNdN". */
+static int do_ipack_entry(const char *filename,
+			  struct ipack_device_id *id, char *alias)
+{
+	id->vendor = TO_NATIVE(id->vendor);
+	id->device = TO_NATIVE(id->device);
+	strcpy(alias, "ipack:");
+	ADD(alias, "f", id->format != IPACK_ANY_ID, id->format);
+	ADD(alias, "v", id->vendor != IPACK_ANY_ID, id->vendor);
+	ADD(alias, "d", id->device != IPACK_ANY_ID, id->device);
+	add_wildcard(alias);
+	return 1;
+}
+ADD_TO_DEVTABLE("ipack", struct ipack_device_id, do_ipack_entry);
+
 /*
  * Append a match expression for a single masked hex digit.
  * outp points to a pointer to the character at which to append.
-- 
1.7.10.4


^ permalink raw reply	[flat|nested] 17+ messages in thread

* [PATCH 09/16] Staging: ipack: Read the ID space during device registration.
  2012-09-04 15:01 [PATCH 00/16] ipack: autoload IP module drivers Samuel Iglesias Gonsálvez
                   ` (7 preceding siblings ...)
  2012-09-04 15:01 ` [PATCH 08/16] Staging: ipack: implement ipack device table Samuel Iglesias Gonsálvez
@ 2012-09-04 15:01 ` Samuel Iglesias Gonsálvez
  2012-09-04 15:01 ` [PATCH 10/16] Staging: ipack: Parse vendor and device id Samuel Iglesias Gonsálvez
                   ` (6 subsequent siblings)
  15 siblings, 0 replies; 17+ messages in thread
From: Samuel Iglesias Gonsálvez @ 2012-09-04 15:01 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 keep a copy of the ID space for later use.

Signed-off-by: Jens Taprogge <jens.taprogge@taprogge.org>
Signed-off-by: Samuel Iglesias Gonsálvez <siglesias@igalia.com>
---
 drivers/staging/ipack/ipack.c |   80 +++++++++++++++++++++++++++++++++++++++++
 drivers/staging/ipack/ipack.h |    5 +++
 2 files changed, 85 insertions(+)

diff --git a/drivers/staging/ipack/ipack.c b/drivers/staging/ipack/ipack.c
index c1cd97a..da9e7bd 100644
--- a/drivers/staging/ipack/ipack.c
+++ b/drivers/staging/ipack/ipack.c
@@ -22,6 +22,7 @@ static DEFINE_IDA(ipack_ida);
 static void ipack_device_release(struct device *dev)
 {
 	struct ipack_device *device = to_ipack_dev(dev);
+	kfree(device->id);
 	kfree(device);
 }
 
@@ -117,6 +118,77 @@ void ipack_driver_unregister(struct ipack_driver *edrv)
 }
 EXPORT_SYMBOL_GPL(ipack_driver_unregister);
 
+static int ipack_device_read_id(struct ipack_device *dev)
+{
+	u8 __iomem *idmem;
+	int i;
+	int ret = 0;
+
+	ret = dev->bus->ops->map_space(dev, 0, IPACK_ID_SPACE);
+	if (ret) {
+		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
+	 * "VITA4 " (16 bit big endian formatted) we are dealing with a
+	 * IndustryPack format 2 device */
+	if ((ioread8(idmem + 1) == 'I') &&
+			(ioread8(idmem + 3) == 'P') &&
+			(ioread8(idmem + 5) == 'A') &&
+			((ioread8(idmem + 7) == 'C') ||
+			 (ioread8(idmem + 7) == 'H'))) {
+		dev->id_format = IPACK_ID_VERSION_1;
+		dev->id_avail = ioread8(idmem + 0x15);
+		if ((dev->id_avail < 0x0c) || (dev->id_avail > 0x40)) {
+			dev_warn(&dev->dev, "invalid id size");
+			dev->id_avail = 0x0c;
+		}
+	} else if ((ioread8(idmem + 0) == 'I') &&
+			(ioread8(idmem + 1) == 'V') &&
+			(ioread8(idmem + 2) == 'A') &&
+			(ioread8(idmem + 3) == 'T') &&
+			(ioread8(idmem + 4) == ' ') &&
+			(ioread8(idmem + 5) == '4')) {
+		dev->id_format = IPACK_ID_VERSION_2;
+		dev->id_avail = ioread16be(idmem + 0x16);
+		if ((dev->id_avail < 0x1a) || (dev->id_avail > 0x40)) {
+			dev_warn(&dev->dev, "invalid id size");
+			dev->id_avail = 0x1a;
+		}
+	} else {
+		dev->id_format = IPACK_ID_VERSION_INVALID;
+		dev->id_avail = 0;
+	}
+
+	if (!dev->id_avail) {
+		ret = -ENODEV;
+		goto out;
+	}
+
+	/* Obtain the amount of memory required to store a copy of the complete
+	 * ID ROM contents */
+	dev->id = kmalloc(dev->id_avail, GFP_KERNEL);
+	if (!dev->id) {
+		dev_err(&dev->dev, "dev->id alloc failed.\n");
+		ret = -ENOMEM;
+		goto out;
+	}
+	for (i = 0; i < dev->id_avail; i++) {
+		if (dev->id_format == IPACK_ID_VERSION_1)
+			dev->id[i] = ioread8(idmem + (i << 1) + 1);
+		else
+			dev->id[i] = ioread8(idmem + i);
+	}
+
+out:
+	dev->bus->ops->unmap_space(dev, IPACK_ID_SPACE);
+
+	return ret;
+}
+
 struct ipack_device *ipack_device_register(struct ipack_bus_device *bus,
 					   int slot, int irqv)
 {
@@ -137,8 +209,16 @@ 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);
 
+	ret = ipack_device_read_id(dev);
+	if (ret < 0) {
+		dev_err(&dev->dev, "error reading device id section.\n");
+		kfree(dev);
+		return NULL;
+	}
+
 	ret = device_register(&dev->dev);
 	if (ret < 0) {
+		kfree(dev->id);
 		kfree(dev);
 		return NULL;
 	}
diff --git a/drivers/staging/ipack/ipack.h b/drivers/staging/ipack/ipack.h
index 703142d..2851e33 100644
--- a/drivers/staging/ipack/ipack.h
+++ b/drivers/staging/ipack/ipack.h
@@ -12,6 +12,8 @@
 #include <linux/mod_devicetable.h>
 #include <linux/device.h>
 
+#include "ipack_ids.h"
+
 #define IPACK_IDPROM_OFFSET_I			0x01
 #define IPACK_IDPROM_OFFSET_P			0x03
 #define IPACK_IDPROM_OFFSET_A			0x05
@@ -72,6 +74,9 @@ struct ipack_device {
 	struct ipack_addr_space io_space;
 	struct ipack_addr_space mem_space;
 	struct device dev;
+	unsigned char           *id;
+	size_t			 id_avail;
+	u8			 id_format;
 };
 
 /**
-- 
1.7.10.4


^ permalink raw reply	[flat|nested] 17+ messages in thread

* [PATCH 10/16] Staging: ipack: Parse vendor and device id.
  2012-09-04 15:01 [PATCH 00/16] ipack: autoload IP module drivers Samuel Iglesias Gonsálvez
                   ` (8 preceding siblings ...)
  2012-09-04 15:01 ` [PATCH 09/16] Staging: ipack: Read the ID space during device registration Samuel Iglesias Gonsálvez
@ 2012-09-04 15:01 ` Samuel Iglesias Gonsálvez
  2012-09-04 15:01 ` [PATCH 11/16] Staging: ipack: Move device ids from ipoctal.c to ipack_ids.h Samuel Iglesias Gonsálvez
                   ` (5 subsequent siblings)
  15 siblings, 0 replies; 17+ messages in thread
From: Samuel Iglesias Gonsálvez @ 2012-09-04 15:01 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>

Also expose the values through sysfs.

Signed-off-by: Jens Taprogge <jens.taprogge@taprogge.org>
Signed-off-by: Samuel Iglesias Gonsálvez <siglesias@igalia.com>
---
 drivers/staging/ipack/ipack.c |   81 +++++++++++++++++++++++++++++++++++++++--
 drivers/staging/ipack/ipack.h |    4 +-
 2 files changed, 80 insertions(+), 5 deletions(-)

diff --git a/drivers/staging/ipack/ipack.c b/drivers/staging/ipack/ipack.c
index da9e7bd..9474226 100644
--- a/drivers/staging/ipack/ipack.c
+++ b/drivers/staging/ipack/ipack.c
@@ -63,11 +63,57 @@ static int ipack_bus_remove(struct device *device)
 	return 0;
 }
 
+#define ipack_device_attr(field, format_string)				\
+static ssize_t								\
+field##_show(struct device *dev, struct device_attribute *attr,		\
+		char *buf)						\
+{									\
+	struct ipack_device *idev = to_ipack_dev(dev);			\
+	return sprintf(buf, format_string, idev->field);		\
+}
+
+static ssize_t
+id_vendor_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct ipack_device *idev = to_ipack_dev(dev);
+	switch (idev->id_format) {
+	case IPACK_ID_VERSION_1:
+		return sprintf(buf, "0x%02x\n", idev->id_vendor);
+	case IPACK_ID_VERSION_2:
+		return sprintf(buf, "0x%06x\n", idev->id_vendor);
+	default:
+		return -EIO;
+	}
+}
+
+static ssize_t
+id_device_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct ipack_device *idev = to_ipack_dev(dev);
+	switch (idev->id_format) {
+	case IPACK_ID_VERSION_1:
+		return sprintf(buf, "0x%02x\n", idev->id_device);
+	case IPACK_ID_VERSION_2:
+		return sprintf(buf, "0x%04x\n", idev->id_device);
+	default:
+		return -EIO;
+	}
+}
+
+ipack_device_attr(id_format, "0x%hhu\n");
+
+static struct device_attribute ipack_dev_attrs[] = {
+	__ATTR_RO(id_device),
+	__ATTR_RO(id_format),
+	__ATTR_RO(id_vendor),
+};
+
 static struct bus_type ipack_bus_type = {
-	.name  = "ipack",
-	.probe = ipack_bus_probe,
-	.match = ipack_bus_match,
-	.remove = ipack_bus_remove,
+	.name      = "ipack",
+	.probe     = ipack_bus_probe,
+	.match     = ipack_bus_match,
+	.remove    = ipack_bus_remove,
+	.dev_attrs = ipack_dev_attrs,
 };
 
 struct ipack_bus_device *ipack_bus_register(struct device *parent, int slots,
@@ -118,6 +164,23 @@ void ipack_driver_unregister(struct ipack_driver *edrv)
 }
 EXPORT_SYMBOL_GPL(ipack_driver_unregister);
 
+static void ipack_parse_id1(struct ipack_device *dev)
+{
+	u8 *id = dev->id;
+
+	dev->id_vendor = id[4];
+	dev->id_device = id[5];
+}
+
+static void ipack_parse_id2(struct ipack_device *dev)
+{
+	__be16 *id = (__be16 *) dev->id;
+
+	dev->id_vendor = ((be16_to_cpu(id[3]) & 0xff) << 16)
+			 + be16_to_cpu(id[4]);
+	dev->id_device = be16_to_cpu(id[5]);
+}
+
 static int ipack_device_read_id(struct ipack_device *dev)
 {
 	u8 __iomem *idmem;
@@ -183,6 +246,16 @@ static int ipack_device_read_id(struct ipack_device *dev)
 			dev->id[i] = ioread8(idmem + i);
 	}
 
+	/* now we can finally work with the copy */
+	switch (dev->id_format) {
+	case IPACK_ID_VERSION_1:
+		ipack_parse_id1(dev);
+		break;
+	case IPACK_ID_VERSION_2:
+		ipack_parse_id2(dev);
+		break;
+	}
+
 out:
 	dev->bus->ops->unmap_space(dev, IPACK_ID_SPACE);
 
diff --git a/drivers/staging/ipack/ipack.h b/drivers/staging/ipack/ipack.h
index 2851e33..a3cd559 100644
--- a/drivers/staging/ipack/ipack.h
+++ b/drivers/staging/ipack/ipack.h
@@ -74,8 +74,10 @@ struct ipack_device {
 	struct ipack_addr_space io_space;
 	struct ipack_addr_space mem_space;
 	struct device dev;
-	unsigned char           *id;
+	u8                      *id;
 	size_t			 id_avail;
+	u32			 id_vendor;
+	u32			 id_device;
 	u8			 id_format;
 };
 
-- 
1.7.10.4


^ permalink raw reply	[flat|nested] 17+ messages in thread

* [PATCH 11/16] Staging: ipack: Move device ids from ipoctal.c to ipack_ids.h.
  2012-09-04 15:01 [PATCH 00/16] ipack: autoload IP module drivers Samuel Iglesias Gonsálvez
                   ` (9 preceding siblings ...)
  2012-09-04 15:01 ` [PATCH 10/16] Staging: ipack: Parse vendor and device id Samuel Iglesias Gonsálvez
@ 2012-09-04 15:01 ` Samuel Iglesias Gonsálvez
  2012-09-04 15:01 ` [PATCH 12/16] Staging: ipack: Make ipack_driver_ops const Samuel Iglesias Gonsálvez
                   ` (4 subsequent siblings)
  15 siblings, 0 replies; 17+ messages in thread
From: Samuel Iglesias Gonsálvez @ 2012-09-04 15:01 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>

Rename them in the process.

Signed-off-by: Jens Taprogge <jens.taprogge@taprogge.org>
Signed-off-by: Samuel Iglesias Gonsálvez <siglesias@igalia.com>
---
 drivers/staging/ipack/devices/ipoctal.c |   26 +++++++++++---------------
 drivers/staging/ipack/ipack_ids.h       |    5 +++++
 2 files changed, 16 insertions(+), 15 deletions(-)

diff --git a/drivers/staging/ipack/devices/ipoctal.c b/drivers/staging/ipack/devices/ipoctal.c
index c1d0c00..ed08864 100644
--- a/drivers/staging/ipack/devices/ipoctal.c
+++ b/drivers/staging/ipack/devices/ipoctal.c
@@ -25,11 +25,6 @@
 #include "ipoctal.h"
 #include "scc2698.h"
 
-#define IP_OCTAL_MANUFACTURER_ID    0xF0
-#define IP_OCTAL_232_ID             0x22
-#define IP_OCTAL_422_ID             0x2A
-#define IP_OCTAL_485_ID             0x48
-
 #define IP_OCTAL_ID_SPACE_VECTOR    0x41
 #define IP_OCTAL_NB_BLOCKS          4
 
@@ -231,7 +226,7 @@ static int ipoctal_irq_handler(void *arg)
 		/* In case of RS-485, change from TX to RX when finishing TX.
 		 * Half-duplex.
 		 */
-		if ((ipoctal->board_id == IP_OCTAL_485_ID) &&
+		if ((ipoctal->board_id == IPACK1_DEVICE_ID_SBS_OCTAL_485) &&
 		    (sr & SR_TX_EMPTY) &&
 		    (ipoctal->nb_bytes[channel] == 0)) {
 			ipoctal_write_io_reg(ipoctal,
@@ -304,7 +299,7 @@ static int ipoctal_irq_handler(void *arg)
 			if ((ipoctal->nb_bytes[channel] == 0) &&
 			    (waitqueue_active(&ipoctal->queue[channel]))) {
 
-				if (ipoctal->board_id != IP_OCTAL_485_ID) {
+				if (ipoctal->board_id != IPACK1_DEVICE_ID_SBS_OCTAL_485) {
 					ipoctal->write = 1;
 					wake_up_interruptible(&ipoctal->queue[channel]);
 				}
@@ -322,15 +317,16 @@ 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 != IP_OCTAL_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 IP_OCTAL_232_ID:
-	case IP_OCTAL_422_ID:
-	case IP_OCTAL_485_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:
@@ -543,7 +539,7 @@ static int ipoctal_write(struct ipoctal *ipoctal, unsigned int channel,
 	ipoctal_copy_write_buffer(ipoctal, channel, buf, count);
 
 	/* As the IP-OCTAL 485 only supports half duplex, do it manually */
-	if (ipoctal->board_id == IP_OCTAL_485_ID) {
+	if (ipoctal->board_id == IPACK1_DEVICE_ID_SBS_OCTAL_485) {
 		ipoctal_write_io_reg(ipoctal,
 				     &ipoctal->chan_regs[channel].w.cr,
 				     CR_DISABLE_RX);
@@ -654,7 +650,7 @@ static void ipoctal_set_termios(struct tty_struct *tty,
 
 	/* Set the flow control */
 	switch (ipoctal->board_id) {
-	case IP_OCTAL_232_ID:
+	case IPACK1_DEVICE_ID_SBS_OCTAL_232:
 		if (cflag & CRTSCTS) {
 			mr1 |= MR1_RxRTS_CONTROL_ON;
 			mr2 |= MR2_TxRTS_CONTROL_OFF | MR2_CTS_ENABLE_TX_ON;
@@ -663,11 +659,11 @@ static void ipoctal_set_termios(struct tty_struct *tty,
 			mr2 |= MR2_TxRTS_CONTROL_OFF | MR2_CTS_ENABLE_TX_OFF;
 		}
 		break;
-	case IP_OCTAL_422_ID:
+	case IPACK1_DEVICE_ID_SBS_OCTAL_422:
 		mr1 |= MR1_RxRTS_CONTROL_OFF;
 		mr2 |= MR2_TxRTS_CONTROL_OFF | MR2_CTS_ENABLE_TX_OFF;
 		break;
-	case IP_OCTAL_485_ID:
+	case IPACK1_DEVICE_ID_SBS_OCTAL_485:
 		mr1 |= MR1_RxRTS_CONTROL_OFF;
 		mr2 |= MR2_TxRTS_CONTROL_ON | MR2_CTS_ENABLE_TX_OFF;
 		break;
diff --git a/drivers/staging/ipack/ipack_ids.h b/drivers/staging/ipack/ipack_ids.h
index ba85ec5..8153fee 100644
--- a/drivers/staging/ipack/ipack_ids.h
+++ b/drivers/staging/ipack/ipack_ids.h
@@ -25,3 +25,8 @@
 #define IPACK1_VENDOR_ID_UNREGISTRED13	0x0D
 #define IPACK1_VENDOR_ID_UNREGISTRED14	0x0E
 #define IPACK1_VENDOR_ID_UNREGISTRED15	0x0F
+
+#define IPACK1_VENDOR_ID_SBS            0xF0
+#define IPACK1_DEVICE_ID_SBS_OCTAL_232  0x22
+#define IPACK1_DEVICE_ID_SBS_OCTAL_422  0x2A
+#define IPACK1_DEVICE_ID_SBS_OCTAL_485  0x48
-- 
1.7.10.4


^ permalink raw reply	[flat|nested] 17+ messages in thread

* [PATCH 12/16] Staging: ipack: Make ipack_driver_ops const.
  2012-09-04 15:01 [PATCH 00/16] ipack: autoload IP module drivers Samuel Iglesias Gonsálvez
                   ` (10 preceding siblings ...)
  2012-09-04 15:01 ` [PATCH 11/16] Staging: ipack: Move device ids from ipoctal.c to ipack_ids.h Samuel Iglesias Gonsálvez
@ 2012-09-04 15:01 ` Samuel Iglesias Gonsálvez
  2012-09-04 15:01 ` [PATCH 13/16] Staging: ipack/devices/ipoctal: Expose DEVICE_TABLE for ipoctal Samuel Iglesias Gonsálvez
                   ` (3 subsequent siblings)
  15 siblings, 0 replies; 17+ messages in thread
From: Samuel Iglesias Gonsálvez @ 2012-09-04 15:01 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/devices/ipoctal.c |    8 +++++---
 drivers/staging/ipack/ipack.h           |    2 +-
 2 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/drivers/staging/ipack/devices/ipoctal.c b/drivers/staging/ipack/devices/ipoctal.c
index ed08864..7e1e6f7 100644
--- a/drivers/staging/ipack/devices/ipoctal.c
+++ b/drivers/staging/ipack/devices/ipoctal.c
@@ -28,7 +28,6 @@
 #define IP_OCTAL_ID_SPACE_VECTOR    0x41
 #define IP_OCTAL_NB_BLOCKS          4
 
-static struct ipack_driver driver;
 static const struct tty_operations ipoctal_fops;
 
 struct ipoctal {
@@ -846,15 +845,18 @@ static void ipoctal_remove(struct ipack_device *device)
 	}
 }
 
-static struct ipack_driver_ops ipoctal_drv_ops = {
+static const struct ipack_driver_ops ipoctal_drv_ops = {
 	.match = ipoctal_match,
 	.probe = ipoctal_probe,
 	.remove = ipoctal_remove,
 };
 
+static struct ipack_driver driver = {
+	.ops      = &ipoctal_drv_ops,
+};
+
 static int __init ipoctal_init(void)
 {
-	driver.ops = &ipoctal_drv_ops;
 	return ipack_driver_register(&driver, THIS_MODULE, KBUILD_MODNAME);
 }
 
diff --git a/drivers/staging/ipack/ipack.h b/drivers/staging/ipack/ipack.h
index a3cd559..e6e38e7 100644
--- a/drivers/staging/ipack/ipack.h
+++ b/drivers/staging/ipack/ipack.h
@@ -104,7 +104,7 @@ struct ipack_driver_ops {
 struct ipack_driver {
 	struct device_driver driver;
 	const struct ipack_device_id *id_table;
-	struct ipack_driver_ops *ops;
+	const struct ipack_driver_ops *ops;
 };
 
 /**
-- 
1.7.10.4


^ permalink raw reply	[flat|nested] 17+ messages in thread

* [PATCH 13/16] Staging: ipack/devices/ipoctal: Expose DEVICE_TABLE for ipoctal.
  2012-09-04 15:01 [PATCH 00/16] ipack: autoload IP module drivers Samuel Iglesias Gonsálvez
                   ` (11 preceding siblings ...)
  2012-09-04 15:01 ` [PATCH 12/16] Staging: ipack: Make ipack_driver_ops const Samuel Iglesias Gonsálvez
@ 2012-09-04 15:01 ` Samuel Iglesias Gonsálvez
  2012-09-04 15:01 ` [PATCH 14/16] Staging: ipack: Implement device matching on the bus level Samuel Iglesias Gonsálvez
                   ` (2 subsequent siblings)
  15 siblings, 0 replies; 17+ messages in thread
From: Samuel Iglesias Gonsálvez @ 2012-09-04 15:01 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>

The modalias entries for the module are now created.

Signed-off-by: Jens Taprogge <jens.taprogge@taprogge.org>
Signed-off-by: Samuel Iglesias Gonsálvez <siglesias@igalia.com>
---
 drivers/staging/ipack/devices/ipoctal.c |   13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/drivers/staging/ipack/devices/ipoctal.c b/drivers/staging/ipack/devices/ipoctal.c
index 7e1e6f7..829b887 100644
--- a/drivers/staging/ipack/devices/ipoctal.c
+++ b/drivers/staging/ipack/devices/ipoctal.c
@@ -845,6 +845,18 @@ static void ipoctal_remove(struct ipack_device *device)
 	}
 }
 
+static DEFINE_IPACK_DEVICE_TABLE(ipoctal_ids) = {
+	{ IPACK_DEVICE(IPACK_ID_VERSION_1, IPACK1_VENDOR_ID_SBS,
+			IPACK1_DEVICE_ID_SBS_OCTAL_232) },
+	{ IPACK_DEVICE(IPACK_ID_VERSION_1, IPACK1_VENDOR_ID_SBS,
+			IPACK1_DEVICE_ID_SBS_OCTAL_422) },
+	{ IPACK_DEVICE(IPACK_ID_VERSION_1, IPACK1_VENDOR_ID_SBS,
+			IPACK1_DEVICE_ID_SBS_OCTAL_485) },
+	{ 0, },
+};
+
+MODULE_DEVICE_TABLE(ipack, ipoctal_ids);
+
 static const struct ipack_driver_ops ipoctal_drv_ops = {
 	.match = ipoctal_match,
 	.probe = ipoctal_probe,
@@ -853,6 +865,7 @@ static const struct ipack_driver_ops ipoctal_drv_ops = {
 
 static struct ipack_driver driver = {
 	.ops      = &ipoctal_drv_ops,
+	.id_table = ipoctal_ids,
 };
 
 static int __init ipoctal_init(void)
-- 
1.7.10.4


^ permalink raw reply	[flat|nested] 17+ messages in thread

* [PATCH 14/16] Staging: ipack: Implement device matching on the bus level.
  2012-09-04 15:01 [PATCH 00/16] ipack: autoload IP module drivers Samuel Iglesias Gonsálvez
                   ` (12 preceding siblings ...)
  2012-09-04 15:01 ` [PATCH 13/16] Staging: ipack/devices/ipoctal: Expose DEVICE_TABLE for ipoctal Samuel Iglesias Gonsálvez
@ 2012-09-04 15:01 ` Samuel Iglesias Gonsálvez
  2012-09-04 15:01 ` [PATCH 15/16] Staging: ipack: Expose modalias through sysfs Samuel Iglesias Gonsálvez
  2012-09-04 15:01 ` [PATCH 16/16] Staging: ipack: Provide ID Prom " Samuel Iglesias Gonsálvez
  15 siblings, 0 replies; 17+ messages in thread
From: Samuel Iglesias Gonsálvez @ 2012-09-04 15:01 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>

Devices are match based upon their vendor and device ids.  Since
the individual drivers provide a list of supported ids they do not
need to implement the matching themselves.

Signed-off-by: Jens Taprogge <jens.taprogge@taprogge.org>
Signed-off-by: Samuel Iglesias Gonsálvez <siglesias@igalia.com>
---
 drivers/staging/ipack/devices/ipoctal.c |   24 +----------------
 drivers/staging/ipack/ipack.c           |   43 ++++++++++++++++++++++++-------
 drivers/staging/ipack/ipack.h           |    2 --
 3 files changed, 34 insertions(+), 35 deletions(-)

diff --git a/drivers/staging/ipack/devices/ipoctal.c b/drivers/staging/ipack/devices/ipoctal.c
index 829b887..c94a9df 100644
--- a/drivers/staging/ipack/devices/ipoctal.c
+++ b/drivers/staging/ipack/devices/ipoctal.c
@@ -777,27 +777,6 @@ static const struct tty_operations ipoctal_fops = {
 	.hangup =		ipoctal_hangup,
 };
 
-static int ipoctal_match(struct ipack_device *dev)
-{
-	int res;
-	unsigned char board_id;
-
-	if ((!dev->bus->ops) || (!dev->bus->ops->map_space) ||
-	    (!dev->bus->ops->unmap_space))
-		return 0;
-
-	res = dev->bus->ops->map_space(dev, 0, IPACK_ID_SPACE);
-	if (res)
-		return 0;
-
-	res = ipoctal_check_model(dev, &board_id);
-	dev->bus->ops->unmap_space(dev, IPACK_ID_SPACE);
-	if (!res)
-		return 1;
-
-	return 0;
-}
-
 static int ipoctal_probe(struct ipack_device *dev)
 {
 	int res;
@@ -858,8 +837,7 @@ static DEFINE_IPACK_DEVICE_TABLE(ipoctal_ids) = {
 MODULE_DEVICE_TABLE(ipack, ipoctal_ids);
 
 static const struct ipack_driver_ops ipoctal_drv_ops = {
-	.match = ipoctal_match,
-	.probe = ipoctal_probe,
+	.probe  = ipoctal_probe,
 	.remove = ipoctal_remove,
 };
 
diff --git a/drivers/staging/ipack/ipack.c b/drivers/staging/ipack/ipack.c
index 9474226..a328629 100644
--- a/drivers/staging/ipack/ipack.c
+++ b/drivers/staging/ipack/ipack.c
@@ -26,20 +26,43 @@ static void ipack_device_release(struct device *dev)
 	kfree(device);
 }
 
-static int ipack_bus_match(struct device *device, struct device_driver *driver)
+static inline const struct ipack_device_id *
+ipack_match_one_device(const struct ipack_device_id *id,
+		       const struct ipack_device *device)
 {
-	int ret;
-	struct ipack_device *dev = to_ipack_dev(device);
-	struct ipack_driver *drv = to_ipack_driver(driver);
+	if ((id->format == IPACK_ANY_ID || id->format == device->id_format) &&
+	    (id->vendor == IPACK_ANY_ID || id->vendor == device->id_vendor) &&
+	    (id->device == IPACK_ANY_ID || id->device == device->id_device))
+		return id;
+	return NULL;
+}
 
-	if ((!drv->ops) || (!drv->ops->match))
-		return -EINVAL;
+static const struct ipack_device_id *
+ipack_match_id(const struct ipack_device_id *ids, struct ipack_device *idev)
+{
+	if (ids) {
+		while (ids->vendor || ids->device) {
+			if (ipack_match_one_device(ids, idev))
+				return ids;
+			ids++;
+		}
+	}
+	return NULL;
+}
 
-	ret = drv->ops->match(dev);
-	if (ret)
-		dev->driver = drv;
+static int ipack_bus_match(struct device *dev, struct device_driver *drv)
+{
+	struct ipack_device *idev = to_ipack_dev(dev);
+	struct ipack_driver *idrv = to_ipack_driver(drv);
+	const struct ipack_device_id *found_id;
 
-	return ret;
+	found_id = ipack_match_id(idrv->id_table, idev);
+	if (found_id) {
+		idev->driver = idrv;
+		return 1;
+	}
+
+	return 0;
 }
 
 static int ipack_bus_probe(struct device *device)
diff --git a/drivers/staging/ipack/ipack.h b/drivers/staging/ipack/ipack.h
index e6e38e7..0f482fd 100644
--- a/drivers/staging/ipack/ipack.h
+++ b/drivers/staging/ipack/ipack.h
@@ -84,13 +84,11 @@ struct ipack_device {
 /**
  *	struct ipack_driver_ops -- callbacks to mezzanine driver for installing/removing one device
  *
- *	@match: Match function
  *	@probe: Probe function
  *	@remove: tell the driver that the carrier board wants to remove one device
  */
 
 struct ipack_driver_ops {
-	int (*match) (struct ipack_device *dev);
 	int (*probe) (struct ipack_device *dev);
 	void (*remove) (struct ipack_device *dev);
 };
-- 
1.7.10.4


^ permalink raw reply	[flat|nested] 17+ messages in thread

* [PATCH 15/16] Staging: ipack: Expose modalias through sysfs.
  2012-09-04 15:01 [PATCH 00/16] ipack: autoload IP module drivers Samuel Iglesias Gonsálvez
                   ` (13 preceding siblings ...)
  2012-09-04 15:01 ` [PATCH 14/16] Staging: ipack: Implement device matching on the bus level Samuel Iglesias Gonsálvez
@ 2012-09-04 15:01 ` Samuel Iglesias Gonsálvez
  2012-09-04 15:01 ` [PATCH 16/16] Staging: ipack: Provide ID Prom " Samuel Iglesias Gonsálvez
  15 siblings, 0 replies; 17+ messages in thread
From: Samuel Iglesias Gonsálvez @ 2012-09-04 15:01 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>

Also include it in the hotplug event so that udev can
provide the respective driver.

Signed-off-by: Jens Taprogge <jens.taprogge@taprogge.org>
Signed-off-by: Samuel Iglesias Gonsálvez <siglesias@igalia.com>
---
 drivers/staging/ipack/ipack.c |   36 ++++++++++++++++++++++++++++++++++++
 1 file changed, 36 insertions(+)

diff --git a/drivers/staging/ipack/ipack.c b/drivers/staging/ipack/ipack.c
index a328629..a5ef28f 100644
--- a/drivers/staging/ipack/ipack.c
+++ b/drivers/staging/ipack/ipack.c
@@ -86,6 +86,31 @@ static int ipack_bus_remove(struct device *device)
 	return 0;
 }
 
+#ifdef CONFIG_HOTPLUG
+
+static int ipack_uevent(struct device *dev, struct kobj_uevent_env *env)
+{
+	struct ipack_device *idev;
+
+	if (!dev)
+		return -ENODEV;
+
+	idev = to_ipack_dev(dev);
+
+	if (add_uevent_var(env,
+			   "MODALIAS=ipack:f%02Xv%08Xd%08X", idev->id_format,
+			   idev->id_vendor, idev->id_device))
+		return -ENOMEM;
+
+	return 0;
+}
+
+#else /* !CONFIG_HOTPLUG */
+
+#define ipack_uevent NULL
+
+#endif /* !CONFIG_HOTPLUG */
+
 #define ipack_device_attr(field, format_string)				\
 static ssize_t								\
 field##_show(struct device *dev, struct device_attribute *attr,		\
@@ -123,12 +148,22 @@ id_device_show(struct device *dev, struct device_attribute *attr, char *buf)
 	}
 }
 
+static ssize_t modalias_show(struct device *dev, struct device_attribute *attr,
+			     char *buf)
+{
+	struct ipack_device *idev = to_ipack_dev(dev);
+
+	return sprintf(buf, "ipac:f%02Xv%08Xd%08X", idev->id_format,
+		       idev->id_vendor, idev->id_device);
+}
+
 ipack_device_attr(id_format, "0x%hhu\n");
 
 static struct device_attribute ipack_dev_attrs[] = {
 	__ATTR_RO(id_device),
 	__ATTR_RO(id_format),
 	__ATTR_RO(id_vendor),
+	__ATTR_RO(modalias),
 };
 
 static struct bus_type ipack_bus_type = {
@@ -137,6 +172,7 @@ static struct bus_type ipack_bus_type = {
 	.match     = ipack_bus_match,
 	.remove    = ipack_bus_remove,
 	.dev_attrs = ipack_dev_attrs,
+	.uevent	   = ipack_uevent,
 };
 
 struct ipack_bus_device *ipack_bus_register(struct device *parent, int slots,
-- 
1.7.10.4


^ permalink raw reply	[flat|nested] 17+ messages in thread

* [PATCH 16/16] Staging: ipack: Provide ID Prom through sysfs.
  2012-09-04 15:01 [PATCH 00/16] ipack: autoload IP module drivers Samuel Iglesias Gonsálvez
                   ` (14 preceding siblings ...)
  2012-09-04 15:01 ` [PATCH 15/16] Staging: ipack: Expose modalias through sysfs Samuel Iglesias Gonsálvez
@ 2012-09-04 15:01 ` Samuel Iglesias Gonsálvez
  15 siblings, 0 replies; 17+ messages in thread
From: Samuel Iglesias Gonsálvez @ 2012-09-04 15:01 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 |   31 +++++++++++++++++++++++++++++++
 1 file changed, 31 insertions(+)

diff --git a/drivers/staging/ipack/ipack.c b/drivers/staging/ipack/ipack.c
index a5ef28f..ff907fa 100644
--- a/drivers/staging/ipack/ipack.c
+++ b/drivers/staging/ipack/ipack.c
@@ -120,6 +120,36 @@ field##_show(struct device *dev, struct device_attribute *attr,		\
 	return sprintf(buf, format_string, idev->field);		\
 }
 
+static ssize_t id_show(struct device *dev,
+		       struct device_attribute *attr, char *buf)
+{
+	unsigned int i, c, l, s;
+	struct ipack_device *idev = to_ipack_dev(dev);
+
+
+	switch (idev->id_format) {
+	case IPACK_ID_VERSION_1:
+		l = 0x7; s = 1; break;
+	case IPACK_ID_VERSION_2:
+		l = 0xf; s = 2; break;
+	default:
+		return -EIO;
+	}
+	c = 0;
+	for (i = 0; i < idev->id_avail; i++) {
+		if (i > 0) {
+			if ((i & l) == 0)
+				buf[c++] = '\n';
+			else if ((i & s) == 0)
+				buf[c++] = ' ';
+		}
+		sprintf(&buf[c], "%02x", idev->id[i]);
+		c += 2;
+	}
+	buf[c++] = '\n';
+	return c;
+}
+
 static ssize_t
 id_vendor_show(struct device *dev, struct device_attribute *attr, char *buf)
 {
@@ -160,6 +190,7 @@ static ssize_t modalias_show(struct device *dev, struct device_attribute *attr,
 ipack_device_attr(id_format, "0x%hhu\n");
 
 static struct device_attribute ipack_dev_attrs[] = {
+	__ATTR_RO(id),
 	__ATTR_RO(id_device),
 	__ATTR_RO(id_format),
 	__ATTR_RO(id_vendor),
-- 
1.7.10.4


^ permalink raw reply	[flat|nested] 17+ messages in thread

end of thread, other threads:[~2012-09-04 15:15 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-09-04 15:01 [PATCH 00/16] ipack: autoload IP module drivers Samuel Iglesias Gonsálvez
2012-09-04 15:01 ` [PATCH 01/16] Staging: ipack/bridges/tpci200: Reorganize tpci200_probe in preparation for functional changes Samuel Iglesias Gonsálvez
2012-09-04 15:01 ` [PATCH 02/16] Staging: ipack/bridges/tpci200: Use the TPCI200 in big endian mode Samuel Iglesias Gonsálvez
2012-09-04 15:01 ` [PATCH 03/16] Staging: ipack/devices/ipoctal: Convert ipoctal to directly use ioread/write functions Samuel Iglesias Gonsálvez
2012-09-04 15:01 ` [PATCH 04/16] Staging: ipack/bridges/tpci200: Remove the read/write functions from ipack_bus_ops Samuel Iglesias Gonsálvez
2012-09-04 15:01 ` [PATCH 05/16] Staging: ipack: remove read/write operations " Samuel Iglesias Gonsálvez
2012-09-04 15:01 ` [PATCH 06/16] Staging: ipack/devices/ipoctal: ipoctal cleanups Samuel Iglesias Gonsálvez
2012-09-04 15:01 ` [PATCH 07/16] Staging: ipack/devices/ipoctal: Tidy up ipoctal some more Samuel Iglesias Gonsálvez
2012-09-04 15:01 ` [PATCH 08/16] Staging: ipack: implement ipack device table Samuel Iglesias Gonsálvez
2012-09-04 15:01 ` [PATCH 09/16] Staging: ipack: Read the ID space during device registration Samuel Iglesias Gonsálvez
2012-09-04 15:01 ` [PATCH 10/16] Staging: ipack: Parse vendor and device id Samuel Iglesias Gonsálvez
2012-09-04 15:01 ` [PATCH 11/16] Staging: ipack: Move device ids from ipoctal.c to ipack_ids.h Samuel Iglesias Gonsálvez
2012-09-04 15:01 ` [PATCH 12/16] Staging: ipack: Make ipack_driver_ops const Samuel Iglesias Gonsálvez
2012-09-04 15:01 ` [PATCH 13/16] Staging: ipack/devices/ipoctal: Expose DEVICE_TABLE for ipoctal Samuel Iglesias Gonsálvez
2012-09-04 15:01 ` [PATCH 14/16] Staging: ipack: Implement device matching on the bus level Samuel Iglesias Gonsálvez
2012-09-04 15:01 ` [PATCH 15/16] Staging: ipack: Expose modalias through sysfs Samuel Iglesias Gonsálvez
2012-09-04 15:01 ` [PATCH 16/16] Staging: ipack: Provide ID Prom " Samuel Iglesias Gonsálvez

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).