Thread (6 messages) flat view 6 messages, 3 authors, 2007-05-09

Re: [PATCH] [POWERPC] 8xx: PQ SoC IRDA support

From: Samuel Ortiz <hidden>
Date: 2007-05-09 08:49:52

Hi Vitaly,

On 5/8/2007, "Vitaly Bordug" [off-list ref] wrote:
Adds support of IRDA transceiver residing on PowerQUICC processors and
enabling such on mpc885ads reference board. The driver is implemented
using of_device concept, hereby implies arch/powerpc support of the target.

Signed-off-by: Vitaly Bordug <redacted>
I'd really prefer this patch to be splitted in 2 parts: The PPC specific
bits, and the IrDA driver that would apply on top of it.
Meanwhile, I can comment on the IrDA driver code:

quoted hunk ↗ jump to hunk
diff --git a/drivers/net/irda/Kconfig b/drivers/net/irda/Kconfig
index 7c8ccc0..b3681e7 100644
--- a/drivers/net/irda/Kconfig
+++ b/drivers/net/irda/Kconfig
@@ -17,6 +17,10 @@ config IRTTY_SIR
=09  If unsure, say Y.

+config 8XX_SIR
+=09  tristate "mpc8xx SIR"
+=09  depends on 8xx && IRDA
+
Some "help" field here wouldn't hurt.


+static void mpc8xx_irda_rx(struct net_device *dev)
+{
+=09struct mpc8xx_irda *si =3D dev->priv;
+=09cbd_t *bdp;
+=09struct sk_buff *skb;
+=09int len;
+=09ushort status;
+
+=09bdp =3D si->cur_rx;
+
+=09for (;;) {
+=09=09if (bdp->cbd_sc & BD_AHDLC_RX_EMPTY)
+=09=09=09break;
+=09=09status =3D bdp->cbd_sc;
+
+=09=09if (status & BD_AHDLC_RX_STATS) {
+=09=09=09/* process errors
+=09=09=09 */
+=09=09=09if (bdp->cbd_sc & BD_AHDLC_RX_AB)
+=09=09=09=09si->stats.rx_length_errors++;
+=09=09=09if (bdp->cbd_sc & BD_AHDLC_RX_CR)=09/* CRC Error */
+=09=09=09=09si->stats.rx_crc_errors++;
+=09=09=09if (bdp->cbd_sc & BD_AHDLC_RX_OV)=09/* FIFO overrun */
+=09=09=09=09si->stats.rx_over_errors++;
+=09=09} else {
+=09=09=09/* Process the incoming frame.
+=09=09=09 */
+=09=09=09len =3D bdp->cbd_datlen;
+
+=09=09=09skb =3D dev_alloc_skb(len + 1);
+=09=09=09if (skb =3D=3D NULL) {
+=09=09=09=09printk(KERN_INFO
+=09=09=09=09       "%s: Memory squeeze, dropping packet.\n",
+=09=09=09=09       dev->name);
+=09=09=09=09si->stats.rx_dropped++;
+=09=09=09} else {
+=09=09=09=09skb->dev =3D dev;
+=09=09=09=09skb_reserve(skb, 1);
+=09=09=09=09memcpy(skb_put(skb, len),
+=09=09=09=09       si->rx_vaddr[bdp - si->rx_bd_base], len);
+=09=09=09=09skb_trim(skb, skb->len - 2);
+
+=09=09=09=09si->stats.rx_packets++;
+=09=09=09=09si->stats.rx_bytes +=3D len;
+
+=09=09=09=09skb->mac.raw =3D skb->data;
This should be
+=09=09=09=09skb_reset_mac_header(skb);

+static irqreturn_t mpc8xx_irda_irq(int irq, void *dev_id)
+{
+=09struct net_device *dev =3D dev_id;
+=09struct mpc8xx_irda *si =3D dev->priv;
+=09scc_t *sccp =3D si->sccp;
+=09cbd_t *bdp;
+=09ushort int_events;
+=09int must_restart =3D 0;
+
+=09/* Get the interrupt events that caused us to be here.
+=09 */
+=09int_events =3D in_be16(&sccp->scc_scce);
+=09out_be16(&sccp->scc_scce, int_events);
+
+=09/* Handle receive event in its own function.
+=09 */
+=09if (int_events & SCC_AHDLC_RXF)
+=09=09mpc8xx_irda_rx(dev);
+
+=09spin_lock(&si->lock);
+
+=09/* Transmit OK, or non-fatal error.  Update the buffer descriptors.
+=09 */
+=09if (int_events & (SCC_AHDLC_TXE | SCC_AHDLC_TXB)) {
+=09=09bdp =3D si->dirty_tx;
+
+=09=09while ((bdp->cbd_sc & BD_AHDLC_TX_READY) =3D=3D 0) {
+=09=09=09if (si->tx_free =3D=3D TX_RING_SIZE)
+=09=09=09=09break;
+
+=09=09=09if (bdp->cbd_sc & BD_AHDLC_TX_CTS)
+=09=09=09=09must_restart =3D 1;
+
+=09=09=09si->stats.tx_packets++;
+
+=09=09=09/* Free the sk buffer associated with this last transmit.
+=09=09=09 */
+=09=09=09dev_kfree_skb_irq(si->tx_skbuff[si->skb_dirty]);
+=09=09=09si->skb_dirty =3D (si->skb_dirty + 1) & TX_RING_MOD_MASK;
+
+=09=09=09/* Update pointer to next buffer descriptor to be transmitted.
+=09=09=09 */
+=09=09=09if (bdp->cbd_sc & BD_AHDLC_TX_WRAP)
+=09=09=09=09bdp =3D si->tx_bd_base;
+=09=09=09else
+=09=09=09=09bdp++;
+
+=09=09=09/* Since we have freed up a buffer, the ring is no longer full.
+=09=09=09 */
+=09=09=09if (!si->tx_free++) {
+=09=09=09=09if (netif_queue_stopped(dev))
+=09=09=09=09=09netif_wake_queue(dev);
+=09=09=09}
+
+=09=09=09si->dirty_tx =3D (cbd_t *) bdp;
+
+=09=09=09if (si->newspeed) {
+=09=09=09=09mpc8xx_irda_set_speed(dev, si->newspeed);
+=09=09=09=09si->speed =3D si->newspeed;
+=09=09=09=09si->newspeed =3D 0;
+=09=09=09}
+=09=09}
+
+=09=09if (must_restart) {
+=09=09=09cpm8xx_t *cp =3D immr_map(im_cpm);
+=09=09=09printk(KERN_INFO "restart TX\n");
+
+=09=09=09/* Some transmit errors cause the transmitter to shut
+=09=09=09 * down.  We now issue a restart transmit.  Since the
+=09=09=09 * errors close the BD and update the pointers, the restart
+=09=09=09 * _should_ pick up without having to reset any of our
+=09=09=09 * pointers either.
+=09=09=09 */
+=09=09=09out_be16(&cp->cp_cpcr,
+=09=09=09    mk_cr_cmd(CPM_CR_CH_SCC2,
+=09=09=09=09      CPM_CR_RESTART_TX) | CPM_CR_FLG);
+=09=09=09while (in_be16(&cp->cp_cpcr) & CPM_CR_FLG) ;
You're busy looping in an interrupt handler, that's not really nice.
In general, I think this interrupt handler would deserve a bottom half
split since it looks quite busy.

+static struct device_driver m8xxir_driver =3D {
+=09.name =3D "fsl-cpm-scc:irda",
+=09.bus =3D &platform_bus_type,
+=09.probe =3D mpc8xx_irda_probe,
+=09.remove =3D mpc8xx_irda_remove,
+};
Why not a platform driver ?

Cheers,
Samuel.
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help