From 1b72d87cce0dd2192670ed126a6748dba0023be3 Mon Sep 17 00:00:00 2001 From: Jon Hunter Date: Wed, 10 Apr 2024 15:49:15 +0100 Subject: [PATCH] media: camera: Fix build for Linux v6.10 In Linux v6.10, a pointer to a dynamically allocated 'struct device' was replaced with a statically allocated 'struct device' in the 'pwm_chip' structure. Update the Tegra camera drivers accordingly to fix the build for Linux v6.10. Bug 4593750 Change-Id: I05e15e2a63383ab2f96be6c20e81705de9581869 Signed-off-by: Jon Hunter Reviewed-on: https://git-master.nvidia.com/r/c/linux-nv-oot/+/3123220 GVS: buildbot_gerritrpt Reviewed-by: Brad Griffis --- .../media/platform/tegra/cdi/cdi-pwm-priv.h | 6 +- drivers/media/platform/tegra/cdi/cdi_pwm.c | 73 ++++++++++++------- .../media/platform/tegra/isc/isc-pwm-priv.h | 6 +- drivers/media/platform/tegra/isc/isc_pwm.c | 69 +++++++++++------- 4 files changed, 97 insertions(+), 57 deletions(-) diff --git a/drivers/media/platform/tegra/cdi/cdi-pwm-priv.h b/drivers/media/platform/tegra/cdi/cdi-pwm-priv.h index dc2a02ba..fbc832a7 100644 --- a/drivers/media/platform/tegra/cdi/cdi-pwm-priv.h +++ b/drivers/media/platform/tegra/cdi/cdi-pwm-priv.h @@ -1,11 +1,13 @@ -// SPDX-License-Identifier: GPL-2.0 -// Copyright (c) 2016-2022, NVIDIA CORPORATION & AFFILIATES. All rights reserved. +/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-FileCopyrightText: Copyright (c) 2016-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved. */ #ifndef __CDI_PWM_PRIV_H__ #define __CDI_PWM_PRIV_H__ struct cdi_pwm_info { +#if !defined(NV_PWM_CHIP_STRUCT_HAS_STRUCT_DEVICE) struct pwm_chip chip; +#endif struct pwm_device *pwm; atomic_t in_use; struct mutex mutex; diff --git a/drivers/media/platform/tegra/cdi/cdi_pwm.c b/drivers/media/platform/tegra/cdi/cdi_pwm.c index 038ac0da..a6f22d34 100644 --- a/drivers/media/platform/tegra/cdi/cdi_pwm.c +++ b/drivers/media/platform/tegra/cdi/cdi_pwm.c @@ -1,5 +1,5 @@ -// SPDX-License-Identifier: GPL-2.0 -// Copyright (c) 2016-2024, NVIDIA CORPORATION & AFFILIATES. All rights reserved. +// SPDX-License-Identifier: GPL-2.0-only +// SPDX-FileCopyrightText: Copyright (c) 2016-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved. #include @@ -30,7 +30,11 @@ static const struct of_device_id cdi_pwm_of_match[] = { static inline struct cdi_pwm_info *to_cdi_pwm_info(struct pwm_chip *chip) { +#if defined(NV_PWM_CHIP_STRUCT_HAS_STRUCT_DEVICE) + return pwmchip_get_drvdata(chip); +#else return container_of(chip, struct cdi_pwm_info, chip); +#endif } #if KERNEL_VERSION(6, 0, 0) > LINUX_VERSION_CODE @@ -95,30 +99,35 @@ static struct pwm_device *of_cdi_pwm_xlate(struct pwm_chip *pc, { struct pwm_device *pwm; struct cdi_pwm_info *info = to_cdi_pwm_info(pc); +#if defined(NV_PWM_CHIP_STRUCT_HAS_STRUCT_DEVICE) + struct device *dev = &pc->dev; +#else + struct device *dev = pc->dev; +#endif int err = 0; pwm = pwm_request_from_chip(pc, args->args[0], NULL); if (!args->args[1]) { - dev_err(pc->dev, "Period should be larger than 0\n"); + dev_err(dev, "Period should be larger than 0\n"); return NULL; } if (info->force_on) { err = pwm_config(info->pwm, args->args[1]/4, args->args[1]); if (err) { - dev_err(pc->dev, "can't config PWM: %d\n", err); + dev_err(dev, "can't config PWM: %d\n", err); return NULL; } err = pwm_enable(info->pwm); if (err) { - dev_err(pc->dev, "can't enable PWM: %d\n", err); + dev_err(dev, "can't enable PWM: %d\n", err); return NULL; } } else { err = pwm_config(pwm, args->args[1]/4, args->args[1]); if (err) { - dev_err(pc->dev, "can't config PWM: %d\n", err); + dev_err(dev, "can't config PWM: %d\n", err); return NULL; } } @@ -140,50 +149,60 @@ static const struct pwm_ops cdi_pwm_ops = { static int cdi_pwm_probe(struct platform_device *pdev) { struct cdi_pwm_info *info = NULL; + struct pwm_chip *chip; int err = 0, npwm; bool force_on = false; dev_info(&pdev->dev, "%sing...\n", __func__); - info = devm_kzalloc( - &pdev->dev, sizeof(struct cdi_pwm_info), GFP_KERNEL); - if (!info) - return -ENOMEM; - - atomic_set(&info->in_use, 0); - mutex_init(&info->mutex); - err = of_property_read_u32(pdev->dev.of_node, "npwm", &npwm); if (err < 0) { dev_err(&pdev->dev, "npwm is not defined: %d\n", err); return err; } +#if defined(NV_PWM_CHIP_STRUCT_HAS_STRUCT_DEVICE) + chip = devm_pwmchip_alloc(&pdev->dev, npwm, sizeof(*info)); + if (IS_ERR(chip)) + return PTR_ERR(chip); + info = to_cdi_pwm_info(chip); +#else + info = devm_kzalloc( + &pdev->dev, sizeof(struct cdi_pwm_info), GFP_KERNEL); + if (!info) + return -ENOMEM; + + chip = &info->chip; + chip->dev = &pdev->dev; + chip->npwm = npwm; +#endif + + atomic_set(&info->in_use, 0); + mutex_init(&info->mutex); + force_on = of_property_read_bool(pdev->dev.of_node, "force_on"); - info->chip.dev = &pdev->dev; - info->chip.ops = &cdi_pwm_ops; + chip->ops = &cdi_pwm_ops; #if defined(NV_PWM_CHIP_STRUCT_HAS_BASE_ARG) - info->chip.base = -1; + chip->base = -1; #endif - info->chip.npwm = npwm; - info->chip.of_xlate = of_cdi_pwm_xlate; + chip->of_xlate = of_cdi_pwm_xlate; info->force_on = force_on; - err = pwmchip_add(&info->chip); + err = pwmchip_add(chip); if (err < 0) { dev_err(&pdev->dev, "pwmchip_add() failed: %d\n", err); return err; } - platform_set_drvdata(pdev, info); + platform_set_drvdata(pdev, chip); info->pwm = devm_pwm_get(&pdev->dev, NULL); if (!IS_ERR(info->pwm)) { pwm_disable(info->pwm); dev_info(&pdev->dev, "%s success to get PWM\n", __func__); } else { - pwmchip_remove(&info->chip); + pwmchip_remove(chip); err = PTR_ERR(info->pwm); if (err != -EPROBE_DEFER) dev_err(&pdev->dev, @@ -195,24 +214,24 @@ static int cdi_pwm_probe(struct platform_device *pdev) static int cdi_pwm_remove(struct platform_device *pdev) { - struct cdi_pwm_info *info = platform_get_drvdata(pdev); + struct pwm_chip *chip = platform_get_drvdata(pdev); - pwmchip_remove(&info->chip); + pwmchip_remove(chip); return 0; } static int cdi_pwm_suspend(struct device *dev) { - int err = 0; - struct cdi_pwm_info *info = dev_get_drvdata(dev); + struct pwm_chip *chip = dev_get_drvdata(dev); + struct cdi_pwm_info *info = to_cdi_pwm_info(chip); if (info == NULL) { dev_err(dev, "%s: fail to get info\n", __func__); } else { if (!IS_ERR(info->pwm)) { pwm_disable(info->pwm); - err = pwm_config(info->pwm, PWM_SUSPEND_DUTY_RATIO, + pwm_config(info->pwm, PWM_SUSPEND_DUTY_RATIO, PWM_SUSPEND_PERIOD); } } diff --git a/drivers/media/platform/tegra/isc/isc-pwm-priv.h b/drivers/media/platform/tegra/isc/isc-pwm-priv.h index 3fb087ac..c91e75c1 100644 --- a/drivers/media/platform/tegra/isc/isc-pwm-priv.h +++ b/drivers/media/platform/tegra/isc/isc-pwm-priv.h @@ -1,13 +1,13 @@ /* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Copyright (c) 2016-2022, NVIDIA CORPORATION & AFFILIATES. All rights reserved. - */ +/* SPDX-FileCopyrightText: Copyright (c) 2016-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved. */ #ifndef __ISC_PWM_PRIV_H__ #define __ISC_PWM_PRIV_H__ struct isc_pwm_info { +#if !defined(NV_PWM_CHIP_STRUCT_HAS_STRUCT_DEVICE) struct pwm_chip chip; +#endif struct pwm_device *pwm; atomic_t in_use; struct mutex mutex; diff --git a/drivers/media/platform/tegra/isc/isc_pwm.c b/drivers/media/platform/tegra/isc/isc_pwm.c index 4a542ee0..ca39bae5 100644 --- a/drivers/media/platform/tegra/isc/isc_pwm.c +++ b/drivers/media/platform/tegra/isc/isc_pwm.c @@ -30,7 +30,11 @@ static const struct of_device_id isc_pwm_of_match[] = { static inline struct isc_pwm_info *to_isc_pwm_info(struct pwm_chip *chip) { +#if defined(NV_PWM_CHIP_STRUCT_HAS_STRUCT_DEVICE) + return pwmchip_get_drvdata(chip); +#else return container_of(chip, struct isc_pwm_info, chip); +#endif } #if KERNEL_VERSION(6, 0, 0) > LINUX_VERSION_CODE @@ -95,30 +99,35 @@ static struct pwm_device *of_isc_pwm_xlate(struct pwm_chip *pc, { struct pwm_device *pwm; struct isc_pwm_info *info = to_isc_pwm_info(pc); +#if defined(NV_PWM_CHIP_STRUCT_HAS_STRUCT_DEVICE) + struct device *dev = &pc->dev; +#else + struct device *dev = pc->dev; +#endif int err = 0; pwm = pwm_request_from_chip(pc, args->args[0], NULL); if (!args->args[1]) { - dev_err(pc->dev, "Period should be larger than 0\n"); + dev_err(dev, "Period should be larger than 0\n"); return NULL; } if (info->force_on) { err = pwm_config(info->pwm, args->args[1]/4, args->args[1]); if (err) { - dev_err(pc->dev, "can't config PWM: %d\n", err); + dev_err(dev, "can't config PWM: %d\n", err); return NULL; } err = pwm_enable(info->pwm); if (err) { - dev_err(pc->dev, "can't enable PWM: %d\n", err); + dev_err(dev, "can't enable PWM: %d\n", err); return NULL; } } else { err = pwm_config(pwm, args->args[1]/4, args->args[1]); if (err) { - dev_err(pc->dev, "can't config PWM: %d\n", err); + dev_err(dev, "can't config PWM: %d\n", err); return NULL; } } @@ -140,50 +149,60 @@ static const struct pwm_ops isc_pwm_ops = { static int isc_pwm_probe(struct platform_device *pdev) { struct isc_pwm_info *info = NULL; + struct pwm_chip *chip; int err = 0, npwm; bool force_on = false; dev_info(&pdev->dev, "%sing...\n", __func__); - info = devm_kzalloc( - &pdev->dev, sizeof(struct isc_pwm_info), GFP_KERNEL); - if (!info) - return -ENOMEM; - - atomic_set(&info->in_use, 0); - mutex_init(&info->mutex); - err = of_property_read_u32(pdev->dev.of_node, "npwm", &npwm); if (err < 0) { dev_err(&pdev->dev, "npwm is not defined: %d\n", err); return err; } +#if defined(NV_PWM_CHIP_STRUCT_HAS_STRUCT_DEVICE) + chip = devm_pwmchip_alloc(&pdev->dev, npwm, sizeof(*info)); + if (IS_ERR(chip)) + return PTR_ERR(chip); + info = to_isc_pwm_info(chip); +#else + info = devm_kzalloc( + &pdev->dev, sizeof(struct isc_pwm_info), GFP_KERNEL); + if (!info) + return -ENOMEM; + + chip = &info->chip; + chip->dev = &pdev->dev; + chip->npwm = npwm; +#endif + + atomic_set(&info->in_use, 0); + mutex_init(&info->mutex); + force_on = of_property_read_bool(pdev->dev.of_node, "force_on"); - info->chip.dev = &pdev->dev; - info->chip.ops = &isc_pwm_ops; + chip->ops = &isc_pwm_ops; #if defined(NV_PWM_CHIP_STRUCT_HAS_BASE_ARG) - info->chip.base = -1; + chip->base = -1; #endif - info->chip.npwm = npwm; - info->chip.of_xlate = of_isc_pwm_xlate; + chip->of_xlate = of_isc_pwm_xlate; info->force_on = force_on; - err = pwmchip_add(&info->chip); + err = pwmchip_add(chip); if (err < 0) { dev_err(&pdev->dev, "pwmchip_add() failed: %d\n", err); return err; } - platform_set_drvdata(pdev, info); + platform_set_drvdata(pdev, chip); info->pwm = devm_pwm_get(&pdev->dev, NULL); if (!IS_ERR(info->pwm)) { pwm_disable(info->pwm); dev_info(&pdev->dev, "%s success to get PWM\n", __func__); } else { - pwmchip_remove(&info->chip); + pwmchip_remove(chip); err = PTR_ERR(info->pwm); if (err != -EPROBE_DEFER) dev_err(&pdev->dev, @@ -195,24 +214,24 @@ static int isc_pwm_probe(struct platform_device *pdev) static int isc_pwm_remove(struct platform_device *pdev) { - struct isc_pwm_info *info = platform_get_drvdata(pdev); + struct pwm_chip *chip = platform_get_drvdata(pdev); - pwmchip_remove(&info->chip); + pwmchip_remove(chip); return 0; } static int isc_pwm_suspend(struct device *dev) { - int err = 0; - struct isc_pwm_info *info = dev_get_drvdata(dev); + struct pwm_chip *chip = dev_get_drvdata(dev); + struct isc_pwm_info *info = to_isc_pwm_info(chip); if (info == NULL) { dev_err(dev, "%s: fail to get info\n", __func__); } else { if (!IS_ERR(info->pwm)) { pwm_disable(info->pwm); - err = pwm_config(info->pwm, PWM_SUSPEND_DUTY_RATIO, + pwm_config(info->pwm, PWM_SUSPEND_DUTY_RATIO, PWM_SUSPEND_PERIOD); } }