Commit d80d1341 authored by Jarkko Nikula's avatar Jarkko Nikula Committed by Wolfram Sang

i2c: designware: Move common probe code into i2c_dw_probe()

There is some code duplication in i2c-designware-platdrv and
i2c-designware-pcidrv probe functions. What is even worse that duplication
requires i2c_dw_xfer(), i2c_dw_func() and i2c_dw_isr() i2c-designware-core
functions to be exported.

Therefore move common code into new i2c_dw_probe() and make functions above
local to i2c-designware-core.

While merging the code patch does following functional changes:

- I2C Adapter name will be "Synopsys DesignWare I2C adapter". Previously it
  was used for platform and ACPI devices but PCI device used
  "i2c-designware-pci".
- Using device name for interrupt name. Previous it was platform device name,
  ACPI device name or "i2c-designware-pci".
- Error code from devm_request_irq() and i2c_add_numbered_adapter() will be
  printed in case of error.
Signed-off-by: default avatarJarkko Nikula <jarkko.nikula@linux.intel.com>
Signed-off-by: default avatarWolfram Sang <wsa@the-dreams.de>
parent 6ad6fde3
...@@ -618,7 +618,7 @@ static int i2c_dw_handle_tx_abort(struct dw_i2c_dev *dev) ...@@ -618,7 +618,7 @@ static int i2c_dw_handle_tx_abort(struct dw_i2c_dev *dev)
/* /*
* Prepare controller for a transaction and call i2c_dw_xfer_msg * Prepare controller for a transaction and call i2c_dw_xfer_msg
*/ */
int static int
i2c_dw_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num) i2c_dw_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
{ {
struct dw_i2c_dev *dev = i2c_get_adapdata(adap); struct dw_i2c_dev *dev = i2c_get_adapdata(adap);
...@@ -702,14 +702,17 @@ i2c_dw_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num) ...@@ -702,14 +702,17 @@ i2c_dw_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
return ret; return ret;
} }
EXPORT_SYMBOL_GPL(i2c_dw_xfer);
u32 i2c_dw_func(struct i2c_adapter *adap) static u32 i2c_dw_func(struct i2c_adapter *adap)
{ {
struct dw_i2c_dev *dev = i2c_get_adapdata(adap); struct dw_i2c_dev *dev = i2c_get_adapdata(adap);
return dev->functionality; return dev->functionality;
} }
EXPORT_SYMBOL_GPL(i2c_dw_func);
static struct i2c_algorithm i2c_dw_algo = {
.master_xfer = i2c_dw_xfer,
.functionality = i2c_dw_func,
};
static u32 i2c_dw_read_clear_intrbits(struct dw_i2c_dev *dev) static u32 i2c_dw_read_clear_intrbits(struct dw_i2c_dev *dev)
{ {
...@@ -770,7 +773,7 @@ static u32 i2c_dw_read_clear_intrbits(struct dw_i2c_dev *dev) ...@@ -770,7 +773,7 @@ static u32 i2c_dw_read_clear_intrbits(struct dw_i2c_dev *dev)
* Interrupt service routine. This gets called whenever an I2C interrupt * Interrupt service routine. This gets called whenever an I2C interrupt
* occurs. * occurs.
*/ */
irqreturn_t i2c_dw_isr(int this_irq, void *dev_id) static irqreturn_t i2c_dw_isr(int this_irq, void *dev_id)
{ {
struct dw_i2c_dev *dev = dev_id; struct dw_i2c_dev *dev = dev_id;
u32 stat, enabled; u32 stat, enabled;
...@@ -813,7 +816,6 @@ irqreturn_t i2c_dw_isr(int this_irq, void *dev_id) ...@@ -813,7 +816,6 @@ irqreturn_t i2c_dw_isr(int this_irq, void *dev_id)
return IRQ_HANDLED; return IRQ_HANDLED;
} }
EXPORT_SYMBOL_GPL(i2c_dw_isr);
void i2c_dw_disable(struct dw_i2c_dev *dev) void i2c_dw_disable(struct dw_i2c_dev *dev)
{ {
...@@ -838,5 +840,40 @@ u32 i2c_dw_read_comp_param(struct dw_i2c_dev *dev) ...@@ -838,5 +840,40 @@ u32 i2c_dw_read_comp_param(struct dw_i2c_dev *dev)
} }
EXPORT_SYMBOL_GPL(i2c_dw_read_comp_param); EXPORT_SYMBOL_GPL(i2c_dw_read_comp_param);
int i2c_dw_probe(struct dw_i2c_dev *dev)
{
struct i2c_adapter *adap = &dev->adapter;
int r;
init_completion(&dev->cmd_complete);
mutex_init(&dev->lock);
r = i2c_dw_init(dev);
if (r)
return r;
snprintf(adap->name, sizeof(adap->name),
"Synopsys DesignWare I2C adapter");
adap->algo = &i2c_dw_algo;
adap->dev.parent = dev->dev;
i2c_set_adapdata(adap, dev);
i2c_dw_disable_int(dev);
r = devm_request_irq(dev->dev, dev->irq, i2c_dw_isr, IRQF_SHARED,
dev_name(dev->dev), dev);
if (r) {
dev_err(dev->dev, "failure requesting irq %i: %d\n",
dev->irq, r);
return r;
}
r = i2c_add_numbered_adapter(adap);
if (r)
dev_err(dev->dev, "failure adding adapter: %d\n", r);
return r;
}
EXPORT_SYMBOL_GPL(i2c_dw_probe);
MODULE_DESCRIPTION("Synopsys DesignWare I2C bus adapter core"); MODULE_DESCRIPTION("Synopsys DesignWare I2C bus adapter core");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
...@@ -113,13 +113,10 @@ struct dw_i2c_dev { ...@@ -113,13 +113,10 @@ struct dw_i2c_dev {
#define ACCESS_16BIT 0x00000002 #define ACCESS_16BIT 0x00000002
extern int i2c_dw_init(struct dw_i2c_dev *dev); extern int i2c_dw_init(struct dw_i2c_dev *dev);
extern int i2c_dw_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[],
int num);
extern u32 i2c_dw_func(struct i2c_adapter *adap);
extern irqreturn_t i2c_dw_isr(int this_irq, void *dev_id);
extern void i2c_dw_disable(struct dw_i2c_dev *dev); extern void i2c_dw_disable(struct dw_i2c_dev *dev);
extern void i2c_dw_disable_int(struct dw_i2c_dev *dev); extern void i2c_dw_disable_int(struct dw_i2c_dev *dev);
extern u32 i2c_dw_read_comp_param(struct dw_i2c_dev *dev); extern u32 i2c_dw_read_comp_param(struct dw_i2c_dev *dev);
extern int i2c_dw_probe(struct dw_i2c_dev *dev);
#if IS_ENABLED(CONFIG_I2C_DESIGNWARE_BAYTRAIL) #if IS_ENABLED(CONFIG_I2C_DESIGNWARE_BAYTRAIL)
extern int i2c_dw_eval_lock_support(struct dw_i2c_dev *dev); extern int i2c_dw_eval_lock_support(struct dw_i2c_dev *dev);
......
...@@ -158,11 +158,6 @@ static struct dw_pci_controller dw_pci_controllers[] = { ...@@ -158,11 +158,6 @@ static struct dw_pci_controller dw_pci_controllers[] = {
}, },
}; };
static struct i2c_algorithm i2c_dw_algo = {
.master_xfer = i2c_dw_xfer,
.functionality = i2c_dw_func,
};
#ifdef CONFIG_PM #ifdef CONFIG_PM
static int i2c_dw_pci_suspend(struct device *dev) static int i2c_dw_pci_suspend(struct device *dev)
{ {
...@@ -222,13 +217,12 @@ static int i2c_dw_pci_probe(struct pci_dev *pdev, ...@@ -222,13 +217,12 @@ static int i2c_dw_pci_probe(struct pci_dev *pdev,
if (!dev) if (!dev)
return -ENOMEM; return -ENOMEM;
init_completion(&dev->cmd_complete);
mutex_init(&dev->lock);
dev->clk = NULL; dev->clk = NULL;
dev->controller = controller; dev->controller = controller;
dev->get_clk_rate_khz = i2c_dw_get_clk_rate_khz; dev->get_clk_rate_khz = i2c_dw_get_clk_rate_khz;
dev->base = pcim_iomap_table(pdev)[0]; dev->base = pcim_iomap_table(pdev)[0];
dev->dev = &pdev->dev; dev->dev = &pdev->dev;
dev->irq = pdev->irq;
dev->functionality = controller->functionality | dev->functionality = controller->functionality |
DW_DEFAULT_FUNCTIONALITY; DW_DEFAULT_FUNCTIONALITY;
...@@ -246,33 +240,15 @@ static int i2c_dw_pci_probe(struct pci_dev *pdev, ...@@ -246,33 +240,15 @@ static int i2c_dw_pci_probe(struct pci_dev *pdev,
dev->tx_fifo_depth = controller->tx_fifo_depth; dev->tx_fifo_depth = controller->tx_fifo_depth;
dev->rx_fifo_depth = controller->rx_fifo_depth; dev->rx_fifo_depth = controller->rx_fifo_depth;
r = i2c_dw_init(dev);
if (r)
return r;
adap = &dev->adapter; adap = &dev->adapter;
i2c_set_adapdata(adap, dev);
adap->owner = THIS_MODULE; adap->owner = THIS_MODULE;
adap->class = 0; adap->class = 0;
adap->algo = &i2c_dw_algo;
adap->dev.parent = &pdev->dev;
adap->nr = controller->bus_num; adap->nr = controller->bus_num;
snprintf(adap->name, sizeof(adap->name), "i2c-designware-pci"); r = i2c_dw_probe(dev);
if (r)
i2c_dw_disable_int(dev);
r = devm_request_irq(&pdev->dev, pdev->irq, i2c_dw_isr,
IRQF_SHARED | IRQF_COND_SUSPEND, adap->name, dev);
if (r) {
dev_err(&pdev->dev, "failure requesting irq %i\n", dev->irq);
return r;
}
r = i2c_add_numbered_adapter(adap);
if (r) {
dev_err(&pdev->dev, "failure adding adapter\n");
return r; return r;
}
pm_runtime_set_autosuspend_delay(&pdev->dev, 1000); pm_runtime_set_autosuspend_delay(&pdev->dev, 1000);
pm_runtime_use_autosuspend(&pdev->dev); pm_runtime_use_autosuspend(&pdev->dev);
......
...@@ -41,10 +41,6 @@ ...@@ -41,10 +41,6 @@
#include <linux/platform_data/i2c-designware.h> #include <linux/platform_data/i2c-designware.h>
#include "i2c-designware-core.h" #include "i2c-designware-core.h"
static struct i2c_algorithm i2c_dw_algo = {
.master_xfer = i2c_dw_xfer,
.functionality = i2c_dw_func,
};
static u32 i2c_dw_get_clk_rate_khz(struct dw_i2c_dev *dev) static u32 i2c_dw_get_clk_rate_khz(struct dw_i2c_dev *dev)
{ {
return clk_get_rate(dev->clk)/1000; return clk_get_rate(dev->clk)/1000;
...@@ -155,8 +151,6 @@ static int dw_i2c_plat_probe(struct platform_device *pdev) ...@@ -155,8 +151,6 @@ static int dw_i2c_plat_probe(struct platform_device *pdev)
if (IS_ERR(dev->base)) if (IS_ERR(dev->base))
return PTR_ERR(dev->base); return PTR_ERR(dev->base);
init_completion(&dev->cmd_complete);
mutex_init(&dev->lock);
dev->dev = &pdev->dev; dev->dev = &pdev->dev;
dev->irq = irq; dev->irq = irq;
platform_set_drvdata(pdev, dev); platform_set_drvdata(pdev, dev);
...@@ -231,33 +225,15 @@ static int dw_i2c_plat_probe(struct platform_device *pdev) ...@@ -231,33 +225,15 @@ static int dw_i2c_plat_probe(struct platform_device *pdev)
dev->rx_fifo_depth = ((param1 >> 8) & 0xff) + 1; dev->rx_fifo_depth = ((param1 >> 8) & 0xff) + 1;
dev->adapter.nr = pdev->id; dev->adapter.nr = pdev->id;
} }
r = i2c_dw_init(dev);
if (r)
return r;
i2c_dw_disable_int(dev);
r = devm_request_irq(&pdev->dev, dev->irq, i2c_dw_isr, IRQF_SHARED,
pdev->name, dev);
if (r) {
dev_err(&pdev->dev, "failure requesting irq %i\n", dev->irq);
return r;
}
adap = &dev->adapter; adap = &dev->adapter;
i2c_set_adapdata(adap, dev);
adap->owner = THIS_MODULE; adap->owner = THIS_MODULE;
adap->class = I2C_CLASS_DEPRECATED; adap->class = I2C_CLASS_DEPRECATED;
strlcpy(adap->name, "Synopsys DesignWare I2C adapter",
sizeof(adap->name));
adap->algo = &i2c_dw_algo;
adap->dev.parent = &pdev->dev;
adap->dev.of_node = pdev->dev.of_node; adap->dev.of_node = pdev->dev.of_node;
r = i2c_add_numbered_adapter(adap); r = i2c_dw_probe(dev);
if (r) { if (r)
dev_err(&pdev->dev, "failure adding adapter\n");
return r; return r;
}
if (dev->pm_runtime_disabled) { if (dev->pm_runtime_disabled) {
pm_runtime_forbid(&pdev->dev); pm_runtime_forbid(&pdev->dev);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment