diff options
Diffstat (limited to 'drivers/pci/switch/switchtec.c')
-rw-r--r-- | drivers/pci/switch/switchtec.c | 56 |
1 files changed, 44 insertions, 12 deletions
diff --git a/drivers/pci/switch/switchtec.c b/drivers/pci/switch/switchtec.c index cc6e085008fb..af81b2dec42e 100644 --- a/drivers/pci/switch/switchtec.c +++ b/drivers/pci/switch/switchtec.c | |||
@@ -120,6 +120,13 @@ struct sw_event_regs { | |||
120 | u32 reserved16[4]; | 120 | u32 reserved16[4]; |
121 | } __packed; | 121 | } __packed; |
122 | 122 | ||
123 | enum { | ||
124 | SWITCHTEC_CFG0_RUNNING = 0x04, | ||
125 | SWITCHTEC_CFG1_RUNNING = 0x05, | ||
126 | SWITCHTEC_IMG0_RUNNING = 0x03, | ||
127 | SWITCHTEC_IMG1_RUNNING = 0x07, | ||
128 | }; | ||
129 | |||
123 | struct sys_info_regs { | 130 | struct sys_info_regs { |
124 | u32 device_id; | 131 | u32 device_id; |
125 | u32 device_version; | 132 | u32 device_version; |
@@ -129,7 +136,9 @@ struct sys_info_regs { | |||
129 | u32 table_format_version; | 136 | u32 table_format_version; |
130 | u32 partition_id; | 137 | u32 partition_id; |
131 | u32 cfg_file_fmt_version; | 138 | u32 cfg_file_fmt_version; |
132 | u32 reserved2[58]; | 139 | u16 cfg_running; |
140 | u16 img_running; | ||
141 | u32 reserved2[57]; | ||
133 | char vendor_id[8]; | 142 | char vendor_id[8]; |
134 | char product_id[16]; | 143 | char product_id[16]; |
135 | char product_revision[4]; | 144 | char product_revision[4]; |
@@ -807,6 +816,7 @@ static int ioctl_flash_part_info(struct switchtec_dev *stdev, | |||
807 | { | 816 | { |
808 | struct switchtec_ioctl_flash_part_info info = {0}; | 817 | struct switchtec_ioctl_flash_part_info info = {0}; |
809 | struct flash_info_regs __iomem *fi = stdev->mmio_flash_info; | 818 | struct flash_info_regs __iomem *fi = stdev->mmio_flash_info; |
819 | struct sys_info_regs __iomem *si = stdev->mmio_sys_info; | ||
810 | u32 active_addr = -1; | 820 | u32 active_addr = -1; |
811 | 821 | ||
812 | if (copy_from_user(&info, uinfo, sizeof(info))) | 822 | if (copy_from_user(&info, uinfo, sizeof(info))) |
@@ -816,18 +826,26 @@ static int ioctl_flash_part_info(struct switchtec_dev *stdev, | |||
816 | case SWITCHTEC_IOCTL_PART_CFG0: | 826 | case SWITCHTEC_IOCTL_PART_CFG0: |
817 | active_addr = ioread32(&fi->active_cfg); | 827 | active_addr = ioread32(&fi->active_cfg); |
818 | set_fw_info_part(&info, &fi->cfg0); | 828 | set_fw_info_part(&info, &fi->cfg0); |
829 | if (ioread16(&si->cfg_running) == SWITCHTEC_CFG0_RUNNING) | ||
830 | info.active |= SWITCHTEC_IOCTL_PART_RUNNING; | ||
819 | break; | 831 | break; |
820 | case SWITCHTEC_IOCTL_PART_CFG1: | 832 | case SWITCHTEC_IOCTL_PART_CFG1: |
821 | active_addr = ioread32(&fi->active_cfg); | 833 | active_addr = ioread32(&fi->active_cfg); |
822 | set_fw_info_part(&info, &fi->cfg1); | 834 | set_fw_info_part(&info, &fi->cfg1); |
835 | if (ioread16(&si->cfg_running) == SWITCHTEC_CFG1_RUNNING) | ||
836 | info.active |= SWITCHTEC_IOCTL_PART_RUNNING; | ||
823 | break; | 837 | break; |
824 | case SWITCHTEC_IOCTL_PART_IMG0: | 838 | case SWITCHTEC_IOCTL_PART_IMG0: |
825 | active_addr = ioread32(&fi->active_img); | 839 | active_addr = ioread32(&fi->active_img); |
826 | set_fw_info_part(&info, &fi->img0); | 840 | set_fw_info_part(&info, &fi->img0); |
841 | if (ioread16(&si->img_running) == SWITCHTEC_IMG0_RUNNING) | ||
842 | info.active |= SWITCHTEC_IOCTL_PART_RUNNING; | ||
827 | break; | 843 | break; |
828 | case SWITCHTEC_IOCTL_PART_IMG1: | 844 | case SWITCHTEC_IOCTL_PART_IMG1: |
829 | active_addr = ioread32(&fi->active_img); | 845 | active_addr = ioread32(&fi->active_img); |
830 | set_fw_info_part(&info, &fi->img1); | 846 | set_fw_info_part(&info, &fi->img1); |
847 | if (ioread16(&si->img_running) == SWITCHTEC_IMG1_RUNNING) | ||
848 | info.active |= SWITCHTEC_IOCTL_PART_RUNNING; | ||
831 | break; | 849 | break; |
832 | case SWITCHTEC_IOCTL_PART_NVLOG: | 850 | case SWITCHTEC_IOCTL_PART_NVLOG: |
833 | set_fw_info_part(&info, &fi->nvlog); | 851 | set_fw_info_part(&info, &fi->nvlog); |
@@ -861,7 +879,7 @@ static int ioctl_flash_part_info(struct switchtec_dev *stdev, | |||
861 | } | 879 | } |
862 | 880 | ||
863 | if (info.address == active_addr) | 881 | if (info.address == active_addr) |
864 | info.active = 1; | 882 | info.active |= SWITCHTEC_IOCTL_PART_ACTIVE; |
865 | 883 | ||
866 | if (copy_to_user(uinfo, &info, sizeof(info))) | 884 | if (copy_to_user(uinfo, &info, sizeof(info))) |
867 | return -EFAULT; | 885 | return -EFAULT; |
@@ -1291,7 +1309,6 @@ static struct switchtec_dev *stdev_create(struct pci_dev *pdev) | |||
1291 | cdev = &stdev->cdev; | 1309 | cdev = &stdev->cdev; |
1292 | cdev_init(cdev, &switchtec_fops); | 1310 | cdev_init(cdev, &switchtec_fops); |
1293 | cdev->owner = THIS_MODULE; | 1311 | cdev->owner = THIS_MODULE; |
1294 | cdev->kobj.parent = &dev->kobj; | ||
1295 | 1312 | ||
1296 | return stdev; | 1313 | return stdev; |
1297 | 1314 | ||
@@ -1442,12 +1459,15 @@ static int switchtec_init_pci(struct switchtec_dev *stdev, | |||
1442 | stdev->mmio_sys_info = stdev->mmio + SWITCHTEC_GAS_SYS_INFO_OFFSET; | 1459 | stdev->mmio_sys_info = stdev->mmio + SWITCHTEC_GAS_SYS_INFO_OFFSET; |
1443 | stdev->mmio_flash_info = stdev->mmio + SWITCHTEC_GAS_FLASH_INFO_OFFSET; | 1460 | stdev->mmio_flash_info = stdev->mmio + SWITCHTEC_GAS_FLASH_INFO_OFFSET; |
1444 | stdev->mmio_ntb = stdev->mmio + SWITCHTEC_GAS_NTB_OFFSET; | 1461 | stdev->mmio_ntb = stdev->mmio + SWITCHTEC_GAS_NTB_OFFSET; |
1445 | stdev->partition = ioread8(&stdev->mmio_ntb->partition_id); | 1462 | stdev->partition = ioread8(&stdev->mmio_sys_info->partition_id); |
1446 | stdev->partition_count = ioread8(&stdev->mmio_ntb->partition_count); | 1463 | stdev->partition_count = ioread8(&stdev->mmio_ntb->partition_count); |
1447 | stdev->mmio_part_cfg_all = stdev->mmio + SWITCHTEC_GAS_PART_CFG_OFFSET; | 1464 | stdev->mmio_part_cfg_all = stdev->mmio + SWITCHTEC_GAS_PART_CFG_OFFSET; |
1448 | stdev->mmio_part_cfg = &stdev->mmio_part_cfg_all[stdev->partition]; | 1465 | stdev->mmio_part_cfg = &stdev->mmio_part_cfg_all[stdev->partition]; |
1449 | stdev->mmio_pff_csr = stdev->mmio + SWITCHTEC_GAS_PFF_CSR_OFFSET; | 1466 | stdev->mmio_pff_csr = stdev->mmio + SWITCHTEC_GAS_PFF_CSR_OFFSET; |
1450 | 1467 | ||
1468 | if (stdev->partition_count < 1) | ||
1469 | stdev->partition_count = 1; | ||
1470 | |||
1451 | init_pff(stdev); | 1471 | init_pff(stdev); |
1452 | 1472 | ||
1453 | pci_set_drvdata(pdev, stdev); | 1473 | pci_set_drvdata(pdev, stdev); |
@@ -1479,11 +1499,7 @@ static int switchtec_pci_probe(struct pci_dev *pdev, | |||
1479 | SWITCHTEC_EVENT_EN_IRQ, | 1499 | SWITCHTEC_EVENT_EN_IRQ, |
1480 | &stdev->mmio_part_cfg->mrpc_comp_hdr); | 1500 | &stdev->mmio_part_cfg->mrpc_comp_hdr); |
1481 | 1501 | ||
1482 | rc = cdev_add(&stdev->cdev, stdev->dev.devt, 1); | 1502 | rc = cdev_device_add(&stdev->cdev, &stdev->dev); |
1483 | if (rc) | ||
1484 | goto err_put; | ||
1485 | |||
1486 | rc = device_add(&stdev->dev); | ||
1487 | if (rc) | 1503 | if (rc) |
1488 | goto err_devadd; | 1504 | goto err_devadd; |
1489 | 1505 | ||
@@ -1492,7 +1508,6 @@ static int switchtec_pci_probe(struct pci_dev *pdev, | |||
1492 | return 0; | 1508 | return 0; |
1493 | 1509 | ||
1494 | err_devadd: | 1510 | err_devadd: |
1495 | cdev_del(&stdev->cdev); | ||
1496 | stdev_kill(stdev); | 1511 | stdev_kill(stdev); |
1497 | err_put: | 1512 | err_put: |
1498 | ida_simple_remove(&switchtec_minor_ida, MINOR(stdev->dev.devt)); | 1513 | ida_simple_remove(&switchtec_minor_ida, MINOR(stdev->dev.devt)); |
@@ -1506,8 +1521,7 @@ static void switchtec_pci_remove(struct pci_dev *pdev) | |||
1506 | 1521 | ||
1507 | pci_set_drvdata(pdev, NULL); | 1522 | pci_set_drvdata(pdev, NULL); |
1508 | 1523 | ||
1509 | device_del(&stdev->dev); | 1524 | cdev_device_del(&stdev->cdev, &stdev->dev); |
1510 | cdev_del(&stdev->cdev); | ||
1511 | ida_simple_remove(&switchtec_minor_ida, MINOR(stdev->dev.devt)); | 1525 | ida_simple_remove(&switchtec_minor_ida, MINOR(stdev->dev.devt)); |
1512 | dev_info(&stdev->dev, "unregistered.\n"); | 1526 | dev_info(&stdev->dev, "unregistered.\n"); |
1513 | 1527 | ||
@@ -1544,6 +1558,24 @@ static const struct pci_device_id switchtec_pci_tbl[] = { | |||
1544 | SWITCHTEC_PCI_DEVICE(0x8544), //PSX 64xG3 | 1558 | SWITCHTEC_PCI_DEVICE(0x8544), //PSX 64xG3 |
1545 | SWITCHTEC_PCI_DEVICE(0x8545), //PSX 80xG3 | 1559 | SWITCHTEC_PCI_DEVICE(0x8545), //PSX 80xG3 |
1546 | SWITCHTEC_PCI_DEVICE(0x8546), //PSX 96xG3 | 1560 | SWITCHTEC_PCI_DEVICE(0x8546), //PSX 96xG3 |
1561 | SWITCHTEC_PCI_DEVICE(0x8551), //PAX 24XG3 | ||
1562 | SWITCHTEC_PCI_DEVICE(0x8552), //PAX 32XG3 | ||
1563 | SWITCHTEC_PCI_DEVICE(0x8553), //PAX 48XG3 | ||
1564 | SWITCHTEC_PCI_DEVICE(0x8554), //PAX 64XG3 | ||
1565 | SWITCHTEC_PCI_DEVICE(0x8555), //PAX 80XG3 | ||
1566 | SWITCHTEC_PCI_DEVICE(0x8556), //PAX 96XG3 | ||
1567 | SWITCHTEC_PCI_DEVICE(0x8561), //PFXL 24XG3 | ||
1568 | SWITCHTEC_PCI_DEVICE(0x8562), //PFXL 32XG3 | ||
1569 | SWITCHTEC_PCI_DEVICE(0x8563), //PFXL 48XG3 | ||
1570 | SWITCHTEC_PCI_DEVICE(0x8564), //PFXL 64XG3 | ||
1571 | SWITCHTEC_PCI_DEVICE(0x8565), //PFXL 80XG3 | ||
1572 | SWITCHTEC_PCI_DEVICE(0x8566), //PFXL 96XG3 | ||
1573 | SWITCHTEC_PCI_DEVICE(0x8571), //PFXI 24XG3 | ||
1574 | SWITCHTEC_PCI_DEVICE(0x8572), //PFXI 32XG3 | ||
1575 | SWITCHTEC_PCI_DEVICE(0x8573), //PFXI 48XG3 | ||
1576 | SWITCHTEC_PCI_DEVICE(0x8574), //PFXI 64XG3 | ||
1577 | SWITCHTEC_PCI_DEVICE(0x8575), //PFXI 80XG3 | ||
1578 | SWITCHTEC_PCI_DEVICE(0x8576), //PFXI 96XG3 | ||
1547 | {0} | 1579 | {0} |
1548 | }; | 1580 | }; |
1549 | MODULE_DEVICE_TABLE(pci, switchtec_pci_tbl); | 1581 | MODULE_DEVICE_TABLE(pci, switchtec_pci_tbl); |