Skip to content

Commit

Permalink
i2c: designware: Consolidate firmware parsing and configuring code
Browse files Browse the repository at this point in the history
We have the same code flows in the PCI and platform drivers. Moreover,
the flow requires the common code to export a few functions. Instead,
consolidate that flow under new function called
i2c_dw_fw_parse_and_configure() and drop unneeded exports.

Reviewed-by: Andi Shyti <andi.shyti@kernel.org>
Reviewed-by: Mario Limonciello <mario.limonciello@amd.com>
Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: Andi Shyti <andi.shyti@kernel.org>
  • Loading branch information
Andy Shevchenko authored and Andi Shyti committed Sep 9, 2024
1 parent 628c248 commit ebe508e
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 70 deletions.
68 changes: 62 additions & 6 deletions drivers/i2c/busses/i2c-designware-common.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/pm_runtime.h>
#include <linux/regmap.h>
#include <linux/swab.h>
Expand Down Expand Up @@ -188,7 +189,7 @@ static const u32 supported_speeds[] = {
I2C_MAX_STANDARD_MODE_FREQ,
};

int i2c_dw_validate_speed(struct dw_i2c_dev *dev)
static int i2c_dw_validate_speed(struct dw_i2c_dev *dev)
{
struct i2c_timings *t = &dev->timings;
unsigned int i;
Expand All @@ -208,7 +209,44 @@ int i2c_dw_validate_speed(struct dw_i2c_dev *dev)

return -EINVAL;
}
EXPORT_SYMBOL_GPL(i2c_dw_validate_speed);

#ifdef CONFIG_OF

#include <linux/platform_device.h>

#define MSCC_ICPU_CFG_TWI_DELAY 0x0
#define MSCC_ICPU_CFG_TWI_DELAY_ENABLE BIT(0)
#define MSCC_ICPU_CFG_TWI_SPIKE_FILTER 0x4

static int mscc_twi_set_sda_hold_time(struct dw_i2c_dev *dev)
{
writel((dev->sda_hold_time << 1) | MSCC_ICPU_CFG_TWI_DELAY_ENABLE,
dev->ext + MSCC_ICPU_CFG_TWI_DELAY);

return 0;
}

static void i2c_dw_of_configure(struct device *device)
{
struct platform_device *pdev = to_platform_device(device);
struct dw_i2c_dev *dev = dev_get_drvdata(device);

switch (dev->flags & MODEL_MASK) {
case MODEL_MSCC_OCELOT:
dev->ext = devm_platform_ioremap_resource(pdev, 1);
if (!IS_ERR(dev->ext))
dev->set_sda_hold_time = mscc_twi_set_sda_hold_time;
break;
default:
break;
}
}

#else /* CONFIG_OF */

static inline void i2c_dw_of_configure(struct device *device) { }

#endif /* CONFIG_OF */

#ifdef CONFIG_ACPI

Expand Down Expand Up @@ -255,7 +293,7 @@ static void i2c_dw_acpi_params(struct device *device, char method[],
kfree(buf.pointer);
}

void i2c_dw_acpi_configure(struct device *device)
static void i2c_dw_acpi_configure(struct device *device)
{
struct dw_i2c_dev *dev = dev_get_drvdata(device);
struct i2c_timings *t = &dev->timings;
Expand Down Expand Up @@ -286,7 +324,6 @@ void i2c_dw_acpi_configure(struct device *device)
break;
}
}
EXPORT_SYMBOL_GPL(i2c_dw_acpi_configure);

static u32 i2c_dw_acpi_round_bus_speed(struct device *device)
{
Expand All @@ -308,11 +345,13 @@ static u32 i2c_dw_acpi_round_bus_speed(struct device *device)

#else /* CONFIG_ACPI */

static inline void i2c_dw_acpi_configure(struct device *device) { }

static inline u32 i2c_dw_acpi_round_bus_speed(struct device *device) { return 0; }

#endif /* CONFIG_ACPI */

void i2c_dw_adjust_bus_speed(struct dw_i2c_dev *dev)
static void i2c_dw_adjust_bus_speed(struct dw_i2c_dev *dev)
{
u32 acpi_speed = i2c_dw_acpi_round_bus_speed(dev->dev);
struct i2c_timings *t = &dev->timings;
Expand All @@ -328,7 +367,24 @@ void i2c_dw_adjust_bus_speed(struct dw_i2c_dev *dev)
else
t->bus_freq_hz = I2C_MAX_FAST_MODE_FREQ;
}
EXPORT_SYMBOL_GPL(i2c_dw_adjust_bus_speed);

int i2c_dw_fw_parse_and_configure(struct dw_i2c_dev *dev)
{
struct i2c_timings *t = &dev->timings;
struct device *device = dev->dev;

i2c_parse_fw_timings(device, t, false);

i2c_dw_adjust_bus_speed(dev);

if (device->of_node)
i2c_dw_of_configure(device);
if (has_acpi_companion(device))
i2c_dw_acpi_configure(device);

return i2c_dw_validate_speed(dev);
}
EXPORT_SYMBOL_GPL(i2c_dw_fw_parse_and_configure);

static u32 i2c_dw_read_scl_reg(struct dw_i2c_dev *dev, u32 reg)
{
Expand Down
9 changes: 1 addition & 8 deletions drivers/i2c/busses/i2c-designware-core.h
Original file line number Diff line number Diff line change
Expand Up @@ -416,11 +416,4 @@ int i2c_dw_baytrail_probe_lock_support(struct dw_i2c_dev *dev);
int i2c_dw_amdpsp_probe_lock_support(struct dw_i2c_dev *dev);
#endif

int i2c_dw_validate_speed(struct dw_i2c_dev *dev);
void i2c_dw_adjust_bus_speed(struct dw_i2c_dev *dev);

#if IS_ENABLED(CONFIG_ACPI)
void i2c_dw_acpi_configure(struct device *device);
#else
static inline void i2c_dw_acpi_configure(struct device *device) { }
#endif
int i2c_dw_fw_parse_and_configure(struct dw_i2c_dev *dev);
11 changes: 1 addition & 10 deletions drivers/i2c/busses/i2c-designware-pcidrv.c
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,6 @@ static int i2c_dw_pci_probe(struct pci_dev *pdev,
int r;
struct dw_pci_controller *controller;
struct dw_scl_sda_cfg *cfg;
struct i2c_timings *t;

if (id->driver_data >= ARRAY_SIZE(dw_pci_controllers))
return dev_err_probe(&pdev->dev, -EINVAL,
Expand Down Expand Up @@ -288,9 +287,6 @@ static int i2c_dw_pci_probe(struct pci_dev *pdev,
dev->irq = pci_irq_vector(pdev, 0);
dev->flags |= controller->flags;

t = &dev->timings;
i2c_parse_fw_timings(&pdev->dev, t, false);

pci_set_drvdata(pdev, dev);

if (controller->setup) {
Expand All @@ -299,12 +295,7 @@ static int i2c_dw_pci_probe(struct pci_dev *pdev,
return r;
}

i2c_dw_adjust_bus_speed(dev);

if (has_acpi_companion(&pdev->dev))
i2c_dw_acpi_configure(&pdev->dev);

r = i2c_dw_validate_speed(dev);
r = i2c_dw_fw_parse_and_configure(dev);
if (r)
return r;

Expand Down
48 changes: 2 additions & 46 deletions drivers/i2c/busses/i2c-designware-platdrv.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
#include <linux/kernel.h>
#include <linux/mfd/syscon.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/pm.h>
#include <linux/pm_runtime.h>
Expand Down Expand Up @@ -97,43 +96,11 @@ static int bt1_i2c_request_regs(struct dw_i2c_dev *dev)
dev->map = devm_regmap_init(dev->dev, NULL, dev, &bt1_i2c_cfg);
return PTR_ERR_OR_ZERO(dev->map);
}

#define MSCC_ICPU_CFG_TWI_DELAY 0x0
#define MSCC_ICPU_CFG_TWI_DELAY_ENABLE BIT(0)
#define MSCC_ICPU_CFG_TWI_SPIKE_FILTER 0x4

static int mscc_twi_set_sda_hold_time(struct dw_i2c_dev *dev)
{
writel((dev->sda_hold_time << 1) | MSCC_ICPU_CFG_TWI_DELAY_ENABLE,
dev->ext + MSCC_ICPU_CFG_TWI_DELAY);

return 0;
}

static void i2c_dw_of_configure(struct device *device)
{
struct platform_device *pdev = to_platform_device(device);
struct dw_i2c_dev *dev = dev_get_drvdata(device);

switch (dev->flags & MODEL_MASK) {
case MODEL_MSCC_OCELOT:
dev->ext = devm_platform_ioremap_resource(pdev, 1);
if (!IS_ERR(dev->ext))
dev->set_sda_hold_time = mscc_twi_set_sda_hold_time;
break;
default:
break;
}
}
#else
static int bt1_i2c_request_regs(struct dw_i2c_dev *dev)
{
return -ENODEV;
}

static inline void i2c_dw_of_configure(struct device *device)
{
}
#endif

static int txgbe_i2c_request_regs(struct dw_i2c_dev *dev)
Expand Down Expand Up @@ -242,7 +209,6 @@ static int dw_i2c_plat_probe(struct platform_device *pdev)
{
struct i2c_adapter *adap;
struct dw_i2c_dev *dev;
struct i2c_timings *t;
int irq, ret;

irq = platform_get_irq(pdev, 0);
Expand Down Expand Up @@ -271,18 +237,7 @@ static int dw_i2c_plat_probe(struct platform_device *pdev)

reset_control_deassert(dev->rst);

t = &dev->timings;
i2c_parse_fw_timings(&pdev->dev, t, false);

i2c_dw_adjust_bus_speed(dev);

if (pdev->dev.of_node)
i2c_dw_of_configure(&pdev->dev);

if (has_acpi_companion(&pdev->dev))
i2c_dw_acpi_configure(&pdev->dev);

ret = i2c_dw_validate_speed(dev);
ret = i2c_dw_fw_parse_and_configure(dev);
if (ret)
goto exit_reset;

Expand Down Expand Up @@ -310,6 +265,7 @@ static int dw_i2c_plat_probe(struct platform_device *pdev)
goto exit_reset;

if (dev->clk) {
struct i2c_timings *t = &dev->timings;
u64 clk_khz;

dev->get_clk_rate_khz = i2c_dw_get_clk_rate_khz;
Expand Down

0 comments on commit ebe508e

Please sign in to comment.