* Re: [PATCH v15 07/10] USB/ppc4xx: Add Synopsys DWC OTG PCD function
From: Pratyush Anand @ 2011-10-20 9:55 UTC (permalink / raw)
To: tmarri; +Cc: Mark Miesfeld, greg, linux-usb, linuxppc-dev, Fushen Chen
In-Reply-To: <1318630147-14358-1-git-send-email-tmarri@apm.com>
On Sat, Oct 15, 2011 at 3:39 AM, <tmarri@apm.com> wrote:
> From: Tirumala Marri <tmarri@apm.com>
>
> The PCD is responsible for translating requests from the gadget driver
> to appropriate actions on the DWC OTG controller.
>
[...]
> +static int dwc_otg_pcd_ep_disable(struct usb_ep *_ep)
> +{
> + struct pcd_ep *ep;
> + struct core_if *core_if;
> + unsigned long flags;
> +
> + ep = container_of(_ep, struct pcd_ep, ep);
> + if (!_ep || !ep->desc)
> + return -EINVAL;
> +
> + core_if = ep->pcd->otg_dev->core_if;
> +
> + spin_lock_irqsave(&ep->pcd->lock, flags);
> +
> + request_nuke(ep);
> + dwc_otg_ep_deactivate(core_if, &ep->dwc_ep);
> +
> + ep->desc = NULL;
> + ep->stopped = 1;
> + if (ep->dwc_ep.is_in) {
> + release_perio_tx_fifo(core_if, ep->dwc_ep.tx_fifo_num);
> + release_tx_fifo(core_if, ep->dwc_ep.tx_fifo_num);
Is only releasing fifo sufficient?
Will the above procedure insures that EP is disable?
I think not.
To insure that EP is disabled , you need to fllow steps as defines in specs.
Also, Fifo must be flushed completely.
Just a question: Which test have you run to test the driver?
I had tested your v13 with testusb and zero gadget and found that all the IN
test were failing because of this limitation.
> + }
> +
[...]
> +/**
> + * Set the EP STALL.
> + */
> +void dwc_otg_ep_set_stall(struct core_if *core_if, struct dwc_ep *ep)
> +{
> + u32 depctl = 0;
> + ulong depctl_addr;
> +
> + if (ep->is_in) {
> + depctl_addr =
> + (core_if->dev_if->in_ep_regs[ep->num]) + DWC_DIEPCTL;
> + depctl = dwc_reg_read(depctl_addr, 0);
> +
> + /* set the disable and stall bits */
> + if (DWC_DEPCTL_EPENA_RD(depctl))
> + depctl = DWC_DEPCTL_EPDIS_RW(depctl, 1);
> + depctl = DWC_DEPCTL_STALL_HNDSHK_RW(depctl, 1);
> + dwc_reg_write(depctl_addr, 0, depctl);
After stall bit set, you must disable EP.
Also you must clear TX fifo completetly for respective EP.
> + } else {
> + depctl_addr =
> + (core_if->dev_if->out_ep_regs[ep->num] + DWC_DOEPCTL);
> + depctl = dwc_reg_read(depctl_addr, 0);
> +
> + /* set the stall bit */
> + depctl = DWC_DEPCTL_STALL_HNDSHK_RW(depctl, 1);
> + dwc_reg_write(depctl_addr, 0, depctl);
> + }
> +}
Regards
Pratyush
^ permalink raw reply
* Re: [PATCH v15 08/10] USB ppc4xx: Add Synopsys DWC OTG PCD interrupt function
From: Pratyush Anand @ 2011-10-20 10:12 UTC (permalink / raw)
To: tmarri; +Cc: Mark Miesfeld, greg, linux-usb, linuxppc-dev, Fushen Chen
In-Reply-To: <1318630151-14394-1-git-send-email-tmarri@apm.com>
On Sat, Oct 15, 2011 at 3:39 AM, <tmarri@apm.com> wrote:
> From: Tirumala Marri <tmarri@apm.com>
>
[...]
> +static int write_empty_tx_fifo(struct dwc_pcd *pcd, u32 epnum)
> +{
> + struct core_if *core_if = GET_CORE_IF(pcd);
> + ulong regs;
> + u32 txstatus = 0;
> + struct pcd_ep *ep;
> + u32 len;
> + int dwords;
> + u32 diepint = 0;
> +
> + ep = get_in_ep(pcd, epnum);
> + regs = core_if->dev_if->in_ep_regs[epnum];
> + txstatus = dwc_reg_read(regs, DWC_DTXFSTS);
> +
> + /*
> + * While there is space in the queue, space in the FIFO and data to
> + * tranfer, write packets to the Tx FIFO
> + */
> + len = ep->dwc_ep.xfer_len - ep->dwc_ep.xfer_count;
> + dwords = count_dwords(ep, len);
> + while (DWC_DTXFSTS_TXFSSPC_AVAI_RD(txstatus) > dwords
If you use a >= here, it will be more efficient.
Other wise even if you have 512 bytes spece remaining in TXFIFO, you will not be
able to send a 512 byte packet.
> + && ep->dwc_ep.xfer_count < ep->dwc_ep.xfer_len
> + && ep->dwc_ep.xfer_len != 0) {
> + dwc_otg_ep_write_packet(core_if, &ep->dwc_ep, 0);
> + len = ep->dwc_ep.xfer_len - ep->dwc_ep.xfer_count;
> + dwords = count_dwords(ep, len);
> + txstatus = dwc_reg_read(regs, DWC_DTXFSTS);
> + }
> + /* Clear emptyintr */
> + diepint = DWC_DIEPINT_TXFIFO_EMPTY_RW(diepint, 1);
> + dwc_reg_write(in_ep_int_reg(pcd, epnum), 0, diepint);
> + return 1;
> +}
[...]
> +/**
> + * Clear the EP halt (STALL) and if pending requests start the
> + * transfer.
> + */
> +static void pcd_clear_halt(struct dwc_pcd *pcd, struct pcd_ep *ep)
> +{
> + struct core_if *core_if = GET_CORE_IF(pcd);
> +
> + if (!ep->dwc_ep.stall_clear_flag)
> + dwc_otg_ep_clear_stall(core_if, &ep->dwc_ep);
> +
> + /* Reactive the EP */
> + dwc_otg_ep_activate(core_if, &ep->dwc_ep);
> +
> + if (ep->stopped) {
> + ep->stopped = 0;
> + /* If there is a request in the EP queue start it */
> +
> + /*
> + * dwc_start_next_request(), outside of interpt contxt at some
> + * time after the current time, after a clear-halt setup packet.
> + * Still need to implement ep mismatch in the future if a gadget
> + * ever uses more than one endpoint at once
> + */
> + if (core_if->dma_enable) {
> + ep->queue_sof = 1;
> + tasklet_schedule(pcd->start_xfer_tasklet);
> + } else {
> + /*
> + * Added-sr: 2007-07-26
> + *
> + * To re-enable this endpoint it's important to
> + * set this next_ep number. Otherwise the endpoint
> + * will not get active again after stalling.
> + */
> + if (dwc_has_feature(core_if, DWC_LIMITED_XFER))
> + dwc_start_next_request(ep);
Should next request be not started for all the cases?
> + }
> + }
> +
> + /* Start Control Status Phase */
> + do_setup_in_status_phase(pcd);
> +}
> +
Regards
Pratyush
^ permalink raw reply
* Re: [PATCH v15 06/10] USB/ppc4xx: Add Synopsys DWC OTG HCD queue function
From: Philipp Ittershagen @ 2011-10-20 11:29 UTC (permalink / raw)
To: tmarri; +Cc: greg, linux-usb, linuxppc-dev, Fushen Chen, Mark Miesfeld
In-Reply-To: <1318630143-14327-1-git-send-email-tmarri@apm.com>
Hello Tirumala,
I have some coding style comments below.
On Sat, Oct 15, 2011 at 12:09 AM, <tmarri@apm.com> wrote:
> From: Tirumala Marri <tmarri@apm.com>
>
> Implements functions to manage Queue Heads and Queue
> Transfer Descriptors of DWC USB OTG Controller.
>
> Signed-off-by: Tirumala R Marri <tmarri@apm.com>
> Signed-off-by: Fushen Chen <fchen@apm.com>
> Signed-off-by: Mark Miesfeld <mmiesfeld@apm.com>
> ---
> drivers/usb/dwc/hcd_queue.c | 696 +++++++++++++++++++++++++++++++++++++++++++
> 1 files changed, 696 insertions(+), 0 deletions(-)
> create mode 100644 drivers/usb/dwc/hcd_queue.c
>
> diff --git a/drivers/usb/dwc/hcd_queue.c b/drivers/usb/dwc/hcd_queue.c
> new file mode 100644
> index 0000000..67f0409
> --- /dev/null
> +++ b/drivers/usb/dwc/hcd_queue.c
> @@ -0,0 +1,696 @@
> +/*
> + * DesignWare HS OTG controller driver
> + * Copyright (C) 2006 Synopsys, Inc.
> + * Portions Copyright (C) 2010 Applied Micro Circuits Corporation.
> + *
> + * This program is free software: you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License
> + * version 2 as published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope that it will be useful
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License version 2 for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, see http://www.gnu.org/licenses
> + * or write to the Free Software Foundation, Inc., 51 Franklin Street,
> + * Suite 500, Boston, MA 02110-1335 USA.
> + *
> + * Based on Synopsys driver version 2.60a
> + * Modified by Mark Miesfeld <mmiesfeld@apm.com>
> + * Modified by Stefan Roese <sr@denx.de>, DENX Software Engineering
> + * Modified by Chuck Meade <chuck@theptrgroup.com>
> + *
> + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
> + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO THE
> + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
> + * ARE DISCLAIMED. IN NO EVENT SHALL SYNOPSYS, INC. BE LIABLE FOR ANY DIRECT,
> + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES
> + * (INCLUDING BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
> + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
> + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY OR TORT
> + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
> + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> + *
> + */
> +
> +/*
> + * This file contains the functions to manage Queue Heads and Queue
> + * Transfer Descriptors.
> + */
> +
> +#include "hcd.h"
> +
> +static inline int is_fs_ls(enum usb_device_speed speed)
> +{
> + return speed == USB_SPEED_FULL || speed == USB_SPEED_LOW;
> +}
> +
> +/* Allocates memory for a QH structure. */
> +static inline struct dwc_qh *dwc_otg_hcd_qh_alloc(void)
> +{
> + return kmalloc(sizeof(struct dwc_qh), GFP_ATOMIC);
> +}
Why do you have this extra function? I know its inlined, but it does not
increase code readability.
> +
> +/**
> + * Initializes a QH structure to initialize the QH.
> + */
> +#define SCHEDULE_SLOP 10
> +static void dwc_otg_hcd_qh_init(struct dwc_hcd *hcd, struct dwc_qh *qh,
> + struct urb *urb)
> +{
> + memset(qh, 0, sizeof(struct dwc_qh));
> +
> + /* Initialize QH */
> + switch (usb_pipetype(urb->pipe)) {
> + case PIPE_CONTROL:
> + qh->ep_type = USB_ENDPOINT_XFER_CONTROL;
> + break;
> + case PIPE_BULK:
> + qh->ep_type = USB_ENDPOINT_XFER_BULK;
> + break;
> + case PIPE_ISOCHRONOUS:
> + qh->ep_type = USB_ENDPOINT_XFER_ISOC;
> + break;
> + case PIPE_INTERRUPT:
> + qh->ep_type = USB_ENDPOINT_XFER_INT;
> + break;
> + }
> +
> + qh->ep_is_in = usb_pipein(urb->pipe) ? 1 : 0;
> + qh->data_toggle = DWC_OTG_HC_PID_DATA0;
> + qh->maxp = usb_maxpacket(urb->dev, urb->pipe, !(usb_pipein(urb->pipe)));
> +
> + INIT_LIST_HEAD(&qh->qtd_list);
> + INIT_LIST_HEAD(&qh->qh_list_entry);
> +
> + qh->channel = NULL;
> + qh->speed = urb->dev->speed;
> +
> + /*
> + * FS/LS Enpoint on HS Hub NOT virtual root hub
> + */
> + qh->do_split = 0;
> + if (is_fs_ls(urb->dev->speed) && urb->dev->tt && urb->dev->tt->hub &&
> + urb->dev->tt->hub->devnum != 1)
> + qh->do_split = 1;
> +
> + if (qh->ep_type == USB_ENDPOINT_XFER_INT ||
> + qh->ep_type == USB_ENDPOINT_XFER_ISOC) {
> + /* Compute scheduling parameters once and save them. */
> + u32 hprt;
> + int bytecount = dwc_hb_mult(qh->maxp) *
> + dwc_max_packet(qh->maxp);
> +
> + qh->usecs = NS_TO_US(usb_calc_bus_time(urb->dev->speed,
> + usb_pipein(urb->pipe),
> + (qh->ep_type ==
> + USB_ENDPOINT_XFER_ISOC),
> + bytecount));
> +
> + /* Start in a slightly future (micro)frame. */
> + qh->sched_frame = dwc_frame_num_inc(hcd->frame_number,
> + SCHEDULE_SLOP);
> + qh->interval = urb->interval;
> +
> + hprt = dwc_reg_read(hcd->core_if->host_if->hprt0, 0);
> + if (DWC_HPRT0_PRT_SPD_RD(hprt) == DWC_HPRT0_PRTSPD_HIGH_SPEED &&
> + is_fs_ls(urb->dev->speed)) {
> + qh->interval *= 8;
> + qh->sched_frame |= 0x7;
> + qh->start_split_frame = qh->sched_frame;
> + }
> + }
> +}
> +
> +/**
> + * This function allocates and initializes a QH.
> + */
> +static struct dwc_qh *dwc_otg_hcd_qh_create(struct dwc_hcd *hcd,
> + struct urb *urb)
> +{
> + struct dwc_qh *qh;
> +
> + /* Allocate memory */
> + qh = dwc_otg_hcd_qh_alloc();
> + if (qh == NULL)
> + return NULL;
> +
> + dwc_otg_hcd_qh_init(hcd, qh, urb);
> + return qh;
> +}
> +
> +/**
> + * Free each QTD in the QH's QTD-list then free the QH. QH should already be
> + * removed from a list. QTD list should already be empty if called from URB
> + * Dequeue.
> + */
> +void dwc_otg_hcd_qh_free(struct dwc_qh *qh)
> +{
> + struct dwc_qtd *qtd;
> + struct list_head *pos, *temp;
> +
> + /* Free each QTD in the QTD list */
> + list_for_each_safe(pos, temp, &qh->qtd_list) {
> + list_del(pos);
> + qtd = dwc_list_to_qtd(pos);
> + dwc_otg_hcd_qtd_free(qtd);
> + }
> + kfree(qh);
> +}
> +
> +/**
> + * Microframe scheduler
> + * track the total use in hcd->frame_usecs
> + * keep each qh use in qh->frame_usecs
> + * when surrendering the qh then donate the time back
> + */
> +static const u16 max_uframe_usecs[] = { 100, 100, 100, 100, 100, 100, 30, 0 };
> +
> +/*
> + * called from dwc_otg_hcd.c:dwc_otg_hcd_init
> + */
> +int init_hcd_usecs(struct dwc_hcd *hcd)
> +{
> + int i;
> +
> + for (i = 0; i < 8; i++)
> + hcd->frame_usecs[i] = max_uframe_usecs[i];
> +
> + return 0;
> +}
> +
> +static int find_single_uframe(struct dwc_hcd *hcd, struct dwc_qh *qh)
> +{
> + int i;
> + u16 utime;
> + int t_left;
> + int ret;
> + int done;
> +
> + ret = -1;
> + utime = qh->usecs;
> + t_left = utime;
> + i = 0;
> + done = 0;
> + while (done == 0) {
> + /* At the start hcd->frame_usecs[i] = max_uframe_usecs[i]; */
> + if (utime <= hcd->frame_usecs[i]) {
> + hcd->frame_usecs[i] -= utime;
> + qh->frame_usecs[i] += utime;
> + t_left -= utime;
> + ret = i;
> + done = 1;
> + return ret;
> + } else {
> + i++;
> + if (i == 8) {
> + done = 1;
> + ret = -1;
> + }
> + }
> + }
> + return ret;
> +}
I suggest a for loop for this function, makes it a lot easier to read IMHO.
static int find_single_uframe(struct dwc_hcd *hcd, struct dwc_qh *qh)
{
int i, utime = qh->usecs;
for(i = 0; i < 8; i++) {
if (utime <= hcd->frame_usecs[i]) {
hcd->frame_usecs[i] -= utime;
qh->frame_usecs[i] += utime;
return i;
}
}
return -1;
}
> +
> +/*
> + * use this for FS apps that can span multiple uframes
> + */
> +static int find_multi_uframe(struct dwc_hcd *hcd, struct dwc_qh *qh)
> +{
> + int i;
> + int j;
> + u16 utime;
> + int t_left;
> + int ret;
> + int done;
> + u16 xtime;
> +
> + ret = -1;
> + utime = qh->usecs;
> + t_left = utime;
> + i = 0;
> + done = 0;
> +loop:
> + while (done == 0) {
> + if (hcd->frame_usecs[i] <= 0) {
> + i++;
> + if (i == 8) {
> + done = 1;
> + ret = -1;
> + }
> + goto loop;
This really looks messy. Maybe you can also use a for loop here to prevent
jumping back with a goto in the code.
> + }
> +
> + /*
> + * We need n consequtive slots so use j as a start slot.
> + * j plus j+1 must be enough time (for now)
> + */
> + xtime = hcd->frame_usecs[i];
> + for (j = i + 1; j < 8; j++) {
> + /*
> + * if we add this frame remaining time to xtime we may
> + * be OK, if not we need to test j for a complete frame.
> + */
> + if ((xtime + hcd->frame_usecs[j]) < utime) {
> + if (hcd->frame_usecs[j] < max_uframe_usecs[j]) {
> + j = 8;
> + ret = -1;
> + continue;
> + }
You can use break to break out of the inner for loop here.
> + }
> + if (xtime >= utime) {
> + ret = i;
> + j = 8; /* stop loop with a good value ret */
> + continue;
Same here.
> + }
> + /* add the frame time to x time */
> + xtime += hcd->frame_usecs[j];
> + /* we must have a fully available next frame or break */
> + if ((xtime < utime) &&
> + (hcd->frame_usecs[j] == max_uframe_usecs[j])) {
> + ret = -1;
> + j = 8; /* stop loop with a bad value ret */
> + continue;
And here.
> + }
> + }
Maybe you can export this loop to an inlined function to increase code
readability.
> + if (ret >= 0) {
> + t_left = utime;
> + for (j = i; (t_left > 0) && (j < 8); j++) {
> + t_left -= hcd->frame_usecs[j];
> + if (t_left <= 0) {
> + qh->frame_usecs[j] +=
> + hcd->frame_usecs[j] + t_left;
> + hcd->frame_usecs[j] = -t_left;
> + ret = i;
> + done = 1;
> + } else {
> + qh->frame_usecs[j] +=
> + hcd->frame_usecs[j];
> + hcd->frame_usecs[j] = 0;
> + }
> + }
> + } else {
> + i++;
> + if (i == 8) {
> + done = 1;
> + ret = -1;
> + }
> + }
> + }
> + return ret;
> +}
> +
> +static int find_uframe(struct dwc_hcd *hcd, struct dwc_qh *qh)
> +{
> + int ret = -1;
> +
> + if (qh->speed == USB_SPEED_HIGH)
> + /* if this is a hs transaction we need a full frame */
> + ret = find_single_uframe(hcd, qh);
> + else
> + /* FS transaction may need a sequence of frames */
> + ret = find_multi_uframe(hcd, qh);
> +
> + return ret;
> +}
> +
> +/**
> + * Checks that the max transfer size allowed in a host channel is large enough
> + * to handle the maximum data transfer in a single (micro)frame for a periodic
> + * transfer.
> + */
> +static int check_max_xfer_size(struct dwc_hcd *hcd, struct dwc_qh *qh)
> +{
> + int status = 0;
> + u32 max_xfer_size;
> + u32 max_channel_xfer_size;
> +
> + max_xfer_size = dwc_max_packet(qh->maxp) * dwc_hb_mult(qh->maxp);
> + max_channel_xfer_size = hcd->core_if->core_params->max_transfer_size;
> +
> + if (max_xfer_size > max_channel_xfer_size) {
> + pr_notice("%s: Periodic xfer length %d > max xfer "
> + "length for channel %d\n", __func__, max_xfer_size,
> + max_channel_xfer_size);
> + status = -ENOSPC;
> + }
> +
> + return status;
> +}
> +
> +/**
> + * Schedules an interrupt or isochronous transfer in the periodic schedule.
> + */
> +static int schedule_periodic(struct dwc_hcd *hcd, struct dwc_qh *qh)
> +{
> + int status;
> + struct usb_bus *bus = hcd_to_bus(dwc_otg_hcd_to_hcd(hcd));
> + int frame;
> +
> + status = find_uframe(hcd, qh);
> + frame = -1;
> + if (status == 0) {
> + frame = 7;
> + } else {
> + if (status > 0)
> + frame = status - 1;
> + }
> + /* Set the new frame up */
> + if (frame > -1) {
> + qh->sched_frame &= ~0x7;
> + qh->sched_frame |= (frame & 7);
> + }
> + if (status != -1)
> + status = 0;
> + if (status) {
> + pr_notice("%s: Insufficient periodic bandwidth for "
> + "periodic transfer.\n", __func__);
> + return status;
> + }
> + status = check_max_xfer_size(hcd, qh);
> + if (status) {
> + pr_notice("%s: Channel max transfer size too small "
> + "for periodic transfer.\n", __func__);
> + return status;
> + }
> + /* Always start in the inactive schedule. */
> + list_add_tail(&qh->qh_list_entry, &hcd->periodic_sched_inactive);
> +
> + /* Update claimed usecs per (micro)frame. */
> + hcd->periodic_usecs += qh->usecs;
> +
> + /*
> + * Update average periodic bandwidth claimed and # periodic reqs for
> + * usbfs.
> + */
> + bus->bandwidth_allocated += qh->usecs / qh->interval;
> +
> + if (qh->ep_type == USB_ENDPOINT_XFER_INT)
> + bus->bandwidth_int_reqs++;
> + else
> + bus->bandwidth_isoc_reqs++;
> +
> + return status;
> +}
> +
> +/**
> + * This function adds a QH to either the non periodic or periodic schedule if
> + * it is not already in the schedule. If the QH is already in the schedule, no
> + * action is taken.
> + */
> +static int dwc_otg_hcd_qh_add(struct dwc_hcd *hcd, struct dwc_qh *qh)
> +{
> + int status = 0;
> +
> + /* QH may already be in a schedule. */
> + if (!list_empty(&qh->qh_list_entry))
> + goto done;
You can return here directly and remove the done label.
> + /*
> + * Add the new QH to the appropriate schedule. For non-periodic, always
> + * start in the inactive schedule.
> + */
> + if (dwc_qh_is_non_per(qh))
> + list_add_tail(&qh->qh_list_entry,
> + &hcd->non_periodic_sched_inactive);
> + else
> + status = schedule_periodic(hcd, qh);
> +
> +done:
> + return status;
> +}
> +
> +/**
> + * This function adds a QH to the non periodic deferred schedule.
> + *
> + * @return 0 if successful, negative error code otherwise.
> + */
> +static int dwc_otg_hcd_qh_add_deferred(struct dwc_hcd *hcd, struct dwc_qh *qh)
> +{
> + if (!list_empty(&qh->qh_list_entry))
> + /* QH already in a schedule. */
> + goto done;
You can return here directly and remove the done label.
> +
> + /* Add the new QH to the non periodic deferred schedule */
> + if (dwc_qh_is_non_per(qh))
> + list_add_tail(&qh->qh_list_entry,
> + &hcd->non_periodic_sched_deferred);
> +done:
> + return 0;
> +}
> +
> +/**
> + * Removes an interrupt or isochronous transfer from the periodic schedule.
> + */
> +static void deschedule_periodic(struct dwc_hcd *hcd, struct dwc_qh *qh)
> +{
> + struct usb_bus *bus = hcd_to_bus(dwc_otg_hcd_to_hcd(hcd));
> + int i;
> +
> + list_del_init(&qh->qh_list_entry);
> + /* Update claimed usecs per (micro)frame. */
> + hcd->periodic_usecs -= qh->usecs;
> + for (i = 0; i < 8; i++) {
> + hcd->frame_usecs[i] += qh->frame_usecs[i];
> + qh->frame_usecs[i] = 0;
> + }
> + /*
> + * Update average periodic bandwidth claimed and # periodic reqs for
> + * usbfs.
> + */
> + bus->bandwidth_allocated -= qh->usecs / qh->interval;
> +
> + if (qh->ep_type == USB_ENDPOINT_XFER_INT)
> + bus->bandwidth_int_reqs--;
> + else
> + bus->bandwidth_isoc_reqs--;
> +}
> +
> +/**
> + * Removes a QH from either the non-periodic or periodic schedule. Memory is
> + * not freed.
> + */
> +void dwc_otg_hcd_qh_remove(struct dwc_hcd *hcd, struct dwc_qh *qh)
> +{
> + /* Do nothing if QH is not in a schedule */
> + if (list_empty(&qh->qh_list_entry))
> + return;
> +
> + if (dwc_qh_is_non_per(qh)) {
> + if (hcd->non_periodic_qh_ptr == &qh->qh_list_entry)
> + hcd->non_periodic_qh_ptr =
> + hcd->non_periodic_qh_ptr->next;
> + list_del_init(&qh->qh_list_entry);
> + } else {
> + deschedule_periodic(hcd, qh);
> + }
> +}
> +
> +/**
> + * Defers a QH. For non-periodic QHs, removes the QH from the active
> + * non-periodic schedule. The QH is added to the deferred non-periodic
> + * schedule if any QTDs are still attached to the QH.
> + */
> +int dwc_otg_hcd_qh_deferr(struct dwc_hcd *hcd, struct dwc_qh *qh, int delay)
> +{
> + int deact = 1;
> +
> + if (dwc_qh_is_non_per(qh)) {
> + qh->sched_frame = dwc_frame_num_inc(hcd->frame_number, delay);
> + qh->channel = NULL;
> + qh->qtd_in_process = NULL;
> + deact = 0;
> + dwc_otg_hcd_qh_remove(hcd, qh);
> + if (!list_empty(&qh->qtd_list))
> + /* Add back to deferred non-periodic schedule. */
> + dwc_otg_hcd_qh_add_deferred(hcd, qh);
> + }
> + return deact;
> +}
> +
> +/**
> + * Schedule the next continuing periodic split transfer
> + */
> +static void sched_next_per_split_xfr(struct dwc_qh *qh, u16 fr_num,
> + int sched_split)
> +{
> + if (sched_split) {
> + qh->sched_frame = fr_num;
> + if (dwc_frame_num_le(fr_num,
> + dwc_frame_num_inc(qh->start_split_frame,
> + 1))) {
> + /*
> + * Allow one frame to elapse after start split
> + * microframe before scheduling complete split, but DONT
> + * if we are doing the next start split in the
> + * same frame for an ISOC out.
> + */
> + if (qh->ep_type != USB_ENDPOINT_XFER_ISOC ||
> + qh->ep_is_in)
> + qh->sched_frame =
> + dwc_frame_num_inc(qh->sched_frame, 1);
> + }
> + } else {
> + qh->sched_frame = dwc_frame_num_inc(qh->start_split_frame,
> + qh->interval);
> +
> + if (dwc_frame_num_le(qh->sched_frame, fr_num))
> + qh->sched_frame = fr_num;
> + qh->sched_frame |= 0x7;
> + qh->start_split_frame = qh->sched_frame;
> + }
> +}
> +
> +/**
> + * Deactivates a periodic QH. The QH is removed from the periodic queued
> + * schedule. If there are any QTDs still attached to the QH, the QH is added to
> + * either the periodic inactive schedule or the periodic ready schedule and its
> + * next scheduled frame is calculated. The QH is placed in the ready schedule if
> + * the scheduled frame has been reached already. Otherwise it's placed in the
> + * inactive schedule. If there are no QTDs attached to the QH, the QH is
> + * completely removed from the periodic schedule.
> + */
> +static void deactivate_periodic_qh(struct dwc_hcd *hcd, struct dwc_qh *qh,
> + int sched_next_split)
> +{
> + /* unsigned long flags; */
> + u16 fr_num = dwc_otg_hcd_get_frame_number(dwc_otg_hcd_to_hcd(hcd));
> +
> + if (qh->do_split) {
> + sched_next_per_split_xfr(qh, fr_num, sched_next_split);
> + } else {
> + qh->sched_frame = dwc_frame_num_inc(qh->sched_frame,
> + qh->interval);
> + if (dwc_frame_num_le(qh->sched_frame, fr_num))
> + qh->sched_frame = fr_num;
> + }
> +
> + if (list_empty(&qh->qtd_list)) {
> + dwc_otg_hcd_qh_remove(hcd, qh);
> + } else {
> + /*
> + * Remove from periodic_sched_queued and move to appropriate
> + * queue.
> + */
> + if (qh->sched_frame == fr_num)
> + list_move(&qh->qh_list_entry,
> + &hcd->periodic_sched_ready);
> + else
> + list_move(&qh->qh_list_entry,
> + &hcd->periodic_sched_inactive);
> + }
> +}
> +
> +/**
> + * Deactivates a non-periodic QH. Removes the QH from the active non-periodic
> + * schedule. The QH is added to the inactive non-periodic schedule if any QTDs
> + * are still attached to the QH.
> + */
> +static void deactivate_non_periodic_qh(struct dwc_hcd *hcd, struct dwc_qh *qh)
> +{
> + dwc_otg_hcd_qh_remove(hcd, qh);
> + if (!list_empty(&qh->qtd_list))
> + dwc_otg_hcd_qh_add(hcd, qh);
> +}
> +
> +/**
> + * Deactivates a QH. Determines if the QH is periodic or non-periodic and takes
> + * the appropriate action.
> + */
> +void dwc_otg_hcd_qh_deactivate(struct dwc_hcd *hcd, struct dwc_qh *qh,
> + int sched_next_periodic_split)
> +{
> + if (dwc_qh_is_non_per(qh))
> + deactivate_non_periodic_qh(hcd, qh);
> + else
> + deactivate_periodic_qh(hcd, qh, sched_next_periodic_split);
> +}
> +
> +/**
> + * Initializes a QTD structure.
> + */
> +static void dwc_otg_hcd_qtd_init(struct dwc_qtd *qtd, struct urb *urb)
> +{
> + memset(qtd, 0, sizeof(struct dwc_qtd));
> + qtd->urb = urb;
> +
> + if (usb_pipecontrol(urb->pipe)) {
> + /*
> + * The only time the QTD data toggle is used is on the data
> + * phase of control transfers. This phase always starts with
> + * DATA1.
> + */
> + qtd->data_toggle = DWC_OTG_HC_PID_DATA1;
> + qtd->control_phase = DWC_OTG_CONTROL_SETUP;
> + }
> +
> + /* start split */
> + qtd->complete_split = 0;
> + qtd->isoc_split_pos = DWC_HCSPLIT_XACTPOS_ALL;
> + qtd->isoc_split_offset = 0;
> +
> + /* Store the qtd ptr in the urb to reference what QTD. */
> + urb->hcpriv = qtd;
> +
> + INIT_LIST_HEAD(&qtd->qtd_list_entry);
> + return;
> +}
> +
> +/* Allocates memory for a QTD structure. */
> +static inline struct dwc_qtd *dwc_otg_hcd_qtd_alloc(gfp_t _mem_flags)
> +{
> + return kmalloc(sizeof(struct dwc_qtd), _mem_flags);
> +}
Again, only used once.
> +
> +/**
> + * This function allocates and initializes a QTD.
> + */
> +struct dwc_qtd *dwc_otg_hcd_qtd_create(struct urb *urb, gfp_t _mem_flags)
> +{
> + struct dwc_qtd *qtd = dwc_otg_hcd_qtd_alloc(_mem_flags);
> +
> + if (!qtd)
> + return NULL;
> +
> + dwc_otg_hcd_qtd_init(qtd, urb);
> + return qtd;
> +}
> +
> +/**
> + * This function adds a QTD to the QTD-list of a QH. It will find the correct
> + * QH to place the QTD into. If it does not find a QH, then it will create a
> + * new QH. If the QH to which the QTD is added is not currently scheduled, it
> + * is placed into the proper schedule based on its EP type.
> + *
> + */
> +int dwc_otg_hcd_qtd_add(struct dwc_qtd *qtd, struct dwc_hcd *hcd)
> +{
> + struct usb_host_endpoint *ep;
> + struct dwc_qh *qh;
> + int retval = 0;
> + struct urb *urb = qtd->urb;
> +
> + /*
> + * Get the QH which holds the QTD-list to insert to. Create QH if it
> + * doesn't exist.
> + */
> + ep = dwc_urb_to_endpoint(urb);
> +
> + qh = (struct dwc_qh *)ep->hcpriv;
> + if (!qh) {
> + qh = dwc_otg_hcd_qh_create(hcd, urb);
> + if (!qh) {
> + retval = -1;
> + goto done;
You can return directly and then don't need the goto statement and the
done label.
Greetings,
Philipp
^ permalink raw reply
* Re: [RFC][PATCH 2/2] powerpc/85xx: Introduce a P1020 SoC device tree
From: Tabi Timur-B04825 @ 2011-10-20 16:28 UTC (permalink / raw)
To: Kumar Gala; +Cc: linuxppc-dev@ozlabs.org, devicetree-discuss@lists.ozlabs.org
In-Reply-To: <1319095467-6229-2-git-send-email-galak@kernel.crashing.org>
On Thu, Oct 20, 2011 at 2:24 AM, Kumar Gala <galak@kernel.crashing.org> wro=
te:
>
> =A0arch/powerpc/boot/dts/p1020soc.dtsi | =A0262 +++++++++++++++++++++++++=
++++++++++
All of the other dtsi files are of the format "___si.dtsi". Why does
this one use "___soc.dtsi"?
--=20
Timur Tabi
Linux kernel developer at Freescale=
^ permalink raw reply
* Re: [RFC][PATCH 1/2] powerpc/85xx: create dts components to build up an SoC
From: Tabi Timur-B04825 @ 2011-10-20 16:42 UTC (permalink / raw)
To: Kumar Gala; +Cc: linuxppc-dev@ozlabs.org, devicetree-discuss@lists.ozlabs.org
In-Reply-To: <1319095467-6229-1-git-send-email-galak@kernel.crashing.org>
Ok, your other patch makes more sense now.
On Thu, Oct 20, 2011 at 2:24 AM, Kumar Gala <galak@kernel.crashing.org> wro=
te:
> +++ b/arch/powerpc/boot/dts/fsl/pq3-duart-0.dtsi
> @@ -0,0 +1,8 @@
> +&serial0 {
> + =A0 =A0 =A0 cell-index =3D <0>;
> + =A0 =A0 =A0 device_type =3D "serial";
> + =A0 =A0 =A0 compatible =3D "ns16550";
> + =A0 =A0 =A0 reg =3D <0x4500 0x100>;
> + =A0 =A0 =A0 clock-frequency =3D <0>;
> + =A0 =A0 =A0 interrupts =3D <42 2 0 0>;
> +};
How about we put all serial devices into one pq3-duart.dtsi file, and
let the parent dtsi file reference just the ones that it needs?
--=20
Timur Tabi
Linux kernel developer at Freescale=
^ permalink raw reply
* Re: [RFC][PATCH 1/2] powerpc/85xx: create dts components to build up an SoC
From: Kumar Gala @ 2011-10-20 20:44 UTC (permalink / raw)
To: Tabi Timur-B04825
Cc: linuxppc-dev@ozlabs.org, devicetree-discuss@lists.ozlabs.org
In-Reply-To: <CAOZdJXWtnBB5=DahG8LGQpeP7or0VZv78duhtPiORk3WOir8gQ@mail.gmail.com>
On Oct 20, 2011, at 11:42 AM, Tabi Timur-B04825 wrote:
> Ok, your other patch makes more sense now.
>=20
> On Thu, Oct 20, 2011 at 2:24 AM, Kumar Gala =
<galak@kernel.crashing.org> wrote:
>=20
>> +++ b/arch/powerpc/boot/dts/fsl/pq3-duart-0.dtsi
>> @@ -0,0 +1,8 @@
>> +&serial0 {
>> + cell-index =3D <0>;
>> + device_type =3D "serial";
>> + compatible =3D "ns16550";
>> + reg =3D <0x4500 0x100>;
>> + clock-frequency =3D <0>;
>> + interrupts =3D <42 2 0 0>;
>> +};
>=20
> How about we put all serial devices into one pq3-duart.dtsi file, and
> let the parent dtsi file reference just the ones that it needs?
there isn't an option to do that w/dtc
- k=
^ permalink raw reply
* Re: [RFC][PATCH 2/2] powerpc/85xx: Introduce a P1020 SoC device tree
From: Kumar Gala @ 2011-10-20 20:56 UTC (permalink / raw)
To: Tabi Timur-B04825
Cc: linuxppc-dev@ozlabs.org, devicetree-discuss@lists.ozlabs.org
In-Reply-To: <CAOZdJXU4uHSTRD0vf2jS9gOzjVyO4BLn9=kEmLwwb72LhkTz=w@mail.gmail.com>
On Oct 20, 2011, at 11:28 AM, Tabi Timur-B04825 wrote:
> On Thu, Oct 20, 2011 at 2:24 AM, Kumar Gala =
<galak@kernel.crashing.org> wrote:
>>=20
>> arch/powerpc/boot/dts/p1020soc.dtsi | 262 =
+++++++++++++++++++++++++++++++++++
>=20
> All of the other dtsi files are of the format "___si.dtsi". Why does
> this one use "___soc.dtsi"?
I intend to also have a ___si.dtsi, still playing around with this so we =
have less overall duplication to support both 32 & 36-bit address maps =
as an example.
- k=
^ permalink raw reply
* Re: [RFC][PATCH 1/2] powerpc/85xx: create dts components to build up an SoC
From: Timur Tabi @ 2011-10-20 21:05 UTC (permalink / raw)
To: Kumar Gala; +Cc: linuxppc-dev@ozlabs.org, devicetree-discuss@lists.ozlabs.org
In-Reply-To: <A54F7698-A96F-4EE1-89DB-B6A7C5A071FB@kernel.crashing.org>
Kumar Gala wrote:
>> > How about we put all serial devices into one pq3-duart.dtsi file, and
>> > let the parent dtsi file reference just the ones that it needs?
> there isn't an option to do that w/dtc
What about making all the nodes disabled by default, and then the soc.dtsi
or si.dtsi file can re-enable them?
--
Timur Tabi
Linux kernel developer at Freescale
^ permalink raw reply
* [RFC PATCH 13/17] mpc836x: Move board-specific bcm5481 fixup out of the PHY driver
From: Kyle Moffett @ 2011-10-20 21:00 UTC (permalink / raw)
To: linux-kernel, netdev; +Cc: linuxppc-dev, Paul Mackerras, Kyle Moffett
In-Reply-To: <1319144425-15547-1-git-send-email-Kyle.D.Moffett@boeing.com>
By comparing the BCM5481 registers modified in the ->config_aneg()
method with the datasheet I have for the BCM5482, it appears that the
register writes are adjusting signal timing to work around a known
trace-length issue on the PCB.
Such hardware workarounds don't belong in the generic driver, and should
instead be placed in a board-specific PHY fixup.
NOTE: Needs testing by somebody with the hardware.
Signed-off-by: Kyle Moffett <Kyle.D.Moffett@boeing.com>
---
arch/powerpc/platforms/83xx/mpc836x_rdk.c | 35 ++++++++++++++++++++++++++++
drivers/net/phy/broadcom.c | 36 -----------------------------
2 files changed, 35 insertions(+), 36 deletions(-)
diff --git a/arch/powerpc/platforms/83xx/mpc836x_rdk.c b/arch/powerpc/platforms/83xx/mpc836x_rdk.c
index b0090aa..b7cc607 100644
--- a/arch/powerpc/platforms/83xx/mpc836x_rdk.c
+++ b/arch/powerpc/platforms/83xx/mpc836x_rdk.c
@@ -14,6 +14,7 @@
#include <linux/kernel.h>
#include <linux/pci.h>
+#include <linux/phy.h>
#include <linux/of_platform.h>
#include <linux/io.h>
#include <asm/prom.h>
@@ -38,6 +39,36 @@ static int __init mpc836x_rdk_declare_of_platform_devices(void)
}
machine_device_initcall(mpc836x_rdk, mpc836x_rdk_declare_of_platform_devices);
+static int mpc836x_rdk_bcm5481_fixup(struct phy_device *phydev)
+{
+ int reg;
+
+ if (phydev->interface != PHY_INTERFACE_MODE_RGMII_RXID)
+ return;
+
+ /*
+ * There is no BCM5481 specification available, so down
+ * here is everything we know about "register 0x18". This
+ * at least helps BCM5481 to successfuly receive packets
+ * on MPC8360E-RDK board. Peter Barada <peterb@logicpd.com>
+ * says: "This sets delay between the RXD and RXC signals
+ * instead of using trace lengths to achieve timing".
+ */
+
+ /* Set RDX clk delay. */
+ reg = 0x7 | (0x7 << 12);
+ phy_write(phydev, 0x18, reg);
+ reg = phy_read(phydev, 0x18);
+ if (reg < 0)
+ return reg;
+
+ /* Set RDX-RXC skew. */
+ reg |= (1 << 8);
+ /* Write bits 14:0. */
+ reg |= (1 << 15);
+ return phy_write(phydev, 0x18, reg);
+}
+
static void __init mpc836x_rdk_setup_arch(void)
{
#ifdef CONFIG_PCI
@@ -54,6 +85,10 @@ static void __init mpc836x_rdk_setup_arch(void)
#ifdef CONFIG_QUICC_ENGINE
qe_reset();
#endif
+#ifdef CONFIG_BROADCOM_PHY
+ phy_register_fixup_for_uid(0x0143bca0, 0xfffffff0,
+ &mpc836x_rdk_bcm5481_phy_fixup);
+#endif
}
static void __init mpc836x_rdk_init_IRQ(void)
diff --git a/drivers/net/phy/broadcom.c b/drivers/net/phy/broadcom.c
index 1b83f75..8c03ebc 100644
--- a/drivers/net/phy/broadcom.c
+++ b/drivers/net/phy/broadcom.c
@@ -539,41 +539,6 @@ static int bcm54xx_config_intr(struct phy_device *phydev)
return err;
}
-static int bcm5481_config_aneg(struct phy_device *phydev)
-{
- int ret;
-
- /* Aneg firsly. */
- ret = genphy_config_aneg(phydev);
-
- /* Then we can set up the delay. */
- if (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID) {
- u16 reg;
-
- /*
- * There is no BCM5481 specification available, so down
- * here is everything we know about "register 0x18". This
- * at least helps BCM5481 to successfuly receive packets
- * on MPC8360E-RDK board. Peter Barada <peterb@logicpd.com>
- * says: "This sets delay between the RXD and RXC signals
- * instead of using trace lengths to achieve timing".
- */
-
- /* Set RDX clk delay. */
- reg = 0x7 | (0x7 << 12);
- phy_write(phydev, 0x18, reg);
-
- reg = phy_read(phydev, 0x18);
- /* Set RDX-RXC skew. */
- reg |= (1 << 8);
- /* Write bits 14:0. */
- reg |= (1 << 15);
- phy_write(phydev, 0x18, reg);
- }
-
- return ret;
-}
-
static int brcm_phy_setbits(struct phy_device *phydev, int reg, int set)
{
int val;
@@ -736,7 +701,6 @@ static struct phy_driver broadcom_drivers[] = { {
SUPPORTED_Pause | SUPPORTED_Asym_Pause,
.flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT,
.config_init = bcm54xx_config_init,
- .config_aneg = bcm5481_config_aneg,
.ack_interrupt = bcm54xx_ack_interrupt,
.config_intr = bcm54xx_config_intr,
.driver = { .owner = THIS_MODULE },
--
1.7.2.5
^ permalink raw reply related
* [RFC PATCH 17/17] phy_device: Rename phy_start_aneg() to phy_start_link()
From: Kyle Moffett @ 2011-10-20 21:00 UTC (permalink / raw)
To: linux-kernel, netdev
Cc: linux-doc, Randy Dunlap, Stephen Hemminger, David Decotigny,
devel, Matt Carlson, Kyle Moffett, Kuninori Morimoto,
Alexey Dobriyan, Lennert Buytenhek, Mike Frysinger,
Michał Mirosław, Michael Chan, Giuseppe Cavallaro,
Nobuhiro Iwamatsu, John Crispin, Kristoffer Glembo, Ilya Yanok,
Yoshihiro Shimoda, Greg Kroah-Hartman, Ralf Baechle,
Christian Dietrich, Ralph Hempel, Jon Mason, Joe Perches,
Steve Glendinning, Andrew Morton, Richard Cochran, linuxppc-dev,
David S. Miller, Krzysztof Halasa
In-Reply-To: <1319144425-15547-1-git-send-email-Kyle.D.Moffett@boeing.com>
The name of the "phy_start_aneg()" function is very confusing, because
it also handles forced-mode (AUTONEG_DISABLE) links.
Rename the function to phy_start_link() and fix up all users.
Signed-off-by: Kyle Moffett <Kyle.D.Moffett@boeing.com>
---
Documentation/networking/phy.txt | 2 +-
drivers/net/arm/ixp4xx_eth.c | 2 +-
drivers/net/dnet.c | 2 +-
drivers/net/greth.c | 2 +-
drivers/net/lantiq_etop.c | 2 +-
drivers/net/mv643xx_eth.c | 2 +-
drivers/net/octeon/octeon_mgmt.c | 2 +-
drivers/net/phy/phy.c | 12 ++++++------
drivers/net/pxa168_eth.c | 2 +-
drivers/net/sh_eth.c | 2 +-
drivers/net/smsc911x.c | 2 +-
drivers/net/smsc9420.c | 2 +-
drivers/net/stmmac/stmmac_ethtool.c | 2 +-
drivers/net/tg3.c | 8 ++++----
drivers/net/ucc_geth_ethtool.c | 2 +-
drivers/staging/octeon/ethernet-mdio.c | 4 ++--
include/linux/phy.h | 2 +-
net/dsa/slave.c | 2 +-
18 files changed, 27 insertions(+), 27 deletions(-)
diff --git a/Documentation/networking/phy.txt b/Documentation/networking/phy.txt
index 0db8c81..6f862e5 100644
--- a/Documentation/networking/phy.txt
+++ b/Documentation/networking/phy.txt
@@ -190,7 +190,7 @@ Doing it all yourself
driver if none was found during bus initialization. Passes in
any phy-specific flags as needed.
- int phy_start_aneg(struct phy_device *phydev);
+ int phy_start_link(struct phy_device *phydev);
Using variables inside the phydev structure, either configures advertising
and resets autonegotiation, or disables autonegotiation, and configures
diff --git a/drivers/net/arm/ixp4xx_eth.c b/drivers/net/arm/ixp4xx_eth.c
index de51e84..8864be5 100644
--- a/drivers/net/arm/ixp4xx_eth.c
+++ b/drivers/net/arm/ixp4xx_eth.c
@@ -998,7 +998,7 @@ static int ixp4xx_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
static int ixp4xx_nway_reset(struct net_device *dev)
{
struct port *port = netdev_priv(dev);
- return phy_start_aneg(port->phydev);
+ return phy_start_link(port->phydev);
}
static const struct ethtool_ops ixp4xx_ethtool_ops = {
diff --git a/drivers/net/dnet.c b/drivers/net/dnet.c
index c1063d1..edb4635 100644
--- a/drivers/net/dnet.c
+++ b/drivers/net/dnet.c
@@ -669,7 +669,7 @@ static int dnet_open(struct net_device *dev)
napi_enable(&bp->napi);
dnet_init_hw(bp);
- phy_start_aneg(bp->phy_dev);
+ phy_start_link(bp->phy_dev);
/* schedule a link state check */
phy_start(bp->phy_dev);
diff --git a/drivers/net/greth.c b/drivers/net/greth.c
index e7f268f..0ad3f14 100644
--- a/drivers/net/greth.c
+++ b/drivers/net/greth.c
@@ -1363,7 +1363,7 @@ static int greth_mdio_init(struct greth_private *greth)
/* If Ethernet debug link is used make autoneg happen right away */
if (greth->edcl && greth_edcl == 1) {
- phy_start_aneg(greth->phy);
+ phy_start_link(greth->phy);
timeout = jiffies + 6*HZ;
while (!phy_aneg_done(greth->phy) && time_before(jiffies, timeout)) {
}
diff --git a/drivers/net/lantiq_etop.c b/drivers/net/lantiq_etop.c
index 45f252b..c8795aa 100644
--- a/drivers/net/lantiq_etop.c
+++ b/drivers/net/lantiq_etop.c
@@ -326,7 +326,7 @@ ltq_etop_nway_reset(struct net_device *dev)
{
struct ltq_etop_priv *priv = netdev_priv(dev);
- return phy_start_aneg(priv->phydev);
+ return phy_start_link(priv->phydev);
}
static const struct ethtool_ops ltq_etop_ethtool_ops = {
diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c
index d3e223c..0ce514c 100644
--- a/drivers/net/mv643xx_eth.c
+++ b/drivers/net/mv643xx_eth.c
@@ -2775,7 +2775,7 @@ static void phy_init(struct mv643xx_eth_private *mp, int speed, int duplex)
phy->speed = speed;
phy->duplex = duplex;
}
- phy_start_aneg(phy);
+ phy_start_link(phy);
}
static void init_pscr(struct mv643xx_eth_private *mp, int speed, int duplex)
diff --git a/drivers/net/octeon/octeon_mgmt.c b/drivers/net/octeon/octeon_mgmt.c
index 429e08c..fcdf28a 100644
--- a/drivers/net/octeon/octeon_mgmt.c
+++ b/drivers/net/octeon/octeon_mgmt.c
@@ -686,7 +686,7 @@ static int octeon_mgmt_init_phy(struct net_device *netdev)
return -1;
}
- phy_start_aneg(p->phydev);
+ phy_start_link(p->phydev);
return 0;
}
diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
index 5f72055..fc486fe 100644
--- a/drivers/net/phy/phy.c
+++ b/drivers/net/phy/phy.c
@@ -232,7 +232,7 @@ static void phy_sanitize_settings(struct phy_device *phydev)
* A few notes about parameter checking:
* - We don't set port or transceiver, so we don't care what they
* were set to.
- * - phy_start_aneg() will make sure forced settings are sane, and
+ * - phy_start_link() will make sure forced settings are sane, and
* choose the next best ones from the ones selected, so we don't
* care if ethtool tries to give us bad values.
*/
@@ -276,7 +276,7 @@ int phy_ethtool_sset(struct phy_device *phydev, struct ethtool_cmd *cmd)
phydev->duplex = cmd->duplex;
/* Restart the PHY */
- phy_start_aneg(phydev);
+ phy_start_link(phydev);
return 0;
}
@@ -384,7 +384,7 @@ int phy_mii_ioctl(struct phy_device *phydev,
EXPORT_SYMBOL(phy_mii_ioctl);
/**
- * phy_start_aneg - start auto-negotiation for this PHY device
+ * phy_start_link - start auto-negotiation for this PHY device
* @phydev: the phy_device struct
*
* Description: Sanitizes the settings (if we're not autonegotiating
@@ -392,7 +392,7 @@ EXPORT_SYMBOL(phy_mii_ioctl);
* If the PHYCONTROL Layer is operating, we change the state to
* reflect the beginning of Auto-negotiation or forcing.
*/
-int phy_start_aneg(struct phy_device *phydev)
+int phy_start_link(struct phy_device *phydev)
{
int err;
@@ -423,7 +423,7 @@ out_unlock:
mutex_unlock(&phydev->lock);
return err;
}
-EXPORT_SYMBOL(phy_start_aneg);
+EXPORT_SYMBOL(phy_start_link);
static void phy_change(struct work_struct *work);
@@ -970,7 +970,7 @@ void phy_state_machine(struct work_struct *work)
mutex_unlock(&phydev->lock);
if (needs_aneg)
- err = phy_start_aneg(phydev);
+ err = phy_start_link(phydev);
if (err < 0)
phy_error(phydev);
diff --git a/drivers/net/pxa168_eth.c b/drivers/net/pxa168_eth.c
index ab3bca9..8f3d751 100644
--- a/drivers/net/pxa168_eth.c
+++ b/drivers/net/pxa168_eth.c
@@ -1390,7 +1390,7 @@ static void phy_init(struct pxa168_eth_private *pep, int speed, int duplex)
phy->speed = speed;
phy->duplex = duplex;
}
- phy_start_aneg(phy);
+ phy_start_link(phy);
}
static int ethernet_phy_setup(struct net_device *dev)
diff --git a/drivers/net/sh_eth.c b/drivers/net/sh_eth.c
index 7ef4378..0927b1b 100644
--- a/drivers/net/sh_eth.c
+++ b/drivers/net/sh_eth.c
@@ -1291,7 +1291,7 @@ static int sh_eth_nway_reset(struct net_device *ndev)
int ret;
spin_lock_irqsave(&mdp->lock, flags);
- ret = phy_start_aneg(mdp->phydev);
+ ret = phy_start_link(mdp->phydev);
spin_unlock_irqrestore(&mdp->lock, flags);
return ret;
diff --git a/drivers/net/smsc911x.c b/drivers/net/smsc911x.c
index b9016a3..0b5bb15 100644
--- a/drivers/net/smsc911x.c
+++ b/drivers/net/smsc911x.c
@@ -1712,7 +1712,7 @@ static int smsc911x_ethtool_nwayreset(struct net_device *dev)
{
struct smsc911x_data *pdata = netdev_priv(dev);
- return phy_start_aneg(pdata->phy_dev);
+ return phy_start_link(pdata->phy_dev);
}
static u32 smsc911x_ethtool_getmsglevel(struct net_device *dev)
diff --git a/drivers/net/smsc9420.c b/drivers/net/smsc9420.c
index 459726f..fb9e160 100644
--- a/drivers/net/smsc9420.c
+++ b/drivers/net/smsc9420.c
@@ -302,7 +302,7 @@ static int smsc9420_ethtool_nway_reset(struct net_device *netdev)
if (!pd->phy_dev)
return -ENODEV;
- return phy_start_aneg(pd->phy_dev);
+ return phy_start_link(pd->phy_dev);
}
static int smsc9420_ethtool_getregslen(struct net_device *dev)
diff --git a/drivers/net/stmmac/stmmac_ethtool.c b/drivers/net/stmmac/stmmac_ethtool.c
index 7ed8fb6..68e107b 100644
--- a/drivers/net/stmmac/stmmac_ethtool.c
+++ b/drivers/net/stmmac/stmmac_ethtool.c
@@ -240,7 +240,7 @@ stmmac_set_pauseparam(struct net_device *netdev,
if (phy->autoneg) {
if (netif_running(netdev))
- ret = phy_start_aneg(phy);
+ ret = phy_start_link(phy);
} else
priv->hw->mac->flow_ctrl(priv->ioaddr, phy->duplex,
priv->flow_ctrl, priv->pause);
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index 4a1374d..a317d11 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -1661,7 +1661,7 @@ static void tg3_phy_start(struct tg3 *tp)
phy_start(phydev);
- phy_start_aneg(phydev);
+ phy_start_link(phydev);
}
static void tg3_phy_stop(struct tg3 *tp)
@@ -2848,7 +2848,7 @@ static int tg3_power_down_prepare(struct tg3 *tp)
phydev->advertising = advertising;
- phy_start_aneg(phydev);
+ phy_start_link(phydev);
phyid = phydev->drv->phy_id & phydev->drv->phy_id_mask;
if (phyid != PHY_ID_BCMAC131) {
@@ -10340,7 +10340,7 @@ static int tg3_nway_reset(struct net_device *dev)
if (tg3_flag(tp, USE_PHYLIB)) {
if (!(tp->phy_flags & TG3_PHYFLG_IS_CONNECTED))
return -EAGAIN;
- r = phy_start_aneg(tp->mdio_bus->phy_map[TG3_PHY_MII_ADDR]);
+ r = phy_start_link(tp->mdio_bus->phy_map[TG3_PHY_MII_ADDR]);
} else {
u32 bmcr;
@@ -10500,7 +10500,7 @@ static int tg3_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam
* tg3_adjust_link() do the final
* flow control setup.
*/
- return phy_start_aneg(phydev);
+ return phy_start_link(phydev);
}
}
diff --git a/drivers/net/ucc_geth_ethtool.c b/drivers/net/ucc_geth_ethtool.c
index a97257f..68a8743 100644
--- a/drivers/net/ucc_geth_ethtool.c
+++ b/drivers/net/ucc_geth_ethtool.c
@@ -342,7 +342,7 @@ static int uec_nway_reset(struct net_device *netdev)
{
struct ucc_geth_private *ugeth = netdev_priv(netdev);
- return phy_start_aneg(ugeth->phydev);
+ return phy_start_link(ugeth->phydev);
}
/* Report driver information */
diff --git a/drivers/staging/octeon/ethernet-mdio.c b/drivers/staging/octeon/ethernet-mdio.c
index f18e3e1..dc152dd 100644
--- a/drivers/staging/octeon/ethernet-mdio.c
+++ b/drivers/staging/octeon/ethernet-mdio.c
@@ -81,7 +81,7 @@ static int cvm_oct_nway_reset(struct net_device *dev)
return -EPERM;
if (priv->phydev)
- return phy_start_aneg(priv->phydev);
+ return phy_start_link(priv->phydev);
return -EINVAL;
}
@@ -176,7 +176,7 @@ int cvm_oct_phy_setup_device(struct net_device *dev)
return -1;
}
priv->last_link = 0;
- phy_start_aneg(priv->phydev);
+ phy_start_link(priv->phydev);
}
return 0;
}
diff --git a/include/linux/phy.h b/include/linux/phy.h
index 3713c8d..45f6ee8 100644
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -511,7 +511,7 @@ void phy_disconnect(struct phy_device *phydev);
void phy_detach(struct phy_device *phydev);
void phy_start(struct phy_device *phydev);
void phy_stop(struct phy_device *phydev);
-int phy_start_aneg(struct phy_device *phydev);
+int phy_start_link(struct phy_device *phydev);
int phy_stop_interrupts(struct phy_device *phydev);
diff --git a/net/dsa/slave.c b/net/dsa/slave.c
index 0a47b6c..90ff96d 100644
--- a/net/dsa/slave.c
+++ b/net/dsa/slave.c
@@ -400,7 +400,7 @@ dsa_slave_create(struct dsa_switch *ds, struct device *parent,
p->phy->speed = 0;
p->phy->duplex = 0;
p->phy->advertising = p->phy->supported | ADVERTISED_Autoneg;
- phy_start_aneg(p->phy);
+ phy_start_link(p->phy);
}
return slave_dev;
--
1.7.2.5
^ permalink raw reply related
* Re: [RFC][PATCH 1/2] powerpc/85xx: create dts components to build up an SoC
From: Kumar Gala @ 2011-10-21 3:03 UTC (permalink / raw)
To: Timur Tabi; +Cc: linuxppc-dev@ozlabs.org, devicetree-discuss@lists.ozlabs.org
In-Reply-To: <4EA08D20.7010405@freescale.com>
On Oct 20, 2011, at 4:05 PM, Timur Tabi wrote:
> Kumar Gala wrote:
>>>> How about we put all serial devices into one pq3-duart.dtsi file, =
and
>>>> let the parent dtsi file reference just the ones that it needs?
>> there isn't an option to do that w/dtc
>=20
> What about making all the nodes disabled by default, and then the =
soc.dtsi
> or si.dtsi file can re-enable them?
Its still a bit problematic in that I don't want nodes to exist that =
aren't in the SoC.
- k=
^ permalink raw reply
* Re: [PATCH v15 02/10] USB/ppc4xx: Add Synopsys DesignWare HS USB OTG driver framework
From: Pratyush Anand @ 2011-10-21 3:40 UTC (permalink / raw)
To: tmarri; +Cc: Mark Miesfeld, greg, linux-usb, linuxppc-dev, Fushen Chen
In-Reply-To: <1318630125-14200-1-git-send-email-tmarri@apm.com>
On Sat, Oct 15, 2011 at 3:38 AM, <tmarri@apm.com> wrote:
> From: Tirumala Marri <tmarri@apm.com>
>
> Platform probing is in apmppc.c.
Most if this file is common for other platform too.
So, why not extract common part and put them here.
All the platform specific whether PPC or ARM or else
should move to arch directory.
> Driver parameter and parameter checking are in param.c.
>
> Signed-off-by: Tirumala R Marri <tmarri@apm.com>
> Signed-off-by: Fushen Chen <fchen@apm.com>
> Signed-off-by: Mark Miesfeld <mmiesfeld@apm.com>
> ---
> drivers/usb/dwc/apmppc.c | 355 ++++++++++++++++++++++++++++++++++++++++++++++
> drivers/usb/dwc/driver.h | 76 ++++++++++
> drivers/usb/dwc/param.c | 180 +++++++++++++++++++++++
> 3 files changed, 611 insertions(+), 0 deletions(-)
> create mode 100644 drivers/usb/dwc/apmppc.c
> create mode 100644 drivers/usb/dwc/driver.h
> +
[...]
> +static int __devinit dwc_otg_driver_probe(struct platform_device *ofdev)
> +{
> + int retval;
> + struct dwc_otg_device *dwc_dev;
> + struct device *dev = &ofdev->dev;
> + struct resource res;
> + ulong gusbcfg_addr;
> + u32 usbcfg = 0;
> +
> + dwc_dev = kzalloc(sizeof(*dwc_dev), GFP_KERNEL);
> + if (!dwc_dev) {
> + dev_err(dev, "kmalloc of dwc_otg_device failed\n");
> + retval = -ENOMEM;
> + goto fail_dwc_dev;
> + }
> +
> + /* Retrieve the memory and IRQ resources. */
> + dwc_dev->irq = irq_of_parse_and_map(ofdev->dev.of_node, 0);
> + if (dwc_dev->irq == NO_IRQ) {
> + dev_err(dev, "no device irq\n");
> + retval = -ENODEV;
> + goto fail_of_irq;
> + }
> +
> + if (of_address_to_resource(ofdev->dev.of_node, 0, &res)) {
> + dev_err(dev, "%s: Can't get USB-OTG register address\n",
> + __func__);
> + retval = -ENOMEM;
> + goto fail_of_irq;
> + }
> +
> + dwc_dev->phys_addr = res.start;
> + dwc_dev->base_len = res.end - res.start + 1;
> + if (!request_mem_region(dwc_dev->phys_addr,
> + dwc_dev->base_len, dwc_driver_name)) {
> + dev_err(dev, "request_mem_region failed\n");
> + retval = -EBUSY;
> + goto fail_of_irq;
> + }
> +
> + /* Map the DWC_otg Core memory into virtual address space. */
> + dwc_dev->base = ioremap(dwc_dev->phys_addr, dwc_dev->base_len);
> + if (!dwc_dev->base) {
> + dev_err(dev, "ioremap() failed\n");
> + retval = -ENOMEM;
> + goto fail_ioremap;
> + }
> + dev_dbg(dev, "mapped base=0x%08x\n", (__force u32)dwc_dev->base);
> +
> + /*
> + * Initialize driver data to point to the global DWC_otg
> + * Device structure.
> + */
> + dev_set_drvdata(dev, dwc_dev);
> +
> + dwc_dev->core_if =
> + dwc_otg_cil_init(dwc_dev->base, &dwc_otg_module_params);
> + if (!dwc_dev->core_if) {
> + dev_err(dev, "CIL initialization failed!\n");
> + retval = -ENOMEM;
> + goto fail_cil_init;
> + }
> +
> + /*
> + * Validate parameter values after dwc_otg_cil_init.
> + */
> + if (check_parameters(dwc_dev->core_if)) {
> + retval = -EINVAL;
> + goto fail_check_param;
> + }
> +
> + usb_nop_xceiv_register();
> + dwc_dev->core_if->xceiv = otg_get_transceiver();
> + if (!dwc_dev->core_if->xceiv) {
> + retval = -ENODEV;
> + goto fail_xceiv;
> + }
> + dwc_set_feature(dwc_dev->core_if);
> +
> + /* Initialize the DWC_otg core. */
> + dwc_otg_core_init(dwc_dev->core_if);
> +
> + /*
> + * Disable the global interrupt until all the interrupt
> + * handlers are installed.
> + */
> + spin_lock(&dwc_dev->hcd->lock);
> + dwc_otg_disable_global_interrupts(dwc_dev->core_if);
> + spin_unlock(&dwc_dev->hcd->lock);
> +
> + /*
> + * Install the interrupt handler for the common interrupts before
> + * enabling common interrupts in core_init below.
> + */
> + retval = request_irq(dwc_dev->irq, dwc_otg_common_irq,
> + IRQF_SHARED, "dwc_otg", dwc_dev);
> + if (retval) {
> + dev_err(dev, "request of irq%d failed retval: %d\n",
> + dwc_dev->irq, retval);
> + retval = -EBUSY;
> + goto fail_req_irq;
> + } else {
> + dwc_dev->common_irq_installed = 1;
> + }
> +
> + if (!dwc_has_feature(dwc_dev->core_if, DWC_HOST_ONLY)) {
> + /* Initialize the PCD */
> + retval = dwc_otg_pcd_init(dev);
> + if (retval) {
> + dev_err(dev, "dwc_otg_pcd_init failed\n");
> + dwc_dev->pcd = NULL;
> + goto fail_req_irq;
> + }
> + }
> +
> + gusbcfg_addr = (ulong) (dwc_dev->core_if->core_global_regs)
> + + DWC_GUSBCFG;
> + if (!dwc_has_feature(dwc_dev->core_if, DWC_DEVICE_ONLY)) {
> + /* Initialize the HCD and force_host_mode */
> + usbcfg = dwc_reg_read(gusbcfg_addr, 0);
> + usbcfg |= DWC_USBCFG_FRC_HST_MODE;
> + dwc_reg_write(gusbcfg_addr, 0, usbcfg);
What, if default mode supported by controller is device?
This code will set both host and device mode, even for host only.
So, along with setting forced host mode you should reset forced device
mode bit.
Same for the device only case.
> +
> + retval = dwc_otg_hcd_init(dev, dwc_dev);
> + if (retval) {
> + dev_err(dev, "dwc_otg_hcd_init failed\n");
> + dwc_dev->hcd = NULL;
> + goto fail_hcd;
> + }
> + /* configure chargepump interrupt */
> + dwc_dev->hcd->cp_irq = irq_of_parse_and_map(ofdev->dev.of_node,
> + 3);
Is the above function return 0 on error , I think , it retrun NO_IRQ
which is -1. So even then , the below code will try to register irq.
> + if (dwc_dev->hcd->cp_irq) {
> + retval = request_irq(dwc_dev->hcd->cp_irq,
> + dwc_otg_externalchgpump_irq,
> + IRQF_SHARED,
> + "dwc_otg_ext_chg_pump", dwc_dev);
> + if (retval) {
> + dev_err(dev,
> + "request of irq failed retval: %d\n",
> + retval);
> + retval = -EBUSY;
> + goto fail_hcd;
> + } else {
> + dev_dbg(dev, "%s: ExtChgPump Detection "
> + "IRQ registered\n", dwc_driver_name);
> + }
> + }
> + }
> + /*
> + * Enable the global interrupt after all the interrupt
> + * handlers are installed.
> + */
> + dwc_otg_enable_global_interrupts(dwc_dev->core_if);
> +
> + usbcfg = dwc_reg_read(gusbcfg_addr, 0);
> + usbcfg &= ~DWC_USBCFG_FRC_HST_MODE;
> + dwc_reg_write(gusbcfg_addr, 0, usbcfg);
Why are you disbling forced host mode here. How will the system work, if
you have selected DWC_HOST_ONLY.
> +
> + return 0;
> +fail_hcd:
> + free_irq(dwc_dev->irq, dwc_dev);
> + if (!dwc_has_feature(dwc_dev->core_if, DWC_HOST_ONLY)) {
> + if (dwc_dev->pcd)
> + dwc_otg_pcd_remove(dev);
> + }
> +fail_req_irq:
> + otg_put_transceiver(dwc_dev->core_if->xceiv);
> +fail_xceiv:
> + usb_nop_xceiv_unregister();
> +fail_check_param:
> + dwc_otg_cil_remove(dwc_dev->core_if);
> +fail_cil_init:
> + dev_set_drvdata(dev, NULL);
> + iounmap(dwc_dev->base);
> +fail_ioremap:
> + release_mem_region(dwc_dev->phys_addr, dwc_dev->base_len);
> +fail_of_irq:
> + kfree(dwc_dev);
> +fail_dwc_dev:
> + return retval;
> +}
> +
> +static const struct of_device_id dwc_otg_match[] = {
> + {.compatible = "amcc,dwc-otg",},
> + {}
> +};
> +
> +MODULE_DEVICE_TABLE(of, dwc_otg_match);
> +
> +static struct platform_driver dwc_otg_driver = {
> + .probe = dwc_otg_driver_probe,
> + .remove = __devexit_p(dwc_otg_driver_remove),
> + .driver = {
> + .name = "dwc_otg",
> + .owner = THIS_MODULE,
> + .of_match_table = dwc_otg_match,
> + },
> +};
> +
> +static int __init dwc_otg_driver_init(void)
> +{
> +
> + return platform_driver_register(&dwc_otg_driver);
> +}
> +
> +module_init(dwc_otg_driver_init);
> +
> +static void __exit dwc_otg_driver_cleanup(void)
> +{
> + platform_driver_unregister(&dwc_otg_driver);
> +}
> +
> +module_exit(dwc_otg_driver_cleanup);
> +
> +MODULE_DESCRIPTION(DWC_DRIVER_DESC);
> +MODULE_AUTHOR("Mark Miesfeld <mmiesfeld@apm.com");
> +MODULE_LICENSE("GPL");
Which part do you say that, its PPC specific.
I see everything generic.
Will work for ARM too.
[...]
> diff --git a/drivers/usb/dwc/param.c b/drivers/usb/dwc/param.c
> new file mode 100644
> index 0000000..afae800
> --- /dev/null
> +++ b/drivers/usb/dwc/param.c
> @@ -0,0 +1,180 @@
> +/*
> + * DesignWare HS OTG controller driver
> + * Copyright (C) 2006 Synopsys, Inc.
> + * Portions Copyright (C) 2010 Applied Micro Circuits Corporation.
> + *
> + * This program is free software: you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License
> + * version 2 as published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope that it will be useful
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License version 2 for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, see http://www.gnu.org/licenses
> + * or write to the Free Software Foundation, Inc., 51 Franklin Street,
> + * Suite 500, Boston, MA 02110-1335 USA.
> + *
> + * Based on Synopsys driver version 2.60a
> + * Modified by Mark Miesfeld <mmiesfeld@apm.com>
> + *
> + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
> + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO THE
> + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
> + * ARE DISCLAIMED. IN NO EVENT SHALL SYNOPSYS, INC. BE LIABLE FOR ANY DIRECT,
> + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES
> + * (INCLUDING BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
> + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
> + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY OR TORT
> + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
> + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> + *
> + */
> +
> +/*
> + * This file provides dwc_otg driver parameter and parameter checking.
> + */
> +
> +#include "cil.h"
> +
> +/*
> + * Encapsulate the module parameter settings
> + */
> +struct core_params dwc_otg_module_params = {
> + .otg_cap = -1,
> + .dma_enable = -1,
> + .dma_burst_size = -1,
> + .speed = -1,
> + .host_support_fs_ls_low_power = -1,
> + .host_ls_low_power_phy_clk = -1,
> + .enable_dynamic_fifo = -1,
> + .dev_rx_fifo_size = -1,
> + .dev_nperio_tx_fifo_size = -1,
> + .dev_perio_tx_fifo_size = {-1, -1, -1, -1, -1, -1, -1, -1,
> + -1, -1, -1, -1, -1, -1, -1}, /* 15 */
> + .host_rx_fifo_size = -1,
> + .host_nperio_tx_fifo_size = -1,
> + .host_perio_tx_fifo_size = -1,
> + .max_transfer_size = -1,
> + .max_packet_count = -1,
> + .host_channels = -1,
> + .dev_endpoints = -1,
> + .phy_type = -1,
> + .phy_utmi_width = -1,
> + .phy_ulpi_ddr = -1,
> + .phy_ulpi_ext_vbus = -1,
> + .i2c_enable = -1,
> + .ulpi_fs_ls = -1,
> + .ts_dline = -1,
> + .en_multiple_tx_fifo = -1,
> + .dev_tx_fifo_size = {-1, -1, -1, -1, -1, -1, -1, -1, -1,
> + -1, -1, -1, -1, -1, -1}, /* 15 */
> + .thr_ctl = -1,
> + .tx_thr_length = -1,
> + .rx_thr_length = -1,
> +};
> +
> +/**
> + * Checks that parameter settings for the periodic Tx FIFO sizes are correct
> + * according to the hardware configuration. Sets the size to the hardware
> + * configuration if an incorrect size is detected.
> + */
> +static int set_valid_perio_tx_fifo_sizes(struct core_if *core_if)
> +{
> + ulong regs = (u32) core_if->core_global_regs;
> + u32 *param_size = &dwc_otg_module_params.dev_perio_tx_fifo_size[0];
> + u32 i, size;
> +
> + for (i = 0; i < MAX_PERIO_FIFOS; i++, param_size++) {
So, if you take my suggestion to define fifo number also as user parameter
then, the loop will run only for fifo_number times.
> + size = dwc_reg_read(regs, DWC_DPTX_FSIZ_DIPTXF(i));
> + *param_size = size;
> + }
> + return 0;
> +}
> +
> +/**
> + * Checks that parameter settings for the Tx FIFO sizes are correct according to
> + * the hardware configuration. Sets the size to the hardware configuration if
> + * an incorrect size is detected.
> + */
> +static int set_valid_tx_fifo_sizes(struct core_if *core_if)
> +{
> + ulong regs = (u32) core_if->core_global_regs;
> + u32 *param_size = &dwc_otg_module_params.dev_tx_fifo_size[0];
> + u32 i, size;
> +
> + for (i = 0; i < MAX_TX_FIFOS; i++, param_size) {
Its really starnge, how does this code work without incrementing param_size?
> + size = dwc_reg_read(regs, DWC_DPTX_FSIZ_DIPTXF(i));
> + *param_size = size;
> + }
> + return 0;
> +}
> +
> +/**
> + * This function is called during module intialization to verify that
> + * the module parameters are in a valid state.
> + */
> +int __devinit check_parameters(struct core_if *core_if)
> +{
> + /* Default values */
> + dwc_otg_module_params.otg_cap = dwc_param_otg_cap_default;
> + dwc_otg_module_params.dma_enable = dwc_param_dma_enable_default;
> + dwc_otg_module_params.speed = dwc_param_speed_default;
> + dwc_otg_module_params.host_support_fs_ls_low_power =
> + dwc_param_host_support_fs_ls_low_power_default;
> + dwc_otg_module_params.host_ls_low_power_phy_clk =
> + dwc_param_host_ls_low_power_phy_clk_default;
> + dwc_otg_module_params.phy_type = dwc_param_phy_type_default;
> + dwc_otg_module_params.phy_ulpi_ddr = dwc_param_phy_ulpi_ddr_default;
> + dwc_otg_module_params.phy_ulpi_ext_vbus =
> + dwc_param_phy_ulpi_ext_vbus_default;
> + dwc_otg_module_params.i2c_enable = dwc_param_i2c_enable_default;
> + dwc_otg_module_params.ulpi_fs_ls = dwc_param_ulpi_fs_ls_default;
> + dwc_otg_module_params.ts_dline = dwc_param_ts_dline_default;
> +
> + dwc_otg_module_params.dma_burst_size = dwc_param_dma_burst_size_default;
> + dwc_otg_module_params.phy_utmi_width = dwc_param_phy_utmi_width_default;
> + dwc_otg_module_params.thr_ctl = dwc_param_thr_ctl_default;
> + dwc_otg_module_params.tx_thr_length = dwc_param_tx_thr_length_default;
> + dwc_otg_module_params.rx_thr_length = dwc_param_rx_thr_length_default;
Since, you are assiging default values here, why not to do that when
you have defined the
structure. In stead of initilizing struct with -1, you can initilize
with these default values.
It will save lot of computation.
> +
> + /*
> + * Hardware configurations of the OTG core.
> + */
> + dwc_otg_module_params.enable_dynamic_fifo =
> + DWC_HWCFG2_DYN_FIFO_RD(core_if->hwcfg2);
What if, someone has passed enable_dynamic_fifo as parameter?
Will this code not overwrite user/application defined parameter?
So, before overwrting any of the parameter, you must check whether they
have been passed by the user or not? If passed, then you must not overwrite it.
Otherwise, there is no meaning of keeping such huge list of parameter.
> + dwc_otg_module_params.dev_rx_fifo_size =
> + dwc_reg_read(core_if->core_global_regs, DWC_GRXFSIZ);
> + dwc_otg_module_params.dev_nperio_tx_fifo_size =
> + dwc_reg_read(core_if->core_global_regs, DWC_GNPTXFSIZ) >> 16;
> +
> + dwc_otg_module_params.host_rx_fifo_size =
> + dwc_reg_read(core_if->core_global_regs, DWC_GRXFSIZ);
> + dwc_otg_module_params.host_nperio_tx_fifo_size =
> + dwc_reg_read(core_if->core_global_regs, DWC_GNPTXFSIZ) >> 16;
> + dwc_otg_module_params.host_perio_tx_fifo_size =
> + dwc_reg_read(core_if->core_global_regs, DWC_HPTXFSIZ) >> 16;
> + dwc_otg_module_params.max_transfer_size =
> + (1 << (DWC_HWCFG3_XFERSIZE_CTR_WIDTH_RD(core_if->hwcfg3) + 11))
> + - 1;
> + dwc_otg_module_params.max_packet_count =
> + (1 << (DWC_HWCFG3_PKTSIZE_CTR_WIDTH_RD(core_if->hwcfg3) + 4))
> + - 1;
> +
> + dwc_otg_module_params.host_channels =
> + DWC_HWCFG2_NO_HST_CHAN_RD(core_if->hwcfg2) + 1;
> + dwc_otg_module_params.dev_endpoints =
> + DWC_HWCFG2_NO_DEV_EP_RD(core_if->hwcfg2);
> + dwc_otg_module_params.en_multiple_tx_fifo =
> + (DWC_HWCFG4_DED_FIFO_ENA_RD(core_if->hwcfg4) == 0)
> + ? 0 : 1, 0;
> + set_valid_perio_tx_fifo_sizes(core_if);
> + set_valid_tx_fifo_sizes(core_if);
> +
> + return 0;
> +}
> +
> +module_param_named(dma_enable, dwc_otg_module_params.dma_enable, bool, 0444);
> +MODULE_PARM_DESC(dma_enable, "DMA Mode 0=Slave 1=DMA enabled");
> --
> 1.6.1.rc3
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-usb" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
Regards
Pratyush
^ permalink raw reply
* Re: [PATCH v15 00/10] Add-Synopsys-DesignWare-HS-USB-OTG-driver
From: Pratyush Anand @ 2011-10-21 3:48 UTC (permalink / raw)
To: tmarri; +Cc: greg, linux-usb, linuxppc-dev
In-Reply-To: <1318630114-14064-1-git-send-email-tmarri@apm.com>
Hi Tirumala,
I have reviwed all the patches.
Thanks for taking my most of the diffs over your v13.
There are few thing, which are really very important like,
AHB disable check, EP Disable/Stall (have commented about them in
respective patches). I am doubtful, that how does all of usbcv test cases p=
asses
without those modifications.
So, please have a look on those comments.
You may add my signed-off.
Regards
Pratyush
On Sat, Oct 15, 2011 at 3:38 AM, <tmarri@apm.com> wrote:
> From: Tirumala Marri <tmarri@apm.com>
>
> v15:
> =A01. Fixed some checkpatch errors.
> =A02. Added spin lock check during read-modify-write of interrupt registe=
rs
> =A0 =A0out side intr handlers.
> =A03. Removed Kconfig var which is not used and not defined.
>
> v14:
> =A01. Modifying dwc_reg_read/write functions to accepts offset as arg.
> =A02. Adding spin_lock to common interrupt function.
> =A03. Adding start/stop, vbus_power functions to gadget_opst struct.
> =A04. Removed some unnecessary comments and prints.
> =A05. op_state_str() replace with common function.
> =A06. Removed some unnecessary checks from apmppc.c file.
>
> Tirumala Marri (10):
> =A0USB/ppc4xx: Add Synopsys DesignWare HS USB OTG Register definitions
> =A0USB/ppc4xx: Add Synopsys DesignWare HS USB OTG driver framework
> =A0USB/ppc4xx: Add Synopsys DWC OTG Core Interface Layer (CIL)
> =A0USB/ppc4xx: Add Synopsys DWC OTG HCD function
> =A0USB/ppc4xx: Add Synopsys DWC OTG HCD interrupt function
> =A0USB/ppc4xx: Add Synopsys DWC OTG HCD queue function
> =A0USB/ppc4xx: Add Synopsys DWC OTG PCD function
> =A0USB ppc4xx: Add Synopsys DWC OTG PCD interrupt function
> =A0USB ppc4xx: Add Synopsys DWC OTG driver kernel configuration and
> =A0 =A0Makefile
> =A0USB/ppc4xx:Synopsys DWC OTG driver enable gadget support
>
> =A0drivers/usb/Kconfig =A0 =A0 =A0 =A0 =A0 =A0 =A0 | =A0 =A02 +
> =A0drivers/usb/Makefile =A0 =A0 =A0 =A0 =A0 =A0 =A0| =A0 =A01 +
> =A0drivers/usb/dwc/Kconfig =A0 =A0 =A0 =A0 =A0 | =A0 84 ++
> =A0drivers/usb/dwc/Makefile =A0 =A0 =A0 =A0 =A0| =A0 19 +
> =A0drivers/usb/dwc/apmppc.c =A0 =A0 =A0 =A0 =A0| =A0355 ++++++
> =A0drivers/usb/dwc/cil.c =A0 =A0 =A0 =A0 =A0 =A0 | =A0890 +++++++++++++
> =A0drivers/usb/dwc/cil.h =A0 =A0 =A0 =A0 =A0 =A0 | 1174 +++++++++++++++++=
+
> =A0drivers/usb/dwc/cil_intr.c =A0 =A0 =A0 =A0| =A0616 +++++++++
> =A0drivers/usb/dwc/driver.h =A0 =A0 =A0 =A0 =A0| =A0 76 ++
> =A0drivers/usb/dwc/hcd.c =A0 =A0 =A0 =A0 =A0 =A0 | 2471 +++++++++++++++++=
++++++++++++++++++++
> =A0drivers/usb/dwc/hcd.h =A0 =A0 =A0 =A0 =A0 =A0 | =A0416 +++++++
> =A0drivers/usb/dwc/hcd_intr.c =A0 =A0 =A0 =A0| 1477 +++++++++++++++++++++=
+
> =A0drivers/usb/dwc/hcd_queue.c =A0 =A0 =A0 | =A0696 +++++++++++
> =A0drivers/usb/dwc/param.c =A0 =A0 =A0 =A0 =A0 | =A0180 +++
> =A0drivers/usb/dwc/pcd.c =A0 =A0 =A0 =A0 =A0 =A0 | 1791 +++++++++++++++++=
++++++++++
> =A0drivers/usb/dwc/pcd.h =A0 =A0 =A0 =A0 =A0 =A0 | =A0139 +++
> =A0drivers/usb/dwc/pcd_intr.c =A0 =A0 =A0 =A0| 2312 +++++++++++++++++++++=
+++++++++++++
> =A0drivers/usb/dwc/regs.h =A0 =A0 =A0 =A0 =A0 =A0| 1326 +++++++++++++++++=
+++
> =A0drivers/usb/gadget/Kconfig =A0 =A0 =A0 =A0| =A0 10 +
> =A0drivers/usb/gadget/gadget_chips.h | =A0 =A03 +
> =A020 files changed, 14038 insertions(+), 0 deletions(-)
> =A0create mode 100644 drivers/usb/dwc/Kconfig
> =A0create mode 100644 drivers/usb/dwc/Makefile
> =A0create mode 100644 drivers/usb/dwc/apmppc.c
> =A0create mode 100644 drivers/usb/dwc/cil.c
> =A0create mode 100644 drivers/usb/dwc/cil.h
> =A0create mode 100644 drivers/usb/dwc/cil_intr.c
> =A0create mode 100644 drivers/usb/dwc/driver.h
> =A0create mode 100644 drivers/usb/dwc/hcd.c
> =A0create mode 100644 drivers/usb/dwc/hcd.h
> =A0create mode 100644 drivers/usb/dwc/hcd_intr.c
> =A0create mode 100644 drivers/usb/dwc/hcd_queue.c
> =A0create mode 100644 drivers/usb/dwc/param.c
> =A0create mode 100644 drivers/usb/dwc/pcd.c
> =A0create mode 100644 drivers/usb/dwc/pcd.h
> =A0create mode 100644 drivers/usb/dwc/pcd_intr.c
> =A0create mode 100644 drivers/usb/dwc/regs.h
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-usb" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at =A0http://vger.kernel.org/majordomo-info.html
>
^ permalink raw reply
* Re: [PATCH v15 01/10] USB/ppc4xx: Add Synopsys DesignWare HS USB OTG Register definitions
From: Olof Johansson @ 2011-10-21 17:27 UTC (permalink / raw)
To: tmarri; +Cc: Mark Miesfeld, greg, linux-usb, linuxppc-dev, Fushen Chen
In-Reply-To: <1318630119-14165-1-git-send-email-tmarri@apm.com>
On Fri, Oct 14, 2011 at 03:08:39PM -0700, tmarri@apm.com wrote:
> diff --git a/drivers/usb/dwc/regs.h b/drivers/usb/dwc/regs.h
> new file mode 100644
> index 0000000..d3694f3
> --- /dev/null
> +++ b/drivers/usb/dwc/regs.h
> +#define DWC_GCTL_BSESSION_VALID_RW(reg, x) \
> + (((reg) & (~((u32)0x01 << 19))) | ((x) << 19))
> +#define DWC_GCTL_CSESSION_VALID_RW(reg, x) \
> + (((reg) & (~((u32)0x01 << 18))) | ((x) << 18))
> +#define DWC_GCTL_DEBOUNCE_RW(reg, x) \
> + (((reg) & (~((u32)0x01 << 17))) | ((x) << 17))
> +#define DWC_GCTL_CONN_ID_STATUS_RW(reg, x) \
> + (((reg) & (~((u32)0x01 << 16))) | ((x) << 16))
> +#define DWC_GCTL_DEV_HNP_ENA_RW (reg, x) \
> + (((reg) & (~((u32)0x01 << 11))) | ((x) << 11))
> +#define DWC_GCTL_HOST_HNP_ENA_RW(reg, x) \
> + (((reg) & (~((u32)0x01 << 10))) | ((x) << 10))
> +#define DWC_GCTL_HNP_REQ_RW(reg, x) \
> + (((reg) & (~((u32)0x01 << 9))) | ((x) << 9))
> +#define DWC_GCTL_HOST_NEG_SUCCES_RW(reg, x) \
> + (((reg) & (~((u32)0x01 << 8))) | ((x) << 8))
> +#define DWC_GCTL_SES_REQ_RW(reg, x) \
> + (((reg) & (~((u32)0x01 << 1))) | ((x) << 1))
> +#define DWC_GCTL_SES_REQ_SUCCESS_RW(reg, x) \
> + (((reg) & (~((u32)0x01 << 0))) | ((x) << 0))
Ouch! These could be done much more readable.
> +/*
> + * These Macros represents the bit fields in the FIFO Size Registers (HPTXFSIZ,
> + * GNPTXFSIZ, DPTXFSIZn). Read the register into the u32 element then
> + * read out the bits using the bit elements.
> + */
> +#define DWC_RX_FIFO_DEPTH_RD(reg) (((reg) & ((u32)0xffff << 16)) >> 16)
What the... What's wrong with ((reg >> 16) & 0xffff) here and everywhere
else?
-Olof
^ permalink raw reply
* Re: [PATCH v15 00/10] Add-Synopsys-DesignWare-HS-USB-OTG-driver
From: Olof Johansson @ 2011-10-21 17:33 UTC (permalink / raw)
To: tmarri; +Cc: greg, linux-usb, linuxppc-dev
In-Reply-To: <1318630114-14064-1-git-send-email-tmarri@apm.com>
On Fri, Oct 14, 2011 at 03:08:34PM -0700, tmarri@apm.com wrote:
> From: Tirumala Marri <tmarri@apm.com>
Overall this driver seems to be based on the IP vendor driver? It
looks like a completely flexible driver that implements all possible
combinations of everything.
And as a result, it's huge, and it's got a lot of extra code in there that I'm
willing to bet that you have never even executed on your platform.
Please, pare it down to the portions that you have used, and know works
and can support. If others need the extra functionality in the future,
they can and will expand and bring in what is needed.
Compare this to the dwc3 driver, which is much much cleaner.
Overall other comments:
* Register definitions are crazy long. It means you have to do lots of line
wraps to keep the 80-character limit, which makes it hard to read the code.
* The header files seem to have been autogenerated and have unnneeded
shift/mask operations.
* It doesn't build on non-powerpc platforms since it uses out_{b,l}e accessors.
-Olof
^ permalink raw reply
* Re: [PATCH v15 03/10] USB/ppc4xx: Add Synopsys DWC OTG Core Interface Layer (CIL)
From: Olof Johansson @ 2011-10-21 17:43 UTC (permalink / raw)
To: tmarri; +Cc: Mark Miesfeld, greg, linux-usb, linuxppc-dev, Fushen Chen
In-Reply-To: <1318630129-14235-1-git-send-email-tmarri@apm.com>
Hi,
Some hit-and-run comments below.
-Olof
On Fri, Oct 14, 2011 at 03:08:49PM -0700, tmarri@apm.com wrote:
> diff --git a/drivers/usb/dwc/cil.h b/drivers/usb/dwc/cil.h
> new file mode 100644
> index 0000000..8c29678
> --- /dev/null
> +++ b/drivers/usb/dwc/cil.h
> @@ -0,0 +1,1174 @@
> +/*
> + * DesignWare HS OTG controller driver
> + * Copyright (C) 2006 Synopsys, Inc.
> + * Portions Copyright (C) 2010 Applied Micro Circuits Corporation.
> + *
> + * This program is free software: you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License
> + * version 2 as published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope that it will be useful
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License version 2 for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, see http://www.gnu.org/licenses
> + * or write to the Free Software Foundation, Inc., 51 Franklin Street,
> + * Suite 500, Boston, MA 02110-1335 USA.
> + *
> + * Based on Synopsys driver version 2.60a
> + * Modified by Mark Miesfeld <mmiesfeld@apm.com>
> + * Modified by Stefan Roese <sr@denx.de>, DENX Software Engineering
> + *
> + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
> + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO THE
> + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
> + * ARE DISCLAIMED. IN NO EVENT SHALL SYNOPSYS, INC. BE LIABLE FOR ANY DIRECT,
> + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES
> + * (INCLUDING BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
> + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
> + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY OR TORT
> + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
> + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> + *
> + */
> +
> +#if !defined(__DWC_CIL_H__)
> +#define __DWC_CIL_H__
> +#include <linux/io.h>
> +#include <linux/usb/ch9.h>
> +#include <linux/usb/gadget.h>
> +#include <linux/interrupt.h>
> +#include <linux/dmapool.h>
> +#include <linux/spinlock.h>
> +#include <linux/usb/otg.h>
> +
> +#include "regs.h"
> +
> +#ifdef CONFIG_DWC_DEBUG
> +#define DEBUG
> +#endif
> +
> +/**
> + * Reads the content of a register.
> + */
> +static inline u32 dwc_reg_read(ulong reg , u32 offset)
> +{
> +
> +#ifdef CONFIG_DWC_OTG_REG_LE
> + return in_le32((unsigned __iomem *)(reg + offset));
> +#else
> + return in_be32((unsigned __iomem *)(reg + offset));
> +#endif
> +}
> +
> +static inline void dwc_reg_write(ulong reg, u32 offset, const u32 value)
> +{
> +#ifdef CONFIG_DWC_OTG_REG_LE
> + out_le32((unsigned __iomem *)(reg + offset), value);
> +#else
> + out_be32((unsigned __iomem *)(reg + offset), value);
> +#endif
> +};
NACK. This is powerpc-specific code.
Also, your function has to take the register as a void __iomem * type instead
of casting it here.
Finally, please try to abstract away the endian ness a bit further, instead of
duplicating each implementation here twice.
> +/*
> + * Debugging support vanishes in non-debug builds.
> + */
> +/* Display CIL Debug messages */
> +#define dwc_dbg_cil (0x2)
> +
> +/* Display CIL Verbose debug messages */
> +#define dwc_dbg_cilv (0x20)
> +
> +/* Display PCD (Device) debug messages */
> +#define dwc_dbg_pcd (0x4)
> +
> +/* Display PCD (Device) Verbose debug messages */
> +#define dwc_dbg_pcdv (0x40)
> +
> +/* Display Host debug messages */
> +#define dwc_dbg_hcd (0x8)
> +
> +/* Display Verbose Host debug messages */
> +#define dwc_dbg_hcdv (0x80)
> +
> +/* Display enqueued URBs in host mode. */
> +#define dwc_dbg_hcd_urb (0x800)
> +
> +/* Display "special purpose" debug messages */
> +#define dwc_dbg_sp (0x400)
> +
> +/* Display all debug messages */
> +#define dwc_dbg_any (0xFF)
> +
> +/* All debug messages off */
> +#define dwc_dbg_off 0
> +
> +/* Prefix string for DWC_DEBUG print macros. */
> +#define usb_dwc "dwc_otg: "
These don't seem to have to do with CIL, so should go in their own debug header
perhaps?
> +/*
> + * Added-sr: 2007-07-26
Irrellevant in the upstream context.
> + /* Internal DWC HCD Flags */
> + union dwc_otg_hcd_internal_flags {
> + u32 d32;
> + struct {
> + unsigned port_connect_status_change:1;
> + unsigned port_connect_status:1;
> + unsigned port_reset_change:1;
> + unsigned port_enable_change:1;
> + unsigned port_suspend_change:1;
> + unsigned port_over_current_change:1;
> + unsigned reserved:27;
> + } b;
> + } flags;
Please don't use structs/unions for register definitions.
> +static int dwc_otg_handle_otg_intr(struct core_if *core_if)
> +{
This function looks a bit long and indentation is deep. Please refactor into helpers.
-Olof
^ permalink raw reply
* Re: [PATCH v15 04/10] USB/ppc4xx: Add Synopsys DWC OTG HCD function
From: Olof Johansson @ 2011-10-21 17:48 UTC (permalink / raw)
To: tmarri; +Cc: Mark Miesfeld, greg, linux-usb, linuxppc-dev, Fushen Chen
In-Reply-To: <1318630133-14264-1-git-send-email-tmarri@apm.com>
Some more hit-and-run comments.
On Fri, Oct 14, 2011 at 03:08:53PM -0700, tmarri@apm.com wrote:
> +static int dwc_otg_hcd_disconnect_cb(void *_p)
> +{
> + u32 intr;
> + struct dwc_hcd *hcd = hcd_to_dwc_otg_hcd(_p);
> + struct core_if *core_if = hcd->core_if;
> +
> + /* Set status flags for the hub driver. */
> + hcd->flags.b.port_connect_status_change = 1;
> + hcd->flags.b.port_connect_status = 0;
> +
> + /*
> + * Shutdown any transfers in process by clearing the Tx FIFO Empty
> + * interrupt mask and status bits and disabling subsequent host
> + * channel interrupts.
> + */
> + intr = 0;
> + intr |= DWC_INTMSK_NP_TXFIFO_EMPT;
> + intr |= DWC_INTMSK_P_TXFIFO_EMPTY;
> + intr |= DWC_INTMSK_HST_CHAN;
> + spin_lock(&hcd->lock);
> + dwc_reg_modify(gintmsk_reg(hcd), 0, intr, 0);
> + dwc_reg_modify(gintsts_reg(hcd), 0, intr, 0);
> + spin_unlock(&hcd->lock);
> +
> + del_timers(hcd);
> +
> + /*
> + * Turn off the vbus power only if the core has transitioned to device
> + * mode. If still in host mode, need to keep power on to detect a
> + * reconnection.
> + */
> + if (dwc_otg_is_device_mode(core_if)) {
> + if (core_if->xceiv->state != OTG_STATE_A_SUSPEND) {
> + u32 hprt0 = 0;
> +
> + pr_info("Disconnect: PortPower off\n");
> + hprt0 = DWC_HPRT0_PRT_PWR_RW(hprt0, 0);
> + dwc_reg_write(core_if->host_if->hprt0, 0, hprt0);
> + }
> + dwc_otg_disable_host_interrupts(core_if);
> + }
> +
> + /* Respond with an error status to all URBs in the schedule. */
> + kill_all_urbs(hcd);
> + if (dwc_otg_is_host_mode(core_if)) {
> + /* Clean up any host channels that were in use. */
> + int num_channels;
> + u32 i;
> + struct dwc_hc *channel;
> + ulong regs;
> + u32 hcchar;
If you need these many local variables here, and this much indentation, then
please refactor to a helper function. That will get rid of the crazy
linewrapping below too.
> +
> + num_channels = core_if->core_params->host_channels;
> + if (!core_if->dma_enable) {
> + /* Flush out any channel requests in slave mode. */
> + for (i = 0; i < num_channels; i++) {
> + channel = hcd->hc_ptr_array[i];
> + if (list_empty(&channel->hc_list_entry)) {
> + regs =
> + core_if->host_if->hc_regs[i];
> + hcchar = dwc_reg_read(regs, DWC_HCCHAR);
> +
> + if (DWC_HCCHAR_ENA_RD(hcchar)) {
> + hcchar =
> + DWC_HCCHAR_ENA_RW(hcchar,
> + 0);
> + hcchar =
> + DWC_HCCHAR_DIS_RW(hcchar,
> + 1);
> + hcchar =
> + DWC_HCCHAR_EPDIR_RW(hcchar,
> + 0);
> + dwc_reg_write(regs, DWC_HCCHAR,
> + hcchar);
> + }
> + }
> + }
> + }
> +
> + for (i = 0; i < num_channels; i++) {
> + channel = hcd->hc_ptr_array[i];
> + if (list_empty(&channel->hc_list_entry)) {
> + regs = core_if->host_if->hc_regs[i];
> + hcchar = dwc_reg_read(regs, DWC_HCCHAR);
> +
> + if (DWC_HCCHAR_ENA_RD(hcchar)) {
> + /* Halt the channel. */
> + hcchar = DWC_HCCHAR_DIS_RW(hcchar, 1);
> + dwc_reg_write(regs, DWC_HCCHAR, hcchar);
> + }
> + dwc_otg_hc_cleanup(core_if, channel);
> + list_add_tail(&channel->hc_list_entry,
> + &hcd->free_hc_list);
> + }
> + }
> + }
> +
> + /*
> + * A disconnect will end the session so the B-Device is no
> + * longer a B-host.
> + */
> + ((struct usb_hcd *)_p)->self.is_b_host = 0;
> + return 1;
> +}
> +
-Olof
^ permalink raw reply
* Re: [PATCH] powerpc/fsl_msi: add support for "msi-address-64" property
From: Tabi Timur-B04825 @ 2011-10-21 19:16 UTC (permalink / raw)
To: Gala Kumar-B11780; +Cc: linuxppc-dev@ozlabs.org
In-Reply-To: <C4D76656-C95E-4906-BC65-6EBAFBBB6A7C@freescale.com>
On Fri, Oct 14, 2011 at 9:15 AM, Kumar Gala <kumar.gala@freescale.com> wrot=
e:
>> .../devicetree/bindings/powerpc/fsl/msi-pic.txt =A0 =A0| =A0 42 ++++++++=
++++++++++++
>> arch/powerpc/sysdev/fsl_msi.c =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =
=A0| =A0 20 +++++++---
>> arch/powerpc/sysdev/fsl_msi.h =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =
=A0| =A0 =A03 +-
>> 3 files changed, 57 insertions(+), 8 deletions(-)
>
> applied
Applied where, exactly? You don't have a repo on kernel.org, and your
repo on github.org is over a month old.
--=20
Timur Tabi
Linux kernel developer at Freescale=
^ permalink raw reply
* RE: [PATCH 3/5][v2] fsl-rio: Add two ports and rapidio message units support
From: Liu Gang-B34182 @ 2011-10-22 5:15 UTC (permalink / raw)
To: Bounine, Alexandre, Kumar Gala, linuxppc-dev@ozlabs.org,
Zang Roy-R61911
Cc: Andrew Morton, linux-kernel@vger.kernel.org
In-Reply-To: <0CE8B6BE3C4AD74AB97D9D29BD24E55202367762@CORPEXCH1.na.ads.idt.com>
Hi, Alex,
Thanks for your comments, please find my replies inlines.
-----Original Message-----
From: Bounine, Alexandre [mailto:Alexandre.Bounine@idt.com]=20
Sent: Thursday, October 20, 2011 3:54 AM
To: Kumar Gala; linuxppc-dev@ozlabs.org
Cc: Andrew Morton; Liu Gang-B34182; linux-kernel@vger.kernel.org
Subject: RE: [PATCH 3/5][v2] fsl-rio: Add two ports and rapidio message uni=
ts support
On Thu, Oct 13, 2011 at 10:09 AM, Kumar Gala wrote:
>=20
> From: Liu Gang <Gang.Liu@freescale.com>
>=20
> Usually, freescale rapidio endpoint can support one 1X or two 4X LP-=20
> Serial link interfaces, and rapidio message transactions can be=20
> implemented
by
> two
Is the number of 1x ports described correctly?
Can we have two 1x ports as well?=20
[Liu Gang-B34182] Yes you are right. endpoint can also have two 1x ports. I=
'll correct it.
> message units. This patch adds the support of two rapidio ports and=20
> initializes message unit 0 and message unit 1. And these ports and=20
> message
... skip ...
> +
> + /* Probe the master port phy type */
> + ccsr =3D in_be32(priv->regs_win + RIO_CCSR + i*0x20);
> + port->phy_type =3D (ccsr & 1) ? RIO_PHY_SERIAL :
> RIO_PHY_PARALLEL;
> + dev_info(&dev->dev, "RapidIO PHY type: %s\n",
> + (port->phy_type =3D=3D RIO_PHY_PARALLEL) ?
> + "parallel" :
> + ((port->phy_type =3D=3D RIO_PHY_SERIAL) ?
"serial"
> :
> + "unknown"));
> + /* Checking the port training status */
> + if (in_be32((priv->regs_win + RIO_ESCSR + i*0x20)) & 1)
{
> + dev_err(&dev->dev, "Port %d is not ready. "
> + "Try to restart connection...\n", i);
> + switch (port->phy_type) {
> + case RIO_PHY_SERIAL:
> + /* Disable ports */
> + out_be32(priv->regs_win
> + + RIO_CCSR + i*0x20, 0);
> + /* Set 1x lane */
> + setbits32(priv->regs_win
> + + RIO_CCSR + i*0x20,
0x02000000);
> + /* Enable ports */
> + setbits32(priv->regs_win
> + + RIO_CCSR + i*0x20,
0x00600000);
> + break;
> + case RIO_PHY_PARALLEL:
> + /* Disable ports */
> + out_be32(priv->regs_win
> + + RIO_CCSR + i*0x20,
0x22000000);
> + /* Enable ports */
> + out_be32(priv->regs_win
> + + RIO_CCSR + i*0x20,
0x44000000);
> + break;
> + }
Probably this may be a good moment to drop the support for parallel link.
Especially after you renamed controller to "srio" in the device tree.
[Liu Gang-B34182] I'm also considering if we should drop the parallel link =
support and doorbell outbound ATMU configuration.
I found some older powerpc chips support parallel link, like mpc8540 and so=
on. But DTS files of these chips do not support
Rapidio nodes. For example we can't find rapidio node in arch/powerpc/boot/=
dts/mpc8540ads.dts file. So can we conclude that
these chips with parallel rapidio link do not need the support for rapidio =
module and the code for parallel link can be removed?=20
> + msleep(100);
> + if (in_be32((priv->regs_win
> + + RIO_ESCSR + i*0x20)) & 1) {
> + dev_err(&dev->dev,
> + "Port %d restart failed.\n", i);
> + release_resource(&port->iores);
> + kfree(priv);
> + kfree(port);
> + continue;
> + }
> + dev_info(&dev->dev, "Port %d restart
success!\n", i);
> + }
> + fsl_rio_info(&dev->dev, ccsr);
> +
... skip ...
>=20
> struct rio_msg_regs {
> - u32 omr; /* 0xD_3000 - Outbound message 0 mode register
*/
> - u32 osr; /* 0xD_3004 - Outbound message 0 status register
*/
> + u32 omr;
> + u32 osr;
> u32 pad1;
> - u32 odqdpar; /* 0xD_300C - Outbound message 0 descriptor
> queue
> - dequeue pointer address register */
> + u32 odqdpar;
> u32 pad2;
> - u32 osar; /* 0xD_3014 - Outbound message 0 source address
> - register */
> - u32 odpr; /* 0xD_3018 - Outbound message 0 destination
port
> - register */
> - u32 odatr; /* 0xD_301C - Outbound message 0 destination
> attributes
> - Register*/
> - u32 odcr; /* 0xD_3020 - Outbound message 0 double-word
count
> - register */
> + u32 osar;
> + u32 odpr;
> + u32 odatr;
> + u32 odcr;
> u32 pad3;
> - u32 odqepar; /* 0xD_3028 - Outbound message 0 descriptor
> queue
> - enqueue pointer address register */
> + u32 odqepar;
> u32 pad4[13];
> - u32 imr; /* 0xD_3060 - Inbound message 0 mode register */
> - u32 isr; /* 0xD_3064 - Inbound message 0 status register
*/
> + u32 imr;
> + u32 isr;
> u32 pad5;
> - u32 ifqdpar; /* 0xD_306C - Inbound message 0 frame queue
> dequeue
> - pointer address register*/
> + u32 ifqdpar;
> u32 pad6;
> - u32 ifqepar; /* 0xD_3074 - Inbound message 0 frame queue
> enqueue
> - pointer address register */
> - u32 pad7[226];
> - u32 odmr; /* 0xD_3400 - Outbound doorbell mode register */
> - u32 odsr; /* 0xD_3404 - Outbound doorbell status register
*/
> + u32 ifqepar;
> + u32 pad7;
Do we need pad7 here?
[Liu Gang-B34182] Yeah, it's not required here. Forgot to remove it when re=
-wrote this struct.
> +};
> +
> +struct rio_dbell_regs {
> + u32 odmr;
> + u32 odsr;
> u32 res0[4];
> - u32 oddpr; /* 0xD_3418 - Outbound doorbell destination port
> - register */
... skip ...
>=20
> @@ -340,35 +327,45 @@ fsl_rio_dbell_handler(int irq, void
> *dev_instance)
> " sid %2.2x tid %2.2x info %4.4x\n",
> DBELL_SID(dmsg), DBELL_TID(dmsg),
DBELL_INF(dmsg));
>=20
> - list_for_each_entry(dbell, &port->dbells, node) {
> - if ((dbell->res->start <=3D DBELL_INF(dmsg)) &&
> - (dbell->res->end >=3D DBELL_INF(dmsg))) {
> - found =3D 1;
> - break;
> + for (i =3D 0; i < MAX_PORT_NUM; i++) {
> + if (fsl_dbell->mport[i]) {
> + list_for_each_entry(dbell,
> + &fsl_dbell->mport[i]->dbells,
node) {
> + if ((dbell->res->start
> + <=3D DBELL_INF(dmsg))
> + && (dbell->res->end
> + >=3D DBELL_INF(dmsg))) {
> + found =3D 1;
> + break;
> + }
> + }
> + if (found && dbell->dinb) {
> + dbell->dinb(fsl_dbell->mport[i],
> + dbell->dev_id,
DBELL_SID(dmsg),
> + DBELL_TID(dmsg),
> + DBELL_INF(dmsg));
> + break;
> + }
> }
> }
Do we need to check for matching DBELL_TID and mport destID here and scan o=
nly doorbell list attached to the right port? Otherwise this may call servi=
ce routine associated with doorbell on a wrong port.
[Liu Gang-B34182] Do you mean to match DBELL_TID and mport DevID? Usually t=
his is a reliable method, but for the rapidio module of powerpc, will encou=
nter some problem. We set the port's DevID by
the register "Base Device ID CSR" defined in Rapidio Specification. The rap=
idio module of powerpc can support two ports but have only one the Base Dev=
ice ID CSR. So these two ports will have the same
DevID. Although there are two registers "Alternate Device ID CSR" to separa=
te deviceIDs for each port, they are specific registers of the freescale ra=
pidio and can't be accessed by getting the extended feature
space block offset. For this doobell issue, in order to call a right servic=
e routine, perhaps we should ensure that different ports in different "res-=
>start and res->end" configurations.
> - if (found) {
> - dbell->dinb(port, dbell->dev_id,
> - DBELL_SID(dmsg),
> - DBELL_TID(dmsg),
DBELL_INF(dmsg));
> - } else {
> +
> + if (!found) {
> pr_debug
> ("RIO: spurious doorbell,"
> " sid %2.2x tid %2.2x info %4.4x\n",
> DBELL_SID(dmsg), DBELL_TID(dmsg),
> DBELL_INF(dmsg));
> }
> - setbits32(&rmu->msg_regs->dmr, DOORBELL_DMR_DI);
> - out_be32(&rmu->msg_regs->dsr, DOORBELL_DSR_DIQI);
> + setbits32(&fsl_dbell->dbell_regs->dmr, DOORBELL_DMR_DI);
> + out_be32(&fsl_dbell->dbell_regs->dsr,
DOORBELL_DSR_DIQI);
> }
>=20
> out:
> return IRQ_HANDLED;
> }
>=20
... skip ...
> @@ -1114,50 +1104,48 @@ int fsl_rio_setup_rmu(struct rio_mport *mport,=20
> struct device_node *node) {
> struct rio_priv *priv;
> struct fsl_rmu *rmu;
> - struct rio_ops *ops;
> + u64 msg_start;
> + const u32 *msg_addr;
> + int mlen;
> + int aw;
>=20
> - if (!mport || !mport->priv || !node)
> - return -1;
> + if (!mport || !mport->priv)
> + return -EFAULT;
EINVAL may be better here?
[Liu Gang-B34182] Yes EINVAL will be better and I'll correct. Thanks!
> +
> + priv =3D mport->priv;
> +
> + if (!node) {
> + dev_warn(priv->dev, "Can't get %s property 'fsl,rmu'\n",
> + priv->dev->of_node->full_name);
> + return -EFAULT;
EINVAL as well?
[Liu Gang-B34182] Ditto.
> + }
Regards,
Alex.=
^ permalink raw reply
* [PATCH 15/49] powerpc: irq: Remove IRQF_DISABLED
From: Yong Zhang @ 2011-10-22 9:56 UTC (permalink / raw)
To: linux-kernel
Cc: cbe-oss-dev, Arnd Bergmann, Geoff Levand, Paul Mackerras, tglx,
linuxppc-dev
In-Reply-To: <1319277421-9203-1-git-send-email-yong.zhang0@gmail.com>
Since commit [e58aa3d2: genirq: Run irq handlers with interrupts disabled],
We run all interrupt handlers with interrupts disabled
and we even check and yell when an interrupt handler
returns with interrupts enabled (see commit [b738a50a:
genirq: Warn when handler enables interrupts]).
So now this flag is a NOOP and can be removed.
Signed-off-by: Yong Zhang <yong.zhang0@gmail.com>
Acked-by: Arnd Bergmann <arnd@arndb.de>
---
arch/powerpc/include/asm/floppy.h | 4 ++--
arch/powerpc/include/asm/xics.h | 4 ++--
arch/powerpc/kernel/smp.c | 2 +-
arch/powerpc/platforms/cell/beat.c | 2 +-
arch/powerpc/platforms/cell/celleb_scc_pciex.c | 2 +-
arch/powerpc/platforms/cell/iommu.c | 3 +--
arch/powerpc/platforms/cell/pmu.c | 2 +-
arch/powerpc/platforms/cell/spu_base.c | 9 +++------
arch/powerpc/platforms/powermac/pic.c | 1 -
arch/powerpc/platforms/powermac/smp.c | 4 ++--
arch/powerpc/platforms/ps3/device-init.c | 2 +-
arch/powerpc/sysdev/mpic.c | 2 --
arch/powerpc/sysdev/ppc4xx_soc.c | 2 +-
arch/powerpc/sysdev/xics/xics-common.c | 5 ++---
14 files changed, 18 insertions(+), 26 deletions(-)
diff --git a/arch/powerpc/include/asm/floppy.h b/arch/powerpc/include/asm/floppy.h
index 24bd34c..936a904 100644
--- a/arch/powerpc/include/asm/floppy.h
+++ b/arch/powerpc/include/asm/floppy.h
@@ -108,10 +108,10 @@ static int fd_request_irq(void)
{
if (can_use_virtual_dma)
return request_irq(FLOPPY_IRQ, floppy_hardint,
- IRQF_DISABLED, "floppy", NULL);
+ 0, "floppy", NULL);
else
return request_irq(FLOPPY_IRQ, floppy_interrupt,
- IRQF_DISABLED, "floppy", NULL);
+ 0, "floppy", NULL);
}
static int vdma_dma_setup(char *addr, unsigned long size, int mode, int io)
diff --git a/arch/powerpc/include/asm/xics.h b/arch/powerpc/include/asm/xics.h
index bd6c401..c48de98 100644
--- a/arch/powerpc/include/asm/xics.h
+++ b/arch/powerpc/include/asm/xics.h
@@ -15,8 +15,8 @@
#define DEFAULT_PRIORITY 5
/*
- * Mark IPIs as higher priority so we can take them inside interrupts that
- * arent marked IRQF_DISABLED
+ * Mark IPIs as higher priority so we can take them inside interrupts
+ * FIXME: still true now?
*/
#define IPI_PRIORITY 4
diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c
index 25ddbfc..6df7090 100644
--- a/arch/powerpc/kernel/smp.c
+++ b/arch/powerpc/kernel/smp.c
@@ -187,7 +187,7 @@ int smp_request_message_ipi(int virq, int msg)
return 1;
}
#endif
- err = request_irq(virq, smp_ipi_action[msg], IRQF_DISABLED|IRQF_PERCPU,
+ err = request_irq(virq, smp_ipi_action[msg], IRQF_PERCPU,
smp_ipi_name[msg], 0);
WARN(err < 0, "unable to request_irq %d for %s (rc %d)\n",
virq, smp_ipi_name[msg], err);
diff --git a/arch/powerpc/platforms/cell/beat.c b/arch/powerpc/platforms/cell/beat.c
index 232fc38..852592b 100644
--- a/arch/powerpc/platforms/cell/beat.c
+++ b/arch/powerpc/platforms/cell/beat.c
@@ -230,7 +230,7 @@ static int __init beat_register_event(void)
}
ev->virq = virq;
- rc = request_irq(virq, ev->handler, IRQF_DISABLED,
+ rc = request_irq(virq, ev->handler, 0,
ev->typecode, NULL);
if (rc != 0) {
printk(KERN_ERR "Beat: failed to request virtual IRQ"
diff --git a/arch/powerpc/platforms/cell/celleb_scc_pciex.c b/arch/powerpc/platforms/cell/celleb_scc_pciex.c
index ae790ac..14be2bd 100644
--- a/arch/powerpc/platforms/cell/celleb_scc_pciex.c
+++ b/arch/powerpc/platforms/cell/celleb_scc_pciex.c
@@ -514,7 +514,7 @@ static __init int celleb_setup_pciex(struct device_node *node,
virq = irq_create_of_mapping(oirq.controller, oirq.specifier,
oirq.size);
if (request_irq(virq, pciex_handle_internal_irq,
- IRQF_DISABLED, "pciex", (void *)phb)) {
+ 0, "pciex", (void *)phb)) {
pr_err("PCIEXC:Failed to request irq\n");
goto error;
}
diff --git a/arch/powerpc/platforms/cell/iommu.c b/arch/powerpc/platforms/cell/iommu.c
index fc46fca..592c3d5 100644
--- a/arch/powerpc/platforms/cell/iommu.c
+++ b/arch/powerpc/platforms/cell/iommu.c
@@ -412,8 +412,7 @@ static void cell_iommu_enable_hardware(struct cbe_iommu *iommu)
IIC_IRQ_IOEX_ATI | (iommu->nid << IIC_IRQ_NODE_SHIFT));
BUG_ON(virq == NO_IRQ);
- ret = request_irq(virq, ioc_interrupt, IRQF_DISABLED,
- iommu->name, iommu);
+ ret = request_irq(virq, ioc_interrupt, 0, iommu->name, iommu);
BUG_ON(ret);
/* set the IOC segment table origin register (and turn on the iommu) */
diff --git a/arch/powerpc/platforms/cell/pmu.c b/arch/powerpc/platforms/cell/pmu.c
index 1acf360..59c1a16 100644
--- a/arch/powerpc/platforms/cell/pmu.c
+++ b/arch/powerpc/platforms/cell/pmu.c
@@ -392,7 +392,7 @@ static int __init cbe_init_pm_irq(void)
}
rc = request_irq(irq, cbe_pm_irq,
- IRQF_DISABLED, "cbe-pmu-0", NULL);
+ 0, "cbe-pmu-0", NULL);
if (rc) {
printk("ERROR: Request for irq on node %d failed\n",
node);
diff --git a/arch/powerpc/platforms/cell/spu_base.c b/arch/powerpc/platforms/cell/spu_base.c
index 3675da7..e94d3ec 100644
--- a/arch/powerpc/platforms/cell/spu_base.c
+++ b/arch/powerpc/platforms/cell/spu_base.c
@@ -442,8 +442,7 @@ static int spu_request_irqs(struct spu *spu)
snprintf(spu->irq_c0, sizeof (spu->irq_c0), "spe%02d.0",
spu->number);
ret = request_irq(spu->irqs[0], spu_irq_class_0,
- IRQF_DISABLED,
- spu->irq_c0, spu);
+ 0, spu->irq_c0, spu);
if (ret)
goto bail0;
}
@@ -451,8 +450,7 @@ static int spu_request_irqs(struct spu *spu)
snprintf(spu->irq_c1, sizeof (spu->irq_c1), "spe%02d.1",
spu->number);
ret = request_irq(spu->irqs[1], spu_irq_class_1,
- IRQF_DISABLED,
- spu->irq_c1, spu);
+ 0, spu->irq_c1, spu);
if (ret)
goto bail1;
}
@@ -460,8 +458,7 @@ static int spu_request_irqs(struct spu *spu)
snprintf(spu->irq_c2, sizeof (spu->irq_c2), "spe%02d.2",
spu->number);
ret = request_irq(spu->irqs[2], spu_irq_class_2,
- IRQF_DISABLED,
- spu->irq_c2, spu);
+ 0, spu->irq_c2, spu);
if (ret)
goto bail2;
}
diff --git a/arch/powerpc/platforms/powermac/pic.c b/arch/powerpc/platforms/powermac/pic.c
index cb40e92..901bfbd 100644
--- a/arch/powerpc/platforms/powermac/pic.c
+++ b/arch/powerpc/platforms/powermac/pic.c
@@ -272,7 +272,6 @@ static struct irqaction xmon_action = {
static struct irqaction gatwick_cascade_action = {
.handler = gatwick_action,
- .flags = IRQF_DISABLED,
.name = "cascade",
};
diff --git a/arch/powerpc/platforms/powermac/smp.c b/arch/powerpc/platforms/powermac/smp.c
index 9a521dc..9b6a820 100644
--- a/arch/powerpc/platforms/powermac/smp.c
+++ b/arch/powerpc/platforms/powermac/smp.c
@@ -200,7 +200,7 @@ static int psurge_secondary_ipi_init(void)
if (psurge_secondary_virq)
rc = request_irq(psurge_secondary_virq, psurge_ipi_intr,
- IRQF_DISABLED|IRQF_PERCPU, "IPI", NULL);
+ IRQF_PERCPU, "IPI", NULL);
if (rc)
pr_err("Failed to setup secondary cpu IPI\n");
@@ -408,7 +408,7 @@ static int __init smp_psurge_kick_cpu(int nr)
static struct irqaction psurge_irqaction = {
.handler = psurge_ipi_intr,
- .flags = IRQF_DISABLED|IRQF_PERCPU,
+ .flags = IRQF_PERCPU,
.name = "primary IPI",
};
diff --git a/arch/powerpc/platforms/ps3/device-init.c b/arch/powerpc/platforms/ps3/device-init.c
index 6c4b583..3f175e8 100644
--- a/arch/powerpc/platforms/ps3/device-init.c
+++ b/arch/powerpc/platforms/ps3/device-init.c
@@ -825,7 +825,7 @@ static int ps3_probe_thread(void *data)
spin_lock_init(&dev.lock);
- res = request_irq(irq, ps3_notification_interrupt, IRQF_DISABLED,
+ res = request_irq(irq, ps3_notification_interrupt, 0,
"ps3_notification", &dev);
if (res) {
pr_err("%s:%u: request_irq failed %d\n", __func__, __LINE__,
diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c
index 9678081..1b0493d 100644
--- a/arch/powerpc/sysdev/mpic.c
+++ b/arch/powerpc/sysdev/mpic.c
@@ -800,8 +800,6 @@ static void mpic_end_ipi(struct irq_data *d)
* IPIs are marked IRQ_PER_CPU. This has the side effect of
* preventing the IRQ_PENDING/IRQ_INPROGRESS logic from
* applying to them. We EOI them late to avoid re-entering.
- * We mark IPI's with IRQF_DISABLED as they must run with
- * irqs disabled.
*/
mpic_eoi(mpic);
}
diff --git a/arch/powerpc/sysdev/ppc4xx_soc.c b/arch/powerpc/sysdev/ppc4xx_soc.c
index d3d6ce3..0debcc3 100644
--- a/arch/powerpc/sysdev/ppc4xx_soc.c
+++ b/arch/powerpc/sysdev/ppc4xx_soc.c
@@ -115,7 +115,7 @@ static int __init ppc4xx_l2c_probe(void)
}
/* Install error handler */
- if (request_irq(irq, l2c_error_handler, IRQF_DISABLED, "L2C", 0) < 0) {
+ if (request_irq(irq, l2c_error_handler, 0, "L2C", 0) < 0) {
printk(KERN_ERR "Cannot install L2C error handler"
", cache is not enabled\n");
of_node_put(np);
diff --git a/arch/powerpc/sysdev/xics/xics-common.c b/arch/powerpc/sysdev/xics/xics-common.c
index 3d93a8d..63762c6 100644
--- a/arch/powerpc/sysdev/xics/xics-common.c
+++ b/arch/powerpc/sysdev/xics/xics-common.c
@@ -134,11 +134,10 @@ static void xics_request_ipi(void)
BUG_ON(ipi == NO_IRQ);
/*
- * IPIs are marked IRQF_DISABLED as they must run with irqs
- * disabled, and PERCPU. The handler was set in map.
+ * IPIs are marked IRQF_PERCPU. The handler was set in map.
*/
BUG_ON(request_irq(ipi, icp_ops->ipi_action,
- IRQF_DISABLED|IRQF_PERCPU, "IPI", NULL));
+ IRQF_PERCPU, "IPI", NULL));
}
int __init xics_smp_probe(void)
--
1.7.1
^ permalink raw reply related
* [PATCH 41/49] powerpc/ps3: irq: Remove IRQF_DISABLED
From: Yong Zhang @ 2011-10-22 9:56 UTC (permalink / raw)
To: linux-kernel; +Cc: Geoff Levand, cbe-oss-dev, tglx, linuxppc-dev
In-Reply-To: <1319277421-9203-1-git-send-email-yong.zhang0@gmail.com>
Since commit [e58aa3d2: genirq: Run irq handlers with interrupts disabled],
We run all interrupt handlers with interrupts disabled
and we even check and yell when an interrupt handler
returns with interrupts enabled (see commit [b738a50a:
genirq: Warn when handler enables interrupts]).
So now this flag is a NOOP and can be removed.
Signed-off-by: Yong Zhang <yong.zhang0@gmail.com>
Acked-by: Geoff Levand <geoff@infradead.org>
---
drivers/ps3/ps3-vuart.c | 2 +-
drivers/ps3/ps3stor_lib.c | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/ps3/ps3-vuart.c b/drivers/ps3/ps3-vuart.c
index d9fb729..fb73008 100644
--- a/drivers/ps3/ps3-vuart.c
+++ b/drivers/ps3/ps3-vuart.c
@@ -952,7 +952,7 @@ static int ps3_vuart_bus_interrupt_get(void)
}
result = request_irq(vuart_bus_priv.virq, ps3_vuart_irq_handler,
- IRQF_DISABLED, "vuart", &vuart_bus_priv);
+ 0, "vuart", &vuart_bus_priv);
if (result) {
pr_debug("%s:%d: request_irq failed (%d)\n",
diff --git a/drivers/ps3/ps3stor_lib.c b/drivers/ps3/ps3stor_lib.c
index cc328de..8c3f5ad 100644
--- a/drivers/ps3/ps3stor_lib.c
+++ b/drivers/ps3/ps3stor_lib.c
@@ -167,7 +167,7 @@ int ps3stor_setup(struct ps3_storage_device *dev, irq_handler_t handler)
goto fail_close_device;
}
- error = request_irq(dev->irq, handler, IRQF_DISABLED,
+ error = request_irq(dev->irq, handler, 0,
dev->sbd.core.driver->name, dev);
if (error) {
dev_err(&dev->sbd.core, "%s:%u: request_irq failed %d\n",
--
1.7.1
^ permalink raw reply related
* Re: [PATCH v15 00/10] Add-Synopsys-DesignWare-HS-USB-OTG-driver
From: Olof Johansson @ 2011-10-22 20:30 UTC (permalink / raw)
To: tmarri; +Cc: greg, linux-usb, linuxppc-dev
In-Reply-To: <20111021173302.GB27652@quad.lixom.net>
Hi,
On Fri, Oct 21, 2011 at 10:33 AM, Olof Johansson <olof@lixom.net> wrote:
> On Fri, Oct 14, 2011 at 03:08:34PM -0700, tmarri@apm.com wrote:
>> From: Tirumala Marri <tmarri@apm.com>
>
> Overall this driver seems to be based on the IP vendor driver? It
> looks like a completely flexible driver that implements all possible
> combinations of everything.
After looking a little closer at the patch set, it seems that number
one thing you need to do is simplify the driver. A lot.
I suggest starting from scratch with a clean implementation, only
bringing in the pieces you need. Over time, if other vendors are using
other aspects of the same IP, they get to add those parts of the
driver when they need it. Look at the dwc3 driver for comparison on
cleanliness, it's much cleaner than what you've posted.
-Olof
^ permalink raw reply
* Re: [PATCH] powerpc/fsl_msi: add support for "msi-address-64" property
From: Kumar Gala @ 2011-10-22 21:19 UTC (permalink / raw)
To: Tabi Timur-B04825; +Cc: linuxppc-dev@ozlabs.org, Gala Kumar-B11780
In-Reply-To: <CAOZdJXVJXhiSsjm9cBruGgJ946fr6xwpOZzTLcN2GQGq6eamVw@mail.gmail.com>
On Oct 21, 2011, at 2:16 PM, Tabi Timur-B04825 wrote:
> On Fri, Oct 14, 2011 at 9:15 AM, Kumar Gala <kumar.gala@freescale.com> =
wrote:
>=20
>>> .../devicetree/bindings/powerpc/fsl/msi-pic.txt | 42 =
++++++++++++++++++++
>>> arch/powerpc/sysdev/fsl_msi.c | 20 +++++++---
>>> arch/powerpc/sysdev/fsl_msi.h | 3 +-
>>> 3 files changed, 57 insertions(+), 8 deletions(-)
>>=20
>> applied
>=20
> Applied where, exactly? You don't have a repo on kernel.org, and your
> repo on github.org is over a month old.
I've updated github as still trying to figure out when I'll get my =
kernel.org account back.
- k=
^ permalink raw reply
* [PATCH 01/11] powerpc/85xx: Add 'fsl, pq3-gpio' compatiable for GPIO driver
From: Kumar Gala @ 2011-10-22 21:20 UTC (permalink / raw)
To: linuxppc-dev
Support MPC85xx platforms outside of MPC8572/MPC8536. The
MPC8572/MPC8536 have an erratum that is worked around based on having
"fsl,mpc8572-gpio" in the compatiable list. All other MPC85xx SoCs
don't require this workaround and thus utilize the 'fsl,pq3-gpio'
compatiable.
Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
---
drivers/gpio/gpio-mpc8xxx.c | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/drivers/gpio/gpio-mpc8xxx.c b/drivers/gpio/gpio-mpc8xxx.c
index fb4963a..d74d19b 100644
--- a/drivers/gpio/gpio-mpc8xxx.c
+++ b/drivers/gpio/gpio-mpc8xxx.c
@@ -310,6 +310,7 @@ static struct of_device_id mpc8xxx_gpio_ids[] __initdata = {
{ .compatible = "fsl,mpc8572-gpio", },
{ .compatible = "fsl,mpc8610-gpio", },
{ .compatible = "fsl,mpc5121-gpio", .data = mpc512x_irq_set_type, },
+ { .compatible = "fsl,pq3-gpio", },
{ .compatible = "fsl,qoriq-gpio", },
{}
};
--
1.7.3.4
^ permalink raw reply related
* [PATCH 02/11] powerpc/85xx: Simplify P1020RDB CAMP dts using includes
From: Kumar Gala @ 2011-10-22 21:20 UTC (permalink / raw)
To: linuxppc-dev
In-Reply-To: <1319318452-27036-1-git-send-email-galak@kernel.crashing.org>
If we include the p1020rdb.dts instead of p1020si.dts we greatly reduce
duplication and maintenance. We can just list which devices are
disabled for the given core and mpic protected sources.
Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
---
arch/powerpc/boot/dts/p1020rdb_camp_core0.dts | 154 +------------------------
arch/powerpc/boot/dts/p1020rdb_camp_core1.dts | 11 +--
2 files changed, 4 insertions(+), 161 deletions(-)
diff --git a/arch/powerpc/boot/dts/p1020rdb_camp_core0.dts b/arch/powerpc/boot/dts/p1020rdb_camp_core0.dts
index f0bf7f4..41b4585 100644
--- a/arch/powerpc/boot/dts/p1020rdb_camp_core0.dts
+++ b/arch/powerpc/boot/dts/p1020rdb_camp_core0.dts
@@ -16,7 +16,7 @@
* option) any later version.
*/
-/include/ "p1020si.dtsi"
+/include/ "p1020rdb.dts"
/ {
model = "fsl,P1020RDB";
@@ -32,7 +32,7 @@
cpus {
PowerPC,P1020@1 {
- status = "disabled";
+ status = "disabled";
};
};
@@ -45,169 +45,19 @@
};
soc@ffe00000 {
- i2c@3000 {
- rtc@68 {
- compatible = "dallas,ds1339";
- reg = <0x68>;
- };
- };
-
serial1: serial@4600 {
status = "disabled";
};
- spi@7000 {
- fsl_m25p80@0 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "fsl,espi-flash";
- reg = <0>;
- linux,modalias = "fsl_m25p80";
- spi-max-frequency = <40000000>;
-
- partition@0 {
- /* 512KB for u-boot Bootloader Image */
- reg = <0x0 0x00080000>;
- label = "SPI (RO) U-Boot Image";
- read-only;
- };
-
- partition@80000 {
- /* 512KB for DTB Image */
- reg = <0x00080000 0x00080000>;
- label = "SPI (RO) DTB Image";
- read-only;
- };
-
- partition@100000 {
- /* 4MB for Linux Kernel Image */
- reg = <0x00100000 0x00400000>;
- label = "SPI (RO) Linux Kernel Image";
- read-only;
- };
-
- partition@500000 {
- /* 4MB for Compressed RFS Image */
- reg = <0x00500000 0x00400000>;
- label = "SPI (RO) Compressed RFS Image";
- read-only;
- };
-
- partition@900000 {
- /* 7MB for JFFS2 based RFS */
- reg = <0x00900000 0x00700000>;
- label = "SPI (RW) JFFS2 RFS";
- };
- };
- };
-
- mdio@24000 {
- phy0: ethernet-phy@0 {
- interrupt-parent = <&mpic>;
- interrupts = <3 1>;
- reg = <0x0>;
- };
- phy1: ethernet-phy@1 {
- interrupt-parent = <&mpic>;
- interrupts = <2 1>;
- reg = <0x1>;
- };
- };
-
- mdio@25000 {
- tbi0: tbi-phy@11 {
- reg = <0x11>;
- device_type = "tbi-phy";
- };
- };
-
enet0: ethernet@b0000 {
status = "disabled";
};
- enet1: ethernet@b1000 {
- phy-handle = <&phy0>;
- tbi-handle = <&tbi0>;
- phy-connection-type = "sgmii";
- };
-
- enet2: ethernet@b2000 {
- phy-handle = <&phy1>;
- phy-connection-type = "rgmii-id";
- };
-
- usb@22000 {
- phy_type = "ulpi";
- };
-
- /* USB2 is shared with localbus, so it must be disabled
- by default. We can't put 'status = "disabled";' here
- since U-Boot doesn't clear the status property when
- it enables USB2. OTOH, U-Boot does create a new node
- when there isn't any. So, just comment it out.
- usb@23000 {
- phy_type = "ulpi";
- };
- */
-
mpic: pic@40000 {
protected-sources = <
42 29 30 34 /* serial1, enet0-queue-group0 */
17 18 24 45 /* enet0-queue-group1, crypto */
>;
};
-
- };
-
- pci0: pcie@ffe09000 {
- ranges = <0x2000000 0x0 0xa0000000 0 0xa0000000 0x0 0x20000000
- 0x1000000 0x0 0x00000000 0 0xffc10000 0x0 0x10000>;
- interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
- interrupt-map = <
- /* IDSEL 0x0 */
- 0000 0x0 0x0 0x1 &mpic 0x4 0x1
- 0000 0x0 0x0 0x2 &mpic 0x5 0x1
- 0000 0x0 0x0 0x3 &mpic 0x6 0x1
- 0000 0x0 0x0 0x4 &mpic 0x7 0x1
- >;
- pcie@0 {
- reg = <0x0 0x0 0x0 0x0 0x0>;
- #size-cells = <2>;
- #address-cells = <3>;
- device_type = "pci";
- ranges = <0x2000000 0x0 0xa0000000
- 0x2000000 0x0 0xa0000000
- 0x0 0x20000000
-
- 0x1000000 0x0 0x0
- 0x1000000 0x0 0x0
- 0x0 0x100000>;
- };
- };
-
- pci1: pcie@ffe0a000 {
- ranges = <0x2000000 0x0 0x80000000 0 0x80000000 0x0 0x20000000
- 0x1000000 0x0 0x00000000 0 0xffc00000 0x0 0x10000>;
- interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
- interrupt-map = <
- /* IDSEL 0x0 */
- 0000 0x0 0x0 0x1 &mpic 0x0 0x1
- 0000 0x0 0x0 0x2 &mpic 0x1 0x1
- 0000 0x0 0x0 0x3 &mpic 0x2 0x1
- 0000 0x0 0x0 0x4 &mpic 0x3 0x1
- >;
- pcie@0 {
- reg = <0x0 0x0 0x0 0x0 0x0>;
- #size-cells = <2>;
- #address-cells = <3>;
- device_type = "pci";
- ranges = <0x2000000 0x0 0x80000000
- 0x2000000 0x0 0x80000000
- 0x0 0x20000000
-
- 0x1000000 0x0 0x0
- 0x1000000 0x0 0x0
- 0x0 0x100000>;
- };
};
};
diff --git a/arch/powerpc/boot/dts/p1020rdb_camp_core1.dts b/arch/powerpc/boot/dts/p1020rdb_camp_core1.dts
index 6ec0220..5174538 100644
--- a/arch/powerpc/boot/dts/p1020rdb_camp_core1.dts
+++ b/arch/powerpc/boot/dts/p1020rdb_camp_core1.dts
@@ -15,7 +15,7 @@
* option) any later version.
*/
-/include/ "p1020si.dtsi"
+/include/ "p1020rdb.dts"
/ {
model = "fsl,P1020RDB";
@@ -28,7 +28,7 @@
cpus {
PowerPC,P1020@0 {
- status = "disabled";
+ status = "disabled";
};
};
@@ -85,12 +85,6 @@
status = "disabled";
};
- enet0: ethernet@b0000 {
- fixed-link = <1 1 1000 0 0>;
- phy-connection-type = "rgmii-id";
-
- };
-
enet1: ethernet@b1000 {
status = "disabled";
};
@@ -135,7 +129,6 @@
global-utilities@e0000 { //global utilities block
status = "disabled";
};
-
};
pci0: pcie@ffe09000 {
--
1.7.3.4
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox