Files
linux/drivers/mfd/bcm2835-pm.c
Jonathan Bell f8f7b1136b drivers: char: add chardev for mmap'ing the RPiVid control registers
Based on the gpiomem driver, allow mapping of the decoder register
spaces such that userspace can access control/status registers.
This driver is intended for use with a custom ffmpeg backend accelerator
prior to a v4l2 driver being written.

Signed-off-by: Jonathan Bell <jonathan@raspberrypi.org>

driver: char: rpivid: Destroy the legacy device on remove

The legacy name support created a new device that was never destroyed.
If the driver was unloaded and reloaded, it failed due to the
device already existing.

Fixes: "75f1d14 driver: char: rpivid - also support legacy name"
Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>

driver: char: rpivid: Clean up error handling use of ERR_PTR/IS_ERR

The driver used an unnecessary intermediate void* variable so it
only called ERR_PTR once to convert to the error value.

Switch to converting as the error arises to remove these intermediate
variables.

Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>

driver: char: rpivid: Add error handling to the legacy device load

The return value from device_create for the legacy device was never
checked or handled. Add the required error handling.

Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>

driver: char: rpivid: Fix coding style whitespace issues.

Makes checkpatch happier.

Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>

driver: char: rpimem: Add SPDX licence header.

Stops checkpatch complaining.

Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>

driver: char: rpivid: Fix access to freed memory

The error path during probe frees the private memory block, and
then promptly dereferences it to log an error message.

Use the base device instead of the pointer to it in the private
structure.

Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
2021-01-27 19:13:01 +00:00

104 lines
2.5 KiB
C

// SPDX-License-Identifier: GPL-2.0+
/*
* PM MFD driver for Broadcom BCM2835
*
* This driver binds to the PM block and creates the MFD device for
* the WDT and power drivers.
*/
#include <linux/delay.h>
#include <linux/io.h>
#include <linux/mfd/bcm2835-pm.h>
#include <linux/mfd/core.h>
#include <linux/module.h>
#include <linux/of_address.h>
#include <linux/of_platform.h>
#include <linux/platform_device.h>
#include <linux/types.h>
#include <linux/watchdog.h>
static const struct mfd_cell bcm2835_pm_devs[] = {
{ .name = "bcm2835-wdt" },
};
static const struct mfd_cell bcm2835_power_devs[] = {
{ .name = "bcm2835-power" },
};
static int bcm2835_pm_probe(struct platform_device *pdev)
{
struct resource *res;
struct device *dev = &pdev->dev;
struct bcm2835_pm *pm;
int ret;
pm = devm_kzalloc(dev, sizeof(*pm), GFP_KERNEL);
if (!pm)
return -ENOMEM;
platform_set_drvdata(pdev, pm);
pm->dev = dev;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
pm->base = devm_ioremap_resource(dev, res);
if (IS_ERR(pm->base))
return PTR_ERR(pm->base);
ret = devm_mfd_add_devices(dev, -1,
bcm2835_pm_devs, ARRAY_SIZE(bcm2835_pm_devs),
NULL, 0, NULL);
if (ret)
return ret;
/* Map the RPiVid ASB regs if present. */
res = platform_get_resource(pdev, IORESOURCE_MEM, 2);
if (res) {
pm->rpivid_asb = devm_ioremap_resource(dev, res);
if (IS_ERR(pm->rpivid_asb)) {
dev_err(dev, "Failed to map RPiVid ASB: %ld\n",
PTR_ERR(pm->rpivid_asb));
return PTR_ERR(pm->rpivid_asb);
}
}
/* We'll use the presence of the AXI ASB regs in the
* bcm2835-pm binding as the key for whether we can reference
* the full PM register range and support power domains.
*/
res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
if (res) {
pm->asb = devm_ioremap_resource(dev, res);
if (IS_ERR(pm->asb))
return PTR_ERR(pm->asb);
ret = devm_mfd_add_devices(dev, -1,
bcm2835_power_devs,
ARRAY_SIZE(bcm2835_power_devs),
NULL, 0, NULL);
if (ret)
return ret;
}
return 0;
}
static const struct of_device_id bcm2835_pm_of_match[] = {
{ .compatible = "brcm,bcm2835-pm-wdt", },
{ .compatible = "brcm,bcm2835-pm", },
{},
};
MODULE_DEVICE_TABLE(of, bcm2835_pm_of_match);
static struct platform_driver bcm2835_pm_driver = {
.probe = bcm2835_pm_probe,
.driver = {
.name = "bcm2835-pm",
.of_match_table = bcm2835_pm_of_match,
},
};
module_platform_driver(bcm2835_pm_driver);
MODULE_AUTHOR("Eric Anholt <eric@anholt.net>");
MODULE_DESCRIPTION("Driver for Broadcom BCM2835 PM MFD");
MODULE_LICENSE("GPL");