diff options
-rw-r--r-- | drivers/platform/x86/intel_pmc_ipc.c | 94 |
1 files changed, 28 insertions, 66 deletions
diff --git a/drivers/platform/x86/intel_pmc_ipc.c b/drivers/platform/x86/intel_pmc_ipc.c index bb792a52248b..751b1212d01c 100644 --- a/drivers/platform/x86/intel_pmc_ipc.c +++ b/drivers/platform/x86/intel_pmc_ipc.c | |||
@@ -480,52 +480,39 @@ static irqreturn_t ioc(int irq, void *dev_id) | |||
480 | 480 | ||
481 | static int ipc_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) | 481 | static int ipc_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) |
482 | { | 482 | { |
483 | resource_size_t pci_resource; | 483 | struct intel_pmc_ipc_dev *pmc = &ipcdev; |
484 | int ret; | 484 | int ret; |
485 | int len; | ||
486 | 485 | ||
487 | ipcdev.dev = &pci_dev_get(pdev)->dev; | 486 | /* Only one PMC is supported */ |
488 | ipcdev.irq_mode = IPC_TRIGGER_MODE_IRQ; | 487 | if (pmc->dev) |
488 | return -EBUSY; | ||
489 | 489 | ||
490 | ret = pci_enable_device(pdev); | 490 | pmc->irq_mode = IPC_TRIGGER_MODE_IRQ; |
491 | |||
492 | ret = pcim_enable_device(pdev); | ||
491 | if (ret) | 493 | if (ret) |
492 | return ret; | 494 | return ret; |
493 | 495 | ||
494 | ret = pci_request_regions(pdev, "intel_pmc_ipc"); | 496 | ret = pcim_iomap_regions(pdev, 1 << 0, pci_name(pdev)); |
495 | if (ret) | 497 | if (ret) |
496 | return ret; | 498 | return ret; |
497 | 499 | ||
498 | pci_resource = pci_resource_start(pdev, 0); | 500 | init_completion(&pmc->cmd_complete); |
499 | len = pci_resource_len(pdev, 0); | ||
500 | if (!pci_resource || !len) { | ||
501 | dev_err(&pdev->dev, "Failed to get resource\n"); | ||
502 | return -ENOMEM; | ||
503 | } | ||
504 | 501 | ||
505 | init_completion(&ipcdev.cmd_complete); | 502 | pmc->ipc_base = pcim_iomap_table(pdev)[0]; |
506 | 503 | ||
507 | if (request_irq(pdev->irq, ioc, 0, "intel_pmc_ipc", &ipcdev)) { | 504 | ret = devm_request_irq(&pdev->dev, pdev->irq, ioc, 0, "intel_pmc_ipc", |
505 | pmc); | ||
506 | if (ret) { | ||
508 | dev_err(&pdev->dev, "Failed to request irq\n"); | 507 | dev_err(&pdev->dev, "Failed to request irq\n"); |
509 | return -EBUSY; | 508 | return ret; |
510 | } | 509 | } |
511 | 510 | ||
512 | ipcdev.ipc_base = ioremap_nocache(pci_resource, len); | 511 | pmc->dev = &pdev->dev; |
513 | if (!ipcdev.ipc_base) { | ||
514 | dev_err(&pdev->dev, "Failed to ioremap ipc base\n"); | ||
515 | free_irq(pdev->irq, &ipcdev); | ||
516 | ret = -ENOMEM; | ||
517 | } | ||
518 | 512 | ||
519 | return ret; | 513 | pci_set_drvdata(pdev, pmc); |
520 | } | ||
521 | 514 | ||
522 | static void ipc_pci_remove(struct pci_dev *pdev) | 515 | return 0; |
523 | { | ||
524 | free_irq(pdev->irq, &ipcdev); | ||
525 | pci_release_regions(pdev); | ||
526 | pci_dev_put(pdev); | ||
527 | iounmap(ipcdev.ipc_base); | ||
528 | ipcdev.dev = NULL; | ||
529 | } | 516 | } |
530 | 517 | ||
531 | static const struct pci_device_id ipc_pci_ids[] = { | 518 | static const struct pci_device_id ipc_pci_ids[] = { |
@@ -540,7 +527,6 @@ static struct pci_driver ipc_pci_driver = { | |||
540 | .name = "intel_pmc_ipc", | 527 | .name = "intel_pmc_ipc", |
541 | .id_table = ipc_pci_ids, | 528 | .id_table = ipc_pci_ids, |
542 | .probe = ipc_pci_probe, | 529 | .probe = ipc_pci_probe, |
543 | .remove = ipc_pci_remove, | ||
544 | }; | 530 | }; |
545 | 531 | ||
546 | static ssize_t intel_pmc_ipc_simple_cmd_store(struct device *dev, | 532 | static ssize_t intel_pmc_ipc_simple_cmd_store(struct device *dev, |
@@ -850,17 +836,12 @@ static int ipc_plat_get_res(struct platform_device *pdev) | |||
850 | return -ENXIO; | 836 | return -ENXIO; |
851 | } | 837 | } |
852 | size = PLAT_RESOURCE_IPC_SIZE + PLAT_RESOURCE_GCR_SIZE; | 838 | size = PLAT_RESOURCE_IPC_SIZE + PLAT_RESOURCE_GCR_SIZE; |
839 | res->end = res->start + size - 1; | ||
840 | |||
841 | addr = devm_ioremap_resource(&pdev->dev, res); | ||
842 | if (IS_ERR(addr)) | ||
843 | return PTR_ERR(addr); | ||
853 | 844 | ||
854 | if (!request_mem_region(res->start, size, pdev->name)) { | ||
855 | dev_err(&pdev->dev, "Failed to request ipc resource\n"); | ||
856 | return -EBUSY; | ||
857 | } | ||
858 | addr = ioremap_nocache(res->start, size); | ||
859 | if (!addr) { | ||
860 | dev_err(&pdev->dev, "I/O memory remapping failed\n"); | ||
861 | release_mem_region(res->start, size); | ||
862 | return -ENOMEM; | ||
863 | } | ||
864 | ipcdev.ipc_base = addr; | 845 | ipcdev.ipc_base = addr; |
865 | 846 | ||
866 | ipcdev.gcr_mem_base = addr + PLAT_RESOURCE_GCR_OFFSET; | 847 | ipcdev.gcr_mem_base = addr + PLAT_RESOURCE_GCR_OFFSET; |
@@ -917,7 +898,6 @@ MODULE_DEVICE_TABLE(acpi, ipc_acpi_ids); | |||
917 | 898 | ||
918 | static int ipc_plat_probe(struct platform_device *pdev) | 899 | static int ipc_plat_probe(struct platform_device *pdev) |
919 | { | 900 | { |
920 | struct resource *res; | ||
921 | int ret; | 901 | int ret; |
922 | 902 | ||
923 | ipcdev.dev = &pdev->dev; | 903 | ipcdev.dev = &pdev->dev; |
@@ -939,11 +919,11 @@ static int ipc_plat_probe(struct platform_device *pdev) | |||
939 | ret = ipc_create_pmc_devices(); | 919 | ret = ipc_create_pmc_devices(); |
940 | if (ret) { | 920 | if (ret) { |
941 | dev_err(&pdev->dev, "Failed to create pmc devices\n"); | 921 | dev_err(&pdev->dev, "Failed to create pmc devices\n"); |
942 | goto err_device; | 922 | return ret; |
943 | } | 923 | } |
944 | 924 | ||
945 | if (request_irq(ipcdev.irq, ioc, IRQF_NO_SUSPEND, | 925 | if (devm_request_irq(&pdev->dev, ipcdev.irq, ioc, IRQF_NO_SUSPEND, |
946 | "intel_pmc_ipc", &ipcdev)) { | 926 | "intel_pmc_ipc", &ipcdev)) { |
947 | dev_err(&pdev->dev, "Failed to request irq\n"); | 927 | dev_err(&pdev->dev, "Failed to request irq\n"); |
948 | ret = -EBUSY; | 928 | ret = -EBUSY; |
949 | goto err_irq; | 929 | goto err_irq; |
@@ -960,40 +940,22 @@ static int ipc_plat_probe(struct platform_device *pdev) | |||
960 | 940 | ||
961 | return 0; | 941 | return 0; |
962 | err_sys: | 942 | err_sys: |
963 | free_irq(ipcdev.irq, &ipcdev); | 943 | devm_free_irq(&pdev->dev, ipcdev.irq, &ipcdev); |
964 | err_irq: | 944 | err_irq: |
965 | platform_device_unregister(ipcdev.tco_dev); | 945 | platform_device_unregister(ipcdev.tco_dev); |
966 | platform_device_unregister(ipcdev.punit_dev); | 946 | platform_device_unregister(ipcdev.punit_dev); |
967 | platform_device_unregister(ipcdev.telemetry_dev); | 947 | platform_device_unregister(ipcdev.telemetry_dev); |
968 | err_device: | 948 | |
969 | iounmap(ipcdev.ipc_base); | ||
970 | res = platform_get_resource(pdev, IORESOURCE_MEM, | ||
971 | PLAT_RESOURCE_IPC_INDEX); | ||
972 | if (res) { | ||
973 | release_mem_region(res->start, | ||
974 | PLAT_RESOURCE_IPC_SIZE + | ||
975 | PLAT_RESOURCE_GCR_SIZE); | ||
976 | } | ||
977 | return ret; | 949 | return ret; |
978 | } | 950 | } |
979 | 951 | ||
980 | static int ipc_plat_remove(struct platform_device *pdev) | 952 | static int ipc_plat_remove(struct platform_device *pdev) |
981 | { | 953 | { |
982 | struct resource *res; | ||
983 | |||
984 | sysfs_remove_group(&pdev->dev.kobj, &intel_ipc_group); | 954 | sysfs_remove_group(&pdev->dev.kobj, &intel_ipc_group); |
985 | free_irq(ipcdev.irq, &ipcdev); | 955 | devm_free_irq(&pdev->dev, ipcdev.irq, &ipcdev); |
986 | platform_device_unregister(ipcdev.tco_dev); | 956 | platform_device_unregister(ipcdev.tco_dev); |
987 | platform_device_unregister(ipcdev.punit_dev); | 957 | platform_device_unregister(ipcdev.punit_dev); |
988 | platform_device_unregister(ipcdev.telemetry_dev); | 958 | platform_device_unregister(ipcdev.telemetry_dev); |
989 | iounmap(ipcdev.ipc_base); | ||
990 | res = platform_get_resource(pdev, IORESOURCE_MEM, | ||
991 | PLAT_RESOURCE_IPC_INDEX); | ||
992 | if (res) { | ||
993 | release_mem_region(res->start, | ||
994 | PLAT_RESOURCE_IPC_SIZE + | ||
995 | PLAT_RESOURCE_GCR_SIZE); | ||
996 | } | ||
997 | ipcdev.dev = NULL; | 959 | ipcdev.dev = NULL; |
998 | return 0; | 960 | return 0; |
999 | } | 961 | } |