i3c: Add support for ast2600 i3c controller
Subsystems (5)
Jeremy Kerr
maintainercover i3c: Add support for ast2600 i3c controller
The AST2600 SoC hardware includes a set of i3c controllers, based on the designware i3c core, plus some global registers for SoC integration.
This series adds support for these i3c controllers, through the existing dw i3c master controller driver, by adding a set of platform-specific hooks to handle the global register configuration. This also gives us a way to add any future hardware-specific behaviours.
We also need a DT binding to describe the ast2600-specific hardware. Since this involves new (mandatory) properties, I have added this as a separate binding rather than add a new compat string to the dw binding.
The dt-binding example depends on a prior submission to the dt binding headers:
https://lore.kernel.org/linux-devicetree/cover.1676294433.git.jk at codeconstruct.com.au/
Full support for the global regmap will land with this queued mfd change:
Of course, any queries/comments/etc are most welcome.
Cheers,
Jeremy
Jeremy Kerr (4):
dt-bindings: i3c: Add AST2600 i3c controller
i3c: dw: Add platform operations
i3c: dw: Add AST2600 platform ops
i3c: dw: Add compatible string for ASPEED AST2600 BMC platform
.../bindings/i3c/aspeed,ast2600-i3c.yaml | 73 ++++++++ drivers/i3c/master/dw-i3c-master.c | 165 +++++++++++++++++- 2 files changed, 232 insertions(+), 6 deletions(-) create mode 100644 Documentation/devicetree/bindings/i3c/aspeed,ast2600-i3c.yaml
Signature · 1 line
2.39.1
Jeremy Kerr
maintainerPATCH 1/4 dt-bindings: i3c: Add AST2600 i3c controller
Add a devicetree binding for the ast2600 i3c controller hardware. This is heavily based on the designware i3c core, plus a reset facility and two platform-specific properties:
- sda-pullup-ohms: to specify the value of the configurable pullup resistors on the SDA line
- aspeed,global-regs: to reference the (ast2600-specific) i3c global register block, and the device index to use within it.
---
changes from RFC:
- add vendor prefix to global-regs properties
- add item description on global-regs property
- drop global reg node from example
--- .../bindings/i3c/aspeed,ast2600-i3c.yaml | 73 +++++++++++++++++++ 1 file changed, 73 insertions(+) create mode 100644 Documentation/devicetree/bindings/i3c/aspeed,ast2600-i3c.yaml
Documentation/devicetree/bindings/i3c/aspeed,ast2600-i3c.yaml new file +73 -0
@@ -0,0 +1,73 @@ +# SPDX-License-Identifier: GPL-2.0 +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/i3c/aspeed,ast2600-i3c.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: ASPEED AST2600 i3c controller + +maintainers: + - Jeremy Kerr <[email protected]> + +allOf: + - $ref: i3c.yaml# + +properties: + compatible: + const: aspeed,ast2600-i3c + + reg: + maxItems: 1 + + clocks: + maxItems: 1 + + resets: + maxItems: 1 + + interrupts: + maxItems: 1 + + sda-pullup-ohms: + enum: [545, 750, 2000] + default: 2000 + description: | + Value to configure SDA pullup resistor, in Ohms. + + aspeed,global-regs: + $ref: /schemas/types.yaml#/definitions/phandle-array + items: + - items: + - description: phandle to i3c global register syscon node + - description: index of this i3c controller in the global register set + description: | + A (phandle, controller index) reference to the i3c global register set + used for this device. + +required: + - compatible + - reg + - clocks + - interrupts + - aspeed,global-regs + +unevaluatedProperties: false + +examples: + - | + #include <dt-bindings/clock/ast2600-clock.h> + #include <dt-bindings/interrupt-controller/arm-gic.h> + + i3c-master at 2000 { + compatible = "aspeed,ast2600-i3c"; + reg = <0x2000 0x1000>; + #address-cells = <3>; + #size-cells = <0>; + clocks = <&syscon ASPEED_CLK_GATE_I3C0CLK>; + resets = <&syscon ASPEED_RESET_I3C0>; + aspeed,global-regs = <&i3c_global 0>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i3c1_default>; + interrupts = <GIC_SPI 102 IRQ_TYPE_LEVEL_HIGH>; + }; +...
Signature · 1 line
2.39.1
Jeremy Kerr
maintainerPATCH 2/4 i3c: dw: Add platform operations
In reply to Jeremy KerrThe dw i3c core can be integrated into various SoC devices. Platforms that use this core may need a little configuration that is specific to that platform.
Add a little infrastructure to allow platform-specific behaviour: a bit of data on struct dw_i3c_master, and two hooks to the probe and init calls to enable this.
A future change will add new platform support that uses these hooks.
--- drivers/i3c/master/dw-i3c-master.c | 42 +++++++++++++++++++++++++----- 1 file changed, 36 insertions(+), 6 deletions(-)
drivers/i3c/master/dw-i3c-master.c +36 -6
@@ -241,6 +241,17 @@ struct dw_i3c_master {char version[5 ];char type[5 ];u8 addrs[MAX_DEVS ]; + +/* platform-specific data */ +const struct dw_i3c_platform_ops *platform_ops; +union { + } pdata; + +}; + +struct dw_i3c_platform_ops { +int (*probe)(struct dw_i3c_master *i3c,struct platform_device *pdev); +int (*init)(struct dw_i3c_master *i3c); };struct dw_i3c_i2c_dev_data {
@@ -612,6 +623,12 @@ static int dw_i3c_master_bus_init(struct i3c_master_controller *m)u32 thld_ctrl;int ret; +if (master->platform_ops && master->platform_ops->init) { + ret = master->platform_ops->init (master); +if (ret) +return ret; + } +switch (bus->mode) {case I3C_BUS_MODE_MIXED_FAST :case I3C_BUS_MODE_MIXED_LIMITED :
@@ -1128,8 +1145,15 @@ static const struct i3c_master_controller_ops dw_mipi_i3c_ops = { .i2c_xfers = dw_i3c_master_i2c_xfers, }; +static const struct of_device_id dw_i3c_master_of_match[] = { + { .compatible ="snps,dw-i3c-master-1.00a" , }, + {}, +}; +MODULE_DEVICE_TABLE (of, dw_i3c_master_of_match); +static int dw_i3c_probe (struct platform_device *pdev) { +const struct of_device_id *match;struct dw_i3c_master *master;int ret, irq;
@@ -1181,6 +1205,18 @@ static int dw_i3c_probe(struct platform_device *pdev) master->maxdevs = ret >>16 ; master->free_pos =GENMASK (master->maxdevs -1 ,0 ); +/* match any platform-specific ops */ + match =of_match_node (dw_i3c_master_of_match, pdev->dev.of_node); +if (match && match->data) + master->platform_ops = match->data; + +/* platform-specific probe */ +if (master->platform_ops && master->platform_ops->probe) { + ret = master->platform_ops->probe (master, pdev); +if (ret) + goto err_assert_rst; + } + ret =i3c_master_register (&master->base, &pdev->dev, &dw_mipi_i3c_ops, false);if (ret)
@@ -1213,12 +1249,6 @@ static int dw_i3c_remove(struct platform_device *pdev)return 0 ; } -static const struct of_device_id dw_i3c_master_of_match[] = { - { .compatible ="snps,dw-i3c-master-1.00a" , }, - {}, -}; -MODULE_DEVICE_TABLE (of, dw_i3c_master_of_match); -static struct platform_driver dw_i3c_driver = { .probe = dw_i3c_probe, .remove = dw_i3c_remove,
Signature · 1 line
2.39.1
Jeremy Kerr
maintainerPATCH 3/4 i3c: dw: Add AST2600 platform ops
In reply to Jeremy KerrNow that we have platform-specific hooks for the dw i3c driver, add platform support for the ASPEED AST2600 SoC.
The AST2600 has a small set of "i3c global" registers, providing platform-level i3c configuration outside of the i3c core.
For the ast2600, we need a couple of extra setup operations:
- on probe: find the i3c global register set and parse the SDA pullup resistor values
- on init: set the pullups accordingly, and set the i3c instance IDs
--- drivers/i3c/master/dw-i3c-master.c | 122 +++++++++++++++++++++++++++++ 1 file changed, 122 insertions(+)
drivers/i3c/master/dw-i3c-master.c +122 -0
@@ -16,8 +16,10 @@#include <linux/iopoll.h> #include <linux/list.h> #include <linux/module.h> +#include <linux/mfd/syscon.h> #include <linux/of.h> #include <linux/platform_device.h> +#include <linux/regmap.h> #include <linux/reset.h> #include <linux/slab.h>
@@ -201,6 +203,28 @@#define XFER_TIMEOUT (msecs_to_jiffies(1000)) +/* AST2600-specific global register set */ +#define AST2600_I3CG_REG0 (idx) (((idx) * 4 * 4) + 0x10) +#define AST2600_I3CG_REG1 (idx) (((idx) * 4 * 4) + 0x14) + +#define AST2600_I3CG_REG0_SDA_PULLUP_EN_MASK GENMASK(29, 28) +#define AST2600_I3CG_REG0_SDA_PULLUP_EN_2K (0x0 << 28) +#define AST2600_I3CG_REG0_SDA_PULLUP_EN_750 (0x2 << 28) + +#define AST2600_I3CG_REG1_I2C_MODE BIT(0) +#define AST2600_I3CG_REG1_TEST_MODE BIT(1) +#define AST2600_I3CG_REG1_ACT_MODE_MASK GENMASK(3, 2) +#define AST2600_I3CG_REG1_ACT_MODE (x) (((x) << 2) & AST2600_I3CG_REG1_ACT_MODE_MASK) +#define AST2600_I3CG_REG1_PENDING_INT_MASK GENMASK(7, 4) +#define AST2600_I3CG_REG1_PENDING_INT (x) (((x) << 4) & AST2600_I3CG_REG1_PENDING_INT_MASK) +#define AST2600_I3CG_REG1_SA_MASK GENMASK(14, 8) +#define AST2600_I3CG_REG1_SA (x) (((x) << 8) & AST2600_I3CG_REG1_SA_MASK) +#define AST2600_I3CG_REG1_SA_EN BIT(15) +#define AST2600_I3CG_REG1_INST_ID_MASK GENMASK(19, 16) +#define AST2600_I3CG_REG1_INST_ID (x) (((x) << 16) & AST2600_I3CG_REG1_INST_ID_MASK) + +#define AST2600_DEFAULT_SDA_PULLUP_OHMS 2000 +struct dw_i3c_master_caps {u8 cmdfifodepth;u8 datafifodepth;
@@ -224,6 +248,12 @@ struct dw_i3c_xfer {struct dw_i3c_cmd cmds[]; }; +struct pdata_ast2600 { +struct regmap *global_regs; +unsigned int global_idx; +unsigned int sda_pullup; +}; +struct dw_i3c_master {struct i3c_master_controller base;u16 maxdevs;
@@ -245,6 +275,7 @@ struct dw_i3c_master {/* platform-specific data */ const struct dw_i3c_platform_ops *platform_ops;union { +struct pdata_ast2600 ast2600; } pdata; };
@@ -1145,6 +1176,97 @@ static const struct i3c_master_controller_ops dw_mipi_i3c_ops = { .i2c_xfers = dw_i3c_master_i2c_xfers, }; +/* hardware-specific ops */ + +static int ast2600_i3c_pullup_to_reg (unsigned int ohms,u32 *regp) +{ +u32 reg; + +switch (ohms) { +case 2000 : + reg =AST2600_I3CG_REG0_SDA_PULLUP_EN_2K ; +break ; +case 750 : + reg =AST2600_I3CG_REG0_SDA_PULLUP_EN_750 ; +break ; +case 545 : + reg =AST2600_I3CG_REG0_SDA_PULLUP_EN_2K | +AST2600_I3CG_REG0_SDA_PULLUP_EN_750 ; +break ; +default : +return -EINVAL ; + } + +if (regp) + *regp = reg; + +return 0 ; +} + +static int ast2600_i3c_probe (struct dw_i3c_master *master, +struct platform_device *pdev) +{ +struct pdata_ast2600 *pdata = &master->pdata.ast2600; +struct device_node *np = pdev->dev.of_node; +struct of_phandle_args gspec; +int rc; + + rc =of_parse_phandle_with_fixed_args (np,"aspeed,global-regs" ,1 ,0 , + &gspec); +if (rc) +return -ENODEV ; + + pdata->global_regs =syscon_node_to_regmap (gspec.np); +of_node_put (gspec.np); + +if (IS_ERR (pdata->global_regs)) +return PTR_ERR (pdata->global_regs); + + pdata->global_idx = gspec.args[0 ]; + + rc =of_property_read_u32 (np,"sda-pullup-ohms" , &pdata->sda_pullup); +if (rc) + pdata->sda_pullup =AST2600_DEFAULT_SDA_PULLUP_OHMS ; + + rc =ast2600_i3c_pullup_to_reg (pdata->sda_pullup,NULL ); +if (rc) +dev_err (&master->base.dev,"invalid sda-pullup value %d\n" , + pdata->sda_pullup); + +return rc; +} + +static int ast2600_i3c_init (struct dw_i3c_master *master) +{ +struct pdata_ast2600 *pdata = &master->pdata.ast2600; +u32 reg =0 ; +int rc; + +/* reg0: set SDA pullup values */ + rc =ast2600_i3c_pullup_to_reg (pdata->sda_pullup, ®); +if (rc) +return rc; + + rc =regmap_write (pdata->global_regs, +AST2600_I3CG_REG0 (pdata->global_idx), reg); +if (rc) +return rc; + +/* reg1: set up the instance id, but leave everything else disabled, +* as it's all for client mode +*/ + reg =AST2600_I3CG_REG1_INST_ID (pdata->global_idx); + rc =regmap_write (pdata->global_regs, +AST2600_I3CG_REG1 (pdata->global_idx), reg); + +return rc; +} + +static const struct dw_i3c_platform_ops ast2600_platform_ops = { + .probe = ast2600_i3c_probe, + .init = ast2600_i3c_init, +}; +static const struct of_device_id dw_i3c_master_of_match[] = { { .compatible ="snps,dw-i3c-master-1.00a" , }, {},
Signature · 1 line
2.39.1
Jeremy Kerr
maintainerPATCH 4/4 i3c: dw: Add compatible string for ASPEED AST2600 BMC platform
In reply to Jeremy KerrNow that we have platform-specific code for the ast2600, enable it through a new compatible string.
--- drivers/i3c/master/dw-i3c-master.c | 1 + 1 file changed, 1 insertion(+)
drivers/i3c/master/dw-i3c-master.c +1 -0
@@ -1269,6 +1269,7 @@ static const struct dw_i3c_platform_ops ast2600_platform_ops = {static const struct of_device_id dw_i3c_master_of_match[] = { { .compatible ="snps,dw-i3c-master-1.00a" , }, + { .compatible ="aspeed,ast2600-i3c" , .data = &ast2600_platform_ops }, {}, };MODULE_DEVICE_TABLE (of, dw_i3c_master_of_match);
Signature · 1 line
2.39.1
PATCH 1/4 dt-bindings: i3c: Add AST2600 i3c controller
In reply to Jeremy KerrQuoted 4 lines · Jeremy Kerr
Add a devicetree binding for the ast2600 i3c controller hardware. This is heavily based on the designware i3c core, plus a reset facility and two platform-specific properties:
Quoted 8 lines
- sda-pullup-ohms: to specify the value of the configurable pullup resistors on the SDA line
- aspeed,global-regs: to reference the (ast2600-specific) i3c global register block, and the device index to use within it.
Signed-off-by Jeremy Kerr <[email protected]>
Best regards,
Krzysztof
Rob Herring
maintainerPATCH 1/4 dt-bindings: i3c: Add AST2600 i3c controller
In reply to Jeremy KerrQuoted 17 lines · Jeremy Kerr
Add a devicetree binding for the ast2600 i3c controller hardware. This is heavily based on the designware i3c core, plus a reset facility and two platform-specific properties:
- sda-pullup-ohms: to specify the value of the configurable pullup resistors on the SDA line
- aspeed,global-regs: to reference the (ast2600-specific) i3c global register block, and the device index to use within it.
Signed-off-by Jeremy Kerr <[email protected]>---
changes from RFC:
- add vendor prefix to global-regs properties
- add item description on global-regs property
- drop global reg node from example
Quoted 5 lines
--- .../bindings/i3c/aspeed,ast2600-i3c.yaml | 73 +++++++++++++++++++ 1 file changed, 73 insertions(+) create mode 100644 Documentation/devicetree/bindings/i3c/aspeed,ast2600-i3c.yaml
My bot found errors running 'make DT_CHECKER_FLAGS=-m dt_binding_check' on your patch (DT_CHECKER_FLAGS is new in v5.13):
yamllint warnings/errors:
dtschema/dtc warnings/errors:
Error: Documentation/devicetree/bindings/i3c/aspeed,ast2600-i3c.example.dts:30.31-32 syntax error FATAL ERROR: Unable to parse input tree
make[1]: *** [scripts/Makefile.lib:434: Documentation/devicetree/bindings/i3c/aspeed,ast2600-i3c.example.dtb] Error 1 make[1]: *** Waiting for unfinished jobs....
make: *** [Makefile:1508: dt_binding_check] Error 2
doc reference errors (make refcheckdocs):
See https://patchwork.ozlabs.org/project/devicetree-bindings/patch/82d750f53df622d8986e9a07053c7ee27dee61a2.1676532146.git.jk at codeconstruct.com.au
The base for the series is generally the latest rc1. A different dependency should be noted in *this* patch.
If you already ran 'make dt_binding_check' and didn't see the above error(s), then make sure 'yamllint' is installed and dt-schema is up to date:
pip3 install dtschema --upgrade
Please check and re-submit after running the above command yourself. Note that DT_SCHEMA_FILES can be set to your schema file to speed up checking your schema. However, it must be unset to test all examples with your schema.
PATCH 2/4 i3c: dw: Add platform operations
In reply to Jeremy KerrQuoted 25 lines · Jeremy Kerr
The dw i3c core can be integrated into various SoC devices. Platforms that use this core may need a little configuration that is specific to that platform.
Add a little infrastructure to allow platform-specific behaviour: a bit of data on struct
dw_i3c_master, and two hooks to the probe and init calls to enable this.A future change will add new platform support that uses these hooks.
Signed-off-by Jeremy Kerr <[email protected]>--- drivers/i3c/master/dw-i3c-master.c | 42 +++++++++++++++++++++++++----- 1 file changed, 36 insertions(+), 6 deletions(-)drivers/i3c/master/dw-i3c-master.c +2
-0@@ -241,6 +241,17 @@ struct dw_i3c_master {char version[5 ];char type[5 ];u8 addrs[MAX_DEVS ]; + +/* platform-specific data */
drivers/i3c/master/dw-i3c-master.c struct dw_i3c_master { · line 255
Quoted 10 lines
drivers/i3c/master/dw-i3c-master.c +9
-0+const struct dw_i3c_platform_ops *platform_ops; +union { + } pdata; + +}; + +struct dw_i3c_platform_ops { +int (*probe)(struct dw_i3c_master *i3c,struct platform_device *pdev); +int (*init)(struct dw_i3c_master *i3c); };
Given the comment below having this and the main probe defined in a header so users can just call in and we don't have to change the main code here every time someone comes up with their own special way of handing this?
drivers/i3c/master/dw-i3c-master.c static int dw_i3c_master_bus_init(struct i3c_master_controller *m) · line 630
Quoted 10 lines
drivers/i3c/master/dw-i3c-master.c +5
-0struct dw_i3c_i2c_dev_data {@@ -612,6 +623,12 @@ static int dw_i3c_master_bus_init(struct i3c_master_controller *m)u32 thld_ctrl;int ret; +if (master->platform_ops && master->platform_ops->init) { + ret = master->platform_ops->init (master); +if (ret) +return ret; + }
I'd rather have a "default" set of ops than have all this checking for NULL pointers all over the place.
Quoted 21 lines
drivers/i3c/master/dw-i3c-master.c +8
-0+switch (bus->mode) {case I3C_BUS_MODE_MIXED_FAST :case I3C_BUS_MODE_MIXED_LIMITED :@@ -1128,8 +1145,15 @@ static const struct i3c_master_controller_ops dw_mipi_i3c_ops = { .i2c_xfers = dw_i3c_master_i2c_xfers, }; +static const struct of_device_id dw_i3c_master_of_match[] = { + { .compatible ="snps,dw-i3c-master-1.00a" , }, + {}, +}; +MODULE_DEVICE_TABLE (of, dw_i3c_master_of_match); +static int dw_i3c_probe (struct platform_device *pdev) { +const struct of_device_id *match;struct dw_i3c_master *master;int ret, irq;
drivers/i3c/master/dw-i3c-master.c static int dw_i3c_probe(struct platform_device *pdev) · line 1211
Quoted 7 lines
drivers/i3c/master/dw-i3c-master.c +4
-0@@ -1181,6 +1205,18 @@ static int dw_i3c_probe(struct platform_device *pdev) master->maxdevs = ret >>16 ; master->free_pos =GENMASK (master->maxdevs -1 ,0 ); +/* match any platform-specific ops */ + match =of_match_node (dw_i3c_master_of_match, pdev->dev.of_node); +if (match && match->data) + master->platform_ops = match->data;
I'm sure there's a of_device_get_match_data() which would have both removed hte need to move the match table around and the call to of_match_node().
Quoted 24 lines
drivers/i3c/master/dw-i3c-master.c +8
-6+ +/* platform-specific probe */ +if (master->platform_ops && master->platform_ops->probe) { + ret = master->platform_ops->probe (master, pdev); +if (ret) + goto err_assert_rst; + } + ret =i3c_master_register (&master->base, &pdev->dev, &dw_mipi_i3c_ops, false);if (ret)@@ -1213,12 +1249,6 @@ static int dw_i3c_remove(struct platform_device *pdev)return 0 ; } -static const struct of_device_id dw_i3c_master_of_match[] = { - { .compatible ="snps,dw-i3c-master-1.00a" , }, - {}, -}; -MODULE_DEVICE_TABLE (of, dw_i3c_master_of_match); -static struct platform_driver dw_i3c_driver = { .probe = dw_i3c_probe, .remove = dw_i3c_remove,
Jeremy Kerr
maintainerPATCH 2/4 i3c: dw: Add platform operations
Hi Ben,
Thanks for taking a look at the patch. My responses inline (just re-ordered, simple stuff first)
Quoted 5 lines
Quoted 5 lines
? struct
dw_i3c_i2c_dev_data{(quoted diff) +0
-0@@ -612,6 +623,12 @@ static int dw_i3c_master_bus_init(struct i3c_master_controller *m) ????????u32 thld_ctrl; ????????int ret;?
Quoted 8 lines
Quoted 5 lines
+???????if (
master->platform_ops&&master->platform_ops->init) { +???????????????ret =master->platform_ops->init(master); +???????????????if (ret)
+???????????????????????return ret;
+???????}I'd rather have a "default" set of ops than have all this checking for NULL pointers all over the place.
Yep, that's a better structure, changed for v2.
Quoted 4 lines
Quoted 4 lines
(quoted diff) +0
-0@@ -1181,6 +1205,18 @@ static int dw_i3c_probe(struct platform_device *pdev) ????????master->maxdevs = ret >> 16; ????????master->free_pos = GENMASK(master->maxdevs - 1, 0);?
Quoted 8 lines
Quoted 4 lines
+???????/* match any platform-specific ops */
+???????match =of_match_node(dw_i3c_master_of_match, pdev->dev.of_node); +???????if (match &&match->data) +???????????????master->platform_ops =match->data;I'm sure there's a
of_device_get_match_data()which would have both removed hte need to move the match table around and the call toof_match_node().
That's the one I was looking for! Thanks for the pointer, I have updated in v2.
Quoted 13 lines
Quoted 13 lines
(quoted diff) +9
-0@@ -241,6 +241,17 @@ struct dw_i3c_master { ????????char version[5]; ????????char type[5]; ????????u8 addrs[MAX_DEVS]; + +???????/* platform-specific data */ +???????const struct dw_i3c_platform_ops *platform_ops; +???????union { +???????} pdata; + +}; + +struct dw_i3c_platform_ops {
Quoted 8 lines
Review struct dw_i3c_master { · line 255
Quoted 3 lines
(quoted diff) +2
-0+???????int (*probe)(struct dw_i3c_master *i3c, struct platform_device *pdev); +???????int (*init)(struct dw_i3c_master *i3c); ? };Given the comment below having this and the main probe defined in a header so users can just call in and we don't have to change the main code here every time someone comes up with their own special way of handing this?
I'm not sure I 100% understand the intention here - is it that we'd split the platform-specific code into entirely new drivers, and have those call into dw_i3c_probe() (presumably doing a bit of custom init either before or after that call)?
If so: I think the platform support should stay fairly minimal, so I'm not sure that warrants a new driver for each instance. In the ast2600 case it's just a couple of extra reg writes in the i3c init path. I'd be reluctant to split that out completely at this stage - but if this does grow, we can certainly reconsider.
Also, I'd like to allow for the case where the platform-specific parts may access the fields of struct dw_i3c_master; with this approach we don't need to expose that struct outside of the single driver.
Cheers,
Jeremy
Joel Stanley
maintainercover i3c: Add support for ast2600 i3c controller
In reply to Jeremy KerrQuoted 16 lines · Jeremy Kerr
The AST2600 SoC hardware includes a set of i3c controllers, based on the designware i3c core, plus some global registers for SoC integration.
This series adds support for these i3c controllers, through the existing dw i3c master controller driver, by adding a set of platform-specific hooks to handle the global register configuration. This also gives us a way to add any future hardware-specific behaviours.
We also need a DT binding to describe the ast2600-specific hardware. Since this involves new (mandatory) properties, I have added this as a separate binding rather than add a new compat string to the dw binding.
The dt-binding example depends on a prior submission to the dt binding headers:
Quoted 7 lines
https://lore.kernel.org/linux-devicetree/cover.1676294433.git.jk at codeconstruct.com.au/
Full support for the global regmap will land with this queued mfd change:
Of course, any queries/comments/etc are most welcome.
Quoted 20 lines
Cheers,
Jeremy
Jeremy Kerr (4):
dt-bindings: i3c: Add AST2600 i3c controller
i3c: dw: Add platform operations
i3c: dw: Add AST2600 platform ops
i3c: dw: Add compatible string for ASPEED AST2600 BMC platform.../bindings/i3c/aspeed,ast2600-i3c.yaml | 73 ++++++++ drivers/i3c/master/dw-i3c-master.c | 165 +++++++++++++++++- 2 files changed, 232 insertions(+), 6 deletions(-) create mode 100644 Documentation/devicetree/bindings/i3c/aspeed,ast2600-i3c.yaml--
2.39.1