aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/i2c/busses/i2c-designware-platdrv.c
diff options
context:
space:
mode:
authorCarl Peng <carlpeng008@gmail.com>2014-09-30 06:04:55 -0400
committerWolfram Sang <wsa@the-dreams.de>2014-10-06 13:50:21 -0400
commita445900c906092f3b49ee40a7365d0d54acc568e (patch)
tree93e68e3b3826d394d13f82ba89e52343f359a42c /drivers/i2c/busses/i2c-designware-platdrv.c
parent925ddb240d6c76e56dd3aa22493f5755c452ba61 (diff)
i2c: designware: Add support for AMD I2C controller
Add support for AMD version of the DW I2C host controller. The device is enumerated from ACPI namespace with ACPI ID AMD0010. Because the core driver needs an input source clock, and this is not an Intel LPSS device where clocks are provided through drivers/acpi/acpi_lpss.c, we register the clock ourselves if the clock rate is given in ->driver_data Signed-off-by: Carl Peng <carlpeng008@gmail.com> Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com> Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
Diffstat (limited to 'drivers/i2c/busses/i2c-designware-platdrv.c')
-rw-r--r--drivers/i2c/busses/i2c-designware-platdrv.c27
1 files changed, 27 insertions, 0 deletions
diff --git a/drivers/i2c/busses/i2c-designware-platdrv.c b/drivers/i2c/busses/i2c-designware-platdrv.c
index e59c63ae4d41..a7431150acf7 100644
--- a/drivers/i2c/busses/i2c-designware-platdrv.c
+++ b/drivers/i2c/busses/i2c-designware-platdrv.c
@@ -30,6 +30,7 @@
30#include <linux/delay.h> 30#include <linux/delay.h>
31#include <linux/i2c.h> 31#include <linux/i2c.h>
32#include <linux/clk.h> 32#include <linux/clk.h>
33#include <linux/clk-provider.h>
33#include <linux/errno.h> 34#include <linux/errno.h>
34#include <linux/sched.h> 35#include <linux/sched.h>
35#include <linux/err.h> 36#include <linux/err.h>
@@ -80,6 +81,7 @@ static void dw_i2c_acpi_params(struct platform_device *pdev, char method[],
80static int dw_i2c_acpi_configure(struct platform_device *pdev) 81static int dw_i2c_acpi_configure(struct platform_device *pdev)
81{ 82{
82 struct dw_i2c_dev *dev = platform_get_drvdata(pdev); 83 struct dw_i2c_dev *dev = platform_get_drvdata(pdev);
84 const struct acpi_device_id *id;
83 85
84 dev->adapter.nr = -1; 86 dev->adapter.nr = -1;
85 dev->tx_fifo_depth = 32; 87 dev->tx_fifo_depth = 32;
@@ -93,9 +95,29 @@ static int dw_i2c_acpi_configure(struct platform_device *pdev)
93 dw_i2c_acpi_params(pdev, "FMCN", &dev->fs_hcnt, &dev->fs_lcnt, 95 dw_i2c_acpi_params(pdev, "FMCN", &dev->fs_hcnt, &dev->fs_lcnt,
94 &dev->sda_hold_time); 96 &dev->sda_hold_time);
95 97
98 /*
99 * Provide a way for Designware I2C host controllers that are not
100 * based on Intel LPSS to specify their input clock frequency via
101 * id->driver_data.
102 */
103 id = acpi_match_device(pdev->dev.driver->acpi_match_table, &pdev->dev);
104 if (id && id->driver_data)
105 clk_register_fixed_rate(&pdev->dev, dev_name(&pdev->dev), NULL,
106 CLK_IS_ROOT, id->driver_data);
107
96 return 0; 108 return 0;
97} 109}
98 110
111static void dw_i2c_acpi_unconfigure(struct platform_device *pdev)
112{
113 struct dw_i2c_dev *dev = platform_get_drvdata(pdev);
114 const struct acpi_device_id *id;
115
116 id = acpi_match_device(pdev->dev.driver->acpi_match_table, &pdev->dev);
117 if (id && id->driver_data)
118 clk_unregister(dev->clk);
119}
120
99static const struct acpi_device_id dw_i2c_acpi_match[] = { 121static const struct acpi_device_id dw_i2c_acpi_match[] = {
100 { "INT33C2", 0 }, 122 { "INT33C2", 0 },
101 { "INT33C3", 0 }, 123 { "INT33C3", 0 },
@@ -103,6 +125,7 @@ static const struct acpi_device_id dw_i2c_acpi_match[] = {
103 { "INT3433", 0 }, 125 { "INT3433", 0 },
104 { "80860F41", 0 }, 126 { "80860F41", 0 },
105 { "808622C1", 0 }, 127 { "808622C1", 0 },
128 { "AMD0010", 133 * 1000 * 1000 },
106 { } 129 { }
107}; 130};
108MODULE_DEVICE_TABLE(acpi, dw_i2c_acpi_match); 131MODULE_DEVICE_TABLE(acpi, dw_i2c_acpi_match);
@@ -111,6 +134,7 @@ static inline int dw_i2c_acpi_configure(struct platform_device *pdev)
111{ 134{
112 return -ENODEV; 135 return -ENODEV;
113} 136}
137static inline void dw_i2c_acpi_unconfigure(struct platform_device *pdev) { }
114#endif 138#endif
115 139
116static int dw_i2c_probe(struct platform_device *pdev) 140static int dw_i2c_probe(struct platform_device *pdev)
@@ -258,6 +282,9 @@ static int dw_i2c_remove(struct platform_device *pdev)
258 pm_runtime_put(&pdev->dev); 282 pm_runtime_put(&pdev->dev);
259 pm_runtime_disable(&pdev->dev); 283 pm_runtime_disable(&pdev->dev);
260 284
285 if (ACPI_COMPANION(&pdev->dev))
286 dw_i2c_acpi_unconfigure(pdev);
287
261 return 0; 288 return 0;
262} 289}
263 290