diff options
30 files changed, 84 insertions, 2781 deletions
@@ -1717,6 +1717,10 @@ S: Talstr. 1 S: D - 72072 Tuebingen S: Germany +N: Vaibhav Hiremath +E: hvaibhav.linux@gmail.com +D: Greybus Arche Platform driver + N: Richard Hirst E: richard@sleepie.demon.co.uk E: rhirst@linuxcare.com diff --git a/MAINTAINERS b/MAINTAINERS index cdb14794d326..e192cf26b757 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -11449,13 +11449,6 @@ M: Bryan O'Donoghue <pure.logic@nexus-software.ie> S: Maintained F: drivers/staging/greybus/loopback.c -GREYBUS PLATFORM DRIVERS -M: Vaibhav Hiremath <hvaibhav.linux@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@gmail.com> S: Maintained diff --git a/drivers/staging/axis-fifo/axis-fifo.c b/drivers/staging/axis-fifo/axis-fifo.c index 3d358f919352..7bb35e11d1dd 100644 --- a/drivers/staging/axis-fifo/axis-fifo.c +++ b/drivers/staging/axis-fifo/axis-fifo.c @@ -212,9 +212,9 @@ static ssize_t axis_fifo_write(struct file *f, const char __user *buf, size_t len, loff_t *off) { struct axis_fifo *fifo = f->private_data; - unsigned int words_to_write; + size_t words_to_write; u32 *txbuf; - int ret; + ssize_t ret; words_to_write = len / sizeof(u32); @@ -256,7 +256,7 @@ static ssize_t axis_fifo_write(struct file *f, const char __user *buf, goto end_unlock; } - for (int i = 0; i < words_to_write; ++i) + for (size_t i = 0; i < words_to_write; ++i) iowrite32(txbuf[i], fifo->base_addr + XLLF_TDFD_OFFSET); iowrite32(len, fifo->base_addr + XLLF_TLR_OFFSET); diff --git a/drivers/staging/fbtft/fb_bd663474.c b/drivers/staging/fbtft/fb_bd663474.c index 1629c2c440a9..c34f859043ef 100644 --- a/drivers/staging/fbtft/fb_bd663474.c +++ b/drivers/staging/fbtft/fb_bd663474.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0+ /* - * FB driver for the uPD161704 LCD Controller + * FB driver for the BD663474 LCD Controller * * Copyright (C) 2014 Seong-Woo Kim * @@ -166,6 +166,6 @@ MODULE_ALIAS("platform:" DRVNAME); MODULE_ALIAS("spi:bd663474"); MODULE_ALIAS("platform:bd663474"); -MODULE_DESCRIPTION("FB driver for the uPD161704 LCD Controller"); +MODULE_DESCRIPTION("FB driver for the BD663474 LCD Controller"); MODULE_AUTHOR("Seong-Woo Kim"); MODULE_LICENSE("GPL"); diff --git a/drivers/staging/fbtft/fbtft.h b/drivers/staging/fbtft/fbtft.h index c7afb0fd3943..40a7567df1eb 100644 --- a/drivers/staging/fbtft/fbtft.h +++ b/drivers/staging/fbtft/fbtft.h @@ -37,7 +37,7 @@ struct fbtft_par; * @write: Writes to interface bus * @read: Reads from interface bus * @write_vmem: Writes video memory to display - * @write_reg: Writes to controller register + * @write_register: Writes to controller register * @set_addr_win: Set the GRAM update window * @reset: Reset the LCD controller * @mkdirty: Marks display lines for update @@ -46,7 +46,6 @@ struct fbtft_par; * @blank: Blank the display (optional) * @request_gpios_match: Do pinname to gpio matching * @request_gpios: Request gpios from the kernel - * @free_gpios: Free previously requested gpios * @verify_gpios: Verify that necessary gpios is present (optional) * @register_backlight: Used to register backlight device (optional) * @unregister_backlight: Unregister backlight device (optional) diff --git a/drivers/staging/greybus/Kconfig b/drivers/staging/greybus/Kconfig index 7635f3e850fa..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 @@ -204,13 +194,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..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 @@ -65,9 +63,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/TODO b/drivers/staging/greybus/TODO deleted file mode 100644 index e69de29bb2d1..000000000000 --- a/drivers/staging/greybus/TODO +++ /dev/null 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@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 */ 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/firmware.h b/drivers/staging/greybus/firmware.h index 5d2564462ffc..04a67d2d5b8f 100644 --- a/drivers/staging/greybus/firmware.h +++ b/drivers/staging/greybus/firmware.h @@ -22,7 +22,6 @@ /* Firmware Management Protocol specific functions */ int fw_mgmt_init(void); void fw_mgmt_exit(void); -struct gb_connection *to_fw_mgmt_connection(struct device *dev); int gb_fw_mgmt_request_handler(struct gb_operation *op); int gb_fw_mgmt_connection_init(struct gb_connection *connection); void gb_fw_mgmt_connection_exit(struct gb_connection *connection); diff --git a/drivers/staging/greybus/fw-core.c b/drivers/staging/greybus/fw-core.c index 2016a74f137f..46b35ef55090 100644 --- a/drivers/staging/greybus/fw-core.c +++ b/drivers/staging/greybus/fw-core.c @@ -21,13 +21,6 @@ struct gb_fw_core { static struct spilib_ops *spilib_ops; -struct gb_connection *to_fw_mgmt_connection(struct device *dev) -{ - struct gb_fw_core *fw_core = dev_get_drvdata(dev); - - return fw_core->mgmt_connection; -} - static int gb_fw_spi_connection_init(struct gb_connection *connection) { int ret; @@ -93,8 +86,8 @@ static int gb_fw_core_probe(struct gb_bundle *bundle, if (IS_ERR(connection)) { ret = PTR_ERR(connection); dev_err(&bundle->dev, - "failed to create management connection (%d)\n", - ret); + "failed to create management connection (%pe)\n", + connection); goto err_destroy_connections; } @@ -112,8 +105,8 @@ static int gb_fw_core_probe(struct gb_bundle *bundle, connection = gb_connection_create(bundle, cport_id, gb_fw_download_request_handler); if (IS_ERR(connection)) { - dev_err(&bundle->dev, "failed to create download connection (%ld)\n", - PTR_ERR(connection)); + dev_err(&bundle->dev, "failed to create download connection (%pe)\n", + connection); } else { fw_core->download_connection = connection; } @@ -131,8 +124,8 @@ static int gb_fw_core_probe(struct gb_bundle *bundle, connection = gb_connection_create(bundle, cport_id, NULL); if (IS_ERR(connection)) { - dev_err(&bundle->dev, "failed to create SPI connection (%ld)\n", - PTR_ERR(connection)); + dev_err(&bundle->dev, "failed to create SPI connection (%pe)\n", + connection); } else { fw_core->spi_connection = connection; } @@ -149,8 +142,8 @@ static int gb_fw_core_probe(struct gb_bundle *bundle, connection = gb_connection_create(bundle, cport_id, NULL); if (IS_ERR(connection)) { - dev_err(&bundle->dev, "failed to create Authentication connection (%ld)\n", - PTR_ERR(connection)); + dev_err(&bundle->dev, "failed to create Authentication connection (%pe)\n", + connection); } else { fw_core->cap_connection = connection; } 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 */ diff --git a/drivers/staging/greybus/gbphy.c b/drivers/staging/greybus/gbphy.c index bdb0f5164a6f..bb9a5b538e6e 100644 --- a/drivers/staging/greybus/gbphy.c +++ b/drivers/staging/greybus/gbphy.c @@ -31,7 +31,7 @@ static ssize_t protocol_id_show(struct device *dev, { struct gbphy_device *gbphy_dev = to_gbphy_dev(dev); - return sprintf(buf, "0x%02x\n", gbphy_dev->cport_desc->protocol_id); + return sysfs_emit(buf, "0x%02x\n", gbphy_dev->cport_desc->protocol_id); } static DEVICE_ATTR_RO(protocol_id); diff --git a/drivers/staging/greybus/loopback.c b/drivers/staging/greybus/loopback.c index 2a623fc2e99b..efc69c10cffe 100644 --- a/drivers/staging/greybus/loopback.c +++ b/drivers/staging/greybus/loopback.c @@ -562,8 +562,7 @@ static int gb_loopback_async_sink(struct gb_loopback *gb, u32 len) return retval; } -static int gb_loopback_async_transfer_complete( - struct gb_loopback_async_operation *op_async) +static int gb_loopback_async_transfer_complete(struct gb_loopback_async_operation *op_async) { struct gb_loopback *gb; struct gb_operation *operation; @@ -653,7 +652,8 @@ static int gb_loopback_request_handler(struct gb_operation *operation) } if (!gb_operation_response_alloc(operation, - len + sizeof(*response), GFP_KERNEL)) { + len + sizeof(*response), + GFP_KERNEL)) { dev_err(dev, "error allocating response\n"); return -ENOMEM; } diff --git a/drivers/staging/greybus/power_supply.c b/drivers/staging/greybus/power_supply.c index 44bd8a72fa50..beefcbaf3681 100644 --- a/drivers/staging/greybus/power_supply.c +++ b/drivers/staging/greybus/power_supply.c @@ -377,12 +377,8 @@ static void gb_power_supply_state_change(struct gb_power_supply *gbpsy, gbpsy->pm_acquired = true; } else { if (gbpsy->pm_acquired) { - ret = gb_pm_runtime_put_autosuspend(connection->bundle); - if (ret) - dev_err(&connection->bundle->dev, - "Fail to set wake unlock for none charging\n"); - else - gbpsy->pm_acquired = false; + gb_pm_runtime_put_autosuspend(connection->bundle); + gbpsy->pm_acquired = false; } } diff --git a/drivers/staging/greybus/spilib.c b/drivers/staging/greybus/spilib.c index e4d1ae8308aa..c1982f3fb931 100644 --- a/drivers/staging/greybus/spilib.c +++ b/drivers/staging/greybus/spilib.c @@ -160,7 +160,8 @@ static struct spi_transfer *get_next_xfer(struct spi_transfer *xfer, /* Routines to transfer data */ static struct gb_operation *gb_spi_operation_create(struct gb_spilib *spi, - struct gb_connection *connection, struct spi_message *msg) + struct gb_connection *connection, + struct spi_message *msg) { struct gb_spi_transfer_request *request; struct spi_device *dev = msg->spi; diff --git a/drivers/staging/greybus/uart.c b/drivers/staging/greybus/uart.c index 172cf900eaf0..e1b73db6a17c 100644 --- a/drivers/staging/greybus/uart.c +++ b/drivers/staging/greybus/uart.c @@ -53,7 +53,6 @@ struct gb_tty { spinlock_t read_lock; spinlock_t write_lock; struct async_icount iocount; - struct async_icount oldcount; wait_queue_head_t wioctl; struct mutex mutex; u8 ctrlin; /* input control lines */ @@ -318,7 +317,7 @@ static int gb_uart_wait_for_all_credits(struct gb_tty *gb_tty) return 0; ret = wait_for_completion_timeout(&gb_tty->credits_complete, - msecs_to_jiffies(GB_UART_CREDIT_WAIT_TIMEOUT_MSEC)); + msecs_to_jiffies(GB_UART_CREDIT_WAIT_TIMEOUT_MSEC)); if (!ret) { dev_err(&gb_tty->gbphy_dev->dev, "time out waiting for credits\n"); @@ -643,11 +642,16 @@ static int wait_serial_change(struct gb_tty *gb_tty, unsigned long arg) if (!(arg & (TIOCM_DSR | TIOCM_RI | TIOCM_CD))) return -EINVAL; - do { + spin_lock_irq(&gb_tty->read_lock); + old = gb_tty->iocount; + spin_unlock_irq(&gb_tty->read_lock); + + add_wait_queue(&gb_tty->wioctl, &wait); + for (;;) { + set_current_state(TASK_INTERRUPTIBLE); + spin_lock_irq(&gb_tty->read_lock); - old = gb_tty->oldcount; new = gb_tty->iocount; - gb_tty->oldcount = new; spin_unlock_irq(&gb_tty->read_lock); if ((arg & TIOCM_DSR) && (old.dsr != new.dsr)) @@ -657,18 +661,20 @@ static int wait_serial_change(struct gb_tty *gb_tty, unsigned long arg) if ((arg & TIOCM_RI) && (old.rng != new.rng)) break; - add_wait_queue(&gb_tty->wioctl, &wait); - set_current_state(TASK_INTERRUPTIBLE); - schedule(); - remove_wait_queue(&gb_tty->wioctl, &wait); if (gb_tty->disconnected) { - if (arg & TIOCM_CD) - break; retval = -ENODEV; - } else if (signal_pending(current)) { + break; + } + + schedule(); + + if (signal_pending(current)) { retval = -ERESTARTSYS; + break; } - } while (!retval); + } + __set_current_state(TASK_RUNNING); + remove_wait_queue(&gb_tty->wioctl, &wait); return retval; } diff --git a/drivers/staging/most/Documentation/driver_usage.txt b/drivers/staging/most/Documentation/driver_usage.txt index f1b6977f4543..32a2e5ecb48b 100644 --- a/drivers/staging/most/Documentation/driver_usage.txt +++ b/drivers/staging/most/Documentation/driver_usage.txt @@ -109,7 +109,7 @@ following components are available driver via the V4L subsystem. 4) Advanced Linux Sound Architecture (ALSA) - Standard sound applications (e.g. aplay, arecord, audacity) can by + Standard sound applications (e.g. aplay, arecord, audacity) can be used to access the driver via the ALSA subsystem. diff --git a/drivers/staging/most/video/video.c b/drivers/staging/most/video/video.c index 88892b5db28b..3a0445ff62f4 100644 --- a/drivers/staging/most/video/video.c +++ b/drivers/staging/most/video/video.c @@ -439,7 +439,6 @@ static int comp_register_videodev(struct most_video_dev *mdev) mdev->vdev->release = video_device_release; return 0; - } static void comp_unregister_videodev(struct most_video_dev *mdev) diff --git a/drivers/staging/nvec/nvec.h b/drivers/staging/nvec/nvec.h index 80c0353f141c..5ef959352338 100644 --- a/drivers/staging/nvec/nvec.h +++ b/drivers/staging/nvec/nvec.h @@ -102,7 +102,7 @@ struct nvec_msg { /** * struct nvec_chip - A single connection to an NVIDIA Embedded controller * @dev: The device - * @gpio: The same as for &struct nvec_platform_data + * @gpiod: GPIO descriptor for the embedded controller request line * @irq: The IRQ of the I2C device * @i2c_addr: The address of the I2C slave * @base: The base of the memory mapped region of the I2C device diff --git a/drivers/staging/octeon/ethernet-tx.c b/drivers/staging/octeon/ethernet-tx.c index cc20c1e6791f..5e536827f87a 100644 --- a/drivers/staging/octeon/ethernet-tx.c +++ b/drivers/staging/octeon/ethernet-tx.c @@ -481,7 +481,7 @@ skip_xmit: cvmx_fau_fetch_and_add32(FAU_TOTAL_TX_TO_CLEAN, 1); } - if (total_to_clean & 0x3ff) { + if ((total_to_clean & 0x3ff) == 0) { /* * Schedule the cleanup tasklet every 1024 packets for * the pathological case of high traffic on one port diff --git a/drivers/staging/octeon/octeon-ethernet.h b/drivers/staging/octeon/octeon-ethernet.h index 0ac430db1e6e..de27fae47931 100644 --- a/drivers/staging/octeon/octeon-ethernet.h +++ b/drivers/staging/octeon/octeon-ethernet.h @@ -43,7 +43,7 @@ #endif -/** +/* * This is the definition of the Ethernet driver's private * driver state stored in netdev_priv(dev). */ diff --git a/drivers/staging/sm750fb/sm750.c b/drivers/staging/sm750fb/sm750.c index 8b93bfeb217b..21e310274330 100644 --- a/drivers/staging/sm750fb/sm750.c +++ b/drivers/staging/sm750fb/sm750.c @@ -13,7 +13,7 @@ static int g_hwcursor = 1; static int g_noaccel __ro_after_init; static int g_nomtrr __ro_after_init; static const char *g_fbmode[] = {NULL, NULL}; -static const char *g_def_fbmode = "1024x768-32@60"; +static const char * const g_def_fbmode = "1024x768-32@60"; static char *g_settings; static int g_dualview __ro_after_init; static char *g_option; @@ -384,7 +384,7 @@ static inline unsigned int chan_to_field(unsigned int chan, return chan << bf->offset; } -static int __maybe_unused lynxfb_suspend(struct device *dev) +static int lynxfb_suspend(struct device *dev) { struct fb_info *info; struct sm750_dev *sm750_dev; @@ -405,7 +405,7 @@ static int __maybe_unused lynxfb_suspend(struct device *dev) return 0; } -static int __maybe_unused lynxfb_resume(struct device *dev) +static int lynxfb_resume(struct device *dev) { struct pci_dev *pdev = to_pci_dev(dev); struct fb_info *info; @@ -479,7 +479,7 @@ static int lynxfb_ops_check_var(struct fb_var_screeninfo *var, /* check if current fb's video memory big enough to hold the onscreen*/ request = var->xres_virtual * (var->bits_per_pixel >> 3); - /* defaulty crtc->channel go with par->index */ + /* default crtc->channel go with par->index */ request = ALIGN(request, crtc->line_pad); request = request * var->yres_virtual; @@ -825,6 +825,11 @@ exit: return ret; } +static void lynxfb_unset_fbinfo(struct fb_info *info) +{ + fb_dealloc_cmap(&info->cmap); +} + /* chip specific g_option configuration routine */ static void sm750fb_setup(struct sm750_dev *sm750_dev, char *src) { @@ -910,6 +915,7 @@ static void sm750fb_framebuffer_release(struct sm750_dev *sm750_dev) while (sm750_dev->fb_count) { fb_info = sm750_dev->fbinfo[sm750_dev->fb_count - 1]; unregister_framebuffer(fb_info); + lynxfb_unset_fbinfo(fb_info); framebuffer_release(fb_info); sm750_dev->fb_count--; } @@ -936,12 +942,14 @@ static int sm750fb_framebuffer_alloc(struct sm750_dev *sm750_dev, int fbidx) err = register_framebuffer(fb_info); if (err < 0) - goto release_fb; + goto unset_fb; sm750_dev->fb_count++; return 0; +unset_fb: + lynxfb_unset_fbinfo(fb_info); release_fb: framebuffer_release(fb_info); return err; @@ -1094,14 +1102,14 @@ static const struct pci_device_id smi_pci_table[] = { MODULE_DEVICE_TABLE(pci, smi_pci_table); -static SIMPLE_DEV_PM_OPS(lynxfb_pm_ops, lynxfb_suspend, lynxfb_resume); +static DEFINE_SIMPLE_DEV_PM_OPS(lynxfb_pm_ops, lynxfb_suspend, lynxfb_resume); static struct pci_driver lynxfb_driver = { .name = "sm750fb", .id_table = smi_pci_table, .probe = lynxfb_pci_probe, .remove = lynxfb_pci_remove, - .driver.pm = &lynxfb_pm_ops, + .driver.pm = pm_sleep_ptr(&lynxfb_pm_ops), }; static int __init lynxfb_init(void) diff --git a/drivers/staging/sm750fb/sm750_accel.h b/drivers/staging/sm750fb/sm750_accel.h index efceefaaafb0..6db54c6526dc 100644 --- a/drivers/staging/sm750fb/sm750_accel.h +++ b/drivers/staging/sm750fb/sm750_accel.h @@ -195,7 +195,8 @@ int sm750_hw_fillrect(struct lynx_accel *accel, u32 color, u32 rop); /** - * sm750_hm_copyarea + * sm750_hw_copyarea + * @accel: Acceleration device data * @source_base: Address of source: offset in frame buffer * @source_pitch: Pitch value of source surface in BYTE * @sx: Starting x coordinate of source surface @@ -219,6 +220,7 @@ int sm750_hw_copyarea(struct lynx_accel *accel, /** * sm750_hw_imageblit + * @accel: Acceleration device data * @src_buf: pointer to start of source buffer in system memory * @start_bit: Mono data can start at any bit in a byte, this value should be *>----- 0 to 7 diff --git a/drivers/staging/vme_user/vme.c b/drivers/staging/vme_user/vme.c index b5c66b66ce32..d38c792eb890 100644 --- a/drivers/staging/vme_user/vme.c +++ b/drivers/staging/vme_user/vme.c @@ -298,9 +298,9 @@ struct vme_resource *vme_slave_request(struct vme_dev *vdev, u32 address, err_alloc: /* Unlock image */ - mutex_lock(&slave_image->mtx); - slave_image->locked = 0; - mutex_unlock(&slave_image->mtx); + mutex_lock(&allocated_image->mtx); + allocated_image->locked = 0; + mutex_unlock(&allocated_image->mtx); err_image: err_bus: return NULL; @@ -495,9 +495,9 @@ struct vme_resource *vme_master_request(struct vme_dev *vdev, u32 address, err_alloc: /* Unlock image */ - spin_lock(&master_image->lock); - master_image->locked = 0; - spin_unlock(&master_image->lock); + spin_lock(&allocated_image->lock); + allocated_image->locked = 0; + spin_unlock(&allocated_image->lock); err_image: err_bus: return NULL; @@ -865,9 +865,9 @@ struct vme_resource *vme_dma_request(struct vme_dev *vdev, u32 route) err_alloc: /* Unlock image */ - mutex_lock(&dma_ctrlr->mtx); - dma_ctrlr->locked = 0; - mutex_unlock(&dma_ctrlr->mtx); + mutex_lock(&allocated_ctrlr->mtx); + allocated_ctrlr->locked = 0; + mutex_unlock(&allocated_ctrlr->mtx); err_ctrlr: err_bus: return NULL; @@ -1469,9 +1469,9 @@ struct vme_resource *vme_lm_request(struct vme_dev *vdev) err_alloc: /* Unlock image */ - mutex_lock(&lm->mtx); - lm->locked = 0; - mutex_unlock(&lm->mtx); + mutex_lock(&allocated_lm->mtx); + allocated_lm->locked = 0; + mutex_unlock(&allocated_lm->mtx); err_lm: err_bus: return NULL; diff --git a/drivers/staging/vme_user/vme_tsi148.c b/drivers/staging/vme_user/vme_tsi148.c index c695ad9b4ca2..9447c00bc013 100644 --- a/drivers/staging/vme_user/vme_tsi148.c +++ b/drivers/staging/vme_user/vme_tsi148.c @@ -26,6 +26,7 @@ #include <linux/io.h> #include <linux/uaccess.h> #include <linux/byteorder/generic.h> +#include <linux/string_choices.h> #include "vme.h" #include "vme_bridge.h" @@ -2458,7 +2459,7 @@ static int tsi148_probe(struct pci_dev *pdev, const struct pci_device_id *id) geoid); dev_info(&pdev->dev, "VME Write and flush and error check is %s\n", - err_chk ? "enabled" : "disabled"); + str_enabled_disabled(err_chk)); retval = tsi148_crcsr_init(tsi148_bridge, pdev); if (retval) { diff --git a/include/linux/greybus/bundle.h b/include/linux/greybus/bundle.h index df8d88424cb7..361a94d3499b 100644 --- a/include/linux/greybus/bundle.h +++ b/include/linux/greybus/bundle.h @@ -59,14 +59,9 @@ static inline int gb_pm_runtime_get_sync(struct gb_bundle *bundle) return 0; } -static inline int gb_pm_runtime_put_autosuspend(struct gb_bundle *bundle) +static inline void gb_pm_runtime_put_autosuspend(struct gb_bundle *bundle) { - int retval; - - pm_runtime_mark_last_busy(&bundle->dev); - retval = pm_runtime_put_autosuspend(&bundle->dev); - - return retval; + pm_runtime_put_autosuspend(&bundle->dev); } static inline void gb_pm_runtime_get_noresume(struct gb_bundle *bundle) @@ -82,8 +77,7 @@ static inline void gb_pm_runtime_put_noidle(struct gb_bundle *bundle) #else static inline int gb_pm_runtime_get_sync(struct gb_bundle *bundle) { return 0; } -static inline int gb_pm_runtime_put_autosuspend(struct gb_bundle *bundle) -{ return 0; } +static inline void gb_pm_runtime_put_autosuspend(struct gb_bundle *bundle) {} static inline void gb_pm_runtime_get_noresume(struct gb_bundle *bundle) {} static inline void gb_pm_runtime_put_noidle(struct gb_bundle *bundle) {} |
