Skip to content

Commit c2f2b01

Browse files
committed
Merge tag 'i3c/for-6.19' of git://git.kernel.org/pub/scm/linux/kernel/git/i3c/linux
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() ...
2 parents ba65a4e + 79c3ae7 commit c2f2b01

12 files changed

Lines changed: 424 additions & 113 deletions

File tree

Documentation/devicetree/bindings/i3c/snps,dw-i3c-master.yaml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,11 @@ allOf:
1414

1515
properties:
1616
compatible:
17-
const: snps,dw-i3c-master-1.00a
17+
oneOf:
18+
- const: snps,dw-i3c-master-1.00a
19+
- items:
20+
- const: altr,agilex5-dw-i3c-master
21+
- const: snps,dw-i3c-master-1.00a
1822

1923
reg:
2024
maxItems: 1

drivers/base/regmap/regmap-i3c.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,15 @@ static int regmap_i3c_write(void *context, const void *data, size_t count)
1111
{
1212
struct device *dev = context;
1313
struct i3c_device *i3c = dev_to_i3cdev(dev);
14-
struct i3c_priv_xfer xfers[] = {
14+
struct i3c_xfer xfers[] = {
1515
{
1616
.rnw = false,
1717
.len = count,
1818
.data.out = data,
1919
},
2020
};
2121

22-
return i3c_device_do_priv_xfers(i3c, xfers, ARRAY_SIZE(xfers));
22+
return i3c_device_do_xfers(i3c, xfers, ARRAY_SIZE(xfers), I3C_SDR);
2323
}
2424

2525
static int regmap_i3c_read(void *context,
@@ -28,7 +28,7 @@ static int regmap_i3c_read(void *context,
2828
{
2929
struct device *dev = context;
3030
struct i3c_device *i3c = dev_to_i3cdev(dev);
31-
struct i3c_priv_xfer xfers[2];
31+
struct i3c_xfer xfers[2];
3232

3333
xfers[0].rnw = false;
3434
xfers[0].len = reg_size;
@@ -38,7 +38,7 @@ static int regmap_i3c_read(void *context,
3838
xfers[1].len = val_size;
3939
xfers[1].data.in = val;
4040

41-
return i3c_device_do_priv_xfers(i3c, xfers, ARRAY_SIZE(xfers));
41+
return i3c_device_do_xfers(i3c, xfers, ARRAY_SIZE(xfers), I3C_SDR);
4242
}
4343

4444
static const struct regmap_bus regmap_i3c = {

drivers/hwmon/lm75.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -621,7 +621,7 @@ static int lm75_i3c_reg_read(void *context, unsigned int reg, unsigned int *val)
621621
{
622622
struct i3c_device *i3cdev = context;
623623
struct lm75_data *data = i3cdev_get_drvdata(i3cdev);
624-
struct i3c_priv_xfer xfers[] = {
624+
struct i3c_xfer xfers[] = {
625625
{
626626
.rnw = false,
627627
.len = 1,
@@ -640,7 +640,7 @@ static int lm75_i3c_reg_read(void *context, unsigned int reg, unsigned int *val)
640640
if (reg == LM75_REG_CONF && !data->params->config_reg_16bits)
641641
xfers[1].len--;
642642

643-
ret = i3c_device_do_priv_xfers(i3cdev, xfers, 2);
643+
ret = i3c_device_do_xfers(i3cdev, xfers, 2, I3C_SDR);
644644
if (ret < 0)
645645
return ret;
646646

@@ -658,7 +658,7 @@ static int lm75_i3c_reg_write(void *context, unsigned int reg, unsigned int val)
658658
{
659659
struct i3c_device *i3cdev = context;
660660
struct lm75_data *data = i3cdev_get_drvdata(i3cdev);
661-
struct i3c_priv_xfer xfers[] = {
661+
struct i3c_xfer xfers[] = {
662662
{
663663
.rnw = false,
664664
.len = 3,
@@ -680,7 +680,7 @@ static int lm75_i3c_reg_write(void *context, unsigned int reg, unsigned int val)
680680
data->val_buf[2] = val & 0xff;
681681
}
682682

683-
return i3c_device_do_priv_xfers(i3cdev, xfers, 1);
683+
return i3c_device_do_xfers(i3cdev, xfers, 1, I3C_SDR);
684684
}
685685

686686
static const struct regmap_bus lm75_i3c_regmap_bus = {

drivers/i3c/device.c

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,12 @@
1515
#include "internals.h"
1616

1717
/**
18-
* i3c_device_do_priv_xfers() - do I3C SDR private transfers directed to a
19-
* specific device
18+
* i3c_device_do_xfers() - do I3C transfers directed to a specific device
2019
*
2120
* @dev: device with which the transfers should be done
2221
* @xfers: array of transfers
2322
* @nxfers: number of transfers
23+
* @mode: transfer mode
2424
*
2525
* Initiate one or several private SDR transfers with @dev.
2626
*
@@ -33,9 +33,8 @@
3333
* 'xfers' some time later. See I3C spec ver 1.1.1 09-Jun-2021. Section:
3434
* 5.1.2.2.3.
3535
*/
36-
int i3c_device_do_priv_xfers(struct i3c_device *dev,
37-
struct i3c_priv_xfer *xfers,
38-
int nxfers)
36+
int i3c_device_do_xfers(struct i3c_device *dev, struct i3c_xfer *xfers,
37+
int nxfers, enum i3c_xfer_mode mode)
3938
{
4039
int ret, i;
4140

@@ -48,12 +47,12 @@ int i3c_device_do_priv_xfers(struct i3c_device *dev,
4847
}
4948

5049
i3c_bus_normaluse_lock(dev->bus);
51-
ret = i3c_dev_do_priv_xfers_locked(dev->desc, xfers, nxfers);
50+
ret = i3c_dev_do_xfers_locked(dev->desc, xfers, nxfers, mode);
5251
i3c_bus_normaluse_unlock(dev->bus);
5352

5453
return ret;
5554
}
56-
EXPORT_SYMBOL_GPL(i3c_device_do_priv_xfers);
55+
EXPORT_SYMBOL_GPL(i3c_device_do_xfers);
5756

5857
/**
5958
* i3c_device_do_setdasa() - do I3C dynamic address assignement with
@@ -260,6 +259,20 @@ i3c_device_match_id(struct i3c_device *i3cdev,
260259
}
261260
EXPORT_SYMBOL_GPL(i3c_device_match_id);
262261

262+
/**
263+
* i3c_device_get_supported_xfer_mode - Returns the supported transfer mode by
264+
* connected master controller.
265+
* @dev: I3C device
266+
*
267+
* Return: a bit mask, which supported transfer mode, bit position is defined at
268+
* enum i3c_hdr_mode
269+
*/
270+
u32 i3c_device_get_supported_xfer_mode(struct i3c_device *dev)
271+
{
272+
return i3c_dev_get_master(dev->desc)->this->info.hdr_cap | BIT(I3C_SDR);
273+
}
274+
EXPORT_SYMBOL_GPL(i3c_device_get_supported_xfer_mode);
275+
263276
/**
264277
* i3c_driver_register_with_owner() - register an I3C device driver
265278
*

drivers/i3c/internals.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,9 @@ void i3c_bus_normaluse_lock(struct i3c_bus *bus);
1515
void i3c_bus_normaluse_unlock(struct i3c_bus *bus);
1616

1717
int i3c_dev_setdasa_locked(struct i3c_dev_desc *dev);
18-
int i3c_dev_do_priv_xfers_locked(struct i3c_dev_desc *dev,
19-
struct i3c_priv_xfer *xfers,
20-
int nxfers);
18+
int i3c_dev_do_xfers_locked(struct i3c_dev_desc *dev,
19+
struct i3c_xfer *xfers,
20+
int nxfers, enum i3c_xfer_mode mode);
2121
int i3c_dev_disable_ibi_locked(struct i3c_dev_desc *dev);
2222
int i3c_dev_enable_ibi_locked(struct i3c_dev_desc *dev);
2323
int i3c_dev_request_ibi_locked(struct i3c_dev_desc *dev,

drivers/i3c/master.c

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -334,8 +334,6 @@ static void i3c_device_remove(struct device *dev)
334334

335335
if (driver->remove)
336336
driver->remove(i3cdev);
337-
338-
i3c_device_free_ibi(i3cdev);
339337
}
340338

341339
const struct bus_type i3c_bus_type = {
@@ -2821,10 +2819,14 @@ EXPORT_SYMBOL_GPL(i3c_generic_ibi_recycle_slot);
28212819

28222820
static int i3c_master_check_ops(const struct i3c_master_controller_ops *ops)
28232821
{
2824-
if (!ops || !ops->bus_init || !ops->priv_xfers ||
2822+
if (!ops || !ops->bus_init ||
28252823
!ops->send_ccc_cmd || !ops->do_daa || !ops->i2c_xfers)
28262824
return -EINVAL;
28272825

2826+
/* Must provide one of priv_xfers (SDR only) or i3c_xfers (all modes) */
2827+
if (!ops->priv_xfers && !ops->i3c_xfers)
2828+
return -EINVAL;
2829+
28282830
if (ops->request_ibi &&
28292831
(!ops->enable_ibi || !ops->disable_ibi || !ops->free_ibi ||
28302832
!ops->recycle_ibi_slot))
@@ -2883,17 +2885,17 @@ int i3c_master_register(struct i3c_master_controller *master,
28832885
INIT_LIST_HEAD(&master->boardinfo.i2c);
28842886
INIT_LIST_HEAD(&master->boardinfo.i3c);
28852887

2886-
ret = i3c_bus_init(i3cbus, master->dev.of_node);
2887-
if (ret)
2888-
return ret;
2889-
28902888
device_initialize(&master->dev);
28912889
dev_set_name(&master->dev, "i3c-%d", i3cbus->id);
28922890

28932891
master->dev.dma_mask = parent->dma_mask;
28942892
master->dev.coherent_dma_mask = parent->coherent_dma_mask;
28952893
master->dev.dma_parms = parent->dma_parms;
28962894

2895+
ret = i3c_bus_init(i3cbus, master->dev.of_node);
2896+
if (ret)
2897+
goto err_put_dev;
2898+
28972899
ret = of_populate_i3c_bus(master);
28982900
if (ret)
28992901
goto err_put_dev;
@@ -2925,7 +2927,7 @@ int i3c_master_register(struct i3c_master_controller *master,
29252927
if (ret)
29262928
goto err_put_dev;
29272929

2928-
master->wq = alloc_workqueue("%s", 0, 0, dev_name(parent));
2930+
master->wq = alloc_workqueue("%s", WQ_PERCPU, 0, dev_name(parent));
29292931
if (!master->wq) {
29302932
ret = -ENOMEM;
29312933
goto err_put_dev;
@@ -3014,9 +3016,8 @@ int i3c_dev_setdasa_locked(struct i3c_dev_desc *dev)
30143016
dev->boardinfo->init_dyn_addr);
30153017
}
30163018

3017-
int i3c_dev_do_priv_xfers_locked(struct i3c_dev_desc *dev,
3018-
struct i3c_priv_xfer *xfers,
3019-
int nxfers)
3019+
int i3c_dev_do_xfers_locked(struct i3c_dev_desc *dev, struct i3c_xfer *xfers,
3020+
int nxfers, enum i3c_xfer_mode mode)
30203021
{
30213022
struct i3c_master_controller *master;
30223023

@@ -3027,9 +3028,15 @@ int i3c_dev_do_priv_xfers_locked(struct i3c_dev_desc *dev,
30273028
if (!master || !xfers)
30283029
return -EINVAL;
30293030

3030-
if (!master->ops->priv_xfers)
3031+
if (mode != I3C_SDR && !(master->this->info.hdr_cap & BIT(mode)))
30313032
return -EOPNOTSUPP;
30323033

3034+
if (master->ops->i3c_xfers)
3035+
return master->ops->i3c_xfers(dev, xfers, nxfers, mode);
3036+
3037+
if (mode != I3C_SDR)
3038+
return -EINVAL;
3039+
30333040
return master->ops->priv_xfers(dev, xfers, nxfers);
30343041
}
30353042

drivers/i3c/master/dw-i3c-master.c

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,7 @@
228228

229229
/* List of quirks */
230230
#define AMD_I3C_OD_PP_TIMING BIT(1)
231+
#define DW_I3C_DISABLE_RUNTIME_PM_QUIRK BIT(2)
231232

232233
struct dw_i3c_cmd {
233234
u32 cmd_lo;
@@ -252,6 +253,10 @@ struct dw_i3c_i2c_dev_data {
252253
struct i3c_generic_ibi_pool *ibi_pool;
253254
};
254255

256+
struct dw_i3c_drvdata {
257+
u32 flags;
258+
};
259+
255260
static bool dw_i3c_master_supports_ccc_cmd(struct i3c_master_controller *m,
256261
const struct i3c_ccc_cmd *cmd)
257262
{
@@ -1535,6 +1540,8 @@ int dw_i3c_common_probe(struct dw_i3c_master *master,
15351540
struct platform_device *pdev)
15361541
{
15371542
int ret, irq;
1543+
const struct dw_i3c_drvdata *drvdata;
1544+
unsigned long quirks = 0;
15381545

15391546
if (!master->platform_ops)
15401547
master->platform_ops = &dw_i3c_platform_ops_default;
@@ -1590,7 +1597,18 @@ int dw_i3c_common_probe(struct dw_i3c_master *master,
15901597
master->maxdevs = ret >> 16;
15911598
master->free_pos = GENMASK(master->maxdevs - 1, 0);
15921599

1593-
master->quirks = (unsigned long)device_get_match_data(&pdev->dev);
1600+
if (has_acpi_companion(&pdev->dev)) {
1601+
quirks = (unsigned long)device_get_match_data(&pdev->dev);
1602+
} else if (pdev->dev.of_node) {
1603+
drvdata = device_get_match_data(&pdev->dev);
1604+
if (drvdata)
1605+
quirks = drvdata->flags;
1606+
}
1607+
master->quirks = quirks;
1608+
1609+
/* Keep controller enabled by preventing runtime suspend */
1610+
if (master->quirks & DW_I3C_DISABLE_RUNTIME_PM_QUIRK)
1611+
pm_runtime_get_noresume(&pdev->dev);
15941612

15951613
INIT_WORK(&master->hj_work, dw_i3c_hj_work);
15961614
ret = i3c_master_register(&master->base, &pdev->dev,
@@ -1617,6 +1635,10 @@ void dw_i3c_common_remove(struct dw_i3c_master *master)
16171635
cancel_work_sync(&master->hj_work);
16181636
i3c_master_unregister(&master->base);
16191637

1638+
/* Balance pm_runtime_get_noresume() from probe() */
1639+
if (master->quirks & DW_I3C_DISABLE_RUNTIME_PM_QUIRK)
1640+
pm_runtime_put_noidle(master->dev);
1641+
16201642
pm_runtime_disable(master->dev);
16211643
pm_runtime_set_suspended(master->dev);
16221644
pm_runtime_dont_use_autosuspend(master->dev);
@@ -1759,8 +1781,15 @@ static void dw_i3c_shutdown(struct platform_device *pdev)
17591781
pm_runtime_put_autosuspend(master->dev);
17601782
}
17611783

1784+
static const struct dw_i3c_drvdata altr_agilex5_drvdata = {
1785+
.flags = DW_I3C_DISABLE_RUNTIME_PM_QUIRK,
1786+
};
1787+
17621788
static const struct of_device_id dw_i3c_master_of_match[] = {
17631789
{ .compatible = "snps,dw-i3c-master-1.00a", },
1790+
{ .compatible = "altr,agilex5-dw-i3c-master",
1791+
.data = &altr_agilex5_drvdata,
1792+
},
17641793
{},
17651794
};
17661795
MODULE_DEVICE_TABLE(of, dw_i3c_master_of_match);

0 commit comments

Comments
 (0)