Merge tag 'char-misc-5.1-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc
Pull char/misc driver updates from Greg KH: "Here is the big char/misc driver patch pull request for 5.1-rc1. The largest thing by far is the new habanalabs driver for their AI accelerator chip. For now it is in the drivers/misc directory but will probably move to a new directory soon along with other drivers of this type. Other than that, just the usual set of individual driver updates and fixes. There's an "odd" merge in here from the DRM tree that they asked me to do as the MEI driver is starting to interact with the i915 driver, and it needed some coordination. All of those patches have been properly acked by the relevant subsystem maintainers. All of these have been in linux-next with no reported issues, most for quite some time" * tag 'char-misc-5.1-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc: (219 commits) habanalabs: adjust Kconfig to fix build errors habanalabs: use %px instead of %p in error print habanalabs: use do_div for 64-bit divisions intel_th: gth: Fix an off-by-one in output unassigning habanalabs: fix little-endian<->cpu conversion warnings habanalabs: use NULL to initialize array of pointers habanalabs: fix little-endian<->cpu conversion warnings habanalabs: soft-reset device if context-switch fails habanalabs: print pointer using %p habanalabs: fix memory leak with CBs with unaligned size habanalabs: return correct error code on MMU mapping failure habanalabs: add comments in uapi/misc/habanalabs.h habanalabs: extend QMAN0 job timeout habanalabs: set DMA0 completion to SOB 1007 habanalabs: fix validation of WREG32 to DMA completion habanalabs: fix mmu cache registers init habanalabs: disable CPU access on timeouts habanalabs: add MMU DRAM default page mapping habanalabs: Dissociate RAZWI info from event types misc/habanalabs: adjust Kconfig to fix build errors ...
This commit is contained in:
@@ -26,7 +26,7 @@ config NVMEM_IMX_IIM
|
||||
|
||||
config NVMEM_IMX_OCOTP
|
||||
tristate "i.MX6 On-Chip OTP Controller support"
|
||||
depends on SOC_IMX6 || COMPILE_TEST
|
||||
depends on SOC_IMX6 || SOC_IMX7D || COMPILE_TEST
|
||||
depends on HAS_IOMEM
|
||||
help
|
||||
This is a driver for the On-Chip OTP Controller (OCOTP) available on
|
||||
|
@@ -11,13 +11,14 @@
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/nvmem-provider.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
/*
|
||||
@@ -78,9 +79,9 @@ static struct otpc_map otp_map_v2 = {
|
||||
};
|
||||
|
||||
struct otpc_priv {
|
||||
struct device *dev;
|
||||
void __iomem *base;
|
||||
struct otpc_map *map;
|
||||
struct device *dev;
|
||||
void __iomem *base;
|
||||
const struct otpc_map *map;
|
||||
struct nvmem_config *config;
|
||||
};
|
||||
|
||||
@@ -237,16 +238,22 @@ static struct nvmem_config bcm_otpc_nvmem_config = {
|
||||
};
|
||||
|
||||
static const struct of_device_id bcm_otpc_dt_ids[] = {
|
||||
{ .compatible = "brcm,ocotp" },
|
||||
{ .compatible = "brcm,ocotp-v2" },
|
||||
{ .compatible = "brcm,ocotp", .data = &otp_map },
|
||||
{ .compatible = "brcm,ocotp-v2", .data = &otp_map_v2 },
|
||||
{ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, bcm_otpc_dt_ids);
|
||||
|
||||
static const struct acpi_device_id bcm_otpc_acpi_ids[] = {
|
||||
{ .id = "BRCM0700", .driver_data = (kernel_ulong_t)&otp_map },
|
||||
{ .id = "BRCM0701", .driver_data = (kernel_ulong_t)&otp_map_v2 },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(acpi, bcm_otpc_acpi_ids);
|
||||
|
||||
static int bcm_otpc_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
struct device_node *dn = dev->of_node;
|
||||
struct resource *res;
|
||||
struct otpc_priv *priv;
|
||||
struct nvmem_device *nvmem;
|
||||
@@ -257,14 +264,9 @@ static int bcm_otpc_probe(struct platform_device *pdev)
|
||||
if (!priv)
|
||||
return -ENOMEM;
|
||||
|
||||
if (of_device_is_compatible(dev->of_node, "brcm,ocotp"))
|
||||
priv->map = &otp_map;
|
||||
else if (of_device_is_compatible(dev->of_node, "brcm,ocotp-v2"))
|
||||
priv->map = &otp_map_v2;
|
||||
else {
|
||||
dev_err(dev, "%s otpc config map not defined\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
priv->map = device_get_match_data(dev);
|
||||
if (!priv->map)
|
||||
return -ENODEV;
|
||||
|
||||
/* Get OTP base address register. */
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
@@ -281,7 +283,7 @@ static int bcm_otpc_probe(struct platform_device *pdev)
|
||||
reset_start_bit(priv->base);
|
||||
|
||||
/* Read size of memory in words. */
|
||||
err = of_property_read_u32(dn, "brcm,ocotp-size", &num_words);
|
||||
err = device_property_read_u32(dev, "brcm,ocotp-size", &num_words);
|
||||
if (err) {
|
||||
dev_err(dev, "size parameter not specified\n");
|
||||
return -EINVAL;
|
||||
@@ -294,7 +296,7 @@ static int bcm_otpc_probe(struct platform_device *pdev)
|
||||
bcm_otpc_nvmem_config.dev = dev;
|
||||
bcm_otpc_nvmem_config.priv = priv;
|
||||
|
||||
if (of_device_is_compatible(dev->of_node, "brcm,ocotp-v2")) {
|
||||
if (priv->map == &otp_map_v2) {
|
||||
bcm_otpc_nvmem_config.word_size = 8;
|
||||
bcm_otpc_nvmem_config.stride = 8;
|
||||
}
|
||||
@@ -315,6 +317,7 @@ static struct platform_driver bcm_otpc_driver = {
|
||||
.driver = {
|
||||
.name = "brcm-otpc",
|
||||
.of_match_table = bcm_otpc_dt_ids,
|
||||
.acpi_match_table = ACPI_PTR(bcm_otpc_acpi_ids),
|
||||
},
|
||||
};
|
||||
module_platform_driver(bcm_otpc_driver);
|
||||
|
@@ -525,12 +525,14 @@ out:
|
||||
static struct nvmem_cell *
|
||||
nvmem_find_cell_by_name(struct nvmem_device *nvmem, const char *cell_id)
|
||||
{
|
||||
struct nvmem_cell *cell = NULL;
|
||||
struct nvmem_cell *iter, *cell = NULL;
|
||||
|
||||
mutex_lock(&nvmem_mutex);
|
||||
list_for_each_entry(cell, &nvmem->cells, node) {
|
||||
if (strcmp(cell_id, cell->name) == 0)
|
||||
list_for_each_entry(iter, &nvmem->cells, node) {
|
||||
if (strcmp(cell_id, iter->name) == 0) {
|
||||
cell = iter;
|
||||
break;
|
||||
}
|
||||
}
|
||||
mutex_unlock(&nvmem_mutex);
|
||||
|
||||
@@ -646,8 +648,8 @@ struct nvmem_device *nvmem_register(const struct nvmem_config *config)
|
||||
config->name ? config->id : nvmem->id);
|
||||
}
|
||||
|
||||
nvmem->read_only = device_property_present(config->dev, "read-only") |
|
||||
config->read_only;
|
||||
nvmem->read_only = device_property_present(config->dev, "read-only") ||
|
||||
config->read_only || !nvmem->reg_write;
|
||||
|
||||
if (config->root_only)
|
||||
nvmem->dev.groups = nvmem->read_only ?
|
||||
@@ -686,9 +688,7 @@ struct nvmem_device *nvmem_register(const struct nvmem_config *config)
|
||||
if (rval)
|
||||
goto err_remove_cells;
|
||||
|
||||
rval = blocking_notifier_call_chain(&nvmem_notifier, NVMEM_ADD, nvmem);
|
||||
if (rval)
|
||||
goto err_remove_cells;
|
||||
blocking_notifier_call_chain(&nvmem_notifier, NVMEM_ADD, nvmem);
|
||||
|
||||
return nvmem;
|
||||
|
||||
@@ -809,6 +809,7 @@ static struct nvmem_device *__nvmem_device_get(struct device_node *np,
|
||||
"could not increase module refcount for cell %s\n",
|
||||
nvmem_dev_name(nvmem));
|
||||
|
||||
put_device(&nvmem->dev);
|
||||
return ERR_PTR(-EINVAL);
|
||||
}
|
||||
|
||||
@@ -819,6 +820,7 @@ static struct nvmem_device *__nvmem_device_get(struct device_node *np,
|
||||
|
||||
static void __nvmem_device_put(struct nvmem_device *nvmem)
|
||||
{
|
||||
put_device(&nvmem->dev);
|
||||
module_put(nvmem->owner);
|
||||
kref_put(&nvmem->refcnt, nvmem_device_release);
|
||||
}
|
||||
@@ -837,13 +839,14 @@ struct nvmem_device *of_nvmem_device_get(struct device_node *np, const char *id)
|
||||
{
|
||||
|
||||
struct device_node *nvmem_np;
|
||||
int index;
|
||||
int index = 0;
|
||||
|
||||
index = of_property_match_string(np, "nvmem-names", id);
|
||||
if (id)
|
||||
index = of_property_match_string(np, "nvmem-names", id);
|
||||
|
||||
nvmem_np = of_parse_phandle(np, "nvmem", index);
|
||||
if (!nvmem_np)
|
||||
return ERR_PTR(-EINVAL);
|
||||
return ERR_PTR(-ENOENT);
|
||||
|
||||
return __nvmem_device_get(nvmem_np, NULL);
|
||||
}
|
||||
@@ -871,7 +874,7 @@ struct nvmem_device *nvmem_device_get(struct device *dev, const char *dev_name)
|
||||
|
||||
}
|
||||
|
||||
return nvmem_find(dev_name);
|
||||
return __nvmem_device_get(NULL, dev_name);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nvmem_device_get);
|
||||
|
||||
@@ -972,7 +975,7 @@ nvmem_cell_get_from_lookup(struct device *dev, const char *con_id)
|
||||
if (IS_ERR(nvmem)) {
|
||||
/* Provider may not be registered yet. */
|
||||
cell = ERR_CAST(nvmem);
|
||||
goto out;
|
||||
break;
|
||||
}
|
||||
|
||||
cell = nvmem_find_cell_by_name(nvmem,
|
||||
@@ -980,12 +983,11 @@ nvmem_cell_get_from_lookup(struct device *dev, const char *con_id)
|
||||
if (!cell) {
|
||||
__nvmem_device_put(nvmem);
|
||||
cell = ERR_PTR(-ENOENT);
|
||||
goto out;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
mutex_unlock(&nvmem_lookup_mutex);
|
||||
return cell;
|
||||
}
|
||||
@@ -994,12 +996,14 @@ out:
|
||||
static struct nvmem_cell *
|
||||
nvmem_find_cell_by_node(struct nvmem_device *nvmem, struct device_node *np)
|
||||
{
|
||||
struct nvmem_cell *cell = NULL;
|
||||
struct nvmem_cell *iter, *cell = NULL;
|
||||
|
||||
mutex_lock(&nvmem_mutex);
|
||||
list_for_each_entry(cell, &nvmem->cells, node) {
|
||||
if (np == cell->np)
|
||||
list_for_each_entry(iter, &nvmem->cells, node) {
|
||||
if (np == iter->np) {
|
||||
cell = iter;
|
||||
break;
|
||||
}
|
||||
}
|
||||
mutex_unlock(&nvmem_mutex);
|
||||
|
||||
@@ -1031,7 +1035,7 @@ struct nvmem_cell *of_nvmem_cell_get(struct device_node *np, const char *id)
|
||||
|
||||
cell_np = of_parse_phandle(np, "nvmem-cells", index);
|
||||
if (!cell_np)
|
||||
return ERR_PTR(-EINVAL);
|
||||
return ERR_PTR(-ENOENT);
|
||||
|
||||
nvmem_np = of_get_next_parent(cell_np);
|
||||
if (!nvmem_np)
|
||||
|
@@ -427,19 +427,32 @@ static const struct ocotp_params imx6ul_params = {
|
||||
.set_timing = imx_ocotp_set_imx6_timing,
|
||||
};
|
||||
|
||||
static const struct ocotp_params imx6ull_params = {
|
||||
.nregs = 64,
|
||||
.bank_address_words = 0,
|
||||
.set_timing = imx_ocotp_set_imx6_timing,
|
||||
};
|
||||
|
||||
static const struct ocotp_params imx7d_params = {
|
||||
.nregs = 64,
|
||||
.bank_address_words = 4,
|
||||
.set_timing = imx_ocotp_set_imx7_timing,
|
||||
};
|
||||
|
||||
static const struct ocotp_params imx7ulp_params = {
|
||||
.nregs = 256,
|
||||
.bank_address_words = 0,
|
||||
};
|
||||
|
||||
static const struct of_device_id imx_ocotp_dt_ids[] = {
|
||||
{ .compatible = "fsl,imx6q-ocotp", .data = &imx6q_params },
|
||||
{ .compatible = "fsl,imx6sl-ocotp", .data = &imx6sl_params },
|
||||
{ .compatible = "fsl,imx6sx-ocotp", .data = &imx6sx_params },
|
||||
{ .compatible = "fsl,imx6ul-ocotp", .data = &imx6ul_params },
|
||||
{ .compatible = "fsl,imx6ull-ocotp", .data = &imx6ull_params },
|
||||
{ .compatible = "fsl,imx7d-ocotp", .data = &imx7d_params },
|
||||
{ .compatible = "fsl,imx6sll-ocotp", .data = &imx6sll_params },
|
||||
{ .compatible = "fsl,imx7ulp-ocotp", .data = &imx7ulp_params },
|
||||
{ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, imx_ocotp_dt_ids);
|
||||
|
@@ -106,10 +106,12 @@ static int sc27xx_efuse_poll_status(struct sc27xx_efuse *efuse, u32 bits)
|
||||
static int sc27xx_efuse_read(void *context, u32 offset, void *val, size_t bytes)
|
||||
{
|
||||
struct sc27xx_efuse *efuse = context;
|
||||
u32 buf;
|
||||
u32 buf, blk_index = offset / SC27XX_EFUSE_BLOCK_WIDTH;
|
||||
u32 blk_offset = (offset % SC27XX_EFUSE_BLOCK_WIDTH) * BITS_PER_BYTE;
|
||||
int ret;
|
||||
|
||||
if (offset > SC27XX_EFUSE_BLOCK_MAX || bytes > SC27XX_EFUSE_BLOCK_WIDTH)
|
||||
if (blk_index > SC27XX_EFUSE_BLOCK_MAX ||
|
||||
bytes > SC27XX_EFUSE_BLOCK_WIDTH)
|
||||
return -EINVAL;
|
||||
|
||||
ret = sc27xx_efuse_lock(efuse);
|
||||
@@ -133,7 +135,7 @@ static int sc27xx_efuse_read(void *context, u32 offset, void *val, size_t bytes)
|
||||
/* Set the block address to be read. */
|
||||
ret = regmap_write(efuse->regmap,
|
||||
efuse->base + SC27XX_EFUSE_BLOCK_INDEX,
|
||||
offset & SC27XX_EFUSE_BLOCK_MASK);
|
||||
blk_index & SC27XX_EFUSE_BLOCK_MASK);
|
||||
if (ret)
|
||||
goto disable_efuse;
|
||||
|
||||
@@ -171,8 +173,10 @@ disable_efuse:
|
||||
unlock_efuse:
|
||||
sc27xx_efuse_unlock(efuse);
|
||||
|
||||
if (!ret)
|
||||
if (!ret) {
|
||||
buf >>= blk_offset;
|
||||
memcpy(val, &buf, bytes);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
Reference in New Issue
Block a user