diff options
Diffstat (limited to 'drivers/net/irda')
-rw-r--r-- | drivers/net/irda/au1k_ir.c | 48 | ||||
-rw-r--r-- | drivers/net/irda/kingsun-sir.c | 4 | ||||
-rw-r--r-- | drivers/net/irda/vlsi_ir.c | 4 |
3 files changed, 50 insertions, 6 deletions
diff --git a/drivers/net/irda/au1k_ir.c b/drivers/net/irda/au1k_ir.c index 5f91e3e01c04..aab2cf72d025 100644 --- a/drivers/net/irda/au1k_ir.c +++ b/drivers/net/irda/au1k_ir.c @@ -18,6 +18,7 @@ * with this program; if not, see <http://www.gnu.org/licenses/>. */ +#include <linux/clk.h> #include <linux/module.h> #include <linux/netdevice.h> #include <linux/interrupt.h> @@ -175,6 +176,7 @@ struct au1k_private { struct resource *ioarea; struct au1k_irda_platform_data *platdata; + struct clk *irda_clk; }; static int qos_mtt_bits = 0x07; /* 1 ms or more */ @@ -514,9 +516,39 @@ static irqreturn_t au1k_irda_interrupt(int dummy, void *dev_id) static int au1k_init(struct net_device *dev) { struct au1k_private *aup = netdev_priv(dev); - u32 enable, ring_address; + u32 enable, ring_address, phyck; + struct clk *c; int i; + c = clk_get(NULL, "irda_clk"); + if (IS_ERR(c)) + return PTR_ERR(c); + i = clk_prepare_enable(c); + if (i) { + clk_put(c); + return i; + } + + switch (clk_get_rate(c)) { + case 40000000: + phyck = IR_PHYCLK_40MHZ; + break; + case 48000000: + phyck = IR_PHYCLK_48MHZ; + break; + case 56000000: + phyck = IR_PHYCLK_56MHZ; + break; + case 64000000: + phyck = IR_PHYCLK_64MHZ; + break; + default: + clk_disable_unprepare(c); + clk_put(c); + return -EINVAL; + } + aup->irda_clk = c; + enable = IR_HC | IR_CE | IR_C; #ifndef CONFIG_CPU_LITTLE_ENDIAN enable |= IR_BE; @@ -545,7 +577,7 @@ static int au1k_init(struct net_device *dev) irda_write(aup, IR_RING_SIZE, (RING_SIZE_64 << 8) | (RING_SIZE_64 << 12)); - irda_write(aup, IR_CONFIG_2, IR_PHYCLK_48MHZ | IR_ONE_PIN); + irda_write(aup, IR_CONFIG_2, phyck | IR_ONE_PIN); irda_write(aup, IR_RING_ADDR_CMPR, 0); au1k_irda_set_speed(dev, 9600); @@ -619,6 +651,9 @@ static int au1k_irda_stop(struct net_device *dev) free_irq(aup->irq_tx, dev); free_irq(aup->irq_rx, dev); + clk_disable_unprepare(aup->irda_clk); + clk_put(aup->irda_clk); + return 0; } @@ -853,6 +888,7 @@ static int au1k_irda_probe(struct platform_device *pdev) struct au1k_private *aup; struct net_device *dev; struct resource *r; + struct clk *c; int err; dev = alloc_irdadev(sizeof(struct au1k_private)); @@ -886,6 +922,14 @@ static int au1k_irda_probe(struct platform_device *pdev) if (!aup->ioarea) goto out; + /* bail out early if clock doesn't exist */ + c = clk_get(NULL, "irda_clk"); + if (IS_ERR(c)) { + err = PTR_ERR(c); + goto out; + } + clk_put(c); + aup->iobase = ioremap_nocache(r->start, resource_size(r)); if (!aup->iobase) goto out2; diff --git a/drivers/net/irda/kingsun-sir.c b/drivers/net/irda/kingsun-sir.c index 96fe3659012d..e638893e98a9 100644 --- a/drivers/net/irda/kingsun-sir.c +++ b/drivers/net/irda/kingsun-sir.c @@ -553,8 +553,8 @@ static int kingsun_probe(struct usb_interface *intf, return 0; free_mem: - if (kingsun->out_buf) kfree(kingsun->out_buf); - if (kingsun->in_buf) kfree(kingsun->in_buf); + kfree(kingsun->out_buf); + kfree(kingsun->in_buf); free_netdev(net); err_out1: return ret; diff --git a/drivers/net/irda/vlsi_ir.c b/drivers/net/irda/vlsi_ir.c index 485006604bbc..58ef59469dd0 100644 --- a/drivers/net/irda/vlsi_ir.c +++ b/drivers/net/irda/vlsi_ir.c @@ -485,13 +485,13 @@ static int vlsi_create_hwif(vlsi_irda_dev_t *idev) idev->virtaddr = NULL; idev->busaddr = 0; - ringarea = pci_alloc_consistent(idev->pdev, HW_RING_AREA_SIZE, &idev->busaddr); + ringarea = pci_zalloc_consistent(idev->pdev, HW_RING_AREA_SIZE, + &idev->busaddr); if (!ringarea) { IRDA_ERROR("%s: insufficient memory for descriptor rings\n", __func__); goto out; } - memset(ringarea, 0, HW_RING_AREA_SIZE); hwmap = (struct ring_descr_hw *)ringarea; idev->rx_ring = vlsi_alloc_ring(idev->pdev, hwmap, ringsize[1], |