Some blank line are unncessary, and one is missing after declaration.
This patch fix thoses style problems.
Signed-off-by: LABBE Corentin <[email protected]>
---
drivers/char/hw_random/amd-rng.c | 6 +-----
1 file changed, 1 insertion(+), 5 deletions(-)
diff --git a/drivers/char/hw_random/amd-rng.c b/drivers/char/hw_random/amd-rng.c
index 48f6a83..45b7965 100644
--- a/drivers/char/hw_random/amd-rng.c
+++ b/drivers/char/hw_random/amd-rng.c
@@ -31,10 +31,8 @@
#include <linux/delay.h>
#include <asm/io.h>
-
#define PFX KBUILD_MODNAME ": "
-
/*
* Data for PCI driver interface
*
@@ -52,7 +50,6 @@ MODULE_DEVICE_TABLE(pci, pci_tbl);
static struct pci_dev *amd_pdev;
-
static int amd_rng_data_present(struct hwrng *rng, int wait)
{
u32 pmbase = (u32)rng->priv;
@@ -100,7 +97,6 @@ static void amd_rng_cleanup(struct hwrng *rng)
pci_write_config_byte(amd_pdev, 0x40, rnen);
}
-
static struct hwrng amd_rng = {
.name = "amd",
.init = amd_rng_init,
@@ -109,7 +105,6 @@ static struct hwrng amd_rng = {
.data_read = amd_rng_data_read,
};
-
static int __init mod_init(void)
{
int err = -ENODEV;
@@ -157,6 +152,7 @@ out:
static void __exit mod_exit(void)
{
u32 pmbase = (unsigned long)amd_rng.priv;
+
release_region(pmbase + 0xF0, 8);
hwrng_unregister(&amd_rng);
}
--
2.7.3
checkpatch complains about <asm/io.h> used instead of linux/io.h.
In fact it is not needed.
This patch remove it, and in the process, alphabetize the other headers.
Signed-off-by: LABBE Corentin <[email protected]>
---
drivers/char/hw_random/amd-rng.c | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/drivers/char/hw_random/amd-rng.c b/drivers/char/hw_random/amd-rng.c
index d0a806a..9ddc99c 100644
--- a/drivers/char/hw_random/amd-rng.c
+++ b/drivers/char/hw_random/amd-rng.c
@@ -24,12 +24,11 @@
* warranty of any kind, whether express or implied.
*/
-#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/hw_random.h>
#include <linux/kernel.h>
+#include <linux/module.h>
#include <linux/pci.h>
-#include <linux/hw_random.h>
-#include <linux/delay.h>
-#include <asm/io.h>
#define DRV_NAME "AMD768-HWRNG"
--
2.7.3
The driver name is displayed each time differently.
This patch make use of the same name everywhere.
Signed-off-by: LABBE Corentin <[email protected]>
---
drivers/char/hw_random/amd-rng.c | 13 ++++++-------
1 file changed, 6 insertions(+), 7 deletions(-)
diff --git a/drivers/char/hw_random/amd-rng.c b/drivers/char/hw_random/amd-rng.c
index d0042f5..d0a806a 100644
--- a/drivers/char/hw_random/amd-rng.c
+++ b/drivers/char/hw_random/amd-rng.c
@@ -31,7 +31,7 @@
#include <linux/delay.h>
#include <asm/io.h>
-#define PFX KBUILD_MODNAME ": "
+#define DRV_NAME "AMD768-HWRNG"
/*
* Data for PCI driver interface
@@ -98,7 +98,7 @@ static void amd_rng_cleanup(struct hwrng *rng)
}
static struct hwrng amd_rng = {
- .name = "amd",
+ .name = DRV_NAME,
.init = amd_rng_init,
.cleanup = amd_rng_cleanup,
.data_present = amd_rng_data_present,
@@ -128,8 +128,8 @@ found:
pmbase &= 0x0000FF00;
if (pmbase == 0)
goto out;
- if (!request_region(pmbase + 0xF0, 8, "AMD HWRNG")) {
- dev_err(&pdev->dev, "AMD HWRNG region 0x%x already in use!\n",
+ if (!request_region(pmbase + 0xF0, 8, DRV_NAME)) {
+ dev_err(&pdev->dev, DRV_NAME " region 0x%x already in use!\n",
pmbase + 0xF0);
err = -EBUSY;
goto out;
@@ -137,11 +137,10 @@ found:
amd_rng.priv = (unsigned long)pmbase;
amd_pdev = pdev;
- pr_info("AMD768 RNG detected\n");
+ pr_info(DRV_NAME " detected\n");
err = hwrng_register(&amd_rng);
if (err) {
- pr_err(PFX "RNG registering failed (%d)\n",
- err);
+ pr_err(DRV_NAME " registering failed (%d)\n", err);
release_region(pmbase + 0xF0, 8);
goto out;
}
--
2.7.3
This patch add usage of the BIT() macro
Signed-off-by: LABBE Corentin <[email protected]>
---
drivers/char/hw_random/amd-rng.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/char/hw_random/amd-rng.c b/drivers/char/hw_random/amd-rng.c
index 45b7965..d0042f5 100644
--- a/drivers/char/hw_random/amd-rng.c
+++ b/drivers/char/hw_random/amd-rng.c
@@ -78,11 +78,11 @@ static int amd_rng_init(struct hwrng *rng)
u8 rnen;
pci_read_config_byte(amd_pdev, 0x40, &rnen);
- rnen |= (1 << 7); /* RNG on */
+ rnen |= BIT(7); /* RNG on */
pci_write_config_byte(amd_pdev, 0x40, rnen);
pci_read_config_byte(amd_pdev, 0x41, &rnen);
- rnen |= (1 << 7); /* PMIO enable */
+ rnen |= BIT(7); /* PMIO enable */
pci_write_config_byte(amd_pdev, 0x41, rnen);
return 0;
@@ -93,7 +93,7 @@ static void amd_rng_cleanup(struct hwrng *rng)
u8 rnen;
pci_read_config_byte(amd_pdev, 0x40, &rnen);
- rnen &= ~(1 << 7); /* RNG off */
+ rnen &= ~BIT(7); /* RNG off */
pci_write_config_byte(amd_pdev, 0x40, rnen);
}
--
2.7.3
This patch convert the hwrng interface used by amd768-rng to its new API
by replacing data_read()/data_present() by read().
Furthermore, Instead of having two global variable, it's better to use a
private struct. This will permit to remove amd_pdev variable.
Finally, Instead of accessing hw directly via pmbase, it's better to
access after ioport_map() via ioread32/iowrite32.
Signed-off-by: LABBE Corentin <[email protected]>
---
drivers/char/hw_random/amd-rng.c | 151 +++++++++++++++++++++++++--------------
1 file changed, 99 insertions(+), 52 deletions(-)
diff --git a/drivers/char/hw_random/amd-rng.c b/drivers/char/hw_random/amd-rng.c
index 9ddc99c..efdd853 100644
--- a/drivers/char/hw_random/amd-rng.c
+++ b/drivers/char/hw_random/amd-rng.c
@@ -32,6 +32,14 @@
#define DRV_NAME "AMD768-HWRNG"
+#define GEN_CFG_REG1 0x40
+#define GEN_CFG_REG2 0x41
+#define SMIO_SPACEPTR 0x58
+#define RNGDATA 0x00
+#define RNGDONE 0x04
+#define PMBASE_OFFSET 0xF0
+#define PMBASE_SIZE 8
+
/*
* Data for PCI driver interface
*
@@ -39,6 +47,7 @@
* PCI ids via MODULE_DEVICE_TABLE. We do not actually
* register a pci_driver, because someone else might one day
* want to register another driver on the same PCI id.
+ * Like i2c-amd756
*/
static const struct pci_device_id pci_tbl[] = {
{ PCI_VDEVICE(AMD, 0x7443), 0, },
@@ -47,112 +56,150 @@ static const struct pci_device_id pci_tbl[] = {
};
MODULE_DEVICE_TABLE(pci, pci_tbl);
-static struct pci_dev *amd_pdev;
+struct amd768_priv {
+ void __iomem *iobase;
+ struct pci_dev *pcidev;
+ u32 pmbase;
+};
-static int amd_rng_data_present(struct hwrng *rng, int wait)
+static int amd_rng_read(struct hwrng *rng, void *buf, size_t max, bool wait)
{
- u32 pmbase = (u32)rng->priv;
- int data, i;
-
- for (i = 0; i < 20; i++) {
- data = !!(inl(pmbase + 0xF4) & 1);
- if (data || !wait)
- break;
- udelay(10);
+ u32 *data = buf;
+ struct amd768_priv *priv = (struct amd768_priv *)rng->priv;
+ size_t read = 0;
+ /* We will wait at maximum one time per read */
+ int timeout = max / 4 + 1;
+
+ /*
+ * RNG data is available when RNGDONE is set to 1
+ * New random numbers are generated approximately 128 microseconds
+ * after RNGDATA is read
+ */
+ while (read < max) {
+ if (ioread32(priv->iobase + RNGDONE) == 0) {
+ if (wait) {
+ /* Delay given by datasheet */
+ usleep_range(128, 196);
+ if (timeout-- == 0)
+ return read;
+ } else {
+ return 0;
+ }
+ } else {
+ *data = ioread32(priv->iobase + RNGDATA);
+ data++;
+ read += 4;
+ }
}
- return data;
-}
-
-static int amd_rng_data_read(struct hwrng *rng, u32 *data)
-{
- u32 pmbase = (u32)rng->priv;
- *data = inl(pmbase + 0xF0);
-
- return 4;
+ return read;
}
static int amd_rng_init(struct hwrng *rng)
{
u8 rnen;
+ struct amd768_priv *priv = (struct amd768_priv *)rng->priv;
- pci_read_config_byte(amd_pdev, 0x40, &rnen);
+ pci_read_config_byte(priv->pcidev, GEN_CFG_REG1, &rnen);
rnen |= BIT(7); /* RNG on */
- pci_write_config_byte(amd_pdev, 0x40, rnen);
+ pci_write_config_byte(priv->pcidev, GEN_CFG_REG1, rnen);
- pci_read_config_byte(amd_pdev, 0x41, &rnen);
+ pci_read_config_byte(priv->pcidev, GEN_CFG_REG2, &rnen);
rnen |= BIT(7); /* PMIO enable */
- pci_write_config_byte(amd_pdev, 0x41, rnen);
-
+ pci_write_config_byte(priv->pcidev, GEN_CFG_REG2, rnen);
return 0;
}
static void amd_rng_cleanup(struct hwrng *rng)
{
u8 rnen;
+ struct amd768_priv *priv = (struct amd768_priv *)rng->priv;
- pci_read_config_byte(amd_pdev, 0x40, &rnen);
+ pci_read_config_byte(priv->pcidev, GEN_CFG_REG1, &rnen);
rnen &= ~BIT(7); /* RNG off */
- pci_write_config_byte(amd_pdev, 0x40, rnen);
+ pci_write_config_byte(priv->pcidev, GEN_CFG_REG1, rnen);
}
static struct hwrng amd_rng = {
.name = DRV_NAME,
+ .read = amd_rng_read,
.init = amd_rng_init,
.cleanup = amd_rng_cleanup,
- .data_present = amd_rng_data_present,
- .data_read = amd_rng_data_read,
};
-static int __init mod_init(void)
+static int mod_init(void)
{
- int err = -ENODEV;
+ int err;
struct pci_dev *pdev = NULL;
const struct pci_device_id *ent;
u32 pmbase;
+ struct amd768_priv *priv;
for_each_pci_dev(pdev) {
ent = pci_match_id(pci_tbl, pdev);
if (ent)
goto found;
}
- /* Device not found. */
- goto out;
-
+ return -ENODEV;
found:
- err = pci_read_config_dword(pdev, 0x58, &pmbase);
+
+ err = pci_read_config_dword(pdev, SMIO_SPACEPTR, &pmbase);
if (err)
- goto out;
- err = -EIO;
+ return err;
+
pmbase &= 0x0000FF00;
- if (pmbase == 0)
- goto out;
- if (!request_region(pmbase + 0xF0, 8, DRV_NAME)) {
- dev_err(&pdev->dev, DRV_NAME " region 0x%x already in use!\n",
- pmbase + 0xF0);
- err = -EBUSY;
- goto out;
+
+ priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
+ if (!request_region(pmbase + PMBASE_OFFSET, PMBASE_SIZE, DRV_NAME)) {
+ pr_err(DRV_NAME "region 0x%x already in use!\n", pmbase);
+ goto err_pmbase;
+ }
+
+ priv->iobase = ioport_map(pmbase + PMBASE_OFFSET, PMBASE_SIZE);
+ if (!priv->iobase) {
+ pr_err(DRV_NAME "Cannot map ioport\n");
+ err = -EINVAL;
+ goto err_iomap;
}
- amd_rng.priv = (unsigned long)pmbase;
- amd_pdev = pdev;
+
+ amd_rng.priv = (unsigned long)priv;
+ priv->pmbase = pmbase;
+ priv->pcidev = pdev;
pr_info(DRV_NAME " detected\n");
+
err = hwrng_register(&amd_rng);
if (err) {
- pr_err(DRV_NAME " registering failed (%d)\n", err);
- release_region(pmbase + 0xF0, 8);
- goto out;
+ pr_err(DRV_NAME "Cannot register HWRNG %d\n", err);
+ goto err_hwrng;
}
-out:
+ return 0;
+
+err_hwrng:
+ ioport_unmap(priv->iobase);
+err_iomap:
+ release_region(pmbase + PMBASE_OFFSET, PMBASE_SIZE);
+err_pmbase:
+ kfree(priv);
return err;
}
-static void __exit mod_exit(void)
+static void mod_exit(void)
{
- u32 pmbase = (unsigned long)amd_rng.priv;
+ struct amd768_priv *priv;
+
+ priv = (struct amd768_priv *)amd_rng.priv;
- release_region(pmbase + 0xF0, 8);
hwrng_unregister(&amd_rng);
+
+ ioport_unmap(priv->iobase);
+
+ release_region(priv->pmbase + PMBASE_OFFSET, PMBASE_SIZE);
+
+ kfree(priv);
}
module_init(mod_init);
--
2.7.3
On Fri, Aug 19, 2016 at 03:42:55PM +0200, LABBE Corentin wrote:
> The driver name is displayed each time differently.
> This patch make use of the same name everywhere.
>
> Signed-off-by: LABBE Corentin <[email protected]>
> ---
> drivers/char/hw_random/amd-rng.c | 13 ++++++-------
> 1 file changed, 6 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/char/hw_random/amd-rng.c b/drivers/char/hw_random/amd-rng.c
> index d0042f5..d0a806a 100644
> --- a/drivers/char/hw_random/amd-rng.c
> +++ b/drivers/char/hw_random/amd-rng.c
> @@ -31,7 +31,7 @@
> #include <linux/delay.h>
> #include <asm/io.h>
>
> -#define PFX KBUILD_MODNAME ": "
> +#define DRV_NAME "AMD768-HWRNG"
>
> /*
> * Data for PCI driver interface
> @@ -98,7 +98,7 @@ static void amd_rng_cleanup(struct hwrng *rng)
> }
>
> static struct hwrng amd_rng = {
> - .name = "amd",
> + .name = DRV_NAME,
Hmm, this changes a sysfs-exported name which has the potential
to break user-space. So I think you'd need to a stronger argument
to do it other than just cleaning it up.
Cheers,
--
Email: Herbert Xu <[email protected]>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
On Wed, Aug 24, 2016 at 06:58:11PM +0800, Herbert Xu wrote:
> On Fri, Aug 19, 2016 at 03:42:55PM +0200, LABBE Corentin wrote:
> > The driver name is displayed each time differently.
> > This patch make use of the same name everywhere.
> >
> > Signed-off-by: LABBE Corentin <[email protected]>
> > ---
> > drivers/char/hw_random/amd-rng.c | 13 ++++++-------
> > 1 file changed, 6 insertions(+), 7 deletions(-)
> >
> > diff --git a/drivers/char/hw_random/amd-rng.c b/drivers/char/hw_random/amd-rng.c
> > index d0042f5..d0a806a 100644
> > --- a/drivers/char/hw_random/amd-rng.c
> > +++ b/drivers/char/hw_random/amd-rng.c
> > @@ -31,7 +31,7 @@
> > #include <linux/delay.h>
> > #include <asm/io.h>
> >
> > -#define PFX KBUILD_MODNAME ": "
> > +#define DRV_NAME "AMD768-HWRNG"
> >
> > /*
> > * Data for PCI driver interface
> > @@ -98,7 +98,7 @@ static void amd_rng_cleanup(struct hwrng *rng)
> > }
> >
> > static struct hwrng amd_rng = {
> > - .name = "amd",
> > + .name = DRV_NAME,
>
> Hmm, this changes a sysfs-exported name which has the potential
> to break user-space. So I think you'd need to a stronger argument
> to do it other than just cleaning it up.
>
amd is really really too generic.
But if you still NACK that (and I understand perfectly why), I will update my series.
Regards
On Wed, Aug 24, 2016 at 03:51:22PM +0200, LABBE Corentin wrote:
> On Wed, Aug 24, 2016 at 06:58:11PM +0800, Herbert Xu wrote:
> > On Fri, Aug 19, 2016 at 03:42:55PM +0200, LABBE Corentin wrote:
> > > The driver name is displayed each time differently.
> > > This patch make use of the same name everywhere.
> > >
> > > Signed-off-by: LABBE Corentin <[email protected]>
> > > ---
> > > drivers/char/hw_random/amd-rng.c | 13 ++++++-------
> > > 1 file changed, 6 insertions(+), 7 deletions(-)
> > >
> > > diff --git a/drivers/char/hw_random/amd-rng.c b/drivers/char/hw_random/amd-rng.c
> > > index d0042f5..d0a806a 100644
> > > --- a/drivers/char/hw_random/amd-rng.c
> > > +++ b/drivers/char/hw_random/amd-rng.c
> > > @@ -31,7 +31,7 @@
> > > #include <linux/delay.h>
> > > #include <asm/io.h>
> > >
> > > -#define PFX KBUILD_MODNAME ": "
> > > +#define DRV_NAME "AMD768-HWRNG"
> > >
> > > /*
> > > * Data for PCI driver interface
> > > @@ -98,7 +98,7 @@ static void amd_rng_cleanup(struct hwrng *rng)
> > > }
> > >
> > > static struct hwrng amd_rng = {
> > > - .name = "amd",
> > > + .name = DRV_NAME,
> >
> > Hmm, this changes a sysfs-exported name which has the potential
> > to break user-space. So I think you'd need to a stronger argument
> > to do it other than just cleaning it up.
> >
>
> amd is really really too generic.
Well this would have been a good reason to change it before it
went into the kernel.
Cheers,
--
Email: Herbert Xu <[email protected]>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt