diff options
Diffstat (limited to 'drivers/i2c')
-rw-r--r-- | drivers/i2c/busses/i2c-designware-platdrv.c | 33 | ||||
-rw-r--r-- | drivers/i2c/busses/i2c-rcar.c | 7 | ||||
-rw-r--r-- | drivers/i2c/busses/i2c-s3c2410.c | 8 | ||||
-rw-r--r-- | drivers/i2c/i2c-core.c | 12 |
4 files changed, 42 insertions, 18 deletions
diff --git a/drivers/i2c/busses/i2c-designware-platdrv.c b/drivers/i2c/busses/i2c-designware-platdrv.c index 3dd2de31a2f8..472b88285c75 100644 --- a/drivers/i2c/busses/i2c-designware-platdrv.c +++ b/drivers/i2c/busses/i2c-designware-platdrv.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <linux/kernel.h> | 24 | #include <linux/kernel.h> |
25 | #include <linux/module.h> | 25 | #include <linux/module.h> |
26 | #include <linux/delay.h> | 26 | #include <linux/delay.h> |
27 | #include <linux/dmi.h> | ||
27 | #include <linux/i2c.h> | 28 | #include <linux/i2c.h> |
28 | #include <linux/clk.h> | 29 | #include <linux/clk.h> |
29 | #include <linux/clk-provider.h> | 30 | #include <linux/clk-provider.h> |
@@ -51,6 +52,22 @@ static u32 i2c_dw_get_clk_rate_khz(struct dw_i2c_dev *dev) | |||
51 | } | 52 | } |
52 | 53 | ||
53 | #ifdef CONFIG_ACPI | 54 | #ifdef CONFIG_ACPI |
55 | /* | ||
56 | * The HCNT/LCNT information coming from ACPI should be the most accurate | ||
57 | * for given platform. However, some systems get it wrong. On such systems | ||
58 | * we get better results by calculating those based on the input clock. | ||
59 | */ | ||
60 | static const struct dmi_system_id dw_i2c_no_acpi_params[] = { | ||
61 | { | ||
62 | .ident = "Dell Inspiron 7348", | ||
63 | .matches = { | ||
64 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | ||
65 | DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 7348"), | ||
66 | }, | ||
67 | }, | ||
68 | { } | ||
69 | }; | ||
70 | |||
54 | static void dw_i2c_acpi_params(struct platform_device *pdev, char method[], | 71 | static void dw_i2c_acpi_params(struct platform_device *pdev, char method[], |
55 | u16 *hcnt, u16 *lcnt, u32 *sda_hold) | 72 | u16 *hcnt, u16 *lcnt, u32 *sda_hold) |
56 | { | 73 | { |
@@ -58,6 +75,9 @@ static void dw_i2c_acpi_params(struct platform_device *pdev, char method[], | |||
58 | acpi_handle handle = ACPI_HANDLE(&pdev->dev); | 75 | acpi_handle handle = ACPI_HANDLE(&pdev->dev); |
59 | union acpi_object *obj; | 76 | union acpi_object *obj; |
60 | 77 | ||
78 | if (dmi_check_system(dw_i2c_no_acpi_params)) | ||
79 | return; | ||
80 | |||
61 | if (ACPI_FAILURE(acpi_evaluate_object(handle, method, NULL, &buf))) | 81 | if (ACPI_FAILURE(acpi_evaluate_object(handle, method, NULL, &buf))) |
62 | return; | 82 | return; |
63 | 83 | ||
@@ -253,12 +273,6 @@ static int dw_i2c_probe(struct platform_device *pdev) | |||
253 | adap->dev.parent = &pdev->dev; | 273 | adap->dev.parent = &pdev->dev; |
254 | adap->dev.of_node = pdev->dev.of_node; | 274 | adap->dev.of_node = pdev->dev.of_node; |
255 | 275 | ||
256 | r = i2c_add_numbered_adapter(adap); | ||
257 | if (r) { | ||
258 | dev_err(&pdev->dev, "failure adding adapter\n"); | ||
259 | return r; | ||
260 | } | ||
261 | |||
262 | if (dev->pm_runtime_disabled) { | 276 | if (dev->pm_runtime_disabled) { |
263 | pm_runtime_forbid(&pdev->dev); | 277 | pm_runtime_forbid(&pdev->dev); |
264 | } else { | 278 | } else { |
@@ -268,6 +282,13 @@ static int dw_i2c_probe(struct platform_device *pdev) | |||
268 | pm_runtime_enable(&pdev->dev); | 282 | pm_runtime_enable(&pdev->dev); |
269 | } | 283 | } |
270 | 284 | ||
285 | r = i2c_add_numbered_adapter(adap); | ||
286 | if (r) { | ||
287 | dev_err(&pdev->dev, "failure adding adapter\n"); | ||
288 | pm_runtime_disable(&pdev->dev); | ||
289 | return r; | ||
290 | } | ||
291 | |||
271 | return 0; | 292 | return 0; |
272 | } | 293 | } |
273 | 294 | ||
diff --git a/drivers/i2c/busses/i2c-rcar.c b/drivers/i2c/busses/i2c-rcar.c index d8361dada584..d8b5a8fee1e6 100644 --- a/drivers/i2c/busses/i2c-rcar.c +++ b/drivers/i2c/busses/i2c-rcar.c | |||
@@ -690,15 +690,16 @@ static int rcar_i2c_probe(struct platform_device *pdev) | |||
690 | return ret; | 690 | return ret; |
691 | } | 691 | } |
692 | 692 | ||
693 | pm_runtime_enable(dev); | ||
694 | platform_set_drvdata(pdev, priv); | ||
695 | |||
693 | ret = i2c_add_numbered_adapter(adap); | 696 | ret = i2c_add_numbered_adapter(adap); |
694 | if (ret < 0) { | 697 | if (ret < 0) { |
695 | dev_err(dev, "reg adap failed: %d\n", ret); | 698 | dev_err(dev, "reg adap failed: %d\n", ret); |
699 | pm_runtime_disable(dev); | ||
696 | return ret; | 700 | return ret; |
697 | } | 701 | } |
698 | 702 | ||
699 | pm_runtime_enable(dev); | ||
700 | platform_set_drvdata(pdev, priv); | ||
701 | |||
702 | dev_info(dev, "probed\n"); | 703 | dev_info(dev, "probed\n"); |
703 | 704 | ||
704 | return 0; | 705 | return 0; |
diff --git a/drivers/i2c/busses/i2c-s3c2410.c b/drivers/i2c/busses/i2c-s3c2410.c index 50bfd8cef5f2..5df819610d52 100644 --- a/drivers/i2c/busses/i2c-s3c2410.c +++ b/drivers/i2c/busses/i2c-s3c2410.c | |||
@@ -1243,17 +1243,19 @@ static int s3c24xx_i2c_probe(struct platform_device *pdev) | |||
1243 | i2c->adap.nr = i2c->pdata->bus_num; | 1243 | i2c->adap.nr = i2c->pdata->bus_num; |
1244 | i2c->adap.dev.of_node = pdev->dev.of_node; | 1244 | i2c->adap.dev.of_node = pdev->dev.of_node; |
1245 | 1245 | ||
1246 | platform_set_drvdata(pdev, i2c); | ||
1247 | |||
1248 | pm_runtime_enable(&pdev->dev); | ||
1249 | |||
1246 | ret = i2c_add_numbered_adapter(&i2c->adap); | 1250 | ret = i2c_add_numbered_adapter(&i2c->adap); |
1247 | if (ret < 0) { | 1251 | if (ret < 0) { |
1248 | dev_err(&pdev->dev, "failed to add bus to i2c core\n"); | 1252 | dev_err(&pdev->dev, "failed to add bus to i2c core\n"); |
1253 | pm_runtime_disable(&pdev->dev); | ||
1249 | s3c24xx_i2c_deregister_cpufreq(i2c); | 1254 | s3c24xx_i2c_deregister_cpufreq(i2c); |
1250 | clk_unprepare(i2c->clk); | 1255 | clk_unprepare(i2c->clk); |
1251 | return ret; | 1256 | return ret; |
1252 | } | 1257 | } |
1253 | 1258 | ||
1254 | platform_set_drvdata(pdev, i2c); | ||
1255 | |||
1256 | pm_runtime_enable(&pdev->dev); | ||
1257 | pm_runtime_enable(&i2c->adap.dev); | 1259 | pm_runtime_enable(&i2c->adap.dev); |
1258 | 1260 | ||
1259 | dev_info(&pdev->dev, "%s: S3C I2C adapter\n", dev_name(&i2c->adap.dev)); | 1261 | dev_info(&pdev->dev, "%s: S3C I2C adapter\n", dev_name(&i2c->adap.dev)); |
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index 5f89f1e3c2f2..a59c3111f7fb 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c | |||
@@ -694,12 +694,12 @@ static int i2c_device_probe(struct device *dev) | |||
694 | goto err_clear_wakeup_irq; | 694 | goto err_clear_wakeup_irq; |
695 | 695 | ||
696 | status = dev_pm_domain_attach(&client->dev, true); | 696 | status = dev_pm_domain_attach(&client->dev, true); |
697 | if (status != -EPROBE_DEFER) { | 697 | if (status == -EPROBE_DEFER) |
698 | status = driver->probe(client, i2c_match_id(driver->id_table, | 698 | goto err_clear_wakeup_irq; |
699 | client)); | 699 | |
700 | if (status) | 700 | status = driver->probe(client, i2c_match_id(driver->id_table, client)); |
701 | goto err_detach_pm_domain; | 701 | if (status) |
702 | } | 702 | goto err_detach_pm_domain; |
703 | 703 | ||
704 | return 0; | 704 | return 0; |
705 | 705 | ||