mirror of
https://github.com/linux-msm/laptops-kernel.git
synced 2026-08-13 14:19:53 -07:00
Merge branch 'soc_fsl' of https://git.kernel.org/pub/scm/linux/kernel/git/chleroy/linux.git
This commit is contained in:
@@ -0,0 +1,84 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/gpio/fsl,mpc8323-qe-pario-bank.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Freescale QUICC Engine Parallel I/O (QE PARIO) GPIO Bank
|
||||
|
||||
maintainers:
|
||||
- Christophe Leroy <christophe.leroy@csgroup.eu>
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
oneOf:
|
||||
- items:
|
||||
- enum:
|
||||
- fsl,mpc8360-qe-pario-bank
|
||||
- fsl,mpc8569-qe-pario-bank
|
||||
- const: fsl,mpc8323-qe-pario-bank
|
||||
- const: fsl,mpc8323-qe-pario-bank
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
gpio-controller: true
|
||||
|
||||
"#gpio-cells":
|
||||
const: 2
|
||||
|
||||
"#address-cells":
|
||||
const: 0
|
||||
|
||||
"#interrupt-cells":
|
||||
const: 2
|
||||
|
||||
interrupt-map:
|
||||
description: |
|
||||
Specifies the mapping of GPIO lines to the parent interrupt controller, as the
|
||||
GPIO controller does not do interrupt handling itself.
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- gpio-controller
|
||||
- "#gpio-cells"
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/interrupt-controller/irq.h>
|
||||
|
||||
gpio-controller@1400 {
|
||||
compatible = "fsl,mpc8360-qe-pario-bank", "fsl,mpc8323-qe-pario-bank";
|
||||
reg = <0x1400 0x18>;
|
||||
gpio-controller;
|
||||
#gpio-cells = <2>;
|
||||
};
|
||||
|
||||
gpio-controller@1418 {
|
||||
compatible = "fsl,mpc8323-qe-pario-bank";
|
||||
reg = <0x1418 0x18>;
|
||||
gpio-controller;
|
||||
#gpio-cells = <2>;
|
||||
#address-cells = <0>;
|
||||
#interrupt-cells = <2>;
|
||||
interrupt-map = <
|
||||
7 IRQ_TYPE_EDGE_FALLING &pic 4 IRQ_TYPE_EDGE_FALLING
|
||||
7 IRQ_TYPE_EDGE_BOTH &pic 4 IRQ_TYPE_EDGE_BOTH
|
||||
7 0 &pic 4 IRQ_TYPE_NONE
|
||||
|
||||
9 IRQ_TYPE_EDGE_FALLING &pic 5 IRQ_TYPE_EDGE_FALLING
|
||||
9 IRQ_TYPE_EDGE_BOTH &pic 5 IRQ_TYPE_EDGE_BOTH
|
||||
9 0 &pic 5 IRQ_TYPE_NONE
|
||||
|
||||
25 IRQ_TYPE_EDGE_FALLING &pic 6 IRQ_TYPE_EDGE_FALLING
|
||||
25 IRQ_TYPE_EDGE_BOTH &pic 6 IRQ_TYPE_EDGE_BOTH
|
||||
25 0 &pic 6 IRQ_TYPE_NONE
|
||||
|
||||
27 IRQ_TYPE_EDGE_FALLING &pic 7 IRQ_TYPE_EDGE_FALLING
|
||||
27 IRQ_TYPE_EDGE_BOTH &pic 7 IRQ_TYPE_EDGE_BOTH
|
||||
27 0 &pic 7 IRQ_TYPE_NONE
|
||||
>;
|
||||
};
|
||||
@@ -23,7 +23,7 @@ properties:
|
||||
const: 0
|
||||
|
||||
'#interrupt-cells':
|
||||
const: 1
|
||||
const: 2
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
@@ -45,7 +45,7 @@ examples:
|
||||
reg = <0xc00 0x18>;
|
||||
interrupt-controller;
|
||||
#address-cells = <0>;
|
||||
#interrupt-cells = <1>;
|
||||
#interrupt-cells = <2>;
|
||||
interrupts = <74 0x8>;
|
||||
interrupt-parent = <&ipic>;
|
||||
};
|
||||
|
||||
@@ -24,28 +24,4 @@ par_io@1400 {
|
||||
|
||||
Note that "par_io" nodes are obsolete, and should not be used for
|
||||
the new device trees. Instead, each Par I/O bank should be represented
|
||||
via its own gpio-controller node:
|
||||
|
||||
Required properties:
|
||||
- #gpio-cells : should be "2".
|
||||
- compatible : should be "fsl,<chip>-qe-pario-bank",
|
||||
"fsl,mpc8323-qe-pario-bank".
|
||||
- reg : offset to the register set and its length.
|
||||
- gpio-controller : node to identify gpio controllers.
|
||||
|
||||
Example:
|
||||
qe_pio_a: gpio-controller@1400 {
|
||||
#gpio-cells = <2>;
|
||||
compatible = "fsl,mpc8360-qe-pario-bank",
|
||||
"fsl,mpc8323-qe-pario-bank";
|
||||
reg = <0x1400 0x18>;
|
||||
gpio-controller;
|
||||
};
|
||||
|
||||
qe_pio_e: gpio-controller@1460 {
|
||||
#gpio-cells = <2>;
|
||||
compatible = "fsl,mpc8360-qe-pario-bank",
|
||||
"fsl,mpc8323-qe-pario-bank";
|
||||
reg = <0x1460 0x18>;
|
||||
gpio-controller;
|
||||
};
|
||||
via its own gpio-controller node.
|
||||
|
||||
@@ -36,7 +36,20 @@ properties:
|
||||
- const: simple-mfd
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
minItems: 1
|
||||
items:
|
||||
- description:
|
||||
Customer-visible DCFG register map from CCSR address space
|
||||
(Configuration, Control and Status Registers)
|
||||
- description:
|
||||
Customer-hidden DCFG register map from DCSR address space
|
||||
(Debug Control and Status Registers)
|
||||
|
||||
reg-names:
|
||||
minItems: 1
|
||||
items:
|
||||
- const: dcfg_ccsr
|
||||
- const: dcfg_dcsr
|
||||
|
||||
little-endian: true
|
||||
big-endian: true
|
||||
|
||||
+1
-1
@@ -7814,7 +7814,7 @@ F: Documentation/devicetree/bindings/media/i2c/dongwoon,dw9807-vcm.yaml
|
||||
F: drivers/media/i2c/dw9807-vcm.c
|
||||
|
||||
DPAA2 DATAPATH I/O (DPIO) DRIVER
|
||||
M: Roy Pledge <Roy.Pledge@nxp.com>
|
||||
M: Ioana Ciornei <ioana.ciornei@nxp.com>
|
||||
L: linux-kernel@vger.kernel.org
|
||||
S: Maintained
|
||||
F: drivers/soc/fsl/dpio
|
||||
|
||||
@@ -228,14 +228,6 @@ config TAU_AVERAGE
|
||||
|
||||
If in doubt, say N here.
|
||||
|
||||
config QE_GPIO
|
||||
bool "QE GPIO support"
|
||||
depends on QUICC_ENGINE
|
||||
select GPIOLIB
|
||||
help
|
||||
Say Y here if you're going to use hardware that connects to the
|
||||
QE GPIOs.
|
||||
|
||||
config CPM2
|
||||
bool "Enable support for the CPM2 (Communications Processor Module)"
|
||||
depends on (FSL_SOC_BOOKE && PPC32) || PPC_82xx
|
||||
|
||||
@@ -521,12 +521,8 @@ static int register_dprc_irq_handler(struct fsl_mc_device *mc_dev)
|
||||
IRQF_NO_SUSPEND | IRQF_ONESHOT,
|
||||
dev_name(&mc_dev->dev),
|
||||
&mc_dev->dev);
|
||||
if (error < 0) {
|
||||
dev_err(&mc_dev->dev,
|
||||
"devm_request_threaded_irq() failed: %d\n",
|
||||
error);
|
||||
if (error < 0)
|
||||
return error;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -908,7 +908,7 @@ struct fsl_mc_device *fsl_mc_get_endpoint(struct fsl_mc_device *mc_dev,
|
||||
int state, err;
|
||||
|
||||
mc_bus_dev = to_fsl_mc_device(mc_dev->dev.parent);
|
||||
strcpy(endpoint1.type, mc_dev->obj_desc.type);
|
||||
strscpy(endpoint1.type, mc_dev->obj_desc.type);
|
||||
endpoint1.id = mc_dev->obj_desc.id;
|
||||
endpoint1.if_id = if_id;
|
||||
|
||||
@@ -925,7 +925,7 @@ struct fsl_mc_device *fsl_mc_get_endpoint(struct fsl_mc_device *mc_dev,
|
||||
return ERR_PTR(err);
|
||||
}
|
||||
|
||||
strcpy(endpoint_desc.type, endpoint2.type);
|
||||
strscpy(endpoint_desc.type, endpoint2.type);
|
||||
endpoint_desc.id = endpoint2.id;
|
||||
endpoint = fsl_mc_device_lookup(&endpoint_desc, mc_bus_dev);
|
||||
if (endpoint)
|
||||
|
||||
@@ -58,6 +58,7 @@ config PHY_FSL_LYNX_10G
|
||||
tristate "Freescale Layerscape Lynx 10G SerDes PHY support"
|
||||
depends on OF
|
||||
depends on ARCH_LAYERSCAPE || COMPILE_TEST
|
||||
select FSL_GUTS
|
||||
select GENERIC_PHY
|
||||
select PHY_FSL_LYNX_CORE
|
||||
help
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include <linux/phy/phy.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <linux/fsl/guts.h>
|
||||
|
||||
#include "phy-fsl-lynx-core.h"
|
||||
|
||||
@@ -1167,14 +1168,7 @@ static bool lynx_10g_lane_mode_needs_rcw_override(struct lynx_lane *lane,
|
||||
|
||||
/* Major protocol changes, which involve changing the PCS connection to
|
||||
* the GMII MAC with the one to the XGMII MAC, require an RCW override
|
||||
* procedure to reconfigure an internal mux, as documented here:
|
||||
* https://lore.kernel.org/linux-phy/20230810102631.bvozjer3t67r67iy@skbuf/
|
||||
* This is SoC-specific, and not yet implemented in drivers/soc/fsl/guts.c.
|
||||
*
|
||||
* So the supported set of protocols depends on the initial lane mode.
|
||||
*
|
||||
* Minor protocol changes (SGMII <-> 1000Base-X <-> 2500Base-X or
|
||||
* 10GBase-R <-> USXGMII) are supported.
|
||||
* procedure to reconfigure an internal mux.
|
||||
*/
|
||||
if ((lynx_lane_mode_uses_gmii_mac(curr) &&
|
||||
lynx_lane_mode_uses_xgmii_mac(new)) ||
|
||||
@@ -1189,6 +1183,7 @@ static int lynx_10g_validate(struct phy *phy, enum phy_mode mode, int submode,
|
||||
union phy_configure_opts *opts)
|
||||
{
|
||||
struct lynx_lane *lane = phy_get_drvdata(phy);
|
||||
struct lynx_priv *priv = lane->priv;
|
||||
enum lynx_lane_mode lane_mode;
|
||||
int err;
|
||||
|
||||
@@ -1197,7 +1192,8 @@ static int lynx_10g_validate(struct phy *phy, enum phy_mode mode, int submode,
|
||||
return err;
|
||||
|
||||
if (lynx_10g_lane_mode_needs_rcw_override(lane, lane_mode))
|
||||
return -EINVAL;
|
||||
return fsl_guts_lane_validate(priv->info->index, lane->id,
|
||||
lane_mode);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1205,6 +1201,7 @@ static int lynx_10g_validate(struct phy *phy, enum phy_mode mode, int submode,
|
||||
static int lynx_10g_set_mode(struct phy *phy, enum phy_mode mode, int submode)
|
||||
{
|
||||
struct lynx_lane *lane = phy_get_drvdata(phy);
|
||||
struct lynx_priv *priv = lane->priv;
|
||||
bool powered_up = lane->powered_up;
|
||||
enum lynx_lane_mode lane_mode;
|
||||
int err;
|
||||
@@ -1225,6 +1222,13 @@ static int lynx_10g_set_mode(struct phy *phy, enum phy_mode mode, int submode)
|
||||
if (powered_up)
|
||||
lynx_10g_lane_halt(phy);
|
||||
|
||||
if (lynx_10g_lane_mode_needs_rcw_override(lane, lane_mode)) {
|
||||
err = fsl_guts_lane_set_mode(priv->info->index, lane->id,
|
||||
lane_mode);
|
||||
if (err)
|
||||
goto out;
|
||||
}
|
||||
|
||||
err = lynx_10g_lane_disable_pcvt(lane, lane->mode);
|
||||
if (err)
|
||||
goto out;
|
||||
@@ -1314,6 +1318,7 @@ static struct platform_driver lynx_10g_driver = {
|
||||
};
|
||||
module_platform_driver(lynx_10g_driver);
|
||||
|
||||
MODULE_IMPORT_NS("FSL_GUTS");
|
||||
MODULE_IMPORT_NS("PHY_FSL_LYNX");
|
||||
MODULE_AUTHOR("Ioana Ciornei <ioana.ciornei@nxp.com>");
|
||||
MODULE_AUTHOR("Vladimir Oltean <vladimir.oltean@nxp.com>");
|
||||
|
||||
@@ -102,12 +102,8 @@ static int register_dpio_irq_handlers(struct fsl_mc_device *dpio_dev, int cpu)
|
||||
0,
|
||||
dev_name(&dpio_dev->dev),
|
||||
&dpio_dev->dev);
|
||||
if (error < 0) {
|
||||
dev_err(&dpio_dev->dev,
|
||||
"devm_request_irq() failed: %d\n",
|
||||
error);
|
||||
if (error < 0)
|
||||
return error;
|
||||
}
|
||||
|
||||
/* set the affinity hint */
|
||||
if (irq_set_affinity_hint(irq->virq, cpumask_of(cpu)))
|
||||
|
||||
+488
-40
File diff suppressed because it is too large
Load Diff
@@ -67,3 +67,12 @@ config QE_USB
|
||||
default y if USB_FSL_QE
|
||||
help
|
||||
QE USB Controller support
|
||||
|
||||
config QE_GPIO
|
||||
bool "QE GPIO support"
|
||||
depends on QUICC_ENGINE
|
||||
select GENERIC_IRQ_CHIP
|
||||
select GPIOLIB
|
||||
help
|
||||
Say Y here if you're going to use hardware that connects to the
|
||||
QE GPIOs.
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#include <linux/gpio/driver.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/export.h>
|
||||
#include <linux/of_irq.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
#include <soc/fsl/qe/qe.h>
|
||||
@@ -23,6 +24,7 @@
|
||||
#define PIN_MASK(gpio) (1UL << (QE_PIO_PINS - 1 - (gpio)))
|
||||
|
||||
struct qe_gpio_chip {
|
||||
struct device_node *np;
|
||||
struct gpio_chip gc;
|
||||
void __iomem *regs;
|
||||
spinlock_t lock;
|
||||
@@ -135,6 +137,53 @@ static int qe_gpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int qe_gpio_get_direction(struct gpio_chip *gc, unsigned int gpio)
|
||||
{
|
||||
struct qe_gpio_chip *qe_gc = gpiochip_get_data(gc);
|
||||
struct qe_pio_regs __iomem *regs = qe_gc->regs;
|
||||
unsigned long flags;
|
||||
u32 val, mask;
|
||||
|
||||
spin_lock_irqsave(&qe_gc->lock, flags);
|
||||
|
||||
if (gpio < QE_PIO_PINS / 2)
|
||||
val = ioread32be(®s->cpdir1);
|
||||
else
|
||||
val = ioread32be(®s->cpdir2);
|
||||
|
||||
spin_unlock_irqrestore(&qe_gc->lock, flags);
|
||||
|
||||
mask = (u32)QE_PIO_DIR_OUT << (QE_PIO_PINS - 2 - (gpio % (QE_PIO_PINS / 2)) * 2);
|
||||
|
||||
if (val & mask)
|
||||
return GPIO_LINE_DIRECTION_OUT;
|
||||
else
|
||||
return GPIO_LINE_DIRECTION_IN;
|
||||
}
|
||||
|
||||
static int qe_gpio_to_irq(struct gpio_chip *gc, unsigned int gpio)
|
||||
{
|
||||
struct qe_gpio_chip *qe_gc = gpiochip_get_data(gc);
|
||||
struct of_phandle_args oirq;
|
||||
struct irq_domain *domain;
|
||||
int ret;
|
||||
|
||||
oirq.np = qe_gc->np;
|
||||
oirq.args_count = 2;
|
||||
oirq.args[0] = gpio;
|
||||
oirq.args[1] = 0;
|
||||
|
||||
ret = of_irq_parse_raw(NULL, &oirq);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
domain = irq_find_host(oirq.np);
|
||||
if (!domain)
|
||||
return -EPROBE_DEFER;
|
||||
|
||||
return irq_create_of_mapping(&oirq);
|
||||
}
|
||||
|
||||
struct qe_pin {
|
||||
/*
|
||||
* The qe_gpio_chip name is unfortunate, we should change that to
|
||||
@@ -299,7 +348,7 @@ static int qe_gpio_probe(struct platform_device *ofdev)
|
||||
qe_gc = devm_kzalloc(dev, sizeof(*qe_gc), GFP_KERNEL);
|
||||
if (!qe_gc)
|
||||
return -ENOMEM;
|
||||
|
||||
qe_gc->np = np;
|
||||
spin_lock_init(&qe_gc->lock);
|
||||
|
||||
gc = &qe_gc->gc;
|
||||
@@ -308,9 +357,11 @@ static int qe_gpio_probe(struct platform_device *ofdev)
|
||||
gc->ngpio = QE_PIO_PINS;
|
||||
gc->direction_input = qe_gpio_dir_in;
|
||||
gc->direction_output = qe_gpio_dir_out;
|
||||
gc->get_direction = qe_gpio_get_direction;
|
||||
gc->get = qe_gpio_get;
|
||||
gc->set = qe_gpio_set;
|
||||
gc->set_multiple = qe_gpio_set_multiple;
|
||||
gc->to_irq = qe_gpio_to_irq;
|
||||
gc->parent = dev;
|
||||
gc->owner = THIS_MODULE;
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#include <linux/errno.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/ioport.h>
|
||||
#include <linux/of_platform.h>
|
||||
|
||||
#include <asm/io.h>
|
||||
#include <soc/fsl/qe/qe.h>
|
||||
@@ -184,3 +185,17 @@ int par_io_of_config(struct device_node *np)
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(par_io_of_config);
|
||||
|
||||
static int __init par_io_populate(void)
|
||||
{
|
||||
struct device_node *np = of_find_node_by_type(NULL, "par_io");
|
||||
|
||||
if (!np)
|
||||
return 0;
|
||||
|
||||
of_platform_default_populate(np, NULL, NULL);
|
||||
of_node_put(np);
|
||||
|
||||
return 0;
|
||||
}
|
||||
arch_initcall(par_io_populate);
|
||||
|
||||
@@ -5,7 +5,9 @@
|
||||
* Copyright (c) 2025 Christophe Leroy CS GROUP France (christophe.leroy@csgroup.eu)
|
||||
*/
|
||||
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/irqchip/chained_irq.h>
|
||||
#include <linux/irqdomain.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
@@ -16,116 +18,158 @@
|
||||
|
||||
struct qepic_data {
|
||||
void __iomem *reg;
|
||||
struct irq_domain *host;
|
||||
int irq;
|
||||
int parent_irq;
|
||||
};
|
||||
|
||||
static void qepic_mask(struct irq_data *d)
|
||||
{
|
||||
struct qepic_data *data = irq_data_get_irq_chip_data(d);
|
||||
struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
|
||||
u32 val;
|
||||
|
||||
clrbits32(data->reg + CEPIMR, 1 << (31 - irqd_to_hwirq(d)));
|
||||
guard(raw_spinlock)(&gc->lock);
|
||||
|
||||
val = ioread32be(gc->reg_base + CEPIMR);
|
||||
iowrite32be(val & ~d->mask, gc->reg_base + CEPIMR);
|
||||
}
|
||||
|
||||
static void qepic_unmask(struct irq_data *d)
|
||||
{
|
||||
struct qepic_data *data = irq_data_get_irq_chip_data(d);
|
||||
struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
|
||||
u32 val;
|
||||
|
||||
setbits32(data->reg + CEPIMR, 1 << (31 - irqd_to_hwirq(d)));
|
||||
guard(raw_spinlock)(&gc->lock);
|
||||
|
||||
val = ioread32be(gc->reg_base + CEPIMR);
|
||||
iowrite32be(val | d->mask, gc->reg_base + CEPIMR);
|
||||
}
|
||||
|
||||
static void qepic_end(struct irq_data *d)
|
||||
{
|
||||
struct qepic_data *data = irq_data_get_irq_chip_data(d);
|
||||
struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
|
||||
|
||||
out_be32(data->reg + CEPIER, 1 << (31 - irqd_to_hwirq(d)));
|
||||
iowrite32be(d->mask, gc->reg_base + CEPIER);
|
||||
}
|
||||
|
||||
static void qepic_calc_mask(struct irq_data *d)
|
||||
{
|
||||
d->mask = 1 << (31 - irqd_to_hwirq(d));
|
||||
}
|
||||
|
||||
static int qepic_set_type(struct irq_data *d, unsigned int flow_type)
|
||||
{
|
||||
struct qepic_data *data = irq_data_get_irq_chip_data(d);
|
||||
unsigned int vec = (unsigned int)irqd_to_hwirq(d);
|
||||
struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
|
||||
u32 val;
|
||||
|
||||
guard(raw_spinlock)(&gc->lock);
|
||||
|
||||
val = ioread32be(gc->reg_base + CEPICR);
|
||||
switch (flow_type & IRQ_TYPE_SENSE_MASK) {
|
||||
case IRQ_TYPE_EDGE_FALLING:
|
||||
setbits32(data->reg + CEPICR, 1 << (31 - vec));
|
||||
iowrite32be(val | d->mask, gc->reg_base + CEPICR);
|
||||
return 0;
|
||||
case IRQ_TYPE_EDGE_BOTH:
|
||||
case IRQ_TYPE_NONE:
|
||||
clrbits32(data->reg + CEPICR, 1 << (31 - vec));
|
||||
iowrite32be(val & ~d->mask, gc->reg_base + CEPICR);
|
||||
return 0;
|
||||
}
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static struct irq_chip qepic = {
|
||||
.name = "QEPIC",
|
||||
.irq_mask = qepic_mask,
|
||||
.irq_unmask = qepic_unmask,
|
||||
.irq_eoi = qepic_end,
|
||||
.irq_set_type = qepic_set_type,
|
||||
};
|
||||
|
||||
static int qepic_get_irq(struct irq_desc *desc)
|
||||
{
|
||||
struct qepic_data *data = irq_desc_get_handler_data(desc);
|
||||
u32 event = in_be32(data->reg + CEPIER);
|
||||
|
||||
if (!event)
|
||||
return -1;
|
||||
|
||||
return irq_find_mapping(data->host, 32 - ffs(event));
|
||||
}
|
||||
|
||||
static void qepic_cascade(struct irq_desc *desc)
|
||||
{
|
||||
generic_handle_irq(qepic_get_irq(desc));
|
||||
struct irq_domain *domain = irq_desc_get_handler_data(desc);
|
||||
struct irq_chip_generic *gc = irq_get_domain_generic_chip(domain, 0);
|
||||
struct irq_chip *chip = irq_desc_get_chip(desc);
|
||||
unsigned long event, bit;
|
||||
|
||||
chained_irq_enter(chip, desc);
|
||||
|
||||
event = ioread32be(gc->reg_base + CEPIER);
|
||||
if (!event) {
|
||||
handle_bad_irq(desc);
|
||||
goto out;
|
||||
}
|
||||
|
||||
for_each_set_bit(bit, &event, 32)
|
||||
generic_handle_domain_irq(domain, 31 - bit);
|
||||
|
||||
out:
|
||||
chained_irq_exit(chip, desc);
|
||||
}
|
||||
|
||||
static int qepic_host_map(struct irq_domain *h, unsigned int virq, irq_hw_number_t hw)
|
||||
static int qepic_chip_init(struct irq_chip_generic *gc)
|
||||
{
|
||||
irq_set_chip_data(virq, h->host_data);
|
||||
irq_set_chip_and_handler(virq, &qepic, handle_fasteoi_irq);
|
||||
struct qepic_data *data = gc->domain->host_data;
|
||||
struct irq_chip_type *ct = gc->chip_types;
|
||||
|
||||
gc->reg_base = data->reg;
|
||||
|
||||
ct->chip.irq_mask = qepic_mask;
|
||||
ct->chip.irq_unmask = qepic_unmask;
|
||||
ct->chip.irq_eoi = qepic_end;
|
||||
ct->chip.irq_set_type = qepic_set_type;
|
||||
ct->chip.irq_calc_mask = qepic_calc_mask;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct irq_domain_ops qepic_host_ops = {
|
||||
.map = qepic_host_map,
|
||||
};
|
||||
|
||||
static void qepic_remove(void *res)
|
||||
static int qepic_domain_init(struct irq_domain *d)
|
||||
{
|
||||
struct qepic_data *data = res;
|
||||
struct qepic_data *data = d->host_data;
|
||||
|
||||
irq_set_chained_handler_and_data(data->irq, NULL, NULL);
|
||||
irq_domain_remove(data->host);
|
||||
irq_set_chained_handler_and_data(data->parent_irq, qepic_cascade, d);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void qepic_domain_exit(struct irq_domain *d)
|
||||
{
|
||||
struct qepic_data *data = d->host_data;
|
||||
|
||||
irq_set_chained_handler_and_data(data->parent_irq, NULL, NULL);
|
||||
}
|
||||
|
||||
static int qepic_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct irq_domain_chip_generic_info dgc_info = {
|
||||
.name = "QEPIC",
|
||||
.handler = handle_fasteoi_irq,
|
||||
.irqs_per_chip = 32,
|
||||
.num_ct = 1,
|
||||
.init = qepic_chip_init,
|
||||
};
|
||||
struct irq_domain_info d_info = {
|
||||
.fwnode = of_fwnode_handle(pdev->dev.of_node),
|
||||
.domain_flags = IRQ_DOMAIN_FLAG_DESTROY_GC,
|
||||
.size = 32,
|
||||
.hwirq_max = 32,
|
||||
.ops = &irq_generic_chip_ops,
|
||||
.dgc_info = &dgc_info,
|
||||
.init = qepic_domain_init,
|
||||
.exit = qepic_domain_exit,
|
||||
};
|
||||
struct device *dev = &pdev->dev;
|
||||
struct irq_domain *domain;
|
||||
struct qepic_data *data;
|
||||
|
||||
data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
|
||||
if (!data)
|
||||
return -ENOMEM;
|
||||
d_info.host_data = data;
|
||||
|
||||
data->reg = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(data->reg))
|
||||
return PTR_ERR(data->reg);
|
||||
|
||||
data->irq = platform_get_irq(pdev, 0);
|
||||
if (data->irq < 0)
|
||||
return data->irq;
|
||||
data->parent_irq = platform_get_irq(pdev, 0);
|
||||
if (data->parent_irq < 0)
|
||||
return data->parent_irq;
|
||||
|
||||
data->host = irq_domain_create_linear(dev_fwnode(dev), 32, &qepic_host_ops, data);
|
||||
if (!data->host)
|
||||
return -ENODEV;
|
||||
|
||||
irq_set_chained_handler_and_data(data->irq, qepic_cascade, data);
|
||||
|
||||
return devm_add_action_or_reset(dev, qepic_remove, data);
|
||||
domain = devm_irq_domain_instantiate(dev, &d_info);
|
||||
if (IS_ERR(domain))
|
||||
return PTR_ERR(domain);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id qepic_match[] = {
|
||||
|
||||
@@ -611,6 +611,7 @@ config USB_UHCI_ASPEED
|
||||
config USB_FHCI_HCD
|
||||
tristate "Freescale QE USB Host Controller support"
|
||||
depends on QE_GPIO && QUICC_ENGINE
|
||||
depends on PPC
|
||||
select FSL_GTM
|
||||
select QE_USB
|
||||
help
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/io.h>
|
||||
#include <soc/fsl/phy-fsl-lynx.h>
|
||||
|
||||
/*
|
||||
* Global Utility Registers.
|
||||
@@ -91,9 +92,15 @@ struct ccsr_guts {
|
||||
u32 iovselsr; /* 0x.00c0 - I/O voltage select status register
|
||||
Called 'elbcvselcr' on 86xx SOCs */
|
||||
u8 res0c4[0x100 - 0xc4];
|
||||
u32 rcwsr[16]; /* 0x.0100 - Reset Control Word Status registers
|
||||
There are 16 registers */
|
||||
u8 res140[0x224 - 0x140];
|
||||
/* 0x.0100 - read-only Reset Configuration Word Status registers in
|
||||
* CCSR, or write-only Reset Configuration Word Control registers in
|
||||
* DCSR. In both cases there are 32 registers.
|
||||
*/
|
||||
union {
|
||||
u32 rcwsr[32];
|
||||
u32 rcwcr[32];
|
||||
};
|
||||
u8 res180[0x224 - 0x180];
|
||||
u32 iodelay1; /* 0x.0224 - IO delay control register 1 */
|
||||
u32 iodelay2; /* 0x.0228 - IO delay control register 2 */
|
||||
u8 res22c[0x604 - 0x22c];
|
||||
@@ -131,6 +138,11 @@ struct ccsr_guts {
|
||||
u32 srds2cr1; /* 0x.0f44 - SerDes2 Control Register 0 */
|
||||
} __attribute__ ((packed));
|
||||
|
||||
int fsl_guts_lane_validate(int serdes_idx, int lane,
|
||||
enum lynx_lane_mode lane_mode);
|
||||
int fsl_guts_lane_set_mode(int serdes_idx, int lane,
|
||||
enum lynx_lane_mode lane_mode);
|
||||
|
||||
/* Alternate function signal multiplex control */
|
||||
#define MPC85xx_PMUXCR_QE(x) (0x8000 >> (x))
|
||||
|
||||
|
||||
@@ -25,14 +25,15 @@
|
||||
|
||||
/**
|
||||
* struct dpaa2_fd - Struct describing FDs
|
||||
* @words: for easier/faster copying the whole FD structure
|
||||
* @addr: address in the FD
|
||||
* @len: length in the FD
|
||||
* @bpid: buffer pool ID
|
||||
* @format_offset: format, offset, and short-length fields
|
||||
* @frc: frame context
|
||||
* @ctrl: control bits...including dd, sc, va, err, etc
|
||||
* @flc: flow context address
|
||||
* @words: for easier/faster copying the whole FD structure
|
||||
* @simple: struct for the FD fields
|
||||
* @simple.addr: address in the FD
|
||||
* @simple.len: length in the FD
|
||||
* @simple.bpid: buffer pool ID
|
||||
* @simple.format_offset: format, offset, and short-length fields
|
||||
* @simple.frc: frame context
|
||||
* @simple.ctrl: control bits...including dd, sc, va, err, etc
|
||||
* @simple.flc: flow context address
|
||||
*
|
||||
* This structure represents the basic Frame Descriptor used in the system.
|
||||
*/
|
||||
@@ -497,7 +498,7 @@ static inline void dpaa2_fl_set_addr(struct dpaa2_fl_entry *fle,
|
||||
* dpaa2_fl_get_frc() - Get the frame context in the FLE
|
||||
* @fle: the given frame list entry
|
||||
*
|
||||
* Return the frame context field in the frame lsit entry.
|
||||
* Return the frame context field in the frame list entry.
|
||||
*/
|
||||
static inline u32 dpaa2_fl_get_frc(const struct dpaa2_fl_entry *fle)
|
||||
{
|
||||
|
||||
@@ -22,7 +22,7 @@ struct device;
|
||||
* DOC: DPIO Service
|
||||
*
|
||||
* The DPIO service provides APIs for users to interact with the datapath
|
||||
* by enqueueing and dequeing frame descriptors.
|
||||
* by enqueueing and dequeueing frame descriptors.
|
||||
*
|
||||
* The following set of APIs can be used to enqueue and dequeue frames
|
||||
* as well as producing notification callbacks when data is available
|
||||
@@ -33,7 +33,7 @@ struct device;
|
||||
|
||||
/**
|
||||
* struct dpaa2_io_desc - The DPIO descriptor
|
||||
* @receives_notifications: Use notificaton mode. Non-zero if the DPIO
|
||||
* @receives_notifications: Use notification mode. Non-zero if the DPIO
|
||||
* has a channel.
|
||||
* @has_8prio: Set to non-zero for channel with 8 priority WQs. Ignored
|
||||
* unless receives_notification is TRUE.
|
||||
|
||||
Reference in New Issue
Block a user