summaryrefslogtreecommitdiff
path: root/drivers/i3c/master/dw-i3c-master.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2025-12-08 11:25:14 +0900
committerLinus Torvalds <torvalds@linux-foundation.org>2025-12-08 11:25:14 +0900
commitc2f2b01b74be8b40a2173372bcd770723f87e7b2 (patch)
treea838ec3198c9f7103595d0859495c9aba932577c /drivers/i3c/master/dw-i3c-master.c
parentba65a4e7120a616d9c592750d9147f6dcafedffa (diff)
parent79c3ae7ada0548d5097bdb65dde5d24a7d660fae (diff)
Merge tag 'i3c/for-6.19' of git://git.kernel.org/pub/scm/linux/kernel/git/i3c/linuxHEADmaster
Pull i3c updates from Alexandre Belloni: "HDR support has finally been added. mipi-i3c-hci has been reworked and Intel Nova Lake-S support has been added. Subsystem: - Add HDR transfer support Drivers: - dw: fix bus hang on Agilex5 - mipi-i3c-hci: Intel Nova Lake-S support, IOMMU support - svc: HDR support" * tag 'i3c/for-6.19' of git://git.kernel.org/pub/scm/linux/kernel/git/i3c/linux: (28 commits) regmap: i3c: switch to use i3c_xfer from i3c_priv_xfer net: mctp i3c: switch to use i3c_xfer from i3c_priv_xfer hwmon: (lm75): switch to use i3c_xfer from i3c_priv_xfer i3c: document i3c_xfers i3c: fix I3C_SDR bit number i3c: master: svc: Add basic HDR mode support i3c: master: svc: Replace bool rnw with union for HDR support i3c: Switch to use new i3c_xfer from i3c_priv_xfer i3c: Add HDR API support i3c: master: add WQ_PERCPU to alloc_workqueue users i3c: master: Remove i3c_device_free_ibi from i3c_device_remove i3c: mipi-i3c-hci-pci: Set d3cold_delay to 0 for Intel controllers i3c: mipi-i3c-hci-pci: Add LTR support for Intel controllers i3c: mipi-i3c-hci-pci: Add exit callback i3c: mipi-i3c-hci-pci: Change callback parameter i3c: mipi-i3c-hci-pci: Allocate a structure for mipi_i3c_hci_pci device information i3c: mipi-i3c-hci-pci: Factor out intel_reset() i3c: mipi-i3c-hci-pci: Factor out private registers ioremapping i3c: mipi-i3c-hci-pci: Constify driver data i3c: mipi-i3c-hci-pci: Use readl_poll_timeout() ...
Diffstat (limited to 'drivers/i3c/master/dw-i3c-master.c')
-rw-r--r--drivers/i3c/master/dw-i3c-master.c31
1 files changed, 30 insertions, 1 deletions
diff --git a/drivers/i3c/master/dw-i3c-master.c b/drivers/i3c/master/dw-i3c-master.c
index 9ceedf09c3b6..276592a8222e 100644
--- a/drivers/i3c/master/dw-i3c-master.c
+++ b/drivers/i3c/master/dw-i3c-master.c
@@ -228,6 +228,7 @@
/* List of quirks */
#define AMD_I3C_OD_PP_TIMING BIT(1)
+#define DW_I3C_DISABLE_RUNTIME_PM_QUIRK BIT(2)
struct dw_i3c_cmd {
u32 cmd_lo;
@@ -252,6 +253,10 @@ struct dw_i3c_i2c_dev_data {
struct i3c_generic_ibi_pool *ibi_pool;
};
+struct dw_i3c_drvdata {
+ u32 flags;
+};
+
static bool dw_i3c_master_supports_ccc_cmd(struct i3c_master_controller *m,
const struct i3c_ccc_cmd *cmd)
{
@@ -1535,6 +1540,8 @@ int dw_i3c_common_probe(struct dw_i3c_master *master,
struct platform_device *pdev)
{
int ret, irq;
+ const struct dw_i3c_drvdata *drvdata;
+ unsigned long quirks = 0;
if (!master->platform_ops)
master->platform_ops = &dw_i3c_platform_ops_default;
@@ -1590,7 +1597,18 @@ int dw_i3c_common_probe(struct dw_i3c_master *master,
master->maxdevs = ret >> 16;
master->free_pos = GENMASK(master->maxdevs - 1, 0);
- master->quirks = (unsigned long)device_get_match_data(&pdev->dev);
+ if (has_acpi_companion(&pdev->dev)) {
+ quirks = (unsigned long)device_get_match_data(&pdev->dev);
+ } else if (pdev->dev.of_node) {
+ drvdata = device_get_match_data(&pdev->dev);
+ if (drvdata)
+ quirks = drvdata->flags;
+ }
+ master->quirks = quirks;
+
+ /* Keep controller enabled by preventing runtime suspend */
+ if (master->quirks & DW_I3C_DISABLE_RUNTIME_PM_QUIRK)
+ pm_runtime_get_noresume(&pdev->dev);
INIT_WORK(&master->hj_work, dw_i3c_hj_work);
ret = i3c_master_register(&master->base, &pdev->dev,
@@ -1617,6 +1635,10 @@ void dw_i3c_common_remove(struct dw_i3c_master *master)
cancel_work_sync(&master->hj_work);
i3c_master_unregister(&master->base);
+ /* Balance pm_runtime_get_noresume() from probe() */
+ if (master->quirks & DW_I3C_DISABLE_RUNTIME_PM_QUIRK)
+ pm_runtime_put_noidle(master->dev);
+
pm_runtime_disable(master->dev);
pm_runtime_set_suspended(master->dev);
pm_runtime_dont_use_autosuspend(master->dev);
@@ -1759,8 +1781,15 @@ static void dw_i3c_shutdown(struct platform_device *pdev)
pm_runtime_put_autosuspend(master->dev);
}
+static const struct dw_i3c_drvdata altr_agilex5_drvdata = {
+ .flags = DW_I3C_DISABLE_RUNTIME_PM_QUIRK,
+};
+
static const struct of_device_id dw_i3c_master_of_match[] = {
{ .compatible = "snps,dw-i3c-master-1.00a", },
+ { .compatible = "altr,agilex5-dw-i3c-master",
+ .data = &altr_agilex5_drvdata,
+ },
{},
};
MODULE_DEVICE_TABLE(of, dw_i3c_master_of_match);