* Re: [net-next-2.6 PATCH v2] can: SJA1000: generic OF platform bus driver
From: Wolfgang Grandegger @ 2009-05-23 16:44 UTC (permalink / raw)
To: Grant Likely; +Cc: Linux Netdev List, devicetree-discuss, linuxppc-dev
In-Reply-To: <4A1797C5.1040907@grandegger.com>
Wolfgang Grandegger wrote:
> Hi Grant,
>
> Grant Likely wrote:
>> Hi Wolfgang, thanks for the quick response. Comments below...
>>
>> On Fri, May 22, 2009 at 8:46 AM, Wolfgang Grandegger <wg@grandegger.com> wrote:
>>> +++ net-next-2.6/Documentation/powerpc/dts-bindings/can/sja1000.txt
>>> @@ -0,0 +1,37 @@
>>> +Memory mapped SJA1000 CAN controller from NXP (formerly Philips)
>>> +
>>> +Required properties:
>>> +
>>> +- compatible : should be "nxp,sja1000".
>>> +- reg : should specify the chip select, address offset and size used
>>> + for the chip depending on the bus it is connected to.
>>> +- interrupts: property with a value describing the interrupt source
>>> + (number and sensitivity) for that device. The encoding depends
>>> + on the type of interrupt controller used.
>> Hmmm, "reg", "interrupts", and "interrupt-parent" are well understood
>> properties. I don't think we need to keep boilerplate defining the
>> meaning every time a new binding is added. (general musing; not an
>> ack or nack of this patch)
>
> OK.
>
>> However, what should be defined is *what* the register range is (ie.
>> one tuple; location of device registers), and what the interrupts are
>> (ie. single tuple for device's irq line). Granted this is a trivial
>> case, but in the case of devices with more than one address range or
>> irq line, the meaning of each tuple is critical information. I think
>> it would be a good pattern to establish.
>
> Sounds reasonable.
>
>>> +Optional properties:
>>> +
>>> +- interrupt-parent : the phandle for the interrupt controller that
>>> + services interrupts for that device.
>> Thinking further; I wouldn't even mention "interrupt-parent" here.
>> Anyone working with this stuff must already understand irq routing.
>
> OK, I will remove it.
>
>>> +- clock-frequency : CAN system clock frequency in Hz, which is normally
>>> + half of the oscillator clock frequency. If not specified, a
>>> + default value of 8000000 (8 MHz) is used.
>> A clock-frequency property typically refers to the bus clock
>> frequency. Something like can-frequency would be better.
>
> Ah, right, but I'm also not happy with "can-frequency". The manual
> speaks about the "internal clock", which is half of the external
> oscillator frequency. Maybe "internal-clock-frequency" might be better.
>
>>> +- cdr-reg : value of the SJA1000 clock divider register according to
>>> + the SJA1000 data sheet. If not specified, a default value of
>>> + 0x48 is used.
>> Ewh. The driver should be clueful enough to derive the clock divider
>> value given both the bus and can frequencies. I don't like this
>> property.
>
> The clock divider register controls the CLKOUT frequency for the
> microcontroller another CAN controller and allows to deactivate the
> CLKOUT pin. It's not used to configure the CAN bus frequency.
>
>>> +- ocr-reg : value of the SJA1000 output control register according to
>>> + the SJA1000 data sheet. If not specified, a default value of
>>> + 0x0a is used.
>> Ditto here; the binding should describe the usage mode; not the
>> register settings to get the usage mode. What sort of settings will
>> the .dts author be writing here?
>
> Unfortunately, there are many:
>
> clkout-frequency
> bypass-comperator
> tx1-output-on-rx-irq
>
> #define OCR_MODE_BIPHASE 0x00
> #define OCR_MODE_TEST 0x01
> #define OCR_MODE_NORMAL 0x02
> #define OCR_MODE_CLOCK 0x03
>
> #define OCR_TX0_INVERT 0x04
> #define OCR_TX0_PULLDOWN 0x08
> #define OCR_TX0_PULLUP 0x10
> #define OCR_TX0_PUSHPULL 0x18
> #define OCR_TX1_INVERT 0x20
> #define OCR_TX1_PULLDOWN 0x40
> #define OCR_TX1_PULLUP 0x80
> #define OCR_TX1_PUSHPULL 0xc0
>
> I think implementing properties for each option is overkill.
Would the following more descriptive properties be OK?
clock-out-frequency = <0>, // CLKOUT pin clock off
= <4000000>; // frequency on CLKOUT pin
bypass-input-comparator; // allows to bypass the CAN input comparator.
tx1-output-on-rx-irq; // allows the TX1 output to be used as a
// dedicated RX interrupt output.
output-control-mode = <0x0> // bi-phase output mode
<0x1> // test output mode
<0x2> // normal output mode (default)
<0x3> // clock output mode
output-pin-config = <0x01> // TX0 invert
<0x02> // TX0 pull-down
<0x04> // TX0 pull-up
<0x06> // TX0 push-pull
<0x08> // TX1 invert
<0x10> // TX1 pull-down
<0x20> // TX1 pull-up
<0x30> // TX1 push-pull
Wolfgang.
^ permalink raw reply
* Re: PPC405EX based irq flooding with USB-OTG and usbserial device
From: Hunter Cobbs @ 2009-05-23 13:44 UTC (permalink / raw)
To: linuxppc-dev
In-Reply-To: <ad84a70a0905230544m42bc2ce1o8c3d9a240f83fcc8@mail.gmail.com>
[-- Attachment #1: Type: text/plain, Size: 7040 bytes --]
OK, here are the patches... one for ppc4xx_dma.h and one for the Makefile
----------- ppc4xx_dma.h snip --------
--- linux-2.6-denx/drivers/usb/gadget/dwc_otg/ppc4xx_dma.h 2008-05-07
09:13:33.000000000 -0500
+++ linux-2.6-denx_patched/drivers/usb/gadget/dwc_otg/ppc4xx_dma.h
2009-05-23 08:33:26.172500000 -0500
@@ -84,8 +84,13 @@
* DMA Channel Control Registers
*/
-#if defined(CONFIG_44x) || defined(CONFIG_405EX) || defined(CONFIG_405EXr)
+/* The PPC44x series has a 64Bit DMA */
+#if defined(CONFIG_44x)
#define PPC4xx_DMA_64BIT
+#endif
+
+/* The PPC44x and PPC405EX/r have a reserved bit in DMA control register*/
+#if defined(CONFIG_44x) || defined(CONFIG_405EX) || defined(CONFIG_405EXr)
#define DMA_CR_OFFSET 1
#else
#define DMA_CR_OFFSET 0
------------- end snip -----------
--------- Makefile snip ----------
--- linux-2.6-denx/drivers/usb/gadget/dwc_otg/Makefile 2008-05-07
09:13:33.000000000 -0500
+++ linux-2.6-denx_patched/drivers/usb/gadget/dwc_otg/Makefile 2009-05-23
08:38:04.182500000 -0500
@@ -22,7 +22,7 @@
#KBUILD_CPPFLAGS += -DOTG_EXT_CHG_PUMP
# PLB DMA mode
-KBUILD_CPPFLAGS += -Dlinux -DDWC_SLAVE -DOTG_PLB_DMA
-DOTG_PLB_DMA_TASKLET #-DDWC_DEVICE_ONLY # -DDWC_HS_ELECT_TST -DDWC_SLAVE
-DDWC_HOST_ONLY
+KBUILD_CPPFLAGS += -Dlinux -DOTG_PLB_DMA -DOTG_PLB_DMA_TASKLET
endif
ifeq ($(CONFIG_460EX),y)
------------- end snip -----------
On Sat, May 23, 2009 at 7:44 AM, Hunter Cobbs <hunter.cobbs@gmail.com>wrote:
> Egads! Forgot to respond to the list!
>
> My git checkout failed last night, so I'm downloading the resource cd, but
> I can tell you what I did before I get the actual patch done, and you can
> tell me if my logic is sound.
>
> First thing I thought when I saw this is WHY use IRQ based methods to
> access a USB controller with internal DMA transfers? I tried in vain to
> enable this with the driver module parameters(which I dug up how to specify
> module parameters to built-in drivers from an old 2.2-series kernel
> discussion). So, then I put on my boots and started slogging throught the
> driver.
>
> Getting frustrated with that line of execution, I turned up the verbosity
> on the kernel compile and noticed a warning in the dwc_otg compilation.
> Specifically that a left and right shift go out of bounds of the variables
> used. The only place this occurs is in a section of code that is wrapped
> with DMA_64BIT. Which made absolutely no sense because the DMA controller
> on the 405EX is only 32 bits wide. On tracking this define down, I come to
> find out that someone made the assumption that the 44x and the 405EX/r all
> have the same DMA controller. Which is incorrect, they both have the same
> control register definitions(the offset of 1 due to the MSBit being reserved
> and the register being in Big Endian mode); however, the 44x is 64bits and
> the 405 is 32bits. So, I broke the DMA control down into two areas,
> data-width and control register offsets.
>
> When this still didn't fix the problem, I found yet another section that
> can force you to operate in slave(irq) mode only wrapped in yet another
> define. When I search out that define (DWC_SLAVE I believe), I find it in
> the dwc_otg Makefile.
>
> Correcting both of these has enabled full DMA access to the USB, and I'm
> doing much better with my sierra wireless dev kit.
>
> On Sat, May 23, 2009 at 7:11 AM, Chuck Meade <chuckmeade@mindspring.com>wrote:
>
>> Hunter Cobbs wrote:
>> > Hello everyone,
>> >
>> > This is my first post to the PPC dev list as my company has just started
>> > developing a new project based on Linux. The good news is, this post is
>> > not debug-related as much as it is an introduction and query while I
>> > download the latest DENX kernel(only place I know that has the DWC_OTG
>> > driver).
>> >
>> > I've been working with a Kilauea dev board and have had lots of trouble
>> > when I plug in a sierra-wireless modem dev kit on the USB. It goes fine
>> > untill I actually try to communicate(pppd or minicom) with the little
>> > bugger and then my IRQs go through the roof. And they only calm back
>> > down after I shut down my communicaiton channel.
>> >
>> > I've solved this issue with our board, and was wondering if it has since
>> > been fixed (I'm running 2.6.25-DENX). I don't want to waste the board's
>> > time with a patch that is no longer necesarry.
>> >
>> > --
>> > Hunter Cobbs
>>
>> Hello Hunter,
>>
>> It would absolutely *not* be a waste of anyone's time. I for one would
>> like
>> to see how you solved this. I am dealing with the same problem, with the
>> same
>> setup.
>>
>> The underlying cause for this problem is the PPC405EX CPU's erratum
>> USBO_9.
>> The USB 2.0 PING protocol is supposed to handle a PING transaction in
>> the hardware -- note that in USB 2.0, a PING is the method used by the
>> sender to
>> determine if it can send. If I remember correctly, erratum USBO_9 is
>> caused when
>> a NAK response from the PING transaction is handled not in hardware, but
>> instead
>> as an interrupt in software, and that NAK leads to a lot of processing.
>> In the
>> 2.6.25 Denx Linux tree that I used, that processing ends up trying to
>> restart the
>> channel, restart the send, which leads to yet another PING/NAK sequence,
>> yet another
>> interrupt...
>>
>> The end result is that you get over 100,000 interrupts (with significant
>> interrupt
>> handling logic) per second, and the target can't do anything else. I was
>> able
>> to get this interrupt count by looking at /proc/interrupts, then causing
>> this problem
>> for 20 seconds, then pulling out the USB modem physically (mine is on a
>> Express card)
>> to stop the interrupt storm, then checking /proc/interrupts again.
>> Averaged over
>> 100,000 ints/sec.
>>
>> In contact with AMCC, they told us they are not respinning the CPU (at
>> least not
>> at this time) to fix this erratum.
>>
>> I have tried to solve the problem as suggested by the erratum, by not
>> allowing the
>> NAK interrupt handling to *directly* cause a retry of the send, but rather
>> to wait
>> until the next SOF interrupt (start of microframe, which happens 8,000
>> times per sec)
>> to restart it. "Breaking the chain" like this does allow the board to
>> proceed, but
>> I think it is suboptimal, or at least unfortunate.
>>
>> One painful side effect of this workaround is that you cannot disable the
>> 8,000 SOF
>> interrupts/second, or at least some of them, since they are being used now
>> for another
>> purpose -- recovery from the erratum.
>>
>> The 8000 SOF ints being handled per second do cause a measurable drain on
>> the
>> CPU. In some cursory testing we see a 10% slowdown of certain
>> transactions in
>> lmbench.
>>
>> So please send me your patch for the dwc_otg driver. I am very interested
>> in what
>> you did, and if it perhaps is a better solution for the problem we both
>> are seeing
>> than what I implemented.
>>
>> Thanks in advance,
>> Chuck
>>
>>
>
>
> --
> Hunter Cobbs
>
--
Hunter Cobbs
[-- Attachment #2: Type: text/html, Size: 8116 bytes --]
^ permalink raw reply
* Re: PPC405EX based irq flooding with USB-OTG and usbserial device
From: Hunter Cobbs @ 2009-05-23 12:44 UTC (permalink / raw)
To: linuxppc-dev
In-Reply-To: <4A17E7FD.1070905@mindspring.com>
[-- Attachment #1: Type: text/plain, Size: 5372 bytes --]
Egads! Forgot to respond to the list!
My git checkout failed last night, so I'm downloading the resource cd, but I
can tell you what I did before I get the actual patch done, and you can tell
me if my logic is sound.
First thing I thought when I saw this is WHY use IRQ based methods to access
a USB controller with internal DMA transfers? I tried in vain to enable
this with the driver module parameters(which I dug up how to specify module
parameters to built-in drivers from an old 2.2-series kernel discussion).
So, then I put on my boots and started slogging throught the driver.
Getting frustrated with that line of execution, I turned up the verbosity on
the kernel compile and noticed a warning in the dwc_otg compilation.
Specifically that a left and right shift go out of bounds of the variables
used. The only place this occurs is in a section of code that is wrapped
with DMA_64BIT. Which made absolutely no sense because the DMA controller
on the 405EX is only 32 bits wide. On tracking this define down, I come to
find out that someone made the assumption that the 44x and the 405EX/r all
have the same DMA controller. Which is incorrect, they both have the same
control register definitions(the offset of 1 due to the MSBit being reserved
and the register being in Big Endian mode); however, the 44x is 64bits and
the 405 is 32bits. So, I broke the DMA control down into two areas,
data-width and control register offsets.
When this still didn't fix the problem, I found yet another section that can
force you to operate in slave(irq) mode only wrapped in yet another define.
When I search out that define (DWC_SLAVE I believe), I find it in the
dwc_otg Makefile.
Correcting both of these has enabled full DMA access to the USB, and I'm
doing much better with my sierra wireless dev kit.
On Sat, May 23, 2009 at 7:11 AM, Chuck Meade <chuckmeade@mindspring.com>wrote:
> Hunter Cobbs wrote:
> > Hello everyone,
> >
> > This is my first post to the PPC dev list as my company has just started
> > developing a new project based on Linux. The good news is, this post is
> > not debug-related as much as it is an introduction and query while I
> > download the latest DENX kernel(only place I know that has the DWC_OTG
> > driver).
> >
> > I've been working with a Kilauea dev board and have had lots of trouble
> > when I plug in a sierra-wireless modem dev kit on the USB. It goes fine
> > untill I actually try to communicate(pppd or minicom) with the little
> > bugger and then my IRQs go through the roof. And they only calm back
> > down after I shut down my communicaiton channel.
> >
> > I've solved this issue with our board, and was wondering if it has since
> > been fixed (I'm running 2.6.25-DENX). I don't want to waste the board's
> > time with a patch that is no longer necesarry.
> >
> > --
> > Hunter Cobbs
>
> Hello Hunter,
>
> It would absolutely *not* be a waste of anyone's time. I for one would
> like
> to see how you solved this. I am dealing with the same problem, with the
> same
> setup.
>
> The underlying cause for this problem is the PPC405EX CPU's erratum USBO_9.
> The USB 2.0 PING protocol is supposed to handle a PING transaction in
> the hardware -- note that in USB 2.0, a PING is the method used by the
> sender to
> determine if it can send. If I remember correctly, erratum USBO_9 is
> caused when
> a NAK response from the PING transaction is handled not in hardware, but
> instead
> as an interrupt in software, and that NAK leads to a lot of processing. In
> the
> 2.6.25 Denx Linux tree that I used, that processing ends up trying to
> restart the
> channel, restart the send, which leads to yet another PING/NAK sequence,
> yet another
> interrupt...
>
> The end result is that you get over 100,000 interrupts (with significant
> interrupt
> handling logic) per second, and the target can't do anything else. I was
> able
> to get this interrupt count by looking at /proc/interrupts, then causing
> this problem
> for 20 seconds, then pulling out the USB modem physically (mine is on a
> Express card)
> to stop the interrupt storm, then checking /proc/interrupts again.
> Averaged over
> 100,000 ints/sec.
>
> In contact with AMCC, they told us they are not respinning the CPU (at
> least not
> at this time) to fix this erratum.
>
> I have tried to solve the problem as suggested by the erratum, by not
> allowing the
> NAK interrupt handling to *directly* cause a retry of the send, but rather
> to wait
> until the next SOF interrupt (start of microframe, which happens 8,000
> times per sec)
> to restart it. "Breaking the chain" like this does allow the board to
> proceed, but
> I think it is suboptimal, or at least unfortunate.
>
> One painful side effect of this workaround is that you cannot disable the
> 8,000 SOF
> interrupts/second, or at least some of them, since they are being used now
> for another
> purpose -- recovery from the erratum.
>
> The 8000 SOF ints being handled per second do cause a measurable drain on
> the
> CPU. In some cursory testing we see a 10% slowdown of certain transactions
> in
> lmbench.
>
> So please send me your patch for the dwc_otg driver. I am very interested
> in what
> you did, and if it perhaps is a better solution for the problem we both are
> seeing
> than what I implemented.
>
> Thanks in advance,
> Chuck
>
>
--
Hunter Cobbs
[-- Attachment #2: Type: text/html, Size: 6078 bytes --]
^ permalink raw reply
* Re: PPC405EX based irq flooding with USB-OTG and usbserial device
From: Chuck Meade @ 2009-05-23 12:11 UTC (permalink / raw)
To: Hunter Cobbs; +Cc: linuxppc-dev
In-Reply-To: <ad84a70a0905222048i4e7ae5ddp66418f96d531f5f3@mail.gmail.com>
Hunter Cobbs wrote:
> Hello everyone,
>
> This is my first post to the PPC dev list as my company has just started
> developing a new project based on Linux. The good news is, this post is
> not debug-related as much as it is an introduction and query while I
> download the latest DENX kernel(only place I know that has the DWC_OTG
> driver).
>
> I've been working with a Kilauea dev board and have had lots of trouble
> when I plug in a sierra-wireless modem dev kit on the USB. It goes fine
> untill I actually try to communicate(pppd or minicom) with the little
> bugger and then my IRQs go through the roof. And they only calm back
> down after I shut down my communicaiton channel.
>
> I've solved this issue with our board, and was wondering if it has since
> been fixed (I'm running 2.6.25-DENX). I don't want to waste the board's
> time with a patch that is no longer necesarry.
>
> --
> Hunter Cobbs
Hello Hunter,
It would absolutely *not* be a waste of anyone's time. I for one would like
to see how you solved this. I am dealing with the same problem, with the same
setup.
The underlying cause for this problem is the PPC405EX CPU's erratum USBO_9.
The USB 2.0 PING protocol is supposed to handle a PING transaction in
the hardware -- note that in USB 2.0, a PING is the method used by the sender to
determine if it can send. If I remember correctly, erratum USBO_9 is caused when
a NAK response from the PING transaction is handled not in hardware, but instead
as an interrupt in software, and that NAK leads to a lot of processing. In the
2.6.25 Denx Linux tree that I used, that processing ends up trying to restart the
channel, restart the send, which leads to yet another PING/NAK sequence, yet another
interrupt...
The end result is that you get over 100,000 interrupts (with significant interrupt
handling logic) per second, and the target can't do anything else. I was able
to get this interrupt count by looking at /proc/interrupts, then causing this problem
for 20 seconds, then pulling out the USB modem physically (mine is on a Express card)
to stop the interrupt storm, then checking /proc/interrupts again. Averaged over
100,000 ints/sec.
In contact with AMCC, they told us they are not respinning the CPU (at least not
at this time) to fix this erratum.
I have tried to solve the problem as suggested by the erratum, by not allowing the
NAK interrupt handling to *directly* cause a retry of the send, but rather to wait
until the next SOF interrupt (start of microframe, which happens 8,000 times per sec)
to restart it. "Breaking the chain" like this does allow the board to proceed, but
I think it is suboptimal, or at least unfortunate.
One painful side effect of this workaround is that you cannot disable the 8,000 SOF
interrupts/second, or at least some of them, since they are being used now for another
purpose -- recovery from the erratum.
The 8000 SOF ints being handled per second do cause a measurable drain on the
CPU. In some cursory testing we see a 10% slowdown of certain transactions in
lmbench.
So please send me your patch for the dwc_otg driver. I am very interested in what
you did, and if it perhaps is a better solution for the problem we both are seeing
than what I implemented.
Thanks in advance,
Chuck
^ permalink raw reply
* Re: [net-next-2.6 PATCH v2] can: SJA1000: generic OF platform bus driver
From: Arnd Bergmann @ 2009-05-23 11:15 UTC (permalink / raw)
To: devicetree-discuss; +Cc: Linux Netdev List, linuxppc-dev
In-Reply-To: <4A16BAAE.3070401@grandegger.com>
On Friday 22 May 2009, Wolfgang Grandegger wrote:
> This patch adds a generic driver for SJA1000 chips on the OpenFirmware
> platform bus found on embedded PowerPC systems.
Nice driver!
> +static u8 sja1000_ofp_read_reg(const struct net_device *dev, int reg)
> +{
> + return in_8((void __iomem *)(dev->base_addr + reg));
> +}
> +
> +static void sja1000_ofp_write_reg(const struct net_device *dev, int reg, u8 val)
> +{
> + out_8((void __iomem *)(dev->base_addr + reg), val);
> +}
Minor nitpicking: dev->base_addr should be defined as an __iomem pointer
so you can avoid the cast here and in the ioremap/iounmap path.
Arnd <><
^ permalink raw reply
* Re: [net-next-2.6 PATCH v2] can: SJA1000: generic OF platform bus driver
From: Wolfgang Grandegger @ 2009-05-23 6:29 UTC (permalink / raw)
To: Grant Likely; +Cc: Linux Netdev List, devicetree-discuss, linuxppc-dev
In-Reply-To: <fa686aa40905220808kecd06cdqb570b78ca97f0ca6@mail.gmail.com>
Hi Grant,
Grant Likely wrote:
> Hi Wolfgang, thanks for the quick response. Comments below...
>
> On Fri, May 22, 2009 at 8:46 AM, Wolfgang Grandegger <wg@grandegger.com> wrote:
>> +++ net-next-2.6/Documentation/powerpc/dts-bindings/can/sja1000.txt
>> @@ -0,0 +1,37 @@
>> +Memory mapped SJA1000 CAN controller from NXP (formerly Philips)
>> +
>> +Required properties:
>> +
>> +- compatible : should be "nxp,sja1000".
>> +- reg : should specify the chip select, address offset and size used
>> + for the chip depending on the bus it is connected to.
>> +- interrupts: property with a value describing the interrupt source
>> + (number and sensitivity) for that device. The encoding depends
>> + on the type of interrupt controller used.
>
> Hmmm, "reg", "interrupts", and "interrupt-parent" are well understood
> properties. I don't think we need to keep boilerplate defining the
> meaning every time a new binding is added. (general musing; not an
> ack or nack of this patch)
OK.
> However, what should be defined is *what* the register range is (ie.
> one tuple; location of device registers), and what the interrupts are
> (ie. single tuple for device's irq line). Granted this is a trivial
> case, but in the case of devices with more than one address range or
> irq line, the meaning of each tuple is critical information. I think
> it would be a good pattern to establish.
Sounds reasonable.
>> +Optional properties:
>> +
>> +- interrupt-parent : the phandle for the interrupt controller that
>> + services interrupts for that device.
>
> Thinking further; I wouldn't even mention "interrupt-parent" here.
> Anyone working with this stuff must already understand irq routing.
OK, I will remove it.
>> +- clock-frequency : CAN system clock frequency in Hz, which is normally
>> + half of the oscillator clock frequency. If not specified, a
>> + default value of 8000000 (8 MHz) is used.
>
> A clock-frequency property typically refers to the bus clock
> frequency. Something like can-frequency would be better.
Ah, right, but I'm also not happy with "can-frequency". The manual
speaks about the "internal clock", which is half of the external
oscillator frequency. Maybe "internal-clock-frequency" might be better.
>> +- cdr-reg : value of the SJA1000 clock divider register according to
>> + the SJA1000 data sheet. If not specified, a default value of
>> + 0x48 is used.
>
> Ewh. The driver should be clueful enough to derive the clock divider
> value given both the bus and can frequencies. I don't like this
> property.
The clock divider register controls the CLKOUT frequency for the
microcontroller another CAN controller and allows to deactivate the
CLKOUT pin. It's not used to configure the CAN bus frequency.
>
>> +- ocr-reg : value of the SJA1000 output control register according to
>> + the SJA1000 data sheet. If not specified, a default value of
>> + 0x0a is used.
>
> Ditto here; the binding should describe the usage mode; not the
> register settings to get the usage mode. What sort of settings will
> the .dts author be writing here?
Unfortunately, there are many:
clkout-frequency
bypass-comperator
tx1-output-on-rx-irq
#define OCR_MODE_BIPHASE 0x00
#define OCR_MODE_TEST 0x01
#define OCR_MODE_NORMAL 0x02
#define OCR_MODE_CLOCK 0x03
#define OCR_TX0_INVERT 0x04
#define OCR_TX0_PULLDOWN 0x08
#define OCR_TX0_PULLUP 0x10
#define OCR_TX0_PUSHPULL 0x18
#define OCR_TX1_INVERT 0x20
#define OCR_TX1_PULLDOWN 0x40
#define OCR_TX1_PULLUP 0x80
#define OCR_TX1_PUSHPULL 0xc0
I think implementing properties for each option is overkill.
Wolfgang.
>
^ permalink raw reply
* PPC405EX based irq flooding with USB-OTG and usbserial device
From: Hunter Cobbs @ 2009-05-23 3:48 UTC (permalink / raw)
To: linuxppc-dev
[-- Attachment #1: Type: text/plain, Size: 859 bytes --]
Hello everyone,
This is my first post to the PPC dev list as my company has just started
developing a new project based on Linux. The good news is, this post is not
debug-related as much as it is an introduction and query while I download
the latest DENX kernel(only place I know that has the DWC_OTG driver).
I've been working with a Kilauea dev board and have had lots of trouble when
I plug in a sierra-wireless modem dev kit on the USB. It goes fine untill I
actually try to communicate(pppd or minicom) with the little bugger and then
my IRQs go through the roof. And they only calm back down after I shut down
my communicaiton channel.
I've solved this issue with our board, and was wondering if it has since
been fixed (I'm running 2.6.25-DENX). I don't want to waste the board's
time with a patch that is no longer necesarry.
--
Hunter Cobbs
[-- Attachment #2: Type: text/html, Size: 930 bytes --]
^ permalink raw reply
* Re: [PATCH V2 2/3] powerpc: Add support for swiotlb on 32-bit
From: Jeremy Fitzhardinge @ 2009-05-22 23:55 UTC (permalink / raw)
To: Ian Campbell
Cc: FUJITA Tomonori, linuxppc-dev@ozlabs.org,
linux-kernel@vger.kernel.org
In-Reply-To: <1242990702.22654.253.camel@zakaz.uk.xensource.com>
Ian Campbell wrote:
> On Thu, 2009-05-21 at 14:27 -0400, Becky Bruce wrote:
>
>> I can work with that, but it's going to be a bit inefficient, as I
>> actually need the dma_addr_t, not the phys_addr_t, so I'll have to
>> convert. In every case, this is a conversion I've already done and
>> that I need in the calling code as well.
>>
>
> Does
>
> dma_addr_t dma_map_range(struct device *hwdev, phys_addr_t addr,
> size_t size);
>
> work for you?
>
> If the range does not need mapping then it returns the dma address, if
> you needed to calculate the dma address anyway to figure out if mapping
> is required then this is fine. If the range does need mapping then it
> returns NULL.
>
My only concern is whether dma_addr_t == 0 is actually equivalent to
NULL. That is, can we be sure that address 0 will never be used?
Taking dma_alloc_coherent as a model, we could have something like:
int dma_map_range(struct device *hwdev, phys_addr_t addr, size_t size, dma_addr_t *dma_addrp);
where *dma_addrp is set if the function returns success (bool return
type might be clearer).
J
^ permalink raw reply
* [PATCH] therm_adt746x: Always clear hardware bit which inverts fan speed range.
From: Michel Dänzer @ 2009-05-22 20:59 UTC (permalink / raw)
To: Colin Leroy, Benjamin Herrenschmidt; +Cc: linuxppc-dev
This bit would get enabled sometimes (probably after suspend/resume), so the
fan would run at full speed below the temperature thresholds, but slow down and
eventually stop if temperatures rose above the thresholds... not exactly what
you want.
Signed-off-by: Michel Dänzer <michel@daenzer.net>
---
drivers/macintosh/therm_adt746x.c | 4 +++-
1 files changed, 3 insertions(+), 1 deletions(-)
diff --git a/drivers/macintosh/therm_adt746x.c b/drivers/macintosh/therm_adt746x.c
index 82607ad..321eaad 100644
--- a/drivers/macintosh/therm_adt746x.c
+++ b/drivers/macintosh/therm_adt746x.c
@@ -37,6 +37,7 @@
#define CONFIG_REG 0x40
#define MANUAL_MASK 0xe0
#define AUTO_MASK 0x20
+#define INVERT_MASK 0x10
static u8 TEMP_REG[3] = {0x26, 0x25, 0x27}; /* local, sensor1, sensor2 */
static u8 LIMIT_REG[3] = {0x6b, 0x6a, 0x6c}; /* local, sensor1, sensor2 */
@@ -229,7 +230,8 @@ static void write_fan_speed(struct thermostat *th, int speed, int fan)
if (speed >= 0) {
manual = read_reg(th, MANUAL_MODE[fan]);
- write_reg(th, MANUAL_MODE[fan], manual|MANUAL_MASK);
+ write_reg(th, MANUAL_MODE[fan],
+ (manual|MANUAL_MASK) & (~INVERT_MASK));
write_reg(th, FAN_SPD_SET[fan], speed);
} else {
/* back to automatic */
--
1.6.3
^ permalink raw reply related
* [PATCH] powerpc/virtex: Add ml510 reference design device tree
From: Grant Likely @ 2009-05-22 16:29 UTC (permalink / raw)
To: devicetree-discuss, linuxppc-dev; +Cc: Roderick Colenbrander
From: Roderick Colenbrander <thunderbird2k@gmail.com>
As subject says, add dts files for Xilinx ML510 reference design with
the PCI host bridge device
Signed-off-by: Roderick Colenbrander <thunderbird2k@gmail.com>
Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
---
I'm posting this one to the devicetree-discuss list for review before merging.
The dts file was generated using the Xilinx EDK device-tree generation tool
and then modified by hand to add in the non-FPGA bits.
g.
arch/powerpc/boot/dts/virtex440-ml510.dts | 465 +++++++++++++++++++++++++++++
1 files changed, 465 insertions(+), 0 deletions(-)
create mode 100644 arch/powerpc/boot/dts/virtex440-ml510.dts
diff --git a/arch/powerpc/boot/dts/virtex440-ml510.dts b/arch/powerpc/boot/dts/virtex440-ml510.dts
new file mode 100644
index 0000000..81a8dc2
--- /dev/null
+++ b/arch/powerpc/boot/dts/virtex440-ml510.dts
@@ -0,0 +1,465 @@
+/*
+ * Xilinx ML510 Reference Design support
+ *
+ * This DTS file was created for the ml510_bsb1_pcores_ppc440 reference design.
+ * The reference design contains a bug which prevent PCI DMA from working
+ * properly. A description of the bug is given in the plbv46_pci section. It
+ * needs to be fixed by the user until Xilinx updates their reference design.
+ *
+ * Copyright 2009, Roderick Colenbrander
+ */
+
+/dts-v1/;
+/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "xlnx,ml510-ref-design", "xlnx,virtex440";
+ dcr-parent = <&ppc440_0>;
+ DDR2_SDRAM_DIMM0: memory@0 {
+ device_type = "memory";
+ reg = < 0x0 0x20000000 >;
+ } ;
+ alias {
+ ethernet0 = &Hard_Ethernet_MAC;
+ serial0 = &RS232_Uart_1;
+ } ;
+ chosen {
+ bootargs = "console=ttyS0 root=/dev/ram";
+ linux,stdout-path = "/plb@0/serial@83e00000";
+ } ;
+ cpus {
+ #address-cells = <1>;
+ #cpus = <0x1>;
+ #size-cells = <0>;
+ ppc440_0: cpu@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ clock-frequency = <300000000>;
+ compatible = "PowerPC,440", "ibm,ppc440";
+ d-cache-line-size = <0x20>;
+ d-cache-size = <0x8000>;
+ dcr-access-method = "native";
+ dcr-controller ;
+ device_type = "cpu";
+ i-cache-line-size = <0x20>;
+ i-cache-size = <0x8000>;
+ model = "PowerPC,440";
+ reg = <0>;
+ timebase-frequency = <300000000>;
+ xlnx,apu-control = <0x2000>;
+ xlnx,apu-udi-0 = <0x0>;
+ xlnx,apu-udi-1 = <0x0>;
+ xlnx,apu-udi-10 = <0x0>;
+ xlnx,apu-udi-11 = <0x0>;
+ xlnx,apu-udi-12 = <0x0>;
+ xlnx,apu-udi-13 = <0x0>;
+ xlnx,apu-udi-14 = <0x0>;
+ xlnx,apu-udi-15 = <0x0>;
+ xlnx,apu-udi-2 = <0x0>;
+ xlnx,apu-udi-3 = <0x0>;
+ xlnx,apu-udi-4 = <0x0>;
+ xlnx,apu-udi-5 = <0x0>;
+ xlnx,apu-udi-6 = <0x0>;
+ xlnx,apu-udi-7 = <0x0>;
+ xlnx,apu-udi-8 = <0x0>;
+ xlnx,apu-udi-9 = <0x0>;
+ xlnx,dcr-autolock-enable = <0x1>;
+ xlnx,dcu-rd-ld-cache-plb-prio = <0x0>;
+ xlnx,dcu-rd-noncache-plb-prio = <0x0>;
+ xlnx,dcu-rd-touch-plb-prio = <0x0>;
+ xlnx,dcu-rd-urgent-plb-prio = <0x0>;
+ xlnx,dcu-wr-flush-plb-prio = <0x0>;
+ xlnx,dcu-wr-store-plb-prio = <0x0>;
+ xlnx,dcu-wr-urgent-plb-prio = <0x0>;
+ xlnx,dma0-control = <0x0>;
+ xlnx,dma0-plb-prio = <0x0>;
+ xlnx,dma0-rxchannelctrl = <0x1010000>;
+ xlnx,dma0-rxirqtimer = <0x3ff>;
+ xlnx,dma0-txchannelctrl = <0x1010000>;
+ xlnx,dma0-txirqtimer = <0x3ff>;
+ xlnx,dma1-control = <0x0>;
+ xlnx,dma1-plb-prio = <0x0>;
+ xlnx,dma1-rxchannelctrl = <0x1010000>;
+ xlnx,dma1-rxirqtimer = <0x3ff>;
+ xlnx,dma1-txchannelctrl = <0x1010000>;
+ xlnx,dma1-txirqtimer = <0x3ff>;
+ xlnx,dma2-control = <0x0>;
+ xlnx,dma2-plb-prio = <0x0>;
+ xlnx,dma2-rxchannelctrl = <0x1010000>;
+ xlnx,dma2-rxirqtimer = <0x3ff>;
+ xlnx,dma2-txchannelctrl = <0x1010000>;
+ xlnx,dma2-txirqtimer = <0x3ff>;
+ xlnx,dma3-control = <0x0>;
+ xlnx,dma3-plb-prio = <0x0>;
+ xlnx,dma3-rxchannelctrl = <0x1010000>;
+ xlnx,dma3-rxirqtimer = <0x3ff>;
+ xlnx,dma3-txchannelctrl = <0x1010000>;
+ xlnx,dma3-txirqtimer = <0x3ff>;
+ xlnx,endian-reset = <0x0>;
+ xlnx,generate-plb-timespecs = <0x1>;
+ xlnx,icu-rd-fetch-plb-prio = <0x0>;
+ xlnx,icu-rd-spec-plb-prio = <0x0>;
+ xlnx,icu-rd-touch-plb-prio = <0x0>;
+ xlnx,interconnect-imask = <0xffffffff>;
+ xlnx,mplb-allow-lock-xfer = <0x1>;
+ xlnx,mplb-arb-mode = <0x0>;
+ xlnx,mplb-awidth = <0x20>;
+ xlnx,mplb-counter = <0x500>;
+ xlnx,mplb-dwidth = <0x80>;
+ xlnx,mplb-max-burst = <0x8>;
+ xlnx,mplb-native-dwidth = <0x80>;
+ xlnx,mplb-p2p = <0x0>;
+ xlnx,mplb-prio-dcur = <0x2>;
+ xlnx,mplb-prio-dcuw = <0x3>;
+ xlnx,mplb-prio-icu = <0x4>;
+ xlnx,mplb-prio-splb0 = <0x1>;
+ xlnx,mplb-prio-splb1 = <0x0>;
+ xlnx,mplb-read-pipe-enable = <0x1>;
+ xlnx,mplb-sync-tattribute = <0x0>;
+ xlnx,mplb-wdog-enable = <0x1>;
+ xlnx,mplb-write-pipe-enable = <0x1>;
+ xlnx,mplb-write-post-enable = <0x1>;
+ xlnx,num-dma = <0x0>;
+ xlnx,pir = <0xf>;
+ xlnx,ppc440mc-addr-base = <0x0>;
+ xlnx,ppc440mc-addr-high = <0x1fffffff>;
+ xlnx,ppc440mc-arb-mode = <0x0>;
+ xlnx,ppc440mc-bank-conflict-mask = <0x1800000>;
+ xlnx,ppc440mc-control = <0xf810008f>;
+ xlnx,ppc440mc-max-burst = <0x8>;
+ xlnx,ppc440mc-prio-dcur = <0x2>;
+ xlnx,ppc440mc-prio-dcuw = <0x3>;
+ xlnx,ppc440mc-prio-icu = <0x4>;
+ xlnx,ppc440mc-prio-splb0 = <0x1>;
+ xlnx,ppc440mc-prio-splb1 = <0x0>;
+ xlnx,ppc440mc-row-conflict-mask = <0x7ffe00>;
+ xlnx,ppcdm-asyncmode = <0x0>;
+ xlnx,ppcds-asyncmode = <0x0>;
+ xlnx,user-reset = <0x0>;
+ } ;
+ } ;
+ plb_v46_0: plb@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "xlnx,plb-v46-1.03.a", "simple-bus";
+ ranges ;
+ FLASH: flash@fc000000 {
+ bank-width = <2>;
+ compatible = "xlnx,xps-mch-emc-2.00.a", "cfi-flash";
+ reg = < 0xfc000000 0x2000000 >;
+ xlnx,family = "virtex5";
+ xlnx,include-datawidth-matching-0 = <0x1>;
+ xlnx,include-datawidth-matching-1 = <0x0>;
+ xlnx,include-datawidth-matching-2 = <0x0>;
+ xlnx,include-datawidth-matching-3 = <0x0>;
+ xlnx,include-negedge-ioregs = <0x0>;
+ xlnx,include-plb-ipif = <0x1>;
+ xlnx,include-wrbuf = <0x1>;
+ xlnx,max-mem-width = <0x10>;
+ xlnx,mch-native-dwidth = <0x20>;
+ xlnx,mch-plb-clk-period-ps = <0x2710>;
+ xlnx,mch-splb-awidth = <0x20>;
+ xlnx,mch0-accessbuf-depth = <0x10>;
+ xlnx,mch0-protocol = <0x0>;
+ xlnx,mch0-rddatabuf-depth = <0x10>;
+ xlnx,mch1-accessbuf-depth = <0x10>;
+ xlnx,mch1-protocol = <0x0>;
+ xlnx,mch1-rddatabuf-depth = <0x10>;
+ xlnx,mch2-accessbuf-depth = <0x10>;
+ xlnx,mch2-protocol = <0x0>;
+ xlnx,mch2-rddatabuf-depth = <0x10>;
+ xlnx,mch3-accessbuf-depth = <0x10>;
+ xlnx,mch3-protocol = <0x0>;
+ xlnx,mch3-rddatabuf-depth = <0x10>;
+ xlnx,mem0-width = <0x10>;
+ xlnx,mem1-width = <0x20>;
+ xlnx,mem2-width = <0x20>;
+ xlnx,mem3-width = <0x20>;
+ xlnx,num-banks-mem = <0x1>;
+ xlnx,num-channels = <0x2>;
+ xlnx,priority-mode = <0x0>;
+ xlnx,synch-mem-0 = <0x0>;
+ xlnx,synch-mem-1 = <0x0>;
+ xlnx,synch-mem-2 = <0x0>;
+ xlnx,synch-mem-3 = <0x0>;
+ xlnx,synch-pipedelay-0 = <0x2>;
+ xlnx,synch-pipedelay-1 = <0x2>;
+ xlnx,synch-pipedelay-2 = <0x2>;
+ xlnx,synch-pipedelay-3 = <0x2>;
+ xlnx,tavdv-ps-mem-0 = <0x1adb0>;
+ xlnx,tavdv-ps-mem-1 = <0x3a98>;
+ xlnx,tavdv-ps-mem-2 = <0x3a98>;
+ xlnx,tavdv-ps-mem-3 = <0x3a98>;
+ xlnx,tcedv-ps-mem-0 = <0x1adb0>;
+ xlnx,tcedv-ps-mem-1 = <0x3a98>;
+ xlnx,tcedv-ps-mem-2 = <0x3a98>;
+ xlnx,tcedv-ps-mem-3 = <0x3a98>;
+ xlnx,thzce-ps-mem-0 = <0x88b8>;
+ xlnx,thzce-ps-mem-1 = <0x1b58>;
+ xlnx,thzce-ps-mem-2 = <0x1b58>;
+ xlnx,thzce-ps-mem-3 = <0x1b58>;
+ xlnx,thzoe-ps-mem-0 = <0x1b58>;
+ xlnx,thzoe-ps-mem-1 = <0x1b58>;
+ xlnx,thzoe-ps-mem-2 = <0x1b58>;
+ xlnx,thzoe-ps-mem-3 = <0x1b58>;
+ xlnx,tlzwe-ps-mem-0 = <0x88b8>;
+ xlnx,tlzwe-ps-mem-1 = <0x0>;
+ xlnx,tlzwe-ps-mem-2 = <0x0>;
+ xlnx,tlzwe-ps-mem-3 = <0x0>;
+ xlnx,twc-ps-mem-0 = <0x1adb0>;
+ xlnx,twc-ps-mem-1 = <0x3a98>;
+ xlnx,twc-ps-mem-2 = <0x3a98>;
+ xlnx,twc-ps-mem-3 = <0x3a98>;
+ xlnx,twp-ps-mem-0 = <0x11170>;
+ xlnx,twp-ps-mem-1 = <0x2ee0>;
+ xlnx,twp-ps-mem-2 = <0x2ee0>;
+ xlnx,twp-ps-mem-3 = <0x2ee0>;
+ xlnx,xcl0-linesize = <0x4>;
+ xlnx,xcl0-writexfer = <0x1>;
+ xlnx,xcl1-linesize = <0x4>;
+ xlnx,xcl1-writexfer = <0x1>;
+ xlnx,xcl2-linesize = <0x4>;
+ xlnx,xcl2-writexfer = <0x1>;
+ xlnx,xcl3-linesize = <0x4>;
+ xlnx,xcl3-writexfer = <0x1>;
+ } ;
+ Hard_Ethernet_MAC: xps-ll-temac@81c00000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "xlnx,compound";
+ ethernet@81c00000 {
+ compatible = "xlnx,xps-ll-temac-1.01.b";
+ device_type = "network";
+ interrupt-parent = <&xps_intc_0>;
+ interrupts = < 8 2 >;
+ llink-connected = <&Hard_Ethernet_MAC_fifo>;
+ local-mac-address = [ 02 00 00 00 00 00 ];
+ reg = < 0x81c00000 0x40 >;
+ xlnx,bus2core-clk-ratio = <0x1>;
+ xlnx,phy-type = <0x3>;
+ xlnx,phyaddr = <0x1>;
+ xlnx,rxcsum = <0x0>;
+ xlnx,rxfifo = <0x8000>;
+ xlnx,temac-type = <0x0>;
+ xlnx,txcsum = <0x0>;
+ xlnx,txfifo = <0x8000>;
+ } ;
+ } ;
+ Hard_Ethernet_MAC_fifo: xps-ll-fifo@81a00000 {
+ compatible = "xlnx,xps-ll-fifo-1.01.a";
+ interrupt-parent = <&xps_intc_0>;
+ interrupts = < 6 2 >;
+ reg = < 0x81a00000 0x10000 >;
+ xlnx,family = "virtex5";
+ } ;
+ IIC_EEPROM: i2c@81600000 {
+ compatible = "xlnx,xps-iic-2.00.a";
+ interrupt-parent = <&xps_intc_0>;
+ interrupts = < 9 2 >;
+ reg = < 0x81600000 0x10000 >;
+ xlnx,clk-freq = <0x5f5e100>;
+ xlnx,family = "virtex5";
+ xlnx,gpo-width = <0x1>;
+ xlnx,iic-freq = <0x186a0>;
+ xlnx,scl-inertial-delay = <0x5>;
+ xlnx,sda-inertial-delay = <0x5>;
+ xlnx,ten-bit-adr = <0x0>;
+ } ;
+ LCD_OPTIONAL: gpio@81420000 {
+ compatible = "xlnx,xps-gpio-1.00.a";
+ reg = < 0x81420000 0x10000 >;
+ xlnx,all-inputs = <0x0>;
+ xlnx,all-inputs-2 = <0x0>;
+ xlnx,dout-default = <0x0>;
+ xlnx,dout-default-2 = <0x0>;
+ xlnx,family = "virtex5";
+ xlnx,gpio-width = <0xb>;
+ xlnx,interrupt-present = <0x0>;
+ xlnx,is-bidir = <0x1>;
+ xlnx,is-bidir-2 = <0x1>;
+ xlnx,is-dual = <0x0>;
+ xlnx,tri-default = <0xffffffff>;
+ xlnx,tri-default-2 = <0xffffffff>;
+ } ;
+ LEDs_4Bit: gpio@81400000 {
+ compatible = "xlnx,xps-gpio-1.00.a";
+ reg = < 0x81400000 0x10000 >;
+ xlnx,all-inputs = <0x0>;
+ xlnx,all-inputs-2 = <0x0>;
+ xlnx,dout-default = <0x0>;
+ xlnx,dout-default-2 = <0x0>;
+ xlnx,family = "virtex5";
+ xlnx,gpio-width = <0x4>;
+ xlnx,interrupt-present = <0x0>;
+ xlnx,is-bidir = <0x1>;
+ xlnx,is-bidir-2 = <0x1>;
+ xlnx,is-dual = <0x0>;
+ xlnx,tri-default = <0xffffffff>;
+ xlnx,tri-default-2 = <0xffffffff>;
+ } ;
+ RS232_Uart_1: serial@83e00000 {
+ clock-frequency = <100000000>;
+ compatible = "xlnx,xps-uart16550-2.00.b", "ns16550";
+ current-speed = <9600>;
+ device_type = "serial";
+ interrupt-parent = <&xps_intc_0>;
+ interrupts = < 11 2 >;
+ reg = < 0x83e00000 0x10000 >;
+ reg-offset = <0x1003>;
+ reg-shift = <2>;
+ xlnx,family = "virtex5";
+ xlnx,has-external-rclk = <0x0>;
+ xlnx,has-external-xin = <0x0>;
+ xlnx,is-a-16550 = <0x1>;
+ } ;
+ SPI_EEPROM: xps-spi@feff8000 {
+ compatible = "xlnx,xps-spi-2.00.b";
+ interrupt-parent = <&xps_intc_0>;
+ interrupts = < 10 2 >;
+ reg = < 0xfeff8000 0x80 >;
+ xlnx,family = "virtex5";
+ xlnx,fifo-exist = <0x1>;
+ xlnx,num-ss-bits = <0x1>;
+ xlnx,num-transfer-bits = <0x8>;
+ xlnx,sck-ratio = <0x80>;
+ } ;
+ SysACE_CompactFlash: sysace@83600000 {
+ compatible = "xlnx,xps-sysace-1.00.a";
+ interrupt-parent = <&xps_intc_0>;
+ interrupts = < 7 2 >;
+ reg = < 0x83600000 0x10000 >;
+ xlnx,family = "virtex5";
+ xlnx,mem-width = <0x10>;
+ } ;
+ plbv46_pci_0: plbv46-pci@85e00000 {
+ #size-cells = <2>;
+ #address-cells = <3>;
+ compatible = "xlnx,plbv46-pci-1.03.a";
+ device_type = "pci";
+ reg = < 0x85e00000 0x10000 >;
+
+ /*
+ * The default ML510 BSB has C_IPIFBAR2PCIBAR_0 set to
+ * 0 which means that a read/write to the memory mapped
+ * i/o region (which starts at 0xa0000000) for pci
+ * bar 0 on the plb side translates to 0.
+ * It is important to set this value to 0xa0000000, so
+ * that inbound and outbound pci transactions work
+ * properly including DMA.
+ */
+ ranges = <0x02000000 0 0xa0000000 0xa0000000 0 0x20000000
+ 0x01000000 0 0x00000000 0xf0000000 0 0x00010000>;
+
+ #interrupt-cells = <1>;
+ interrupt-parent = <&xps_intc_0>;
+ interrupt-map-mask = <0xff00 0x0 0x0 0x7>;
+ interrupt-map = <
+ /* IRQ mapping for pci slots and ALI M1533
+ * periperhals. In total there are 5 interrupt
+ * lines connected to a xps_intc controller.
+ * Four of them are PCI IRQ A, B, C, D and
+ * which correspond to respectively xpx_intc
+ * 5, 4, 3 and 2. The fifth interrupt line is
+ * connected to the south bridge and this one
+ * uses irq 1 and is active high instead of
+ * active low.
+ *
+ * The M1533 contains various peripherals
+ * including AC97 audio, a modem, USB, IDE and
+ * some power management stuff. The modem
+ * isn't connected on the ML510 and the power
+ * management core also isn't used.
+ */
+
+ /* IDSEL 0x16 / dev=6, bus=0 / PCI slot 3 */
+ 0x3000 0 0 1 &xps_intc_0 3 2
+ 0x3000 0 0 2 &xps_intc_0 2 2
+ 0x3000 0 0 3 &xps_intc_0 5 2
+ 0x3000 0 0 4 &xps_intc_0 4 2
+
+ /* IDSEL 0x13 / dev=3, bus=1 / PCI slot 4 */
+ /*
+ 0x11800 0 0 1 &xps_intc_0 5 0 2
+ 0x11800 0 0 2 &xps_intc_0 4 0 2
+ 0x11800 0 0 3 &xps_intc_0 3 0 2
+ 0x11800 0 0 4 &xps_intc_0 2 0 2
+ */
+
+ /* According to the datasheet + schematic
+ * ABCD [FPGA] of slot 5 is mapped to DABC.
+ * Testing showed that at least A maps to B,
+ * the mapping of the other pins is a guess
+ * and for that reason the lines have been
+ * commented out.
+ */
+ /* IDSEL 0x15 / dev=5, bus=0 / PCI slot 5 */
+ 0x2800 0 0 1 &xps_intc_0 4 2
+ /*
+ 0x2800 0 0 2 &xps_intc_0 3 2
+ 0x2800 0 0 3 &xps_intc_0 2 2
+ 0x2800 0 0 4 &xps_intc_0 5 2
+ */
+
+ /* IDSEL 0x12 / dev=2, bus=1 / PCI slot 6 */
+ /*
+ 0x11000 0 0 1 &xps_intc_0 4 0 2
+ 0x11000 0 0 2 &xps_intc_0 3 0 2
+ 0x11000 0 0 3 &xps_intc_0 2 0 2
+ 0x11000 0 0 4 &xps_intc_0 5 0 2
+ */
+
+ /* IDSEL 0x11 / dev=1, bus=0 / AC97 audio */
+ 0x0800 0 0 1 &i8259 7 2
+
+ /* IDSEL 0x1b / dev=11, bus=0 / IDE */
+ 0x5800 0 0 1 &i8259 14 2
+
+ /* IDSEL 0x1f / dev 15, bus=0 / 2x USB 1.1 */
+ 0x7800 0 0 1 &i8259 7 2
+ >;
+ ali_m1533 {
+ #size-cells = <1>;
+ #address-cells = <2>;
+ i8259: interrupt-controller@20 {
+ reg = <1 0x20 2
+ 1 0xa0 2
+ 1 0x4d0 2>;
+ interrupt-controller;
+ device_type = "interrupt-controller";
+ #address-cells = <0>;
+ #interrupt-cells = <2>;
+ compatible = "chrp,iic";
+
+ /* south bridge irq is active high */
+ interrupts = <1 3>;
+ interrupt-parent = <&xps_intc_0>;
+ };
+ };
+ } ;
+ xps_bram_if_cntlr_1: xps-bram-if-cntlr@ffff0000 {
+ compatible = "xlnx,xps-bram-if-cntlr-1.00.a";
+ reg = < 0xffff0000 0x10000 >;
+ xlnx,family = "virtex5";
+ } ;
+ xps_intc_0: interrupt-controller@81800000 {
+ #interrupt-cells = <0x2>;
+ compatible = "xlnx,xps-intc-1.00.a";
+ interrupt-controller ;
+ reg = < 0x81800000 0x10000 >;
+ xlnx,num-intr-inputs = <0xc>;
+ } ;
+ xps_tft_0: tft@86e00000 {
+ compatible = "xlnx,xps-tft-1.00.a";
+ reg = < 0x86e00000 0x10000 >;
+ xlnx,dcr-splb-slave-if = <0x1>;
+ xlnx,default-tft-base-addr = <0x0>;
+ xlnx,family = "virtex5";
+ xlnx,i2c-slave-addr = <0x76>;
+ xlnx,mplb-awidth = <0x20>;
+ xlnx,mplb-dwidth = <0x80>;
+ xlnx,mplb-native-dwidth = <0x40>;
+ xlnx,mplb-smallest-slave = <0x20>;
+ xlnx,tft-interface = <0x1>;
+ } ;
+ } ;
+} ;
^ permalink raw reply related
* Re: ipr boot failure caused by MSI (2.6.30-rc1+)
From: James Bottomley @ 2009-05-22 16:23 UTC (permalink / raw)
To: Brian King; +Cc: ppc-dev, Wayne Boyer, linux-scsi
In-Reply-To: <1242935515.3007.10.camel@localhost.localdomain>
On Thu, 2009-05-21 at 14:51 -0500, James Bottomley wrote:
> On Thu, 2009-05-21 at 13:47 -0500, Brian King wrote:
> > cc'ing linuxppc-dev...
> >
> > -Brian
> >
> >
> > James Bottomley wrote:
> > > Kernels after 2.6.30-rc1 stopped booting on my powerstation. The ipr
> > > just times out and refuses to probe devices. If I let it drop into the
> > > initramfs system, this is what the interrupts shows:
> > >
> > > (initramfs) cat /proc/interrupts
> > > CPU0 CPU1 CPU2 CPU3
> > > 16: 20 10 13 11 MPIC Level pata_amd
> > > 20: 0 0 0 0 MPIC Level ohci_hcd:usb1, ohci_hcd:usb2
> > > 21: 0 0 0 0 MPIC-U3MSI Edge ipr
> > > 68: 37 37 48 37 MPIC Edge serial
> > > 251: 10 71 69 72 MPIC Edge ipi call function
> > > 252: 1555 1779 1372 1155 MPIC Edge ipi reschedule
> > > 253: 0 0 0 0 MPIC Edge ipi call function single
> > > 254: 0 0 0 0 MPIC Edge ipi debugger
> > > BAD: 416
> > >
> > > So you see the IPR is the only device not receiving them.
> > >
> > > I can fix the boot hang by reverting
> > >
> > > commit 5a9ef25b14d39b8413364df12cb8d9bb7a673a32
> > > Author: Wayne Boyer <wayneb@linux.vnet.ibm.com>
> > > Date: Fri Jan 23 09:17:35 2009 -0800
> > >
> > > [SCSI] ipr: add MSI support
> > >
> > > The system in question is:
> > >
> > > SYSTEM INFORMATION
> > > Processor = PowerPC,970MP @ 2500 MHz
> > > I/O Bridge = U4 (4.4)
> > > SMP Size = 4 (#0 #1 #2 #3)
> > > Boot-Date = 2009-04-21 17:13:36
> > > Memory = 2 GB of RAM @ 666 MHz
> > > Board Type = Bimini (7047191/0000000/1)
> > > MFG Date = 1608
> > > Part No. = 10N8748
> > > FRU No. = 10N7182
> > > FRU Serial = YL30W8106038
> > > UUID = 00000000000000000000000000000000
> > > Flashside = 1 (temporary)
> > > Version = HEAD
> > > Build Date = 12-04-2008 16:13
>
> OK, so as an update, I booted to the initrd and inserted the network
> modules, which are also MSI enabled and this is what I get:
>
> (initramfs) cat /proc/interrupts
> CPU0 CPU1 CPU2 CPU3
> 16: 14 11 11 18 MPIC Level pata_amd
> 20: 0 0 0 0 MPIC Level ohci_hcd:usb1, ohci_hcd:usb2
> 21: 0 0 0 0 MPIC-U3MSI Edge ipr
> 22: 1 0 1 0 MPIC-U3MSI Edge eth0
> 23: 0 2 1 0 MPIC-U3MSI Edge eth1
> 68: 193 166 113 177 MPIC Edge serial
> 251: 16 65 71 70 MPIC Edge ipi call function
> 252: 1574 1804 1346 1289 MPIC Edge ipi reschedule
> 253: 0 0 0 0 MPIC Edge ipi call function single
> 254: 0 0 0 0 MPIC Edge ipi debugger
> BAD: 1866
>
> So clearly the MSI interrupts to the network cards are working and it
> looks like just a local problem with the ipr rather than a platform
> problem with MSI.
I saw the quirk fix for this go by:
http://ozlabs.org/pipermail/linuxppc-dev/2009-May/072436.html
Is there an easy way to trigger an interrupt on this device? Preferably
in ipr_probe_ioa() so we can at least print out if the interrupts are
misrouted and fall back from MSI to normal using the PCI infrastructure?
James
^ permalink raw reply
* Re: [PATCH] Add a few more mpc5200 PSC defines
From: Jon Smirl @ 2009-05-22 16:06 UTC (permalink / raw)
To: Grant Likely; +Cc: linuxppc-dev
In-Reply-To: <fa686aa40905220833m56e7d705n8105813b615df24e@mail.gmail.com>
On Fri, May 22, 2009 at 11:33 AM, Grant Likely
<grant.likely@secretlab.ca> wrote:
> On Fri, May 22, 2009 at 9:25 AM, Jon Smirl <jonsmirl@gmail.com> wrote:
>> Add a few more mpc5200 PSC defines. More bit fields defines for mpc5200 =
PSC registers
>>
>> Signed-off-by: Jon Smirl <jonsmirl@gmail.com>
>
> Thanks Jon,
>
> What are you adding these defines for (so I can add it to the commit log)=
?
AC97 support
>
> g.
>
>> ---
>> =A0arch/powerpc/include/asm/mpc52xx_psc.h | =A0 11 +++++++++++
>> =A01 files changed, 11 insertions(+), 0 deletions(-)
>>
>> diff --git a/arch/powerpc/include/asm/mpc52xx_psc.h b/arch/powerpc/inclu=
de/asm/mpc52xx_psc.h
>> index a218da6..fb84120 100644
>> --- a/arch/powerpc/include/asm/mpc52xx_psc.h
>> +++ b/arch/powerpc/include/asm/mpc52xx_psc.h
>> @@ -28,6 +28,10 @@
>> =A0#define MPC52xx_PSC_MAXNUM =A0 =A0 6
>>
>> =A0/* Programmable Serial Controller (PSC) status register bits */
>> +#define MPC52xx_PSC_SR_UNEX_RX 0x0001
>> +#define MPC52xx_PSC_SR_DATA_VAL =A0 =A0 =A0 =A00x0002
>> +#define MPC52xx_PSC_SR_DATA_OVR =A0 =A0 =A0 =A00x0004
>> +#define MPC52xx_PSC_SR_CMDSEND 0x0008
>> =A0#define MPC52xx_PSC_SR_CDE =A0 =A0 0x0080
>> =A0#define MPC52xx_PSC_SR_RXRDY =A0 0x0100
>> =A0#define MPC52xx_PSC_SR_RXFULL =A00x0200
>> @@ -61,6 +65,12 @@
>> =A0#define MPC52xx_PSC_RXTX_FIFO_EMPTY =A0 =A00x0001
>>
>> =A0/* PSC interrupt status/mask bits */
>> +#define MPC52xx_PSC_IMR_UNEX_RX_SLOT 0x0001
>> +#define MPC52xx_PSC_IMR_DATA_VALID =A0 =A0 0x0002
>> +#define MPC52xx_PSC_IMR_DATA_OVR =A0 =A0 =A0 0x0004
>> +#define MPC52xx_PSC_IMR_CMD_SEND =A0 =A0 =A0 0x0008
>> +#define MPC52xx_PSC_IMR_ERROR =A0 =A0 =A0 =A0 =A00x0040
>> +#define MPC52xx_PSC_IMR_DEOF =A0 =A0 =A0 =A0 =A0 0x0080
>> =A0#define MPC52xx_PSC_IMR_TXRDY =A0 =A0 =A0 =A0 =A00x0100
>> =A0#define MPC52xx_PSC_IMR_RXRDY =A0 =A0 =A0 =A0 =A00x0200
>> =A0#define MPC52xx_PSC_IMR_DB =A0 =A0 =A0 =A0 =A0 =A0 0x0400
>> @@ -117,6 +127,7 @@
>> =A0#define MPC52xx_PSC_SICR_SIM_FIR =A0 =A0 =A0 =A0 =A0 =A0 =A0 (0x6 << =
24)
>> =A0#define MPC52xx_PSC_SICR_SIM_CODEC_24 =A0 =A0 =A0 =A0 =A0(0x7 << 24)
>> =A0#define MPC52xx_PSC_SICR_SIM_CODEC_32 =A0 =A0 =A0 =A0 =A0(0xf << 24)
>> +#define MPC52xx_PSC_SICR_AWR =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 (1 << =
30)
>> =A0#define MPC52xx_PSC_SICR_GENCLK =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =
=A0 =A0 =A0(1 << 23)
>> =A0#define MPC52xx_PSC_SICR_I2S =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 (1 <=
< 22)
>> =A0#define MPC52xx_PSC_SICR_CLKPOL =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =
=A0 =A0 =A0(1 << 21)
>>
>>
>
>
>
> --
> Grant Likely, B.Sc., P.Eng.
> Secret Lab Technologies Ltd.
>
--=20
Jon Smirl
jonsmirl@gmail.com
^ permalink raw reply
* [PATCH] Add a few more mpc5200 PSC defines
From: Jon Smirl @ 2009-05-22 15:25 UTC (permalink / raw)
To: grant.likely, linuxppc-dev
Add a few more mpc5200 PSC defines. More bit fields defines for mpc5200 PSC registers
Signed-off-by: Jon Smirl <jonsmirl@gmail.com>
---
arch/powerpc/include/asm/mpc52xx_psc.h | 11 +++++++++++
1 files changed, 11 insertions(+), 0 deletions(-)
diff --git a/arch/powerpc/include/asm/mpc52xx_psc.h b/arch/powerpc/include/asm/mpc52xx_psc.h
index a218da6..fb84120 100644
--- a/arch/powerpc/include/asm/mpc52xx_psc.h
+++ b/arch/powerpc/include/asm/mpc52xx_psc.h
@@ -28,6 +28,10 @@
#define MPC52xx_PSC_MAXNUM 6
/* Programmable Serial Controller (PSC) status register bits */
+#define MPC52xx_PSC_SR_UNEX_RX 0x0001
+#define MPC52xx_PSC_SR_DATA_VAL 0x0002
+#define MPC52xx_PSC_SR_DATA_OVR 0x0004
+#define MPC52xx_PSC_SR_CMDSEND 0x0008
#define MPC52xx_PSC_SR_CDE 0x0080
#define MPC52xx_PSC_SR_RXRDY 0x0100
#define MPC52xx_PSC_SR_RXFULL 0x0200
@@ -61,6 +65,12 @@
#define MPC52xx_PSC_RXTX_FIFO_EMPTY 0x0001
/* PSC interrupt status/mask bits */
+#define MPC52xx_PSC_IMR_UNEX_RX_SLOT 0x0001
+#define MPC52xx_PSC_IMR_DATA_VALID 0x0002
+#define MPC52xx_PSC_IMR_DATA_OVR 0x0004
+#define MPC52xx_PSC_IMR_CMD_SEND 0x0008
+#define MPC52xx_PSC_IMR_ERROR 0x0040
+#define MPC52xx_PSC_IMR_DEOF 0x0080
#define MPC52xx_PSC_IMR_TXRDY 0x0100
#define MPC52xx_PSC_IMR_RXRDY 0x0200
#define MPC52xx_PSC_IMR_DB 0x0400
@@ -117,6 +127,7 @@
#define MPC52xx_PSC_SICR_SIM_FIR (0x6 << 24)
#define MPC52xx_PSC_SICR_SIM_CODEC_24 (0x7 << 24)
#define MPC52xx_PSC_SICR_SIM_CODEC_32 (0xf << 24)
+#define MPC52xx_PSC_SICR_AWR (1 << 30)
#define MPC52xx_PSC_SICR_GENCLK (1 << 23)
#define MPC52xx_PSC_SICR_I2S (1 << 22)
#define MPC52xx_PSC_SICR_CLKPOL (1 << 21)
^ permalink raw reply related
* Re: [PATCH] Add a few more mpc5200 PSC defines
From: Grant Likely @ 2009-05-22 15:33 UTC (permalink / raw)
To: Jon Smirl; +Cc: linuxppc-dev
In-Reply-To: <20090522152510.20037.26911.stgit@terra>
On Fri, May 22, 2009 at 9:25 AM, Jon Smirl <jonsmirl@gmail.com> wrote:
> Add a few more mpc5200 PSC defines. More bit fields defines for mpc5200 P=
SC registers
>
> Signed-off-by: Jon Smirl <jonsmirl@gmail.com>
Thanks Jon,
What are you adding these defines for (so I can add it to the commit log)?
g.
> ---
> =A0arch/powerpc/include/asm/mpc52xx_psc.h | =A0 11 +++++++++++
> =A01 files changed, 11 insertions(+), 0 deletions(-)
>
> diff --git a/arch/powerpc/include/asm/mpc52xx_psc.h b/arch/powerpc/includ=
e/asm/mpc52xx_psc.h
> index a218da6..fb84120 100644
> --- a/arch/powerpc/include/asm/mpc52xx_psc.h
> +++ b/arch/powerpc/include/asm/mpc52xx_psc.h
> @@ -28,6 +28,10 @@
> =A0#define MPC52xx_PSC_MAXNUM =A0 =A0 6
>
> =A0/* Programmable Serial Controller (PSC) status register bits */
> +#define MPC52xx_PSC_SR_UNEX_RX 0x0001
> +#define MPC52xx_PSC_SR_DATA_VAL =A0 =A0 =A0 =A00x0002
> +#define MPC52xx_PSC_SR_DATA_OVR =A0 =A0 =A0 =A00x0004
> +#define MPC52xx_PSC_SR_CMDSEND 0x0008
> =A0#define MPC52xx_PSC_SR_CDE =A0 =A0 0x0080
> =A0#define MPC52xx_PSC_SR_RXRDY =A0 0x0100
> =A0#define MPC52xx_PSC_SR_RXFULL =A00x0200
> @@ -61,6 +65,12 @@
> =A0#define MPC52xx_PSC_RXTX_FIFO_EMPTY =A0 =A00x0001
>
> =A0/* PSC interrupt status/mask bits */
> +#define MPC52xx_PSC_IMR_UNEX_RX_SLOT 0x0001
> +#define MPC52xx_PSC_IMR_DATA_VALID =A0 =A0 0x0002
> +#define MPC52xx_PSC_IMR_DATA_OVR =A0 =A0 =A0 0x0004
> +#define MPC52xx_PSC_IMR_CMD_SEND =A0 =A0 =A0 0x0008
> +#define MPC52xx_PSC_IMR_ERROR =A0 =A0 =A0 =A0 =A00x0040
> +#define MPC52xx_PSC_IMR_DEOF =A0 =A0 =A0 =A0 =A0 0x0080
> =A0#define MPC52xx_PSC_IMR_TXRDY =A0 =A0 =A0 =A0 =A00x0100
> =A0#define MPC52xx_PSC_IMR_RXRDY =A0 =A0 =A0 =A0 =A00x0200
> =A0#define MPC52xx_PSC_IMR_DB =A0 =A0 =A0 =A0 =A0 =A0 0x0400
> @@ -117,6 +127,7 @@
> =A0#define MPC52xx_PSC_SICR_SIM_FIR =A0 =A0 =A0 =A0 =A0 =A0 =A0 (0x6 << 2=
4)
> =A0#define MPC52xx_PSC_SICR_SIM_CODEC_24 =A0 =A0 =A0 =A0 =A0(0x7 << 24)
> =A0#define MPC52xx_PSC_SICR_SIM_CODEC_32 =A0 =A0 =A0 =A0 =A0(0xf << 24)
> +#define MPC52xx_PSC_SICR_AWR =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 (1 << 3=
0)
> =A0#define MPC52xx_PSC_SICR_GENCLK =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =
=A0 =A0 =A0(1 << 23)
> =A0#define MPC52xx_PSC_SICR_I2S =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 (1 <<=
22)
> =A0#define MPC52xx_PSC_SICR_CLKPOL =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =
=A0 =A0 =A0(1 << 21)
>
>
--=20
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.
^ permalink raw reply
* Re: [net-next-2.6 PATCH v2] can: SJA1000: generic OF platform bus driver
From: Grant Likely @ 2009-05-22 15:08 UTC (permalink / raw)
To: Wolfgang Grandegger; +Cc: Linux Netdev List, devicetree-discuss, linuxppc-dev
In-Reply-To: <4A16BAAE.3070401@grandegger.com>
Hi Wolfgang, thanks for the quick response. Comments below...
On Fri, May 22, 2009 at 8:46 AM, Wolfgang Grandegger <wg@grandegger.com> wr=
ote:
> +++ net-next-2.6/Documentation/powerpc/dts-bindings/can/sja1000.txt
> @@ -0,0 +1,37 @@
> +Memory mapped SJA1000 CAN controller from NXP (formerly Philips)
> +
> +Required properties:
> +
> +- compatible : should be "nxp,sja1000".
> +- reg : should specify the chip select, address offset and size used
> + =A0 =A0 =A0 for the chip depending on the bus it is connected to.
> +- interrupts: property with a value describing the interrupt source
> + =A0 =A0 =A0 (number and sensitivity) for that device. The encoding depe=
nds
> + =A0 =A0 =A0 on the type of interrupt controller used.
Hmmm, "reg", "interrupts", and "interrupt-parent" are well understood
properties. I don't think we need to keep boilerplate defining the
meaning every time a new binding is added. (general musing; not an
ack or nack of this patch)
However, what should be defined is *what* the register range is (ie.
one tuple; location of device registers), and what the interrupts are
(ie. single tuple for device's irq line). Granted this is a trivial
case, but in the case of devices with more than one address range or
irq line, the meaning of each tuple is critical information. I think
it would be a good pattern to establish.
> +Optional properties:
> +
> +- interrupt-parent : the phandle for the interrupt controller that
> + =A0 =A0 =A0 services interrupts for that device.
Thinking further; I wouldn't even mention "interrupt-parent" here.
Anyone working with this stuff must already understand irq routing.
> +- clock-frequency : CAN system clock frequency in Hz, which is normally
> + =A0 =A0 =A0 half of the oscillator clock frequency. If not specified, a
> + =A0 =A0 =A0 default value of 8000000 (8 MHz) is used.
A clock-frequency property typically refers to the bus clock
frequency. Something like can-frequency would be better.
> +- cdr-reg : value of the SJA1000 clock divider register according to
> + =A0 =A0 =A0 the SJA1000 data sheet. If not specified, a default value o=
f
> + =A0 =A0 =A0 0x48 is used.
Ewh. The driver should be clueful enough to derive the clock divider
value given both the bus and can frequencies. I don't like this
property.
> +- ocr-reg : value of the SJA1000 output control register according to
> + =A0 =A0 =A0 the SJA1000 data sheet. If not specified, a default value o=
f
> + =A0 =A0 =A0 0x0a is used.
Ditto here; the binding should describe the usage mode; not the
register settings to get the usage mode. What sort of settings will
the .dts author be writing here?
Cheers,
g.
--=20
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.
^ permalink raw reply
* Re: [net-next-2.6 PATCH] can: SJA1000: generic OF platform bus driver
From: Wolfgang Grandegger @ 2009-05-22 14:47 UTC (permalink / raw)
To: David Miller; +Cc: netdev, devicetree-discuss, Linuxppc-dev
In-Reply-To: <20090521.233123.135354184.davem@davemloft.net>
David Miller wrote:
> From: Grant Likely <grant.likely@secretlab.ca>
> Date: Thu, 21 May 2009 22:42:07 -0600
>
>> On Wed, May 20, 2009 at 11:06 AM, Wolfgang Grandegger <wg@grandegger.com> wrote:
>>> This patch adds a generic driver for SJA1000 chips on the OpenFirmware
>>> platform bus found on embedded PowerPC systems. You need a SJA1000 node
>>> definition in your flattened device tree source (DTS) file similar to:
>>>
>>> can@3,100 {
>>> compatible = "philips,sja1000";
>>> reg = <3 0x100 0x80>;
>>> clock-frequency = <8000000>;
>>> cdr-reg = <0x48>;
>>> ocr-reg = <0x0a>;
>>> interrupts = <2 0>;
>>> interrupt-parent = <&mpic>;
>>> };
>> This new binding must be documented in Documentation/powerpc/dts-bindings
>
> Wolfgang, please add this documentation and resubmit your patch.
> Thanks!
I just sent out v2 incuding the missing documentation.
Thanks,
Wolfgang.
^ permalink raw reply
* [net-next-2.6 PATCH v2] can: SJA1000: generic OF platform bus driver
From: Wolfgang Grandegger @ 2009-05-22 14:46 UTC (permalink / raw)
To: Linux Netdev List; +Cc: linuxppc-dev, devicetree-discuss
This patch adds a generic driver for SJA1000 chips on the OpenFirmware
platform bus found on embedded PowerPC systems. You need a SJA1000 node
definition in your flattened device tree source (DTS) file similar to:
can@3,100 {
compatible = "nxp,sja1000";
reg = <3 0x100 0x80>;
clock-frequency = <8000000>;
cdr-reg = <0x48>;
ocr-reg = <0x0a>;
interrupts = <2 0>;
interrupt-parent = <&mpic>;
};
See also Documentation/powerpc/dts-bindings/can/sja1000.txt.
Signed-off-by: Wolfgang Grandegger <wg@grandegger.com>
---
Documentation/powerpc/dts-bindings/can/sja1000.txt | 37 +++
drivers/net/can/Kconfig | 9
drivers/net/can/sja1000/Makefile | 1
drivers/net/can/sja1000/sja1000_of_platform.c | 215 +++++++++++++++++++++
4 files changed, 262 insertions(+)
Index: net-next-2.6/drivers/net/can/Kconfig
===================================================================
--- net-next-2.6.orig/drivers/net/can/Kconfig
+++ net-next-2.6/drivers/net/can/Kconfig
@@ -51,6 +51,15 @@ config CAN_SJA1000_PLATFORM
boards from Phytec (http://www.phytec.de) like the PCM027,
PCM038.
+config CAN_SJA1000_OF_PLATFORM
+ depends on CAN_SJA1000 && PPC_OF
+ tristate "Generic OF Platform Bus based SJA1000 driver"
+ ---help---
+ This driver adds support for the SJA1000 chips connected to
+ the OpenFirmware "platform bus" found on embedded systems with
+ OpenFirmware bindings, e.g. if you have a PowerPC based system
+ you may want to enable this option.
+
config CAN_EMS_PCI
tristate "EMS CPC-PCI and CPC-PCIe Card"
depends on PCI && CAN_SJA1000
Index: net-next-2.6/drivers/net/can/sja1000/Makefile
===================================================================
--- net-next-2.6.orig/drivers/net/can/sja1000/Makefile
+++ net-next-2.6/drivers/net/can/sja1000/Makefile
@@ -4,6 +4,7 @@
obj-$(CONFIG_CAN_SJA1000) += sja1000.o
obj-$(CONFIG_CAN_SJA1000_PLATFORM) += sja1000_platform.o
+obj-$(CONFIG_CAN_SJA1000_OF_PLATFORM) += sja1000_of_platform.o
obj-$(CONFIG_CAN_EMS_PCI) += ems_pci.o
obj-$(CONFIG_CAN_KVASER_PCI) += kvaser_pci.o
Index: net-next-2.6/drivers/net/can/sja1000/sja1000_of_platform.c
===================================================================
--- /dev/null
+++ net-next-2.6/drivers/net/can/sja1000/sja1000_of_platform.c
@@ -0,0 +1,215 @@
+/*
+ * Driver for SJA1000 CAN controllers on the OpenFirmware platform bus
+ *
+ * Copyright (C) 2008-2009 Wolfgang Grandegger <wg@grandegger.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the version 2 of the GNU General Public License
+ * as published by the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/* This is a generic driver for SJA1000 chips on the OpenFirmware platform
+ * bus found on embedded PowerPC systems. You need a SJA1000 CAN node
+ * definition in your flattened device tree source (DTS) file similar to:
+ *
+ * can@3,100 {
+ * compatible = "philips,sja1000";
+ * reg = <3 0x100 0x80>;
+ * clock-frequency = <8000000>;
+ * cdr-reg = <0x48>;
+ * ocr-reg = <0x0a>;
+ * interrupts = <2 0>;
+ * interrupt-parent = <&mpic>;
+ * };
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/netdevice.h>
+#include <linux/delay.h>
+#include <linux/can.h>
+#include <linux/can/dev.h>
+
+#include <linux/of_platform.h>
+#include <asm/prom.h>
+
+#include "sja1000.h"
+
+#define DRV_NAME "sja1000_of_platform"
+
+MODULE_AUTHOR("Wolfgang Grandegger <wg@grandegger.com>");
+MODULE_DESCRIPTION("Socket-CAN driver for SJA1000 on the OF platform bus");
+MODULE_LICENSE("GPL v2");
+
+#define SJA1000_OFP_CAN_CLOCK (16000000 / 2)
+
+#define SJA1000_OFP_OCR OCR_TX0_PULLDOWN
+#define SJA1000_OFP_CDR (CDR_CBP | CDR_CLK_OFF)
+
+static u8 sja1000_ofp_read_reg(const struct net_device *dev, int reg)
+{
+ return in_8((void __iomem *)(dev->base_addr + reg));
+}
+
+static void sja1000_ofp_write_reg(const struct net_device *dev, int reg, u8 val)
+{
+ out_8((void __iomem *)(dev->base_addr + reg), val);
+}
+
+static int __devexit sja1000_ofp_remove(struct of_device *ofdev)
+{
+ struct net_device *dev = dev_get_drvdata(&ofdev->dev);
+ struct device_node *np = ofdev->node;
+ struct resource res;
+
+ dev_set_drvdata(&ofdev->dev, NULL);
+
+ unregister_sja1000dev(dev);
+ free_sja1000dev(dev);
+ iounmap((void __iomem *)dev->base_addr);
+ irq_dispose_mapping(dev->irq);
+
+ of_address_to_resource(np, 0, &res);
+ release_mem_region(res.start, resource_size(&res));
+
+ return 0;
+}
+
+static int __devinit sja1000_ofp_probe(struct of_device *ofdev,
+ const struct of_device_id *id)
+{
+ struct device_node *np = ofdev->node;
+ struct net_device *dev;
+ struct sja1000_priv *priv;
+ struct resource res;
+ const u32 *prop;
+ int err, irq, res_size, prop_size;
+ void __iomem *base;
+
+ err = of_address_to_resource(np, 0, &res);
+ if (err) {
+ dev_err(&ofdev->dev, "invalid address\n");
+ return err;
+ }
+
+ res_size = resource_size(&res);
+
+ if (!request_mem_region(res.start, res_size, DRV_NAME)) {
+ dev_err(&ofdev->dev, "couldn't request %#x..%#x\n",
+ res.start, res.end);
+ return -EBUSY;
+ }
+
+ base = ioremap_nocache(res.start, res_size);
+ if (!base) {
+ dev_err(&ofdev->dev, "couldn't ioremap %#x..%#x\n",
+ res.start, res.end);
+ err = -ENOMEM;
+ goto exit_release_mem;
+ }
+
+ irq = irq_of_parse_and_map(np, 0);
+ if (irq == NO_IRQ) {
+ dev_err(&ofdev->dev, "no irq found\n");
+ err = -ENODEV;
+ goto exit_unmap_mem;
+ }
+
+ dev = alloc_sja1000dev(0);
+ if (!dev) {
+ err = -ENOMEM;
+ goto exit_dispose_irq;
+ }
+
+ priv = netdev_priv(dev);
+
+ priv->read_reg = sja1000_ofp_read_reg;
+ priv->write_reg = sja1000_ofp_write_reg;
+
+ prop = of_get_property(np, "clock-frequency", &prop_size);
+ if (prop && (prop_size == sizeof(u32)))
+ priv->can.clock.freq = *prop;
+ else
+ priv->can.clock.freq = SJA1000_OFP_CAN_CLOCK;
+
+ prop = of_get_property(np, "ocr-reg", &prop_size);
+ if (prop && (prop_size == sizeof(u32)))
+ priv->ocr = (u8)*prop;
+ else
+ priv->ocr = SJA1000_OFP_OCR;
+
+ prop = of_get_property(np, "cdr-reg", &prop_size);
+ if (prop && (prop_size == sizeof(u32)))
+ priv->cdr = (u8)*prop;
+ else
+ priv->cdr = SJA1000_OFP_CDR;
+
+ priv->irq_flags = IRQF_SHARED;
+
+ dev->irq = irq;
+ dev->base_addr = (unsigned long)base;
+
+ dev_info(&ofdev->dev,
+ "base=0x%lx irq=%d clock=%d ocr=0x%02x cdr=0x%02x\n",
+ dev->base_addr, dev->irq, priv->can.clock.freq,
+ priv->ocr, priv->cdr);
+
+ dev_set_drvdata(&ofdev->dev, dev);
+ SET_NETDEV_DEV(dev, &ofdev->dev);
+
+ err = register_sja1000dev(dev);
+ if (err) {
+ dev_err(&ofdev->dev, "registering %s failed (err=%d)\n",
+ DRV_NAME, err);
+ goto exit_free_sja1000;
+ }
+
+ return 0;
+
+exit_free_sja1000:
+ free_sja1000dev(dev);
+exit_dispose_irq:
+ irq_dispose_mapping(irq);
+exit_unmap_mem:
+ iounmap(base);
+exit_release_mem:
+ release_mem_region(res.start, res_size);
+
+ return err;
+}
+
+static struct of_device_id __devinitdata sja1000_ofp_table[] = {
+ {.compatible = "philips,sja1000"},
+ {.compatible = "nxp,sja1000"},
+ {},
+};
+
+static struct of_platform_driver sja1000_ofp_driver = {
+ .owner = THIS_MODULE,
+ .name = DRV_NAME,
+ .probe = sja1000_ofp_probe,
+ .remove = __devexit_p(sja1000_ofp_remove),
+ .match_table = sja1000_ofp_table,
+};
+
+static int __init sja1000_ofp_init(void)
+{
+ return of_register_platform_driver(&sja1000_ofp_driver);
+}
+module_init(sja1000_ofp_init);
+
+static void __exit sja1000_ofp_exit(void)
+{
+ return of_unregister_platform_driver(&sja1000_ofp_driver);
+};
+module_exit(sja1000_ofp_exit);
Index: net-next-2.6/Documentation/powerpc/dts-bindings/can/sja1000.txt
===================================================================
--- /dev/null
+++ net-next-2.6/Documentation/powerpc/dts-bindings/can/sja1000.txt
@@ -0,0 +1,37 @@
+Memory mapped SJA1000 CAN controller from NXP (formerly Philips)
+
+Required properties:
+
+- compatible : should be "nxp,sja1000".
+- reg : should specify the chip select, address offset and size used
+ for the chip depending on the bus it is connected to.
+- interrupts: property with a value describing the interrupt source
+ (number and sensitivity) for that device. The encoding depends
+ on the type of interrupt controller used.
+
+Optional properties:
+
+- interrupt-parent : the phandle for the interrupt controller that
+ services interrupts for that device.
+- clock-frequency : CAN system clock frequency in Hz, which is normally
+ half of the oscillator clock frequency. If not specified, a
+ default value of 8000000 (8 MHz) is used.
+- cdr-reg : value of the SJA1000 clock divider register according to
+ the SJA1000 data sheet. If not specified, a default value of
+ 0x48 is used.
+- ocr-reg : value of the SJA1000 output control register according to
+ the SJA1000 data sheet. If not specified, a default value of
+ 0x0a is used.
+
+Examples:
+
+can@3,100 {
+ compatible = "nxp,sja1000";
+ reg = <3 0x100 0x80>;
+ clock-frequency = <8000000>;
+ cdr-reg = <0x48>;
+ ocr-reg = <0x0a>;
+ interrupts = <2 0>;
+ interrupt-parent = <&mpic>;
+};
+
^ permalink raw reply
* Re: [PATCH] mpc52xx_psc_spi: Convert to cs_control callback
From: Jon Smirl @ 2009-05-22 13:29 UTC (permalink / raw)
To: Anton Vorontsov
Cc: linuxppc-dev, Andrew Morton, David Brownell, spi-devel-general
In-Reply-To: <20090430223114.GA12571@oksana.dev.rtsoft.ru>
On Thu, Apr 30, 2009 at 6:31 PM, Anton Vorontsov
<avorontsov@ru.mvista.com> wrote:
> mpc52xx_psc_spi driver is the last user of the legacy activate_cs
> and deactivate_cs callbacks, so convert the driver to the cs_control
This driver is missing a call to of_register_spi_devices(master, op->node);
Here's how I added it, but it could be done more cleanly.
diff --git a/drivers/spi/mpc52xx_psc_spi.c b/drivers/spi/mpc52xx_psc_spi.c
index 68c77a9..fe0658a 100644
--- a/drivers/spi/mpc52xx_psc_spi.c
+++ b/drivers/spi/mpc52xx_psc_spi.c
@@ -22,6 +22,7 @@
#include <linux/delay.h>
#include <linux/spi/spi.h>
#include <linux/fsl_devices.h>
+#include <linux/of_spi.h>
#include <asm/mpc52xx.h>
#include <asm/mpc52xx_psc.h>
@@ -370,24 +371,24 @@ static irqreturn_t mpc52xx_psc_spi_isr(int irq,
void *dev_id)
}
/* bus_num is used only for the case dev->platform_data == NULL */
-static int __init mpc52xx_psc_spi_do_probe(struct device *dev, u32 regaddr,
+static int __init mpc52xx_psc_spi_do_probe(struct of_device *op, u32 regaddr,
u32 size, unsigned int irq, s16 bus_num)
{
- struct fsl_spi_platform_data *pdata = dev->platform_data;
+ struct fsl_spi_platform_data *pdata = op->dev.platform_data;
struct mpc52xx_psc_spi *mps;
struct spi_master *master;
int ret;
- master = spi_alloc_master(dev, sizeof *mps);
+ master = spi_alloc_master(&op->dev, sizeof *mps);
if (master == NULL)
return -ENOMEM;
- dev_set_drvdata(dev, master);
+ dev_set_drvdata(&op->dev, master);
mps = spi_master_get_devdata(master);
mps->irq = irq;
if (pdata == NULL) {
- dev_warn(dev, "probe called without platform data, no "
+ dev_warn(&op->dev, "probe called without platform data, no "
"(de)activate_cs function will be called\n");
mps->activate_cs = NULL;
mps->deactivate_cs = NULL;
@@ -407,7 +408,7 @@ static int __init mpc52xx_psc_spi_do_probe(struct
device *dev, u32 regaddr,
mps->psc = ioremap(regaddr, size);
if (!mps->psc) {
- dev_err(dev, "could not ioremap I/O port range\n");
+ dev_err(&op->dev, "could not ioremap I/O port range\n");
ret = -EFAULT;
goto free_master;
}
@@ -439,6 +440,8 @@ static int __init mpc52xx_psc_spi_do_probe(struct
device *dev, u32 regaddr,
if (ret < 0)
goto unreg_master;
+ of_register_spi_devices(master, op->node);
+
return ret;
unreg_master:
@@ -495,7 +498,7 @@ static int __init mpc52xx_psc_spi_of_probe(struct
of_device *op,
id = *psc_nump + 1;
}
- return mpc52xx_psc_spi_do_probe(&op->dev, (u32)regaddr64, (u32)size64,
+ return mpc52xx_psc_spi_do_probe(op, (u32)regaddr64, (u32)size64,
irq_of_parse_and_map(op->node, 0), id);
}
--
Jon Smirl
jonsmirl@gmail.com
^ permalink raw reply related
* Re: [PATCH] mmc: Add fsl,esdhc as a valid compatible to bind against
From: Pierre Ossman @ 2009-05-22 11:53 UTC (permalink / raw)
To: Kumar Gala; +Cc: linuxppc-dev, linux-kernel
In-Reply-To: <1241790769-3843-1-git-send-email-galak@kernel.crashing.org>
[-- Attachment #1: Type: text/plain, Size: 504 bytes --]
On Fri, 8 May 2009 08:52:49 -0500
Kumar Gala <galak@kernel.crashing.org> wrote:
> We plan to use fsl,esdhc going forward as the base compatible so update
> the driver to bind against it.
>
> Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
> ---
Applied.
Rgds
--
-- Pierre Ossman
WARNING: This correspondence is being monitored by the
Swedish government. Make sure your server uses encryption
for SMTP traffic and consider using PGP for end-to-end
encryption.
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 198 bytes --]
^ permalink raw reply
* Re: [PATCH V2 2/3] powerpc: Add support for swiotlb on 32-bit
From: Ian Campbell @ 2009-05-22 11:11 UTC (permalink / raw)
To: Becky Bruce
Cc: FUJITA Tomonori, linuxppc-dev@ozlabs.org, Jeremy Fitzhardinge,
linux-kernel@vger.kernel.org
In-Reply-To: <E6DAA792-9923-4B76-9759-6955AABE3EAB@kernel.crashing.org>
On Thu, 2009-05-21 at 14:27 -0400, Becky Bruce wrote:
> I can work with that, but it's going to be a bit inefficient, as I
> actually need the dma_addr_t, not the phys_addr_t, so I'll have to
> convert. In every case, this is a conversion I've already done and
> that I need in the calling code as well.
Does
dma_addr_t dma_map_range(struct device *hwdev, phys_addr_t addr,
size_t size);
work for you?
If the range does not need mapping then it returns the dma address, if
you needed to calculate the dma address anyway to figure out if mapping
is required then this is fine. If the range does need mapping then it
returns NULL.
This subsumes many of the phys->dma address conversions which would
otherwise be done in the callers. IMHO this is an architecture specific
detail which should be pushed down into the arch code as much as
possible. The only ones which I don't think can be pushed down are the
ones in swiotlb_virt_to_bus/swiotlb_bus_to_virt.
BTW do you need swiotlb_bus_to_virt to be __weak or is the fact that it
is implemented in terms of swiotlb_bus_to_phys sufficient?
I have an appointment all afternoon and it's a bank holiday on Monday
but here is my WIP patch as an example of what I'm thinking. Obviously
some cleanups are still very much required:
* The Xen specific stuff in arch/x86/include/asm/dma-mapping.h
clearly needs to be properly abstracted away (I just stuck it
there for testing).
* swiotlb_phys_to_bus and swiotlb_bus_to_phys need to move to
arch/*/include/asm/dma-mapping.h instead of being __weak
* Maybe swiotlb_bus_to_virt can become static again.
* Need to finish auditing the handful of non-swiotlb users of
is_buffer_dma_capable.
* It might be possible to implement swiolb_dma_mapping_error
and/or swiotlb_dma_supported in terms of dma_map_range.
* Minor detail: it doesn't actually work at the moment ;-)
Ian.
diff --git a/arch/ia64/include/asm/dma-mapping.h b/arch/ia64/include/asm/dma-mapping.h
index 36c0009..026667f 100644
--- a/arch/ia64/include/asm/dma-mapping.h
+++ b/arch/ia64/include/asm/dma-mapping.h
@@ -174,4 +174,12 @@ dma_cache_sync (struct device *dev, void *vaddr, size_t size,
#define dma_is_consistent(d, h) (1) /* all we do is coherent memory... */
+static inline dma_addr_t dma_map_range(struct device *dev, u64 mask,
+ phys_addr_t addr, size_t size)
+{
+ if (addr + size <= mask)
+ return addr;
+ return 0;
+}
+
#endif /* _ASM_IA64_DMA_MAPPING_H */
diff --git a/arch/x86/include/asm/dma-mapping.h b/arch/x86/include/asm/dma-mapping.h
index 916cbb6..b2813ab 100644
--- a/arch/x86/include/asm/dma-mapping.h
+++ b/arch/x86/include/asm/dma-mapping.h
@@ -309,4 +309,20 @@ static inline void dma_free_coherent(struct device *dev, size_t size,
ops->free_coherent(dev, size, vaddr, bus);
}
+static inline dma_addr_t dma_map_range(struct device *dev, u64 mask,
+ phys_addr_t addr, size_t size)
+{
+ dma_addr_t dma_addr;
+#ifdef CONFIG_XEN
+ extern int xen_range_needs_mapping(phys_addr_t paddr, size_t size);
+ if (xen_pv_domain() && xen_range_needs_mapping(addr, size))
+ return 0;
+#endif
+
+ dma_addr = swiotlb_phys_to_bus(dev, addr);
+ if (dma_addr + size <= mask)
+ return 0;
+ return dma_addr;
+}
+
#endif
diff --git a/arch/x86/kernel/pci-dma.c b/arch/x86/kernel/pci-dma.c
index 2fffc22..c2b4196 100644
--- a/arch/x86/kernel/pci-dma.c
+++ b/arch/x86/kernel/pci-dma.c
@@ -145,8 +145,8 @@ again:
if (!page)
return NULL;
- addr = page_to_phys(page);
- if (!is_buffer_dma_capable(dma_mask, addr, size)) {
+ addr = dma_map_range(dev, dma_mask, page_to_phys(page), size);
+ if (!(addr == 0)) {
__free_pages(page, get_order(size));
if (dma_mask < DMA_BIT_MASK(32) && !(flag & GFP_DMA)) {
diff --git a/arch/x86/kernel/pci-gart_64.c b/arch/x86/kernel/pci-gart_64.c
index 1e8920d..6a55770 100644
--- a/arch/x86/kernel/pci-gart_64.c
+++ b/arch/x86/kernel/pci-gart_64.c
@@ -191,13 +191,13 @@ static inline int
need_iommu(struct device *dev, unsigned long addr, size_t size)
{
return force_iommu ||
- !is_buffer_dma_capable(*dev->dma_mask, addr, size);
+ dma_map_range(dev, *dev->dma_mask, addr, size) == 0;
}
static inline int
nonforced_iommu(struct device *dev, unsigned long addr, size_t size)
{
- return !is_buffer_dma_capable(*dev->dma_mask, addr, size);
+ return dma_map_range(dev, *dev->dma_mask, addr, size) == 0;
}
/* Map a single continuous physical area into the IOMMU.
diff --git a/arch/x86/kernel/pci-nommu.c b/arch/x86/kernel/pci-nommu.c
index 71d412a..712ce59 100644
--- a/arch/x86/kernel/pci-nommu.c
+++ b/arch/x86/kernel/pci-nommu.c
@@ -12,13 +12,13 @@
#include <asm/dma.h>
static int
-check_addr(char *name, struct device *hwdev, dma_addr_t bus, size_t size)
+check_addr(char *name, struct device *hwdev, phys_addr_t phys, size_t size)
{
- if (hwdev && !is_buffer_dma_capable(*hwdev->dma_mask, bus, size)) {
+ if (hwdev && dma_map_range(hwdev, *hwdev->dma_mask, phys, size) == 0) {
if (*hwdev->dma_mask >= DMA_BIT_MASK(32))
printk(KERN_ERR
"nommu_%s: overflow %Lx+%zu of device mask %Lx\n",
- name, (long long)bus, size,
+ name, (long long)phys, size,
(long long)*hwdev->dma_mask);
return 0;
}
@@ -30,12 +30,12 @@ static dma_addr_t nommu_map_page(struct device *dev, struct page *page,
enum dma_data_direction dir,
struct dma_attrs *attrs)
{
- dma_addr_t bus = page_to_phys(page) + offset;
+ phys_addr_t phys = page_to_phys(page) + offset;
WARN_ON(size == 0);
- if (!check_addr("map_single", dev, bus, size))
+ if (!check_addr("map_single", dev, phys, size))
return bad_dma_address;
flush_write_buffers();
- return bus;
+ return phys;
}
/* Map a set of buffers described by scatterlist in streaming
diff --git a/include/linux/dma-mapping.h b/include/linux/dma-mapping.h
index 8083b6a..85dafa1 100644
--- a/include/linux/dma-mapping.h
+++ b/include/linux/dma-mapping.h
@@ -96,11 +96,6 @@ static inline int is_device_dma_capable(struct device *dev)
return dev->dma_mask != NULL && *dev->dma_mask != DMA_MASK_NONE;
}
-static inline int is_buffer_dma_capable(u64 mask, dma_addr_t addr, size_t size)
-{
- return addr + size <= mask;
-}
-
#ifdef CONFIG_HAS_DMA
#include <asm/dma-mapping.h>
#else
diff --git a/lib/swiotlb.c b/lib/swiotlb.c
index cec5f62..4fd5185 100644
--- a/lib/swiotlb.c
+++ b/lib/swiotlb.c
@@ -147,17 +147,6 @@ void * __weak swiotlb_bus_to_virt(struct device *hwdev, dma_addr_t address)
return phys_to_virt(swiotlb_bus_to_phys(hwdev, address));
}
-int __weak swiotlb_arch_address_needs_mapping(struct device *hwdev,
- dma_addr_t addr, size_t size)
-{
- return !is_buffer_dma_capable(dma_get_mask(hwdev), addr, size);
-}
-
-int __weak swiotlb_arch_range_needs_mapping(phys_addr_t paddr, size_t size)
-{
- return 0;
-}
-
static void swiotlb_print_info(unsigned long bytes)
{
phys_addr_t pstart, pend;
@@ -318,17 +307,6 @@ cleanup1:
return -ENOMEM;
}
-static inline int
-address_needs_mapping(struct device *hwdev, dma_addr_t addr, size_t size)
-{
- return swiotlb_arch_address_needs_mapping(hwdev, addr, size);
-}
-
-static inline int range_needs_mapping(phys_addr_t paddr, size_t size)
-{
- return swiotlb_force || swiotlb_arch_range_needs_mapping(paddr, size);
-}
-
static int is_swiotlb_buffer(char *addr)
{
return addr >= io_tlb_start && addr < io_tlb_end;
@@ -555,18 +533,17 @@ void *
swiotlb_alloc_coherent(struct device *hwdev, size_t size,
dma_addr_t *dma_handle, gfp_t flags)
{
- dma_addr_t dev_addr;
+ phys_addr_t phys;
void *ret;
int order = get_order(size);
u64 dma_mask = DMA_BIT_MASK(32);
+ dma_addr_t dma_addr;
if (hwdev && hwdev->coherent_dma_mask)
dma_mask = hwdev->coherent_dma_mask;
ret = (void *)__get_free_pages(flags, order);
- if (ret &&
- !is_buffer_dma_capable(dma_mask, swiotlb_virt_to_bus(hwdev, ret),
- size)) {
+ if (ret && dma_map_range(hwdev, dma_mask, virt_to_phys(ret), size) == 0) {
/*
* The allocated memory isn't reachable by the device.
*/
@@ -585,19 +562,20 @@ swiotlb_alloc_coherent(struct device *hwdev, size_t size,
}
memset(ret, 0, size);
- dev_addr = swiotlb_virt_to_bus(hwdev, ret);
+ phys = virt_to_phys(ret);
/* Confirm address can be DMA'd by device */
- if (!is_buffer_dma_capable(dma_mask, dev_addr, size)) {
- printk("hwdev DMA mask = 0x%016Lx, dev_addr = 0x%016Lx\n",
+ dma_addr = dma_map_range(hwdev, dma_mask, phys, size);
+ if (dma_addr == 0) {
+ printk("hwdev DMA mask = 0x%016Lx, physical addr = 0x%016Lx\n",
(unsigned long long)dma_mask,
- (unsigned long long)dev_addr);
+ (unsigned long long)phys);
/* DMA_TO_DEVICE to avoid memcpy in unmap_single */
do_unmap_single(hwdev, ret, size, DMA_TO_DEVICE);
return NULL;
}
- *dma_handle = dev_addr;
+ *dma_handle = dma_addr;
return ret;
}
EXPORT_SYMBOL(swiotlb_alloc_coherent);
@@ -649,7 +627,7 @@ dma_addr_t swiotlb_map_page(struct device *dev, struct page *page,
struct dma_attrs *attrs)
{
phys_addr_t phys = page_to_phys(page) + offset;
- dma_addr_t dev_addr = swiotlb_phys_to_bus(dev, phys);
+ dma_addr_t dma_addr;
void *map;
BUG_ON(dir == DMA_NONE);
@@ -658,9 +636,9 @@ dma_addr_t swiotlb_map_page(struct device *dev, struct page *page,
* we can safely return the device addr and not worry about bounce
* buffering it.
*/
- if (!address_needs_mapping(dev, dev_addr, size) &&
- !range_needs_mapping(phys, size))
- return dev_addr;
+ dma_addr = dma_map_range(dev, dma_get_mask(dev), phys, size);
+ if (dma_addr && !swiotlb_force)
+ return dma_addr;
/*
* Oh well, have to allocate and map a bounce buffer.
@@ -671,15 +649,14 @@ dma_addr_t swiotlb_map_page(struct device *dev, struct page *page,
map = io_tlb_overflow_buffer;
}
- dev_addr = swiotlb_virt_to_bus(dev, map);
-
/*
* Ensure that the address returned is DMA'ble
*/
- if (address_needs_mapping(dev, dev_addr, size))
+ dma_addr = dma_map_range(dev, dma_get_mask(dev), virt_to_phys(map), size);
+ if (dma_addr == 0)
panic("map_single: bounce buffer is not DMA'ble");
- return dev_addr;
+ return dma_addr;
}
EXPORT_SYMBOL_GPL(swiotlb_map_page);
@@ -820,10 +797,8 @@ swiotlb_map_sg_attrs(struct device *hwdev, struct scatterlist *sgl, int nelems,
for_each_sg(sgl, sg, nelems, i) {
phys_addr_t paddr = sg_phys(sg);
- dma_addr_t dev_addr = swiotlb_phys_to_bus(hwdev, paddr);
-
- if (range_needs_mapping(paddr, sg->length) ||
- address_needs_mapping(hwdev, dev_addr, sg->length)) {
+ dma_addr_t dma_addr = dma_map_range(hwdev, dma_get_mask(hwdev), paddr, sg->length);
+ if (dma_addr == 0 || swiotlb_force) {
void *map = map_single(hwdev, sg_phys(sg),
sg->length, dir);
if (!map) {
@@ -835,9 +810,9 @@ swiotlb_map_sg_attrs(struct device *hwdev, struct scatterlist *sgl, int nelems,
sgl[0].dma_length = 0;
return 0;
}
- sg->dma_address = swiotlb_virt_to_bus(hwdev, map);
- } else
- sg->dma_address = dev_addr;
+ dma_addr = dma_map_range(hwdev, dma_get_mask(hwdev), virt_to_phys(map), sg->length);
+ }
+ sg->dma_address = dma_addr;
sg->dma_length = sg->length;
}
return nelems;
^ permalink raw reply related
* Re: [PATCH V2 2/3] powerpc: Add support for swiotlb on 32-bit
From: FUJITA Tomonori @ 2009-05-22 10:51 UTC (permalink / raw)
To: jeremy; +Cc: fujita.tomonori, linuxppc-dev, linux-kernel, Ian.Campbell
In-Reply-To: <4A15B72E.2070202@goop.org>
On Thu, 21 May 2009 13:18:54 -0700
Jeremy Fitzhardinge <jeremy@goop.org> wrote:
> Becky Bruce wrote:
> > I can work with that, but it's going to be a bit inefficient, as I
> > actually need the dma_addr_t, not the phys_addr_t, so I'll have to
> > convert. In every case, this is a conversion I've already done and
> > that I need in the calling code as well. Can we pass in both the
> > phys_addr_t and the dma_addr_t?
>
> The Xen implementation would needs to do the phys to bus conversion page
> by page anyway, so it wouldn't help much. But it also wouldn't hurt.
>
> How expensive is the phys-to-bus conversion on power? Is it worth
> making the interface more complex for? Would passing phys+bus mean that
> we wouldn't also need to pass dev?
I don't think so. POWERPC needs it.
^ permalink raw reply
* Re: [PATCH V2 2/3] powerpc: Add support for swiotlb on 32-bit
From: FUJITA Tomonori @ 2009-05-22 10:51 UTC (permalink / raw)
To: Ian.Campbell; +Cc: fujita.tomonori, linuxppc-dev, jeremy, linux-kernel
In-Reply-To: <1242932497.25553.230.camel@localhost.localdomain>
On Thu, 21 May 2009 20:01:37 +0100
Ian Campbell <Ian.Campbell@eu.citrix.com> wrote:
> > It's not actually clear to me that we need that check, though. Can
> > someone explain what case that was designed to catch?
>
> If map_single fails and returns NULL then we try to use
> io_tlb_overflow_buffer, if that is somehow not DMA-able (for the
> particular device) then the check will trigger. I would have thought we
> could arrange that the overflow buffer is always OK and really if
> map_page is failing we must be close the edge already.
And iotlb buffers are not guaranteed to be DMA-capable; it's possible
that some drivers (with poor dma address restrictions) can't handle
some part of iotlb buffers.
So after allocating some ioblb buffer, we need to check if the buffers
are DMA-capable for a driver. Well, it's unlikely though.
Well, it would be better to move the check to map_single().
^ permalink raw reply
* [GIT PULL] fsldma driver fixes
From: Li Yang @ 2009-05-22 10:47 UTC (permalink / raw)
To: Dan Williams; +Cc: linuxppc-dev Development, lkml
Hi Dan,
Here are fixes for Freescale DMA engine driver.
Thanks,
- Leo
The following changes since commit 5805977e63a36ad56594a623f3bd2bebcb7db233:
Linus Torvalds (1):
Merge branch 'for-linus' of git://git.kernel.org/.../jbarnes/drm-2.6
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/leo/fsl-soc.git fsldma
Ira Snyder (4):
fsldma: fix "DMA halt timeout!" errors
fsldma: fix infinite loop on multi-descriptor DMA chain completion
fsldma: snooping is not enabled for last entry in descriptor chain
fsldma: fix memory leak on error path in fsl_dma_prep_memcpy()
Li Yang (1):
fsldma: update mailling list address in MAINTAINERS
Roel Kluin (1):
fsldma: fix check on potential fdev->chan[] overflow
MAINTAINERS | 2 +-
drivers/dma/fsldma.c | 58 ++++++++++++++++++++++++++++++++++---------------
2 files changed, 41 insertions(+), 19 deletions(-)
diff --git a/MAINTAINERS b/MAINTAINERS
index 2b349ba..cac3e3b 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2241,7 +2241,7 @@ P: Li Yang
M: leoli@freescale.com
P: Zhang Wei
M: zw@zh-kernel.org
-L: linuxppc-embedded@ozlabs.org
+L: linuxppc-dev@ozlabs.org
L: linux-kernel@vger.kernel.org
S: Maintained
F: drivers/dma/fsldma.*
diff --git a/drivers/dma/fsldma.c b/drivers/dma/fsldma.c
index da8a8ed..1578310 100644
--- a/drivers/dma/fsldma.c
+++ b/drivers/dma/fsldma.c
@@ -179,9 +179,14 @@ static void dma_halt(struct fsl_dma_chan *fsl_chan)
static void set_ld_eol(struct fsl_dma_chan *fsl_chan,
struct fsl_desc_sw *desc)
{
+ u64 snoop_bits;
+
+ snoop_bits = ((fsl_chan->feature & FSL_DMA_IP_MASK) == FSL_DMA_IP_83XX)
+ ? FSL_DMA_SNEN : 0;
+
desc->hw.next_ln_addr = CPU_TO_DMA(fsl_chan,
- DMA_TO_CPU(fsl_chan, desc->hw.next_ln_addr, 64) | FSL_DMA_EOL,
- 64);
+ DMA_TO_CPU(fsl_chan, desc->hw.next_ln_addr, 64) | FSL_DMA_EOL
+ | snoop_bits, 64);
}
static void append_ld_queue(struct fsl_dma_chan *fsl_chan,
@@ -313,8 +318,8 @@ static void fsl_chan_toggle_ext_start(struct
fsl_dma_chan *fsl_chan, int enable)
static dma_cookie_t fsl_dma_tx_submit(struct dma_async_tx_descriptor *tx)
{
- struct fsl_desc_sw *desc = tx_to_fsl_desc(tx);
struct fsl_dma_chan *fsl_chan = to_fsl_chan(tx->chan);
+ struct fsl_desc_sw *desc;
unsigned long flags;
dma_cookie_t cookie;
@@ -322,14 +327,17 @@ static dma_cookie_t fsl_dma_tx_submit(struct
dma_async_tx_descriptor *tx)
spin_lock_irqsave(&fsl_chan->desc_lock, flags);
cookie = fsl_chan->common.cookie;
- cookie++;
- if (cookie < 0)
- cookie = 1;
- desc->async_tx.cookie = cookie;
- fsl_chan->common.cookie = desc->async_tx.cookie;
+ list_for_each_entry(desc, &tx->tx_list, node) {
+ cookie++;
+ if (cookie < 0)
+ cookie = 1;
- append_ld_queue(fsl_chan, desc);
- list_splice_init(&desc->async_tx.tx_list, fsl_chan->ld_queue.prev);
+ desc->async_tx.cookie = cookie;
+ }
+
+ fsl_chan->common.cookie = cookie;
+ append_ld_queue(fsl_chan, tx_to_fsl_desc(tx));
+ list_splice_init(&tx->tx_list, fsl_chan->ld_queue.prev);
spin_unlock_irqrestore(&fsl_chan->desc_lock, flags);
@@ -454,8 +462,8 @@ static struct dma_async_tx_descriptor *fsl_dma_prep_memcpy(
{
struct fsl_dma_chan *fsl_chan;
struct fsl_desc_sw *first = NULL, *prev = NULL, *new;
+ struct list_head *list;
size_t copy;
- LIST_HEAD(link_chain);
if (!chan)
return NULL;
@@ -472,7 +480,7 @@ static struct dma_async_tx_descriptor *fsl_dma_prep_memcpy(
if (!new) {
dev_err(fsl_chan->dev,
"No free memory for link descriptor\n");
- return NULL;
+ goto fail;
}
#ifdef FSL_DMA_LD_DEBUG
dev_dbg(fsl_chan->dev, "new link desc alloc %p\n", new);
@@ -507,7 +515,19 @@ static struct dma_async_tx_descriptor *fsl_dma_prep_memcpy(
/* Set End-of-link to the last link descriptor of new list*/
set_ld_eol(fsl_chan, new);
- return first ? &first->async_tx : NULL;
+ return &first->async_tx;
+
+fail:
+ if (!first)
+ return NULL;
+
+ list = &first->async_tx.tx_list;
+ list_for_each_entry_safe_reverse(new, prev, list, node) {
+ list_del(&new->node);
+ dma_pool_free(fsl_chan->desc_pool, new, new->async_tx.phys);
+ }
+
+ return NULL;
}
/**
@@ -598,15 +618,16 @@ static void fsl_chan_xfer_ld_queue(struct
fsl_dma_chan *fsl_chan)
dma_addr_t next_dest_addr;
unsigned long flags;
+ spin_lock_irqsave(&fsl_chan->desc_lock, flags);
+
if (!dma_is_idle(fsl_chan))
- return;
+ goto out_unlock;
dma_halt(fsl_chan);
/* If there are some link descriptors
* not transfered in queue. We need to start it.
*/
- spin_lock_irqsave(&fsl_chan->desc_lock, flags);
/* Find the first un-transfer desciptor */
for (ld_node = fsl_chan->ld_queue.next;
@@ -617,8 +638,6 @@ static void fsl_chan_xfer_ld_queue(struct
fsl_dma_chan *fsl_chan)
fsl_chan->common.cookie) == DMA_SUCCESS);
ld_node = ld_node->next);
- spin_unlock_irqrestore(&fsl_chan->desc_lock, flags);
-
if (ld_node != &fsl_chan->ld_queue) {
/* Get the ld start address from ld_queue */
next_dest_addr = to_fsl_desc(ld_node)->async_tx.phys;
@@ -630,6 +649,9 @@ static void fsl_chan_xfer_ld_queue(struct
fsl_dma_chan *fsl_chan)
set_cdar(fsl_chan, 0);
set_ndar(fsl_chan, 0);
}
+
+out_unlock:
+ spin_unlock_irqrestore(&fsl_chan->desc_lock, flags);
}
/**
@@ -830,7 +852,7 @@ static int __devinit fsl_dma_chan_probe(struct
fsl_dma_device *fdev,
new_fsl_chan->reg.end - new_fsl_chan->reg.start + 1);
new_fsl_chan->id = ((new_fsl_chan->reg.start - 0x100) & 0xfff) >> 7;
- if (new_fsl_chan->id > FSL_DMA_MAX_CHANS_PER_DEVICE) {
+ if (new_fsl_chan->id >= FSL_DMA_MAX_CHANS_PER_DEVICE) {
dev_err(fdev->dev, "There is no %d channel!\n",
new_fsl_chan->id);
err = -EINVAL;
^ permalink raw reply related
* Re: [PATCH] fsldma: fix memory leak on error path in fsl_dma_prep_memcpy()
From: Li Yang @ 2009-05-22 10:30 UTC (permalink / raw)
To: Ira Snyder; +Cc: linuxppc-dev, Dan Williams
In-Reply-To: <20090515165946.GA858@ovro.caltech.edu>
On Sat, May 16, 2009 at 12:59 AM, Ira Snyder <iws@ovro.caltech.edu> wrote:
> When preparing a memcpy operation, if the kernel fails to allocate memory
> for a link descriptor after the first link descriptor has already been
> allocated, then some memory will never be released. Fix the problem by
> walking the list of allocated descriptors backwards, and freeing the
> allocated descriptors back into the DMA pool.
>
> Signed-off-by: Ira W. Snyder <iws@ovro.caltech.edu>
Applied the following patches:
fsldma: fix "DMA halt timeout!" errors
fsldma: fix infinite loop on multi-descriptor DMA chain completion
fsldma: snooping is not enabled for last entry in descriptor chain
fsldma: fix memory leak on error path in fsl_dma_prep_memcpy()
Thanks
- Leo
^ permalink raw reply
* Re: can't flush tlb on e500
From: Benjamin Herrenschmidt @ 2009-05-22 9:42 UTC (permalink / raw)
To: Saito Hideo; +Cc: linuxppc-dev list, linux-kernel, Kumar Gala
In-Reply-To: <1242984470.26104.29.camel@pasglop>
On Fri, 2009-05-22 at 19:27 +1000, Benjamin Herrenschmidt wrote:
> On Wed, 2009-05-20 at 19:12 +0900, Saito Hideo wrote:
>
> > I think that the tlb should be cleared before mm->context.id is set
> > MMU_NO_CONTEXT.
>
> You are right, this definitely looks like a bug on platforms that have
> HW support for the tlbil instruction (and thus care about the PID for
> flushing) which afaik is only the case of recent freescale chips.
In fact, you are doubly right in that it also happens on other platforms
because local_flush_tlb_mm() will check if the PID is MMU_NO_CONTEXT
regardless of what tlbilx supports.. oops
Looks like I only ran my context torture test with CONFIG_SMP enabled.
Shame on me.
> Have you verified that this change fixes your problem ?
>
> Can you re-submit to linuxppc-dev@ozlabs.org mailing list, along with
> proper changeset comment and signed-off-by: line ?
>
> Cheers,
> Ben.
>
> > --- arch/powerpc/mm/mmu_context_nohash.c.orig 2009-03-24
> > 08:12:14.000000000 +0900
> > +++ arch/powerpc/mm/mmu_context_nohash.c 2009-05-20 18:33:53.000000000 +0900
> > @@ -122,22 +122,22 @@ static unsigned int steal_context_up(uns
> > struct mm_struct *mm;
> > int cpu = smp_processor_id();
> >
> > /* Pick up the victim mm */
> > mm = context_mm[id];
> >
> > pr_debug("[%d] steal context %d from mm @%p\n", cpu, id, mm);
> >
> > - /* Mark this mm has having no context anymore */
> > - mm->context.id = MMU_NO_CONTEXT;
> > -
> > /* Flush the TLB for that context */
> > local_flush_tlb_mm(mm);
> >
> > + /* Mark this mm has having no context anymore */
> > + mm->context.id = MMU_NO_CONTEXT;
> > +
> > /* XXX This clear should ultimately be part of local_flush_tlb_mm */
> > __clear_bit(id, stale_map[cpu]);
> >
> > return id;
> > }
> >
> > #ifdef DEBUG_MAP_CONSISTENCY
> > static void context_check_map(void)
> > --
> > To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> > the body of a message to majordomo@vger.kernel.org
> > More majordomo info at http://vger.kernel.org/majordomo-info.html
> > Please read the FAQ at http://www.tux.org/lkml/
>
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev@ozlabs.org
> https://ozlabs.org/mailman/listinfo/linuxppc-dev
^ 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