mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-05 10:31:46 +09:00
Merge ac18d78146 ("media: uvcvideo: Remove dangling pointers") into android14-6.1-lts
Steps on the way to 6.1.130 Resolves merge conflicts in: drivers/bluetooth/btqca.c Change-Id: I8e563e9814854b55f5ee133f4ae72d59659161a8 Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
This commit is contained in:
@@ -1753,6 +1753,7 @@
|
|||||||
resets = <&mmsys MT8183_MMSYS_SW0_RST_B_DISP_DSI0>;
|
resets = <&mmsys MT8183_MMSYS_SW0_RST_B_DISP_DSI0>;
|
||||||
phys = <&mipi_tx0>;
|
phys = <&mipi_tx0>;
|
||||||
phy-names = "dphy";
|
phy-names = "dphy";
|
||||||
|
status = "disabled";
|
||||||
};
|
};
|
||||||
|
|
||||||
mutex: mutex@14016000 {
|
mutex: mutex@14016000 {
|
||||||
|
|||||||
@@ -2226,7 +2226,7 @@
|
|||||||
|
|
||||||
cdsp: remoteproc@98900000 {
|
cdsp: remoteproc@98900000 {
|
||||||
compatible = "qcom,sm8350-cdsp-pas";
|
compatible = "qcom,sm8350-cdsp-pas";
|
||||||
reg = <0 0x098900000 0 0x1400000>;
|
reg = <0 0x98900000 0 0x1400000>;
|
||||||
|
|
||||||
interrupts-extended = <&intc GIC_SPI 578 IRQ_TYPE_LEVEL_HIGH>,
|
interrupts-extended = <&intc GIC_SPI 578 IRQ_TYPE_LEVEL_HIGH>,
|
||||||
<&smp2p_cdsp_in 0 IRQ_TYPE_EDGE_RISING>,
|
<&smp2p_cdsp_in 0 IRQ_TYPE_EDGE_RISING>,
|
||||||
|
|||||||
@@ -2093,7 +2093,7 @@
|
|||||||
|
|
||||||
remoteproc_adsp: remoteproc@30000000 {
|
remoteproc_adsp: remoteproc@30000000 {
|
||||||
compatible = "qcom,sm8450-adsp-pas";
|
compatible = "qcom,sm8450-adsp-pas";
|
||||||
reg = <0 0x030000000 0 0x100>;
|
reg = <0 0x30000000 0 0x100>;
|
||||||
|
|
||||||
interrupts-extended = <&pdc 6 IRQ_TYPE_EDGE_RISING>,
|
interrupts-extended = <&pdc 6 IRQ_TYPE_EDGE_RISING>,
|
||||||
<&smp2p_adsp_in 0 IRQ_TYPE_EDGE_RISING>,
|
<&smp2p_adsp_in 0 IRQ_TYPE_EDGE_RISING>,
|
||||||
@@ -2159,7 +2159,7 @@
|
|||||||
|
|
||||||
remoteproc_cdsp: remoteproc@32300000 {
|
remoteproc_cdsp: remoteproc@32300000 {
|
||||||
compatible = "qcom,sm8450-cdsp-pas";
|
compatible = "qcom,sm8450-cdsp-pas";
|
||||||
reg = <0 0x032300000 0 0x1400000>;
|
reg = <0 0x32300000 0 0x10000>;
|
||||||
|
|
||||||
interrupts-extended = <&intc GIC_SPI 578 IRQ_TYPE_EDGE_RISING>,
|
interrupts-extended = <&intc GIC_SPI 578 IRQ_TYPE_EDGE_RISING>,
|
||||||
<&smp2p_cdsp_in 0 IRQ_TYPE_EDGE_RISING>,
|
<&smp2p_cdsp_in 0 IRQ_TYPE_EDGE_RISING>,
|
||||||
|
|||||||
@@ -246,6 +246,39 @@ int qca_send_pre_shutdown_cmd(struct hci_dev *hdev)
|
|||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(qca_send_pre_shutdown_cmd);
|
EXPORT_SYMBOL_GPL(qca_send_pre_shutdown_cmd);
|
||||||
|
|
||||||
|
static bool qca_filename_has_extension(const char *filename)
|
||||||
|
{
|
||||||
|
const char *suffix = strrchr(filename, '.');
|
||||||
|
|
||||||
|
/* File extensions require a dot, but not as the first or last character */
|
||||||
|
if (!suffix || suffix == filename || *(suffix + 1) == '\0')
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* Avoid matching directories with names that look like files with extensions */
|
||||||
|
return !strchr(suffix, '/');
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool qca_get_alt_nvm_file(char *filename, size_t max_size)
|
||||||
|
{
|
||||||
|
char fwname[64];
|
||||||
|
const char *suffix;
|
||||||
|
|
||||||
|
/* nvm file name has an extension, replace with .bin */
|
||||||
|
if (qca_filename_has_extension(filename)) {
|
||||||
|
suffix = strrchr(filename, '.');
|
||||||
|
strscpy(fwname, filename, suffix - filename + 1);
|
||||||
|
snprintf(fwname + (suffix - filename),
|
||||||
|
sizeof(fwname) - (suffix - filename), ".bin");
|
||||||
|
/* If nvm file is already the default one, return false to skip the retry. */
|
||||||
|
if (strcmp(fwname, filename) == 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
snprintf(filename, max_size, "%s", fwname);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
static int qca_tlv_check_data(struct hci_dev *hdev,
|
static int qca_tlv_check_data(struct hci_dev *hdev,
|
||||||
struct qca_fw_config *config,
|
struct qca_fw_config *config,
|
||||||
u8 *fw_data, size_t fw_size,
|
u8 *fw_data, size_t fw_size,
|
||||||
@@ -543,6 +576,19 @@ static int qca_download_firmware(struct hci_dev *hdev,
|
|||||||
config->fwname, ret);
|
config->fwname, ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
/* If the board-specific file is missing, try loading the default
|
||||||
|
* one, unless that was attempted already.
|
||||||
|
*/
|
||||||
|
else if (config->type == TLV_TYPE_NVM &&
|
||||||
|
qca_get_alt_nvm_file(config->fwname, sizeof(config->fwname))) {
|
||||||
|
bt_dev_info(hdev, "QCA Downloading %s", config->fwname);
|
||||||
|
ret = request_firmware(&fw, config->fwname, &hdev->dev);
|
||||||
|
if (ret) {
|
||||||
|
bt_dev_err(hdev, "QCA Failed to request file: %s (%d)",
|
||||||
|
config->fwname, ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
bt_dev_err(hdev, "QCA Failed to request file: %s (%d)",
|
bt_dev_err(hdev, "QCA Failed to request file: %s (%d)",
|
||||||
config->fwname, ret);
|
config->fwname, ret);
|
||||||
|
|||||||
@@ -14,6 +14,7 @@
|
|||||||
* Access to the event log extended by the TCG BIOS of PC platform
|
* Access to the event log extended by the TCG BIOS of PC platform
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <linux/device.h>
|
||||||
#include <linux/seq_file.h>
|
#include <linux/seq_file.h>
|
||||||
#include <linux/fs.h>
|
#include <linux/fs.h>
|
||||||
#include <linux/security.h>
|
#include <linux/security.h>
|
||||||
@@ -62,6 +63,11 @@ static bool tpm_is_tpm2_log(void *bios_event_log, u64 len)
|
|||||||
return n == 0;
|
return n == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void tpm_bios_log_free(void *data)
|
||||||
|
{
|
||||||
|
kvfree(data);
|
||||||
|
}
|
||||||
|
|
||||||
/* read binary bios log */
|
/* read binary bios log */
|
||||||
int tpm_read_log_acpi(struct tpm_chip *chip)
|
int tpm_read_log_acpi(struct tpm_chip *chip)
|
||||||
{
|
{
|
||||||
@@ -135,7 +141,7 @@ int tpm_read_log_acpi(struct tpm_chip *chip)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* malloc EventLog space */
|
/* malloc EventLog space */
|
||||||
log->bios_event_log = kmalloc(len, GFP_KERNEL);
|
log->bios_event_log = kvmalloc(len, GFP_KERNEL);
|
||||||
if (!log->bios_event_log)
|
if (!log->bios_event_log)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
@@ -161,10 +167,16 @@ int tpm_read_log_acpi(struct tpm_chip *chip)
|
|||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ret = devm_add_action(&chip->dev, tpm_bios_log_free, log->bios_event_log);
|
||||||
|
if (ret) {
|
||||||
|
log->bios_event_log = NULL;
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
return format;
|
return format;
|
||||||
|
|
||||||
err:
|
err:
|
||||||
kfree(log->bios_event_log);
|
tpm_bios_log_free(log->bios_event_log);
|
||||||
log->bios_event_log = NULL;
|
log->bios_event_log = NULL;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
* Thiebaud Weksteen <tweek@google.com>
|
* Thiebaud Weksteen <tweek@google.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <linux/device.h>
|
||||||
#include <linux/efi.h>
|
#include <linux/efi.h>
|
||||||
#include <linux/tpm_eventlog.h>
|
#include <linux/tpm_eventlog.h>
|
||||||
|
|
||||||
@@ -55,7 +56,7 @@ int tpm_read_log_efi(struct tpm_chip *chip)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* malloc EventLog space */
|
/* malloc EventLog space */
|
||||||
log->bios_event_log = kmemdup(log_tbl->log, log_size, GFP_KERNEL);
|
log->bios_event_log = devm_kmemdup(&chip->dev, log_tbl->log, log_size, GFP_KERNEL);
|
||||||
if (!log->bios_event_log) {
|
if (!log->bios_event_log) {
|
||||||
ret = -ENOMEM;
|
ret = -ENOMEM;
|
||||||
goto out;
|
goto out;
|
||||||
@@ -76,7 +77,7 @@ int tpm_read_log_efi(struct tpm_chip *chip)
|
|||||||
MEMREMAP_WB);
|
MEMREMAP_WB);
|
||||||
if (!final_tbl) {
|
if (!final_tbl) {
|
||||||
pr_err("Could not map UEFI TPM final log\n");
|
pr_err("Could not map UEFI TPM final log\n");
|
||||||
kfree(log->bios_event_log);
|
devm_kfree(&chip->dev, log->bios_event_log);
|
||||||
ret = -ENOMEM;
|
ret = -ENOMEM;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
@@ -91,11 +92,11 @@ int tpm_read_log_efi(struct tpm_chip *chip)
|
|||||||
* Allocate memory for the 'combined log' where we will append the
|
* Allocate memory for the 'combined log' where we will append the
|
||||||
* 'final events log' to.
|
* 'final events log' to.
|
||||||
*/
|
*/
|
||||||
tmp = krealloc(log->bios_event_log,
|
tmp = devm_krealloc(&chip->dev, log->bios_event_log,
|
||||||
log_size + final_events_log_size,
|
log_size + final_events_log_size,
|
||||||
GFP_KERNEL);
|
GFP_KERNEL);
|
||||||
if (!tmp) {
|
if (!tmp) {
|
||||||
kfree(log->bios_event_log);
|
devm_kfree(&chip->dev, log->bios_event_log);
|
||||||
ret = -ENOMEM;
|
ret = -ENOMEM;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
* Read the event log created by the firmware on PPC64
|
* Read the event log created by the firmware on PPC64
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <linux/device.h>
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
#include <linux/of.h>
|
#include <linux/of.h>
|
||||||
#include <linux/tpm_eventlog.h>
|
#include <linux/tpm_eventlog.h>
|
||||||
@@ -65,7 +66,7 @@ int tpm_read_log_of(struct tpm_chip *chip)
|
|||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
log->bios_event_log = kmemdup(__va(base), size, GFP_KERNEL);
|
log->bios_event_log = devm_kmemdup(&chip->dev, __va(base), size, GFP_KERNEL);
|
||||||
if (!log->bios_event_log)
|
if (!log->bios_event_log)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
|
|||||||
@@ -267,7 +267,6 @@ static void tpm_dev_release(struct device *dev)
|
|||||||
idr_remove(&dev_nums_idr, chip->dev_num);
|
idr_remove(&dev_nums_idr, chip->dev_num);
|
||||||
mutex_unlock(&idr_lock);
|
mutex_unlock(&idr_lock);
|
||||||
|
|
||||||
kfree(chip->log.bios_event_log);
|
|
||||||
kfree(chip->work_space.context_buf);
|
kfree(chip->work_space.context_buf);
|
||||||
kfree(chip->work_space.session_buf);
|
kfree(chip->work_space.session_buf);
|
||||||
kfree(chip->allocated_banks);
|
kfree(chip->allocated_banks);
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ static const struct mtk_gate_regs bdp1_cg_regs = {
|
|||||||
GATE_MTK(_id, _name, _parent, &bdp1_cg_regs, _shift, &mtk_clk_gate_ops_setclr_inv)
|
GATE_MTK(_id, _name, _parent, &bdp1_cg_regs, _shift, &mtk_clk_gate_ops_setclr_inv)
|
||||||
|
|
||||||
static const struct mtk_gate bdp_clks[] = {
|
static const struct mtk_gate bdp_clks[] = {
|
||||||
|
GATE_DUMMY(CLK_DUMMY, "bdp_dummy"),
|
||||||
GATE_BDP0(CLK_BDP_BRG_BA, "brg_baclk", "mm_sel", 0),
|
GATE_BDP0(CLK_BDP_BRG_BA, "brg_baclk", "mm_sel", 0),
|
||||||
GATE_BDP0(CLK_BDP_BRG_DRAM, "brg_dram", "mm_sel", 1),
|
GATE_BDP0(CLK_BDP_BRG_DRAM, "brg_dram", "mm_sel", 1),
|
||||||
GATE_BDP0(CLK_BDP_LARB_DRAM, "larb_dram", "mm_sel", 2),
|
GATE_BDP0(CLK_BDP_LARB_DRAM, "larb_dram", "mm_sel", 2),
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ static const struct mtk_gate_regs img_cg_regs = {
|
|||||||
GATE_MTK(_id, _name, _parent, &img_cg_regs, _shift, &mtk_clk_gate_ops_setclr)
|
GATE_MTK(_id, _name, _parent, &img_cg_regs, _shift, &mtk_clk_gate_ops_setclr)
|
||||||
|
|
||||||
static const struct mtk_gate img_clks[] = {
|
static const struct mtk_gate img_clks[] = {
|
||||||
|
GATE_DUMMY(CLK_DUMMY, "img_dummy"),
|
||||||
GATE_IMG(CLK_IMG_SMI_COMM, "img_smi_comm", "mm_sel", 0),
|
GATE_IMG(CLK_IMG_SMI_COMM, "img_smi_comm", "mm_sel", 0),
|
||||||
GATE_IMG(CLK_IMG_RESZ, "img_resz", "mm_sel", 1),
|
GATE_IMG(CLK_IMG_RESZ, "img_resz", "mm_sel", 1),
|
||||||
GATE_IMG(CLK_IMG_JPGDEC_SMI, "img_jpgdec_smi", "mm_sel", 5),
|
GATE_IMG(CLK_IMG_JPGDEC_SMI, "img_jpgdec_smi", "mm_sel", 5),
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ static const struct mtk_gate_regs vdec1_cg_regs = {
|
|||||||
GATE_MTK(_id, _name, _parent, &vdec1_cg_regs, _shift, &mtk_clk_gate_ops_setclr_inv)
|
GATE_MTK(_id, _name, _parent, &vdec1_cg_regs, _shift, &mtk_clk_gate_ops_setclr_inv)
|
||||||
|
|
||||||
static const struct mtk_gate vdec_clks[] = {
|
static const struct mtk_gate vdec_clks[] = {
|
||||||
|
GATE_DUMMY(CLK_DUMMY, "vdec_dummy"),
|
||||||
GATE_VDEC0(CLK_VDEC_CKGEN, "vdec_cken", "vdec_sel", 0),
|
GATE_VDEC0(CLK_VDEC_CKGEN, "vdec_cken", "vdec_sel", 0),
|
||||||
GATE_VDEC1(CLK_VDEC_LARB, "vdec_larb_cken", "mm_sel", 0),
|
GATE_VDEC1(CLK_VDEC_LARB, "vdec_larb_cken", "mm_sel", 0),
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -21,6 +21,22 @@
|
|||||||
#include "clk-gate.h"
|
#include "clk-gate.h"
|
||||||
#include "clk-mux.h"
|
#include "clk-mux.h"
|
||||||
|
|
||||||
|
const struct mtk_gate_regs cg_regs_dummy = { 0, 0, 0 };
|
||||||
|
EXPORT_SYMBOL_GPL(cg_regs_dummy);
|
||||||
|
|
||||||
|
static int mtk_clk_dummy_enable(struct clk_hw *hw)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void mtk_clk_dummy_disable(struct clk_hw *hw) { }
|
||||||
|
|
||||||
|
const struct clk_ops mtk_clk_dummy_ops = {
|
||||||
|
.enable = mtk_clk_dummy_enable,
|
||||||
|
.disable = mtk_clk_dummy_disable,
|
||||||
|
};
|
||||||
|
EXPORT_SYMBOL_GPL(mtk_clk_dummy_ops);
|
||||||
|
|
||||||
static void mtk_init_clk_data(struct clk_hw_onecell_data *clk_data,
|
static void mtk_init_clk_data(struct clk_hw_onecell_data *clk_data,
|
||||||
unsigned int clk_num)
|
unsigned int clk_num)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -22,6 +22,25 @@
|
|||||||
|
|
||||||
struct platform_device;
|
struct platform_device;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We need the clock IDs to start from zero but to maintain devicetree
|
||||||
|
* backwards compatibility we can't change bindings to start from zero.
|
||||||
|
* Only a few platforms are affected, so we solve issues given by the
|
||||||
|
* commonized MTK clocks probe function(s) by adding a dummy clock at
|
||||||
|
* the beginning where needed.
|
||||||
|
*/
|
||||||
|
#define CLK_DUMMY 0
|
||||||
|
|
||||||
|
extern const struct clk_ops mtk_clk_dummy_ops;
|
||||||
|
extern const struct mtk_gate_regs cg_regs_dummy;
|
||||||
|
|
||||||
|
#define GATE_DUMMY(_id, _name) { \
|
||||||
|
.id = _id, \
|
||||||
|
.name = _name, \
|
||||||
|
.regs = &cg_regs_dummy, \
|
||||||
|
.ops = &mtk_clk_dummy_ops, \
|
||||||
|
}
|
||||||
|
|
||||||
struct mtk_fixed_clk {
|
struct mtk_fixed_clk {
|
||||||
int id;
|
int id;
|
||||||
const char *name;
|
const char *name;
|
||||||
|
|||||||
@@ -288,12 +288,9 @@ static int stm32_cec_probe(struct platform_device *pdev)
|
|||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
cec->clk_cec = devm_clk_get(&pdev->dev, "cec");
|
cec->clk_cec = devm_clk_get(&pdev->dev, "cec");
|
||||||
if (IS_ERR(cec->clk_cec)) {
|
if (IS_ERR(cec->clk_cec))
|
||||||
if (PTR_ERR(cec->clk_cec) != -EPROBE_DEFER)
|
return dev_err_probe(&pdev->dev, PTR_ERR(cec->clk_cec),
|
||||||
dev_err(&pdev->dev, "Cannot get cec clock\n");
|
"Cannot get cec clock\n");
|
||||||
|
|
||||||
return PTR_ERR(cec->clk_cec);
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = clk_prepare(cec->clk_cec);
|
ret = clk_prepare(cec->clk_cec);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
|
|||||||
@@ -301,21 +301,15 @@ static int ad5820_probe(struct i2c_client *client,
|
|||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
coil->vana = devm_regulator_get(&client->dev, "VANA");
|
coil->vana = devm_regulator_get(&client->dev, "VANA");
|
||||||
if (IS_ERR(coil->vana)) {
|
if (IS_ERR(coil->vana))
|
||||||
ret = PTR_ERR(coil->vana);
|
return dev_err_probe(&client->dev, PTR_ERR(coil->vana),
|
||||||
if (ret != -EPROBE_DEFER)
|
"could not get regulator for vana\n");
|
||||||
dev_err(&client->dev, "could not get regulator for vana\n");
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
coil->enable_gpio = devm_gpiod_get_optional(&client->dev, "enable",
|
coil->enable_gpio = devm_gpiod_get_optional(&client->dev, "enable",
|
||||||
GPIOD_OUT_LOW);
|
GPIOD_OUT_LOW);
|
||||||
if (IS_ERR(coil->enable_gpio)) {
|
if (IS_ERR(coil->enable_gpio))
|
||||||
ret = PTR_ERR(coil->enable_gpio);
|
return dev_err_probe(&client->dev, PTR_ERR(coil->enable_gpio),
|
||||||
if (ret != -EPROBE_DEFER)
|
"could not get enable gpio\n");
|
||||||
dev_err(&client->dev, "could not get enable gpio\n");
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
mutex_init(&coil->power_lock);
|
mutex_init(&coil->power_lock);
|
||||||
|
|
||||||
|
|||||||
@@ -2060,9 +2060,8 @@ static int imx274_probe(struct i2c_client *client)
|
|||||||
imx274->reset_gpio = devm_gpiod_get_optional(dev, "reset",
|
imx274->reset_gpio = devm_gpiod_get_optional(dev, "reset",
|
||||||
GPIOD_OUT_HIGH);
|
GPIOD_OUT_HIGH);
|
||||||
if (IS_ERR(imx274->reset_gpio)) {
|
if (IS_ERR(imx274->reset_gpio)) {
|
||||||
if (PTR_ERR(imx274->reset_gpio) != -EPROBE_DEFER)
|
ret = dev_err_probe(dev, PTR_ERR(imx274->reset_gpio),
|
||||||
dev_err(dev, "Reset GPIO not setup in DT");
|
"Reset GPIO not setup in DT\n");
|
||||||
ret = PTR_ERR(imx274->reset_gpio);
|
|
||||||
goto err_me;
|
goto err_me;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1891,12 +1891,9 @@ static int tc358743_probe_of(struct tc358743_state *state)
|
|||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
refclk = devm_clk_get(dev, "refclk");
|
refclk = devm_clk_get(dev, "refclk");
|
||||||
if (IS_ERR(refclk)) {
|
if (IS_ERR(refclk))
|
||||||
if (PTR_ERR(refclk) != -EPROBE_DEFER)
|
return dev_err_probe(dev, PTR_ERR(refclk),
|
||||||
dev_err(dev, "failed to get refclk: %ld\n",
|
"failed to get refclk\n");
|
||||||
PTR_ERR(refclk));
|
|
||||||
return PTR_ERR(refclk);
|
|
||||||
}
|
|
||||||
|
|
||||||
ep = of_graph_get_next_endpoint(dev->of_node, NULL);
|
ep = of_graph_get_next_endpoint(dev->of_node, NULL);
|
||||||
if (!ep) {
|
if (!ep) {
|
||||||
|
|||||||
@@ -52,9 +52,8 @@ int mtk_mdp_comp_init(struct device *dev, struct device_node *node,
|
|||||||
for (i = 0; i < ARRAY_SIZE(comp->clk); i++) {
|
for (i = 0; i < ARRAY_SIZE(comp->clk); i++) {
|
||||||
comp->clk[i] = of_clk_get(node, i);
|
comp->clk[i] = of_clk_get(node, i);
|
||||||
if (IS_ERR(comp->clk[i])) {
|
if (IS_ERR(comp->clk[i])) {
|
||||||
if (PTR_ERR(comp->clk[i]) != -EPROBE_DEFER)
|
ret = dev_err_probe(dev, PTR_ERR(comp->clk[i]),
|
||||||
dev_err(dev, "Failed to get clock\n");
|
"Failed to get clock\n");
|
||||||
ret = PTR_ERR(comp->clk[i]);
|
|
||||||
goto put_dev;
|
goto put_dev;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1471,9 +1471,7 @@ static int fimc_md_probe(struct platform_device *pdev)
|
|||||||
|
|
||||||
pinctrl = devm_pinctrl_get(dev);
|
pinctrl = devm_pinctrl_get(dev);
|
||||||
if (IS_ERR(pinctrl)) {
|
if (IS_ERR(pinctrl)) {
|
||||||
ret = PTR_ERR(pinctrl);
|
ret = dev_err_probe(dev, PTR_ERR(pinctrl), "Failed to get pinctrl\n");
|
||||||
if (ret != -EPROBE_DEFER)
|
|
||||||
dev_err(dev, "Failed to get pinctrl: %d\n", ret);
|
|
||||||
goto err_clk;
|
goto err_clk;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1946,12 +1946,9 @@ static int dcmi_probe(struct platform_device *pdev)
|
|||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
dcmi->rstc = devm_reset_control_get_exclusive(&pdev->dev, NULL);
|
dcmi->rstc = devm_reset_control_get_exclusive(&pdev->dev, NULL);
|
||||||
if (IS_ERR(dcmi->rstc)) {
|
if (IS_ERR(dcmi->rstc))
|
||||||
if (PTR_ERR(dcmi->rstc) != -EPROBE_DEFER)
|
return dev_err_probe(&pdev->dev, PTR_ERR(dcmi->rstc),
|
||||||
dev_err(&pdev->dev, "Could not get reset control\n");
|
"Could not get reset control\n");
|
||||||
|
|
||||||
return PTR_ERR(dcmi->rstc);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get bus characteristics from devicetree */
|
/* Get bus characteristics from devicetree */
|
||||||
np = of_graph_get_next_endpoint(np, NULL);
|
np = of_graph_get_next_endpoint(np, NULL);
|
||||||
@@ -2003,20 +2000,14 @@ static int dcmi_probe(struct platform_device *pdev)
|
|||||||
}
|
}
|
||||||
|
|
||||||
mclk = devm_clk_get(&pdev->dev, "mclk");
|
mclk = devm_clk_get(&pdev->dev, "mclk");
|
||||||
if (IS_ERR(mclk)) {
|
if (IS_ERR(mclk))
|
||||||
if (PTR_ERR(mclk) != -EPROBE_DEFER)
|
return dev_err_probe(&pdev->dev, PTR_ERR(mclk),
|
||||||
dev_err(&pdev->dev, "Unable to get mclk\n");
|
"Unable to get mclk\n");
|
||||||
return PTR_ERR(mclk);
|
|
||||||
}
|
|
||||||
|
|
||||||
chan = dma_request_chan(&pdev->dev, "tx");
|
chan = dma_request_chan(&pdev->dev, "tx");
|
||||||
if (IS_ERR(chan)) {
|
if (IS_ERR(chan))
|
||||||
ret = PTR_ERR(chan);
|
return dev_err_probe(&pdev->dev, PTR_ERR(chan),
|
||||||
if (ret != -EPROBE_DEFER)
|
"Failed to request DMA channel\n");
|
||||||
dev_err(&pdev->dev,
|
|
||||||
"Failed to request DMA channel: %d\n", ret);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
dcmi->dma_max_burst = UINT_MAX;
|
dcmi->dma_max_burst = UINT_MAX;
|
||||||
ret = dma_get_slave_caps(chan, &caps);
|
ret = dma_get_slave_caps(chan, &caps);
|
||||||
|
|||||||
@@ -1884,8 +1884,7 @@ static int isp_initialize_modules(struct isp_device *isp)
|
|||||||
|
|
||||||
ret = omap3isp_ccp2_init(isp);
|
ret = omap3isp_ccp2_init(isp);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
if (ret != -EPROBE_DEFER)
|
dev_err_probe(isp->dev, ret, "CCP2 initialization failed\n");
|
||||||
dev_err(isp->dev, "CCP2 initialization failed\n");
|
|
||||||
goto error_ccp2;
|
goto error_ccp2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -976,11 +976,9 @@ static int xcsi2rxss_probe(struct platform_device *pdev)
|
|||||||
/* Reset GPIO */
|
/* Reset GPIO */
|
||||||
xcsi2rxss->rst_gpio = devm_gpiod_get_optional(dev, "video-reset",
|
xcsi2rxss->rst_gpio = devm_gpiod_get_optional(dev, "video-reset",
|
||||||
GPIOD_OUT_HIGH);
|
GPIOD_OUT_HIGH);
|
||||||
if (IS_ERR(xcsi2rxss->rst_gpio)) {
|
if (IS_ERR(xcsi2rxss->rst_gpio))
|
||||||
if (PTR_ERR(xcsi2rxss->rst_gpio) != -EPROBE_DEFER)
|
return dev_err_probe(dev, PTR_ERR(xcsi2rxss->rst_gpio),
|
||||||
dev_err(dev, "Video Reset GPIO not setup in DT");
|
"Video Reset GPIO not setup in DT\n");
|
||||||
return PTR_ERR(xcsi2rxss->rst_gpio);
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = xcsi2rxss_parse_of(xcsi2rxss);
|
ret = xcsi2rxss_parse_of(xcsi2rxss);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
|
|||||||
@@ -74,13 +74,9 @@ static int gpio_ir_recv_probe(struct platform_device *pdev)
|
|||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
gpio_dev->gpiod = devm_gpiod_get(dev, NULL, GPIOD_IN);
|
gpio_dev->gpiod = devm_gpiod_get(dev, NULL, GPIOD_IN);
|
||||||
if (IS_ERR(gpio_dev->gpiod)) {
|
if (IS_ERR(gpio_dev->gpiod))
|
||||||
rc = PTR_ERR(gpio_dev->gpiod);
|
return dev_err_probe(dev, PTR_ERR(gpio_dev->gpiod),
|
||||||
/* Just try again if this happens */
|
"error getting gpio\n");
|
||||||
if (rc != -EPROBE_DEFER)
|
|
||||||
dev_err(dev, "error getting gpio (%d)\n", rc);
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
gpio_dev->irq = gpiod_to_irq(gpio_dev->gpiod);
|
gpio_dev->irq = gpiod_to_irq(gpio_dev->gpiod);
|
||||||
if (gpio_dev->irq < 0)
|
if (gpio_dev->irq < 0)
|
||||||
return gpio_dev->irq;
|
return gpio_dev->irq;
|
||||||
|
|||||||
@@ -174,12 +174,9 @@ static int gpio_ir_tx_probe(struct platform_device *pdev)
|
|||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
gpio_ir->gpio = devm_gpiod_get(&pdev->dev, NULL, GPIOD_OUT_LOW);
|
gpio_ir->gpio = devm_gpiod_get(&pdev->dev, NULL, GPIOD_OUT_LOW);
|
||||||
if (IS_ERR(gpio_ir->gpio)) {
|
if (IS_ERR(gpio_ir->gpio))
|
||||||
if (PTR_ERR(gpio_ir->gpio) != -EPROBE_DEFER)
|
return dev_err_probe(&pdev->dev, PTR_ERR(gpio_ir->gpio),
|
||||||
dev_err(&pdev->dev, "Failed to get gpio (%ld)\n",
|
"Failed to get gpio\n");
|
||||||
PTR_ERR(gpio_ir->gpio));
|
|
||||||
return PTR_ERR(gpio_ir->gpio);
|
|
||||||
}
|
|
||||||
|
|
||||||
rcdev->priv = gpio_ir;
|
rcdev->priv = gpio_ir;
|
||||||
rcdev->driver_name = DRIVER_NAME;
|
rcdev->driver_name = DRIVER_NAME;
|
||||||
|
|||||||
@@ -231,13 +231,8 @@ static int ir_rx51_probe(struct platform_device *dev)
|
|||||||
struct rc_dev *rcdev;
|
struct rc_dev *rcdev;
|
||||||
|
|
||||||
pwm = pwm_get(&dev->dev, NULL);
|
pwm = pwm_get(&dev->dev, NULL);
|
||||||
if (IS_ERR(pwm)) {
|
if (IS_ERR(pwm))
|
||||||
int err = PTR_ERR(pwm);
|
return dev_err_probe(&dev->dev, PTR_ERR(pwm), "pwm_get failed\n");
|
||||||
|
|
||||||
if (err != -EPROBE_DEFER)
|
|
||||||
dev_err(&dev->dev, "pwm_get failed: %d\n", err);
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Use default, in case userspace does not set the carrier */
|
/* Use default, in case userspace does not set the carrier */
|
||||||
ir_rx51.freq = DIV_ROUND_CLOSEST_ULL(pwm_get_period(pwm), NSEC_PER_SEC);
|
ir_rx51.freq = DIV_ROUND_CLOSEST_ULL(pwm_get_period(pwm), NSEC_PER_SEC);
|
||||||
|
|||||||
@@ -1470,6 +1470,40 @@ static void uvc_ctrl_send_slave_event(struct uvc_video_chain *chain,
|
|||||||
uvc_ctrl_send_event(chain, handle, ctrl, mapping, val, changes);
|
uvc_ctrl_send_event(chain, handle, ctrl, mapping, val, changes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void uvc_ctrl_set_handle(struct uvc_fh *handle, struct uvc_control *ctrl,
|
||||||
|
struct uvc_fh *new_handle)
|
||||||
|
{
|
||||||
|
lockdep_assert_held(&handle->chain->ctrl_mutex);
|
||||||
|
|
||||||
|
if (new_handle) {
|
||||||
|
if (ctrl->handle)
|
||||||
|
dev_warn_ratelimited(&handle->stream->dev->udev->dev,
|
||||||
|
"UVC non compliance: Setting an async control with a pending operation.");
|
||||||
|
|
||||||
|
if (new_handle == ctrl->handle)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (ctrl->handle) {
|
||||||
|
WARN_ON(!ctrl->handle->pending_async_ctrls);
|
||||||
|
if (ctrl->handle->pending_async_ctrls)
|
||||||
|
ctrl->handle->pending_async_ctrls--;
|
||||||
|
}
|
||||||
|
|
||||||
|
ctrl->handle = new_handle;
|
||||||
|
handle->pending_async_ctrls++;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Cannot clear the handle for a control not owned by us.*/
|
||||||
|
if (WARN_ON(ctrl->handle != handle))
|
||||||
|
return;
|
||||||
|
|
||||||
|
ctrl->handle = NULL;
|
||||||
|
if (WARN_ON(!handle->pending_async_ctrls))
|
||||||
|
return;
|
||||||
|
handle->pending_async_ctrls--;
|
||||||
|
}
|
||||||
|
|
||||||
void uvc_ctrl_status_event(struct uvc_video_chain *chain,
|
void uvc_ctrl_status_event(struct uvc_video_chain *chain,
|
||||||
struct uvc_control *ctrl, const u8 *data)
|
struct uvc_control *ctrl, const u8 *data)
|
||||||
{
|
{
|
||||||
@@ -1480,7 +1514,8 @@ void uvc_ctrl_status_event(struct uvc_video_chain *chain,
|
|||||||
mutex_lock(&chain->ctrl_mutex);
|
mutex_lock(&chain->ctrl_mutex);
|
||||||
|
|
||||||
handle = ctrl->handle;
|
handle = ctrl->handle;
|
||||||
ctrl->handle = NULL;
|
if (handle)
|
||||||
|
uvc_ctrl_set_handle(handle, ctrl, NULL);
|
||||||
|
|
||||||
list_for_each_entry(mapping, &ctrl->info.mappings, list) {
|
list_for_each_entry(mapping, &ctrl->info.mappings, list) {
|
||||||
s32 value = __uvc_ctrl_get_value(mapping, data);
|
s32 value = __uvc_ctrl_get_value(mapping, data);
|
||||||
@@ -1700,7 +1735,10 @@ int uvc_ctrl_begin(struct uvc_video_chain *chain)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int uvc_ctrl_commit_entity(struct uvc_device *dev,
|
static int uvc_ctrl_commit_entity(struct uvc_device *dev,
|
||||||
struct uvc_entity *entity, int rollback, struct uvc_control **err_ctrl)
|
struct uvc_fh *handle,
|
||||||
|
struct uvc_entity *entity,
|
||||||
|
int rollback,
|
||||||
|
struct uvc_control **err_ctrl)
|
||||||
{
|
{
|
||||||
struct uvc_control *ctrl;
|
struct uvc_control *ctrl;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
@@ -1748,6 +1786,10 @@ static int uvc_ctrl_commit_entity(struct uvc_device *dev,
|
|||||||
*err_ctrl = ctrl;
|
*err_ctrl = ctrl;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!rollback && handle &&
|
||||||
|
ctrl->info.flags & UVC_CTRL_FLAG_ASYNCHRONOUS)
|
||||||
|
uvc_ctrl_set_handle(handle, ctrl, handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@@ -1784,18 +1826,20 @@ int __uvc_ctrl_commit(struct uvc_fh *handle, int rollback,
|
|||||||
|
|
||||||
/* Find the control. */
|
/* Find the control. */
|
||||||
list_for_each_entry(entity, &chain->entities, chain) {
|
list_for_each_entry(entity, &chain->entities, chain) {
|
||||||
ret = uvc_ctrl_commit_entity(chain->dev, entity, rollback,
|
ret = uvc_ctrl_commit_entity(chain->dev, handle, entity,
|
||||||
&err_ctrl);
|
rollback, &err_ctrl);
|
||||||
if (ret < 0)
|
if (ret < 0) {
|
||||||
|
if (ctrls)
|
||||||
|
ctrls->error_idx =
|
||||||
|
uvc_ctrl_find_ctrl_idx(entity, ctrls,
|
||||||
|
err_ctrl);
|
||||||
goto done;
|
goto done;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!rollback)
|
if (!rollback)
|
||||||
uvc_ctrl_send_events(handle, ctrls->controls, ctrls->count);
|
uvc_ctrl_send_events(handle, ctrls->controls, ctrls->count);
|
||||||
done:
|
done:
|
||||||
if (ret < 0 && ctrls)
|
|
||||||
ctrls->error_idx = uvc_ctrl_find_ctrl_idx(entity, ctrls,
|
|
||||||
err_ctrl);
|
|
||||||
mutex_unlock(&chain->ctrl_mutex);
|
mutex_unlock(&chain->ctrl_mutex);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@@ -1925,9 +1969,6 @@ int uvc_ctrl_set(struct uvc_fh *handle,
|
|||||||
mapping->set(mapping, value,
|
mapping->set(mapping, value,
|
||||||
uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT));
|
uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT));
|
||||||
|
|
||||||
if (ctrl->info.flags & UVC_CTRL_FLAG_ASYNCHRONOUS)
|
|
||||||
ctrl->handle = handle;
|
|
||||||
|
|
||||||
ctrl->dirty = 1;
|
ctrl->dirty = 1;
|
||||||
ctrl->modified = 1;
|
ctrl->modified = 1;
|
||||||
return 0;
|
return 0;
|
||||||
@@ -2100,7 +2141,7 @@ static int uvc_ctrl_init_xu_ctrl(struct uvc_device *dev,
|
|||||||
int uvc_xu_ctrl_query(struct uvc_video_chain *chain,
|
int uvc_xu_ctrl_query(struct uvc_video_chain *chain,
|
||||||
struct uvc_xu_control_query *xqry)
|
struct uvc_xu_control_query *xqry)
|
||||||
{
|
{
|
||||||
struct uvc_entity *entity;
|
struct uvc_entity *entity, *iter;
|
||||||
struct uvc_control *ctrl;
|
struct uvc_control *ctrl;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
bool found;
|
bool found;
|
||||||
@@ -2110,16 +2151,16 @@ int uvc_xu_ctrl_query(struct uvc_video_chain *chain,
|
|||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
/* Find the extension unit. */
|
/* Find the extension unit. */
|
||||||
found = false;
|
entity = NULL;
|
||||||
list_for_each_entry(entity, &chain->entities, chain) {
|
list_for_each_entry(iter, &chain->entities, chain) {
|
||||||
if (UVC_ENTITY_TYPE(entity) == UVC_VC_EXTENSION_UNIT &&
|
if (UVC_ENTITY_TYPE(iter) == UVC_VC_EXTENSION_UNIT &&
|
||||||
entity->id == xqry->unit) {
|
iter->id == xqry->unit) {
|
||||||
found = true;
|
entity = iter;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!found) {
|
if (!entity) {
|
||||||
uvc_dbg(chain->dev, CONTROL, "Extension unit %u not found\n",
|
uvc_dbg(chain->dev, CONTROL, "Extension unit %u not found\n",
|
||||||
xqry->unit);
|
xqry->unit);
|
||||||
return -ENOENT;
|
return -ENOENT;
|
||||||
@@ -2256,7 +2297,7 @@ int uvc_ctrl_restore_values(struct uvc_device *dev)
|
|||||||
ctrl->dirty = 1;
|
ctrl->dirty = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = uvc_ctrl_commit_entity(dev, entity, 0, NULL);
|
ret = uvc_ctrl_commit_entity(dev, NULL, entity, 0, NULL);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@@ -2660,6 +2701,26 @@ int uvc_ctrl_init_device(struct uvc_device *dev)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void uvc_ctrl_cleanup_fh(struct uvc_fh *handle)
|
||||||
|
{
|
||||||
|
struct uvc_entity *entity;
|
||||||
|
|
||||||
|
guard(mutex)(&handle->chain->ctrl_mutex);
|
||||||
|
|
||||||
|
if (!handle->pending_async_ctrls)
|
||||||
|
return;
|
||||||
|
|
||||||
|
list_for_each_entry(entity, &handle->chain->dev->entities, list) {
|
||||||
|
for (unsigned int i = 0; i < entity->ncontrols; ++i) {
|
||||||
|
if (entity->controls[i].handle != handle)
|
||||||
|
continue;
|
||||||
|
uvc_ctrl_set_handle(handle, &entity->controls[i], NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
WARN_ON(handle->pending_async_ctrls);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Cleanup device controls.
|
* Cleanup device controls.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -1247,18 +1247,15 @@ static int uvc_gpio_parse(struct uvc_device *dev)
|
|||||||
struct gpio_desc *gpio_privacy;
|
struct gpio_desc *gpio_privacy;
|
||||||
int irq;
|
int irq;
|
||||||
|
|
||||||
gpio_privacy = devm_gpiod_get_optional(&dev->udev->dev, "privacy",
|
gpio_privacy = devm_gpiod_get_optional(&dev->intf->dev, "privacy",
|
||||||
GPIOD_IN);
|
GPIOD_IN);
|
||||||
if (IS_ERR_OR_NULL(gpio_privacy))
|
if (IS_ERR_OR_NULL(gpio_privacy))
|
||||||
return PTR_ERR_OR_ZERO(gpio_privacy);
|
return PTR_ERR_OR_ZERO(gpio_privacy);
|
||||||
|
|
||||||
irq = gpiod_to_irq(gpio_privacy);
|
irq = gpiod_to_irq(gpio_privacy);
|
||||||
if (irq < 0) {
|
if (irq < 0)
|
||||||
if (irq != EPROBE_DEFER)
|
return dev_err_probe(&dev->intf->dev, irq,
|
||||||
dev_err(&dev->udev->dev,
|
"No IRQ for privacy GPIO\n");
|
||||||
"No IRQ for privacy GPIO (%d)\n", irq);
|
|
||||||
return irq;
|
|
||||||
}
|
|
||||||
|
|
||||||
unit = uvc_alloc_entity(UVC_EXT_GPIO_UNIT, UVC_EXT_GPIO_UNIT_ID, 0, 1);
|
unit = uvc_alloc_entity(UVC_EXT_GPIO_UNIT, UVC_EXT_GPIO_UNIT_ID, 0, 1);
|
||||||
if (!unit)
|
if (!unit)
|
||||||
@@ -1283,15 +1280,27 @@ static int uvc_gpio_parse(struct uvc_device *dev)
|
|||||||
static int uvc_gpio_init_irq(struct uvc_device *dev)
|
static int uvc_gpio_init_irq(struct uvc_device *dev)
|
||||||
{
|
{
|
||||||
struct uvc_entity *unit = dev->gpio_unit;
|
struct uvc_entity *unit = dev->gpio_unit;
|
||||||
|
int ret;
|
||||||
|
|
||||||
if (!unit || unit->gpio.irq < 0)
|
if (!unit || unit->gpio.irq < 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
return devm_request_threaded_irq(&dev->udev->dev, unit->gpio.irq, NULL,
|
ret = request_threaded_irq(unit->gpio.irq, NULL, uvc_gpio_irq,
|
||||||
uvc_gpio_irq,
|
IRQF_ONESHOT | IRQF_TRIGGER_FALLING |
|
||||||
IRQF_ONESHOT | IRQF_TRIGGER_FALLING |
|
IRQF_TRIGGER_RISING,
|
||||||
IRQF_TRIGGER_RISING,
|
"uvc_privacy_gpio", dev);
|
||||||
"uvc_privacy_gpio", dev);
|
|
||||||
|
unit->gpio.initialized = !ret;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void uvc_gpio_deinit(struct uvc_device *dev)
|
||||||
|
{
|
||||||
|
if (!dev->gpio_unit || !dev->gpio_unit->gpio.initialized)
|
||||||
|
return;
|
||||||
|
|
||||||
|
free_irq(dev->gpio_unit->gpio.irq, dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------
|
/* ------------------------------------------------------------------------
|
||||||
@@ -1885,6 +1894,8 @@ static void uvc_unregister_video(struct uvc_device *dev)
|
|||||||
{
|
{
|
||||||
struct uvc_streaming *stream;
|
struct uvc_streaming *stream;
|
||||||
|
|
||||||
|
uvc_gpio_deinit(dev);
|
||||||
|
|
||||||
list_for_each_entry(stream, &dev->streams, list) {
|
list_for_each_entry(stream, &dev->streams, list) {
|
||||||
/* Nothing to do here, continue. */
|
/* Nothing to do here, continue. */
|
||||||
if (!video_is_registered(&stream->vdev))
|
if (!video_is_registered(&stream->vdev))
|
||||||
|
|||||||
@@ -607,6 +607,8 @@ static int uvc_v4l2_release(struct file *file)
|
|||||||
|
|
||||||
uvc_dbg(stream->dev, CALLS, "%s\n", __func__);
|
uvc_dbg(stream->dev, CALLS, "%s\n", __func__);
|
||||||
|
|
||||||
|
uvc_ctrl_cleanup_fh(handle);
|
||||||
|
|
||||||
/* Only free resources if this is a privileged handle. */
|
/* Only free resources if this is a privileged handle. */
|
||||||
if (uvc_has_privileges(handle))
|
if (uvc_has_privileges(handle))
|
||||||
uvc_queue_release(&stream->queue);
|
uvc_queue_release(&stream->queue);
|
||||||
|
|||||||
@@ -227,6 +227,7 @@ struct uvc_entity {
|
|||||||
u8 *bmControls;
|
u8 *bmControls;
|
||||||
struct gpio_desc *gpio_privacy;
|
struct gpio_desc *gpio_privacy;
|
||||||
int irq;
|
int irq;
|
||||||
|
bool initialized;
|
||||||
} gpio;
|
} gpio;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -330,7 +331,11 @@ struct uvc_video_chain {
|
|||||||
struct uvc_entity *processing; /* Processing unit */
|
struct uvc_entity *processing; /* Processing unit */
|
||||||
struct uvc_entity *selector; /* Selector unit */
|
struct uvc_entity *selector; /* Selector unit */
|
||||||
|
|
||||||
struct mutex ctrl_mutex; /* Protects ctrl.info */
|
struct mutex ctrl_mutex; /*
|
||||||
|
* Protects ctrl.info,
|
||||||
|
* ctrl.handle and
|
||||||
|
* uvc_fh.pending_async_ctrls
|
||||||
|
*/
|
||||||
|
|
||||||
struct v4l2_prio_state prio; /* V4L2 priority state */
|
struct v4l2_prio_state prio; /* V4L2 priority state */
|
||||||
u32 caps; /* V4L2 chain-wide caps */
|
u32 caps; /* V4L2 chain-wide caps */
|
||||||
@@ -584,6 +589,7 @@ struct uvc_fh {
|
|||||||
struct uvc_video_chain *chain;
|
struct uvc_video_chain *chain;
|
||||||
struct uvc_streaming *stream;
|
struct uvc_streaming *stream;
|
||||||
enum uvc_handle_state state;
|
enum uvc_handle_state state;
|
||||||
|
unsigned int pending_async_ctrls;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct uvc_driver {
|
struct uvc_driver {
|
||||||
@@ -768,6 +774,8 @@ int uvc_ctrl_is_accessible(struct uvc_video_chain *chain, u32 v4l2_id,
|
|||||||
int uvc_xu_ctrl_query(struct uvc_video_chain *chain,
|
int uvc_xu_ctrl_query(struct uvc_video_chain *chain,
|
||||||
struct uvc_xu_control_query *xqry);
|
struct uvc_xu_control_query *xqry);
|
||||||
|
|
||||||
|
void uvc_ctrl_cleanup_fh(struct uvc_fh *handle);
|
||||||
|
|
||||||
/* Utility functions */
|
/* Utility functions */
|
||||||
struct usb_host_endpoint *uvc_find_endpoint(struct usb_host_interface *alts,
|
struct usb_host_endpoint *uvc_find_endpoint(struct usb_host_interface *alts,
|
||||||
u8 epaddr);
|
u8 epaddr);
|
||||||
|
|||||||
@@ -781,12 +781,18 @@ static void scsi_io_completion_action(struct scsi_cmnd *cmd, int result)
|
|||||||
case 0x1a: /* start stop unit in progress */
|
case 0x1a: /* start stop unit in progress */
|
||||||
case 0x1b: /* sanitize in progress */
|
case 0x1b: /* sanitize in progress */
|
||||||
case 0x1d: /* configuration in progress */
|
case 0x1d: /* configuration in progress */
|
||||||
case 0x24: /* depopulation in progress */
|
|
||||||
action = ACTION_DELAYED_RETRY;
|
action = ACTION_DELAYED_RETRY;
|
||||||
break;
|
break;
|
||||||
case 0x0a: /* ALUA state transition */
|
case 0x0a: /* ALUA state transition */
|
||||||
action = ACTION_DELAYED_REPREP;
|
action = ACTION_DELAYED_REPREP;
|
||||||
break;
|
break;
|
||||||
|
/*
|
||||||
|
* Depopulation might take many hours,
|
||||||
|
* thus it is not worthwhile to retry.
|
||||||
|
*/
|
||||||
|
case 0x24: /* depopulation in progress */
|
||||||
|
case 0x25: /* depopulation restore in progress */
|
||||||
|
fallthrough;
|
||||||
default:
|
default:
|
||||||
action = ACTION_FAIL;
|
action = ACTION_FAIL;
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -2127,6 +2127,10 @@ sd_spinup_disk(struct scsi_disk *sdkp)
|
|||||||
break; /* unavailable */
|
break; /* unavailable */
|
||||||
if (sshdr.asc == 4 && sshdr.ascq == 0x1b)
|
if (sshdr.asc == 4 && sshdr.ascq == 0x1b)
|
||||||
break; /* sanitize in progress */
|
break; /* sanitize in progress */
|
||||||
|
if (sshdr.asc == 4 && sshdr.ascq == 0x24)
|
||||||
|
break; /* depopulation in progress */
|
||||||
|
if (sshdr.asc == 4 && sshdr.ascq == 0x25)
|
||||||
|
break; /* depopulation restoration in progress */
|
||||||
/*
|
/*
|
||||||
* Issue command to spin up drive when not ready
|
* Issue command to spin up drive when not ready
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -273,44 +273,44 @@ static int mtk_devapc_probe(struct platform_device *pdev)
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
devapc_irq = irq_of_parse_and_map(node, 0);
|
devapc_irq = irq_of_parse_and_map(node, 0);
|
||||||
if (!devapc_irq)
|
if (!devapc_irq) {
|
||||||
return -EINVAL;
|
ret = -EINVAL;
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
ctx->infra_clk = devm_clk_get(&pdev->dev, "devapc-infra-clock");
|
ctx->infra_clk = devm_clk_get_enabled(&pdev->dev, "devapc-infra-clock");
|
||||||
if (IS_ERR(ctx->infra_clk))
|
if (IS_ERR(ctx->infra_clk)) {
|
||||||
return -EINVAL;
|
ret = -EINVAL;
|
||||||
|
goto err;
|
||||||
if (clk_prepare_enable(ctx->infra_clk))
|
}
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
ret = devm_request_irq(&pdev->dev, devapc_irq, devapc_violation_irq,
|
ret = devm_request_irq(&pdev->dev, devapc_irq, devapc_violation_irq,
|
||||||
IRQF_TRIGGER_NONE, "devapc", ctx);
|
IRQF_TRIGGER_NONE, "devapc", ctx);
|
||||||
if (ret) {
|
if (ret)
|
||||||
clk_disable_unprepare(ctx->infra_clk);
|
goto err;
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
platform_set_drvdata(pdev, ctx);
|
platform_set_drvdata(pdev, ctx);
|
||||||
|
|
||||||
start_devapc(ctx);
|
start_devapc(ctx);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
err:
|
||||||
|
iounmap(ctx->infra_base);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int mtk_devapc_remove(struct platform_device *pdev)
|
static void mtk_devapc_remove(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct mtk_devapc_context *ctx = platform_get_drvdata(pdev);
|
struct mtk_devapc_context *ctx = platform_get_drvdata(pdev);
|
||||||
|
|
||||||
stop_devapc(ctx);
|
stop_devapc(ctx);
|
||||||
|
iounmap(ctx->infra_base);
|
||||||
clk_disable_unprepare(ctx->infra_clk);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct platform_driver mtk_devapc_driver = {
|
static struct platform_driver mtk_devapc_driver = {
|
||||||
.probe = mtk_devapc_probe,
|
.probe = mtk_devapc_probe,
|
||||||
.remove = mtk_devapc_remove,
|
.remove_new = mtk_devapc_remove,
|
||||||
.driver = {
|
.driver = {
|
||||||
.name = "mtk-devapc",
|
.name = "mtk-devapc",
|
||||||
.of_match_table = mtk_devapc_dt_match,
|
.of_match_table = mtk_devapc_dt_match,
|
||||||
|
|||||||
@@ -483,6 +483,8 @@ static int rz_ssi_pio_send(struct rz_ssi_priv *ssi, struct rz_ssi_stream *strm)
|
|||||||
sample_space = strm->fifo_sample_size;
|
sample_space = strm->fifo_sample_size;
|
||||||
ssifsr = rz_ssi_reg_readl(ssi, SSIFSR);
|
ssifsr = rz_ssi_reg_readl(ssi, SSIFSR);
|
||||||
sample_space -= (ssifsr >> SSIFSR_TDC_SHIFT) & SSIFSR_TDC_MASK;
|
sample_space -= (ssifsr >> SSIFSR_TDC_SHIFT) & SSIFSR_TDC_MASK;
|
||||||
|
if (sample_space < 0)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
/* Only add full frames at a time */
|
/* Only add full frames at a time */
|
||||||
while (frames_left && (sample_space >= runtime->channels)) {
|
while (frames_left && (sample_space >= runtime->channels)) {
|
||||||
|
|||||||
Reference in New Issue
Block a user