Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

serial: sh-sci: Introduced sci_of_data

The aim here is to provide an easier support to more different SCI
controllers, like the RZ/T2H one.

The existing .data field of_sci_match is changed to a structure containing
all what that can be statically initialized, and avoid a call to
'sci_probe_regmap', in both 'sci_init_single', and 'early_console_setup'.

'sci_probe_regmap' is now assumed to be called in the only case where the
device description is from a board file instead of a dts.

In this way, there is no need to patch 'sci_probe_regmap' for adding new
SCI type, and also, the specific sci_port_params for a new SCI type can be
provided by an external file.

Reviewed-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
Tested-by: Geert Uytterhoeven <geert+renesas@glider.be>
Signed-off-by: Thierry Bultel <thierry.bultel.yh@bp.renesas.com>
Link: https://lore.kernel.org/r/20250403212919.1137670-10-thierry.bultel.yh@bp.renesas.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Thierry Bultel and committed by
Greg Kroah-Hartman
043806bc 21fc3d6b

+131 -43
+9 -1
drivers/tty/serial/sh-sci-common.h
··· 89 89 size_t (*suspend_regs_size)(void); 90 90 }; 91 91 92 + struct sci_of_data { 93 + const struct sci_port_params *params; 94 + const struct uart_ops *uart_ops; 95 + const struct sci_port_ops *ops; 96 + unsigned short regtype; 97 + unsigned short type; 98 + }; 99 + 92 100 struct sci_port { 93 101 struct uart_port port; 94 102 ··· 161 153 #define max_sr(_port) fls((_port)->sampling_rate_mask) 162 154 163 155 #ifdef CONFIG_SERIAL_SH_SCI_EARLYCON 164 - int __init scix_early_console_setup(struct earlycon_device *device, int); 156 + int __init scix_early_console_setup(struct earlycon_device *device, const struct sci_of_data *data); 165 157 #endif 166 158 167 159 #endif /* __SH_SCI_COMMON_H__ */
+122 -42
drivers/tty/serial/sh-sci.c
··· 2996 2996 } 2997 2997 2998 2998 static const struct sci_port_params * 2999 - sci_probe_regmap(const struct plat_sci_port *cfg) 2999 + sci_probe_regmap(const struct plat_sci_port *cfg, struct sci_port *sci_port) 3000 3000 { 3001 3001 unsigned int regtype; 3002 + 3003 + sci_port->ops = &sci_port_ops; 3004 + sci_port->port.ops = &sci_uart_ops; 3002 3005 3003 3006 if (cfg->regtype != SCIx_PROBE_REGTYPE) 3004 3007 return &sci_port_params[cfg->regtype]; ··· 3049 3046 int ret; 3050 3047 3051 3048 sci_port->cfg = p; 3052 - sci_port->ops = &sci_port_ops; 3053 3049 3054 - port->ops = &sci_uart_ops; 3055 3050 port->iotype = UPIO_MEM; 3056 3051 port->line = index; 3057 3052 port->has_sysrq = IS_ENABLED(CONFIG_SERIAL_SH_SCI_CONSOLE); ··· 3088 3087 if (sci_port->irqs[1] < 0) 3089 3088 for (i = 1; i < ARRAY_SIZE(sci_port->irqs); i++) 3090 3089 sci_port->irqs[i] = sci_port->irqs[0]; 3091 - 3092 - sci_port->params = sci_probe_regmap(p); 3093 - if (unlikely(sci_port->params == NULL)) 3094 - return -EINVAL; 3095 3090 3096 3091 switch (p->type) { 3097 3092 case PORT_SCIFB: ··· 3274 3277 static int sci_probe_earlyprintk(struct platform_device *pdev) 3275 3278 { 3276 3279 const struct plat_sci_port *cfg = dev_get_platdata(&pdev->dev); 3280 + struct sci_port *sp = &sci_ports[pdev->id]; 3277 3281 3278 3282 if (early_serial_console.data) 3279 3283 return -EEXIST; 3280 3284 3281 3285 early_serial_console.index = pdev->id; 3282 3286 3283 - sci_init_single(pdev, &sci_ports[pdev->id], pdev->id, cfg, true); 3287 + sp->params = sci_probe_regmap(cfg, sp); 3288 + if (!sp->params) 3289 + return -ENODEV; 3290 + 3291 + sci_init_single(pdev, sp, pdev->id, cfg, true); 3284 3292 3285 3293 if (!strstr(early_serial_buf, "keep")) 3286 3294 early_serial_console.flags |= CON_BOOT; ··· 3334 3332 device_remove_file(&dev->dev, &dev_attr_rx_fifo_timeout); 3335 3333 } 3336 3334 3337 - #define SCI_OF_DATA(type, regtype) (void *)((type) << 16 | (regtype)) 3338 - #define SCI_OF_TYPE(data) ((unsigned long)(data) >> 16) 3339 - #define SCI_OF_REGTYPE(data) ((unsigned long)(data) & 0xffff) 3335 + static const struct sci_of_data of_sci_scif_sh2 = { 3336 + .type = PORT_SCIF, 3337 + .regtype = SCIx_SH2_SCIF_FIFODATA_REGTYPE, 3338 + .ops = &sci_port_ops, 3339 + .uart_ops = &sci_uart_ops, 3340 + .params = &sci_port_params[SCIx_SH2_SCIF_FIFODATA_REGTYPE], 3341 + }; 3342 + 3343 + static const struct sci_of_data of_sci_scif_rz_scifa = { 3344 + .type = PORT_SCIF, 3345 + .regtype = SCIx_RZ_SCIFA_REGTYPE, 3346 + .ops = &sci_port_ops, 3347 + .uart_ops = &sci_uart_ops, 3348 + .params = &sci_port_params[SCIx_RZ_SCIFA_REGTYPE], 3349 + }; 3350 + 3351 + static const struct sci_of_data of_sci_scif_rzv2h = { 3352 + .type = PORT_SCIF, 3353 + .regtype = SCIx_RZV2H_SCIF_REGTYPE, 3354 + .ops = &sci_port_ops, 3355 + .uart_ops = &sci_uart_ops, 3356 + .params = &sci_port_params[SCIx_RZV2H_SCIF_REGTYPE], 3357 + }; 3358 + 3359 + static const struct sci_of_data of_sci_rcar_scif = { 3360 + .type = PORT_SCIF, 3361 + .regtype = SCIx_SH4_SCIF_BRG_REGTYPE, 3362 + .ops = &sci_port_ops, 3363 + .uart_ops = &sci_uart_ops, 3364 + .params = &sci_port_params[SCIx_SH4_SCIF_BRG_REGTYPE], 3365 + }; 3366 + 3367 + static const struct sci_of_data of_sci_scif_sh4 = { 3368 + .type = PORT_SCIF, 3369 + .regtype = SCIx_SH4_SCIF_REGTYPE, 3370 + .ops = &sci_port_ops, 3371 + .uart_ops = &sci_uart_ops, 3372 + .params = &sci_port_params[SCIx_SH4_SCIF_REGTYPE], 3373 + }; 3374 + 3375 + static const struct sci_of_data of_sci_scifa = { 3376 + .type = PORT_SCIFA, 3377 + .regtype = SCIx_SCIFA_REGTYPE, 3378 + .ops = &sci_port_ops, 3379 + .uart_ops = &sci_uart_ops, 3380 + .params = &sci_port_params[SCIx_SCIFA_REGTYPE], 3381 + }; 3382 + 3383 + static const struct sci_of_data of_sci_scifb = { 3384 + .type = PORT_SCIFB, 3385 + .regtype = SCIx_SCIFB_REGTYPE, 3386 + .ops = &sci_port_ops, 3387 + .uart_ops = &sci_uart_ops, 3388 + .params = &sci_port_params[SCIx_SCIFB_REGTYPE], 3389 + }; 3390 + 3391 + static const struct sci_of_data of_sci_hscif = { 3392 + .type = PORT_HSCIF, 3393 + .regtype = SCIx_HSCIF_REGTYPE, 3394 + .ops = &sci_port_ops, 3395 + .uart_ops = &sci_uart_ops, 3396 + .params = &sci_port_params[SCIx_HSCIF_REGTYPE], 3397 + }; 3398 + 3399 + static const struct sci_of_data of_sci_sci = { 3400 + .type = PORT_SCI, 3401 + .regtype = SCIx_SCI_REGTYPE, 3402 + .ops = &sci_port_ops, 3403 + .uart_ops = &sci_uart_ops, 3404 + .params = &sci_port_params[SCIx_SCI_REGTYPE], 3405 + }; 3340 3406 3341 3407 static const struct of_device_id of_sci_match[] __maybe_unused = { 3342 3408 /* SoC-specific types */ 3343 3409 { 3344 3410 .compatible = "renesas,scif-r7s72100", 3345 - .data = SCI_OF_DATA(PORT_SCIF, SCIx_SH2_SCIF_FIFODATA_REGTYPE), 3411 + .data = &of_sci_scif_sh2, 3346 3412 }, 3347 3413 { 3348 3414 .compatible = "renesas,scif-r7s9210", 3349 - .data = SCI_OF_DATA(PORT_SCIF, SCIx_RZ_SCIFA_REGTYPE), 3415 + .data = &of_sci_scif_rz_scifa, 3350 3416 }, 3351 3417 { 3352 3418 .compatible = "renesas,scif-r9a07g044", 3353 - .data = SCI_OF_DATA(PORT_SCIF, SCIx_RZ_SCIFA_REGTYPE), 3419 + .data = &of_sci_scif_rz_scifa, 3354 3420 }, 3355 3421 { 3356 3422 .compatible = "renesas,scif-r9a09g057", 3357 - .data = SCI_OF_DATA(PORT_SCIF, SCIx_RZV2H_SCIF_REGTYPE), 3423 + .data = &of_sci_scif_rzv2h, 3358 3424 }, 3359 3425 /* Family-specific types */ 3360 3426 { 3361 3427 .compatible = "renesas,rcar-gen1-scif", 3362 - .data = SCI_OF_DATA(PORT_SCIF, SCIx_SH4_SCIF_BRG_REGTYPE), 3428 + .data = &of_sci_rcar_scif, 3363 3429 }, { 3364 3430 .compatible = "renesas,rcar-gen2-scif", 3365 - .data = SCI_OF_DATA(PORT_SCIF, SCIx_SH4_SCIF_BRG_REGTYPE), 3431 + .data = &of_sci_rcar_scif, 3366 3432 }, { 3367 3433 .compatible = "renesas,rcar-gen3-scif", 3368 - .data = SCI_OF_DATA(PORT_SCIF, SCIx_SH4_SCIF_BRG_REGTYPE), 3434 + .data = &of_sci_rcar_scif 3369 3435 }, { 3370 3436 .compatible = "renesas,rcar-gen4-scif", 3371 - .data = SCI_OF_DATA(PORT_SCIF, SCIx_SH4_SCIF_BRG_REGTYPE), 3437 + .data = &of_sci_rcar_scif 3372 3438 }, 3373 3439 /* Generic types */ 3374 3440 { 3375 3441 .compatible = "renesas,scif", 3376 - .data = SCI_OF_DATA(PORT_SCIF, SCIx_SH4_SCIF_REGTYPE), 3442 + .data = &of_sci_scif_sh4, 3377 3443 }, { 3378 3444 .compatible = "renesas,scifa", 3379 - .data = SCI_OF_DATA(PORT_SCIFA, SCIx_SCIFA_REGTYPE), 3445 + .data = &of_sci_scifa, 3380 3446 }, { 3381 3447 .compatible = "renesas,scifb", 3382 - .data = SCI_OF_DATA(PORT_SCIFB, SCIx_SCIFB_REGTYPE), 3448 + .data = &of_sci_scifb, 3383 3449 }, { 3384 3450 .compatible = "renesas,hscif", 3385 - .data = SCI_OF_DATA(PORT_HSCIF, SCIx_HSCIF_REGTYPE), 3451 + .data = &of_sci_hscif, 3386 3452 }, { 3387 3453 .compatible = "renesas,sci", 3388 - .data = SCI_OF_DATA(PORT_SCI, SCIx_SCI_REGTYPE), 3454 + .data = &of_sci_sci, 3389 3455 }, { 3390 3456 /* Terminator */ 3391 3457 }, ··· 3472 3402 struct reset_control *rstc; 3473 3403 struct plat_sci_port *p; 3474 3404 struct sci_port *sp; 3475 - const void *data; 3405 + const struct sci_of_data *data; 3476 3406 int id, ret; 3477 3407 3478 3408 if (!IS_ENABLED(CONFIG_OF) || !np) ··· 3519 3449 sp->rstc = rstc; 3520 3450 *dev_id = id; 3521 3451 3522 - p->type = SCI_OF_TYPE(data); 3523 - p->regtype = SCI_OF_REGTYPE(data); 3452 + p->type = data->type; 3453 + p->regtype = data->regtype; 3454 + 3455 + sp->ops = data->ops; 3456 + sp->port.ops = data->uart_ops; 3457 + sp->params = data->params; 3524 3458 3525 3459 sp->has_rtscts = of_property_read_bool(np, "uart-has-rtscts"); 3526 3460 ··· 3631 3557 p = sci_parse_dt(dev, &dev_id); 3632 3558 if (IS_ERR(p)) 3633 3559 return PTR_ERR(p); 3560 + sp = &sci_ports[dev_id]; 3634 3561 } else { 3635 3562 p = dev->dev.platform_data; 3636 3563 if (p == NULL) { ··· 3640 3565 } 3641 3566 3642 3567 dev_id = dev->id; 3568 + sp = &sci_ports[dev_id]; 3569 + sp->params = sci_probe_regmap(p, sp); 3570 + if (!sp->params) 3571 + return -ENODEV; 3643 3572 } 3644 3573 3645 - sp = &sci_ports[dev_id]; 3646 3574 sp->suspend_regs = devm_kzalloc(&dev->dev, 3647 3575 sp->ops->suspend_regs_size(), 3648 3576 GFP_KERNEL); ··· 3792 3714 } 3793 3715 3794 3716 int __init scix_early_console_setup(struct earlycon_device *device, 3795 - int type) 3717 + const struct sci_of_data *data) 3796 3718 { 3797 3719 const struct sci_common_regs *regs; 3798 3720 3799 3721 if (!device->port.membase) 3800 3722 return -ENODEV; 3801 3723 3802 - device->port.type = type; 3724 + device->port.type = data->type; 3803 3725 sci_ports[0].port = device->port; 3804 - port_cfg.type = type; 3726 + 3727 + port_cfg.type = data->type; 3728 + port_cfg.regtype = data->regtype; 3729 + 3805 3730 sci_ports[0].cfg = &port_cfg; 3806 - sci_ports[0].ops = &sci_port_ops; 3807 - sci_ports[0].params = sci_probe_regmap(&port_cfg); 3731 + sci_ports[0].params = data->params; 3732 + sci_ports[0].ops = data->ops; 3733 + sci_ports[0].port.ops = data->uart_ops; 3808 3734 sci_uart_earlycon = true; 3809 3735 regs = sci_ports[0].params->common_regs; 3810 3736 ··· 3825 3743 static int __init sci_early_console_setup(struct earlycon_device *device, 3826 3744 const char *opt) 3827 3745 { 3828 - return scix_early_console_setup(device, PORT_SCI); 3746 + return scix_early_console_setup(device, &of_sci_sci); 3829 3747 } 3830 3748 static int __init scif_early_console_setup(struct earlycon_device *device, 3831 3749 const char *opt) 3832 3750 { 3833 - return scix_early_console_setup(device, PORT_SCIF); 3751 + return scix_early_console_setup(device, &of_sci_scif_sh4); 3834 3752 } 3835 3753 static int __init rzscifa_early_console_setup(struct earlycon_device *device, 3836 3754 const char *opt) 3837 3755 { 3838 - port_cfg.regtype = SCIx_RZ_SCIFA_REGTYPE; 3839 - return scix_early_console_setup(device, PORT_SCIF); 3756 + return scix_early_console_setup(device, &of_sci_scif_rz_scifa); 3840 3757 } 3841 3758 3842 3759 static int __init rzv2hscif_early_console_setup(struct earlycon_device *device, 3843 3760 const char *opt) 3844 3761 { 3845 - port_cfg.regtype = SCIx_RZV2H_SCIF_REGTYPE; 3846 - return scix_early_console_setup(device, PORT_SCIF); 3762 + return scix_early_console_setup(device, &of_sci_scif_rzv2h); 3847 3763 } 3848 3764 3849 3765 static int __init scifa_early_console_setup(struct earlycon_device *device, 3850 3766 const char *opt) 3851 3767 { 3852 - return scix_early_console_setup(device, PORT_SCIFA); 3768 + return scix_early_console_setup(device, &of_sci_scifa); 3853 3769 } 3854 3770 static int __init scifb_early_console_setup(struct earlycon_device *device, 3855 3771 const char *opt) 3856 3772 { 3857 - return scix_early_console_setup(device, PORT_SCIFB); 3773 + return scix_early_console_setup(device, &of_sci_scifb); 3858 3774 } 3859 3775 static int __init hscif_early_console_setup(struct earlycon_device *device, 3860 3776 const char *opt) 3861 3777 { 3862 - return scix_early_console_setup(device, PORT_HSCIF); 3778 + return scix_early_console_setup(device, &of_sci_hscif); 3863 3779 } 3864 3780 3865 3781 OF_EARLYCON_DECLARE(sci, "renesas,sci", sci_early_console_setup);