* Re: [PATCH 2/2] ppc64: Add arch-specific pcie_get_speed_cap_mask
From: Thadeu Lima de Souza Cascardo @ 2013-03-14 18:52 UTC (permalink / raw)
To: lucaskt
Cc: linux-pci, linuxppc-dev, dri-devel, brking, Alex Deucher,
Bjorn Helgaas
In-Reply-To: <1363283147-8852-3-git-send-email-lucaskt@linux.vnet.ibm.com>
On Thu, Mar 14, 2013 at 02:45:47PM -0300, lucaskt@linux.vnet.ibm.com wrote:
> From: Lucas Kannebley Tavares <lucaskt@linux.vnet.ibm.com>
>
> Betters support for gen2 speed detections on PCI buses on ppc64
> architectures.
>
> Signed-off-by: Lucas Kannebley Tavares <lucaskt@linux.vnet.ibm.com>
> ---
> arch/powerpc/platforms/pseries/pci.c | 32 ++++++++++++++++++++++++++++++++
> 1 files changed, 32 insertions(+), 0 deletions(-)
>
> diff --git a/arch/powerpc/platforms/pseries/pci.c b/arch/powerpc/platforms/pseries/pci.c
> index 0b580f4..58469fe 100644
> --- a/arch/powerpc/platforms/pseries/pci.c
> +++ b/arch/powerpc/platforms/pseries/pci.c
> @@ -24,6 +24,7 @@
> #include <linux/kernel.h>
> #include <linux/pci.h>
> #include <linux/string.h>
> +#include <linux/device.h>
>
> #include <asm/eeh.h>
> #include <asm/pci-bridge.h>
> @@ -108,3 +109,34 @@ static void fixup_winbond_82c105(struct pci_dev* dev)
> }
> DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_WINBOND, PCI_DEVICE_ID_WINBOND_82C105,
> fixup_winbond_82c105);
> +
> +int pcibios_get_speed_cap_mask(struct pci_dev *dev, u32 *mask)
> +{
> + struct device_node *dn, *pdn;
> + const uint32_t *pcie_link_speed_stats = NULL;
> +
> + *mask = 0;
> + dn = pci_bus_to_OF_node(dev->bus);
> +
> + /* Find nearest ibm,pcie-link-speed-stats, walking up the device tree */
> + for (pdn = dn; pdn != NULL; pdn = pdn->parent) {
> + pcie_link_speed_stats = (const uint32_t *) of_get_property(pdn,
> + "ibm,pcie-link-speed-stats", NULL);
> + if (pcie_link_speed_stats != NULL)
> + break;
> + }
> +
> + if (pcie_link_speed_stats == NULL) {
> + dev_info(&dev->dev, "no ibm,pcie-link-speed-stats property\n");
> + return -EINVAL;
> + }
> +
> + switch (pcie_link_speed_stats[0]) {
> + case 0x02:
> + *mask |= PCIE_SPEED_50;
> + case 0x01:
> + *mask |= PCIE_SPEED_25;
> + }
I recall seeing this returns 0x00 as well. Maybe you should include both
0x00 and a default case and return EINVAL.
Regards.
Cascardo.
> +
> + return 0;
> +}
> --
> 1.7.4.4
>
^ permalink raw reply
* Re: [PATCH 0/5] mv643xx_eth: use mvmdio MDIO bus driver
From: Jason Cooper @ 2013-03-14 18:16 UTC (permalink / raw)
To: Florian Fainelli
Cc: Thomas Petazzoni, Andrew Lunn, Russell King, linux-doc,
devicetree-discuss, linux-kernel, Rob Herring, Greg Kroah-Hartman,
Paul Mackerras, Lennert Buytenhek, Rob Landley, netdev,
linuxppc-dev, davem, linux-arm-kernel
In-Reply-To: <5142124E.7050909@openwrt.org>
On Thu, Mar 14, 2013 at 07:09:18PM +0100, Florian Fainelli wrote:
> Hello Jason,
>=20
> Le 03/14/13 18:25, Jason Cooper a =E9crit :
> >Florian,
> >
> >Any word on version 2 of this series? I'd like to base the conversion
> >of kirkwood to DT based ethernet init on it.
>=20
> Just sent them out for review, thanks for reminder, they were
> sitting in my tree for a couple days already.
Great! I'll give this a spin.
thx,
Jason.
^ permalink raw reply
* [PATCH 1/4 v2] net: mvmdio: allow platform device style registration
From: Florian Fainelli @ 2013-03-14 18:11 UTC (permalink / raw)
To: davem
Cc: Thomas Petazzoni, Andrew Lunn, Russell King, Jason Cooper,
linux-doc, devicetree-discuss, linux-kernel, Rob Herring, netdev,
Paul Mackerras, linux-arm-kernel, Rob Landley, Greg Kroah-Hartman,
linuxppc-dev, Florian Fainelli, Lennert Buytenhek
In-Reply-To: <1363284515-9865-1-git-send-email-florian@openwrt.org>
This patch changes the mvmdio driver not to use device tree
helper functions such as of_mdiobus_register() and of_iomap() so we can
instantiate this driver using a classic platform_device approach. Use
the device manager helper to ioremap() the base register cookie so we
get automatic freeing upon error and removal. This change is harmless
for Device Tree platforms because they will get the driver be registered
the same way as it was before.
Signed-off-by: Florian Fainelli <florian@openwrt.org>
---
Changes since v1:
- use device managed helpers to fix an ioremap leak in remove function
- remove the use of Device Tree specific helpers to allow platform-style
registration
drivers/net/ethernet/marvell/mvmdio.c | 18 +++++++++++-------
1 file changed, 11 insertions(+), 7 deletions(-)
diff --git a/drivers/net/ethernet/marvell/mvmdio.c b/drivers/net/ethernet/marvell/mvmdio.c
index 77b7c80..8a182f1 100644
--- a/drivers/net/ethernet/marvell/mvmdio.c
+++ b/drivers/net/ethernet/marvell/mvmdio.c
@@ -24,10 +24,9 @@
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/phy.h>
-#include <linux/of_address.h>
-#include <linux/of_mdio.h>
#include <linux/platform_device.h>
#include <linux/delay.h>
+#include <linux/io.h>
#define MVMDIO_SMI_DATA_SHIFT 0
#define MVMDIO_SMI_PHY_ADDR_SHIFT 16
@@ -143,11 +142,17 @@ static int orion_mdio_reset(struct mii_bus *bus)
static int orion_mdio_probe(struct platform_device *pdev)
{
- struct device_node *np = pdev->dev.of_node;
+ struct resource *r;
struct mii_bus *bus;
struct orion_mdio_dev *dev;
int i, ret;
+ r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!r) {
+ dev_err(&pdev->dev, "No SMI register address given\n");
+ return -ENODEV;
+ }
+
bus = mdiobus_alloc_size(sizeof(struct orion_mdio_dev));
if (!bus) {
dev_err(&pdev->dev, "Cannot allocate MDIO bus\n");
@@ -172,9 +177,9 @@ static int orion_mdio_probe(struct platform_device *pdev)
bus->irq[i] = PHY_POLL;
dev = bus->priv;
- dev->smireg = of_iomap(pdev->dev.of_node, 0);
+ dev->smireg = devm_ioremap(&pdev->dev, r->start, resource_size(r));
if (!dev->smireg) {
- dev_err(&pdev->dev, "No SMI register address given in DT\n");
+ dev_err(&pdev->dev, "Unable to remap SMI register\n");
kfree(bus->irq);
mdiobus_free(bus);
return -ENODEV;
@@ -182,10 +187,9 @@ static int orion_mdio_probe(struct platform_device *pdev)
mutex_init(&dev->lock);
- ret = of_mdiobus_register(bus, np);
+ ret = mdiobus_register(bus);
if (ret < 0) {
dev_err(&pdev->dev, "Cannot register MDIO bus (%d)\n", ret);
- iounmap(dev->smireg);
kfree(bus->irq);
mdiobus_free(bus);
return ret;
--
1.7.10.4
^ permalink raw reply related
* Re: [PATCH 0/5] mv643xx_eth: use mvmdio MDIO bus driver
From: Florian Fainelli @ 2013-03-14 18:09 UTC (permalink / raw)
To: Jason Cooper
Cc: Thomas Petazzoni, Andrew Lunn, Russell King, linux-doc,
devicetree-discuss, linux-kernel, Rob Herring, Greg Kroah-Hartman,
Paul Mackerras, Lennert Buytenhek, Rob Landley, netdev,
linuxppc-dev, davem, linux-arm-kernel
In-Reply-To: <20130314172544.GT12700@titan.lakedaemon.net>
Hello Jason,
Le 03/14/13 18:25, Jason Cooper a écrit :
> Florian,
>
> Any word on version 2 of this series? I'd like to base the conversion
> of kirkwood to DT based ethernet init on it.
Just sent them out for review, thanks for reminder, they were sitting in
my tree for a couple days already.
--
Florian
^ permalink raw reply
* [PATCH 4/4 v2] mv643xx_eth: convert to use the Marvell Orion MDIO driver
From: Florian Fainelli @ 2013-03-14 18:08 UTC (permalink / raw)
To: davem
Cc: Thomas Petazzoni, Andrew Lunn, Russell King, Jason Cooper,
linux-doc, devicetree-discuss, linux-kernel, Rob Herring, netdev,
Paul Mackerras, linux-arm-kernel, Rob Landley, Greg Kroah-Hartman,
linuxppc-dev, Florian Fainelli, Lennert Buytenhek
In-Reply-To: <1363284515-9865-1-git-send-email-florian@openwrt.org>
This patch converts the Marvell MV643XX ethernet driver to use the
Marvell Orion MDIO driver. As a result, PowerPC and ARM platforms
registering the Marvell MV643XX ethernet driver are also updated to
register a Marvell Orion MDIO driver. This driver voluntarily overlaps
with the Marvell Ethernet shared registers because it will use a subset
of this shared register (shared_base + 0x4 - shared_base + 0x84). The
Ethernet driver is also updated to look up for a PHY device using the
Orion MDIO bus driver.
Signed-off-by: Florian Fainelli <florian@openwrt.org>
---
Changes since v1:
- removed one too many mdio bus registration for Orion5x/Kirkwood
arch/arm/plat-orion/common.c | 97 +++++++++++----
arch/powerpc/platforms/chrp/pegasos_eth.c | 20 +++
arch/powerpc/sysdev/mv64x60_dev.c | 14 ++-
drivers/net/ethernet/marvell/Kconfig | 1 +
drivers/net/ethernet/marvell/mv643xx_eth.c | 186 ++--------------------------
include/linux/mv643xx_eth.h | 1 -
6 files changed, 117 insertions(+), 202 deletions(-)
diff --git a/arch/arm/plat-orion/common.c b/arch/arm/plat-orion/common.c
index 2d4b641..dc4345e 100644
--- a/arch/arm/plat-orion/common.c
+++ b/arch/arm/plat-orion/common.c
@@ -238,6 +238,7 @@ static __init void ge_complete(
struct mv643xx_eth_shared_platform_data *orion_ge_shared_data,
struct resource *orion_ge_resource, unsigned long irq,
struct platform_device *orion_ge_shared,
+ struct platform_device *orion_ge_mvmdio,
struct mv643xx_eth_platform_data *eth_data,
struct platform_device *orion_ge)
{
@@ -247,6 +248,8 @@ static __init void ge_complete(
orion_ge->dev.platform_data = eth_data;
platform_device_register(orion_ge_shared);
+ if (orion_ge_mvmdio)
+ platform_device_register(orion_ge_mvmdio);
platform_device_register(orion_ge);
}
@@ -258,8 +261,6 @@ struct mv643xx_eth_shared_platform_data orion_ge00_shared_data;
static struct resource orion_ge00_shared_resources[] = {
{
.name = "ge00 base",
- }, {
- .name = "ge00 err irq",
},
};
@@ -271,6 +272,19 @@ static struct platform_device orion_ge00_shared = {
},
};
+static struct resource orion_ge00_mvmdio_resources[] = {
+ {
+ .name = "ge00 mvmdio base",
+ }, {
+ .name = "ge00 mvmdio irr irq",
+ },
+};
+
+static struct platform_device orion_ge00_mvmdio = {
+ .name = "orion-mdio",
+ .id = 0,
+};
+
static struct resource orion_ge00_resources[] = {
{
.name = "ge00 irq",
@@ -295,26 +309,25 @@ void __init orion_ge00_init(struct mv643xx_eth_platform_data *eth_data,
unsigned int tx_csum_limit)
{
fill_resources(&orion_ge00_shared, orion_ge00_shared_resources,
- mapbase + 0x2000, SZ_16K - 1, irq_err);
+ mapbase + 0x2000, SZ_16K - 1, NO_IRQ);
+ fill_resources(&orion_ge00_mvmdio, orion_ge00_mvmdio_resources,
+ mapbase + 0x2004, 0x84 - 1, irq_err);
orion_ge00_shared_data.tx_csum_limit = tx_csum_limit;
ge_complete(&orion_ge00_shared_data,
orion_ge00_resources, irq, &orion_ge00_shared,
+ &orion_ge00_mvmdio,
eth_data, &orion_ge00);
}
/*****************************************************************************
* GE01
****************************************************************************/
-struct mv643xx_eth_shared_platform_data orion_ge01_shared_data = {
- .shared_smi = &orion_ge00_shared,
-};
+struct mv643xx_eth_shared_platform_data orion_ge01_shared_data;
static struct resource orion_ge01_shared_resources[] = {
{
.name = "ge01 base",
- }, {
- .name = "ge01 err irq",
- },
+ }
};
static struct platform_device orion_ge01_shared = {
@@ -325,6 +338,19 @@ static struct platform_device orion_ge01_shared = {
},
};
+static struct resource orion_ge01_mvmdio_resources[] = {
+ {
+ .name = "ge01 mdio base",
+ }, {
+ .name = "ge01 mdio err irq",
+ },
+};
+
+static struct platform_device orion_ge01_mvmdio = {
+ .name = "orion-mdio",
+ .id = 1,
+};
+
static struct resource orion_ge01_resources[] = {
{
.name = "ge01 irq",
@@ -349,26 +375,25 @@ void __init orion_ge01_init(struct mv643xx_eth_platform_data *eth_data,
unsigned int tx_csum_limit)
{
fill_resources(&orion_ge01_shared, orion_ge01_shared_resources,
- mapbase + 0x2000, SZ_16K - 1, irq_err);
+ mapbase + 0x2000, SZ_16K - 1, NO_IRQ);
+ fill_resources(&orion_ge01_mvmdio, orion_ge01_mvmdio_resources,
+ mapbase + 0x2004, 0x84 - 1, irq_err);
orion_ge01_shared_data.tx_csum_limit = tx_csum_limit;
ge_complete(&orion_ge01_shared_data,
orion_ge01_resources, irq, &orion_ge01_shared,
+ NULL,
eth_data, &orion_ge01);
}
/*****************************************************************************
* GE10
****************************************************************************/
-struct mv643xx_eth_shared_platform_data orion_ge10_shared_data = {
- .shared_smi = &orion_ge00_shared,
-};
+struct mv643xx_eth_shared_platform_data orion_ge10_shared_data;
static struct resource orion_ge10_shared_resources[] = {
{
.name = "ge10 base",
- }, {
- .name = "ge10 err irq",
- },
+ }
};
static struct platform_device orion_ge10_shared = {
@@ -379,6 +404,19 @@ static struct platform_device orion_ge10_shared = {
},
};
+static struct resource orion_ge10_mvmdio_resources[] = {
+ {
+ .name = "ge10 mvmdio base",
+ }, {
+ .name = "ge10 mvmdio err irq",
+ },
+};
+
+static struct platform_device orion_ge10_mvmdio = {
+ .name = "orion-mdio",
+ .id = 1,
+};
+
static struct resource orion_ge10_resources[] = {
{
.name = "ge10 irq",
@@ -403,23 +441,22 @@ void __init orion_ge10_init(struct mv643xx_eth_platform_data *eth_data,
{
fill_resources(&orion_ge10_shared, orion_ge10_shared_resources,
mapbase + 0x2000, SZ_16K - 1, irq_err);
+ fill_resources(&orion_ge10_mvmdio, orion_ge10_mvmdio_resources,
+ mapbase + 0x2004, 0x84 - 1, irq_err);
ge_complete(&orion_ge10_shared_data,
orion_ge10_resources, irq, &orion_ge10_shared,
+ &orion_ge10_mvmdio,
eth_data, &orion_ge10);
}
/*****************************************************************************
* GE11
****************************************************************************/
-struct mv643xx_eth_shared_platform_data orion_ge11_shared_data = {
- .shared_smi = &orion_ge00_shared,
-};
+struct mv643xx_eth_shared_platform_data orion_ge11_shared_data;
static struct resource orion_ge11_shared_resources[] = {
{
.name = "ge11 base",
- }, {
- .name = "ge11 err irq",
},
};
@@ -431,6 +468,19 @@ static struct platform_device orion_ge11_shared = {
},
};
+static struct resource orion_ge11_mvmdio_resources[] = {
+ {
+ .name = "ge11 mvmdio base",
+ }, {
+ .name = "ge11 mvmdio err irq",
+ },
+};
+
+static struct platform_device orion_ge11_mvmdio = {
+ .name = "orion-mdio",
+ .id = 1,
+};
+
static struct resource orion_ge11_resources[] = {
{
.name = "ge11 irq",
@@ -454,9 +504,12 @@ void __init orion_ge11_init(struct mv643xx_eth_platform_data *eth_data,
unsigned long irq_err)
{
fill_resources(&orion_ge11_shared, orion_ge11_shared_resources,
- mapbase + 0x2000, SZ_16K - 1, irq_err);
+ mapbase + 0x2000, SZ_16K - 1, NO_IRQ);
+ fill_resources(&orion_ge11_mvmdio, orion_ge11_mvmdio_resources,
+ mapbase + 0x2004, 0x84 - 1, irq_err);
ge_complete(&orion_ge11_shared_data,
orion_ge11_resources, irq, &orion_ge11_shared,
+ NULL,
eth_data, &orion_ge11);
}
diff --git a/arch/powerpc/platforms/chrp/pegasos_eth.c b/arch/powerpc/platforms/chrp/pegasos_eth.c
index 039fc8e..a671508 100644
--- a/arch/powerpc/platforms/chrp/pegasos_eth.c
+++ b/arch/powerpc/platforms/chrp/pegasos_eth.c
@@ -47,6 +47,25 @@ static struct platform_device mv643xx_eth_shared_device = {
.resource = mv643xx_eth_shared_resources,
};
+/*
+ * The orion mdio driver only covers shared + 0x4 up to shared + 0x84 - 1
+ */
+static struct resource mv643xx_eth_mvmdio_resources[] = {
+ [0] = {
+ .name = "ethernet mdio base",
+ .start = 0xf1000000 + MV643XX_ETH_SHARED_REGS + 0x4,
+ .end = 0xf1000000 + MV643XX_ETH_SHARED_REGS + 0x83,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device mv643xx_eth_mvmdio_device = {
+ .name = "orion-mdio",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(mv643xx_eth_mvmdio_resources),
+ .resource = mv643xx_eth_shared_resources,
+};
+
static struct resource mv643xx_eth_port1_resources[] = {
[0] = {
.name = "eth port1 irq",
@@ -82,6 +101,7 @@ static struct platform_device eth_port1_device = {
static struct platform_device *mv643xx_eth_pd_devs[] __initdata = {
&mv643xx_eth_shared_device,
+ &mv643xx_eth_mvmdio_device,
ð_port1_device,
};
diff --git a/arch/powerpc/sysdev/mv64x60_dev.c b/arch/powerpc/sysdev/mv64x60_dev.c
index 0f6af41..630cea3 100644
--- a/arch/powerpc/sysdev/mv64x60_dev.c
+++ b/arch/powerpc/sysdev/mv64x60_dev.c
@@ -214,15 +214,25 @@ static struct platform_device * __init mv64x60_eth_register_shared_pdev(
struct device_node *np, int id)
{
struct platform_device *pdev;
- struct resource r[1];
+ struct resource r[2];
int err;
err = of_address_to_resource(np, 0, &r[0]);
if (err)
return ERR_PTR(err);
+ /* register an orion mdio bus driver */
+ r[1].start = r[0].start + 0x4;
+ r[1].end = r[0].start + 0x84 - 1;
+ r[1].flags = IORESOURCE_MEM;
+
+ pdev = platform_device_register_simple("orion-mdio", id, &r[1], 1);
+ if (!pdev)
+ return pdev;
+
pdev = platform_device_register_simple(MV643XX_ETH_SHARED_NAME, id,
- r, 1);
+ &r[0], 1);
+
return pdev;
}
diff --git a/drivers/net/ethernet/marvell/Kconfig b/drivers/net/ethernet/marvell/Kconfig
index edfba93..df06061 100644
--- a/drivers/net/ethernet/marvell/Kconfig
+++ b/drivers/net/ethernet/marvell/Kconfig
@@ -23,6 +23,7 @@ config MV643XX_ETH
depends on (MV64X60 || PPC32 || PLAT_ORION) && INET
select INET_LRO
select PHYLIB
+ select MVMDIO
---help---
This driver supports the gigabit ethernet MACs in the
Marvell Discovery PPC/MIPS chipset family (MV643XX) and
diff --git a/drivers/net/ethernet/marvell/mv643xx_eth.c b/drivers/net/ethernet/marvell/mv643xx_eth.c
index d1ecf4b..df04bee 100644
--- a/drivers/net/ethernet/marvell/mv643xx_eth.c
+++ b/drivers/net/ethernet/marvell/mv643xx_eth.c
@@ -69,14 +69,6 @@ static char mv643xx_eth_driver_version[] = "1.4";
* Registers shared between all ports.
*/
#define PHY_ADDR 0x0000
-#define SMI_REG 0x0004
-#define SMI_BUSY 0x10000000
-#define SMI_READ_VALID 0x08000000
-#define SMI_OPCODE_READ 0x04000000
-#define SMI_OPCODE_WRITE 0x00000000
-#define ERR_INT_CAUSE 0x0080
-#define ERR_INT_SMI_DONE 0x00000010
-#define ERR_INT_MASK 0x0084
#define WINDOW_BASE(w) (0x0200 + ((w) << 3))
#define WINDOW_SIZE(w) (0x0204 + ((w) << 3))
#define WINDOW_REMAP_HIGH(w) (0x0280 + ((w) << 2))
@@ -266,25 +258,6 @@ struct mv643xx_eth_shared_private {
void __iomem *base;
/*
- * Points at the right SMI instance to use.
- */
- struct mv643xx_eth_shared_private *smi;
-
- /*
- * Provides access to local SMI interface.
- */
- struct mii_bus *smi_bus;
-
- /*
- * If we have access to the error interrupt pin (which is
- * somewhat misnamed as it not only reflects internal errors
- * but also reflects SMI completion), use that to wait for
- * SMI access completion instead of polling the SMI busy bit.
- */
- int err_interrupt;
- wait_queue_head_t smi_busy_wait;
-
- /*
* Per-port MBUS window access register value.
*/
u32 win_protect;
@@ -1122,97 +1095,6 @@ out_write:
wrlp(mp, PORT_SERIAL_CONTROL, pscr);
}
-static irqreturn_t mv643xx_eth_err_irq(int irq, void *dev_id)
-{
- struct mv643xx_eth_shared_private *msp = dev_id;
-
- if (readl(msp->base + ERR_INT_CAUSE) & ERR_INT_SMI_DONE) {
- writel(~ERR_INT_SMI_DONE, msp->base + ERR_INT_CAUSE);
- wake_up(&msp->smi_busy_wait);
- return IRQ_HANDLED;
- }
-
- return IRQ_NONE;
-}
-
-static int smi_is_done(struct mv643xx_eth_shared_private *msp)
-{
- return !(readl(msp->base + SMI_REG) & SMI_BUSY);
-}
-
-static int smi_wait_ready(struct mv643xx_eth_shared_private *msp)
-{
- if (msp->err_interrupt == NO_IRQ) {
- int i;
-
- for (i = 0; !smi_is_done(msp); i++) {
- if (i == 10)
- return -ETIMEDOUT;
- msleep(10);
- }
-
- return 0;
- }
-
- if (!smi_is_done(msp)) {
- wait_event_timeout(msp->smi_busy_wait, smi_is_done(msp),
- msecs_to_jiffies(100));
- if (!smi_is_done(msp))
- return -ETIMEDOUT;
- }
-
- return 0;
-}
-
-static int smi_bus_read(struct mii_bus *bus, int addr, int reg)
-{
- struct mv643xx_eth_shared_private *msp = bus->priv;
- void __iomem *smi_reg = msp->base + SMI_REG;
- int ret;
-
- if (smi_wait_ready(msp)) {
- pr_warn("SMI bus busy timeout\n");
- return -ETIMEDOUT;
- }
-
- writel(SMI_OPCODE_READ | (reg << 21) | (addr << 16), smi_reg);
-
- if (smi_wait_ready(msp)) {
- pr_warn("SMI bus busy timeout\n");
- return -ETIMEDOUT;
- }
-
- ret = readl(smi_reg);
- if (!(ret & SMI_READ_VALID)) {
- pr_warn("SMI bus read not valid\n");
- return -ENODEV;
- }
-
- return ret & 0xffff;
-}
-
-static int smi_bus_write(struct mii_bus *bus, int addr, int reg, u16 val)
-{
- struct mv643xx_eth_shared_private *msp = bus->priv;
- void __iomem *smi_reg = msp->base + SMI_REG;
-
- if (smi_wait_ready(msp)) {
- pr_warn("SMI bus busy timeout\n");
- return -ETIMEDOUT;
- }
-
- writel(SMI_OPCODE_WRITE | (reg << 21) |
- (addr << 16) | (val & 0xffff), smi_reg);
-
- if (smi_wait_ready(msp)) {
- pr_warn("SMI bus busy timeout\n");
- return -ETIMEDOUT;
- }
-
- return 0;
-}
-
-
/* statistics ***************************************************************/
static struct net_device_stats *mv643xx_eth_get_stats(struct net_device *dev)
{
@@ -2688,47 +2570,6 @@ static int mv643xx_eth_shared_probe(struct platform_device *pdev)
goto out_free;
/*
- * Set up and register SMI bus.
- */
- if (pd == NULL || pd->shared_smi == NULL) {
- msp->smi_bus = mdiobus_alloc();
- if (msp->smi_bus == NULL)
- goto out_unmap;
-
- msp->smi_bus->priv = msp;
- msp->smi_bus->name = "mv643xx_eth smi";
- msp->smi_bus->read = smi_bus_read;
- msp->smi_bus->write = smi_bus_write,
- snprintf(msp->smi_bus->id, MII_BUS_ID_SIZE, "%s-%d",
- pdev->name, pdev->id);
- msp->smi_bus->parent = &pdev->dev;
- msp->smi_bus->phy_mask = 0xffffffff;
- if (mdiobus_register(msp->smi_bus) < 0)
- goto out_free_mii_bus;
- msp->smi = msp;
- } else {
- msp->smi = platform_get_drvdata(pd->shared_smi);
- }
-
- msp->err_interrupt = NO_IRQ;
- init_waitqueue_head(&msp->smi_busy_wait);
-
- /*
- * Check whether the error interrupt is hooked up.
- */
- res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
- if (res != NULL) {
- int err;
-
- err = request_irq(res->start, mv643xx_eth_err_irq,
- IRQF_SHARED, "mv643xx_eth", msp);
- if (!err) {
- writel(ERR_INT_SMI_DONE, msp->base + ERR_INT_MASK);
- msp->err_interrupt = res->start;
- }
- }
-
- /*
* (Re-)program MBUS remapping windows if we are asked to.
*/
dram = mv_mbus_dram_info();
@@ -2743,10 +2584,6 @@ static int mv643xx_eth_shared_probe(struct platform_device *pdev)
return 0;
-out_free_mii_bus:
- mdiobus_free(msp->smi_bus);
-out_unmap:
- iounmap(msp->base);
out_free:
kfree(msp);
out:
@@ -2756,14 +2593,7 @@ out:
static int mv643xx_eth_shared_remove(struct platform_device *pdev)
{
struct mv643xx_eth_shared_private *msp = platform_get_drvdata(pdev);
- struct mv643xx_eth_shared_platform_data *pd = pdev->dev.platform_data;
- if (pd == NULL || pd->shared_smi == NULL) {
- mdiobus_unregister(msp->smi_bus);
- mdiobus_free(msp->smi_bus);
- }
- if (msp->err_interrupt != NO_IRQ)
- free_irq(msp->err_interrupt, msp);
iounmap(msp->base);
kfree(msp);
@@ -2829,11 +2659,11 @@ static void set_params(struct mv643xx_eth_private *mp,
static struct phy_device *phy_scan(struct mv643xx_eth_private *mp,
int phy_addr)
{
- struct mii_bus *bus = mp->shared->smi->smi_bus;
struct phy_device *phydev;
int start;
int num;
int i;
+ char phy_id[MII_BUS_ID_SIZE + 3];
if (phy_addr == MV643XX_ETH_PHY_ADDR_DEFAULT) {
start = phy_addr_get(mp) & 0x1f;
@@ -2843,17 +2673,19 @@ static struct phy_device *phy_scan(struct mv643xx_eth_private *mp,
num = 1;
}
+ /* Attempt to connect to the PHY using orion-mdio */
phydev = NULL;
for (i = 0; i < num; i++) {
int addr = (start + i) & 0x1f;
- if (bus->phy_map[addr] == NULL)
- mdiobus_scan(bus, addr);
+ snprintf(phy_id, sizeof(phy_id), PHY_ID_FMT,
+ "orion-mdio-mii", addr);
- if (phydev == NULL) {
- phydev = bus->phy_map[addr];
- if (phydev != NULL)
- phy_addr_set(mp, addr);
+ phydev = phy_connect(mp->dev, phy_id, NULL,
+ PHY_INTERFACE_MODE_GMII);
+ if (!IS_ERR(phydev)) {
+ phy_addr_set(mp, addr);
+ break;
}
}
diff --git a/include/linux/mv643xx_eth.h b/include/linux/mv643xx_eth.h
index 49258e0..141d395 100644
--- a/include/linux/mv643xx_eth.h
+++ b/include/linux/mv643xx_eth.h
@@ -19,7 +19,6 @@
struct mv643xx_eth_shared_platform_data {
struct mbus_dram_target_info *dram;
- struct platform_device *shared_smi;
/*
* Max packet size for Tx IP/Layer 4 checksum, when set to 0, default
* limit of 9KiB will be used.
--
1.7.10.4
^ permalink raw reply related
* [PATCH 3/4 v2] net: mvmdio: enhance driver to support SMI error/done interrupts
From: Florian Fainelli @ 2013-03-14 18:08 UTC (permalink / raw)
To: davem
Cc: Thomas Petazzoni, Andrew Lunn, Russell King, Jason Cooper,
linux-doc, devicetree-discuss, linux-kernel, Rob Herring, netdev,
Paul Mackerras, linux-arm-kernel, Rob Landley, Greg Kroah-Hartman,
linuxppc-dev, Florian Fainelli, Lennert Buytenhek
In-Reply-To: <1363284515-9865-1-git-send-email-florian@openwrt.org>
This patch enhances the "mvmdio" to support a SMI error/done interrupt
line which can be used along with a wait queue instead of doing
busy-waiting on the registers. This is a feature which is available in
the mv643xx_eth SMI code and thus reduces again the gap between the two.
Signed-off-by: Florian Fainelli <florian@openwrt.org>
---
Chances since v1:
- always use orion_smi_is_done() helper
- make interrupt/non-interrupt code path entirely independant
.../devicetree/bindings/net/marvell-orion-mdio.txt | 3 +
drivers/net/ethernet/marvell/mvmdio.c | 83 +++++++++++++++++---
2 files changed, 74 insertions(+), 12 deletions(-)
diff --git a/Documentation/devicetree/bindings/net/marvell-orion-mdio.txt b/Documentation/devicetree/bindings/net/marvell-orion-mdio.txt
index 34e7aaf..052b5f2 100644
--- a/Documentation/devicetree/bindings/net/marvell-orion-mdio.txt
+++ b/Documentation/devicetree/bindings/net/marvell-orion-mdio.txt
@@ -9,6 +9,9 @@ Required properties:
- compatible: "marvell,orion-mdio"
- reg: address and length of the SMI register
+Optional properties:
+- interrupts: interrupt line number for the SMI error/done interrupt
+
The child nodes of the MDIO driver are the individual PHY devices
connected to this MDIO bus. They must have a "reg" property given the
PHY address on the MDIO bus.
diff --git a/drivers/net/ethernet/marvell/mvmdio.c b/drivers/net/ethernet/marvell/mvmdio.c
index 595deea..7ac83de 100644
--- a/drivers/net/ethernet/marvell/mvmdio.c
+++ b/drivers/net/ethernet/marvell/mvmdio.c
@@ -24,9 +24,12 @@
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/phy.h>
+#include <linux/interrupt.h>
#include <linux/platform_device.h>
#include <linux/delay.h>
#include <linux/io.h>
+#include <linux/sched.h>
+#include <linux/wait.h>
#define MVMDIO_SMI_DATA_SHIFT 0
#define MVMDIO_SMI_PHY_ADDR_SHIFT 16
@@ -35,33 +38,58 @@
#define MVMDIO_SMI_WRITE_OPERATION 0
#define MVMDIO_SMI_READ_VALID BIT(27)
#define MVMDIO_SMI_BUSY BIT(28)
+#define MVMDIO_ERR_INT_CAUSE 0x007C
+#define MVMDIO_ERR_INT_SMI_DONE 0x00000010
+#define MVMDIO_ERR_INT_MASK 0x0080
struct orion_mdio_dev {
struct mutex lock;
void __iomem *regs;
+ /*
+ * If we have access to the error interrupt pin (which is
+ * somewhat misnamed as it not only reflects internal errors
+ * but also reflects SMI completion), use that to wait for
+ * SMI access completion instead of polling the SMI busy bit.
+ */
+ int err_interrupt;
+ wait_queue_head_t smi_busy_wait;
};
+static int orion_mdio_smi_is_done(struct orion_mdio_dev *dev)
+{
+ return !(readl(dev->regs) & MVMDIO_SMI_BUSY);
+}
+
/* Wait for the SMI unit to be ready for another operation
*/
static int orion_mdio_wait_ready(struct mii_bus *bus)
{
struct orion_mdio_dev *dev = bus->priv;
int count;
- u32 val;
- count = 0;
- while (1) {
- val = readl(dev->regs);
- if (!(val & MVMDIO_SMI_BUSY))
- break;
+ if (dev->err_interrupt == NO_IRQ) {
+ count = 0;
+ while (1) {
+ if (orion_mdio_smi_is_done(dev))
+ break;
- if (count > 100) {
- dev_err(bus->parent, "Timeout: SMI busy for too long\n");
- return -ETIMEDOUT;
- }
+ if (count > 100) {
+ dev_err(bus->parent,
+ "Timeout: SMI busy for too long\n");
+ return -ETIMEDOUT;
+ }
- udelay(10);
- count++;
+ udelay(10);
+ count++;
+ }
+ } else {
+ if (!orion_mdio_smi_is_done(dev)) {
+ wait_event_timeout(dev->smi_busy_wait,
+ orion_mdio_smi_is_done(dev),
+ msecs_to_jiffies(100));
+ if (!orion_mdio_smi_is_done(dev))
+ return -ETIMEDOUT;
+ }
}
return 0;
@@ -140,6 +168,21 @@ static int orion_mdio_reset(struct mii_bus *bus)
return 0;
}
+static irqreturn_t orion_mdio_err_irq(int irq, void *dev_id)
+{
+ struct orion_mdio_dev *dev = dev_id;
+
+ if (readl(dev->regs + MVMDIO_ERR_INT_CAUSE) &
+ MVMDIO_ERR_INT_SMI_DONE) {
+ writel(~MVMDIO_ERR_INT_SMI_DONE,
+ dev->regs + MVMDIO_ERR_INT_CAUSE);
+ wake_up(&dev->smi_busy_wait);
+ return IRQ_HANDLED;
+ }
+
+ return IRQ_NONE;
+}
+
static int orion_mdio_probe(struct platform_device *pdev)
{
struct resource *r;
@@ -185,6 +228,19 @@ static int orion_mdio_probe(struct platform_device *pdev)
return -ENODEV;
}
+ init_waitqueue_head(&dev->smi_busy_wait);
+
+ dev->err_interrupt = platform_get_irq(pdev, 0);
+ if (dev->err_interrupt != -ENXIO) {
+ ret = devm_request_irq(&pdev->dev, dev->err_interrupt,
+ orion_mdio_err_irq,
+ IRQF_SHARED, pdev->name, dev);
+ if (!ret)
+ writel(MVMDIO_ERR_INT_SMI_DONE,
+ dev->regs + MVMDIO_ERR_INT_MASK);
+ } else
+ dev->err_interrupt = NO_IRQ;
+
mutex_init(&dev->lock);
ret = mdiobus_register(bus);
@@ -203,6 +259,9 @@ static int orion_mdio_probe(struct platform_device *pdev)
static int orion_mdio_remove(struct platform_device *pdev)
{
struct mii_bus *bus = platform_get_drvdata(pdev);
+ struct orion_mdio_dev *dev = bus->priv;
+
+ writel(0, dev->regs + MVMDIO_ERR_INT_MASK);
mdiobus_unregister(bus);
kfree(bus->irq);
mdiobus_free(bus);
--
1.7.10.4
^ permalink raw reply related
* [PATCH 2/4 v2] net: mvmdio: rename base register cookie from smireg to regs
From: Florian Fainelli @ 2013-03-14 18:08 UTC (permalink / raw)
To: davem
Cc: Thomas Petazzoni, Andrew Lunn, Russell King, Jason Cooper,
linux-doc, devicetree-discuss, linux-kernel, Rob Herring, netdev,
Paul Mackerras, linux-arm-kernel, Rob Landley, Greg Kroah-Hartman,
linuxppc-dev, Florian Fainelli, Lennert Buytenhek
In-Reply-To: <1363284515-9865-1-git-send-email-florian@openwrt.org>
This patch renames the base register cookie in the mvmdio drive from
"smireg" to "regs" since a subsequent patch is going to use an ioremap()
cookie whose size is larger than a single register of 4 bytes. No
functionnal code change introduced.
Acked-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
Signed-off-by: Florian Fainelli <florian@openwrt.org>
---
Changes since v1:
- added Thomas Acked-by tag
drivers/net/ethernet/marvell/mvmdio.c | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/drivers/net/ethernet/marvell/mvmdio.c b/drivers/net/ethernet/marvell/mvmdio.c
index 8a182f1..595deea 100644
--- a/drivers/net/ethernet/marvell/mvmdio.c
+++ b/drivers/net/ethernet/marvell/mvmdio.c
@@ -38,7 +38,7 @@
struct orion_mdio_dev {
struct mutex lock;
- void __iomem *smireg;
+ void __iomem *regs;
};
/* Wait for the SMI unit to be ready for another operation
@@ -51,7 +51,7 @@ static int orion_mdio_wait_ready(struct mii_bus *bus)
count = 0;
while (1) {
- val = readl(dev->smireg);
+ val = readl(dev->regs);
if (!(val & MVMDIO_SMI_BUSY))
break;
@@ -86,12 +86,12 @@ static int orion_mdio_read(struct mii_bus *bus, int mii_id,
writel(((mii_id << MVMDIO_SMI_PHY_ADDR_SHIFT) |
(regnum << MVMDIO_SMI_PHY_REG_SHIFT) |
MVMDIO_SMI_READ_OPERATION),
- dev->smireg);
+ dev->regs);
/* Wait for the value to become available */
count = 0;
while (1) {
- val = readl(dev->smireg);
+ val = readl(dev->regs);
if (val & MVMDIO_SMI_READ_VALID)
break;
@@ -128,7 +128,7 @@ static int orion_mdio_write(struct mii_bus *bus, int mii_id,
(regnum << MVMDIO_SMI_PHY_REG_SHIFT) |
MVMDIO_SMI_WRITE_OPERATION |
(value << MVMDIO_SMI_DATA_SHIFT)),
- dev->smireg);
+ dev->regs);
mutex_unlock(&dev->lock);
@@ -177,8 +177,8 @@ static int orion_mdio_probe(struct platform_device *pdev)
bus->irq[i] = PHY_POLL;
dev = bus->priv;
- dev->smireg = devm_ioremap(&pdev->dev, r->start, resource_size(r));
- if (!dev->smireg) {
+ dev->regs = devm_ioremap(&pdev->dev, r->start, resource_size(r));
+ if (!dev->regs) {
dev_err(&pdev->dev, "Unable to remap SMI register\n");
kfree(bus->irq);
mdiobus_free(bus);
--
1.7.10.4
^ permalink raw reply related
* [PATCH] mv643xx_eth: convert to use the Marvell Orion MDIO driver
From: Florian Fainelli @ 2013-03-14 18:08 UTC (permalink / raw)
To: davem
Cc: Thomas Petazzoni, Andrew Lunn, Russell King, Jason Cooper,
linux-doc, devicetree-discuss, linux-kernel, Rob Herring, netdev,
Paul Mackerras, linux-arm-kernel, Rob Landley, Greg Kroah-Hartman,
linuxppc-dev, Florian Fainelli, Lennert Buytenhek
In-Reply-To: <1363284515-9865-1-git-send-email-florian@openwrt.org>
This patch converts the Marvell MV643XX ethernet driver to use the
Marvell Orion MDIO driver. As a result, PowerPC and ARM platforms
registering the Marvell MV643XX ethernet driver are also updated to
register a Marvell Orion MDIO driver. This driver voluntarily overlaps
with the Marvell Ethernet shared registers because it will use a subset
of this shared register (shared_base + 0x4 - shared_base + 0x84). The
Ethernet driver is also updated to look up for a PHY device using the
Orion MDIO bus driver.
Signed-off-by: Florian Fainelli <florian@openwrt.org>
---
arch/arm/plat-orion/common.c | 97 +++++++++++----
arch/powerpc/platforms/chrp/pegasos_eth.c | 20 +++
arch/powerpc/sysdev/mv64x60_dev.c | 14 ++-
drivers/net/ethernet/marvell/Kconfig | 1 +
drivers/net/ethernet/marvell/mv643xx_eth.c | 186 ++--------------------------
include/linux/mv643xx_eth.h | 1 -
6 files changed, 117 insertions(+), 202 deletions(-)
diff --git a/arch/arm/plat-orion/common.c b/arch/arm/plat-orion/common.c
index 2d4b641..dc4345e 100644
--- a/arch/arm/plat-orion/common.c
+++ b/arch/arm/plat-orion/common.c
@@ -238,6 +238,7 @@ static __init void ge_complete(
struct mv643xx_eth_shared_platform_data *orion_ge_shared_data,
struct resource *orion_ge_resource, unsigned long irq,
struct platform_device *orion_ge_shared,
+ struct platform_device *orion_ge_mvmdio,
struct mv643xx_eth_platform_data *eth_data,
struct platform_device *orion_ge)
{
@@ -247,6 +248,8 @@ static __init void ge_complete(
orion_ge->dev.platform_data = eth_data;
platform_device_register(orion_ge_shared);
+ if (orion_ge_mvmdio)
+ platform_device_register(orion_ge_mvmdio);
platform_device_register(orion_ge);
}
@@ -258,8 +261,6 @@ struct mv643xx_eth_shared_platform_data orion_ge00_shared_data;
static struct resource orion_ge00_shared_resources[] = {
{
.name = "ge00 base",
- }, {
- .name = "ge00 err irq",
},
};
@@ -271,6 +272,19 @@ static struct platform_device orion_ge00_shared = {
},
};
+static struct resource orion_ge00_mvmdio_resources[] = {
+ {
+ .name = "ge00 mvmdio base",
+ }, {
+ .name = "ge00 mvmdio irr irq",
+ },
+};
+
+static struct platform_device orion_ge00_mvmdio = {
+ .name = "orion-mdio",
+ .id = 0,
+};
+
static struct resource orion_ge00_resources[] = {
{
.name = "ge00 irq",
@@ -295,26 +309,25 @@ void __init orion_ge00_init(struct mv643xx_eth_platform_data *eth_data,
unsigned int tx_csum_limit)
{
fill_resources(&orion_ge00_shared, orion_ge00_shared_resources,
- mapbase + 0x2000, SZ_16K - 1, irq_err);
+ mapbase + 0x2000, SZ_16K - 1, NO_IRQ);
+ fill_resources(&orion_ge00_mvmdio, orion_ge00_mvmdio_resources,
+ mapbase + 0x2004, 0x84 - 1, irq_err);
orion_ge00_shared_data.tx_csum_limit = tx_csum_limit;
ge_complete(&orion_ge00_shared_data,
orion_ge00_resources, irq, &orion_ge00_shared,
+ &orion_ge00_mvmdio,
eth_data, &orion_ge00);
}
/*****************************************************************************
* GE01
****************************************************************************/
-struct mv643xx_eth_shared_platform_data orion_ge01_shared_data = {
- .shared_smi = &orion_ge00_shared,
-};
+struct mv643xx_eth_shared_platform_data orion_ge01_shared_data;
static struct resource orion_ge01_shared_resources[] = {
{
.name = "ge01 base",
- }, {
- .name = "ge01 err irq",
- },
+ }
};
static struct platform_device orion_ge01_shared = {
@@ -325,6 +338,19 @@ static struct platform_device orion_ge01_shared = {
},
};
+static struct resource orion_ge01_mvmdio_resources[] = {
+ {
+ .name = "ge01 mdio base",
+ }, {
+ .name = "ge01 mdio err irq",
+ },
+};
+
+static struct platform_device orion_ge01_mvmdio = {
+ .name = "orion-mdio",
+ .id = 1,
+};
+
static struct resource orion_ge01_resources[] = {
{
.name = "ge01 irq",
@@ -349,26 +375,25 @@ void __init orion_ge01_init(struct mv643xx_eth_platform_data *eth_data,
unsigned int tx_csum_limit)
{
fill_resources(&orion_ge01_shared, orion_ge01_shared_resources,
- mapbase + 0x2000, SZ_16K - 1, irq_err);
+ mapbase + 0x2000, SZ_16K - 1, NO_IRQ);
+ fill_resources(&orion_ge01_mvmdio, orion_ge01_mvmdio_resources,
+ mapbase + 0x2004, 0x84 - 1, irq_err);
orion_ge01_shared_data.tx_csum_limit = tx_csum_limit;
ge_complete(&orion_ge01_shared_data,
orion_ge01_resources, irq, &orion_ge01_shared,
+ NULL,
eth_data, &orion_ge01);
}
/*****************************************************************************
* GE10
****************************************************************************/
-struct mv643xx_eth_shared_platform_data orion_ge10_shared_data = {
- .shared_smi = &orion_ge00_shared,
-};
+struct mv643xx_eth_shared_platform_data orion_ge10_shared_data;
static struct resource orion_ge10_shared_resources[] = {
{
.name = "ge10 base",
- }, {
- .name = "ge10 err irq",
- },
+ }
};
static struct platform_device orion_ge10_shared = {
@@ -379,6 +404,19 @@ static struct platform_device orion_ge10_shared = {
},
};
+static struct resource orion_ge10_mvmdio_resources[] = {
+ {
+ .name = "ge10 mvmdio base",
+ }, {
+ .name = "ge10 mvmdio err irq",
+ },
+};
+
+static struct platform_device orion_ge10_mvmdio = {
+ .name = "orion-mdio",
+ .id = 1,
+};
+
static struct resource orion_ge10_resources[] = {
{
.name = "ge10 irq",
@@ -403,23 +441,22 @@ void __init orion_ge10_init(struct mv643xx_eth_platform_data *eth_data,
{
fill_resources(&orion_ge10_shared, orion_ge10_shared_resources,
mapbase + 0x2000, SZ_16K - 1, irq_err);
+ fill_resources(&orion_ge10_mvmdio, orion_ge10_mvmdio_resources,
+ mapbase + 0x2004, 0x84 - 1, irq_err);
ge_complete(&orion_ge10_shared_data,
orion_ge10_resources, irq, &orion_ge10_shared,
+ &orion_ge10_mvmdio,
eth_data, &orion_ge10);
}
/*****************************************************************************
* GE11
****************************************************************************/
-struct mv643xx_eth_shared_platform_data orion_ge11_shared_data = {
- .shared_smi = &orion_ge00_shared,
-};
+struct mv643xx_eth_shared_platform_data orion_ge11_shared_data;
static struct resource orion_ge11_shared_resources[] = {
{
.name = "ge11 base",
- }, {
- .name = "ge11 err irq",
},
};
@@ -431,6 +468,19 @@ static struct platform_device orion_ge11_shared = {
},
};
+static struct resource orion_ge11_mvmdio_resources[] = {
+ {
+ .name = "ge11 mvmdio base",
+ }, {
+ .name = "ge11 mvmdio err irq",
+ },
+};
+
+static struct platform_device orion_ge11_mvmdio = {
+ .name = "orion-mdio",
+ .id = 1,
+};
+
static struct resource orion_ge11_resources[] = {
{
.name = "ge11 irq",
@@ -454,9 +504,12 @@ void __init orion_ge11_init(struct mv643xx_eth_platform_data *eth_data,
unsigned long irq_err)
{
fill_resources(&orion_ge11_shared, orion_ge11_shared_resources,
- mapbase + 0x2000, SZ_16K - 1, irq_err);
+ mapbase + 0x2000, SZ_16K - 1, NO_IRQ);
+ fill_resources(&orion_ge11_mvmdio, orion_ge11_mvmdio_resources,
+ mapbase + 0x2004, 0x84 - 1, irq_err);
ge_complete(&orion_ge11_shared_data,
orion_ge11_resources, irq, &orion_ge11_shared,
+ NULL,
eth_data, &orion_ge11);
}
diff --git a/arch/powerpc/platforms/chrp/pegasos_eth.c b/arch/powerpc/platforms/chrp/pegasos_eth.c
index 039fc8e..a671508 100644
--- a/arch/powerpc/platforms/chrp/pegasos_eth.c
+++ b/arch/powerpc/platforms/chrp/pegasos_eth.c
@@ -47,6 +47,25 @@ static struct platform_device mv643xx_eth_shared_device = {
.resource = mv643xx_eth_shared_resources,
};
+/*
+ * The orion mdio driver only covers shared + 0x4 up to shared + 0x84 - 1
+ */
+static struct resource mv643xx_eth_mvmdio_resources[] = {
+ [0] = {
+ .name = "ethernet mdio base",
+ .start = 0xf1000000 + MV643XX_ETH_SHARED_REGS + 0x4,
+ .end = 0xf1000000 + MV643XX_ETH_SHARED_REGS + 0x83,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device mv643xx_eth_mvmdio_device = {
+ .name = "orion-mdio",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(mv643xx_eth_mvmdio_resources),
+ .resource = mv643xx_eth_shared_resources,
+};
+
static struct resource mv643xx_eth_port1_resources[] = {
[0] = {
.name = "eth port1 irq",
@@ -82,6 +101,7 @@ static struct platform_device eth_port1_device = {
static struct platform_device *mv643xx_eth_pd_devs[] __initdata = {
&mv643xx_eth_shared_device,
+ &mv643xx_eth_mvmdio_device,
ð_port1_device,
};
diff --git a/arch/powerpc/sysdev/mv64x60_dev.c b/arch/powerpc/sysdev/mv64x60_dev.c
index 0f6af41..630cea3 100644
--- a/arch/powerpc/sysdev/mv64x60_dev.c
+++ b/arch/powerpc/sysdev/mv64x60_dev.c
@@ -214,15 +214,25 @@ static struct platform_device * __init mv64x60_eth_register_shared_pdev(
struct device_node *np, int id)
{
struct platform_device *pdev;
- struct resource r[1];
+ struct resource r[2];
int err;
err = of_address_to_resource(np, 0, &r[0]);
if (err)
return ERR_PTR(err);
+ /* register an orion mdio bus driver */
+ r[1].start = r[0].start + 0x4;
+ r[1].end = r[0].start + 0x84 - 1;
+ r[1].flags = IORESOURCE_MEM;
+
+ pdev = platform_device_register_simple("orion-mdio", id, &r[1], 1);
+ if (!pdev)
+ return pdev;
+
pdev = platform_device_register_simple(MV643XX_ETH_SHARED_NAME, id,
- r, 1);
+ &r[0], 1);
+
return pdev;
}
diff --git a/drivers/net/ethernet/marvell/Kconfig b/drivers/net/ethernet/marvell/Kconfig
index edfba93..df06061 100644
--- a/drivers/net/ethernet/marvell/Kconfig
+++ b/drivers/net/ethernet/marvell/Kconfig
@@ -23,6 +23,7 @@ config MV643XX_ETH
depends on (MV64X60 || PPC32 || PLAT_ORION) && INET
select INET_LRO
select PHYLIB
+ select MVMDIO
---help---
This driver supports the gigabit ethernet MACs in the
Marvell Discovery PPC/MIPS chipset family (MV643XX) and
diff --git a/drivers/net/ethernet/marvell/mv643xx_eth.c b/drivers/net/ethernet/marvell/mv643xx_eth.c
index d1ecf4b..df04bee 100644
--- a/drivers/net/ethernet/marvell/mv643xx_eth.c
+++ b/drivers/net/ethernet/marvell/mv643xx_eth.c
@@ -69,14 +69,6 @@ static char mv643xx_eth_driver_version[] = "1.4";
* Registers shared between all ports.
*/
#define PHY_ADDR 0x0000
-#define SMI_REG 0x0004
-#define SMI_BUSY 0x10000000
-#define SMI_READ_VALID 0x08000000
-#define SMI_OPCODE_READ 0x04000000
-#define SMI_OPCODE_WRITE 0x00000000
-#define ERR_INT_CAUSE 0x0080
-#define ERR_INT_SMI_DONE 0x00000010
-#define ERR_INT_MASK 0x0084
#define WINDOW_BASE(w) (0x0200 + ((w) << 3))
#define WINDOW_SIZE(w) (0x0204 + ((w) << 3))
#define WINDOW_REMAP_HIGH(w) (0x0280 + ((w) << 2))
@@ -266,25 +258,6 @@ struct mv643xx_eth_shared_private {
void __iomem *base;
/*
- * Points at the right SMI instance to use.
- */
- struct mv643xx_eth_shared_private *smi;
-
- /*
- * Provides access to local SMI interface.
- */
- struct mii_bus *smi_bus;
-
- /*
- * If we have access to the error interrupt pin (which is
- * somewhat misnamed as it not only reflects internal errors
- * but also reflects SMI completion), use that to wait for
- * SMI access completion instead of polling the SMI busy bit.
- */
- int err_interrupt;
- wait_queue_head_t smi_busy_wait;
-
- /*
* Per-port MBUS window access register value.
*/
u32 win_protect;
@@ -1122,97 +1095,6 @@ out_write:
wrlp(mp, PORT_SERIAL_CONTROL, pscr);
}
-static irqreturn_t mv643xx_eth_err_irq(int irq, void *dev_id)
-{
- struct mv643xx_eth_shared_private *msp = dev_id;
-
- if (readl(msp->base + ERR_INT_CAUSE) & ERR_INT_SMI_DONE) {
- writel(~ERR_INT_SMI_DONE, msp->base + ERR_INT_CAUSE);
- wake_up(&msp->smi_busy_wait);
- return IRQ_HANDLED;
- }
-
- return IRQ_NONE;
-}
-
-static int smi_is_done(struct mv643xx_eth_shared_private *msp)
-{
- return !(readl(msp->base + SMI_REG) & SMI_BUSY);
-}
-
-static int smi_wait_ready(struct mv643xx_eth_shared_private *msp)
-{
- if (msp->err_interrupt == NO_IRQ) {
- int i;
-
- for (i = 0; !smi_is_done(msp); i++) {
- if (i == 10)
- return -ETIMEDOUT;
- msleep(10);
- }
-
- return 0;
- }
-
- if (!smi_is_done(msp)) {
- wait_event_timeout(msp->smi_busy_wait, smi_is_done(msp),
- msecs_to_jiffies(100));
- if (!smi_is_done(msp))
- return -ETIMEDOUT;
- }
-
- return 0;
-}
-
-static int smi_bus_read(struct mii_bus *bus, int addr, int reg)
-{
- struct mv643xx_eth_shared_private *msp = bus->priv;
- void __iomem *smi_reg = msp->base + SMI_REG;
- int ret;
-
- if (smi_wait_ready(msp)) {
- pr_warn("SMI bus busy timeout\n");
- return -ETIMEDOUT;
- }
-
- writel(SMI_OPCODE_READ | (reg << 21) | (addr << 16), smi_reg);
-
- if (smi_wait_ready(msp)) {
- pr_warn("SMI bus busy timeout\n");
- return -ETIMEDOUT;
- }
-
- ret = readl(smi_reg);
- if (!(ret & SMI_READ_VALID)) {
- pr_warn("SMI bus read not valid\n");
- return -ENODEV;
- }
-
- return ret & 0xffff;
-}
-
-static int smi_bus_write(struct mii_bus *bus, int addr, int reg, u16 val)
-{
- struct mv643xx_eth_shared_private *msp = bus->priv;
- void __iomem *smi_reg = msp->base + SMI_REG;
-
- if (smi_wait_ready(msp)) {
- pr_warn("SMI bus busy timeout\n");
- return -ETIMEDOUT;
- }
-
- writel(SMI_OPCODE_WRITE | (reg << 21) |
- (addr << 16) | (val & 0xffff), smi_reg);
-
- if (smi_wait_ready(msp)) {
- pr_warn("SMI bus busy timeout\n");
- return -ETIMEDOUT;
- }
-
- return 0;
-}
-
-
/* statistics ***************************************************************/
static struct net_device_stats *mv643xx_eth_get_stats(struct net_device *dev)
{
@@ -2688,47 +2570,6 @@ static int mv643xx_eth_shared_probe(struct platform_device *pdev)
goto out_free;
/*
- * Set up and register SMI bus.
- */
- if (pd == NULL || pd->shared_smi == NULL) {
- msp->smi_bus = mdiobus_alloc();
- if (msp->smi_bus == NULL)
- goto out_unmap;
-
- msp->smi_bus->priv = msp;
- msp->smi_bus->name = "mv643xx_eth smi";
- msp->smi_bus->read = smi_bus_read;
- msp->smi_bus->write = smi_bus_write,
- snprintf(msp->smi_bus->id, MII_BUS_ID_SIZE, "%s-%d",
- pdev->name, pdev->id);
- msp->smi_bus->parent = &pdev->dev;
- msp->smi_bus->phy_mask = 0xffffffff;
- if (mdiobus_register(msp->smi_bus) < 0)
- goto out_free_mii_bus;
- msp->smi = msp;
- } else {
- msp->smi = platform_get_drvdata(pd->shared_smi);
- }
-
- msp->err_interrupt = NO_IRQ;
- init_waitqueue_head(&msp->smi_busy_wait);
-
- /*
- * Check whether the error interrupt is hooked up.
- */
- res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
- if (res != NULL) {
- int err;
-
- err = request_irq(res->start, mv643xx_eth_err_irq,
- IRQF_SHARED, "mv643xx_eth", msp);
- if (!err) {
- writel(ERR_INT_SMI_DONE, msp->base + ERR_INT_MASK);
- msp->err_interrupt = res->start;
- }
- }
-
- /*
* (Re-)program MBUS remapping windows if we are asked to.
*/
dram = mv_mbus_dram_info();
@@ -2743,10 +2584,6 @@ static int mv643xx_eth_shared_probe(struct platform_device *pdev)
return 0;
-out_free_mii_bus:
- mdiobus_free(msp->smi_bus);
-out_unmap:
- iounmap(msp->base);
out_free:
kfree(msp);
out:
@@ -2756,14 +2593,7 @@ out:
static int mv643xx_eth_shared_remove(struct platform_device *pdev)
{
struct mv643xx_eth_shared_private *msp = platform_get_drvdata(pdev);
- struct mv643xx_eth_shared_platform_data *pd = pdev->dev.platform_data;
- if (pd == NULL || pd->shared_smi == NULL) {
- mdiobus_unregister(msp->smi_bus);
- mdiobus_free(msp->smi_bus);
- }
- if (msp->err_interrupt != NO_IRQ)
- free_irq(msp->err_interrupt, msp);
iounmap(msp->base);
kfree(msp);
@@ -2829,11 +2659,11 @@ static void set_params(struct mv643xx_eth_private *mp,
static struct phy_device *phy_scan(struct mv643xx_eth_private *mp,
int phy_addr)
{
- struct mii_bus *bus = mp->shared->smi->smi_bus;
struct phy_device *phydev;
int start;
int num;
int i;
+ char phy_id[MII_BUS_ID_SIZE + 3];
if (phy_addr == MV643XX_ETH_PHY_ADDR_DEFAULT) {
start = phy_addr_get(mp) & 0x1f;
@@ -2843,17 +2673,19 @@ static struct phy_device *phy_scan(struct mv643xx_eth_private *mp,
num = 1;
}
+ /* Attempt to connect to the PHY using orion-mdio */
phydev = NULL;
for (i = 0; i < num; i++) {
int addr = (start + i) & 0x1f;
- if (bus->phy_map[addr] == NULL)
- mdiobus_scan(bus, addr);
+ snprintf(phy_id, sizeof(phy_id), PHY_ID_FMT,
+ "orion-mdio-mii", addr);
- if (phydev == NULL) {
- phydev = bus->phy_map[addr];
- if (phydev != NULL)
- phy_addr_set(mp, addr);
+ phydev = phy_connect(mp->dev, phy_id, NULL,
+ PHY_INTERFACE_MODE_GMII);
+ if (!IS_ERR(phydev)) {
+ phy_addr_set(mp, addr);
+ break;
}
}
diff --git a/include/linux/mv643xx_eth.h b/include/linux/mv643xx_eth.h
index 49258e0..141d395 100644
--- a/include/linux/mv643xx_eth.h
+++ b/include/linux/mv643xx_eth.h
@@ -19,7 +19,6 @@
struct mv643xx_eth_shared_platform_data {
struct mbus_dram_target_info *dram;
- struct platform_device *shared_smi;
/*
* Max packet size for Tx IP/Layer 4 checksum, when set to 0, default
* limit of 9KiB will be used.
--
1.7.10.4
^ permalink raw reply related
* [PATCH 0/4] mv643xx_eth: use mvmdio MDIO bus driver
From: Florian Fainelli @ 2013-03-14 18:08 UTC (permalink / raw)
To: davem
Cc: Thomas Petazzoni, Andrew Lunn, Russell King, Jason Cooper,
linux-doc, devicetree-discuss, linux-kernel, Rob Herring, netdev,
Paul Mackerras, linux-arm-kernel, Rob Landley, Greg Kroah-Hartman,
linuxppc-dev, Florian Fainelli, Lennert Buytenhek
In-Reply-To: <1359473048-26551-1-git-send-email-florian@openwrt.org>
Hi all,
This patch converts the mv643xx_eth driver to use the mvmdio MDIO bus driver
instead of rolling its own implementation. As a result, all users of this
mv643xx_eth driver are converted to register an "orion-mdio" platform_device.
The mvmdio driver is also updated to support an interrupt line which reports
SMI error/completion, and to allow traditionnal platform device registration
instead of just device tree.
David, I think it makes sense for you to merge all of this, since we do
not want the architecture files to be desynchronized from the mv643xx_eth to
avoid runtime breakage. The potential for merge conflicts should be very small.
Florian Fainelli (4):
net: mvmdio: allow platform device style registration
net: mvmdio: rename base register cookie from smireg to regs
net: mvmdio: enhance driver to support SMI error/done interrupts
mv643xx_eth: convert to use the Marvell Orion MDIO driver
.../devicetree/bindings/net/marvell-orion-mdio.txt | 3 +
arch/arm/plat-orion/common.c | 97 +++++++---
arch/powerpc/platforms/chrp/pegasos_eth.c | 20 +++
arch/powerpc/sysdev/mv64x60_dev.c | 14 +-
drivers/net/ethernet/marvell/Kconfig | 1 +
drivers/net/ethernet/marvell/mv643xx_eth.c | 186 +-------------------
drivers/net/ethernet/marvell/mvmdio.c | 111 +++++++++---
include/linux/mv643xx_eth.h | 1 -
8 files changed, 207 insertions(+), 226 deletions(-)
--
1.7.10.4
^ permalink raw reply
* Re: [PATCH] powerpc: add Book E support to 64-bit hibernation
From: Scott Wood @ 2013-03-14 16:52 UTC (permalink / raw)
To: Johannes Berg; +Cc: linuxppc-dev, Wang Dongsheng
In-Reply-To: <1363250273.4833.1.camel@jlt4.sipsolutions.net>
On 03/14/2013 03:37:53 AM, Johannes Berg wrote:
> On Thu, 2013-03-14 at 11:36 +0800, Wang Dongsheng wrote:
>=20
> > +#ifdef CONFIG_PPC_BOOK3S_64
> > /* can't use RESTORE_SPECIAL(MSR) */
> > ld r0, SL_MSR(r11)
> > mtmsrd r0, 0
>=20
> Unfortunately, I forgot the reason for this comment, and didn't put a
> better one (almost 6 years ago!!)
>=20
> > + RESTORE_SPECIAL(MSR)
>=20
> but maybe you also can't do this on BookE?
If it's because book3s needs mtmsrd instead of mtmsr, that doesn't =20
apply to booke.
-Scott=
^ permalink raw reply
* Re: [PATCH] powerpc: Fix -mcmodel=medium breakage in prom_init.c
From: Alexander Graf @ 2013-03-14 16:26 UTC (permalink / raw)
To: Anton Blanchard; +Cc: amodra, linuxppc-dev, aaro.koskinen
In-Reply-To: <20130312225151.2faeb395@kryten>
On 12.03.2013, at 12:51, Anton Blanchard wrote:
>=20
> Commit 5ac47f7a6efb (powerpc: Relocate prom_init.c on 64bit) made
> prom_init.c position independent by manually relocating its entries
> in the TOC.
>=20
> We get the address of the TOC entries with the __prom_init_toc_start
> linker symbol. If __prom_init_toc_start ends up as an entry in the
> TOC then we need to add an offset to get the current address. This is
> the case for older toolchains.
>=20
> On the other hand, if we have a newer toolchain that supports
> -mcmodel=3Dmedium then __prom_init_toc_start will be created by a
> relative offset from r2 (the TOC pointer). Since r2 has already been
> relocated, nothing more needs to be done. Adding an offset in this
> case is wrong and Aaro Koskinen and Alexander Graf have noticed =
noticed
> G5 and OpenBIOS breakage.
>=20
> Alan Modra suggested we just use r2 to get at the TOC which is simpler
> and works with both old and new toolchains.
>=20
> Reported-by: Alexander Graf <agraf@suse.de>
> Signed-off-by: Anton Blanchard <anton@samba.org>
This fixes my G5 again as well.
Acked-by: Alexander Graf <agraf@suse.de>
Please make sure this patch goes into 3.9.
Alex
> ---
>=20
> Thanks Aaro for reporting this, and Alexander for an initial
> fix. This tested ok for me with both a new and an old toolchain,
> but would appreciate if you could double check it fixes your issues
> too.
>=20
> diff --git a/arch/powerpc/kernel/prom_init.c =
b/arch/powerpc/kernel/prom_init.c
> index 7f7fb7f..13f8d16 100644
> --- a/arch/powerpc/kernel/prom_init.c
> +++ b/arch/powerpc/kernel/prom_init.c
> @@ -2832,11 +2832,13 @@ static void unreloc_toc(void)
> {
> }
> #else
> -static void __reloc_toc(void *tocstart, unsigned long offset,
> - unsigned long nr_entries)
> +static void __reloc_toc(unsigned long offset, unsigned long =
nr_entries)
> {
> unsigned long i;
> - unsigned long *toc_entry =3D (unsigned long *)tocstart;
> + unsigned long *toc_entry;
> +
> + /* Get the start of the TOC by using r2 directly. */
> + asm volatile("addi %0,2,-0x8000" : "=3Db" (toc_entry));
>=20
> for (i =3D 0; i < nr_entries; i++) {
> *toc_entry =3D *toc_entry + offset;
> @@ -2850,8 +2852,7 @@ static void reloc_toc(void)
> unsigned long nr_entries =3D
> (__prom_init_toc_end - __prom_init_toc_start) / =
sizeof(long);
>=20
> - /* Need to add offset to get at __prom_init_toc_start */
> - __reloc_toc(__prom_init_toc_start + offset, offset, nr_entries);
> + __reloc_toc(offset, nr_entries);
>=20
> mb();
> }
> @@ -2864,8 +2865,7 @@ static void unreloc_toc(void)
>=20
> mb();
>=20
> - /* __prom_init_toc_start has been relocated, no need to add =
offset */
> - __reloc_toc(__prom_init_toc_start, -offset, nr_entries);
> + __reloc_toc(-offset, nr_entries);
> }
> #endif
> #endif
^ permalink raw reply
* [PATCH] powerpc: remove "config 8260_PCI9"
From: Paul Bolle @ 2013-03-14 15:14 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Paul Mackerras; +Cc: linuxppc-dev, linux-kernel
The last user of Kconfig symbol 8260_PCI9 got removed in release v3.2.
Remove this symbol too.
Signed-off-by: Paul Bolle <pebolle@tiscali.nl>
---
0) Untested.
1) This probably is a second order effect of my commit
6805ab6daa2b589fe3242d05ddc47a9dbb0c4eb1 ("powerpc: drop unused Kconfig
symbols"). Not sure how I missed that.
arch/powerpc/Kconfig | 5 -----
1 file changed, 5 deletions(-)
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index b89d7eb..8014a44 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -774,11 +774,6 @@ config PCI_8260
select PPC_INDIRECT_PCI
default y
-config 8260_PCI9
- bool "Enable workaround for MPC826x erratum PCI 9"
- depends on PCI_8260 && !8272
- default y
-
source "drivers/pci/pcie/Kconfig"
source "drivers/pci/Kconfig"
--
1.7.11.7
^ permalink raw reply related
* [PATCH] powerpc: Replaced tlbilx with tlbwe in the initialization code
From: Diana Craciun @ 2013-03-14 14:55 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Diana Craciun
From: Diana Craciun <Diana.Craciun@freescale.com>
On Freescale e6500 cores EPCR[DGTMI] controls whether guest supervisor
state can execute TLB management instructions. If EPCR[DGTMI]=0
tlbwe and tlbilx are allowed to execute normally in the guest state.
A hypervisor may choose to virtualize TLB1 and for this purpose it
may use IPROT to protect the entries for being invalidated by the
guest. However, because tlbwe and tlbilx execution in the guest state
are sharing the same bit, it is not possible to have a scenario where
tlbwe is allowed to be executed in guest state and tlbilx traps. When
guest TLB management instructions are allowed to be executed in guest
state the guest cannot use tlbilx to invalidate TLB1 guest entries.
Linux is using tlbilx in the boot code to invalidate the temporary
entries it creates when initializing the MMU. The patch is replacing
the usage of tlbilx in initialization code with tlbwe with VALID bit
cleared.
Linux is also using tlbilx in other contexts (like huge pages or
indirect entries) but removing the tlbilx from the initialization code
offers the possibility to have scenarios under hypervisor which are
not using huge pages or indirect entries.
Signed-off-by: Diana Craciun <Diana.Craciun@freescale.com>
---
arch/powerpc/kernel/exceptions-64e.S | 10 ++--------
1 file changed, 2 insertions(+), 8 deletions(-)
diff --git a/arch/powerpc/kernel/exceptions-64e.S b/arch/powerpc/kernel/exceptions-64e.S
index 42a756e..a979e9d 100644
--- a/arch/powerpc/kernel/exceptions-64e.S
+++ b/arch/powerpc/kernel/exceptions-64e.S
@@ -1053,12 +1053,9 @@ skpinv: addi r6,r6,1 /* Increment */
mtspr SPRN_MAS0,r3
tlbre
mfspr r6,SPRN_MAS1
- rlwinm r6,r6,0,2,0 /* clear IPROT */
+ rlwinm r6,r6,0,2,31 /* clear IPROT and VALID */
mtspr SPRN_MAS1,r6
tlbwe
-
- /* Invalidate TLB1 */
- PPC_TLBILX_ALL(0,R0)
sync
isync
@@ -1112,12 +1109,9 @@ skpinv: addi r6,r6,1 /* Increment */
mtspr SPRN_MAS0,r4
tlbre
mfspr r5,SPRN_MAS1
- rlwinm r5,r5,0,2,0 /* clear IPROT */
+ rlwinm r5,r5,0,2,31 /* clear IPROT and VALID */
mtspr SPRN_MAS1,r5
tlbwe
-
- /* Invalidate TLB1 */
- PPC_TLBILX_ALL(0,R0)
sync
isync
--
1.7.11.7
^ permalink raw reply related
* Re: [PATCH] powerpc/40x: remove unused "config 405GPR"
From: Josh Boyer @ 2013-03-14 14:17 UTC (permalink / raw)
To: Paul Bolle; +Cc: Paul Mackerras, linuxppc-dev, linux-kernel
In-Reply-To: <1363268870.1335.75.camel@x61.thuisdomein>
On Thu, Mar 14, 2013 at 9:47 AM, Paul Bolle <pebolle@tiscali.nl> wrote:
> The last user of Kconfig symbol 405GPR got removed in release v3.2.
> Remove this symbol too.
>
> Signed-off-by: Paul Bolle <pebolle@tiscali.nl>
Acked-by: Josh Boyer <jwboyer@gmail.com>
> ---
> arch/powerpc/platforms/40x/Kconfig | 3 ---
> 1 file changed, 3 deletions(-)
>
> diff --git a/arch/powerpc/platforms/40x/Kconfig b/arch/powerpc/platforms/40x/Kconfig
> index a392d12..7b7a77c 100644
> --- a/arch/powerpc/platforms/40x/Kconfig
> +++ b/arch/powerpc/platforms/40x/Kconfig
> @@ -119,9 +119,6 @@ config 405EZ
> select IBM_EMAC_MAL_CLR_ICINTSTAT
> select IBM_EMAC_MAL_COMMON_ERR
>
> -config 405GPR
> - bool
> -
> config XILINX_VIRTEX
> bool
> select DEFAULT_UIMAGE
> --
> 1.7.11.7
>
>
>
^ permalink raw reply
* [PATCH] powerpc/40x: remove unused "config 405GPR"
From: Paul Bolle @ 2013-03-14 13:47 UTC (permalink / raw)
To: Josh Boyer, Matt Porter, Benjamin Herrenschmidt, Paul Mackerras
Cc: linuxppc-dev, linux-kernel
The last user of Kconfig symbol 405GPR got removed in release v3.2.
Remove this symbol too.
Signed-off-by: Paul Bolle <pebolle@tiscali.nl>
---
arch/powerpc/platforms/40x/Kconfig | 3 ---
1 file changed, 3 deletions(-)
diff --git a/arch/powerpc/platforms/40x/Kconfig b/arch/powerpc/platforms/40x/Kconfig
index a392d12..7b7a77c 100644
--- a/arch/powerpc/platforms/40x/Kconfig
+++ b/arch/powerpc/platforms/40x/Kconfig
@@ -119,9 +119,6 @@ config 405EZ
select IBM_EMAC_MAL_CLR_ICINTSTAT
select IBM_EMAC_MAL_COMMON_ERR
-config 405GPR
- bool
-
config XILINX_VIRTEX
bool
select DEFAULT_UIMAGE
--
1.7.11.7
^ permalink raw reply related
* Re: [PATCH 4/11] Add platform_has_feature()
From: Michael Ellerman @ 2013-03-14 13:42 UTC (permalink / raw)
To: Nathan Fontenot; +Cc: linuxppc-dev
In-Reply-To: <513AB457.9000409@linux.vnet.ibm.com>
On Fri, Mar 08, 2013 at 10:02:31PM -0600, Nathan Fontenot wrote:
> The firmware_has_feature() function makes it easy to check for supported
> features of the hardware. There is not corresponding function to check for
> features supported by the client architecture.
Actually it doesn't tell you about features of the hardware, it tells
you about features of the firmware, or the platform ..
So I think you should really just be adding a new firmware feature flag,
and adding whatever glue code is required to set it based on what you
find in the device tree.
Also notice where you end up using it:
- if (firmware_has_feature(FW_FEATURE_OPAL))
+ if (firmware_has_feature(FW_FEATURE_OPAL) ||
+ platform_has_feature(OV5_TYPE1_AFFINITY)) {
+ dbg("Using form 1 affinity\n");
form1_affinity = 1;
Could be:
+ if (firmware_has_feature(FW_FEATURE_FORM1_AFFINITY) ||
cheers
^ permalink raw reply
* [GIT PULL 0/8] perf/urgent fixes
From: Arnaldo Carvalho de Melo @ 2013-03-14 12:23 UTC (permalink / raw)
To: Ingo Molnar
Cc: Feng Tang, Srikar Dronamraju, Jack Mitchell, Stephane Eranian,
Oleg Nesterov, linuxppc-dev, Paul Mackerras, Jiri Olsa,
Namhyung Kim, Andi Kleen, Irina Tirdea, Robert Richter,
Vinson Lee, Ingo Molnar, Marcin Slusarz, Arnaldo Carvalho de Melo,
Frederic Weisbecker, Ingo Molnar, Sukadev Bhattiprolu,
Peter Zijlstra, Corey Ashford, Anton Blanchard, Namhyung Kim,
Arnaldo Carvalho de Melo, linux-kernel, Pekka Enberg, David Ahern
From: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
Hi Ingo,
Please consider pulling,
- Arnaldo
The following changes since commit cb16b91a449afd01b85ec4e59f30449d11c4acd7:
s390: Fix a header dependencies related build error (2013-03-11 10:43:35 +0100)
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux tags/perf-urgent-for-mingo
for you to fetch changes up to d1398ccfec56e54010476efd6a316427d29045a6:
perf tools: Fix LIBNUMA build with glibc 2.12 and older. (2013-03-14 08:06:21 -0300)
----------------------------------------------------------------
perf/urgent fixes:
. perf probe: Fix segfault due to testing the wrong pointer for NULL,
from Ananth N Mavinakayanahalli.
. libtraceevent: Remove hard coded include to /usr/local/include in
Makefile, which causes cross builds to include host header files,
fix from Jack Mitchell.
. perf record: Use the right target interface for synthesizing
threads when --cpu/-C option is used, fix from Jiri Olsa.
. Check if -DFORTIFY_SOURCE=2 is allowed, as gcc 4.7.2 defines
it and then the build is broken when it is redefined in perf,
fix from Marcin Slusarz.
. Fix build with NO_NEWT=1, that can happen explicitely or when
the newt-devel package is not installed, from Michael Ellerman.
. perf/POWER7: Create a sysfs format entry for Power7 events, missing
patch from a patchseries already merged, from Sukadev Bhattiprolu.
. Fix LIBNUMA build with glibc 2.12 and older, from Vinson Lee.
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
----------------------------------------------------------------
Ananth N Mavinakayanahalli (1):
perf probe: Fix segfault
Jack Mitchell (1):
libtraceevent: Remove hard coded include to /usr/local/include in Makefile
Jiri Olsa (1):
perf record: Fix -C option
Marcin Slusarz (1):
perf tools: check if -DFORTIFY_SOURCE=2 is allowed
Michael Ellerman (2):
perf annotate: Fix build with NO_NEWT=1
perf report: Fix build with NO_NEWT=1
Sukadev Bhattiprolu (1):
perf/POWER7: Create a sysfs format entry for Power7 events
Vinson Lee (1):
perf tools: Fix LIBNUMA build with glibc 2.12 and older.
arch/powerpc/perf/power7-pmu.c | 13 +++++++++++++
tools/lib/traceevent/Makefile | 2 +-
tools/perf/Makefile | 8 +++++++-
tools/perf/bench/bench.h | 24 ++++++++++++++++++++++++
tools/perf/builtin-record.c | 6 ++++--
tools/perf/util/hist.h | 5 +++--
tools/perf/util/strlist.c | 2 +-
7 files changed, 53 insertions(+), 7 deletions(-)
^ permalink raw reply
* [PATCH 7/8] perf/POWER7: Create a sysfs format entry for Power7 events
From: Arnaldo Carvalho de Melo @ 2013-03-14 12:23 UTC (permalink / raw)
To: Ingo Molnar
Cc: Arnaldo Carvalho de Melo, Andi Kleen, Peter Zijlstra,
Robert Richter, Anton Blanchard, linux-kernel, Stephane Eranian,
linuxppc-dev, Ingo Molnar, Paul Mackerras, Sukadev Bhattiprolu,
Jiri Olsa
In-Reply-To: <1363263795-31485-1-git-send-email-acme@infradead.org>
From: Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com>
Create a sysfs entry, '/sys/bus/event_source/devices/cpu/format/event'
which describes the format of the POWER7 PMU events.
This code is based on corresponding code in x86.
Changelog[v4]: [Michael Ellerman, Paul Mckerras] The event format is different
for other POWER cpus. So move the code to POWER7-specific,
power7-pmu.c Also, the POWER7 format uses bits 0-19 not 0-20.
Changelog[v2]: [Jiri Osla] Use PMU_FORMAT_ATTR rather than duplicating code.
Signed-off-by: Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com>
Acked-by: Paul Mackerras <paulus@samba.org>
Tested-by: Michael Ellerman <michael@ellerman.id.au>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: Anton Blanchard <anton@au1.ibm.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Michael Ellerman <michael@ellerman.id.au>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Robert Richter <robert.richter@amd.com>
Cc: Stephane Eranian <eranian@google.com>
Cc: benh@kernel.crashing.org
Cc: linuxppc-dev@ozlabs.org
Link: http://lkml.kernel.org/r/20130306054826.GA14627@us.ibm.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
arch/powerpc/perf/power7-pmu.c | 13 +++++++++++++
1 files changed, 13 insertions(+), 0 deletions(-)
diff --git a/arch/powerpc/perf/power7-pmu.c b/arch/powerpc/perf/power7-pmu.c
index b554879..3c475d6 100644
--- a/arch/powerpc/perf/power7-pmu.c
+++ b/arch/powerpc/perf/power7-pmu.c
@@ -420,7 +420,20 @@ static struct attribute_group power7_pmu_events_group = {
.attrs = power7_events_attr,
};
+PMU_FORMAT_ATTR(event, "config:0-19");
+
+static struct attribute *power7_pmu_format_attr[] = {
+ &format_attr_event.attr,
+ NULL,
+};
+
+struct attribute_group power7_pmu_format_group = {
+ .name = "format",
+ .attrs = power7_pmu_format_attr,
+};
+
static const struct attribute_group *power7_pmu_attr_groups[] = {
+ &power7_pmu_format_group,
&power7_pmu_events_group,
NULL,
};
--
1.7.1
^ permalink raw reply related
* [PATCH V2] powerpc/85xx: workaround for chips with MSI hardware errata
From: Jia Hongtao @ 2013-03-14 10:35 UTC (permalink / raw)
To: linuxppc-dev, galak; +Cc: B07421, b38951
The MPIC version 2.0 has a MSI errata (errata PIC1 of mpc8544), It causes
that neither MSI nor MSI-X can work fine. This is a workaround to allow
MSI-X to function properly.
Signed-off-by: Liu Shuo <soniccat.liu@gmail.com>
Signed-off-by: Li Yang <leoli@freescale.com>
Signed-off-by: Jia Hongtao <hongtao.jia@freescale.com>
---
Changes for V2:
- Address almost all the comments from Michael Ellerman for V1.
Here is the link:
http://patchwork.ozlabs.org/patch/226833/
arch/powerpc/sysdev/fsl_msi.c | 65 +++++++++++++++++++++++++++++++++++++++++--
arch/powerpc/sysdev/fsl_msi.h | 2 ++
2 files changed, 64 insertions(+), 3 deletions(-)
diff --git a/arch/powerpc/sysdev/fsl_msi.c b/arch/powerpc/sysdev/fsl_msi.c
index 178c994..54cb83e 100644
--- a/arch/powerpc/sysdev/fsl_msi.c
+++ b/arch/powerpc/sysdev/fsl_msi.c
@@ -98,8 +98,18 @@ static int fsl_msi_init_allocator(struct fsl_msi *msi_data)
static int fsl_msi_check_device(struct pci_dev *pdev, int nvec, int type)
{
- if (type == PCI_CAP_ID_MSIX)
- pr_debug("fslmsi: MSI-X untested, trying anyway.\n");
+ struct fsl_msi *msi;
+
+ if (type == PCI_CAP_ID_MSI) {
+ /*
+ * MPIC version 2.0 has erratum PIC1. For now MSI
+ * could not work. So check to prevent MSI from
+ * being used on the board with this erratum.
+ */
+ list_for_each_entry(msi, &msi_head, list)
+ if (msi->feature & MSI_HW_ERRATA_ENDIAN)
+ return -EINVAL;
+ }
return 0;
}
@@ -142,7 +152,17 @@ static void fsl_compose_msi_msg(struct pci_dev *pdev, int hwirq,
msg->address_lo = lower_32_bits(address);
msg->address_hi = upper_32_bits(address);
- msg->data = hwirq;
+ /*
+ * MPIC version 2.0 has erratum PIC1. It causes
+ * that neither MSI nor MSI-X can work fine.
+ * This is a workaround to allow MSI-X to function
+ * properly. It only works for MSI-X, we prevent
+ * MSI on buggy chips in fsl_msi_check_device().
+ */
+ if (msi_data->feature & MSI_HW_ERRATA_ENDIAN)
+ msg->data = __swab32(hwirq);
+ else
+ msg->data = hwirq;
pr_debug("%s: allocated srs: %d, ibs: %d\n",
__func__, hwirq / IRQS_PER_MSI_REG, hwirq % IRQS_PER_MSI_REG);
@@ -361,6 +381,35 @@ static int fsl_msi_setup_hwirq(struct fsl_msi *msi, struct platform_device *dev,
return 0;
}
+/* MPIC version 2.0 has erratum PIC1 */
+static int mpic_has_errata(struct platform_device *dev)
+{
+ struct device_node *mpic_node;
+
+ mpic_node = of_irq_find_parent(dev->dev.of_node);
+ if (mpic_node) {
+ u32 *reg_base, brr1 = 0;
+ /* Get the PIC reg base */
+ reg_base = of_iomap(mpic_node, 0);
+ of_node_put(mpic_node);
+ if (!reg_base) {
+ dev_err(&dev->dev, "ioremap problem failed.\n");
+ return -EIO;
+ }
+
+ /* Get the mpic version from block revision register 1 */
+ brr1 = in_be32(reg_base + MPIC_FSL_BRR1);
+ iounmap(reg_base);
+ if ((brr1 & MPIC_FSL_BRR1_VER) == 0x0200)
+ return 1;
+ } else {
+ dev_err(&dev->dev, "MSI can't find his parent mpic node.\n");
+ return -ENODEV;
+ }
+
+ return 0;
+}
+
static const struct of_device_id fsl_of_msi_ids[];
static int fsl_of_msi_probe(struct platform_device *dev)
{
@@ -423,6 +472,16 @@ static int fsl_of_msi_probe(struct platform_device *dev)
msi->feature = features->fsl_pic_ip;
+ if ((features->fsl_pic_ip & FSL_PIC_IP_MASK) == FSL_PIC_IP_MPIC) {
+ rc = mpic_has_errata(dev);
+ if (rc > 0) {
+ msi->feature |= MSI_HW_ERRATA_ENDIAN;
+ } else if (rc < 0) {
+ err = rc;
+ goto error_out;
+ }
+ }
+
/*
* Remember the phandle, so that we can match with any PCI nodes
* that have an "fsl,msi" property.
diff --git a/arch/powerpc/sysdev/fsl_msi.h b/arch/powerpc/sysdev/fsl_msi.h
index 8225f86..7389e8e 100644
--- a/arch/powerpc/sysdev/fsl_msi.h
+++ b/arch/powerpc/sysdev/fsl_msi.h
@@ -25,6 +25,8 @@
#define FSL_PIC_IP_IPIC 0x00000002
#define FSL_PIC_IP_VMPIC 0x00000003
+#define MSI_HW_ERRATA_ENDIAN 0x00000010
+
struct fsl_msi {
struct irq_domain *irqhost;
--
1.8.0
^ permalink raw reply related
* RE: [PATCH] powerpc/85xx: workaround for chips with MSI hardware errata
From: Jia Hongtao-B38951 @ 2013-03-14 11:04 UTC (permalink / raw)
To: Wood Scott-B07421, Michael Ellerman; +Cc: linuxppc-dev@lists.ozlabs.org
In-Reply-To: <1363206260.8945.13@snotra>
> -----Original Message-----
> From: Wood Scott-B07421
> Sent: Thursday, March 14, 2013 4:24 AM
> To: Michael Ellerman
> Cc: Jia Hongtao-B38951; linuxppc-dev@lists.ozlabs.org;
> galak@kernel.crashing.org; Wood Scott-B07421
> Subject: Re: [PATCH] powerpc/85xx: workaround for chips with MSI hardware
> errata
>=20
> On 03/13/2013 12:04:03 AM, Michael Ellerman wrote:
> > On Tue, Mar 12, 2013 at 03:48:02PM +0800, Jia Hongtao wrote:
> > > The MPIC chip with version 2.0 has a MSI errata (errata PIC1 of
> > mpc8544),
> > > It causes that neither MSI nor MSI-X can work fine. This is a
> > workaround
> > > to allow MSI-X to function properly.
> >
> > You say "neither MSI nor MSI-X can work fine", which I take to mean
> > "both MSI and MSI-X do not work".
> >
> > But then you say this is a workaround to allow MSI-X to work.
> >
> > So what I think you mean is, the erratum prevents both MSI and MSI-X
> > from working. This is a workaround that allows MSI-X to work, and in
> > addition the patch prevents MSI from being used on chips with the
> > erratum - because there is no workaround for MSI.
>=20
> There actually is a workaround for MSI, but it's more complicated and not
> implemented by this patch.
>=20
> We could also possibly get away with allowing exactly one MSI
> (byteswapping doesn't matter if the value is zero) -- not sure how hard
> that would be.
For now we have no plan to support MSI workaround. Also MSI workaround
deserve a new patch :)
I will sent V2 of this patch soon.
-Hongtao.
>=20
> > > + list_for_each_entry(msi, &msi_head, list)
> > > + if (msi->feature & MSI_HW_ERRATA_ENDIAN)
> > > + return -EINVAL;
> >
> > I take it you're happy preventing MSI for all devices even if only a
> > single chip in the machine has the erratum? In practice you probably
> > have all or none with the erratum right?
>=20
> Yes, it's all integrated onto one chip (the SoC itself). In fact there
> should only be one MSI block on these chips.
>=20
> -Scott
^ permalink raw reply
* Re: [RFC][PATCH 2/2] powerpc/fsl-pci Make PCIe hotplug work with Freescale
From: Rojhalat Ibrahim @ 2013-03-14 9:43 UTC (permalink / raw)
To: Kumar Gala; +Cc: linuxppc-dev
In-Reply-To: <1363201636-7318-2-git-send-email-galak@kernel.crashing.org>
On Wednesday 13 March 2013 14:07:16 Kumar Gala wrote:
> diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c
> index 41bbcc4..b18c377 100644
> --- a/arch/powerpc/sysdev/fsl_pci.c
> +++ b/arch/powerpc/sysdev/fsl_pci.c
> @@ -74,6 +74,35 @@ static int __init fsl_pcie_check_link(struct
> pci_controller *hose) return 0;
> }
>
> +static int fsl_indirect_read_config(struct pci_bus *bus, unsigned int
> devfn, + int offset, int len, u32 *val)
> +{
> + struct pci_controller *hose = pci_bus_to_host(bus);
> +
> + /* check the link status */
> + if ((bus->number == hose->first_busno) && (devfn == 0)) {
> + if (fsl_pcie_check_link(hose))
> + hose->indirect_type |= PPC_INDIRECT_TYPE_NO_PCIE_LINK;
> + else
> + hose->indirect_type &= ~PPC_INDIRECT_TYPE_NO_PCIE_LINK;
> + }
> + return indirect_read_config(bus, devfn, offset, len, val);
> +}
> +
This does not work because fsl_indirect_read_config calls fsl_pcie_check_link which calls early_read_config_dword which eventually calls fsl_indirect_read_config, so the kernel hangs in a recursion loop. Below is a modified patch that does work.
Signed-off-by: Rojhalat Ibrahim <imr@rtschenk.de>
---
arch/powerpc/include/asm/pci-bridge.h | 6 ++++
arch/powerpc/sysdev/fsl_pci.c | 51 ++++++++++++++++++++++++++++++----
arch/powerpc/sysdev/indirect_pci.c | 10 ++----
3 files changed, 55 insertions(+), 12 deletions(-)
diff --git a/arch/powerpc/include/asm/pci-bridge.h b/arch/powerpc/include/asm/pci-bridge.h
index c0278f0..ffbc5fd 100644
--- a/arch/powerpc/include/asm/pci-bridge.h
+++ b/arch/powerpc/include/asm/pci-bridge.h
@@ -120,6 +120,12 @@ extern void setup_indirect_pci(struct pci_controller* hose,
resource_size_t cfg_addr,
resource_size_t cfg_data, u32 flags);
+extern int indirect_read_config(struct pci_bus *bus, unsigned int devfn,
+ int offset, int len, u32 *val);
+
+extern int indirect_write_config(struct pci_bus *bus, unsigned int devfn,
+ int offset, int len, u32 val);
+
static inline struct pci_controller *pci_bus_to_host(const struct pci_bus *bus)
{
return bus->sysdata;
diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c
index 41bbcc4..63740f6 100644
--- a/arch/powerpc/sysdev/fsl_pci.c
+++ b/arch/powerpc/sysdev/fsl_pci.c
@@ -54,12 +54,22 @@ static void quirk_fsl_pcie_header(struct pci_dev *dev)
return;
}
-static int __init fsl_pcie_check_link(struct pci_controller *hose)
+static int fsl_indirect_read_config(struct pci_bus *, unsigned int,
+ int, int, u32 *);
+
+static int fsl_pcie_check_link(struct pci_controller *hose)
{
u32 val;
if (hose->indirect_type & PPC_INDIRECT_TYPE_FSL_CFG_REG_LINK) {
- early_read_config_dword(hose, 0, 0, PCIE_LTSSM, &val);
+ if (hose->ops->read == fsl_indirect_read_config) {
+ struct pci_bus bus;
+ bus.number = 0;
+ bus.sysdata = hose;
+ bus.ops = hose->ops;
+ indirect_read_config(&bus, 0, PCIE_LTSSM, 4, &val);
+ } else
+ early_read_config_dword(hose, 0, 0, PCIE_LTSSM, &val);
if (val < PCIE_LTSSM_L0)
return 1;
} else {
@@ -74,6 +84,35 @@ static int __init fsl_pcie_check_link(struct pci_controller *hose)
return 0;
}
+static int fsl_indirect_read_config(struct pci_bus *bus, unsigned int devfn,
+ int offset, int len, u32 *val)
+{
+ struct pci_controller *hose = pci_bus_to_host(bus);
+
+ /* check the link status */
+ if ((bus->number == hose->first_busno) && (devfn == 0)) {
+ if (fsl_pcie_check_link(hose))
+ hose->indirect_type |= PPC_INDIRECT_TYPE_NO_PCIE_LINK;
+ else
+ hose->indirect_type &= ~PPC_INDIRECT_TYPE_NO_PCIE_LINK;
+ }
+ return indirect_read_config(bus, devfn, offset, len, val);
+}
+
+static struct pci_ops fsl_indirect_pci_ops =
+{
+ .read = fsl_indirect_read_config,
+ .write = indirect_write_config,
+};
+
+static void __init fsl_setup_indirect_pci(struct pci_controller* hose,
+ resource_size_t cfg_addr,
+ resource_size_t cfg_data, u32 flags)
+{
+ setup_indirect_pci(hose, cfg_addr, cfg_data, flags);
+ hose->ops = &fsl_indirect_pci_ops;
+}
+
#if defined(CONFIG_FSL_SOC_BOOKE) || defined(CONFIG_PPC_86xx)
#define MAX_PHYS_ADDR_BITS 40
@@ -469,8 +508,8 @@ int __init fsl_add_bridge(struct platform_device *pdev, int is_primary)
if (!hose->private_data)
goto no_bridge;
- setup_indirect_pci(hose, rsrc.start, rsrc.start + 0x4,
- PPC_INDIRECT_TYPE_BIG_ENDIAN);
+ fsl_setup_indirect_pci(hose, rsrc.start, rsrc.start + 0x4,
+ PPC_INDIRECT_TYPE_BIG_ENDIAN);
if (in_be32(&pci->block_rev1) < PCIE_IP_REV_3_0)
hose->indirect_type |= PPC_INDIRECT_TYPE_FSL_CFG_REG_LINK;
@@ -779,8 +818,8 @@ int __init mpc83xx_add_bridge(struct device_node *dev)
if (ret)
goto err0;
} else {
- setup_indirect_pci(hose, rsrc_cfg.start,
- rsrc_cfg.start + 4, 0);
+ fsl_setup_indirect_pci(hose, rsrc_cfg.start,
+ rsrc_cfg.start + 4, 0);
}
printk(KERN_INFO "Found FSL PCI host bridge at 0x%016llx. "
diff --git a/arch/powerpc/sysdev/indirect_pci.c b/arch/powerpc/sysdev/indirect_pci.c
index 82fdad8..c6c8b52 100644
--- a/arch/powerpc/sysdev/indirect_pci.c
+++ b/arch/powerpc/sysdev/indirect_pci.c
@@ -20,9 +20,8 @@
#include <asm/pci-bridge.h>
#include <asm/machdep.h>
-static int
-indirect_read_config(struct pci_bus *bus, unsigned int devfn, int offset,
- int len, u32 *val)
+int indirect_read_config(struct pci_bus *bus, unsigned int devfn,
+ int offset, int len, u32 *val)
{
struct pci_controller *hose = pci_bus_to_host(bus);
volatile void __iomem *cfg_data;
@@ -78,9 +77,8 @@ indirect_read_config(struct pci_bus *bus, unsigned int devfn, int offset,
return PCIBIOS_SUCCESSFUL;
}
-static int
-indirect_write_config(struct pci_bus *bus, unsigned int devfn, int offset,
- int len, u32 val)
+int indirect_write_config(struct pci_bus *bus, unsigned int devfn,
+ int offset, int len, u32 val)
{
struct pci_controller *hose = pci_bus_to_host(bus);
volatile void __iomem *cfg_data;
^ permalink raw reply related
* Re: [PATCH 8/11] Update numa cpu vdso info
From: Paul Mackerras @ 2013-03-14 9:02 UTC (permalink / raw)
To: Nathan Fontenot; +Cc: linuxppc-dev
In-Reply-To: <513AB569.1040106@linux.vnet.ibm.com>
On Fri, Mar 08, 2013 at 10:07:05PM -0600, Nathan Fontenot wrote:
> From: Jesse Larrew <jlarrew@linux.vnet.ibm.com>
>
> The following patch adds vdso_getcpu_init(), which stores the NUMA node for
> a cpu in SPRG3:
>
> http://patchwork.ozlabs.org/patch/169070/
Since that patch is now upstream, it would be better to refer to it by
its git SHA1 ID and title, like this:
Commit 18ad51dd34 ("powerpc: Add VDSO version of getcpu") adds
vdso_getcpu_init(), which stores the NUMA node for a cpu in SPRG3.
Paul.
^ permalink raw reply
* Re: [PATCH 4/11] Add platform_has_feature()
From: Paul Mackerras @ 2013-03-14 8:59 UTC (permalink / raw)
To: Nathan Fontenot; +Cc: linuxppc-dev
In-Reply-To: <513AB457.9000409@linux.vnet.ibm.com>
On Fri, Mar 08, 2013 at 10:02:31PM -0600, Nathan Fontenot wrote:
> This patch adds a platform_has_feature() function to check features selected
> by firmware and reported via the device tree 'ibm,architecture-vec5'
> property. As part of this the #defines used for the architecture vector are
> moved to prom.h and re-defined such that the vector 5 options have the vector
> index and the feature bits encoded into them. This allows for callers of
> platform_has_feature() to pass in a single pre-defined value.
One other comment...
> +#if defined(CONFIG_PPC_PSERIES) || defined(CONFIG_PPC_POWERNV)
> +bool platform_has_feature(unsigned int feature)
> +{
> + struct device_node *chosen;
> + const char *vec5;
> + bool has_option;
> +
> + chosen = of_find_node_by_path("/chosen");
> + if (!chosen)
> + return false;
> +
> + vec5 = of_get_property(chosen, "ibm,architecture-vec-5", NULL);
> + has_option = vec5 && (vec5[OV5_INDX(feature)] & OV5_FEAT(feature));
You access vec5[index] without checking that the vector is at least
index+1 bytes long, according to either the length byte at the
beginning of the vector, or the total length of the property.
Checking both would be a good idea.
Paul.
^ permalink raw reply
* Re: [PATCH 4/11] Add platform_has_feature()
From: Paul Mackerras @ 2013-03-14 8:56 UTC (permalink / raw)
To: Nathan Fontenot; +Cc: linuxppc-dev
In-Reply-To: <513AB457.9000409@linux.vnet.ibm.com>
On Fri, Mar 08, 2013 at 10:02:31PM -0600, Nathan Fontenot wrote:
> The firmware_has_feature() function makes it easy to check for supported
> features of the hardware. There is not corresponding function to check for
> features supported by the client architecture.
Actually, firmware_has_feature checks for supported features of the
hypervisor, or in a sense the platform, rather than hardware.
> This patch adds a platform_has_feature() function to check features selected
> by firmware and reported via the device tree 'ibm,architecture-vec5'
> property. As part of this the #defines used for the architecture vector are
> moved to prom.h and re-defined such that the vector 5 options have the vector
> index and the feature bits encoded into them. This allows for callers of
> platform_has_feature() to pass in a single pre-defined value.
One other comment below...
> /* PCIe/MSI support. Without MSI full PCIe is not supported */
> #ifdef CONFIG_PCI_MSI
> -#define OV5_MSI 0x01 /* PCIe/MSI support */
> +#define OV5_MSI 0x0201 /* PCIe/MSI support */
> #else
> -#define OV5_MSI 0x00
> +#define OV5_MSI 0x0200
> #endif /* CONFIG_PCI_MSI */
The #ifdef was done this way in order to control what ended up in the
option vector we pass to the platform firmware. For checking what the
platform supports, wouldn't we want OV5_MSI to be 0x0201 always?
Similarly for OV5_CMO, OV5_XCMO, etc.?
Paul.
^ permalink raw reply
* Re: [PATCH 3/11] Move architecture vector definitions to prom.h
From: Paul Mackerras @ 2013-03-14 8:52 UTC (permalink / raw)
To: Nathan Fontenot; +Cc: linuxppc-dev
In-Reply-To: <513AB415.2040006@linux.vnet.ibm.com>
On Fri, Mar 08, 2013 at 10:01:25PM -0600, Nathan Fontenot wrote:
> As part of handling of handling PRRN events we will need to check the
> vector 5 portion of the architecture bits reported in the device tree
> to ensure that PRRN event handling is enabled. In order to do this a
> new platform_has_feature call is introduced (in a subsequent patch) to
> make this check. To avoid having to re-define bits in the architecture
> vector the bits are moved to prom.h.
>
> This patch is the first step in implementing the platform_has_feature
> call by simply moving the bit definitions from prom_init.c to asm/prom.h.
> There are no functional.
>
> Signed-off-by: Nathan Fontenot <nfont@linux.vnet.ibm.com>
Acked-by: Paul Mackerras <paulus@samba.org>
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox