* Re: [PATCH] [v2] ASoC: claim the IRQ when the fsl_ssi device is probed, not opened
From: Mark Brown @ 2011-08-17 1:04 UTC (permalink / raw)
To: Timur Tabi; +Cc: linuxppc-dev, alsa-devel, lrg
In-Reply-To: <1313534865-7795-1-git-send-email-timur@freescale.com>
On Tue, Aug 16, 2011 at 06:47:45PM -0400, Timur Tabi wrote:
> The PowerPC Freescale SSI driver is claiming the IRQ when the IRQ when
> the device is opened, which means that the /proc/interrupts entry for
> the SSI exists only during playback or capture. This also meant that
> the user won't know that the IRQ number is wrong until he tries to use
> the device. Instead, we should claim the IRQ when the device is probed.
Applied, thanks.
^ permalink raw reply
* [PATCH v13 3/6] flexcan: Fix up fsl-flexcan device tree binding.
From: Robin Holt @ 2011-08-17 3:32 UTC (permalink / raw)
To: Robin Holt, David S. Miller, Kumar Gala, Wolfgang Grandegger,
Marc Kleine-Budde, U Bhaskar-B22300
Cc: socketcan-core, netdev, devicetree-discuss, U Bhaskar-B22300,
Robin Holt, Scott Wood, PPC list
In-Reply-To: <1313551944-28603-1-git-send-email-holt@sgi.com>
This patch cleans up the documentation of the device-tree binding for
the Flexcan devices on Freescale's PowerPC and ARM cores. Extra
properties are not used by the driver so we are removing them.
Signed-off-by: Robin Holt <holt@sgi.com>
Acked-by: Marc Kleine-Budde <mkl@pengutronix.de>,
Acked-by: Wolfgang Grandegger <wg@grandegger.com>,
Cc: U Bhaskar-B22300 <B22300@freescale.com>
Cc: Scott Wood <scottwood@freescale.com>
Cc: Grant Likely <grant.likely@secretlab.ca>
Cc: Kumar Gala <galak@kernel.crashing.org>
Cc: socketcan-core@lists.berlios.de,
Cc: netdev@vger.kernel.org,
Cc: PPC list <linuxppc-dev@lists.ozlabs.org>
Cc: devicetree-discuss@lists.ozlabs.org
---
.../devicetree/bindings/net/can/fsl-flexcan.txt | 61 ++++----------------
arch/powerpc/boot/dts/p1010rdb.dts | 10 +---
arch/powerpc/boot/dts/p1010si.dtsi | 10 +--
3 files changed, 17 insertions(+), 64 deletions(-)
diff --git a/Documentation/devicetree/bindings/net/can/fsl-flexcan.txt b/Documentation/devicetree/bindings/net/can/fsl-flexcan.txt
index 1a729f0..8dfb98b 100644
--- a/Documentation/devicetree/bindings/net/can/fsl-flexcan.txt
+++ b/Documentation/devicetree/bindings/net/can/fsl-flexcan.txt
@@ -1,61 +1,22 @@
-CAN Device Tree Bindings
-------------------------
-2011 Freescale Semiconductor, Inc.
+Flexcan CAN contoller on Freescale's ARM and PowerPC system-on-a-chip (SOC).
-fsl,flexcan-v1.0 nodes
------------------------
-In addition to the required compatible-, reg- and interrupt-properties, you can
-also specify which clock source shall be used for the controller.
+Required properties:
-CPI Clock- Can Protocol Interface Clock
- This CLK_SRC bit of CTRL(control register) selects the clock source to
- the CAN Protocol Interface(CPI) to be either the peripheral clock
- (driven by the PLL) or the crystal oscillator clock. The selected clock
- is the one fed to the prescaler to generate the Serial Clock (Sclock).
- The PRESDIV field of CTRL(control register) controls a prescaler that
- generates the Serial Clock (Sclock), whose period defines the
- time quantum used to compose the CAN waveform.
+- compatible : Should be "fsl,<processor>-flexcan"
-Can Engine Clock Source
- There are two sources for CAN clock
- - Platform Clock It represents the bus clock
- - Oscillator Clock
+ An implementation should also claim any of the following compatibles
+ that it is fully backwards compatible with:
- Peripheral Clock (PLL)
- --------------
- |
- --------- -------------
- | |CPI Clock | Prescaler | Sclock
- | |---------------->| (1.. 256) |------------>
- --------- -------------
- | |
- -------------- ---------------------CLK_SRC
- Oscillator Clock
+ - fsl,p1010-flexcan
-- fsl,flexcan-clock-source : CAN Engine Clock Source.This property selects
- the peripheral clock. PLL clock is fed to the
- prescaler to generate the Serial Clock (Sclock).
- Valid values are "oscillator" and "platform"
- "oscillator": CAN engine clock source is oscillator clock.
- "platform" The CAN engine clock source is the bus clock
- (platform clock).
+- reg : Offset and length of the register set for this device
+- interrupts : Interrupt tuple for this device
-- fsl,flexcan-clock-divider : for the reference and system clock, an additional
- clock divider can be specified.
-- clock-frequency: frequency required to calculate the bitrate for FlexCAN.
+Example:
-Note:
- - v1.0 of flexcan-v1.0 represent the IP block version for P1010 SOC.
- - P1010 does not have oscillator as the Clock Source.So the default
- Clock Source is platform clock.
-Examples:
-
- can0@1c000 {
- compatible = "fsl,flexcan-v1.0";
+ can@1c000 {
+ compatible = "fsl,p1010-flexcan";
reg = <0x1c000 0x1000>;
interrupts = <48 0x2>;
interrupt-parent = <&mpic>;
- fsl,flexcan-clock-source = "platform";
- fsl,flexcan-clock-divider = <2>;
- clock-frequency = <fixed by u-boot>;
};
diff --git a/arch/powerpc/boot/dts/p1010rdb.dts b/arch/powerpc/boot/dts/p1010rdb.dts
index 6b33b73..d6c669c 100644
--- a/arch/powerpc/boot/dts/p1010rdb.dts
+++ b/arch/powerpc/boot/dts/p1010rdb.dts
@@ -23,6 +23,8 @@
ethernet2 = &enet2;
pci0 = &pci0;
pci1 = &pci1;
+ can0 = &can0;
+ can1 = &can1;
};
memory {
@@ -169,14 +171,6 @@
};
};
- can0@1c000 {
- fsl,flexcan-clock-source = "platform";
- };
-
- can1@1d000 {
- fsl,flexcan-clock-source = "platform";
- };
-
usb@22000 {
phy_type = "utmi";
};
diff --git a/arch/powerpc/boot/dts/p1010si.dtsi b/arch/powerpc/boot/dts/p1010si.dtsi
index 7f51104..cabe0a4 100644
--- a/arch/powerpc/boot/dts/p1010si.dtsi
+++ b/arch/powerpc/boot/dts/p1010si.dtsi
@@ -140,20 +140,18 @@
interrupt-parent = <&mpic>;
};
- can0@1c000 {
- compatible = "fsl,flexcan-v1.0";
+ can0: can@1c000 {
+ compatible = "fsl,p1010-flexcan";
reg = <0x1c000 0x1000>;
interrupts = <48 0x2>;
interrupt-parent = <&mpic>;
- fsl,flexcan-clock-divider = <2>;
};
- can1@1d000 {
- compatible = "fsl,flexcan-v1.0";
+ can1: can@1d000 {
+ compatible = "fsl,p1010-flexcan";
reg = <0x1d000 0x1000>;
interrupts = <61 0x2>;
interrupt-parent = <&mpic>;
- fsl,flexcan-clock-divider = <2>;
};
L2: l2-cache-controller@20000 {
--
1.7.2.1
^ permalink raw reply related
* [PATCH v13 4/6] flexcan: Add of_match to platform_device definition.
From: Robin Holt @ 2011-08-17 3:32 UTC (permalink / raw)
To: Robin Holt, David S. Miller, Kumar Gala, Wolfgang Grandegger,
Marc Kleine-Budde, U Bhaskar-B22300
Cc: socketcan-core, netdev, devicetree-discuss, U Bhaskar-B22300,
Robin Holt, PPC list
In-Reply-To: <1313551944-28603-1-git-send-email-holt@sgi.com>
On powerpc, the OpenFirmware devices are not matched without specifying
an of_match array. Introduce that array as that is used for matching
on the Freescale P1010 processor.
Signed-off-by: Robin Holt <holt@sgi.com>
Acked-by: Marc Kleine-Budde <mkl@pengutronix.de>
Acked-by: Wolfgang Grandegger <wg@grandegger.com>
Cc: U Bhaskar-B22300 <B22300@freescale.com>
Cc: Grant Likely <grant.likely@secretlab.ca>
Cc: socketcan-core@lists.berlios.de
Cc: netdev@vger.kernel.org
Cc: PPC list <linuxppc-dev@lists.ozlabs.org>
Cc: devicetree-discuss@lists.ozlabs.org
---
drivers/net/can/flexcan.c | 13 ++++++++++++-
1 files changed, 12 insertions(+), 1 deletions(-)
diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c
index 68cbe52..cc1e0a7 100644
--- a/drivers/net/can/flexcan.c
+++ b/drivers/net/can/flexcan.c
@@ -1027,8 +1027,19 @@ static int __devexit flexcan_remove(struct platform_device *pdev)
return 0;
}
+static struct of_device_id flexcan_of_match[] = {
+ {
+ .compatible = "fsl,p1010-flexcan",
+ },
+ {},
+};
+
static struct platform_driver flexcan_driver = {
- .driver.name = DRV_NAME,
+ .driver = {
+ .name = DRV_NAME,
+ .owner = THIS_MODULE,
+ .of_match_table = flexcan_of_match,
+ },
.probe = flexcan_probe,
.remove = __devexit_p(flexcan_remove),
};
--
1.7.2.1
^ permalink raw reply related
* [PATCH v13 5/6] flexcan: Prefer device tree clock frequency if available.
From: Robin Holt @ 2011-08-17 3:32 UTC (permalink / raw)
To: Robin Holt, David S. Miller, Kumar Gala, Wolfgang Grandegger,
Marc Kleine-Budde, U Bhaskar-B22300
Cc: socketcan-core, netdev, devicetree-discuss, U Bhaskar-B22300,
Robin Holt, Scott Wood, PPC list
In-Reply-To: <1313551944-28603-1-git-send-email-holt@sgi.com>
If our CAN device's device tree node has a clock-frequency property,
then use that value for the can devices clock frequency. If not, fall
back to asking the platform/mach code for the clock frequency associated
with the flexcan device.
Signed-off-by: Robin Holt <holt@sgi.com>
Acked-by: Wolfgang Grandegger <wg@grandegger.com>,
Cc: Kumar Gala <galak@kernel.crashing.org>
Cc: Marc Kleine-Budde <mkl@pengutronix.de>,
Cc: U Bhaskar-B22300 <B22300@freescale.com>
Cc: Scott Wood <scottwood@freescale.com>
Cc: Grant Likely <grant.likely@secretlab.ca>
Cc: socketcan-core@lists.berlios.de,
Cc: netdev@vger.kernel.org,
Cc: PPC list <linuxppc-dev@lists.ozlabs.org>
Cc: devicetree-discuss@lists.ozlabs.org
---
.../devicetree/bindings/net/can/fsl-flexcan.txt | 2 +
drivers/net/can/flexcan.c | 34 ++++++++++++++-----
2 files changed, 27 insertions(+), 9 deletions(-)
diff --git a/Documentation/devicetree/bindings/net/can/fsl-flexcan.txt b/Documentation/devicetree/bindings/net/can/fsl-flexcan.txt
index 8dfb98b..1ad80d5 100644
--- a/Documentation/devicetree/bindings/net/can/fsl-flexcan.txt
+++ b/Documentation/devicetree/bindings/net/can/fsl-flexcan.txt
@@ -11,6 +11,7 @@ Required properties:
- reg : Offset and length of the register set for this device
- interrupts : Interrupt tuple for this device
+- clock-frequency : The oscillator frequency driving the flexcan device
Example:
@@ -19,4 +20,5 @@ Example:
reg = <0x1c000 0x1000>;
interrupts = <48 0x2>;
interrupt-parent = <&mpic>;
+ clock-frequency = <200000000>; // filled in by bootloader
};
diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c
index cc1e0a7..e023379 100644
--- a/drivers/net/can/flexcan.c
+++ b/drivers/net/can/flexcan.c
@@ -33,6 +33,7 @@
#include <linux/kernel.h>
#include <linux/list.h>
#include <linux/module.h>
+#include <linux/of.h>
#include <linux/platform_device.h>
#define DRV_NAME "flexcan"
@@ -925,16 +926,29 @@ static int __devinit flexcan_probe(struct platform_device *pdev)
struct net_device *dev;
struct flexcan_priv *priv;
struct resource *mem;
- struct clk *clk;
+ struct clk *clk = NULL;
void __iomem *base;
resource_size_t mem_size;
int err, irq;
+ u32 clock_freq = 0;
+
+ if (pdev->dev.of_node) {
+ const u32 *clock_freq_p;
- clk = clk_get(&pdev->dev, NULL);
- if (IS_ERR(clk)) {
- dev_err(&pdev->dev, "no clock defined\n");
- err = PTR_ERR(clk);
- goto failed_clock;
+ clock_freq_p = of_get_property(pdev->dev.of_node,
+ "clock-frequency", NULL);
+ if (clock_freq_p)
+ clock_freq = *clock_freq_p;
+ }
+
+ if (!clock_freq) {
+ clk = clk_get(&pdev->dev, NULL);
+ if (IS_ERR(clk)) {
+ dev_err(&pdev->dev, "no clock defined\n");
+ err = PTR_ERR(clk);
+ goto failed_clock;
+ }
+ clock_freq = clk_get_rate(clk);
}
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -967,7 +981,7 @@ static int __devinit flexcan_probe(struct platform_device *pdev)
dev->flags |= IFF_ECHO; /* we support local echo in hardware */
priv = netdev_priv(dev);
- priv->can.clock.freq = clk_get_rate(clk);
+ priv->can.clock.freq = clock_freq;
priv->can.bittiming_const = &flexcan_bittiming_const;
priv->can.do_set_mode = flexcan_set_mode;
priv->can.do_get_berr_counter = flexcan_get_berr_counter;
@@ -1002,7 +1016,8 @@ static int __devinit flexcan_probe(struct platform_device *pdev)
failed_map:
release_mem_region(mem->start, mem_size);
failed_get:
- clk_put(clk);
+ if (clk)
+ clk_put(clk);
failed_clock:
return err;
}
@@ -1020,7 +1035,8 @@ static int __devexit flexcan_remove(struct platform_device *pdev)
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
release_mem_region(mem->start, resource_size(mem));
- clk_put(priv->clk);
+ if (priv->clk)
+ clk_put(priv->clk);
free_candev(dev);
--
1.7.2.1
^ permalink raw reply related
* [PATCH v13 0/6] flexcan: Add support for powerpc flexcan (freescale p1010)
From: Robin Holt @ 2011-08-17 3:32 UTC (permalink / raw)
To: Robin Holt, David S. Miller, Kumar Gala, Wolfgang Grandegger,
Marc Kleine-Budde, U Bhaskar-B22300
Cc: socketcan-core, netdev, PPC list, Robin Holt
David,
The following set of patches have been reviewed by the above parties and
all comments have been integrated. Although the patches stray from the
drivers/net/can directory, the diversions are related to changes for
the flexcan driver.
The patch set is based upon your net-next-2.6 tree's commit 6c37e46.
Could you please queue these up for the next appropriate push to Linus'
tree?
Thanks,
Robin Holt
^ permalink raw reply
* [PATCH v13 1/6] flexcan: Remove #include <mach/clock.h>
From: Robin Holt @ 2011-08-17 3:32 UTC (permalink / raw)
To: Robin Holt, David S. Miller, Kumar Gala, Wolfgang Grandegger,
Marc Kleine-Budde, U Bhaskar-B22300
Cc: netdev, U Bhaskar-B22300, socketcan-core, Robin Holt, PPC list
In-Reply-To: <1313551944-28603-1-git-send-email-holt@sgi.com>
powerpc does not have a mach-####/clock.h. When testing, I found neither
arm nor powerpc needed the mach/clock.h at all so I removed it.
Signed-off-by: Robin Holt <holt@sgi.com>
Acked-by: Marc Kleine-Budde <mkl@pengutronix.de>
Acked-by: Wolfgang Grandegger <wg@grandegger.com>
Cc: U Bhaskar-B22300 <B22300@freescale.com>
Cc: socketcan-core@lists.berlios.de
Cc: netdev@vger.kernel.org
Cc: PPC list <linuxppc-dev@lists.ozlabs.org>
---
drivers/net/can/flexcan.c | 2 --
1 files changed, 0 insertions(+), 2 deletions(-)
diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c
index 1767811..586b2cd 100644
--- a/drivers/net/can/flexcan.c
+++ b/drivers/net/can/flexcan.c
@@ -35,8 +35,6 @@
#include <linux/module.h>
#include <linux/platform_device.h>
-#include <mach/clock.h>
-
#define DRV_NAME "flexcan"
/* 8 for RX fifo and 2 error handling */
--
1.7.2.1
^ permalink raw reply related
* [PATCH v13 2/6] flexcan: Abstract off read/write for big/little endian.
From: Robin Holt @ 2011-08-17 3:32 UTC (permalink / raw)
To: Robin Holt, David S. Miller, Kumar Gala, Wolfgang Grandegger,
Marc Kleine-Budde, U Bhaskar-B22300
Cc: netdev, U Bhaskar-B22300, socketcan-core, Robin Holt, PPC list
In-Reply-To: <1313551944-28603-1-git-send-email-holt@sgi.com>
Make flexcan driver handle register reads in the appropriate endianess.
This was a basic search and replace and then define some inlines.
Signed-off-by: Robin Holt <holt@sgi.com>
Acked-by: Marc Kleine-Budde <mkl@pengutronix.de>
Acked-by: Wolfgang Grandegger <wg@grandegger.com>
Cc: U Bhaskar-B22300 <B22300@freescale.com>
Cc: socketcan-core@lists.berlios.de
Cc: netdev@vger.kernel.org
Cc: PPC list <linuxppc-dev@lists.ozlabs.org>
---
drivers/net/can/flexcan.c | 140 ++++++++++++++++++++++++++------------------
1 files changed, 83 insertions(+), 57 deletions(-)
diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c
index 586b2cd..68cbe52 100644
--- a/drivers/net/can/flexcan.c
+++ b/drivers/net/can/flexcan.c
@@ -190,6 +190,31 @@ static struct can_bittiming_const flexcan_bittiming_const = {
};
/*
+ * Abstract off the read/write for arm versus ppc.
+ */
+#if defined(__BIG_ENDIAN)
+static inline u32 flexcan_read(void __iomem *addr)
+{
+ return in_be32(addr);
+}
+
+static inline void flexcan_write(u32 val, void __iomem *addr)
+{
+ out_be32(addr, val);
+}
+#else
+static inline u32 flexcan_read(void __iomem *addr)
+{
+ return readl(addr);
+}
+
+static inline void flexcan_write(u32 val, void __iomem *addr)
+{
+ writel(val, addr);
+}
+#endif
+
+/*
* Swtich transceiver on or off
*/
static void flexcan_transceiver_switch(const struct flexcan_priv *priv, int on)
@@ -210,9 +235,9 @@ static inline void flexcan_chip_enable(struct flexcan_priv *priv)
struct flexcan_regs __iomem *regs = priv->base;
u32 reg;
- reg = readl(®s->mcr);
+ reg = flexcan_read(®s->mcr);
reg &= ~FLEXCAN_MCR_MDIS;
- writel(reg, ®s->mcr);
+ flexcan_write(reg, ®s->mcr);
udelay(10);
}
@@ -222,9 +247,9 @@ static inline void flexcan_chip_disable(struct flexcan_priv *priv)
struct flexcan_regs __iomem *regs = priv->base;
u32 reg;
- reg = readl(®s->mcr);
+ reg = flexcan_read(®s->mcr);
reg |= FLEXCAN_MCR_MDIS;
- writel(reg, ®s->mcr);
+ flexcan_write(reg, ®s->mcr);
}
static int flexcan_get_berr_counter(const struct net_device *dev,
@@ -232,7 +257,7 @@ static int flexcan_get_berr_counter(const struct net_device *dev,
{
const struct flexcan_priv *priv = netdev_priv(dev);
struct flexcan_regs __iomem *regs = priv->base;
- u32 reg = readl(®s->ecr);
+ u32 reg = flexcan_read(®s->ecr);
bec->txerr = (reg >> 0) & 0xff;
bec->rxerr = (reg >> 8) & 0xff;
@@ -266,15 +291,15 @@ static int flexcan_start_xmit(struct sk_buff *skb, struct net_device *dev)
if (cf->can_dlc > 0) {
u32 data = be32_to_cpup((__be32 *)&cf->data[0]);
- writel(data, ®s->cantxfg[FLEXCAN_TX_BUF_ID].data[0]);
+ flexcan_write(data, ®s->cantxfg[FLEXCAN_TX_BUF_ID].data[0]);
}
if (cf->can_dlc > 3) {
u32 data = be32_to_cpup((__be32 *)&cf->data[4]);
- writel(data, ®s->cantxfg[FLEXCAN_TX_BUF_ID].data[1]);
+ flexcan_write(data, ®s->cantxfg[FLEXCAN_TX_BUF_ID].data[1]);
}
- writel(can_id, ®s->cantxfg[FLEXCAN_TX_BUF_ID].can_id);
- writel(ctrl, ®s->cantxfg[FLEXCAN_TX_BUF_ID].can_ctrl);
+ flexcan_write(can_id, ®s->cantxfg[FLEXCAN_TX_BUF_ID].can_id);
+ flexcan_write(ctrl, ®s->cantxfg[FLEXCAN_TX_BUF_ID].can_ctrl);
kfree_skb(skb);
@@ -462,8 +487,8 @@ static void flexcan_read_fifo(const struct net_device *dev,
struct flexcan_mb __iomem *mb = ®s->cantxfg[0];
u32 reg_ctrl, reg_id;
- reg_ctrl = readl(&mb->can_ctrl);
- reg_id = readl(&mb->can_id);
+ reg_ctrl = flexcan_read(&mb->can_ctrl);
+ reg_id = flexcan_read(&mb->can_id);
if (reg_ctrl & FLEXCAN_MB_CNT_IDE)
cf->can_id = ((reg_id >> 0) & CAN_EFF_MASK) | CAN_EFF_FLAG;
else
@@ -473,12 +498,12 @@ static void flexcan_read_fifo(const struct net_device *dev,
cf->can_id |= CAN_RTR_FLAG;
cf->can_dlc = get_can_dlc((reg_ctrl >> 16) & 0xf);
- *(__be32 *)(cf->data + 0) = cpu_to_be32(readl(&mb->data[0]));
- *(__be32 *)(cf->data + 4) = cpu_to_be32(readl(&mb->data[1]));
+ *(__be32 *)(cf->data + 0) = cpu_to_be32(flexcan_read(&mb->data[0]));
+ *(__be32 *)(cf->data + 4) = cpu_to_be32(flexcan_read(&mb->data[1]));
/* mark as read */
- writel(FLEXCAN_IFLAG_RX_FIFO_AVAILABLE, ®s->iflag1);
- readl(®s->timer);
+ flexcan_write(FLEXCAN_IFLAG_RX_FIFO_AVAILABLE, ®s->iflag1);
+ flexcan_read(®s->timer);
}
static int flexcan_read_frame(struct net_device *dev)
@@ -514,17 +539,17 @@ static int flexcan_poll(struct napi_struct *napi, int quota)
* The error bits are cleared on read,
* use saved value from irq handler.
*/
- reg_esr = readl(®s->esr) | priv->reg_esr;
+ reg_esr = flexcan_read(®s->esr) | priv->reg_esr;
/* handle state changes */
work_done += flexcan_poll_state(dev, reg_esr);
/* handle RX-FIFO */
- reg_iflag1 = readl(®s->iflag1);
+ reg_iflag1 = flexcan_read(®s->iflag1);
while (reg_iflag1 & FLEXCAN_IFLAG_RX_FIFO_AVAILABLE &&
work_done < quota) {
work_done += flexcan_read_frame(dev);
- reg_iflag1 = readl(®s->iflag1);
+ reg_iflag1 = flexcan_read(®s->iflag1);
}
/* report bus errors */
@@ -534,8 +559,8 @@ static int flexcan_poll(struct napi_struct *napi, int quota)
if (work_done < quota) {
napi_complete(napi);
/* enable IRQs */
- writel(FLEXCAN_IFLAG_DEFAULT, ®s->imask1);
- writel(priv->reg_ctrl_default, ®s->ctrl);
+ flexcan_write(FLEXCAN_IFLAG_DEFAULT, ®s->imask1);
+ flexcan_write(priv->reg_ctrl_default, ®s->ctrl);
}
return work_done;
@@ -549,9 +574,9 @@ static irqreturn_t flexcan_irq(int irq, void *dev_id)
struct flexcan_regs __iomem *regs = priv->base;
u32 reg_iflag1, reg_esr;
- reg_iflag1 = readl(®s->iflag1);
- reg_esr = readl(®s->esr);
- writel(FLEXCAN_ESR_ERR_INT, ®s->esr); /* ACK err IRQ */
+ reg_iflag1 = flexcan_read(®s->iflag1);
+ reg_esr = flexcan_read(®s->esr);
+ flexcan_write(FLEXCAN_ESR_ERR_INT, ®s->esr); /* ACK err IRQ */
/*
* schedule NAPI in case of:
@@ -567,16 +592,16 @@ static irqreturn_t flexcan_irq(int irq, void *dev_id)
* save them for later use.
*/
priv->reg_esr = reg_esr & FLEXCAN_ESR_ERR_BUS;
- writel(FLEXCAN_IFLAG_DEFAULT & ~FLEXCAN_IFLAG_RX_FIFO_AVAILABLE,
- ®s->imask1);
- writel(priv->reg_ctrl_default & ~FLEXCAN_CTRL_ERR_ALL,
+ flexcan_write(FLEXCAN_IFLAG_DEFAULT &
+ ~FLEXCAN_IFLAG_RX_FIFO_AVAILABLE, ®s->imask1);
+ flexcan_write(priv->reg_ctrl_default & ~FLEXCAN_CTRL_ERR_ALL,
®s->ctrl);
napi_schedule(&priv->napi);
}
/* FIFO overflow */
if (reg_iflag1 & FLEXCAN_IFLAG_RX_FIFO_OVERFLOW) {
- writel(FLEXCAN_IFLAG_RX_FIFO_OVERFLOW, ®s->iflag1);
+ flexcan_write(FLEXCAN_IFLAG_RX_FIFO_OVERFLOW, ®s->iflag1);
dev->stats.rx_over_errors++;
dev->stats.rx_errors++;
}
@@ -585,7 +610,7 @@ static irqreturn_t flexcan_irq(int irq, void *dev_id)
if (reg_iflag1 & (1 << FLEXCAN_TX_BUF_ID)) {
/* tx_bytes is incremented in flexcan_start_xmit */
stats->tx_packets++;
- writel((1 << FLEXCAN_TX_BUF_ID), ®s->iflag1);
+ flexcan_write((1 << FLEXCAN_TX_BUF_ID), ®s->iflag1);
netif_wake_queue(dev);
}
@@ -599,7 +624,7 @@ static void flexcan_set_bittiming(struct net_device *dev)
struct flexcan_regs __iomem *regs = priv->base;
u32 reg;
- reg = readl(®s->ctrl);
+ reg = flexcan_read(®s->ctrl);
reg &= ~(FLEXCAN_CTRL_PRESDIV(0xff) |
FLEXCAN_CTRL_RJW(0x3) |
FLEXCAN_CTRL_PSEG1(0x7) |
@@ -623,11 +648,11 @@ static void flexcan_set_bittiming(struct net_device *dev)
reg |= FLEXCAN_CTRL_SMP;
dev_info(dev->dev.parent, "writing ctrl=0x%08x\n", reg);
- writel(reg, ®s->ctrl);
+ flexcan_write(reg, ®s->ctrl);
/* print chip status */
dev_dbg(dev->dev.parent, "%s: mcr=0x%08x ctrl=0x%08x\n", __func__,
- readl(®s->mcr), readl(®s->ctrl));
+ flexcan_read(®s->mcr), flexcan_read(®s->ctrl));
}
/*
@@ -648,10 +673,10 @@ static int flexcan_chip_start(struct net_device *dev)
flexcan_chip_enable(priv);
/* soft reset */
- writel(FLEXCAN_MCR_SOFTRST, ®s->mcr);
+ flexcan_write(FLEXCAN_MCR_SOFTRST, ®s->mcr);
udelay(10);
- reg_mcr = readl(®s->mcr);
+ reg_mcr = flexcan_read(®s->mcr);
if (reg_mcr & FLEXCAN_MCR_SOFTRST) {
dev_err(dev->dev.parent,
"Failed to softreset can module (mcr=0x%08x)\n",
@@ -673,12 +698,12 @@ static int flexcan_chip_start(struct net_device *dev)
* choose format C
*
*/
- reg_mcr = readl(®s->mcr);
+ reg_mcr = flexcan_read(®s->mcr);
reg_mcr |= FLEXCAN_MCR_FRZ | FLEXCAN_MCR_FEN | FLEXCAN_MCR_HALT |
FLEXCAN_MCR_SUPV | FLEXCAN_MCR_WRN_EN |
FLEXCAN_MCR_IDAM_C;
dev_dbg(dev->dev.parent, "%s: writing mcr=0x%08x", __func__, reg_mcr);
- writel(reg_mcr, ®s->mcr);
+ flexcan_write(reg_mcr, ®s->mcr);
/*
* CTRL
@@ -696,7 +721,7 @@ static int flexcan_chip_start(struct net_device *dev)
* (FLEXCAN_CTRL_ERR_MSK), too. Otherwise we don't get any
* warning or bus passive interrupts.
*/
- reg_ctrl = readl(®s->ctrl);
+ reg_ctrl = flexcan_read(®s->ctrl);
reg_ctrl &= ~FLEXCAN_CTRL_TSYN;
reg_ctrl |= FLEXCAN_CTRL_BOFF_REC | FLEXCAN_CTRL_LBUF |
FLEXCAN_CTRL_ERR_STATE | FLEXCAN_CTRL_ERR_MSK;
@@ -704,38 +729,39 @@ static int flexcan_chip_start(struct net_device *dev)
/* save for later use */
priv->reg_ctrl_default = reg_ctrl;
dev_dbg(dev->dev.parent, "%s: writing ctrl=0x%08x", __func__, reg_ctrl);
- writel(reg_ctrl, ®s->ctrl);
+ flexcan_write(reg_ctrl, ®s->ctrl);
for (i = 0; i < ARRAY_SIZE(regs->cantxfg); i++) {
- writel(0, ®s->cantxfg[i].can_ctrl);
- writel(0, ®s->cantxfg[i].can_id);
- writel(0, ®s->cantxfg[i].data[0]);
- writel(0, ®s->cantxfg[i].data[1]);
+ flexcan_write(0, ®s->cantxfg[i].can_ctrl);
+ flexcan_write(0, ®s->cantxfg[i].can_id);
+ flexcan_write(0, ®s->cantxfg[i].data[0]);
+ flexcan_write(0, ®s->cantxfg[i].data[1]);
/* put MB into rx queue */
- writel(FLEXCAN_MB_CNT_CODE(0x4), ®s->cantxfg[i].can_ctrl);
+ flexcan_write(FLEXCAN_MB_CNT_CODE(0x4),
+ ®s->cantxfg[i].can_ctrl);
}
/* acceptance mask/acceptance code (accept everything) */
- writel(0x0, ®s->rxgmask);
- writel(0x0, ®s->rx14mask);
- writel(0x0, ®s->rx15mask);
+ flexcan_write(0x0, ®s->rxgmask);
+ flexcan_write(0x0, ®s->rx14mask);
+ flexcan_write(0x0, ®s->rx15mask);
flexcan_transceiver_switch(priv, 1);
/* synchronize with the can bus */
- reg_mcr = readl(®s->mcr);
+ reg_mcr = flexcan_read(®s->mcr);
reg_mcr &= ~FLEXCAN_MCR_HALT;
- writel(reg_mcr, ®s->mcr);
+ flexcan_write(reg_mcr, ®s->mcr);
priv->can.state = CAN_STATE_ERROR_ACTIVE;
/* enable FIFO interrupts */
- writel(FLEXCAN_IFLAG_DEFAULT, ®s->imask1);
+ flexcan_write(FLEXCAN_IFLAG_DEFAULT, ®s->imask1);
/* print chip status */
dev_dbg(dev->dev.parent, "%s: reading mcr=0x%08x ctrl=0x%08x\n",
- __func__, readl(®s->mcr), readl(®s->ctrl));
+ __func__, flexcan_read(®s->mcr), flexcan_read(®s->ctrl));
return 0;
@@ -757,12 +783,12 @@ static void flexcan_chip_stop(struct net_device *dev)
u32 reg;
/* Disable all interrupts */
- writel(0, ®s->imask1);
+ flexcan_write(0, ®s->imask1);
/* Disable + halt module */
- reg = readl(®s->mcr);
+ reg = flexcan_read(®s->mcr);
reg |= FLEXCAN_MCR_MDIS | FLEXCAN_MCR_HALT;
- writel(reg, ®s->mcr);
+ flexcan_write(reg, ®s->mcr);
flexcan_transceiver_switch(priv, 0);
priv->can.state = CAN_STATE_STOPPED;
@@ -854,24 +880,24 @@ static int __devinit register_flexcandev(struct net_device *dev)
/* select "bus clock", chip must be disabled */
flexcan_chip_disable(priv);
- reg = readl(®s->ctrl);
+ reg = flexcan_read(®s->ctrl);
reg |= FLEXCAN_CTRL_CLK_SRC;
- writel(reg, ®s->ctrl);
+ flexcan_write(reg, ®s->ctrl);
flexcan_chip_enable(priv);
/* set freeze, halt and activate FIFO, restrict register access */
- reg = readl(®s->mcr);
+ reg = flexcan_read(®s->mcr);
reg |= FLEXCAN_MCR_FRZ | FLEXCAN_MCR_HALT |
FLEXCAN_MCR_FEN | FLEXCAN_MCR_SUPV;
- writel(reg, ®s->mcr);
+ flexcan_write(reg, ®s->mcr);
/*
* Currently we only support newer versions of this core
* featuring a RX FIFO. Older cores found on some Coldfire
* derivates are not yet supported.
*/
- reg = readl(®s->mcr);
+ reg = flexcan_read(®s->mcr);
if (!(reg & FLEXCAN_MCR_FEN)) {
dev_err(dev->dev.parent,
"Could not enable RX FIFO, unsupported core\n");
--
1.7.2.1
^ permalink raw reply related
* [PATCH v13 6/6] flexcan: Add flexcan device support for p1010rdb.
From: Robin Holt @ 2011-08-17 3:32 UTC (permalink / raw)
To: Robin Holt, David S. Miller, Kumar Gala, Wolfgang Grandegger,
Marc Kleine-Budde, U Bhaskar-B22300
Cc: netdev, U Bhaskar-B22300, socketcan-core, Robin Holt, PPC list
In-Reply-To: <1313551944-28603-1-git-send-email-holt@sgi.com>
Allow the p1010 processor to select the flexcan network driver.
Signed-off-by: Robin Holt <holt@sgi.com>
Acked-by: Marc Kleine-Budde <mkl@pengutronix.de>,
Acked-by: Wolfgang Grandegger <wg@grandegger.com>,
Cc: U Bhaskar-B22300 <B22300@freescale.com>
Cc: socketcan-core@lists.berlios.de,
Cc: netdev@vger.kernel.org,
Cc: PPC list <linuxppc-dev@lists.ozlabs.org>
Cc: Kumar Gala <galak@kernel.crashing.org>
---
arch/powerpc/Kconfig | 2 ++
1 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 6926b61..47682b6 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -656,6 +656,8 @@ config SBUS
config FSL_SOC
bool
+ select HAVE_CAN_FLEXCAN if NET && CAN
+ select PPC_CLOCK if CAN_FLEXCAN
config FSL_PCI
bool
--
1.7.2.1
^ permalink raw reply related
* [PATCH] tags, powerpc: Update tags.sh to support _GLOBAL symbols
From: Ian Munsie @ 2011-08-17 6:25 UTC (permalink / raw)
To: Benjamin Herrenschmidt, linuxppc-dev, Michal Marek
Cc: Ian Munsie, linux-kbuild
From: Ian Munsie <imunsie@au1.ibm.com>
On PowerPC we use _GLOBAL throughout the assembly to define symbols, but
currently these symbols are missing from the tags generated with
ARCH=powerpc make tags. This patch modifies the tags.sh script to
recognise _GLOBAL(.*) so that these symbols will be in the tags.
This is almost (but not quite) PowerPC specific and this change should
not affect anyone else:
$ git grep -E '^_GLOBAL\(([^)]*)\).*' |sed 's/^\([^/]*\/[^/]*\)\/.*$/\1/'|uniq -c
627 arch/powerpc
2 arch/um
Signed-off-by: Ian Munsie <imunsie@au1.ibm.com>
---
scripts/tags.sh | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/scripts/tags.sh b/scripts/tags.sh
index 75c5d24f1..38f6617 100755
--- a/scripts/tags.sh
+++ b/scripts/tags.sh
@@ -129,7 +129,7 @@ exuberant()
-I EXPORT_SYMBOL,EXPORT_SYMBOL_GPL \
-I DEFINE_TRACE,EXPORT_TRACEPOINT_SYMBOL,EXPORT_TRACEPOINT_SYMBOL_GPL \
--extra=+f --c-kinds=+px \
- --regex-asm='/^ENTRY\(([^)]*)\).*/\1/' \
+ --regex-asm='/^(ENTRY|_GLOBAL)\(([^)]*)\).*/\2/' \
--regex-c='/^SYSCALL_DEFINE[[:digit:]]?\(([^,)]*).*/sys_\1/' \
--regex-c++='/^TRACE_EVENT\(([^,)]*).*/trace_\1/' \
--regex-c++='/^DEFINE_EVENT\([^,)]*, *([^,)]*).*/trace_\1/'
@@ -151,7 +151,7 @@ exuberant()
emacs()
{
all_sources | xargs $1 -a \
- --regex='/^ENTRY(\([^)]*\)).*/\1/' \
+ --regex='/^(ENTRY|_GLOBAL)(\([^)]*\)).*/\2/' \
--regex='/^SYSCALL_DEFINE[0-9]?(\([^,)]*\).*/sys_\1/' \
--regex='/^TRACE_EVENT(\([^,)]*\).*/trace_\1/' \
--regex='/^DEFINE_EVENT([^,)]*, *\([^,)]*\).*/trace_\1/'
--
1.7.2.5
^ permalink raw reply related
* [PATCH] powerpc/mm: fix the call trace when resumed from hibernation
From: b29983 @ 2011-08-17 5:51 UTC (permalink / raw)
To: benh; +Cc: Tang Yuantian, linuxppc-dev
From: Tang Yuantian <B29983@freescale.com>
In SMP mode, the kernel would produce call trace when resumed
from hibernation. The reason is when the function destroy_context
is called to drop the resuming mm context, the mm->context.active
is 1 which is wrong and should be zero.
We pass the current->active_mm as previous mm context to function
switch_mmu_context to decrease the context.active by 1.
In UP mode, there is no effect.
Signed-off-by: Tang Yuantian <b29983@freescale.com>
---
arch/powerpc/kernel/swsusp.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/arch/powerpc/kernel/swsusp.c b/arch/powerpc/kernel/swsusp.c
index 560c961..7cc81f0 100644
--- a/arch/powerpc/kernel/swsusp.c
+++ b/arch/powerpc/kernel/swsusp.c
@@ -34,6 +34,6 @@ void save_processor_state(void)
void restore_processor_state(void)
{
#ifdef CONFIG_PPC32
- switch_mmu_context(NULL, current->active_mm);
+ switch_mmu_context(current->active_mm, current->active_mm);
#endif
}
--
1.6.4
^ permalink raw reply related
* Re: [PATCH] mtd-utils: fix corrupt cleanmarker with flash_erase -j command
From: LiuShuo @ 2011-08-17 7:35 UTC (permalink / raw)
To: dedekind1; +Cc: linuxppc-dev, dwmw2, linux-mtd, linuxppc-dev
In-Reply-To: <1313507201.2679.2.camel@sauron>
=E4=BA=8E 2011=E5=B9=B408=E6=9C=8816=E6=97=A5 23:06, Artem Bityutskiy =E5=
=86=99=E9=81=93:
> On Wed, 2011-08-03 at 13:50 +0800, b35362@freescale.com wrote:
>> From: Liu Shuo<b35362@freescale.com>
>>
>> Flash_erase -j should fill discrete freeoob areas with required bytes
>> of JFFS2 cleanmarker in jffs2_check_nand_cleanmarker(). Not just fill
>> the first freeoob area.
>>
>> Signed-off-by: Liu Shuo<b35362@freescale.com>
>> Signed-off-by: Li Yang<leoli@freescale.com>
> ...
>
>> /*
>> * Process user arguments
>> @@ -197,15 +198,40 @@ int main(int argc, char *argv[])
>> if (ioctl(fd, MEMGETOOBSEL,&oobinfo) !=3D 0)
>> return sys_errmsg("%s: unable to get NAND oobinfo", mtd_device);
>>
>> + cleanmarker.totlen =3D cpu_to_je32(8);
>> /* Check for autoplacement */
>> if (oobinfo.useecc =3D=3D MTD_NANDECC_AUTOPLACE) {
>> + struct nand_ecclayout_user ecclayout;
>> /* Get the position of the free bytes */
>> - if (!oobinfo.oobfree[0][1])
>> + if (ioctl(fd, ECCGETLAYOUT,&ecclayout) !=3D 0)
>> + return sys_errmsg("%s: unable to get NAND ecclayout", mtd_device=
);
>> +
> Hmm, shouldn't we instead make MTD_OOB_AUTO be available for userspace
> via an ioctl instead and make flash_eraseall use it instead?
>
I think We can add a new ioctl MEMSETOOBMODE for selecting a mode to=20
access the OOB area.
Add new member into struct mtd_info:
struct mtd_info {
......
enum {
MTD_OOB_PLACE,
MTD_OOB_AUTO,
MTD_OOB_RAW,
} oob_mode;
}
In function mtd_do_writeoob() (in drivers/mtd/mtdchar.c) :
- ops.mode =3D MTD_OOB_PLACE;
+ ops.mode =3D mtd->oob_mode;
Could we do it like this ?
Thanks
-LiuShuo
^ permalink raw reply
* Re: [PATCH] mtd-utils: fix corrupt cleanmarker with flash_erase -j command
From: Artem Bityutskiy @ 2011-08-17 7:39 UTC (permalink / raw)
To: LiuShuo; +Cc: linuxppc-dev, dwmw2, linux-mtd, linuxppc-dev
In-Reply-To: <4E4B6F46.2050209@freescale.com>
On Wed, 2011-08-17 at 15:35 +0800, LiuShuo wrote:
> I think We can add a new ioctl MEMSETOOBMODE for selecting a mode to
> access the OOB area.
>
> Add new member into struct mtd_info:
>
> struct mtd_info {
> ......
>
> enum {
> MTD_OOB_PLACE,
> MTD_OOB_AUTO,
> MTD_OOB_RAW,
> } oob_mode;
> }
>
> In function mtd_do_writeoob() (in drivers/mtd/mtdchar.c) :
> - ops.mode = MTD_OOB_PLACE;
> + ops.mode = mtd->oob_mode;
>
>
>
> Could we do it like this ?
I think the OOB mode should not be a global MTD device state. Each
ioctl invocation should just specify the mode.
Brian's idea of having a completely new ioctl or a set of new ioctls for
OOB which would copletely deprecate the old ones is a good idea. Let's
wait for his patch.
May be we should even start physically removing depricated ioctls by
first adding a printk with a warning and then removing completely. But
first mtdutils should be updated to not use them.
--
Best Regards,
Artem Bityutskiy
^ permalink raw reply
* RE: [PATCH] rio: Use discovered bit to test if enumeration is complete
From: Liu Gang-B34182 @ 2011-08-17 9:45 UTC (permalink / raw)
To: 'Bounine, Alexandre',
'linux-kernel@vger.kernel.org'
Cc: 'linuxppc-dev@ozlabs.org',
'akpm@linux-foundation.org', Gala Kumar-B11780,
Li Yang-R58472, Zang Roy-R61911
In-Reply-To: <0CE8B6BE3C4AD74AB97D9D29BD24E552020244E5@CORPEXCH1.na.ads.idt.com>
Hi, Andrew,
Could you please apply this patch into your tree?
Thanks a lot!
Regards,
Liu Gang
-----Original Message-----
From: Bounine, Alexandre [mailto:Alexandre.Bounine@idt.com]=20
Sent: Tuesday, August 09, 2011 8:36 PM
To: Liu Gang-B34182; linux-kernel@vger.kernel.org
Cc: Li Yang-R58472; Zang Roy-R61911; linuxppc-dev@ozlabs.org; Liu Gang-B341=
82; akpm@linux-foundation.org; Gala Kumar-B11780
Subject: RE: [PATCH] rio: Use discovered bit to test if enumeration is comp=
lete
On Monday, August 08, 2011 at 10:17 PM, Liu Gang wrote:
> Subject: [PATCH] rio: Use discovered bit to test if enumeration is=20
> complete
>=20
> The discovered bit in PGCCSR register indicates if the device has been=20
> discovered by system host. In Rapidio system, some agent devices can=20
> also be master devices. They can issue requests into the system.
>=20
> Signed-off-by: Liu Gang <Gang.Liu@freescale.com>
> ---
> drivers/rapidio/rio-scan.c | 4 ++--
> 1 files changed, 2 insertions(+), 2 deletions(-)
Acked-by: Alexandre Bounine <alexandre.bounine@idt.com>
^ permalink raw reply
* Networkinterface on MPC5200b
From: Bjoern Slotkowski @ 2011-08-17 11:31 UTC (permalink / raw)
To: linuxppc-dev
Hello,
We have two problems when using the fec of the MPC5200b.
The occurence of both problems is very seldom.
1.
Sometimes the first two octets of the MAC-Adress are wrong.
Removing/inserting the driver does not help.
2.
Sometimes the communication stops.
When Removing the driver following message occurs:
net eth0: queues didn't drain
net eth0: tx: index: 9, outdex: 23
net eth0: rx: index: 81, outdex: 82
Is there any known issue about this ?
For the second point I was able to create a situation to reproduce the
behavior:
For this only a wrong checksum has to be appended to the ethernet-frame
transmitted to the fec.
When sending normal frames afterward nothing happens, the comunication is
dead.
It seems as if the part of the bestcom dma which handles the fec stops.
So we modified the driver code:
Normallly when a checksum error occurs, an error interrupt is generated for
the fec-driver and nothing will be done
beside error counting.
We modified the interrupt routine: The bestcom dma for the fec is setup
again.
This modification helps sometimes but not always.
Sometimes receiving frames does not work.
Sometimes sending frames does not work after the handling of the error.
So we tried to modify the microcode of the dma to find out what wents wrong.
But here we run into trouble:
Every modifiaction especially inserting a NOP at the end leads to a non
working dma
(We also modified the size in the setup-header).
Does anyone has experience with the microcode of the bestcom dma ?
We found some documentation of the dma and how it could be possible to do
something like a debugging
and we were roughly able to read what is happening in the mirocode.
But probably we do not understand all.
Thanks a million,
Björn Slotkowski
--
imc Messsysteme GmbH
Bereich Entwicklung / Dept. Development
Voltastraße 5
D-13355 Berlin
Germany
Tel: +49 30 46 70 90 23
Fax: +49 30 46 31 57 6
mailto:Bjoern.Slotkowski@imc-berlin.de
Homepage: http://www.imc-berlin.de
Sitz der Gesellschaft : Berlin
Handelsregister : Berlin-Charlottenburg HRB 28778
Geschäftsführer : Dr.-Ing. Dietmar Sprenger
^ permalink raw reply
* RE: [PATCH] RapidIO: Add mport driver for Tsi721 bridge
From: Bounine, Alexandre @ 2011-08-17 20:21 UTC (permalink / raw)
To: Andrew Morton; +Cc: Kim, Chul, linuxppc-dev, linux-kernel
In-Reply-To: <20110816160120.50bda968.akpm@linux-foundation.org>
Andrew Morton wrote:
> On Fri, 12 Aug 2011 15:45:34 -0400
> Alexandre Bounine <alexandre.bounine@idt.com> wrote:
>=20
> > Add RapidIO mport driver for IDT TSI721 PCI Express-to-SRIO bridge
device.
>=20
> What a huge driver.
It is not over yet. We have plans to add more stuff later.
=20
> >
> > ...
> > +config RAPIDIO_TSI721
> > + bool "IDT Tsi721 PCI Express SRIO Controller support"
> > + depends on RAPIDIO && PCI && PCIEPORTBUS
>=20
> The dependency on PCI is redundant - PCIEPORTBUS already depends on
> PCI. Doesn't matter much though.
Agree. Will clean it for next release.=20
=20
> > + default "n"
> > + ---help---
> > + Include support for IDT Tsi721 PCI Express Serial RapidIO
> controller.
> >
> > ...
> >
> > + /* Wait until DMA transfer is finished */
> > + while ((ch_stat =3D ioread32(priv->regs +
> > + TSI721_DMAC_STS(TSI721_DMACH_MAINT))) &
TSI721_DMAC_STS_RUN) {
> > + udelay(10);
> > + i++;
> > + if (i >=3D 5000000) {
> > + dev_dbg(&priv->pdev->dev,
> > + "%s : DMA[%d] read timeout
ch_status=3D%x\n",
> > + __func__, TSI721_DMACH_MAINT, ch_stat);
> > + if (!do_wr)
> > + *data =3D 0xffffffff;
> > + err =3D -EFAULT;
> > + goto err_out;
> > + }
> > + }
>=20
> Fifty seconds!?!?
Should be "udelay(1)" - 10 usec is too much here.
=20
> EFAULT seems an inappropriate errno.
Switching to EIO.
=20
> > + if (ch_stat & TSI721_DMAC_STS_ABORT) {
> > + /* If DMA operation aborted due to error,
> > + * reinitialize DMA channel
> > + */
.....
> > + iowrite32(0, priv->regs +
> > + TSI721_DMAC_DWRCNT(TSI721_DMACH_MAINT));
> > + udelay(1);
> > + if (!do_wr)
> > + *data =3D 0xffffffff;
> > + err =3D -EFAULT;
Here EIO as well because ABORT error reports more events than just bad
address.
> > ...
> >
> > +static int
> > +tsi721_pw_handler(struct rio_mport *mport)
> > +{
> > + struct tsi721_device *priv =3D mport->priv;
> > + u32 pw_stat;
> > + u32 pw_buf[TSI721_RIO_PW_MSG_SIZE/sizeof(u32)];
> > +
> > +
> > + pw_stat =3D ioread32(priv->regs + TSI721_RIO_PW_RX_STAT);
> > +
> > + if (pw_stat & TSI721_RIO_PW_RX_STAT_PW_VAL) {
> > + pw_buf[0] =3D ioread32(priv->regs +
TSI721_RIO_PW_RX_CAPT(0));
> > + pw_buf[1] =3D ioread32(priv->regs +
TSI721_RIO_PW_RX_CAPT(1));
> > + pw_buf[2] =3D ioread32(priv->regs +
TSI721_RIO_PW_RX_CAPT(2));
> > + pw_buf[3] =3D ioread32(priv->regs +
TSI721_RIO_PW_RX_CAPT(3));
> > +
> > + /* Queue PW message (if there is room in FIFO),
> > + * otherwise discard it.
> > + */
> > + spin_lock(&priv->pw_fifo_lock);
> > + if (kfifo_avail(&priv->pw_fifo) >=3D
TSI721_RIO_PW_MSG_SIZE)
> > + kfifo_in(&priv->pw_fifo, pw_buf,
> > + TSI721_RIO_PW_MSG_SIZE);
> > + else
> > + priv->pw_discard_count++;
> > + spin_unlock(&priv->pw_fifo_lock);
> > + }
> > +
> > + /* Clear pending PW interrupts */
> > + iowrite32(TSI721_RIO_PW_RX_STAT_PW_DISC |
TSI721_RIO_PW_RX_STAT_PW_VAL,
> > + priv->regs + TSI721_RIO_PW_RX_STAT);
> > +
> > + schedule_work(&priv->pw_work);
>=20
> I see scheduled work being done, but no flush_scheduled_work() or
> similar. This is often a bug, leading to code being executed after
> device shutdown or even after rmmod.
Possibly my oversight. I will check if/where flush is needed.
=20
> > + return 0;
> > +}
> > +
> > +static void tsi721_pw_dpc(struct work_struct *work)
> > +{
> > + struct tsi721_device *priv =3D container_of(work, struct
tsi721_device,
> > + pw_work);
> > + unsigned long flags;
> > + u32 msg_buffer[RIO_PW_MSG_SIZE/sizeof(u32)]; /* Use full size PW
message
> > + buffer for RIO
layer */
> > +
> > + /*
> > + * Process port-write messages
> > + */
> > + spin_lock_irqsave(&priv->pw_fifo_lock, flags);
> > + while (kfifo_out(&priv->pw_fifo, (unsigned char *)msg_buffer,
> > + TSI721_RIO_PW_MSG_SIZE)) {
> > + /* Process one message */
> > + spin_unlock_irqrestore(&priv->pw_fifo_lock, flags);
> > +#ifdef DEBUG_PW
> > + {
> > + u32 i;
> > + pr_debug("%s : Port-Write Message:", __func__);
> > + for (i =3D 0; i < RIO_PW_MSG_SIZE/sizeof(u32); ) {
> > + pr_debug("0x%02x: %08x %08x %08x %08x", i*4,
> > + msg_buffer[i], msg_buffer[i + 1],
> > + msg_buffer[i + 2], msg_buffer[i + 3]);
> > + i +=3D 4;
> > + }
> > + pr_debug("\n");
> > + }
> > +#endif
> > + /* Pass the port-write message to RIO core for
processing */
> > + rio_inb_pwrite_handler((union rio_pw_msg *)msg_buffer);
> > + spin_lock_irqsave(&priv->pw_fifo_lock, flags);
> > + }
> > + spin_unlock_irqrestore(&priv->pw_fifo_lock, flags);
> > +}
>=20
> The lock handling in this function is pretty ugly-looking. Is it
> correct?
Ugly for sure. I am trying to protect message FIFO and not to lock it
during=20
execution of rio_inb_pwrite_handler() because it may take relatively
long time.
Inbound port-write controller does not have any HW queue to store PW
messages
and my goal is to get them from device ASAP and to place into the FIFO.
I will redo this function to make locking to look better. =20
=20
> >
> > ...
> >
> > +static void tsi721_db_dpc(struct work_struct *work)
> > +{
> > + struct tsi721_device *priv =3D container_of(work, struct
tsi721_device,
> > + idb_work);
> > + struct rio_mport *mport;
> > + struct rio_dbell *dbell;
> > + int found =3D 0;
> > + u32 wr_ptr, rd_ptr;
> > + u64 *idb_entry;
> > + u32 regval;
> > + union {
> > + u64 msg;
> > + u8 bytes[8];
> > + } idb;
> > +
> > + /*
> > + * Process queued inbound doorbells
> > + */
> > + mport =3D priv->mport;
> > +
> > + wr_ptr =3D ioread32(priv->regs + TSI721_IDQ_WP(IDB_QUEUE));
> > + rd_ptr =3D ioread32(priv->regs + TSI721_IDQ_RP(IDB_QUEUE));
> > +
> > + while (wr_ptr !=3D rd_ptr) {
> > + idb_entry =3D (u64 *)(priv->idb_base +
> > + (TSI721_IDB_ENTRY_SIZE *
rd_ptr));
> > + rd_ptr++;
> > + idb.msg =3D *idb_entry;
>=20
> Is this code correct on both little-endian and big-endian hardware?
Yes. It works on both. Tested on x86 and powerpc.
=20
> > + *idb_entry =3D 0;
> > +
> > + /* Process one doorbell */
> > + list_for_each_entry(dbell, &mport->dbells, node) {
> > + if ((dbell->res->start <=3D DBELL_INF(idb.bytes))
&&
> > + (dbell->res->end >=3D DBELL_INF(idb.bytes))) {
> > ...
> >
> > +static void tsi721_interrupts_init(struct tsi721_device *priv)
> > +{
> > + u32 intr;
> > +
> > + /* Enable IDB interrupts */
> > + iowrite32(TSI721_SR_CHINT_ALL,
> > + priv->regs + TSI721_SR_CHINT(IDB_QUEUE));
> > + iowrite32(TSI721_SR_CHINT_IDBQRCV,
> > + priv->regs + TSI721_SR_CHINTE(IDB_QUEUE));
> > + iowrite32(TSI721_INT_SR2PC_CHAN(IDB_QUEUE),
> > + priv->regs + TSI721_DEV_CHAN_INTE);
> > +
> > + /* Enable SRIO MAC interrupts */
> > + iowrite32(TSI721_RIO_EM_DEV_INT_EN_INT,
> > + priv->regs + TSI721_RIO_EM_DEV_INT_EN);
> > +
> > + if (priv->flags & TSI721_USING_MSIX)
> > + intr =3D TSI721_DEV_INT_SRIO;
> > + else
> > + intr =3D TSI721_DEV_INT_SR2PC_CH | TSI721_DEV_INT_SRIO |
> > + TSI721_DEV_INT_SMSG_CH;
> > +
> > + iowrite32(intr, priv->regs + TSI721_DEV_INTE);
> > + (void)ioread32(priv->regs + TSI721_DEV_INTE);
>=20
> Why include all of these void casts, btw?
Old habit. Used to have compiler warnings in some situations.
Not applicable to this case though. Will clean-up.
> > +}
> > +
> > +/**
> > + * tsi721_request_msix - register interrupt service for MSI-X mode.
> > + * @mport: RapidIO master port structure
> > + *
> > + * Registers MSI-X interrupt service routines for interrupts that
are active
> > + * immediately after mport initialization. Messaging interrupt
service routines
> > + * should be registered during corresponding open requests.
> > + */
> > +static int tsi721_request_msix(struct rio_mport *mport)
> > +{
> > + struct tsi721_device *priv =3D mport->priv;
> > + int err =3D 0;
> > +
> > + err =3D request_irq(priv->msix[TSI721_VECT_IDB].vector,
> > + tsi721_sr2pc_ch_msix, 0,
> > + priv->msix[TSI721_VECT_IDB].irq_name, (void
*)mport);
> > + if (err)
> > + goto out;
> > +
> > + err =3D request_irq(priv->msix[TSI721_VECT_PWRX].vector,
> > + tsi721_srio_msix, 0,
> > + priv->msix[TSI721_VECT_PWRX].irq_name, (void
> *)mport);
>=20
> Did we leak the first IRQ here?
Yes we did. Will fix it here and in one more place.
>=20
> > +out:
> > + return err;
> > +}
> > +
> >
> > ...
> >
> > +static int tsi721_enable_msix(struct tsi721_device *priv)
> > +{
> > + struct msix_entry entries[TSI721_VECT_MAX];
> > + int err;
> > + int i;
> > +
> > + entries[TSI721_VECT_IDB].entry =3D
TSI721_MSIX_SR2PC_IDBQ_RCV(IDB_QUEUE);
> > + entries[TSI721_VECT_PWRX].entry =3D TSI721_MSIX_SRIO_MAC_INT;
> > +
> > + /*
> > + * Initialize MSI-X entries for Messaging Engine:
> > + * this driver supports four RIO mailboxes (inbound and
outbound)
> > + * NOTE: Inbound message MBOX 0...4 use IB channels 4...7.
Therefore
> > + * offset +4 is added to IB MBOX number.
> > + */
> > + for (i =3D 0; i < RIO_MAX_MBOX; i++) {
> > + entries[TSI721_VECT_IMB0_RCV + i].entry =3D
> > + TSI721_MSIX_IMSG_DQ_RCV(i + 4);
> > + entries[TSI721_VECT_IMB0_INT + i].entry =3D
> > + TSI721_MSIX_IMSG_INT(i + 4);
> > + entries[TSI721_VECT_OMB0_DONE + i].entry =3D
> > + TSI721_MSIX_OMSG_DONE(i);
> > + entries[TSI721_VECT_OMB0_INT + i].entry =3D
> > + TSI721_MSIX_OMSG_INT(i);
> > + }
> > +
> > + err =3D pci_enable_msix(priv->pdev, entries, ARRAY_SIZE(entries));
> > + if (err) {
> > + if (err > 0)
> > + dev_info(&priv->pdev->dev,
> > + "Only %d MSI-X vectors available, "
> > + "not using MSI-X\n", err);
> > + return err;
> > + }
> > +
> > + /*
> > + * Copy MSI-X vector information into tsi721 private structure
> > + */
> > + priv->msix[TSI721_VECT_IDB].vector =3D
entries[TSI721_VECT_IDB].vector;
> > + snprintf(priv->msix[TSI721_VECT_IDB].irq_name,
IRQ_DEVICE_NAME_MAX,
> > + DRV_NAME "-idb@pci:%s", pci_name(priv->pdev));
> > + priv->msix[TSI721_VECT_PWRX].vector =3D
entries[TSI721_VECT_PWRX].vector;
> > + snprintf(priv->msix[TSI721_VECT_PWRX].irq_name,
IRQ_DEVICE_NAME_MAX,
> > + DRV_NAME "-pwrx@pci:%s", pci_name(priv->pdev));
> > +
> > + for (i =3D 0; i < RIO_MAX_MBOX; i++) {
> > + priv->msix[TSI721_VECT_IMB0_RCV + i].vector =3D
> > + entries[TSI721_VECT_IMB0_RCV +
i].vector;
> > + snprintf(priv->msix[TSI721_VECT_IMB0_RCV + i].irq_name,
> > + IRQ_DEVICE_NAME_MAX, DRV_NAME "-imbr%d@pci:%s",
> > + i, pci_name(priv->pdev));
> > +
> > + priv->msix[TSI721_VECT_IMB0_INT + i].vector =3D
> > + entries[TSI721_VECT_IMB0_INT +
i].vector;
> > + snprintf(priv->msix[TSI721_VECT_IMB0_INT + i].irq_name,
> > + IRQ_DEVICE_NAME_MAX, DRV_NAME "-imbi%d@pci:%s",
> > + i, pci_name(priv->pdev));
> > +
> > + priv->msix[TSI721_VECT_OMB0_DONE + i].vector =3D
> > + entries[TSI721_VECT_OMB0_DONE +
i].vector;
> > + snprintf(priv->msix[TSI721_VECT_OMB0_DONE + i].irq_name,
> > + IRQ_DEVICE_NAME_MAX, DRV_NAME "-ombd%d@pci:%s",
> > + i, pci_name(priv->pdev));
> > +
> > + priv->msix[TSI721_VECT_OMB0_INT + i].vector =3D
> > + entries[TSI721_VECT_OMB0_INT +
i].vector;
> > + snprintf(priv->msix[TSI721_VECT_OMB0_INT + i].irq_name,
> > + IRQ_DEVICE_NAME_MAX, DRV_NAME "-ombi%d@pci:%s",
> > + i, pci_name(priv->pdev));
> > + }
>=20
> Did we need a dependency on CONFIG_PCI_MSI?
To reduce a driver footprint yes, but it will not help if
system implements regular MSI only. This may be better handled by using
device specific config option depending on CONFIG_PCI_MSI. This way I
will be able
to remove MSI-X code while keeping MSI function. Marking as TODO.
If code size is not a concern, pci_enable_msix() has dependency on
CONFIG_PCI_MSI
and will fail if MSI support is not enabled.
>=20
> > + return 0;
> > +}
> > +
> >
> > ...
> >
> > +static int tsi721_bdma_ch_init(struct tsi721_device *priv, int
chnum)
> > +{
> > + struct tsi721_dma_desc *bd_ptr;
> > + u64 *sts_ptr;
> > + dma_addr_t bd_phys, sts_phys;
> > + int sts_size;
> > + int bd_num =3D priv->bdma[chnum].bd_num;
> > +
> > + dev_dbg(&priv->pdev->dev, "Init Block DMA Engine, CH%d\n",
chnum);
> > +
> > + /*
> > + * Initialize DMA channel for maintenance requests
> > + */
> > +
> > + /* Allocate space for DMA descriptors */
> > + bd_ptr =3D dma_alloc_coherent(&priv->pdev->dev,
> > + bd_num * sizeof(struct
tsi721_dma_desc),
> > + &bd_phys, GFP_KERNEL);
> > + if (!bd_ptr)
> > + return -ENOMEM;
> > +
> > + priv->bdma[chnum].bd_phys =3D bd_phys;
> > + priv->bdma[chnum].bd_base =3D bd_ptr;
> > +
> > + memset(bd_ptr, 0, bd_num * sizeof(struct tsi721_dma_desc));
>=20
> There it is again. Perhaps we need a dma_zalloc_coherent().
It will be nice match to kzalloc().
=20
> > + dev_dbg(&priv->pdev->dev, "DMA descriptors @ %p (phys =3D
%llx)\n",
> > + bd_ptr, (unsigned long long)bd_phys);
> > +
> > + /* Allocate space for descriptor status FIFO */
> > + sts_size =3D (bd_num >=3D TSI721_DMA_MINSTSSZ) ?
> > + bd_num : TSI721_DMA_MINSTSSZ;
> > + sts_size =3D roundup_pow_of_two(sts_size);
> > + sts_ptr =3D dma_alloc_coherent(&priv->pdev->dev,
> > + sts_size * sizeof(struct
tsi721_dma_sts),
> > + &sts_phys, GFP_KERNEL);
> > + if (!sts_ptr) {
> > + /* Free space allocated for DMA descriptors */
> > + dma_free_coherent(&priv->pdev->dev,
> > + bd_num * sizeof(struct
tsi721_dma_desc),
> > + bd_ptr, bd_phys);
> > + priv->bdma[chnum].bd_base =3D NULL;
> > + return -ENOMEM;
> > + }
> > +
> > + priv->bdma[chnum].sts_phys =3D sts_phys;
> > + priv->bdma[chnum].sts_base =3D sts_ptr;
> > + priv->bdma[chnum].sts_size =3D sts_size;
> > +
> > + memset(sts_ptr, 0, sts_size);
>=20
> and again.
This memset() may be safely removed. I will review all similar cases.
=20
> >
> > ...
> >
> > +struct tsi721_dma_desc {
> > + __le32 type_id;
> > +
...
> > +
> > + union {
> > + struct { /* if DTYPE =3D=3D 1 */
> > + __le32 bufptr_lo;
> > + __le32 bufptr_hi;
> > + __le32 s_dist;
> > + __le32 s_size;
> > + } t1;
> > + __le32 data[4]; /* if DTYPE =3D=3D 2 */
> > + u32 reserved[4]; /* if DTYPE =3D=3D 3 */
> > + };
> > +} __attribute__((aligned(32)));
>=20
> We have the __aligned helper for this. (more below)
No excuse to ignore it. Will update.
=20
> >
> > ...
> >
>=20
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev@lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/linuxppc-dev
^ permalink raw reply
* Re: [PATCH] mtd-utils: fix corrupt cleanmarker with flash_erase -j command
From: Brian Norris @ 2011-08-18 1:20 UTC (permalink / raw)
To: dedekind1; +Cc: LiuShuo, linuxppc-dev, linuxppc-dev, linux-mtd, dwmw2
In-Reply-To: <1313566762.19563.3.camel@sauron>
On Wed, Aug 17, 2011 at 12:39 AM, Artem Bityutskiy <dedekind1@gmail.com> wrote:
> I think the OOB mode should not be a global MTD device state. Each
> ioctl invocation should just specify the mode.
I agree. This brings up some questions, though. See below.
> Brian's idea of having a completely new ioctl or a set of new ioctls for
> OOB which would copletely deprecate the old ones is a good idea. Let's
> wait for his patch.
I sent a patch series (RFC) to the MTD mailing list. You can see the
cover description, which describes my proposed changes and asks some
questions, at the following link, but for some reason the patches are
being held up by the mailing list software - for now, you'll only
receive them if you were CC'd directly:
http://lists.infradead.org/pipermail/linux-mtd/2011-August/037522.html
Follow that thread for more information.
> May be we should even start physically removing depricated ioctls by
> first adding a printk with a warning and then removing completely. But
> first mtdutils should be updated to not use them.
Yes, this sounds fine, although I'm not too familiar with the
MTD_OOB_AUTO stuff, so I'm not sure how well it will replace all the
uses of MEMGETOOBSEL. I don't actually see any users of ECCGETLAYOUT;
I think I've asked about this ioctl before, but I can't seem to find
any response...perhaps it can be killed with no work?
Brian
^ permalink raw reply
* [PATCH v3] mtd/nand : workaround for Freescale FCM to support large-page Nand chip
From: b35362 @ 2011-08-18 2:33 UTC (permalink / raw)
To: dwmw2; +Cc: Liu Shuo, linuxppc-dev, linux-mtd
From: Liu Shuo <b35362@freescale.com>
Freescale FCM controller has a 2K size limitation of buffer RAM. In order
to support the Nand flash chip whose page size is larger than 2K bytes,
we divide a page into multi-2K pages for MTD layer driver. In that case,
we force to set the page size to 2K bytes. We convert the page address of
MTD layer driver to a real page address in flash chips and a column index
in fsl_elbc driver. We can issue any column address by UA instruction of
elbc controller.
NOTE: Due to there is a limitation of 'Number of Partial Program Cycles in
the Same Page (NOP)', the flash chip which is supported by this workaround
have to meet below conditions.
1. page size is not greater than 4KB
2. 1) if main area and spare area have independent NOPs:
main area NOP : >=3
spare area NOP : >=2
2) if main area and spare area have a common NOP:
NOP : >=4
Signed-off-by: Liu Shuo <b35362@freescale.com>
Signed-off-by: Li Yang <leoli@freescale.com>
---
drivers/mtd/nand/fsl_elbc_nand.c | 66 ++++++++++++++++++++++++++++++-------
1 files changed, 53 insertions(+), 13 deletions(-)
diff --git a/drivers/mtd/nand/fsl_elbc_nand.c b/drivers/mtd/nand/fsl_elbc_nand.c
index a212116..884a9f1 100644
--- a/drivers/mtd/nand/fsl_elbc_nand.c
+++ b/drivers/mtd/nand/fsl_elbc_nand.c
@@ -76,6 +76,13 @@ struct fsl_elbc_fcm_ctrl {
unsigned int oob; /* Non zero if operating on OOB data */
unsigned int counter; /* counter for the initializations */
char *oob_poi; /* Place to write ECC after read back */
+
+ /*
+ * If writesize > 2048, these two members are used to calculate
+ * the real page address and real column address.
+ */
+ int subpage_shift;
+ int subpage_mask;
};
/* These map to the positions used by the FCM hardware ECC generator */
@@ -164,18 +171,27 @@ static void set_addr(struct mtd_info *mtd, int column, int page_addr, int oob)
struct fsl_lbc_regs __iomem *lbc = ctrl->regs;
struct fsl_elbc_fcm_ctrl *elbc_fcm_ctrl = ctrl->nand;
int buf_num;
+ u32 real_ca = column;
- elbc_fcm_ctrl->page = page_addr;
+ if (priv->page_size && elbc_fcm_ctrl->subpage_shift) {
+ real_ca = (page_addr & elbc_fcm_ctrl->subpage_mask) * 2112;
+ page_addr >>= elbc_fcm_ctrl->subpage_shift;
+ }
- out_be32(&lbc->fbar,
- page_addr >> (chip->phys_erase_shift - chip->page_shift));
+ elbc_fcm_ctrl->page = page_addr;
if (priv->page_size) {
+ real_ca += (oob ? 2048 : 0);
+ elbc_fcm_ctrl->use_mdr = 1;
+ elbc_fcm_ctrl->mdr = real_ca;
+
+ out_be32(&lbc->fbar, page_addr >> 6);
out_be32(&lbc->fpar,
((page_addr << FPAR_LP_PI_SHIFT) & FPAR_LP_PI) |
(oob ? FPAR_LP_MS : 0) | column);
buf_num = (page_addr & 1) << 2;
} else {
+ out_be32(&lbc->fbar, page_addr >> 5);
out_be32(&lbc->fpar,
((page_addr << FPAR_SP_PI_SHIFT) & FPAR_SP_PI) |
(oob ? FPAR_SP_MS : 0) | column);
@@ -256,10 +272,11 @@ static void fsl_elbc_do_read(struct nand_chip *chip, int oob)
if (priv->page_size) {
out_be32(&lbc->fir,
(FIR_OP_CM0 << FIR_OP0_SHIFT) |
- (FIR_OP_CA << FIR_OP1_SHIFT) |
- (FIR_OP_PA << FIR_OP2_SHIFT) |
- (FIR_OP_CM1 << FIR_OP3_SHIFT) |
- (FIR_OP_RBW << FIR_OP4_SHIFT));
+ (FIR_OP_UA << FIR_OP1_SHIFT) |
+ (FIR_OP_UA << FIR_OP2_SHIFT) |
+ (FIR_OP_PA << FIR_OP3_SHIFT) |
+ (FIR_OP_CM1 << FIR_OP4_SHIFT) |
+ (FIR_OP_RBW << FIR_OP5_SHIFT));
out_be32(&lbc->fcr, (NAND_CMD_READ0 << FCR_CMD0_SHIFT) |
(NAND_CMD_READSTART << FCR_CMD1_SHIFT));
@@ -399,12 +416,13 @@ static void fsl_elbc_cmdfunc(struct mtd_info *mtd, unsigned int command,
if (priv->page_size) {
out_be32(&lbc->fir,
(FIR_OP_CM2 << FIR_OP0_SHIFT) |
- (FIR_OP_CA << FIR_OP1_SHIFT) |
- (FIR_OP_PA << FIR_OP2_SHIFT) |
- (FIR_OP_WB << FIR_OP3_SHIFT) |
- (FIR_OP_CM3 << FIR_OP4_SHIFT) |
- (FIR_OP_CW1 << FIR_OP5_SHIFT) |
- (FIR_OP_RS << FIR_OP6_SHIFT));
+ (FIR_OP_UA << FIR_OP1_SHIFT) |
+ (FIR_OP_UA << FIR_OP2_SHIFT) |
+ (FIR_OP_PA << FIR_OP3_SHIFT) |
+ (FIR_OP_WB << FIR_OP4_SHIFT) |
+ (FIR_OP_CM3 << FIR_OP5_SHIFT) |
+ (FIR_OP_CW1 << FIR_OP6_SHIFT) |
+ (FIR_OP_RS << FIR_OP7_SHIFT));
} else {
out_be32(&lbc->fir,
(FIR_OP_CM0 << FIR_OP0_SHIFT) |
@@ -453,6 +471,9 @@ static void fsl_elbc_cmdfunc(struct mtd_info *mtd, unsigned int command,
full_page = 1;
}
+ if (priv->page_size)
+ elbc_fcm_ctrl->use_mdr = 1;
+
fsl_elbc_run_command(mtd);
/* Read back the page in order to fill in the ECC for the
@@ -654,9 +675,28 @@ static int fsl_elbc_chip_init_tail(struct mtd_info *mtd)
struct nand_chip *chip = mtd->priv;
struct fsl_elbc_mtd *priv = chip->priv;
struct fsl_lbc_ctrl *ctrl = priv->ctrl;
+ struct fsl_elbc_fcm_ctrl *elbc_fcm_ctrl = ctrl->nand;
struct fsl_lbc_regs __iomem *lbc = ctrl->regs;
unsigned int al;
+ /*
+ * Hack for supporting the flash chip whose writesize is
+ * larger than 2K bytes.
+ */
+ if (mtd->writesize > 2048) {
+ elbc_fcm_ctrl->subpage_shift = ffs(mtd->writesize >> 11) - 1;
+ elbc_fcm_ctrl->subpage_mask =
+ (1 << elbc_fcm_ctrl->subpage_shift) - 1;
+ /*
+ * Rewrite mtd->writesize, mtd->oobsize, chip->page_shift
+ * and chip->pagemask.
+ */
+ mtd->writesize = 2048;
+ mtd->oobsize = 64;
+ chip->page_shift = ffs(mtd->writesize) - 1;
+ chip->pagemask = (chip->chipsize >> chip->page_shift) - 1;
+ }
+
/* calculate FMR Address Length field */
al = 0;
if (chip->pagemask & 0xffff0000)
--
1.7.1
^ permalink raw reply related
* Re: [PATCH v13 0/6] flexcan: Add support for powerpc flexcan (freescale p1010)
From: David Miller @ 2011-08-18 3:36 UTC (permalink / raw)
To: holt; +Cc: netdev, B22300, socketcan-core, linuxppc-dev
In-Reply-To: <1313551944-28603-1-git-send-email-holt@sgi.com>
From: Robin Holt <holt@sgi.com>
Date: Tue, 16 Aug 2011 22:32:18 -0500
> The following set of patches have been reviewed by the above parties and
> all comments have been integrated. Although the patches stray from the
> drivers/net/can directory, the diversions are related to changes for
> the flexcan driver.
>
> The patch set is based upon your net-next-2.6 tree's commit 6c37e46.
>
> Could you please queue these up for the next appropriate push to Linus'
> tree?
Applied to net-next, thanks!
^ permalink raw reply
* build failure with gcc 4.6.0 "array subscript is above array bounds"
From: Ian Campbell @ 2011-08-18 8:27 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Paul Mackerras
I noticed this with a defconfig build:
CC arch/powerpc/kernel/ptrace.o
arch/powerpc/kernel/ptrace.c: In function 'arch_ptrace':
arch/powerpc/kernel/ptrace.c:1502:5: error: array subscript is above array bounds [-Werror=array-bounds]
arch/powerpc/kernel/ptrace.c:1530:5: error: array subscript is above array bounds [-Werror=array-bounds]
That corresponds to:
tmp = ((unsigned long *)child->thread.fpr)
[TS_FPRWIDTH * (index - PT_FPR0)];
child->thread.fpr is "double fpr[32][TS_FPRWIDTH]".
index has already been bounds checked so we know it is <= PT_FPSCR.
I tried to fix but I don't really know enough about PPC to figure out
the correct fix is. PT_FPSCR is "PT_FPR0 + 32" on ppc64, which seems
consistent with the fpr definition.
On ppc32 PT_FPSCR is "PT_FPR0 + 2*32 + 1", I tried replacing the 32 with
"PT_FPSCR - PT_FPR0" (+ 1) but that got me into the BUILD_BUG_ONs at
line 346 and 374. At this point I'm afraid gave up trying to fix things,
I hope the report is useful anyway...
Ian.
^ permalink raw reply
* RE: build failure with gcc 4.6.0 "array subscript is above array bounds"
From: David Laight @ 2011-08-18 8:58 UTC (permalink / raw)
To: Ian Campbell, linuxppc-dev; +Cc: Paul Mackerras
In-Reply-To: <1313656032.5010.247.camel@zakaz.uk.xensource.com>
=20
> Subject: build failure with gcc 4.6.0 "array subscript is=20
> above array bounds"
...
> That corresponds to:
> tmp =3D ((unsigned long *)child->thread.fpr)
> [TS_FPRWIDTH * (index - PT_FPR0)];
>=20
> child->thread.fpr is "double fpr[32][TS_FPRWIDTH]".
>=20
> index has already been bounds checked so we know it is <=3D PT_FPSCR.
That code looks gross....
I think it is trying to index a 2D array with a single index
and type-pun the lookup.
I'm not sure how the array size (for the subscript error)
is determined in the presence of the cast, but without
the cast the index would have to be less than 32.
I also suspect this is failing when gcc inlines the function
from a call where 'index' is a constant.
Possibly the code should read:
tmp =3D (unsigned long *)child->thread.fpr[index - PT_FPRO];
although index may have been scaled by 'sizeof double/sizeof long'.
David
^ permalink raw reply
* Re: build failure with gcc 4.6.0 "array subscript is above array bounds"
From: Andreas Schwab @ 2011-08-18 9:31 UTC (permalink / raw)
To: Ian Campbell; +Cc: Paul Mackerras, linuxppc-dev
In-Reply-To: <1313656032.5010.247.camel@zakaz.uk.xensource.com>
Ian Campbell <Ian.Campbell@citrix.com> writes:
> I noticed this with a defconfig build:
> CC arch/powerpc/kernel/ptrace.o
> arch/powerpc/kernel/ptrace.c: In function 'arch_ptrace':
> arch/powerpc/kernel/ptrace.c:1502:5: error: array subscript is above array bounds [-Werror=array-bounds]
> arch/powerpc/kernel/ptrace.c:1530:5: error: array subscript is above array bounds [-Werror=array-bounds]
>
> That corresponds to:
> tmp = ((unsigned long *)child->thread.fpr)
> [TS_FPRWIDTH * (index - PT_FPR0)];
>
> child->thread.fpr is "double fpr[32][TS_FPRWIDTH]".
>
> index has already been bounds checked so we know it is <= PT_FPSCR.
>
> I tried to fix but I don't really know enough about PPC to figure out
> the correct fix is. PT_FPSCR is "PT_FPR0 + 32" on ppc64, which seems
> consistent with the fpr definition.
Perhaps there should be a union that overlays fpr with an array of
longs.
> On ppc32 PT_FPSCR is "PT_FPR0 + 2*32 + 1", I tried replacing the 32 with
> "PT_FPSCR - PT_FPR0" (+ 1) but that got me into the BUILD_BUG_ONs at
> line 346 and 374. At this point I'm afraid gave up trying to fix things,
> I hope the report is useful anyway...
On ppc32 a single ptrace call can only read/write half of an fpr, so
each fpr occupies two slots.
Andreas.
--
Andreas Schwab, schwab@redhat.com
GPG Key fingerprint = D4E8 DBE3 3813 BB5D FA84 5EC7 45C6 250E 6F00 984E
"And now for something completely different."
^ permalink raw reply
* Re: [PATCH v3] mtd/nand : workaround for Freescale FCM to support large-page Nand chip
From: Scott Wood @ 2011-08-18 16:25 UTC (permalink / raw)
To: b35362; +Cc: linuxppc-dev, dwmw2, linux-mtd
In-Reply-To: <1313634783-8855-1-git-send-email-b35362@freescale.com>
On 08/17/2011 09:33 PM, b35362@freescale.com wrote:
> From: Liu Shuo <b35362@freescale.com>
>
> Freescale FCM controller has a 2K size limitation of buffer RAM. In order
> to support the Nand flash chip whose page size is larger than 2K bytes,
> we divide a page into multi-2K pages for MTD layer driver. In that case,
> we force to set the page size to 2K bytes. We convert the page address of
> MTD layer driver to a real page address in flash chips and a column index
> in fsl_elbc driver. We can issue any column address by UA instruction of
> elbc controller.
>
> NOTE: Due to there is a limitation of 'Number of Partial Program Cycles in
> the Same Page (NOP)', the flash chip which is supported by this workaround
> have to meet below conditions.
> 1. page size is not greater than 4KB
> 2. 1) if main area and spare area have independent NOPs:
> main area NOP : >=3
> spare area NOP : >=2?
How often are the NOPs split like this?
> 2) if main area and spare area have a common NOP:
> NOP : >=4
This depends on how the flash is used. If you treat it as a NOP1 flash
(e.g. run ubifs rather than jffs2), then you need NOP2 for a 4K chip and
NOP4 for an 8K chip. OTOH, if you would be making full use of NOP4 on a
real 2K chip, you'll need NOP8 for a 4K chip.
The NOP restrictions should be documented in the code itself, not just
in the git changelog. Maybe print it to the console when this hack is
used, along with the NOP value read from the ID. If it's less than 4
for 4K or 8 for 8K, also print a message saying not to use jffs2 (does
yaffs2 do similar things?). If it's less than 2 for 4K or 4 for 8K, the
probe should fail.
-Scott
^ permalink raw reply
* Re: [PATCH v3] mtd/nand : workaround for Freescale FCM to support large-page Nand chip
From: Matthieu CASTET @ 2011-08-18 17:00 UTC (permalink / raw)
To: b35362@freescale.com
Cc: linuxppc-dev@ozlabs.org, dwmw2@infradead.org,
linux-mtd@lists.infradead.org
In-Reply-To: <1313634783-8855-1-git-send-email-b35362@freescale.com>
b35362@freescale.com a écrit :
> From: Liu Shuo <b35362@freescale.com>
>
> Freescale FCM controller has a 2K size limitation of buffer RAM. In order
> to support the Nand flash chip whose page size is larger than 2K bytes,
> we divide a page into multi-2K pages for MTD layer driver. In that case,
> we force to set the page size to 2K bytes. We convert the page address of
> MTD layer driver to a real page address in flash chips and a column index
> in fsl_elbc driver. We can issue any column address by UA instruction of
> elbc controller.
>
Why do you need to do that ?
When mtd send you a 4k page, why can't you write it by 2*2k pages write ?
Even better send the first 2K and then if your controller allow it send the
remaining 2K without command/address phase.
Matthieu
^ permalink raw reply
* [PATCH] powerpc/85xx: remove left-over printks in p1022_ds.c
From: Timur Tabi @ 2011-08-18 18:12 UTC (permalink / raw)
To: kumar.gala, linuxppc-dev
Two debugging prinkts were accidentally included in the last patch to
arch/powerpc/platforms/85xx/p1022_ds.c.
Signed-off-by: Timur Tabi <timur@freescale.com>
---
arch/powerpc/platforms/85xx/p1022_ds.c | 2 --
1 files changed, 0 insertions(+), 2 deletions(-)
diff --git a/arch/powerpc/platforms/85xx/p1022_ds.c b/arch/powerpc/platforms/85xx/p1022_ds.c
index a13d3cc..9d5dd8c 100644
--- a/arch/powerpc/platforms/85xx/p1022_ds.c
+++ b/arch/powerpc/platforms/85xx/p1022_ds.c
@@ -147,13 +147,11 @@ static void p1022ds_set_monitor_port(enum fsl_diu_monitor_port port)
switch (port) {
case FSL_DIU_PORT_DVI:
- printk(KERN_INFO "%s:%u\n", __func__, __LINE__);
/* Enable the DVI port, disable the DFP and the backlight */
clrsetbits_8(brdcfg1, PX_BRDCFG1_DFPEN | PX_BRDCFG1_BACKLIGHT,
PX_BRDCFG1_DVIEN);
break;
case FSL_DIU_PORT_LVDS:
- printk(KERN_INFO "%s:%u\n", __func__, __LINE__);
/* Enable the DFP port, disable the DVI and the backlight */
clrsetbits_8(brdcfg1, PX_BRDCFG1_DVIEN | PX_BRDCFG1_BACKLIGHT,
PX_BRDCFG1_DFPEN);
--
1.7.4.4
^ permalink raw reply related
* Re: [PATCH v3] mtd/nand : workaround for Freescale FCM to support large-page Nand chip
From: Scott Wood @ 2011-08-18 18:24 UTC (permalink / raw)
To: Matthieu CASTET
Cc: linuxppc-dev@ozlabs.org, b35362@freescale.com,
dwmw2@infradead.org, linux-mtd@lists.infradead.org
In-Reply-To: <4E4D452C.7050805@parrot.com>
On 08/18/2011 12:00 PM, Matthieu CASTET wrote:
> b35362@freescale.com a =E9crit :
>> From: Liu Shuo <b35362@freescale.com>
>>
>> Freescale FCM controller has a 2K size limitation of buffer RAM. In or=
der
>> to support the Nand flash chip whose page size is larger than 2K bytes=
,
>> we divide a page into multi-2K pages for MTD layer driver. In that cas=
e,
>> we force to set the page size to 2K bytes. We convert the page address=
of
>> MTD layer driver to a real page address in flash chips and a column in=
dex
>> in fsl_elbc driver. We can issue any column address by UA instruction =
of
>> elbc controller.
>>
> Why do you need to do that ?
>=20
> When mtd send you a 4k page, why can't you write it by 2*2k pages write=
?
That would be more complicated given the statefulness of the interface,
for no real benefit.
> Even better send the first 2K and then if your controller allow it send=
the
> remaining 2K without command/address phase.
IIRC Shuo tried this first and couldn't make it work.
-Scott
^ 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