aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci/switch/switchtec.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pci/switch/switchtec.c')
-rw-r--r--drivers/pci/switch/switchtec.c56
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
123enum {
124 SWITCHTEC_CFG0_RUNNING = 0x04,
125 SWITCHTEC_CFG1_RUNNING = 0x05,
126 SWITCHTEC_IMG0_RUNNING = 0x03,
127 SWITCHTEC_IMG1_RUNNING = 0x07,
128};
129
123struct sys_info_regs { 130struct 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
1494err_devadd: 1510err_devadd:
1495 cdev_del(&stdev->cdev);
1496 stdev_kill(stdev); 1511 stdev_kill(stdev);
1497err_put: 1512err_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};
1549MODULE_DEVICE_TABLE(pci, switchtec_pci_tbl); 1581MODULE_DEVICE_TABLE(pci, switchtec_pci_tbl);