diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2019-03-07 01:18:59 +0300 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2019-03-07 01:18:59 +0300 |
commit | 45763bf4bc1ebdf8eb95697607e1fd042a3e1221 (patch) | |
tree | c5b26c2d5d1190247b59d6d1fe68b8a247351362 /drivers/nvmem | |
parent | da2577fe63f865cd9dc785a42c29c0071f567a35 (diff) | |
parent | 142a0f83b216a607aebed42e54a1be620765e28c (diff) | |
download | linux-45763bf4bc1ebdf8eb95697607e1fd042a3e1221.tar.xz |
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
...
Diffstat (limited to 'drivers/nvmem')
-rw-r--r-- | drivers/nvmem/Kconfig | 2 | ||||
-rw-r--r-- | drivers/nvmem/bcm-ocotp.c | 37 | ||||
-rw-r--r-- | drivers/nvmem/core.c | 42 | ||||
-rw-r--r-- | drivers/nvmem/imx-ocotp.c | 13 | ||||
-rw-r--r-- | drivers/nvmem/sc27xx-efuse.c | 12 |
5 files changed, 65 insertions, 41 deletions
diff --git a/drivers/nvmem/Kconfig b/drivers/nvmem/Kconfig index 4ad846ceac7c..530d570724c9 100644 --- a/drivers/nvmem/Kconfig +++ b/drivers/nvmem/Kconfig @@ -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 diff --git a/drivers/nvmem/bcm-ocotp.c b/drivers/nvmem/bcm-ocotp.c index 4159b3f41d79..a8097511582a 100644 --- a/drivers/nvmem/bcm-ocotp.c +++ b/drivers/nvmem/bcm-ocotp.c @@ -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); diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c index f7301bb4ef3b..f24008b66826 100644 --- a/drivers/nvmem/core.c +++ b/drivers/nvmem/core.c @@ -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) diff --git a/drivers/nvmem/imx-ocotp.c b/drivers/nvmem/imx-ocotp.c index afb429a417fe..08a9b1ef8ae4 100644 --- a/drivers/nvmem/imx-ocotp.c +++ b/drivers/nvmem/imx-ocotp.c @@ -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); diff --git a/drivers/nvmem/sc27xx-efuse.c b/drivers/nvmem/sc27xx-efuse.c index 33185d8d82cf..c6ee21018d80 100644 --- a/drivers/nvmem/sc27xx-efuse.c +++ b/drivers/nvmem/sc27xx-efuse.c @@ -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; } |