mirror of
https://github.com/torvalds/linux.git
synced 2026-05-25 07:33:19 +02:00
This pull request contains Broadcom SoCs drivers updates for 6.17,
please pull the following: - Andrea adds the RP1 clock, pinctrl/pinconf/gpio and misc driver to bind them all -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEm+Rq3+YGJdiR9yuFh9CWnEQHBwQFAmhi3rwACgkQh9CWnEQH BwSCmxAAwEDCorz31+5yt1NjJfS6DVbbXlN6EcZfa4Ysri3uGVQnUC/IdBou7UOO t03wnrQmrl2GXKSJBp5jvA6JbuTwBMeMtPy0e3Ayg+k5iJf0s+DgVO7NJeMhEHPP Y/TfcHvsVQkRJ2jaXl9zLA2PRQhKxVhvj0lTmm0AtHm0ctdxfqgJct1k65fj9/Qk sYbSQ+ZXT+1nLnoL1WoEl0QStIJGDNp4Jns0ZfHaYxFcc1AGZRLckYHyjxLjG1i3 b+t5uIpppbUIRLQTJpX7YlD8dk9laCACoD5P5aULPPBe2uykOeYViux/FTFgWrLY a8RYBZfAzw6HWYuUivWoMmnGzXPea+wKuT8IS776E/0wk/gAmuuu1eA2ioJ+pyj6 bAfAcgTL/gkaHKL1pH4OCu3SmMnhtYQQaERzHFf49Xucjaou3XM37YOhNo2hraNp jeS9f1HQUuBYr31FWjw6h19dbAWkJJ4Kzux9K9g1x3XSYVZeOv4POfrCztpYtA53 uDCdql21MNrjvRfE4xBcRGJ+j4PVOdB8UKJ77vo0+c+sKbVLLDGOSrqTbpagNSaR R7WBOgygPU8TSxqe7xzqds5ZGevMhQ0j8yJupxlYJoias4ak8q7hEL6WtJKDm+dQ pegyUzB/cYC5y+sKN3RFfQQ3s05Ee6UUXXEOntFAj8S/Ns3fOpU= =V+Co -----END PGP SIGNATURE----- gpgsig -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEo6/YBQwIrVS28WGKmmx57+YAGNkFAmh+VTAACgkQmmx57+YA GNkZWg/+OiQoQBMfhPuALhK3y/C3xE6m59Qio2EkyAVqJiDzsXEXs2AZrlqNCJ+G WVeJuEWHRYfeMf+XWpUZi/UL2agPNjFUOiV4m8ShikZ6mMiIhrzzpRquYcgAi1Ey GorgadJAOuWlDRQnVmJZ83+asRAlKnnKiwbJYmfgQTURyGd78LfUiMN2AucWH1+o MPZw8+uxrL56AOgHBrLAmaq5U0pLvUlp8wHByFhiIZ9jPQGTHlmoloVngHenaVfs hlMVghyh55G8VWrhnmls0cdz8CBvvXG3ZukcSXw7uFS7B+oJLbPyk1OSvst6dzh+ S43cX1X5hzAyVTlpIUMR4/Lyzd+x2DZalX2VwdT3x/FG4xAwG8nH/ZG2j5oXyES7 AMICQ2O/+heljpYYvqK4ZDR1ju+KEvOpmaO7aRWHlPIIMJnN6Z1dajdWoIpMlnv/ dHsNFzBE00dYZ+iqLbDw/L0HTN9v2diHrStrrHvhylq0Q2og/JtAlDWUis/s9doS 83DfSY7+BePVrwxVXb3Jf6WO0ADCQZ7xc3XuM0C9ptvQaHoyshXAHb9P6X/DTULd ErRYjS/5WZ9Bc0B15gY9Vwxe4UZTfryXcIdCLzVJ/4bHC1rf95b+GNILgtLNT58/ 8uDgd41fpVE2OnGIebeDOb1VBxRTMtSBg9iNWhnmfmzBNgVXHsI= =pldc -----END PGP SIGNATURE----- Merge tag 'arm-soc/for-6.17/drivers' of https://github.com/Broadcom/stblinux into soc/drivers This pull request contains Broadcom SoCs drivers updates for 6.17, please pull the following: - Andrea adds the RP1 clock, pinctrl/pinconf/gpio and misc driver to bind them all * tag 'arm-soc/for-6.17/drivers' of https://github.com/Broadcom/stblinux: pinctrl: rp1: Implement RaspberryPi RP1 pinmux/pinconf support misc: rp1: RaspberryPi RP1 misc driver pinctrl: rp1: Implement RaspberryPi RP1 gpio support clk: rp1: Add support for clocks provided by RP1 dt-bindings: clock: Add RaspberryPi RP1 clock bindings Link: https://lore.kernel.org/r/20250630190216.1518354-4-florian.fainelli@broadcom.com Signed-off-by: Arnd Bergmann <arnd@arndb.de>
This commit is contained in:
commit
aee4eeec7e
|
|
@ -0,0 +1,58 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/clock/raspberrypi,rp1-clocks.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: RaspberryPi RP1 clock generator
|
||||
|
||||
maintainers:
|
||||
- A. della Porta <andrea.porta@suse.com>
|
||||
|
||||
description: |
|
||||
The RP1 contains a clock generator designed as three PLLs (CORE, AUDIO,
|
||||
VIDEO), and each PLL output can be programmed through dividers to generate
|
||||
the clocks to drive the sub-peripherals embedded inside the chipset.
|
||||
|
||||
Link to datasheet:
|
||||
https://datasheets.raspberrypi.com/rp1/rp1-peripherals.pdf
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: raspberrypi,rp1-clocks
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
'#clock-cells':
|
||||
const: 1
|
||||
description:
|
||||
The available clocks are defined in
|
||||
include/dt-bindings/clock/raspberrypi,rp1-clocks.h.
|
||||
|
||||
clocks:
|
||||
maxItems: 1
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- '#clock-cells'
|
||||
- clocks
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/raspberrypi,rp1-clocks.h>
|
||||
|
||||
rp1 {
|
||||
#address-cells = <2>;
|
||||
#size-cells = <2>;
|
||||
|
||||
clocks@c040018000 {
|
||||
compatible = "raspberrypi,rp1-clocks";
|
||||
reg = <0xc0 0x40018000 0x0 0x10038>;
|
||||
#clock-cells = <1>;
|
||||
clocks = <&clk_rp1_xosc>;
|
||||
};
|
||||
};
|
||||
|
|
@ -88,6 +88,15 @@ config COMMON_CLK_RK808
|
|||
These multi-function devices have two fixed-rate oscillators, clocked at 32KHz each.
|
||||
Clkout1 is always on, Clkout2 can off by control register.
|
||||
|
||||
config COMMON_CLK_RP1
|
||||
tristate "Raspberry Pi RP1-based clock support"
|
||||
depends on MISC_RP1 || COMPILE_TEST
|
||||
default MISC_RP1
|
||||
help
|
||||
Enable common clock framework support for Raspberry Pi RP1.
|
||||
This multi-function device has 3 main PLLs and several clock
|
||||
generators to drive the internal sub-peripherals.
|
||||
|
||||
config COMMON_CLK_HI655X
|
||||
tristate "Clock driver for Hi655x" if EXPERT
|
||||
depends on (MFD_HI655X_PMIC || COMPILE_TEST)
|
||||
|
|
|
|||
|
|
@ -84,6 +84,7 @@ obj-$(CONFIG_CLK_LS1028A_PLLDIG) += clk-plldig.o
|
|||
obj-$(CONFIG_COMMON_CLK_PWM) += clk-pwm.o
|
||||
obj-$(CONFIG_CLK_QORIQ) += clk-qoriq.o
|
||||
obj-$(CONFIG_COMMON_CLK_RK808) += clk-rk808.o
|
||||
obj-$(CONFIG_COMMON_CLK_RP1) += clk-rp1.o
|
||||
obj-$(CONFIG_COMMON_CLK_HI655X) += clk-hi655x.o
|
||||
obj-$(CONFIG_COMMON_CLK_S2MPS11) += clk-s2mps11.o
|
||||
obj-$(CONFIG_COMMON_CLK_SCMI) += clk-scmi.o
|
||||
|
|
|
|||
1494
drivers/clk/clk-rp1.c
Normal file
1494
drivers/clk/clk-rp1.c
Normal file
File diff suppressed because it is too large
Load Diff
|
|
@ -660,4 +660,5 @@ source "drivers/misc/pvpanic/Kconfig"
|
|||
source "drivers/misc/mchp_pci1xxxx/Kconfig"
|
||||
source "drivers/misc/keba/Kconfig"
|
||||
source "drivers/misc/amd-sbi/Kconfig"
|
||||
source "drivers/misc/rp1/Kconfig"
|
||||
endmenu
|
||||
|
|
|
|||
|
|
@ -75,3 +75,4 @@ lan966x-pci-objs += lan966x_pci.dtbo.o
|
|||
obj-$(CONFIG_MCHP_LAN966X_PCI) += lan966x-pci.o
|
||||
obj-y += keba/
|
||||
obj-y += amd-sbi/
|
||||
obj-$(CONFIG_MISC_RP1) += rp1/
|
||||
|
|
|
|||
20
drivers/misc/rp1/Kconfig
Normal file
20
drivers/misc/rp1/Kconfig
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
#
|
||||
# RaspberryPi RP1 misc device
|
||||
#
|
||||
|
||||
config MISC_RP1
|
||||
tristate "RaspberryPi RP1 misc device"
|
||||
depends on OF_IRQ && OF_OVERLAY && PCI_MSI && PCI_QUIRKS
|
||||
select PCI_DYNAMIC_OF_NODES
|
||||
help
|
||||
Support the RP1 peripheral chip found on Raspberry Pi 5 board.
|
||||
|
||||
This device supports several sub-devices including e.g. Ethernet
|
||||
controller, USB controller, I2C, SPI and UART.
|
||||
|
||||
The driver is responsible for enabling the DT node once the PCIe
|
||||
endpoint has been configured, and handling interrupts.
|
||||
|
||||
This driver uses an overlay to load other drivers to support for
|
||||
RP1 internal sub-devices.
|
||||
3
drivers/misc/rp1/Makefile
Normal file
3
drivers/misc/rp1/Makefile
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
obj-$(CONFIG_MISC_RP1) += rp1-pci.o
|
||||
rp1-pci-objs := rp1_pci.o rp1-pci.dtbo.o
|
||||
25
drivers/misc/rp1/rp1-pci.dtso
Normal file
25
drivers/misc/rp1/rp1-pci.dtso
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
// SPDX-License-Identifier: (GPL-2.0 OR MIT)
|
||||
|
||||
/*
|
||||
* The dts overlay is included from the dts directory so
|
||||
* it can be possible to check it with CHECK_DTBS while
|
||||
* also compile it from the driver source directory.
|
||||
*/
|
||||
|
||||
/dts-v1/;
|
||||
/plugin/;
|
||||
|
||||
/ {
|
||||
fragment@0 {
|
||||
target-path="";
|
||||
__overlay__ {
|
||||
compatible = "pci1de4,1";
|
||||
#address-cells = <3>;
|
||||
#size-cells = <2>;
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <2>;
|
||||
|
||||
#include "arm64/broadcom/rp1-common.dtsi"
|
||||
};
|
||||
};
|
||||
};
|
||||
333
drivers/misc/rp1/rp1_pci.c
Normal file
333
drivers/misc/rp1/rp1_pci.c
Normal file
|
|
@ -0,0 +1,333 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Copyright (c) 2018-2025 Raspberry Pi Ltd.
|
||||
*
|
||||
* All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/err.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/irqchip/chained_irq.h>
|
||||
#include <linux/irqdomain.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/msi.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
#define RP1_HW_IRQ_MASK GENMASK(5, 0)
|
||||
|
||||
#define REG_SET 0x800
|
||||
#define REG_CLR 0xc00
|
||||
|
||||
/* MSI-X CFG registers start at 0x8 */
|
||||
#define MSIX_CFG(x) (0x8 + (4 * (x)))
|
||||
|
||||
#define MSIX_CFG_IACK_EN BIT(3)
|
||||
#define MSIX_CFG_IACK BIT(2)
|
||||
#define MSIX_CFG_ENABLE BIT(0)
|
||||
|
||||
/* Address map */
|
||||
#define RP1_PCIE_APBS_BASE 0x108000
|
||||
|
||||
/* Interrupts */
|
||||
#define RP1_INT_END 61
|
||||
|
||||
/* Embedded dtbo symbols created by cmd_wrap_S_dtb in scripts/Makefile.lib */
|
||||
extern char __dtbo_rp1_pci_begin[];
|
||||
extern char __dtbo_rp1_pci_end[];
|
||||
|
||||
struct rp1_dev {
|
||||
struct pci_dev *pdev;
|
||||
struct irq_domain *domain;
|
||||
struct irq_data *pcie_irqds[64];
|
||||
void __iomem *bar1;
|
||||
int ovcs_id; /* overlay changeset id */
|
||||
bool level_triggered_irq[RP1_INT_END];
|
||||
};
|
||||
|
||||
static void msix_cfg_set(struct rp1_dev *rp1, unsigned int hwirq, u32 value)
|
||||
{
|
||||
iowrite32(value, rp1->bar1 + RP1_PCIE_APBS_BASE + REG_SET + MSIX_CFG(hwirq));
|
||||
}
|
||||
|
||||
static void msix_cfg_clr(struct rp1_dev *rp1, unsigned int hwirq, u32 value)
|
||||
{
|
||||
iowrite32(value, rp1->bar1 + RP1_PCIE_APBS_BASE + REG_CLR + MSIX_CFG(hwirq));
|
||||
}
|
||||
|
||||
static void rp1_mask_irq(struct irq_data *irqd)
|
||||
{
|
||||
struct rp1_dev *rp1 = irqd->domain->host_data;
|
||||
struct irq_data *pcie_irqd = rp1->pcie_irqds[irqd->hwirq];
|
||||
|
||||
pci_msi_mask_irq(pcie_irqd);
|
||||
}
|
||||
|
||||
static void rp1_unmask_irq(struct irq_data *irqd)
|
||||
{
|
||||
struct rp1_dev *rp1 = irqd->domain->host_data;
|
||||
struct irq_data *pcie_irqd = rp1->pcie_irqds[irqd->hwirq];
|
||||
|
||||
pci_msi_unmask_irq(pcie_irqd);
|
||||
}
|
||||
|
||||
static int rp1_irq_set_type(struct irq_data *irqd, unsigned int type)
|
||||
{
|
||||
struct rp1_dev *rp1 = irqd->domain->host_data;
|
||||
unsigned int hwirq = (unsigned int)irqd->hwirq;
|
||||
|
||||
switch (type) {
|
||||
case IRQ_TYPE_LEVEL_HIGH:
|
||||
dev_dbg(&rp1->pdev->dev, "MSIX IACK EN for IRQ %u\n", hwirq);
|
||||
msix_cfg_set(rp1, hwirq, MSIX_CFG_IACK_EN);
|
||||
rp1->level_triggered_irq[hwirq] = true;
|
||||
break;
|
||||
case IRQ_TYPE_EDGE_RISING:
|
||||
msix_cfg_clr(rp1, hwirq, MSIX_CFG_IACK_EN);
|
||||
rp1->level_triggered_irq[hwirq] = false;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct irq_chip rp1_irq_chip = {
|
||||
.name = "rp1_irq_chip",
|
||||
.irq_mask = rp1_mask_irq,
|
||||
.irq_unmask = rp1_unmask_irq,
|
||||
.irq_set_type = rp1_irq_set_type,
|
||||
};
|
||||
|
||||
static void rp1_chained_handle_irq(struct irq_desc *desc)
|
||||
{
|
||||
unsigned int hwirq = desc->irq_data.hwirq & RP1_HW_IRQ_MASK;
|
||||
struct rp1_dev *rp1 = irq_desc_get_handler_data(desc);
|
||||
struct irq_chip *chip = irq_desc_get_chip(desc);
|
||||
unsigned int virq;
|
||||
|
||||
chained_irq_enter(chip, desc);
|
||||
|
||||
virq = irq_find_mapping(rp1->domain, hwirq);
|
||||
generic_handle_irq(virq);
|
||||
if (rp1->level_triggered_irq[hwirq])
|
||||
msix_cfg_set(rp1, hwirq, MSIX_CFG_IACK);
|
||||
|
||||
chained_irq_exit(chip, desc);
|
||||
}
|
||||
|
||||
static int rp1_irq_xlate(struct irq_domain *d, struct device_node *node,
|
||||
const u32 *intspec, unsigned int intsize,
|
||||
unsigned long *out_hwirq, unsigned int *out_type)
|
||||
{
|
||||
struct rp1_dev *rp1 = d->host_data;
|
||||
struct irq_data *pcie_irqd;
|
||||
unsigned long hwirq;
|
||||
int pcie_irq;
|
||||
int ret;
|
||||
|
||||
ret = irq_domain_xlate_twocell(d, node, intspec, intsize,
|
||||
&hwirq, out_type);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
pcie_irq = pci_irq_vector(rp1->pdev, hwirq);
|
||||
pcie_irqd = irq_get_irq_data(pcie_irq);
|
||||
rp1->pcie_irqds[hwirq] = pcie_irqd;
|
||||
*out_hwirq = hwirq;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rp1_irq_activate(struct irq_domain *d, struct irq_data *irqd,
|
||||
bool reserve)
|
||||
{
|
||||
struct rp1_dev *rp1 = d->host_data;
|
||||
|
||||
msix_cfg_set(rp1, (unsigned int)irqd->hwirq, MSIX_CFG_ENABLE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void rp1_irq_deactivate(struct irq_domain *d, struct irq_data *irqd)
|
||||
{
|
||||
struct rp1_dev *rp1 = d->host_data;
|
||||
|
||||
msix_cfg_clr(rp1, (unsigned int)irqd->hwirq, MSIX_CFG_ENABLE);
|
||||
}
|
||||
|
||||
static const struct irq_domain_ops rp1_domain_ops = {
|
||||
.xlate = rp1_irq_xlate,
|
||||
.activate = rp1_irq_activate,
|
||||
.deactivate = rp1_irq_deactivate,
|
||||
};
|
||||
|
||||
static void rp1_unregister_interrupts(struct pci_dev *pdev)
|
||||
{
|
||||
struct rp1_dev *rp1 = pci_get_drvdata(pdev);
|
||||
int irq, i;
|
||||
|
||||
if (rp1->domain) {
|
||||
for (i = 0; i < RP1_INT_END; i++) {
|
||||
irq = irq_find_mapping(rp1->domain, i);
|
||||
irq_dispose_mapping(irq);
|
||||
}
|
||||
|
||||
irq_domain_remove(rp1->domain);
|
||||
}
|
||||
|
||||
pci_free_irq_vectors(pdev);
|
||||
}
|
||||
|
||||
static int rp1_probe(struct pci_dev *pdev, const struct pci_device_id *id)
|
||||
{
|
||||
u32 dtbo_size = __dtbo_rp1_pci_end - __dtbo_rp1_pci_begin;
|
||||
void *dtbo_start = __dtbo_rp1_pci_begin;
|
||||
struct device *dev = &pdev->dev;
|
||||
struct device_node *rp1_node;
|
||||
bool skip_ovl = true;
|
||||
struct rp1_dev *rp1;
|
||||
int err = 0;
|
||||
int i;
|
||||
|
||||
/*
|
||||
* Either use rp1_nexus node if already present in DT, or
|
||||
* set a flag to load it from overlay at runtime
|
||||
*/
|
||||
rp1_node = of_find_node_by_name(NULL, "rp1_nexus");
|
||||
if (!rp1_node) {
|
||||
rp1_node = dev_of_node(dev);
|
||||
skip_ovl = false;
|
||||
}
|
||||
|
||||
if (!rp1_node) {
|
||||
dev_err(dev, "Missing of_node for device\n");
|
||||
err = -EINVAL;
|
||||
goto err_put_node;
|
||||
}
|
||||
|
||||
rp1 = devm_kzalloc(&pdev->dev, sizeof(*rp1), GFP_KERNEL);
|
||||
if (!rp1) {
|
||||
err = -ENOMEM;
|
||||
goto err_put_node;
|
||||
}
|
||||
|
||||
rp1->pdev = pdev;
|
||||
|
||||
if (pci_resource_len(pdev, 1) <= 0x10000) {
|
||||
dev_err(&pdev->dev,
|
||||
"Not initialized - is the firmware running?\n");
|
||||
err = -EINVAL;
|
||||
goto err_put_node;
|
||||
}
|
||||
|
||||
err = pcim_enable_device(pdev);
|
||||
if (err < 0) {
|
||||
err = dev_err_probe(&pdev->dev, err,
|
||||
"Enabling PCI device has failed");
|
||||
goto err_put_node;
|
||||
}
|
||||
|
||||
rp1->bar1 = pcim_iomap(pdev, 1, 0);
|
||||
if (!rp1->bar1) {
|
||||
dev_err(&pdev->dev, "Cannot map PCI BAR\n");
|
||||
err = -EIO;
|
||||
goto err_put_node;
|
||||
}
|
||||
|
||||
pci_set_master(pdev);
|
||||
|
||||
err = pci_alloc_irq_vectors(pdev, RP1_INT_END, RP1_INT_END,
|
||||
PCI_IRQ_MSIX);
|
||||
if (err < 0) {
|
||||
err = dev_err_probe(&pdev->dev, err,
|
||||
"Failed to allocate MSI-X vectors\n");
|
||||
goto err_put_node;
|
||||
} else if (err != RP1_INT_END) {
|
||||
dev_err(&pdev->dev, "Cannot allocate enough interrupts\n");
|
||||
err = -EINVAL;
|
||||
goto err_put_node;
|
||||
}
|
||||
|
||||
pci_set_drvdata(pdev, rp1);
|
||||
rp1->domain = irq_domain_add_linear(rp1_node, RP1_INT_END,
|
||||
&rp1_domain_ops, rp1);
|
||||
if (!rp1->domain) {
|
||||
dev_err(&pdev->dev, "Error creating IRQ domain\n");
|
||||
err = -ENOMEM;
|
||||
goto err_unregister_interrupts;
|
||||
}
|
||||
|
||||
for (i = 0; i < RP1_INT_END; i++) {
|
||||
unsigned int irq = irq_create_mapping(rp1->domain, i);
|
||||
|
||||
if (!irq) {
|
||||
dev_err(&pdev->dev, "Failed to create IRQ mapping\n");
|
||||
err = -EINVAL;
|
||||
goto err_unregister_interrupts;
|
||||
}
|
||||
|
||||
irq_set_chip_and_handler(irq, &rp1_irq_chip, handle_level_irq);
|
||||
irq_set_probe(irq);
|
||||
irq_set_chained_handler_and_data(pci_irq_vector(pdev, i),
|
||||
rp1_chained_handle_irq, rp1);
|
||||
}
|
||||
|
||||
if (!skip_ovl) {
|
||||
err = of_overlay_fdt_apply(dtbo_start, dtbo_size, &rp1->ovcs_id,
|
||||
rp1_node);
|
||||
if (err)
|
||||
goto err_unregister_interrupts;
|
||||
}
|
||||
|
||||
err = of_platform_default_populate(rp1_node, NULL, dev);
|
||||
if (err) {
|
||||
dev_err_probe(&pdev->dev, err, "Error populating devicetree\n");
|
||||
goto err_unload_overlay;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err_unload_overlay:
|
||||
of_overlay_remove(&rp1->ovcs_id);
|
||||
err_unregister_interrupts:
|
||||
rp1_unregister_interrupts(pdev);
|
||||
err_put_node:
|
||||
if (skip_ovl)
|
||||
of_node_put(rp1_node);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static void rp1_remove(struct pci_dev *pdev)
|
||||
{
|
||||
struct rp1_dev *rp1 = pci_get_drvdata(pdev);
|
||||
struct device *dev = &pdev->dev;
|
||||
|
||||
of_platform_depopulate(dev);
|
||||
of_overlay_remove(&rp1->ovcs_id);
|
||||
rp1_unregister_interrupts(pdev);
|
||||
}
|
||||
|
||||
static const struct pci_device_id dev_id_table[] = {
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_RPI, PCI_DEVICE_ID_RPI_RP1_C0), },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(pci, dev_id_table);
|
||||
|
||||
static struct pci_driver rp1_driver = {
|
||||
.name = KBUILD_MODNAME,
|
||||
.id_table = dev_id_table,
|
||||
.probe = rp1_probe,
|
||||
.remove = rp1_remove,
|
||||
};
|
||||
|
||||
module_pci_driver(rp1_driver);
|
||||
|
||||
MODULE_AUTHOR("Phil Elwell <phil@raspberrypi.com>");
|
||||
MODULE_AUTHOR("Andrea della Porta <andrea.porta@suse.com>");
|
||||
MODULE_DESCRIPTION("RaspberryPi RP1 misc device");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
|
@ -6303,6 +6303,7 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_XILINX, 0x5020, of_pci_make_dev_node);
|
|||
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_XILINX, 0x5021, of_pci_make_dev_node);
|
||||
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_REDHAT, 0x0005, of_pci_make_dev_node);
|
||||
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_EFAR, 0x9660, of_pci_make_dev_node);
|
||||
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_RPI, PCI_DEVICE_ID_RPI_RP1_C0, of_pci_make_dev_node);
|
||||
|
||||
/*
|
||||
* Devices known to require a longer delay before first config space access
|
||||
|
|
|
|||
|
|
@ -624,6 +624,17 @@ config PINCTRL_MLXBF3
|
|||
each pin. This driver can also be built as a module called
|
||||
pinctrl-mlxbf3.
|
||||
|
||||
config PINCTRL_RP1
|
||||
tristate "Pinctrl driver for RP1"
|
||||
depends on MISC_RP1
|
||||
default MISC_RP1
|
||||
select PINMUX
|
||||
select PINCONF
|
||||
select GENERIC_PINCONF
|
||||
help
|
||||
Enable the gpio and pinctrl/mux driver for RaspberryPi RP1
|
||||
multi function device.
|
||||
|
||||
source "drivers/pinctrl/actions/Kconfig"
|
||||
source "drivers/pinctrl/aspeed/Kconfig"
|
||||
source "drivers/pinctrl/bcm/Kconfig"
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@ obj-$(CONFIG_PINCTRL_PIC32) += pinctrl-pic32.o
|
|||
obj-$(CONFIG_PINCTRL_PISTACHIO) += pinctrl-pistachio.o
|
||||
obj-$(CONFIG_PINCTRL_RK805) += pinctrl-rk805.o
|
||||
obj-$(CONFIG_PINCTRL_ROCKCHIP) += pinctrl-rockchip.o
|
||||
obj-$(CONFIG_PINCTRL_RP1) += pinctrl-rp1.o
|
||||
obj-$(CONFIG_PINCTRL_SCMI) += pinctrl-scmi.o
|
||||
obj-$(CONFIG_PINCTRL_SINGLE) += pinctrl-single.o
|
||||
obj-$(CONFIG_PINCTRL_ST) += pinctrl-st.o
|
||||
|
|
|
|||
1829
drivers/pinctrl/pinctrl-rp1.c
Normal file
1829
drivers/pinctrl/pinctrl-rp1.c
Normal file
File diff suppressed because it is too large
Load Diff
61
include/dt-bindings/clock/raspberrypi,rp1-clocks.h
Normal file
61
include/dt-bindings/clock/raspberrypi,rp1-clocks.h
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
|
||||
/*
|
||||
* Copyright (C) 2021 Raspberry Pi Ltd.
|
||||
*/
|
||||
|
||||
#ifndef __DT_BINDINGS_CLOCK_RASPBERRYPI_RP1
|
||||
#define __DT_BINDINGS_CLOCK_RASPBERRYPI_RP1
|
||||
|
||||
#define RP1_PLL_SYS_CORE 0
|
||||
#define RP1_PLL_AUDIO_CORE 1
|
||||
#define RP1_PLL_VIDEO_CORE 2
|
||||
|
||||
#define RP1_PLL_SYS 3
|
||||
#define RP1_PLL_AUDIO 4
|
||||
#define RP1_PLL_VIDEO 5
|
||||
|
||||
#define RP1_PLL_SYS_PRI_PH 6
|
||||
#define RP1_PLL_SYS_SEC_PH 7
|
||||
#define RP1_PLL_AUDIO_PRI_PH 8
|
||||
|
||||
#define RP1_PLL_SYS_SEC 9
|
||||
#define RP1_PLL_AUDIO_SEC 10
|
||||
#define RP1_PLL_VIDEO_SEC 11
|
||||
|
||||
#define RP1_CLK_SYS 12
|
||||
#define RP1_CLK_SLOW_SYS 13
|
||||
#define RP1_CLK_DMA 14
|
||||
#define RP1_CLK_UART 15
|
||||
#define RP1_CLK_ETH 16
|
||||
#define RP1_CLK_PWM0 17
|
||||
#define RP1_CLK_PWM1 18
|
||||
#define RP1_CLK_AUDIO_IN 19
|
||||
#define RP1_CLK_AUDIO_OUT 20
|
||||
#define RP1_CLK_I2S 21
|
||||
#define RP1_CLK_MIPI0_CFG 22
|
||||
#define RP1_CLK_MIPI1_CFG 23
|
||||
#define RP1_CLK_PCIE_AUX 24
|
||||
#define RP1_CLK_USBH0_MICROFRAME 25
|
||||
#define RP1_CLK_USBH1_MICROFRAME 26
|
||||
#define RP1_CLK_USBH0_SUSPEND 27
|
||||
#define RP1_CLK_USBH1_SUSPEND 28
|
||||
#define RP1_CLK_ETH_TSU 29
|
||||
#define RP1_CLK_ADC 30
|
||||
#define RP1_CLK_SDIO_TIMER 31
|
||||
#define RP1_CLK_SDIO_ALT_SRC 32
|
||||
#define RP1_CLK_GP0 33
|
||||
#define RP1_CLK_GP1 34
|
||||
#define RP1_CLK_GP2 35
|
||||
#define RP1_CLK_GP3 36
|
||||
#define RP1_CLK_GP4 37
|
||||
#define RP1_CLK_GP5 38
|
||||
#define RP1_CLK_VEC 39
|
||||
#define RP1_CLK_DPI 40
|
||||
#define RP1_CLK_MIPI0_DPI 41
|
||||
#define RP1_CLK_MIPI1_DPI 42
|
||||
|
||||
/* Extra PLL output channels - RP1B0 only */
|
||||
#define RP1_PLL_VIDEO_PRI_PH 43
|
||||
#define RP1_PLL_AUDIO_TERN 44
|
||||
|
||||
#endif
|
||||
|
|
@ -2624,6 +2624,9 @@
|
|||
#define PCI_VENDOR_ID_TEKRAM 0x1de1
|
||||
#define PCI_DEVICE_ID_TEKRAM_DC290 0xdc29
|
||||
|
||||
#define PCI_VENDOR_ID_RPI 0x1de4
|
||||
#define PCI_DEVICE_ID_RPI_RP1_C0 0x0001
|
||||
|
||||
#define PCI_VENDOR_ID_ALIBABA 0x1ded
|
||||
|
||||
#define PCI_VENDOR_ID_CXL 0x1e98
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user