dmaengine: PL08x: Allow using PL08x with sound drivers
This patch serie extend the PL08x driver to allow using it with sound drivers. Sound drivers require the cyclic transfer mode and that tx_status give reliable results. * Patch 1 is a trivial fix * Patch 2 implement the cyclic mode needed by sound drivers * Patch 3 fix the tx_status implementation to get reliable results -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 3/3] dmaengine: PL08x: Make the transfer status reliable
To reliably get the current DMA position it is not possible to just read the PL08x registers. As several reads are needed the values are not consistent. To overcome this keep track of the position as each LLI finish, this give a coarse but reliable value. Signed-off-by: Alban Bedel --- drivers/dma/amba-pl08x.c | 79 + 1 files changed, 23 insertions(+), 56 deletions(-) diff --git a/drivers/dma/amba-pl08x.c b/drivers/dma/amba-pl08x.c index b097788..57a4d80 100644 --- a/drivers/dma/amba-pl08x.c +++ b/drivers/dma/amba-pl08x.c @@ -175,6 +175,10 @@ struct pl08x_sg { * @done: this marks completed descriptors, which should not have their * mux released. * @cyclic: indicate cyclic transfers + * @llis_pos: current position in the linked list + * @llis_count: number of transfer in the linked list + * @bytes_transferred: number of bytes tranfered up to now + * @bytes_requested: number of bytes in the whole transfer */ struct pl08x_txd { struct virt_dma_desc vd; @@ -191,6 +195,10 @@ struct pl08x_txd { bool done; bool cyclic; + unsigned llis_pos; + unsigned llis_count; + unsigned bytes_transferred; + unsigned bytes_requested; }; /** @@ -470,56 +478,6 @@ static inline u32 get_bytes_in_cctl(u32 cctl) return bytes; } -/* The channel should be paused when calling this */ -static u32 pl08x_getbytes_chan(struct pl08x_dma_chan *plchan) -{ - struct pl08x_phy_chan *ch; - struct pl08x_txd *txd; - size_t bytes = 0; - - ch = plchan->phychan; - txd = plchan->at; - - /* -* Follow the LLIs to get the number of remaining -* bytes in the currently active transaction. -*/ - if (ch && txd) { - u32 clli = readl(ch->base + PL080_CH_LLI) & ~PL080_LLI_LM_AHB2; - - /* First get the remaining bytes in the active transfer */ - bytes = get_bytes_in_cctl(readl(ch->base + PL080_CH_CONTROL)); - - if (clli) { - struct pl08x_lli *llis_va = txd->llis_va; - dma_addr_t llis_bus = txd->llis_bus; - int index; - - BUG_ON(clli < llis_bus || clli >= llis_bus + - sizeof(struct pl08x_lli) * MAX_NUM_TSFR_LLIS); - - /* -* Locate the next LLI - as this is an array, -* it's simple maths to find. -*/ - index = (clli - llis_bus) / sizeof(struct pl08x_lli); - - for (; index < MAX_NUM_TSFR_LLIS; index++) { - bytes += get_bytes_in_cctl(llis_va[index].cctl); - - /* -* A LLI pointer going backward terminates -* the LLI list -*/ - if (llis_va[index].lli <= clli) - break; - } - } - } - - return bytes; -} - /* * Allocate a physical channel for a virtual channel * @@ -777,7 +735,8 @@ static void pl08x_fill_lli_for_desc(struct pl08x_lli_build_data *bd, BUG_ON(num_llis >= MAX_NUM_TSFR_LLIS); - llis_va[num_llis].cctl = cctl; + /* Always enable TC IRQ to keep track of the position in the LLIs */ + llis_va[num_llis].cctl = cctl | PL080_CONTROL_TC_IRQ_EN; llis_va[num_llis].src = bd->srcbus.addr; llis_va[num_llis].dst = bd->dstbus.addr; llis_va[num_llis].lli = llis_bus + (num_llis + 1) * @@ -1011,8 +970,10 @@ static int pl08x_fill_llis_for_desc(struct pl08x_driver_data *pl08x, __func__, (u32) MAX_NUM_TSFR_LLIS); return 0; } + txd->bytes_requested += total_bytes; } + txd->llis_count = num_llis; llis_va = txd->llis_va; if (txd->cyclic) { /* Link back to the first LLI. */ @@ -1020,7 +981,6 @@ static int pl08x_fill_llis_for_desc(struct pl08x_driver_data *pl08x, } else { /* The final LLI terminates the LLI. */ llis_va[num_llis - 1].lli = 0; - llis_va[num_llis - 1].cctl |= PL080_CONTROL_TC_IRQ_EN; } #ifdef VERBOSE_DEBUG @@ -1177,8 +1137,9 @@ static enum dma_status pl08x_dma_tx_status(struct dma_chan *chan, list_for_each_entry(dsg, &txd->dsg_list, node) bytes += dsg->len; - } else { - bytes = pl08x_getbytes_chan(plchan); + } else if (plchan->at) { + bytes = plchan->at->bytes_requested - + plchan->at->bytes_transferred;
[PATCH 1/3] dmaengine: PL08x: Fix reading the byte count in cctl
Signed-off-by: Alban Bedel --- drivers/dma/amba-pl08x.c |3 ++- 1 files changed, 2 insertions(+), 1 deletions(-) diff --git a/drivers/dma/amba-pl08x.c b/drivers/dma/amba-pl08x.c index d1cc579..fc8bedf 100644 --- a/drivers/dma/amba-pl08x.c +++ b/drivers/dma/amba-pl08x.c @@ -453,7 +453,8 @@ static inline u32 get_bytes_in_cctl(u32 cctl) /* The source width defines the number of bytes */ u32 bytes = cctl & PL080_CONTROL_TRANSFER_SIZE_MASK; - switch (cctl >> PL080_CONTROL_SWIDTH_SHIFT) { + switch ((cctl & PL080_CONTROL_SWIDTH_MASK) >> + PL080_CONTROL_SWIDTH_SHIFT) { case PL080_WIDTH_8BIT: break; case PL080_WIDTH_16BIT: -- 1.7.0.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 2/3] dmaengine: PL08x: Add cyclic transfer support
Signed-off-by: Alban Bedel --- drivers/dma/amba-pl08x.c | 184 ++ 1 files changed, 138 insertions(+), 46 deletions(-) diff --git a/drivers/dma/amba-pl08x.c b/drivers/dma/amba-pl08x.c index fc8bedf..b097788 100644 --- a/drivers/dma/amba-pl08x.c +++ b/drivers/dma/amba-pl08x.c @@ -174,6 +174,7 @@ struct pl08x_sg { * @ccfg: config reg values for current txd * @done: this marks completed descriptors, which should not have their * mux released. + * @cyclic: indicate cyclic transfers */ struct pl08x_txd { struct virt_dma_desc vd; @@ -188,6 +189,8 @@ struct pl08x_txd { */ u32 ccfg; bool done; + + bool cyclic; }; /** @@ -505,9 +508,10 @@ static u32 pl08x_getbytes_chan(struct pl08x_dma_chan *plchan) bytes += get_bytes_in_cctl(llis_va[index].cctl); /* -* A LLI pointer of 0 terminates the LLI list +* A LLI pointer going backward terminates +* the LLI list */ - if (!llis_va[index].lli) + if (llis_va[index].lli <= clli) break; } } @@ -1010,10 +1014,14 @@ static int pl08x_fill_llis_for_desc(struct pl08x_driver_data *pl08x, } llis_va = txd->llis_va; - /* The final LLI terminates the LLI. */ - llis_va[num_llis - 1].lli = 0; - /* The final LLI element shall also fire an interrupt. */ - llis_va[num_llis - 1].cctl |= PL080_CONTROL_TC_IRQ_EN; + if (txd->cyclic) { + /* Link back to the first LLI. */ + llis_va[num_llis - 1].lli = txd->llis_bus | bd.lli_bus; + } else { + /* The final LLI terminates the LLI. */ + llis_va[num_llis - 1].lli = 0; + llis_va[num_llis - 1].cctl |= PL080_CONTROL_TC_IRQ_EN; + } #ifdef VERBOSE_DEBUG { @@ -1411,25 +1419,19 @@ static struct dma_async_tx_descriptor *pl08x_prep_dma_memcpy( return vchan_tx_prep(&plchan->vc, &txd->vd, flags); } -static struct dma_async_tx_descriptor *pl08x_prep_slave_sg( - struct dma_chan *chan, struct scatterlist *sgl, - unsigned int sg_len, enum dma_transfer_direction direction, - unsigned long flags, void *context) +static struct pl08x_txd *pl08x_init_txd( + struct dma_chan *chan, + enum dma_transfer_direction direction, + dma_addr_t *slave_addr) { struct pl08x_dma_chan *plchan = to_pl08x_chan(chan); struct pl08x_driver_data *pl08x = plchan->host; struct pl08x_txd *txd; - struct pl08x_sg *dsg; - struct scatterlist *sg; enum dma_slave_buswidth addr_width; - dma_addr_t slave_addr; int ret, tmp; u8 src_buses, dst_buses; u32 maxburst, cctl; - dev_dbg(&pl08x->adev->dev, "%s prepare transaction of %d bytes from %s\n", - __func__, sg_dma_len(sgl), plchan->name); - txd = pl08x_get_txd(plchan); if (!txd) { dev_err(&pl08x->adev->dev, "%s no txd\n", __func__); @@ -1443,14 +1445,14 @@ static struct dma_async_tx_descriptor *pl08x_prep_slave_sg( */ if (direction == DMA_MEM_TO_DEV) { cctl = PL080_CONTROL_SRC_INCR; - slave_addr = plchan->cfg.dst_addr; + *slave_addr = plchan->cfg.dst_addr; addr_width = plchan->cfg.dst_addr_width; maxburst = plchan->cfg.dst_maxburst; src_buses = pl08x->mem_buses; dst_buses = plchan->cd->periph_buses; } else if (direction == DMA_DEV_TO_MEM) { cctl = PL080_CONTROL_DST_INCR; - slave_addr = plchan->cfg.src_addr; + *slave_addr = plchan->cfg.src_addr; addr_width = plchan->cfg.src_addr_width; maxburst = plchan->cfg.src_maxburst; src_buses = plchan->cd->periph_buses; @@ -1499,24 +1501,107 @@ static struct dma_async_tx_descriptor *pl08x_prep_slave_sg( else txd->ccfg |= plchan->signal << PL080_CONFIG_SRC_SEL_SHIFT; + return txd; +} + +static int pl08x_tx_add_sg(struct pl08x_txd *txd, + enum dma_transfer_direction direction, + dma_addr_t slave_addr, + dma_addr_t buf_addr, + unsigned int len) +{ + struct pl08x_sg *dsg; + + dsg = kzalloc(sizeof(struct pl08x_sg), GFP_NOWAIT); + if (!dsg) + return -ENOMEM; + + list_add_tail(&dsg->node, &txd->dsg_
[PATCH] pwm-backlight: Add support for active low PWM backlights
Signed-off-by: Alban Bedel --- .../bindings/video/backlight/pwm-backlight.txt |1 + drivers/video/backlight/pwm_bl.c | 22 ++- include/linux/pwm_backlight.h |1 + 3 files changed, 18 insertions(+), 6 deletions(-) diff --git a/Documentation/devicetree/bindings/video/backlight/pwm-backlight.txt b/Documentation/devicetree/bindings/video/backlight/pwm-backlight.txt index 1e4fc72..3a40539 100644 --- a/Documentation/devicetree/bindings/video/backlight/pwm-backlight.txt +++ b/Documentation/devicetree/bindings/video/backlight/pwm-backlight.txt @@ -14,6 +14,7 @@ Required properties: Optional properties: - pwm-names: a list of names for the PWM devices specified in the "pwms" property (see PWM binding[0]) + - active-low: boolean indicating that the backlight use active low logic [0]: Documentation/devicetree/bindings/pwm/pwm.txt diff --git a/drivers/video/backlight/pwm_bl.c b/drivers/video/backlight/pwm_bl.c index 995f016..109c703 100644 --- a/drivers/video/backlight/pwm_bl.c +++ b/drivers/video/backlight/pwm_bl.c @@ -25,6 +25,7 @@ struct pwm_bl_data { struct pwm_device *pwm; struct device *dev; unsigned intperiod; + unsigned intactive_low; unsigned intlth_brightness; unsigned int*levels; int (*notify)(struct device *, @@ -40,6 +41,7 @@ static int pwm_backlight_update_status(struct backlight_device *bl) struct pwm_bl_data *pb = dev_get_drvdata(&bl->dev); int brightness = bl->props.brightness; int max = bl->props.max_brightness; + int duty_cycle; if (bl->props.power != FB_BLANK_UNBLANK) brightness = 0; @@ -51,11 +53,8 @@ static int pwm_backlight_update_status(struct backlight_device *bl) brightness = pb->notify(pb->dev, brightness); if (brightness == 0) { - pwm_config(pb->pwm, 0, pb->period); - pwm_disable(pb->pwm); + duty_cycle = 0; } else { - int duty_cycle; - if (pb->levels) { duty_cycle = pb->levels[brightness]; max = pb->levels[max]; @@ -65,10 +64,17 @@ static int pwm_backlight_update_status(struct backlight_device *bl) duty_cycle = pb->lth_brightness + (duty_cycle * (pb->period - pb->lth_brightness) / max); - pwm_config(pb->pwm, duty_cycle, pb->period); - pwm_enable(pb->pwm); } + if (pb->active_low) + duty_cycle = pb->period - duty_cycle; + + pwm_config(pb->pwm, duty_cycle, pb->period); + if (duty_cycle == 0) + pwm_disable(pb->pwm); + else + pwm_enable(pb->pwm); + if (pb->notify_after) pb->notify_after(pb->dev, brightness); @@ -145,6 +151,9 @@ static int pwm_backlight_parse_dt(struct device *dev, data->max_brightness--; } + /* Is the backlight low active? */ + data->active_low = of_property_read_bool(node, "active-low"); + /* * TODO: Most users of this driver use a number of GPIOs to control * backlight power. Support for specifying these needs to be @@ -237,6 +246,7 @@ static int pwm_backlight_probe(struct platform_device *pdev) pb->period = pwm_get_period(pb->pwm); pb->lth_brightness = data->lth_brightness * (pb->period / max); + pb->active_low = data->active_low; memset(&props, 0, sizeof(struct backlight_properties)); props.type = BACKLIGHT_RAW; diff --git a/include/linux/pwm_backlight.h b/include/linux/pwm_backlight.h index 56f4a86..52b19d9 100644 --- a/include/linux/pwm_backlight.h +++ b/include/linux/pwm_backlight.h @@ -12,6 +12,7 @@ struct platform_pwm_backlight_data { unsigned int dft_brightness; unsigned int lth_brightness; unsigned int pwm_period_ns; + unsigned int active_low; unsigned int *levels; int (*init)(struct device *dev); int (*notify)(struct device *dev, int brightness); -- 1.7.0.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] pwm: lpc32xx - Fix the PWM polarity
Signed-off-by: Alban Bedel --- drivers/pwm/pwm-lpc32xx.c |6 +- 1 files changed, 5 insertions(+), 1 deletions(-) diff --git a/drivers/pwm/pwm-lpc32xx.c b/drivers/pwm/pwm-lpc32xx.c index adb87f0..a2704b8 100644 --- a/drivers/pwm/pwm-lpc32xx.c +++ b/drivers/pwm/pwm-lpc32xx.c @@ -51,7 +51,11 @@ static int lpc32xx_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, c = 256 * duty_ns; do_div(c, period_ns); - duty_cycles = c; + if (c > 255) + c = 255; + if (c < 1) + c = 1; + duty_cycles = 256 - c; writel(PWM_ENABLE | PWM_RELOADV(period_cycles) | PWM_DUTY(duty_cycles), lpc32xx->base + (pwm->hwpwm << 2)); -- 1.7.0.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 3/3] pwm: lpc32xx - Set the chip base for dynamic allocation
Signed-off-by: Alban Bedel --- drivers/pwm/pwm-lpc32xx.c |1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/drivers/pwm/pwm-lpc32xx.c b/drivers/pwm/pwm-lpc32xx.c index f45ce2c..3e63689 100644 --- a/drivers/pwm/pwm-lpc32xx.c +++ b/drivers/pwm/pwm-lpc32xx.c @@ -121,6 +121,7 @@ static int lpc32xx_pwm_probe(struct platform_device *pdev) lpc32xx->chip.dev = &pdev->dev; lpc32xx->chip.ops = &lpc32xx_pwm_ops; lpc32xx->chip.npwm = 2; + lpc32xx->chip.base = -1; ret = pwmchip_add(&lpc32xx->chip); if (ret < 0) { -- 1.7.0.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 1/3] pwm: lpc32xx - Fix the PWM polarity
The duty cycles value goes from 1 (99% HIGH) to 256 (0% HIGH) but it is stored modulo 256 in the register as it is only 8 bits wide. Signed-off-by: Alban Bedel --- drivers/pwm/pwm-lpc32xx.c | 17 - 1 files changed, 16 insertions(+), 1 deletions(-) diff --git a/drivers/pwm/pwm-lpc32xx.c b/drivers/pwm/pwm-lpc32xx.c index adb87f0..03ec3ff 100644 --- a/drivers/pwm/pwm-lpc32xx.c +++ b/drivers/pwm/pwm-lpc32xx.c @@ -49,9 +49,24 @@ static int lpc32xx_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, c = 0; /* 0 set division by 256 */ period_cycles = c; + /* The duty value is a follow: +* +* DUTY HIGH LEVEL +* 1 99.9% +* 2590.0% +* 128 50.0% +* 220 10.0% +* 2550.1% +* 0 0.0% +* +* In other word the in-register value is duty % 256 with duty +* in the range 1-256. +*/ c = 256 * duty_ns; do_div(c, period_ns); - duty_cycles = c; + if (c > 255) + c = 255; + duty_cycles = 256 - c; writel(PWM_ENABLE | PWM_RELOADV(period_cycles) | PWM_DUTY(duty_cycles), lpc32xx->base + (pwm->hwpwm << 2)); -- 1.7.0.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 2/3] pwm: lpc32xx - Properly disable the clock on device remove
A single clock is used for all PWMs meaning the clock ref count might be between 0 and N when remove() is called. Instead of a single clk_disable() call pwm_disable() on each PWM, that ensure that clk_disable() is called for each PWM that were still enabled. Signed-off-by: Alban Bedel --- drivers/pwm/pwm-lpc32xx.c |5 - 1 files changed, 4 insertions(+), 1 deletions(-) diff --git a/drivers/pwm/pwm-lpc32xx.c b/drivers/pwm/pwm-lpc32xx.c index 03ec3ff..f45ce2c 100644 --- a/drivers/pwm/pwm-lpc32xx.c +++ b/drivers/pwm/pwm-lpc32xx.c @@ -136,8 +136,11 @@ static int lpc32xx_pwm_probe(struct platform_device *pdev) static int __devexit lpc32xx_pwm_remove(struct platform_device *pdev) { struct lpc32xx_pwm_chip *lpc32xx = platform_get_drvdata(pdev); + int i; + + for (i = 0 ; i < lpc32xx->chip.npwm ; i += 1) + pwm_disable(&lpc32xx->chip.pwms[i]); - clk_disable(lpc32xx->clk); return pwmchip_remove(&lpc32xx->chip); } -- 1.7.0.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 0/3] pwm: lpc32xx - Various small fixes
A few fixes for the LPC32 PWM driver: * [PATCH 1/3] pwm: lpc32xx - Fix the PWM polarity * [PATCH 2/3] pwm: lpc32xx - Properly disable the clock on device remove * [PATCH 3/3] pwm: lpc32xx - Set the chip base for dynamic allocation Alban -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] pwm: lpc32xx - Fix the PWM polarity
On Tue, 6 Nov 2012 07:47:22 -0200 Alexandre Pereira da Silva wrote: > Can you test the 0 and 255 values on actual hardware and see the effective > values? 0 -> 0% 1 -> 99% 128 -> 50% 255 -> 1% So yes 0 mean 256. > It may be handled as the RELOADV where 0 really means 256. If so, you can > use the same logic I used originally on the frequency division. I'll look at this and submit a new patch. Alban -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] pwm-backlight: Add support for active low PWM backlights
On Tue, 6 Nov 2012 07:44:06 +0100 Thierry Reding wrote: > > --- a/Documentation/devicetree/bindings/video/backlight/pwm-backlight.txt > > +++ b/Documentation/devicetree/bindings/video/backlight/pwm-backlight.txt > > @@ -14,6 +14,7 @@ Required properties: > > Optional properties: > >- pwm-names: a list of names for the PWM devices specified in the > > "pwms" property (see PWM binding[0]) > > + - active-low: boolean indicating that the backlight use active low logic > > Couldn't you use the brightness-levels property to achieve the same > effect? Not in the current state as the curve currently hardcode the fact the first element have 0% duty and the last 100%. But relaxing this limitation is probably better as it would also allow clamping the curve like the lth_brightness parameter do when no curve is used. I'll send a new patch implementing this soon. Alban -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] pwm-backlight: Allow any kind of brightness curve
The brightness curve assume that the first level always have a duty cycle of 0% and the last level 100%. However it is desirable to allow any kind of curve to handle low-active devices, or devices that need to clamp the curve to some range. To allow defining any kind of curve the brightness levels are expected to be in the range from 0 to 255, where 0 is 0% duty and 255 is 100% duty. Signed-off-by: Alban Bedel --- .../bindings/video/backlight/pwm-backlight.txt |8 ++--- drivers/video/backlight/pwm_bl.c | 28 +-- include/linux/pwm_backlight.h |2 + 3 files changed, 18 insertions(+), 20 deletions(-) diff --git a/Documentation/devicetree/bindings/video/backlight/pwm-backlight.txt b/Documentation/devicetree/bindings/video/backlight/pwm-backlight.txt index 1e4fc72..d0ecbd4 100644 --- a/Documentation/devicetree/bindings/video/backlight/pwm-backlight.txt +++ b/Documentation/devicetree/bindings/video/backlight/pwm-backlight.txt @@ -3,11 +3,9 @@ pwm-backlight bindings Required properties: - compatible: "pwm-backlight" - pwms: OF device-tree PWM specification (see PWM binding[0]) - - brightness-levels: Array of distinct brightness levels. Typically these - are in the range from 0 to 255, but any range starting at 0 will do. - The actual brightness level (PWM duty cycle) will be interpolated - from these values. 0 means a 0% duty cycle (darkest/off), while the - last value in the array represents a 100% duty cycle (brightest). + - brightness-levels: Array of distinct brightness levels in the + range from 0 to 255. 0 means a 0% duty cycle, while 255 + represents a 100% duty cycle. - default-brightness-level: the default brightness level (index into the array defined by the "brightness-levels" property) diff --git a/drivers/video/backlight/pwm_bl.c b/drivers/video/backlight/pwm_bl.c index 995f016..09ce501 100644 --- a/drivers/video/backlight/pwm_bl.c +++ b/drivers/video/backlight/pwm_bl.c @@ -40,6 +40,7 @@ static int pwm_backlight_update_status(struct backlight_device *bl) struct pwm_bl_data *pb = dev_get_drvdata(&bl->dev); int brightness = bl->props.brightness; int max = bl->props.max_brightness; + int duty_cycle; if (bl->props.power != FB_BLANK_UNBLANK) brightness = 0; @@ -50,24 +51,21 @@ static int pwm_backlight_update_status(struct backlight_device *bl) if (pb->notify) brightness = pb->notify(pb->dev, brightness); - if (brightness == 0) { - pwm_config(pb->pwm, 0, pb->period); - pwm_disable(pb->pwm); + if (pb->levels) { + duty_cycle = pb->levels[brightness]; + max = PWM_BL_MAX_LEVEL; } else { - int duty_cycle; + duty_cycle = brightness; + } - if (pb->levels) { - duty_cycle = pb->levels[brightness]; - max = pb->levels[max]; - } else { - duty_cycle = brightness; - } + duty_cycle = pb->lth_brightness + + (duty_cycle * (pb->period - pb->lth_brightness) / max); - duty_cycle = pb->lth_brightness + -(duty_cycle * (pb->period - pb->lth_brightness) / max); - pwm_config(pb->pwm, duty_cycle, pb->period); + pwm_config(pb->pwm, duty_cycle, pb->period); + if (duty_cycle == 0) + pwm_disable(pb->pwm); + else pwm_enable(pb->pwm); - } if (pb->notify_after) pb->notify_after(pb->dev, brightness); @@ -202,7 +200,7 @@ static int pwm_backlight_probe(struct platform_device *pdev) } if (data->levels) { - max = data->levels[data->max_brightness]; + max = PWM_BL_MAX_LEVEL; pb->levels = data->levels; } else max = data->max_brightness; diff --git a/include/linux/pwm_backlight.h b/include/linux/pwm_backlight.h index 56f4a86..f5ed046 100644 --- a/include/linux/pwm_backlight.h +++ b/include/linux/pwm_backlight.h @@ -6,6 +6,8 @@ #include +#define PWM_BL_MAX_LEVEL 255 + struct platform_pwm_backlight_data { int pwm_id; unsigned int max_brightness; -- 1.7.0.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] pwm: lpc32xx - Fix the PWM polarity
Signed-off-by: Alban Bedel --- drivers/pwm/pwm-lpc32xx.c |6 +- 1 files changed, 5 insertions(+), 1 deletions(-) diff --git a/drivers/pwm/pwm-lpc32xx.c b/drivers/pwm/pwm-lpc32xx.c index adb87f0..0dc278d 100644 --- a/drivers/pwm/pwm-lpc32xx.c +++ b/drivers/pwm/pwm-lpc32xx.c @@ -51,7 +51,11 @@ static int lpc32xx_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, c = 256 * duty_ns; do_div(c, period_ns); - duty_cycles = c; + if (c == 0) + c = 256; + if (c > 255) + c = 255; + duty_cycles = 256 - c; writel(PWM_ENABLE | PWM_RELOADV(period_cycles) | PWM_DUTY(duty_cycles), lpc32xx->base + (pwm->hwpwm << 2)); -- 1.7.0.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] pwm: lpc32xx - Fix the PWM polarity
On Thu, 08 Nov 2012 10:51:35 +0100 Roland Stigge wrote: > On 07/11/12 16:25, Alban Bedel wrote: > > Signed-off-by: Alban Bedel > > --- > > drivers/pwm/pwm-lpc32xx.c |6 +- > > 1 files changed, 5 insertions(+), 1 deletions(-) > > > > diff --git a/drivers/pwm/pwm-lpc32xx.c b/drivers/pwm/pwm-lpc32xx.c > > index adb87f0..0dc278d 100644 > > --- a/drivers/pwm/pwm-lpc32xx.c > > +++ b/drivers/pwm/pwm-lpc32xx.c > > @@ -51,7 +51,11 @@ static int lpc32xx_pwm_config(struct pwm_chip *chip, > > struct pwm_device *pwm, > > > > c = 256 * duty_ns; > > do_div(c, period_ns); > > - duty_cycles = c; > > + if (c == 0) > > + c = 256; > > + if (c > 255) > > + c = 255; > > + duty_cycles = 256 - c; > > Except for the range check (for the original c > 255), this results in: > > duty_cycles = 256 - c > > except for (c == 0) where > > duty_cycles = 1 No it lead to duty_cycles = 0 > which actually is > > duty_cycles = (256 - c) - 255 > > (think with the original c) > > i.e. nearly a polarity inversion in the case of (c == 0). > > Why is the case (c == 0) so special here? Maybe you can document this, > if it is really intended? It is intended, the formular for duty value in the register is: duty = (256 - 256*duty_ns/period_ns) % 256 But the code avoid the modulo by clamping '256*duty_ns/period_ns' to 1-256. Perhaps something like: if (c > 255) c = 255; duty_cycles = (256 - c) % 256; would be easier to understand. Alban -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] pwm: lpc32xx - Fix the PWM polarity
On Thu, 08 Nov 2012 11:44:48 +0100 Roland Stigge wrote: > On 08/11/12 11:33, Alban Bedel wrote: > > On Thu, 08 Nov 2012 10:51:35 +0100 > > Roland Stigge wrote: > > > >> On 07/11/12 16:25, Alban Bedel wrote: > >>> Signed-off-by: Alban Bedel > >>> --- > >>> drivers/pwm/pwm-lpc32xx.c |6 +- > >>> 1 files changed, 5 insertions(+), 1 deletions(-) > >>> > >>> diff --git a/drivers/pwm/pwm-lpc32xx.c b/drivers/pwm/pwm-lpc32xx.c > >>> index adb87f0..0dc278d 100644 > >>> --- a/drivers/pwm/pwm-lpc32xx.c > >>> +++ b/drivers/pwm/pwm-lpc32xx.c > >>> @@ -51,7 +51,11 @@ static int lpc32xx_pwm_config(struct pwm_chip *chip, > >>> struct pwm_device *pwm, > >>> > >>> c = 256 * duty_ns; > >>> do_div(c, period_ns); > >>> - duty_cycles = c; > >>> + if (c == 0) > >>> + c = 256; > >>> + if (c > 255) > >>> + c = 255; > >>> + duty_cycles = 256 - c; > >> > >> Except for the range check (for the original c > 255), this results in: > >> > >>duty_cycles = 256 - c > >> > >> except for (c == 0) where > >> > >>duty_cycles = 1 > > > > No it lead to duty_cycles = 0 > > Let's do it step by step with the above code: > > c == 0 > > >>> + if (c == 0) > >>> + c = 256; > > c == 256 > > >>> + if (c > 255) > >>> + c = 255; > > c == 255 > > >>> + duty_cycles = 256 - c; > > c == 1 > > See? Right, my bad. > > > >> which actually is > >> > >>duty_cycles = (256 - c) - 255 > >> > >> (think with the original c) > >> > >> i.e. nearly a polarity inversion in the case of (c == 0). > >> > >> Why is the case (c == 0) so special here? Maybe you can document this, > >> if it is really intended? > > > > It is intended, the formular for duty value in the register is: > > > > duty = (256 - 256*duty_ns/period_ns) % 256 > > Where does this modulo defined? In the Manual, there is sth. like this > defined for RELOADV (tables 606+607), but not for DUTY. > > Maybe I missed sth. in the manual. Link or hint appreciated! The manual doesn't mention this explicitly but you can see that without the modulo when duty_ns==0 DUTY would be 256, but the register is only 8 bits wide (ie. modulo 256). I made a few test and looked at the PWM output on a scope they confirm this: DUTY HIGH LEVEL 1 99.9% 2590.0% 128 50.0% 220 10.0% 2550.1% 0 0.0% I'll resubmit the patch with the clamping in the correct order. Alban -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] pwm: lpc32xx - Fix the PWM polarity
The duty cycles value goes from 1 (99% HIGH) to 256 (0% HIGH) but it is stored modulo 256 in the register as it is only 8 bits wide. Signed-off-by: Alban Bedel --- drivers/pwm/pwm-lpc32xx.c |4 +++- 1 files changed, 3 insertions(+), 1 deletions(-) diff --git a/drivers/pwm/pwm-lpc32xx.c b/drivers/pwm/pwm-lpc32xx.c index adb87f0..2590f8d 100644 --- a/drivers/pwm/pwm-lpc32xx.c +++ b/drivers/pwm/pwm-lpc32xx.c @@ -51,7 +51,9 @@ static int lpc32xx_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, c = 256 * duty_ns; do_div(c, period_ns); - duty_cycles = c; + if (c > 255) + c = 255; + duty_cycles = 256 - c; writel(PWM_ENABLE | PWM_RELOADV(period_cycles) | PWM_DUTY(duty_cycles), lpc32xx->base + (pwm->hwpwm << 2)); -- 1.7.0.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] [media] v4l2-async: Always unregister the subdev on failure
On Fri, 1 Jul 2016 13:55:44 +0200 Hans Verkuil wrote: > On 05/11/2016 06:32 PM, Alban Bedel wrote: > > On Wed, 11 May 2016 12:22:44 -0400 > > Javier Martinez Canillas wrote: > > > >> Hello Alban, > >> > >> On 05/11/2016 11:40 AM, Alban Bedel wrote: > >>> In v4l2_async_test_notify() if the registered_async callback or the > >>> complete notifier returns an error the subdev is not unregistered. > >>> This leave paths where v4l2_async_register_subdev() can fail but > >>> leave the subdev still registered. > >>> > >>> Add the required calls to v4l2_device_unregister_subdev() to plug > >>> these holes. > >>> > >>> Signed-off-by: Alban Bedel > >>> --- > >>> drivers/media/v4l2-core/v4l2-async.c | 10 -- > >>> 1 file changed, 8 insertions(+), 2 deletions(-) > >>> > >>> diff --git a/drivers/media/v4l2-core/v4l2-async.c > >>> b/drivers/media/v4l2-core/v4l2-async.c > >>> index ceb28d4..43393f8 100644 > >>> --- a/drivers/media/v4l2-core/v4l2-async.c > >>> +++ b/drivers/media/v4l2-core/v4l2-async.c > >>> @@ -121,13 +121,19 @@ static int v4l2_async_test_notify(struct > >>> v4l2_async_notifier *notifier, > >>> > >>> ret = v4l2_subdev_call(sd, core, registered_async); > >>> if (ret < 0 && ret != -ENOIOCTLCMD) { > >>> + v4l2_device_unregister_subdev(sd); > >>> if (notifier->unbind) > >>> notifier->unbind(notifier, sd, asd); > >>> return ret; > >>> } > >>> > >>> - if (list_empty(¬ifier->waiting) && notifier->complete) > >>> - return notifier->complete(notifier); > >>> + if (list_empty(¬ifier->waiting) && notifier->complete) { > >>> + ret = notifier->complete(notifier); > >>> + if (ret < 0) { > >>> + v4l2_device_unregister_subdev(sd); > >> > >> Isn't a call to notifier->unbind() missing here as well? > >> > >> Also, I think the error path is becoming too duplicated and complex, so > >> maybe we can have a single error path and use goto labels as is common > >> in Linux? For example something like the following (not tested) can be > >> squashed on top of your change: > > > > Yes, that look better. I'll test it and report tomorrow. > > I haven't heard anything back about this. Did you manage to test it? Yes, that's working fine. Sorry for the delay, I'm sending the v2 patch. Alban pgpXTq6f3KCYt.pgp Description: OpenPGP digital signature
[PATCH] usbnet: ax88179_178a: Add support for writing the EEPROM
Implement the .set_eeprom callback to allow setting the MAC address as well as a few other parameters. Note that the EEPROM must have a correct PID/VID checksum set otherwise the SROM is used and reads return the SROM content. Signed-off-by: Alban Bedel --- drivers/net/usb/ax88179_178a.c | 57 ++ 1 file changed, 57 insertions(+) diff --git a/drivers/net/usb/ax88179_178a.c b/drivers/net/usb/ax88179_178a.c index e6338c16081a..e6a986303dad 100644 --- a/drivers/net/usb/ax88179_178a.c +++ b/drivers/net/usb/ax88179_178a.c @@ -28,6 +28,7 @@ #define AX88179_PHY_ID 0x03 #define AX_EEPROM_LEN 0x100 +#define AX_EEPROM_BLOCK0x40u #define AX88179_EEPROM_MAGIC 0x17900b95 #define AX_MCAST_FLTSIZE 8 #define AX_MAX_MCAST 64 @@ -43,6 +44,7 @@ #define AX_ACCESS_PHY 0x02 #define AX_ACCESS_EEPROM 0x04 #define AX_ACCESS_EFUS 0x05 +#define AX_RELOAD_EEPROM 0x06 #define AX_PAUSE_WATERLVL_HIGH 0x54 #define AX_PAUSE_WATERLVL_LOW 0x55 @@ -620,6 +622,60 @@ ax88179_get_eeprom(struct net_device *net, struct ethtool_eeprom *eeprom, return 0; } +static int +ax88179_set_eeprom(struct net_device *net, struct ethtool_eeprom *eeprom, + u8 *data) +{ + struct usbnet *dev = netdev_priv(net); + unsigned int offset = eeprom->offset; + unsigned int len = eeprom->len; + int i, err = 0; + u8 *block; + + /* The EEPROM data must be aligned on blocks of 64 bytes */ + if ((offset % AX_EEPROM_BLOCK) || (len % AX_EEPROM_BLOCK)) { + offset = eeprom->offset / AX_EEPROM_BLOCK * AX_EEPROM_BLOCK; + len = eeprom->len + eeprom->offset - offset; + len = DIV_ROUND_UP(len, AX_EEPROM_BLOCK) * AX_EEPROM_BLOCK; + + block = kmalloc(len, GFP_KERNEL); + if (!block) + return -ENOMEM; + + /* Copy the current data, we could skip some but KISS */ + for (i = 0; i < len; i += AX_EEPROM_BLOCK) { + err = __ax88179_read_cmd(dev, AX_ACCESS_EEPROM, +(offset + i) >> 1, +AX_EEPROM_BLOCK >> 1, +AX_EEPROM_BLOCK, +&block[i], 0); + if (err < 0) { + kfree(block); + return err; + } + } + memcpy(block + eeprom->offset - offset, data, eeprom->len); + } else { + block = data; + } + + for (i = 0; err >= 0 && i < len; i += AX_EEPROM_BLOCK) { + err = ax88179_write_cmd(dev, AX_ACCESS_EEPROM, + (offset + i) >> 1, + AX_EEPROM_BLOCK >> 1, + AX_EEPROM_BLOCK, &block[i]); + } + + if (block != data) + kfree(block); + + /* Reload the EEPROM */ + if (err >= 0) + err = ax88179_write_cmd(dev, AX_RELOAD_EEPROM, 0, 0, 0, NULL); + + return err < 0 ? err : 0; +} + static int ax88179_get_settings(struct net_device *net, struct ethtool_cmd *cmd) { struct usbnet *dev = netdev_priv(net); @@ -826,6 +882,7 @@ static const struct ethtool_ops ax88179_ethtool_ops = { .set_wol= ax88179_set_wol, .get_eeprom_len = ax88179_get_eeprom_len, .get_eeprom = ax88179_get_eeprom, + .set_eeprom = ax88179_set_eeprom, .get_settings = ax88179_get_settings, .set_settings = ax88179_set_settings, .get_eee= ax88179_get_eee, -- 2.9.3
[PATCH v2] [media] v4l2-async: Always unregister the subdev on failure
In v4l2_async_test_notify() if the registered_async callback or the complete notifier returns an error the subdev is not unregistered. This leave paths where v4l2_async_register_subdev() can fail but leave the subdev still registered. Add the required calls to v4l2_device_unregister_subdev() to plug these holes. Signed-off-by: Alban Bedel --- Changelog: v2: * Added the missing unbind() calls as suggested by Javier. --- drivers/media/v4l2-core/v4l2-async.c | 29 + 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/drivers/media/v4l2-core/v4l2-async.c b/drivers/media/v4l2-core/v4l2-async.c index ceb28d47c3f9..abe512d0b4cb 100644 --- a/drivers/media/v4l2-core/v4l2-async.c +++ b/drivers/media/v4l2-core/v4l2-async.c @@ -113,23 +113,28 @@ static int v4l2_async_test_notify(struct v4l2_async_notifier *notifier, list_move(&sd->async_list, ¬ifier->done); ret = v4l2_device_register_subdev(notifier->v4l2_dev, sd); - if (ret < 0) { - if (notifier->unbind) - notifier->unbind(notifier, sd, asd); - return ret; - } + if (ret < 0) + goto err_subdev_register; ret = v4l2_subdev_call(sd, core, registered_async); - if (ret < 0 && ret != -ENOIOCTLCMD) { - if (notifier->unbind) - notifier->unbind(notifier, sd, asd); - return ret; + if (ret < 0 && ret != -ENOIOCTLCMD) + goto err_subdev_call; + + if (list_empty(¬ifier->waiting) && notifier->complete) { + ret = notifier->complete(notifier); + if (ret < 0) + goto err_subdev_call; } - if (list_empty(¬ifier->waiting) && notifier->complete) - return notifier->complete(notifier); - return 0; + +err_subdev_call: + v4l2_device_unregister_subdev(sd); +err_subdev_register: + if (notifier->unbind) + notifier->unbind(notifier, sd, asd); + + return ret; } static void v4l2_async_cleanup(struct v4l2_subdev *sd) -- 2.9.3
Re: [PATCH] usbnet: ax88179_178a: Add support for writing the EEPROM
On Wed, 24 Aug 2016 16:30:39 +0200 Oliver Neukum wrote: > On Wed, 2016-08-24 at 15:52 +0200, Alban Bedel wrote: > > Implement the .set_eeprom callback to allow setting the MAC address > > as well as a few other parameters. Note that the EEPROM must have a > > correct PID/VID checksum set otherwise the SROM is used and reads > > return the SROM content. > > > > Signed-off-by: Alban Bedel > > --- > > drivers/net/usb/ax88179_178a.c | 57 > > ++ > > 1 file changed, 57 insertions(+) > > > > diff --git a/drivers/net/usb/ax88179_178a.c > > b/drivers/net/usb/ax88179_178a.c > > index e6338c16081a..e6a986303dad 100644 > > --- a/drivers/net/usb/ax88179_178a.c > > +++ b/drivers/net/usb/ax88179_178a.c > > @@ -28,6 +28,7 @@ > > > > #define AX88179_PHY_ID 0x03 > > #define AX_EEPROM_LEN 0x100 > > +#define AX_EEPROM_BLOCK0x40u > > #define AX88179_EEPROM_MAGIC 0x17900b95 > > #define AX_MCAST_FLTSIZE 8 > > #define AX_MAX_MCAST 64 > > @@ -43,6 +44,7 @@ > > #define AX_ACCESS_PHY 0x02 > > #define AX_ACCESS_EEPROM 0x04 > > #define AX_ACCESS_EFUS 0x05 > > +#define AX_RELOAD_EEPROM 0x06 > > #define AX_PAUSE_WATERLVL_HIGH 0x54 > > #define AX_PAUSE_WATERLVL_LOW 0x55 > > > > @@ -620,6 +622,60 @@ ax88179_get_eeprom(struct net_device *net, struct > > ethtool_eeprom *eeprom, > > return 0; > > } > > > > +static int > > +ax88179_set_eeprom(struct net_device *net, struct ethtool_eeprom > > *eeprom, > > + u8 *data) > > +{ > > + struct usbnet *dev = netdev_priv(net); > > + unsigned int offset = eeprom->offset; > > + unsigned int len = eeprom->len; > > + int i, err = 0; > > + u8 *block; > > + > > + /* The EEPROM data must be aligned on blocks of 64 bytes */ > > + if ((offset % AX_EEPROM_BLOCK) || (len % AX_EEPROM_BLOCK)) { > > + offset = eeprom->offset / AX_EEPROM_BLOCK * > > AX_EEPROM_BLOCK; > > + len = eeprom->len + eeprom->offset - offset; > > + len = DIV_ROUND_UP(len, AX_EEPROM_BLOCK) * > > AX_EEPROM_BLOCK; > > + > > + block = kmalloc(len, GFP_KERNEL); > > + if (!block) > > + return -ENOMEM; > > + > > + /* Copy the current data, we could skip some but KISS > > */ > > + for (i = 0; i < len; i += AX_EEPROM_BLOCK) { > > + err = __ax88179_read_cmd(dev, > > AX_ACCESS_EEPROM, > > +(offset + i) >> 1, > > +AX_EEPROM_BLOCK >> 1, > > +AX_EEPROM_BLOCK, > > +&block[i], 0); > > + if (err < 0) { > > + kfree(block); > > + return err; > > + } > > + } > > + memcpy(block + eeprom->offset - offset, data, > > eeprom->len); > > + } else { > > + block = data; > > + } > > + > > + for (i = 0; err >= 0 && i < len; i += AX_EEPROM_BLOCK) { > > + err = ax88179_write_cmd(dev, AX_ACCESS_EEPROM, > > + (offset + i) >> 1, > > + AX_EEPROM_BLOCK >> 1, > > + AX_EEPROM_BLOCK, &block[i]); > > + } > > + > > + if (block != data) > > + kfree(block); > > And if block == dta, what frees the memory? In this case this function didn't allocate any memory, so there is nothing to free. Alban pgpG1wkRaedOX.pgp Description: OpenPGP digital signature
Re: [PATCH] usbnet: ax88179_178a: Add support for writing the EEPROM
On Thu, 25 Aug 2016 11:16:36 +0200 Oliver Neukum wrote: > On Wed, 2016-08-24 at 16:40 +0200, Alban Bedel wrote: > > On Wed, 24 Aug 2016 16:30:39 +0200 > > Oliver Neukum wrote: > > > > > On Wed, 2016-08-24 at 15:52 +0200, Alban Bedel wrote: > > > > > + if (block != data) > > > > + kfree(block); > > > > > > And if block == dta, what frees the memory? > > > > In this case this function didn't allocate any memory, so there is > > nothing to free. > > Hi, > > I see. kfree() has a check for NULL, so you could drop the > test, but it doesn't matter much either way. I think you misunderstand something here. data is the buffer passed by the caller and block is a local variable. There is two cases: 1) The data to write is block aligned, then we use the caller buffer as is and set block = data. 2) The requested data is not block aligned, then we kalloc block. In both case the writing loop then use the block pointer. Afterwards we only need to kfree block in case 2, that is when block != data. Alban pgpsdCKDOvchx.pgp Description: OpenPGP digital signature
[PATCH] gpio: ath79: Convert to the state container design pattern
Turn the ath79 driver into a true driver supporting multiple instances. While at it also removed unneed includes and make use of the BIT() macro. Signed-off-by: Alban Bedel --- This patch apply on top of my previous MIPS GPIO patches that are pending for 4.3, so it might be better to take it thru the MIPS tree. Alban --- drivers/gpio/gpio-ath79.c | 129 +++--- 1 file changed, 65 insertions(+), 64 deletions(-) diff --git a/drivers/gpio/gpio-ath79.c b/drivers/gpio/gpio-ath79.c index 03b9953..e5827a5 100644 --- a/drivers/gpio/gpio-ath79.c +++ b/drivers/gpio/gpio-ath79.c @@ -12,61 +12,51 @@ * by the Free Software Foundation. */ -#include -#include -#include -#include -#include -#include -#include -#include +#include #include #include #include -static void __iomem *ath79_gpio_base; -static u32 ath79_gpio_count; -static DEFINE_SPINLOCK(ath79_gpio_lock); +struct ath79_gpio_ctrl { + struct gpio_chip chip; + void __iomem *base; + spinlock_t lock; +}; -static void __ath79_gpio_set_value(unsigned gpio, int value) -{ - void __iomem *base = ath79_gpio_base; - - if (value) - __raw_writel(1 << gpio, base + AR71XX_GPIO_REG_SET); - else - __raw_writel(1 << gpio, base + AR71XX_GPIO_REG_CLEAR); -} - -static int __ath79_gpio_get_value(unsigned gpio) -{ - return (__raw_readl(ath79_gpio_base + AR71XX_GPIO_REG_IN) >> gpio) & 1; -} - -static int ath79_gpio_get_value(struct gpio_chip *chip, unsigned offset) -{ - return __ath79_gpio_get_value(offset); -} +#define to_ath79_gpio_ctrl(c) container_of(c, struct ath79_gpio_ctrl, chip) static void ath79_gpio_set_value(struct gpio_chip *chip, - unsigned offset, int value) + unsigned gpio, int value) { - __ath79_gpio_set_value(offset, value); + struct ath79_gpio_ctrl *ctrl = to_ath79_gpio_ctrl(chip); + + if (value) + __raw_writel(BIT(gpio), ctrl->base + AR71XX_GPIO_REG_SET); + else + __raw_writel(BIT(gpio), ctrl->base + AR71XX_GPIO_REG_CLEAR); +} + +static int ath79_gpio_get_value(struct gpio_chip *chip, unsigned gpio) +{ + struct ath79_gpio_ctrl *ctrl = to_ath79_gpio_ctrl(chip); + + return (__raw_readl(ctrl->base + AR71XX_GPIO_REG_IN) >> gpio) & 1; } static int ath79_gpio_direction_input(struct gpio_chip *chip, unsigned offset) { - void __iomem *base = ath79_gpio_base; + struct ath79_gpio_ctrl *ctrl = to_ath79_gpio_ctrl(chip); unsigned long flags; - spin_lock_irqsave(&ath79_gpio_lock, flags); + spin_lock_irqsave(&ctrl->lock, flags); - __raw_writel(__raw_readl(base + AR71XX_GPIO_REG_OE) & ~(1 << offset), -base + AR71XX_GPIO_REG_OE); + __raw_writel( + __raw_readl(ctrl->base + AR71XX_GPIO_REG_OE) & ~BIT(offset), + ctrl->base + AR71XX_GPIO_REG_OE); - spin_unlock_irqrestore(&ath79_gpio_lock, flags); + spin_unlock_irqrestore(&ctrl->lock, flags); return 0; } @@ -74,35 +64,37 @@ static int ath79_gpio_direction_input(struct gpio_chip *chip, static int ath79_gpio_direction_output(struct gpio_chip *chip, unsigned offset, int value) { - void __iomem *base = ath79_gpio_base; + struct ath79_gpio_ctrl *ctrl = to_ath79_gpio_ctrl(chip); unsigned long flags; - spin_lock_irqsave(&ath79_gpio_lock, flags); + spin_lock_irqsave(&ctrl->lock, flags); if (value) - __raw_writel(1 << offset, base + AR71XX_GPIO_REG_SET); + __raw_writel(BIT(offset), ctrl->base + AR71XX_GPIO_REG_SET); else - __raw_writel(1 << offset, base + AR71XX_GPIO_REG_CLEAR); + __raw_writel(BIT(offset), ctrl->base + AR71XX_GPIO_REG_CLEAR); - __raw_writel(__raw_readl(base + AR71XX_GPIO_REG_OE) | (1 << offset), -base + AR71XX_GPIO_REG_OE); + __raw_writel( + __raw_readl(ctrl->base + AR71XX_GPIO_REG_OE) | BIT(offset), + ctrl->base + AR71XX_GPIO_REG_OE); - spin_unlock_irqrestore(&ath79_gpio_lock, flags); + spin_unlock_irqrestore(&ctrl->lock, flags); return 0; } static int ar934x_gpio_direction_input(struct gpio_chip *chip, unsigned offset) { - void __iomem *base = ath79_gpio_base; + struct ath79_gpio_ctrl *ctrl = to_ath79_gpio_ctrl(chip); unsigned long flags; - spin_lock_irqsave(&ath79_gpio_lock, flags); + spin_lock_irqsave(&ctrl->lock, flags); - __raw_writel(__raw_readl(base + AR71XX_GPIO_REG_OE) | (1 << offset), -base + AR71XX_GPIO_RE
[PATCH 1/4] devicetree: Add bindings for the ATH79 USB phy
Signed-off-by: Alban Bedel --- .../devicetree/bindings/phy/phy-ath79-usb.txt | 18 ++ 1 file changed, 18 insertions(+) create mode 100644 Documentation/devicetree/bindings/phy/phy-ath79-usb.txt diff --git a/Documentation/devicetree/bindings/phy/phy-ath79-usb.txt b/Documentation/devicetree/bindings/phy/phy-ath79-usb.txt new file mode 100644 index 000..cafe219 --- /dev/null +++ b/Documentation/devicetree/bindings/phy/phy-ath79-usb.txt @@ -0,0 +1,18 @@ +* Atheros AR71XX/9XXX USB PHY + +Required properties: +- compatible: "qca,ar7100-usb-phy" +- #phys-cells: should be 0 +- reset-names: "usb-phy"[, "usb-suspend-override"] +- resets: references to the reset controllers + +Example: + + usb-phy { + compatible = "qca,ar7100-usb-phy"; + + reset-names = "usb-phy", "usb-suspend-override"; + resets = <&rst 4>, <&rst 3>; + + #phy-cells = <0>; + }; -- 2.0.0 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 0/4] MIPS: ath79: Add USB support on the TL-WR1043ND
Hi, this serie add a driver for the USB phy on the ATH79 SoCs and enable the USB port on the TL-WR1043ND. The phy controller is really trivial as it only use reset lines. Alban Alban Bedel (4): devicetree: Add bindings for the ATH79 USB phy phy: Add a driver for the ATH79 USB phy MIPS: ath79: Add the EHCI controller and USB phy to the AR9132 dtsi MIPS: ath79: Enable the USB port on the TL-WR1043ND .../devicetree/bindings/phy/phy-ath79-usb.txt | 18 arch/mips/boot/dts/qca/ar9132.dtsi | 24 + arch/mips/boot/dts/qca/ar9132_tl_wr1043nd_v1.dts | 4 + drivers/phy/Kconfig| 8 ++ drivers/phy/Makefile | 1 + drivers/phy/phy-ath79-usb.c| 115 + 6 files changed, 170 insertions(+) create mode 100644 Documentation/devicetree/bindings/phy/phy-ath79-usb.txt create mode 100644 drivers/phy/phy-ath79-usb.c -- 2.0.0 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 2/4] phy: Add a driver for the ATH79 USB phy
The ATH79 USB phy is very simple, it only have a reset. On some SoC a second reset is used to force the phy in suspend mode regardless of the USB controller status. Signed-off-by: Alban Bedel --- drivers/phy/Kconfig | 8 +++ drivers/phy/Makefile| 1 + drivers/phy/phy-ath79-usb.c | 115 3 files changed, 124 insertions(+) create mode 100644 drivers/phy/phy-ath79-usb.c diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig index 47da573..aa950a7 100644 --- a/drivers/phy/Kconfig +++ b/drivers/phy/Kconfig @@ -15,6 +15,14 @@ config GENERIC_PHY phy users can obtain reference to the PHY. All the users of this framework should select this config. +config PHY_ATH79_USB + tristate "Atheros AR71XX/9XXX USB PHY driver" + depends on ATH79 || COMPILE_TEST + default y if USB_EHCI_HCD_PLATFORM + select GENERIC_PHY + help + Enable this to support the USB PHY on Atheros AR71XX/9XXX SoCs. + config PHY_BERLIN_USB tristate "Marvell Berlin USB PHY Driver" depends on ARCH_BERLIN && RESET_CONTROLLER && HAS_IOMEM && OF diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile index a5b18c1..ba13fcf 100644 --- a/drivers/phy/Makefile +++ b/drivers/phy/Makefile @@ -3,6 +3,7 @@ # obj-$(CONFIG_GENERIC_PHY) += phy-core.o +obj-$(CONFIG_PHY_ATH79_USB)+= phy-ath79-usb.o obj-$(CONFIG_PHY_BERLIN_USB) += phy-berlin-usb.o obj-$(CONFIG_PHY_BERLIN_SATA) += phy-berlin-sata.o obj-$(CONFIG_PHY_DM816X_USB) += phy-dm816x-usb.o diff --git a/drivers/phy/phy-ath79-usb.c b/drivers/phy/phy-ath79-usb.c new file mode 100644 index 000..d26aabe --- /dev/null +++ b/drivers/phy/phy-ath79-usb.c @@ -0,0 +1,115 @@ +/* + * Copyright (C) 2015 Alban Bedel + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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. + */ + +#include +#include +#include +#include + +struct ath79_usb_phy { + struct reset_control *reset; + struct reset_control *suspend_override; +}; + +static int ath79_usb_phy_power_on(struct phy *phy) +{ + struct ath79_usb_phy *priv = phy_get_drvdata(phy); + int err; + + err = reset_control_deassert(priv->reset); + if (err) + return err; + + if (priv->suspend_override) { + err = reset_control_assert(priv->suspend_override); + if (err) + return err; + } + + return 0; +} + +static int ath79_usb_phy_power_off(struct phy *phy) +{ + struct ath79_usb_phy *priv = phy_get_drvdata(phy); + int err; + + if (priv->suspend_override) { + err = reset_control_deassert(priv->suspend_override); + if (err) + return err; + } + + err = reset_control_assert(priv->reset); + if (err) + return err; + + return 0; +} + +static struct phy_ops ath79_usb_phy_ops = { + .power_on = ath79_usb_phy_power_on, + .power_off = ath79_usb_phy_power_off, + .owner = THIS_MODULE, +}; + +static int ath79_usb_phy_probe(struct platform_device *pdev) +{ + struct ath79_usb_phy *priv; + struct phy *phy; + + priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + priv->reset = devm_reset_control_get(&pdev->dev, "usb-phy"); + if (IS_ERR(priv->reset)) + return PTR_ERR(priv->reset); + + priv->suspend_override = devm_reset_control_get_optional( + &pdev->dev, "usb-suspend-override"); + if (IS_ERR(priv->suspend_override)) { + if (PTR_ERR(priv->suspend_override) == -ENOENT) + priv->suspend_override = NULL; + else + return PTR_ERR(priv->suspend_override); + } + + phy = devm_phy_create(&pdev->dev, NULL, &ath79_usb_phy_ops); + if (IS_ERR(phy)) + return PTR_ERR(phy); + phy_set_drvdata(phy, priv); + + return PTR_ERR_OR_ZERO(devm_of_phy_provider_register( + &pdev->dev, of_phy_simple_xlate)); +} + +static const struct of_device_id ath79_usb_phy_of_match[] = { + { .compatible = "qca,ar7100-usb-phy" }, + {} +}; +MODULE_DEVICE_TABLE(of, ath79_usb_phy_of_m
[PATCH 3/4] MIPS: ath79: Add the EHCI controller and USB phy to the AR9132 dtsi
Signed-off-by: Alban Bedel --- arch/mips/boot/dts/qca/ar9132.dtsi | 24 1 file changed, 24 insertions(+) diff --git a/arch/mips/boot/dts/qca/ar9132.dtsi b/arch/mips/boot/dts/qca/ar9132.dtsi index fb7734e..665ee84 100644 --- a/arch/mips/boot/dts/qca/ar9132.dtsi +++ b/arch/mips/boot/dts/qca/ar9132.dtsi @@ -125,6 +125,21 @@ }; }; + ehci@1b000100 { + compatible = "qca,ar7100-ehci", "generic-ehci"; + reg = <0x1b000100 0x100>; + + interrupts = <3>; + resets = <&rst 5>; + + has-transaction-translator; + + phy-names = "usb"; + phys = <&usb_phy>; + + status = "disabled"; + }; + spi@1f00 { compatible = "qca,ar9132-spi", "qca,ar7100-spi"; reg = <0x1f00 0x10>; @@ -138,4 +153,13 @@ #size-cells = <0>; }; }; + + usb_phy: usb-phy { + compatible = "qca,ar7100-usb-phy"; + + reset-names = "usb-phy", "usb-suspend-override"; + resets = <&rst 4>, <&rst 3>; + + #phy-cells = <0>; + }; }; -- 2.0.0 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 4/4] MIPS: ath79: Enable the USB port on the TL-WR1043ND
Signed-off-by: Alban Bedel --- arch/mips/boot/dts/qca/ar9132_tl_wr1043nd_v1.dts | 4 1 file changed, 4 insertions(+) diff --git a/arch/mips/boot/dts/qca/ar9132_tl_wr1043nd_v1.dts b/arch/mips/boot/dts/qca/ar9132_tl_wr1043nd_v1.dts index 003015a..cd51199 100644 --- a/arch/mips/boot/dts/qca/ar9132_tl_wr1043nd_v1.dts +++ b/arch/mips/boot/dts/qca/ar9132_tl_wr1043nd_v1.dts @@ -35,6 +35,10 @@ }; }; + ehci@1b000100 { + status = "okay"; + }; + spi@1f00 { status = "okay"; num-cs = <1>; -- 2.0.0 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] reset: Fix of_reset_control_get() for consistent return values
When of_reset_control_get() is called without connection ID it returns -ENOENT when the 'resets' property doesn't exists or is an empty entry. However when a connection ID is given it returns -EINVAL when the 'resets' property doesn't exists or the requested name can't be found. This is because the error code returned by of_property_match_string() is just passed down as an index to of_parse_phandle_with_args(), which then returns -EINVAL. To get a consistent return value with both code paths we must return -ENOENT when of_property_match_string() fails. Signed-off-by: Alban Bedel --- drivers/reset/core.c | 5 - 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/reset/core.c b/drivers/reset/core.c index 3cbc764..fd6ac9b 100644 --- a/drivers/reset/core.c +++ b/drivers/reset/core.c @@ -265,9 +265,12 @@ struct reset_control *of_reset_control_get(struct device_node *node, int rstc_id; int ret; - if (id) + if (id) { index = of_property_match_string(node, "reset-names", id); + if (index < 0) + return ERR_PTR(-ENOENT); + } ret = of_parse_phandle_with_args(node, "resets", "#reset-cells", index, &args); if (ret) -- 2.0.0 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] MIPS: Fix the build on jz4740 after removing the custom gpio.h
Somehow the wrong version of the patch to remove the use of custom gpio.h on mips has been merged. This patch add the missing fixes for a build error on jz4740 because linux/gpio.h doesn't provide any machine specfics definitions anymore. Signed-off-by: Alban Bedel --- arch/mips/jz4740/board-qi_lb60.c | 1 + arch/mips/jz4740/gpio.c | 1 + 2 files changed, 2 insertions(+) diff --git a/arch/mips/jz4740/board-qi_lb60.c b/arch/mips/jz4740/board-qi_lb60.c index 4e62bf8..459cb01 100644 --- a/arch/mips/jz4740/board-qi_lb60.c +++ b/arch/mips/jz4740/board-qi_lb60.c @@ -26,6 +26,7 @@ #include #include +#include #include #include #include diff --git a/arch/mips/jz4740/gpio.c b/arch/mips/jz4740/gpio.c index 6cd69fd..3866263 100644 --- a/arch/mips/jz4740/gpio.c +++ b/arch/mips/jz4740/gpio.c @@ -28,6 +28,7 @@ #include #include +#include #define JZ4740_GPIO_BASE_A (32*0) #define JZ4740_GPIO_BASE_B (32*1) -- 2.0.0 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] phy: Add a driver for the ATH79 USB phy
The ATH79 USB phy is very simple, it only have a reset. On some SoC a second reset is used to force the phy in suspend mode regardless of the USB controller status. This driver is added to the qualcom directory as atheros is now part of qualcom and newer SoC of this familly are marketed under the qualcom name. Signed-off-by: Alban Bedel --- MAINTAINERS | 8 +++ drivers/phy/qualcomm/Kconfig | 11 +++- drivers/phy/qualcomm/Makefile| 1 + drivers/phy/qualcomm/phy-ath79-usb.c | 108 +++ 4 files changed, 127 insertions(+), 1 deletion(-) create mode 100644 drivers/phy/qualcomm/phy-ath79-usb.c diff --git a/MAINTAINERS b/MAINTAINERS index 73c0cda..ce5ecd6 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2294,6 +2294,14 @@ S: Maintained F: drivers/gpio/gpio-ath79.c F: Documentation/devicetree/bindings/gpio/gpio-ath79.txt +ATHEROS 71XX/9XXX USB PHY DRIVER +M: Alban Bedel +W: https://github.com/AlbanBedel/linux +T: git git://github.com/AlbanBedel/linux +S: Maintained +F: drivers/phy/qualcomm/phy-ath79-usb.c +F: Documentation/devicetree/bindings/phy/phy-ath79-usb.txt + ATHEROS ATH GENERIC UTILITIES M: "Luis R. Rodriguez" L: linux-wirel...@vger.kernel.org diff --git a/drivers/phy/qualcomm/Kconfig b/drivers/phy/qualcomm/Kconfig index 7bfa64b..632a0e7 100644 --- a/drivers/phy/qualcomm/Kconfig +++ b/drivers/phy/qualcomm/Kconfig @@ -1,6 +1,15 @@ # -# Phy drivers for Qualcomm platforms +# Phy drivers for Qualcomm and Atheros platforms # +config PHY_ATH79_USB + tristate "Atheros AR71XX/9XXX USB PHY driver" + depends on OF && (ATH79 || COMPILE_TEST) + default y if USB_EHCI_HCD_PLATFORM || USB_OHCI_HCD_PLATFORM + select RESET_CONTROLLER + select GENERIC_PHY + help + Enable this to support the USB PHY on Atheros AR71XX/9XXX SoCs. + config PHY_QCOM_APQ8064_SATA tristate "Qualcomm APQ8064 SATA SerDes/PHY driver" depends on ARCH_QCOM diff --git a/drivers/phy/qualcomm/Makefile b/drivers/phy/qualcomm/Makefile index 9abb789..deb831f4 100644 --- a/drivers/phy/qualcomm/Makefile +++ b/drivers/phy/qualcomm/Makefile @@ -1,4 +1,5 @@ # SPDX-License-Identifier: GPL-2.0 +obj-$(CONFIG_PHY_ATH79_USB)+= phy-ath79-usb.o obj-$(CONFIG_PHY_QCOM_APQ8064_SATA)+= phy-qcom-apq8064-sata.o obj-$(CONFIG_PHY_QCOM_IPQ806X_SATA)+= phy-qcom-ipq806x-sata.o obj-$(CONFIG_PHY_QCOM_QMP) += phy-qcom-qmp.o diff --git a/drivers/phy/qualcomm/phy-ath79-usb.c b/drivers/phy/qualcomm/phy-ath79-usb.c new file mode 100644 index 000..6fd6e07 --- /dev/null +++ b/drivers/phy/qualcomm/phy-ath79-usb.c @@ -0,0 +1,108 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Atheros AR71XX/9XXX USB PHY driver + * + * Copyright (C) 2015-2018 Alban Bedel + */ + +#include +#include +#include +#include + +struct ath79_usb_phy { + struct reset_control *reset; + /* The suspend override logic is inverted, hence the no prefix +* to make the code a bit easier to understand. +*/ + struct reset_control *no_suspend_override; +}; + +static int ath79_usb_phy_power_on(struct phy *phy) +{ + struct ath79_usb_phy *priv = phy_get_drvdata(phy); + int err = 0; + + if (priv->no_suspend_override) { + err = reset_control_assert(priv->no_suspend_override); + if (err) + return err; + } + + err = reset_control_deassert(priv->reset); + if (err && priv->no_suspend_override) + reset_control_assert(priv->no_suspend_override); + + return err; +} + +static int ath79_usb_phy_power_off(struct phy *phy) +{ + struct ath79_usb_phy *priv = phy_get_drvdata(phy); + int err = 0; + + err = reset_control_assert(priv->reset); + if (err) + return err; + + if (priv->no_suspend_override) { + err = reset_control_deassert(priv->no_suspend_override); + if (err) + reset_control_deassert(priv->reset); + } + + return err; +} + +static const struct phy_ops ath79_usb_phy_ops = { + .power_on = ath79_usb_phy_power_on, + .power_off = ath79_usb_phy_power_off, + .owner = THIS_MODULE, +}; + +static int ath79_usb_phy_probe(struct platform_device *pdev) +{ + struct ath79_usb_phy *priv; + struct phy *phy; + + priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + priv->reset = devm_reset_control_get(&pdev->dev, "usb-phy"); + if (IS_ERR(priv->reset)) + return PTR_ERR(priv->reset); + + priv->no_suspend_override = devm_reset_control_get_optional( + &pdev->dev, "usb-suspend-override&q
[PATCH] usb: host: Remove the deprecated ATH79 USB host config options
The options USB_EHCI_ATH79 and USB_OHCI_ATH79 only enable the generic EHCI and OHCI platform drivers, and have been marked as deprecated since 2012. These can be safely removed if we make sure that USB_EHCI_ROOT_HUB_TT still get enabled for the EHCI driver. This is now done be selecting this option when the EHCI platform driver is enabled on the ATH79 platform. Signed-off-by: Alban Bedel --- arch/mips/Kconfig| 1 + drivers/usb/host/Kconfig | 25 - 2 files changed, 1 insertion(+), 25 deletions(-) diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 8128c3b..61e9a24 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -200,6 +200,7 @@ config ATH79 select SYS_SUPPORTS_MIPS16 select SYS_SUPPORTS_ZBOOT_UART_PROM select USE_OF + select USB_EHCI_ROOT_HUB_TT if USB_EHCI_HCD_PLATFORM help Support for the Atheros AR71XX/AR724X/AR913X SoCs. diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index 4fcfb30..55b45dc 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig @@ -293,19 +293,6 @@ config USB_CNS3XXX_EHCI It is needed for high-speed (480Mbit/sec) USB 2.0 device support. -config USB_EHCI_ATH79 - bool "EHCI support for AR7XXX/AR9XXX SoCs (DEPRECATED)" - depends on (SOC_AR71XX || SOC_AR724X || SOC_AR913X || SOC_AR933X) - select USB_EHCI_ROOT_HUB_TT - select USB_EHCI_HCD_PLATFORM - default y - ---help--- - This option is deprecated now and the driver was removed, use - USB_EHCI_HCD_PLATFORM instead. - - Enables support for the built-in EHCI controller present - on the Atheros AR7XXX/AR9XXX SoCs. - config USB_EHCI_HCD_PLATFORM tristate "Generic EHCI driver for a platform device" default n @@ -489,18 +476,6 @@ config USB_OHCI_HCD_DAVINCI controller. This driver cannot currently be a loadable module because it lacks a proper PHY abstraction. -config USB_OHCI_ATH79 - bool "USB OHCI support for the Atheros AR71XX/AR7240 SoCs (DEPRECATED)" - depends on (SOC_AR71XX || SOC_AR724X) - select USB_OHCI_HCD_PLATFORM - default y - help - This option is deprecated now and the driver was removed, use - USB_OHCI_HCD_PLATFORM instead. - - Enables support for the built-in OHCI controller present on the - Atheros AR71XX/AR7240 SoCs. - config USB_OHCI_HCD_PPC_OF_BE bool "OHCI support for OF platform bus (big endian)" depends on PPC -- 2.7.4
[PATCH v3 1/3] nvmem: Update the OF binding to use a subnode for the cells list
Having the cells as subnodes of the provider device without any compatible property might clash with other bindings. To avoid this problem update the binding to have all the cells in a 'nvmem-cells' subnode with a 'nvmem-cells' compatible string. This new binding guarantee that we can turn any kind of device in a nvmem provider. While discouraged for new uses the old scheme is still supported for backward compatibility. Signed-off-by: Alban Bedel --- Documentation/devicetree/bindings/nvmem/nvmem.txt | 55 --- drivers/nvmem/core.c | 10 + 2 files changed, 48 insertions(+), 17 deletions(-) diff --git a/Documentation/devicetree/bindings/nvmem/nvmem.txt b/Documentation/devicetree/bindings/nvmem/nvmem.txt index fd06c09..6b723e7 100644 --- a/Documentation/devicetree/bindings/nvmem/nvmem.txt +++ b/Documentation/devicetree/bindings/nvmem/nvmem.txt @@ -11,14 +11,29 @@ these data from, and where they are stored on the storage device. This document is here to document this. = Data providers = -Contains bindings specific to provider drivers and data cells as children -of this node. +A data provider should have a subnode named 'nvmem-cells' that contains +a subnodes for each data cells. + +For backward compatibility the nvmem data cells can be direct children +of the data provider. This use is discouraged as it can conflict with +other bindings. Optional properties: read-only: Mark the provider as read only. += Data cells list = +The data cells list node should be named 'nvmem-cells' and have a +child node for each data cell. + +Required properties: + compatible: Must be "nvmem-cells" + #address-cells: <1> if the provider use 32 bit addressing, + <2> for 64 bits addressing + #size-cells: <1> if the provider use 32 bit sizes, + <2> for 64 bits sizes + = Data cells = -These are the child nodes of the provider which contain data cell +These are the child nodes of the nvmem-cells node which contain data cell information like offset and size in nvmem provider. Required properties: @@ -37,24 +52,30 @@ For example: ... /* Data cells */ - tsens_calibration: calib@404 { - reg = <0x404 0x10>; - }; + nvmem-cells { + compatible = "nvmem-cells"; + #address-cells = <1>; + #size-cells = <1>; - tsens_calibration_bckp: calib_bckp@504 { - reg = <0x504 0x11>; - bits = <6 128> - }; + tsens_calibration: calib@404 { + reg = <0x404 0x10>; + }; - pvs_version: pvs-version@6 { - reg = <0x6 0x2> - bits = <7 2> - }; + tsens_calibration_bckp: calib_bckp@504 { + reg = <0x504 0x11>; + bits = <6 128> + }; - speed_bin: speed-bin@c{ - reg = <0xc 0x1>; - bits = <2 3>; + pvs_version: pvs-version@6 { + reg = <0x6 0x2> + bits = <7 2> + }; + speed_bin: speed-bin@c{ + reg = <0xc 0x1>; + bits = <2 3>; + + }; }; ... }; diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c index 78051f0..a59195c 100644 --- a/drivers/nvmem/core.c +++ b/drivers/nvmem/core.c @@ -783,6 +783,16 @@ struct nvmem_cell *of_nvmem_cell_get(struct device_node *np, if (!nvmem_np) return ERR_PTR(-EINVAL); + /* Devices using the new binding have all the cells in +* a subnode with compatible = "nvmem-cells". In this +* case the device will be the parent of this node. +*/ + if (of_device_is_compatible(nvmem_np, "nvmem-cells")) { + nvmem_np = of_get_next_parent(nvmem_np); + if (!nvmem_np) + return ERR_PTR(-EINVAL); + } + nvmem = __nvmem_device_get(nvmem_np, NULL, NULL); of_node_put(nvmem_np); if (IS_ERR(nvmem)) -- 2.7.4
[PATCH v3 0/3] mtd: Add support for reading MTD devices via the nvmem API
Hi all, this series add support for reading MTD devices via the nvmem API, this is mostly needed on embedded devices where things like MAC address and calibration data is often stored in a partition on the main flash device. Adding support for the nvmem API to the MTD core is trivial, however there is a clash in the OF binding used by both subsystems. The current nvmem binding expect nvmem cell to be subnode of the nvmem device, without any compatible string. But MTD devices used a similar scheme for partition in the past, so a subnode from an MTD device could be a partition using the old binding or an nvmem cell. To avoid this problem we update the nvmem cell binding to use a 'nvmem-cells' subnode with compatible string to hold the list of nvmem cells. This new binding make sure that any kind of device can be used as nvmem provider. Alban Bedel (3): nvmem: Update the OF binding to use a subnode for the cells list doc: bindings: Add bindings documentation for mtd nvmem mtd: Add support for reading MTD devices via the nvmem API .../devicetree/bindings/nvmem/mtd-nvmem.txt| 27 ++ Documentation/devicetree/bindings/nvmem/nvmem.txt | 55 +--- drivers/mtd/Kconfig| 1 + drivers/mtd/mtdcore.c | 59 ++ drivers/nvmem/core.c | 10 include/linux/mtd/mtd.h| 2 + 6 files changed, 137 insertions(+), 17 deletions(-) create mode 100644 Documentation/devicetree/bindings/nvmem/mtd-nvmem.txt -- 2.7.4
[PATCH v3 3/3] mtd: Add support for reading MTD devices via the nvmem API
Allow drivers that use the nvmem API to read data stored on MTD devices. For this the mtd devices are registered as read-only NVMEM providers. On OF systems only devices that have the 'nvmem-provider' property are registered, on non-OF system all MTD devices are registered. Signed-off-by: Alban Bedel --- Changelog: v2: * Moved to the MTD core instead of using notifiers * Fixed the Kconfig description v3: * Rebased on current kernel * Moved the code to mtdcore.c and removed the conditional compilation as suggested by Boris Brezillon * Fixed my name in From and Signed-off-by * Only allow root to read from the nvmem sysfs interface --- drivers/mtd/Kconfig | 1 + drivers/mtd/mtdcore.c | 59 + include/linux/mtd/mtd.h | 2 ++ 3 files changed, 62 insertions(+) diff --git a/drivers/mtd/Kconfig b/drivers/mtd/Kconfig index 2a8ac68..911d869 100644 --- a/drivers/mtd/Kconfig +++ b/drivers/mtd/Kconfig @@ -1,5 +1,6 @@ menuconfig MTD tristate "Memory Technology Device (MTD) support" + imply NVMEM help Memory Technology Devices are flash, RAM and similar chips, often used for solid state file systems on embedded devices. This option diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c index 28553c8..d2a127c 100644 --- a/drivers/mtd/mtdcore.c +++ b/drivers/mtd/mtdcore.c @@ -478,6 +478,48 @@ int mtd_pairing_groups(struct mtd_info *mtd) } EXPORT_SYMBOL_GPL(mtd_pairing_groups); +static int mtd_nvmem_reg_read(void *priv, unsigned int offset, + void *val, size_t bytes) +{ + struct mtd_info *mtd = priv; + size_t retlen; + int err; + + err = mtd_read(mtd, offset, bytes, &retlen, val); + if (err && err != -EUCLEAN) + return err; + + return retlen == bytes ? 0 : -EIO; +} + +static int mtd_nvmem_add(struct mtd_info *mtd) +{ + struct nvmem_config config = {}; + + config.dev = &mtd->dev; + config.owner = THIS_MODULE; + config.reg_read = mtd_nvmem_reg_read; + config.size = mtd->size; + config.word_size = 1; + config.stride = 1; + config.read_only = true; + config.root_only = true; + config.priv = mtd; + + mtd->nvmem = nvmem_register(&config); + if (IS_ERR(mtd->nvmem)) { + /* Just ignore if there is no NVMEM support in the kernel */ + if (PTR_ERR(mtd->nvmem) == -ENOSYS) { + mtd->nvmem = NULL; + } else { + dev_err(&mtd->dev, "Failed to register NVMEM device\n"); + return PTR_ERR(mtd->nvmem); + } + } + + return 0; +} + static struct dentry *dfs_dir_mtd; /** @@ -560,6 +602,11 @@ int add_mtd_device(struct mtd_info *mtd) if (error) goto fail_added; + /* Add the nvmem provider */ + error = mtd_nvmem_add(mtd); + if (error) + goto fail_nvmem_add; + if (!IS_ERR_OR_NULL(dfs_dir_mtd)) { mtd->dbg.dfs_dir = debugfs_create_dir(dev_name(&mtd->dev), dfs_dir_mtd); if (IS_ERR_OR_NULL(mtd->dbg.dfs_dir)) { @@ -585,6 +632,8 @@ int add_mtd_device(struct mtd_info *mtd) __module_get(THIS_MODULE); return 0; +fail_nvmem_add: + device_unregister(&mtd->dev); fail_added: of_node_put(mtd_get_of_node(mtd)); idr_remove(&mtd_idr, i); @@ -627,6 +676,16 @@ int del_mtd_device(struct mtd_info *mtd) mtd->index, mtd->name, mtd->usecount); ret = -EBUSY; } else { + /* Try to remove the NVMEM provider */ + if (mtd->nvmem) { + ret = nvmem_unregister(mtd->nvmem); + if (ret) { + dev_err(&mtd->dev, + "Failed to unregister NVMEM device\n"); + goto out_error; + } + } + device_unregister(&mtd->dev); idr_remove(&mtd_idr, mtd->index); diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h index 205eded..660b8e7 100644 --- a/include/linux/mtd/mtd.h +++ b/include/linux/mtd/mtd.h @@ -25,6 +25,7 @@ #include #include #include +#include #include @@ -352,6 +353,7 @@ struct mtd_info { struct device dev; int usecount; struct mtd_debug_info dbg; + struct nvmem_device *nvmem; }; int mtd_ooblayout_ecc(struct mtd_info *mtd, int section, -- 2.7.4
[PATCH v3 2/3] doc: bindings: Add bindings documentation for mtd nvmem
Config data for drivers, like MAC addresses, is often stored in MTD. Add a binding that define how such data storage can be represented in device tree. Signed-off-by: Alban Bedel --- Changelog: v2: * Added a "Required properties" section with the nvmem-provider property v3: * Fixed my name in From and Signed-off-by * Moved to the new nvmem binding with the nvmem-cells subnode --- .../devicetree/bindings/nvmem/mtd-nvmem.txt| 27 ++ 1 file changed, 27 insertions(+) create mode 100644 Documentation/devicetree/bindings/nvmem/mtd-nvmem.txt diff --git a/Documentation/devicetree/bindings/nvmem/mtd-nvmem.txt b/Documentation/devicetree/bindings/nvmem/mtd-nvmem.txt new file mode 100644 index 000..c819a69 --- /dev/null +++ b/Documentation/devicetree/bindings/nvmem/mtd-nvmem.txt @@ -0,0 +1,27 @@ += NVMEM in MTD = + +Config data for drivers, like MAC addresses, is often stored in MTD. +An MTD device, or one of its partition, can be defined as a NVMEM provider +by having an 'nvmem-cells' subnode as defined in nvmem.txt. + +Example: + + flash@0 { + ... + + partition@2 { + label = "art"; + reg = <0x7F 0x01>; + read-only; + + nvmem-cells { + compatible = "nvmem-cells"; + #address-cells = <1>; + #size-cells = <1>; + + eeprom@1000 { + reg = <0x1000 0x1000>; + }; + }; + }; + }; -- 2.7.4
[PATCH v2] gpio: ath79: Fix potential NULL dereference in ath79_gpio_probe()
From: Wei Yongjun platform_get_resource() may return NULL, add proper check to avoid potential NULL dereferencing. This is detected by Coccinelle semantic patch. @@ expression pdev, res, n, t, e, e1, e2; @@ res = platform_get_resource(pdev, t, n); + if (!res) + return -EINVAL; ... when != res == NULL e = devm_ioremap(e1, res->start, e2); Signed-off-by: Wei Yongjun [al...@free.fr: Fixed patch to apply on current tree] Signed-off-by: Alban Bedel --- drivers/gpio/gpio-ath79.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpio/gpio-ath79.c b/drivers/gpio/gpio-ath79.c index 3ae7c18..684e9d6 100644 --- a/drivers/gpio/gpio-ath79.c +++ b/drivers/gpio/gpio-ath79.c @@ -258,6 +258,8 @@ static int ath79_gpio_probe(struct platform_device *pdev) } res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) + return -EINVAL; ctrl->base = devm_ioremap_nocache( &pdev->dev, res->start, resource_size(res)); if (!ctrl->base) -- 2.7.4
[PATCH 1/8] nvmem: core: Set the provider read-only when no write callback is given
If no write callback is given the device should be marked as read-only. While at it also move from a bit or to a logical or as that is a logical expression. Signed-off-by: Alban Bedel --- drivers/nvmem/core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c index f7301bb4ef3b..cf2e1091fe89 100644 --- a/drivers/nvmem/core.c +++ b/drivers/nvmem/core.c @@ -646,8 +646,8 @@ struct nvmem_device *nvmem_register(const struct nvmem_config *config) config->name ? config->id : nvmem->id); } - nvmem->read_only = device_property_present(config->dev, "read-only") | - config->read_only; + nvmem->read_only = device_property_present(config->dev, "read-only") || + config->read_only || !nvmem->reg_write; if (config->root_only) nvmem->dev.groups = nvmem->read_only ? -- 2.19.1
[PATCH 2/8] nvmem: core: Fix of_nvmem_cell_get() for optional cells
of_nvmem_cell_get() should return -ENOENT when a cell isn't defined, otherwise callers can't distinguish between a missing cell and other errors. Signed-off-by: Alban Bedel --- drivers/nvmem/core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c index cf2e1091fe89..f8c43da6f2ca 100644 --- a/drivers/nvmem/core.c +++ b/drivers/nvmem/core.c @@ -1031,7 +1031,7 @@ struct nvmem_cell *of_nvmem_cell_get(struct device_node *np, const char *id) cell_np = of_parse_phandle(np, "nvmem-cells", index); if (!cell_np) - return ERR_PTR(-EINVAL); + return ERR_PTR(-ENOENT); nvmem_np = of_get_next_parent(cell_np); if (!nvmem_np) -- 2.19.1
[PATCH 0/8] nvmem: Various small fixes and improvements
Hi, this series is mostly small bug fixes, but also add a new API to make things simpler in drivers that need to request an optional cell. Alban Bedel (8): nvmem: core: Set the provider read-only when no write callback is given nvmem: core: Fix of_nvmem_cell_get() for optional cells nvmem: Add nvmem_cell_get_optional and devm_nvmem_cell_get_optional nvmem: core: Fix cell lookup when no cell is found nvmem: core: Properly handle connection ID in of_nvmem_device_get() nvmem: core: Always reference the device returned by nvmem_device_get() nvmem: core: Fix device reference leak nvmem: core: Avoid useless iterations in nvmem_cell_get_from_lookup() drivers/nvmem/core.c | 86 +++--- include/linux/nvmem-consumer.h | 16 +++ 2 files changed, 86 insertions(+), 16 deletions(-) -- 2.19.1
[PATCH 6/8] nvmem: core: Always reference the device returned by nvmem_device_get()
In nvmem_device_get(), when the device lookup fails with DT it currently fallback on nvmem_find() which is wrong for two reasons. First nvmem_find() return NULL when nothing is found instead of an ERR_PTR. But nvmem_find() also just lookup the device, it doesn't reference the module and increment the reference count like it is done in the DT path. To fix this we replace the call to nvmem_find() with a call to __nvmem_device_get() which does all the referencing and return a proper ERR_PTR in case of error. Signed-off-by: Alban Bedel --- drivers/nvmem/core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c index 28e01a9876c6..2fa97b373601 100644 --- a/drivers/nvmem/core.c +++ b/drivers/nvmem/core.c @@ -874,7 +874,7 @@ struct nvmem_device *nvmem_device_get(struct device *dev, const char *dev_name) } - return nvmem_find(dev_name); + return __nvmem_device_get(NULL, dev_name); } EXPORT_SYMBOL_GPL(nvmem_device_get); -- 2.19.1
[PATCH 4/8] nvmem: core: Fix cell lookup when no cell is found
If the cell list is not empty and nvmem_find_cell_by_node/name() is called for a cell that is not present in the list they will return an invalid pointer instead of NULL. This happen because list_for_each_entry() stop once it reach the list head again, but as the list head is not contained in a struct nvmem_cell the iteration variable then contains an invalid value. This is easily solved by using a variable to iterate over the list and one to return the cell found. Signed-off-by: Alban Bedel --- drivers/nvmem/core.c | 16 ++-- 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c index 8e1b52559467..a7556b20cff4 100644 --- a/drivers/nvmem/core.c +++ b/drivers/nvmem/core.c @@ -525,12 +525,14 @@ static int nvmem_add_cells_from_table(struct nvmem_device *nvmem) static struct nvmem_cell * nvmem_find_cell_by_name(struct nvmem_device *nvmem, const char *cell_id) { - struct nvmem_cell *cell = NULL; + struct nvmem_cell *iter, *cell = NULL; mutex_lock(&nvmem_mutex); - list_for_each_entry(cell, &nvmem->cells, node) { - if (strcmp(cell_id, cell->name) == 0) + list_for_each_entry(iter, &nvmem->cells, node) { + if (strcmp(cell_id, iter->name) == 0) { + cell = iter; break; + } } mutex_unlock(&nvmem_mutex); @@ -994,12 +996,14 @@ nvmem_cell_get_from_lookup(struct device *dev, const char *con_id) static struct nvmem_cell * nvmem_find_cell_by_node(struct nvmem_device *nvmem, struct device_node *np) { - struct nvmem_cell *cell = NULL; + struct nvmem_cell *iter, *cell = NULL; mutex_lock(&nvmem_mutex); - list_for_each_entry(cell, &nvmem->cells, node) { - if (np == cell->np) + list_for_each_entry(iter, &nvmem->cells, node) { + if (np == iter->np) { + cell = iter; break; + } } mutex_unlock(&nvmem_mutex); -- 2.19.1
[PATCH 5/8] nvmem: core: Properly handle connection ID in of_nvmem_device_get()
of_nvmem_device_get() would crash if NULL was passed as a connection ID. Rework this to use the usual sementic of assuming the first connection when no connection ID is given. Furthermore of_nvmem_device_get() would return -EINVAL when it failed to resolve the connection, making it impossible to properly implement an optional connection. Return -ENOENT instead to let the caller know that the connection doesn't exists. Signed-off-by: Alban Bedel --- drivers/nvmem/core.c | 7 --- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c index a7556b20cff4..28e01a9876c6 100644 --- a/drivers/nvmem/core.c +++ b/drivers/nvmem/core.c @@ -839,13 +839,14 @@ struct nvmem_device *of_nvmem_device_get(struct device_node *np, const char *id) { struct device_node *nvmem_np; - int index; + int index = 0; - index = of_property_match_string(np, "nvmem-names", id); + if (id) + index = of_property_match_string(np, "nvmem-names", id); nvmem_np = of_parse_phandle(np, "nvmem", index); if (!nvmem_np) - return ERR_PTR(-EINVAL); + return ERR_PTR(-ENOENT); return __nvmem_device_get(nvmem_np, NULL); } -- 2.19.1
[PATCH 3/8] nvmem: Add nvmem_cell_get_optional and devm_nvmem_cell_get_optional
Add helper functions to make the driver code simpler when a cell is optional. Using these functions just return NULL when the cell doesn't exists or if nvmem is disabled. Signed-off-by: Alban Bedel --- drivers/nvmem/core.c | 48 ++ include/linux/nvmem-consumer.h | 16 2 files changed, 64 insertions(+) diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c index f8c43da6f2ca..8e1b52559467 100644 --- a/drivers/nvmem/core.c +++ b/drivers/nvmem/core.c @@ -1083,6 +1083,30 @@ struct nvmem_cell *nvmem_cell_get(struct device *dev, const char *id) } EXPORT_SYMBOL_GPL(nvmem_cell_get); +/** + * nvmem_cell_get_optional() - Get an optional nvmem cell of device from + * a given id. + * + * @dev: Device that requests the nvmem cell. + * @cell_id: nvmem cell name to get. + * + * Return: Will be NULL if no cell with the given name is defined, + * an ERR_PTR() on error or a valid pointer to a struct nvmem_cell. + * The nvmem_cell will be freed by the nvmem_cell_put(). + */ +struct nvmem_cell *nvmem_cell_get_optional(struct device *dev, + const char *cell_id) +{ + struct nvmem_cell *cell; + + cell = nvmem_cell_get(dev, cell_id); + if (IS_ERR(cell) && PTR_ERR(cell) == -ENOENT) + return NULL; + + return cell; +} +EXPORT_SYMBOL_GPL(nvmem_cell_get_optional); + static void devm_nvmem_cell_release(struct device *dev, void *res) { nvmem_cell_put(*(struct nvmem_cell **)res); @@ -1118,6 +1142,30 @@ struct nvmem_cell *devm_nvmem_cell_get(struct device *dev, const char *id) } EXPORT_SYMBOL_GPL(devm_nvmem_cell_get); +/** + * devm_nvmem_cell_get() - Get an optional nvmem cell of device from + * a given id. + * + * @dev: Device that requests the nvmem cell. + * @id: nvmem cell name id to get. + * + * Return: Will be NULL if the cell doesn't exists, an ERR_PTR() on + * error or a valid pointer to a struct nvmem_cell. The nvmem_cell + * will be freed by the automatically once the device is freed. + */ +struct nvmem_cell *devm_nvmem_cell_get_optional(struct device *dev, + const char *cell_id) +{ + struct nvmem_cell *cell; + + cell = devm_nvmem_cell_get(dev, cell_id); + if (IS_ERR(cell) && PTR_ERR(cell) == -ENOENT) + return NULL; + + return cell; +} +EXPORT_SYMBOL_GPL(devm_nvmem_cell_get_optional); + static int devm_nvmem_cell_match(struct device *dev, void *res, void *data) { struct nvmem_cell **c = res; diff --git a/include/linux/nvmem-consumer.h b/include/linux/nvmem-consumer.h index 312bfa5efd80..8d7bf21a9adc 100644 --- a/include/linux/nvmem-consumer.h +++ b/include/linux/nvmem-consumer.h @@ -56,7 +56,11 @@ enum { /* Cell based interface */ struct nvmem_cell *nvmem_cell_get(struct device *dev, const char *id); +struct nvmem_cell *nvmem_cell_get_optional(struct device *dev, + const char *id); struct nvmem_cell *devm_nvmem_cell_get(struct device *dev, const char *id); +struct nvmem_cell *devm_nvmem_cell_get_optional(struct device *dev, + const char *id); void nvmem_cell_put(struct nvmem_cell *cell); void devm_nvmem_cell_put(struct device *dev, struct nvmem_cell *cell); void *nvmem_cell_read(struct nvmem_cell *cell, size_t *len); @@ -96,12 +100,24 @@ static inline struct nvmem_cell *nvmem_cell_get(struct device *dev, return ERR_PTR(-EOPNOTSUPP); } +static inline struct nvmem_cell *nvmem_cell_get_optional(struct device *dev, +const char *id) +{ + return NULL; +} + static inline struct nvmem_cell *devm_nvmem_cell_get(struct device *dev, const char *id) { return ERR_PTR(-EOPNOTSUPP); } +static inline struct nvmem_cell * +devm_nvmem_cell_get_optional(struct device *dev, const char *id) +{ + return NULL; +} + static inline void devm_nvmem_cell_put(struct device *dev, struct nvmem_cell *cell) { -- 2.19.1
[PATCH 7/8] nvmem: core: Fix device reference leak
__nvmem_device_get() make use of bus_find_device() to get the relevant device and this function increase the reference count of the device found, however this is not accounted for anywhere. Fix __nvmem_device_get() and __nvmem_device_put() to properly release this reference count. Signed-off-by: Alban Bedel --- drivers/nvmem/core.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c index 2fa97b373601..176fe72f4eb5 100644 --- a/drivers/nvmem/core.c +++ b/drivers/nvmem/core.c @@ -811,6 +811,7 @@ static struct nvmem_device *__nvmem_device_get(struct device_node *np, "could not increase module refcount for cell %s\n", nvmem_dev_name(nvmem)); + put_device(&nvmem->dev); return ERR_PTR(-EINVAL); } @@ -821,6 +822,7 @@ static struct nvmem_device *__nvmem_device_get(struct device_node *np, static void __nvmem_device_put(struct nvmem_device *nvmem) { + put_device(&nvmem->dev); module_put(nvmem->owner); kref_put(&nvmem->refcnt, nvmem_device_release); } -- 2.19.1
[PATCH 8/8] nvmem: core: Avoid useless iterations in nvmem_cell_get_from_lookup()
Once the correct cell has been found there is no need to continue iterating, just stop there. While at it replace the goto used to leave the loop with simple break statements. Signed-off-by: Alban Bedel --- drivers/nvmem/core.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c index 176fe72f4eb5..9334f074defb 100644 --- a/drivers/nvmem/core.c +++ b/drivers/nvmem/core.c @@ -977,7 +977,7 @@ nvmem_cell_get_from_lookup(struct device *dev, const char *con_id) if (IS_ERR(nvmem)) { /* Provider may not be registered yet. */ cell = ERR_CAST(nvmem); - goto out; + break; } cell = nvmem_find_cell_by_name(nvmem, @@ -985,12 +985,11 @@ nvmem_cell_get_from_lookup(struct device *dev, const char *con_id) if (!cell) { __nvmem_device_put(nvmem); cell = ERR_PTR(-ENOENT); - goto out; } + break; } } -out: mutex_unlock(&nvmem_lookup_mutex); return cell; } -- 2.19.1
[PATCH 1/2] phy: ath79-usb: Fix the power on error path
In the power on function the error path doesn't return the suspend override to its proper state. It should should deassert this reset line to enable the suspend override. Signed-off-by: Alban Bedel --- drivers/phy/qualcomm/phy-ath79-usb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/phy/qualcomm/phy-ath79-usb.c b/drivers/phy/qualcomm/phy-ath79-usb.c index 6fd6e07ab345..f7d64f3910b4 100644 --- a/drivers/phy/qualcomm/phy-ath79-usb.c +++ b/drivers/phy/qualcomm/phy-ath79-usb.c @@ -31,7 +31,7 @@ static int ath79_usb_phy_power_on(struct phy *phy) err = reset_control_deassert(priv->reset); if (err && priv->no_suspend_override) - reset_control_assert(priv->no_suspend_override); + reset_control_deassert(priv->no_suspend_override); return err; } -- 2.19.1
[PATCH 1/2] phy: ath79-usb: Fix the power on error path
In the power on function the error path doesn't return the suspend override to its proper state. It should should deassert this reset line to enable the suspend override. Signed-off-by: Alban Bedel --- drivers/phy/qualcomm/phy-ath79-usb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/phy/qualcomm/phy-ath79-usb.c b/drivers/phy/qualcomm/phy-ath79-usb.c index 6fd6e07ab345..f7d64f3910b4 100644 --- a/drivers/phy/qualcomm/phy-ath79-usb.c +++ b/drivers/phy/qualcomm/phy-ath79-usb.c @@ -31,7 +31,7 @@ static int ath79_usb_phy_power_on(struct phy *phy) err = reset_control_deassert(priv->reset); if (err && priv->no_suspend_override) - reset_control_assert(priv->no_suspend_override); + reset_control_deassert(priv->no_suspend_override); return err; } -- 2.19.1
[PATCH] MIPS: ath79: Enable OF serial ports in the default config
CONFIG_SERIAL_OF_PLATFORM is needed to get a working console on the OF boards, enable it in the default config to get a working setup out of the box. Signed-off-by: Alban Bedel --- arch/mips/configs/ath79_defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/mips/configs/ath79_defconfig b/arch/mips/configs/ath79_defconfig index 4e4ec779f182..6f981af67826 100644 --- a/arch/mips/configs/ath79_defconfig +++ b/arch/mips/configs/ath79_defconfig @@ -66,6 +66,7 @@ CONFIG_SERIAL_8250_CONSOLE=y # CONFIG_SERIAL_8250_PCI is not set CONFIG_SERIAL_8250_NR_UARTS=1 CONFIG_SERIAL_8250_RUNTIME_UARTS=1 +CONFIG_SERIAL_OF_PLATFORM=y CONFIG_SERIAL_AR933X=y CONFIG_SERIAL_AR933X_CONSOLE=y # CONFIG_HW_RANDOM is not set -- 2.19.1
[PATCH 2/2] phy: ath79-usb: Fix the main reset name to match the DT binding
I submitted this driver several times before it got accepted. The first series hasn't been accepted but the DTS binding did made it. I then made a second series that added generic reset support to the PHY core, this in turn required a change to the DT binding. This second series seemed to have been ignored, so I did a third one without the change to the PHY core and the DT binding update, and this last attempt finally made it. But two months later the DT binding update from the second series has been integrated too. So now the driver doesn't match the binding and the only DTS using it. This patch fix the driver to match the new binding. Signed-off-by: Alban Bedel --- drivers/phy/qualcomm/phy-ath79-usb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/phy/qualcomm/phy-ath79-usb.c b/drivers/phy/qualcomm/phy-ath79-usb.c index f7d64f3910b4..09a77e556ece 100644 --- a/drivers/phy/qualcomm/phy-ath79-usb.c +++ b/drivers/phy/qualcomm/phy-ath79-usb.c @@ -69,7 +69,7 @@ static int ath79_usb_phy_probe(struct platform_device *pdev) if (!priv) return -ENOMEM; - priv->reset = devm_reset_control_get(&pdev->dev, "usb-phy"); + priv->reset = devm_reset_control_get(&pdev->dev, "phy"); if (IS_ERR(priv->reset)) return PTR_ERR(priv->reset); -- 2.19.1
[PATCH v3 01/12] devicetree: Add bindings for the SoC of the ATH79 family
Signed-off-by: Alban Bedel --- .../devicetree/bindings/mips/ath79-soc.txt | 21 + 1 file changed, 21 insertions(+) create mode 100644 Documentation/devicetree/bindings/mips/ath79-soc.txt diff --git a/Documentation/devicetree/bindings/mips/ath79-soc.txt b/Documentation/devicetree/bindings/mips/ath79-soc.txt new file mode 100644 index 000..88a12a4 --- /dev/null +++ b/Documentation/devicetree/bindings/mips/ath79-soc.txt @@ -0,0 +1,21 @@ +Binding for Qualcomm Atheros AR7xxx/AR9XXX SoC + +Each device tree must specify a compatible value for the AR SoC +it uses in the compatible property of the root node. The compatible +value must be one of the following values: + +- qca,ar7130 +- qca,ar7141 +- qca,ar7161 +- qca,ar7240 +- qca,ar7241 +- qca,ar7242 +- qca,ar9130 +- qca,ar9132 +- qca,ar9330 +- qca,ar9331 +- qca,ar9341 +- qca,ar9342 +- qca,ar9344 +- qca,qca9556 +- qca,qca9558 -- 2.0.0 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v3 00/12] MIPS: ath79: Add OF support and DTS for TL-WR1043ND
This series add OF bindings and code support for the interrupt controllers, clocks and GPIOs. However it was only tested on a TL-WR1043ND with an AR9132, others SoCs are untested, and a few are not supported at all. Most code changes base on the previous bug fix series: [PATCH v2 0/5] MIPS: ath79: Various small fix to prepare OF support The requested patch to move the GPIO driver to drivers/gpio is ready and will follow once it is clearer if this serie get merged. ChangeLog: v2: * Fixed the OF bindings and DTS to use ePAPR standardized names * Fixed the typos in the OF bindings * Added an ngpios property to the GPIO binding and driver * Removed all the soc_is_xxx() calls out of the GPIO driver probe() * Updated the DTS patches to the new directory structure and merged both in one. Having 3 patches to add Makefile, SoC dtsi and board DTS seemed a bit overkill. * Moved the patch to use the common clk API to the bug fix serie to keep this one cleaner. v3: * Moved the builtin DTB menu to the patch adding the TL-WR1043ND DTS * Made the builtin DTB menu optional * Fixed more typos * Really fixed the DDR controller binding example to use ePAPR names * Fixed the qca9550 compatible string in the PLL bindings and driver * Fixed the example in the GPIO controller binding * Moved the new vendor entry to the correct place Alban Bedel (12): devicetree: Add bindings for the SoC of the ATH79 family MIPS: ath79: Add basic device tree support devicetree: Add bindings for the ATH79 DDR controllers devicetree: Add bindings for the ATH79 interrupt controllers devicetree: Add bindings for the ATH79 MISC interrupt controllers MIPS: ath79: Add OF support to the IRQ controllers devicetree: Add bindings for the ATH79 PLL controllers MIPS: ath79: Add OF support to the clocks devicetree: Add bindings for the ATH79 GPIO controllers MIPS: ath79: Add OF support to the GPIO driver of: Add vendor prefix for TP-Link Technologies Co. Ltd MIPS: Add basic support for the TL-WR1043ND version 1 .../devicetree/bindings/clock/qca,ath79-pll.txt| 33 ++ .../devicetree/bindings/gpio/gpio-ath79.txt| 38 +++ .../interrupt-controller/qca,ath79-cpu-intc.txt| 44 .../interrupt-controller/qca,ath79-misc-intc.txt | 30 + .../memory-controllers/ath79-ddr-controller.txt| 35 ++ .../devicetree/bindings/mips/ath79-soc.txt | 21 .../devicetree/bindings/vendor-prefixes.txt| 1 + arch/mips/Kconfig | 1 + arch/mips/ath79/Kconfig| 12 ++ arch/mips/ath79/clock.c| 63 +++ arch/mips/ath79/dev-common.c | 51 + arch/mips/ath79/gpio.c | 79 ++ arch/mips/ath79/irq.c | 87 ++- arch/mips/ath79/machtypes.h| 1 + arch/mips/ath79/setup.c| 27 - arch/mips/boot/dts/Makefile| 1 + arch/mips/boot/dts/qca/Makefile| 9 ++ arch/mips/boot/dts/qca/ar9132.dtsi | 121 + arch/mips/boot/dts/qca/ar9132_tl_wr1043nd_v1.dts | 83 ++ include/linux/platform_data/gpio-ath79.h | 19 20 files changed, 713 insertions(+), 43 deletions(-) create mode 100644 Documentation/devicetree/bindings/clock/qca,ath79-pll.txt create mode 100644 Documentation/devicetree/bindings/gpio/gpio-ath79.txt create mode 100644 Documentation/devicetree/bindings/interrupt-controller/qca,ath79-cpu-intc.txt create mode 100644 Documentation/devicetree/bindings/interrupt-controller/qca,ath79-misc-intc.txt create mode 100644 Documentation/devicetree/bindings/memory-controllers/ath79-ddr-controller.txt create mode 100644 Documentation/devicetree/bindings/mips/ath79-soc.txt create mode 100644 arch/mips/boot/dts/qca/Makefile create mode 100644 arch/mips/boot/dts/qca/ar9132.dtsi create mode 100644 arch/mips/boot/dts/qca/ar9132_tl_wr1043nd_v1.dts create mode 100644 include/linux/platform_data/gpio-ath79.h -- 2.0.0 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v3 02/12] MIPS: ath79: Add basic device tree support
Add the bare minimum to load a device tree. Signed-off-by: Alban Bedel --- v3: * Removed the empty Builtin devicetree menu --- arch/mips/Kconfig | 1 + arch/mips/ath79/machtypes.h | 1 + arch/mips/ath79/setup.c | 27 ++- 3 files changed, 28 insertions(+), 1 deletion(-) diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 874bbaf..772312d 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -133,6 +133,7 @@ config ATH79 select SYS_SUPPORTS_BIG_ENDIAN select SYS_SUPPORTS_MIPS16 select SYS_SUPPORTS_ZBOOT + select USE_OF help Support for the Atheros AR71XX/AR724X/AR913X SoCs. diff --git a/arch/mips/ath79/machtypes.h b/arch/mips/ath79/machtypes.h index 2625405..a13db3d 100644 --- a/arch/mips/ath79/machtypes.h +++ b/arch/mips/ath79/machtypes.h @@ -15,6 +15,7 @@ #include enum ath79_mach_type { + ATH79_MACH_GENERIC_OF = -1, /* Device tree board */ ATH79_MACH_GENERIC = 0, ATH79_MACH_AP121, /* Atheros AP121 reference board */ ATH79_MACH_AP136_010, /* Atheros AP136-010 reference board */ diff --git a/arch/mips/ath79/setup.c b/arch/mips/ath79/setup.c index 74f1af7..01a644f 100644 --- a/arch/mips/ath79/setup.c +++ b/arch/mips/ath79/setup.c @@ -17,12 +17,16 @@ #include #include #include +#include +#include #include #include #include /* for mips_hpt_frequency */ #include /* for _machine_{restart,halt} */ #include +#include +#include #include #include @@ -194,8 +198,19 @@ unsigned int get_c0_compare_int(void) void __init plat_mem_setup(void) { + unsigned long fdt_start; + set_io_port_base(KSEG1); + /* Get the position of the FDT passed by the bootloader */ + fdt_start = fw_getenvl("fdt_start"); + if (fdt_start) + __dt_setup_arch((void *)KSEG0ADDR(fdt_start)); +#ifdef CONFIG_BUILTIN_DTB + else + __dt_setup_arch(__dtb_start); +#endif + ath79_reset_base = ioremap_nocache(AR71XX_RESET_BASE, AR71XX_RESET_SIZE); ath79_pll_base = ioremap_nocache(AR71XX_PLL_BASE, @@ -203,7 +218,8 @@ void __init plat_mem_setup(void) ath79_ddr_ctrl_init(); ath79_detect_sys_type(); - detect_memory_region(0, ATH79_MEM_SIZE_MIN, ATH79_MEM_SIZE_MAX); + if (mips_machtype != ATH79_MACH_GENERIC_OF) + detect_memory_region(0, ATH79_MEM_SIZE_MIN, ATH79_MEM_SIZE_MAX); _machine_restart = ath79_restart; _machine_halt = ath79_halt; @@ -235,6 +251,10 @@ void __init plat_time_init(void) static int __init ath79_setup(void) { + of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); + if (mips_machtype == ATH79_MACH_GENERIC_OF) + return 0; + ath79_gpio_init(); ath79_register_uart(); ath79_register_wdt(); @@ -246,6 +266,11 @@ static int __init ath79_setup(void) arch_initcall(ath79_setup); +void __init device_tree_init(void) +{ + unflatten_and_copy_device_tree(); +} + static void __init ath79_generic_init(void) { /* Nothing to do */ -- 2.0.0 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v3 04/12] devicetree: Add bindings for the ATH79 interrupt controllers
Signed-off-by: Alban Bedel --- v2: * Fixed the node names to respect ePAPR * Removed the unneeded @0 on the node name --- .../interrupt-controller/qca,ath79-cpu-intc.txt| 44 ++ 1 file changed, 44 insertions(+) create mode 100644 Documentation/devicetree/bindings/interrupt-controller/qca,ath79-cpu-intc.txt diff --git a/Documentation/devicetree/bindings/interrupt-controller/qca,ath79-cpu-intc.txt b/Documentation/devicetree/bindings/interrupt-controller/qca,ath79-cpu-intc.txt new file mode 100644 index 000..aabce78 --- /dev/null +++ b/Documentation/devicetree/bindings/interrupt-controller/qca,ath79-cpu-intc.txt @@ -0,0 +1,44 @@ +Binding for Qualcomm Atheros AR7xxx/AR9XXX CPU interrupt controller + +On most SoC the IRQ controller need to flush the DDR FIFO before running +the interrupt handler of some devices. This is configured using the +qca,ddr-wb-channels and qca,ddr-wb-channel-interrupts properties. + +Required Properties: + +- compatible: has to be "qca,-cpu-intc", "qca,ar7100-cpu-intc" + as fallback +- interrupt-controller : Identifies the node as an interrupt controller +- #interrupt-cells : Specifies the number of cells needed to encode interrupt +source, should be 1 for intc + +Please refer to interrupts.txt in this directory for details of the common +Interrupt Controllers bindings used by client devices. + +Optional Properties: + +- qca,ddr-wb-channel-interrupts: List of the interrupts needing a write + buffer flush +- qca,ddr-wb-channels: List of phandles to the write buffer channels for + each interrupt. If qca,ddr-wb-channel-interrupts is not present the interrupt + default to the entry's index. + +Example: + + interrupt-controller { + compatible = "qca,ar9132-cpu-intc", "qca,ar7100-cpu-intc"; + + interrupt-controller; + #interrupt-cells = <1>; + + qca,ddr-wb-channel-interrupts = <2>, <3>, <4>, <5>; + qca,ddr-wb-channels = <&ddr_ctrl 3>, <&ddr_ctrl 2>, + <&ddr_ctrl 0>, <&ddr_ctrl 1>; + }; + + ... + + ddr_ctrl: memory-controller@1800 { + ... + #qca,ddr-wb-channel-cells = <1>; + }; -- 2.0.0 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v3 03/12] devicetree: Add bindings for the ATH79 DDR controllers
The DDR controller of the ARxxx and AR9xxx families provides an interface to flush the FIFO between various devices and the DDR. This is mainly used by the IRQ controller to flush the FIFO before running the interrupt handler of such devices. Signed-off-by: Alban Bedel --- v2: * Fix the node names to respect ePAPR v3: * Fix some typos * Really fix the node names this time --- .../memory-controllers/ath79-ddr-controller.txt| 35 ++ 1 file changed, 35 insertions(+) create mode 100644 Documentation/devicetree/bindings/memory-controllers/ath79-ddr-controller.txt diff --git a/Documentation/devicetree/bindings/memory-controllers/ath79-ddr-controller.txt b/Documentation/devicetree/bindings/memory-controllers/ath79-ddr-controller.txt new file mode 100644 index 000..efe35a06 --- /dev/null +++ b/Documentation/devicetree/bindings/memory-controllers/ath79-ddr-controller.txt @@ -0,0 +1,35 @@ +Binding for Qualcomm Atheros AR7xxx/AR9xxx DDR controller + +The DDR controller of the ARxxx and AR9xxx families provides an interface +to flush the FIFO between various devices and the DDR. This is mainly used +by the IRQ controller to flush the FIFO before running the interrupt handler +of such devices. + +Required properties: + +- compatible: has to be "qca,-ddr-controller", + "qca,[ar7100|ar7240]-ddr-controller" as fallback. + On SoC with PCI support "qca,ar7100-ddr-controller" should be used as + fallback, otherwise "qca,ar7240-ddr-controller" should be used. +- reg: Base address and size of the controllers memory area +- #qca,ddr-wb-channel-cells: has to be 1, the index of the write buffer + channel + +Example: + + ddr_ctrl: memory-controller@1800 { + compatible = "qca,ar9132-ddr-controller", + "qca,ar7240-ddr-controller"; + reg = <0x1800 0x100>; + + #qca,ddr-wb-channel-cells = <1>; + }; + + ... + + interrupt-controller { + ... + qca,ddr-wb-channel-interrupts = <2>, <3>, <4>, <5>; + qca,ddr-wb-channels = <&ddr_ctrl 3>, <&ddr_ctrl 2>, + <&ddr_ctrl 0>, <&ddr_ctrl 1>; + }; -- 2.0.0 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v3 05/12] devicetree: Add bindings for the ATH79 MISC interrupt controllers
Signed-off-by: Alban Bedel --- v2: * Fixed the node names to respect ePAPR --- .../interrupt-controller/qca,ath79-misc-intc.txt | 30 ++ 1 file changed, 30 insertions(+) create mode 100644 Documentation/devicetree/bindings/interrupt-controller/qca,ath79-misc-intc.txt diff --git a/Documentation/devicetree/bindings/interrupt-controller/qca,ath79-misc-intc.txt b/Documentation/devicetree/bindings/interrupt-controller/qca,ath79-misc-intc.txt new file mode 100644 index 000..391717a --- /dev/null +++ b/Documentation/devicetree/bindings/interrupt-controller/qca,ath79-misc-intc.txt @@ -0,0 +1,30 @@ +Binding for Qualcomm Atheros AR7xxx/AR9XXX MISC interrupt controller + +The MISC interrupt controller is a secondary controller for lower priority +interrupt. + +Required Properties: +- compatible: has to be "qca,-cpu-intc", "qca,ar7100-misc-intc" + as fallback +- reg: Base address and size of the controllers memory area +- interrupt-parent: phandle of the parent interrupt controller. +- interrupts: Interrupt specifier for the controllers interrupt. +- interrupt-controller : Identifies the node as an interrupt controller +- #interrupt-cells : Specifies the number of cells needed to encode interrupt +source, should be 1 + +Please refer to interrupts.txt in this directory for details of the common +Interrupt Controllers bindings used by client devices. + +Example: + + interrupt-controller@18060010 { + compatible = "qca,ar9132-misc-intc", qca,ar7100-misc-intc"; + reg = <0x18060010 0x4>; + + interrupt-parent = <&cpuintc>; + interrupts = <6>; + + interrupt-controller; + #interrupt-cells = <1>; + }; -- 2.0.0 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v3 07/12] devicetree: Add bindings for the ATH79 PLL controllers
Signed-off-by: Alban Bedel --- v2: * Fixed the node names to respect ePAPR * Fixed the missing 's' in 'fallbacks' and the 'clocks' property v3: * Fix the compatible string for qca9550 --- .../devicetree/bindings/clock/qca,ath79-pll.txt| 33 ++ 1 file changed, 33 insertions(+) create mode 100644 Documentation/devicetree/bindings/clock/qca,ath79-pll.txt diff --git a/Documentation/devicetree/bindings/clock/qca,ath79-pll.txt b/Documentation/devicetree/bindings/clock/qca,ath79-pll.txt new file mode 100644 index 000..e0fc2c1 --- /dev/null +++ b/Documentation/devicetree/bindings/clock/qca,ath79-pll.txt @@ -0,0 +1,33 @@ +Binding for Qualcomm Atheros AR7xxx/AR9XXX PLL controller + +The PPL controller provides the 3 main clocks of the SoC: CPU, DDR and AHB. + +Required Properties: +- compatible: has to be "qca,-cpu-intc" and one of the following + fallbacks: + - "qca,ar7100-pll" + - "qca,ar7240-pll" + - "qca,ar9130-pll" + - "qca,ar9330-pll" + - "qca,ar9340-pll" + - "qca,qca9550-pll" +- reg: Base address and size of the controllers memory area +- clock-names: Name of the input clock, has to be "ref" +- clocks: phandle of the external reference clock +- #clock-cells: has to be one + +Optional properties: +- clock-output-names: should be "cpu", "ddr", "ahb" + +Example: + + memory-controller@1805 { + compatible = "qca,ar9132-ppl", "qca,ar9130-pll"; + reg = <0x1805 0x20>; + + clock-names = "ref"; + clocks = <&extosc>; + + #clock-cells = <1>; + clock-output-names = "cpu", "ddr", "ahb"; + }; -- 2.0.0 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v3 08/12] MIPS: ath79: Add OF support to the clocks
Allow using the SoC clocks in the device tree. --- v3: * Fix the compatible string for qca9550 --- arch/mips/ath79/clock.c | 63 ++--- 1 file changed, 44 insertions(+), 19 deletions(-) diff --git a/arch/mips/ath79/clock.c b/arch/mips/ath79/clock.c index 1fcb691..eb5117c 100644 --- a/arch/mips/ath79/clock.c +++ b/arch/mips/ath79/clock.c @@ -29,7 +29,14 @@ #define AR724X_BASE_FREQ 500 #define AR913X_BASE_FREQ 500 -static void __init ath79_add_sys_clkdev(const char *id, unsigned long rate) +static struct clk *clks[3]; +static struct clk_onecell_data clk_data = { + .clks = clks, + .clk_num = ARRAY_SIZE(clks), +}; + +static struct clk *__init ath79_add_sys_clkdev( + const char *id, unsigned long rate) { struct clk *clk; int err; @@ -41,6 +48,8 @@ static void __init ath79_add_sys_clkdev(const char *id, unsigned long rate) err = clk_register_clkdev(clk, id, NULL); if (err) panic("unable to register %s clock device", id); + + return clk; } static void __init ar71xx_clocks_init(void) @@ -70,9 +79,9 @@ static void __init ar71xx_clocks_init(void) ahb_rate = cpu_rate / div; ath79_add_sys_clkdev("ref", ref_rate); - ath79_add_sys_clkdev("cpu", cpu_rate); - ath79_add_sys_clkdev("ddr", ddr_rate); - ath79_add_sys_clkdev("ahb", ahb_rate); + clks[0] = ath79_add_sys_clkdev("cpu", cpu_rate); + clks[1] = ath79_add_sys_clkdev("ddr", ddr_rate); + clks[2] = ath79_add_sys_clkdev("ahb", ahb_rate); clk_add_alias("wdt", NULL, "ahb", NULL); clk_add_alias("uart", NULL, "ahb", NULL); @@ -106,9 +115,9 @@ static void __init ar724x_clocks_init(void) ahb_rate = cpu_rate / div; ath79_add_sys_clkdev("ref", ref_rate); - ath79_add_sys_clkdev("cpu", cpu_rate); - ath79_add_sys_clkdev("ddr", ddr_rate); - ath79_add_sys_clkdev("ahb", ahb_rate); + clks[0] = ath79_add_sys_clkdev("cpu", cpu_rate); + clks[1] = ath79_add_sys_clkdev("ddr", ddr_rate); + clks[2] = ath79_add_sys_clkdev("ahb", ahb_rate); clk_add_alias("wdt", NULL, "ahb", NULL); clk_add_alias("uart", NULL, "ahb", NULL); @@ -139,9 +148,9 @@ static void __init ar913x_clocks_init(void) ahb_rate = cpu_rate / div; ath79_add_sys_clkdev("ref", ref_rate); - ath79_add_sys_clkdev("cpu", cpu_rate); - ath79_add_sys_clkdev("ddr", ddr_rate); - ath79_add_sys_clkdev("ahb", ahb_rate); + clks[0] = ath79_add_sys_clkdev("cpu", cpu_rate); + clks[1] = ath79_add_sys_clkdev("ddr", ddr_rate); + clks[2] = ath79_add_sys_clkdev("ahb", ahb_rate); clk_add_alias("wdt", NULL, "ahb", NULL); clk_add_alias("uart", NULL, "ahb", NULL); @@ -201,9 +210,9 @@ static void __init ar933x_clocks_init(void) } ath79_add_sys_clkdev("ref", ref_rate); - ath79_add_sys_clkdev("cpu", cpu_rate); - ath79_add_sys_clkdev("ddr", ddr_rate); - ath79_add_sys_clkdev("ahb", ahb_rate); + clks[0] = ath79_add_sys_clkdev("cpu", cpu_rate); + clks[1] = ath79_add_sys_clkdev("ddr", ddr_rate); + clks[2] = ath79_add_sys_clkdev("ahb", ahb_rate); clk_add_alias("wdt", NULL, "ahb", NULL); clk_add_alias("uart", NULL, "ref", NULL); @@ -335,9 +344,9 @@ static void __init ar934x_clocks_init(void) ahb_rate = cpu_pll / (postdiv + 1); ath79_add_sys_clkdev("ref", ref_rate); - ath79_add_sys_clkdev("cpu", cpu_rate); - ath79_add_sys_clkdev("ddr", ddr_rate); - ath79_add_sys_clkdev("ahb", ahb_rate); + clks[0] = ath79_add_sys_clkdev("cpu", cpu_rate); + clks[1] = ath79_add_sys_clkdev("ddr", ddr_rate); + clks[2] = ath79_add_sys_clkdev("ahb", ahb_rate); clk_add_alias("wdt", NULL, "ref", NULL); clk_add_alias("uart", NULL, "ref", NULL); @@ -422,9 +431,9 @@ static void __init qca955x_clocks_init(void) ahb_rate = cpu_pll / (postdiv + 1); ath79_add_sys_clkdev("ref", ref_rate); - ath79_add_sys_clkdev("cpu", cpu_rate); - ath79_add_sys_clkdev("ddr", ddr_rate); - ath79_add_sys_clkdev("ahb", ahb_rate); + clks[0] = ath79_add_sys_clkdev("cpu", cpu_rate); + clks[1] = ath79_add_sys_clkdev("ddr", ddr_rate); + clks[2] = ath79_add_sys_clkdev("ahb", ahb_rate); clk_add_alias("wdt", NULL, "ref", NULL); clk_add_alias("uart", NULL, "ref", NULL); @@ -446,6 +455,8 @@ void __init ath79_clocks_init(void) qca955x_clocks_init(); else BUG(); + + of_clk_init(NULL); } unsigned long __init @@ -463,3 +474,17 @@ ath79_get_sys_clk_rate(const char *id) return rate; } + +#ifdef CONFIG_OF +static void __init ath79_clocks_init_dt(struct device_node *np) +{ + of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data); +} + +CLK_OF_DECLARE(ar7100, "qca,ar7100-pll", ath79_clock
[PATCH v3 10/12] MIPS: ath79: Add OF support to the GPIO driver
Replace the simple GPIO chip registration by a platform driver and make ath79_gpio_init() just register the device. Signed-off-by: Alban Bedel --- v2: * Added an 'ngpios' property instead of the many matches * Use a platform data struct to store the device config on non-DT boards. It make for a cleaner separation of the config and driver code. --- arch/mips/ath79/dev-common.c | 51 + arch/mips/ath79/gpio.c | 79 +++- include/linux/platform_data/gpio-ath79.h | 19 3 files changed, 127 insertions(+), 22 deletions(-) create mode 100644 include/linux/platform_data/gpio-ath79.h diff --git a/arch/mips/ath79/dev-common.c b/arch/mips/ath79/dev-common.c index 516225d..9d0172a 100644 --- a/arch/mips/ath79/dev-common.c +++ b/arch/mips/ath79/dev-common.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -106,3 +107,53 @@ void __init ath79_register_wdt(void) platform_device_register_simple("ath79-wdt", -1, &res, 1); } + +static struct ath79_gpio_platform_data ath79_gpio_pdata; + +static struct resource ath79_gpio_resources[] = { + { + .flags = IORESOURCE_MEM, + .start = AR71XX_GPIO_BASE, + .end = AR71XX_GPIO_BASE + AR71XX_GPIO_SIZE - 1, + }, + { + .start = ATH79_MISC_IRQ(2), + .end= ATH79_MISC_IRQ(2), + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device ath79_gpio_device = { + .name = "ath79-gpio", + .id = -1, + .resource = ath79_gpio_resources, + .num_resources = ARRAY_SIZE(ath79_gpio_resources), + .dev = { + .platform_data = &ath79_gpio_pdata + }, +}; + +void __init ath79_gpio_init(void) +{ + if (soc_is_ar71xx()) { + ath79_gpio_pdata.ngpios = AR71XX_GPIO_COUNT; + } else if (soc_is_ar7240()) { + ath79_gpio_pdata.ngpios = AR7240_GPIO_COUNT; + } else if (soc_is_ar7241() || soc_is_ar7242()) { + ath79_gpio_pdata.ngpios = AR7241_GPIO_COUNT; + } else if (soc_is_ar913x()) { + ath79_gpio_pdata.ngpios = AR913X_GPIO_COUNT; + } else if (soc_is_ar933x()) { + ath79_gpio_pdata.ngpios = AR933X_GPIO_COUNT; + } else if (soc_is_ar934x()) { + ath79_gpio_pdata.ngpios = AR934X_GPIO_COUNT; + ath79_gpio_pdata.oe_inverted = 1; + } else if (soc_is_qca955x()) { + ath79_gpio_pdata.ngpios = QCA955X_GPIO_COUNT; + ath79_gpio_pdata.oe_inverted = 1; + } else { + BUG(); + } + + platform_device_register(&ath79_gpio_device); +} diff --git a/arch/mips/ath79/gpio.c b/arch/mips/ath79/gpio.c index 8d025b0..f59ccb2 100644 --- a/arch/mips/ath79/gpio.c +++ b/arch/mips/ath79/gpio.c @@ -20,13 +20,15 @@ #include #include #include +#include +#include #include #include #include "common.h" static void __iomem *ath79_gpio_base; -static unsigned long ath79_gpio_count; +static u32 ath79_gpio_count; static DEFINE_SPINLOCK(ath79_gpio_lock); static void __ath79_gpio_set_value(unsigned gpio, int value) @@ -178,39 +180,72 @@ void ath79_gpio_function_disable(u32 mask) ath79_gpio_function_setup(0, mask); } -void __init ath79_gpio_init(void) +static const struct of_device_id ath79_gpio_of_match[] = { + { .compatible = "qca,ar7100-gpio" }, + { .compatible = "qca,ar9340-gpio" }, + {}, +}; + +static int ath79_gpio_probe(struct platform_device *pdev) { + struct ath79_gpio_platform_data *pdata = pdev->dev.platform_data; + struct device_node *np = pdev->dev.of_node; + struct resource *res; + bool oe_inverted; int err; - if (soc_is_ar71xx()) - ath79_gpio_count = AR71XX_GPIO_COUNT; - else if (soc_is_ar7240()) - ath79_gpio_count = AR7240_GPIO_COUNT; - else if (soc_is_ar7241() || soc_is_ar7242()) - ath79_gpio_count = AR7241_GPIO_COUNT; - else if (soc_is_ar913x()) - ath79_gpio_count = AR913X_GPIO_COUNT; - else if (soc_is_ar933x()) - ath79_gpio_count = AR933X_GPIO_COUNT; - else if (soc_is_ar934x()) - ath79_gpio_count = AR934X_GPIO_COUNT; - else if (soc_is_qca955x()) - ath79_gpio_count = QCA955X_GPIO_COUNT; - else - BUG(); + if (np) { + err = of_property_read_u32(np, "ngpios", &ath79_gpio_count); + if (err) { + dev_err(&pdev->dev, "ngpios property is not valid\n"); + return err; + } + if (ath79_gpio_count >= 32) { + dev_err(&pdev->dev,
[PATCH v3 06/12] MIPS: ath79: Add OF support to the IRQ controllers
Add OF support for the CPU and MISC interrupt controllers of most supported ATH79 devices. Signed-off-by: Alban Bedel --- arch/mips/ath79/irq.c | 87 ++- 1 file changed, 86 insertions(+), 1 deletion(-) diff --git a/arch/mips/ath79/irq.c b/arch/mips/ath79/irq.c index 2c3991a..afb0096 100644 --- a/arch/mips/ath79/irq.c +++ b/arch/mips/ath79/irq.c @@ -15,7 +15,9 @@ #include #include #include -#include +#include +#include +#include "../../../drivers/irqchip/irqchip.h" #include #include @@ -23,6 +25,7 @@ #include #include #include "common.h" +#include "machtypes.h" static void ath79_misc_irq_handler(unsigned int irq, struct irq_desc *desc) { @@ -268,8 +271,90 @@ asmlinkage void plat_irq_dispatch(void) } } +#ifdef CONFIG_IRQCHIP +static int misc_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hw) +{ + irq_set_chip_and_handler(irq, &ath79_misc_irq_chip, handle_level_irq); + return 0; +} + +static const struct irq_domain_ops misc_irq_domain_ops = { + .xlate = irq_domain_xlate_onecell, + .map = misc_map, +}; + +static int __init ath79_misc_intc_of_init( + struct device_node *node, struct device_node *parent) +{ + void __iomem *base = ath79_reset_base; + struct irq_domain *domain; + int irq; + + irq = irq_of_parse_and_map(node, 0); + if (!irq) + panic("Failed to get MISC IRQ"); + + domain = irq_domain_add_legacy(node, ATH79_MISC_IRQ_COUNT, + ATH79_MISC_IRQ_BASE, 0, &misc_irq_domain_ops, NULL); + if (!domain) + panic("Failed to add MISC irqdomain"); + + /* Disable and clear all interrupts */ + __raw_writel(0, base + AR71XX_RESET_REG_MISC_INT_ENABLE); + __raw_writel(0, base + AR71XX_RESET_REG_MISC_INT_STATUS); + + + irq_set_chained_handler(irq, ath79_misc_irq_handler); + + return 0; +} +IRQCHIP_DECLARE(ath79_misc_intc, "qca,ar7100-misc-intc", + ath79_misc_intc_of_init); + +static int __init ar79_cpu_intc_of_init( + struct device_node *node, struct device_node *parent) +{ + int err, i, count; + + /* Fill the irq_wb_chan table */ + count = of_count_phandle_with_args( + node, "qca,ddr-wb-channels", "#qca,ddr-wb-channel-cells"); + + for (i = 0; i < count; i++) { + struct of_phandle_args args; + u32 irq = i; + + of_property_read_u32_index( + node, "qca,ddr-wb-channel-interrupts", i, &irq); + if (irq >= ARRAY_SIZE(irq_wb_chan)) + continue; + + err = of_parse_phandle_with_args( + node, "qca,ddr-wb-channels", + "#qca,ddr-wb-channel-cells", + i, &args); + if (err) + return err; + + irq_wb_chan[irq] = args.args[0]; + pr_info("IRQ: Set flush channel of IRQ%d to %d\n", + irq, args.args[0]); + } + + return mips_cpu_irq_of_init(node, parent); +} +IRQCHIP_DECLARE(ar79_cpu_intc, "qca,ar7100-cpu-intc", + ar79_cpu_intc_of_init); + +#endif + void __init arch_init_irq(void) { + if (mips_machtype == ATH79_MACH_GENERIC_OF) { + irqchip_init(); + return; + } + if (soc_is_ar71xx() || soc_is_ar724x() || soc_is_ar913x() || soc_is_ar933x()) { irq_wb_chan[2] = 3; -- 2.0.0 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v3 09/12] devicetree: Add bindings for the ATH79 GPIO controllers
These bindings support the GPIO controllers found on the Qualcomm Atheros AR7xxx/AR9XXX SoC. Signed-off-by: Alban Bedel --- v2: * Add the ngpios property to have fewer fallbacks and simpler code v3: * Fix missing 's' typo * Fix the example to be valid with the binding --- .../devicetree/bindings/gpio/gpio-ath79.txt| 38 ++ 1 file changed, 38 insertions(+) create mode 100644 Documentation/devicetree/bindings/gpio/gpio-ath79.txt diff --git a/Documentation/devicetree/bindings/gpio/gpio-ath79.txt b/Documentation/devicetree/bindings/gpio/gpio-ath79.txt new file mode 100644 index 000..3b72492 --- /dev/null +++ b/Documentation/devicetree/bindings/gpio/gpio-ath79.txt @@ -0,0 +1,38 @@ +Binding for Qualcomm Atheros AR7xxx/AR9xxx GPIO controller + +Required properties: +- compatible: has to be "qca,-gpio" and one of the following + fallbacks: + - "qca,ar7100-gpio" + - "qca,ar9340-gpio" +- reg: Base address and size of the controllers memory area +- gpio-controller : Marks the device node as a GPIO controller. +- #gpio-cells : Should be two. The first cell is the pin number and the + second cell is used to specify optional parameters. +- ngpios: Should be set to the number of GPIOs available on the SoC. + +Optional properties: +- interrupt-parent: phandle of the parent interrupt controller. +- interrupts: Interrupt specifier for the controllers interrupt. +- interrupt-controller : Identifies the node as an interrupt controller +- #interrupt-cells : Specifies the number of cells needed to encode interrupt +source, should be 2 + +Please refer to interrupts.txt in this directory for details of the common +Interrupt Controllers bindings used by client devices. + +Example: + + gpio@1804 { + compatible = "qca,ar9132-gpio", "qca,ar7100-gpio"; + reg = <0x1804 0x30>; + interrupts = <2>; + + ngpios = <22>; + + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; -- 2.0.0 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v3 11/12] of: Add vendor prefix for TP-Link Technologies Co. Ltd
Signed-off-by: Alban Bedel --- v3: * Put the new entry at the right place --- Documentation/devicetree/bindings/vendor-prefixes.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt index 83737a3..7ef1a6f 100644 --- a/Documentation/devicetree/bindings/vendor-prefixes.txt +++ b/Documentation/devicetree/bindings/vendor-prefixes.txt @@ -194,6 +194,7 @@ tlm Trusted Logic Mobility toradexToradex AG toshibaToshiba Corporation toumaz Toumaz +tplink TP-LINK Technologies Co., Ltd. truly Truly Semiconductors Limited usiUniversal Scientific Industrial Co., Ltd. v3 V3 Semiconductor -- 2.0.0 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v3 12/12] MIPS: Add basic support for the TL-WR1043ND version 1
Add a DTS for TL-WR1043ND version 1 and allow to have it built in the kernel to circumvent the broken u-boot found on these boards. Currently only the UART, LEDs and buttons are supported. Signed-off-by: Alban Bedel --- v2: * Rebased for the new vendor directory structure * Merged the 2 separate patch for SoC dtsi and board DTS in a single one * Fixed the node names to use ePAPR standardized names v3: * Moved adding the Kconfig Builtin devicetree menu to this patch * Set the Kconfig builtin DTB menu as optional, removed config DTB_ATH79_NONE and slightly improved the menu name and help message. --- arch/mips/ath79/Kconfig | 12 +++ arch/mips/boot/dts/Makefile | 1 + arch/mips/boot/dts/qca/Makefile | 9 ++ arch/mips/boot/dts/qca/ar9132.dtsi | 121 +++ arch/mips/boot/dts/qca/ar9132_tl_wr1043nd_v1.dts | 83 5 files changed, 226 insertions(+) create mode 100644 arch/mips/boot/dts/qca/Makefile create mode 100644 arch/mips/boot/dts/qca/ar9132.dtsi create mode 100644 arch/mips/boot/dts/qca/ar9132_tl_wr1043nd_v1.dts diff --git a/arch/mips/ath79/Kconfig b/arch/mips/ath79/Kconfig index dfc6020..13c04cf 100644 --- a/arch/mips/ath79/Kconfig +++ b/arch/mips/ath79/Kconfig @@ -71,6 +71,18 @@ config ATH79_MACH_UBNT_XM Say 'Y' here if you want your kernel to support the Ubiquiti Networks XM (rev 1.0) board. +choice + prompt "Build a DTB in the kernel" + optional + help + Select a devicetree that should be built into the kernel. + + config DTB_TL_WR1043ND_V1 + bool "TL-WR1043ND Version 1" + select BUILTIN_DTB + select SOC_AR913X +endchoice + endmenu config SOC_AR71XX diff --git a/arch/mips/boot/dts/Makefile b/arch/mips/boot/dts/Makefile index 5d95e4b..9975485 100644 --- a/arch/mips/boot/dts/Makefile +++ b/arch/mips/boot/dts/Makefile @@ -3,6 +3,7 @@ dts-dirs+= cavium-octeon dts-dirs += lantiq dts-dirs += mti dts-dirs += netlogic +dts-dirs += qca dts-dirs += ralink obj-y := $(addsuffix /, $(dts-dirs)) diff --git a/arch/mips/boot/dts/qca/Makefile b/arch/mips/boot/dts/qca/Makefile new file mode 100644 index 000..5f02aa6 --- /dev/null +++ b/arch/mips/boot/dts/qca/Makefile @@ -0,0 +1,9 @@ +dtb-$(CONFIG_DTB_TL_WR1043ND_V1) += ar9132_tl_wr1043nd_v1.dtb + +obj-y += $(patsubst %.dtb, %.dtb.o, $(dtb-y)) + +# Force kbuild to make empty built-in.o if necessary +obj- += dummy.o + +always := $(dtb-y) +clean-files:= *.dtb *.dtb.S diff --git a/arch/mips/boot/dts/qca/ar9132.dtsi b/arch/mips/boot/dts/qca/ar9132.dtsi new file mode 100644 index 000..c05b65c2 --- /dev/null +++ b/arch/mips/boot/dts/qca/ar9132.dtsi @@ -0,0 +1,121 @@ +/ { + compatible = "qca,ar9132"; + + #address-cells = <1>; + #size-cells = <1>; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu@0 { + device_type = "cpu"; + compatible = "mips,mips24Kc"; + reg = <0>; + }; + }; + + cpuintc: interrupt-controller { + compatible = "qca,ar9132-cpu-intc", "qca,ar7100-cpu-intc"; + + interrupt-controller; + #interrupt-cells = <1>; + + qca,ddr-wb-channel-interrupts = <2>, <3>, <4>, <5>; + qca,ddr-wb-channels = <&ddr_ctrl 3>, <&ddr_ctrl 2>, + <&ddr_ctrl 0>, <&ddr_ctrl 1>; + }; + + ahb { + compatible = "simple-bus"; + ranges; + + #address-cells = <1>; + #size-cells = <1>; + + interrupt-parent = <&cpuintc>; + + apb { + compatible = "simple-bus"; + ranges; + + #address-cells = <1>; + #size-cells = <1>; + + interrupt-parent = <&miscintc>; + + ddr_ctrl: memory-controller@1800 { + compatible = "qca,ar9132-ddr-controller", + "qca,ar7240-ddr-controller"; + reg = <0x1800 0x100>; + + #qca,ddr-wb-channel-cells = <1>; + }; + + uart@1802 { + compatible = "ns8250"; +
[PATCH 0/4] spi: spi-ath79: Devicetree support and misc fixes
Hello all, this serie add a DT support for the ATH79 SPI controller and fix a few trivial bugs. While adding DT support we also remove the unused custom controller data in favor of the generic GPIO based chip select. The clock patch add the missing clk_un/prepare to fix the warnings once the platform is moved to the generic clock framework. Finally the last patch is to ensure that CS_HIGH chips using CS0 get the proper CS level before the first transfer. Alban Alban Bedel (4): devicetree: add binding documentation for the AR7100 SPI controller spi: spi-ath79: Add device tree support spi: spi-ath79: Use clk_prepare_enable and clk_disable_unprepare spi: spi-ath79: Set the initial state of CS0 .../devicetree/bindings/spi/spi-ath79.txt | 24 +++ .../include/asm/mach-ath79/ath79_spi_platform.h| 4 --- drivers/spi/spi-ath79.c| 34 ++ 3 files changed, 46 insertions(+), 16 deletions(-) create mode 100644 Documentation/devicetree/bindings/spi/spi-ath79.txt -- 2.0.0 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 4/4] spi: spi-ath79: Set the initial state of CS0
The internal chip select CS0 wasn't initialized properly to work with CS HIGH chips. Signed-off-by: Alban Bedel --- drivers/spi/spi-ath79.c | 8 1 file changed, 8 insertions(+) diff --git a/drivers/spi/spi-ath79.c b/drivers/spi/spi-ath79.c index b37bedd..bf1f9b3 100644 --- a/drivers/spi/spi-ath79.c +++ b/drivers/spi/spi-ath79.c @@ -115,6 +115,7 @@ static void ath79_spi_disable(struct ath79_spi *sp) static int ath79_spi_setup_cs(struct spi_device *spi) { + struct ath79_spi *sp = ath79_spidev_to_sp(spi); int status; if (spi->chip_select && !gpio_is_valid(spi->cs_gpio)) @@ -132,6 +133,13 @@ static int ath79_spi_setup_cs(struct spi_device *spi) status = gpio_request_one(spi->cs_gpio, flags, dev_name(&spi->dev)); + } else { + if (spi->mode & SPI_CS_HIGH) + sp->ioc_base &= ~AR71XX_SPI_IOC_CS0; + else + sp->ioc_base |= AR71XX_SPI_IOC_CS0; + + ath79_spi_wr(sp, AR71XX_SPI_REG_IOC, sp->ioc_base); } return status; -- 2.0.0 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 3/4] spi: spi-ath79: Use clk_prepare_enable and clk_disable_unprepare
Clocks should be prepared and unprepared, fix this by using clk_prepare_enable() and clk_disable_unprepare() instead of clk_enable() and clk_disable(). Signed-off-by: Alban Bedel --- drivers/spi/spi-ath79.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/spi/spi-ath79.c b/drivers/spi/spi-ath79.c index 239bc31..b37bedd 100644 --- a/drivers/spi/spi-ath79.c +++ b/drivers/spi/spi-ath79.c @@ -249,7 +249,7 @@ static int ath79_spi_probe(struct platform_device *pdev) goto err_put_master; } - ret = clk_enable(sp->clk); + ret = clk_prepare_enable(sp->clk); if (ret) goto err_put_master; @@ -273,7 +273,7 @@ static int ath79_spi_probe(struct platform_device *pdev) err_disable: ath79_spi_disable(sp); err_clk_disable: - clk_disable(sp->clk); + clk_disable_unprepare(sp->clk); err_put_master: spi_master_put(sp->bitbang.master); @@ -286,7 +286,7 @@ static int ath79_spi_remove(struct platform_device *pdev) spi_bitbang_stop(&sp->bitbang); ath79_spi_disable(sp); - clk_disable(sp->clk); + clk_disable_unprepare(sp->clk); spi_master_put(sp->bitbang.master); return 0; -- 2.0.0 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 2/4] spi: spi-ath79: Add device tree support
Set the OF node of the spi controller and use the generic GPIO based chip select instead of the custom controller data. As the controller data isn't used by any board just drop it. Signed-off-by: Alban Bedel --- .../mips/include/asm/mach-ath79/ath79_spi_platform.h | 4 drivers/spi/spi-ath79.c | 20 +++- 2 files changed, 11 insertions(+), 13 deletions(-) diff --git a/arch/mips/include/asm/mach-ath79/ath79_spi_platform.h b/arch/mips/include/asm/mach-ath79/ath79_spi_platform.h index aa2283e..aa71216 100644 --- a/arch/mips/include/asm/mach-ath79/ath79_spi_platform.h +++ b/arch/mips/include/asm/mach-ath79/ath79_spi_platform.h @@ -16,8 +16,4 @@ struct ath79_spi_platform_data { unsignednum_chipselect; }; -struct ath79_spi_controller_data { - unsignedgpio; -}; - #endif /* _ATH79_SPI_PLATFORM_H */ diff --git a/drivers/spi/spi-ath79.c b/drivers/spi/spi-ath79.c index b02eb4a..239bc31 100644 --- a/drivers/spi/spi-ath79.c +++ b/drivers/spi/spi-ath79.c @@ -79,10 +79,8 @@ static void ath79_spi_chipselect(struct spi_device *spi, int is_active) } if (spi->chip_select) { - struct ath79_spi_controller_data *cdata = spi->controller_data; - /* SPI is normally active-low */ - gpio_set_value(cdata->gpio, cs_high); + gpio_set_value(spi->cs_gpio, cs_high); } else { if (cs_high) sp->ioc_base |= AR71XX_SPI_IOC_CS0; @@ -117,11 +115,9 @@ static void ath79_spi_disable(struct ath79_spi *sp) static int ath79_spi_setup_cs(struct spi_device *spi) { - struct ath79_spi_controller_data *cdata; int status; - cdata = spi->controller_data; - if (spi->chip_select && !cdata) + if (spi->chip_select && !gpio_is_valid(spi->cs_gpio)) return -EINVAL; status = 0; @@ -134,7 +130,7 @@ static int ath79_spi_setup_cs(struct spi_device *spi) else flags |= GPIOF_INIT_HIGH; - status = gpio_request_one(cdata->gpio, flags, + status = gpio_request_one(spi->cs_gpio, flags, dev_name(&spi->dev)); } @@ -144,8 +140,7 @@ static int ath79_spi_setup_cs(struct spi_device *spi) static void ath79_spi_cleanup_cs(struct spi_device *spi) { if (spi->chip_select) { - struct ath79_spi_controller_data *cdata = spi->controller_data; - gpio_free(cdata->gpio); + gpio_free(spi->cs_gpio); } } @@ -217,6 +212,7 @@ static int ath79_spi_probe(struct platform_device *pdev) } sp = spi_master_get_devdata(master); + master->dev.of_node = pdev->dev.of_node; platform_set_drvdata(pdev, sp); pdata = dev_get_platdata(&pdev->dev); @@ -301,12 +297,18 @@ static void ath79_spi_shutdown(struct platform_device *pdev) ath79_spi_remove(pdev); } +static const struct of_device_id ath79_spi_of_match[] = { + { .compatible = "qca,ar7100-spi", }, + { }, +}; + static struct platform_driver ath79_spi_driver = { .probe = ath79_spi_probe, .remove = ath79_spi_remove, .shutdown = ath79_spi_shutdown, .driver = { .name = DRV_NAME, + .of_match_table = ath79_spi_of_match, }, }; module_platform_driver(ath79_spi_driver); -- 2.0.0 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 1/4] devicetree: add binding documentation for the AR7100 SPI controller
Signed-off-by: Alban Bedel --- .../devicetree/bindings/spi/spi-ath79.txt | 24 ++ 1 file changed, 24 insertions(+) create mode 100644 Documentation/devicetree/bindings/spi/spi-ath79.txt diff --git a/Documentation/devicetree/bindings/spi/spi-ath79.txt b/Documentation/devicetree/bindings/spi/spi-ath79.txt new file mode 100644 index 000..f1ad9c3 --- /dev/null +++ b/Documentation/devicetree/bindings/spi/spi-ath79.txt @@ -0,0 +1,24 @@ +Binding for Qualcomm Atheros AR7xxx/AR9xxx SPI controller + +Required properties: +- compatible: has to be "qca,-spi", "qca,ar7100-spi" as fallback. +- reg: Base address and size of the controllers memory area +- clocks: phandle to the AHB clock. +- clock-names: has to be "ahb". +- #address-cells: <1>, as required by generic SPI binding. +- #size-cells: <0>, also as required by generic SPI binding. + +Child nodes as per the generic SPI binding. + +Example: + + spi@1F00 { + compatible = "qca,ar9132-spi", "qca,ar7100-spi"; + reg = <0x1F00 0x10>; + + clocks = <&pll 2>; + clock-names = "ahb"; + + #address-cells = <1>; + #size-cells = <0>; + }; -- 2.0.0 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATH] MIPS: ath79: Various small fix to prepare OF support
This first small serie allow using ZBOOT, fix a few errors in the registers definitions and rework the DDR controller interface. The DDR controller interface patch is mostly to simplify the IRQ controller code before adding OF support. Following this will a be serie that add the OF bindings and code support for the core component of the SoC as well as a DTS for the TL-WR1043ND. -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 1/5] MIPS: ath79: Enable ZBOOT support
ZBOOT is working fine, so allow using it. Signed-off-by: Alban Bedel --- arch/mips/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index a326c4c..cc7f262 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -128,6 +128,7 @@ config ATH79 select SYS_SUPPORTS_32BIT_KERNEL select SYS_SUPPORTS_BIG_ENDIAN select SYS_SUPPORTS_MIPS16 + select SYS_SUPPORTS_ZBOOT help Support for the Atheros AR71XX/AR724X/AR913X SoCs. -- 2.0.0 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 4/5] MIPS: ath79: Fix the PCI memory size and offset of window 7
The define AR71XX_PCI_MEM_SIZE miss one window, there is 7 windows, not 6. To make things clearer, and allow simpler code, derive AR71XX_PCI_MEM_SIZE from the newly introduced AR71XX_PCI_WIN_COUNT and AR71XX_PCI_WIN_SIZE. The define AR71XX_PCI_WIN7_OFFS also add a typo, fix it. Signed-off-by: Alban Bedel --- arch/mips/include/asm/mach-ath79/ar71xx_regs.h | 6 -- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/arch/mips/include/asm/mach-ath79/ar71xx_regs.h b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h index aa3800c..e2669a8 100644 --- a/arch/mips/include/asm/mach-ath79/ar71xx_regs.h +++ b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h @@ -41,7 +41,9 @@ #define AR71XX_RESET_SIZE 0x100 #define AR71XX_PCI_MEM_BASE0x1000 -#define AR71XX_PCI_MEM_SIZE0x0700 +#define AR71XX_PCI_WIN_COUNT 8 +#define AR71XX_PCI_WIN_SIZE0x0100 +#define AR71XX_PCI_MEM_SIZE(AR71XX_PCI_WIN_COUNT * AR71XX_PCI_WIN_SIZE) #define AR71XX_PCI_WIN0_OFFS 0x1000 #define AR71XX_PCI_WIN1_OFFS 0x1100 @@ -50,7 +52,7 @@ #define AR71XX_PCI_WIN4_OFFS 0x1400 #define AR71XX_PCI_WIN5_OFFS 0x1500 #define AR71XX_PCI_WIN6_OFFS 0x1600 -#define AR71XX_PCI_WIN7_OFFS 0x0700 +#define AR71XX_PCI_WIN7_OFFS 0x1700 #define AR71XX_PCI_CFG_BASE\ (AR71XX_PCI_MEM_BASE + AR71XX_PCI_WIN7_OFFS + 0x1) -- 2.0.0 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 3/5] MIPS: ath79: Correctly name the defines for the PLL_FB register
This register is named PLL_FB and is not a divider but a multiplier. To make things less confusing rename the AR_PLL_DIV_SHIFT and AR_PLL_DIV_MASK macros to AR_PLL_FB_SHIFT and AR_PLL_FB_MASK. Signed-off-by: Alban Bedel --- arch/mips/ath79/clock.c| 6 +++--- arch/mips/include/asm/mach-ath79/ar71xx_regs.h | 12 ++-- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/arch/mips/ath79/clock.c b/arch/mips/ath79/clock.c index 26479f4..226ddf0 100644 --- a/arch/mips/ath79/clock.c +++ b/arch/mips/ath79/clock.c @@ -62,7 +62,7 @@ static void __init ar71xx_clocks_init(void) pll = ath79_pll_rr(AR71XX_PLL_REG_CPU_CONFIG); - div = ((pll >> AR71XX_PLL_DIV_SHIFT) & AR71XX_PLL_DIV_MASK) + 1; + div = ((pll >> AR71XX_PLL_FB_SHIFT) & AR71XX_PLL_FB_MASK) + 1; freq = div * ref_rate; div = ((pll >> AR71XX_CPU_DIV_SHIFT) & AR71XX_CPU_DIV_MASK) + 1; @@ -96,7 +96,7 @@ static void __init ar724x_clocks_init(void) ref_rate = AR724X_BASE_FREQ; pll = ath79_pll_rr(AR724X_PLL_REG_CPU_CONFIG); - div = ((pll >> AR724X_PLL_DIV_SHIFT) & AR724X_PLL_DIV_MASK); + div = ((pll >> AR724X_PLL_FB_SHIFT) & AR724X_PLL_FB_MASK); freq = div * ref_rate; div = ((pll >> AR724X_PLL_REF_DIV_SHIFT) & AR724X_PLL_REF_DIV_MASK); @@ -132,7 +132,7 @@ static void __init ar913x_clocks_init(void) ref_rate = AR913X_BASE_FREQ; pll = ath79_pll_rr(AR913X_PLL_REG_CPU_CONFIG); - div = ((pll >> AR913X_PLL_DIV_SHIFT) & AR913X_PLL_DIV_MASK); + div = ((pll >> AR913X_PLL_FB_SHIFT) & AR913X_PLL_FB_MASK); freq = div * ref_rate; cpu_rate = freq; diff --git a/arch/mips/include/asm/mach-ath79/ar71xx_regs.h b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h index cd41e93..aa3800c 100644 --- a/arch/mips/include/asm/mach-ath79/ar71xx_regs.h +++ b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h @@ -157,8 +157,8 @@ #define AR71XX_PLL_REG_ETH0_INT_CLOCK 0x10 #define AR71XX_PLL_REG_ETH1_INT_CLOCK 0x14 -#define AR71XX_PLL_DIV_SHIFT 3 -#define AR71XX_PLL_DIV_MASK0x1f +#define AR71XX_PLL_FB_SHIFT3 +#define AR71XX_PLL_FB_MASK 0x1f #define AR71XX_CPU_DIV_SHIFT 16 #define AR71XX_CPU_DIV_MASK0x3 #define AR71XX_DDR_DIV_SHIFT 18 @@ -169,8 +169,8 @@ #define AR724X_PLL_REG_CPU_CONFIG 0x00 #define AR724X_PLL_REG_PCIE_CONFIG 0x18 -#define AR724X_PLL_DIV_SHIFT 0 -#define AR724X_PLL_DIV_MASK0x3ff +#define AR724X_PLL_FB_SHIFT0 +#define AR724X_PLL_FB_MASK 0x3ff #define AR724X_PLL_REF_DIV_SHIFT 10 #define AR724X_PLL_REF_DIV_MASK0xf #define AR724X_AHB_DIV_SHIFT 19 @@ -183,8 +183,8 @@ #define AR913X_PLL_REG_ETH0_INT_CLOCK 0x14 #define AR913X_PLL_REG_ETH1_INT_CLOCK 0x18 -#define AR913X_PLL_DIV_SHIFT 0 -#define AR913X_PLL_DIV_MASK0x3ff +#define AR913X_PLL_FB_SHIFT0 +#define AR913X_PLL_FB_MASK 0x3ff #define AR913X_DDR_DIV_SHIFT 22 #define AR913X_DDR_DIV_MASK0x3 #define AR913X_AHB_DIV_SHIFT 19 -- 2.0.0 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 2/5] MIPS: ath79: Add a missing new line in log message
The memory setup log is missing a new line. Signed-off-by: Alban Bedel --- arch/mips/ath79/setup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/mips/ath79/setup.c b/arch/mips/ath79/setup.c index a73c93c..7fc8397 100644 --- a/arch/mips/ath79/setup.c +++ b/arch/mips/ath79/setup.c @@ -225,7 +225,7 @@ void __init plat_time_init(void) ddr_clk_rate = ath79_get_sys_clk_rate("ddr"); ref_clk_rate = ath79_get_sys_clk_rate("ref"); - pr_info("Clocks: CPU:%lu.%03luMHz, DDR:%lu.%03luMHz, AHB:%lu.%03luMHz, Ref:%lu.%03luMHz", + pr_info("Clocks: CPU:%lu.%03luMHz, DDR:%lu.%03luMHz, AHB:%lu.%03luMHz, Ref:%lu.%03luMHz\n", cpu_clk_rate / 100, (cpu_clk_rate / 1000) % 1000, ddr_clk_rate / 100, (ddr_clk_rate / 1000) % 1000, ahb_clk_rate / 100, (ahb_clk_rate / 1000) % 1000, -- 2.0.0 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 5/5] MIPS: ath79: Improve the DDR controller interface
The DDR controller need to be used by the IRQ controller to flush the write buffer of some devices before running the IRQ handler. It is also used by the PCI controller to setup the PCI memory windows. The current interface used to access the DDR controller doesn't provides any useful abstraction and simply rely on a shared global pointer. Replace this by a simple API to setup the PCI memory windows and use the write buffer flush independently of the SoC type. That remove the need for the shared global pointer, simplify the IRQ handler code. Signed-off-by: Alban Bedel --- arch/mips/ath79/common.c | 32 ++- arch/mips/ath79/common.h | 1 + arch/mips/ath79/irq.c| 147 +++ arch/mips/ath79/setup.c | 3 +- arch/mips/include/asm/mach-ath79/ath79.h | 3 +- arch/mips/pci/pci-ar71xx.c | 10 +-- 6 files changed, 68 insertions(+), 128 deletions(-) diff --git a/arch/mips/ath79/common.c b/arch/mips/ath79/common.c index eb3966c..61022b6 100644 --- a/arch/mips/ath79/common.c +++ b/arch/mips/ath79/common.c @@ -38,11 +38,27 @@ unsigned int ath79_soc_rev; void __iomem *ath79_pll_base; void __iomem *ath79_reset_base; EXPORT_SYMBOL_GPL(ath79_reset_base); -void __iomem *ath79_ddr_base; +static void __iomem *ath79_ddr_base; +static void __iomem *ath79_ddr_wb_flush_base; +static void __iomem *ath79_ddr_pci_win_base; + +void ath79_ddr_ctrl_init(void) +{ + ath79_ddr_base = ioremap_nocache(AR71XX_DDR_CTRL_BASE, +AR71XX_DDR_CTRL_SIZE); + if (soc_is_ar71xx() || soc_is_ar934x()) { + ath79_ddr_wb_flush_base = ath79_ddr_base + 0x9c; + ath79_ddr_pci_win_base = ath79_ddr_base + 0x7c; + } else { + ath79_ddr_wb_flush_base = ath79_ddr_base + 0x7c; + ath79_ddr_pci_win_base = 0; + } +} +EXPORT_SYMBOL_GPL(ath79_ddr_ctrl_init); void ath79_ddr_wb_flush(u32 reg) { - void __iomem *flush_reg = ath79_ddr_base + reg; + void __iomem *flush_reg = ath79_ddr_wb_flush_base + reg; /* Flush the DDR write buffer. */ __raw_writel(0x1, flush_reg); @@ -56,6 +72,18 @@ void ath79_ddr_wb_flush(u32 reg) } EXPORT_SYMBOL_GPL(ath79_ddr_wb_flush); +void ath79_ddr_set_pci_windows(void) +{ + unsigned win; + + BUG_ON(!ath79_ddr_pci_win_base); + + for (win = 0; win < AR71XX_PCI_WIN_COUNT ; win++) + __raw_writel(AR71XX_PCI_MEM_BASE + win * AR71XX_PCI_WIN_SIZE, + ath79_ddr_pci_win_base + win); +} +EXPORT_SYMBOL_GPL(ath79_ddr_set_pci_windows); + void ath79_device_reset_set(u32 mask) { unsigned long flags; diff --git a/arch/mips/ath79/common.h b/arch/mips/ath79/common.h index a312071..a14269f 100644 --- a/arch/mips/ath79/common.h +++ b/arch/mips/ath79/common.h @@ -22,6 +22,7 @@ void ath79_clocks_init(void); unsigned long ath79_get_sys_clk_rate(const char *id); +void ath79_ddr_ctrl_init(void); void ath79_ddr_wb_flush(unsigned int reg); void ath79_gpio_function_enable(u32 mask); diff --git a/arch/mips/ath79/irq.c b/arch/mips/ath79/irq.c index 6adae36..2c3991a 100644 --- a/arch/mips/ath79/irq.c +++ b/arch/mips/ath79/irq.c @@ -24,9 +24,6 @@ #include #include "common.h" -static void (*ath79_ip2_handler)(void); -static void (*ath79_ip3_handler)(void); - static void ath79_misc_irq_handler(unsigned int irq, struct irq_desc *desc) { void __iomem *base = ath79_reset_base; @@ -129,10 +126,10 @@ static void ar934x_ip2_irq_dispatch(unsigned int irq, struct irq_desc *desc) status = ath79_reset_rr(AR934X_RESET_REG_PCIE_WMAC_INT_STATUS); if (status & AR934X_PCIE_WMAC_INT_PCIE_ALL) { - ath79_ddr_wb_flush(AR934X_DDR_REG_FLUSH_PCIE); + ath79_ddr_wb_flush(3); generic_handle_irq(ATH79_IP2_IRQ(0)); } else if (status & AR934X_PCIE_WMAC_INT_WMAC_ALL) { - ath79_ddr_wb_flush(AR934X_DDR_REG_FLUSH_WMAC); + ath79_ddr_wb_flush(4); generic_handle_irq(ATH79_IP2_IRQ(1)); } else { spurious_interrupt(); @@ -235,128 +232,50 @@ static void qca955x_irq_init(void) irq_set_chained_handler(ATH79_CPU_IRQ(3), qca955x_ip3_irq_dispatch); } -asmlinkage void plat_irq_dispatch(void) -{ - unsigned long pending; - - pending = read_c0_status() & read_c0_cause() & ST0_IM; - - if (pending & STATUSF_IP7) - do_IRQ(ATH79_CPU_IRQ(7)); - - else if (pending & STATUSF_IP2) - ath79_ip2_handler(); - - else if (pending & STATUSF_IP4) - do_IRQ(ATH79_CPU_IRQ(4)); - - else if (pending & STATUSF_IP5) - do_IRQ(ATH79_CPU_IRQ(5)); - - else if (pending & STATUSF_IP3) - ath79_ip3_handler(); - - else if (pending & STATUSF_IP6
[PATH] MIPS: ath79: Add OF support and DTS for TL-WR1043ND
This series add OF bindings and code support for the interrupt controllers, clocks and GPIOs. However it was only tested on a TL-WR1043ND with an AR9132, others SoCs are untested, and a few are not supported at all. Most code changes base on the previous bug fix series: [PATH] MIPS: ath79: Various small fix to prepare OF support -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 01/14] devicetree: Add bindings for the SoC of the ATH79 familly
Signed-off-by: Alban Bedel --- .../devicetree/bindings/mips/ath79-soc.txt | 21 + 1 file changed, 21 insertions(+) create mode 100644 Documentation/devicetree/bindings/mips/ath79-soc.txt diff --git a/Documentation/devicetree/bindings/mips/ath79-soc.txt b/Documentation/devicetree/bindings/mips/ath79-soc.txt new file mode 100644 index 000..88a12a4 --- /dev/null +++ b/Documentation/devicetree/bindings/mips/ath79-soc.txt @@ -0,0 +1,21 @@ +Binding for Qualcomm Atheros AR7xxx/AR9XXX SoC + +Each device tree must specify a compatible value for the AR SoC +it uses in the compatible property of the root node. The compatible +value must be one of the following values: + +- qca,ar7130 +- qca,ar7141 +- qca,ar7161 +- qca,ar7240 +- qca,ar7241 +- qca,ar7242 +- qca,ar9130 +- qca,ar9132 +- qca,ar9330 +- qca,ar9331 +- qca,ar9341 +- qca,ar9342 +- qca,ar9344 +- qca,qca9556 +- qca,qca9558 -- 2.0.0 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 04/14] devicetree: Add bindings for the ATH79 interrupt controllers
Signed-off-by: Alban Bedel --- .../interrupt-controller/qca,ath79-cpu-intc.txt| 45 ++ 1 file changed, 45 insertions(+) create mode 100644 Documentation/devicetree/bindings/interrupt-controller/qca,ath79-cpu-intc.txt diff --git a/Documentation/devicetree/bindings/interrupt-controller/qca,ath79-cpu-intc.txt b/Documentation/devicetree/bindings/interrupt-controller/qca,ath79-cpu-intc.txt new file mode 100644 index 000..1548512 --- /dev/null +++ b/Documentation/devicetree/bindings/interrupt-controller/qca,ath79-cpu-intc.txt @@ -0,0 +1,45 @@ +Binding for Qualcomm Atheros AR7xxx/AR9XXX CPU interrupt controller + +On most SoC the IRQ controller need to flush the DDR FIFO before running +the interrupt handler of some devices. This is configured using the +qca,ddr-wb-channels and qca,ddr-wb-channel-interrupts properties. + +Required Properties: + +- compatible: has to be "qca,-cpu-intc", "qca,ar7100-cpu-intc" + as fallback +- interrupt-controller : Identifies the node as an interrupt controller +- #interrupt-cells : Specifies the number of cells needed to encode interrupt +source, should be 1 for intc + +Please refer to interrupts.txt in this directory for details of the common +Interrupt Controllers bindings used by client devices. + +Optional Properties: + +- qca,ddr-wb-channel-interrupts: List of the interrupts needing a write + buffer flush +- qca,ddr-wb-channels: List of phandles to the write buffer channels for + each interrupt. If qca,ddr-wb-channel-interrupts is not present the interrupt + default to the entry's index. + +Example: + + cpuintc@0 { + compatible = "qca,ar9132-cpu-intc", "qca,ar7100-cpu-intc"; + + interrupt-controller; + #interrupt-cells = <1>; + + qca,ddr-wb-channel-interrupts = <2>, <3>, <4>, <5>; + qca,ddr-wb-channels = <&ddr_ctrl 3>, <&ddr_ctrl 2>, + <&ddr_ctrl 0>, <&ddr_ctrl 1>; + }; + + ... + + ddr_ctrl: ddr-controller@1800 { + ... + #qca,ddr-wb-channel-cells = <1>; + }; + -- 2.0.0 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 11/14] MIPS: ath79: Add OF support to the GPIO driver
Replace the simple GPIO chip registration by a platform driver and make ath79_gpio_init() just register the device. Signed-off-by: Alban Bedel --- arch/mips/ath79/dev-common.c | 13 arch/mips/ath79/gpio.c | 73 +--- 2 files changed, 81 insertions(+), 5 deletions(-) diff --git a/arch/mips/ath79/dev-common.c b/arch/mips/ath79/dev-common.c index 516225d..4f397cb 100644 --- a/arch/mips/ath79/dev-common.c +++ b/arch/mips/ath79/dev-common.c @@ -106,3 +106,16 @@ void __init ath79_register_wdt(void) platform_device_register_simple("ath79-wdt", -1, &res, 1); } + +void __init ath79_gpio_init(void) +{ + struct resource res; + + memset(&res, 0, sizeof(res)); + + res.flags = IORESOURCE_MEM; + res.start = AR71XX_GPIO_BASE; + res.end = res.start + AR71XX_GPIO_SIZE - 1; + + platform_device_register_simple("ath79-gpio", -1, &res, 1); +} diff --git a/arch/mips/ath79/gpio.c b/arch/mips/ath79/gpio.c index 8d025b0..ce1a61d 100644 --- a/arch/mips/ath79/gpio.c +++ b/arch/mips/ath79/gpio.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -178,11 +179,52 @@ void ath79_gpio_function_disable(u32 mask) ath79_gpio_function_setup(0, mask); } -void __init ath79_gpio_init(void) +static const struct of_device_id ath79_gpio_of_match[] = { + { + .compatible = "qca,ar7100-gpio", + .data = (void *)AR71XX_GPIO_COUNT, + }, + { + .compatible = "qca,ar7240-gpio", + .data = (void *)AR7240_GPIO_COUNT, + }, + { + .compatible = "qca,ar7241-gpio", + .data = (void *)AR7241_GPIO_COUNT, + }, + { + .compatible = "qca,ar9130-gpio", + .data = (void *)AR913X_GPIO_COUNT, + }, + { + .compatible = "qca,ar9330-gpio", + .data = (void *)AR933X_GPIO_COUNT, + }, + { + .compatible = "qca,ar9340-gpio", + .data = (void *)AR934X_GPIO_COUNT, + }, + { + .compatible = "qca,qca9550-gpio", + .data = (void *)QCA955X_GPIO_COUNT, + }, + {}, +}; + +static int ath79_gpio_probe(struct platform_device *pdev) { + struct resource *res; int err; - if (soc_is_ar71xx()) + if (pdev->dev.of_node) { + const struct of_device_id *of_id = + of_match_device(ath79_gpio_of_match, &pdev->dev); + if (!of_id) { + dev_err(&pdev->dev, "Error: No device match found\n"); + return -ENODEV; + } + ath79_gpio_count = (unsigned long)of_id->data; + } else if (soc_is_ar71xx()) ath79_gpio_count = AR71XX_GPIO_COUNT; else if (soc_is_ar7240()) ath79_gpio_count = AR7240_GPIO_COUNT; @@ -199,7 +241,13 @@ void __init ath79_gpio_init(void) else BUG(); - ath79_gpio_base = ioremap_nocache(AR71XX_GPIO_BASE, AR71XX_GPIO_SIZE); + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + ath79_gpio_base = devm_ioremap_nocache( + &pdev->dev, res->start, resource_size(res)); + if (!ath79_gpio_base) + return -ENOMEM; + + ath79_gpio_chip.dev = &pdev->dev; ath79_gpio_chip.ngpio = ath79_gpio_count; if (soc_is_ar934x() || soc_is_qca955x()) { ath79_gpio_chip.direction_input = ar934x_gpio_direction_input; @@ -207,10 +255,25 @@ void __init ath79_gpio_init(void) } err = gpiochip_add(&ath79_gpio_chip); - if (err) - panic("cannot add AR71xx GPIO chip, error=%d", err); + if (err) { + dev_err(&pdev->dev, + "cannot add AR71xx GPIO chip, error=%d", err); + return err; + } + + return 0; } +static struct platform_driver ath79_gpio_driver = { + .driver = { + .name = "ath79-gpio", + .of_match_table = ath79_gpio_of_match, + }, + .probe = ath79_gpio_probe, +}; + +module_platform_driver(ath79_gpio_driver); + int gpio_get_value(unsigned gpio) { if (gpio < ath79_gpio_count) -- 2.0.0 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 09/14] MIPS: ath79: Add OF support to the clocks
Allow using the SoC clocks in the device tree. Signed-off-by: Alban Bedel --- arch/mips/ath79/clock.c | 63 ++--- 1 file changed, 44 insertions(+), 19 deletions(-) diff --git a/arch/mips/ath79/clock.c b/arch/mips/ath79/clock.c index 1fcb691..682bf61 100644 --- a/arch/mips/ath79/clock.c +++ b/arch/mips/ath79/clock.c @@ -29,7 +29,14 @@ #define AR724X_BASE_FREQ 500 #define AR913X_BASE_FREQ 500 -static void __init ath79_add_sys_clkdev(const char *id, unsigned long rate) +static struct clk *clks[3]; +static struct clk_onecell_data clk_data = { + .clks = clks, + .clk_num = ARRAY_SIZE(clks), +}; + +static struct clk *__init ath79_add_sys_clkdev( + const char *id, unsigned long rate) { struct clk *clk; int err; @@ -41,6 +48,8 @@ static void __init ath79_add_sys_clkdev(const char *id, unsigned long rate) err = clk_register_clkdev(clk, id, NULL); if (err) panic("unable to register %s clock device", id); + + return clk; } static void __init ar71xx_clocks_init(void) @@ -70,9 +79,9 @@ static void __init ar71xx_clocks_init(void) ahb_rate = cpu_rate / div; ath79_add_sys_clkdev("ref", ref_rate); - ath79_add_sys_clkdev("cpu", cpu_rate); - ath79_add_sys_clkdev("ddr", ddr_rate); - ath79_add_sys_clkdev("ahb", ahb_rate); + clks[0] = ath79_add_sys_clkdev("cpu", cpu_rate); + clks[1] = ath79_add_sys_clkdev("ddr", ddr_rate); + clks[2] = ath79_add_sys_clkdev("ahb", ahb_rate); clk_add_alias("wdt", NULL, "ahb", NULL); clk_add_alias("uart", NULL, "ahb", NULL); @@ -106,9 +115,9 @@ static void __init ar724x_clocks_init(void) ahb_rate = cpu_rate / div; ath79_add_sys_clkdev("ref", ref_rate); - ath79_add_sys_clkdev("cpu", cpu_rate); - ath79_add_sys_clkdev("ddr", ddr_rate); - ath79_add_sys_clkdev("ahb", ahb_rate); + clks[0] = ath79_add_sys_clkdev("cpu", cpu_rate); + clks[1] = ath79_add_sys_clkdev("ddr", ddr_rate); + clks[2] = ath79_add_sys_clkdev("ahb", ahb_rate); clk_add_alias("wdt", NULL, "ahb", NULL); clk_add_alias("uart", NULL, "ahb", NULL); @@ -139,9 +148,9 @@ static void __init ar913x_clocks_init(void) ahb_rate = cpu_rate / div; ath79_add_sys_clkdev("ref", ref_rate); - ath79_add_sys_clkdev("cpu", cpu_rate); - ath79_add_sys_clkdev("ddr", ddr_rate); - ath79_add_sys_clkdev("ahb", ahb_rate); + clks[0] = ath79_add_sys_clkdev("cpu", cpu_rate); + clks[1] = ath79_add_sys_clkdev("ddr", ddr_rate); + clks[2] = ath79_add_sys_clkdev("ahb", ahb_rate); clk_add_alias("wdt", NULL, "ahb", NULL); clk_add_alias("uart", NULL, "ahb", NULL); @@ -201,9 +210,9 @@ static void __init ar933x_clocks_init(void) } ath79_add_sys_clkdev("ref", ref_rate); - ath79_add_sys_clkdev("cpu", cpu_rate); - ath79_add_sys_clkdev("ddr", ddr_rate); - ath79_add_sys_clkdev("ahb", ahb_rate); + clks[0] = ath79_add_sys_clkdev("cpu", cpu_rate); + clks[1] = ath79_add_sys_clkdev("ddr", ddr_rate); + clks[2] = ath79_add_sys_clkdev("ahb", ahb_rate); clk_add_alias("wdt", NULL, "ahb", NULL); clk_add_alias("uart", NULL, "ref", NULL); @@ -335,9 +344,9 @@ static void __init ar934x_clocks_init(void) ahb_rate = cpu_pll / (postdiv + 1); ath79_add_sys_clkdev("ref", ref_rate); - ath79_add_sys_clkdev("cpu", cpu_rate); - ath79_add_sys_clkdev("ddr", ddr_rate); - ath79_add_sys_clkdev("ahb", ahb_rate); + clks[0] = ath79_add_sys_clkdev("cpu", cpu_rate); + clks[1] = ath79_add_sys_clkdev("ddr", ddr_rate); + clks[2] = ath79_add_sys_clkdev("ahb", ahb_rate); clk_add_alias("wdt", NULL, "ref", NULL); clk_add_alias("uart", NULL, "ref", NULL); @@ -422,9 +431,9 @@ static void __init qca955x_clocks_init(void) ahb_rate = cpu_pll / (postdiv + 1); ath79_add_sys_clkdev("ref", ref_rate); - ath79_add_sys_clkdev("cpu", cpu_rate); - ath79_add_sys_clkdev("ddr", ddr_rate); - ath79_add_sys_clkdev("ahb", ahb_rate); + clks[0] = ath79_add_sys_clkdev("cpu", cpu_rate); + clks[1] = ath79_add_sys_clkdev("ddr", ddr_rate); + clks[2] = ath79_add_sys_cl
[PATCH 08/14] MIPS: ath79: Use the common clk API
Make the code simpler and open the way for device tree clocks. Signed-off-by: Alban Bedel --- arch/mips/Kconfig | 1 + arch/mips/ath79/clock.c | 29 ++--- 2 files changed, 3 insertions(+), 27 deletions(-) diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 1fa7f2f..a7b8ef4 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -120,6 +120,7 @@ config ATH79 select CSRC_R4K select DMA_NONCOHERENT select HAVE_CLK + select COMMON_CLK select CLKDEV_LOOKUP select IRQ_CPU select MIPS_MACHINE diff --git a/arch/mips/ath79/clock.c b/arch/mips/ath79/clock.c index 226ddf0..1fcb691 100644 --- a/arch/mips/ath79/clock.c +++ b/arch/mips/ath79/clock.c @@ -17,6 +17,7 @@ #include #include #include +#include #include @@ -28,21 +29,15 @@ #define AR724X_BASE_FREQ 500 #define AR913X_BASE_FREQ 500 -struct clk { - unsigned long rate; -}; - static void __init ath79_add_sys_clkdev(const char *id, unsigned long rate) { struct clk *clk; int err; - clk = kzalloc(sizeof(*clk), GFP_KERNEL); + clk = clk_register_fixed_rate(NULL, id, NULL, CLK_IS_ROOT, rate); if (!clk) panic("failed to allocate %s clock structure", id); - clk->rate = rate; - err = clk_register_clkdev(clk, id, NULL); if (err) panic("unable to register %s clock device", id); @@ -468,23 +463,3 @@ ath79_get_sys_clk_rate(const char *id) return rate; } - -/* - * Linux clock API - */ -int clk_enable(struct clk *clk) -{ - return 0; -} -EXPORT_SYMBOL(clk_enable); - -void clk_disable(struct clk *clk) -{ -} -EXPORT_SYMBOL(clk_disable); - -unsigned long clk_get_rate(struct clk *clk) -{ - return clk->rate; -} -EXPORT_SYMBOL(clk_get_rate); -- 2.0.0 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 02/14] MIPS: ath79: Add basic device tree support
Add the bare minimum to load a device tree. Signed-off-by: Alban Bedel --- arch/mips/Kconfig | 1 + arch/mips/ath79/Kconfig | 10 ++ arch/mips/ath79/machtypes.h | 1 + arch/mips/ath79/setup.c | 27 ++- 4 files changed, 38 insertions(+), 1 deletion(-) diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index cc7f262..1fa7f2f 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -129,6 +129,7 @@ config ATH79 select SYS_SUPPORTS_BIG_ENDIAN select SYS_SUPPORTS_MIPS16 select SYS_SUPPORTS_ZBOOT + select USE_OF help Support for the Atheros AR71XX/AR724X/AR913X SoCs. diff --git a/arch/mips/ath79/Kconfig b/arch/mips/ath79/Kconfig index dfc6020..1d38c6a 100644 --- a/arch/mips/ath79/Kconfig +++ b/arch/mips/ath79/Kconfig @@ -71,6 +71,16 @@ config ATH79_MACH_UBNT_XM Say 'Y' here if you want your kernel to support the Ubiquiti Networks XM (rev 1.0) board. +choice + prompt "Builtin devicetree selection" + default DTB_ATH79_NONE + help + Select the devicetree. + + config DTB_ATH79_NONE + bool "None" +endchoice + endmenu config SOC_AR71XX diff --git a/arch/mips/ath79/machtypes.h b/arch/mips/ath79/machtypes.h index 2625405..a13db3d 100644 --- a/arch/mips/ath79/machtypes.h +++ b/arch/mips/ath79/machtypes.h @@ -15,6 +15,7 @@ #include enum ath79_mach_type { + ATH79_MACH_GENERIC_OF = -1, /* Device tree board */ ATH79_MACH_GENERIC = 0, ATH79_MACH_AP121, /* Atheros AP121 reference board */ ATH79_MACH_AP136_010, /* Atheros AP136-010 reference board */ diff --git a/arch/mips/ath79/setup.c b/arch/mips/ath79/setup.c index 74f1af7..01a644f 100644 --- a/arch/mips/ath79/setup.c +++ b/arch/mips/ath79/setup.c @@ -17,12 +17,16 @@ #include #include #include +#include +#include #include #include #include /* for mips_hpt_frequency */ #include /* for _machine_{restart,halt} */ #include +#include +#include #include #include @@ -194,8 +198,19 @@ unsigned int get_c0_compare_int(void) void __init plat_mem_setup(void) { + unsigned long fdt_start; + set_io_port_base(KSEG1); + /* Get the position of the FDT passed by the bootloader */ + fdt_start = fw_getenvl("fdt_start"); + if (fdt_start) + __dt_setup_arch((void *)KSEG0ADDR(fdt_start)); +#ifdef CONFIG_BUILTIN_DTB + else + __dt_setup_arch(__dtb_start); +#endif + ath79_reset_base = ioremap_nocache(AR71XX_RESET_BASE, AR71XX_RESET_SIZE); ath79_pll_base = ioremap_nocache(AR71XX_PLL_BASE, @@ -203,7 +218,8 @@ void __init plat_mem_setup(void) ath79_ddr_ctrl_init(); ath79_detect_sys_type(); - detect_memory_region(0, ATH79_MEM_SIZE_MIN, ATH79_MEM_SIZE_MAX); + if (mips_machtype != ATH79_MACH_GENERIC_OF) + detect_memory_region(0, ATH79_MEM_SIZE_MIN, ATH79_MEM_SIZE_MAX); _machine_restart = ath79_restart; _machine_halt = ath79_halt; @@ -235,6 +251,10 @@ void __init plat_time_init(void) static int __init ath79_setup(void) { + of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); + if (mips_machtype == ATH79_MACH_GENERIC_OF) + return 0; + ath79_gpio_init(); ath79_register_uart(); ath79_register_wdt(); @@ -246,6 +266,11 @@ static int __init ath79_setup(void) arch_initcall(ath79_setup); +void __init device_tree_init(void) +{ + unflatten_and_copy_device_tree(); +} + static void __init ath79_generic_init(void) { /* Nothing to do */ -- 2.0.0 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 03/14] devicetree: Add bindings for the ATH79 DDR controllers
The DDR controller of the ARxxx and AR9xxx famillies provides an interface to flush the FIFO between various devices and the DDR. This is mainly used by the IRQ controller to flush the FIFO before running the interrupt handler of such devices. Signed-off-by: Alban Bedel --- .../memory-controllers/ath79-ddr-controller.txt| 35 ++ 1 file changed, 35 insertions(+) create mode 100644 Documentation/devicetree/bindings/memory-controllers/ath79-ddr-controller.txt diff --git a/Documentation/devicetree/bindings/memory-controllers/ath79-ddr-controller.txt b/Documentation/devicetree/bindings/memory-controllers/ath79-ddr-controller.txt new file mode 100644 index 000..5541eed --- /dev/null +++ b/Documentation/devicetree/bindings/memory-controllers/ath79-ddr-controller.txt @@ -0,0 +1,35 @@ +Binding for Qualcomm Atheros AR7xxx/AR9xxx DDR controller + +The DDR controller of the ARxxx and AR9xxx famillies provides an interface +to flush the FIFO between various devices and the DDR. This is mainly used +by the IRQ controller to flush the FIFO before running the interrupt handler +of such devices. + +Required properties: + +- compatible: has to be "qca,-ddr-controller", + "qca,[ar7100|ar7240]-ddr-controller" as fallback. + On SoC with PCI support "qca,ar7100-ddr-controller" should be used as + fallback, otherwise "qca,ar7240-ddr-controller" should be used. +- reg: Base address and size of the controllers memory area +- #qca,ddr-wb-channel-cells: has to be 1, the index of the write buffer + channel + +Example: + + ddr_ctrl: ddr-controller@1800 { + compatible = "qca,ar9132-ddr-controller", + "qca,ar7240-ddr-controller"; + reg = <0x1800 0x100>; + + #qca,ddr-wb-channel-cells = <1>; + }; + + ... + + cpuintc@0 { + ... + qca,ddr-wb-channel-interrupts = <2>, <3>, <4>, <5>; + qca,ddr-wb-channels = <&ddr_ctrl 3>, <&ddr_ctrl 2>, + <&ddr_ctrl 0>, <&ddr_ctrl 1>; + }; -- 2.0.0 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 07/14] devicetree: Add bindings for the ATH79 PLL controllers
Signed-off-by: Alban Bedel --- .../devicetree/bindings/clock/qca,ath79-pll.txt| 33 ++ 1 file changed, 33 insertions(+) create mode 100644 Documentation/devicetree/bindings/clock/qca,ath79-pll.txt diff --git a/Documentation/devicetree/bindings/clock/qca,ath79-pll.txt b/Documentation/devicetree/bindings/clock/qca,ath79-pll.txt new file mode 100644 index 000..2d2da3f --- /dev/null +++ b/Documentation/devicetree/bindings/clock/qca,ath79-pll.txt @@ -0,0 +1,33 @@ +Binding for Qualcomm Atheros AR7xxx/AR9XXX PLL controller + +The PPL controller provides the 3 main clocks of the SoC: CPU, DDR and AHB. + +Required Properties: +- compatible: has to be "qca,-cpu-intc" and one of the following + fallback: + - "qca,ar7100-pll" + - "qca,ar7240-pll" + - "qca,ar9130-pll" + - "qca,ar9330-pll" + - "qca,ar9340-pll" + - "qca,ar9550-pll" +- reg: Base address and size of the controllers memory area +- clock-names: Name of the input clock, has to be "ref" +- clock: phandle of the external reference clock +- #clock-cells: has to be one + +Optional properties: +- clock-output-names: should be "cpu", "ddr", "ahb" + +Example: + + pll-controller@1805 { + compatible = "qca,ar9132-ppl", "qca,ar9130-pll"; + reg = <0x1805 0x20>; + + clock-names = "ref"; + clocks = <&extosc>; + + #clock-cells = <1>; + clock-output-names = "cpu", "ddr", "ahb"; + }; -- 2.0.0 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 05/14] devicetree: Add bindings for the ATH79 MISC interrupt controllers
Signed-off-by: Alban Bedel --- .../interrupt-controller/qca,ath79-misc-intc.txt | 30 ++ 1 file changed, 30 insertions(+) create mode 100644 Documentation/devicetree/bindings/interrupt-controller/qca,ath79-misc-intc.txt diff --git a/Documentation/devicetree/bindings/interrupt-controller/qca,ath79-misc-intc.txt b/Documentation/devicetree/bindings/interrupt-controller/qca,ath79-misc-intc.txt new file mode 100644 index 000..11b54dd --- /dev/null +++ b/Documentation/devicetree/bindings/interrupt-controller/qca,ath79-misc-intc.txt @@ -0,0 +1,30 @@ +Binding for Qualcomm Atheros AR7xxx/AR9XXX MISC interrupt controller + +The MISC interrupt controller is a secondary controller for lower priority +interrupt. + +Required Properties: +- compatible: has to be "qca,-cpu-intc", "qca,ar7100-misc-intc" + as fallback +- reg: Base address and size of the controllers memory area +- interrupt-parent: phandle of the parent interrupt controller. +- interrupts: Interrupt specifier for the controllers interrupt. +- interrupt-controller : Identifies the node as an interrupt controller +- #interrupt-cells : Specifies the number of cells needed to encode interrupt +source, should be 1 + +Please refer to interrupts.txt in this directory for details of the common +Interrupt Controllers bindings used by client devices. + +Example: + + miscintc@18060010 { + compatible = "qca,ar9132-misc-intc", qca,ar7100-misc-intc"; + reg = <0x18060010 0x4>; + + interrupt-parent = <&cpuintc>; + interrupts = <6>; + + interrupt-controller; + #interrupt-cells = <1>; + }; -- 2.0.0 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 10/14] devicetree: Add bindings for the ATH79 GPIO controllers
These bindings support the GPIO controllers found on the Qualcomm Atheros AR7xxx/AR9XXX SoC. Signed-off-by: Alban Bedel --- .../devicetree/bindings/gpio/gpio-ath79.txt| 40 ++ 1 file changed, 40 insertions(+) create mode 100644 Documentation/devicetree/bindings/gpio/gpio-ath79.txt diff --git a/Documentation/devicetree/bindings/gpio/gpio-ath79.txt b/Documentation/devicetree/bindings/gpio/gpio-ath79.txt new file mode 100644 index 000..663c0b6 --- /dev/null +++ b/Documentation/devicetree/bindings/gpio/gpio-ath79.txt @@ -0,0 +1,40 @@ +Binding for Qualcomm Atheros AR7xxx/AR9xxx GPIO controller + +Required properties: +- compatible: has to be "qca,-gpio" and one of the following + fallback: + - "qca,ar7100-gpio" + - "qca,ar7240-gpio" + - "qca,ar7241-gpio" + - "qca,ar9130-gpio" + - "qca,ar9330-gpio" + - "qca,ar9340-gpio" + - "qca,qca9550-gpio" +- reg: Base address and size of the controllers memory area +- gpio-controller : Marks the device node as a GPIO controller. +- #gpio-cells : Should be two. The first cell is the pin number and the + second cell is used to specify optional parameters. + +Optional properties: +- interrupt-parent: phandle of the parent interrupt controller. +- interrupts: Interrupt specifier for the controllers interrupt. +- interrupt-controller : Identifies the node as an interrupt controller +- #interrupt-cells : Specifies the number of cells needed to encode interrupt +source, should be 2 + +Please refer to interrupts.txt in this directory for details of the common +Interrupt Controllers bindings used by client devices. + +Example: + + gpio@1804 { + compatible = "qca,ar9132-gpio", "qca,ar9130-gpio"; + reg = <0x1804 0x30>; + interrupts = <2>; + + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; -- 2.0.0 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 06/14] MIPS: ath79: Add OF support to the IRQ controllers
Add OF support for the CPU and MISC interrupt controllers of most supported ATH79 devices. Signed-off-by: Alban Bedel --- arch/mips/ath79/irq.c | 87 ++- 1 file changed, 86 insertions(+), 1 deletion(-) diff --git a/arch/mips/ath79/irq.c b/arch/mips/ath79/irq.c index 2c3991a..afb0096 100644 --- a/arch/mips/ath79/irq.c +++ b/arch/mips/ath79/irq.c @@ -15,7 +15,9 @@ #include #include #include -#include +#include +#include +#include "../../../drivers/irqchip/irqchip.h" #include #include @@ -23,6 +25,7 @@ #include #include #include "common.h" +#include "machtypes.h" static void ath79_misc_irq_handler(unsigned int irq, struct irq_desc *desc) { @@ -268,8 +271,90 @@ asmlinkage void plat_irq_dispatch(void) } } +#ifdef CONFIG_IRQCHIP +static int misc_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hw) +{ + irq_set_chip_and_handler(irq, &ath79_misc_irq_chip, handle_level_irq); + return 0; +} + +static const struct irq_domain_ops misc_irq_domain_ops = { + .xlate = irq_domain_xlate_onecell, + .map = misc_map, +}; + +static int __init ath79_misc_intc_of_init( + struct device_node *node, struct device_node *parent) +{ + void __iomem *base = ath79_reset_base; + struct irq_domain *domain; + int irq; + + irq = irq_of_parse_and_map(node, 0); + if (!irq) + panic("Failed to get MISC IRQ"); + + domain = irq_domain_add_legacy(node, ATH79_MISC_IRQ_COUNT, + ATH79_MISC_IRQ_BASE, 0, &misc_irq_domain_ops, NULL); + if (!domain) + panic("Failed to add MISC irqdomain"); + + /* Disable and clear all interrupts */ + __raw_writel(0, base + AR71XX_RESET_REG_MISC_INT_ENABLE); + __raw_writel(0, base + AR71XX_RESET_REG_MISC_INT_STATUS); + + + irq_set_chained_handler(irq, ath79_misc_irq_handler); + + return 0; +} +IRQCHIP_DECLARE(ath79_misc_intc, "qca,ar7100-misc-intc", + ath79_misc_intc_of_init); + +static int __init ar79_cpu_intc_of_init( + struct device_node *node, struct device_node *parent) +{ + int err, i, count; + + /* Fill the irq_wb_chan table */ + count = of_count_phandle_with_args( + node, "qca,ddr-wb-channels", "#qca,ddr-wb-channel-cells"); + + for (i = 0; i < count; i++) { + struct of_phandle_args args; + u32 irq = i; + + of_property_read_u32_index( + node, "qca,ddr-wb-channel-interrupts", i, &irq); + if (irq >= ARRAY_SIZE(irq_wb_chan)) + continue; + + err = of_parse_phandle_with_args( + node, "qca,ddr-wb-channels", + "#qca,ddr-wb-channel-cells", + i, &args); + if (err) + return err; + + irq_wb_chan[irq] = args.args[0]; + pr_info("IRQ: Set flush channel of IRQ%d to %d\n", + irq, args.args[0]); + } + + return mips_cpu_irq_of_init(node, parent); +} +IRQCHIP_DECLARE(ar79_cpu_intc, "qca,ar7100-cpu-intc", + ar79_cpu_intc_of_init); + +#endif + void __init arch_init_irq(void) { + if (mips_machtype == ATH79_MACH_GENERIC_OF) { + irqchip_init(); + return; + } + if (soc_is_ar71xx() || soc_is_ar724x() || soc_is_ar913x() || soc_is_ar933x()) { irq_wb_chan[2] = 3; -- 2.0.0 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 12/14] MIPS: Add a basic dtsi for the AR9132
A basic dtsi for the AR9132 with support for the DDR controller, CPU and MISC interrupt controller, GPIO controller, the UART and the watchdog. Signed-off-by: Alban Bedel --- arch/mips/boot/dts/ar9132.dtsi | 119 + 1 file changed, 119 insertions(+) create mode 100644 arch/mips/boot/dts/ar9132.dtsi diff --git a/arch/mips/boot/dts/ar9132.dtsi b/arch/mips/boot/dts/ar9132.dtsi new file mode 100644 index 000..ede58cd --- /dev/null +++ b/arch/mips/boot/dts/ar9132.dtsi @@ -0,0 +1,119 @@ +/ { + compatible = "qca,ar9132"; + + #address-cells = <1>; + #size-cells = <1>; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu@0 { + device_type = "cpu"; + compatible = "mips,mips24Kc"; + reg = <0>; + }; + }; + + cpuintc: cpuintc { + compatible = "qca,ar9132-cpu-intc", "qca,ar7100-cpu-intc"; + + interrupt-controller; + #interrupt-cells = <1>; + + qca,ddr-wb-channel-interrupts = <2>, <3>, <4>, <5>; + qca,ddr-wb-channels = <&ddr_ctrl 3>, <&ddr_ctrl 2>, + <&ddr_ctrl 0>, <&ddr_ctrl 1>; + }; + + ahb { + compatible = "simple-bus"; + ranges; + + #address-cells = <1>; + #size-cells = <1>; + + interrupt-parent = <&cpuintc>; + + apb { + compatible = "simple-bus"; + ranges; + + #address-cells = <1>; + #size-cells = <1>; + + interrupt-parent = <&miscintc>; + + ddr_ctrl: ddr-controller@1800 { + compatible = "qca,ar9132-ddr-controller", + "qca,ar7240-ddr-controller"; + reg = <0x1800 0x100>; + + #qca,ddr-wb-channel-cells = <1>; + }; + + uart@1802 { + compatible = "ns8250"; + reg = <0x1802 0x20>; + interrupts = <3>; + + clocks = <&pll 2>; + clock-names = "uart"; + + reg-io-width = <4>; + reg-shift = <2>; + no-loopback-test; + + status = "disabled"; + }; + + gpio: gpio@1804 { + compatible = "qca,ar9132-gpio", + "qca,ar9130-gpio"; + reg = <0x1804 0x30>; + interrupts = <2>; + + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + pll: pll-controller@1805 { + compatible = "qca,ar9132-ppl", + "qca,ar9130-pll"; + reg = <0x1805 0x20>; + + clock-names = "ref"; + /* The board must provides the ref clock */ + + #clock-cells = <1>; + clock-output-names = "cpu", "ddr", "ahb"; + }; + + wdt@18060008 { + compatible = "qca,ar7130-wdt"; + reg = <0x18060008 0x8>; + + interrupts = <4>; + + clocks = <&pll 2>; + clock-names = "wdt"; + }; + + miscintc: miscintc@18060010 { + compatible = "qca,ar9132-misc-intc", + qca,ar7100-misc-intc"; + reg = <0x18060010 0x4>; + + interrupt-parent = <&cpuintc>; + interrupts = <6>; + + interrupt-controller; + #interrupt-cells = <1>; + }; + + }; + }; +}; -- 2.0.0 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 14/14] MIPS: Add basic support for the TL-WR1043ND version 1
Add a DTS for TL-WR1043ND version 1 and allow to have it built in the kernel to circumvent the broken u-boot found on these boards. Currently only the UART, LEDs and buttons are supported. Signed-off-by: Alban Bedel --- arch/mips/ath79/Kconfig | 5 ++ arch/mips/boot/dts/Makefile | 1 + arch/mips/boot/dts/ar9132_tl_wr1043nd_v1.dts | 83 3 files changed, 89 insertions(+) create mode 100644 arch/mips/boot/dts/ar9132_tl_wr1043nd_v1.dts diff --git a/arch/mips/ath79/Kconfig b/arch/mips/ath79/Kconfig index 1d38c6a..0df05d0 100644 --- a/arch/mips/ath79/Kconfig +++ b/arch/mips/ath79/Kconfig @@ -79,6 +79,11 @@ choice config DTB_ATH79_NONE bool "None" + + config DTB_TL_WR1043ND_V1 + bool "TL-WR1043ND Version 1" + select BUILTIN_DTB + select SOC_AR913X endchoice endmenu diff --git a/arch/mips/boot/dts/Makefile b/arch/mips/boot/dts/Makefile index 4f49fa4..d40aae2 100644 --- a/arch/mips/boot/dts/Makefile +++ b/arch/mips/boot/dts/Makefile @@ -10,6 +10,7 @@ dtb-$(CONFIG_DTB_RT305X_EVAL) += rt3052_eval.dtb dtb-$(CONFIG_DTB_RT3883_EVAL) += rt3883_eval.dtb dtb-$(CONFIG_DTB_MT7620A_EVAL) += mt7620a_eval.dtb dtb-$(CONFIG_MIPS_SEAD3) += sead3.dtb +dtb-$(CONFIG_DTB_TL_WR1043ND_V1) += ar9132_tl_wr1043nd.dtb obj-y += $(patsubst %.dtb, %.dtb.o, $(dtb-y)) diff --git a/arch/mips/boot/dts/ar9132_tl_wr1043nd_v1.dts b/arch/mips/boot/dts/ar9132_tl_wr1043nd_v1.dts new file mode 100644 index 000..ab36c7c --- /dev/null +++ b/arch/mips/boot/dts/ar9132_tl_wr1043nd_v1.dts @@ -0,0 +1,83 @@ +/dts-v1/; + +#include +#include + +#include "ar9132.dtsi" + +/ { + compatible = "tplink,tl-wr1043nd-v1", "qca,ar9132"; + model = "TP-Link TL-WR1043ND Version 1"; + + alias { + serial0 = "/ahb/apb/uart@1802"; + }; + + memory@0 { + device_type = "memory"; + reg = <0x0 0x200>; + }; + + extosc: oscillator { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <4000>; + }; + + ahb { + apb { + uart@1802 { + status = "okay"; + }; + + pll-controller@1805 { + clocks = <&extosc>; + }; + }; + }; + + gpio-keys { + compatible = "gpio-keys-polled"; + #address-cells = <1>; + #size-cells = <0>; + + poll-interval = <20>; + button@0 { + label = "reset"; + linux,code = ; + gpios = <&gpio 3 GPIO_ACTIVE_LOW>; + debounce-interval = <60>; + }; + + button@1 { + label = "qss"; + linux,code = ; + gpios = <&gpio 7 GPIO_ACTIVE_LOW>; + debounce-interval = <60>; + }; + }; + + leds { + compatible = "gpio-leds"; + led@0 { + label = "tp-link:green:usb"; + gpios = <&gpio 1 GPIO_ACTIVE_LOW>; + }; + + led@1 { + label = "tp-link:green:system"; + gpios = <&gpio 2 GPIO_ACTIVE_LOW>; + linux,default-trigger = "heartbeat"; + }; + + led@2 { + label = "tp-link:green:qss"; + gpios = <&gpio 5 GPIO_ACTIVE_HIGH>; + }; + + led@3 { + label = "tp-link:green:wlan"; + gpios = <&gpio 9 GPIO_ACTIVE_LOW>; + }; + }; +}; -- 2.0.0 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 13/14] of: Add vendor prefix for TP-Link Technologies Co. Ltd
Signed-off-by: Alban Bedel --- Documentation/devicetree/bindings/vendor-prefixes.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt index b13aa55..9e965b6 100644 --- a/Documentation/devicetree/bindings/vendor-prefixes.txt +++ b/Documentation/devicetree/bindings/vendor-prefixes.txt @@ -185,6 +185,7 @@ tbs TBS Technologies thine THine Electronics, Inc. ti Texas Instruments tlmTrusted Logic Mobility +tplink TP-LINK Technologies Co., Ltd. toradexToradex AG toshibaToshiba Corporation toumaz Toumaz -- 2.0.0 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v2 0/5] MIPS: ath79: Various small fix to prepare OF support
First re-run of this serie of misc fix and preparation for OF support on ATH79. * Dropped the bad PCI patch * Moved the patch to use the common clk API out of the OF support serie into this one. Alban Bedel (5): MIPS: ath79: Enable ZBOOT support MIPS: ath79: Add a missing new line in log message MIPS: ath79: Correctly name the defines for the PLL_FB register MIPS: ath79: Improve the DDR controller interface MIPS: ath79: Use the common clk API arch/mips/Kconfig | 2 + arch/mips/ath79/clock.c| 35 +- arch/mips/ath79/common.c | 35 +- arch/mips/ath79/common.h | 1 + arch/mips/ath79/irq.c | 147 ++--- arch/mips/ath79/setup.c| 5 +- arch/mips/include/asm/mach-ath79/ar71xx_regs.h | 12 +- arch/mips/include/asm/mach-ath79/ath79.h | 3 +- arch/mips/pci/pci-ar71xx.c | 10 +- 9 files changed, 85 insertions(+), 165 deletions(-) -- 2.0.0 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v2 1/5] MIPS: ath79: Enable ZBOOT support
ZBOOT is working fine, so allow using it. Signed-off-by: Alban Bedel --- arch/mips/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index f501665..9075147 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -131,6 +131,7 @@ config ATH79 select SYS_SUPPORTS_32BIT_KERNEL select SYS_SUPPORTS_BIG_ENDIAN select SYS_SUPPORTS_MIPS16 + select SYS_SUPPORTS_ZBOOT help Support for the Atheros AR71XX/AR724X/AR913X SoCs. -- 2.0.0 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v2 5/5] MIPS: ath79: Use the common clk API
Make the code simpler and open the way for device tree clocks. Signed-off-by: Alban Bedel --- arch/mips/Kconfig | 1 + arch/mips/ath79/clock.c | 29 ++--- 2 files changed, 3 insertions(+), 27 deletions(-) diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 9075147..874bbaf 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -123,6 +123,7 @@ config ATH79 select CSRC_R4K select DMA_NONCOHERENT select HAVE_CLK + select COMMON_CLK select CLKDEV_LOOKUP select IRQ_CPU select MIPS_MACHINE diff --git a/arch/mips/ath79/clock.c b/arch/mips/ath79/clock.c index 226ddf0..1fcb691 100644 --- a/arch/mips/ath79/clock.c +++ b/arch/mips/ath79/clock.c @@ -17,6 +17,7 @@ #include #include #include +#include #include @@ -28,21 +29,15 @@ #define AR724X_BASE_FREQ 500 #define AR913X_BASE_FREQ 500 -struct clk { - unsigned long rate; -}; - static void __init ath79_add_sys_clkdev(const char *id, unsigned long rate) { struct clk *clk; int err; - clk = kzalloc(sizeof(*clk), GFP_KERNEL); + clk = clk_register_fixed_rate(NULL, id, NULL, CLK_IS_ROOT, rate); if (!clk) panic("failed to allocate %s clock structure", id); - clk->rate = rate; - err = clk_register_clkdev(clk, id, NULL); if (err) panic("unable to register %s clock device", id); @@ -468,23 +463,3 @@ ath79_get_sys_clk_rate(const char *id) return rate; } - -/* - * Linux clock API - */ -int clk_enable(struct clk *clk) -{ - return 0; -} -EXPORT_SYMBOL(clk_enable); - -void clk_disable(struct clk *clk) -{ -} -EXPORT_SYMBOL(clk_disable); - -unsigned long clk_get_rate(struct clk *clk) -{ - return clk->rate; -} -EXPORT_SYMBOL(clk_get_rate); -- 2.0.0 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v2 3/5] MIPS: ath79: Correctly name the defines for the PLL_FB register
This register is named PLL_FB and is not a divider but a multiplier. To make things less confusing rename the AR_PLL_DIV_SHIFT and AR_PLL_DIV_MASK macros to AR_PLL_FB_SHIFT and AR_PLL_FB_MASK. Signed-off-by: Alban Bedel --- arch/mips/ath79/clock.c| 6 +++--- arch/mips/include/asm/mach-ath79/ar71xx_regs.h | 12 ++-- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/arch/mips/ath79/clock.c b/arch/mips/ath79/clock.c index 26479f4..226ddf0 100644 --- a/arch/mips/ath79/clock.c +++ b/arch/mips/ath79/clock.c @@ -62,7 +62,7 @@ static void __init ar71xx_clocks_init(void) pll = ath79_pll_rr(AR71XX_PLL_REG_CPU_CONFIG); - div = ((pll >> AR71XX_PLL_DIV_SHIFT) & AR71XX_PLL_DIV_MASK) + 1; + div = ((pll >> AR71XX_PLL_FB_SHIFT) & AR71XX_PLL_FB_MASK) + 1; freq = div * ref_rate; div = ((pll >> AR71XX_CPU_DIV_SHIFT) & AR71XX_CPU_DIV_MASK) + 1; @@ -96,7 +96,7 @@ static void __init ar724x_clocks_init(void) ref_rate = AR724X_BASE_FREQ; pll = ath79_pll_rr(AR724X_PLL_REG_CPU_CONFIG); - div = ((pll >> AR724X_PLL_DIV_SHIFT) & AR724X_PLL_DIV_MASK); + div = ((pll >> AR724X_PLL_FB_SHIFT) & AR724X_PLL_FB_MASK); freq = div * ref_rate; div = ((pll >> AR724X_PLL_REF_DIV_SHIFT) & AR724X_PLL_REF_DIV_MASK); @@ -132,7 +132,7 @@ static void __init ar913x_clocks_init(void) ref_rate = AR913X_BASE_FREQ; pll = ath79_pll_rr(AR913X_PLL_REG_CPU_CONFIG); - div = ((pll >> AR913X_PLL_DIV_SHIFT) & AR913X_PLL_DIV_MASK); + div = ((pll >> AR913X_PLL_FB_SHIFT) & AR913X_PLL_FB_MASK); freq = div * ref_rate; cpu_rate = freq; diff --git a/arch/mips/include/asm/mach-ath79/ar71xx_regs.h b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h index cd41e93..aa3800c 100644 --- a/arch/mips/include/asm/mach-ath79/ar71xx_regs.h +++ b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h @@ -157,8 +157,8 @@ #define AR71XX_PLL_REG_ETH0_INT_CLOCK 0x10 #define AR71XX_PLL_REG_ETH1_INT_CLOCK 0x14 -#define AR71XX_PLL_DIV_SHIFT 3 -#define AR71XX_PLL_DIV_MASK0x1f +#define AR71XX_PLL_FB_SHIFT3 +#define AR71XX_PLL_FB_MASK 0x1f #define AR71XX_CPU_DIV_SHIFT 16 #define AR71XX_CPU_DIV_MASK0x3 #define AR71XX_DDR_DIV_SHIFT 18 @@ -169,8 +169,8 @@ #define AR724X_PLL_REG_CPU_CONFIG 0x00 #define AR724X_PLL_REG_PCIE_CONFIG 0x18 -#define AR724X_PLL_DIV_SHIFT 0 -#define AR724X_PLL_DIV_MASK0x3ff +#define AR724X_PLL_FB_SHIFT0 +#define AR724X_PLL_FB_MASK 0x3ff #define AR724X_PLL_REF_DIV_SHIFT 10 #define AR724X_PLL_REF_DIV_MASK0xf #define AR724X_AHB_DIV_SHIFT 19 @@ -183,8 +183,8 @@ #define AR913X_PLL_REG_ETH0_INT_CLOCK 0x14 #define AR913X_PLL_REG_ETH1_INT_CLOCK 0x18 -#define AR913X_PLL_DIV_SHIFT 0 -#define AR913X_PLL_DIV_MASK0x3ff +#define AR913X_PLL_FB_SHIFT0 +#define AR913X_PLL_FB_MASK 0x3ff #define AR913X_DDR_DIV_SHIFT 22 #define AR913X_DDR_DIV_MASK0x3 #define AR913X_AHB_DIV_SHIFT 19 -- 2.0.0 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v2 4/5] MIPS: ath79: Improve the DDR controller interface
The DDR controller need to be used by the IRQ controller to flush the write buffer of some devices before running the IRQ handler. It is also used by the PCI controller to setup the PCI memory windows. The current interface used to access the DDR controller doesn't provides any useful abstraction and simply rely on a shared global pointer. Replace this by a simple API to setup the PCI memory windows and use the write buffer flush independently of the SoC type. That remove the need for the shared global pointer, simplify the IRQ handler code. Signed-off-by: Alban Bedel --- v2: * Updated ath79_ddr_set_pci_windows() after dropping the buggy PCI "fix" patch. --- arch/mips/ath79/common.c | 35 +++- arch/mips/ath79/common.h | 1 + arch/mips/ath79/irq.c| 147 +++ arch/mips/ath79/setup.c | 3 +- arch/mips/include/asm/mach-ath79/ath79.h | 3 +- arch/mips/pci/pci-ar71xx.c | 10 +-- 6 files changed, 71 insertions(+), 128 deletions(-) diff --git a/arch/mips/ath79/common.c b/arch/mips/ath79/common.c index eb3966c..3cedd1f 100644 --- a/arch/mips/ath79/common.c +++ b/arch/mips/ath79/common.c @@ -38,11 +38,27 @@ unsigned int ath79_soc_rev; void __iomem *ath79_pll_base; void __iomem *ath79_reset_base; EXPORT_SYMBOL_GPL(ath79_reset_base); -void __iomem *ath79_ddr_base; +static void __iomem *ath79_ddr_base; +static void __iomem *ath79_ddr_wb_flush_base; +static void __iomem *ath79_ddr_pci_win_base; + +void ath79_ddr_ctrl_init(void) +{ + ath79_ddr_base = ioremap_nocache(AR71XX_DDR_CTRL_BASE, +AR71XX_DDR_CTRL_SIZE); + if (soc_is_ar71xx() || soc_is_ar934x()) { + ath79_ddr_wb_flush_base = ath79_ddr_base + 0x9c; + ath79_ddr_pci_win_base = ath79_ddr_base + 0x7c; + } else { + ath79_ddr_wb_flush_base = ath79_ddr_base + 0x7c; + ath79_ddr_pci_win_base = 0; + } +} +EXPORT_SYMBOL_GPL(ath79_ddr_ctrl_init); void ath79_ddr_wb_flush(u32 reg) { - void __iomem *flush_reg = ath79_ddr_base + reg; + void __iomem *flush_reg = ath79_ddr_wb_flush_base + reg; /* Flush the DDR write buffer. */ __raw_writel(0x1, flush_reg); @@ -56,6 +72,21 @@ void ath79_ddr_wb_flush(u32 reg) } EXPORT_SYMBOL_GPL(ath79_ddr_wb_flush); +void ath79_ddr_set_pci_windows(void) +{ + BUG_ON(!ath79_ddr_pci_win_base); + + __raw_writel(AR71XX_PCI_WIN0_OFFS, ath79_ddr_pci_win_base + 0); + __raw_writel(AR71XX_PCI_WIN1_OFFS, ath79_ddr_pci_win_base + 1); + __raw_writel(AR71XX_PCI_WIN2_OFFS, ath79_ddr_pci_win_base + 2); + __raw_writel(AR71XX_PCI_WIN3_OFFS, ath79_ddr_pci_win_base + 3); + __raw_writel(AR71XX_PCI_WIN4_OFFS, ath79_ddr_pci_win_base + 4); + __raw_writel(AR71XX_PCI_WIN5_OFFS, ath79_ddr_pci_win_base + 5); + __raw_writel(AR71XX_PCI_WIN6_OFFS, ath79_ddr_pci_win_base + 6); + __raw_writel(AR71XX_PCI_WIN7_OFFS, ath79_ddr_pci_win_base + 7); +} +EXPORT_SYMBOL_GPL(ath79_ddr_set_pci_windows); + void ath79_device_reset_set(u32 mask) { unsigned long flags; diff --git a/arch/mips/ath79/common.h b/arch/mips/ath79/common.h index c39de61..e5ea712 100644 --- a/arch/mips/ath79/common.h +++ b/arch/mips/ath79/common.h @@ -22,6 +22,7 @@ void ath79_clocks_init(void); unsigned long ath79_get_sys_clk_rate(const char *id); +void ath79_ddr_ctrl_init(void); void ath79_ddr_wb_flush(unsigned int reg); void ath79_gpio_function_enable(u32 mask); diff --git a/arch/mips/ath79/irq.c b/arch/mips/ath79/irq.c index 6adae36..2c3991a 100644 --- a/arch/mips/ath79/irq.c +++ b/arch/mips/ath79/irq.c @@ -24,9 +24,6 @@ #include #include "common.h" -static void (*ath79_ip2_handler)(void); -static void (*ath79_ip3_handler)(void); - static void ath79_misc_irq_handler(unsigned int irq, struct irq_desc *desc) { void __iomem *base = ath79_reset_base; @@ -129,10 +126,10 @@ static void ar934x_ip2_irq_dispatch(unsigned int irq, struct irq_desc *desc) status = ath79_reset_rr(AR934X_RESET_REG_PCIE_WMAC_INT_STATUS); if (status & AR934X_PCIE_WMAC_INT_PCIE_ALL) { - ath79_ddr_wb_flush(AR934X_DDR_REG_FLUSH_PCIE); + ath79_ddr_wb_flush(3); generic_handle_irq(ATH79_IP2_IRQ(0)); } else if (status & AR934X_PCIE_WMAC_INT_WMAC_ALL) { - ath79_ddr_wb_flush(AR934X_DDR_REG_FLUSH_WMAC); + ath79_ddr_wb_flush(4); generic_handle_irq(ATH79_IP2_IRQ(1)); } else { spurious_interrupt(); @@ -235,128 +232,50 @@ static void qca955x_irq_init(void) irq_set_chained_handler(ATH79_CPU_IRQ(3), qca955x_ip3_irq_dispatch); } -asmlinkage void plat_irq_dispatch(void) -{ - unsigned long pending; - - pending = read_c0_status() & read_c0_cause() & ST0_IM; - - if (pending & STATUS
[PATCH v2 2/5] MIPS: ath79: Add a missing new line in log message
The memory setup log is missing a new line. Signed-off-by: Alban Bedel --- arch/mips/ath79/setup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/mips/ath79/setup.c b/arch/mips/ath79/setup.c index a73c93c..7fc8397 100644 --- a/arch/mips/ath79/setup.c +++ b/arch/mips/ath79/setup.c @@ -225,7 +225,7 @@ void __init plat_time_init(void) ddr_clk_rate = ath79_get_sys_clk_rate("ddr"); ref_clk_rate = ath79_get_sys_clk_rate("ref"); - pr_info("Clocks: CPU:%lu.%03luMHz, DDR:%lu.%03luMHz, AHB:%lu.%03luMHz, Ref:%lu.%03luMHz", + pr_info("Clocks: CPU:%lu.%03luMHz, DDR:%lu.%03luMHz, AHB:%lu.%03luMHz, Ref:%lu.%03luMHz\n", cpu_clk_rate / 100, (cpu_clk_rate / 1000) % 1000, ddr_clk_rate / 100, (ddr_clk_rate / 1000) % 1000, ahb_clk_rate / 100, (ahb_clk_rate / 1000) % 1000, -- 2.0.0 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v2 00/12] MIPS: ath79: Add OF support and DTS for TL-WR1043ND
This series add OF bindings and code support for the interrupt controllers, clocks and GPIOs. However it was only tested on a TL-WR1043ND with an AR9132, others SoCs are untested, and a few are not supported at all. Most code changes base on the previous bug fix series: [PATCH v2 0/5] MIPS: ath79: Various small fix to prepare OF support The requested patch to move the GPIO driver to drivers/gpio is ready and will follow once it is clearer if this serie get merged. ChangeLog: v2: * Fixed the OF bindings and DTS to use ePAPR standardized names * Fixed the typos in the OF bindings * Added an ngpios property to the GPIO binding and driver * Removed all the soc_is_xxx() calls out of the GPIO driver probe() * Updated the DTS patches to the new directory structure and merged both in one. Having 3 patches to add Makefile, SoC dtsi and board DTS seemed a bit overkill. * Moved the patch to use the common clk API to the bug fix serie to keep this one cleaner. Alban Bedel (12): devicetree: Add bindings for the SoC of the ATH79 familly MIPS: ath79: Add basic device tree support devicetree: Add bindings for the ATH79 DDR controllers devicetree: Add bindings for the ATH79 interrupt controllers devicetree: Add bindings for the ATH79 MISC interrupt controllers MIPS: ath79: Add OF support to the IRQ controllers devicetree: Add bindings for the ATH79 PLL controllers MIPS: ath79: Add OF support to the clocks devicetree: Add bindings for the ATH79 GPIO controllers MIPS: ath79: Add OF support to the GPIO driver of: Add vendor prefix for TP-Link Technologies Co. Ltd MIPS: Add basic support for the TL-WR1043ND version 1 .../devicetree/bindings/clock/qca,ath79-pll.txt| 33 ++ .../devicetree/bindings/gpio/gpio-ath79.txt| 38 +++ .../interrupt-controller/qca,ath79-cpu-intc.txt| 44 .../interrupt-controller/qca,ath79-misc-intc.txt | 30 + .../memory-controllers/ath79-ddr-controller.txt| 35 ++ .../devicetree/bindings/mips/ath79-soc.txt | 21 .../devicetree/bindings/vendor-prefixes.txt| 1 + arch/mips/Kconfig | 1 + arch/mips/ath79/Kconfig| 15 +++ arch/mips/ath79/clock.c| 63 +++ arch/mips/ath79/dev-common.c | 51 + arch/mips/ath79/gpio.c | 79 ++ arch/mips/ath79/irq.c | 87 ++- arch/mips/ath79/machtypes.h| 1 + arch/mips/ath79/setup.c| 27 - arch/mips/boot/dts/Makefile| 1 + arch/mips/boot/dts/qca/Makefile| 9 ++ arch/mips/boot/dts/qca/ar9132.dtsi | 121 + arch/mips/boot/dts/qca/ar9132_tl_wr1043nd_v1.dts | 83 ++ include/linux/platform_data/gpio-ath79.h | 19 20 files changed, 716 insertions(+), 43 deletions(-) create mode 100644 Documentation/devicetree/bindings/clock/qca,ath79-pll.txt create mode 100644 Documentation/devicetree/bindings/gpio/gpio-ath79.txt create mode 100644 Documentation/devicetree/bindings/interrupt-controller/qca,ath79-cpu-intc.txt create mode 100644 Documentation/devicetree/bindings/interrupt-controller/qca,ath79-misc-intc.txt create mode 100644 Documentation/devicetree/bindings/memory-controllers/ath79-ddr-controller.txt create mode 100644 Documentation/devicetree/bindings/mips/ath79-soc.txt create mode 100644 arch/mips/boot/dts/qca/Makefile create mode 100644 arch/mips/boot/dts/qca/ar9132.dtsi create mode 100644 arch/mips/boot/dts/qca/ar9132_tl_wr1043nd_v1.dts create mode 100644 include/linux/platform_data/gpio-ath79.h -- 2.0.0 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v2 02/12] MIPS: ath79: Add basic device tree support
Add the bare minimum to load a device tree. Signed-off-by: Alban Bedel --- arch/mips/Kconfig | 1 + arch/mips/ath79/Kconfig | 10 ++ arch/mips/ath79/machtypes.h | 1 + arch/mips/ath79/setup.c | 27 ++- 4 files changed, 38 insertions(+), 1 deletion(-) diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 874bbaf..772312d 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -133,6 +133,7 @@ config ATH79 select SYS_SUPPORTS_BIG_ENDIAN select SYS_SUPPORTS_MIPS16 select SYS_SUPPORTS_ZBOOT + select USE_OF help Support for the Atheros AR71XX/AR724X/AR913X SoCs. diff --git a/arch/mips/ath79/Kconfig b/arch/mips/ath79/Kconfig index dfc6020..1d38c6a 100644 --- a/arch/mips/ath79/Kconfig +++ b/arch/mips/ath79/Kconfig @@ -71,6 +71,16 @@ config ATH79_MACH_UBNT_XM Say 'Y' here if you want your kernel to support the Ubiquiti Networks XM (rev 1.0) board. +choice + prompt "Builtin devicetree selection" + default DTB_ATH79_NONE + help + Select the devicetree. + + config DTB_ATH79_NONE + bool "None" +endchoice + endmenu config SOC_AR71XX diff --git a/arch/mips/ath79/machtypes.h b/arch/mips/ath79/machtypes.h index 2625405..a13db3d 100644 --- a/arch/mips/ath79/machtypes.h +++ b/arch/mips/ath79/machtypes.h @@ -15,6 +15,7 @@ #include enum ath79_mach_type { + ATH79_MACH_GENERIC_OF = -1, /* Device tree board */ ATH79_MACH_GENERIC = 0, ATH79_MACH_AP121, /* Atheros AP121 reference board */ ATH79_MACH_AP136_010, /* Atheros AP136-010 reference board */ diff --git a/arch/mips/ath79/setup.c b/arch/mips/ath79/setup.c index 74f1af7..01a644f 100644 --- a/arch/mips/ath79/setup.c +++ b/arch/mips/ath79/setup.c @@ -17,12 +17,16 @@ #include #include #include +#include +#include #include #include #include /* for mips_hpt_frequency */ #include /* for _machine_{restart,halt} */ #include +#include +#include #include #include @@ -194,8 +198,19 @@ unsigned int get_c0_compare_int(void) void __init plat_mem_setup(void) { + unsigned long fdt_start; + set_io_port_base(KSEG1); + /* Get the position of the FDT passed by the bootloader */ + fdt_start = fw_getenvl("fdt_start"); + if (fdt_start) + __dt_setup_arch((void *)KSEG0ADDR(fdt_start)); +#ifdef CONFIG_BUILTIN_DTB + else + __dt_setup_arch(__dtb_start); +#endif + ath79_reset_base = ioremap_nocache(AR71XX_RESET_BASE, AR71XX_RESET_SIZE); ath79_pll_base = ioremap_nocache(AR71XX_PLL_BASE, @@ -203,7 +218,8 @@ void __init plat_mem_setup(void) ath79_ddr_ctrl_init(); ath79_detect_sys_type(); - detect_memory_region(0, ATH79_MEM_SIZE_MIN, ATH79_MEM_SIZE_MAX); + if (mips_machtype != ATH79_MACH_GENERIC_OF) + detect_memory_region(0, ATH79_MEM_SIZE_MIN, ATH79_MEM_SIZE_MAX); _machine_restart = ath79_restart; _machine_halt = ath79_halt; @@ -235,6 +251,10 @@ void __init plat_time_init(void) static int __init ath79_setup(void) { + of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); + if (mips_machtype == ATH79_MACH_GENERIC_OF) + return 0; + ath79_gpio_init(); ath79_register_uart(); ath79_register_wdt(); @@ -246,6 +266,11 @@ static int __init ath79_setup(void) arch_initcall(ath79_setup); +void __init device_tree_init(void) +{ + unflatten_and_copy_device_tree(); +} + static void __init ath79_generic_init(void) { /* Nothing to do */ -- 2.0.0 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v2 04/12] devicetree: Add bindings for the ATH79 interrupt controllers
Signed-off-by: Alban Bedel --- v2: * Fixed the node names to respect ePAPR * Removed the unneeded @0 on the node name --- .../interrupt-controller/qca,ath79-cpu-intc.txt| 44 ++ 1 file changed, 44 insertions(+) create mode 100644 Documentation/devicetree/bindings/interrupt-controller/qca,ath79-cpu-intc.txt diff --git a/Documentation/devicetree/bindings/interrupt-controller/qca,ath79-cpu-intc.txt b/Documentation/devicetree/bindings/interrupt-controller/qca,ath79-cpu-intc.txt new file mode 100644 index 000..aabce78 --- /dev/null +++ b/Documentation/devicetree/bindings/interrupt-controller/qca,ath79-cpu-intc.txt @@ -0,0 +1,44 @@ +Binding for Qualcomm Atheros AR7xxx/AR9XXX CPU interrupt controller + +On most SoC the IRQ controller need to flush the DDR FIFO before running +the interrupt handler of some devices. This is configured using the +qca,ddr-wb-channels and qca,ddr-wb-channel-interrupts properties. + +Required Properties: + +- compatible: has to be "qca,-cpu-intc", "qca,ar7100-cpu-intc" + as fallback +- interrupt-controller : Identifies the node as an interrupt controller +- #interrupt-cells : Specifies the number of cells needed to encode interrupt +source, should be 1 for intc + +Please refer to interrupts.txt in this directory for details of the common +Interrupt Controllers bindings used by client devices. + +Optional Properties: + +- qca,ddr-wb-channel-interrupts: List of the interrupts needing a write + buffer flush +- qca,ddr-wb-channels: List of phandles to the write buffer channels for + each interrupt. If qca,ddr-wb-channel-interrupts is not present the interrupt + default to the entry's index. + +Example: + + interrupt-controller { + compatible = "qca,ar9132-cpu-intc", "qca,ar7100-cpu-intc"; + + interrupt-controller; + #interrupt-cells = <1>; + + qca,ddr-wb-channel-interrupts = <2>, <3>, <4>, <5>; + qca,ddr-wb-channels = <&ddr_ctrl 3>, <&ddr_ctrl 2>, + <&ddr_ctrl 0>, <&ddr_ctrl 1>; + }; + + ... + + ddr_ctrl: memory-controller@1800 { + ... + #qca,ddr-wb-channel-cells = <1>; + }; -- 2.0.0 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v2 01/12] devicetree: Add bindings for the SoC of the ATH79 familly
Signed-off-by: Alban Bedel --- .../devicetree/bindings/mips/ath79-soc.txt | 21 + 1 file changed, 21 insertions(+) create mode 100644 Documentation/devicetree/bindings/mips/ath79-soc.txt diff --git a/Documentation/devicetree/bindings/mips/ath79-soc.txt b/Documentation/devicetree/bindings/mips/ath79-soc.txt new file mode 100644 index 000..88a12a4 --- /dev/null +++ b/Documentation/devicetree/bindings/mips/ath79-soc.txt @@ -0,0 +1,21 @@ +Binding for Qualcomm Atheros AR7xxx/AR9XXX SoC + +Each device tree must specify a compatible value for the AR SoC +it uses in the compatible property of the root node. The compatible +value must be one of the following values: + +- qca,ar7130 +- qca,ar7141 +- qca,ar7161 +- qca,ar7240 +- qca,ar7241 +- qca,ar7242 +- qca,ar9130 +- qca,ar9132 +- qca,ar9330 +- qca,ar9331 +- qca,ar9341 +- qca,ar9342 +- qca,ar9344 +- qca,qca9556 +- qca,qca9558 -- 2.0.0 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v2 03/12] devicetree: Add bindings for the ATH79 DDR controllers
The DDR controller of the ARxxx and AR9xxx famillies provides an interface to flush the FIFO between various devices and the DDR. This is mainly used by the IRQ controller to flush the FIFO before running the interrupt handler of such devices. Signed-off-by: Alban Bedel --- v2: * Fix the node names to respect ePAPR --- .../memory-controllers/ath79-ddr-controller.txt| 35 ++ 1 file changed, 35 insertions(+) create mode 100644 Documentation/devicetree/bindings/memory-controllers/ath79-ddr-controller.txt diff --git a/Documentation/devicetree/bindings/memory-controllers/ath79-ddr-controller.txt b/Documentation/devicetree/bindings/memory-controllers/ath79-ddr-controller.txt new file mode 100644 index 000..5541eed --- /dev/null +++ b/Documentation/devicetree/bindings/memory-controllers/ath79-ddr-controller.txt @@ -0,0 +1,35 @@ +Binding for Qualcomm Atheros AR7xxx/AR9xxx DDR controller + +The DDR controller of the ARxxx and AR9xxx famillies provides an interface +to flush the FIFO between various devices and the DDR. This is mainly used +by the IRQ controller to flush the FIFO before running the interrupt handler +of such devices. + +Required properties: + +- compatible: has to be "qca,-ddr-controller", + "qca,[ar7100|ar7240]-ddr-controller" as fallback. + On SoC with PCI support "qca,ar7100-ddr-controller" should be used as + fallback, otherwise "qca,ar7240-ddr-controller" should be used. +- reg: Base address and size of the controllers memory area +- #qca,ddr-wb-channel-cells: has to be 1, the index of the write buffer + channel + +Example: + + ddr_ctrl: ddr-controller@1800 { + compatible = "qca,ar9132-ddr-controller", + "qca,ar7240-ddr-controller"; + reg = <0x1800 0x100>; + + #qca,ddr-wb-channel-cells = <1>; + }; + + ... + + cpuintc@0 { + ... + qca,ddr-wb-channel-interrupts = <2>, <3>, <4>, <5>; + qca,ddr-wb-channels = <&ddr_ctrl 3>, <&ddr_ctrl 2>, + <&ddr_ctrl 0>, <&ddr_ctrl 1>; + }; -- 2.0.0 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/