Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

PCI: kirin: Add dev struct for of_device_get_match_data()

Bean reported that a622435fbe1a ("PCI: kirin: Prefer
of_device_get_match_data()") broke kirin_pcie_probe() because it assumed
match data of 0 was a failure when in fact, it meant the match data was
"(void *)PCIE_KIRIN_INTERNAL_PHY".

Therefore, probing of "hisilicon,kirin960-pcie" devices failed with -EINVAL
and an "OF data missing" message.

Add a struct kirin_pcie_data to encode the PHY type. Then the result of
of_device_get_match_data() should always be a non-NULL pointer to a struct
kirin_pcie_data that contains the PHY type.

Fixes: a622435fbe1a ("PCI: kirin: Prefer of_device_get_match_data()")
Link: https://lore.kernel.org/r/20220202162659.GA12603@bhelgaas
Link: https://lore.kernel.org/r/20220201215941.1203155-1-huobean@gmail.com
Reported-by: Bean Huo <beanhuo@micron.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>

+18 -13
+18 -13
drivers/pci/controller/dwc/pcie-kirin.c
··· 756 756 return 0; 757 757 } 758 758 759 + struct kirin_pcie_data { 760 + enum pcie_kirin_phy_type phy_type; 761 + }; 762 + 763 + static const struct kirin_pcie_data kirin_960_data = { 764 + .phy_type = PCIE_KIRIN_INTERNAL_PHY, 765 + }; 766 + 767 + static const struct kirin_pcie_data kirin_970_data = { 768 + .phy_type = PCIE_KIRIN_EXTERNAL_PHY, 769 + }; 770 + 759 771 static const struct of_device_id kirin_pcie_match[] = { 760 - { 761 - .compatible = "hisilicon,kirin960-pcie", 762 - .data = (void *)PCIE_KIRIN_INTERNAL_PHY 763 - }, 764 - { 765 - .compatible = "hisilicon,kirin970-pcie", 766 - .data = (void *)PCIE_KIRIN_EXTERNAL_PHY 767 - }, 772 + { .compatible = "hisilicon,kirin960-pcie", .data = &kirin_960_data }, 773 + { .compatible = "hisilicon,kirin970-pcie", .data = &kirin_970_data }, 768 774 {}, 769 775 }; 770 776 771 777 static int kirin_pcie_probe(struct platform_device *pdev) 772 778 { 773 - enum pcie_kirin_phy_type phy_type; 774 779 struct device *dev = &pdev->dev; 780 + const struct kirin_pcie_data *data; 775 781 struct kirin_pcie *kirin_pcie; 776 782 struct dw_pcie *pci; 777 783 int ret; ··· 787 781 return -EINVAL; 788 782 } 789 783 790 - phy_type = (long)of_device_get_match_data(dev); 791 - if (!phy_type) { 784 + data = of_device_get_match_data(dev); 785 + if (!data) { 792 786 dev_err(dev, "OF data missing\n"); 793 787 return -EINVAL; 794 788 } 795 - 796 789 797 790 kirin_pcie = devm_kzalloc(dev, sizeof(struct kirin_pcie), GFP_KERNEL); 798 791 if (!kirin_pcie) ··· 805 800 pci->ops = &kirin_dw_pcie_ops; 806 801 pci->pp.ops = &kirin_pcie_host_ops; 807 802 kirin_pcie->pci = pci; 808 - kirin_pcie->type = phy_type; 803 + kirin_pcie->type = data->phy_type; 809 804 810 805 ret = kirin_pcie_get_resource(kirin_pcie, pdev); 811 806 if (ret)