From: Marc Kleine-Budde <mkl@pengutronix.de>
To: Federico Vaga <federico.vaga@gmail.com>
Cc: Wolfgang Grandegger <wg@grandegger.com>,
Giancarlo Asnaghi <giancarlo.asnaghi@st.com>,
Alan Cox <alan@linux.intel.com>,
Alessandro Rubini <rubini@gnudd.com>,
linux-can@vger.kernel.org, netdev@vger.kernel.org,
linux-kernel@vger.kernel.org
Subject: Re: [PATCH RFC] c_can_pci: generic module for c_can on PCI
Date: Mon, 04 Jun 2012 16:04:39 +0200 [thread overview]
Message-ID: <4FCCC077.7000303@pengutronix.de> (raw)
In-Reply-To: <1338816766-7089-2-git-send-email-federico.vaga@gmail.com>
[-- Attachment #1: Type: text/plain, Size: 9563 bytes --]
On 06/04/2012 03:32 PM, Federico Vaga wrote:
> Signed-off-by: Federico Vaga <federico.vaga@gmail.com>
> Acked-by: Giancarlo Asnaghi <giancarlo.asnaghi@st.com>
> Cc: Alan Cox <alan@linux.intel.com>
Please port you driver to the recent c_can changes. Use the c_can branch
of the linux-can-next repo[1] as base for your work. You have to rework
the register access function. Please have a look if there are devm_
variants for the registration/mapping of the pci and clock.
[1] https://gitorious.org/linux-can/linux-can-next
More comments inline. Marc
> ---
> drivers/net/can/c_can/Kconfig | 11 +-
> drivers/net/can/c_can/Makefile | 1 +
> drivers/net/can/c_can/c_can_pci.c | 221 +++++++++++++++++++++++++++++++++++++
> 3 files changed, 230 insertions(+), 3 deletions(-)
> create mode 100644 drivers/net/can/c_can/c_can_pci.c
>
> diff --git a/drivers/net/can/c_can/Kconfig b/drivers/net/can/c_can/Kconfig
> index ffb9773..74ef97d 100644
> --- a/drivers/net/can/c_can/Kconfig
> +++ b/drivers/net/can/c_can/Kconfig
> @@ -2,14 +2,19 @@ menuconfig CAN_C_CAN
> tristate "Bosch C_CAN devices"
> depends on CAN_DEV && HAS_IOMEM
>
> -if CAN_C_CAN
please keep the if CAN_C_CAN...
> -
> config CAN_C_CAN_PLATFORM
> tristate "Generic Platform Bus based C_CAN driver"
> + depends on CAN_C_CAN
...then you don't have to add the depends on here.
> ---help---
> This driver adds support for the C_CAN chips connected to
> the "platform bus" (Linux abstraction for directly to the
> processor attached devices) which can be found on various
> boards from ST Microelectronics (http://www.st.com)
> like the SPEAr1310 and SPEAr320 evaluation boards.
> -endif
... Just move you pci driver inside the if...endif block...
> +
> +config CAN_C_CAN_PCI
> + tristate "Generic PCI Bus based C_CAN driver"
> + depends on CAN_C_CAN
...and remove the depends on CAN_C_CAN. You probably have to add a
depends on PCI.
> + ---help---
> + This driver adds support for the C_CAN chips connected to
> + the PCI bus.
> diff --git a/drivers/net/can/c_can/Makefile b/drivers/net/can/c_can/Makefile
> index 9273f6d..ad1cc84 100644
> --- a/drivers/net/can/c_can/Makefile
> +++ b/drivers/net/can/c_can/Makefile
> @@ -4,5 +4,6 @@
>
> obj-$(CONFIG_CAN_C_CAN) += c_can.o
> obj-$(CONFIG_CAN_C_CAN_PLATFORM) += c_can_platform.o
> +obj-$(CONFIG_CAN_C_CAN_PCI) += c_can_pci.o
>
> ccflags-$(CONFIG_CAN_DEBUG_DEVICES) := -DDEBUG
> diff --git a/drivers/net/can/c_can/c_can_pci.c b/drivers/net/can/c_can/c_can_pci.c
> new file mode 100644
> index 0000000..b635375
> --- /dev/null
> +++ b/drivers/net/can/c_can/c_can_pci.c
> @@ -0,0 +1,221 @@
> +/*
> + * Platform CAN bus driver for Bosch C_CAN controller
> + *
> + * Copyright (C) 2012 Federico Vaga <federico.vaga@gmail.com>
> + *
^^^ double space :)
> + * This file is licensed under the terms of the GNU General Public
> + * License version 2. This program is licensed "as is" without any
> + * warranty of any kind, whether express or implied.
> + */
> +
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/netdevice.h>
> +#include <linux/clk.h>
> +#include <linux/pci.h>
> +#include <linux/can/dev.h>
> +
> +#include "c_can.h"
> +
> +enum c_can_pci_reg_align {
> + C_CAN_REG_ALIGN_16,
> + C_CAN_REG_ALIGN_32,
> +};
> +
> +struct c_can_pci_data {
> + unsigned int reg_align; /* Set the register alignment in the memory */
^^^^^^^^^^^^
use the enum you defined above.
> + unsigned int freq; /* Set the frequency if clk is not usable */
> +};
> +
> +/*
> + * 16-bit c_can registers can be arranged differently in the memory
> + * architecture of different implementations. For example: 16-bit
> + * registers can be aligned to a 16-bit boundary or 32-bit boundary etc.
> + * Handle the same by providing a common read/write interface.
> + */
> +static u16 c_can_pci_read_reg_aligned_to_16bit(struct c_can_priv *priv,
> + void *reg)
> +{
> + return readw(reg);
> +}
> +
> +static void c_can_pci_write_reg_aligned_to_16bit(struct c_can_priv *priv,
> + void *reg, u16 val)
> +{
> + writew(val, reg);
> +}
> +
> +static u16 c_can_pci_read_reg_aligned_to_32bit(struct c_can_priv *priv,
> + void *reg)
> +{
> + return readw(reg + (long)reg - (long)priv->regs);
> +}
> +
> +static void c_can_pci_write_reg_aligned_to_32bit(struct c_can_priv *priv,
> + void *reg, u16 val)
> +{
> + writew(val, reg + (long)reg - (long)priv->regs);
> +}
> +
> +static int __devinit c_can_pci_probe(struct pci_dev *pdev,
> + const struct pci_device_id *ent)
> +{
> + struct c_can_pci_data *c_can_pci_data = (void *)ent->driver_data;
> + struct c_can_priv *priv;
> + struct net_device *dev;
> + void __iomem *addr;
> + struct clk *clk;
> + int ret;
> +
> + ret = pci_enable_device(pdev);
> + if (ret) {
> + dev_err(&pdev->dev, "pci_enable_device FAILED\n");
> + goto out;
> + }
> +
> + ret = pci_request_regions(pdev, KBUILD_MODNAME);
> + if (ret) {
> + dev_err(&pdev->dev, "pci_request_regions FAILED\n");
> + goto out_disable_device;
> + }
> +
> + pci_set_master(pdev);
> + pci_enable_msi(pdev);
> +
> + addr = pci_iomap(pdev, 0, pci_resource_len(pdev, 0));
> + if (!addr) {
> + dev_err(&pdev->dev,
> + "device has no PCI memory resources, "
> + "failing adapter\n");
> + ret = -ENOMEM;
> + goto out_release_regions;
> + }
> +
> + /* allocate the c_can device */
> + dev = alloc_c_can_dev();
> + if (!dev) {
> + ret = -ENOMEM;
> + goto out_iounmap;
> + }
> +
> + priv = netdev_priv(dev);
> + pci_set_drvdata(pdev, dev);
> + SET_NETDEV_DEV(dev, &pdev->dev);
> +
> + dev->irq = pdev->irq;
> + priv->regs = addr;
> +
> + if (!c_can_pci_data->freq) {
> + /* get the appropriate clk */
> + clk = clk_get(&pdev->dev, NULL);
> + if (IS_ERR(clk)) {
> + dev_err(&pdev->dev, "no clock defined\n");
> + ret = -ENODEV;
> + goto out_free_c_can;
> + }
> + priv->can.clock.freq = clk_get_rate(clk);
> + priv->priv = clk;
> + } else {
> + priv->can.clock.freq = c_can_pci_data->freq;
> + priv->priv = NULL;
> + }
> +
> + switch (c_can_pci_data->reg_align) {
> + case C_CAN_REG_ALIGN_32:
> + priv->read_reg = c_can_pci_read_reg_aligned_to_32bit;
> + priv->write_reg = c_can_pci_write_reg_aligned_to_32bit;
> + break;
> + case C_CAN_REG_ALIGN_16:
> + default:
> + priv->read_reg = c_can_pci_read_reg_aligned_to_16bit;
> + priv->write_reg = c_can_pci_write_reg_aligned_to_16bit;
> + break;
> + }
> +
> + ret = register_c_can_dev(dev);
> + if (ret) {
> + dev_err(&pdev->dev, "registering %s failed (err=%d)\n",
> + KBUILD_MODNAME, ret);
> + goto out_free_clock;
> + }
> +
> + dev_info(&pdev->dev, "%s device registered (regs=%p, irq=%d)\n",
> + KBUILD_MODNAME, priv->regs, dev->irq);
> +
> + return 0;
> +
> +out_free_clock:
> + if (!priv->priv)
^^^
looks fishy
> + clk_put(priv->priv);
> +out_free_c_can:
> + pci_set_drvdata(pdev, NULL);
> + free_c_can_dev(dev);
> +out_iounmap:
> + pci_iounmap(pdev, addr);
> +out_release_regions:
> + pci_disable_msi(pdev);
> + pci_clear_master(pdev);
> + pci_release_regions(pdev);
> +out_disable_device:
> + /*
> + * do not call pci_disable_device on sta2x11 because it
> + * break all other Bus masters on this EP
> + */
> + if(pdev->vendor == PCI_VENDOR_ID_STMICRO &&
> + pdev->device == PCI_DEVICE_ID_STMICRO_CAN)
> + goto out;
> + pci_disable_device(pdev);
> +out:
> + return ret;
> +}
> +
> +static void __devexit c_can_pci_remove(struct pci_dev *pdev)
> +{
> + struct net_device *dev = pci_get_drvdata(pdev);
> + struct c_can_priv *priv = netdev_priv(dev);
> +
> + pci_set_drvdata(pdev, NULL);
> + free_c_can_dev(dev);
> + if (!priv->priv)
dito
> + clk_put(priv->priv);
> + pci_iounmap(pdev, priv->regs);
> + pci_disable_msi(pdev);
> + pci_clear_master(pdev);
> + pci_release_regions(pdev);
> + /*
> + * do not call pci_disable_device on sta2x11 because it
> + * break all other Bus masters on this EP
> + */
> + if(pdev->vendor == PCI_VENDOR_ID_STMICRO &&
> + pdev->device == PCI_DEVICE_ID_STMICRO_CAN)
> + return;
> + pci_disable_device(pdev);
> +}
> +
> +static struct c_can_pci_data c_can_sta2x11= {
> + .reg_align = C_CAN_REG_ALIGN_32,
> + .freq = 52000000, /* 52 Mhz */
> +};
> +
> +#define C_CAN_ID(_vend, _dev, _driverdata) { \
> + PCI_DEVICE(_vend, _dev), \
> + .driver_data = (unsigned long)&_driverdata, \
> +}
> +DEFINE_PCI_DEVICE_TABLE(c_can_pci_tbl) = {
^^^^
static?
> + C_CAN_ID(PCI_VENDOR_ID_STMICRO, PCI_DEVICE_ID_STMICRO_CAN,
> + c_can_sta2x11),
> + {},
> +};
> +static struct pci_driver sta2x11_pci_driver = {
> + .name = KBUILD_MODNAME,
> + .id_table = c_can_pci_tbl,
> + .probe = c_can_pci_probe,
> + .remove = __devexit_p(c_can_pci_remove),
> +};
> +
> +module_pci_driver(sta2x11_pci_driver);
> +
> +MODULE_AUTHOR("Federico Vaga <federico.vaga@gmail.com>");
> +MODULE_LICENSE("GPL V2");
IIRC, the correct case is "GPL v2"
> +MODULE_DESCRIPTION("PCI CAN bus driver for Bosch C_CAN controller");
> +MODULE_DEVICE_TABLE(pci, c_can_pci_tbl);
--
Pengutronix e.K. | Marc Kleine-Budde |
Industrial Linux Solutions | Phone: +49-231-2826-924 |
Vertretung West/Dortmund | Fax: +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686 | http://www.pengutronix.de |
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 262 bytes --]
next prev parent reply other threads:[~2012-06-04 14:05 UTC|newest]
Thread overview: 28+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-05-17 20:59 [PATCH] STA2X11 CAN: CAN driver for the STA2X11 board Federico Vaga
2012-05-18 6:00 ` Wolfgang Grandegger
2012-05-26 8:36 ` Federico Vaga
2012-05-26 19:57 ` Wolfgang Grandegger
2012-06-04 13:32 ` generic module for c-can on pci Federico Vaga
2012-06-04 13:32 ` [PATCH RFC] c_can_pci: generic module for c_can on PCI Federico Vaga
2012-06-04 14:04 ` Marc Kleine-Budde [this message]
2012-06-12 14:25 ` Federico Vaga
2012-06-12 14:46 ` Marc Kleine-Budde
2012-06-12 14:53 ` Federico Vaga
2012-06-04 15:56 ` Alan Cox
2012-06-04 16:45 ` Alessandro Rubini
2012-06-11 13:51 ` Wolfgang Grandegger
2012-06-11 14:23 ` Alessandro Rubini
2012-06-04 16:45 ` Federico Vaga
2012-06-05 3:42 ` Bhupesh SHARMA
2012-06-05 11:19 ` Federico Vaga
2012-06-05 13:04 ` Bhupesh SHARMA
2012-06-05 13:13 ` Alessandro Rubini
2012-06-05 13:21 ` Marc Kleine-Budde
2012-06-05 13:30 ` Alessandro Rubini
2012-06-05 15:12 ` AnilKumar, Chimata
2012-06-05 16:50 ` Alessandro Rubini
2012-06-06 3:50 ` Bhupesh SHARMA
2012-06-11 13:18 ` Federico Vaga
2012-06-11 14:21 ` Wolfgang Grandegger
2012-06-05 13:22 ` Bhupesh SHARMA
2012-06-11 14:09 ` Wolfgang Grandegger
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4FCCC077.7000303@pengutronix.de \
--to=mkl@pengutronix.de \
--cc=alan@linux.intel.com \
--cc=federico.vaga@gmail.com \
--cc=giancarlo.asnaghi@st.com \
--cc=linux-can@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=netdev@vger.kernel.org \
--cc=rubini@gnudd.com \
--cc=wg@grandegger.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.