|
@@ -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);
|
|
|
}
|