From: Stanislaw Gruszka <stf_xl@wp.pl>
To: Sergei Shtylyov <sshtylyov@ru.mvista.com>
Cc: linux-ide@vger.kernel.org, Andrew Victor <linux@maxim.org.za>,
linux-arm-kernel@lists.arm.linux.org.uk
Subject: Re: [PATCH 2/3] ide: add at91_ide driver
Date: Wed, 4 Feb 2009 15:47:43 +0100 [thread overview]
Message-ID: <200902041547.44149.stf_xl@wp.pl> (raw)
In-Reply-To: <498987E6.7040909@ru.mvista.com>
Wednesday 04 February 2009 13:19:50 Sergei Shtylyov napisał(a):
> > diff --git a/arch/arm/mach-at91/include/mach/board.h b/arch/arm/mach-at91/include/mach/board.h
> > index fb51f0e..6674b9b 100644
> > --- a/arch/arm/mach-at91/include/mach/board.h
> > +++ b/arch/arm/mach-at91/include/mach/board.h
> > @@ -59,6 +59,18 @@ struct at91_cf_data {
> > };
> > extern void __init at91_add_device_cf(struct at91_cf_data *data);
> >
> > + /* Compact Flash True IDE mode */
> > +struct at91_ide_data {
> > + u8 irq_pin; /* the same meaning as for CF */
> >
>
> I again have to express my dislike about not passing IRQ the usual
> way. Also, see my comments to the platform code.
Yes, I know, I don't like to argue. Only reasoning to use platform irq resource
seams to be: "because other drivers do". However we have exception - at91_cf
also use board->irq_pin, so maybe this driver could also do ?
> > + u8 det_pin;
> > + u8 rst_pin;
> > + u8 chipselect;
> > + u8 flags;
> > +#define AT91_IDE_SWAP_A0_A2 0x01
> > +};
> > +
> > +extern void __init at91_add_device_ide(struct at91_ide_data *data);
> > +
> > /* MMC / SD */
> > struct at91_mmc_data {
> > u8 det_pin; /* card detect IRQ */
> > diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig
> > index 3dad229..b11da5b 100644
> > --- a/drivers/ide/Kconfig
> > +++ b/drivers/ide/Kconfig
> > @@ -721,6 +721,11 @@ config BLK_DEV_IDE_TX4939
> > depends on SOC_TX4939
> > select BLK_DEV_IDEDMA_SFF
> >
> > +config BLK_DEV_IDE_AT91
> > + tristate "Atmel AT91 IDE support"
> >
>
> Please be more specific -- you can't drive AT91RM9200 SMC.
Ok.
>
> > + depends on ARM && ARCH_AT91
> >
>
> Please add "&& !ARCH_AT91RM9200". And maybe "&& !ARCH_AT91X40" too...
Ok.
> > diff --git a/drivers/ide/at91_ide.c b/drivers/ide/at91_ide.c
> > new file mode 100644
> > index 0000000..3a1f7e0
> > --- /dev/null
> > +++ b/drivers/ide/at91_ide.c
> > @@ -0,0 +1,496 @@
> > +/*
> > + * IDE host driver for AT91SAM9 Static Memory Controller
> >
>
> Why not call the driver 'at91sam9_ide'?
>
> > +/*
> > + * AT91 Static Memory Controller
>
> AT91SAM9.
Ok, currently only SAM9 can be used with driver. However I think adding
support to AT91RM9200 to this driver will be not much effort. I don't think
someone will want to write new driver for RM9200 insted using this one.
IMHO, current name is short and sweet and not miss the true so much -
most of the AT91s which can work with True IDE logic are supported.
I would like to stay with current name.
> > maps Task File and Data Register
> >
> > + * at the same address. To distinguish access between these two
>
> It would have been strange if it did it otherwise...
>
> > + * different bus data width is used: 8Bit for Task File, 16Bit for Data I/O
> > + *
> > + * After initialization we do 8/16 bit flipping (changes in SMC MODE register)
> > + * only inside IDE callback routines which are serialized by IDE layer,
> > + * so no additional locking needed.
> > + */
> > +
> > +static void init_smc_mode(const u8 chipselect)
> > +{
> > + at91_sys_write(AT91_SMC_MODE(chipselect), AT91_SMC_READMODE |
> > + AT91_SMC_WRITEMODE |
> > + AT91_SMC_BAT_SELECT |
> > + AT91_SMC_TDF_(0));
> >
>
> I'm not sure why are you fixing the dataflow timing again, this time
> to 0...
Not necessary code, will be removed.
> > +}
> > +
> > +static inline void set_8bit_mode(const u8 chipselect)
> > +{
> > + unsigned long mode = at91_sys_read(AT91_SMC_MODE(chipselect));
> > + mode &= ~AT91_SMC_DBW;
> > + mode |= AT91_SMC_DBW_8;
> > + at91_sys_write(AT91_SMC_MODE(chipselect), mode);
> > + pdbg("%u %08lx\n", chipselect, mode);
> > +}
> > +
> > +static inline void set_16bit_mode(const u8 chipselect)
> > +{
> > + unsigned long mode = at91_sys_read(AT91_SMC_MODE(chipselect));
> > + mode &= ~AT91_SMC_DBW;
> > + mode |= AT91_SMC_DBW_16;
> > + at91_sys_write(AT91_SMC_MODE(chipselect), mode);
> > + pdbg("%u %08lx\n", chipselect, mode);
> > +}
> >
>
> I'd advice to make this single function because it looks like a code
> duplication too much.
Uh well.
> > +static void set_smc_timings(const u8 chipselect, const u16 cycle,
> > + const u16 setup, const u16 pulse,
> > + const u16 data_float, int use_iordy)
> >
>
> Have you considered using already present sam9_smc_configure()
> instead to avoid the code duplication (it needs to be exported though)?
I think, it need to be exported, I'll check.
> > +{
> > + unsigned long mode;
> > +
> > + /* setup timings in SMC */
> > + at91_sys_write(AT91_SMC_SETUP(chipselect), AT91_SMC_NWESETUP_(setup) |
> > + AT91_SMC_NCS_WRSETUP_(0) |
> > + AT91_SMC_NRDSETUP_(setup) |
> > + AT91_SMC_NCS_RDSETUP_(0));
> > + at91_sys_write(AT91_SMC_PULSE(chipselect), AT91_SMC_NWEPULSE_(pulse) |
> > + AT91_SMC_NCS_WRPULSE_(cycle) |
> > + AT91_SMC_NRDPULSE_(pulse) |
> > + AT91_SMC_NCS_RDPULSE_(cycle));
> > + at91_sys_write(AT91_SMC_CYCLE(chipselect), AT91_SMC_NWECYCLE_(cycle) |
> > + AT91_SMC_NRDCYCLE_(cycle));
> > +
> > + mode = at91_sys_read(AT91_SMC_MODE(chipselect));
> >
>
> Frankly speaking, I don't see why you're reading this register back
> if you already know what needs to be set there -- as you've done it in
> init_smc_mode().
This function is not only used at initialization. It is also used when PIO mode
is changed.
> > +static unsigned int calc_mck_cycles(unsigned int ns, unsigned int mck_hz)
> > +{
> > + u64 tmp = ns;
> > +
> > + tmp *= mck_hz;
> > + tmp += 1000*1000*1000 - 1; /* round up */
> > + do_div(tmp, 1000*1000*1000);
> > + return (unsigned int) tmp;
> > +}
> > +
> > +static void apply_timings(const u8 chipselect, const u8 pio,
> > + const struct ide_timing *timing, const u16 *ata_id)
> > +{
> > + unsigned int t0, t1, t2, t6z, th;
> > + unsigned int cycle, setup, pulse, data_float;
> > + unsigned int mck_hz;
> > + struct clk *mck;
> > + int use_iordy;
> >
> [...]
> > +
> > + use_iordy = 0;
> >
>
> Can be done in initializer...
But here is more readable, I think.
> > + if (ata_id) {
> > + if (ata_id_is_cfa(ata_id)) {
> > + if (pio == 3 || pio == 4)
> > + use_iordy = 1;
> >
> > + } else if (pio >= 3 || ata_id_has_iordy(ata_id))
> > + use_iordy = 1;
> >
>
>
> No, you should check for IORDY regardless of CFA and using IORDY
> shouldn't be limeited to modes 3 and 4:
Hmm, I take as example ata_pio_need_iordy(), it is also wrong or maybe
I don't follow the logic properly.
> if (ata_id_has_iordy(ata_id) && !(ata_id_is_cfa(ata_id) && pio > 4))
> use_iodry = 1;
>
> > +static u8 ide_mm_inb(unsigned long port)
> > +{
> > + return (u8) readb((void __iomem *) port);
> >
>
> Explict cast not needed here.
Ok.
> > +irqreturn_t at91_irq_handler(int irq, void *dev_id)
> > +{
> > + int ntries = 8;
> > + int pin_val1, pin_val2;
> > +
> > + /* additional deglitch, line can be noisy in badly designed PCB */
> > + do {
> > + pin_val1 = at91_get_gpio_value(irq);
> > + pin_val2 = at91_get_gpio_value(irq);
> > + } while (pin_val1 != pin_val2 && --ntries > 0);
> >
> I suggest a shorter code:
>
> do {
> pin_val = at91_get_gpio_value(irq);
> } while (pin_val != at91_get_gpio_value(irq) && --ntries > 0);
For me your form is less readable.
> > +static int __init at91_ide_probe(struct platform_device *pdev)
> > +{
> >
> [...]
> > + host->ports[0]->extra_base = board->chipselect;
> >
>
> BTW, we have 2 fields in the struct hwif_s that fit this case better:
> config_data and select_data. It's a bit stange that you've selected
> extra_base...
Ok.
Regards
Stanislaw Gruszka
next prev parent reply other threads:[~2009-02-04 14:47 UTC|newest]
Thread overview: 23+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-02-03 10:47 [PATCH 2/3] ide: add at91_ide driver Stanislaw Gruszka
2009-02-04 12:19 ` Sergei Shtylyov
2009-02-04 14:47 ` Stanislaw Gruszka [this message]
2009-02-04 16:04 ` Sergei Shtylyov
2009-02-04 16:08 ` Sergei Shtylyov
2009-02-05 15:01 ` Stanislaw Gruszka
2009-02-05 16:09 ` Sergei Shtylyov
2009-02-05 20:00 ` Andrew Victor
2009-02-05 20:03 ` Sergei Shtylyov
2009-02-06 9:35 ` Stanislaw Gruszka
2009-02-06 10:55 ` Sergei Shtylyov
2009-02-06 16:50 ` Bartlomiej Zolnierkiewicz
2009-02-06 17:20 ` Sergei Shtylyov
2009-02-05 21:23 ` Bartlomiej Zolnierkiewicz
2009-02-05 23:31 ` Sergei Shtylyov
2009-02-06 16:36 ` Bartlomiej Zolnierkiewicz
2009-02-08 0:10 ` Sergei Shtylyov
2009-02-08 11:39 ` Sergei Shtylyov
2009-02-08 22:58 ` Sergei Shtylyov
2009-02-09 19:48 ` Bartlomiej Zolnierkiewicz
2009-02-06 9:30 ` Stanislaw Gruszka
2009-02-06 10:36 ` Sergei Shtylyov
2009-02-06 10:47 ` Stanislaw Gruszka
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=200902041547.44149.stf_xl@wp.pl \
--to=stf_xl@wp.pl \
--cc=linux-arm-kernel@lists.arm.linux.org.uk \
--cc=linux-ide@vger.kernel.org \
--cc=linux@maxim.org.za \
--cc=sshtylyov@ru.mvista.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.