diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2022-05-24 07:04:25 +0300 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2022-05-24 07:04:25 +0300 |
commit | d6edf95109661e5fb9b20613478470d2e8fa4455 (patch) | |
tree | a7901e2721318e002ec89214347c13fbc885cc3f /drivers | |
parent | 95fbef17e8253775876a08ec2011d3665b86a55f (diff) | |
parent | b6f21d14f1ac1261579b691673a0c823275cbaf8 (diff) | |
download | linux-d6edf95109661e5fb9b20613478470d2e8fa4455.tar.xz |
Merge tag 'for-linus' of git://git.armlinux.org.uk/~rmk/linux-arm
Pull ARM updates from Russell King:
- amba bus updates
- simplify ldr_this_cpu assembler macro for uniprocessor builds
- avoid explicit assembler literal loads
- more spectre-bhb improvements
- add Cortex-A9 Errata 764319 workaround
- add all unwind tables for modules
* tag 'for-linus' of git://git.armlinux.org.uk/~rmk/linux-arm:
ARM: 9204/2: module: Add all unwind tables when load module
ARM: 9206/1: A9: Add ARM ERRATA 764319 workaround (Updated)
ARM: 9201/1: spectre-bhb: rely on linker to emit cross-section literal loads
ARM: 9200/1: spectre-bhb: avoid cross-subsection jump using a numbered label
ARM: 9199/1: spectre-bhb: use local DSB and elide ISB in loop8 sequence
ARM: 9198/1: spectre-bhb: simplify BPIALL vector macro
ARM: 9195/1: entry: avoid explicit literal loads
ARM: 9194/1: assembler: simplify ldr_this_cpu for !SMP builds
ARM: 9192/1: amba: fix memory leak in amba_device_try_add()
ARM: 9193/1: amba: Add amba_read_periphid() helper
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/amba/bus.c | 137 |
1 files changed, 67 insertions, 70 deletions
diff --git a/drivers/amba/bus.c b/drivers/amba/bus.c index d3bd14aaabf6..7e775ba6fdd9 100644 --- a/drivers/amba/bus.c +++ b/drivers/amba/bus.c @@ -395,107 +395,104 @@ static void amba_device_release(struct device *dev) kfree(d); } -static int amba_device_try_add(struct amba_device *dev, struct resource *parent) +static int amba_read_periphid(struct amba_device *dev) { - u32 size; + struct reset_control *rstc; + u32 size, pid, cid; void __iomem *tmp; int i, ret; - ret = request_resource(parent, &dev->res); + ret = dev_pm_domain_attach(&dev->dev, true); if (ret) goto err_out; - /* Hard-coded primecell ID instead of plug-n-play */ - if (dev->periphid != 0) - goto skip_probe; + ret = amba_get_enable_pclk(dev); + if (ret) + goto err_pm; /* - * Dynamically calculate the size of the resource - * and use this for iomap + * Find reset control(s) of the amba bus and de-assert them. */ + rstc = of_reset_control_array_get_optional_shared(dev->dev.of_node); + if (IS_ERR(rstc)) { + ret = PTR_ERR(rstc); + if (ret != -EPROBE_DEFER) + dev_err(&dev->dev, "can't get reset: %d\n", ret); + goto err_clk; + } + reset_control_deassert(rstc); + reset_control_put(rstc); + size = resource_size(&dev->res); tmp = ioremap(dev->res.start, size); if (!tmp) { ret = -ENOMEM; - goto err_release; + goto err_clk; } - ret = dev_pm_domain_attach(&dev->dev, true); - if (ret) { - iounmap(tmp); - goto err_release; - } - - ret = amba_get_enable_pclk(dev); - if (ret == 0) { - u32 pid, cid; - struct reset_control *rstc; - - /* - * Find reset control(s) of the amba bus and de-assert them. - */ - rstc = of_reset_control_array_get_optional_shared(dev->dev.of_node); - if (IS_ERR(rstc)) { - ret = PTR_ERR(rstc); - if (ret != -EPROBE_DEFER) - dev_err(&dev->dev, "can't get reset: %d\n", - ret); - goto err_reset; - } - reset_control_deassert(rstc); - reset_control_put(rstc); - - /* - * Read pid and cid based on size of resource - * they are located at end of region - */ - for (pid = 0, i = 0; i < 4; i++) - pid |= (readl(tmp + size - 0x20 + 4 * i) & 255) << - (i * 8); - for (cid = 0, i = 0; i < 4; i++) - cid |= (readl(tmp + size - 0x10 + 4 * i) & 255) << - (i * 8); - - if (cid == CORESIGHT_CID) { - /* set the base to the start of the last 4k block */ - void __iomem *csbase = tmp + size - 4096; - - dev->uci.devarch = - readl(csbase + UCI_REG_DEVARCH_OFFSET); - dev->uci.devtype = - readl(csbase + UCI_REG_DEVTYPE_OFFSET) & 0xff; - } + /* + * Read pid and cid based on size of resource + * they are located at end of region + */ + for (pid = 0, i = 0; i < 4; i++) + pid |= (readl(tmp + size - 0x20 + 4 * i) & 255) << (i * 8); + for (cid = 0, i = 0; i < 4; i++) + cid |= (readl(tmp + size - 0x10 + 4 * i) & 255) << (i * 8); - amba_put_disable_pclk(dev); + if (cid == CORESIGHT_CID) { + /* set the base to the start of the last 4k block */ + void __iomem *csbase = tmp + size - 4096; - if (cid == AMBA_CID || cid == CORESIGHT_CID) { - dev->periphid = pid; - dev->cid = cid; - } + dev->uci.devarch = readl(csbase + UCI_REG_DEVARCH_OFFSET); + dev->uci.devtype = readl(csbase + UCI_REG_DEVTYPE_OFFSET) & 0xff; + } - if (!dev->periphid) - ret = -ENODEV; + if (cid == AMBA_CID || cid == CORESIGHT_CID) { + dev->periphid = pid; + dev->cid = cid; } + if (!dev->periphid) + ret = -ENODEV; + iounmap(tmp); + +err_clk: + amba_put_disable_pclk(dev); +err_pm: dev_pm_domain_detach(&dev->dev, true); +err_out: + return ret; +} + +static int amba_device_try_add(struct amba_device *dev, struct resource *parent) +{ + int ret; + ret = request_resource(parent, &dev->res); if (ret) + goto err_out; + + /* Hard-coded primecell ID instead of plug-n-play */ + if (dev->periphid != 0) + goto skip_probe; + + ret = amba_read_periphid(dev); + if (ret) { + if (ret != -EPROBE_DEFER) { + amba_device_put(dev); + goto err_out; + } goto err_release; + } - skip_probe: +skip_probe: ret = device_add(&dev->dev); - err_release: +err_release: if (ret) release_resource(&dev->res); - err_out: +err_out: return ret; - - err_reset: - amba_put_disable_pclk(dev); - iounmap(tmp); - dev_pm_domain_detach(&dev->dev, true); - goto err_release; } /* |