* [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 related [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 related [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 related [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 related [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 related [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 related [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 related [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 related [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 related [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 related [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 related [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 related [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 related [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 related [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 related [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 related [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).