Re: [patch] mtd: pmcmsp-flash: Allocating too much in init_msp_flash()
On Thu, Jul 14, 2016 at 01:44:56PM +0300, Dan Carpenter wrote: > There is a cut and paste issue here. The bug is that we are allocating > more memory than necessary for msp_maps. We should be allocating enough > space for a map_info struct (144 bytes) but we instead allocate enough > for an mtd_info struct (1840 bytes). It's a small waste. > > The other part of this is not harmful but when we allocated msp_flash > then we allocated enough space fro a map_info pointer instead of an > mtd_info pointer. But since pointers are the same size it works out > fine. > > Anyway, I decided to clean up all three allocations a bit to make them > a bit more consistent and clear. > > Fixes: 68aa0fa87f6d ('[MTD] PMC MSP71xx flash/rootfs mappings') > Signed-off-by: Dan CarpenterApplied to l2-mtd.git.
Re: [patch] mtd: pmcmsp-flash: Allocating too much in init_msp_flash()
On Thu, Jul 14, 2016 at 01:44:56PM +0300, Dan Carpenter wrote: > There is a cut and paste issue here. The bug is that we are allocating > more memory than necessary for msp_maps. We should be allocating enough > space for a map_info struct (144 bytes) but we instead allocate enough > for an mtd_info struct (1840 bytes). It's a small waste. > > The other part of this is not harmful but when we allocated msp_flash > then we allocated enough space fro a map_info pointer instead of an > mtd_info pointer. But since pointers are the same size it works out > fine. > > Anyway, I decided to clean up all three allocations a bit to make them > a bit more consistent and clear. > > Fixes: 68aa0fa87f6d ('[MTD] PMC MSP71xx flash/rootfs mappings') > Signed-off-by: Dan Carpenter Applied to l2-mtd.git.
[PATCH] drm/tegra: Delete an unnecessary check before the function call "vunmap"
From: Markus ElfringDate: Sat, 16 Jul 2016 07:23:42 +0200 The vunmap() function performs also input parameter validation. Thus the test around the call is not needed. This issue was detected by using the Coccinelle software. Signed-off-by: Markus Elfring --- drivers/gpu/drm/tegra/fb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/tegra/fb.c b/drivers/gpu/drm/tegra/fb.c index 1b12aa7..e6d71fa 100644 --- a/drivers/gpu/drm/tegra/fb.c +++ b/drivers/gpu/drm/tegra/fb.c @@ -68,7 +68,7 @@ static void tegra_fb_destroy(struct drm_framebuffer *framebuffer) struct tegra_bo *bo = fb->planes[i]; if (bo) { - if (bo->pages && bo->vaddr) + if (bo->pages) vunmap(bo->vaddr); drm_gem_object_unreference_unlocked(>gem); -- 2.9.1
[PATCH] drm/tegra: Delete an unnecessary check before the function call "vunmap"
From: Markus Elfring Date: Sat, 16 Jul 2016 07:23:42 +0200 The vunmap() function performs also input parameter validation. Thus the test around the call is not needed. This issue was detected by using the Coccinelle software. Signed-off-by: Markus Elfring --- drivers/gpu/drm/tegra/fb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/tegra/fb.c b/drivers/gpu/drm/tegra/fb.c index 1b12aa7..e6d71fa 100644 --- a/drivers/gpu/drm/tegra/fb.c +++ b/drivers/gpu/drm/tegra/fb.c @@ -68,7 +68,7 @@ static void tegra_fb_destroy(struct drm_framebuffer *framebuffer) struct tegra_bo *bo = fb->planes[i]; if (bo) { - if (bo->pages && bo->vaddr) + if (bo->pages) vunmap(bo->vaddr); drm_gem_object_unreference_unlocked(>gem); -- 2.9.1
Re: [PATCH 1/2] iio: humidity: hdc100x: move lock on config updates to single function
On Sun, Jul 10, 2016 at 02:30:01PM -0700, Alison Schofield wrote: > Move the config register locking to the config update function. This > continues to protect updates to heater and integration times. It puts > the lock in one place, right where it needs to occur. Since creating this patch, I've learned that it is a design choice in kernel drivers to keep the locking at a higher level - ie point of entry. This patch goes against that design, so, I get that it's not do-able. alisons > > Add the checkpatch required comment on this lock declaration. > > Signed-off-by: Alison Schofield> Cc: Daniel Baluta > --- > drivers/iio/humidity/hdc100x.c | 16 ++-- > 1 file changed, 6 insertions(+), 10 deletions(-) > > diff --git a/drivers/iio/humidity/hdc100x.c b/drivers/iio/humidity/hdc100x.c > index a03832a..ad5a12a 100644 > --- a/drivers/iio/humidity/hdc100x.c > +++ b/drivers/iio/humidity/hdc100x.c > @@ -31,7 +31,7 @@ > > struct hdc100x_data { > struct i2c_client *client; > - struct mutex lock; > + struct mutex lock; /* protect config updates & raw measurements */ > u16 config; > > /* integration time of the sensor */ > @@ -108,10 +108,12 @@ static int hdc100x_update_config(struct hdc100x_data > *data, int mask, int val) > int tmp = (~mask & data->config) | val; > int ret; > > + mutex_lock(>lock); > ret = i2c_smbus_write_word_swapped(data->client, > HDC100X_REG_CONFIG, tmp); > if (!ret) > data->config = tmp; > + mutex_unlock(>lock); > > return ret; > } > @@ -234,26 +236,20 @@ static int hdc100x_write_raw(struct iio_dev *indio_dev, >int val, int val2, long mask) > { > struct hdc100x_data *data = iio_priv(indio_dev); > - int ret = -EINVAL; > > switch (mask) { > case IIO_CHAN_INFO_INT_TIME: > if (val != 0) > return -EINVAL; > > - mutex_lock(>lock); > - ret = hdc100x_set_it_time(data, chan->address, val2); > - mutex_unlock(>lock); > - return ret; > + return hdc100x_set_it_time(data, chan->address, val2); > + > case IIO_CHAN_INFO_RAW: > if (chan->type != IIO_CURRENT || val2 != 0) > return -EINVAL; > > - mutex_lock(>lock); > - ret = hdc100x_update_config(data, HDC100X_REG_CONFIG_HEATER_EN, > + return hdc100x_update_config(data, HDC100X_REG_CONFIG_HEATER_EN, > val ? HDC100X_REG_CONFIG_HEATER_EN : 0); > - mutex_unlock(>lock); > - return ret; > default: > return -EINVAL; > } > -- > 2.1.4 >
Re: [PATCH 1/2] iio: humidity: hdc100x: move lock on config updates to single function
On Sun, Jul 10, 2016 at 02:30:01PM -0700, Alison Schofield wrote: > Move the config register locking to the config update function. This > continues to protect updates to heater and integration times. It puts > the lock in one place, right where it needs to occur. Since creating this patch, I've learned that it is a design choice in kernel drivers to keep the locking at a higher level - ie point of entry. This patch goes against that design, so, I get that it's not do-able. alisons > > Add the checkpatch required comment on this lock declaration. > > Signed-off-by: Alison Schofield > Cc: Daniel Baluta > --- > drivers/iio/humidity/hdc100x.c | 16 ++-- > 1 file changed, 6 insertions(+), 10 deletions(-) > > diff --git a/drivers/iio/humidity/hdc100x.c b/drivers/iio/humidity/hdc100x.c > index a03832a..ad5a12a 100644 > --- a/drivers/iio/humidity/hdc100x.c > +++ b/drivers/iio/humidity/hdc100x.c > @@ -31,7 +31,7 @@ > > struct hdc100x_data { > struct i2c_client *client; > - struct mutex lock; > + struct mutex lock; /* protect config updates & raw measurements */ > u16 config; > > /* integration time of the sensor */ > @@ -108,10 +108,12 @@ static int hdc100x_update_config(struct hdc100x_data > *data, int mask, int val) > int tmp = (~mask & data->config) | val; > int ret; > > + mutex_lock(>lock); > ret = i2c_smbus_write_word_swapped(data->client, > HDC100X_REG_CONFIG, tmp); > if (!ret) > data->config = tmp; > + mutex_unlock(>lock); > > return ret; > } > @@ -234,26 +236,20 @@ static int hdc100x_write_raw(struct iio_dev *indio_dev, >int val, int val2, long mask) > { > struct hdc100x_data *data = iio_priv(indio_dev); > - int ret = -EINVAL; > > switch (mask) { > case IIO_CHAN_INFO_INT_TIME: > if (val != 0) > return -EINVAL; > > - mutex_lock(>lock); > - ret = hdc100x_set_it_time(data, chan->address, val2); > - mutex_unlock(>lock); > - return ret; > + return hdc100x_set_it_time(data, chan->address, val2); > + > case IIO_CHAN_INFO_RAW: > if (chan->type != IIO_CURRENT || val2 != 0) > return -EINVAL; > > - mutex_lock(>lock); > - ret = hdc100x_update_config(data, HDC100X_REG_CONFIG_HEATER_EN, > + return hdc100x_update_config(data, HDC100X_REG_CONFIG_HEATER_EN, > val ? HDC100X_REG_CONFIG_HEATER_EN : 0); > - mutex_unlock(>lock); > - return ret; > default: > return -EINVAL; > } > -- > 2.1.4 >
Re: [PATCH] clk: probe common clock drivers earlier
2016-07-16 11:11 GMT+09:00 Michael Turquette: > Quoting Masahiro Yamada (2016-05-05 00:57:17) >> Several SoCs implement platform drivers for clocks rather than >> CLK_OF_DECLARE(). Clocks should come earlier because they are >> prerequisites for many of other drivers. It will help to mitigate >> EPROBE_DEFER issues. >> >> Also, drop the comment since it does not look valuable. >> >> Signed-off-by: Masahiro Yamada > > Acked-by: Michael Turquette > > Regards, > Mike > Thanks for taking a look at this patch. While I was wondering where is the best place for "obj-y += clk/", I thought it can be probed even earlier. So, v2 is here: https://patchwork.kernel.org/patch/9129749/ Please consider it as a applicable candidate. Thanks! -- Best Regards Masahiro Yamada
Re: [PATCH] clk: probe common clock drivers earlier
2016-07-16 11:11 GMT+09:00 Michael Turquette : > Quoting Masahiro Yamada (2016-05-05 00:57:17) >> Several SoCs implement platform drivers for clocks rather than >> CLK_OF_DECLARE(). Clocks should come earlier because they are >> prerequisites for many of other drivers. It will help to mitigate >> EPROBE_DEFER issues. >> >> Also, drop the comment since it does not look valuable. >> >> Signed-off-by: Masahiro Yamada > > Acked-by: Michael Turquette > > Regards, > Mike > Thanks for taking a look at this patch. While I was wondering where is the best place for "obj-y += clk/", I thought it can be probed even earlier. So, v2 is here: https://patchwork.kernel.org/patch/9129749/ Please consider it as a applicable candidate. Thanks! -- Best Regards Masahiro Yamada
Re: [RESEND PATCH 05/14] eeprom: at24: hide the read/write loop behind a macro
> > >> +#define loop_until_timeout(tout, op_time)\ > > >> + for (tout = jiffies + msecs_to_jiffies(write_timeout), \ > > >> + op_time = jiffies; \ > > >> + time_before(op_time, tout);\ > > >> + usleep_range(1000, 1500), op_time = jiffies) What about: #define loop_until_timeout(tout, op_time)\ for (tout = jiffies + msecs_to_jiffies(write_timeout), op_time = 0; \ op_time ? time_before(op_time, tout) : true; \ usleep_range(1000, 1500), op_time = jiffies) ? Would probably need an explanation in a comment, though. signature.asc Description: PGP signature
Re: [RESEND PATCH 05/14] eeprom: at24: hide the read/write loop behind a macro
> > >> +#define loop_until_timeout(tout, op_time)\ > > >> + for (tout = jiffies + msecs_to_jiffies(write_timeout), \ > > >> + op_time = jiffies; \ > > >> + time_before(op_time, tout);\ > > >> + usleep_range(1000, 1500), op_time = jiffies) What about: #define loop_until_timeout(tout, op_time)\ for (tout = jiffies + msecs_to_jiffies(write_timeout), op_time = 0; \ op_time ? time_before(op_time, tout) : true; \ usleep_range(1000, 1500), op_time = jiffies) ? Would probably need an explanation in a comment, though. signature.asc Description: PGP signature
Re: [RFC][PATCH 0/7] Add HDMI audio support for HiKey
On Fri, Jul 15, 2016 at 8:15 PM, Andy Greenwrote: > On Fri, 2016-07-15 at 19:13 -0700, John Stultz wrote: >> This patch set is required for HDMI audio support on HiKey. >> >> This patchset hasn't yet seen the light of lkml, so I suspect >> there will be a few revisions, but I wanted to send it out for >> an initial review. >> >> The work is mostly that of Andy Green's, but I've taking a swing >> at forward porting and cleaning it up where I saw fit. So credit >> to Andy and blame to me. Apologies in advance, as I'm not super >> familiar with either DMA or ASoC driver. >> >> The one bit missing to have audio fully working is changes to the >> adv7511 driver, but most of those changes are still out of tree, so >> I'll submit those changes once they land. >> >> Feedback would be very much appreicated! > > Thanks John, it's good to know that work didn't go to waste. > > The linaro.org email in the patches is dead, since I resigned from > Linaro a few months ago. If the goal of adding it to the kernel is to > make it possible to contact the author, it should change to > . Yea. I'm not sure what the communities policy on Author/SoB lines in the face of email address changes. For the moment I'll leave the credit lines as is (since that's how I got them, and changing SoB's is usually a big no no). But if others have advice on how to best handle this I'd appreciate it. I'll be sure to leave your new email in the Cc: entries. (Though I need to figure out how to get git send-email to not cc the author line to avoid the reply-all noise) > There are (were) a couple of limitations with it that should be > commented somewhere: > > 1) The cyclic DMA, at least going into the I2S FIFO, had what appeared > to be hw bugs when I left it, I had asked hisilicon about it but got no > useful reply. The DMA worked well generally, but there were audible > clicks and pops at intervals even though the DMA really is cyclic. I > dunno whether they got around to looking at it or not: if not, there > should probably be a comment in the driver about it. There were notes > in the I2S FIFO docs (it seemed the likely culprit) about needing to > take care about FIFO trigger levels but didn't seem to change anything. So against the 4.4 and later kernels, I've no longer had trouble with the pops and noise. There is an outstanding issue of a occasional DMA error from the hardware on the first transfer after opening the audio device, but some of the HiSi folks are looking into that. > 2) The driver only exposes 48kHz / 2ch. Yea. I've limited the i2s/hdmi-card driver to only 48k to match. thanks -john
Re: [RFC][PATCH 0/7] Add HDMI audio support for HiKey
On Fri, Jul 15, 2016 at 8:15 PM, Andy Green wrote: > On Fri, 2016-07-15 at 19:13 -0700, John Stultz wrote: >> This patch set is required for HDMI audio support on HiKey. >> >> This patchset hasn't yet seen the light of lkml, so I suspect >> there will be a few revisions, but I wanted to send it out for >> an initial review. >> >> The work is mostly that of Andy Green's, but I've taking a swing >> at forward porting and cleaning it up where I saw fit. So credit >> to Andy and blame to me. Apologies in advance, as I'm not super >> familiar with either DMA or ASoC driver. >> >> The one bit missing to have audio fully working is changes to the >> adv7511 driver, but most of those changes are still out of tree, so >> I'll submit those changes once they land. >> >> Feedback would be very much appreicated! > > Thanks John, it's good to know that work didn't go to waste. > > The linaro.org email in the patches is dead, since I resigned from > Linaro a few months ago. If the goal of adding it to the kernel is to > make it possible to contact the author, it should change to > . Yea. I'm not sure what the communities policy on Author/SoB lines in the face of email address changes. For the moment I'll leave the credit lines as is (since that's how I got them, and changing SoB's is usually a big no no). But if others have advice on how to best handle this I'd appreciate it. I'll be sure to leave your new email in the Cc: entries. (Though I need to figure out how to get git send-email to not cc the author line to avoid the reply-all noise) > There are (were) a couple of limitations with it that should be > commented somewhere: > > 1) The cyclic DMA, at least going into the I2S FIFO, had what appeared > to be hw bugs when I left it, I had asked hisilicon about it but got no > useful reply. The DMA worked well generally, but there were audible > clicks and pops at intervals even though the DMA really is cyclic. I > dunno whether they got around to looking at it or not: if not, there > should probably be a comment in the driver about it. There were notes > in the I2S FIFO docs (it seemed the likely culprit) about needing to > take care about FIFO trigger levels but didn't seem to change anything. So against the 4.4 and later kernels, I've no longer had trouble with the pops and noise. There is an outstanding issue of a occasional DMA error from the hardware on the first transfer after opening the audio device, but some of the HiSi folks are looking into that. > 2) The driver only exposes 48kHz / 2ch. Yea. I've limited the i2s/hdmi-card driver to only 48k to match. thanks -john
Re: [patch] tools/vm/slabinfo: fix an unintentional printf
On (07/16/16 00:12), Dan Carpenter wrote: > The curly braces are missing here so we print stuff unintentionally. > > Fixes: 9da4714a2d4f ('slub: slabinfo update for cmpxchg handling') Hello, a minor correction: it's9da4714a2d44 not 9da4714a2d4f -ss > Signed-off-by: Dan Carpenter> > diff --git a/tools/vm/slabinfo.c b/tools/vm/slabinfo.c > index 7cf6e17..b9d34b3 100644 > --- a/tools/vm/slabinfo.c > +++ b/tools/vm/slabinfo.c > @@ -510,10 +510,11 @@ static void slab_stats(struct slabinfo *s) > s->alloc_node_mismatch, (s->alloc_node_mismatch * 100) > / total); > } > > - if (s->cmpxchg_double_fail || s->cmpxchg_double_cpu_fail) > + if (s->cmpxchg_double_fail || s->cmpxchg_double_cpu_fail) { > printf("\nCmpxchg_double Looping\n\n"); > printf("Locked Cmpxchg Double redos %lu\nUnlocked Cmpxchg > Double redos %lu\n", > s->cmpxchg_double_fail, s->cmpxchg_double_cpu_fail); > + } > } > > static void report(struct slabinfo *s) >
Re: [patch] tools/vm/slabinfo: fix an unintentional printf
On (07/16/16 00:12), Dan Carpenter wrote: > The curly braces are missing here so we print stuff unintentionally. > > Fixes: 9da4714a2d4f ('slub: slabinfo update for cmpxchg handling') Hello, a minor correction: it's9da4714a2d44 not 9da4714a2d4f -ss > Signed-off-by: Dan Carpenter > > diff --git a/tools/vm/slabinfo.c b/tools/vm/slabinfo.c > index 7cf6e17..b9d34b3 100644 > --- a/tools/vm/slabinfo.c > +++ b/tools/vm/slabinfo.c > @@ -510,10 +510,11 @@ static void slab_stats(struct slabinfo *s) > s->alloc_node_mismatch, (s->alloc_node_mismatch * 100) > / total); > } > > - if (s->cmpxchg_double_fail || s->cmpxchg_double_cpu_fail) > + if (s->cmpxchg_double_fail || s->cmpxchg_double_cpu_fail) { > printf("\nCmpxchg_double Looping\n\n"); > printf("Locked Cmpxchg Double redos %lu\nUnlocked Cmpxchg > Double redos %lu\n", > s->cmpxchg_double_fail, s->cmpxchg_double_cpu_fail); > + } > } > > static void report(struct slabinfo *s) >
Re: [RFC][PATCH 0/7] Add HDMI audio support for HiKey
On Fri, 2016-07-15 at 19:13 -0700, John Stultz wrote: > This patch set is required for HDMI audio support on HiKey. > > This patchset hasn't yet seen the light of lkml, so I suspect > there will be a few revisions, but I wanted to send it out for > an initial review. > > The work is mostly that of Andy Green's, but I've taking a swing > at forward porting and cleaning it up where I saw fit. So credit > to Andy and blame to me. Apologies in advance, as I'm not super > familiar with either DMA or ASoC driver. > > The one bit missing to have audio fully working is changes to the > adv7511 driver, but most of those changes are still out of tree, so > I'll submit those changes once they land. > > Feedback would be very much appreicated! Thanks John, it's good to know that work didn't go to waste. The linaro.org email in the patches is dead, since I resigned from Linaro a few months ago. If the goal of adding it to the kernel is to make it possible to contact the author, it should change to. There are (were) a couple of limitations with it that should be commented somewhere: 1) The cyclic DMA, at least going into the I2S FIFO, had what appeared to be hw bugs when I left it, I had asked hisilicon about it but got no useful reply. The DMA worked well generally, but there were audible clicks and pops at intervals even though the DMA really is cyclic. I dunno whether they got around to looking at it or not: if not, there should probably be a comment in the driver about it. There were notes in the I2S FIFO docs (it seemed the likely culprit) about needing to take care about FIFO trigger levels but didn't seem to change anything. 2) The driver only exposes 48kHz / 2ch. Otherwise it worked well. Thanks again for upstreaming it. -Andy > thanks > -john > > Cc: Zhangfei Gao > Cc: Jingoo Han > Cc: Krzysztof Kozlowski > Cc: Maxime Ripard > Cc: Vinod Koul > Cc: Dan Williams > Cc: Liam Girdwood > Cc: Mark Brown > Cc: Jaroslav Kysela > Cc: Takashi Iwai > Cc: Wei Xu > Cc: Rob Herring > Cc: Andy Green > Cc: Dave Long > Cc: Guodong Xu > > Andy Green (5): > k3dma: Fix hisi burst clipping > k3dma: Fix dma err offsets > k3dma: Fix "nobody cared" message seen on any error > k3dma: Add cyclic mode for audio > ASoC: hisilicon: Add hi6210 i2s audio driver for hdmi audio > > John Stultz (2): > Kconfig: Allow k3dma driver to be selected for more then HISI3xx > platforms > dts: hi6220: Add k3-dma and i2s/hdmi audio support > > arch/arm64/boot/dts/hisilicon/hi6220.dtsi | 36 ++ > drivers/dma/Kconfig | 1 - > drivers/dma/k3dma.c | 149 ++- > sound/soc/Kconfig | 1 + > sound/soc/Makefile| 1 + > sound/soc/hisilicon/Kconfig | 5 + > sound/soc/hisilicon/Makefile | 2 + > sound/soc/hisilicon/hi6210-hdmi-card.c| 131 ++ > sound/soc/hisilicon/hi6210-i2s.c | 641 > ++ > sound/soc/hisilicon/hi6210-i2s.h | 276 + > 10 files changed, 1222 insertions(+), 21 deletions(-) > create mode 100644 sound/soc/hisilicon/Kconfig > create mode 100644 sound/soc/hisilicon/Makefile > create mode 100644 sound/soc/hisilicon/hi6210-hdmi-card.c > create mode 100644 sound/soc/hisilicon/hi6210-i2s.c > create mode 100644 sound/soc/hisilicon/hi6210-i2s.h >
RE: Memory and IO space Enabling different in x86 and ARM64
> Subject: Re: Memory and IO space Enabling different in x86 and ARM64 > > On Fri, Jul 15, 2016 at 08:29:49AM +, Bharat Kumar Gogada wrote: > > Hi, > > > > I observe that memory and IO space are enabled by BIOS in x86. > > > > In ARM64 we need to call pci_enable_device form End Point to enable > these resources. > > > > Why the resource enablement is different in x86 and ARM64 ? > > A portable driver should call pci_enable_device() if it needs access > to any BARs. As you've observed, the command register enable bits may > be set differently on different architectures, and the PCI core > doesn't set them automatically for you, so the driver can't rely on > their initial settings. > > One reason why Linux doesn't enable them automatically before calling > the driver's probe method is that it may not be possible to allocate > space for all the BARs (e.g., if the platform doesn't support I/O port > space, or if we just run out of space), but the driver may be able to > operate the device even without all the BARs. > Thanks Bjorn This email and any attachments are intended for the sole use of the named recipient(s) and contain(s) confidential information that may be proprietary, privileged or copyrighted under applicable law. If you are not the intended recipient, do not read, copy, or forward this email message or any attachments. Delete this email message and any attachments immediately.
Re: [RFC][PATCH 0/7] Add HDMI audio support for HiKey
On Fri, 2016-07-15 at 19:13 -0700, John Stultz wrote: > This patch set is required for HDMI audio support on HiKey. > > This patchset hasn't yet seen the light of lkml, so I suspect > there will be a few revisions, but I wanted to send it out for > an initial review. > > The work is mostly that of Andy Green's, but I've taking a swing > at forward porting and cleaning it up where I saw fit. So credit > to Andy and blame to me. Apologies in advance, as I'm not super > familiar with either DMA or ASoC driver. > > The one bit missing to have audio fully working is changes to the > adv7511 driver, but most of those changes are still out of tree, so > I'll submit those changes once they land. > > Feedback would be very much appreicated! Thanks John, it's good to know that work didn't go to waste. The linaro.org email in the patches is dead, since I resigned from Linaro a few months ago. If the goal of adding it to the kernel is to make it possible to contact the author, it should change to . There are (were) a couple of limitations with it that should be commented somewhere: 1) The cyclic DMA, at least going into the I2S FIFO, had what appeared to be hw bugs when I left it, I had asked hisilicon about it but got no useful reply. The DMA worked well generally, but there were audible clicks and pops at intervals even though the DMA really is cyclic. I dunno whether they got around to looking at it or not: if not, there should probably be a comment in the driver about it. There were notes in the I2S FIFO docs (it seemed the likely culprit) about needing to take care about FIFO trigger levels but didn't seem to change anything. 2) The driver only exposes 48kHz / 2ch. Otherwise it worked well. Thanks again for upstreaming it. -Andy > thanks > -john > > Cc: Zhangfei Gao > Cc: Jingoo Han > Cc: Krzysztof Kozlowski > Cc: Maxime Ripard > Cc: Vinod Koul > Cc: Dan Williams > Cc: Liam Girdwood > Cc: Mark Brown > Cc: Jaroslav Kysela > Cc: Takashi Iwai > Cc: Wei Xu > Cc: Rob Herring > Cc: Andy Green > Cc: Dave Long > Cc: Guodong Xu > > Andy Green (5): > k3dma: Fix hisi burst clipping > k3dma: Fix dma err offsets > k3dma: Fix "nobody cared" message seen on any error > k3dma: Add cyclic mode for audio > ASoC: hisilicon: Add hi6210 i2s audio driver for hdmi audio > > John Stultz (2): > Kconfig: Allow k3dma driver to be selected for more then HISI3xx > platforms > dts: hi6220: Add k3-dma and i2s/hdmi audio support > > arch/arm64/boot/dts/hisilicon/hi6220.dtsi | 36 ++ > drivers/dma/Kconfig | 1 - > drivers/dma/k3dma.c | 149 ++- > sound/soc/Kconfig | 1 + > sound/soc/Makefile| 1 + > sound/soc/hisilicon/Kconfig | 5 + > sound/soc/hisilicon/Makefile | 2 + > sound/soc/hisilicon/hi6210-hdmi-card.c| 131 ++ > sound/soc/hisilicon/hi6210-i2s.c | 641 > ++ > sound/soc/hisilicon/hi6210-i2s.h | 276 + > 10 files changed, 1222 insertions(+), 21 deletions(-) > create mode 100644 sound/soc/hisilicon/Kconfig > create mode 100644 sound/soc/hisilicon/Makefile > create mode 100644 sound/soc/hisilicon/hi6210-hdmi-card.c > create mode 100644 sound/soc/hisilicon/hi6210-i2s.c > create mode 100644 sound/soc/hisilicon/hi6210-i2s.h >
RE: Memory and IO space Enabling different in x86 and ARM64
> Subject: Re: Memory and IO space Enabling different in x86 and ARM64 > > On Fri, Jul 15, 2016 at 08:29:49AM +, Bharat Kumar Gogada wrote: > > Hi, > > > > I observe that memory and IO space are enabled by BIOS in x86. > > > > In ARM64 we need to call pci_enable_device form End Point to enable > these resources. > > > > Why the resource enablement is different in x86 and ARM64 ? > > A portable driver should call pci_enable_device() if it needs access > to any BARs. As you've observed, the command register enable bits may > be set differently on different architectures, and the PCI core > doesn't set them automatically for you, so the driver can't rely on > their initial settings. > > One reason why Linux doesn't enable them automatically before calling > the driver's probe method is that it may not be possible to allocate > space for all the BARs (e.g., if the platform doesn't support I/O port > space, or if we just run out of space), but the driver may be able to > operate the device even without all the BARs. > Thanks Bjorn This email and any attachments are intended for the sole use of the named recipient(s) and contain(s) confidential information that may be proprietary, privileged or copyrighted under applicable law. If you are not the intended recipient, do not read, copy, or forward this email message or any attachments. Delete this email message and any attachments immediately.
[ANNOUNCE] 3.14.73-rt78
Dear RT Folks, I'm pleased to announce the 3.14.73-rt78 stable release. Due to a bug in a backport, I had to make a quick update. Reported-by: Arnd BergmannYou can get this release via the git tree at: git://git.kernel.org/pub/scm/linux/kernel/git/rt/linux-stable-rt.git branch: v3.14-rt Head SHA1: 01af6fad4dae666b64d5db5ec6807b1f2994f438 Or to build 3.14.73-rt78 directly, the following patches should be applied: http://www.kernel.org/pub/linux/kernel/v3.x/linux-3.14.tar.xz http://www.kernel.org/pub/linux/kernel/v3.x/patch-3.14.73.xz http://www.kernel.org/pub/linux/kernel/projects/rt/3.14/patch-3.14.73-rt78.patch.xz You can also build from 3.14.73-rt77 by applying the incremental patch: http://www.kernel.org/pub/linux/kernel/projects/rt/3.14/incr/patch-3.14.73-rt77-rt78.patch.xz Enjoy, -- Steve Changes from v3.14.73-rt77: --- Steven Rostedt (Red Hat) (2): Fix backport of: sched,preempt: Fix preempt_count manipulations Linux 3.14.73-rt78 include/asm-generic/preempt.h | 2 +- localversion-rt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) --- diff --git a/include/asm-generic/preempt.h b/include/asm-generic/preempt.h index 65759d8b0b46..25c09df2c046 100644 --- a/include/asm-generic/preempt.h +++ b/include/asm-generic/preempt.h @@ -7,7 +7,7 @@ static __always_inline int preempt_count(void) { - return READ_ONCE(current_thread_info()->preempt_count); + return ACCESS_ONCE(current_thread_info()->preempt_count); } static __always_inline volatile int *preempt_count_ptr(void) diff --git a/localversion-rt b/localversion-rt index 595841feef80..30758e0b2242 100644 --- a/localversion-rt +++ b/localversion-rt @@ -1 +1 @@ --rt77 +-rt78
[ANNOUNCE] 3.14.73-rt78
Dear RT Folks, I'm pleased to announce the 3.14.73-rt78 stable release. Due to a bug in a backport, I had to make a quick update. Reported-by: Arnd Bergmann You can get this release via the git tree at: git://git.kernel.org/pub/scm/linux/kernel/git/rt/linux-stable-rt.git branch: v3.14-rt Head SHA1: 01af6fad4dae666b64d5db5ec6807b1f2994f438 Or to build 3.14.73-rt78 directly, the following patches should be applied: http://www.kernel.org/pub/linux/kernel/v3.x/linux-3.14.tar.xz http://www.kernel.org/pub/linux/kernel/v3.x/patch-3.14.73.xz http://www.kernel.org/pub/linux/kernel/projects/rt/3.14/patch-3.14.73-rt78.patch.xz You can also build from 3.14.73-rt77 by applying the incremental patch: http://www.kernel.org/pub/linux/kernel/projects/rt/3.14/incr/patch-3.14.73-rt77-rt78.patch.xz Enjoy, -- Steve Changes from v3.14.73-rt77: --- Steven Rostedt (Red Hat) (2): Fix backport of: sched,preempt: Fix preempt_count manipulations Linux 3.14.73-rt78 include/asm-generic/preempt.h | 2 +- localversion-rt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) --- diff --git a/include/asm-generic/preempt.h b/include/asm-generic/preempt.h index 65759d8b0b46..25c09df2c046 100644 --- a/include/asm-generic/preempt.h +++ b/include/asm-generic/preempt.h @@ -7,7 +7,7 @@ static __always_inline int preempt_count(void) { - return READ_ONCE(current_thread_info()->preempt_count); + return ACCESS_ONCE(current_thread_info()->preempt_count); } static __always_inline volatile int *preempt_count_ptr(void) diff --git a/localversion-rt b/localversion-rt index 595841feef80..30758e0b2242 100644 --- a/localversion-rt +++ b/localversion-rt @@ -1 +1 @@ --rt77 +-rt78
RE: Memory and IO space Enabling different in x86 and ARM64
> Subject: Re: Memory and IO space Enabling different in x86 and ARM64 > > On Friday, July 15, 2016 8:29:49 AM CEST Bharat Kumar Gogada wrote: > > I observe that memory and IO space are enabled by BIOS in x86. > > > > In ARM64 we need to call pci_enable_device form End Point to enable > these resources. > > > > Why the resource enablement is different in x86 and ARM64 ? > > > > Please correct me if my observation is wrong. > > This is a difference between systems with a BIOS and embedded systems > with a plain bootloader that ignores PCI. On an ARM64 server system with > UEFI you should expect the device to be usable too, but on an embedded > system, Linux takes the role of the BIOS. > Thanks Arnd Bergmann This email and any attachments are intended for the sole use of the named recipient(s) and contain(s) confidential information that may be proprietary, privileged or copyrighted under applicable law. If you are not the intended recipient, do not read, copy, or forward this email message or any attachments. Delete this email message and any attachments immediately.
RE: Memory and IO space Enabling different in x86 and ARM64
> Subject: Re: Memory and IO space Enabling different in x86 and ARM64 > > On Friday, July 15, 2016 8:29:49 AM CEST Bharat Kumar Gogada wrote: > > I observe that memory and IO space are enabled by BIOS in x86. > > > > In ARM64 we need to call pci_enable_device form End Point to enable > these resources. > > > > Why the resource enablement is different in x86 and ARM64 ? > > > > Please correct me if my observation is wrong. > > This is a difference between systems with a BIOS and embedded systems > with a plain bootloader that ignores PCI. On an ARM64 server system with > UEFI you should expect the device to be usable too, but on an embedded > system, Linux takes the role of the BIOS. > Thanks Arnd Bergmann This email and any attachments are intended for the sole use of the named recipient(s) and contain(s) confidential information that may be proprietary, privileged or copyrighted under applicable law. If you are not the intended recipient, do not read, copy, or forward this email message or any attachments. Delete this email message and any attachments immediately.
Re: [PATCH v2 4/4] hwmon: iio: add label for channels read by iio_hwmon
On 07/15/2016 07:36 AM, Quentin Schulz wrote: On 15/07/2016 16:03, Guenter Roeck wrote: On 07/15/2016 02:59 AM, Quentin Schulz wrote: [...] +static ssize_t iio_hwmon_read_label(struct device *dev, +struct device_attribute *attr, +char *buf) +{ +struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr); +struct iio_hwmon_state *state = dev_get_drvdata(dev); +const char *label = state->channels[sattr->index].channel->extend_name; + +if (label) +return sprintf(buf, "%s\n", label); + Can the name disappear on the fly, or be changed on the fly ? Then this is unusable. We should and can only provide labels if a name exists and is permanent. Otherwise all we do is to confuse user space. It cannot, the extend_name field is const char* in the struct: http://lxr.free-electrons.com/source/include/linux/iio/iio.h#L247 Then why "if(label)" ? [...] @@ -107,6 +123,18 @@ static int iio_hwmon_probe(struct platform_device *pdev) } sysfs_attr_init(>dev_attr.attr); + +b = NULL; +if (st->channels[i].channel->extend_name) { +b = devm_kzalloc(dev, sizeof(*b), GFP_KERNEL); +if (b == NULL) { +ret = -ENOMEM; +goto error_release_channels; +} + +sysfs_attr_init(>dev_attr.attr); Why is this initialization here and not with the rest of the initialization of this attribute ? I don't get your question. I've followed the exact same pattern as for "a" variable's initialization. The initialization is before the switch case because the name of the exposed sysfs file depends on the type of the IIO channel. If I move the initialization in the switch case, I'll have duplicated code. Yes, but that didn't require all those if statements. +} + ret = iio_get_channel_type(>channels[i], ); if (ret < 0) goto error_release_channels; @@ -115,35 +143,66 @@ static int iio_hwmon_probe(struct platform_device *pdev) case IIO_VOLTAGE: a->dev_attr.attr.name = kasprintf(GFP_KERNEL, "in%d_input", - in_i++); + in_i); +if (b) +b->dev_attr.attr.name = kasprintf(GFP_KERNEL, + "in%d_label", + in_i); +in_i++; break; case IIO_TEMP: a->dev_attr.attr.name = kasprintf(GFP_KERNEL, "temp%d_input", - temp_i++); + temp_i); + +if (b) +b->dev_attr.attr.name = kasprintf(GFP_KERNEL, + "temp%d_label", + temp_i); +temp_i++; break; case IIO_CURRENT: a->dev_attr.attr.name = kasprintf(GFP_KERNEL, "curr%d_input", - curr_i++); + curr_i); + +if (b) +b->dev_attr.attr.name = kasprintf(GFP_KERNEL, + "curr%d_label", + curr_i); +curr_i++; break; case IIO_HUMIDITYRELATIVE: a->dev_attr.attr.name = kasprintf(GFP_KERNEL, "humidity%d_input", - humidity_i++); + humidity_i); + +if (b) +b->dev_attr.attr.name = kasprintf(GFP_KERNEL, + "humidity%d_label", + humidity_i); +humidity_i++; break; default: ret = -EINVAL; goto error_release_channels; } -if (a->dev_attr.attr.name == NULL) { +if (a->dev_attr.attr.name == NULL || +(b && b->dev_attr.attr.name == NULL)) { ret = -ENOMEM; goto error_release_channels; } Just realized that we have a memory leak here. The 'name' memory is never released. I don't know if we have to do something to revert the effects of sysfs_attr_init but you sure are right that the a and b's attribute's name is never freed. This case would be handled with devm_kasprintf, I guess? Thanks. a->dev_attr.show = iio_hwmon_read_val; a->dev_attr.attr.mode = S_IRUGO; a->index = i; -st->attrs[i] = >dev_attr.attr; +st->attrs[j++] = >dev_attr.attr; + +if (b) { sysfs_attr_init() might be better here to keep the initialization of '*b' as close together as possible. Guenetr +b->dev_attr.show = iio_hwmon_read_label; +b->dev_attr.attr.mode = S_IRUGO; +b->index = i; +st->attrs[j++]
Re: [PATCH v2 4/4] hwmon: iio: add label for channels read by iio_hwmon
On 07/15/2016 07:36 AM, Quentin Schulz wrote: On 15/07/2016 16:03, Guenter Roeck wrote: On 07/15/2016 02:59 AM, Quentin Schulz wrote: [...] +static ssize_t iio_hwmon_read_label(struct device *dev, +struct device_attribute *attr, +char *buf) +{ +struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr); +struct iio_hwmon_state *state = dev_get_drvdata(dev); +const char *label = state->channels[sattr->index].channel->extend_name; + +if (label) +return sprintf(buf, "%s\n", label); + Can the name disappear on the fly, or be changed on the fly ? Then this is unusable. We should and can only provide labels if a name exists and is permanent. Otherwise all we do is to confuse user space. It cannot, the extend_name field is const char* in the struct: http://lxr.free-electrons.com/source/include/linux/iio/iio.h#L247 Then why "if(label)" ? [...] @@ -107,6 +123,18 @@ static int iio_hwmon_probe(struct platform_device *pdev) } sysfs_attr_init(>dev_attr.attr); + +b = NULL; +if (st->channels[i].channel->extend_name) { +b = devm_kzalloc(dev, sizeof(*b), GFP_KERNEL); +if (b == NULL) { +ret = -ENOMEM; +goto error_release_channels; +} + +sysfs_attr_init(>dev_attr.attr); Why is this initialization here and not with the rest of the initialization of this attribute ? I don't get your question. I've followed the exact same pattern as for "a" variable's initialization. The initialization is before the switch case because the name of the exposed sysfs file depends on the type of the IIO channel. If I move the initialization in the switch case, I'll have duplicated code. Yes, but that didn't require all those if statements. +} + ret = iio_get_channel_type(>channels[i], ); if (ret < 0) goto error_release_channels; @@ -115,35 +143,66 @@ static int iio_hwmon_probe(struct platform_device *pdev) case IIO_VOLTAGE: a->dev_attr.attr.name = kasprintf(GFP_KERNEL, "in%d_input", - in_i++); + in_i); +if (b) +b->dev_attr.attr.name = kasprintf(GFP_KERNEL, + "in%d_label", + in_i); +in_i++; break; case IIO_TEMP: a->dev_attr.attr.name = kasprintf(GFP_KERNEL, "temp%d_input", - temp_i++); + temp_i); + +if (b) +b->dev_attr.attr.name = kasprintf(GFP_KERNEL, + "temp%d_label", + temp_i); +temp_i++; break; case IIO_CURRENT: a->dev_attr.attr.name = kasprintf(GFP_KERNEL, "curr%d_input", - curr_i++); + curr_i); + +if (b) +b->dev_attr.attr.name = kasprintf(GFP_KERNEL, + "curr%d_label", + curr_i); +curr_i++; break; case IIO_HUMIDITYRELATIVE: a->dev_attr.attr.name = kasprintf(GFP_KERNEL, "humidity%d_input", - humidity_i++); + humidity_i); + +if (b) +b->dev_attr.attr.name = kasprintf(GFP_KERNEL, + "humidity%d_label", + humidity_i); +humidity_i++; break; default: ret = -EINVAL; goto error_release_channels; } -if (a->dev_attr.attr.name == NULL) { +if (a->dev_attr.attr.name == NULL || +(b && b->dev_attr.attr.name == NULL)) { ret = -ENOMEM; goto error_release_channels; } Just realized that we have a memory leak here. The 'name' memory is never released. I don't know if we have to do something to revert the effects of sysfs_attr_init but you sure are right that the a and b's attribute's name is never freed. This case would be handled with devm_kasprintf, I guess? Thanks. a->dev_attr.show = iio_hwmon_read_val; a->dev_attr.attr.mode = S_IRUGO; a->index = i; -st->attrs[i] = >dev_attr.attr; +st->attrs[j++] = >dev_attr.attr; + +if (b) { sysfs_attr_init() might be better here to keep the initialization of '*b' as close together as possible. Guenetr +b->dev_attr.show = iio_hwmon_read_label; +b->dev_attr.attr.mode = S_IRUGO; +b->index = i; +st->attrs[j++]
Re: [PATCH v4.1 3/4] drm/bridge: analogix_dp: add the PSR function support
Sean, On 07/15/2016 09:13 PM, Sean Paul wrote: On Fri, Jul 15, 2016 at 06:55:17PM +0800, Yakir Yang wrote: The full name of PSR is Panel Self Refresh, panel device could refresh itself with the hardware framebuffer in panel, this would make lots of sense to save the power consumption. This patch have exported two symbols for platform driver to implement the PSR function in hardware side: - analogix_dp_active_psr() - analogix_dp_inactive_psr() Signed-off-by: Yakir YangReviewed-by: Sean Paul Thanks for your reviewed :-D - Yakir --- Changes in v4.1: - Take use of existing edp_psr_vsc struct to swap HBx and DBx setting. (Sean) - Remove PSR_VID_CRC_FLUSH setting analogix_dp_enable_psr_crc(). - Add comment about PBx magic numbers. (Sean) Changes in v4: - Downgrade the PSR version print message to debug level. (Sean) - Return 'void' instead of 'int' in analogix_dp_enable_sink_psr(). (Sean) - Delete the unused read dpcd operations in analogix_dp_enable_sink_psr(). (Sean) - Delete the arbitrary usleep_range in analogix_dp_enable_psr_crc. (Sean). - Clean up the hardcoded values in analogix_dp_send_psr_spd(). (Sean) - Rename "active/inactive" to "enable/disable". (Sean, Dominik) - Keep set the PSR_VID_CRC_FLUSH gate in analogix_dp_enable_psr_crc(). Changes in v3: - split analogix_dp_enable_psr(), make it more clearly analogix_dp_detect_sink_psr() analogix_dp_enable_sink_psr() - remove some nosie register setting comments Changes in v2: - introduce in v2, splite the common Analogix DP changes out drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 81 ++ drivers/gpu/drm/bridge/analogix/analogix_dp_core.h | 5 ++ drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c | 51 ++ drivers/gpu/drm/bridge/analogix/analogix_dp_reg.h | 34 + include/drm/bridge/analogix_dp.h | 3 + 5 files changed, 174 insertions(+) diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c index 32715da..381b25e 100644 --- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c +++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c @@ -97,6 +97,83 @@ static int analogix_dp_detect_hpd(struct analogix_dp_device *dp) return 0; } +int analogix_dp_enable_psr(struct device *dev) +{ + struct analogix_dp_device *dp = dev_get_drvdata(dev); + struct edp_vsc_psr psr_vsc; + + if (!dp->psr_support) + return -EINVAL; + + /* Prepare VSC packet as per EDP 1.4 spec, Table 6.9 */ + memset(_vsc, 0, sizeof(psr_vsc)); + psr_vsc.sdp_header.HB0 = 0; + psr_vsc.sdp_header.HB1 = 0x7; + psr_vsc.sdp_header.HB2 = 0x2; + psr_vsc.sdp_header.HB3 = 0x8; + + psr_vsc.DB0 = 0; + psr_vsc.DB1 = EDP_VSC_PSR_STATE_ACTIVE | EDP_VSC_PSR_CRC_VALUES_VALID; + + analogix_dp_send_psr_spd(dp, _vsc); + return 0; +} +EXPORT_SYMBOL_GPL(analogix_dp_enable_psr); + +int analogix_dp_disable_psr(struct device *dev) +{ + struct analogix_dp_device *dp = dev_get_drvdata(dev); + struct edp_vsc_psr psr_vsc; + + if (!dp->psr_support) + return -EINVAL; + + /* Prepare VSC packet as per EDP 1.4 spec, Table 6.9 */ + memset(_vsc, 0, sizeof(psr_vsc)); + psr_vsc.sdp_header.HB0 = 0; + psr_vsc.sdp_header.HB1 = 0x7; + psr_vsc.sdp_header.HB2 = 0x2; + psr_vsc.sdp_header.HB3 = 0x8; + + psr_vsc.DB0 = 0; + psr_vsc.DB1 = 0; + + analogix_dp_send_psr_spd(dp, _vsc); + return 0; +} +EXPORT_SYMBOL_GPL(analogix_dp_disable_psr); + +static bool analogix_dp_detect_sink_psr(struct analogix_dp_device *dp) +{ + unsigned char psr_version; + + analogix_dp_read_byte_from_dpcd(dp, DP_PSR_SUPPORT, _version); + dev_dbg(dp->dev, "Panel PSR version : %x\n", psr_version); + + return (psr_version & DP_PSR_IS_SUPPORTED) ? true : false; +} + +static void analogix_dp_enable_sink_psr(struct analogix_dp_device *dp) +{ + unsigned char psr_en; + + /* Disable psr function */ + analogix_dp_read_byte_from_dpcd(dp, DP_PSR_EN_CFG, _en); + psr_en &= ~DP_PSR_ENABLE; + analogix_dp_write_byte_to_dpcd(dp, DP_PSR_EN_CFG, psr_en); + + /* Main-Link transmitter remains active during PSR active states */ + psr_en = DP_PSR_MAIN_LINK_ACTIVE | DP_PSR_CRC_VERIFICATION; + analogix_dp_write_byte_to_dpcd(dp, DP_PSR_EN_CFG, psr_en); + + /* Enable psr function */ + psr_en = DP_PSR_ENABLE | DP_PSR_MAIN_LINK_ACTIVE | +DP_PSR_CRC_VERIFICATION; + analogix_dp_write_byte_to_dpcd(dp, DP_PSR_EN_CFG, psr_en); + + analogix_dp_enable_psr_crc(dp); +} + static unsigned char analogix_dp_calc_edid_check_sum(unsigned char *edid_data) { int i; @@ -921,6 +998,10 @@ static void analogix_dp_commit(struct analogix_dp_device *dp) /* Enable video */
Re: [PATCH v4.1 3/4] drm/bridge: analogix_dp: add the PSR function support
Sean, On 07/15/2016 09:13 PM, Sean Paul wrote: On Fri, Jul 15, 2016 at 06:55:17PM +0800, Yakir Yang wrote: The full name of PSR is Panel Self Refresh, panel device could refresh itself with the hardware framebuffer in panel, this would make lots of sense to save the power consumption. This patch have exported two symbols for platform driver to implement the PSR function in hardware side: - analogix_dp_active_psr() - analogix_dp_inactive_psr() Signed-off-by: Yakir Yang Reviewed-by: Sean Paul Thanks for your reviewed :-D - Yakir --- Changes in v4.1: - Take use of existing edp_psr_vsc struct to swap HBx and DBx setting. (Sean) - Remove PSR_VID_CRC_FLUSH setting analogix_dp_enable_psr_crc(). - Add comment about PBx magic numbers. (Sean) Changes in v4: - Downgrade the PSR version print message to debug level. (Sean) - Return 'void' instead of 'int' in analogix_dp_enable_sink_psr(). (Sean) - Delete the unused read dpcd operations in analogix_dp_enable_sink_psr(). (Sean) - Delete the arbitrary usleep_range in analogix_dp_enable_psr_crc. (Sean). - Clean up the hardcoded values in analogix_dp_send_psr_spd(). (Sean) - Rename "active/inactive" to "enable/disable". (Sean, Dominik) - Keep set the PSR_VID_CRC_FLUSH gate in analogix_dp_enable_psr_crc(). Changes in v3: - split analogix_dp_enable_psr(), make it more clearly analogix_dp_detect_sink_psr() analogix_dp_enable_sink_psr() - remove some nosie register setting comments Changes in v2: - introduce in v2, splite the common Analogix DP changes out drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 81 ++ drivers/gpu/drm/bridge/analogix/analogix_dp_core.h | 5 ++ drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c | 51 ++ drivers/gpu/drm/bridge/analogix/analogix_dp_reg.h | 34 + include/drm/bridge/analogix_dp.h | 3 + 5 files changed, 174 insertions(+) diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c index 32715da..381b25e 100644 --- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c +++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c @@ -97,6 +97,83 @@ static int analogix_dp_detect_hpd(struct analogix_dp_device *dp) return 0; } +int analogix_dp_enable_psr(struct device *dev) +{ + struct analogix_dp_device *dp = dev_get_drvdata(dev); + struct edp_vsc_psr psr_vsc; + + if (!dp->psr_support) + return -EINVAL; + + /* Prepare VSC packet as per EDP 1.4 spec, Table 6.9 */ + memset(_vsc, 0, sizeof(psr_vsc)); + psr_vsc.sdp_header.HB0 = 0; + psr_vsc.sdp_header.HB1 = 0x7; + psr_vsc.sdp_header.HB2 = 0x2; + psr_vsc.sdp_header.HB3 = 0x8; + + psr_vsc.DB0 = 0; + psr_vsc.DB1 = EDP_VSC_PSR_STATE_ACTIVE | EDP_VSC_PSR_CRC_VALUES_VALID; + + analogix_dp_send_psr_spd(dp, _vsc); + return 0; +} +EXPORT_SYMBOL_GPL(analogix_dp_enable_psr); + +int analogix_dp_disable_psr(struct device *dev) +{ + struct analogix_dp_device *dp = dev_get_drvdata(dev); + struct edp_vsc_psr psr_vsc; + + if (!dp->psr_support) + return -EINVAL; + + /* Prepare VSC packet as per EDP 1.4 spec, Table 6.9 */ + memset(_vsc, 0, sizeof(psr_vsc)); + psr_vsc.sdp_header.HB0 = 0; + psr_vsc.sdp_header.HB1 = 0x7; + psr_vsc.sdp_header.HB2 = 0x2; + psr_vsc.sdp_header.HB3 = 0x8; + + psr_vsc.DB0 = 0; + psr_vsc.DB1 = 0; + + analogix_dp_send_psr_spd(dp, _vsc); + return 0; +} +EXPORT_SYMBOL_GPL(analogix_dp_disable_psr); + +static bool analogix_dp_detect_sink_psr(struct analogix_dp_device *dp) +{ + unsigned char psr_version; + + analogix_dp_read_byte_from_dpcd(dp, DP_PSR_SUPPORT, _version); + dev_dbg(dp->dev, "Panel PSR version : %x\n", psr_version); + + return (psr_version & DP_PSR_IS_SUPPORTED) ? true : false; +} + +static void analogix_dp_enable_sink_psr(struct analogix_dp_device *dp) +{ + unsigned char psr_en; + + /* Disable psr function */ + analogix_dp_read_byte_from_dpcd(dp, DP_PSR_EN_CFG, _en); + psr_en &= ~DP_PSR_ENABLE; + analogix_dp_write_byte_to_dpcd(dp, DP_PSR_EN_CFG, psr_en); + + /* Main-Link transmitter remains active during PSR active states */ + psr_en = DP_PSR_MAIN_LINK_ACTIVE | DP_PSR_CRC_VERIFICATION; + analogix_dp_write_byte_to_dpcd(dp, DP_PSR_EN_CFG, psr_en); + + /* Enable psr function */ + psr_en = DP_PSR_ENABLE | DP_PSR_MAIN_LINK_ACTIVE | +DP_PSR_CRC_VERIFICATION; + analogix_dp_write_byte_to_dpcd(dp, DP_PSR_EN_CFG, psr_en); + + analogix_dp_enable_psr_crc(dp); +} + static unsigned char analogix_dp_calc_edid_check_sum(unsigned char *edid_data) { int i; @@ -921,6 +998,10 @@ static void analogix_dp_commit(struct analogix_dp_device *dp) /* Enable video */ analogix_dp_start_video(dp); + + dp->psr_support =
Re: [PATCH 1/1] tracing, bpf: Implement function bpf_probe_write
On Fri, Jul 15, 2016 at 07:16:01PM -0700, Sargun Dhillon wrote: > > > On Thu, 14 Jul 2016, Alexei Starovoitov wrote: > > >On Wed, Jul 13, 2016 at 01:31:57PM -0700, Sargun Dhillon wrote: > >> > >> > >>On Wed, 13 Jul 2016, Alexei Starovoitov wrote: > >> > >>>On Wed, Jul 13, 2016 at 03:36:11AM -0700, Sargun Dhillon wrote: > Provides BPF programs, attached to kprobes a safe way to write to > memory referenced by probes. This is done by making probe_kernel_write > accessible to bpf functions via the bpf_probe_write helper. > >>> > >>>not quite :) > >>> > Signed-off-by: Sargun Dhillon> --- > include/uapi/linux/bpf.h | 3 +++ > kernel/trace/bpf_trace.c | 20 > samples/bpf/bpf_helpers.h | 2 ++ > 3 files changed, 25 insertions(+) > > diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h > index 406459b..355b565 100644 > --- a/include/uapi/linux/bpf.h > +++ b/include/uapi/linux/bpf.h > @@ -313,6 +313,9 @@ enum bpf_func_id { > */ > BPF_FUNC_skb_get_tunnel_opt, > BPF_FUNC_skb_set_tunnel_opt, > + > + BPF_FUNC_probe_write, /* int bpf_probe_write(void *dst, void *src, > int size) */ > + > >>> > >>>the patch is against some old kernel. > >>>Please always make the patch against net-next tree and cc netdev list. > >>> > >>Sorry, I did this against Linus's tree, not net-next. Will fix. > >> > +static u64 bpf_probe_write(u64 r1, u64 r2, u64 r3, u64 r4, u64 r5) > +{ > + void *dst = (void *) (long) r1; > + void *unsafe_ptr = (void *) (long) r2; > + int size = (int) r3; > + > + return probe_kernel_write(dst, unsafe_ptr, size); > +} > >>> > >>>the patch is whitepsace mangled. Please see > >>>Documentation/networking/netdev-FAQ.txt > >>Also will fix. > >> > >>> > >>>the main issue though that we cannot simply allow bpf to do probe_write, > >>>since it may crash the kernel. > >>>What might be ok is to allow writing into memory of current > >>>user space process only. This way bpf prog will keep kernel safety > >>>guarantees, > >>>yet it will be able to modify user process memory when necessary. > >>>Since bpf+tracing is root only, it doesn't pose security risk. > >>> > >>> > >> > >>Doesn't probe_write prevent you from writing to protected memory and > >>generate an EFAULT? Or are you worried about the situation where a bpf > >>program writes to some other chunk of kernel memory, or writes bad data > >>to said kernel memory? > >> > >>I guess when I meant "safe" -- it's safer than allowing arbitrary memcpy. > >>I don't see a good way to ensure safety otherwise as we don't know > >>which registers point to memory that it's reasonable for probes to > >>manipulate. It's not like skb_store_bytes where we can check the pointer > >>going in is the same pointer that's referenced, and with a super > >>restricted datatype. > > > >exactly. probe_write can write anywhere in the kernel and that > >will cause crashes. If we allow that bpf becomes no different than > >kernel module. > > > >>Perhaps, it would be a good idea to describe an example where I used this: > >>#include > >>#include > >>#include > >> > >> > >>int trace_inet_stream_connect(struct pt_regs *ctx) > >>{ > >>if (!PT_REGS_PARM2(ctx)) { > >>return 0; > >>} > >>struct sockaddr uaddr = {}; > >>struct sockaddr_in *addr_in; > >>bpf_probe_read(, sizeof(struct sockaddr), (void > >> *)PT_REGS_PARM2(ctx)); > >>if (uaddr.sa_family == AF_INET) { > >>// Simple cast causes LLVM weirdness > >>addr_in = > >>char fmt[] = "Connecting on port: %d\n"; > >>bpf_trace_printk(fmt, sizeof(fmt), ntohs(addr_in->sin_port)); > >>if (ntohs(addr_in->sin_port) == 80) { > >>addr_in->sin_port = htons(443); > >>bpf_probe_write((void *)PT_REGS_PARM2(ctx), , > >> sizeof(uaddr)); > >>} > >>} > >>return 0; > >>}; > >> > >>There are two reasons I want to do this: > >>1) Debugging - sometimes, it makes sense to divert a program's syscalls in > >>order to allow for better debugging > >>2) Network Functions - I wrote a load balancer which intercepts > >>inet_stream_connect & tcp_set_state. We can manipulate the destination > >>address as neccessary at connect time. This also has the nice side effect > >>that getpeername() returns the real IP that a server is connected to, and > >>the performance is far better than doing "network load balancing" > >> > >>(I realize this is a total hack, better approaches would be appreciated) > > > >nice. interesting idea. > >Have you considered ld_preload hack to do port rewrite? > > > We've thought about it. It wont really work for us, because we're doing this > to manipulate 3rd party runtimes, many of which are written in languages > that don't play nice with LD_PRELOAD. Go is the primary problem child in > this case. We also looked
Re: [PATCH 1/1] tracing, bpf: Implement function bpf_probe_write
On Fri, Jul 15, 2016 at 07:16:01PM -0700, Sargun Dhillon wrote: > > > On Thu, 14 Jul 2016, Alexei Starovoitov wrote: > > >On Wed, Jul 13, 2016 at 01:31:57PM -0700, Sargun Dhillon wrote: > >> > >> > >>On Wed, 13 Jul 2016, Alexei Starovoitov wrote: > >> > >>>On Wed, Jul 13, 2016 at 03:36:11AM -0700, Sargun Dhillon wrote: > Provides BPF programs, attached to kprobes a safe way to write to > memory referenced by probes. This is done by making probe_kernel_write > accessible to bpf functions via the bpf_probe_write helper. > >>> > >>>not quite :) > >>> > Signed-off-by: Sargun Dhillon > --- > include/uapi/linux/bpf.h | 3 +++ > kernel/trace/bpf_trace.c | 20 > samples/bpf/bpf_helpers.h | 2 ++ > 3 files changed, 25 insertions(+) > > diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h > index 406459b..355b565 100644 > --- a/include/uapi/linux/bpf.h > +++ b/include/uapi/linux/bpf.h > @@ -313,6 +313,9 @@ enum bpf_func_id { > */ > BPF_FUNC_skb_get_tunnel_opt, > BPF_FUNC_skb_set_tunnel_opt, > + > + BPF_FUNC_probe_write, /* int bpf_probe_write(void *dst, void *src, > int size) */ > + > >>> > >>>the patch is against some old kernel. > >>>Please always make the patch against net-next tree and cc netdev list. > >>> > >>Sorry, I did this against Linus's tree, not net-next. Will fix. > >> > +static u64 bpf_probe_write(u64 r1, u64 r2, u64 r3, u64 r4, u64 r5) > +{ > + void *dst = (void *) (long) r1; > + void *unsafe_ptr = (void *) (long) r2; > + int size = (int) r3; > + > + return probe_kernel_write(dst, unsafe_ptr, size); > +} > >>> > >>>the patch is whitepsace mangled. Please see > >>>Documentation/networking/netdev-FAQ.txt > >>Also will fix. > >> > >>> > >>>the main issue though that we cannot simply allow bpf to do probe_write, > >>>since it may crash the kernel. > >>>What might be ok is to allow writing into memory of current > >>>user space process only. This way bpf prog will keep kernel safety > >>>guarantees, > >>>yet it will be able to modify user process memory when necessary. > >>>Since bpf+tracing is root only, it doesn't pose security risk. > >>> > >>> > >> > >>Doesn't probe_write prevent you from writing to protected memory and > >>generate an EFAULT? Or are you worried about the situation where a bpf > >>program writes to some other chunk of kernel memory, or writes bad data > >>to said kernel memory? > >> > >>I guess when I meant "safe" -- it's safer than allowing arbitrary memcpy. > >>I don't see a good way to ensure safety otherwise as we don't know > >>which registers point to memory that it's reasonable for probes to > >>manipulate. It's not like skb_store_bytes where we can check the pointer > >>going in is the same pointer that's referenced, and with a super > >>restricted datatype. > > > >exactly. probe_write can write anywhere in the kernel and that > >will cause crashes. If we allow that bpf becomes no different than > >kernel module. > > > >>Perhaps, it would be a good idea to describe an example where I used this: > >>#include > >>#include > >>#include > >> > >> > >>int trace_inet_stream_connect(struct pt_regs *ctx) > >>{ > >>if (!PT_REGS_PARM2(ctx)) { > >>return 0; > >>} > >>struct sockaddr uaddr = {}; > >>struct sockaddr_in *addr_in; > >>bpf_probe_read(, sizeof(struct sockaddr), (void > >> *)PT_REGS_PARM2(ctx)); > >>if (uaddr.sa_family == AF_INET) { > >>// Simple cast causes LLVM weirdness > >>addr_in = > >>char fmt[] = "Connecting on port: %d\n"; > >>bpf_trace_printk(fmt, sizeof(fmt), ntohs(addr_in->sin_port)); > >>if (ntohs(addr_in->sin_port) == 80) { > >>addr_in->sin_port = htons(443); > >>bpf_probe_write((void *)PT_REGS_PARM2(ctx), , > >> sizeof(uaddr)); > >>} > >>} > >>return 0; > >>}; > >> > >>There are two reasons I want to do this: > >>1) Debugging - sometimes, it makes sense to divert a program's syscalls in > >>order to allow for better debugging > >>2) Network Functions - I wrote a load balancer which intercepts > >>inet_stream_connect & tcp_set_state. We can manipulate the destination > >>address as neccessary at connect time. This also has the nice side effect > >>that getpeername() returns the real IP that a server is connected to, and > >>the performance is far better than doing "network load balancing" > >> > >>(I realize this is a total hack, better approaches would be appreciated) > > > >nice. interesting idea. > >Have you considered ld_preload hack to do port rewrite? > > > We've thought about it. It wont really work for us, because we're doing this > to manipulate 3rd party runtimes, many of which are written in languages > that don't play nice with LD_PRELOAD. Go is the primary problem child in > this case. We also looked at using SECCOMP +
Re: [PATCH v4.1 1/4] drm/rockchip: vop: export line flag function
Sean, On 07/15/2016 09:04 PM, Sean Paul wrote: On Fri, Jul 15, 2016 at 6:55 AM, Yakir Yangwrote: VOP have integrated a hardware counter which indicate the exact display line that vop is scanning. And if we're interested in a specific line, we can set the line number to vop line_flag register, and then vop would generate a line_flag interrupt for it. For example eDP PSR function is interested in the vertical blanking period, then driver could set the line number to zero. This patch have exported a symbol that allow other driver to listen the line flag event with given timeout limit: - rockchip_drm_wait_line_flag() Signed-off-by: Yakir Yang Thanks for the update. Reviewed-by: Sean Paul Thanks for your reviewed :-D - Yakir --- Changes in v4.1: - Remove the completion_done() check in irq handler (Sean) Changes in v4: - Avoid the weird behavior in rockchip_drm_wait_line_flag(). (Sean) - Make line_flag_num_x to an array. (Sean) - Remove the unused vop_cfg_done() in vop_line_flag_irq_enable(). (Stephane, reviewed in Google gerrit) [https://chromium-review.googlesource.com/#/c/349084/33/drivers/gpu/drm/rockchip/rockchip_drm_vop.c@466] Changes in v3: - Export the 'rockchip_drm_wait_line_flag' symbol, and document it. - Add 'line_flag_num_0' for RK3288/RK3036 - Remove the notify for waiting line_flag event (Daniel) Changes in v2: - Introduce in v2, split VOP line flag changes out drivers/gpu/drm/rockchip/rockchip_drm_drv.h | 3 + drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 117 drivers/gpu/drm/rockchip/rockchip_drm_vop.h | 2 + drivers/gpu/drm/rockchip/rockchip_vop_reg.c | 4 + 4 files changed, 126 insertions(+) diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h index ea39329..239b830 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h +++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h @@ -70,4 +70,7 @@ int rockchip_drm_dma_attach_device(struct drm_device *drm_dev, struct device *dev); void rockchip_drm_dma_detach_device(struct drm_device *drm_dev, struct device *dev); +int rockchip_drm_wait_line_flag(struct drm_crtc *crtc, unsigned int line_num, + unsigned int mstimeout); + #endif /* _ROCKCHIP_DRM_DRV_H_ */ diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c index c8a62a8..8a4f36e 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c @@ -121,6 +121,8 @@ struct vop { /* protected by dev->event_lock */ struct drm_pending_vblank_event *event; + struct completion line_flag_completion; + const struct vop_data *data; uint32_t *regsbak; @@ -431,6 +433,71 @@ static void vop_dsp_hold_valid_irq_disable(struct vop *vop) spin_unlock_irqrestore(>irq_lock, flags); } +/* + * (1) each frame starts at the start of the Vsync pulse which is signaled by + * the "FRAME_SYNC" interrupt. + * (2) the active data region of each frame ends at dsp_vact_end + * (3) we should program this same number (dsp_vact_end) into dsp_line_frag_num, + * to get "LINE_FLAG" interrupt at the end of the active on screen data. + * + * VOP_INTR_CTRL0.dsp_line_frag_num = VOP_DSP_VACT_ST_END.dsp_vact_end + * Interrupts + * LINE_FLAG ---+ + * FRAME_SYNC + | + *| | + *v v + *| Vsync | Vbp | Vactive | Vfp | + *^ ^ ^ ^ + *| | | | + *| | | | + * dsp_vs_end + | | | VOP_DSP_VTOTAL_VS_END + * dsp_vact_start --+ | | VOP_DSP_VACT_ST_END + * dsp_vact_end + | VOP_DSP_VACT_ST_END + * dsp_total -+ VOP_DSP_VTOTAL_VS_END + */ +static bool vop_line_flag_irq_is_enabled(struct vop *vop) +{ + uint32_t line_flag_irq; + unsigned long flags; + + spin_lock_irqsave(>irq_lock, flags); + + line_flag_irq = VOP_INTR_GET_TYPE(vop, enable, LINE_FLAG_INTR); + + spin_unlock_irqrestore(>irq_lock, flags); + + return !!line_flag_irq; +} + +static void vop_line_flag_irq_enable(struct vop *vop, int line_num) +{ + unsigned long flags; + + if (WARN_ON(!vop->is_enabled)) + return; + + spin_lock_irqsave(>irq_lock, flags); + + VOP_CTRL_SET(vop, line_flag_num[0], line_num); + VOP_INTR_SET_TYPE(vop, enable, LINE_FLAG_INTR, 1); + + spin_unlock_irqrestore(>irq_lock, flags); +} + +static void vop_line_flag_irq_disable(struct vop *vop) +{ +
Re: [PATCH v4.1 1/4] drm/rockchip: vop: export line flag function
Sean, On 07/15/2016 09:04 PM, Sean Paul wrote: On Fri, Jul 15, 2016 at 6:55 AM, Yakir Yang wrote: VOP have integrated a hardware counter which indicate the exact display line that vop is scanning. And if we're interested in a specific line, we can set the line number to vop line_flag register, and then vop would generate a line_flag interrupt for it. For example eDP PSR function is interested in the vertical blanking period, then driver could set the line number to zero. This patch have exported a symbol that allow other driver to listen the line flag event with given timeout limit: - rockchip_drm_wait_line_flag() Signed-off-by: Yakir Yang Thanks for the update. Reviewed-by: Sean Paul Thanks for your reviewed :-D - Yakir --- Changes in v4.1: - Remove the completion_done() check in irq handler (Sean) Changes in v4: - Avoid the weird behavior in rockchip_drm_wait_line_flag(). (Sean) - Make line_flag_num_x to an array. (Sean) - Remove the unused vop_cfg_done() in vop_line_flag_irq_enable(). (Stephane, reviewed in Google gerrit) [https://chromium-review.googlesource.com/#/c/349084/33/drivers/gpu/drm/rockchip/rockchip_drm_vop.c@466] Changes in v3: - Export the 'rockchip_drm_wait_line_flag' symbol, and document it. - Add 'line_flag_num_0' for RK3288/RK3036 - Remove the notify for waiting line_flag event (Daniel) Changes in v2: - Introduce in v2, split VOP line flag changes out drivers/gpu/drm/rockchip/rockchip_drm_drv.h | 3 + drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 117 drivers/gpu/drm/rockchip/rockchip_drm_vop.h | 2 + drivers/gpu/drm/rockchip/rockchip_vop_reg.c | 4 + 4 files changed, 126 insertions(+) diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h index ea39329..239b830 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h +++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h @@ -70,4 +70,7 @@ int rockchip_drm_dma_attach_device(struct drm_device *drm_dev, struct device *dev); void rockchip_drm_dma_detach_device(struct drm_device *drm_dev, struct device *dev); +int rockchip_drm_wait_line_flag(struct drm_crtc *crtc, unsigned int line_num, + unsigned int mstimeout); + #endif /* _ROCKCHIP_DRM_DRV_H_ */ diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c index c8a62a8..8a4f36e 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c @@ -121,6 +121,8 @@ struct vop { /* protected by dev->event_lock */ struct drm_pending_vblank_event *event; + struct completion line_flag_completion; + const struct vop_data *data; uint32_t *regsbak; @@ -431,6 +433,71 @@ static void vop_dsp_hold_valid_irq_disable(struct vop *vop) spin_unlock_irqrestore(>irq_lock, flags); } +/* + * (1) each frame starts at the start of the Vsync pulse which is signaled by + * the "FRAME_SYNC" interrupt. + * (2) the active data region of each frame ends at dsp_vact_end + * (3) we should program this same number (dsp_vact_end) into dsp_line_frag_num, + * to get "LINE_FLAG" interrupt at the end of the active on screen data. + * + * VOP_INTR_CTRL0.dsp_line_frag_num = VOP_DSP_VACT_ST_END.dsp_vact_end + * Interrupts + * LINE_FLAG ---+ + * FRAME_SYNC + | + *| | + *v v + *| Vsync | Vbp | Vactive | Vfp | + *^ ^ ^ ^ + *| | | | + *| | | | + * dsp_vs_end + | | | VOP_DSP_VTOTAL_VS_END + * dsp_vact_start --+ | | VOP_DSP_VACT_ST_END + * dsp_vact_end + | VOP_DSP_VACT_ST_END + * dsp_total -+ VOP_DSP_VTOTAL_VS_END + */ +static bool vop_line_flag_irq_is_enabled(struct vop *vop) +{ + uint32_t line_flag_irq; + unsigned long flags; + + spin_lock_irqsave(>irq_lock, flags); + + line_flag_irq = VOP_INTR_GET_TYPE(vop, enable, LINE_FLAG_INTR); + + spin_unlock_irqrestore(>irq_lock, flags); + + return !!line_flag_irq; +} + +static void vop_line_flag_irq_enable(struct vop *vop, int line_num) +{ + unsigned long flags; + + if (WARN_ON(!vop->is_enabled)) + return; + + spin_lock_irqsave(>irq_lock, flags); + + VOP_CTRL_SET(vop, line_flag_num[0], line_num); + VOP_INTR_SET_TYPE(vop, enable, LINE_FLAG_INTR, 1); + + spin_unlock_irqrestore(>irq_lock, flags); +} + +static void vop_line_flag_irq_disable(struct vop *vop) +{ + unsigned long flags; + + if (WARN_ON(!vop->is_enabled)) +
[PATCH] staging: iio: light: isl29018/28: remove I2C_CLASS_HWMON .class setting
I2C_CLASS_HWMON is for a hardware monitoring chip wanting auto-detection. IIO drivers don't typically use .class. Remove it. Signed-off-by: Alison SchofieldCc: Daniel Baluta --- drivers/staging/iio/light/isl29018.c | 1 - drivers/staging/iio/light/isl29028.c | 1 - 2 files changed, 2 deletions(-) diff --git a/drivers/staging/iio/light/isl29018.c b/drivers/staging/iio/light/isl29018.c index 80b6a9e..f47a17d 100644 --- a/drivers/staging/iio/light/isl29018.c +++ b/drivers/staging/iio/light/isl29018.c @@ -823,7 +823,6 @@ static const struct of_device_id isl29018_of_match[] = { MODULE_DEVICE_TABLE(of, isl29018_of_match); static struct i2c_driver isl29018_driver = { - .class = I2C_CLASS_HWMON, .driver = { .name = "isl29018", .acpi_match_table = ACPI_PTR(isl29018_acpi_match), diff --git a/drivers/staging/iio/light/isl29028.c b/drivers/staging/iio/light/isl29028.c index a238b16..aa413e5 100644 --- a/drivers/staging/iio/light/isl29028.c +++ b/drivers/staging/iio/light/isl29028.c @@ -546,7 +546,6 @@ static const struct of_device_id isl29028_of_match[] = { MODULE_DEVICE_TABLE(of, isl29028_of_match); static struct i2c_driver isl29028_driver = { - .class = I2C_CLASS_HWMON, .driver = { .name = "isl29028", .of_match_table = isl29028_of_match, -- 2.1.4
[PATCH] staging: iio: light: isl29018/28: remove I2C_CLASS_HWMON .class setting
I2C_CLASS_HWMON is for a hardware monitoring chip wanting auto-detection. IIO drivers don't typically use .class. Remove it. Signed-off-by: Alison Schofield Cc: Daniel Baluta --- drivers/staging/iio/light/isl29018.c | 1 - drivers/staging/iio/light/isl29028.c | 1 - 2 files changed, 2 deletions(-) diff --git a/drivers/staging/iio/light/isl29018.c b/drivers/staging/iio/light/isl29018.c index 80b6a9e..f47a17d 100644 --- a/drivers/staging/iio/light/isl29018.c +++ b/drivers/staging/iio/light/isl29018.c @@ -823,7 +823,6 @@ static const struct of_device_id isl29018_of_match[] = { MODULE_DEVICE_TABLE(of, isl29018_of_match); static struct i2c_driver isl29018_driver = { - .class = I2C_CLASS_HWMON, .driver = { .name = "isl29018", .acpi_match_table = ACPI_PTR(isl29018_acpi_match), diff --git a/drivers/staging/iio/light/isl29028.c b/drivers/staging/iio/light/isl29028.c index a238b16..aa413e5 100644 --- a/drivers/staging/iio/light/isl29028.c +++ b/drivers/staging/iio/light/isl29028.c @@ -546,7 +546,6 @@ static const struct of_device_id isl29028_of_match[] = { MODULE_DEVICE_TABLE(of, isl29028_of_match); static struct i2c_driver isl29028_driver = { - .class = I2C_CLASS_HWMON, .driver = { .name = "isl29028", .of_match_table = isl29028_of_match, -- 2.1.4
Re: [PATCH v7 4/9] acpi/arm64: Add GTDT table parse driver
Hi Rafeal, On 16 July 2016 at 05:22, Rafael J. Wysockiwrote: > On Saturday, July 16, 2016 12:32:14 AM Fu Wei wrote: >> Hi Rafael, >> >> On 15 July 2016 at 21:07, Rafael J. Wysocki wrote: >> > On Friday, July 15, 2016 02:15:27 PM Rafael J. Wysocki wrote: >> >> On Friday, July 15, 2016 03:32:35 PM Fu Wei wrote: >> >> > Hi Rafael, >> >> > >> > >> > [cut] >> > >> >> > > >> >> > >> + return 0; >> >> > >> + } >> >> > >> + >> >> > >> + if (!gtdt->platform_timer_count) { >> >> > >> + pr_info("No Platform Timer.\n"); >> >> > >> + return 0; >> >> > >> + } >> >> > >> + >> >> > >> + acpi_gtdt_desc.platform_timer_start = (void *)gtdt + >> >> > >> + >> >> > >> gtdt->platform_timer_offset; >> >> > >> + if (acpi_gtdt_desc.platform_timer_start < >> >> > >> + (void *)table + sizeof(struct acpi_table_gtdt)) { >> >> > >> + pr_err(FW_BUG "Platform Timer pointer error.\n"); >> >> > > >> >> > > Why pr_err()? >> >> > >> >> > if (true), that means the GTDT table has bugs. >> >> > >> >> >> >> And that's not a very useful piece of information unless you're debugging >> >> the >> >> platform, is it? >> > >> > FWIW, I'm not a big fan of printing "your firmware is buggy" type of >> > messages >> > (especially at the "error" log level or higher) unless they can be clearly >> > connected to a specific type of functional failure. >> > >> > So if you want to pring an error-level message, something like "I cannot >> > do X >> > because of the firmware bug Y" would be better IMO. >> >> So can I do this: >> pr_err(FW_BUG "Can NOT init platform_timer pointer, because of the >> GTDT table bug\n"); >> >> or pr_debug(FW_BUG "Can NOT init platform_timer_start, because of >> platform_timer_offset bug in GTDT\n"); >> >> or just delete it? >> >> which one do you prefer? I think maybe should provide some clue for >> users to fix the problem :-) > > And how exactly would they fix it then? > >> >> any thought ? > > If you print variable or function names and the like, the message should be > a debug one, because that's information that can only be understood by > developers (some developers are users too, but they are a minority). > > If you want to report an error, say what is not working (or not available > etc) and why (if you know the reason at the time the message is printed). Great thanks, I guess I got you point. maybe just a very simple message like: pr_err(FW_BUG "Failed to init table: GTDT table is buggy.\n"); I will also check other pr_* , if I can update them > > Thanks, > Rafael > -- Best regards, Fu Wei Software Engineer Red Hat
Re: [PATCH v7 4/9] acpi/arm64: Add GTDT table parse driver
Hi Rafeal, On 16 July 2016 at 05:22, Rafael J. Wysocki wrote: > On Saturday, July 16, 2016 12:32:14 AM Fu Wei wrote: >> Hi Rafael, >> >> On 15 July 2016 at 21:07, Rafael J. Wysocki wrote: >> > On Friday, July 15, 2016 02:15:27 PM Rafael J. Wysocki wrote: >> >> On Friday, July 15, 2016 03:32:35 PM Fu Wei wrote: >> >> > Hi Rafael, >> >> > >> > >> > [cut] >> > >> >> > > >> >> > >> + return 0; >> >> > >> + } >> >> > >> + >> >> > >> + if (!gtdt->platform_timer_count) { >> >> > >> + pr_info("No Platform Timer.\n"); >> >> > >> + return 0; >> >> > >> + } >> >> > >> + >> >> > >> + acpi_gtdt_desc.platform_timer_start = (void *)gtdt + >> >> > >> + >> >> > >> gtdt->platform_timer_offset; >> >> > >> + if (acpi_gtdt_desc.platform_timer_start < >> >> > >> + (void *)table + sizeof(struct acpi_table_gtdt)) { >> >> > >> + pr_err(FW_BUG "Platform Timer pointer error.\n"); >> >> > > >> >> > > Why pr_err()? >> >> > >> >> > if (true), that means the GTDT table has bugs. >> >> > >> >> >> >> And that's not a very useful piece of information unless you're debugging >> >> the >> >> platform, is it? >> > >> > FWIW, I'm not a big fan of printing "your firmware is buggy" type of >> > messages >> > (especially at the "error" log level or higher) unless they can be clearly >> > connected to a specific type of functional failure. >> > >> > So if you want to pring an error-level message, something like "I cannot >> > do X >> > because of the firmware bug Y" would be better IMO. >> >> So can I do this: >> pr_err(FW_BUG "Can NOT init platform_timer pointer, because of the >> GTDT table bug\n"); >> >> or pr_debug(FW_BUG "Can NOT init platform_timer_start, because of >> platform_timer_offset bug in GTDT\n"); >> >> or just delete it? >> >> which one do you prefer? I think maybe should provide some clue for >> users to fix the problem :-) > > And how exactly would they fix it then? > >> >> any thought ? > > If you print variable or function names and the like, the message should be > a debug one, because that's information that can only be understood by > developers (some developers are users too, but they are a minority). > > If you want to report an error, say what is not working (or not available > etc) and why (if you know the reason at the time the message is printed). Great thanks, I guess I got you point. maybe just a very simple message like: pr_err(FW_BUG "Failed to init table: GTDT table is buggy.\n"); I will also check other pr_* , if I can update them > > Thanks, > Rafael > -- Best regards, Fu Wei Software Engineer Red Hat
Re: [PATCH 1/1] tracing, bpf: Implement function bpf_probe_write
On Thu, 14 Jul 2016, Alexei Starovoitov wrote: On Wed, Jul 13, 2016 at 01:31:57PM -0700, Sargun Dhillon wrote: On Wed, 13 Jul 2016, Alexei Starovoitov wrote: On Wed, Jul 13, 2016 at 03:36:11AM -0700, Sargun Dhillon wrote: Provides BPF programs, attached to kprobes a safe way to write to memory referenced by probes. This is done by making probe_kernel_write accessible to bpf functions via the bpf_probe_write helper. not quite :) Signed-off-by: Sargun Dhillon--- include/uapi/linux/bpf.h | 3 +++ kernel/trace/bpf_trace.c | 20 samples/bpf/bpf_helpers.h | 2 ++ 3 files changed, 25 insertions(+) diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h index 406459b..355b565 100644 --- a/include/uapi/linux/bpf.h +++ b/include/uapi/linux/bpf.h @@ -313,6 +313,9 @@ enum bpf_func_id { */ BPF_FUNC_skb_get_tunnel_opt, BPF_FUNC_skb_set_tunnel_opt, + + BPF_FUNC_probe_write, /* int bpf_probe_write(void *dst, void *src, int size) */ + the patch is against some old kernel. Please always make the patch against net-next tree and cc netdev list. Sorry, I did this against Linus's tree, not net-next. Will fix. +static u64 bpf_probe_write(u64 r1, u64 r2, u64 r3, u64 r4, u64 r5) +{ + void *dst = (void *) (long) r1; + void *unsafe_ptr = (void *) (long) r2; + int size = (int) r3; + + return probe_kernel_write(dst, unsafe_ptr, size); +} the patch is whitepsace mangled. Please see Documentation/networking/netdev-FAQ.txt Also will fix. the main issue though that we cannot simply allow bpf to do probe_write, since it may crash the kernel. What might be ok is to allow writing into memory of current user space process only. This way bpf prog will keep kernel safety guarantees, yet it will be able to modify user process memory when necessary. Since bpf+tracing is root only, it doesn't pose security risk. Doesn't probe_write prevent you from writing to protected memory and generate an EFAULT? Or are you worried about the situation where a bpf program writes to some other chunk of kernel memory, or writes bad data to said kernel memory? I guess when I meant "safe" -- it's safer than allowing arbitrary memcpy. I don't see a good way to ensure safety otherwise as we don't know which registers point to memory that it's reasonable for probes to manipulate. It's not like skb_store_bytes where we can check the pointer going in is the same pointer that's referenced, and with a super restricted datatype. exactly. probe_write can write anywhere in the kernel and that will cause crashes. If we allow that bpf becomes no different than kernel module. Perhaps, it would be a good idea to describe an example where I used this: #include #include #include int trace_inet_stream_connect(struct pt_regs *ctx) { if (!PT_REGS_PARM2(ctx)) { return 0; } struct sockaddr uaddr = {}; struct sockaddr_in *addr_in; bpf_probe_read(, sizeof(struct sockaddr), (void *)PT_REGS_PARM2(ctx)); if (uaddr.sa_family == AF_INET) { // Simple cast causes LLVM weirdness addr_in = char fmt[] = "Connecting on port: %d\n"; bpf_trace_printk(fmt, sizeof(fmt), ntohs(addr_in->sin_port)); if (ntohs(addr_in->sin_port) == 80) { addr_in->sin_port = htons(443); bpf_probe_write((void *)PT_REGS_PARM2(ctx), , sizeof(uaddr)); } } return 0; }; There are two reasons I want to do this: 1) Debugging - sometimes, it makes sense to divert a program's syscalls in order to allow for better debugging 2) Network Functions - I wrote a load balancer which intercepts inet_stream_connect & tcp_set_state. We can manipulate the destination address as neccessary at connect time. This also has the nice side effect that getpeername() returns the real IP that a server is connected to, and the performance is far better than doing "network load balancing" (I realize this is a total hack, better approaches would be appreciated) nice. interesting idea. Have you considered ld_preload hack to do port rewrite? We've thought about it. It wont really work for us, because we're doing this to manipulate 3rd party runtimes, many of which are written in languages that don't play nice with LD_PRELOAD. Go is the primary problem child in this case. We also looked at using SECCOMP + ptrace, but again, not all runtimes play nice with ptrace. If we allowed manipulation of the current task's user memory by exposing copy_to_user, that could also work if I attach the probe to sys_connect, I could overwrite the address there before it gets copied into kernel space, but that could lead to its own weirdness. we cannot simply call copy_to_user from the bpf either, but yeah, something semantically equivalent to copy_to_user should solve your port rewriting case, right? Could you explain little bit more on
Re: [PATCH 1/1] tracing, bpf: Implement function bpf_probe_write
On Thu, 14 Jul 2016, Alexei Starovoitov wrote: On Wed, Jul 13, 2016 at 01:31:57PM -0700, Sargun Dhillon wrote: On Wed, 13 Jul 2016, Alexei Starovoitov wrote: On Wed, Jul 13, 2016 at 03:36:11AM -0700, Sargun Dhillon wrote: Provides BPF programs, attached to kprobes a safe way to write to memory referenced by probes. This is done by making probe_kernel_write accessible to bpf functions via the bpf_probe_write helper. not quite :) Signed-off-by: Sargun Dhillon --- include/uapi/linux/bpf.h | 3 +++ kernel/trace/bpf_trace.c | 20 samples/bpf/bpf_helpers.h | 2 ++ 3 files changed, 25 insertions(+) diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h index 406459b..355b565 100644 --- a/include/uapi/linux/bpf.h +++ b/include/uapi/linux/bpf.h @@ -313,6 +313,9 @@ enum bpf_func_id { */ BPF_FUNC_skb_get_tunnel_opt, BPF_FUNC_skb_set_tunnel_opt, + + BPF_FUNC_probe_write, /* int bpf_probe_write(void *dst, void *src, int size) */ + the patch is against some old kernel. Please always make the patch against net-next tree and cc netdev list. Sorry, I did this against Linus's tree, not net-next. Will fix. +static u64 bpf_probe_write(u64 r1, u64 r2, u64 r3, u64 r4, u64 r5) +{ + void *dst = (void *) (long) r1; + void *unsafe_ptr = (void *) (long) r2; + int size = (int) r3; + + return probe_kernel_write(dst, unsafe_ptr, size); +} the patch is whitepsace mangled. Please see Documentation/networking/netdev-FAQ.txt Also will fix. the main issue though that we cannot simply allow bpf to do probe_write, since it may crash the kernel. What might be ok is to allow writing into memory of current user space process only. This way bpf prog will keep kernel safety guarantees, yet it will be able to modify user process memory when necessary. Since bpf+tracing is root only, it doesn't pose security risk. Doesn't probe_write prevent you from writing to protected memory and generate an EFAULT? Or are you worried about the situation where a bpf program writes to some other chunk of kernel memory, or writes bad data to said kernel memory? I guess when I meant "safe" -- it's safer than allowing arbitrary memcpy. I don't see a good way to ensure safety otherwise as we don't know which registers point to memory that it's reasonable for probes to manipulate. It's not like skb_store_bytes where we can check the pointer going in is the same pointer that's referenced, and with a super restricted datatype. exactly. probe_write can write anywhere in the kernel and that will cause crashes. If we allow that bpf becomes no different than kernel module. Perhaps, it would be a good idea to describe an example where I used this: #include #include #include int trace_inet_stream_connect(struct pt_regs *ctx) { if (!PT_REGS_PARM2(ctx)) { return 0; } struct sockaddr uaddr = {}; struct sockaddr_in *addr_in; bpf_probe_read(, sizeof(struct sockaddr), (void *)PT_REGS_PARM2(ctx)); if (uaddr.sa_family == AF_INET) { // Simple cast causes LLVM weirdness addr_in = char fmt[] = "Connecting on port: %d\n"; bpf_trace_printk(fmt, sizeof(fmt), ntohs(addr_in->sin_port)); if (ntohs(addr_in->sin_port) == 80) { addr_in->sin_port = htons(443); bpf_probe_write((void *)PT_REGS_PARM2(ctx), , sizeof(uaddr)); } } return 0; }; There are two reasons I want to do this: 1) Debugging - sometimes, it makes sense to divert a program's syscalls in order to allow for better debugging 2) Network Functions - I wrote a load balancer which intercepts inet_stream_connect & tcp_set_state. We can manipulate the destination address as neccessary at connect time. This also has the nice side effect that getpeername() returns the real IP that a server is connected to, and the performance is far better than doing "network load balancing" (I realize this is a total hack, better approaches would be appreciated) nice. interesting idea. Have you considered ld_preload hack to do port rewrite? We've thought about it. It wont really work for us, because we're doing this to manipulate 3rd party runtimes, many of which are written in languages that don't play nice with LD_PRELOAD. Go is the primary problem child in this case. We also looked at using SECCOMP + ptrace, but again, not all runtimes play nice with ptrace. If we allowed manipulation of the current task's user memory by exposing copy_to_user, that could also work if I attach the probe to sys_connect, I could overwrite the address there before it gets copied into kernel space, but that could lead to its own weirdness. we cannot simply call copy_to_user from the bpf either, but yeah, something semantically equivalent to copy_to_user should solve your port rewriting case, right? Could you explain little bit more on 'syscall divert'
[RFC][PATCH 4/7] k3dma: Add cyclic mode for audio
From: Andy GreenCurrently the k3dma driver doesn't offer the cyclic mode necessary for handling audio. This patch adds it. Cc: Zhangfei Gao Cc: Jingoo Han Cc: Krzysztof Kozlowski Cc: Maxime Ripard Cc: Vinod Koul Cc: Dan Williams Cc: Liam Girdwood Cc: Mark Brown Cc: Jaroslav Kysela Cc: Takashi Iwai Cc: Wei Xu Cc: Rob Herring Cc: Andy Green Cc: Dave Long Cc: Guodong Xu Signed-off-by: Andy Green [jstultz: Forward ported to mainline, removed a few bits of logic that didn't seem to have much effect] Signed-off-by: John Stultz --- drivers/dma/k3dma.c | 135 ++-- 1 file changed, 121 insertions(+), 14 deletions(-) diff --git a/drivers/dma/k3dma.c b/drivers/dma/k3dma.c index c2906a82..eff7483 100644 --- a/drivers/dma/k3dma.c +++ b/drivers/dma/k3dma.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013 Linaro Ltd. + * Copyright (c) 2013 - 2015 Linaro Ltd. * Copyright (c) 2013 Hisilicon Limited. * * This program is free software; you can redistribute it and/or modify @@ -25,22 +25,27 @@ #define DRIVER_NAME"k3-dma" #define DMA_MAX_SIZE 0x1ffc +#define DMA_CYCLIC_MAX_PERIOD 0x1000 #define INT_STAT 0x00 #define INT_TC10x04 +#define INT_TC20x08 #define INT_ERR1 0x0c #define INT_ERR2 0x10 #define INT_TC1_MASK 0x18 +#define INT_TC2_MASK 0x1c #define INT_ERR1_MASK 0x20 #define INT_ERR2_MASK 0x24 #define INT_TC1_RAW0x600 +#define INT_TC2_RAW0x608 #define INT_ERR1_RAW 0x610 #define INT_ERR2_RAW 0x618 #define CH_PRI 0x688 #define CH_STAT0x690 #define CX_CUR_CNT 0x704 #define CX_LLI 0x800 -#define CX_CNT 0x810 +#define CX_CNT10x80c +#define CX_CNT00x810 #define CX_SRC 0x814 #define CX_DST 0x818 #define CX_CFG 0x81c @@ -49,6 +54,7 @@ #define CX_LLI_CHAIN_EN0x2 #define CX_CFG_EN 0x1 +#define CX_CFG_NODEIRQ BIT(1) #define CX_CFG_MEM2PER (0x1 << 2) #define CX_CFG_PER2MEM (0x2 << 2) #define CX_CFG_SRCINCR (0x1 << 31) @@ -81,6 +87,7 @@ struct k3_dma_chan { enum dma_transfer_direction dir; dma_addr_t dev_addr; enum dma_status status; + boolcyclic; }; struct k3_dma_phy { @@ -134,6 +141,7 @@ static void k3_dma_terminate_chan(struct k3_dma_phy *phy, struct k3_dma_dev *d) val = 0x1 << phy->idx; writel_relaxed(val, d->base + INT_TC1_RAW); + writel_relaxed(val, d->base + INT_TC2_RAW); writel_relaxed(val, d->base + INT_ERR1_RAW); writel_relaxed(val, d->base + INT_ERR2_RAW); } @@ -141,11 +149,15 @@ static void k3_dma_terminate_chan(struct k3_dma_phy *phy, struct k3_dma_dev *d) static void k3_dma_set_desc(struct k3_dma_phy *phy, struct k3_desc_hw *hw) { writel_relaxed(hw->lli, phy->base + CX_LLI); - writel_relaxed(hw->count, phy->base + CX_CNT); + writel_relaxed(hw->count, phy->base + CX_CNT0); writel_relaxed(hw->saddr, phy->base + CX_SRC); writel_relaxed(hw->daddr, phy->base + CX_DST); writel_relaxed(AXI_CFG_DEFAULT, phy->base + AXI_CFG); writel_relaxed(hw->config, phy->base + CX_CFG); + pr_debug("%s: desc %p: ch idx = %d, lli: 0x%x, count: 0x%x," + " saddr: 0x%x, daddr 0x%x, cfg: 0x%x\n", __func__, + (void *) hw, phy->idx, hw->lli, hw->count, hw->saddr, + hw->daddr, hw->config); } static u32 k3_dma_get_curr_cnt(struct k3_dma_dev *d, struct k3_dma_phy *phy) @@ -175,11 +187,13 @@ static void k3_dma_enable_dma(struct k3_dma_dev *d, bool on) /* unmask irq */ writel_relaxed(0x, d->base + INT_TC1_MASK); + writel_relaxed(0x, d->base + INT_TC2_MASK); writel_relaxed(0x, d->base + INT_ERR1_MASK); writel_relaxed(0x, d->base + INT_ERR2_MASK); } else { /* mask irq */ writel_relaxed(0x0, d->base + INT_TC1_MASK); + writel_relaxed(0x0, d->base + INT_TC2_MASK); writel_relaxed(0x0, d->base + INT_ERR1_MASK); writel_relaxed(0x0, d->base + INT_ERR2_MASK); } @@ -192,24 +206,31 @@ static irqreturn_t k3_dma_int_handler(int irq, void
[RFC][PATCH 4/7] k3dma: Add cyclic mode for audio
From: Andy Green Currently the k3dma driver doesn't offer the cyclic mode necessary for handling audio. This patch adds it. Cc: Zhangfei Gao Cc: Jingoo Han Cc: Krzysztof Kozlowski Cc: Maxime Ripard Cc: Vinod Koul Cc: Dan Williams Cc: Liam Girdwood Cc: Mark Brown Cc: Jaroslav Kysela Cc: Takashi Iwai Cc: Wei Xu Cc: Rob Herring Cc: Andy Green Cc: Dave Long Cc: Guodong Xu Signed-off-by: Andy Green [jstultz: Forward ported to mainline, removed a few bits of logic that didn't seem to have much effect] Signed-off-by: John Stultz --- drivers/dma/k3dma.c | 135 ++-- 1 file changed, 121 insertions(+), 14 deletions(-) diff --git a/drivers/dma/k3dma.c b/drivers/dma/k3dma.c index c2906a82..eff7483 100644 --- a/drivers/dma/k3dma.c +++ b/drivers/dma/k3dma.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013 Linaro Ltd. + * Copyright (c) 2013 - 2015 Linaro Ltd. * Copyright (c) 2013 Hisilicon Limited. * * This program is free software; you can redistribute it and/or modify @@ -25,22 +25,27 @@ #define DRIVER_NAME"k3-dma" #define DMA_MAX_SIZE 0x1ffc +#define DMA_CYCLIC_MAX_PERIOD 0x1000 #define INT_STAT 0x00 #define INT_TC10x04 +#define INT_TC20x08 #define INT_ERR1 0x0c #define INT_ERR2 0x10 #define INT_TC1_MASK 0x18 +#define INT_TC2_MASK 0x1c #define INT_ERR1_MASK 0x20 #define INT_ERR2_MASK 0x24 #define INT_TC1_RAW0x600 +#define INT_TC2_RAW0x608 #define INT_ERR1_RAW 0x610 #define INT_ERR2_RAW 0x618 #define CH_PRI 0x688 #define CH_STAT0x690 #define CX_CUR_CNT 0x704 #define CX_LLI 0x800 -#define CX_CNT 0x810 +#define CX_CNT10x80c +#define CX_CNT00x810 #define CX_SRC 0x814 #define CX_DST 0x818 #define CX_CFG 0x81c @@ -49,6 +54,7 @@ #define CX_LLI_CHAIN_EN0x2 #define CX_CFG_EN 0x1 +#define CX_CFG_NODEIRQ BIT(1) #define CX_CFG_MEM2PER (0x1 << 2) #define CX_CFG_PER2MEM (0x2 << 2) #define CX_CFG_SRCINCR (0x1 << 31) @@ -81,6 +87,7 @@ struct k3_dma_chan { enum dma_transfer_direction dir; dma_addr_t dev_addr; enum dma_status status; + boolcyclic; }; struct k3_dma_phy { @@ -134,6 +141,7 @@ static void k3_dma_terminate_chan(struct k3_dma_phy *phy, struct k3_dma_dev *d) val = 0x1 << phy->idx; writel_relaxed(val, d->base + INT_TC1_RAW); + writel_relaxed(val, d->base + INT_TC2_RAW); writel_relaxed(val, d->base + INT_ERR1_RAW); writel_relaxed(val, d->base + INT_ERR2_RAW); } @@ -141,11 +149,15 @@ static void k3_dma_terminate_chan(struct k3_dma_phy *phy, struct k3_dma_dev *d) static void k3_dma_set_desc(struct k3_dma_phy *phy, struct k3_desc_hw *hw) { writel_relaxed(hw->lli, phy->base + CX_LLI); - writel_relaxed(hw->count, phy->base + CX_CNT); + writel_relaxed(hw->count, phy->base + CX_CNT0); writel_relaxed(hw->saddr, phy->base + CX_SRC); writel_relaxed(hw->daddr, phy->base + CX_DST); writel_relaxed(AXI_CFG_DEFAULT, phy->base + AXI_CFG); writel_relaxed(hw->config, phy->base + CX_CFG); + pr_debug("%s: desc %p: ch idx = %d, lli: 0x%x, count: 0x%x," + " saddr: 0x%x, daddr 0x%x, cfg: 0x%x\n", __func__, + (void *) hw, phy->idx, hw->lli, hw->count, hw->saddr, + hw->daddr, hw->config); } static u32 k3_dma_get_curr_cnt(struct k3_dma_dev *d, struct k3_dma_phy *phy) @@ -175,11 +187,13 @@ static void k3_dma_enable_dma(struct k3_dma_dev *d, bool on) /* unmask irq */ writel_relaxed(0x, d->base + INT_TC1_MASK); + writel_relaxed(0x, d->base + INT_TC2_MASK); writel_relaxed(0x, d->base + INT_ERR1_MASK); writel_relaxed(0x, d->base + INT_ERR2_MASK); } else { /* mask irq */ writel_relaxed(0x0, d->base + INT_TC1_MASK); + writel_relaxed(0x0, d->base + INT_TC2_MASK); writel_relaxed(0x0, d->base + INT_ERR1_MASK); writel_relaxed(0x0, d->base + INT_ERR2_MASK); } @@ -192,24 +206,31 @@ static irqreturn_t k3_dma_int_handler(int irq, void *dev_id) struct k3_dma_chan *c; u32 stat = readl_relaxed(d->base + INT_STAT); u32 tc1 = readl_relaxed(d->base + INT_TC1); + u32 tc2 = readl_relaxed(d->base + INT_TC2); u32 err1 = readl_relaxed(d->base + INT_ERR1); u32 err2 = readl_relaxed(d->base + INT_ERR2); u32 i, irq_chan = 0; while (stat) { i = __ffs(stat); -
[RFC][PATCH 6/7] ASoC: hisilicon: Add hi6210 i2s audio driver for hdmi audio
From: Andy GreenAdd driver for hi6210 i2s controller found on hi6220 boards. Cc: Zhangfei Gao Cc: Jingoo Han Cc: Krzysztof Kozlowski Cc: Maxime Ripard Cc: Vinod Koul Cc: Dan Williams Cc: Liam Girdwood Cc: Mark Brown Cc: Jaroslav Kysela Cc: Takashi Iwai Cc: Wei Xu Cc: Rob Herring Cc: Andy Green Cc: Dave Long Cc: Guodong Xu Signed-off-by: Andy Green [jstultz: Forward ported to mainline, limit rates to 48k] Signed-off-by: John Stultz --- sound/soc/Kconfig | 1 + sound/soc/Makefile | 1 + sound/soc/hisilicon/Kconfig| 5 + sound/soc/hisilicon/Makefile | 2 + sound/soc/hisilicon/hi6210-hdmi-card.c | 131 +++ sound/soc/hisilicon/hi6210-i2s.c | 641 + sound/soc/hisilicon/hi6210-i2s.h | 276 ++ 7 files changed, 1057 insertions(+) create mode 100644 sound/soc/hisilicon/Kconfig create mode 100644 sound/soc/hisilicon/Makefile create mode 100644 sound/soc/hisilicon/hi6210-hdmi-card.c create mode 100644 sound/soc/hisilicon/hi6210-i2s.c create mode 100644 sound/soc/hisilicon/hi6210-i2s.h diff --git a/sound/soc/Kconfig b/sound/soc/Kconfig index 182d92e..9df9658 100644 --- a/sound/soc/Kconfig +++ b/sound/soc/Kconfig @@ -47,6 +47,7 @@ source "sound/soc/cirrus/Kconfig" source "sound/soc/davinci/Kconfig" source "sound/soc/dwc/Kconfig" source "sound/soc/fsl/Kconfig" +source "sound/soc/hisilicon/Kconfig" source "sound/soc/jz4740/Kconfig" source "sound/soc/nuc900/Kconfig" source "sound/soc/omap/Kconfig" diff --git a/sound/soc/Makefile b/sound/soc/Makefile index 9a30f21..2f6aabb 100644 --- a/sound/soc/Makefile +++ b/sound/soc/Makefile @@ -27,6 +27,7 @@ obj-$(CONFIG_SND_SOC) += cirrus/ obj-$(CONFIG_SND_SOC) += davinci/ obj-$(CONFIG_SND_SOC) += dwc/ obj-$(CONFIG_SND_SOC) += fsl/ +obj-$(CONFIG_SND_SOC) += hisilicon/ obj-$(CONFIG_SND_SOC) += jz4740/ obj-$(CONFIG_SND_SOC) += img/ obj-$(CONFIG_SND_SOC) += intel/ diff --git a/sound/soc/hisilicon/Kconfig b/sound/soc/hisilicon/Kconfig new file mode 100644 index 000..4356d5a --- /dev/null +++ b/sound/soc/hisilicon/Kconfig @@ -0,0 +1,5 @@ +config SND_I2S_HI6210_I2S + tristate "Hisilicon I2S controller" + select SND_SOC_GENERIC_DMAENGINE_PCM + help + Hisilicon I2S diff --git a/sound/soc/hisilicon/Makefile b/sound/soc/hisilicon/Makefile new file mode 100644 index 000..43a5504 --- /dev/null +++ b/sound/soc/hisilicon/Makefile @@ -0,0 +1,2 @@ +obj-$(CONFIG_SND_I2S_HI6210_I2S) += hi6210-i2s.o \ + hi6210-hdmi-card.o \ No newline at end of file diff --git a/sound/soc/hisilicon/hi6210-hdmi-card.c b/sound/soc/hisilicon/hi6210-hdmi-card.c new file mode 100644 index 000..f0995a7 --- /dev/null +++ b/sound/soc/hisilicon/hi6210-hdmi-card.c @@ -0,0 +1,131 @@ +/* + * linux/sound/soc/hisilicon/hi6210-hdmi-card.c + * + * Copyright (C) 2015 Linaro, Ltd + * + * 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, version 2 of the License. + */ + +#include +#include +#include + +static int hdmi_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + int ret; + + ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S | + SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS); + if (ret) + return ret; + + /* set i2s system clock */ + ret = snd_soc_dai_set_sysclk(cpu_dai, 0, 24576000, SND_SOC_CLOCK_IN); + if (ret) + return ret; + + return 0; +} + +/* operations of sound device */ +static struct snd_soc_ops hdmi_ops = { + .hw_params = hdmi_hw_params, +}; + +static struct snd_soc_dai_link hi6210_hdmi_dai_link = { + .name = "hi6210-hdmi-dai-link", /* "codec name" */ + .stream_name = "hdmi", /* stream name */ + + .cpu_dai_name = "f7118000.hi6210_i2s", + .codec_name = "0.hi6210_hdmi_card", + .id = 0, + .ops = _ops, + .codec_dai_name = "hi6210_hdmi_dai", + .platform_name = "f7118000.hi6210_i2s", +}; + +static struct snd_soc_card snd_soc_hi6210_hdmi = { + .name = "hi6210-hdmi", + .owner = THIS_MODULE, + .dai_link = _hdmi_dai_link, + .num_links = 1, +}; + +static const struct snd_soc_dai_ops hi6210_hdmi_dai_ops = { +}; + +static
[RFC][PATCH 2/7] k3dma: Fix dma err offsets
From: Andy GreenThe offsets for ERR1 and ERR2 are wrong actually. That's why you can never clear an error. Cc: Zhangfei Gao Cc: Jingoo Han Cc: Krzysztof Kozlowski Cc: Maxime Ripard Cc: Vinod Koul Cc: Dan Williams Cc: Liam Girdwood Cc: Mark Brown Cc: Jaroslav Kysela Cc: Takashi Iwai Cc: Wei Xu Cc: Rob Herring Cc: Andy Green Cc: Dave Long Cc: Guodong Xu Signed-off-by: Andy Green [jstultz: Forward ported to mainline] Signed-off-by: John Stultz --- drivers/dma/k3dma.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/dma/k3dma.c b/drivers/dma/k3dma.c index d01a11d..8dd050c 100644 --- a/drivers/dma/k3dma.c +++ b/drivers/dma/k3dma.c @@ -34,8 +34,8 @@ #define INT_ERR1_MASK 0x20 #define INT_ERR2_MASK 0x24 #define INT_TC1_RAW0x600 -#define INT_ERR1_RAW 0x608 -#define INT_ERR2_RAW 0x610 +#define INT_ERR1_RAW 0x610 +#define INT_ERR2_RAW 0x618 #define CH_PRI 0x688 #define CH_STAT0x690 #define CX_CUR_CNT 0x704 -- 1.9.1
[RFC][PATCH 5/7] Kconfig: Allow k3dma driver to be selected for more then HISI3xx platforms
This allows the k3dma driver to be selected on HiKey Cc: Zhangfei GaoCc: Jingoo Han Cc: Krzysztof Kozlowski Cc: Maxime Ripard Cc: Vinod Koul Cc: Dan Williams Cc: Liam Girdwood Cc: Mark Brown Cc: Jaroslav Kysela Cc: Takashi Iwai Cc: Wei Xu Cc: Rob Herring Cc: Andy Green Cc: Dave Long Cc: Guodong Xu Signed-off-by: John Stultz --- drivers/dma/Kconfig | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig index 8c98779..c5a230d 100644 --- a/drivers/dma/Kconfig +++ b/drivers/dma/Kconfig @@ -279,7 +279,6 @@ config INTEL_MIC_X100_DMA config K3_DMA tristate "Hisilicon K3 DMA support" - depends on ARCH_HI3xxx select DMA_ENGINE select DMA_VIRTUAL_CHANNELS help -- 1.9.1
[RFC][PATCH 1/7] k3dma: Fix hisi burst clipping
From: Andy GreenMax burst len is a 4-bit field, but at the moment it's clipped with a 5-bit constant... reduce it to that which can be expressed Cc: Zhangfei Gao Cc: Jingoo Han Cc: Krzysztof Kozlowski Cc: Maxime Ripard Cc: Vinod Koul Cc: Dan Williams Cc: Liam Girdwood Cc: Mark Brown Cc: Jaroslav Kysela Cc: Takashi Iwai Cc: Wei Xu Cc: Rob Herring Cc: Andy Green Cc: Dave Long Cc: Guodong Xu Signed-off-by: Andy Green [jstultz: Forward ported to mainline] Signed-off-by: John Stultz --- drivers/dma/k3dma.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/dma/k3dma.c b/drivers/dma/k3dma.c index 1ba2fd7..d01a11d 100644 --- a/drivers/dma/k3dma.c +++ b/drivers/dma/k3dma.c @@ -552,7 +552,7 @@ static int k3_dma_config(struct dma_chan *chan, c->ccfg |= (val << 12) | (val << 16); if ((maxburst == 0) || (maxburst > 16)) - val = 16; + val = 15; else val = maxburst - 1; c->ccfg |= (val << 20) | (val << 24); -- 1.9.1
[RFC][PATCH 2/7] k3dma: Fix dma err offsets
From: Andy Green The offsets for ERR1 and ERR2 are wrong actually. That's why you can never clear an error. Cc: Zhangfei Gao Cc: Jingoo Han Cc: Krzysztof Kozlowski Cc: Maxime Ripard Cc: Vinod Koul Cc: Dan Williams Cc: Liam Girdwood Cc: Mark Brown Cc: Jaroslav Kysela Cc: Takashi Iwai Cc: Wei Xu Cc: Rob Herring Cc: Andy Green Cc: Dave Long Cc: Guodong Xu Signed-off-by: Andy Green [jstultz: Forward ported to mainline] Signed-off-by: John Stultz --- drivers/dma/k3dma.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/dma/k3dma.c b/drivers/dma/k3dma.c index d01a11d..8dd050c 100644 --- a/drivers/dma/k3dma.c +++ b/drivers/dma/k3dma.c @@ -34,8 +34,8 @@ #define INT_ERR1_MASK 0x20 #define INT_ERR2_MASK 0x24 #define INT_TC1_RAW0x600 -#define INT_ERR1_RAW 0x608 -#define INT_ERR2_RAW 0x610 +#define INT_ERR1_RAW 0x610 +#define INT_ERR2_RAW 0x618 #define CH_PRI 0x688 #define CH_STAT0x690 #define CX_CUR_CNT 0x704 -- 1.9.1
[RFC][PATCH 5/7] Kconfig: Allow k3dma driver to be selected for more then HISI3xx platforms
This allows the k3dma driver to be selected on HiKey Cc: Zhangfei Gao Cc: Jingoo Han Cc: Krzysztof Kozlowski Cc: Maxime Ripard Cc: Vinod Koul Cc: Dan Williams Cc: Liam Girdwood Cc: Mark Brown Cc: Jaroslav Kysela Cc: Takashi Iwai Cc: Wei Xu Cc: Rob Herring Cc: Andy Green Cc: Dave Long Cc: Guodong Xu Signed-off-by: John Stultz --- drivers/dma/Kconfig | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig index 8c98779..c5a230d 100644 --- a/drivers/dma/Kconfig +++ b/drivers/dma/Kconfig @@ -279,7 +279,6 @@ config INTEL_MIC_X100_DMA config K3_DMA tristate "Hisilicon K3 DMA support" - depends on ARCH_HI3xxx select DMA_ENGINE select DMA_VIRTUAL_CHANNELS help -- 1.9.1
[RFC][PATCH 1/7] k3dma: Fix hisi burst clipping
From: Andy Green Max burst len is a 4-bit field, but at the moment it's clipped with a 5-bit constant... reduce it to that which can be expressed Cc: Zhangfei Gao Cc: Jingoo Han Cc: Krzysztof Kozlowski Cc: Maxime Ripard Cc: Vinod Koul Cc: Dan Williams Cc: Liam Girdwood Cc: Mark Brown Cc: Jaroslav Kysela Cc: Takashi Iwai Cc: Wei Xu Cc: Rob Herring Cc: Andy Green Cc: Dave Long Cc: Guodong Xu Signed-off-by: Andy Green [jstultz: Forward ported to mainline] Signed-off-by: John Stultz --- drivers/dma/k3dma.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/dma/k3dma.c b/drivers/dma/k3dma.c index 1ba2fd7..d01a11d 100644 --- a/drivers/dma/k3dma.c +++ b/drivers/dma/k3dma.c @@ -552,7 +552,7 @@ static int k3_dma_config(struct dma_chan *chan, c->ccfg |= (val << 12) | (val << 16); if ((maxburst == 0) || (maxburst > 16)) - val = 16; + val = 15; else val = maxburst - 1; c->ccfg |= (val << 20) | (val << 24); -- 1.9.1
[RFC][PATCH 6/7] ASoC: hisilicon: Add hi6210 i2s audio driver for hdmi audio
From: Andy Green Add driver for hi6210 i2s controller found on hi6220 boards. Cc: Zhangfei Gao Cc: Jingoo Han Cc: Krzysztof Kozlowski Cc: Maxime Ripard Cc: Vinod Koul Cc: Dan Williams Cc: Liam Girdwood Cc: Mark Brown Cc: Jaroslav Kysela Cc: Takashi Iwai Cc: Wei Xu Cc: Rob Herring Cc: Andy Green Cc: Dave Long Cc: Guodong Xu Signed-off-by: Andy Green [jstultz: Forward ported to mainline, limit rates to 48k] Signed-off-by: John Stultz --- sound/soc/Kconfig | 1 + sound/soc/Makefile | 1 + sound/soc/hisilicon/Kconfig| 5 + sound/soc/hisilicon/Makefile | 2 + sound/soc/hisilicon/hi6210-hdmi-card.c | 131 +++ sound/soc/hisilicon/hi6210-i2s.c | 641 + sound/soc/hisilicon/hi6210-i2s.h | 276 ++ 7 files changed, 1057 insertions(+) create mode 100644 sound/soc/hisilicon/Kconfig create mode 100644 sound/soc/hisilicon/Makefile create mode 100644 sound/soc/hisilicon/hi6210-hdmi-card.c create mode 100644 sound/soc/hisilicon/hi6210-i2s.c create mode 100644 sound/soc/hisilicon/hi6210-i2s.h diff --git a/sound/soc/Kconfig b/sound/soc/Kconfig index 182d92e..9df9658 100644 --- a/sound/soc/Kconfig +++ b/sound/soc/Kconfig @@ -47,6 +47,7 @@ source "sound/soc/cirrus/Kconfig" source "sound/soc/davinci/Kconfig" source "sound/soc/dwc/Kconfig" source "sound/soc/fsl/Kconfig" +source "sound/soc/hisilicon/Kconfig" source "sound/soc/jz4740/Kconfig" source "sound/soc/nuc900/Kconfig" source "sound/soc/omap/Kconfig" diff --git a/sound/soc/Makefile b/sound/soc/Makefile index 9a30f21..2f6aabb 100644 --- a/sound/soc/Makefile +++ b/sound/soc/Makefile @@ -27,6 +27,7 @@ obj-$(CONFIG_SND_SOC) += cirrus/ obj-$(CONFIG_SND_SOC) += davinci/ obj-$(CONFIG_SND_SOC) += dwc/ obj-$(CONFIG_SND_SOC) += fsl/ +obj-$(CONFIG_SND_SOC) += hisilicon/ obj-$(CONFIG_SND_SOC) += jz4740/ obj-$(CONFIG_SND_SOC) += img/ obj-$(CONFIG_SND_SOC) += intel/ diff --git a/sound/soc/hisilicon/Kconfig b/sound/soc/hisilicon/Kconfig new file mode 100644 index 000..4356d5a --- /dev/null +++ b/sound/soc/hisilicon/Kconfig @@ -0,0 +1,5 @@ +config SND_I2S_HI6210_I2S + tristate "Hisilicon I2S controller" + select SND_SOC_GENERIC_DMAENGINE_PCM + help + Hisilicon I2S diff --git a/sound/soc/hisilicon/Makefile b/sound/soc/hisilicon/Makefile new file mode 100644 index 000..43a5504 --- /dev/null +++ b/sound/soc/hisilicon/Makefile @@ -0,0 +1,2 @@ +obj-$(CONFIG_SND_I2S_HI6210_I2S) += hi6210-i2s.o \ + hi6210-hdmi-card.o \ No newline at end of file diff --git a/sound/soc/hisilicon/hi6210-hdmi-card.c b/sound/soc/hisilicon/hi6210-hdmi-card.c new file mode 100644 index 000..f0995a7 --- /dev/null +++ b/sound/soc/hisilicon/hi6210-hdmi-card.c @@ -0,0 +1,131 @@ +/* + * linux/sound/soc/hisilicon/hi6210-hdmi-card.c + * + * Copyright (C) 2015 Linaro, Ltd + * + * 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, version 2 of the License. + */ + +#include +#include +#include + +static int hdmi_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + int ret; + + ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S | + SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS); + if (ret) + return ret; + + /* set i2s system clock */ + ret = snd_soc_dai_set_sysclk(cpu_dai, 0, 24576000, SND_SOC_CLOCK_IN); + if (ret) + return ret; + + return 0; +} + +/* operations of sound device */ +static struct snd_soc_ops hdmi_ops = { + .hw_params = hdmi_hw_params, +}; + +static struct snd_soc_dai_link hi6210_hdmi_dai_link = { + .name = "hi6210-hdmi-dai-link", /* "codec name" */ + .stream_name = "hdmi", /* stream name */ + + .cpu_dai_name = "f7118000.hi6210_i2s", + .codec_name = "0.hi6210_hdmi_card", + .id = 0, + .ops = _ops, + .codec_dai_name = "hi6210_hdmi_dai", + .platform_name = "f7118000.hi6210_i2s", +}; + +static struct snd_soc_card snd_soc_hi6210_hdmi = { + .name = "hi6210-hdmi", + .owner = THIS_MODULE, + .dai_link = _hdmi_dai_link, + .num_links = 1, +}; + +static const struct snd_soc_dai_ops hi6210_hdmi_dai_ops = { +}; + +static struct snd_soc_dai_driver hi6210_hdmi_dai = { + .name = "hi6210_hdmi_dai", + .playback = { + .channels_min = 2, + .channels_max = 2, + .rates = SNDRV_PCM_RATE_48000, + .formats = SNDRV_PCM_FMTBIT_S16_LE, + }, + .ops = _hdmi_dai_ops, +}; + +static struct snd_soc_codec_driver hi6210_hdmi_codec; + +static int
[RFC][PATCH 0/7] Add HDMI audio support for HiKey
This patch set is required for HDMI audio support on HiKey. This patchset hasn't yet seen the light of lkml, so I suspect there will be a few revisions, but I wanted to send it out for an initial review. The work is mostly that of Andy Green's, but I've taking a swing at forward porting and cleaning it up where I saw fit. So credit to Andy and blame to me. Apologies in advance, as I'm not super familiar with either DMA or ASoC driver. The one bit missing to have audio fully working is changes to the adv7511 driver, but most of those changes are still out of tree, so I'll submit those changes once they land. Feedback would be very much appreicated! thanks -john Cc: Zhangfei GaoCc: Jingoo Han Cc: Krzysztof Kozlowski Cc: Maxime Ripard Cc: Vinod Koul Cc: Dan Williams Cc: Liam Girdwood Cc: Mark Brown Cc: Jaroslav Kysela Cc: Takashi Iwai Cc: Wei Xu Cc: Rob Herring Cc: Andy Green Cc: Dave Long Cc: Guodong Xu Andy Green (5): k3dma: Fix hisi burst clipping k3dma: Fix dma err offsets k3dma: Fix "nobody cared" message seen on any error k3dma: Add cyclic mode for audio ASoC: hisilicon: Add hi6210 i2s audio driver for hdmi audio John Stultz (2): Kconfig: Allow k3dma driver to be selected for more then HISI3xx platforms dts: hi6220: Add k3-dma and i2s/hdmi audio support arch/arm64/boot/dts/hisilicon/hi6220.dtsi | 36 ++ drivers/dma/Kconfig | 1 - drivers/dma/k3dma.c | 149 ++- sound/soc/Kconfig | 1 + sound/soc/Makefile| 1 + sound/soc/hisilicon/Kconfig | 5 + sound/soc/hisilicon/Makefile | 2 + sound/soc/hisilicon/hi6210-hdmi-card.c| 131 ++ sound/soc/hisilicon/hi6210-i2s.c | 641 ++ sound/soc/hisilicon/hi6210-i2s.h | 276 + 10 files changed, 1222 insertions(+), 21 deletions(-) create mode 100644 sound/soc/hisilicon/Kconfig create mode 100644 sound/soc/hisilicon/Makefile create mode 100644 sound/soc/hisilicon/hi6210-hdmi-card.c create mode 100644 sound/soc/hisilicon/hi6210-i2s.c create mode 100644 sound/soc/hisilicon/hi6210-i2s.h -- 1.9.1
[RFC][PATCH 3/7] k3dma: Fix "nobody cared" message seen on any error
From: Andy GreenAs it was before, as soon as the DMAC IP felt there was an error he would return IRQ_NONE since no actual transfer had completed. After spinning on that for 100K interrupts, Linux yanks the IRQ with a "nobody cared" error. This patch lets it handle the interrupt and keep the IRQ alive. Cc: Zhangfei Gao Cc: Jingoo Han Cc: Krzysztof Kozlowski Cc: Maxime Ripard Cc: Vinod Koul Cc: Dan Williams Cc: Liam Girdwood Cc: Mark Brown Cc: Jaroslav Kysela Cc: Takashi Iwai Cc: Wei Xu Cc: Rob Herring Cc: Andy Green Cc: Dave Long Cc: Guodong Xu Signed-off-by: Andy Green [jstultz: Forward ported to mainline] Signed-off-by: John Stultz --- drivers/dma/k3dma.c | 8 +--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/dma/k3dma.c b/drivers/dma/k3dma.c index 8dd050c..c2906a82 100644 --- a/drivers/dma/k3dma.c +++ b/drivers/dma/k3dma.c @@ -220,11 +220,13 @@ static irqreturn_t k3_dma_int_handler(int irq, void *dev_id) writel_relaxed(err1, d->base + INT_ERR1_RAW); writel_relaxed(err2, d->base + INT_ERR2_RAW); - if (irq_chan) { + if (irq_chan) tasklet_schedule(>task); + + if (irq_chan || err1 || err2) return IRQ_HANDLED; - } else - return IRQ_NONE; + + return IRQ_NONE; } static int k3_dma_start_txd(struct k3_dma_chan *c) -- 1.9.1
[PATCH 7/7] dts: hi6220: Add k3-dma and i2s/hdmi audio support
Add entry for k3-dma driver and i2s/hdmi audio devices. This enables HDMI audio output. Cc: Zhangfei GaoCc: Jingoo Han Cc: Krzysztof Kozlowski Cc: Maxime Ripard Cc: Vinod Koul Cc: Dan Williams Cc: Liam Girdwood Cc: Mark Brown Cc: Jaroslav Kysela Cc: Takashi Iwai Cc: Wei Xu Cc: Rob Herring Cc: Andy Green Cc: Dave Long Cc: Guodong Xu Signed-off-by: John Stultz --- arch/arm64/boot/dts/hisilicon/hi6220.dtsi | 36 +++ 1 file changed, 36 insertions(+) diff --git a/arch/arm64/boot/dts/hisilicon/hi6220.dtsi b/arch/arm64/boot/dts/hisilicon/hi6220.dtsi index 189d215..ba34962 100644 --- a/arch/arm64/boot/dts/hisilicon/hi6220.dtsi +++ b/arch/arm64/boot/dts/hisilicon/hi6220.dtsi @@ -228,6 +228,8 @@ compatible = "simple-bus"; #address-cells = <2>; #size-cells = <2>; + #sound-dai-cells = <0>; + interrupt-parent = <>; ranges; sram: sram@fff8 { @@ -325,6 +327,19 @@ status = "disabled"; }; + dma0: dma@f737 { + compatible = "hisilicon,k3-dma-1.0"; + reg = <0x0 0xf737 0x0 0x1000>; + #dma-cells = <1>; + dma-channels = <15>; + dma-requests = <32>; + interrupts = <0 84 4>; + clocks = <_ctrl HI6220_EDMAC_ACLK>; + dma-no-cci; + dma-type = "hi6220_dma"; + status = "ok"; + }; + dual_timer0: timer@f8008000 { compatible = "arm,sp804", "arm,primecell"; reg = <0x0 0xf8008000 0x0 0x1000>; @@ -800,6 +815,27 @@ #thermal-sensor-cells = <1>; }; + i2s0: hi6210_i2s { + compatible = "hisilicon,hi6210-i2s"; + reg = <0x0 0xf7118000 0x0 0x8000>, /* i2s unit */ + <0x0 0xf703 0x0 0x400>, /* syscon */ + <0x0 0xf7032000 0x0 0x400>; /* pmctrl */ + interrupts = <0 123 0x4>; /* 155 "DigACodec_intr"-32 */ + pinctrl-names = "default"; + pinctrl-0 = <_pmx_func _cfg_func>; + clocks = <_ctrl HI6220_DACODEC_PCLK>, +<_ctrl HI6220_BBPPLL0_DIV>; + clock-names = "dacodec", "i2s-base"; + dmas = < 15 14>; + dma-names = "rx", "tx"; + }; + + hi6210_hdmi_card: hi6210_hdmi_card { + compatible = "hisilicon,hi6210-hdmi-audio-card"; + reg = <0 0 0 0>; + sound-dai = <>; + }; + thermal-zones { cls0: cls0 { -- 1.9.1
[RFC][PATCH 0/7] Add HDMI audio support for HiKey
This patch set is required for HDMI audio support on HiKey. This patchset hasn't yet seen the light of lkml, so I suspect there will be a few revisions, but I wanted to send it out for an initial review. The work is mostly that of Andy Green's, but I've taking a swing at forward porting and cleaning it up where I saw fit. So credit to Andy and blame to me. Apologies in advance, as I'm not super familiar with either DMA or ASoC driver. The one bit missing to have audio fully working is changes to the adv7511 driver, but most of those changes are still out of tree, so I'll submit those changes once they land. Feedback would be very much appreicated! thanks -john Cc: Zhangfei Gao Cc: Jingoo Han Cc: Krzysztof Kozlowski Cc: Maxime Ripard Cc: Vinod Koul Cc: Dan Williams Cc: Liam Girdwood Cc: Mark Brown Cc: Jaroslav Kysela Cc: Takashi Iwai Cc: Wei Xu Cc: Rob Herring Cc: Andy Green Cc: Dave Long Cc: Guodong Xu Andy Green (5): k3dma: Fix hisi burst clipping k3dma: Fix dma err offsets k3dma: Fix "nobody cared" message seen on any error k3dma: Add cyclic mode for audio ASoC: hisilicon: Add hi6210 i2s audio driver for hdmi audio John Stultz (2): Kconfig: Allow k3dma driver to be selected for more then HISI3xx platforms dts: hi6220: Add k3-dma and i2s/hdmi audio support arch/arm64/boot/dts/hisilicon/hi6220.dtsi | 36 ++ drivers/dma/Kconfig | 1 - drivers/dma/k3dma.c | 149 ++- sound/soc/Kconfig | 1 + sound/soc/Makefile| 1 + sound/soc/hisilicon/Kconfig | 5 + sound/soc/hisilicon/Makefile | 2 + sound/soc/hisilicon/hi6210-hdmi-card.c| 131 ++ sound/soc/hisilicon/hi6210-i2s.c | 641 ++ sound/soc/hisilicon/hi6210-i2s.h | 276 + 10 files changed, 1222 insertions(+), 21 deletions(-) create mode 100644 sound/soc/hisilicon/Kconfig create mode 100644 sound/soc/hisilicon/Makefile create mode 100644 sound/soc/hisilicon/hi6210-hdmi-card.c create mode 100644 sound/soc/hisilicon/hi6210-i2s.c create mode 100644 sound/soc/hisilicon/hi6210-i2s.h -- 1.9.1
[RFC][PATCH 3/7] k3dma: Fix "nobody cared" message seen on any error
From: Andy Green As it was before, as soon as the DMAC IP felt there was an error he would return IRQ_NONE since no actual transfer had completed. After spinning on that for 100K interrupts, Linux yanks the IRQ with a "nobody cared" error. This patch lets it handle the interrupt and keep the IRQ alive. Cc: Zhangfei Gao Cc: Jingoo Han Cc: Krzysztof Kozlowski Cc: Maxime Ripard Cc: Vinod Koul Cc: Dan Williams Cc: Liam Girdwood Cc: Mark Brown Cc: Jaroslav Kysela Cc: Takashi Iwai Cc: Wei Xu Cc: Rob Herring Cc: Andy Green Cc: Dave Long Cc: Guodong Xu Signed-off-by: Andy Green [jstultz: Forward ported to mainline] Signed-off-by: John Stultz --- drivers/dma/k3dma.c | 8 +--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/dma/k3dma.c b/drivers/dma/k3dma.c index 8dd050c..c2906a82 100644 --- a/drivers/dma/k3dma.c +++ b/drivers/dma/k3dma.c @@ -220,11 +220,13 @@ static irqreturn_t k3_dma_int_handler(int irq, void *dev_id) writel_relaxed(err1, d->base + INT_ERR1_RAW); writel_relaxed(err2, d->base + INT_ERR2_RAW); - if (irq_chan) { + if (irq_chan) tasklet_schedule(>task); + + if (irq_chan || err1 || err2) return IRQ_HANDLED; - } else - return IRQ_NONE; + + return IRQ_NONE; } static int k3_dma_start_txd(struct k3_dma_chan *c) -- 1.9.1
[PATCH 7/7] dts: hi6220: Add k3-dma and i2s/hdmi audio support
Add entry for k3-dma driver and i2s/hdmi audio devices. This enables HDMI audio output. Cc: Zhangfei Gao Cc: Jingoo Han Cc: Krzysztof Kozlowski Cc: Maxime Ripard Cc: Vinod Koul Cc: Dan Williams Cc: Liam Girdwood Cc: Mark Brown Cc: Jaroslav Kysela Cc: Takashi Iwai Cc: Wei Xu Cc: Rob Herring Cc: Andy Green Cc: Dave Long Cc: Guodong Xu Signed-off-by: John Stultz --- arch/arm64/boot/dts/hisilicon/hi6220.dtsi | 36 +++ 1 file changed, 36 insertions(+) diff --git a/arch/arm64/boot/dts/hisilicon/hi6220.dtsi b/arch/arm64/boot/dts/hisilicon/hi6220.dtsi index 189d215..ba34962 100644 --- a/arch/arm64/boot/dts/hisilicon/hi6220.dtsi +++ b/arch/arm64/boot/dts/hisilicon/hi6220.dtsi @@ -228,6 +228,8 @@ compatible = "simple-bus"; #address-cells = <2>; #size-cells = <2>; + #sound-dai-cells = <0>; + interrupt-parent = <>; ranges; sram: sram@fff8 { @@ -325,6 +327,19 @@ status = "disabled"; }; + dma0: dma@f737 { + compatible = "hisilicon,k3-dma-1.0"; + reg = <0x0 0xf737 0x0 0x1000>; + #dma-cells = <1>; + dma-channels = <15>; + dma-requests = <32>; + interrupts = <0 84 4>; + clocks = <_ctrl HI6220_EDMAC_ACLK>; + dma-no-cci; + dma-type = "hi6220_dma"; + status = "ok"; + }; + dual_timer0: timer@f8008000 { compatible = "arm,sp804", "arm,primecell"; reg = <0x0 0xf8008000 0x0 0x1000>; @@ -800,6 +815,27 @@ #thermal-sensor-cells = <1>; }; + i2s0: hi6210_i2s { + compatible = "hisilicon,hi6210-i2s"; + reg = <0x0 0xf7118000 0x0 0x8000>, /* i2s unit */ + <0x0 0xf703 0x0 0x400>, /* syscon */ + <0x0 0xf7032000 0x0 0x400>; /* pmctrl */ + interrupts = <0 123 0x4>; /* 155 "DigACodec_intr"-32 */ + pinctrl-names = "default"; + pinctrl-0 = <_pmx_func _cfg_func>; + clocks = <_ctrl HI6220_DACODEC_PCLK>, +<_ctrl HI6220_BBPPLL0_DIV>; + clock-names = "dacodec", "i2s-base"; + dmas = < 15 14>; + dma-names = "rx", "tx"; + }; + + hi6210_hdmi_card: hi6210_hdmi_card { + compatible = "hisilicon,hi6210-hdmi-audio-card"; + reg = <0 0 0 0>; + sound-dai = <>; + }; + thermal-zones { cls0: cls0 { -- 1.9.1
Re: [PATCH] clk: probe common clock drivers earlier
Quoting Masahiro Yamada (2016-05-05 00:57:17) > Several SoCs implement platform drivers for clocks rather than > CLK_OF_DECLARE(). Clocks should come earlier because they are > prerequisites for many of other drivers. It will help to mitigate > EPROBE_DEFER issues. > > Also, drop the comment since it does not look valuable. > > Signed-off-by: Masahiro YamadaAcked-by: Michael Turquette Regards, Mike > --- > > drivers/Makefile | 3 +-- > 1 file changed, 1 insertion(+), 2 deletions(-) > > diff --git a/drivers/Makefile b/drivers/Makefile > index 8f5d076..a2a4922 100644 > --- a/drivers/Makefile > +++ b/drivers/Makefile > @@ -44,6 +44,7 @@ obj-$(CONFIG_REGULATOR) += regulator/ > > # reset controllers early, since gpu drivers might rely on them to initialize > obj-$(CONFIG_RESET_CONTROLLER) += reset/ > +obj-y += clk/ > > # tty/ comes before char/ so that the VT console is the boot-time > # default. > @@ -141,8 +142,6 @@ obj-$(CONFIG_VHOST_RING)+= vhost/ > obj-$(CONFIG_VLYNQ)+= vlynq/ > obj-$(CONFIG_STAGING) += staging/ > obj-y += platform/ > -#common clk code > -obj-y += clk/ > > obj-$(CONFIG_MAILBOX) += mailbox/ > obj-$(CONFIG_HWSPINLOCK) += hwspinlock/ > -- > 1.9.1 > > -- > To unsubscribe from this list: send the line "unsubscribe linux-clk" in > the body of a message to majord...@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] clk: probe common clock drivers earlier
Quoting Masahiro Yamada (2016-05-05 00:57:17) > Several SoCs implement platform drivers for clocks rather than > CLK_OF_DECLARE(). Clocks should come earlier because they are > prerequisites for many of other drivers. It will help to mitigate > EPROBE_DEFER issues. > > Also, drop the comment since it does not look valuable. > > Signed-off-by: Masahiro Yamada Acked-by: Michael Turquette Regards, Mike > --- > > drivers/Makefile | 3 +-- > 1 file changed, 1 insertion(+), 2 deletions(-) > > diff --git a/drivers/Makefile b/drivers/Makefile > index 8f5d076..a2a4922 100644 > --- a/drivers/Makefile > +++ b/drivers/Makefile > @@ -44,6 +44,7 @@ obj-$(CONFIG_REGULATOR) += regulator/ > > # reset controllers early, since gpu drivers might rely on them to initialize > obj-$(CONFIG_RESET_CONTROLLER) += reset/ > +obj-y += clk/ > > # tty/ comes before char/ so that the VT console is the boot-time > # default. > @@ -141,8 +142,6 @@ obj-$(CONFIG_VHOST_RING)+= vhost/ > obj-$(CONFIG_VLYNQ)+= vlynq/ > obj-$(CONFIG_STAGING) += staging/ > obj-y += platform/ > -#common clk code > -obj-y += clk/ > > obj-$(CONFIG_MAILBOX) += mailbox/ > obj-$(CONFIG_HWSPINLOCK) += hwspinlock/ > -- > 1.9.1 > > -- > To unsubscribe from this list: send the line "unsubscribe linux-clk" in > the body of a message to majord...@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v4] locking/pvqspinlock: Fix double hash race
From: Wanpeng LiWhen the lock holder vCPU is racing with the queue head vCPU: lock holder vCPU queue head vCPU === node->locked = 1; READ_ONCE(node->locked) ... pv_wait_head_or_lock(): SPIN_THRESHOLD loop; pv_hash(); lock->locked = _Q_SLOW_VAL; node->state = vcpu_hashed; pv_kick_node(): cmpxchg(node->state, vcpu_halted, vcpu_hashed); lock->locked = _Q_SLOW_VAL; pv_hash(); With preemption at the right moment, it is possible that both the lock holder and queue head vCPUs can be racing to set node->state which can result in hash entry race. Making sure the state is never set to vcpu_halted will prevent this racing from happening. This patch fix it by setting vcpu_hashed after we did all hash thing. Reviewed-by: Pan Xinhui Cc: Peter Zijlstra (Intel) Cc: Ingo Molnar Cc: Waiman Long Cc: Davidlohr Bueso Signed-off-by: Wanpeng Li --- v3 -> v4: * update patch subject * add code comments v2 -> v3: * fix typo in patch description v1 -> v2: * adjust patch description kernel/locking/qspinlock_paravirt.h | 23 ++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/kernel/locking/qspinlock_paravirt.h b/kernel/locking/qspinlock_paravirt.h index 21ede57..ca96db4 100644 --- a/kernel/locking/qspinlock_paravirt.h +++ b/kernel/locking/qspinlock_paravirt.h @@ -450,7 +450,28 @@ pv_wait_head_or_lock(struct qspinlock *lock, struct mcs_spinlock *node) goto gotlock; } } - WRITE_ONCE(pn->state, vcpu_halted); + /* +* lock holder vCPU queue head vCPU +* --- +* node->locked = 1; +* READ_ONCE(node->locked) +*... pv_wait_head_or_lock(): +*SPIN_THRESHOLD loop; +*pv_hash(); +*lock->locked = _Q_SLOW_VAL; +*node->state = vcpu_hashed; +* pv_kick_node(): +* cmpxchg(node->state, +* vcpu_halted, vcpu_hashed); +* lock->locked = _Q_SLOW_VAL; +* pv_hash(); +* +* With preemption at the right moment, it is possible that both the +* lock holder and queue head vCPUs can be racing to set node->state. +* Making sure the state is never set to vcpu_halted will prevent this +* racing from happening. +*/ + WRITE_ONCE(pn->state, vcpu_hashed); qstat_inc(qstat_pv_wait_head, true); qstat_inc(qstat_pv_wait_again, waitcnt); pv_wait(>locked, _Q_SLOW_VAL); -- 2.1.0
[PATCH v4] locking/pvqspinlock: Fix double hash race
From: Wanpeng Li When the lock holder vCPU is racing with the queue head vCPU: lock holder vCPU queue head vCPU === node->locked = 1; READ_ONCE(node->locked) ... pv_wait_head_or_lock(): SPIN_THRESHOLD loop; pv_hash(); lock->locked = _Q_SLOW_VAL; node->state = vcpu_hashed; pv_kick_node(): cmpxchg(node->state, vcpu_halted, vcpu_hashed); lock->locked = _Q_SLOW_VAL; pv_hash(); With preemption at the right moment, it is possible that both the lock holder and queue head vCPUs can be racing to set node->state which can result in hash entry race. Making sure the state is never set to vcpu_halted will prevent this racing from happening. This patch fix it by setting vcpu_hashed after we did all hash thing. Reviewed-by: Pan Xinhui Cc: Peter Zijlstra (Intel) Cc: Ingo Molnar Cc: Waiman Long Cc: Davidlohr Bueso Signed-off-by: Wanpeng Li --- v3 -> v4: * update patch subject * add code comments v2 -> v3: * fix typo in patch description v1 -> v2: * adjust patch description kernel/locking/qspinlock_paravirt.h | 23 ++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/kernel/locking/qspinlock_paravirt.h b/kernel/locking/qspinlock_paravirt.h index 21ede57..ca96db4 100644 --- a/kernel/locking/qspinlock_paravirt.h +++ b/kernel/locking/qspinlock_paravirt.h @@ -450,7 +450,28 @@ pv_wait_head_or_lock(struct qspinlock *lock, struct mcs_spinlock *node) goto gotlock; } } - WRITE_ONCE(pn->state, vcpu_halted); + /* +* lock holder vCPU queue head vCPU +* --- +* node->locked = 1; +* READ_ONCE(node->locked) +*... pv_wait_head_or_lock(): +*SPIN_THRESHOLD loop; +*pv_hash(); +*lock->locked = _Q_SLOW_VAL; +*node->state = vcpu_hashed; +* pv_kick_node(): +* cmpxchg(node->state, +* vcpu_halted, vcpu_hashed); +* lock->locked = _Q_SLOW_VAL; +* pv_hash(); +* +* With preemption at the right moment, it is possible that both the +* lock holder and queue head vCPUs can be racing to set node->state. +* Making sure the state is never set to vcpu_halted will prevent this +* racing from happening. +*/ + WRITE_ONCE(pn->state, vcpu_hashed); qstat_inc(qstat_pv_wait_head, true); qstat_inc(qstat_pv_wait_again, waitcnt); pv_wait(>locked, _Q_SLOW_VAL); -- 2.1.0
Re: [patch] mtd: maps: sa1100-flash: potential NULL dereference
Hi, On Sat, Jul 16, 2016 at 09:48:25AM +0900, Greg Kroah-Hartman wrote: > On Fri, Jul 15, 2016 at 05:32:09PM -0700, Brian Norris wrote: > > + stable > > > > Hi Dan, > > > > Patch looks good, but one question. > > > > On Fri, Jul 15, 2016 at 02:06:30PM +0300, Dan Carpenter wrote: > > > We check for NULL but then dereference "info->mtd" on the next line. > > > > > > Fixes: 72169755cf36 ('mtd: maps: sa1100-flash: show parent device in > > > sysfs') > > > > What am I supposed to do about tags like this? It appears that the > > -stable folks have started taking patches with a 'Fixes' tag alone [0], > > even though that's not mentioned in [1]. I ask because I strongly > > suspect this patch doesn't fit the rules in [1] -- it quite likely has > > only been compile tested; and it qualifies quite well as violating > > bullet 4: > > > > """ > > - It must fix a real bug that bothers people (not a, "This could be a > >problem..." type thing). > > """ > > > > So, I'd like to keep the tag, but I'd like to avoid having to NAK it in > > the stable review process. (And really, I often don't care enough to > > even do that. I believe there's a very low chance that something like > > this would cause additional problems more than the original bug.) > > Only sometimes will I pick up something that only has a fixes: tag in > it, not all the time, I try to review the patch to see if it does match > the rules or not. OK, good to know. I've seen other -stable maintainers do similarly, but I don't know what their process is. > But, fixing an oops is a good thing, I'm sure you can figure out how to > trigger it otherwise you would not be taking such a patch as it would be > not be needed :) Of course. But it's still not always clear whether such fixes will trigger other errors in poorly-tested error paths. Is (for instance) an oops that we know about better than a use-after-free that we don't know about? Anyway, applied to l2-mtd.git. Regards, Brian
Re: [patch] mtd: maps: sa1100-flash: potential NULL dereference
Hi, On Sat, Jul 16, 2016 at 09:48:25AM +0900, Greg Kroah-Hartman wrote: > On Fri, Jul 15, 2016 at 05:32:09PM -0700, Brian Norris wrote: > > + stable > > > > Hi Dan, > > > > Patch looks good, but one question. > > > > On Fri, Jul 15, 2016 at 02:06:30PM +0300, Dan Carpenter wrote: > > > We check for NULL but then dereference "info->mtd" on the next line. > > > > > > Fixes: 72169755cf36 ('mtd: maps: sa1100-flash: show parent device in > > > sysfs') > > > > What am I supposed to do about tags like this? It appears that the > > -stable folks have started taking patches with a 'Fixes' tag alone [0], > > even though that's not mentioned in [1]. I ask because I strongly > > suspect this patch doesn't fit the rules in [1] -- it quite likely has > > only been compile tested; and it qualifies quite well as violating > > bullet 4: > > > > """ > > - It must fix a real bug that bothers people (not a, "This could be a > >problem..." type thing). > > """ > > > > So, I'd like to keep the tag, but I'd like to avoid having to NAK it in > > the stable review process. (And really, I often don't care enough to > > even do that. I believe there's a very low chance that something like > > this would cause additional problems more than the original bug.) > > Only sometimes will I pick up something that only has a fixes: tag in > it, not all the time, I try to review the patch to see if it does match > the rules or not. OK, good to know. I've seen other -stable maintainers do similarly, but I don't know what their process is. > But, fixing an oops is a good thing, I'm sure you can figure out how to > trigger it otherwise you would not be taking such a patch as it would be > not be needed :) Of course. But it's still not always clear whether such fixes will trigger other errors in poorly-tested error paths. Is (for instance) an oops that we know about better than a use-after-free that we don't know about? Anyway, applied to l2-mtd.git. Regards, Brian
Re: [RCF 1/3] hwmon: Add ads1118 driver
On 07/15/2016 05:18 PM, Joshua Clayton wrote: Add new driver for Texas Instruments ADS1118 and and ADS1018. This driver works with ADS1018, because of code borrowed from asd1015, which is similar, but I can only test ADS1118 Browsing through the datasheet, I think this should probably be implemented as iio driver (and iio already has a driver for ads1015). Jonathan, what do you think ? Thanks, Guenter Signed-off-by: Joshua Clayton--- drivers/hwmon/Kconfig | 11 ++ drivers/hwmon/Makefile | 1 + drivers/hwmon/ads1118.c | 516 3 files changed, 528 insertions(+) create mode 100644 drivers/hwmon/ads1118.c diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index ff94007..cadde38 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig @@ -1459,6 +1459,17 @@ config SENSORS_ADS1015 This driver can also be built as a module. If so, the module will be called ads1015. +config SENSORS_ADS1118 + tristate "Texas Instruments ADS1018/ADS1118" + depends on SPI + help + If you say yes here you get support for Texas Instruments + ADS1118 16-bit 4-input ADC device and temperature sensor, + and the 12-bit ADS1018. + + This driver can also be built as a module. If so, the module + will be called ads1118. + config SENSORS_ADS7828 tristate "Texas Instruments ADS7828 and compatibles" depends on I2C diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile index 2ef5b7c..a3b4b2e 100644 --- a/drivers/hwmon/Makefile +++ b/drivers/hwmon/Makefile @@ -34,6 +34,7 @@ obj-$(CONFIG_SENSORS_ADM1029) += adm1029.o obj-$(CONFIG_SENSORS_ADM1031) += adm1031.o obj-$(CONFIG_SENSORS_ADM9240) += adm9240.o obj-$(CONFIG_SENSORS_ADS1015) += ads1015.o +obj-$(CONFIG_SENSORS_ADS1118) += ads1118.o obj-$(CONFIG_SENSORS_ADS7828) += ads7828.o obj-$(CONFIG_SENSORS_ADS7871) += ads7871.o obj-$(CONFIG_SENSORS_ADT7X10) += adt7x10.o diff --git a/drivers/hwmon/ads1118.c b/drivers/hwmon/ads1118.c new file mode 100644 index 000..65ee337 --- /dev/null +++ b/drivers/hwmon/ads1118.c @@ -0,0 +1,516 @@ +/* + * ads1118.c - hwmon driver for Texas Instruments ADS1118 16-bit 4-input ADC + * / temperature sensor, and Texas Instruments ADS1018, a faster, 12-bit + * chip of the same family. + * + * Author: Joshua Clayton + * + * Loosely based on ads1015.c by Dirk Eibach and others + * + * 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. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct ads_table { + unsigned int rates[8]; + unsigned int divisor; +}; + +struct ads_channel { + unsigned int delay_ms; + int pga; + u16 cfg; + bool enabled; +}; + +/* PGA fullscale voltages in microvolts */ +static const unsigned int fullscale_table[8] = { + 6144000, 4096000, 2048000, 1024000, 512000, 256000, 256000, 256000 }; + +static const struct ads_table ads1018_table = { + .rates = {128, 250, 490, 920, 1600, 2400, 3300, 3300}, + .divisor = 0x7ff0, +}; + +static const struct ads_table ads1118_table = { + .rates = {8, 16, 32, 64, 128, 250, 475, 860}, + .divisor = 0x7fff, +}; + +#define ADS1118_NUM_CHANS 5 +#define ADS1118_TEMP_CHAN 4 + +struct ads1118 { + struct device *hwmon_dev; + struct device *dev; + struct mutex update_lock; /* mutex protect updates */ + struct ads_channel channel_data[ADS1118_NUM_CHANS]; + const struct ads_table *ref; +}; + +/* + * NOTE: the bit offsets in the datasheet are 16 bit big + * endian. I've swapped upper and lower bytes in the defines + * so no twiddling is needed when sending the cfg to the device. + */ +#define ADS1118_MODE 0 /* single shot mode */ +#define ADS1118_PGA1 /* programmmed gain */ +#define ADS1118_MUX4 /* input channel */ +#define ADS1118_SS 7 /* start a conversion */ +#define ADS1118_NOP8 /* validation pattern */ +#define ADS1118_PULL_UP11 /* pullup resistor on MISO */ +#define ADS1118_TS_MODE12 /* temperature sensor mode */ +#define ADS1118_DR 13 /* data rate table index */ + +#define ADS1118_ADC_CFG (BIT(ADS1118_MODE) | BIT(ADS1118_SS) | \ + (0x3 << ADS1118_NOP) | BIT(ADS1118_PULL_UP)) +#define ADS1118_TEMP_CFG (ADS1118_ADC_CFG | BIT(ADS1118_TS_MODE)) + +/* MUX values for AINN (second input or ground) */ +#define ADS1118_MUX_AINN1 0 +#define ADS1118_MUX_AINN3 1 +#define ADS1118_MUX_AINN_GND 4 + +#define ADS1118_DEFAULT_PGA 0 +#define ADS1118_DEFAULT_DR 7 + +static inline void ads1118_set_cfg(u16 *cfg, u16 value, int offset) +{ + *cfg
Re: [RCF 1/3] hwmon: Add ads1118 driver
On 07/15/2016 05:18 PM, Joshua Clayton wrote: Add new driver for Texas Instruments ADS1118 and and ADS1018. This driver works with ADS1018, because of code borrowed from asd1015, which is similar, but I can only test ADS1118 Browsing through the datasheet, I think this should probably be implemented as iio driver (and iio already has a driver for ads1015). Jonathan, what do you think ? Thanks, Guenter Signed-off-by: Joshua Clayton --- drivers/hwmon/Kconfig | 11 ++ drivers/hwmon/Makefile | 1 + drivers/hwmon/ads1118.c | 516 3 files changed, 528 insertions(+) create mode 100644 drivers/hwmon/ads1118.c diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index ff94007..cadde38 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig @@ -1459,6 +1459,17 @@ config SENSORS_ADS1015 This driver can also be built as a module. If so, the module will be called ads1015. +config SENSORS_ADS1118 + tristate "Texas Instruments ADS1018/ADS1118" + depends on SPI + help + If you say yes here you get support for Texas Instruments + ADS1118 16-bit 4-input ADC device and temperature sensor, + and the 12-bit ADS1018. + + This driver can also be built as a module. If so, the module + will be called ads1118. + config SENSORS_ADS7828 tristate "Texas Instruments ADS7828 and compatibles" depends on I2C diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile index 2ef5b7c..a3b4b2e 100644 --- a/drivers/hwmon/Makefile +++ b/drivers/hwmon/Makefile @@ -34,6 +34,7 @@ obj-$(CONFIG_SENSORS_ADM1029) += adm1029.o obj-$(CONFIG_SENSORS_ADM1031) += adm1031.o obj-$(CONFIG_SENSORS_ADM9240) += adm9240.o obj-$(CONFIG_SENSORS_ADS1015) += ads1015.o +obj-$(CONFIG_SENSORS_ADS1118) += ads1118.o obj-$(CONFIG_SENSORS_ADS7828) += ads7828.o obj-$(CONFIG_SENSORS_ADS7871) += ads7871.o obj-$(CONFIG_SENSORS_ADT7X10) += adt7x10.o diff --git a/drivers/hwmon/ads1118.c b/drivers/hwmon/ads1118.c new file mode 100644 index 000..65ee337 --- /dev/null +++ b/drivers/hwmon/ads1118.c @@ -0,0 +1,516 @@ +/* + * ads1118.c - hwmon driver for Texas Instruments ADS1118 16-bit 4-input ADC + * / temperature sensor, and Texas Instruments ADS1018, a faster, 12-bit + * chip of the same family. + * + * Author: Joshua Clayton + * + * Loosely based on ads1015.c by Dirk Eibach and others + * + * 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. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct ads_table { + unsigned int rates[8]; + unsigned int divisor; +}; + +struct ads_channel { + unsigned int delay_ms; + int pga; + u16 cfg; + bool enabled; +}; + +/* PGA fullscale voltages in microvolts */ +static const unsigned int fullscale_table[8] = { + 6144000, 4096000, 2048000, 1024000, 512000, 256000, 256000, 256000 }; + +static const struct ads_table ads1018_table = { + .rates = {128, 250, 490, 920, 1600, 2400, 3300, 3300}, + .divisor = 0x7ff0, +}; + +static const struct ads_table ads1118_table = { + .rates = {8, 16, 32, 64, 128, 250, 475, 860}, + .divisor = 0x7fff, +}; + +#define ADS1118_NUM_CHANS 5 +#define ADS1118_TEMP_CHAN 4 + +struct ads1118 { + struct device *hwmon_dev; + struct device *dev; + struct mutex update_lock; /* mutex protect updates */ + struct ads_channel channel_data[ADS1118_NUM_CHANS]; + const struct ads_table *ref; +}; + +/* + * NOTE: the bit offsets in the datasheet are 16 bit big + * endian. I've swapped upper and lower bytes in the defines + * so no twiddling is needed when sending the cfg to the device. + */ +#define ADS1118_MODE 0 /* single shot mode */ +#define ADS1118_PGA1 /* programmmed gain */ +#define ADS1118_MUX4 /* input channel */ +#define ADS1118_SS 7 /* start a conversion */ +#define ADS1118_NOP8 /* validation pattern */ +#define ADS1118_PULL_UP11 /* pullup resistor on MISO */ +#define ADS1118_TS_MODE12 /* temperature sensor mode */ +#define ADS1118_DR 13 /* data rate table index */ + +#define ADS1118_ADC_CFG (BIT(ADS1118_MODE) | BIT(ADS1118_SS) | \ + (0x3 << ADS1118_NOP) | BIT(ADS1118_PULL_UP)) +#define ADS1118_TEMP_CFG (ADS1118_ADC_CFG | BIT(ADS1118_TS_MODE)) + +/* MUX values for AINN (second input or ground) */ +#define ADS1118_MUX_AINN1 0 +#define ADS1118_MUX_AINN3 1 +#define ADS1118_MUX_AINN_GND 4 + +#define ADS1118_DEFAULT_PGA 0 +#define ADS1118_DEFAULT_DR 7 + +static inline void ads1118_set_cfg(u16 *cfg, u16 value, int offset) +{ + *cfg &= ~(0x07 << offset); +
Re: [PATCH 1/1] irqdomain: Export __irq_domain_alloc_irqs() and irq_domain_free_irqs()
On 08.07.2016 11:34, Alexander Popov wrote: > On 06.07.2016 14:17, Thomas Gleixner wrote: >> On Fri, 1 Jul 2016, Alexander Popov wrote: >> >>> Export __irq_domain_alloc_irqs() and irq_domain_free_irqs() for being >>> able to work with irq_domain hierarchy in modules. >> >> We usually export only when we have a proper use case which is supposed to go >> into the kernel tree proper. What's yours? > > Hello, Thomas, > > I work at Positive Technologies ( https://www.ptsecurity.com/ ). We develop > a bare-metal hypervisor, which targets x86_64 and supports Linux as a guest > OS. > > Intel VT-x allows hypervisor to inject interrupts into virtual machines. > We want to handle these interrupts in guest Linux. > > So I wrote a simple kernel module creating an irq_domain, which has > x86_vector_domain as a parent in the hierarchy. In this module I just call: > - irq_domain_alloc_irqs() to allocate irqs and allow calling request_irq() >for them; > - irqd_cfg(irq_get_irq_data()) to get the APIC vectors of the allocated irqs; > - irq_domain_free_irqs() to free the resources at the end. > > It allows to handle interrupts injected by the hypervisor in guest Linux > easily, > without emulating MSI-capable PCI device at the hypervisor side. > > Everything works fine if __irq_domain_alloc_irqs() and irq_domain_free_irqs() > are exported. Is it a proper use-case? Hello again, Thomas, Did I properly answer your question? Will you accept my patch exporting these two functions? > Do you think my module could be useful for the mainline in some form? > It took me some time to understand irq_domain hierarchy design, so I can > prepare some patch or share my code to help others. Do you think my paravirtualization code registering a child irq_domain for x86_vector_domain could bring any profit to the mainline? I would be glad to put effort and do it. Thanks again, sorry for disturbing. Best regards, Alexander
Re: [PATCH 1/1] irqdomain: Export __irq_domain_alloc_irqs() and irq_domain_free_irqs()
On 08.07.2016 11:34, Alexander Popov wrote: > On 06.07.2016 14:17, Thomas Gleixner wrote: >> On Fri, 1 Jul 2016, Alexander Popov wrote: >> >>> Export __irq_domain_alloc_irqs() and irq_domain_free_irqs() for being >>> able to work with irq_domain hierarchy in modules. >> >> We usually export only when we have a proper use case which is supposed to go >> into the kernel tree proper. What's yours? > > Hello, Thomas, > > I work at Positive Technologies ( https://www.ptsecurity.com/ ). We develop > a bare-metal hypervisor, which targets x86_64 and supports Linux as a guest > OS. > > Intel VT-x allows hypervisor to inject interrupts into virtual machines. > We want to handle these interrupts in guest Linux. > > So I wrote a simple kernel module creating an irq_domain, which has > x86_vector_domain as a parent in the hierarchy. In this module I just call: > - irq_domain_alloc_irqs() to allocate irqs and allow calling request_irq() >for them; > - irqd_cfg(irq_get_irq_data()) to get the APIC vectors of the allocated irqs; > - irq_domain_free_irqs() to free the resources at the end. > > It allows to handle interrupts injected by the hypervisor in guest Linux > easily, > without emulating MSI-capable PCI device at the hypervisor side. > > Everything works fine if __irq_domain_alloc_irqs() and irq_domain_free_irqs() > are exported. Is it a proper use-case? Hello again, Thomas, Did I properly answer your question? Will you accept my patch exporting these two functions? > Do you think my module could be useful for the mainline in some form? > It took me some time to understand irq_domain hierarchy design, so I can > prepare some patch or share my code to help others. Do you think my paravirtualization code registering a child irq_domain for x86_vector_domain could bring any profit to the mainline? I would be glad to put effort and do it. Thanks again, sorry for disturbing. Best regards, Alexander
Re: [PATCH 1/2] ipc/sem.c: Fix complex_count vs. simple op race
On Wed, 13 Jul 2016, Manfred Spraul wrote: -static void sem_wait_array(struct sem_array *sma) +static void complexmode_enter(struct sem_array *sma) { int i; struct sem *sem; - if (sma->complex_count) { - /* The thread that increased sma->complex_count waited on -* all sem->lock locks. Thus we don't need to wait again. -*/ + if (sma->complex_mode) { + /* We are already in complex_mode. Nothing to do */ return; } + WRITE_ONCE(sma->complex_mode, true); So we can actually save those READ/WRITE_ONCE calls for complex_mode as it's a bool and therefore tearing is not an issue. + + /* We need a full barrier: +* The write to complex_mode must be visible +* before we read the first sem->lock spinlock state. +*/ + smp_mb(); smp_store_mb()? /* @@ -300,56 +338,40 @@ static inline int sem_lock(struct sem_array *sma, struct sembuf *sops, /* Complex operation - acquire a full lock */ ipc_lock_object(>sem_perm); - /* And wait until all simple ops that are processed -* right now have dropped their locks. -*/ - sem_wait_array(sma); + /* Prevent parallel simple ops */ + complexmode_enter(sma); return -1; nit and unrelated: we should probably use some better label here than a raw -1 (although I don't see it changing, just for nicer reading), ie: SEM_OBJECT_LOCKED Thanks, Davidlohr
Re: [PATCH V9 4/9] vfio: platform: add support for ACPI probe
On 7/14/2016 5:41 PM, Alex Williamson wrote: > On Wed, 13 Jul 2016 22:06:30 -0400 > Sinan Kayawrote: > >> The code is using the compatible DT string to associate a reset driver >> with the actual device itself. The compatible string does not exist on >> ACPI based systems. HID is the unique identifier for a device driver >> instead. >> >> Signed-off-by: Sinan Kaya >> Reviewed-by: Eric Auger >> Reviewed-by: Baptiste Reynal >> --- >> drivers/vfio/platform/vfio_platform_common.c | 70 >> +-- >> drivers/vfio/platform/vfio_platform_private.h | 1 + >> 2 files changed, 66 insertions(+), 5 deletions(-) >> >> diff --git a/drivers/vfio/platform/vfio_platform_common.c >> b/drivers/vfio/platform/vfio_platform_common.c >> index 6be92c3..ff148764 100644 >> --- a/drivers/vfio/platform/vfio_platform_common.c >> +++ b/drivers/vfio/platform/vfio_platform_common.c >> @@ -13,6 +13,7 @@ >> */ >> >> #include >> +#include >> #include >> #include >> #include >> @@ -49,6 +50,33 @@ static vfio_platform_reset_fn_t >> vfio_platform_lookup_reset(const char *compat, >> return reset_fn; >> } >> > > This function still feels a bit sloppy > >> +static int vfio_platform_acpi_probe(struct vfio_platform_device *vdev, >> +struct device *dev) >> +{ >> +struct acpi_device *adev = ACPI_COMPANION(dev); > > When !CONFIG_ACPI, this returns NULL > >> + >> +if (acpi_disabled) > > When !CONFIG_ACPI, this is defined as 1, so we'll always exit here. > >> +return -EPERM; >> + I'll move this here and leave the variable definition above only. adev = ACPI_COMPANION(dev); >> +if (!adev) { > > This is really the only (ACPI_CONFIG && !acpi_disabled) error exit, > because... > >> +pr_err("VFIO: ACPI companion device not found for %s\n", >> +vdev->name); >> +return -ENODEV; >> +} >> + >> +#ifdef CONFIG_ACPI >> +vdev->acpihid = acpi_device_hid(adev); > Based on the current implementation of acpi_device_hid, the function wlll return a name of "device" when the pnp device id list is empty. Do you want to rely on the current implementation behavior rather than be safe? > This can't actually return NULL. So the test below is unreached. > Maybe we should just conclude this function here with: > > #endif > > return vdev->acpihid ? 0 : -ENOENT; > > which is even still a bit paranoid since it can't actually happen. > >> +if (!vdev->acpihid) { >> +pr_err("VFIO: cannot find ACPI HID for %s\n", >> + vdev->name); >> +return -EINVAL; >> +} >> +return 0; >> +#else >> +return -ENOENT; >> +#endif >> +} >> + >> + >> +/* >> + * There can be two kernel build combinations. One build where >> + * ACPI is not selected in Kconfig and another one with the ACPI Kconfig. >> + * >> + * In the first case, vfio_platform_acpi_probe will return since >> + * acpi_disabled * is 1. DT user will not see any kind of messages from > > ^^ Previous editing cruft? Yep, good catch. Got warned by checkpatch for 80 characters. -- Sinan Kaya Qualcomm Datacenter Technologies, Inc. as an affiliate of Qualcomm Technologies, Inc. Qualcomm Technologies, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project.
Re: [PATCH 1/2] ipc/sem.c: Fix complex_count vs. simple op race
On Wed, 13 Jul 2016, Manfred Spraul wrote: -static void sem_wait_array(struct sem_array *sma) +static void complexmode_enter(struct sem_array *sma) { int i; struct sem *sem; - if (sma->complex_count) { - /* The thread that increased sma->complex_count waited on -* all sem->lock locks. Thus we don't need to wait again. -*/ + if (sma->complex_mode) { + /* We are already in complex_mode. Nothing to do */ return; } + WRITE_ONCE(sma->complex_mode, true); So we can actually save those READ/WRITE_ONCE calls for complex_mode as it's a bool and therefore tearing is not an issue. + + /* We need a full barrier: +* The write to complex_mode must be visible +* before we read the first sem->lock spinlock state. +*/ + smp_mb(); smp_store_mb()? /* @@ -300,56 +338,40 @@ static inline int sem_lock(struct sem_array *sma, struct sembuf *sops, /* Complex operation - acquire a full lock */ ipc_lock_object(>sem_perm); - /* And wait until all simple ops that are processed -* right now have dropped their locks. -*/ - sem_wait_array(sma); + /* Prevent parallel simple ops */ + complexmode_enter(sma); return -1; nit and unrelated: we should probably use some better label here than a raw -1 (although I don't see it changing, just for nicer reading), ie: SEM_OBJECT_LOCKED Thanks, Davidlohr
Re: [PATCH V9 4/9] vfio: platform: add support for ACPI probe
On 7/14/2016 5:41 PM, Alex Williamson wrote: > On Wed, 13 Jul 2016 22:06:30 -0400 > Sinan Kaya wrote: > >> The code is using the compatible DT string to associate a reset driver >> with the actual device itself. The compatible string does not exist on >> ACPI based systems. HID is the unique identifier for a device driver >> instead. >> >> Signed-off-by: Sinan Kaya >> Reviewed-by: Eric Auger >> Reviewed-by: Baptiste Reynal >> --- >> drivers/vfio/platform/vfio_platform_common.c | 70 >> +-- >> drivers/vfio/platform/vfio_platform_private.h | 1 + >> 2 files changed, 66 insertions(+), 5 deletions(-) >> >> diff --git a/drivers/vfio/platform/vfio_platform_common.c >> b/drivers/vfio/platform/vfio_platform_common.c >> index 6be92c3..ff148764 100644 >> --- a/drivers/vfio/platform/vfio_platform_common.c >> +++ b/drivers/vfio/platform/vfio_platform_common.c >> @@ -13,6 +13,7 @@ >> */ >> >> #include >> +#include >> #include >> #include >> #include >> @@ -49,6 +50,33 @@ static vfio_platform_reset_fn_t >> vfio_platform_lookup_reset(const char *compat, >> return reset_fn; >> } >> > > This function still feels a bit sloppy > >> +static int vfio_platform_acpi_probe(struct vfio_platform_device *vdev, >> +struct device *dev) >> +{ >> +struct acpi_device *adev = ACPI_COMPANION(dev); > > When !CONFIG_ACPI, this returns NULL > >> + >> +if (acpi_disabled) > > When !CONFIG_ACPI, this is defined as 1, so we'll always exit here. > >> +return -EPERM; >> + I'll move this here and leave the variable definition above only. adev = ACPI_COMPANION(dev); >> +if (!adev) { > > This is really the only (ACPI_CONFIG && !acpi_disabled) error exit, > because... > >> +pr_err("VFIO: ACPI companion device not found for %s\n", >> +vdev->name); >> +return -ENODEV; >> +} >> + >> +#ifdef CONFIG_ACPI >> +vdev->acpihid = acpi_device_hid(adev); > Based on the current implementation of acpi_device_hid, the function wlll return a name of "device" when the pnp device id list is empty. Do you want to rely on the current implementation behavior rather than be safe? > This can't actually return NULL. So the test below is unreached. > Maybe we should just conclude this function here with: > > #endif > > return vdev->acpihid ? 0 : -ENOENT; > > which is even still a bit paranoid since it can't actually happen. > >> +if (!vdev->acpihid) { >> +pr_err("VFIO: cannot find ACPI HID for %s\n", >> + vdev->name); >> +return -EINVAL; >> +} >> +return 0; >> +#else >> +return -ENOENT; >> +#endif >> +} >> + >> + >> +/* >> + * There can be two kernel build combinations. One build where >> + * ACPI is not selected in Kconfig and another one with the ACPI Kconfig. >> + * >> + * In the first case, vfio_platform_acpi_probe will return since >> + * acpi_disabled * is 1. DT user will not see any kind of messages from > > ^^ Previous editing cruft? Yep, good catch. Got warned by checkpatch for 80 characters. -- Sinan Kaya Qualcomm Datacenter Technologies, Inc. as an affiliate of Qualcomm Technologies, Inc. Qualcomm Technologies, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project.
Re: [PATCH v2 2/5] locking/pvqspinlock: Fix missed PV wakeup problem
On Fri, Jul 15, 2016 at 06:35:56PM +0200, Peter Zijlstra wrote: > On Fri, Jul 15, 2016 at 12:07:03PM +0200, Peter Zijlstra wrote: > > > So if we are kicked by the unlock_slowpath, and the lock is stealed by > > > someone else, we need hash its node again and set l->locked to > > > _Q_SLOW_VAL, then enter pv_wait. > > > > Right, let me go think about this a bit. > > Urgh, brain hurt. > > So I _think_ the below does for it but I could easily have missed yet > another case. > > Waiman's patch has the problem that it can have two pv_hash() calls for > the same lock in progress and I'm thinking that means we can hit the > BUG() in pv_hash() due to that. > I think Waiman's patch does have the problem of two pv_hash() calls for the same lock in progress. As I mentioned in the first version: http://lkml.kernel.org/g/20160527074331.GB8096@insomnia And he tried to address this in the patch #3 of this series. However, I think what is proper here is either to reorder patch 2 and 3 or to merge patch 2 and 3, otherwise, we are introducing a bug in the middle of this series. Thoughts, Waiman? That said, I found Peter's way is much simpler and easier to understand ;-) > If we can't, it still has a problem because its not telling us either. > > > > --- a/kernel/locking/qspinlock_paravirt.h > +++ b/kernel/locking/qspinlock_paravirt.h > @@ -20,7 +20,8 @@ > * native_queued_spin_unlock(). > */ > > -#define _Q_SLOW_VAL (3U << _Q_LOCKED_OFFSET) > +#define _Q_HASH_VAL (3U << _Q_LOCKED_OFFSET) > +#define _Q_SLOW_VAL (7U << _Q_LOCKED_OFFSET) > > /* > * Queue Node Adaptive Spinning > @@ -36,14 +37,11 @@ > */ > #define PV_PREV_CHECK_MASK 0xff > > -/* > - * Queue node uses: vcpu_running & vcpu_halted. > - * Queue head uses: vcpu_running & vcpu_hashed. > - */ > enum vcpu_state { > - vcpu_running = 0, > - vcpu_halted,/* Used only in pv_wait_node */ > - vcpu_hashed,/* = pv_hash'ed + vcpu_halted */ > + vcpu_node_running = 0, > + vcpu_node_halted, > + vcpu_head_running, We actually don't need this extra running state, right? Because nobody cares about the difference between two running states right now. > + vcpu_head_halted, > }; > > struct pv_node { > @@ -263,7 +261,7 @@ pv_wait_early(struct pv_node *prev, int > if ((loop & PV_PREV_CHECK_MASK) != 0) > return false; > > - return READ_ONCE(prev->state) != vcpu_running; > + return READ_ONCE(prev->state) & 1; > } > > /* > @@ -311,20 +309,19 @@ static void pv_wait_node(struct mcs_spin >* >* Matches the cmpxchg() from pv_kick_node(). >*/ > - smp_store_mb(pn->state, vcpu_halted); > + smp_store_mb(pn->state, vcpu_node_halted); > > - if (!READ_ONCE(node->locked)) { > - qstat_inc(qstat_pv_wait_node, true); > - qstat_inc(qstat_pv_wait_early, wait_early); > - pv_wait(>state, vcpu_halted); > - } > + if (READ_ONCE(node->locked)) > + return; > + > + qstat_inc(qstat_pv_wait_node, true); > + qstat_inc(qstat_pv_wait_early, wait_early); > + pv_wait(>state, vcpu_node_halted); > > /* > - * If pv_kick_node() changed us to vcpu_hashed, retain that > - * value so that pv_wait_head_or_lock() knows to not also try > - * to hash this lock. > + * If pv_kick_node() advanced us, retain that state. >*/ > - cmpxchg(>state, vcpu_halted, vcpu_running); > + cmpxchg(>state, vcpu_node_halted, vcpu_node_running); > > /* >* If the locked flag is still not set after wakeup, it is a > @@ -362,18 +359,17 @@ static void pv_kick_node(struct qspinloc >* >* Matches with smp_store_mb() and cmpxchg() in pv_wait_node() >*/ > - if (cmpxchg(>state, vcpu_halted, vcpu_hashed) != vcpu_halted) > + if (cmpxchg(>state, vcpu_node_halted, vcpu_head_running) != > vcpu_node_halted) > return; > > /* > - * Put the lock into the hash table and set the _Q_SLOW_VAL. > - * > - * As this is the same vCPU that will check the _Q_SLOW_VAL value and > - * the hash table later on at unlock time, no atomic instruction is > - * needed. > + * See pv_wait_head_or_lock(). We have to hash and force the unlock > + * into the slow path to deliver the actual kick for waking. >*/ > - WRITE_ONCE(l->locked, _Q_SLOW_VAL); > - (void)pv_hash(lock, pn); > + if (cmpxchg(>locked, _Q_LOCKED_VAL, _Q_HASH_VAL) == _Q_LOCKED_VAL) { > + (void)pv_hash(lock, pn); > + smp_store_release(>locked, _Q_SLOW_VAL); > + } > } > > /* > @@ -388,28 +384,22 @@ pv_wait_head_or_lock(struct qspinlock *l > { > struct pv_node *pn = (struct pv_node *)node; > struct
Re: [PATCH v2 2/5] locking/pvqspinlock: Fix missed PV wakeup problem
On Fri, Jul 15, 2016 at 06:35:56PM +0200, Peter Zijlstra wrote: > On Fri, Jul 15, 2016 at 12:07:03PM +0200, Peter Zijlstra wrote: > > > So if we are kicked by the unlock_slowpath, and the lock is stealed by > > > someone else, we need hash its node again and set l->locked to > > > _Q_SLOW_VAL, then enter pv_wait. > > > > Right, let me go think about this a bit. > > Urgh, brain hurt. > > So I _think_ the below does for it but I could easily have missed yet > another case. > > Waiman's patch has the problem that it can have two pv_hash() calls for > the same lock in progress and I'm thinking that means we can hit the > BUG() in pv_hash() due to that. > I think Waiman's patch does have the problem of two pv_hash() calls for the same lock in progress. As I mentioned in the first version: http://lkml.kernel.org/g/20160527074331.GB8096@insomnia And he tried to address this in the patch #3 of this series. However, I think what is proper here is either to reorder patch 2 and 3 or to merge patch 2 and 3, otherwise, we are introducing a bug in the middle of this series. Thoughts, Waiman? That said, I found Peter's way is much simpler and easier to understand ;-) > If we can't, it still has a problem because its not telling us either. > > > > --- a/kernel/locking/qspinlock_paravirt.h > +++ b/kernel/locking/qspinlock_paravirt.h > @@ -20,7 +20,8 @@ > * native_queued_spin_unlock(). > */ > > -#define _Q_SLOW_VAL (3U << _Q_LOCKED_OFFSET) > +#define _Q_HASH_VAL (3U << _Q_LOCKED_OFFSET) > +#define _Q_SLOW_VAL (7U << _Q_LOCKED_OFFSET) > > /* > * Queue Node Adaptive Spinning > @@ -36,14 +37,11 @@ > */ > #define PV_PREV_CHECK_MASK 0xff > > -/* > - * Queue node uses: vcpu_running & vcpu_halted. > - * Queue head uses: vcpu_running & vcpu_hashed. > - */ > enum vcpu_state { > - vcpu_running = 0, > - vcpu_halted,/* Used only in pv_wait_node */ > - vcpu_hashed,/* = pv_hash'ed + vcpu_halted */ > + vcpu_node_running = 0, > + vcpu_node_halted, > + vcpu_head_running, We actually don't need this extra running state, right? Because nobody cares about the difference between two running states right now. > + vcpu_head_halted, > }; > > struct pv_node { > @@ -263,7 +261,7 @@ pv_wait_early(struct pv_node *prev, int > if ((loop & PV_PREV_CHECK_MASK) != 0) > return false; > > - return READ_ONCE(prev->state) != vcpu_running; > + return READ_ONCE(prev->state) & 1; > } > > /* > @@ -311,20 +309,19 @@ static void pv_wait_node(struct mcs_spin >* >* Matches the cmpxchg() from pv_kick_node(). >*/ > - smp_store_mb(pn->state, vcpu_halted); > + smp_store_mb(pn->state, vcpu_node_halted); > > - if (!READ_ONCE(node->locked)) { > - qstat_inc(qstat_pv_wait_node, true); > - qstat_inc(qstat_pv_wait_early, wait_early); > - pv_wait(>state, vcpu_halted); > - } > + if (READ_ONCE(node->locked)) > + return; > + > + qstat_inc(qstat_pv_wait_node, true); > + qstat_inc(qstat_pv_wait_early, wait_early); > + pv_wait(>state, vcpu_node_halted); > > /* > - * If pv_kick_node() changed us to vcpu_hashed, retain that > - * value so that pv_wait_head_or_lock() knows to not also try > - * to hash this lock. > + * If pv_kick_node() advanced us, retain that state. >*/ > - cmpxchg(>state, vcpu_halted, vcpu_running); > + cmpxchg(>state, vcpu_node_halted, vcpu_node_running); > > /* >* If the locked flag is still not set after wakeup, it is a > @@ -362,18 +359,17 @@ static void pv_kick_node(struct qspinloc >* >* Matches with smp_store_mb() and cmpxchg() in pv_wait_node() >*/ > - if (cmpxchg(>state, vcpu_halted, vcpu_hashed) != vcpu_halted) > + if (cmpxchg(>state, vcpu_node_halted, vcpu_head_running) != > vcpu_node_halted) > return; > > /* > - * Put the lock into the hash table and set the _Q_SLOW_VAL. > - * > - * As this is the same vCPU that will check the _Q_SLOW_VAL value and > - * the hash table later on at unlock time, no atomic instruction is > - * needed. > + * See pv_wait_head_or_lock(). We have to hash and force the unlock > + * into the slow path to deliver the actual kick for waking. >*/ > - WRITE_ONCE(l->locked, _Q_SLOW_VAL); > - (void)pv_hash(lock, pn); > + if (cmpxchg(>locked, _Q_LOCKED_VAL, _Q_HASH_VAL) == _Q_LOCKED_VAL) { > + (void)pv_hash(lock, pn); > + smp_store_release(>locked, _Q_SLOW_VAL); > + } > } > > /* > @@ -388,28 +384,22 @@ pv_wait_head_or_lock(struct qspinlock *l > { > struct pv_node *pn = (struct pv_node *)node; > struct
Re: [PATCH v3] locking/pvqspinlock: restore/set vcpu_hashed state after failing adaptive locking spinning
2016-07-16 0:44 GMT+08:00 Waiman Long: > On 07/15/2016 03:45 AM, Wanpeng Li wrote: >> >> 2016-07-15 15:09 GMT+08:00 Peter Zijlstra : >>> >>> On Fri, Jul 15, 2016 at 05:26:40AM +0800, Wanpeng Li wrote: 2016-07-14 22:52 GMT+08:00 Waiman Long : [...] > > As pv_kick_node() is called immediately after designating the next node > as > the queue head, the chance of this racing is possible, but is not > likely > unless the lock holder vCPU gets preempted for a long time at that > right > moment. This change does not do any harm though, so I am OK with that. > However, I do want you to add a comment about the possible race in the > code > as it isn't that obvious or likely. How about something like: /* * If the lock holder vCPU gets preempted for a long time, pv_kick_node will * advance its state and hash the lock, restore/set the vcpu_hashed state to * avoid the race. */ >>> >>> So I'm not sure. Yes it was a bug, but its fairly 'obvious' it should be >> >> I believe Waiman can give a better comments. :) > > > Yes, setting the state to vcpu_hashed is the more obvious choice. What I > said is not obvious is that there can be a race between the new lock holder > in pv_kick_node() and the new queue head trying to call pv_wait(). And it is > what I want to document it. Maybe something more graphical can help: > > /* > * lock holder vCPU queue head vCPU > * --- > * node->locked = 1; > * READ_ONCE(node->locked) > *... pv_wait_head_or_lock(): > *SPIN_THRESHOLD loop; > *pv_hash(); > *lock->locked = _Q_SLOW_VAL; > *node->state = vcpu_hashed; > * pv_kick_node(): > * cmpxchg(node->state, > * vcpu_halted, vcpu_hashed); > * lock->locked = _Q_SLOW_VAL; > * pv_hash(); > * > * With preemption at the right moment, it is possible that both the > * lock holder and queue head vCPUs can be racing to set node->state. > * Making sure the state is never set to vcpu_halted will prevent this > * racing from happening. > */ Thanks, I will fold this in my patch. :) Regards, Wanpeng Li
Re: [PATCH v3] locking/pvqspinlock: restore/set vcpu_hashed state after failing adaptive locking spinning
2016-07-16 0:44 GMT+08:00 Waiman Long : > On 07/15/2016 03:45 AM, Wanpeng Li wrote: >> >> 2016-07-15 15:09 GMT+08:00 Peter Zijlstra: >>> >>> On Fri, Jul 15, 2016 at 05:26:40AM +0800, Wanpeng Li wrote: 2016-07-14 22:52 GMT+08:00 Waiman Long: [...] > > As pv_kick_node() is called immediately after designating the next node > as > the queue head, the chance of this racing is possible, but is not > likely > unless the lock holder vCPU gets preempted for a long time at that > right > moment. This change does not do any harm though, so I am OK with that. > However, I do want you to add a comment about the possible race in the > code > as it isn't that obvious or likely. How about something like: /* * If the lock holder vCPU gets preempted for a long time, pv_kick_node will * advance its state and hash the lock, restore/set the vcpu_hashed state to * avoid the race. */ >>> >>> So I'm not sure. Yes it was a bug, but its fairly 'obvious' it should be >> >> I believe Waiman can give a better comments. :) > > > Yes, setting the state to vcpu_hashed is the more obvious choice. What I > said is not obvious is that there can be a race between the new lock holder > in pv_kick_node() and the new queue head trying to call pv_wait(). And it is > what I want to document it. Maybe something more graphical can help: > > /* > * lock holder vCPU queue head vCPU > * --- > * node->locked = 1; > * READ_ONCE(node->locked) > *... pv_wait_head_or_lock(): > *SPIN_THRESHOLD loop; > *pv_hash(); > *lock->locked = _Q_SLOW_VAL; > *node->state = vcpu_hashed; > * pv_kick_node(): > * cmpxchg(node->state, > * vcpu_halted, vcpu_hashed); > * lock->locked = _Q_SLOW_VAL; > * pv_hash(); > * > * With preemption at the right moment, it is possible that both the > * lock holder and queue head vCPUs can be racing to set node->state. > * Making sure the state is never set to vcpu_halted will prevent this > * racing from happening. > */ Thanks, I will fold this in my patch. :) Regards, Wanpeng Li
Re: [PATCH V9 6/9] vfio: platform: call _RST method when using ACPI
On 7/14/2016 6:04 PM, Alex Williamson wrote: >> +static inline >> > +bool vfio_platform_acpi_has_reset(struct vfio_platform_device *vdev) >> > +{ >> > +#ifdef CONFIG_ACPI >> > + struct device *dev = vdev->device; >> > + acpi_handle handle = ACPI_HANDLE(dev); >> > + >> > + return acpi_has_method(handle, "_RST"); >> > +#else >> > + return false; >> > +#endif >> > +} > What exactly is the rationale for making these inline? Clearly reset > is not a performance relevant path. Thanks, > > Alex > It is remaining from the previous stub functions which were inline. I'll get rid of the inlines. -- Sinan Kaya Qualcomm Datacenter Technologies, Inc. as an affiliate of Qualcomm Technologies, Inc. Qualcomm Technologies, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project.
Re: [PATCH V9 6/9] vfio: platform: call _RST method when using ACPI
On 7/14/2016 6:04 PM, Alex Williamson wrote: >> +static inline >> > +bool vfio_platform_acpi_has_reset(struct vfio_platform_device *vdev) >> > +{ >> > +#ifdef CONFIG_ACPI >> > + struct device *dev = vdev->device; >> > + acpi_handle handle = ACPI_HANDLE(dev); >> > + >> > + return acpi_has_method(handle, "_RST"); >> > +#else >> > + return false; >> > +#endif >> > +} > What exactly is the rationale for making these inline? Clearly reset > is not a performance relevant path. Thanks, > > Alex > It is remaining from the previous stub functions which were inline. I'll get rid of the inlines. -- Sinan Kaya Qualcomm Datacenter Technologies, Inc. as an affiliate of Qualcomm Technologies, Inc. Qualcomm Technologies, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project.
Re: [PATCH V9 7/9] vfio, platform: make reset driver a requirement by default
On 7/14/2016 6:24 PM, Alex Williamson wrote: >> struct vfio_platform_device { >> > + boolreset_required; >> >struct vfio_platform_region *regions; >> >u32 num_regions; >> >struct vfio_platform_irq*irqs; > Either you have 64bit bools or you're not paying any attention to > to the alignment of this structure. If we only care about 64bit > systems we could tuck this into the gap after num_regions, otherwise > append it to the end of the structure, we certainly don't care about > keeping a reset flag within cache line boundaries. Thanks, OK, I moved it to the end of the structure. -- Sinan Kaya Qualcomm Datacenter Technologies, Inc. as an affiliate of Qualcomm Technologies, Inc. Qualcomm Technologies, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project.
Re: [PATCH V9 7/9] vfio, platform: make reset driver a requirement by default
On 7/14/2016 6:24 PM, Alex Williamson wrote: >> struct vfio_platform_device { >> > + boolreset_required; >> >struct vfio_platform_region *regions; >> >u32 num_regions; >> >struct vfio_platform_irq*irqs; > Either you have 64bit bools or you're not paying any attention to > to the alignment of this structure. If we only care about 64bit > systems we could tuck this into the gap after num_regions, otherwise > append it to the end of the structure, we certainly don't care about > keeping a reset flag within cache line boundaries. Thanks, OK, I moved it to the end of the structure. -- Sinan Kaya Qualcomm Datacenter Technologies, Inc. as an affiliate of Qualcomm Technologies, Inc. Qualcomm Technologies, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project.
Re: [PATCH] dmaengine: qcom_hidma: release the descriptor before the callback
Hi Vinod, On 7/13/2016 10:57 PM, Sinan Kaya wrote: > There is a race condition between data transfer callback and descriptor > free code. The callback routine may decide to clear the resources even > though the descriptor has not yet been freed. > > Instead of calling the callback first and then releasing the memory, > this code is changing the order to return the descriptor back to the > free pool and then call the user provided callback. > > Signed-off-by: Sinan Kaya> --- > drivers/dma/qcom/hidma.c | 26 +++--- > 1 file changed, 15 insertions(+), 11 deletions(-) > > diff --git a/drivers/dma/qcom/hidma.c b/drivers/dma/qcom/hidma.c > index 41b5c6d..c41696e 100644 > --- a/drivers/dma/qcom/hidma.c > +++ b/drivers/dma/qcom/hidma.c > @@ -111,6 +111,7 @@ static void hidma_process_completed(struct hidma_chan > *mchan) > struct dma_async_tx_descriptor *desc; > dma_cookie_t last_cookie; > struct hidma_desc *mdesc; > + struct hidma_desc *next; > unsigned long irqflags; > struct list_head list; > > @@ -122,28 +123,31 @@ static void hidma_process_completed(struct hidma_chan > *mchan) > spin_unlock_irqrestore(>lock, irqflags); > > /* Execute callbacks and run dependencies */ > - list_for_each_entry(mdesc, , node) { > - enum dma_status llstat; > + list_for_each_entry_safe(mdesc, next, , node) { > + dma_async_tx_callback callback; > + void *param; > > desc = >desc; > > spin_lock_irqsave(>lock, irqflags); > - dma_cookie_complete(desc); > + if (hidma_ll_status(mdma->lldev, mdesc->tre_ch) > + == DMA_COMPLETE) > + dma_cookie_complete(desc); It looks like I introduced a behavioral change while refactoring the code. The previous one would call the callback only if the transfer was successful but it would always call dma_cookie_complete. The new behavior is to call dma_cookie_complete only if the transfer is successful and it calls the callback even in the case of error cases. Then, the client has to query if transfer was successful. Which one is the correct behavior? > spin_unlock_irqrestore(>lock, irqflags); > > - llstat = hidma_ll_status(mdma->lldev, mdesc->tre_ch); > - if (desc->callback && (llstat == DMA_COMPLETE)) > - desc->callback(desc->callback_param); > + callback = desc->callback; > + param = desc->callback_param; > > last_cookie = desc->cookie; > dma_run_dependencies(desc); > - } > > - /* Free descriptors */ > - spin_lock_irqsave(>lock, irqflags); > - list_splice_tail_init(, >free); > - spin_unlock_irqrestore(>lock, irqflags); > + spin_lock_irqsave(>lock, irqflags); > + list_move(>node, >free); > + spin_unlock_irqrestore(>lock, irqflags); > > + if (callback) > + callback(param); > + } > } > > /* > -- Sinan Kaya Qualcomm Datacenter Technologies, Inc. as an affiliate of Qualcomm Technologies, Inc. Qualcomm Technologies, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project.
Re: [PATCH] dmaengine: qcom_hidma: release the descriptor before the callback
Hi Vinod, On 7/13/2016 10:57 PM, Sinan Kaya wrote: > There is a race condition between data transfer callback and descriptor > free code. The callback routine may decide to clear the resources even > though the descriptor has not yet been freed. > > Instead of calling the callback first and then releasing the memory, > this code is changing the order to return the descriptor back to the > free pool and then call the user provided callback. > > Signed-off-by: Sinan Kaya > --- > drivers/dma/qcom/hidma.c | 26 +++--- > 1 file changed, 15 insertions(+), 11 deletions(-) > > diff --git a/drivers/dma/qcom/hidma.c b/drivers/dma/qcom/hidma.c > index 41b5c6d..c41696e 100644 > --- a/drivers/dma/qcom/hidma.c > +++ b/drivers/dma/qcom/hidma.c > @@ -111,6 +111,7 @@ static void hidma_process_completed(struct hidma_chan > *mchan) > struct dma_async_tx_descriptor *desc; > dma_cookie_t last_cookie; > struct hidma_desc *mdesc; > + struct hidma_desc *next; > unsigned long irqflags; > struct list_head list; > > @@ -122,28 +123,31 @@ static void hidma_process_completed(struct hidma_chan > *mchan) > spin_unlock_irqrestore(>lock, irqflags); > > /* Execute callbacks and run dependencies */ > - list_for_each_entry(mdesc, , node) { > - enum dma_status llstat; > + list_for_each_entry_safe(mdesc, next, , node) { > + dma_async_tx_callback callback; > + void *param; > > desc = >desc; > > spin_lock_irqsave(>lock, irqflags); > - dma_cookie_complete(desc); > + if (hidma_ll_status(mdma->lldev, mdesc->tre_ch) > + == DMA_COMPLETE) > + dma_cookie_complete(desc); It looks like I introduced a behavioral change while refactoring the code. The previous one would call the callback only if the transfer was successful but it would always call dma_cookie_complete. The new behavior is to call dma_cookie_complete only if the transfer is successful and it calls the callback even in the case of error cases. Then, the client has to query if transfer was successful. Which one is the correct behavior? > spin_unlock_irqrestore(>lock, irqflags); > > - llstat = hidma_ll_status(mdma->lldev, mdesc->tre_ch); > - if (desc->callback && (llstat == DMA_COMPLETE)) > - desc->callback(desc->callback_param); > + callback = desc->callback; > + param = desc->callback_param; > > last_cookie = desc->cookie; > dma_run_dependencies(desc); > - } > > - /* Free descriptors */ > - spin_lock_irqsave(>lock, irqflags); > - list_splice_tail_init(, >free); > - spin_unlock_irqrestore(>lock, irqflags); > + spin_lock_irqsave(>lock, irqflags); > + list_move(>node, >free); > + spin_unlock_irqrestore(>lock, irqflags); > > + if (callback) > + callback(param); > + } > } > > /* > -- Sinan Kaya Qualcomm Datacenter Technologies, Inc. as an affiliate of Qualcomm Technologies, Inc. Qualcomm Technologies, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project.
Re: [PATCH v2] cpufreq: powernv: Replacing pstate_id with frequency table index
On Monday, July 11, 2016 11:47:53 AM Viresh Kumar wrote: > On 30-06-16, 11:53, Akshay Adiga wrote: > > Refactoring code to use frequency table index instead of pstate_id. > > This abstraction will make the code independent of the pstate values. > > > > - No functional changes > > - The highest frequency is at frequency table index 0 and the frequency > > decreases as the index increases. > > - Macros pstates_to_idx() and idx_to_pstate() can be used for conversion > > between pstate_id and index. > > - powernv_pstate_info now contains frequency table index to min, max and > > nominal frequency (instead of pstate_ids) > > - global_pstate_info new stores index values instead pstate ids. > > - variables renamed as *_idx which now store index instead of pstate > > > > Signed-off-by: Akshay Adiga> > Reviewed-by: Gautham R. Shenoy > > --- > > Changes from v1: > > - changed macro names from get_pstate()/ get_index() to > > idx_to_pstate()/ pstate_to_idx() > > - Renamed variables that store index instead of pstate_id to *_idx > > - Retained previous printk's > > > > v1 : http://marc.info/?l=linux-pm=146677701501225=1 > > > > drivers/cpufreq/powernv-cpufreq.c | 177 > > ++ > > 1 file changed, 102 insertions(+), 75 deletions(-) > > Haven't done in-depth review, but I trust that Gautham has done it :) > > Acked-by: Viresh Kumar Patch applied, thanks!
Re: [PATCH v2] cpufreq: powernv: Replacing pstate_id with frequency table index
On Monday, July 11, 2016 11:47:53 AM Viresh Kumar wrote: > On 30-06-16, 11:53, Akshay Adiga wrote: > > Refactoring code to use frequency table index instead of pstate_id. > > This abstraction will make the code independent of the pstate values. > > > > - No functional changes > > - The highest frequency is at frequency table index 0 and the frequency > > decreases as the index increases. > > - Macros pstates_to_idx() and idx_to_pstate() can be used for conversion > > between pstate_id and index. > > - powernv_pstate_info now contains frequency table index to min, max and > > nominal frequency (instead of pstate_ids) > > - global_pstate_info new stores index values instead pstate ids. > > - variables renamed as *_idx which now store index instead of pstate > > > > Signed-off-by: Akshay Adiga > > Reviewed-by: Gautham R. Shenoy > > --- > > Changes from v1: > > - changed macro names from get_pstate()/ get_index() to > > idx_to_pstate()/ pstate_to_idx() > > - Renamed variables that store index instead of pstate_id to *_idx > > - Retained previous printk's > > > > v1 : http://marc.info/?l=linux-pm=146677701501225=1 > > > > drivers/cpufreq/powernv-cpufreq.c | 177 > > ++ > > 1 file changed, 102 insertions(+), 75 deletions(-) > > Haven't done in-depth review, but I trust that Gautham has done it :) > > Acked-by: Viresh Kumar Patch applied, thanks!
Re: [UPDATE PATCH v2 1/3] ACPICA: Events: Introduce acpi_mask_gpe() to implement GPE masking mechanism
On Monday, July 04, 2016 03:59:07 PM Rafael J. Wysocki wrote: > On Thursday, June 23, 2016 03:05:47 PM Lv Zheng wrote: > > (remove acpi_unmask_gpe() from the patch description) > > > > There is a facility in Linux, developers can control the enabling/disabling > > of a GPE via /sys/firmware/acpi/interrupts/gpexx. This is mainly for > > debugging purposes. > > > > But many users expect to use this facility to implement quirks to mask a > > specific GPE when there is a gap in Linux causing this GPE to flood. This > > is not working correctly because currently this facility invokes > > enabling/disabling counting based GPE driver APIs: > > acpi_enable_gpe()/acpi_disable_gpe() > > and the GPE drivers can still affect the count to mess up the GPE > > masking purposes. > > > > However, most of the IRQ chip designs allow masking/unmasking IRQs via a > > masking bit which is different from the enabled bit to achieve the same > > purpose. But the GPE hardware doesn't contain such a feature, this brings > > the trouble. > > > > In this patch, we introduce a software mechanism to implement the GPE > > masking feature, and acpi_mask_gpe() are provided to the OSPMs to > > mask/unmask GPEs in the above mentioned situation instead of > > acpi_enable_gpe()/acpi_disable_gpe(). ACPICA BZ 1102. Lv Zheng. > > > > Link: https://bugs.acpica.org/show_bug.cgi?id=1102 > > Signed-off-by: Lv Zheng> > I've queued up this one and the [2/3] and please see my comments on the [3/3]. I've decided that it's better if this goes in via upstream ACPICA, so it's not in the queue any more. For the time being, I'd like all changes in the ACPICA code to go in via the upstream. Thanks, Rafael
Re: [UPDATE PATCH v2 1/3] ACPICA: Events: Introduce acpi_mask_gpe() to implement GPE masking mechanism
On Monday, July 04, 2016 03:59:07 PM Rafael J. Wysocki wrote: > On Thursday, June 23, 2016 03:05:47 PM Lv Zheng wrote: > > (remove acpi_unmask_gpe() from the patch description) > > > > There is a facility in Linux, developers can control the enabling/disabling > > of a GPE via /sys/firmware/acpi/interrupts/gpexx. This is mainly for > > debugging purposes. > > > > But many users expect to use this facility to implement quirks to mask a > > specific GPE when there is a gap in Linux causing this GPE to flood. This > > is not working correctly because currently this facility invokes > > enabling/disabling counting based GPE driver APIs: > > acpi_enable_gpe()/acpi_disable_gpe() > > and the GPE drivers can still affect the count to mess up the GPE > > masking purposes. > > > > However, most of the IRQ chip designs allow masking/unmasking IRQs via a > > masking bit which is different from the enabled bit to achieve the same > > purpose. But the GPE hardware doesn't contain such a feature, this brings > > the trouble. > > > > In this patch, we introduce a software mechanism to implement the GPE > > masking feature, and acpi_mask_gpe() are provided to the OSPMs to > > mask/unmask GPEs in the above mentioned situation instead of > > acpi_enable_gpe()/acpi_disable_gpe(). ACPICA BZ 1102. Lv Zheng. > > > > Link: https://bugs.acpica.org/show_bug.cgi?id=1102 > > Signed-off-by: Lv Zheng > > I've queued up this one and the [2/3] and please see my comments on the [3/3]. I've decided that it's better if this goes in via upstream ACPICA, so it's not in the queue any more. For the time being, I'd like all changes in the ACPICA code to go in via the upstream. Thanks, Rafael
Re: [patch] mtd: maps: sa1100-flash: potential NULL dereference
On Fri, Jul 15, 2016 at 05:32:09PM -0700, Brian Norris wrote: > + stable > > Hi Dan, > > Patch looks good, but one question. > > On Fri, Jul 15, 2016 at 02:06:30PM +0300, Dan Carpenter wrote: > > We check for NULL but then dereference "info->mtd" on the next line. > > > > Fixes: 72169755cf36 ('mtd: maps: sa1100-flash: show parent device in sysfs') > > What am I supposed to do about tags like this? It appears that the > -stable folks have started taking patches with a 'Fixes' tag alone [0], > even though that's not mentioned in [1]. I ask because I strongly > suspect this patch doesn't fit the rules in [1] -- it quite likely has > only been compile tested; and it qualifies quite well as violating > bullet 4: > > """ > - It must fix a real bug that bothers people (not a, "This could be a >problem..." type thing). > """ > > So, I'd like to keep the tag, but I'd like to avoid having to NAK it in > the stable review process. (And really, I often don't care enough to > even do that. I believe there's a very low chance that something like > this would cause additional problems more than the original bug.) Only sometimes will I pick up something that only has a fixes: tag in it, not all the time, I try to review the patch to see if it does match the rules or not. But, fixing an oops is a good thing, I'm sure you can figure out how to trigger it otherwise you would not be taking such a patch as it would be not be needed :) thanks, greg k-h
Re: [patch] mtd: maps: sa1100-flash: potential NULL dereference
On Fri, Jul 15, 2016 at 05:32:09PM -0700, Brian Norris wrote: > + stable > > Hi Dan, > > Patch looks good, but one question. > > On Fri, Jul 15, 2016 at 02:06:30PM +0300, Dan Carpenter wrote: > > We check for NULL but then dereference "info->mtd" on the next line. > > > > Fixes: 72169755cf36 ('mtd: maps: sa1100-flash: show parent device in sysfs') > > What am I supposed to do about tags like this? It appears that the > -stable folks have started taking patches with a 'Fixes' tag alone [0], > even though that's not mentioned in [1]. I ask because I strongly > suspect this patch doesn't fit the rules in [1] -- it quite likely has > only been compile tested; and it qualifies quite well as violating > bullet 4: > > """ > - It must fix a real bug that bothers people (not a, "This could be a >problem..." type thing). > """ > > So, I'd like to keep the tag, but I'd like to avoid having to NAK it in > the stable review process. (And really, I often don't care enough to > even do that. I believe there's a very low chance that something like > this would cause additional problems more than the original bug.) Only sometimes will I pick up something that only has a fixes: tag in it, not all the time, I try to review the patch to see if it does match the rules or not. But, fixing an oops is a good thing, I'm sure you can figure out how to trigger it otherwise you would not be taking such a patch as it would be not be needed :) thanks, greg k-h
Re: [RFC PATCH 3/3] ACPI / PM: Fix EC polling issue by implementing prepare_late/finish_early suspend_ops callbacks
On Tuesday, June 28, 2016 04:04:46 PM Lv Zheng wrote: > _PTS/_WAK may contain EC transactions, it is better to have them handled > with IRQ enabled. This patch moves the 2 suspend PM ops from noirq stage > to late/early stage. > > Signed-off-by: Lv ZhengThere are systems that won't work with this patch applied, so I don't see a point in applying the other two. > --- > drivers/acpi/sleep.c |5 +++-- > 1 file changed, 3 insertions(+), 2 deletions(-) > > diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c > index d30fce7f..c5c374c9 100644 > --- a/drivers/acpi/sleep.c > +++ b/drivers/acpi/sleep.c > @@ -595,9 +595,10 @@ static int acpi_suspend_state_valid(suspend_state_t > pm_state) > static const struct platform_suspend_ops acpi_suspend_ops = { > .valid = acpi_suspend_state_valid, > .begin = acpi_suspend_begin, > - .prepare_noirq = acpi_pm_prepare, > + .prepare_late = __acpi_pm_prepare, > + .prepare_noirq = acpi_pm_pre_suspend, > .enter = acpi_suspend_enter, > - .finish_noirq = acpi_pm_finish, > + .finish_early = acpi_pm_finish, > .end = acpi_pm_end, > }; > > Thanks, Rafael
Re: [RFC PATCH 3/3] ACPI / PM: Fix EC polling issue by implementing prepare_late/finish_early suspend_ops callbacks
On Tuesday, June 28, 2016 04:04:46 PM Lv Zheng wrote: > _PTS/_WAK may contain EC transactions, it is better to have them handled > with IRQ enabled. This patch moves the 2 suspend PM ops from noirq stage > to late/early stage. > > Signed-off-by: Lv Zheng There are systems that won't work with this patch applied, so I don't see a point in applying the other two. > --- > drivers/acpi/sleep.c |5 +++-- > 1 file changed, 3 insertions(+), 2 deletions(-) > > diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c > index d30fce7f..c5c374c9 100644 > --- a/drivers/acpi/sleep.c > +++ b/drivers/acpi/sleep.c > @@ -595,9 +595,10 @@ static int acpi_suspend_state_valid(suspend_state_t > pm_state) > static const struct platform_suspend_ops acpi_suspend_ops = { > .valid = acpi_suspend_state_valid, > .begin = acpi_suspend_begin, > - .prepare_noirq = acpi_pm_prepare, > + .prepare_late = __acpi_pm_prepare, > + .prepare_noirq = acpi_pm_pre_suspend, > .enter = acpi_suspend_enter, > - .finish_noirq = acpi_pm_finish, > + .finish_early = acpi_pm_finish, > .end = acpi_pm_end, > }; > > Thanks, Rafael
Re: [PATCH 2/2] mtd: atmel-quadspi: add driver for Atmel QSPI controller
Hi Cyrille, On Wed, Jul 13, 2016 at 06:32:42PM -0700, Brian Norris wrote: > On Mon, Jun 13, 2016 at 05:10:26PM +0200, Cyrille Pitchen wrote: > > This driver add support to the new Atmel QSPI controller embedded into > > sama5d2x SoCs. It expects a NOR memory to be connected to the QSPI > > controller. > > > > Signed-off-by: Cyrille Pitchen> > Acked-by: Nicolas Ferre > > --- > > drivers/mtd/spi-nor/Kconfig | 9 + > > drivers/mtd/spi-nor/Makefile| 1 + > > drivers/mtd/spi-nor/atmel-quadspi.c | 741 > > > > 3 files changed, 751 insertions(+) > > create mode 100644 drivers/mtd/spi-nor/atmel-quadspi.c > > > > diff --git a/drivers/mtd/spi-nor/Kconfig b/drivers/mtd/spi-nor/Kconfig > > index d42c98e1f581..c546efd1357b 100644 > > --- a/drivers/mtd/spi-nor/Kconfig > > +++ b/drivers/mtd/spi-nor/Kconfig > > @@ -38,6 +38,15 @@ config SPI_FSL_QUADSPI > > This controller does not support generic SPI. It only supports > > SPI NOR. > > > > +config SPI_ATMEL_QUADSPI > > + tristate "Atmel Quad SPI Controller" > > + depends on ARCH_AT91 || (ARM && COMPILE_TEST) > > + depends on OF && HAS_IOMEM > > + help > > + This enables support for the Quad SPI controller in master mode. > > + This driver does not support generic SPI. The implementation only > > + supports SPI NOR. > > + > > config SPI_NXP_SPIFI > > tristate "NXP SPI Flash Interface (SPIFI)" > > depends on OF && (ARCH_LPC18XX || COMPILE_TEST) > > diff --git a/drivers/mtd/spi-nor/Makefile b/drivers/mtd/spi-nor/Makefile > > index 0bf3a7f81675..1525913698ad 100644 > > --- a/drivers/mtd/spi-nor/Makefile > > +++ b/drivers/mtd/spi-nor/Makefile > > @@ -2,3 +2,4 @@ obj-$(CONFIG_MTD_SPI_NOR) += spi-nor.o > > obj-$(CONFIG_SPI_FSL_QUADSPI) += fsl-quadspi.o > > obj-$(CONFIG_MTD_MT81xx_NOR)+= mtk-quadspi.o > > obj-$(CONFIG_SPI_NXP_SPIFI)+= nxp-spifi.o > > +obj-$(CONFIG_SPI_ATMEL_QUADSPI)+= atmel-quadspi.o > > diff --git a/drivers/mtd/spi-nor/atmel-quadspi.c > > b/drivers/mtd/spi-nor/atmel-quadspi.c > > new file mode 100644 > > index ..06d1bf276dd0 > > --- /dev/null > > +++ b/drivers/mtd/spi-nor/atmel-quadspi.c > > @@ -0,0 +1,741 @@ > > [...] > > > +struct atmel_qspi_command { > > + union { > > + struct { > > + u32 instruction:1; > > + u32 address:3; > > + u32 mode:1; > > + u32 dummy:1; > > + u32 data:1; > > + u32 reserved:25; > > + } bits; > > Are you sure this bitfield is going to do what you want, all the time? > What about on big-endian architectures? And are you guaranteed it'll > pack properly, with no padding? IIRC, the answer to the first 2 is "no", > and I have no idea about the 3rd. Honestly, I've been scared away from > using bitfields on anything where the ordering mattered, and I thought > that's because I was hurt by the lack of guarantee once. But I easily > could be misguided. > > > + u32 word; > > + } enable; > > + u8 instruction; > > + u8 mode; > > + u8 num_mode_cycles; > > + u8 num_dummy_cycles; > > + u32 address; > > + > > + size_t buf_len; > > + const void *tx_buf; > > + void*rx_buf; > > +}; > > + > > [...] > > > +static int atmel_qspi_probe(struct platform_device *pdev) > > +{ > > + struct device_node *child, *np = pdev->dev.of_node; > > + char modalias[SPI_NAME_SIZE]; > > + const char *name = NULL; > > + struct atmel_qspi *aq; > > + struct resource *res; > > + struct spi_nor *nor; > > + struct mtd_info *mtd; > > + int irq, err = 0; > > + > > + if (of_get_child_count(np) != 1) > > + return -ENODEV; > > + child = of_get_next_child(np, NULL); > > + > > + aq = devm_kzalloc(>dev, sizeof(*aq), GFP_KERNEL); > > + if (!aq) { > > + err = -ENOMEM; > > + goto exit; > > + } > > + > > + platform_set_drvdata(pdev, aq); > > + init_completion(>cmd_completion); > > + aq->pdev = pdev; > > + > > + /* Map the registers */ > > + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "qspi_base"); > > + aq->regs = devm_ioremap_resource(>dev, res); > > + if (IS_ERR(aq->regs)) { > > + dev_err(>dev, "missing registers\n"); > > + err = PTR_ERR(aq->regs); > > + goto exit; > > + } > > + > > + /* Map the AHB memory */ > > + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "qspi_mmap"); > > + aq->mem = devm_ioremap_resource(>dev, res); > > + if (IS_ERR(aq->mem)) { > > + dev_err(>dev, "missing AHB memory\n"); > > + err = PTR_ERR(aq->mem); > > + goto exit; > > + } > > + > > + /* Get the peripheral clock */ > > + aq->clk = devm_clk_get(>dev, NULL); > > + if (IS_ERR(aq->clk)) { > > +
Re: [PATCH 2/2] mtd: atmel-quadspi: add driver for Atmel QSPI controller
Hi Cyrille, On Wed, Jul 13, 2016 at 06:32:42PM -0700, Brian Norris wrote: > On Mon, Jun 13, 2016 at 05:10:26PM +0200, Cyrille Pitchen wrote: > > This driver add support to the new Atmel QSPI controller embedded into > > sama5d2x SoCs. It expects a NOR memory to be connected to the QSPI > > controller. > > > > Signed-off-by: Cyrille Pitchen > > Acked-by: Nicolas Ferre > > --- > > drivers/mtd/spi-nor/Kconfig | 9 + > > drivers/mtd/spi-nor/Makefile| 1 + > > drivers/mtd/spi-nor/atmel-quadspi.c | 741 > > > > 3 files changed, 751 insertions(+) > > create mode 100644 drivers/mtd/spi-nor/atmel-quadspi.c > > > > diff --git a/drivers/mtd/spi-nor/Kconfig b/drivers/mtd/spi-nor/Kconfig > > index d42c98e1f581..c546efd1357b 100644 > > --- a/drivers/mtd/spi-nor/Kconfig > > +++ b/drivers/mtd/spi-nor/Kconfig > > @@ -38,6 +38,15 @@ config SPI_FSL_QUADSPI > > This controller does not support generic SPI. It only supports > > SPI NOR. > > > > +config SPI_ATMEL_QUADSPI > > + tristate "Atmel Quad SPI Controller" > > + depends on ARCH_AT91 || (ARM && COMPILE_TEST) > > + depends on OF && HAS_IOMEM > > + help > > + This enables support for the Quad SPI controller in master mode. > > + This driver does not support generic SPI. The implementation only > > + supports SPI NOR. > > + > > config SPI_NXP_SPIFI > > tristate "NXP SPI Flash Interface (SPIFI)" > > depends on OF && (ARCH_LPC18XX || COMPILE_TEST) > > diff --git a/drivers/mtd/spi-nor/Makefile b/drivers/mtd/spi-nor/Makefile > > index 0bf3a7f81675..1525913698ad 100644 > > --- a/drivers/mtd/spi-nor/Makefile > > +++ b/drivers/mtd/spi-nor/Makefile > > @@ -2,3 +2,4 @@ obj-$(CONFIG_MTD_SPI_NOR) += spi-nor.o > > obj-$(CONFIG_SPI_FSL_QUADSPI) += fsl-quadspi.o > > obj-$(CONFIG_MTD_MT81xx_NOR)+= mtk-quadspi.o > > obj-$(CONFIG_SPI_NXP_SPIFI)+= nxp-spifi.o > > +obj-$(CONFIG_SPI_ATMEL_QUADSPI)+= atmel-quadspi.o > > diff --git a/drivers/mtd/spi-nor/atmel-quadspi.c > > b/drivers/mtd/spi-nor/atmel-quadspi.c > > new file mode 100644 > > index ..06d1bf276dd0 > > --- /dev/null > > +++ b/drivers/mtd/spi-nor/atmel-quadspi.c > > @@ -0,0 +1,741 @@ > > [...] > > > +struct atmel_qspi_command { > > + union { > > + struct { > > + u32 instruction:1; > > + u32 address:3; > > + u32 mode:1; > > + u32 dummy:1; > > + u32 data:1; > > + u32 reserved:25; > > + } bits; > > Are you sure this bitfield is going to do what you want, all the time? > What about on big-endian architectures? And are you guaranteed it'll > pack properly, with no padding? IIRC, the answer to the first 2 is "no", > and I have no idea about the 3rd. Honestly, I've been scared away from > using bitfields on anything where the ordering mattered, and I thought > that's because I was hurt by the lack of guarantee once. But I easily > could be misguided. > > > + u32 word; > > + } enable; > > + u8 instruction; > > + u8 mode; > > + u8 num_mode_cycles; > > + u8 num_dummy_cycles; > > + u32 address; > > + > > + size_t buf_len; > > + const void *tx_buf; > > + void*rx_buf; > > +}; > > + > > [...] > > > +static int atmel_qspi_probe(struct platform_device *pdev) > > +{ > > + struct device_node *child, *np = pdev->dev.of_node; > > + char modalias[SPI_NAME_SIZE]; > > + const char *name = NULL; > > + struct atmel_qspi *aq; > > + struct resource *res; > > + struct spi_nor *nor; > > + struct mtd_info *mtd; > > + int irq, err = 0; > > + > > + if (of_get_child_count(np) != 1) > > + return -ENODEV; > > + child = of_get_next_child(np, NULL); > > + > > + aq = devm_kzalloc(>dev, sizeof(*aq), GFP_KERNEL); > > + if (!aq) { > > + err = -ENOMEM; > > + goto exit; > > + } > > + > > + platform_set_drvdata(pdev, aq); > > + init_completion(>cmd_completion); > > + aq->pdev = pdev; > > + > > + /* Map the registers */ > > + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "qspi_base"); > > + aq->regs = devm_ioremap_resource(>dev, res); > > + if (IS_ERR(aq->regs)) { > > + dev_err(>dev, "missing registers\n"); > > + err = PTR_ERR(aq->regs); > > + goto exit; > > + } > > + > > + /* Map the AHB memory */ > > + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "qspi_mmap"); > > + aq->mem = devm_ioremap_resource(>dev, res); > > + if (IS_ERR(aq->mem)) { > > + dev_err(>dev, "missing AHB memory\n"); > > + err = PTR_ERR(aq->mem); > > + goto exit; > > + } > > + > > + /* Get the peripheral clock */ > > + aq->clk = devm_clk_get(>dev, NULL); > > + if (IS_ERR(aq->clk)) { > > + dev_err(>dev, "missing peripheral clock\n"); >
[PATCH 1/6] arm64: dts: qcom: msm8916: Add smsm and smp2p nodes
This patch adds the smsm and smp2p nodes for the hexagon and wcnss cores. Signed-off-by: Bjorn Andersson--- arch/arm64/boot/dts/qcom/msm8916.dtsi | 82 +++ 1 file changed, 82 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/msm8916.dtsi b/arch/arm64/boot/dts/qcom/msm8916.dtsi index 11bdc24cfc74..6148ea05b50a 100644 --- a/arch/arm64/boot/dts/qcom/msm8916.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8916.dtsi @@ -657,6 +657,88 @@ }; }; }; + + hexagon-smp2p { + compatible = "qcom,smp2p"; + qcom,smem = <435>, <428>; + + interrupts = <0 27 IRQ_TYPE_EDGE_RISING>; + + qcom,ipc = < 8 14>; + + qcom,local-pid = <0>; + qcom,remote-pid = <1>; + + hexagon_smp2p_out: master-kernel { + qcom,entry-name = "master-kernel"; + + #qcom,smem-state-cells = <1>; + }; + + hexagon_smp2p_in: slave-kernel { + qcom,entry-name = "slave-kernel"; + + interrupt-controller; + #interrupt-cells = <2>; + }; + }; + + wcnss-smp2p { + compatible = "qcom,smp2p"; + qcom,smem = <451>, <431>; + + interrupts = <0 143 IRQ_TYPE_EDGE_RISING>; + + qcom,ipc = < 8 18>; + + qcom,local-pid = <0>; + qcom,remote-pid = <4>; + + wcnss_smp2p_out: master-kernel { + qcom,entry-name = "master-kernel"; + + #qcom,smem-state-cells = <1>; + }; + + wcnss_smp2p_in: slave-kernel { + qcom,entry-name = "slave-kernel"; + + interrupt-controller; + #interrupt-cells = <2>; + }; + }; + + smsm { + compatible = "qcom,smsm"; + + #address-cells = <1>; + #size-cells = <0>; + + qcom,ipc-1 = < 0 13>; + qcom,ipc-6 = < 0 19>; + + apps_smsm: apps@0 { + reg = <0>; + + #qcom,smem-state-cells = <1>; + }; + + hexagon_smsm: hexagon@1 { + reg = <1>; + interrupts = <0 26 IRQ_TYPE_EDGE_RISING>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + wcnss_smsm: wcnss@6 { + reg = <6>; + interrupts = <0 144 IRQ_TYPE_EDGE_RISING>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + }; }; #include "msm8916-pins.dtsi" -- 2.5.0
[PATCH 2/6] arm64: dts: qcom: msm8916: Add mba memory reserve
The modem boot authenticator needs space to play in, this is supposed to be relocatable and as such could later be replaced with a dynamically allocated chunk of memory. But let's give it a reserve for now, as we know that works. Signed-off-by: Bjorn Andersson--- arch/arm64/boot/dts/qcom/msm8916.dtsi | 5 + 1 file changed, 5 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/msm8916.dtsi b/arch/arm64/boot/dts/qcom/msm8916.dtsi index 6148ea05b50a..4f2882605138 100644 --- a/arch/arm64/boot/dts/qcom/msm8916.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8916.dtsi @@ -86,6 +86,11 @@ reg = <0x0 0x8930 0x0 0x60>; no-map; }; + + mba_mem: mba@8ea0 { + no-map; + reg = <0 0x8ea0 0 0x10>; + }; }; cpus { -- 2.5.0
[PATCH 1/6] arm64: dts: qcom: msm8916: Add smsm and smp2p nodes
This patch adds the smsm and smp2p nodes for the hexagon and wcnss cores. Signed-off-by: Bjorn Andersson --- arch/arm64/boot/dts/qcom/msm8916.dtsi | 82 +++ 1 file changed, 82 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/msm8916.dtsi b/arch/arm64/boot/dts/qcom/msm8916.dtsi index 11bdc24cfc74..6148ea05b50a 100644 --- a/arch/arm64/boot/dts/qcom/msm8916.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8916.dtsi @@ -657,6 +657,88 @@ }; }; }; + + hexagon-smp2p { + compatible = "qcom,smp2p"; + qcom,smem = <435>, <428>; + + interrupts = <0 27 IRQ_TYPE_EDGE_RISING>; + + qcom,ipc = < 8 14>; + + qcom,local-pid = <0>; + qcom,remote-pid = <1>; + + hexagon_smp2p_out: master-kernel { + qcom,entry-name = "master-kernel"; + + #qcom,smem-state-cells = <1>; + }; + + hexagon_smp2p_in: slave-kernel { + qcom,entry-name = "slave-kernel"; + + interrupt-controller; + #interrupt-cells = <2>; + }; + }; + + wcnss-smp2p { + compatible = "qcom,smp2p"; + qcom,smem = <451>, <431>; + + interrupts = <0 143 IRQ_TYPE_EDGE_RISING>; + + qcom,ipc = < 8 18>; + + qcom,local-pid = <0>; + qcom,remote-pid = <4>; + + wcnss_smp2p_out: master-kernel { + qcom,entry-name = "master-kernel"; + + #qcom,smem-state-cells = <1>; + }; + + wcnss_smp2p_in: slave-kernel { + qcom,entry-name = "slave-kernel"; + + interrupt-controller; + #interrupt-cells = <2>; + }; + }; + + smsm { + compatible = "qcom,smsm"; + + #address-cells = <1>; + #size-cells = <0>; + + qcom,ipc-1 = < 0 13>; + qcom,ipc-6 = < 0 19>; + + apps_smsm: apps@0 { + reg = <0>; + + #qcom,smem-state-cells = <1>; + }; + + hexagon_smsm: hexagon@1 { + reg = <1>; + interrupts = <0 26 IRQ_TYPE_EDGE_RISING>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + wcnss_smsm: wcnss@6 { + reg = <6>; + interrupts = <0 144 IRQ_TYPE_EDGE_RISING>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + }; }; #include "msm8916-pins.dtsi" -- 2.5.0
[PATCH 2/6] arm64: dts: qcom: msm8916: Add mba memory reserve
The modem boot authenticator needs space to play in, this is supposed to be relocatable and as such could later be replaced with a dynamically allocated chunk of memory. But let's give it a reserve for now, as we know that works. Signed-off-by: Bjorn Andersson --- arch/arm64/boot/dts/qcom/msm8916.dtsi | 5 + 1 file changed, 5 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/msm8916.dtsi b/arch/arm64/boot/dts/qcom/msm8916.dtsi index 6148ea05b50a..4f2882605138 100644 --- a/arch/arm64/boot/dts/qcom/msm8916.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8916.dtsi @@ -86,6 +86,11 @@ reg = <0x0 0x8930 0x0 0x60>; no-map; }; + + mba_mem: mba@8ea0 { + no-map; + reg = <0 0x8ea0 0 0x10>; + }; }; cpus { -- 2.5.0
[PATCH 4/6] arm64: dts: qcom: msm8916: Add tcsr syscon
The TCSR memory segment includes various functionality, among other things the halt-registers for the Hexagon. Signed-off-by: Bjorn Andersson--- arch/arm64/boot/dts/qcom/msm8916.dtsi | 5 + 1 file changed, 5 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/msm8916.dtsi b/arch/arm64/boot/dts/qcom/msm8916.dtsi index 1e67acc19a9d..64f85f82602c 100644 --- a/arch/arm64/boot/dts/qcom/msm8916.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8916.dtsi @@ -234,6 +234,11 @@ reg = <0x1905000 0x2>; }; + tcsr: syscon@1937000 { + compatible = "qcom,tcsr-msm8916", "syscon"; + reg = <0x1937000 0x3>; + }; + tcsr_mutex: hwlock { compatible = "qcom,tcsr-mutex"; syscon = <_mutex_regs 0 0x1000>; -- 2.5.0
[PATCH 3/6] arm64: dts: qcom: msm8916: Make scm a reset-controller
On msm8916 SCM acts as a controller for the MSS_RESET found in the GCC, update the DT node so that we can address this. Signed-off-by: Bjorn Andersson--- arch/arm64/boot/dts/qcom/msm8916.dtsi | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/qcom/msm8916.dtsi b/arch/arm64/boot/dts/qcom/msm8916.dtsi index 4f2882605138..1e67acc19a9d 100644 --- a/arch/arm64/boot/dts/qcom/msm8916.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8916.dtsi @@ -192,10 +192,11 @@ }; firmware { - scm { + scm: scm { compatible = "qcom,scm"; clocks = < GCC_CRYPTO_CLK>, < GCC_CRYPTO_AXI_CLK>, < GCC_CRYPTO_AHB_CLK>; clock-names = "core", "bus", "iface"; + #reset-cells = <1>; }; }; -- 2.5.0
[PATCH 4/6] arm64: dts: qcom: msm8916: Add tcsr syscon
The TCSR memory segment includes various functionality, among other things the halt-registers for the Hexagon. Signed-off-by: Bjorn Andersson --- arch/arm64/boot/dts/qcom/msm8916.dtsi | 5 + 1 file changed, 5 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/msm8916.dtsi b/arch/arm64/boot/dts/qcom/msm8916.dtsi index 1e67acc19a9d..64f85f82602c 100644 --- a/arch/arm64/boot/dts/qcom/msm8916.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8916.dtsi @@ -234,6 +234,11 @@ reg = <0x1905000 0x2>; }; + tcsr: syscon@1937000 { + compatible = "qcom,tcsr-msm8916", "syscon"; + reg = <0x1937000 0x3>; + }; + tcsr_mutex: hwlock { compatible = "qcom,tcsr-mutex"; syscon = <_mutex_regs 0 0x1000>; -- 2.5.0
[PATCH 3/6] arm64: dts: qcom: msm8916: Make scm a reset-controller
On msm8916 SCM acts as a controller for the MSS_RESET found in the GCC, update the DT node so that we can address this. Signed-off-by: Bjorn Andersson --- arch/arm64/boot/dts/qcom/msm8916.dtsi | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/qcom/msm8916.dtsi b/arch/arm64/boot/dts/qcom/msm8916.dtsi index 4f2882605138..1e67acc19a9d 100644 --- a/arch/arm64/boot/dts/qcom/msm8916.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8916.dtsi @@ -192,10 +192,11 @@ }; firmware { - scm { + scm: scm { compatible = "qcom,scm"; clocks = < GCC_CRYPTO_CLK>, < GCC_CRYPTO_AXI_CLK>, < GCC_CRYPTO_AHB_CLK>; clock-names = "core", "bus", "iface"; + #reset-cells = <1>; }; }; -- 2.5.0
[PATCH 6/6] arm64: dts: qcom: msm8916: Add Hexagon remoteproc node
Add the remoteproc node that allows us to control the life cycle of the Hexagon core found in the msm8916 SoC. Signed-off-by: Bjorn Andersson--- arch/arm64/boot/dts/qcom/msm8916.dtsi | 43 ++- 1 file changed, 42 insertions(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/qcom/msm8916.dtsi b/arch/arm64/boot/dts/qcom/msm8916.dtsi index 85ec5c932975..504e524b910e 100644 --- a/arch/arm64/boot/dts/qcom/msm8916.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8916.dtsi @@ -77,7 +77,7 @@ no-map; }; - mpss@8680 { + mpss_mem: mpss@8680 { reg = <0x0 0x8680 0x0 0x2b0>; no-map; }; @@ -620,6 +620,47 @@ clocks = < GCC_PRNG_AHB_CLK>; clock-names = "core"; }; + + hexagon@408 { + compatible = "qcom,q6v5-pil"; + reg = <0x0408 0x100>, + <0x0402 0x040>; + + reg-names = "qdsp6", "rmb"; + + interrupts-extended = < 0 24 1>, + <_smp2p_in 0 0>, + <_smp2p_in 1 0>, + <_smp2p_in 2 0>, + <_smp2p_in 3 0>; + interrupt-names = "wdog", "fatal", "ready", + "handover", "stop-ack"; + + clocks = < GCC_MSS_CFG_AHB_CLK>, +< GCC_MSS_Q6_BIMC_AXI_CLK>, +< GCC_BOOT_ROM_AHB_CLK>; + clock-names = "iface", "bus", "mem"; + + qcom,smem-states = <_smp2p_out 0>; + qcom,smem-state-names = "stop"; + + resets = < 0>; + reset-names = "mss_restart"; + + mx-supply = <_l3>; + pll-supply = <_l7>; + + qcom,halt-regs = < 0x18000 0x19000 0x1a000>; + + mba { + memory-region = <_mem>; + }; + + mpss { + memory-region = <_mem>; + }; + }; + }; smd { -- 2.5.0
[PATCH 6/6] arm64: dts: qcom: msm8916: Add Hexagon remoteproc node
Add the remoteproc node that allows us to control the life cycle of the Hexagon core found in the msm8916 SoC. Signed-off-by: Bjorn Andersson --- arch/arm64/boot/dts/qcom/msm8916.dtsi | 43 ++- 1 file changed, 42 insertions(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/qcom/msm8916.dtsi b/arch/arm64/boot/dts/qcom/msm8916.dtsi index 85ec5c932975..504e524b910e 100644 --- a/arch/arm64/boot/dts/qcom/msm8916.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8916.dtsi @@ -77,7 +77,7 @@ no-map; }; - mpss@8680 { + mpss_mem: mpss@8680 { reg = <0x0 0x8680 0x0 0x2b0>; no-map; }; @@ -620,6 +620,47 @@ clocks = < GCC_PRNG_AHB_CLK>; clock-names = "core"; }; + + hexagon@408 { + compatible = "qcom,q6v5-pil"; + reg = <0x0408 0x100>, + <0x0402 0x040>; + + reg-names = "qdsp6", "rmb"; + + interrupts-extended = < 0 24 1>, + <_smp2p_in 0 0>, + <_smp2p_in 1 0>, + <_smp2p_in 2 0>, + <_smp2p_in 3 0>; + interrupt-names = "wdog", "fatal", "ready", + "handover", "stop-ack"; + + clocks = < GCC_MSS_CFG_AHB_CLK>, +< GCC_MSS_Q6_BIMC_AXI_CLK>, +< GCC_BOOT_ROM_AHB_CLK>; + clock-names = "iface", "bus", "mem"; + + qcom,smem-states = <_smp2p_out 0>; + qcom,smem-state-names = "stop"; + + resets = < 0>; + reset-names = "mss_restart"; + + mx-supply = <_l3>; + pll-supply = <_l7>; + + qcom,halt-regs = < 0x18000 0x19000 0x1a000>; + + mba { + memory-region = <_mem>; + }; + + mpss { + memory-region = <_mem>; + }; + }; + }; smd { -- 2.5.0
[GIT PULL] Late MTD fix for v4.7
Hi Linus, The following changes since commit 1a695a905c18548062509178b98bc91e67510864: Linux 4.7-rc1 (2016-05-29 09:29:24 -0700) are available in the git repository at: git://git.infradead.org/linux-mtd.git tags/for-linus-20160715 for you to fetch changes up to 7ce9ea7e6b35a652034486133174d4e17055cef5: mtd: nand: omap2: Add check for old elm binding (2016-07-14 08:57:36 -0700) Late MTD fix for v4.7: One regression in the Device Tree handling for OMAP NAND handling of the ELM node. TI migrated to using the property name "ti,elm-id", but forgot to keep compatibility with the old "elm_id" property. Also, might as well send out this MAINTAINERS fixup now. Geert Uytterhoeven (1): MAINTAINERS: Add file patterns for mtd device tree bindings Teresa Remmet (1): mtd: nand: omap2: Add check for old elm binding MAINTAINERS | 1 + drivers/mtd/nand/omap2.c | 7 +-- 2 files changed, 6 insertions(+), 2 deletions(-)
[PATCH 5/6] arm64: dts: qcom: msm8916: Add Hexagon SMD edge
Add the Hexagon SMD edge so that SMD channels provided by the Hexagon is recognized. Signed-off-by: Bjorn Andersson--- arch/arm64/boot/dts/qcom/msm8916.dtsi | 8 1 file changed, 8 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/msm8916.dtsi b/arch/arm64/boot/dts/qcom/msm8916.dtsi index 64f85f82602c..85ec5c932975 100644 --- a/arch/arm64/boot/dts/qcom/msm8916.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8916.dtsi @@ -667,6 +667,14 @@ }; }; }; + + hexagon { + interrupts = <0 25 IRQ_TYPE_EDGE_RISING>; + qcom,ipc = < 8 12>; + + qcom,smd-edge = <0>; + qcom,remote-pid = <1>; + }; }; hexagon-smp2p { -- 2.5.0
[GIT PULL] Late MTD fix for v4.7
Hi Linus, The following changes since commit 1a695a905c18548062509178b98bc91e67510864: Linux 4.7-rc1 (2016-05-29 09:29:24 -0700) are available in the git repository at: git://git.infradead.org/linux-mtd.git tags/for-linus-20160715 for you to fetch changes up to 7ce9ea7e6b35a652034486133174d4e17055cef5: mtd: nand: omap2: Add check for old elm binding (2016-07-14 08:57:36 -0700) Late MTD fix for v4.7: One regression in the Device Tree handling for OMAP NAND handling of the ELM node. TI migrated to using the property name "ti,elm-id", but forgot to keep compatibility with the old "elm_id" property. Also, might as well send out this MAINTAINERS fixup now. Geert Uytterhoeven (1): MAINTAINERS: Add file patterns for mtd device tree bindings Teresa Remmet (1): mtd: nand: omap2: Add check for old elm binding MAINTAINERS | 1 + drivers/mtd/nand/omap2.c | 7 +-- 2 files changed, 6 insertions(+), 2 deletions(-)
[PATCH 5/6] arm64: dts: qcom: msm8916: Add Hexagon SMD edge
Add the Hexagon SMD edge so that SMD channels provided by the Hexagon is recognized. Signed-off-by: Bjorn Andersson --- arch/arm64/boot/dts/qcom/msm8916.dtsi | 8 1 file changed, 8 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/msm8916.dtsi b/arch/arm64/boot/dts/qcom/msm8916.dtsi index 64f85f82602c..85ec5c932975 100644 --- a/arch/arm64/boot/dts/qcom/msm8916.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8916.dtsi @@ -667,6 +667,14 @@ }; }; }; + + hexagon { + interrupts = <0 25 IRQ_TYPE_EDGE_RISING>; + qcom,ipc = < 8 12>; + + qcom,smd-edge = <0>; + qcom,remote-pid = <1>; + }; }; hexagon-smp2p { -- 2.5.0