Re: [PATCH v10 1/1] Mailbox: Add support for Platform Communication Channel

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 7 November 2014 20:22, Ashwin Chaugule <ashwin.chaugule@xxxxxxxxxx> wrote:

> +struct mbox_chan *pcc_mbox_request_channel(struct mbox_client *cl,
> +               int index)
> +{
> +       struct device *dev = pcc_mbox_ctrl.dev;
> +       struct mbox_chan *chan;
> +       unsigned long flags;
> +
> +       /*
> +        * Each PCC Subspace is a Mailbox Channel.
> +        * The PCC Clients get their PCC Subspace ID
> +        * from their own tables and pass it here.
> +        * This returns a pointer to the PCC subspace
> +        * for the Client to operate on.
> +        */
> +       chan = &pcc_mbox_chan[index];
> +
You are mapping 'Type' of a client directly onto SubSpace-ID of the
channel allocated.
If two clients need an instance of, say,
Generic-Communications-Channel i.e, Type-0, this will not work.
If no two clients can ask the same channel, MAX_PCC_SUBSPACES should
be limited to max 'Type' value defined in ACPI specs (just 2 in
ACPI-5.1).

> +       if (!chan || chan->cl) {
> +               dev_err(dev, "%s: PCC mailbox not free\n", __func__);
> +               return ERR_PTR(-EBUSY);
> +       }
> +
> +       spin_lock_irqsave(&chan->lock, flags);
> +       chan->msg_free = 0;
> +       chan->msg_count = 0;
> +       chan->active_req = NULL;
> +       chan->cl = cl;
> +       init_completion(&chan->tx_complete);
> +
> +       if (chan->txdone_method == TXDONE_BY_POLL && cl->knows_txdone)
> +               chan->txdone_method |= TXDONE_BY_ACK;
> +
> +       spin_unlock_irqrestore(&chan->lock, flags);
> +
> +       return chan;
> +}
> +EXPORT_SYMBOL_GPL(pcc_mbox_request_channel);
>
Nothing PCC specific here. All you have done is define a new api just
to pick an element from the array. You simply needed the
mbox_request_channel() let you through to controller.

> +void pcc_mbox_free_channel(struct mbox_chan *chan)
> +{
> +       unsigned long flags;
> +
> +       if (!chan || !chan->cl)
> +               return;
> +
> +       spin_lock_irqsave(&chan->lock, flags);
> +       chan->cl = NULL;
> +       chan->active_req = NULL;
> +       if (chan->txdone_method == (TXDONE_BY_POLL | TXDONE_BY_ACK))
> +               chan->txdone_method = TXDONE_BY_POLL;
> +
> +       spin_unlock_irqrestore(&chan->lock, flags);
> +}
> +EXPORT_SYMBOL_GPL(pcc_mbox_free_channel);
> +
Ditto, nothing PCC in this new PCC specific api.


> +/**
> + * pcc_send_data - Called from Mailbox Controller code to finally
> + *     transmit data over channel.
> + * @chan: Pointer to Mailbox channel over which to send data.
> + * @data: Actual data to be written over channel.
> + *
> + * Return: Err if something failed else 0 for success.
> + */
> +static int pcc_send_data(struct mbox_chan *chan, void *data)
> +{
> +       struct acpi_pcct_hw_reduced *pcct_ss = chan->con_priv;
> +       struct acpi_pcct_shared_memory *generic_comm_base =
> +               (struct acpi_pcct_shared_memory *) pcct_ss->base_address;
> +       struct acpi_generic_address doorbell;
> +       u64 doorbell_preserve;
> +       u64 doorbell_val;
> +       u64 doorbell_write;
> +       u16 cmd = *(u16 *) data;
> +       u16 ss_idx = -1;
> +
> +       ss_idx = get_subspace_id(chan);
> +
> +       if (ss_idx < 0) {
> +               pr_err("Invalid Subspace ID from PCC client\n");
> +               return -EINVAL;
> +       }
> +
> +       doorbell = pcct_ss->doorbell_register;
> +       doorbell_preserve = pcct_ss->preserve_mask;
> +       doorbell_write = pcct_ss->write_mask;
> +
> +       /* Write to the shared comm region. */
> +       writew(cmd, &generic_comm_base->command);
> +
> +       /* Write Subspace MAGIC value so platform can identify destination. */
> +       writel((PCCS_SS_SIG_MAGIC | ss_idx), &generic_comm_base->signature);
> +
> +       /* Flip CMD COMPLETE bit */
> +       writew(0, &generic_comm_base->status);
> +
> +       /* Sync notification from OSPM to Platform. */
> +       acpi_read(&doorbell_val, &doorbell);
> +       acpi_write((doorbell_val & doorbell_preserve) | doorbell_write,
> +                       &doorbell);
> +
> +       return 0;
> +}
> +
> +static struct mbox_chan_ops pcc_chan_ops = {
> +       .send_data = pcc_send_data,
> +       .last_tx_done = pcc_tx_done,
> +};
> +
> +/**
> + * parse_pcc_subspace - Parse the PCC table and extract PCC subspace
> + *             entries. There should be one entry per PCC client.
> + * @header: Pointer to the ACPI subtable header under the PCCT.
> + * @end: End of subtable entry.
> + *
> + * Return: 0 for Success, else errno.
> + *
> + * This gets called for each entry in the PCC table.
> + */
> +static int parse_pcc_subspace(struct acpi_subtable_header *header,
> +               const unsigned long end)
> +{
> +       struct acpi_pcct_hw_reduced *pcct_ss;
> +
> +       if (pcc_mbox_ctrl.num_chans <= MAX_PCC_SUBSPACES) {
> +               pcct_ss = (struct acpi_pcct_hw_reduced *) header;
> +
> +               if (pcct_ss->header.type !=
> +                               ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE) {
> +                       pr_err("Incorrect PCC Subspace type detected\n");
> +                       return -EINVAL;
> +               }
> +
The driver supports only ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE client ?!

-Jassi
--
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Linux IBM ACPI]     [Linux Power Management]     [Linux Kernel]     [Linux Laptop]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Samba]     [Video 4 Linux]     [Device Mapper]     [Linux Resources]

  Powered by Linux