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

i2c-eg20t: correct the driver init order of pch_i2c_probe()

Before registering an adapter to i2c subsystem, we need make sure
driver is ready for incoming i2c xfer, becasue the i2c_add_adapter()
may trigger a i2c device driver's proble function which may start
some real i2c xfer. I met this issue when integrating a TSC2007 i2c
touch screen device with the i2c-eg20t driver.

This patch will call request_irq() and hw init before calling
i2c_add_adapter().

Signed-off-by: Feng Tang <feng.tang@intel.com>
Signed-off-by: Ben Dooks <ben-linux@fluff.org>

authored by

Feng Tang and committed by
Ben Dooks
0d5fb5ea 1d5a34fe

+12 -10
+12 -10
drivers/i2c/busses/i2c-eg20t.c
··· 893 893 /* Set the number of I2C channel instance */ 894 894 adap_info->ch_num = id->driver_data; 895 895 896 + ret = request_irq(pdev->irq, pch_i2c_handler, IRQF_SHARED, 897 + KBUILD_MODNAME, adap_info); 898 + if (ret) { 899 + pch_pci_err(pdev, "request_irq FAILED\n"); 900 + goto err_request_irq; 901 + } 902 + 896 903 for (i = 0; i < adap_info->ch_num; i++) { 897 904 pch_adap = &adap_info->pch_data[i].pch_adapter; 898 905 adap_info->pch_i2c_suspended = false; ··· 917 910 918 911 pch_adap->dev.parent = &pdev->dev; 919 912 913 + pch_i2c_init(&adap_info->pch_data[i]); 920 914 ret = i2c_add_adapter(pch_adap); 921 915 if (ret) { 922 916 pch_pci_err(pdev, "i2c_add_adapter[ch:%d] FAILED\n", i); 923 - goto err_i2c_add_adapter; 917 + goto err_add_adapter; 924 918 } 925 - 926 - pch_i2c_init(&adap_info->pch_data[i]); 927 - } 928 - ret = request_irq(pdev->irq, pch_i2c_handler, IRQF_SHARED, 929 - KBUILD_MODNAME, adap_info); 930 - if (ret) { 931 - pch_pci_err(pdev, "request_irq FAILED\n"); 932 - goto err_i2c_add_adapter; 933 919 } 934 920 935 921 pci_set_drvdata(pdev, adap_info); 936 922 pch_pci_dbg(pdev, "returns %d.\n", ret); 937 923 return 0; 938 924 939 - err_i2c_add_adapter: 925 + err_add_adapter: 940 926 for (j = 0; j < i; j++) 941 927 i2c_del_adapter(&adap_info->pch_data[j].pch_adapter); 928 + free_irq(pdev->irq, adap_info); 929 + err_request_irq: 942 930 pci_iounmap(pdev, base_addr); 943 931 err_pci_iomap: 944 932 pci_release_regions(pdev);