Skip to content

Commit cea2f7c

Browse files
jtaproggegregkh
authored andcommitted
Staging: ipack/bridges/tpci200: Use the TPCI200 in big endian mode.
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 <[email protected]> Signed-off-by: Samuel Iglesias Gonsálvez <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 5e15a75 commit cea2f7c

File tree

3 files changed

+53
-7
lines changed

3 files changed

+53
-7
lines changed

drivers/staging/ipack/bridges/tpci200.c

Lines changed: 43 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -54,39 +54,39 @@ static struct tpci200_board *check_slot(struct ipack_device *dev)
5454
static inline unsigned char __tpci200_read8(void __iomem *address,
5555
unsigned long offset)
5656
{
57-
return ioread8(address + (offset^1));
57+
return ioread8(address + offset);
5858
}
5959

6060
static inline unsigned short __tpci200_read16(void __iomem *address,
6161
unsigned long offset)
6262
{
63-
return ioread16(address + offset);
63+
return ioread16be(address + offset);
6464
}
6565

6666
static inline unsigned int __tpci200_read32(void __iomem *address,
6767
unsigned long offset)
6868
{
69-
return swahw32(ioread32(address + offset));
69+
return ioread32be(address + offset);
7070
}
7171

7272
static inline void __tpci200_write8(unsigned char value,
7373
void __iomem *address, unsigned long offset)
7474
{
75-
iowrite8(value, address+(offset^1));
75+
iowrite8(value, address + offset);
7676
}
7777

7878
static inline void __tpci200_write16(unsigned short value,
7979
void __iomem *address,
8080
unsigned long offset)
8181
{
82-
iowrite16(value, address+offset);
82+
iowrite16be(value, address + offset);
8383
}
8484

8585
static inline void __tpci200_write32(unsigned int value,
8686
void __iomem *address,
8787
unsigned long offset)
8888
{
89-
iowrite32(swahw32(value), address+offset);
89+
iowrite32be(value, address + offset);
9090
}
9191

9292
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,
783783
{
784784
int ret, i;
785785
struct tpci200_board *tpci200;
786+
__le32 reg32;
786787

787788
tpci200 = kzalloc(sizeof(struct tpci200_board), GFP_KERNEL);
788789
if (!tpci200)
@@ -794,6 +795,34 @@ static int tpci200_pciprobe(struct pci_dev *pdev,
794795
goto out_err_info;
795796
}
796797

798+
/* Obtain a mapping of the carrier's PCI configuration registers */
799+
ret = pci_request_region(pdev, TPCI200_CFG_MEM_BAR,
800+
KBUILD_MODNAME " Configuration Memory");
801+
if (ret) {
802+
dev_err(&pdev->dev, "Failed to allocate PCI Configuration Memory");
803+
ret = -EBUSY;
804+
goto out_err_pci_request;
805+
}
806+
tpci200->info->cfg_regs = ioremap_nocache(
807+
pci_resource_start(pdev, TPCI200_CFG_MEM_BAR),
808+
pci_resource_len(pdev, TPCI200_CFG_MEM_BAR));
809+
if (!tpci200->info->cfg_regs) {
810+
dev_err(&pdev->dev, "Failed to map PCI Configuration Memory");
811+
ret = -EFAULT;
812+
goto out_err_ioremap;
813+
}
814+
815+
/* Disable byte swapping for 16 bit IP module access. This will ensure
816+
* that the Industrypack big endian byte order is preserved by the
817+
* carrier. */
818+
reg32 = ioread32(tpci200->info->cfg_regs + LAS1_DESC);
819+
reg32 |= 1 << LAS_BIT_BIGENDIAN;
820+
iowrite32(reg32, tpci200->info->cfg_regs + LAS1_DESC);
821+
822+
reg32 = ioread32(tpci200->info->cfg_regs + LAS2_DESC);
823+
reg32 |= 1 << LAS_BIT_BIGENDIAN;
824+
iowrite32(reg32, tpci200->info->cfg_regs + LAS2_DESC);
825+
797826
/* Save struct pci_dev pointer */
798827
tpci200->info->pdev = pdev;
799828
tpci200->info->id_table = (struct pci_device_id *)id;
@@ -833,6 +862,10 @@ static int tpci200_pciprobe(struct pci_dev *pdev,
833862
out_err_bus_register:
834863
tpci200_uninstall(tpci200);
835864
out_err_install:
865+
iounmap(tpci200->info->cfg_regs);
866+
out_err_ioremap:
867+
pci_release_region(pdev, TPCI200_CFG_MEM_BAR);
868+
out_err_pci_request:
836869
kfree(tpci200->info);
837870
out_err_info:
838871
kfree(tpci200);
@@ -843,6 +876,10 @@ static void __tpci200_pci_remove(struct tpci200_board *tpci200)
843876
{
844877
tpci200_uninstall(tpci200);
845878
ipack_bus_unregister(tpci200->info->ipack_bus);
879+
880+
iounmap(tpci200->info->cfg_regs);
881+
pci_release_region(tpci200->info->pdev, TPCI200_CFG_MEM_BAR);
882+
846883
kfree(tpci200->info);
847884
kfree(tpci200);
848885
}

drivers/staging/ipack/bridges/tpci200.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
#define TPCI200_SUBVENDOR_ID 0x1498
3232
#define TPCI200_SUBDEVICE_ID 0x300A
3333

34+
#define TPCI200_CFG_MEM_BAR 0
3435
#define TPCI200_IP_INTERFACE_BAR 2
3536
#define TPCI200_IO_ID_INT_SPACES_BAR 3
3637
#define TPCI200_MEM16_SPACE_BAR 4
@@ -97,6 +98,13 @@
9798

9899
#define TPCI200_SLOT_INT_MASK 0x00FF
99100

101+
/* PCI Configuration registers. The PCI bridge is a PLX Technology PCI9030. */
102+
#define LAS1_DESC 0x2C
103+
#define LAS2_DESC 0x30
104+
105+
/* Bits in the LAS?_DESC registers */
106+
#define LAS_BIT_BIGENDIAN 24
107+
100108
#define VME_IOID_SPACE "IOID"
101109
#define VME_MEM_SPACE "MEM"
102110

@@ -144,6 +152,7 @@ struct tpci200_infos {
144152
void __iomem *interface_regs;
145153
void __iomem *ioidint_space;
146154
void __iomem *mem8_space;
155+
void __iomem *cfg_regs;
147156
struct ipack_bus_device *ipack_bus;
148157
};
149158
struct tpci200_board {

drivers/staging/ipack/devices/ipoctal.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -449,7 +449,7 @@ static int ipoctal_inst_slot(struct ipoctal *ipoctal, unsigned int bus_nr,
449449
*/
450450
ipoctal->dev->bus->ops->request_irq(ipoctal->dev, vector,
451451
ipoctal_irq_handler, ipoctal);
452-
ipoctal->dev->bus->ops->write8(ipoctal->dev, IPACK_MEM_SPACE, 0,
452+
ipoctal->dev->bus->ops->write8(ipoctal->dev, IPACK_MEM_SPACE, 1,
453453
vector);
454454

455455
/* Register the TTY device */

0 commit comments

Comments
 (0)