* [PATCH] mfd: intel_quark_i2c_gpio: manage the fixed-rate clock
@ 2026-09-12 19:12 Myeonghun Pak
2026-09-12 19:21 ` sashiko-bot
0 siblings, 1 reply; 2+ messages in thread
From: Myeonghun Pak @ 2026-09-12 19:12 UTC (permalink / raw)
To: Lee Jones; +Cc: mfd, linux-kernel, Ijae Kim
The I2C clock is allocated by clk_register_fixed_rate(), but cleanup uses
clk_unregister(), leaving the fixed-rate provider allocation behind.
Manage the provider with devm_clk_hw_register_fixed_rate() and its lookup
with devm_clk_hw_register_clkdev(). Managed resources release the lookup
before the provider, after the MFD children have been removed.
Remove the manual clock cleanup and the private structure that only
stored the clock and lookup pointers.
This issue was identified during our ongoing static-analysis research while
reviewing kernel code.
Fixes: 60ae5b9f5cdd ("mfd: intel_quark_i2c_gpio: Add Intel Quark X1000 I2C-GPIO MFD Driver")
Assisted-by: OpenAI:GPT-5.6
Co-developed-by: Ijae Kim <ae878000@gmail.com>
Signed-off-by: Ijae Kim <ae878000@gmail.com>
Signed-off-by: Myeonghun Pak <mhun512@gmail.com>
---
drivers/mfd/intel_quark_i2c_gpio.c | 52 +++++---------------------------------
1 file changed, 6 insertions(+), 46 deletions(-)
diff --git a/drivers/mfd/intel_quark_i2c_gpio.c b/drivers/mfd/intel_quark_i2c_gpio.c
index 9b9c76bd067b8198553013af70c9123e33fb9041..443a1a0cf7778d400b40e0c75439e3c7235f8ec5 100644
--- a/drivers/mfd/intel_quark_i2c_gpio.c
+++ b/drivers/mfd/intel_quark_i2c_gpio.c
@@ -35,11 +35,6 @@
/* The Quark I2C controller source clock */
#define INTEL_QUARK_I2C_CLK_HZ 33000000
-struct intel_quark_mfd {
- struct clk *i2c_clk;
- struct clk_lookup *i2c_clk_lookup;
-};
-
static const struct property_entry intel_quark_i2c_controller_standard_properties[] = {
PROPERTY_ENTRY_U32("clock-frequency", I2C_MAX_STANDARD_MODE_FREQ),
{ }
@@ -160,37 +155,12 @@ MODULE_DEVICE_TABLE(pci, intel_quark_mfd_ids);
static int intel_quark_register_i2c_clk(struct device *dev)
{
- struct intel_quark_mfd *quark_mfd = dev_get_drvdata(dev);
- struct clk *i2c_clk;
-
- i2c_clk = clk_register_fixed_rate(dev,
- INTEL_QUARK_I2C_CONTROLLER_CLK, NULL,
- 0, INTEL_QUARK_I2C_CLK_HZ);
- if (IS_ERR(i2c_clk))
- return PTR_ERR(i2c_clk);
-
- quark_mfd->i2c_clk = i2c_clk;
- quark_mfd->i2c_clk_lookup = clkdev_create(i2c_clk, NULL,
- INTEL_QUARK_I2C_CONTROLLER_CLK);
-
- if (!quark_mfd->i2c_clk_lookup) {
- clk_unregister(quark_mfd->i2c_clk);
- dev_err(dev, "Fixed clk register failed\n");
- return -ENOMEM;
- }
-
- return 0;
-}
-
-static void intel_quark_unregister_i2c_clk(struct device *dev)
-{
- struct intel_quark_mfd *quark_mfd = dev_get_drvdata(dev);
-
- if (!quark_mfd->i2c_clk_lookup)
- return;
+ struct clk_hw *hw;
- clkdev_drop(quark_mfd->i2c_clk_lookup);
- clk_unregister(quark_mfd->i2c_clk);
+ hw = devm_clk_hw_register_fixed_rate(dev, INTEL_QUARK_I2C_CONTROLLER_CLK,
+ NULL, 0, INTEL_QUARK_I2C_CLK_HZ);
+ return devm_clk_hw_register_clkdev(dev, hw, NULL,
+ INTEL_QUARK_I2C_CONTROLLER_CLK);
}
static int intel_quark_i2c_setup(struct pci_dev *pdev)
@@ -238,19 +208,12 @@ static int intel_quark_gpio_setup(struct pci_dev *pdev)
static int intel_quark_mfd_probe(struct pci_dev *pdev,
const struct pci_device_id *id)
{
- struct intel_quark_mfd *quark_mfd;
int ret;
ret = pcim_enable_device(pdev);
if (ret)
return ret;
- quark_mfd = devm_kzalloc(&pdev->dev, sizeof(*quark_mfd), GFP_KERNEL);
- if (!quark_mfd)
- return -ENOMEM;
-
- dev_set_drvdata(&pdev->dev, quark_mfd);
-
ret = intel_quark_register_i2c_clk(&pdev->dev);
if (ret)
return ret;
@@ -260,7 +223,7 @@ static int intel_quark_mfd_probe(struct pci_dev *pdev,
/* This driver only requires 1 IRQ vector */
ret = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_ALL_TYPES);
if (ret < 0)
- goto err_unregister_i2c_clk;
+ return ret;
ret = intel_quark_i2c_setup(pdev);
if (ret)
@@ -282,8 +245,6 @@ static int intel_quark_mfd_probe(struct pci_dev *pdev,
software_node_unregister_node_group(intel_quark_gpio_node_group);
err_free_irq_vectors:
pci_free_irq_vectors(pdev);
-err_unregister_i2c_clk:
- intel_quark_unregister_i2c_clk(&pdev->dev);
return ret;
}
@@ -292,7 +253,6 @@ static void intel_quark_mfd_remove(struct pci_dev *pdev)
mfd_remove_devices(&pdev->dev);
software_node_unregister_node_group(intel_quark_gpio_node_group);
pci_free_irq_vectors(pdev);
- intel_quark_unregister_i2c_clk(&pdev->dev);
}
static struct pci_driver intel_quark_mfd_driver = {
--
2.53.0
^ permalink raw reply related [flat|nested] 2+ messages in thread
* Re: [PATCH] mfd: intel_quark_i2c_gpio: manage the fixed-rate clock
2026-09-12 19:12 [PATCH] mfd: intel_quark_i2c_gpio: manage the fixed-rate clock Myeonghun Pak
@ 2026-09-12 19:21 ` sashiko-bot
0 siblings, 0 replies; 2+ messages in thread
From: sashiko-bot @ 2026-09-12 19:21 UTC (permalink / raw)
To: Myeonghun Pak; +Cc: mfd, lee
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
New issues:
- [Low] Commit Message Guideline Violation
Pre-existing issues:
- [High] Data Race / Global State Mutation in PCI probe path
--
commit 963e47fef2beb8ea997a39b28407399109b523e7
Author: Myeonghun Pak <mhun512@gmail.com>
mfd: intel_quark_i2c_gpio: manage the fixed-rate clock
This commit transitions the I2C clock provider to use managed resource
functions like devm_clk_hw_register_fixed_rate. It removes the manual clock
cleanup functions and the private data structure previously used for tracking.
> mfd: intel_quark_i2c_gpio: manage the fixed-rate clock
[Severity: Low]
This isn't a bug introduced by this patch, but the MFD subsystem guidelines
mandate that the description after the subsystem prefix must be capitalized.
Should the title be "mfd: intel_quark_i2c_gpio: Manage the fixed-rate clock"
to align with subsystem formatting rules?
> diff --git a/drivers/mfd/intel_quark_i2c_gpio.c b/drivers/mfd/intel_quark_i2c_gpio.c
> index 9b9c76bd067b8..443a1a0cf7778 100644
> --- a/drivers/mfd/intel_quark_i2c_gpio.c
> +++ b/drivers/mfd/intel_quark_i2c_gpio.c
[ ... ]
> @@ -260,7 +223,7 @@ static int intel_quark_mfd_probe(struct pci_dev *pdev,
> /* This driver only requires 1 IRQ vector */
> ret = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_ALL_TYPES);
> if (ret < 0)
> - goto err_unregister_i2c_clk;
> + return ret;
>
> ret = intel_quark_i2c_setup(pdev);
[Severity: High]
This is a pre-existing issue, but intel_quark_i2c_setup() mutates global
arrays during the PCI device probe.
If multiple instances of this PCI device are probed concurrently, will their
probe functions simultaneously overwrite the global static intel_quark_i2c_res
and intel_quark_mfd_cells arrays?
drivers/mfd/intel_quark_i2c_gpio.c:intel_quark_i2c_setup() {
...
res[INTEL_QUARK_IORES_MEM].start = pci_resource_start(pdev, MFD_I2C_BAR);
...
cell->swnode = &intel_quark_i2c_controller_standard_node;
...
}
Does this data race lead to data corruption of PCI resource mappings and cell
configurations, causing incorrect hardware memory addresses to be used if the
driver binds to multiple devices?
> if (ret)
> goto err_free_irq_vectors;
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260912191223.46136-1-mhun512@gmail.com?part=1
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2026-09-12 19:21 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-12 19:12 [PATCH] mfd: intel_quark_i2c_gpio: manage the fixed-rate clock Myeonghun Pak
2026-09-12 19:21 ` sashiko-bot
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).