lists.linaro.org
Sign In
Sign Up
Sign In
Sign Up
Manage this list
×
Keyboard Shortcuts
Thread View
j
: Next unread message
k
: Previous unread message
j a
: Jump to all threads
j l
: Jump to MailingList overview
2026
October
September
August
July
June
May
April
March
February
January
2025
December
November
October
September
August
July
June
May
April
March
February
January
2024
December
November
October
September
August
July
June
May
April
March
February
January
2023
December
November
October
September
August
July
June
May
April
March
February
January
2022
December
November
October
September
August
July
June
May
April
March
February
January
2021
December
November
October
September
August
July
June
May
April
March
February
January
2020
December
November
October
September
August
July
June
May
April
March
February
January
2019
December
November
October
September
August
July
June
May
April
March
February
January
2018
December
November
October
September
August
July
June
May
April
March
February
January
2017
December
November
October
September
August
July
June
May
April
March
February
January
2016
December
November
List overview
Download
greybus-dev
October 2026
----- 2026 -----
October 2026
September 2026
August 2026
July 2026
June 2026
May 2026
April 2026
March 2026
February 2026
January 2026
----- 2025 -----
December 2025
November 2025
October 2025
September 2025
August 2025
July 2025
June 2025
May 2025
April 2025
March 2025
February 2025
January 2025
----- 2024 -----
December 2024
November 2024
October 2024
September 2024
August 2024
July 2024
June 2024
May 2024
April 2024
March 2024
February 2024
January 2024
----- 2023 -----
December 2023
November 2023
October 2023
September 2023
August 2023
July 2023
June 2023
May 2023
April 2023
March 2023
February 2023
January 2023
----- 2022 -----
December 2022
November 2022
October 2022
September 2022
August 2022
July 2022
June 2022
May 2022
April 2022
March 2022
February 2022
January 2022
----- 2021 -----
December 2021
November 2021
October 2021
September 2021
August 2021
July 2021
June 2021
May 2021
April 2021
March 2021
February 2021
January 2021
----- 2020 -----
December 2020
November 2020
October 2020
September 2020
August 2020
July 2020
June 2020
May 2020
April 2020
March 2020
February 2020
January 2020
----- 2019 -----
December 2019
November 2019
October 2019
September 2019
August 2019
July 2019
June 2019
May 2019
April 2019
March 2019
February 2019
January 2019
----- 2018 -----
December 2018
November 2018
October 2018
September 2018
August 2018
July 2018
June 2018
May 2018
April 2018
March 2018
February 2018
January 2018
----- 2017 -----
December 2017
November 2017
October 2017
September 2017
August 2017
July 2017
June 2017
May 2017
April 2017
March 2017
February 2017
January 2017
----- 2016 -----
December 2016
November 2016
greybus-dev@lists.linaro.org
28 participants
38 discussions
Start a n
N
ew thread
[PATCH] staging: greybus: bootrom: fix null pointer dereference in get_firmware
by Marinela Tatiana Selseth
Automated static analysis via Coccinelle uncovered a potential null pointer dereference and uninitialized stack pointer vulnerability inside gb_bootrom_get_firmware(). The routine evaluates whether a firmware transmission sequence is complete at its trailing 'queue_work:' label by checking if the transfer bounds match 'fw->size'. When this label is reached the 'fw' can be uninitialized or NULL. Both scenarios expose the kernel to critical memory faults or null pointer panics. Fix these dual vulnerability paths by initializing the 'fw' pointer to NULL at its top-level definition block and introducing an explicit short-circuit guard condition to safely gate the trailing size evaluation. Assisted-by: Gemini Signed-off-by: Marinela Tatiana Selseth <marinela.selseth(a)firmwaredesign.org> --- drivers/staging/greybus/bootrom.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/greybus/bootrom.c b/drivers/staging/greybus/bootrom.c index 83921d90c322..cead4b505f6c 100644 --- a/drivers/staging/greybus/bootrom.c +++ b/drivers/staging/greybus/bootrom.c @@ -241,7 +241,7 @@ static int gb_bootrom_firmware_size_request(struct gb_operation *op) static int gb_bootrom_get_firmware(struct gb_operation *op) { struct gb_bootrom *bootrom = gb_connection_get_data(op->connection); - const struct firmware *fw; + const struct firmware *fw = NULL; struct gb_bootrom_get_firmware_request *firmware_request; struct device *dev = &op->connection->bundle->dev; unsigned int offset, size; @@ -298,7 +298,7 @@ static int gb_bootrom_get_firmware(struct gb_operation *op) queue_work: /* Refresh timeout */ - if (!ret && (offset + size == fw->size)) + if (fw && !ret && (offset + size == fw->size)) next_request = NEXT_REQ_READY_TO_BOOT; else next_request = NEXT_REQ_GET_FIRMWARE; -- 2.43.0
2 weeks, 2 days
2
1
0
0
[PATCH] staging: greybus: audio: Fix no terminating newline in sysfs emit
by Raiden Horner
Terminating newlines added to adhere kernel coding standards and reduce noise when debugging with checkpatch. Reported by checkpatch: WARNING: SYSFS_EMIT: return sysfs_emit(...) formats should include a terminating newline Signed-off-by: Raiden Horner <raidenhornerdev(a)gmail.com> --- drivers/staging/greybus/audio_manager_module.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/staging/greybus/audio_manager_module.c b/drivers/staging/greybus/audio_manager_module.c index dc90cc2d2308..98b12b77aa9f 100644 --- a/drivers/staging/greybus/audio_manager_module.c +++ b/drivers/staging/greybus/audio_manager_module.c @@ -75,7 +75,7 @@ static void gb_audio_module_release(struct kobject *kobj) static ssize_t gb_audio_module_name_show(struct gb_audio_manager_module *module, struct gb_audio_manager_module_attribute *attr, char *buf) { - return sysfs_emit(buf, "%s", module->desc.name); + return sysfs_emit(buf, "%s\n", module->desc.name); } static struct gb_audio_manager_module_attribute gb_audio_module_name_attribute = @@ -84,7 +84,7 @@ static struct gb_audio_manager_module_attribute gb_audio_module_name_attribute = static ssize_t gb_audio_module_vid_show(struct gb_audio_manager_module *module, struct gb_audio_manager_module_attribute *attr, char *buf) { - return sysfs_emit(buf, "%d", module->desc.vid); + return sysfs_emit(buf, "%d\n", module->desc.vid); } static struct gb_audio_manager_module_attribute gb_audio_module_vid_attribute = @@ -93,7 +93,7 @@ static struct gb_audio_manager_module_attribute gb_audio_module_vid_attribute = static ssize_t gb_audio_module_pid_show(struct gb_audio_manager_module *module, struct gb_audio_manager_module_attribute *attr, char *buf) { - return sysfs_emit(buf, "%d", module->desc.pid); + return sysfs_emit(buf, "%d\n", module->desc.pid); } static struct gb_audio_manager_module_attribute gb_audio_module_pid_attribute = @@ -103,7 +103,7 @@ static ssize_t gb_audio_module_intf_id_show(struct gb_audio_manager_module *modu struct gb_audio_manager_module_attribute *attr, char *buf) { - return sysfs_emit(buf, "%d", module->desc.intf_id); + return sysfs_emit(buf, "%d\n", module->desc.intf_id); } static struct gb_audio_manager_module_attribute @@ -114,7 +114,7 @@ static ssize_t gb_audio_module_ip_devices_show(struct gb_audio_manager_module *m struct gb_audio_manager_module_attribute *attr, char *buf) { - return sysfs_emit(buf, "0x%X", module->desc.ip_devices); + return sysfs_emit(buf, "0x%X\n", module->desc.ip_devices); } static struct gb_audio_manager_module_attribute @@ -125,7 +125,7 @@ static ssize_t gb_audio_module_op_devices_show(struct gb_audio_manager_module *m struct gb_audio_manager_module_attribute *attr, char *buf) { - return sysfs_emit(buf, "0x%X", module->desc.op_devices); + return sysfs_emit(buf, "0x%X\n", module->desc.op_devices); } static struct gb_audio_manager_module_attribute @@ -158,7 +158,7 @@ static void send_add_uevent(struct gb_audio_manager_module *module) char ip_devices_string[64]; char op_devices_string[64]; - char *envp[] = { + char * const envp[] = { name_string, vid_string, pid_string, -- 2.47.3
2 weeks, 5 days
2
1
0
0
[PATCH v2] staging: greybus: remove driver depending on nonexistent config option
by Ethan Nelson-Moore
The Greybus Arche Platform driver depends on the config options USB_HSIC_USB3613 or COMPILE_TEST. USB_HSIC_USB3613 has never existed in mainline Linux, and COMPILE_TEST is intended to enable the compilation of drivers on platforms that can't support them to improve code coverage and ease testing of trivial or tree-wide changes. Therefore, it is impossible for anyone to be using this driver with unmodified mainline kernels. Remove it and move the former maintainer to the CREDITS file. Signed-off-by: Ethan Nelson-Moore <enelsonmoore(a)gmail.com> --- Changes in v2: Clarify commit message - mention COMPILE_TEST CREDITS | 4 + MAINTAINERS | 7 - drivers/staging/greybus/Kconfig | 9 - drivers/staging/greybus/Makefile | 6 - drivers/staging/greybus/arche-apb-ctrl.c | 490 ----------------- drivers/staging/greybus/arche-platform.c | 653 ----------------------- drivers/staging/greybus/arche_platform.h | 28 - 7 files changed, 4 insertions(+), 1193 deletions(-) delete mode 100644 drivers/staging/greybus/arche-apb-ctrl.c delete mode 100644 drivers/staging/greybus/arche-platform.c delete mode 100644 drivers/staging/greybus/arche_platform.h diff --git a/CREDITS b/CREDITS index a0bd941ca5dd..9f74318ac0da 100644 --- a/CREDITS +++ b/CREDITS @@ -1717,6 +1717,10 @@ S: Talstr. 1 S: D - 72072 Tuebingen S: Germany +N: Vaibhav Hiremath +E: hvaibhav.linux(a)gmail.com +D: Greybus Arche Platform driver + N: Richard Hirst E: richard(a)sleepie.demon.co.uk E: rhirst(a)linuxcare.com diff --git a/MAINTAINERS b/MAINTAINERS index c2414447892c..ade7c36f9318 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -11315,13 +11315,6 @@ M: Bryan O'Donoghue <pure.logic(a)nexus-software.ie> S: Maintained F: drivers/staging/greybus/loopback.c -GREYBUS PLATFORM DRIVERS -M: Vaibhav Hiremath <hvaibhav.linux(a)gmail.com> -S: Maintained -F: drivers/staging/greybus/arche-apb-ctrl.c -F: drivers/staging/greybus/arche-platform.c -F: drivers/staging/greybus/arche_platform.h - GREYBUS SDIO/GPIO/SPI PROTOCOLS DRIVERS M: Rui Miguel Silva <rmfrfs(a)gmail.com> S: Maintained diff --git a/drivers/staging/greybus/Kconfig b/drivers/staging/greybus/Kconfig index 7635f3e850fa..c25da61570eb 100644 --- a/drivers/staging/greybus/Kconfig +++ b/drivers/staging/greybus/Kconfig @@ -204,13 +204,4 @@ config GREYBUS_USB endif # GREYBUS_BRIDGED_PHY -config GREYBUS_ARCHE - tristate "Greybus Arche Platform driver" - depends on USB_HSIC_USB3613 || COMPILE_TEST - help - Select this option if you have an Arche device. - - To compile this code as a module, chose M here: the module - will be called gb-arche.ko - endif # GREYBUS diff --git a/drivers/staging/greybus/Makefile b/drivers/staging/greybus/Makefile index 7c5e89622334..7b9807f8a1a3 100644 --- a/drivers/staging/greybus/Makefile +++ b/drivers/staging/greybus/Makefile @@ -65,9 +65,3 @@ obj-$(CONFIG_GREYBUS_SDIO) += gb-sdio.o obj-$(CONFIG_GREYBUS_SPI) += gb-spi.o gb-spilib.o obj-$(CONFIG_GREYBUS_UART) += gb-uart.o obj-$(CONFIG_GREYBUS_USB) += gb-usb.o - - -# Greybus Platform driver -gb-arche-y := arche-platform.o arche-apb-ctrl.o - -obj-$(CONFIG_GREYBUS_ARCHE) += gb-arche.o diff --git a/drivers/staging/greybus/arche-apb-ctrl.c b/drivers/staging/greybus/arche-apb-ctrl.c deleted file mode 100644 index 4302c2226126..000000000000 --- a/drivers/staging/greybus/arche-apb-ctrl.c +++ /dev/null @@ -1,490 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Arche Platform driver to control APB. - * - * Copyright 2014-2015 Google Inc. - * Copyright 2014-2015 Linaro Ltd. - */ - -#include <linux/clk.h> -#include <linux/delay.h> -#include <linux/gpio/consumer.h> -#include <linux/interrupt.h> -#include <linux/module.h> -#include <linux/pinctrl/consumer.h> -#include <linux/platform_device.h> -#include <linux/pm.h> -#include <linux/property.h> -#include <linux/regulator/consumer.h> -#include <linux/spinlock.h> -#include "arche_platform.h" - -static void apb_bootret_deassert(struct device *dev); - -struct arche_apb_ctrl_drvdata { - /* Control GPIO signals to and from AP <=> AP Bridges */ - struct gpio_desc *resetn; - struct gpio_desc *boot_ret; - struct gpio_desc *pwroff; - struct gpio_desc *wake_in; - struct gpio_desc *wake_out; - struct gpio_desc *pwrdn; - - enum arche_platform_state state; - bool init_disabled; - - struct regulator *vcore; - struct regulator *vio; - - struct gpio_desc *clk_en; - struct clk *clk; - - struct pinctrl *pinctrl; - struct pinctrl_state *pin_default; - - /* V2: SPI Bus control */ - struct gpio_desc *spi_en; - bool spi_en_polarity_high; -}; - -/* - * Note that these low level api's are active high - */ -static inline void deassert_reset(struct gpio_desc *gpio) -{ - gpiod_set_raw_value(gpio, 1); -} - -static inline void assert_reset(struct gpio_desc *gpio) -{ - gpiod_set_raw_value(gpio, 0); -} - -/* - * Note: Please do not modify the below sequence, as it is as per the spec - */ -static int coldboot_seq(struct platform_device *pdev) -{ - struct device *dev = &pdev->dev; - struct arche_apb_ctrl_drvdata *apb = platform_get_drvdata(pdev); - int ret; - - if (apb->init_disabled || - apb->state == ARCHE_PLATFORM_STATE_ACTIVE) - return 0; - - /* Hold APB in reset state */ - assert_reset(apb->resetn); - - if (apb->state == ARCHE_PLATFORM_STATE_FW_FLASHING && apb->spi_en) - devm_gpiod_put(dev, apb->spi_en); - - /* Enable power to APB */ - if (!IS_ERR(apb->vcore)) { - ret = regulator_enable(apb->vcore); - if (ret) { - dev_err(dev, "failed to enable core regulator\n"); - return ret; - } - } - - if (!IS_ERR(apb->vio)) { - ret = regulator_enable(apb->vio); - if (ret) { - dev_err(dev, "failed to enable IO regulator\n"); - return ret; - } - } - - apb_bootret_deassert(dev); - - /* On DB3 clock was not mandatory */ - if (apb->clk_en) - gpiod_set_value(apb->clk_en, 1); - - usleep_range(100, 200); - - /* deassert reset to APB : Active-low signal */ - deassert_reset(apb->resetn); - - apb->state = ARCHE_PLATFORM_STATE_ACTIVE; - - return 0; -} - -static int fw_flashing_seq(struct platform_device *pdev) -{ - struct device *dev = &pdev->dev; - struct arche_apb_ctrl_drvdata *apb = platform_get_drvdata(pdev); - int ret; - - if (apb->init_disabled || - apb->state == ARCHE_PLATFORM_STATE_FW_FLASHING) - return 0; - - ret = regulator_enable(apb->vcore); - if (ret) { - dev_err(dev, "failed to enable core regulator\n"); - return ret; - } - - ret = regulator_enable(apb->vio); - if (ret) { - dev_err(dev, "failed to enable IO regulator\n"); - return ret; - } - - if (apb->spi_en) { - unsigned long flags; - - if (apb->spi_en_polarity_high) - flags = GPIOD_OUT_HIGH; - else - flags = GPIOD_OUT_LOW; - - apb->spi_en = devm_gpiod_get(dev, "spi-en", flags); - if (IS_ERR(apb->spi_en)) { - ret = PTR_ERR(apb->spi_en); - dev_err(dev, "Failed requesting SPI bus en GPIO: %d\n", - ret); - return ret; - } - } - - /* for flashing device should be in reset state */ - assert_reset(apb->resetn); - apb->state = ARCHE_PLATFORM_STATE_FW_FLASHING; - - return 0; -} - -static int standby_boot_seq(struct platform_device *pdev) -{ - struct device *dev = &pdev->dev; - struct arche_apb_ctrl_drvdata *apb = platform_get_drvdata(pdev); - - if (apb->init_disabled) - return 0; - - /* - * Even if it is in OFF state, - * then we do not want to change the state - */ - if (apb->state == ARCHE_PLATFORM_STATE_STANDBY || - apb->state == ARCHE_PLATFORM_STATE_OFF) - return 0; - - if (apb->state == ARCHE_PLATFORM_STATE_FW_FLASHING && apb->spi_en) - devm_gpiod_put(dev, apb->spi_en); - - /* - * As per WDM spec, do nothing - * - * Pasted from WDM spec, - * - A falling edge on POWEROFF_L is detected (a) - * - WDM enters standby mode, but no output signals are changed - */ - - /* TODO: POWEROFF_L is input to WDM module */ - apb->state = ARCHE_PLATFORM_STATE_STANDBY; - return 0; -} - -static void poweroff_seq(struct platform_device *pdev) -{ - struct device *dev = &pdev->dev; - struct arche_apb_ctrl_drvdata *apb = platform_get_drvdata(pdev); - - if (apb->init_disabled || apb->state == ARCHE_PLATFORM_STATE_OFF) - return; - - if (apb->state == ARCHE_PLATFORM_STATE_FW_FLASHING && apb->spi_en) - devm_gpiod_put(dev, apb->spi_en); - - /* disable the clock */ - if (apb->clk_en) - gpiod_set_value(apb->clk_en, 0); - - if (!IS_ERR(apb->vcore) && regulator_is_enabled(apb->vcore) > 0) - regulator_disable(apb->vcore); - - if (!IS_ERR(apb->vio) && regulator_is_enabled(apb->vio) > 0) - regulator_disable(apb->vio); - - /* As part of exit, put APB back in reset state */ - assert_reset(apb->resetn); - apb->state = ARCHE_PLATFORM_STATE_OFF; - - /* TODO: May have to send an event to SVC about this exit */ -} - -static void apb_bootret_deassert(struct device *dev) -{ - struct arche_apb_ctrl_drvdata *apb = dev_get_drvdata(dev); - - gpiod_set_value(apb->boot_ret, 0); -} - -int apb_ctrl_coldboot(struct device *dev) -{ - return coldboot_seq(to_platform_device(dev)); -} - -int apb_ctrl_fw_flashing(struct device *dev) -{ - return fw_flashing_seq(to_platform_device(dev)); -} - -int apb_ctrl_standby_boot(struct device *dev) -{ - return standby_boot_seq(to_platform_device(dev)); -} - -void apb_ctrl_poweroff(struct device *dev) -{ - poweroff_seq(to_platform_device(dev)); -} - -static ssize_t state_store(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) -{ - struct platform_device *pdev = to_platform_device(dev); - struct arche_apb_ctrl_drvdata *apb = platform_get_drvdata(pdev); - int ret = 0; - bool is_disabled; - - if (sysfs_streq(buf, "off")) { - if (apb->state == ARCHE_PLATFORM_STATE_OFF) - return count; - - poweroff_seq(pdev); - } else if (sysfs_streq(buf, "active")) { - if (apb->state == ARCHE_PLATFORM_STATE_ACTIVE) - return count; - - poweroff_seq(pdev); - is_disabled = apb->init_disabled; - apb->init_disabled = false; - ret = coldboot_seq(pdev); - if (ret) - apb->init_disabled = is_disabled; - } else if (sysfs_streq(buf, "standby")) { - if (apb->state == ARCHE_PLATFORM_STATE_STANDBY) - return count; - - ret = standby_boot_seq(pdev); - } else if (sysfs_streq(buf, "fw_flashing")) { - if (apb->state == ARCHE_PLATFORM_STATE_FW_FLASHING) - return count; - - /* - * First we want to make sure we power off everything - * and then enter FW flashing state - */ - poweroff_seq(pdev); - ret = fw_flashing_seq(pdev); - } else { - dev_err(dev, "unknown state\n"); - ret = -EINVAL; - } - - return ret ? ret : count; -} - -static ssize_t state_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct arche_apb_ctrl_drvdata *apb = dev_get_drvdata(dev); - - switch (apb->state) { - case ARCHE_PLATFORM_STATE_OFF: - return sysfs_emit(buf, "off%s\n", - apb->init_disabled ? ",disabled" : ""); - case ARCHE_PLATFORM_STATE_ACTIVE: - return sysfs_emit(buf, "active\n"); - case ARCHE_PLATFORM_STATE_STANDBY: - return sysfs_emit(buf, "standby\n"); - case ARCHE_PLATFORM_STATE_FW_FLASHING: - return sysfs_emit(buf, "fw_flashing\n"); - default: - return sysfs_emit(buf, "unknown state\n"); - } -} - -static DEVICE_ATTR_RW(state); - -static int apb_ctrl_get_fw_data(struct platform_device *pdev, - struct arche_apb_ctrl_drvdata *apb) -{ - struct device *dev = &pdev->dev; - int ret; - - apb->resetn = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW); - if (IS_ERR(apb->resetn)) { - ret = PTR_ERR(apb->resetn); - dev_err(dev, "Failed requesting reset GPIO: %d\n", ret); - return ret; - } - - apb->boot_ret = devm_gpiod_get(dev, "boot-ret", GPIOD_OUT_LOW); - if (IS_ERR(apb->boot_ret)) { - ret = PTR_ERR(apb->boot_ret); - dev_err(dev, "Failed requesting bootret GPIO: %d\n", ret); - return ret; - } - - /* It's not mandatory to support power management interface */ - apb->pwroff = devm_gpiod_get_optional(dev, "pwr-off", GPIOD_IN); - if (IS_ERR(apb->pwroff)) { - ret = PTR_ERR(apb->pwroff); - dev_err(dev, "Failed requesting pwroff_n GPIO: %d\n", ret); - return ret; - } - - /* Do not make clock mandatory as of now (for DB3) */ - apb->clk_en = devm_gpiod_get_optional(dev, "clock-en", GPIOD_OUT_LOW); - if (IS_ERR(apb->clk_en)) { - ret = PTR_ERR(apb->clk_en); - dev_err(dev, "Failed requesting APB clock en GPIO: %d\n", ret); - return ret; - } - - apb->pwrdn = devm_gpiod_get(dev, "pwr-down", GPIOD_OUT_LOW); - if (IS_ERR(apb->pwrdn)) { - ret = PTR_ERR(apb->pwrdn); - dev_warn(dev, "Failed requesting power down GPIO: %d\n", ret); - return ret; - } - - /* Regulators are optional, as we may have fixed supply coming in */ - apb->vcore = devm_regulator_get(dev, "vcore"); - if (IS_ERR(apb->vcore)) - dev_warn(dev, "no core regulator found\n"); - - apb->vio = devm_regulator_get(dev, "vio"); - if (IS_ERR(apb->vio)) - dev_warn(dev, "no IO regulator found\n"); - - apb->pinctrl = devm_pinctrl_get(&pdev->dev); - if (IS_ERR(apb->pinctrl)) { - dev_err(&pdev->dev, "could not get pinctrl handle\n"); - return PTR_ERR(apb->pinctrl); - } - apb->pin_default = pinctrl_lookup_state(apb->pinctrl, "default"); - if (IS_ERR(apb->pin_default)) { - dev_err(&pdev->dev, "could not get default pin state\n"); - return PTR_ERR(apb->pin_default); - } - - /* Only applicable for platform >= V2 */ - if (device_property_read_bool(&pdev->dev, "gb,spi-en-active-high")) - apb->spi_en_polarity_high = true; - - return 0; -} - -static int arche_apb_ctrl_probe(struct platform_device *pdev) -{ - int ret; - struct arche_apb_ctrl_drvdata *apb; - struct device *dev = &pdev->dev; - - apb = devm_kzalloc(&pdev->dev, sizeof(*apb), GFP_KERNEL); - if (!apb) - return -ENOMEM; - - ret = apb_ctrl_get_fw_data(pdev, apb); - if (ret) { - dev_err(dev, "failed to get apb devicetree data %d\n", ret); - return ret; - } - - /* Initially set APB to OFF state */ - apb->state = ARCHE_PLATFORM_STATE_OFF; - /* Check whether device needs to be enabled on boot */ - if (device_property_read_bool(&pdev->dev, "arche,init-disable")) - apb->init_disabled = true; - - platform_set_drvdata(pdev, apb); - - /* Create sysfs interface to allow user to change state dynamically */ - ret = device_create_file(dev, &dev_attr_state); - if (ret) { - dev_err(dev, "failed to create state file in sysfs\n"); - return ret; - } - - dev_info(&pdev->dev, "Device registered successfully\n"); - return 0; -} - -static void arche_apb_ctrl_remove(struct platform_device *pdev) -{ - device_remove_file(&pdev->dev, &dev_attr_state); - poweroff_seq(pdev); - platform_set_drvdata(pdev, NULL); -} - -static int __maybe_unused arche_apb_ctrl_suspend(struct device *dev) -{ - /* - * If timing profile permits, we may shutdown bridge - * completely - * - * TODO: sequence ?? - * - * Also, need to make sure we meet precondition for unipro suspend - * Precondition: Definition ??? - */ - return 0; -} - -static int __maybe_unused arche_apb_ctrl_resume(struct device *dev) -{ - /* - * At least for ES2 we have to meet the delay requirement between - * unipro switch and AP bridge init, depending on whether bridge is in - * OFF state or standby state. - * - * Based on whether bridge is in standby or OFF state we may have to - * assert multiple signals. Please refer to WDM spec, for more info. - * - */ - return 0; -} - -static void arche_apb_ctrl_shutdown(struct platform_device *pdev) -{ - apb_ctrl_poweroff(&pdev->dev); -} - -static SIMPLE_DEV_PM_OPS(arche_apb_ctrl_pm_ops, arche_apb_ctrl_suspend, - arche_apb_ctrl_resume); - -static const struct of_device_id arche_apb_ctrl_of_match[] = { - { .compatible = "usbffff,2", }, - { }, -}; -MODULE_DEVICE_TABLE(of, arche_apb_ctrl_of_match); - -static struct platform_driver arche_apb_ctrl_device_driver = { - .probe = arche_apb_ctrl_probe, - .remove = arche_apb_ctrl_remove, - .shutdown = arche_apb_ctrl_shutdown, - .driver = { - .name = "arche-apb-ctrl", - .pm = &arche_apb_ctrl_pm_ops, - .of_match_table = arche_apb_ctrl_of_match, - } -}; - -int __init arche_apb_init(void) -{ - return platform_driver_register(&arche_apb_ctrl_device_driver); -} - -void __exit arche_apb_exit(void) -{ - platform_driver_unregister(&arche_apb_ctrl_device_driver); -} diff --git a/drivers/staging/greybus/arche-platform.c b/drivers/staging/greybus/arche-platform.c deleted file mode 100644 index de5de59ea8ab..000000000000 --- a/drivers/staging/greybus/arche-platform.c +++ /dev/null @@ -1,653 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Arche Platform driver to enable Unipro link. - * - * Copyright 2014-2015 Google Inc. - * Copyright 2014-2015 Linaro Ltd. - */ - -#include <linux/clk.h> -#include <linux/delay.h> -#include <linux/gpio/consumer.h> -#include <linux/init.h> -#include <linux/module.h> -#include <linux/of_platform.h> -#include <linux/pinctrl/consumer.h> -#include <linux/platform_device.h> -#include <linux/pm.h> -#include <linux/interrupt.h> -#include <linux/irq.h> -#include <linux/suspend.h> -#include <linux/time.h> -#include <linux/greybus.h> -#include <linux/of.h> -#include "arche_platform.h" - -#if IS_ENABLED(CONFIG_USB_HSIC_USB3613) -#include <linux/usb/usb3613.h> -#else -static inline int usb3613_hub_mode_ctrl(bool unused) -{ - return 0; -} -#endif - -#define WD_COLDBOOT_PULSE_WIDTH_MS 30 - -enum svc_wakedetect_state { - WD_STATE_IDLE, /* Default state = pulled high/low */ - WD_STATE_BOOT_INIT, /* WD = falling edge (low) */ - WD_STATE_COLDBOOT_TRIG, /* WD = rising edge (high), > 30msec */ - WD_STATE_STANDBYBOOT_TRIG, /* As of now not used ?? */ - WD_STATE_COLDBOOT_START, /* Cold boot process started */ - WD_STATE_STANDBYBOOT_START, /* Not used */ -}; - -struct arche_platform_drvdata { - /* Control GPIO signals to and from AP <=> SVC */ - struct gpio_desc *svc_reset; - bool is_reset_act_hi; - struct gpio_desc *svc_sysboot; - struct gpio_desc *wake_detect; /* bi-dir,maps to WAKE_MOD & WAKE_FRAME signals */ - - enum arche_platform_state state; - - struct gpio_desc *svc_refclk_req; - struct clk *svc_ref_clk; - - struct pinctrl *pinctrl; - struct pinctrl_state *pin_default; - - int num_apbs; - - enum svc_wakedetect_state wake_detect_state; - int wake_detect_irq; - spinlock_t wake_lock; /* Protect wake_detect_state */ - struct mutex platform_state_mutex; /* Protect state */ - unsigned long wake_detect_start; - struct notifier_block pm_notifier; - - struct device *dev; -}; - -/* Requires calling context to hold arche_pdata->platform_state_mutex */ -static void arche_platform_set_state(struct arche_platform_drvdata *arche_pdata, - enum arche_platform_state state) -{ - arche_pdata->state = state; -} - -/* Requires arche_pdata->wake_lock is held by calling context */ -static void arche_platform_set_wake_detect_state(struct arche_platform_drvdata *arche_pdata, - enum svc_wakedetect_state state) -{ - arche_pdata->wake_detect_state = state; -} - -static inline void svc_reset_onoff(struct gpio_desc *gpio, bool onoff) -{ - gpiod_set_raw_value(gpio, onoff); -} - -static int apb_cold_boot(struct device *dev, void *data) -{ - int ret; - - ret = apb_ctrl_coldboot(dev); - if (ret) - dev_warn(dev, "failed to coldboot\n"); - - /*Child nodes are independent, so do not exit coldboot operation */ - return 0; -} - -static int apb_poweroff(struct device *dev, void *data) -{ - apb_ctrl_poweroff(dev); - - /* Enable HUB3613 into HUB mode. */ - if (usb3613_hub_mode_ctrl(false)) - dev_warn(dev, "failed to control hub device\n"); - - return 0; -} - -static void arche_platform_wd_irq_en(struct arche_platform_drvdata *arche_pdata) -{ - /* Enable interrupt here, to read event back from SVC */ - enable_irq(arche_pdata->wake_detect_irq); -} - -static irqreturn_t arche_platform_wd_irq_thread(int irq, void *devid) -{ - struct arche_platform_drvdata *arche_pdata = devid; - unsigned long flags; - - spin_lock_irqsave(&arche_pdata->wake_lock, flags); - if (arche_pdata->wake_detect_state != WD_STATE_COLDBOOT_TRIG) { - /* Something is wrong */ - spin_unlock_irqrestore(&arche_pdata->wake_lock, flags); - return IRQ_HANDLED; - } - - arche_platform_set_wake_detect_state(arche_pdata, - WD_STATE_COLDBOOT_START); - spin_unlock_irqrestore(&arche_pdata->wake_lock, flags); - - /* It should complete power cycle, so first make sure it is poweroff */ - device_for_each_child(arche_pdata->dev, NULL, apb_poweroff); - - /* Bring APB out of reset: cold boot sequence */ - device_for_each_child(arche_pdata->dev, NULL, apb_cold_boot); - - /* Enable HUB3613 into HUB mode. */ - if (usb3613_hub_mode_ctrl(true)) - dev_warn(arche_pdata->dev, "failed to control hub device\n"); - - spin_lock_irqsave(&arche_pdata->wake_lock, flags); - arche_platform_set_wake_detect_state(arche_pdata, WD_STATE_IDLE); - spin_unlock_irqrestore(&arche_pdata->wake_lock, flags); - - return IRQ_HANDLED; -} - -static irqreturn_t arche_platform_wd_irq(int irq, void *devid) -{ - struct arche_platform_drvdata *arche_pdata = devid; - unsigned long flags; - - spin_lock_irqsave(&arche_pdata->wake_lock, flags); - - if (gpiod_get_value(arche_pdata->wake_detect)) { - /* wake/detect rising */ - - /* - * If wake/detect line goes high after low, within less than - * 30msec, then standby boot sequence is initiated, which is not - * supported/implemented as of now. So ignore it. - */ - if (arche_pdata->wake_detect_state == WD_STATE_BOOT_INIT) { - if (time_before(jiffies, - arche_pdata->wake_detect_start + - msecs_to_jiffies(WD_COLDBOOT_PULSE_WIDTH_MS))) { - arche_platform_set_wake_detect_state(arche_pdata, - WD_STATE_IDLE); - } else { - /* - * Check we are not in middle of irq thread - * already - */ - if (arche_pdata->wake_detect_state != - WD_STATE_COLDBOOT_START) { - arche_platform_set_wake_detect_state(arche_pdata, - WD_STATE_COLDBOOT_TRIG); - spin_unlock_irqrestore(&arche_pdata->wake_lock, - flags); - return IRQ_WAKE_THREAD; - } - } - } - } else { - /* wake/detect falling */ - if (arche_pdata->wake_detect_state == WD_STATE_IDLE) { - arche_pdata->wake_detect_start = jiffies; - /* - * In the beginning, when wake/detect goes low - * (first time), we assume it is meant for coldboot - * and set the flag. If wake/detect line stays low - * beyond 30msec, then it is coldboot else fallback - * to standby boot. - */ - arche_platform_set_wake_detect_state(arche_pdata, - WD_STATE_BOOT_INIT); - } - } - - spin_unlock_irqrestore(&arche_pdata->wake_lock, flags); - - return IRQ_HANDLED; -} - -/* - * Requires arche_pdata->platform_state_mutex to be held - */ -static int -arche_platform_coldboot_seq(struct arche_platform_drvdata *arche_pdata) -{ - int ret; - - if (arche_pdata->state == ARCHE_PLATFORM_STATE_ACTIVE) - return 0; - - dev_info(arche_pdata->dev, "Booting from cold boot state\n"); - - svc_reset_onoff(arche_pdata->svc_reset, arche_pdata->is_reset_act_hi); - - gpiod_set_value(arche_pdata->svc_sysboot, 0); - usleep_range(100, 200); - - ret = clk_prepare_enable(arche_pdata->svc_ref_clk); - if (ret) { - dev_err(arche_pdata->dev, "failed to enable svc_ref_clk: %d\n", - ret); - return ret; - } - - /* bring SVC out of reset */ - svc_reset_onoff(arche_pdata->svc_reset, !arche_pdata->is_reset_act_hi); - - arche_platform_set_state(arche_pdata, ARCHE_PLATFORM_STATE_ACTIVE); - - return 0; -} - -/* - * Requires arche_pdata->platform_state_mutex to be held - */ -static int -arche_platform_fw_flashing_seq(struct arche_platform_drvdata *arche_pdata) -{ - int ret; - - if (arche_pdata->state == ARCHE_PLATFORM_STATE_FW_FLASHING) - return 0; - - dev_info(arche_pdata->dev, "Switching to FW flashing state\n"); - - svc_reset_onoff(arche_pdata->svc_reset, arche_pdata->is_reset_act_hi); - - gpiod_set_value(arche_pdata->svc_sysboot, 1); - - usleep_range(100, 200); - - ret = clk_prepare_enable(arche_pdata->svc_ref_clk); - if (ret) { - dev_err(arche_pdata->dev, "failed to enable svc_ref_clk: %d\n", - ret); - return ret; - } - - svc_reset_onoff(arche_pdata->svc_reset, !arche_pdata->is_reset_act_hi); - - arche_platform_set_state(arche_pdata, ARCHE_PLATFORM_STATE_FW_FLASHING); - - return 0; -} - -/* - * Requires arche_pdata->platform_state_mutex to be held - */ -static void -arche_platform_poweroff_seq(struct arche_platform_drvdata *arche_pdata) -{ - unsigned long flags; - - if (arche_pdata->state == ARCHE_PLATFORM_STATE_OFF) - return; - - /* If in fw_flashing mode, then no need to repeate things again */ - if (arche_pdata->state != ARCHE_PLATFORM_STATE_FW_FLASHING) { - disable_irq(arche_pdata->wake_detect_irq); - - spin_lock_irqsave(&arche_pdata->wake_lock, flags); - arche_platform_set_wake_detect_state(arche_pdata, - WD_STATE_IDLE); - spin_unlock_irqrestore(&arche_pdata->wake_lock, flags); - } - - clk_disable_unprepare(arche_pdata->svc_ref_clk); - - /* As part of exit, put APB back in reset state */ - svc_reset_onoff(arche_pdata->svc_reset, arche_pdata->is_reset_act_hi); - - arche_platform_set_state(arche_pdata, ARCHE_PLATFORM_STATE_OFF); -} - -static ssize_t state_store(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) -{ - struct arche_platform_drvdata *arche_pdata = dev_get_drvdata(dev); - int ret = 0; - - mutex_lock(&arche_pdata->platform_state_mutex); - - if (sysfs_streq(buf, "off")) { - if (arche_pdata->state == ARCHE_PLATFORM_STATE_OFF) - goto exit; - - /* If SVC goes down, bring down APB's as well */ - device_for_each_child(arche_pdata->dev, NULL, apb_poweroff); - - arche_platform_poweroff_seq(arche_pdata); - - } else if (sysfs_streq(buf, "active")) { - if (arche_pdata->state == ARCHE_PLATFORM_STATE_ACTIVE) - goto exit; - - /* First we want to make sure we power off everything - * and then activate back again - */ - device_for_each_child(arche_pdata->dev, NULL, apb_poweroff); - arche_platform_poweroff_seq(arche_pdata); - - arche_platform_wd_irq_en(arche_pdata); - ret = arche_platform_coldboot_seq(arche_pdata); - if (ret) - goto exit; - - } else if (sysfs_streq(buf, "standby")) { - if (arche_pdata->state == ARCHE_PLATFORM_STATE_STANDBY) - goto exit; - - dev_warn(arche_pdata->dev, "standby state not supported\n"); - } else if (sysfs_streq(buf, "fw_flashing")) { - if (arche_pdata->state == ARCHE_PLATFORM_STATE_FW_FLASHING) - goto exit; - - /* - * Here we only control SVC. - * - * In case of FW_FLASHING mode we do not want to control - * APBs, as in case of V2, SPI bus is shared between both - * the APBs. So let user chose which APB he wants to flash. - */ - arche_platform_poweroff_seq(arche_pdata); - - ret = arche_platform_fw_flashing_seq(arche_pdata); - if (ret) - goto exit; - } else { - dev_err(arche_pdata->dev, "unknown state\n"); - ret = -EINVAL; - } - -exit: - mutex_unlock(&arche_pdata->platform_state_mutex); - return ret ? ret : count; -} - -static ssize_t state_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct arche_platform_drvdata *arche_pdata = dev_get_drvdata(dev); - - switch (arche_pdata->state) { - case ARCHE_PLATFORM_STATE_OFF: - return sysfs_emit(buf, "off\n"); - case ARCHE_PLATFORM_STATE_ACTIVE: - return sysfs_emit(buf, "active\n"); - case ARCHE_PLATFORM_STATE_STANDBY: - return sysfs_emit(buf, "standby\n"); - case ARCHE_PLATFORM_STATE_FW_FLASHING: - return sysfs_emit(buf, "fw_flashing\n"); - default: - return sysfs_emit(buf, "unknown state\n"); - } -} - -static DEVICE_ATTR_RW(state); - -static int arche_platform_pm_notifier(struct notifier_block *notifier, - unsigned long pm_event, void *unused) -{ - struct arche_platform_drvdata *arche_pdata = - container_of(notifier, struct arche_platform_drvdata, - pm_notifier); - int ret = NOTIFY_DONE; - - mutex_lock(&arche_pdata->platform_state_mutex); - switch (pm_event) { - case PM_SUSPEND_PREPARE: - if (arche_pdata->state != ARCHE_PLATFORM_STATE_ACTIVE) { - ret = NOTIFY_STOP; - break; - } - device_for_each_child(arche_pdata->dev, NULL, apb_poweroff); - arche_platform_poweroff_seq(arche_pdata); - break; - case PM_POST_SUSPEND: - if (arche_pdata->state != ARCHE_PLATFORM_STATE_OFF) - break; - - arche_platform_wd_irq_en(arche_pdata); - arche_platform_coldboot_seq(arche_pdata); - break; - default: - break; - } - mutex_unlock(&arche_pdata->platform_state_mutex); - - return ret; -} - -static int arche_platform_probe(struct platform_device *pdev) -{ - struct arche_platform_drvdata *arche_pdata; - struct device *dev = &pdev->dev; - struct device_node *np = dev->of_node; - int ret; - unsigned int flags; - - arche_pdata = devm_kzalloc(&pdev->dev, sizeof(*arche_pdata), - GFP_KERNEL); - if (!arche_pdata) - return -ENOMEM; - - /* setup svc reset gpio */ - arche_pdata->is_reset_act_hi = of_property_read_bool(np, - "svc,reset-active-high"); - if (arche_pdata->is_reset_act_hi) - flags = GPIOD_OUT_HIGH; - else - flags = GPIOD_OUT_LOW; - - arche_pdata->svc_reset = devm_gpiod_get(dev, "svc,reset", flags); - if (IS_ERR(arche_pdata->svc_reset)) { - ret = PTR_ERR(arche_pdata->svc_reset); - dev_err(dev, "failed to request svc-reset GPIO: %d\n", ret); - return ret; - } - arche_platform_set_state(arche_pdata, ARCHE_PLATFORM_STATE_OFF); - - arche_pdata->svc_sysboot = devm_gpiod_get(dev, "svc,sysboot", - GPIOD_OUT_LOW); - if (IS_ERR(arche_pdata->svc_sysboot)) { - ret = PTR_ERR(arche_pdata->svc_sysboot); - dev_err(dev, "failed to request sysboot0 GPIO: %d\n", ret); - return ret; - } - - /* setup the clock request gpio first */ - arche_pdata->svc_refclk_req = devm_gpiod_get(dev, "svc,refclk-req", - GPIOD_IN); - if (IS_ERR(arche_pdata->svc_refclk_req)) { - ret = PTR_ERR(arche_pdata->svc_refclk_req); - dev_err(dev, "failed to request svc-clk-req GPIO: %d\n", ret); - return ret; - } - - /* setup refclk2 to follow the pin */ - arche_pdata->svc_ref_clk = devm_clk_get(dev, "svc_ref_clk"); - if (IS_ERR(arche_pdata->svc_ref_clk)) { - ret = PTR_ERR(arche_pdata->svc_ref_clk); - dev_err(dev, "failed to get svc_ref_clk: %d\n", ret); - return ret; - } - - platform_set_drvdata(pdev, arche_pdata); - - arche_pdata->num_apbs = of_get_child_count(np); - dev_dbg(dev, "Number of APB's available - %d\n", arche_pdata->num_apbs); - - arche_pdata->wake_detect = devm_gpiod_get(dev, "svc,wake-detect", - GPIOD_IN); - if (IS_ERR(arche_pdata->wake_detect)) { - ret = PTR_ERR(arche_pdata->wake_detect); - dev_err(dev, "Failed requesting wake_detect GPIO: %d\n", ret); - return ret; - } - - arche_platform_set_wake_detect_state(arche_pdata, WD_STATE_IDLE); - - arche_pdata->dev = &pdev->dev; - - spin_lock_init(&arche_pdata->wake_lock); - mutex_init(&arche_pdata->platform_state_mutex); - arche_pdata->wake_detect_irq = - gpiod_to_irq(arche_pdata->wake_detect); - - ret = devm_request_threaded_irq(dev, arche_pdata->wake_detect_irq, - arche_platform_wd_irq, - arche_platform_wd_irq_thread, - IRQF_TRIGGER_FALLING | - IRQF_TRIGGER_RISING | IRQF_ONESHOT, - dev_name(dev), arche_pdata); - if (ret) { - dev_err(dev, "failed to request wake detect IRQ %d\n", ret); - return ret; - } - disable_irq(arche_pdata->wake_detect_irq); - - ret = device_create_file(dev, &dev_attr_state); - if (ret) { - dev_err(dev, "failed to create state file in sysfs\n"); - return ret; - } - - ret = of_platform_populate(np, NULL, NULL, dev); - if (ret) { - dev_err(dev, "failed to populate child nodes %d\n", ret); - goto err_device_remove; - } - - arche_pdata->pm_notifier.notifier_call = arche_platform_pm_notifier; - ret = register_pm_notifier(&arche_pdata->pm_notifier); - if (ret) { - dev_err(dev, "failed to register pm notifier %d\n", ret); - goto err_depopulate; - } - - /* Explicitly power off if requested */ - if (!of_property_read_bool(pdev->dev.of_node, "arche,init-off")) { - mutex_lock(&arche_pdata->platform_state_mutex); - ret = arche_platform_coldboot_seq(arche_pdata); - if (ret) { - mutex_unlock(&arche_pdata->platform_state_mutex); - dev_err(dev, "Failed to cold boot svc %d\n", ret); - goto err_unregister_pm_notifier; - } - arche_platform_wd_irq_en(arche_pdata); - mutex_unlock(&arche_pdata->platform_state_mutex); - } - - dev_info(dev, "Device registered successfully\n"); - return 0; - -err_unregister_pm_notifier: - unregister_pm_notifier(&arche_pdata->pm_notifier); -err_depopulate: - of_platform_depopulate(dev); -err_device_remove: - device_remove_file(&pdev->dev, &dev_attr_state); - return ret; -} - -static void arche_platform_remove(struct platform_device *pdev) -{ - struct arche_platform_drvdata *arche_pdata = platform_get_drvdata(pdev); - - unregister_pm_notifier(&arche_pdata->pm_notifier); - device_remove_file(&pdev->dev, &dev_attr_state); - of_platform_depopulate(&pdev->dev); - arche_platform_poweroff_seq(arche_pdata); - - if (usb3613_hub_mode_ctrl(false)) - dev_warn(arche_pdata->dev, "failed to control hub device\n"); -} - -static __maybe_unused int arche_platform_suspend(struct device *dev) -{ - /* - * If timing profile permits, we may shutdown bridge - * completely - * - * TODO: define shutdown sequence - * - * Also, need to make sure we meet precondition for unipro suspend - * Precondition: Definition ??? - */ - return 0; -} - -static __maybe_unused int arche_platform_resume(struct device *dev) -{ - /* - * At least for ES2 we have to meet the delay requirement between - * unipro switch and AP bridge init, depending on whether bridge is in - * OFF state or standby state. - * - * Based on whether bridge is in standby or OFF state we may have to - * assert multiple signals. Please refer to WDM spec, for more info. - * - */ - return 0; -} - -static void arche_platform_shutdown(struct platform_device *pdev) -{ - struct arche_platform_drvdata *arche_pdata = platform_get_drvdata(pdev); - - arche_platform_poweroff_seq(arche_pdata); - - usb3613_hub_mode_ctrl(false); -} - -static SIMPLE_DEV_PM_OPS(arche_platform_pm_ops, - arche_platform_suspend, - arche_platform_resume); - -static const struct of_device_id arche_platform_of_match[] = { - /* Use PID/VID of SVC device */ - { .compatible = "google,arche-platform", }, - { }, -}; -MODULE_DEVICE_TABLE(of, arche_platform_of_match); - -static struct platform_driver arche_platform_device_driver = { - .probe = arche_platform_probe, - .remove = arche_platform_remove, - .shutdown = arche_platform_shutdown, - .driver = { - .name = "arche-platform-ctrl", - .pm = &arche_platform_pm_ops, - .of_match_table = arche_platform_of_match, - } -}; - -static int __init arche_init(void) -{ - int retval; - - retval = platform_driver_register(&arche_platform_device_driver); - if (retval) - return retval; - - retval = arche_apb_init(); - if (retval) - platform_driver_unregister(&arche_platform_device_driver); - - return retval; -} -module_init(arche_init); - -static void __exit arche_exit(void) -{ - arche_apb_exit(); - platform_driver_unregister(&arche_platform_device_driver); -} -module_exit(arche_exit); - -MODULE_LICENSE("GPL v2"); -MODULE_AUTHOR("Vaibhav Hiremath <vaibhav.hiremath(a)linaro.org>"); -MODULE_DESCRIPTION("Arche Platform Driver"); diff --git a/drivers/staging/greybus/arche_platform.h b/drivers/staging/greybus/arche_platform.h deleted file mode 100644 index 9d997f2d6517..000000000000 --- a/drivers/staging/greybus/arche_platform.h +++ /dev/null @@ -1,28 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * Arche Platform driver to enable Unipro link. - * - * Copyright 2015-2016 Google Inc. - * Copyright 2015-2016 Linaro Ltd. - */ - -#ifndef __ARCHE_PLATFORM_H -#define __ARCHE_PLATFORM_H - -enum arche_platform_state { - ARCHE_PLATFORM_STATE_OFF, - ARCHE_PLATFORM_STATE_ACTIVE, - ARCHE_PLATFORM_STATE_STANDBY, - ARCHE_PLATFORM_STATE_FW_FLASHING, -}; - -int __init arche_apb_init(void); -void __exit arche_apb_exit(void); - -/* Operational states for the APB device */ -int apb_ctrl_coldboot(struct device *dev); -int apb_ctrl_fw_flashing(struct device *dev); -int apb_ctrl_standby_boot(struct device *dev); -void apb_ctrl_poweroff(struct device *dev); - -#endif /* __ARCHE_PLATFORM_H */ -- 2.43.0
2 weeks, 5 days
3
2
0
0
[PATCH] staging: greybus: remove camera driver marked as broken since 2016
by Ethan Nelson-Moore
The Greybus camera driver has been marked as BROKEN since commit d4f56b47a8fa ("staging: greybus: Add drivers/staging/greybus to the build"). It has not been able to compile since at least commit ec0ad868173d ("staging: greybus: move core include files to include/linux/greybus/") because it includes greybus_protocols.h from its own directory. These two facts make it very clear there is no demand for this driver. Remove it from the kernel. Signed-off-by: Ethan Nelson-Moore <enelsonmoore(a)gmail.com> --- drivers/staging/greybus/Kconfig | 10 - drivers/staging/greybus/Makefile | 2 - drivers/staging/greybus/camera.c | 1367 --------------------------- drivers/staging/greybus/gb-camera.h | 127 --- 4 files changed, 1506 deletions(-) delete mode 100644 drivers/staging/greybus/camera.c delete mode 100644 drivers/staging/greybus/gb-camera.h diff --git a/drivers/staging/greybus/Kconfig b/drivers/staging/greybus/Kconfig index c25da61570eb..e1d7ffdf4a6f 100644 --- a/drivers/staging/greybus/Kconfig +++ b/drivers/staging/greybus/Kconfig @@ -32,16 +32,6 @@ config GREYBUS_BOOTROM To compile this code as a module, chose M here: the module will be called gb-bootrom.ko -config GREYBUS_CAMERA - tristate "Greybus Camera Class driver" - depends on MEDIA_SUPPORT && LEDS_CLASS_FLASH && BROKEN - help - Select this option if you have a device that follows the - Greybus Camera Class specification. - - To compile this code as a module, chose M here: the module - will be called gb-camera.ko - config GREYBUS_FIRMWARE tristate "Greybus Firmware Download Class driver" depends on SPI diff --git a/drivers/staging/greybus/Makefile b/drivers/staging/greybus/Makefile index 7b9807f8a1a3..01a372e9833e 100644 --- a/drivers/staging/greybus/Makefile +++ b/drivers/staging/greybus/Makefile @@ -4,7 +4,6 @@ ccflags-y += -I$(src) # Greybus class drivers gb-bootrom-y := bootrom.o -gb-camera-y := camera.o gb-firmware-y := fw-core.o fw-download.o fw-management.o authentication.o gb-spilib-y := spilib.o gb-hid-y := hid.o @@ -16,7 +15,6 @@ gb-raw-y := raw.o gb-vibrator-y := vibrator.o obj-$(CONFIG_GREYBUS_BOOTROM) += gb-bootrom.o -obj-$(CONFIG_GREYBUS_CAMERA) += gb-camera.o obj-$(CONFIG_GREYBUS_FIRMWARE) += gb-firmware.o gb-spilib.o obj-$(CONFIG_GREYBUS_HID) += gb-hid.o obj-$(CONFIG_GREYBUS_LIGHT) += gb-light.o diff --git a/drivers/staging/greybus/camera.c b/drivers/staging/greybus/camera.c deleted file mode 100644 index 62b55bb28408..000000000000 --- a/drivers/staging/greybus/camera.c +++ /dev/null @@ -1,1367 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Greybus Camera protocol driver. - * - * Copyright 2015 Google Inc. - * Copyright 2015 Linaro Ltd. - */ - -#include <linux/debugfs.h> -#include <linux/fs.h> -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/slab.h> -#include <linux/string.h> -#include <linux/uaccess.h> -#include <linux/vmalloc.h> -#include <linux/greybus.h> - -#include "gb-camera.h" -#include "greybus_protocols.h" - -enum gb_camera_debugs_buffer_id { - GB_CAMERA_DEBUGFS_BUFFER_CAPABILITIES, - GB_CAMERA_DEBUGFS_BUFFER_STREAMS, - GB_CAMERA_DEBUGFS_BUFFER_CAPTURE, - GB_CAMERA_DEBUGFS_BUFFER_FLUSH, - GB_CAMERA_DEBUGFS_BUFFER_MAX, -}; - -struct gb_camera_debugfs_buffer { - char data[PAGE_SIZE]; - size_t length; -}; - -enum gb_camera_state { - GB_CAMERA_STATE_UNCONFIGURED, - GB_CAMERA_STATE_CONFIGURED, -}; - -/** - * struct gb_camera - A Greybus Camera Device - * @connection: the greybus connection for camera management - * @data_connection: the greybus connection for camera data - * @data_cport_id: the data CPort ID on the module side - * @mutex: protects the connection and state fields - * @state: the current module state - * @debugfs: debugfs entries for camera protocol operations testing - * @module: Greybus camera module registered to HOST processor. - */ -struct gb_camera { - struct gb_bundle *bundle; - struct gb_connection *connection; - struct gb_connection *data_connection; - u16 data_cport_id; - - struct mutex mutex; - enum gb_camera_state state; - - struct { - struct dentry *root; - struct gb_camera_debugfs_buffer *buffers; - } debugfs; - - struct gb_camera_module module; -}; - -struct gb_camera_stream_config { - unsigned int width; - unsigned int height; - unsigned int format; - unsigned int vc; - unsigned int dt[2]; - unsigned int max_size; -}; - -struct gb_camera_fmt_info { - enum v4l2_mbus_pixelcode mbus_code; - unsigned int gb_format; - unsigned int bpp; -}; - -/* GB format to media code map */ -static const struct gb_camera_fmt_info gb_fmt_info[] = { - { - .mbus_code = V4L2_MBUS_FMT_UYVY8_1X16, - .gb_format = 0x01, - .bpp = 16, - }, - { - .mbus_code = V4L2_MBUS_FMT_NV12_1x8, - .gb_format = 0x12, - .bpp = 12, - }, - { - .mbus_code = V4L2_MBUS_FMT_NV21_1x8, - .gb_format = 0x13, - .bpp = 12, - }, - { - .mbus_code = V4L2_MBUS_FMT_YU12_1x8, - .gb_format = 0x16, - .bpp = 12, - }, - { - .mbus_code = V4L2_MBUS_FMT_YV12_1x8, - .gb_format = 0x17, - .bpp = 12, - }, - { - .mbus_code = V4L2_MBUS_FMT_JPEG_1X8, - .gb_format = 0x40, - .bpp = 0, - }, - { - .mbus_code = V4L2_MBUS_FMT_GB_CAM_METADATA_1X8, - .gb_format = 0x41, - .bpp = 0, - }, - { - .mbus_code = V4L2_MBUS_FMT_GB_CAM_DEBUG_DATA_1X8, - .gb_format = 0x42, - .bpp = 0, - }, - { - .mbus_code = V4L2_MBUS_FMT_SBGGR10_1X10, - .gb_format = 0x80, - .bpp = 10, - }, - { - .mbus_code = V4L2_MBUS_FMT_SGBRG10_1X10, - .gb_format = 0x81, - .bpp = 10, - }, - { - .mbus_code = V4L2_MBUS_FMT_SGRBG10_1X10, - .gb_format = 0x82, - .bpp = 10, - }, - { - .mbus_code = V4L2_MBUS_FMT_SRGGB10_1X10, - .gb_format = 0x83, - .bpp = 10, - }, - { - .mbus_code = V4L2_MBUS_FMT_SBGGR12_1X12, - .gb_format = 0x84, - .bpp = 12, - }, - { - .mbus_code = V4L2_MBUS_FMT_SGBRG12_1X12, - .gb_format = 0x85, - .bpp = 12, - }, - { - .mbus_code = V4L2_MBUS_FMT_SGRBG12_1X12, - .gb_format = 0x86, - .bpp = 12, - }, - { - .mbus_code = V4L2_MBUS_FMT_SRGGB12_1X12, - .gb_format = 0x87, - .bpp = 12, - }, -}; - -static const struct gb_camera_fmt_info *gb_camera_get_format_info(u16 gb_fmt) -{ - unsigned int i; - - for (i = 0; i < ARRAY_SIZE(gb_fmt_info); i++) { - if (gb_fmt_info[i].gb_format == gb_fmt) - return &gb_fmt_info[i]; - } - - return NULL; -} - -#define ES2_APB_CDSI0_CPORT 16 -#define ES2_APB_CDSI1_CPORT 17 - -#define GB_CAMERA_MAX_SETTINGS_SIZE 8192 - -static int gb_camera_operation_sync_flags(struct gb_connection *connection, - int type, unsigned int flags, - void *request, size_t request_size, - void *response, size_t *response_size) -{ - struct gb_operation *operation; - int ret; - - operation = gb_operation_create_flags(connection, type, request_size, - *response_size, flags, - GFP_KERNEL); - if (!operation) - return -ENOMEM; - - if (request_size) - memcpy(operation->request->payload, request, request_size); - - ret = gb_operation_request_send_sync(operation); - if (ret) { - dev_err(&connection->hd->dev, - "%s: synchronous operation of type 0x%02x failed: %d\n", - connection->name, type, ret); - } else { - *response_size = operation->response->payload_size; - - if (operation->response->payload_size) - memcpy(response, operation->response->payload, - operation->response->payload_size); - } - - gb_operation_put(operation); - - return ret; -} - -static int gb_camera_get_max_pkt_size(struct gb_camera *gcam, - struct gb_camera_configure_streams_response *resp) -{ - unsigned int max_pkt_size = 0; - unsigned int i; - - for (i = 0; i < resp->num_streams; i++) { - struct gb_camera_stream_config_response *cfg = &resp->config[i]; - const struct gb_camera_fmt_info *fmt_info; - unsigned int pkt_size; - - fmt_info = gb_camera_get_format_info(cfg->format); - if (!fmt_info) { - dev_err(&gcam->bundle->dev, "unsupported greybus image format: %d\n", - cfg->format); - return -EIO; - } - - if (fmt_info->bpp == 0) { - pkt_size = le32_to_cpu(cfg->max_pkt_size); - - if (pkt_size == 0) { - dev_err(&gcam->bundle->dev, - "Stream %u: invalid zero maximum packet size\n", - i); - return -EIO; - } - } else { - pkt_size = le16_to_cpu(cfg->width) * fmt_info->bpp / 8; - - if (pkt_size != le32_to_cpu(cfg->max_pkt_size)) { - dev_err(&gcam->bundle->dev, - "Stream %u: maximum packet size mismatch (%u/%u)\n", - i, pkt_size, cfg->max_pkt_size); - return -EIO; - } - } - - max_pkt_size = max(pkt_size, max_pkt_size); - } - - return max_pkt_size; -} - -/* - * Validate the stream configuration response verifying padding is correctly - * set and the returned number of streams is supported - */ -static const int gb_camera_configure_streams_validate_response(struct gb_camera *gcam, - struct gb_camera_configure_streams_response *resp, - unsigned int nstreams) -{ - unsigned int i; - - /* Validate the returned response structure */ - if (resp->padding[0] || resp->padding[1]) { - dev_err(&gcam->bundle->dev, "response padding != 0\n"); - return -EIO; - } - - if (resp->num_streams > nstreams) { - dev_err(&gcam->bundle->dev, "got #streams %u > request %u\n", - resp->num_streams, nstreams); - return -EIO; - } - - for (i = 0; i < resp->num_streams; i++) { - struct gb_camera_stream_config_response *cfg = &resp->config[i]; - - if (cfg->padding) { - dev_err(&gcam->bundle->dev, "stream #%u padding != 0\n", i); - return -EIO; - } - } - - return 0; -} - -/* ----------------------------------------------------------------------------- - * Hardware Configuration - */ - -static int gb_camera_set_intf_power_mode(struct gb_camera *gcam, u8 intf_id, - bool hs) -{ - struct gb_svc *svc = gcam->connection->hd->svc; - int ret; - - if (hs) - ret = gb_svc_intf_set_power_mode(svc, intf_id, - GB_SVC_UNIPRO_HS_SERIES_A, - GB_SVC_UNIPRO_FAST_MODE, 2, 2, - GB_SVC_SMALL_AMPLITUDE, - GB_SVC_NO_DE_EMPHASIS, - GB_SVC_UNIPRO_FAST_MODE, 2, 2, - GB_SVC_PWRM_RXTERMINATION | - GB_SVC_PWRM_TXTERMINATION, 0, - NULL, NULL); - else - ret = gb_svc_intf_set_power_mode(svc, intf_id, - GB_SVC_UNIPRO_HS_SERIES_A, - GB_SVC_UNIPRO_SLOW_AUTO_MODE, - 2, 1, - GB_SVC_SMALL_AMPLITUDE, - GB_SVC_NO_DE_EMPHASIS, - GB_SVC_UNIPRO_SLOW_AUTO_MODE, - 2, 1, - 0, 0, - NULL, NULL); - - return ret; -} - -static int gb_camera_set_power_mode(struct gb_camera *gcam, bool hs) -{ - struct gb_interface *intf = gcam->connection->intf; - struct gb_svc *svc = gcam->connection->hd->svc; - int ret; - - ret = gb_camera_set_intf_power_mode(gcam, intf->interface_id, hs); - if (ret < 0) { - dev_err(&gcam->bundle->dev, "failed to set module interface to %s (%d)\n", - hs ? "HS" : "PWM", ret); - return ret; - } - - ret = gb_camera_set_intf_power_mode(gcam, svc->ap_intf_id, hs); - if (ret < 0) { - gb_camera_set_intf_power_mode(gcam, intf->interface_id, !hs); - dev_err(&gcam->bundle->dev, "failed to set AP interface to %s (%d)\n", - hs ? "HS" : "PWM", ret); - return ret; - } - - return 0; -} - -struct ap_csi_config_request { - __u8 csi_id; - __u8 flags; -#define GB_CAMERA_CSI_FLAG_CLOCK_CONTINUOUS 0x01 - __u8 num_lanes; - __u8 padding; - __le32 csi_clk_freq; - __le32 max_pkt_size; -} __packed; - -/* - * TODO: Compute the number of lanes dynamically based on bandwidth - * requirements. - */ -#define GB_CAMERA_CSI_NUM_DATA_LANES 4 - -#define GB_CAMERA_CSI_CLK_FREQ_MAX 999000000U -#define GB_CAMERA_CSI_CLK_FREQ_MIN 100000000U -#define GB_CAMERA_CSI_CLK_FREQ_MARGIN 150000000U - -static int gb_camera_setup_data_connection(struct gb_camera *gcam, - struct gb_camera_configure_streams_response *resp, - struct gb_camera_csi_params *csi_params) -{ - struct ap_csi_config_request csi_cfg; - struct gb_connection *conn; - unsigned int clk_freq; - int ret; - - /* - * Create the data connection between the camera module data CPort and - * APB CDSI1. The CDSI1 CPort ID is hardcoded by the ES2 bridge. - */ - conn = gb_connection_create_offloaded(gcam->bundle, gcam->data_cport_id, - GB_CONNECTION_FLAG_NO_FLOWCTRL | - GB_CONNECTION_FLAG_CDSI1); - if (IS_ERR(conn)) - return PTR_ERR(conn); - - gcam->data_connection = conn; - gb_connection_set_data(conn, gcam); - - ret = gb_connection_enable(conn); - if (ret) - goto error_conn_destroy; - - /* Set the UniPro link to high speed mode. */ - ret = gb_camera_set_power_mode(gcam, true); - if (ret < 0) - goto error_conn_disable; - - /* - * Configure the APB-A CSI-2 transmitter. - * - * Hardcode the number of lanes to 4 and compute the bus clock frequency - * based on the module bandwidth requirements with a safety margin. - */ - memset(&csi_cfg, 0, sizeof(csi_cfg)); - csi_cfg.csi_id = 1; - csi_cfg.flags = 0; - csi_cfg.num_lanes = GB_CAMERA_CSI_NUM_DATA_LANES; - - clk_freq = resp->data_rate / 2 / GB_CAMERA_CSI_NUM_DATA_LANES; - clk_freq = clamp(clk_freq + GB_CAMERA_CSI_CLK_FREQ_MARGIN, - GB_CAMERA_CSI_CLK_FREQ_MIN, - GB_CAMERA_CSI_CLK_FREQ_MAX); - csi_cfg.csi_clk_freq = clk_freq; - - ret = gb_camera_get_max_pkt_size(gcam, resp); - if (ret < 0) { - ret = -EIO; - goto error_power; - } - csi_cfg.max_pkt_size = ret; - - ret = gb_hd_output(gcam->connection->hd, &csi_cfg, - sizeof(csi_cfg), - GB_APB_REQUEST_CSI_TX_CONTROL, false); - if (ret < 0) { - dev_err(&gcam->bundle->dev, "failed to start the CSI transmitter\n"); - goto error_power; - } - - if (csi_params) { - csi_params->clk_freq = csi_cfg.csi_clk_freq; - csi_params->num_lanes = csi_cfg.num_lanes; - } - - return 0; - -error_power: - gb_camera_set_power_mode(gcam, false); -error_conn_disable: - gb_connection_disable(gcam->data_connection); -error_conn_destroy: - gb_connection_destroy(gcam->data_connection); - gcam->data_connection = NULL; - return ret; -} - -static void gb_camera_teardown_data_connection(struct gb_camera *gcam) -{ - struct ap_csi_config_request csi_cfg; - int ret; - - /* Stop the APB1 CSI transmitter. */ - memset(&csi_cfg, 0, sizeof(csi_cfg)); - csi_cfg.csi_id = 1; - - ret = gb_hd_output(gcam->connection->hd, &csi_cfg, - sizeof(csi_cfg), - GB_APB_REQUEST_CSI_TX_CONTROL, false); - - if (ret < 0) - dev_err(&gcam->bundle->dev, "failed to stop the CSI transmitter\n"); - - /* Set the UniPro link to low speed mode. */ - gb_camera_set_power_mode(gcam, false); - - /* Destroy the data connection. */ - gb_connection_disable(gcam->data_connection); - gb_connection_destroy(gcam->data_connection); - gcam->data_connection = NULL; -} - -/* ----------------------------------------------------------------------------- - * Camera Protocol Operations - */ - -static int gb_camera_capabilities(struct gb_camera *gcam, - u8 *capabilities, size_t *size) -{ - int ret; - - ret = gb_pm_runtime_get_sync(gcam->bundle); - if (ret) - return ret; - - mutex_lock(&gcam->mutex); - - if (!gcam->connection) { - ret = -EINVAL; - goto done; - } - - ret = gb_camera_operation_sync_flags(gcam->connection, - GB_CAMERA_TYPE_CAPABILITIES, - GB_OPERATION_FLAG_SHORT_RESPONSE, - NULL, 0, - (void *)capabilities, size); - if (ret) - dev_err(&gcam->bundle->dev, "failed to retrieve capabilities: %d\n", ret); - -done: - mutex_unlock(&gcam->mutex); - - gb_pm_runtime_put_autosuspend(gcam->bundle); - - return ret; -} - -static int gb_camera_configure_streams(struct gb_camera *gcam, - unsigned int *num_streams, - unsigned int *flags, - struct gb_camera_stream_config *streams, - struct gb_camera_csi_params *csi_params) -{ - struct gb_camera_configure_streams_request *req; - struct gb_camera_configure_streams_response *resp; - unsigned int nstreams = *num_streams; - unsigned int i; - size_t req_size; - size_t resp_size; - int ret; - - if (nstreams > GB_CAMERA_MAX_STREAMS) - return -EINVAL; - - req_size = sizeof(*req) + nstreams * sizeof(req->config[0]); - resp_size = sizeof(*resp) + nstreams * sizeof(resp->config[0]); - - req = kmalloc(req_size, GFP_KERNEL); - resp = kmalloc(resp_size, GFP_KERNEL); - if (!req || !resp) { - kfree(req); - kfree(resp); - return -ENOMEM; - } - - req->num_streams = nstreams; - req->flags = *flags; - req->padding = 0; - - for (i = 0; i < nstreams; ++i) { - struct gb_camera_stream_config_request *cfg = &req->config[i]; - - cfg->width = cpu_to_le16(streams[i].width); - cfg->height = cpu_to_le16(streams[i].height); - cfg->format = cpu_to_le16(streams[i].format); - cfg->padding = 0; - } - - mutex_lock(&gcam->mutex); - - ret = gb_pm_runtime_get_sync(gcam->bundle); - if (ret) - goto done_skip_pm_put; - - if (!gcam->connection) { - ret = -EINVAL; - goto done; - } - - ret = gb_camera_operation_sync_flags(gcam->connection, - GB_CAMERA_TYPE_CONFIGURE_STREAMS, - GB_OPERATION_FLAG_SHORT_RESPONSE, - req, req_size, - resp, &resp_size); - if (ret < 0) - goto done; - - ret = gb_camera_configure_streams_validate_response(gcam, resp, - nstreams); - if (ret < 0) - goto done; - - *flags = resp->flags; - *num_streams = resp->num_streams; - - for (i = 0; i < resp->num_streams; ++i) { - struct gb_camera_stream_config_response *cfg = &resp->config[i]; - - streams[i].width = le16_to_cpu(cfg->width); - streams[i].height = le16_to_cpu(cfg->height); - streams[i].format = le16_to_cpu(cfg->format); - streams[i].vc = cfg->virtual_channel; - streams[i].dt[0] = cfg->data_type[0]; - streams[i].dt[1] = cfg->data_type[1]; - streams[i].max_size = le32_to_cpu(cfg->max_size); - } - - if ((resp->flags & GB_CAMERA_CONFIGURE_STREAMS_ADJUSTED) || - (req->flags & GB_CAMERA_CONFIGURE_STREAMS_TEST_ONLY)) - goto done; - - if (gcam->state == GB_CAMERA_STATE_CONFIGURED) { - gb_camera_teardown_data_connection(gcam); - gcam->state = GB_CAMERA_STATE_UNCONFIGURED; - - /* - * When unconfiguring streams release the PM runtime reference - * that was acquired when streams were configured. The bundle - * won't be suspended until the PM runtime reference acquired at - * the beginning of this function gets released right before - * returning. - */ - gb_pm_runtime_put_noidle(gcam->bundle); - } - - if (resp->num_streams == 0) - goto done; - - /* - * Make sure the bundle won't be suspended until streams get - * unconfigured after the stream is configured successfully - */ - gb_pm_runtime_get_noresume(gcam->bundle); - - /* Setup CSI-2 connection from APB-A to AP */ - ret = gb_camera_setup_data_connection(gcam, resp, csi_params); - if (ret < 0) { - memset(req, 0, sizeof(*req)); - gb_operation_sync(gcam->connection, - GB_CAMERA_TYPE_CONFIGURE_STREAMS, - req, sizeof(*req), - resp, sizeof(*resp)); - *flags = 0; - *num_streams = 0; - gb_pm_runtime_put_noidle(gcam->bundle); - goto done; - } - - gcam->state = GB_CAMERA_STATE_CONFIGURED; - -done: - gb_pm_runtime_put_autosuspend(gcam->bundle); - -done_skip_pm_put: - mutex_unlock(&gcam->mutex); - kfree(req); - kfree(resp); - return ret; -} - -static int gb_camera_capture(struct gb_camera *gcam, u32 request_id, - unsigned int streams, unsigned int num_frames, - size_t settings_size, const void *settings) -{ - struct gb_camera_capture_request *req; - size_t req_size; - int ret; - - if (settings_size > GB_CAMERA_MAX_SETTINGS_SIZE) - return -EINVAL; - - req_size = sizeof(*req) + settings_size; - req = kmalloc(req_size, GFP_KERNEL); - if (!req) - return -ENOMEM; - - req->request_id = cpu_to_le32(request_id); - req->streams = streams; - req->padding = 0; - req->num_frames = cpu_to_le16(num_frames); - memcpy(req->settings, settings, settings_size); - - mutex_lock(&gcam->mutex); - - if (!gcam->connection) { - ret = -EINVAL; - goto done; - } - - ret = gb_operation_sync(gcam->connection, GB_CAMERA_TYPE_CAPTURE, - req, req_size, NULL, 0); -done: - mutex_unlock(&gcam->mutex); - - kfree(req); - - return ret; -} - -static int gb_camera_flush(struct gb_camera *gcam, u32 *request_id) -{ - struct gb_camera_flush_response resp; - int ret; - - mutex_lock(&gcam->mutex); - - if (!gcam->connection) { - ret = -EINVAL; - goto done; - } - - ret = gb_operation_sync(gcam->connection, GB_CAMERA_TYPE_FLUSH, NULL, 0, - &resp, sizeof(resp)); - - if (ret < 0) - goto done; - - if (request_id) - *request_id = le32_to_cpu(resp.request_id); - -done: - mutex_unlock(&gcam->mutex); - - return ret; -} - -static int gb_camera_request_handler(struct gb_operation *op) -{ - struct gb_camera *gcam = gb_connection_get_data(op->connection); - struct gb_camera_metadata_request *payload; - struct gb_message *request; - - if (op->type != GB_CAMERA_TYPE_METADATA) { - dev_err(&gcam->bundle->dev, "Unsupported unsolicited event: %u\n", op->type); - return -EINVAL; - } - - request = op->request; - - if (request->payload_size < sizeof(*payload)) { - dev_err(&gcam->bundle->dev, "Wrong event size received (%zu < %zu)\n", - request->payload_size, sizeof(*payload)); - return -EINVAL; - } - - payload = request->payload; - - dev_dbg(&gcam->bundle->dev, "received metadata for request %u, frame %u, stream %u\n", - payload->request_id, payload->frame_number, payload->stream); - - return 0; -} - -/* ----------------------------------------------------------------------------- - * Interface with HOST gmp camera. - */ -static unsigned int gb_camera_mbus_to_gb(enum v4l2_mbus_pixelcode mbus_code) -{ - unsigned int i; - - for (i = 0; i < ARRAY_SIZE(gb_fmt_info); i++) { - if (gb_fmt_info[i].mbus_code == mbus_code) - return gb_fmt_info[i].gb_format; - } - return gb_fmt_info[0].gb_format; -} - -static enum v4l2_mbus_pixelcode gb_camera_gb_to_mbus(u16 gb_fmt) -{ - unsigned int i; - - for (i = 0; i < ARRAY_SIZE(gb_fmt_info); i++) { - if (gb_fmt_info[i].gb_format == gb_fmt) - return gb_fmt_info[i].mbus_code; - } - return gb_fmt_info[0].mbus_code; -} - -static ssize_t gb_camera_op_capabilities(void *priv, char *data, size_t len) -{ - struct gb_camera *gcam = priv; - size_t capabilities_len = len; - int ret; - - ret = gb_camera_capabilities(gcam, data, &capabilities_len); - if (ret) - return ret; - - return capabilities_len; -} - -static int gb_camera_op_configure_streams(void *priv, unsigned int *nstreams, - unsigned int *flags, struct gb_camera_stream *streams, - struct gb_camera_csi_params *csi_params) -{ - struct gb_camera *gcam = priv; - struct gb_camera_stream_config *gb_streams; - unsigned int gb_flags = 0; - unsigned int gb_nstreams = *nstreams; - unsigned int i; - int ret; - - if (gb_nstreams > GB_CAMERA_MAX_STREAMS) - return -EINVAL; - - gb_streams = kzalloc_objs(*gb_streams, gb_nstreams); - if (!gb_streams) - return -ENOMEM; - - for (i = 0; i < gb_nstreams; i++) { - gb_streams[i].width = streams[i].width; - gb_streams[i].height = streams[i].height; - gb_streams[i].format = - gb_camera_mbus_to_gb(streams[i].pixel_code); - } - - if (*flags & GB_CAMERA_IN_FLAG_TEST) - gb_flags |= GB_CAMERA_CONFIGURE_STREAMS_TEST_ONLY; - - ret = gb_camera_configure_streams(gcam, &gb_nstreams, - &gb_flags, gb_streams, csi_params); - if (ret < 0) - goto done; - if (gb_nstreams > *nstreams) { - ret = -EINVAL; - goto done; - } - - *flags = 0; - if (gb_flags & GB_CAMERA_CONFIGURE_STREAMS_ADJUSTED) - *flags |= GB_CAMERA_OUT_FLAG_ADJUSTED; - - for (i = 0; i < gb_nstreams; i++) { - streams[i].width = gb_streams[i].width; - streams[i].height = gb_streams[i].height; - streams[i].vc = gb_streams[i].vc; - streams[i].dt[0] = gb_streams[i].dt[0]; - streams[i].dt[1] = gb_streams[i].dt[1]; - streams[i].max_size = gb_streams[i].max_size; - streams[i].pixel_code = - gb_camera_gb_to_mbus(gb_streams[i].format); - } - *nstreams = gb_nstreams; - -done: - kfree(gb_streams); - return ret; -} - -static int gb_camera_op_capture(void *priv, u32 request_id, - unsigned int streams, unsigned int num_frames, - size_t settings_size, const void *settings) -{ - struct gb_camera *gcam = priv; - - return gb_camera_capture(gcam, request_id, streams, num_frames, - settings_size, settings); -} - -static int gb_camera_op_flush(void *priv, u32 *request_id) -{ - struct gb_camera *gcam = priv; - - return gb_camera_flush(gcam, request_id); -} - -static const struct gb_camera_ops gb_cam_ops = { - .capabilities = gb_camera_op_capabilities, - .configure_streams = gb_camera_op_configure_streams, - .capture = gb_camera_op_capture, - .flush = gb_camera_op_flush, -}; - -/* ----------------------------------------------------------------------------- - * DebugFS - */ - -static ssize_t gb_camera_debugfs_capabilities(struct gb_camera *gcam, - char *buf, size_t len) -{ - struct gb_camera_debugfs_buffer *buffer = - &gcam->debugfs.buffers[GB_CAMERA_DEBUGFS_BUFFER_CAPABILITIES]; - size_t size = 1024; - unsigned int i; - u8 *caps; - int ret; - - caps = kmalloc(size, GFP_KERNEL); - if (!caps) - return -ENOMEM; - - ret = gb_camera_capabilities(gcam, caps, &size); - if (ret < 0) - goto done; - - /* - * hex_dump_to_buffer() doesn't return the number of bytes dumped prior - * to v4.0, we need our own implementation :-( - */ - buffer->length = 0; - - for (i = 0; i < size; i += 16) { - unsigned int nbytes = min_t(unsigned int, size - i, 16); - - buffer->length += sprintf(buffer->data + buffer->length, - "%*ph\n", nbytes, caps + i); - } - -done: - kfree(caps); - return ret; -} - -static ssize_t gb_camera_debugfs_configure_streams(struct gb_camera *gcam, - char *buf, size_t len) -{ - struct gb_camera_debugfs_buffer *buffer = - &gcam->debugfs.buffers[GB_CAMERA_DEBUGFS_BUFFER_STREAMS]; - struct gb_camera_stream_config *streams; - unsigned int nstreams; - unsigned int flags; - unsigned int i; - char *token; - int ret; - - /* Retrieve number of streams to configure */ - token = strsep(&buf, ";"); - if (!token) - return -EINVAL; - - ret = kstrtouint(token, 10, &nstreams); - if (ret < 0) - return ret; - - if (nstreams > GB_CAMERA_MAX_STREAMS) - return -EINVAL; - - token = strsep(&buf, ";"); - if (!token) - return -EINVAL; - - ret = kstrtouint(token, 10, &flags); - if (ret < 0) - return ret; - - /* For each stream to configure parse width, height and format */ - streams = kzalloc_objs(*streams, nstreams); - if (!streams) - return -ENOMEM; - - for (i = 0; i < nstreams; ++i) { - struct gb_camera_stream_config *stream = &streams[i]; - - /* width */ - token = strsep(&buf, ";"); - if (!token) { - ret = -EINVAL; - goto done; - } - ret = kstrtouint(token, 10, &stream->width); - if (ret < 0) - goto done; - - /* height */ - token = strsep(&buf, ";"); - if (!token) - goto done; - - ret = kstrtouint(token, 10, &stream->height); - if (ret < 0) - goto done; - - /* Image format code */ - token = strsep(&buf, ";"); - if (!token) - goto done; - - ret = kstrtouint(token, 16, &stream->format); - if (ret < 0) - goto done; - } - - ret = gb_camera_configure_streams(gcam, &nstreams, &flags, streams, - NULL); - if (ret < 0) - goto done; - - buffer->length = sprintf(buffer->data, "%u;%u;", nstreams, flags); - - for (i = 0; i < nstreams; ++i) { - struct gb_camera_stream_config *stream = &streams[i]; - - buffer->length += sprintf(buffer->data + buffer->length, - "%u;%u;%u;%u;%u;%u;%u;", - stream->width, stream->height, - stream->format, stream->vc, - stream->dt[0], stream->dt[1], - stream->max_size); - } - - ret = len; - -done: - kfree(streams); - return ret; -}; - -static ssize_t gb_camera_debugfs_capture(struct gb_camera *gcam, - char *buf, size_t len) -{ - unsigned int request_id; - unsigned int streams_mask; - unsigned int num_frames; - char *token; - int ret; - - /* Request id */ - token = strsep(&buf, ";"); - if (!token) - return -EINVAL; - ret = kstrtouint(token, 10, &request_id); - if (ret < 0) - return ret; - - /* Stream mask */ - token = strsep(&buf, ";"); - if (!token) - return -EINVAL; - ret = kstrtouint(token, 16, &streams_mask); - if (ret < 0) - return ret; - - /* number of frames */ - token = strsep(&buf, ";"); - if (!token) - return -EINVAL; - ret = kstrtouint(token, 10, &num_frames); - if (ret < 0) - return ret; - - ret = gb_camera_capture(gcam, request_id, streams_mask, num_frames, 0, - NULL); - if (ret < 0) - return ret; - - return len; -} - -static ssize_t gb_camera_debugfs_flush(struct gb_camera *gcam, - char *buf, size_t len) -{ - struct gb_camera_debugfs_buffer *buffer = - &gcam->debugfs.buffers[GB_CAMERA_DEBUGFS_BUFFER_FLUSH]; - unsigned int req_id; - int ret; - - ret = gb_camera_flush(gcam, &req_id); - if (ret < 0) - return ret; - - buffer->length = sprintf(buffer->data, "%u", req_id); - - return len; -} - -struct gb_camera_debugfs_entry { - const char *name; - unsigned int mask; - unsigned int buffer; - ssize_t (*execute)(struct gb_camera *gcam, char *buf, size_t len); -}; - -static const struct gb_camera_debugfs_entry gb_camera_debugfs_entries[] = { - { - .name = "capabilities", - .mask = S_IFREG | 0444, - .buffer = GB_CAMERA_DEBUGFS_BUFFER_CAPABILITIES, - .execute = gb_camera_debugfs_capabilities, - }, { - .name = "configure_streams", - .mask = S_IFREG | 0666, - .buffer = GB_CAMERA_DEBUGFS_BUFFER_STREAMS, - .execute = gb_camera_debugfs_configure_streams, - }, { - .name = "capture", - .mask = S_IFREG | 0666, - .buffer = GB_CAMERA_DEBUGFS_BUFFER_CAPTURE, - .execute = gb_camera_debugfs_capture, - }, { - .name = "flush", - .mask = S_IFREG | 0666, - .buffer = GB_CAMERA_DEBUGFS_BUFFER_FLUSH, - .execute = gb_camera_debugfs_flush, - }, -}; - -static ssize_t gb_camera_debugfs_read(struct file *file, char __user *buf, - size_t len, loff_t *offset) -{ - const struct gb_camera_debugfs_entry *op = file->private_data; - struct gb_camera *gcam = file_inode(file)->i_private; - struct gb_camera_debugfs_buffer *buffer; - ssize_t ret; - - /* For read-only entries the operation is triggered by a read. */ - if (!(op->mask & 0222)) { - ret = op->execute(gcam, NULL, 0); - if (ret < 0) - return ret; - } - - buffer = &gcam->debugfs.buffers[op->buffer]; - - return simple_read_from_buffer(buf, len, offset, buffer->data, - buffer->length); -} - -static ssize_t gb_camera_debugfs_write(struct file *file, - const char __user *buf, size_t len, - loff_t *offset) -{ - const struct gb_camera_debugfs_entry *op = file->private_data; - struct gb_camera *gcam = file_inode(file)->i_private; - ssize_t ret; - char *kbuf; - - if (len > 1024) - return -EINVAL; - - kbuf = memdup_user_nul(buf, len); - if (IS_ERR(kbuf)) - return PTR_ERR(kbuf); - - ret = op->execute(gcam, kbuf, len); - -done: - kfree(kbuf); - return ret; -} - -static int gb_camera_debugfs_open(struct inode *inode, struct file *file) -{ - file->private_data = debugfs_get_aux(file); - return 0; -} - -static const struct file_operations gb_camera_debugfs_ops = { - .open = gb_camera_debugfs_open, - .read = gb_camera_debugfs_read, - .write = gb_camera_debugfs_write, -}; - -static int gb_camera_debugfs_init(struct gb_camera *gcam) -{ - struct gb_connection *connection = gcam->connection; - char dirname[27]; - unsigned int i; - - /* - * Create root debugfs entry and a file entry for each camera operation. - */ - snprintf(dirname, 27, "camera-%u.%u", connection->intf->interface_id, - gcam->bundle->id); - - gcam->debugfs.root = debugfs_create_dir(dirname, gb_debugfs_get()); - - gcam->debugfs.buffers = - vmalloc(array_size(GB_CAMERA_DEBUGFS_BUFFER_MAX, - sizeof(*gcam->debugfs.buffers))); - if (!gcam->debugfs.buffers) - return -ENOMEM; - - for (i = 0; i < ARRAY_SIZE(gb_camera_debugfs_entries); ++i) { - const struct gb_camera_debugfs_entry *entry = - &gb_camera_debugfs_entries[i]; - - gcam->debugfs.buffers[i].length = 0; - - debugfs_create_file_aux(entry->name, entry->mask, - gcam->debugfs.root, gcam, entry, - &gb_camera_debugfs_ops); - } - - return 0; -} - -static void gb_camera_debugfs_cleanup(struct gb_camera *gcam) -{ - debugfs_remove_recursive(gcam->debugfs.root); - - vfree(gcam->debugfs.buffers); -} - -/* ----------------------------------------------------------------------------- - * Init & Cleanup - */ - -static void gb_camera_cleanup(struct gb_camera *gcam) -{ - gb_camera_debugfs_cleanup(gcam); - - mutex_lock(&gcam->mutex); - if (gcam->data_connection) { - gb_connection_disable(gcam->data_connection); - gb_connection_destroy(gcam->data_connection); - gcam->data_connection = NULL; - } - - if (gcam->connection) { - gb_connection_disable(gcam->connection); - gb_connection_destroy(gcam->connection); - gcam->connection = NULL; - } - mutex_unlock(&gcam->mutex); -} - -static void gb_camera_release_module(struct kref *ref) -{ - struct gb_camera_module *cam_mod = - container_of(ref, struct gb_camera_module, refcount); - kfree(cam_mod->priv); -} - -static int gb_camera_probe(struct gb_bundle *bundle, - const struct greybus_bundle_id *id) -{ - struct gb_connection *conn; - struct gb_camera *gcam; - u16 mgmt_cport_id = 0; - u16 data_cport_id = 0; - unsigned int i; - int ret; - - /* - * The camera bundle must contain exactly two CPorts, one for the - * camera management protocol and one for the camera data protocol. - */ - if (bundle->num_cports != 2) - return -ENODEV; - - for (i = 0; i < bundle->num_cports; ++i) { - struct greybus_descriptor_cport *desc = &bundle->cport_desc[i]; - - switch (desc->protocol_id) { - case GREYBUS_PROTOCOL_CAMERA_MGMT: - mgmt_cport_id = le16_to_cpu(desc->id); - break; - case GREYBUS_PROTOCOL_CAMERA_DATA: - data_cport_id = le16_to_cpu(desc->id); - break; - default: - return -ENODEV; - } - } - - if (!mgmt_cport_id || !data_cport_id) - return -ENODEV; - - gcam = kzalloc_obj(*gcam); - if (!gcam) - return -ENOMEM; - - mutex_init(&gcam->mutex); - - gcam->bundle = bundle; - gcam->state = GB_CAMERA_STATE_UNCONFIGURED; - gcam->data_cport_id = data_cport_id; - - conn = gb_connection_create(bundle, mgmt_cport_id, - gb_camera_request_handler); - if (IS_ERR(conn)) { - ret = PTR_ERR(conn); - goto error; - } - - gcam->connection = conn; - gb_connection_set_data(conn, gcam); - - ret = gb_connection_enable(conn); - if (ret) - goto error; - - ret = gb_camera_debugfs_init(gcam); - if (ret < 0) - goto error; - - gcam->module.priv = gcam; - gcam->module.ops = &gb_cam_ops; - gcam->module.interface_id = gcam->connection->intf->interface_id; - gcam->module.release = gb_camera_release_module; - ret = gb_camera_register(&gcam->module); - if (ret < 0) - goto error; - - greybus_set_drvdata(bundle, gcam); - - gb_pm_runtime_put_autosuspend(gcam->bundle); - - return 0; - -error: - gb_camera_cleanup(gcam); - kfree(gcam); - return ret; -} - -static void gb_camera_disconnect(struct gb_bundle *bundle) -{ - struct gb_camera *gcam = greybus_get_drvdata(bundle); - int ret; - - ret = gb_pm_runtime_get_sync(bundle); - if (ret) - gb_pm_runtime_get_noresume(bundle); - - gb_camera_cleanup(gcam); - gb_camera_unregister(&gcam->module); -} - -static const struct greybus_bundle_id gb_camera_id_table[] = { - { GREYBUS_DEVICE_CLASS(GREYBUS_CLASS_CAMERA) }, - { }, -}; - -#ifdef CONFIG_PM -static int gb_camera_suspend(struct device *dev) -{ - struct gb_bundle *bundle = to_gb_bundle(dev); - struct gb_camera *gcam = greybus_get_drvdata(bundle); - - if (gcam->data_connection) - gb_connection_disable(gcam->data_connection); - - gb_connection_disable(gcam->connection); - - return 0; -} - -static int gb_camera_resume(struct device *dev) -{ - struct gb_bundle *bundle = to_gb_bundle(dev); - struct gb_camera *gcam = greybus_get_drvdata(bundle); - int ret; - - ret = gb_connection_enable(gcam->connection); - if (ret) { - dev_err(&gcam->bundle->dev, "failed to enable connection: %d\n", ret); - return ret; - } - - if (gcam->data_connection) { - ret = gb_connection_enable(gcam->data_connection); - if (ret) { - dev_err(&gcam->bundle->dev, - "failed to enable data connection: %d\n", ret); - return ret; - } - } - - return 0; -} -#endif - -static const struct dev_pm_ops gb_camera_pm_ops = { - SET_RUNTIME_PM_OPS(gb_camera_suspend, gb_camera_resume, NULL) -}; - -static struct greybus_driver gb_camera_driver = { - .name = "camera", - .probe = gb_camera_probe, - .disconnect = gb_camera_disconnect, - .id_table = gb_camera_id_table, - .driver.pm = &gb_camera_pm_ops, -}; - -module_greybus_driver(gb_camera_driver); - -MODULE_DESCRIPTION("Greybus Camera protocol driver."); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/staging/greybus/gb-camera.h b/drivers/staging/greybus/gb-camera.h deleted file mode 100644 index d5a33a13f2a4..000000000000 --- a/drivers/staging/greybus/gb-camera.h +++ /dev/null @@ -1,127 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * Greybus Camera protocol driver. - * - * Copyright 2015 Google Inc. - */ -#ifndef __GB_CAMERA_H -#define __GB_CAMERA_H - -#include <linux/v4l2-mediabus.h> - -/* Input flags need to be set from the caller */ -#define GB_CAMERA_IN_FLAG_TEST BIT(0) -/* Output flags returned */ -#define GB_CAMERA_OUT_FLAG_ADJUSTED BIT(0) - -/** - * struct gb_camera_stream - Represents greybus camera stream. - * @width: Stream width in pixels. - * @height: Stream height in pixels. - * @pixel_code: Media bus pixel code. - * @vc: MIPI CSI virtual channel. - * @dt: MIPI CSI data types. Most formats use a single data type, in which case - * the second element will be ignored. - * @max_size: Maximum size of a frame in bytes. The camera module guarantees - * that all data between the Frame Start and Frame End packet for - * the associated virtual channel and data type(s) will not exceed - * this size. - */ -struct gb_camera_stream { - unsigned int width; - unsigned int height; - enum v4l2_mbus_pixelcode pixel_code; - unsigned int vc; - unsigned int dt[2]; - unsigned int max_size; -}; - -/** - * struct gb_camera_csi_params - CSI configuration parameters - * @num_lanes: number of CSI data lanes - * @clk_freq: CSI clock frequency in Hz - */ -struct gb_camera_csi_params { - unsigned int num_lanes; - unsigned int clk_freq; -}; - -/** - * struct gb_camera_ops - Greybus camera operations, used by the Greybus camera - * driver to expose operations to the host camera driver. - * @capabilities: Retrieve camera capabilities and store them in the buffer - * 'buf' capabilities. The buffer maximum size is specified by - * the caller in the 'size' parameter, and the effective - * capabilities size is returned from the function. If the buffer - * size is too small to hold the capabilities an error is - * returned and the buffer is left untouched. - * - * @configure_streams: Negotiate configuration and prepare the module for video - * capture. The caller specifies the number of streams it - * requests in the 'nstreams' argument and the associated - * streams configurations in the 'streams' argument. The - * GB_CAMERA_IN_FLAG_TEST 'flag' can be set to test a - * configuration without applying it, otherwise the - * configuration is applied by the module. The module can - * decide to modify the requested configuration, including - * using a different number of streams. In that case the - * modified configuration won't be applied, the - * GB_CAMERA_OUT_FLAG_ADJUSTED 'flag' will be set upon - * return, and the modified configuration and number of - * streams stored in 'streams' and 'array'. The module - * returns its CSI-2 bus parameters in the 'csi_params' - * structure in all cases. - * - * @capture: Submit a capture request. The supplied 'request_id' must be unique - * and higher than the IDs of all the previously submitted requests. - * The 'streams' argument specifies which streams are affected by the - * request in the form of a bitmask, with bits corresponding to the - * configured streams indexes. If the request contains settings, the - * 'settings' argument points to the settings buffer and its size is - * specified by the 'settings_size' argument. Otherwise the 'settings' - * argument should be set to NULL and 'settings_size' to 0. - * - * @flush: Flush the capture requests queue. Return the ID of the last request - * that will processed by the device before it stops transmitting video - * frames. All queued capture requests with IDs higher than the returned - * ID will be dropped without being processed. - */ -struct gb_camera_ops { - ssize_t (*capabilities)(void *priv, char *buf, size_t len); - int (*configure_streams)(void *priv, unsigned int *nstreams, - unsigned int *flags, - struct gb_camera_stream *streams, - struct gb_camera_csi_params *csi_params); - int (*capture)(void *priv, u32 request_id, - unsigned int streams, unsigned int num_frames, - size_t settings_size, const void *settings); - int (*flush)(void *priv, u32 *request_id); -}; - -/** - * struct gb_camera_module - Represents greybus camera module. - * @priv: Module private data, passed to all camera operations. - * @ops: Greybus camera operation callbacks. - * @interface_id: Interface id of the module. - * @refcount: Reference counting object. - * @release: Module release function. - * @list: List entry in the camera modules list. - */ -struct gb_camera_module { - void *priv; - const struct gb_camera_ops *ops; - - unsigned int interface_id; - struct kref refcount; - void (*release)(struct kref *kref); - struct list_head list; /* Global list */ -}; - -#define gb_camera_call(f, op, args...) \ - (!(f) ? -ENODEV : (((f)->ops->op) ? \ - (f)->ops->op((f)->priv, ##args) : -ENOIOCTLCMD)) - -int gb_camera_register(struct gb_camera_module *module); -int gb_camera_unregister(struct gb_camera_module *module); - -#endif /* __GB_CAMERA_H */ -- 2.43.0
2 weeks, 5 days
5
5
0
0
[PATCH] staging: greybus: add missing newlines in sysfs_emit formats
by Ashutosh Yadav
According to Documentation/filesystems/sysfs.rst, sysfs attribute show functions should output a single value and terminate with a newline. Currently, gb_audio_module_name_show(), gb_audio_module_vid_show(), gb_audio_module_pid_show(), gb_audio_module_intf_id_show(), gb_audio_module_ip_devices_show(), and gb_audio_module_op_devices_show() call sysfs_emit() without a trailing newline in their format strings. Add the missing newline character to each sysfs_emit() format string to comply with the sysfs documentation and silence checkpatch warnings. Signed-off-by: Ashutosh Yadav <yadavxashutosh(a)gmail.com> --- drivers/staging/greybus/audio_manager_module.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/staging/greybus/audio_manager_module.c b/drivers/staging/greybus/audio_manager_module.c index dc90cc2d2308..5737f2a32f5a 100644 --- a/drivers/staging/greybus/audio_manager_module.c +++ b/drivers/staging/greybus/audio_manager_module.c @@ -75,7 +75,7 @@ static void gb_audio_module_release(struct kobject *kobj) static ssize_t gb_audio_module_name_show(struct gb_audio_manager_module *module, struct gb_audio_manager_module_attribute *attr, char *buf) { - return sysfs_emit(buf, "%s", module->desc.name); + return sysfs_emit(buf, "%s\n", module->desc.name); } static struct gb_audio_manager_module_attribute gb_audio_module_name_attribute = @@ -84,7 +84,7 @@ static struct gb_audio_manager_module_attribute gb_audio_module_name_attribute = static ssize_t gb_audio_module_vid_show(struct gb_audio_manager_module *module, struct gb_audio_manager_module_attribute *attr, char *buf) { - return sysfs_emit(buf, "%d", module->desc.vid); + return sysfs_emit(buf, "%d\n", module->desc.vid); } static struct gb_audio_manager_module_attribute gb_audio_module_vid_attribute = @@ -93,7 +93,7 @@ static struct gb_audio_manager_module_attribute gb_audio_module_vid_attribute = static ssize_t gb_audio_module_pid_show(struct gb_audio_manager_module *module, struct gb_audio_manager_module_attribute *attr, char *buf) { - return sysfs_emit(buf, "%d", module->desc.pid); + return sysfs_emit(buf, "%d\n", module->desc.pid); } static struct gb_audio_manager_module_attribute gb_audio_module_pid_attribute = @@ -103,7 +103,7 @@ static ssize_t gb_audio_module_intf_id_show(struct gb_audio_manager_module *modu struct gb_audio_manager_module_attribute *attr, char *buf) { - return sysfs_emit(buf, "%d", module->desc.intf_id); + return sysfs_emit(buf, "%d\n", module->desc.intf_id); } static struct gb_audio_manager_module_attribute @@ -114,7 +114,7 @@ static ssize_t gb_audio_module_ip_devices_show(struct gb_audio_manager_module *m struct gb_audio_manager_module_attribute *attr, char *buf) { - return sysfs_emit(buf, "0x%X", module->desc.ip_devices); + return sysfs_emit(buf, "0x%X\n", module->desc.ip_devices); } static struct gb_audio_manager_module_attribute @@ -125,7 +125,7 @@ static ssize_t gb_audio_module_op_devices_show(struct gb_audio_manager_module *m struct gb_audio_manager_module_attribute *attr, char *buf) { - return sysfs_emit(buf, "0x%X", module->desc.op_devices); + return sysfs_emit(buf, "0x%X\n", module->desc.op_devices); } static struct gb_audio_manager_module_attribute -- 2.43.0
2 weeks, 5 days
2
2
0
0
[PATCH] staging: greybus: audio_manager_module: Add missing newlines to sysfs_emit() formats
by Ronit Gupta
According to Documentation/filesystems/sysfs.rst, sysfs attribute values should terminate with a single newline character. Add missing trailing '\n' characters to the format strings of all sysfs_emit() calls in gb_audio_module_*_show() attribute callbacks. Signed-off-by: Ronit Gupta <ronitgupta138(a)gmail.com> --- drivers/staging/greybus/audio_manager_module.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/staging/greybus/audio_manager_module.c b/drivers/staging/greybus/audio_manager_module.c index dc90cc2d2..5737f2a32 100644 --- a/drivers/staging/greybus/audio_manager_module.c +++ b/drivers/staging/greybus/audio_manager_module.c @@ -75,7 +75,7 @@ static void gb_audio_module_release(struct kobject *kobj) static ssize_t gb_audio_module_name_show(struct gb_audio_manager_module *module, struct gb_audio_manager_module_attribute *attr, char *buf) { - return sysfs_emit(buf, "%s", module->desc.name); + return sysfs_emit(buf, "%s\n", module->desc.name); } static struct gb_audio_manager_module_attribute gb_audio_module_name_attribute = @@ -84,7 +84,7 @@ static struct gb_audio_manager_module_attribute gb_audio_module_name_attribute = static ssize_t gb_audio_module_vid_show(struct gb_audio_manager_module *module, struct gb_audio_manager_module_attribute *attr, char *buf) { - return sysfs_emit(buf, "%d", module->desc.vid); + return sysfs_emit(buf, "%d\n", module->desc.vid); } static struct gb_audio_manager_module_attribute gb_audio_module_vid_attribute = @@ -93,7 +93,7 @@ static struct gb_audio_manager_module_attribute gb_audio_module_vid_attribute = static ssize_t gb_audio_module_pid_show(struct gb_audio_manager_module *module, struct gb_audio_manager_module_attribute *attr, char *buf) { - return sysfs_emit(buf, "%d", module->desc.pid); + return sysfs_emit(buf, "%d\n", module->desc.pid); } static struct gb_audio_manager_module_attribute gb_audio_module_pid_attribute = @@ -103,7 +103,7 @@ static ssize_t gb_audio_module_intf_id_show(struct gb_audio_manager_module *modu struct gb_audio_manager_module_attribute *attr, char *buf) { - return sysfs_emit(buf, "%d", module->desc.intf_id); + return sysfs_emit(buf, "%d\n", module->desc.intf_id); } static struct gb_audio_manager_module_attribute @@ -114,7 +114,7 @@ static ssize_t gb_audio_module_ip_devices_show(struct gb_audio_manager_module *m struct gb_audio_manager_module_attribute *attr, char *buf) { - return sysfs_emit(buf, "0x%X", module->desc.ip_devices); + return sysfs_emit(buf, "0x%X\n", module->desc.ip_devices); } static struct gb_audio_manager_module_attribute @@ -125,7 +125,7 @@ static ssize_t gb_audio_module_op_devices_show(struct gb_audio_manager_module *m struct gb_audio_manager_module_attribute *attr, char *buf) { - return sysfs_emit(buf, "0x%X", module->desc.op_devices); + return sysfs_emit(buf, "0x%X\n", module->desc.op_devices); } static struct gb_audio_manager_module_attribute -- 2.43.0
2 weeks, 5 days
2
2
0
0
[PATCH] staging: greybus: audio_manager_module: Add missing newlines to sysfs_emit() formats
by Ronit Gupta
According to Documentation/filesystems/sysfs.rst, sysfs attribute values should terminate with a single newline character. Add missing trailing '\n' characters to the format strings of all sysfs_emit() calls in gb_audio_module_*_show() attribute callbacks. Signed-off-by: Ronit Gupta <ronitgupta138(a)gmail.com> --- drivers/staging/greybus/audio_manager_module.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/staging/greybus/audio_manager_module.c b/drivers/staging/greybus/audio_manager_module.c index dc90cc2d2..5737f2a32 100644 --- a/drivers/staging/greybus/audio_manager_module.c +++ b/drivers/staging/greybus/audio_manager_module.c @@ -75,7 +75,7 @@ static void gb_audio_module_release(struct kobject *kobj) static ssize_t gb_audio_module_name_show(struct gb_audio_manager_module *module, struct gb_audio_manager_module_attribute *attr, char *buf) { - return sysfs_emit(buf, "%s", module->desc.name); + return sysfs_emit(buf, "%s\n", module->desc.name); } static struct gb_audio_manager_module_attribute gb_audio_module_name_attribute = @@ -84,7 +84,7 @@ static struct gb_audio_manager_module_attribute gb_audio_module_name_attribute = static ssize_t gb_audio_module_vid_show(struct gb_audio_manager_module *module, struct gb_audio_manager_module_attribute *attr, char *buf) { - return sysfs_emit(buf, "%d", module->desc.vid); + return sysfs_emit(buf, "%d\n", module->desc.vid); } static struct gb_audio_manager_module_attribute gb_audio_module_vid_attribute = @@ -93,7 +93,7 @@ static struct gb_audio_manager_module_attribute gb_audio_module_vid_attribute = static ssize_t gb_audio_module_pid_show(struct gb_audio_manager_module *module, struct gb_audio_manager_module_attribute *attr, char *buf) { - return sysfs_emit(buf, "%d", module->desc.pid); + return sysfs_emit(buf, "%d\n", module->desc.pid); } static struct gb_audio_manager_module_attribute gb_audio_module_pid_attribute = @@ -103,7 +103,7 @@ static ssize_t gb_audio_module_intf_id_show(struct gb_audio_manager_module *modu static struct gb_audio_manager_module_attribute gb_audio_module_pid_attribute = @@ -103,7 +103,7 @@ static ssize_t gb_audio_module_intf_id_show(struct gb_audio_manager_module *modu struct gb_audio_manager_module_attribute *attr, char *buf) { - return sysfs_emit(buf, "%d", module->desc.intf_id); + return sysfs_emit(buf, "%d\n", module->desc.intf_id); } static struct gb_audio_manager_module_attribute @@ -114,7 +114,7 @@ static ssize_t gb_audio_module_ip_devices_show(struct gb_audio_manager_module *m struct gb_audio_manager_module_attribute *attr, char *buf) { - return sysfs_emit(buf, "0x%X", module->desc.ip_devices); + return sysfs_emit(buf, "0x%X\n", module->desc.ip_devices); } static struct gb_audio_manager_module_attribute @@ -125,7 +125,7 @@ static ssize_t gb_audio_module_op_devices_show(struct gb_audio_manager_module *m struct gb_audio_manager_module_attribute *attr, char *buf) { - return sysfs_emit(buf, "0x%X", module->desc.op_devices); + return sysfs_emit(buf, "0x%X\n", module->desc.op_devices); } static struct gb_audio_manager_module_attribute -- 2.43.0
2 weeks, 5 days
3
2
0
0
[PATCH] staging: greybus: audio_codec: fix stack overflow in stream name parsing
by Yudi Yang
intf_name and dir are 32-byte buffers. Parsing a module-provided AIF stream name with unbounded %s conversions can cause buffer-overwrites. Limit each conversion to 31 characters. Fixes: 60e7327d54b2 ("greybus: audio: Find data connection based on id") Cc: stable(a)vger.kernel.org Signed-off-by: Yudi Yang <2000jedi(a)gmail.com> --- drivers/staging/greybus/audio_codec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/greybus/audio_codec.c b/drivers/staging/greybus/audio_codec.c index 6daa4e706792..c3fefe1414f9 100644 --- a/drivers/staging/greybus/audio_codec.c +++ b/drivers/staging/greybus/audio_codec.c @@ -311,7 +311,7 @@ int gbaudio_module_update(struct gbaudio_codec_info *codec, } /* parse dai_id from AIF widget's stream_name */ - if (sscanf(w->sname, "%s %d %s", intf_name, &dai_id, dir) != 3) { + if (sscanf(w->sname, "%31s %d %31s", intf_name, &dai_id, dir) != 3) { dev_err(codec->dev, "Error while parsing dai_id for %s\n", w->name); return -EINVAL; } -- 2.43.0
2 weeks, 6 days
2
2
0
0
← Newer
1
2
3
4
Older →
Jump to page:
1
2
3
4
Results per page:
10
25
50
100
200