mirror of
https://github.com/raspberrypi/linux.git
synced 2025-12-06 01:49:46 +00:00
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>
104 lines
2.5 KiB
C
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");
|