[PATCH] Revert "mmc: mxs: fix card detection in case of 'broken-cd' flag set"
This reverts commit 6f726f495f2d ("mmc: mxs: fix card detection in case of 'broken-cd' flag set"). Since mxs_mmc_probe always sets MMC_CAP_NEEDS_POLL unconditionally, card detect is not working properly any more since commit 6f726f495f2d. Instead of querying the card detect status mxs_mmc_get_cd now always returns 1 which causes probing commands being sent to the mmc card. The expected behaviour of commit 6f726f495f2d should be reachable by setting broken_cd instead. Signed-off-by: Michael Thalmeier --- drivers/mmc/host/mxs-mmc.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/mmc/host/mxs-mmc.c b/drivers/mmc/host/mxs-mmc.c index add1e70..cfdae61 100644 --- a/drivers/mmc/host/mxs-mmc.c +++ b/drivers/mmc/host/mxs-mmc.c @@ -86,8 +86,7 @@ static int mxs_mmc_get_cd(struct mmc_host *mmc) if (ret >= 0) return ret; - present = mmc->caps & MMC_CAP_NEEDS_POLL || - !(readl(ssp->base + HW_SSP_STATUS(ssp)) & + present = !(readl(ssp->base + HW_SSP_STATUS(ssp)) & BM_SSP_STATUS_CARD_DETECT); if (mmc->caps2 & MMC_CAP2_CD_ACTIVE_HIGH) -- 2.9.2
[PATCH] Revert "mmc: mxs: fix card detection in case of 'broken-cd' flag set"
This reverts commit 6f726f495f2d ("mmc: mxs: fix card detection in case of 'broken-cd' flag set"). Since mxs_mmc_probe always sets MMC_CAP_NEEDS_POLL unconditionally, card detect is not working properly any more since commit 6f726f495f2d. Instead of querying the card detect status mxs_mmc_get_cd now always returns 1 which causes probing commands being sent to the mmc card. The expected behaviour of commit 6f726f495f2d should be reachable by setting broken_cd instead. Signed-off-by: Michael Thalmeier --- drivers/mmc/host/mxs-mmc.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/mmc/host/mxs-mmc.c b/drivers/mmc/host/mxs-mmc.c index add1e70..cfdae61 100644 --- a/drivers/mmc/host/mxs-mmc.c +++ b/drivers/mmc/host/mxs-mmc.c @@ -86,8 +86,7 @@ static int mxs_mmc_get_cd(struct mmc_host *mmc) if (ret >= 0) return ret; - present = mmc->caps & MMC_CAP_NEEDS_POLL || - !(readl(ssp->base + HW_SSP_STATUS(ssp)) & + present = !(readl(ssp->base + HW_SSP_STATUS(ssp)) & BM_SSP_STATUS_CARD_DETECT); if (mmc->caps2 & MMC_CAP2_CD_ACTIVE_HIGH) -- 2.9.2
Re: [PATCH] rtc: rtc-stmp3xxx: detect power failure on backup power domain
On Thu, May 18, 2017 at 05:56:31PM +0200, Alexandre Belloni wrote: > Hi, > > On 18/05/2017 at 16:45:21 +0200, Michael Thalmeier wrote: > > To detect when the backup power domain has lost power a software defined bit > > is set in one of the general purpose persistent registers when writing a new > > time into the rtc. > > When reading the time this bit is checked to determine if a power fail has > > happened since the last time the rtc time was set. > > > > I'm kind of concerned that other people may want to use those register > for something else but I don't currently have anything better to > suggest. > > The other concern is that when updating the kernel, this will make amm > the rtc report that the time is invalid until the next update. So this > should be disabled by default. How would you think this is best to disable by default? With a config option or with a module parameter? Either way would also allow to make the bit mask in the PERSISTENT2 register configurable, so one can use whichever bit is still unused by some other applications. > > > When we detect a power fail we return -ENODATA. > > > > All the other drivers return -EINVAL in that case. > > > Signed-off-by: Michael Thalmeier <michael.thalme...@hale.at> > > --- > > drivers/rtc/rtc-stmp3xxx.c | 9 + > > 1 file changed, 9 insertions(+) > > > > diff --git a/drivers/rtc/rtc-stmp3xxx.c b/drivers/rtc/rtc-stmp3xxx.c > > index d578e40..51330ec 100644 > > --- a/drivers/rtc/rtc-stmp3xxx.c > > +++ b/drivers/rtc/rtc-stmp3xxx.c > > @@ -62,6 +62,9 @@ > > /* missing bitmask in headers */ > > #define STMP3XXX_RTC_PERSISTENT1_FORCE_UPDATER 0x8000 > > > > +#define STMP3XXX_RTC_PERSISTENT2 0x80 > > +#define STMP3XXX_RTC_PERSISTENT2_VALID_TIME0x01 > > + > > struct stmp3xxx_rtc_data { > > struct rtc_device *rtc; > > void __iomem *io; > > @@ -160,6 +163,10 @@ static int stmp3xxx_rtc_gettime(struct device *dev, > > struct rtc_time *rtc_tm) > > if (ret) > > return ret; > > > > + if (!(readl(rtc_data->io + STMP3XXX_RTC_PERSISTENT2) & > > + STMP3XXX_RTC_PERSISTENT2_VALID_TIME)) > > + return -ENODATA; > > + > > rtc_time_to_tm(readl(rtc_data->io + STMP3XXX_RTC_SECONDS), rtc_tm); > > return 0; > > } > > @@ -169,6 +176,8 @@ static int stmp3xxx_rtc_set_mmss(struct device *dev, > > unsigned long t) > > struct stmp3xxx_rtc_data *rtc_data = dev_get_drvdata(dev); > > > > writel(t, rtc_data->io + STMP3XXX_RTC_SECONDS); > > + writel(STMP3XXX_RTC_PERSISTENT2_VALID_TIME, > > + rtc_data->io + STMP3XXX_RTC_PERSISTENT2 + STMP_OFFSET_REG_SET); > > return stmp3xxx_wait_time(rtc_data); > > } > > > > -- > > 2.9.2 > > > > -- > Alexandre Belloni, Free Electrons > Embedded Linux and Kernel engineering > http://free-electrons.com -- Michael Thalmeier (Entwicklung) HALE electronic GmbH Eugen-Müller-Straße 18, 5020 Salzburg, Austria Tel: +43 (662) 439011 0 Fax: +43 (662) 439011 9 michael.thalme...@hale.at Firmenbuchnummer: FN 66801m HG Salzburg
Re: [PATCH] rtc: rtc-stmp3xxx: detect power failure on backup power domain
On Thu, May 18, 2017 at 05:56:31PM +0200, Alexandre Belloni wrote: > Hi, > > On 18/05/2017 at 16:45:21 +0200, Michael Thalmeier wrote: > > To detect when the backup power domain has lost power a software defined bit > > is set in one of the general purpose persistent registers when writing a new > > time into the rtc. > > When reading the time this bit is checked to determine if a power fail has > > happened since the last time the rtc time was set. > > > > I'm kind of concerned that other people may want to use those register > for something else but I don't currently have anything better to > suggest. > > The other concern is that when updating the kernel, this will make amm > the rtc report that the time is invalid until the next update. So this > should be disabled by default. How would you think this is best to disable by default? With a config option or with a module parameter? Either way would also allow to make the bit mask in the PERSISTENT2 register configurable, so one can use whichever bit is still unused by some other applications. > > > When we detect a power fail we return -ENODATA. > > > > All the other drivers return -EINVAL in that case. > > > Signed-off-by: Michael Thalmeier > > --- > > drivers/rtc/rtc-stmp3xxx.c | 9 + > > 1 file changed, 9 insertions(+) > > > > diff --git a/drivers/rtc/rtc-stmp3xxx.c b/drivers/rtc/rtc-stmp3xxx.c > > index d578e40..51330ec 100644 > > --- a/drivers/rtc/rtc-stmp3xxx.c > > +++ b/drivers/rtc/rtc-stmp3xxx.c > > @@ -62,6 +62,9 @@ > > /* missing bitmask in headers */ > > #define STMP3XXX_RTC_PERSISTENT1_FORCE_UPDATER 0x8000 > > > > +#define STMP3XXX_RTC_PERSISTENT2 0x80 > > +#define STMP3XXX_RTC_PERSISTENT2_VALID_TIME0x01 > > + > > struct stmp3xxx_rtc_data { > > struct rtc_device *rtc; > > void __iomem *io; > > @@ -160,6 +163,10 @@ static int stmp3xxx_rtc_gettime(struct device *dev, > > struct rtc_time *rtc_tm) > > if (ret) > > return ret; > > > > + if (!(readl(rtc_data->io + STMP3XXX_RTC_PERSISTENT2) & > > + STMP3XXX_RTC_PERSISTENT2_VALID_TIME)) > > + return -ENODATA; > > + > > rtc_time_to_tm(readl(rtc_data->io + STMP3XXX_RTC_SECONDS), rtc_tm); > > return 0; > > } > > @@ -169,6 +176,8 @@ static int stmp3xxx_rtc_set_mmss(struct device *dev, > > unsigned long t) > > struct stmp3xxx_rtc_data *rtc_data = dev_get_drvdata(dev); > > > > writel(t, rtc_data->io + STMP3XXX_RTC_SECONDS); > > + writel(STMP3XXX_RTC_PERSISTENT2_VALID_TIME, > > + rtc_data->io + STMP3XXX_RTC_PERSISTENT2 + STMP_OFFSET_REG_SET); > > return stmp3xxx_wait_time(rtc_data); > > } > > > > -- > > 2.9.2 > > > > -- > Alexandre Belloni, Free Electrons > Embedded Linux and Kernel engineering > http://free-electrons.com -- Michael Thalmeier (Entwicklung) HALE electronic GmbH Eugen-Müller-Straße 18, 5020 Salzburg, Austria Tel: +43 (662) 439011 0 Fax: +43 (662) 439011 9 michael.thalme...@hale.at Firmenbuchnummer: FN 66801m HG Salzburg
[PATCH] i2c: mxs: change error printing to debug for mxs_i2c_pio_wait_xfer_end
Instead of printing errors after mxs_i2c_pio_wait_xfer_end returns with an error code just print a debug message. NAKs and timeouts can occur in this situation normally, so do not treat them as errors. Signed-off-by: Michael Thalmeier <michael.thalme...@hale.at> --- drivers/i2c/busses/i2c-mxs.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/i2c/busses/i2c-mxs.c b/drivers/i2c/busses/i2c-mxs.c index 5738556..d4e8f19 100644 --- a/drivers/i2c/busses/i2c-mxs.c +++ b/drivers/i2c/busses/i2c-mxs.c @@ -419,7 +419,7 @@ static int mxs_i2c_pio_setup_xfer(struct i2c_adapter *adap, ret = mxs_i2c_pio_wait_xfer_end(i2c); if (ret) { - dev_err(i2c->dev, + dev_dbg(i2c->dev, "PIO: Failed to send SELECT command!\n"); goto cleanup; } @@ -431,7 +431,7 @@ static int mxs_i2c_pio_setup_xfer(struct i2c_adapter *adap, ret = mxs_i2c_pio_wait_xfer_end(i2c); if (ret) { - dev_err(i2c->dev, + dev_dbg(i2c->dev, "PIO: Failed to send READ command!\n"); goto cleanup; } @@ -528,7 +528,7 @@ static int mxs_i2c_pio_setup_xfer(struct i2c_adapter *adap, /* Wait for the end of the transfer. */ ret = mxs_i2c_pio_wait_xfer_end(i2c); if (ret) { - dev_err(i2c->dev, + dev_dbg(i2c->dev, "PIO: Failed to finish WRITE cmd!\n"); break; } -- 2.9.2
[PATCH] i2c: mxs: change error printing to debug for mxs_i2c_pio_wait_xfer_end
Instead of printing errors after mxs_i2c_pio_wait_xfer_end returns with an error code just print a debug message. NAKs and timeouts can occur in this situation normally, so do not treat them as errors. Signed-off-by: Michael Thalmeier --- drivers/i2c/busses/i2c-mxs.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/i2c/busses/i2c-mxs.c b/drivers/i2c/busses/i2c-mxs.c index 5738556..d4e8f19 100644 --- a/drivers/i2c/busses/i2c-mxs.c +++ b/drivers/i2c/busses/i2c-mxs.c @@ -419,7 +419,7 @@ static int mxs_i2c_pio_setup_xfer(struct i2c_adapter *adap, ret = mxs_i2c_pio_wait_xfer_end(i2c); if (ret) { - dev_err(i2c->dev, + dev_dbg(i2c->dev, "PIO: Failed to send SELECT command!\n"); goto cleanup; } @@ -431,7 +431,7 @@ static int mxs_i2c_pio_setup_xfer(struct i2c_adapter *adap, ret = mxs_i2c_pio_wait_xfer_end(i2c); if (ret) { - dev_err(i2c->dev, + dev_dbg(i2c->dev, "PIO: Failed to send READ command!\n"); goto cleanup; } @@ -528,7 +528,7 @@ static int mxs_i2c_pio_setup_xfer(struct i2c_adapter *adap, /* Wait for the end of the transfer. */ ret = mxs_i2c_pio_wait_xfer_end(i2c); if (ret) { - dev_err(i2c->dev, + dev_dbg(i2c->dev, "PIO: Failed to finish WRITE cmd!\n"); break; } -- 2.9.2
[PATCH] usb: chipidea: core: check before accessing ci_role in ci_role_show
ci_role BUGs when the role is >= CI_ROLE_END. This is the case while the role is changing. Signed-off-by: Michael Thalmeier <michael.thalme...@hale.at> --- drivers/usb/chipidea/core.c | 5 - 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c index 9e217b1..fe4fe24 100644 --- a/drivers/usb/chipidea/core.c +++ b/drivers/usb/chipidea/core.c @@ -843,7 +843,10 @@ static ssize_t ci_role_show(struct device *dev, struct device_attribute *attr, { struct ci_hdrc *ci = dev_get_drvdata(dev); - return sprintf(buf, "%s\n", ci_role(ci)->name); + if (ci->role != CI_ROLE_END) + return sprintf(buf, "%s\n", ci_role(ci)->name); + + return 0; } static ssize_t ci_role_store(struct device *dev, -- 2.9.2
[PATCH] usb: chipidea: core: check before accessing ci_role in ci_role_show
ci_role BUGs when the role is >= CI_ROLE_END. This is the case while the role is changing. Signed-off-by: Michael Thalmeier --- drivers/usb/chipidea/core.c | 5 - 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c index 9e217b1..fe4fe24 100644 --- a/drivers/usb/chipidea/core.c +++ b/drivers/usb/chipidea/core.c @@ -843,7 +843,10 @@ static ssize_t ci_role_show(struct device *dev, struct device_attribute *attr, { struct ci_hdrc *ci = dev_get_drvdata(dev); - return sprintf(buf, "%s\n", ci_role(ci)->name); + if (ci->role != CI_ROLE_END) + return sprintf(buf, "%s\n", ci_role(ci)->name); + + return 0; } static ssize_t ci_role_store(struct device *dev, -- 2.9.2
Re: [PATCH] usb: chipidea: debug: check before accessing ci_role
On Fri, May 19, 2017 at 09:15:40AM +0800, Peter Chen wrote: > On Thu, May 18, 2017 at 04:14:14PM +0200, Michael Thalmeier wrote: > > ci_role BUGs when the role is >= CI_ROLE_END. > > > > Signed-off-by: Michael Thalmeier <michael.thalme...@hale.at> > > --- > > drivers/usb/chipidea/debug.c | 3 ++- > > 1 file changed, 2 insertions(+), 1 deletion(-) > > > > diff --git a/drivers/usb/chipidea/debug.c b/drivers/usb/chipidea/debug.c > > index 6d23eed..1c31e8a 100644 > > --- a/drivers/usb/chipidea/debug.c > > +++ b/drivers/usb/chipidea/debug.c > > @@ -294,7 +294,8 @@ static int ci_role_show(struct seq_file *s, void *data) > > { > > struct ci_hdrc *ci = s->private; > > > > - seq_printf(s, "%s\n", ci_role(ci)->name); > > + if (ci->role != CI_ROLE_END) > > + seq_printf(s, "%s\n", ci_role(ci)->name); > > > > return 0; > > } > > By the way, how can you trigger this issue? It is quite easy to trigger. I have an USB OTG adapter cable connected to the micro-USB port of my device. When the cable is connected, the port has the "host" role. When disconnected, the role changes to "gadget". When polling (1 second interval) the role file while connecting/disconnecting the USB OTG cable, the error occurs within the first few tries. > Do you mind sending another patch to fix the same issue for ci_role_show > at core.c? I did not see, that there is now another place this is used. Will send a patch later. > > -- > > Best Regards, > Peter Chen Regards, Michael
Re: [PATCH] usb: chipidea: debug: check before accessing ci_role
On Fri, May 19, 2017 at 09:15:40AM +0800, Peter Chen wrote: > On Thu, May 18, 2017 at 04:14:14PM +0200, Michael Thalmeier wrote: > > ci_role BUGs when the role is >= CI_ROLE_END. > > > > Signed-off-by: Michael Thalmeier > > --- > > drivers/usb/chipidea/debug.c | 3 ++- > > 1 file changed, 2 insertions(+), 1 deletion(-) > > > > diff --git a/drivers/usb/chipidea/debug.c b/drivers/usb/chipidea/debug.c > > index 6d23eed..1c31e8a 100644 > > --- a/drivers/usb/chipidea/debug.c > > +++ b/drivers/usb/chipidea/debug.c > > @@ -294,7 +294,8 @@ static int ci_role_show(struct seq_file *s, void *data) > > { > > struct ci_hdrc *ci = s->private; > > > > - seq_printf(s, "%s\n", ci_role(ci)->name); > > + if (ci->role != CI_ROLE_END) > > + seq_printf(s, "%s\n", ci_role(ci)->name); > > > > return 0; > > } > > By the way, how can you trigger this issue? It is quite easy to trigger. I have an USB OTG adapter cable connected to the micro-USB port of my device. When the cable is connected, the port has the "host" role. When disconnected, the role changes to "gadget". When polling (1 second interval) the role file while connecting/disconnecting the USB OTG cable, the error occurs within the first few tries. > Do you mind sending another patch to fix the same issue for ci_role_show > at core.c? I did not see, that there is now another place this is used. Will send a patch later. > > -- > > Best Regards, > Peter Chen Regards, Michael
[PATCH] rtc: rtc-stmp3xxx: detect power failure on backup power domain
To detect when the backup power domain has lost power a software defined bit is set in one of the general purpose persistent registers when writing a new time into the rtc. When reading the time this bit is checked to determine if a power fail has happened since the last time the rtc time was set. When we detect a power fail we return -ENODATA. Signed-off-by: Michael Thalmeier <michael.thalme...@hale.at> --- drivers/rtc/rtc-stmp3xxx.c | 9 + 1 file changed, 9 insertions(+) diff --git a/drivers/rtc/rtc-stmp3xxx.c b/drivers/rtc/rtc-stmp3xxx.c index d578e40..51330ec 100644 --- a/drivers/rtc/rtc-stmp3xxx.c +++ b/drivers/rtc/rtc-stmp3xxx.c @@ -62,6 +62,9 @@ /* missing bitmask in headers */ #define STMP3XXX_RTC_PERSISTENT1_FORCE_UPDATER 0x8000 +#define STMP3XXX_RTC_PERSISTENT2 0x80 +#define STMP3XXX_RTC_PERSISTENT2_VALID_TIME0x01 + struct stmp3xxx_rtc_data { struct rtc_device *rtc; void __iomem *io; @@ -160,6 +163,10 @@ static int stmp3xxx_rtc_gettime(struct device *dev, struct rtc_time *rtc_tm) if (ret) return ret; + if (!(readl(rtc_data->io + STMP3XXX_RTC_PERSISTENT2) & + STMP3XXX_RTC_PERSISTENT2_VALID_TIME)) + return -ENODATA; + rtc_time_to_tm(readl(rtc_data->io + STMP3XXX_RTC_SECONDS), rtc_tm); return 0; } @@ -169,6 +176,8 @@ static int stmp3xxx_rtc_set_mmss(struct device *dev, unsigned long t) struct stmp3xxx_rtc_data *rtc_data = dev_get_drvdata(dev); writel(t, rtc_data->io + STMP3XXX_RTC_SECONDS); + writel(STMP3XXX_RTC_PERSISTENT2_VALID_TIME, + rtc_data->io + STMP3XXX_RTC_PERSISTENT2 + STMP_OFFSET_REG_SET); return stmp3xxx_wait_time(rtc_data); } -- 2.9.2
[PATCH] rtc: rtc-stmp3xxx: detect power failure on backup power domain
To detect when the backup power domain has lost power a software defined bit is set in one of the general purpose persistent registers when writing a new time into the rtc. When reading the time this bit is checked to determine if a power fail has happened since the last time the rtc time was set. When we detect a power fail we return -ENODATA. Signed-off-by: Michael Thalmeier --- drivers/rtc/rtc-stmp3xxx.c | 9 + 1 file changed, 9 insertions(+) diff --git a/drivers/rtc/rtc-stmp3xxx.c b/drivers/rtc/rtc-stmp3xxx.c index d578e40..51330ec 100644 --- a/drivers/rtc/rtc-stmp3xxx.c +++ b/drivers/rtc/rtc-stmp3xxx.c @@ -62,6 +62,9 @@ /* missing bitmask in headers */ #define STMP3XXX_RTC_PERSISTENT1_FORCE_UPDATER 0x8000 +#define STMP3XXX_RTC_PERSISTENT2 0x80 +#define STMP3XXX_RTC_PERSISTENT2_VALID_TIME0x01 + struct stmp3xxx_rtc_data { struct rtc_device *rtc; void __iomem *io; @@ -160,6 +163,10 @@ static int stmp3xxx_rtc_gettime(struct device *dev, struct rtc_time *rtc_tm) if (ret) return ret; + if (!(readl(rtc_data->io + STMP3XXX_RTC_PERSISTENT2) & + STMP3XXX_RTC_PERSISTENT2_VALID_TIME)) + return -ENODATA; + rtc_time_to_tm(readl(rtc_data->io + STMP3XXX_RTC_SECONDS), rtc_tm); return 0; } @@ -169,6 +176,8 @@ static int stmp3xxx_rtc_set_mmss(struct device *dev, unsigned long t) struct stmp3xxx_rtc_data *rtc_data = dev_get_drvdata(dev); writel(t, rtc_data->io + STMP3XXX_RTC_SECONDS); + writel(STMP3XXX_RTC_PERSISTENT2_VALID_TIME, + rtc_data->io + STMP3XXX_RTC_PERSISTENT2 + STMP_OFFSET_REG_SET); return stmp3xxx_wait_time(rtc_data); } -- 2.9.2
[PATCH] usb: chipidea: debug: check before accessing ci_role
ci_role BUGs when the role is >= CI_ROLE_END. Signed-off-by: Michael Thalmeier <michael.thalme...@hale.at> --- drivers/usb/chipidea/debug.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/usb/chipidea/debug.c b/drivers/usb/chipidea/debug.c index 6d23eed..1c31e8a 100644 --- a/drivers/usb/chipidea/debug.c +++ b/drivers/usb/chipidea/debug.c @@ -294,7 +294,8 @@ static int ci_role_show(struct seq_file *s, void *data) { struct ci_hdrc *ci = s->private; - seq_printf(s, "%s\n", ci_role(ci)->name); + if (ci->role != CI_ROLE_END) + seq_printf(s, "%s\n", ci_role(ci)->name); return 0; } -- 2.9.2
[PATCH] i2c: mxs: dont print error on NAK
When mxs_i2c_pio_wait_xfer_end returns with a return code of -ENXIO, the NO_SLAVE_ACK_IRQ bit is set in CTRL1. In this case, do not print an error message, because every NAK would otherwise generate a new message. Signed-off-by: Michael Thalmeier <michael.thalme...@hale.at> --- drivers/i2c/busses/i2c-mxs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/i2c/busses/i2c-mxs.c b/drivers/i2c/busses/i2c-mxs.c index 5738556..e2dbb9c 100644 --- a/drivers/i2c/busses/i2c-mxs.c +++ b/drivers/i2c/busses/i2c-mxs.c @@ -527,7 +527,7 @@ static int mxs_i2c_pio_setup_xfer(struct i2c_adapter *adap, /* Wait for the end of the transfer. */ ret = mxs_i2c_pio_wait_xfer_end(i2c); - if (ret) { + if (ret && ret != -ENXIO) { dev_err(i2c->dev, "PIO: Failed to finish WRITE cmd!\n"); break; -- 2.9.2
[PATCH] i2c: mxs: dont print error on NAK
When mxs_i2c_pio_wait_xfer_end returns with a return code of -ENXIO, the NO_SLAVE_ACK_IRQ bit is set in CTRL1. In this case, do not print an error message, because every NAK would otherwise generate a new message. Signed-off-by: Michael Thalmeier --- drivers/i2c/busses/i2c-mxs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/i2c/busses/i2c-mxs.c b/drivers/i2c/busses/i2c-mxs.c index 5738556..e2dbb9c 100644 --- a/drivers/i2c/busses/i2c-mxs.c +++ b/drivers/i2c/busses/i2c-mxs.c @@ -527,7 +527,7 @@ static int mxs_i2c_pio_setup_xfer(struct i2c_adapter *adap, /* Wait for the end of the transfer. */ ret = mxs_i2c_pio_wait_xfer_end(i2c); - if (ret) { + if (ret && ret != -ENXIO) { dev_err(i2c->dev, "PIO: Failed to finish WRITE cmd!\n"); break; -- 2.9.2
[PATCH] usb: chipidea: debug: check before accessing ci_role
ci_role BUGs when the role is >= CI_ROLE_END. Signed-off-by: Michael Thalmeier --- drivers/usb/chipidea/debug.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/usb/chipidea/debug.c b/drivers/usb/chipidea/debug.c index 6d23eed..1c31e8a 100644 --- a/drivers/usb/chipidea/debug.c +++ b/drivers/usb/chipidea/debug.c @@ -294,7 +294,8 @@ static int ci_role_show(struct seq_file *s, void *data) { struct ci_hdrc *ci = s->private; - seq_printf(s, "%s\n", ci_role(ci)->name); + if (ci->role != CI_ROLE_END) + seq_printf(s, "%s\n", ci_role(ci)->name); return 0; } -- 2.9.2
[PATCH 07/11] NFC: pn533: improve cmd queue handling
Make sure cmd is set before a frame is passed to the transport layer for sending. In addition pn533_send_async_complete checks if cmd is set before accessing its members. Signed-off-by: Michael Thalmeier <michael.thalme...@hale.at> --- drivers/nfc/pn533/pn533.c | 54 +-- 1 file changed, 34 insertions(+), 20 deletions(-) diff --git a/drivers/nfc/pn533/pn533.c b/drivers/nfc/pn533/pn533.c index d9c5583..d1cc70a 100644 --- a/drivers/nfc/pn533/pn533.c +++ b/drivers/nfc/pn533/pn533.c @@ -383,26 +383,36 @@ static void pn533_build_cmd_frame(struct pn533 *dev, u8 cmd_code, static int pn533_send_async_complete(struct pn533 *dev) { struct pn533_cmd *cmd = dev->cmd; - int status = cmd->status; + int rc = 0; - struct sk_buff *req = cmd->req; - struct sk_buff *resp = cmd->resp; + if (cmd) { + int status = cmd->status; - int rc; + struct sk_buff *req = cmd->req; + struct sk_buff *resp = cmd->resp; - dev_kfree_skb(req); + dev_kfree_skb(req); - if (status < 0) { - rc = cmd->complete_cb(dev, cmd->complete_cb_context, - ERR_PTR(status)); - dev_kfree_skb(resp); - goto done; - } + if (status < 0) { + rc = cmd->complete_cb(dev, cmd->complete_cb_context, + ERR_PTR(status)); + dev_kfree_skb(resp); + goto done; + } + + /* when no response is set we got interrupted */ + if (!resp) + resp = ERR_PTR(-EINTR); - skb_pull(resp, dev->ops->rx_header_len); - skb_trim(resp, resp->len - dev->ops->rx_tail_len); + if (!IS_ERR(resp)) { + skb_pull(resp, dev->ops->rx_header_len); + skb_trim(resp, resp->len - dev->ops->rx_tail_len); + } - rc = cmd->complete_cb(dev, cmd->complete_cb_context, resp); + rc = cmd->complete_cb(dev, cmd->complete_cb_context, resp); + } else { + dev_dbg(dev->dev, "%s: cmd not set\n", __func__); + } done: kfree(cmd); @@ -434,12 +444,14 @@ static int __pn533_send_async(struct pn533 *dev, u8 cmd_code, mutex_lock(>cmd_lock); if (!dev->cmd_pending) { + dev->cmd = cmd; rc = dev->phy_ops->send_frame(dev, req); - if (rc) + if (rc) { + dev->cmd = NULL; goto error; + } dev->cmd_pending = 1; - dev->cmd = cmd; goto unlock; } @@ -511,11 +523,12 @@ static int pn533_send_cmd_direct_async(struct pn533 *dev, u8 cmd_code, pn533_build_cmd_frame(dev, cmd_code, req); + dev->cmd = cmd; rc = dev->phy_ops->send_frame(dev, req); - if (rc < 0) + if (rc < 0) { + dev->cmd = NULL; kfree(cmd); - else - dev->cmd = cmd; + } return rc; } @@ -550,14 +563,15 @@ static void pn533_wq_cmd(struct work_struct *work) mutex_unlock(>cmd_lock); + dev->cmd = cmd; rc = dev->phy_ops->send_frame(dev, cmd->req); if (rc < 0) { + dev->cmd = NULL; dev_kfree_skb(cmd->req); kfree(cmd); return; } - dev->cmd = cmd; } struct pn533_sync_cmd_response { -- 2.5.5
[PATCH 07/11] NFC: pn533: improve cmd queue handling
Make sure cmd is set before a frame is passed to the transport layer for sending. In addition pn533_send_async_complete checks if cmd is set before accessing its members. Signed-off-by: Michael Thalmeier --- drivers/nfc/pn533/pn533.c | 54 +-- 1 file changed, 34 insertions(+), 20 deletions(-) diff --git a/drivers/nfc/pn533/pn533.c b/drivers/nfc/pn533/pn533.c index d9c5583..d1cc70a 100644 --- a/drivers/nfc/pn533/pn533.c +++ b/drivers/nfc/pn533/pn533.c @@ -383,26 +383,36 @@ static void pn533_build_cmd_frame(struct pn533 *dev, u8 cmd_code, static int pn533_send_async_complete(struct pn533 *dev) { struct pn533_cmd *cmd = dev->cmd; - int status = cmd->status; + int rc = 0; - struct sk_buff *req = cmd->req; - struct sk_buff *resp = cmd->resp; + if (cmd) { + int status = cmd->status; - int rc; + struct sk_buff *req = cmd->req; + struct sk_buff *resp = cmd->resp; - dev_kfree_skb(req); + dev_kfree_skb(req); - if (status < 0) { - rc = cmd->complete_cb(dev, cmd->complete_cb_context, - ERR_PTR(status)); - dev_kfree_skb(resp); - goto done; - } + if (status < 0) { + rc = cmd->complete_cb(dev, cmd->complete_cb_context, + ERR_PTR(status)); + dev_kfree_skb(resp); + goto done; + } + + /* when no response is set we got interrupted */ + if (!resp) + resp = ERR_PTR(-EINTR); - skb_pull(resp, dev->ops->rx_header_len); - skb_trim(resp, resp->len - dev->ops->rx_tail_len); + if (!IS_ERR(resp)) { + skb_pull(resp, dev->ops->rx_header_len); + skb_trim(resp, resp->len - dev->ops->rx_tail_len); + } - rc = cmd->complete_cb(dev, cmd->complete_cb_context, resp); + rc = cmd->complete_cb(dev, cmd->complete_cb_context, resp); + } else { + dev_dbg(dev->dev, "%s: cmd not set\n", __func__); + } done: kfree(cmd); @@ -434,12 +444,14 @@ static int __pn533_send_async(struct pn533 *dev, u8 cmd_code, mutex_lock(>cmd_lock); if (!dev->cmd_pending) { + dev->cmd = cmd; rc = dev->phy_ops->send_frame(dev, req); - if (rc) + if (rc) { + dev->cmd = NULL; goto error; + } dev->cmd_pending = 1; - dev->cmd = cmd; goto unlock; } @@ -511,11 +523,12 @@ static int pn533_send_cmd_direct_async(struct pn533 *dev, u8 cmd_code, pn533_build_cmd_frame(dev, cmd_code, req); + dev->cmd = cmd; rc = dev->phy_ops->send_frame(dev, req); - if (rc < 0) + if (rc < 0) { + dev->cmd = NULL; kfree(cmd); - else - dev->cmd = cmd; + } return rc; } @@ -550,14 +563,15 @@ static void pn533_wq_cmd(struct work_struct *work) mutex_unlock(>cmd_lock); + dev->cmd = cmd; rc = dev->phy_ops->send_frame(dev, cmd->req); if (rc < 0) { + dev->cmd = NULL; dev_kfree_skb(cmd->req); kfree(cmd); return; } - dev->cmd = cmd; } struct pn533_sync_cmd_response { -- 2.5.5
[PATCH 11/11] nfc: pn533: increase clock frequency for PN532
Default clock frequency of PN532 is 6.78 MHz. Increase the frequency to 27.12 MHz to increase throughput. Signed-off-by: Michael Thalmeier <michael.thalme...@hale.at> --- drivers/nfc/pn533/pn533.c | 70 +++ drivers/nfc/pn533/pn533.h | 2 ++ 2 files changed, 72 insertions(+) diff --git a/drivers/nfc/pn533/pn533.c b/drivers/nfc/pn533/pn533.c index 44bc5e0..19ee4ba 100644 --- a/drivers/nfc/pn533/pn533.c +++ b/drivers/nfc/pn533/pn533.c @@ -2469,6 +2469,63 @@ static int pn532_sam_configuration(struct nfc_dev *nfc_dev) return 0; } +#define PN533_CFR_27 0x00 +#define PN533_CFR_13 0x01 +#define PN533_CFR_60x02 + +static int pn533_get_cfr(struct nfc_dev *nfc_dev) +{ + struct pn533 *dev = nfc_get_drvdata(nfc_dev); + struct sk_buff *skb; + struct sk_buff *resp; + int clk; + + dev_dbg(dev->dev, "%s\n", __func__); + + skb = pn533_alloc_skb(dev, 2); + if (!skb) + return -ENOMEM; + + *skb_put(skb, 1) = 0x02; + *skb_put(skb, 1) = 0xFF; + + resp = pn533_send_cmd_sync(dev, PN533_CMD_READ_REGISTER, skb); + if (IS_ERR(resp)) + return PTR_ERR(resp); + + if (resp->len != 1) + return -EINVAL; + + clk = resp->data[0]; + + dev_kfree_skb(resp); + return clk; +} + +static int pn533_set_cfr(struct nfc_dev *nfc_dev, int clk) +{ + struct pn533 *dev = nfc_get_drvdata(nfc_dev); + struct sk_buff *skb; + struct sk_buff *resp; + + dev_dbg(dev->dev, "%s\n", __func__); + + skb = pn533_alloc_skb(dev, 3); + if (!skb) + return -ENOMEM; + + *skb_put(skb, 1) = 0x02; + *skb_put(skb, 1) = 0xFF; + *skb_put(skb, 1) = clk & 0x03; + + resp = pn533_send_cmd_sync(dev, PN533_CMD_WRITE_REGISTER, skb); + if (IS_ERR(resp)) + return PTR_ERR(resp); + + dev_kfree_skb(resp); + return 0; +} + static int pn533_dev_up(struct nfc_dev *nfc_dev) { struct pn533 *dev = nfc_get_drvdata(nfc_dev); @@ -2478,6 +2535,10 @@ static int pn533_dev_up(struct nfc_dev *nfc_dev) if (rc) return rc; + + rc = pn533_set_cfr(nfc_dev, PN533_CFR_27); + if (rc) + return rc; } return pn533_rf_field(nfc_dev, 1); @@ -2485,6 +2546,15 @@ static int pn533_dev_up(struct nfc_dev *nfc_dev) static int pn533_dev_down(struct nfc_dev *nfc_dev) { + struct pn533 *dev = nfc_get_drvdata(nfc_dev); + + if (dev->device_type == PN533_DEVICE_PN532) { + int rc = pn533_set_cfr(nfc_dev, PN533_CFR_6); + + if (rc) + return rc; + } + return pn533_rf_field(nfc_dev, 0); } diff --git a/drivers/nfc/pn533/pn533.h b/drivers/nfc/pn533/pn533.h index 553c7d1..2bd3816 100644 --- a/drivers/nfc/pn533/pn533.h +++ b/drivers/nfc/pn533/pn533.h @@ -74,6 +74,8 @@ #define PN533_FRAME_CMD(f) (f->data[1]) #define PN533_CMD_GET_FIRMWARE_VERSION 0x02 +#define PN533_CMD_READ_REGISTER 0x06 +#define PN533_CMD_WRITE_REGISTER 0x08 #define PN533_CMD_SAM_CONFIGURATION 0x14 #define PN533_CMD_RF_CONFIGURATION 0x32 #define PN533_CMD_IN_DATA_EXCHANGE 0x40 -- 2.5.5
[PATCH 11/11] nfc: pn533: increase clock frequency for PN532
Default clock frequency of PN532 is 6.78 MHz. Increase the frequency to 27.12 MHz to increase throughput. Signed-off-by: Michael Thalmeier --- drivers/nfc/pn533/pn533.c | 70 +++ drivers/nfc/pn533/pn533.h | 2 ++ 2 files changed, 72 insertions(+) diff --git a/drivers/nfc/pn533/pn533.c b/drivers/nfc/pn533/pn533.c index 44bc5e0..19ee4ba 100644 --- a/drivers/nfc/pn533/pn533.c +++ b/drivers/nfc/pn533/pn533.c @@ -2469,6 +2469,63 @@ static int pn532_sam_configuration(struct nfc_dev *nfc_dev) return 0; } +#define PN533_CFR_27 0x00 +#define PN533_CFR_13 0x01 +#define PN533_CFR_60x02 + +static int pn533_get_cfr(struct nfc_dev *nfc_dev) +{ + struct pn533 *dev = nfc_get_drvdata(nfc_dev); + struct sk_buff *skb; + struct sk_buff *resp; + int clk; + + dev_dbg(dev->dev, "%s\n", __func__); + + skb = pn533_alloc_skb(dev, 2); + if (!skb) + return -ENOMEM; + + *skb_put(skb, 1) = 0x02; + *skb_put(skb, 1) = 0xFF; + + resp = pn533_send_cmd_sync(dev, PN533_CMD_READ_REGISTER, skb); + if (IS_ERR(resp)) + return PTR_ERR(resp); + + if (resp->len != 1) + return -EINVAL; + + clk = resp->data[0]; + + dev_kfree_skb(resp); + return clk; +} + +static int pn533_set_cfr(struct nfc_dev *nfc_dev, int clk) +{ + struct pn533 *dev = nfc_get_drvdata(nfc_dev); + struct sk_buff *skb; + struct sk_buff *resp; + + dev_dbg(dev->dev, "%s\n", __func__); + + skb = pn533_alloc_skb(dev, 3); + if (!skb) + return -ENOMEM; + + *skb_put(skb, 1) = 0x02; + *skb_put(skb, 1) = 0xFF; + *skb_put(skb, 1) = clk & 0x03; + + resp = pn533_send_cmd_sync(dev, PN533_CMD_WRITE_REGISTER, skb); + if (IS_ERR(resp)) + return PTR_ERR(resp); + + dev_kfree_skb(resp); + return 0; +} + static int pn533_dev_up(struct nfc_dev *nfc_dev) { struct pn533 *dev = nfc_get_drvdata(nfc_dev); @@ -2478,6 +2535,10 @@ static int pn533_dev_up(struct nfc_dev *nfc_dev) if (rc) return rc; + + rc = pn533_set_cfr(nfc_dev, PN533_CFR_27); + if (rc) + return rc; } return pn533_rf_field(nfc_dev, 1); @@ -2485,6 +2546,15 @@ static int pn533_dev_up(struct nfc_dev *nfc_dev) static int pn533_dev_down(struct nfc_dev *nfc_dev) { + struct pn533 *dev = nfc_get_drvdata(nfc_dev); + + if (dev->device_type == PN533_DEVICE_PN532) { + int rc = pn533_set_cfr(nfc_dev, PN533_CFR_6); + + if (rc) + return rc; + } + return pn533_rf_field(nfc_dev, 0); } diff --git a/drivers/nfc/pn533/pn533.h b/drivers/nfc/pn533/pn533.h index 553c7d1..2bd3816 100644 --- a/drivers/nfc/pn533/pn533.h +++ b/drivers/nfc/pn533/pn533.h @@ -74,6 +74,8 @@ #define PN533_FRAME_CMD(f) (f->data[1]) #define PN533_CMD_GET_FIRMWARE_VERSION 0x02 +#define PN533_CMD_READ_REGISTER 0x06 +#define PN533_CMD_WRITE_REGISTER 0x08 #define PN533_CMD_SAM_CONFIGURATION 0x14 #define PN533_CMD_RF_CONFIGURATION 0x32 #define PN533_CMD_IN_DATA_EXCHANGE 0x40 -- 2.5.5
[PATCH 04/11] NFC: pn533: reset poll modulation list before calling nfc_targets_found
We need to reset the poll modulation list before calling nfc_targets_found because otherwise it is possible that the application is scheduled to run before the modulation list is cleared and gets an error "Cannot activate target while polling" upon calling activate_target. Signed-off-by: Michael Thalmeier <michael.thalme...@hale.at> --- drivers/nfc/pn533/pn533.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/nfc/pn533/pn533.c b/drivers/nfc/pn533/pn533.c index d82eecd..745181e 100644 --- a/drivers/nfc/pn533/pn533.c +++ b/drivers/nfc/pn533/pn533.c @@ -865,6 +865,7 @@ static int pn533_target_found_type_b(struct nfc_target *nfc_tgt, u8 *tgt_data, return 0; } +static void pn533_poll_reset_mod_list(struct pn533 *dev); static int pn533_target_found(struct pn533 *dev, u8 tg, u8 *tgdata, int tgdata_len) { @@ -914,6 +915,7 @@ static int pn533_target_found(struct pn533 *dev, u8 tg, u8 *tgdata, dev->tgt_available_prots = nfc_tgt.supported_protocols; + pn533_poll_reset_mod_list(dev); nfc_targets_found(dev->nfc_dev, _tgt, 1); return 0; @@ -980,10 +982,8 @@ static int pn533_start_poll_complete(struct pn533 *dev, struct sk_buff *resp) rc = pn533_target_found(dev, tg, tgdata, tgdata_len); /* We must stop the poll after a valid target found */ - if (rc == 0) { - pn533_poll_reset_mod_list(dev); + if (rc == 0) return 0; - } } return -EAGAIN; -- 2.5.5
[PATCH 04/11] NFC: pn533: reset poll modulation list before calling nfc_targets_found
We need to reset the poll modulation list before calling nfc_targets_found because otherwise it is possible that the application is scheduled to run before the modulation list is cleared and gets an error "Cannot activate target while polling" upon calling activate_target. Signed-off-by: Michael Thalmeier --- drivers/nfc/pn533/pn533.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/nfc/pn533/pn533.c b/drivers/nfc/pn533/pn533.c index d82eecd..745181e 100644 --- a/drivers/nfc/pn533/pn533.c +++ b/drivers/nfc/pn533/pn533.c @@ -865,6 +865,7 @@ static int pn533_target_found_type_b(struct nfc_target *nfc_tgt, u8 *tgt_data, return 0; } +static void pn533_poll_reset_mod_list(struct pn533 *dev); static int pn533_target_found(struct pn533 *dev, u8 tg, u8 *tgdata, int tgdata_len) { @@ -914,6 +915,7 @@ static int pn533_target_found(struct pn533 *dev, u8 tg, u8 *tgdata, dev->tgt_available_prots = nfc_tgt.supported_protocols; + pn533_poll_reset_mod_list(dev); nfc_targets_found(dev->nfc_dev, _tgt, 1); return 0; @@ -980,10 +982,8 @@ static int pn533_start_poll_complete(struct pn533 *dev, struct sk_buff *resp) rc = pn533_target_found(dev, tg, tgdata, tgdata_len); /* We must stop the poll after a valid target found */ - if (rc == 0) { - pn533_poll_reset_mod_list(dev); + if (rc == 0) return 0; - } } return -EAGAIN; -- 2.5.5
[PATCH 08/11] NFC: pn533: reduce output when stopping poll
Handle return codes for stopped polling operations better to reduce logging activity. Signed-off-by: Michael Thalmeier <michael.thalme...@hale.at> --- drivers/nfc/pn533/pn533.c | 8 +++- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/drivers/nfc/pn533/pn533.c b/drivers/nfc/pn533/pn533.c index d1cc70a..c06d22f 100644 --- a/drivers/nfc/pn533/pn533.c +++ b/drivers/nfc/pn533/pn533.c @@ -1259,7 +1259,8 @@ static int pn533_rf_complete(struct pn533 *dev, void *arg, if (IS_ERR(resp)) { rc = PTR_ERR(resp); - nfc_err(dev->dev, "RF setting error %d\n", rc); + if (rc != -ENOENT) + nfc_err(dev->dev, "RF setting error %d\n", rc); return rc; } @@ -1416,9 +1417,6 @@ static int pn533_poll_complete(struct pn533 *dev, void *arg, if (IS_ERR(resp)) { rc = PTR_ERR(resp); - nfc_err(dev->dev, "%s Poll complete error %d\n", - __func__, rc); - if (rc == -ENOENT) { if (dev->poll_mod_count != 0) return rc; @@ -1457,7 +1455,7 @@ done: return rc; stop_poll: - nfc_err(dev->dev, "Polling operation has been stopped\n"); + dev_dbg(dev->dev, "Polling operation has been stopped\n"); pn533_poll_reset_mod_list(dev); dev->poll_protocols = 0; -- 2.5.5
[PATCH 06/11] NFC: pn533: usb: fix errors when poll is stopped
When a poll ist stopped we need to kill the out_urb request too before starting a new request. Additionally check if cmd is set in pn533_recv_ack befor accessing its struct members. Signed-off-by: Michael Thalmeier <michael.thalme...@hale.at> --- drivers/nfc/pn533/usb.c | 12 +--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/drivers/nfc/pn533/usb.c b/drivers/nfc/pn533/usb.c index 8ca0603..5500175 100644 --- a/drivers/nfc/pn533/usb.c +++ b/drivers/nfc/pn533/usb.c @@ -98,7 +98,8 @@ static void pn533_recv_ack(struct urb *urb) struct pn533_std_frame *in_frame; int rc; - cmd->status = urb->status; + if (cmd) + cmd->status = urb->status; switch (urb->status) { case 0: @@ -120,7 +121,8 @@ static void pn533_recv_ack(struct urb *urb) if (!pn533_rx_frame_is_ack(in_frame)) { nfc_err(>udev->dev, "Received an invalid ack\n"); - cmd->status = -EIO; + if (cmd) + cmd->status = -EIO; goto sched_wq; } @@ -128,7 +130,8 @@ static void pn533_recv_ack(struct urb *urb) if (rc) { nfc_err(>udev->dev, "usb_submit_urb failed with result %d\n", rc); - cmd->status = rc; + if (cmd) + cmd->status = rc; goto sched_wq; } @@ -209,6 +212,9 @@ static void pn533_usb_abort_cmd(struct pn533 *dev, gfp_t flags) if (dev->device_type == PN533_DEVICE_ACR122U) return; + /* cancel the out urb request */ + usb_kill_urb(phy->out_urb); + /* An ack will cancel the last issued command */ pn533_usb_send_ack(dev, flags); -- 2.5.5
[PATCH 08/11] NFC: pn533: reduce output when stopping poll
Handle return codes for stopped polling operations better to reduce logging activity. Signed-off-by: Michael Thalmeier --- drivers/nfc/pn533/pn533.c | 8 +++- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/drivers/nfc/pn533/pn533.c b/drivers/nfc/pn533/pn533.c index d1cc70a..c06d22f 100644 --- a/drivers/nfc/pn533/pn533.c +++ b/drivers/nfc/pn533/pn533.c @@ -1259,7 +1259,8 @@ static int pn533_rf_complete(struct pn533 *dev, void *arg, if (IS_ERR(resp)) { rc = PTR_ERR(resp); - nfc_err(dev->dev, "RF setting error %d\n", rc); + if (rc != -ENOENT) + nfc_err(dev->dev, "RF setting error %d\n", rc); return rc; } @@ -1416,9 +1417,6 @@ static int pn533_poll_complete(struct pn533 *dev, void *arg, if (IS_ERR(resp)) { rc = PTR_ERR(resp); - nfc_err(dev->dev, "%s Poll complete error %d\n", - __func__, rc); - if (rc == -ENOENT) { if (dev->poll_mod_count != 0) return rc; @@ -1457,7 +1455,7 @@ done: return rc; stop_poll: - nfc_err(dev->dev, "Polling operation has been stopped\n"); + dev_dbg(dev->dev, "Polling operation has been stopped\n"); pn533_poll_reset_mod_list(dev); dev->poll_protocols = 0; -- 2.5.5
[PATCH 06/11] NFC: pn533: usb: fix errors when poll is stopped
When a poll ist stopped we need to kill the out_urb request too before starting a new request. Additionally check if cmd is set in pn533_recv_ack befor accessing its struct members. Signed-off-by: Michael Thalmeier --- drivers/nfc/pn533/usb.c | 12 +--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/drivers/nfc/pn533/usb.c b/drivers/nfc/pn533/usb.c index 8ca0603..5500175 100644 --- a/drivers/nfc/pn533/usb.c +++ b/drivers/nfc/pn533/usb.c @@ -98,7 +98,8 @@ static void pn533_recv_ack(struct urb *urb) struct pn533_std_frame *in_frame; int rc; - cmd->status = urb->status; + if (cmd) + cmd->status = urb->status; switch (urb->status) { case 0: @@ -120,7 +121,8 @@ static void pn533_recv_ack(struct urb *urb) if (!pn533_rx_frame_is_ack(in_frame)) { nfc_err(>udev->dev, "Received an invalid ack\n"); - cmd->status = -EIO; + if (cmd) + cmd->status = -EIO; goto sched_wq; } @@ -128,7 +130,8 @@ static void pn533_recv_ack(struct urb *urb) if (rc) { nfc_err(>udev->dev, "usb_submit_urb failed with result %d\n", rc); - cmd->status = rc; + if (cmd) + cmd->status = rc; goto sched_wq; } @@ -209,6 +212,9 @@ static void pn533_usb_abort_cmd(struct pn533 *dev, gfp_t flags) if (dev->device_type == PN533_DEVICE_ACR122U) return; + /* cancel the out urb request */ + usb_kill_urb(phy->out_urb); + /* An ack will cancel the last issued command */ pn533_usb_send_ack(dev, flags); -- 2.5.5
[PATCH 03/11] NFC: pn533: i2c: do not call pn533_recv_frame with aborted commands
When a command gets aborted the pn533 core does not need any RX frames that may be received until a new frame is sent. Signed-off-by: Michael Thalmeier <michael.thalme...@hale.at> --- drivers/nfc/pn533/i2c.c | 15 +++ 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/drivers/nfc/pn533/i2c.c b/drivers/nfc/pn533/i2c.c index 0141f19..1dc89248 100644 --- a/drivers/nfc/pn533/i2c.c +++ b/drivers/nfc/pn533/i2c.c @@ -39,6 +39,8 @@ struct pn533_i2c_phy { struct i2c_client *i2c_dev; struct pn533 *priv; + bool aborted; + int hard_fault; /* * < 0 if hardware error occurred (e.g. i2c err) * and prevents normal operation. @@ -71,6 +73,8 @@ static int pn533_i2c_send_frame(struct pn533 *dev, if (phy->priv == NULL) phy->priv = dev; + phy->aborted = false; + print_hex_dump_debug("PN533_i2c TX: ", DUMP_PREFIX_NONE, 16, 1, out->data, out->len, false); @@ -93,13 +97,15 @@ static int pn533_i2c_send_frame(struct pn533 *dev, static void pn533_i2c_abort_cmd(struct pn533 *dev, gfp_t flags) { + struct pn533_i2c_phy *phy = dev->phy; + + phy->aborted = true; + /* An ack will cancel the last issued command */ pn533_i2c_send_ack(dev, flags); /* schedule cmd_complete_work to finish current command execution */ - if (dev->cmd != NULL) - dev->cmd->status = -ENOENT; - queue_work(dev->wq, >cmd_complete_work); + pn533_recv_frame(phy->priv, NULL, -ENOENT); } static int pn533_i2c_read(struct pn533_i2c_phy *phy, struct sk_buff **skb) @@ -164,7 +170,8 @@ static irqreturn_t pn533_i2c_irq_thread_fn(int irq, void *data) return IRQ_HANDLED; } - pn533_recv_frame(phy->priv, skb, 0); + if (!phy->aborted) + pn533_recv_frame(phy->priv, skb, 0); return IRQ_HANDLED; } -- 2.5.5
[PATCH 09/11] NFC: pn533: use nfc_alloc_recv_skb for skb allocation
When multiple receive frames need to be put together in pn533_build_response we need to use nfc_alloc_recv_skb instead of the normal alloc_skb. Otherwise the nfc core causes an skb error when it tries to push the status byte in front of the data. Signed-off-by: Michael Thalmeier <michael.thalme...@hale.at> --- drivers/nfc/pn533/pn533.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/nfc/pn533/pn533.c b/drivers/nfc/pn533/pn533.c index c06d22f..ae13277 100644 --- a/drivers/nfc/pn533/pn533.c +++ b/drivers/nfc/pn533/pn533.c @@ -1942,7 +1942,7 @@ static struct sk_buff *pn533_build_response(struct pn533 *dev) dev_dbg(dev->dev, "%s total length %d\n", __func__, skb_len); - skb = alloc_skb(skb_len, GFP_KERNEL); + skb = nfc_alloc_recv_skb(skb_len, GFP_KERNEL); if (skb == NULL) goto out; -- 2.5.5
[PATCH 09/11] NFC: pn533: use nfc_alloc_recv_skb for skb allocation
When multiple receive frames need to be put together in pn533_build_response we need to use nfc_alloc_recv_skb instead of the normal alloc_skb. Otherwise the nfc core causes an skb error when it tries to push the status byte in front of the data. Signed-off-by: Michael Thalmeier --- drivers/nfc/pn533/pn533.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/nfc/pn533/pn533.c b/drivers/nfc/pn533/pn533.c index c06d22f..ae13277 100644 --- a/drivers/nfc/pn533/pn533.c +++ b/drivers/nfc/pn533/pn533.c @@ -1942,7 +1942,7 @@ static struct sk_buff *pn533_build_response(struct pn533 *dev) dev_dbg(dev->dev, "%s total length %d\n", __func__, skb_len); - skb = alloc_skb(skb_len, GFP_KERNEL); + skb = nfc_alloc_recv_skb(skb_len, GFP_KERNEL); if (skb == NULL) goto out; -- 2.5.5
[PATCH 03/11] NFC: pn533: i2c: do not call pn533_recv_frame with aborted commands
When a command gets aborted the pn533 core does not need any RX frames that may be received until a new frame is sent. Signed-off-by: Michael Thalmeier --- drivers/nfc/pn533/i2c.c | 15 +++ 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/drivers/nfc/pn533/i2c.c b/drivers/nfc/pn533/i2c.c index 0141f19..1dc89248 100644 --- a/drivers/nfc/pn533/i2c.c +++ b/drivers/nfc/pn533/i2c.c @@ -39,6 +39,8 @@ struct pn533_i2c_phy { struct i2c_client *i2c_dev; struct pn533 *priv; + bool aborted; + int hard_fault; /* * < 0 if hardware error occurred (e.g. i2c err) * and prevents normal operation. @@ -71,6 +73,8 @@ static int pn533_i2c_send_frame(struct pn533 *dev, if (phy->priv == NULL) phy->priv = dev; + phy->aborted = false; + print_hex_dump_debug("PN533_i2c TX: ", DUMP_PREFIX_NONE, 16, 1, out->data, out->len, false); @@ -93,13 +97,15 @@ static int pn533_i2c_send_frame(struct pn533 *dev, static void pn533_i2c_abort_cmd(struct pn533 *dev, gfp_t flags) { + struct pn533_i2c_phy *phy = dev->phy; + + phy->aborted = true; + /* An ack will cancel the last issued command */ pn533_i2c_send_ack(dev, flags); /* schedule cmd_complete_work to finish current command execution */ - if (dev->cmd != NULL) - dev->cmd->status = -ENOENT; - queue_work(dev->wq, >cmd_complete_work); + pn533_recv_frame(phy->priv, NULL, -ENOENT); } static int pn533_i2c_read(struct pn533_i2c_phy *phy, struct sk_buff **skb) @@ -164,7 +170,8 @@ static irqreturn_t pn533_i2c_irq_thread_fn(int irq, void *data) return IRQ_HANDLED; } - pn533_recv_frame(phy->priv, skb, 0); + if (!phy->aborted) + pn533_recv_frame(phy->priv, skb, 0); return IRQ_HANDLED; } -- 2.5.5
[PATCH 00/11] NFC: pn533: bug fixes and improvements
Hello Samuel, This patchset fixes some major bugs in the pn533 drivers (usb and i2c) and improves performance of the PN532 chip by increasing its clock speed. Best Regards Michael Michael Thalmeier (11): NFC: pn533: i2c: free irq on driver remove NFC: pn533: fix order of initialization NFC: pn533: i2c: do not call pn533_recv_frame with aborted commands NFC: pn533: reset poll modulation list before calling nfc_targets_found NFC: pn533: handle interrupted commands in pn533_recv_frame NFC: pn533: usb: fix errors when poll is stopped NFC: pn533: improve cmd queue handling NFC: pn533: reduce output when stopping poll NFC: pn533: use nfc_alloc_recv_skb for skb allocation NFC: pn533: set cmd status when not set nfc: pn533: increase clock frequency for PN532 drivers/nfc/pn533/i2c.c | 20 -- drivers/nfc/pn533/pn533.c | 154 +- drivers/nfc/pn533/pn533.h | 5 +- drivers/nfc/pn533/usb.c | 15 +++-- 4 files changed, 153 insertions(+), 41 deletions(-) -- 2.5.5
[PATCH 00/11] NFC: pn533: bug fixes and improvements
Hello Samuel, This patchset fixes some major bugs in the pn533 drivers (usb and i2c) and improves performance of the PN532 chip by increasing its clock speed. Best Regards Michael Michael Thalmeier (11): NFC: pn533: i2c: free irq on driver remove NFC: pn533: fix order of initialization NFC: pn533: i2c: do not call pn533_recv_frame with aborted commands NFC: pn533: reset poll modulation list before calling nfc_targets_found NFC: pn533: handle interrupted commands in pn533_recv_frame NFC: pn533: usb: fix errors when poll is stopped NFC: pn533: improve cmd queue handling NFC: pn533: reduce output when stopping poll NFC: pn533: use nfc_alloc_recv_skb for skb allocation NFC: pn533: set cmd status when not set nfc: pn533: increase clock frequency for PN532 drivers/nfc/pn533/i2c.c | 20 -- drivers/nfc/pn533/pn533.c | 154 +- drivers/nfc/pn533/pn533.h | 5 +- drivers/nfc/pn533/usb.c | 15 +++-- 4 files changed, 153 insertions(+), 41 deletions(-) -- 2.5.5
[PATCH 05/11] NFC: pn533: handle interrupted commands in pn533_recv_frame
When pn533_recv_frame is called from within abort_command context the current dev->cmd is not guaranteed to be set. Additionally on receiving an error status we can omit frame checking and simply schedule the workquueue. Signed-off-by: Michael Thalmeier <michael.thalme...@hale.at> --- drivers/nfc/pn533/pn533.c | 8 1 file changed, 8 insertions(+) diff --git a/drivers/nfc/pn533/pn533.c b/drivers/nfc/pn533/pn533.c index 745181e..d9c5583 100644 --- a/drivers/nfc/pn533/pn533.c +++ b/drivers/nfc/pn533/pn533.c @@ -2016,8 +2016,16 @@ _error: */ void pn533_recv_frame(struct pn533 *dev, struct sk_buff *skb, int status) { + if (!dev->cmd) + goto sched_wq; + dev->cmd->status = status; + if (status != 0) { + dev_dbg(dev->dev, "%s: Error received: %d\n", __func__, status); + goto sched_wq; + } + if (skb == NULL) { pr_err("NULL Frame -> link is dead\n"); goto sched_wq; -- 2.5.5
[PATCH 05/11] NFC: pn533: handle interrupted commands in pn533_recv_frame
When pn533_recv_frame is called from within abort_command context the current dev->cmd is not guaranteed to be set. Additionally on receiving an error status we can omit frame checking and simply schedule the workquueue. Signed-off-by: Michael Thalmeier --- drivers/nfc/pn533/pn533.c | 8 1 file changed, 8 insertions(+) diff --git a/drivers/nfc/pn533/pn533.c b/drivers/nfc/pn533/pn533.c index 745181e..d9c5583 100644 --- a/drivers/nfc/pn533/pn533.c +++ b/drivers/nfc/pn533/pn533.c @@ -2016,8 +2016,16 @@ _error: */ void pn533_recv_frame(struct pn533 *dev, struct sk_buff *skb, int status) { + if (!dev->cmd) + goto sched_wq; + dev->cmd->status = status; + if (status != 0) { + dev_dbg(dev->dev, "%s: Error received: %d\n", __func__, status); + goto sched_wq; + } + if (skb == NULL) { pr_err("NULL Frame -> link is dead\n"); goto sched_wq; -- 2.5.5
[PATCH 02/11] NFC: pn533: fix order of initialization
Correctly call nfc_set_parent_dev before nfc_register_device. Otherwise the driver will oops when being removed. Signed-off-by: Michael Thalmeier <michael.thalme...@hale.at> --- drivers/nfc/pn533/i2c.c | 3 ++- drivers/nfc/pn533/pn533.c | 4 +++- drivers/nfc/pn533/pn533.h | 3 ++- drivers/nfc/pn533/usb.c | 3 +-- 4 files changed, 8 insertions(+), 5 deletions(-) diff --git a/drivers/nfc/pn533/i2c.c b/drivers/nfc/pn533/i2c.c index 1a622e1..0141f19 100644 --- a/drivers/nfc/pn533/i2c.c +++ b/drivers/nfc/pn533/i2c.c @@ -211,7 +211,8 @@ static int pn533_i2c_probe(struct i2c_client *client, PN533_NO_TYPE_B_PROTOCOLS, PN533_PROTO_REQ_ACK_RESP, phy, _phy_ops, NULL, ->i2c_dev->dev); +>i2c_dev->dev, +>dev); if (IS_ERR(priv)) { r = PTR_ERR(priv); diff --git a/drivers/nfc/pn533/pn533.c b/drivers/nfc/pn533/pn533.c index ee9e8f1..d82eecd 100644 --- a/drivers/nfc/pn533/pn533.c +++ b/drivers/nfc/pn533/pn533.c @@ -2554,7 +2554,8 @@ struct pn533 *pn533_register_device(u32 device_type, void *phy, struct pn533_phy_ops *phy_ops, struct pn533_frame_ops *fops, - struct device *dev) + struct device *dev, + struct device *parent) { struct pn533_fw_version fw_ver; struct pn533 *priv; @@ -2617,6 +2618,7 @@ struct pn533 *pn533_register_device(u32 device_type, goto destroy_wq; } + nfc_set_parent_dev(priv->nfc_dev, parent); nfc_set_drvdata(priv->nfc_dev, priv); rc = nfc_register_device(priv->nfc_dev); diff --git a/drivers/nfc/pn533/pn533.h b/drivers/nfc/pn533/pn533.h index ba604f6..553c7d1 100644 --- a/drivers/nfc/pn533/pn533.h +++ b/drivers/nfc/pn533/pn533.h @@ -228,7 +228,8 @@ struct pn533 *pn533_register_device(u32 device_type, void *phy, struct pn533_phy_ops *phy_ops, struct pn533_frame_ops *fops, - struct device *dev); + struct device *dev, + struct device *parent); void pn533_unregister_device(struct pn533 *priv); void pn533_recv_frame(struct pn533 *dev, struct sk_buff *skb, int status); diff --git a/drivers/nfc/pn533/usb.c b/drivers/nfc/pn533/usb.c index 4f73cbf..8ca0603 100644 --- a/drivers/nfc/pn533/usb.c +++ b/drivers/nfc/pn533/usb.c @@ -536,7 +536,7 @@ static int pn533_usb_probe(struct usb_interface *interface, priv = pn533_register_device(id->driver_info, protocols, protocol_type, phy, _phy_ops, fops, - >udev->dev); + >udev->dev, >dev); if (IS_ERR(priv)) { rc = PTR_ERR(priv); @@ -544,7 +544,6 @@ static int pn533_usb_probe(struct usb_interface *interface, } phy->priv = priv; - nfc_set_parent_dev(priv->nfc_dev, >dev); usb_set_intfdata(interface, phy); -- 2.5.5
[PATCH 01/11] NFC: pn533: i2c: free irq on driver remove
The requested irq needs to be freed when removing the driver, otherwise a following driver load fails to request the irq. Signed-off-by: Michael Thalmeier <michael.thalme...@hale.at> --- drivers/nfc/pn533/i2c.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/nfc/pn533/i2c.c b/drivers/nfc/pn533/i2c.c index 9679aa5..1a622e1 100644 --- a/drivers/nfc/pn533/i2c.c +++ b/drivers/nfc/pn533/i2c.c @@ -236,6 +236,8 @@ static int pn533_i2c_remove(struct i2c_client *client) pn533_unregister_device(phy->priv); + free_irq(client->irq, phy); + return 0; } -- 2.5.5
[PATCH 02/11] NFC: pn533: fix order of initialization
Correctly call nfc_set_parent_dev before nfc_register_device. Otherwise the driver will oops when being removed. Signed-off-by: Michael Thalmeier --- drivers/nfc/pn533/i2c.c | 3 ++- drivers/nfc/pn533/pn533.c | 4 +++- drivers/nfc/pn533/pn533.h | 3 ++- drivers/nfc/pn533/usb.c | 3 +-- 4 files changed, 8 insertions(+), 5 deletions(-) diff --git a/drivers/nfc/pn533/i2c.c b/drivers/nfc/pn533/i2c.c index 1a622e1..0141f19 100644 --- a/drivers/nfc/pn533/i2c.c +++ b/drivers/nfc/pn533/i2c.c @@ -211,7 +211,8 @@ static int pn533_i2c_probe(struct i2c_client *client, PN533_NO_TYPE_B_PROTOCOLS, PN533_PROTO_REQ_ACK_RESP, phy, _phy_ops, NULL, ->i2c_dev->dev); +>i2c_dev->dev, +>dev); if (IS_ERR(priv)) { r = PTR_ERR(priv); diff --git a/drivers/nfc/pn533/pn533.c b/drivers/nfc/pn533/pn533.c index ee9e8f1..d82eecd 100644 --- a/drivers/nfc/pn533/pn533.c +++ b/drivers/nfc/pn533/pn533.c @@ -2554,7 +2554,8 @@ struct pn533 *pn533_register_device(u32 device_type, void *phy, struct pn533_phy_ops *phy_ops, struct pn533_frame_ops *fops, - struct device *dev) + struct device *dev, + struct device *parent) { struct pn533_fw_version fw_ver; struct pn533 *priv; @@ -2617,6 +2618,7 @@ struct pn533 *pn533_register_device(u32 device_type, goto destroy_wq; } + nfc_set_parent_dev(priv->nfc_dev, parent); nfc_set_drvdata(priv->nfc_dev, priv); rc = nfc_register_device(priv->nfc_dev); diff --git a/drivers/nfc/pn533/pn533.h b/drivers/nfc/pn533/pn533.h index ba604f6..553c7d1 100644 --- a/drivers/nfc/pn533/pn533.h +++ b/drivers/nfc/pn533/pn533.h @@ -228,7 +228,8 @@ struct pn533 *pn533_register_device(u32 device_type, void *phy, struct pn533_phy_ops *phy_ops, struct pn533_frame_ops *fops, - struct device *dev); + struct device *dev, + struct device *parent); void pn533_unregister_device(struct pn533 *priv); void pn533_recv_frame(struct pn533 *dev, struct sk_buff *skb, int status); diff --git a/drivers/nfc/pn533/usb.c b/drivers/nfc/pn533/usb.c index 4f73cbf..8ca0603 100644 --- a/drivers/nfc/pn533/usb.c +++ b/drivers/nfc/pn533/usb.c @@ -536,7 +536,7 @@ static int pn533_usb_probe(struct usb_interface *interface, priv = pn533_register_device(id->driver_info, protocols, protocol_type, phy, _phy_ops, fops, - >udev->dev); + >udev->dev, >dev); if (IS_ERR(priv)) { rc = PTR_ERR(priv); @@ -544,7 +544,6 @@ static int pn533_usb_probe(struct usb_interface *interface, } phy->priv = priv; - nfc_set_parent_dev(priv->nfc_dev, >dev); usb_set_intfdata(interface, phy); -- 2.5.5
[PATCH 01/11] NFC: pn533: i2c: free irq on driver remove
The requested irq needs to be freed when removing the driver, otherwise a following driver load fails to request the irq. Signed-off-by: Michael Thalmeier --- drivers/nfc/pn533/i2c.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/nfc/pn533/i2c.c b/drivers/nfc/pn533/i2c.c index 9679aa5..1a622e1 100644 --- a/drivers/nfc/pn533/i2c.c +++ b/drivers/nfc/pn533/i2c.c @@ -236,6 +236,8 @@ static int pn533_i2c_remove(struct i2c_client *client) pn533_unregister_device(phy->priv); + free_irq(client->irq, phy); + return 0; } -- 2.5.5
[PATCH 10/11] NFC: pn533: set cmd status when not set
When pn533_recv_frame is called with skb = NULL and cmd->status = 0, set cmd->status to an error code. Signed-off-by: Michael Thalmeier <michael.thalme...@hale.at> --- drivers/nfc/pn533/pn533.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/nfc/pn533/pn533.c b/drivers/nfc/pn533/pn533.c index ae13277..44bc5e0 100644 --- a/drivers/nfc/pn533/pn533.c +++ b/drivers/nfc/pn533/pn533.c @@ -2040,6 +2040,8 @@ void pn533_recv_frame(struct pn533 *dev, struct sk_buff *skb, int status) if (skb == NULL) { pr_err("NULL Frame -> link is dead\n"); + if (!dev->cmd->status) + dev->cmd->status = -ENOENT; goto sched_wq; } -- 2.5.5
[PATCH 10/11] NFC: pn533: set cmd status when not set
When pn533_recv_frame is called with skb = NULL and cmd->status = 0, set cmd->status to an error code. Signed-off-by: Michael Thalmeier --- drivers/nfc/pn533/pn533.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/nfc/pn533/pn533.c b/drivers/nfc/pn533/pn533.c index ae13277..44bc5e0 100644 --- a/drivers/nfc/pn533/pn533.c +++ b/drivers/nfc/pn533/pn533.c @@ -2040,6 +2040,8 @@ void pn533_recv_frame(struct pn533 *dev, struct sk_buff *skb, int status) if (skb == NULL) { pr_err("NULL Frame -> link is dead\n"); + if (!dev->cmd->status) + dev->cmd->status = -ENOENT; goto sched_wq; } -- 2.5.5
[PATCH] nfc: pn533: Add device tree documentation for i2c phy
Add pn533-i2c phy devicetree documentation Signed-off-by: Michael Thalmeier <michael.thalme...@hale.at> --- .../devicetree/bindings/net/nfc/pn533-i2c.txt | 31 ++ 1 file changed, 31 insertions(+) create mode 100644 Documentation/devicetree/bindings/net/nfc/pn533-i2c.txt diff --git a/Documentation/devicetree/bindings/net/nfc/pn533-i2c.txt b/Documentation/devicetree/bindings/net/nfc/pn533-i2c.txt new file mode 100644 index 000..1aea822 --- /dev/null +++ b/Documentation/devicetree/bindings/net/nfc/pn533-i2c.txt @@ -0,0 +1,31 @@ +* NXP Semiconductors PN532 NFC Controller + +Required properties: +- compatible: Should be "nxp,pn532-i2c" or "nxp,pn533-i2c". +- clock-frequency: I²C work frequency. +- reg: address on the bus +- interrupt-parent: phandle for the interrupt gpio controller +- interrupts: GPIO interrupt to which the chip is connected + +Optional SoC Specific Properties: +- pinctrl-names: Contains only one value - "default". +- pintctrl-0: Specifies the pin control groups used for this controller. + +Example (for ARM-based BeagleBone with PN532 on I2C2): + + { + + status = "okay"; + + pn532: pn532@24 { + + compatible = "nxp,pn532-i2c"; + + reg = <0x24>; + clock-frequency = <40>; + + interrupt-parent = <>; + interrupts = <17 IRQ_TYPE_EDGE_FALLING>; + + }; +}; -- 2.5.5
[PATCH] nfc: pn533: Add device tree documentation for i2c phy
Add pn533-i2c phy devicetree documentation Signed-off-by: Michael Thalmeier --- .../devicetree/bindings/net/nfc/pn533-i2c.txt | 31 ++ 1 file changed, 31 insertions(+) create mode 100644 Documentation/devicetree/bindings/net/nfc/pn533-i2c.txt diff --git a/Documentation/devicetree/bindings/net/nfc/pn533-i2c.txt b/Documentation/devicetree/bindings/net/nfc/pn533-i2c.txt new file mode 100644 index 000..1aea822 --- /dev/null +++ b/Documentation/devicetree/bindings/net/nfc/pn533-i2c.txt @@ -0,0 +1,31 @@ +* NXP Semiconductors PN532 NFC Controller + +Required properties: +- compatible: Should be "nxp,pn532-i2c" or "nxp,pn533-i2c". +- clock-frequency: I²C work frequency. +- reg: address on the bus +- interrupt-parent: phandle for the interrupt gpio controller +- interrupts: GPIO interrupt to which the chip is connected + +Optional SoC Specific Properties: +- pinctrl-names: Contains only one value - "default". +- pintctrl-0: Specifies the pin control groups used for this controller. + +Example (for ARM-based BeagleBone with PN532 on I2C2): + + { + + status = "okay"; + + pn532: pn532@24 { + + compatible = "nxp,pn532-i2c"; + + reg = <0x24>; + clock-frequency = <40>; + + interrupt-parent = <>; + interrupts = <17 IRQ_TYPE_EDGE_FALLING>; + + }; +}; -- 2.5.5
[RFC 2/4] NFC: pn533: fix deadlock when socket is closed while processing command
A deadlock can occur when the NFC raw socket is closed while the driver is processing a command. Following is the call graph of the affected situation: send data via raw_sock: - rawsock_tx_work sock_hold => socket refcnt++ nfc_data_exchange => cb = rawsock_data_exchange_complete ops->im_transceive = pn533_transceive => arg->cb = db = rawsock_data_exchange_complete pn533_send_data_async => cb = pn533_data_exchange_complete __pn533_send_async => cmd->complete_cb = cb = pn533_data_exchange_complete if_ops->send_frame_async response: pn533_recv_response queue_work(priv->wq, >cmd_complete_work) pn533_wq_cmd_complete pn533_send_async_complete cmd->complete_cb() = pn533_data_exchange_complete() arg->cb() = rawsock_data_exchange_complete() sock_put => socket refcnt-- => If the corresponding socket gets closed in the meantime socket will be destructed sk_free __sk_free sk->sk_destruct = rawsock_destruct nfc_deactivate_target ops->deactivate_target = pn533_deactivate_target pn533_send_cmd_sync pn533_send_cmd_async __pn533_send_async list_add_tail(>queue, >cmd_queue)=> add to command list because a command is currently processed wait_for_completion => the workqueue thread waits here because it is the one processing the commands => deadlock To fix the deadlock pn533_deactivate_target is changed to issue the PN533_CMD_IN_RELEASE command in async mode. This way nothing blocks and the release command is executed after the current command. Signed-off-by: Michael Thalmeier <michael.thalme...@hale.at> --- drivers/nfc/pn533.c | 40 ++-- 1 file changed, 30 insertions(+), 10 deletions(-) diff --git a/drivers/nfc/pn533.c b/drivers/nfc/pn533.c index a85830f..074f1e4 100644 --- a/drivers/nfc/pn533.c +++ b/drivers/nfc/pn533.c @@ -2263,12 +2263,35 @@ static int pn533_activate_target(struct nfc_dev *nfc_dev, return 0; } +static int pn533_deactivate_target_complete(struct pn533 *dev, void *arg, +struct sk_buff *resp) +{ + int rc = 0; + + dev_dbg(>interface->dev, "%s\n", __func__); + + if (IS_ERR(resp)) { + rc = PTR_ERR(resp); + + nfc_err(>interface->dev, "Target release error %d\n", rc); + + return rc; + } + + rc = resp->data[0] & PN533_CMD_RET_MASK; + if (rc != PN533_CMD_RET_SUCCESS) + nfc_err(>interface->dev, + "Error 0x%x when releasing the target\n", rc); + + dev_kfree_skb(resp); + return rc; +} + static void pn533_deactivate_target(struct nfc_dev *nfc_dev, struct nfc_target *target, u8 mode) { struct pn533 *dev = nfc_get_drvdata(nfc_dev); struct sk_buff *skb; - struct sk_buff *resp; int rc; dev_dbg(>interface->dev, "%s\n", __func__); @@ -2287,16 +2310,13 @@ static void pn533_deactivate_target(struct nfc_dev *nfc_dev, *skb_put(skb, 1) = 1; /* TG*/ - resp = pn533_send_cmd_sync(dev, PN533_CMD_IN_RELEASE, skb); - if (IS_ERR(resp)) - return; - - rc = resp->data[0] & PN533_CMD_RET_MASK; - if (rc != PN533_CMD_RET_SUCCESS) - nfc_err(>interface->dev, - "Error 0x%x when releasing the target\n", rc); + rc = pn533_send_cmd_async(dev, PN533_CMD_IN_RELEASE, skb, + pn533_deactivate_target_complete, NULL); + if (rc < 0) { + dev_kfree_skb(skb); + nfc_err(>interface->dev, "Target release error %d\n", rc); + } - dev_kfree_skb(resp); return; } -- 2.5.5
[RFC 2/4] NFC: pn533: fix deadlock when socket is closed while processing command
A deadlock can occur when the NFC raw socket is closed while the driver is processing a command. Following is the call graph of the affected situation: send data via raw_sock: - rawsock_tx_work sock_hold => socket refcnt++ nfc_data_exchange => cb = rawsock_data_exchange_complete ops->im_transceive = pn533_transceive => arg->cb = db = rawsock_data_exchange_complete pn533_send_data_async => cb = pn533_data_exchange_complete __pn533_send_async => cmd->complete_cb = cb = pn533_data_exchange_complete if_ops->send_frame_async response: pn533_recv_response queue_work(priv->wq, >cmd_complete_work) pn533_wq_cmd_complete pn533_send_async_complete cmd->complete_cb() = pn533_data_exchange_complete() arg->cb() = rawsock_data_exchange_complete() sock_put => socket refcnt-- => If the corresponding socket gets closed in the meantime socket will be destructed sk_free __sk_free sk->sk_destruct = rawsock_destruct nfc_deactivate_target ops->deactivate_target = pn533_deactivate_target pn533_send_cmd_sync pn533_send_cmd_async __pn533_send_async list_add_tail(>queue, >cmd_queue)=> add to command list because a command is currently processed wait_for_completion => the workqueue thread waits here because it is the one processing the commands => deadlock To fix the deadlock pn533_deactivate_target is changed to issue the PN533_CMD_IN_RELEASE command in async mode. This way nothing blocks and the release command is executed after the current command. Signed-off-by: Michael Thalmeier --- drivers/nfc/pn533.c | 40 ++-- 1 file changed, 30 insertions(+), 10 deletions(-) diff --git a/drivers/nfc/pn533.c b/drivers/nfc/pn533.c index a85830f..074f1e4 100644 --- a/drivers/nfc/pn533.c +++ b/drivers/nfc/pn533.c @@ -2263,12 +2263,35 @@ static int pn533_activate_target(struct nfc_dev *nfc_dev, return 0; } +static int pn533_deactivate_target_complete(struct pn533 *dev, void *arg, +struct sk_buff *resp) +{ + int rc = 0; + + dev_dbg(>interface->dev, "%s\n", __func__); + + if (IS_ERR(resp)) { + rc = PTR_ERR(resp); + + nfc_err(>interface->dev, "Target release error %d\n", rc); + + return rc; + } + + rc = resp->data[0] & PN533_CMD_RET_MASK; + if (rc != PN533_CMD_RET_SUCCESS) + nfc_err(>interface->dev, + "Error 0x%x when releasing the target\n", rc); + + dev_kfree_skb(resp); + return rc; +} + static void pn533_deactivate_target(struct nfc_dev *nfc_dev, struct nfc_target *target, u8 mode) { struct pn533 *dev = nfc_get_drvdata(nfc_dev); struct sk_buff *skb; - struct sk_buff *resp; int rc; dev_dbg(>interface->dev, "%s\n", __func__); @@ -2287,16 +2310,13 @@ static void pn533_deactivate_target(struct nfc_dev *nfc_dev, *skb_put(skb, 1) = 1; /* TG*/ - resp = pn533_send_cmd_sync(dev, PN533_CMD_IN_RELEASE, skb); - if (IS_ERR(resp)) - return; - - rc = resp->data[0] & PN533_CMD_RET_MASK; - if (rc != PN533_CMD_RET_SUCCESS) - nfc_err(>interface->dev, - "Error 0x%x when releasing the target\n", rc); + rc = pn533_send_cmd_async(dev, PN533_CMD_IN_RELEASE, skb, + pn533_deactivate_target_complete, NULL); + if (rc < 0) { + dev_kfree_skb(skb); + nfc_err(>interface->dev, "Target release error %d\n", rc); + } - dev_kfree_skb(resp); return; } -- 2.5.5
[RFC 1/4] NFC: pn533: Send ATR_REQ only if NFC_PROTO_NFC_DEP bit is set in poll_protocols
Currently it is not possible to only poll for passive targets with the pn533 driver. To change this ATR_REQ is only sent when NFC_PROTO_NFC_DEP is explicitly requested in poll_protocols. As most implementations (e.g. neard) poll for all protocols that are reported to be supported by the adapter, this should not have much of an effect for current implementations. Signed-off-by: Michael Thalmeier <michael.thalme...@hale.at> --- drivers/nfc/pn533.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/nfc/pn533.c b/drivers/nfc/pn533.c index bb3d5ea..a85830f 100644 --- a/drivers/nfc/pn533.c +++ b/drivers/nfc/pn533.c @@ -1540,7 +1540,8 @@ static int pn533_start_poll_complete(struct pn533 *dev, struct sk_buff *resp) int rc, tgdata_len; /* Toggle the DEP polling */ - dev->poll_dep = 1; + if (dev->poll_protocols & NFC_PROTO_NFC_DEP_MASK) + dev->poll_dep = 1; nbtg = resp->data[0]; tg = resp->data[1]; @@ -2054,7 +2055,7 @@ static int pn533_send_poll_frame(struct pn533 *dev) dev_dbg(>interface->dev, "%s mod len %d\n", __func__, mod->len); - if (dev->poll_dep) { + if ((dev->poll_protocols & NFC_PROTO_NFC_DEP_MASK) && dev->poll_dep) { dev->poll_dep = 0; return pn533_poll_dep(dev->nfc_dev); } -- 2.5.5
[RFC 1/4] NFC: pn533: Send ATR_REQ only if NFC_PROTO_NFC_DEP bit is set in poll_protocols
Currently it is not possible to only poll for passive targets with the pn533 driver. To change this ATR_REQ is only sent when NFC_PROTO_NFC_DEP is explicitly requested in poll_protocols. As most implementations (e.g. neard) poll for all protocols that are reported to be supported by the adapter, this should not have much of an effect for current implementations. Signed-off-by: Michael Thalmeier --- drivers/nfc/pn533.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/nfc/pn533.c b/drivers/nfc/pn533.c index bb3d5ea..a85830f 100644 --- a/drivers/nfc/pn533.c +++ b/drivers/nfc/pn533.c @@ -1540,7 +1540,8 @@ static int pn533_start_poll_complete(struct pn533 *dev, struct sk_buff *resp) int rc, tgdata_len; /* Toggle the DEP polling */ - dev->poll_dep = 1; + if (dev->poll_protocols & NFC_PROTO_NFC_DEP_MASK) + dev->poll_dep = 1; nbtg = resp->data[0]; tg = resp->data[1]; @@ -2054,7 +2055,7 @@ static int pn533_send_poll_frame(struct pn533 *dev) dev_dbg(>interface->dev, "%s mod len %d\n", __func__, mod->len); - if (dev->poll_dep) { + if ((dev->poll_protocols & NFC_PROTO_NFC_DEP_MASK) && dev->poll_dep) { dev->poll_dep = 0; return pn533_poll_dep(dev->nfc_dev); } -- 2.5.5
[RFC 4/4] NFC: pn533: add I2C phy driver
This adds the I2C phy interface for the pn533 driver. This way the driver can be used to interact with I2C connected pn532. Signed-off-by: Michael Thalmeier <michael.thalme...@hale.at> --- drivers/nfc/pn533/Kconfig | 11 ++ drivers/nfc/pn533/Makefile | 2 + drivers/nfc/pn533/i2c.c| 277 + drivers/nfc/pn533/pn533.c | 29 + drivers/nfc/pn533/pn533.h | 2 + 5 files changed, 321 insertions(+) create mode 100644 drivers/nfc/pn533/i2c.c diff --git a/drivers/nfc/pn533/Kconfig b/drivers/nfc/pn533/Kconfig index b5a926e..d94122d 100644 --- a/drivers/nfc/pn533/Kconfig +++ b/drivers/nfc/pn533/Kconfig @@ -14,3 +14,14 @@ config NFC_PN533_USB If you choose to build a module, it'll be called pn533_usb. Say N if unsure. + +config NFC_PN533_I2C + tristate "NFC PN533 device support (I2C)" + depends on I2C + select NFC_PN533 + ---help--- + This module adds support for the NXP pn533 I2C interface. + Select this if your platform is using the I2C bus. + + If you choose to build a module, it'll be called pn533_i2c. + Say N if unsure. diff --git a/drivers/nfc/pn533/Makefile b/drivers/nfc/pn533/Makefile index 12c6be4..51d24c6 100644 --- a/drivers/nfc/pn533/Makefile +++ b/drivers/nfc/pn533/Makefile @@ -2,6 +2,8 @@ # Makefile for PN533 NFC driver # pn533_usb-objs = usb.o +pn533_i2c-objs = i2c.o obj-$(CONFIG_NFC_PN533) += pn533.o obj-$(CONFIG_NFC_PN533_USB) += pn533_usb.o +obj-$(CONFIG_NFC_PN533_I2C) += pn533_i2c.o diff --git a/drivers/nfc/pn533/i2c.c b/drivers/nfc/pn533/i2c.c new file mode 100644 index 000..35066b30 --- /dev/null +++ b/drivers/nfc/pn533/i2c.c @@ -0,0 +1,277 @@ +/* + * Driver for NXP PN533 NFC Chip - I2C transport layer + * + * Copyright (C) 2011 Instituto Nokia de Tecnologia + * Copyright (C) 2012-2013 Tieto Poland + * Copyright (C) 2016 HALE electronic + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 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/>. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "pn533.h" + +#define VERSION "0.1" + +#define PN533_I2C_DRIVER_NAME "pn533_i2c" + +struct pn533_i2c_phy { + struct i2c_client *i2c_dev; + struct pn533 *priv; + + int hard_fault; /* +* < 0 if hardware error occured (e.g. i2c err) +* and prevents normal operation. +*/ +}; + +static int pn533_i2c_send_ack(struct pn533 *dev, gfp_t flags) +{ + struct pn533_i2c_phy *phy = dev->phy; + struct i2c_client *client = phy->i2c_dev; + u8 ack[6] = {0x00, 0x00, 0xff, 0x00, 0xff, 0x00}; + /* spec 6.2.1.3: Preamble, SoPC (2), ACK Code (2), Postamble */ + int rc; + + rc = i2c_master_send(client, ack, 6); + + return rc; +} + +static int pn533_i2c_send_frame(struct pn533 *dev, + struct sk_buff *out) +{ + struct pn533_i2c_phy *phy = dev->phy; + struct i2c_client *client = phy->i2c_dev; + int rc; + + if (phy->hard_fault != 0) + return phy->hard_fault; + + if (phy->priv == NULL) + phy->priv = dev; + + print_hex_dump_debug("PN533_i2c TX: ", DUMP_PREFIX_NONE, 16, 1, +out->data, out->len, false); + + rc = i2c_master_send(client, out->data, out->len); + + if (rc == -EREMOTEIO) { /* Retry, chip was in power down */ + usleep_range(6000, 1); + rc = i2c_master_send(client, out->data, out->len); + } + + if (rc >= 0) { + if (rc != out->len) + rc = -EREMOTEIO; + else + rc = 0; + } + + return rc; +} + +static void pn533_i2c_abort_cmd(struct pn533 *dev, gfp_t flags) +{ + /* An ack will cancel the last issued command */ + pn533_i2c_send_ack(dev, flags); + + /* schedule cmd_complete_work to finish current command execution */ + if (dev->cmd != NULL) + dev->cmd->status = -ENOENT; + queue_work(dev->wq, >cmd_complete_work); +} + +static int pn533_i2c_read(struct pn533_i2c_p
[RFC 0/4] NFC: pn533: support for pn532 via I2C
This patchset is an attempt to implement support for NXP pn532 NFC chip connected via I2C. PN532 and PN533 are nearly identical despite the transport layer. So this implementation seperates the phy layer of the current pn533 usb driver and implements a new I2C phy layer for pn532. While implementing and testing I also triggered a few bugs that are fixed with the first two patches. Michael Thalmeier (4): NFC: pn533: Send ATR_REQ only if NFC_PROTO_NFC_DEP bit is set in poll_protocols NFC: pn533: fix deadlock when socket is closed while processing command NFC: pn533: Separate pn533 driver in HW dependant and independant parts NFC: pn533: add I2C phy driver drivers/nfc/Kconfig| 11 +- drivers/nfc/Makefile |2 +- drivers/nfc/pn533.c| 3313 drivers/nfc/pn533/Kconfig | 27 + drivers/nfc/pn533/Makefile |9 + drivers/nfc/pn533/i2c.c| 277 drivers/nfc/pn533/pn533.c | 2681 +++ drivers/nfc/pn533/pn533.h | 236 drivers/nfc/pn533/usb.c| 595 9 files changed, 3827 insertions(+), 3324 deletions(-) delete mode 100644 drivers/nfc/pn533.c create mode 100644 drivers/nfc/pn533/Kconfig create mode 100644 drivers/nfc/pn533/Makefile create mode 100644 drivers/nfc/pn533/i2c.c create mode 100644 drivers/nfc/pn533/pn533.c create mode 100644 drivers/nfc/pn533/pn533.h create mode 100644 drivers/nfc/pn533/usb.c -- 2.5.5
[RFC 4/4] NFC: pn533: add I2C phy driver
This adds the I2C phy interface for the pn533 driver. This way the driver can be used to interact with I2C connected pn532. Signed-off-by: Michael Thalmeier --- drivers/nfc/pn533/Kconfig | 11 ++ drivers/nfc/pn533/Makefile | 2 + drivers/nfc/pn533/i2c.c| 277 + drivers/nfc/pn533/pn533.c | 29 + drivers/nfc/pn533/pn533.h | 2 + 5 files changed, 321 insertions(+) create mode 100644 drivers/nfc/pn533/i2c.c diff --git a/drivers/nfc/pn533/Kconfig b/drivers/nfc/pn533/Kconfig index b5a926e..d94122d 100644 --- a/drivers/nfc/pn533/Kconfig +++ b/drivers/nfc/pn533/Kconfig @@ -14,3 +14,14 @@ config NFC_PN533_USB If you choose to build a module, it'll be called pn533_usb. Say N if unsure. + +config NFC_PN533_I2C + tristate "NFC PN533 device support (I2C)" + depends on I2C + select NFC_PN533 + ---help--- + This module adds support for the NXP pn533 I2C interface. + Select this if your platform is using the I2C bus. + + If you choose to build a module, it'll be called pn533_i2c. + Say N if unsure. diff --git a/drivers/nfc/pn533/Makefile b/drivers/nfc/pn533/Makefile index 12c6be4..51d24c6 100644 --- a/drivers/nfc/pn533/Makefile +++ b/drivers/nfc/pn533/Makefile @@ -2,6 +2,8 @@ # Makefile for PN533 NFC driver # pn533_usb-objs = usb.o +pn533_i2c-objs = i2c.o obj-$(CONFIG_NFC_PN533) += pn533.o obj-$(CONFIG_NFC_PN533_USB) += pn533_usb.o +obj-$(CONFIG_NFC_PN533_I2C) += pn533_i2c.o diff --git a/drivers/nfc/pn533/i2c.c b/drivers/nfc/pn533/i2c.c new file mode 100644 index 000..35066b30 --- /dev/null +++ b/drivers/nfc/pn533/i2c.c @@ -0,0 +1,277 @@ +/* + * Driver for NXP PN533 NFC Chip - I2C transport layer + * + * Copyright (C) 2011 Instituto Nokia de Tecnologia + * Copyright (C) 2012-2013 Tieto Poland + * Copyright (C) 2016 HALE electronic + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 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/>. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "pn533.h" + +#define VERSION "0.1" + +#define PN533_I2C_DRIVER_NAME "pn533_i2c" + +struct pn533_i2c_phy { + struct i2c_client *i2c_dev; + struct pn533 *priv; + + int hard_fault; /* +* < 0 if hardware error occured (e.g. i2c err) +* and prevents normal operation. +*/ +}; + +static int pn533_i2c_send_ack(struct pn533 *dev, gfp_t flags) +{ + struct pn533_i2c_phy *phy = dev->phy; + struct i2c_client *client = phy->i2c_dev; + u8 ack[6] = {0x00, 0x00, 0xff, 0x00, 0xff, 0x00}; + /* spec 6.2.1.3: Preamble, SoPC (2), ACK Code (2), Postamble */ + int rc; + + rc = i2c_master_send(client, ack, 6); + + return rc; +} + +static int pn533_i2c_send_frame(struct pn533 *dev, + struct sk_buff *out) +{ + struct pn533_i2c_phy *phy = dev->phy; + struct i2c_client *client = phy->i2c_dev; + int rc; + + if (phy->hard_fault != 0) + return phy->hard_fault; + + if (phy->priv == NULL) + phy->priv = dev; + + print_hex_dump_debug("PN533_i2c TX: ", DUMP_PREFIX_NONE, 16, 1, +out->data, out->len, false); + + rc = i2c_master_send(client, out->data, out->len); + + if (rc == -EREMOTEIO) { /* Retry, chip was in power down */ + usleep_range(6000, 1); + rc = i2c_master_send(client, out->data, out->len); + } + + if (rc >= 0) { + if (rc != out->len) + rc = -EREMOTEIO; + else + rc = 0; + } + + return rc; +} + +static void pn533_i2c_abort_cmd(struct pn533 *dev, gfp_t flags) +{ + /* An ack will cancel the last issued command */ + pn533_i2c_send_ack(dev, flags); + + /* schedule cmd_complete_work to finish current command execution */ + if (dev->cmd != NULL) + dev->cmd->status = -ENOENT; + queue_work(dev->wq, >cmd_complete_work); +} + +static int pn533_i2c_read(struct pn533_i2c_phy *phy, struct sk_buff **skb) +{ + struct i2c_clien
[RFC 0/4] NFC: pn533: support for pn532 via I2C
This patchset is an attempt to implement support for NXP pn532 NFC chip connected via I2C. PN532 and PN533 are nearly identical despite the transport layer. So this implementation seperates the phy layer of the current pn533 usb driver and implements a new I2C phy layer for pn532. While implementing and testing I also triggered a few bugs that are fixed with the first two patches. Michael Thalmeier (4): NFC: pn533: Send ATR_REQ only if NFC_PROTO_NFC_DEP bit is set in poll_protocols NFC: pn533: fix deadlock when socket is closed while processing command NFC: pn533: Separate pn533 driver in HW dependant and independant parts NFC: pn533: add I2C phy driver drivers/nfc/Kconfig| 11 +- drivers/nfc/Makefile |2 +- drivers/nfc/pn533.c| 3313 drivers/nfc/pn533/Kconfig | 27 + drivers/nfc/pn533/Makefile |9 + drivers/nfc/pn533/i2c.c| 277 drivers/nfc/pn533/pn533.c | 2681 +++ drivers/nfc/pn533/pn533.h | 236 drivers/nfc/pn533/usb.c| 595 9 files changed, 3827 insertions(+), 3324 deletions(-) delete mode 100644 drivers/nfc/pn533.c create mode 100644 drivers/nfc/pn533/Kconfig create mode 100644 drivers/nfc/pn533/Makefile create mode 100644 drivers/nfc/pn533/i2c.c create mode 100644 drivers/nfc/pn533/pn533.c create mode 100644 drivers/nfc/pn533/pn533.h create mode 100644 drivers/nfc/pn533/usb.c -- 2.5.5
[PATCH v2] hwmon: (lm75) Add support for the NXP LM75B
It is basically a faster lm75 with improved (11 bit) resolution. Signed-off-by: Michael Thalmeier --- v2: keep alphabetic order Documentation/hwmon/lm75 | 5 + drivers/hwmon/lm75.c | 6 ++ 2 files changed, 11 insertions(+) diff --git a/Documentation/hwmon/lm75 b/Documentation/hwmon/lm75 index c6a5ff1..67691a0a 100644 --- a/Documentation/hwmon/lm75 +++ b/Documentation/hwmon/lm75 @@ -53,6 +53,11 @@ Supported chips: http://www.ti.com/product/tmp75 http://www.ti.com/product/tmp175 http://www.ti.com/product/tmp275 + * NXP LM75B +Prefix: 'lm75b' +Addresses scanned: none +Datasheet: Publicly available at the NXP website + http://www.nxp.com/documents/data_sheet/LM75B.pdf Author: Frodo Looijaard diff --git a/drivers/hwmon/lm75.c b/drivers/hwmon/lm75.c index d16dbb33a..f58439b 100644 --- a/drivers/hwmon/lm75.c +++ b/drivers/hwmon/lm75.c @@ -44,6 +44,7 @@ enum lm75_type { /* keep sorted in alphabetical order */ g751, lm75, lm75a, + lm75b, max6625, max6626, mcp980x, @@ -233,6 +234,10 @@ lm75_probe(struct i2c_client *client, const struct i2c_device_id *id) data->resolution = 9; data->sample_time = HZ / 2; break; + case lm75b: + data->resolution = 11; + data->sample_time = HZ / 4; + break; case max6625: data->resolution = 9; data->sample_time = HZ / 4; @@ -322,6 +327,7 @@ static const struct i2c_device_id lm75_ids[] = { { "g751", g751, }, { "lm75", lm75, }, { "lm75a", lm75a, }, + { "lm75b", lm75b, }, { "max6625", max6625, }, { "max6626", max6626, }, { "mcp980x", mcp980x, }, -- 1.9.3 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v2] hwmon: (lm75) Add support for the NXP LM75B
It is basically a faster lm75 with improved (11 bit) resolution. Signed-off-by: Michael Thalmeier michael.thalme...@hale.at --- v2: keep alphabetic order Documentation/hwmon/lm75 | 5 + drivers/hwmon/lm75.c | 6 ++ 2 files changed, 11 insertions(+) diff --git a/Documentation/hwmon/lm75 b/Documentation/hwmon/lm75 index c6a5ff1..67691a0a 100644 --- a/Documentation/hwmon/lm75 +++ b/Documentation/hwmon/lm75 @@ -53,6 +53,11 @@ Supported chips: http://www.ti.com/product/tmp75 http://www.ti.com/product/tmp175 http://www.ti.com/product/tmp275 + * NXP LM75B +Prefix: 'lm75b' +Addresses scanned: none +Datasheet: Publicly available at the NXP website + http://www.nxp.com/documents/data_sheet/LM75B.pdf Author: Frodo Looijaard fro...@dds.nl diff --git a/drivers/hwmon/lm75.c b/drivers/hwmon/lm75.c index d16dbb33a..f58439b 100644 --- a/drivers/hwmon/lm75.c +++ b/drivers/hwmon/lm75.c @@ -44,6 +44,7 @@ enum lm75_type { /* keep sorted in alphabetical order */ g751, lm75, lm75a, + lm75b, max6625, max6626, mcp980x, @@ -233,6 +234,10 @@ lm75_probe(struct i2c_client *client, const struct i2c_device_id *id) data-resolution = 9; data-sample_time = HZ / 2; break; + case lm75b: + data-resolution = 11; + data-sample_time = HZ / 4; + break; case max6625: data-resolution = 9; data-sample_time = HZ / 4; @@ -322,6 +327,7 @@ static const struct i2c_device_id lm75_ids[] = { { g751, g751, }, { lm75, lm75, }, { lm75a, lm75a, }, + { lm75b, lm75b, }, { max6625, max6625, }, { max6626, max6626, }, { mcp980x, mcp980x, }, -- 1.9.3 -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] hwmon: (lm75) put chip into shutdown mode on shutdown
In addition to going into shutdown mode on suspend also go into shutdown mode on system shutdown. This way we can save a few mA when the main CPU is powered off and the lm75 is still powered but not used any more. Signed-off-by: Michael Thalmeier --- drivers/hwmon/lm75.c | 19 +-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/drivers/hwmon/lm75.c b/drivers/hwmon/lm75.c index 7ec5ccd..d860af9 100644 --- a/drivers/hwmon/lm75.c +++ b/drivers/hwmon/lm75.c @@ -433,10 +433,10 @@ static int lm75_detect(struct i2c_client *new_client, } #ifdef CONFIG_PM -static int lm75_suspend(struct device *dev) + +static int _lm75_shutdown(struct i2c_client *client) { int status; - struct i2c_client *client = to_i2c_client(dev); status = lm75_read_value(client, LM75_REG_CONF); if (status < 0) { dev_dbg(>dev, "Can't read config? %d\n", status); @@ -447,6 +447,18 @@ static int lm75_suspend(struct device *dev) return 0; } +static void lm75_shutdown(struct i2c_client *client) +{ + _lm75_shutdown(client); +} + +static int lm75_suspend(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + + return _lm75_shutdown(client); +} + static int lm75_resume(struct device *dev) { int status; @@ -466,8 +478,10 @@ static const struct dev_pm_ops lm75_dev_pm_ops = { .resume = lm75_resume, }; #define LM75_DEV_PM_OPS (_dev_pm_ops) +#define LM75_SHUTDOWN_OP lm75_shutdown #else #define LM75_DEV_PM_OPS NULL +#define LM75_SHUTDOWN_OP NULL #endif /* CONFIG_PM */ static struct i2c_driver lm75_driver = { @@ -478,6 +492,7 @@ static struct i2c_driver lm75_driver = { }, .probe = lm75_probe, .remove = lm75_remove, + .shutdown = LM75_SHUTDOWN_OP, .id_table = lm75_ids, .detect = lm75_detect, .address_list = normal_i2c, -- 1.9.3 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] hwmon: (lm75) Add support for the NXP LM75B
It is basically a faster lm75 with improved (11 bit) resolution. Signed-off-by: Michael Thalmeier --- Documentation/hwmon/lm75 | 6 ++ drivers/hwmon/lm75.c | 6 ++ 2 files changed, 12 insertions(+) diff --git a/Documentation/hwmon/lm75 b/Documentation/hwmon/lm75 index c6a5ff1..62e216a 100644 --- a/Documentation/hwmon/lm75 +++ b/Documentation/hwmon/lm75 @@ -53,6 +53,12 @@ Supported chips: http://www.ti.com/product/tmp75 http://www.ti.com/product/tmp175 http://www.ti.com/product/tmp275 + * NXP LM75B +Prefix: 'lm75b' +Addresses scanned: none +Datasheet: Publicly available at the NXP website + http://www.nxp.com/documents/data_sheet/LM75B.pdf + Author: Frodo Looijaard diff --git a/drivers/hwmon/lm75.c b/drivers/hwmon/lm75.c index d16dbb33a..7ec5ccd 100644 --- a/drivers/hwmon/lm75.c +++ b/drivers/hwmon/lm75.c @@ -44,6 +44,7 @@ enum lm75_type { /* keep sorted in alphabetical order */ g751, lm75, lm75a, + lm75b, max6625, max6626, mcp980x, @@ -271,6 +272,10 @@ lm75_probe(struct i2c_client *client, const struct i2c_device_id *id) data->resolution = 12; data->sample_time = HZ / 2; break; + case lm75b: + data->resolution = 11; + data->sample_time = HZ / 4; + break; } /* configure as specified */ @@ -334,6 +339,7 @@ static const struct i2c_device_id lm75_ids[] = { { "tmp175", tmp175, }, { "tmp275", tmp275, }, { "tmp75", tmp75, }, + { "lm75b", lm75b, }, { /* LIST END */ } }; MODULE_DEVICE_TABLE(i2c, lm75_ids); -- 1.9.3 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] hwmon: (lm75) Add support for the NXP LM75B
It is basically a faster lm75 with improved (11 bit) resolution. Signed-off-by: Michael Thalmeier michael.thalme...@hale.at --- Documentation/hwmon/lm75 | 6 ++ drivers/hwmon/lm75.c | 6 ++ 2 files changed, 12 insertions(+) diff --git a/Documentation/hwmon/lm75 b/Documentation/hwmon/lm75 index c6a5ff1..62e216a 100644 --- a/Documentation/hwmon/lm75 +++ b/Documentation/hwmon/lm75 @@ -53,6 +53,12 @@ Supported chips: http://www.ti.com/product/tmp75 http://www.ti.com/product/tmp175 http://www.ti.com/product/tmp275 + * NXP LM75B +Prefix: 'lm75b' +Addresses scanned: none +Datasheet: Publicly available at the NXP website + http://www.nxp.com/documents/data_sheet/LM75B.pdf + Author: Frodo Looijaard fro...@dds.nl diff --git a/drivers/hwmon/lm75.c b/drivers/hwmon/lm75.c index d16dbb33a..7ec5ccd 100644 --- a/drivers/hwmon/lm75.c +++ b/drivers/hwmon/lm75.c @@ -44,6 +44,7 @@ enum lm75_type { /* keep sorted in alphabetical order */ g751, lm75, lm75a, + lm75b, max6625, max6626, mcp980x, @@ -271,6 +272,10 @@ lm75_probe(struct i2c_client *client, const struct i2c_device_id *id) data-resolution = 12; data-sample_time = HZ / 2; break; + case lm75b: + data-resolution = 11; + data-sample_time = HZ / 4; + break; } /* configure as specified */ @@ -334,6 +339,7 @@ static const struct i2c_device_id lm75_ids[] = { { tmp175, tmp175, }, { tmp275, tmp275, }, { tmp75, tmp75, }, + { lm75b, lm75b, }, { /* LIST END */ } }; MODULE_DEVICE_TABLE(i2c, lm75_ids); -- 1.9.3 -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] hwmon: (lm75) put chip into shutdown mode on shutdown
In addition to going into shutdown mode on suspend also go into shutdown mode on system shutdown. This way we can save a few mA when the main CPU is powered off and the lm75 is still powered but not used any more. Signed-off-by: Michael Thalmeier michael.thalme...@hale.at --- drivers/hwmon/lm75.c | 19 +-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/drivers/hwmon/lm75.c b/drivers/hwmon/lm75.c index 7ec5ccd..d860af9 100644 --- a/drivers/hwmon/lm75.c +++ b/drivers/hwmon/lm75.c @@ -433,10 +433,10 @@ static int lm75_detect(struct i2c_client *new_client, } #ifdef CONFIG_PM -static int lm75_suspend(struct device *dev) + +static int _lm75_shutdown(struct i2c_client *client) { int status; - struct i2c_client *client = to_i2c_client(dev); status = lm75_read_value(client, LM75_REG_CONF); if (status 0) { dev_dbg(client-dev, Can't read config? %d\n, status); @@ -447,6 +447,18 @@ static int lm75_suspend(struct device *dev) return 0; } +static void lm75_shutdown(struct i2c_client *client) +{ + _lm75_shutdown(client); +} + +static int lm75_suspend(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + + return _lm75_shutdown(client); +} + static int lm75_resume(struct device *dev) { int status; @@ -466,8 +478,10 @@ static const struct dev_pm_ops lm75_dev_pm_ops = { .resume = lm75_resume, }; #define LM75_DEV_PM_OPS (lm75_dev_pm_ops) +#define LM75_SHUTDOWN_OP lm75_shutdown #else #define LM75_DEV_PM_OPS NULL +#define LM75_SHUTDOWN_OP NULL #endif /* CONFIG_PM */ static struct i2c_driver lm75_driver = { @@ -478,6 +492,7 @@ static struct i2c_driver lm75_driver = { }, .probe = lm75_probe, .remove = lm75_remove, + .shutdown = LM75_SHUTDOWN_OP, .id_table = lm75_ids, .detect = lm75_detect, .address_list = normal_i2c, -- 1.9.3 -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH RT 0/2] [ANNOUNCE] 3.0.41-rt62-rc1 stable review
Hi, I have tested this patch on our board (custom i.MX31 ARMv6 based) and everything seems to be working as expected. Thanks, Michael -- Scanned by MailScanner. -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH RT 0/2] [ANNOUNCE] 3.0.41-rt62-rc1 stable review
Hi, I have tested this patch on our board (custom i.MX31 ARMv6 based) and everything seems to be working as expected. Thanks, Michael -- Scanned by MailScanner. -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH RT 2/2] fix printk flush of messages
Frank Rowand am.sony.com> writes: > > > Updates console-make-rt-friendly.patch > > #ifdef CONFIG_PREEMPT_RT_FULL, printk() output is never flushed by > printk() because: > ... > > On system boot some printk() output is flushed because register_console() > and tty_open() call console_unlock(). > > This change also fixes the problem that was previously fixed by > preempt-rt-allow-immediate-magic-sysrq-output-for-preempt_rt_full.patch > > Signed-off-by: Frank Rowand am.sony.com> > > --- > kernel/printk.c |2 1 + 1 - 0 ! > 1 file changed, 1 insertion(+), 1 deletion(-) > > Index: b/kernel/printk.c > === > --- a/kernel/printk.c > +++ b/kernel/printk.c > @@ -847,7 +847,7 @@ static int console_trylock_for_printk(un > int retval = 0, wake = 0; > #ifdef CONFIG_PREEMPT_RT_FULL > int lock = !early_boot_irqs_disabled && !irqs_disabled_flags(flags) && > - !preempt_count(); > + (preempt_count() <= 1); > #else > int lock = 1; > #endif > > I have seen that this patch is applied in the 3.4 stable rt series. As we are using the 3.0 stable rt kernel I have tested this patch on this kernel series (on a Freescale i.MX31 based board) and have not found any problems so far. Is there something I have missed why this patch has not found its way in the 3.0 series ? Thanks in advance, Michael -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH RT 2/2] fix printk flush of messages
Frank Rowand frank.rowand at am.sony.com writes: Updates console-make-rt-friendly.patch #ifdef CONFIG_PREEMPT_RT_FULL, printk() output is never flushed by printk() because: ... On system boot some printk() output is flushed because register_console() and tty_open() call console_unlock(). This change also fixes the problem that was previously fixed by preempt-rt-allow-immediate-magic-sysrq-output-for-preempt_rt_full.patch Signed-off-by: Frank Rowand frank.rowand at am.sony.com --- kernel/printk.c |2 1 + 1 - 0 ! 1 file changed, 1 insertion(+), 1 deletion(-) Index: b/kernel/printk.c === --- a/kernel/printk.c +++ b/kernel/printk.c @@ -847,7 +847,7 @@ static int console_trylock_for_printk(un int retval = 0, wake = 0; #ifdef CONFIG_PREEMPT_RT_FULL int lock = !early_boot_irqs_disabled !irqs_disabled_flags(flags) - !preempt_count(); + (preempt_count() = 1); #else int lock = 1; #endif I have seen that this patch is applied in the 3.4 stable rt series. As we are using the 3.0 stable rt kernel I have tested this patch on this kernel series (on a Freescale i.MX31 based board) and have not found any problems so far. Is there something I have missed why this patch has not found its way in the 3.0 series ? Thanks in advance, Michael -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/